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

📄 classfilewriter.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is Rhino code, released * May 6, 1999. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1997-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): *   Roger Lawrence * * Alternatively, the contents of this file may be used under the terms of * the GNU General Public License Version 2 or later (the "GPL"), in which * case the provisions of the GPL are applicable instead of those above. If * you wish to allow use of your version of this file only under the terms of * the GPL and not to allow others to use your version of this file under the * MPL, indicate your decision by deleting the provisions above and replacing * them with the notice and other provisions required by the GPL. If you do * not delete the provisions above, a recipient may use your version of this * file under either the MPL or the GPL. * * ***** END LICENSE BLOCK ***** */package org.mozilla.classfile;import org.mozilla.javascript.ObjToIntMap;import org.mozilla.javascript.ObjArray;import org.mozilla.javascript.UintMap;import java.io.*;/** * ClassFileWriter * * A ClassFileWriter is used to write a Java class file. Methods are * provided to create fields and methods, and within methods to write * Java bytecodes. * * @author Roger Lawrence */public class ClassFileWriter {    /**     * Construct a ClassFileWriter for a class.     *     * @param className the name of the class to write, including     *        full package qualification.     * @param superClassName the name of the superclass of the class     *        to write, including full package qualification.     * @param sourceFileName the name of the source file to use for     *        producing debug information, or null if debug information     *        is not desired     */    public ClassFileWriter(String className, String superClassName,                           String sourceFileName)    {        generatedClassName = className;        itsConstantPool = new ConstantPool(this);        itsThisClassIndex = itsConstantPool.addClass(className);        itsSuperClassIndex = itsConstantPool.addClass(superClassName);        if (sourceFileName != null)            itsSourceFileNameIndex = itsConstantPool.addUtf8(sourceFileName);        itsFlags = ACC_PUBLIC;    }    public final String getClassName()    {        return generatedClassName;    }    /**     * Add an interface implemented by this class.     *     * This method may be called multiple times for classes that     * implement multiple interfaces.     *     * @param interfaceName a name of an interface implemented     *        by the class being written, including full package     *        qualification.     */    public void addInterface(String interfaceName) {        short interfaceIndex = itsConstantPool.addClass(interfaceName);        itsInterfaces.add(new Short(interfaceIndex));    }    public static final short        ACC_PUBLIC = 0x0001,        ACC_PRIVATE = 0x0002,        ACC_PROTECTED = 0x0004,        ACC_STATIC = 0x0008,        ACC_FINAL = 0x0010,        ACC_SYNCHRONIZED = 0x0020,        ACC_VOLATILE = 0x0040,        ACC_TRANSIENT = 0x0080,        ACC_NATIVE = 0x0100,        ACC_ABSTRACT = 0x0400;    /**     * Set the class's flags.     *     * Flags must be a set of the following flags, bitwise or'd     * together:     *      ACC_PUBLIC     *      ACC_PRIVATE     *      ACC_PROTECTED     *      ACC_FINAL     *      ACC_ABSTRACT     * TODO: check that this is the appropriate set     * @param flags the set of class flags to set     */    public void setFlags(short flags) {        itsFlags = flags;    }    static String getSlashedForm(String name)    {        return name.replace('.', '/');    }    /**     * Convert Java class name in dot notation into     * "Lname-with-dots-replaced-by-slashes;" form suitable for use as     * JVM type signatures.     */    public static String classNameToSignature(String name)    {        int nameLength = name.length();        int colonPos = 1 + nameLength;        char[] buf = new char[colonPos + 1];        buf[0] = 'L';        buf[colonPos] = ';';        name.getChars(0, nameLength, buf, 1);        for (int i = 1; i != colonPos; ++i) {            if (buf[i] == '.') {                buf[i] = '/';            }        }        return new String(buf, 0, colonPos + 1);    }    /**     * Add a field to the class.     *     * @param fieldName the name of the field     * @param type the type of the field using ...     * @param flags the attributes of the field, such as ACC_PUBLIC, etc.     *        bitwise or'd together     */    public void addField(String fieldName, String type, short flags) {        short fieldNameIndex = itsConstantPool.addUtf8(fieldName);        short typeIndex = itsConstantPool.addUtf8(type);        itsFields.add(new ClassFileField(fieldNameIndex, typeIndex, flags));    }    /**     * Add a field to the class.     *     * @param fieldName the name of the field     * @param type the type of the field using ...     * @param flags the attributes of the field, such as ACC_PUBLIC, etc.     *        bitwise or'd together     * @param value an initial integral value     */    public void addField(String fieldName, String type, short flags,                         int value)    {        short fieldNameIndex = itsConstantPool.addUtf8(fieldName);        short typeIndex = itsConstantPool.addUtf8(type);        ClassFileField field = new ClassFileField(fieldNameIndex, typeIndex,                                                  flags);        field.setAttributes(itsConstantPool.addUtf8("ConstantValue"),                            (short)0,                            (short)0,                            itsConstantPool.addConstant(value));        itsFields.add(field);    }    /**     * Add a field to the class.     *     * @param fieldName the name of the field     * @param type the type of the field using ...     * @param flags the attributes of the field, such as ACC_PUBLIC, etc.     *        bitwise or'd together     * @param value an initial long value     */    public void addField(String fieldName, String type, short flags,                         long value)    {        short fieldNameIndex = itsConstantPool.addUtf8(fieldName);        short typeIndex = itsConstantPool.addUtf8(type);        ClassFileField field = new ClassFileField(fieldNameIndex, typeIndex,                                                  flags);        field.setAttributes(itsConstantPool.addUtf8("ConstantValue"),                            (short)0,                            (short)2,                            itsConstantPool.addConstant(value));        itsFields.add(field);    }    /**     * Add a field to the class.     *     * @param fieldName the name of the field     * @param type the type of the field using ...     * @param flags the attributes of the field, such as ACC_PUBLIC, etc.     *        bitwise or'd together     * @param value an initial double value     */    public void addField(String fieldName, String type, short flags,                         double value)    {        short fieldNameIndex = itsConstantPool.addUtf8(fieldName);        short typeIndex = itsConstantPool.addUtf8(type);        ClassFileField field = new ClassFileField(fieldNameIndex, typeIndex,                                                  flags);        field.setAttributes(itsConstantPool.addUtf8("ConstantValue"),                            (short)0,                            (short)2,                            itsConstantPool.addConstant(value));        itsFields.add(field);    }    /**     * Add Information about java variable to use when generating the local     * variable table.     *     * @param name variable name.     * @param type variable type as bytecode descriptor string.     * @param startPC the starting bytecode PC where this variable is live,     *                 or -1 if it does not have a Java register.     * @param register the Java register number of variable     *                 or -1 if it does not have a Java register.     */    public void addVariableDescriptor(String name, String type, int startPC, int register)    {        int nameIndex = itsConstantPool.addUtf8(name);        int descriptorIndex = itsConstantPool.addUtf8(type);        int [] chunk = { nameIndex, descriptorIndex, startPC, register };        if (itsVarDescriptors == null) {            itsVarDescriptors = new ObjArray();        }        itsVarDescriptors.add(chunk);    }    /**     * Add a method and begin adding code.     *     * This method must be called before other methods for adding code,     * exception tables, etc. can be invoked.     *     * @param methodName the name of the method     * @param type a string representing the type     * @param flags the attributes of the field, such as ACC_PUBLIC, etc.     *        bitwise or'd together     */    public void startMethod(String methodName, String type, short flags) {        short methodNameIndex = itsConstantPool.addUtf8(methodName);        short typeIndex = itsConstantPool.addUtf8(type);        itsCurrentMethod = new ClassFileMethod(methodNameIndex, typeIndex,                                               flags);        itsMethods.add(itsCurrentMethod);    }    /**     * Complete generation of the method.     *     * After this method is called, no more code can be added to the     * method begun with <code>startMethod</code>.     *     * @param maxLocals the maximum number of local variable slots     *        (a.k.a. Java registers) used by the method     * @param vars the array of the variables for the method,     *        or null if none     */    public void stopMethod(short maxLocals) {        if (itsCurrentMethod == null)            throw new IllegalStateException("No method to stop");        fixLabelGotos();        itsMaxLocals = maxLocals;        int lineNumberTableLength = 0;        if (itsLineNumberTable != null) {            // 6 bytes for the attribute header            // 2 bytes for the line number count            // 4 bytes for each entry            lineNumberTableLength = 6 + 2 + (itsLineNumberTableTop * 4);        }        int variableTableLength = 0;        if (itsVarDescriptors != null) {            // 6 bytes for the attribute header            // 2 bytes for the variable count            // 10 bytes for each entry            variableTableLength = 6 + 2 + (itsVarDescriptors.size() * 10);        }        int attrLength = 2 +                    // attribute_name_index                         4 +                    // attribute_length                         2 +                    // max_stack                         2 +                    // max_locals                         4 +                    // code_length                         itsCodeBufferTop +                         2 +                    // exception_table_length                         (itsExceptionTableTop * 8) +                         2 +                    // attributes_count                         lineNumberTableLength +                         variableTableLength;        byte[] codeAttribute = new byte[attrLength];        int index = 0;        int codeAttrIndex = itsConstantPool.addUtf8("Code");        index = putInt16(codeAttrIndex, codeAttribute, index);        attrLength -= 6;                 // discount the attribute header        index = putInt32(attrLength, codeAttribute, index);        index = putInt16(itsMaxStack, codeAttribute, index);        index = putInt16(itsMaxLocals, codeAttribute, index);        index = putInt32(itsCodeBufferTop, codeAttribute, index);        System.arraycopy(itsCodeBuffer, 0, codeAttribute, index,                         itsCodeBufferTop);        index += itsCodeBufferTop;        if (itsExceptionTableTop > 0) {            index = putInt16(itsExceptionTableTop, codeAttribute, index);            for (int i = 0; i < itsExceptionTableTop; i++) {                ExceptionTableEntry ete = itsExceptionTable[i];                short startPC = (short)getLabelPC(ete.itsStartLabel);                short endPC = (short)getLabelPC(ete.itsEndLabel);                short handlerPC = (short)getLabelPC(ete.itsHandlerLabel);                short catchType = ete.itsCatchType;                if (startPC == -1)                    throw new IllegalStateException("start label not defined");                if (endPC == -1)                    throw new IllegalStateException("end label not defined");                if (handlerPC == -1)                    throw new IllegalStateException(                        "handler label not defined");                index = putInt16(startPC, codeAttribute, index);                index = putInt16(endPC, codeAttribute, index);                index = putInt16(handlerPC, codeAttribute, index);                index = putInt16(catchType, codeAttribute, index);            }        }        else {            // write 0 as exception table length            index = putInt16(0, codeAttribute, index);        }        int attributeCount = 0;        if (itsLineNumberTable != null)            attributeCount++;        if (itsVarDescriptors != null)            attributeCount++;        index = putInt16(attributeCount, codeAttribute, index);

⌨️ 快捷键说明

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