⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 createbcode.jrag

📁 JDK1.4编译器后端
💻 JRAG
📖 第 1 页 / 共 4 页
字号:
/* * 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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -