Commit 885f0bc4 authored by Toon Verwaest's avatar Toon Verwaest Committed by Commit Bot

[csa] Support typed arrays in Has(Own)Property

BUG=chromium:703226

Change-Id: Ic71ae018c0090b2142f1d732bcf9c94c65e81f83
Reviewed-on: https://chromium-review.googlesource.com/458917Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Toon Verwaest <verwaest@chromium.org>
Cr-Commit-Position: refs/heads/master@{#44110}
parent 565829f5
......@@ -80,7 +80,7 @@ TF_BUILTIN(ObjectHasOwnProperty, ObjectBuiltinsAssembler) {
// Handle negative keys in the runtime.
GotoIf(IntPtrLessThan(var_index.value(), IntPtrConstant(0)), &call_runtime);
TryLookupElement(object, map, instance_type, var_index.value(),
&return_true, &return_false, &call_runtime);
&return_true, &return_false, &return_false, &call_runtime);
}
Bind(&return_true);
Return(BooleanConstant(true));
......
......@@ -5147,7 +5147,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,
......@@ -5158,7 +5158,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}.
......@@ -5174,6 +5175,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,
......@@ -5183,6 +5194,15 @@ 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));
......@@ -5239,6 +5259,15 @@ void CodeStubAssembler::TryLookupElement(Node* object, Node* map,
GotoIf(UintPtrLessThan(intptr_index, SmiUntag(length)), if_found);
Goto(&if_isdictionary);
}
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
......@@ -7519,11 +7548,12 @@ 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,
......
......@@ -1068,8 +1068,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Variable* var_meta_storage, Variable* var_name_index,
Label* if_not_found, Label* if_bailout);
// This method jumps to if_found if the element is known to exist. To
// if_absent if it's known to not exist. To if_not_found if the prototype
// chain needs to be checked. And if_bailout if the lookup is unsupported.
void TryLookupElement(Node* object, Node* map, Node* instance_type,
Node* intptr_index, Label* if_found,
Node* intptr_index, Label* if_found, Label* if_absent,
Label* if_not_found, Label* if_bailout);
// This is a type of a lookup in holder generator function. In case of a
......
......@@ -1027,25 +1027,29 @@ TEST(TryLookupElement) {
CodeAssemblerTester data(isolate, kNumParams);
CodeStubAssembler m(data.state());
enum Result { kFound, kNotFound, kBailout };
enum Result { kFound, kAbsent, kNotFound, kBailout };
{
Node* object = m.Parameter(0);
Node* index = m.SmiUntag(m.Parameter(1));
Node* expected_result = m.Parameter(2);
Label passed(&m), failed(&m);
Label if_found(&m), if_not_found(&m), if_bailout(&m);
Label if_found(&m), if_not_found(&m), if_bailout(&m), if_absent(&m);
Node* map = m.LoadMap(object);
Node* instance_type = m.LoadMapInstanceType(map);
m.TryLookupElement(object, map, instance_type, index, &if_found,
m.TryLookupElement(object, map, instance_type, index, &if_found, &if_absent,
&if_not_found, &if_bailout);
m.Bind(&if_found);
m.Branch(m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kFound))),
&passed, &failed);
m.Bind(&if_absent);
m.Branch(m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kAbsent))),
&passed, &failed);
m.Bind(&if_not_found);
m.Branch(
m.WordEqual(expected_result, m.SmiConstant(Smi::FromInt(kNotFound))),
......@@ -1074,6 +1078,7 @@ TEST(TryLookupElement) {
Handle<Object> smi42(Smi::FromInt(42), isolate);
Handle<Object> expect_found(Smi::FromInt(kFound), isolate);
Handle<Object> expect_absent(Smi::FromInt(kAbsent), isolate);
Handle<Object> expect_not_found(Smi::FromInt(kNotFound), isolate);
Handle<Object> expect_bailout(Smi::FromInt(kBailout), isolate);
......@@ -1085,6 +1090,17 @@ TEST(TryLookupElement) {
CHECK(!JSReceiver::HasElement(object, index).FromJust()); \
ft.CheckTrue(object, smi##index, expect_not_found);
#define CHECK_ABSENT(object, index) \
{ \
bool success; \
Handle<Smi> smi(Smi::FromInt(index), isolate); \
LookupIterator it = \
LookupIterator::PropertyOrElement(isolate, object, smi, &success); \
CHECK(success); \
CHECK(!JSReceiver::HasProperty(&it).FromJust()); \
ft.CheckTrue(object, smi, expect_absent); \
}
{
Handle<JSArray> object = factory->NewJSArray(0, FAST_SMI_ELEMENTS);
AddElement(object, 0, smi0);
......@@ -1137,6 +1153,30 @@ TEST(TryLookupElement) {
CHECK_NOT_FOUND(object, 42);
}
{
Handle<JSTypedArray> object = factory->NewJSTypedArray(INT32_ELEMENTS, 2);
Local<v8::ArrayBuffer> buffer = Utils::ToLocal(object->GetBuffer());
CHECK_EQ(INT32_ELEMENTS, object->map()->elements_kind());
CHECK_FOUND(object, 0);
CHECK_FOUND(object, 1);
CHECK_ABSENT(object, -10);
CHECK_ABSENT(object, 13);
CHECK_ABSENT(object, 42);
v8::ArrayBuffer::Contents contents = buffer->Externalize();
buffer->Neuter();
isolate->array_buffer_allocator()->Free(contents.Data(),
contents.ByteLength());
CHECK_ABSENT(object, 0);
CHECK_ABSENT(object, 1);
CHECK_ABSENT(object, -10);
CHECK_ABSENT(object, 13);
CHECK_ABSENT(object, 42);
}
{
Handle<JSFunction> constructor = isolate->string_function();
Handle<JSObject> object = factory->NewJSObject(constructor);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment