X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Fibex%2Fjs%2FInterpreter.java;h=6fc2859c30fe596b45c8625f83cb16a288f2ece2;hb=efb8222281235696686fd094844e1d2dcab916ae;hp=14f0f19899581397787f5f3bde5e08c914604208;hpb=44ef8d82de0e921098345942a6a68bfb264df1e4;p=org.ibex.core.git diff --git a/src/org/ibex/js/Interpreter.java b/src/org/ibex/js/Interpreter.java index 14f0f19..6fc2859 100644 --- a/src/org/ibex/js/Interpreter.java +++ b/src/org/ibex/js/Interpreter.java @@ -6,7 +6,7 @@ import java.util.*; /** Encapsulates a single JS interpreter (ie call stack) */ class Interpreter implements ByteCodes, Tokens { - + private static final int MAX_STACK_SIZE = 512; // Thread-Interpreter Mapping ///////////////////////////////////////////////////////////////////////// @@ -236,9 +236,6 @@ class Interpreter implements ByteCodes, Tokens { while (t != null && t.f.numFormalArgs == 0) t = t.next; if (t == null) { target = ts.t.trapee; key = ts.t.name; } - } else if (target instanceof Trap.TrapScope && key.equals(((Trap.TrapScope)target).t.name)) { - throw je("tried to put to " + key + " inside a trap it owns; use cascade instead"); - } else if (target instanceof JS) { if (target instanceof JSScope) { JSScope p = (JSScope)target; // search the scope-path for the trap @@ -251,6 +248,7 @@ class Interpreter implements ByteCodes, Tokens { } if (t != null) { stack.push(new CallMarker(this)); + if(stack.size() > MAX_STACK_SIZE) throw new JSExn("stack overflow"); JSArray args = new JSArray(); args.addElement(val); stack.push(args); @@ -302,6 +300,7 @@ class Interpreter implements ByteCodes, Tokens { } if (t != null) { stack.push(new CallMarker(this)); + if(stack.size() > MAX_STACK_SIZE) throw new JSExn("stack overflow"); JSArray args = new JSArray(); stack.push(args); f = t.f; @@ -352,6 +351,7 @@ class Interpreter implements ByteCodes, Tokens { JSArray arguments = new JSArray(); for(int i=0; i MAX_STACK_SIZE) throw new JSExn("stack overflow"); stack.push(arguments); f = (JSFunction)object; scope = new JSScope(f.parentScope); @@ -402,7 +402,17 @@ class Interpreter implements ByteCodes, Tokens { Object key = stack.pop(); Object obj = stack.peek(); // A trap addition/removal - JS js = obj instanceof JSScope ? ((JSScope)obj).top() : (JS) obj; + JS js = (JS) obj; + if(js instanceof JSScope) { + JSScope s = (JSScope) js; + while(s.getParentScope() != null) { + if(s.has(key)) throw new JSExn("cannot trap a variable that isn't at the top level scope"); + s = s.getParentScope(); + } + js = s; + } + // might want this? + // if(!js.has(key)) throw new JSExn("tried to add/remove a trap from an uninitialized variable"); if(op == ADD_TRAP) js.addTrap(key, (JSFunction)val); else js.delTrap(key, (JSFunction)val); break; @@ -486,7 +496,7 @@ class Interpreter implements ByteCodes, Tokens { if (right == null) right = JS.N(0); int result = 0; if (left instanceof String || right instanceof String) { - result = left.toString().compareTo(right.toString()); + result = JS.toString(left).compareTo(JS.toString(right)); } else { result = (int)java.lang.Math.ceil(JS.toDouble(left) - JS.toDouble(right)); } @@ -497,6 +507,7 @@ class Interpreter implements ByteCodes, Tokens { case EQ: case NE: { + // FIXME: This is not correct, see ECMA-262 11.9.3 Object l = left; Object r = right; boolean ret; @@ -505,7 +516,7 @@ class Interpreter implements ByteCodes, Tokens { else if (r == null) ret = false; // l != null, so its false else if (l instanceof Boolean) ret = JS.B(JS.toBoolean(r)).equals(l); else if (l instanceof Number) ret = JS.toNumber(r).doubleValue() == JS.toNumber(l).doubleValue(); - else if (l instanceof String) ret = r != null && l.equals(r.toString()); + else if (l instanceof String) ret = r != null && l.equals(JS.toString(r)); else ret = l.equals(r); stack.push(JS.B(op == EQ ? ret : !ret)); break; } @@ -652,13 +663,13 @@ class Interpreter implements ByteCodes, Tokens { return sb.toString(); } case "indexOf": { - String search = alength >= 1 ? arg0.toString() : "null"; + String search = alength >= 1 ? JS.toString(arg0) : "null"; int start = alength >= 2 ? JS.toInt(arg1) : 0; // Java's indexOf handles an out of bounds start index, it'll return -1 return JS.N(s.indexOf(search,start)); } case "lastIndexOf": { - String search = alength >= 1 ? arg0.toString() : "null"; + String search = alength >= 1 ? JS.toString(arg0) : "null"; int start = alength >= 2 ? JS.toInt(arg1) : 0; // Java's indexOf handles an out of bounds start index, it'll return -1 return JS.N(s.lastIndexOf(search,start)); @@ -696,7 +707,7 @@ class Interpreter implements ByteCodes, Tokens { } if (!returnJS) { // the string stuff applies to everything - String s = o.toString(); + String s = JS.toString(o); // this is sort of ugly, but this list should never change // These should provide a complete (enough) implementation of the ECMA-262 String object @@ -711,7 +722,7 @@ class Interpreter implements ByteCodes, Tokens { case "lastIndexOf": returnJS = true; break; case "match": returnJS = true; break; case "replace": returnJS = true; break; - case "seatch": returnJS = true; break; + case "search": returnJS = true; break; case "slice": returnJS = true; break; case "split": returnJS = true; break; case "toLowerCase": returnJS = true; break; @@ -722,7 +733,7 @@ class Interpreter implements ByteCodes, Tokens { } if (returnJS) { final Object target = o; - final String method = key.toString(); + final String method = JS.toString(o); return new JS() { public Object call(Object a0, Object a1, Object a2, Object[] rest, int nargs) throws JSExn { if (nargs > 2) throw new JSExn("cannot call that method with that many arguments");