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(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 Loading... |
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 |
OLD | NEW |