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

Side by Side Diff: src/lookup.cc

Issue 392243002: Reimplement SetProperty using the LookupIterator (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 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/lookup.h ('k') | src/objects.h » ('j') | src/objects.cc » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/v8.h" 5 #include "src/v8.h"
6 6
7 #include "src/bootstrapper.h" 7 #include "src/bootstrapper.h"
8 #include "src/lookup.h" 8 #include "src/lookup.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
109 ASSERT(is_guaranteed_to_have_holder()); 109 ASSERT(is_guaranteed_to_have_holder());
110 110
111 if (property_encoding_ == DICTIONARY) { 111 if (property_encoding_ == DICTIONARY) {
112 Handle<JSObject> holder = GetHolder(); 112 Handle<JSObject> holder = GetHolder();
113 number_ = holder->property_dictionary()->FindEntry(name_); 113 number_ = holder->property_dictionary()->FindEntry(name_);
114 if (number_ == NameDictionary::kNotFound) return false; 114 if (number_ == NameDictionary::kNotFound) return false;
115 115
116 property_details_ = GetHolder()->property_dictionary()->DetailsAt(number_); 116 property_details_ = GetHolder()->property_dictionary()->DetailsAt(number_);
117 // Holes in dictionary cells are absent values unless marked as read-only. 117 // Holes in dictionary cells are absent values unless marked as read-only.
118 if (holder->IsGlobalObject() && 118 if (holder->IsGlobalObject() &&
119 (property_details_.IsDeleted() || 119 (property_details_.IsDeleted() || FetchValue()->IsTheHole())) {
120 (!property_details_.IsReadOnly() && FetchValue()->IsTheHole()))) {
121 return false; 120 return false;
122 } 121 }
123 } else { 122 } else {
124 property_details_ = holder_map_->instance_descriptors()->GetDetails( 123 property_details_ = holder_map_->instance_descriptors()->GetDetails(
125 number_); 124 number_);
126 } 125 }
127 126
128 switch (property_details_.type()) { 127 switch (property_details_.type()) {
129 case v8::internal::FIELD: 128 case v8::internal::FIELD:
130 case v8::internal::NORMAL: 129 case v8::internal::NORMAL:
131 case v8::internal::CONSTANT: 130 case v8::internal::CONSTANT:
132 property_kind_ = DATA; 131 property_kind_ = DATA;
133 break; 132 break;
134 case v8::internal::CALLBACKS: 133 case v8::internal::CALLBACKS:
135 property_kind_ = ACCESSOR; 134 property_kind_ = ACCESSOR;
136 break; 135 break;
137 case v8::internal::HANDLER: 136 case v8::internal::HANDLER:
138 case v8::internal::NONEXISTENT: 137 case v8::internal::NONEXISTENT:
139 case v8::internal::INTERCEPTOR: 138 case v8::internal::INTERCEPTOR:
140 UNREACHABLE(); 139 UNREACHABLE();
141 } 140 }
142 141
143 has_property_ = true; 142 has_property_ = true;
144 return true; 143 return true;
145 } 144 }
146 145
147 146
147 void LookupIterator::PrepareForDataProperty(Handle<Object> value) {
148 ASSERT(has_property_);
149 ASSERT(HolderIsReceiver());
150 if (property_encoding_ == DICTIONARY) return;
151 holder_map_ = Map::PrepareForDataProperty(holder_map_, number_, value);
152 JSObject::MigrateToMap(GetHolder(), holder_map_);
153 // Reload property information.
154 if (holder_map_->is_dictionary_map()) {
155 property_encoding_ = DICTIONARY;
156 } else {
157 property_encoding_ = DESCRIPTOR;
158 }
159 CHECK(HasProperty());
160 }
161
162
163 void LookupIterator::TransitionToDataProperty(
164 Handle<Object> value, PropertyAttributes attributes,
165 Object::StoreFromKeyed store_mode) {
166 ASSERT(!has_property_ || !HolderIsReceiver());
167
168 // Can only be called when the receiver is a JSObject. JSProxy has to be
169 // handled via a trap. Adding properties to primitive values is not
170 // observable.
171 Handle<JSObject> receiver = Handle<JSObject>::cast(GetReceiver());
172
173 // Properties have to be added to context extension objects through
174 // SetOwnPropertyIgnoreAttributes.
175 ASSERT(!receiver->IsJSContextExtensionObject());
176
177 if (receiver->IsJSGlobalProxy()) {
178 receiver = handle(JSGlobalObject::cast(receiver->GetPrototype()));
179 }
180
181 maybe_holder_ = receiver;
182 holder_map_ = Map::TransitionToDataProperty(handle(receiver->map()), name_,
183 value, attributes, store_mode);
184 JSObject::MigrateToMap(receiver, holder_map_);
185
186 // Reload the information.
187 state_ = NOT_FOUND;
188 configuration_ = CHECK_OWN_REAL;
189 state_ = LookupInHolder();
190 ASSERT(IsFound());
191 HasProperty();
192 }
193
194
195 bool LookupIterator::HolderIsReceiver() const {
196 ASSERT(has_property_ || state_ == INTERCEPTOR || state_ == JSPROXY);
197 DisallowHeapAllocation no_gc;
198 Handle<Object> receiver = GetReceiver();
199 if (!receiver->IsJSReceiver()) return false;
200 Object* current = *receiver;
201 JSReceiver* holder = *maybe_holder_.ToHandleChecked();
202 // JSProxy do not occur as hidden prototypes.
203 if (current->IsJSProxy()) {
204 return JSReceiver::cast(current) == holder;
205 }
206 do {
207 if (JSReceiver::cast(current) == holder) return true;
208 ASSERT(!current->IsJSProxy());
209 current = JSObject::cast(current)->GetPrototype();
210 } while (!current->IsNull() &&
211 (current->IsJSGlobalObject() ||
212 JSReceiver::cast(current)->map()->is_hidden_prototype()));
213 return false;
214 }
215
216
148 Handle<Object> LookupIterator::FetchValue() const { 217 Handle<Object> LookupIterator::FetchValue() const {
149 Object* result = NULL; 218 Object* result = NULL;
150 switch (property_encoding_) { 219 switch (property_encoding_) {
151 case DICTIONARY: 220 case DICTIONARY:
152 result = GetHolder()->property_dictionary()->ValueAt(number_); 221 result = GetHolder()->property_dictionary()->ValueAt(number_);
153 if (GetHolder()->IsGlobalObject()) { 222 if (GetHolder()->IsGlobalObject()) {
154 result = PropertyCell::cast(result)->value(); 223 result = PropertyCell::cast(result)->value();
155 } 224 }
156 break; 225 break;
157 case DESCRIPTOR: 226 case DESCRIPTOR:
(...skipping 21 matching lines...) Expand all
179 ASSERT_EQ(DATA, property_kind_); 248 ASSERT_EQ(DATA, property_kind_);
180 Handle<Object> value = FetchValue(); 249 Handle<Object> value = FetchValue();
181 if (value->IsTheHole()) { 250 if (value->IsTheHole()) {
182 ASSERT(property_details_.IsReadOnly()); 251 ASSERT(property_details_.IsReadOnly());
183 return factory()->undefined_value(); 252 return factory()->undefined_value();
184 } 253 }
185 return value; 254 return value;
186 } 255 }
187 256
188 257
258 void LookupIterator::WriteDataValue(Handle<Object> value) {
259 ASSERT(is_guaranteed_to_have_holder());
260 ASSERT(has_property_);
261 if (property_encoding_ == DICTIONARY) {
262 Handle<JSObject> holder = GetHolder();
263 NameDictionary* property_dictionary = holder->property_dictionary();
264 if (holder->IsGlobalObject()) {
265 Handle<PropertyCell> cell(
266 PropertyCell::cast(property_dictionary->ValueAt(number_)));
267 PropertyCell::SetValueInferType(cell, value);
268 } else {
269 property_dictionary->ValueAtPut(number_, *value);
270 }
271 } else if (property_details_.type() == v8::internal::FIELD) {
272 GetHolder()->WriteToField(number_, *value);
273 } else {
274 ASSERT_EQ(v8::internal::CONSTANT, property_details_.type());
275 }
276 }
277
278
279 void LookupIterator::InternalizeName() {
280 if (name_->IsUniqueName()) return;
281 name_ = factory()->InternalizeString(Handle<String>::cast(name_));
282 }
189 } } // namespace v8::internal 283 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/lookup.h ('k') | src/objects.h » ('j') | src/objects.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698