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

📄 codegen.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    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;    boolean itsUseDynamicScope;    int languageVersion;    private double[] itsConstantList;    private int itsConstantListSize;}class BodyCodegen{    void generateBodyCode()    {        initBodyGeneration();        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, null);        generateEpilogue();        cfw.stopMethod((short)(localsMax + 1));    }    private void initBodyGeneration()    {        isTopLevel = (scriptOrFn == codegen.scriptOrFnNodes[0]);        varRegisters = null;        if (scriptOrFn.getType() == Token.FUNCTION) {            fnCurrent = OptFunctionNode.get(scriptOrFn);            hasVarsInRegs = !fnCurrent.fnode.requiresActivation();            if (hasVarsInRegs) {                int n = fnCurrent.fnode.getParamAndVarCount();                if (n != 0) {                    varRegisters = new short[n];                }            }            inDirectCallFunction = fnCurrent.isTargetOfDirectCall();            if (inDirectCallFunction && !hasVarsInRegs) Codegen.badTree();        } else {            fnCurrent = null;            hasVarsInRegs = false;            inDirectCallFunction = false;        }        locals = new boolean[MAX_LOCALS];        funObjLocal = 0;        contextLocal = 1;        variableObjectLocal = 2;        thisObjLocal = 3;        localsMax = (short) 4;  // number of parms + "this"        firstFreeLocal = 4;        popvLocal = -1;        argsLocal = -1;        itsZeroArgArray = -1;        itsOneArgArray = -1;        scriptRegexpLocal = -1;        epilogueLabel = -1;        enterAreaStartLabel = -1;    }    /**     * Generate the prologue for a function or script.     */    private void generatePrologue()    {        if (inDirectCallFunction) {            int directParameterCount = scriptOrFn.getParamCount();            // 0 is reserved for function Object 'this'            // 1 is reserved for context            // 2 is reserved for parentScope            // 3 is reserved for script 'this'            if (firstFreeLocal != 4) Kit.codeBug();            for (int i = 0; i != directParameterCount; ++i) {                varRegisters[i] = firstFreeLocal;                // 3 is 1 for Object parm and 2 for double parm                firstFreeLocal += 3;            }            if (!fnCurrent.getParameterNumberContext()) {                // make sure that all parameters are objects                itsForcedObjectParameters = true;                for (int i = 0; i != directParameterCount; ++i) {                    short reg = varRegisters[i];                    cfw.addALoad(reg);                    cfw.add(ByteCode.GETSTATIC,                            "java/lang/Void",                            "TYPE",                            "Ljava/lang/Class;");                    int isObjectLabel = cfw.acquireLabel();                    cfw.add(ByteCode.IF_ACMPNE, isObjectLabel);                    cfw.addDLoad(reg + 1);                    addDoubleWrap();                    cfw.addAStore(reg);                    cfw.markLabel(isObjectLabel);                }            }        }        if (fnCurrent != null && !inDirectCallFunction            && (!compilerEnv.isUseDynamicScope()                || fnCurrent.fnode.getIgnoreDynamicScope()))        {            // Unless we're either in a direct call or using dynamic scope,            // use the enclosing scope of the function as our variable object.            cfw.addALoad(funObjLocal);            cfw.addInvoke(ByteCode.INVOKEINTERFACE,                          "org/mozilla/javascript/Scriptable",                          "getParentScope",                          "()Lorg/mozilla/javascript/Scriptable;");            cfw.addAStore(variableObjectLocal);        }        // reserve 'args[]'        argsLocal = firstFreeLocal++;        localsMax = firstFreeLocal;        if (fnCurrent == null) {            // See comments in case Token.REGEXP            if (scriptOrFn.getRegexpCount() != 0) {                scriptRegexpLocal = getNewWordLocal();                codegen.pushRegExpArray(cfw, scriptOrFn, contextLocal,                                        variableObjectLocal);                cfw.addAStore(scriptRegexpLocal);            }        }        if (hasVarsInRegs) {            // No need to create activation. Pad arguments if need be.            int parmCount = scriptOrFn.getParamCount();            if (parmCount > 0 && !inDirectCallFunction) {                // Set up args array                // check length of arguments, pad if need be                cfw.addALoad(argsLocal);                cfw.add(ByteCode.ARRAYLENGTH);                cfw.addPush(parmCount);                int label = cfw.acquireLabel();                cfw.add(ByteCode.IF_ICMPGE, label);                cfw.addALoad(argsLocal);                cfw.addPush(parmCount);                addScriptRuntimeInvoke("padArguments",                                       "([Ljava/lang/Object;I"                                       +")[Ljava/lang/Object;");                cfw.addAStore(argsLocal);                cfw.markLabel(label);            }            int paramCount = fnCurrent.fnode.getParamCount();            int varCount = fnCurrent.fnode.getParamAndVarCount();            // REMIND - only need to initialize the vars that don't get a value            // before the next call and are used in the function            short firstUndefVar = -1;            for (int i = 0; i != varCount; ++i) {                short reg = -1;                if (i < paramCount) {                    if (!inDirectCallFunction) {                        reg = getNewWordLocal();                        cfw.addALoad(argsLocal);                        cfw.addPush(i);                        cfw.add(ByteCode.AALOAD);                        cfw.addAStore(reg);                    }                } else if (fnCurrent.isNumberVar(i)) {                    reg = getNewWordPairLocal();                    cfw.addPush(0.0);                    cfw.addDStore(reg);                } else {                    reg = getNewWordLocal();                    if (firstUndefVar == -1) {                        Codegen.pushUndefined(cfw);                        firstUndefVar = reg;                    } else {                        cfw.addALoad(firstUndefVar);                    }                    cfw.addAStore(reg);                }                if (reg >= 0) {                    varRegisters[i] = reg;                }                // Add debug table enry if we're generating debug info                if (compilerEnv.isGenerateDebugInfo()) {                    String name = fnCurrent.fnode.getParamOrVarName(i);                    String type = fnCurrent.isNumberVar(i)                                      ? "D" : "Ljava/lang/Object;";                    int startPC = cfw.getCurrentCodeOffset();                    if (reg < 0) {                        reg = varRegisters[i];                    }                    cfw.addVariableDescriptor(name, type, startPC, reg);                }            }            // Skip creating activation object.            return;        }        String debugVariableName;        if (fnCurrent != null) {            debugVariableName = "activation";            cfw.addALoad(funObjLocal);            cfw.addALoad(variableObjectLocal);            cfw.addALoad(argsLocal);            addScriptRuntimeInvoke("createFunctionActivation",                                   "(Lorg/mozilla/javascript/NativeFunction;"                                   +"Lorg/mozilla/javascript/Scriptable;"                                   +"[Ljava/lang/Object;"                                   +")Lorg/mozilla/javascript/Scriptable;");            cfw.addAStore(variableObjectLocal);            cfw.addALoad(contextLocal);            cfw.addALoad(variableObjectLocal);            addScriptRuntimeInvoke("enterActivationFunction",                                   "(Lorg/mozilla/javascript/Context;"                                   +"Lorg/mozilla/javascript/Scriptable;"                                   +")V");        } else {            debugVariableName = "global";            cfw.addALoad(funObjLocal);            cfw.addALoad(thisObjLocal);            cfw.addALoad(contextLocal);            cfw.addALoad(variableObjectLocal);            cfw.addPush(0); // false to indicate it is not eval script            addScriptRuntimeInvoke("initScript",                                   "(Lorg/mozilla/javascript/NativeFunction;"                                   +"Lorg/mozilla/javascript/Scriptable;"                                   +"Lorg/mozilla/javascript/Context;"                                   +"Lorg/mozilla/javascript/Scriptable;"                                   +"Z"                                   +")V");        }        enterAreaStartLabel = cfw.acquireLabel();        epilogueLabel = cfw.acquireLabel();        cfw.markLabel(enterAreaStartLabel);        int functionCount = scriptOrFn.getFunctionCount();

⌨️ 快捷键说明

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