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]; }
package org.ibex.js;
import java.io.InputStream;
-import java.util.*;
import org.ibex.util.*;
-import org.ibex.util.Collections;
/** A JavaScript JSArray */
-class JSArray extends ArrayList implements JS, Comparator {
+class JSArray extends Basket.Array implements JS, Basket.CompareFunc {
private static final JS.Method METHOD = new JS.Method();
private static final String[] empty = new String[0];
JSArray(JS arg) { super(1); add(arg); }
public JS unclone() { return this; }
- public JS.Enumeration keys() throws JSExn { return new Enumeration.RandomAccessList(null, this); }
+ public JS.Enumeration keys() throws JSExn {
+ return new Enumeration(null) {
+ private int pos = 0;
+ public boolean _hasNext() { return pos < size(); }
+ public JS _next() { return (JS)JSArray.this.get(pos++); }
+ };
+ }
public JS get(JS key) throws JSExn {
if (key == null || !(key instanceof JSNumber.I)) {
//#switch(Script.str(key))
"arrays only support positive integer keys, can not use: "+Script.str(key));
int i = ((JSNumber.I)key).toInt();
if (i < 0) throw new JSExn("arrays can not use negative integer keys "+i);
- ensureCapacity(i + 1); while (size() < i) add(null);
+ size(i + 1); while (size() < i) add(null);
set(i, val);
}
public InputStream getInputStream() { return null; }
//#switch(Script.str(method))
case "pop": return size() == 0 ? null : (JS)remove(size() - 1);
case "push": addAll(args); return Script.N(size());
- case "reverse": Collections.reverse(this); return this;
+ case "reverse": reverse(); return this;
case "toString": return join(",");
case "shift": return size() == 0 ? null : (JS)remove(0);
case "join": return join(args.length == 0 ? "," : Script.str(args[0]));
public void addAll(JS[] entries) { for (int i=0; i < entries.length; i++) add(entries[i]); }
public void setSize(int newSize) {
- ensureCapacity(newSize);
+ size(newSize);
for (int i=size(); i < newSize; i++) add(null);
for (int i=size() - 1; i >= newSize; i--) remove(i);
}
return ret;
}
+ private static final Basket.CompareFunc defaultSort = new Basket.CompareFunc() {
+ public int compare(Object a, Object b) {
+ try { return Script.toString((JS)a).compareTo(Script.toString((JS)b)); }
+ catch (JSExn e) { throw new JSExn.Wrapper(e); }
+ }
+ };
private JS sort(JS comparator) throws JSExn {
try {
- if (comparator == null) Collections.sort(this);
- else { sort = comparator; Collections.sort(this, this); }
+ if (comparator == null) sort(defaultSort);
+ else { sort = comparator; sort((CompareFunc)this); }
return this;
- } catch (JSExn.Wrapper w) { throw w.unwrap(); }
+ } catch (JSExn.Wrapper w) { throw w.unwrap();
+ } finally { sort = null; }
}
private JS sort = null;
private final JS[] sortargs = new JS[2];
- public int compare(java.lang.Object a, java.lang.Object b) throws JSExn.Wrapper {
+ public int compare(Object a, Object b) throws JSExn.Wrapper {
try {
sortargs[0] = (JS)a; sortargs[1] = (JS)b;
return Script.toInt(sort.call(sortargs));
package org.ibex.js;
-import org.ibex.util.*;
+import org.ibex.util.*;
import java.io.*;
/** An exception which can be thrown and caught by JavaScript code */
public class JSExn extends Exception {
- private List backtrace = new ArrayList();
+ private Basket.List backtrace = new Basket.Array();
private JS js;
public JSExn(String s) { this(Script.S(s)); }
public JSExn(JS js) { this(js,null); }
}
// Local variable management
- List scopeStack = new ArrayList();
+ Basket.Array scopeStack = new Basket.Array();
static class ScopeInfo {
int base;
int end;
JS scopeKey(String name) {
if(globalCache.get(name) != null) return null;
for(int i=scopeStack.size()-1;i>=0;i--) {
- JS key = (JS)((ScopeInfo) scopeStack.elementAt(i)).mapping.get(name);
+ JS key = (JS)((ScopeInfo) scopeStack.get(i)).mapping.get(name);
if(key != null) return key;
}
globalCache.put(name,Boolean.TRUE);
return null;
}
void scopeDeclare(String name) throws IOException {
- ScopeInfo si = (ScopeInfo) scopeStack.lastElement();
+ ScopeInfo si = (ScopeInfo) scopeStack.peek();
if(si.mapping.get(name) != null) throw pe("" + name + " already declared in this scope");
si.mapping.put(name,JS.N(si.end++));
globalCache.put(name,null);
}
void scopePush(JSFunction b) {
- ScopeInfo prev = (ScopeInfo) scopeStack.lastElement();
+ ScopeInfo prev = (ScopeInfo) scopeStack.peek();
ScopeInfo si = new ScopeInfo();
si.base = prev.end;
si.end = si.base;
JSFunction ret = new JSFunction(sourceName, firstLine, null);
if (sourceCode == null) return ret;
Parser p = new Parser(sourceCode, sourceName, firstLine);
- p.scopeStack.setSize(0);
+ p.scopeStack.clear();
p.scopeStack.push(new ScopeInfo());
p.scopePush(ret);
while(true) {
int catchJMPDistance = -1;
if (peekToken() == CATCH) {
- Vec catchEnds = new Vec();
+ Basket.List catchEnds = new Basket.Array();
boolean catchAll = false;
catchJMPDistance = b.size - tryInsn;
scopePop(b);
b.add(parserLine, JMP);
- catchEnds.addElement(new Integer(b.size-1));
+ catchEnds.add(new Integer(b.size-1));
for(int i=0; i<3; i++) if (writebacks[i] != -1) b.set(writebacks[i], JS.N(b.size-writebacks[i]));
b.add(parserLine, POP); // pop the element thats on the stack from the compare
b.add(parserLine, THROW);
for(int i=0;i<catchEnds.size();i++) {
- int n = ((Integer)catchEnds.elementAt(i)).intValue();
+ int n = ((Integer)catchEnds.get(i)).intValue();
b.set(n, JS.N(b.size-n));
}