Bug 749822 - Pass original argc to uncompiled functions. r=pierron

This commit is contained in:
Sean Stangl 2012-04-27 16:55:12 -07:00
parent 7c539ced68
commit 12bea17284
5 changed files with 20 additions and 9 deletions

View File

@ -616,9 +616,9 @@ CodeGenerator::visitCallGeneric(LCallGeneric *call)
// Each path must account for framePushed_ separately, for callVM to be valid. // Each path must account for framePushed_ separately, for callVM to be valid.
masm.freeStack(unusedStack); masm.freeStack(unusedStack);
pushArg(StackPointer); // argv. pushArg(StackPointer); // argv.
pushArg(Imm32(call->nargs())); // argc. pushArg(Imm32(call->bytecodeArgc())); // argc.
pushArg(calleereg); // JSFunction *. pushArg(calleereg); // JSFunction *.
if (!callVM(InvokeFunctionInfo, call)) if (!callVM(InvokeFunctionInfo, call))
return false; return false;

View File

@ -2626,7 +2626,7 @@ IonBuilder::makeCall(HandleFunction target, uint32 argc, bool constructing)
if (target && !target->isNative()) if (target && !target->isNative())
targetArgs = Max<uint32>(target->nargs, argc); targetArgs = Max<uint32>(target->nargs, argc);
MCall *call = MCall::New(targetArgs + 1, constructing); // +1 for implicit this. MCall *call = MCall::New(targetArgs + 1, argc, constructing); // +1 for implicit this.
if (!call) if (!call)
return false; return false;

View File

@ -419,6 +419,9 @@ class LCallGeneric : public LCallInstructionHelper<BOX_PIECES, 1, 2>
JS_ASSERT(mir()->argc() >= 1); JS_ASSERT(mir()->argc() >= 1);
return mir()->argc() - 1; // |this| is not a formal argument. return mir()->argc() - 1; // |this| is not a formal argument.
} }
uint32 bytecodeArgc() const {
return mir()->bytecodeArgc();
}
bool hasSingleTarget() const { bool hasSingleTarget() const {
return getSingleTarget() != NULL; return getSingleTarget() != NULL;

View File

@ -384,9 +384,9 @@ MParameter::congruentTo(MDefinition * const &ins) const
} }
MCall * MCall *
MCall::New(size_t argc, bool construct) MCall::New(size_t argc, size_t bytecodeArgc, bool construct)
{ {
MCall *ins = new MCall(construct); MCall *ins = new MCall(construct, bytecodeArgc);
if (!ins->init(argc + NumNonArgumentOperands)) if (!ins->init(argc + NumNonArgumentOperands))
return NULL; return NULL;
return ins; return ins;

View File

@ -1123,17 +1123,20 @@ class MCall
bool construct_; bool construct_;
// Monomorphic cache of single target from TI, or NULL. // Monomorphic cache of single target from TI, or NULL.
JSFunction *target_; JSFunction *target_;
// Original value of argc from the bytecode.
uint32 bytecodeArgc_;
MCall(bool construct) MCall(bool construct, uint32 bytecodeArgc)
: construct_(construct), : construct_(construct),
target_(NULL) target_(NULL),
bytecodeArgc_(bytecodeArgc)
{ {
setResultType(MIRType_Value); setResultType(MIRType_Value);
} }
public: public:
INSTRUCTION_HEADER(Call); INSTRUCTION_HEADER(Call);
static MCall *New(size_t argc, bool construct); static MCall *New(size_t argc, size_t bytecodeArgc, bool construct);
void initPrepareCall(MDefinition *start) { void initPrepareCall(MDefinition *start) {
JS_ASSERT(start->isPrepareCall()); JS_ASSERT(start->isPrepareCall());
@ -1174,6 +1177,11 @@ class MCall
return numOperands() - NumNonArgumentOperands; return numOperands() - NumNonArgumentOperands;
} }
// Includes |this|. Does not include any callsite-added Undefined values.
uint32 bytecodeArgc() const {
return bytecodeArgc_;
}
TypePolicy *typePolicy() { TypePolicy *typePolicy() {
return this; return this;
} }