Create a side-entry path into the interpreter that bypasses the initialization code and allows switching back and forth between two interpreters (i.e. tracing and non-tracing).

This commit is contained in:
Andreas Gal 2008-06-10 17:45:38 -07:00
parent 17d0d41459
commit b5238a9929
3 changed files with 51 additions and 26 deletions

View File

@ -1318,7 +1318,7 @@ have_fun:
goto out;
}
}
ok = js_Interpret(cx);
ok = js_Interpret(cx, 0);
} else {
/* fun might be onerror trying to report a syntax error in itself. */
frame.scopeChain = NULL;
@ -1541,7 +1541,7 @@ js_Execute(JSContext *cx, JSObject *chain, JSScript *script,
cx->debugHooks->executeHookData);
}
ok = js_Interpret(cx);
ok = js_Interpret(cx, 0);
*result = frame.rval;
if (hookData) {
@ -2682,7 +2682,7 @@ JS_STATIC_ASSERT(JSOP_SETNAME_LENGTH == JSOP_SETPROP_LENGTH);
JS_STATIC_ASSERT(JSOP_DEFFUN_LENGTH == JSOP_CLOSURE_LENGTH);
JSBool
JS_INTERPRET(JSContext *cx)
JS_INTERPRET(JSContext *cx, JSInterpreterState *state)
{
JSRuntime *rt;
JSStackFrame *fp;
@ -2749,9 +2749,7 @@ JS_INTERPRET(JSContext *cx)
# include "jsopcode.tbl"
# undef OPDEF
};
METER_OP_INIT(op); /* to nullify first METER_OP_PAIR */
# define DO_OP() JS_EXTENSION_(goto *jumpTable[op])
# define DO_NEXT_OP(n) JS_BEGIN_MACRO \
METER_OP_PAIR(op, regs.pc[n]); \
@ -2801,6 +2799,40 @@ JS_INTERPRET(JSContext *cx)
#endif
/*
* Load the debugger's interrupt hook here and after calling out to native
* functions (but not to getters, setters, or other native hooks), so we do
* not have to reload it each time through the interpreter loop -- we hope
* the compiler can keep it in a register when it is non-null.
*/
#if JS_THREADED_INTERP
# define LOAD_INTERRUPT_HANDLER(cx) \
((void) (jumpTable = (cx)->debugHooks->interruptHandler \
? interruptJumpTable \
: normalJumpTable))
#else
# define LOAD_INTERRUPT_HANDLER(cx) \
((void) (switchMask = (cx)->debugHooks->interruptHandler ? 0 : 255))
#endif
LOAD_INTERRUPT_HANDLER(cx);
if (state != 0) {
rt = state->rt;
fp = state->fp;
script = state->script;
inlineCallCount = state->inlineCallCount;
atoms = state->atoms;
currentVersion = state->currentVersion;
originalVersion = state->originalVersion;
mark = state->mark;
regs = state->regs;
op = (JSOp) *regs.pc;
DO_OP();
}
METER_OP_INIT(op); /* to nullify first METER_OP_PAIR */
/* Check for too deep of a native thread stack. */
JS_CHECK_RECURSION(cx, return JS_FALSE);
@ -2883,24 +2915,6 @@ JS_INTERPRET(JSContext *cx)
/*
* From this point control must flow through the label exit2.
*
* Load the debugger's interrupt hook here and after calling out to native
* functions (but not to getters, setters, or other native hooks), so we do
* not have to reload it each time through the interpreter loop -- we hope
* the compiler can keep it in a register when it is non-null.
*/
#if JS_THREADED_INTERP
# define LOAD_INTERRUPT_HANDLER(cx) \
((void) (jumpTable = (cx)->debugHooks->interruptHandler \
? interruptJumpTable \
: normalJumpTable))
#else
# define LOAD_INTERRUPT_HANDLER(cx) \
((void) (switchMask = (cx)->debugHooks->interruptHandler ? 0 : 255))
#endif
LOAD_INTERRUPT_HANDLER(cx);
/*
* Initialize the pc register and allocate operand stack slots for the
* script's worst-case depth, unless we're resuming a generator.
*/

View File

@ -101,6 +101,17 @@ typedef struct JSInlineFrame {
JSVersion callerVersion; /* dynamic version of calling script */
} JSInlineFrame;
typedef struct JSInterpreterState {
JSRuntime *rt;
JSStackFrame *fp;
JSScript *script;
uintN inlineCallCount;
JSAtom **atoms;
JSVersion currentVersion, originalVersion;
void *mark;
JSFrameRegs regs;
};
/* JS stack frame flags. */
#define JSFRAME_CONSTRUCTING 0x01 /* frame is for a constructor invocation */
#define JSFRAME_COMPUTED_THIS 0x02 /* frame.thisp was computed already */
@ -458,7 +469,7 @@ extern JSBool
js_InvokeConstructor(JSContext *cx, uintN argc, jsval *vp);
extern JSBool
js_Interpret(JSContext *cx);
js_Interpret(JSContext *cx, JSInterpreterState *state);
#define JSPROP_INITIALIZER 0x100 /* NB: Not a valid property attribute. */

View File

@ -883,7 +883,7 @@ SendToGenerator(JSContext *cx, JSGeneratorOp op, JSObject *obj,
fp = cx->fp;
cx->fp = &gen->frame;
gen->frame.down = fp;
ok = js_Interpret(cx);
ok = js_Interpret(cx, 0);
cx->fp = fp;
gen->frame.down = NULL;