public String coerceToString() { return clonee.coerceToString(); }
}
- public static class Obj extends LinearStore implements JS {
+ public static class Obj extends Basket.Hash implements JS {
private static final String[] emptystr = new String[0];
private static final Placeholder holder = new Placeholder();
public String[] getFormalArgs() { return emptystr; }
public Enumeration keys() throws JSExn {
- // FEATURE: replicate some code from a superclass to avoid double object creation
- return new Enumeration.JavaIterator(null, new LinearStore.IndexIterator() {
- public Object next() { return entries[nextIndex()]; } });
+ return new Enumeration(null) {
+ private int dest = -1, next = -1;
+ public boolean _hasNext() {
+ for (int i = Math.max(0, dest); i < usedslots; i++)
+ if (i > 0 ? entries[i * indexmultiple] != null : true &&
+ entries[i * indexmultiple] != this) { next = i; return true; }
+ return false;
+ }
+ public JS _next() throws JSExn {
+ if (next < 0 && !hasNext()) throw new NoSuchElementException();
+ int index = next; dest = next; next = -1;
+ return (JS)entries[index * indexmultiple];
+ }
+ };
}
public JS get(JS key) throws JSExn { int i = indexOf(key);
return i < 0 ? null : entries[i + 1] instanceof Placeholder ? null : (JS)entries[i + 1]; }
return (JS)new Interpreter(t, val, true).run(null);
}
- /** returns a callback which will restart the context; expects a value to be pushed onto the stack when unpaused */
- public static UnpauseCallback pause() throws NotPauseableException {
- Interpreter i = Interpreter.current();
- if (i.pausecount == -1) throw new NotPauseableException();
- boolean get;
- switch(i.f.op[i.pc]) {
- case Tokens.RETURN: case ByteCodes.PUT: get = false; break;
- case ByteCodes.GET: case ByteCodes.CALL: get = true; break;
- default: throw new Error("should never happen");
+ public void addTrap(JS key, JS f) throws JSExn {
+ if (f.getFormalArgs() == null || f.getFormalArgs().length > 1) throw new JSExn(
+ "traps must take either one argument (write) or no arguments (read)");
+ int i = indexOf(key); if (i < 0) i = put(i, key);
+ for (Trap t = (Trap)entries[i + 2]; t != null; t = t.next())
+ if (t.function().equals(f)) return;
+ entries[i + 2] = new TrapHolder(this, key, f, (Trap)entries[i + 2]);
}
public void delTrap(JS key, JS f) throws JSExn {