Fix bungled attempt to ComputeThis before __noSuchMethod__ extension (225423, r=shaver, a=asa).

This commit is contained in:
brendan%mozilla.org 2003-11-26 02:46:50 +00:00
Родитель d36a85645e
Коммит b8206857f8
1 изменённых файлов: 30 добавлений и 19 удалений

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

@ -661,23 +661,13 @@ js_Invoke(JSContext *cx, uintN argc, uintN flags)
* Once vp is set, control should flow through label out2: to return.
* Set frame.rval early so native class and object ops can throw and
* return false, causing a goto out2 with ok set to false. Also set
* frame.flags and frame.argv so that ComputeThis can use them.
* frame.flags to flags so that ComputeThis can test bits in it.
*/
vp = sp - (2 + argc);
v = *vp;
frame.rval = JSVAL_VOID;
frame.flags = flags;
frame.argv = sp - argc;
/*
* Compute the 'this' parameter and store it in frame as frame.thisp.
* Do this early for the JS_HAS_NO_SUCH_METHOD special case. We "know"
* that ComputeThis depends on only frame.{argv,flags}.
*/
ok = ComputeThis(cx, JSVAL_TO_OBJECT(vp[1]), &frame);
if (!ok)
goto out2;
thisp = frame.thisp;
thisp = JSVAL_TO_OBJECT(vp[1]);
/*
* A callee must be an object reference, unless its |this| parameter
@ -700,6 +690,26 @@ js_Invoke(JSContext *cx, uintN argc, uintN flags)
if (!fp->script || (flags & JSINVOKE_INTERNAL))
goto bad;
/*
* We must ComputeThis here to censor Call objects; performance hit,
* but at least it's idempotent.
*
* Normally, we call ComputeThis after all frame members have been
* set, and in particular, after any revision of the callee value at
* *vp due to clasp->convert (see below). This matters because
* ComputeThis may access *vp via fp->argv[-2], to follow the parent
* chain to a global object to use as the |this| parameter.
*
* Obviously, here in the JSVAL_IS_PRIMITIVE(v) case, there can't be
* any such defaulting of |this| to callee (v, *vp) ancestor.
*/
frame.argv = vp + 2;
ok = ComputeThis(cx, thisp, &frame);
if (!ok)
goto out2;
thisp = frame.thisp;
ok = OBJ_GET_PROPERTY(cx, thisp,
(jsid)cx->runtime->atomState.noSuchMethodAtom,
&v);
@ -737,7 +747,6 @@ js_Invoke(JSContext *cx, uintN argc, uintN flags)
}
newsp[1] = OBJECT_TO_JSVAL(thisp);
sp = newsp + 4;
frame.argv = newsp + 2;
} else if ((jsuword)sp > a->avail) {
/*
* Inline, optimized version of JS_ARENA_ALLOCATE to claim
@ -816,16 +825,13 @@ have_fun:
thisp = parent;
}
/* Initialize frame except for the already-initialized rval, flags, argv,
* thisp, and sp members. Null varobj, spbase, and other pointer members
* which will be set conditionally.
*/
/* Initialize frame except for varobj, thisp, sp, spbase, and scopeChain. */
frame.varobj = NULL;
frame.callobj = frame.argsobj = NULL;
frame.script = script;
frame.fun = fun;
frame.argc = argc;
JS_ASSERT(frame.argv == sp - argc);
frame.argv = sp - argc;
frame.nvars = nvars;
frame.vars = sp;
frame.down = fp;
@ -838,6 +844,11 @@ have_fun:
frame.dormantNext = NULL;
frame.objAtomMap = NULL;
/* Compute the 'this' parameter and store it in frame as frame.thisp. */
ok = ComputeThis(cx, thisp, &frame);
if (!ok)
goto out2;
/* From here on, control must flow through label out: to return. */
cx->fp = &frame;
@ -3496,7 +3507,7 @@ js_Interpret(JSContext *cx, jsval *result)
if (!obj) {
/*
* If arguments was not overridden by eval('arguments = ...'),
* set obj to the magic cookie respected by ComputeThis, just
* set obj to the magic cookie respected by JSOP_PUSHOBJ, just
* in case this bytecode is part of an 'arguments[i](j, k)' or
* similar such invocation sequence, where the function that
* is invoked expects its 'this' parameter to be the caller's