| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 511 if (info->all_can_read()) { | 511 if (info->all_can_read()) { |
| 512 *attributes = result->GetAttributes(); | 512 *attributes = result->GetAttributes(); |
| 513 return result->holder()->GetPropertyWithCallback( | 513 return result->holder()->GetPropertyWithCallback( |
| 514 receiver, result->GetCallbackObject(), name); | 514 receiver, result->GetCallbackObject(), name); |
| 515 } | 515 } |
| 516 } | 516 } |
| 517 break; | 517 break; |
| 518 } | 518 } |
| 519 case NORMAL: | 519 case NORMAL: |
| 520 case FIELD: | 520 case FIELD: |
| 521 case CONSTANT_FUNCTION: { | 521 case CONSTANT: { |
| 522 // Search ALL_CAN_READ accessors in prototype chain. | 522 // Search ALL_CAN_READ accessors in prototype chain. |
| 523 LookupResult r(GetIsolate()); | 523 LookupResult r(GetIsolate()); |
| 524 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); | 524 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); |
| 525 if (r.IsProperty()) { | 525 if (r.IsProperty()) { |
| 526 return GetPropertyWithFailedAccessCheck(receiver, | 526 return GetPropertyWithFailedAccessCheck(receiver, |
| 527 &r, | 527 &r, |
| 528 name, | 528 name, |
| 529 attributes); | 529 attributes); |
| 530 } | 530 } |
| 531 break; | 531 break; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 AccessorInfo* info = AccessorInfo::cast(obj); | 572 AccessorInfo* info = AccessorInfo::cast(obj); |
| 573 if (info->all_can_read()) { | 573 if (info->all_can_read()) { |
| 574 return result->GetAttributes(); | 574 return result->GetAttributes(); |
| 575 } | 575 } |
| 576 } | 576 } |
| 577 break; | 577 break; |
| 578 } | 578 } |
| 579 | 579 |
| 580 case NORMAL: | 580 case NORMAL: |
| 581 case FIELD: | 581 case FIELD: |
| 582 case CONSTANT_FUNCTION: { | 582 case CONSTANT: { |
| 583 if (!continue_search) break; | 583 if (!continue_search) break; |
| 584 // Search ALL_CAN_READ accessors in prototype chain. | 584 // Search ALL_CAN_READ accessors in prototype chain. |
| 585 LookupResult r(GetIsolate()); | 585 LookupResult r(GetIsolate()); |
| 586 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); | 586 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); |
| 587 if (r.IsProperty()) { | 587 if (r.IsProperty()) { |
| 588 return GetPropertyAttributeWithFailedAccessCheck(receiver, | 588 return GetPropertyAttributeWithFailedAccessCheck(receiver, |
| 589 &r, | 589 &r, |
| 590 name, | 590 name, |
| 591 continue_search); | 591 continue_search); |
| 592 } | 592 } |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 867 ASSERT(!value->IsTheHole() || result->IsReadOnly()); |
| 868 return value->IsTheHole() ? heap->undefined_value() : value; | 868 return value->IsTheHole() ? heap->undefined_value() : value; |
| 869 case FIELD: { | 869 case FIELD: { |
| 870 MaybeObject* maybe_result = result->holder()->FastPropertyAt( | 870 MaybeObject* maybe_result = result->holder()->FastPropertyAt( |
| 871 result->representation(), | 871 result->representation(), |
| 872 result->GetFieldIndex().field_index()); | 872 result->GetFieldIndex().field_index()); |
| 873 if (!maybe_result->To(&value)) return maybe_result; | 873 if (!maybe_result->To(&value)) return maybe_result; |
| 874 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 874 ASSERT(!value->IsTheHole() || result->IsReadOnly()); |
| 875 return value->IsTheHole() ? heap->undefined_value() : value; | 875 return value->IsTheHole() ? heap->undefined_value() : value; |
| 876 } | 876 } |
| 877 case CONSTANT_FUNCTION: | 877 case CONSTANT: |
| 878 return result->GetConstantFunction(); | 878 return result->GetConstant(); |
| 879 case CALLBACKS: | 879 case CALLBACKS: |
| 880 return result->holder()->GetPropertyWithCallback( | 880 return result->holder()->GetPropertyWithCallback( |
| 881 receiver, result->GetCallbackObject(), name); | 881 receiver, result->GetCallbackObject(), name); |
| 882 case HANDLER: | 882 case HANDLER: |
| 883 return result->proxy()->GetPropertyWithHandler(receiver, name); | 883 return result->proxy()->GetPropertyWithHandler(receiver, name); |
| 884 case INTERCEPTOR: | 884 case INTERCEPTOR: |
| 885 return result->holder()->GetPropertyWithInterceptor( | 885 return result->holder()->GetPropertyWithInterceptor( |
| 886 receiver, name, attributes); | 886 receiver, name, attributes); |
| 887 case TRANSITION: | 887 case TRANSITION: |
| 888 case NONEXISTENT: | 888 case NONEXISTENT: |
| (...skipping 1031 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1920 new_map->set_unused_property_fields(map()->unused_property_fields() - 1); | 1920 new_map->set_unused_property_fields(map()->unused_property_fields() - 1); |
| 1921 } | 1921 } |
| 1922 | 1922 |
| 1923 set_map(new_map); | 1923 set_map(new_map); |
| 1924 | 1924 |
| 1925 FastPropertyAtPut(index, storage); | 1925 FastPropertyAtPut(index, storage); |
| 1926 return value; | 1926 return value; |
| 1927 } | 1927 } |
| 1928 | 1928 |
| 1929 | 1929 |
| 1930 MaybeObject* JSObject::AddConstantFunctionProperty( | 1930 MaybeObject* JSObject::AddConstantProperty( |
| 1931 Name* name, | 1931 Name* name, |
| 1932 JSFunction* function, | 1932 Object* constant, |
| 1933 PropertyAttributes attributes) { | 1933 PropertyAttributes attributes) { |
| 1934 // Allocate new instance descriptors with (name, function) added | 1934 // Allocate new instance descriptors with (name, constant) added |
| 1935 ConstantFunctionDescriptor d(name, function, attributes); | 1935 ConstantDescriptor d(name, constant, attributes); |
| 1936 | 1936 |
| 1937 TransitionFlag flag = | 1937 TransitionFlag flag = |
| 1938 // Do not add transitions to global objects. | 1938 // Do not add transitions to global objects. |
| 1939 (IsGlobalObject() || | 1939 (IsGlobalObject() || |
| 1940 // Don't add transitions to special properties with non-trivial | 1940 // Don't add transitions to special properties with non-trivial |
| 1941 // attributes. | 1941 // attributes. |
| 1942 attributes != NONE) | 1942 attributes != NONE) |
| 1943 ? OMIT_TRANSITION | 1943 ? OMIT_TRANSITION |
| 1944 : INSERT_TRANSITION; | 1944 : INSERT_TRANSITION; |
| 1945 | 1945 |
| 1946 Map* new_map; | 1946 Map* new_map; |
| 1947 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); | 1947 MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); |
| 1948 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 1948 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| 1949 | 1949 |
| 1950 set_map(new_map); | 1950 set_map(new_map); |
| 1951 return function; | 1951 return constant; |
| 1952 } | 1952 } |
| 1953 | 1953 |
| 1954 | 1954 |
| 1955 // Add property in slow mode | 1955 // Add property in slow mode |
| 1956 MaybeObject* JSObject::AddSlowProperty(Name* name, | 1956 MaybeObject* JSObject::AddSlowProperty(Name* name, |
| 1957 Object* value, | 1957 Object* value, |
| 1958 PropertyAttributes attributes) { | 1958 PropertyAttributes attributes) { |
| 1959 ASSERT(!HasFastProperties()); | 1959 ASSERT(!HasFastProperties()); |
| 1960 NameDictionary* dict = property_dictionary(); | 1960 NameDictionary* dict = property_dictionary(); |
| 1961 Object* store_value = value; | 1961 Object* store_value = value; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1993 return value; | 1993 return value; |
| 1994 } | 1994 } |
| 1995 | 1995 |
| 1996 | 1996 |
| 1997 MaybeObject* JSObject::AddProperty(Name* name, | 1997 MaybeObject* JSObject::AddProperty(Name* name, |
| 1998 Object* value, | 1998 Object* value, |
| 1999 PropertyAttributes attributes, | 1999 PropertyAttributes attributes, |
| 2000 StrictModeFlag strict_mode, | 2000 StrictModeFlag strict_mode, |
| 2001 JSReceiver::StoreFromKeyed store_mode, | 2001 JSReceiver::StoreFromKeyed store_mode, |
| 2002 ExtensibilityCheck extensibility_check, | 2002 ExtensibilityCheck extensibility_check, |
| 2003 ValueType value_type) { | 2003 ValueType value_type, |
| 2004 StoreMode mode) { |
| 2004 ASSERT(!IsJSGlobalProxy()); | 2005 ASSERT(!IsJSGlobalProxy()); |
| 2005 Map* map_of_this = map(); | 2006 Map* map_of_this = map(); |
| 2006 Heap* heap = GetHeap(); | 2007 Heap* heap = GetHeap(); |
| 2007 Isolate* isolate = heap->isolate(); | 2008 Isolate* isolate = heap->isolate(); |
| 2008 MaybeObject* result; | 2009 MaybeObject* result; |
| 2009 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && | 2010 if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && |
| 2010 !map_of_this->is_extensible()) { | 2011 !map_of_this->is_extensible()) { |
| 2011 if (strict_mode == kNonStrictMode) { | 2012 if (strict_mode == kNonStrictMode) { |
| 2012 return value; | 2013 return value; |
| 2013 } else { | 2014 } else { |
| 2014 Handle<Object> args[1] = {Handle<Name>(name)}; | 2015 Handle<Object> args[1] = {Handle<Name>(name)}; |
| 2015 return isolate->Throw( | 2016 return isolate->Throw( |
| 2016 *isolate->factory()->NewTypeError("object_not_extensible", | 2017 *isolate->factory()->NewTypeError("object_not_extensible", |
| 2017 HandleVector(args, 1))); | 2018 HandleVector(args, 1))); |
| 2018 } | 2019 } |
| 2019 } | 2020 } |
| 2020 | 2021 |
| 2021 if (HasFastProperties()) { | 2022 if (HasFastProperties()) { |
| 2022 // Ensure the descriptor array does not get too big. | 2023 // Ensure the descriptor array does not get too big. |
| 2023 if (map_of_this->NumberOfOwnDescriptors() < | 2024 if (map_of_this->NumberOfOwnDescriptors() < |
| 2024 DescriptorArray::kMaxNumberOfDescriptors) { | 2025 DescriptorArray::kMaxNumberOfDescriptors) { |
| 2026 // TODO(verwaest): Support other constants. |
| 2027 // if (mode == ALLOW_AS_CONSTANT && |
| 2028 // !value->IsTheHole() && |
| 2029 // !value->IsConsString()) { |
| 2025 if (value->IsJSFunction()) { | 2030 if (value->IsJSFunction()) { |
| 2026 result = AddConstantFunctionProperty(name, | 2031 result = AddConstantProperty(name, value, attributes); |
| 2027 JSFunction::cast(value), | |
| 2028 attributes); | |
| 2029 } else { | 2032 } else { |
| 2030 result = AddFastProperty( | 2033 result = AddFastProperty( |
| 2031 name, value, attributes, store_mode, value_type); | 2034 name, value, attributes, store_mode, value_type); |
| 2032 } | 2035 } |
| 2033 } else { | 2036 } else { |
| 2034 // Normalize the object to prevent very large instance descriptors. | 2037 // Normalize the object to prevent very large instance descriptors. |
| 2035 // This eliminates unwanted N^2 allocation and lookup behavior. | 2038 // This eliminates unwanted N^2 allocation and lookup behavior. |
| 2036 Object* obj; | 2039 Object* obj; |
| 2037 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 2040 MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 2038 if (!maybe->To(&obj)) return maybe; | 2041 if (!maybe->To(&obj)) return maybe; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2088 ASSERT(!threw); | 2091 ASSERT(!threw); |
| 2089 isolate->set_observer_delivery_pending(false); | 2092 isolate->set_observer_delivery_pending(false); |
| 2090 } | 2093 } |
| 2091 | 2094 |
| 2092 | 2095 |
| 2093 MaybeObject* JSObject::SetPropertyPostInterceptor( | 2096 MaybeObject* JSObject::SetPropertyPostInterceptor( |
| 2094 Name* name, | 2097 Name* name, |
| 2095 Object* value, | 2098 Object* value, |
| 2096 PropertyAttributes attributes, | 2099 PropertyAttributes attributes, |
| 2097 StrictModeFlag strict_mode, | 2100 StrictModeFlag strict_mode, |
| 2098 ExtensibilityCheck extensibility_check) { | 2101 ExtensibilityCheck extensibility_check, |
| 2102 StoreMode mode) { |
| 2099 // Check local property, ignore interceptor. | 2103 // Check local property, ignore interceptor. |
| 2100 LookupResult result(GetIsolate()); | 2104 LookupResult result(GetIsolate()); |
| 2101 LocalLookupRealNamedProperty(name, &result); | 2105 LocalLookupRealNamedProperty(name, &result); |
| 2102 if (!result.IsFound()) map()->LookupTransition(this, name, &result); | 2106 if (!result.IsFound()) map()->LookupTransition(this, name, &result); |
| 2103 if (result.IsFound()) { | 2107 if (result.IsFound()) { |
| 2104 // An existing property or a map transition was found. Use set property to | 2108 // An existing property or a map transition was found. Use set property to |
| 2105 // handle all these cases. | 2109 // handle all these cases. |
| 2106 return SetProperty(&result, name, value, attributes, strict_mode); | 2110 return SetProperty(&result, name, value, attributes, strict_mode); |
| 2107 } | 2111 } |
| 2108 bool done = false; | 2112 bool done = false; |
| 2109 MaybeObject* result_object; | 2113 MaybeObject* result_object; |
| 2110 result_object = | 2114 result_object = |
| 2111 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); | 2115 SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); |
| 2112 if (done) return result_object; | 2116 if (done) return result_object; |
| 2113 // Add a new real property. | 2117 // Add a new real property. |
| 2114 return AddProperty(name, value, attributes, strict_mode, | 2118 return AddProperty(name, value, attributes, strict_mode, |
| 2115 MAY_BE_STORE_FROM_KEYED, extensibility_check); | 2119 MAY_BE_STORE_FROM_KEYED, extensibility_check, |
| 2120 OPTIMAL_REPRESENTATION, mode); |
| 2116 } | 2121 } |
| 2117 | 2122 |
| 2118 | 2123 |
| 2119 MaybeObject* JSObject::ReplaceSlowProperty(Name* name, | 2124 MaybeObject* JSObject::ReplaceSlowProperty(Name* name, |
| 2120 Object* value, | 2125 Object* value, |
| 2121 PropertyAttributes attributes) { | 2126 PropertyAttributes attributes) { |
| 2122 NameDictionary* dictionary = property_dictionary(); | 2127 NameDictionary* dictionary = property_dictionary(); |
| 2123 int old_index = dictionary->FindEntry(name); | 2128 int old_index = dictionary->FindEntry(name); |
| 2124 int new_enumeration_index = 0; // 0 means "Use the next available index." | 2129 int new_enumeration_index = 0; // 0 means "Use the next available index." |
| 2125 if (old_index != -1) { | 2130 if (old_index != -1) { |
| (...skipping 244 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2370 if (!maybe_array->To(&array)) return maybe_array; | 2375 if (!maybe_array->To(&array)) return maybe_array; |
| 2371 | 2376 |
| 2372 DescriptorArray* old_descriptors = old_map->instance_descriptors(); | 2377 DescriptorArray* old_descriptors = old_map->instance_descriptors(); |
| 2373 DescriptorArray* new_descriptors = new_map->instance_descriptors(); | 2378 DescriptorArray* new_descriptors = new_map->instance_descriptors(); |
| 2374 int descriptors = new_map->NumberOfOwnDescriptors(); | 2379 int descriptors = new_map->NumberOfOwnDescriptors(); |
| 2375 | 2380 |
| 2376 for (int i = 0; i < descriptors; i++) { | 2381 for (int i = 0; i < descriptors; i++) { |
| 2377 PropertyDetails details = new_descriptors->GetDetails(i); | 2382 PropertyDetails details = new_descriptors->GetDetails(i); |
| 2378 if (details.type() != FIELD) continue; | 2383 if (details.type() != FIELD) continue; |
| 2379 PropertyDetails old_details = old_descriptors->GetDetails(i); | 2384 PropertyDetails old_details = old_descriptors->GetDetails(i); |
| 2380 ASSERT(old_details.type() == CONSTANT_FUNCTION || | 2385 ASSERT(old_details.type() == CONSTANT || |
| 2381 old_details.type() == FIELD); | 2386 old_details.type() == FIELD); |
| 2382 Object* value = old_details.type() == CONSTANT_FUNCTION | 2387 Object* value = old_details.type() == CONSTANT |
| 2383 ? old_descriptors->GetValue(i) | 2388 ? old_descriptors->GetValue(i) |
| 2384 : RawFastPropertyAt(old_descriptors->GetFieldIndex(i)); | 2389 : RawFastPropertyAt(old_descriptors->GetFieldIndex(i)); |
| 2385 if (FLAG_track_double_fields && | 2390 if (FLAG_track_double_fields && |
| 2386 !old_details.representation().IsDouble() && | 2391 !old_details.representation().IsDouble() && |
| 2387 details.representation().IsDouble()) { | 2392 details.representation().IsDouble()) { |
| 2388 if (old_details.representation().IsNone()) value = Smi::FromInt(0); | 2393 if (old_details.representation().IsNone()) value = Smi::FromInt(0); |
| 2389 // Objects must be allocated in the old object space, since the | 2394 // Objects must be allocated in the old object space, since the |
| 2390 // overall number of HeapNumbers needed for the conversion might | 2395 // overall number of HeapNumbers needed for the conversion might |
| 2391 // exceed the capacity of new space, and we would fail repeatedly | 2396 // exceed the capacity of new space, and we would fail repeatedly |
| 2392 // trying to migrate the instance. | 2397 // trying to migrate the instance. |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2987 *done = false; | 2992 *done = false; |
| 2988 // We could not find a local property so let's check whether there is an | 2993 // We could not find a local property so let's check whether there is an |
| 2989 // accessor that wants to handle the property, or whether the property is | 2994 // accessor that wants to handle the property, or whether the property is |
| 2990 // read-only on the prototype chain. | 2995 // read-only on the prototype chain. |
| 2991 LookupResult result(isolate); | 2996 LookupResult result(isolate); |
| 2992 LookupRealNamedPropertyInPrototypes(name, &result); | 2997 LookupRealNamedPropertyInPrototypes(name, &result); |
| 2993 if (result.IsFound()) { | 2998 if (result.IsFound()) { |
| 2994 switch (result.type()) { | 2999 switch (result.type()) { |
| 2995 case NORMAL: | 3000 case NORMAL: |
| 2996 case FIELD: | 3001 case FIELD: |
| 2997 case CONSTANT_FUNCTION: | 3002 case CONSTANT: |
| 2998 *done = result.IsReadOnly(); | 3003 *done = result.IsReadOnly(); |
| 2999 break; | 3004 break; |
| 3000 case INTERCEPTOR: { | 3005 case INTERCEPTOR: { |
| 3001 PropertyAttributes attr = | 3006 PropertyAttributes attr = |
| 3002 result.holder()->GetPropertyAttributeWithInterceptor( | 3007 result.holder()->GetPropertyAttributeWithInterceptor( |
| 3003 this, name, true); | 3008 this, name, true); |
| 3004 *done = !!(attr & READ_ONLY); | 3009 *done = !!(attr & READ_ONLY); |
| 3005 break; | 3010 break; |
| 3006 } | 3011 } |
| 3007 case CALLBACKS: { | 3012 case CALLBACKS: { |
| (...skipping 852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3860 lookup->GetFieldIndex().field_index())); | 3865 lookup->GetFieldIndex().field_index())); |
| 3861 storage->set_value(value->Number()); | 3866 storage->set_value(value->Number()); |
| 3862 result = *value; | 3867 result = *value; |
| 3863 break; | 3868 break; |
| 3864 } | 3869 } |
| 3865 lookup->holder()->FastPropertyAtPut( | 3870 lookup->holder()->FastPropertyAtPut( |
| 3866 lookup->GetFieldIndex().field_index(), *value); | 3871 lookup->GetFieldIndex().field_index(), *value); |
| 3867 result = *value; | 3872 result = *value; |
| 3868 break; | 3873 break; |
| 3869 } | 3874 } |
| 3870 case CONSTANT_FUNCTION: | 3875 case CONSTANT: |
| 3871 // Only replace the function if necessary. | 3876 // Only replace the constant if necessary. |
| 3872 if (*value == lookup->GetConstantFunction()) return *value; | 3877 if (*value == lookup->GetConstant()) return *value; |
| 3873 // Preserve the attributes of this existing property. | 3878 // Preserve the attributes of this existing property. |
| 3874 attributes = lookup->GetAttributes(); | 3879 attributes = lookup->GetAttributes(); |
| 3875 result = | 3880 result = lookup->holder()->ConvertDescriptorToField( |
| 3876 lookup->holder()->ConvertDescriptorToField(*name, *value, attributes); | 3881 *name, *value, attributes); |
| 3877 break; | 3882 break; |
| 3878 case CALLBACKS: { | 3883 case CALLBACKS: { |
| 3879 Object* callback_object = lookup->GetCallbackObject(); | 3884 Object* callback_object = lookup->GetCallbackObject(); |
| 3880 return self->SetPropertyWithCallback( | 3885 return self->SetPropertyWithCallback( |
| 3881 callback_object, *name, *value, lookup->holder(), strict_mode); | 3886 callback_object, *name, *value, lookup->holder(), strict_mode); |
| 3882 } | 3887 } |
| 3883 case INTERCEPTOR: | 3888 case INTERCEPTOR: |
| 3884 result = lookup->holder()->SetPropertyWithInterceptor( | 3889 result = lookup->holder()->SetPropertyWithInterceptor( |
| 3885 *name, *value, attributes, strict_mode); | 3890 *name, *value, attributes, strict_mode); |
| 3886 break; | 3891 break; |
| (...skipping 25 matching lines...) Expand all Loading... |
| 3912 result = lookup->holder()->AddFastPropertyUsingMap( | 3917 result = lookup->holder()->AddFastPropertyUsingMap( |
| 3913 transition_map, *name, *value, field_index, representation); | 3918 transition_map, *name, *value, field_index, representation); |
| 3914 } else { | 3919 } else { |
| 3915 result = lookup->holder()->ConvertDescriptorToField( | 3920 result = lookup->holder()->ConvertDescriptorToField( |
| 3916 *name, *value, attributes); | 3921 *name, *value, attributes); |
| 3917 } | 3922 } |
| 3918 } else if (details.type() == CALLBACKS) { | 3923 } else if (details.type() == CALLBACKS) { |
| 3919 result = lookup->holder()->ConvertDescriptorToField( | 3924 result = lookup->holder()->ConvertDescriptorToField( |
| 3920 *name, *value, attributes); | 3925 *name, *value, attributes); |
| 3921 } else { | 3926 } else { |
| 3922 ASSERT(details.type() == CONSTANT_FUNCTION); | 3927 ASSERT(details.type() == CONSTANT); |
| 3923 | 3928 |
| 3924 Object* constant_function = descriptors->GetValue(descriptor); | 3929 Object* constant = descriptors->GetValue(descriptor); |
| 3925 if (constant_function == *value) { | 3930 if (constant == *value) { |
| 3926 // If the same constant function is being added we can simply | 3931 // If the same constant function is being added we can simply |
| 3927 // transition to the target map. | 3932 // transition to the target map. |
| 3928 lookup->holder()->set_map(transition_map); | 3933 lookup->holder()->set_map(transition_map); |
| 3929 result = constant_function; | 3934 result = constant; |
| 3930 } else { | 3935 } else { |
| 3931 // Otherwise, replace with a map transition to a new map with a FIELD, | 3936 // Otherwise, replace with a map transition to a new map with a FIELD, |
| 3932 // even if the value is a constant function. | 3937 // even if the value is a constant function. |
| 3933 result = lookup->holder()->ConvertTransitionToMapTransition( | 3938 result = lookup->holder()->ConvertTransitionToMapTransition( |
| 3934 lookup->GetTransitionIndex(), *name, *value, attributes); | 3939 lookup->GetTransitionIndex(), *name, *value, attributes); |
| 3935 } | 3940 } |
| 3936 } | 3941 } |
| 3937 break; | 3942 break; |
| 3938 } | 3943 } |
| 3939 case HANDLER: | 3944 case HANDLER: |
| (...skipping 30 matching lines...) Expand all Loading... |
| 3970 // result are also added. If one of the functions is changed, the other | 3975 // result are also added. If one of the functions is changed, the other |
| 3971 // should be. | 3976 // should be. |
| 3972 // Note that this method cannot be used to set the prototype of a function | 3977 // Note that this method cannot be used to set the prototype of a function |
| 3973 // because ConvertDescriptorToField() which is called in "case CALLBACKS:" | 3978 // because ConvertDescriptorToField() which is called in "case CALLBACKS:" |
| 3974 // doesn't handle function prototypes correctly. | 3979 // doesn't handle function prototypes correctly. |
| 3975 Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes( | 3980 Handle<Object> JSObject::SetLocalPropertyIgnoreAttributes( |
| 3976 Handle<JSObject> object, | 3981 Handle<JSObject> object, |
| 3977 Handle<Name> key, | 3982 Handle<Name> key, |
| 3978 Handle<Object> value, | 3983 Handle<Object> value, |
| 3979 PropertyAttributes attributes, | 3984 PropertyAttributes attributes, |
| 3980 ValueType value_type) { | 3985 ValueType value_type, |
| 3986 StoreMode mode) { |
| 3981 CALL_HEAP_FUNCTION( | 3987 CALL_HEAP_FUNCTION( |
| 3982 object->GetIsolate(), | 3988 object->GetIsolate(), |
| 3983 object->SetLocalPropertyIgnoreAttributes( | 3989 object->SetLocalPropertyIgnoreAttributes( |
| 3984 *key, *value, attributes, value_type), | 3990 *key, *value, attributes, value_type, mode), |
| 3985 Object); | 3991 Object); |
| 3986 } | 3992 } |
| 3987 | 3993 |
| 3988 | 3994 |
| 3989 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( | 3995 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
| 3990 Name* name_raw, | 3996 Name* name_raw, |
| 3991 Object* value_raw, | 3997 Object* value_raw, |
| 3992 PropertyAttributes attributes, | 3998 PropertyAttributes attributes, |
| 3993 ValueType value_type) { | 3999 ValueType value_type, |
| 4000 StoreMode mode) { |
| 3994 // Make sure that the top context does not change when doing callbacks or | 4001 // Make sure that the top context does not change when doing callbacks or |
| 3995 // interceptor calls. | 4002 // interceptor calls. |
| 3996 AssertNoContextChange ncc; | 4003 AssertNoContextChange ncc; |
| 3997 Isolate* isolate = GetIsolate(); | 4004 Isolate* isolate = GetIsolate(); |
| 3998 LookupResult lookup(isolate); | 4005 LookupResult lookup(isolate); |
| 3999 LocalLookup(name_raw, &lookup, true); | 4006 LocalLookup(name_raw, &lookup, true); |
| 4000 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup); | 4007 if (!lookup.IsFound()) map()->LookupTransition(this, name_raw, &lookup); |
| 4001 // Check access rights if needed. | 4008 // Check access rights if needed. |
| 4002 if (IsAccessCheckNeeded()) { | 4009 if (IsAccessCheckNeeded()) { |
| 4003 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { | 4010 if (!isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { |
| 4004 return SetPropertyWithFailedAccessCheck(&lookup, | 4011 return SetPropertyWithFailedAccessCheck(&lookup, |
| 4005 name_raw, | 4012 name_raw, |
| 4006 value_raw, | 4013 value_raw, |
| 4007 false, | 4014 false, |
| 4008 kNonStrictMode); | 4015 kNonStrictMode); |
| 4009 } | 4016 } |
| 4010 } | 4017 } |
| 4011 | 4018 |
| 4012 if (IsJSGlobalProxy()) { | 4019 if (IsJSGlobalProxy()) { |
| 4013 Object* proto = GetPrototype(); | 4020 Object* proto = GetPrototype(); |
| 4014 if (proto->IsNull()) return value_raw; | 4021 if (proto->IsNull()) return value_raw; |
| 4015 ASSERT(proto->IsJSGlobalObject()); | 4022 ASSERT(proto->IsJSGlobalObject()); |
| 4016 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( | 4023 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( |
| 4017 name_raw, | 4024 name_raw, |
| 4018 value_raw, | 4025 value_raw, |
| 4019 attributes, | 4026 attributes, |
| 4020 value_type); | 4027 value_type, |
| 4028 mode); |
| 4021 } | 4029 } |
| 4022 | 4030 |
| 4023 // Check for accessor in prototype chain removed here in clone. | 4031 // Check for accessor in prototype chain removed here in clone. |
| 4024 if (!lookup.IsFound()) { | 4032 if (!lookup.IsFound()) { |
| 4025 // Neither properties nor transitions found. | 4033 // Neither properties nor transitions found. |
| 4026 return AddProperty( | 4034 return AddProperty( |
| 4027 name_raw, value_raw, attributes, kNonStrictMode, | 4035 name_raw, value_raw, attributes, kNonStrictMode, |
| 4028 MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, value_type); | 4036 MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, value_type, mode); |
| 4029 } | 4037 } |
| 4030 | 4038 |
| 4031 // From this point on everything needs to be handlified. | 4039 // From this point on everything needs to be handlified. |
| 4032 HandleScope scope(isolate); | 4040 HandleScope scope(isolate); |
| 4033 Handle<JSObject> self(this); | 4041 Handle<JSObject> self(this); |
| 4034 Handle<Name> name(name_raw); | 4042 Handle<Name> name(name_raw); |
| 4035 Handle<Object> value(value_raw, isolate); | 4043 Handle<Object> value(value_raw, isolate); |
| 4036 | 4044 |
| 4037 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); | 4045 Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); |
| 4038 PropertyAttributes old_attributes = ABSENT; | 4046 PropertyAttributes old_attributes = ABSENT; |
| (...skipping 29 matching lines...) Expand all Loading... |
| 4068 HeapNumber::cast(self->RawFastPropertyAt( | 4076 HeapNumber::cast(self->RawFastPropertyAt( |
| 4069 lookup.GetFieldIndex().field_index())); | 4077 lookup.GetFieldIndex().field_index())); |
| 4070 storage->set_value(value->Number()); | 4078 storage->set_value(value->Number()); |
| 4071 result = *value; | 4079 result = *value; |
| 4072 break; | 4080 break; |
| 4073 } | 4081 } |
| 4074 self->FastPropertyAtPut(lookup.GetFieldIndex().field_index(), *value); | 4082 self->FastPropertyAtPut(lookup.GetFieldIndex().field_index(), *value); |
| 4075 result = *value; | 4083 result = *value; |
| 4076 break; | 4084 break; |
| 4077 } | 4085 } |
| 4078 case CONSTANT_FUNCTION: | 4086 case CONSTANT: |
| 4079 // Only replace the function if necessary. | 4087 // Only replace the function if necessary. |
| 4080 if (*value != lookup.GetConstantFunction()) { | 4088 if (*value != lookup.GetConstant()) { |
| 4081 // Preserve the attributes of this existing property. | 4089 // Preserve the attributes of this existing property. |
| 4082 attributes = lookup.GetAttributes(); | 4090 attributes = lookup.GetAttributes(); |
| 4083 result = self->ConvertDescriptorToField(*name, *value, attributes); | 4091 result = self->ConvertDescriptorToField(*name, *value, attributes); |
| 4084 } | 4092 } |
| 4085 break; | 4093 break; |
| 4086 case CALLBACKS: | 4094 case CALLBACKS: |
| 4087 case INTERCEPTOR: | 4095 case INTERCEPTOR: |
| 4088 // Override callback in clone | 4096 // Override callback in clone |
| 4089 result = self->ConvertDescriptorToField(*name, *value, attributes); | 4097 result = self->ConvertDescriptorToField(*name, *value, attributes); |
| 4090 break; | 4098 break; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 4115 } | 4123 } |
| 4116 int field_index = descriptors->GetFieldIndex(descriptor); | 4124 int field_index = descriptors->GetFieldIndex(descriptor); |
| 4117 result = self->AddFastPropertyUsingMap( | 4125 result = self->AddFastPropertyUsingMap( |
| 4118 transition_map, *name, *value, field_index, representation); | 4126 transition_map, *name, *value, field_index, representation); |
| 4119 } else { | 4127 } else { |
| 4120 result = self->ConvertDescriptorToField(*name, *value, attributes); | 4128 result = self->ConvertDescriptorToField(*name, *value, attributes); |
| 4121 } | 4129 } |
| 4122 } else if (details.type() == CALLBACKS) { | 4130 } else if (details.type() == CALLBACKS) { |
| 4123 result = self->ConvertDescriptorToField(*name, *value, attributes); | 4131 result = self->ConvertDescriptorToField(*name, *value, attributes); |
| 4124 } else { | 4132 } else { |
| 4125 ASSERT(details.type() == CONSTANT_FUNCTION); | 4133 ASSERT(details.type() == CONSTANT); |
| 4126 | 4134 |
| 4127 // Replace transition to CONSTANT FUNCTION with a map transition to a | 4135 // Replace transition to CONSTANT FUNCTION with a map transition to a |
| 4128 // new map with a FIELD, even if the value is a function. | 4136 // new map with a FIELD, even if the value is a function. |
| 4129 result = self->ConvertTransitionToMapTransition( | 4137 result = self->ConvertTransitionToMapTransition( |
| 4130 lookup.GetTransitionIndex(), *name, *value, attributes); | 4138 lookup.GetTransitionIndex(), *name, *value, attributes); |
| 4131 } | 4139 } |
| 4132 break; | 4140 break; |
| 4133 } | 4141 } |
| 4134 case HANDLER: | 4142 case HANDLER: |
| 4135 case NONEXISTENT: | 4143 case NONEXISTENT: |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4257 Heap* heap = GetHeap(); | 4265 Heap* heap = GetHeap(); |
| 4258 if (!heap->isolate()->MayNamedAccess(this_obj, name, v8::ACCESS_HAS)) { | 4266 if (!heap->isolate()->MayNamedAccess(this_obj, name, v8::ACCESS_HAS)) { |
| 4259 return this_obj->GetPropertyAttributeWithFailedAccessCheck( | 4267 return this_obj->GetPropertyAttributeWithFailedAccessCheck( |
| 4260 receiver, lookup, name, continue_search); | 4268 receiver, lookup, name, continue_search); |
| 4261 } | 4269 } |
| 4262 } | 4270 } |
| 4263 if (lookup->IsFound()) { | 4271 if (lookup->IsFound()) { |
| 4264 switch (lookup->type()) { | 4272 switch (lookup->type()) { |
| 4265 case NORMAL: // fall through | 4273 case NORMAL: // fall through |
| 4266 case FIELD: | 4274 case FIELD: |
| 4267 case CONSTANT_FUNCTION: | 4275 case CONSTANT: |
| 4268 case CALLBACKS: | 4276 case CALLBACKS: |
| 4269 return lookup->GetAttributes(); | 4277 return lookup->GetAttributes(); |
| 4270 case HANDLER: { | 4278 case HANDLER: { |
| 4271 return JSProxy::cast(lookup->proxy())->GetPropertyAttributeWithHandler( | 4279 return JSProxy::cast(lookup->proxy())->GetPropertyAttributeWithHandler( |
| 4272 receiver, name); | 4280 receiver, name); |
| 4273 } | 4281 } |
| 4274 case INTERCEPTOR: | 4282 case INTERCEPTOR: |
| 4275 return lookup->holder()->GetPropertyAttributeWithInterceptor( | 4283 return lookup->holder()->GetPropertyAttributeWithInterceptor( |
| 4276 JSObject::cast(receiver), name, continue_search); | 4284 JSObject::cast(receiver), name, continue_search); |
| 4277 case TRANSITION: | 4285 case TRANSITION: |
| (...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4497 } | 4505 } |
| 4498 NameDictionary* dictionary; | 4506 NameDictionary* dictionary; |
| 4499 MaybeObject* maybe_dictionary = | 4507 MaybeObject* maybe_dictionary = |
| 4500 NameDictionary::Allocate(GetHeap(), property_count); | 4508 NameDictionary::Allocate(GetHeap(), property_count); |
| 4501 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; | 4509 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; |
| 4502 | 4510 |
| 4503 DescriptorArray* descs = map_of_this->instance_descriptors(); | 4511 DescriptorArray* descs = map_of_this->instance_descriptors(); |
| 4504 for (int i = 0; i < real_size; i++) { | 4512 for (int i = 0; i < real_size; i++) { |
| 4505 PropertyDetails details = descs->GetDetails(i); | 4513 PropertyDetails details = descs->GetDetails(i); |
| 4506 switch (details.type()) { | 4514 switch (details.type()) { |
| 4507 case CONSTANT_FUNCTION: { | 4515 case CONSTANT: { |
| 4508 PropertyDetails d = PropertyDetails( | 4516 PropertyDetails d = PropertyDetails( |
| 4509 details.attributes(), NORMAL, i + 1); | 4517 details.attributes(), NORMAL, i + 1); |
| 4510 Object* value = descs->GetConstantFunction(i); | 4518 Object* value = descs->GetConstant(i); |
| 4511 MaybeObject* maybe_dictionary = | 4519 MaybeObject* maybe_dictionary = |
| 4512 dictionary->Add(descs->GetKey(i), value, d); | 4520 dictionary->Add(descs->GetKey(i), value, d); |
| 4513 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; | 4521 if (!maybe_dictionary->To(&dictionary)) return maybe_dictionary; |
| 4514 break; | 4522 break; |
| 4515 } | 4523 } |
| 4516 case FIELD: { | 4524 case FIELD: { |
| 4517 PropertyDetails d = | 4525 PropertyDetails d = |
| 4518 PropertyDetails(details.attributes(), NORMAL, i + 1); | 4526 PropertyDetails(details.attributes(), NORMAL, i + 1); |
| 4519 Object* value = RawFastPropertyAt(descs->GetFieldIndex(i)); | 4527 Object* value = RawFastPropertyAt(descs->GetFieldIndex(i)); |
| 4520 MaybeObject* maybe_dictionary = | 4528 MaybeObject* maybe_dictionary = |
| (...skipping 421 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4942 if (!insert_result->To(&new_table)) return insert_result; | 4950 if (!insert_result->To(&new_table)) return insert_result; |
| 4943 // We expect no resizing for the first insert. | 4951 // We expect no resizing for the first insert. |
| 4944 ASSERT_EQ(hashtable, new_table); | 4952 ASSERT_EQ(hashtable, new_table); |
| 4945 } | 4953 } |
| 4946 | 4954 |
| 4947 MaybeObject* store_result = | 4955 MaybeObject* store_result = |
| 4948 SetPropertyPostInterceptor(GetHeap()->hidden_string(), | 4956 SetPropertyPostInterceptor(GetHeap()->hidden_string(), |
| 4949 hashtable, | 4957 hashtable, |
| 4950 DONT_ENUM, | 4958 DONT_ENUM, |
| 4951 kNonStrictMode, | 4959 kNonStrictMode, |
| 4952 OMIT_EXTENSIBILITY_CHECK); | 4960 OMIT_EXTENSIBILITY_CHECK, |
| 4961 FORCE_FIELD); |
| 4953 if (store_result->IsFailure()) return store_result; | 4962 if (store_result->IsFailure()) return store_result; |
| 4954 return hashtable; | 4963 return hashtable; |
| 4955 } | 4964 } |
| 4956 | 4965 |
| 4957 | 4966 |
| 4958 MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) { | 4967 MaybeObject* JSObject::SetHiddenPropertiesHashTable(Object* value) { |
| 4959 ASSERT(!IsJSGlobalProxy()); | 4968 ASSERT(!IsJSGlobalProxy()); |
| 4960 // We can store the identity hash inline iff there is no backing store | 4969 // We can store the identity hash inline iff there is no backing store |
| 4961 // for hidden properties yet. | 4970 // for hidden properties yet. |
| 4962 ASSERT(HasHiddenProperties() != value->IsSmi()); | 4971 ASSERT(HasHiddenProperties() != value->IsSmi()); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 4974 FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), value); | 4983 FastPropertyAtPut(descriptors->GetFieldIndex(sorted_index), value); |
| 4975 return this; | 4984 return this; |
| 4976 } | 4985 } |
| 4977 } | 4986 } |
| 4978 } | 4987 } |
| 4979 MaybeObject* store_result = | 4988 MaybeObject* store_result = |
| 4980 SetPropertyPostInterceptor(GetHeap()->hidden_string(), | 4989 SetPropertyPostInterceptor(GetHeap()->hidden_string(), |
| 4981 value, | 4990 value, |
| 4982 DONT_ENUM, | 4991 DONT_ENUM, |
| 4983 kNonStrictMode, | 4992 kNonStrictMode, |
| 4984 OMIT_EXTENSIBILITY_CHECK); | 4993 OMIT_EXTENSIBILITY_CHECK, |
| 4994 FORCE_FIELD); |
| 4985 if (store_result->IsFailure()) return store_result; | 4995 if (store_result->IsFailure()) return store_result; |
| 4986 return this; | 4996 return this; |
| 4987 } | 4997 } |
| 4988 | 4998 |
| 4989 | 4999 |
| 4990 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object, | 5000 Handle<Object> JSObject::DeletePropertyPostInterceptor(Handle<JSObject> object, |
| 4991 Handle<Name> name, | 5001 Handle<Name> name, |
| 4992 DeleteMode mode) { | 5002 DeleteMode mode) { |
| 4993 // Check local property, ignore interceptor. | 5003 // Check local property, ignore interceptor. |
| 4994 Isolate* isolate = object->GetIsolate(); | 5004 Isolate* isolate = object->GetIsolate(); |
| (...skipping 1455 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6450 Object* property = RawFastPropertyAt(descs->GetFieldIndex(i)); | 6460 Object* property = RawFastPropertyAt(descs->GetFieldIndex(i)); |
| 6451 if (FLAG_track_double_fields && | 6461 if (FLAG_track_double_fields && |
| 6452 descs->GetDetails(i).representation().IsDouble()) { | 6462 descs->GetDetails(i).representation().IsDouble()) { |
| 6453 ASSERT(property->IsHeapNumber()); | 6463 ASSERT(property->IsHeapNumber()); |
| 6454 if (value->IsNumber() && property->Number() == value->Number()) { | 6464 if (value->IsNumber() && property->Number() == value->Number()) { |
| 6455 return descs->GetKey(i); | 6465 return descs->GetKey(i); |
| 6456 } | 6466 } |
| 6457 } else if (property == value) { | 6467 } else if (property == value) { |
| 6458 return descs->GetKey(i); | 6468 return descs->GetKey(i); |
| 6459 } | 6469 } |
| 6460 } else if (descs->GetType(i) == CONSTANT_FUNCTION) { | 6470 } else if (descs->GetType(i) == CONSTANT) { |
| 6461 if (descs->GetConstantFunction(i) == value) { | 6471 if (descs->GetConstant(i) == value) { |
| 6462 return descs->GetKey(i); | 6472 return descs->GetKey(i); |
| 6463 } | 6473 } |
| 6464 } | 6474 } |
| 6465 } | 6475 } |
| 6466 return GetHeap()->undefined_value(); | 6476 return GetHeap()->undefined_value(); |
| 6467 } else { | 6477 } else { |
| 6468 return property_dictionary()->SlowReverseLookup(value); | 6478 return property_dictionary()->SlowReverseLookup(value); |
| 6469 } | 6479 } |
| 6470 } | 6480 } |
| 6471 | 6481 |
| (...skipping 1321 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7793 result->CopyFrom(descriptor, this, descriptor, witness); | 7803 result->CopyFrom(descriptor, this, descriptor, witness); |
| 7794 } | 7804 } |
| 7795 | 7805 |
| 7796 // |verbatim| -> |valid| | 7806 // |verbatim| -> |valid| |
| 7797 for (; descriptor < valid; descriptor++) { | 7807 for (; descriptor < valid; descriptor++) { |
| 7798 Name* key = GetKey(descriptor); | 7808 Name* key = GetKey(descriptor); |
| 7799 PropertyDetails details = GetDetails(descriptor); | 7809 PropertyDetails details = GetDetails(descriptor); |
| 7800 PropertyDetails other_details = other->GetDetails(descriptor); | 7810 PropertyDetails other_details = other->GetDetails(descriptor); |
| 7801 | 7811 |
| 7802 if (details.type() == FIELD || other_details.type() == FIELD || | 7812 if (details.type() == FIELD || other_details.type() == FIELD || |
| 7803 (details.type() == CONSTANT_FUNCTION && | 7813 (details.type() == CONSTANT && |
| 7804 other_details.type() == CONSTANT_FUNCTION && | 7814 other_details.type() == CONSTANT && |
| 7805 GetValue(descriptor) != other->GetValue(descriptor))) { | 7815 GetValue(descriptor) != other->GetValue(descriptor))) { |
| 7806 Representation representation = | 7816 Representation representation = |
| 7807 details.representation().generalize(other_details.representation()); | 7817 details.representation().generalize(other_details.representation()); |
| 7808 FieldDescriptor d(key, | 7818 FieldDescriptor d(key, |
| 7809 current_offset++, | 7819 current_offset++, |
| 7810 other_details.attributes(), | 7820 other_details.attributes(), |
| 7811 representation); | 7821 representation); |
| 7812 result->Set(descriptor, &d, witness); | 7822 result->Set(descriptor, &d, witness); |
| 7813 } else { | 7823 } else { |
| 7814 result->CopyFrom(descriptor, other, descriptor, witness); | 7824 result->CopyFrom(descriptor, other, descriptor, witness); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 7843 ASSERT(verbatim <= valid); | 7853 ASSERT(verbatim <= valid); |
| 7844 ASSERT(valid <= new_size); | 7854 ASSERT(valid <= new_size); |
| 7845 if (valid != new_size) return false; | 7855 if (valid != new_size) return false; |
| 7846 | 7856 |
| 7847 for (int descriptor = verbatim; descriptor < valid; descriptor++) { | 7857 for (int descriptor = verbatim; descriptor < valid; descriptor++) { |
| 7848 PropertyDetails details = GetDetails(descriptor); | 7858 PropertyDetails details = GetDetails(descriptor); |
| 7849 PropertyDetails other_details = other->GetDetails(descriptor); | 7859 PropertyDetails other_details = other->GetDetails(descriptor); |
| 7850 if (!other_details.representation().fits_into(details.representation())) { | 7860 if (!other_details.representation().fits_into(details.representation())) { |
| 7851 return false; | 7861 return false; |
| 7852 } | 7862 } |
| 7853 if (details.type() == CONSTANT_FUNCTION) { | 7863 if (details.type() == CONSTANT) { |
| 7854 if (other_details.type() != CONSTANT_FUNCTION) return false; | 7864 if (other_details.type() != CONSTANT) return false; |
| 7855 if (GetValue(descriptor) != other->GetValue(descriptor)) return false; | 7865 if (GetValue(descriptor) != other->GetValue(descriptor)) return false; |
| 7856 } | 7866 } |
| 7857 } | 7867 } |
| 7858 | 7868 |
| 7859 return true; | 7869 return true; |
| 7860 } | 7870 } |
| 7861 | 7871 |
| 7862 | 7872 |
| 7863 // We need the whiteness witness since sort will reshuffle the entries in the | 7873 // We need the whiteness witness since sort will reshuffle the entries in the |
| 7864 // descriptor array. If the descriptor array were to be black, the shuffling | 7874 // descriptor array. If the descriptor array were to be black, the shuffling |
| (...skipping 2816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10681 } | 10691 } |
| 10682 UNREACHABLE(); | 10692 UNREACHABLE(); |
| 10683 return NULL; | 10693 return NULL; |
| 10684 } | 10694 } |
| 10685 | 10695 |
| 10686 | 10696 |
| 10687 const char* Code::StubType2String(StubType type) { | 10697 const char* Code::StubType2String(StubType type) { |
| 10688 switch (type) { | 10698 switch (type) { |
| 10689 case NORMAL: return "NORMAL"; | 10699 case NORMAL: return "NORMAL"; |
| 10690 case FIELD: return "FIELD"; | 10700 case FIELD: return "FIELD"; |
| 10691 case CONSTANT_FUNCTION: return "CONSTANT_FUNCTION"; | 10701 case CONSTANT: return "CONSTANT"; |
| 10692 case CALLBACKS: return "CALLBACKS"; | 10702 case CALLBACKS: return "CALLBACKS"; |
| 10693 case INTERCEPTOR: return "INTERCEPTOR"; | 10703 case INTERCEPTOR: return "INTERCEPTOR"; |
| 10694 case MAP_TRANSITION: return "MAP_TRANSITION"; | 10704 case MAP_TRANSITION: return "MAP_TRANSITION"; |
| 10695 case NONEXISTENT: return "NONEXISTENT"; | 10705 case NONEXISTENT: return "NONEXISTENT"; |
| 10696 } | 10706 } |
| 10697 UNREACHABLE(); // keep the compiler happy | 10707 UNREACHABLE(); // keep the compiler happy |
| 10698 return NULL; | 10708 return NULL; |
| 10699 } | 10709 } |
| 10700 | 10710 |
| 10701 | 10711 |
| (...skipping 4560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15262 // instance descriptor. | 15272 // instance descriptor. |
| 15263 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k)); | 15273 MaybeObject* maybe_key = heap->InternalizeString(String::cast(k)); |
| 15264 if (!maybe_key->To(&key)) return maybe_key; | 15274 if (!maybe_key->To(&key)) return maybe_key; |
| 15265 } | 15275 } |
| 15266 | 15276 |
| 15267 PropertyDetails details = DetailsAt(i); | 15277 PropertyDetails details = DetailsAt(i); |
| 15268 int enumeration_index = details.dictionary_index(); | 15278 int enumeration_index = details.dictionary_index(); |
| 15269 PropertyType type = details.type(); | 15279 PropertyType type = details.type(); |
| 15270 | 15280 |
| 15271 if (value->IsJSFunction()) { | 15281 if (value->IsJSFunction()) { |
| 15272 ConstantFunctionDescriptor d(key, | 15282 ConstantDescriptor d(key, value, details.attributes()); |
| 15273 JSFunction::cast(value), | |
| 15274 details.attributes()); | |
| 15275 descriptors->Set(enumeration_index - 1, &d, witness); | 15283 descriptors->Set(enumeration_index - 1, &d, witness); |
| 15276 } else if (type == NORMAL) { | 15284 } else if (type == NORMAL) { |
| 15277 if (current_offset < inobject_props) { | 15285 if (current_offset < inobject_props) { |
| 15278 obj->InObjectPropertyAtPut(current_offset, | 15286 obj->InObjectPropertyAtPut(current_offset, |
| 15279 value, | 15287 value, |
| 15280 UPDATE_WRITE_BARRIER); | 15288 UPDATE_WRITE_BARRIER); |
| 15281 } else { | 15289 } else { |
| 15282 int offset = current_offset - inobject_props; | 15290 int offset = current_offset - inobject_props; |
| 15283 fields->set(offset, value); | 15291 fields->set(offset, value); |
| 15284 } | 15292 } |
| (...skipping 626 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15911 void PropertyCell::set_type(Type* type, WriteBarrierMode ignored) { | 15919 void PropertyCell::set_type(Type* type, WriteBarrierMode ignored) { |
| 15912 ASSERT(IsPropertyCell()); | 15920 ASSERT(IsPropertyCell()); |
| 15913 set_type_raw(type, ignored); | 15921 set_type_raw(type, ignored); |
| 15914 } | 15922 } |
| 15915 | 15923 |
| 15916 | 15924 |
| 15917 Type* PropertyCell::UpdateType(Handle<PropertyCell> cell, | 15925 Type* PropertyCell::UpdateType(Handle<PropertyCell> cell, |
| 15918 Handle<Object> value) { | 15926 Handle<Object> value) { |
| 15919 Isolate* isolate = cell->GetIsolate(); | 15927 Isolate* isolate = cell->GetIsolate(); |
| 15920 Handle<Type> old_type(cell->type(), isolate); | 15928 Handle<Type> old_type(cell->type(), isolate); |
| 15929 // TODO(2803): Do not track ConsString as constant because they cannot be |
| 15930 // embedded into code. |
| 15921 Handle<Type> new_type(value->IsConsString() || value->IsTheHole() | 15931 Handle<Type> new_type(value->IsConsString() || value->IsTheHole() |
| 15922 ? Type::Any() | 15932 ? Type::Any() |
| 15923 : Type::Constant(value, isolate), isolate); | 15933 : Type::Constant(value, isolate), isolate); |
| 15924 | 15934 |
| 15925 if (new_type->Is(old_type)) { | 15935 if (new_type->Is(old_type)) { |
| 15926 return *old_type; | 15936 return *old_type; |
| 15927 } | 15937 } |
| 15928 | 15938 |
| 15929 cell->dependent_code()->DeoptimizeDependentCodeGroup( | 15939 cell->dependent_code()->DeoptimizeDependentCodeGroup( |
| 15930 isolate, DependentCode::kPropertyCellChangedGroup); | 15940 isolate, DependentCode::kPropertyCellChangedGroup); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15967 | 15977 |
| 15968 void PropertyCell::AddDependentCode(Handle<Code> code) { | 15978 void PropertyCell::AddDependentCode(Handle<Code> code) { |
| 15969 Handle<DependentCode> codes = DependentCode::Insert( | 15979 Handle<DependentCode> codes = DependentCode::Insert( |
| 15970 Handle<DependentCode>(dependent_code()), | 15980 Handle<DependentCode>(dependent_code()), |
| 15971 DependentCode::kPropertyCellChangedGroup, code); | 15981 DependentCode::kPropertyCellChangedGroup, code); |
| 15972 if (*codes != dependent_code()) set_dependent_code(*codes); | 15982 if (*codes != dependent_code()) set_dependent_code(*codes); |
| 15973 } | 15983 } |
| 15974 | 15984 |
| 15975 | 15985 |
| 15976 } } // namespace v8::internal | 15986 } } // namespace v8::internal |
| OLD | NEW |