diff options
-rw-r--r-- | src/main/javassist/CtBehavior.java | 2 | ||||
-rw-r--r-- | src/main/javassist/CtConstructor.java | 6 | ||||
-rw-r--r-- | src/main/javassist/CtMethod.java | 2 | ||||
-rw-r--r-- | src/main/javassist/CtNewConstructor.java | 13 | ||||
-rw-r--r-- | src/main/javassist/CtNewMethod.java | 12 | ||||
-rw-r--r-- | src/main/javassist/compiler/CodeGen.java | 8 | ||||
-rw-r--r-- | src/main/javassist/compiler/Javac.java | 44 | ||||
-rw-r--r-- | src/main/javassist/compiler/Parser.java | 9 | ||||
-rw-r--r-- | 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 <code>null</code>, 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 <code>null</code>, the substituted + * constructor body does nothing except calling + * <code>super()</code>. */ 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 <code>null</code>, 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 <code>{}</code>. + * If it is <code>null</code>, the substituted + * constructor body does nothing except calling + * <code>super()</code>. * @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 <code>{}</code>. + * If it is <code>null</code>, 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) { <p><code>CtMethod</code> and <code>CtConstructor</code> provide <code>setBody()</code> 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 <code>null</code>, the substituted body includes only a +<code>return</code> statement, which returns zero or null unless the +result type is <code>void</code>. <p>In the source text given to <code>setBody()</code>, the identifiers -starting with $ have special meaning +starting with <code>$</code> have special meaning <ul><table border=0> <tr> @@ -1095,7 +1098,10 @@ point.addMethod(m); In this example, <code>x</code> is a <code>int</code> field in the class <code>Point</code>. -<p>The source text passed to <code>make()</code> can refer to +<p>The source text passed to <code>make()</code> can include the +identifiers starting with <code>$</code> except <code>$_</code> +as in <code>setBody()</code>. +It can also include <code>$proceed</code> if the target object and the target method name are also given to <code>make()</code>. For example, @@ -1207,7 +1213,8 @@ supported. <p><li>Inner classes or anonymous classes are not supported. -<p><li><code>switch</code> statements are not supported yet. +<p><li><code>switch</code> or <code>synchronized</code> +statements are not supported yet. <p><li>Labeled <code>continue</code> and <code>break</code> statements are not supported. |