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

📄 classwriter.java

📁 GJC编译器的源代码。是一个开放源代码的工业级编译器。
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            return sym.name;
    }

    /**
      * Given a symbol, return its name-and-type.
      */
    NameAndType nameType(Symbol sym) {
        return new NameAndType(fieldName(sym),
                retrofit ? sym.erasure() : sym.externalType());
    }

    /**
      * Write header for an attribute to data buffer and return
      *  position past attribute length index.
      */
    int writeAttr(Name attrName) {
        databuf.appendChar(pool.put(attrName));
        databuf.appendInt(0);
        return databuf.length;
    }

    /**
      * Fill in attribute length.
      */
    void endAttr(int index) {
        putInt(databuf, index - 4, databuf.length - index);
    }

    /**
      * Leave space for attribute count and return index for
      *  number of attributes field.
      */
    int beginAttrs() {
        databuf.appendChar(0);
        return databuf.length;
    }

    /**
      * Fill in number of attributes.
      */
    void endAttrs(int index, int count) {
        putChar(databuf, index - 2, count);
    }

    /**
      * Write flag attributes; return number of attributes written.
      */
    int writeFlagAttrs(long flags) {
        int acount = 0;
        if ((flags & DEPRECATED) != 0) {
            int alenIdx = writeAttr(names.Deprecated);
            endAttr(alenIdx);
            acount++;
        }
        if ((flags & SYNTHETIC) != 0) {
            int alenIdx = writeAttr(names.Synthetic);
            endAttr(alenIdx);
            acount++;
        }
        return acount;
    }

    /**
      * Write member (field or method) attributes;
      *  return number of attributes written.
      */
    int writeMemberAttrs(Symbol sym) {
        int acount = writeFlagAttrs(sym.flags());
        return acount;
    }

    /**
      * Enter an inner class into the `innerClasses' set/queue.
      */
    void enterInner(ClassSymbol c) {
        assert (c.flags() & COMPOUND) == 0;
        if (c.type.tag != CLASS)
            return;
        if (pool != null && c.owner.kind != PCK &&
                (innerClasses == null || !innerClasses.contains(c))) {
            if (c.owner.kind == TYP)
                enterInner((ClassSymbol) c.owner);
            pool.put(c);
            pool.put(c.name);
            if (innerClasses == null) {
                innerClasses = Set.make();
                innerClassesQueue = new ListBuffer();
                pool.put(names.InnerClasses);
            }
            innerClasses.put(c);
            innerClassesQueue.append(c);
        }
    }

    /**
      * Write "inner classes" attribute.
      */
    void writeInnerClasses() {
        int alenIdx = writeAttr(names.InnerClasses);
        databuf.appendChar(innerClassesQueue.length());
        for (List l = innerClassesQueue.toList(); l.nonEmpty(); l = l.tail) {
            ClassSymbol inner = (ClassSymbol) l.head;
            if (dumpInnerClassModifiers) {
                log.errWriter.println("INNERCLASS  " + inner.name);
                log.errWriter.println("---" + flagNames(inner.flags_field));
            }
            databuf.appendChar(pool.get(inner));
            databuf.appendChar(inner.owner.kind == TYP ? pool.get(inner.owner) : 0);
            databuf.appendChar(inner.name.len != 0 ? pool.get(inner.name) : 0);
            databuf.appendChar((int) inner.flags_field);
        }
        endAttr(alenIdx);
    }

    /**
      * Write field symbol, entering all references into constant pool.
      */
    void writeField(VarSymbol v) {
        databuf.appendChar((int) v.flags());
        if (dumpFieldModifiers) {
            log.errWriter.println("FIELD  " + fieldName(v));
            log.errWriter.println("---" + flagNames(v.flags()));
        }
        databuf.appendChar(pool.put(fieldName(v)));
        databuf.appendChar(pool.put(typeSig(v.erasure())));
        int acountIdx = beginAttrs();
        int acount = 0;
        if (v.constValue != null) {
            int alenIdx = writeAttr(names.ConstantValue);
            databuf.appendChar(pool.put(v.constValue));
            endAttr(alenIdx);
            acount++;
        }
        acount += writeMemberAttrs(v);
        endAttrs(acountIdx, acount);
    }

    /**
      * Write method symbol, entering all references into constant pool.
      */
    void writeMethod(MethodSymbol m) {
        databuf.appendChar((int) m.flags());
        if (dumpMethodModifiers) {
            log.errWriter.println("METHOD  " + fieldName(m));
            log.errWriter.println("---" + flagNames(m.flags()));
        }
        databuf.appendChar(pool.put(fieldName(m)));
        databuf.appendChar(pool.put(typeSig(m.externalType())));
        int acountIdx = beginAttrs();
        int acount = 0;
        if (m.code != null) {
            int alenIdx = writeAttr(names.Code);
            writeCode(m.code);
            m.code = null;
            endAttr(alenIdx);
            acount++;
        }
        List thrown = m.erasure().thrown();
        if (thrown.nonEmpty()) {
            int alenIdx = writeAttr(names.Exceptions);
            databuf.appendChar(thrown.length());
            for (List l = thrown; l.nonEmpty(); l = l.tail)
                databuf.appendChar(pool.put(((Type) l.head).tsym));
            endAttr(alenIdx);
            acount++;
        }
        acount += writeMemberAttrs(m);
        endAttrs(acountIdx, acount);
    }

    /**
      * Write code attribute of method.
      */
    void writeCode(Code code) {
        databuf.appendChar(code.max_stack);
        databuf.appendChar(code.max_locals);
        databuf.appendInt(code.cp);
        databuf.appendBytes(code.code, 0, code.cp);
        databuf.appendChar(code.catchInfo.length());
        for (List l = code.catchInfo.toList(); l.nonEmpty(); l = l.tail) {
            for (int i = 0; i < ((char[]) l.head).length; i++)
                databuf.appendChar(((char[]) l.head)[i]);
        }
        int acountIdx = beginAttrs();
        int acount = 0;
        if (code.lineInfo.nonEmpty()) {
            int alenIdx = writeAttr(names.LineNumberTable);
            databuf.appendChar(code.lineInfo.length());
            for (List l = code.lineInfo.reverse(); l.nonEmpty(); l = l.tail)
                for (int i = 0; i < ((char[]) l.head).length; i++)
                    databuf.appendChar(((char[]) l.head)[i]);
            endAttr(alenIdx);
            acount++;
        }
        if (genCrt && (code.crt != null)) {
            CRTable crt = code.crt;
            int alenIdx = writeAttr(names.CharacterRangeTable);
            int crtIdx = beginAttrs();
            int crtEntries = crt.writeCRT(databuf);
            endAttrs(crtIdx, crtEntries);
            endAttr(alenIdx);
            acount++;
        }
        if (code.varBufferSize > 0) {
            int alenIdx = writeAttr(names.LocalVariableTable);
            int nvars = code.varBufferSize;
            databuf.appendChar(nvars);
            for (int i = 0; i < nvars; i++) {
                Code.LocalVar var = code.varBuffer[i];
                assert var.start_pc >= 0;
                assert var.start_pc <= code.cp;
                databuf.appendChar(var.start_pc);
                assert var.length >= 0;
                assert (var.start_pc + var.length) <= code.cp;
                databuf.appendChar(var.length);
                VarSymbol sym = var.var;
                databuf.appendChar(pool.put(sym.name));
                databuf.appendChar(pool.put(typeSig(sym.erasure())));
                databuf.appendChar(var.reg);
            }
            endAttr(alenIdx);
            acount++;
        }
        endAttrs(acountIdx, acount);
    }

    void writeFields(Scope.Entry e) {
        List vars = List.make();
        for (Scope.Entry i = e; i != null; i = i.sibling) {
            if (i.sym.kind == VAR)
                vars = vars.prepend((VarSymbol) i.sym);
        }
        while (vars.nonEmpty()) {
            writeField((VarSymbol) vars.head);
            vars = vars.tail;
        }
    }

    void writeMethods(Scope.Entry e) {
        List methods = List.make();
        for (Scope.Entry i = e; i != null; i = i.sibling) {
            if (i.sym.kind == MTH)
                methods = methods.prepend((MethodSymbol) i.sym);
        }
        while (methods.nonEmpty()) {
            writeMethod((MethodSymbol) methods.head);
            methods = methods.tail;
        }
    }

    /**
      * Emit a class file for a given class.
      *  @param c      The class from which a class file is generated.
      */
    public void writeClass(ClassSymbol c) throws IOException, PoolOverflow,
    StringOverflow {
        File outFile = outputFile(c, ".class");
        OutputStream out = new FileOutputStream(outFile);
        try {
            writeClassFile(out, c);
            if (verbose)
                log.errWriter.println( log.getLocalizedString("verbose.wrote.file",
                        outFile.getPath()));
            out.close();
            out = null;
        }
        finally { if (out != null) {
                      out.close();
                      outFile.delete();
                      out = null;
                  }
                } }

    /**
      * Write class `c' to outstream `out'.
      */
    public void writeClassFile(OutputStream out,
            ClassSymbol c) throws IOException, PoolOverflow, StringOverflow {
        assert (c.flags() & COMPOUND) == 0;
        databuf.reset();
        poolbuf.reset();
        sigbuf.reset();
        pool = c.pool;
        innerClasses = null;
        innerClassesQueue = null;
        Type supertype = c.type.supertype();
        List interfaces = c.type.interfaces();
        long flags = c.flags();
        if ((flags & PROTECTED) != 0)
            flags |= PUBLIC;
        flags = flags & ClassFlags & ~STRICTFP;
        if ((flags & INTERFACE) == 0)
            flags |= ACC_SUPER;
        if (dumpClassModifiers) {
            log.errWriter.println();
            log.errWriter.println("CLASSFILE  " + c.fullName());
            log.errWriter.println("---" + flagNames(flags));
        }
        databuf.appendChar((int) flags);
        databuf.appendChar(pool.put(c));
        databuf.appendChar(supertype.tag == CLASS ? pool.put(supertype.tsym) : 0);
        databuf.appendChar(interfaces.length());
        for (List l = interfaces; l.nonEmpty(); l = l.tail)
            databuf.appendChar(pool.put(((Type) l.head).tsym));
        int fieldsCount = 0;
        int methodsCount = 0;
        for (Scope.Entry e = c.members().elems; e != null; e = e.sibling) {
            switch (e.sym.kind) {
            case VAR:
                fieldsCount++;
                break;

            case MTH:
                methodsCount++;
                break;

            case TYP:
                enterInner((ClassSymbol) e.sym);
                break;

            default:
                assert false;

            }
        }
        databuf.appendChar(fieldsCount);
        writeFields(c.members().elems);
        databuf.appendChar(methodsCount);
        writeMethods(c.members().elems);
        int acountIdx = beginAttrs();
        int acount = 0;
        if (c.sourcefile != null && emitSourceFile) {
            int alenIdx = writeAttr(names.SourceFile);
            String filename = c.sourcefile.toString();
            int sepIdx = filename.lastIndexOf(File.separatorChar);
            int slashIdx = filename.lastIndexOf('/');
            if (slashIdx > sepIdx)
                sepIdx = slashIdx;
            if (sepIdx >= 0)
                filename = filename.substring(sepIdx + 1);
            databuf.appendChar(c.pool.put(names.fromString(filename)));
            endAttr(alenIdx);
            acount++;
        }
        if (genCrt) {
            int alenIdx = writeAttr(names.SourceID);
            databuf.appendChar( c.pool.put(
                    names.fromString(Long.toString(getLastModified(c.sourcefile)))));
            endAttr(alenIdx);
            acount++;
            alenIdx = writeAttr(names.CompilationID);
            databuf.appendChar( c.pool.put(
                    names.fromString(Long.toString(System.currentTimeMillis()))));
            endAttr(alenIdx);
            acount++;
        }
        acount += writeFlagAttrs(c.flags());
        poolbuf.appendInt(JAVA_MAGIC);
        poolbuf.appendChar(target.minorVersion);
        poolbuf.appendChar(target.majorVersion);
        writePool(c.pool);
        if (innerClasses != null) {
            writeInnerClasses();
            acount++;
        }
        endAttrs(acountIdx, acount);
        poolbuf.appendBytes(databuf.elems, 0, databuf.length);
        out.write(poolbuf.elems, 0, poolbuf.length);
        pool = c.pool = null;
    }

    /**
      * Get modification date of file entry with name filename
      */
    long getLastModified(Name filename) {
        long mod = 0;
        File file = new File(filename.toString());
        try {
            mod = file.lastModified();
        } catch (SecurityException e) {
            throw new AssertionError(
                    "CRT: couldn\'t get source file modification date: " +
                    e.getMessage());
        }
        return mod;
    }

    /**
      * Create output file with given extension for given class.
      */
    public File outputFile(ClassSymbol c, String extension) throws IOException {
        if (outDir == null) {
            String filename = Convert.shortName(c.flatname) + extension;
            if (c.sourcefile == null)
                return new File(filename);
            String sourcedir = new File(c.sourcefile.toString()).getParent();
            if (sourcedir == null)
                return new File(filename);
            else
                return new File(sourcedir, filename);
        } else {
            return outputFile(outDir, c.flatname.toString(), extension);
        }
    }

    /**
      * open file given by a fully qualified name from root directory `outdir'.
      *  create intermediate directories if they don't exist already
      */
    File outputFile(File outdir, String name, String extension) throws IOException {
        int start = 0;
        int end = name.indexOf('.');
        while (end >= start) {
            outdir = new File(outdir, name.substring(start, end));
            if (!outdir.exists())
                outdir.mkdir();
            start = end + 1;
            end = name.indexOf('.', start);
        }
        return new File(outdir, name.substring(start) + extension);
    }
}

⌨️ 快捷键说明

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