зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1185106 - Part 0.1: Refactor JSOP_DEFFUN. r=efaust,jandem,till,h4writer
MozReview-Commit-ID: 8XpAiHEzWVm
This commit is contained in:
Родитель
5c16f7080d
Коммит
8f8d409007
|
@ -6942,6 +6942,13 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||
MOZ_ASSERT(pn->getOp() == JSOP_FUNWITHPROTO || pn->getOp() == JSOP_LAMBDA);
|
||||
pn->setOp(JSOP_FUNWITHPROTO);
|
||||
}
|
||||
|
||||
if (pn->getOp() == JSOP_DEFFUN) {
|
||||
if (!emitIndex32(JSOP_LAMBDA, index))
|
||||
return false;
|
||||
return emit1(JSOP_DEFFUN);
|
||||
}
|
||||
|
||||
return emitIndex32(pn->getOp(), index);
|
||||
}
|
||||
|
||||
|
@ -6972,7 +6979,9 @@ BytecodeEmitter::emitFunction(ParseNode* pn, bool needsProto)
|
|||
MOZ_ASSERT(sc->isGlobalContext() || sc->isEvalContext());
|
||||
MOZ_ASSERT(pn->getOp() == JSOP_NOP);
|
||||
switchToPrologue();
|
||||
if (!emitIndex32(JSOP_DEFFUN, index))
|
||||
if (!emitIndex32(JSOP_LAMBDA, index))
|
||||
return false;
|
||||
if (!emit1(JSOP_DEFFUN))
|
||||
return false;
|
||||
if (!updateSourceCoordNotes(pn->pn_pos.begin))
|
||||
return false;
|
||||
|
|
|
@ -2750,15 +2750,14 @@ static const VMFunction DefFunOperationInfo =
|
|||
bool
|
||||
BaselineCompiler::emit_JSOP_DEFFUN()
|
||||
{
|
||||
RootedFunction fun(cx, script->getFunction(GET_UINT32_INDEX(pc)));
|
||||
|
||||
frame.syncStack(0);
|
||||
masm.loadPtr(frame.addressOfEnvironmentChain(), R0.scratchReg());
|
||||
frame.popRegsAndSync(1);
|
||||
masm.unboxObject(R0, R0.scratchReg());
|
||||
masm.loadPtr(frame.addressOfEnvironmentChain(), R1.scratchReg());
|
||||
|
||||
prepareVMCall();
|
||||
|
||||
pushArg(ImmGCPtr(fun));
|
||||
pushArg(R0.scratchReg());
|
||||
pushArg(R1.scratchReg());
|
||||
pushArg(ImmGCPtr(script));
|
||||
|
||||
return callVM(DefFunOperationInfo);
|
||||
|
|
|
@ -4694,7 +4694,8 @@ CodeGenerator::visitDefFun(LDefFun* lir)
|
|||
{
|
||||
Register envChain = ToRegister(lir->environmentChain());
|
||||
|
||||
pushArg(ImmGCPtr(lir->mir()->fun()));
|
||||
Register fun = ToRegister(lir->fun());
|
||||
pushArg(fun);
|
||||
pushArg(envChain);
|
||||
pushArg(ImmGCPtr(current->mir()->info().script()));
|
||||
|
||||
|
|
|
@ -13442,13 +13442,9 @@ IonBuilder::jsop_deflexical(uint32_t index)
|
|||
bool
|
||||
IonBuilder::jsop_deffun(uint32_t index)
|
||||
{
|
||||
JSFunction* fun = script()->getFunction(index);
|
||||
if (IsAsmJSModule(fun))
|
||||
return abort("asm.js module function");
|
||||
|
||||
MOZ_ASSERT(analysis().usesEnvironmentChain());
|
||||
|
||||
MDefFun* deffun = MDefFun::New(alloc(), fun, current->environmentChain());
|
||||
MDefFun* deffun = MDefFun::New(alloc(), current->pop(), current->environmentChain());
|
||||
current->add(deffun);
|
||||
|
||||
return resumeAfter(deffun);
|
||||
|
|
|
@ -207,7 +207,11 @@ LIRGenerator::visitDefLexical(MDefLexical* ins)
|
|||
void
|
||||
LIRGenerator::visitDefFun(MDefFun* ins)
|
||||
{
|
||||
LDefFun* lir = new(alloc()) LDefFun(useRegisterAtStart(ins->environmentChain()));
|
||||
MDefinition* fun = ins->fun();
|
||||
MOZ_ASSERT(fun->type() == MIRType::Object);
|
||||
|
||||
LDefFun* lir = new(alloc()) LDefFun(useRegisterAtStart(fun),
|
||||
useRegisterAtStart(ins->environmentChain()));
|
||||
add(lir, ins);
|
||||
assignSafepoint(lir, ins);
|
||||
}
|
||||
|
|
|
@ -8106,31 +8106,22 @@ class MDefLexical
|
|||
};
|
||||
|
||||
class MDefFun
|
||||
: public MUnaryInstruction,
|
||||
public NoTypePolicy::Data
|
||||
: public MBinaryInstruction,
|
||||
public ObjectPolicy<0>::Data
|
||||
{
|
||||
CompilerFunction fun_;
|
||||
|
||||
private:
|
||||
MDefFun(JSFunction* fun, MDefinition* envChain)
|
||||
: MUnaryInstruction(envChain),
|
||||
fun_(fun)
|
||||
MDefFun(MDefinition* fun, MDefinition* envChain)
|
||||
: MBinaryInstruction(fun, envChain)
|
||||
{}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(DefFun)
|
||||
TRIVIAL_NEW_WRAPPERS
|
||||
NAMED_OPERANDS((0, environmentChain))
|
||||
NAMED_OPERANDS((0, fun), (1, environmentChain))
|
||||
|
||||
JSFunction* fun() const {
|
||||
return fun_;
|
||||
}
|
||||
bool possiblyCalls() const override {
|
||||
return true;
|
||||
}
|
||||
bool appendRoots(MRootList& roots) const override {
|
||||
return roots.append(fun_);
|
||||
}
|
||||
};
|
||||
|
||||
class MRegExp : public MNullaryInstruction
|
||||
|
|
|
@ -1550,19 +1550,23 @@ class LDefLexical : public LCallInstructionHelper<0, 0, 0>
|
|||
}
|
||||
};
|
||||
|
||||
class LDefFun : public LCallInstructionHelper<0, 1, 0>
|
||||
class LDefFun : public LCallInstructionHelper<0, 2, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(DefFun)
|
||||
|
||||
explicit LDefFun(const LAllocation& envChain)
|
||||
LDefFun(const LAllocation& fun, const LAllocation& envChain)
|
||||
{
|
||||
setOperand(0, envChain);
|
||||
setOperand(0, fun);
|
||||
setOperand(1, envChain);
|
||||
}
|
||||
|
||||
const LAllocation* environmentChain() {
|
||||
const LAllocation* fun() {
|
||||
return getOperand(0);
|
||||
}
|
||||
const LAllocation* environmentChain() {
|
||||
return getOperand(1);
|
||||
}
|
||||
MDefFun* mir() const {
|
||||
return mir_->toDefFun();
|
||||
}
|
||||
|
|
|
@ -3446,9 +3446,10 @@ CASE(JSOP_DEFFUN)
|
|||
* a compound statement (not at the top statement level of global code, or
|
||||
* at the top level of a function body).
|
||||
*/
|
||||
ReservedRooted<JSFunction*> fun(&rootFunction0, script->getFunction(GET_UINT32_INDEX(REGS.pc)));
|
||||
ReservedRooted<JSFunction*> fun(&rootFunction0, ®S.sp[-1].toObject().as<JSFunction>());
|
||||
if (!DefFunOperation(cx, script, REGS.fp()->environmentChain(), fun))
|
||||
goto error;
|
||||
REGS.sp--;
|
||||
}
|
||||
END_CASE(JSOP_DEFFUN)
|
||||
|
||||
|
@ -4330,27 +4331,8 @@ js::LambdaArrow(JSContext* cx, HandleFunction fun, HandleObject parent, HandleVa
|
|||
|
||||
bool
|
||||
js::DefFunOperation(JSContext* cx, HandleScript script, HandleObject envChain,
|
||||
HandleFunction funArg)
|
||||
HandleFunction fun)
|
||||
{
|
||||
/*
|
||||
* If static link is not current scope, clone fun's object to link to the
|
||||
* current scope via parent. We do this to enable sharing of compiled
|
||||
* functions among multiple equivalent scopes, amortizing the cost of
|
||||
* compilation over a number of executions. Examples include XUL scripts
|
||||
* and event handlers shared among Firefox or other Mozilla app chrome
|
||||
* windows, and user-defined JS functions precompiled and then shared among
|
||||
* requests in server-side JS.
|
||||
*/
|
||||
RootedFunction fun(cx, funArg);
|
||||
if (fun->isNative() || fun->environment() != envChain) {
|
||||
fun = CloneFunctionObjectIfNotSingleton(cx, fun, envChain, nullptr, TenuredObject);
|
||||
if (!fun)
|
||||
return false;
|
||||
} else {
|
||||
MOZ_ASSERT(script->treatAsRunOnce());
|
||||
MOZ_ASSERT(!script->functionNonDelazifying());
|
||||
}
|
||||
|
||||
/*
|
||||
* We define the function as a property of the variable object and not the
|
||||
* current scope chain even for the case of function expression statements
|
||||
|
|
|
@ -1300,10 +1300,10 @@
|
|||
* scripts where use of dynamic scoping inhibits optimization.
|
||||
* Category: Variables and Scopes
|
||||
* Type: Variables
|
||||
* Operands: uint32_t funcIndex
|
||||
* Stack: =>
|
||||
* Operands:
|
||||
* Stack: fun =>
|
||||
*/ \
|
||||
macro(JSOP_DEFFUN, 127,"deffun", NULL, 5, 0, 0, JOF_OBJECT) \
|
||||
macro(JSOP_DEFFUN, 127,"deffun", NULL, 1, 1, 0, JOF_BYTE) \
|
||||
/* Defines the new constant binding on global lexical scope.
|
||||
*
|
||||
* Throws if a binding with the same name already exists on the scope, or
|
||||
|
|
Загрузка…
Ссылка в новой задаче