mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Handle JSOP_DEFVAR, JSOP_DEFCONST. (Bug 725532, r=dvander)
This commit is contained in:
parent
a4fa17e0cb
commit
22ab59f33c
@ -824,6 +824,28 @@ CodeGenerator::visitCheckOverRecursed(LCheckOverRecursed *lir)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenerator::visitDefVar(LDefVar *lir)
|
||||
{
|
||||
Register scopeChain = ToRegister(lir->getScopeChain());
|
||||
Register nameTemp = ToRegister(lir->nameTemp());
|
||||
|
||||
typedef bool (*pf)(JSContext *, PropertyName *, uintN, JSObject *);
|
||||
static const VMFunction DefVarOrConstInfo =
|
||||
FunctionInfo<pf>(DefVarOrConst);
|
||||
|
||||
masm.movePtr(ImmWord(lir->mir()->name()), nameTemp);
|
||||
|
||||
pushArg(scopeChain); // JSObject *
|
||||
pushArg(Imm32(lir->mir()->attrs())); // uintN
|
||||
pushArg(nameTemp); // PropertyName *
|
||||
|
||||
if (!callVM(DefVarOrConstInfo, lir))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CodeGenerator::visitCheckOverRecursedFailure(CheckOverRecursedFailure *ool)
|
||||
{
|
||||
|
@ -80,6 +80,7 @@ class CodeGenerator : public CodeGeneratorSpecific
|
||||
bool visitCallee(LCallee *lir);
|
||||
bool visitStart(LStart *lir);
|
||||
bool visitReturn(LReturn *ret);
|
||||
bool visitDefVar(LDefVar *lir);
|
||||
bool visitOsrEntry(LOsrEntry *lir);
|
||||
bool visitOsrScopeChain(LOsrScopeChain *lir);
|
||||
bool visitStackArg(LStackArg *lir);
|
||||
|
@ -773,6 +773,7 @@ CheckFrame(StackFrame *fp)
|
||||
if (fp->isEvalFrame()) {
|
||||
// Eval frames are not yet supported. Supporting this will require new
|
||||
// logic in pushBailoutFrame to deal with linking prev.
|
||||
// Additionally, JSOP_DEFVAR support will require baking in isEvalFrame().
|
||||
IonSpew(IonSpew_Abort, "eval frame");
|
||||
return false;
|
||||
}
|
||||
|
@ -640,6 +640,10 @@ IonBuilder::inspectOpcode(JSOp op)
|
||||
case JSOP_OR:
|
||||
return jsop_andor(op);
|
||||
|
||||
case JSOP_DEFVAR:
|
||||
case JSOP_DEFCONST:
|
||||
return jsop_defvar(GET_SLOTNO(pc));
|
||||
|
||||
case JSOP_LOCALINC:
|
||||
case JSOP_INCLOCAL:
|
||||
case JSOP_LOCALDEC:
|
||||
@ -3668,6 +3672,31 @@ IonBuilder::jsop_deflocalfun(uint32 local, JSFunction *fun)
|
||||
return resumeAfter(ins);
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::jsop_defvar(uint32 index)
|
||||
{
|
||||
JS_ASSERT(JSOp(*pc) == JSOP_DEFVAR || JSOp(*pc) == JSOP_DEFCONST);
|
||||
|
||||
PropertyName *name = script->getName(index);
|
||||
|
||||
// Bake in attrs.
|
||||
uintN attrs = JSPROP_ENUMERATE;
|
||||
// isEvalFrame() requires attrs |= JSPROP_PERMANENT.
|
||||
if (JSOp(*pc) == JSOP_DEFCONST)
|
||||
attrs |= JSPROP_READONLY;
|
||||
|
||||
// Pass the ScopeChain.
|
||||
JS_ASSERT(script->analysis()->usesScopeChain());
|
||||
MDefinition *scopeChain = current->getSlot(info().scopeChainSlot());
|
||||
JS_ASSERT(scopeChain->type() == MIRType_Object);
|
||||
|
||||
// Bake the name pointer into the MDefVar.
|
||||
MDefVar *defvar = MDefVar::New(name, attrs, scopeChain);
|
||||
current->add(defvar);
|
||||
|
||||
return resumeAfter(defvar);
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::jsop_this()
|
||||
{
|
||||
|
@ -285,6 +285,7 @@ class IonBuilder : public MIRGenerator
|
||||
bool jsop_binary(JSOp op, MDefinition *left, MDefinition *right);
|
||||
bool jsop_pos();
|
||||
bool jsop_neg();
|
||||
bool jsop_defvar(uint32 index);
|
||||
bool jsop_notearg();
|
||||
bool jsop_call(uint32 argc, bool constructing);
|
||||
bool jsop_ifeq(JSOp op);
|
||||
|
@ -250,6 +250,28 @@ class LCheckOverRecursed : public LInstructionHelper<0, 0, 1>
|
||||
}
|
||||
};
|
||||
|
||||
class LDefVar : public LInstructionHelper<0, 1, 1>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(DefVar);
|
||||
|
||||
LDefVar(const LAllocation &scopeChain, const LDefinition &namereg)
|
||||
{
|
||||
setOperand(0, scopeChain);
|
||||
setTemp(0, namereg);
|
||||
}
|
||||
|
||||
const LAllocation *getScopeChain() {
|
||||
return getOperand(0);
|
||||
}
|
||||
const LAllocation *nameTemp() {
|
||||
return getTemp(0)->output();
|
||||
}
|
||||
MDefVar *mir() const {
|
||||
return mir_->toDefVar();
|
||||
}
|
||||
};
|
||||
|
||||
class LTypeOfV : public LInstructionHelper<1, BOX_PIECES, 0>
|
||||
{
|
||||
public:
|
||||
|
@ -58,6 +58,7 @@
|
||||
_(NewArray) \
|
||||
_(CheckOverRecursed) \
|
||||
_(RecompileCheck) \
|
||||
_(DefVar) \
|
||||
_(CallGeneric) \
|
||||
_(CallNative) \
|
||||
_(StackArg) \
|
||||
|
@ -106,9 +106,28 @@ LIRGenerator::visitCheckOverRecursed(MCheckOverRecursed *ins)
|
||||
{
|
||||
LCheckOverRecursed *lir = new LCheckOverRecursed(temp(LDefinition::GENERAL));
|
||||
|
||||
if (!add(lir))
|
||||
return false;
|
||||
if (!assignSafepoint(lir, ins))
|
||||
return false;
|
||||
return add(lir);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
LIRGenerator::visitDefVar(MDefVar *ins)
|
||||
{
|
||||
LAllocation scopeChain = useRegister(ins->scopeChain());
|
||||
LDefVar *lir = new LDefVar(scopeChain, temp(LDefinition::GENERAL));
|
||||
|
||||
lir->setMir(ins);
|
||||
|
||||
if (!add(lir))
|
||||
return false;
|
||||
if (!assignSafepoint(lir, ins))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -116,6 +116,7 @@ class LIRGenerator : public LIRGeneratorSpecific
|
||||
bool visitGoto(MGoto *ins);
|
||||
bool visitNewArray(MNewArray *ins);
|
||||
bool visitCheckOverRecursed(MCheckOverRecursed *ins);
|
||||
bool visitDefVar(MDefVar *ins);
|
||||
bool visitPrepareCall(MPrepareCall *ins);
|
||||
bool visitPassArg(MPassArg *arg);
|
||||
bool visitCall(MCall *call);
|
||||
|
@ -2139,6 +2139,39 @@ class MRecompileCheck : public MNullaryInstruction
|
||||
}
|
||||
};
|
||||
|
||||
// If not defined, set a global variable to |undefined|.
|
||||
class MDefVar : public MUnaryInstruction
|
||||
{
|
||||
PropertyName *name_; // Target name to be defined.
|
||||
uintN attrs_; // Attributes to be set.
|
||||
|
||||
private:
|
||||
MDefVar(PropertyName *name, uintN attrs, MDefinition *scopeChain)
|
||||
: MUnaryInstruction(scopeChain),
|
||||
name_(name),
|
||||
attrs_(attrs)
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(DefVar);
|
||||
|
||||
static MDefVar *New(PropertyName *name, uintN attrs, MDefinition *scopeChain) {
|
||||
return new MDefVar(name, attrs, scopeChain);
|
||||
}
|
||||
|
||||
PropertyName *name() const {
|
||||
return name_;
|
||||
}
|
||||
uintN attrs() const {
|
||||
return attrs_;
|
||||
}
|
||||
MDefinition *scopeChain() const {
|
||||
return getOperand(0);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class MRegExp : public MNullaryInstruction
|
||||
{
|
||||
public:
|
||||
|
@ -59,6 +59,7 @@ namespace ion {
|
||||
_(OsrScopeChain) \
|
||||
_(CheckOverRecursed) \
|
||||
_(RecompileCheck) \
|
||||
_(DefVar) \
|
||||
_(PrepareCall) \
|
||||
_(PassArg) \
|
||||
_(Call) \
|
||||
|
@ -87,6 +87,17 @@ ReportOverRecursed(JSContext *cx)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
DefVarOrConst(JSContext *cx, PropertyName *dn, uintN attrs, JSObject *scopeChain)
|
||||
{
|
||||
// Given the ScopeChain, extract the VarObj.
|
||||
JSObject *obj = scopeChain;
|
||||
while (!obj->isVarObj())
|
||||
obj = obj->enclosingScope();
|
||||
|
||||
return DefVarOrConstOperation(cx, *obj, dn, attrs);
|
||||
}
|
||||
|
||||
template<bool Equal>
|
||||
bool
|
||||
LooselyEqual(JSContext *cx, const Value &lhs, const Value &rhs, JSBool *res)
|
||||
|
@ -293,6 +293,8 @@ bool InvokeFunction(JSContext *cx, JSFunction *fun, uint32 argc, Value *argv, Va
|
||||
bool InvokeConstructorFunction(JSContext *cx, JSFunction *fun, uint32 argc, Value *argv, Value *rval);
|
||||
bool ReportOverRecursed(JSContext *cx);
|
||||
|
||||
bool DefVarOrConst(JSContext *cx, PropertyName *dn, uintN attrs, JSObject *scopeChain);
|
||||
|
||||
template<bool Equal>
|
||||
bool LooselyEqual(JSContext *cx, const Value &lhs, const Value &rhs, JSBool *res);
|
||||
|
||||
|
@ -354,6 +354,7 @@ ScriptAnalysis::analyzeBytecode(JSContext *cx)
|
||||
case JSOP_SETCONST:
|
||||
checkAliasedName(cx, pc);
|
||||
extendsScope_ = true;
|
||||
usesScopeChain_ = true; // Requires access to VarObj via ScopeChain.
|
||||
isInlineable = canTrackVars = false;
|
||||
break;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user