TClass cls = new TClass(name, flags)
cls.add(member)
byte[] bytes = cls.getBytes()
public String hello() { return "Hello"; }Use the following code:
Frame f = new Frame(new TypeID[0], false); Statement code = Statement._return(Expression.constant("Hello")); TMethod method = new TMethod("hello", Flags.PUBLIC, frame, TypeID.STRING, code);
static int count;The same is accomplished in TransJVM with:
TClass cls = new TClass("XXX", Flags.PUBLIC); TField field = new TField("count", Flags.STATIC, TypeID.INT); cls.add(field);
A frame represents the parameters of a method and it local variables. It corresponds to the stack frame during the execution of its owning method.
There is a one to one relation between a frame and a method. Each method must contain exactly one Frame. Each Frame must belong to exactly one method.
A Frame is created by specifying its parameters and whether it is static. For example the Frame for the java.lang.String method
indexOf(String str, int fromIndex)would be
TypeID[] parameters = new TypeID[] { TypeID.STRING, TypeID.INT }; Frame frameForIndexOf = new Frame(parameters, false);Note that we do not care what the method is called or its return type.
Once we have a frame we can get locals variables with
Variable localVariable = frame.variable(type);Variables can be returned for reuse with:
frame.free(localVariable);Frame also allows for local variables to have a name and type attached for debugging purposes. To attach a name to a variable for the duration of Statement s, use:
s = frame.name(variable, name, s);
Statements are the most important part of TransJVM. They are the executable part of a method or constructor. There are about a dozen basic statements provided in TransJVM, but any complex statement can be created out of these building blocks.
You may have noted that TMethod and TConstructor accept only a single statement, but most methods and constructors consist of many statements. Several statements can be combined into one statement that executes those statements in turn.
A pair of statements s1 and s2 can be combined into one statement with
Statement pair = s1.concat(s2);
A list of statements can be combined
into one with Statement list = Statement.list(mylist)
,
where myList
is a List of Statements
Statement._goto(label)
Eg.Label label = new Label(); Statement go = Statement._goto(label); Statement ignore = Statement.RETURN_VOID; Statement jumpOver = go.concat(ignore).concat(label);
Statement._if(cond, stmt)
Otherwise see Conditional Branching
Statement._throw(exception)
Statement.guarded(body,
errorValue, handlers)
Statement.always(body,
postscript)
Statement._return(value);
Statement.RETURN_VOID;
stm = Statement.line(stm, line);
1
new StringBuffer("<html>")
(7 + x) / y > 2
Expression.constant(1)
ConstructorID newBuffer = new ConstructorID(TypeID.forName("java.lang.StringBuffer"), TypeID.STRING);
newBuffer.newInstance(Expression.constant("<html>"))
Expression.constant(7).math(Operator.ADD, x).math(Operator.DIV, y).compare(Operator.GT, Expression.constant(2))
Expression.constant(value)
.
For booleans use Expression.TRUE
or Expression.FALSE
.
expression1.math(operator, expression2)
For example x + y is x.math(Operator.ADD, y)
expression1.compare(operator, expression2)
For example x >= y is x.compare(Operator.GE, y)
For direct evaluation use expression1.bitwise(operator, expression2)
.
For example x & y is x.bitwise(Operator.AND, y)
.
For shortcut or lazy evaluation (ie. only evaluate y in x && y if x is
true) use expression1.shortCut(operator, expression2)
.
For example x && y is x.shortCut(Operator.AND, y)
.
MethodID.call(arg0, arg1...)
.
For example "Hello".substring(2) is
substring.call(Expression.constant("Hello"), Expression.constant(2))
where
substring = MethodID.virtual(TypeID.STRING, TypeID.STRING, "substring", TypeID.INT)
exp.branch(branchOnTrue, target)
For example, to get a Statement that jumps to 'end' when cond is false
Statement toEnd = cond.branch(false, end);
var.store(exp)
This returns a statement
which stores exp in var.
var.assign(exp)
This returns an
expression which has the same value as exp, but as a side effect stores exp
in var.