bug 469492 - calling the call hook after fully initializing the freame. r=brendan

This commit is contained in:
Igor Bukanov 2009-03-30 15:29:17 +02:00
Родитель 1b89a19e2e
Коммит 221bc79d4a
1 изменённых файлов: 43 добавлений и 37 удалений

Просмотреть файл

@ -1132,9 +1132,8 @@ js_Invoke(JSContext *cx, uintN argc, jsval *vp, uintN flags)
* XXX better to call that hook without converting
* XXX the only thing that needs fixing is liveconnect
*
* Try converting to function, for closure and API compatibility.
* We attempt the conversion under all circumstances for 1.2, but
* only if there is a call op defined otherwise.
* FIXME bug 408416: try converting to function, for API compatibility
* if there is a call op defined.
*/
if ((ops == &js_ObjectOps) ? clasp->call : ops->call) {
ok = clasp->convert(cx, funobj, JSTYPE_FUNCTION, &v);
@ -1175,8 +1174,18 @@ have_fun:
if (FUN_INTERPRETED(fun)) {
native = NULL;
script = fun->u.i.script;
JS_ASSERT(script);
} else {
native = fun->u.n.native;
if (!native) {
/*
* FIXME bug 485905: we should disallow native functions with
* null fun->u.n.native.
*/
*vp = (flags & JSINVOKE_CONSTRUCT) ? vp[1] : JSVAL_VOID;
ok = JS_TRUE;
goto out2;
}
script = NULL;
nslots += fun->u.n.extra;
}
@ -1299,6 +1308,7 @@ have_fun:
frame.down = cx->fp;
frame.annotation = NULL;
frame.scopeChain = NULL; /* set below for real, after cx->fp is set */
frame.blockChain = NULL;
frame.regs = NULL;
frame.imacpc = NULL;
frame.slots = NULL;
@ -1307,7 +1317,7 @@ have_fun:
frame.flags = flags | rootedArgsFlag;
frame.dormantNext = NULL;
frame.xmlNamespace = NULL;
frame.blockChain = NULL;
frame.displaySave = NULL;
MUST_FLOW_THROUGH("out");
cx->fp = &frame;
@ -1316,8 +1326,33 @@ have_fun:
hook = cx->debugHooks->callHook;
hookData = NULL;
/* call the hook if present */
if (hook && (native || script))
if (native) {
/* If native, use caller varobj and scopeChain for eval. */
JS_ASSERT(!frame.varobj);
JS_ASSERT(!frame.scopeChain);
if (frame.down) {
frame.varobj = frame.down->varobj;
frame.scopeChain = frame.down->scopeChain;
}
/* But ensure that we have a scope chain. */
if (!frame.scopeChain)
frame.scopeChain = parent;
} else {
/* Use parent scope so js_GetCallObject can find the right "Call". */
frame.scopeChain = parent;
if (JSFUN_HEAVYWEIGHT_TEST(fun->flags)) {
/* Scope with a call object parented by the callee's parent. */
if (!js_GetCallObject(cx, &frame)) {
ok = JS_FALSE;
goto out;
}
}
frame.slots = sp - fun->u.i.nvars;
}
/* Call the hook if present after we fully initialized the frame. */
if (hook)
hookData = hook(cx, &frame, JS_TRUE, 0, cx->debugHooks->callHookData);
/* Call the function, either a native method or an interpreted script. */
@ -1330,44 +1365,15 @@ have_fun:
/* Set by JS_SetCallReturnValue2, used to return reference types. */
cx->rval2set = JS_FALSE;
#endif
/* If native, use caller varobj and scopeChain for eval. */
JS_ASSERT(!frame.varobj);
JS_ASSERT(!frame.scopeChain);
if (frame.down) {
frame.varobj = frame.down->varobj;
frame.scopeChain = frame.down->scopeChain;
}
/* But ensure that we have a scope chain. */
if (!frame.scopeChain)
frame.scopeChain = parent;
frame.displaySave = NULL;
ok = native(cx, frame.thisp, argc, frame.argv, &frame.rval);
JS_RUNTIME_METER(cx->runtime, nativeCalls);
#ifdef DEBUG_NOT_THROWING
if (ok && !alreadyThrowing)
ASSERT_NOT_THROWING(cx);
#endif
} else if (script) {
/* Use parent scope so js_GetCallObject can find the right "Call". */
frame.scopeChain = parent;
if (JSFUN_HEAVYWEIGHT_TEST(fun->flags)) {
/* Scope with a call object parented by the callee's parent. */
if (!js_GetCallObject(cx, &frame)) {
ok = JS_FALSE;
goto out;
}
}
frame.slots = sp - fun->u.i.nvars;
ok = js_Interpret(cx);
} else {
/* fun might be onerror trying to report a syntax error in itself. */
frame.scopeChain = NULL;
frame.displaySave = NULL;
ok = JS_TRUE;
JS_ASSERT(script);
ok = js_Interpret(cx);
}
out: