[+] EMCAScript: implicit upcast of expressions involving u64s
[+] Massive performance boost in dealing with expressions consisting of non-literal/const bigints (1 out of 2)
[*] Updated source url map
Last aurora commit: b8f6b544
This commit is contained in:
parent
b8f6b544b0
commit
1224fc8eea
@ -58,8 +58,12 @@ extern macro BigIntBuiltinsAssembler::WriteBigIntSignAndLength(
|
||||
extern macro CodeStubAssembler::AllocateBigInt(intptr): MutableBigInt;
|
||||
extern macro CodeStubAssembler::StoreBigIntDigit(
|
||||
MutableBigInt, intptr, uintptr): void;
|
||||
extern macro CodeStubAssembler::SetBigInt(
|
||||
MutableBigInt, Smi, bool): void;
|
||||
extern macro CodeStubAssembler::LoadBigIntDigit(BigIntBase, intptr): uintptr;
|
||||
|
||||
extern runtime ToBigIntConvertNumber(Context, Object): BigInt;
|
||||
|
||||
macro IsCanonicalized(bigint: BigIntBase): bool {
|
||||
const length = ReadBigIntLength(bigint);
|
||||
|
||||
@ -74,6 +78,30 @@ macro InvertSign(sign: uint32): uint32 {
|
||||
return sign == kPositiveSign ? kNegativeSign : kPositiveSign;
|
||||
}
|
||||
|
||||
macro NormalizeWord(implicit context: Context)(
|
||||
n: Numeric): BigInt {
|
||||
try {
|
||||
return Cast<BigInt>(n) otherwise NotBigInt;
|
||||
} label NotBigInt {
|
||||
try {
|
||||
const ssWord : Smi = Cast<Smi>(n) otherwise NotSmi;
|
||||
const bSign : bool = SmiUntag(ssWord) <= 0;
|
||||
const iSign : uint32 = bSign ? kNegativeSign : kPositiveSign;
|
||||
const mbiRet : MutableBigInt = AllocateBigInt(1);
|
||||
|
||||
WriteBigIntSignAndLength(mbiRet,
|
||||
iSign,
|
||||
1 /* SMI = x < 2^32, where digit_t = uintptr_t, 2 ^ (1 * sizeof(uintptr_t)) > x*/);
|
||||
|
||||
SetBigInt(mbiRet, ssWord, bSign);
|
||||
|
||||
return Convert<BigInt>(mbiRet);
|
||||
} label NotSmi {
|
||||
return ToBigIntConvertNumber(context, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
macro AllocateEmptyBigIntNoThrow(implicit context: Context)(
|
||||
sign: uint32, length: intptr): MutableBigInt labels BigIntTooBig {
|
||||
if (length > kBigIntMaxLength) {
|
||||
@ -173,8 +201,11 @@ macro BigIntAddImpl(implicit context: Context)(x: BigInt, y: BigInt): BigInt
|
||||
}
|
||||
|
||||
builtin BigIntAddNoThrow(implicit context: Context)(
|
||||
x: BigInt, y: BigInt): Numeric {
|
||||
xNum: Numeric, yNum: Numeric): Numeric {
|
||||
try {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntAddImpl(x, y) otherwise BigIntTooBig;
|
||||
} label BigIntTooBig {
|
||||
// Smi sentinal is used to signal BigIntTooBig exception.
|
||||
@ -185,11 +216,11 @@ builtin BigIntAddNoThrow(implicit context: Context)(
|
||||
builtin BigIntAdd(implicit context: Context)(
|
||||
xNum: Numeric, yNum: Numeric): BigInt {
|
||||
try {
|
||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntAddImpl(x, y) otherwise BigIntTooBig;
|
||||
} label MixedTypes {
|
||||
} label _MixedTypes {
|
||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||
} label BigIntTooBig {
|
||||
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
||||
@ -215,8 +246,11 @@ macro BigIntSubtractImpl(implicit context: Context)(
|
||||
}
|
||||
|
||||
builtin BigIntSubtractNoThrow(implicit context: Context)(
|
||||
x: BigInt, y: BigInt): Numeric {
|
||||
xNum: Numeric, yNum: Numeric): Numeric {
|
||||
try {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntSubtractImpl(x, y) otherwise BigIntTooBig;
|
||||
} label BigIntTooBig {
|
||||
// Smi sentinal is used to signal BigIntTooBig exception.
|
||||
@ -227,11 +261,11 @@ builtin BigIntSubtractNoThrow(implicit context: Context)(
|
||||
builtin BigIntSubtract(implicit context: Context)(
|
||||
xNum: Numeric, yNum: Numeric): BigInt {
|
||||
try {
|
||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntSubtractImpl(x, y) otherwise BigIntTooBig;
|
||||
} label MixedTypes {
|
||||
} label _MixedTypes {
|
||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||
} label BigIntTooBig {
|
||||
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
||||
@ -268,8 +302,11 @@ macro BigIntMultiplyImpl(implicit context: Context)(x: BigInt, y: BigInt):
|
||||
}
|
||||
|
||||
builtin BigIntMultiplyNoThrow(implicit context: Context)(
|
||||
x: BigInt, y: BigInt): Numeric {
|
||||
xNum: Numeric, yNum: Numeric): Numeric {
|
||||
try {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntMultiplyImpl(x, y) otherwise BigIntTooBig,
|
||||
TerminationRequested;
|
||||
} label BigIntTooBig {
|
||||
@ -284,12 +321,12 @@ builtin BigIntMultiplyNoThrow(implicit context: Context)(
|
||||
builtin BigIntMultiply(implicit context: Context)(
|
||||
xNum: Numeric, yNum: Numeric): BigInt {
|
||||
try {
|
||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntMultiplyImpl(x, y) otherwise BigIntTooBig,
|
||||
TerminationRequested;
|
||||
} label MixedTypes {
|
||||
} label _MixedTypes {
|
||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||
} label BigIntTooBig {
|
||||
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
||||
@ -337,8 +374,11 @@ macro BigIntDivideImpl(implicit context: Context)(x: BigInt, y: BigInt):
|
||||
}
|
||||
|
||||
builtin BigIntDivideNoThrow(implicit context: Context)(
|
||||
x: BigInt, y: BigInt): Numeric {
|
||||
xNum: Numeric, yNum: Numeric): Numeric {
|
||||
try {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntDivideImpl(x, y) otherwise BigIntDivZero, TerminationRequested;
|
||||
} label BigIntDivZero {
|
||||
// Smi sentinel 0 is used to signal BigIntDivZero exception.
|
||||
@ -352,11 +392,11 @@ builtin BigIntDivideNoThrow(implicit context: Context)(
|
||||
builtin BigIntDivide(implicit context: Context)(
|
||||
xNum: Numeric, yNum: Numeric): BigInt {
|
||||
try {
|
||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntDivideImpl(x, y) otherwise BigIntDivZero, TerminationRequested;
|
||||
} label MixedTypes {
|
||||
} label _MixedTypes {
|
||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||
} label BigIntDivZero {
|
||||
ThrowRangeError(MessageTemplate::kBigIntDivZero);
|
||||
@ -399,8 +439,11 @@ macro BigIntModulusImpl(implicit context: Context)(x: BigInt, y: BigInt):
|
||||
}
|
||||
|
||||
builtin BigIntModulusNoThrow(implicit context: Context)(
|
||||
x: BigInt, y: BigInt): Numeric {
|
||||
xNum: Numeric, yNum: Numeric): Numeric {
|
||||
try {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntModulusImpl(x, y) otherwise BigIntDivZero,
|
||||
TerminationRequested;
|
||||
} label BigIntDivZero {
|
||||
@ -415,12 +458,12 @@ builtin BigIntModulusNoThrow(implicit context: Context)(
|
||||
builtin BigIntModulus(implicit context: Context)(
|
||||
xNum: Numeric, yNum: Numeric): BigInt {
|
||||
try {
|
||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntModulusImpl(x, y) otherwise BigIntDivZero,
|
||||
TerminationRequested;
|
||||
} label MixedTypes {
|
||||
} label _MixedTypes {
|
||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||
} label BigIntDivZero {
|
||||
ThrowRangeError(MessageTemplate::kBigIntDivZero);
|
||||
@ -473,8 +516,11 @@ macro BigIntBitwiseAndImpl(implicit context: Context)(
|
||||
}
|
||||
|
||||
builtin BigIntBitwiseAndNoThrow(implicit context: Context)(
|
||||
x: BigInt, y: BigInt): Numeric {
|
||||
xNum: Numeric, yNum: Numeric): Numeric {
|
||||
try {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntBitwiseAndImpl(x, y) otherwise BigIntTooBig;
|
||||
} label BigIntTooBig {
|
||||
// Smi sentinel 0 is used to signal BigIntTooBig exception.
|
||||
@ -485,11 +531,11 @@ builtin BigIntBitwiseAndNoThrow(implicit context: Context)(
|
||||
builtin BigIntBitwiseAnd(implicit context: Context)(
|
||||
xNum: Numeric, yNum: Numeric): BigInt {
|
||||
try {
|
||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntBitwiseAndImpl(x, y) otherwise BigIntTooBig;
|
||||
} label MixedTypes {
|
||||
} label _MixedTypes {
|
||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||
} label BigIntTooBig {
|
||||
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
||||
@ -539,18 +585,21 @@ macro BigIntBitwiseOrImpl(implicit context: Context)(
|
||||
}
|
||||
|
||||
builtin BigIntBitwiseOrNoThrow(implicit context: Context)(
|
||||
x: BigInt, y: BigInt): Numeric {
|
||||
xNum: Numeric, yNum: Numeric): Numeric {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntBitwiseOrImpl(x, y);
|
||||
}
|
||||
|
||||
builtin BigIntBitwiseOr(implicit context: Context)(
|
||||
xNum: Numeric, yNum: Numeric): BigInt {
|
||||
try {
|
||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntBitwiseOrImpl(x, y);
|
||||
} label MixedTypes {
|
||||
} label _MixedTypes {
|
||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||
}
|
||||
}
|
||||
@ -601,8 +650,11 @@ macro BigIntBitwiseXorImpl(implicit context: Context)(
|
||||
}
|
||||
|
||||
builtin BigIntBitwiseXorNoThrow(implicit context: Context)(
|
||||
x: BigInt, y: BigInt): Numeric {
|
||||
xNum: Numeric, yNum: Numeric): Numeric {
|
||||
try {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntBitwiseXorImpl(x, y) otherwise BigIntTooBig;
|
||||
} label BigIntTooBig {
|
||||
// Smi sentinel 0 is used to signal BigIntTooBig exception.
|
||||
@ -613,11 +665,11 @@ builtin BigIntBitwiseXorNoThrow(implicit context: Context)(
|
||||
builtin BigIntBitwiseXor(implicit context: Context)(
|
||||
xNum: Numeric, yNum: Numeric): BigInt {
|
||||
try {
|
||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntBitwiseXorImpl(x, y) otherwise BigIntTooBig;
|
||||
} label MixedTypes {
|
||||
} label _MixedTypes {
|
||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||
} label BigIntTooBig {
|
||||
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
||||
@ -733,8 +785,11 @@ macro BigIntShiftRightImpl(implicit context: Context)(
|
||||
}
|
||||
|
||||
builtin BigIntShiftLeftNoThrow(implicit context: Context)(
|
||||
x: BigInt, y: BigInt): Numeric {
|
||||
xNum: Numeric, yNum: Numeric): Numeric {
|
||||
try {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntShiftLeftImpl(x, y) otherwise BigIntTooBig;
|
||||
} label BigIntTooBig {
|
||||
// Smi sentinel 0 is used to signal BigIntTooBig exception.
|
||||
@ -745,11 +800,11 @@ builtin BigIntShiftLeftNoThrow(implicit context: Context)(
|
||||
builtin BigIntShiftLeft(implicit context: Context)(
|
||||
xNum: Numeric, yNum: Numeric): BigInt {
|
||||
try {
|
||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntShiftLeftImpl(x, y) otherwise BigIntTooBig;
|
||||
} label MixedTypes {
|
||||
} label _MixedTypes {
|
||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||
} label BigIntTooBig {
|
||||
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
||||
@ -757,8 +812,11 @@ builtin BigIntShiftLeft(implicit context: Context)(
|
||||
}
|
||||
|
||||
builtin BigIntShiftRightNoThrow(implicit context: Context)(
|
||||
x: BigInt, y: BigInt): Numeric {
|
||||
xNum: Numeric, yNum: Numeric): Numeric {
|
||||
try {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntShiftRightImpl(x, y) otherwise BigIntTooBig;
|
||||
} label BigIntTooBig {
|
||||
// Smi sentinel 0 is used to signal BigIntTooBig exception.
|
||||
@ -769,18 +827,21 @@ builtin BigIntShiftRightNoThrow(implicit context: Context)(
|
||||
builtin BigIntShiftRight(implicit context: Context)(
|
||||
xNum: Numeric, yNum: Numeric): BigInt {
|
||||
try {
|
||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
return BigIntShiftRightImpl(x, y) otherwise BigIntTooBig;
|
||||
} label MixedTypes {
|
||||
} label _MixedTypes {
|
||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||
} label BigIntTooBig {
|
||||
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
||||
}
|
||||
}
|
||||
|
||||
builtin BigIntEqual(implicit context: Context)(x: BigInt, y: BigInt): Boolean {
|
||||
builtin BigIntEqual(implicit context: Context)(xNum: Numeric, yNum: Numeric): Boolean {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
|
||||
if (ReadBigIntSign(x) != ReadBigIntSign(y)) {
|
||||
return False;
|
||||
}
|
||||
@ -836,22 +897,30 @@ macro BigIntCompare(implicit context: Context)(x: BigInt, y: BigInt): intptr {
|
||||
}
|
||||
|
||||
builtin BigIntLessThan(implicit context: Context)(
|
||||
x: BigInt, y: BigInt): Boolean {
|
||||
xNum: Numeric, yNum: Numeric): Boolean {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
return BigIntCompare(x, y) < 0 ? True : False;
|
||||
}
|
||||
|
||||
builtin BigIntGreaterThan(implicit context: Context)(
|
||||
x: BigInt, y: BigInt): Boolean {
|
||||
xNum: Numeric, yNum: Numeric): Boolean {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
return BigIntCompare(x, y) > 0 ? True : False;
|
||||
}
|
||||
|
||||
builtin BigIntLessThanOrEqual(implicit context: Context)(
|
||||
x: BigInt, y: BigInt): Boolean {
|
||||
xNum: Numeric, yNum: Numeric): Boolean {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
return BigIntCompare(x, y) <= 0 ? True : False;
|
||||
}
|
||||
|
||||
builtin BigIntGreaterThanOrEqual(implicit context: Context)(
|
||||
x: BigInt, y: BigInt): Boolean {
|
||||
xNum: Numeric, yNum: Numeric): Boolean {
|
||||
const x = NormalizeWord(xNum);
|
||||
const y = NormalizeWord(yNum);
|
||||
return BigIntCompare(x, y) >= 0 ? True : False;
|
||||
}
|
||||
|
||||
|
@ -3625,6 +3625,32 @@ TNode<Word32T> CodeStubAssembler::LoadBigIntBitfield(TNode<BigInt> bigint) {
|
||||
LoadObjectField<Uint32T>(bigint, BigInt::kBitfieldOffset));
|
||||
}
|
||||
|
||||
void CodeStubAssembler::SetBigInt(TNode<BigInt> bigint, TNode<Smi> digit,
|
||||
TNode<BoolT> bFlip) {
|
||||
|
||||
Label trCondition(this), frCondition(this), epilogue(this);
|
||||
|
||||
auto ret = ChangeInt32ToIntPtr(SmiToInt32(digit));
|
||||
|
||||
Branch(bFlip, &trCondition, &frCondition);
|
||||
|
||||
BIND(&trCondition);
|
||||
{
|
||||
StoreObjectFieldNoWriteBarrier(bigint, BigInt::kDigitsOffset,
|
||||
Unsigned(IntPtrAdd(WordNot(ret), IntPtrConstant(1))));
|
||||
Goto(&epilogue);
|
||||
}
|
||||
|
||||
BIND(&frCondition);
|
||||
{
|
||||
StoreObjectFieldNoWriteBarrier(bigint, BigInt::kDigitsOffset,
|
||||
Unsigned(ret));
|
||||
Goto(&epilogue);
|
||||
}
|
||||
|
||||
BIND(&epilogue);
|
||||
}
|
||||
|
||||
TNode<UintPtrT> CodeStubAssembler::LoadBigIntDigit(TNode<BigInt> bigint,
|
||||
intptr_t digit_index) {
|
||||
CHECK_LE(0, digit_index);
|
||||
@ -5717,7 +5743,7 @@ TNode<Word32T> CodeStubAssembler::TruncateTaggedToWord32(TNode<Context> context,
|
||||
void CodeStubAssembler::TaggedToWord32OrBigInt(
|
||||
TNode<Context> context, TNode<Object> value, Label* if_number,
|
||||
TVariable<Word32T>* var_word32, Label* if_bigint, Label* if_bigint64,
|
||||
TVariable<BigInt>* var_maybe_bigint) {
|
||||
TVariable<Numeric>* var_maybe_bigint) {
|
||||
TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>(
|
||||
context, value, if_number, var_word32, IsKnownTaggedPointer::kNo,
|
||||
if_bigint, if_bigint64, var_maybe_bigint);
|
||||
@ -5729,7 +5755,7 @@ void CodeStubAssembler::TaggedToWord32OrBigInt(
|
||||
void CodeStubAssembler::TaggedToWord32OrBigIntWithFeedback(
|
||||
TNode<Context> context, TNode<Object> value, Label* if_number,
|
||||
TVariable<Word32T>* var_word32, Label* if_bigint, Label* if_bigint64,
|
||||
TVariable<BigInt>* var_maybe_bigint, TVariable<Smi>* var_feedback) {
|
||||
TVariable<Numeric>* var_maybe_bigint, TVariable<Smi>* var_feedback) {
|
||||
TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>(
|
||||
context, value, if_number, var_word32, IsKnownTaggedPointer::kNo,
|
||||
if_bigint, if_bigint64, var_maybe_bigint, var_feedback);
|
||||
@ -5741,7 +5767,7 @@ void CodeStubAssembler::TaggedToWord32OrBigIntWithFeedback(
|
||||
void CodeStubAssembler::TaggedPointerToWord32OrBigIntWithFeedback(
|
||||
TNode<Context> context, TNode<HeapObject> pointer, Label* if_number,
|
||||
TVariable<Word32T>* var_word32, Label* if_bigint, Label* if_bigint64,
|
||||
TVariable<BigInt>* var_maybe_bigint, TVariable<Smi>* var_feedback) {
|
||||
TVariable<Numeric>* var_maybe_bigint, TVariable<Smi>* var_feedback) {
|
||||
TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>(
|
||||
context, pointer, if_number, var_word32, IsKnownTaggedPointer::kYes,
|
||||
if_bigint, if_bigint64, var_maybe_bigint, var_feedback);
|
||||
@ -5752,7 +5778,7 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
|
||||
TNode<Context> context, TNode<Object> value, Label* if_number,
|
||||
TVariable<Word32T>* var_word32,
|
||||
IsKnownTaggedPointer is_known_tagged_pointer, Label* if_bigint,
|
||||
Label* if_bigint64, TVariable<BigInt>* var_maybe_bigint,
|
||||
Label* if_bigint64, TVariable<Numeric>* var_maybe_bigint,
|
||||
TVariable<Smi>* var_feedback) {
|
||||
// We might need to loop after conversion.
|
||||
TVARIABLE(Object, var_value, value);
|
||||
@ -7995,6 +8021,8 @@ TNode<BigInt> CodeStubAssembler::ToBigInt(TNode<Context> context,
|
||||
Goto(&done);
|
||||
|
||||
BIND(&if_throw);
|
||||
//result = CallBuiltin(Builtin::kBigInt, context(),
|
||||
// var_left_bigint.value(), var_right_bigint.value());
|
||||
ThrowTypeError(context, MessageTemplate::kBigIntFromObject, input);
|
||||
|
||||
BIND(&done);
|
||||
@ -8025,9 +8053,9 @@ TNode<BigInt> CodeStubAssembler::ToBigIntConvertNumber(TNode<Context> context,
|
||||
|
||||
void CodeStubAssembler::TaggedToBigInt(TNode<Context> context,
|
||||
TNode<Object> value,
|
||||
Label* if_not_bigint, Label* if_bigint,
|
||||
Label* if_invalid, Label* if_bigint,
|
||||
Label* if_bigint64,
|
||||
TVariable<BigInt>* var_bigint,
|
||||
TVariable<Numeric>* var_bigint,
|
||||
TVariable<Smi>* var_feedback) {
|
||||
Label done(this), is_smi(this), is_heapnumber(this), maybe_bigint64(this),
|
||||
is_bigint(this), is_oddball(this);
|
||||
@ -8047,18 +8075,20 @@ void CodeStubAssembler::TaggedToBigInt(TNode<Context> context,
|
||||
TNode<Numeric> numeric_value = CAST(
|
||||
CallBuiltin(Builtin::kNonNumberToNumeric, context, heap_object_value));
|
||||
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kAny);
|
||||
GotoIf(TaggedIsSmi(numeric_value), if_not_bigint);
|
||||
GotoIfNot(IsBigInt(CAST(numeric_value)), if_not_bigint);
|
||||
*var_bigint = CAST(numeric_value);
|
||||
GotoIf(TaggedIsSmi(numeric_value), if_invalid);
|
||||
GotoIfNot(IsBigInt(CAST(numeric_value)), if_invalid);
|
||||
*var_bigint = numeric_value;
|
||||
Goto(if_bigint);
|
||||
|
||||
BIND(&is_smi);
|
||||
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kSignedSmall);
|
||||
Goto(if_not_bigint);
|
||||
*var_bigint = CAST(value);
|
||||
Goto(if_bigint);
|
||||
|
||||
BIND(&is_heapnumber);
|
||||
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kNumber);
|
||||
Goto(if_not_bigint);
|
||||
*var_bigint = CAST(value);
|
||||
Goto(if_bigint);
|
||||
|
||||
if (Is64() && if_bigint64) {
|
||||
BIND(&maybe_bigint64);
|
||||
@ -8074,8 +8104,9 @@ void CodeStubAssembler::TaggedToBigInt(TNode<Context> context,
|
||||
Goto(if_bigint);
|
||||
|
||||
BIND(&is_oddball);
|
||||
*var_bigint = SmiConstant(0);
|
||||
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kNumberOrOddball);
|
||||
Goto(if_not_bigint);
|
||||
Goto(if_bigint);
|
||||
}
|
||||
|
||||
// ES#sec-touint32
|
||||
|
@ -1893,6 +1893,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
void StoreBigIntDigit(TNode<BigInt> bigint, TNode<IntPtrT> digit_index,
|
||||
TNode<UintPtrT> digit);
|
||||
|
||||
void SetBigInt(TNode<BigInt> bigint, TNode<Smi> digit,
|
||||
TNode<BoolT> bFlip);
|
||||
|
||||
TNode<Word32T> LoadBigIntBitfield(TNode<BigInt> bigint);
|
||||
TNode<UintPtrT> LoadBigIntDigit(TNode<BigInt> bigint, intptr_t digit_index);
|
||||
TNode<UintPtrT> LoadBigIntDigit(TNode<BigInt> bigint,
|
||||
@ -2433,17 +2436,17 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
void TaggedToWord32OrBigInt(TNode<Context> context, TNode<Object> value,
|
||||
Label* if_number, TVariable<Word32T>* var_word32,
|
||||
Label* if_bigint, Label* if_bigint64,
|
||||
TVariable<BigInt>* var_maybe_bigint);
|
||||
TVariable<Numeric>* var_maybe_bigint);
|
||||
void TaggedToWord32OrBigIntWithFeedback(TNode<Context> context,
|
||||
TNode<Object> value, Label* if_number,
|
||||
TVariable<Word32T>* var_word32,
|
||||
Label* if_bigint, Label* if_bigint64,
|
||||
TVariable<BigInt>* var_maybe_bigint,
|
||||
TVariable<Numeric>* var_maybe_bigint,
|
||||
TVariable<Smi>* var_feedback);
|
||||
void TaggedPointerToWord32OrBigIntWithFeedback(
|
||||
TNode<Context> context, TNode<HeapObject> pointer, Label* if_number,
|
||||
TVariable<Word32T>* var_word32, Label* if_bigint, Label* if_bigint64,
|
||||
TVariable<BigInt>* var_maybe_bigint, TVariable<Smi>* var_feedback);
|
||||
TVariable<Numeric>* var_maybe_bigint, TVariable<Smi>* var_feedback);
|
||||
|
||||
TNode<Int32T> TruncateNumberToWord32(TNode<Number> value);
|
||||
// Truncate the floating point value of a HeapNumber to an Int32.
|
||||
@ -2474,7 +2477,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
|
||||
void TaggedToBigInt(TNode<Context> context, TNode<Object> value,
|
||||
Label* if_not_bigint, Label* if_bigint,
|
||||
Label* if_bigint64, TVariable<BigInt>* var_bigint,
|
||||
Label* if_bigint64, TVariable<Numeric>* var_bigint,
|
||||
TVariable<Smi>* var_feedback);
|
||||
|
||||
// Ensures that {var_shared_value} is shareable across Isolates, and throws if
|
||||
@ -4325,7 +4328,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
IsKnownTaggedPointer is_known_tagged_pointer,
|
||||
Label* if_bigint = nullptr,
|
||||
Label* if_bigint64 = nullptr,
|
||||
TVariable<BigInt>* var_maybe_bigint = nullptr,
|
||||
TVariable<Numeric>* var_maybe_bigint = nullptr,
|
||||
TVariable<Smi>* var_feedback = nullptr);
|
||||
|
||||
// Low-level accessors for Descriptor arrays.
|
||||
|
@ -788,7 +788,7 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
|
||||
TVARIABLE(Smi, var_right_feedback);
|
||||
TVARIABLE(Word32T, var_left_word32);
|
||||
TVARIABLE(Word32T, var_right_word32);
|
||||
TVARIABLE(BigInt, var_left_bigint);
|
||||
TVARIABLE(Numeric, var_left_bigint);
|
||||
Label done(this);
|
||||
Label if_left_number(this), do_number_op(this);
|
||||
Label if_left_bigint(this), if_left_bigint64(this);
|
||||
@ -800,11 +800,15 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
|
||||
&var_left_bigint, slot ? &var_left_feedback : nullptr);
|
||||
|
||||
BIND(&if_left_number);
|
||||
{
|
||||
TaggedToWord32OrBigIntWithFeedback(
|
||||
context(), right, &do_number_op, &var_right_word32,
|
||||
&if_left_number_right_bigint, nullptr, nullptr,
|
||||
slot ? &var_right_feedback : nullptr);
|
||||
&if_left_number_right_bigint,
|
||||
nullptr, nullptr, slot ? &var_right_feedback : nullptr);
|
||||
}
|
||||
|
||||
// SMI of X &^| bigint Y should remain a throw
|
||||
// Logically, it does not make sense for the right hand operand to be greater than the lefthand
|
||||
BIND(&if_left_number_right_bigint);
|
||||
{
|
||||
if (slot) {
|
||||
@ -835,17 +839,17 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
|
||||
|
||||
// BigInt cases.
|
||||
{
|
||||
TVARIABLE(BigInt, var_right_bigint);
|
||||
TVARIABLE(Numeric, var_right_bigint);
|
||||
Label if_both_bigint(this), if_both_bigint64(this);
|
||||
Label if_bigint_mix(this, Label::kDeferred);
|
||||
Label if_invalid(this, Label::kDeferred);
|
||||
|
||||
BIND(&if_left_bigint);
|
||||
TaggedToBigInt(context(), right, &if_bigint_mix, &if_both_bigint, nullptr,
|
||||
TaggedToBigInt(context(), right, &if_invalid, &if_both_bigint, nullptr,
|
||||
&var_right_bigint, slot ? &var_right_feedback : nullptr);
|
||||
|
||||
if (IsBigInt64OpSupported(this, bitwise_op)) {
|
||||
BIND(&if_left_bigint64);
|
||||
TaggedToBigInt(context(), right, &if_bigint_mix, &if_both_bigint,
|
||||
TaggedToBigInt(context(), right, &if_invalid, &if_both_bigint,
|
||||
&if_both_bigint64, &var_right_bigint,
|
||||
slot ? &var_right_feedback : nullptr);
|
||||
|
||||
@ -860,8 +864,12 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
|
||||
|
||||
TVARIABLE(UintPtrT, left_raw);
|
||||
TVARIABLE(UintPtrT, right_raw);
|
||||
BigIntToRawBytes(var_left_bigint.value(), &left_raw, &left_raw);
|
||||
BigIntToRawBytes(var_right_bigint.value(), &right_raw, &right_raw);
|
||||
|
||||
BigIntToRawBytes(UncheckedCast<BigInt>(var_left_bigint.value()),
|
||||
&left_raw, &left_raw);
|
||||
|
||||
BigIntToRawBytes(UncheckedCast<BigInt>(var_right_bigint.value()),
|
||||
&right_raw, &right_raw);
|
||||
|
||||
switch (bitwise_op) {
|
||||
case Operation::kBitwiseAnd: {
|
||||
@ -995,14 +1003,14 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
|
||||
}
|
||||
}
|
||||
|
||||
BIND(&if_bigint_mix);
|
||||
BIND(&if_invalid);
|
||||
{
|
||||
if (slot) {
|
||||
// Ensure that the feedback is updated before we throw.
|
||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
||||
(*maybe_feedback_vector)(), *slot, update_feedback_mode);
|
||||
}
|
||||
ThrowTypeError(context(), MessageTemplate::kBigIntMixedTypes);
|
||||
ThrowTypeError(context(), MessageTemplate::kBigIntFromNumber);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1020,11 +1028,12 @@ BinaryOpAssembler::Generate_BitwiseBinaryOpWithSmiOperandAndOptionalFeedback(
|
||||
TVARIABLE(Object, result);
|
||||
TVARIABLE(Smi, var_left_feedback);
|
||||
TVARIABLE(Word32T, var_left_word32);
|
||||
TVARIABLE(BigInt, var_left_bigint);
|
||||
TVARIABLE(Numeric, var_left_bigint);
|
||||
TVARIABLE(Smi, feedback);
|
||||
// Check if the {lhs} is a Smi or a HeapObject.
|
||||
Label if_lhsissmi(this), if_lhsisnotsmi(this, Label::kDeferred);
|
||||
Label do_number_op(this), if_bigint_mix(this), done(this);
|
||||
Label if_lhsissmi(this), if_lhsisnotsmi(this);
|
||||
Label do_number_op(this), if_bigint_mix(this), done(this), done2(this),
|
||||
mixedBigInt(this);
|
||||
|
||||
Branch(TaggedIsSmi(left), &if_lhsissmi, &if_lhsisnotsmi);
|
||||
|
||||
@ -1065,18 +1074,118 @@ BinaryOpAssembler::Generate_BitwiseBinaryOpWithSmiOperandAndOptionalFeedback(
|
||||
|
||||
BIND(&if_bigint_mix);
|
||||
{
|
||||
Goto(&mixedBigInt);
|
||||
}
|
||||
}
|
||||
|
||||
BIND(&mixedBigInt);
|
||||
{
|
||||
if (slot) {
|
||||
// Ensure that the feedback is updated even if the runtime call below
|
||||
// would throw.
|
||||
feedback = SmiOr(var_left_feedback.value(), right_smi);
|
||||
UpdateFeedback(feedback.value(), (*maybe_feedback_vector)(), *slot,
|
||||
update_feedback_mode);
|
||||
}
|
||||
|
||||
switch (bitwise_op) {
|
||||
case Operation::kBitwiseAnd: {
|
||||
result = CallBuiltin(Builtin::kBigIntBitwiseAndNoThrow, context(),
|
||||
var_left_bigint.value(), right_smi);
|
||||
// Check for sentinel that signals BigIntTooBig exception.
|
||||
GotoIfNot(TaggedIsSmi(result.value()), &done2);
|
||||
|
||||
if (slot) {
|
||||
// Update feedback to prevent deopt loop.
|
||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
||||
(*maybe_feedback_vector)(), *slot,
|
||||
update_feedback_mode);
|
||||
}
|
||||
ThrowRangeError(context(), MessageTemplate::kBigIntTooBig);
|
||||
break;
|
||||
}
|
||||
case Operation::kBitwiseOr: {
|
||||
result = CallBuiltin(Builtin::kBigIntBitwiseOrNoThrow, context(),
|
||||
var_left_bigint.value(), right_smi);
|
||||
// Check for sentinel that signals BigIntTooBig exception.
|
||||
GotoIfNot(TaggedIsSmi(result.value()), &done2);
|
||||
|
||||
if (slot) {
|
||||
// Update feedback to prevent deopt loop.
|
||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
||||
(*maybe_feedback_vector)(), *slot,
|
||||
update_feedback_mode);
|
||||
}
|
||||
ThrowRangeError(context(), MessageTemplate::kBigIntTooBig);
|
||||
break;
|
||||
}
|
||||
case Operation::kBitwiseXor: {
|
||||
result = CallBuiltin(Builtin::kBigIntBitwiseXorNoThrow, context(),
|
||||
var_left_bigint.value(), right_smi);
|
||||
// Check for sentinel that signals BigIntTooBig exception.
|
||||
GotoIfNot(TaggedIsSmi(result.value()), &done2);
|
||||
|
||||
if (slot) {
|
||||
// Update feedback to prevent deopt loop.
|
||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
||||
(*maybe_feedback_vector)(), *slot,
|
||||
update_feedback_mode);
|
||||
}
|
||||
ThrowRangeError(context(), MessageTemplate::kBigIntTooBig);
|
||||
break;
|
||||
}
|
||||
case Operation::kShiftLeft: {
|
||||
result = CallBuiltin(Builtin::kBigIntShiftLeftNoThrow, context(),
|
||||
var_left_bigint.value(), right_smi);
|
||||
// Check for sentinel that signals BigIntTooBig exception.
|
||||
GotoIfNot(TaggedIsSmi(result.value()), &done2);
|
||||
|
||||
if (slot) {
|
||||
// Update feedback to prevent deopt loop.
|
||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
||||
(*maybe_feedback_vector)(), *slot,
|
||||
update_feedback_mode);
|
||||
}
|
||||
ThrowRangeError(context(), MessageTemplate::kBigIntTooBig);
|
||||
break;
|
||||
}
|
||||
case Operation::kShiftRight: {
|
||||
result = CallBuiltin(Builtin::kBigIntShiftRightNoThrow, context(),
|
||||
var_left_bigint.value(), right_smi);
|
||||
// Check for sentinel that signals BigIntTooBig exception.
|
||||
GotoIfNot(TaggedIsSmi(result.value()), &done2);
|
||||
|
||||
if (slot) {
|
||||
// Update feedback to prevent deopt loop.
|
||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
||||
(*maybe_feedback_vector)(), *slot,
|
||||
update_feedback_mode);
|
||||
}
|
||||
ThrowRangeError(context(), MessageTemplate::kBigIntTooBig);
|
||||
break;
|
||||
}
|
||||
case Operation::kShiftRightLogical: {
|
||||
if (slot) {
|
||||
// Ensure that the feedback is updated before we throw.
|
||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
||||
(*maybe_feedback_vector)(), *slot, update_feedback_mode);
|
||||
(*maybe_feedback_vector)(), *slot,
|
||||
update_feedback_mode);
|
||||
}
|
||||
ThrowTypeError(context(), MessageTemplate::kBigIntMixedTypes);
|
||||
// BigInt does not support logical right shift.
|
||||
ThrowTypeError(context(), MessageTemplate::kBigIntShr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
BIND(&done);
|
||||
UpdateFeedback(feedback.value(), (*maybe_feedback_vector)(), *slot,
|
||||
update_feedback_mode);
|
||||
Goto(&done2);
|
||||
|
||||
BIND(&done2);
|
||||
return result.value();
|
||||
}
|
||||
|
||||
|
@ -25,7 +25,7 @@ class UnaryOpAssemblerImpl final : public CodeStubAssembler {
|
||||
// mechanism).
|
||||
TVARIABLE(Word32T, var_word32);
|
||||
TVARIABLE(Smi, var_feedback);
|
||||
TVARIABLE(BigInt, var_bigint);
|
||||
TVARIABLE(Numeric, var_bigint);
|
||||
TVARIABLE(Object, var_result);
|
||||
Label if_number(this), if_bigint(this, Label::kDeferred), out(this);
|
||||
TaggedToWord32OrBigIntWithFeedback(context, value, &if_number, &var_word32,
|
||||
|
@ -121,12 +121,32 @@ RUNTIME_FUNCTION(Runtime_BigIntBinaryOp) {
|
||||
int opcode = args.smi_value_at(2);
|
||||
Operation op = static_cast<Operation>(opcode);
|
||||
|
||||
if (!left_obj->IsBigInt() || !right_obj->IsBigInt()) {
|
||||
Handle<BigInt> left ;
|
||||
Handle<BigInt> right;
|
||||
|
||||
if (!left_obj->IsBigInt()) {
|
||||
auto mebi = BigInt::FromObject(isolate, left_obj);
|
||||
if (mebi.is_null()) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kBigIntMixedTypes));
|
||||
}
|
||||
Handle<BigInt> left(Handle<BigInt>::cast(left_obj));
|
||||
Handle<BigInt> right(Handle<BigInt>::cast(right_obj));
|
||||
left = mebi.ToHandleChecked();
|
||||
}
|
||||
else {
|
||||
left = Handle<BigInt>::cast(left_obj);
|
||||
}
|
||||
|
||||
if (!right_obj->IsBigInt()) {
|
||||
auto mebi = BigInt::FromObject(isolate, right_obj);
|
||||
if (mebi.is_null()) {
|
||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||
isolate, NewTypeError(MessageTemplate::kBigIntMixedTypes));
|
||||
}
|
||||
right = mebi.ToHandleChecked();
|
||||
} else {
|
||||
right = Handle<BigInt>::cast(right_obj);
|
||||
}
|
||||
|
||||
MaybeHandle<BigInt> result;
|
||||
switch (op) {
|
||||
case Operation::kAdd:
|
||||
|
@ -109,10 +109,9 @@ inline std::string PositionAsString(SourcePosition pos) {
|
||||
}
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& out, SourcePosition pos) {
|
||||
return out << "https://source.chromium.org/chromium/chromium/src/+/main:v8/"
|
||||
return out << "https://gitea.reece.sx/AuroraMiddleware/v8/src/branch/master/"
|
||||
<< SourceFileMap::PathFromV8Root(pos.source)
|
||||
<< "?l=" << (pos.start.line + 1)
|
||||
<< "&c=" << (pos.start.column + 1);
|
||||
<< "#L" << (pos.start.line + 1);
|
||||
}
|
||||
|
||||
} // namespace torque
|
||||
|
Loading…
Reference in New Issue
Block a user