Commit e3833fdc authored by jkummerow's avatar jkummerow Committed by Commit bot

Add LookupIterator constructor for arbitrary Object keys

Continuing unification of properties/elements handling, the new
LookupIterator::PropertyOrElement(..., Handle<Object> key, ...) takes
any Object and does the required ToPrimitive/ToName/ToArrayIndex
conversions on it.

Review URL: https://codereview.chromium.org/1375943002

Cr-Commit-Position: refs/heads/master@{#31023}
parent 66660ab0
......@@ -3526,20 +3526,12 @@ static i::MaybeHandle<i::Object> DefineObjectProperty(
i::Handle<i::JSObject> js_object, i::Handle<i::Object> key,
i::Handle<i::Object> value, PropertyAttributes attrs) {
i::Isolate* isolate = js_object->GetIsolate();
// Check if the given key is an array index.
uint32_t index = 0;
if (key->ToArrayIndex(&index)) {
return i::JSObject::SetOwnElementIgnoreAttributes(js_object, index, value,
attrs);
}
i::Handle<i::Name> name;
ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, name,
i::Object::ToName(isolate, key),
i::MaybeHandle<i::Object>());
bool success = false;
i::LookupIterator it = i::LookupIterator::PropertyOrElement(
isolate, js_object, key, &success, i::LookupIterator::OWN);
if (!success) return i::MaybeHandle<i::Object>();
return i::JSObject::DefinePropertyOrElementIgnoreAttributes(js_object, name,
value, attrs);
return i::JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attrs);
}
......
......@@ -13,6 +13,38 @@ namespace v8 {
namespace internal {
// static
LookupIterator LookupIterator::PropertyOrElement(Isolate* isolate,
Handle<Object> receiver,
Handle<Object> key,
bool* success,
Configuration configuration) {
uint32_t index = 0;
if (key->ToArrayIndex(&index)) {
*success = true;
return LookupIterator(isolate, receiver, index, configuration);
}
Handle<Name> name;
*success = Object::ToName(isolate, key).ToHandle(&name);
if (!*success) {
DCHECK(isolate->has_pending_exception());
// Return an unusable dummy.
return LookupIterator(receiver, isolate->factory()->empty_string());
}
if (name->AsArrayIndex(&index)) {
LookupIterator it(isolate, receiver, index, configuration);
// Here we try to avoid having to rebuild the string later
// by storing it on the indexed LookupIterator.
it.name_ = name;
return it;
}
return LookupIterator(receiver, name, configuration);
}
void LookupIterator::Next() {
DCHECK_NE(JSPROXY, state_);
DCHECK_NE(TRANSITION, state_);
......
......@@ -158,6 +158,10 @@ class LookupIterator final BASE_EMBEDDED {
return it;
}
static LookupIterator PropertyOrElement(
Isolate* isolate, Handle<Object> receiver, Handle<Object> key,
bool* success, Configuration configuration = DEFAULT);
Isolate* isolate() const { return isolate_; }
State state() const { return state_; }
......
......@@ -26,26 +26,12 @@ MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
Object);
}
// Check if the given key is an array index.
uint32_t index = 0;
if (key->ToArrayIndex(&index)) {
return Object::GetElement(isolate, object, index, language_mode);
}
bool success = false;
LookupIterator it =
LookupIterator::PropertyOrElement(isolate, object, key, &success);
if (!success) return MaybeHandle<Object>();
// Convert the key to a name - possibly by calling back into JavaScript.
Handle<Name> name;
ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key),
Object);
// Check if the name is trivially convertible to an index and get
// the element if so.
// TODO(verwaest): Make sure GetProperty(LookupIterator*) can handle this, and
// remove the special casing here.
if (name->AsArrayIndex(&index)) {
return Object::GetElement(isolate, object, index);
} else {
return Object::GetProperty(object, name, language_mode);
}
return Object::GetProperty(&it, language_mode);
}
......@@ -135,17 +121,12 @@ MaybeHandle<Object> Runtime::DeleteObjectProperty(Isolate* isolate,
Handle<JSReceiver> receiver,
Handle<Object> key,
LanguageMode language_mode) {
// Check if the given key is an array index.
uint32_t index = 0;
if (key->ToArrayIndex(&index)) {
return JSReceiver::DeleteElement(receiver, index, language_mode);
}
Handle<Name> name;
ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key),
Object);
bool success = false;
LookupIterator it = LookupIterator::PropertyOrElement(
isolate, receiver, key, &success, LookupIterator::HIDDEN);
if (!success) return MaybeHandle<Object>();
return JSReceiver::DeletePropertyOrElement(receiver, name, language_mode);
return JSReceiver::DeleteProperty(&it, language_mode);
}
......@@ -162,16 +143,11 @@ MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
}
// Check if the given key is an array index.
uint32_t index = 0;
if (key->ToArrayIndex(&index)) {
return Object::SetElement(isolate, object, index, value, language_mode);
}
Handle<Name> name;
ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key),
Object);
bool success = false;
LookupIterator it =
LookupIterator::PropertyOrElement(isolate, object, key, &success);
if (!success) return MaybeHandle<Object>();
LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name);
return Object::SetProperty(&it, value, language_mode,
Object::MAY_BE_STORE_FROM_KEYED);
}
......
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