Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(175)

Unified Diff: src/runtime/runtime-object.cc

Issue 1185343005: Revert of Revert of [strong] Implement strong mode restrictions on property access (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/runtime/runtime-debug.cc ('k') | src/x64/code-stubs-x64.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime/runtime-object.cc
diff --git a/src/runtime/runtime-object.cc b/src/runtime/runtime-object.cc
index b3b917b03ab2eafc8bebc5a9d212517b4d250ea9..d119867b3044480881e24e890a69092b64430cc5 100644
--- a/src/runtime/runtime-object.cc
+++ b/src/runtime/runtime-object.cc
@@ -26,7 +26,8 @@
MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
Handle<Object> object,
- uint32_t index) {
+ uint32_t index,
+ LanguageMode language_mode) {
// Handle [] indexing on Strings
if (object->IsString() &&
index < static_cast<uint32_t>(String::cast(*object)->length())) {
@@ -34,7 +35,7 @@
if (!result->IsUndefined()) return result;
}
- return Object::GetElement(isolate, object, index);
+ return Object::GetElement(isolate, object, index, language_mode);
}
@@ -52,7 +53,8 @@
MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
Handle<Object> object,
- Handle<Object> key) {
+ Handle<Object> key,
+ LanguageMode language_mode) {
if (object->IsUndefined() || object->IsNull()) {
THROW_NEW_ERROR(
isolate,
@@ -63,7 +65,7 @@
// Check if the given key is an array index.
uint32_t index = 0;
if (key->ToArrayIndex(&index)) {
- return GetElementOrCharAt(isolate, object, index);
+ return GetElementOrCharAt(isolate, object, index, language_mode);
}
// Convert the key to a name - possibly by calling back into JavaScript.
@@ -77,320 +79,8 @@
if (name->AsArrayIndex(&index)) {
return GetElementOrCharAt(isolate, object, index);
} else {
- return Object::GetProperty(object, name);
- }
-}
-
-
-MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
- Handle<Object> object,
- Handle<Object> key,
- Handle<Object> value,
- LanguageMode language_mode) {
- if (object->IsUndefined() || object->IsNull()) {
- THROW_NEW_ERROR(
- isolate,
- NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object),
- Object);
- }
-
- // Check if the given key is an array index.
- uint32_t index = 0;
- if (key->ToArrayIndex(&index)) {
- // TODO(verwaest): Support other objects as well.
- if (!object->IsJSReceiver()) return value;
- return JSReceiver::SetElement(Handle<JSReceiver>::cast(object), index,
- value, language_mode);
- }
-
- Handle<Name> name;
- ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
-
- LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name);
- // TODO(verwaest): Support other objects as well.
- if (it.IsElement() && !object->IsJSReceiver()) return value;
- return Object::SetProperty(&it, value, language_mode,
- Object::MAY_BE_STORE_FROM_KEYED);
-}
-
-
-MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate,
- Handle<Object> obj) {
- // We don't expect access checks to be needed on JSProxy objects.
- DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
- PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
- do {
- if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
- !isolate->MayAccess(
- Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)))) {
- isolate->ReportFailedAccessCheck(
- Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)));
- RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
- return isolate->factory()->undefined_value();
- }
- iter.AdvanceIgnoringProxies();
- if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
- return PrototypeIterator::GetCurrent(iter);
- }
- } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
- return PrototypeIterator::GetCurrent(iter);
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetPrototype) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
- Runtime::GetPrototype(isolate, obj));
- return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
- DCHECK(!obj->IsAccessCheckNeeded());
- DCHECK(!obj->map()->is_observed());
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, JSObject::SetPrototype(obj, prototype, false));
- return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_SetPrototype) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
- if (obj->IsAccessCheckNeeded() && !isolate->MayAccess(obj)) {
- isolate->ReportFailedAccessCheck(obj);
- RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
- return isolate->heap()->undefined_value();
- }
- if (obj->map()->is_observed()) {
- Handle<Object> old_value =
- Object::GetPrototypeSkipHiddenPrototypes(isolate, obj);
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, JSObject::SetPrototype(obj, prototype, true));
-
- Handle<Object> new_value =
- Object::GetPrototypeSkipHiddenPrototypes(isolate, obj);
- if (!new_value->SameValue(*old_value)) {
- RETURN_FAILURE_ON_EXCEPTION(
- isolate, JSObject::EnqueueChangeRecord(
- obj, "setPrototype", isolate->factory()->proto_string(),
- old_value));
- }
- return *result;
- }
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, JSObject::SetPrototype(obj, prototype, true));
- return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
- HandleScope shs(isolate);
- DCHECK(args.length() == 2);
- // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
- CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
- PrototypeIterator iter(isolate, V, PrototypeIterator::START_AT_RECEIVER);
- while (true) {
- iter.AdvanceIgnoringProxies();
- if (iter.IsAtEnd()) return isolate->heap()->false_value();
- if (iter.IsAtEnd(O)) return isolate->heap()->true_value();
- }
-}
-
-
-// Enumerator used as indices into the array returned from GetOwnProperty
-enum PropertyDescriptorIndices {
- IS_ACCESSOR_INDEX,
- VALUE_INDEX,
- GETTER_INDEX,
- SETTER_INDEX,
- WRITABLE_INDEX,
- ENUMERABLE_INDEX,
- CONFIGURABLE_INDEX,
- DESCRIPTOR_SIZE
-};
-
-
-MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
- Handle<JSObject> obj,
- Handle<Name> name) {
- Heap* heap = isolate->heap();
- Factory* factory = isolate->factory();
-
- PropertyAttributes attrs;
- // Get attributes.
- LookupIterator it = LookupIterator::PropertyOrElement(isolate, obj, name,
- LookupIterator::HIDDEN);
- Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
-
- if (!maybe.IsJust()) return MaybeHandle<Object>();
- attrs = maybe.FromJust();
- if (attrs == ABSENT) return factory->undefined_value();
-
- DCHECK(!isolate->has_pending_exception());
- Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE);
- elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
- elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
-
- bool is_accessor_pair = it.state() == LookupIterator::ACCESSOR &&
- it.GetAccessors()->IsAccessorPair();
- elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(is_accessor_pair));
-
- if (is_accessor_pair) {
- Handle<AccessorPair> accessors =
- Handle<AccessorPair>::cast(it.GetAccessors());
- Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
- Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
- elms->set(GETTER_INDEX, *getter);
- elms->set(SETTER_INDEX, *setter);
- } else {
- Handle<Object> value;
- ASSIGN_RETURN_ON_EXCEPTION(isolate, value, Object::GetProperty(&it),
- Object);
- elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
- elms->set(VALUE_INDEX, *value);
- }
-
- return factory->NewJSArrayWithElements(elms);
-}
-
-
-// Returns an array with the property description:
-// if args[1] is not a property on args[0]
-// returns undefined
-// if args[1] is a data property on args[0]
-// [false, value, Writeable, Enumerable, Configurable]
-// if args[1] is an accessor on args[0]
-// [true, GetFunction, SetFunction, Enumerable, Configurable]
-RUNTIME_FUNCTION(Runtime_GetOwnProperty) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
- CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
- GetOwnProperty(isolate, obj, name));
- return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_PreventExtensions) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
- JSObject::PreventExtensions(obj));
- return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_IsExtensible) {
- SealHandleScope shs(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_CHECKED(JSObject, obj, 0);
- return isolate->heap()->ToBoolean(obj->IsExtensible());
-}
-
-
-RUNTIME_FUNCTION(Runtime_DisableAccessChecks) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
- Handle<Map> old_map(object->map());
- bool needs_access_checks = old_map->is_access_check_needed();
- if (needs_access_checks) {
- // Copy map so it won't interfere constructor's initial map.
- Handle<Map> new_map = Map::Copy(old_map, "DisableAccessChecks");
- new_map->set_is_access_check_needed(false);
- JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
- }
- return isolate->heap()->ToBoolean(needs_access_checks);
-}
-
-
-RUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
- Handle<Map> old_map(object->map());
- RUNTIME_ASSERT(!old_map->is_access_check_needed());
- // Copy map so it won't interfere constructor's initial map.
- Handle<Map> new_map = Map::Copy(old_map, "EnableAccessChecks");
- new_map->set_is_access_check_needed(true);
- JSObject::MigrateToMap(object, new_map);
- return isolate->heap()->undefined_value();
-}
-
-
-RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
- CONVERT_SMI_ARG_CHECKED(properties, 1);
- // Conservative upper limit to prevent fuzz tests from going OOM.
- RUNTIME_ASSERT(properties <= 100000);
- if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
- JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties,
- "OptimizeForAdding");
- }
- return *object;
-}
-
-
-RUNTIME_FUNCTION(Runtime_ObjectFreeze) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-
- // %ObjectFreeze is a fast path and these cases are handled elsewhere.
- RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
- !object->map()->is_observed() && !object->IsJSProxy());
-
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object));
- return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_ObjectSeal) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
-
- // %ObjectSeal is a fast path and these cases are handled elsewhere.
- RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
- !object->map()->is_observed() && !object->IsJSProxy());
-
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Seal(object));
- return *result;
-}
-
-
-RUNTIME_FUNCTION(Runtime_GetProperty) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
-
- CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
- Handle<Object> result;
- ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result, Runtime::GetObjectProperty(isolate, object, key));
- return *result;
+ return Object::GetProperty(object, name, language_mode);
+ }
}
@@ -412,14 +102,9 @@
}
-// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
-RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
- HandleScope scope(isolate);
- DCHECK(args.length() == 2);
-
- CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
- CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
-
+MaybeHandle<Object> Runtime::KeyedGetObjectProperty(
+ Isolate* isolate, Handle<Object> receiver_obj, Handle<Object> key_obj,
+ LanguageMode language_mode) {
// Fast cases for getting named properties of the receiver JSObject
// itself.
//
@@ -446,7 +131,7 @@
PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry));
if (cell->property_details().type() == DATA) {
Object* value = cell->value();
- if (!value->IsTheHole()) return value;
+ if (!value->IsTheHole()) return Handle<Object>(value, isolate);
// If value is the hole (meaning, absent) do the general lookup.
}
}
@@ -457,7 +142,7 @@
if ((entry != NameDictionary::kNotFound) &&
(dictionary->DetailsAt(entry).type() == DATA)) {
Object* value = dictionary->ValueAt(entry);
- return value;
+ return Handle<Object>(value, isolate);
}
}
} else if (key_obj->IsSmi()) {
@@ -477,8 +162,9 @@
} else {
elements_kind = FAST_ELEMENTS;
}
- RETURN_FAILURE_ON_EXCEPTION(
- isolate, TransitionElements(js_object, elements_kind, isolate));
+ RETURN_ON_EXCEPTION(
+ isolate, TransitionElements(js_object, elements_kind, isolate),
+ Object);
}
} else {
DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
@@ -488,17 +174,344 @@
} else if (receiver_obj->IsString() && key_obj->IsSmi()) {
// Fast case for string indexing using [] with a smi index.
Handle<String> str = Handle<String>::cast(receiver_obj);
- int index = args.smi_at(1);
+ int index = Handle<Smi>::cast(key_obj)->value();
if (index >= 0 && index < str->length()) {
- return *GetCharAt(str, index);
+ return GetCharAt(str, index);
}
}
// Fall back to GetObjectProperty.
+ return GetObjectProperty(isolate, receiver_obj, key_obj, language_mode);
+}
+
+
+MaybeHandle<Object> Runtime::SetObjectProperty(Isolate* isolate,
+ Handle<Object> object,
+ Handle<Object> key,
+ Handle<Object> value,
+ LanguageMode language_mode) {
+ if (object->IsUndefined() || object->IsNull()) {
+ THROW_NEW_ERROR(
+ isolate,
+ NewTypeError(MessageTemplate::kNonObjectPropertyStore, key, object),
+ Object);
+ }
+
+ // Check if the given key is an array index.
+ uint32_t index = 0;
+ if (key->ToArrayIndex(&index)) {
+ // TODO(verwaest): Support other objects as well.
+ if (!object->IsJSReceiver()) return value;
+ return JSReceiver::SetElement(Handle<JSReceiver>::cast(object), index,
+ value, language_mode);
+ }
+
+ Handle<Name> name;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, name, ToName(isolate, key), Object);
+
+ LookupIterator it = LookupIterator::PropertyOrElement(isolate, object, name);
+ // TODO(verwaest): Support other objects as well.
+ if (it.IsElement() && !object->IsJSReceiver()) return value;
+ return Object::SetProperty(&it, value, language_mode,
+ Object::MAY_BE_STORE_FROM_KEYED);
+}
+
+
+MaybeHandle<Object> Runtime::GetPrototype(Isolate* isolate,
+ Handle<Object> obj) {
+ // We don't expect access checks to be needed on JSProxy objects.
+ DCHECK(!obj->IsAccessCheckNeeded() || obj->IsJSObject());
+ PrototypeIterator iter(isolate, obj, PrototypeIterator::START_AT_RECEIVER);
+ do {
+ if (PrototypeIterator::GetCurrent(iter)->IsAccessCheckNeeded() &&
+ !isolate->MayAccess(
+ Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)))) {
+ isolate->ReportFailedAccessCheck(
+ Handle<JSObject>::cast(PrototypeIterator::GetCurrent(iter)));
+ RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object);
+ return isolate->factory()->undefined_value();
+ }
+ iter.AdvanceIgnoringProxies();
+ if (PrototypeIterator::GetCurrent(iter)->IsJSProxy()) {
+ return PrototypeIterator::GetCurrent(iter);
+ }
+ } while (!iter.IsAtEnd(PrototypeIterator::END_AT_NON_HIDDEN));
+ return PrototypeIterator::GetCurrent(iter);
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetPrototype) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(Object, obj, 0);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+ Runtime::GetPrototype(isolate, obj));
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_InternalSetPrototype) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
+ DCHECK(!obj->IsAccessCheckNeeded());
+ DCHECK(!obj->map()->is_observed());
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, JSObject::SetPrototype(obj, prototype, false));
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_SetPrototype) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, prototype, 1);
+ if (obj->IsAccessCheckNeeded() && !isolate->MayAccess(obj)) {
+ isolate->ReportFailedAccessCheck(obj);
+ RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate);
+ return isolate->heap()->undefined_value();
+ }
+ if (obj->map()->is_observed()) {
+ Handle<Object> old_value =
+ Object::GetPrototypeSkipHiddenPrototypes(isolate, obj);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, JSObject::SetPrototype(obj, prototype, true));
+
+ Handle<Object> new_value =
+ Object::GetPrototypeSkipHiddenPrototypes(isolate, obj);
+ if (!new_value->SameValue(*old_value)) {
+ RETURN_FAILURE_ON_EXCEPTION(
+ isolate, JSObject::EnqueueChangeRecord(
+ obj, "setPrototype", isolate->factory()->proto_string(),
+ old_value));
+ }
+ return *result;
+ }
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, JSObject::SetPrototype(obj, prototype, true));
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsInPrototypeChain) {
+ HandleScope shs(isolate);
+ DCHECK(args.length() == 2);
+ // See ECMA-262, section 15.3.5.3, page 88 (steps 5 - 8).
+ CONVERT_ARG_HANDLE_CHECKED(Object, O, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, V, 1);
+ PrototypeIterator iter(isolate, V, PrototypeIterator::START_AT_RECEIVER);
+ while (true) {
+ iter.AdvanceIgnoringProxies();
+ if (iter.IsAtEnd()) return isolate->heap()->false_value();
+ if (iter.IsAtEnd(O)) return isolate->heap()->true_value();
+ }
+}
+
+
+// Enumerator used as indices into the array returned from GetOwnProperty
+enum PropertyDescriptorIndices {
+ IS_ACCESSOR_INDEX,
+ VALUE_INDEX,
+ GETTER_INDEX,
+ SETTER_INDEX,
+ WRITABLE_INDEX,
+ ENUMERABLE_INDEX,
+ CONFIGURABLE_INDEX,
+ DESCRIPTOR_SIZE
+};
+
+
+MUST_USE_RESULT static MaybeHandle<Object> GetOwnProperty(Isolate* isolate,
+ Handle<JSObject> obj,
+ Handle<Name> name) {
+ Heap* heap = isolate->heap();
+ Factory* factory = isolate->factory();
+
+ PropertyAttributes attrs;
+ // Get attributes.
+ LookupIterator it = LookupIterator::PropertyOrElement(isolate, obj, name,
+ LookupIterator::HIDDEN);
+ Maybe<PropertyAttributes> maybe = JSObject::GetPropertyAttributes(&it);
+
+ if (!maybe.IsJust()) return MaybeHandle<Object>();
+ attrs = maybe.FromJust();
+ if (attrs == ABSENT) return factory->undefined_value();
+
+ DCHECK(!isolate->has_pending_exception());
+ Handle<FixedArray> elms = factory->NewFixedArray(DESCRIPTOR_SIZE);
+ elms->set(ENUMERABLE_INDEX, heap->ToBoolean((attrs & DONT_ENUM) == 0));
+ elms->set(CONFIGURABLE_INDEX, heap->ToBoolean((attrs & DONT_DELETE) == 0));
+
+ bool is_accessor_pair = it.state() == LookupIterator::ACCESSOR &&
+ it.GetAccessors()->IsAccessorPair();
+ elms->set(IS_ACCESSOR_INDEX, heap->ToBoolean(is_accessor_pair));
+
+ if (is_accessor_pair) {
+ Handle<AccessorPair> accessors =
+ Handle<AccessorPair>::cast(it.GetAccessors());
+ Handle<Object> getter(accessors->GetComponent(ACCESSOR_GETTER), isolate);
+ Handle<Object> setter(accessors->GetComponent(ACCESSOR_SETTER), isolate);
+ elms->set(GETTER_INDEX, *getter);
+ elms->set(SETTER_INDEX, *setter);
+ } else {
+ Handle<Object> value;
+ ASSIGN_RETURN_ON_EXCEPTION(isolate, value, Object::GetProperty(&it),
+ Object);
+ elms->set(WRITABLE_INDEX, heap->ToBoolean((attrs & READ_ONLY) == 0));
+ elms->set(VALUE_INDEX, *value);
+ }
+
+ return factory->NewJSArrayWithElements(elms);
+}
+
+
+// Returns an array with the property description:
+// if args[1] is not a property on args[0]
+// returns undefined
+// if args[1] is a data property on args[0]
+// [false, value, Writeable, Enumerable, Configurable]
+// if args[1] is an accessor on args[0]
+// [true, GetFunction, SetFunction, Enumerable, Configurable]
+RUNTIME_FUNCTION(Runtime_GetOwnProperty) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+ GetOwnProperty(isolate, obj, name));
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_PreventExtensions) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result,
+ JSObject::PreventExtensions(obj));
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_IsExtensible) {
+ SealHandleScope shs(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_CHECKED(JSObject, obj, 0);
+ return isolate->heap()->ToBoolean(obj->IsExtensible());
+}
+
+
+RUNTIME_FUNCTION(Runtime_DisableAccessChecks) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(HeapObject, object, 0);
+ Handle<Map> old_map(object->map());
+ bool needs_access_checks = old_map->is_access_check_needed();
+ if (needs_access_checks) {
+ // Copy map so it won't interfere constructor's initial map.
+ Handle<Map> new_map = Map::Copy(old_map, "DisableAccessChecks");
+ new_map->set_is_access_check_needed(false);
+ JSObject::MigrateToMap(Handle<JSObject>::cast(object), new_map);
+ }
+ return isolate->heap()->ToBoolean(needs_access_checks);
+}
+
+
+RUNTIME_FUNCTION(Runtime_EnableAccessChecks) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+ Handle<Map> old_map(object->map());
+ RUNTIME_ASSERT(!old_map->is_access_check_needed());
+ // Copy map so it won't interfere constructor's initial map.
+ Handle<Map> new_map = Map::Copy(old_map, "EnableAccessChecks");
+ new_map->set_is_access_check_needed(true);
+ JSObject::MigrateToMap(object, new_map);
+ return isolate->heap()->undefined_value();
+}
+
+
+RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 2);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+ CONVERT_SMI_ARG_CHECKED(properties, 1);
+ // Conservative upper limit to prevent fuzz tests from going OOM.
+ RUNTIME_ASSERT(properties <= 100000);
+ if (object->HasFastProperties() && !object->IsJSGlobalProxy()) {
+ JSObject::NormalizeProperties(object, KEEP_INOBJECT_PROPERTIES, properties,
+ "OptimizeForAdding");
+ }
+ return *object;
+}
+
+
+RUNTIME_FUNCTION(Runtime_ObjectFreeze) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+
+ // %ObjectFreeze is a fast path and these cases are handled elsewhere.
+ RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
+ !object->map()->is_observed() && !object->IsJSProxy());
+
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Freeze(object));
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_ObjectSeal) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
+
+ // %ObjectSeal is a fast path and these cases are handled elsewhere.
+ RUNTIME_ASSERT(!object->HasSloppyArgumentsElements() &&
+ !object->map()->is_observed() && !object->IsJSProxy());
+
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, result, JSObject::Seal(object));
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_GetProperty) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+
+ CONVERT_ARG_HANDLE_CHECKED(Object, object, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key, 1);
+ CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 2);
+
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, result,
- Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
+ Runtime::GetObjectProperty(isolate, object, key, language_mode));
+ return *result;
+}
+
+
+RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
+ HandleScope scope(isolate);
+ DCHECK(args.length() == 3);
+
+ CONVERT_ARG_HANDLE_CHECKED(Object, receiver_obj, 0);
+ CONVERT_ARG_HANDLE_CHECKED(Object, key_obj, 1);
+ CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 2);
+
+ Handle<Object> result;
+ ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
+ isolate, result, Runtime::KeyedGetObjectProperty(isolate, receiver_obj,
+ key_obj, language_mode));
return *result;
}
« no previous file with comments | « src/runtime/runtime-debug.cc ('k') | src/x64/code-stubs-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698