2674 lines · 109.2 KB · Java
RawDownload
                                               new ThrowStatement(w, e));        Statement handlers[] = { handler };        body = new TryStatement(w, body, handlers);         Type mtype = Type.tMethod(Type.tClassDesc, strarg);        IdentifierToken args[] = { arg };         // Use default (package) access.  If private, an access method would        // be needed in the event that the class literal belonged to an interface.        // Also, making it private tickles bug 4098316.        lookup = toplevelEnv.makeMemberDefinition(toplevelEnv, w,                                                  c, null,                                                  M_STATIC | M_SYNTHETIC,                                                  mtype, idDClass,                                                  args, null, body);         // If a new class was created to contain the helper method,        // check it now.        if (needNewClass) {            if (c.getClassDeclaration().getStatus() == CS_CHECKED) {                throw new CompilerError("duplicate check");            }            c.getClassDeclaration().setDefinition(c, CS_PARSED);            Expression argsX[] = {};            Type argTypesX[] = {};            try {                ClassDefinition sup =                    toplevelEnv.getClassDefinition(idJavaLangObject);                c.checkLocalClass(toplevelEnv, null,                                  new Vset(), sup, argsX, argTypesX);            } catch (ClassNotFound ee) {};        }         return lookup;    }      /**     * A list of active ongoing compilations. This list     * is used to stop two compilations from saving the     * same class.     */    private static Vector active = new Vector();     /**     * Compile this class     */    public void compile(OutputStream out)                throws InterruptedException, IOException {        Environment env = toplevelEnv;        synchronized (active) {            while (active.contains(getName())) {                active.wait();            }            active.addElement(getName());        }         try {            compileClass(env, out);        } catch (ClassNotFound e) {            throw new CompilerError(e);        } finally {            synchronized (active) {                active.removeElement(getName());                active.notifyAll();            }        }    }     /**     * Verify that the modifier bits included in 'required' are     * all present in 'mods', otherwise signal an internal error.     * Note that errors in the source program may corrupt the modifiers,     * thus we rely on the fact that 'CompilerError' exceptions are     * silently ignored after an error message has been issued.     */    private static void assertModifiers(int mods, int required) {        if ((mods & required) != required) {            throw new CompilerError("illegal class modifiers");        }    }     protected void compileClass(Environment env, OutputStream out)                throws IOException, ClassNotFound {        Vector variables = new Vector();        Vector methods = new Vector();        Vector innerClasses = new Vector();        CompilerMember init = new CompilerMember(new MemberDefinition(getWhere(), this, M_STATIC, Type.tMethod(Type.tVoid), idClassInit, null, null), new Assembler());        Context ctx = new Context((Context)null, init.field);         for (ClassDefinition def = this; def.isInnerClass(); def = def.getOuterClass()) {            innerClasses.addElement(def);        }        // Reverse the order, so that outer levels come first:        int ncsize = innerClasses.size();        for (int i = ncsize; --i >= 0; )            innerClasses.addElement(innerClasses.elementAt(i));        for (int i = ncsize; --i >= 0; )            innerClasses.removeElementAt(i);         // System.out.println("compile class " + getName());         boolean haveDeprecated = this.isDeprecated();        boolean haveSynthetic = this.isSynthetic();        boolean haveConstantValue = false;        boolean haveExceptions = false;         // Generate code for all fields        for (SourceMember field = (SourceMember)getFirstMember();             field != null;             field = (SourceMember)field.getNextMember()) {             //System.out.println("compile field " + field.getName());             haveDeprecated |= field.isDeprecated();            haveSynthetic |= field.isSynthetic();             try {                if (field.isMethod()) {                    haveExceptions |=                        (field.getExceptions(env).length > 0);                     if (field.isInitializer()) {                        if (field.isStatic()) {                            field.code(env, init.asm);                        }                    } else {                        CompilerMember f =                            new CompilerMember(field, new Assembler());                        field.code(env, f.asm);                        methods.addElement(f);                    }                } else if (field.isInnerClass()) {                    innerClasses.addElement(field.getInnerClass());                } else if (field.isVariable()) {                    field.inline(env);                    CompilerMember f = new CompilerMember(field, null);                    variables.addElement(f);                    if (field.isStatic()) {                        field.codeInit(env, ctx, init.asm);                     }                    haveConstantValue |=                        (field.getInitialValue() != null);                }            } catch (CompilerError ee) {                ee.printStackTrace();                env.error(field, 0, "generic",                          field.getClassDeclaration() + ":" + field +                          "@" + ee.toString(), null, null);            }        }        if (!init.asm.empty()) {           init.asm.add(getWhere(), opc_return, true);            methods.addElement(init);        }         // bail out if there were any errors        if (getNestError()) {            return;        }         int nClassAttrs = 0;         // Insert constants        if (methods.size() > 0) {            tab.put("Code");        }        if (haveConstantValue) {            tab.put("ConstantValue");        }         String sourceFile = null;        if (env.debug_source()) {            sourceFile = ((ClassFile)getSource()).getName();            tab.put("SourceFile");            tab.put(sourceFile);            nClassAttrs += 1;        }         if (haveExceptions) {            tab.put("Exceptions");        }         if (env.debug_lines()) {            tab.put("LineNumberTable");        }        if (haveDeprecated) {            tab.put("Deprecated");            if (this.isDeprecated()) {                nClassAttrs += 1;            }        }        if (haveSynthetic) {            tab.put("Synthetic");            if (this.isSynthetic()) {                nClassAttrs += 1;            }        }// JCOV        if (env.coverage()) {            nClassAttrs += 2;           // AbsoluteSourcePath, TimeStamp            tab.put("AbsoluteSourcePath");            tab.put("TimeStamp");            tab.put("CoverageTable");        }// end JCOV        if (env.debug_vars()) {            tab.put("LocalVariableTable");        }        if (innerClasses.size() > 0) {            tab.put("InnerClasses");            nClassAttrs += 1;           // InnerClasses        } // JCOV        String absoluteSourcePath = "";        long timeStamp = 0;         if (env.coverage()) {                absoluteSourcePath = getAbsoluteName();                timeStamp = System.currentTimeMillis();                tab.put(absoluteSourcePath);        }// end JCOV        tab.put(getClassDeclaration());        if (getSuperClass() != null) {            tab.put(getSuperClass());        }        for (int i = 0 ; i < interfaces.length ; i++) {            tab.put(interfaces[i]);        }         // Sort the methods in order to make sure both constant pool        // entries and methods are in a deterministic order from run        // to run (this allows comparing class files for a fixed point        // to validate the compiler)        CompilerMember[] ordered_methods =            new CompilerMember[methods.size()];        methods.copyInto(ordered_methods);        java.util.Arrays.sort(ordered_methods);        for (int i=0; i<methods.size(); i++)            methods.setElementAt(ordered_methods[i], i);         // Optimize Code and Collect method constants        for (Enumeration e = methods.elements() ; e.hasMoreElements() ; ) {            CompilerMember f = (CompilerMember)e.nextElement();            try {                f.asm.optimize(env);                f.asm.collect(env, f.field, tab);                tab.put(f.name);                tab.put(f.sig);                ClassDeclaration exp[] = f.field.getExceptions(env);                for (int i = 0 ; i < exp.length ; i++) {                    tab.put(exp[i]);                }            } catch (Exception ee) {                ee.printStackTrace();                env.error(f.field, -1, "generic", f.field.getName() + "@" + ee.toString(), null, null);                f.asm.listing(System.out);            }        }         // Collect field constants        for (Enumeration e = variables.elements() ; e.hasMoreElements() ; ) {            CompilerMember f = (CompilerMember)e.nextElement();            tab.put(f.name);            tab.put(f.sig);             Object val = f.field.getInitialValue();            if (val != null) {                tab.put((val instanceof String) ? new StringExpression(f.field.getWhere(), (String)val) : val);            }        }         // Collect inner class constants        for (Enumeration e = innerClasses.elements();             e.hasMoreElements() ; ) {            ClassDefinition inner = (ClassDefinition)e.nextElement();            tab.put(inner.getClassDeclaration());             // If the inner class is local, we do not need to add its            // outer class here -- the outer_class_info_index is zero.            if (!inner.isLocal()) {                ClassDefinition outer = inner.getOuterClass();                tab.put(outer.getClassDeclaration());            }             // If the local name of the class is idNull, don't bother to            // add it to the constant pool.  We won't need it.            Identifier inner_local_name = inner.getLocalName();            if (inner_local_name != idNull) {                tab.put(inner_local_name.toString());            }        }         // Write header        DataOutputStream data = new DataOutputStream(out);        data.writeInt(JAVA_MAGIC);        data.writeShort(toplevelEnv.getMinorVersion());        data.writeShort(toplevelEnv.getMajorVersion());        tab.write(env, data);         // Write class information        int cmods = getModifiers() & MM_CLASS;         // Certain modifiers are implied:        // 1.  Any interface (nested or not) is implicitly deemed to be abstract,        //     whether it is explicitly marked so or not.  (Java 1.0.)        // 2.  A interface which is a member of a type is implicitly deemed to        //     be static, whether it is explicitly marked so or not.        // 3a. A type which is a member of an interface is implicitly deemed        //     to be public, whether it is explicitly marked so or not.        // 3b. A type which is a member of an interface is implicitly deemed        //     to be static, whether it is explicitly marked so or not.        // All of these rules are implemented in 'BatchParser.beginClass',        // but the results are verified here.         if (isInterface()) {            // Rule 1.            // The VM spec states that ACC_ABSTRACT must be set when            // ACC_INTERFACE is; this was not done by javac prior to 1.2,            // and the runtime compensates by setting it.  Making sure            // it is set here will allow the runtime hack to eventually            // be removed. Rule 2 doesn't apply to transformed modifiers.            assertModifiers(cmods, ACC_ABSTRACT);        } else {            // Contrary to the JVM spec, we only set ACC_SUPER for classes,            // not interfaces.  This is a workaround for a bug in IE3.0,            // which refuses interfaces with ACC_SUPER on.            cmods |= ACC_SUPER;        }         // If this is a nested class, transform access modifiers.        if (outerClass != null) {            // If private, transform to default (package) access.            // If protected, transform to public.            // M_PRIVATE and M_PROTECTED are already masked off by MM_CLASS above.            // cmods &= ~(M_PRIVATE | M_PROTECTED);            if (isProtected()) cmods |= M_PUBLIC;            // Rule 3a.  Note that Rule 3b doesn't apply to transformed modifiers.            if (outerClass.isInterface()) {                assertModifiers(cmods, M_PUBLIC);            }        }         data.writeShort(cmods);         if (env.dumpModifiers()) {            Identifier cn = getName();            Identifier nm =                Identifier.lookup(cn.getQualifier(), cn.getFlatName());            System.out.println();            System.out.println("CLASSFILE  " + nm);            System.out.println("---" + classModifierString(cmods));        }         data.writeShort(tab.index(getClassDeclaration()));        data.writeShort((getSuperClass() != null) ? tab.index(getSuperClass()) : 0);        data.writeShort(interfaces.length);        for (int i = 0 ; i < interfaces.length ; i++) {            data.writeShort(tab.index(interfaces[i]));        }         // write variables        ByteArrayOutputStream buf = new ByteArrayOutputStream(256);        ByteArrayOutputStream attbuf = new ByteArrayOutputStream(256);        DataOutputStream databuf = new DataOutputStream(buf);         data.writeShort(variables.size());        for (Enumeration e = variables.elements() ; e.hasMoreElements() ; ) {            CompilerMember f = (CompilerMember)e.nextElement();            Object val = f.field.getInitialValue();             data.writeShort(f.field.getModifiers() & MM_FIELD);            data.writeShort(tab.index(f.name));            data.writeShort(tab.index(f.sig));             int fieldAtts = (val != null ? 1 : 0);            boolean dep = f.field.isDeprecated();            boolean syn = f.field.isSynthetic();            fieldAtts += (dep ? 1 : 0) + (syn ? 1 : 0);             data.writeShort(fieldAtts);            if (val != null) {                data.writeShort(tab.index("ConstantValue"));                data.writeInt(2);                data.writeShort(tab.index((val instanceof String) ? new StringExpression(f.field.getWhere(), (String)val) : val));            }            if (dep) {                data.writeShort(tab.index("Deprecated"));                data.writeInt(0);            }            if (syn) {                data.writeShort(tab.index("Synthetic"));                data.writeInt(0);            }        }         // write methods         data.writeShort(methods.size());        for (Enumeration e = methods.elements() ; e.hasMoreElements() ; ) {            CompilerMember f = (CompilerMember)e.nextElement();             int xmods = f.field.getModifiers() & MM_METHOD;            // Transform floating point modifiers.  M_STRICTFP            // of member + status of enclosing class turn into            // ACC_STRICT bit.            if (((xmods & M_STRICTFP)!=0) || ((cmods & M_STRICTFP)!=0)) {                xmods |= ACC_STRICT;            } else {                // Use the default                if (env.strictdefault()) {                    xmods |= ACC_STRICT;                }            }            data.writeShort(xmods);             data.writeShort(tab.index(f.name));            data.writeShort(tab.index(f.sig));            ClassDeclaration exp[] = f.field.getExceptions(env);            int methodAtts = ((exp.length > 0) ? 1 : 0);            boolean dep = f.field.isDeprecated();            boolean syn = f.field.isSynthetic();            methodAtts += (dep ? 1 : 0) + (syn ? 1 : 0);             if (!f.asm.empty()) {                data.writeShort(methodAtts+1);                f.asm.write(env, databuf, f.field, tab);                int natts = 0;                if (env.debug_lines()) {                    natts++;                }// JCOV                if (env.coverage()) {                    natts++;                }// end JCOV                if (env.debug_vars()) {                    natts++;                }                databuf.writeShort(natts);                 if (env.debug_lines()) {                    f.asm.writeLineNumberTable(env, new DataOutputStream(attbuf), tab);                    databuf.writeShort(tab.index("LineNumberTable"));                    databuf.writeInt(attbuf.size());                    attbuf.writeTo(buf);                    attbuf.reset();                } //JCOV                if (env.coverage()) {                    f.asm.writeCoverageTable(env, (ClassDefinition)this, new DataOutputStream(attbuf), tab, f.field.getWhere());                    databuf.writeShort(tab.index("CoverageTable"));                    databuf.writeInt(attbuf.size());                    attbuf.writeTo(buf);                    attbuf.reset();                }// end JCOV                if (env.debug_vars()) {                    f.asm.writeLocalVariableTable(env, f.field, new DataOutputStream(attbuf), tab);                    databuf.writeShort(tab.index("LocalVariableTable"));                    databuf.writeInt(attbuf.size());                    attbuf.writeTo(buf);                    attbuf.reset();                }                 data.writeShort(tab.index("Code"));                data.writeInt(buf.size());                buf.writeTo(data);                buf.reset();            } else {//JCOV                if ((env.coverage()) && ((f.field.getModifiers() & M_NATIVE) > 0))                    f.asm.addNativeToJcovTab(env, (ClassDefinition)this);// end JCOV                data.writeShort(methodAtts);            }             if (exp.length > 0) {                data.writeShort(tab.index("Exceptions"));                data.writeInt(2 + exp.length * 2);                data.writeShort(exp.length);                for (int i = 0 ; i < exp.length ; i++) {                    data.writeShort(tab.index(exp[i]));                }            }            if (dep) {                data.writeShort(tab.index("Deprecated"));                data.writeInt(0);            }            if (syn) {                data.writeShort(tab.index("Synthetic"));                data.writeInt(0);            }        }         // class attributes

Lines 2001–2500 of 2674. Previous lines