git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@16 30ef5769-5b8d-40dd-aea6-55b5d6557bb3tags/rel_3_17_1_ga
return sbuf.toString(); | return sbuf.toString(); | ||||
} | } | ||||
protected static int jvmTypeNameToExprType(char type) { | |||||
switch(type) { | |||||
case 'Z' : | |||||
return BOOLEAN; | |||||
case 'B' : | |||||
return BYTE; | |||||
case 'C' : | |||||
return CHAR; | |||||
case 'S' : | |||||
return SHORT; | |||||
case 'I' : | |||||
return INT; | |||||
case 'J' : | |||||
return LONG; | |||||
case 'F' : | |||||
return FLOAT; | |||||
case 'D' : | |||||
return DOUBLE; | |||||
case 'V' : | |||||
return VOID; | |||||
default : | |||||
return CLASS; | |||||
} | |||||
} | |||||
public void atASTList(ASTList n) throws CompileError { fatal(); } | public void atASTList(ASTList n) throws CompileError { fatal(); } | ||||
*/ | */ | ||||
protected void atCastToRtype(CastExpr expr) throws CompileError { | protected void atCastToRtype(CastExpr expr) throws CompileError { | ||||
expr.getOprand().accept(this); | expr.getOprand().accept(this); | ||||
if (!isRefType(exprType) || arrayDim > 0) | |||||
throw new CompileError("invalid type for " + returnCastName); | |||||
compileUnwrapValue(returnType, bytecode); | |||||
if (exprType == VOID || isRefType(exprType) || arrayDim > 0) | |||||
compileUnwrapValue(returnType, bytecode); | |||||
else if (returnType instanceof CtPrimitiveType) { | |||||
CtPrimitiveType pt = (CtPrimitiveType)returnType; | |||||
int destType = jvmTypeNameToExprType(pt.getDescriptor()); | |||||
atNumCastExpr(exprType, destType); | |||||
exprType = destType; | |||||
arrayDim = 0; | |||||
className = null; | |||||
} | |||||
else | |||||
throw new CompileError("invalid cast"); | |||||
} | } | ||||
protected void atCastToWrapper(CastExpr expr) throws CompileError { | protected void atCastToWrapper(CastExpr expr) throws CompileError { | ||||
protected void compileUnwrapValue(CtClass type, Bytecode code) | protected void compileUnwrapValue(CtClass type, Bytecode code) | ||||
throws CompileError | throws CompileError | ||||
{ | { | ||||
if (type == CtClass.voidType) { | |||||
addNullIfVoid(); | |||||
return; | |||||
} | |||||
if (exprType == VOID) | |||||
throw new CompileError("invalid type for " + returnCastName); | |||||
if (type instanceof CtPrimitiveType) { | if (type instanceof CtPrimitiveType) { | ||||
CtPrimitiveType pt = (CtPrimitiveType)type; | CtPrimitiveType pt = (CtPrimitiveType)type; | ||||
if (pt != CtClass.voidType) { | |||||
String wrapper = pt.getWrapperName(); | |||||
code.addCheckcast(wrapper); | |||||
code.addInvokevirtual(wrapper, pt.getGetMethodName(), | |||||
pt.getGetMethodDescriptor()); | |||||
setType(type); | |||||
} | |||||
// pt is not voidType. | |||||
String wrapper = pt.getWrapperName(); | |||||
code.addCheckcast(wrapper); | |||||
code.addInvokevirtual(wrapper, pt.getGetMethodName(), | |||||
pt.getGetMethodDescriptor()); | |||||
setType(type); | |||||
} | } | ||||
else { | else { | ||||
code.addCheckcast(type); | code.addCheckcast(type); |
$_ = ($r)result;</pre></ul> | $_ = ($r)result;</pre></ul> | ||||
<p>If the result type is a primitive type, then <code>($r)</code> | <p>If the result type is a primitive type, then <code>($r)</code> | ||||
converts from the wrapper type to the primitive type. | |||||
follows special semantics. First, if the operand type of the cast | |||||
expression is a primitive type, <code>($r)</code> works as a normal | |||||
cast operator to the result type. | |||||
On the other hand, if the operand type is a wrapper type, | |||||
<code>($r)</code> converts from the wrapper type to the result type. | |||||
For example, if the result type is <code>int</code>, then | For example, if the result type is <code>int</code>, then | ||||
<code>($r)</code> converts from <code>java.lang.Integer</code> to | <code>($r)</code> converts from <code>java.lang.Integer</code> to | ||||
<code>int</code>. | <code>int</code>. | ||||
<p>If the result type is <code>void</code>, then | <p>If the result type is <code>void</code>, then | ||||
<code>($r)</code> does not convert a type; it does nothing. | <code>($r)</code> does not convert a type; it does nothing. | ||||
Moreover, the soruce text can include a <code>return</code> | |||||
statement with a resulting value: | |||||
However, if the operand is a call to a <code>void</code> method, | |||||
then <code>($r)</code> results in <code>null</code>. For example, | |||||
<ul><pre>$_ = ($r)foo();</pre></ul> | |||||
<p>is a valid statement if the result type is <code>void</code>. | |||||
Here, <code>foo()</code> is a <code>void</code> method. | |||||
<p>The cast operator <code>($r)</code> is also useful in a | |||||
<code>return</code> statement. Even if the result type is | |||||
<code>void</code>, the following <code>return</code> statement is valid: | |||||
<ul><pre>return ($r)result;</pre></ul> | <ul><pre>return ($r)result;</pre></ul> | ||||