169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal/* 269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Javassist, a Java-bytecode translator toolkit. 369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Copyright (C) 1999-2007 Shigeru Chiba. All Rights Reserved. 469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The contents of this file are subject to the Mozilla Public License Version 669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1.1 (the "License"); you may not use this file except in compliance with 769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the License. Alternatively, the contents of this file may be used under 869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the terms of the GNU Lesser General Public License Version 2.1 or later. 969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 1069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Software distributed under the License is distributed on an "AS IS" basis, 1169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 1269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for the specific language governing rights and limitations under the 1369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * License. 1469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 1569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpackage javassist.compiler; 1769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 1869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtClass; 1969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtPrimitiveType; 2069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtMember; 2169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtField; 2269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtBehavior; 2369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtMethod; 2469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CtConstructor; 2569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.CannotCompileException; 2669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.Modifier; 2769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.Bytecode; 2869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.CodeAttribute; 2969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.LocalVariableAttribute; 3069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.BadBytecode; 3169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.bytecode.Opcode; 3269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.NotFoundException; 3369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalimport javassist.compiler.ast.*; 3569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 3669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigalpublic class Javac { 3769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal JvstCodeGen gen; 3869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal SymbolTable stable; 3969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private Bytecode bytecode; 4069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static final String param0Name = "$0"; 4269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static final String resultVarName = "$_"; 4369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static final String proceedName = "$proceed"; 4469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 4569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 4669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Constructs a compiler. 4769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 4869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param thisClass the class that a compiled method/field 4969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * belongs to. 5069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 5169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Javac(CtClass thisClass) { 5269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal this(new Bytecode(thisClass.getClassFile2().getConstPool(), 0, 0), 5369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal thisClass); 5469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 5569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 5669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 5769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Constructs a compiler. 5869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The produced bytecode is stored in the <code>Bytecode</code> object 5969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * specified by <code>b</code>. 6069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 6169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param thisClass the class that a compiled method/field 6269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * belongs to. 6369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 6469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Javac(Bytecode b, CtClass thisClass) { 6569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen = new JvstCodeGen(b, thisClass, thisClass.getClassPool()); 6669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal stable = new SymbolTable(); 6769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode = b; 6869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 6969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 7169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Returns the produced bytecode. 7269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 7369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Bytecode getBytecode() { return bytecode; } 7469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 7569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 7669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Compiles a method, constructor, or field declaration 7769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * to a class. 7869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * A field declaration can declare only one field. 7969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 8069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>In a method or constructor body, $0, $1, ... and $_ 8169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * are not available. 8269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 8369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return a <code>CtMethod</code>, <code>CtConstructor</code>, 8469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * or <code>CtField</code> object. 8569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see #recordProceed(String,String) 8669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 8769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public CtMember compile(String src) throws CompileError { 8869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Parser p = new Parser(new Lex(src)); 8969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTList mem = p.parseMember1(stable); 9069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 9169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (mem instanceof FieldDecl) 9269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return compileField((FieldDecl)mem); 9369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 9469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtBehavior cb = compileMethod(p, (MethodDecl)mem); 9569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtClass decl = cb.getDeclaringClass(); 9669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cb.getMethodInfo2() 9769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal .rebuildStackMapIf6(decl.getClassPool(), 9869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal decl.getClassFile2()); 9969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return cb; 10069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (BadBytecode bb) { 10369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new CompileError(bb.getMessage()); 10469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (CannotCompileException e) { 10669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new CompileError(e.getMessage()); 10769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 10969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static class CtFieldWithInit extends CtField { 11169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private ASTree init; 11269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 11369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtFieldWithInit(CtClass type, String name, CtClass declaring) 11469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CannotCompileException 11569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 11669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal super(type, name, declaring); 11769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal init = null; 11869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 11969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected void setInit(ASTree i) { init = i; } 12169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal protected ASTree getInitAST() { 12369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return init; 12469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 12669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 12769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private CtField compileField(FieldDecl fd) 12869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError, CannotCompileException 12969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 13069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtFieldWithInit f; 13169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Declarator d = fd.getDeclarator(); 13269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal f = new CtFieldWithInit(gen.resolver.lookupClass(d), 13369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal d.getVariable().get(), gen.getThisClass()); 13469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal f.setModifiers(MemberResolver.getModifiers(fd.getModifiers())); 13569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (fd.getInit() != null) 13669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal f.setInit(fd.getInit()); 13769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 13869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return f; 13969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 14069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 14169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private CtBehavior compileMethod(Parser p, MethodDecl md) 14269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 14369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 14469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int mod = MemberResolver.getModifiers(md.getModifiers()); 14569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtClass[] plist = gen.makeParamList(md); 14669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtClass[] tlist = gen.makeThrowsList(md); 14769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal recordParams(plist, Modifier.isStatic(mod)); 14869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal md = p.parseMethod2(stable, md); 14969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 15069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (md.isConstructor()) { 15169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtConstructor cons = new CtConstructor(plist, 15269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.getThisClass()); 15369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cons.setModifiers(mod); 15469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal md.accept(gen); 15569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cons.getMethodInfo().setCodeAttribute( 15669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.toCodeAttribute()); 15769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal cons.setExceptionTypes(tlist); 15869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return cons; 15969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 16069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 16169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Declarator r = md.getReturn(); 16269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtClass rtype = gen.resolver.lookupClass(r); 16369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal recordReturnType(rtype, false); 16469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtMethod method = new CtMethod(rtype, r.getVariable().get(), 16569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal plist, gen.getThisClass()); 16669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal method.setModifiers(mod); 16769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.setThisMethod(method); 16869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal md.accept(gen); 16969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (md.getBody() != null) 17069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal method.getMethodInfo().setCodeAttribute( 17169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal bytecode.toCodeAttribute()); 17269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 17369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal method.setModifiers(mod | Modifier.ABSTRACT); 17469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 17569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal method.setExceptionTypes(tlist); 17669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return method; 17769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 17969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (NotFoundException e) { 18069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new CompileError(e.toString()); 18169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 18369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 18469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 18569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Compiles a method (or constructor) body. 18669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 18769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @src a single statement or a block. 18869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If null, this method produces a body returning zero or null. 18969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 19069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public Bytecode compileBody(CtBehavior method, String src) 19169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 19269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 19369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal try { 19469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int mod = method.getModifiers(); 19569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal recordParams(method.getParameterTypes(), Modifier.isStatic(mod)); 19669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 19769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtClass rtype; 19869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (method instanceof CtMethod) { 19969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.setThisMethod((CtMethod)method); 20069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal rtype = ((CtMethod)method).getReturnType(); 20169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 20269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 20369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal rtype = CtClass.voidType; 20469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal recordReturnType(rtype, false); 20669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean isVoid = rtype == CtClass.voidType; 20769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 20869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (src == null) 20969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal makeDefaultBody(bytecode, rtype); 21069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 21169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Parser p = new Parser(new Lex(src)); 21269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal SymbolTable stb = new SymbolTable(stable); 21369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Stmnt s = p.parseStatement(stb); 21469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (p.hasMore()) 21569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new CompileError( 21669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal "the method/constructor body must be surrounded by {}"); 21769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 21869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean callSuper = false; 21969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (method instanceof CtConstructor) 22069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal callSuper = !((CtConstructor)method).isClassInitializer(); 22169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 22269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.atMethodBody(s, callSuper, isVoid); 22369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 22569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return bytecode; 22669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 22769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal catch (NotFoundException e) { 22869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throw new CompileError(e.toString()); 22969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 23069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 23169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 23269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal private static void makeDefaultBody(Bytecode b, CtClass type) { 23369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int op; 23469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int value; 23569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (type instanceof CtPrimitiveType) { 23669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal CtPrimitiveType pt = (CtPrimitiveType)type; 23769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal op = pt.getReturnOp(); 23869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (op == Opcode.DRETURN) 23969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal value = Opcode.DCONST_0; 24069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (op == Opcode.FRETURN) 24169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal value = Opcode.FCONST_0; 24269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (op == Opcode.LRETURN) 24369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal value = Opcode.LCONST_0; 24469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else if (op == Opcode.RETURN) 24569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal value = Opcode.NOP; 24669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else 24769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal value = Opcode.ICONST_0; 24869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 24969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal else { 25069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal op = Opcode.ARETURN; 25169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal value = Opcode.ACONST_NULL; 25269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 25369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 25469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (value != Opcode.NOP) 25569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal b.addOpcode(value); 25669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 25769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal b.addOpcode(op); 25869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 25969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 26069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 26169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Records local variables available at the specified program counter. 26269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If the LocalVariableAttribute is not available, this method does not 26369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * record any local variable. It only returns false. 26469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 26569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param pc program counter (>= 0) 26669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return false if the CodeAttribute does not include a 26769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * LocalVariableAttribute. 26869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 26969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean recordLocalVariables(CodeAttribute ca, int pc) 27069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 27169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 27269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal LocalVariableAttribute va 27369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal = (LocalVariableAttribute) 27469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ca.getAttribute(LocalVariableAttribute.tag); 27569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (va == null) 27669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; 27769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 27869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = va.tableLength(); 27969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; ++i) { 28069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int start = va.startPc(i); 28169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int len = va.codeLength(i); 28269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (start <= pc && pc < start + len) 28369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.recordVariable(va.descriptor(i), va.variableName(i), 28469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal va.index(i), stable); 28569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 28669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 28769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return true; 28869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 28969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 29069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 29169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Records parameter names if the LocalVariableAttribute is available. 29269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It returns false unless the LocalVariableAttribute is available. 29369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 29469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param numOfLocalVars the number of local variables used 29569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for storing the parameters. 29669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return false if the CodeAttribute does not include a 29769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * LocalVariableAttribute. 29869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 29969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public boolean recordParamNames(CodeAttribute ca, int numOfLocalVars) 30069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 30169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 30269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal LocalVariableAttribute va 30369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal = (LocalVariableAttribute) 30469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ca.getAttribute(LocalVariableAttribute.tag); 30569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (va == null) 30669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return false; 30769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 30869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int n = va.tableLength(); 30969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal for (int i = 0; i < n; ++i) { 31069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal int index = va.index(i); 31169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (index < numOfLocalVars) 31269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.recordVariable(va.descriptor(i), va.variableName(i), 31369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal index, stable); 31469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 31569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 31669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return true; 31769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 31869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 31969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 32069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 32169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Makes variables $0 (this), $1, $2, ..., and $args represent method 32269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * parameters. $args represents an array of all the parameters. 32369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It also makes $$ available as a parameter list of method call. 32469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 32569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This must be called before calling <code>compileStmnt()</code> and 32669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>compileExpr()</code>. The correct value of 32769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>isStatic</code> must be recorded before compilation. 32869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>maxLocals</code> is updated to include $0,... 32969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 33069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int recordParams(CtClass[] params, boolean isStatic) 33169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 33269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 33369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return gen.recordParams(params, isStatic, "$", "$args", "$$", stable); 33469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 33569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 33669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 33769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Makes variables $0, $1, $2, ..., and $args represent method 33869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * parameters. $args represents an array of all the parameters. 33969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It also makes $$ available as a parameter list of method call. 34069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * $0 can represent a local variable other than THIS (variable 0). 34169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * $class is also made available. 34269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 34369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This must be called before calling <code>compileStmnt()</code> and 34469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>compileExpr()</code>. The correct value of 34569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>isStatic</code> must be recorded before compilation. 34669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>maxLocals</code> is updated to include $0,... 34769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 34869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @paaram use0 true if $0 is used. 34969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param varNo the register number of $0 (use0 is true) 35069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * or $1 (otherwise). 35169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param target the type of $0 (it can be null if use0 is false). 35269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It is used as the name of the type represented 35369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * by $class. 35469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param isStatic true if the method in which the compiled bytecode 35569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * is embedded is static. 35669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 35769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int recordParams(String target, CtClass[] params, 35869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal boolean use0, int varNo, boolean isStatic) 35969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 36069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 36169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return gen.recordParams(params, isStatic, "$", "$args", "$$", 36269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal use0, varNo, target, stable); 36369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 36469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 36569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 36669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Sets <code>maxLocals</code> to <code>max</code>. 36769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * This method tells the compiler the local variables that have been 36869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * allocated for the rest of the code. When the compiler needs 36969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * new local variables, the local variables at the index <code>max</code>, 37069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>max + 1</code>, ... are assigned. 37169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 37269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>This method is indirectly called by <code>recordParams</code>. 37369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 37469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setMaxLocals(int max) { 37569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.setMaxLocals(max); 37669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 37769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 37869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 37969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Prepares to use cast $r, $w, $_, and $type. 38069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * $type is made to represent the specified return type. 38169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * It also enables to write a return statement with a return value 38269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * for void method. 38369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 38469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>If the return type is void, ($r) does nothing. 38569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * The type of $_ is java.lang.Object. 38669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 38769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param type the return type. 38869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param useResultVar true if $_ is used. 38969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @return -1 or the variable index assigned to $_. 39069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @see #recordType(CtClass) 39169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 39269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int recordReturnType(CtClass type, boolean useResultVar) 39369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 39469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 39569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.recordType(type); 39669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return gen.recordReturnType(type, "$r", 39769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal (useResultVar ? resultVarName : null), stable); 39869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 39969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 40069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 40169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Prepares to use $type. Note that recordReturnType() overwrites 40269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * the value of $type. 40369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 40469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param t the type represented by $type. 40569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 40669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void recordType(CtClass t) { 40769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.recordType(t); 40869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 40969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 41069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 41169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Makes the given variable available. 41269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 41369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param type variable type 41469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param name variable name 41569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 41669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public int recordVariable(CtClass type, String name) 41769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 41869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 41969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return gen.recordVariable(type, name, stable); 42069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 42169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 42269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 42369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Prepares to use $proceed(). 42469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If the return type of $proceed() is void, null is pushed on the 42569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * stack. 42669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 42769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param target an expression specifying the target object. 42869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * if null, "this" is the target. 42969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param method the method name. 43069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 43169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void recordProceed(String target, String method) 43269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 43369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 43469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Parser p = new Parser(new Lex(target)); 43569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal final ASTree texpr = p.parseExpression(stable); 43669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal final String m = method; 43769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 43869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ProceedHandler h = new ProceedHandler() { 43969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void doit(JvstCodeGen gen, Bytecode b, ASTList args) 44069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 44169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 44269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree expr = new Member(m); 44369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (texpr != null) 44469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr = Expr.make('.', texpr, expr); 44569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 44669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr = CallExpr.makeCall(expr, args); 44769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.compileExpr(expr); 44869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.addNullIfVoid(); 44969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 45069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 45169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setReturnType(JvstTypeChecker check, ASTList args) 45269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 45369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 45469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree expr = new Member(m); 45569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (texpr != null) 45669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr = Expr.make('.', texpr, expr); 45769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 45869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr = CallExpr.makeCall(expr, args); 45969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.accept(check); 46069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal check.addNullIfVoid(); 46169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 46269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal }; 46369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 46469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.setProceedHandler(h, proceedName); 46569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 46669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 46769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 46869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Prepares to use $proceed() representing a static method. 46969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If the return type of $proceed() is void, null is pushed on the 47069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * stack. 47169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 47269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param targetClass the fully-qualified dot-separated name 47369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * of the class declaring the method. 47469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param method the method name. 47569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 47669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void recordStaticProceed(String targetClass, String method) 47769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 47869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 47969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal final String c = targetClass; 48069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal final String m = method; 48169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 48269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ProceedHandler h = new ProceedHandler() { 48369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void doit(JvstCodeGen gen, Bytecode b, ASTList args) 48469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 48569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 48669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Expr expr = Expr.make(TokenId.MEMBER, 48769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal new Symbol(c), new Member(m)); 48869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr = CallExpr.makeCall(expr, args); 48969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.compileExpr(expr); 49069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.addNullIfVoid(); 49169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 49269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 49369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setReturnType(JvstTypeChecker check, ASTList args) 49469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 49569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 49669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Expr expr = Expr.make(TokenId.MEMBER, 49769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal new Symbol(c), new Member(m)); 49869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr = CallExpr.makeCall(expr, args); 49969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal expr.accept(check); 50069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal check.addNullIfVoid(); 50169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 50269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal }; 50369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 50469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.setProceedHandler(h, proceedName); 50569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 50669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 50769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 50869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Prepares to use $proceed() representing a private/super's method. 50969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * If the return type of $proceed() is void, null is pushed on the 51069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * stack. This method is for methods invoked by INVOKESPECIAL. 51169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 51269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param target an expression specifying the target object. 51369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * if null, "this" is the target. 51469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param classname the class name declaring the method. 51569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param methodname the method name. 51669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * @param descriptor the method descriptor. 51769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 51869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void recordSpecialProceed(String target, String classname, 51969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal String methodname, String descriptor) 52069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 52169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 52269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Parser p = new Parser(new Lex(target)); 52369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal final ASTree texpr = p.parseExpression(stable); 52469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal final String cname = classname; 52569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal final String method = methodname; 52669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal final String desc = descriptor; 52769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 52869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ProceedHandler h = new ProceedHandler() { 52969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void doit(JvstCodeGen gen, Bytecode b, ASTList args) 53069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 53169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 53269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.compileInvokeSpecial(texpr, cname, method, desc, args); 53369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 53469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 53569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void setReturnType(JvstTypeChecker c, ASTList args) 53669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 53769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 53869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal c.compileInvokeSpecial(texpr, cname, method, desc, args); 53969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 54069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 54169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal }; 54269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 54369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.setProceedHandler(h, proceedName); 54469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 54569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 54669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 54769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Prepares to use $proceed(). 54869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 54969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void recordProceed(ProceedHandler h) { 55069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.setProceedHandler(h, proceedName); 55169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 55269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 55369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 55469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Compiles a statement (or a block). 55569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <code>recordParams()</code> must be called before invoking 55669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * this method. 55769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 55869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>Local variables that are not declared 55969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * in the compiled source text might not be accessible within that 56069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * source text. Fields and method parameters ($0, $1, ..) are available. 56169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 56269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void compileStmnt(String src) throws CompileError { 56369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Parser p = new Parser(new Lex(src)); 56469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal SymbolTable stb = new SymbolTable(stable); 56569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal while (p.hasMore()) { 56669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Stmnt s = p.parseStatement(stb); 56769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (s != null) 56869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal s.accept(gen); 56969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 57069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 57169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 57269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 57369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Compiles an exression. <code>recordParams()</code> must be 57469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * called before invoking this method. 57569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 57669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>Local variables are not accessible 57769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * within the compiled source text. Fields and method parameters 57869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * ($0, $1, ..) are available if <code>recordParams()</code> 57969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * have been invoked. 58069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 58169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void compileExpr(String src) throws CompileError { 58269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal ASTree e = parseExpr(src, stable); 58369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal compileExpr(e); 58469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 58569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 58669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 58769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Parsers an expression. 58869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 58969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public static ASTree parseExpr(String src, SymbolTable st) 59069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal throws CompileError 59169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal { 59269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal Parser p = new Parser(new Lex(src)); 59369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal return p.parseExpression(st); 59469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 59569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal 59669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal /** 59769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * Compiles an exression. <code>recordParams()</code> must be 59869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * called before invoking this method. 59969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * 60069e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * <p>Local variables are not accessible 60169e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * within the compiled source text. Fields and method parameters 60269e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * ($0, $1, ..) are available if <code>recordParams()</code> 60369e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal * have been invoked. 60469e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal */ 60569e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal public void compileExpr(ASTree e) throws CompileError { 60669e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal if (e != null) 60769e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal gen.compileExpr(e); 60869e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal } 60969e17611504376e4d4603925f8528dfc890fd2c6Luis Sigal} 610