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 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1058 int entry = dictionary->FindEntry(index); | 1058 int entry = dictionary->FindEntry(index); |
1059 ASSERT(entry != SeededNumberDictionary::kNotFound); | 1059 ASSERT(entry != SeededNumberDictionary::kNotFound); |
1060 PropertyDetails details = dictionary->DetailsAt(entry); | 1060 PropertyDetails details = dictionary->DetailsAt(entry); |
1061 switch (details.type()) { | 1061 switch (details.type()) { |
1062 case CALLBACKS: { | 1062 case CALLBACKS: { |
1063 // This is an accessor property with getter and/or setter. | 1063 // This is an accessor property with getter and/or setter. |
1064 AccessorPair* accessors = | 1064 AccessorPair* accessors = |
1065 AccessorPair::cast(dictionary->ValueAt(entry)); | 1065 AccessorPair::cast(dictionary->ValueAt(entry)); |
1066 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); | 1066 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); |
1067 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { | 1067 if (CheckElementAccess(*obj, index, v8::ACCESS_GET)) { |
1068 elms->set(GETTER_INDEX, accessors->SafeGet(ACCESSOR_GETTER)); | 1068 elms->set(GETTER_INDEX, accessors->GetComponent(ACCESSOR_GETTER)); |
1069 } | 1069 } |
1070 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) { | 1070 if (CheckElementAccess(*obj, index, v8::ACCESS_SET)) { |
1071 elms->set(SETTER_INDEX, accessors->SafeGet(ACCESSOR_SETTER)); | 1071 elms->set(SETTER_INDEX, accessors->GetComponent(ACCESSOR_SETTER)); |
1072 } | 1072 } |
1073 break; | 1073 break; |
1074 } | 1074 } |
1075 case NORMAL: { | 1075 case NORMAL: { |
1076 // This is a data property. | 1076 // This is a data property. |
1077 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); | 1077 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
1078 Handle<Object> value = Object::GetElement(obj, index); | 1078 Handle<Object> value = Object::GetElement(obj, index); |
1079 ASSERT(!value.is_null()); | 1079 ASSERT(!value.is_null()); |
1080 elms->set(VALUE_INDEX, *value); | 1080 elms->set(VALUE_INDEX, *value); |
1081 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly())); | 1081 elms->set(WRITABLE_INDEX, heap->ToBoolean(!details.IsReadOnly())); |
(...skipping 26 matching lines...) Expand all Loading... |
1108 | 1108 |
1109 bool is_js_accessor = (result.type() == CALLBACKS) && | 1109 bool is_js_accessor = (result.type() == CALLBACKS) && |
1110 (result.GetCallbackObject()->IsAccessorPair()); | 1110 (result.GetCallbackObject()->IsAccessorPair()); |
1111 | 1111 |
1112 if (is_js_accessor) { | 1112 if (is_js_accessor) { |
1113 // __defineGetter__/__defineSetter__ callback. | 1113 // __defineGetter__/__defineSetter__ callback. |
1114 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); | 1114 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); |
1115 | 1115 |
1116 AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject()); | 1116 AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject()); |
1117 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { | 1117 if (CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { |
1118 elms->set(GETTER_INDEX, accessors->SafeGet(ACCESSOR_GETTER)); | 1118 elms->set(GETTER_INDEX, accessors->GetComponent(ACCESSOR_GETTER)); |
1119 } | 1119 } |
1120 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) { | 1120 if (CheckAccess(*obj, *name, &result, v8::ACCESS_SET)) { |
1121 elms->set(SETTER_INDEX, accessors->SafeGet(ACCESSOR_SETTER)); | 1121 elms->set(SETTER_INDEX, accessors->GetComponent(ACCESSOR_SETTER)); |
1122 } | 1122 } |
1123 } else { | 1123 } else { |
1124 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); | 1124 elms->set(IS_ACCESSOR_INDEX, heap->false_value()); |
1125 elms->set(WRITABLE_INDEX, heap->ToBoolean(!result.IsReadOnly())); | 1125 elms->set(WRITABLE_INDEX, heap->ToBoolean(!result.IsReadOnly())); |
1126 | 1126 |
1127 PropertyAttributes attrs; | 1127 PropertyAttributes attrs; |
1128 Object* value; | 1128 Object* value; |
1129 // GetProperty will check access and report any violations. | 1129 // GetProperty will check access and report any violations. |
1130 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); | 1130 { MaybeObject* maybe_value = obj->GetProperty(*obj, &result, *name, &attrs); |
1131 if (!maybe_value->ToObject(&value)) return maybe_value; | 1131 if (!maybe_value->ToObject(&value)) return maybe_value; |
(...skipping 3211 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4343 RUNTIME_ASSERT(!obj->IsNull()); | 4343 RUNTIME_ASSERT(!obj->IsNull()); |
4344 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); | 4344 CONVERT_ARG_HANDLE_CHECKED(String, name, 1); |
4345 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2); | 4345 CONVERT_ARG_HANDLE_CHECKED(Object, getter, 2); |
4346 RUNTIME_ASSERT(IsValidAccessor(getter)); | 4346 RUNTIME_ASSERT(IsValidAccessor(getter)); |
4347 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3); | 4347 CONVERT_ARG_HANDLE_CHECKED(Object, setter, 3); |
4348 RUNTIME_ASSERT(IsValidAccessor(setter)); | 4348 RUNTIME_ASSERT(IsValidAccessor(setter)); |
4349 CONVERT_SMI_ARG_CHECKED(unchecked, 4); | 4349 CONVERT_SMI_ARG_CHECKED(unchecked, 4); |
4350 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 4350 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
4351 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 4351 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
4352 | 4352 |
4353 // TODO(svenpanne) Define getter/setter/attributes in a single step. | 4353 bool fast = obj->HasFastProperties(); |
4354 if (getter->IsNull() && setter->IsNull()) { | 4354 JSObject::DefineAccessor(obj, name, getter, setter, attr); |
4355 JSArray* array; | 4355 if (fast) JSObject::TransformToFastProperties(obj, 0); |
4356 { MaybeObject* maybe_array = GetOwnProperty(isolate, obj, name); | |
4357 if (!maybe_array->To(&array)) return maybe_array; | |
4358 } | |
4359 Object* current = FixedArray::cast(array->elements())->get(GETTER_INDEX); | |
4360 getter = Handle<Object>(current, isolate); | |
4361 } | |
4362 if (!getter->IsNull()) { | |
4363 MaybeObject* ok = | |
4364 obj->DefineAccessor(*name, ACCESSOR_GETTER, *getter, attr); | |
4365 if (ok->IsFailure()) return ok; | |
4366 } | |
4367 if (!setter->IsNull()) { | |
4368 MaybeObject* ok = | |
4369 obj->DefineAccessor(*name, ACCESSOR_SETTER, *setter, attr); | |
4370 if (ok->IsFailure()) return ok; | |
4371 } | |
4372 | |
4373 return isolate->heap()->undefined_value(); | 4356 return isolate->heap()->undefined_value(); |
4374 } | 4357 } |
4375 | 4358 |
4376 // Implements part of 8.12.9 DefineOwnProperty. | 4359 // Implements part of 8.12.9 DefineOwnProperty. |
4377 // There are 3 cases that lead here: | 4360 // There are 3 cases that lead here: |
4378 // Step 4a - define a new data property. | 4361 // Step 4a - define a new data property. |
4379 // Steps 9b & 12 - replace an existing accessor property with a data property. | 4362 // Steps 9b & 12 - replace an existing accessor property with a data property. |
4380 // Step 12 - update an existing data property with a data or generic | 4363 // Step 12 - update an existing data property with a data or generic |
4381 // descriptor. | 4364 // descriptor. |
4382 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { | 4365 RUNTIME_FUNCTION(MaybeObject*, Runtime_DefineOrRedefineDataProperty) { |
(...skipping 5833 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10216 // getter and/or setter. | 10199 // getter and/or setter. |
10217 bool hasJavaScriptAccessors = result_type == CALLBACKS && | 10200 bool hasJavaScriptAccessors = result_type == CALLBACKS && |
10218 result_callback_obj->IsAccessorPair(); | 10201 result_callback_obj->IsAccessorPair(); |
10219 Handle<FixedArray> details = | 10202 Handle<FixedArray> details = |
10220 isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2); | 10203 isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2); |
10221 details->set(0, *value); | 10204 details->set(0, *value); |
10222 details->set(1, property_details); | 10205 details->set(1, property_details); |
10223 if (hasJavaScriptAccessors) { | 10206 if (hasJavaScriptAccessors) { |
10224 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); | 10207 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); |
10225 details->set(2, isolate->heap()->ToBoolean(caught_exception)); | 10208 details->set(2, isolate->heap()->ToBoolean(caught_exception)); |
10226 details->set(3, accessors->SafeGet(ACCESSOR_GETTER)); | 10209 details->set(3, accessors->GetComponent(ACCESSOR_GETTER)); |
10227 details->set(4, accessors->SafeGet(ACCESSOR_SETTER)); | 10210 details->set(4, accessors->GetComponent(ACCESSOR_SETTER)); |
10228 } | 10211 } |
10229 | 10212 |
10230 return *isolate->factory()->NewJSArrayWithElements(details); | 10213 return *isolate->factory()->NewJSArrayWithElements(details); |
10231 } | 10214 } |
10232 if (i < length - 1) { | 10215 if (i < length - 1) { |
10233 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); | 10216 jsproto = Handle<JSObject>(JSObject::cast(jsproto->GetPrototype())); |
10234 } | 10217 } |
10235 } | 10218 } |
10236 | 10219 |
10237 return isolate->heap()->undefined_value(); | 10220 return isolate->heap()->undefined_value(); |
(...skipping 3124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13362 // Handle last resort GC and make sure to allow future allocations | 13345 // Handle last resort GC and make sure to allow future allocations |
13363 // to grow the heap without causing GCs (if possible). | 13346 // to grow the heap without causing GCs (if possible). |
13364 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13347 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13365 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13348 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13366 "Runtime::PerformGC"); | 13349 "Runtime::PerformGC"); |
13367 } | 13350 } |
13368 } | 13351 } |
13369 | 13352 |
13370 | 13353 |
13371 } } // namespace v8::internal | 13354 } } // namespace v8::internal |
OLD | NEW |