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

Side by Side Diff: src/objects.cc

Issue 23819003: Handlify JSObject::SetAccessor method. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 7 years, 3 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 5953 matching lines...) Expand 10 before | Expand all | Expand 10 after
5964 } 5964 }
5965 break; 5965 break;
5966 } 5966 }
5967 } 5967 }
5968 5968
5969 Isolate* isolate = object->GetIsolate(); 5969 Isolate* isolate = object->GetIsolate();
5970 Handle<AccessorPair> accessors = isolate->factory()->NewAccessorPair(); 5970 Handle<AccessorPair> accessors = isolate->factory()->NewAccessorPair();
5971 accessors->SetComponents(*getter, *setter); 5971 accessors->SetComponents(*getter, *setter);
5972 accessors->set_access_flags(access_control); 5972 accessors->set_access_flags(access_control);
5973 5973
5974 CALL_HEAP_FUNCTION_VOID( 5974 SetElementCallback(object, index, accessors, attributes);
5975 isolate, object->SetElementCallback(index, *accessors, attributes));
5976 } 5975 }
5977 5976
5978 5977
5979 Handle<AccessorPair> JSObject::CreateAccessorPairFor(Handle<JSObject> object, 5978 Handle<AccessorPair> JSObject::CreateAccessorPairFor(Handle<JSObject> object,
5980 Handle<Name> name) { 5979 Handle<Name> name) {
5981 Isolate* isolate = object->GetIsolate(); 5980 Isolate* isolate = object->GetIsolate();
5982 LookupResult result(isolate); 5981 LookupResult result(isolate);
5983 object->LocalLookupRealNamedProperty(*name, &result); 5982 object->LocalLookupRealNamedProperty(*name, &result);
5984 if (result.IsPropertyCallbacks()) { 5983 if (result.IsPropertyCallbacks()) {
5985 // Note that the result can actually have IsDontDelete() == true when we 5984 // Note that the result can actually have IsDontDelete() == true when we
(...skipping 28 matching lines...) Expand all
6014 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); 6013 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes);
6015 bool setterOk = !getterOk || setter->IsNull() || 6014 bool setterOk = !getterOk || setter->IsNull() ||
6016 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); 6015 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes);
6017 if (getterOk && setterOk) return; 6016 if (getterOk && setterOk) return;
6018 } 6017 }
6019 6018
6020 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); 6019 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name);
6021 accessors->SetComponents(*getter, *setter); 6020 accessors->SetComponents(*getter, *setter);
6022 accessors->set_access_flags(access_control); 6021 accessors->set_access_flags(access_control);
6023 6022
6024 CALL_HEAP_FUNCTION_VOID( 6023 SetPropertyCallback(object, name, accessors, attributes);
6025 object->GetIsolate(),
6026 object->SetPropertyCallback(*name, *accessors, attributes));
6027 } 6024 }
6028 6025
6029 6026
6030 bool JSObject::CanSetCallback(Name* name) { 6027 bool JSObject::CanSetCallback(Name* name) {
6031 ASSERT(!IsAccessCheckNeeded() || 6028 ASSERT(!IsAccessCheckNeeded() ||
6032 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); 6029 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET));
6033 6030
6034 // Check if there is an API defined callback object which prohibits 6031 // Check if there is an API defined callback object which prohibits
6035 // callback overwriting in this object or its prototype chain. 6032 // callback overwriting in this object or its prototype chain.
6036 // This mechanism is needed for instance in a browser setting, where 6033 // This mechanism is needed for instance in a browser setting, where
6037 // certain accessors such as window.location should not be allowed 6034 // certain accessors such as window.location should not be allowed
6038 // to be overwritten because allowing overwriting could potentially 6035 // to be overwritten because allowing overwriting could potentially
6039 // cause security problems. 6036 // cause security problems.
6040 LookupResult callback_result(GetIsolate()); 6037 LookupResult callback_result(GetIsolate());
6041 LookupCallbackProperty(name, &callback_result); 6038 LookupCallbackProperty(name, &callback_result);
6042 if (callback_result.IsFound()) { 6039 if (callback_result.IsFound()) {
6043 Object* obj = callback_result.GetCallbackObject(); 6040 Object* obj = callback_result.GetCallbackObject();
6044 if (obj->IsAccessorInfo()) { 6041 if (obj->IsAccessorInfo()) {
6045 return !AccessorInfo::cast(obj)->prohibits_overwriting(); 6042 return !AccessorInfo::cast(obj)->prohibits_overwriting();
6046 } 6043 }
6047 if (obj->IsAccessorPair()) { 6044 if (obj->IsAccessorPair()) {
6048 return !AccessorPair::cast(obj)->prohibits_overwriting(); 6045 return !AccessorPair::cast(obj)->prohibits_overwriting();
6049 } 6046 }
6050 } 6047 }
6051 return true; 6048 return true;
6052 } 6049 }
6053 6050
6054 6051
6055 MaybeObject* JSObject::SetElementCallback(uint32_t index, 6052 void JSObject::SetElementCallback(Handle<JSObject> object,
6056 Object* structure, 6053 uint32_t index,
6057 PropertyAttributes attributes) { 6054 Handle<Object> structure,
6055 PropertyAttributes attributes) {
6056 Heap* heap = object->GetHeap();
6058 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); 6057 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0);
6059 6058
6060 // Normalize elements to make this operation simple. 6059 // Normalize elements to make this operation simple.
6061 SeededNumberDictionary* dictionary; 6060 Handle<SeededNumberDictionary> dictionary = NormalizeElements(object);
6062 { MaybeObject* maybe_dictionary = NormalizeElements(); 6061 ASSERT(object->HasDictionaryElements() ||
6063 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; 6062 object->HasDictionaryArgumentsElements());
6064 }
6065 ASSERT(HasDictionaryElements() || HasDictionaryArgumentsElements());
6066 6063
6067 // Update the dictionary with the new CALLBACKS property. 6064 // Update the dictionary with the new CALLBACKS property.
6068 { MaybeObject* maybe_dictionary = dictionary->Set(index, structure, details); 6065 dictionary = SeededNumberDictionary::Set(dictionary, index, structure,
6069 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; 6066 details);
6070 } 6067 dictionary->set_requires_slow_elements();
6071 6068
6072 dictionary->set_requires_slow_elements();
6073 // Update the dictionary backing store on the object. 6069 // Update the dictionary backing store on the object.
6074 if (elements()->map() == GetHeap()->non_strict_arguments_elements_map()) { 6070 if (object->elements()->map() == heap->non_strict_arguments_elements_map()) {
6075 // Also delete any parameter alias. 6071 // Also delete any parameter alias.
6076 // 6072 //
6077 // TODO(kmillikin): when deleting the last parameter alias we could 6073 // TODO(kmillikin): when deleting the last parameter alias we could
6078 // switch to a direct backing store without the parameter map. This 6074 // switch to a direct backing store without the parameter map. This
6079 // would allow GC of the context. 6075 // would allow GC of the context.
6080 FixedArray* parameter_map = FixedArray::cast(elements()); 6076 FixedArray* parameter_map = FixedArray::cast(object->elements());
6081 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) { 6077 if (index < static_cast<uint32_t>(parameter_map->length()) - 2) {
6082 parameter_map->set(index + 2, GetHeap()->the_hole_value()); 6078 parameter_map->set(index + 2, heap->the_hole_value());
6083 } 6079 }
6084 parameter_map->set(1, dictionary); 6080 parameter_map->set(1, *dictionary);
6085 } else { 6081 } else {
6086 set_elements(dictionary); 6082 object->set_elements(*dictionary);
6087 } 6083 }
6088
6089 return GetHeap()->undefined_value();
6090 } 6084 }
6091 6085
6092 6086
6093 MaybeObject* JSObject::SetPropertyCallback(Name* name, 6087 void JSObject::SetPropertyCallback(Handle<JSObject> object,
6094 Object* structure, 6088 Handle<Name> name,
6095 PropertyAttributes attributes) { 6089 Handle<Object> structure,
6090 PropertyAttributes attributes) {
6096 // Normalize object to make this operation simple. 6091 // Normalize object to make this operation simple.
6097 MaybeObject* maybe_ok = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); 6092 NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0);
6098 if (maybe_ok->IsFailure()) return maybe_ok;
6099 6093
6100 // For the global object allocate a new map to invalidate the global inline 6094 // For the global object allocate a new map to invalidate the global inline
6101 // caches which have a global property cell reference directly in the code. 6095 // caches which have a global property cell reference directly in the code.
6102 if (IsGlobalObject()) { 6096 if (object->IsGlobalObject()) {
6103 Map* new_map; 6097 Handle<Map> new_map = Map::CopyDropDescriptors(handle(object->map()));
6104 MaybeObject* maybe_new_map = map()->CopyDropDescriptors();
6105 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
6106 ASSERT(new_map->is_dictionary_map()); 6098 ASSERT(new_map->is_dictionary_map());
6099 object->set_map(*new_map);
6107 6100
6108 set_map(new_map);
6109 // When running crankshaft, changing the map is not enough. We 6101 // When running crankshaft, changing the map is not enough. We
6110 // need to deoptimize all functions that rely on this global 6102 // need to deoptimize all functions that rely on this global
6111 // object. 6103 // object.
6112 Deoptimizer::DeoptimizeGlobalObject(this); 6104 Deoptimizer::DeoptimizeGlobalObject(*object);
6113 } 6105 }
6114 6106
6115 // Update the dictionary with the new CALLBACKS property. 6107 // Update the dictionary with the new CALLBACKS property.
6116 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0); 6108 PropertyDetails details = PropertyDetails(attributes, CALLBACKS, 0);
6117 maybe_ok = SetNormalizedProperty(name, structure, details); 6109 SetNormalizedProperty(object, name, structure, details);
6118 if (maybe_ok->IsFailure()) return maybe_ok;
6119
6120 return GetHeap()->undefined_value();
6121 } 6110 }
6122 6111
6123 6112
6124 void JSObject::DefineAccessor(Handle<JSObject> object, 6113 void JSObject::DefineAccessor(Handle<JSObject> object,
6125 Handle<Name> name, 6114 Handle<Name> name,
6126 Handle<Object> getter, 6115 Handle<Object> getter,
6127 Handle<Object> setter, 6116 Handle<Object> setter,
6128 PropertyAttributes attributes, 6117 PropertyAttributes attributes,
6129 v8::AccessControl access_control) { 6118 v8::AccessControl access_control) {
6130 Isolate* isolate = object->GetIsolate(); 6119 Isolate* isolate = object->GetIsolate();
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
6306 ? AccessorPair::Copy(Handle<AccessorPair>(source_accessors)) 6295 ? AccessorPair::Copy(Handle<AccessorPair>(source_accessors))
6307 : isolate->factory()->NewAccessorPair(); 6296 : isolate->factory()->NewAccessorPair();
6308 accessors->set(component, *accessor); 6297 accessors->set(component, *accessor);
6309 Handle<Map> new_map = CopyInsertDescriptor(Handle<Map>(object->map()), 6298 Handle<Map> new_map = CopyInsertDescriptor(Handle<Map>(object->map()),
6310 name, accessors, attributes); 6299 name, accessors, attributes);
6311 object->set_map(*new_map); 6300 object->set_map(*new_map);
6312 return true; 6301 return true;
6313 } 6302 }
6314 6303
6315 6304
6316 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { 6305 Handle<Object> JSObject::SetAccessor(Handle<JSObject> object,
6317 Isolate* isolate = GetIsolate(); 6306 Handle<AccessorInfo> info) {
6318 Name* name = Name::cast(info->name()); 6307 Isolate* isolate = object->GetIsolate();
6308 Factory* factory = isolate->factory();
6309 Handle<Name> name(Name::cast(info->name()));
6310
6319 // Check access rights if needed. 6311 // Check access rights if needed.
6320 if (IsAccessCheckNeeded() && 6312 if (object->IsAccessCheckNeeded() &&
6321 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { 6313 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
6322 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); 6314 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET);
6323 RETURN_IF_SCHEDULED_EXCEPTION(isolate); 6315 RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object);
6324 return isolate->heap()->undefined_value(); 6316 return factory->undefined_value();
6325 } 6317 }
6326 6318
6327 if (IsJSGlobalProxy()) { 6319 if (object->IsJSGlobalProxy()) {
6328 Object* proto = GetPrototype(); 6320 Handle<Object> proto(object->GetPrototype(), isolate);
6329 if (proto->IsNull()) return this; 6321 if (proto->IsNull()) return object;
6330 ASSERT(proto->IsJSGlobalObject()); 6322 ASSERT(proto->IsJSGlobalObject());
6331 return JSObject::cast(proto)->DefineAccessor(info); 6323 return SetAccessor(Handle<JSObject>::cast(proto), info);
6332 } 6324 }
6333 6325
6334 // Make sure that the top context does not change when doing callbacks or 6326 // Make sure that the top context does not change when doing callbacks or
6335 // interceptor calls. 6327 // interceptor calls.
6336 AssertNoContextChangeWithHandleScope ncc; 6328 AssertNoContextChange ncc;
6337 6329
6338 // Try to flatten before operating on the string. 6330 // Try to flatten before operating on the string.
6339 if (name->IsString()) String::cast(name)->TryFlatten(); 6331 if (name->IsString()) FlattenString(Handle<String>::cast(name));
6340 6332
6341 if (!CanSetCallback(name)) return isolate->heap()->undefined_value(); 6333 if (!object->CanSetCallback(*name)) return factory->undefined_value();
6342 6334
6343 uint32_t index = 0; 6335 uint32_t index = 0;
6344 bool is_element = name->AsArrayIndex(&index); 6336 bool is_element = name->AsArrayIndex(&index);
6345 6337
6346 if (is_element) { 6338 if (is_element) {
6347 if (IsJSArray()) return isolate->heap()->undefined_value(); 6339 if (object->IsJSArray()) return factory->undefined_value();
6348 6340
6349 // Accessors overwrite previous callbacks (cf. with getters/setters). 6341 // Accessors overwrite previous callbacks (cf. with getters/setters).
6350 switch (GetElementsKind()) { 6342 switch (object->GetElementsKind()) {
6351 case FAST_SMI_ELEMENTS: 6343 case FAST_SMI_ELEMENTS:
6352 case FAST_ELEMENTS: 6344 case FAST_ELEMENTS:
6353 case FAST_DOUBLE_ELEMENTS: 6345 case FAST_DOUBLE_ELEMENTS:
6354 case FAST_HOLEY_SMI_ELEMENTS: 6346 case FAST_HOLEY_SMI_ELEMENTS:
6355 case FAST_HOLEY_ELEMENTS: 6347 case FAST_HOLEY_ELEMENTS:
6356 case FAST_HOLEY_DOUBLE_ELEMENTS: 6348 case FAST_HOLEY_DOUBLE_ELEMENTS:
6357 break; 6349 break;
6358 case EXTERNAL_PIXEL_ELEMENTS: 6350 case EXTERNAL_PIXEL_ELEMENTS:
6359 case EXTERNAL_BYTE_ELEMENTS: 6351 case EXTERNAL_BYTE_ELEMENTS:
6360 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 6352 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
6361 case EXTERNAL_SHORT_ELEMENTS: 6353 case EXTERNAL_SHORT_ELEMENTS:
6362 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: 6354 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS:
6363 case EXTERNAL_INT_ELEMENTS: 6355 case EXTERNAL_INT_ELEMENTS:
6364 case EXTERNAL_UNSIGNED_INT_ELEMENTS: 6356 case EXTERNAL_UNSIGNED_INT_ELEMENTS:
6365 case EXTERNAL_FLOAT_ELEMENTS: 6357 case EXTERNAL_FLOAT_ELEMENTS:
6366 case EXTERNAL_DOUBLE_ELEMENTS: 6358 case EXTERNAL_DOUBLE_ELEMENTS:
6367 // Ignore getters and setters on pixel and external array 6359 // Ignore getters and setters on pixel and external array
6368 // elements. 6360 // elements.
6369 return isolate->heap()->undefined_value(); 6361 return factory->undefined_value();
6370 case DICTIONARY_ELEMENTS: 6362 case DICTIONARY_ELEMENTS:
6371 break; 6363 break;
6372 case NON_STRICT_ARGUMENTS_ELEMENTS: 6364 case NON_STRICT_ARGUMENTS_ELEMENTS:
6373 UNIMPLEMENTED(); 6365 UNIMPLEMENTED();
6374 break; 6366 break;
6375 } 6367 }
6376 6368
6377 MaybeObject* maybe_ok = 6369 SetElementCallback(object, index, info, info->property_attributes());
6378 SetElementCallback(index, info, info->property_attributes());
6379 if (maybe_ok->IsFailure()) return maybe_ok;
6380 } else { 6370 } else {
6381 // Lookup the name. 6371 // Lookup the name.
6382 LookupResult result(isolate); 6372 LookupResult result(isolate);
6383 LocalLookup(name, &result, true); 6373 object->LocalLookup(*name, &result, true);
6384 // ES5 forbids turning a property into an accessor if it's not 6374 // ES5 forbids turning a property into an accessor if it's not
6385 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5). 6375 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5).
6386 if (result.IsFound() && (result.IsReadOnly() || result.IsDontDelete())) { 6376 if (result.IsFound() && (result.IsReadOnly() || result.IsDontDelete())) {
6387 return isolate->heap()->undefined_value(); 6377 return factory->undefined_value();
6388 } 6378 }
6389 6379
6390 MaybeObject* maybe_ok = 6380 SetPropertyCallback(object, name, info, info->property_attributes());
6391 SetPropertyCallback(name, info, info->property_attributes());
6392 if (maybe_ok->IsFailure()) return maybe_ok;
6393 } 6381 }
6394 6382
6395 return this; 6383 return object;
6396 } 6384 }
6397 6385
6398 6386
6399 MaybeObject* JSObject::LookupAccessor(Name* name, AccessorComponent component) { 6387 MaybeObject* JSObject::LookupAccessor(Name* name, AccessorComponent component) {
6400 Heap* heap = GetHeap(); 6388 Heap* heap = GetHeap();
6401 6389
6402 // Make sure that the top context does not change when doing callbacks or 6390 // Make sure that the top context does not change when doing callbacks or
6403 // interceptor calls. 6391 // interceptor calls.
6404 AssertNoContextChangeWithHandleScope ncc; 6392 AssertNoContextChangeWithHandleScope ncc;
6405 6393
(...skipping 9588 matching lines...) Expand 10 before | Expand all | Expand 10 after
15994 #define ERROR_MESSAGES_TEXTS(C, T) T, 15982 #define ERROR_MESSAGES_TEXTS(C, T) T,
15995 static const char* error_messages_[] = { 15983 static const char* error_messages_[] = {
15996 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 15984 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
15997 }; 15985 };
15998 #undef ERROR_MESSAGES_TEXTS 15986 #undef ERROR_MESSAGES_TEXTS
15999 return error_messages_[reason]; 15987 return error_messages_[reason];
16000 } 15988 }
16001 15989
16002 15990
16003 } } // namespace v8::internal 15991 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698