OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 3482 matching lines...) Loading... |
3493 int index = Smi::cast(args[1])->value(); | 3493 int index = Smi::cast(args[1])->value(); |
3494 Handle<Object> result = GetCharAt(str, index); | 3494 Handle<Object> result = GetCharAt(str, index); |
3495 return *result; | 3495 return *result; |
3496 } | 3496 } |
3497 | 3497 |
3498 // Fall back to GetObjectProperty. | 3498 // Fall back to GetObjectProperty. |
3499 return Runtime::GetObjectProperty(args.at<Object>(0), | 3499 return Runtime::GetObjectProperty(args.at<Object>(0), |
3500 args.at<Object>(1)); | 3500 args.at<Object>(1)); |
3501 } | 3501 } |
3502 | 3502 |
3503 | 3503 // Implements part of 8.12.9 DefineOwnProperty. |
| 3504 // There are 3 cases that lead here: |
| 3505 // Step 4b - define a new accessor property. |
| 3506 // Steps 9c & 12 - replace an existing data property with an accessor property. |
| 3507 // Step 12 - update an existing accessor property with an accessor or generic |
| 3508 // descriptor. |
3504 static MaybeObject* Runtime_DefineOrRedefineAccessorProperty(Arguments args) { | 3509 static MaybeObject* Runtime_DefineOrRedefineAccessorProperty(Arguments args) { |
3505 ASSERT(args.length() == 5); | 3510 ASSERT(args.length() == 5); |
3506 HandleScope scope; | 3511 HandleScope scope; |
3507 CONVERT_ARG_CHECKED(JSObject, obj, 0); | 3512 CONVERT_ARG_CHECKED(JSObject, obj, 0); |
3508 CONVERT_CHECKED(String, name, args[1]); | 3513 CONVERT_CHECKED(String, name, args[1]); |
3509 CONVERT_CHECKED(Smi, flag_setter, args[2]); | 3514 CONVERT_CHECKED(Smi, flag_setter, args[2]); |
3510 Object* fun = args[3]; | 3515 Object* fun = args[3]; |
3511 RUNTIME_ASSERT(fun->IsJSFunction() || fun->IsUndefined()); | 3516 RUNTIME_ASSERT(fun->IsJSFunction() || fun->IsUndefined()); |
3512 CONVERT_CHECKED(Smi, flag_attr, args[4]); | 3517 CONVERT_CHECKED(Smi, flag_attr, args[4]); |
3513 int unchecked = flag_attr->value(); | 3518 int unchecked = flag_attr->value(); |
(...skipping 11 matching lines...) Loading... |
3525 || result.type() == CONSTANT_FUNCTION)) { | 3530 || result.type() == CONSTANT_FUNCTION)) { |
3526 Object* ok; | 3531 Object* ok; |
3527 { MaybeObject* maybe_ok = | 3532 { MaybeObject* maybe_ok = |
3528 obj->DeleteProperty(name, JSObject::NORMAL_DELETION); | 3533 obj->DeleteProperty(name, JSObject::NORMAL_DELETION); |
3529 if (!maybe_ok->ToObject(&ok)) return maybe_ok; | 3534 if (!maybe_ok->ToObject(&ok)) return maybe_ok; |
3530 } | 3535 } |
3531 } | 3536 } |
3532 return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr); | 3537 return obj->DefineAccessor(name, flag_setter->value() == 0, fun, attr); |
3533 } | 3538 } |
3534 | 3539 |
| 3540 // Implements part of 8.12.9 DefineOwnProperty. |
| 3541 // There are 3 cases that lead here: |
| 3542 // Step 4a - define a new data property. |
| 3543 // Steps 9b & 12 - replace an existing accessor property with a data property. |
| 3544 // Step 12 - update an existing data property with a data or generic |
| 3545 // descriptor. |
3535 static MaybeObject* Runtime_DefineOrRedefineDataProperty(Arguments args) { | 3546 static MaybeObject* Runtime_DefineOrRedefineDataProperty(Arguments args) { |
3536 ASSERT(args.length() == 4); | 3547 ASSERT(args.length() == 4); |
3537 HandleScope scope; | 3548 HandleScope scope; |
3538 CONVERT_ARG_CHECKED(JSObject, js_object, 0); | 3549 CONVERT_ARG_CHECKED(JSObject, js_object, 0); |
3539 CONVERT_ARG_CHECKED(String, name, 1); | 3550 CONVERT_ARG_CHECKED(String, name, 1); |
3540 Handle<Object> obj_value = args.at<Object>(2); | 3551 Handle<Object> obj_value = args.at<Object>(2); |
3541 | 3552 |
3542 CONVERT_CHECKED(Smi, flag, args[3]); | 3553 CONVERT_CHECKED(Smi, flag, args[3]); |
3543 int unchecked = flag->value(); | 3554 int unchecked = flag->value(); |
3544 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); | 3555 RUNTIME_ASSERT((unchecked & ~(READ_ONLY | DONT_ENUM | DONT_DELETE)) == 0); |
3545 | 3556 |
3546 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); | 3557 PropertyAttributes attr = static_cast<PropertyAttributes>(unchecked); |
3547 | 3558 |
3548 // Check if this is an element. | 3559 // Check if this is an element. |
3549 uint32_t index; | 3560 uint32_t index; |
3550 bool is_element = name->AsArrayIndex(&index); | 3561 bool is_element = name->AsArrayIndex(&index); |
3551 | 3562 |
3552 // Special case for elements if any of the flags are true. | 3563 // Special case for elements if any of the flags are true. |
3553 // If elements are in fast case we always implicitly assume that: | 3564 // If elements are in fast case we always implicitly assume that: |
3554 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. | 3565 // DONT_DELETE: false, DONT_ENUM: false, READ_ONLY: false. |
3555 if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) && | 3566 if (((unchecked & (DONT_DELETE | DONT_ENUM | READ_ONLY)) != 0) && |
3556 is_element) { | 3567 is_element) { |
3557 // Normalize the elements to enable attributes on the property. | 3568 // Normalize the elements to enable attributes on the property. |
3558 NormalizeElements(js_object); | 3569 if (!js_object->IsJSGlobalProxy()) { |
| 3570 NormalizeElements(js_object); |
| 3571 } |
3559 Handle<NumberDictionary> dictionary(js_object->element_dictionary()); | 3572 Handle<NumberDictionary> dictionary(js_object->element_dictionary()); |
3560 // Make sure that we never go back to fast case. | 3573 // Make sure that we never go back to fast case. |
3561 dictionary->set_requires_slow_elements(); | 3574 dictionary->set_requires_slow_elements(); |
3562 PropertyDetails details = PropertyDetails(attr, NORMAL); | 3575 PropertyDetails details = PropertyDetails(attr, NORMAL); |
3563 NumberDictionarySet(dictionary, index, obj_value, details); | 3576 NumberDictionarySet(dictionary, index, obj_value, details); |
3564 } | 3577 } |
3565 | 3578 |
3566 LookupResult result; | 3579 LookupResult result; |
3567 js_object->LookupRealNamedProperty(*name, &result); | 3580 js_object->LookupRealNamedProperty(*name, &result); |
3568 | 3581 |
3569 // Take special care when attributes are different and there is already | 3582 // Take special care when attributes are different and there is already |
3570 // a property. For simplicity we normalize the property which enables us | 3583 // a property. For simplicity we normalize the property which enables us |
3571 // to not worry about changing the instance_descriptor and creating a new | 3584 // to not worry about changing the instance_descriptor and creating a new |
3572 // map. The current version of SetObjectProperty does not handle attributes | 3585 // map. The current version of SetObjectProperty does not handle attributes |
3573 // correctly in the case where a property is a field and is reset with | 3586 // correctly in the case where a property is a field and is reset with |
3574 // new attributes. | 3587 // new attributes. |
3575 if (result.IsProperty() && | 3588 if (result.IsProperty() && |
3576 (attr != result.GetAttributes() || result.type() == CALLBACKS)) { | 3589 (attr != result.GetAttributes() || result.type() == CALLBACKS)) { |
3577 // New attributes - normalize to avoid writing to instance descriptor | 3590 // New attributes - normalize to avoid writing to instance descriptor |
3578 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); | 3591 if (!js_object->IsJSGlobalProxy()) { |
| 3592 NormalizeProperties(js_object, CLEAR_INOBJECT_PROPERTIES, 0); |
| 3593 } |
3579 // Use IgnoreAttributes version since a readonly property may be | 3594 // Use IgnoreAttributes version since a readonly property may be |
3580 // overridden and SetProperty does not allow this. | 3595 // overridden and SetProperty does not allow this. |
3581 return js_object->SetLocalPropertyIgnoreAttributes(*name, | 3596 return js_object->SetLocalPropertyIgnoreAttributes(*name, |
3582 *obj_value, | 3597 *obj_value, |
3583 attr); | 3598 attr); |
3584 } | 3599 } |
3585 | 3600 |
3586 return Runtime::SetObjectProperty(js_object, name, obj_value, attr); | 3601 return Runtime::SetObjectProperty(js_object, name, obj_value, attr); |
3587 } | 3602 } |
3588 | 3603 |
(...skipping 7285 matching lines...) Loading... |
10874 } else { | 10889 } else { |
10875 // Handle last resort GC and make sure to allow future allocations | 10890 // Handle last resort GC and make sure to allow future allocations |
10876 // to grow the heap without causing GCs (if possible). | 10891 // to grow the heap without causing GCs (if possible). |
10877 Counters::gc_last_resort_from_js.Increment(); | 10892 Counters::gc_last_resort_from_js.Increment(); |
10878 Heap::CollectAllGarbage(false); | 10893 Heap::CollectAllGarbage(false); |
10879 } | 10894 } |
10880 } | 10895 } |
10881 | 10896 |
10882 | 10897 |
10883 } } // namespace v8::internal | 10898 } } // namespace v8::internal |
OLD | NEW |