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 5820 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5831 PropertyDetails(attributes, CALLBACKS, index)); | 5831 PropertyDetails(attributes, CALLBACKS, index)); |
5832 } | 5832 } |
5833 AccessorPair::cast(result)->SetComponents(getter, setter); | 5833 AccessorPair::cast(result)->SetComponents(getter, setter); |
5834 return true; | 5834 return true; |
5835 } | 5835 } |
5836 } | 5836 } |
5837 return false; | 5837 return false; |
5838 } | 5838 } |
5839 | 5839 |
5840 | 5840 |
5841 MaybeObject* JSObject::DefineElementAccessor(uint32_t index, | 5841 void JSObject::DefineElementAccessor(Handle<JSObject> object, |
5842 Object* getter, | 5842 uint32_t index, |
5843 Object* setter, | 5843 Handle<Object> getter, |
5844 PropertyAttributes attributes) { | 5844 Handle<Object> setter, |
5845 switch (GetElementsKind()) { | 5845 PropertyAttributes attributes) { |
5846 switch (object->GetElementsKind()) { | |
5846 case FAST_SMI_ELEMENTS: | 5847 case FAST_SMI_ELEMENTS: |
5847 case FAST_ELEMENTS: | 5848 case FAST_ELEMENTS: |
5848 case FAST_DOUBLE_ELEMENTS: | 5849 case FAST_DOUBLE_ELEMENTS: |
5849 case FAST_HOLEY_SMI_ELEMENTS: | 5850 case FAST_HOLEY_SMI_ELEMENTS: |
5850 case FAST_HOLEY_ELEMENTS: | 5851 case FAST_HOLEY_ELEMENTS: |
5851 case FAST_HOLEY_DOUBLE_ELEMENTS: | 5852 case FAST_HOLEY_DOUBLE_ELEMENTS: |
5852 break; | 5853 break; |
5853 case EXTERNAL_PIXEL_ELEMENTS: | 5854 case EXTERNAL_PIXEL_ELEMENTS: |
5854 case EXTERNAL_BYTE_ELEMENTS: | 5855 case EXTERNAL_BYTE_ELEMENTS: |
5855 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 5856 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
5856 case EXTERNAL_SHORT_ELEMENTS: | 5857 case EXTERNAL_SHORT_ELEMENTS: |
5857 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 5858 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
5858 case EXTERNAL_INT_ELEMENTS: | 5859 case EXTERNAL_INT_ELEMENTS: |
5859 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 5860 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
5860 case EXTERNAL_FLOAT_ELEMENTS: | 5861 case EXTERNAL_FLOAT_ELEMENTS: |
5861 case EXTERNAL_DOUBLE_ELEMENTS: | 5862 case EXTERNAL_DOUBLE_ELEMENTS: |
5862 // Ignore getters and setters on pixel and external array elements. | 5863 // Ignore getters and setters on pixel and external array elements. |
5863 return GetHeap()->undefined_value(); | 5864 return; |
5864 case DICTIONARY_ELEMENTS: | 5865 case DICTIONARY_ELEMENTS: |
5865 if (UpdateGetterSetterInDictionary(element_dictionary(), | 5866 if (UpdateGetterSetterInDictionary(object->element_dictionary(), |
5866 index, | 5867 index, |
5867 getter, | 5868 *getter, |
5868 setter, | 5869 *setter, |
5869 attributes)) { | 5870 attributes)) { |
5870 return GetHeap()->undefined_value(); | 5871 return; |
5871 } | 5872 } |
5872 break; | 5873 break; |
5873 case NON_STRICT_ARGUMENTS_ELEMENTS: { | 5874 case NON_STRICT_ARGUMENTS_ELEMENTS: { |
5874 // Ascertain whether we have read-only properties or an existing | 5875 // Ascertain whether we have read-only properties or an existing |
5875 // getter/setter pair in an arguments elements dictionary backing | 5876 // getter/setter pair in an arguments elements dictionary backing |
5876 // store. | 5877 // store. |
5877 FixedArray* parameter_map = FixedArray::cast(elements()); | 5878 FixedArray* parameter_map = FixedArray::cast(object->elements()); |
5878 uint32_t length = parameter_map->length(); | 5879 uint32_t length = parameter_map->length(); |
5879 Object* probe = | 5880 Object* probe = |
5880 index < (length - 2) ? parameter_map->get(index + 2) : NULL; | 5881 index < (length - 2) ? parameter_map->get(index + 2) : NULL; |
5881 if (probe == NULL || probe->IsTheHole()) { | 5882 if (probe == NULL || probe->IsTheHole()) { |
5882 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 5883 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
5883 if (arguments->IsDictionary()) { | 5884 if (arguments->IsDictionary()) { |
5884 SeededNumberDictionary* dictionary = | 5885 SeededNumberDictionary* dictionary = |
5885 SeededNumberDictionary::cast(arguments); | 5886 SeededNumberDictionary::cast(arguments); |
5886 if (UpdateGetterSetterInDictionary(dictionary, | 5887 if (UpdateGetterSetterInDictionary(dictionary, |
5887 index, | 5888 index, |
5888 getter, | 5889 *getter, |
5889 setter, | 5890 *setter, |
5890 attributes)) { | 5891 attributes)) { |
5891 return GetHeap()->undefined_value(); | 5892 return; |
5892 } | 5893 } |
5893 } | 5894 } |
5894 } | 5895 } |
5895 break; | 5896 break; |
5896 } | 5897 } |
5897 } | 5898 } |
5898 | 5899 |
5899 AccessorPair* accessors; | 5900 Isolate* isolate = object->GetIsolate(); |
5900 { MaybeObject* maybe_accessors = GetHeap()->AllocateAccessorPair(); | 5901 Handle<AccessorPair> accessors = isolate->factory()->NewAccessorPair(); |
5901 if (!maybe_accessors->To(&accessors)) return maybe_accessors; | 5902 accessors->SetComponents(*getter, *setter); |
5902 } | |
5903 accessors->SetComponents(getter, setter); | |
5904 | 5903 |
5905 return SetElementCallback(index, accessors, attributes); | 5904 CALL_HEAP_FUNCTION_VOID( |
5905 isolate, object->SetElementCallback(index, *accessors, attributes)); | |
5906 } | 5906 } |
5907 | 5907 |
5908 | 5908 |
5909 MaybeObject* JSObject::CreateAccessorPairFor(Name* name) { | 5909 Handle<AccessorPair> JSObject::CreateAccessorPairFor(Handle<JSObject> object, |
5910 LookupResult result(GetHeap()->isolate()); | 5910 Handle<Name> name) { |
5911 LocalLookupRealNamedProperty(name, &result); | 5911 Isolate* isolate = object->GetIsolate(); |
5912 LookupResult result(isolate); | |
5913 object->LocalLookupRealNamedProperty(*name, &result); | |
5912 if (result.IsPropertyCallbacks()) { | 5914 if (result.IsPropertyCallbacks()) { |
5913 // Note that the result can actually have IsDontDelete() == true when we | 5915 // Note that the result can actually have IsDontDelete() == true when we |
5914 // e.g. have to fall back to the slow case while adding a setter after | 5916 // e.g. have to fall back to the slow case while adding a setter after |
5915 // successfully reusing a map transition for a getter. Nevertheless, this is | 5917 // successfully reusing a map transition for a getter. Nevertheless, this is |
5916 // OK, because the assertion only holds for the whole addition of both | 5918 // OK, because the assertion only holds for the whole addition of both |
5917 // accessors, not for the addition of each part. See first comment in | 5919 // accessors, not for the addition of each part. See first comment in |
5918 // DefinePropertyAccessor below. | 5920 // DefinePropertyAccessor below. |
5919 Object* obj = result.GetCallbackObject(); | 5921 Object* obj = result.GetCallbackObject(); |
5920 if (obj->IsAccessorPair()) { | 5922 if (obj->IsAccessorPair()) { |
5921 return AccessorPair::cast(obj)->Copy(); | 5923 return AccessorPair::Copy(Handle<AccessorPair>(AccessorPair::cast(obj))); |
rossberg
2013/07/02 12:20:47
Use handle() and pass isolate.
Michael Starzinger
2013/07/02 15:50:23
Done.
| |
5922 } | 5924 } |
5923 } | 5925 } |
5924 return GetHeap()->AllocateAccessorPair(); | 5926 return isolate->factory()->NewAccessorPair(); |
5925 } | 5927 } |
5926 | 5928 |
5927 | 5929 |
5928 MaybeObject* JSObject::DefinePropertyAccessor(Name* name, | 5930 void JSObject::DefinePropertyAccessor(Handle<JSObject> object, |
5929 Object* getter, | 5931 Handle<Name> name, |
5930 Object* setter, | 5932 Handle<Object> getter, |
5931 PropertyAttributes attributes) { | 5933 Handle<Object> setter, |
5934 PropertyAttributes attributes) { | |
5932 // We could assert that the property is configurable here, but we would need | 5935 // We could assert that the property is configurable here, but we would need |
5933 // to do a lookup, which seems to be a bit of overkill. | 5936 // to do a lookup, which seems to be a bit of overkill. |
5934 Heap* heap = GetHeap(); | 5937 Factory* factory = object->GetIsolate()->factory(); |
5935 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); | 5938 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); |
5936 if (HasFastProperties() && !only_attribute_changes && | 5939 if (object->HasFastProperties() && !only_attribute_changes && |
5937 (map()->NumberOfOwnDescriptors() < | 5940 (object->map()->NumberOfOwnDescriptors() < |
5938 DescriptorArray::kMaxNumberOfDescriptors)) { | 5941 DescriptorArray::kMaxNumberOfDescriptors)) { |
5939 MaybeObject* getterOk = heap->undefined_value(); | 5942 Handle<Object> getterOk = getter->IsNull() |
5940 if (!getter->IsNull()) { | 5943 ? Handle<Object>(factory->undefined_value()) |
rossberg
2013/07/02 12:20:47
Pass isolate. Though actually, isn't the construct
Michael Starzinger
2013/07/02 15:50:23
Done. As discussed offline: Returning an object he
| |
5941 getterOk = DefineFastAccessor(name, ACCESSOR_GETTER, getter, attributes); | 5944 : DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes); |
5942 if (getterOk->IsFailure()) return getterOk; | |
5943 } | |
5944 | 5945 |
5945 MaybeObject* setterOk = heap->undefined_value(); | 5946 Handle<Object> setterOk = getterOk->IsNull() || setter->IsNull() |
5946 if (getterOk != heap->null_value() && !setter->IsNull()) { | 5947 ? Handle<Object>(factory->undefined_value()) |
rossberg
2013/07/02 12:20:47
Same here
Michael Starzinger
2013/07/02 15:50:23
Likewise.
| |
5947 setterOk = DefineFastAccessor(name, ACCESSOR_SETTER, setter, attributes); | 5948 : DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes); |
5948 if (setterOk->IsFailure()) return setterOk; | |
5949 } | |
5950 | 5949 |
5951 if (getterOk != heap->null_value() && setterOk != heap->null_value()) { | 5950 if (!getterOk->IsNull() && !setterOk->IsNull()) { |
5952 return heap->undefined_value(); | 5951 return; |
5953 } | 5952 } |
5954 } | 5953 } |
5955 | 5954 |
5956 AccessorPair* accessors; | 5955 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name); |
5957 MaybeObject* maybe_accessors = CreateAccessorPairFor(name); | 5956 accessors->SetComponents(*getter, *setter); |
5958 if (!maybe_accessors->To(&accessors)) return maybe_accessors; | |
5959 | 5957 |
5960 accessors->SetComponents(getter, setter); | 5958 CALL_HEAP_FUNCTION_VOID( |
5961 return SetPropertyCallback(name, accessors, attributes); | 5959 object->GetIsolate(), |
5960 object->SetPropertyCallback(*name, *accessors, attributes)); | |
5962 } | 5961 } |
5963 | 5962 |
5964 | 5963 |
5965 bool JSObject::CanSetCallback(Name* name) { | 5964 bool JSObject::CanSetCallback(Name* name) { |
5966 ASSERT(!IsAccessCheckNeeded() || | 5965 ASSERT(!IsAccessCheckNeeded() || |
5967 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); | 5966 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); |
5968 | 5967 |
5969 // Check if there is an API defined callback object which prohibits | 5968 // Check if there is an API defined callback object which prohibits |
5970 // callback overwriting in this object or its prototype chain. | 5969 // callback overwriting in this object or its prototype chain. |
5971 // This mechanism is needed for instance in a browser setting, where | 5970 // This mechanism is needed for instance in a browser setting, where |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6053 | 6052 |
6054 return GetHeap()->undefined_value(); | 6053 return GetHeap()->undefined_value(); |
6055 } | 6054 } |
6056 | 6055 |
6057 | 6056 |
6058 void JSObject::DefineAccessor(Handle<JSObject> object, | 6057 void JSObject::DefineAccessor(Handle<JSObject> object, |
6059 Handle<Name> name, | 6058 Handle<Name> name, |
6060 Handle<Object> getter, | 6059 Handle<Object> getter, |
6061 Handle<Object> setter, | 6060 Handle<Object> setter, |
6062 PropertyAttributes attributes) { | 6061 PropertyAttributes attributes) { |
6063 CALL_HEAP_FUNCTION_VOID( | 6062 Isolate* isolate = object->GetIsolate(); |
6064 object->GetIsolate(), | |
6065 object->DefineAccessor(*name, *getter, *setter, attributes)); | |
6066 } | |
6067 | |
6068 MaybeObject* JSObject::DefineAccessor(Name* name_raw, | |
6069 Object* getter_raw, | |
6070 Object* setter_raw, | |
6071 PropertyAttributes attributes) { | |
6072 Isolate* isolate = GetIsolate(); | |
6073 // Check access rights if needed. | 6063 // Check access rights if needed. |
6074 if (IsAccessCheckNeeded() && | 6064 if (object->IsAccessCheckNeeded() && |
6075 !isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { | 6065 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) { |
6076 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 6066 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET); |
6077 return isolate->heap()->undefined_value(); | 6067 return; |
6078 } | 6068 } |
6079 | 6069 |
6080 if (IsJSGlobalProxy()) { | 6070 if (object->IsJSGlobalProxy()) { |
6081 Object* proto = GetPrototype(); | 6071 Handle<Object> proto(object->GetPrototype(), isolate); |
6082 if (proto->IsNull()) return this; | 6072 if (proto->IsNull()) return; |
6083 ASSERT(proto->IsJSGlobalObject()); | 6073 ASSERT(proto->IsJSGlobalObject()); |
6084 return JSObject::cast(proto)->DefineAccessor( | 6074 DefineAccessor( |
6085 name_raw, getter_raw, setter_raw, attributes); | 6075 Handle<JSObject>::cast(proto), name, getter, setter, attributes); |
6076 return; | |
6086 } | 6077 } |
6087 | 6078 |
6088 // Make sure that the top context does not change when doing callbacks or | 6079 // Make sure that the top context does not change when doing callbacks or |
6089 // interceptor calls. | 6080 // interceptor calls. |
6090 AssertNoContextChange ncc; | 6081 AssertNoContextChange ncc; |
6091 | 6082 |
6092 // Try to flatten before operating on the string. | 6083 // Try to flatten before operating on the string. |
6093 if (name_raw->IsString()) String::cast(name_raw)->TryFlatten(); | 6084 if (name->IsString()) String::cast(*name)->TryFlatten(); |
6094 | 6085 |
6095 if (!CanSetCallback(name_raw)) return isolate->heap()->undefined_value(); | 6086 if (!object->CanSetCallback(*name)) return; |
6096 | |
6097 // From this point on everything needs to be handlified. | |
rossberg
2013/07/02 12:20:47
Glad this goes away...
| |
6098 HandleScope scope(isolate); | |
6099 Handle<JSObject> self(this); | |
6100 Handle<Name> name(name_raw); | |
6101 Handle<Object> getter(getter_raw, isolate); | |
6102 Handle<Object> setter(setter_raw, isolate); | |
6103 | 6087 |
6104 uint32_t index = 0; | 6088 uint32_t index = 0; |
6105 bool is_element = name->AsArrayIndex(&index); | 6089 bool is_element = name->AsArrayIndex(&index); |
6106 | 6090 |
6107 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 6091 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
6108 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); | 6092 bool is_observed = FLAG_harmony_observation && object->map()->is_observed(); |
6109 bool preexists = false; | 6093 bool preexists = false; |
6110 if (is_observed) { | 6094 if (is_observed) { |
6111 if (is_element) { | 6095 if (is_element) { |
6112 preexists = HasLocalElement(index); | 6096 preexists = object->HasLocalElement(index); |
6113 if (preexists && self->GetLocalElementAccessorPair(index) == NULL) { | 6097 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) { |
6114 old_value = Object::GetElement(self, index); | 6098 old_value = Object::GetElement(object, index); |
6115 } | 6099 } |
6116 } else { | 6100 } else { |
6117 LookupResult lookup(isolate); | 6101 LookupResult lookup(isolate); |
6118 LocalLookup(*name, &lookup, true); | 6102 object->LocalLookup(*name, &lookup, true); |
6119 preexists = lookup.IsProperty(); | 6103 preexists = lookup.IsProperty(); |
6120 if (preexists && lookup.IsDataProperty()) { | 6104 if (preexists && lookup.IsDataProperty()) { |
6121 old_value = Object::GetProperty(self, name); | 6105 old_value = Object::GetProperty(object, name); |
6122 } | 6106 } |
6123 } | 6107 } |
6124 } | 6108 } |
6125 | 6109 |
6126 MaybeObject* result = is_element ? | 6110 if (is_element) { |
6127 self->DefineElementAccessor(index, *getter, *setter, attributes) : | 6111 DefineElementAccessor(object, index, getter, setter, attributes); |
6128 self->DefinePropertyAccessor(*name, *getter, *setter, attributes); | 6112 } else { |
6129 | 6113 DefinePropertyAccessor(object, name, getter, setter, attributes); |
6130 Handle<Object> hresult; | 6114 } |
6131 if (!result->ToHandle(&hresult, isolate)) return result; | |
6132 | 6115 |
6133 if (is_observed) { | 6116 if (is_observed) { |
6134 const char* type = preexists ? "reconfigured" : "new"; | 6117 const char* type = preexists ? "reconfigured" : "new"; |
6135 EnqueueChangeRecord(self, type, name, old_value); | 6118 EnqueueChangeRecord(object, type, name, old_value); |
6136 } | 6119 } |
6137 | |
6138 return *hresult; | |
6139 } | 6120 } |
6140 | 6121 |
6141 | 6122 |
6142 static MaybeObject* TryAccessorTransition(JSObject* self, | 6123 static MaybeObject* TryAccessorTransition(JSObject* self, |
6143 Map* transitioned_map, | 6124 Map* transitioned_map, |
6144 int target_descriptor, | 6125 int target_descriptor, |
6145 AccessorComponent component, | 6126 AccessorComponent component, |
6146 Object* accessor, | 6127 Object* accessor, |
6147 PropertyAttributes attributes) { | 6128 PropertyAttributes attributes) { |
6148 DescriptorArray* descs = transitioned_map->instance_descriptors(); | 6129 DescriptorArray* descs = transitioned_map->instance_descriptors(); |
(...skipping 12 matching lines...) Expand all Loading... | |
6161 self->set_map(transitioned_map); | 6142 self->set_map(transitioned_map); |
6162 return self; | 6143 return self; |
6163 } | 6144 } |
6164 | 6145 |
6165 // If either not the same accessor, or not the same attributes, fall back to | 6146 // If either not the same accessor, or not the same attributes, fall back to |
6166 // the slow case. | 6147 // the slow case. |
6167 return self->GetHeap()->null_value(); | 6148 return self->GetHeap()->null_value(); |
6168 } | 6149 } |
6169 | 6150 |
6170 | 6151 |
6171 MaybeObject* JSObject::DefineFastAccessor(Name* name, | 6152 static MaybeObject* CopyInsertDescriptor(Map* map, |
6172 AccessorComponent component, | 6153 Name* name, |
6173 Object* accessor, | 6154 AccessorPair* accessors, |
6174 PropertyAttributes attributes) { | 6155 PropertyAttributes attributes) { |
6156 CallbacksDescriptor new_accessors_desc(name, accessors, attributes); | |
6157 return map->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION); | |
6158 } | |
6159 | |
6160 | |
6161 static Handle<Map> CopyInsertDescriptor(Handle<Map> map, | |
6162 Handle<Name> name, | |
6163 Handle<AccessorPair> accessors, | |
6164 PropertyAttributes attributes) { | |
6165 CALL_HEAP_FUNCTION(map->GetIsolate(), | |
6166 CopyInsertDescriptor(*map, *name, *accessors, attributes), | |
6167 Map); | |
6168 } | |
6169 | |
6170 | |
6171 Handle<Object> JSObject::DefineFastAccessor(Handle<JSObject> object, | |
6172 Handle<Name> name, | |
6173 AccessorComponent component, | |
6174 Handle<Object> accessor, | |
6175 PropertyAttributes attributes) { | |
6175 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); | 6176 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); |
6176 LookupResult result(GetIsolate()); | 6177 Isolate* isolate = object->GetIsolate(); |
6177 LocalLookup(name, &result); | 6178 LookupResult result(isolate); |
6179 object->LocalLookup(*name, &result); | |
6178 | 6180 |
6179 if (result.IsFound() && !result.IsPropertyCallbacks()) { | 6181 if (result.IsFound() && !result.IsPropertyCallbacks()) { |
6180 return GetHeap()->null_value(); | 6182 return isolate->factory()->null_value(); |
6181 } | 6183 } |
6182 | 6184 |
6183 // Return success if the same accessor with the same attributes already exist. | 6185 // Return success if the same accessor with the same attributes already exist. |
6184 AccessorPair* source_accessors = NULL; | 6186 AccessorPair* source_accessors = NULL; |
6185 if (result.IsPropertyCallbacks()) { | 6187 if (result.IsPropertyCallbacks()) { |
6186 Object* callback_value = result.GetCallbackObject(); | 6188 Object* callback_value = result.GetCallbackObject(); |
6187 if (callback_value->IsAccessorPair()) { | 6189 if (callback_value->IsAccessorPair()) { |
6188 source_accessors = AccessorPair::cast(callback_value); | 6190 source_accessors = AccessorPair::cast(callback_value); |
6189 Object* entry = source_accessors->get(component); | 6191 Object* entry = source_accessors->get(component); |
6190 if (entry == accessor && result.GetAttributes() == attributes) { | 6192 if (entry == *accessor && result.GetAttributes() == attributes) { |
6191 return this; | 6193 return object; |
6192 } | 6194 } |
6193 } else { | 6195 } else { |
6194 return GetHeap()->null_value(); | 6196 return isolate->factory()->null_value(); |
6195 } | 6197 } |
6196 | 6198 |
6197 int descriptor_number = result.GetDescriptorIndex(); | 6199 int descriptor_number = result.GetDescriptorIndex(); |
6198 | 6200 |
6199 map()->LookupTransition(this, name, &result); | 6201 object->map()->LookupTransition(*object, *name, &result); |
6200 | 6202 |
6201 if (result.IsFound()) { | 6203 if (result.IsFound()) { |
6202 Map* target = result.GetTransitionTarget(); | 6204 Map* target = result.GetTransitionTarget(); |
6203 ASSERT(target->NumberOfOwnDescriptors() == | 6205 ASSERT(target->NumberOfOwnDescriptors() == |
6204 map()->NumberOfOwnDescriptors()); | 6206 object->map()->NumberOfOwnDescriptors()); |
6205 // This works since descriptors are sorted in order of addition. | 6207 // This works since descriptors are sorted in order of addition. |
6206 ASSERT(map()->instance_descriptors()->GetKey(descriptor_number) == name); | 6208 ASSERT(object->map()->instance_descriptors()-> |
6207 return TryAccessorTransition( | 6209 GetKey(descriptor_number) == *name); |
6208 this, target, descriptor_number, component, accessor, attributes); | 6210 CALL_HEAP_FUNCTION( |
6211 isolate, | |
6212 TryAccessorTransition(*object, target, descriptor_number, | |
6213 component, *accessor, attributes), | |
6214 Object); | |
6209 } | 6215 } |
6210 } else { | 6216 } else { |
6211 // If not, lookup a transition. | 6217 // If not, lookup a transition. |
6212 map()->LookupTransition(this, name, &result); | 6218 object->map()->LookupTransition(*object, *name, &result); |
6213 | 6219 |
6214 // If there is a transition, try to follow it. | 6220 // If there is a transition, try to follow it. |
6215 if (result.IsFound()) { | 6221 if (result.IsFound()) { |
6216 Map* target = result.GetTransitionTarget(); | 6222 Map* target = result.GetTransitionTarget(); |
6217 int descriptor_number = target->LastAdded(); | 6223 int descriptor_number = target->LastAdded(); |
6218 ASSERT(target->instance_descriptors()->GetKey(descriptor_number) | 6224 ASSERT(target->instance_descriptors()->GetKey(descriptor_number) |
6219 ->Equals(name)); | 6225 ->Equals(*name)); |
6220 return TryAccessorTransition( | 6226 CALL_HEAP_FUNCTION( |
6221 this, target, descriptor_number, component, accessor, attributes); | 6227 isolate, |
6228 TryAccessorTransition(*object, target, descriptor_number, | |
6229 component, *accessor, attributes), | |
6230 Object); | |
6222 } | 6231 } |
6223 } | 6232 } |
6224 | 6233 |
6225 // If there is no transition yet, add a transition to the a new accessor pair | 6234 // If there is no transition yet, add a transition to the a new accessor pair |
6226 // containing the accessor. | 6235 // containing the accessor. Allocate a new pair if there were no source |
6227 AccessorPair* accessors; | 6236 // accessors. Otherwise, copy the pair and modify the accessor. |
6228 MaybeObject* maybe_accessors; | 6237 Handle<AccessorPair> accessors = source_accessors != NULL |
6229 | 6238 ? AccessorPair::Copy(Handle<AccessorPair>(source_accessors)) |
rossberg
2013/07/02 12:20:47
Pass isolate
Michael Starzinger
2013/07/02 15:50:23
As discussed offline: Not needed here.
| |
6230 // Allocate a new pair if there were no source accessors. Otherwise, copy the | 6239 : isolate->factory()->NewAccessorPair(); |
6231 // pair and modify the accessor. | 6240 accessors->set(component, *accessor); |
6232 if (source_accessors != NULL) { | 6241 Handle<Map> new_map = CopyInsertDescriptor(Handle<Map>(object->map()), |
6233 maybe_accessors = source_accessors->Copy(); | 6242 name, accessors, attributes); |
6234 } else { | 6243 object->set_map(*new_map); |
6235 maybe_accessors = GetHeap()->AllocateAccessorPair(); | 6244 return object; |
6236 } | |
6237 if (!maybe_accessors->To(&accessors)) return maybe_accessors; | |
6238 accessors->set(component, accessor); | |
6239 | |
6240 CallbacksDescriptor new_accessors_desc(name, accessors, attributes); | |
6241 | |
6242 Map* new_map; | |
6243 MaybeObject* maybe_new_map = | |
6244 map()->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION); | |
6245 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | |
6246 | |
6247 set_map(new_map); | |
6248 return this; | |
6249 } | 6245 } |
6250 | 6246 |
6251 | 6247 |
6252 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { | 6248 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { |
6253 Isolate* isolate = GetIsolate(); | 6249 Isolate* isolate = GetIsolate(); |
6254 Name* name = Name::cast(info->name()); | 6250 Name* name = Name::cast(info->name()); |
6255 // Check access rights if needed. | 6251 // Check access rights if needed. |
6256 if (IsAccessCheckNeeded() && | 6252 if (IsAccessCheckNeeded() && |
6257 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { | 6253 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
6258 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 6254 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
(...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
7818 } | 7814 } |
7819 if (child_hash <= parent_hash) break; | 7815 if (child_hash <= parent_hash) break; |
7820 SwapSortedKeys(parent_index, child_index); | 7816 SwapSortedKeys(parent_index, child_index); |
7821 parent_index = child_index; | 7817 parent_index = child_index; |
7822 } | 7818 } |
7823 } | 7819 } |
7824 ASSERT(IsSortedNoDuplicates()); | 7820 ASSERT(IsSortedNoDuplicates()); |
7825 } | 7821 } |
7826 | 7822 |
7827 | 7823 |
7828 MaybeObject* AccessorPair::Copy() { | 7824 Handle<AccessorPair> AccessorPair::Copy(Handle<AccessorPair> pair) { |
7829 Heap* heap = GetHeap(); | 7825 Handle<AccessorPair> copy = pair->GetIsolate()->factory()->NewAccessorPair(); |
7830 AccessorPair* copy; | 7826 copy->set_getter(pair->getter()); |
7831 MaybeObject* maybe_copy = heap->AllocateAccessorPair(); | 7827 copy->set_setter(pair->setter()); |
7832 if (!maybe_copy->To(©)) return maybe_copy; | |
7833 | |
7834 copy->set_getter(getter()); | |
7835 copy->set_setter(setter()); | |
7836 return copy; | 7828 return copy; |
7837 } | 7829 } |
7838 | 7830 |
7839 | 7831 |
7840 Object* AccessorPair::GetComponent(AccessorComponent component) { | 7832 Object* AccessorPair::GetComponent(AccessorComponent component) { |
7841 Object* accessor = get(component); | 7833 Object* accessor = get(component); |
7842 return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor; | 7834 return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor; |
7843 } | 7835 } |
7844 | 7836 |
7845 | 7837 |
(...skipping 7976 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
15822 | 15814 |
15823 void PropertyCell::AddDependentCode(Handle<Code> code) { | 15815 void PropertyCell::AddDependentCode(Handle<Code> code) { |
15824 Handle<DependentCode> codes = DependentCode::Insert( | 15816 Handle<DependentCode> codes = DependentCode::Insert( |
15825 Handle<DependentCode>(dependent_code()), | 15817 Handle<DependentCode>(dependent_code()), |
15826 DependentCode::kPropertyCellChangedGroup, code); | 15818 DependentCode::kPropertyCellChangedGroup, code); |
15827 if (*codes != dependent_code()) set_dependent_code(*codes); | 15819 if (*codes != dependent_code()) set_dependent_code(*codes); |
15828 } | 15820 } |
15829 | 15821 |
15830 | 15822 |
15831 } } // namespace v8::internal | 15823 } } // namespace v8::internal |
OLD | NEW |