Browse Source

modified the semantics of ($r).


git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@16 30ef5769-5b8d-40dd-aea6-55b5d6557bb3
tags/rel_3_17_1_ga
chiba 21 years ago
parent
commit
5fc3a4c6aa

+ 24
- 0
src/main/javassist/compiler/CodeGen.java View File

@@ -192,6 +192,30 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId {
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(); }

+ 26
- 11
src/main/javassist/compiler/JvstCodeGen.java View File

@@ -184,10 +184,18 @@ public class JvstCodeGen extends MemberCodeGen {
*/
protected void atCastToRtype(CastExpr expr) throws CompileError {
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 {
@@ -583,15 +591,22 @@ public class JvstCodeGen extends MemberCodeGen {
protected void compileUnwrapValue(CtClass type, Bytecode code)
throws CompileError
{
if (type == CtClass.voidType) {
addNullIfVoid();
return;
}

if (exprType == VOID)
throw new CompileError("invalid type for " + returnCastName);

if (type instanceof CtPrimitiveType) {
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 {
code.addCheckcast(type);

+ 16
- 3
tutorial/tutorial2.html View File

@@ -350,15 +350,28 @@ For example, this is a typical use:
$_ = ($r)result;</pre></ul>

<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
<code>($r)</code> converts from <code>java.lang.Integer</code> to
<code>int</code>.

<p>If the result type is <code>void</code>, then
<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>


Loading…
Cancel
Save