зеркало из https://github.com/mozilla/pjs.git
Bug 636296 - Change meaning of JSStackFrame::hasCallObj to be more sane (r=waldo)
This commit is contained in:
Родитель
02a6d56e11
Коммит
fb28814119
|
@ -1494,14 +1494,13 @@ JS_GetFrameCallObject(JSContext *cx, JSStackFrame *fp)
|
|||
if (!ac.enter())
|
||||
return NULL;
|
||||
|
||||
/* Force creation of argument object if not yet created */
|
||||
(void) js_GetArgsObject(cx, fp);
|
||||
|
||||
/*
|
||||
* XXX ill-defined: null return here means error was reported, unlike a
|
||||
* null returned above or in the #else
|
||||
*/
|
||||
return js_GetCallObject(cx, fp);
|
||||
if (!fp->hasCallObj() && fp->isNonEvalFunctionFrame())
|
||||
return CreateFunCallObject(cx, fp);
|
||||
return &fp->callObj();
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(JSBool)
|
||||
|
|
|
@ -295,7 +295,7 @@ InitExnPrivate(JSContext *cx, JSObject *exnObject, JSString *message,
|
|||
stackDepth = 0;
|
||||
valueCount = 0;
|
||||
for (fp = js_GetTopStackFrame(cx); fp; fp = fp->prev()) {
|
||||
if (fp->isFunctionFrame() && !fp->isEvalFrame()) {
|
||||
if (fp->isNonEvalFunctionFrame()) {
|
||||
Value v = NullValue();
|
||||
if (checkAccess &&
|
||||
!checkAccess(cx, &fp->callee(), callerid, JSACC_READ, &v)) {
|
||||
|
|
|
@ -946,16 +946,17 @@ CalleeGetter(JSContext *cx, JSObject *obj, jsid id, Value *vp)
|
|||
return CheckForEscapingClosure(cx, obj, vp);
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Construct a call object for the given bindings. The callee is the function
|
||||
* on behalf of which the call object is being created.
|
||||
* Construct a call object for the given bindings. If this is a call object
|
||||
* for a function invocation, callee should be the function being called.
|
||||
* Otherwise it must be a call object for eval of strict mode code, and callee
|
||||
* must be null.
|
||||
*/
|
||||
JSObject *
|
||||
NewCallObject(JSContext *cx, Bindings *bindings, JSObject &scopeChain, JSObject *callee)
|
||||
static JSObject *
|
||||
NewCallObject(JSContext *cx, JSScript *script, JSObject &scopeChain, JSObject *callee)
|
||||
{
|
||||
size_t argsVars = bindings->countArgsAndVars();
|
||||
Bindings &bindings = script->bindings;
|
||||
size_t argsVars = bindings.countArgsAndVars();
|
||||
size_t slots = JSObject::CALL_RESERVED_SLOTS + argsVars;
|
||||
gc::FinalizeKind kind = gc::GetGCObjectKind(slots);
|
||||
|
||||
|
@ -984,8 +985,6 @@ NewCallObject(JSContext *cx, Bindings *bindings, JSObject &scopeChain, JSObject
|
|||
return callobj;
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
||||
static inline JSObject *
|
||||
NewDeclEnvObject(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
|
@ -1002,39 +1001,28 @@ NewDeclEnvObject(JSContext *cx, JSStackFrame *fp)
|
|||
return envobj;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
js_GetCallObject(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
/* Create a call object for fp only if it lacks one. */
|
||||
JS_ASSERT(fp->isFunctionFrame());
|
||||
if (fp->hasCallObj())
|
||||
return &fp->callObj();
|
||||
namespace js {
|
||||
|
||||
#ifdef DEBUG
|
||||
/* A call object should be a frame's outermost scope chain element. */
|
||||
Class *clasp = fp->scopeChain().getClass();
|
||||
if (clasp == &js_WithClass || clasp == &js_BlockClass)
|
||||
JS_ASSERT(fp->scopeChain().getPrivate() != js_FloatingFrameIfGenerator(cx, fp));
|
||||
else if (clasp == &js_CallClass)
|
||||
JS_ASSERT(fp->scopeChain().getPrivate() != fp);
|
||||
#endif
|
||||
JSObject *
|
||||
CreateFunCallObject(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
JS_ASSERT(fp->isNonEvalFunctionFrame());
|
||||
JS_ASSERT(!fp->hasCallObj());
|
||||
|
||||
JSObject *scopeChain = &fp->scopeChain();
|
||||
JS_ASSERT_IF(scopeChain->isWith() || scopeChain->isBlock() || scopeChain->isCall(),
|
||||
scopeChain->getPrivate() != fp);
|
||||
|
||||
/*
|
||||
* Create the call object, using the frame's enclosing scope as its
|
||||
* parent, and link the call to its stack frame. For a named function
|
||||
* expression Call's parent points to an environment object holding
|
||||
* function's name.
|
||||
* For a named function expression Call's parent points to an environment
|
||||
* object holding function's name.
|
||||
*/
|
||||
JSAtom *lambdaName =
|
||||
(fp->fun()->flags & JSFUN_LAMBDA) ? fp->fun()->atom : NULL;
|
||||
if (lambdaName) {
|
||||
JSObject *envobj = NewDeclEnvObject(cx, fp);
|
||||
if (!envobj)
|
||||
if (JSAtom *lambdaName = (fp->fun()->flags & JSFUN_LAMBDA) ? fp->fun()->atom : NULL) {
|
||||
scopeChain = NewDeclEnvObject(cx, fp);
|
||||
if (!scopeChain)
|
||||
return NULL;
|
||||
|
||||
/* Root envobj before js_DefineNativeProperty (-> JSClass.addProperty). */
|
||||
fp->setScopeChainNoCallObj(*envobj);
|
||||
if (!js_DefineNativeProperty(cx, &fp->scopeChain(), ATOM_TO_JSID(lambdaName),
|
||||
if (!js_DefineNativeProperty(cx, scopeChain, ATOM_TO_JSID(lambdaName),
|
||||
ObjectValue(fp->callee()),
|
||||
CalleeGetter, NULL,
|
||||
JSPROP_PERMANENT | JSPROP_READONLY,
|
||||
|
@ -1043,29 +1031,36 @@ js_GetCallObject(JSContext *cx, JSStackFrame *fp)
|
|||
}
|
||||
}
|
||||
|
||||
JSObject *callobj =
|
||||
NewCallObject(cx, &fp->fun()->script()->bindings, fp->scopeChain(), &fp->callee());
|
||||
JSObject *callobj = NewCallObject(cx, fp->script(), *scopeChain, &fp->callee());
|
||||
if (!callobj)
|
||||
return NULL;
|
||||
|
||||
callobj->setPrivate(fp);
|
||||
JS_ASSERT(fp->fun() == fp->callee().getFunctionPrivate());
|
||||
|
||||
/*
|
||||
* Push callobj on the top of the scope chain, and make it the
|
||||
* variables object.
|
||||
*/
|
||||
fp->setScopeChainAndCallObj(*callobj);
|
||||
fp->setScopeChainWithOwnCallObj(*callobj);
|
||||
return callobj;
|
||||
}
|
||||
|
||||
JSObject *
|
||||
CreateEvalCallObject(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
JSObject *callobj = NewCallObject(cx, fp->script(), fp->scopeChain(), NULL);
|
||||
if (!callobj)
|
||||
return false;
|
||||
|
||||
callobj->setPrivate(fp);
|
||||
fp->setScopeChainWithOwnCallObj(*callobj);
|
||||
return callobj;
|
||||
}
|
||||
|
||||
} // namespace js
|
||||
|
||||
JSObject * JS_FASTCALL
|
||||
js_CreateCallObjectOnTrace(JSContext *cx, JSFunction *fun, JSObject *callee, JSObject *scopeChain)
|
||||
{
|
||||
JS_ASSERT(!js_IsNamedLambda(fun));
|
||||
JS_ASSERT(scopeChain);
|
||||
JS_ASSERT(callee);
|
||||
return NewCallObject(cx, &fun->script()->bindings, *scopeChain, callee);
|
||||
return NewCallObject(cx, fun->script(), *scopeChain, callee);
|
||||
}
|
||||
|
||||
JS_DEFINE_CALLINFO_4(extern, OBJECT, js_CreateCallObjectOnTrace, CONTEXT, FUNCTION, OBJECT, OBJECT,
|
||||
|
@ -1084,11 +1079,8 @@ void
|
|||
js_PutCallObject(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
JSObject &callobj = fp->callObj();
|
||||
|
||||
/*
|
||||
* Strict mode eval frames have Call objects to put. Normal eval frames
|
||||
* never put a Call object.
|
||||
*/
|
||||
JS_ASSERT(callobj.getPrivate() == fp);
|
||||
JS_ASSERT_IF(fp->isEvalFrame(), fp->isStrictEvalFrame());
|
||||
JS_ASSERT(fp->isEvalFrame() == callobj.callIsForEval());
|
||||
|
||||
/* Get the arguments object to snapshot fp's actual argument values. */
|
||||
|
|
|
@ -321,15 +321,6 @@ JSObject::getFunctionPrivate() const
|
|||
|
||||
namespace js {
|
||||
|
||||
/*
|
||||
* Construct a call object for the given bindings. If this is a call object
|
||||
* for a function invocation, callee should be the function being called.
|
||||
* Otherwise it must be a call object for eval of strict mode code, and callee
|
||||
* must be null.
|
||||
*/
|
||||
extern JSObject *
|
||||
NewCallObject(JSContext *cx, js::Bindings *bindings, JSObject &scopeChain, JSObject *callee);
|
||||
|
||||
/*
|
||||
* NB: jsapi.h and jsobj.h must be included before any call to this macro.
|
||||
*/
|
||||
|
@ -515,9 +506,6 @@ js_ValueToCallableObject(JSContext *cx, js::Value *vp, uintN flags);
|
|||
extern void
|
||||
js_ReportIsNotFunction(JSContext *cx, const js::Value *vp, uintN flags);
|
||||
|
||||
extern JSObject *
|
||||
js_GetCallObject(JSContext *cx, JSStackFrame *fp);
|
||||
|
||||
extern JSObject * JS_FASTCALL
|
||||
js_CreateCallObjectOnTrace(JSContext *cx, JSFunction *fun, JSObject *callee, JSObject *scopeChain);
|
||||
|
||||
|
@ -530,6 +518,12 @@ js_PutCallObjectOnTrace(JSContext *cx, JSObject *scopeChain, uint32 nargs,
|
|||
|
||||
namespace js {
|
||||
|
||||
JSObject *
|
||||
CreateFunCallObject(JSContext *cx, JSStackFrame *fp);
|
||||
|
||||
JSObject *
|
||||
CreateEvalCallObject(JSContext *cx, JSStackFrame *fp);
|
||||
|
||||
extern JSBool
|
||||
GetCallArg(JSContext *cx, JSObject *obj, jsid id, js::Value *vp);
|
||||
|
||||
|
|
|
@ -1494,16 +1494,10 @@ js_TraceStackFrame(JSTracer *trc, JSStackFrame *fp)
|
|||
MarkObject(trc, fp->scopeChain(), "scope chain");
|
||||
if (fp->isDummyFrame())
|
||||
return;
|
||||
|
||||
if (fp->hasCallObj())
|
||||
MarkObject(trc, fp->callObj(), "call");
|
||||
if (fp->hasArgsObj())
|
||||
MarkObject(trc, fp->argsObj(), "arguments");
|
||||
if (fp->isScriptFrame()) {
|
||||
js_TraceScript(trc, fp->script());
|
||||
fp->script()->compartment->active = true;
|
||||
}
|
||||
|
||||
js_TraceScript(trc, fp->script());
|
||||
fp->script()->compartment->active = true;
|
||||
MarkValue(trc, fp->returnValue(), "rval");
|
||||
}
|
||||
|
||||
|
|
|
@ -277,7 +277,7 @@ GetScopeChainFull(JSContext *cx, JSStackFrame *fp, JSObject *blockChain)
|
|||
* Don't force a call object for a lightweight function call, but do
|
||||
* insist that there is a call object for a heavyweight function call.
|
||||
*/
|
||||
JS_ASSERT_IF(fp->isFunctionFrame() && fp->fun()->isHeavyweight(),
|
||||
JS_ASSERT_IF(fp->isNonEvalFunctionFrame() && fp->fun()->isHeavyweight(),
|
||||
fp->hasCallObj());
|
||||
return &fp->scopeChain();
|
||||
}
|
||||
|
@ -293,10 +293,9 @@ GetScopeChainFull(JSContext *cx, JSStackFrame *fp, JSObject *blockChain)
|
|||
* Also, identify the innermost compiler-allocated block we needn't clone.
|
||||
*/
|
||||
JSObject *limitBlock, *limitClone;
|
||||
if (fp->isFunctionFrame() && !fp->hasCallObj()) {
|
||||
JS_ASSERT_IF(fp->scopeChain().isClonedBlock(),
|
||||
fp->scopeChain().getPrivate() != js_FloatingFrameIfGenerator(cx, fp));
|
||||
if (!js_GetCallObject(cx, fp))
|
||||
if (fp->isNonEvalFunctionFrame() && !fp->hasCallObj()) {
|
||||
JS_ASSERT_IF(fp->scopeChain().isClonedBlock(), fp->scopeChain().getPrivate() != fp);
|
||||
if (!CreateFunCallObject(cx, fp))
|
||||
return NULL;
|
||||
|
||||
/* We know we must clone everything on blockChain. */
|
||||
|
@ -635,15 +634,13 @@ RunScript(JSContext *cx, JSScript *script, JSStackFrame *fp)
|
|||
|
||||
if (status == mjit::Compile_Okay) {
|
||||
ok = mjit::JaegerShot(cx);
|
||||
JS_ASSERT_IF(!fp->isYielding() && !(fp->isEvalFrame() && !fp->script()->strictModeCode),
|
||||
!fp->hasCallObj() && !fp->hasArgsObj());
|
||||
JS_ASSERT_IF(!fp->isYielding(), !fp->hasCallObj() && !fp->hasArgsObj());
|
||||
return ok;
|
||||
}
|
||||
#endif
|
||||
|
||||
ok = Interpret(cx, fp);
|
||||
JS_ASSERT_IF(!fp->isYielding() && !(fp->isEvalFrame() && !fp->script()->strictModeCode),
|
||||
!fp->hasCallObj() && !fp->hasArgsObj());
|
||||
JS_ASSERT_IF(!fp->isYielding(), !fp->hasCallObj() && !fp->hasArgsObj());
|
||||
return ok;
|
||||
|
||||
error:
|
||||
|
@ -721,7 +718,7 @@ Invoke(JSContext *cx, const CallArgs &argsRef, uint32 flags)
|
|||
cx->stack().pushInvokeFrame(cx, args, &frame);
|
||||
|
||||
/* Now that the new frame is rooted, maybe create a call object. */
|
||||
if (fun->isHeavyweight() && !js_GetCallObject(cx, fp))
|
||||
if (fun->isHeavyweight() && !CreateFunCallObject(cx, fp))
|
||||
return false;
|
||||
|
||||
/* Run function until JSOP_STOP, JSOP_RETURN or error. */
|
||||
|
@ -894,6 +891,34 @@ ExternalGetOrSet(JSContext *cx, JSObject *obj, jsid id, const Value &fval,
|
|||
return ExternalInvoke(cx, ObjectValue(*obj), fval, argc, argv, rval);
|
||||
}
|
||||
|
||||
#if JS_HAS_SHARP_VARS
|
||||
JS_STATIC_ASSERT(SHARP_NSLOTS == 2);
|
||||
|
||||
static JS_NEVER_INLINE bool
|
||||
InitSharpSlots(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
JSStackFrame *prev = fp->prev();
|
||||
JSScript *script = fp->script();
|
||||
JS_ASSERT(script->nfixed >= SHARP_NSLOTS);
|
||||
|
||||
Value *sharps = &fp->slots()[script->nfixed - SHARP_NSLOTS];
|
||||
if (prev && prev->script()->hasSharps) {
|
||||
JS_ASSERT(prev->numFixed() >= SHARP_NSLOTS);
|
||||
int base = (prev->isFunctionFrame() && !prev->isEvalOrDebuggerFrame())
|
||||
? prev->fun()->script()->bindings.sharpSlotBase(cx)
|
||||
: prev->numFixed() - SHARP_NSLOTS;
|
||||
if (base < 0)
|
||||
return false;
|
||||
sharps[0] = prev->slots()[base];
|
||||
sharps[1] = prev->slots()[base + 1];
|
||||
} else {
|
||||
sharps[0].setUndefined();
|
||||
sharps[1].setUndefined();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool
|
||||
Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
||||
JSStackFrame *prev, uintN flags, Value *result)
|
||||
|
@ -908,10 +933,12 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||
}
|
||||
|
||||
LeaveTrace(cx);
|
||||
AutoScriptRooter root(cx, script);
|
||||
|
||||
/*
|
||||
* Get a pointer to new frame/slots. This memory is not "claimed", so the
|
||||
* code before pushExecuteFrame must not reenter the interpreter.
|
||||
* code before pushExecuteFrame must not reenter the interpreter or assume
|
||||
* the frame is rooted.
|
||||
*/
|
||||
ExecuteFrameGuard frame;
|
||||
if (!cx->stack().getExecuteFrame(cx, script, &frame))
|
||||
|
@ -926,13 +953,7 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||
JS_ASSERT(chain == &prev->scopeChain());
|
||||
frame.fp()->initEvalFrame(cx, script, prev, flags);
|
||||
|
||||
/*
|
||||
* We want to call |prev->varobj()|, but this requires knowing the
|
||||
* CallStackSegment of |prev|. If |prev == cx->fp()|, the callstack is
|
||||
* simply the context's active callstack, so we can use
|
||||
* |prev->varobj(cx)|. When |prev != cx->fp()|, we need to do a slow
|
||||
* linear search. Luckily, this only happens with EvaluateInFrame.
|
||||
*/
|
||||
/* NB: prev may not be in cx->currentSegment. */
|
||||
initialVarObj = (prev == cx->maybefp())
|
||||
? &prev->varobj(cx)
|
||||
: &prev->varobj(cx->containingSegment(prev));
|
||||
|
@ -950,67 +971,35 @@ Execute(JSContext *cx, JSObject *chain, JSScript *script,
|
|||
return false;
|
||||
}
|
||||
|
||||
/* Initialize frame. */
|
||||
frame.fp()->initGlobalFrame(script, *innerizedChain, flags);
|
||||
|
||||
/* Compute 'this'. */
|
||||
/* If scope chain is an inner window, outerize for 'this'. */
|
||||
JSObject *thisp = chain->thisObject(cx);
|
||||
if (!thisp)
|
||||
return false;
|
||||
frame.fp()->globalThis().setObject(*thisp);
|
||||
|
||||
initialVarObj = cx->hasRunOption(JSOPTION_VAROBJFIX) ? chain->getGlobal() : chain;
|
||||
}
|
||||
|
||||
/*
|
||||
* Strict mode eval code receives its own, fresh lexical environment; thus
|
||||
* strict mode eval can't mutate its calling frame's binding set.
|
||||
*/
|
||||
if ((flags & JSFRAME_EVAL) && script->strictModeCode) {
|
||||
AutoScriptRooter root(cx, script);
|
||||
initialVarObj = NewCallObject(cx, &script->bindings, *initialVarObj, NULL);
|
||||
if (!initialVarObj)
|
||||
return false;
|
||||
initialVarObj->setPrivate(frame.fp());
|
||||
|
||||
/* Clear the Call object propagated from the previous frame, if any. */
|
||||
if (frame.fp()->hasCallObj())
|
||||
frame.fp()->clearCallObj();
|
||||
frame.fp()->setScopeChainAndCallObj(*initialVarObj);
|
||||
initialVarObj = cx->hasRunOption(JSOPTION_VAROBJFIX)
|
||||
? chain->getGlobal()
|
||||
: chain;
|
||||
}
|
||||
JS_ASSERT(!initialVarObj->getOps()->defineProperty);
|
||||
|
||||
#if JS_HAS_SHARP_VARS
|
||||
JS_STATIC_ASSERT(SHARP_NSLOTS == 2);
|
||||
if (script->hasSharps) {
|
||||
JS_ASSERT(script->nfixed >= SHARP_NSLOTS);
|
||||
Value *sharps = &frame.fp()->slots()[script->nfixed - SHARP_NSLOTS];
|
||||
if (prev && prev->script()->hasSharps) {
|
||||
JS_ASSERT(prev->numFixed() >= SHARP_NSLOTS);
|
||||
int base = (prev->isFunctionFrame() && !prev->isEvalOrDebuggerFrame())
|
||||
? prev->fun()->script()->bindings.sharpSlotBase(cx)
|
||||
: prev->numFixed() - SHARP_NSLOTS;
|
||||
if (base < 0)
|
||||
return false;
|
||||
sharps[0] = prev->slots()[base];
|
||||
sharps[1] = prev->slots()[base + 1];
|
||||
} else {
|
||||
sharps[0].setUndefined();
|
||||
sharps[1].setUndefined();
|
||||
}
|
||||
if (frame.fp()->isStrictEvalFrame()) {
|
||||
/* Give strict mode eval its own fresh lexical environment. */
|
||||
initialVarObj = CreateEvalCallObject(cx, frame.fp());
|
||||
if (!initialVarObj)
|
||||
return false;
|
||||
JS_ASSERT(initialVarObj == &frame.fp()->scopeChain());
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Officially push |fp|. |frame|'s destructor pops. */
|
||||
/* Officially push the frame. ~FrameGuard pops. */
|
||||
cx->stack().pushExecuteFrame(cx, initialVarObj, &frame);
|
||||
|
||||
/* Now that the frame has been pushed, we can call the thisObject hook. */
|
||||
if (!prev) {
|
||||
JSObject *thisp = chain->thisObject(cx);
|
||||
if (!thisp)
|
||||
return false;
|
||||
frame.fp()->globalThis().setObject(*thisp);
|
||||
}
|
||||
#if JS_HAS_SHARP_VARS
|
||||
if (script->hasSharps && !InitSharpSlots(cx, frame.fp()))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
Probes::startExecution(cx, script);
|
||||
|
||||
|
@ -4718,7 +4707,7 @@ BEGIN_CASE(JSOP_FUNCALL)
|
|||
atoms = script->atomMap.vector;
|
||||
|
||||
/* Now that the new frame is rooted, maybe create a call object. */
|
||||
if (newfun->isHeavyweight() && !js_GetCallObject(cx, regs.fp))
|
||||
if (newfun->isHeavyweight() && !CreateFunCallObject(cx, regs.fp))
|
||||
goto error;
|
||||
|
||||
RESET_USE_METHODJIT();
|
||||
|
@ -5265,7 +5254,7 @@ END_CASE(JSOP_GETUPVAR_DBG)
|
|||
BEGIN_CASE(JSOP_GETFCSLOT)
|
||||
BEGIN_CASE(JSOP_CALLFCSLOT)
|
||||
{
|
||||
JS_ASSERT(regs.fp->isFunctionFrame() && !regs.fp->isEvalFrame());
|
||||
JS_ASSERT(regs.fp->isNonEvalFunctionFrame());
|
||||
uintN index = GET_UINT16(regs.pc);
|
||||
JSObject *obj = &argv[-2].toObject();
|
||||
|
||||
|
@ -5702,7 +5691,7 @@ BEGIN_CASE(JSOP_LAMBDA_DBGFC)
|
|||
END_CASE(JSOP_LAMBDA_DBGFC)
|
||||
|
||||
BEGIN_CASE(JSOP_CALLEE)
|
||||
JS_ASSERT(regs.fp->isFunctionFrame() && !regs.fp->isEvalFrame());
|
||||
JS_ASSERT(regs.fp->isNonEvalFunctionFrame());
|
||||
PUSH_COPY(argv[-2]);
|
||||
END_CASE(JSOP_CALLEE)
|
||||
|
||||
|
@ -6615,7 +6604,7 @@ BEGIN_CASE(JSOP_GENERATOR)
|
|||
|
||||
BEGIN_CASE(JSOP_YIELD)
|
||||
JS_ASSERT(!cx->isExceptionPending());
|
||||
JS_ASSERT(regs.fp->isFunctionFrame() && !regs.fp->isEvalFrame());
|
||||
JS_ASSERT(regs.fp->isNonEvalFunctionFrame());
|
||||
if (cx->generatorFor(regs.fp)->state == JSGEN_CLOSING) {
|
||||
js_ReportValueError(cx, JSMSG_BAD_GENERATOR_YIELD,
|
||||
JSDVG_SEARCH_STACK, argv[-2], NULL);
|
||||
|
|
|
@ -150,10 +150,6 @@ struct JSStackFrame
|
|||
* function frame: execution of function code or an eval in a function
|
||||
* dummy frame: bookkeeping frame (read: hack)
|
||||
*
|
||||
* As noted, global and function frames may optionally be 'eval frames', which
|
||||
* further restricts the stack frame members which may be used. Namely, the
|
||||
* argument-related members of function eval frames are not valid, since an eval
|
||||
* shares its containing function's arguments rather than having its own.
|
||||
*/
|
||||
|
||||
bool isFunctionFrame() const {
|
||||
|
@ -174,11 +170,35 @@ struct JSStackFrame
|
|||
return retval;
|
||||
}
|
||||
|
||||
/*
|
||||
* Eval frames
|
||||
*
|
||||
* As noted above, global and function frames may optionally be 'eval
|
||||
* frames'. Eval code shares its parent's arguments which means that the
|
||||
* arg-access members of JSStackFrame may not be used for eval frames.
|
||||
* Search for 'hasArgs' below for more details.
|
||||
*
|
||||
* A further sub-classification of eval frames is whether the frame was
|
||||
* pushed for an ES5 strict-mode eval().
|
||||
*/
|
||||
|
||||
bool isEvalFrame() const {
|
||||
JS_ASSERT_IF(flags_ & JSFRAME_EVAL, isScriptFrame());
|
||||
return flags_ & JSFRAME_EVAL;
|
||||
}
|
||||
|
||||
bool isNonEvalFunctionFrame() const {
|
||||
return (flags_ & (JSFRAME_FUNCTION | JSFRAME_EVAL)) == JSFRAME_FUNCTION;
|
||||
}
|
||||
|
||||
bool isStrictEvalFrame() const {
|
||||
return isEvalFrame() && script()->strictModeCode;
|
||||
}
|
||||
|
||||
bool isNonStrictEvalFrame() const {
|
||||
return isEvalFrame() && !script()->strictModeCode;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frame initialization
|
||||
*
|
||||
|
@ -342,7 +362,7 @@ struct JSStackFrame
|
|||
|
||||
/* True if this frame has arguments. Contrast with hasArgsObj. */
|
||||
bool hasArgs() const {
|
||||
return isFunctionFrame() && !isEvalFrame();
|
||||
return isNonEvalFunctionFrame();
|
||||
}
|
||||
|
||||
uintN numFormalArgs() const {
|
||||
|
@ -484,6 +504,12 @@ struct JSStackFrame
|
|||
* up the scope chain until the first call object. Thus, it is important,
|
||||
* when setting the scope chain, to indicate whether the new scope chain
|
||||
* contains a new call object and thus changes the 'hasCallObj' state.
|
||||
*
|
||||
* NB: 'fp->hasCallObj()' implies that fp->callObj() needs to be 'put' when
|
||||
* the frame is popped. Since the scope chain of a non-strict eval frame
|
||||
* contains the call object of the parent (function) frame, it is possible
|
||||
* to have:
|
||||
* !fp->hasCall() && fp->scopeChain().isCall()
|
||||
*/
|
||||
|
||||
JSObject &scopeChain() const {
|
||||
|
@ -496,13 +522,14 @@ struct JSStackFrame
|
|||
}
|
||||
|
||||
bool hasCallObj() const {
|
||||
return !!(flags_ & JSFRAME_HAS_CALL_OBJ);
|
||||
bool ret = !!(flags_ & JSFRAME_HAS_CALL_OBJ);
|
||||
JS_ASSERT_IF(ret, !isNonStrictEvalFrame());
|
||||
return ret;
|
||||
}
|
||||
|
||||
inline JSObject &callObj() const;
|
||||
inline JSObject *maybeCallObj() const;
|
||||
inline void setScopeChainNoCallObj(JSObject &obj);
|
||||
inline void setScopeChainAndCallObj(JSObject &obj);
|
||||
inline void setScopeChainWithOwnCallObj(JSObject &obj);
|
||||
inline void clearCallObj();
|
||||
|
||||
/*
|
||||
|
|
|
@ -94,7 +94,6 @@ JSStackFrame::initCallFrame(JSContext *cx, JSObject &callee, JSFunction *fun,
|
|||
JS_ASSERT(!hasImacropc());
|
||||
JS_ASSERT(!hasHookData());
|
||||
JS_ASSERT(annotation() == NULL);
|
||||
|
||||
JS_ASSERT(!hasCallObj());
|
||||
}
|
||||
|
||||
|
@ -163,21 +162,21 @@ JSStackFrame::initEvalFrame(JSContext *cx, JSScript *script, JSStackFrame *prev,
|
|||
{
|
||||
JS_ASSERT(flagsArg & JSFRAME_EVAL);
|
||||
JS_ASSERT((flagsArg & ~(JSFRAME_EVAL | JSFRAME_DEBUGGER)) == 0);
|
||||
JS_ASSERT(prev->flags_ & (JSFRAME_FUNCTION | JSFRAME_GLOBAL));
|
||||
JS_ASSERT(prev->isScriptFrame());
|
||||
|
||||
/* Copy (callee, thisv). */
|
||||
js::Value *dstvp = (js::Value *)this - 2;
|
||||
js::Value *srcvp = prev->flags_ & (JSFRAME_GLOBAL | JSFRAME_EVAL)
|
||||
? (js::Value *)prev - 2
|
||||
: prev->formalArgs() - 2;
|
||||
js::Value *srcvp = prev->hasArgs()
|
||||
? prev->formalArgs() - 2
|
||||
: (js::Value *)prev - 2;
|
||||
dstvp[0] = srcvp[0];
|
||||
dstvp[1] = srcvp[1];
|
||||
JS_ASSERT_IF(prev->flags_ & JSFRAME_FUNCTION,
|
||||
JS_ASSERT_IF(prev->isFunctionFrame(),
|
||||
dstvp[0].toObject().isFunction());
|
||||
|
||||
/* Initialize stack frame members. */
|
||||
flags_ = flagsArg | JSFRAME_HAS_PREVPC | JSFRAME_HAS_SCOPECHAIN |
|
||||
(prev->flags_ & (JSFRAME_FUNCTION | JSFRAME_GLOBAL | JSFRAME_HAS_CALL_OBJ));
|
||||
(prev->flags_ & (JSFRAME_FUNCTION | JSFRAME_GLOBAL));
|
||||
if (isFunctionFrame()) {
|
||||
exec = prev->exec;
|
||||
args.script = script;
|
||||
|
@ -186,8 +185,6 @@ JSStackFrame::initEvalFrame(JSContext *cx, JSScript *script, JSStackFrame *prev,
|
|||
}
|
||||
|
||||
scopeChain_ = &prev->scopeChain();
|
||||
JS_ASSERT_IF(isFunctionFrame(), &callObj() == &prev->callObj());
|
||||
|
||||
prev_ = prev;
|
||||
prevpc_ = prev->pc(cx);
|
||||
JS_ASSERT(!hasImacropc());
|
||||
|
@ -249,10 +246,11 @@ JSStackFrame::stealFrameAndSlots(js::Value *vp, JSStackFrame *otherfp,
|
|||
* js_LiveFrameToFloating comment in jsiter.h.
|
||||
*/
|
||||
if (hasCallObj()) {
|
||||
callObj().setPrivate(this);
|
||||
JSObject &obj = callObj();
|
||||
obj.setPrivate(this);
|
||||
otherfp->flags_ &= ~JSFRAME_HAS_CALL_OBJ;
|
||||
if (js_IsNamedLambda(fun())) {
|
||||
JSObject *env = callObj().getParent();
|
||||
JSObject *env = obj.getParent();
|
||||
JS_ASSERT(env->getClass() == &js_DeclEnvClass);
|
||||
env->setPrivate(this);
|
||||
}
|
||||
|
@ -435,19 +433,24 @@ JSStackFrame::setScopeChainNoCallObj(JSObject &obj)
|
|||
{
|
||||
#ifdef DEBUG
|
||||
JS_ASSERT(&obj != NULL);
|
||||
JSObject *callObjBefore = maybeCallObj();
|
||||
if (!hasCallObj() && &scopeChain() != sInvalidScopeChain) {
|
||||
for (JSObject *pobj = &scopeChain(); pobj; pobj = pobj->getParent())
|
||||
JS_ASSERT_IF(pobj->isCall(), pobj->getPrivate() != this);
|
||||
if (&obj != sInvalidScopeChain) {
|
||||
if (hasCallObj()) {
|
||||
JSObject *pobj = &obj;
|
||||
while (pobj && pobj->getPrivate() != this)
|
||||
pobj = pobj->getParent();
|
||||
JS_ASSERT(pobj);
|
||||
} else {
|
||||
for (JSObject *pobj = &obj; pobj; pobj = pobj->getParent())
|
||||
JS_ASSERT_IF(pobj->isCall(), pobj->getPrivate() != this);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
scopeChain_ = &obj;
|
||||
flags_ |= JSFRAME_HAS_SCOPECHAIN;
|
||||
JS_ASSERT(callObjBefore == maybeCallObj());
|
||||
}
|
||||
|
||||
inline void
|
||||
JSStackFrame::setScopeChainAndCallObj(JSObject &obj)
|
||||
JSStackFrame::setScopeChainWithOwnCallObj(JSObject &obj)
|
||||
{
|
||||
JS_ASSERT(&obj != NULL);
|
||||
JS_ASSERT(!hasCallObj() && obj.isCall() && obj.getPrivate() == this);
|
||||
|
@ -465,7 +468,8 @@ JSStackFrame::clearCallObj()
|
|||
inline JSObject &
|
||||
JSStackFrame::callObj() const
|
||||
{
|
||||
JS_ASSERT(hasCallObj());
|
||||
JS_ASSERT_IF(isNonEvalFunctionFrame() || isStrictEvalFrame(), hasCallObj());
|
||||
|
||||
JSObject *pobj = &scopeChain();
|
||||
while (JS_UNLIKELY(pobj->getClass() != &js_CallClass)) {
|
||||
JS_ASSERT(js::IsCacheableNonGlobalScope(pobj) || pobj->isWith());
|
||||
|
@ -474,12 +478,6 @@ JSStackFrame::callObj() const
|
|||
return *pobj;
|
||||
}
|
||||
|
||||
inline JSObject *
|
||||
JSStackFrame::maybeCallObj() const
|
||||
{
|
||||
return hasCallObj() ? &callObj() : NULL;
|
||||
}
|
||||
|
||||
namespace js {
|
||||
|
||||
class AutoPreserveEnumerators {
|
||||
|
@ -516,15 +514,11 @@ struct AutoInterpPreparer {
|
|||
inline void
|
||||
PutActivationObjects(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
JS_ASSERT(!fp->isYielding());
|
||||
JS_ASSERT(!fp->isEvalFrame() || fp->script()->strictModeCode);
|
||||
|
||||
/* The order is important as js_PutCallObject needs to access argsObj. */
|
||||
if (fp->hasCallObj()) {
|
||||
if (fp->hasCallObj())
|
||||
js_PutCallObject(cx, fp);
|
||||
} else if (fp->hasArgsObj()) {
|
||||
else if (fp->hasArgsObj())
|
||||
js_PutArgsObject(cx, fp);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -804,7 +798,7 @@ ValuePropertyBearer(JSContext *cx, const Value &v, int spindex)
|
|||
inline bool
|
||||
ScriptPrologue(JSContext *cx, JSStackFrame *fp)
|
||||
{
|
||||
JS_ASSERT_IF(fp->isFunctionFrame() && fp->fun()->isHeavyweight(), fp->hasCallObj());
|
||||
JS_ASSERT_IF(fp->isNonEvalFunctionFrame() && fp->fun()->isHeavyweight(), fp->hasCallObj());
|
||||
|
||||
if (fp->isConstructing()) {
|
||||
JSObject *obj = js_CreateThisForFunction(cx, &fp->callee());
|
||||
|
@ -824,31 +818,12 @@ ScriptEpilogue(JSContext *cx, JSStackFrame *fp, bool ok)
|
|||
if (cx->compartment->debugMode)
|
||||
ok = ScriptDebugEpilogue(cx, fp, ok);
|
||||
|
||||
if (fp->isEvalFrame()) {
|
||||
/*
|
||||
* The parent (ancestor for nested eval) of a non-strict eval frame
|
||||
* owns its activation objects. Strict mode eval frames own their own
|
||||
* Call objects but never have an arguments object (the first non-eval
|
||||
* parent frame has it).
|
||||
*/
|
||||
if (fp->script()->strictModeCode) {
|
||||
JS_ASSERT(!fp->isYielding());
|
||||
JS_ASSERT(!fp->hasArgsObj());
|
||||
JS_ASSERT(fp->hasCallObj());
|
||||
JS_ASSERT(fp->callObj().callIsForEval());
|
||||
js_PutCallObject(cx, fp);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Otherwise only function frames have activation objects. A yielding
|
||||
* frame's activation objects are transferred to the floating frame,
|
||||
* stored in the generator, and thus need not be synced.
|
||||
*/
|
||||
if (fp->isFunctionFrame() && !fp->isYielding()) {
|
||||
JS_ASSERT_IF(fp->hasCallObj(), !fp->callObj().callIsForEval());
|
||||
PutActivationObjects(cx, fp);
|
||||
}
|
||||
}
|
||||
/*
|
||||
* A yielding frame's activation objects are transferred to the floating
|
||||
* frame, stored in the generator, and thus need not be synced.
|
||||
*/
|
||||
if (!fp->isYielding())
|
||||
PutActivationObjects(cx, fp);
|
||||
|
||||
/*
|
||||
* If inline-constructing, replace primitive rval with the new object
|
||||
|
|
|
@ -1201,7 +1201,7 @@ EvalKernel(JSContext *cx, uintN argc, Value *vp, EvalType evalType, JSStackFrame
|
|||
|
||||
#ifdef DEBUG
|
||||
jsbytecode *callerPC = caller->pc(cx);
|
||||
JS_ASSERT_IF(caller->isFunctionFrame(), caller->hasCallObj());
|
||||
JS_ASSERT_IF(caller->isFunctionFrame(), caller->fun()->isHeavyweight());
|
||||
JS_ASSERT(callerPC && js_GetOpcode(cx, caller->script(), callerPC) == JSOP_EVAL);
|
||||
#endif
|
||||
} else {
|
||||
|
@ -1249,7 +1249,7 @@ EvalKernel(JSContext *cx, uintN argc, Value *vp, EvalType evalType, JSStackFrame
|
|||
|
||||
JSScript *script = NULL;
|
||||
JSScript **bucket = EvalCacheHash(cx, linearStr);
|
||||
if (evalType == DIRECT_EVAL && caller->isFunctionFrame() && !caller->isEvalFrame()) {
|
||||
if (evalType == DIRECT_EVAL && caller->isNonEvalFunctionFrame()) {
|
||||
script = EvalCacheLookup(cx, linearStr, caller, staticLevel, principals, scopeobj, bucket);
|
||||
|
||||
/*
|
||||
|
@ -6869,11 +6869,15 @@ js_DumpStackFrame(JSContext *cx, JSStackFrame *start)
|
|||
fputc('\n', stderr);
|
||||
}
|
||||
}
|
||||
if (fp->isFunctionFrame() && !fp->isEvalFrame()) {
|
||||
if (fp->hasArgs()) {
|
||||
fprintf(stderr, " actuals: %p (%u) ", (void *) fp->actualArgs(), (unsigned) fp->numActualArgs());
|
||||
fprintf(stderr, " formals: %p (%u)\n", (void *) fp->formalArgs(), (unsigned) fp->numFormalArgs());
|
||||
}
|
||||
MaybeDumpObject("callobj", fp->maybeCallObj());
|
||||
if (fp->hasCallObj()) {
|
||||
fprintf(stderr, " has call obj: ");
|
||||
dumpValue(ObjectValue(fp->callObj()));
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
MaybeDumpObject("argsobj", fp->maybeArgsObj());
|
||||
if (!fp->isDummyFrame()) {
|
||||
MaybeDumpValue("this", fp->thisValue());
|
||||
|
|
|
@ -516,7 +516,7 @@ struct JSObject : js::gc::Cell {
|
|||
}
|
||||
|
||||
/* Functions for setting up scope chain object maps and shapes. */
|
||||
void initCall(JSContext *cx, const js::Bindings *bindings, JSObject *parent);
|
||||
void initCall(JSContext *cx, const js::Bindings &bindings, JSObject *parent);
|
||||
void initClonedBlock(JSContext *cx, JSObject *proto, JSStackFrame *priv);
|
||||
void setBlockOwnShape(JSContext *cx);
|
||||
|
||||
|
|
|
@ -172,16 +172,16 @@ JSObject::finalize(JSContext *cx)
|
|||
* parent, map, and shape, and allocate slots.
|
||||
*/
|
||||
inline void
|
||||
JSObject::initCall(JSContext *cx, const js::Bindings *bindings, JSObject *parent)
|
||||
JSObject::initCall(JSContext *cx, const js::Bindings &bindings, JSObject *parent)
|
||||
{
|
||||
init(cx, &js_CallClass, NULL, parent, NULL, false);
|
||||
map = bindings->lastShape();
|
||||
map = bindings.lastShape();
|
||||
|
||||
/*
|
||||
* If |bindings| is for a function that has extensible parents, that means
|
||||
* its Call should have its own shape; see js::Bindings::extensibleParents.
|
||||
*/
|
||||
if (bindings->extensibleParents())
|
||||
if (bindings.extensibleParents())
|
||||
setOwnShape(js_GenerateShape(cx));
|
||||
else
|
||||
objShape = map->shape;
|
||||
|
|
|
@ -1735,7 +1735,7 @@ static inline uintN
|
|||
entryFrameArgc(JSContext *cx)
|
||||
{
|
||||
JSStackFrame *fp = cx->fp();
|
||||
return fp->isGlobalFrame() || fp->isEvalFrame() ? 0 : fp->numActualArgs();
|
||||
return fp->hasArgs() ? fp->numActualArgs() : 0;
|
||||
}
|
||||
|
||||
template <typename Visitor>
|
||||
|
@ -2000,7 +2000,7 @@ NativeStackSlots(JSContext *cx, unsigned callDepth)
|
|||
unsigned depth = callDepth;
|
||||
|
||||
for (; depth > 0; --depth, next = fp, fp = fp->prev()) {
|
||||
JS_ASSERT(fp->isFunctionFrame() && !fp->isEvalFrame());
|
||||
JS_ASSERT(fp->isNonEvalFunctionFrame());
|
||||
slots += SPECIAL_FRAME_SLOTS;
|
||||
if (next)
|
||||
slots += CountStackAndArgs(next, fp->slots());
|
||||
|
@ -3157,7 +3157,7 @@ public:
|
|||
{
|
||||
JS_ASSERT(&fp->scopeChain() == JSStackFrame::sInvalidScopeChain);
|
||||
frameobj->setPrivate(fp);
|
||||
fp->setScopeChainAndCallObj(*frameobj);
|
||||
fp->setScopeChainWithOwnCallObj(*frameobj);
|
||||
} else {
|
||||
fp->setScopeChainNoCallObj(*frameobj);
|
||||
}
|
||||
|
@ -13759,7 +13759,7 @@ TraceRecorder::interpretedFunctionCall(Value& fval, JSFunction* fun, uintN argc,
|
|||
fi->spdist = cx->regs->sp - fp->slots();
|
||||
fi->set_argc(uint16(argc), constructing);
|
||||
fi->callerHeight = stackSlots - (2 + argc);
|
||||
fi->callerArgc = fp->isGlobalFrame() || fp->isEvalFrame() ? 0 : fp->numActualArgs();
|
||||
fi->callerArgc = fp->hasArgs() ? fp->numActualArgs() : 0;
|
||||
|
||||
if (callDepth >= tree->maxCallDepth)
|
||||
tree->maxCallDepth = callDepth + 1;
|
||||
|
|
|
@ -351,7 +351,7 @@ mjit::Compiler::generatePrologue()
|
|||
/* Create the call object. */
|
||||
if (fun->isHeavyweight()) {
|
||||
prepareStubCall(Uses(0));
|
||||
INLINE_STUBCALL(stubs::GetCallObject);
|
||||
INLINE_STUBCALL(stubs::CreateFunCallObject);
|
||||
}
|
||||
|
||||
j.linkTo(masm.label(), &masm);
|
||||
|
@ -360,7 +360,7 @@ mjit::Compiler::generatePrologue()
|
|||
/*
|
||||
* Load the scope chain into the frame if necessary. The scope chain
|
||||
* is always set for global and eval frames, and will have been set by
|
||||
* GetCallObject for heavyweight function frames.
|
||||
* CreateFunCallObject for heavyweight function frames.
|
||||
*/
|
||||
RegisterID t0 = Registers::ReturnReg;
|
||||
Jump hasScope = masm.branchTest32(Assembler::NonZero,
|
||||
|
@ -2248,7 +2248,7 @@ mjit::Compiler::emitReturn(FrameEntry *fe)
|
|||
prepareStubCall(Uses(fe ? 1 : 0));
|
||||
INLINE_STUBCALL(stubs::PutActivationObjects);
|
||||
} else {
|
||||
/* if (hasCallObj() || hasArgsObj()) stubs::PutActivationObjects() */
|
||||
/* if (hasCallObj() || hasArgsObj()) */
|
||||
Jump putObjs = masm.branchTest32(Assembler::NonZero,
|
||||
Address(JSFrameReg, JSStackFrame::offsetOfFlags()),
|
||||
Imm32(JSFRAME_HAS_CALL_OBJ | JSFRAME_HAS_ARGS_OBJ));
|
||||
|
@ -2261,10 +2261,10 @@ mjit::Compiler::emitReturn(FrameEntry *fe)
|
|||
emitFinalReturn(stubcc.masm);
|
||||
}
|
||||
} else {
|
||||
if (fp->isEvalFrame() && script->strictModeCode) {
|
||||
if (fp->isStrictEvalFrame()) {
|
||||
/* There will always be a call object. */
|
||||
prepareStubCall(Uses(fe ? 1 : 0));
|
||||
INLINE_STUBCALL(stubs::PutStrictEvalCallObject);
|
||||
INLINE_STUBCALL(stubs::PutActivationObjects);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -325,7 +325,7 @@ stubs::CompileFunction(VMFrame &f, uint32 nactual)
|
|||
f.regs.sp = fp->base();
|
||||
f.regs.pc = script->code;
|
||||
|
||||
if (fun->isHeavyweight() && !js_GetCallObject(cx, fp))
|
||||
if (fun->isHeavyweight() && !js::CreateFunCallObject(cx, fp))
|
||||
THROWV(NULL);
|
||||
|
||||
CompileStatus status = CanMethodJIT(cx, script, fp, CompileRequest_JIT);
|
||||
|
@ -367,6 +367,10 @@ UncachedInlineCall(VMFrame &f, uint32 flags, void **pret, bool *unjittable, uint
|
|||
stack.pushInlineFrame(cx, newscript, newfp, &f.regs);
|
||||
JS_ASSERT(newfp == f.regs.fp);
|
||||
|
||||
/* Scope with a call object parented by callee's parent. */
|
||||
if (newfun->isHeavyweight() && !js::CreateFunCallObject(cx, newfp))
|
||||
return false;
|
||||
|
||||
/* Try to compile if not already compiled. */
|
||||
if (newscript->getJITStatus(newfp->isConstructing()) == JITScript_None) {
|
||||
CompileStatus status = CanMethodJIT(cx, newscript, newfp, CompileRequest_Interpreter);
|
||||
|
@ -379,10 +383,6 @@ UncachedInlineCall(VMFrame &f, uint32 flags, void **pret, bool *unjittable, uint
|
|||
*unjittable = true;
|
||||
}
|
||||
|
||||
/* Create call object now that we can't fail entering callee. */
|
||||
if (newfun->isHeavyweight() && !js_GetCallObject(cx, newfp))
|
||||
return false;
|
||||
|
||||
/* If newscript was successfully compiled, run it. */
|
||||
if (JITScript *jit = newscript->getJIT(newfp->isConstructing())) {
|
||||
*pret = jit->invokeEntry;
|
||||
|
@ -479,15 +479,6 @@ stubs::UncachedCallHelper(VMFrame &f, uint32 argc, UncachedCallResult *ucr)
|
|||
return;
|
||||
}
|
||||
|
||||
void JS_FASTCALL
|
||||
stubs::PutStrictEvalCallObject(VMFrame &f)
|
||||
{
|
||||
JS_ASSERT(f.fp()->isEvalFrame());
|
||||
JS_ASSERT(f.fp()->script()->strictModeCode);
|
||||
JS_ASSERT(f.fp()->hasCallObj());
|
||||
js_PutCallObject(f.cx, f.fp());
|
||||
}
|
||||
|
||||
void JS_FASTCALL
|
||||
stubs::PutActivationObjects(VMFrame &f)
|
||||
{
|
||||
|
@ -580,10 +571,10 @@ js_InternalThrow(VMFrame &f)
|
|||
}
|
||||
|
||||
void JS_FASTCALL
|
||||
stubs::GetCallObject(VMFrame &f)
|
||||
stubs::CreateFunCallObject(VMFrame &f)
|
||||
{
|
||||
JS_ASSERT(f.fp()->fun()->isHeavyweight());
|
||||
if (!js_GetCallObject(f.cx, f.fp()))
|
||||
if (!js::CreateFunCallObject(f.cx, f.fp()))
|
||||
THROW();
|
||||
}
|
||||
|
||||
|
@ -807,9 +798,7 @@ HandleFinishedFrame(VMFrame &f, JSStackFrame *entryFrame)
|
|||
returnOK = ScriptEpilogue(cx, cx->fp(), true);
|
||||
}
|
||||
|
||||
JS_ASSERT_IF(cx->fp()->isFunctionFrame() &&
|
||||
!cx->fp()->isEvalFrame(),
|
||||
!cx->fp()->hasCallObj());
|
||||
JS_ASSERT_IF(cx->fp()->isNonEvalFunctionFrame(), !cx->fp()->hasCallObj());
|
||||
|
||||
if (cx->fp() != entryFrame) {
|
||||
InlineReturn(f);
|
||||
|
|
|
@ -770,8 +770,7 @@ CheckStackAndEnterMethodJIT(JSContext *cx, JSStackFrame *fp, void *code)
|
|||
goto error;
|
||||
|
||||
ok = EnterMethodJIT(cx, fp, code, stackLimit);
|
||||
JS_ASSERT_IF(!fp->isYielding() && !(fp->isEvalFrame() && !fp->script()->strictModeCode),
|
||||
!fp->hasCallObj() && !fp->hasArgsObj());
|
||||
JS_ASSERT_IF(!fp->isYielding(), !fp->hasCallObj() && !fp->hasArgsObj());
|
||||
return ok;
|
||||
|
||||
error:
|
||||
|
|
|
@ -109,9 +109,8 @@ void UncachedNewHelper(VMFrame &f, uint32 argc, UncachedCallResult *ucr);
|
|||
|
||||
void JS_FASTCALL CreateThis(VMFrame &f, JSObject *proto);
|
||||
void JS_FASTCALL Throw(VMFrame &f);
|
||||
void JS_FASTCALL PutStrictEvalCallObject(VMFrame &f);
|
||||
void JS_FASTCALL PutActivationObjects(VMFrame &f);
|
||||
void JS_FASTCALL GetCallObject(VMFrame &f);
|
||||
void JS_FASTCALL CreateFunCallObject(VMFrame &f);
|
||||
#if JS_MONOIC
|
||||
void * JS_FASTCALL InvokeTracer(VMFrame &f, ic::TraceICInfo *tic);
|
||||
#else
|
||||
|
|
Загрузка…
Ссылка в новой задаче