/** * Constructs a compiler. * The produced bytecode is stored in the <code>Bytecode</code> object * specified by <code>b</code>. * * @param thisClass the class that a compiled method/field * belongs to. */ public Javac(Bytecode b, CtClass thisClass) { gen = new JvstCodeGen(b, thisClass, thisClass.getClassPool()); stable = new SymbolTable(); bytecode = b; }
/** * Makes method parameters $0, $1, ..., $args, $$, and $class available. * $0 is equivalent to THIS if the method is not static. Otherwise, * if the method is static, then $0 is not available. */ public int recordParams(CtClass[] params, boolean isStatic, String prefix, String paramVarName, String paramsName, SymbolTable tbl) throws CompileError { return recordParams(params, isStatic, prefix, paramVarName, paramsName, !isStatic, 0, getThisName(), tbl); }
/** * Prepares to use cast $r, $w, $_, and $type. * $type is made to represent the specified return type. * It also enables to write a return statement with a return value * for void method. * * <p>If the return type is void, ($r) does nothing. * The type of $_ is java.lang.Object. * * @param type the return type. * @param useResultVar true if $_ is used. * @return -1 or the variable index assigned to $_. * @see #recordType(CtClass) */ public int recordReturnType(CtClass type, boolean useResultVar) throws CompileError { gen.recordType(type); return gen.recordReturnType(type, "$r", (useResultVar ? resultVarName : null), stable); }
void compileInvokeSpecial(ASTree target, int methodIndex, String descriptor, ASTList args) throws CompileError { target.accept(this); int nargs = getMethodArgsLength(args); atMethodArgs(args, new int[nargs], new int[nargs], new String[nargs]); bytecode.addInvokespecial(methodIndex, descriptor); setReturnType(descriptor, false, false); addNullIfVoid(); }
try { Bytecode b = new Bytecode(cc.getClassFile2().getConstPool(), 0, 0); JvstCodeGen gen = new JvstCodeGen(b, cc, cc.getClassPool()); SymbolTable stable = new SymbolTable(); gen.recordParams(ctConstructor.getParameterTypes(), Modifier.isStatic(mod), "$", "$args", "$$", stable); gen.recordType(CtClass.voidType); gen.recordReturnType(CtClass.voidType, "$r", null, stable); gen.atMethodBody(s, callSuper, true);
public void doit(JvstCodeGen gen, Bytecode b, ASTList args) throws CompileError { ASTree expr = new Member(m); if (texpr != null) expr = Expr.make('.', texpr, expr); expr = CallExpr.makeCall(expr, args); gen.compileExpr(expr); gen.addNullIfVoid(); }
public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) throws CompileError { if (gen.getMethodArgsLength(args) != 1) throw new CompileError(Javac.proceedName + "() cannot take more than one parameter " + "for field writing"); int stack; if (isStatic(opcode)) stack = 0; else { stack = -1; bytecode.addAload(targetVar); } gen.atMethodArgs(args, new int[1], new int[1], new String[1]); gen.doNumCast(fieldType); if (fieldType instanceof CtPrimitiveType) stack -= ((CtPrimitiveType)fieldType).getDataSize(); else --stack; bytecode.add(opcode); bytecode.addIndex(index); bytecode.growStack(stack); gen.setType(CtClass.voidType); gen.addNullIfVoid(); }
gen.setThisMethod((CtMethod)method); rtype = ((CtMethod)method).getReturnType(); callSuper = !((CtConstructor)method).isClassInitializer(); gen.atMethodBody(s, callSuper, isVoid);
public void atCastExpr(CastExpr expr) throws CompileError { ASTList classname = expr.getClassName(); if (classname != null && expr.getArrayDim() == 0) { ASTree p = classname.head(); if (p instanceof Symbol && classname.tail() == null) { String typename = ((Symbol)p).get(); if (typename.equals(returnCastName)) { atCastToRtype(expr); return; } else if (typename.equals(wrapperCastName)) { atCastToWrapper(expr); return; } } } super.atCastExpr(expr); }
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; // pt is not voidType. String wrapper = pt.getWrapperName(); code.addCheckcast(wrapper); code.addInvokevirtual(wrapper, pt.getGetMethodName(), pt.getGetMethodDescriptor()); setType(type); } else { code.addCheckcast(type); setType(type); } }
/** * Makes variables $0 (this), $1, $2, ..., and $args represent method * parameters. $args represents an array of all the parameters. * It also makes $$ available as a parameter list of method call. * * <p>This must be called before calling <code>compileStmnt()</code> and * <code>compileExpr()</code>. The correct value of * <code>isStatic</code> must be recorded before compilation. * <code>maxLocals</code> is updated to include $0,... */ public int recordParams(CtClass[] params, boolean isStatic) throws CompileError { return gen.recordParams(params, isStatic, "$", "$args", "$$", stable); }
/** * Prepares to use $type. Note that recordReturnType() overwrites * the value of $type. * * @param t the type represented by $type. */ public void recordType(CtClass t) { gen.recordType(t); }
public void atCallExpr(CallExpr expr) throws CompileError { ASTree method = expr.oprand1(); if (method instanceof Member) { String name = ((Member)method).get(); if (procHandler != null && name.equals(proceedName)) { procHandler.doit(this, bytecode, (ASTList)expr.oprand2()); return; } else if (name.equals(cflowName)) { atCflow((ASTList)expr.oprand2()); return; } } super.atCallExpr(expr); }
protected void atFieldAssign(Expr expr, int op, ASTree left, ASTree right, boolean doDup) throws CompileError { if (left instanceof Member && ((Member)left).get().equals(paramArrayName)) { if (op != '=') throw new CompileError("bad operator for " + paramArrayName); right.accept(this); if (arrayDim != 1 || exprType != CLASS) throw new CompileError("invalid type for " + paramArrayName); atAssignParamList(paramTypeList, bytecode); if (!doDup) bytecode.addOpcode(POP); } else super.atFieldAssign(expr, op, left, right, doDup); }
void compileInvokeSpecial(ASTree target, int methodIndex, String descriptor, ASTList args) throws CompileError { target.accept(this); int nargs = getMethodArgsLength(args); atMethodArgs(args, new int[nargs], new int[nargs], new String[nargs]); bytecode.addInvokespecial(methodIndex, descriptor); setReturnType(descriptor, false, false); addNullIfVoid(); }
public void doit(JvstCodeGen gen, Bytecode b, ASTList args) throws CompileError { Expr expr = Expr.make(TokenId.MEMBER, new Symbol(c), new Member(m)); expr = CallExpr.makeCall(expr, args); gen.compileExpr(expr); gen.addNullIfVoid(); }
@Override public void doit(JvstCodeGen gen, Bytecode bytecode, ASTList args) throws CompileError { if (gen.getMethodArgsLength(args) != 1) throw new CompileError(Javac.proceedName + "() cannot take more than one parameter " + "for field writing"); int stack; if (isStatic(opcode)) stack = 0; else { stack = -1; bytecode.addAload(targetVar); } gen.atMethodArgs(args, new int[1], new int[1], new String[1]); gen.doNumCast(fieldType); if (fieldType instanceof CtPrimitiveType) stack -= ((CtPrimitiveType)fieldType).getDataSize(); else --stack; bytecode.add(opcode); bytecode.addIndex(index); bytecode.growStack(stack); gen.setType(CtClass.voidType); gen.addNullIfVoid(); }
gen.setThisMethod((CtMethod)method); rtype = ((CtMethod)method).getReturnType(); callSuper = !((CtConstructor)method).isClassInitializer(); gen.atMethodBody(s, callSuper, isVoid);
@Override public void atCastExpr(CastExpr expr) throws CompileError { ASTList classname = expr.getClassName(); if (classname != null && expr.getArrayDim() == 0) { ASTree p = classname.head(); if (p instanceof Symbol && classname.tail() == null) { String typename = ((Symbol)p).get(); if (typename.equals(returnCastName)) { atCastToRtype(expr); return; } else if (typename.equals(wrapperCastName)) { atCastToWrapper(expr); return; } } } super.atCastExpr(expr); }
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; // pt is not voidType. String wrapper = pt.getWrapperName(); code.addCheckcast(wrapper); code.addInvokevirtual(wrapper, pt.getGetMethodName(), pt.getGetMethodDescriptor()); setType(type); } else { code.addCheckcast(type); setType(type); } }