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

📄 codegen.java

📁 這是一個javascript 的 interpreter是了解 web browser的好材料
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
/* ***** 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-2000 * the Initial Developer. All Rights Reserved. * * Contributor(s): *   Norris Boyd *   Kemal Bayram *   Igor Bukanov *   Bob Jervis *   Roger Lawrence *   Andi Vajda *   Hannes Wallnoefer * * 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.javascript.optimizer;import org.mozilla.javascript.*;import org.mozilla.classfile.*;import java.util.*;import java.lang.reflect.Constructor;import java.util.Hashtable;/** * This class generates code for a given IR tree. * * @author Norris Boyd * @author Roger Lawrence */public class Codegen implements Evaluator{    public void captureStackInfo(RhinoException ex) {        throw new UnsupportedOperationException();    }        public String getSourcePositionFromStack(Context cx, int[] linep) {        throw new UnsupportedOperationException();    }    public String getPatchedStack(RhinoException ex, String nativeStackTrace) {        throw new UnsupportedOperationException();    }    public List getScriptStack(RhinoException ex) {        throw new UnsupportedOperationException();    }    public void setEvalScriptFlag(Script script) {        throw new UnsupportedOperationException();    }    public Object compile(CompilerEnvirons compilerEnv,                          ScriptOrFnNode tree,                          String encodedSource,                          boolean returnFunction)    {        int serial;        synchronized (globalLock) {            serial = ++globalSerialClassCounter;        }        String mainClassName = "org.mozilla.javascript.gen.c"+serial;        byte[] mainClassBytes = compileToClassFile(compilerEnv, mainClassName,                                                   tree, encodedSource,                                                   returnFunction);        return new Object[] { mainClassName, mainClassBytes };    }    public Script createScriptObject(Object bytecode,                                     Object staticSecurityDomain)    {        Class cl = defineClass(bytecode, staticSecurityDomain);        Script script;        try {            script = (Script)cl.newInstance();        } catch (Exception ex) {            throw new RuntimeException                ("Unable to instantiate compiled class:"+ex.toString());        }        return script;    }    public Function createFunctionObject(Context cx, Scriptable scope,                                         Object bytecode,                                         Object staticSecurityDomain)    {        Class cl = defineClass(bytecode, staticSecurityDomain);        NativeFunction f;        try {            Constructor ctor = cl.getConstructors()[0];            Object[] initArgs = { scope, cx, new Integer(0) };            f = (NativeFunction)ctor.newInstance(initArgs);        } catch (Exception ex) {            throw new RuntimeException                ("Unable to instantiate compiled class:"+ex.toString());        }        return f;    }    private Class defineClass(Object bytecode,                              Object staticSecurityDomain)    {        Object[] nameBytesPair = (Object[])bytecode;        String className = (String)nameBytesPair[0];        byte[] classBytes = (byte[])nameBytesPair[1];        // The generated classes in this case refer only to Rhino classes        // which must be accessible through this class loader        ClassLoader rhinoLoader = getClass().getClassLoader();        GeneratedClassLoader loader;        loader = SecurityController.createLoader(rhinoLoader,                                                 staticSecurityDomain);        Exception e;        try {            Class cl = loader.defineClass(className, classBytes);            loader.linkClass(cl);            return cl;        } catch (SecurityException x) {            e = x;        } catch (IllegalArgumentException x) {            e = x;        }        throw new RuntimeException("Malformed optimizer package " + e);    }    byte[] compileToClassFile(CompilerEnvirons compilerEnv,                              String mainClassName,                              ScriptOrFnNode scriptOrFn,                              String encodedSource,                              boolean returnFunction)    {        this.compilerEnv = compilerEnv;        transform(scriptOrFn);        if (Token.printTrees) {            System.out.println(scriptOrFn.toStringTree(scriptOrFn));        }        if (returnFunction) {            scriptOrFn = scriptOrFn.getFunctionNode(0);        }        initScriptOrFnNodesData(scriptOrFn);        this.mainClassName = mainClassName;        this.mainClassSignature            = ClassFileWriter.classNameToSignature(mainClassName);        try {            return generateCode(encodedSource);        } catch (ClassFileWriter.ClassFileFormatException e) {            throw reportClassFileFormatException(scriptOrFn, e.getMessage());        }    }        private RuntimeException reportClassFileFormatException(        ScriptOrFnNode scriptOrFn,        String message)    {        String msg = scriptOrFn instanceof FunctionNode        ? ScriptRuntime.getMessage2("msg.while.compiling.fn",            ((FunctionNode)scriptOrFn).getFunctionName(), message)        : ScriptRuntime.getMessage1("msg.while.compiling.script", message);        return Context.reportRuntimeError(msg, scriptOrFn.getSourceName(),            scriptOrFn.getLineno(), null, 0);    }    private void transform(ScriptOrFnNode tree)    {        initOptFunctions_r(tree);        int optLevel = compilerEnv.getOptimizationLevel();        Hashtable possibleDirectCalls = null;        if (optLevel > 0) {           /*            * Collect all of the contained functions into a hashtable            * so that the call optimizer can access the class name & parameter            * count for any call it encounters            */            if (tree.getType() == Token.SCRIPT) {                int functionCount = tree.getFunctionCount();                for (int i = 0; i != functionCount; ++i) {                    OptFunctionNode ofn = OptFunctionNode.get(tree, i);                    if (ofn.fnode.getFunctionType()                        == FunctionNode.FUNCTION_STATEMENT)                    {                        String name = ofn.fnode.getFunctionName();                        if (name.length() != 0) {                            if (possibleDirectCalls == null) {                                possibleDirectCalls = new Hashtable();                            }                            possibleDirectCalls.put(name, ofn);                        }                    }                }            }        }        if (possibleDirectCalls != null) {            directCallTargets = new ObjArray();        }        OptTransformer ot = new OptTransformer(possibleDirectCalls,                                               directCallTargets);        ot.transform(tree);        if (optLevel > 0) {            (new Optimizer()).optimize(tree);        }    }    private static void initOptFunctions_r(ScriptOrFnNode scriptOrFn)    {        for (int i = 0, N = scriptOrFn.getFunctionCount(); i != N; ++i) {            FunctionNode fn = scriptOrFn.getFunctionNode(i);            new OptFunctionNode(fn);            initOptFunctions_r(fn);        }    }    private void initScriptOrFnNodesData(ScriptOrFnNode scriptOrFn)    {        ObjArray x = new ObjArray();        collectScriptOrFnNodes_r(scriptOrFn, x);        int count = x.size();        scriptOrFnNodes = new ScriptOrFnNode[count];        x.toArray(scriptOrFnNodes);        scriptOrFnIndexes = new ObjToIntMap(count);        for (int i = 0; i != count; ++i) {            scriptOrFnIndexes.put(scriptOrFnNodes[i], i);        }    }    private static void collectScriptOrFnNodes_r(ScriptOrFnNode n,                                                 ObjArray x)    {        x.add(n);        int nestedCount = n.getFunctionCount();        for (int i = 0; i != nestedCount; ++i) {            collectScriptOrFnNodes_r(n.getFunctionNode(i), x);        }    }    private byte[] generateCode(String encodedSource)    {        boolean hasScript = (scriptOrFnNodes[0].getType() == Token.SCRIPT);        boolean hasFunctions = (scriptOrFnNodes.length > 1 || !hasScript);        String sourceFile = null;        if (compilerEnv.isGenerateDebugInfo()) {            sourceFile = scriptOrFnNodes[0].getSourceName();        }        ClassFileWriter cfw = new ClassFileWriter(mainClassName,                                                  SUPER_CLASS_NAME,                                                  sourceFile);        cfw.addField(ID_FIELD_NAME, "I",                     ClassFileWriter.ACC_PRIVATE);        cfw.addField(DIRECT_CALL_PARENT_FIELD, mainClassSignature,                     ClassFileWriter.ACC_PRIVATE);        cfw.addField(REGEXP_ARRAY_FIELD_NAME, REGEXP_ARRAY_FIELD_TYPE,                     ClassFileWriter.ACC_PRIVATE);        if (hasFunctions) {            generateFunctionConstructor(cfw);        }        if (hasScript) {            cfw.addInterface("org/mozilla/javascript/Script");            generateScriptCtor(cfw);            generateMain(cfw);            generateExecute(cfw);        }        generateCallMethod(cfw);        generateResumeGenerator(cfw);        generateNativeFunctionOverrides(cfw, encodedSource);        int count = scriptOrFnNodes.length;        for (int i = 0; i != count; ++i) {            ScriptOrFnNode n = scriptOrFnNodes[i];            BodyCodegen bodygen = new BodyCodegen();            bodygen.cfw = cfw;            bodygen.codegen = this;            bodygen.compilerEnv = compilerEnv;            bodygen.scriptOrFn = n;            bodygen.scriptOrFnIndex = i;            try {                bodygen.generateBodyCode();            } catch (ClassFileWriter.ClassFileFormatException e) {                throw reportClassFileFormatException(n, e.getMessage());            }            if (n.getType() == Token.FUNCTION) {                OptFunctionNode ofn = OptFunctionNode.get(n);                generateFunctionInit(cfw, ofn);                if (ofn.isTargetOfDirectCall()) {                    emitDirectConstructor(cfw, ofn);                }            }        }        if (directCallTargets != null) {

⌨️ 快捷键说明

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