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

📄 scriptableobject.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
    /**     * Puts an indexed property in an object or in an object in its prototype chain.     * <p>     * Seaches for the indexed property in the prototype chain. If it is found,     * the value of the property in <code>obj</code> is changed through a call     * to {@link Scriptable#put(int, Scriptable, Object)} on the prototype     * passing <code>obj</code> as the <code>start</code> argument. This allows     * the prototype to veto the property setting in case the prototype defines     * the property with [[ReadOnly]] attribute. If the property is not found,      * it is added in <code>obj</code>.     * @param obj a JavaScript object     * @param index a property index     * @param value any JavaScript value accepted by Scriptable.put     * @since 1.5R2     */    public static void putProperty(Scriptable obj, int index, Object value)    {        Scriptable base = getBase(obj, index);        if (base == null)            base = obj;        base.put(index, obj, value);    }    /**     * Removes the property from an object or its prototype chain.     * <p>     * Searches for a property with <code>name</code> in obj or     * its prototype chain. If it is found, the object's delete     * method is called.     * @param obj a JavaScript object     * @param name a property name     * @return true if the property doesn't exist or was successfully removed     * @since 1.5R2     */    public static boolean deleteProperty(Scriptable obj, String name)    {        Scriptable base = getBase(obj, name);        if (base == null)            return true;        base.delete(name);        return !base.has(name, obj);    }    /**     * Removes the property from an object or its prototype chain.     * <p>     * Searches for a property with <code>index</code> in obj or     * its prototype chain. If it is found, the object's delete     * method is called.     * @param obj a JavaScript object     * @param index a property index     * @return true if the property doesn't exist or was successfully removed     * @since 1.5R2     */    public static boolean deleteProperty(Scriptable obj, int index)    {        Scriptable base = getBase(obj, index);        if (base == null)            return true;        base.delete(index);        return !base.has(index, obj);    }    /**     * Returns an array of all ids from an object and its prototypes.     * <p>     * @param obj a JavaScript object     * @return an array of all ids from all object in the prototype chain.     *         If a given id occurs multiple times in the prototype chain,     *         it will occur only once in this list.     * @since 1.5R2     */    public static Object[] getPropertyIds(Scriptable obj)    {        if (obj == null) {            return ScriptRuntime.emptyArgs;        }        Object[] result = obj.getIds();        ObjToIntMap map = null;        for (;;) {            obj = obj.getPrototype();            if (obj == null) {                break;            }            Object[] ids = obj.getIds();            if (ids.length == 0) {                continue;            }            if (map == null) {                if (result.length == 0) {                    result = ids;                    continue;                }                map = new ObjToIntMap(result.length + ids.length);                for (int i = 0; i != result.length; ++i) {                    map.intern(result[i]);                }                result = null; // Allow to GC the result            }            for (int i = 0; i != ids.length; ++i) {                map.intern(ids[i]);            }        }        if (map != null) {            result = map.getKeys();        }        return result;    }    /**     * Call a method of an object.     * @param obj the JavaScript object     * @param methodName the name of the function property     * @param args the arguments for the call     *     * @see Context#getCurrentContext()     */    public static Object callMethod(Scriptable obj, String methodName,                                    Object[] args)    {        return callMethod(null, obj, methodName, args);    }    /**     * Call a method of an object.     * @param cx the Context object associated with the current thread.     * @param obj the JavaScript object     * @param methodName the name of the function property     * @param args the arguments for the call     */    public static Object callMethod(Context cx, Scriptable obj,                                    String methodName,                                    Object[] args)    {        Object funObj = getProperty(obj, methodName);        if (!(funObj instanceof Function)) {            throw ScriptRuntime.notFunctionError(obj, methodName);        }        Function fun = (Function)funObj;        // XXX: What should be the scope when calling funObj?        // The following favor scope stored in the object on the assumption        // that is more useful especially under dynamic scope setup.        // An alternative is to check for dynamic scope flag        // and use ScriptableObject.getTopLevelScope(fun) if the flag is not        // set. But that require access to Context and messy code        // so for now it is not checked.        Scriptable scope = ScriptableObject.getTopLevelScope(obj);        if (cx != null) {            return fun.call(cx, scope, obj, args);        } else {            return Context.call(null, fun, scope, obj, args);        }    }    private static Scriptable getBase(Scriptable obj, String name)    {        do {            if (obj.has(name, obj))                break;            obj = obj.getPrototype();        } while(obj != null);        return obj;    }    private static Scriptable getBase(Scriptable obj, int index)    {        do {            if (obj.has(index, obj))                break;            obj = obj.getPrototype();        } while(obj != null);        return obj;    }    /**     * Get arbitrary application-specific value associated with this object.     * @param key key object to select particular value.     * @see #associateValue(Object key, Object value)     */    public final Object getAssociatedValue(Object key)    {        Hashtable h = associatedValues;        if (h == null)            return null;        return h.get(key);    }    /**     * Get arbitrary application-specific value associated with the top scope     * of the given scope.     * The method first calls {@link #getTopLevelScope(Scriptable scope)}     * and then searches the prototype chain of the top scope for the first     * object containing the associated value with the given key.     *     * @param scope the starting scope.     * @param key key object to select particular value.     * @see #getAssociatedValue(Object key)     */    public static Object getTopScopeValue(Scriptable scope, Object key)    {        scope = ScriptableObject.getTopLevelScope(scope);        for (;;) {            if (scope instanceof ScriptableObject) {                ScriptableObject so = (ScriptableObject)scope;                Object value = so.getAssociatedValue(key);                if (value != null) {                    return value;                }            }            scope = scope.getPrototype();            if (scope == null) {                return null;            }        }    }    /**     * Associate arbitrary application-specific value with this object.     * Value can only be associated with the given object and key only once.     * The method ignores any subsequent attempts to change the already     * associated value.     * <p> The associated values are not serilized.     * @param key key object to select particular value.     * @param value the value to associate     * @return the passed value if the method is called first time for the     * given key or old value for any subsequent calls.     * @see #getAssociatedValue(Object key)     */    public final Object associateValue(Object key, Object value)    {        if (value == null) throw new IllegalArgumentException();        Hashtable h = associatedValues;        if (h == null) {            synchronized (this) {                h = associatedValues;                if (h == null) {                    h = new Hashtable();                    associatedValues = h;                }            }        }        return Kit.initHash(h, key, value);    }    private Object getByGetter(GetterSlot slot, Scriptable start)    {        Object getterThis;        Object[] args;        if (slot.delegateTo == null) {            if (start != this) {                // Walk the prototype chain to find an appropriate                // object to invoke the getter on.                Class clazz = slot.getter.getDeclaringClass();                while (!clazz.isInstance(start)) {                    start = start.getPrototype();                    if (start == this) {                        break;                    }                    if (start == null) {                        start = this;                        break;                    }                }            }            getterThis = start;            args = ScriptRuntime.emptyArgs;        } else {            getterThis = slot.delegateTo;            args = new Object[] { this };        }        return slot.getter.invoke(getterThis, args);    }    private void setBySetter(GetterSlot slot, Scriptable start, Object value)    {        if (start != this) {            if (slot.delegateTo != null                || !slot.setter.getDeclaringClass().isInstance(start))            {                start.put(slot.stringKey, start, value);                return;            }        }        Object setterThis;        Object[] args;        Object setterResult;        Context cx = Context.getContext();        Class pTypes[] = slot.setter.argTypes;        Class desired = pTypes[pTypes.length - 1];        // ALERT: cache tag since it is already calculated in defineProperty ?        int tag = FunctionObject.getTypeTag(desired);        Object actualArg = FunctionObject.convertArg(cx, start, value, tag);        if (slot.delegateTo == null) {            setterThis = start;            args = new Object[] { actualArg };        } else {            if (start != this) Kit.codeBug();            setterThis = slot.delegateTo;            args = new Object[] { this, actualArg };        }        // Check start is sealed: start is always instance of ScriptableObject        // due to logic in if (start != this) above        if (((ScriptableObject)start).isSealed()) {            throw Context.reportRuntimeError1("msg.modify.sealed",                                              slot.stringKey);        }        setterResult = slot.setter.invoke(setterThis, args);        if (slot.setter.method().getReturnType() != Void.TYPE) {            // Replace Getter slot by a simple one            Slot replacement = new Slot();            replacement.intKey = slot.intKey;            replacement.stringKey = slot.stringKey;            replacement.attributes = slot.attributes;            replacement.value = setterResult;            synchronized (this) {                int i = getSlotPosition(slots, slot.stringKey, slot.intKey);                // Check slot was not deleted/replaced before synchronization                if (i >= 0 && slots[i] == slot) {                    slots[i] = replacement;                    // It is important to make sure that lastAccess != slot                    // to prevent accessing the old slot via lastAccess and                    // then invoking setter one more time                    lastAccess = replacement;                }            }        }    }    private Slot getNamedSlot(String name)    {        // Query last access cache and check that it was not deleted        Slot slot = lastAccess;        if (name == slot.stringKey && slot.wasDeleted == 0) {            return slot;        }        int hash = name.hashCode();        Slot[] slots = this.slots; // Get stable local reference        int i = getSlotPosition(slots, name, hash);        if (i < 0) {            return null;        }        slot = slots[i];        // Update cache - here stringKey.equals(name) holds, but it can b

⌨️ 快捷键说明

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