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 |