mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 23:38:38 +09:00
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:
parent
4aa193b16b
commit
2d5ee3c457
39 changed files with 448 additions and 43 deletions
|
|
@ -1958,6 +1958,7 @@ jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo)
|
|||
case Bailout_NonObjectInput:
|
||||
case Bailout_NonStringInput:
|
||||
case Bailout_NonSymbolInput:
|
||||
case Bailout_NonBigIntInput:
|
||||
case Bailout_UnexpectedSimdInput:
|
||||
case Bailout_NonSharedTypedArrayInput:
|
||||
case Bailout_Debugger:
|
||||
|
|
|
|||
|
|
@ -710,6 +710,9 @@ BaselineCacheIRCompiler::emitGuardType()
|
|||
case JSVAL_TYPE_SYMBOL:
|
||||
masm.branchTestSymbol(Assembler::NotEqual, input, failure->label());
|
||||
break;
|
||||
case JSVAL_TYPE_BIGINT:
|
||||
masm.branchTestBigInt(Assembler::NotEqual, input, failure->label());
|
||||
break;
|
||||
case JSVAL_TYPE_DOUBLE:
|
||||
masm.branchTestNumber(Assembler::NotEqual, input, failure->label());
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -8094,7 +8094,8 @@ ICTypeOf_Typed::Compiler::generateStubCode(MacroAssembler& masm)
|
|||
break;
|
||||
|
||||
case JSTYPE_BIGINT:
|
||||
return false;
|
||||
masm.branchTestBigInt(Assembler::NotEqual, R0, &failure);
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Unexpected type");
|
||||
|
|
|
|||
|
|
@ -446,6 +446,9 @@ GetPropIRGenerator::tryAttachPrimitive(CacheIRWriter& writer, ValOperandId valId
|
|||
} else if (val_.isSymbol()) {
|
||||
primitiveType = JSVAL_TYPE_SYMBOL;
|
||||
proto = MaybeNativeObject(GetBuiltinPrototypePure(cx_->global(), JSProto_Symbol));
|
||||
} else if (val_.isBigInt()) {
|
||||
primitiveType = JSVAL_TYPE_BIGINT;
|
||||
proto = MaybeNativeObject(GetBuiltinPrototypePure(cx_->global(), JSProto_BigInt));
|
||||
} else {
|
||||
MOZ_ASSERT(val_.isNullOrUndefined() || val_.isMagic());
|
||||
return true;
|
||||
|
|
|
|||
|
|
@ -526,9 +526,11 @@ CodeGenerator::testValueTruthyKernel(const ValueOperand& value,
|
|||
bool mightBeString = valueMIR->mightBeType(MIRType::String);
|
||||
bool mightBeSymbol = valueMIR->mightBeType(MIRType::Symbol);
|
||||
bool mightBeDouble = valueMIR->mightBeType(MIRType::Double);
|
||||
bool mightBeBigInt = valueMIR->mightBeType(MIRType::BigInt);
|
||||
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);
|
||||
|
||||
|
|
@ -618,6 +620,20 @@ CodeGenerator::testValueTruthyKernel(const ValueOperand& value,
|
|||
--tagCount;
|
||||
}
|
||||
|
||||
if (mightBeBigInt) {
|
||||
MOZ_ASSERT(tagCount != 0);
|
||||
Label notBigInt;
|
||||
if (tagCount != 1) {
|
||||
masm.branchTestBigInt(Assembler::NotEqual, tag, ¬BigInt);
|
||||
}
|
||||
masm.branchTestBigIntTruthy(false, value, ifFalsy);
|
||||
if (tagCount != 1) {
|
||||
masm.jump(ifTruthy);
|
||||
}
|
||||
masm.bind(¬BigInt);
|
||||
--tagCount;
|
||||
}
|
||||
|
||||
if (mightBeSymbol) {
|
||||
// All symbols are truthy.
|
||||
MOZ_ASSERT(tagCount != 0);
|
||||
|
|
@ -954,8 +970,15 @@ CodeGenerator::visitValueToString(LValueToString* lir)
|
|||
}
|
||||
|
||||
// Symbol
|
||||
if (lir->mir()->input()->mightBeType(MIRType::Symbol))
|
||||
if (lir->mir()->input()->mightBeType(MIRType::Symbol)) {
|
||||
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
|
||||
masm.assumeUnreachable("Unexpected type for MValueToString.");
|
||||
|
|
@ -4902,10 +4925,11 @@ CodeGenerator::branchIfInvalidated(Register temp, Label* invalidated)
|
|||
}
|
||||
|
||||
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 ||
|
||||
type == MIRType::String || type == MIRType::Symbol);
|
||||
type == MIRType::String || type == MIRType::Symbol ||
|
||||
type == MIRType::BigInt);
|
||||
|
||||
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(input);
|
||||
|
|
@ -4960,6 +4984,9 @@ CodeGenerator::emitAssertObjectOrStringResult(Register input, MIRType type, cons
|
|||
case MIRType::Symbol:
|
||||
callee = JS_FUNC_TO_DATA_PTR(void*, AssertValidSymbolPtr);
|
||||
break;
|
||||
case MIRType::BigInt:
|
||||
callee = JS_FUNC_TO_DATA_PTR(void*, AssertValidBigIntPtr);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH();
|
||||
}
|
||||
|
|
@ -5029,7 +5056,7 @@ CodeGenerator::emitAssertResultV(const ValueOperand input, const TemporaryTypeSe
|
|||
|
||||
#ifdef DEBUG
|
||||
void
|
||||
CodeGenerator::emitObjectOrStringResultChecks(LInstruction* lir, MDefinition* mir)
|
||||
CodeGenerator::emitGCThingResultChecks(LInstruction* lir, MDefinition* mir)
|
||||
{
|
||||
if (lir->numDefs() == 0)
|
||||
return;
|
||||
|
|
@ -5037,7 +5064,7 @@ CodeGenerator::emitObjectOrStringResultChecks(LInstruction* lir, MDefinition* mi
|
|||
MOZ_ASSERT(lir->numDefs() == 1);
|
||||
Register output = ToRegister(lir->getDef(0));
|
||||
|
||||
emitAssertObjectOrStringResult(output, mir->type(), mir->resultTypeSet());
|
||||
emitAssertGCThingResult(output, mir->type(), mir->resultTypeSet());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -5069,7 +5096,8 @@ CodeGenerator::emitDebugResultChecks(LInstruction* ins)
|
|||
case MIRType::ObjectOrNull:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
emitObjectOrStringResultChecks(ins, mir);
|
||||
case MIRType::BigInt:
|
||||
emitGCThingResultChecks(ins, mir);
|
||||
break;
|
||||
case MIRType::Value:
|
||||
emitValueResultChecks(ins, mir);
|
||||
|
|
@ -10386,9 +10414,11 @@ CodeGenerator::visitTypeOfV(LTypeOfV* lir)
|
|||
bool testNull = input->mightBeType(MIRType::Null);
|
||||
bool testString = input->mightBeType(MIRType::String);
|
||||
bool testSymbol = input->mightBeType(MIRType::Symbol);
|
||||
bool testBigInt = input->mightBeType(MIRType::BigInt);
|
||||
|
||||
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);
|
||||
|
||||
|
|
@ -10484,6 +10514,19 @@ CodeGenerator::visitTypeOfV(LTypeOfV* lir)
|
|||
numTests--;
|
||||
}
|
||||
|
||||
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--;
|
||||
}
|
||||
|
||||
MOZ_ASSERT(numTests == 0);
|
||||
|
||||
masm.bind(&done);
|
||||
|
|
@ -11794,7 +11837,7 @@ CodeGenerator::visitAssertResultT(LAssertResultT* ins)
|
|||
Register input = ToRegister(ins->input());
|
||||
MDefinition* mir = ins->mirRaw();
|
||||
|
||||
emitAssertObjectOrStringResult(input, mir->type(), mir->resultTypeSet());
|
||||
emitAssertGCThingResult(input, mir->type(), mir->resultTypeSet());
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -431,7 +431,7 @@ class CodeGenerator final : public CodeGeneratorSpecific
|
|||
void visitAssertResultV(LAssertResultV* ins);
|
||||
void visitAssertResultT(LAssertResultT* ins);
|
||||
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 visitOutOfLineInterruptCheckImplicit(OutOfLineInterruptCheckImplicit* ins);
|
||||
|
|
@ -571,7 +571,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
|
||||
|
||||
|
|
|
|||
|
|
@ -2611,6 +2611,7 @@ IsResumableMIRType(MIRType type)
|
|||
case MIRType::Float32:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
case MIRType::BigInt:
|
||||
case MIRType::Object:
|
||||
case MIRType::MagicOptimizedArguments:
|
||||
case MIRType::MagicOptimizedOut:
|
||||
|
|
|
|||
|
|
@ -721,6 +721,9 @@ IonBuilder::analyzeNewLoopTypes(MBasicBlock* entry, jsbytecode* start, jsbytecod
|
|||
case JSOP_NEG:
|
||||
type = inspector->expectedResultType(last);
|
||||
break;
|
||||
case JSOP_BIGINT:
|
||||
type = MIRType::BigInt;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -1347,6 +1350,7 @@ IonBuilder::addOsrValueTypeBarrier(uint32_t slot, MInstruction** def_,
|
|||
case MIRType::Double:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
case MIRType::BigInt:
|
||||
case MIRType::Object:
|
||||
if (type != def->type()) {
|
||||
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
|
||||
// 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;
|
||||
}
|
||||
|
||||
MBitNot* ins = MBitNot::New(alloc(), input);
|
||||
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 !op->mightBeType(MIRType::String)
|
||||
&& !op->mightBeType(MIRType::Symbol)
|
||||
&& !op->mightBeType(MIRType::BigInt)
|
||||
&& !op->mightBeType(MIRType::Double)
|
||||
&& !op->mightBeType(MIRType::Float32)
|
||||
&& !op->mightBeType(MIRType::MagicOptimizedArguments)
|
||||
|
|
@ -8349,6 +8356,10 @@ IonBuilder::testSingletonPropertyTypes(MDefinition* obj, jsid id)
|
|||
key = JSProto_Symbol;
|
||||
break;
|
||||
|
||||
case MIRType::BigInt:
|
||||
key = JSProto_BigInt;
|
||||
break;
|
||||
|
||||
case MIRType::Int32:
|
||||
case MIRType::Double:
|
||||
key = JSProto_Number;
|
||||
|
|
|
|||
|
|
@ -103,6 +103,7 @@ enum BailoutKind
|
|||
Bailout_NonObjectInput,
|
||||
Bailout_NonStringInput,
|
||||
Bailout_NonSymbolInput,
|
||||
Bailout_NonBigIntInput,
|
||||
|
||||
// SIMD Unbox expects a given type, bails out if it doesn't match.
|
||||
Bailout_UnexpectedSimdInput,
|
||||
|
|
@ -212,6 +213,8 @@ BailoutKindString(BailoutKind kind)
|
|||
return "Bailout_NonStringInput";
|
||||
case Bailout_NonSymbolInput:
|
||||
return "Bailout_NonSymbolInput";
|
||||
case Bailout_NonBigIntInput:
|
||||
return "Bailout_NonBigIntInput";
|
||||
case Bailout_UnexpectedSimdInput:
|
||||
return "Bailout_UnexpectedSimdInput";
|
||||
case Bailout_NonSharedTypedArrayInput:
|
||||
|
|
@ -412,6 +415,7 @@ enum class MIRType
|
|||
// Types above have trivial conversion to a number.
|
||||
String,
|
||||
Symbol,
|
||||
BigInt,
|
||||
// Types above are primitive (including undefined and null).
|
||||
Object,
|
||||
MagicOptimizedArguments, // JS_OPTIMIZED_ARGUMENTS magic value.
|
||||
|
|
@ -496,6 +500,8 @@ MIRTypeFromValueType(JSValueType type)
|
|||
return MIRType::String;
|
||||
case JSVAL_TYPE_SYMBOL:
|
||||
return MIRType::Symbol;
|
||||
case JSVAL_TYPE_BIGINT:
|
||||
return MIRType::BigInt;
|
||||
case JSVAL_TYPE_BOOLEAN:
|
||||
return MIRType::Boolean;
|
||||
case JSVAL_TYPE_NULL:
|
||||
|
|
@ -528,6 +534,8 @@ ValueTypeFromMIRType(MIRType type)
|
|||
return JSVAL_TYPE_STRING;
|
||||
case MIRType::Symbol:
|
||||
return JSVAL_TYPE_SYMBOL;
|
||||
case MIRType::BigInt:
|
||||
return JSVAL_TYPE_BIGINT;
|
||||
case MIRType::MagicOptimizedArguments:
|
||||
case MIRType::MagicOptimizedOut:
|
||||
case MIRType::MagicHole:
|
||||
|
|
@ -568,6 +576,8 @@ StringFromMIRType(MIRType type)
|
|||
return "String";
|
||||
case MIRType::Symbol:
|
||||
return "Symbol";
|
||||
case MIRType::BigInt:
|
||||
return "BigInt";
|
||||
case MIRType::Object:
|
||||
return "Object";
|
||||
case MIRType::MagicOptimizedArguments:
|
||||
|
|
|
|||
|
|
@ -599,6 +599,7 @@ class LDefinition
|
|||
return LDefinition::INT32;
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
case MIRType::BigInt:
|
||||
case MIRType::Object:
|
||||
case MIRType::ObjectOrNull:
|
||||
return LDefinition::OBJECT;
|
||||
|
|
|
|||
|
|
@ -717,6 +717,10 @@ LIRGenerator::visitTest(MTest* test)
|
|||
// TestPolicy).
|
||||
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.
|
||||
if (MConstant* constant = opd->maybeConstantValue()) {
|
||||
bool b;
|
||||
|
|
@ -2149,9 +2153,11 @@ LIRGenerator::visitToInt32(MToInt32* convert)
|
|||
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
case MIRType::BigInt:
|
||||
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:
|
||||
|
|
@ -2939,6 +2945,8 @@ LIRGenerator::visitNot(MNot* ins)
|
|||
// String is converted to length of string in the type analysis phase (see
|
||||
// TestPolicy).
|
||||
MOZ_ASSERT(op->type() != MIRType::String);
|
||||
MOZ_ASSERT(op->type() != MIRType::BigInt,
|
||||
"BigInt should be boxed by TestPolicy");
|
||||
|
||||
// - boolean: x xor 1
|
||||
// - int32: LCompare(x, 0)
|
||||
|
|
|
|||
|
|
@ -2894,6 +2894,7 @@ IonBuilder::inlineToInteger(CallInfo& callInfo)
|
|||
if (input->mightBeType(MIRType::Object) ||
|
||||
input->mightBeType(MIRType::String) ||
|
||||
input->mightBeType(MIRType::Symbol) ||
|
||||
input->mightBeType(MIRType::BigInt) ||
|
||||
input->mightBeType(MIRType::Undefined) ||
|
||||
input->mightBeMagicType())
|
||||
{
|
||||
|
|
@ -3021,12 +3022,16 @@ IonBuilder::inlineAtomicsCompareExchange(CallInfo& callInfo)
|
|||
// 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.
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Scalar::Type arrayType;
|
||||
bool requiresCheck = false;
|
||||
|
|
@ -3063,8 +3068,10 @@ IonBuilder::inlineAtomicsExchange(CallInfo& callInfo)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Scalar::Type arrayType;
|
||||
bool requiresCheck = false;
|
||||
|
|
@ -3151,8 +3158,10 @@ IonBuilder::inlineAtomicsStore(CallInfo& callInfo)
|
|||
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;
|
||||
}
|
||||
|
||||
Scalar::Type arrayType;
|
||||
bool requiresCheck = false;
|
||||
|
|
@ -3194,8 +3203,10 @@ IonBuilder::inlineAtomicsBinop(CallInfo& callInfo, InlinableNative target)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
Scalar::Type arrayType;
|
||||
bool requiresCheck = false;
|
||||
|
|
|
|||
|
|
@ -935,6 +935,9 @@ MConstant::MConstant(const js::Value& vp, CompilerConstraintList* constraints)
|
|||
case MIRType::Symbol:
|
||||
payload_.sym = vp.toSymbol();
|
||||
break;
|
||||
case MIRType::BigInt:
|
||||
payload_.bi = vp.toBigInt();
|
||||
break;
|
||||
case MIRType::Object:
|
||||
payload_.obj = &vp.toObject();
|
||||
// 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::Object:
|
||||
case MIRType::Symbol:
|
||||
case MIRType::BigInt:
|
||||
#if MOZ_LITTLE_ENDIAN
|
||||
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;
|
||||
default:
|
||||
MOZ_ASSERT(IsNullOrUndefined(type()) || IsMagicType(type()));
|
||||
|
|
@ -1103,6 +1111,9 @@ MConstant::printOpcode(GenericPrinter& out) const
|
|||
case MIRType::Symbol:
|
||||
out.printf("symbol at %p", (void*)toSymbol());
|
||||
break;
|
||||
case MIRType::BigInt:
|
||||
out.printf("BigInt at %p", (void*)toBigInt());
|
||||
break;
|
||||
case MIRType::String:
|
||||
out.printf("string %p", (void*)toString());
|
||||
break;
|
||||
|
|
@ -1164,6 +1175,8 @@ MConstant::toJSValue() const
|
|||
return StringValue(toString());
|
||||
case MIRType::Symbol:
|
||||
return SymbolValue(toSymbol());
|
||||
case MIRType::BigInt:
|
||||
return BigIntValue(toBigInt());
|
||||
case MIRType::Object:
|
||||
return ObjectValue(toObject());
|
||||
case MIRType::MagicOptimizedArguments:
|
||||
|
|
@ -1207,6 +1220,9 @@ MConstant::valueToBoolean(bool* res) const
|
|||
case MIRType::Symbol:
|
||||
*res = true;
|
||||
return true;
|
||||
case MIRType::BigInt:
|
||||
*res = !toBigInt()->isZero();
|
||||
return true;
|
||||
case MIRType::String:
|
||||
*res = toString()->length() != 0;
|
||||
return true;
|
||||
|
|
@ -2199,6 +2215,7 @@ MUnbox::printOpcode(GenericPrinter& out) const
|
|||
case MIRType::Boolean: out.printf("to Boolean"); break;
|
||||
case MIRType::String: out.printf("to String"); 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;
|
||||
default: break;
|
||||
}
|
||||
|
|
@ -2591,6 +2608,7 @@ jit::TypeSetIncludes(TypeSet* types, MIRType input, TypeSet* inputTypes)
|
|||
case MIRType::Float32:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
case MIRType::BigInt:
|
||||
case MIRType::MagicOptimizedArguments:
|
||||
return types->hasType(TypeSet::PrimitiveType(ValueTypeFromMIRType(input)));
|
||||
|
||||
|
|
@ -2846,7 +2864,8 @@ void
|
|||
MBinaryBitwiseInstruction::infer(BaselineInspector*, jsbytecode*)
|
||||
{
|
||||
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;
|
||||
setResultType(MIRType::Value);
|
||||
|
|
@ -2872,7 +2891,8 @@ 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(0)->mightBeType(MIRType::Symbol) || getOperand(1)->mightBeType(MIRType::Symbol) ||
|
||||
getOperand(0)->mightBeType(MIRType::BigInt) || getOperand(1)->mightBeType(MIRType::BigInt))
|
||||
{
|
||||
specialization_ = MIRType::None;
|
||||
setResultType(MIRType::Value);
|
||||
|
|
@ -2886,7 +2906,8 @@ 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(0)->mightBeType(MIRType::Symbol) || getOperand(1)->mightBeType(MIRType::Symbol) ||
|
||||
getOperand(0)->mightBeType(MIRType::BigInt) || getOperand(1)->mightBeType(MIRType::BigInt))
|
||||
{
|
||||
specialization_ = MIRType::None;
|
||||
setResultType(MIRType::Value);
|
||||
|
|
@ -3880,6 +3901,9 @@ MTypeOf::foldsTo(TempAllocator& alloc)
|
|||
case MIRType::Symbol:
|
||||
type = JSTYPE_SYMBOL;
|
||||
break;
|
||||
case MIRType::BigInt:
|
||||
type = JSTYPE_BIGINT;
|
||||
break;
|
||||
case MIRType::Null:
|
||||
type = JSTYPE_OBJECT;
|
||||
break;
|
||||
|
|
@ -4459,6 +4483,12 @@ MCompare::tryFoldTypeOf(bool* result)
|
|||
*result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE);
|
||||
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)) {
|
||||
if (!typeOf->input()->mightBeType(MIRType::Object) &&
|
||||
!typeOf->input()->mightBeType(MIRType::Null))
|
||||
|
|
@ -5612,6 +5642,8 @@ MConstant::appendRoots(MRootList& roots) const
|
|||
return roots.append(toString());
|
||||
case MIRType::Symbol:
|
||||
return roots.append(toSymbol());
|
||||
case MIRType::BigInt:
|
||||
return roots.append(toBigInt());
|
||||
case MIRType::Object:
|
||||
return roots.append(&toObject());
|
||||
case MIRType::Undefined:
|
||||
|
|
|
|||
|
|
@ -1548,6 +1548,7 @@ class MConstant : public MNullaryInstruction
|
|||
double d;
|
||||
JSString* str;
|
||||
JS::Symbol* sym;
|
||||
BigInt* bi;
|
||||
JSObject* obj;
|
||||
uint64_t asBits;
|
||||
};
|
||||
|
|
@ -1672,6 +1673,10 @@ class MConstant : public MNullaryInstruction
|
|||
MOZ_ASSERT(type() == MIRType::Symbol);
|
||||
return payload_.sym;
|
||||
}
|
||||
BigInt* toBigInt() const {
|
||||
MOZ_ASSERT(type() == MIRType::BigInt);
|
||||
return payload_.bi;
|
||||
}
|
||||
JSObject& toObject() const {
|
||||
MOZ_ASSERT(type() == MIRType::Object);
|
||||
return *payload_.obj;
|
||||
|
|
@ -4743,6 +4748,7 @@ class MUnbox final : public MUnaryInstruction, public BoxInputsPolicy::Data
|
|||
type == MIRType::Double ||
|
||||
type == MIRType::String ||
|
||||
type == MIRType::Symbol ||
|
||||
type == MIRType::BigInt ||
|
||||
type == MIRType::Object);
|
||||
|
||||
TemporaryTypeSet* resultSet = ins->resultTypeSet();
|
||||
|
|
@ -4781,6 +4787,9 @@ class MUnbox final : public MUnaryInstruction, public BoxInputsPolicy::Data
|
|||
case MIRType::Symbol:
|
||||
kind = Bailout_NonSymbolInput;
|
||||
break;
|
||||
case MIRType::BigInt:
|
||||
kind = Bailout_NonBigIntInput;
|
||||
break;
|
||||
case MIRType::Object:
|
||||
kind = Bailout_NonObjectInput;
|
||||
break;
|
||||
|
|
@ -5189,9 +5198,11 @@ class MToDouble
|
|||
setMovable();
|
||||
|
||||
// An object might have "valueOf", which means it is effectful.
|
||||
// ToNumber(symbol) throws.
|
||||
if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol))
|
||||
// ToNumber(symbol) and ToNumber(bigint) throw.
|
||||
if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol) ||
|
||||
def->mightBeType(MIRType::BigInt)) {
|
||||
setGuard();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -5226,11 +5237,15 @@ class MToDouble
|
|||
|
||||
MOZ_MUST_USE bool writeRecoverData(CompactBufferWriter& writer) const override;
|
||||
bool canRecoverOnBailout() const override {
|
||||
if (input()->type() == MIRType::Value)
|
||||
if (input()->type() == MIRType::Value) {
|
||||
return false;
|
||||
if (input()->type() == MIRType::Symbol)
|
||||
}
|
||||
if (input()->type() == MIRType::Symbol) {
|
||||
return false;
|
||||
|
||||
}
|
||||
if (input()->type() == MIRType::BigInt) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -5253,9 +5268,11 @@ class MToFloat32
|
|||
setMovable();
|
||||
|
||||
// An object might have "valueOf", which means it is effectful.
|
||||
// ToNumber(symbol) throws.
|
||||
if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol))
|
||||
// ToNumber(symbol) and ToNumber(BigInt) throw.
|
||||
if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol) ||
|
||||
def->mightBeType(MIRType::BigInt)) {
|
||||
setGuard();
|
||||
}
|
||||
}
|
||||
|
||||
explicit MToFloat32(MDefinition* def, bool mustPreserveNaN)
|
||||
|
|
@ -5537,9 +5554,11 @@ class MToInt32
|
|||
setMovable();
|
||||
|
||||
// An object might have "valueOf", which means it is effectful.
|
||||
// ToNumber(symbol) throws.
|
||||
if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol))
|
||||
// ToInt32(symbol) and ToInt32(BigInt) throw.
|
||||
if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol) ||
|
||||
def->mightBeType(MIRType::BigInt)) {
|
||||
setGuard();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -5594,9 +5613,11 @@ class MTruncateToInt32
|
|||
setMovable();
|
||||
|
||||
// An object might have "valueOf", which means it is effectful.
|
||||
// ToInt32(symbol) throws.
|
||||
if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol))
|
||||
// ToInt32(symbol) and ToInt32(BigInt) throw.
|
||||
if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol) ||
|
||||
def->mightBeType(MIRType::BigInt)) {
|
||||
setGuard();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
@ -5639,9 +5660,12 @@ class MToString :
|
|||
setResultType(MIRType::String);
|
||||
setMovable();
|
||||
|
||||
// Objects might override toString and Symbols throw.
|
||||
if (def->mightBeType(MIRType::Object) || def->mightBeType(MIRType::Symbol))
|
||||
// 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::BigInt)) {
|
||||
setGuard();
|
||||
}
|
||||
}
|
||||
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -545,6 +545,7 @@ MacroAssembler::branchTestMIRType(Condition cond, const Value& val, MIRType type
|
|||
case MIRType::Int32: return branchTestInt32(cond, val, label);
|
||||
case MIRType::String: return branchTestString(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::Double: return branchTestDouble(cond, val, label);
|
||||
case MIRType::MagicOptimizedArguments: // Fall through.
|
||||
|
|
|
|||
|
|
@ -45,12 +45,13 @@ MacroAssembler::guardTypeSet(const Source& address, const TypeSet* types, Barrie
|
|||
MOZ_ASSERT(!types->unknown());
|
||||
|
||||
Label matched;
|
||||
TypeSet::Type tests[8] = {
|
||||
TypeSet::Type tests[9] = {
|
||||
TypeSet::Int32Type(),
|
||||
TypeSet::UndefinedType(),
|
||||
TypeSet::BooleanType(),
|
||||
TypeSet::StringType(),
|
||||
TypeSet::SymbolType(),
|
||||
TypeSet::BigIntType(),
|
||||
TypeSet::NullType(),
|
||||
TypeSet::MagicArgType(),
|
||||
TypeSet::AnyObjectType()
|
||||
|
|
@ -2736,6 +2737,9 @@ MacroAssembler::maybeBranchTestType(MIRType type, MDefinition* maybeDef, Registe
|
|||
case MIRType::Symbol:
|
||||
branchTestSymbol(Equal, tag, label);
|
||||
break;
|
||||
case MIRType::BigInt:
|
||||
branchTestBigInt(Equal, tag, label);
|
||||
break;
|
||||
case MIRType::Object:
|
||||
branchTestObject(Equal, tag, label);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1137,6 +1137,7 @@ class MacroAssembler : public MacroAssemblerSpecific
|
|||
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 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 branchTestObject(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)
|
||||
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 BaseIndex& address, Label* label) PER_SHARED_ARCH;
|
||||
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 branchTestStringTruthy(bool truthy, const ValueOperand& value, Label* label)
|
||||
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:
|
||||
|
||||
|
|
@ -1256,6 +1263,9 @@ class MacroAssembler : public MacroAssemblerSpecific
|
|||
inline void branchTestSymbolImpl(Condition cond, const T& t, Label* label)
|
||||
DEFINED_ON(arm, arm64, x86_shared);
|
||||
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)
|
||||
DEFINED_ON(arm, arm64, x86_shared);
|
||||
template <typename T>
|
||||
|
|
|
|||
|
|
@ -409,6 +409,8 @@ ValTypeToString(JSValueType type)
|
|||
return "string";
|
||||
case JSVAL_TYPE_SYMBOL:
|
||||
return "symbol";
|
||||
case JSVAL_TYPE_BIGINT:
|
||||
return "BigInt";
|
||||
case JSVAL_TYPE_BOOLEAN:
|
||||
return "boolean";
|
||||
case JSVAL_TYPE_OBJECT:
|
||||
|
|
|
|||
|
|
@ -700,7 +700,8 @@ ToDoublePolicy::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins)
|
|||
case MIRType::Object:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
// Objects might be effectful. Symbols give TypeError.
|
||||
case MIRType::BigInt:
|
||||
// Objects might be effectful. Symbols and BigInts give TypeError.
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -748,7 +749,8 @@ ToInt32Policy::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins)
|
|||
case MIRType::Object:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
// Objects might be effectful. Symbols give TypeError.
|
||||
case MIRType::BigInt:
|
||||
// Objects might be effectful. Symbols and BigInts give TypeError.
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -765,7 +767,8 @@ ToStringPolicy::staticAdjustInputs(TempAllocator& alloc, MInstruction* ins)
|
|||
MOZ_ASSERT(ins->isToString());
|
||||
|
||||
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)));
|
||||
return true;
|
||||
}
|
||||
|
|
@ -955,6 +958,7 @@ StoreUnboxedScalarPolicy::adjustValueInput(TempAllocator& alloc, MInstruction* i
|
|||
case MIRType::Object:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
case MIRType::BigInt:
|
||||
value = BoxAt(alloc, ins, value);
|
||||
break;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -1236,15 +1236,27 @@ AssertValidSymbolPtr(JSContext* cx, JS::Symbol* sym)
|
|||
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
|
||||
AssertValidValue(JSContext* cx, Value* v)
|
||||
{
|
||||
if (v->isObject())
|
||||
if (v->isObject()) {
|
||||
AssertValidObjectPtr(cx, &v->toObject());
|
||||
else if (v->isString())
|
||||
} else if (v->isString()) {
|
||||
AssertValidStringPtr(cx, v->toString());
|
||||
else if (v->isSymbol())
|
||||
} else if (v->isSymbol()) {
|
||||
AssertValidSymbolPtr(cx, v->toSymbol());
|
||||
} else if (v->isBigInt()) {
|
||||
AssertValidBigIntPtr(cx, v->toBigInt());
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
|
|
|
|||
|
|
@ -751,6 +751,7 @@ 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);
|
||||
void AssertValidBigIntPtr(JSContext* cx, JS::BigInt* bi);
|
||||
void AssertValidValue(JSContext* cx, Value* v);
|
||||
|
||||
void MarkValueFromIon(JSRuntime* rt, Value* vp);
|
||||
|
|
|
|||
|
|
@ -1880,6 +1880,29 @@ MacroAssembler::branchTestSymbolImpl(Condition cond, const T& t, Label* label)
|
|||
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
|
||||
MacroAssembler::branchTestNull(Condition cond, Register tag, Label* label)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2717,6 +2717,11 @@ MacroAssemblerARMCompat::testSymbol(Assembler::Condition cond, const ValueOperan
|
|||
return testSymbol(cond, value.typeReg());
|
||||
}
|
||||
|
||||
Assembler::Condition MacroAssemblerARMCompat::testBigInt(Assembler::Condition cond, const ValueOperand& value)
|
||||
{
|
||||
return testBigInt(cond, value.typeReg());
|
||||
}
|
||||
|
||||
Assembler::Condition
|
||||
MacroAssemblerARMCompat::testObject(Assembler::Condition cond, const ValueOperand& value)
|
||||
{
|
||||
|
|
@ -2790,6 +2795,13 @@ MacroAssemblerARMCompat::testSymbol(Assembler::Condition cond, Register tag)
|
|||
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
|
||||
MacroAssemblerARMCompat::testObject(Assembler::Condition cond, Register tag)
|
||||
{
|
||||
|
|
@ -2907,6 +2919,14 @@ MacroAssemblerARMCompat::testObject(Condition cond, const Address& address)
|
|||
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
|
||||
MacroAssemblerARMCompat::testNumber(Condition cond, const Address& address)
|
||||
{
|
||||
|
|
@ -2993,6 +3013,16 @@ MacroAssemblerARMCompat::testInt32(Condition cond, const BaseIndex& src)
|
|||
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
|
||||
MacroAssemblerARMCompat::testObject(Condition cond, const BaseIndex& src)
|
||||
{
|
||||
|
|
@ -3736,6 +3766,19 @@ MacroAssemblerARMCompat::testStringTruthy(bool truthy, const ValueOperand& value
|
|||
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
|
||||
MacroAssemblerARMCompat::floor(FloatRegister input, Register output, Label* bail)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -695,6 +695,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
|||
Condition testUndefined(Condition cond, const ValueOperand& value);
|
||||
Condition testString(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 testNumber(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 testString(Condition cond, Register tag);
|
||||
Condition testSymbol(Condition cond, Register tag);
|
||||
Condition testBigInt(Condition cond, Register tag);
|
||||
Condition testObject(Condition cond, Register tag);
|
||||
Condition testDouble(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 testString(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 testNumber(Condition cond, const Address& address);
|
||||
|
||||
|
|
@ -731,6 +734,7 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM
|
|||
Condition testBoolean(Condition cond, const BaseIndex& src);
|
||||
Condition testString(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 testObject(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 unboxSymbol(const ValueOperand& 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 Address& 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 testDoubleTruthy(bool truthy, FloatRegister reg);
|
||||
Condition testStringTruthy(bool truthy, const ValueOperand& value);
|
||||
Condition testBigIntTruthy(bool truthy, const ValueOperand& value);
|
||||
|
||||
void boolValueToFloat32(const ValueOperand& operand, FloatRegister dest);
|
||||
void int32ValueToFloat32(const ValueOperand& operand, FloatRegister dest);
|
||||
|
|
|
|||
|
|
@ -963,6 +963,19 @@ MacroAssembler::branchTestSymbol(Condition cond, const ValueOperand& value, Labe
|
|||
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
|
||||
MacroAssembler::branchTestNull(Condition cond, const ValueOperand& value, Label* label)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -196,6 +196,9 @@ CodeGeneratorMIPS64::visitUnbox(LUnbox* unbox)
|
|||
case MIRType::Symbol:
|
||||
masm.unboxSymbol(inputReg, result);
|
||||
break;
|
||||
case MIRType::BigInt:
|
||||
masm.unboxBigInt(inputReg, result);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Given MIRType cannot be unboxed.");
|
||||
}
|
||||
|
|
@ -219,6 +222,9 @@ CodeGeneratorMIPS64::visitUnbox(LUnbox* unbox)
|
|||
case MIRType::Symbol:
|
||||
masm.unboxSymbol(inputAddr, result);
|
||||
break;
|
||||
case MIRType::BigInt:
|
||||
masm.unboxBigInt(inputAddr, result);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Given MIRType cannot be unboxed.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -622,6 +622,21 @@ MacroAssembler::branchTestSymbol(Condition cond, const ValueOperand& value, Labe
|
|||
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
|
||||
MacroAssembler::branchTestNull(Condition cond, const ValueOperand& value, Label* label)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1495,6 +1495,21 @@ MacroAssemblerMIPS64Compat::unboxSymbol(Register src, Register dest)
|
|||
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
|
||||
MacroAssemblerMIPS64Compat::unboxSymbol(const Address& src, Register dest)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -361,6 +361,9 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64
|
|||
void unboxSymbol(const ValueOperand& src, Register dest);
|
||||
void unboxSymbol(Register 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(Register src, Register dest);
|
||||
void unboxObject(const Address& src, Register dest);
|
||||
|
|
|
|||
|
|
@ -359,6 +359,7 @@ class MacroAssemblerNone : public Assembler
|
|||
template <typename T> void unboxBoolean(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 unboxBigInt(T, Register) { MOZ_CRASH(); }
|
||||
template <typename T> void unboxObject(T, Register) { MOZ_CRASH(); }
|
||||
template <typename T> void unboxDouble(T, FloatRegister) { MOZ_CRASH(); }
|
||||
void unboxValue(const ValueOperand&, AnyRegister) { MOZ_CRASH(); }
|
||||
|
|
@ -393,6 +394,7 @@ class MacroAssemblerNone : public Assembler
|
|||
void loadConstantFloat32(wasm::RawF32, FloatRegister) { MOZ_CRASH(); }
|
||||
Condition testInt32Truthy(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 storeUnboxedValue(const ConstantOrRegister&, MIRType, T, MIRType) { MOZ_CRASH(); }
|
||||
|
|
|
|||
|
|
@ -431,6 +431,7 @@ CodeGeneratorShared::encodeAllocation(LSnapshot* snapshot, MDefinition* mir,
|
|||
case MIRType::Int32:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol:
|
||||
case MIRType::BigInt:
|
||||
case MIRType::Object:
|
||||
case MIRType::ObjectOrNull:
|
||||
case MIRType::Boolean:
|
||||
|
|
|
|||
|
|
@ -402,7 +402,8 @@ LIRGeneratorShared::redefine(MDefinition* def, MDefinition* as)
|
|||
case MIRType::Object:
|
||||
case MIRType::ObjectOrNull:
|
||||
case MIRType::String:
|
||||
case MIRType::Symbol: {
|
||||
case MIRType::Symbol:
|
||||
case MIRType::BigInt: {
|
||||
LAssertResultT* check = new(alloc()) LAssertResultT(useRegister(def));
|
||||
add(check, def->toInstruction());
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -100,6 +100,9 @@ LIRGeneratorShared::visitConstant(MConstant* ins)
|
|||
case MIRType::Symbol:
|
||||
define(new(alloc()) LPointer(ins->toSymbol()), ins);
|
||||
break;
|
||||
case MIRType::BigInt:
|
||||
define(new (alloc()) LPointer(ins->toBigInt()), ins);
|
||||
break;
|
||||
case MIRType::Object:
|
||||
define(new(alloc()) LPointer(&ins->toObject()), ins);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -121,6 +121,9 @@ CodeGeneratorX64::visitUnbox(LUnbox* unbox)
|
|||
case MIRType::Symbol:
|
||||
cond = masm.testSymbol(Assembler::NotEqual, value);
|
||||
break;
|
||||
case MIRType::BigInt:
|
||||
cond = masm.testBigInt(Assembler::NotEqual, value);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Given MIRType cannot be unboxed.");
|
||||
}
|
||||
|
|
@ -145,6 +148,9 @@ CodeGeneratorX64::visitUnbox(LUnbox* unbox)
|
|||
case MIRType::Symbol:
|
||||
masm.unboxSymbol(input, result);
|
||||
break;
|
||||
case MIRType::BigInt:
|
||||
masm.unboxBigInt(input, result);
|
||||
break;
|
||||
default:
|
||||
MOZ_CRASH("Given MIRType cannot be unboxed.");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -231,6 +231,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
|||
cmp32(tag, ImmTag(JSVAL_TAG_SYMBOL));
|
||||
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) {
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
cmp32(tag, ImmTag(JSVAL_TAG_OBJECT));
|
||||
|
|
@ -306,6 +311,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
|||
splitTag(src, 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) {
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
splitTag(src, scratch);
|
||||
|
|
@ -359,6 +369,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
|||
splitTag(src, 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) {
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
splitTag(src, scratch);
|
||||
|
|
@ -406,6 +421,11 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
|||
splitTag(src, 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) {
|
||||
ScratchRegisterScope scratch(asMasm());
|
||||
splitTag(src, scratch);
|
||||
|
|
@ -794,6 +814,9 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
|
|||
void unboxSymbol(const ValueOperand& 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 Operand& src, Register dest) { unboxNonDouble(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));
|
||||
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>
|
||||
inline void loadInt32OrDouble(const T& src, FloatRegister dest);
|
||||
|
|
|
|||
|
|
@ -944,6 +944,30 @@ MacroAssembler::branchTestSymbolImpl(Condition cond, const T& t, Label* 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
|
||||
MacroAssembler::branchTestNull(Condition cond, Register tag, Label* label)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -294,6 +294,11 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
|||
cmp32(tag, ImmTag(JSVAL_TAG_SYMBOL));
|
||||
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) {
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
cmp32(tag, ImmTag(JSVAL_TAG_OBJECT));
|
||||
|
|
@ -410,6 +415,9 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
|||
Condition testSymbol(Condition cond, const ValueOperand& value) {
|
||||
return testSymbol(cond, value.typeReg());
|
||||
}
|
||||
Condition testBigInt(Condition cond, const ValueOperand& value) {
|
||||
return testBigInt(cond, value.typeReg());
|
||||
}
|
||||
Condition testObject(Condition cond, const ValueOperand& value) {
|
||||
return testObject(cond, value.typeReg());
|
||||
}
|
||||
|
|
@ -455,6 +463,11 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared
|
|||
cmp32(tagOf(address), ImmTag(JSVAL_TAG_SYMBOL));
|
||||
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) {
|
||||
MOZ_ASSERT(cond == Equal || cond == NotEqual);
|
||||
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 unboxSymbol(const ValueOperand& 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 Address& 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));
|
||||
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>
|
||||
inline void loadInt32OrDouble(const T& src, FloatRegister dest);
|
||||
|
|
|
|||
|
|
@ -80,6 +80,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);
|
||||
|
|
|
|||
|
|
@ -368,6 +368,8 @@ TypeSet::mightBeMIRType(jit::MIRType type) const
|
|||
return baseFlags() & TYPE_FLAG_STRING;
|
||||
case jit::MIRType::Symbol:
|
||||
return baseFlags() & TYPE_FLAG_SYMBOL;
|
||||
case jit::MIRType::BigInt:
|
||||
return baseFlags() & TYPE_FLAG_BIGINT;
|
||||
case jit::MIRType::MagicOptimizedArguments:
|
||||
return baseFlags() & TYPE_FLAG_LAZYARGS;
|
||||
case jit::MIRType::MagicHole:
|
||||
|
|
@ -1635,6 +1637,8 @@ GetMIRTypeFromTypeFlags(TypeFlags flags)
|
|||
return jit::MIRType::String;
|
||||
case TYPE_FLAG_SYMBOL:
|
||||
return jit::MIRType::Symbol;
|
||||
case TYPE_FLAG_BIGINT:
|
||||
return jit::MIRType::BigInt;
|
||||
case TYPE_FLAG_LAZYARGS:
|
||||
return jit::MIRType::MagicOptimizedArguments;
|
||||
case TYPE_FLAG_ANYOBJECT:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue