| 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 1496 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1507 if (!cache->IsIdentifierPart(buffer->GetNext())) { | 1507 if (!cache->IsIdentifierPart(buffer->GetNext())) { |
| 1508 return false; | 1508 return false; |
| 1509 } | 1509 } |
| 1510 } | 1510 } |
| 1511 return true; | 1511 return true; |
| 1512 } | 1512 } |
| 1513 | 1513 |
| 1514 | 1514 |
| 1515 MaybeObject* JSObject::AddFastProperty(String* name, | 1515 MaybeObject* JSObject::AddFastProperty(String* name, |
| 1516 Object* value, | 1516 Object* value, |
| 1517 PropertyAttributes attributes) { | 1517 PropertyAttributes attributes, |
| 1518 StoreFromKeyed store_mode) { |
| 1518 ASSERT(!IsJSGlobalProxy()); | 1519 ASSERT(!IsJSGlobalProxy()); |
| 1519 | 1520 |
| 1520 // Normalize the object if the name is an actual string (not the | 1521 // Normalize the object if the name is an actual string (not the |
| 1521 // hidden symbols) and is not a real identifier. | 1522 // hidden symbols) and is not a real identifier. |
| 1522 Isolate* isolate = GetHeap()->isolate(); | 1523 Isolate* isolate = GetHeap()->isolate(); |
| 1523 StringInputBuffer buffer(name); | 1524 StringInputBuffer buffer(name); |
| 1524 if (!IsIdentifier(isolate->unicode_cache(), &buffer) | 1525 if (!IsIdentifier(isolate->unicode_cache(), &buffer) |
| 1525 && name != isolate->heap()->hidden_symbol()) { | 1526 && name != isolate->heap()->hidden_symbol()) { |
| 1526 Object* obj; | 1527 Object* obj; |
| 1527 { MaybeObject* maybe_obj = | 1528 { MaybeObject* maybe_obj = |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1573 // Allocate new instance descriptors for the old map with map transition. | 1574 // Allocate new instance descriptors for the old map with map transition. |
| 1574 MapTransitionDescriptor d(name, Map::cast(new_map), attributes); | 1575 MapTransitionDescriptor d(name, Map::cast(new_map), attributes); |
| 1575 Object* r; | 1576 Object* r; |
| 1576 { MaybeObject* maybe_r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS); | 1577 { MaybeObject* maybe_r = old_descriptors->CopyInsert(&d, KEEP_TRANSITIONS); |
| 1577 if (!maybe_r->ToObject(&r)) return maybe_r; | 1578 if (!maybe_r->ToObject(&r)) return maybe_r; |
| 1578 } | 1579 } |
| 1579 old_descriptors = DescriptorArray::cast(r); | 1580 old_descriptors = DescriptorArray::cast(r); |
| 1580 } | 1581 } |
| 1581 | 1582 |
| 1582 if (map()->unused_property_fields() == 0) { | 1583 if (map()->unused_property_fields() == 0) { |
| 1583 if (TooManyFastProperties(properties()->length())) { | 1584 if (TooManyFastProperties(properties()->length(), store_mode)) { |
| 1584 Object* obj; | 1585 Object* obj; |
| 1585 { MaybeObject* maybe_obj = | 1586 { MaybeObject* maybe_obj = |
| 1586 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1587 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 1587 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1588 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1588 } | 1589 } |
| 1589 return AddSlowProperty(name, value, attributes); | 1590 return AddSlowProperty(name, value, attributes); |
| 1590 } | 1591 } |
| 1591 // Make room for the new value | 1592 // Make room for the new value |
| 1592 Object* values; | 1593 Object* values; |
| 1593 { MaybeObject* maybe_values = | 1594 { MaybeObject* maybe_values = |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1703 if (!maybe_result->ToObject(&result)) return maybe_result; | 1704 if (!maybe_result->ToObject(&result)) return maybe_result; |
| 1704 } | 1705 } |
| 1705 if (dict != result) set_properties(StringDictionary::cast(result)); | 1706 if (dict != result) set_properties(StringDictionary::cast(result)); |
| 1706 return value; | 1707 return value; |
| 1707 } | 1708 } |
| 1708 | 1709 |
| 1709 | 1710 |
| 1710 MaybeObject* JSObject::AddProperty(String* name, | 1711 MaybeObject* JSObject::AddProperty(String* name, |
| 1711 Object* value, | 1712 Object* value, |
| 1712 PropertyAttributes attributes, | 1713 PropertyAttributes attributes, |
| 1713 StrictModeFlag strict_mode) { | 1714 StrictModeFlag strict_mode, |
| 1715 JSReceiver::StoreFromKeyed store_mode) { |
| 1714 ASSERT(!IsJSGlobalProxy()); | 1716 ASSERT(!IsJSGlobalProxy()); |
| 1715 Map* map_of_this = map(); | 1717 Map* map_of_this = map(); |
| 1716 Heap* heap = GetHeap(); | 1718 Heap* heap = GetHeap(); |
| 1717 if (!map_of_this->is_extensible()) { | 1719 if (!map_of_this->is_extensible()) { |
| 1718 if (strict_mode == kNonStrictMode) { | 1720 if (strict_mode == kNonStrictMode) { |
| 1719 return value; | 1721 return value; |
| 1720 } else { | 1722 } else { |
| 1721 Handle<Object> args[1] = {Handle<String>(name)}; | 1723 Handle<Object> args[1] = {Handle<String>(name)}; |
| 1722 return heap->isolate()->Throw( | 1724 return heap->isolate()->Throw( |
| 1723 *FACTORY->NewTypeError("object_not_extensible", | 1725 *FACTORY->NewTypeError("object_not_extensible", |
| 1724 HandleVector(args, 1))); | 1726 HandleVector(args, 1))); |
| 1725 } | 1727 } |
| 1726 } | 1728 } |
| 1727 if (HasFastProperties()) { | 1729 if (HasFastProperties()) { |
| 1728 // Ensure the descriptor array does not get too big. | 1730 // Ensure the descriptor array does not get too big. |
| 1729 if (map_of_this->instance_descriptors()->number_of_descriptors() < | 1731 if (map_of_this->instance_descriptors()->number_of_descriptors() < |
| 1730 DescriptorArray::kMaxNumberOfDescriptors) { | 1732 DescriptorArray::kMaxNumberOfDescriptors) { |
| 1731 if (value->IsJSFunction()) { | 1733 if (value->IsJSFunction()) { |
| 1732 return AddConstantFunctionProperty(name, | 1734 return AddConstantFunctionProperty(name, |
| 1733 JSFunction::cast(value), | 1735 JSFunction::cast(value), |
| 1734 attributes); | 1736 attributes); |
| 1735 } else { | 1737 } else { |
| 1736 return AddFastProperty(name, value, attributes); | 1738 return AddFastProperty(name, value, attributes, store_mode); |
| 1737 } | 1739 } |
| 1738 } else { | 1740 } else { |
| 1739 // Normalize the object to prevent very large instance descriptors. | 1741 // Normalize the object to prevent very large instance descriptors. |
| 1740 // This eliminates unwanted N^2 allocation and lookup behavior. | 1742 // This eliminates unwanted N^2 allocation and lookup behavior. |
| 1741 Object* obj; | 1743 Object* obj; |
| 1742 { MaybeObject* maybe_obj = | 1744 { MaybeObject* maybe_obj = |
| 1743 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1745 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 1744 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1746 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1745 } | 1747 } |
| 1746 } | 1748 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1823 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); | 1825 old_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); |
| 1824 map()->SetBackPointer(old_map); | 1826 map()->SetBackPointer(old_map); |
| 1825 return result; | 1827 return result; |
| 1826 } | 1828 } |
| 1827 | 1829 |
| 1828 | 1830 |
| 1829 MaybeObject* JSObject::ConvertDescriptorToField(String* name, | 1831 MaybeObject* JSObject::ConvertDescriptorToField(String* name, |
| 1830 Object* new_value, | 1832 Object* new_value, |
| 1831 PropertyAttributes attributes) { | 1833 PropertyAttributes attributes) { |
| 1832 if (map()->unused_property_fields() == 0 && | 1834 if (map()->unused_property_fields() == 0 && |
| 1833 TooManyFastProperties(properties()->length())) { | 1835 TooManyFastProperties(properties()->length(), MAY_BE_STORE_FROM_KEYED)) { |
| 1834 Object* obj; | 1836 Object* obj; |
| 1835 { MaybeObject* maybe_obj = | 1837 { MaybeObject* maybe_obj = |
| 1836 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1838 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 1837 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1839 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
| 1838 } | 1840 } |
| 1839 return ReplaceSlowProperty(name, new_value, attributes); | 1841 return ReplaceSlowProperty(name, new_value, attributes); |
| 1840 } | 1842 } |
| 1841 | 1843 |
| 1842 int index = map()->NextFreePropertyIndex(); | 1844 int index = map()->NextFreePropertyIndex(); |
| 1843 FieldDescriptor new_field(name, index, attributes); | 1845 FieldDescriptor new_field(name, index, attributes); |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1938 StrictModeFlag strict_mode) { | 1940 StrictModeFlag strict_mode) { |
| 1939 CALL_HEAP_FUNCTION(object->GetIsolate(), | 1941 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 1940 object->SetProperty(*key, *value, attributes, strict_mode), | 1942 object->SetProperty(*key, *value, attributes, strict_mode), |
| 1941 Object); | 1943 Object); |
| 1942 } | 1944 } |
| 1943 | 1945 |
| 1944 | 1946 |
| 1945 MaybeObject* JSReceiver::SetProperty(String* name, | 1947 MaybeObject* JSReceiver::SetProperty(String* name, |
| 1946 Object* value, | 1948 Object* value, |
| 1947 PropertyAttributes attributes, | 1949 PropertyAttributes attributes, |
| 1948 StrictModeFlag strict_mode) { | 1950 StrictModeFlag strict_mode, |
| 1951 JSReceiver::StoreFromKeyed store_mode) { |
| 1949 LookupResult result(GetIsolate()); | 1952 LookupResult result(GetIsolate()); |
| 1950 LocalLookup(name, &result); | 1953 LocalLookup(name, &result); |
| 1951 return SetProperty(&result, name, value, attributes, strict_mode); | 1954 return SetProperty(&result, name, value, attributes, strict_mode, store_mode); |
| 1952 } | 1955 } |
| 1953 | 1956 |
| 1954 | 1957 |
| 1955 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, | 1958 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, |
| 1956 String* name, | 1959 String* name, |
| 1957 Object* value, | 1960 Object* value, |
| 1958 JSObject* holder, | 1961 JSObject* holder, |
| 1959 StrictModeFlag strict_mode) { | 1962 StrictModeFlag strict_mode) { |
| 1960 Isolate* isolate = GetIsolate(); | 1963 Isolate* isolate = GetIsolate(); |
| 1961 HandleScope scope(isolate); | 1964 HandleScope scope(isolate); |
| (...skipping 650 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2612 Handle<Object> value_handle(value); | 2615 Handle<Object> value_handle(value); |
| 2613 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 2616 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 2614 return *value_handle; | 2617 return *value_handle; |
| 2615 } | 2618 } |
| 2616 | 2619 |
| 2617 | 2620 |
| 2618 MaybeObject* JSReceiver::SetProperty(LookupResult* result, | 2621 MaybeObject* JSReceiver::SetProperty(LookupResult* result, |
| 2619 String* key, | 2622 String* key, |
| 2620 Object* value, | 2623 Object* value, |
| 2621 PropertyAttributes attributes, | 2624 PropertyAttributes attributes, |
| 2622 StrictModeFlag strict_mode) { | 2625 StrictModeFlag strict_mode, |
| 2626 JSReceiver::StoreFromKeyed store_mode) { |
| 2623 if (result->IsFound() && result->type() == HANDLER) { | 2627 if (result->IsFound() && result->type() == HANDLER) { |
| 2624 return result->proxy()->SetPropertyWithHandler( | 2628 return result->proxy()->SetPropertyWithHandler( |
| 2625 this, key, value, attributes, strict_mode); | 2629 this, key, value, attributes, strict_mode); |
| 2626 } else { | 2630 } else { |
| 2627 return JSObject::cast(this)->SetPropertyForResult( | 2631 return JSObject::cast(this)->SetPropertyForResult( |
| 2628 result, key, value, attributes, strict_mode); | 2632 result, key, value, attributes, strict_mode, store_mode); |
| 2629 } | 2633 } |
| 2630 } | 2634 } |
| 2631 | 2635 |
| 2632 | 2636 |
| 2633 bool JSProxy::HasPropertyWithHandler(String* name_raw) { | 2637 bool JSProxy::HasPropertyWithHandler(String* name_raw) { |
| 2634 Isolate* isolate = GetIsolate(); | 2638 Isolate* isolate = GetIsolate(); |
| 2635 HandleScope scope(isolate); | 2639 HandleScope scope(isolate); |
| 2636 Handle<Object> receiver(this); | 2640 Handle<Object> receiver(this); |
| 2637 Handle<Object> name(name_raw); | 2641 Handle<Object> name(name_raw); |
| 2638 | 2642 |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2901 | 2905 |
| 2902 bool threw; | 2906 bool threw; |
| 2903 return Execution::Call(trap, handler, argc, argv, &threw); | 2907 return Execution::Call(trap, handler, argc, argv, &threw); |
| 2904 } | 2908 } |
| 2905 | 2909 |
| 2906 | 2910 |
| 2907 MaybeObject* JSObject::SetPropertyForResult(LookupResult* result, | 2911 MaybeObject* JSObject::SetPropertyForResult(LookupResult* result, |
| 2908 String* name, | 2912 String* name, |
| 2909 Object* value, | 2913 Object* value, |
| 2910 PropertyAttributes attributes, | 2914 PropertyAttributes attributes, |
| 2911 StrictModeFlag strict_mode) { | 2915 StrictModeFlag strict_mode, |
| 2916 StoreFromKeyed store_mode) { |
| 2912 Heap* heap = GetHeap(); | 2917 Heap* heap = GetHeap(); |
| 2913 // Make sure that the top context does not change when doing callbacks or | 2918 // Make sure that the top context does not change when doing callbacks or |
| 2914 // interceptor calls. | 2919 // interceptor calls. |
| 2915 AssertNoContextChange ncc; | 2920 AssertNoContextChange ncc; |
| 2916 | 2921 |
| 2917 // Optimization for 2-byte strings often used as keys in a decompression | 2922 // Optimization for 2-byte strings often used as keys in a decompression |
| 2918 // dictionary. We make these short keys into symbols to avoid constantly | 2923 // dictionary. We make these short keys into symbols to avoid constantly |
| 2919 // reallocating them. | 2924 // reallocating them. |
| 2920 if (!name->IsSymbol() && name->length() <= 2) { | 2925 if (!name->IsSymbol() && name->length() <= 2) { |
| 2921 Object* symbol_version; | 2926 Object* symbol_version; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2932 return SetPropertyWithFailedAccessCheck( | 2937 return SetPropertyWithFailedAccessCheck( |
| 2933 result, name, value, true, strict_mode); | 2938 result, name, value, true, strict_mode); |
| 2934 } | 2939 } |
| 2935 } | 2940 } |
| 2936 | 2941 |
| 2937 if (IsJSGlobalProxy()) { | 2942 if (IsJSGlobalProxy()) { |
| 2938 Object* proto = GetPrototype(); | 2943 Object* proto = GetPrototype(); |
| 2939 if (proto->IsNull()) return value; | 2944 if (proto->IsNull()) return value; |
| 2940 ASSERT(proto->IsJSGlobalObject()); | 2945 ASSERT(proto->IsJSGlobalObject()); |
| 2941 return JSObject::cast(proto)->SetPropertyForResult( | 2946 return JSObject::cast(proto)->SetPropertyForResult( |
| 2942 result, name, value, attributes, strict_mode); | 2947 result, name, value, attributes, strict_mode, store_mode); |
| 2943 } | 2948 } |
| 2944 | 2949 |
| 2945 if (!result->IsProperty() && !IsJSContextExtensionObject()) { | 2950 if (!result->IsProperty() && !IsJSContextExtensionObject()) { |
| 2946 bool done = false; | 2951 bool done = false; |
| 2947 MaybeObject* result_object = | 2952 MaybeObject* result_object = |
| 2948 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); | 2953 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); |
| 2949 if (done) return result_object; | 2954 if (done) return result_object; |
| 2950 } | 2955 } |
| 2951 | 2956 |
| 2952 if (!result->IsFound()) { | 2957 if (!result->IsFound()) { |
| 2953 // Neither properties nor transitions found. | 2958 // Neither properties nor transitions found. |
| 2954 return AddProperty(name, value, attributes, strict_mode); | 2959 return AddProperty(name, value, attributes, strict_mode, store_mode); |
| 2955 } | 2960 } |
| 2956 if (result->IsReadOnly() && result->IsProperty()) { | 2961 if (result->IsReadOnly() && result->IsProperty()) { |
| 2957 if (strict_mode == kStrictMode) { | 2962 if (strict_mode == kStrictMode) { |
| 2958 Handle<JSObject> self(this); | 2963 Handle<JSObject> self(this); |
| 2959 Handle<String> hname(name); | 2964 Handle<String> hname(name); |
| 2960 Handle<Object> args[] = { hname, self }; | 2965 Handle<Object> args[] = { hname, self }; |
| 2961 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( | 2966 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( |
| 2962 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); | 2967 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); |
| 2963 } else { | 2968 } else { |
| 2964 return value; | 2969 return value; |
| (...skipping 10323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 13288 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 13293 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
| 13289 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 13294 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
| 13290 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 13295 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
| 13291 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 13296 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
| 13292 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 13297 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
| 13293 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 13298 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
| 13294 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 13299 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
| 13295 } | 13300 } |
| 13296 | 13301 |
| 13297 } } // namespace v8::internal | 13302 } } // namespace v8::internal |
| OLD | NEW |