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

📄 scriptruntime.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    {        Scriptable parent = scope.getParentScope();        if (parent == null) {            Object result = topScopeName(cx, scope, name);            if (result == Scriptable.NOT_FOUND) {                throw notFoundError(scope, name);            }            return result;        }        return nameOrFunction(cx, scope, parent, name, false);    }    private static Object nameOrFunction(Context cx, Scriptable scope,                                         Scriptable parentScope, String name,                                         boolean asFunctionCall)    {        Object result;        Scriptable thisObj = scope; // It is used only if asFunctionCall==true.        XMLObject firstXMLObject = null;        for (;;) {            if (scope instanceof NativeWith) {                Scriptable withObj = scope.getPrototype();                if (withObj instanceof XMLObject) {                    XMLObject xmlObj = (XMLObject)withObj;                    if (xmlObj.ecmaHas(cx, name)) {                        // function this should be the target object of with                        thisObj = xmlObj;                        result = xmlObj.ecmaGet(cx, name);                        break;                    }                    if (firstXMLObject == null) {                        firstXMLObject = xmlObj;                    }                } else {                    result = ScriptableObject.getProperty(withObj, name);                    if (result != Scriptable.NOT_FOUND) {                        // function this should be the target object of with                        thisObj = withObj;                        break;                    }                }            } else if (scope instanceof NativeCall) {                // NativeCall does not prototype chain and Scriptable.get                // can be called directly.                result = scope.get(name, scope);                if (result != Scriptable.NOT_FOUND) {                    if (asFunctionCall) {                        // ECMA 262 requires that this for nested funtions                        // should be top scope                        thisObj = ScriptableObject.                                      getTopLevelScope(parentScope);                    }                    break;                }            } else {                // Can happen if Rhino embedding decided that nested                // scopes are useful for what ever reasons.                result = ScriptableObject.getProperty(scope, name);                if (result != Scriptable.NOT_FOUND) {                    thisObj = scope;                    break;                }            }            scope = parentScope;            parentScope = parentScope.getParentScope();            if (parentScope == null) {                result = topScopeName(cx, scope, name);                if (result == Scriptable.NOT_FOUND) {                    if (firstXMLObject == null || asFunctionCall) {                        throw notFoundError(scope, name);                    }                    // The name was not found, but we did find an XML                    // object in the scope chain and we are looking for name,                    // not function. The result should be an empty XMLList                    // in name context.                    result = firstXMLObject.ecmaGet(cx, name);                }                // For top scope thisObj for functions is always scope itself.                thisObj = scope;                break;            }        }        if (asFunctionCall) {            if (!(result instanceof Callable)) {                throw notFunctionError(result, name);            }            storeScriptable(cx, thisObj);        }        return result;    }    private static Object topScopeName(Context cx, Scriptable scope,                                       String name)    {        if (cx.useDynamicScope) {            scope = checkDynamicScope(cx.topCallScope, scope);        }        return ScriptableObject.getProperty(scope, name);    }    /**     * Returns the object in the scope chain that has a given property.     *     * The order of evaluation of an assignment expression involves     * evaluating the lhs to a reference, evaluating the rhs, and then     * modifying the reference with the rhs value. This method is used     * to 'bind' the given name to an object containing that property     * so that the side effects of evaluating the rhs do not affect     * which property is modified.     * Typically used in conjunction with setName.     *     * See ECMA 10.1.4     */    public static Scriptable bind(Context cx, Scriptable scope, String id)    {        Scriptable firstXMLObject = null;        Scriptable parent = scope.getParentScope();        childScopesChecks: if (parent != null) {            // Check for possibly nested "with" scopes first            while (scope instanceof NativeWith) {                Scriptable withObj = scope.getPrototype();                if (withObj instanceof XMLObject) {                    XMLObject xmlObject = (XMLObject)withObj;                    if (xmlObject.ecmaHas(cx, id)) {                        return xmlObject;                    }                    if (firstXMLObject == null) {                        firstXMLObject = xmlObject;                    }                } else {                    if (ScriptableObject.hasProperty(withObj, id)) {                        return withObj;                    }                }                scope = parent;                parent = parent.getParentScope();                if (parent == null) {                    break childScopesChecks;                }            }            for (;;) {                if (ScriptableObject.hasProperty(scope, id)) {                    return scope;                }                scope = parent;                parent = parent.getParentScope();                if (parent == null) {                    break childScopesChecks;                }            }        }        // scope here is top scope        if (cx.useDynamicScope) {            scope = checkDynamicScope(cx.topCallScope, scope);        }        if (ScriptableObject.hasProperty(scope, id)) {            return scope;        }        // Nothing was found, but since XML objects always bind        // return one if found        return firstXMLObject;    }    public static Object setName(Scriptable bound, Object value,                                 Context cx, Scriptable scope, String id)    {        if (bound != null) {            if (bound instanceof XMLObject) {                XMLObject xmlObject = (XMLObject)bound;                xmlObject.ecmaPut(cx, id, value);            } else {                ScriptableObject.putProperty(bound, id, value);            }        } else {            // "newname = 7;", where 'newname' has not yet            // been defined, creates a new property in the            // top scope unless strict mode is specified.            if (cx.hasFeature(Context.FEATURE_STRICT_VARS)) {                throw Context.reportRuntimeError1("msg.assn.create.strict", id);            }            // Find the top scope by walking up the scope chain.            bound = ScriptableObject.getTopLevelScope(scope);            if (cx.useDynamicScope) {                bound = checkDynamicScope(cx.topCallScope, bound);            }            bound.put(id, bound, value);        }        return value;    }    /**     * This is the enumeration needed by the for..in statement.     *     * See ECMA 12.6.3.     *     * IdEnumeration maintains a ObjToIntMap to make sure a given     * id is enumerated only once across multiple objects in a     * prototype chain.     *     * XXX - ECMA delete doesn't hide properties in the prototype,     * but js/ref does. This means that the js/ref for..in can     * avoid maintaining a hash table and instead perform lookups     * to see if a given property has already been enumerated.     *     */    private static class IdEnumeration    {        Scriptable obj;        Object[] ids;        int index;        ObjToIntMap used;        String currentId;        boolean enumValues;    }    public static Object enumInit(Object value, Context cx, boolean enumValues)    {        IdEnumeration x = new IdEnumeration();        x.obj = toObjectOrNull(cx, value);        if (x.obj != null) {            // null or undefined do not cause errors but rather lead to empty            // "for in" loop            x.enumValues = enumValues;            // enumInit should read all initial ids before returning            // or "for (a.i in a)" would wrongly enumerate i in a as well            enumChangeObject(x);        }        return x;    }    public static Boolean enumNext(Object enumObj)    {        // OPT this could be more efficient        boolean result;        IdEnumeration x = (IdEnumeration)enumObj;        for (;;) {            if (x.obj == null) {                result = false;                break;            }            if (x.index == x.ids.length) {                x.obj = x.obj.getPrototype();                enumChangeObject(x);                continue;            }            Object id = x.ids[x.index++];            if (x.used != null && x.used.has(id)) {                continue;            }            if (id instanceof String) {                String strId = (String)id;                if (!x.obj.has(strId, x.obj))                    continue;   // must have been deleted                x.currentId = strId;            } else {                int intId = ((Number)id).intValue();                if (!x.obj.has(intId, x.obj))                    continue;   // must have been deleted                x.currentId = String.valueOf(intId);            }            result = true;            break;        }        return wrapBoolean(result);    }    public static Object enumId(Object enumObj, Context cx)    {        IdEnumeration x = (IdEnumeration)enumObj;        if (!x.enumValues) return x.currentId;        Object result;        String s = toStringIdOrIndex(cx, x.currentId);        if (s == null) {            int index = lastIndexResult(cx);            result = x.obj.get(index, x.obj);        } else {            result = x.obj.get(s, x.obj);        }        return result;    }    private static void enumChangeObject(IdEnumeration x)    {        Object[] ids = null;        while (x.obj != null) {            ids = x.obj.getIds();            if (ids.length != 0) {                break;            }            x.obj = x.obj.getPrototype();        }        if (x.obj != null && x.ids != null) {            Object[] previous = x.ids;            int L = previous.length;            if (x.used == null) {                x.used = new ObjToIntMap(L);            }            for (int i = 0; i != L; ++i) {                x.used.intern(previous[i]);            }        }        x.ids = ids;        x.index = 0;    }    /**     * Prepare for calling name(...): return function corresponding to     * name and make current top scope available     * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj.     * The caller must call ScriptRuntime.lastStoredScriptable() immediately     * after calling this method.     */    public static Callable getNameFunctionAndThis(String name,                                                  Context cx,                                                  Scriptable scope)    {        Scriptable parent = scope.getParentScope();        if (parent == null) {            Object result = topScopeName(cx, scope, name);            if (!(result instanceof Callable)) {                if (result == Scriptable.NOT_FOUND) {                    throw notFoundError(scope, name);                } else {                    throw notFunctionError(result, name);                }            }            // Top scope is not NativeWith or NativeCall => thisObj == scope            Scriptable thisObj = scope;            storeScriptable(cx, thisObj);            return (Callable)result;        }        // name will call storeScriptable(cx, thisObj);        return (Callable)nameOrFunction(cx, scope, parent, name, true);    }    /**     * Prepare for calling obj[id](...): return function corresponding to     * obj[id] and make obj properly converted to Scriptable available     * as ScriptRuntime.lastStoredScriptable() for consumption as thisObj.     * The caller must call ScriptRuntime.lastStoredScriptable() immediately     * after calling this method.     */    public static Callable getElemFunctionAndThis(Object obj,                                                  Object elem,                                                  Context cx)    {        String s = toStringIdOrIndex(cx, elem);        if (s != null) {            return getPropFunctionAndThis(obj, s, cx);        }        int index = lastIndexResult(cx);        Scriptable thisObj = toObjectOrNull(cx, obj);        if (thisObj == null) {            throw undefCallError(obj, String.valueOf(index));        }        Object value;        for (;;) {            // Ignore XML lookup as requred by ECMA 357, 11.2.2.1            value = ScriptableObject.getProperty(thisObj, index);            if (value != Scriptable.NOT_FOUND) {                break;            }            if (!(thisObj instanceof XMLObject)) {                break;            }            XMLObject xmlObject = (XMLObject)thisObj;            Scriptable extra = xmlObject.getExtraMethodSource(cx);            if (extra == null) {                break;            }            thisObj = extra;        }        if (!(value instanceof Callable)) {            throw notFunctionError(value, elem);        }        st

⌨️ 快捷键说明

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