Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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(Object* obj) { | |
|
Michael Starzinger
2012/03/07 12:49:14
Since this is only used as part of an assertion, I
Sven Panne
2012/03/07 13:23:32
As discussed offline, it's OK to keep this funtion
| |
| 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); |
|
Michael Starzinger
2012/03/07 12:49:14
Is there a particular reason you handlified the na
Sven Panne
2012/03/07 13:23:32
The Object class was missing an IsObject predicate
| |
| 4322 Object* fun = args[3]; | 4335 Object* getter = args[2]; |
| 4336 RUNTIME_ASSERT(IsValidAccessor(getter)); | |
| 4337 Object* setter = args[3]; | |
| 4338 RUNTIME_ASSERT(IsValidAccessor(setter)); | |
| 4323 CONVERT_SMI_ARG_CHECKED(unchecked, 4); | 4339 CONVERT_SMI_ARG_CHECKED(unchecked, 4); |
| 4324 | |
|
Michael Starzinger
2012/03/07 12:49:14
Please leave this empty line in (or at least keep
Sven Panne
2012/03/07 13:23:32
Done.
| |
| 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 getter = FixedArray::cast(array->elements())->get(GETTER_INDEX); | |
|
Michael Starzinger
2012/03/07 12:49:14
I assume that this goes away once the above TODO i
Sven Panne
2012/03/07 13:23:32
Yes, this will vanish, it is just a temporary C++
| |
| 4350 } | |
| 4351 if (!getter->IsNull()) { | |
| 4352 MaybeObject* ok = obj->DefineAccessor(*name, ACCESSOR_GETTER, getter, attr); | |
| 4353 if (ok->IsFailure()) return ok; | |
| 4354 } | |
| 4355 if (!setter->IsNull()) { | |
| 4356 MaybeObject* ok = obj->DefineAccessor(*name, ACCESSOR_SETTER, setter, attr); | |
| 4357 if (ok->IsFailure()) return ok; | |
| 4358 } | |
| 4359 | |
| 4360 return isolate->heap()->undefined_value(); | |
| 4332 } | 4361 } |
| 4333 | 4362 |
| 4334 // Implements part of 8.12.9 DefineOwnProperty. | 4363 // Implements part of 8.12.9 DefineOwnProperty. |
| 4335 // There are 3 cases that lead here: | 4364 // There are 3 cases that lead here: |
| 4336 // Step 4a - define a new data property. | 4365 // Step 4a - define a new data property. |
| 4337 // Steps 9b & 12 - replace an existing accessor property with a data property. | 4366 // 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 | 4367 // Step 12 - update an existing data property with a data or generic |
| 4339 // descriptor. | 4368 // descriptor. |
| 4340 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { | 4369 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { |
| 4341 ASSERT(args.length() == 4); | 4370 ASSERT(args.length() == 4); |
| (...skipping 9271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 13613 // Handle last resort GC and make sure to allow future allocations | 13642 // Handle last resort GC and make sure to allow future allocations |
| 13614 // to grow the heap without causing GCs (if possible). | 13643 // to grow the heap without causing GCs (if possible). |
| 13615 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13644 isolate->counters()->gc_last_resort_from_js()->Increment(); |
| 13616 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13645 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
| 13617 "Runtime::PerformGC"); | 13646 "Runtime::PerformGC"); |
| 13618 } | 13647 } |
| 13619 } | 13648 } |
| 13620 | 13649 |
| 13621 | 13650 |
| 13622 } } // namespace v8::internal | 13651 } } // namespace v8::internal |
| OLD | NEW |