[+] 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::AllocateBigInt(intptr): MutableBigInt;
|
||||||
extern macro CodeStubAssembler::StoreBigIntDigit(
|
extern macro CodeStubAssembler::StoreBigIntDigit(
|
||||||
MutableBigInt, intptr, uintptr): void;
|
MutableBigInt, intptr, uintptr): void;
|
||||||
|
extern macro CodeStubAssembler::SetBigInt(
|
||||||
|
MutableBigInt, Smi, bool): void;
|
||||||
extern macro CodeStubAssembler::LoadBigIntDigit(BigIntBase, intptr): uintptr;
|
extern macro CodeStubAssembler::LoadBigIntDigit(BigIntBase, intptr): uintptr;
|
||||||
|
|
||||||
|
extern runtime ToBigIntConvertNumber(Context, Object): BigInt;
|
||||||
|
|
||||||
macro IsCanonicalized(bigint: BigIntBase): bool {
|
macro IsCanonicalized(bigint: BigIntBase): bool {
|
||||||
const length = ReadBigIntLength(bigint);
|
const length = ReadBigIntLength(bigint);
|
||||||
|
|
||||||
@ -74,6 +78,30 @@ macro InvertSign(sign: uint32): uint32 {
|
|||||||
return sign == kPositiveSign ? kNegativeSign : kPositiveSign;
|
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)(
|
macro AllocateEmptyBigIntNoThrow(implicit context: Context)(
|
||||||
sign: uint32, length: intptr): MutableBigInt labels BigIntTooBig {
|
sign: uint32, length: intptr): MutableBigInt labels BigIntTooBig {
|
||||||
if (length > kBigIntMaxLength) {
|
if (length > kBigIntMaxLength) {
|
||||||
@ -173,8 +201,11 @@ macro BigIntAddImpl(implicit context: Context)(x: BigInt, y: BigInt): BigInt
|
|||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntAddNoThrow(implicit context: Context)(
|
builtin BigIntAddNoThrow(implicit context: Context)(
|
||||||
x: BigInt, y: BigInt): Numeric {
|
xNum: Numeric, yNum: Numeric): Numeric {
|
||||||
try {
|
try {
|
||||||
|
const x = NormalizeWord(xNum);
|
||||||
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntAddImpl(x, y) otherwise BigIntTooBig;
|
return BigIntAddImpl(x, y) otherwise BigIntTooBig;
|
||||||
} label BigIntTooBig {
|
} label BigIntTooBig {
|
||||||
// Smi sentinal is used to signal BigIntTooBig exception.
|
// Smi sentinal is used to signal BigIntTooBig exception.
|
||||||
@ -185,11 +216,11 @@ builtin BigIntAddNoThrow(implicit context: Context)(
|
|||||||
builtin BigIntAdd(implicit context: Context)(
|
builtin BigIntAdd(implicit context: Context)(
|
||||||
xNum: Numeric, yNum: Numeric): BigInt {
|
xNum: Numeric, yNum: Numeric): BigInt {
|
||||||
try {
|
try {
|
||||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
const x = NormalizeWord(xNum);
|
||||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntAddImpl(x, y) otherwise BigIntTooBig;
|
return BigIntAddImpl(x, y) otherwise BigIntTooBig;
|
||||||
} label MixedTypes {
|
} label _MixedTypes {
|
||||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||||
} label BigIntTooBig {
|
} label BigIntTooBig {
|
||||||
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
||||||
@ -215,8 +246,11 @@ macro BigIntSubtractImpl(implicit context: Context)(
|
|||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntSubtractNoThrow(implicit context: Context)(
|
builtin BigIntSubtractNoThrow(implicit context: Context)(
|
||||||
x: BigInt, y: BigInt): Numeric {
|
xNum: Numeric, yNum: Numeric): Numeric {
|
||||||
try {
|
try {
|
||||||
|
const x = NormalizeWord(xNum);
|
||||||
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntSubtractImpl(x, y) otherwise BigIntTooBig;
|
return BigIntSubtractImpl(x, y) otherwise BigIntTooBig;
|
||||||
} label BigIntTooBig {
|
} label BigIntTooBig {
|
||||||
// Smi sentinal is used to signal BigIntTooBig exception.
|
// Smi sentinal is used to signal BigIntTooBig exception.
|
||||||
@ -227,11 +261,11 @@ builtin BigIntSubtractNoThrow(implicit context: Context)(
|
|||||||
builtin BigIntSubtract(implicit context: Context)(
|
builtin BigIntSubtract(implicit context: Context)(
|
||||||
xNum: Numeric, yNum: Numeric): BigInt {
|
xNum: Numeric, yNum: Numeric): BigInt {
|
||||||
try {
|
try {
|
||||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
const x = NormalizeWord(xNum);
|
||||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntSubtractImpl(x, y) otherwise BigIntTooBig;
|
return BigIntSubtractImpl(x, y) otherwise BigIntTooBig;
|
||||||
} label MixedTypes {
|
} label _MixedTypes {
|
||||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||||
} label BigIntTooBig {
|
} label BigIntTooBig {
|
||||||
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
||||||
@ -268,8 +302,11 @@ macro BigIntMultiplyImpl(implicit context: Context)(x: BigInt, y: BigInt):
|
|||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntMultiplyNoThrow(implicit context: Context)(
|
builtin BigIntMultiplyNoThrow(implicit context: Context)(
|
||||||
x: BigInt, y: BigInt): Numeric {
|
xNum: Numeric, yNum: Numeric): Numeric {
|
||||||
try {
|
try {
|
||||||
|
const x = NormalizeWord(xNum);
|
||||||
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntMultiplyImpl(x, y) otherwise BigIntTooBig,
|
return BigIntMultiplyImpl(x, y) otherwise BigIntTooBig,
|
||||||
TerminationRequested;
|
TerminationRequested;
|
||||||
} label BigIntTooBig {
|
} label BigIntTooBig {
|
||||||
@ -284,12 +321,12 @@ builtin BigIntMultiplyNoThrow(implicit context: Context)(
|
|||||||
builtin BigIntMultiply(implicit context: Context)(
|
builtin BigIntMultiply(implicit context: Context)(
|
||||||
xNum: Numeric, yNum: Numeric): BigInt {
|
xNum: Numeric, yNum: Numeric): BigInt {
|
||||||
try {
|
try {
|
||||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
const x = NormalizeWord(xNum);
|
||||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntMultiplyImpl(x, y) otherwise BigIntTooBig,
|
return BigIntMultiplyImpl(x, y) otherwise BigIntTooBig,
|
||||||
TerminationRequested;
|
TerminationRequested;
|
||||||
} label MixedTypes {
|
} label _MixedTypes {
|
||||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||||
} label BigIntTooBig {
|
} label BigIntTooBig {
|
||||||
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
||||||
@ -337,8 +374,11 @@ macro BigIntDivideImpl(implicit context: Context)(x: BigInt, y: BigInt):
|
|||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntDivideNoThrow(implicit context: Context)(
|
builtin BigIntDivideNoThrow(implicit context: Context)(
|
||||||
x: BigInt, y: BigInt): Numeric {
|
xNum: Numeric, yNum: Numeric): Numeric {
|
||||||
try {
|
try {
|
||||||
|
const x = NormalizeWord(xNum);
|
||||||
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntDivideImpl(x, y) otherwise BigIntDivZero, TerminationRequested;
|
return BigIntDivideImpl(x, y) otherwise BigIntDivZero, TerminationRequested;
|
||||||
} label BigIntDivZero {
|
} label BigIntDivZero {
|
||||||
// Smi sentinel 0 is used to signal BigIntDivZero exception.
|
// Smi sentinel 0 is used to signal BigIntDivZero exception.
|
||||||
@ -352,11 +392,11 @@ builtin BigIntDivideNoThrow(implicit context: Context)(
|
|||||||
builtin BigIntDivide(implicit context: Context)(
|
builtin BigIntDivide(implicit context: Context)(
|
||||||
xNum: Numeric, yNum: Numeric): BigInt {
|
xNum: Numeric, yNum: Numeric): BigInt {
|
||||||
try {
|
try {
|
||||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
const x = NormalizeWord(xNum);
|
||||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntDivideImpl(x, y) otherwise BigIntDivZero, TerminationRequested;
|
return BigIntDivideImpl(x, y) otherwise BigIntDivZero, TerminationRequested;
|
||||||
} label MixedTypes {
|
} label _MixedTypes {
|
||||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||||
} label BigIntDivZero {
|
} label BigIntDivZero {
|
||||||
ThrowRangeError(MessageTemplate::kBigIntDivZero);
|
ThrowRangeError(MessageTemplate::kBigIntDivZero);
|
||||||
@ -399,8 +439,11 @@ macro BigIntModulusImpl(implicit context: Context)(x: BigInt, y: BigInt):
|
|||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntModulusNoThrow(implicit context: Context)(
|
builtin BigIntModulusNoThrow(implicit context: Context)(
|
||||||
x: BigInt, y: BigInt): Numeric {
|
xNum: Numeric, yNum: Numeric): Numeric {
|
||||||
try {
|
try {
|
||||||
|
const x = NormalizeWord(xNum);
|
||||||
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntModulusImpl(x, y) otherwise BigIntDivZero,
|
return BigIntModulusImpl(x, y) otherwise BigIntDivZero,
|
||||||
TerminationRequested;
|
TerminationRequested;
|
||||||
} label BigIntDivZero {
|
} label BigIntDivZero {
|
||||||
@ -415,12 +458,12 @@ builtin BigIntModulusNoThrow(implicit context: Context)(
|
|||||||
builtin BigIntModulus(implicit context: Context)(
|
builtin BigIntModulus(implicit context: Context)(
|
||||||
xNum: Numeric, yNum: Numeric): BigInt {
|
xNum: Numeric, yNum: Numeric): BigInt {
|
||||||
try {
|
try {
|
||||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
const x = NormalizeWord(xNum);
|
||||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntModulusImpl(x, y) otherwise BigIntDivZero,
|
return BigIntModulusImpl(x, y) otherwise BigIntDivZero,
|
||||||
TerminationRequested;
|
TerminationRequested;
|
||||||
} label MixedTypes {
|
} label _MixedTypes {
|
||||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||||
} label BigIntDivZero {
|
} label BigIntDivZero {
|
||||||
ThrowRangeError(MessageTemplate::kBigIntDivZero);
|
ThrowRangeError(MessageTemplate::kBigIntDivZero);
|
||||||
@ -473,8 +516,11 @@ macro BigIntBitwiseAndImpl(implicit context: Context)(
|
|||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntBitwiseAndNoThrow(implicit context: Context)(
|
builtin BigIntBitwiseAndNoThrow(implicit context: Context)(
|
||||||
x: BigInt, y: BigInt): Numeric {
|
xNum: Numeric, yNum: Numeric): Numeric {
|
||||||
try {
|
try {
|
||||||
|
const x = NormalizeWord(xNum);
|
||||||
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntBitwiseAndImpl(x, y) otherwise BigIntTooBig;
|
return BigIntBitwiseAndImpl(x, y) otherwise BigIntTooBig;
|
||||||
} label BigIntTooBig {
|
} label BigIntTooBig {
|
||||||
// Smi sentinel 0 is used to signal BigIntTooBig exception.
|
// Smi sentinel 0 is used to signal BigIntTooBig exception.
|
||||||
@ -485,11 +531,11 @@ builtin BigIntBitwiseAndNoThrow(implicit context: Context)(
|
|||||||
builtin BigIntBitwiseAnd(implicit context: Context)(
|
builtin BigIntBitwiseAnd(implicit context: Context)(
|
||||||
xNum: Numeric, yNum: Numeric): BigInt {
|
xNum: Numeric, yNum: Numeric): BigInt {
|
||||||
try {
|
try {
|
||||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
const x = NormalizeWord(xNum);
|
||||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntBitwiseAndImpl(x, y) otherwise BigIntTooBig;
|
return BigIntBitwiseAndImpl(x, y) otherwise BigIntTooBig;
|
||||||
} label MixedTypes {
|
} label _MixedTypes {
|
||||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||||
} label BigIntTooBig {
|
} label BigIntTooBig {
|
||||||
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
||||||
@ -539,18 +585,21 @@ macro BigIntBitwiseOrImpl(implicit context: Context)(
|
|||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntBitwiseOrNoThrow(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);
|
return BigIntBitwiseOrImpl(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntBitwiseOr(implicit context: Context)(
|
builtin BigIntBitwiseOr(implicit context: Context)(
|
||||||
xNum: Numeric, yNum: Numeric): BigInt {
|
xNum: Numeric, yNum: Numeric): BigInt {
|
||||||
try {
|
try {
|
||||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
const x = NormalizeWord(xNum);
|
||||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntBitwiseOrImpl(x, y);
|
return BigIntBitwiseOrImpl(x, y);
|
||||||
} label MixedTypes {
|
} label _MixedTypes {
|
||||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -601,8 +650,11 @@ macro BigIntBitwiseXorImpl(implicit context: Context)(
|
|||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntBitwiseXorNoThrow(implicit context: Context)(
|
builtin BigIntBitwiseXorNoThrow(implicit context: Context)(
|
||||||
x: BigInt, y: BigInt): Numeric {
|
xNum: Numeric, yNum: Numeric): Numeric {
|
||||||
try {
|
try {
|
||||||
|
const x = NormalizeWord(xNum);
|
||||||
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntBitwiseXorImpl(x, y) otherwise BigIntTooBig;
|
return BigIntBitwiseXorImpl(x, y) otherwise BigIntTooBig;
|
||||||
} label BigIntTooBig {
|
} label BigIntTooBig {
|
||||||
// Smi sentinel 0 is used to signal BigIntTooBig exception.
|
// Smi sentinel 0 is used to signal BigIntTooBig exception.
|
||||||
@ -613,11 +665,11 @@ builtin BigIntBitwiseXorNoThrow(implicit context: Context)(
|
|||||||
builtin BigIntBitwiseXor(implicit context: Context)(
|
builtin BigIntBitwiseXor(implicit context: Context)(
|
||||||
xNum: Numeric, yNum: Numeric): BigInt {
|
xNum: Numeric, yNum: Numeric): BigInt {
|
||||||
try {
|
try {
|
||||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
const x = NormalizeWord(xNum);
|
||||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntBitwiseXorImpl(x, y) otherwise BigIntTooBig;
|
return BigIntBitwiseXorImpl(x, y) otherwise BigIntTooBig;
|
||||||
} label MixedTypes {
|
} label _MixedTypes {
|
||||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||||
} label BigIntTooBig {
|
} label BigIntTooBig {
|
||||||
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
||||||
@ -733,8 +785,11 @@ macro BigIntShiftRightImpl(implicit context: Context)(
|
|||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntShiftLeftNoThrow(implicit context: Context)(
|
builtin BigIntShiftLeftNoThrow(implicit context: Context)(
|
||||||
x: BigInt, y: BigInt): Numeric {
|
xNum: Numeric, yNum: Numeric): Numeric {
|
||||||
try {
|
try {
|
||||||
|
const x = NormalizeWord(xNum);
|
||||||
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntShiftLeftImpl(x, y) otherwise BigIntTooBig;
|
return BigIntShiftLeftImpl(x, y) otherwise BigIntTooBig;
|
||||||
} label BigIntTooBig {
|
} label BigIntTooBig {
|
||||||
// Smi sentinel 0 is used to signal BigIntTooBig exception.
|
// Smi sentinel 0 is used to signal BigIntTooBig exception.
|
||||||
@ -745,11 +800,11 @@ builtin BigIntShiftLeftNoThrow(implicit context: Context)(
|
|||||||
builtin BigIntShiftLeft(implicit context: Context)(
|
builtin BigIntShiftLeft(implicit context: Context)(
|
||||||
xNum: Numeric, yNum: Numeric): BigInt {
|
xNum: Numeric, yNum: Numeric): BigInt {
|
||||||
try {
|
try {
|
||||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
const x = NormalizeWord(xNum);
|
||||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntShiftLeftImpl(x, y) otherwise BigIntTooBig;
|
return BigIntShiftLeftImpl(x, y) otherwise BigIntTooBig;
|
||||||
} label MixedTypes {
|
} label _MixedTypes {
|
||||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||||
} label BigIntTooBig {
|
} label BigIntTooBig {
|
||||||
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
||||||
@ -757,8 +812,11 @@ builtin BigIntShiftLeft(implicit context: Context)(
|
|||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntShiftRightNoThrow(implicit context: Context)(
|
builtin BigIntShiftRightNoThrow(implicit context: Context)(
|
||||||
x: BigInt, y: BigInt): Numeric {
|
xNum: Numeric, yNum: Numeric): Numeric {
|
||||||
try {
|
try {
|
||||||
|
const x = NormalizeWord(xNum);
|
||||||
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntShiftRightImpl(x, y) otherwise BigIntTooBig;
|
return BigIntShiftRightImpl(x, y) otherwise BigIntTooBig;
|
||||||
} label BigIntTooBig {
|
} label BigIntTooBig {
|
||||||
// Smi sentinel 0 is used to signal BigIntTooBig exception.
|
// Smi sentinel 0 is used to signal BigIntTooBig exception.
|
||||||
@ -769,18 +827,21 @@ builtin BigIntShiftRightNoThrow(implicit context: Context)(
|
|||||||
builtin BigIntShiftRight(implicit context: Context)(
|
builtin BigIntShiftRight(implicit context: Context)(
|
||||||
xNum: Numeric, yNum: Numeric): BigInt {
|
xNum: Numeric, yNum: Numeric): BigInt {
|
||||||
try {
|
try {
|
||||||
const x = Cast<BigInt>(xNum) otherwise MixedTypes;
|
const x = NormalizeWord(xNum);
|
||||||
const y = Cast<BigInt>(yNum) otherwise MixedTypes;
|
const y = NormalizeWord(yNum);
|
||||||
|
|
||||||
return BigIntShiftRightImpl(x, y) otherwise BigIntTooBig;
|
return BigIntShiftRightImpl(x, y) otherwise BigIntTooBig;
|
||||||
} label MixedTypes {
|
} label _MixedTypes {
|
||||||
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
ThrowTypeError(MessageTemplate::kBigIntMixedTypes);
|
||||||
} label BigIntTooBig {
|
} label BigIntTooBig {
|
||||||
ThrowRangeError(MessageTemplate::kBigIntTooBig);
|
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)) {
|
if (ReadBigIntSign(x) != ReadBigIntSign(y)) {
|
||||||
return False;
|
return False;
|
||||||
}
|
}
|
||||||
@ -836,22 +897,30 @@ macro BigIntCompare(implicit context: Context)(x: BigInt, y: BigInt): intptr {
|
|||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntLessThan(implicit context: Context)(
|
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;
|
return BigIntCompare(x, y) < 0 ? True : False;
|
||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntGreaterThan(implicit context: Context)(
|
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;
|
return BigIntCompare(x, y) > 0 ? True : False;
|
||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntLessThanOrEqual(implicit context: Context)(
|
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;
|
return BigIntCompare(x, y) <= 0 ? True : False;
|
||||||
}
|
}
|
||||||
|
|
||||||
builtin BigIntGreaterThanOrEqual(implicit context: Context)(
|
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;
|
return BigIntCompare(x, y) >= 0 ? True : False;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3625,6 +3625,32 @@ TNode<Word32T> CodeStubAssembler::LoadBigIntBitfield(TNode<BigInt> bigint) {
|
|||||||
LoadObjectField<Uint32T>(bigint, BigInt::kBitfieldOffset));
|
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,
|
TNode<UintPtrT> CodeStubAssembler::LoadBigIntDigit(TNode<BigInt> bigint,
|
||||||
intptr_t digit_index) {
|
intptr_t digit_index) {
|
||||||
CHECK_LE(0, digit_index);
|
CHECK_LE(0, digit_index);
|
||||||
@ -5717,7 +5743,7 @@ TNode<Word32T> CodeStubAssembler::TruncateTaggedToWord32(TNode<Context> context,
|
|||||||
void CodeStubAssembler::TaggedToWord32OrBigInt(
|
void CodeStubAssembler::TaggedToWord32OrBigInt(
|
||||||
TNode<Context> context, TNode<Object> value, Label* if_number,
|
TNode<Context> context, TNode<Object> value, Label* if_number,
|
||||||
TVariable<Word32T>* var_word32, Label* if_bigint, Label* if_bigint64,
|
TVariable<Word32T>* var_word32, Label* if_bigint, Label* if_bigint64,
|
||||||
TVariable<BigInt>* var_maybe_bigint) {
|
TVariable<Numeric>* var_maybe_bigint) {
|
||||||
TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>(
|
TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>(
|
||||||
context, value, if_number, var_word32, IsKnownTaggedPointer::kNo,
|
context, value, if_number, var_word32, IsKnownTaggedPointer::kNo,
|
||||||
if_bigint, if_bigint64, var_maybe_bigint);
|
if_bigint, if_bigint64, var_maybe_bigint);
|
||||||
@ -5729,7 +5755,7 @@ void CodeStubAssembler::TaggedToWord32OrBigInt(
|
|||||||
void CodeStubAssembler::TaggedToWord32OrBigIntWithFeedback(
|
void CodeStubAssembler::TaggedToWord32OrBigIntWithFeedback(
|
||||||
TNode<Context> context, TNode<Object> value, Label* if_number,
|
TNode<Context> context, TNode<Object> value, Label* if_number,
|
||||||
TVariable<Word32T>* var_word32, Label* if_bigint, Label* if_bigint64,
|
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>(
|
TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>(
|
||||||
context, value, if_number, var_word32, IsKnownTaggedPointer::kNo,
|
context, value, if_number, var_word32, IsKnownTaggedPointer::kNo,
|
||||||
if_bigint, if_bigint64, var_maybe_bigint, var_feedback);
|
if_bigint, if_bigint64, var_maybe_bigint, var_feedback);
|
||||||
@ -5741,7 +5767,7 @@ void CodeStubAssembler::TaggedToWord32OrBigIntWithFeedback(
|
|||||||
void CodeStubAssembler::TaggedPointerToWord32OrBigIntWithFeedback(
|
void CodeStubAssembler::TaggedPointerToWord32OrBigIntWithFeedback(
|
||||||
TNode<Context> context, TNode<HeapObject> pointer, Label* if_number,
|
TNode<Context> context, TNode<HeapObject> pointer, Label* if_number,
|
||||||
TVariable<Word32T>* var_word32, Label* if_bigint, Label* if_bigint64,
|
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>(
|
TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>(
|
||||||
context, pointer, if_number, var_word32, IsKnownTaggedPointer::kYes,
|
context, pointer, if_number, var_word32, IsKnownTaggedPointer::kYes,
|
||||||
if_bigint, if_bigint64, var_maybe_bigint, var_feedback);
|
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,
|
TNode<Context> context, TNode<Object> value, Label* if_number,
|
||||||
TVariable<Word32T>* var_word32,
|
TVariable<Word32T>* var_word32,
|
||||||
IsKnownTaggedPointer is_known_tagged_pointer, Label* if_bigint,
|
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) {
|
TVariable<Smi>* var_feedback) {
|
||||||
// We might need to loop after conversion.
|
// We might need to loop after conversion.
|
||||||
TVARIABLE(Object, var_value, value);
|
TVARIABLE(Object, var_value, value);
|
||||||
@ -7995,6 +8021,8 @@ TNode<BigInt> CodeStubAssembler::ToBigInt(TNode<Context> context,
|
|||||||
Goto(&done);
|
Goto(&done);
|
||||||
|
|
||||||
BIND(&if_throw);
|
BIND(&if_throw);
|
||||||
|
//result = CallBuiltin(Builtin::kBigInt, context(),
|
||||||
|
// var_left_bigint.value(), var_right_bigint.value());
|
||||||
ThrowTypeError(context, MessageTemplate::kBigIntFromObject, input);
|
ThrowTypeError(context, MessageTemplate::kBigIntFromObject, input);
|
||||||
|
|
||||||
BIND(&done);
|
BIND(&done);
|
||||||
@ -8025,9 +8053,9 @@ TNode<BigInt> CodeStubAssembler::ToBigIntConvertNumber(TNode<Context> context,
|
|||||||
|
|
||||||
void CodeStubAssembler::TaggedToBigInt(TNode<Context> context,
|
void CodeStubAssembler::TaggedToBigInt(TNode<Context> context,
|
||||||
TNode<Object> value,
|
TNode<Object> value,
|
||||||
Label* if_not_bigint, Label* if_bigint,
|
Label* if_invalid, Label* if_bigint,
|
||||||
Label* if_bigint64,
|
Label* if_bigint64,
|
||||||
TVariable<BigInt>* var_bigint,
|
TVariable<Numeric>* var_bigint,
|
||||||
TVariable<Smi>* var_feedback) {
|
TVariable<Smi>* var_feedback) {
|
||||||
Label done(this), is_smi(this), is_heapnumber(this), maybe_bigint64(this),
|
Label done(this), is_smi(this), is_heapnumber(this), maybe_bigint64(this),
|
||||||
is_bigint(this), is_oddball(this);
|
is_bigint(this), is_oddball(this);
|
||||||
@ -8047,18 +8075,20 @@ void CodeStubAssembler::TaggedToBigInt(TNode<Context> context,
|
|||||||
TNode<Numeric> numeric_value = CAST(
|
TNode<Numeric> numeric_value = CAST(
|
||||||
CallBuiltin(Builtin::kNonNumberToNumeric, context, heap_object_value));
|
CallBuiltin(Builtin::kNonNumberToNumeric, context, heap_object_value));
|
||||||
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kAny);
|
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kAny);
|
||||||
GotoIf(TaggedIsSmi(numeric_value), if_not_bigint);
|
GotoIf(TaggedIsSmi(numeric_value), if_invalid);
|
||||||
GotoIfNot(IsBigInt(CAST(numeric_value)), if_not_bigint);
|
GotoIfNot(IsBigInt(CAST(numeric_value)), if_invalid);
|
||||||
*var_bigint = CAST(numeric_value);
|
*var_bigint = numeric_value;
|
||||||
Goto(if_bigint);
|
Goto(if_bigint);
|
||||||
|
|
||||||
BIND(&is_smi);
|
BIND(&is_smi);
|
||||||
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kSignedSmall);
|
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kSignedSmall);
|
||||||
Goto(if_not_bigint);
|
*var_bigint = CAST(value);
|
||||||
|
Goto(if_bigint);
|
||||||
|
|
||||||
BIND(&is_heapnumber);
|
BIND(&is_heapnumber);
|
||||||
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kNumber);
|
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kNumber);
|
||||||
Goto(if_not_bigint);
|
*var_bigint = CAST(value);
|
||||||
|
Goto(if_bigint);
|
||||||
|
|
||||||
if (Is64() && if_bigint64) {
|
if (Is64() && if_bigint64) {
|
||||||
BIND(&maybe_bigint64);
|
BIND(&maybe_bigint64);
|
||||||
@ -8074,8 +8104,9 @@ void CodeStubAssembler::TaggedToBigInt(TNode<Context> context,
|
|||||||
Goto(if_bigint);
|
Goto(if_bigint);
|
||||||
|
|
||||||
BIND(&is_oddball);
|
BIND(&is_oddball);
|
||||||
|
*var_bigint = SmiConstant(0);
|
||||||
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kNumberOrOddball);
|
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kNumberOrOddball);
|
||||||
Goto(if_not_bigint);
|
Goto(if_bigint);
|
||||||
}
|
}
|
||||||
|
|
||||||
// ES#sec-touint32
|
// ES#sec-touint32
|
||||||
|
@ -1893,7 +1893,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
|||||||
void StoreBigIntDigit(TNode<BigInt> bigint, TNode<IntPtrT> digit_index,
|
void StoreBigIntDigit(TNode<BigInt> bigint, TNode<IntPtrT> digit_index,
|
||||||
TNode<UintPtrT> digit);
|
TNode<UintPtrT> digit);
|
||||||
|
|
||||||
TNode<Word32T> LoadBigIntBitfield(TNode<BigInt> bigint);
|
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, intptr_t digit_index);
|
||||||
TNode<UintPtrT> LoadBigIntDigit(TNode<BigInt> bigint,
|
TNode<UintPtrT> LoadBigIntDigit(TNode<BigInt> bigint,
|
||||||
TNode<IntPtrT> digit_index);
|
TNode<IntPtrT> digit_index);
|
||||||
@ -2433,17 +2436,17 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
|||||||
void TaggedToWord32OrBigInt(TNode<Context> context, TNode<Object> value,
|
void TaggedToWord32OrBigInt(TNode<Context> context, TNode<Object> value,
|
||||||
Label* if_number, TVariable<Word32T>* var_word32,
|
Label* if_number, TVariable<Word32T>* var_word32,
|
||||||
Label* if_bigint, Label* if_bigint64,
|
Label* if_bigint, Label* if_bigint64,
|
||||||
TVariable<BigInt>* var_maybe_bigint);
|
TVariable<Numeric>* var_maybe_bigint);
|
||||||
void TaggedToWord32OrBigIntWithFeedback(TNode<Context> context,
|
void TaggedToWord32OrBigIntWithFeedback(TNode<Context> context,
|
||||||
TNode<Object> value, Label* if_number,
|
TNode<Object> value, Label* if_number,
|
||||||
TVariable<Word32T>* var_word32,
|
TVariable<Word32T>* var_word32,
|
||||||
Label* if_bigint, Label* if_bigint64,
|
Label* if_bigint, Label* if_bigint64,
|
||||||
TVariable<BigInt>* var_maybe_bigint,
|
TVariable<Numeric>* var_maybe_bigint,
|
||||||
TVariable<Smi>* var_feedback);
|
TVariable<Smi>* var_feedback);
|
||||||
void TaggedPointerToWord32OrBigIntWithFeedback(
|
void TaggedPointerToWord32OrBigIntWithFeedback(
|
||||||
TNode<Context> context, TNode<HeapObject> pointer, Label* if_number,
|
TNode<Context> context, TNode<HeapObject> pointer, Label* if_number,
|
||||||
TVariable<Word32T>* var_word32, Label* if_bigint, Label* if_bigint64,
|
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);
|
TNode<Int32T> TruncateNumberToWord32(TNode<Number> value);
|
||||||
// Truncate the floating point value of a HeapNumber to an Int32.
|
// 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,
|
void TaggedToBigInt(TNode<Context> context, TNode<Object> value,
|
||||||
Label* if_not_bigint, Label* if_bigint,
|
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);
|
TVariable<Smi>* var_feedback);
|
||||||
|
|
||||||
// Ensures that {var_shared_value} is shareable across Isolates, and throws if
|
// 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,
|
IsKnownTaggedPointer is_known_tagged_pointer,
|
||||||
Label* if_bigint = nullptr,
|
Label* if_bigint = nullptr,
|
||||||
Label* if_bigint64 = nullptr,
|
Label* if_bigint64 = nullptr,
|
||||||
TVariable<BigInt>* var_maybe_bigint = nullptr,
|
TVariable<Numeric>* var_maybe_bigint = nullptr,
|
||||||
TVariable<Smi>* var_feedback = nullptr);
|
TVariable<Smi>* var_feedback = nullptr);
|
||||||
|
|
||||||
// Low-level accessors for Descriptor arrays.
|
// Low-level accessors for Descriptor arrays.
|
||||||
|
@ -788,7 +788,7 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
|
|||||||
TVARIABLE(Smi, var_right_feedback);
|
TVARIABLE(Smi, var_right_feedback);
|
||||||
TVARIABLE(Word32T, var_left_word32);
|
TVARIABLE(Word32T, var_left_word32);
|
||||||
TVARIABLE(Word32T, var_right_word32);
|
TVARIABLE(Word32T, var_right_word32);
|
||||||
TVARIABLE(BigInt, var_left_bigint);
|
TVARIABLE(Numeric, var_left_bigint);
|
||||||
Label done(this);
|
Label done(this);
|
||||||
Label if_left_number(this), do_number_op(this);
|
Label if_left_number(this), do_number_op(this);
|
||||||
Label if_left_bigint(this), if_left_bigint64(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);
|
&var_left_bigint, slot ? &var_left_feedback : nullptr);
|
||||||
|
|
||||||
BIND(&if_left_number);
|
BIND(&if_left_number);
|
||||||
TaggedToWord32OrBigIntWithFeedback(
|
{
|
||||||
context(), right, &do_number_op, &var_right_word32,
|
TaggedToWord32OrBigIntWithFeedback(
|
||||||
&if_left_number_right_bigint, nullptr, nullptr,
|
context(), right, &do_number_op, &var_right_word32,
|
||||||
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);
|
BIND(&if_left_number_right_bigint);
|
||||||
{
|
{
|
||||||
if (slot) {
|
if (slot) {
|
||||||
@ -835,17 +839,17 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
|
|||||||
|
|
||||||
// BigInt cases.
|
// BigInt cases.
|
||||||
{
|
{
|
||||||
TVARIABLE(BigInt, var_right_bigint);
|
TVARIABLE(Numeric, var_right_bigint);
|
||||||
Label if_both_bigint(this), if_both_bigint64(this);
|
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);
|
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);
|
&var_right_bigint, slot ? &var_right_feedback : nullptr);
|
||||||
|
|
||||||
if (IsBigInt64OpSupported(this, bitwise_op)) {
|
if (IsBigInt64OpSupported(this, bitwise_op)) {
|
||||||
BIND(&if_left_bigint64);
|
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,
|
&if_both_bigint64, &var_right_bigint,
|
||||||
slot ? &var_right_feedback : nullptr);
|
slot ? &var_right_feedback : nullptr);
|
||||||
|
|
||||||
@ -860,8 +864,12 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
|
|||||||
|
|
||||||
TVARIABLE(UintPtrT, left_raw);
|
TVARIABLE(UintPtrT, left_raw);
|
||||||
TVARIABLE(UintPtrT, right_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) {
|
switch (bitwise_op) {
|
||||||
case Operation::kBitwiseAnd: {
|
case Operation::kBitwiseAnd: {
|
||||||
@ -995,14 +1003,14 @@ TNode<Object> BinaryOpAssembler::Generate_BitwiseBinaryOpWithOptionalFeedback(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BIND(&if_bigint_mix);
|
BIND(&if_invalid);
|
||||||
{
|
{
|
||||||
if (slot) {
|
if (slot) {
|
||||||
// Ensure that the feedback is updated before we throw.
|
// Ensure that the feedback is updated before we throw.
|
||||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
||||||
(*maybe_feedback_vector)(), *slot, update_feedback_mode);
|
(*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(Object, result);
|
||||||
TVARIABLE(Smi, var_left_feedback);
|
TVARIABLE(Smi, var_left_feedback);
|
||||||
TVARIABLE(Word32T, var_left_word32);
|
TVARIABLE(Word32T, var_left_word32);
|
||||||
TVARIABLE(BigInt, var_left_bigint);
|
TVARIABLE(Numeric, var_left_bigint);
|
||||||
TVARIABLE(Smi, feedback);
|
TVARIABLE(Smi, feedback);
|
||||||
// Check if the {lhs} is a Smi or a HeapObject.
|
// Check if the {lhs} is a Smi or a HeapObject.
|
||||||
Label if_lhsissmi(this), if_lhsisnotsmi(this, Label::kDeferred);
|
Label if_lhsissmi(this), if_lhsisnotsmi(this);
|
||||||
Label do_number_op(this), if_bigint_mix(this), done(this);
|
Label do_number_op(this), if_bigint_mix(this), done(this), done2(this),
|
||||||
|
mixedBigInt(this);
|
||||||
|
|
||||||
Branch(TaggedIsSmi(left), &if_lhsissmi, &if_lhsisnotsmi);
|
Branch(TaggedIsSmi(left), &if_lhsissmi, &if_lhsisnotsmi);
|
||||||
|
|
||||||
@ -1065,18 +1074,118 @@ BinaryOpAssembler::Generate_BitwiseBinaryOpWithSmiOperandAndOptionalFeedback(
|
|||||||
|
|
||||||
BIND(&if_bigint_mix);
|
BIND(&if_bigint_mix);
|
||||||
{
|
{
|
||||||
if (slot) {
|
Goto(&mixedBigInt);
|
||||||
// Ensure that the feedback is updated before we throw.
|
}
|
||||||
UpdateFeedback(SmiConstant(BinaryOperationFeedback::kAny),
|
}
|
||||||
(*maybe_feedback_vector)(), *slot, update_feedback_mode);
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
ThrowTypeError(context(), MessageTemplate::kBigIntMixedTypes);
|
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);
|
||||||
|
}
|
||||||
|
// BigInt does not support logical right shift.
|
||||||
|
ThrowTypeError(context(), MessageTemplate::kBigIntShr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
BIND(&done);
|
BIND(&done);
|
||||||
UpdateFeedback(feedback.value(), (*maybe_feedback_vector)(), *slot,
|
UpdateFeedback(feedback.value(), (*maybe_feedback_vector)(), *slot,
|
||||||
update_feedback_mode);
|
update_feedback_mode);
|
||||||
|
Goto(&done2);
|
||||||
|
|
||||||
|
BIND(&done2);
|
||||||
return result.value();
|
return result.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,7 @@ class UnaryOpAssemblerImpl final : public CodeStubAssembler {
|
|||||||
// mechanism).
|
// mechanism).
|
||||||
TVARIABLE(Word32T, var_word32);
|
TVARIABLE(Word32T, var_word32);
|
||||||
TVARIABLE(Smi, var_feedback);
|
TVARIABLE(Smi, var_feedback);
|
||||||
TVARIABLE(BigInt, var_bigint);
|
TVARIABLE(Numeric, var_bigint);
|
||||||
TVARIABLE(Object, var_result);
|
TVARIABLE(Object, var_result);
|
||||||
Label if_number(this), if_bigint(this, Label::kDeferred), out(this);
|
Label if_number(this), if_bigint(this, Label::kDeferred), out(this);
|
||||||
TaggedToWord32OrBigIntWithFeedback(context, value, &if_number, &var_word32,
|
TaggedToWord32OrBigIntWithFeedback(context, value, &if_number, &var_word32,
|
||||||
|
@ -121,12 +121,32 @@ RUNTIME_FUNCTION(Runtime_BigIntBinaryOp) {
|
|||||||
int opcode = args.smi_value_at(2);
|
int opcode = args.smi_value_at(2);
|
||||||
Operation op = static_cast<Operation>(opcode);
|
Operation op = static_cast<Operation>(opcode);
|
||||||
|
|
||||||
if (!left_obj->IsBigInt() || !right_obj->IsBigInt()) {
|
Handle<BigInt> left ;
|
||||||
THROW_NEW_ERROR_RETURN_FAILURE(
|
Handle<BigInt> right;
|
||||||
isolate, NewTypeError(MessageTemplate::kBigIntMixedTypes));
|
|
||||||
|
if (!left_obj->IsBigInt()) {
|
||||||
|
auto mebi = BigInt::FromObject(isolate, left_obj);
|
||||||
|
if (mebi.is_null()) {
|
||||||
|
THROW_NEW_ERROR_RETURN_FAILURE(
|
||||||
|
isolate, NewTypeError(MessageTemplate::kBigIntMixedTypes));
|
||||||
|
}
|
||||||
|
left = mebi.ToHandleChecked();
|
||||||
}
|
}
|
||||||
Handle<BigInt> left(Handle<BigInt>::cast(left_obj));
|
else {
|
||||||
Handle<BigInt> right(Handle<BigInt>::cast(right_obj));
|
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;
|
MaybeHandle<BigInt> result;
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case Operation::kAdd:
|
case Operation::kAdd:
|
||||||
|
@ -109,10 +109,9 @@ inline std::string PositionAsString(SourcePosition pos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, 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)
|
<< SourceFileMap::PathFromV8Root(pos.source)
|
||||||
<< "?l=" << (pos.start.line + 1)
|
<< "#L" << (pos.start.line + 1);
|
||||||
<< "&c=" << (pos.start.column + 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace torque
|
} // namespace torque
|
||||||
|
Loading…
Reference in New Issue
Block a user