Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/objects.cc

Issue 18497003: Handlify JSObject::DefineAccessor method. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressed comments by Andreas Rossberg. Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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::cast(obj), isolate));
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();
5935 bool only_attribute_changes = getter->IsNull() && setter->IsNull(); 5937 bool only_attribute_changes = getter->IsNull() && setter->IsNull();
5936 if (HasFastProperties() && !only_attribute_changes && 5938 if (object->HasFastProperties() && !only_attribute_changes &&
5937 (map()->NumberOfOwnDescriptors() < 5939 (object->map()->NumberOfOwnDescriptors() <
5938 DescriptorArray::kMaxNumberOfDescriptors)) { 5940 DescriptorArray::kMaxNumberOfDescriptors)) {
5939 MaybeObject* getterOk = heap->undefined_value(); 5941 bool getterOk = getter->IsNull() ||
5940 if (!getter->IsNull()) { 5942 DefineFastAccessor(object, name, ACCESSOR_GETTER, getter, attributes);
5941 getterOk = DefineFastAccessor(name, ACCESSOR_GETTER, getter, attributes); 5943 bool setterOk = !getterOk || setter->IsNull() ||
5942 if (getterOk->IsFailure()) return getterOk; 5944 DefineFastAccessor(object, name, ACCESSOR_SETTER, setter, attributes);
5943 } 5945 if (getterOk && setterOk) return;
5944
5945 MaybeObject* setterOk = heap->undefined_value();
5946 if (getterOk != heap->null_value() && !setter->IsNull()) {
5947 setterOk = DefineFastAccessor(name, ACCESSOR_SETTER, setter, attributes);
5948 if (setterOk->IsFailure()) return setterOk;
5949 }
5950
5951 if (getterOk != heap->null_value() && setterOk != heap->null_value()) {
5952 return heap->undefined_value();
5953 }
5954 } 5946 }
5955 5947
5956 AccessorPair* accessors; 5948 Handle<AccessorPair> accessors = CreateAccessorPairFor(object, name);
5957 MaybeObject* maybe_accessors = CreateAccessorPairFor(name); 5949 accessors->SetComponents(*getter, *setter);
5958 if (!maybe_accessors->To(&accessors)) return maybe_accessors;
5959 5950
5960 accessors->SetComponents(getter, setter); 5951 CALL_HEAP_FUNCTION_VOID(
5961 return SetPropertyCallback(name, accessors, attributes); 5952 object->GetIsolate(),
5953 object->SetPropertyCallback(*name, *accessors, attributes));
5962 } 5954 }
5963 5955
5964 5956
5965 bool JSObject::CanSetCallback(Name* name) { 5957 bool JSObject::CanSetCallback(Name* name) {
5966 ASSERT(!IsAccessCheckNeeded() || 5958 ASSERT(!IsAccessCheckNeeded() ||
5967 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET)); 5959 GetIsolate()->MayNamedAccess(this, name, v8::ACCESS_SET));
5968 5960
5969 // Check if there is an API defined callback object which prohibits 5961 // Check if there is an API defined callback object which prohibits
5970 // callback overwriting in this object or its prototype chain. 5962 // callback overwriting in this object or its prototype chain.
5971 // This mechanism is needed for instance in a browser setting, where 5963 // This mechanism is needed for instance in a browser setting, where
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
6053 6045
6054 return GetHeap()->undefined_value(); 6046 return GetHeap()->undefined_value();
6055 } 6047 }
6056 6048
6057 6049
6058 void JSObject::DefineAccessor(Handle<JSObject> object, 6050 void JSObject::DefineAccessor(Handle<JSObject> object,
6059 Handle<Name> name, 6051 Handle<Name> name,
6060 Handle<Object> getter, 6052 Handle<Object> getter,
6061 Handle<Object> setter, 6053 Handle<Object> setter,
6062 PropertyAttributes attributes) { 6054 PropertyAttributes attributes) {
6063 CALL_HEAP_FUNCTION_VOID( 6055 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. 6056 // Check access rights if needed.
6074 if (IsAccessCheckNeeded() && 6057 if (object->IsAccessCheckNeeded() &&
6075 !isolate->MayNamedAccess(this, name_raw, v8::ACCESS_SET)) { 6058 !isolate->MayNamedAccess(*object, *name, v8::ACCESS_SET)) {
6076 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); 6059 isolate->ReportFailedAccessCheck(*object, v8::ACCESS_SET);
6077 return isolate->heap()->undefined_value(); 6060 return;
6078 } 6061 }
6079 6062
6080 if (IsJSGlobalProxy()) { 6063 if (object->IsJSGlobalProxy()) {
6081 Object* proto = GetPrototype(); 6064 Handle<Object> proto(object->GetPrototype(), isolate);
6082 if (proto->IsNull()) return this; 6065 if (proto->IsNull()) return;
6083 ASSERT(proto->IsJSGlobalObject()); 6066 ASSERT(proto->IsJSGlobalObject());
6084 return JSObject::cast(proto)->DefineAccessor( 6067 DefineAccessor(
6085 name_raw, getter_raw, setter_raw, attributes); 6068 Handle<JSObject>::cast(proto), name, getter, setter, attributes);
6069 return;
6086 } 6070 }
6087 6071
6088 // Make sure that the top context does not change when doing callbacks or 6072 // Make sure that the top context does not change when doing callbacks or
6089 // interceptor calls. 6073 // interceptor calls.
6090 AssertNoContextChange ncc; 6074 AssertNoContextChange ncc;
6091 6075
6092 // Try to flatten before operating on the string. 6076 // Try to flatten before operating on the string.
6093 if (name_raw->IsString()) String::cast(name_raw)->TryFlatten(); 6077 if (name->IsString()) String::cast(*name)->TryFlatten();
6094 6078
6095 if (!CanSetCallback(name_raw)) return isolate->heap()->undefined_value(); 6079 if (!object->CanSetCallback(*name)) return;
6096
6097 // From this point on everything needs to be handlified.
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 6080
6104 uint32_t index = 0; 6081 uint32_t index = 0;
6105 bool is_element = name->AsArrayIndex(&index); 6082 bool is_element = name->AsArrayIndex(&index);
6106 6083
6107 Handle<Object> old_value = isolate->factory()->the_hole_value(); 6084 Handle<Object> old_value = isolate->factory()->the_hole_value();
6108 bool is_observed = FLAG_harmony_observation && self->map()->is_observed(); 6085 bool is_observed = FLAG_harmony_observation && object->map()->is_observed();
6109 bool preexists = false; 6086 bool preexists = false;
6110 if (is_observed) { 6087 if (is_observed) {
6111 if (is_element) { 6088 if (is_element) {
6112 preexists = HasLocalElement(index); 6089 preexists = object->HasLocalElement(index);
6113 if (preexists && self->GetLocalElementAccessorPair(index) == NULL) { 6090 if (preexists && object->GetLocalElementAccessorPair(index) == NULL) {
6114 old_value = Object::GetElement(self, index); 6091 old_value = Object::GetElement(object, index);
6115 } 6092 }
6116 } else { 6093 } else {
6117 LookupResult lookup(isolate); 6094 LookupResult lookup(isolate);
6118 LocalLookup(*name, &lookup, true); 6095 object->LocalLookup(*name, &lookup, true);
6119 preexists = lookup.IsProperty(); 6096 preexists = lookup.IsProperty();
6120 if (preexists && lookup.IsDataProperty()) { 6097 if (preexists && lookup.IsDataProperty()) {
6121 old_value = Object::GetProperty(self, name); 6098 old_value = Object::GetProperty(object, name);
6122 } 6099 }
6123 } 6100 }
6124 } 6101 }
6125 6102
6126 MaybeObject* result = is_element ? 6103 if (is_element) {
6127 self->DefineElementAccessor(index, *getter, *setter, attributes) : 6104 DefineElementAccessor(object, index, getter, setter, attributes);
6128 self->DefinePropertyAccessor(*name, *getter, *setter, attributes); 6105 } else {
6129 6106 DefinePropertyAccessor(object, name, getter, setter, attributes);
6130 Handle<Object> hresult; 6107 }
6131 if (!result->ToHandle(&hresult, isolate)) return result;
6132 6108
6133 if (is_observed) { 6109 if (is_observed) {
6134 const char* type = preexists ? "reconfigured" : "new"; 6110 const char* type = preexists ? "reconfigured" : "new";
6135 EnqueueChangeRecord(self, type, name, old_value); 6111 EnqueueChangeRecord(object, type, name, old_value);
6136 } 6112 }
6137
6138 return *hresult;
6139 } 6113 }
6140 6114
6141 6115
6142 static MaybeObject* TryAccessorTransition(JSObject* self, 6116 static bool TryAccessorTransition(JSObject* self,
6143 Map* transitioned_map, 6117 Map* transitioned_map,
6144 int target_descriptor, 6118 int target_descriptor,
6145 AccessorComponent component, 6119 AccessorComponent component,
6146 Object* accessor, 6120 Object* accessor,
6147 PropertyAttributes attributes) { 6121 PropertyAttributes attributes) {
6148 DescriptorArray* descs = transitioned_map->instance_descriptors(); 6122 DescriptorArray* descs = transitioned_map->instance_descriptors();
6149 PropertyDetails details = descs->GetDetails(target_descriptor); 6123 PropertyDetails details = descs->GetDetails(target_descriptor);
6150 6124
6151 // If the transition target was not callbacks, fall back to the slow case. 6125 // If the transition target was not callbacks, fall back to the slow case.
6152 if (details.type() != CALLBACKS) return self->GetHeap()->null_value(); 6126 if (details.type() != CALLBACKS) return false;
6153 Object* descriptor = descs->GetCallbacksObject(target_descriptor); 6127 Object* descriptor = descs->GetCallbacksObject(target_descriptor);
6154 if (!descriptor->IsAccessorPair()) return self->GetHeap()->null_value(); 6128 if (!descriptor->IsAccessorPair()) return false;
6155 6129
6156 Object* target_accessor = AccessorPair::cast(descriptor)->get(component); 6130 Object* target_accessor = AccessorPair::cast(descriptor)->get(component);
6157 PropertyAttributes target_attributes = details.attributes(); 6131 PropertyAttributes target_attributes = details.attributes();
6158 6132
6159 // Reuse transition if adding same accessor with same attributes. 6133 // Reuse transition if adding same accessor with same attributes.
6160 if (target_accessor == accessor && target_attributes == attributes) { 6134 if (target_accessor == accessor && target_attributes == attributes) {
6161 self->set_map(transitioned_map); 6135 self->set_map(transitioned_map);
6162 return self; 6136 return true;
6163 } 6137 }
6164 6138
6165 // If either not the same accessor, or not the same attributes, fall back to 6139 // If either not the same accessor, or not the same attributes, fall back to
6166 // the slow case. 6140 // the slow case.
6167 return self->GetHeap()->null_value(); 6141 return false;
6168 } 6142 }
6169 6143
6170 6144
6171 MaybeObject* JSObject::DefineFastAccessor(Name* name, 6145 static MaybeObject* CopyInsertDescriptor(Map* map,
6172 AccessorComponent component, 6146 Name* name,
6173 Object* accessor, 6147 AccessorPair* accessors,
6174 PropertyAttributes attributes) { 6148 PropertyAttributes attributes) {
6149 CallbacksDescriptor new_accessors_desc(name, accessors, attributes);
6150 return map->CopyInsertDescriptor(&new_accessors_desc, INSERT_TRANSITION);
6151 }
6152
6153
6154 static Handle<Map> CopyInsertDescriptor(Handle<Map> map,
6155 Handle<Name> name,
6156 Handle<AccessorPair> accessors,
6157 PropertyAttributes attributes) {
6158 CALL_HEAP_FUNCTION(map->GetIsolate(),
6159 CopyInsertDescriptor(*map, *name, *accessors, attributes),
6160 Map);
6161 }
6162
6163
6164 bool JSObject::DefineFastAccessor(Handle<JSObject> object,
6165 Handle<Name> name,
6166 AccessorComponent component,
6167 Handle<Object> accessor,
6168 PropertyAttributes attributes) {
6175 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined()); 6169 ASSERT(accessor->IsSpecFunction() || accessor->IsUndefined());
6176 LookupResult result(GetIsolate()); 6170 Isolate* isolate = object->GetIsolate();
6177 LocalLookup(name, &result); 6171 LookupResult result(isolate);
6172 object->LocalLookup(*name, &result);
6178 6173
6179 if (result.IsFound() && !result.IsPropertyCallbacks()) { 6174 if (result.IsFound() && !result.IsPropertyCallbacks()) {
6180 return GetHeap()->null_value(); 6175 return false;
6181 } 6176 }
6182 6177
6183 // Return success if the same accessor with the same attributes already exist. 6178 // Return success if the same accessor with the same attributes already exist.
6184 AccessorPair* source_accessors = NULL; 6179 AccessorPair* source_accessors = NULL;
6185 if (result.IsPropertyCallbacks()) { 6180 if (result.IsPropertyCallbacks()) {
6186 Object* callback_value = result.GetCallbackObject(); 6181 Object* callback_value = result.GetCallbackObject();
6187 if (callback_value->IsAccessorPair()) { 6182 if (callback_value->IsAccessorPair()) {
6188 source_accessors = AccessorPair::cast(callback_value); 6183 source_accessors = AccessorPair::cast(callback_value);
6189 Object* entry = source_accessors->get(component); 6184 Object* entry = source_accessors->get(component);
6190 if (entry == accessor && result.GetAttributes() == attributes) { 6185 if (entry == *accessor && result.GetAttributes() == attributes) {
6191 return this; 6186 return true;
6192 } 6187 }
6193 } else { 6188 } else {
6194 return GetHeap()->null_value(); 6189 return false;
6195 } 6190 }
6196 6191
6197 int descriptor_number = result.GetDescriptorIndex(); 6192 int descriptor_number = result.GetDescriptorIndex();
6198 6193
6199 map()->LookupTransition(this, name, &result); 6194 object->map()->LookupTransition(*object, *name, &result);
6200 6195
6201 if (result.IsFound()) { 6196 if (result.IsFound()) {
6202 Map* target = result.GetTransitionTarget(); 6197 Map* target = result.GetTransitionTarget();
6203 ASSERT(target->NumberOfOwnDescriptors() == 6198 ASSERT(target->NumberOfOwnDescriptors() ==
6204 map()->NumberOfOwnDescriptors()); 6199 object->map()->NumberOfOwnDescriptors());
6205 // This works since descriptors are sorted in order of addition. 6200 // This works since descriptors are sorted in order of addition.
6206 ASSERT(map()->instance_descriptors()->GetKey(descriptor_number) == name); 6201 ASSERT(object->map()->instance_descriptors()->
6207 return TryAccessorTransition( 6202 GetKey(descriptor_number) == *name);
6208 this, target, descriptor_number, component, accessor, attributes); 6203 return TryAccessorTransition(*object, target, descriptor_number,
6204 component, *accessor, attributes);
6209 } 6205 }
6210 } else { 6206 } else {
6211 // If not, lookup a transition. 6207 // If not, lookup a transition.
6212 map()->LookupTransition(this, name, &result); 6208 object->map()->LookupTransition(*object, *name, &result);
6213 6209
6214 // If there is a transition, try to follow it. 6210 // If there is a transition, try to follow it.
6215 if (result.IsFound()) { 6211 if (result.IsFound()) {
6216 Map* target = result.GetTransitionTarget(); 6212 Map* target = result.GetTransitionTarget();
6217 int descriptor_number = target->LastAdded(); 6213 int descriptor_number = target->LastAdded();
6218 ASSERT(target->instance_descriptors()->GetKey(descriptor_number) 6214 ASSERT(target->instance_descriptors()->GetKey(descriptor_number)
6219 ->Equals(name)); 6215 ->Equals(*name));
6220 return TryAccessorTransition( 6216 return TryAccessorTransition(*object, target, descriptor_number,
6221 this, target, descriptor_number, component, accessor, attributes); 6217 component, *accessor, attributes);
6222 } 6218 }
6223 } 6219 }
6224 6220
6225 // If there is no transition yet, add a transition to the a new accessor pair 6221 // If there is no transition yet, add a transition to the a new accessor pair
6226 // containing the accessor. 6222 // containing the accessor. Allocate a new pair if there were no source
6227 AccessorPair* accessors; 6223 // accessors. Otherwise, copy the pair and modify the accessor.
6228 MaybeObject* maybe_accessors; 6224 Handle<AccessorPair> accessors = source_accessors != NULL
6229 6225 ? AccessorPair::Copy(Handle<AccessorPair>(source_accessors))
6230 // Allocate a new pair if there were no source accessors. Otherwise, copy the 6226 : isolate->factory()->NewAccessorPair();
6231 // pair and modify the accessor. 6227 accessors->set(component, *accessor);
6232 if (source_accessors != NULL) { 6228 Handle<Map> new_map = CopyInsertDescriptor(Handle<Map>(object->map()),
6233 maybe_accessors = source_accessors->Copy(); 6229 name, accessors, attributes);
6234 } else { 6230 object->set_map(*new_map);
6235 maybe_accessors = GetHeap()->AllocateAccessorPair(); 6231 return true;
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 } 6232 }
6250 6233
6251 6234
6252 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { 6235 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) {
6253 Isolate* isolate = GetIsolate(); 6236 Isolate* isolate = GetIsolate();
6254 Name* name = Name::cast(info->name()); 6237 Name* name = Name::cast(info->name());
6255 // Check access rights if needed. 6238 // Check access rights if needed.
6256 if (IsAccessCheckNeeded() && 6239 if (IsAccessCheckNeeded() &&
6257 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { 6240 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) {
6258 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); 6241 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET);
(...skipping 1559 matching lines...) Expand 10 before | Expand all | Expand 10 after
7818 } 7801 }
7819 if (child_hash <= parent_hash) break; 7802 if (child_hash <= parent_hash) break;
7820 SwapSortedKeys(parent_index, child_index); 7803 SwapSortedKeys(parent_index, child_index);
7821 parent_index = child_index; 7804 parent_index = child_index;
7822 } 7805 }
7823 } 7806 }
7824 ASSERT(IsSortedNoDuplicates()); 7807 ASSERT(IsSortedNoDuplicates());
7825 } 7808 }
7826 7809
7827 7810
7828 MaybeObject* AccessorPair::Copy() { 7811 Handle<AccessorPair> AccessorPair::Copy(Handle<AccessorPair> pair) {
7829 Heap* heap = GetHeap(); 7812 Handle<AccessorPair> copy = pair->GetIsolate()->factory()->NewAccessorPair();
7830 AccessorPair* copy; 7813 copy->set_getter(pair->getter());
7831 MaybeObject* maybe_copy = heap->AllocateAccessorPair(); 7814 copy->set_setter(pair->setter());
7832 if (!maybe_copy->To(&copy)) return maybe_copy;
7833
7834 copy->set_getter(getter());
7835 copy->set_setter(setter());
7836 return copy; 7815 return copy;
7837 } 7816 }
7838 7817
7839 7818
7840 Object* AccessorPair::GetComponent(AccessorComponent component) { 7819 Object* AccessorPair::GetComponent(AccessorComponent component) {
7841 Object* accessor = get(component); 7820 Object* accessor = get(component);
7842 return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor; 7821 return accessor->IsTheHole() ? GetHeap()->undefined_value() : accessor;
7843 } 7822 }
7844 7823
7845 7824
(...skipping 7976 matching lines...) Expand 10 before | Expand all | Expand 10 after
15822 15801
15823 void PropertyCell::AddDependentCode(Handle<Code> code) { 15802 void PropertyCell::AddDependentCode(Handle<Code> code) {
15824 Handle<DependentCode> codes = DependentCode::Insert( 15803 Handle<DependentCode> codes = DependentCode::Insert(
15825 Handle<DependentCode>(dependent_code()), 15804 Handle<DependentCode>(dependent_code()),
15826 DependentCode::kPropertyCellChangedGroup, code); 15805 DependentCode::kPropertyCellChangedGroup, code);
15827 if (*codes != dependent_code()) set_dependent_code(*codes); 15806 if (*codes != dependent_code()) set_dependent_code(*codes);
15828 } 15807 }
15829 15808
15830 15809
15831 } } // namespace v8::internal 15810 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698