| Index: src/api.cc
|
| diff --git a/src/api.cc b/src/api.cc
|
| index 0c78b5f27058f923fc02ccd2b9b6dc6e53c8bca7..ae6ab1a5d881494bf1b2220a4e1c10bd794a8cc2 100644
|
| --- a/src/api.cc
|
| +++ b/src/api.cc
|
| @@ -3173,6 +3173,44 @@ bool v8::Object::SetPrivate(v8::Handle<Private> key, v8::Handle<Value> value) {
|
| }
|
|
|
|
|
| +i::MaybeHandle<i::Object> DeleteObjectProperty(
|
| + i::Isolate* isolate, i::Handle<i::JSReceiver> receiver,
|
| + i::Handle<i::Object> key, i::JSReceiver::DeleteMode mode) {
|
| + // Check if the given key is an array index.
|
| + uint32_t index;
|
| + if (key->ToArrayIndex(&index)) {
|
| + // In Firefox/SpiderMonkey, Safari and Opera you can access the
|
| + // characters of a string using [] notation. In the case of a
|
| + // String object we just need to redirect the deletion to the
|
| + // underlying string if the index is in range. Since the
|
| + // underlying string does nothing with the deletion, we can ignore
|
| + // such deletions.
|
| + if (receiver->IsStringObjectWithCharacterAt(index)) {
|
| + return isolate->factory()->true_value();
|
| + }
|
| +
|
| + return i::JSReceiver::DeleteElement(receiver, index, mode);
|
| + }
|
| +
|
| + i::Handle<i::Name> name;
|
| + if (key->IsName()) {
|
| + name = i::Handle<i::Name>::cast(key);
|
| + } else {
|
| + // Call-back into JavaScript to convert the key to a string.
|
| + i::Handle<i::Object> converted;
|
| + if (!i::Execution::ToString(isolate, key).ToHandle(&converted)) {
|
| + return i::MaybeHandle<i::Object>();
|
| + }
|
| + name = i::Handle<i::String>::cast(converted);
|
| + }
|
| +
|
| + if (name->IsString()) {
|
| + name = i::String::Flatten(i::Handle<i::String>::cast(name));
|
| + }
|
| + return i::JSReceiver::DeleteProperty(receiver, name, mode);
|
| +}
|
| +
|
| +
|
| bool v8::Object::ForceDelete(v8::Handle<Value> key) {
|
| i::Isolate* isolate = Utils::OpenHandle(this)->GetIsolate();
|
| ON_BAILOUT(isolate, "v8::Object::ForceDelete()", return false);
|
| @@ -3191,8 +3229,9 @@ bool v8::Object::ForceDelete(v8::Handle<Value> key) {
|
|
|
| EXCEPTION_PREAMBLE(isolate);
|
| i::Handle<i::Object> obj;
|
| - has_pending_exception = !i::Runtime::DeleteObjectProperty(
|
| - isolate, self, key_obj, i::JSReceiver::FORCE_DELETION).ToHandle(&obj);
|
| + has_pending_exception =
|
| + !DeleteObjectProperty(isolate, self, key_obj,
|
| + i::JSReceiver::FORCE_DELETION).ToHandle(&obj);
|
| EXCEPTION_BAILOUT_CHECK(isolate, false);
|
| return obj->IsTrue();
|
| }
|
| @@ -3445,8 +3484,9 @@ bool v8::Object::Delete(v8::Handle<Value> key) {
|
| i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
|
| EXCEPTION_PREAMBLE(isolate);
|
| i::Handle<i::Object> obj;
|
| - has_pending_exception = !i::Runtime::DeleteObjectProperty(
|
| - isolate, self, key_obj, i::JSReceiver::NORMAL_DELETION).ToHandle(&obj);
|
| + has_pending_exception =
|
| + !DeleteObjectProperty(isolate, self, key_obj,
|
| + i::JSReceiver::NORMAL_DELETION).ToHandle(&obj);
|
| EXCEPTION_BAILOUT_CHECK(isolate, false);
|
| return obj->IsTrue();
|
| }
|
| @@ -3464,11 +3504,22 @@ bool v8::Object::Has(v8::Handle<Value> key) {
|
| i::Handle<i::JSReceiver> self = Utils::OpenHandle(this);
|
| i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
|
| EXCEPTION_PREAMBLE(isolate);
|
| - i::Handle<i::Object> obj;
|
| - has_pending_exception = !i::Runtime::HasObjectProperty(
|
| - isolate, self, key_obj).ToHandle(&obj);
|
| + Maybe<bool> maybe;
|
| + // Check if the given key is an array index.
|
| + uint32_t index;
|
| + if (key_obj->ToArrayIndex(&index)) {
|
| + maybe = i::JSReceiver::HasElement(self, index);
|
| + } else {
|
| + // Convert the key to a name - possibly by calling back into JavaScript.
|
| + i::Handle<i::Name> name;
|
| + if (i::Runtime::ToName(isolate, key_obj).ToHandle(&name)) {
|
| + maybe = i::JSReceiver::HasProperty(self, name);
|
| + }
|
| + }
|
| + if (!maybe.has_value) has_pending_exception = true;
|
| EXCEPTION_BAILOUT_CHECK(isolate, false);
|
| - return obj->IsTrue();
|
| + DCHECK(maybe.has_value);
|
| + return maybe.value;
|
| }
|
|
|
|
|
|
|