| 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 1882 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1893     set_properties(values); | 1893     set_properties(values); | 
| 1894   } | 1894   } | 
| 1895 | 1895 | 
| 1896   set_map(new_map); | 1896   set_map(new_map); | 
| 1897 | 1897 | 
| 1898   FastPropertyAtPut(field_index, storage); | 1898   FastPropertyAtPut(field_index, storage); | 
| 1899   return value; | 1899   return value; | 
| 1900 } | 1900 } | 
| 1901 | 1901 | 
| 1902 | 1902 | 
| 1903 void JSObject::AddFastProperty(Handle<JSObject> object, |  | 
| 1904                              Handle<Name> name, |  | 
| 1905                              Handle<Object> value, |  | 
| 1906                              PropertyAttributes attributes, |  | 
| 1907                              StoreFromKeyed store_mode, |  | 
| 1908                              ValueType value_type, |  | 
| 1909                              TransitionFlag flag) { |  | 
| 1910   CALL_HEAP_FUNCTION_VOID( |  | 
| 1911       object->GetIsolate(), |  | 
| 1912       object->AddFastProperty( |  | 
| 1913           *name, *value, attributes, store_mode, value_type, flag)); |  | 
| 1914 } |  | 
| 1915 |  | 
| 1916 |  | 
| 1917 MaybeObject* JSObject::AddFastProperty(Name* name, | 1903 MaybeObject* JSObject::AddFastProperty(Name* name, | 
| 1918                                        Object* value, | 1904                                        Object* value, | 
| 1919                                        PropertyAttributes attributes, | 1905                                        PropertyAttributes attributes, | 
| 1920                                        StoreFromKeyed store_mode, | 1906                                        StoreFromKeyed store_mode, | 
| 1921                                        ValueType value_type, | 1907                                        ValueType value_type, | 
| 1922                                        TransitionFlag flag) { | 1908                                        TransitionFlag flag) { | 
| 1923   ASSERT(!IsJSGlobalProxy()); | 1909   ASSERT(!IsJSGlobalProxy()); | 
| 1924   ASSERT(DescriptorArray::kNotFound == | 1910   ASSERT(DescriptorArray::kNotFound == | 
| 1925          map()->instance_descriptors()->Search( | 1911          map()->instance_descriptors()->Search( | 
| 1926              name, map()->NumberOfOwnDescriptors())); | 1912              name, map()->NumberOfOwnDescriptors())); | 
| (...skipping 25 matching lines...) Expand all  Loading... | 
| 1952   int unused_property_fields = map()->unused_property_fields() - 1; | 1938   int unused_property_fields = map()->unused_property_fields() - 1; | 
| 1953   if (unused_property_fields < 0) { | 1939   if (unused_property_fields < 0) { | 
| 1954     unused_property_fields += kFieldsAdded; | 1940     unused_property_fields += kFieldsAdded; | 
| 1955   } | 1941   } | 
| 1956   new_map->set_unused_property_fields(unused_property_fields); | 1942   new_map->set_unused_property_fields(unused_property_fields); | 
| 1957 | 1943 | 
| 1958   return AddFastPropertyUsingMap(new_map, name, value, index, representation); | 1944   return AddFastPropertyUsingMap(new_map, name, value, index, representation); | 
| 1959 } | 1945 } | 
| 1960 | 1946 | 
| 1961 | 1947 | 
| 1962 void JSObject::AddConstantProperty(Handle<JSObject> object, |  | 
| 1963                                    Handle<Name> name, |  | 
| 1964                                    Handle<Object> constant, |  | 
| 1965                                    PropertyAttributes attributes, |  | 
| 1966                                    TransitionFlag flag) { |  | 
| 1967   CALL_HEAP_FUNCTION_VOID( |  | 
| 1968       object->GetIsolate(), |  | 
| 1969       object->AddConstantProperty(*name, *constant, attributes, flag)); |  | 
| 1970 } |  | 
| 1971 |  | 
| 1972 |  | 
| 1973 MaybeObject* JSObject::AddConstantProperty( | 1948 MaybeObject* JSObject::AddConstantProperty( | 
| 1974     Name* name, | 1949     Name* name, | 
| 1975     Object* constant, | 1950     Object* constant, | 
| 1976     PropertyAttributes attributes, | 1951     PropertyAttributes attributes, | 
| 1977     TransitionFlag initial_flag) { | 1952     TransitionFlag initial_flag) { | 
| 1978   // Allocate new instance descriptors with (name, constant) added | 1953   // Allocate new instance descriptors with (name, constant) added | 
| 1979   ConstantDescriptor d(name, constant, attributes); | 1954   ConstantDescriptor d(name, constant, attributes); | 
| 1980 | 1955 | 
| 1981   TransitionFlag flag = | 1956   TransitionFlag flag = | 
| 1982       // Do not add transitions to global objects. | 1957       // Do not add transitions to global objects. | 
| 1983       (IsGlobalObject() || | 1958       (IsGlobalObject() || | 
| 1984       // Don't add transitions to special properties with non-trivial | 1959       // Don't add transitions to special properties with non-trivial | 
| 1985       // attributes. | 1960       // attributes. | 
| 1986        attributes != NONE) | 1961        attributes != NONE) | 
| 1987       ? OMIT_TRANSITION | 1962       ? OMIT_TRANSITION | 
| 1988       : initial_flag; | 1963       : initial_flag; | 
| 1989 | 1964 | 
| 1990   Map* new_map; | 1965   Map* new_map; | 
| 1991   MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); | 1966   MaybeObject* maybe_new_map = map()->CopyAddDescriptor(&d, flag); | 
| 1992   if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 1967   if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 
| 1993 | 1968 | 
| 1994   set_map(new_map); | 1969   set_map(new_map); | 
| 1995   return constant; | 1970   return constant; | 
| 1996 } | 1971 } | 
| 1997 | 1972 | 
| 1998 | 1973 | 
| 1999 void JSObject::AddSlowProperty(Handle<JSObject> object, | 1974 // Add property in slow mode | 
| 2000                                Handle<Name> name, |  | 
| 2001                                Handle<Object> value, |  | 
| 2002                                PropertyAttributes attributes) { |  | 
| 2003   CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), |  | 
| 2004                           object->AddSlowProperty(*name, *value, attributes)); |  | 
| 2005 } |  | 
| 2006 |  | 
| 2007 |  | 
| 2008 MaybeObject* JSObject::AddSlowProperty(Name* name, | 1975 MaybeObject* JSObject::AddSlowProperty(Name* name, | 
| 2009                                        Object* value, | 1976                                        Object* value, | 
| 2010                                        PropertyAttributes attributes) { | 1977                                        PropertyAttributes attributes) { | 
| 2011   ASSERT(!HasFastProperties()); | 1978   ASSERT(!HasFastProperties()); | 
| 2012   NameDictionary* dict = property_dictionary(); | 1979   NameDictionary* dict = property_dictionary(); | 
| 2013   Object* store_value = value; | 1980   Object* store_value = value; | 
| 2014   if (IsGlobalObject()) { | 1981   if (IsGlobalObject()) { | 
| 2015     // In case name is an orphaned property reuse the cell. | 1982     // In case name is an orphaned property reuse the cell. | 
| 2016     int entry = dict->FindEntry(name); | 1983     int entry = dict->FindEntry(name); | 
| 2017     if (entry != NameDictionary::kNotFound) { | 1984     if (entry != NameDictionary::kNotFound) { | 
| (...skipping 21 matching lines...) Expand all  Loading... | 
| 2039   PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); | 2006   PropertyDetails details = PropertyDetails(attributes, NORMAL, 0); | 
| 2040   Object* result; | 2007   Object* result; | 
| 2041   { MaybeObject* maybe_result = dict->Add(name, store_value, details); | 2008   { MaybeObject* maybe_result = dict->Add(name, store_value, details); | 
| 2042     if (!maybe_result->ToObject(&result)) return maybe_result; | 2009     if (!maybe_result->ToObject(&result)) return maybe_result; | 
| 2043   } | 2010   } | 
| 2044   if (dict != result) set_properties(NameDictionary::cast(result)); | 2011   if (dict != result) set_properties(NameDictionary::cast(result)); | 
| 2045   return value; | 2012   return value; | 
| 2046 } | 2013 } | 
| 2047 | 2014 | 
| 2048 | 2015 | 
| 2049 Handle<Object> JSObject::AddProperty(Handle<JSObject> object, | 2016 MaybeObject* JSObject::AddProperty(Name* name, | 
| 2050                                      Handle<Name> name, | 2017                                    Object* value, | 
| 2051                                      Handle<Object> value, | 2018                                    PropertyAttributes attributes, | 
| 2052                                      PropertyAttributes attributes, | 2019                                    StrictModeFlag strict_mode, | 
| 2053                                      StrictModeFlag strict_mode, | 2020                                    JSReceiver::StoreFromKeyed store_mode, | 
| 2054                                      JSReceiver::StoreFromKeyed store_mode, | 2021                                    ExtensibilityCheck extensibility_check, | 
| 2055                                      ExtensibilityCheck extensibility_check, | 2022                                    ValueType value_type, | 
| 2056                                      ValueType value_type, | 2023                                    StoreMode mode, | 
| 2057                                      StoreMode mode, | 2024                                    TransitionFlag transition_flag) { | 
| 2058                                      TransitionFlag transition_flag) { | 2025   ASSERT(!IsJSGlobalProxy()); | 
| 2059   ASSERT(!object->IsJSGlobalProxy()); | 2026   Map* map_of_this = map(); | 
| 2060   Isolate* isolate = object->GetIsolate(); | 2027   Heap* heap = GetHeap(); | 
|  | 2028   Isolate* isolate = heap->isolate(); | 
|  | 2029   MaybeObject* result; | 
| 2061   if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && | 2030   if (extensibility_check == PERFORM_EXTENSIBILITY_CHECK && | 
| 2062       !object->map()->is_extensible()) { | 2031       !map_of_this->is_extensible()) { | 
| 2063     if (strict_mode == kNonStrictMode) { | 2032     if (strict_mode == kNonStrictMode) { | 
| 2064       return value; | 2033       return value; | 
| 2065     } else { | 2034     } else { | 
| 2066       Handle<Object> args[1] = { name }; | 2035       Handle<Object> args[1] = {Handle<Name>(name)}; | 
| 2067       Handle<Object> error = isolate->factory()->NewTypeError( | 2036       return isolate->Throw( | 
| 2068           "object_not_extensible", HandleVector(args, ARRAY_SIZE(args))); | 2037           *isolate->factory()->NewTypeError("object_not_extensible", | 
| 2069       isolate->Throw(*error); | 2038                                             HandleVector(args, 1))); | 
| 2070       return Handle<Object>(); |  | 
| 2071     } | 2039     } | 
| 2072   } | 2040   } | 
| 2073 | 2041 | 
| 2074   if (object->HasFastProperties()) { | 2042   if (HasFastProperties()) { | 
| 2075     // Ensure the descriptor array does not get too big. | 2043     // Ensure the descriptor array does not get too big. | 
| 2076     if (object->map()->NumberOfOwnDescriptors() < | 2044     if (map_of_this->NumberOfOwnDescriptors() < | 
| 2077         DescriptorArray::kMaxNumberOfDescriptors) { | 2045         DescriptorArray::kMaxNumberOfDescriptors) { | 
| 2078       // TODO(verwaest): Support other constants. | 2046       // TODO(verwaest): Support other constants. | 
| 2079       // if (mode == ALLOW_AS_CONSTANT && | 2047       // if (mode == ALLOW_AS_CONSTANT && | 
| 2080       //     !value->IsTheHole() && | 2048       //     !value->IsTheHole() && | 
| 2081       //     !value->IsConsString()) { | 2049       //     !value->IsConsString()) { | 
| 2082       if (value->IsJSFunction()) { | 2050       if (value->IsJSFunction()) { | 
| 2083         AddConstantProperty(object, name, value, attributes, transition_flag); | 2051         result = AddConstantProperty(name, value, attributes, transition_flag); | 
| 2084       } else { | 2052       } else { | 
| 2085         AddFastProperty(object, name, value, attributes, store_mode, | 2053         result = AddFastProperty( | 
| 2086                         value_type, transition_flag); | 2054             name, value, attributes, store_mode, value_type, transition_flag); | 
| 2087       } | 2055       } | 
| 2088     } else { | 2056     } else { | 
| 2089       // Normalize the object to prevent very large instance descriptors. | 2057       // Normalize the object to prevent very large instance descriptors. | 
| 2090       // This eliminates unwanted N^2 allocation and lookup behavior. | 2058       // This eliminates unwanted N^2 allocation and lookup behavior. | 
| 2091       NormalizeProperties(object, CLEAR_INOBJECT_PROPERTIES, 0); | 2059       Object* obj; | 
| 2092       AddSlowProperty(object, name, value, attributes); | 2060       MaybeObject* maybe = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 
|  | 2061       if (!maybe->To(&obj)) return maybe; | 
|  | 2062       result = AddSlowProperty(name, value, attributes); | 
| 2093     } | 2063     } | 
| 2094   } else { | 2064   } else { | 
| 2095     AddSlowProperty(object, name, value, attributes); | 2065     result = AddSlowProperty(name, value, attributes); | 
| 2096   } | 2066   } | 
| 2097 | 2067 | 
| 2098   if (FLAG_harmony_observation && object->map()->is_observed()) { | 2068   Handle<Object> hresult; | 
| 2099     Handle<Object> old_value = isolate->factory()->the_hole_value(); | 2069   if (!result->ToHandle(&hresult, isolate)) return result; | 
| 2100     EnqueueChangeRecord(object, "new", name, old_value); | 2070 | 
|  | 2071   if (FLAG_harmony_observation && map()->is_observed()) { | 
|  | 2072     EnqueueChangeRecord(handle(this, isolate), | 
|  | 2073                         "new", | 
|  | 2074                         handle(name, isolate), | 
|  | 2075                         handle(heap->the_hole_value(), isolate)); | 
| 2101   } | 2076   } | 
| 2102 | 2077 | 
| 2103   return value; | 2078   return *hresult; | 
| 2104 } | 2079 } | 
| 2105 | 2080 | 
| 2106 | 2081 | 
| 2107 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, | 2082 void JSObject::EnqueueChangeRecord(Handle<JSObject> object, | 
| 2108                                    const char* type_str, | 2083                                    const char* type_str, | 
| 2109                                    Handle<Name> name, | 2084                                    Handle<Name> name, | 
| 2110                                    Handle<Object> old_value) { | 2085                                    Handle<Object> old_value) { | 
| 2111   Isolate* isolate = object->GetIsolate(); | 2086   Isolate* isolate = object->GetIsolate(); | 
| 2112   HandleScope scope(isolate); | 2087   HandleScope scope(isolate); | 
| 2113   Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); | 2088   Handle<String> type = isolate->factory()->InternalizeUtf8String(type_str); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 2133       isolate->observers_deliver_changes(), | 2108       isolate->observers_deliver_changes(), | 
| 2134       isolate->factory()->undefined_value(), | 2109       isolate->factory()->undefined_value(), | 
| 2135       0, | 2110       0, | 
| 2136       NULL, | 2111       NULL, | 
| 2137       &threw); | 2112       &threw); | 
| 2138   ASSERT(!threw); | 2113   ASSERT(!threw); | 
| 2139   isolate->set_observer_delivery_pending(false); | 2114   isolate->set_observer_delivery_pending(false); | 
| 2140 } | 2115 } | 
| 2141 | 2116 | 
| 2142 | 2117 | 
| 2143 Handle<Object> JSObject::SetPropertyPostInterceptor( | 2118 MaybeObject* JSObject::SetPropertyPostInterceptor( | 
| 2144     Handle<JSObject> object, | 2119     Name* name, | 
| 2145     Handle<Name> name, | 2120     Object* value, | 
| 2146     Handle<Object> value, |  | 
| 2147     PropertyAttributes attributes, | 2121     PropertyAttributes attributes, | 
| 2148     StrictModeFlag strict_mode) { | 2122     StrictModeFlag strict_mode, | 
|  | 2123     StoreMode mode) { | 
| 2149   // Check local property, ignore interceptor. | 2124   // Check local property, ignore interceptor. | 
| 2150   LookupResult result(object->GetIsolate()); | 2125   LookupResult result(GetIsolate()); | 
| 2151   object->LocalLookupRealNamedProperty(*name, &result); | 2126   LocalLookupRealNamedProperty(name, &result); | 
| 2152   if (!result.IsFound()) { | 2127   if (!result.IsFound()) map()->LookupTransition(this, name, &result); | 
| 2153     object->map()->LookupTransition(*object, *name, &result); |  | 
| 2154   } |  | 
| 2155   if (result.IsFound()) { | 2128   if (result.IsFound()) { | 
| 2156     // An existing property or a map transition was found. Use set property to | 2129     // An existing property or a map transition was found. Use set property to | 
| 2157     // handle all these cases. | 2130     // handle all these cases. | 
| 2158     CALL_HEAP_FUNCTION(object->GetIsolate(), | 2131     return SetProperty(&result, name, value, attributes, strict_mode); | 
| 2159                        object->SetProperty( |  | 
| 2160                            &result, *name, *value, attributes, strict_mode), |  | 
| 2161                        Object); |  | 
| 2162   } | 2132   } | 
| 2163   bool done = false; | 2133   bool done = false; | 
| 2164   Handle<Object> result_object = SetPropertyViaPrototypes( | 2134   MaybeObject* result_object = | 
| 2165       object, name, value, attributes, strict_mode, &done); | 2135       SetPropertyViaPrototypes(name, value, attributes, strict_mode, &done); | 
| 2166   if (done) return result_object; | 2136   if (done) return result_object; | 
| 2167   // Add a new real property. | 2137   // Add a new real property. | 
| 2168   return AddProperty(object, name, value, attributes, strict_mode); | 2138   return AddProperty(name, value, attributes, strict_mode, | 
|  | 2139                      MAY_BE_STORE_FROM_KEYED, PERFORM_EXTENSIBILITY_CHECK, | 
|  | 2140                      OPTIMAL_REPRESENTATION, mode); | 
| 2169 } | 2141 } | 
| 2170 | 2142 | 
| 2171 | 2143 | 
| 2172 MaybeObject* JSObject::ReplaceSlowProperty(Name* name, | 2144 MaybeObject* JSObject::ReplaceSlowProperty(Name* name, | 
| 2173                                            Object* value, | 2145                                            Object* value, | 
| 2174                                            PropertyAttributes attributes) { | 2146                                            PropertyAttributes attributes) { | 
| 2175   NameDictionary* dictionary = property_dictionary(); | 2147   NameDictionary* dictionary = property_dictionary(); | 
| 2176   int old_index = dictionary->FindEntry(name); | 2148   int old_index = dictionary->FindEntry(name); | 
| 2177   int new_enumeration_index = 0;  // 0 means "Use the next available index." | 2149   int new_enumeration_index = 0;  // 0 means "Use the next available index." | 
| 2178   if (old_index != -1) { | 2150   if (old_index != -1) { | 
| (...skipping 545 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2724   int valid = updated->NumberOfOwnDescriptors(); | 2696   int valid = updated->NumberOfOwnDescriptors(); | 
| 2725   if (!updated_descriptors->IsMoreGeneralThan( | 2697   if (!updated_descriptors->IsMoreGeneralThan( | 
| 2726           verbatim, valid, descriptors, old_descriptors)) { | 2698           verbatim, valid, descriptors, old_descriptors)) { | 
| 2727     return NULL; | 2699     return NULL; | 
| 2728   } | 2700   } | 
| 2729 | 2701 | 
| 2730   return updated; | 2702   return updated; | 
| 2731 } | 2703 } | 
| 2732 | 2704 | 
| 2733 | 2705 | 
| 2734 Handle<Object> JSObject::SetPropertyWithInterceptor( | 2706 MaybeObject* JSObject::SetPropertyWithInterceptor( | 
| 2735     Handle<JSObject> object, | 2707     Name* name, | 
| 2736     Handle<Name> name, | 2708     Object* value, | 
| 2737     Handle<Object> value, |  | 
| 2738     PropertyAttributes attributes, | 2709     PropertyAttributes attributes, | 
| 2739     StrictModeFlag strict_mode) { | 2710     StrictModeFlag strict_mode) { | 
| 2740   // TODO(rossberg): Support symbols in the API. | 2711   // TODO(rossberg): Support symbols in the API. | 
| 2741   if (name->IsSymbol()) return value; | 2712   if (name->IsSymbol()) return value; | 
| 2742   Isolate* isolate = object->GetIsolate(); | 2713   Isolate* isolate = GetIsolate(); | 
| 2743   Handle<String> name_string = Handle<String>::cast(name); | 2714   HandleScope scope(isolate); | 
| 2744   Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); | 2715   Handle<JSObject> this_handle(this); | 
|  | 2716   Handle<String> name_handle(String::cast(name)); | 
|  | 2717   Handle<Object> value_handle(value, isolate); | 
|  | 2718   Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 
| 2745   if (!interceptor->setter()->IsUndefined()) { | 2719   if (!interceptor->setter()->IsUndefined()) { | 
| 2746     LOG(isolate, | 2720     LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name)); | 
| 2747         ApiNamedPropertyAccess("interceptor-named-set", *object, *name)); | 2721     PropertyCallbackArguments args(isolate, interceptor->data(), this, this); | 
| 2748     PropertyCallbackArguments args( |  | 
| 2749         isolate, interceptor->data(), *object, *object); |  | 
| 2750     v8::NamedPropertySetterCallback setter = | 2722     v8::NamedPropertySetterCallback setter = | 
| 2751         v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter()); | 2723         v8::ToCData<v8::NamedPropertySetterCallback>(interceptor->setter()); | 
| 2752     Handle<Object> value_unhole = value->IsTheHole() | 2724     Handle<Object> value_unhole(value->IsTheHole() ? | 
| 2753         ? Handle<Object>(isolate->factory()->undefined_value()) : value; | 2725                                 isolate->heap()->undefined_value() : | 
|  | 2726                                 value, | 
|  | 2727                                 isolate); | 
| 2754     v8::Handle<v8::Value> result = args.Call(setter, | 2728     v8::Handle<v8::Value> result = args.Call(setter, | 
| 2755                                              v8::Utils::ToLocal(name_string), | 2729                                              v8::Utils::ToLocal(name_handle), | 
| 2756                                              v8::Utils::ToLocal(value_unhole)); | 2730                                              v8::Utils::ToLocal(value_unhole)); | 
| 2757     RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); | 2731     RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 
| 2758     if (!result.IsEmpty()) return value; | 2732     if (!result.IsEmpty()) return *value_handle; | 
| 2759   } | 2733   } | 
| 2760   Handle<Object> result = | 2734   MaybeObject* raw_result = | 
| 2761       SetPropertyPostInterceptor(object, name, value, attributes, strict_mode); | 2735       this_handle->SetPropertyPostInterceptor(*name_handle, | 
| 2762   RETURN_HANDLE_IF_SCHEDULED_EXCEPTION(isolate, Object); | 2736                                               *value_handle, | 
| 2763   return result; | 2737                                               attributes, | 
|  | 2738                                               strict_mode); | 
|  | 2739   RETURN_IF_SCHEDULED_EXCEPTION(isolate); | 
|  | 2740   return raw_result; | 
| 2764 } | 2741 } | 
| 2765 | 2742 | 
| 2766 | 2743 | 
| 2767 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, | 2744 Handle<Object> JSReceiver::SetProperty(Handle<JSReceiver> object, | 
| 2768                                        Handle<Name> key, | 2745                                        Handle<Name> key, | 
| 2769                                        Handle<Object> value, | 2746                                        Handle<Object> value, | 
| 2770                                        PropertyAttributes attributes, | 2747                                        PropertyAttributes attributes, | 
| 2771                                        StrictModeFlag strict_mode) { | 2748                                        StrictModeFlag strict_mode) { | 
| 2772   CALL_HEAP_FUNCTION(object->GetIsolate(), | 2749   CALL_HEAP_FUNCTION(object->GetIsolate(), | 
| 2773                      object->SetProperty(*key, *value, attributes, strict_mode), | 2750                      object->SetProperty(*key, *value, attributes, strict_mode), | 
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2946                                       value, | 2923                                       value, | 
| 2947                                       JSObject::cast(pt), | 2924                                       JSObject::cast(pt), | 
| 2948                                       strict_mode); | 2925                                       strict_mode); | 
| 2949       } | 2926       } | 
| 2950     } | 2927     } | 
| 2951   } | 2928   } | 
| 2952   *found = false; | 2929   *found = false; | 
| 2953   return heap->the_hole_value(); | 2930   return heap->the_hole_value(); | 
| 2954 } | 2931 } | 
| 2955 | 2932 | 
| 2956 Handle<Object> JSObject::SetPropertyViaPrototypes(Handle<JSObject> object, | 2933 MaybeObject* JSObject::SetPropertyViaPrototypes( | 
| 2957                                                   Handle<Name> name, | 2934     Name* name, | 
| 2958                                                   Handle<Object> value, | 2935     Object* value, | 
| 2959                                                   PropertyAttributes attributes, | 2936     PropertyAttributes attributes, | 
| 2960                                                   StrictModeFlag strict_mode, | 2937     StrictModeFlag strict_mode, | 
| 2961                                                   bool* done) { | 2938     bool* done) { | 
| 2962   Isolate* isolate = object->GetIsolate(); | 2939   Heap* heap = GetHeap(); | 
|  | 2940   Isolate* isolate = heap->isolate(); | 
| 2963 | 2941 | 
| 2964   *done = false; | 2942   *done = false; | 
| 2965   // We could not find a local property so let's check whether there is an | 2943   // We could not find a local property so let's check whether there is an | 
| 2966   // accessor that wants to handle the property, or whether the property is | 2944   // accessor that wants to handle the property, or whether the property is | 
| 2967   // read-only on the prototype chain. | 2945   // read-only on the prototype chain. | 
| 2968   LookupResult result(isolate); | 2946   LookupResult result(isolate); | 
| 2969   object->LookupRealNamedPropertyInPrototypes(*name, &result); | 2947   LookupRealNamedPropertyInPrototypes(name, &result); | 
| 2970   if (result.IsFound()) { | 2948   if (result.IsFound()) { | 
| 2971     switch (result.type()) { | 2949     switch (result.type()) { | 
| 2972       case NORMAL: | 2950       case NORMAL: | 
| 2973       case FIELD: | 2951       case FIELD: | 
| 2974       case CONSTANT: | 2952       case CONSTANT: | 
| 2975         *done = result.IsReadOnly(); | 2953         *done = result.IsReadOnly(); | 
| 2976         break; | 2954         break; | 
| 2977       case INTERCEPTOR: { | 2955       case INTERCEPTOR: { | 
| 2978         PropertyAttributes attr = | 2956         PropertyAttributes attr = | 
| 2979             result.holder()->GetPropertyAttributeWithInterceptor( | 2957             result.holder()->GetPropertyAttributeWithInterceptor( | 
| 2980                 *object, *name, true); | 2958                 this, name, true); | 
| 2981         *done = !!(attr & READ_ONLY); | 2959         *done = !!(attr & READ_ONLY); | 
| 2982         break; | 2960         break; | 
| 2983       } | 2961       } | 
| 2984       case CALLBACKS: { | 2962       case CALLBACKS: { | 
| 2985         if (!FLAG_es5_readonly && result.IsReadOnly()) break; | 2963         if (!FLAG_es5_readonly && result.IsReadOnly()) break; | 
| 2986         *done = true; | 2964         *done = true; | 
| 2987         CALL_HEAP_FUNCTION(isolate, | 2965         return SetPropertyWithCallback(result.GetCallbackObject(), | 
| 2988                            object->SetPropertyWithCallback( | 2966             name, value, result.holder(), strict_mode); | 
| 2989                                result.GetCallbackObject(), |  | 
| 2990                                *name, *value, result.holder(), strict_mode), |  | 
| 2991                            Object); |  | 
| 2992       } | 2967       } | 
| 2993       case HANDLER: { | 2968       case HANDLER: { | 
| 2994         CALL_HEAP_FUNCTION(isolate, | 2969         return result.proxy()->SetPropertyViaPrototypesWithHandler( | 
| 2995                            result.proxy()->SetPropertyViaPrototypesWithHandler( | 2970             this, name, value, attributes, strict_mode, done); | 
| 2996                                *object, *name, *value, attributes, strict_mode, |  | 
| 2997                                done), |  | 
| 2998                            Object); |  | 
| 2999       } | 2971       } | 
| 3000       case TRANSITION: | 2972       case TRANSITION: | 
| 3001       case NONEXISTENT: | 2973       case NONEXISTENT: | 
| 3002         UNREACHABLE(); | 2974         UNREACHABLE(); | 
| 3003         break; | 2975         break; | 
| 3004     } | 2976     } | 
| 3005   } | 2977   } | 
| 3006 | 2978 | 
| 3007   // If we get here with *done true, we have encountered a read-only property. | 2979   // If we get here with *done true, we have encountered a read-only property. | 
| 3008   if (!FLAG_es5_readonly) *done = false; | 2980   if (!FLAG_es5_readonly) *done = false; | 
| 3009   if (*done) { | 2981   if (*done) { | 
| 3010     if (strict_mode == kNonStrictMode) return value; | 2982     if (strict_mode == kNonStrictMode) return value; | 
| 3011     Handle<Object> args[] = { name, object }; | 2983     Handle<Object> args[] = { Handle<Object>(name, isolate), | 
| 3012     Handle<Object> error = isolate->factory()->NewTypeError( | 2984                               Handle<Object>(this, isolate)}; | 
| 3013         "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | 2985     return isolate->Throw(*isolate->factory()->NewTypeError( | 
| 3014     isolate->Throw(*error); | 2986       "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); | 
| 3015     return Handle<Object>(); |  | 
| 3016   } | 2987   } | 
| 3017   return isolate->factory()->the_hole_value(); | 2988   return heap->the_hole_value(); | 
| 3018 } | 2989 } | 
| 3019 | 2990 | 
| 3020 | 2991 | 
| 3021 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) { | 2992 void Map::EnsureDescriptorSlack(Handle<Map> map, int slack) { | 
| 3022   Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 2993   Handle<DescriptorArray> descriptors(map->instance_descriptors()); | 
| 3023   if (slack <= descriptors->NumberOfSlackDescriptors()) return; | 2994   if (slack <= descriptors->NumberOfSlackDescriptors()) return; | 
| 3024   int number_of_descriptors = descriptors->number_of_descriptors(); | 2995   int number_of_descriptors = descriptors->number_of_descriptors(); | 
| 3025   Isolate* isolate = map->GetIsolate(); | 2996   Isolate* isolate = map->GetIsolate(); | 
| 3026   Handle<DescriptorArray> new_descriptors = | 2997   Handle<DescriptorArray> new_descriptors = | 
| 3027       isolate->factory()->NewDescriptorArray(number_of_descriptors, slack); | 2998       isolate->factory()->NewDescriptorArray(number_of_descriptors, slack); | 
| (...skipping 767 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3795   Map* transition_map = lookup->GetTransitionTarget(); | 3766   Map* transition_map = lookup->GetTransitionTarget(); | 
| 3796   int descriptor = transition_map->LastAdded(); | 3767   int descriptor = transition_map->LastAdded(); | 
| 3797 | 3768 | 
| 3798   DescriptorArray* descriptors = transition_map->instance_descriptors(); | 3769   DescriptorArray* descriptors = transition_map->instance_descriptors(); | 
| 3799   PropertyDetails details = descriptors->GetDetails(descriptor); | 3770   PropertyDetails details = descriptors->GetDetails(descriptor); | 
| 3800 | 3771 | 
| 3801   if (details.type() == CALLBACKS || attributes != details.attributes()) { | 3772   if (details.type() == CALLBACKS || attributes != details.attributes()) { | 
| 3802     // AddProperty will either normalize the object, or create a new fast copy | 3773     // AddProperty will either normalize the object, or create a new fast copy | 
| 3803     // of the map. If we get a fast copy of the map, all field representations | 3774     // of the map. If we get a fast copy of the map, all field representations | 
| 3804     // will be tagged since the transition is omitted. | 3775     // will be tagged since the transition is omitted. | 
| 3805     Handle<JSObject> holder(lookup->holder()); | 3776     return lookup->holder()->AddProperty( | 
| 3806     Handle<Object> result = JSObject::AddProperty( | 3777         *name, *value, attributes, kNonStrictMode, | 
| 3807         holder, name, value, attributes, kNonStrictMode, |  | 
| 3808         JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, | 3778         JSReceiver::CERTAINLY_NOT_STORE_FROM_KEYED, | 
| 3809         JSReceiver::OMIT_EXTENSIBILITY_CHECK, | 3779         JSReceiver::OMIT_EXTENSIBILITY_CHECK, | 
| 3810         JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); | 3780         JSObject::FORCE_TAGGED, FORCE_FIELD, OMIT_TRANSITION); | 
| 3811     RETURN_IF_EMPTY_HANDLE(holder->GetIsolate(), result); |  | 
| 3812     return *result; |  | 
| 3813   } | 3781   } | 
| 3814 | 3782 | 
| 3815   // Keep the target CONSTANT if the same value is stored. | 3783   // Keep the target CONSTANT if the same value is stored. | 
| 3816   // TODO(verwaest): Also support keeping the placeholder | 3784   // TODO(verwaest): Also support keeping the placeholder | 
| 3817   // (value->IsUninitialized) as constant. | 3785   // (value->IsUninitialized) as constant. | 
| 3818   if (details.type() == CONSTANT && | 3786   if (details.type() == CONSTANT && | 
| 3819       descriptors->GetValue(descriptor) == *value) { | 3787       descriptors->GetValue(descriptor) == *value) { | 
| 3820     lookup->holder()->set_map(transition_map); | 3788     lookup->holder()->set_map(transition_map); | 
| 3821     return *value; | 3789     return *value; | 
| 3822   } | 3790   } | 
| (...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3972 | 3940 | 
| 3973   // From this point on everything needs to be handlified, because | 3941   // From this point on everything needs to be handlified, because | 
| 3974   // SetPropertyViaPrototypes might call back into JavaScript. | 3942   // SetPropertyViaPrototypes might call back into JavaScript. | 
| 3975   HandleScope scope(isolate); | 3943   HandleScope scope(isolate); | 
| 3976   Handle<JSObject> self(this); | 3944   Handle<JSObject> self(this); | 
| 3977   Handle<Name> name(name_raw); | 3945   Handle<Name> name(name_raw); | 
| 3978   Handle<Object> value(value_raw, isolate); | 3946   Handle<Object> value(value_raw, isolate); | 
| 3979 | 3947 | 
| 3980   if (!lookup->IsProperty() && !self->IsJSContextExtensionObject()) { | 3948   if (!lookup->IsProperty() && !self->IsJSContextExtensionObject()) { | 
| 3981     bool done = false; | 3949     bool done = false; | 
| 3982     Handle<Object> result_object = SetPropertyViaPrototypes( | 3950     MaybeObject* result_object = self->SetPropertyViaPrototypes( | 
| 3983         self, name, value, attributes, strict_mode, &done); | 3951         *name, *value, attributes, strict_mode, &done); | 
| 3984     RETURN_IF_EMPTY_HANDLE(isolate, result_object); | 3952     if (done) return result_object; | 
| 3985     if (done) return *result_object; |  | 
| 3986   } | 3953   } | 
| 3987 | 3954 | 
| 3988   if (!lookup->IsFound()) { | 3955   if (!lookup->IsFound()) { | 
| 3989     // Neither properties nor transitions found. | 3956     // Neither properties nor transitions found. | 
| 3990     Handle<Object> result_object = AddProperty( | 3957     return self->AddProperty( | 
| 3991         self, name, value, attributes, strict_mode, store_mode); | 3958         *name, *value, attributes, strict_mode, store_mode); | 
| 3992     RETURN_IF_EMPTY_HANDLE(isolate, result_object); |  | 
| 3993     return *result_object; |  | 
| 3994   } | 3959   } | 
| 3995 | 3960 | 
| 3996   if (lookup->IsProperty() && lookup->IsReadOnly()) { | 3961   if (lookup->IsProperty() && lookup->IsReadOnly()) { | 
| 3997     if (strict_mode == kStrictMode) { | 3962     if (strict_mode == kStrictMode) { | 
| 3998       Handle<Object> args[] = { name, self }; | 3963       Handle<Object> args[] = { name, self }; | 
| 3999       return isolate->Throw(*isolate->factory()->NewTypeError( | 3964       return isolate->Throw(*isolate->factory()->NewTypeError( | 
| 4000           "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); | 3965           "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args)))); | 
| 4001     } else { | 3966     } else { | 
| 4002       return *value; | 3967       return *value; | 
| 4003     } | 3968     } | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 4022     case CONSTANT: | 3987     case CONSTANT: | 
| 4023       // Only replace the constant if necessary. | 3988       // Only replace the constant if necessary. | 
| 4024       if (*value == lookup->GetConstant()) return *value; | 3989       if (*value == lookup->GetConstant()) return *value; | 
| 4025       result = SetPropertyToField(lookup, name, value); | 3990       result = SetPropertyToField(lookup, name, value); | 
| 4026       break; | 3991       break; | 
| 4027     case CALLBACKS: { | 3992     case CALLBACKS: { | 
| 4028       Object* callback_object = lookup->GetCallbackObject(); | 3993       Object* callback_object = lookup->GetCallbackObject(); | 
| 4029       return self->SetPropertyWithCallback( | 3994       return self->SetPropertyWithCallback( | 
| 4030           callback_object, *name, *value, lookup->holder(), strict_mode); | 3995           callback_object, *name, *value, lookup->holder(), strict_mode); | 
| 4031     } | 3996     } | 
| 4032     case INTERCEPTOR: { | 3997     case INTERCEPTOR: | 
| 4033       Handle<JSObject> holder(lookup->holder()); | 3998       result = lookup->holder()->SetPropertyWithInterceptor( | 
| 4034       Handle<Object> hresult = SetPropertyWithInterceptor( | 3999           *name, *value, attributes, strict_mode); | 
| 4035           holder, name, value, attributes, strict_mode); |  | 
| 4036       RETURN_IF_EMPTY_HANDLE(isolate, hresult); |  | 
| 4037       result = *hresult; |  | 
| 4038       break; | 4000       break; | 
| 4039     } |  | 
| 4040     case TRANSITION: { | 4001     case TRANSITION: { | 
| 4041       result = SetPropertyUsingTransition(lookup, name, value, attributes); | 4002       result = SetPropertyUsingTransition(lookup, name, value, attributes); | 
| 4042       break; | 4003       break; | 
| 4043     } | 4004     } | 
| 4044     case HANDLER: | 4005     case HANDLER: | 
| 4045     case NONEXISTENT: | 4006     case NONEXISTENT: | 
| 4046       UNREACHABLE(); | 4007       UNREACHABLE(); | 
| 4047   } | 4008   } | 
| 4048 | 4009 | 
| 4049   Handle<Object> hresult; | 4010   Handle<Object> hresult; | 
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4152         value_type, | 4113         value_type, | 
| 4153         mode, | 4114         mode, | 
| 4154         extensibility_check); | 4115         extensibility_check); | 
| 4155   } | 4116   } | 
| 4156 | 4117 | 
| 4157   if (lookup.IsFound() && | 4118   if (lookup.IsFound() && | 
| 4158       (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) { | 4119       (lookup.type() == INTERCEPTOR || lookup.type() == CALLBACKS)) { | 
| 4159     LocalLookupRealNamedProperty(name_raw, &lookup); | 4120     LocalLookupRealNamedProperty(name_raw, &lookup); | 
| 4160   } | 4121   } | 
| 4161 | 4122 | 
|  | 4123   // Check for accessor in prototype chain removed here in clone. | 
|  | 4124   if (!lookup.IsFound()) { | 
|  | 4125     // Neither properties nor transitions found. | 
|  | 4126     return AddProperty( | 
|  | 4127         name_raw, value_raw, attributes, kNonStrictMode, | 
|  | 4128         MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode); | 
|  | 4129   } | 
|  | 4130 | 
| 4162   // From this point on everything needs to be handlified. | 4131   // From this point on everything needs to be handlified. | 
| 4163   HandleScope scope(isolate); | 4132   HandleScope scope(isolate); | 
| 4164   Handle<JSObject> self(this); | 4133   Handle<JSObject> self(this); | 
| 4165   Handle<Name> name(name_raw); | 4134   Handle<Name> name(name_raw); | 
| 4166   Handle<Object> value(value_raw, isolate); | 4135   Handle<Object> value(value_raw, isolate); | 
| 4167 | 4136 | 
| 4168   // Check for accessor in prototype chain removed here in clone. | 4137   Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate); | 
| 4169   if (!lookup.IsFound()) { |  | 
| 4170     // Neither properties nor transitions found. |  | 
| 4171     Handle<Object> result = AddProperty( |  | 
| 4172         self, name, value, attributes, kNonStrictMode, |  | 
| 4173         MAY_BE_STORE_FROM_KEYED, extensibility_check, value_type, mode); |  | 
| 4174     RETURN_IF_EMPTY_HANDLE(isolate, result); |  | 
| 4175     return *result; |  | 
| 4176   } |  | 
| 4177 |  | 
| 4178   Handle<Object> old_value = isolate->factory()->the_hole_value(); |  | 
| 4179   PropertyAttributes old_attributes = ABSENT; | 4138   PropertyAttributes old_attributes = ABSENT; | 
| 4180   bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); | 4139   bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); | 
| 4181   if (is_observed && lookup.IsProperty()) { | 4140   if (is_observed && lookup.IsProperty()) { | 
| 4182     if (lookup.IsDataProperty()) old_value = | 4141     if (lookup.IsDataProperty()) old_value = | 
| 4183         Object::GetProperty(self, name); | 4142         Object::GetProperty(self, name); | 
| 4184     old_attributes = lookup.GetAttributes(); | 4143     old_attributes = lookup.GetAttributes(); | 
| 4185   } | 4144   } | 
| 4186 | 4145 | 
| 4187   // Check of IsReadOnly removed from here in clone. | 4146   // Check of IsReadOnly removed from here in clone. | 
| 4188   MaybeObject* result = *value; | 4147   MaybeObject* result = *value; | 
| (...skipping 11932 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 16121 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16080 #define ERROR_MESSAGES_TEXTS(C, T) T, | 
| 16122   static const char* error_messages_[] = { | 16081   static const char* error_messages_[] = { | 
| 16123       ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16082       ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 
| 16124   }; | 16083   }; | 
| 16125 #undef ERROR_MESSAGES_TEXTS | 16084 #undef ERROR_MESSAGES_TEXTS | 
| 16126   return error_messages_[reason]; | 16085   return error_messages_[reason]; | 
| 16127 } | 16086 } | 
| 16128 | 16087 | 
| 16129 | 16088 | 
| 16130 } }  // namespace v8::internal | 16089 } }  // namespace v8::internal | 
| OLD | NEW | 
|---|