зеркало из https://github.com/mozilla/gecko-dev.git
Bug 764310 part 2 - Implement JSOP_DEFFUN in IonMonkey. r=bhackett
This commit is contained in:
Родитель
ba8670f4b0
Коммит
7dc505b1cf
|
@ -1504,14 +1504,11 @@ static const VMFunction DefVarOrConstInfo =
|
|||
bool
|
||||
CodeGenerator::visitDefVar(LDefVar *lir)
|
||||
{
|
||||
Register scopeChain = ToRegister(lir->getScopeChain());
|
||||
Register nameTemp = ToRegister(lir->nameTemp());
|
||||
|
||||
masm.movePtr(ImmGCPtr(lir->mir()->name()), nameTemp);
|
||||
Register scopeChain = ToRegister(lir->scopeChain());
|
||||
|
||||
pushArg(scopeChain); // JSObject *
|
||||
pushArg(Imm32(lir->mir()->attrs())); // unsigned
|
||||
pushArg(nameTemp); // PropertyName *
|
||||
pushArg(ImmGCPtr(lir->mir()->name())); // PropertyName *
|
||||
|
||||
if (!callVM(DefVarOrConstInfo, lir))
|
||||
return false;
|
||||
|
@ -1519,6 +1516,21 @@ CodeGenerator::visitDefVar(LDefVar *lir)
|
|||
return true;
|
||||
}
|
||||
|
||||
typedef bool (*DefFunOperationFn)(JSContext *, HandleScript, HandleObject, HandleFunction);
|
||||
static const VMFunction DefFunOperationInfo = FunctionInfo<DefFunOperationFn>(DefFunOperation);
|
||||
|
||||
bool
|
||||
CodeGenerator::visitDefFun(LDefFun *lir)
|
||||
{
|
||||
Register scopeChain = ToRegister(lir->scopeChain());
|
||||
|
||||
pushArg(ImmGCPtr(lir->mir()->fun()));
|
||||
pushArg(scopeChain);
|
||||
pushArg(ImmGCPtr(current->mir()->info().script()));
|
||||
|
||||
return callVM(DefFunOperationInfo, lir);
|
||||
}
|
||||
|
||||
typedef bool (*ReportOverRecursedFn)(JSContext *);
|
||||
static const VMFunction CheckOverRecursedInfo =
|
||||
FunctionInfo<ReportOverRecursedFn>(CheckOverRecursed);
|
||||
|
|
|
@ -54,6 +54,7 @@ class CodeGenerator : public CodeGeneratorSpecific
|
|||
bool visitStart(LStart *lir);
|
||||
bool visitReturn(LReturn *ret);
|
||||
bool visitDefVar(LDefVar *lir);
|
||||
bool visitDefFun(LDefFun *lir);
|
||||
bool visitOsrEntry(LOsrEntry *lir);
|
||||
bool visitOsrScopeChain(LOsrScopeChain *lir);
|
||||
bool visitStackArgT(LStackArgT *lir);
|
||||
|
|
|
@ -842,6 +842,9 @@ IonBuilder::inspectOpcode(JSOp op)
|
|||
case JSOP_DEFCONST:
|
||||
return jsop_defvar(GET_UINT32_INDEX(pc));
|
||||
|
||||
case JSOP_DEFFUN:
|
||||
return jsop_deffun(GET_UINT32_INDEX(pc));
|
||||
|
||||
case JSOP_EQ:
|
||||
case JSOP_NE:
|
||||
case JSOP_STRICTEQ:
|
||||
|
@ -6775,7 +6778,7 @@ IonBuilder::jsop_defvar(uint32_t index)
|
|||
{
|
||||
JS_ASSERT(JSOp(*pc) == JSOP_DEFVAR || JSOp(*pc) == JSOP_DEFCONST);
|
||||
|
||||
PropertyName *name = script()->getName(index);
|
||||
RootedPropertyName name(cx, script()->getName(index));
|
||||
|
||||
// Bake in attrs.
|
||||
unsigned attrs = JSPROP_ENUMERATE | JSPROP_PERMANENT;
|
||||
|
@ -6792,6 +6795,19 @@ IonBuilder::jsop_defvar(uint32_t index)
|
|||
return resumeAfter(defvar);
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::jsop_deffun(uint32_t index)
|
||||
{
|
||||
RootedFunction fun(cx, script()->getFunction(index));
|
||||
|
||||
JS_ASSERT(script()->analysis()->usesScopeChain());
|
||||
|
||||
MDefFun *deffun = MDefFun::New(fun, current->scopeChain());
|
||||
current->add(deffun);
|
||||
|
||||
return resumeAfter(deffun);
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::jsop_this()
|
||||
{
|
||||
|
|
|
@ -334,6 +334,7 @@ class IonBuilder : public MIRGenerator
|
|||
bool jsop_pos();
|
||||
bool jsop_neg();
|
||||
bool jsop_defvar(uint32_t index);
|
||||
bool jsop_deffun(uint32_t index);
|
||||
bool jsop_notearg();
|
||||
bool jsop_funcall(uint32_t argc);
|
||||
bool jsop_funapply(uint32_t argc);
|
||||
|
|
|
@ -371,28 +371,42 @@ class LCheckOverRecursed : public LInstructionHelper<0, 0, 1>
|
|||
}
|
||||
};
|
||||
|
||||
class LDefVar : public LCallInstructionHelper<0, 1, 1>
|
||||
class LDefVar : public LCallInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(DefVar)
|
||||
|
||||
LDefVar(const LAllocation &scopeChain, const LDefinition &namereg)
|
||||
LDefVar(const LAllocation &scopeChain)
|
||||
{
|
||||
setOperand(0, scopeChain);
|
||||
setTemp(0, namereg);
|
||||
}
|
||||
|
||||
const LAllocation *getScopeChain() {
|
||||
const LAllocation *scopeChain() {
|
||||
return getOperand(0);
|
||||
}
|
||||
const LAllocation *nameTemp() {
|
||||
return getTemp(0)->output();
|
||||
}
|
||||
MDefVar *mir() const {
|
||||
return mir_->toDefVar();
|
||||
}
|
||||
};
|
||||
|
||||
class LDefFun : public LCallInstructionHelper<0, 1, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(DefFun)
|
||||
|
||||
LDefFun(const LAllocation &scopeChain)
|
||||
{
|
||||
setOperand(0, scopeChain);
|
||||
}
|
||||
|
||||
const LAllocation *scopeChain() {
|
||||
return getOperand(0);
|
||||
}
|
||||
MDefFun *mir() const {
|
||||
return mir_->toDefFun();
|
||||
}
|
||||
};
|
||||
|
||||
class LTypeOfV : public LInstructionHelper<1, BOX_PIECES, 0>
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
_(CheckOverRecursed) \
|
||||
_(RecompileCheck) \
|
||||
_(DefVar) \
|
||||
_(DefFun) \
|
||||
_(CallKnown) \
|
||||
_(CallGeneric) \
|
||||
_(CallNative) \
|
||||
|
|
|
@ -122,9 +122,7 @@ LIRGenerator::visitCheckOverRecursed(MCheckOverRecursed *ins)
|
|||
bool
|
||||
LIRGenerator::visitDefVar(MDefVar *ins)
|
||||
{
|
||||
LDefVar *lir = new LDefVar(useFixed(ins->scopeChain(), CallTempReg0),
|
||||
tempFixed(CallTempReg1));
|
||||
|
||||
LDefVar *lir = new LDefVar(useRegisterAtStart(ins->scopeChain()));
|
||||
if (!add(lir, ins))
|
||||
return false;
|
||||
if (!assignSafepoint(lir, ins))
|
||||
|
@ -133,6 +131,13 @@ LIRGenerator::visitDefVar(MDefVar *ins)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitDefFun(MDefFun *ins)
|
||||
{
|
||||
LDefFun *lir = new LDefFun(useRegisterAtStart(ins->scopeChain()));
|
||||
return add(lir, ins) && assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitNewSlots(MNewSlots *ins)
|
||||
{
|
||||
|
|
|
@ -87,6 +87,7 @@ class LIRGenerator : public LIRGeneratorSpecific
|
|||
bool visitInitProp(MInitProp *ins);
|
||||
bool visitCheckOverRecursed(MCheckOverRecursed *ins);
|
||||
bool visitDefVar(MDefVar *ins);
|
||||
bool visitDefFun(MDefFun *ins);
|
||||
bool visitPrepareCall(MPrepareCall *ins);
|
||||
bool visitPassArg(MPassArg *arg);
|
||||
bool visitCreateThisWithTemplate(MCreateThisWithTemplate *ins);
|
||||
|
|
|
@ -3062,8 +3062,8 @@ class MInterruptCheck : public MNullaryInstruction
|
|||
// If not defined, set a global variable to |undefined|.
|
||||
class MDefVar : public MUnaryInstruction
|
||||
{
|
||||
PropertyName *name_; // Target name to be defined.
|
||||
unsigned attrs_; // Attributes to be set.
|
||||
CompilerRootPropertyName name_; // Target name to be defined.
|
||||
unsigned attrs_; // Attributes to be set.
|
||||
|
||||
private:
|
||||
MDefVar(PropertyName *name, unsigned attrs, MDefinition *scopeChain)
|
||||
|
@ -3092,6 +3092,31 @@ class MDefVar : public MUnaryInstruction
|
|||
|
||||
};
|
||||
|
||||
class MDefFun : public MUnaryInstruction
|
||||
{
|
||||
CompilerRootFunction fun_;
|
||||
|
||||
private:
|
||||
MDefFun(HandleFunction fun, MDefinition *scopeChain)
|
||||
: MUnaryInstruction(scopeChain),
|
||||
fun_(fun)
|
||||
{}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(DefFun)
|
||||
|
||||
static MDefFun *New(HandleFunction fun, MDefinition *scopeChain) {
|
||||
return new MDefFun(fun, scopeChain);
|
||||
}
|
||||
|
||||
JSFunction *fun() const {
|
||||
return fun_;
|
||||
}
|
||||
MDefinition *scopeChain() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
};
|
||||
|
||||
class MRegExp : public MNullaryInstruction
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -29,6 +29,7 @@ namespace ion {
|
|||
_(CheckOverRecursed) \
|
||||
_(RecompileCheck) \
|
||||
_(DefVar) \
|
||||
_(DefFun) \
|
||||
_(CreateThis) \
|
||||
_(CreateThisWithTemplate) \
|
||||
_(PrepareCall) \
|
||||
|
|
Загрузка…
Ссылка в новой задаче