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

Side by Side Diff: src/runtime.cc

Issue 9616016: Make the runtime entry for setting/changing accessors "atomic". (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Incorporated review comments. Created 8 years, 9 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/regexp.js ('k') | src/v8natives.js » ('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 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 977 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 IS_ACCESSOR_INDEX, 988 IS_ACCESSOR_INDEX,
989 VALUE_INDEX, 989 VALUE_INDEX,
990 GETTER_INDEX, 990 GETTER_INDEX,
991 SETTER_INDEX, 991 SETTER_INDEX,
992 WRITABLE_INDEX, 992 WRITABLE_INDEX,
993 ENUMERABLE_INDEX, 993 ENUMERABLE_INDEX,
994 CONFIGURABLE_INDEX, 994 CONFIGURABLE_INDEX,
995 DESCRIPTOR_SIZE 995 DESCRIPTOR_SIZE
996 }; 996 };
997 997
998 // Returns an array with the property description: 998
999 // if args[1] is not a property on args[0] 999 static MaybeObject* GetOwnProperty(Isolate* isolate,
1000 // returns undefined 1000 Handle<JSObject> obj,
1001 // if args[1] is a data property on args[0] 1001 Handle<String> name) {
1002 // [false, value, Writeable, Enumerable, Configurable]
1003 // if args[1] is an accessor on args[0]
1004 // [true, GetFunction, SetFunction, Enumerable, Configurable]
1005 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
1006 ASSERT(args.length() == 2);
1007 Heap* heap = isolate->heap(); 1002 Heap* heap = isolate->heap();
1008 HandleScope scope(isolate);
1009 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE); 1003 Handle<FixedArray> elms = isolate->factory()->NewFixedArray(DESCRIPTOR_SIZE);
1010 Handle<JSArray> desc = isolate->factory()->NewJSArrayWithElements(elms); 1004 Handle<JSArray> desc = isolate->factory()->NewJSArrayWithElements(elms);
1011 LookupResult result(isolate); 1005 LookupResult result(isolate);
1012 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1013 CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
1014
1015 // This could be an element. 1006 // This could be an element.
1016 uint32_t index; 1007 uint32_t index;
1017 if (name->AsArrayIndex(&index)) { 1008 if (name->AsArrayIndex(&index)) {
1018 switch (obj->HasLocalElement(index)) { 1009 switch (obj->HasLocalElement(index)) {
1019 case JSObject::UNDEFINED_ELEMENT: 1010 case JSObject::UNDEFINED_ELEMENT:
1020 return heap->undefined_value(); 1011 return heap->undefined_value();
1021 1012
1022 case JSObject::STRING_CHARACTER_ELEMENT: { 1013 case JSObject::STRING_CHARACTER_ELEMENT: {
1023 // Special handling of string objects according to ECMAScript 5 1014 // Special handling of string objects according to ECMAScript 5
1024 // 15.5.5.2. Note that this might be a string object with elements 1015 // 15.5.5.2. Note that this might be a string object with elements
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1138 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); 1129 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs);
1139 if (!maybe_value->ToObject(&value)) return maybe_value; 1130 if (!maybe_value->ToObject(&value)) return maybe_value;
1140 } 1131 }
1141 elms->set(VALUE_INDEX, value); 1132 elms->set(VALUE_INDEX, value);
1142 } 1133 }
1143 1134
1144 return *desc; 1135 return *desc;
1145 } 1136 }
1146 1137
1147 1138
1139 // Returns an array with the property description:
1140 // if args[1] is not a property on args[0]
1141 // returns undefined
1142 // if args[1] is a data property on args[0]
1143 // [false, value, Writeable, Enumerable, Configurable]
1144 // if args[1] is an accessor on args[0]
1145 // [true, GetFunction, SetFunction, Enumerable, Configurable]
1146 RUNTIME_FUNCTION(MaybeObject*, Runtime_GetOwnProperty) {
1147 ASSERT(args.length() == 2);
1148 HandleScope scope(isolate);
1149 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
1150 CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
1151 return GetOwnProperty(isolate, obj, name);
1152 }
1153
1154
1148 RUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) { 1155 RUNTIME_FUNCTION(MaybeObject*, Runtime_PreventExtensions) {
1149 ASSERT(args.length() == 1); 1156 ASSERT(args.length() == 1);
1150 CONVERT_ARG_CHECKED(JSObject, obj, 0); 1157 CONVERT_ARG_CHECKED(JSObject, obj, 0);
1151 return obj->PreventExtensions(); 1158 return obj->PreventExtensions();
1152 } 1159 }
1153 1160
1154 1161
1155 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsExtensible) { 1162 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsExtensible) {
1156 ASSERT(args.length() == 1); 1163 ASSERT(args.length() == 1);
1157 CONVERT_ARG_CHECKED(JSObject, obj, 0); 1164 CONVERT_ARG_CHECKED(JSObject, obj, 0);
(...skipping 3142 matching lines...) Expand 10 before | Expand all | Expand 10 after
4300 return *result; 4307 return *result;
4301 } 4308 }
4302 } 4309 }
4303 4310
4304 // Fall back to GetObjectProperty. 4311 // Fall back to GetObjectProperty.
4305 return Runtime::GetObjectProperty(isolate, 4312 return Runtime::GetObjectProperty(isolate,
4306 args.at<Object>(0), 4313 args.at<Object>(0),
4307 args.at<Object>(1)); 4314 args.at<Object>(1));
4308 } 4315 }
4309 4316
4317
4318 static bool IsValidAccessor(Handle<Object> obj) {
4319 return obj->IsUndefined() || obj->IsSpecFunction() || obj->IsNull();
4320 }
4321
4322
4310 // Implements part of 8.12.9 DefineOwnProperty. 4323 // Implements part of 8.12.9 DefineOwnProperty.
4311 // There are 3 cases that lead here: 4324 // There are 3 cases that lead here:
4312 // Step 4b - define a new accessor property. 4325 // Step 4b - define a new accessor property.
4313 // Steps 9c & 12 - replace an existing data property with an accessor property. 4326 // Steps 9c & 12 - replace an existing data property with an accessor property.
4314 // Step 12 - update an existing accessor property with an accessor or generic 4327 // Step 12 - update an existing accessor property with an accessor or generic
4315 // descriptor. 4328 // descriptor.
4316 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) { 4329 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineAccessorProperty) {
4317 ASSERT(args.length() == 5); 4330 ASSERT(args.length() == 5);
4318 HandleScope scope(isolate); 4331 HandleScope scope(isolate);
4319 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0); 4332 CONVERT_ARG_HANDLE_CHECKED(JSObject, obj, 0);
4320 CONVERT_ARG_CHECKED(String, name, 1); 4333 RUNTIME_ASSERT(!obj->IsNull());
4321 CONVERT_SMI_ARG_CHECKED(flag, 2); 4334 CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
4322 Object* fun = args[3]; 4335 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2);
4336 RUNTIME_ASSERT(IsValidAccessor(getter));
4337 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3);
4338 RUNTIME_ASSERT(IsValidAccessor(setter));
4323 CONVERT_SMI_ARG_CHECKED(unchecked, 4); 4339 CONVERT_SMI_ARG_CHECKED(unchecked, 4);
4324
4325 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 4340 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4326 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); 4341 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
4327 4342
4328 RUNTIME_ASSERT(!obj->IsNull()); 4343 // TODO(svenpanne) Define getter/setter/attributes in a single step.
4329 RUNTIME_ASSERT(fun->IsSpecFunction() || fun->IsUndefined()); 4344 if (getter->IsNull() && setter->IsNull()) {
4330 AccessorComponent component = flag == 0 ? ACCESSOR_GETTER : ACCESSOR_SETTER; 4345 JSArray* array;
4331 return obj->DefineAccessor(name, component, fun, attr); 4346 { MaybeObject* maybe_array = GetOwnProperty(isolate, obj, name);
4347 if (!maybe_array->To(&array)) return maybe_array;
4348 }
4349 Object* current = FixedArray::cast(array->elements())->get(GETTER_INDEX);
4350 getter = Handle<Object>(current, isolate);
4351 }
4352 if (!getter->IsNull()) {
4353 MaybeObject* ok =
4354 obj->DefineAccessor(*name, ACCESSOR_GETTER, *getter, attr);
4355 if (ok->IsFailure()) return ok;
4356 }
4357 if (!setter->IsNull()) {
4358 MaybeObject* ok =
4359 obj->DefineAccessor(*name, ACCESSOR_SETTER, *setter, attr);
4360 if (ok->IsFailure()) return ok;
4361 }
4362
4363 return isolate->heap()->undefined_value();
4332 } 4364 }
4333 4365
4334 // Implements part of 8.12.9 DefineOwnProperty. 4366 // Implements part of 8.12.9 DefineOwnProperty.
4335 // There are 3 cases that lead here: 4367 // There are 3 cases that lead here:
4336 // Step 4a - define a new data property. 4368 // Step 4a - define a new data property.
4337 // Steps 9b & 12 - replace an existing accessor property with a data property. 4369 // Steps 9b & 12 - replace an existing accessor property with a data property.
4338 // Step 12 - update an existing data property with a data or generic 4370 // Step 12 - update an existing data property with a data or generic
4339 // descriptor. 4371 // descriptor.
4340 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { 4372 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) {
4341 ASSERT(args.length() == 4); 4373 ASSERT(args.length() == 4);
4342 HandleScope scope(isolate); 4374 HandleScope scope(isolate);
4343 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0); 4375 CONVERT_ARG_HANDLE_CHECKED(JSObject, js_object, 0);
4344 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); 4376 CONVERT_ARG_HANDLE_CHECKED(String, name, 1);
4345 Handle<Object> obj_value = args.at<Object>(2); 4377 CONVERT_ARG_HANDLE_CHECKED(Object, obj_value, 2);
4346 CONVERT_SMI_ARG_CHECKED(unchecked, 3); 4378 CONVERT_SMI_ARG_CHECKED(unchecked, 3);
4347
4348 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); 4379 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0);
4349 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); 4380 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked);
4350 4381
4351 LookupResult result(isolate); 4382 LookupResult result(isolate);
4352 js_object->LocalLookupRealNamedProperty(*name, &result); 4383 js_object->LocalLookupRealNamedProperty(*name, &result);
4353 4384
4354 // Special case for callback properties. 4385 // Special case for callback properties.
4355 if (result.IsFound() && result.type() == CALLBACKS) { 4386 if (result.IsFound() && result.type() == CALLBACKS) {
4356 Object* callback = result.GetCallbackObject(); 4387 Object* callback = result.GetCallbackObject();
4357 // To be compatible with Safari we do not change the value on API objects 4388 // To be compatible with Safari we do not change the value on API objects
(...skipping 9256 matching lines...) Expand 10 before | Expand all | Expand 10 after
13614 // Handle last resort GC and make sure to allow future allocations 13645 // Handle last resort GC and make sure to allow future allocations
13615 // to grow the heap without causing GCs (if possible). 13646 // to grow the heap without causing GCs (if possible).
13616 isolate->counters()->gc_last_resort_from_js()->Increment(); 13647 isolate->counters()->gc_last_resort_from_js()->Increment();
13617 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, 13648 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags,
13618 "Runtime::PerformGC"); 13649 "Runtime::PerformGC");
13619 } 13650 }
13620 } 13651 }
13621 13652
13622 13653
13623 } } // namespace v8::internal 13654 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/regexp.js ('k') | src/v8natives.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698