From 03e676c3ec809a09ebcc3ee3c2927e903d19e461 Mon Sep 17 00:00:00 2001 From: chiba Date: Mon, 19 May 2003 05:57:40 +0000 Subject: [PATCH] changed CtBehavior.setBody() so that setBody(null) produces a body including nothing but a return statement. git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@20 30ef5769-5b8d-40dd-aea6-55b5d6557bb3 --- src/main/javassist/CtBehavior.java | 2 ++ src/main/javassist/CtConstructor.java | 6 ++++ src/main/javassist/CtMethod.java | 2 ++ src/main/javassist/CtNewConstructor.java | 13 ++++--- src/main/javassist/CtNewMethod.java | 12 ++++--- src/main/javassist/compiler/CodeGen.java | 8 ++++- src/main/javassist/compiler/Javac.java | 44 +++++++++++++++++++++--- src/main/javassist/compiler/Parser.java | 9 +++++ tutorial/tutorial2.html | 15 +++++--- 9 files changed, 92 insertions(+), 19 deletions(-) diff --git a/src/main/javassist/CtBehavior.java b/src/main/javassist/CtBehavior.java index f040b87b..35ea4061 100644 --- a/src/main/javassist/CtBehavior.java +++ b/src/main/javassist/CtBehavior.java @@ -147,6 +147,8 @@ public abstract class CtBehavior extends CtMember { * * @param src the source code representing the member body. * It must be a single statement or block. + * If it is null, the substituted member + * body does nothing except returning zero or null. */ public void setBody(String src) throws CannotCompileException { declaringClass.checkModify(); diff --git a/src/main/javassist/CtConstructor.java b/src/main/javassist/CtConstructor.java index e44e6db0..403ce95d 100644 --- a/src/main/javassist/CtConstructor.java +++ b/src/main/javassist/CtConstructor.java @@ -283,8 +283,14 @@ public final class CtConstructor extends CtBehavior { * * @param src the source code representing the constructor body. * It must be a single statement or block. + * If it is null, the substituted + * constructor body does nothing except calling + * super(). */ public void setBody(String src) throws CannotCompileException { + if (src == null) + src = "super();"; + super.setBody(src); } diff --git a/src/main/javassist/CtMethod.java b/src/main/javassist/CtMethod.java index 7e100717..22796467 100644 --- a/src/main/javassist/CtMethod.java +++ b/src/main/javassist/CtMethod.java @@ -304,6 +304,8 @@ public final class CtMethod extends CtBehavior { * * @param src the source code representing the method body. * It must be a single statement or block. + * If it is null, the substituted method + * body does nothing except returning zero or null. */ public void setBody(String src) throws CannotCompileException { super.setBody(src); diff --git a/src/main/javassist/CtNewConstructor.java b/src/main/javassist/CtNewConstructor.java index a461bb19..49e7465a 100644 --- a/src/main/javassist/CtNewConstructor.java +++ b/src/main/javassist/CtNewConstructor.java @@ -74,12 +74,15 @@ public class CtNewConstructor { /** * Creates a public constructor. * - * @param returnType the type of the returned value - * @param mname the method name - * @param parameters a list of the parameter types - * @param exceptions a list of the exception types - * @param src the source text of the method body. + * @param returnType the type of the returned value. + * @param mname the method name. + * @param parameters a list of the parameter types. + * @param exceptions a list of the exception types. + * @param body the source text of the constructor body. * It must be a block surrounded by {}. + * If it is null, the substituted + * constructor body does nothing except calling + * super(). * @param declaring the class to which the created method is added. */ public static CtConstructor make(CtClass[] parameters, diff --git a/src/main/javassist/CtNewMethod.java b/src/main/javassist/CtNewMethod.java index 525a1216..4853c2fd 100644 --- a/src/main/javassist/CtNewMethod.java +++ b/src/main/javassist/CtNewMethod.java @@ -84,12 +84,14 @@ public class CtNewMethod { /** * Creates a public method. * - * @param returnType the type of the returned value - * @param mname the method name - * @param parameters a list of the parameter types - * @param exceptions a list of the exception types - * @param src the source text of the method body. + * @param returnType the type of the returned value. + * @param mname the method name. + * @param parameters a list of the parameter types. + * @param exceptions a list of the exception types. + * @param body the source text of the method body. * It must be a block surrounded by {}. + * If it is null, the created method + * does nothing except returning zero or null. * @param declaring the class to which the created method is added. */ public static CtMethod make(CtClass returnType, String mname, diff --git a/src/main/javassist/compiler/CodeGen.java b/src/main/javassist/compiler/CodeGen.java index 35ca2605..d0009429 100644 --- a/src/main/javassist/compiler/CodeGen.java +++ b/src/main/javassist/compiler/CodeGen.java @@ -1090,7 +1090,13 @@ public abstract class CodeGen extends Visitor implements Opcode, TokenId { bytecode.addOpcode(POP2); } else if (result_type == P_FLOAT) { - bytecode.addOpcode(SWAP); + if (type1_p == P_LONG) { + bytecode.addOpcode(DUP_X2); + bytecode.addOpcode(POP); + } + else + bytecode.addOpcode(SWAP); + bytecode.addOpcode(op); bytecode.addOpcode(SWAP); } diff --git a/src/main/javassist/compiler/Javac.java b/src/main/javassist/compiler/Javac.java index de322cdf..491cff45 100644 --- a/src/main/javassist/compiler/Javac.java +++ b/src/main/javassist/compiler/Javac.java @@ -16,6 +16,7 @@ package javassist.compiler; import javassist.CtClass; +import javassist.CtPrimitiveType; import javassist.CtMember; import javassist.CtField; import javassist.CtBehavior; @@ -25,6 +26,7 @@ import javassist.CannotCompileException; import javassist.ClassPool; import javassist.Modifier; import javassist.bytecode.Bytecode; +import javassist.bytecode.Opcode; import javassist.NotFoundException; import javassist.compiler.ast.*; @@ -172,6 +174,7 @@ public class Javac { * Compiles a method (or constructor) body. * * @src a single statement or a block. + * If null, this method produces a body returning zero or null. */ public Bytecode compileBody(CtBehavior method, String src) throws CompileError @@ -191,10 +194,15 @@ public class Javac { recordReturnType(rtype, false); boolean isVoid = rtype == CtClass.voidType; - Parser p = new Parser(new Lex(src)); - SymbolTable stb = new SymbolTable(stable); - Stmnt s = p.parseStatement(stb); - gen.atMethodBody(s, method instanceof CtConstructor, isVoid); + if (src == null) + makeDefaultBody(bytecode, rtype); + else { + Parser p = new Parser(new Lex(src)); + SymbolTable stb = new SymbolTable(stable); + Stmnt s = p.parseStatement(stb); + gen.atMethodBody(s, method instanceof CtConstructor, isVoid); + } + return bytecode; } catch (NotFoundException e) { @@ -202,6 +210,34 @@ public class Javac { } } + private static void makeDefaultBody(Bytecode b, CtClass type) { + int op; + int value; + if (type instanceof CtPrimitiveType) { + CtPrimitiveType pt = (CtPrimitiveType)type; + op = pt.getReturnOp(); + if (op == Opcode.DRETURN) + value = Opcode.DCONST_0; + else if (op == Opcode.FRETURN) + value = Opcode.FCONST_0; + else if (op == Opcode.LRETURN) + value = Opcode.LCONST_0; + else if (op == Opcode.RETURN) + value = Opcode.NOP; + else + value = Opcode.ICONST_0; + } + else { + op = Opcode.ARETURN; + value = Opcode.ACONST_NULL; + } + + if (value != Opcode.NOP) + b.addOpcode(value); + + b.addOpcode(op); + } + /** * Makes variables $0 (this), $1, $2, ..., and $args represent method * parameters. $args represents an array of all the parameters. diff --git a/src/main/javassist/compiler/Parser.java b/src/main/javassist/compiler/Parser.java index 3bddb7c8..f1865951 100644 --- a/src/main/javassist/compiler/Parser.java +++ b/src/main/javassist/compiler/Parser.java @@ -262,6 +262,8 @@ public final class Parser implements TokenId { return parseTry(tbl); else if (t == SWITCH) return parseSwitch(tbl); + else if (t == SYNCHRONIZED) + return parseSynchronized(tbl); else if (t == RETURN) return parseReturn(tbl); else if (t == THROW) @@ -403,6 +405,13 @@ public final class Parser implements TokenId { throw new CompileError("switch is not supported", lex); } + /* synchronized.statement : + * SYNCHRONIZED "(" expression ")" block.statement + */ + private Stmnt parseSynchronized(SymbolTable tbl) throws CompileError { + throw new CompileError("synchronized is not supported", lex); + } + /* try.statement * : TRY block.statement * [ CATCH "(" class.type Identifier ")" block.statement ]* diff --git a/tutorial/tutorial2.html b/tutorial/tutorial2.html index 5016474a..31d75f0b 100644 --- a/tutorial/tutorial2.html +++ b/tutorial/tutorial2.html @@ -489,10 +489,13 @@ catch (java.io.IOException e) {

CtMethod and CtConstructor provide setBody() for substituting a whole method body. They compile the given source text into Java bytecode -and substitutes it for the original method body. +and substitutes it for the original method body. If the given source +text is null, the substituted body includes only a +return statement, which returns zero or null unless the +result type is void.

In the source text given to setBody(), the identifiers -starting with $ have special meaning +starting with $ have special meaning