Issue #1240 - Part 10 - Implement minimal Ion support for BigInt. https://bugzilla.mozilla.org/show_bug.cgi?id=1507484 Implement IC support for BigInt. https://bugzilla.mozilla.org/show_bug.cgi?id=1522431

This commit is contained in:
Brian Smith 2023-07-21 20:25:52 -05:00 • committed by roytam1
commit 2d5ee3c457
39 changed files with 448 additions and 43 deletions

View file

@ -1958,6 +1958,7 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo)
case Bailout_NonObjectInput: case Bailout_NonObjectInput:
case Bailout_NonStringInput: case Bailout_NonStringInput:
case Bailout_NonSymbolInput: case Bailout_NonSymbolInput:
case Bailout_NonBigIntInput:
case Bailout_UnexpectedSimdInput: case Bailout_UnexpectedSimdInput:
case Bailout_NonSharedTypedArrayInput: case Bailout_NonSharedTypedArrayInput:
case Bailout_Debugger: case Bailout_Debugger:

View file

@ -710,6 +710,9 @@ BaselineCacheIRCompiler::emitGuardType()
case JSVAL_TYPE_SYMBOL: case JSVAL_TYPE_SYMBOL:
masm.branchTestSymbol(Assembler::NotEqual, input, failure->label()); masm.branchTestSymbol(Assembler::NotEqual, input, failure->label());
break; break;
case JSVAL_TYPE_BIGINT:
masm.branchTestBigInt(Assembler::NotEqual, input, failure->label());
break;
case JSVAL_TYPE_DOUBLE: case JSVAL_TYPE_DOUBLE:
masm.branchTestNumber(Assembler::NotEqual, input, failure->label()); masm.branchTestNumber(Assembler::NotEqual, input, failure->label());
break; break;

View file

@ -8094,7 +8094,8 @@ ICTypeOf_Typed::Compiler::generateStubCode(MacroAssembler& masm)
break; break;
case JSTYPE_BIGINT: case JSTYPE_BIGINT:
return false; masm.branchTestBigInt(Assembler::NotEqual, R0, &failure);
break;
default: default:
MOZ_CRASH("Unexpected type"); MOZ_CRASH("Unexpected type");

View file

@ -446,6 +446,9 @@ GetPropIRGenerator::tryAttachPrimitive(CacheIRWriter& writer, ValOperandId valId
} else if (val_.isSymbol()) { } else if (val_.isSymbol()) {
primitiveType = JSVAL_TYPE_SYMBOL; primitiveType = JSVAL_TYPE_SYMBOL;
proto = MaybeNativeObject(GetBuiltinPrototypePure(cx_->global(), JSProto_Symbol)); proto = MaybeNativeObject(GetBuiltinPrototypePure(cx_->global(), JSProto_Symbol));
} else if (val_.isBigInt()) {
primitiveType = JSVAL_TYPE_BIGINT;
proto = MaybeNativeObject(GetBuiltinPrototypePure(cx_->global(), JSProto_BigInt));
} else { } else {
MOZ_ASSERT(val_.isNullOrUndefined() || val_.isMagic()); MOZ_ASSERT(val_.isNullOrUndefined() || val_.isMagic());
return true; return true;

View file

@ -526,9 +526,11 @@ CodeGenerator::testValueTruthyKernel(const ValueOperand& value,
bool mightBeString = valueMIR->mightBeType(MIRType::String); bool mightBeString = valueMIR->mightBeType(MIRType::String);
bool mightBeSymbol = valueMIR->mightBeType(MIRType::Symbol); bool mightBeSymbol = valueMIR->mightBeType(MIRType::Symbol);
bool mightBeDouble = valueMIR->mightBeType(MIRType::Double); bool mightBeDouble = valueMIR->mightBeType(MIRType::Double);
bool mightBeBigInt = valueMIR->mightBeType(MIRType::BigInt);
int tagCount = int(mightBeUndefined) + int(mightBeNull) + int tagCount = int(mightBeUndefined) + int(mightBeNull) +
int(mightBeBoolean) + int(mightBeInt32) + int(mightBeObject) + 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); MOZ_ASSERT_IF(!valueMIR->emptyResultTypeSet(), tagCount > 0);
@ -618,6 +620,20 @@ CodeGenerator::testValueTruthyKernel(const ValueOperand& value,
--tagCount; --tagCount;
} }
if (mightBeBigInt) {
MOZ_ASSERT(tagCount != 0);
Label notBigInt;
if (tagCount != 1) {
masm.branchTestBigInt(Assembler::NotEqual, tag, &notBigInt);
}
masm.branchTestBigIntTruthy(false, value, ifFalsy);
if (tagCount != 1) {
masm.jump(ifTruthy);
}
masm.bind(&notBigInt);
--tagCount;
}
if (mightBeSymbol) { if (mightBeSymbol) {
// All symbols are truthy. // All symbols are truthy.
MOZ_ASSERT(tagCount != 0); MOZ_ASSERT(tagCount != 0);
@ -954,8 +970,15 @@ CodeGenerator::visitValueToString(LValueToString* lir)
} }
// Symbol // Symbol
if (lir->mir()->input()->mightBeType(MIRType::Symbol)) if (lir->mir()->input()->mightBeType(MIRType::Symbol)) {
masm.branchTestSymbol(Assembler::Equal, tag, ool->entry()); masm.branchTestSymbol(Assembler::Equal, tag, ool->entry());
}
// BigInt
if (lir->mir()->input()->mightBeType(MIRType::BigInt)) {
// No fastpath currently implemented.
masm.branchTestBigInt(Assembler::Equal, tag, ool->entry());
}
#ifdef DEBUG #ifdef DEBUG
masm.assumeUnreachable("Unexpected type for MValueToString."); masm.assumeUnreachable("Unexpected type for MValueToString.");
@ -4902,10 +4925,11 @@ CodeGenerator::branchIfInvalidated(Register temp, Label* invalidated)
} }
void void
CodeGenerator::emitAssertObjectOrStringResult(Register input, MIRType type, const TemporaryTypeSet* typeset) CodeGenerator::emitAssertGCThingResult(Register input, MIRType type, const TemporaryTypeSet* typeset)
{ {
MOZ_ASSERT(type == MIRType::Object || type == MIRType::ObjectOrNull || MOZ_ASSERT(type == MIRType::Object || type == MIRType::ObjectOrNull ||
type == MIRType::String || type == MIRType::Symbol); type == MIRType::String || type == MIRType::Symbol ||
type == MIRType::BigInt);
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All()); AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
regs.take(input); regs.take(input);
@ -4960,6 +4984,9 @@ CodeGenerator::emitAssertObjectOrStringResult(Register input, MIRType type, cons
case MIRType::Symbol: case MIRType::Symbol:
callee = JS_FUNC_TO_DATA_PTR(void*, AssertValidSymbolPtr); callee = JS_FUNC_TO_DATA_PTR(void*, AssertValidSymbolPtr);
break; break;
case MIRType::BigInt:
callee = JS_FUNC_TO_DATA_PTR(void*, AssertValidBigIntPtr);
break;
default: default:
MOZ_CRASH(); MOZ_CRASH();
} }
@ -5029,7 +5056,7 @@ CodeGenerator::emitAssertResultV(const ValueOperand input, const TemporaryTypeSe
#ifdef DEBUG #ifdef DEBUG
void void
CodeGenerator::emitObjectOrStringResultChecks(LInstruction* lir, MDefinition* mir) CodeGenerator::emitGCThingResultChecks(LInstruction* lir, MDefinition* mir)
{ {
if (lir->numDefs() == 0) if (lir->numDefs() == 0)
return; return;
@ -5037,7 +5064,7 @@ CodeGenerator::emitObjectOrStringResultChecks(LInstruction* lir, MDefinition* mi
MOZ_ASSERT(lir->numDefs() == 1); MOZ_ASSERT(lir->numDefs() == 1);
Register output = ToRegister(lir->getDef(0)); Register output = ToRegister(lir->getDef(0));
emitAssertObjectOrStringResult(output, mir->type(), mir->resultTypeSet()); emitAssertGCThingResult(output, mir->type(), mir->resultTypeSet());
} }
void void
@ -5069,7 +5096,8 @@ CodeGenerator::emitDebugResultChecks(LInstruction* ins)
case MIRType::ObjectOrNull: case MIRType::ObjectOrNull:
case MIRType::String: case MIRType::String:
case MIRType::Symbol: case MIRType::Symbol:
emitObjectOrStringResultChecks(ins, mir); case MIRType::BigInt:
emitGCThingResultChecks(ins, mir);
break; break;
case MIRType::Value: case MIRType::Value:
emitValueResultChecks(ins, mir); emitValueResultChecks(ins, mir);
@ -10386,9 +10414,11 @@ CodeGenerator::visitTypeOfV(LTypeOfV* lir)
bool testNull = input->mightBeType(MIRType::Null); bool testNull = input->mightBeType(MIRType::Null);
bool testString = input->mightBeType(MIRType::String); bool testString = input->mightBeType(MIRType::String);
bool testSymbol = input->mightBeType(MIRType::Symbol); bool testSymbol = input->mightBeType(MIRType::Symbol);
bool testBigInt = input->mightBeType(MIRType::BigInt);
unsigned numTests = unsigned(testObject) + unsigned(testNumber) + unsigned(testBoolean) + unsigned numTests = unsigned(testObject) + unsigned(testNumber) + unsigned(testBoolean) +
unsigned(testUndefined) + unsigned(testNull) + unsigned(testString) + unsigned(testSymbol); unsigned(testUndefined) + unsigned(testNull) + unsigned(testString) + unsigned(testSymbol) +
unsigned(testBigInt);
MOZ_ASSERT_IF(!input->emptyResultTypeSet(), numTests > 0); MOZ_ASSERT_IF(!input->emptyResultTypeSet(), numTests > 0);
@ -10484,6 +10514,19 @@ CodeGenerator::visitTypeOfV(LTypeOfV* lir)
numTests--; numTests--;
} }
if (testBigInt) {
Label notBigInt;
if (numTests > 1) {
masm.branchTestBigInt(Assembler::NotEqual, tag, &notBigInt);
}
masm.movePtr(ImmGCPtr(names.bigint), output);
if (numTests > 1) {
masm.jump(&done);
}
masm.bind(&notBigInt);
numTests--;
}
MOZ_ASSERT(numTests == 0); MOZ_ASSERT(numTests == 0);
masm.bind(&done); masm.bind(&done);
@ -11794,7 +11837,7 @@ CodeGenerator::visitAssertResultT(LAssertResultT* ins)
Register input = ToRegister(ins->input()); Register input = ToRegister(ins->input());
MDefinition* mir = ins->mirRaw(); MDefinition* mir = ins->mirRaw();
emitAssertObjectOrStringResult(input, mir->type(), mir->resultTypeSet()); emitAssertGCThingResult(input, mir->type(), mir->resultTypeSet());
} }
void void

View file

@ -431,7 +431,7 @@ class CodeGenerator final : public CodeGeneratorSpecific
void visitAssertResultV(LAssertResultV* ins); void visitAssertResultV(LAssertResultV* ins);
void visitAssertResultT(LAssertResultT* ins); void visitAssertResultT(LAssertResultT* ins);
void emitAssertResultV(const ValueOperand output, const TemporaryTypeSet* typeset); 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);
void visitInterruptCheck(LInterruptCheck* lir); void visitInterruptCheck(LInterruptCheck* lir);
void visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit* ins); void visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit* ins);
@ -571,7 +571,7 @@ class CodeGenerator final : public CodeGeneratorSpecific
#ifdef DEBUG #ifdef DEBUG
void emitDebugResultChecks(LInstruction* ins); void emitDebugResultChecks(LInstruction* ins);
void emitObjectOrStringResultChecks(LInstruction* lir, MDefinition* mir); void emitGCThingResultChecks(LInstruction* lir, MDefinition* mir);
void emitValueResultChecks(LInstruction* lir, MDefinition* mir); void emitValueResultChecks(LInstruction* lir, MDefinition* mir);
#endif #endif

View file

@ -2611,6 +2611,7 @@ IsResumableMIRType(MIRType type)
case MIRType::Float32: case MIRType::Float32:
case MIRType::String: case MIRType::String:
case MIRType::Symbol: case MIRType::Symbol:
case MIRType::BigInt:
case MIRType::Object: case MIRType::Object:
case MIRType::MagicOptimizedArguments: case MIRType::MagicOptimizedArguments:
case MIRType::MagicOptimizedOut: case MIRType::MagicOptimizedOut:

View file

@ -721,6 +721,9 @@ IonBuilder::analyzeNewLoopTypes(MBasicBlock* entry, jsbytecode* start, jsbytecod
case JSOP_NEG: case JSOP_NEG:
type = inspector->expectedResultType(last); type = inspector->expectedResultType(last);
break; break;
case JSOP_BIGINT:
type = MIRType::BigInt;
break;
default: default:
break; break;
} }
@ -1347,6 +1350,7 @@ IonBuilder::addOsrValueTypeBarrier(uint32_t slot, MInstruction** def_,
case MIRType::Double: case MIRType::Double:
case MIRType::String: case MIRType::String:
case MIRType::Symbol: case MIRType::Symbol:
case MIRType::BigInt:
case MIRType::Object: case MIRType::Object:
if (type != def->type()) { if (type != def->type()) {
MUnbox* unbox = MUnbox::New(alloc(), def, type, MUnbox::Fallible); MUnbox* unbox = MUnbox::New(alloc(), def, type, MUnbox::Fallible);
@ -4761,8 +4765,10 @@ IonBuilder::bitnotTrySpecialized(bool* emitted, MDefinition* input)
// Try to emit a specialized bitnot instruction based on the input type // Try to emit a specialized bitnot instruction based on the input type
// of the operand. // of the operand.
if (input->mightBeType(MIRType::Object) || input->mightBeType(MIRType::Symbol)) if (input->mightBeType(MIRType::Object) || input->mightBeType(MIRType::Symbol) ||
input->mightBeType(MIRType::BigInt)) {
return true; return true;
}
MBitNot* ins = MBitNot::New(alloc(), input); MBitNot* ins = MBitNot::New(alloc(), input);
ins->setSpecialization(MIRType::Int32); ins->setSpecialization(MIRType::Int32);
@ -7210,6 +7216,7 @@ ObjectOrSimplePrimitive(MDefinition* op)
// Return true if op is either undefined/null/boolean/int32 or an object. // Return true if op is either undefined/null/boolean/int32 or an object.
return !op->mightBeType(MIRType::String) return !op->mightBeType(MIRType::String)
&& !op->mightBeType(MIRType::Symbol) && !op->mightBeType(MIRType::Symbol)
&& !op->mightBeType(MIRType::BigInt)
&& !op->mightBeType(MIRType::Double) && !op->mightBeType(MIRType::Double)
&& !op->mightBeType(MIRType::Float32) && !op->mightBeType(MIRType::Float32)
&& !op->mightBeType(MIRType::MagicOptimizedArguments) && !op->mightBeType(MIRType::MagicOptimizedArguments)
@ -8349,6 +8356,10 @@ IonBuilder::testSingletonPropertyTypes(MDefinition* obj, jsid id)
key = JSProto_Symbol; key = JSProto_Symbol;
break; break;
case MIRType::BigInt:
key = JSProto_BigInt;
break;
case MIRType::Int32: case MIRType::Int32:
case MIRType::Double: case MIRType::Double:
key = JSProto_Number; key = JSProto_Number;

View file

@ -103,6 +103,7 @@ enum BailoutKind
Bailout_NonObjectInput, Bailout_NonObjectInput,
Bailout_NonStringInput, Bailout_NonStringInput,
Bailout_NonSymbolInput, Bailout_NonSymbolInput,
Bailout_NonBigIntInput,
// SIMD Unbox expects a given type, bails out if it doesn't match. // SIMD Unbox expects a given type, bails out if it doesn't match.
Bailout_UnexpectedSimdInput, Bailout_UnexpectedSimdInput,
@ -212,6 +213,8 @@ BailoutKindString(BailoutKind kind)
return "Bailout_NonStringInput"; return "Bailout_NonStringInput";
case Bailout_NonSymbolInput: case Bailout_NonSymbolInput:
return "Bailout_NonSymbolInput"; return "Bailout_NonSymbolInput";
case Bailout_NonBigIntInput:
return "Bailout_NonBigIntInput";
case Bailout_UnexpectedSimdInput: case Bailout_UnexpectedSimdInput:
return "Bailout_UnexpectedSimdInput"; return "Bailout_UnexpectedSimdInput";
case Bailout_NonSharedTypedArrayInput: case Bailout_NonSharedTypedArrayInput:
@ -412,6 +415,7 @@ enum class MIRType
// Types above have trivial conversion to a number. // Types above have trivial conversion to a number.
String, String,
Symbol, Symbol,
BigInt,
// Types above are primitive (including undefined and null). // Types above are primitive (including undefined and null).
Object, Object,
MagicOptimizedArguments, // JS_OPTIMIZED_ARGUMENTS magic value. MagicOptimizedArguments, // JS_OPTIMIZED_ARGUMENTS magic value.
@ -496,6 +500,8 @@ MIRTypeFromValueType(JSValueType type)
return MIRType::String; return MIRType::String;
case JSVAL_TYPE_SYMBOL: case JSVAL_TYPE_SYMBOL:
return MIRType::Symbol; return MIRType::Symbol;
case JSVAL_TYPE_BIGINT:
return MIRType::BigInt;
case JSVAL_TYPE_BOOLEAN: case JSVAL_TYPE_BOOLEAN:
return MIRType::Boolean; return MIRType::Boolean;
case JSVAL_TYPE_NULL: case JSVAL_TYPE_NULL:
@ -528,6 +534,8 @@ ValueTypeFromMIRType(MIRType type)
return JSVAL_TYPE_STRING; return JSVAL_TYPE_STRING;
case MIRType::Symbol: case MIRType::Symbol:
return JSVAL_TYPE_SYMBOL; return JSVAL_TYPE_SYMBOL;
case MIRType::BigInt:
return JSVAL_TYPE_BIGINT;
case MIRType::MagicOptimizedArguments: case MIRType::MagicOptimizedArguments:
case MIRType::MagicOptimizedOut: case MIRType::MagicOptimizedOut:
case MIRType::MagicHole: case MIRType::MagicHole:
@ -568,6 +576,8 @@ StringFromMIRType(MIRType type)
return "String"; return "String";
case MIRType::Symbol: case MIRType::Symbol:
return "Symbol"; return "Symbol";
case MIRType::BigInt:
return "BigInt";
case MIRType::Object: case MIRType::Object:
return "Object"; return "Object";
case MIRType::MagicOptimizedArguments: case MIRType::MagicOptimizedArguments:

View file

@ -599,6 +599,7 @@ class LDefinition
return LDefinition::INT32; return LDefinition::INT32;
case MIRType::String: case MIRType::String:
case MIRType::Symbol: case MIRType::Symbol:
case MIRType::BigInt:
case MIRType::Object: case MIRType::Object:
case MIRType::ObjectOrNull: case MIRType::ObjectOrNull:
return LDefinition::OBJECT; return LDefinition::OBJECT;

View file

@ -717,6 +717,10 @@ LIRGenerator::visitTest(MTest* test)
// TestPolicy). // TestPolicy).
MOZ_ASSERT(opd->type() != MIRType::String); MOZ_ASSERT(opd->type() != MIRType::String);
// BigInt is boxed in type analysis.
MOZ_ASSERT(opd->type() != MIRType::BigInt,
"BigInt should be boxed by TestPolicy");
// Testing a constant. // Testing a constant.
if (MConstant* constant = opd->maybeConstantValue()) { if (MConstant* constant = opd->maybeConstantValue()) {
bool b; bool b;
@ -2149,9 +2153,11 @@ LIRGenerator::visitToInt32(MToInt32* convert)
case MIRType::String: case MIRType::String:
case MIRType::Symbol: case MIRType::Symbol:
case MIRType::BigInt:
case MIRType::Object: case MIRType::Object:
case MIRType::Undefined: 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"); MOZ_CRASH("ToInt32 invalid input type");
default: default:
@ -2939,6 +2945,8 @@ LIRGenerator::visitNot(MNot* ins)
// String is converted to length of string in the type analysis phase (see // String is converted to length of string in the type analysis phase (see
// TestPolicy). // TestPolicy).
MOZ_ASSERT(op->type() != MIRType::String); MOZ_ASSERT(op->type() != MIRType::String);
MOZ_ASSERT(op->type() != MIRType::BigInt,
"BigInt should be boxed by TestPolicy");
// - boolean: x xor 1 // - boolean: x xor 1
// - int32: LCompare(x, 0) // - int32: LCompare(x, 0)

View file

@ -2894,6 +2894,7 @@ IonBuilder::inlineToInteger(CallInfo& callInfo)
if (input->mightBeType(MIRType::Object) || if (input->mightBeType(MIRType::Object) ||
input->mightBeType(MIRType::String) || input->mightBeType(MIRType::String) ||
input->mightBeType(MIRType::Symbol) || input->mightBeType(MIRType::Symbol) ||
input->mightBeType(MIRType::BigInt) ||
input->mightBeType(MIRType::Undefined) || input->mightBeType(MIRType::Undefined) ||
input->mightBeMagicType()) input->mightBeMagicType())
{ {
@ -3021,12 +3022,16 @@ IonBuilder::inlineAtomicsCompareExchange(CallInfo& callInfo)
// These guards are desirable here and in subsequent atomics to // These guards are desirable here and in subsequent atomics to
// avoid bad bailouts with MTruncateToInt32, see https://bugzilla.mozilla.org/show_bug.cgi?id=1141986#c20. // avoid bad bailouts with MTruncateToInt32, see https://bugzilla.mozilla.org/show_bug.cgi?id=1141986#c20.
MDefinition* oldval = callInfo.getArg(2); MDefinition* oldval = callInfo.getArg(2);
if (oldval->mightBeType(MIRType::Object) || oldval->mightBeType(MIRType::Symbol)) if (oldval->mightBeType(MIRType::Object) || oldval->mightBeType(MIRType::Symbol) ||
oldval->mightBeType(MIRType::BigInt)) {
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
}
MDefinition* newval = callInfo.getArg(3); MDefinition* newval = callInfo.getArg(3);
if (newval->mightBeType(MIRType::Object) || newval->mightBeType(MIRType::Symbol)) if (newval->mightBeType(MIRType::Object) || newval->mightBeType(MIRType::Symbol) ||
newval->mightBeType(MIRType::BigInt)) {
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
}
Scalar::Type arrayType; Scalar::Type arrayType;
bool requiresCheck = false; bool requiresCheck = false;
@ -3063,8 +3068,10 @@ IonBuilder::inlineAtomicsExchange(CallInfo& callInfo)
} }
MDefinition* value = callInfo.getArg(2); MDefinition* value = callInfo.getArg(2);
if (value->mightBeType(MIRType::Object) || value->mightBeType(MIRType::Symbol)) if (value->mightBeType(MIRType::Object) || value->mightBeType(MIRType::Symbol) ||
value->mightBeType(MIRType::BigInt)) {
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
}
Scalar::Type arrayType; Scalar::Type arrayType;
bool requiresCheck = false; bool requiresCheck = false;
@ -3151,8 +3158,10 @@ IonBuilder::inlineAtomicsStore(CallInfo& callInfo)
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
} }
if (value->mightBeType(MIRType::Object) || value->mightBeType(MIRType::Symbol)) if (value->mightBeType(MIRType::Object) || value->mightBeType(MIRType::Symbol) ||
value->mightBeType(MIRType::BigInt)) {
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
}
Scalar::Type arrayType; Scalar::Type arrayType;
bool requiresCheck = false; bool requiresCheck = false;
@ -3194,8 +3203,10 @@ IonBuilder::inlineAtomicsBinop(CallInfo& callInfo, InlinableNative target)
} }
MDefinition* value = callInfo.getArg(2); MDefinition* value = callInfo.getArg(2);
if (value->mightBeType(MIRType::Object) || value->mightBeType(MIRType::Symbol)) if (value->mightBeType(MIRType::Object) || value->mightBeType(MIRType::Symbol) ||
value->mightBeType(MIRType::BigInt)) {
return InliningStatus_NotInlined; return InliningStatus_NotInlined;
}
Scalar::Type arrayType; Scalar::Type arrayType;
bool requiresCheck = false; bool requiresCheck = false;

View file

@ -935,6 +935,9 @@ MConstant::MConstant(const js::Value& vp, CompilerConstraintList* constraints)
case MIRType::Symbol: case MIRType::Symbol:
payload_.sym = vp.toSymbol(); payload_.sym = vp.toSymbol();
break; break;
case MIRType::BigInt:
payload_.bi = vp.toBigInt();
break;
case MIRType::Object: case MIRType::Object:
payload_.obj = &vp.toObject(); payload_.obj = &vp.toObject();
// Create a singleton type set for the object. This isn't necessary for // Create a singleton type set for the object. This isn't necessary for
@ -1014,7 +1017,12 @@ MConstant::assertInitializedPayload() const
case MIRType::String: case MIRType::String:
case MIRType::Object: case MIRType::Object:
case MIRType::Symbol: case MIRType::Symbol:
case MIRType::BigInt:
#if MOZ_LITTLE_ENDIAN
MOZ_ASSERT_IF(JS_BITS_PER_WORD == 32, (payload_.asBits >> 32) == 0); MOZ_ASSERT_IF(JS_BITS_PER_WORD == 32, (payload_.asBits >> 32) == 0);
#else
MOZ_ASSERT_IF(JS_BITS_PER_WORD == 32, (payload_.asBits << 32) == 0);
#endif
break; break;
default: default:
MOZ_ASSERT(IsNullOrUndefined(type()) || IsMagicType(type())); MOZ_ASSERT(IsNullOrUndefined(type()) || IsMagicType(type()));
@ -1103,6 +1111,9 @@ MConstant::printOpcode(GenericPrinter& out) const
case MIRType::Symbol: case MIRType::Symbol:
out.printf("symbol at %p", (void*)toSymbol()); out.printf("symbol at %p", (void*)toSymbol());
break; break;
case MIRType::BigInt:
out.printf("BigInt at %p", (void*)toBigInt());
break;
case MIRType::String: case MIRType::String:
out.printf("string %p", (void*)toString()); out.printf("string %p", (void*)toString());
break; break;
@ -1164,6 +1175,8 @@ MConstant::toJSValue() const
return StringValue(toString()); return StringValue(toString());
case MIRType::Symbol: case MIRType::Symbol:
return SymbolValue(toSymbol()); return SymbolValue(toSymbol());
case MIRType::BigInt:
return BigIntValue(toBigInt());
case MIRType::Object: case MIRType::Object:
return ObjectValue(toObject()); return ObjectValue(toObject());
case MIRType::MagicOptimizedArguments: case MIRType::MagicOptimizedArguments:
@ -1207,6 +1220,9 @@ MConstant::valueToBoolean(bool* res) const
case MIRType::Symbol: case MIRType::Symbol:
*res = true; *res = true;
return true; return true;
case MIRType::BigInt:
*res = !toBigInt()->isZero();
return true;
case MIRType::String: case MIRType::String:
*res = toString()->length() != 0; *res = toString()->length() != 0;
return true; return true;
@ -2199,6 +2215,7 @@ MUnbox::printOpcode(GenericPrinter& out) const
case MIRType::Boolean: out.printf("to Boolean"); break; case MIRType::Boolean: out.printf("to Boolean"); break;
case MIRType::String: out.printf("to String"); break; case MIRType::String: out.printf("to String"); break;
case MIRType::Symbol: out.printf("to Symbol"); break; case MIRType::Symbol: out.printf("to Symbol"); break;
case MIRType::BigInt: out.printf("to BigInt"); break;
case MIRType::Object: out.printf("to Object"); break; case MIRType::Object: out.printf("to Object"); break;
default: break; default: break;
} }
@ -2591,6 +2608,7 @@ jit::TypeSetIncludes(TypeSet* types, MIRType input, TypeSet* inputTypes)
case MIRType::Float32: case MIRType::Float32:
case MIRType::String: case MIRType::String:
case MIRType::Symbol: case MIRType::Symbol:
case MIRType::BigInt:
case MIRType::MagicOptimizedArguments: case MIRType::MagicOptimizedArguments:
return types->hasType(TypeSet::PrimitiveType(ValueTypeFromMIRType(input))); return types->hasType(TypeSet::PrimitiveType(ValueTypeFromMIRType(input)));
@ -2846,7 +2864,8 @@ void
MBinaryBitwiseInstruction::infer(BaselineInspector*, jsbytecode*) MBinaryBitwiseInstruction::infer(BaselineInspector*, jsbytecode*)
{ {
if (getOperand(0)->mightBeType(MIRType::Object) || getOperand(0)->mightBeType(MIRType::Symbol) || if (getOperand(0)->mightBeType(MIRType::Object) || getOperand(0)->mightBeType(MIRType::Symbol) ||
getOperand(1)->mightBeType(MIRType::Object) || getOperand(1)->mightBeType(MIRType::Symbol)) getOperand(1)->mightBeType(MIRType::Object) || getOperand(1)->mightBeType(MIRType::Symbol) ||
getOperand(1)->mightBeType(MIRType::BigInt))
{ {
specialization_ = MIRType::None; specialization_ = MIRType::None;
setResultType(MIRType::Value); setResultType(MIRType::Value);
@ -2872,7 +2891,8 @@ void
MShiftInstruction::infer(BaselineInspector*, jsbytecode*) MShiftInstruction::infer(BaselineInspector*, jsbytecode*)
{ {
if (getOperand(0)->mightBeType(MIRType::Object) || getOperand(1)->mightBeType(MIRType::Object) || if (getOperand(0)->mightBeType(MIRType::Object) || getOperand(1)->mightBeType(MIRType::Object) ||
getOperand(0)->mightBeType(MIRType::Symbol) || getOperand(1)->mightBeType(MIRType::Symbol)) getOperand(0)->mightBeType(MIRType::Symbol) || getOperand(1)->mightBeType(MIRType::Symbol) ||
getOperand(0)->mightBeType(MIRType::BigInt) || getOperand(1)->mightBeType(MIRType::BigInt))
{ {
specialization_ = MIRType::None; specialization_ = MIRType::None;
setResultType(MIRType::Value); setResultType(MIRType::Value);
@ -2886,7 +2906,8 @@ void
MUrsh::infer(BaselineInspector* inspector, jsbytecode* pc) MUrsh::infer(BaselineInspector* inspector, jsbytecode* pc)
{ {
if (getOperand(0)->mightBeType(MIRType::Object) || getOperand(1)->mightBeType(MIRType::Object) || if (getOperand(0)->mightBeType(MIRType::Object) || getOperand(1)->mightBeType(MIRType::Object) ||
getOperand(0)->mightBeType(MIRType::Symbol) || getOperand(1)->mightBeType(MIRType::Symbol)) getOperand(0)->mightBeType(MIRType::Symbol) || getOperand(1)->mightBeType(MIRType::Symbol) ||
getOperand(0)->mightBeType(MIRType::BigInt) || getOperand(1)->mightBeType(MIRType::BigInt))
{ {
specialization_ = MIRType::None; specialization_ = MIRType::None;
setResultType(MIRType::Value); setResultType(MIRType::Value);
@ -3880,6 +3901,9 @@ MTypeOf::foldsTo(TempAllocator& alloc)
case MIRType::Symbol: case MIRType::Symbol:
type = JSTYPE_SYMBOL; type = JSTYPE_SYMBOL;
break; break;
case MIRType::BigInt:
type = JSTYPE_BIGINT;
break;
case MIRType::Null: case MIRType::Null:
type = JSTYPE_OBJECT; type = JSTYPE_OBJECT;
break; break;
@ -4459,6 +4483,12 @@ MCompare::tryFoldTypeOf(bool* result)
*result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE); *result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE);
return true; return true;
} }
}
else if (constant->toString() == TypeName(JSTYPE_BIGINT, names)) {
if (!typeOf->input()->mightBeType(MIRType::BigInt)) {
*result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE);
return true;
}
} else if (constant->toString() == TypeName(JSTYPE_OBJECT, names)) { } else if (constant->toString() == TypeName(JSTYPE_OBJECT, names)) {
if (!typeOf->input()->mightBeType(MIRType::Object) && if (!typeOf->input()->mightBeType(MIRType::Object) &&
!typeOf->input()->mightBeType(MIRType::Null)) !typeOf->input()->mightBeType(MIRType::Null))
@ -5612,6 +5642,8 @@ MConstant::appendRoots(MRootList& roots) const
return roots.append(toString()); return roots.append(toString());
case MIRType::Symbol: case MIRType::Symbol:
return roots.append(toSymbol()); return roots.append(toSymbol());
case MIRType::BigInt:
return roots.append(toBigInt());
case MIRType::Object: case MIRType::Object:
return roots.append(&toObject()); return roots.append(&toObject());
case MIRType::Undefined: case MIRType::Undefined:

View file

@ -1548,6 +1548,7 @@ class MConstant : public MNullaryInstruction
double d; double d;
JSString* str; JSString* str;
JS::Symbol* sym; JS::Symbol* sym;
BigInt* bi;
JSObject* obj; JSObject* obj;
uint64_t asBits; uint64_t asBits;
}; };
@ -1672,6 +1673,10 @@ class MConstant : public MNullaryInstruction
MOZ_ASSERT(type() == MIRType::Symbol); MOZ_ASSERT(type() == MIRType::Symbol);
return payload_.sym; return payload_.sym;
} }
BigInt* toBigInt() const {
MOZ_ASSERT(type() == MIRType::BigInt);
return payload_.bi;
}
JSObject& toObject() const { JSObject& toObject() const {
MOZ_ASSERT(type() == MIRType::Object); MOZ_ASSERT(type() == MIRType::Object);
return *payload_.obj; return *payload_.obj;
@ -4743,6 +4748,7 @@ class MUnbox final : public MUnaryInstruction, public BoxInputsPolicy::Data
type == MIRType::Double || type == MIRType::Double ||
type == MIRType::String || type == MIRType::String ||
type == MIRType::Symbol || type == MIRType::Symbol ||
type == MIRType::BigInt ||
type == MIRType::Object); type == MIRType::Object);
TemporaryTypeSet* resultSet = ins->resultTypeSet(); TemporaryTypeSet* resultSet = ins->resultTypeSet();
@ -4781,6 +4787,9 @@ class MUnbox final : public MUnaryInstruction, public BoxInputsPolicy::Data
case MIRType::Symbol: case MIRType::Symbol:
kind = Bailout_NonSymbolInput; kind = Bailout_NonSymbolInput;
break; break;
case MIRType::BigInt:
kind = Bailout_NonBigIntInput;
break;
case MIRType::Object: case MIRType::Object:
kind = Bailout_NonObjectInput; kind = Bailout_NonObjectInput;
break; break;
@ -5189,9 +5198,11 @@ class MToDouble
setMovable(); setMovable();
// An object might have "valueOf", which means it is effectful. // 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)) if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol) ||
def->mightBeType(MIRType::BigInt)) {
setGuard(); setGuard();
}
} }
public: public:
@ -5226,11 +5237,15 @@ class MToDouble
MOZ_MUST_USE bool writeRecoverData(CompactBufferWriter& writer) const override; MOZ_MUST_USE bool writeRecoverData(CompactBufferWriter& writer) const override;
bool canRecoverOnBailout() const override { bool canRecoverOnBailout() const override {
if (input()->type() == MIRType::Value) if (input()->type() == MIRType::Value) {
return false; return false;
if (input()->type() == MIRType::Symbol) }
if (input()->type() == MIRType::Symbol) {
return false; return false;
}
if (input()->type() == MIRType::BigInt) {
return false;
}
return true; return true;
} }
@ -5253,9 +5268,11 @@ class MToFloat32
setMovable(); setMovable();
// An object might have "valueOf", which means it is effectful. // 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)) if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol) ||
def->mightBeType(MIRType::BigInt)) {
setGuard(); setGuard();
}
} }
explicit MToFloat32(MDefinition* def, bool mustPreserveNaN) explicit MToFloat32(MDefinition* def, bool mustPreserveNaN)
@ -5537,9 +5554,11 @@ class MToInt32
setMovable(); setMovable();
// An object might have "valueOf", which means it is effectful. // An object might have "valueOf", which means it is effectful.
// ToNumber(symbol) throws. // ToInt32(symbol) and ToInt32(BigInt) throw.
if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol)) if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol) ||
def->mightBeType(MIRType::BigInt)) {
setGuard(); setGuard();
}
} }
public: public:
@ -5594,9 +5613,11 @@ class MTruncateToInt32
setMovable(); setMovable();
// An object might have "valueOf", which means it is effectful. // 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)) if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol) ||
def->mightBeType(MIRType::BigInt)) {
setGuard(); setGuard();
}
} }
public: public:
@ -5639,9 +5660,12 @@ class MToString :
setResultType(MIRType::String); setResultType(MIRType::String);
setMovable(); setMovable();
// Objects might override toString and Symbols throw. // Objects might override toString; Symbol and BigInts throw. We bailout in
if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol)) // those cases and run side-effects in baseline instead.
if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol) ||
def->mightBeType(MIRType::BigInt)) {
setGuard(); setGuard();
}
} }
public: public:

View file

@ -545,6 +545,7 @@ MacroAssembler::branchTestMIRType(Condition cond, const Value& val, MIRType type
case MIRType::Int32: return branchTestInt32(cond, val, label); case MIRType::Int32: return branchTestInt32(cond, val, label);
case MIRType::String: return branchTestString(cond, val, label); case MIRType::String: return branchTestString(cond, val, label);
case MIRType::Symbol: return branchTestSymbol(cond, val, label); case MIRType::Symbol: return branchTestSymbol(cond, val, label);
case MIRType::BigInt: return branchTestBigInt(cond, val, label);
case MIRType::Object: return branchTestObject(cond, val, label); case MIRType::Object: return branchTestObject(cond, val, label);
case MIRType::Double: return branchTestDouble(cond, val, label); case MIRType::Double: return branchTestDouble(cond, val, label);
case MIRType::MagicOptimizedArguments: // Fall through. case MIRType::MagicOptimizedArguments: // Fall through.

View file

@ -45,12 +45,13 @@ MacroAssembler::guardTypeSet(const Source& address, const TypeSet* types, Barrie
MOZ_ASSERT(!types->unknown()); MOZ_ASSERT(!types->unknown());
Label matched; Label matched;
TypeSet::Type tests[8] = { TypeSet::Type tests[9] = {
TypeSet::Int32Type(), TypeSet::Int32Type(),
TypeSet::UndefinedType(), TypeSet::UndefinedType(),
TypeSet::BooleanType(), TypeSet::BooleanType(),
TypeSet::StringType(), TypeSet::StringType(),
TypeSet::SymbolType(), TypeSet::SymbolType(),
TypeSet::BigIntType(),
TypeSet::NullType(), TypeSet::NullType(),
TypeSet::MagicArgType(), TypeSet::MagicArgType(),
TypeSet::AnyObjectType() TypeSet::AnyObjectType()
@ -2736,6 +2737,9 @@ MacroAssembler::maybeBranchTestType(MIRType type, MDefinition* maybeDef, Registe
case MIRType::Symbol: case MIRType::Symbol:
branchTestSymbol(Equal, tag, label); branchTestSymbol(Equal, tag, label);
break; break;
case MIRType::BigInt:
branchTestBigInt(Equal, tag, label);
break;
case MIRType::Object: case MIRType::Object:
branchTestObject(Equal, tag, label); branchTestObject(Equal, tag, label);
break; break;

View file

@ -1137,6 +1137,7 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void branchTestBoolean(Condition cond, Register tag, Label* label) PER_SHARED_ARCH; inline void branchTestBoolean(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
inline void branchTestString(Condition cond, Register tag, Label* label) PER_SHARED_ARCH; inline void branchTestString(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
inline void branchTestSymbol(Condition cond, Register tag, Label* label) PER_SHARED_ARCH; inline void branchTestSymbol(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
inline void branchTestBigInt(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
inline void branchTestNull(Condition cond, Register tag, Label* label) PER_SHARED_ARCH; inline void branchTestNull(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
inline void branchTestObject(Condition cond, Register tag, Label* label) PER_SHARED_ARCH; inline void branchTestObject(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
inline void branchTestPrimitive(Condition cond, Register tag, Label* label) PER_SHARED_ARCH; inline void branchTestPrimitive(Condition cond, Register tag, Label* label) PER_SHARED_ARCH;
@ -1177,6 +1178,10 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void branchTestSymbol(Condition cond, const ValueOperand& value, Label* label) inline void branchTestSymbol(Condition cond, const ValueOperand& value, Label* label)
DEFINED_ON(arm, arm64, mips32, mips64, x86_shared); DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
inline void branchTestBigInt(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH;
inline void branchTestBigInt(Condition cond, const ValueOperand& value, Label* label)
DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
inline void branchTestNull(Condition cond, const Address& address, Label* label) PER_SHARED_ARCH; inline void branchTestNull(Condition cond, const Address& address, Label* label) PER_SHARED_ARCH;
inline void branchTestNull(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH; inline void branchTestNull(Condition cond, const BaseIndex& address, Label* label) PER_SHARED_ARCH;
inline void branchTestNull(Condition cond, const ValueOperand& value, Label* label) inline void branchTestNull(Condition cond, const ValueOperand& value, Label* label)
@ -1216,6 +1221,8 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void branchTestBooleanTruthy(bool truthy, const ValueOperand& value, Label* label) PER_ARCH; inline void branchTestBooleanTruthy(bool truthy, const ValueOperand& value, Label* label) PER_ARCH;
inline void branchTestStringTruthy(bool truthy, const ValueOperand& value, Label* label) inline void branchTestStringTruthy(bool truthy, const ValueOperand& value, Label* label)
DEFINED_ON(arm, arm64, mips32, mips64, x86_shared); DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
inline void branchTestBigIntTruthy(bool truthy, const ValueOperand& value, Label* label)
DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
private: private:
@ -1256,6 +1263,9 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void branchTestSymbolImpl(Condition cond, const T& t, Label* label) inline void branchTestSymbolImpl(Condition cond, const T& t, Label* label)
DEFINED_ON(arm, arm64, x86_shared); DEFINED_ON(arm, arm64, x86_shared);
template <typename T> template <typename T>
inline void branchTestBigIntImpl(Condition cond, const T& t, Label* label)
DEFINED_ON(arm, arm64, x86_shared);
template <typename T>
inline void branchTestNullImpl(Condition cond, const T& t, Label* label) inline void branchTestNullImpl(Condition cond, const T& t, Label* label)
DEFINED_ON(arm, arm64, x86_shared); DEFINED_ON(arm, arm64, x86_shared);
template <typename T> template <typename T>

View file

@ -409,6 +409,8 @@ ValTypeToString(JSValueType type)
return "string"; return "string";
case JSVAL_TYPE_SYMBOL: case JSVAL_TYPE_SYMBOL:
return "symbol"; return "symbol";
case JSVAL_TYPE_BIGINT:
return "BigInt";
case JSVAL_TYPE_BOOLEAN: case JSVAL_TYPE_BOOLEAN:
return "boolean"; return "boolean";
case JSVAL_TYPE_OBJECT: case JSVAL_TYPE_OBJECT:

View file

@ -700,7 +700,8 @@ ToDoublePolicy::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins)
case MIRType::Object: case MIRType::Object:
case MIRType::String: case MIRType::String:
case MIRType::Symbol: case MIRType::Symbol:
// Objects might be effectful. Symbols give TypeError. case MIRType::BigInt:
// Objects might be effectful. Symbols and BigInts give TypeError.
break; break;
default: default:
break; break;
@ -748,7 +749,8 @@ ToInt32Policy::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins)
case MIRType::Object: case MIRType::Object:
case MIRType::String: case MIRType::String:
case MIRType::Symbol: case MIRType::Symbol:
// Objects might be effectful. Symbols give TypeError. case MIRType::BigInt:
// Objects might be effectful. Symbols and BigInts give TypeError.
break; break;
default: default:
break; break;
@ -765,7 +767,8 @@ ToStringPolicy::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins)
MOZ_ASSERT(ins->isToString()); MOZ_ASSERT(ins->isToString());
MIRType type = ins->getOperand(0)->type(); MIRType type = ins->getOperand(0)->type();
if (type == MIRType::Object || type == MIRType::Symbol) { if (type == MIRType::Object || type == MIRType::Symbol ||
type == MIRType::BigInt) {
ins->replaceOperand(0, BoxAt(alloc, ins, ins->getOperand(0))); ins->replaceOperand(0, BoxAt(alloc, ins, ins->getOperand(0)));
return true; return true;
} }
@ -955,6 +958,7 @@ StoreUnboxedScalarPolicy::adjustValueInput(TempAllocator& alloc, MInstruction* i
case MIRType::Object: case MIRType::Object:
case MIRType::String: case MIRType::String:
case MIRType::Symbol: case MIRType::Symbol:
case MIRType::BigInt:
value = BoxAt(alloc, ins, value); value = BoxAt(alloc, ins, value);
break; break;
default: default:

View file

@ -1236,15 +1236,27 @@ AssertValidSymbolPtr(JSContext* cx, JS::Symbol* sym)
MOZ_ASSERT(sym->getAllocKind() == gc::AllocKind::SYMBOL); MOZ_ASSERT(sym->getAllocKind() == gc::AllocKind::SYMBOL);
} }
void
AssertValidBigIntPtr(JSContext* cx, JS::BigInt* bi) {
// FIXME: check runtime?
MOZ_ASSERT(cx->zone() == bi->zone());
MOZ_ASSERT(bi->isAligned());
MOZ_ASSERT(bi->isTenured());
MOZ_ASSERT(bi->getAllocKind() == gc::AllocKind::BIGINT);
}
void void
AssertValidValue(JSContext* cx, Value* v) AssertValidValue(JSContext* cx, Value* v)
{ {
if (v->isObject()) if (v->isObject()) {
AssertValidObjectPtr(cx, &v->toObject()); AssertValidObjectPtr(cx, &v->toObject());
else if (v->isString()) } else if (v->isString()) {
AssertValidStringPtr(cx, v->toString()); AssertValidStringPtr(cx, v->toString());
else if (v->isSymbol()) } else if (v->isSymbol()) {
AssertValidSymbolPtr(cx, v->toSymbol()); AssertValidSymbolPtr(cx, v->toSymbol());
} else if (v->isBigInt()) {
AssertValidBigIntPtr(cx, v->toBigInt());
}
} }
bool bool

View file

@ -751,6 +751,7 @@ void AssertValidObjectPtr(JSContext* cx, JSObject* obj);
void AssertValidObjectOrNullPtr(JSContext* cx, JSObject* obj); void AssertValidObjectOrNullPtr(JSContext* cx, JSObject* obj);
void AssertValidStringPtr(JSContext* cx, JSString* str); void AssertValidStringPtr(JSContext* cx, JSString* str);
void AssertValidSymbolPtr(JSContext* cx, JS::Symbol* sym); void AssertValidSymbolPtr(JSContext* cx, JS::Symbol* sym);
void AssertValidBigIntPtr(JSContext* cx, JS::BigInt* bi);
void AssertValidValue(JSContext* cx, Value* v); void AssertValidValue(JSContext* cx, Value* v);
void MarkValueFromIon(JSRuntime* rt, Value* vp); void MarkValueFromIon(JSRuntime* rt, Value* vp);

View file

@ -1880,6 +1880,29 @@ MacroAssembler::branchTestSymbolImpl(Condition cond, const T& t, Label* label)
ma_b(label, c); ma_b(label, c);
} }
void MacroAssembler::branchTestBigInt(Condition cond, Register tag, Label* label) {
branchTestBigIntImpl(cond, tag, label);
}
void MacroAssembler::branchTestBigInt(Condition cond, const BaseIndex& address, Label* label) {
branchTestBigIntImpl(cond, address, label);
}
void MacroAssembler::branchTestBigInt(Condition cond, const ValueOperand& value, Label* label) {
branchTestBigIntImpl(cond, value, label);
}
template <typename T>
void MacroAssembler::branchTestBigIntImpl(Condition cond, const T& t, Label* label) {
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);
}
void void
MacroAssembler::branchTestNull(Condition cond, Register tag, Label* label) MacroAssembler::branchTestNull(Condition cond, Register tag, Label* label)
{ {

View file

@ -2717,6 +2717,11 @@ MacroAssemblerARMCompat::testSymbol(Assembler::Condition cond, const ValueOperan
return testSymbol(cond, value.typeReg()); return testSymbol(cond, value.typeReg());
} }
Assembler::Condition MacroAssemblerARMCompat::testBigInt(Assembler::Condition cond, const ValueOperand& value)
{
return testBigInt(cond, value.typeReg());
}
Assembler::Condition Assembler::Condition
MacroAssemblerARMCompat::testObject(Assembler::Condition cond, const ValueOperand& value) MacroAssemblerARMCompat::testObject(Assembler::Condition cond, const ValueOperand& value)
{ {
@ -2790,6 +2795,13 @@ MacroAssemblerARMCompat::testSymbol(Assembler::Condition cond, Register tag)
return cond; return cond;
} }
Assembler::Condition MacroAssemblerARMCompat::testBigInt(Assembler::Condition cond, Register tag)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ma_cmp(tag, ImmTag(JSVAL_TAG_BIGINT));
return cond;
}
Assembler::Condition Assembler::Condition
MacroAssemblerARMCompat::testObject(Assembler::Condition cond, Register tag) MacroAssemblerARMCompat::testObject(Assembler::Condition cond, Register tag)
{ {
@ -2907,6 +2919,14 @@ MacroAssemblerARMCompat::testObject(Condition cond, const Address& address)
return testObject(cond, scratch); return testObject(cond, scratch);
} }
Assembler::Condition MacroAssemblerARMCompat::testBigInt(Condition cond, const Address& address)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
Register tag = extractTag(address, scratch);
return testBigInt(cond, tag);
}
Assembler::Condition Assembler::Condition
MacroAssemblerARMCompat::testNumber(Condition cond, const Address& address) MacroAssemblerARMCompat::testNumber(Condition cond, const Address& address)
{ {
@ -2993,6 +3013,16 @@ MacroAssemblerARMCompat::testInt32(Condition cond, const BaseIndex& src)
return cond; return cond;
} }
+Assembler::Condition
MacroAssemblerARMCompat::testBigInt(Condition cond,const BaseIndex& src)
{
MOZ_ASSERT(cond == Equal || cond == NotEqual);
ScratchRegisterScope scratch(asMasm());
Register tag = extractTag(src, scratch);
ma_cmp(tag, ImmTag(JSVAL_TAG_BIGINT));
return cond;
}
Assembler::Condition Assembler::Condition
MacroAssemblerARMCompat::testObject(Condition cond, const BaseIndex& src) MacroAssemblerARMCompat::testObject(Condition cond, const BaseIndex& src)
{ {
@ -3736,6 +3766,19 @@ MacroAssemblerARMCompat::testStringTruthy(bool truthy, const ValueOperand& value
return truthy ? Assembler::NotEqual : Assembler::Equal; return truthy ? Assembler::NotEqual : Assembler::Equal;
} }
+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;
}
void void
MacroAssemblerARMCompat::floor(FloatRegister input, Register output, Label* bail) MacroAssemblerARMCompat::floor(FloatRegister input, Register output, Label* bail)
{ {

View file

@ -695,6 +695,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
Condition testUndefined(Condition cond, const ValueOperand& value); Condition testUndefined(Condition cond, const ValueOperand& value);
Condition testString(Condition cond, const ValueOperand& value); Condition testString(Condition cond, const ValueOperand& value);
Condition testSymbol(Condition cond, const ValueOperand& value); Condition testSymbol(Condition cond, const ValueOperand& value);
Condition testBigInt(Condition cond, const ValueOperand& value);
Condition testObject(Condition cond, const ValueOperand& value); Condition testObject(Condition cond, const ValueOperand& value);
Condition testNumber(Condition cond, const ValueOperand& value); Condition testNumber(Condition cond, const ValueOperand& value);
Condition testMagic(Condition cond, const ValueOperand& value); Condition testMagic(Condition cond, const ValueOperand& value);
@ -708,6 +709,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
Condition testUndefined(Condition cond, Register tag); Condition testUndefined(Condition cond, Register tag);
Condition testString(Condition cond, Register tag); Condition testString(Condition cond, Register tag);
Condition testSymbol(Condition cond, Register tag); Condition testSymbol(Condition cond, Register tag);
Condition testBigInt(Condition cond, Register tag);
Condition testObject(Condition cond, Register tag); Condition testObject(Condition cond, Register tag);
Condition testDouble(Condition cond, Register tag); Condition testDouble(Condition cond, Register tag);
Condition testNumber(Condition cond, Register tag); Condition testNumber(Condition cond, Register tag);
@ -723,6 +725,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
Condition testUndefined(Condition cond, const Address& address); Condition testUndefined(Condition cond, const Address& address);
Condition testString(Condition cond, const Address& address); Condition testString(Condition cond, const Address& address);
Condition testSymbol(Condition cond, const Address& address); Condition testSymbol(Condition cond, const Address& address);
Condition testBigInt(Condition cond, const Address& address);
Condition testObject(Condition cond, const Address& address); Condition testObject(Condition cond, const Address& address);
Condition testNumber(Condition cond, const Address& address); Condition testNumber(Condition cond, const Address& address);
@ -731,6 +734,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
Condition testBoolean(Condition cond, const BaseIndex& src); Condition testBoolean(Condition cond, const BaseIndex& src);
Condition testString(Condition cond, const BaseIndex& src); Condition testString(Condition cond, const BaseIndex& src);
Condition testSymbol(Condition cond, const BaseIndex& src); Condition testSymbol(Condition cond, const BaseIndex& src);
Condition testBigInt(Condition cond, const BaseIndex& src);
Condition testInt32(Condition cond, const BaseIndex& src); Condition testInt32(Condition cond, const BaseIndex& src);
Condition testObject(Condition cond, const BaseIndex& src); Condition testObject(Condition cond, const BaseIndex& src);
Condition testDouble(Condition cond, const BaseIndex& src); Condition testDouble(Condition cond, const BaseIndex& src);
@ -749,6 +753,8 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
void unboxString(const Address& src, Register dest) { unboxNonDouble(src, dest); } void unboxString(const Address& src, Register dest) { unboxNonDouble(src, dest); }
void unboxSymbol(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); } void unboxSymbol(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxSymbol(const Address& src, Register dest) { unboxNonDouble(src, dest); } void unboxSymbol(const Address& src, Register dest) { unboxNonDouble(src, dest); }
void unboxBigInt(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxBigInt(const Address& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); } void unboxObject(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const Address& src, Register dest) { unboxNonDouble(src, dest); } void unboxObject(const Address& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const BaseIndex& src, Register dest) { unboxNonDouble(src, dest); } void unboxObject(const BaseIndex& src, Register dest) { unboxNonDouble(src, dest); }
@ -797,6 +803,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
Condition testBooleanTruthy(bool truthy, const ValueOperand& operand); Condition testBooleanTruthy(bool truthy, const ValueOperand& operand);
Condition testDoubleTruthy(bool truthy, FloatRegister reg); Condition testDoubleTruthy(bool truthy, FloatRegister reg);
Condition testStringTruthy(bool truthy, const ValueOperand& value); Condition testStringTruthy(bool truthy, const ValueOperand& value);
Condition testBigIntTruthy(bool truthy, const ValueOperand& value);
void boolValueToFloat32(const ValueOperand& operand, FloatRegister dest); void boolValueToFloat32(const ValueOperand& operand, FloatRegister dest);
void int32ValueToFloat32(const ValueOperand& operand, FloatRegister dest); void int32ValueToFloat32(const ValueOperand& operand, FloatRegister dest);

View file

@ -963,6 +963,19 @@ MacroAssembler::branchTestSymbol(Condition cond, const ValueOperand& value, Labe
branchTestSymbol(cond, value.typeReg(), label); branchTestSymbol(cond, value.typeReg(), label);
} }
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);
}
void void
MacroAssembler::branchTestNull(Condition cond, const ValueOperand& value, Label* label) MacroAssembler::branchTestNull(Condition cond, const ValueOperand& value, Label* label)
{ {

View file

@ -196,6 +196,9 @@ CodeGeneratorMIPS64::visitUnbox(LUnbox* unbox)
case MIRType::Symbol: case MIRType::Symbol:
masm.unboxSymbol(inputReg, result); masm.unboxSymbol(inputReg, result);
break; break;
case MIRType::BigInt:
masm.unboxBigInt(inputReg, result);
break;
default: default:
MOZ_CRASH("Given MIRType cannot be unboxed."); MOZ_CRASH("Given MIRType cannot be unboxed.");
} }
@ -219,6 +222,9 @@ CodeGeneratorMIPS64::visitUnbox(LUnbox* unbox)
case MIRType::Symbol: case MIRType::Symbol:
masm.unboxSymbol(inputAddr, result); masm.unboxSymbol(inputAddr, result);
break; break;
case MIRType::BigInt:
masm.unboxBigInt(inputAddr, result);
break;
default: default:
MOZ_CRASH("Given MIRType cannot be unboxed."); MOZ_CRASH("Given MIRType cannot be unboxed.");
} }

View file

@ -622,6 +622,21 @@ MacroAssembler::branchTestSymbol(Condition cond, const ValueOperand& value, Labe
branchTestSymbol(cond, scratch2, label); branchTestSymbol(cond, scratch2, label);
} }
void MacroAssembler::branchTestBigInt(Condition cond, const ValueOperand& value, Label* label)
{
SecondScratchRegisterScope scratch2(*this);
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);
}
void void
MacroAssembler::branchTestNull(Condition cond, const ValueOperand& value, Label* label) MacroAssembler::branchTestNull(Condition cond, const ValueOperand& value, Label* label)
{ {

View file

@ -1495,6 +1495,21 @@ MacroAssemblerMIPS64Compat::unboxSymbol(Register src, Register dest)
ma_dext(dest, src, Imm32(0), Imm32(JSVAL_TAG_SHIFT)); ma_dext(dest, src, Imm32(0), Imm32(JSVAL_TAG_SHIFT));
} }
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);
}
void void
MacroAssemblerMIPS64Compat::unboxSymbol(const Address& src, Register dest) MacroAssemblerMIPS64Compat::unboxSymbol(const Address& src, Register dest)
{ {

View file

@ -361,6 +361,9 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
void unboxSymbol(const ValueOperand& src, Register dest); void unboxSymbol(const ValueOperand& src, Register dest);
void unboxSymbol(Register src, Register dest); void unboxSymbol(Register src, Register dest);
void unboxSymbol(const Address& src, Register dest); void unboxSymbol(const Address& src, Register dest);
void unboxBigInt(const ValueOperand& operand, Register dest);
void unboxBigInt(Register src, Register dest);
void unboxBigInt(const Address& src, Register dest);
void unboxObject(const ValueOperand& src, Register dest); void unboxObject(const ValueOperand& src, Register dest);
void unboxObject(Register src, Register dest); void unboxObject(Register src, Register dest);
void unboxObject(const Address& src, Register dest); void unboxObject(const Address& src, Register dest);

View file

@ -359,6 +359,7 @@ class MacroAssemblerNone : public Assembler
template <typename T> void unboxBoolean(T, Register) { MOZ_CRASH(); } template <typename T> void unboxBoolean(T, Register) { MOZ_CRASH(); }
template <typename T> void unboxString(T, Register) { MOZ_CRASH(); } template <typename T> void unboxString(T, Register) { MOZ_CRASH(); }
template <typename T> void unboxSymbol(T, Register) { MOZ_CRASH(); } template <typename T> void unboxSymbol(T, Register) { MOZ_CRASH(); }
template <typename T> void unboxBigInt(T, Register) { MOZ_CRASH(); }
template <typename T> void unboxObject(T, Register) { MOZ_CRASH(); } template <typename T> void unboxObject(T, Register) { MOZ_CRASH(); }
template <typename T> void unboxDouble(T, FloatRegister) { MOZ_CRASH(); } template <typename T> void unboxDouble(T, FloatRegister) { MOZ_CRASH(); }
void unboxValue(const ValueOperand&, AnyRegister) { MOZ_CRASH(); } void unboxValue(const ValueOperand&, AnyRegister) { MOZ_CRASH(); }
@ -393,6 +394,7 @@ class MacroAssemblerNone : public Assembler
void loadConstantFloat32(wasm::RawF32, FloatRegister) { MOZ_CRASH(); } void loadConstantFloat32(wasm::RawF32, FloatRegister) { MOZ_CRASH(); }
Condition testInt32Truthy(bool, ValueOperand) { MOZ_CRASH(); } Condition testInt32Truthy(bool, ValueOperand) { MOZ_CRASH(); }
Condition testStringTruthy(bool, ValueOperand) { MOZ_CRASH(); } Condition testStringTruthy(bool, ValueOperand) { MOZ_CRASH(); }
Condition testBigIntTruthy(bool, ValueOperand) { MOZ_CRASH(); }
template <typename T> void loadUnboxedValue(T, MIRType, AnyRegister) { MOZ_CRASH(); } template <typename T> void loadUnboxedValue(T, MIRType, AnyRegister) { MOZ_CRASH(); }
template <typename T> void storeUnboxedValue(const ConstantOrRegister&, MIRType, T, MIRType) { MOZ_CRASH(); } template <typename T> void storeUnboxedValue(const ConstantOrRegister&, MIRType, T, MIRType) { MOZ_CRASH(); }

View file

@ -431,6 +431,7 @@ CodeGeneratorShared::encodeAllocation(LSnapshot* snapshot, MDefinition* mir,
case MIRType::Int32: case MIRType::Int32:
case MIRType::String: case MIRType::String:
case MIRType::Symbol: case MIRType::Symbol:
case MIRType::BigInt:
case MIRType::Object: case MIRType::Object:
case MIRType::ObjectOrNull: case MIRType::ObjectOrNull:
case MIRType::Boolean: case MIRType::Boolean:

View file

@ -402,7 +402,8 @@ LIRGeneratorShared::redefine(MDefinition* def, MDefinition* as)
case MIRType::Object: case MIRType::Object:
case MIRType::ObjectOrNull: case MIRType::ObjectOrNull:
case MIRType::String: case MIRType::String:
case MIRType::Symbol: { case MIRType::Symbol:
case MIRType::BigInt: {
LAssertResultT* check = new(alloc()) LAssertResultT(useRegister(def)); LAssertResultT* check = new(alloc()) LAssertResultT(useRegister(def));
add(check, def->toInstruction()); add(check, def->toInstruction());
break; break;

View file

@ -100,6 +100,9 @@ LIRGeneratorShared::visitConstant(MConstant* ins)
case MIRType::Symbol: case MIRType::Symbol:
define(new(alloc()) LPointer(ins->toSymbol()), ins); define(new(alloc()) LPointer(ins->toSymbol()), ins);
break; break;
case MIRType::BigInt:
define(new (alloc()) LPointer(ins->toBigInt()), ins);
break;
case MIRType::Object: case MIRType::Object:
define(new(alloc()) LPointer(&ins->toObject()), ins); define(new(alloc()) LPointer(&ins->toObject()), ins);
break; break;

View file

@ -121,6 +121,9 @@ CodeGeneratorX64::visitUnbox(LUnbox* unbox)
case MIRType::Symbol: case MIRType::Symbol:
cond = masm.testSymbol(Assembler::NotEqual, value); cond = masm.testSymbol(Assembler::NotEqual, value);
break; break;
case MIRType::BigInt:
cond = masm.testBigInt(Assembler::NotEqual, value);
break;
default: default:
MOZ_CRASH("Given MIRType cannot be unboxed."); MOZ_CRASH("Given MIRType cannot be unboxed.");
} }
@ -145,6 +148,9 @@ CodeGeneratorX64::visitUnbox(LUnbox* unbox)
case MIRType::Symbol: case MIRType::Symbol:
masm.unboxSymbol(input, result); masm.unboxSymbol(input, result);
break; break;
case MIRType::BigInt:
masm.unboxBigInt(input, result);
break;
default: default:
MOZ_CRASH("Given MIRType cannot be unboxed."); MOZ_CRASH("Given MIRType cannot be unboxed.");
} }

View file

@ -231,6 +231,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
cmp32(tag, ImmTag(JSVAL_TAG_SYMBOL)); cmp32(tag, ImmTag(JSVAL_TAG_SYMBOL));
return cond; return cond;
} }
Condition testBigInt(Condition cond, Register tag) {
MOZ_ASSERT(cond == Equal || cond == NotEqual);
cmp32(tag, ImmTag(JSVAL_TAG_BIGINT));
return cond;
}
Condition testObject(Condition cond, Register tag) { Condition testObject(Condition cond, Register tag) {
MOZ_ASSERT(cond == Equal || cond == NotEqual); MOZ_ASSERT(cond == Equal || cond == NotEqual);
cmp32(tag, ImmTag(JSVAL_TAG_OBJECT)); cmp32(tag, ImmTag(JSVAL_TAG_OBJECT));
@ -306,6 +311,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
splitTag(src, scratch); splitTag(src, scratch);
return testSymbol(cond, scratch); return testSymbol(cond, scratch);
} }
Condition testBigInt(Condition cond, const ValueOperand& src) {
ScratchRegisterScope scratch(asMasm());
splitTag(src, scratch);
return testBigInt(cond, scratch);
}
Condition testObject(Condition cond, const ValueOperand& src) { Condition testObject(Condition cond, const ValueOperand& src) {
ScratchRegisterScope scratch(asMasm()); ScratchRegisterScope scratch(asMasm());
splitTag(src, scratch); splitTag(src, scratch);
@ -359,6 +369,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
splitTag(src, scratch); splitTag(src, scratch);
return testSymbol(cond, scratch); return testSymbol(cond, scratch);
} }
Condition testBigInt(Condition cond, const Address& src) {
ScratchRegisterScope scratch(asMasm());
splitTag(src, scratch);
return testBigInt(cond, scratch);
}
Condition testObject(Condition cond, const Address& src) { Condition testObject(Condition cond, const Address& src) {
ScratchRegisterScope scratch(asMasm()); ScratchRegisterScope scratch(asMasm());
splitTag(src, scratch); splitTag(src, scratch);
@ -406,6 +421,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
splitTag(src, scratch); splitTag(src, scratch);
return testSymbol(cond, scratch); return testSymbol(cond, scratch);
} }
Condition testBigInt(Condition cond, const BaseIndex& src) {
ScratchRegisterScope scratch(asMasm());
splitTag(src, scratch);
return testBigInt(cond, scratch);
}
Condition testInt32(Condition cond, const BaseIndex& src) { Condition testInt32(Condition cond, const BaseIndex& src) {
ScratchRegisterScope scratch(asMasm()); ScratchRegisterScope scratch(asMasm());
splitTag(src, scratch); splitTag(src, scratch);
@ -794,6 +814,9 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
void unboxSymbol(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); } void unboxSymbol(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxSymbol(const Operand& src, Register dest) { unboxNonDouble(src, dest); } void unboxSymbol(const Operand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxBigInt(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxBigInt(const Operand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); } void unboxObject(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const Operand& src, Register dest) { unboxNonDouble(src, dest); } void unboxObject(const Operand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const Address& src, Register dest) { unboxNonDouble(Operand(src), dest); } void unboxObject(const Address& src, Register dest) { unboxNonDouble(Operand(src), dest); }
@ -894,6 +917,13 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
cmp32(Operand(scratch, JSString::offsetOfLength()), Imm32(0)); cmp32(Operand(scratch, JSString::offsetOfLength()), Imm32(0));
return truthy ? Assembler::NotEqual : Assembler::Equal; return truthy ? Assembler::NotEqual : Assembler::Equal;
} }
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;
}
template <typename T> template <typename T>
inline void loadInt32OrDouble(const T& src, FloatRegister dest); inline void loadInt32OrDouble(const T& src, FloatRegister dest);

View file

@ -944,6 +944,30 @@ MacroAssembler::branchTestSymbolImpl(Condition cond, const T& t, Label* label)
j(cond, label); j(cond, label);
} }
void MacroAssembler::branchTestBigInt(Condition cond, Register tag, Label* label) {
branchTestBigIntImpl(cond, tag, label);
}
void MacroAssembler::branchTestBigInt(Condition cond, const BaseIndex& address, Label* label) {
branchTestBigIntImpl(cond, address, label);
}
void MacroAssembler::branchTestBigInt(Condition cond, const ValueOperand& value, Label* label) {
branchTestBigIntImpl(cond, value, label);
}
template <typename T>
void MacroAssembler::branchTestBigIntImpl(Condition cond, const T& t, Label* label) {
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);
}
void void
MacroAssembler::branchTestNull(Condition cond, Register tag, Label* label) MacroAssembler::branchTestNull(Condition cond, Register tag, Label* label)
{ {

View file

@ -294,6 +294,11 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
cmp32(tag, ImmTag(JSVAL_TAG_SYMBOL)); cmp32(tag, ImmTag(JSVAL_TAG_SYMBOL));
return cond; return cond;
} }
Condition testBigInt(Condition cond, Register tag) {
MOZ_ASSERT(cond == Equal || cond == NotEqual);
cmp32(tag, ImmTag(JSVAL_TAG_BIGINT));
return cond;
}
Condition testObject(Condition cond, Register tag) { Condition testObject(Condition cond, Register tag) {
MOZ_ASSERT(cond == Equal || cond == NotEqual); MOZ_ASSERT(cond == Equal || cond == NotEqual);
cmp32(tag, ImmTag(JSVAL_TAG_OBJECT)); cmp32(tag, ImmTag(JSVAL_TAG_OBJECT));
@ -410,6 +415,9 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
Condition testSymbol(Condition cond, const ValueOperand& value) { Condition testSymbol(Condition cond, const ValueOperand& value) {
return testSymbol(cond, value.typeReg()); return testSymbol(cond, value.typeReg());
} }
Condition testBigInt(Condition cond, const ValueOperand& value) {
return testBigInt(cond, value.typeReg());
}
Condition testObject(Condition cond, const ValueOperand& value) { Condition testObject(Condition cond, const ValueOperand& value) {
return testObject(cond, value.typeReg()); return testObject(cond, value.typeReg());
} }
@ -455,6 +463,11 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
cmp32(tagOf(address), ImmTag(JSVAL_TAG_SYMBOL)); cmp32(tagOf(address), ImmTag(JSVAL_TAG_SYMBOL));
return cond; return cond;
} }
Condition testBigInt(Condition cond, const BaseIndex& address) {
MOZ_ASSERT(cond == Equal || cond == NotEqual);
cmp32(tagOf(address), ImmTag(JSVAL_TAG_BIGINT));
return cond;
}
Condition testInt32(Condition cond, const BaseIndex& address) { Condition testInt32(Condition cond, const BaseIndex& address) {
MOZ_ASSERT(cond == Equal || cond == NotEqual); MOZ_ASSERT(cond == Equal || cond == NotEqual);
cmp32(tagOf(address), ImmTag(JSVAL_TAG_INT32)); cmp32(tagOf(address), ImmTag(JSVAL_TAG_INT32));
@ -696,6 +709,8 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
void unboxString(const Address& src, Register dest) { unboxNonDouble(src, dest); } void unboxString(const Address& src, Register dest) { unboxNonDouble(src, dest); }
void unboxSymbol(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); } void unboxSymbol(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxSymbol(const Address& src, Register dest) { unboxNonDouble(src, dest); } void unboxSymbol(const Address& src, Register dest) { unboxNonDouble(src, dest); }
void unboxBigInt(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxBigInt(const Address& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); } void unboxObject(const ValueOperand& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const Address& src, Register dest) { unboxNonDouble(src, dest); } void unboxObject(const Address& src, Register dest) { unboxNonDouble(src, dest); }
void unboxObject(const BaseIndex& src, Register dest) { unboxNonDouble(src, dest); } void unboxObject(const BaseIndex& src, Register dest) { unboxNonDouble(src, dest); }
@ -793,6 +808,12 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
cmp32(Operand(string, JSString::offsetOfLength()), Imm32(0)); cmp32(Operand(string, JSString::offsetOfLength()), Imm32(0));
return truthy ? Assembler::NotEqual : Assembler::Equal; return truthy ? Assembler::NotEqual : Assembler::Equal;
} }
Condition testBigIntTruthy(bool truthy, const ValueOperand& value) {
Register bi = value.payloadReg();
cmpPtr(Operand(bi, BigInt::offsetOfLengthSignAndReservedBits()),
ImmWord(0));
return truthy ? Assembler::NotEqual : Assembler::Equal;
}
template <typename T> template <typename T>
inline void loadInt32OrDouble(const T& src, FloatRegister dest); inline void loadInt32OrDouble(const T& src, FloatRegister dest);

View file

@ -80,6 +80,11 @@ class BigInt final : public js::gc::TenuredCell {
bool isZero() const { return digitLength() == 0; } bool isZero() const { return digitLength() == 0; }
bool isNegative() const { return lengthSignAndReservedBits_ & SignBit; } 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 initializeDigitsToZero();
void traceChildren(JSTracer* trc); void traceChildren(JSTracer* trc);

View file

@ -368,6 +368,8 @@ TypeSet::mightBeMIRType(jit::MIRType type) const
return baseFlags() & TYPE_FLAG_STRING; return baseFlags() & TYPE_FLAG_STRING;
case jit::MIRType::Symbol: case jit::MIRType::Symbol:
return baseFlags() & TYPE_FLAG_SYMBOL; return baseFlags() & TYPE_FLAG_SYMBOL;
case jit::MIRType::BigInt:
return baseFlags() & TYPE_FLAG_BIGINT;
case jit::MIRType::MagicOptimizedArguments: case jit::MIRType::MagicOptimizedArguments:
return baseFlags() & TYPE_FLAG_LAZYARGS; return baseFlags() & TYPE_FLAG_LAZYARGS;
case jit::MIRType::MagicHole: case jit::MIRType::MagicHole:
@ -1635,6 +1637,8 @@ GetMIRTypeFromTypeFlags(TypeFlags flags)
return jit::MIRType::String; return jit::MIRType::String;
case TYPE_FLAG_SYMBOL: case TYPE_FLAG_SYMBOL:
return jit::MIRType::Symbol; return jit::MIRType::Symbol;
case TYPE_FLAG_BIGINT:
return jit::MIRType::BigInt;
case TYPE_FLAG_LAZYARGS: case TYPE_FLAG_LAZYARGS:
return jit::MIRType::MagicOptimizedArguments; return jit::MIRType::MagicOptimizedArguments;
case TYPE_FLAG_ANYOBJECT: case TYPE_FLAG_ANYOBJECT: