ESBase unshift(Call eval, int length) throws Throwable { ESObject obj = eval.getArg(-1).toObject(); ESBase lenObj = obj.getProperty(LENGTH); int len = lenObj.toInt32(); if (len < 0) len = 0; if (length == 0) return ESNumber.create(0); for (int i = len - 1; i >= 0; i--) { ESBase value = obj.getProperty(i); if (value == null) obj.delete(ESString.create(length + i)); else obj.setProperty(length + i, value); } for (int i = 0; i < length; i++) { ESBase value = eval.getArg(i); if (value == null) obj.delete(ESString.create(i)); else obj.setProperty(i, value); } ESNumber numLen = ESNumber.create(len + length); obj.setProperty(LENGTH, numLen); return numLen; }
ESBase splice(Call eval, int length) throws Throwable { if (length < 2) return esUndefined; ESObject obj = eval.getArg(-1).toObject(); int index = eval.getArg(0).toInt32(); int count = eval.getArg(1).toInt32(); boolean single = count == 1; ESBase lenObj = obj.getProperty(LENGTH); int len = lenObj.toInt32(); if (index < 0) index += len; if (index < 0) index = 0; if (count < 0) count = 0; if (index + count > len) count = len - index; ESBase value; if (count < 1) value = esUndefined; else { value = Global.getGlobalProto().createArray(); for (int i = 0; i < count; i++) value.setProperty(i, obj.getProperty(index + i)); } int delta = length - 2 - count; if (delta < 0) { for (int i = 0; i < len - count; i++) { ESBase temp = obj.getProperty(i + index + count); if (temp == null) obj.delete(ESString.create(i + index + count + delta)); else obj.setProperty(i + index + count + delta, temp); } } else if (delta > 0) { for (int i = len - count - 1; i >= 0; i--) { ESBase temp = obj.getProperty(i + index + count); if (temp == null) obj.delete(ESString.create(i + index + count + delta)); else obj.setProperty(i + index + count + delta, temp); } } for (int i = 0; i < length - 2; i++) obj.setProperty(i + index, eval.getArg(i + 2)); obj.setProperty(LENGTH, ESNumber.create(len - count + length - 2)); return value; }
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; } } }
static ESBase join(ESObject array, String separator) throws Throwable { if (array.mark != 0) { return ESString.create("..."); } array.mark = -1; try { int len = array.getProperty(LENGTH).toInt32(); StringBuffer sbuf = new StringBuffer(); for (int i = 0; i < len; i++) { if (i != 0) sbuf.append(separator); ESBase value = array.hasProperty(i); if (value != null && value != esNull && value != esUndefined) sbuf.append(value.toString()); } return ESString.create(sbuf.toString()); } finally { array.mark = 0; } }
/** 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; } }
ESBase shift(Call eval, int length) throws Throwable { ESObject obj = eval.getArg(-1).toObject(); ESBase lenObj = obj.hasProperty(LENGTH); int len; if (lenObj == null || (len = (int) lenObj.toInt32()) <= 0) return esUndefined; ESBase value = obj.getProperty(0); for (int i = 1; i < len; i++) { ESBase temp = obj.hasProperty(i); if (temp == null) obj.delete(ESString.create(i - 1)); else obj.setProperty(i - 1, temp); } obj.setProperty(LENGTH, ESNumber.create(len - 1)); return value; }
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 ESBase typeof() throws ESException { return ESString.create("object"); }
/** Sets the named property */ public void put(int i, ESBase value, int flags) { put(ESString.create(i), value, flags); }
/** returns the string representation */ public ESString toStr() throws ESException { return ESString.create("[global]"); }
/** Returns the string representation of the type. */ public ESBase typeof() throws ESException { return ESString.create("function"); }