Bug 1507484 - Implement minimal Ion support for BigInt r=wingo,jandem

Co-authored-by: Andy Wingo <wingo@igalia.com>

Differential Revision: https://phabricator.services.mozilla.com/D14826

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Robin Templeton 2019-02-05 23:19:44 +00:00
Родитель 587bc41d36
Коммит e11487a677
37 изменённых файлов: 477 добавлений и 45 удалений

Просмотреть файл

@ -2183,6 +2183,9 @@ bool jit::FinishBailoutToBaseline(BaselineBailoutInfo* bailoutInfo) {
case Bailout_NonObjectInput:
case Bailout_NonStringInput:
case Bailout_NonSymbolInput:
#ifdef ENABLE_BIGINT
case Bailout_NonBigIntInput:
#endif
case Bailout_NonSharedTypedArrayInput:
case Bailout_Debugger:
case Bailout_UninitializedThis:

Просмотреть файл

@ -786,9 +786,11 @@ void CodeGenerator::testValueTruthyKernel(
bool mightBeString = valueMIR->mightBeType(MIRType::String);
bool mightBeSymbol = valueMIR->mightBeType(MIRType::Symbol);
bool mightBeDouble = valueMIR->mightBeType(MIRType::Double);
bool mightBeBigInt = IF_BIGINT(valueMIR->mightBeType(MIRType::BigInt), false);
int tagCount = int(mightBeUndefined) + int(mightBeNull) +
int(mightBeBoolean) + int(mightBeInt32) + int(mightBeObject) +
int(mightBeString) + int(mightBeSymbol) + int(mightBeDouble);
int(mightBeString) + int(mightBeSymbol) + int(mightBeDouble) +
int(mightBeBigInt);
MOZ_ASSERT_IF(!valueMIR->emptyResultTypeSet(), tagCount > 0);
@ -902,6 +904,25 @@ void CodeGenerator::testValueTruthyKernel(
--tagCount;
}
#ifdef ENABLE_BIGINT
if (mightBeBigInt) {
MOZ_ASSERT(tagCount != 0);
Label notBigInt;
if (tagCount != 1) {
masm.branchTestBigInt(Assembler::NotEqual, tag, &notBigInt);
}
{
ScratchTagScopeRelease _(&tag);
masm.branchTestBigIntTruthy(false, value, ifFalsy);
}
if (tagCount != 1) {
masm.jump(ifTruthy);
}
masm.bind(&notBigInt);
--tagCount;
}
#endif
if (mightBeSymbol) {
// All symbols are truthy.
MOZ_ASSERT(tagCount != 0);
@ -1244,6 +1265,14 @@ void CodeGenerator::visitValueToString(LValueToString* lir) {
bailoutFrom(&bail, lir->snapshot());
}
#ifdef ENABLE_BIGINT
// BigInt
if (lir->mir()->input()->mightBeType(MIRType::BigInt)) {
// No fastpath currently implemented.
masm.branchTestBigInt(Assembler::Equal, tag, ool->entry());
}
#endif
#ifdef DEBUG
masm.assumeUnreachable("Unexpected type for MValueToString.");
#endif
@ -5598,10 +5627,11 @@ void CodeGenerator::branchIfInvalidated(Register temp, Label* invalidated) {
}
#ifdef DEBUG
void CodeGenerator::emitAssertObjectOrStringResult(
Register input, MIRType type, const TemporaryTypeSet* typeset) {
void CodeGenerator::emitAssertGCThingResult(Register input, MIRType type,
const TemporaryTypeSet* typeset) {
MOZ_ASSERT(type == MIRType::Object || type == MIRType::ObjectOrNull ||
type == MIRType::String || type == MIRType::Symbol);
type == MIRType::String || type == MIRType::Symbol ||
IF_BIGINT(type == MIRType::BigInt, false));
AllocatableGeneralRegisterSet regs(GeneralRegisterSet::All());
regs.take(input);
@ -5659,6 +5689,11 @@ void CodeGenerator::emitAssertObjectOrStringResult(
case MIRType::Symbol:
callee = JS_FUNC_TO_DATA_PTR(void*, AssertValidSymbolPtr);
break;
# ifdef ENABLE_BIGINT
case MIRType::BigInt:
callee = JS_FUNC_TO_DATA_PTR(void*, AssertValidBigIntPtr);
break;
# endif
default:
MOZ_CRASH();
}
@ -5730,8 +5765,8 @@ void CodeGenerator::emitAssertResultV(const ValueOperand input,
masm.pop(temp1);
}
void CodeGenerator::emitObjectOrStringResultChecks(LInstruction* lir,
MDefinition* mir) {
void CodeGenerator::emitGCThingResultChecks(LInstruction* lir,
MDefinition* mir) {
if (lir->numDefs() == 0) {
return;
}
@ -5742,7 +5777,7 @@ void CodeGenerator::emitObjectOrStringResultChecks(LInstruction* lir,
}
Register output = ToRegister(lir->getDef(0));
emitAssertObjectOrStringResult(output, mir->type(), mir->resultTypeSet());
emitAssertGCThingResult(output, mir->type(), mir->resultTypeSet());
}
void CodeGenerator::emitValueResultChecks(LInstruction* lir, MDefinition* mir) {
@ -5773,7 +5808,10 @@ void CodeGenerator::emitDebugResultChecks(LInstruction* ins) {
case MIRType::ObjectOrNull:
case MIRType::String:
case MIRType::Symbol:
emitObjectOrStringResultChecks(ins, mir);
# ifdef ENABLE_BIGINT
case MIRType::BigInt:
# endif
emitGCThingResultChecks(ins, mir);
break;
case MIRType::Value:
emitValueResultChecks(ins, mir);
@ -11162,11 +11200,14 @@ void CodeGenerator::visitTypeOfV(LTypeOfV* lir) {
bool testNull = input->mightBeType(MIRType::Null);
bool testString = input->mightBeType(MIRType::String);
bool testSymbol = input->mightBeType(MIRType::Symbol);
#ifdef ENABLE_BIGINT
bool testBigInt = input->mightBeType(MIRType::BigInt);
#endif
unsigned numTests = unsigned(testObject) + unsigned(testNumber) +
unsigned(testBoolean) + unsigned(testUndefined) +
unsigned(testNull) + unsigned(testString) +
unsigned(testSymbol);
unsigned(testSymbol) + unsigned(IF_BIGINT(testBigInt, 0));
MOZ_ASSERT_IF(!input->emptyResultTypeSet(), numTests > 0);
@ -11277,6 +11318,21 @@ void CodeGenerator::visitTypeOfV(LTypeOfV* lir) {
numTests--;
}
#ifdef ENABLE_BIGINT
if (testBigInt) {
Label notBigInt;
if (numTests > 1) {
masm.branchTestBigInt(Assembler::NotEqual, tag, &notBigInt);
}
masm.movePtr(ImmGCPtr(names.bigint), output);
if (numTests > 1) {
masm.jump(&done);
}
masm.bind(&notBigInt);
numTests--;
}
#endif
MOZ_ASSERT(numTests == 0);
masm.bind(&done);
@ -12874,7 +12930,7 @@ void CodeGenerator::visitAssertResultT(LAssertResultT* ins) {
#ifdef DEBUG
Register input = ToRegister(ins->input());
MDefinition* mir = ins->mirRaw();
emitAssertObjectOrStringResult(input, mir->type(), mir->resultTypeSet());
emitAssertGCThingResult(input, mir->type(), mir->resultTypeSet());
#else
MOZ_CRASH("LAssertResultT is debug only");
#endif

Просмотреть файл

@ -193,8 +193,8 @@ class CodeGenerator final : public CodeGeneratorSpecific {
#ifdef DEBUG
void emitAssertResultV(const ValueOperand output,
const TemporaryTypeSet* typeset);
void emitAssertObjectOrStringResult(Register input, MIRType type,
const TemporaryTypeSet* typeset);
void emitAssertGCThingResult(Register input, MIRType type,
const TemporaryTypeSet* typeset);
#endif
#ifdef DEBUG
@ -314,7 +314,7 @@ class CodeGenerator final : public CodeGeneratorSpecific {
#ifdef DEBUG
void emitDebugResultChecks(LInstruction* ins);
void emitObjectOrStringResultChecks(LInstruction* lir, MDefinition* mir);
void emitGCThingResultChecks(LInstruction* lir, MDefinition* mir);
void emitValueResultChecks(LInstruction* lir, MDefinition* mir);
#endif

Просмотреть файл

@ -2344,7 +2344,8 @@ static bool CanCompareRegExp(MCompare* compare, MDefinition* def) {
value->mightBeType(MIRType::Int32) ||
value->mightBeType(MIRType::Double) ||
value->mightBeType(MIRType::Float32) ||
value->mightBeType(MIRType::Symbol)) {
value->mightBeType(MIRType::Symbol) ||
IF_BIGINT(value->mightBeType(MIRType::BigInt), false)) {
return false;
}
@ -3176,6 +3177,9 @@ static bool IsResumableMIRType(MIRType type) {
case MIRType::Float32:
case MIRType::String:
case MIRType::Symbol:
# ifdef ENABLE_BIGINT
case MIRType::BigInt:
# endif
case MIRType::Object:
case MIRType::MagicOptimizedArguments:
case MIRType::MagicOptimizedOut:

Просмотреть файл

@ -717,6 +717,11 @@ AbortReasonOr<Ok> IonBuilder::analyzeNewLoopTypes(
case JSOP_DEC:
type = inspector->expectedResultType(last);
break;
#ifdef ENABLE_BIGINT
case JSOP_BIGINT:
type = MIRType::BigInt;
break;
#endif
default:
break;
}
@ -1337,6 +1342,9 @@ AbortReasonOr<Ok> IonBuilder::addOsrValueTypeBarrier(
case MIRType::Double:
case MIRType::String:
case MIRType::Symbol:
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
#endif
case MIRType::Object:
if (type != def->type()) {
MUnbox* unbox = MUnbox::New(alloc(), def, type, MUnbox::Fallible);
@ -3349,7 +3357,8 @@ AbortReasonOr<Ok> IonBuilder::bitnotTrySpecialized(bool* emitted,
// of the operand.
if (input->mightBeType(MIRType::Object) ||
input->mightBeType(MIRType::Symbol)) {
input->mightBeType(MIRType::Symbol) ||
IF_BIGINT(input->mightBeType(MIRType::BigInt), false)) {
return Ok();
}
@ -6210,6 +6219,7 @@ static bool ObjectOrSimplePrimitive(MDefinition* op) {
// Return true if op is either undefined/null/boolean/int32/symbol or an
// object.
return !op->mightBeType(MIRType::String) &&
IF_BIGINT(!op->mightBeType(MIRType::BigInt), true) &&
!op->mightBeType(MIRType::Double) &&
!op->mightBeType(MIRType::Float32) &&
!op->mightBeType(MIRType::MagicOptimizedArguments) &&
@ -7460,6 +7470,12 @@ JSObject* IonBuilder::testSingletonPropertyTypes(MDefinition* obj, jsid id) {
key = JSProto_Symbol;
break;
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
key = JSProto_BigInt;
break;
#endif
case MIRType::Int32:
case MIRType::Double:
key = JSProto_Number;

Просмотреть файл

@ -124,6 +124,9 @@ enum BailoutKind {
Bailout_NonObjectInput,
Bailout_NonStringInput,
Bailout_NonSymbolInput,
#ifdef ENABLE_BIGINT
Bailout_NonBigIntInput,
#endif
// Atomic operations require shared memory, bail out if the typed array
// maps unshared memory.
@ -223,6 +226,10 @@ inline const char* BailoutKindString(BailoutKind kind) {
return "Bailout_NonStringInput";
case Bailout_NonSymbolInput:
return "Bailout_NonSymbolInput";
#ifdef ENABLE_BIGINT
case Bailout_NonBigIntInput:
return "Bailout_NonBigIntInput";
#endif
case Bailout_NonSharedTypedArrayInput:
return "Bailout_NonSharedTypedArrayInput";
case Bailout_Debugger:
@ -441,6 +448,9 @@ enum class MIRType : uint8_t {
// Types above have trivial conversion to a number.
String,
Symbol,
#ifdef ENABLE_BIGINT
BigInt,
#endif
// Types above are primitive (including undefined and null).
Object,
MagicOptimizedArguments, // JS_OPTIMIZED_ARGUMENTS magic value.
@ -488,6 +498,10 @@ static inline MIRType MIRTypeFromValueType(JSValueType type) {
return MIRType::String;
case JSVAL_TYPE_SYMBOL:
return MIRType::Symbol;
#ifdef ENABLE_BIGINT
case JSVAL_TYPE_BIGINT:
return MIRType::BigInt;
#endif
case JSVAL_TYPE_BOOLEAN:
return MIRType::Boolean;
case JSVAL_TYPE_NULL:
@ -518,6 +532,10 @@ static inline JSValueType ValueTypeFromMIRType(MIRType type) {
return JSVAL_TYPE_STRING;
case MIRType::Symbol:
return JSVAL_TYPE_SYMBOL;
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
return JSVAL_TYPE_BIGINT;
#endif
case MIRType::MagicOptimizedArguments:
case MIRType::MagicOptimizedOut:
case MIRType::MagicHole:
@ -571,6 +589,10 @@ static inline const char* StringFromMIRType(MIRType type) {
return "String";
case MIRType::Symbol:
return "Symbol";
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
return "BigInt";
#endif
case MIRType::Object:
return "Object";
case MIRType::MagicOptimizedArguments:

Просмотреть файл

@ -525,6 +525,9 @@ class LDefinition {
return LDefinition::INT32;
case MIRType::String:
case MIRType::Symbol:
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
#endif
case MIRType::Object:
case MIRType::ObjectOrNull:
return LDefinition::OBJECT;

Просмотреть файл

@ -590,6 +590,12 @@ void LIRGenerator::visitTest(MTest* test) {
// TestPolicy).
MOZ_ASSERT(opd->type() != MIRType::String);
#ifdef ENABLE_BIGINT
// BigInt is boxed in type analysis.
MOZ_ASSERT(opd->type() != MIRType::BigInt,
"BigInt should be boxed by TestPolicy");
#endif
// Testing a constant.
if (MConstant* constant = opd->maybeConstantValue()) {
bool b;
@ -2090,10 +2096,13 @@ void LIRGenerator::visitToNumberInt32(MToNumberInt32* convert) {
case MIRType::String:
case MIRType::Symbol:
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
#endif
case MIRType::Object:
case MIRType::Undefined:
// Objects might be effectful. Symbols throw. Undefined coerces to NaN,
// not int32.
// Objects might be effectful. Symbols and BigInts throw. Undefined
// coerces to NaN, not int32.
MOZ_CRASH("ToInt32 invalid input type");
default:
@ -2876,6 +2885,10 @@ void LIRGenerator::visitNot(MNot* ins) {
// String is converted to length of string in the type analysis phase (see
// TestPolicy).
MOZ_ASSERT(op->type() != MIRType::String);
#ifdef ENABLE_BIGINT
MOZ_ASSERT(op->type() != MIRType::BigInt,
"BigInt should be boxed by TestPolicy");
#endif
// - boolean: x xor 1
// - int32: LCompare(x, 0)
@ -4671,6 +4684,11 @@ void LIRGenerator::visitConstant(MConstant* ins) {
case MIRType::Symbol:
define(new (alloc()) LPointer(ins->toSymbol()), ins);
break;
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
define(new (alloc()) LPointer(ins->toBigInt()), ins);
break;
#endif
case MIRType::Object:
define(new (alloc()) LPointer(&ins->toObject()), ins);
break;

Просмотреть файл

@ -2119,10 +2119,11 @@ IonBuilder::InliningResult IonBuilder::inlineStrFromCharCode(
MDefinition* codeUnit = callInfo.getArg(0);
if (codeUnit->type() != MIRType::Int32) {
// MTruncateToInt32 will always bail for objects and symbols, so don't
// try to inline String.fromCharCode() for these two value types.
// MTruncateToInt32 will always bail for objects, symbols and BigInts, so
// don't try to inline String.fromCharCode() for these value types.
if (codeUnit->mightBeType(MIRType::Object) ||
codeUnit->mightBeType(MIRType::Symbol)) {
codeUnit->mightBeType(MIRType::Symbol) ||
IF_BIGINT(codeUnit->mightBeType(MIRType::BigInt), false)) {
return InliningStatus_NotInlined;
}
@ -3537,6 +3538,7 @@ IonBuilder::InliningResult IonBuilder::inlineToInteger(CallInfo& callInfo) {
if (input->mightBeType(MIRType::Object) ||
input->mightBeType(MIRType::String) ||
input->mightBeType(MIRType::Symbol) ||
IF_BIGINT(input->mightBeType(MIRType::BigInt), false) ||
input->mightBeType(MIRType::Undefined) || input->mightBeMagicType()) {
return InliningStatus_NotInlined;
}
@ -3661,13 +3663,15 @@ IonBuilder::InliningResult IonBuilder::inlineAtomicsCompareExchange(
// https://bugzilla.mozilla.org/show_bug.cgi?id=1141986#c20.
MDefinition* oldval = callInfo.getArg(2);
if (oldval->mightBeType(MIRType::Object) ||
oldval->mightBeType(MIRType::Symbol)) {
oldval->mightBeType(MIRType::Symbol) ||
IF_BIGINT(oldval->mightBeType(MIRType::BigInt), false)) {
return InliningStatus_NotInlined;
}
MDefinition* newval = callInfo.getArg(3);
if (newval->mightBeType(MIRType::Object) ||
newval->mightBeType(MIRType::Symbol)) {
newval->mightBeType(MIRType::Symbol) ||
IF_BIGINT(newval->mightBeType(MIRType::BigInt), false)) {
return InliningStatus_NotInlined;
}
@ -3707,7 +3711,8 @@ IonBuilder::InliningResult IonBuilder::inlineAtomicsExchange(
MDefinition* value = callInfo.getArg(2);
if (value->mightBeType(MIRType::Object) ||
value->mightBeType(MIRType::Symbol)) {
value->mightBeType(MIRType::Symbol) ||
IF_BIGINT(value->mightBeType(MIRType::BigInt), false)) {
return InliningStatus_NotInlined;
}
@ -3792,7 +3797,8 @@ IonBuilder::InliningResult IonBuilder::inlineAtomicsStore(CallInfo& callInfo) {
}
if (value->mightBeType(MIRType::Object) ||
value->mightBeType(MIRType::Symbol)) {
value->mightBeType(MIRType::Symbol) ||
IF_BIGINT(value->mightBeType(MIRType::BigInt), false)) {
return InliningStatus_NotInlined;
}
@ -3837,7 +3843,8 @@ IonBuilder::InliningResult IonBuilder::inlineAtomicsBinop(
MDefinition* value = callInfo.getArg(2);
if (value->mightBeType(MIRType::Object) ||
value->mightBeType(MIRType::Symbol)) {
value->mightBeType(MIRType::Symbol) ||
IF_BIGINT(value->mightBeType(MIRType::BigInt), false)) {
return InliningStatus_NotInlined;
}

Просмотреть файл

@ -966,6 +966,11 @@ MConstant::MConstant(TempAllocator& alloc, const js::Value& vp,
case MIRType::Symbol:
payload_.sym = vp.toSymbol();
break;
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
payload_.bi = vp.toBigInt();
break;
#endif
case MIRType::Object:
payload_.obj = &vp.toObject();
// Create a singleton type set for the object. This isn't necessary for
@ -1043,6 +1048,9 @@ void MConstant::assertInitializedPayload() const {
case MIRType::String:
case MIRType::Object:
case MIRType::Symbol:
# ifdef ENABLE_BIGINT
case MIRType::BigInt:
# endif
# if MOZ_LITTLE_ENDIAN
MOZ_ASSERT_IF(JS_BITS_PER_WORD == 32, (payload_.asBits >> 32) == 0);
# else
@ -1134,6 +1142,11 @@ void MConstant::printOpcode(GenericPrinter& out) const {
case MIRType::Symbol:
out.printf("symbol at %p", (void*)toSymbol());
break;
# ifdef ENABLE_BIGINT
case MIRType::BigInt:
out.printf("BigInt at %p", (void*)toBigInt());
break;
# endif
case MIRType::String:
out.printf("string %p", (void*)toString());
break;
@ -1195,6 +1208,10 @@ Value MConstant::toJSValue() const {
return StringValue(toString());
case MIRType::Symbol:
return SymbolValue(toSymbol());
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
return BigIntValue(toBigInt());
#endif
case MIRType::Object:
return ObjectValue(toObject());
case MIRType::MagicOptimizedArguments:
@ -1236,6 +1253,11 @@ bool MConstant::valueToBoolean(bool* res) const {
case MIRType::Symbol:
*res = true;
return true;
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
*res = !toBigInt()->isZero();
return true;
#endif
case MIRType::String:
*res = toString()->length() != 0;
return true;
@ -1777,6 +1799,11 @@ void MUnbox::printOpcode(GenericPrinter& out) const {
case MIRType::Symbol:
out.printf("to Symbol");
break;
# ifdef ENABLE_BIGINT
case MIRType::BigInt:
out.printf("to BigInt");
break;
# endif
case MIRType::Object:
out.printf("to Object");
break;
@ -2255,6 +2282,9 @@ bool jit::TypeSetIncludes(TypeSet* types, MIRType input, TypeSet* inputTypes) {
case MIRType::Float32:
case MIRType::String:
case MIRType::Symbol:
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
#endif
case MIRType::MagicOptimizedArguments:
return types->hasType(
TypeSet::PrimitiveType(ValueTypeFromMIRType(input)));
@ -2515,8 +2545,10 @@ MDefinition* MBinaryBitwiseInstruction::foldUnnecessaryBitop() {
void MBinaryBitwiseInstruction::infer(BaselineInspector*, jsbytecode*) {
if (getOperand(0)->mightBeType(MIRType::Object) ||
getOperand(0)->mightBeType(MIRType::Symbol) ||
IF_BIGINT(getOperand(0)->mightBeType(MIRType::BigInt), false) ||
getOperand(1)->mightBeType(MIRType::Object) ||
getOperand(1)->mightBeType(MIRType::Symbol)) {
getOperand(1)->mightBeType(MIRType::Symbol) ||
IF_BIGINT(getOperand(1)->mightBeType(MIRType::BigInt), false)) {
specialization_ = MIRType::None;
setResultType(MIRType::Value);
} else {
@ -2540,7 +2572,9 @@ void MShiftInstruction::infer(BaselineInspector*, jsbytecode*) {
if (getOperand(0)->mightBeType(MIRType::Object) ||
getOperand(1)->mightBeType(MIRType::Object) ||
getOperand(0)->mightBeType(MIRType::Symbol) ||
getOperand(1)->mightBeType(MIRType::Symbol)) {
getOperand(1)->mightBeType(MIRType::Symbol) ||
IF_BIGINT(getOperand(0)->mightBeType(MIRType::BigInt), false) ||
IF_BIGINT(getOperand(1)->mightBeType(MIRType::BigInt), false)) {
specialization_ = MIRType::None;
setResultType(MIRType::Value);
} else {
@ -2553,7 +2587,9 @@ void MUrsh::infer(BaselineInspector* inspector, jsbytecode* pc) {
if (getOperand(0)->mightBeType(MIRType::Object) ||
getOperand(1)->mightBeType(MIRType::Object) ||
getOperand(0)->mightBeType(MIRType::Symbol) ||
getOperand(1)->mightBeType(MIRType::Symbol)) {
getOperand(1)->mightBeType(MIRType::Symbol) ||
IF_BIGINT(getOperand(0)->mightBeType(MIRType::BigInt), false) ||
IF_BIGINT(getOperand(1)->mightBeType(MIRType::BigInt), false)) {
specialization_ = MIRType::None;
setResultType(MIRType::Value);
return;
@ -3501,7 +3537,7 @@ MCompare::CompareType MCompare::determineCompareType(JSOp op, MDefinition* left,
return Compare_String;
}
// Handle symbol comparisons. (Relaational compare will throw)
// Handle symbol comparisons. (Relational compare will throw)
if (!relationalEq && lhs == MIRType::Symbol && rhs == MIRType::Symbol) {
return Compare_Symbol;
}
@ -3594,6 +3630,11 @@ MDefinition* MTypeOf::foldsTo(TempAllocator& alloc) {
case MIRType::Symbol:
type = JSTYPE_SYMBOL;
break;
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
type = JSTYPE_BIGINT;
break;
#endif
case MIRType::Null:
type = JSTYPE_OBJECT;
break;
@ -4196,7 +4237,16 @@ bool MCompare::tryFoldTypeOf(bool* result) {
*result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE);
return true;
}
} else if (constant->toString() == TypeName(JSTYPE_OBJECT, names)) {
}
#ifdef ENABLE_BIGINT
else if (constant->toString() == TypeName(JSTYPE_BIGINT, names)) {
if (!typeOf->input()->mightBeType(MIRType::BigInt)) {
*result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE);
return true;
}
}
#endif
else if (constant->toString() == TypeName(JSTYPE_OBJECT, names)) {
if (!typeOf->input()->mightBeType(MIRType::Object) &&
!typeOf->input()->mightBeType(MIRType::Null)) {
*result = (jsop() == JSOP_STRICTNE || jsop() == JSOP_NE);
@ -5443,6 +5493,10 @@ bool MConstant::appendRoots(MRootList& roots) const {
return roots.append(toString());
case MIRType::Symbol:
return roots.append(toSymbol());
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
return roots.append(toBigInt());
#endif
case MIRType::Object:
return roots.append(&toObject());
case MIRType::Undefined:

Просмотреть файл

@ -892,6 +892,7 @@ static inline bool SimpleArithOperand(MDefinition* op) {
return !op->emptyResultTypeSet() && !op->mightBeType(MIRType::Object) &&
!op->mightBeType(MIRType::String) &&
!op->mightBeType(MIRType::Symbol) &&
IF_BIGINT(!op->mightBeType(MIRType::BigInt), true) &&
!op->mightBeType(MIRType::MagicOptimizedArguments) &&
!op->mightBeType(MIRType::MagicHole) &&
!op->mightBeType(MIRType::MagicIsConstructing);
@ -1391,6 +1392,9 @@ class MConstant : public MNullaryInstruction {
double d;
JSString* str;
JS::Symbol* sym;
#ifdef ENABLE_BIGINT
BigInt* bi;
#endif
JSObject* obj;
uint64_t asBits;
};
@ -1508,6 +1512,12 @@ class MConstant : public MNullaryInstruction {
MOZ_ASSERT(type() == MIRType::Symbol);
return payload_.sym;
}
#ifdef ENABLE_BIGINT
BigInt* toBigInt() const {
MOZ_ASSERT(type() == MIRType::BigInt);
return payload_.bi;
}
#endif
JSObject& toObject() const {
MOZ_ASSERT(type() == MIRType::Object);
return *payload_.obj;
@ -3306,7 +3316,9 @@ class MUnbox final : public MUnaryInstruction, public BoxInputsPolicy::Data {
MOZ_ASSERT(type == MIRType::Boolean || type == MIRType::Int32 ||
type == MIRType::Double || type == MIRType::String ||
type == MIRType::Symbol || type == MIRType::Object);
type == MIRType::Symbol ||
IF_BIGINT(type == MIRType::BigInt, false) ||
type == MIRType::Object);
TemporaryTypeSet* resultSet = ins->resultTypeSet();
if (resultSet && type == MIRType::Object) {
@ -3347,6 +3359,11 @@ class MUnbox final : public MUnaryInstruction, public BoxInputsPolicy::Data {
case MIRType::Symbol:
kind = Bailout_NonSymbolInput;
break;
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
kind = Bailout_NonBigIntInput;
break;
#endif
case MIRType::Object:
kind = Bailout_NonObjectInput;
break;
@ -3660,9 +3677,10 @@ class MToDouble : public MToFPInstruction {
setMovable();
// An object might have "valueOf", which means it is effectful.
// ToNumber(symbol) throws.
// ToNumber(symbol) and ToNumber(bigint) throw.
if (def->mightBeType(MIRType::Object) ||
def->mightBeType(MIRType::Symbol)) {
def->mightBeType(MIRType::Symbol) ||
IF_BIGINT(def->mightBeType(MIRType::BigInt), false)) {
setGuard();
}
}
@ -3703,6 +3721,11 @@ class MToDouble : public MToFPInstruction {
if (input()->type() == MIRType::Symbol) {
return false;
}
#ifdef ENABLE_BIGINT
if (input()->type() == MIRType::BigInt) {
return false;
}
#endif
return true;
}
@ -3724,9 +3747,10 @@ class MToFloat32 : public MToFPInstruction {
setMovable();
// An object might have "valueOf", which means it is effectful.
// ToNumber(symbol) throws.
// ToNumber(symbol) and ToNumber(BigInt) throw.
if (def->mightBeType(MIRType::Object) ||
def->mightBeType(MIRType::Symbol)) {
def->mightBeType(MIRType::Symbol) ||
IF_BIGINT(def->mightBeType(MIRType::BigInt), false)) {
setGuard();
}
}
@ -3982,9 +4006,10 @@ class MToNumberInt32 : public MUnaryInstruction, public ToInt32Policy::Data {
setMovable();
// An object might have "valueOf", which means it is effectful.
// ToNumber(symbol) throws.
// ToNumber(symbol) and ToNumber(BigInt) throw.
if (def->mightBeType(MIRType::Object) ||
def->mightBeType(MIRType::Symbol)) {
def->mightBeType(MIRType::Symbol) ||
IF_BIGINT(def->mightBeType(MIRType::BigInt), false)) {
setGuard();
}
}
@ -4037,9 +4062,10 @@ class MTruncateToInt32 : public MUnaryInstruction, public ToInt32Policy::Data {
setMovable();
// An object might have "valueOf", which means it is effectful.
// ToInt32(symbol) throws.
// ToInt32(symbol) and ToInt32(BigInt) throw.
if (def->mightBeType(MIRType::Object) ||
def->mightBeType(MIRType::Symbol)) {
def->mightBeType(MIRType::Symbol) ||
IF_BIGINT(def->mightBeType(MIRType::BigInt), false)) {
setGuard();
}
}
@ -4078,10 +4104,11 @@ class MToString : public MUnaryInstruction, public ToStringPolicy::Data {
setResultType(MIRType::String);
setMovable();
// Objects might override toString and Symbols throw. We bailout in
// Objects might override toString; Symbol and BigInts throw. We bailout in
// those cases and run side-effects in baseline instead.
if (def->mightBeType(MIRType::Object) ||
def->mightBeType(MIRType::Symbol)) {
def->mightBeType(MIRType::Symbol) ||
IF_BIGINT(def->mightBeType(MIRType::BigInt), false)) {
setGuard();
}
}

Просмотреть файл

@ -3369,6 +3369,11 @@ void MacroAssembler::maybeBranchTestType(MIRType type, MDefinition* maybeDef,
case MIRType::Symbol:
branchTestSymbol(Equal, tag, label);
break;
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
branchTestBigInt(Equal, tag, label);
break;
#endif
case MIRType::Object:
branchTestObject(Equal, tag, label);
break;

Просмотреть файл

@ -1558,6 +1558,11 @@ class MacroAssembler : public MacroAssemblerSpecific {
inline void branchTestStringTruthy(bool truthy, const ValueOperand& value,
Label* label)
DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
#ifdef ENABLE_BIGINT
inline void branchTestBigIntTruthy(bool truthy, const ValueOperand& value,
Label* label)
DEFINED_ON(arm, arm64, mips32, mips64, x86_shared);
#endif
// Create an unconditional branch to the address given as argument.
inline void branchToComputedAddress(const BaseIndex& address) PER_ARCH;

Просмотреть файл

@ -343,6 +343,10 @@ static const char* ValTypeToString(JSValueType type) {
return "string";
case JSVAL_TYPE_SYMBOL:
return "symbol";
#ifdef ENABLE_BIGINT
case JSVAL_TYPE_BIGINT:
return "BigInt";
#endif
case JSVAL_TYPE_BOOLEAN:
return "boolean";
case JSVAL_TYPE_OBJECT:

Просмотреть файл

@ -775,7 +775,10 @@ bool ToDoublePolicy::staticAdjustInputs(TempAllocator& alloc,
case MIRType::Object:
case MIRType::String:
case MIRType::Symbol:
// Objects might be effectful. Symbols give TypeError.
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
#endif
// Objects might be effectful. Symbols and BigInts give TypeError.
break;
default:
break;
@ -827,7 +830,10 @@ bool ToInt32Policy::staticAdjustInputs(TempAllocator& alloc,
case MIRType::Object:
case MIRType::String:
case MIRType::Symbol:
// Objects might be effectful. Symbols give TypeError.
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
#endif
// Objects might be effectful. Symbols and BigInts give TypeError.
break;
default:
break;
@ -843,7 +849,8 @@ bool ToStringPolicy::staticAdjustInputs(TempAllocator& alloc,
MOZ_ASSERT(ins->isToString());
MIRType type = ins->getOperand(0)->type();
if (type == MIRType::Object || type == MIRType::Symbol) {
if (type == MIRType::Object || type == MIRType::Symbol ||
IF_BIGINT(type == MIRType::BigInt, false)) {
ins->replaceOperand(0, BoxAt(alloc, ins, ins->getOperand(0)));
return true;
}
@ -962,6 +969,9 @@ bool StoreUnboxedScalarPolicy::adjustValueInput(TempAllocator& alloc,
case MIRType::Object:
case MIRType::String:
case MIRType::Symbol:
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
#endif
value = BoxAt(alloc, ins, value);
break;
default:

Просмотреть файл

@ -1263,6 +1263,17 @@ void AssertValidSymbolPtr(JSContext* cx, JS::Symbol* sym) {
MOZ_ASSERT(sym->getAllocKind() == gc::AllocKind::SYMBOL);
}
#ifdef ENABLE_BIGINT
void AssertValidBigIntPtr(JSContext* cx, JS::BigInt* bi) {
AutoUnsafeCallWithABI unsafe;
// FIXME: check runtime?
MOZ_ASSERT(cx->zone() == bi->zone());
MOZ_ASSERT(bi->isAligned());
MOZ_ASSERT(bi->isTenured());
MOZ_ASSERT(bi->getAllocKind() == gc::AllocKind::BIGINT);
}
#endif
void AssertValidValue(JSContext* cx, Value* v) {
AutoUnsafeCallWithABI unsafe;
if (v->isObject()) {
@ -1272,6 +1283,11 @@ void AssertValidValue(JSContext* cx, Value* v) {
} else if (v->isSymbol()) {
AssertValidSymbolPtr(cx, v->toSymbol());
}
#ifdef ENABLE_BIGINT
else if (v->isBigInt()) {
AssertValidBigIntPtr(cx, v->toBigInt());
}
#endif
}
bool ObjectIsCallable(JSObject* obj) {

Просмотреть файл

@ -1092,6 +1092,9 @@ void AssertValidObjectPtr(JSContext* cx, JSObject* obj);
void AssertValidObjectOrNullPtr(JSContext* cx, JSObject* obj);
void AssertValidStringPtr(JSContext* cx, JSString* str);
void AssertValidSymbolPtr(JSContext* cx, JS::Symbol* sym);
#ifdef ENABLE_BIGINT
void AssertValidBigIntPtr(JSContext* cx, JS::BigInt* bi);
#endif
void AssertValidValue(JSContext* cx, Value* v);
void MarkValueFromJit(JSRuntime* rt, Value* vp);

Просмотреть файл

@ -1723,6 +1723,13 @@ void MacroAssembler::branchTestBigIntImpl(Condition cond, const T& t,
Condition c = testBigInt(cond, t);
ma_b(label, c);
}
void MacroAssembler::branchTestBigIntTruthy(bool truthy,
const ValueOperand& value,
Label* label) {
Condition c = testBigIntTruthy(truthy, value);
ma_b(label, c);
}
#endif
void MacroAssembler::branchTestNull(Condition cond, Register tag,

Просмотреть файл

@ -3441,6 +3441,20 @@ Assembler::Condition MacroAssemblerARMCompat::testStringTruthy(
return truthy ? Assembler::NotEqual : Assembler::Equal;
}
#ifdef ENABLE_BIGINT
Assembler::Condition MacroAssemblerARMCompat::testBigIntTruthy(
bool truthy, const ValueOperand& value) {
Register bi = value.payloadReg();
ScratchRegisterScope scratch(asMasm());
SecondScratchRegisterScope scratch2(asMasm());
ma_dtr(IsLoad, bi, Imm32(BigInt::offsetOfLengthSignAndReservedBits()),
scratch, scratch2);
as_cmp(scratch, Imm8(0));
return truthy ? Assembler::NotEqual : Assembler::Equal;
}
#endif
void MacroAssemblerARMCompat::floor(FloatRegister input, Register output,
Label* bail) {
Label handleZero;

Просмотреть файл

@ -849,6 +849,14 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM {
void unboxSymbol(const Address& src, Register dest) {
unboxNonDouble(src, dest, JSVAL_TYPE_SYMBOL);
}
#ifdef ENABLE_BIGINT
void unboxBigInt(const ValueOperand& src, Register dest) {
unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
}
void unboxBigInt(const Address& src, Register dest) {
unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
}
#endif
void unboxObject(const ValueOperand& src, Register dest) {
unboxNonDouble(src, dest, JSVAL_TYPE_OBJECT);
}
@ -917,6 +925,9 @@ class MacroAssemblerARMCompat : public MacroAssemblerARM {
Condition testBooleanTruthy(bool truthy, const ValueOperand& operand);
Condition testDoubleTruthy(bool truthy, FloatRegister reg);
Condition testStringTruthy(bool truthy, const ValueOperand& value);
#ifdef ENABLE_BIGINT
Condition testBigIntTruthy(bool truthy, const ValueOperand& value);
#endif
void boolValueToFloat32(const ValueOperand& operand, FloatRegister dest);
void int32ValueToFloat32(const ValueOperand& operand, FloatRegister dest);

Просмотреть файл

@ -1252,6 +1252,11 @@ void CodeGenerator::visitUnbox(LUnbox* unbox) {
case MIRType::Symbol:
cond = masm.testSymbol(Assembler::NotEqual, value);
break;
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
cond = masm.testBigInt(Assembler::NotEqual, value);
break;
#endif
default:
MOZ_CRASH("Given MIRType cannot be unboxed.");
}
@ -1289,6 +1294,11 @@ void CodeGenerator::visitUnbox(LUnbox* unbox) {
case MIRType::Symbol:
masm.unboxSymbol(input, result);
break;
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
masm.unboxBigInt(input, result);
break;
#endif
default:
MOZ_CRASH("Given MIRType cannot be unboxed.");
}

Просмотреть файл

@ -1432,6 +1432,13 @@ void MacroAssembler::branchTestBigIntImpl(Condition cond, const T& t,
Condition c = testBigInt(cond, t);
B(label, c);
}
void MacroAssembler::branchTestBigIntTruthy(bool truthy,
const ValueOperand& value,
Label* label) {
Condition c = testBigIntTruthy(truthy, value);
B(label, c);
}
#endif
void MacroAssembler::branchTestNull(Condition cond, Register tag,

Просмотреть файл

@ -1394,6 +1394,14 @@ class MacroAssemblerCompat : public vixl::MacroAssembler {
void unboxSymbol(const Address& src, Register dest) {
unboxNonDouble(src, dest, JSVAL_TYPE_SYMBOL);
}
#ifdef ENABLE_BIGINT
void unboxBigInt(const ValueOperand& operand, Register dest) {
unboxNonDouble(operand, dest, JSVAL_TYPE_BIGINT);
}
void unboxBigInt(const Address& src, Register dest) {
unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
}
#endif
// These two functions use the low 32-bits of the full value register.
void boolValueToDouble(const ValueOperand& operand, FloatRegister dest) {
convertInt32ToDouble(operand.valueReg(), dest);
@ -1755,6 +1763,19 @@ class MacroAssemblerCompat : public vixl::MacroAssembler {
splitSignExtTag(src, scratch);
return testBigInt(cond, scratch);
}
Condition testBigIntTruthy(bool truthy, const ValueOperand& value) {
vixl::UseScratchRegisterScope temps(this);
const Register scratch = temps.AcquireX().asUnsized();
const ARMRegister scratch64(scratch, 64);
MOZ_ASSERT(value.valueReg() != scratch);
unboxBigInt(value, scratch);
Ldr(scratch64,
MemOperand(scratch64, BigInt::offsetOfLengthSignAndReservedBits()));
Cmp(scratch64, Operand(0));
return truthy ? Condition::NonZero : Condition::Zero;
}
#endif
Condition testInt32(Condition cond, const BaseIndex& src) {
vixl::UseScratchRegisterScope temps(this);

Просмотреть файл

@ -819,6 +819,14 @@ void MacroAssembler::branchTestBigInt(Condition cond, const ValueOperand& value,
Label* label) {
branchTestBigInt(cond, value.typeReg(), label);
}
void MacroAssembler::branchTestBigIntTruthy(bool b, const ValueOperand& value,
Label* label) {
Register bi = value.payloadReg();
SecondScratchRegisterScope scratch2(*this);
ma_lw(scratch2, Address(bi, BigInt::offsetOfLengthSignAndReservedBits()));
ma_b(scratch2, Imm32(0), label, b ? NotEqual : Equal);
}
#endif
void MacroAssembler::branchTestNull(Condition cond, const ValueOperand& value,

Просмотреть файл

@ -78,6 +78,10 @@ void CodeGenerator::visitUnbox(LUnbox* unbox) {
case MIRType::Symbol:
masm.unboxSymbol(inputReg, result);
break;
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
masm.unboxBigInt(inputReg, result);
#endif
default:
MOZ_CRASH("Given MIRType cannot be unboxed.");
}
@ -101,6 +105,10 @@ void CodeGenerator::visitUnbox(LUnbox* unbox) {
case MIRType::Symbol:
masm.unboxSymbol(inputAddr, result);
break;
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
masm.unboxBigInt(inputAddr, result);
#endif
default:
MOZ_CRASH("Given MIRType cannot be unboxed.");
}

Просмотреть файл

@ -553,6 +553,15 @@ void MacroAssembler::branchTestBigInt(Condition cond, const ValueOperand& value,
splitTag(value, scratch2);
branchTestBigInt(cond, scratch2, label);
}
void MacroAssembler::branchTestBigIntTruthy(bool b, const ValueOperand& value,
Label* label) {
SecondScratchRegisterScope scratch2(*this);
unboxBigInt(value, scratch2);
loadPtr(Address(scratch2, BigInt::offsetOfLengthSignAndReservedBits()),
scratch2);
ma_b(scratch2, ImmWord(0), label, b ? NotEqual : Equal);
}
#endif
void MacroAssembler::branchTestNull(Condition cond, const ValueOperand& value,

Просмотреть файл

@ -1266,6 +1266,22 @@ void MacroAssemblerMIPS64Compat::unboxSymbol(const Address& src,
unboxNonDouble(src, dest, JSVAL_TYPE_SYMBOL);
}
#ifdef ENABLE_BIGINT
void MacroAssemblerMIPS64Compat::unboxBigInt(const ValueOperand& operand,
Register dest) {
unboxNonDouble(operand, dest, JSVAL_TYPE_BIGINT);
}
void MacroAssemblerMIPS64Compat::unboxBigInt(Register src, Register dest) {
unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
}
void MacroAssemblerMIPS64Compat::unboxBigInt(const Address& src,
Register dest) {
unboxNonDouble(src, dest, JSVAL_TYPE_BIGINT);
}
#endif
void MacroAssemblerMIPS64Compat::unboxObject(const ValueOperand& src,
Register dest) {
unboxNonDouble(src, dest, JSVAL_TYPE_OBJECT);

Просмотреть файл

@ -398,6 +398,11 @@ class MacroAssemblerMIPS64Compat : public MacroAssemblerMIPS64 {
void unboxSymbol(const ValueOperand& src, Register dest);
void unboxSymbol(Register src, Register dest);
void unboxSymbol(const Address& src, Register dest);
#ifdef ENABLE_BIGINT
void unboxBigInt(const ValueOperand& operand, Register dest);
void unboxBigInt(Register src, Register dest);
void unboxBigInt(const Address& src, Register dest);
#endif
void unboxObject(const ValueOperand& src, Register dest);
void unboxObject(Register src, Register dest);
void unboxObject(const Address& src, Register dest);

Просмотреть файл

@ -463,6 +463,12 @@ class MacroAssemblerNone : public Assembler {
void unboxSymbol(T, Register) {
MOZ_CRASH();
}
#ifdef ENABLE_BIGINT
template <typename T>
void unboxBigInt(T, Register) {
MOZ_CRASH();
}
#endif
template <typename T>
void unboxObject(T, Register) {
MOZ_CRASH();
@ -522,6 +528,9 @@ class MacroAssemblerNone : public Assembler {
void loadConstantFloat32(float, FloatRegister) { MOZ_CRASH(); }
Condition testInt32Truthy(bool, ValueOperand) { MOZ_CRASH(); }
Condition testStringTruthy(bool, ValueOperand) { MOZ_CRASH(); }
#ifdef ENABLE_BIGINT
Condition testBigIntTruthy(bool, ValueOperand) { MOZ_CRASH(); }
#endif
template <typename T>
void loadUnboxedValue(T, MIRType, AnyRegister) {

Просмотреть файл

@ -434,6 +434,9 @@ void CodeGeneratorShared::encodeAllocation(LSnapshot* snapshot,
case MIRType::Int32:
case MIRType::String:
case MIRType::Symbol:
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
#endif
case MIRType::Object:
case MIRType::ObjectOrNull:
case MIRType::Boolean:

Просмотреть файл

@ -429,7 +429,11 @@ void LIRGeneratorShared::redefine(MDefinition* def, MDefinition* as) {
case MIRType::Object:
case MIRType::ObjectOrNull:
case MIRType::String:
case MIRType::Symbol: {
case MIRType::Symbol:
# ifdef ENABLE_BIGINT
case MIRType::BigInt:
# endif
{
LAssertResultT* check =
new (alloc()) LAssertResultT(useRegister(def));
add(check, def->toInstruction());

Просмотреть файл

@ -85,6 +85,11 @@ void CodeGenerator::visitUnbox(LUnbox* unbox) {
case MIRType::Symbol:
cond = masm.testSymbol(Assembler::NotEqual, value);
break;
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
cond = masm.testBigInt(Assembler::NotEqual, value);
break;
#endif
default:
MOZ_CRASH("Given MIRType cannot be unboxed.");
}
@ -119,6 +124,11 @@ void CodeGenerator::visitUnbox(LUnbox* unbox) {
case MIRType::Symbol:
masm.unboxSymbol(input, result);
break;
#ifdef ENABLE_BIGINT
case MIRType::BigInt:
masm.unboxBigInt(input, result);
break;
#endif
default:
MOZ_CRASH("Given MIRType cannot be unboxed.");
}

Просмотреть файл

@ -957,6 +957,15 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared {
cmp32(Operand(scratch, JSString::offsetOfLength()), Imm32(0));
return truthy ? Assembler::NotEqual : Assembler::Equal;
}
#ifdef ENABLE_BIGINT
Condition testBigIntTruthy(bool truthy, const ValueOperand& value) {
ScratchRegisterScope scratch(asMasm());
unboxBigInt(value, scratch);
cmpPtr(Operand(scratch, BigInt::offsetOfLengthSignAndReservedBits()),
ImmWord(0));
return truthy ? Assembler::NotEqual : Assembler::Equal;
}
#endif
template <typename T>
inline void loadInt32OrDouble(const T& src, FloatRegister dest);

Просмотреть файл

@ -823,6 +823,13 @@ void MacroAssembler::branchTestBigIntImpl(Condition cond, const T& t,
cond = testBigInt(cond, t);
j(cond, label);
}
void MacroAssembler::branchTestBigIntTruthy(bool truthy,
const ValueOperand& value,
Label* label) {
Condition cond = testBigIntTruthy(truthy, value);
j(cond, label);
}
#endif
void MacroAssembler::branchTestNull(Condition cond, Register tag,

Просмотреть файл

@ -890,6 +890,14 @@ class MacroAssemblerX86 : public MacroAssemblerX86Shared {
cmp32(Operand(string, JSString::offsetOfLength()), Imm32(0));
return truthy ? Assembler::NotEqual : Assembler::Equal;
}
#ifdef ENABLE_BIGINT
Condition testBigIntTruthy(bool truthy, const ValueOperand& value) {
Register bi = value.payloadReg();
cmpPtr(Operand(bi, BigInt::offsetOfLengthSignAndReservedBits()),
ImmWord(0));
return truthy ? Assembler::NotEqual : Assembler::Equal;
}
#endif
template <typename T>
inline void loadInt32OrDouble(const T& src, FloatRegister dest);

Просмотреть файл

@ -78,6 +78,11 @@ class BigInt final : public js::gc::TenuredCell {
bool isZero() const { return digitLength() == 0; }
bool isNegative() const { return lengthSignAndReservedBits_ & SignBit; }
// Offset for direct access from JIT code.
static constexpr size_t offsetOfLengthSignAndReservedBits() {
return offsetof(BigInt, lengthSignAndReservedBits_);
}
void initializeDigitsToZero();
void traceChildren(JSTracer* trc);

Просмотреть файл

@ -391,6 +391,10 @@ bool TypeSet::mightBeMIRType(jit::MIRType type) const {
return baseFlags() & TYPE_FLAG_STRING;
case jit::MIRType::Symbol:
return baseFlags() & TYPE_FLAG_SYMBOL;
#ifdef ENABLE_BIGINT
case jit::MIRType::BigInt:
return baseFlags() & TYPE_FLAG_BIGINT;
#endif
case jit::MIRType::MagicOptimizedArguments:
return baseFlags() & TYPE_FLAG_LAZYARGS;
case jit::MIRType::MagicHole:
@ -1709,6 +1713,10 @@ static inline jit::MIRType GetMIRTypeFromTypeFlags(TypeFlags flags) {
return jit::MIRType::String;
case TYPE_FLAG_SYMBOL:
return jit::MIRType::Symbol;
#ifdef ENABLE_BIGINT
case TYPE_FLAG_BIGINT:
return jit::MIRType::BigInt;
#endif
case TYPE_FLAG_LAZYARGS:
return jit::MIRType::MagicOptimizedArguments;
case TYPE_FLAG_ANYOBJECT: