?? createbcode.jrag
字號(hào):
/* * The JastAdd Extensible Java Compiler (http://jastadd.org) is covered * by the modified BSD License. You should have received a copy of the * modified BSD license with this compiler. * * Copyright (c) 2005-2008, Torbjorn Ekman * All rights reserved. */import java.util.*;import java.io.*;aspect CreateBCode { inh TypeDecl CatchClause.hostType(); syn lazy boolean TypeDecl.hasClinit() { for(int i = 0; i < getNumBodyDecl(); i++) { BodyDecl b = getBodyDecl(i); if(b instanceof FieldDeclaration) { FieldDeclaration f = (FieldDeclaration)b; if(f.isStatic() && f.hasInit()) { return true; } } else if(b instanceof StaticInitializer) { return true; } } return false; } syn lazy CodeGeneration TypeDecl.bytecodes(ConstantPool constantPool) { CodeGeneration gen = new CodeGeneration(constantPool); generateBytecodes(gen); if(!gen.numberFormatError()) return gen; gen = new CodeGeneration(constantPool, true); generateBytecodes(gen); if(!gen.numberFormatError()) return gen; throw new Error("Could not generate code for initializers in " + hostType().typeName()); } private void TypeDecl.generateBytecodes(CodeGeneration gen) { for(int i = 0; i < getNumBodyDecl(); i++) { BodyDecl b = getBodyDecl(i); if(b instanceof FieldDeclaration && b.isBytecodeField() && b.generate()) { FieldDeclaration f = (FieldDeclaration)b; if(f.isStatic() && f.hasInit()) { f.getInit().createBCode(gen); f.getInit().type().emitAssignConvTo(gen, f.type()); // AssignConversion f.emitStoreField(gen, this); } } else if(b instanceof StaticInitializer) { b.createBCode(gen); } } gen.emitReturn(); } syn lazy CodeGeneration MethodDecl.bytecodes(ConstantPool constantPool) { //if(Program.verbose()) // System.out.println("Generating bytecodes for " + signature() + " in " + hostType().fullName()); CodeGeneration gen = new CodeGeneration(constantPool); generateBytecodes(gen); if(!gen.numberFormatError()) return gen; gen = new CodeGeneration(constantPool, true); generateBytecodes(gen); if(!gen.numberFormatError()) return gen; throw new Error("Could not generate code for " + signature() + " in " + hostType().typeName()); } private void MethodDecl.generateBytecodes(CodeGeneration gen) { int label = gen.variableScopeLabel(); if(!isStatic()) gen.addLocalVariableEntryAtCurrentPC("this", hostType().typeDescriptor(), 0, label); for(int i = 0; i < getNumParameter(); i++) { ParameterDeclaration p = (ParameterDeclaration)getParameter(i); gen.addLocalVariableEntryAtCurrentPC( p.name(), p.type().typeDescriptor(), p.localNum(), label ); } createBCode(gen); if(type() instanceof VoidType) // TODO: canCompleteNormally check as well gen.emitReturn(); gen.addVariableScopeLabel(label); } syn lazy CodeGeneration ConstructorDecl.bytecodes(ConstantPool constantPool) { CodeGeneration gen = new CodeGeneration(constantPool); generateBytecodes(gen); if(!gen.numberFormatError()) return gen; gen = new CodeGeneration(constantPool, true); generateBytecodes(gen); if(!gen.numberFormatError()) return gen; throw new Error("Could not generate code for " + signature() + " in " + hostType().typeName()); } private void ConstructorDecl.generateBytecodes(CodeGeneration gen) { int label = gen.variableScopeLabel(); gen.addLocalVariableEntryAtCurrentPC("this", hostType().typeDescriptor(), 0, label); for(int i = 0; i < getNumParameter(); i++) { ParameterDeclaration p = (ParameterDeclaration)getParameter(i); gen.addLocalVariableEntryAtCurrentPC( p.name(), p.type().typeDescriptor(), p.localNum(), label ); } createBCode(gen); gen.emitReturn(); gen.addVariableScopeLabel(label); } public void MethodDecl.createBCode(CodeGeneration gen) { try { if(hasBlock()) { gen.maxLocals = Math.max(gen.maxLocals, getBlock().localNum()); getBlock().createBCode(gen); } } catch (Error e) { System.err.println(hostType().typeName() + ": " + this); throw e; } } public void ConstructorDecl.createBCode(CodeGeneration gen) { try { boolean needsInit = true; if(hasConstructorInvocation()) { getConstructorInvocation().createBCode(gen); Stmt stmt = getConstructorInvocation(); if(stmt instanceof ExprStmt) { ExprStmt exprStmt = (ExprStmt)stmt; Expr expr = exprStmt.getExpr(); if(!expr.isSuperConstructorAccess()) needsInit = false; } } if(needsEnclosing()) { gen.emitLoadReference(0); gen.emitLoadReference(1); String classname = hostType().constantPoolName(); String desc = enclosing().typeDescriptor(); String name = "this$0"; int index = gen.constantPool().addFieldref(classname, name, desc); gen.emit(Bytecode.PUTFIELD, -2).add2(index); } int localIndex = offsetFirstEnclosingVariable(); for(Iterator iter = hostType().enclosingVariables().iterator(); iter.hasNext(); ) { Variable v = (Variable)iter.next(); gen.emitLoadReference(0); v.type().emitLoadLocal(gen, localIndex); 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.PUTFIELD, -1 - v.type().variableSize()).add2(index); localIndex += v.type().variableSize(); } if(needsInit) { TypeDecl typeDecl = hostType(); for(int i = 0; i < typeDecl.getNumBodyDecl(); i++) { BodyDecl b = typeDecl.getBodyDecl(i); if(b instanceof FieldDeclaration && b.isBytecodeField() && b.generate()) { FieldDeclaration f = (FieldDeclaration)b; if(!f.isStatic() && f.hasInit()) { gen.emit(Bytecode.ALOAD_0); f.getInit().createBCode(gen); f.getInit().type().emitAssignConvTo(gen, f.type()); // AssignConversion f.emitStoreField(gen, hostType()); } } else if(b instanceof InstanceInitializer) { b.createBCode(gen); } } } gen.maxLocals = Math.max(gen.maxLocals, getBlock().localNum()); getBlock().createBCode(gen); } catch (Error e) { System.err.println(hostType().typeName() + ": " + this); throw e; } } public void ASTNode.createBCode(CodeGeneration gen) { for (int i=0; i<getNumChild(); i++) getChild(i).createBCode(gen); } public void Literal.createBCode(CodeGeneration gen) { emitPushConstant(gen); } protected boolean Expr.needsPush() { ASTNode n = getParent(); while(n instanceof ParExpr) n = n.getParent(); return !(n instanceof ExprStmt); } syn boolean ExprStmt.needsPop() = getExpr().needsPop(); syn boolean Expr.needsPop() = true; eq AbstractDot.needsPop() = lastAccess().needsPop(); eq ConstructorAccess.needsPop() = false; eq ParExpr.needsPop() = getExpr().needsPop(); eq AssignExpr.needsPop() = false; // if dest is instance variable that needs accessor eq PreIncExpr.needsPop() = false; eq PostIncExpr.needsPop() = false; eq PreDecExpr.needsPop() = false; eq PostDecExpr.needsPop() = false; public void VariableDeclaration.createBCode(CodeGeneration gen) { super.createBCode(gen); if(hasInit()) { gen.addLocalVariableEntryAtCurrentPC(name(), type().typeDescriptor(), localNum(), variableScopeEndLabel(gen)); getInit().createBCode(gen); getInit().type().emitAssignConvTo(gen, type()); // AssignConversion type().emitStoreLocal(gen, localNum()); } } // simple assign expression public void AssignSimpleExpr.createBCode(CodeGeneration gen) { getDest().createAssignSimpleLoadDest(gen); getSource().createBCode(gen); getSource().type().emitAssignConvTo(gen, getDest().type()); // AssignConversion if(needsPush()) { getDest().createPushAssignmentResult(gen); } getDest().emitStore(gen); } // compund assign expression public void AssignExpr.createBCode(CodeGeneration gen) { TypeDecl dest = getDest().type(); TypeDecl source = getSource().type(); TypeDecl type; if(dest.isNumericType() && source.isNumericType()) type = dest.binaryNumericPromotion(source); else type = dest; getDest().createAssignLoadDest(gen); dest.emitCastTo(gen, type); getSource().createBCode(gen); source.emitCastTo(gen, type); createAssignOp(gen, type); type.emitCastTo(gen, dest); if(needsPush()) { getDest().createPushAssignmentResult(gen); } getDest().emitStore(gen); } // string addition assign expression public void AssignPlusExpr.createBCode(CodeGeneration gen) { TypeDecl dest = getDest().type(); TypeDecl source = getSource().type(); if(dest.isString()) { getDest().createAssignLoadDest(gen); // new StringBuffer() TypeDecl stringBuffer = lookupType("java.lang", "StringBuffer"); String classname = stringBuffer.constantPoolName(); String desc; int index; TypeDecl argumentType; stringBuffer.emitNew(gen); // new StringBuffer gen.emitDup(); // dup desc = "()V"; index = gen.constantPool().addMethodref(classname, "<init>", desc); gen.emit(Bytecode.INVOKESPECIAL, -1).add2(index); // invokespecial StringBuffer() gen.emitSwap(); // append argumentType = dest.stringPromotion(); desc = "(" + argumentType.typeDescriptor() + ")" + stringBuffer.typeDescriptor(); index = gen.constantPool().addMethodref(classname, "append", desc); gen.emit(Bytecode.INVOKEVIRTUAL, -argumentType.variableSize()).add2(index); // StringBuffer.append getSource().createBCode(gen); // typed append argumentType = source.stringPromotion(); desc = "(" + argumentType.typeDescriptor() + ")" + stringBuffer.typeDescriptor(); index = gen.constantPool().addMethodref(classname, "append", desc); gen.emit(Bytecode.INVOKEVIRTUAL, -argumentType.variableSize()).add2(index); // StringBuffer.append // toString desc = "()" + type().typeDescriptor(); index = gen.constantPool().addMethodref(classname, "toString", desc); gen.emit(Bytecode.INVOKEVIRTUAL, 0).add2(index); // StringBuffer.toString if(needsPush()) { getDest().createPushAssignmentResult(gen); } getDest().emitStore(gen); } else { super.createBCode(gen); } } // shift assign expression public void AssignExpr.emitShiftExpr(CodeGeneration gen) { TypeDecl dest = getDest().type(); TypeDecl source = getSource().type(); TypeDecl type = dest.unaryNumericPromotion(); getDest().createAssignLoadDest(gen); dest.emitCastTo(gen, type); getSource().createBCode(gen); source.emitCastTo(gen, typeInt()); createAssignOp(gen, type); type.emitCastTo(gen, dest); if(needsPush()) { getDest().createPushAssignmentResult(gen); } getDest().emitStore(gen); } public void AssignLShiftExpr.createBCode(CodeGeneration gen) { emitShiftExpr(gen); } public void AssignRShiftExpr.createBCode(CodeGeneration gen) { emitShiftExpr(gen); } public void AssignURShiftExpr.createBCode(CodeGeneration gen) { emitShiftExpr(gen); } // load left hand side of destination in a simple assign expression public void Expr.createAssignSimpleLoadDest(CodeGeneration gen) { } public void AbstractDot.createAssignSimpleLoadDest(CodeGeneration gen) { lastAccess().createAssignSimpleLoadDest(gen); } public void VarAccess.createAssignSimpleLoadDest(CodeGeneration gen) { createLoadQualifier(gen); } public void ArrayAccess.createAssignSimpleLoadDest(CodeGeneration gen) { prevExpr().createBCode(gen); getExpr().createBCode(gen); } // duplicate top value on stack and store below destination element public void Expr.createPushAssignmentResult(CodeGeneration gen) { } public void AbstractDot.createPushAssignmentResult(CodeGeneration gen) { lastAccess().createPushAssignmentResult(gen); } public void VarAccess.createPushAssignmentResult(CodeGeneration gen) { if(hostType().needsAccessorFor(decl())) return; if(decl().isInstanceVariable()) type().emitDup_x1(gen); else type().emitDup(gen); } public void ArrayAccess.createPushAssignmentResult(CodeGeneration gen) { type().emitDup_x2(gen); } // load left hand side of destination in a compound assign expression public void Expr.createAssignLoadDest(CodeGeneration gen) { } public void AbstractDot.createAssignLoadDest(CodeGeneration gen) { lastAccess().createAssignLoadDest(gen); } public void VarAccess.createAssignLoadDest(CodeGeneration gen) { createLoadQualifier(gen); Variable v = decl(); if(v.isInstanceVariable()) gen.emitDup(); if(v instanceof VariableDeclaration) { VariableDeclaration decl = (VariableDeclaration)v; decl.type().emitLoadLocal(gen, decl.localNum()); } else if(v instanceof ParameterDeclaration) { ParameterDeclaration decl = (ParameterDeclaration)v; decl.type().emitLoadLocal(gen, decl.localNum()); } else if(v instanceof FieldDeclaration) { FieldDeclaration f = (FieldDeclaration)v; if(f.isPrivate() && !hostType().hasField(v.name())) f.createAccessor(fieldQualifierType()).emitInvokeMethod(gen, fieldQualifierType()); else f.emitLoadField(gen, fieldQualifierType()); } } public void ArrayAccess.createAssignLoadDest(CodeGeneration gen) { prevExpr().createBCode(gen); gen.emitDup(); getExpr().createBCode(gen); typeInt().emitDup_x1(gen);
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -