| Index: src/api.cc
|
| diff --git a/src/api.cc b/src/api.cc
|
| index 808def3b0fad215568c02b494e8faac6b5249c5b..e340449e8ab3115d2555222a048326fc9ad3a98f 100644
|
| --- a/src/api.cc
|
| +++ b/src/api.cc
|
| @@ -3461,6 +3461,106 @@ bool v8::Object::Set(uint32_t index, v8::Handle<Value> value) {
|
| }
|
|
|
|
|
| +Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
|
| + v8::Local<Name> key,
|
| + v8::Local<Value> value) {
|
| + PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::CreateDataProperty()",
|
| + bool);
|
| + auto self = Utils::OpenHandle(this);
|
| + auto key_obj = Utils::OpenHandle(*key);
|
| + auto value_obj = Utils::OpenHandle(*value);
|
| +
|
| + if (self->IsAccessCheckNeeded() && !isolate->MayAccess(self)) {
|
| + isolate->ReportFailedAccessCheck(self);
|
| + return Nothing<bool>();
|
| + }
|
| +
|
| + if (!self->IsExtensible()) return Just(false);
|
| +
|
| + uint32_t index = 0;
|
| + if (key_obj->AsArrayIndex(&index)) {
|
| + return CreateDataProperty(context, index, value);
|
| + }
|
| +
|
| + // Special case for Array.length.
|
| + if (self->IsJSArray() &&
|
| + key->StrictEquals(Utils::ToLocal(isolate->factory()->length_string()))) {
|
| + // Length is not configurable, however, CreateDataProperty always attempts
|
| + // to create a configurable property, so we just fail here.
|
| + return Just(false);
|
| + }
|
| +
|
| + i::LookupIterator it(self, key_obj, i::LookupIterator::OWN_SKIP_INTERCEPTOR);
|
| + if (it.IsFound() && it.state() == i::LookupIterator::ACCESS_CHECK) {
|
| + DCHECK(isolate->MayAccess(self));
|
| + it.Next();
|
| + }
|
| +
|
| + if (it.state() == i::LookupIterator::DATA ||
|
| + it.state() == i::LookupIterator::ACCESSOR) {
|
| + if (!it.IsConfigurable()) return Just(false);
|
| +
|
| + if (it.state() == i::LookupIterator::ACCESSOR) {
|
| + has_pending_exception = i::JSObject::SetOwnPropertyIgnoreAttributes(
|
| + self, key_obj, value_obj, NONE,
|
| + i::JSObject::DONT_FORCE_FIELD).is_null();
|
| + RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
|
| + return Just(true);
|
| + }
|
| + }
|
| +
|
| + has_pending_exception = i::Runtime::DefineObjectProperty(
|
| + self, key_obj, value_obj, NONE).is_null();
|
| + RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
|
| + return Just(true);
|
| +}
|
| +
|
| +
|
| +Maybe<bool> v8::Object::CreateDataProperty(v8::Local<v8::Context> context,
|
| + uint32_t index,
|
| + v8::Local<Value> value) {
|
| + PREPARE_FOR_EXECUTION_PRIMITIVE(context, "v8::Object::CreateDataProperty()",
|
| + bool);
|
| + auto self = Utils::OpenHandle(this);
|
| + auto value_obj = Utils::OpenHandle(*value);
|
| +
|
| + if (self->IsAccessCheckNeeded() && !isolate->MayAccess(self)) {
|
| + isolate->ReportFailedAccessCheck(self);
|
| + return Nothing<bool>();
|
| + }
|
| +
|
| + if (!self->IsExtensible()) return Just(false);
|
| +
|
| + if (self->IsJSArray()) {
|
| + size_t length =
|
| + i::NumberToSize(isolate, i::Handle<i::JSArray>::cast(self)->length());
|
| + if (index >= length) {
|
| + i::Handle<i::Object> args[] = {
|
| + self, isolate->factory()->Uint32ToString(index), value_obj};
|
| + i::Handle<i::Object> result;
|
| + has_pending_exception =
|
| + !CallV8HeapFunction(isolate, "$objectDefineArrayProperty",
|
| + isolate->factory()->undefined_value(),
|
| + arraysize(args), args).ToHandle(&result);
|
| + RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
|
| + return Just(result->BooleanValue());
|
| + }
|
| + }
|
| +
|
| + Maybe<PropertyAttributes> attributes =
|
| + i::JSReceiver::GetOwnElementAttribute(self, index);
|
| + if (attributes.IsJust() && attributes.FromJust() & DONT_DELETE) {
|
| + return Just(false);
|
| + }
|
| +
|
| + has_pending_exception = i::Runtime::DefineObjectProperty(
|
| + self, isolate->factory()->Uint32ToString(index),
|
| + value_obj, NONE).is_null();
|
| + RETURN_ON_FAILED_EXECUTION_PRIMITIVE(bool);
|
| + return Just(true);
|
| +}
|
| +
|
| +
|
| Maybe<bool> v8::Object::ForceSet(v8::Local<v8::Context> context,
|
| v8::Local<Value> key, v8::Local<Value> value,
|
| v8::PropertyAttribute attribs) {
|
|
|