From 221bc79d4a86152012eb08582e85347526474499 Mon Sep 17 00:00:00 2001 From: Igor Bukanov Date: Mon, 30 Mar 2009 15:29:17 +0200 Subject: [PATCH] bug 469492 - calling the call hook after fully initializing the freame. r=brendan --- js/src/jsinterp.cpp | 80 ++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 37 deletions(-) diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index e3ce221179f..55b2e2e757c 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -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: