зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1507484 - Implement minimal Ion support for BigInt r=wingo,jandem
Co-authored-by: Andy Wingo <wingo@igalia.com> Differential Revision: https://phabricator.services.mozilla.com/D14826 --HG-- extra : moz-landing-system : lando
This commit is contained in:
Родитель
587bc41d36
Коммит
e11487a677
|
@ -2183,6 +2183,9 @@ bool jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo) {
|
|||
case Bailout_NonObjectInput:
|
||||
case Bailout_NonStringInput:
|
||||
case Bailout_NonSymbolInput:
|
||||
#ifdef ENABLE_BIGINT
|
||||
case Bailout_NonBigIntInput:
|
||||
#endif
|
||||
case Bailout_NonSharedTypedArrayInput:
|
||||
case Bailout_Debugger:
|
||||
case Bailout_UninitializedThis:
|
||||
|
|
|
@ -786,9 +786,11 @@ void CodeGenerator::testValueTruthyKernel(
|
|||
bool mightBeString = valueMIR->mightBeType(MIRType::String);
|
||||
bool mightBeSymbol = valueMIR->mightBeType(MIRType::Symbol);
|
||||
bool mightBeDouble = valueMIR->mightBeType(MIRType::Double);
|
||||
bool mightBeBigInt = IF_BIGINT(valueMIR->mightBeType(MIRType::BigInt), false);
|
||||
int tagCount = int(mightBeUndefined) + int(mightBeNull) +
|
||||
int(mightBeBoolean) + int(mightBeInt32) + int(mightBeObject) +
|
||||
int(mightBeString) + int(mightBeSymbol) + int(mightBeDouble);
|
||||
int(mightBeString) + int(mightBeSymbol) + int(mightBeDouble) +
|
||||
int(mightBeBigInt);
|
||||
|
||||
MOZ_ASSERT_IF(!valueMIR->emptyResultTypeSet(), tagCount > 0);
|
||||
|
||||
|
@ -902,6 +904,25 @@ void CodeGenerator::testValueTruthyKernel(
|
|||
--tagCount;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (mightBeBigInt) {
|
||||
MOZ_ASSERT(tagCount != 0);
|
||||
Label notBigInt;
|
||||
if (tagCount != 1) {
|
||||
masm.branchTestBigInt(Assembler::NotEqual, tag, ¬BigInt);
|
||||
}
|
||||
{
|
||||
ScratchTagScopeRelease _(&tag);
|
||||
masm.branchTestBigIntTruthy(false, value, ifFalsy);
|
||||
}
|
||||
if (tagCount != 1) {
|
||||
masm.jump(ifTruthy);
|
||||
}
|
||||
masm.bind(¬BigInt);
|
||||
--tagCount;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mightBeSymbol) {
|
||||
// All symbols are truthy.
|
||||
MOZ_ASSERT(tagCount != 0);
|
||||
|
@ -1244,6 +1265,14 @@ void CodeGenerator::visitValueToString(LValueToString* lir) {
|
|||
bailoutFrom(&bail, lir->snapshot());
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
// BigInt
|
||||
if (lir->mir()->input()->mightBeType(MIRType::BigInt)) {
|
||||
// No fastpath currently implemented.
|
||||
masm.branchTestBigInt(Assembler::Equal, tag, ool->entry());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
masm.assumeUnreachable("Unexpected type for MValueToString.");
|
||||
#endif
|
||||
|
@ -5598,10 +5627,11 @@ void CodeGenerator::branchIfInvalidated(Register temp, Label* invalidated) {
|
|||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
void CodeGenerator::emitAssertObjectOrStringResult(
|
||||
Register input, MIRType type, const TemporaryTypeSet* typeset) {
|
||||
void CodeGenerator::emitAssertGCThingResult(Register input, MIRType type,
|
||||
const TemporaryTypeSet* typeset) {
|
||||
MOZ_ASSERT(type == MIRType::Object || type == MIRType::ObjectOrNull ||
|
||||
type == MIRType::String || type == MIRType::Symbol);
|
||||
type == MIRType::String || type == MIRType::Symbol ||
|
||||
IF_BIGINT(type == MIRType::BigInt, false));
|
||||
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(input);
|
||||
|
@ -5659,6 +5689,11 @@ void CodeGenerator::emitAssertObjectOrStringResult(
|
|||
case MIRType::Symbol:
|
||||
callee = JS_FUNC_TO_DATA_PTR(void*, AssertValidSymbolPtr);
|
||||
break;
|
||||
# ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
callee = JS_FUNC_TO_DATA_PTR(void*, AssertValidBigIntPtr);
|
||||
break;
|
||||
# endif
|
||||
default:
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
@ -5730,8 +5765,8 @@ void CodeGenerator::emitAssertResultV(const ValueOperand input,
|
|||
masm.pop(temp1);
|
||||
}
|
||||
|
||||
void CodeGenerator::emitObjectOrStringResultChecks(LInstruction* lir,
|
||||
MDefinition* mir) {
|
||||
void CodeGenerator::emitGCThingResultChecks(LInstruction* lir,
|
||||
MDefinition* mir) {
|
||||
if (lir->numDefs() == 0) {
|
||||
return;
|
||||
}
|
||||
|
@ -5742,7 +5777,7 @@ void CodeGenerator::emitObjectOrStringResultChecks(LInstruction* lir,
|
|||
}
|
||||
|
||||
Register output = ToRegister(lir->getDef(0));
|
||||
emitAssertObjectOrStringResult(output, mir->type(), mir->resultTypeSet());
|
||||
emitAssertGCThingResult(output, mir->type(), mir->resultTypeSet());
|
||||
}
|
||||
|
||||
void CodeGenerator::emitValueResultChecks(LInstruction* lir, MDefinition* mir) {
|
||||
|
@ -5773,7 +5808,10 @@ void CodeGenerator::emitDebugResultChecks(LInstruction* ins) {
|
|||
case MIRType::ObjectOrNull:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
emitObjectOrStringResultChecks(ins, mir);
|
||||
# ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
# endif
|
||||
emitGCThingResultChecks(ins, mir);
|
||||
break;
|
||||
case MIRType::Value:
|
||||
emitValueResultChecks(ins, mir);
|
||||
|
@ -11162,11 +11200,14 @@ void CodeGenerator::visitTypeOfV(LTypeOfV* lir) {
|
|||
bool testNull = input->mightBeType(MIRType::Null);
|
||||
bool testString = input->mightBeType(MIRType::String);
|
||||
bool testSymbol = input->mightBeType(MIRType::Symbol);
|
||||
#ifdef ENABLE_BIGINT
|
||||
bool testBigInt = input->mightBeType(MIRType::BigInt);
|
||||
#endif
|
||||
|
||||
unsigned numTests = unsigned(testObject) + unsigned(testNumber) +
|
||||
unsigned(testBoolean) + unsigned(testUndefined) +
|
||||
unsigned(testNull) + unsigned(testString) +
|
||||
unsigned(testSymbol);
|
||||
unsigned(testSymbol) + unsigned(IF_BIGINT(testBigInt, 0));
|
||||
|
||||
MOZ_ASSERT_IF(!input->emptyResultTypeSet(), numTests > 0);
|
||||
|
||||
|
@ -11277,6 +11318,21 @@ void CodeGenerator::visitTypeOfV(LTypeOfV* lir) {
|
|||
numTests--;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (testBigInt) {
|
||||
Label notBigInt;
|
||||
if (numTests > 1) {
|
||||
masm.branchTestBigInt(Assembler::NotEqual, tag, ¬BigInt);
|
||||
}
|
||||
masm.movePtr(ImmGCPtr(names.bigint), output);
|
||||
if (numTests > 1) {
|
||||
masm.jump(&done);
|
||||
}
|
||||
masm.bind(¬BigInt);
|
||||
numTests--;
|
||||
}
|
||||
#endif
|
||||
|
||||
MOZ_ASSERT(numTests == 0);
|
||||
|
||||
masm.bind(&done);
|
||||
|
@ -12874,7 +12930,7 @@ void CodeGenerator::visitAssertResultT(LAssertResultT* ins) {
|
|||
#ifdef DEBUG
|
||||
Register input = ToRegister(ins->input());
|
||||
MDefinition* mir = ins->mirRaw();
|
||||
emitAssertObjectOrStringResult(input, mir->type(), mir->resultTypeSet());
|
||||
emitAssertGCThingResult(input, mir->type(), mir->resultTypeSet());
|
||||
#else
|
||||
MOZ_CRASH("LAssertResultT is debug only");
|
||||
#endif
|
||||
|
|
|
@ -193,8 +193,8 @@ class CodeGenerator final : public CodeGeneratorSpecific {
|
|||
#ifdef DEBUG
|
||||
void emitAssertResultV(const ValueOperand output,
|
||||
const TemporaryTypeSet* typeset);
|
||||
void emitAssertObjectOrStringResult(Register input, MIRType type,
|
||||
const TemporaryTypeSet* typeset);
|
||||
void emitAssertGCThingResult(Register input, MIRType type,
|
||||
const TemporaryTypeSet* typeset);
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -314,7 +314,7 @@ class CodeGenerator final : public CodeGeneratorSpecific {
|
|||
|
||||
#ifdef DEBUG
|
||||
void emitDebugResultChecks(LInstruction* ins);
|
||||
void emitObjectOrStringResultChecks(LInstruction* lir, MDefinition* mir);
|
||||
void emitGCThingResultChecks(LInstruction* lir, MDefinition* mir);
|
||||
void emitValueResultChecks(LInstruction* lir, MDefinition* mir);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -2344,7 +2344,8 @@ static bool CanCompareRegExp(MCompare* compare, MDefinition* def) {
|
|||
value->mightBeType(MIRType::Int32) ||
|
||||
value->mightBeType(MIRType::Double) ||
|
||||
value->mightBeType(MIRType::Float32) ||
|
||||
value->mightBeType(MIRType::Symbol)) {
|
||||
value->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(value->mightBeType(MIRType::BigInt), false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -3176,6 +3177,9 @@ static bool IsResumableMIRType(MIRType type) {
|
|||
case MIRType::Float32:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
# ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
# endif
|
||||
case MIRType::Object:
|
||||
case MIRType::MagicOptimizedArguments:
|
||||
case MIRType::MagicOptimizedOut:
|
||||
|
|
|
@ -717,6 +717,11 @@ AbortReasonOr<Ok> IonBuilder::analyzeNewLoopTypes(
|
|||
case JSOP_DEC:
|
||||
type = inspector->expectedResultType(last);
|
||||
break;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case JSOP_BIGINT:
|
||||
type = MIRType::BigInt;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1337,6 +1342,9 @@ AbortReasonOr<Ok> IonBuilder::addOsrValueTypeBarrier(
|
|||
case MIRType::Double:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
#endif
|
||||
case MIRType::Object:
|
||||
if (type != def->type()) {
|
||||
MUnbox* unbox = MUnbox::New(alloc(), def, type, MUnbox::Fallible);
|
||||
|
@ -3349,7 +3357,8 @@ AbortReasonOr<Ok> IonBuilder::bitnotTrySpecialized(bool* emitted,
|
|||
// of the operand.
|
||||
|
||||
if (input->mightBeType(MIRType::Object) ||
|
||||
input->mightBeType(MIRType::Symbol)) {
|
||||
input->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(input->mightBeType(MIRType::BigInt), false)) {
|
||||
return Ok();
|
||||
}
|
||||
|
||||
|
@ -6210,6 +6219,7 @@ static bool ObjectOrSimplePrimitive(MDefinition* op) {
|
|||
// Return true if op is either undefined/null/boolean/int32/symbol or an
|
||||
// object.
|
||||
return !op->mightBeType(MIRType::String) &&
|
||||
IF_BIGINT(!op->mightBeType(MIRType::BigInt), true) &&
|
||||
!op->mightBeType(MIRType::Double) &&
|
||||
!op->mightBeType(MIRType::Float32) &&
|
||||
!op->mightBeType(MIRType::MagicOptimizedArguments) &&
|
||||
|
@ -7460,6 +7470,12 @@ JSObject* IonBuilder::testSingletonPropertyTypes(MDefinition* obj, jsid id) {
|
|||
key = JSProto_Symbol;
|
||||
break;
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
key = JSProto_BigInt;
|
||||
break;
|
||||
#endif
|
||||
|
||||
case MIRType::Int32:
|
||||
case MIRType::Double:
|
||||
key = JSProto_Number;
|
||||
|
|
|
@ -124,6 +124,9 @@ enum BailoutKind {
|
|||
Bailout_NonObjectInput,
|
||||
Bailout_NonStringInput,
|
||||
Bailout_NonSymbolInput,
|
||||
#ifdef ENABLE_BIGINT
|
||||
Bailout_NonBigIntInput,
|
||||
#endif
|
||||
|
||||
// Atomic operations require shared memory, bail out if the typed array
|
||||
// maps unshared memory.
|
||||
|
@ -223,6 +226,10 @@ inline const char* BailoutKindString(BailoutKind kind) {
|
|||
return "Bailout_NonStringInput";
|
||||
case Bailout_NonSymbolInput:
|
||||
return "Bailout_NonSymbolInput";
|
||||
#ifdef ENABLE_BIGINT
|
||||
case Bailout_NonBigIntInput:
|
||||
return "Bailout_NonBigIntInput";
|
||||
#endif
|
||||
case Bailout_NonSharedTypedArrayInput:
|
||||
return "Bailout_NonSharedTypedArrayInput";
|
||||
case Bailout_Debugger:
|
||||
|
@ -441,6 +448,9 @@ enum class MIRType : uint8_t {
|
|||
// Types above have trivial conversion to a number.
|
||||
String,
|
||||
Symbol,
|
||||
#ifdef ENABLE_BIGINT
|
||||
BigInt,
|
||||
#endif
|
||||
// Types above are primitive (including undefined and null).
|
||||
Object,
|
||||
MagicOptimizedArguments, // JS_OPTIMIZED_ARGUMENTS magic value.
|
||||
|
@ -488,6 +498,10 @@ static inline MIRType MIRTypeFromValueType(JSValueType type) {
|
|||
return MIRType::String;
|
||||
case JSVAL_TYPE_SYMBOL:
|
||||
return MIRType::Symbol;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case JSVAL_TYPE_BIGINT:
|
||||
return MIRType::BigInt;
|
||||
#endif
|
||||
case JSVAL_TYPE_BOOLEAN:
|
||||
return MIRType::Boolean;
|
||||
case JSVAL_TYPE_NULL:
|
||||
|
@ -518,6 +532,10 @@ static inline JSValueType ValueTypeFromMIRType(MIRType type) {
|
|||
return JSVAL_TYPE_STRING;
|
||||
case MIRType::Symbol:
|
||||
return JSVAL_TYPE_SYMBOL;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
return JSVAL_TYPE_BIGINT;
|
||||
#endif
|
||||
case MIRType::MagicOptimizedArguments:
|
||||
case MIRType::MagicOptimizedOut:
|
||||
case MIRType::MagicHole:
|
||||
|
@ -571,6 +589,10 @@ static inline const char* StringFromMIRType(MIRType type) {
|
|||
return "String";
|
||||
case MIRType::Symbol:
|
||||
return "Symbol";
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
return "BigInt";
|
||||
#endif
|
||||
case MIRType::Object:
|
||||
return "Object";
|
||||
case MIRType::MagicOptimizedArguments:
|
||||
|
|
|
@ -525,6 +525,9 @@ class LDefinition {
|
|||
return LDefinition::INT32;
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
#endif
|
||||
case MIRType::Object:
|
||||
case MIRType::ObjectOrNull:
|
||||
return LDefinition::OBJECT;
|
||||
|
|
|
@ -590,6 +590,12 @@ void LIRGenerator::visitTest(MTest* test) {
|
|||
// TestPolicy).
|
||||
MOZ_ASSERT(opd->type() != MIRType::String);
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
// BigInt is boxed in type analysis.
|
||||
MOZ_ASSERT(opd->type() != MIRType::BigInt,
|
||||
"BigInt should be boxed by TestPolicy");
|
||||
#endif
|
||||
|
||||
// Testing a constant.
|
||||
if (MConstant* constant = opd->maybeConstantValue()) {
|
||||
bool b;
|
||||
|
@ -2090,10 +2096,13 @@ void LIRGenerator::visitToNumberInt32(MToNumberInt32* convert) {
|
|||
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
#endif
|
||||
case MIRType::Object:
|
||||
case MIRType::Undefined:
|
||||
// Objects might be effectful. Symbols throw. Undefined coerces to NaN,
|
||||
// not int32.
|
||||
// Objects might be effectful. Symbols and BigInts throw. Undefined
|
||||
// coerces to NaN, not int32.
|
||||
MOZ_CRASH("ToInt32 invalid input type");
|
||||
|
||||
default:
|
||||
|
@ -2876,6 +2885,10 @@ void LIRGenerator::visitNot(MNot* ins) {
|
|||
// String is converted to length of string in the type analysis phase (see
|
||||
// TestPolicy).
|
||||
MOZ_ASSERT(op->type() != MIRType::String);
|
||||
#ifdef ENABLE_BIGINT
|
||||
MOZ_ASSERT(op->type() != MIRType::BigInt,
|
||||
"BigInt should be boxed by TestPolicy");
|
||||
#endif
|
||||
|
||||
// - boolean: x xor 1
|
||||
// - int32: LCompare(x, 0)
|
||||
|
@ -4671,6 +4684,11 @@ void LIRGenerator::visitConstant(MConstant* ins) {
|
|||
case MIRType::Symbol:
|
||||
define(new (alloc()) LPointer(ins->toSymbol()), ins);
|
||||
break;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
define(new (alloc()) LPointer(ins->toBigInt()), ins);
|
||||
break;
|
||||
#endif
|
||||
case MIRType::Object:
|
||||
define(new (alloc()) LPointer(&ins->toObject()), ins);
|
||||
break;
|
||||
|
|
|
@ -2119,10 +2119,11 @@ IonBuilder::InliningResult IonBuilder::inlineStrFromCharCode(
|
|||
|
||||
MDefinition* codeUnit = callInfo.getArg(0);
|
||||
if (codeUnit->type() != MIRType::Int32) {
|
||||
// MTruncateToInt32 will always bail for objects and symbols, so don't
|
||||
// try to inline String.fromCharCode() for these two value types.
|
||||
// MTruncateToInt32 will always bail for objects, symbols and BigInts, so
|
||||
// don't try to inline String.fromCharCode() for these value types.
|
||||
if (codeUnit->mightBeType(MIRType::Object) ||
|
||||
codeUnit->mightBeType(MIRType::Symbol)) {
|
||||
codeUnit->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(codeUnit->mightBeType(MIRType::BigInt), false)) {
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
|
||||
|
@ -3537,6 +3538,7 @@ IonBuilder::InliningResult IonBuilder::inlineToInteger(CallInfo& callInfo) {
|
|||
if (input->mightBeType(MIRType::Object) ||
|
||||
input->mightBeType(MIRType::String) ||
|
||||
input->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(input->mightBeType(MIRType::BigInt), false) ||
|
||||
input->mightBeType(MIRType::Undefined) || input->mightBeMagicType()) {
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
|
@ -3661,13 +3663,15 @@ IonBuilder::InliningResult IonBuilder::inlineAtomicsCompareExchange(
|
|||
// https://bugzilla.mozilla.org/show_bug.cgi?id=1141986#c20.
|
||||
MDefinition* oldval = callInfo.getArg(2);
|
||||
if (oldval->mightBeType(MIRType::Object) ||
|
||||
oldval->mightBeType(MIRType::Symbol)) {
|
||||
oldval->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(oldval->mightBeType(MIRType::BigInt), false)) {
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
|
||||
MDefinition* newval = callInfo.getArg(3);
|
||||
if (newval->mightBeType(MIRType::Object) ||
|
||||
newval->mightBeType(MIRType::Symbol)) {
|
||||
newval->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(newval->mightBeType(MIRType::BigInt), false)) {
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
|
||||
|
@ -3707,7 +3711,8 @@ IonBuilder::InliningResult IonBuilder::inlineAtomicsExchange(
|
|||
|
||||
MDefinition* value = callInfo.getArg(2);
|
||||
if (value->mightBeType(MIRType::Object) ||
|
||||
value->mightBeType(MIRType::Symbol)) {
|
||||
value->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(value->mightBeType(MIRType::BigInt), false)) {
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
|
||||
|
@ -3792,7 +3797,8 @@ IonBuilder::InliningResult IonBuilder::inlineAtomicsStore(CallInfo& callInfo) {
|
|||
}
|
||||
|
||||
if (value->mightBeType(MIRType::Object) ||
|
||||
value->mightBeType(MIRType::Symbol)) {
|
||||
value->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(value->mightBeType(MIRType::BigInt), false)) {
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
|
||||
|
@ -3837,7 +3843,8 @@ IonBuilder::InliningResult IonBuilder::inlineAtomicsBinop(
|
|||
|
||||
MDefinition* value = callInfo.getArg(2);
|
||||
if (value->mightBeType(MIRType::Object) ||
|
||||
value->mightBeType(MIRType::Symbol)) {
|
||||
value->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(value->mightBeType(MIRType::BigInt), false)) {
|
||||
return InliningStatus_NotInlined;
|
||||
}
|
||||
|
||||
|
|
|
@ -966,6 +966,11 @@ MConstant::MConstant(TempAllocator& alloc, const js::Value& vp,
|
|||
case MIRType::Symbol:
|
||||
payload_.sym = vp.toSymbol();
|
||||
break;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
payload_.bi = vp.toBigInt();
|
||||
break;
|
||||
#endif
|
||||
case MIRType::Object:
|
||||
payload_.obj = &vp.toObject();
|
||||
// Create a singleton type set for the object. This isn't necessary for
|
||||
|
@ -1043,6 +1048,9 @@ void MConstant::assertInitializedPayload() const {
|
|||
case MIRType::String:
|
||||
case MIRType::Object:
|
||||
case MIRType::Symbol:
|
||||
# ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
# endif
|
||||
# if MOZ_LITTLE_ENDIAN
|
||||
MOZ_ASSERT_IF(JS_BITS_PER_WORD == 32, (payload_.asBits >> 32) == 0);
|
||||
# else
|
||||
|
@ -1134,6 +1142,11 @@ void MConstant::printOpcode(GenericPrinter& out) const {
|
|||
case MIRType::Symbol:
|
||||
out.printf("symbol at %p", (void*)toSymbol());
|
||||
break;
|
||||
# ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
out.printf("BigInt at %p", (void*)toBigInt());
|
||||
break;
|
||||
# endif
|
||||
case MIRType::String:
|
||||
out.printf("string %p", (void*)toString());
|
||||
break;
|
||||
|
@ -1195,6 +1208,10 @@ Value MConstant::toJSValue() const {
|
|||
return StringValue(toString());
|
||||
case MIRType::Symbol:
|
||||
return SymbolValue(toSymbol());
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
return BigIntValue(toBigInt());
|
||||
#endif
|
||||
case MIRType::Object:
|
||||
return ObjectValue(toObject());
|
||||
case MIRType::MagicOptimizedArguments:
|
||||
|
@ -1236,6 +1253,11 @@ bool MConstant::valueToBoolean(bool* res) const {
|
|||
case MIRType::Symbol:
|
||||
*res = true;
|
||||
return true;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
*res = !toBigInt()->isZero();
|
||||
return true;
|
||||
#endif
|
||||
case MIRType::String:
|
||||
*res = toString()->length() != 0;
|
||||
return true;
|
||||
|
@ -1777,6 +1799,11 @@ void MUnbox::printOpcode(GenericPrinter& out) const {
|
|||
case MIRType::Symbol:
|
||||
out.printf("to Symbol");
|
||||
break;
|
||||
# ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
out.printf("to BigInt");
|
||||
break;
|
||||
# endif
|
||||
case MIRType::Object:
|
||||
out.printf("to Object");
|
||||
break;
|
||||
|
@ -2255,6 +2282,9 @@ bool jit::TypeSetIncludes(TypeSet* types, MIRType input, TypeSet* inputTypes) {
|
|||
case MIRType::Float32:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
#endif
|
||||
case MIRType::MagicOptimizedArguments:
|
||||
return types->hasType(
|
||||
TypeSet::PrimitiveType(ValueTypeFromMIRType(input)));
|
||||
|
@ -2515,8 +2545,10 @@ MDefinition* MBinaryBitwiseInstruction::foldUnnecessaryBitop() {
|
|||
void MBinaryBitwiseInstruction::infer(BaselineInspector*, jsbytecode*) {
|
||||
if (getOperand(0)->mightBeType(MIRType::Object) ||
|
||||
getOperand(0)->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(getOperand(0)->mightBeType(MIRType::BigInt), false) ||
|
||||
getOperand(1)->mightBeType(MIRType::Object) ||
|
||||
getOperand(1)->mightBeType(MIRType::Symbol)) {
|
||||
getOperand(1)->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(getOperand(1)->mightBeType(MIRType::BigInt), false)) {
|
||||
specialization_ = MIRType::None;
|
||||
setResultType(MIRType::Value);
|
||||
} else {
|
||||
|
@ -2540,7 +2572,9 @@ void MShiftInstruction::infer(BaselineInspector*, jsbytecode*) {
|
|||
if (getOperand(0)->mightBeType(MIRType::Object) ||
|
||||
getOperand(1)->mightBeType(MIRType::Object) ||
|
||||
getOperand(0)->mightBeType(MIRType::Symbol) ||
|
||||
getOperand(1)->mightBeType(MIRType::Symbol)) {
|
||||
getOperand(1)->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(getOperand(0)->mightBeType(MIRType::BigInt), false) ||
|
||||
IF_BIGINT(getOperand(1)->mightBeType(MIRType::BigInt), false)) {
|
||||
specialization_ = MIRType::None;
|
||||
setResultType(MIRType::Value);
|
||||
} else {
|
||||
|
@ -2553,7 +2587,9 @@ void MUrsh::infer(BaselineInspector* inspector, jsbytecode* pc) {
|
|||
if (getOperand(0)->mightBeType(MIRType::Object) ||
|
||||
getOperand(1)->mightBeType(MIRType::Object) ||
|
||||
getOperand(0)->mightBeType(MIRType::Symbol) ||
|
||||
getOperand(1)->mightBeType(MIRType::Symbol)) {
|
||||
getOperand(1)->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(getOperand(0)->mightBeType(MIRType::BigInt), false) ||
|
||||
IF_BIGINT(getOperand(1)->mightBeType(MIRType::BigInt), false)) {
|
||||
specialization_ = MIRType::None;
|
||||
setResultType(MIRType::Value);
|
||||
return;
|
||||
|
@ -3501,7 +3537,7 @@ MCompare::CompareType MCompare::determineCompareType(JSOp op, MDefinition* left,
|
|||
return Compare_String;
|
||||
}
|
||||
|
||||
// Handle symbol comparisons. (Relaational compare will throw)
|
||||
// Handle symbol comparisons. (Relational compare will throw)
|
||||
if (!relationalEq && lhs == MIRType::Symbol && rhs == MIRType::Symbol) {
|
||||
return Compare_Symbol;
|
||||
}
|
||||
|
@ -3594,6 +3630,11 @@ MDefinition* MTypeOf::foldsTo(TempAllocator& alloc) {
|
|||
case MIRType::Symbol:
|
||||
type = JSTYPE_SYMBOL;
|
||||
break;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
type = JSTYPE_BIGINT;
|
||||
break;
|
||||
#endif
|
||||
case MIRType::Null:
|
||||
type = JSTYPE_OBJECT;
|
||||
break;
|
||||
|
@ -4196,7 +4237,16 @@ bool MCompare::tryFoldTypeOf(bool* result) {
|
|||
*result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE);
|
||||
return true;
|
||||
}
|
||||
} else if (constant->toString() == TypeName(JSTYPE_OBJECT, names)) {
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
else if (constant->toString() == TypeName(JSTYPE_BIGINT, names)) {
|
||||
if (!typeOf->input()->mightBeType(MIRType::BigInt)) {
|
||||
*result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
else if (constant->toString() == TypeName(JSTYPE_OBJECT, names)) {
|
||||
if (!typeOf->input()->mightBeType(MIRType::Object) &&
|
||||
!typeOf->input()->mightBeType(MIRType::Null)) {
|
||||
*result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE);
|
||||
|
@ -5443,6 +5493,10 @@ bool MConstant::appendRoots(MRootList& roots) const {
|
|||
return roots.append(toString());
|
||||
case MIRType::Symbol:
|
||||
return roots.append(toSymbol());
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
return roots.append(toBigInt());
|
||||
#endif
|
||||
case MIRType::Object:
|
||||
return roots.append(&toObject());
|
||||
case MIRType::Undefined:
|
||||
|
|
|
@ -892,6 +892,7 @@ static inline bool SimpleArithOperand(MDefinition* op) {
|
|||
return !op->emptyResultTypeSet() && !op->mightBeType(MIRType::Object) &&
|
||||
!op->mightBeType(MIRType::String) &&
|
||||
!op->mightBeType(MIRType::Symbol) &&
|
||||
IF_BIGINT(!op->mightBeType(MIRType::BigInt), true) &&
|
||||
!op->mightBeType(MIRType::MagicOptimizedArguments) &&
|
||||
!op->mightBeType(MIRType::MagicHole) &&
|
||||
!op->mightBeType(MIRType::MagicIsConstructing);
|
||||
|
@ -1391,6 +1392,9 @@ class MConstant : public MNullaryInstruction {
|
|||
double d;
|
||||
JSString* str;
|
||||
JS::Symbol* sym;
|
||||
#ifdef ENABLE_BIGINT
|
||||
BigInt* bi;
|
||||
#endif
|
||||
JSObject* obj;
|
||||
uint64_t asBits;
|
||||
};
|
||||
|
@ -1508,6 +1512,12 @@ class MConstant : public MNullaryInstruction {
|
|||
MOZ_ASSERT(type() == MIRType::Symbol);
|
||||
return payload_.sym;
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
BigInt* toBigInt() const {
|
||||
MOZ_ASSERT(type() == MIRType::BigInt);
|
||||
return payload_.bi;
|
||||
}
|
||||
#endif
|
||||
JSObject& toObject() const {
|
||||
MOZ_ASSERT(type() == MIRType::Object);
|
||||
return *payload_.obj;
|
||||
|
@ -3306,7 +3316,9 @@ class MUnbox final : public MUnaryInstruction, public BoxInputsPolicy::Data {
|
|||
|
||||
MOZ_ASSERT(type == MIRType::Boolean || type == MIRType::Int32 ||
|
||||
type == MIRType::Double || type == MIRType::String ||
|
||||
type == MIRType::Symbol || type == MIRType::Object);
|
||||
type == MIRType::Symbol ||
|
||||
IF_BIGINT(type == MIRType::BigInt, false) ||
|
||||
type == MIRType::Object);
|
||||
|
||||
TemporaryTypeSet* resultSet = ins->resultTypeSet();
|
||||
if (resultSet && type == MIRType::Object) {
|
||||
|
@ -3347,6 +3359,11 @@ class MUnbox final : public MUnaryInstruction, public BoxInputsPolicy::Data {
|
|||
case MIRType::Symbol:
|
||||
kind = Bailout_NonSymbolInput;
|
||||
break;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
kind = Bailout_NonBigIntInput;
|
||||
break;
|
||||
#endif
|
||||
case MIRType::Object:
|
||||
kind = Bailout_NonObjectInput;
|
||||
break;
|
||||
|
@ -3660,9 +3677,10 @@ class MToDouble : public MToFPInstruction {
|
|||
setMovable();
|
||||
|
||||
// An object might have "valueOf", which means it is effectful.
|
||||
// ToNumber(symbol) throws.
|
||||
// ToNumber(symbol) and ToNumber(bigint) throw.
|
||||
if (def->mightBeType(MIRType::Object) ||
|
||||
def->mightBeType(MIRType::Symbol)) {
|
||||
def->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(def->mightBeType(MIRType::BigInt), false)) {
|
||||
setGuard();
|
||||
}
|
||||
}
|
||||
|
@ -3703,6 +3721,11 @@ class MToDouble : public MToFPInstruction {
|
|||
if (input()->type() == MIRType::Symbol) {
|
||||
return false;
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
if (input()->type() == MIRType::BigInt) {
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -3724,9 +3747,10 @@ class MToFloat32 : public MToFPInstruction {
|
|||
setMovable();
|
||||
|
||||
// An object might have "valueOf", which means it is effectful.
|
||||
// ToNumber(symbol) throws.
|
||||
// ToNumber(symbol) and ToNumber(BigInt) throw.
|
||||
if (def->mightBeType(MIRType::Object) ||
|
||||
def->mightBeType(MIRType::Symbol)) {
|
||||
def->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(def->mightBeType(MIRType::BigInt), false)) {
|
||||
setGuard();
|
||||
}
|
||||
}
|
||||
|
@ -3982,9 +4006,10 @@ class MToNumberInt32 : public MUnaryInstruction, public ToInt32Policy::Data {
|
|||
setMovable();
|
||||
|
||||
// An object might have "valueOf", which means it is effectful.
|
||||
// ToNumber(symbol) throws.
|
||||
// ToNumber(symbol) and ToNumber(BigInt) throw.
|
||||
if (def->mightBeType(MIRType::Object) ||
|
||||
def->mightBeType(MIRType::Symbol)) {
|
||||
def->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(def->mightBeType(MIRType::BigInt), false)) {
|
||||
setGuard();
|
||||
}
|
||||
}
|
||||
|
@ -4037,9 +4062,10 @@ class MTruncateToInt32 : public MUnaryInstruction, public ToInt32Policy::Data {
|
|||
setMovable();
|
||||
|
||||
// An object might have "valueOf", which means it is effectful.
|
||||
// ToInt32(symbol) throws.
|
||||
// ToInt32(symbol) and ToInt32(BigInt) throw.
|
||||
if (def->mightBeType(MIRType::Object) ||
|
||||
def->mightBeType(MIRType::Symbol)) {
|
||||
def->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(def->mightBeType(MIRType::BigInt), false)) {
|
||||
setGuard();
|
||||
}
|
||||
}
|
||||
|
@ -4078,10 +4104,11 @@ class MToString : public MUnaryInstruction, public ToStringPolicy::Data {
|
|||
setResultType(MIRType::String);
|
||||
setMovable();
|
||||
|
||||
// Objects might override toString and Symbols throw. We bailout in
|
||||
// Objects might override toString; Symbol and BigInts throw. We bailout in
|
||||
// those cases and run side-effects in baseline instead.
|
||||
if (def->mightBeType(MIRType::Object) ||
|
||||
def->mightBeType(MIRType::Symbol)) {
|
||||
def->mightBeType(MIRType::Symbol) ||
|
||||
IF_BIGINT(def->mightBeType(MIRType::BigInt), false)) {
|
||||
setGuard();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3369,6 +3369,11 @@ void MacroAssembler::maybeBranchTestType(MIRType type, MDefinition* maybeDef,
|
|||
case MIRType::Symbol:
|
||||
branchTestSymbol(Equal, tag, label);
|
||||
break;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
branchTestBigInt(Equal, tag, label);
|
||||
break;
|
||||
#endif
|
||||
case MIRType::Object:
|
||||
branchTestObject(Equal, tag, label);
|
||||
break;
|
||||
|
|
|
@ -1558,6 +1558,11 @@ class MacroAssembler : public MacroAssemblerSpecific {
|
|||
inline void branchTestStringTruthy(bool truthy, const ValueOperand& value,
|
||||
Label* label)
|
||||
DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
|
||||
#ifdef ENABLE_BIGINT
|
||||
inline void branchTestBigIntTruthy(bool truthy, const ValueOperand& value,
|
||||
Label* label)
|
||||
DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
|
||||
#endif
|
||||
|
||||
// Create an unconditional branch to the address given as argument.
|
||||
inline void branchToComputedAddress(const BaseIndex& address) PER_ARCH;
|
||||
|
|
|
@ -343,6 +343,10 @@ static const char* ValTypeToString(JSValueType type) {
|
|||
return "string";
|
||||
case JSVAL_TYPE_SYMBOL:
|
||||
return "symbol";
|
||||
#ifdef ENABLE_BIGINT
|
||||
case JSVAL_TYPE_BIGINT:
|
||||
return "BigInt";
|
||||
#endif
|
||||
case JSVAL_TYPE_BOOLEAN:
|
||||
return "boolean";
|
||||
case JSVAL_TYPE_OBJECT:
|
||||
|
|
|
@ -775,7 +775,10 @@ bool ToDoublePolicy::staticAdjustInputs(TempAllocator& alloc,
|
|||
case MIRType::Object:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
// Objects might be effectful. Symbols give TypeError.
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
#endif
|
||||
// Objects might be effectful. Symbols and BigInts give TypeError.
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -827,7 +830,10 @@ bool ToInt32Policy::staticAdjustInputs(TempAllocator& alloc,
|
|||
case MIRType::Object:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
// Objects might be effectful. Symbols give TypeError.
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
#endif
|
||||
// Objects might be effectful. Symbols and BigInts give TypeError.
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -843,7 +849,8 @@ bool ToStringPolicy::staticAdjustInputs(TempAllocator& alloc,
|
|||
MOZ_ASSERT(ins->isToString());
|
||||
|
||||
MIRType type = ins->getOperand(0)->type();
|
||||
if (type == MIRType::Object || type == MIRType::Symbol) {
|
||||
if (type == MIRType::Object || type == MIRType::Symbol ||
|
||||
IF_BIGINT(type == MIRType::BigInt, false)) {
|
||||
ins->replaceOperand(0, BoxAt(alloc, ins, ins->getOperand(0)));
|
||||
return true;
|
||||
}
|
||||
|
@ -962,6 +969,9 @@ bool StoreUnboxedScalarPolicy::adjustValueInput(TempAllocator& alloc,
|
|||
case MIRType::Object:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
#endif
|
||||
value = BoxAt(alloc, ins, value);
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -1263,6 +1263,17 @@ void AssertValidSymbolPtr(JSContext* cx, JS::Symbol* sym) {
|
|||
MOZ_ASSERT(sym->getAllocKind() == gc::AllocKind::SYMBOL);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
void AssertValidBigIntPtr(JSContext* cx, JS::BigInt* bi) {
|
||||
AutoUnsafeCallWithABI unsafe;
|
||||
// FIXME: check runtime?
|
||||
MOZ_ASSERT(cx->zone() == bi->zone());
|
||||
MOZ_ASSERT(bi->isAligned());
|
||||
MOZ_ASSERT(bi->isTenured());
|
||||
MOZ_ASSERT(bi->getAllocKind() == gc::AllocKind::BIGINT);
|
||||
}
|
||||
#endif
|
||||
|
||||
void AssertValidValue(JSContext* cx, Value* v) {
|
||||
AutoUnsafeCallWithABI unsafe;
|
||||
if (v->isObject()) {
|
||||
|
@ -1272,6 +1283,11 @@ void AssertValidValue(JSContext* cx, Value* v) {
|
|||
} else if (v->isSymbol()) {
|
||||
AssertValidSymbolPtr(cx, v->toSymbol());
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
else if (v->isBigInt()) {
|
||||
AssertValidBigIntPtr(cx, v->toBigInt());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool ObjectIsCallable(JSObject* obj) {
|
||||
|
|
|
@ -1092,6 +1092,9 @@ void AssertValidObjectPtr(JSContext* cx, JSObject* obj);
|
|||
void AssertValidObjectOrNullPtr(JSContext* cx, JSObject* obj);
|
||||
void AssertValidStringPtr(JSContext* cx, JSString* str);
|
||||
void AssertValidSymbolPtr(JSContext* cx, JS::Symbol* sym);
|
||||
#ifdef ENABLE_BIGINT
|
||||
void AssertValidBigIntPtr(JSContext* cx, JS::BigInt* bi);
|
||||
#endif
|
||||
void AssertValidValue(JSContext* cx, Value* v);
|
||||
|
||||
void MarkValueFromJit(JSRuntime* rt, Value* vp);
|
||||
|
|
|
@ -1723,6 +1723,13 @@ void MacroAssembler::branchTestBigIntImpl(Condition cond, const T& t,
|
|||
Condition c = testBigInt(cond, t);
|
||||
ma_b(label, c);
|
||||
}
|
||||
|
||||
void MacroAssembler::branchTestBigIntTruthy(bool truthy,
|
||||
const ValueOperand& value,
|
||||
Label* label) {
|
||||
Condition c = testBigIntTruthy(truthy, value);
|
||||
ma_b(label, c);
|
||||
}
|
||||
#endif
|
||||
|
||||
void MacroAssembler::branchTestNull(Condition cond, Register tag,
|
||||
|
|
|
@ -3441,6 +3441,20 @@ Assembler::Condition MacroAssemblerARMCompat::testStringTruthy(
|
|||
return truthy ? Assembler::NotEqual : Assembler::Equal;
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
Assembler::Condition MacroAssemblerARMCompat::testBigIntTruthy(
|
||||
bool truthy, const ValueOperand& value) {
|
||||
Register bi = value.payloadReg();
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
SecondScratchRegisterScope scratch2(asMasm());
|
||||
|
||||
ma_dtr(IsLoad, bi, Imm32(BigInt::offsetOfLengthSignAndReservedBits()),
|
||||
scratch, scratch2);
|
||||
as_cmp(scratch, Imm8(0));
|
||||
return truthy ? Assembler::NotEqual : Assembler::Equal;
|
||||
}
|
||||
#endif
|
||||
|
||||
void MacroAssemblerARMCompat::floor(FloatRegister input, Register output,
|
||||
Label* bail) {
|
||||
Label handleZero;
|
||||
|
|
|
@ -849,6 +849,14 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM {
|
|||
void unboxSymbol(const Address& src, Register dest) {
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_SYMBOL);
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
void unboxBigInt(const ValueOperand& src, Register dest) {
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
|
||||
}
|
||||
void unboxBigInt(const Address& src, Register dest) {
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
|
||||
}
|
||||
#endif
|
||||
void unboxObject(const ValueOperand& src, Register dest) {
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_OBJECT);
|
||||
}
|
||||
|
@ -917,6 +925,9 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM {
|
|||
Condition testBooleanTruthy(bool truthy, const ValueOperand& operand);
|
||||
Condition testDoubleTruthy(bool truthy, FloatRegister reg);
|
||||
Condition testStringTruthy(bool truthy, const ValueOperand& value);
|
||||
#ifdef ENABLE_BIGINT
|
||||
Condition testBigIntTruthy(bool truthy, const ValueOperand& value);
|
||||
#endif
|
||||
|
||||
void boolValueToFloat32(const ValueOperand& operand, FloatRegister dest);
|
||||
void int32ValueToFloat32(const ValueOperand& operand, FloatRegister dest);
|
||||
|
|
|
@ -1252,6 +1252,11 @@ void CodeGenerator::visitUnbox(LUnbox* unbox) {
|
|||
case MIRType::Symbol:
|
||||
cond = masm.testSymbol(Assembler::NotEqual, value);
|
||||
break;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
cond = masm.testBigInt(Assembler::NotEqual, value);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
MOZ_CRASH("Given MIRType cannot be unboxed.");
|
||||
}
|
||||
|
@ -1289,6 +1294,11 @@ void CodeGenerator::visitUnbox(LUnbox* unbox) {
|
|||
case MIRType::Symbol:
|
||||
masm.unboxSymbol(input, result);
|
||||
break;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
masm.unboxBigInt(input, result);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
MOZ_CRASH("Given MIRType cannot be unboxed.");
|
||||
}
|
||||
|
|
|
@ -1432,6 +1432,13 @@ void MacroAssembler::branchTestBigIntImpl(Condition cond, const T& t,
|
|||
Condition c = testBigInt(cond, t);
|
||||
B(label, c);
|
||||
}
|
||||
|
||||
void MacroAssembler::branchTestBigIntTruthy(bool truthy,
|
||||
const ValueOperand& value,
|
||||
Label* label) {
|
||||
Condition c = testBigIntTruthy(truthy, value);
|
||||
B(label, c);
|
||||
}
|
||||
#endif
|
||||
|
||||
void MacroAssembler::branchTestNull(Condition cond, Register tag,
|
||||
|
|
|
@ -1394,6 +1394,14 @@ class MacroAssemblerCompat : public vixl::MacroAssembler {
|
|||
void unboxSymbol(const Address& src, Register dest) {
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_SYMBOL);
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
void unboxBigInt(const ValueOperand& operand, Register dest) {
|
||||
unboxNonDouble(operand, dest, JSVAL_TYPE_BIGINT);
|
||||
}
|
||||
void unboxBigInt(const Address& src, Register dest) {
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
|
||||
}
|
||||
#endif
|
||||
// These two functions use the low 32-bits of the full value register.
|
||||
void boolValueToDouble(const ValueOperand& operand, FloatRegister dest) {
|
||||
convertInt32ToDouble(operand.valueReg(), dest);
|
||||
|
@ -1755,6 +1763,19 @@ class MacroAssemblerCompat : public vixl::MacroAssembler {
|
|||
splitSignExtTag(src, scratch);
|
||||
return testBigInt(cond, scratch);
|
||||
}
|
||||
Condition testBigIntTruthy(bool truthy, const ValueOperand& value) {
|
||||
vixl::UseScratchRegisterScope temps(this);
|
||||
const Register scratch = temps.AcquireX().asUnsized();
|
||||
const ARMRegister scratch64(scratch, 64);
|
||||
|
||||
MOZ_ASSERT(value.valueReg() != scratch);
|
||||
|
||||
unboxBigInt(value, scratch);
|
||||
Ldr(scratch64,
|
||||
MemOperand(scratch64, BigInt::offsetOfLengthSignAndReservedBits()));
|
||||
Cmp(scratch64, Operand(0));
|
||||
return truthy ? Condition::NonZero : Condition::Zero;
|
||||
}
|
||||
#endif
|
||||
Condition testInt32(Condition cond, const BaseIndex& src) {
|
||||
vixl::UseScratchRegisterScope temps(this);
|
||||
|
|
|
@ -819,6 +819,14 @@ void MacroAssembler::branchTestBigInt(Condition cond, const ValueOperand& value,
|
|||
Label* label) {
|
||||
branchTestBigInt(cond, value.typeReg(), label);
|
||||
}
|
||||
|
||||
void MacroAssembler::branchTestBigIntTruthy(bool b, const ValueOperand& value,
|
||||
Label* label) {
|
||||
Register bi = value.payloadReg();
|
||||
SecondScratchRegisterScope scratch2(*this);
|
||||
ma_lw(scratch2, Address(bi, BigInt::offsetOfLengthSignAndReservedBits()));
|
||||
ma_b(scratch2, Imm32(0), label, b ? NotEqual : Equal);
|
||||
}
|
||||
#endif
|
||||
|
||||
void MacroAssembler::branchTestNull(Condition cond, const ValueOperand& value,
|
||||
|
|
|
@ -78,6 +78,10 @@ void CodeGenerator::visitUnbox(LUnbox* unbox) {
|
|||
case MIRType::Symbol:
|
||||
masm.unboxSymbol(inputReg, result);
|
||||
break;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
masm.unboxBigInt(inputReg, result);
|
||||
#endif
|
||||
default:
|
||||
MOZ_CRASH("Given MIRType cannot be unboxed.");
|
||||
}
|
||||
|
@ -101,6 +105,10 @@ void CodeGenerator::visitUnbox(LUnbox* unbox) {
|
|||
case MIRType::Symbol:
|
||||
masm.unboxSymbol(inputAddr, result);
|
||||
break;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
masm.unboxBigInt(inputAddr, result);
|
||||
#endif
|
||||
default:
|
||||
MOZ_CRASH("Given MIRType cannot be unboxed.");
|
||||
}
|
||||
|
|
|
@ -553,6 +553,15 @@ void MacroAssembler::branchTestBigInt(Condition cond, const ValueOperand& value,
|
|||
splitTag(value, scratch2);
|
||||
branchTestBigInt(cond, scratch2, label);
|
||||
}
|
||||
|
||||
void MacroAssembler::branchTestBigIntTruthy(bool b, const ValueOperand& value,
|
||||
Label* label) {
|
||||
SecondScratchRegisterScope scratch2(*this);
|
||||
unboxBigInt(value, scratch2);
|
||||
loadPtr(Address(scratch2, BigInt::offsetOfLengthSignAndReservedBits()),
|
||||
scratch2);
|
||||
ma_b(scratch2, ImmWord(0), label, b ? NotEqual : Equal);
|
||||
}
|
||||
#endif
|
||||
|
||||
void MacroAssembler::branchTestNull(Condition cond, const ValueOperand& value,
|
||||
|
|
|
@ -1266,6 +1266,22 @@ void MacroAssemblerMIPS64Compat::unboxSymbol(const Address& src,
|
|||
unboxNonDouble(src, dest, JSVAL_TYPE_SYMBOL);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_BIGINT
|
||||
void MacroAssemblerMIPS64Compat::unboxBigInt(const ValueOperand& operand,
|
||||
Register dest) {
|
||||
unboxNonDouble(operand, dest, JSVAL_TYPE_BIGINT);
|
||||
}
|
||||
|
||||
void MacroAssemblerMIPS64Compat::unboxBigInt(Register src, Register dest) {
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
|
||||
}
|
||||
|
||||
void MacroAssemblerMIPS64Compat::unboxBigInt(const Address& src,
|
||||
Register dest) {
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
|
||||
}
|
||||
#endif
|
||||
|
||||
void MacroAssemblerMIPS64Compat::unboxObject(const ValueOperand& src,
|
||||
Register dest) {
|
||||
unboxNonDouble(src, dest, JSVAL_TYPE_OBJECT);
|
||||
|
|
|
@ -398,6 +398,11 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 {
|
|||
void unboxSymbol(const ValueOperand& src, Register dest);
|
||||
void unboxSymbol(Register src, Register dest);
|
||||
void unboxSymbol(const Address& src, Register dest);
|
||||
#ifdef ENABLE_BIGINT
|
||||
void unboxBigInt(const ValueOperand& operand, Register dest);
|
||||
void unboxBigInt(Register src, Register dest);
|
||||
void unboxBigInt(const Address& src, Register dest);
|
||||
#endif
|
||||
void unboxObject(const ValueOperand& src, Register dest);
|
||||
void unboxObject(Register src, Register dest);
|
||||
void unboxObject(const Address& src, Register dest);
|
||||
|
|
|
@ -463,6 +463,12 @@ class MacroAssemblerNone : public Assembler {
|
|||
void unboxSymbol(T, Register) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
template <typename T>
|
||||
void unboxBigInt(T, Register) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
#endif
|
||||
template <typename T>
|
||||
void unboxObject(T, Register) {
|
||||
MOZ_CRASH();
|
||||
|
@ -522,6 +528,9 @@ class MacroAssemblerNone : public Assembler {
|
|||
void loadConstantFloat32(float, FloatRegister) { MOZ_CRASH(); }
|
||||
Condition testInt32Truthy(bool, ValueOperand) { MOZ_CRASH(); }
|
||||
Condition testStringTruthy(bool, ValueOperand) { MOZ_CRASH(); }
|
||||
#ifdef ENABLE_BIGINT
|
||||
Condition testBigIntTruthy(bool, ValueOperand) { MOZ_CRASH(); }
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
void loadUnboxedValue(T, MIRType, AnyRegister) {
|
||||
|
|
|
@ -434,6 +434,9 @@ void CodeGeneratorShared::encodeAllocation(LSnapshot* snapshot,
|
|||
case MIRType::Int32:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
#endif
|
||||
case MIRType::Object:
|
||||
case MIRType::ObjectOrNull:
|
||||
case MIRType::Boolean:
|
||||
|
|
|
@ -429,7 +429,11 @@ void LIRGeneratorShared::redefine(MDefinition* def, MDefinition* as) {
|
|||
case MIRType::Object:
|
||||
case MIRType::ObjectOrNull:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol: {
|
||||
case MIRType::Symbol:
|
||||
# ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
# endif
|
||||
{
|
||||
LAssertResultT* check =
|
||||
new (alloc()) LAssertResultT(useRegister(def));
|
||||
add(check, def->toInstruction());
|
||||
|
|
|
@ -85,6 +85,11 @@ void CodeGenerator::visitUnbox(LUnbox* unbox) {
|
|||
case MIRType::Symbol:
|
||||
cond = masm.testSymbol(Assembler::NotEqual, value);
|
||||
break;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
cond = masm.testBigInt(Assembler::NotEqual, value);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
MOZ_CRASH("Given MIRType cannot be unboxed.");
|
||||
}
|
||||
|
@ -119,6 +124,11 @@ void CodeGenerator::visitUnbox(LUnbox* unbox) {
|
|||
case MIRType::Symbol:
|
||||
masm.unboxSymbol(input, result);
|
||||
break;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case MIRType::BigInt:
|
||||
masm.unboxBigInt(input, result);
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
MOZ_CRASH("Given MIRType cannot be unboxed.");
|
||||
}
|
||||
|
|
|
@ -957,6 +957,15 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared {
|
|||
cmp32(Operand(scratch, JSString::offsetOfLength()), Imm32(0));
|
||||
return truthy ? Assembler::NotEqual : Assembler::Equal;
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
Condition testBigIntTruthy(bool truthy, const ValueOperand& value) {
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
unboxBigInt(value, scratch);
|
||||
cmpPtr(Operand(scratch, BigInt::offsetOfLengthSignAndReservedBits()),
|
||||
ImmWord(0));
|
||||
return truthy ? Assembler::NotEqual : Assembler::Equal;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline void loadInt32OrDouble(const T& src, FloatRegister dest);
|
||||
|
|
|
@ -823,6 +823,13 @@ void MacroAssembler::branchTestBigIntImpl(Condition cond, const T& t,
|
|||
cond = testBigInt(cond, t);
|
||||
j(cond, label);
|
||||
}
|
||||
|
||||
void MacroAssembler::branchTestBigIntTruthy(bool truthy,
|
||||
const ValueOperand& value,
|
||||
Label* label) {
|
||||
Condition cond = testBigIntTruthy(truthy, value);
|
||||
j(cond, label);
|
||||
}
|
||||
#endif
|
||||
|
||||
void MacroAssembler::branchTestNull(Condition cond, Register tag,
|
||||
|
|
|
@ -890,6 +890,14 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared {
|
|||
cmp32(Operand(string, JSString::offsetOfLength()), Imm32(0));
|
||||
return truthy ? Assembler::NotEqual : Assembler::Equal;
|
||||
}
|
||||
#ifdef ENABLE_BIGINT
|
||||
Condition testBigIntTruthy(bool truthy, const ValueOperand& value) {
|
||||
Register bi = value.payloadReg();
|
||||
cmpPtr(Operand(bi, BigInt::offsetOfLengthSignAndReservedBits()),
|
||||
ImmWord(0));
|
||||
return truthy ? Assembler::NotEqual : Assembler::Equal;
|
||||
}
|
||||
#endif
|
||||
|
||||
template <typename T>
|
||||
inline void loadInt32OrDouble(const T& src, FloatRegister dest);
|
||||
|
|
|
@ -78,6 +78,11 @@ class BigInt final : public js::gc::TenuredCell {
|
|||
bool isZero() const { return digitLength() == 0; }
|
||||
bool isNegative() const { return lengthSignAndReservedBits_ & SignBit; }
|
||||
|
||||
// Offset for direct access from JIT code.
|
||||
static constexpr size_t offsetOfLengthSignAndReservedBits() {
|
||||
return offsetof(BigInt, lengthSignAndReservedBits_);
|
||||
}
|
||||
|
||||
void initializeDigitsToZero();
|
||||
|
||||
void traceChildren(JSTracer* trc);
|
||||
|
|
|
@ -391,6 +391,10 @@ bool TypeSet::mightBeMIRType(jit::MIRType type) const {
|
|||
return baseFlags() & TYPE_FLAG_STRING;
|
||||
case jit::MIRType::Symbol:
|
||||
return baseFlags() & TYPE_FLAG_SYMBOL;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case jit::MIRType::BigInt:
|
||||
return baseFlags() & TYPE_FLAG_BIGINT;
|
||||
#endif
|
||||
case jit::MIRType::MagicOptimizedArguments:
|
||||
return baseFlags() & TYPE_FLAG_LAZYARGS;
|
||||
case jit::MIRType::MagicHole:
|
||||
|
@ -1709,6 +1713,10 @@ static inline jit::MIRType GetMIRTypeFromTypeFlags(TypeFlags flags) {
|
|||
return jit::MIRType::String;
|
||||
case TYPE_FLAG_SYMBOL:
|
||||
return jit::MIRType::Symbol;
|
||||
#ifdef ENABLE_BIGINT
|
||||
case TYPE_FLAG_BIGINT:
|
||||
return jit::MIRType::BigInt;
|
||||
#endif
|
||||
case TYPE_FLAG_LAZYARGS:
|
||||
return jit::MIRType::MagicOptimizedArguments;
|
||||
case TYPE_FLAG_ANYOBJECT:
|
||||
|
|
Загрузка…
Ссылка в новой задаче