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

📄 codegen.java

📁 這是一個javascript 的 interpreter是了解 web browser的好材料
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
                             (short)(ClassFileWriter.ACC_STATIC                                     | ClassFileWriter.ACC_PRIVATE));                cfw.addALoad(0); // proxy                cfw.addALoad(1); // context                cfw.addPush(reString);                if (reFlags == null) {                    cfw.add(ByteCode.ACONST_NULL);                } else {                    cfw.addPush(reFlags);                }                cfw.addInvoke(ByteCode.INVOKEINTERFACE,                              "org/mozilla/javascript/RegExpProxy",                              "compileRegExp",                              "(Lorg/mozilla/javascript/Context;"                              +"Ljava/lang/String;Ljava/lang/String;"                              +")Ljava/lang/Object;");                cfw.add(ByteCode.PUTSTATIC, mainClassName,                        reFieldName, reFieldType);            }        }        cfw.addPush(1);        cfw.add(ByteCode.PUTSTATIC, mainClassName, "_reInitDone", "Z");        cfw.add(ByteCode.RETURN);        cfw.stopMethod((short)2);    }    private void emitConstantDudeInitializers(ClassFileWriter cfw)    {        int N = itsConstantListSize;        if (N == 0)            return;        cfw.startMethod("<clinit>", "()V",            (short)(ClassFileWriter.ACC_STATIC | ClassFileWriter.ACC_FINAL));        double[] array = itsConstantList;        for (int i = 0; i != N; ++i) {            double num = array[i];            String constantName = "_k" + i;            String constantType = getStaticConstantWrapperType(num);            cfw.addField(constantName, constantType,                         (short)(ClassFileWriter.ACC_STATIC                                 | ClassFileWriter.ACC_PRIVATE));            int inum = (int)num;            if (inum == num) {                cfw.add(ByteCode.NEW, "java/lang/Integer");                cfw.add(ByteCode.DUP);                cfw.addPush(inum);                cfw.addInvoke(ByteCode.INVOKESPECIAL, "java/lang/Integer",                              "<init>", "(I)V");            } else {                cfw.addPush(num);                addDoubleWrap(cfw);            }            cfw.add(ByteCode.PUTSTATIC, mainClassName,                    constantName, constantType);        }        cfw.add(ByteCode.RETURN);        cfw.stopMethod((short)0);    }    void pushRegExpArray(ClassFileWriter cfw, ScriptOrFnNode n,                         int contextArg, int scopeArg)    {        int regexpCount = n.getRegexpCount();        if (regexpCount == 0) throw badTree();        cfw.addPush(regexpCount);        cfw.add(ByteCode.ANEWARRAY, "java/lang/Object");        cfw.addALoad(contextArg);        cfw.addInvoke(ByteCode.INVOKESTATIC,                      "org/mozilla/javascript/ScriptRuntime",                      "checkRegExpProxy",                      "(Lorg/mozilla/javascript/Context;"                      +")Lorg/mozilla/javascript/RegExpProxy;");        // Stack: proxy, array        cfw.add(ByteCode.DUP);        cfw.addALoad(contextArg);        cfw.addInvoke(ByteCode.INVOKESTATIC, mainClassName,                      REGEXP_INIT_METHOD_NAME, REGEXP_INIT_METHOD_SIGNATURE);        for (int i = 0; i != regexpCount; ++i) {            // Stack: proxy, array            cfw.add(ByteCode.DUP2);            cfw.addALoad(contextArg);            cfw.addALoad(scopeArg);            cfw.add(ByteCode.GETSTATIC, mainClassName,                    getCompiledRegexpName(n, i), "Ljava/lang/Object;");            // Stack: compiledRegExp, scope, cx, proxy, array, proxy, array            cfw.addInvoke(ByteCode.INVOKEINTERFACE,                          "org/mozilla/javascript/RegExpProxy",                          "wrapRegExp",                          "(Lorg/mozilla/javascript/Context;"                          +"Lorg/mozilla/javascript/Scriptable;"                          +"Ljava/lang/Object;"                          +")Lorg/mozilla/javascript/Scriptable;");            // Stack: wrappedRegExp, array, proxy, array            cfw.addPush(i);            cfw.add(ByteCode.SWAP);            cfw.add(ByteCode.AASTORE);            // Stack: proxy, array        }        // remove proxy        cfw.add(ByteCode.POP);    }    void pushNumberAsObject(ClassFileWriter cfw, double num)    {        if (num == 0.0) {            if (1 / num > 0) {                // +0.0                cfw.add(ByteCode.GETSTATIC,                        "org/mozilla/javascript/optimizer/OptRuntime",                        "zeroObj", "Ljava/lang/Double;");            } else {                cfw.addPush(num);                addDoubleWrap(cfw);            }        } else if (num == 1.0) {            cfw.add(ByteCode.GETSTATIC,                    "org/mozilla/javascript/optimizer/OptRuntime",                    "oneObj", "Ljava/lang/Double;");            return;        } else if (num == -1.0) {            cfw.add(ByteCode.GETSTATIC,                    "org/mozilla/javascript/optimizer/OptRuntime",                    "minusOneObj", "Ljava/lang/Double;");        } else if (num != num) {            cfw.add(ByteCode.GETSTATIC,                    "org/mozilla/javascript/ScriptRuntime",                    "NaNobj", "Ljava/lang/Double;");        } else if (itsConstantListSize >= 2000) {            // There appears to be a limit in the JVM on either the number            // of static fields in a class or the size of the class            // initializer. Either way, we can't have any more than 2000            // statically init'd constants.            cfw.addPush(num);            addDoubleWrap(cfw);        } else {            int N = itsConstantListSize;            int index = 0;            if (N == 0) {                itsConstantList = new double[64];            } else {                double[] array = itsConstantList;                while (index != N && array[index] != num) {                    ++index;                }                if (N == array.length) {                    array = new double[N * 2];                    System.arraycopy(itsConstantList, 0, array, 0, N);                    itsConstantList = array;                }            }            if (index == N) {                itsConstantList[N] = num;                itsConstantListSize = N + 1;            }            String constantName = "_k" + index;            String constantType = getStaticConstantWrapperType(num);            cfw.add(ByteCode.GETSTATIC, mainClassName,                    constantName, constantType);        }    }    private static void addDoubleWrap(ClassFileWriter cfw)    {        cfw.addInvoke(ByteCode.INVOKESTATIC,                      "org/mozilla/javascript/optimizer/OptRuntime",                      "wrapDouble", "(D)Ljava/lang/Double;");    }    private static String getStaticConstantWrapperType(double num)    {        int inum = (int)num;        if (inum == num) {            return "Ljava/lang/Integer;";        } else {            return "Ljava/lang/Double;";        }    }    static void pushUndefined(ClassFileWriter cfw)    {        cfw.add(ByteCode.GETSTATIC, "org/mozilla/javascript/Undefined",                "instance", "Ljava/lang/Object;");    }    int getIndex(ScriptOrFnNode n)    {        return scriptOrFnIndexes.getExisting(n);    }    static String getDirectTargetFieldName(int i)    {        return "_dt" + i;    }    String getDirectCtorName(ScriptOrFnNode n)    {        return "_n"+getIndex(n);    }    String getBodyMethodName(ScriptOrFnNode n)    {        return "_c"+getIndex(n);    }    String getBodyMethodSignature(ScriptOrFnNode n)    {        StringBuffer sb = new StringBuffer();        sb.append('(');        sb.append(mainClassSignature);        sb.append("Lorg/mozilla/javascript/Context;"                  +"Lorg/mozilla/javascript/Scriptable;"                  +"Lorg/mozilla/javascript/Scriptable;");        if (n.getType() == Token.FUNCTION) {            OptFunctionNode ofn = OptFunctionNode.get(n);            if (ofn.isTargetOfDirectCall()) {                int pCount = ofn.fnode.getParamCount();                for (int i = 0; i != pCount; i++) {                    sb.append("Ljava/lang/Object;D");                }            }        }        sb.append("[Ljava/lang/Object;)Ljava/lang/Object;");        return sb.toString();    }    String getFunctionInitMethodName(OptFunctionNode ofn)    {        return "_i"+getIndex(ofn.fnode);    }    String getCompiledRegexpName(ScriptOrFnNode n, int regexpIndex)    {        return "_re"+getIndex(n)+"_"+regexpIndex;    }    static RuntimeException badTree()    {        throw new RuntimeException("Bad tree in codegen");    }     void setMainMethodClass(String className)     {         mainMethodClass = className;     }     static final String DEFAULT_MAIN_METHOD_CLASS        = "org.mozilla.javascript.optimizer.OptRuntime";    private static final String SUPER_CLASS_NAME        = "org.mozilla.javascript.NativeFunction";    static final String DIRECT_CALL_PARENT_FIELD = "_dcp";    private static final String ID_FIELD_NAME = "_id";    private static final String REGEXP_INIT_METHOD_NAME = "_reInit";    private static final String REGEXP_INIT_METHOD_SIGNATURE        =  "(Lorg/mozilla/javascript/RegExpProxy;"           +"Lorg/mozilla/javascript/Context;"           +")V";    static final String REGEXP_ARRAY_FIELD_NAME = "_re";    static final String REGEXP_ARRAY_FIELD_TYPE = "[Ljava/lang/Object;";    static final String FUNCTION_INIT_SIGNATURE        =  "(Lorg/mozilla/javascript/Context;"           +"Lorg/mozilla/javascript/Scriptable;"           +")V";   static final String FUNCTION_CONSTRUCTOR_SIGNATURE        = "(Lorg/mozilla/javascript/Scriptable;"          +"Lorg/mozilla/javascript/Context;I)V";    private static final Object globalLock = new Object();    private static int globalSerialClassCounter;    private CompilerEnvirons compilerEnv;    private ObjArray directCallTargets;    ScriptOrFnNode[] scriptOrFnNodes;    private ObjToIntMap scriptOrFnIndexes;    private String mainMethodClass = DEFAULT_MAIN_METHOD_CLASS;    String mainClassName;    String mainClassSignature;    private double[] itsConstantList;    private int itsConstantListSize;}class BodyCodegen{    void generateBodyCode()    {        isGenerator = Codegen.isGenerator(scriptOrFn);                // generate the body of the current function or script object        initBodyGeneration();        if (isGenerator) {            // All functions in the generated bytecode have a unique name. Every            // generator has a unique prefix followed by _gen            String type = "(" +                          codegen.mainClassSignature +                          "Lorg/mozilla/javascript/Context;" +                          "Lorg/mozilla/javascript/Scriptable;" +                          "Ljava/lang/Object;" +                          "Ljava/lang/Object;I)Ljava/lang/Object;";             cfw.startMethod(codegen.getBodyMethodName(scriptOrFn) + "_gen",                    type,                    (short)(ClassFileWriter.ACC_STATIC                            | ClassFileWriter.ACC_PRIVATE));        } else {            cfw.startMethod(codegen.getBodyMethodName(scriptOrFn),                    codegen.getBodyMethodSignature(scriptOrFn),                    (short)(ClassFileWriter.ACC_STATIC                            | ClassFileWriter.ACC_PRIVATE));        }        generatePrologue();        Node treeTop;        if (fnCurrent != null) {            treeTop = scriptOrFn.getLastChild();        } else {            treeTop = scriptOrFn;        }        generateStatement(treeTop);        generateEpilogue();        cfw.stopMethod((short)(localsMax + 1));

⌨️ 快捷键说明

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