[turbofan] Inline BigInt Constructor for Integral32 input
This CL introduces two JS operators JSToBigInt and JSToBigIntConvertNumber and one simplified operator Integral32OrMinusZeroToBigInt. - BigInt constructors are lowered to JSToBigIntConvertNumber in the inlining phase. - JSToBigIntConvertNumber is replaced with Integral32OrMinusZeroToBigInt if the input is typed as Integral32 in typed lowering. - In simplified lowering, Integral32OrMinusZeroToBigInt is lowered to conversion to word64 accordingly. - If the input is not Integral32 or BigInt, JSToBigIntConvertNumber is lowered to a builtin call in generic lowering. Bug: v8:9407 Change-Id: I8539d742e82cce515bd9350797f5f9b0876ee6f2 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4055670 Reviewed-by: Igor Sheludko <ishell@chromium.org> Reviewed-by: Nico Hartmann <nicohartmann@chromium.org> Commit-Queue: Qifan Pan <panq@google.com> Cr-Commit-Position: refs/heads/main@{#84761}
This commit is contained in:
parent
458cda96fe
commit
753584c74b
@ -21,6 +21,13 @@ TF_BUILTIN(ToNumber, CodeStubAssembler) {
|
||||
Return(ToNumber(context, input));
|
||||
}
|
||||
|
||||
TF_BUILTIN(ToBigInt, CodeStubAssembler) {
|
||||
auto context = Parameter<Context>(Descriptor::kContext);
|
||||
auto input = Parameter<Object>(Descriptor::kArgument);
|
||||
|
||||
Return(ToBigInt(context, input));
|
||||
}
|
||||
|
||||
TF_BUILTIN(ToNumber_Baseline, CodeStubAssembler) {
|
||||
auto input = Parameter<Object>(Descriptor::kArgument);
|
||||
auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot);
|
||||
@ -63,6 +70,13 @@ TF_BUILTIN(ToNumberConvertBigInt, CodeStubAssembler) {
|
||||
Return(ToNumber(context, input, BigIntHandling::kConvertToNumber));
|
||||
}
|
||||
|
||||
TF_BUILTIN(ToBigIntConvertNumber, CodeStubAssembler) {
|
||||
auto context = Parameter<Context>(Descriptor::kContext);
|
||||
auto input = Parameter<Object>(Descriptor::kArgument);
|
||||
|
||||
Return(ToBigIntConvertNumber(context, input));
|
||||
}
|
||||
|
||||
// ES6 section 7.1.2 ToBoolean ( argument )
|
||||
// Requires parameter on stack so that it can be used as a continuation from a
|
||||
// LAZY deopt.
|
||||
|
@ -257,10 +257,12 @@ namespace internal {
|
||||
\
|
||||
/* Type conversions */ \
|
||||
TFC(ToNumber, TypeConversion) \
|
||||
TFC(ToBigInt, TypeConversion) \
|
||||
TFC(ToNumber_Baseline, TypeConversion_Baseline) \
|
||||
TFC(ToNumeric_Baseline, TypeConversion_Baseline) \
|
||||
TFC(PlainPrimitiveToNumber, TypeConversionNoContext) \
|
||||
TFC(ToNumberConvertBigInt, TypeConversion) \
|
||||
TFC(ToBigIntConvertNumber, TypeConversion) \
|
||||
TFC(Typeof, Typeof) \
|
||||
TFC(BigIntToI64, BigIntToI64) \
|
||||
TFC(BigIntToI32Pair, BigIntToI32Pair) \
|
||||
|
@ -7960,6 +7960,28 @@ TNode<BigInt> CodeStubAssembler::ToBigInt(TNode<Context> context,
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
TNode<BigInt> CodeStubAssembler::ToBigIntConvertNumber(TNode<Context> context,
|
||||
TNode<Object> input) {
|
||||
TVARIABLE(BigInt, var_result);
|
||||
Label if_bigint(this), if_not_bigint(this), done(this);
|
||||
|
||||
GotoIf(TaggedIsSmi(input), &if_not_bigint);
|
||||
GotoIf(IsBigInt(CAST(input)), &if_bigint);
|
||||
Goto(&if_not_bigint);
|
||||
|
||||
BIND(&if_bigint);
|
||||
var_result = CAST(input);
|
||||
Goto(&done);
|
||||
|
||||
BIND(&if_not_bigint);
|
||||
var_result =
|
||||
CAST(CallRuntime(Runtime::kToBigIntConvertNumber, context, input));
|
||||
Goto(&done);
|
||||
|
||||
BIND(&done);
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
void CodeStubAssembler::TaggedToBigIntWithFeedback(
|
||||
TNode<Context> context, TNode<Object> value, Label* if_not_bigint,
|
||||
Label* if_bigint, Label* if_bigint64, TVariable<BigInt>* var_bigint,
|
||||
|
@ -2871,6 +2871,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
// Try to convert an object to a BigInt. Throws on failure (e.g. for Numbers).
|
||||
// https://tc39.github.io/proposal-bigint/#sec-to-bigint
|
||||
TNode<BigInt> ToBigInt(TNode<Context> context, TNode<Object> input);
|
||||
// Try to convert any object to a BigInt, including Numbers.
|
||||
TNode<BigInt> ToBigIntConvertNumber(TNode<Context> context,
|
||||
TNode<Object> input);
|
||||
|
||||
// Converts |input| to one of 2^32 integer values in the range 0 through
|
||||
// 2^32-1, inclusive.
|
||||
|
@ -3144,7 +3144,7 @@ Node* EffectControlLinearizer::LowerChangeInt64ToBigInt(Node* node) {
|
||||
Node* bitfield =
|
||||
__ Word32Or(__ Int32Constant(BigInt::LengthBits::encode(1)), sign);
|
||||
|
||||
// We use (value XOR (value >>> 63)) - (value >>> 63) to compute the
|
||||
// We use (value XOR (value >> 63)) - (value >> 63) to compute the
|
||||
// absolute value, in a branchless fashion.
|
||||
Node* sign_mask = __ Word64Sar(value, __ Int64Constant(63));
|
||||
Node* absolute_value = __ Int64Sub(__ Word64Xor(value, sign_mask), sign_mask);
|
||||
|
@ -4892,6 +4892,8 @@ Reduction JSCallReducer::ReduceJSCall(Node* node,
|
||||
return ReduceDateNow(node);
|
||||
case Builtin::kNumberConstructor:
|
||||
return ReduceNumberConstructor(node);
|
||||
case Builtin::kBigIntConstructor:
|
||||
return ReduceBigIntConstructor(node);
|
||||
case Builtin::kBigIntAsIntN:
|
||||
case Builtin::kBigIntAsUintN:
|
||||
return ReduceBigIntAsN(node, builtin);
|
||||
@ -8328,6 +8330,39 @@ Reduction JSCallReducer::ReduceNumberConstructor(Node* node) {
|
||||
return Changed(node);
|
||||
}
|
||||
|
||||
// ES section #sec-bigint-constructor
|
||||
Reduction JSCallReducer::ReduceBigIntConstructor(Node* node) {
|
||||
if (!jsgraph()->machine()->Is64()) return NoChange();
|
||||
|
||||
JSCallNode n(node);
|
||||
if (n.ArgumentCount() < 1) {
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
Node* target = n.target();
|
||||
Node* receiver = n.receiver();
|
||||
Node* value = n.Argument(0);
|
||||
Node* context = n.context();
|
||||
FrameState frame_state = n.frame_state();
|
||||
|
||||
// Create the artificial frame state in the middle of the BigInt constructor.
|
||||
SharedFunctionInfoRef shared_info =
|
||||
native_context().bigint_function().shared();
|
||||
Node* stack_parameters[] = {receiver};
|
||||
int stack_parameter_count = arraysize(stack_parameters);
|
||||
Node* continuation_frame_state =
|
||||
CreateJavaScriptBuiltinContinuationFrameState(
|
||||
jsgraph(), shared_info, Builtin::kGenericLazyDeoptContinuation,
|
||||
target, context, stack_parameters, stack_parameter_count, frame_state,
|
||||
ContinuationFrameStateMode::LAZY);
|
||||
|
||||
// Convert the {value} to a BigInt.
|
||||
NodeProperties::ReplaceValueInputs(node, value);
|
||||
NodeProperties::ChangeOp(node, javascript()->ToBigIntConvertNumber());
|
||||
NodeProperties::ReplaceFrameStateInput(node, continuation_frame_state);
|
||||
return Changed(node);
|
||||
}
|
||||
|
||||
Reduction JSCallReducer::ReduceBigIntAsN(Node* node, Builtin builtin) {
|
||||
DCHECK(builtin == Builtin::kBigIntAsIntN ||
|
||||
builtin == Builtin::kBigIntAsUintN);
|
||||
|
@ -231,6 +231,7 @@ class V8_EXPORT_PRIVATE JSCallReducer final : public AdvancedReducer {
|
||||
Reduction ReduceNumberParseInt(Node* node);
|
||||
|
||||
Reduction ReduceNumberConstructor(Node* node);
|
||||
Reduction ReduceBigIntConstructor(Node* node);
|
||||
Reduction ReduceBigIntAsN(Node* node, Builtin builtin);
|
||||
|
||||
base::Optional<Reduction> TryReduceJSCallMathMinMaxWithArrayLike(Node* node);
|
||||
|
@ -63,6 +63,8 @@ Reduction JSGenericLowering::Reduce(Node* node) {
|
||||
REPLACE_STUB_CALL(ToLength)
|
||||
REPLACE_STUB_CALL(ToNumber)
|
||||
REPLACE_STUB_CALL(ToNumberConvertBigInt)
|
||||
REPLACE_STUB_CALL(ToBigInt)
|
||||
REPLACE_STUB_CALL(ToBigIntConvertNumber)
|
||||
REPLACE_STUB_CALL(ToNumeric)
|
||||
REPLACE_STUB_CALL(ToName)
|
||||
REPLACE_STUB_CALL(ToObject)
|
||||
|
@ -741,6 +741,8 @@ Type JSWasmCallNode::TypeForWasmReturnType(const wasm::ValueType& type) {
|
||||
V(ToName, Operator::kNoProperties, 1, 1) \
|
||||
V(ToNumber, Operator::kNoProperties, 1, 1) \
|
||||
V(ToNumberConvertBigInt, Operator::kNoProperties, 1, 1) \
|
||||
V(ToBigInt, Operator::kNoProperties, 1, 1) \
|
||||
V(ToBigIntConvertNumber, Operator::kNoProperties, 1, 1) \
|
||||
V(ToNumeric, Operator::kNoProperties, 1, 1) \
|
||||
V(ToObject, Operator::kFoldable, 1, 1) \
|
||||
V(ToString, Operator::kNoProperties, 1, 1) \
|
||||
|
@ -935,6 +935,8 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
|
||||
const Operator* ToName();
|
||||
const Operator* ToNumber();
|
||||
const Operator* ToNumberConvertBigInt();
|
||||
const Operator* ToBigInt();
|
||||
const Operator* ToBigIntConvertNumber();
|
||||
const Operator* ToNumeric();
|
||||
const Operator* ToObject();
|
||||
const Operator* ToString();
|
||||
|
@ -1044,6 +1044,37 @@ Reduction JSTypedLowering::ReduceJSToNumber(Node* node) {
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
Reduction JSTypedLowering::ReduceJSToBigInt(Node* node) {
|
||||
// TODO(panq): Reduce constant inputs.
|
||||
Node* const input = node->InputAt(0);
|
||||
Type const input_type = NodeProperties::GetType(input);
|
||||
if (input_type.Is(Type::BigInt())) {
|
||||
ReplaceWithValue(node, input);
|
||||
return Changed(input);
|
||||
}
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
Reduction JSTypedLowering::ReduceJSToBigIntConvertNumber(Node* node) {
|
||||
// TODO(panq): Reduce constant inputs.
|
||||
Node* const input = node->InputAt(0);
|
||||
Type const input_type = NodeProperties::GetType(input);
|
||||
if (input_type.Is(Type::BigInt())) {
|
||||
ReplaceWithValue(node, input);
|
||||
return Changed(input);
|
||||
} else if (input_type.Is(Type::Integral32OrMinusZero())) {
|
||||
RelaxEffectsAndControls(node);
|
||||
node->TrimInputCount(1);
|
||||
Type node_type = NodeProperties::GetType(node);
|
||||
NodeProperties::SetType(
|
||||
node, Type::Intersect(node_type, Type::BigInt(), graph()->zone()));
|
||||
NodeProperties::ChangeOp(node,
|
||||
simplified()->Integral32OrMinusZeroToBigInt());
|
||||
return Changed(node);
|
||||
}
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
Reduction JSTypedLowering::ReduceJSToNumeric(Node* node) {
|
||||
Node* const input = NodeProperties::GetValueInput(node, 0);
|
||||
Type const input_type = NodeProperties::GetType(input);
|
||||
@ -2395,6 +2426,10 @@ Reduction JSTypedLowering::Reduce(Node* node) {
|
||||
case IrOpcode::kJSToNumber:
|
||||
case IrOpcode::kJSToNumberConvertBigInt:
|
||||
return ReduceJSToNumber(node);
|
||||
case IrOpcode::kJSToBigInt:
|
||||
return ReduceJSToBigInt(node);
|
||||
case IrOpcode::kJSToBigIntConvertNumber:
|
||||
return ReduceJSToBigIntConvertNumber(node);
|
||||
case IrOpcode::kJSToNumeric:
|
||||
return ReduceJSToNumeric(node);
|
||||
case IrOpcode::kJSToString:
|
||||
|
@ -61,6 +61,8 @@ class V8_EXPORT_PRIVATE JSTypedLowering final
|
||||
Reduction ReduceJSToName(Node* node);
|
||||
Reduction ReduceJSToNumberInput(Node* input);
|
||||
Reduction ReduceJSToNumber(Node* node);
|
||||
Reduction ReduceJSToBigInt(Node* node);
|
||||
Reduction ReduceJSToBigIntConvertNumber(Node* node);
|
||||
Reduction ReduceJSToNumeric(Node* node);
|
||||
Reduction ReduceJSToStringInput(Node* input);
|
||||
Reduction ReduceJSToString(Node* node);
|
||||
|
@ -133,6 +133,8 @@
|
||||
V(JSToName) \
|
||||
V(JSToNumber) \
|
||||
V(JSToNumberConvertBigInt) \
|
||||
V(JSToBigInt) \
|
||||
V(JSToBigIntConvertNumber) \
|
||||
V(JSToNumeric) \
|
||||
V(JSToObject) \
|
||||
V(JSToString) \
|
||||
@ -409,6 +411,7 @@
|
||||
V(NumberToString) \
|
||||
V(NumberToUint32) \
|
||||
V(NumberToUint8Clamped) \
|
||||
V(Integral32OrMinusZeroToBigInt) \
|
||||
V(NumberSilenceNaN)
|
||||
|
||||
#define SIMPLIFIED_BIGINT_UNOP_LIST(V) \
|
||||
|
@ -310,6 +310,27 @@ Type OperationTyper::ToNumberConvertBigInt(Type type) {
|
||||
return maybe_bigint ? Type::Union(type, cache_->kInteger, zone()) : type;
|
||||
}
|
||||
|
||||
Type OperationTyper::ToBigInt(Type type) {
|
||||
if (type.Is(Type::BigInt())) {
|
||||
return type;
|
||||
}
|
||||
|
||||
return Type::BigInt();
|
||||
}
|
||||
|
||||
Type OperationTyper::ToBigIntConvertNumber(Type type) {
|
||||
if (type.Is(Type::Signed32OrMinusZero())) {
|
||||
return Type::SignedBigInt64();
|
||||
} else if (type.Is(Type::Unsigned32OrMinusZero())) {
|
||||
return Type::UnsignedBigInt63();
|
||||
}
|
||||
|
||||
bool maybe_number =
|
||||
type.Maybe(Type::Number()) || type.Maybe(Type::Receiver());
|
||||
type = ToBigInt(Type::Intersect(type, Type::NonNumber(), zone()));
|
||||
return maybe_number ? Type::Union(type, Type::BigInt(), zone()) : type;
|
||||
}
|
||||
|
||||
Type OperationTyper::ToNumeric(Type type) {
|
||||
// If the {type} includes any receivers, then the callbacks
|
||||
// might actually produce BigInt primitive values here.
|
||||
@ -566,6 +587,18 @@ Type OperationTyper::NumberToUint8Clamped(Type type) {
|
||||
return cache_->kUint8;
|
||||
}
|
||||
|
||||
Type OperationTyper::Integral32OrMinusZeroToBigInt(Type type) {
|
||||
DCHECK(type.Is(Type::Number()));
|
||||
|
||||
if (type.Is(Type::Signed32())) {
|
||||
return Type::SignedBigInt64();
|
||||
}
|
||||
if (type.Is(Type::Unsigned32())) {
|
||||
return Type::UnsignedBigInt63();
|
||||
}
|
||||
return Type::BigInt();
|
||||
}
|
||||
|
||||
Type OperationTyper::NumberSilenceNaN(Type type) {
|
||||
DCHECK(type.Is(Type::Number()));
|
||||
// TODO(jarin): This is a terrible hack; we definitely need a dedicated type
|
||||
|
@ -54,6 +54,8 @@ class V8_EXPORT_PRIVATE OperationTyper {
|
||||
Type ToPrimitive(Type type);
|
||||
Type ToNumber(Type type);
|
||||
Type ToNumberConvertBigInt(Type type);
|
||||
Type ToBigInt(Type type);
|
||||
Type ToBigIntConvertNumber(Type type);
|
||||
Type ToNumeric(Type type);
|
||||
Type ToBoolean(Type type);
|
||||
|
||||
|
@ -213,6 +213,8 @@ bool OperatorProperties::HasFrameStateInput(const Operator* op) {
|
||||
case IrOpcode::kJSToName:
|
||||
case IrOpcode::kJSToNumber:
|
||||
case IrOpcode::kJSToNumberConvertBigInt:
|
||||
case IrOpcode::kJSToBigInt:
|
||||
case IrOpcode::kJSToBigIntConvertNumber:
|
||||
case IrOpcode::kJSToNumeric:
|
||||
case IrOpcode::kJSToObject:
|
||||
case IrOpcode::kJSToString:
|
||||
|
@ -1252,7 +1252,10 @@ Node* RepresentationChanger::GetWord64RepresentationFor(
|
||||
use_node, use_info);
|
||||
op = simplified()->TruncateBigIntToWord64();
|
||||
} else if (CanBeTaggedPointer(output_rep)) {
|
||||
if (output_type.Is(cache_->kDoubleRepresentableInt64)) {
|
||||
if (output_type.Is(cache_->kDoubleRepresentableInt64) ||
|
||||
(output_type.Is(Type::MinusZero()) &&
|
||||
use_info.minus_zero_check() ==
|
||||
CheckForMinusZeroMode::kDontCheckForMinusZero)) {
|
||||
op = simplified()->ChangeTaggedToInt64();
|
||||
} else if (use_info.type_check() == TypeCheckKind::kSigned64) {
|
||||
op = simplified()->CheckedTaggedToInt64(
|
||||
|
@ -2274,6 +2274,12 @@ class RepresentationSelector {
|
||||
}
|
||||
return;
|
||||
}
|
||||
case IrOpcode::kJSToBigInt:
|
||||
case IrOpcode::kJSToBigIntConvertNumber: {
|
||||
VisitInputs<T>(node);
|
||||
SetOutput<T>(node, MachineRepresentation::kTaggedPointer);
|
||||
return;
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------
|
||||
// Simplified operators.
|
||||
@ -3199,6 +3205,16 @@ class RepresentationSelector {
|
||||
}
|
||||
return;
|
||||
}
|
||||
case IrOpcode::kIntegral32OrMinusZeroToBigInt: {
|
||||
VisitUnop<T>(node, UseInfo::Word64(kIdentifyZeros),
|
||||
MachineRepresentation::kWord64);
|
||||
if (lower<T>()) {
|
||||
DeferReplacement(
|
||||
node, InsertTypeOverrideForVerifier(NodeProperties::GetType(node),
|
||||
node->InputAt(0)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
case IrOpcode::kReferenceEqual: {
|
||||
VisitBinop<T>(node, UseInfo::AnyTagged(), MachineRepresentation::kBit);
|
||||
if (lower<T>()) {
|
||||
|
@ -683,129 +683,130 @@ bool operator==(CheckMinusZeroParameters const& lhs,
|
||||
return lhs.mode() == rhs.mode() && lhs.feedback() == rhs.feedback();
|
||||
}
|
||||
|
||||
#define PURE_OP_LIST(V) \
|
||||
V(BooleanNot, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberEqual, Operator::kCommutative, 2, 0) \
|
||||
V(NumberLessThan, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberLessThanOrEqual, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberAdd, Operator::kCommutative, 2, 0) \
|
||||
V(NumberSubtract, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberMultiply, Operator::kCommutative, 2, 0) \
|
||||
V(NumberDivide, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberModulus, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberBitwiseOr, Operator::kCommutative, 2, 0) \
|
||||
V(NumberBitwiseXor, Operator::kCommutative, 2, 0) \
|
||||
V(NumberBitwiseAnd, Operator::kCommutative, 2, 0) \
|
||||
V(NumberShiftLeft, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberShiftRight, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberShiftRightLogical, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberImul, Operator::kCommutative, 2, 0) \
|
||||
V(NumberAbs, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberClz32, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberCeil, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberFloor, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberFround, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberAcos, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberAcosh, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberAsin, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberAsinh, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberAtan, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberAtan2, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberAtanh, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberCbrt, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberCos, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberCosh, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberExp, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberExpm1, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberLog, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberLog1p, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberLog10, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberLog2, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberMax, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberMin, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberPow, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberRound, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberSign, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberSin, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberSinh, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberSqrt, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberTan, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberTanh, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberTrunc, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberToBoolean, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberToInt32, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberToString, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberToUint32, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberToUint8Clamped, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberSilenceNaN, Operator::kNoProperties, 1, 0) \
|
||||
V(BigIntNegate, Operator::kNoProperties, 1, 0) \
|
||||
V(StringConcat, Operator::kNoProperties, 3, 0) \
|
||||
V(StringToNumber, Operator::kNoProperties, 1, 0) \
|
||||
V(StringFromSingleCharCode, Operator::kNoProperties, 1, 0) \
|
||||
V(StringFromSingleCodePoint, Operator::kNoProperties, 1, 0) \
|
||||
V(StringIndexOf, Operator::kNoProperties, 3, 0) \
|
||||
V(StringLength, Operator::kNoProperties, 1, 0) \
|
||||
V(StringToLowerCaseIntl, Operator::kNoProperties, 1, 0) \
|
||||
V(StringToUpperCaseIntl, Operator::kNoProperties, 1, 0) \
|
||||
V(TypeOf, Operator::kNoProperties, 1, 1) \
|
||||
V(PlainPrimitiveToNumber, Operator::kNoProperties, 1, 0) \
|
||||
V(PlainPrimitiveToWord32, Operator::kNoProperties, 1, 0) \
|
||||
V(PlainPrimitiveToFloat64, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedSignedToInt32, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedSignedToInt64, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedToInt32, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedToInt64, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedToUint32, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedToFloat64, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedToTaggedSigned, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeFloat64ToTaggedPointer, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeInt31ToTaggedSigned, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeInt32ToTagged, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeInt64ToTagged, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeUint32ToTagged, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeUint64ToTagged, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedToBit, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeBitToTagged, Operator::kNoProperties, 1, 0) \
|
||||
V(TruncateBigIntToWord64, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeInt64ToBigInt, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeUint64ToBigInt, Operator::kNoProperties, 1, 0) \
|
||||
V(TruncateTaggedToBit, Operator::kNoProperties, 1, 0) \
|
||||
V(TruncateTaggedPointerToBit, Operator::kNoProperties, 1, 0) \
|
||||
V(TruncateTaggedToWord32, Operator::kNoProperties, 1, 0) \
|
||||
V(TruncateTaggedToFloat64, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsArrayBufferView, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsBigInt, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsCallable, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsConstructor, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsDetectableCallable, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsMinusZero, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberIsMinusZero, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsNaN, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberIsNaN, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsNonCallable, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsNumber, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsReceiver, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsSmi, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsString, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsSymbol, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsUndetectable, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberIsFloat64Hole, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberIsFinite, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsFiniteNumber, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberIsInteger, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsSafeInteger, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberIsSafeInteger, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsInteger, Operator::kNoProperties, 1, 0) \
|
||||
V(ConvertTaggedHoleToUndefined, Operator::kNoProperties, 1, 0) \
|
||||
V(SameValue, Operator::kCommutative, 2, 0) \
|
||||
V(SameValueNumbersOnly, Operator::kCommutative, 2, 0) \
|
||||
V(NumberSameValue, Operator::kCommutative, 2, 0) \
|
||||
V(ReferenceEqual, Operator::kCommutative, 2, 0) \
|
||||
V(StringEqual, Operator::kCommutative, 2, 0) \
|
||||
V(StringLessThan, Operator::kNoProperties, 2, 0) \
|
||||
V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0) \
|
||||
V(ToBoolean, Operator::kNoProperties, 1, 0) \
|
||||
V(NewConsString, Operator::kNoProperties, 3, 0) \
|
||||
#define PURE_OP_LIST(V) \
|
||||
V(BooleanNot, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberEqual, Operator::kCommutative, 2, 0) \
|
||||
V(NumberLessThan, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberLessThanOrEqual, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberAdd, Operator::kCommutative, 2, 0) \
|
||||
V(NumberSubtract, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberMultiply, Operator::kCommutative, 2, 0) \
|
||||
V(NumberDivide, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberModulus, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberBitwiseOr, Operator::kCommutative, 2, 0) \
|
||||
V(NumberBitwiseXor, Operator::kCommutative, 2, 0) \
|
||||
V(NumberBitwiseAnd, Operator::kCommutative, 2, 0) \
|
||||
V(NumberShiftLeft, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberShiftRight, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberShiftRightLogical, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberImul, Operator::kCommutative, 2, 0) \
|
||||
V(NumberAbs, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberClz32, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberCeil, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberFloor, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberFround, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberAcos, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberAcosh, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberAsin, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberAsinh, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberAtan, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberAtan2, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberAtanh, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberCbrt, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberCos, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberCosh, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberExp, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberExpm1, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberLog, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberLog1p, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberLog10, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberLog2, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberMax, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberMin, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberPow, Operator::kNoProperties, 2, 0) \
|
||||
V(NumberRound, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberSign, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberSin, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberSinh, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberSqrt, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberTan, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberTanh, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberTrunc, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberToBoolean, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberToInt32, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberToString, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberToUint32, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberToUint8Clamped, Operator::kNoProperties, 1, 0) \
|
||||
V(Integral32OrMinusZeroToBigInt, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberSilenceNaN, Operator::kNoProperties, 1, 0) \
|
||||
V(BigIntNegate, Operator::kNoProperties, 1, 0) \
|
||||
V(StringConcat, Operator::kNoProperties, 3, 0) \
|
||||
V(StringToNumber, Operator::kNoProperties, 1, 0) \
|
||||
V(StringFromSingleCharCode, Operator::kNoProperties, 1, 0) \
|
||||
V(StringFromSingleCodePoint, Operator::kNoProperties, 1, 0) \
|
||||
V(StringIndexOf, Operator::kNoProperties, 3, 0) \
|
||||
V(StringLength, Operator::kNoProperties, 1, 0) \
|
||||
V(StringToLowerCaseIntl, Operator::kNoProperties, 1, 0) \
|
||||
V(StringToUpperCaseIntl, Operator::kNoProperties, 1, 0) \
|
||||
V(TypeOf, Operator::kNoProperties, 1, 1) \
|
||||
V(PlainPrimitiveToNumber, Operator::kNoProperties, 1, 0) \
|
||||
V(PlainPrimitiveToWord32, Operator::kNoProperties, 1, 0) \
|
||||
V(PlainPrimitiveToFloat64, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedSignedToInt32, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedSignedToInt64, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedToInt32, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedToInt64, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedToUint32, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedToFloat64, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedToTaggedSigned, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeFloat64ToTaggedPointer, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeInt31ToTaggedSigned, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeInt32ToTagged, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeInt64ToTagged, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeUint32ToTagged, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeUint64ToTagged, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeTaggedToBit, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeBitToTagged, Operator::kNoProperties, 1, 0) \
|
||||
V(TruncateBigIntToWord64, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeInt64ToBigInt, Operator::kNoProperties, 1, 0) \
|
||||
V(ChangeUint64ToBigInt, Operator::kNoProperties, 1, 0) \
|
||||
V(TruncateTaggedToBit, Operator::kNoProperties, 1, 0) \
|
||||
V(TruncateTaggedPointerToBit, Operator::kNoProperties, 1, 0) \
|
||||
V(TruncateTaggedToWord32, Operator::kNoProperties, 1, 0) \
|
||||
V(TruncateTaggedToFloat64, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsArrayBufferView, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsBigInt, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsCallable, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsConstructor, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsDetectableCallable, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsMinusZero, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberIsMinusZero, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsNaN, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberIsNaN, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsNonCallable, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsNumber, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsReceiver, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsSmi, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsString, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsSymbol, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsUndetectable, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberIsFloat64Hole, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberIsFinite, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsFiniteNumber, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberIsInteger, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsSafeInteger, Operator::kNoProperties, 1, 0) \
|
||||
V(NumberIsSafeInteger, Operator::kNoProperties, 1, 0) \
|
||||
V(ObjectIsInteger, Operator::kNoProperties, 1, 0) \
|
||||
V(ConvertTaggedHoleToUndefined, Operator::kNoProperties, 1, 0) \
|
||||
V(SameValue, Operator::kCommutative, 2, 0) \
|
||||
V(SameValueNumbersOnly, Operator::kCommutative, 2, 0) \
|
||||
V(NumberSameValue, Operator::kCommutative, 2, 0) \
|
||||
V(ReferenceEqual, Operator::kCommutative, 2, 0) \
|
||||
V(StringEqual, Operator::kCommutative, 2, 0) \
|
||||
V(StringLessThan, Operator::kNoProperties, 2, 0) \
|
||||
V(StringLessThanOrEqual, Operator::kNoProperties, 2, 0) \
|
||||
V(ToBoolean, Operator::kNoProperties, 1, 0) \
|
||||
V(NewConsString, Operator::kNoProperties, 3, 0) \
|
||||
V(Unsigned32Divide, Operator::kNoProperties, 2, 0)
|
||||
|
||||
#define EFFECT_DEPENDENT_OP_LIST(V) \
|
||||
|
@ -779,6 +779,7 @@ class V8_EXPORT_PRIVATE SimplifiedOperatorBuilder final
|
||||
const Operator* NumberToString();
|
||||
const Operator* NumberToUint32();
|
||||
const Operator* NumberToUint8Clamped();
|
||||
const Operator* Integral32OrMinusZeroToBigInt();
|
||||
|
||||
const Operator* NumberSilenceNaN();
|
||||
|
||||
|
@ -341,6 +341,8 @@ class Typer::Visitor : public Reducer {
|
||||
static Type ToName(Type, Typer*);
|
||||
static Type ToNumber(Type, Typer*);
|
||||
static Type ToNumberConvertBigInt(Type, Typer*);
|
||||
static Type ToBigInt(Type, Typer*);
|
||||
static Type ToBigIntConvertNumber(Type, Typer*);
|
||||
static Type ToNumeric(Type, Typer*);
|
||||
static Type ToObject(Type, Typer*);
|
||||
static Type ToString(Type, Typer*);
|
||||
@ -674,6 +676,16 @@ Type Typer::Visitor::ToNumberConvertBigInt(Type type, Typer* t) {
|
||||
return t->operation_typer_.ToNumberConvertBigInt(type);
|
||||
}
|
||||
|
||||
// static
|
||||
Type Typer::Visitor::ToBigInt(Type type, Typer* t) {
|
||||
return t->operation_typer_.ToBigInt(type);
|
||||
}
|
||||
|
||||
// static
|
||||
Type Typer::Visitor::ToBigIntConvertNumber(Type type, Typer* t) {
|
||||
return t->operation_typer_.ToBigIntConvertNumber(type);
|
||||
}
|
||||
|
||||
// static
|
||||
Type Typer::Visitor::ToNumeric(Type type, Typer* t) {
|
||||
return t->operation_typer_.ToNumeric(type);
|
||||
@ -1361,6 +1373,8 @@ DEFINE_METHOD(ToLength)
|
||||
DEFINE_METHOD(ToName)
|
||||
DEFINE_METHOD(ToNumber)
|
||||
DEFINE_METHOD(ToNumberConvertBigInt)
|
||||
DEFINE_METHOD(ToBigInt)
|
||||
DEFINE_METHOD(ToBigIntConvertNumber)
|
||||
DEFINE_METHOD(ToNumeric)
|
||||
DEFINE_METHOD(ToObject)
|
||||
DEFINE_METHOD(ToString)
|
||||
|
@ -200,8 +200,9 @@ class UseInfo {
|
||||
return UseInfo(MachineRepresentation::kWord64, Truncation::Any(),
|
||||
TypeCheckKind::kBigInt64, feedback);
|
||||
}
|
||||
static UseInfo Word64() {
|
||||
return UseInfo(MachineRepresentation::kWord64, Truncation::Any());
|
||||
static UseInfo Word64(IdentifyZeros identify_zeros = kDistinguishZeros) {
|
||||
return UseInfo(MachineRepresentation::kWord64,
|
||||
Truncation::Any(identify_zeros));
|
||||
}
|
||||
static UseInfo Word() {
|
||||
return UseInfo(MachineType::PointerRepresentation(), Truncation::Any());
|
||||
|
@ -674,6 +674,10 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
|
||||
case IrOpcode::kJSToNumberConvertBigInt:
|
||||
CheckTypeIs(node, Type::Number());
|
||||
break;
|
||||
case IrOpcode::kJSToBigInt:
|
||||
case IrOpcode::kJSToBigIntConvertNumber:
|
||||
CheckTypeIs(node, Type::BigInt());
|
||||
break;
|
||||
case IrOpcode::kJSToNumeric:
|
||||
CheckTypeIs(node, Type::Numeric());
|
||||
break;
|
||||
@ -1121,6 +1125,10 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
|
||||
CheckValueInputIs(node, 0, Type::Number());
|
||||
CheckTypeIs(node, Type::Unsigned32());
|
||||
break;
|
||||
case IrOpcode::kIntegral32OrMinusZeroToBigInt:
|
||||
CheckValueInputIs(node, 0, Type::Integral32OrMinusZero());
|
||||
CheckTypeIs(node, Type::BigInt());
|
||||
break;
|
||||
case IrOpcode::kUnsigned32Divide:
|
||||
CheckValueInputIs(node, 0, Type::Unsigned32());
|
||||
CheckValueInputIs(node, 1, Type::Unsigned32());
|
||||
|
@ -94,6 +94,25 @@ RUNTIME_FUNCTION(Runtime_ToBigInt) {
|
||||
RETURN_RESULT_OR_FAILURE(isolate, BigInt::FromObject(isolate, x));
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_ToBigIntConvertNumber) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(1, args.length());
|
||||
Handle<Object> x = args.at(0);
|
||||
|
||||
if (x->IsJSReceiver()) {
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, x,
|
||||
JSReceiver::ToPrimitive(isolate, Handle<JSReceiver>::cast(x),
|
||||
ToPrimitiveHint::kNumber));
|
||||
}
|
||||
|
||||
if (x->IsNumber()) {
|
||||
RETURN_RESULT_OR_FAILURE(isolate, BigInt::FromNumber(isolate, x));
|
||||
} else {
|
||||
RETURN_RESULT_OR_FAILURE(isolate, BigInt::FromObject(isolate, x));
|
||||
}
|
||||
}
|
||||
|
||||
RUNTIME_FUNCTION(Runtime_BigIntBinaryOp) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK_EQ(3, args.length());
|
||||
|
@ -80,7 +80,8 @@ namespace internal {
|
||||
F(BigIntToBoolean, 1, 1) \
|
||||
F(BigIntToNumber, 1, 1) \
|
||||
F(BigIntUnaryOp, 2, 1) \
|
||||
F(ToBigInt, 1, 1)
|
||||
F(ToBigInt, 1, 1) \
|
||||
F(ToBigIntConvertNumber, 1, 1)
|
||||
|
||||
#define FOR_EACH_INTRINSIC_CLASSES(F, I) \
|
||||
F(DefineClass, -1 /* >= 3 */, 1) \
|
||||
|
107
test/mjsunit/compiler/bigint-constructor.js
Normal file
107
test/mjsunit/compiler/bigint-constructor.js
Normal file
@ -0,0 +1,107 @@
|
||||
// Copyright 2022 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Flags: --allow-natives-syntax --turbofan --no-always-turbofan
|
||||
|
||||
(function () {
|
||||
function ToBigInt(x) {
|
||||
return BigInt(x);
|
||||
}
|
||||
|
||||
%PrepareFunctionForOptimization(ToBigInt);
|
||||
assertEquals(0n, ToBigInt(0));
|
||||
%OptimizeFunctionOnNextCall(ToBigInt);
|
||||
|
||||
// Test the builtin ToBigIntConvertNumber.
|
||||
assertThrows(() => ToBigInt(undefined), TypeError);
|
||||
|
||||
assertEquals(0n, ToBigInt(false));
|
||||
assertEquals(1n, ToBigInt(true));
|
||||
|
||||
assertEquals(42n, ToBigInt(42n));
|
||||
|
||||
assertEquals(3n, ToBigInt(3));
|
||||
assertEquals(0xdeadbeefn, ToBigInt(0xdeadbeef));
|
||||
assertEquals(-0xdeadbeefn, ToBigInt(-0xdeadbeef));
|
||||
|
||||
assertEquals(2n, ToBigInt("2"));
|
||||
assertEquals(0xdeadbeefdeadbeefdn, ToBigInt("0xdeadbeefdeadbeefd"));
|
||||
assertThrows(() => ToBigInt("-0x10"), SyntaxError);
|
||||
|
||||
assertThrows(() => ToBigInt(Symbol("foo")), TypeError);
|
||||
assertOptimized(ToBigInt);
|
||||
})();
|
||||
|
||||
{
|
||||
// Test constants to BigInts.
|
||||
function OptimizeAndTest(expected, fun) {
|
||||
%PrepareFunctionForOptimization(fun);
|
||||
assertEquals(expected, fun());
|
||||
%OptimizeFunctionOnNextCall(fun);
|
||||
assertEquals(expected, fun());
|
||||
assertOptimized(fun);
|
||||
}
|
||||
|
||||
OptimizeAndTest(42n, () => BigInt(42n));
|
||||
|
||||
// MinusZero
|
||||
OptimizeAndTest(0n, () => BigInt(-0));
|
||||
OptimizeAndTest(0n, () => BigInt.asIntN(32, BigInt(-0)));
|
||||
OptimizeAndTest(0n, () => BigInt.asUintN(32, BigInt(-0)));
|
||||
OptimizeAndTest(0n, () => 0n + BigInt(-0));
|
||||
|
||||
// Smi
|
||||
OptimizeAndTest(42n, () => BigInt(42));
|
||||
OptimizeAndTest(42n, () => BigInt.asIntN(32, BigInt(42)));
|
||||
OptimizeAndTest(42n, () => BigInt.asUintN(32, BigInt(42)));
|
||||
OptimizeAndTest(42n, () => 0n + BigInt(42));
|
||||
|
||||
// Signed32
|
||||
OptimizeAndTest(-0x80000000n, () => BigInt(-0x80000000));
|
||||
OptimizeAndTest(-0x80000000n, () => BigInt.asIntN(32, BigInt(-0x80000000)));
|
||||
OptimizeAndTest(0x80000000n, () => BigInt.asUintN(32, BigInt(-0x80000000)));
|
||||
OptimizeAndTest(-0x80000000n, () => 0n + BigInt(-0x80000000));
|
||||
|
||||
// Unsigned32
|
||||
OptimizeAndTest(0x80000000n, () => BigInt(0x80000000));
|
||||
OptimizeAndTest(-0x80000000n, () => BigInt.asIntN(32, BigInt(0x80000000)));
|
||||
OptimizeAndTest(0x80000000n, () => BigInt.asUintN(32, BigInt(0x80000000)));
|
||||
OptimizeAndTest(0x80000000n, () => 0n + BigInt(0x80000000));
|
||||
}
|
||||
|
||||
(function () {
|
||||
function SmiToBigInt(arr) {
|
||||
return BigInt(arr[0]);
|
||||
}
|
||||
|
||||
// Element kind: PACKED_SMI_ELEMENTS
|
||||
const numbers = [0x3fffffff, 0, -0x40000000];
|
||||
%PrepareFunctionForOptimization(SmiToBigInt);
|
||||
assertEquals(0x3fffffffn, SmiToBigInt(numbers));
|
||||
%OptimizeFunctionOnNextCall(SmiToBigInt);
|
||||
assertEquals(0x3fffffffn, SmiToBigInt(numbers));
|
||||
assertOptimized(SmiToBigInt);
|
||||
|
||||
// Change the map of {numbers}.
|
||||
numbers[1] = 0x80000000;
|
||||
assertEquals(0x3fffffffn, SmiToBigInt(numbers));
|
||||
assertUnoptimized(SmiToBigInt);
|
||||
})();
|
||||
|
||||
(function () {
|
||||
function ToBigInt() {
|
||||
return BigInt(123);
|
||||
}
|
||||
|
||||
%PrepareFunctionForOptimization(ToBigInt);
|
||||
assertEquals(123n, ToBigInt());
|
||||
%OptimizeFunctionOnNextCall(ToBigInt);
|
||||
assertEquals(123n, ToBigInt());
|
||||
assertOptimized(ToBigInt);
|
||||
|
||||
// Replace the global BigInt object.
|
||||
BigInt = () => 42;
|
||||
assertUnoptimized(ToBigInt);
|
||||
assertEquals(42, ToBigInt());
|
||||
})();
|
Loading…
Reference in New Issue
Block a user