📄 idscriptableobject.java
字号:
} return super.has(name, start); } public Object get(String name, Scriptable start) { int info = findInstanceIdInfo(name); if (info != 0) { int id = (info & 0xFFFF); return getInstanceIdValue(id); } if (prototypeValues != null) { int id = prototypeValues.findId(name); if (id != 0) { return prototypeValues.get(id); } } return super.get(name, start); } public void put(String name, Scriptable start, Object value) { int info = findInstanceIdInfo(name); if (info != 0) { if (start == this && isSealed()) { throw Context.reportRuntimeError1("msg.modify.sealed", name); } int attr = (info >>> 16); if ((attr & READONLY) == 0) { if (start == this) { int id = (info & 0xFFFF); setInstanceIdValue(id, value); } else { start.put(name, start, value); } } return; } if (prototypeValues != null) { int id = prototypeValues.findId(name); if (id != 0) { if (start == this && isSealed()) { throw Context.reportRuntimeError1("msg.modify.sealed", name); } prototypeValues.set(id, start, value); return; } } super.put(name, start, value); } public void delete(String name) { int info = findInstanceIdInfo(name); if (info != 0) { // Let the super class to throw exceptions for sealed objects if (!isSealed()) { int attr = (info >>> 16); if ((attr & PERMANENT) == 0) { int id = (info & 0xFFFF); setInstanceIdValue(id, NOT_FOUND); } return; } } if (prototypeValues != null) { int id = prototypeValues.findId(name); if (id != 0) { if (!isSealed()) { prototypeValues.delete(id); } return; } } super.delete(name); } public int getAttributes(String name) { int info = findInstanceIdInfo(name); if (info != 0) { int attr = (info >>> 16); return attr; } if (prototypeValues != null) { int id = prototypeValues.findId(name); if (id != 0) { return prototypeValues.getAttributes(id); } } return super.getAttributes(name); } public void setAttributes(String name, int attributes) { ScriptableObject.checkValidAttributes(attributes); int info = findInstanceIdInfo(name); if (info != 0) { int currentAttributes = (info >>> 16); if (attributes != currentAttributes) { throw new RuntimeException( "Change of attributes for this id is not supported"); } return; } if (prototypeValues != null) { int id = prototypeValues.findId(name); if (id != 0) { prototypeValues.setAttributes(id, attributes); return; } } super.setAttributes(name, attributes); } Object[] getIds(boolean getAll) { Object[] result = super.getIds(getAll); if (prototypeValues != null) { result = prototypeValues.getNames(getAll, result); } int maxInstanceId = getMaxInstanceId(); if (maxInstanceId != 0) { Object[] ids = null; int count = 0; for (int id = maxInstanceId; id != 0; --id) { String name = getInstanceIdName(id); int info = findInstanceIdInfo(name); if (info != 0) { int attr = (info >>> 16); if ((attr & PERMANENT) == 0) { if (NOT_FOUND == getInstanceIdValue(id)) { continue; } } if (getAll || (attr & DONTENUM) == 0) { if (count == 0) { // Need extra room for no more then [1..id] names ids = new Object[id]; } ids[count++] = name; } } } if (count != 0) { if (result.length == 0 && ids.length == count) { result = ids; } else { Object[] tmp = new Object[result.length + count]; System.arraycopy(result, 0, tmp, 0, result.length); System.arraycopy(ids, 0, tmp, result.length, count); result = tmp; } } } return result; } /** * Get maximum id findInstanceIdInfo can generate. */ protected int getMaxInstanceId() { return 0; } protected static int instanceIdInfo(int attributes, int id) { return (attributes << 16) | id; } /** * Map name to id of instance property. * Should return 0 if not found or the result of * {@link #instanceIdInfo(int, int)}. */ protected int findInstanceIdInfo(String name) { return 0; } /** Map id back to property name it defines. */ protected String getInstanceIdName(int id) { throw new IllegalArgumentException(String.valueOf(id)); } /** Get id value. ** If id value is constant, descendant can call cacheIdValue to store ** value in the permanent cache. ** Default implementation creates IdFunctionObject instance for given id ** and cache its value */ protected Object getInstanceIdValue(int id) { throw new IllegalStateException(String.valueOf(id)); } /** * Set or delete id value. If value == NOT_FOUND , the implementation * should make sure that the following getInstanceIdValue return NOT_FOUND. */ protected void setInstanceIdValue(int id, Object value) { throw new IllegalStateException(String.valueOf(id)); } /** 'thisObj' will be null if invoked as constructor, in which case ** instance of Scriptable should be returned. */ public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { throw f.unknown(); } public final IdFunctionObject exportAsJSClass(int maxPrototypeId, Scriptable scope, boolean sealed) { // Set scope and prototype unless this is top level scope itself if (scope != this && scope != null) { setParentScope(scope); setPrototype(getObjectPrototype(scope)); } activatePrototypeMap(maxPrototypeId); IdFunctionObject ctor = prototypeValues.createPrecachedConstructor(); if (sealed) { sealObject(); } fillConstructorProperties(ctor); if (sealed) { ctor.sealObject(); } ctor.exportAsScopeProperty(); return ctor; } public final boolean hasPrototypeMap() { return prototypeValues != null; } public final void activatePrototypeMap(int maxPrototypeId) { PrototypeValues values = new PrototypeValues(this, maxPrototypeId); synchronized (this) { if (prototypeValues != null) throw new IllegalStateException(); prototypeValues = values; } } public final void initPrototypeMethod(Object tag, int id, String name, int arity) { Scriptable scope = ScriptableObject.getTopLevelScope(this); IdFunctionObject f = newIdFunction(tag, id, name, arity, scope); prototypeValues.initValue(id, name, f, DONTENUM); } public final void initPrototypeConstructor(IdFunctionObject f) { int id = prototypeValues.constructorId; if (id == 0) throw new IllegalStateException(); if (f.methodId() != id) throw new IllegalArgumentException(); if (isSealed()) { f.sealObject(); } prototypeValues.initValue(id, "constructor", f, DONTENUM); } public final void initPrototypeValue(int id, String name, Object value, int attributes) { prototypeValues.initValue(id, name, value, attributes); } protected void initPrototypeId(int id) { throw new IllegalStateException(String.valueOf(id)); } protected int findPrototypeId(String name) { throw new IllegalStateException(name); } protected void fillConstructorProperties(IdFunctionObject ctor) { } protected void addIdFunctionProperty(Scriptable obj, Object tag, int id, String name, int arity) { Scriptable scope = ScriptableObject.getTopLevelScope(obj); IdFunctionObject f = newIdFunction(tag, id, name, arity, scope); f.addAsProperty(obj); } /** * Utility method to construct type error to indicate incompatible call * when converting script thisObj to a particular type is not possible. * Possible usage would be to have a private function like realThis: * <pre> * private static NativeSomething realThis(Scriptable thisObj, * IdFunctionObject f) * { * if (!(thisObj instanceof NativeSomething)) * throw incompatibleCallError(f); * return (NativeSomething)thisObj; * } * </pre> * Note that although such function can be implemented universally via * java.lang.Class.isInstance(), it would be much more slower. * @param readOnly specify if the function f does not change state of * object. * @return Scriptable object suitable for a check by the instanceof * operator. * @throws RuntimeException if no more instanceof target can be found */ protected static EcmaError incompatibleCallError(IdFunctionObject f) { throw ScriptRuntime.typeError1("msg.incompat.call", f.getFunctionName()); } private IdFunctionObject newIdFunction(Object tag, int id, String name, int arity, Scriptable scope) { IdFunctionObject f = new IdFunctionObject(this, tag, id, name, arity, scope); if (isSealed()) { f.sealObject(); } return f; } private void readObject(ObjectInputStream stream) throws IOException, ClassNotFoundException { stream.defaultReadObject(); int maxPrototypeId = stream.readInt(); if (maxPrototypeId != 0) { activatePrototypeMap(maxPrototypeId); } } private void writeObject(ObjectOutputStream stream) throws IOException { stream.defaultWriteObject(); int maxPrototypeId = 0; if (prototypeValues != null) { maxPrototypeId = prototypeValues.getMaxId(); } stream.writeInt(maxPrototypeId); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -