[CSA][cleanup] TNodify builtins numbers gen
TNodify related methods in CSA: * TaggedToWord32OrBigInt * TaggedToWord32OrBigIntWithFeedback * TaggedToWord32OrBigIntImpl Remove Sloppy-ness in RelationalComparison Bug: v8:6949 Change-Id: I970a40a424f6e8cdc45544eb79c95291a5a5a608 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1807362 Reviewed-by: Jakob Gruber <jgruber@chromium.org> Reviewed-by: Mythri Alle <mythria@chromium.org> Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org> Cr-Commit-Position: refs/heads/master@{#63861}
This commit is contained in:
parent
d7903dd3de
commit
26372107aa
@ -22,57 +22,58 @@ class NumberBuiltinsAssembler : public CodeStubAssembler {
|
||||
protected:
|
||||
template <typename Descriptor>
|
||||
void EmitBitwiseOp(Operation op) {
|
||||
Node* left = Parameter(Descriptor::kLeft);
|
||||
Node* right = Parameter(Descriptor::kRight);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TNode<Object> left = CAST(Parameter(Descriptor::kLeft));
|
||||
TNode<Object> right = CAST(Parameter(Descriptor::kRight));
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
|
||||
VARIABLE(var_left_word32, MachineRepresentation::kWord32);
|
||||
VARIABLE(var_right_word32, MachineRepresentation::kWord32);
|
||||
VARIABLE(var_left_bigint, MachineRepresentation::kTagged, left);
|
||||
VARIABLE(var_right_bigint, MachineRepresentation::kTagged);
|
||||
TVARIABLE(Word32T, var_left_word32);
|
||||
TVARIABLE(Word32T, var_right_word32);
|
||||
TVARIABLE(Object, var_left_maybe_bigint, left);
|
||||
TVARIABLE(Object, var_right_maybe_bigint);
|
||||
Label if_left_number(this), do_number_op(this);
|
||||
Label if_left_bigint(this), do_bigint_op(this);
|
||||
|
||||
TaggedToWord32OrBigInt(context, left, &if_left_number, &var_left_word32,
|
||||
&if_left_bigint, &var_left_bigint);
|
||||
&if_left_bigint, &var_left_maybe_bigint);
|
||||
BIND(&if_left_number);
|
||||
TaggedToWord32OrBigInt(context, right, &do_number_op, &var_right_word32,
|
||||
&do_bigint_op, &var_right_bigint);
|
||||
&do_bigint_op, &var_right_maybe_bigint);
|
||||
BIND(&do_number_op);
|
||||
Return(BitwiseOp(var_left_word32.value(), var_right_word32.value(), op));
|
||||
|
||||
// BigInt cases.
|
||||
BIND(&if_left_bigint);
|
||||
TaggedToNumeric(context, right, &do_bigint_op, &var_right_bigint);
|
||||
TaggedToNumeric(context, right, &do_bigint_op, &var_right_maybe_bigint);
|
||||
|
||||
BIND(&do_bigint_op);
|
||||
Return(CallRuntime(Runtime::kBigIntBinaryOp, context,
|
||||
var_left_bigint.value(), var_right_bigint.value(),
|
||||
SmiConstant(op)));
|
||||
var_left_maybe_bigint.value(),
|
||||
var_right_maybe_bigint.value(), SmiConstant(op)));
|
||||
}
|
||||
|
||||
template <typename Descriptor>
|
||||
void RelationalComparisonBuiltin(Operation op) {
|
||||
Node* lhs = Parameter(Descriptor::kLeft);
|
||||
Node* rhs = Parameter(Descriptor::kRight);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TNode<Object> lhs = CAST(Parameter(Descriptor::kLeft));
|
||||
TNode<Object> rhs = CAST(Parameter(Descriptor::kRight));
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
|
||||
Return(RelationalComparison(op, lhs, rhs, context));
|
||||
}
|
||||
|
||||
template <typename Descriptor>
|
||||
void UnaryOp(Variable* var_input, Label* do_smi, Label* do_double,
|
||||
Variable* var_input_double, Label* do_bigint);
|
||||
void UnaryOp(TVariable<Object>* var_input, Label* do_smi, Label* do_double,
|
||||
TVariable<Float64T>* var_input_double, Label* do_bigint);
|
||||
|
||||
template <typename Descriptor>
|
||||
void BinaryOp(Label* smis, Variable* var_left, Variable* var_right,
|
||||
Label* doubles, Variable* var_left_double,
|
||||
Variable* var_right_double, Label* bigints);
|
||||
void BinaryOp(Label* smis, TVariable<Object>* var_left,
|
||||
TVariable<Object>* var_right, Label* doubles,
|
||||
TVariable<Float64T>* var_left_double,
|
||||
TVariable<Float64T>* var_right_double, Label* bigints);
|
||||
};
|
||||
|
||||
// ES6 #sec-number.isfinite
|
||||
TF_BUILTIN(NumberIsFinite, CodeStubAssembler) {
|
||||
Node* number = Parameter(Descriptor::kNumber);
|
||||
TNode<Object> number = CAST(Parameter(Descriptor::kNumber));
|
||||
|
||||
Label return_true(this), return_false(this);
|
||||
|
||||
@ -80,10 +81,11 @@ TF_BUILTIN(NumberIsFinite, CodeStubAssembler) {
|
||||
GotoIf(TaggedIsSmi(number), &return_true);
|
||||
|
||||
// Check if {number} is a HeapNumber.
|
||||
GotoIfNot(IsHeapNumber(number), &return_false);
|
||||
TNode<HeapObject> number_heap_object = CAST(number);
|
||||
GotoIfNot(IsHeapNumber(number_heap_object), &return_false);
|
||||
|
||||
// Check if {number} contains a finite, non-NaN value.
|
||||
TNode<Float64T> number_value = LoadHeapNumberValue(number);
|
||||
TNode<Float64T> number_value = LoadHeapNumberValue(number_heap_object);
|
||||
BranchIfFloat64IsNaN(Float64Sub(number_value, number_value), &return_false,
|
||||
&return_true);
|
||||
|
||||
@ -107,7 +109,7 @@ TF_BUILTIN(NumberIsInteger, CodeStubAssembler) {
|
||||
|
||||
// ES6 #sec-number.isnan
|
||||
TF_BUILTIN(NumberIsNaN, CodeStubAssembler) {
|
||||
Node* number = Parameter(Descriptor::kNumber);
|
||||
TNode<Object> number = CAST(Parameter(Descriptor::kNumber));
|
||||
|
||||
Label return_true(this), return_false(this);
|
||||
|
||||
@ -115,10 +117,11 @@ TF_BUILTIN(NumberIsNaN, CodeStubAssembler) {
|
||||
GotoIf(TaggedIsSmi(number), &return_false);
|
||||
|
||||
// Check if {number} is a HeapNumber.
|
||||
GotoIfNot(IsHeapNumber(number), &return_false);
|
||||
TNode<HeapObject> number_heap_object = CAST(number);
|
||||
GotoIfNot(IsHeapNumber(number_heap_object), &return_false);
|
||||
|
||||
// Check if {number} contains a NaN value.
|
||||
TNode<Float64T> number_value = LoadHeapNumberValue(number);
|
||||
TNode<Float64T> number_value = LoadHeapNumberValue(number_heap_object);
|
||||
BranchIfFloat64IsNaN(number_value, &return_true, &return_false);
|
||||
|
||||
BIND(&return_true);
|
||||
@ -136,17 +139,16 @@ TF_BUILTIN(NumberIsSafeInteger, CodeStubAssembler) {
|
||||
|
||||
// ES6 #sec-number.parsefloat
|
||||
TF_BUILTIN(NumberParseFloat, CodeStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
|
||||
// We might need to loop once for ToString conversion.
|
||||
VARIABLE(var_input, MachineRepresentation::kTagged,
|
||||
Parameter(Descriptor::kString));
|
||||
TVARIABLE(Object, var_input, CAST(Parameter(Descriptor::kString)));
|
||||
Label loop(this, &var_input);
|
||||
Goto(&loop);
|
||||
BIND(&loop);
|
||||
{
|
||||
// Load the current {input} value.
|
||||
Node* input = var_input.value();
|
||||
TNode<Object> input = var_input.value();
|
||||
|
||||
// Check if the {input} is a HeapObject or a Smi.
|
||||
Label if_inputissmi(this), if_inputisnotsmi(this);
|
||||
@ -161,8 +163,9 @@ TF_BUILTIN(NumberParseFloat, CodeStubAssembler) {
|
||||
BIND(&if_inputisnotsmi);
|
||||
{
|
||||
// The {input} is a HeapObject, check if it's already a String.
|
||||
TNode<HeapObject> input_heap_object = CAST(input);
|
||||
Label if_inputisstring(this), if_inputisnotstring(this);
|
||||
TNode<Map> input_map = LoadMap(input);
|
||||
TNode<Map> input_map = LoadMap(input_heap_object);
|
||||
TNode<Uint16T> input_instance_type = LoadMapInstanceType(input_map);
|
||||
Branch(IsStringInstanceType(input_instance_type), &if_inputisstring,
|
||||
&if_inputisnotstring);
|
||||
@ -172,7 +175,7 @@ TF_BUILTIN(NumberParseFloat, CodeStubAssembler) {
|
||||
// The {input} is already a String, check if {input} contains
|
||||
// a cached array index.
|
||||
Label if_inputcached(this), if_inputnotcached(this);
|
||||
TNode<Uint32T> input_hash = LoadNameHashField(input);
|
||||
TNode<Uint32T> input_hash = LoadNameHashField(CAST(input));
|
||||
Branch(IsClearWord32(input_hash,
|
||||
Name::kDoesNotContainCachedArrayIndexMask),
|
||||
&if_inputcached, &if_inputnotcached);
|
||||
@ -204,7 +207,7 @@ TF_BUILTIN(NumberParseFloat, CodeStubAssembler) {
|
||||
{
|
||||
// The {input} is already a Number, take care of -0.
|
||||
Label if_inputiszero(this), if_inputisnotzero(this);
|
||||
TNode<Float64T> input_value = LoadHeapNumberValue(input);
|
||||
TNode<Float64T> input_value = LoadHeapNumberValue(input_heap_object);
|
||||
Branch(Float64Equal(input_value, Float64Constant(0.0)),
|
||||
&if_inputiszero, &if_inputisnotzero);
|
||||
|
||||
@ -219,7 +222,7 @@ TF_BUILTIN(NumberParseFloat, CodeStubAssembler) {
|
||||
{
|
||||
// Need to convert the {input} to String first.
|
||||
// TODO(bmeurer): This could be more efficient if necessary.
|
||||
var_input.Bind(CallBuiltin(Builtins::kToString, context, input));
|
||||
var_input = CallBuiltin(Builtins::kToString, context, input);
|
||||
Goto(&loop);
|
||||
}
|
||||
}
|
||||
@ -309,9 +312,9 @@ TF_BUILTIN(ParseInt, CodeStubAssembler) {
|
||||
|
||||
// ES6 #sec-number.parseint
|
||||
TF_BUILTIN(NumberParseInt, CodeStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
Node* input = Parameter(Descriptor::kString);
|
||||
Node* radix = Parameter(Descriptor::kRadix);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TNode<Object> input = CAST(Parameter(Descriptor::kString));
|
||||
TNode<Object> radix = CAST(Parameter(Descriptor::kRadix));
|
||||
Return(CallBuiltin(Builtins::kParseInt, context, input, radix));
|
||||
}
|
||||
|
||||
@ -331,27 +334,29 @@ class AddStubAssembler : public CodeStubAssembler {
|
||||
: CodeStubAssembler(state) {}
|
||||
|
||||
protected:
|
||||
void ConvertReceiverAndLoop(Variable* var_value, Label* loop, Node* context) {
|
||||
TNode<Object> ConvertReceiver(TNode<JSReceiver> js_receiver,
|
||||
TNode<Context> context) {
|
||||
// Call ToPrimitive explicitly without hint (whereas ToNumber
|
||||
// would pass a "number" hint).
|
||||
Callable callable = CodeFactory::NonPrimitiveToPrimitive(isolate());
|
||||
var_value->Bind(CallStub(callable, context, var_value->value()));
|
||||
return CallStub(callable, context, js_receiver);
|
||||
}
|
||||
|
||||
void ConvertNonReceiverAndLoop(TVariable<Object>* var_value, Label* loop,
|
||||
TNode<Context> context) {
|
||||
*var_value =
|
||||
CallBuiltin(Builtins::kNonNumberToNumeric, context, var_value->value());
|
||||
Goto(loop);
|
||||
}
|
||||
|
||||
void ConvertNonReceiverAndLoop(Variable* var_value, Label* loop,
|
||||
Node* context) {
|
||||
var_value->Bind(CallBuiltin(Builtins::kNonNumberToNumeric, context,
|
||||
var_value->value()));
|
||||
Goto(loop);
|
||||
}
|
||||
|
||||
void ConvertAndLoop(Variable* var_value, Node* instance_type, Label* loop,
|
||||
Node* context) {
|
||||
void ConvertAndLoop(TVariable<Object>* var_value,
|
||||
TNode<Uint16T> instance_type, Label* loop,
|
||||
TNode<Context> context) {
|
||||
Label is_not_receiver(this, Label::kDeferred);
|
||||
GotoIfNot(IsJSReceiverInstanceType(instance_type), &is_not_receiver);
|
||||
|
||||
ConvertReceiverAndLoop(var_value, loop, context);
|
||||
*var_value = ConvertReceiver(CAST(var_value->value()), context);
|
||||
Goto(loop);
|
||||
|
||||
BIND(&is_not_receiver);
|
||||
ConvertNonReceiverAndLoop(var_value, loop, context);
|
||||
@ -359,30 +364,26 @@ class AddStubAssembler : public CodeStubAssembler {
|
||||
};
|
||||
|
||||
TF_BUILTIN(Add, AddStubAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
VARIABLE(var_left, MachineRepresentation::kTagged,
|
||||
Parameter(Descriptor::kLeft));
|
||||
VARIABLE(var_right, MachineRepresentation::kTagged,
|
||||
Parameter(Descriptor::kRight));
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TVARIABLE(Object, var_left, CAST(Parameter(Descriptor::kLeft)));
|
||||
TVARIABLE(Object, var_right, CAST(Parameter(Descriptor::kRight)));
|
||||
|
||||
// Shared entry for floating point addition.
|
||||
Label do_double_add(this);
|
||||
VARIABLE(var_left_double, MachineRepresentation::kFloat64);
|
||||
VARIABLE(var_right_double, MachineRepresentation::kFloat64);
|
||||
TVARIABLE(Float64T, var_left_double);
|
||||
TVARIABLE(Float64T, var_right_double);
|
||||
|
||||
// We might need to loop several times due to ToPrimitive, ToString and/or
|
||||
// ToNumeric conversions.
|
||||
VARIABLE(var_result, MachineRepresentation::kTagged);
|
||||
Variable* loop_vars[2] = {&var_left, &var_right};
|
||||
Label loop(this, 2, loop_vars),
|
||||
Label loop(this, {&var_left, &var_right}),
|
||||
string_add_convert_left(this, Label::kDeferred),
|
||||
string_add_convert_right(this, Label::kDeferred),
|
||||
do_bigint_add(this, Label::kDeferred);
|
||||
Goto(&loop);
|
||||
BIND(&loop);
|
||||
{
|
||||
Node* left = var_left.value();
|
||||
Node* right = var_right.value();
|
||||
TNode<Object> left = var_left.value();
|
||||
TNode<Object> right = var_right.value();
|
||||
|
||||
Label if_left_smi(this), if_left_heapobject(this);
|
||||
Branch(TaggedIsSmi(left), &if_left_smi, &if_left_heapobject);
|
||||
@ -395,27 +396,30 @@ TF_BUILTIN(Add, AddStubAssembler) {
|
||||
BIND(&if_right_smi);
|
||||
{
|
||||
Label if_overflow(this);
|
||||
TNode<Smi> result = TrySmiAdd(CAST(left), CAST(right), &if_overflow);
|
||||
TNode<Smi> left_smi = CAST(left);
|
||||
TNode<Smi> right_smi = CAST(right);
|
||||
TNode<Smi> result = TrySmiAdd(left_smi, right_smi, &if_overflow);
|
||||
Return(result);
|
||||
|
||||
BIND(&if_overflow);
|
||||
{
|
||||
var_left_double.Bind(SmiToFloat64(left));
|
||||
var_right_double.Bind(SmiToFloat64(right));
|
||||
var_left_double = SmiToFloat64(left_smi);
|
||||
var_right_double = SmiToFloat64(right_smi);
|
||||
Goto(&do_double_add);
|
||||
}
|
||||
} // if_right_smi
|
||||
|
||||
BIND(&if_right_heapobject);
|
||||
{
|
||||
TNode<Map> right_map = LoadMap(right);
|
||||
TNode<HeapObject> right_heap_object = CAST(right);
|
||||
TNode<Map> right_map = LoadMap(right_heap_object);
|
||||
|
||||
Label if_right_not_number(this, Label::kDeferred);
|
||||
GotoIfNot(IsHeapNumberMap(right_map), &if_right_not_number);
|
||||
|
||||
// {right} is a HeapNumber.
|
||||
var_left_double.Bind(SmiToFloat64(left));
|
||||
var_right_double.Bind(LoadHeapNumberValue(right));
|
||||
var_left_double = SmiToFloat64(CAST(left));
|
||||
var_right_double = LoadHeapNumberValue(right_heap_object);
|
||||
Goto(&do_double_add);
|
||||
|
||||
BIND(&if_right_not_number);
|
||||
@ -431,7 +435,8 @@ TF_BUILTIN(Add, AddStubAssembler) {
|
||||
|
||||
BIND(&if_left_heapobject);
|
||||
{
|
||||
TNode<Map> left_map = LoadMap(left);
|
||||
TNode<HeapObject> left_heap_object = CAST(left);
|
||||
TNode<Map> left_map = LoadMap(left_heap_object);
|
||||
Label if_right_smi(this), if_right_heapobject(this);
|
||||
Branch(TaggedIsSmi(right), &if_right_smi, &if_right_heapobject);
|
||||
|
||||
@ -441,8 +446,8 @@ TF_BUILTIN(Add, AddStubAssembler) {
|
||||
GotoIfNot(IsHeapNumberMap(left_map), &if_left_not_number);
|
||||
|
||||
// {left} is a HeapNumber, {right} is a Smi.
|
||||
var_left_double.Bind(LoadHeapNumberValue(left));
|
||||
var_right_double.Bind(SmiToFloat64(right));
|
||||
var_left_double = LoadHeapNumberValue(left_heap_object);
|
||||
var_right_double = SmiToFloat64(CAST(right));
|
||||
Goto(&do_double_add);
|
||||
|
||||
BIND(&if_left_not_number);
|
||||
@ -458,7 +463,8 @@ TF_BUILTIN(Add, AddStubAssembler) {
|
||||
|
||||
BIND(&if_right_heapobject);
|
||||
{
|
||||
TNode<Map> right_map = LoadMap(right);
|
||||
TNode<HeapObject> right_heap_object = CAST(right);
|
||||
TNode<Map> right_map = LoadMap(right_heap_object);
|
||||
|
||||
Label if_left_number(this), if_left_not_number(this, Label::kDeferred);
|
||||
Branch(IsHeapNumberMap(left_map), &if_left_number, &if_left_not_number);
|
||||
@ -469,8 +475,8 @@ TF_BUILTIN(Add, AddStubAssembler) {
|
||||
GotoIfNot(IsHeapNumberMap(right_map), &if_right_not_number);
|
||||
|
||||
// Both {left} and {right} are HeapNumbers.
|
||||
var_left_double.Bind(LoadHeapNumberValue(left));
|
||||
var_right_double.Bind(LoadHeapNumberValue(right));
|
||||
var_left_double = LoadHeapNumberValue(CAST(left));
|
||||
var_right_double = LoadHeapNumberValue(right_heap_object);
|
||||
Goto(&do_double_add);
|
||||
|
||||
BIND(&if_right_not_number);
|
||||
@ -499,7 +505,8 @@ TF_BUILTIN(Add, AddStubAssembler) {
|
||||
GotoIfNot(IsJSReceiverInstanceType(left_instance_type),
|
||||
&if_left_not_receiver);
|
||||
// {left} is a JSReceiver, convert it first.
|
||||
ConvertReceiverAndLoop(&var_left, &loop, context);
|
||||
var_left = ConvertReceiver(CAST(var_left.value()), context);
|
||||
Goto(&loop);
|
||||
|
||||
BIND(&if_left_bigint);
|
||||
{
|
||||
@ -515,7 +522,8 @@ TF_BUILTIN(Add, AddStubAssembler) {
|
||||
&if_right_not_receiver);
|
||||
// {left} is a Primitive, but {right} is a JSReceiver, so convert
|
||||
// {right} with priority.
|
||||
ConvertReceiverAndLoop(&var_right, &loop, context);
|
||||
var_right = ConvertReceiver(CAST(var_right.value()), context);
|
||||
Goto(&loop);
|
||||
|
||||
BIND(&if_right_not_receiver);
|
||||
// Neither {left} nor {right} are JSReceivers.
|
||||
@ -553,54 +561,46 @@ TF_BUILTIN(Add, AddStubAssembler) {
|
||||
}
|
||||
|
||||
template <typename Descriptor>
|
||||
void NumberBuiltinsAssembler::UnaryOp(Variable* var_input, Label* do_smi,
|
||||
Label* do_double,
|
||||
Variable* var_input_double,
|
||||
void NumberBuiltinsAssembler::UnaryOp(TVariable<Object>* var_input,
|
||||
Label* do_smi, Label* do_double,
|
||||
TVariable<Float64T>* var_input_double,
|
||||
Label* do_bigint) {
|
||||
DCHECK_EQ(var_input->rep(), MachineRepresentation::kTagged);
|
||||
DCHECK_IMPLIES(var_input_double != nullptr,
|
||||
var_input_double->rep() == MachineRepresentation::kFloat64);
|
||||
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
var_input->Bind(Parameter(Descriptor::kValue));
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
*var_input = CAST(Parameter(Descriptor::kValue));
|
||||
|
||||
// We might need to loop for ToNumeric conversion.
|
||||
Label loop(this, {var_input});
|
||||
Goto(&loop);
|
||||
BIND(&loop);
|
||||
Node* input = var_input->value();
|
||||
TNode<Object> input = var_input->value();
|
||||
|
||||
Label not_number(this);
|
||||
GotoIf(TaggedIsSmi(input), do_smi);
|
||||
GotoIfNot(IsHeapNumber(input), ¬_number);
|
||||
TNode<HeapObject> input_heap_object = CAST(input);
|
||||
GotoIfNot(IsHeapNumber(input_heap_object), ¬_number);
|
||||
if (var_input_double != nullptr) {
|
||||
var_input_double->Bind(LoadHeapNumberValue(input));
|
||||
*var_input_double = LoadHeapNumberValue(input_heap_object);
|
||||
}
|
||||
Goto(do_double);
|
||||
|
||||
BIND(¬_number);
|
||||
GotoIf(IsBigInt(input), do_bigint);
|
||||
var_input->Bind(CallBuiltin(Builtins::kNonNumberToNumeric, context, input));
|
||||
GotoIf(IsBigInt(input_heap_object), do_bigint);
|
||||
*var_input = CallBuiltin(Builtins::kNonNumberToNumeric, context, input);
|
||||
Goto(&loop);
|
||||
}
|
||||
|
||||
template <typename Descriptor>
|
||||
void NumberBuiltinsAssembler::BinaryOp(Label* smis, Variable* var_left,
|
||||
Variable* var_right, Label* doubles,
|
||||
Variable* var_left_double,
|
||||
Variable* var_right_double,
|
||||
void NumberBuiltinsAssembler::BinaryOp(Label* smis, TVariable<Object>* var_left,
|
||||
TVariable<Object>* var_right,
|
||||
Label* doubles,
|
||||
TVariable<Float64T>* var_left_double,
|
||||
TVariable<Float64T>* var_right_double,
|
||||
Label* bigints) {
|
||||
DCHECK_EQ(var_left->rep(), MachineRepresentation::kTagged);
|
||||
DCHECK_EQ(var_right->rep(), MachineRepresentation::kTagged);
|
||||
DCHECK_IMPLIES(var_left_double != nullptr,
|
||||
var_left_double->rep() == MachineRepresentation::kFloat64);
|
||||
DCHECK_IMPLIES(var_right_double != nullptr,
|
||||
var_right_double->rep() == MachineRepresentation::kFloat64);
|
||||
DCHECK_EQ(var_left_double == nullptr, var_right_double == nullptr);
|
||||
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
var_left->Bind(Parameter(Descriptor::kLeft));
|
||||
var_right->Bind(Parameter(Descriptor::kRight));
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
*var_left = CAST(Parameter(Descriptor::kLeft));
|
||||
*var_right = CAST(Parameter(Descriptor::kRight));
|
||||
|
||||
// We might need to loop for ToNumeric conversions.
|
||||
Label loop(this, {var_left, var_right});
|
||||
@ -613,32 +613,36 @@ void NumberBuiltinsAssembler::BinaryOp(Label* smis, Variable* var_left,
|
||||
GotoIf(TaggedIsSmi(var_right->value()), smis);
|
||||
|
||||
// At this point, var_left is a Smi but var_right is not.
|
||||
GotoIfNot(IsHeapNumber(var_right->value()), &right_not_number);
|
||||
TNode<Smi> var_left_smi = CAST(var_left->value());
|
||||
TNode<HeapObject> var_right_heap_object = CAST(var_right->value());
|
||||
GotoIfNot(IsHeapNumber(var_right_heap_object), &right_not_number);
|
||||
if (var_left_double != nullptr) {
|
||||
var_left_double->Bind(SmiToFloat64(var_left->value()));
|
||||
var_right_double->Bind(LoadHeapNumberValue(var_right->value()));
|
||||
*var_left_double = SmiToFloat64(var_left_smi);
|
||||
*var_right_double = LoadHeapNumberValue(var_right_heap_object);
|
||||
}
|
||||
Goto(doubles);
|
||||
|
||||
BIND(&left_not_smi);
|
||||
{
|
||||
GotoIfNot(IsHeapNumber(var_left->value()), &left_not_number);
|
||||
TNode<HeapObject> var_left_heap_object = CAST(var_left->value());
|
||||
GotoIfNot(IsHeapNumber(var_left_heap_object), &left_not_number);
|
||||
GotoIfNot(TaggedIsSmi(var_right->value()), &right_not_smi);
|
||||
|
||||
// At this point, var_left is a HeapNumber and var_right is a Smi.
|
||||
if (var_left_double != nullptr) {
|
||||
var_left_double->Bind(LoadHeapNumberValue(var_left->value()));
|
||||
var_right_double->Bind(SmiToFloat64(var_right->value()));
|
||||
*var_left_double = LoadHeapNumberValue(var_left_heap_object);
|
||||
*var_right_double = SmiToFloat64(CAST(var_right->value()));
|
||||
}
|
||||
Goto(doubles);
|
||||
}
|
||||
|
||||
BIND(&right_not_smi);
|
||||
{
|
||||
GotoIfNot(IsHeapNumber(var_right->value()), &right_not_number);
|
||||
TNode<HeapObject> var_right_heap_object = CAST(var_right->value());
|
||||
GotoIfNot(IsHeapNumber(var_right_heap_object), &right_not_number);
|
||||
if (var_left_double != nullptr) {
|
||||
var_left_double->Bind(LoadHeapNumberValue(var_left->value()));
|
||||
var_right_double->Bind(LoadHeapNumberValue(var_right->value()));
|
||||
*var_left_double = LoadHeapNumberValue(CAST(var_left->value()));
|
||||
*var_right_double = LoadHeapNumberValue(var_right_heap_object);
|
||||
}
|
||||
Goto(doubles);
|
||||
}
|
||||
@ -646,37 +650,38 @@ void NumberBuiltinsAssembler::BinaryOp(Label* smis, Variable* var_left,
|
||||
BIND(&left_not_number);
|
||||
{
|
||||
Label left_bigint(this);
|
||||
GotoIf(IsBigInt(var_left->value()), &left_bigint);
|
||||
var_left->Bind(
|
||||
CallBuiltin(Builtins::kNonNumberToNumeric, context, var_left->value()));
|
||||
GotoIf(IsBigInt(CAST(var_left->value())), &left_bigint);
|
||||
*var_left =
|
||||
CallBuiltin(Builtins::kNonNumberToNumeric, context, var_left->value());
|
||||
Goto(&loop);
|
||||
|
||||
BIND(&left_bigint);
|
||||
{
|
||||
// Jump to {bigints} if {var_right} is already a Numeric.
|
||||
GotoIf(TaggedIsSmi(var_right->value()), bigints);
|
||||
GotoIf(IsBigInt(var_right->value()), bigints);
|
||||
GotoIf(IsHeapNumber(var_right->value()), bigints);
|
||||
var_right->Bind(CallBuiltin(Builtins::kNonNumberToNumeric, context,
|
||||
var_right->value()));
|
||||
TNode<HeapObject> var_right_heap_object = CAST(var_right->value());
|
||||
GotoIf(IsBigInt(var_right_heap_object), bigints);
|
||||
GotoIf(IsHeapNumber(var_right_heap_object), bigints);
|
||||
*var_right = CallBuiltin(Builtins::kNonNumberToNumeric, context,
|
||||
var_right->value());
|
||||
Goto(&loop);
|
||||
}
|
||||
}
|
||||
|
||||
BIND(&right_not_number);
|
||||
{
|
||||
GotoIf(IsBigInt(var_right->value()), bigints);
|
||||
var_right->Bind(CallBuiltin(Builtins::kNonNumberToNumeric, context,
|
||||
var_right->value()));
|
||||
GotoIf(IsBigInt(CAST(var_right->value())), bigints);
|
||||
*var_right =
|
||||
CallBuiltin(Builtins::kNonNumberToNumeric, context, var_right->value());
|
||||
Goto(&loop);
|
||||
}
|
||||
}
|
||||
|
||||
TF_BUILTIN(Subtract, NumberBuiltinsAssembler) {
|
||||
VARIABLE(var_left, MachineRepresentation::kTagged);
|
||||
VARIABLE(var_right, MachineRepresentation::kTagged);
|
||||
VARIABLE(var_left_double, MachineRepresentation::kFloat64);
|
||||
VARIABLE(var_right_double, MachineRepresentation::kFloat64);
|
||||
TVARIABLE(Object, var_left);
|
||||
TVARIABLE(Object, var_right);
|
||||
TVARIABLE(Float64T, var_left_double);
|
||||
TVARIABLE(Float64T, var_right_double);
|
||||
Label do_smi_sub(this), do_double_sub(this), do_bigint_sub(this);
|
||||
|
||||
BinaryOp<Descriptor>(&do_smi_sub, &var_left, &var_right, &do_double_sub,
|
||||
@ -685,14 +690,15 @@ TF_BUILTIN(Subtract, NumberBuiltinsAssembler) {
|
||||
BIND(&do_smi_sub);
|
||||
{
|
||||
Label if_overflow(this);
|
||||
TNode<Smi> result = TrySmiSub(CAST(var_left.value()),
|
||||
CAST(var_right.value()), &if_overflow);
|
||||
TNode<Smi> var_left_smi = CAST(var_left.value());
|
||||
TNode<Smi> var_right_smi = CAST(var_right.value());
|
||||
TNode<Smi> result = TrySmiSub(var_left_smi, var_right_smi, &if_overflow);
|
||||
Return(result);
|
||||
|
||||
BIND(&if_overflow);
|
||||
{
|
||||
var_left_double.Bind(SmiToFloat64(var_left.value()));
|
||||
var_right_double.Bind(SmiToFloat64(var_right.value()));
|
||||
var_left_double = SmiToFloat64(var_left_smi);
|
||||
var_right_double = SmiToFloat64(var_right_smi);
|
||||
Goto(&do_double_sub);
|
||||
}
|
||||
}
|
||||
@ -706,15 +712,15 @@ TF_BUILTIN(Subtract, NumberBuiltinsAssembler) {
|
||||
|
||||
BIND(&do_bigint_sub);
|
||||
{
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
Return(CallRuntime(Runtime::kBigIntBinaryOp, context, var_left.value(),
|
||||
var_right.value(), SmiConstant(Operation::kSubtract)));
|
||||
}
|
||||
}
|
||||
|
||||
TF_BUILTIN(BitwiseNot, NumberBuiltinsAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
VARIABLE(var_input, MachineRepresentation::kTagged);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TVARIABLE(Object, var_input);
|
||||
Label do_number(this), do_bigint(this);
|
||||
|
||||
UnaryOp<Descriptor>(&var_input, &do_number, &do_number, nullptr, &do_bigint);
|
||||
@ -733,8 +739,8 @@ TF_BUILTIN(BitwiseNot, NumberBuiltinsAssembler) {
|
||||
}
|
||||
|
||||
TF_BUILTIN(Decrement, NumberBuiltinsAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
VARIABLE(var_input, MachineRepresentation::kTagged);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TVARIABLE(Object, var_input);
|
||||
Label do_number(this), do_bigint(this);
|
||||
|
||||
UnaryOp<Descriptor>(&var_input, &do_number, &do_number, nullptr, &do_bigint);
|
||||
@ -753,8 +759,8 @@ TF_BUILTIN(Decrement, NumberBuiltinsAssembler) {
|
||||
}
|
||||
|
||||
TF_BUILTIN(Increment, NumberBuiltinsAssembler) {
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
VARIABLE(var_input, MachineRepresentation::kTagged);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
TVARIABLE(Object, var_input);
|
||||
Label do_number(this), do_bigint(this);
|
||||
|
||||
UnaryOp<Descriptor>(&var_input, &do_number, &do_number, nullptr, &do_bigint);
|
||||
@ -772,8 +778,8 @@ TF_BUILTIN(Increment, NumberBuiltinsAssembler) {
|
||||
}
|
||||
|
||||
TF_BUILTIN(Negate, NumberBuiltinsAssembler) {
|
||||
VARIABLE(var_input, MachineRepresentation::kTagged);
|
||||
VARIABLE(var_input_double, MachineRepresentation::kFloat64);
|
||||
TVARIABLE(Object, var_input);
|
||||
TVARIABLE(Float64T, var_input_double);
|
||||
Label do_smi(this), do_double(this), do_bigint(this);
|
||||
|
||||
UnaryOp<Descriptor>(&var_input, &do_smi, &do_double, &var_input_double,
|
||||
@ -791,17 +797,17 @@ TF_BUILTIN(Negate, NumberBuiltinsAssembler) {
|
||||
|
||||
BIND(&do_bigint);
|
||||
{
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
Return(CallRuntime(Runtime::kBigIntUnaryOp, context, var_input.value(),
|
||||
SmiConstant(Operation::kNegate)));
|
||||
}
|
||||
}
|
||||
|
||||
TF_BUILTIN(Multiply, NumberBuiltinsAssembler) {
|
||||
VARIABLE(var_left, MachineRepresentation::kTagged);
|
||||
VARIABLE(var_right, MachineRepresentation::kTagged);
|
||||
VARIABLE(var_left_double, MachineRepresentation::kFloat64);
|
||||
VARIABLE(var_right_double, MachineRepresentation::kFloat64);
|
||||
TVARIABLE(Object, var_left);
|
||||
TVARIABLE(Object, var_right);
|
||||
TVARIABLE(Float64T, var_left_double);
|
||||
TVARIABLE(Float64T, var_right_double);
|
||||
Label do_smi_mul(this), do_double_mul(this), do_bigint_mul(this);
|
||||
|
||||
BinaryOp<Descriptor>(&do_smi_mul, &var_left, &var_right, &do_double_mul,
|
||||
@ -818,17 +824,17 @@ TF_BUILTIN(Multiply, NumberBuiltinsAssembler) {
|
||||
|
||||
BIND(&do_bigint_mul);
|
||||
{
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
Return(CallRuntime(Runtime::kBigIntBinaryOp, context, var_left.value(),
|
||||
var_right.value(), SmiConstant(Operation::kMultiply)));
|
||||
}
|
||||
}
|
||||
|
||||
TF_BUILTIN(Divide, NumberBuiltinsAssembler) {
|
||||
VARIABLE(var_left, MachineRepresentation::kTagged);
|
||||
VARIABLE(var_right, MachineRepresentation::kTagged);
|
||||
VARIABLE(var_left_double, MachineRepresentation::kFloat64);
|
||||
VARIABLE(var_right_double, MachineRepresentation::kFloat64);
|
||||
TVARIABLE(Object, var_left);
|
||||
TVARIABLE(Object, var_right);
|
||||
TVARIABLE(Float64T, var_left_double);
|
||||
TVARIABLE(Float64T, var_right_double);
|
||||
Label do_smi_div(this), do_double_div(this), do_bigint_div(this);
|
||||
|
||||
BinaryOp<Descriptor>(&do_smi_div, &var_left, &var_right, &do_double_div,
|
||||
@ -889,8 +895,8 @@ TF_BUILTIN(Divide, NumberBuiltinsAssembler) {
|
||||
// division.
|
||||
BIND(&bailout);
|
||||
{
|
||||
var_left_double.Bind(SmiToFloat64(dividend));
|
||||
var_right_double.Bind(SmiToFloat64(divisor));
|
||||
var_left_double = SmiToFloat64(dividend);
|
||||
var_right_double = SmiToFloat64(divisor);
|
||||
Goto(&do_double_div);
|
||||
}
|
||||
}
|
||||
@ -904,17 +910,17 @@ TF_BUILTIN(Divide, NumberBuiltinsAssembler) {
|
||||
|
||||
BIND(&do_bigint_div);
|
||||
{
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
Return(CallRuntime(Runtime::kBigIntBinaryOp, context, var_left.value(),
|
||||
var_right.value(), SmiConstant(Operation::kDivide)));
|
||||
}
|
||||
}
|
||||
|
||||
TF_BUILTIN(Modulus, NumberBuiltinsAssembler) {
|
||||
VARIABLE(var_left, MachineRepresentation::kTagged);
|
||||
VARIABLE(var_right, MachineRepresentation::kTagged);
|
||||
VARIABLE(var_left_double, MachineRepresentation::kFloat64);
|
||||
VARIABLE(var_right_double, MachineRepresentation::kFloat64);
|
||||
TVARIABLE(Object, var_left);
|
||||
TVARIABLE(Object, var_right);
|
||||
TVARIABLE(Float64T, var_left_double);
|
||||
TVARIABLE(Float64T, var_right_double);
|
||||
Label do_smi_mod(this), do_double_mod(this), do_bigint_mod(this);
|
||||
|
||||
BinaryOp<Descriptor>(&do_smi_mod, &var_left, &var_right, &do_double_mod,
|
||||
@ -930,17 +936,17 @@ TF_BUILTIN(Modulus, NumberBuiltinsAssembler) {
|
||||
|
||||
BIND(&do_bigint_mod);
|
||||
{
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
Return(CallRuntime(Runtime::kBigIntBinaryOp, context, var_left.value(),
|
||||
var_right.value(), SmiConstant(Operation::kModulus)));
|
||||
}
|
||||
}
|
||||
|
||||
TF_BUILTIN(Exponentiate, NumberBuiltinsAssembler) {
|
||||
VARIABLE(var_left, MachineRepresentation::kTagged);
|
||||
VARIABLE(var_right, MachineRepresentation::kTagged);
|
||||
TVARIABLE(Object, var_left);
|
||||
TVARIABLE(Object, var_right);
|
||||
Label do_number_exp(this), do_bigint_exp(this);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
|
||||
BinaryOp<Descriptor>(&do_number_exp, &var_left, &var_right, &do_number_exp,
|
||||
nullptr, nullptr, &do_bigint_exp);
|
||||
@ -997,9 +1003,9 @@ TF_BUILTIN(GreaterThanOrEqual, NumberBuiltinsAssembler) {
|
||||
}
|
||||
|
||||
TF_BUILTIN(Equal, CodeStubAssembler) {
|
||||
Node* lhs = Parameter(Descriptor::kLeft);
|
||||
Node* rhs = Parameter(Descriptor::kRight);
|
||||
Node* context = Parameter(Descriptor::kContext);
|
||||
TNode<Object> lhs = CAST(Parameter(Descriptor::kLeft));
|
||||
TNode<Object> rhs = CAST(Parameter(Descriptor::kRight));
|
||||
TNode<Context> context = CAST(Parameter(Descriptor::kContext));
|
||||
|
||||
Return(Equal(lhs, rhs, context));
|
||||
}
|
||||
|
@ -5629,48 +5629,43 @@ TNode<Float64T> CodeStubAssembler::TruncateTaggedToFloat64(
|
||||
|
||||
TNode<Word32T> CodeStubAssembler::TruncateTaggedToWord32(
|
||||
SloppyTNode<Context> context, SloppyTNode<Object> value) {
|
||||
VARIABLE(var_result, MachineRepresentation::kWord32);
|
||||
TVARIABLE(Word32T, var_result);
|
||||
Label done(this);
|
||||
TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumber>(context, value,
|
||||
&done, &var_result);
|
||||
BIND(&done);
|
||||
return UncheckedCast<Word32T>(var_result.value());
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
// Truncate {value} to word32 and jump to {if_number} if it is a Number,
|
||||
// or find that it is a BigInt and jump to {if_bigint}.
|
||||
void CodeStubAssembler::TaggedToWord32OrBigInt(Node* context, Node* value,
|
||||
Label* if_number,
|
||||
Variable* var_word32,
|
||||
Label* if_bigint,
|
||||
Variable* var_bigint) {
|
||||
void CodeStubAssembler::TaggedToWord32OrBigInt(
|
||||
TNode<Context> context, TNode<Object> value, Label* if_number,
|
||||
TVariable<Word32T>* var_word32, Label* if_bigint,
|
||||
TVariable<Object>* var_maybe_bigint) {
|
||||
TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>(
|
||||
context, value, if_number, var_word32, if_bigint, var_bigint);
|
||||
context, value, if_number, var_word32, if_bigint, var_maybe_bigint);
|
||||
}
|
||||
|
||||
// Truncate {value} to word32 and jump to {if_number} if it is a Number,
|
||||
// or find that it is a BigInt and jump to {if_bigint}. In either case,
|
||||
// store the type feedback in {var_feedback}.
|
||||
void CodeStubAssembler::TaggedToWord32OrBigIntWithFeedback(
|
||||
Node* context, Node* value, Label* if_number, Variable* var_word32,
|
||||
Label* if_bigint, Variable* var_bigint, Variable* var_feedback) {
|
||||
TNode<Context> context, TNode<Object> value, Label* if_number,
|
||||
TVariable<Word32T>* var_word32, Label* if_bigint,
|
||||
TVariable<Object>* var_maybe_bigint, TVariable<Smi>* var_feedback) {
|
||||
TaggedToWord32OrBigIntImpl<Object::Conversion::kToNumeric>(
|
||||
context, value, if_number, var_word32, if_bigint, var_bigint,
|
||||
context, value, if_number, var_word32, if_bigint, var_maybe_bigint,
|
||||
var_feedback);
|
||||
}
|
||||
|
||||
template <Object::Conversion conversion>
|
||||
void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
|
||||
Node* context, Node* value, Label* if_number, Variable* var_word32,
|
||||
Label* if_bigint, Variable* var_bigint, Variable* var_feedback) {
|
||||
DCHECK(var_word32->rep() == MachineRepresentation::kWord32);
|
||||
DCHECK(var_bigint == nullptr ||
|
||||
var_bigint->rep() == MachineRepresentation::kTagged);
|
||||
DCHECK(var_feedback == nullptr ||
|
||||
var_feedback->rep() == MachineRepresentation::kTaggedSigned);
|
||||
|
||||
TNode<Context> context, TNode<Object> value, Label* if_number,
|
||||
TVariable<Word32T>* var_word32, Label* if_bigint,
|
||||
TVariable<Object>* var_maybe_bigint, TVariable<Smi>* var_feedback) {
|
||||
// We might need to loop after conversion.
|
||||
VARIABLE(var_value, MachineRepresentation::kTagged, value);
|
||||
TVARIABLE(Object, var_value, value);
|
||||
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kNone);
|
||||
Variable* loop_vars[] = {&var_value, var_feedback};
|
||||
int num_vars =
|
||||
@ -5685,12 +5680,13 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
|
||||
GotoIf(TaggedIsNotSmi(value), ¬_smi);
|
||||
|
||||
// {value} is a Smi.
|
||||
var_word32->Bind(SmiToInt32(value));
|
||||
*var_word32 = SmiToInt32(CAST(value));
|
||||
CombineFeedback(var_feedback, BinaryOperationFeedback::kSignedSmall);
|
||||
Goto(if_number);
|
||||
|
||||
BIND(¬_smi);
|
||||
TNode<Map> map = LoadMap(value);
|
||||
TNode<HeapObject> value_heap_object = CAST(value);
|
||||
TNode<Map> map = LoadMap(value_heap_object);
|
||||
GotoIf(IsHeapNumberMap(map), &is_heap_number);
|
||||
TNode<Uint16T> instance_type = LoadMapInstanceType(map);
|
||||
if (conversion == Object::Conversion::kToNumeric) {
|
||||
@ -5703,7 +5699,7 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
|
||||
// We do not require an Or with earlier feedback here because once we
|
||||
// convert the value to a Numeric, we cannot reach this path. We can
|
||||
// only reach this path on the first pass when the feedback is kNone.
|
||||
CSA_ASSERT(this, SmiEqual(CAST(var_feedback->value()),
|
||||
CSA_ASSERT(this, SmiEqual(var_feedback->value(),
|
||||
SmiConstant(BinaryOperationFeedback::kNone)));
|
||||
}
|
||||
GotoIf(InstanceTypeEqual(instance_type, ODDBALL_TYPE), &is_oddball);
|
||||
@ -5711,25 +5707,25 @@ void CodeStubAssembler::TaggedToWord32OrBigIntImpl(
|
||||
auto builtin = conversion == Object::Conversion::kToNumeric
|
||||
? Builtins::kNonNumberToNumeric
|
||||
: Builtins::kNonNumberToNumber;
|
||||
var_value.Bind(CallBuiltin(builtin, context, value));
|
||||
var_value = CallBuiltin(builtin, context, value);
|
||||
OverwriteFeedback(var_feedback, BinaryOperationFeedback::kAny);
|
||||
Goto(&loop);
|
||||
|
||||
BIND(&is_oddball);
|
||||
var_value.Bind(LoadObjectField(value, Oddball::kToNumberOffset));
|
||||
var_value = LoadObjectField(value_heap_object, Oddball::kToNumberOffset);
|
||||
OverwriteFeedback(var_feedback,
|
||||
BinaryOperationFeedback::kNumberOrOddball);
|
||||
Goto(&loop);
|
||||
}
|
||||
|
||||
BIND(&is_heap_number);
|
||||
var_word32->Bind(TruncateHeapNumberValueToWord32(CAST(value)));
|
||||
*var_word32 = TruncateHeapNumberValueToWord32(CAST(value));
|
||||
CombineFeedback(var_feedback, BinaryOperationFeedback::kNumber);
|
||||
Goto(if_number);
|
||||
|
||||
if (conversion == Object::Conversion::kToNumeric) {
|
||||
BIND(&is_bigint);
|
||||
var_bigint->Bind(value);
|
||||
*var_maybe_bigint = value;
|
||||
CombineFeedback(var_feedback, BinaryOperationFeedback::kBigInt);
|
||||
Goto(if_bigint);
|
||||
}
|
||||
@ -11547,8 +11543,8 @@ Operation Reverse(Operation op) {
|
||||
} // anonymous namespace
|
||||
|
||||
TNode<Oddball> CodeStubAssembler::RelationalComparison(
|
||||
Operation op, SloppyTNode<Object> left, SloppyTNode<Object> right,
|
||||
SloppyTNode<Context> context, TVariable<Smi>* var_type_feedback) {
|
||||
Operation op, TNode<Object> left, TNode<Object> right,
|
||||
TNode<Context> context, TVariable<Smi>* var_type_feedback) {
|
||||
Label return_true(this), return_false(this), do_float_comparison(this),
|
||||
end(this);
|
||||
TVARIABLE(Oddball, var_result); // Actually only "true" or "false".
|
||||
|
@ -2305,12 +2305,16 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
SloppyTNode<Object> value);
|
||||
TNode<Word32T> TruncateTaggedToWord32(SloppyTNode<Context> context,
|
||||
SloppyTNode<Object> value);
|
||||
void TaggedToWord32OrBigInt(Node* context, Node* value, Label* if_number,
|
||||
Variable* var_word32, Label* if_bigint,
|
||||
Variable* var_bigint);
|
||||
void TaggedToWord32OrBigIntWithFeedback(
|
||||
Node* context, Node* value, Label* if_number, Variable* var_word32,
|
||||
Label* if_bigint, Variable* var_bigint, Variable* var_feedback);
|
||||
void TaggedToWord32OrBigInt(TNode<Context> context, TNode<Object> value,
|
||||
Label* if_number, TVariable<Word32T>* var_word32,
|
||||
Label* if_bigint,
|
||||
TVariable<Object>* var_maybe_bigint);
|
||||
void TaggedToWord32OrBigIntWithFeedback(TNode<Context> context,
|
||||
TNode<Object> value, Label* if_number,
|
||||
TVariable<Word32T>* var_word32,
|
||||
Label* if_bigint,
|
||||
TVariable<Object>* var_maybe_bigint,
|
||||
TVariable<Smi>* var_feedback);
|
||||
|
||||
// Truncate the floating point value of a HeapNumber to an Int32.
|
||||
TNode<Int32T> TruncateHeapNumberValueToWord32(TNode<HeapNumber> object);
|
||||
@ -3409,9 +3413,8 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
TNode<IntPtrT> end_offset, RootIndex root);
|
||||
|
||||
TNode<Oddball> RelationalComparison(
|
||||
Operation op, SloppyTNode<Object> left, SloppyTNode<Object> right,
|
||||
SloppyTNode<Context> context,
|
||||
TVariable<Smi>* var_type_feedback = nullptr);
|
||||
Operation op, TNode<Object> left, TNode<Object> right,
|
||||
TNode<Context> context, TVariable<Smi>* var_type_feedback = nullptr);
|
||||
|
||||
void BranchIfNumberRelationalComparison(Operation op,
|
||||
SloppyTNode<Number> left,
|
||||
@ -3811,11 +3814,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
||||
Variable* var_numeric, Variable* var_feedback);
|
||||
|
||||
template <Object::Conversion conversion>
|
||||
void TaggedToWord32OrBigIntImpl(Node* context, Node* value, Label* if_number,
|
||||
Variable* var_word32,
|
||||
void TaggedToWord32OrBigIntImpl(TNode<Context> context, TNode<Object> value,
|
||||
Label* if_number,
|
||||
TVariable<Word32T>* var_word32,
|
||||
Label* if_bigint = nullptr,
|
||||
Variable* var_bigint = nullptr,
|
||||
Variable* var_feedback = nullptr);
|
||||
TVariable<Object>* var_maybe_bigint = nullptr,
|
||||
TVariable<Smi>* var_feedback = nullptr);
|
||||
|
||||
private:
|
||||
// Low-level accessors for Descriptor arrays.
|
||||
|
Loading…
Reference in New Issue
Block a user