bug 469492 - calling the call hook after fully initializing the freame. p=igor r=brendan a=dveditz

git-svn-id: svn://10.0.0.236/trunk@258096 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
mrbkap%gmail.com 2009-08-13 04:47:12 +00:00
parent 2d5c16f9da
commit d6ddaaef71

View File

@ -1076,9 +1076,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);
@ -1119,9 +1118,19 @@ have_fun:
if (FUN_INTERPRETED(fun)) {
native = NULL;
script = fun->u.i.script;
JS_ASSERT(script);
nvars = fun->u.i.nvars;
} 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;
nvars = 0;
nslots += fun->u.n.extra;
@ -1260,6 +1269,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.spbase = NULL;
frame.sharpDepth = 0;
@ -1267,7 +1277,6 @@ have_fun:
frame.flags = flags | rootedArgsFlag;
frame.dormantNext = NULL;
frame.xmlNamespace = NULL;
frame.blockChain = NULL;
/* From here on, control must flow through label out: to return. */
cx->fp = &frame;
@ -1276,8 +1285,32 @@ 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, parent)) {
ok = JS_FALSE;
goto out;
}
}
}
/* 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. */
@ -1290,40 +1323,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;
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, parent)) {
ok = JS_FALSE;
goto out;
}
}
ok = js_Interpret(cx);
} else {
/* fun might be onerror trying to report a syntax error in itself. */
frame.scopeChain = NULL;
ok = JS_TRUE;
JS_ASSERT(script);
ok = js_Interpret(cx);
}
out: