including nothing but a return statement. git-svn-id: http://anonsvn.jboss.org/repos/javassist/trunk@20 30ef5769-5b8d-40dd-aea6-55b5d6557bb3tags/rel_3_17_1_ga
@@ -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(); |
@@ -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); | |||
} | |||
@@ -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); |
@@ -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, |
@@ -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, |
@@ -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); | |||
} |
@@ -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. |
@@ -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 ]* |
@@ -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. |