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

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

Issue 1168093002: [strong] Implement strong mode restrictions on property access (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase 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 @@ static Handle<Object> GetCharAt(Handle<String> string, uint32_t index) {
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 @@ MaybeHandle<Object> Runtime::GetElementOrCharAt(Isolate* isolate,
if (!result->IsUndefined()) return result;
}
- return Object::GetElement(isolate, object, index);
+ return Object::GetElement(isolate, object, index, language_mode);
}
@@ -52,7 +53,8 @@ MaybeHandle<Name> Runtime::ToName(Isolate* isolate, Handle<Object> key) {
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 @@ MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
// 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,8 +79,109 @@ MaybeHandle<Object> Runtime::GetObjectProperty(Isolate* isolate,
if (name->AsArrayIndex(&index)) {
return GetElementOrCharAt(isolate, object, index);
} else {
- return Object::GetProperty(object, name);
+ return Object::GetProperty(object, name, language_mode);
+ }
+}
+
+
+MUST_USE_RESULT static MaybeHandle<Object> TransitionElements(
+ Handle<Object> object, ElementsKind to_kind, Isolate* isolate) {
+ HandleScope scope(isolate);
+ if (!object->IsJSObject()) {
+ isolate->ThrowIllegalOperation();
+ return MaybeHandle<Object>();
+ }
+ ElementsKind from_kind =
+ Handle<JSObject>::cast(object)->map()->elements_kind();
+ if (Map::IsValidElementsTransition(from_kind, to_kind)) {
+ JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
+ return object;
}
+ isolate->ThrowIllegalOperation();
+ return MaybeHandle<Object>();
+}
+
+
+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.
+ //
+ // The global proxy objects has to be excluded since LookupOwn on
+ // the global proxy object can return a valid result even though the
+ // global proxy object never has properties. This is the case
+ // because the global proxy object forwards everything to its hidden
+ // prototype including own lookups.
+ //
+ // Additionally, we need to make sure that we do not cache results
+ // for objects that require access checks.
+ if (receiver_obj->IsJSObject()) {
+ if (!receiver_obj->IsJSGlobalProxy() &&
+ !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) {
+ DisallowHeapAllocation no_allocation;
+ Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
+ Handle<Name> key = Handle<Name>::cast(key_obj);
+ if (receiver->IsGlobalObject()) {
+ // Attempt dictionary lookup.
+ GlobalDictionary* dictionary = receiver->global_dictionary();
+ int entry = dictionary->FindEntry(key);
+ if (entry != GlobalDictionary::kNotFound) {
+ DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
+ PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry));
+ if (cell->property_details().type() == DATA) {
+ Object* value = cell->value();
+ if (!value->IsTheHole()) return Handle<Object>(value, isolate);
+ // If value is the hole (meaning, absent) do the general lookup.
+ }
+ }
+ } else if (!receiver->HasFastProperties()) {
+ // Attempt dictionary lookup.
+ NameDictionary* dictionary = receiver->property_dictionary();
+ int entry = dictionary->FindEntry(key);
+ if ((entry != NameDictionary::kNotFound) &&
+ (dictionary->DetailsAt(entry).type() == DATA)) {
+ Object* value = dictionary->ValueAt(entry);
+ return Handle<Object>(value, isolate);
+ }
+ }
+ } else if (key_obj->IsSmi()) {
+ // JSObject without a name key. If the key is a Smi, check for a
+ // definite out-of-bounds access to elements, which is a strong indicator
+ // that subsequent accesses will also call the runtime. Proactively
+ // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
+ // doubles for those future calls in the case that the elements would
+ // become FAST_DOUBLE_ELEMENTS.
+ Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
+ ElementsKind elements_kind = js_object->GetElementsKind();
+ if (IsFastDoubleElementsKind(elements_kind)) {
+ Handle<Smi> key = Handle<Smi>::cast(key_obj);
+ if (key->value() >= js_object->elements()->length()) {
+ if (IsFastHoleyElementsKind(elements_kind)) {
+ elements_kind = FAST_HOLEY_ELEMENTS;
+ } else {
+ elements_kind = FAST_ELEMENTS;
+ }
+ RETURN_ON_EXCEPTION(
+ isolate, TransitionElements(js_object, elements_kind, isolate),
+ Object);
+ }
+ } else {
+ DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
+ !IsFastElementsKind(elements_kind));
+ }
+ }
+ } 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 = Handle<Smi>::cast(key_obj)->value();
+ if (index >= 0 && index < str->length()) {
+ return GetCharAt(str, index);
+ }
+ }
+
+ // Fall back to GetObjectProperty.
+ return GetObjectProperty(isolate, receiver_obj, key_obj, language_mode);
}
@@ -383,122 +486,32 @@ RUNTIME_FUNCTION(Runtime_ObjectSeal) {
RUNTIME_FUNCTION(Runtime_GetProperty) {
HandleScope scope(isolate);
- DCHECK(args.length() == 2);
+ 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, object, key));
+ isolate, result,
+ Runtime::GetObjectProperty(isolate, object, key, language_mode));
return *result;
}
-MUST_USE_RESULT static MaybeHandle<Object> TransitionElements(
- Handle<Object> object, ElementsKind to_kind, Isolate* isolate) {
- HandleScope scope(isolate);
- if (!object->IsJSObject()) {
- isolate->ThrowIllegalOperation();
- return MaybeHandle<Object>();
- }
- ElementsKind from_kind =
- Handle<JSObject>::cast(object)->map()->elements_kind();
- if (Map::IsValidElementsTransition(from_kind, to_kind)) {
- JSObject::TransitionElementsKind(Handle<JSObject>::cast(object), to_kind);
- return object;
- }
- isolate->ThrowIllegalOperation();
- return MaybeHandle<Object>();
-}
-
-
-// KeyedGetProperty is called from KeyedLoadIC::GenerateGeneric.
RUNTIME_FUNCTION(Runtime_KeyedGetProperty) {
HandleScope scope(isolate);
- DCHECK(args.length() == 2);
+ 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);
- // Fast cases for getting named properties of the receiver JSObject
- // itself.
- //
- // The global proxy objects has to be excluded since LookupOwn on
- // the global proxy object can return a valid result even though the
- // global proxy object never has properties. This is the case
- // because the global proxy object forwards everything to its hidden
- // prototype including own lookups.
- //
- // Additionally, we need to make sure that we do not cache results
- // for objects that require access checks.
- if (receiver_obj->IsJSObject()) {
- if (!receiver_obj->IsJSGlobalProxy() &&
- !receiver_obj->IsAccessCheckNeeded() && key_obj->IsName()) {
- DisallowHeapAllocation no_allocation;
- Handle<JSObject> receiver = Handle<JSObject>::cast(receiver_obj);
- Handle<Name> key = Handle<Name>::cast(key_obj);
- if (receiver->IsGlobalObject()) {
- // Attempt dictionary lookup.
- GlobalDictionary* dictionary = receiver->global_dictionary();
- int entry = dictionary->FindEntry(key);
- if (entry != GlobalDictionary::kNotFound) {
- DCHECK(dictionary->ValueAt(entry)->IsPropertyCell());
- PropertyCell* cell = PropertyCell::cast(dictionary->ValueAt(entry));
- if (cell->property_details().type() == DATA) {
- Object* value = cell->value();
- if (!value->IsTheHole()) return value;
- // If value is the hole (meaning, absent) do the general lookup.
- }
- }
- } else if (!receiver->HasFastProperties()) {
- // Attempt dictionary lookup.
- NameDictionary* dictionary = receiver->property_dictionary();
- int entry = dictionary->FindEntry(key);
- if ((entry != NameDictionary::kNotFound) &&
- (dictionary->DetailsAt(entry).type() == DATA)) {
- Object* value = dictionary->ValueAt(entry);
- return value;
- }
- }
- } else if (key_obj->IsSmi()) {
- // JSObject without a name key. If the key is a Smi, check for a
- // definite out-of-bounds access to elements, which is a strong indicator
- // that subsequent accesses will also call the runtime. Proactively
- // transition elements to FAST_*_ELEMENTS to avoid excessive boxing of
- // doubles for those future calls in the case that the elements would
- // become FAST_DOUBLE_ELEMENTS.
- Handle<JSObject> js_object = Handle<JSObject>::cast(receiver_obj);
- ElementsKind elements_kind = js_object->GetElementsKind();
- if (IsFastDoubleElementsKind(elements_kind)) {
- Handle<Smi> key = Handle<Smi>::cast(key_obj);
- if (key->value() >= js_object->elements()->length()) {
- if (IsFastHoleyElementsKind(elements_kind)) {
- elements_kind = FAST_HOLEY_ELEMENTS;
- } else {
- elements_kind = FAST_ELEMENTS;
- }
- RETURN_FAILURE_ON_EXCEPTION(
- isolate, TransitionElements(js_object, elements_kind, isolate));
- }
- } else {
- DCHECK(IsFastSmiOrObjectElementsKind(elements_kind) ||
- !IsFastElementsKind(elements_kind));
- }
- }
- } 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);
- if (index >= 0 && index < str->length()) {
- return *GetCharAt(str, index);
- }
- }
-
- // Fall back to GetObjectProperty.
Handle<Object> result;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
- isolate, result,
- Runtime::GetObjectProperty(isolate, receiver_obj, key_obj));
+ 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