Bug 693895 - Remove call to js_ReconstructStackDepth in StackIter (r=dmandelin)

This commit is contained in:
Luke Wagner 2011-10-12 10:30:15 -07:00
parent 0833156fbb
commit d3b7077c0c
2 changed files with 13 additions and 54 deletions

View File

@ -45,7 +45,6 @@ eval("assertStackIs(['eval-code', 'global-code'])");
this['eval']("assertStackIs(['eval-code', eval, 'global-code'])");
eval.bind(null, "assertStackIs(['eval-code', eval, 'bound(eval)', 'global-code'])")();
(function f() { assertStackIs([f, Function.prototype.call, 'global-code']) }).call(null);
(function f() { assertStackIs([f, Function.prototype.apply, 'global-code']) }).apply(null, {});
(function f() { (function g(x,y,z) { assertStackIs([g,f,'global-code']); })() })(1);
/***********/
@ -135,10 +134,9 @@ new proxy();
/***********/
for (var i = 0; i < 10; ++i) {
eval("'no imacros please'");
/* No loss for scripts. */
(function f() {
assertStackIs([f, Function.prototype.apply, 'global-code']);
}).apply(null, {});
(function f() {
assertStackIs([f, Function.prototype.call, 'global-code']);
}).call(null);
@ -155,26 +153,4 @@ for (var i = 0; i < 10; ++i) {
assertEq(stack[1], Function.prototype.call);
}
}).bind().call(null);
(function f() {
var stack = dumpStack();
assertEq(stack[0], f);
if (stack.length === 4) {
assertEq(stack[1].name, 'f');
assertEq(stack[2], Function.prototype.apply);
} else {
assertEq(stack.length, 3);
assertEq(stack[1], Function.prototype.apply);
}
}).bind().apply(null, {});
(function f() {
var stack = dumpStack();
assertEq(stack[0], f);
if (stack.length === 4) {
assertEq(stack[1].name, 'f');
assertEq(stack[2], Function.prototype.apply);
} else {
assertEq(stack.length, 3);
assertEq(stack[1], Function.prototype.apply);
}
}).bind().apply(null, [1,2,3,4,5]);
}

View File

@ -1028,19 +1028,20 @@ StackIter::settleOnNewState()
*
* regs.sp == vp + 2 + argc
*
* The mjit Function.prototype.apply optimization breaks this
* invariant (see ic::SplatApplyArgs). Thus, for JSOP_FUNAPPLY we
* need to (slowly) reconstruct the depth.
*
* Additionally, the Function.prototype.{call,apply} optimizations
* leave no record when 'this' is a native function. Thus, if the
* following expression runs and breaks in the debugger, the call
* to 'replace' will not appear on the callstack.
* The Function.prototype.call optimization leaves no record when
* 'this' is a native function. Thus, if the following expression
* runs and breaks in the debugger, the call to 'replace' will not
* appear on the callstack.
*
* (String.prototype.replace).call('a',/a/,function(){debugger});
*
* Function.prototype.call will however appear, hence the debugger
* can, by inspecting 'args.thisv', give some useful information.
*
* For Function.prototype.apply, the situation is even worse: since
* a dynamic number of arguments have been pushed onto the stack
* (see SplatApplyArgs), there is no efficient way to know how to
* find the callee. Thus, calls to apply are lost completely.
*/
JSOp op = js_GetOpcode(cx_, fp_->script(), pc_);
if (op == JSOP_CALL || op == JSOP_FUNCALL) {
@ -1056,30 +1057,12 @@ StackIter::settleOnNewState()
args_ = CallArgsFromVp(argc, vp);
return;
}
} else if (op == JSOP_FUNAPPLY) {
JS_ASSERT(!fp_->hasImacropc());
uintN argc = GET_ARGC(pc_);
uintN spoff = js_ReconstructStackDepth(cx_, fp_->script(), pc_);
Value *sp = fp_->base() + spoff;
Value *vp = sp - (2 + argc);
CrashIfInvalidSlot(fp_, vp);
if (IsNativeFunction(*vp)) {
if (sp_ != sp) {
JS_ASSERT(argc == 2);
JS_ASSERT(vp[0].toObject().getFunctionPrivate()->native() == js_fun_apply);
JS_ASSERT(sp_ >= vp + 3);
argc = sp_ - (vp + 2);
}
state_ = IMPLICIT_NATIVE;
args_ = CallArgsFromVp(argc, vp);
return;
}
}
state_ = SCRIPTED;
JS_ASSERT(sp_ >= fp_->base() && sp_ <= fp_->slots() + fp_->script()->nslots);
DebugOnly<JSScript *> script = fp_->script();
JS_ASSERT_IF(op != JSOP_FUNAPPLY,
sp_ >= fp_->base() && sp_ <= fp_->slots() + script->nslots);
JS_ASSERT_IF(!fp_->hasImacropc(),
pc_ >= script->code && pc_ < script->code + script->length);
return;