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

📄 idscriptableobject.java

📁 java中比较著名的js引擎当属mozilla开源的rhino
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* -*- Mode: java; tab-width: 4; indent-tabs-mode: 1; c-basic-offset: 4 -*- * * ***** 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-1999 * the Initial Developer. All Rights Reserved. * * Contributor(s): *   Igor Bukanov * * 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;import java.io.*;/**Base class for native object implementation that uses IdFunctionObject to export its methods to script via <class-name>.prototype object.Any descendant should implement at least the following methods:    findInstanceIdInfo    getInstanceIdName    execIdCall    methodArityTo define non-function properties, the descendant should override    getInstanceIdValue    setInstanceIdValueto get/set property value and provide its default attributes.To customize initializition of constructor and protype objects, descendantmay override scopeInit or fillConstructorProperties methods.*/public abstract class IdScriptableObject extends ScriptableObject    implements IdFunctionCall{    private transient volatile PrototypeValues prototypeValues;    private static final class PrototypeValues implements Serializable    {        static final long serialVersionUID = 3038645279153854371L;        private static final int VALUE_SLOT = 0;        private static final int NAME_SLOT = 1;        private static final int SLOT_SPAN = 2;        private IdScriptableObject obj;        private Object tag;        private int maxId;        private volatile Object[] valueArray;        private volatile short[] attributeArray;        private volatile int lastFoundId = 1;        // The following helps to avoid creation of valueArray during runtime        // initialization for common case of "constructor" property        int constructorId;        private IdFunctionObject constructor;        private short constructorAttrs;        PrototypeValues(IdScriptableObject obj, int maxId)        {            if (obj == null) throw new IllegalArgumentException();            if (maxId < 1) throw new IllegalArgumentException();            this.obj = obj;            this.maxId = maxId;        }        final int getMaxId()        {            return maxId;        }        final void initValue(int id, String name, Object value, int attributes)        {            if (!(1 <= id && id <= maxId))                throw new IllegalArgumentException();            if (name == null)                throw new IllegalArgumentException();            if (value == NOT_FOUND)                throw new IllegalArgumentException();            ScriptableObject.checkValidAttributes(attributes);            if (obj.findPrototypeId(name) != id)                throw new IllegalArgumentException(name);            if (id == constructorId) {                if (!(value instanceof IdFunctionObject)) {                    throw new IllegalArgumentException("consructor should be initialized with IdFunctionObject");                }                constructor = (IdFunctionObject)value;                constructorAttrs = (short)attributes;                return;            }            initSlot(id, name, value, attributes);        }        private void initSlot(int id, String name, Object value,                              int attributes)        {            Object[] array = valueArray;            if (array == null)                throw new IllegalStateException();            if (value == null) {                value = UniqueTag.NULL_VALUE;            }            int index = (id - 1) * SLOT_SPAN;            synchronized (this) {                Object value2 = array[index + VALUE_SLOT];                if (value2 == null) {                    array[index + VALUE_SLOT] = value;                    array[index + NAME_SLOT] = name;                    attributeArray[id - 1] = (short)attributes;                } else {                    if (!name.equals(array[index + NAME_SLOT]))                         throw new IllegalStateException();                }            }        }        final IdFunctionObject createPrecachedConstructor()        {            if (constructorId != 0) throw new IllegalStateException();            constructorId = obj.findPrototypeId("constructor");            if (constructorId == 0) {                throw new IllegalStateException(                    "No id for constructor property");            }            obj.initPrototypeId(constructorId);            if (constructor == null) {                throw new IllegalStateException(                    obj.getClass().getName()+".initPrototypeId() did not "                    +"initialize id="+constructorId);            }            constructor.initFunction(obj.getClassName(),                                     ScriptableObject.getTopLevelScope(obj));            constructor.markAsConstructor(obj);            return constructor;        }        final int findId(String name)        {            Object[] array = valueArray;            if (array == null) {                return obj.findPrototypeId(name);            }            int id = lastFoundId;            if (name == array[(id - 1) * SLOT_SPAN + NAME_SLOT]) {                return id;            }            id = obj.findPrototypeId(name);            if (id != 0) {                int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT;                // Make cache to work!                array[nameSlot] = name;                lastFoundId = id;            }            return id;        }        final boolean has(int id)        {            Object[] array = valueArray;            if (array == null) {                // Not yet initialized, assume all exists                return true;            }            int valueSlot = (id  - 1) * SLOT_SPAN + VALUE_SLOT;            Object value = array[valueSlot];            if (value == null) {                // The particular entry has not been yet initialized                return true;            }            return value != NOT_FOUND;        }        final Object get(int id)        {            Object value = ensureId(id);            if (value == UniqueTag.NULL_VALUE) {                value = null;            }            return value;        }        final void set(int id, Scriptable start, Object value)        {            if (value == NOT_FOUND) throw new IllegalArgumentException();            ensureId(id);            int attr = attributeArray[id - 1];            if ((attr & READONLY) == 0) {                if (start == obj) {                    if (value == null) {                        value = UniqueTag.NULL_VALUE;                    }                    int valueSlot = (id  - 1) * SLOT_SPAN + VALUE_SLOT;                    synchronized (this) {                        valueArray[valueSlot] = value;                    }                }                else {                    int nameSlot = (id  - 1) * SLOT_SPAN + NAME_SLOT;                    String name = (String)valueArray[nameSlot];                    start.put(name, start, value);                }            }        }        final void delete(int id)        {            ensureId(id);            int attr = attributeArray[id - 1];            if ((attr & PERMANENT) == 0) {                int valueSlot = (id  - 1) * SLOT_SPAN + VALUE_SLOT;                synchronized (this) {                    valueArray[valueSlot] = NOT_FOUND;                    attributeArray[id - 1] = EMPTY;                }            }        }        final int getAttributes(int id)        {            ensureId(id);            return attributeArray[id - 1];        }        final void setAttributes(int id, int attributes)        {            ScriptableObject.checkValidAttributes(attributes);            ensureId(id);            synchronized (this) {                attributeArray[id - 1] = (short)attributes;            }        }        final Object[] getNames(boolean getAll, Object[] extraEntries)        {            Object[] names = null;            int count = 0;            for (int id = 1; id <= maxId; ++id) {                Object value = ensureId(id);                if (getAll || (attributeArray[id - 1] & DONTENUM) == 0) {                    if (value != NOT_FOUND) {                        int nameSlot = (id  - 1) * SLOT_SPAN + NAME_SLOT;                        String name = (String)valueArray[nameSlot];                        if (names == null) {                            names = new Object[maxId];                        }                        names[count++] = name;                    }                }            }            if (count == 0) {                return extraEntries;            } else if (extraEntries == null || extraEntries.length == 0) {                if (count != names.length) {                    Object[] tmp = new Object[count];                    System.arraycopy(names, 0, tmp, 0, count);                    names = tmp;                }                return names;            } else {                int extra = extraEntries.length;                Object[] tmp = new Object[extra + count];                System.arraycopy(extraEntries, 0, tmp, 0, extra);                System.arraycopy(names, 0, tmp, extra, count);                return tmp;            }        }        private Object ensureId(int id)        {            Object[] array = valueArray;            if (array == null) {                synchronized (this) {                    array = valueArray;                    if (array == null) {                        array = new Object[maxId * SLOT_SPAN];                        valueArray = array;                        attributeArray = new short[maxId];                    }                }            }            int valueSlot = (id  - 1) * SLOT_SPAN + VALUE_SLOT;            Object value = array[valueSlot];            if (value == null) {                if (id == constructorId) {                    initSlot(constructorId, "constructor",                             constructor, constructorAttrs);                    constructor = null; // no need to refer it any longer                } else {                    obj.initPrototypeId(id);                }                value = array[valueSlot];                if (value == null) {                    throw new IllegalStateException(                        obj.getClass().getName()+".initPrototypeId(int id) "                        +"did not initialize id="+id);                }            }            return value;        }    }    public IdScriptableObject()    {    }    public IdScriptableObject(Scriptable scope, Scriptable prototype)    {        super(scope, prototype);    }    protected final Object defaultGet(String name)    {        return super.get(name, this);    }    protected final void defaultPut(String name, Object value)    {        super.put(name, this, value);    }    public boolean has(String name, Scriptable start)    {        int info = findInstanceIdInfo(name);        if (info != 0) {            int attr = (info >>> 16);            if ((attr & PERMANENT) != 0) {                return true;            }            int id = (info & 0xFFFF);            return NOT_FOUND != getInstanceIdValue(id);        }        if (prototypeValues != null) {            int id = prototypeValues.findId(name);            if (id != 0) {                return prototypeValues.has(id);            }

⌨️ 快捷键说明

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