summaryrefslogtreecommitdiff
path: root/deps/v8/src/code-stub-assembler.cc
diff options
context:
space:
mode:
authorMichaël Zasso <targos@protonmail.com>2017-06-06 10:28:14 +0200
committerMichaël Zasso <targos@protonmail.com>2017-06-07 10:33:31 +0200
commit3dc8c3bed4cf3a77607edbb0b015e33f8b60fc09 (patch)
tree9dee56e142638b34f1eccbd0ad88c3bce5377c29 /deps/v8/src/code-stub-assembler.cc
parent91a1bbe3055a660194ca4d403795aa0c03e9d056 (diff)
downloadnode-new-3dc8c3bed4cf3a77607edbb0b015e33f8b60fc09.tar.gz
deps: update V8 to 5.9.211.32
PR-URL: https://github.com/nodejs/node/pull/13263 Reviewed-By: Gibson Fahnestock <gibfahn@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com> Reviewed-By: Myles Borins <myles.borins@gmail.com>
Diffstat (limited to 'deps/v8/src/code-stub-assembler.cc')
-rw-r--r--deps/v8/src/code-stub-assembler.cc2298
1 files changed, 1217 insertions, 1081 deletions
diff --git a/deps/v8/src/code-stub-assembler.cc b/deps/v8/src/code-stub-assembler.cc
index e1ab040ab5..7b062b6bf6 100644
--- a/deps/v8/src/code-stub-assembler.cc
+++ b/deps/v8/src/code-stub-assembler.cc
@@ -58,7 +58,7 @@ void CodeStubAssembler::Assert(const NodeGenerator& codition_body,
Node* condition = codition_body();
DCHECK_NOT_NULL(condition);
Branch(condition, &ok, &not_ok);
- Bind(&not_ok);
+ BIND(&not_ok);
if (message != nullptr) {
char chars[1024];
Vector<char> buffer(chars);
@@ -74,7 +74,7 @@ void CodeStubAssembler::Assert(const NodeGenerator& codition_body,
}
DebugBreak();
Goto(&ok);
- Bind(&ok);
+ BIND(&ok);
Comment("] Assert");
}
#endif
@@ -83,22 +83,22 @@ void CodeStubAssembler::Assert(const NodeGenerator& codition_body,
Node* CodeStubAssembler::Select(Node* condition, const NodeGenerator& true_body,
const NodeGenerator& false_body,
MachineRepresentation rep) {
- Variable value(this, rep);
+ VARIABLE(value, rep);
Label vtrue(this), vfalse(this), end(this);
Branch(condition, &vtrue, &vfalse);
- Bind(&vtrue);
+ BIND(&vtrue);
{
value.Bind(true_body());
Goto(&end);
}
- Bind(&vfalse);
+ BIND(&vfalse);
{
value.Bind(false_body());
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
return value.value();
}
@@ -212,14 +212,14 @@ Node* CodeStubAssembler::Float64Round(Node* x) {
Label return_x(this);
// Round up {x} towards Infinity.
- Variable var_x(this, MachineRepresentation::kFloat64, Float64Ceil(x));
+ VARIABLE(var_x, MachineRepresentation::kFloat64, Float64Ceil(x));
GotoIf(Float64LessThanOrEqual(Float64Sub(var_x.value(), one_half), x),
&return_x);
var_x.Bind(Float64Sub(var_x.value(), one));
Goto(&return_x);
- Bind(&return_x);
+ BIND(&return_x);
return var_x.value();
}
@@ -233,7 +233,7 @@ Node* CodeStubAssembler::Float64Ceil(Node* x) {
Node* two_52 = Float64Constant(4503599627370496.0E0);
Node* minus_two_52 = Float64Constant(-4503599627370496.0E0);
- Variable var_x(this, MachineRepresentation::kFloat64, x);
+ VARIABLE(var_x, MachineRepresentation::kFloat64, x);
Label return_x(this), return_minus_x(this);
// Check if {x} is greater than zero.
@@ -241,7 +241,7 @@ Node* CodeStubAssembler::Float64Ceil(Node* x) {
Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero,
&if_xnotgreaterthanzero);
- Bind(&if_xgreaterthanzero);
+ BIND(&if_xgreaterthanzero);
{
// Just return {x} unless it's in the range ]0,2^52[.
GotoIf(Float64GreaterThanOrEqual(x, two_52), &return_x);
@@ -253,7 +253,7 @@ Node* CodeStubAssembler::Float64Ceil(Node* x) {
Goto(&return_x);
}
- Bind(&if_xnotgreaterthanzero);
+ BIND(&if_xnotgreaterthanzero);
{
// Just return {x} unless it's in the range ]-2^52,0[
GotoIf(Float64LessThanOrEqual(x, minus_two_52), &return_x);
@@ -267,11 +267,11 @@ Node* CodeStubAssembler::Float64Ceil(Node* x) {
Goto(&return_minus_x);
}
- Bind(&return_minus_x);
+ BIND(&return_minus_x);
var_x.Bind(Float64Neg(var_x.value()));
Goto(&return_x);
- Bind(&return_x);
+ BIND(&return_x);
return var_x.value();
}
@@ -285,7 +285,7 @@ Node* CodeStubAssembler::Float64Floor(Node* x) {
Node* two_52 = Float64Constant(4503599627370496.0E0);
Node* minus_two_52 = Float64Constant(-4503599627370496.0E0);
- Variable var_x(this, MachineRepresentation::kFloat64, x);
+ VARIABLE(var_x, MachineRepresentation::kFloat64, x);
Label return_x(this), return_minus_x(this);
// Check if {x} is greater than zero.
@@ -293,7 +293,7 @@ Node* CodeStubAssembler::Float64Floor(Node* x) {
Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero,
&if_xnotgreaterthanzero);
- Bind(&if_xgreaterthanzero);
+ BIND(&if_xgreaterthanzero);
{
// Just return {x} unless it's in the range ]0,2^52[.
GotoIf(Float64GreaterThanOrEqual(x, two_52), &return_x);
@@ -305,7 +305,7 @@ Node* CodeStubAssembler::Float64Floor(Node* x) {
Goto(&return_x);
}
- Bind(&if_xnotgreaterthanzero);
+ BIND(&if_xnotgreaterthanzero);
{
// Just return {x} unless it's in the range ]-2^52,0[
GotoIf(Float64LessThanOrEqual(x, minus_two_52), &return_x);
@@ -319,11 +319,11 @@ Node* CodeStubAssembler::Float64Floor(Node* x) {
Goto(&return_minus_x);
}
- Bind(&return_minus_x);
+ BIND(&return_minus_x);
var_x.Bind(Float64Neg(var_x.value()));
Goto(&return_x);
- Bind(&return_x);
+ BIND(&return_x);
return var_x.value();
}
@@ -335,7 +335,7 @@ Node* CodeStubAssembler::Float64RoundToEven(Node* x) {
Node* f = Float64Floor(x);
Node* f_and_half = Float64Add(f, Float64Constant(0.5));
- Variable var_result(this, MachineRepresentation::kFloat64);
+ VARIABLE(var_result, MachineRepresentation::kFloat64);
Label return_f(this), return_f_plus_one(this), done(this);
GotoIf(Float64LessThan(f_and_half, x), &return_f_plus_one);
@@ -346,15 +346,15 @@ Node* CodeStubAssembler::Float64RoundToEven(Node* x) {
&return_f_plus_one);
}
- Bind(&return_f);
+ BIND(&return_f);
var_result.Bind(f);
Goto(&done);
- Bind(&return_f_plus_one);
+ BIND(&return_f_plus_one);
var_result.Bind(Float64Add(f, Float64Constant(1.0)));
Goto(&done);
- Bind(&done);
+ BIND(&done);
return var_result.value();
}
@@ -368,7 +368,7 @@ Node* CodeStubAssembler::Float64Trunc(Node* x) {
Node* two_52 = Float64Constant(4503599627370496.0E0);
Node* minus_two_52 = Float64Constant(-4503599627370496.0E0);
- Variable var_x(this, MachineRepresentation::kFloat64, x);
+ VARIABLE(var_x, MachineRepresentation::kFloat64, x);
Label return_x(this), return_minus_x(this);
// Check if {x} is greater than 0.
@@ -376,7 +376,7 @@ Node* CodeStubAssembler::Float64Trunc(Node* x) {
Branch(Float64GreaterThan(x, zero), &if_xgreaterthanzero,
&if_xnotgreaterthanzero);
- Bind(&if_xgreaterthanzero);
+ BIND(&if_xgreaterthanzero);
{
if (IsFloat64RoundDownSupported()) {
var_x.Bind(Float64RoundDown(x));
@@ -392,7 +392,7 @@ Node* CodeStubAssembler::Float64Trunc(Node* x) {
Goto(&return_x);
}
- Bind(&if_xnotgreaterthanzero);
+ BIND(&if_xnotgreaterthanzero);
{
if (IsFloat64RoundUpSupported()) {
var_x.Bind(Float64RoundUp(x));
@@ -411,11 +411,11 @@ Node* CodeStubAssembler::Float64Trunc(Node* x) {
}
}
- Bind(&return_minus_x);
+ BIND(&return_minus_x);
var_x.Bind(Float64Neg(var_x.value()));
Goto(&return_x);
- Bind(&return_x);
+ BIND(&return_x);
return var_x.value();
}
@@ -458,7 +458,7 @@ Node* CodeStubAssembler::SmiMin(Node* a, Node* b) {
}
Node* CodeStubAssembler::SmiMod(Node* a, Node* b) {
- Variable var_result(this, MachineRepresentation::kTagged);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
Label return_result(this, &var_result),
return_minuszero(this, Label::kDeferred),
return_nan(this, Label::kDeferred);
@@ -475,7 +475,7 @@ Node* CodeStubAssembler::SmiMod(Node* a, Node* b) {
Branch(Int32LessThanOrEqual(Int32Constant(0), a), &if_aisnotnegative,
&if_aisnegative);
- Bind(&if_aisnotnegative);
+ BIND(&if_aisnotnegative);
{
// Fast case, don't need to check any other edge cases.
Node* r = Int32Mod(a, b);
@@ -483,7 +483,7 @@ Node* CodeStubAssembler::SmiMod(Node* a, Node* b) {
Goto(&return_result);
}
- Bind(&if_aisnegative);
+ BIND(&if_aisnegative);
{
if (SmiValuesAre32Bits()) {
// Check if {a} is kMinInt and {b} is -1 (only relevant if the
@@ -492,7 +492,7 @@ Node* CodeStubAssembler::SmiMod(Node* a, Node* b) {
GotoIfNot(Word32Equal(a, Int32Constant(kMinInt)), &join);
GotoIf(Word32Equal(b, Int32Constant(-1)), &return_minuszero);
Goto(&join);
- Bind(&join);
+ BIND(&join);
}
// Perform the integer modulus operation.
@@ -508,22 +508,22 @@ Node* CodeStubAssembler::SmiMod(Node* a, Node* b) {
Goto(&return_result);
}
- Bind(&return_minuszero);
+ BIND(&return_minuszero);
var_result.Bind(MinusZeroConstant());
Goto(&return_result);
- Bind(&return_nan);
+ BIND(&return_nan);
var_result.Bind(NanConstant());
Goto(&return_result);
- Bind(&return_result);
+ BIND(&return_result);
return var_result.value();
}
Node* CodeStubAssembler::SmiMul(Node* a, Node* b) {
- Variable var_result(this, MachineRepresentation::kTagged);
- Variable var_lhs_float64(this, MachineRepresentation::kFloat64),
- var_rhs_float64(this, MachineRepresentation::kFloat64);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
+ VARIABLE(var_lhs_float64, MachineRepresentation::kFloat64);
+ VARIABLE(var_rhs_float64, MachineRepresentation::kFloat64);
Label return_result(this, &var_result);
// Both {a} and {b} are Smis. Convert them to integers and multiply.
@@ -536,7 +536,7 @@ Node* CodeStubAssembler::SmiMul(Node* a, Node* b) {
// Check if the multiplication overflowed.
Label if_overflow(this, Label::kDeferred), if_notoverflow(this);
Branch(overflow, &if_overflow, &if_notoverflow);
- Bind(&if_notoverflow);
+ BIND(&if_notoverflow);
{
// If the answer is zero, we may need to return -0.0, depending on the
// input.
@@ -544,30 +544,30 @@ Node* CodeStubAssembler::SmiMul(Node* a, Node* b) {
Node* answer = Projection(0, pair);
Node* zero = Int32Constant(0);
Branch(Word32Equal(answer, zero), &answer_zero, &answer_not_zero);
- Bind(&answer_not_zero);
+ BIND(&answer_not_zero);
{
var_result.Bind(ChangeInt32ToTagged(answer));
Goto(&return_result);
}
- Bind(&answer_zero);
+ BIND(&answer_zero);
{
Node* or_result = Word32Or(lhs32, rhs32);
Label if_should_be_negative_zero(this), if_should_be_zero(this);
Branch(Int32LessThan(or_result, zero), &if_should_be_negative_zero,
&if_should_be_zero);
- Bind(&if_should_be_negative_zero);
+ BIND(&if_should_be_negative_zero);
{
var_result.Bind(MinusZeroConstant());
Goto(&return_result);
}
- Bind(&if_should_be_zero);
+ BIND(&if_should_be_zero);
{
var_result.Bind(SmiConstant(0));
Goto(&return_result);
}
}
}
- Bind(&if_overflow);
+ BIND(&if_overflow);
{
var_lhs_float64.Bind(SmiToFloat64(a));
var_rhs_float64.Bind(SmiToFloat64(b));
@@ -577,10 +577,57 @@ Node* CodeStubAssembler::SmiMul(Node* a, Node* b) {
Goto(&return_result);
}
- Bind(&return_result);
+ BIND(&return_result);
return var_result.value();
}
+Node* CodeStubAssembler::TrySmiDiv(Node* dividend, Node* divisor,
+ Label* bailout) {
+ // Both {a} and {b} are Smis. Bailout to floating point division if {divisor}
+ // is zero.
+ GotoIf(WordEqual(divisor, SmiConstant(0)), bailout);
+
+ // Do floating point division if {dividend} is zero and {divisor} is
+ // negative.
+ Label dividend_is_zero(this), dividend_is_not_zero(this);
+ Branch(WordEqual(dividend, SmiConstant(0)), &dividend_is_zero,
+ &dividend_is_not_zero);
+
+ Bind(&dividend_is_zero);
+ {
+ GotoIf(SmiLessThan(divisor, SmiConstant(0)), bailout);
+ Goto(&dividend_is_not_zero);
+ }
+ Bind(&dividend_is_not_zero);
+
+ Node* untagged_divisor = SmiToWord32(divisor);
+ Node* untagged_dividend = SmiToWord32(dividend);
+
+ // Do floating point division if {dividend} is kMinInt (or kMinInt - 1
+ // if the Smi size is 31) and {divisor} is -1.
+ Label divisor_is_minus_one(this), divisor_is_not_minus_one(this);
+ Branch(Word32Equal(untagged_divisor, Int32Constant(-1)),
+ &divisor_is_minus_one, &divisor_is_not_minus_one);
+
+ Bind(&divisor_is_minus_one);
+ {
+ GotoIf(Word32Equal(
+ untagged_dividend,
+ Int32Constant(kSmiValueSize == 32 ? kMinInt : (kMinInt >> 1))),
+ bailout);
+ Goto(&divisor_is_not_minus_one);
+ }
+ Bind(&divisor_is_not_minus_one);
+
+ Node* untagged_result = Int32Div(untagged_dividend, untagged_divisor);
+ Node* truncated = Int32Mul(untagged_result, untagged_divisor);
+
+ // Do floating point division if the remainder is not 0.
+ GotoIf(Word32NotEqual(untagged_dividend, truncated), bailout);
+
+ return SmiFromWord32(untagged_result);
+}
+
Node* CodeStubAssembler::TruncateWordToWord32(Node* value) {
if (Is64()) {
return TruncateInt64ToInt32(value);
@@ -613,12 +660,12 @@ Node* CodeStubAssembler::WordIsWordAligned(Node* word) {
void CodeStubAssembler::BranchIfPrototypesHaveNoElements(
Node* receiver_map, Label* definitely_no_elements,
Label* possibly_elements) {
- Variable var_map(this, MachineRepresentation::kTagged, receiver_map);
+ VARIABLE(var_map, MachineRepresentation::kTagged, receiver_map);
Label loop_body(this, &var_map);
Node* empty_elements = LoadRoot(Heap::kEmptyFixedArrayRootIndex);
Goto(&loop_body);
- Bind(&loop_body);
+ BIND(&loop_body);
{
Node* map = var_map.value();
Node* prototype = LoadMapPrototype(map);
@@ -680,24 +727,24 @@ void CodeStubAssembler::BranchIfFastJSArray(
BranchIfPrototypesHaveNoElements(map, if_true, if_false);
}
-Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes,
- AllocationFlags flags,
- Node* top_address,
- Node* limit_address) {
+Node* CodeStubAssembler::AllocateRaw(Node* size_in_bytes, AllocationFlags flags,
+ Node* top_address, Node* limit_address) {
Node* top = Load(MachineType::Pointer(), top_address);
Node* limit = Load(MachineType::Pointer(), limit_address);
// If there's not enough space, call the runtime.
- Variable result(this, MachineRepresentation::kTagged);
+ VARIABLE(result, MachineRepresentation::kTagged);
Label runtime_call(this, Label::kDeferred), no_runtime_call(this);
Label merge_runtime(this, &result);
+ bool needs_double_alignment = flags & kDoubleAlignment;
+
if (flags & kAllowLargeObjectAllocation) {
Label next(this);
GotoIf(IsRegularHeapObjectSize(size_in_bytes), &next);
Node* runtime_flags = SmiConstant(
- Smi::FromInt(AllocateDoubleAlignFlag::encode(false) |
+ Smi::FromInt(AllocateDoubleAlignFlag::encode(needs_double_alignment) |
AllocateTargetSpace::encode(AllocationSpace::LO_SPACE)));
Node* const runtime_result =
CallRuntime(Runtime::kAllocateInTargetSpace, NoContextConstant(),
@@ -705,18 +752,35 @@ Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes,
result.Bind(runtime_result);
Goto(&merge_runtime);
- Bind(&next);
+ BIND(&next);
}
- Node* new_top = IntPtrAdd(top, size_in_bytes);
+ VARIABLE(adjusted_size, MachineType::PointerRepresentation(), size_in_bytes);
+
+ if (needs_double_alignment) {
+ Label not_aligned(this), done_alignment(this, &adjusted_size);
+
+ Branch(WordAnd(top, IntPtrConstant(kDoubleAlignmentMask)), &not_aligned,
+ &done_alignment);
+
+ BIND(&not_aligned);
+ Node* not_aligned_size = IntPtrAdd(size_in_bytes, IntPtrConstant(4));
+ adjusted_size.Bind(not_aligned_size);
+ Goto(&done_alignment);
+
+ BIND(&done_alignment);
+ }
+
+ Node* new_top = IntPtrAdd(top, adjusted_size.value());
+
Branch(UintPtrGreaterThanOrEqual(new_top, limit), &runtime_call,
&no_runtime_call);
- Bind(&runtime_call);
+ BIND(&runtime_call);
Node* runtime_result;
if (flags & kPretenured) {
Node* runtime_flags = SmiConstant(
- Smi::FromInt(AllocateDoubleAlignFlag::encode(false) |
+ Smi::FromInt(AllocateDoubleAlignFlag::encode(needs_double_alignment) |
AllocateTargetSpace::encode(AllocationSpace::OLD_SPACE)));
runtime_result =
CallRuntime(Runtime::kAllocateInTargetSpace, NoContextConstant(),
@@ -729,69 +793,68 @@ Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes,
Goto(&merge_runtime);
// When there is enough space, return `top' and bump it up.
- Bind(&no_runtime_call);
+ BIND(&no_runtime_call);
Node* no_runtime_result = top;
StoreNoWriteBarrier(MachineType::PointerRepresentation(), top_address,
new_top);
- no_runtime_result = BitcastWordToTagged(
- IntPtrAdd(no_runtime_result, IntPtrConstant(kHeapObjectTag)));
- result.Bind(no_runtime_result);
- Goto(&merge_runtime);
- Bind(&merge_runtime);
- return result.value();
-}
+ VARIABLE(address, MachineType::PointerRepresentation(), no_runtime_result);
-Node* CodeStubAssembler::AllocateRawAligned(Node* size_in_bytes,
- AllocationFlags flags,
- Node* top_address,
- Node* limit_address) {
- Node* top = Load(MachineType::Pointer(), top_address);
- Node* limit = Load(MachineType::Pointer(), limit_address);
- Variable adjusted_size(this, MachineType::PointerRepresentation(),
- size_in_bytes);
- if (flags & kDoubleAlignment) {
- Label aligned(this), not_aligned(this), merge(this, &adjusted_size);
- Branch(WordAnd(top, IntPtrConstant(kDoubleAlignmentMask)), &not_aligned,
- &aligned);
+ if (needs_double_alignment) {
+ Label needs_filler(this), done_filling(this, &address);
+ Branch(IntPtrEqual(adjusted_size.value(), size_in_bytes), &done_filling,
+ &needs_filler);
- Bind(&not_aligned);
- Node* not_aligned_size =
- IntPtrAdd(size_in_bytes, IntPtrConstant(kPointerSize));
- adjusted_size.Bind(not_aligned_size);
- Goto(&merge);
+ BIND(&needs_filler);
+ // Store a filler and increase the address by kPointerSize.
+ StoreNoWriteBarrier(MachineRepresentation::kTagged, top,
+ LoadRoot(Heap::kOnePointerFillerMapRootIndex));
+ address.Bind(IntPtrAdd(no_runtime_result, IntPtrConstant(4)));
- Bind(&aligned);
- Goto(&merge);
+ Goto(&done_filling);
- Bind(&merge);
+ BIND(&done_filling);
}
- Variable address(
- this, MachineRepresentation::kTagged,
- AllocateRawUnaligned(adjusted_size.value(), kNone, top, limit));
+ no_runtime_result = BitcastWordToTagged(
+ IntPtrAdd(address.value(), IntPtrConstant(kHeapObjectTag)));
- Label needs_filler(this), doesnt_need_filler(this),
- merge_address(this, &address);
- Branch(IntPtrEqual(adjusted_size.value(), size_in_bytes), &doesnt_need_filler,
- &needs_filler);
+ result.Bind(no_runtime_result);
+ Goto(&merge_runtime);
- Bind(&needs_filler);
- // Store a filler and increase the address by kPointerSize.
- StoreNoWriteBarrier(MachineType::PointerRepresentation(), top,
- LoadRoot(Heap::kOnePointerFillerMapRootIndex));
- address.Bind(BitcastWordToTagged(
- IntPtrAdd(address.value(), IntPtrConstant(kPointerSize))));
- Goto(&merge_address);
+ BIND(&merge_runtime);
+ return result.value();
+}
- Bind(&doesnt_need_filler);
- Goto(&merge_address);
+Node* CodeStubAssembler::AllocateRawUnaligned(Node* size_in_bytes,
+ AllocationFlags flags,
+ Node* top_address,
+ Node* limit_address) {
+ DCHECK((flags & kDoubleAlignment) == 0);
+ return AllocateRaw(size_in_bytes, flags, top_address, limit_address);
+}
+
+Node* CodeStubAssembler::AllocateRawDoubleAligned(Node* size_in_bytes,
+ AllocationFlags flags,
+ Node* top_address,
+ Node* limit_address) {
+#if defined(V8_HOST_ARCH_32_BIT)
+ return AllocateRaw(size_in_bytes, flags | kDoubleAlignment, top_address,
+ limit_address);
+#elif defined(V8_HOST_ARCH_64_BIT)
+ // Allocation on 64 bit machine is naturally double aligned
+ return AllocateRaw(size_in_bytes, flags & ~kDoubleAlignment, top_address,
+ limit_address);
+#else
+#error Architecture not supported
+#endif
+}
- Bind(&merge_address);
- // Update the top.
- StoreNoWriteBarrier(MachineType::PointerRepresentation(), top_address,
- IntPtrAdd(top, adjusted_size.value()));
- return address.value();
+Node* CodeStubAssembler::AllocateInNewSpace(Node* size_in_bytes,
+ AllocationFlags flags) {
+ DCHECK(flags == kNone || flags == kDoubleAlignment);
+ CSA_ASSERT(this, IsRegularHeapObjectSize(size_in_bytes));
+ return Allocate(size_in_bytes, flags);
}
Node* CodeStubAssembler::Allocate(Node* size_in_bytes, AllocationFlags flags) {
@@ -813,13 +876,20 @@ Node* CodeStubAssembler::Allocate(Node* size_in_bytes, AllocationFlags flags) {
.address());
Node* limit_address = IntPtrAdd(top_address, IntPtrConstant(kPointerSize));
-#ifdef V8_HOST_ARCH_32_BIT
if (flags & kDoubleAlignment) {
- return AllocateRawAligned(size_in_bytes, flags, top_address, limit_address);
+ return AllocateRawDoubleAligned(size_in_bytes, flags, top_address,
+ limit_address);
+ } else {
+ return AllocateRawUnaligned(size_in_bytes, flags, top_address,
+ limit_address);
}
-#endif
+}
- return AllocateRawUnaligned(size_in_bytes, flags, top_address, limit_address);
+Node* CodeStubAssembler::AllocateInNewSpace(int size_in_bytes,
+ AllocationFlags flags) {
+ CHECK(flags == kNone || flags == kDoubleAlignment);
+ DCHECK_LE(size_in_bytes, kMaxRegularHeapObjectSize);
+ return CodeStubAssembler::Allocate(IntPtrConstant(size_in_bytes), flags);
}
Node* CodeStubAssembler::Allocate(int size_in_bytes, AllocationFlags flags) {
@@ -850,13 +920,13 @@ void CodeStubAssembler::BranchIfToBooleanIsTrue(Node* value, Label* if_true,
// Check if {value} is a Smi or a HeapObject.
Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi);
- Bind(&if_valueissmi);
+ BIND(&if_valueissmi);
{
// The {value} is a Smi, only need to check against zero.
BranchIfSmiEqual(value, SmiConstant(0), if_false, if_true);
}
- Bind(&if_valueisnotsmi);
+ BIND(&if_valueisnotsmi);
{
// Check if {value} is the empty string.
GotoIf(IsEmptyString(value), if_false);
@@ -877,7 +947,7 @@ void CodeStubAssembler::BranchIfToBooleanIsTrue(Node* value, Label* if_true,
// that make it here yield true.
Branch(IsHeapNumberMap(value_map), &if_valueisheapnumber, if_true);
- Bind(&if_valueisheapnumber);
+ BIND(&if_valueisheapnumber);
{
// Load the floating point value of {value}.
Node* value_value = LoadObjectField(value, HeapNumber::kValueOffset,
@@ -1109,12 +1179,12 @@ Node* CodeStubAssembler::LoadMapConstructorFunctionIndex(Node* map) {
Node* CodeStubAssembler::LoadMapConstructor(Node* map) {
CSA_SLOW_ASSERT(this, IsMap(map));
- Variable result(this, MachineRepresentation::kTagged,
- LoadObjectField(map, Map::kConstructorOrBackPointerOffset));
+ VARIABLE(result, MachineRepresentation::kTagged,
+ LoadObjectField(map, Map::kConstructorOrBackPointerOffset));
Label done(this), loop(this, &result);
Goto(&loop);
- Bind(&loop);
+ BIND(&loop);
{
GotoIf(TaggedIsSmi(result.value()), &done);
Node* is_map_type =
@@ -1124,7 +1194,7 @@ Node* CodeStubAssembler::LoadMapConstructor(Node* map) {
LoadObjectField(result.value(), Map::kConstructorOrBackPointerOffset));
Goto(&loop);
}
- Bind(&done);
+ BIND(&done);
return result.value();
}
@@ -1235,6 +1305,32 @@ Node* CodeStubAssembler::LoadFixedTypedArrayElement(
return Load(type, data_pointer, offset);
}
+Node* CodeStubAssembler::LoadFixedTypedArrayElementAsTagged(
+ Node* data_pointer, Node* index_node, ElementsKind elements_kind,
+ ParameterMode parameter_mode) {
+ Node* value = LoadFixedTypedArrayElement(data_pointer, index_node,
+ elements_kind, parameter_mode);
+ switch (elements_kind) {
+ case ElementsKind::INT8_ELEMENTS:
+ case ElementsKind::UINT8_CLAMPED_ELEMENTS:
+ case ElementsKind::UINT8_ELEMENTS:
+ case ElementsKind::INT16_ELEMENTS:
+ case ElementsKind::UINT16_ELEMENTS:
+ return SmiFromWord32(value);
+ case ElementsKind::INT32_ELEMENTS:
+ return ChangeInt32ToTagged(value);
+ case ElementsKind::UINT32_ELEMENTS:
+ return ChangeUint32ToTagged(value);
+ case ElementsKind::FLOAT32_ELEMENTS:
+ return AllocateHeapNumberWithValue(ChangeFloat32ToFloat64(value));
+ case ElementsKind::FLOAT64_ELEMENTS:
+ return AllocateHeapNumberWithValue(value);
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
+}
+
Node* CodeStubAssembler::LoadAndUntagToWord32FixedArrayElement(
Node* object, Node* index_node, int additional_offset,
ParameterMode parameter_mode) {
@@ -1435,12 +1531,11 @@ Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context,
Comment("BuildAppendJSArray: %s", ElementsKindToString(kind));
Label pre_bailout(this);
Label success(this);
- Variable var_tagged_length(this, MachineRepresentation::kTagged);
+ VARIABLE(var_tagged_length, MachineRepresentation::kTagged);
ParameterMode mode = OptimalParameterMode();
- Variable var_length(this, OptimalParameterRepresentation(),
- TaggedToParameter(LoadJSArrayLength(array), mode));
- Variable var_elements(this, MachineRepresentation::kTagged,
- LoadElements(array));
+ VARIABLE(var_length, OptimalParameterRepresentation(),
+ TaggedToParameter(LoadJSArrayLength(array), mode));
+ VARIABLE(var_elements, MachineRepresentation::kTagged, LoadElements(array));
Node* capacity =
TaggedToParameter(LoadFixedArrayBaseLength(var_elements.value()), mode);
@@ -1456,7 +1551,7 @@ Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context,
kind, capacity, new_capacity, mode,
&pre_bailout));
Goto(&fits);
- Bind(&fits);
+ BIND(&fits);
Node* elements = var_elements.value();
// Push each argument onto the end of the array now that there is enough
@@ -1491,7 +1586,7 @@ Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context,
Goto(&success);
}
- Bind(&pre_bailout);
+ BIND(&pre_bailout);
{
Node* length = ParameterToTagged(var_length.value(), mode);
var_tagged_length.Bind(length);
@@ -1501,7 +1596,7 @@ Node* CodeStubAssembler::BuildAppendJSArray(ElementsKind kind, Node* context,
Goto(bailout);
}
- Bind(&success);
+ BIND(&success);
return var_tagged_length.value();
}
@@ -1543,7 +1638,7 @@ Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length,
ParameterMode mode,
AllocationFlags flags) {
Comment("AllocateSeqOneByteString");
- Variable var_result(this, MachineRepresentation::kTagged);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
// Compute the SeqOneByteString size and check if it fits into new space.
Label if_lengthiszero(this), if_sizeissmall(this),
@@ -1557,10 +1652,10 @@ Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length,
Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)),
&if_sizeissmall, &if_notsizeissmall);
- Bind(&if_sizeissmall);
+ BIND(&if_sizeissmall);
{
// Just allocate the SeqOneByteString in new space.
- Node* result = Allocate(size, flags);
+ Node* result = AllocateInNewSpace(size, flags);
DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex));
StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex);
StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset,
@@ -1573,7 +1668,7 @@ Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length,
Goto(&if_join);
}
- Bind(&if_notsizeissmall);
+ BIND(&if_notsizeissmall);
{
// We might need to allocate in large object space, go to the runtime.
Node* result = CallRuntime(Runtime::kAllocateSeqOneByteString, context,
@@ -1582,13 +1677,13 @@ Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length,
Goto(&if_join);
}
- Bind(&if_lengthiszero);
+ BIND(&if_lengthiszero);
{
var_result.Bind(LoadRoot(Heap::kempty_stringRootIndex));
Goto(&if_join);
}
- Bind(&if_join);
+ BIND(&if_join);
return var_result.value();
}
@@ -1614,7 +1709,7 @@ Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length,
ParameterMode mode,
AllocationFlags flags) {
Comment("AllocateSeqTwoByteString");
- Variable var_result(this, MachineRepresentation::kTagged);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
// Compute the SeqTwoByteString size and check if it fits into new space.
Label if_lengthiszero(this), if_sizeissmall(this),
@@ -1628,10 +1723,10 @@ Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length,
Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)),
&if_sizeissmall, &if_notsizeissmall);
- Bind(&if_sizeissmall);
+ BIND(&if_sizeissmall);
{
// Just allocate the SeqTwoByteString in new space.
- Node* result = Allocate(size, flags);
+ Node* result = AllocateInNewSpace(size, flags);
DCHECK(Heap::RootIsImmortalImmovable(Heap::kStringMapRootIndex));
StoreMapNoWriteBarrier(result, Heap::kStringMapRootIndex);
StoreObjectFieldNoWriteBarrier(
@@ -1645,7 +1740,7 @@ Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length,
Goto(&if_join);
}
- Bind(&if_notsizeissmall);
+ BIND(&if_notsizeissmall);
{
// We might need to allocate in large object space, go to the runtime.
Node* result =
@@ -1655,13 +1750,13 @@ Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length,
Goto(&if_join);
}
- Bind(&if_lengthiszero);
+ BIND(&if_lengthiszero);
{
var_result.Bind(LoadRoot(Heap::kempty_stringRootIndex));
Goto(&if_join);
}
- Bind(&if_join);
+ BIND(&if_join);
return var_result.value();
}
@@ -1765,7 +1860,7 @@ Node* CodeStubAssembler::NewConsString(Node* context, Node* length, Node* left,
STATIC_ASSERT(kOneByteDataHintTag != 0);
Label one_byte_map(this);
Label two_byte_map(this);
- Variable result(this, MachineRepresentation::kTagged);
+ VARIABLE(result, MachineRepresentation::kTagged);
Label done(this, &result);
GotoIf(Word32NotEqual(Word32And(anded_instance_types,
Int32Constant(kStringEncodingMask |
@@ -1778,17 +1873,17 @@ Node* CodeStubAssembler::NewConsString(Node* context, Node* length, Node* left,
Int32Constant(kOneByteStringTag | kOneByteDataHintTag)),
&two_byte_map, &one_byte_map);
- Bind(&one_byte_map);
+ BIND(&one_byte_map);
Comment("One-byte ConsString");
result.Bind(AllocateOneByteConsString(length, left, right, flags));
Goto(&done);
- Bind(&two_byte_map);
+ BIND(&two_byte_map);
Comment("Two-byte ConsString");
result.Bind(AllocateTwoByteConsString(length, left, right, flags));
Goto(&done);
- Bind(&done);
+ BIND(&done);
return result.value();
}
@@ -1853,7 +1948,7 @@ Node* CodeStubAssembler::AllocateNameDictionary(Node* at_least_space_for) {
IntPtrAdd(WordShl(length, IntPtrConstant(kPointerSizeLog2)),
IntPtrConstant(NameDictionary::kHeaderSize));
- Node* result = Allocate(store_size);
+ Node* result = AllocateInNewSpace(store_size);
Comment("Initialize NameDictionary");
// Initialize FixedArray fields.
DCHECK(Heap::RootIsImmortalImmovable(Heap::kHashTableMapRootIndex));
@@ -1894,8 +1989,7 @@ Node* CodeStubAssembler::AllocateJSObjectFromMap(Node* map, Node* properties,
CSA_ASSERT(this, IsMap(map));
Node* size =
IntPtrMul(LoadMapInstanceSize(map), IntPtrConstant(kPointerSize));
- CSA_ASSERT(this, IsRegularHeapObjectSize(size));
- Node* object = Allocate(size, flags);
+ Node* object = AllocateInNewSpace(size, flags);
StoreMapNoWriteBarrier(object, map);
InitializeJSObjectFromMap(object, map, size, properties, elements);
return object;
@@ -1996,7 +2090,8 @@ Node* CodeStubAssembler::AllocateUninitializedJSArray(ElementsKind kind,
Node* length,
Node* allocation_site,
Node* size_in_bytes) {
- Node* array = Allocate(size_in_bytes);
+ // Allocate space for the JSArray and the elements FixedArray in one go.
+ Node* array = AllocateInNewSpace(size_in_bytes);
Comment("write JSArray headers");
StoreMapNoWriteBarrier(array, array_map);
@@ -2147,12 +2242,12 @@ void CodeStubAssembler::CopyFixedArrayElements(
Node* limit_offset = ElementOffsetFromIndex(
IntPtrOrSmiConstant(0, mode), from_kind, mode, first_element_offset);
- Variable var_from_offset(this, MachineType::PointerRepresentation(),
- ElementOffsetFromIndex(element_count, from_kind,
- mode, first_element_offset));
+ VARIABLE(var_from_offset, MachineType::PointerRepresentation(),
+ ElementOffsetFromIndex(element_count, from_kind, mode,
+ first_element_offset));
// This second variable is used only when the element sizes of source and
// destination arrays do not match.
- Variable var_to_offset(this, MachineType::PointerRepresentation());
+ VARIABLE(var_to_offset, MachineType::PointerRepresentation());
if (element_size_matches) {
var_to_offset.Bind(var_from_offset.value());
} else {
@@ -2165,7 +2260,7 @@ void CodeStubAssembler::CopyFixedArrayElements(
Branch(WordEqual(var_from_offset.value(), limit_offset), &done, &decrement);
- Bind(&decrement);
+ BIND(&decrement);
{
Node* from_offset = IntPtrSub(
var_from_offset.value(),
@@ -2210,7 +2305,7 @@ void CodeStubAssembler::CopyFixedArrayElements(
Goto(&next_iter);
if (if_hole == &store_double_hole) {
- Bind(&store_double_hole);
+ BIND(&store_double_hole);
// Don't use doubles to store the hole double, since manipulating the
// signaling NaN used for the hole in C++, e.g. with bit_cast, will
// change its value on ia32 (the x87 stack is used to return values
@@ -2232,12 +2327,12 @@ void CodeStubAssembler::CopyFixedArrayElements(
Goto(&next_iter);
}
- Bind(&next_iter);
+ BIND(&next_iter);
Node* compare = WordNotEqual(from_offset, limit_offset);
Branch(compare, &decrement, &done);
}
- Bind(&done);
+ BIND(&done);
IncrementCounter(isolate()->counters()->inlined_copied_elements(), 1);
Comment("] CopyFixedArrayElements");
}
@@ -2274,8 +2369,7 @@ void CodeStubAssembler::CopyStringCharacters(Node* from_string, Node* to_string,
int from_increment = 1 << ElementsKindToShiftSize(from_kind);
int to_increment = 1 << ElementsKindToShiftSize(to_kind);
- Variable current_to_offset(this, MachineType::PointerRepresentation(),
- to_offset);
+ VARIABLE(current_to_offset, MachineType::PointerRepresentation(), to_offset);
VariableList vars({&current_to_offset}, zone());
int to_index_constant = 0, from_index_constant = 0;
Smi* to_index_smi = nullptr;
@@ -2419,45 +2513,45 @@ void CodeStubAssembler::InitializeAllocationMemento(Node* base_allocation,
Node* CodeStubAssembler::TryTaggedToFloat64(Node* value,
Label* if_valueisnotnumber) {
Label out(this);
- Variable var_result(this, MachineRepresentation::kFloat64);
+ VARIABLE(var_result, MachineRepresentation::kFloat64);
// Check if the {value} is a Smi or a HeapObject.
Label if_valueissmi(this), if_valueisnotsmi(this);
Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi);
- Bind(&if_valueissmi);
+ BIND(&if_valueissmi);
{
// Convert the Smi {value}.
var_result.Bind(SmiToFloat64(value));
Goto(&out);
}
- Bind(&if_valueisnotsmi);
+ BIND(&if_valueisnotsmi);
{
// Check if {value} is a HeapNumber.
Label if_valueisheapnumber(this);
Branch(IsHeapNumberMap(LoadMap(value)), &if_valueisheapnumber,
if_valueisnotnumber);
- Bind(&if_valueisheapnumber);
+ BIND(&if_valueisheapnumber);
{
// Load the floating point value.
var_result.Bind(LoadHeapNumberValue(value));
Goto(&out);
}
}
- Bind(&out);
+ BIND(&out);
return var_result.value();
}
Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) {
// We might need to loop once due to ToNumber conversion.
- Variable var_value(this, MachineRepresentation::kTagged),
- var_result(this, MachineRepresentation::kFloat64);
+ VARIABLE(var_value, MachineRepresentation::kTagged);
+ VARIABLE(var_result, MachineRepresentation::kFloat64);
Label loop(this, &var_value), done_loop(this, &var_result);
var_value.Bind(value);
Goto(&loop);
- Bind(&loop);
+ BIND(&loop);
{
Label if_valueisnotnumber(this, Label::kDeferred);
@@ -2470,7 +2564,7 @@ Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) {
var_result.Bind(result);
Goto(&done_loop);
- Bind(&if_valueisnotnumber);
+ BIND(&if_valueisnotnumber);
{
// Convert the {value} to a Number first.
Callable callable = CodeFactory::NonNumberToNumber(isolate());
@@ -2478,17 +2572,17 @@ Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) {
Goto(&loop);
}
}
- Bind(&done_loop);
+ BIND(&done_loop);
return var_result.value();
}
Node* CodeStubAssembler::TruncateTaggedToWord32(Node* context, Node* value) {
// We might need to loop once due to ToNumber conversion.
- Variable var_value(this, MachineRepresentation::kTagged, value),
- var_result(this, MachineRepresentation::kWord32);
+ VARIABLE(var_value, MachineRepresentation::kTagged, value);
+ VARIABLE(var_result, MachineRepresentation::kWord32);
Label loop(this, &var_value), done_loop(this, &var_result);
Goto(&loop);
- Bind(&loop);
+ BIND(&loop);
{
// Load the current {value}.
value = var_value.value();
@@ -2497,14 +2591,14 @@ Node* CodeStubAssembler::TruncateTaggedToWord32(Node* context, Node* value) {
Label if_valueissmi(this), if_valueisnotsmi(this);
Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi);
- Bind(&if_valueissmi);
+ BIND(&if_valueissmi);
{
// Convert the Smi {value}.
var_result.Bind(SmiToWord32(value));
Goto(&done_loop);
}
- Bind(&if_valueisnotsmi);
+ BIND(&if_valueisnotsmi);
{
// Check if {value} is a HeapNumber.
Label if_valueisheapnumber(this),
@@ -2512,14 +2606,14 @@ Node* CodeStubAssembler::TruncateTaggedToWord32(Node* context, Node* value) {
Branch(IsHeapNumberMap(LoadMap(value)), &if_valueisheapnumber,
&if_valueisnotheapnumber);
- Bind(&if_valueisheapnumber);
+ BIND(&if_valueisheapnumber);
{
// Truncate the floating point value.
var_result.Bind(TruncateHeapNumberValueToWord32(value));
Goto(&done_loop);
}
- Bind(&if_valueisnotheapnumber);
+ BIND(&if_valueisnotheapnumber);
{
// Convert the {value} to a Number first.
Callable callable = CodeFactory::NonNumberToNumber(isolate());
@@ -2528,7 +2622,7 @@ Node* CodeStubAssembler::TruncateTaggedToWord32(Node* context, Node* value) {
}
}
}
- Bind(&done_loop);
+ BIND(&done_loop);
return var_result.value();
}
@@ -2545,17 +2639,17 @@ Node* CodeStubAssembler::ChangeFloat64ToTagged(Node* value) {
Label if_valueisequal(this), if_valueisnotequal(this);
Branch(Float64Equal(value, value64), &if_valueisequal, &if_valueisnotequal);
- Bind(&if_valueisequal);
+ BIND(&if_valueisequal);
{
GotoIfNot(Word32Equal(value32, Int32Constant(0)), &if_valueisint32);
Branch(Int32LessThan(Float64ExtractHighWord32(value), Int32Constant(0)),
&if_valueisheapnumber, &if_valueisint32);
}
- Bind(&if_valueisnotequal);
+ BIND(&if_valueisnotequal);
Goto(&if_valueisheapnumber);
- Variable var_result(this, MachineRepresentation::kTagged);
- Bind(&if_valueisint32);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
+ BIND(&if_valueisint32);
{
if (Is64()) {
Node* result = SmiTag(ChangeInt32ToInt64(value32));
@@ -2566,9 +2660,9 @@ Node* CodeStubAssembler::ChangeFloat64ToTagged(Node* value) {
Node* overflow = Projection(1, pair);
Label if_overflow(this, Label::kDeferred), if_notoverflow(this);
Branch(overflow, &if_overflow, &if_notoverflow);
- Bind(&if_overflow);
+ BIND(&if_overflow);
Goto(&if_valueisheapnumber);
- Bind(&if_notoverflow);
+ BIND(&if_notoverflow);
{
Node* result = BitcastWordToTaggedSigned(Projection(0, pair));
var_result.Bind(result);
@@ -2576,13 +2670,13 @@ Node* CodeStubAssembler::ChangeFloat64ToTagged(Node* value) {
}
}
}
- Bind(&if_valueisheapnumber);
+ BIND(&if_valueisheapnumber);
{
Node* result = AllocateHeapNumberWithValue(value);
var_result.Bind(result);
Goto(&if_join);
}
- Bind(&if_join);
+ BIND(&if_join);
return var_result.value();
}
@@ -2590,38 +2684,38 @@ Node* CodeStubAssembler::ChangeInt32ToTagged(Node* value) {
if (Is64()) {
return SmiTag(ChangeInt32ToInt64(value));
}
- Variable var_result(this, MachineRepresentation::kTagged);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
Node* pair = Int32AddWithOverflow(value, value);
Node* overflow = Projection(1, pair);
Label if_overflow(this, Label::kDeferred), if_notoverflow(this),
if_join(this);
Branch(overflow, &if_overflow, &if_notoverflow);
- Bind(&if_overflow);
+ BIND(&if_overflow);
{
Node* value64 = ChangeInt32ToFloat64(value);
Node* result = AllocateHeapNumberWithValue(value64);
var_result.Bind(result);
}
Goto(&if_join);
- Bind(&if_notoverflow);
+ BIND(&if_notoverflow);
{
Node* result = BitcastWordToTaggedSigned(Projection(0, pair));
var_result.Bind(result);
}
Goto(&if_join);
- Bind(&if_join);
+ BIND(&if_join);
return var_result.value();
}
Node* CodeStubAssembler::ChangeUint32ToTagged(Node* value) {
Label if_overflow(this, Label::kDeferred), if_not_overflow(this),
if_join(this);
- Variable var_result(this, MachineRepresentation::kTagged);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
// If {value} > 2^31 - 1, we need to store it in a HeapNumber.
Branch(Uint32LessThan(Int32Constant(Smi::kMaxValue), value), &if_overflow,
&if_not_overflow);
- Bind(&if_not_overflow);
+ BIND(&if_not_overflow);
{
if (Is64()) {
var_result.Bind(SmiTag(ChangeUint32ToUint64(value)));
@@ -2638,26 +2732,26 @@ Node* CodeStubAssembler::ChangeUint32ToTagged(Node* value) {
}
Goto(&if_join);
- Bind(&if_overflow);
+ BIND(&if_overflow);
{
Node* float64_value = ChangeUint32ToFloat64(value);
var_result.Bind(AllocateHeapNumberWithValue(float64_value));
}
Goto(&if_join);
- Bind(&if_join);
+ BIND(&if_join);
return var_result.value();
}
Node* CodeStubAssembler::ToThisString(Node* context, Node* value,
char const* method_name) {
- Variable var_value(this, MachineRepresentation::kTagged, value);
+ VARIABLE(var_value, MachineRepresentation::kTagged, value);
// Check if the {value} is a Smi or a HeapObject.
Label if_valueissmi(this, Label::kDeferred), if_valueisnotsmi(this),
if_valueisstring(this);
Branch(TaggedIsSmi(value), &if_valueissmi, &if_valueisnotsmi);
- Bind(&if_valueisnotsmi);
+ BIND(&if_valueisnotsmi);
{
// Load the instance type of the {value}.
Node* value_instance_type = LoadInstanceType(value);
@@ -2666,7 +2760,7 @@ Node* CodeStubAssembler::ToThisString(Node* context, Node* value,
Label if_valueisnotstring(this, Label::kDeferred);
Branch(IsStringInstanceType(value_instance_type), &if_valueisstring,
&if_valueisnotstring);
- Bind(&if_valueisnotstring);
+ BIND(&if_valueisnotstring);
{
// Check if the {value} is null.
Label if_valueisnullorundefined(this, Label::kDeferred),
@@ -2674,12 +2768,12 @@ Node* CodeStubAssembler::ToThisString(Node* context, Node* value,
if_valueisnotnull(this, Label::kDeferred);
Branch(WordEqual(value, NullConstant()), &if_valueisnullorundefined,
&if_valueisnotnull);
- Bind(&if_valueisnotnull);
+ BIND(&if_valueisnotnull);
{
// Check if the {value} is undefined.
Branch(WordEqual(value, UndefinedConstant()),
&if_valueisnullorundefined, &if_valueisnotnullorundefined);
- Bind(&if_valueisnotnullorundefined);
+ BIND(&if_valueisnotnullorundefined);
{
// Convert the {value} to a String.
Callable callable = CodeFactory::ToString(isolate());
@@ -2688,7 +2782,7 @@ Node* CodeStubAssembler::ToThisString(Node* context, Node* value,
}
}
- Bind(&if_valueisnullorundefined);
+ BIND(&if_valueisnullorundefined);
{
// The {value} is either null or undefined.
CallRuntime(Runtime::kThrowCalledOnNullOrUndefined, context,
@@ -2698,19 +2792,19 @@ Node* CodeStubAssembler::ToThisString(Node* context, Node* value,
}
}
}
- Bind(&if_valueissmi);
+ BIND(&if_valueissmi);
{
// The {value} is a Smi, convert it to a String.
Callable callable = CodeFactory::NumberToString(isolate());
var_value.Bind(CallStub(callable, context, value));
Goto(&if_valueisstring);
}
- Bind(&if_valueisstring);
+ BIND(&if_valueisstring);
return var_value.value();
}
-Node* CodeStubAssembler::ChangeNumberToFloat64(compiler::Node* value) {
- Variable result(this, MachineRepresentation::kFloat64);
+Node* CodeStubAssembler::ChangeNumberToFloat64(Node* value) {
+ VARIABLE(result, MachineRepresentation::kFloat64);
Label smi(this);
Label done(this, &result);
GotoIf(TaggedIsSmi(value), &smi);
@@ -2718,13 +2812,30 @@ Node* CodeStubAssembler::ChangeNumberToFloat64(compiler::Node* value) {
LoadObjectField(value, HeapNumber::kValueOffset, MachineType::Float64()));
Goto(&done);
- Bind(&smi);
+ BIND(&smi);
{
result.Bind(SmiToFloat64(value));
Goto(&done);
}
- Bind(&done);
+ BIND(&done);
+ return result.value();
+}
+
+Node* CodeStubAssembler::ChangeNumberToIntPtr(Node* value) {
+ VARIABLE(result, MachineType::PointerRepresentation());
+ Label smi(this), done(this, &result);
+ GotoIf(TaggedIsSmi(value), &smi);
+
+ CSA_ASSERT(this, IsHeapNumber(value));
+ result.Bind(ChangeFloat64ToUintPtr(LoadHeapNumberValue(value)));
+ Goto(&done);
+
+ BIND(&smi);
+ result.Bind(SmiToWord(value));
+ Goto(&done);
+
+ BIND(&done);
return result.value();
}
@@ -2732,11 +2843,11 @@ Node* CodeStubAssembler::ToThisValue(Node* context, Node* value,
PrimitiveType primitive_type,
char const* method_name) {
// We might need to loop once due to JSValue unboxing.
- Variable var_value(this, MachineRepresentation::kTagged, value);
+ VARIABLE(var_value, MachineRepresentation::kTagged, value);
Label loop(this, &var_value), done_loop(this),
done_throw(this, Label::kDeferred);
Goto(&loop);
- Bind(&loop);
+ BIND(&loop);
{
// Load the current {value}.
value = var_value.value();
@@ -2757,14 +2868,14 @@ Node* CodeStubAssembler::ToThisValue(Node* context, Node* value,
Branch(Word32Equal(value_instance_type, Int32Constant(JS_VALUE_TYPE)),
&if_valueisvalue, &if_valueisnotvalue);
- Bind(&if_valueisvalue);
+ BIND(&if_valueisvalue);
{
// Load the actual value from the {value}.
var_value.Bind(LoadObjectField(value, JSValue::kValueOffset));
Goto(&loop);
}
- Bind(&if_valueisnotvalue);
+ BIND(&if_valueisnotvalue);
{
switch (primitive_type) {
case PrimitiveType::kBoolean:
@@ -2787,7 +2898,7 @@ Node* CodeStubAssembler::ToThisValue(Node* context, Node* value,
}
}
- Bind(&done_throw);
+ BIND(&done_throw);
{
// The {value} is not a compatible receiver for this method.
CallRuntime(Runtime::kThrowNotGeneric, context,
@@ -2796,7 +2907,7 @@ Node* CodeStubAssembler::ToThisValue(Node* context, Node* value,
Unreachable();
}
- Bind(&done_loop);
+ BIND(&done_loop);
return var_value.value();
}
@@ -2804,7 +2915,7 @@ Node* CodeStubAssembler::ThrowIfNotInstanceType(Node* context, Node* value,
InstanceType instance_type,
char const* method_name) {
Label out(this), throw_exception(this, Label::kDeferred);
- Variable var_value_map(this, MachineRepresentation::kTagged);
+ VARIABLE(var_value_map, MachineRepresentation::kTagged);
GotoIf(TaggedIsSmi(value), &throw_exception);
@@ -2816,14 +2927,14 @@ Node* CodeStubAssembler::ThrowIfNotInstanceType(Node* context, Node* value,
&throw_exception);
// The {value} is not a compatible receiver for this method.
- Bind(&throw_exception);
+ BIND(&throw_exception);
CallRuntime(
Runtime::kThrowIncompatibleMethodReceiver, context,
HeapConstant(factory()->NewStringFromAsciiChecked(method_name, TENURED)),
value);
Unreachable();
- Bind(&out);
+ BIND(&out);
return var_value_map.value();
}
@@ -2857,6 +2968,11 @@ Node* CodeStubAssembler::IsCallableMap(Node* map) {
Int32Constant(0));
}
+Node* CodeStubAssembler::IsDeprecatedMap(Node* map) {
+ CSA_ASSERT(this, IsMap(map));
+ return IsSetWord32<Map::Deprecated>(LoadMapBitField3(map));
+}
+
Node* CodeStubAssembler::IsCallable(Node* object) {
return IsCallableMap(LoadMap(object));
}
@@ -2879,6 +2995,36 @@ Node* CodeStubAssembler::IsStringInstanceType(Node* instance_type) {
return Int32LessThan(instance_type, Int32Constant(FIRST_NONSTRING_TYPE));
}
+Node* CodeStubAssembler::IsOneByteStringInstanceType(Node* instance_type) {
+ CSA_ASSERT(this, IsStringInstanceType(instance_type));
+ return Word32Equal(
+ Word32And(instance_type, Int32Constant(kStringEncodingMask)),
+ Int32Constant(kOneByteStringTag));
+}
+
+Node* CodeStubAssembler::IsSequentialStringInstanceType(Node* instance_type) {
+ CSA_ASSERT(this, IsStringInstanceType(instance_type));
+ return Word32Equal(
+ Word32And(instance_type, Int32Constant(kStringRepresentationMask)),
+ Int32Constant(kSeqStringTag));
+}
+
+Node* CodeStubAssembler::IsExternalStringInstanceType(Node* instance_type) {
+ CSA_ASSERT(this, IsStringInstanceType(instance_type));
+ return Word32Equal(
+ Word32And(instance_type, Int32Constant(kStringRepresentationMask)),
+ Int32Constant(kExternalStringTag));
+}
+
+Node* CodeStubAssembler::IsShortExternalStringInstanceType(
+ Node* instance_type) {
+ CSA_ASSERT(this, IsStringInstanceType(instance_type));
+ STATIC_ASSERT(kShortExternalStringTag != 0);
+ return Word32NotEqual(
+ Word32And(instance_type, Int32Constant(kShortExternalStringMask)),
+ Int32Constant(0));
+}
+
Node* CodeStubAssembler::IsJSReceiverInstanceType(Node* instance_type) {
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
return Int32GreaterThanOrEqual(instance_type,
@@ -2919,13 +3065,21 @@ Node* CodeStubAssembler::IsJSArray(Node* object) {
}
Node* CodeStubAssembler::IsWeakCell(Node* object) {
- return HasInstanceType(object, WEAK_CELL_TYPE);
+ return IsWeakCellMap(LoadMap(object));
}
Node* CodeStubAssembler::IsBoolean(Node* object) {
return IsBooleanMap(LoadMap(object));
}
+Node* CodeStubAssembler::IsPropertyCell(Node* object) {
+ return IsPropertyCellMap(LoadMap(object));
+}
+
+Node* CodeStubAssembler::IsAccessorPair(Node* object) {
+ return IsAccessorPairMap(LoadMap(object));
+}
+
Node* CodeStubAssembler::IsHeapNumber(Node* object) {
return IsHeapNumberMap(LoadMap(object));
}
@@ -2936,8 +3090,8 @@ Node* CodeStubAssembler::IsName(Node* object) {
}
Node* CodeStubAssembler::IsString(Node* object) {
- return Int32LessThanOrEqual(LoadInstanceType(object),
- Int32Constant(FIRST_NONSTRING_TYPE));
+ return Int32LessThan(LoadInstanceType(object),
+ Int32Constant(FIRST_NONSTRING_TYPE));
}
Node* CodeStubAssembler::IsSymbol(Node* object) {
@@ -2981,203 +3135,121 @@ Node* CodeStubAssembler::IsJSFunction(Node* object) {
return HasInstanceType(object, JS_FUNCTION_TYPE);
}
+Node* CodeStubAssembler::IsJSTypedArray(Node* object) {
+ return HasInstanceType(object, JS_TYPED_ARRAY_TYPE);
+}
+
+Node* CodeStubAssembler::IsFixedTypedArray(Node* object) {
+ Node* instance_type = LoadInstanceType(object);
+ return Word32And(
+ Int32GreaterThanOrEqual(instance_type,
+ Int32Constant(FIRST_FIXED_TYPED_ARRAY_TYPE)),
+ Int32LessThanOrEqual(instance_type,
+ Int32Constant(LAST_FIXED_TYPED_ARRAY_TYPE)));
+}
+
+Node* CodeStubAssembler::IsJSRegExp(Node* object) {
+ return HasInstanceType(object, JS_REGEXP_TYPE);
+}
+
+Node* CodeStubAssembler::IsNumber(Node* object) {
+ return Select(TaggedIsSmi(object), [=] { return Int32Constant(1); },
+ [=] { return IsHeapNumber(object); },
+ MachineRepresentation::kWord32);
+}
+
+Node* CodeStubAssembler::IsNumberNormalized(Node* number) {
+ CSA_ASSERT(this, IsNumber(number));
+
+ VARIABLE(var_result, MachineRepresentation::kWord32, Int32Constant(1));
+ Label out(this);
+
+ GotoIf(TaggedIsSmi(number), &out);
+
+ Node* const value = LoadHeapNumberValue(number);
+ Node* const smi_min = Float64Constant(static_cast<double>(Smi::kMinValue));
+ Node* const smi_max = Float64Constant(static_cast<double>(Smi::kMaxValue));
+
+ GotoIf(Float64LessThan(value, smi_min), &out);
+ GotoIf(Float64GreaterThan(value, smi_max), &out);
+ GotoIfNot(Float64Equal(value, value), &out); // NaN.
+
+ var_result.Bind(Int32Constant(0));
+ Goto(&out);
+
+ BIND(&out);
+ return var_result.value();
+}
+
Node* CodeStubAssembler::StringCharCodeAt(Node* string, Node* index,
ParameterMode parameter_mode) {
+ if (parameter_mode == SMI_PARAMETERS) CSA_ASSERT(this, TaggedIsSmi(index));
CSA_ASSERT(this, IsString(string));
- // Translate the {index} into a Word.
- index = ParameterToWord(index, parameter_mode);
-
- // We may need to loop in case of cons, thin, or sliced strings.
- Variable var_index(this, MachineType::PointerRepresentation(), index);
- Variable var_string(this, MachineRepresentation::kTagged, string);
- Variable var_result(this, MachineRepresentation::kWord32);
- Variable* loop_vars[] = {&var_index, &var_string};
- Label done_loop(this, &var_result), loop(this, 2, loop_vars);
- Goto(&loop);
- Bind(&loop);
- {
- // Load the current {index}.
- index = var_index.value();
-
- // Load the current {string}.
- string = var_string.value();
- // Load the instance type of the {string}.
- Node* string_instance_type = LoadInstanceType(string);
+ // Translate the {index} into a Word.
+ Node* const int_index = ParameterToWord(index, parameter_mode);
+ CSA_ASSERT(this, IntPtrGreaterThanOrEqual(int_index, IntPtrConstant(0)));
- // Check if the {string} is a SeqString.
- Label if_stringissequential(this), if_stringisnotsequential(this);
- Branch(Word32Equal(Word32And(string_instance_type,
- Int32Constant(kStringRepresentationMask)),
- Int32Constant(kSeqStringTag)),
- &if_stringissequential, &if_stringisnotsequential);
+ VARIABLE(var_result, MachineRepresentation::kWord32);
- Bind(&if_stringissequential);
- {
- // Check if the {string} is a TwoByteSeqString or a OneByteSeqString.
- Label if_stringistwobyte(this), if_stringisonebyte(this);
- Branch(Word32Equal(Word32And(string_instance_type,
- Int32Constant(kStringEncodingMask)),
- Int32Constant(kTwoByteStringTag)),
- &if_stringistwobyte, &if_stringisonebyte);
-
- Bind(&if_stringisonebyte);
- {
- var_result.Bind(
- Load(MachineType::Uint8(), string,
- IntPtrAdd(index, IntPtrConstant(SeqOneByteString::kHeaderSize -
- kHeapObjectTag))));
- Goto(&done_loop);
- }
+ Label out(this, &var_result), runtime_generic(this), runtime_external(this);
- Bind(&if_stringistwobyte);
- {
- var_result.Bind(
- Load(MachineType::Uint16(), string,
- IntPtrAdd(WordShl(index, IntPtrConstant(1)),
- IntPtrConstant(SeqTwoByteString::kHeaderSize -
- kHeapObjectTag))));
- Goto(&done_loop);
- }
- }
+ ToDirectStringAssembler to_direct(state(), string);
+ Node* const direct_string = to_direct.TryToDirect(&runtime_generic);
+ Node* const offset = IntPtrAdd(int_index, to_direct.offset());
+ Node* const instance_type = to_direct.instance_type();
- Bind(&if_stringisnotsequential);
- {
- // Check if the {string} is a ConsString.
- Label if_stringiscons(this), if_stringisnotcons(this);
- Branch(Word32Equal(Word32And(string_instance_type,
- Int32Constant(kStringRepresentationMask)),
- Int32Constant(kConsStringTag)),
- &if_stringiscons, &if_stringisnotcons);
-
- Bind(&if_stringiscons);
- {
- // Check whether the right hand side is the empty string (i.e. if
- // this is really a flat string in a cons string). If that is not
- // the case we flatten the string first.
- Label if_rhsisempty(this), if_rhsisnotempty(this, Label::kDeferred);
- Node* rhs = LoadObjectField(string, ConsString::kSecondOffset);
- Branch(WordEqual(rhs, EmptyStringConstant()), &if_rhsisempty,
- &if_rhsisnotempty);
-
- Bind(&if_rhsisempty);
- {
- // Just operate on the left hand side of the {string}.
- var_string.Bind(LoadObjectField(string, ConsString::kFirstOffset));
- Goto(&loop);
- }
+ Node* const string_data = to_direct.PointerToData(&runtime_external);
- Bind(&if_rhsisnotempty);
- {
- // Flatten the {string} and lookup in the resulting string.
- var_string.Bind(CallRuntime(Runtime::kFlattenString,
- NoContextConstant(), string));
- Goto(&loop);
- }
- }
+ // Check if the {string} is a TwoByteSeqString or a OneByteSeqString.
+ Label if_stringistwobyte(this), if_stringisonebyte(this);
+ Branch(IsOneByteStringInstanceType(instance_type), &if_stringisonebyte,
+ &if_stringistwobyte);
- Bind(&if_stringisnotcons);
- {
- // Check if the {string} is an ExternalString.
- Label if_stringisexternal(this), if_stringisnotexternal(this);
- Branch(Word32Equal(Word32And(string_instance_type,
- Int32Constant(kStringRepresentationMask)),
- Int32Constant(kExternalStringTag)),
- &if_stringisexternal, &if_stringisnotexternal);
-
- Bind(&if_stringisexternal);
- {
- // Check if the {string} is a short external string.
- Label if_stringisnotshort(this),
- if_stringisshort(this, Label::kDeferred);
- Branch(Word32Equal(Word32And(string_instance_type,
- Int32Constant(kShortExternalStringMask)),
- Int32Constant(0)),
- &if_stringisnotshort, &if_stringisshort);
-
- Bind(&if_stringisnotshort);
- {
- // Load the actual resource data from the {string}.
- Node* string_resource_data =
- LoadObjectField(string, ExternalString::kResourceDataOffset,
- MachineType::Pointer());
-
- // Check if the {string} is a TwoByteExternalString or a
- // OneByteExternalString.
- Label if_stringistwobyte(this), if_stringisonebyte(this);
- Branch(Word32Equal(Word32And(string_instance_type,
- Int32Constant(kStringEncodingMask)),
- Int32Constant(kTwoByteStringTag)),
- &if_stringistwobyte, &if_stringisonebyte);
-
- Bind(&if_stringisonebyte);
- {
- var_result.Bind(
- Load(MachineType::Uint8(), string_resource_data, index));
- Goto(&done_loop);
- }
+ BIND(&if_stringisonebyte);
+ {
+ var_result.Bind(Load(MachineType::Uint8(), string_data, offset));
+ Goto(&out);
+ }
- Bind(&if_stringistwobyte);
- {
- var_result.Bind(Load(MachineType::Uint16(), string_resource_data,
- WordShl(index, IntPtrConstant(1))));
- Goto(&done_loop);
- }
- }
+ BIND(&if_stringistwobyte);
+ {
+ var_result.Bind(Load(MachineType::Uint16(), string_data,
+ WordShl(offset, IntPtrConstant(1))));
+ Goto(&out);
+ }
- Bind(&if_stringisshort);
- {
- // The {string} might be compressed, call the runtime.
- var_result.Bind(SmiToWord32(
- CallRuntime(Runtime::kExternalStringGetChar,
- NoContextConstant(), string, SmiTag(index))));
- Goto(&done_loop);
- }
- }
+ BIND(&runtime_generic);
+ {
+ Node* const smi_index = ParameterToTagged(index, parameter_mode);
+ Node* const result = CallRuntime(Runtime::kStringCharCodeAtRT,
+ NoContextConstant(), string, smi_index);
+ var_result.Bind(SmiToWord32(result));
+ Goto(&out);
+ }
- Bind(&if_stringisnotexternal);
- {
- Label if_stringissliced(this), if_stringisthin(this);
- Branch(
- Word32Equal(Word32And(string_instance_type,
- Int32Constant(kStringRepresentationMask)),
- Int32Constant(kSlicedStringTag)),
- &if_stringissliced, &if_stringisthin);
- Bind(&if_stringissliced);
- {
- // The {string} is a SlicedString, continue with its parent.
- Node* string_offset =
- LoadAndUntagObjectField(string, SlicedString::kOffsetOffset);
- Node* string_parent =
- LoadObjectField(string, SlicedString::kParentOffset);
- var_index.Bind(IntPtrAdd(index, string_offset));
- var_string.Bind(string_parent);
- Goto(&loop);
- }
- Bind(&if_stringisthin);
- {
- // The {string} is a ThinString, continue with its actual value.
- var_string.Bind(LoadObjectField(string, ThinString::kActualOffset));
- Goto(&loop);
- }
- }
- }
- }
+ BIND(&runtime_external);
+ {
+ Node* const result =
+ CallRuntime(Runtime::kExternalStringGetChar, NoContextConstant(),
+ direct_string, SmiTag(offset));
+ var_result.Bind(SmiToWord32(result));
+ Goto(&out);
}
- Bind(&done_loop);
+ BIND(&out);
return var_result.value();
}
Node* CodeStubAssembler::StringFromCharCode(Node* code) {
- Variable var_result(this, MachineRepresentation::kTagged);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
// Check if the {code} is a one-byte char code.
Label if_codeisonebyte(this), if_codeistwobyte(this, Label::kDeferred),
if_done(this);
Branch(Int32LessThanOrEqual(code, Int32Constant(String::kMaxOneByteCharCode)),
&if_codeisonebyte, &if_codeistwobyte);
- Bind(&if_codeisonebyte);
+ BIND(&if_codeisonebyte);
{
// Load the isolate wide single character string cache.
Node* cache = LoadRoot(Heap::kSingleCharacterStringCacheRootIndex);
@@ -3191,7 +3263,7 @@ Node* CodeStubAssembler::StringFromCharCode(Node* code) {
Branch(WordEqual(entry, UndefinedConstant()), &if_entryisundefined,
&if_entryisnotundefined);
- Bind(&if_entryisundefined);
+ BIND(&if_entryisundefined);
{
// Allocate a new SeqOneByteString for {code} and store it in the {cache}.
Node* result = AllocateSeqOneByteString(1);
@@ -3203,7 +3275,7 @@ Node* CodeStubAssembler::StringFromCharCode(Node* code) {
Goto(&if_done);
}
- Bind(&if_entryisnotundefined);
+ BIND(&if_entryisnotundefined);
{
// Return the entry from the {cache}.
var_result.Bind(entry);
@@ -3211,7 +3283,7 @@ Node* CodeStubAssembler::StringFromCharCode(Node* code) {
}
}
- Bind(&if_codeistwobyte);
+ BIND(&if_codeistwobyte);
{
// Allocate a new SeqTwoByteString for {code}.
Node* result = AllocateSeqTwoByteString(1);
@@ -3222,7 +3294,7 @@ Node* CodeStubAssembler::StringFromCharCode(Node* code) {
Goto(&if_done);
}
- Bind(&if_done);
+ BIND(&if_done);
return var_result.value();
}
@@ -3240,18 +3312,16 @@ Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context,
typedef CodeStubAssembler::Label Label;
typedef CodeStubAssembler::Variable Variable;
- Label end(a), two_byte_sequential(a);
+ Label end(a), one_byte_sequential(a), two_byte_sequential(a);
Variable var_result(a, MachineRepresentation::kTagged);
Node* const smi_zero = a->SmiConstant(Smi::kZero);
- STATIC_ASSERT((kOneByteStringTag & kStringEncodingMask) != 0);
- a->GotoIf(a->Word32Equal(a->Word32And(from_instance_type,
- a->Int32Constant(kStringEncodingMask)),
- a->Int32Constant(0)),
- &two_byte_sequential);
+ a->Branch(a->IsOneByteStringInstanceType(from_instance_type),
+ &one_byte_sequential, &two_byte_sequential);
// The subject string is a sequential one-byte string.
+ a->BIND(&one_byte_sequential);
{
Node* result =
a->AllocateSeqOneByteString(context, a->SmiToWord(character_count));
@@ -3265,7 +3335,7 @@ Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context,
}
// The subject string is a sequential two-byte string.
- a->Bind(&two_byte_sequential);
+ a->BIND(&two_byte_sequential);
{
Node* result =
a->AllocateSeqTwoByteString(context, a->SmiToWord(character_count));
@@ -3278,7 +3348,7 @@ Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context,
a->Goto(&end);
}
- a->Bind(&end);
+ a->BIND(&end);
return var_result.value();
}
@@ -3286,27 +3356,14 @@ Node* AllocAndCopyStringCharacters(CodeStubAssembler* a, Node* context,
Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from,
Node* to) {
- Label end(this);
- Label runtime(this);
-
- Node* const int_zero = Int32Constant(0);
-
- // Int32 variables.
- Variable var_instance_type(this, MachineRepresentation::kWord32, int_zero);
- Variable var_representation(this, MachineRepresentation::kWord32, int_zero);
-
- Variable var_from(this, MachineRepresentation::kTagged, from); // Smi.
- Variable var_string(this, MachineRepresentation::kTagged, string); // String.
- Variable var_result(this, MachineRepresentation::kTagged); // String.
+ VARIABLE(var_result, MachineRepresentation::kTagged);
+ ToDirectStringAssembler to_direct(state(), string);
+ Label end(this), runtime(this);
// Make sure first argument is a string.
CSA_ASSERT(this, TaggedIsNotSmi(string));
CSA_ASSERT(this, IsString(string));
- // Load the instance type of the {string}.
- Node* const instance_type = LoadInstanceType(string);
- var_instance_type.Bind(instance_type);
-
// Make sure that both from and to are non-negative smis.
GotoIfNot(TaggedIsPositiveSmi(from), &runtime);
@@ -3329,132 +3386,56 @@ Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from,
// TODO(jgruber): Add an additional case for substring of length == 0?
// Deal with different string types: update the index if necessary
- // and put the underlying string into var_string.
-
- // If the string is not indirect, it can only be sequential or external.
- STATIC_ASSERT(kIsIndirectStringMask ==
- (kSlicedStringTag & kConsStringTag & kThinStringTag));
- STATIC_ASSERT(kIsIndirectStringMask != 0);
- Label underlying_unpacked(this);
- GotoIf(Word32Equal(
- Word32And(instance_type, Int32Constant(kIsIndirectStringMask)),
- Int32Constant(0)),
- &underlying_unpacked);
-
- // The subject string is a sliced, cons, or thin string.
-
- Label thin_string(this), thin_or_sliced(this);
- var_representation.Bind(
- Word32And(instance_type, Int32Constant(kStringRepresentationMask)));
- GotoIf(
- Word32NotEqual(var_representation.value(), Int32Constant(kConsStringTag)),
- &thin_or_sliced);
-
- // Cons string. Check whether it is flat, then fetch first part.
- // Flat cons strings have an empty second part.
- {
- GotoIf(WordNotEqual(LoadObjectField(string, ConsString::kSecondOffset),
- EmptyStringConstant()),
- &runtime);
-
- Node* first_string_part = LoadObjectField(string, ConsString::kFirstOffset);
- var_string.Bind(first_string_part);
- var_instance_type.Bind(LoadInstanceType(first_string_part));
- var_representation.Bind(Word32And(
- var_instance_type.value(), Int32Constant(kStringRepresentationMask)));
-
- // The loaded first part might be a thin string.
- Branch(Word32Equal(Word32And(var_instance_type.value(),
- Int32Constant(kIsIndirectStringMask)),
- Int32Constant(0)),
- &underlying_unpacked, &thin_string);
- }
-
- Bind(&thin_or_sliced);
- {
- GotoIf(
- Word32Equal(var_representation.value(), Int32Constant(kThinStringTag)),
- &thin_string);
- // Otherwise it's a sliced string.
- // Fetch parent and correct start index by offset.
- Node* sliced_offset =
- LoadObjectField(var_string.value(), SlicedString::kOffsetOffset);
- var_from.Bind(SmiAdd(from, sliced_offset));
+ // and extract the underlying string.
- Node* slice_parent = LoadObjectField(string, SlicedString::kParentOffset);
- var_string.Bind(slice_parent);
-
- Node* slice_parent_instance_type = LoadInstanceType(slice_parent);
- var_instance_type.Bind(slice_parent_instance_type);
-
- // The loaded parent might be a thin string.
- Branch(Word32Equal(Word32And(var_instance_type.value(),
- Int32Constant(kIsIndirectStringMask)),
- Int32Constant(0)),
- &underlying_unpacked, &thin_string);
- }
-
- Bind(&thin_string);
- {
- Node* actual_string =
- LoadObjectField(var_string.value(), ThinString::kActualOffset);
- var_string.Bind(actual_string);
- var_instance_type.Bind(LoadInstanceType(actual_string));
- Goto(&underlying_unpacked);
- }
+ Node* const direct_string = to_direct.TryToDirect(&runtime);
+ Node* const offset = SmiAdd(from, SmiTag(to_direct.offset()));
+ Node* const instance_type = to_direct.instance_type();
// The subject string can only be external or sequential string of either
// encoding at this point.
Label external_string(this);
- Bind(&underlying_unpacked);
{
if (FLAG_string_slices) {
- Label copy_routine(this);
+ Label next(this);
// Short slice. Copy instead of slicing.
GotoIf(SmiLessThan(substr_length,
SmiConstant(Smi::FromInt(SlicedString::kMinLength))),
- &copy_routine);
+ &next);
// Allocate new sliced string.
- Label two_byte_slice(this);
- STATIC_ASSERT((kStringEncodingMask & kOneByteStringTag) != 0);
- STATIC_ASSERT((kStringEncodingMask & kTwoByteStringTag) == 0);
-
Counters* counters = isolate()->counters();
IncrementCounter(counters->sub_string_native(), 1);
- GotoIf(Word32Equal(Word32And(var_instance_type.value(),
- Int32Constant(kStringEncodingMask)),
- Int32Constant(0)),
- &two_byte_slice);
-
- var_result.Bind(AllocateSlicedOneByteString(
- substr_length, var_string.value(), var_from.value()));
- Goto(&end);
+ Label one_byte_slice(this), two_byte_slice(this);
+ Branch(IsOneByteStringInstanceType(to_direct.instance_type()),
+ &one_byte_slice, &two_byte_slice);
- Bind(&two_byte_slice);
+ BIND(&one_byte_slice);
+ {
+ var_result.Bind(
+ AllocateSlicedOneByteString(substr_length, direct_string, offset));
+ Goto(&end);
+ }
- var_result.Bind(AllocateSlicedTwoByteString(
- substr_length, var_string.value(), var_from.value()));
- Goto(&end);
+ BIND(&two_byte_slice);
+ {
+ var_result.Bind(
+ AllocateSlicedTwoByteString(substr_length, direct_string, offset));
+ Goto(&end);
+ }
- Bind(&copy_routine);
+ BIND(&next);
}
// The subject string can only be external or sequential string of either
// encoding at this point.
- STATIC_ASSERT(kExternalStringTag != 0);
- STATIC_ASSERT(kSeqStringTag == 0);
- GotoIfNot(Word32Equal(Word32And(var_instance_type.value(),
- Int32Constant(kExternalStringTag)),
- Int32Constant(0)),
- &external_string);
+ GotoIf(to_direct.is_external(), &external_string);
var_result.Bind(AllocAndCopyStringCharacters(
- this, context, var_string.value(), var_instance_type.value(),
- var_from.value(), substr_length));
+ this, context, direct_string, instance_type, offset, substr_length));
Counters* counters = isolate()->counters();
IncrementCounter(counters->sub_string_native(), 1);
@@ -3463,14 +3444,13 @@ Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from,
}
// Handle external string.
- Bind(&external_string);
+ BIND(&external_string);
{
- Node* const fake_sequential_string = TryDerefExternalString(
- var_string.value(), var_instance_type.value(), &runtime);
+ Node* const fake_sequential_string = to_direct.PointerToString(&runtime);
- var_result.Bind(AllocAndCopyStringCharacters(
- this, context, fake_sequential_string, var_instance_type.value(),
- var_from.value(), substr_length));
+ var_result.Bind(
+ AllocAndCopyStringCharacters(this, context, fake_sequential_string,
+ instance_type, offset, substr_length));
Counters* counters = isolate()->counters();
IncrementCounter(counters->sub_string_native(), 1);
@@ -3479,14 +3459,14 @@ Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from,
}
// Substrings of length 1 are generated through CharCodeAt and FromCharCode.
- Bind(&single_char);
+ BIND(&single_char);
{
- Node* char_code = StringCharCodeAt(var_string.value(), var_from.value());
+ Node* char_code = StringCharCodeAt(string, from);
var_result.Bind(StringFromCharCode(char_code));
Goto(&end);
}
- Bind(&original_string_or_invalid_length);
+ BIND(&original_string_or_invalid_length);
{
// Longer than original string's length or negative: unsafe arguments.
GotoIf(SmiAbove(substr_length, string_length), &runtime);
@@ -3504,46 +3484,163 @@ Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from,
}
// Fall back to a runtime call.
- Bind(&runtime);
+ BIND(&runtime);
{
var_result.Bind(
CallRuntime(Runtime::kSubString, context, string, from, to));
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
return var_result.value();
}
-namespace {
+ToDirectStringAssembler::ToDirectStringAssembler(
+ compiler::CodeAssemblerState* state, Node* string)
+ : CodeStubAssembler(state),
+ var_string_(this, MachineRepresentation::kTagged, string),
+ var_instance_type_(this, MachineRepresentation::kWord32),
+ var_offset_(this, MachineType::PointerRepresentation()),
+ var_is_external_(this, MachineRepresentation::kWord32) {
+ CSA_ASSERT(this, TaggedIsNotSmi(string));
+ CSA_ASSERT(this, IsString(string));
-Node* IsExternalStringInstanceType(CodeStubAssembler* a,
- Node* const instance_type) {
- CSA_ASSERT(a, a->IsStringInstanceType(instance_type));
- return a->Word32Equal(
- a->Word32And(instance_type, a->Int32Constant(kStringRepresentationMask)),
- a->Int32Constant(kExternalStringTag));
+ var_string_.Bind(string);
+ var_offset_.Bind(IntPtrConstant(0));
+ var_instance_type_.Bind(LoadInstanceType(string));
+ var_is_external_.Bind(Int32Constant(0));
}
-Node* IsShortExternalStringInstanceType(CodeStubAssembler* a,
- Node* const instance_type) {
- CSA_ASSERT(a, a->IsStringInstanceType(instance_type));
- STATIC_ASSERT(kShortExternalStringTag != 0);
- return a->Word32NotEqual(
- a->Word32And(instance_type, a->Int32Constant(kShortExternalStringMask)),
- a->Int32Constant(0));
+Node* ToDirectStringAssembler::TryToDirect(Label* if_bailout) {
+ VariableList vars({&var_string_, &var_offset_, &var_instance_type_}, zone());
+ Label dispatch(this, vars);
+ Label if_iscons(this);
+ Label if_isexternal(this);
+ Label if_issliced(this);
+ Label if_isthin(this);
+ Label out(this);
+
+ Branch(IsSequentialStringInstanceType(var_instance_type_.value()), &out,
+ &dispatch);
+
+ // Dispatch based on string representation.
+ BIND(&dispatch);
+ {
+ int32_t values[] = {
+ kSeqStringTag, kConsStringTag, kExternalStringTag,
+ kSlicedStringTag, kThinStringTag,
+ };
+ Label* labels[] = {
+ &out, &if_iscons, &if_isexternal, &if_issliced, &if_isthin,
+ };
+ STATIC_ASSERT(arraysize(values) == arraysize(labels));
+
+ Node* const representation = Word32And(
+ var_instance_type_.value(), Int32Constant(kStringRepresentationMask));
+ Switch(representation, if_bailout, values, labels, arraysize(values));
+ }
+
+ // Cons string. Check whether it is flat, then fetch first part.
+ // Flat cons strings have an empty second part.
+ BIND(&if_iscons);
+ {
+ Node* const string = var_string_.value();
+ GotoIfNot(IsEmptyString(LoadObjectField(string, ConsString::kSecondOffset)),
+ if_bailout);
+
+ Node* const lhs = LoadObjectField(string, ConsString::kFirstOffset);
+ var_string_.Bind(lhs);
+ var_instance_type_.Bind(LoadInstanceType(lhs));
+
+ Goto(&dispatch);
+ }
+
+ // Sliced string. Fetch parent and correct start index by offset.
+ BIND(&if_issliced);
+ {
+ Node* const string = var_string_.value();
+ Node* const sliced_offset =
+ LoadAndUntagObjectField(string, SlicedString::kOffsetOffset);
+ var_offset_.Bind(IntPtrAdd(var_offset_.value(), sliced_offset));
+
+ Node* const parent = LoadObjectField(string, SlicedString::kParentOffset);
+ var_string_.Bind(parent);
+ var_instance_type_.Bind(LoadInstanceType(parent));
+
+ Goto(&dispatch);
+ }
+
+ // Thin string. Fetch the actual string.
+ BIND(&if_isthin);
+ {
+ Node* const string = var_string_.value();
+ Node* const actual_string =
+ LoadObjectField(string, ThinString::kActualOffset);
+ Node* const actual_instance_type = LoadInstanceType(actual_string);
+
+ var_string_.Bind(actual_string);
+ var_instance_type_.Bind(actual_instance_type);
+
+ Goto(&dispatch);
+ }
+
+ // External string.
+ BIND(&if_isexternal);
+ var_is_external_.Bind(Int32Constant(1));
+ Goto(&out);
+
+ BIND(&out);
+ return var_string_.value();
}
-} // namespace
+Node* ToDirectStringAssembler::TryToSequential(StringPointerKind ptr_kind,
+ Label* if_bailout) {
+ CHECK(ptr_kind == PTR_TO_DATA || ptr_kind == PTR_TO_STRING);
+
+ VARIABLE(var_result, MachineType::PointerRepresentation());
+ Label out(this), if_issequential(this), if_isexternal(this, Label::kDeferred);
+ Branch(is_external(), &if_isexternal, &if_issequential);
+
+ BIND(&if_issequential);
+ {
+ STATIC_ASSERT(SeqOneByteString::kHeaderSize ==
+ SeqTwoByteString::kHeaderSize);
+ Node* result = BitcastTaggedToWord(var_string_.value());
+ if (ptr_kind == PTR_TO_DATA) {
+ result = IntPtrAdd(result, IntPtrConstant(SeqOneByteString::kHeaderSize -
+ kHeapObjectTag));
+ }
+ var_result.Bind(result);
+ Goto(&out);
+ }
+
+ BIND(&if_isexternal);
+ {
+ GotoIf(IsShortExternalStringInstanceType(var_instance_type_.value()),
+ if_bailout);
+
+ Node* const string = var_string_.value();
+ Node* result = LoadObjectField(string, ExternalString::kResourceDataOffset,
+ MachineType::Pointer());
+ if (ptr_kind == PTR_TO_STRING) {
+ result = IntPtrSub(result, IntPtrConstant(SeqOneByteString::kHeaderSize -
+ kHeapObjectTag));
+ }
+ var_result.Bind(result);
+ Goto(&out);
+ }
+
+ BIND(&out);
+ return var_result.value();
+}
Node* CodeStubAssembler::TryDerefExternalString(Node* const string,
Node* const instance_type,
Label* if_bailout) {
Label out(this);
- USE(IsExternalStringInstanceType);
- CSA_ASSERT(this, IsExternalStringInstanceType(this, instance_type));
- GotoIf(IsShortExternalStringInstanceType(this, instance_type), if_bailout);
+ CSA_ASSERT(this, IsExternalStringInstanceType(instance_type));
+ GotoIf(IsShortExternalStringInstanceType(instance_type), if_bailout);
// Move the pointer so that offset-wise, it looks like a sequential string.
STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
@@ -3570,14 +3667,14 @@ void CodeStubAssembler::MaybeDerefIndirectString(Variable* var_string,
GotoIf(WordEqual(rhs, EmptyStringConstant()), &deref);
Goto(&done);
- Bind(&deref);
+ BIND(&deref);
STATIC_ASSERT(ThinString::kActualOffset == ConsString::kFirstOffset);
var_string->Bind(
LoadObjectField(var_string->value(), ThinString::kActualOffset));
var_did_something->Bind(IntPtrConstant(1));
Goto(&done);
- Bind(&done);
+ BIND(&done);
}
void CodeStubAssembler::MaybeDerefIndirectStrings(Variable* var_left,
@@ -3585,8 +3682,8 @@ void CodeStubAssembler::MaybeDerefIndirectStrings(Variable* var_left,
Variable* var_right,
Node* right_instance_type,
Label* did_something) {
- Variable var_did_something(this, MachineType::PointerRepresentation(),
- IntPtrConstant(0));
+ VARIABLE(var_did_something, MachineType::PointerRepresentation(),
+ IntPtrConstant(0));
MaybeDerefIndirectString(var_left, left_instance_type, &var_did_something);
MaybeDerefIndirectString(var_right, right_instance_type, &var_did_something);
@@ -3597,12 +3694,9 @@ void CodeStubAssembler::MaybeDerefIndirectStrings(Variable* var_left,
Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right,
AllocationFlags flags) {
- Label check_right(this);
- Label runtime(this, Label::kDeferred);
- Label cons(this);
- Variable result(this, MachineRepresentation::kTagged);
- Label done(this, &result);
- Label done_native(this, &result);
+ VARIABLE(result, MachineRepresentation::kTagged);
+ Label check_right(this), runtime(this, Label::kDeferred), cons(this),
+ done(this, &result), done_native(this, &result);
Counters* counters = isolate()->counters();
Node* left_length = LoadStringLength(left);
@@ -3610,13 +3704,13 @@ Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right,
result.Bind(right);
Goto(&done_native);
- Bind(&check_right);
+ BIND(&check_right);
Node* right_length = LoadStringLength(right);
GotoIf(WordNotEqual(IntPtrConstant(0), right_length), &cons);
result.Bind(left);
Goto(&done_native);
- Bind(&cons);
+ BIND(&cons);
{
CSA_ASSERT(this, TaggedIsSmi(left_length));
CSA_ASSERT(this, TaggedIsSmi(right_length));
@@ -3624,8 +3718,8 @@ Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right,
GotoIf(SmiAboveOrEqual(new_length, SmiConstant(String::kMaxLength)),
&runtime);
- Variable var_left(this, MachineRepresentation::kTagged, left);
- Variable var_right(this, MachineRepresentation::kTagged, right);
+ VARIABLE(var_left, MachineRepresentation::kTagged, left);
+ VARIABLE(var_right, MachineRepresentation::kTagged, right);
Variable* input_vars[2] = {&var_left, &var_right};
Label non_cons(this, 2, input_vars);
Label slow(this, Label::kDeferred);
@@ -3636,7 +3730,7 @@ Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right,
var_right.value(), flags));
Goto(&done_native);
- Bind(&non_cons);
+ BIND(&non_cons);
Comment("Full string concatenate");
Node* left_instance_type = LoadInstanceType(var_left.value());
@@ -3676,7 +3770,7 @@ Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right,
result.Bind(new_string);
Goto(&done_native);
- Bind(&two_byte);
+ BIND(&two_byte);
{
// Two-byte sequential string case
new_string =
@@ -3693,7 +3787,7 @@ Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right,
Goto(&done_native);
}
- Bind(&slow);
+ BIND(&slow);
{
// Try to unwrap indirect strings, restart the above attempt on success.
MaybeDerefIndirectStrings(&var_left, left_instance_type, &var_right,
@@ -3701,39 +3795,38 @@ Node* CodeStubAssembler::StringAdd(Node* context, Node* left, Node* right,
Goto(&runtime);
}
}
- Bind(&runtime);
+ BIND(&runtime);
{
result.Bind(CallRuntime(Runtime::kStringAdd, context, left, right));
Goto(&done);
}
- Bind(&done_native);
+ BIND(&done_native);
{
IncrementCounter(counters->string_add_native(), 1);
Goto(&done);
}
- Bind(&done);
+ BIND(&done);
return result.value();
}
Node* CodeStubAssembler::StringFromCodePoint(Node* codepoint,
UnicodeEncoding encoding) {
- Variable var_result(this, MachineRepresentation::kTagged,
- EmptyStringConstant());
+ VARIABLE(var_result, MachineRepresentation::kTagged, EmptyStringConstant());
Label if_isword16(this), if_isword32(this), return_result(this);
Branch(Uint32LessThan(codepoint, Int32Constant(0x10000)), &if_isword16,
&if_isword32);
- Bind(&if_isword16);
+ BIND(&if_isword16);
{
var_result.Bind(StringFromCharCode(codepoint));
Goto(&return_result);
}
- Bind(&if_isword32);
+ BIND(&if_isword32);
{
switch (encoding) {
case UnicodeEncoding::UTF16:
@@ -3765,7 +3858,7 @@ Node* CodeStubAssembler::StringFromCodePoint(Node* codepoint,
Goto(&return_result);
}
- Bind(&return_result);
+ BIND(&return_result);
return var_result.value();
}
@@ -3773,7 +3866,7 @@ Node* CodeStubAssembler::StringToNumber(Node* context, Node* input) {
Label runtime(this, Label::kDeferred);
Label end(this);
- Variable var_result(this, MachineRepresentation::kTagged);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
// Check if string has a cached array index.
Node* hash = LoadNameHashField(input);
@@ -3785,21 +3878,19 @@ Node* CodeStubAssembler::StringToNumber(Node* context, Node* input) {
SmiTag(DecodeWordFromWord32<String::ArrayIndexValueBits>(hash)));
Goto(&end);
- Bind(&runtime);
+ BIND(&runtime);
{
var_result.Bind(CallRuntime(Runtime::kStringToNumber, context, input));
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
return var_result.value();
}
Node* CodeStubAssembler::NumberToString(Node* context, Node* argument) {
- Variable result(this, MachineRepresentation::kTagged);
- Label runtime(this, Label::kDeferred);
- Label smi(this);
- Label done(this, &result);
+ VARIABLE(result, MachineRepresentation::kTagged);
+ Label runtime(this, Label::kDeferred), smi(this), done(this, &result);
// Load the number string cache.
Node* number_string_cache = LoadRoot(Heap::kNumberStringCacheRootIndex);
@@ -3847,14 +3938,14 @@ Node* CodeStubAssembler::NumberToString(Node* context, Node* argument) {
result.Bind(LoadFixedArrayElement(number_string_cache, index, kPointerSize));
Goto(&done);
- Bind(&runtime);
+ BIND(&runtime);
{
// No cache entry, go to the runtime.
result.Bind(CallRuntime(Runtime::kNumberToString, context, argument));
}
Goto(&done);
- Bind(&smi);
+ BIND(&smi);
{
// Load the smi key, make sure it matches the smi we're looking for.
Node* smi_index = BitcastWordToTagged(
@@ -3870,13 +3961,13 @@ Node* CodeStubAssembler::NumberToString(Node* context, Node* argument) {
Goto(&done);
}
- Bind(&done);
+ BIND(&done);
return result.value();
}
Node* CodeStubAssembler::ToName(Node* context, Node* value) {
Label end(this);
- Variable var_result(this, MachineRepresentation::kTagged);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
Label is_number(this);
GotoIf(TaggedIsSmi(value), &is_number);
@@ -3890,14 +3981,14 @@ Node* CodeStubAssembler::ToName(Node* context, Node* value) {
var_result.Bind(value);
Goto(&end);
- Bind(&is_number);
+ BIND(&is_number);
{
Callable callable = CodeFactory::NumberToString(isolate());
var_result.Bind(CallStub(callable, context, value));
Goto(&end);
}
- Bind(&not_name);
+ BIND(&not_name);
{
GotoIf(Word32Equal(value_instance_type, Int32Constant(HEAP_NUMBER_TYPE)),
&is_number);
@@ -3909,14 +4000,14 @@ Node* CodeStubAssembler::ToName(Node* context, Node* value) {
var_result.Bind(LoadObjectField(value, Oddball::kToStringOffset));
Goto(&end);
- Bind(&not_oddball);
+ BIND(&not_oddball);
{
var_result.Bind(CallRuntime(Runtime::kToName, context, value));
Goto(&end);
}
}
- Bind(&end);
+ BIND(&end);
return var_result.value();
}
@@ -3926,12 +4017,12 @@ Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) {
CSA_ASSERT(this, Word32BinaryNot(IsHeapNumberMap(LoadMap(input))));
// We might need to loop once here due to ToPrimitive conversions.
- Variable var_input(this, MachineRepresentation::kTagged, input);
- Variable var_result(this, MachineRepresentation::kTagged);
+ VARIABLE(var_input, MachineRepresentation::kTagged, input);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
Label loop(this, &var_input);
Label end(this);
Goto(&loop);
- Bind(&loop);
+ BIND(&loop);
{
// Load the current {input} value (known to be a HeapObject).
Node* input = var_input.value();
@@ -3947,21 +4038,21 @@ Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) {
Branch(IsJSReceiverInstanceType(input_instance_type), &if_inputisreceiver,
&if_inputisother);
- Bind(&if_inputisstring);
+ BIND(&if_inputisstring);
{
// The {input} is a String, use the fast stub to convert it to a Number.
var_result.Bind(StringToNumber(context, input));
Goto(&end);
}
- Bind(&if_inputisoddball);
+ BIND(&if_inputisoddball);
{
// The {input} is an Oddball, we just need to load the Number value of it.
var_result.Bind(LoadObjectField(input, Oddball::kToNumberOffset));
Goto(&end);
}
- Bind(&if_inputisreceiver);
+ BIND(&if_inputisreceiver);
{
// The {input} is a JSReceiver, we need to convert it to a Primitive first
// using the ToPrimitive type conversion, preferably yielding a Number.
@@ -3976,14 +4067,14 @@ Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) {
Branch(IsHeapNumberMap(result_map), &if_resultisnumber,
&if_resultisnotnumber);
- Bind(&if_resultisnumber);
+ BIND(&if_resultisnumber);
{
// The ToPrimitive conversion already gave us a Number, so we're done.
var_result.Bind(result);
Goto(&end);
}
- Bind(&if_resultisnotnumber);
+ BIND(&if_resultisnotnumber);
{
// We now have a Primitive {result}, but it's not yet a Number.
var_input.Bind(result);
@@ -3991,7 +4082,7 @@ Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) {
}
}
- Bind(&if_inputisother);
+ BIND(&if_inputisother);
{
// The {input} is something else (e.g. Symbol), let the runtime figure
// out the correct exception.
@@ -4004,12 +4095,12 @@ Node* CodeStubAssembler::NonNumberToNumber(Node* context, Node* input) {
}
}
- Bind(&end);
+ BIND(&end);
return var_result.value();
}
Node* CodeStubAssembler::ToNumber(Node* context, Node* input) {
- Variable var_result(this, MachineRepresentation::kTagged);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
Label end(this);
Label not_smi(this, Label::kDeferred);
@@ -4017,7 +4108,7 @@ Node* CodeStubAssembler::ToNumber(Node* context, Node* input) {
var_result.Bind(input);
Goto(&end);
- Bind(&not_smi);
+ BIND(&not_smi);
{
Label not_heap_number(this, Label::kDeferred);
Node* input_map = LoadMap(input);
@@ -4026,24 +4117,25 @@ Node* CodeStubAssembler::ToNumber(Node* context, Node* input) {
var_result.Bind(input);
Goto(&end);
- Bind(&not_heap_number);
+ BIND(&not_heap_number);
{
var_result.Bind(NonNumberToNumber(context, input));
Goto(&end);
}
}
- Bind(&end);
+ BIND(&end);
return var_result.value();
}
+// ES#sec-touint32
Node* CodeStubAssembler::ToUint32(Node* context, Node* input) {
Node* const float_zero = Float64Constant(0.0);
Node* const float_two_32 = Float64Constant(static_cast<double>(1ULL << 32));
Label out(this);
- Variable var_result(this, MachineRepresentation::kTagged, input);
+ VARIABLE(var_result, MachineRepresentation::kTagged, input);
// Early exit for positive smis.
{
@@ -4051,7 +4143,7 @@ Node* CodeStubAssembler::ToUint32(Node* context, Node* input) {
// have a ToNumber with multiple exits.
Label next(this, Label::kDeferred);
Branch(TaggedIsPositiveSmi(input), &out, &next);
- Bind(&next);
+ BIND(&next);
}
Node* const number = ToNumber(context, input);
@@ -4061,23 +4153,21 @@ Node* CodeStubAssembler::ToUint32(Node* context, Node* input) {
{
Label next(this, Label::kDeferred);
Branch(TaggedIsPositiveSmi(number), &out, &next);
- Bind(&next);
+ BIND(&next);
}
Label if_isnegativesmi(this), if_isheapnumber(this);
Branch(TaggedIsSmi(number), &if_isnegativesmi, &if_isheapnumber);
- Bind(&if_isnegativesmi);
+ BIND(&if_isnegativesmi);
{
- // floor({input}) mod 2^32 === {input} + 2^32.
- Node* const float_number = SmiToFloat64(number);
- Node* const float_result = Float64Add(float_number, float_two_32);
- Node* const result = ChangeFloat64ToTagged(float_result);
- var_result.Bind(result);
+ Node* const uint32_value = SmiToWord32(number);
+ Node* float64_value = ChangeUint32ToFloat64(uint32_value);
+ var_result.Bind(AllocateHeapNumberWithValue(float64_value));
Goto(&out);
}
- Bind(&if_isheapnumber);
+ BIND(&if_isheapnumber);
{
Label return_zero(this);
Node* const value = LoadHeapNumberValue(number);
@@ -4086,14 +4176,14 @@ Node* CodeStubAssembler::ToUint32(Node* context, Node* input) {
// +-0.
Label next(this);
Branch(Float64Equal(value, float_zero), &return_zero, &next);
- Bind(&next);
+ BIND(&next);
}
{
// NaN.
Label next(this);
Branch(Float64Equal(value, value), &next, &return_zero);
- Bind(&next);
+ BIND(&next);
}
{
@@ -4102,7 +4192,7 @@ Node* CodeStubAssembler::ToUint32(Node* context, Node* input) {
Node* const positive_infinity =
Float64Constant(std::numeric_limits<double>::infinity());
Branch(Float64Equal(value, positive_infinity), &return_zero, &next);
- Bind(&next);
+ BIND(&next);
}
{
@@ -4111,13 +4201,15 @@ Node* CodeStubAssembler::ToUint32(Node* context, Node* input) {
Node* const negative_infinity =
Float64Constant(-1.0 * std::numeric_limits<double>::infinity());
Branch(Float64Equal(value, negative_infinity), &return_zero, &next);
- Bind(&next);
+ BIND(&next);
}
- // Return floor({input}) mod 2^32 (assuming mod semantics that always return
- // positive results).
+ // * Let int be the mathematical value that is the same sign as number and
+ // whose magnitude is floor(abs(number)).
+ // * Let int32bit be int modulo 2^32.
+ // * Return int32bit.
{
- Node* x = Float64Floor(value);
+ Node* x = Float64Trunc(value);
x = Float64Mod(x, float_two_32);
x = Float64Add(x, float_two_32);
x = Float64Mod(x, float_two_32);
@@ -4127,21 +4219,21 @@ Node* CodeStubAssembler::ToUint32(Node* context, Node* input) {
Goto(&out);
}
- Bind(&return_zero);
+ BIND(&return_zero);
{
var_result.Bind(SmiConstant(Smi::kZero));
Goto(&out);
}
}
- Bind(&out);
+ BIND(&out);
return var_result.value();
}
Node* CodeStubAssembler::ToString(Node* context, Node* input) {
Label is_number(this);
Label runtime(this, Label::kDeferred);
- Variable result(this, MachineRepresentation::kTagged);
+ VARIABLE(result, MachineRepresentation::kTagged);
Label done(this, &result);
GotoIf(TaggedIsSmi(input), &is_number);
@@ -4155,11 +4247,11 @@ Node* CodeStubAssembler::ToString(Node* context, Node* input) {
Label not_heap_number(this);
Branch(IsHeapNumberMap(input_map), &is_number, &not_heap_number);
- Bind(&is_number);
+ BIND(&is_number);
result.Bind(NumberToString(context, input));
Goto(&done);
- Bind(&not_heap_number);
+ BIND(&not_heap_number);
{
GotoIf(Word32NotEqual(input_instance_type, Int32Constant(ODDBALL_TYPE)),
&runtime);
@@ -4167,24 +4259,24 @@ Node* CodeStubAssembler::ToString(Node* context, Node* input) {
Goto(&done);
}
- Bind(&runtime);
+ BIND(&runtime);
{
result.Bind(CallRuntime(Runtime::kToString, context, input));
Goto(&done);
}
- Bind(&done);
+ BIND(&done);
return result.value();
}
Node* CodeStubAssembler::JSReceiverToPrimitive(Node* context, Node* input) {
Label if_isreceiver(this, Label::kDeferred), if_isnotreceiver(this);
- Variable result(this, MachineRepresentation::kTagged);
+ VARIABLE(result, MachineRepresentation::kTagged);
Label done(this, &result);
BranchIfJSReceiver(input, &if_isreceiver, &if_isnotreceiver);
- Bind(&if_isreceiver);
+ BIND(&if_isreceiver);
{
// Convert {input} to a primitive first passing Number hint.
Callable callable = CodeFactory::NonPrimitiveToPrimitive(isolate());
@@ -4192,23 +4284,75 @@ Node* CodeStubAssembler::JSReceiverToPrimitive(Node* context, Node* input) {
Goto(&done);
}
- Bind(&if_isnotreceiver);
+ BIND(&if_isnotreceiver);
{
result.Bind(input);
Goto(&done);
}
- Bind(&done);
+ BIND(&done);
+ return result.value();
+}
+
+Node* CodeStubAssembler::ToSmiIndex(Node* const input, Node* const context,
+ Label* range_error) {
+ VARIABLE(result, MachineRepresentation::kTagged, input);
+ Label check_undefined(this), return_zero(this), defined(this),
+ negative_check(this), done(this);
+ Branch(TaggedIsSmi(result.value()), &negative_check, &check_undefined);
+
+ BIND(&check_undefined);
+ Branch(IsUndefined(result.value()), &return_zero, &defined);
+
+ BIND(&defined);
+ result.Bind(ToInteger(context, result.value(),
+ CodeStubAssembler::kTruncateMinusZero));
+ GotoIfNot(TaggedIsSmi(result.value()), range_error);
+ CSA_ASSERT(this, TaggedIsSmi(result.value()));
+ Goto(&negative_check);
+
+ BIND(&negative_check);
+ Branch(SmiLessThan(result.value(), SmiConstant(0)), range_error, &done);
+
+ BIND(&return_zero);
+ result.Bind(SmiConstant(0));
+ Goto(&done);
+
+ BIND(&done);
+ return result.value();
+}
+
+Node* CodeStubAssembler::ToSmiLength(Node* input, Node* const context,
+ Label* range_error) {
+ VARIABLE(result, MachineRepresentation::kTagged, input);
+ Label to_integer(this), negative_check(this), return_zero(this), done(this);
+ Branch(TaggedIsSmi(result.value()), &negative_check, &to_integer);
+
+ BIND(&to_integer);
+ result.Bind(ToInteger(context, result.value(),
+ CodeStubAssembler::kTruncateMinusZero));
+ GotoIfNot(TaggedIsSmi(result.value()), range_error);
+ CSA_ASSERT(this, TaggedIsSmi(result.value()));
+ Goto(&negative_check);
+
+ BIND(&negative_check);
+ Branch(SmiLessThan(result.value(), SmiConstant(0)), &return_zero, &done);
+
+ BIND(&return_zero);
+ result.Bind(SmiConstant(0));
+ Goto(&done);
+
+ BIND(&done);
return result.value();
}
Node* CodeStubAssembler::ToInteger(Node* context, Node* input,
ToIntegerTruncationMode mode) {
// We might need to loop once for ToNumber conversion.
- Variable var_arg(this, MachineRepresentation::kTagged, input);
+ VARIABLE(var_arg, MachineRepresentation::kTagged, input);
Label loop(this, &var_arg), out(this);
Goto(&loop);
- Bind(&loop);
+ BIND(&loop);
{
// Shared entry points.
Label return_zero(this, Label::kDeferred);
@@ -4225,7 +4369,7 @@ Node* CodeStubAssembler::ToInteger(Node* context, Node* input,
Branch(IsHeapNumberMap(LoadMap(arg)), &if_argisheapnumber,
&if_argisnotheapnumber);
- Bind(&if_argisheapnumber);
+ BIND(&if_argisheapnumber);
{
// Load the floating-point value of {arg}.
Node* arg_value = LoadHeapNumberValue(arg);
@@ -4245,7 +4389,7 @@ Node* CodeStubAssembler::ToInteger(Node* context, Node* input,
Goto(&out);
}
- Bind(&if_argisnotheapnumber);
+ BIND(&if_argisnotheapnumber);
{
// Need to convert {arg} to a Number first.
Callable callable = CodeFactory::NonNumberToNumber(isolate());
@@ -4253,12 +4397,12 @@ Node* CodeStubAssembler::ToInteger(Node* context, Node* input,
Goto(&loop);
}
- Bind(&return_zero);
+ BIND(&return_zero);
var_arg.Bind(SmiConstant(Smi::kZero));
Goto(&out);
}
- Bind(&out);
+ BIND(&out);
return var_arg.value();
}
@@ -4327,7 +4471,7 @@ void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex,
var_index->Bind(TryToIntptr(key, &if_keyisnotindex));
Goto(if_keyisindex);
- Bind(&if_keyisnotindex);
+ BIND(&if_keyisnotindex);
Node* key_map = LoadMap(key);
var_unique->Bind(key);
// Symbols are unique.
@@ -4359,11 +4503,11 @@ void CodeStubAssembler::TryToName(Node* key, Label* if_keyisindex,
GotoIf(Word32NotEqual(not_internalized, Int32Constant(0)), if_bailout);
Goto(if_keyisunique);
- Bind(&if_thinstring);
+ BIND(&if_thinstring);
var_unique->Bind(LoadObjectField(key, ThinString::kActualOffset));
Goto(if_keyisunique);
- Bind(&if_hascachedindex);
+ BIND(&if_hascachedindex);
var_index->Bind(DecodeWordFromWord32<Name::ArrayIndexValueBits>(hash));
Goto(if_keyisindex);
}
@@ -4472,12 +4616,12 @@ void CodeStubAssembler::NameDictionaryLookup(Node* dictionary,
Node* undefined = UndefinedConstant();
Node* the_hole = mode == kFindExisting ? nullptr : TheHoleConstant();
- Variable var_count(this, MachineType::PointerRepresentation(), count);
- Variable var_entry(this, MachineType::PointerRepresentation(), entry);
+ VARIABLE(var_count, MachineType::PointerRepresentation(), count);
+ VARIABLE(var_entry, MachineType::PointerRepresentation(), entry);
Variable* loop_vars[] = {&var_count, &var_entry, var_name_index};
Label loop(this, 3, loop_vars);
Goto(&loop);
- Bind(&loop);
+ BIND(&loop);
{
Node* entry = var_entry.value();
@@ -4551,12 +4695,12 @@ void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
Node* undefined = UndefinedConstant();
Node* the_hole = TheHoleConstant();
- Variable var_count(this, MachineType::PointerRepresentation(), count);
+ VARIABLE(var_count, MachineType::PointerRepresentation(), count);
Variable* loop_vars[] = {&var_count, var_entry};
Label loop(this, 2, loop_vars);
var_entry->Bind(entry);
Goto(&loop);
- Bind(&loop);
+ BIND(&loop);
{
Node* entry = var_entry->value();
@@ -4567,12 +4711,12 @@ void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
{
Label if_currentissmi(this), if_currentisnotsmi(this);
Branch(TaggedIsSmi(current), &if_currentissmi, &if_currentisnotsmi);
- Bind(&if_currentissmi);
+ BIND(&if_currentissmi);
{
Node* current_value = SmiUntag(current);
Branch(WordEqual(current_value, intptr_index), if_found, &next_probe);
}
- Bind(&if_currentisnotsmi);
+ BIND(&if_currentisnotsmi);
{
GotoIf(WordEqual(current, the_hole), &next_probe);
// Current must be the Number.
@@ -4582,7 +4726,7 @@ void CodeStubAssembler::NumberDictionaryLookup(Node* dictionary,
}
}
- Bind(&next_probe);
+ BIND(&next_probe);
// See Dictionary::NextProbe().
Increment(var_count);
entry = WordAnd(IntPtrAdd(entry, var_count.value()), mask);
@@ -4604,7 +4748,7 @@ void CodeStubAssembler::FindInsertionEntry<NameDictionary>(
Label done(this);
NameDictionaryLookup<NameDictionary>(dictionary, key, nullptr, var_key_index,
&done, 0, kFindInsertionIndex);
- Bind(&done);
+ BIND(&done);
}
template <class Dictionary>
@@ -4628,8 +4772,8 @@ void CodeStubAssembler::InsertEntry<NameDictionary>(Node* dictionary,
enum_index =
SmiShl(enum_index, PropertyDetails::DictionaryStorageField::kShift);
STATIC_ASSERT(kInitialIndex == 0);
- Variable var_details(this, MachineRepresentation::kTaggedSigned,
- SmiOr(SmiConstant(d.AsSmi()), enum_index));
+ VARIABLE(var_details, MachineRepresentation::kTaggedSigned,
+ SmiOr(SmiConstant(d.AsSmi()), enum_index));
// Private names must be marked non-enumerable.
Label not_private(this, &var_details);
@@ -4641,7 +4785,7 @@ void CodeStubAssembler::InsertEntry<NameDictionary>(Node* dictionary,
SmiShl(SmiConstant(DONT_ENUM), PropertyDetails::AttributesField::kShift);
var_details.Bind(SmiOr(var_details.value(), dont_enum));
Goto(&not_private);
- Bind(&not_private);
+ BIND(&not_private);
// Finally, store the details.
StoreDetailsByKeyIndex<NameDictionary>(dictionary, index,
@@ -4689,7 +4833,7 @@ void CodeStubAssembler::Add(Node* dictionary, Node* key, Node* value,
}
SetNumberOfElements<Dictionary>(dictionary, new_nof);
- Variable var_key_index(this, MachineType::PointerRepresentation());
+ VARIABLE(var_key_index, MachineType::PointerRepresentation());
FindInsertionEntry<Dictionary>(dictionary, key, &var_key_index);
InsertEntry<Dictionary>(dictionary, key, value, var_key_index.value(),
enum_index);
@@ -4764,10 +4908,10 @@ void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name,
Variable* var_name_index,
Label* if_not_found) {
Comment("DescriptorLookupBinary");
- Variable var_low(this, MachineRepresentation::kWord32, Int32Constant(0));
+ VARIABLE(var_low, MachineRepresentation::kWord32, Int32Constant(0));
Node* limit =
Int32Sub(DescriptorArrayNumberOfEntries(descriptors), Int32Constant(1));
- Variable var_high(this, MachineRepresentation::kWord32, limit);
+ VARIABLE(var_high, MachineRepresentation::kWord32, limit);
Node* hash = LoadNameHashField(unique_name);
CSA_ASSERT(this, Word32NotEqual(hash, Int32Constant(0)));
@@ -4777,7 +4921,7 @@ void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name,
Variable* loop_vars[] = {&var_high, &var_low};
Label binary_loop(this, 2, loop_vars);
Goto(&binary_loop);
- Bind(&binary_loop);
+ BIND(&binary_loop);
{
// mid = low + (high - low) / 2 (to avoid overflow in "(low + high) / 2").
Node* mid =
@@ -4791,23 +4935,23 @@ void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name,
Label mid_greater(this), mid_less(this), merge(this);
Branch(Uint32GreaterThanOrEqual(mid_hash, hash), &mid_greater, &mid_less);
- Bind(&mid_greater);
+ BIND(&mid_greater);
{
var_high.Bind(mid);
Goto(&merge);
}
- Bind(&mid_less);
+ BIND(&mid_less);
{
var_low.Bind(Int32Add(mid, Int32Constant(1)));
Goto(&merge);
}
- Bind(&merge);
+ BIND(&merge);
GotoIf(Word32NotEqual(var_low.value(), var_high.value()), &binary_loop);
}
Label scan_loop(this, &var_low);
Goto(&scan_loop);
- Bind(&scan_loop);
+ BIND(&scan_loop);
{
GotoIf(Int32GreaterThan(var_low.value(), limit), if_not_found);
@@ -4822,7 +4966,7 @@ void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name,
var_name_index->Bind(DescriptorArrayToKeyIndex(sort_index));
Goto(if_found);
- Bind(&next);
+ BIND(&next);
var_low.Bind(Int32Add(var_low.value(), Int32Constant(1)));
Goto(&scan_loop);
}
@@ -4839,12 +4983,12 @@ void CodeStubAssembler::DescriptorLookup(Node* unique_name, Node* descriptors,
const int kMaxElementsForLinearSearch = 32;
Branch(Int32LessThanOrEqual(nof, Int32Constant(kMaxElementsForLinearSearch)),
&linear_search, &binary_search);
- Bind(&linear_search);
+ BIND(&linear_search);
{
DescriptorLookupLinear(unique_name, descriptors, ChangeInt32ToIntPtr(nof),
if_found, var_name_index, if_not_found);
}
- Bind(&binary_search);
+ BIND(&binary_search);
{
DescriptorLookupBinary(unique_name, descriptors, nof, if_found,
var_name_index, if_not_found);
@@ -4874,7 +5018,7 @@ void CodeStubAssembler::TryLookupProperty(
Label if_isfastmap(this), if_isslowmap(this);
Branch(IsSetWord32<Map::DictionaryMap>(bit_field3), &if_isslowmap,
&if_isfastmap);
- Bind(&if_isfastmap);
+ BIND(&if_isfastmap);
{
Node* descriptors = LoadMapDescriptors(map);
var_meta_storage->Bind(descriptors);
@@ -4882,7 +5026,7 @@ void CodeStubAssembler::TryLookupProperty(
DescriptorLookup(unique_name, descriptors, bit_field3, if_found_fast,
var_name_index, if_not_found);
}
- Bind(&if_isslowmap);
+ BIND(&if_isslowmap);
{
Node* dictionary = LoadProperties(object);
var_meta_storage->Bind(dictionary);
@@ -4890,7 +5034,7 @@ void CodeStubAssembler::TryLookupProperty(
NameDictionaryLookup<NameDictionary>(dictionary, unique_name, if_found_dict,
var_name_index, if_not_found);
}
- Bind(&if_objectisspecial);
+ BIND(&if_objectisspecial);
{
// Handle global object here and other special objects in runtime.
GotoIfNot(Word32Equal(instance_type, Int32Constant(JS_GLOBAL_OBJECT_TYPE)),
@@ -4917,17 +5061,17 @@ void CodeStubAssembler::TryHasOwnProperty(Node* object, Node* map,
Label* if_not_found,
Label* if_bailout) {
Comment("TryHasOwnProperty");
- Variable var_meta_storage(this, MachineRepresentation::kTagged);
- Variable var_name_index(this, MachineType::PointerRepresentation());
+ VARIABLE(var_meta_storage, MachineRepresentation::kTagged);
+ VARIABLE(var_name_index, MachineType::PointerRepresentation());
Label if_found_global(this);
TryLookupProperty(object, map, instance_type, unique_name, if_found, if_found,
&if_found_global, &var_meta_storage, &var_name_index,
if_not_found, if_bailout);
- Bind(&if_found_global);
+ BIND(&if_found_global);
{
- Variable var_value(this, MachineRepresentation::kTagged);
- Variable var_details(this, MachineRepresentation::kWord32);
+ VARIABLE(var_value, MachineRepresentation::kTagged);
+ VARIABLE(var_details, MachineRepresentation::kWord32);
// Check if the property cell is not deleted.
LoadPropertyFromGlobalDictionary(var_meta_storage.value(),
var_name_index.value(), &var_value,
@@ -4954,7 +5098,7 @@ void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
Label if_in_field(this), if_in_descriptor(this), done(this);
Branch(Word32Equal(location, Int32Constant(kField)), &if_in_field,
&if_in_descriptor);
- Bind(&if_in_field);
+ BIND(&if_in_field);
{
Node* field_index =
DecodeWordFromWord32<PropertyDetails::FieldIndexField>(details);
@@ -4964,11 +5108,11 @@ void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
Node* inobject_properties = LoadMapInobjectProperties(map);
Label if_inobject(this), if_backing_store(this);
- Variable var_double_value(this, MachineRepresentation::kFloat64);
+ VARIABLE(var_double_value, MachineRepresentation::kFloat64);
Label rebox_double(this, &var_double_value);
Branch(UintPtrLessThan(field_index, inobject_properties), &if_inobject,
&if_backing_store);
- Bind(&if_inobject);
+ BIND(&if_inobject);
{
Comment("if_inobject");
Node* field_offset =
@@ -4980,12 +5124,12 @@ void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
Branch(Word32NotEqual(representation,
Int32Constant(Representation::kDouble)),
&if_tagged, &if_double);
- Bind(&if_tagged);
+ BIND(&if_tagged);
{
var_value->Bind(LoadObjectField(object, field_offset));
Goto(&done);
}
- Bind(&if_double);
+ BIND(&if_double);
{
if (FLAG_unbox_double_fields) {
var_double_value.Bind(
@@ -4997,7 +5141,7 @@ void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
Goto(&rebox_double);
}
}
- Bind(&if_backing_store);
+ BIND(&if_backing_store);
{
Comment("if_backing_store");
Node* properties = LoadProperties(object);
@@ -5008,18 +5152,18 @@ void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
Branch(Word32NotEqual(representation,
Int32Constant(Representation::kDouble)),
&if_tagged, &if_double);
- Bind(&if_tagged);
+ BIND(&if_tagged);
{
var_value->Bind(value);
Goto(&done);
}
- Bind(&if_double);
+ BIND(&if_double);
{
var_double_value.Bind(LoadHeapNumberValue(value));
Goto(&rebox_double);
}
}
- Bind(&rebox_double);
+ BIND(&rebox_double);
{
Comment("rebox_double");
Node* heap_number = AllocateHeapNumberWithValue(var_double_value.value());
@@ -5027,13 +5171,13 @@ void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map,
Goto(&done);
}
}
- Bind(&if_in_descriptor);
+ BIND(&if_in_descriptor);
{
var_value->Bind(
LoadValueByKeyIndex<DescriptorArray>(descriptors, name_index));
Goto(&done);
}
- Bind(&done);
+ BIND(&done);
Comment("] LoadPropertyFromFastObject");
}
@@ -5081,7 +5225,7 @@ void CodeStubAssembler::LoadPropertyFromGlobalDictionary(Node* dictionary,
Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details,
Node* context, Node* receiver,
Label* if_bailout) {
- Variable var_value(this, MachineRepresentation::kTagged, value);
+ VARIABLE(var_value, MachineRepresentation::kTagged, value);
Label done(this);
Node* kind = DecodeWord32<PropertyDetails::KindField>(details);
@@ -5093,7 +5237,7 @@ Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details,
GotoIf(Word32Equal(LoadInstanceType(accessor_pair),
Int32Constant(ACCESSOR_INFO_TYPE)),
if_bailout);
- CSA_ASSERT(this, HasInstanceType(accessor_pair, ACCESSOR_PAIR_TYPE));
+ CSA_ASSERT(this, IsAccessorPair(accessor_pair));
Node* getter = LoadObjectField(accessor_pair, AccessorPair::kGetterOffset);
Node* getter_map = LoadMap(getter);
Node* instance_type = LoadMapInstanceType(getter_map);
@@ -5113,7 +5257,7 @@ Node* CodeStubAssembler::CallGetterIfAccessor(Node* value, Node* details,
Goto(&done);
}
- Bind(&done);
+ BIND(&done);
return var_value.value();
}
@@ -5124,19 +5268,19 @@ void CodeStubAssembler::TryGetOwnProperty(
DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep());
Comment("TryGetOwnProperty");
- Variable var_meta_storage(this, MachineRepresentation::kTagged);
- Variable var_entry(this, MachineType::PointerRepresentation());
+ VARIABLE(var_meta_storage, MachineRepresentation::kTagged);
+ VARIABLE(var_entry, MachineType::PointerRepresentation());
Label if_found_fast(this), if_found_dict(this), if_found_global(this);
- Variable var_details(this, MachineRepresentation::kWord32);
+ VARIABLE(var_details, MachineRepresentation::kWord32);
Variable* vars[] = {var_value, &var_details};
Label if_found(this, 2, vars);
TryLookupProperty(object, map, instance_type, unique_name, &if_found_fast,
&if_found_dict, &if_found_global, &var_meta_storage,
&var_entry, if_not_found, if_bailout);
- Bind(&if_found_fast);
+ BIND(&if_found_fast);
{
Node* descriptors = var_meta_storage.value();
Node* name_index = var_entry.value();
@@ -5145,14 +5289,14 @@ void CodeStubAssembler::TryGetOwnProperty(
&var_details, var_value);
Goto(&if_found);
}
- Bind(&if_found_dict);
+ BIND(&if_found_dict);
{
Node* dictionary = var_meta_storage.value();
Node* entry = var_entry.value();
LoadPropertyFromNameDictionary(dictionary, entry, &var_details, var_value);
Goto(&if_found);
}
- Bind(&if_found_global);
+ BIND(&if_found_global);
{
Node* dictionary = var_meta_storage.value();
Node* entry = var_entry.value();
@@ -5162,7 +5306,7 @@ void CodeStubAssembler::TryGetOwnProperty(
Goto(&if_found);
}
// Here we have details and value which could be an accessor.
- Bind(&if_found);
+ BIND(&if_found);
{
Node* value = CallGetterIfAccessor(var_value->value(), var_details.value(),
context, receiver, if_bailout);
@@ -5174,7 +5318,7 @@ void CodeStubAssembler::TryGetOwnProperty(
void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
Node* instance_type,
Node* intptr_index, Label* if_found,
- Label* if_not_found,
+ Label* if_absent, Label* if_not_found,
Label* if_bailout) {
// Handle special objects in runtime.
GotoIf(Int32LessThanOrEqual(instance_type,
@@ -5185,7 +5329,8 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
// TODO(verwaest): Support other elements kinds as well.
Label if_isobjectorsmi(this), if_isdouble(this), if_isdictionary(this),
- if_isfaststringwrapper(this), if_isslowstringwrapper(this), if_oob(this);
+ if_isfaststringwrapper(this), if_isslowstringwrapper(this), if_oob(this),
+ if_typedarray(this);
// clang-format off
int32_t values[] = {
// Handled by {if_isobjectorsmi}.
@@ -5201,6 +5346,16 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
SLOW_STRING_WRAPPER_ELEMENTS,
// Handled by {if_not_found}.
NO_ELEMENTS,
+ // Handled by {if_typed_array}.
+ UINT8_ELEMENTS,
+ INT8_ELEMENTS,
+ UINT16_ELEMENTS,
+ INT16_ELEMENTS,
+ UINT32_ELEMENTS,
+ INT32_ELEMENTS,
+ FLOAT32_ELEMENTS,
+ FLOAT64_ELEMENTS,
+ UINT8_CLAMPED_ELEMENTS,
};
Label* labels[] = {
&if_isobjectorsmi, &if_isobjectorsmi, &if_isobjectorsmi,
@@ -5210,12 +5365,21 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
&if_isfaststringwrapper,
&if_isslowstringwrapper,
if_not_found,
+ &if_typedarray,
+ &if_typedarray,
+ &if_typedarray,
+ &if_typedarray,
+ &if_typedarray,
+ &if_typedarray,
+ &if_typedarray,
+ &if_typedarray,
+ &if_typedarray,
};
// clang-format on
STATIC_ASSERT(arraysize(values) == arraysize(labels));
Switch(elements_kind, if_bailout, values, labels, arraysize(values));
- Bind(&if_isobjectorsmi);
+ BIND(&if_isobjectorsmi);
{
Node* elements = LoadElements(object);
Node* length = LoadAndUntagFixedArrayBaseLength(elements);
@@ -5226,7 +5390,7 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
Node* the_hole = TheHoleConstant();
Branch(WordEqual(element, the_hole), if_not_found, if_found);
}
- Bind(&if_isdouble);
+ BIND(&if_isdouble);
{
Node* elements = LoadElements(object);
Node* length = LoadAndUntagFixedArrayBaseLength(elements);
@@ -5238,17 +5402,17 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
INTPTR_PARAMETERS, if_not_found);
Goto(if_found);
}
- Bind(&if_isdictionary);
+ BIND(&if_isdictionary);
{
// Negative keys must be converted to property names.
GotoIf(IntPtrLessThan(intptr_index, IntPtrConstant(0)), if_bailout);
- Variable var_entry(this, MachineType::PointerRepresentation());
+ VARIABLE(var_entry, MachineType::PointerRepresentation());
Node* elements = LoadElements(object);
NumberDictionaryLookup<SeededNumberDictionary>(
elements, intptr_index, if_found, &var_entry, if_not_found);
}
- Bind(&if_isfaststringwrapper);
+ BIND(&if_isfaststringwrapper);
{
CSA_ASSERT(this, HasInstanceType(object, JS_VALUE_TYPE));
Node* string = LoadJSValueValue(object);
@@ -5257,7 +5421,7 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
GotoIf(UintPtrLessThan(intptr_index, SmiUntag(length)), if_found);
Goto(&if_isobjectorsmi);
}
- Bind(&if_isslowstringwrapper);
+ BIND(&if_isslowstringwrapper);
{
CSA_ASSERT(this, HasInstanceType(object, JS_VALUE_TYPE));
Node* string = LoadJSValueValue(object);
@@ -5266,7 +5430,16 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
GotoIf(UintPtrLessThan(intptr_index, SmiUntag(length)), if_found);
Goto(&if_isdictionary);
}
- Bind(&if_oob);
+ BIND(&if_typedarray);
+ {
+ Node* buffer = LoadObjectField(object, JSArrayBufferView::kBufferOffset);
+ GotoIf(IsDetachedBuffer(buffer), if_absent);
+
+ Node* length = TryToIntptr(
+ LoadObjectField(object, JSTypedArray::kLengthOffset), if_bailout);
+ Branch(UintPtrLessThan(intptr_index, length), if_found, if_absent);
+ }
+ BIND(&if_oob);
{
// Positive OOB indices mean "not found", negative indices must be
// converted to property names.
@@ -5288,7 +5461,7 @@ void CodeStubAssembler::TryPrototypeChainLookup(
// Ensure receiver is JSReceiver, otherwise bailout.
Label if_objectisnotsmi(this);
Branch(TaggedIsSmi(receiver), if_bailout, &if_objectisnotsmi);
- Bind(&if_objectisnotsmi);
+ BIND(&if_objectisnotsmi);
Node* map = LoadMap(receiver);
Node* instance_type = LoadMapInstanceType(map);
@@ -5299,28 +5472,28 @@ void CodeStubAssembler::TryPrototypeChainLookup(
Branch(
Int32GreaterThan(instance_type, Int32Constant(FIRST_JS_RECEIVER_TYPE)),
&if_objectisreceiver, if_bailout);
- Bind(&if_objectisreceiver);
+ BIND(&if_objectisreceiver);
}
- Variable var_index(this, MachineType::PointerRepresentation());
- Variable var_unique(this, MachineRepresentation::kTagged);
+ VARIABLE(var_index, MachineType::PointerRepresentation());
+ VARIABLE(var_unique, MachineRepresentation::kTagged);
Label if_keyisindex(this), if_iskeyunique(this);
TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, &var_unique,
if_bailout);
- Bind(&if_iskeyunique);
+ BIND(&if_iskeyunique);
{
- Variable var_holder(this, MachineRepresentation::kTagged, receiver);
- Variable var_holder_map(this, MachineRepresentation::kTagged, map);
- Variable var_holder_instance_type(this, MachineRepresentation::kWord32,
- instance_type);
+ VARIABLE(var_holder, MachineRepresentation::kTagged, receiver);
+ VARIABLE(var_holder_map, MachineRepresentation::kTagged, map);
+ VARIABLE(var_holder_instance_type, MachineRepresentation::kWord32,
+ instance_type);
Variable* merged_variables[] = {&var_holder, &var_holder_map,
&var_holder_instance_type};
Label loop(this, arraysize(merged_variables), merged_variables);
Goto(&loop);
- Bind(&loop);
+ BIND(&loop);
{
Node* holder_map = var_holder_map.value();
Node* holder_instance_type = var_holder_instance_type.value();
@@ -5329,7 +5502,7 @@ void CodeStubAssembler::TryPrototypeChainLookup(
lookup_property_in_holder(receiver, var_holder.value(), holder_map,
holder_instance_type, var_unique.value(),
&next_proto, if_bailout);
- Bind(&next_proto);
+ BIND(&next_proto);
// Bailout if it can be an integer indexed exotic case.
GotoIf(
@@ -5340,7 +5513,7 @@ void CodeStubAssembler::TryPrototypeChainLookup(
Label if_not_null(this);
Branch(WordEqual(proto, NullConstant()), if_end, &if_not_null);
- Bind(&if_not_null);
+ BIND(&if_not_null);
Node* map = LoadMap(proto);
Node* instance_type = LoadMapInstanceType(map);
@@ -5351,31 +5524,31 @@ void CodeStubAssembler::TryPrototypeChainLookup(
Goto(&loop);
}
}
- Bind(&if_keyisindex);
+ BIND(&if_keyisindex);
{
- Variable var_holder(this, MachineRepresentation::kTagged, receiver);
- Variable var_holder_map(this, MachineRepresentation::kTagged, map);
- Variable var_holder_instance_type(this, MachineRepresentation::kWord32,
- instance_type);
+ VARIABLE(var_holder, MachineRepresentation::kTagged, receiver);
+ VARIABLE(var_holder_map, MachineRepresentation::kTagged, map);
+ VARIABLE(var_holder_instance_type, MachineRepresentation::kWord32,
+ instance_type);
Variable* merged_variables[] = {&var_holder, &var_holder_map,
&var_holder_instance_type};
Label loop(this, arraysize(merged_variables), merged_variables);
Goto(&loop);
- Bind(&loop);
+ BIND(&loop);
{
Label next_proto(this);
lookup_element_in_holder(receiver, var_holder.value(),
var_holder_map.value(),
var_holder_instance_type.value(),
var_index.value(), &next_proto, if_bailout);
- Bind(&next_proto);
+ BIND(&next_proto);
Node* proto = LoadMapPrototype(var_holder_map.value());
Label if_not_null(this);
Branch(WordEqual(proto, NullConstant()), if_end, &if_not_null);
- Bind(&if_not_null);
+ BIND(&if_not_null);
Node* map = LoadMap(proto);
Node* instance_type = LoadMapInstanceType(map);
@@ -5390,7 +5563,7 @@ void CodeStubAssembler::TryPrototypeChainLookup(
Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable,
Node* object) {
- Variable var_result(this, MachineRepresentation::kTagged);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
Label return_false(this), return_true(this),
return_runtime(this, Label::kDeferred), return_result(this);
@@ -5414,7 +5587,7 @@ Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable,
&instanceof_cache_miss);
var_result.Bind(LoadRoot(Heap::kInstanceofCacheAnswerRootIndex));
Goto(&return_result);
- Bind(&instanceof_cache_miss);
+ BIND(&instanceof_cache_miss);
}
// Goto runtime if {callable} is a Smi.
@@ -5444,8 +5617,8 @@ Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable,
LoadObjectField(callable, JSFunction::kPrototypeOrInitialMapOffset);
{
Label callable_prototype_valid(this);
- Variable var_callable_prototype(this, MachineRepresentation::kTagged,
- callable_prototype);
+ VARIABLE(var_callable_prototype, MachineRepresentation::kTagged,
+ callable_prototype);
// Resolve the "prototype" if the {callable} has an initial map. Afterwards
// the {callable_prototype} will be either the JSReceiver prototype object
@@ -5459,7 +5632,7 @@ Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable,
var_callable_prototype.Bind(
LoadObjectField(callable_prototype, Map::kPrototypeOffset));
Goto(&callable_prototype_valid);
- Bind(&callable_prototype_valid);
+ BIND(&callable_prototype_valid);
callable_prototype = var_callable_prototype.value();
}
@@ -5469,10 +5642,10 @@ Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable,
StoreRoot(Heap::kInstanceofCacheMapRootIndex, object_map);
// Loop through the prototype chain looking for the {callable} prototype.
- Variable var_object_map(this, MachineRepresentation::kTagged, object_map);
+ VARIABLE(var_object_map, MachineRepresentation::kTagged, object_map);
Label loop(this, &var_object_map);
Goto(&loop);
- Bind(&loop);
+ BIND(&loop);
{
Node* object_map = var_object_map.value();
@@ -5499,17 +5672,17 @@ Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable,
Goto(&loop);
}
- Bind(&return_true);
+ BIND(&return_true);
StoreRoot(Heap::kInstanceofCacheAnswerRootIndex, BooleanConstant(true));
var_result.Bind(BooleanConstant(true));
Goto(&return_result);
- Bind(&return_false);
+ BIND(&return_false);
StoreRoot(Heap::kInstanceofCacheAnswerRootIndex, BooleanConstant(false));
var_result.Bind(BooleanConstant(false));
Goto(&return_result);
- Bind(&return_runtime);
+ BIND(&return_runtime);
{
// Invalidate the global instanceof cache.
StoreRoot(Heap::kInstanceofCacheFunctionRootIndex, SmiConstant(0));
@@ -5519,7 +5692,7 @@ Node* CodeStubAssembler::OrdinaryHasInstance(Node* context, Node* callable,
}
Goto(&return_result);
- Bind(&return_result);
+ BIND(&return_result);
return var_result.value();
}
@@ -5574,27 +5747,14 @@ void CodeStubAssembler::UpdateFeedback(Node* feedback, Node* feedback_vector,
}
Node* CodeStubAssembler::LoadReceiverMap(Node* receiver) {
- Variable var_receiver_map(this, MachineRepresentation::kTagged);
- Label load_smi_map(this, Label::kDeferred), load_receiver_map(this),
- if_result(this);
-
- Branch(TaggedIsSmi(receiver), &load_smi_map, &load_receiver_map);
- Bind(&load_smi_map);
- {
- var_receiver_map.Bind(LoadRoot(Heap::kHeapNumberMapRootIndex));
- Goto(&if_result);
- }
- Bind(&load_receiver_map);
- {
- var_receiver_map.Bind(LoadMap(receiver));
- Goto(&if_result);
- }
- Bind(&if_result);
- return var_receiver_map.value();
+ return Select(TaggedIsSmi(receiver),
+ [=] { return LoadRoot(Heap::kHeapNumberMapRootIndex); },
+ [=] { return LoadMap(receiver); },
+ MachineRepresentation::kTagged);
}
Node* CodeStubAssembler::TryToIntptr(Node* key, Label* miss) {
- Variable var_intptr_key(this, MachineType::PointerRepresentation());
+ VARIABLE(var_intptr_key, MachineType::PointerRepresentation());
Label done(this, &var_intptr_key), key_is_smi(this);
GotoIf(TaggedIsSmi(key), &key_is_smi);
// Try to convert a heap number to a Smi.
@@ -5607,13 +5767,13 @@ Node* CodeStubAssembler::TryToIntptr(Node* key, Label* miss) {
Goto(&done);
}
- Bind(&key_is_smi);
+ BIND(&key_is_smi);
{
var_intptr_key.Bind(SmiUntag(key));
Goto(&done);
}
- Bind(&done);
+ BIND(&done);
return var_intptr_key.value();
}
@@ -5654,7 +5814,7 @@ Node* CodeStubAssembler::EmitKeyedSloppyArguments(Node* receiver, Node* key,
Node* elements = LoadElements(receiver);
Node* elements_length = LoadAndUntagFixedArrayBaseLength(elements);
- Variable var_result(this, MachineRepresentation::kTagged);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
if (!is_load) {
var_result.Bind(value);
}
@@ -5668,7 +5828,7 @@ Node* CodeStubAssembler::EmitKeyedSloppyArguments(Node* receiver, Node* key,
LoadFixedArrayElement(elements, IntPtrAdd(key, intptr_two));
Branch(WordEqual(mapped_index, TheHoleConstant()), &if_unmapped, &if_mapped);
- Bind(&if_mapped);
+ BIND(&if_mapped);
{
CSA_ASSERT(this, TaggedIsSmi(mapped_index));
mapped_index = SmiUntag(mapped_index);
@@ -5688,7 +5848,7 @@ Node* CodeStubAssembler::EmitKeyedSloppyArguments(Node* receiver, Node* key,
Goto(&end);
}
- Bind(&if_unmapped);
+ BIND(&if_unmapped);
{
Node* backing_store = LoadFixedArrayElement(elements, 1);
GotoIf(WordNotEqual(LoadMap(backing_store), FixedArrayMapConstant()),
@@ -5709,7 +5869,7 @@ Node* CodeStubAssembler::EmitKeyedSloppyArguments(Node* receiver, Node* key,
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
return var_result.value();
}
@@ -5780,19 +5940,19 @@ Node* CodeStubAssembler::Int32ToUint8Clamped(Node* int32_value) {
Label done(this);
Node* int32_zero = Int32Constant(0);
Node* int32_255 = Int32Constant(255);
- Variable var_value(this, MachineRepresentation::kWord32, int32_value);
+ VARIABLE(var_value, MachineRepresentation::kWord32, int32_value);
GotoIf(Uint32LessThanOrEqual(int32_value, int32_255), &done);
var_value.Bind(int32_zero);
GotoIf(Int32LessThan(int32_value, int32_zero), &done);
var_value.Bind(int32_255);
Goto(&done);
- Bind(&done);
+ BIND(&done);
return var_value.value();
}
Node* CodeStubAssembler::Float64ToUint8Clamped(Node* float64_value) {
Label done(this);
- Variable var_value(this, MachineRepresentation::kWord32, Int32Constant(0));
+ VARIABLE(var_value, MachineRepresentation::kWord32, Int32Constant(0));
GotoIf(Float64LessThanOrEqual(float64_value, Float64Constant(0.0)), &done);
var_value.Bind(Int32Constant(255));
GotoIf(Float64LessThanOrEqual(Float64Constant(255.0), float64_value), &done);
@@ -5801,7 +5961,7 @@ Node* CodeStubAssembler::Float64ToUint8Clamped(Node* float64_value) {
var_value.Bind(TruncateFloat64ToWord32(rounded_value));
Goto(&done);
}
- Bind(&done);
+ BIND(&done);
return var_value.value();
}
@@ -5831,7 +5991,7 @@ Node* CodeStubAssembler::PrepareValueForWriteToTypedArray(
return nullptr;
}
- Variable var_result(this, rep);
+ VARIABLE(var_result, rep);
Label done(this, &var_result), if_smi(this);
GotoIf(TaggedIsSmi(input), &if_smi);
// Try to convert a heap number to a Smi.
@@ -5853,7 +6013,7 @@ Node* CodeStubAssembler::PrepareValueForWriteToTypedArray(
Goto(&done);
}
- Bind(&if_smi);
+ BIND(&if_smi);
{
Node* value = SmiToWord32(input);
if (rep == MachineRepresentation::kFloat32) {
@@ -5870,7 +6030,7 @@ Node* CodeStubAssembler::PrepareValueForWriteToTypedArray(
Goto(&done);
}
- Bind(&done);
+ BIND(&done);
return var_result.value();
}
@@ -5931,7 +6091,7 @@ void CodeStubAssembler::EmitElementStore(Node* object, Node* key, Node* value,
StoreElement(backing_store, elements_kind, key, value, parameter_mode);
Goto(&done);
- Bind(&done);
+ BIND(&done);
return;
}
DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
@@ -5970,7 +6130,7 @@ Node* CodeStubAssembler::CheckForCapacityGrow(Node* object, Node* elements,
Node* key, ParameterMode mode,
bool is_js_array,
Label* bailout) {
- Variable checked_elements(this, MachineRepresentation::kTagged);
+ VARIABLE(checked_elements, MachineRepresentation::kTagged);
Label grow_case(this), no_grow_case(this), done(this);
Node* condition;
@@ -5981,7 +6141,7 @@ Node* CodeStubAssembler::CheckForCapacityGrow(Node* object, Node* elements,
}
Branch(condition, &grow_case, &no_grow_case);
- Bind(&grow_case);
+ BIND(&grow_case);
{
Node* current_capacity =
TaggedToParameter(LoadFixedArrayBaseLength(elements), mode);
@@ -5997,7 +6157,7 @@ Node* CodeStubAssembler::CheckForCapacityGrow(Node* object, Node* elements,
checked_elements.Bind(new_elements);
Goto(&fits_capacity);
}
- Bind(&fits_capacity);
+ BIND(&fits_capacity);
if (is_js_array) {
Node* new_length = IntPtrAdd(key, IntPtrOrSmiConstant(1, mode));
@@ -6007,14 +6167,14 @@ Node* CodeStubAssembler::CheckForCapacityGrow(Node* object, Node* elements,
Goto(&done);
}
- Bind(&no_grow_case);
+ BIND(&no_grow_case);
{
GotoIfNot(UintPtrLessThan(key, length), bailout);
checked_elements.Bind(elements);
Goto(&done);
}
- Bind(&done);
+ BIND(&done);
return checked_elements.value();
}
@@ -6022,7 +6182,7 @@ Node* CodeStubAssembler::CopyElementsOnWrite(Node* object, Node* elements,
ElementsKind kind, Node* length,
ParameterMode mode,
Label* bailout) {
- Variable new_elements_var(this, MachineRepresentation::kTagged, elements);
+ VARIABLE(new_elements_var, MachineRepresentation::kTagged, elements);
Label done(this);
GotoIfNot(
@@ -6038,7 +6198,7 @@ Node* CodeStubAssembler::CopyElementsOnWrite(Node* object, Node* elements,
Goto(&done);
}
- Bind(&done);
+ BIND(&done);
return new_elements_var.value();
}
@@ -6073,7 +6233,7 @@ void CodeStubAssembler::TransitionElementsKind(Node* object, Node* map,
GrowElementsCapacity(object, elements, from_kind, to_kind, array_length,
elements_length, mode, bailout);
Goto(&done);
- Bind(&done);
+ BIND(&done);
}
StoreMap(object, map);
@@ -6122,21 +6282,21 @@ void CodeStubAssembler::TrapAllocationMemento(Node* object,
// If top is on the same page as the current object, we need to check whether
// we are below top.
- Bind(&top_check);
+ BIND(&top_check);
{
Branch(UintPtrGreaterThanOrEqual(memento_last_word, new_space_top),
&no_memento_found, &map_check);
}
// Memento map check.
- Bind(&map_check);
+ BIND(&map_check);
{
Node* memento_map = LoadObjectField(object, kMementoMapOffset);
Branch(
WordEqual(memento_map, LoadRoot(Heap::kAllocationMementoMapRootIndex)),
memento_found, &no_memento_found);
}
- Bind(&no_memento_found);
+ BIND(&no_memento_found);
Comment("] TrapAllocationMemento");
}
@@ -6144,73 +6304,6 @@ Node* CodeStubAssembler::PageFromAddress(Node* address) {
return WordAnd(address, IntPtrConstant(~Page::kPageAlignmentMask));
}
-Node* CodeStubAssembler::EnumLength(Node* map) {
- CSA_ASSERT(this, IsMap(map));
- Node* bitfield_3 = LoadMapBitField3(map);
- Node* enum_length = DecodeWordFromWord32<Map::EnumLengthBits>(bitfield_3);
- return SmiTag(enum_length);
-}
-
-void CodeStubAssembler::CheckEnumCache(Node* receiver, Label* use_cache,
- Label* use_runtime) {
- Variable current_js_object(this, MachineRepresentation::kTagged, receiver);
-
- Variable current_map(this, MachineRepresentation::kTagged,
- LoadMap(current_js_object.value()));
-
- // These variables are updated in the loop below.
- Variable* loop_vars[2] = {&current_js_object, &current_map};
- Label loop(this, 2, loop_vars), next(this);
-
- // Check if the enum length field is properly initialized, indicating that
- // there is an enum cache.
- {
- Node* invalid_enum_cache_sentinel =
- SmiConstant(Smi::FromInt(kInvalidEnumCacheSentinel));
- Node* enum_length = EnumLength(current_map.value());
- Branch(WordEqual(enum_length, invalid_enum_cache_sentinel), use_runtime,
- &loop);
- }
-
- // Check that there are no elements. |current_js_object| contains
- // the current JS object we've reached through the prototype chain.
- Bind(&loop);
- {
- Label if_elements(this), if_no_elements(this);
- Node* elements = LoadElements(current_js_object.value());
- Node* empty_fixed_array = LoadRoot(Heap::kEmptyFixedArrayRootIndex);
- // Check that there are no elements.
- Branch(WordEqual(elements, empty_fixed_array), &if_no_elements,
- &if_elements);
- Bind(&if_elements);
- {
- // Second chance, the object may be using the empty slow element
- // dictionary.
- Node* slow_empty_dictionary =
- LoadRoot(Heap::kEmptySlowElementDictionaryRootIndex);
- Branch(WordNotEqual(elements, slow_empty_dictionary), use_runtime,
- &if_no_elements);
- }
-
- Bind(&if_no_elements);
- {
- // Update map prototype.
- current_js_object.Bind(LoadMapPrototype(current_map.value()));
- Branch(WordEqual(current_js_object.value(), NullConstant()), use_cache,
- &next);
- }
- }
-
- Bind(&next);
- {
- // For all objects but the receiver, check that the cache is empty.
- current_map.Bind(LoadMap(current_js_object.value()));
- Node* enum_length = EnumLength(current_map.value());
- Node* zero_constant = SmiConstant(Smi::kZero);
- Branch(WordEqual(enum_length, zero_constant), &loop, use_runtime);
- }
-}
-
Node* CodeStubAssembler::CreateAllocationSiteInFeedbackVector(
Node* feedback_vector, Node* slot) {
Node* size = IntPtrConstant(AllocationSite::kSize);
@@ -6281,7 +6374,7 @@ Node* CodeStubAssembler::BuildFastLoop(
MachineRepresentation index_rep = (parameter_mode == INTPTR_PARAMETERS)
? MachineType::PointerRepresentation()
: MachineRepresentation::kTaggedSigned;
- Variable var(this, index_rep, start_index);
+ VARIABLE(var, index_rep, start_index);
VariableList vars_copy(vars, zone());
vars_copy.Add(&var, zone());
Label loop(this, vars_copy);
@@ -6294,7 +6387,7 @@ Node* CodeStubAssembler::BuildFastLoop(
// it from the pre-header). The extra branch is slower in the case that the
// loop actually iterates.
Branch(WordEqual(var.value(), end_index), &after_loop, &loop);
- Bind(&loop);
+ BIND(&loop);
{
if (advance_mode == IndexAdvanceMode::kPre) {
Increment(var, increment, parameter_mode);
@@ -6305,7 +6398,7 @@ Node* CodeStubAssembler::BuildFastLoop(
}
Branch(WordNotEqual(var.value(), end_index), &loop, &after_loop);
}
- Bind(&after_loop);
+ BIND(&after_loop);
return var.value();
}
@@ -6391,24 +6484,24 @@ void CodeStubAssembler::BranchIfNumericRelationalComparison(
RelationalComparisonMode mode, Node* lhs, Node* rhs, Label* if_true,
Label* if_false) {
Label end(this);
- Variable result(this, MachineRepresentation::kTagged);
+ VARIABLE(result, MachineRepresentation::kTagged);
// Shared entry for floating point comparison.
Label do_fcmp(this);
- Variable var_fcmp_lhs(this, MachineRepresentation::kFloat64),
- var_fcmp_rhs(this, MachineRepresentation::kFloat64);
+ VARIABLE(var_fcmp_lhs, MachineRepresentation::kFloat64);
+ VARIABLE(var_fcmp_rhs, MachineRepresentation::kFloat64);
// Check if the {lhs} is a Smi or a HeapObject.
Label if_lhsissmi(this), if_lhsisnotsmi(this);
Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
- Bind(&if_lhsissmi);
+ BIND(&if_lhsissmi);
{
// Check if {rhs} is a Smi or a HeapObject.
Label if_rhsissmi(this), if_rhsisnotsmi(this);
Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
- Bind(&if_rhsissmi);
+ BIND(&if_rhsissmi);
{
// Both {lhs} and {rhs} are Smi, so just perform a fast Smi comparison.
switch (mode) {
@@ -6427,7 +6520,7 @@ void CodeStubAssembler::BranchIfNumericRelationalComparison(
}
}
- Bind(&if_rhsisnotsmi);
+ BIND(&if_rhsisnotsmi);
{
CSA_ASSERT(this, IsHeapNumberMap(LoadMap(rhs)));
// Convert the {lhs} and {rhs} to floating point values, and
@@ -6438,7 +6531,7 @@ void CodeStubAssembler::BranchIfNumericRelationalComparison(
}
}
- Bind(&if_lhsisnotsmi);
+ BIND(&if_lhsisnotsmi);
{
CSA_ASSERT(this, IsHeapNumberMap(LoadMap(lhs)));
@@ -6446,7 +6539,7 @@ void CodeStubAssembler::BranchIfNumericRelationalComparison(
Label if_rhsissmi(this), if_rhsisnotsmi(this);
Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
- Bind(&if_rhsissmi);
+ BIND(&if_rhsissmi);
{
// Convert the {lhs} and {rhs} to floating point values, and
// perform a floating point comparison.
@@ -6455,7 +6548,7 @@ void CodeStubAssembler::BranchIfNumericRelationalComparison(
Goto(&do_fcmp);
}
- Bind(&if_rhsisnotsmi);
+ BIND(&if_rhsisnotsmi);
{
CSA_ASSERT(this, IsHeapNumberMap(LoadMap(rhs)));
@@ -6467,7 +6560,7 @@ void CodeStubAssembler::BranchIfNumericRelationalComparison(
}
}
- Bind(&do_fcmp);
+ BIND(&do_fcmp);
{
// Load the {lhs} and {rhs} floating point values.
Node* lhs = var_fcmp_lhs.value();
@@ -6495,28 +6588,28 @@ void CodeStubAssembler::GotoUnlessNumberLessThan(Node* lhs, Node* rhs,
Label* if_false) {
Label if_true(this);
BranchIfNumericRelationalComparison(kLessThan, lhs, rhs, &if_true, if_false);
- Bind(&if_true);
+ BIND(&if_true);
}
Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
Node* lhs, Node* rhs,
Node* context) {
Label return_true(this), return_false(this), end(this);
- Variable result(this, MachineRepresentation::kTagged);
+ VARIABLE(result, MachineRepresentation::kTagged);
// Shared entry for floating point comparison.
Label do_fcmp(this);
- Variable var_fcmp_lhs(this, MachineRepresentation::kFloat64),
- var_fcmp_rhs(this, MachineRepresentation::kFloat64);
+ VARIABLE(var_fcmp_lhs, MachineRepresentation::kFloat64);
+ VARIABLE(var_fcmp_rhs, MachineRepresentation::kFloat64);
// We might need to loop several times due to ToPrimitive and/or ToNumber
// conversions.
- Variable var_lhs(this, MachineRepresentation::kTagged, lhs),
- var_rhs(this, MachineRepresentation::kTagged, rhs);
+ VARIABLE(var_lhs, MachineRepresentation::kTagged, lhs);
+ VARIABLE(var_rhs, MachineRepresentation::kTagged, rhs);
Variable* loop_vars[2] = {&var_lhs, &var_rhs};
Label loop(this, 2, loop_vars);
Goto(&loop);
- Bind(&loop);
+ BIND(&loop);
{
// Load the current {lhs} and {rhs} values.
lhs = var_lhs.value();
@@ -6526,13 +6619,13 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
Label if_lhsissmi(this), if_lhsisnotsmi(this);
Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
- Bind(&if_lhsissmi);
+ BIND(&if_lhsissmi);
{
// Check if {rhs} is a Smi or a HeapObject.
Label if_rhsissmi(this), if_rhsisnotsmi(this);
Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
- Bind(&if_rhsissmi);
+ BIND(&if_rhsissmi);
{
// Both {lhs} and {rhs} are Smi, so just perform a fast Smi comparison.
switch (mode) {
@@ -6551,7 +6644,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
}
}
- Bind(&if_rhsisnotsmi);
+ BIND(&if_rhsisnotsmi);
{
// Load the map of {rhs}.
Node* rhs_map = LoadMap(rhs);
@@ -6560,7 +6653,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
Label if_rhsisnumber(this), if_rhsisnotnumber(this, Label::kDeferred);
Branch(IsHeapNumberMap(rhs_map), &if_rhsisnumber, &if_rhsisnotnumber);
- Bind(&if_rhsisnumber);
+ BIND(&if_rhsisnumber);
{
// Convert the {lhs} and {rhs} to floating point values, and
// perform a floating point comparison.
@@ -6569,7 +6662,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
Goto(&do_fcmp);
}
- Bind(&if_rhsisnotnumber);
+ BIND(&if_rhsisnotnumber);
{
// Convert the {rhs} to a Number; we don't need to perform the
// dedicated ToPrimitive(rhs, hint Number) operation, as the
@@ -6582,7 +6675,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
}
}
- Bind(&if_lhsisnotsmi);
+ BIND(&if_lhsisnotsmi);
{
// Load the map of {lhs}.
Node* lhs_map = LoadMap(lhs);
@@ -6591,13 +6684,13 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
Label if_rhsissmi(this), if_rhsisnotsmi(this);
Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
- Bind(&if_rhsissmi);
+ BIND(&if_rhsissmi);
{
// Check if the {lhs} is a HeapNumber.
Label if_lhsisnumber(this), if_lhsisnotnumber(this, Label::kDeferred);
Branch(IsHeapNumberMap(lhs_map), &if_lhsisnumber, &if_lhsisnotnumber);
- Bind(&if_lhsisnumber);
+ BIND(&if_lhsisnumber);
{
// Convert the {lhs} and {rhs} to floating point values, and
// perform a floating point comparison.
@@ -6606,7 +6699,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
Goto(&do_fcmp);
}
- Bind(&if_lhsisnotnumber);
+ BIND(&if_lhsisnotnumber);
{
// Convert the {lhs} to a Number; we don't need to perform the
// dedicated ToPrimitive(lhs, hint Number) operation, as the
@@ -6618,7 +6711,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
}
}
- Bind(&if_rhsisnotsmi);
+ BIND(&if_rhsisnotsmi);
{
// Load the map of {rhs}.
Node* rhs_map = LoadMap(rhs);
@@ -6627,14 +6720,14 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
Label if_lhsisnumber(this), if_lhsisnotnumber(this);
Branch(IsHeapNumberMap(lhs_map), &if_lhsisnumber, &if_lhsisnotnumber);
- Bind(&if_lhsisnumber);
+ BIND(&if_lhsisnumber);
{
// Check if {rhs} is also a HeapNumber.
Label if_rhsisnumber(this), if_rhsisnotnumber(this, Label::kDeferred);
Branch(WordEqual(lhs_map, rhs_map), &if_rhsisnumber,
&if_rhsisnotnumber);
- Bind(&if_rhsisnumber);
+ BIND(&if_rhsisnumber);
{
// Convert the {lhs} and {rhs} to floating point values, and
// perform a floating point comparison.
@@ -6643,7 +6736,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
Goto(&do_fcmp);
}
- Bind(&if_rhsisnotnumber);
+ BIND(&if_rhsisnotnumber);
{
// Convert the {rhs} to a Number; we don't need to perform
// dedicated ToPrimitive(rhs, hint Number) operation, as the
@@ -6655,7 +6748,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
}
}
- Bind(&if_lhsisnotnumber);
+ BIND(&if_lhsisnotnumber);
{
// Load the instance type of {lhs}.
Node* lhs_instance_type = LoadMapInstanceType(lhs_map);
@@ -6665,7 +6758,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
Branch(IsStringInstanceType(lhs_instance_type), &if_lhsisstring,
&if_lhsisnotstring);
- Bind(&if_lhsisstring);
+ BIND(&if_lhsisstring);
{
// Load the instance type of {rhs}.
Node* rhs_instance_type = LoadMapInstanceType(rhs_map);
@@ -6676,7 +6769,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
Branch(IsStringInstanceType(rhs_instance_type), &if_rhsisstring,
&if_rhsisnotstring);
- Bind(&if_rhsisstring);
+ BIND(&if_rhsisstring);
{
// Both {lhs} and {rhs} are strings.
switch (mode) {
@@ -6706,7 +6799,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
}
}
- Bind(&if_rhsisnotstring);
+ BIND(&if_rhsisnotstring);
{
// The {lhs} is a String, while {rhs} is neither a Number nor a
// String, so we need to call ToPrimitive(rhs, hint Number) if
@@ -6718,7 +6811,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
Branch(IsJSReceiverInstanceType(rhs_instance_type),
&if_rhsisreceiver, &if_rhsisnotreceiver);
- Bind(&if_rhsisreceiver);
+ BIND(&if_rhsisreceiver);
{
// Convert {rhs} to a primitive first passing Number hint.
Callable callable = CodeFactory::NonPrimitiveToPrimitive(
@@ -6727,7 +6820,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
Goto(&loop);
}
- Bind(&if_rhsisnotreceiver);
+ BIND(&if_rhsisnotreceiver);
{
// Convert both {lhs} and {rhs} to Number.
Callable callable = CodeFactory::ToNumber(isolate());
@@ -6738,7 +6831,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
}
}
- Bind(&if_lhsisnotstring);
+ BIND(&if_lhsisnotstring);
{
// The {lhs} is neither a Number nor a String, so we need to call
// ToPrimitive(lhs, hint Number) if {lhs} is a receiver or
@@ -6749,7 +6842,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
Branch(IsJSReceiverInstanceType(lhs_instance_type),
&if_lhsisreceiver, &if_lhsisnotreceiver);
- Bind(&if_lhsisreceiver);
+ BIND(&if_lhsisreceiver);
{
// Convert {lhs} to a primitive first passing Number hint.
Callable callable = CodeFactory::NonPrimitiveToPrimitive(
@@ -6758,7 +6851,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
Goto(&loop);
}
- Bind(&if_lhsisnotreceiver);
+ BIND(&if_lhsisnotreceiver);
{
// Convert both {lhs} and {rhs} to Number.
Callable callable = CodeFactory::ToNumber(isolate());
@@ -6772,7 +6865,7 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
}
}
- Bind(&do_fcmp);
+ BIND(&do_fcmp);
{
// Load the {lhs} and {rhs} floating point values.
Node* lhs = var_fcmp_lhs.value();
@@ -6796,19 +6889,19 @@ Node* CodeStubAssembler::RelationalComparison(RelationalComparisonMode mode,
}
}
- Bind(&return_true);
+ BIND(&return_true);
{
result.Bind(BooleanConstant(true));
Goto(&end);
}
- Bind(&return_false);
+ BIND(&return_false);
{
result.Bind(BooleanConstant(false));
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
return result.value();
}
@@ -6828,7 +6921,7 @@ void GenerateEqual_Same(CodeStubAssembler* assembler, Node* value,
assembler->Branch(assembler->TaggedIsSmi(value), &if_valueissmi,
&if_valueisnotsmi);
- assembler->Bind(&if_valueisnotsmi);
+ assembler->BIND(&if_valueisnotsmi);
{
// Load the map of {value}.
Node* value_map = assembler->LoadMap(value);
@@ -6838,7 +6931,7 @@ void GenerateEqual_Same(CodeStubAssembler* assembler, Node* value,
assembler->Branch(assembler->IsHeapNumberMap(value_map), &if_valueisnumber,
&if_valueisnotnumber);
- assembler->Bind(&if_valueisnumber);
+ assembler->BIND(&if_valueisnumber);
{
// Convert {value} (and therefore {rhs}) to floating point value.
Node* value_value = assembler->LoadHeapNumberValue(value);
@@ -6847,18 +6940,17 @@ void GenerateEqual_Same(CodeStubAssembler* assembler, Node* value,
assembler->BranchIfFloat64IsNaN(value_value, if_notequal, if_equal);
}
- assembler->Bind(&if_valueisnotnumber);
+ assembler->BIND(&if_valueisnotnumber);
assembler->Goto(if_equal);
}
- assembler->Bind(&if_valueissmi);
+ assembler->BIND(&if_valueissmi);
assembler->Goto(if_equal);
}
} // namespace
// ES6 section 7.2.12 Abstract Equality Comparison
-Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
- Node* context) {
+Node* CodeStubAssembler::Equal(Node* lhs, Node* rhs, Node* context) {
// This is a slightly optimized version of Object::Equals represented as
// scheduled TurboFan graph utilizing the CodeStubAssembler. Whenever you
// change something functionality wise in here, remember to update the
@@ -6866,21 +6958,21 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Label if_equal(this), if_notequal(this),
do_rhsstringtonumber(this, Label::kDeferred), end(this);
- Variable result(this, MachineRepresentation::kTagged);
+ VARIABLE(result, MachineRepresentation::kTagged);
// Shared entry for floating point comparison.
Label do_fcmp(this);
- Variable var_fcmp_lhs(this, MachineRepresentation::kFloat64),
- var_fcmp_rhs(this, MachineRepresentation::kFloat64);
+ VARIABLE(var_fcmp_lhs, MachineRepresentation::kFloat64);
+ VARIABLE(var_fcmp_rhs, MachineRepresentation::kFloat64);
// We might need to loop several times due to ToPrimitive and/or ToNumber
// conversions.
- Variable var_lhs(this, MachineRepresentation::kTagged, lhs),
- var_rhs(this, MachineRepresentation::kTagged, rhs);
+ VARIABLE(var_lhs, MachineRepresentation::kTagged, lhs);
+ VARIABLE(var_rhs, MachineRepresentation::kTagged, rhs);
Variable* loop_vars[2] = {&var_lhs, &var_rhs};
Label loop(this, 2, loop_vars);
Goto(&loop);
- Bind(&loop);
+ BIND(&loop);
{
// Load the current {lhs} and {rhs} values.
lhs = var_lhs.value();
@@ -6890,31 +6982,31 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Label if_same(this), if_notsame(this);
Branch(WordEqual(lhs, rhs), &if_same, &if_notsame);
- Bind(&if_same);
+ BIND(&if_same);
{
// The {lhs} and {rhs} reference the exact same value, yet we need special
// treatment for HeapNumber, as NaN is not equal to NaN.
GenerateEqual_Same(this, lhs, &if_equal, &if_notequal);
}
- Bind(&if_notsame);
+ BIND(&if_notsame);
{
// Check if {lhs} is a Smi or a HeapObject.
Label if_lhsissmi(this), if_lhsisnotsmi(this);
Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
- Bind(&if_lhsissmi);
+ BIND(&if_lhsissmi);
{
// Check if {rhs} is a Smi or a HeapObject.
Label if_rhsissmi(this), if_rhsisnotsmi(this);
Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
- Bind(&if_rhsissmi);
+ BIND(&if_rhsissmi);
// We have already checked for {lhs} and {rhs} being the same value, so
// if both are Smis when we get here they must not be equal.
Goto(&if_notequal);
- Bind(&if_rhsisnotsmi);
+ BIND(&if_rhsisnotsmi);
{
// Load the map of {rhs}.
Node* rhs_map = LoadMap(rhs);
@@ -6923,7 +7015,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Label if_rhsisnumber(this), if_rhsisnotnumber(this);
Branch(IsHeapNumberMap(rhs_map), &if_rhsisnumber, &if_rhsisnotnumber);
- Bind(&if_rhsisnumber);
+ BIND(&if_rhsisnumber);
{
// Convert {lhs} and {rhs} to floating point values, and
// perform a floating point comparison.
@@ -6932,7 +7024,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Goto(&do_fcmp);
}
- Bind(&if_rhsisnotnumber);
+ BIND(&if_rhsisnotnumber);
{
// Load the instance type of the {rhs}.
Node* rhs_instance_type = LoadMapInstanceType(rhs_map);
@@ -6943,7 +7035,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Branch(IsStringInstanceType(rhs_instance_type), &if_rhsisstring,
&if_rhsisnotstring);
- Bind(&if_rhsisstring);
+ BIND(&if_rhsisstring);
{
// The {rhs} is a String and the {lhs} is a Smi; we need
// to convert the {rhs} to a Number and compare the output to
@@ -6951,21 +7043,21 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Goto(&do_rhsstringtonumber);
}
- Bind(&if_rhsisnotstring);
+ BIND(&if_rhsisnotstring);
{
// Check if the {rhs} is a Boolean.
Label if_rhsisboolean(this), if_rhsisnotboolean(this);
Branch(IsBooleanMap(rhs_map), &if_rhsisboolean,
&if_rhsisnotboolean);
- Bind(&if_rhsisboolean);
+ BIND(&if_rhsisboolean);
{
// The {rhs} is a Boolean, load its number value.
var_rhs.Bind(LoadObjectField(rhs, Oddball::kToNumberOffset));
Goto(&loop);
}
- Bind(&if_rhsisnotboolean);
+ BIND(&if_rhsisnotboolean);
{
// Check if the {rhs} is a Receiver.
STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
@@ -6974,7 +7066,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Branch(IsJSReceiverInstanceType(rhs_instance_type),
&if_rhsisreceiver, &if_rhsisnotreceiver);
- Bind(&if_rhsisreceiver);
+ BIND(&if_rhsisreceiver);
{
// Convert {rhs} to a primitive first (passing no hint).
Callable callable =
@@ -6983,7 +7075,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Goto(&loop);
}
- Bind(&if_rhsisnotreceiver);
+ BIND(&if_rhsisnotreceiver);
Goto(&if_notequal);
}
}
@@ -6991,13 +7083,13 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
}
}
- Bind(&if_lhsisnotsmi);
+ BIND(&if_lhsisnotsmi);
{
// Check if {rhs} is a Smi or a HeapObject.
Label if_rhsissmi(this), if_rhsisnotsmi(this);
Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
- Bind(&if_rhsissmi);
+ BIND(&if_rhsissmi);
{
// The {lhs} is a HeapObject and the {rhs} is a Smi; swapping {lhs}
// and {rhs} is not observable and doesn't matter for the result, so
@@ -7008,7 +7100,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Goto(&loop);
}
- Bind(&if_rhsisnotsmi);
+ BIND(&if_rhsisnotsmi);
{
Label if_lhsisstring(this), if_lhsisnumber(this),
if_lhsissymbol(this), if_lhsisoddball(this),
@@ -7045,7 +7137,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
delete case_labels[i];
}
- Bind(&if_lhsisstring);
+ BIND(&if_lhsisstring);
{
// Check if {rhs} is also a String.
Label if_rhsisstring(this, Label::kDeferred),
@@ -7053,18 +7145,16 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Branch(IsStringInstanceType(rhs_instance_type), &if_rhsisstring,
&if_rhsisnotstring);
- Bind(&if_rhsisstring);
+ BIND(&if_rhsisstring);
{
// Both {lhs} and {rhs} are of type String, just do the
// string comparison then.
- Callable callable = (mode == kDontNegateResult)
- ? CodeFactory::StringEqual(isolate())
- : CodeFactory::StringNotEqual(isolate());
+ Callable callable = CodeFactory::StringEqual(isolate());
result.Bind(CallStub(callable, context, lhs, rhs));
Goto(&end);
}
- Bind(&if_rhsisnotstring);
+ BIND(&if_rhsisnotstring);
{
// The {lhs} is a String and the {rhs} is some other HeapObject.
// Swapping {lhs} and {rhs} is not observable and doesn't matter
@@ -7076,14 +7166,14 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
}
}
- Bind(&if_lhsisnumber);
+ BIND(&if_lhsisnumber);
{
// Check if {rhs} is also a HeapNumber.
Label if_rhsisnumber(this), if_rhsisnotnumber(this);
Branch(Word32Equal(lhs_instance_type, rhs_instance_type),
&if_rhsisnumber, &if_rhsisnotnumber);
- Bind(&if_rhsisnumber);
+ BIND(&if_rhsisnumber);
{
// Convert {lhs} and {rhs} to floating point values, and
// perform a floating point comparison.
@@ -7092,7 +7182,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Goto(&do_fcmp);
}
- Bind(&if_rhsisnotnumber);
+ BIND(&if_rhsisnotnumber);
{
// The {lhs} is a Number, the {rhs} is some other HeapObject.
Label if_rhsisstring(this, Label::kDeferred),
@@ -7100,7 +7190,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Branch(IsStringInstanceType(rhs_instance_type), &if_rhsisstring,
&if_rhsisnotstring);
- Bind(&if_rhsisstring);
+ BIND(&if_rhsisstring);
{
// The {rhs} is a String and the {lhs} is a HeapNumber; we need
// to convert the {rhs} to a Number and compare the output to
@@ -7108,7 +7198,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Goto(&do_rhsstringtonumber);
}
- Bind(&if_rhsisnotstring);
+ BIND(&if_rhsisnotstring);
{
// Check if the {rhs} is a JSReceiver.
Label if_rhsisreceiver(this), if_rhsisnotreceiver(this);
@@ -7116,7 +7206,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Branch(IsJSReceiverInstanceType(rhs_instance_type),
&if_rhsisreceiver, &if_rhsisnotreceiver);
- Bind(&if_rhsisreceiver);
+ BIND(&if_rhsisreceiver);
{
// The {lhs} is a Primitive and the {rhs} is a JSReceiver.
// Swapping {lhs} and {rhs} is not observable and doesn't
@@ -7128,14 +7218,14 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Goto(&loop);
}
- Bind(&if_rhsisnotreceiver);
+ BIND(&if_rhsisnotreceiver);
{
// Check if {rhs} is a Boolean.
Label if_rhsisboolean(this), if_rhsisnotboolean(this);
Branch(IsBooleanMap(rhs_map), &if_rhsisboolean,
&if_rhsisnotboolean);
- Bind(&if_rhsisboolean);
+ BIND(&if_rhsisboolean);
{
// The {rhs} is a Boolean, convert it to a Smi first.
var_rhs.Bind(
@@ -7143,14 +7233,14 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Goto(&loop);
}
- Bind(&if_rhsisnotboolean);
+ BIND(&if_rhsisnotboolean);
Goto(&if_notequal);
}
}
}
}
- Bind(&if_lhsisoddball);
+ BIND(&if_lhsisoddball);
{
// The {lhs} is an Oddball and {rhs} is some other HeapObject.
Label if_lhsisboolean(this), if_lhsisnotboolean(this);
@@ -7158,20 +7248,20 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Branch(WordEqual(lhs_map, boolean_map), &if_lhsisboolean,
&if_lhsisnotboolean);
- Bind(&if_lhsisboolean);
+ BIND(&if_lhsisboolean);
{
// The {lhs} is a Boolean, check if {rhs} is also a Boolean.
Label if_rhsisboolean(this), if_rhsisnotboolean(this);
Branch(WordEqual(rhs_map, boolean_map), &if_rhsisboolean,
&if_rhsisnotboolean);
- Bind(&if_rhsisboolean);
+ BIND(&if_rhsisboolean);
{
// Both {lhs} and {rhs} are distinct Boolean values.
Goto(&if_notequal);
}
- Bind(&if_rhsisnotboolean);
+ BIND(&if_rhsisnotboolean);
{
// Convert the {lhs} to a Number first.
var_lhs.Bind(LoadObjectField(lhs, Oddball::kToNumberOffset));
@@ -7179,7 +7269,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
}
}
- Bind(&if_lhsisnotboolean);
+ BIND(&if_lhsisnotboolean);
{
// The {lhs} is either Null or Undefined; check if the {rhs} is
// undetectable (i.e. either also Null or Undefined or some
@@ -7193,7 +7283,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
}
}
- Bind(&if_lhsissymbol);
+ BIND(&if_lhsissymbol);
{
// Check if the {rhs} is a JSReceiver.
Label if_rhsisreceiver(this), if_rhsisnotreceiver(this);
@@ -7201,7 +7291,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Branch(IsJSReceiverInstanceType(rhs_instance_type),
&if_rhsisreceiver, &if_rhsisnotreceiver);
- Bind(&if_rhsisreceiver);
+ BIND(&if_rhsisreceiver);
{
// The {lhs} is a Primitive and the {rhs} is a JSReceiver.
// Swapping {lhs} and {rhs} is not observable and doesn't
@@ -7212,7 +7302,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Goto(&loop);
}
- Bind(&if_rhsisnotreceiver);
+ BIND(&if_rhsisnotreceiver);
{
// The {rhs} is not a JSReceiver and also not the same Symbol
// as the {lhs}, so this is equality check is considered false.
@@ -7220,7 +7310,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
}
}
- Bind(&if_lhsisreceiver);
+ BIND(&if_lhsisreceiver);
{
// Check if the {rhs} is also a JSReceiver.
Label if_rhsisreceiver(this), if_rhsisnotreceiver(this);
@@ -7228,14 +7318,14 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Branch(IsJSReceiverInstanceType(rhs_instance_type),
&if_rhsisreceiver, &if_rhsisnotreceiver);
- Bind(&if_rhsisreceiver);
+ BIND(&if_rhsisreceiver);
{
// Both {lhs} and {rhs} are different JSReceiver references, so
// this cannot be considered equal.
Goto(&if_notequal);
}
- Bind(&if_rhsisnotreceiver);
+ BIND(&if_rhsisnotreceiver);
{
// Check if {rhs} is Null or Undefined (an undetectable check
// is sufficient here, since we already know that {rhs} is not
@@ -7249,7 +7339,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Int32Constant(0)),
&if_rhsisnotundetectable, &if_rhsisundetectable);
- Bind(&if_rhsisundetectable);
+ BIND(&if_rhsisundetectable);
{
// Check if {lhs} is an undetectable JSReceiver.
Node* lhs_bitfield = LoadMapBitField(lhs_map);
@@ -7260,7 +7350,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
&if_notequal, &if_equal);
}
- Bind(&if_rhsisnotundetectable);
+ BIND(&if_rhsisnotundetectable);
{
// The {rhs} is some Primitive different from Null and
// Undefined, need to convert {lhs} to Primitive first.
@@ -7275,7 +7365,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
}
}
- Bind(&do_rhsstringtonumber);
+ BIND(&do_rhsstringtonumber);
{
Callable callable = CodeFactory::StringToNumber(isolate());
var_rhs.Bind(CallStub(callable, context, rhs));
@@ -7283,7 +7373,7 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
}
}
- Bind(&do_fcmp);
+ BIND(&do_fcmp);
{
// Load the {lhs} and {rhs} floating point values.
Node* lhs = var_fcmp_lhs.value();
@@ -7293,24 +7383,23 @@ Node* CodeStubAssembler::Equal(ResultMode mode, Node* lhs, Node* rhs,
Branch(Float64Equal(lhs, rhs), &if_equal, &if_notequal);
}
- Bind(&if_equal);
+ BIND(&if_equal);
{
- result.Bind(BooleanConstant(mode == kDontNegateResult));
+ result.Bind(TrueConstant());
Goto(&end);
}
- Bind(&if_notequal);
+ BIND(&if_notequal);
{
- result.Bind(BooleanConstant(mode == kNegateResult));
+ result.Bind(FalseConstant());
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
return result.value();
}
-Node* CodeStubAssembler::StrictEqual(ResultMode mode, Node* lhs, Node* rhs,
- Node* context) {
+Node* CodeStubAssembler::StrictEqual(Node* lhs, Node* rhs) {
// Here's pseudo-code for the algorithm below in case of kDontNegateResult
// mode; for kNegateResult mode we properly negate the result.
//
@@ -7356,20 +7445,20 @@ Node* CodeStubAssembler::StrictEqual(ResultMode mode, Node* lhs, Node* rhs,
// }
Label if_equal(this), if_notequal(this), end(this);
- Variable result(this, MachineRepresentation::kTagged);
+ VARIABLE(result, MachineRepresentation::kTagged);
// Check if {lhs} and {rhs} refer to the same object.
Label if_same(this), if_notsame(this);
Branch(WordEqual(lhs, rhs), &if_same, &if_notsame);
- Bind(&if_same);
+ BIND(&if_same);
{
// The {lhs} and {rhs} reference the exact same value, yet we need special
// treatment for HeapNumber, as NaN is not equal to NaN.
GenerateEqual_Same(this, lhs, &if_equal, &if_notequal);
}
- Bind(&if_notsame);
+ BIND(&if_notsame);
{
// The {lhs} and {rhs} reference different objects, yet for Smi, HeapNumber
// and String they can still be considered equal.
@@ -7378,7 +7467,7 @@ Node* CodeStubAssembler::StrictEqual(ResultMode mode, Node* lhs, Node* rhs,
Label if_lhsissmi(this), if_lhsisnotsmi(this);
Branch(TaggedIsSmi(lhs), &if_lhsissmi, &if_lhsisnotsmi);
- Bind(&if_lhsisnotsmi);
+ BIND(&if_lhsisnotsmi);
{
// Load the map of {lhs}.
Node* lhs_map = LoadMap(lhs);
@@ -7387,13 +7476,13 @@ Node* CodeStubAssembler::StrictEqual(ResultMode mode, Node* lhs, Node* rhs,
Label if_lhsisnumber(this), if_lhsisnotnumber(this);
Branch(IsHeapNumberMap(lhs_map), &if_lhsisnumber, &if_lhsisnotnumber);
- Bind(&if_lhsisnumber);
+ BIND(&if_lhsisnumber);
{
// Check if {rhs} is a Smi or a HeapObject.
Label if_rhsissmi(this), if_rhsisnotsmi(this);
Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
- Bind(&if_rhsissmi);
+ BIND(&if_rhsissmi);
{
// Convert {lhs} and {rhs} to floating point values.
Node* lhs_value = LoadHeapNumberValue(lhs);
@@ -7403,7 +7492,7 @@ Node* CodeStubAssembler::StrictEqual(ResultMode mode, Node* lhs, Node* rhs,
Branch(Float64Equal(lhs_value, rhs_value), &if_equal, &if_notequal);
}
- Bind(&if_rhsisnotsmi);
+ BIND(&if_rhsisnotsmi);
{
// Load the map of {rhs}.
Node* rhs_map = LoadMap(rhs);
@@ -7412,7 +7501,7 @@ Node* CodeStubAssembler::StrictEqual(ResultMode mode, Node* lhs, Node* rhs,
Label if_rhsisnumber(this), if_rhsisnotnumber(this);
Branch(IsHeapNumberMap(rhs_map), &if_rhsisnumber, &if_rhsisnotnumber);
- Bind(&if_rhsisnumber);
+ BIND(&if_rhsisnumber);
{
// Convert {lhs} and {rhs} to floating point values.
Node* lhs_value = LoadHeapNumberValue(lhs);
@@ -7422,21 +7511,21 @@ Node* CodeStubAssembler::StrictEqual(ResultMode mode, Node* lhs, Node* rhs,
Branch(Float64Equal(lhs_value, rhs_value), &if_equal, &if_notequal);
}
- Bind(&if_rhsisnotnumber);
+ BIND(&if_rhsisnotnumber);
Goto(&if_notequal);
}
}
- Bind(&if_lhsisnotnumber);
+ BIND(&if_lhsisnotnumber);
{
// Check if {rhs} is a Smi or a HeapObject.
Label if_rhsissmi(this), if_rhsisnotsmi(this);
Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
- Bind(&if_rhsissmi);
+ BIND(&if_rhsissmi);
Goto(&if_notequal);
- Bind(&if_rhsisnotsmi);
+ BIND(&if_rhsisnotsmi);
{
// Load the instance type of {lhs}.
Node* lhs_instance_type = LoadMapInstanceType(lhs_map);
@@ -7446,7 +7535,7 @@ Node* CodeStubAssembler::StrictEqual(ResultMode mode, Node* lhs, Node* rhs,
Branch(IsStringInstanceType(lhs_instance_type), &if_lhsisstring,
&if_lhsisnotstring);
- Bind(&if_lhsisstring);
+ BIND(&if_lhsisstring);
{
// Load the instance type of {rhs}.
Node* rhs_instance_type = LoadInstanceType(rhs);
@@ -7457,26 +7546,24 @@ Node* CodeStubAssembler::StrictEqual(ResultMode mode, Node* lhs, Node* rhs,
Branch(IsStringInstanceType(rhs_instance_type), &if_rhsisstring,
&if_rhsisnotstring);
- Bind(&if_rhsisstring);
+ BIND(&if_rhsisstring);
{
- Callable callable = (mode == kDontNegateResult)
- ? CodeFactory::StringEqual(isolate())
- : CodeFactory::StringNotEqual(isolate());
- result.Bind(CallStub(callable, context, lhs, rhs));
+ Callable callable = CodeFactory::StringEqual(isolate());
+ result.Bind(CallStub(callable, NoContextConstant(), lhs, rhs));
Goto(&end);
}
- Bind(&if_rhsisnotstring);
+ BIND(&if_rhsisnotstring);
Goto(&if_notequal);
}
- Bind(&if_lhsisnotstring);
+ BIND(&if_lhsisnotstring);
Goto(&if_notequal);
}
}
}
- Bind(&if_lhsissmi);
+ BIND(&if_lhsissmi);
{
// We already know that {lhs} and {rhs} are not reference equal, and {lhs}
// is a Smi; so {lhs} and {rhs} can only be strictly equal if {rhs} is a
@@ -7486,10 +7573,10 @@ Node* CodeStubAssembler::StrictEqual(ResultMode mode, Node* lhs, Node* rhs,
Label if_rhsissmi(this), if_rhsisnotsmi(this);
Branch(TaggedIsSmi(rhs), &if_rhsissmi, &if_rhsisnotsmi);
- Bind(&if_rhsissmi);
+ BIND(&if_rhsissmi);
Goto(&if_notequal);
- Bind(&if_rhsisnotsmi);
+ BIND(&if_rhsisnotsmi);
{
// Load the map of the {rhs}.
Node* rhs_map = LoadMap(rhs);
@@ -7498,7 +7585,7 @@ Node* CodeStubAssembler::StrictEqual(ResultMode mode, Node* lhs, Node* rhs,
Label if_rhsisnumber(this), if_rhsisnotnumber(this);
Branch(IsHeapNumberMap(rhs_map), &if_rhsisnumber, &if_rhsisnotnumber);
- Bind(&if_rhsisnumber);
+ BIND(&if_rhsisnumber);
{
// Convert {lhs} and {rhs} to floating point values.
Node* lhs_value = SmiToFloat64(lhs);
@@ -7508,33 +7595,33 @@ Node* CodeStubAssembler::StrictEqual(ResultMode mode, Node* lhs, Node* rhs,
Branch(Float64Equal(lhs_value, rhs_value), &if_equal, &if_notequal);
}
- Bind(&if_rhsisnotnumber);
+ BIND(&if_rhsisnotnumber);
Goto(&if_notequal);
}
}
}
- Bind(&if_equal);
+ BIND(&if_equal);
{
- result.Bind(BooleanConstant(mode == kDontNegateResult));
+ result.Bind(TrueConstant());
Goto(&end);
}
- Bind(&if_notequal);
+ BIND(&if_notequal);
{
- result.Bind(BooleanConstant(mode == kNegateResult));
+ result.Bind(FalseConstant());
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
return result.value();
}
// ECMA#sec-samevalue
// This algorithm differs from the Strict Equality Comparison Algorithm in its
// treatment of signed zeroes and NaNs.
-Node* CodeStubAssembler::SameValue(Node* lhs, Node* rhs, Node* context) {
- Variable var_result(this, MachineRepresentation::kWord32);
+Node* CodeStubAssembler::SameValue(Node* lhs, Node* rhs) {
+ VARIABLE(var_result, MachineRepresentation::kWord32);
Label strict_equal(this), out(this);
Node* const int_false = Int32Constant(0);
@@ -7543,7 +7630,7 @@ Node* CodeStubAssembler::SameValue(Node* lhs, Node* rhs, Node* context) {
Label if_equal(this), if_notequal(this);
Branch(WordEqual(lhs, rhs), &if_equal, &if_notequal);
- Bind(&if_equal);
+ BIND(&if_equal);
{
// This covers the case when {lhs} == {rhs}. We can simply return true
// because SameValue considers two NaNs to be equal.
@@ -7552,7 +7639,7 @@ Node* CodeStubAssembler::SameValue(Node* lhs, Node* rhs, Node* context) {
Goto(&out);
}
- Bind(&if_notequal);
+ BIND(&if_notequal);
{
// This covers the case when {lhs} != {rhs}. We only handle numbers here
// and defer to StrictEqual for the rest.
@@ -7563,7 +7650,7 @@ Node* CodeStubAssembler::SameValue(Node* lhs, Node* rhs, Node* context) {
Label if_lhsisnan(this), if_lhsnotnan(this);
BranchIfFloat64IsNaN(lhs_float, &if_lhsisnan, &if_lhsnotnan);
- Bind(&if_lhsisnan);
+ BIND(&if_lhsisnan);
{
// Return true iff {rhs} is NaN.
@@ -7574,13 +7661,13 @@ Node* CodeStubAssembler::SameValue(Node* lhs, Node* rhs, Node* context) {
Goto(&out);
}
- Bind(&if_lhsnotnan);
+ BIND(&if_lhsnotnan);
{
Label if_floatisequal(this), if_floatnotequal(this);
Branch(Float64Equal(lhs_float, rhs_float), &if_floatisequal,
&if_floatnotequal);
- Bind(&if_floatisequal);
+ BIND(&if_floatisequal);
{
// We still need to handle the case when {lhs} and {rhs} are -0.0 and
// 0.0 (or vice versa). Compare the high word to
@@ -7597,7 +7684,7 @@ Node* CodeStubAssembler::SameValue(Node* lhs, Node* rhs, Node* context) {
Goto(&out);
}
- Bind(&if_floatnotequal);
+ BIND(&if_floatnotequal);
{
var_result.Bind(int_false);
Goto(&out);
@@ -7605,43 +7692,15 @@ Node* CodeStubAssembler::SameValue(Node* lhs, Node* rhs, Node* context) {
}
}
- Bind(&strict_equal);
+ BIND(&strict_equal);
{
- Node* const is_equal = StrictEqual(kDontNegateResult, lhs, rhs, context);
+ Node* const is_equal = StrictEqual(lhs, rhs);
Node* const result = WordEqual(is_equal, TrueConstant());
var_result.Bind(result);
Goto(&out);
}
- Bind(&out);
- return var_result.value();
-}
-
-Node* CodeStubAssembler::ForInFilter(Node* key, Node* object, Node* context) {
- Label return_undefined(this, Label::kDeferred), return_to_name(this),
- end(this);
-
- Variable var_result(this, MachineRepresentation::kTagged);
-
- Node* has_property =
- HasProperty(object, key, context, Runtime::kForInHasProperty);
-
- Branch(WordEqual(has_property, BooleanConstant(true)), &return_to_name,
- &return_undefined);
-
- Bind(&return_to_name);
- {
- var_result.Bind(ToName(context, key));
- Goto(&end);
- }
-
- Bind(&return_undefined);
- {
- var_result.Bind(UndefinedConstant());
- Goto(&end);
- }
-
- Bind(&end);
+ BIND(&out);
return var_result.value();
}
@@ -7660,44 +7719,47 @@ Node* CodeStubAssembler::HasProperty(
};
CodeStubAssembler::LookupInHolder lookup_element_in_holder =
- [this, &return_true](Node* receiver, Node* holder, Node* holder_map,
- Node* holder_instance_type, Node* index,
- Label* next_holder, Label* if_bailout) {
+ [this, &return_true, &return_false](
+ Node* receiver, Node* holder, Node* holder_map,
+ Node* holder_instance_type, Node* index, Label* next_holder,
+ Label* if_bailout) {
TryLookupElement(holder, holder_map, holder_instance_type, index,
- &return_true, next_holder, if_bailout);
+ &return_true, &return_false, next_holder, if_bailout);
};
TryPrototypeChainLookup(object, key, lookup_property_in_holder,
lookup_element_in_holder, &return_false,
&call_runtime);
- Variable result(this, MachineRepresentation::kTagged);
- Bind(&return_true);
+ VARIABLE(result, MachineRepresentation::kTagged);
+ BIND(&return_true);
{
result.Bind(BooleanConstant(true));
Goto(&end);
}
- Bind(&return_false);
+ BIND(&return_false);
{
result.Bind(BooleanConstant(false));
Goto(&end);
}
- Bind(&call_runtime);
+ BIND(&call_runtime);
{
result.Bind(
CallRuntime(fallback_runtime_function_id, context, object, key));
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
return result.value();
}
Node* CodeStubAssembler::ClassOf(Node* value) {
- Variable var_result(this, MachineRepresentation::kTaggedPointer);
- Label if_function(this, Label::kDeferred), if_object(this, Label::kDeferred),
+ VARIABLE(var_result, MachineRepresentation::kTaggedPointer);
+ Label if_function_template_info(this, Label::kDeferred),
+ if_no_class_name(this, Label::kDeferred),
+ if_function(this, Label::kDeferred), if_object(this, Label::kDeferred),
if_primitive(this, Label::kDeferred), return_result(this);
// Check if {value} is a Smi.
@@ -7720,6 +7782,8 @@ Node* CodeStubAssembler::ClassOf(Node* value) {
// Load the {value}s constructor, and check that it's a JSFunction.
Node* constructor = LoadMapConstructor(value_map);
+ GotoIf(HasInstanceType(constructor, FUNCTION_TEMPLATE_INFO_TYPE),
+ &if_function_template_info);
GotoIfNot(IsJSFunction(constructor), &if_object);
// Return the instance class name for the {constructor}.
@@ -7730,24 +7794,36 @@ Node* CodeStubAssembler::ClassOf(Node* value) {
var_result.Bind(instance_class_name);
Goto(&return_result);
- Bind(&if_function);
+ // For remote objects the constructor might be given as FTI.
+ BIND(&if_function_template_info);
+ Node* class_name =
+ LoadObjectField(constructor, FunctionTemplateInfo::kClassNameOffset);
+ GotoIf(IsUndefined(class_name), &if_no_class_name);
+ var_result.Bind(class_name);
+ Goto(&return_result);
+
+ BIND(&if_no_class_name);
+ var_result.Bind(LoadRoot(Heap::kempty_stringRootIndex));
+ Goto(&return_result);
+
+ BIND(&if_function);
var_result.Bind(LoadRoot(Heap::kFunction_stringRootIndex));
Goto(&return_result);
- Bind(&if_object);
+ BIND(&if_object);
var_result.Bind(LoadRoot(Heap::kObject_stringRootIndex));
Goto(&return_result);
- Bind(&if_primitive);
+ BIND(&if_primitive);
var_result.Bind(NullConstant());
Goto(&return_result);
- Bind(&return_result);
+ BIND(&return_result);
return var_result.value();
}
-Node* CodeStubAssembler::Typeof(Node* value, Node* context) {
- Variable result_var(this, MachineRepresentation::kTagged);
+Node* CodeStubAssembler::Typeof(Node* value) {
+ VARIABLE(result_var, MachineRepresentation::kTagged);
Label return_number(this, Label::kDeferred), if_oddball(this),
return_function(this), return_undefined(this), return_object(this),
@@ -7782,44 +7858,44 @@ Node* CodeStubAssembler::Typeof(Node* value, Node* context) {
result_var.Bind(HeapConstant(isolate()->factory()->symbol_string()));
Goto(&return_result);
- Bind(&return_number);
+ BIND(&return_number);
{
result_var.Bind(HeapConstant(isolate()->factory()->number_string()));
Goto(&return_result);
}
- Bind(&if_oddball);
+ BIND(&if_oddball);
{
Node* type = LoadObjectField(value, Oddball::kTypeOfOffset);
result_var.Bind(type);
Goto(&return_result);
}
- Bind(&return_function);
+ BIND(&return_function);
{
result_var.Bind(HeapConstant(isolate()->factory()->function_string()));
Goto(&return_result);
}
- Bind(&return_undefined);
+ BIND(&return_undefined);
{
result_var.Bind(HeapConstant(isolate()->factory()->undefined_string()));
Goto(&return_result);
}
- Bind(&return_object);
+ BIND(&return_object);
{
result_var.Bind(HeapConstant(isolate()->factory()->object_string()));
Goto(&return_result);
}
- Bind(&return_string);
+ BIND(&return_string);
{
result_var.Bind(HeapConstant(isolate()->factory()->string_string()));
Goto(&return_result);
}
- Bind(&return_result);
+ BIND(&return_result);
return result_var.value();
}
@@ -7828,7 +7904,7 @@ Node* CodeStubAssembler::GetSuperConstructor(Node* active_function,
CSA_ASSERT(this, IsJSFunction(active_function));
Label is_not_constructor(this, Label::kDeferred), out(this);
- Variable result(this, MachineRepresentation::kTagged);
+ VARIABLE(result, MachineRepresentation::kTagged);
Node* map = LoadMap(active_function);
Node* prototype = LoadMapPrototype(map);
@@ -7838,20 +7914,20 @@ Node* CodeStubAssembler::GetSuperConstructor(Node* active_function,
result.Bind(prototype);
Goto(&out);
- Bind(&is_not_constructor);
+ BIND(&is_not_constructor);
{
CallRuntime(Runtime::kThrowNotSuperConstructor, context, prototype,
active_function);
Unreachable();
}
- Bind(&out);
+ BIND(&out);
return result.value();
}
Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable,
Node* context) {
- Variable var_result(this, MachineRepresentation::kTagged);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
Label if_notcallable(this, Label::kDeferred),
if_notreceiver(this, Label::kDeferred), if_otherhandler(this),
if_nohandler(this, Label::kDeferred), return_true(this),
@@ -7862,8 +7938,8 @@ Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable,
GotoIfNot(IsJSReceiver(callable), &if_notreceiver);
// Load the @@hasInstance property from {callable}.
- Node* inst_of_handler = CallStub(CodeFactory::GetProperty(isolate()), context,
- callable, HasInstanceSymbolConstant());
+ Node* inst_of_handler =
+ GetProperty(context, callable, HasInstanceSymbolConstant());
// Optimize for the likely case where {inst_of_handler} is the builtin
// Function.prototype[@@hasInstance] method, and emit a direct call in
@@ -7882,7 +7958,7 @@ Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable,
Goto(&return_result);
}
- Bind(&if_otherhandler);
+ BIND(&if_otherhandler);
{
// Check if there's actually an {inst_of_handler}.
GotoIf(IsNull(inst_of_handler), &if_nohandler);
@@ -7897,7 +7973,7 @@ Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable,
BranchIfToBooleanIsTrue(result, &return_true, &return_false);
}
- Bind(&if_nohandler);
+ BIND(&if_nohandler);
{
// Ensure that the {callable} is actually Callable.
GotoIfNot(IsCallable(callable), &if_notcallable);
@@ -7909,37 +7985,37 @@ Node* CodeStubAssembler::InstanceOf(Node* object, Node* callable,
Goto(&return_result);
}
- Bind(&if_notcallable);
+ BIND(&if_notcallable);
{
CallRuntime(Runtime::kThrowNonCallableInInstanceOfCheck, context);
Unreachable();
}
- Bind(&if_notreceiver);
+ BIND(&if_notreceiver);
{
CallRuntime(Runtime::kThrowNonObjectInInstanceOfCheck, context);
Unreachable();
}
- Bind(&return_true);
+ BIND(&return_true);
var_result.Bind(TrueConstant());
Goto(&return_result);
- Bind(&return_false);
+ BIND(&return_false);
var_result.Bind(FalseConstant());
Goto(&return_result);
- Bind(&return_result);
+ BIND(&return_result);
return var_result.value();
}
Node* CodeStubAssembler::NumberInc(Node* value) {
- Variable var_result(this, MachineRepresentation::kTagged),
- var_finc_value(this, MachineRepresentation::kFloat64);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
+ VARIABLE(var_finc_value, MachineRepresentation::kFloat64);
Label if_issmi(this), if_isnotsmi(this), do_finc(this), end(this);
Branch(TaggedIsSmi(value), &if_issmi, &if_isnotsmi);
- Bind(&if_issmi);
+ BIND(&if_issmi);
{
// Try fast Smi addition first.
Node* one = SmiConstant(Smi::FromInt(1));
@@ -7951,18 +8027,18 @@ Node* CodeStubAssembler::NumberInc(Node* value) {
Label if_overflow(this), if_notoverflow(this);
Branch(overflow, &if_overflow, &if_notoverflow);
- Bind(&if_notoverflow);
+ BIND(&if_notoverflow);
var_result.Bind(BitcastWordToTaggedSigned(Projection(0, pair)));
Goto(&end);
- Bind(&if_overflow);
+ BIND(&if_overflow);
{
var_finc_value.Bind(SmiToFloat64(value));
Goto(&do_finc);
}
}
- Bind(&if_isnotsmi);
+ BIND(&if_isnotsmi);
{
// Check if the value is a HeapNumber.
CSA_ASSERT(this, IsHeapNumberMap(LoadMap(value)));
@@ -7972,7 +8048,7 @@ Node* CodeStubAssembler::NumberInc(Node* value) {
Goto(&do_finc);
}
- Bind(&do_finc);
+ BIND(&do_finc);
{
Node* finc_value = var_finc_value.value();
Node* one = Float64Constant(1.0);
@@ -7981,7 +8057,59 @@ Node* CodeStubAssembler::NumberInc(Node* value) {
Goto(&end);
}
- Bind(&end);
+ BIND(&end);
+ return var_result.value();
+}
+
+Node* CodeStubAssembler::NumberDec(Node* value) {
+ VARIABLE(var_result, MachineRepresentation::kTagged);
+ VARIABLE(var_fdec_value, MachineRepresentation::kFloat64);
+ Label if_issmi(this), if_isnotsmi(this), do_fdec(this), end(this);
+ Branch(TaggedIsSmi(value), &if_issmi, &if_isnotsmi);
+
+ BIND(&if_issmi);
+ {
+ // Try fast Smi addition first.
+ Node* one = SmiConstant(Smi::FromInt(1));
+ Node* pair = IntPtrSubWithOverflow(BitcastTaggedToWord(value),
+ BitcastTaggedToWord(one));
+ Node* overflow = Projection(1, pair);
+
+ // Check if the Smi addition overflowed.
+ Label if_overflow(this), if_notoverflow(this);
+ Branch(overflow, &if_overflow, &if_notoverflow);
+
+ BIND(&if_notoverflow);
+ var_result.Bind(BitcastWordToTaggedSigned(Projection(0, pair)));
+ Goto(&end);
+
+ BIND(&if_overflow);
+ {
+ var_fdec_value.Bind(SmiToFloat64(value));
+ Goto(&do_fdec);
+ }
+ }
+
+ BIND(&if_isnotsmi);
+ {
+ // Check if the value is a HeapNumber.
+ CSA_ASSERT(this, IsHeapNumberMap(LoadMap(value)));
+
+ // Load the HeapNumber value.
+ var_fdec_value.Bind(LoadHeapNumberValue(value));
+ Goto(&do_fdec);
+ }
+
+ BIND(&do_fdec);
+ {
+ Node* fdec_value = var_fdec_value.value();
+ Node* minus_one = Float64Constant(-1.0);
+ Node* fdec_result = Float64Add(fdec_value, minus_one);
+ var_result.Bind(AllocateHeapNumberWithValue(fdec_result));
+ Goto(&end);
+ }
+
+ BIND(&end);
return var_result.value();
}
@@ -7990,7 +8118,7 @@ void CodeStubAssembler::GotoIfNotNumber(Node* input, Label* is_not_number) {
GotoIf(TaggedIsSmi(input), &is_number);
Node* input_map = LoadMap(input);
Branch(IsHeapNumberMap(input_map), &is_number, is_not_number);
- Bind(&is_number);
+ BIND(&is_number);
}
void CodeStubAssembler::GotoIfNumber(Node* input, Label* is_number) {
@@ -8036,9 +8164,9 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
// Assert: Type(array) is Object
CSA_ASSERT(this, IsJSReceiverInstanceType(array_type));
- Variable var_result(this, MachineRepresentation::kTagged);
- Variable var_map_index(this, MachineType::PointerRepresentation());
- Variable var_array_map(this, MachineRepresentation::kTagged);
+ VARIABLE(var_result, MachineRepresentation::kTagged);
+ VARIABLE(var_map_index, MachineType::PointerRepresentation());
+ VARIABLE(var_array_map, MachineRepresentation::kTagged);
Label return_result(this);
Label allocate_iterator(this);
@@ -8052,13 +8180,13 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)),
&if_istypedarray, &if_isgeneric);
- Bind(&if_isgeneric);
+ BIND(&if_isgeneric);
{
Label if_isfast(this), if_isslow(this);
BranchIfFastJSArray(array, context, FastJSArrayAccessMode::INBOUNDS_READ,
&if_isfast, &if_isslow);
- Bind(&if_isfast);
+ BIND(&if_isfast);
{
var_map_index.Bind(
IntPtrConstant(Context::FAST_ARRAY_KEY_ITERATOR_MAP_INDEX));
@@ -8066,7 +8194,7 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
Goto(&allocate_iterator);
}
- Bind(&if_isslow);
+ BIND(&if_isslow);
{
var_map_index.Bind(
IntPtrConstant(Context::GENERIC_ARRAY_KEY_ITERATOR_MAP_INDEX));
@@ -8075,7 +8203,7 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
}
}
- Bind(&if_istypedarray);
+ BIND(&if_istypedarray);
{
var_map_index.Bind(
IntPtrConstant(Context::TYPED_ARRAY_KEY_ITERATOR_MAP_INDEX));
@@ -8087,20 +8215,20 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
Branch(Word32Equal(array_type, Int32Constant(JS_TYPED_ARRAY_TYPE)),
&if_istypedarray, &if_isgeneric);
- Bind(&if_isgeneric);
+ BIND(&if_isgeneric);
{
Label if_isfast(this), if_isslow(this);
BranchIfFastJSArray(array, context, FastJSArrayAccessMode::INBOUNDS_READ,
&if_isfast, &if_isslow);
- Bind(&if_isfast);
+ BIND(&if_isfast);
{
Label if_ispacked(this), if_isholey(this);
Node* elements_kind = LoadMapElementsKind(array_map);
Branch(IsHoleyFastElementsKind(elements_kind), &if_isholey,
&if_ispacked);
- Bind(&if_isholey);
+ BIND(&if_isholey);
{
// Fast holey JSArrays can treat the hole as undefined if the
// protector cell is valid, and the prototype chain is unchanged from
@@ -8132,7 +8260,7 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
prototype = LoadMapPrototype(map);
Branch(IsNull(prototype), &if_ispacked, &if_isslow);
}
- Bind(&if_ispacked);
+ BIND(&if_ispacked);
{
Node* map_index =
IntPtrAdd(IntPtrConstant(kBaseMapIndex + kFastIteratorOffset),
@@ -8150,7 +8278,7 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
}
}
- Bind(&if_isslow);
+ BIND(&if_isslow);
{
Node* map_index = IntPtrAdd(IntPtrConstant(kBaseMapIndex),
IntPtrConstant(kSlowIteratorOffset));
@@ -8160,7 +8288,7 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
}
}
- Bind(&if_istypedarray);
+ BIND(&if_istypedarray);
{
Node* map_index =
IntPtrAdd(IntPtrConstant(kBaseMapIndex - UINT8_ELEMENTS),
@@ -8176,7 +8304,7 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
}
}
- Bind(&allocate_iterator);
+ BIND(&allocate_iterator);
{
Node* map = LoadFixedArrayElement(LoadNativeContext(context),
var_map_index.value());
@@ -8184,7 +8312,7 @@ Node* CodeStubAssembler::CreateArrayIterator(Node* array, Node* array_map,
Goto(&return_result);
}
- Bind(&return_result);
+ BIND(&return_result);
return var_result.value();
}
@@ -8205,6 +8333,16 @@ Node* CodeStubAssembler::AllocateJSArrayIterator(Node* array, Node* array_map,
return iterator;
}
+Node* CodeStubAssembler::ArraySpeciesCreate(Node* context, Node* originalArray,
+ Node* len) {
+ // TODO(mvstanton): Install a fast path as well, which avoids the runtime
+ // call.
+ Node* constructor =
+ CallRuntime(Runtime::kArraySpeciesConstructor, context, originalArray);
+ return ConstructJS(CodeFactory::Construct(isolate()), context, constructor,
+ len);
+}
+
Node* CodeStubAssembler::IsDetachedBuffer(Node* buffer) {
CSA_ASSERT(this, HasInstanceType(buffer, JS_ARRAY_BUFFER_TYPE));
@@ -8373,16 +8511,14 @@ Node* CodeStubAssembler::AllocatePromiseReactionJobInfo(
Node* CodeStubAssembler::MarkerIsFrameType(Node* marker_or_function,
StackFrame::Type frame_type) {
- return WordEqual(
- marker_or_function,
- IntPtrConstant(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
+ return WordEqual(marker_or_function,
+ IntPtrConstant(StackFrame::TypeToMarker(frame_type)));
}
Node* CodeStubAssembler::MarkerIsNotFrameType(Node* marker_or_function,
StackFrame::Type frame_type) {
- return WordNotEqual(
- marker_or_function,
- IntPtrConstant(StackFrame::TypeToMarker(StackFrame::ARGUMENTS_ADAPTOR)));
+ return WordNotEqual(marker_or_function,
+ IntPtrConstant(StackFrame::TypeToMarker(frame_type)));
}
void CodeStubAssembler::Print(const char* s) {