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 |