X-Git-Url: http://git.megacz.com/?p=org.ibex.core.git;a=blobdiff_plain;f=src%2Forg%2Fibex%2Fjs%2FInterpreter.java;h=983b47173b03694fc55b23a917f1e220176ae1b8;hp=92b29a4657f0c646a848351e9c8ee0beeb77325e;hb=bf8dd22d35e1f8f5afd6896d65a4f106305665d3;hpb=4c2d51015dcd304759b31bd0835ae85cd4cf7aab diff --git a/src/org/ibex/js/Interpreter.java b/src/org/ibex/js/Interpreter.java index 92b29a4..983b471 100644 --- a/src/org/ibex/js/Interpreter.java +++ b/src/org/ibex/js/Interpreter.java @@ -217,10 +217,22 @@ class Interpreter implements ByteCodes, Tokens { throw je("tried to assign \"" + (val==null?"(null)":val.toString()) + "\" to the null key"); Trap t = null; - if (target instanceof Trap.TrapScope && key.equals("cascade")) { - Trap.TrapScope ts = (Trap.TrapScope)target; - t = ts.t.next; - ts.cascadeHappened = true; + if (target instanceof JSScope && key.equals("cascade")) { + Trap.TrapScope ts = null; + JSScope p = (JSScope)target; // search the scope-path for the trap + if (target instanceof Trap.TrapScope) { + ts = (Trap.TrapScope)target; + } + else { + while (ts == null && p.getParentScope() != null) { + p = p.getParentScope(); + if (p instanceof Trap.TrapScope) { + ts = (Trap.TrapScope)p; + } + } + } + t = ts.t.next; + ts.cascadeHappened = true; while (t != null && t.f.numFormalArgs == 0) t = t.next; if (t == null) { target = ts.t.trapee; key = ts.t.name; } @@ -235,21 +247,13 @@ class Interpreter implements ByteCodes, Tokens { } else { t = ((JS)target).getTrap(key); } - while (t != null && t.f.numFormalArgs == 0) t = t.next; // find the first write trap - if (t != null) { - stack.push(new CallMarker(this)); - JSArray args = new JSArray(); - args.addElement(val); - stack.push(args); - } } if (t != null) { - stack.pop(); stack.push(new CallMarker(this)); - stack.push(target); JSArray args = new JSArray(); args.addElement(val); + stack.push(args); f = t.f; scope = new Trap.TrapScope(f.parentScope, t, val); pc = -1; @@ -368,7 +372,8 @@ class Interpreter implements ByteCodes, Tokens { } case THROW: - throw new JSExn(stack.pop()); + throw new JSExn(stack.pop(), stack, f, pc, scope); + /* FIXME case MAKE_GRAMMAR: { final Grammar r = (Grammar)arg; @@ -481,7 +486,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)); } @@ -492,6 +497,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; @@ -500,7 +506,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; } @@ -510,7 +516,6 @@ class Interpreter implements ByteCodes, Tokens { } } catch(JSExn e) { - if(f.op[pc] != FINALLY_DONE) e.addBacktrace(f.sourceName,f.line[pc]); while(stack.size() > 0) { Object o = stack.pop(); if (o instanceof CatchMarker || o instanceof TryMarker) { @@ -535,12 +540,6 @@ class Interpreter implements ByteCodes, Tokens { pc = ((TryMarker)o).finallyLoc - 1; continue OUTER; } - } else if(o instanceof CallMarker) { - CallMarker cm = (CallMarker) o; - if(cm.f == null) - e.addBacktrace("",0); // This might not even be worth mentioning - else - e.addBacktrace(cm.f.sourceName,cm.f.line[cm.pc-1]); } } throw e; @@ -654,13 +653,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)); @@ -691,14 +690,14 @@ class Interpreter implements ByteCodes, Tokens { static Object getFromPrimitive(Object o, Object key) throws JSExn { boolean returnJS = false; if (o instanceof Boolean) { - throw new JSExn("cannot call methods on Booleans"); + throw new JSExn("Booleans do not have properties"); } else if (o instanceof Number) { if (key.equals("toPrecision") || key.equals("toExponential") || key.equals("toFixed")) returnJS = true; } 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 @@ -713,7 +712,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; @@ -724,7 +723,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");