예제 #1
0
  // string addition assign expression
  public void 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);
    }
  }
예제 #2
0
  /**
   * @ast method
   * @aspect GenerateClassfile
   * @declaredat /home/uoji/JastAddJ/Java1.4Backend/GenerateClassfile.jrag:142
   */
  public void generateClassfile() {
    super.generateClassfile();
    String fileName = destinationPath() + File.separator + constantPoolName() + ".class";
    if (options().verbose()) System.out.println("Writing class file to " + fileName);
    try {
      ConstantPool cp = constantPool();
      // force building of constant pool
      cp.addClass(constantPoolName());
      cp.addClass("java/lang/Object");
      for (int i = 0; i < getNumSuperInterfaceId(); i++) {
        cp.addClass(getSuperInterfaceId(i).type().constantPoolName());
      }
      for (Iterator iter = bcFields().iterator(); iter.hasNext(); ) {
        FieldDeclaration field = (FieldDeclaration) iter.next();
        cp.addUtf8(field.name());
        cp.addUtf8(field.type().typeDescriptor());
        field.attributes();
      }
      for (Iterator iter = bcMethods().iterator(); iter.hasNext(); ) {
        Object obj = iter.next();
        if (obj instanceof MethodDecl) {
          MethodDecl m = (MethodDecl) obj;
          cp.addUtf8(m.name());
          cp.addUtf8(m.descName());
          m.attributes();
        }
      }
      attributes();

      if (hasClinit()) {
        cp.addUtf8("<clinit>");
        cp.addUtf8("()V");
        clinit_attributes();
      }

      // actual classfile generation
      File dest = new File(fileName);
      File parentFile = dest.getParentFile();
      if (parentFile != null) parentFile.mkdirs();

      FileOutputStream f = new FileOutputStream(fileName);
      DataOutputStream out = new DataOutputStream(new BufferedOutputStream(f));
      out.writeInt(magicHeader());
      out.writeChar(minorVersion());
      out.writeChar(majorVersion());
      cp.emit(out);
      int flags = flags();
      if (isNestedType()) flags = mangledFlags(flags);
      if (isInterfaceDecl()) flags |= Modifiers.ACC_INTERFACE;
      out.writeChar(flags);
      out.writeChar(cp.addClass(constantPoolName()));
      out.writeChar(cp.addClass("java/lang/Object"));
      if (getNumSuperInterfaceId() == 1 && getSuperInterfaceId(0).type().isObject())
        out.writeChar(0);
      else out.writeChar(getNumSuperInterfaceId());
      for (int i = 0; i < getNumSuperInterfaceId(); i++) {
        TypeDecl typeDecl = getSuperInterfaceId(i).type();
        if (typeDecl.isInterfaceDecl()) out.writeChar(cp.addClass(typeDecl.constantPoolName()));
      }
      Collection fields = bcFields();
      out.writeChar(fields.size());
      for (Iterator iter = fields.iterator(); iter.hasNext(); ) {
        FieldDeclaration field = (FieldDeclaration) iter.next();
        out.writeChar(field.flags());
        out.writeChar(cp.addUtf8(field.name()));
        out.writeChar(cp.addUtf8(field.type().typeDescriptor()));
        out.writeChar(field.attributes().size());
        for (Iterator itera = field.attributes().iterator(); itera.hasNext(); )
          ((Attribute) itera.next()).emit(out);
      }
      Collection methods = bcMethods();
      out.writeChar(methods.size() + (hasClinit() ? 1 : 0));
      for (Iterator iter = methods.iterator(); iter.hasNext(); ) {
        BodyDecl b = (BodyDecl) iter.next();
        b.generateMethod(out, cp);
      }
      if (hasClinit()) {
        out.writeChar(Modifiers.ACC_STATIC);
        out.writeChar(cp.addUtf8("<clinit>"));
        out.writeChar(cp.addUtf8("()V"));
        out.writeChar(clinit_attributes().size());
        for (Iterator itera = clinit_attributes().iterator(); itera.hasNext(); )
          ((Attribute) itera.next()).emit(out);
      }
      out.writeChar(attributes().size());
      for (Iterator itera = attributes().iterator(); itera.hasNext(); )
        ((Attribute) itera.next()).emit(out);

      out.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }