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

Side by Side Diff: src/runtime.cc

Issue 61883002: Handlify ForceSetObjectProperty (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: cr changes Created 7 years, 1 month 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/runtime.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 5013 matching lines...) Expand 10 before | Expand all | Expand 10 after
5024 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { 5024 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
5025 HandleScope scope(isolate); 5025 HandleScope scope(isolate);
5026 ASSERT(args.length() == 4); 5026 ASSERT(args.length() == 4);
5027 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); 5027 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
5028 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1); 5028 CONVERT_ARG_HANDLE_CHECKED(Name, name, 1);
5029 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2); 5029 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
5030 CONVERT_SMI_ARG_CHECKED(unchecked, 3); 5030 CONVERT_SMI_ARG_CHECKED(unchecked, 3);
5031 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 5031 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
5032 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); 5032 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
5033 5033
5034 LookupResult result(isolate); 5034 LookupResult lookup(isolate);
5035 js_object->LocalLookupRealNamedProperty(*name, &result); 5035 js_object->LocalLookupRealNamedProperty(*name, &lookup);
5036 5036
5037 // Special case for callback properties. 5037 // Special case for callback properties.
5038 if (result.IsPropertyCallbacks()) { 5038 if (lookup.IsPropertyCallbacks()) {
5039 Object* callback = result.GetCallbackObject(); 5039 Handle<Object> callback(lookup.GetCallbackObject(), isolate);
5040 // To be compatible with Safari we do not change the value on API objects 5040 // To be compatible with Safari we do not change the value on API objects
5041 // in Object.defineProperty(). Firefox disagrees here, and actually changes 5041 // in Object.defineProperty(). Firefox disagrees here, and actually changes
5042 // the value. 5042 // the value.
5043 if (callback->IsAccessorInfo()) { 5043 if (callback->IsAccessorInfo()) {
5044 return isolate->heap()->undefined_value(); 5044 return isolate->heap()->undefined_value();
5045 } 5045 }
5046 // Avoid redefining foreign callback as data property, just use the stored 5046 // Avoid redefining foreign callback as data property, just use the stored
5047 // setter to update the value instead. 5047 // setter to update the value instead.
5048 // TODO(mstarzinger): So far this only works if property attributes don't 5048 // TODO(mstarzinger): So far this only works if property attributes don't
5049 // change, this should be fixed once we cleanup the underlying code. 5049 // change, this should be fixed once we cleanup the underlying code.
5050 if (callback->IsForeign() && result.GetAttributes() == attr) { 5050 if (callback->IsForeign() && lookup.GetAttributes() == attr) {
5051 Handle<Object> result_object = 5051 Handle<Object> result_object =
5052 JSObject::SetPropertyWithCallback(js_object, 5052 JSObject::SetPropertyWithCallback(js_object,
5053 handle(callback, isolate), 5053 callback,
5054 name, 5054 name,
5055 obj_value, 5055 obj_value,
5056 handle(result.holder()), 5056 handle(lookup.holder()),
5057 kStrictMode); 5057 kStrictMode);
5058 RETURN_IF_EMPTY_HANDLE(isolate, result_object); 5058 RETURN_IF_EMPTY_HANDLE(isolate, result_object);
5059 return *result_object; 5059 return *result_object;
5060 } 5060 }
5061 } 5061 }
5062 5062
5063 // Take special care when attributes are different and there is already 5063 // Take special care when attributes are different and there is already
5064 // a property. For simplicity we normalize the property which enables us 5064 // a property. For simplicity we normalize the property which enables us
5065 // to not worry about changing the instance_descriptor and creating a new 5065 // to not worry about changing the instance_descriptor and creating a new
5066 // map. The current version of SetObjectProperty does not handle attributes 5066 // map. The current version of SetObjectProperty does not handle attributes
5067 // correctly in the case where a property is a field and is reset with 5067 // correctly in the case where a property is a field and is reset with
5068 // new attributes. 5068 // new attributes.
5069 if (result.IsFound() && 5069 if (lookup.IsFound() &&
5070 (attr != result.GetAttributes() || result.IsPropertyCallbacks())) { 5070 (attr != lookup.GetAttributes() || lookup.IsPropertyCallbacks())) {
5071 // New attributes - normalize to avoid writing to instance descriptor 5071 // New attributes - normalize to avoid writing to instance descriptor
5072 if (js_object->IsJSGlobalProxy()) { 5072 if (js_object->IsJSGlobalProxy()) {
5073 // Since the result is a property, the prototype will exist so 5073 // Since the result is a property, the prototype will exist so
5074 // we don't have to check for null. 5074 // we don't have to check for null.
5075 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); 5075 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype()));
5076 } 5076 }
5077 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); 5077 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0);
5078 // Use IgnoreAttributes version since a readonly property may be 5078 // Use IgnoreAttributes version since a readonly property may be
5079 // overridden and SetProperty does not allow this. 5079 // overridden and SetProperty does not allow this.
5080 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes( 5080 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes(
5081 js_object, name, obj_value, attr); 5081 js_object, name, obj_value, attr);
5082 RETURN_IF_EMPTY_HANDLE(isolate, result); 5082 RETURN_IF_EMPTY_HANDLE(isolate, result);
5083 return *result; 5083 return *result;
5084 } 5084 }
5085 5085
5086 return Runtime::ForceSetObjectProperty(isolate, 5086 Handle<Object> result = Runtime::ForceSetObjectProperty(isolate, js_object,
5087 js_object, 5087 name,
5088 name, 5088 obj_value,
5089 obj_value, 5089 attr);
5090 attr); 5090 RETURN_IF_EMPTY_HANDLE(isolate, result);
5091 return *result;
5091 } 5092 }
5092 5093
5093 5094
5094 // Return property without being observable by accessors or interceptors. 5095 // Return property without being observable by accessors or interceptors.
5095 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) { 5096 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetDataProperty) {
5096 SealHandleScope shs(isolate); 5097 SealHandleScope shs(isolate);
5097 ASSERT(args.length() == 2); 5098 ASSERT(args.length() == 2);
5098 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0); 5099 CONVERT_ARG_HANDLE_CHECKED(JSObject, object, 0);
5099 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1); 5100 CONVERT_ARG_HANDLE_CHECKED(Name, key, 1);
5100 LookupResult lookup(isolate); 5101 LookupResult lookup(isolate);
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
5234 index, *value, attr, strict_mode, true, set_mode); 5235 index, *value, attr, strict_mode, true, set_mode);
5235 } else { 5236 } else {
5236 Handle<Object> result = 5237 Handle<Object> result =
5237 JSReceiver::SetProperty(js_object, name, value, attr, strict_mode); 5238 JSReceiver::SetProperty(js_object, name, value, attr, strict_mode);
5238 RETURN_IF_EMPTY_HANDLE(isolate, result); 5239 RETURN_IF_EMPTY_HANDLE(isolate, result);
5239 return *result; 5240 return *result;
5240 } 5241 }
5241 } 5242 }
5242 5243
5243 5244
5244 MaybeObject* Runtime::ForceSetObjectProperty(Isolate* isolate, 5245 Handle<Object> Runtime::ForceSetObjectProperty(Isolate* isolate,
5245 Handle<JSObject> js_object, 5246 Handle<JSObject> js_object,
5246 Handle<Object> key, 5247 Handle<Object> key,
5247 Handle<Object> value, 5248 Handle<Object> value,
5248 PropertyAttributes attr) { 5249 PropertyAttributes attr) {
5249 HandleScope scope(isolate);
5250
5251 // Check if the given key is an array index. 5250 // Check if the given key is an array index.
5252 uint32_t index; 5251 uint32_t index;
5253 if (key->ToArrayIndex(&index)) { 5252 if (key->ToArrayIndex(&index)) {
5254 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters 5253 // In Firefox/SpiderMonkey, Safari and Opera you can access the characters
5255 // of a string using [] notation. We need to support this too in 5254 // of a string using [] notation. We need to support this too in
5256 // JavaScript. 5255 // JavaScript.
5257 // In the case of a String object we just need to redirect the assignment to 5256 // In the case of a String object we just need to redirect the assignment to
5258 // the underlying string if the index is in range. Since the underlying 5257 // the underlying string if the index is in range. Since the underlying
5259 // string does nothing with the assignment then we can ignore such 5258 // string does nothing with the assignment then we can ignore such
5260 // assignments. 5259 // assignments.
5261 if (js_object->IsStringObjectWithCharacterAt(index)) { 5260 if (js_object->IsStringObjectWithCharacterAt(index)) {
5262 return *value; 5261 return value;
5263 } 5262 }
5264 5263
5265 return js_object->SetElement( 5264 return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode,
5266 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); 5265 false,
5266 DEFINE_PROPERTY);
5267 } 5267 }
5268 5268
5269 if (key->IsName()) { 5269 if (key->IsName()) {
5270 Handle<Name> name = Handle<Name>::cast(key); 5270 Handle<Name> name = Handle<Name>::cast(key);
5271 if (name->AsArrayIndex(&index)) { 5271 if (name->AsArrayIndex(&index)) {
5272 return js_object->SetElement( 5272 return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode,
5273 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); 5273 false,
5274 DEFINE_PROPERTY);
5274 } else { 5275 } else {
5275 if (name->IsString()) Handle<String>::cast(name)->TryFlatten(); 5276 if (name->IsString()) Handle<String>::cast(name)->TryFlatten();
5276 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes( 5277 return JSObject::SetLocalPropertyIgnoreAttributes(js_object, name,
5277 js_object, name, value, attr); 5278 value, attr);
5278 RETURN_IF_EMPTY_HANDLE(isolate, result);
5279 return *result;
5280 } 5279 }
5281 } 5280 }
5282 5281
5283 // Call-back into JavaScript to convert the key to a string. 5282 // Call-back into JavaScript to convert the key to a string.
5284 bool has_pending_exception = false; 5283 bool has_pending_exception = false;
5285 Handle<Object> converted = 5284 Handle<Object> converted =
5286 Execution::ToString(isolate, key, &has_pending_exception); 5285 Execution::ToString(isolate, key, &has_pending_exception);
5287 if (has_pending_exception) return Failure::Exception(); 5286 if (has_pending_exception) return Handle<Object>(); // exception
5288 Handle<String> name = Handle<String>::cast(converted); 5287 Handle<String> name = Handle<String>::cast(converted);
5289 5288
5290 if (name->AsArrayIndex(&index)) { 5289 if (name->AsArrayIndex(&index)) {
5291 return js_object->SetElement( 5290 return JSObject::SetElement(js_object, index, value, attr, kNonStrictMode,
5292 index, *value, attr, kNonStrictMode, false, DEFINE_PROPERTY); 5291 false,
5292 DEFINE_PROPERTY);
5293 } else { 5293 } else {
5294 Handle<Object> result = JSObject::SetLocalPropertyIgnoreAttributes( 5294 return JSObject::SetLocalPropertyIgnoreAttributes(js_object, name, value,
5295 js_object, name, value, attr); 5295 attr);
5296 RETURN_IF_EMPTY_HANDLE(isolate, result);
5297 return *result;
5298 } 5296 }
5299 } 5297 }
5300 5298
5301 5299
5302 MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate, 5300 MaybeObject* Runtime::DeleteObjectProperty(Isolate* isolate,
5303 Handle<JSReceiver> receiver, 5301 Handle<JSReceiver> receiver,
5304 Handle<Object> key, 5302 Handle<Object> key,
5305 JSReceiver::DeleteMode mode) { 5303 JSReceiver::DeleteMode mode) {
5306 HandleScope scope(isolate); 5304 HandleScope scope(isolate);
5307 5305
(...skipping 9530 matching lines...) Expand 10 before | Expand all | Expand 10 after
14838 // Handle last resort GC and make sure to allow future allocations 14836 // Handle last resort GC and make sure to allow future allocations
14839 // to grow the heap without causing GCs (if possible). 14837 // to grow the heap without causing GCs (if possible).
14840 isolate->counters()->gc_last_resort_from_js()->Increment(); 14838 isolate->counters()->gc_last_resort_from_js()->Increment();
14841 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 14839 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
14842 "Runtime::PerformGC"); 14840 "Runtime::PerformGC");
14843 } 14841 }
14844 } 14842 }
14845 14843
14846 14844
14847 } } // namespace v8::internal 14845 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/runtime.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698