зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1016936 - Part 3: Support JSOP_CHECKISOBJ in Ion. r=jandem
This commit is contained in:
Родитель
726a539a34
Коммит
453cda5798
|
@ -11626,6 +11626,22 @@ CodeGenerator::visitCheckReturn(LCheckReturn* ins)
|
|||
masm.bind(&noChecks);
|
||||
}
|
||||
|
||||
typedef bool (*ThrowCheckIsObjectFn)(JSContext*, CheckIsObjectKind);
|
||||
static const VMFunction ThrowCheckIsObjectInfo =
|
||||
FunctionInfo<ThrowCheckIsObjectFn>(ThrowCheckIsObject, "ThrowCheckIsObject");
|
||||
|
||||
void
|
||||
CodeGenerator::visitCheckIsObj(LCheckIsObj* ins)
|
||||
{
|
||||
ValueOperand checkValue = ToValue(ins, LCheckIsObj::CheckValue);
|
||||
|
||||
OutOfLineCode* ool = oolCallVM(ThrowCheckIsObjectInfo, ins,
|
||||
ArgList(Imm32(ins->mir()->checkKind())),
|
||||
StoreNothing());
|
||||
masm.branchTestObject(Assembler::NotEqual, checkValue, ool->entry());
|
||||
masm.bind(ool->rejoin());
|
||||
}
|
||||
|
||||
typedef bool (*ThrowObjCoercibleFn)(JSContext*, HandleValue);
|
||||
static const VMFunction ThrowObjectCoercibleInfo =
|
||||
FunctionInfo<ThrowObjCoercibleFn>(ThrowObjectCoercible, "ThrowObjectCoercible");
|
||||
|
|
|
@ -373,6 +373,7 @@ class CodeGenerator final : public CodeGeneratorSpecific
|
|||
void visitNewTarget(LNewTarget* ins);
|
||||
void visitArrowNewTarget(LArrowNewTarget* ins);
|
||||
void visitCheckReturn(LCheckReturn* ins);
|
||||
void visitCheckIsObj(LCheckIsObj* ins);
|
||||
void visitCheckObjCoercible(LCheckObjCoercible* ins);
|
||||
void visitDebugCheckSelfHosted(LDebugCheckSelfHosted* ins);
|
||||
|
||||
|
|
|
@ -2145,6 +2145,9 @@ IonBuilder::inspectOpcode(JSOp op)
|
|||
case JSOP_NEWTARGET:
|
||||
return jsop_newtarget();
|
||||
|
||||
case JSOP_CHECKISOBJ:
|
||||
return jsop_checkisobj(GET_UINT8(pc));
|
||||
|
||||
case JSOP_CHECKOBJCOERCIBLE:
|
||||
return jsop_checkobjcoercible();
|
||||
|
||||
|
@ -10794,6 +10797,22 @@ IonBuilder::jsop_rest()
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::jsop_checkisobj(uint8_t kind)
|
||||
{
|
||||
MDefinition* toCheck = current->peek(-1);
|
||||
|
||||
if (toCheck->type() == MIRType::Object) {
|
||||
toCheck->setImplicitlyUsedUnchecked();
|
||||
return true;
|
||||
}
|
||||
|
||||
MCheckIsObj* check = MCheckIsObj::New(alloc(), current->pop(), kind);
|
||||
current->add(check);
|
||||
current->push(check);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IonBuilder::jsop_checkobjcoercible()
|
||||
{
|
||||
|
|
|
@ -780,6 +780,7 @@ class IonBuilder
|
|||
MOZ_MUST_USE bool jsop_setaliasedvar(ScopeCoordinate sc);
|
||||
MOZ_MUST_USE bool jsop_debugger();
|
||||
MOZ_MUST_USE bool jsop_newtarget();
|
||||
MOZ_MUST_USE bool jsop_checkisobj(uint8_t kind);
|
||||
MOZ_MUST_USE bool jsop_checkobjcoercible();
|
||||
|
||||
/* Inlining. */
|
||||
|
|
|
@ -4568,6 +4568,18 @@ LIRGenerator::visitCheckReturn(MCheckReturn* ins)
|
|||
redefine(ins, retVal);
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitCheckIsObj(MCheckIsObj* ins)
|
||||
{
|
||||
MDefinition* checkVal = ins->checkValue();
|
||||
MOZ_ASSERT(checkVal->type() == MIRType::Value);
|
||||
|
||||
LCheckIsObj* lir = new(alloc()) LCheckIsObj(useBoxAtStart(checkVal));
|
||||
redefine(ins, checkVal);
|
||||
add(lir, ins);
|
||||
assignSafepoint(lir, ins);
|
||||
}
|
||||
|
||||
void
|
||||
LIRGenerator::visitCheckObjCoercible(MCheckObjCoercible* ins)
|
||||
{
|
||||
|
|
|
@ -317,6 +317,7 @@ class LIRGenerator : public LIRGeneratorSpecific
|
|||
void visitAtomicIsLockFree(MAtomicIsLockFree* ins);
|
||||
void visitGuardSharedTypedArray(MGuardSharedTypedArray* ins);
|
||||
void visitCheckReturn(MCheckReturn* ins);
|
||||
void visitCheckIsObj(MCheckIsObj* ins);
|
||||
void visitCheckObjCoercible(MCheckObjCoercible* ins);
|
||||
void visitDebugCheckSelfHosted(MDebugCheckSelfHosted* ins);
|
||||
};
|
||||
|
|
|
@ -13050,6 +13050,32 @@ class MDebugger : public MNullaryInstruction
|
|||
TRIVIAL_NEW_WRAPPERS
|
||||
};
|
||||
|
||||
class MCheckIsObj
|
||||
: public MUnaryInstruction,
|
||||
public BoxInputsPolicy::Data
|
||||
{
|
||||
uint8_t checkKind_;
|
||||
|
||||
explicit MCheckIsObj(MDefinition* toCheck, uint8_t checkKind)
|
||||
: MUnaryInstruction(toCheck), checkKind_(checkKind)
|
||||
{
|
||||
setResultType(MIRType::Value);
|
||||
setResultTypeSet(toCheck->resultTypeSet());
|
||||
setGuard();
|
||||
}
|
||||
|
||||
public:
|
||||
INSTRUCTION_HEADER(CheckIsObj)
|
||||
TRIVIAL_NEW_WRAPPERS
|
||||
NAMED_OPERANDS((0, checkValue))
|
||||
|
||||
uint8_t checkKind() const { return checkKind_; }
|
||||
|
||||
AliasSet getAliasSet() const override {
|
||||
return AliasSet::None();
|
||||
}
|
||||
};
|
||||
|
||||
class MCheckObjCoercible
|
||||
: public MUnaryInstruction,
|
||||
public BoxInputsPolicy::Data
|
||||
|
@ -13066,7 +13092,6 @@ class MCheckObjCoercible
|
|||
INSTRUCTION_HEADER(CheckObjCoercible)
|
||||
TRIVIAL_NEW_WRAPPERS
|
||||
NAMED_OPERANDS((0, checkValue))
|
||||
|
||||
};
|
||||
|
||||
class MDebugCheckSelfHosted
|
||||
|
|
|
@ -302,6 +302,7 @@ namespace jit {
|
|||
_(NewTarget) \
|
||||
_(ArrowNewTarget) \
|
||||
_(CheckReturn) \
|
||||
_(CheckIsObj) \
|
||||
_(CheckObjCoercible) \
|
||||
_(DebugCheckSelfHosted)
|
||||
|
||||
|
|
|
@ -8696,6 +8696,22 @@ class LCheckReturn : public LCallInstructionHelper<BOX_PIECES, 2 * BOX_PIECES, 0
|
|||
static const size_t ThisValue = BOX_PIECES;
|
||||
};
|
||||
|
||||
class LCheckIsObj : public LInstructionHelper<BOX_PIECES, BOX_PIECES, 0>
|
||||
{
|
||||
public:
|
||||
LIR_HEADER(CheckIsObj)
|
||||
|
||||
static const size_t CheckValue = 0;
|
||||
|
||||
explicit LCheckIsObj(const LBoxAllocation& value) {
|
||||
setBoxOperand(CheckValue, value);
|
||||
}
|
||||
|
||||
MCheckIsObj* mir() const {
|
||||
return mir_->toCheckIsObj();
|
||||
}
|
||||
};
|
||||
|
||||
class LCheckObjCoercible : public LCallInstructionHelper<BOX_PIECES, BOX_PIECES, 0>
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -427,6 +427,7 @@
|
|||
_(NewTarget) \
|
||||
_(ArrowNewTarget) \
|
||||
_(CheckReturn) \
|
||||
_(CheckIsObj) \
|
||||
_(CheckObjCoercible) \
|
||||
_(DebugCheckSelfHosted)
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче