From 5fc3a4c6aa6cd5378d417f98b66f76529c4341e4 Mon Sep 17 00:00:00 2001 From: chiba Date: Fri, 16 May 2003 17:07:03 +0000 Subject: [PATCH] modified the semantics of ($r). git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@16 30ef5769-5b8d-40dd-aea6-55b5d6557bb3 --- src/main/javassist/compiler/CodeGen.java | 24 +++++++++++++ src/main/javassist/compiler/JvstCodeGen.java | 37 ++++++++++++++------ tutorial/tutorial2.html | 19 ++++++++-- 3 files changed, 66 insertions(+), 14 deletions(-) diff --git a/src/main/javassist/compiler/CodeGen.java b/src/main/javassist/compiler/CodeGen.java index 60170dbb..e0b2dfa4 100644 --- a/src/main/javassist/compiler/CodeGen.java +++ b/src/main/javassist/compiler/CodeGen.java @@ -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(); } diff --git a/src/main/javassist/compiler/JvstCodeGen.java b/src/main/javassist/compiler/JvstCodeGen.java index 0090f851..40d39a11 100644 --- a/src/main/javassist/compiler/JvstCodeGen.java +++ b/src/main/javassist/compiler/JvstCodeGen.java @@ -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); diff --git a/tutorial/tutorial2.html b/tutorial/tutorial2.html index 62c26a94..b9ca5bed 100644 --- a/tutorial/tutorial2.html +++ b/tutorial/tutorial2.html @@ -350,15 +350,28 @@ For example, this is a typical use: $_ = ($r)result;

If the result type is a primitive type, then ($r) -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, ($r) works as a normal +cast operator to the result type. +On the other hand, if the operand type is a wrapper type, +($r) converts from the wrapper type to the result type. For example, if the result type is int, then ($r) converts from java.lang.Integer to int.

If the result type is void, then ($r) does not convert a type; it does nothing. -Moreover, the soruce text can include a return -statement with a resulting value: +However, if the operand is a call to a void method, +then ($r) results in null. For example, + +

+ +

is a valid statement if the result type is void. +Here, foo() is a void method. + +

The cast operator ($r) is also useful in a +return statement. Even if the result type is +void, the following return statement is valid:

-- 2.39.5