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;
}
int pc;
int lastPC = -1;
OUTER: for(pc=0; pc<size; pc++) {
+ try {
String label = null;
cx.pc = lastPC = pc;
int curOP = op[pc];
for(int j=numArgs - 1; j >= 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: {
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);
}