?? createbcode.jrag
字號:
gen.emit(type().arrayLoad()); } // select the typed operation for a compound assign expression public void AssignExpr.createAssignOp(CodeGeneration gen, TypeDecl type) { throw new Error("Operation createAssignOp is not implemented for " + getClass().getName()); } public void AssignMulExpr.createAssignOp(CodeGeneration gen, TypeDecl type) { type.mul(gen); } public void AssignDivExpr.createAssignOp(CodeGeneration gen, TypeDecl type) { type.div(gen); } public void AssignModExpr.createAssignOp(CodeGeneration gen, TypeDecl type) { type.rem(gen); } public void AssignPlusExpr.createAssignOp(CodeGeneration gen, TypeDecl type) { type.add(gen); } public void AssignMinusExpr.createAssignOp(CodeGeneration gen, TypeDecl type) { type.sub(gen); } public void AssignLShiftExpr.createAssignOp(CodeGeneration gen, TypeDecl type) { type.shl(gen); } public void AssignRShiftExpr.createAssignOp(CodeGeneration gen, TypeDecl type) { type.shr(gen); } public void AssignURShiftExpr.createAssignOp(CodeGeneration gen, TypeDecl type) { type.ushr(gen); } public void AssignAndExpr.createAssignOp(CodeGeneration gen, TypeDecl type) { type.bitand(gen); } public void AssignXorExpr.createAssignOp(CodeGeneration gen, TypeDecl type) { type.bitxor(gen); } public void AssignOrExpr.createAssignOp(CodeGeneration gen, TypeDecl type) { type.bitor(gen); } public void AbstractDot.createBCode(CodeGeneration gen) { lastAccess().createBCode(gen); } public void VarAccess.createBCode(CodeGeneration gen) { Variable v = decl(); if(v instanceof VariableDeclaration) { VariableDeclaration decl = (VariableDeclaration)v; if(decl.hostType() == hostType()) decl.type().emitLoadLocal(gen, decl.localNum()); else emitLoadLocalInNestedClass(gen, decl); } else if(v instanceof ParameterDeclaration) { ParameterDeclaration decl = (ParameterDeclaration)v; if(decl.hostType() == hostType()) decl.type().emitLoadLocal(gen, decl.localNum()); else emitLoadLocalInNestedClass(gen, decl); } else if(v instanceof FieldDeclaration) { FieldDeclaration f = (FieldDeclaration)v; createLoadQualifier(gen); if(f.isConstant() && (f.type().isPrimitive() || f.type().isString())) { if(!f.isStatic()) fieldQualifierType().emitPop(gen); f.constant().createBCode(gen); } else if(f.isPrivate() && !hostType().hasField(v.name())) f.createAccessor(fieldQualifierType()).emitInvokeMethod(gen, fieldQualifierType()); else f.emitLoadField(gen, fieldQualifierType()); } } syn boolean TypeDecl.needsAccessorFor(Variable v) { if(!(v instanceof FieldDeclaration)) return false; FieldDeclaration f = (FieldDeclaration)v; if(f.isConstant() && (f.type().isPrimitive() || f.type().isString())) return false; return f.isPrivate() && !hasField(v.name()); } inh boolean Access.inExplicitConstructorInvocation(); public void Access.emitLoadLocalInNestedClass(CodeGeneration gen, Variable v) { if(inExplicitConstructorInvocation() && enclosingBodyDecl() instanceof ConstructorDecl) { ConstructorDecl c = (ConstructorDecl)enclosingBodyDecl(); v.type().emitLoadLocal(gen, c.localIndexOfEnclosingVariable(v)); } else { String classname = hostType().constantPoolName(); String desc = v.type().typeDescriptor(); String name = "val$" + v.name(); int index = gen.constantPool().addFieldref(classname, name, desc); gen.emit(Bytecode.ALOAD_0); gen.emit(Bytecode.GETFIELD, v.type().variableSize() - 1).add2(index); } } protected void VarAccess.createLoadQualifier(CodeGeneration gen) { Variable v = decl(); if(v instanceof FieldDeclaration) { FieldDeclaration f = (FieldDeclaration)v; if(hasPrevExpr()) { // load explicit qualifier prevExpr().createBCode(gen); // pop qualifier stack element for class variables // this qualifier must be computed to ensure side effects if(!prevExpr().isTypeAccess() && f.isClassVariable()) prevExpr().type().emitPop(gen); } else if(f.isInstanceVariable()) { emitThis(gen, fieldQualifierType()); } } } public void MethodAccess.createBCode(CodeGeneration gen) { createLoadQualifier(gen); if(decl().type().isUnknown()) { System.err.println("Could not bind " + this); for (int i = 0; i < getNumArg(); ++i) { System.err.println("Argument " + getArg(i) + " is of type " + getArg(i).type().typeName()); if(getArg(i).varDecl() != null) System.err.println(getArg(i).varDecl() + " in " + getArg(i).varDecl().hostType().typeName()); } if(isQualified()) System.err.println("Qualifier " + qualifier() + " is of type " + qualifier().type().typeName()); throw new Error("Could not bind " + this); } if(decl().getNumParameter() != getNumArg()) { System.out.println(this + " does not have the same number of arguments as " + decl()); } for (int i = 0; i < getNumArg(); ++i) { getArg(i).createBCode(gen); getArg(i).type().emitCastTo(gen, decl().getParameter(i).type()); // MethodInvocationConversion } /* if(decl().isPrivate() && !hostType().hasMethod(name())) { decl().emitInvokeMethodAccessor(gen, methodQualifierType()); } else*/ { if(!decl().isStatic() && isQualified() && prevExpr().isSuperAccess()) { if(!hostType().instanceOf(prevExpr().type())) decl().createSuperAccessor(superAccessorTarget()).emitInvokeMethod(gen, superAccessorTarget()); else decl().emitInvokeSpecialMethod(gen, methodQualifierType()); } else decl().emitInvokeMethod(gen, methodQualifierType()); } } protected void MethodAccess.createLoadQualifier(CodeGeneration gen) { MethodDecl m = decl(); if(hasPrevExpr()) { // load explicit qualifier prevExpr().createBCode(gen); // pop qualifier stack element for class variables // this qualifier must be computed to ensure side effects if(m.isStatic() && !prevExpr().isTypeAccess()) prevExpr().type().emitPop(gen); } else if(!m.isStatic()) { // load implicit this qualifier emitThis(gen, methodQualifierType()); } } public void ArrayAccess.createBCode(CodeGeneration gen) { prevExpr().createBCode(gen); getExpr().createBCode(gen); gen.emit(type().arrayLoad()); } public void ThisAccess.createBCode(CodeGeneration gen) { emitThis(gen, decl()); } public void SuperAccess.createBCode(CodeGeneration gen) { emitThis(gen, decl()); } // load this where hostType is the target this instance // supporting inner classes and in explicit contructor invocations public void Access.emitThis(CodeGeneration gen, TypeDecl targetDecl) { if(targetDecl == hostType()) gen.emit(Bytecode.ALOAD_0); else { TypeDecl enclosing = hostType(); if(inExplicitConstructorInvocation()) { gen.emit(Bytecode.ALOAD_1); enclosing = enclosing.enclosing(); } else { gen.emit(Bytecode.ALOAD_0); } while(enclosing != targetDecl) { String classname = enclosing.constantPoolName(); enclosing = enclosing.enclosingType(); String desc = enclosing.typeDescriptor(); int index = gen.constantPool().addFieldref(classname, "this$0", desc); gen.emit(Bytecode.GETFIELD, 0).add2(index); } } } public void ConstructorAccess.createBCode(CodeGeneration gen) { ConstructorDecl c = decl(); int index = 0; // this gen.emitLoadReference(index++); // this$0 if(c.needsEnclosing()) gen.emitLoadReference(index++); if(c.needsSuperEnclosing()) gen.emitLoadReference(index++); // args for (int i = 0; i < getNumArg(); ++i) { getArg(i).createBCode(gen); getArg(i).type().emitCastTo(gen, decl().getParameter(i).type()); // MethodInvocationConversion } if(decl().isPrivate() && decl().hostType() != hostType()) { gen.emit(Bytecode.ACONST_NULL); decl().createAccessor().emitInvokeConstructor(gen); } else { decl().emitInvokeConstructor(gen); } } public void SuperConstructorAccess.createBCode(CodeGeneration gen) { ConstructorDecl c = decl(); // this gen.emit(Bytecode.ALOAD_0); if(c.needsEnclosing()) { if(hasPrevExpr() && !prevExpr().isTypeAccess()) { prevExpr().createBCode(gen); gen.emitDup(); int index = gen.constantPool().addMethodref("java/lang/Object", "getClass", "()Ljava/lang/Class;"); gen.emit(Bytecode.INVOKEVIRTUAL, 0).add2(index); gen.emitPop(); } else { if(hostType().needsSuperEnclosing()) { if(hostType().needsEnclosing()) gen.emit(Bytecode.ALOAD_2); else gen.emit(Bytecode.ALOAD_1); } else { emitThis(gen, superConstructorQualifier(c.hostType().enclosingType())); } } } // args for (int i = 0; i < getNumArg(); ++i) { getArg(i).createBCode(gen); getArg(i).type().emitCastTo(gen, decl().getParameter(i).type()); // MethodInvocationConversion } if(decl().isPrivate() && decl().hostType() != hostType()) { gen.emit(Bytecode.ACONST_NULL); decl().createAccessor().emitInvokeConstructor(gen); } else { decl().emitInvokeConstructor(gen); } } // 15.9.2 private void ClassInstanceExpr.emitLocalEnclosing(CodeGeneration gen, TypeDecl localClass) { if(!localClass.inStaticContext()) { emitThis(gen, localClass.enclosingType()); } } private void ClassInstanceExpr.emitInnerMemberEnclosing(CodeGeneration gen, TypeDecl innerClass) { if(hasPrevExpr()) { prevExpr().createBCode(gen); gen.emitDup(); int index = gen.constantPool().addMethodref("java/lang/Object", "getClass", "()Ljava/lang/Class;"); gen.emit(Bytecode.INVOKEVIRTUAL, 0).add2(index); gen.emitPop(); } else { TypeDecl enclosing = hostType(); while(enclosing != null && !enclosing.hasType(innerClass.name())) enclosing = enclosing.enclosingType(); if(enclosing == null) throw new Error(errorPrefix() + "Could not find enclosing for " + this); else emitThis(gen, enclosing); } } public void ClassInstanceExpr.createBCode(CodeGeneration gen) { type().emitNew(gen); type().emitDup(gen); // 15.9.2 first part if(type().isAnonymous()) { if(type().isAnonymousInNonStaticContext()) { if(type().inExplicitConstructorInvocation()) gen.emit(Bytecode.ALOAD_1); else gen.emit(Bytecode.ALOAD_0); } // 15.9.2 second part ClassDecl C = (ClassDecl)type(); TypeDecl S = C.superclass(); if(S.isLocalClass()) { if(!type().inStaticContext()) emitLocalEnclosing(gen, S); } else if(S.isInnerType()) { emitInnerMemberEnclosing(gen, S); } } else if(type().isLocalClass()) { if(!type().inStaticContext()) emitLocalEnclosing(gen, type()); } else if(type().isInnerType()) { emitInnerMemberEnclosing(gen, type()); } /* // 15.9.2 first part if(type().isAnonymous()) { if(type().isAnonymousInNonStaticContext()) { if(type().inExplicitConstructorInvocation()) gen.emit(Bytecode.ALOAD_1); else gen.emit(Bytecode.ALOAD_0); } if(type().needsSuperEnclosing()) { // 15.9.2 second part ClassDecl C = (ClassDecl)type(); TypeDecl S = C.superclass(); if(S.isLocalClass()) { emitLocalEnclosing(gen, S); } else if(S.isInnerType()) { emitInnerMemberEnclosing(gen, S); } } } else if(type().isLocalClass()) { emitLocalEnclosing(gen, type()); } else if(type().isInnerType()) { emitInnerMemberEnclosing(gen, type()); } */ for (int i = 0; i < getNumArg(); ++i) { getArg(i).createBCode(gen); getArg(i).type().emitCastTo(gen, decl().getParameter(i).type()); // MethodInvocationConversion } if(decl().isPrivate() && type() != hostType()) { gen.emit(Bytecode.ACONST_NULL); decl().createAccessor().emitInvokeConstructor(gen); } else { decl().emitInvokeConstructor(gen); } } public void ArrayCreationExpr.createBCode(CodeGeneration gen) { if(hasArrayInit()){ getArrayInit().createBCode(gen); } else { getTypeAccess().createBCode(gen); // push array sizes if(type().componentType().isPrimitive()) { gen.emit(Bytecode.NEWARRAY).add(type().componentType().arrayPrimitiveTypeDescriptor()); } else { if(numArrays() == 1) { String n = type().componentType().arrayTypeDescriptor(); int index = gen.constantPool().addClass(n); gen.emit(Bytecode.ANEWARRAY).add2(index); } else { String n = type().arrayTypeDescriptor(); int index = gen.constantPool().addClass(n); gen.emit(Bytecode.MULTIANEWARRAY, 1 - numArrays()).add2(index).add(numArrays()); } } } } public void ArrayInit.createBCode(CodeGeneration gen) { IntegerLiteral.push(gen, getNumInit()); if(type().componentType().isPrimitive()) { gen.emit(Bytecode.NEWARRAY).add(type().componentType().arrayPrimitiveTypeDescriptor()); } else { String n = type().componentType().arrayTypeDescriptor(); int index = gen.constantPool().addClass(n); gen.emit(Bytecode.ANEWARRAY).add2(index); } for(int i = 0; i < getNumInit(); i++) { gen.emitDup(); IntegerLiteral.push(gen, i); getInit(i).createBCode(gen); if(getInit(i) instanceof ArrayInit) gen.emit(Bytecode.AASTORE); else { getInit(i).type().emitAssignConvTo(gen, expectedType()); // AssignConversion gen.emit(expectedType().arrayStore()); }
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -