[stubs] Extract ToInteger to CodeStubAssembler
Moving ToInteger to CodeStubAssembler allows us to inline it in several builtins. In a follow-up commit, we'll add a TruncationMode argument to specify how -0.0 should be handled. BUG= Review-Url: https://codereview.chromium.org/2364473006 Cr-Commit-Position: refs/heads/master@{#39671}
This commit is contained in:
parent
7f025eb626
commit
84145a149b
@ -1307,8 +1307,7 @@ void Builtins::Generate_ArrayIncludes(CodeStubAssembler* assembler) {
|
||||
{
|
||||
Label done(assembler), init_k_smi(assembler), init_k_heap_num(assembler),
|
||||
init_k_zero(assembler), init_k_n(assembler);
|
||||
Callable call_to_integer = CodeFactory::ToInteger(assembler->isolate());
|
||||
Node* tagged_n = assembler->CallStub(call_to_integer, context, start_from);
|
||||
Node* tagged_n = assembler->ToInteger(context, start_from);
|
||||
|
||||
assembler->Branch(assembler->WordIsSmi(tagged_n), &init_k_smi,
|
||||
&init_k_heap_num);
|
||||
@ -1755,8 +1754,7 @@ void Builtins::Generate_ArrayIndexOf(CodeStubAssembler* assembler) {
|
||||
{
|
||||
Label done(assembler), init_k_smi(assembler), init_k_heap_num(assembler),
|
||||
init_k_zero(assembler), init_k_n(assembler);
|
||||
Callable call_to_integer = CodeFactory::ToInteger(assembler->isolate());
|
||||
Node* tagged_n = assembler->CallStub(call_to_integer, context, start_from);
|
||||
Node* tagged_n = assembler->ToInteger(context, start_from);
|
||||
|
||||
assembler->Branch(assembler->WordIsSmi(tagged_n), &init_k_smi,
|
||||
&init_k_heap_num);
|
||||
|
@ -228,8 +228,7 @@ void Builtins::Generate_AtomicsStore(CodeStubAssembler* a) {
|
||||
ValidateAtomicIndex(a, index_word32, array_length_word32, context);
|
||||
Node* index_word = a->ChangeUint32ToWord(index_word32);
|
||||
|
||||
Callable to_integer = CodeFactory::ToInteger(a->isolate());
|
||||
Node* value_integer = a->CallStub(to_integer, context, value);
|
||||
Node* value_integer = a->ToInteger(context, value);
|
||||
Node* value_word32 = a->TruncateTaggedToWord32(context, value_integer);
|
||||
|
||||
CodeStubAssembler::Label u8(a), u16(a), u32(a), other(a);
|
||||
|
@ -318,8 +318,7 @@ void Builtins::Generate_StringPrototypeCharAt(CodeStubAssembler* assembler) {
|
||||
assembler->Bind(&if_positionisnotsmi);
|
||||
{
|
||||
// Convert the {position} to an Integer via the ToIntegerStub.
|
||||
Callable callable = CodeFactory::ToInteger(assembler->isolate());
|
||||
Node* index = assembler->CallStub(callable, context, position);
|
||||
Node* index = assembler->ToInteger(context, position);
|
||||
|
||||
// Check if the resulting {index} is now a Smi.
|
||||
Label if_indexissmi(assembler, Label::kDeferred),
|
||||
@ -413,8 +412,7 @@ void Builtins::Generate_StringPrototypeCharCodeAt(
|
||||
assembler->Bind(&if_positionisnotsmi);
|
||||
{
|
||||
// Convert the {position} to an Integer via the ToIntegerStub.
|
||||
Callable callable = CodeFactory::ToInteger(assembler->isolate());
|
||||
Node* index = assembler->CallStub(callable, context, position);
|
||||
Node* index = assembler->ToInteger(context, position);
|
||||
|
||||
// Check if the resulting {index} is now a Smi.
|
||||
Label if_indexissmi(assembler, Label::kDeferred),
|
||||
|
@ -2985,6 +2985,60 @@ Node* CodeStubAssembler::ToNumber(Node* context, Node* input) {
|
||||
return var_result.value();
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::ToInteger(Node* context, Node* input) {
|
||||
// We might need to loop once for ToNumber conversion.
|
||||
Variable var_arg(this, MachineRepresentation::kTagged);
|
||||
Label loop(this, &var_arg), out(this);
|
||||
var_arg.Bind(input);
|
||||
Goto(&loop);
|
||||
Bind(&loop);
|
||||
{
|
||||
// Shared entry points.
|
||||
Label return_zero(this, Label::kDeferred);
|
||||
|
||||
// Load the current {arg} value.
|
||||
Node* arg = var_arg.value();
|
||||
|
||||
// Check if {arg} is a Smi.
|
||||
GotoIf(WordIsSmi(arg), &out);
|
||||
|
||||
// Check if {arg} is a HeapNumber.
|
||||
Label if_argisheapnumber(this),
|
||||
if_argisnotheapnumber(this, Label::kDeferred);
|
||||
Branch(WordEqual(LoadMap(arg), HeapNumberMapConstant()),
|
||||
&if_argisheapnumber, &if_argisnotheapnumber);
|
||||
|
||||
Bind(&if_argisheapnumber);
|
||||
{
|
||||
// Load the floating-point value of {arg}.
|
||||
Node* arg_value = LoadHeapNumberValue(arg);
|
||||
|
||||
// Check if {arg} is NaN.
|
||||
GotoUnless(Float64Equal(arg_value, arg_value), &return_zero);
|
||||
|
||||
// Truncate {arg} towards zero.
|
||||
Node* value = Float64Trunc(arg_value);
|
||||
var_arg.Bind(ChangeFloat64ToTagged(value));
|
||||
Goto(&out);
|
||||
}
|
||||
|
||||
Bind(&if_argisnotheapnumber);
|
||||
{
|
||||
// Need to convert {arg} to a Number first.
|
||||
Callable callable = CodeFactory::NonNumberToNumber(isolate());
|
||||
var_arg.Bind(CallStub(callable, context, arg));
|
||||
Goto(&loop);
|
||||
}
|
||||
|
||||
Bind(&return_zero);
|
||||
var_arg.Bind(SmiConstant(Smi::FromInt(0)));
|
||||
Goto(&out);
|
||||
}
|
||||
|
||||
Bind(&out);
|
||||
return var_arg.value();
|
||||
}
|
||||
|
||||
Node* CodeStubAssembler::BitFieldDecode(Node* word32, uint32_t shift,
|
||||
uint32_t mask) {
|
||||
return Word32Shr(Word32And(word32, Int32Constant(mask)),
|
||||
|
@ -489,6 +489,9 @@ class CodeStubAssembler : public compiler::CodeAssembler {
|
||||
// Convert any object to a Number.
|
||||
compiler::Node* ToNumber(compiler::Node* context, compiler::Node* input);
|
||||
|
||||
// Convert any object to an Integer.
|
||||
compiler::Node* ToInteger(compiler::Node* context, compiler::Node* input);
|
||||
|
||||
// Returns a node that contains a decoded (unsigned!) value of a bit
|
||||
// field |T| in |word32|. Returns result as an uint32 node.
|
||||
template <typename T>
|
||||
|
@ -4927,64 +4927,12 @@ void ToLengthStub::GenerateAssembly(CodeStubAssembler* assembler) const {
|
||||
}
|
||||
|
||||
void ToIntegerStub::GenerateAssembly(CodeStubAssembler* assembler) const {
|
||||
typedef CodeStubAssembler::Label Label;
|
||||
typedef compiler::Node Node;
|
||||
typedef CodeStubAssembler::Variable Variable;
|
||||
|
||||
Node* context = assembler->Parameter(1);
|
||||
Node* input = assembler->Parameter(Descriptor::kArgument);
|
||||
Node* context = assembler->Parameter(Descriptor::kContext);
|
||||
|
||||
// We might need to loop once for ToNumber conversion.
|
||||
Variable var_arg(assembler, MachineRepresentation::kTagged);
|
||||
Label loop(assembler, &var_arg);
|
||||
var_arg.Bind(assembler->Parameter(0));
|
||||
assembler->Goto(&loop);
|
||||
assembler->Bind(&loop);
|
||||
{
|
||||
// Shared entry points.
|
||||
Label return_arg(assembler), return_zero(assembler, Label::kDeferred);
|
||||
|
||||
// Load the current {arg} value.
|
||||
Node* arg = var_arg.value();
|
||||
|
||||
// Check if {arg} is a Smi.
|
||||
assembler->GotoIf(assembler->WordIsSmi(arg), &return_arg);
|
||||
|
||||
// Check if {arg} is a HeapNumber.
|
||||
Label if_argisheapnumber(assembler),
|
||||
if_argisnotheapnumber(assembler, Label::kDeferred);
|
||||
assembler->Branch(assembler->WordEqual(assembler->LoadMap(arg),
|
||||
assembler->HeapNumberMapConstant()),
|
||||
&if_argisheapnumber, &if_argisnotheapnumber);
|
||||
|
||||
assembler->Bind(&if_argisheapnumber);
|
||||
{
|
||||
// Load the floating-point value of {arg}.
|
||||
Node* arg_value = assembler->LoadHeapNumberValue(arg);
|
||||
|
||||
// Check if {arg} is NaN.
|
||||
assembler->GotoUnless(assembler->Float64Equal(arg_value, arg_value),
|
||||
&return_zero);
|
||||
|
||||
// Truncate {arg} towards zero.
|
||||
Node* value = assembler->Float64Trunc(arg_value);
|
||||
var_arg.Bind(assembler->ChangeFloat64ToTagged(value));
|
||||
assembler->Goto(&return_arg);
|
||||
}
|
||||
|
||||
assembler->Bind(&if_argisnotheapnumber);
|
||||
{
|
||||
// Need to convert {arg} to a Number first.
|
||||
Callable callable = CodeFactory::NonNumberToNumber(assembler->isolate());
|
||||
var_arg.Bind(assembler->CallStub(callable, context, arg));
|
||||
assembler->Goto(&loop);
|
||||
}
|
||||
|
||||
assembler->Bind(&return_arg);
|
||||
assembler->Return(var_arg.value());
|
||||
|
||||
assembler->Bind(&return_zero);
|
||||
assembler->Return(assembler->SmiConstant(Smi::FromInt(0)));
|
||||
}
|
||||
assembler->Return(assembler->ToInteger(context, input));
|
||||
}
|
||||
|
||||
void StoreInterceptorStub::GenerateAssembly(
|
||||
|
Loading…
Reference in New Issue
Block a user