📄 esobject.java
字号:
while (true) { ESString propName = propNames[hash]; if (propValues[hash] == null) { if (! prototype.canPut(name)) return; if (propName == null) fill++; propNames[hash] = name; propValues[hash] = esEmpty; propFlags[hash] = WATCH; if (propWatch == null) propWatch = new ESBase[propFlags.length]; propWatch[hash] = fun; size++; if (propNames.length <= 4 * size) resize(4 * propNames.length); else if (propNames.length <= 2 * fill) refill(); return; } else if (propName != name && ! propName.equals(name)) { hash = (hash + 1) & mask; continue; } else if ((propFlags[hash] & READ_ONLY) != 0) return; else { propFlags[hash] |= WATCH; if (propWatch == null) propWatch = new ESBase[propFlags.length]; propWatch[hash] = fun; return; } } } public void unwatch(ESString name) { if (copyState != DIRTY) { if (copyState == COW) copyAll(); copyState = DIRTY; } int hash = name.hashCode() & mask; while (true) { ESString propName = propNames[hash]; if (propName == null) return; else if (propName.equals(name)) { propFlags[hash] &= ~WATCH; return; } } } /** * Sets the named property */ public void put(int i, ESBase value, int flags) { put(ESString.create(i), value, flags); } public Iterator keys() throws ESException { return new PropertyEnumeration(this); } public ESBase typeof() throws ESException { return ESString.create("object"); } /** * XXX: not right */ public ESBase toPrimitive(int hint) throws Throwable { Global resin = Global.getGlobalProto(); Call eval = resin.getCall(); eval.global = resin.getGlobal(); try { ESBase fun = hasProperty(hint == STRING ? TO_STRING : VALUE_OF); if (fun instanceof ESClosure || fun instanceof Native) { eval.stack[0] = this; eval.top = 1; ESBase value = fun.call(eval, 0); if (value instanceof ESBase && ! (value instanceof ESObject)) return value; } fun = hasProperty(hint == STRING ? VALUE_OF : TO_STRING); if (fun instanceof ESClosure || fun instanceof Native) { eval.stack[0] = this; eval.top = 1; ESBase value = fun.call(eval, 0); if (value instanceof ESBase && ! (value instanceof ESObject)) return value; } throw new ESException("cannot convert object to primitive type"); } finally { resin.freeCall(eval); } } public ESObject toObject() { return this; } public Object toJavaObject() throws ESException { return this; } /** * Returns a string rep of the object */ public double toNum() throws Throwable { ESBase value = toPrimitive(NUMBER); if (value instanceof ESObject) throw new ESException("toPrimitive must return primitive"); return value.toNum(); } /** * Returns a string rep of the object */ public ESString toStr() throws Throwable { ESBase prim = toPrimitive(STRING); if (prim instanceof ESObject) throw new ESException("toPrimitive must return primitive"); return prim.toStr(); } public ESString toSource(IntMap map, boolean isLoopPass) throws Throwable { CharBuffer cb = new CharBuffer(); Global resin = Global.getGlobalProto(); int mark = map.get(this); if (mark > 0 && isLoopPass) return null; else if (mark > 0) { cb.append("#" + mark + "="); map.put(this, -mark); } else if (mark == 0 && isLoopPass) { map.put(this, resin.addMark()); return null; } else if (mark < 0 && ! isLoopPass) { return ESString.create("#" + -mark + "#"); } cb.append("{"); if (isLoopPass) map.put(this, 0); Iterator e = keys(); boolean isFirst = true; while (e.hasNext()) { if (! isFirst) cb.append(", "); isFirst = false; ESString key = (ESString) e.next(); cb.append(key); cb.append(":"); ESBase value = getProperty(key); if (isLoopPass) value.toSource(map, isLoopPass); else cb.append(value.toSource(map, isLoopPass)); } cb.append("}"); return new ESString(cb.toString()); } public boolean toBoolean() { return true; } ESObject dup() { return new ESObject(); } public Object copy(HashMap refs) { Object ref = refs.get(this); if (ref != null) return ref; ESObject copy = dup(); refs.put(this, copy); copy(refs, copy); return copy; } private void copyAll() { copyState = DIRTY; int len = propValues.length; ESString []newPropNames = new ESString[len]; int []newPropFlags = new int[len]; ESBase []newPropValues = new ESBase[len]; System.arraycopy(propNames, 0, newPropNames, 0, len); System.arraycopy(propFlags, 0, newPropFlags, 0, len); System.arraycopy(propValues, 0, newPropValues, 0, len); propNames = newPropNames; propFlags = newPropFlags; propValues = newPropValues; if (propWatch != null) { ESBase []newPropWatch = new ESBase[len]; System.arraycopy(propWatch, 0, newPropWatch, 0, len); propWatch = newPropWatch; } } ESObject resinCopy() { ESObject obj = dup(); copy(obj); return obj; } protected void copy(Object newObj) { ESObject obj = (ESObject) newObj; obj.prototype = prototype; obj.className = className; obj.propNames = propNames; obj.propValues = propValues; obj.propFlags = propFlags; obj.propWatch = propWatch; obj.size = size; obj.fill = fill; obj.mask = mask; obj.copyState = copyState; if (obj.copyState == DIRTY) { throw new RuntimeException(); } else if (copyState == CLEAN) { copyState = COW; obj.copyState = COW; } } protected void copy(HashMap refs, Object newObj) { ESObject obj = (ESObject) newObj; obj.prototype = (ESBase) prototype.copy(refs); obj.className = className; obj.propNames = propNames; obj.propValues = propValues; obj.propFlags = propFlags; obj.propWatch = propWatch; obj.size = size; obj.fill = fill; obj.mask = mask; obj.copyState = copyState; if (obj.copyState == DIRTY) { obj.copyAll(); } else if (copyState == CLEAN) { copyState = COW; obj.copyState = COW; } } ESObject shallowCopy() { ESObject obj = dup(); shallowCopy(obj); return obj; } protected void shallowCopy(Object newObj) { ESObject obj = (ESObject) newObj; obj.prototype = prototype; obj.className = className; int len = propValues.length; if (propWatch != null) { obj.propWatch = new ESBase[len]; System.arraycopy(propWatch, 0, obj.propWatch, 0, len); } obj.propNames = new ESString[len]; obj.propFlags = new int[len]; obj.propValues = new ESBase[len]; ESString []newNames = obj.propNames; ESString []oldNames = propNames; ESBase []newValues = obj.propValues; ESBase []oldValues = propValues; int []newFlags = obj.propFlags; int []oldFlags = propFlags; for (int i = 0; i < len; i++) { newNames[i] = oldNames[i]; newValues[i] = oldValues[i]; newFlags[i] = oldFlags[i]; } obj.size = size; obj.mask = mask; obj.fill = fill; obj.copyState = DIRTY; } public boolean ecmaEquals(ESBase b) throws Throwable { if (b instanceof ESObject || b instanceof ESThunk) return this == b; else return toPrimitive(NONE).ecmaEquals(b); } public ESBase call(Call call, int length) throws Throwable { ESBase callFun = hasProperty(CALL); if (callFun != null) { call.setThis(this); return callFun.call(call, length); } throw new ESNullException(toStr() + " is not a function"); } public ESBase construct(Call call, int length) throws Throwable { ESBase callFun = hasProperty(CONSTRUCT); if (callFun != null) { call.setThis(this); return callFun.construct(call, length); } throw new ESNullException(toStr() + " is not a constructor"); }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -