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 1152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1163 return heap->undefined_value(); | 1163 return heap->undefined_value(); |
1164 } | 1164 } |
1165 | 1165 |
1166 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) { | 1166 if (!CheckAccess(*obj, *name, &result, v8::ACCESS_HAS)) { |
1167 return heap->false_value(); | 1167 return heap->false_value(); |
1168 } | 1168 } |
1169 | 1169 |
1170 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum())); | 1170 elms->set(ENUMERABLE_INDEX, heap->ToBoolean(!result.IsDontEnum())); |
1171 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete())); | 1171 elms->set(CONFIGURABLE_INDEX, heap->ToBoolean(!result.IsDontDelete())); |
1172 | 1172 |
1173 bool is_js_accessor = result.IsCallbacks() && | 1173 bool is_js_accessor = result.IsPropertyCallbacks() && |
1174 (result.GetCallbackObject()->IsAccessorPair()); | 1174 (result.GetCallbackObject()->IsAccessorPair()); |
1175 | 1175 |
1176 if (is_js_accessor) { | 1176 if (is_js_accessor) { |
1177 // __defineGetter__/__defineSetter__ callback. | 1177 // __defineGetter__/__defineSetter__ callback. |
1178 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); | 1178 elms->set(IS_ACCESSOR_INDEX, heap->true_value()); |
1179 | 1179 |
1180 AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject()); | 1180 AccessorPair* accessors = AccessorPair::cast(result.GetCallbackObject()); |
1181 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); | 1181 Object* getter = accessors->GetComponent(ACCESSOR_GETTER); |
1182 if (!getter->IsMap() && CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { | 1182 if (!getter->IsMap() && CheckAccess(*obj, *name, &result, v8::ACCESS_GET)) { |
1183 elms->set(GETTER_INDEX, getter); | 1183 elms->set(GETTER_INDEX, getter); |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1414 attr |= READ_ONLY; | 1414 attr |= READ_ONLY; |
1415 } | 1415 } |
1416 | 1416 |
1417 LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags); | 1417 LanguageMode language_mode = DeclareGlobalsLanguageMode::decode(flags); |
1418 | 1418 |
1419 if (!lookup.IsProperty() || is_function || is_module) { | 1419 if (!lookup.IsProperty() || is_function || is_module) { |
1420 // If the local property exists, check that we can reconfigure it | 1420 // If the local property exists, check that we can reconfigure it |
1421 // as required for function declarations. | 1421 // as required for function declarations. |
1422 if (lookup.IsProperty() && lookup.IsDontDelete()) { | 1422 if (lookup.IsProperty() && lookup.IsDontDelete()) { |
1423 if (lookup.IsReadOnly() || lookup.IsDontEnum() || | 1423 if (lookup.IsReadOnly() || lookup.IsDontEnum() || |
1424 lookup.IsCallbacks()) { | 1424 lookup.IsPropertyCallbacks()) { |
1425 return ThrowRedeclarationError( | 1425 return ThrowRedeclarationError( |
1426 isolate, is_function ? "function" : "module", name); | 1426 isolate, is_function ? "function" : "module", name); |
1427 } | 1427 } |
1428 // If the existing property is not configurable, keep its attributes. | 1428 // If the existing property is not configurable, keep its attributes. |
1429 attr = lookup.GetAttributes(); | 1429 attr = lookup.GetAttributes(); |
1430 } | 1430 } |
1431 // Define or redefine own property. | 1431 // Define or redefine own property. |
1432 RETURN_IF_EMPTY_HANDLE(isolate, | 1432 RETURN_IF_EMPTY_HANDLE(isolate, |
1433 JSObject::SetLocalPropertyIgnoreAttributes( | 1433 JSObject::SetLocalPropertyIgnoreAttributes( |
1434 global, name, value, static_cast<PropertyAttributes>(attr))); | 1434 global, name, value, static_cast<PropertyAttributes>(attr))); |
(...skipping 740 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2175 int index = instance_desc->Search(name); | 2175 int index = instance_desc->Search(name); |
2176 ASSERT(index != DescriptorArray::kNotFound); | 2176 ASSERT(index != DescriptorArray::kNotFound); |
2177 PropertyDetails details = instance_desc->GetDetails(index); | 2177 PropertyDetails details = instance_desc->GetDetails(index); |
2178 CallbacksDescriptor new_desc(name, | 2178 CallbacksDescriptor new_desc(name, |
2179 instance_desc->GetValue(index), | 2179 instance_desc->GetValue(index), |
2180 static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), | 2180 static_cast<PropertyAttributes>(details.attributes() | READ_ONLY), |
2181 details.index()); | 2181 details.index()); |
2182 // Construct a new field descriptors array containing the new descriptor. | 2182 // Construct a new field descriptors array containing the new descriptor. |
2183 Object* descriptors_unchecked; | 2183 Object* descriptors_unchecked; |
2184 { MaybeObject* maybe_descriptors_unchecked = | 2184 { MaybeObject* maybe_descriptors_unchecked = |
2185 instance_desc->CopyInsert(&new_desc, REMOVE_TRANSITIONS); | 2185 instance_desc->CopyInsert(&new_desc); |
2186 if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) { | 2186 if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) { |
2187 return maybe_descriptors_unchecked; | 2187 return maybe_descriptors_unchecked; |
2188 } | 2188 } |
2189 } | 2189 } |
2190 DescriptorArray* new_descriptors = | 2190 DescriptorArray* new_descriptors = |
2191 DescriptorArray::cast(descriptors_unchecked); | 2191 DescriptorArray::cast(descriptors_unchecked); |
2192 // Create a new map featuring the new field descriptors array. | 2192 // Create a new map featuring the new field descriptors array. |
2193 Object* map_unchecked; | 2193 Object* map_unchecked; |
2194 { MaybeObject* maybe_map_unchecked = function->map()->CopyDropDescriptors(); | 2194 { MaybeObject* maybe_map_unchecked = function->map()->CopyDropDescriptors(); |
2195 if (!maybe_map_unchecked->ToObject(&map_unchecked)) { | 2195 if (!maybe_map_unchecked->ToObject(&map_unchecked)) { |
(...skipping 2363 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4559 } | 4559 } |
4560 } | 4560 } |
4561 | 4561 |
4562 // Take special care when attributes are different and there is already | 4562 // Take special care when attributes are different and there is already |
4563 // a property. For simplicity we normalize the property which enables us | 4563 // a property. For simplicity we normalize the property which enables us |
4564 // to not worry about changing the instance_descriptor and creating a new | 4564 // to not worry about changing the instance_descriptor and creating a new |
4565 // map. The current version of SetObjectProperty does not handle attributes | 4565 // map. The current version of SetObjectProperty does not handle attributes |
4566 // correctly in the case where a property is a field and is reset with | 4566 // correctly in the case where a property is a field and is reset with |
4567 // new attributes. | 4567 // new attributes. |
4568 if (result.IsProperty() && | 4568 if (result.IsProperty() && |
4569 (attr != result.GetAttributes() || result.IsCallbacks())) { | 4569 (attr != result.GetAttributes() || result.IsPropertyCallbacks())) { |
4570 // New attributes - normalize to avoid writing to instance descriptor | 4570 // New attributes - normalize to avoid writing to instance descriptor |
4571 if (js_object->IsJSGlobalProxy()) { | 4571 if (js_object->IsJSGlobalProxy()) { |
4572 // Since the result is a property, the prototype will exist so | 4572 // Since the result is a property, the prototype will exist so |
4573 // we don't have to check for null. | 4573 // we don't have to check for null. |
4574 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); | 4574 js_object = Handle<JSObject>(JSObject::cast(js_object->GetPrototype())); |
4575 } | 4575 } |
4576 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 4576 JSObject::NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
4577 // Use IgnoreAttributes version since a readonly property may be | 4577 // Use IgnoreAttributes version since a readonly property may be |
4578 // overridden and SetProperty does not allow this. | 4578 // overridden and SetProperty does not allow this. |
4579 return js_object->SetLocalPropertyIgnoreAttributes(*name, | 4579 return js_object->SetLocalPropertyIgnoreAttributes(*name, |
(...skipping 5751 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10331 *caught_exception = true; | 10331 *caught_exception = true; |
10332 } | 10332 } |
10333 return maybe_value; | 10333 return maybe_value; |
10334 } | 10334 } |
10335 return value; | 10335 return value; |
10336 } else { | 10336 } else { |
10337 return heap->undefined_value(); | 10337 return heap->undefined_value(); |
10338 } | 10338 } |
10339 } | 10339 } |
10340 case INTERCEPTOR: | 10340 case INTERCEPTOR: |
10341 case MAP_TRANSITION: | 10341 case TRANSITION: |
10342 case CONSTANT_TRANSITION: | |
10343 return heap->undefined_value(); | 10342 return heap->undefined_value(); |
10344 case HANDLER: | 10343 case HANDLER: |
10345 case NONEXISTENT: | 10344 case NONEXISTENT: |
10346 UNREACHABLE(); | 10345 UNREACHABLE(); |
10347 return heap->undefined_value(); | 10346 return heap->undefined_value(); |
10348 } | 10347 } |
10349 UNREACHABLE(); // keep the compiler happy | 10348 UNREACHABLE(); // keep the compiler happy |
10350 return heap->undefined_value(); | 10349 return heap->undefined_value(); |
10351 } | 10350 } |
10352 | 10351 |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10412 // Try local lookup on each of the objects. | 10411 // Try local lookup on each of the objects. |
10413 Handle<JSObject> jsproto = obj; | 10412 Handle<JSObject> jsproto = obj; |
10414 for (int i = 0; i < length; i++) { | 10413 for (int i = 0; i < length; i++) { |
10415 LookupResult result(isolate); | 10414 LookupResult result(isolate); |
10416 jsproto->LocalLookup(*name, &result); | 10415 jsproto->LocalLookup(*name, &result); |
10417 if (result.IsProperty()) { | 10416 if (result.IsProperty()) { |
10418 // LookupResult is not GC safe as it holds raw object pointers. | 10417 // LookupResult is not GC safe as it holds raw object pointers. |
10419 // GC can happen later in this code so put the required fields into | 10418 // GC can happen later in this code so put the required fields into |
10420 // local variables using handles when required for later use. | 10419 // local variables using handles when required for later use. |
10421 Handle<Object> result_callback_obj; | 10420 Handle<Object> result_callback_obj; |
10422 if (result.IsCallbacks()) { | 10421 if (result.IsPropertyCallbacks()) { |
10423 result_callback_obj = Handle<Object>(result.GetCallbackObject(), | 10422 result_callback_obj = Handle<Object>(result.GetCallbackObject(), |
10424 isolate); | 10423 isolate); |
10425 } | 10424 } |
10426 Smi* property_details = result.GetPropertyDetails().AsSmi(); | 10425 Smi* property_details = result.GetPropertyDetails().AsSmi(); |
10427 // DebugLookupResultValue can cause GC so details from LookupResult needs | 10426 // DebugLookupResultValue can cause GC so details from LookupResult needs |
10428 // to be copied to handles before this. | 10427 // to be copied to handles before this. |
10429 bool caught_exception = false; | 10428 bool caught_exception = false; |
10430 Object* raw_value; | 10429 Object* raw_value; |
10431 { MaybeObject* maybe_raw_value = | 10430 { MaybeObject* maybe_raw_value = |
10432 DebugLookupResultValue(isolate->heap(), *obj, *name, | 10431 DebugLookupResultValue(isolate->heap(), *obj, *name, |
10433 &result, &caught_exception); | 10432 &result, &caught_exception); |
10434 if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value; | 10433 if (!maybe_raw_value->ToObject(&raw_value)) return maybe_raw_value; |
10435 } | 10434 } |
10436 Handle<Object> value(raw_value, isolate); | 10435 Handle<Object> value(raw_value, isolate); |
10437 | 10436 |
10438 // If the callback object is a fixed array then it contains JavaScript | 10437 // If the callback object is a fixed array then it contains JavaScript |
10439 // getter and/or setter. | 10438 // getter and/or setter. |
10440 bool hasJavaScriptAccessors = result.IsCallbacks() && | 10439 bool hasJavaScriptAccessors = result.IsPropertyCallbacks() && |
10441 result_callback_obj->IsAccessorPair(); | 10440 result_callback_obj->IsAccessorPair(); |
10442 Handle<FixedArray> details = | 10441 Handle<FixedArray> details = |
10443 isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2); | 10442 isolate->factory()->NewFixedArray(hasJavaScriptAccessors ? 5 : 2); |
10444 details->set(0, *value); | 10443 details->set(0, *value); |
10445 details->set(1, property_details); | 10444 details->set(1, property_details); |
10446 if (hasJavaScriptAccessors) { | 10445 if (hasJavaScriptAccessors) { |
10447 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); | 10446 AccessorPair* accessors = AccessorPair::cast(*result_callback_obj); |
10448 details->set(2, isolate->heap()->ToBoolean(caught_exception)); | 10447 details->set(2, isolate->heap()->ToBoolean(caught_exception)); |
10449 details->set(3, accessors->GetComponent(ACCESSOR_GETTER)); | 10448 details->set(3, accessors->GetComponent(ACCESSOR_GETTER)); |
10450 details->set(4, accessors->GetComponent(ACCESSOR_SETTER)); | 10449 details->set(4, accessors->GetComponent(ACCESSOR_SETTER)); |
(...skipping 3254 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13705 // Handle last resort GC and make sure to allow future allocations | 13704 // Handle last resort GC and make sure to allow future allocations |
13706 // to grow the heap without causing GCs (if possible). | 13705 // to grow the heap without causing GCs (if possible). |
13707 isolate->counters()->gc_last_resort_from_js()->Increment(); | 13706 isolate->counters()->gc_last_resort_from_js()->Increment(); |
13708 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, | 13707 isolate->heap()->CollectAllGarbage(Heap::kNoGCFlags, |
13709 "Runtime::PerformGC"); | 13708 "Runtime::PerformGC"); |
13710 } | 13709 } |
13711 } | 13710 } |
13712 | 13711 |
13713 | 13712 |
13714 } } // namespace v8::internal | 13713 } } // namespace v8::internal |
OLD | NEW |