From: brian Date: Fri, 30 Jan 2004 07:04:27 +0000 (+0000) Subject: 2003/08/14 07:01:48 X-Git-Tag: RC3~737 X-Git-Url: http://git.megacz.com/?a=commitdiff_plain;h=7aff6dbf6c8af7212fe187c404d3118626af8278;p=org.ibex.core.git 2003/08/14 07:01:48 darcs-hash:20040130070427-aa32f-6882599699fa6a65c8b04bff9eee2c7d587e685b.gz --- diff --git a/src/org/xwt/js/CompiledFunctionImpl.java b/src/org/xwt/js/CompiledFunctionImpl.java index 721b0a4..5771060 100644 --- a/src/org/xwt/js/CompiledFunctionImpl.java +++ b/src/org/xwt/js/CompiledFunctionImpl.java @@ -72,11 +72,14 @@ class CompiledFunctionImpl extends JSCallable implements ByteCodes, Tokens { cx.stack.push(args); eval(scope); Object ret = cx.stack.pop(); - // FIXME: if we catch an exception in Java, JS won't notice and the stack will be messed up if (cx.stack.size() > size) // this should never happen - throw new Error("ERROR: stack grew by " + (cx.stack.size() - size) + " elements during call"); + throw new Error("ERROR: stack grew by " + (cx.stack.size() - size) + " elements during call at " + sourceName + ":" + firstLine); return ret; + } catch(Error e) { + // Unwind the stack + while(cx.stack.size() > 0) if(cx.stack.pop() instanceof CallMarker) throw e; + throw new Error("CallMarker not found on the stack"); // should never happen } finally { cx.currentCompiledFunction = saved; } @@ -119,6 +122,7 @@ class CompiledFunctionImpl extends JSCallable implements ByteCodes, Tokens { int pc; int lastPC = -1; OUTER: for(pc=0; pc= 0; j--) arguments.setElementAt(t.pop(), j); Object o = t.pop(); if(o == null) throw je("attempted to call null"); - try { - Object ret; - if(op[pc] == CALLMETHOD) { - Object method = o; - o = t.pop(); - if(o instanceof String || o instanceof Number || o instanceof Boolean) - ret = Internal.callMethodOnPrimitive(o,method,arguments); - else if(o instanceof JS) - ret = ((JS)o).callMethod(method,arguments,false); - else - throw new JS.Exn("Tried to call a method on an object that isn't a JS object"); - } else { - ret = ((JS.Callable)o).call(arguments); - } - t.push(ret); - break; - } catch (JS.Exn e) { - t.push(e); + Object ret; + if(op[pc] == CALLMETHOD) { + Object method = o; + o = t.pop(); + if(o instanceof String || o instanceof Number || o instanceof Boolean) + ret = Internal.callMethodOnPrimitive(o,method,arguments); + else if(o instanceof JS) + ret = ((JS)o).callMethod(method,arguments,false); + else + throw new JS.Exn("Tried to call a method on an object that isn't a JS object"); + } else { + ret = ((JS.Callable)o).call(arguments); } + t.push(ret); + break; } // fall through if exception was thrown case THROW: { - Object exn = t.pop(); - while(t.size() > 0) { - Object o = t.pop(); - if (o instanceof CatchMarker || o instanceof TryMarker) { - boolean inCatch = o instanceof CatchMarker; - if(inCatch) { - o = t.pop(); - if(((TryMarker)o).finallyLoc < 0) continue; // no finally block, keep going - } - if(!inCatch && ((TryMarker)o).catchLoc >= 0) { - // run the catch block, this will implicitly run the finally block, if it exists - t.push(o); - t.push(catchMarker); - t.push((exn instanceof JS.Exn) ? ((JS.Exn)exn).getObject() : exn); - s = ((TryMarker)o).scope; - pc = ((TryMarker)o).catchLoc - 1; - continue OUTER; - } else { - t.push(exn); - t.push(new FinallyData(THROW)); - s = ((TryMarker)o).scope; - pc = ((TryMarker)o).finallyLoc - 1; - continue OUTER; - } - } - // no handler found within this func - if(o instanceof CallMarker) { - if(exn instanceof JS.Exn) - throw (JS.Exn)exn; - else - throw new JS.Exn(exn); - } - } - throw new Error("error: THROW invoked but couldn't find a Try or Call Marker!"); + Object o = t.pop(); + if(o instanceof JS.Exn) throw (JS.Exn)o; + throw new JS.Exn(o); } case INC: case DEC: { @@ -444,7 +413,37 @@ class CompiledFunctionImpl extends JSCallable implements ByteCodes, Tokens { default: throw new Error("unknown opcode " + op[pc]); } } } - } + } catch(JS.Exn e) { + while(t.size() > 0) { + Object o = t.pop(); + if (o instanceof CatchMarker || o instanceof TryMarker) { + boolean inCatch = o instanceof CatchMarker; + if(inCatch) { + o = t.pop(); + if(((TryMarker)o).finallyLoc < 0) continue; // no finally block, keep going + } + if(!inCatch && ((TryMarker)o).catchLoc >= 0) { + // run the catch block, this will implicitly run the finally block, if it exists + t.push(o); + t.push(catchMarker); + t.push(e.getObject()); + s = ((TryMarker)o).scope; + pc = ((TryMarker)o).catchLoc - 1; + continue OUTER; + } else { + t.push(e); + t.push(new FinallyData(THROW)); + s = ((TryMarker)o).scope; + pc = ((TryMarker)o).finallyLoc - 1; + continue OUTER; + } + } + // no handler found within this func + if(o instanceof CallMarker) throw e; + } + throw new Error("couldn't find a Try or Call Marker!"); + } // end try/catch + } // end for // this should never happen, we will ALWAYS have a RETURN at the end of the func throw new Error("Just fell out of CompiledFunction::eval() loop. Last PC was " + lastPC); }