protected boolean canPut(ESString name) { int hash = name.hashCode() & mask; while (true) { ESString propName = propNames[hash]; if (name.equals(propName) && propValues[hash] != null) return (propFlags[hash] & READ_ONLY) == 0; else if (propName == null) { if (prototype instanceof ESObject) return ((ESObject) prototype).canPut(name); else return true; } hash = (hash + 1) & mask; } }
/** Puts a new value in the property table with the appropriate flags */ public void setProperty(ESString name, ESBase value) throws Throwable { if (copyState != DIRTY) { if (copyState == COW) copyAll(); copyState = DIRTY; } if (value == esEmpty) value = esUndefined; int hash = name.hashCode() & mask; while (true) { ESString propName = propNames[hash]; if (propValues[hash] == null) { if (!prototype.canPut(name)) return; if (propName == null) fill++; propNames[hash] = name; /* if ((propFlags[hash] & WATCH) != 0) value = callWatch(name, hash, value); */ propValues[hash] = value; propFlags[hash] = 0; 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 { /* if ((propFlags[hash] & WATCH) != 0) value = callWatch(name, hash, value); */ propValues[hash] = value; return; } } }
/** Gets a property value. */ public ESBase getProperty(ESString name) throws Throwable { int hash = name.hashCode() & mask; while (true) { ESString propName = propNames[hash]; if (propName == name || name.equals(propName)) { ESBase value = propValues[hash]; return value == null ? prototype.getProperty(name) : value; } else if (propName == null) { ESBase value = prototype.getProperty(name); if (snapPrototype) setProperty(name, value); return value; } hash = (hash + 1) & mask; } }
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; } } }
public void watch(ESString name, ESBase fun) { if (copyState != DIRTY) { if (copyState == COW) copyAll(); copyState = DIRTY; } int hash = name.hashCode() & mask; 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; } } }
/** Deletes the entry. Returns true if successful. */ public ESBase delete(ESString name) throws Throwable { if (copyState != DIRTY) { if (copyState == COW) copyAll(); copyState = DIRTY; } int hash = name.hashCode() & mask; while (true) { ESString hashName = propNames[hash]; if (hashName == null) return ESBoolean.FALSE; else if (propValues[hash] != null && hashName.equals(name)) { if ((propFlags[hash] & DONT_DELETE) != 0) return ESBoolean.FALSE; else { propValues[hash] = null; size--; return ESBoolean.TRUE; } } hash = (hash + 1) & mask; } }
public void put(ESString name, ESBase value, int flags) { int hash = name.hashCode() & mask; while (true) { ESString propName = propNames[hash]; if (propName == null || propValues[hash] == null || propName.equals(name)) { if (propName == null) fill++; if (propValues[hash] == null) size++; propNames[hash] = name; propValues[hash] = value; propFlags[hash] = flags; if (propNames.length <= 4 * size) { resize(4 * propNames.length); } else if (propNames.length <= 2 * fill) refill(); return; } hash = (hash + 1) & mask; } }