[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:
jgruber 2016-09-23 07:27:58 -07:00 committed by Commit bot
parent 7f025eb626
commit 84145a149b
6 changed files with 65 additions and 65 deletions

View File

@ -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);

View File

@ -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);

View File

@ -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),

View File

@ -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)),

View File

@ -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>

View File

@ -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(