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

Side by Side Diff: src/property-descriptor.cc

Issue 1438233002: [proxies] Teach ToPropertyDescriptor to deal with Proxies (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 1 month 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
« no previous file with comments | « src/property-descriptor.h ('k') | src/runtime/runtime-object.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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/property-descriptor.h" 5 #include "src/property-descriptor.h"
6 6
7 #include "src/bootstrapper.h" 7 #include "src/bootstrapper.h"
8 #include "src/factory.h" 8 #include "src/factory.h"
9 #include "src/isolate-inl.h" 9 #include "src/isolate-inl.h"
10 #include "src/lookup.h" 10 #include "src/lookup.h"
11 #include "src/objects-inl.h" 11 #include "src/objects-inl.h"
12 12
13 namespace v8 { 13 namespace v8 {
14 namespace internal { 14 namespace internal {
15 15
16 // Helper function for ToPropertyDescriptor. Comments describe steps for 16 // Helper function for ToPropertyDescriptor. Comments describe steps for
17 // "enumerable", other properties are handled the same way. 17 // "enumerable", other properties are handled the same way.
18 // Returns false if an exception was thrown. 18 // Returns false if an exception was thrown.
19 bool GetPropertyIfPresent(Handle<Object> obj, Handle<String> name, 19 bool GetPropertyIfPresent(Handle<Object> obj, Handle<String> name,
Camillo Bruni 2015/11/12 13:52:19 Probably this will (as so many other methods) need
Jakob Kummerow 2015/11/12 14:01:45 Maybe. Let's introduce them as needed.
20 Handle<Object>* value) { 20 Handle<Object>* value) {
21 LookupIterator it(obj, name); 21 LookupIterator it(obj, name);
22 // 4. Let hasEnumerable be HasProperty(Obj, "enumerable"). 22 // 4. Let hasEnumerable be HasProperty(Obj, "enumerable").
23 Maybe<PropertyAttributes> maybe_attr = JSReceiver::GetPropertyAttributes(&it); 23 Maybe<bool> has_property = JSReceiver::HasProperty(&it);
24 // 5. ReturnIfAbrupt(hasEnumerable). 24 // 5. ReturnIfAbrupt(hasEnumerable).
25 if (!maybe_attr.IsJust()) return false; 25 if (has_property.IsNothing()) return false;
26 // 6. If hasEnumerable is true, then 26 // 6. If hasEnumerable is true, then
27 if (maybe_attr.FromJust() != ABSENT) { 27 if (has_property.FromJust() == true) {
28 // 6a. Let enum be ToBoolean(Get(Obj, "enumerable")). 28 // 6a. Let enum be ToBoolean(Get(Obj, "enumerable")).
29 // 6b. ReturnIfAbrupt(enum). 29 // 6b. ReturnIfAbrupt(enum).
30 if (!JSObject::GetProperty(&it).ToHandle(value)) return false; 30 if (!JSObject::GetProperty(&it).ToHandle(value)) return false;
31 } 31 }
32 return true; 32 return true;
33 } 33 }
34 34
35 35
36 // Helper function for ToPropertyDescriptor. Handles the case of "simple" 36 // Helper function for ToPropertyDescriptor. Handles the case of "simple"
37 // objects: nothing on the prototype chain, just own fast data properties. 37 // objects: nothing on the prototype chain, just own fast data properties.
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
153 MessageTemplate::kPropertyDescObject, obj)); 153 MessageTemplate::kPropertyDescObject, obj));
154 return false; 154 return false;
155 } 155 }
156 // 3. Let desc be a new Property Descriptor that initially has no fields. 156 // 3. Let desc be a new Property Descriptor that initially has no fields.
157 DCHECK(desc->is_empty()); 157 DCHECK(desc->is_empty());
158 158
159 if (ToPropertyDescriptorFastPath(isolate, obj, desc)) { 159 if (ToPropertyDescriptorFastPath(isolate, obj, desc)) {
160 return true; 160 return true;
161 } 161 }
162 162
163 // TODO(jkummerow): Implement JSProxy support. 163 // enumerable?
Jakob Kummerow 2015/11/12 13:44:45 This is the same as old lines 167 through 253 with
164 // Specifically, instead of taking the attributes != ABSENT shortcut, we 164 Handle<Object> enumerable;
165 // have to implement proper HasProperty for proxies. 165 // 4 through 6b.
166 if (!obj->IsJSProxy()) { 166 if (!GetPropertyIfPresent(obj, isolate->factory()->enumerable_string(),
167 { // enumerable? 167 &enumerable)) {
168 Handle<Object> enumerable;
169 // 4 through 6b.
170 if (!GetPropertyIfPresent(obj, isolate->factory()->enumerable_string(),
171 &enumerable)) {
172 return false;
173 }
174 // 6c. Set the [[Enumerable]] field of desc to enum.
175 if (!enumerable.is_null()) {
176 desc->set_enumerable(enumerable->BooleanValue());
177 }
178 }
179 { // configurable?
180 Handle<Object> configurable;
181 // 7 through 9b.
182 if (!GetPropertyIfPresent(obj, isolate->factory()->configurable_string(),
183 &configurable)) {
184 return false;
185 }
186 // 9c. Set the [[Configurable]] field of desc to conf.
187 if (!configurable.is_null()) {
188 desc->set_configurable(configurable->BooleanValue());
189 }
190 }
191 { // value?
192 Handle<Object> value;
193 // 10 through 12b.
194 if (!GetPropertyIfPresent(obj, isolate->factory()->value_string(),
195 &value))
196 return false;
197 // 12c. Set the [[Value]] field of desc to value.
198 if (!value.is_null()) desc->set_value(value);
199 }
200 { // writable?
201 Handle<Object> writable;
202 // 13 through 15b.
203 if (!GetPropertyIfPresent(obj, isolate->factory()->writable_string(),
204 &writable)) {
205 return false;
206 }
207 // 15c. Set the [[Writable]] field of desc to writable.
208 if (!writable.is_null()) desc->set_writable(writable->BooleanValue());
209 }
210 { // getter?
211 Handle<Object> getter;
212 // 16 through 18b.
213 if (!GetPropertyIfPresent(obj, isolate->factory()->get_string(), &getter))
214 return false;
215 if (!getter.is_null()) {
216 // 18c. If IsCallable(getter) is false and getter is not undefined,
217 // throw a TypeError exception.
218 if (!getter->IsCallable() && !getter->IsUndefined()) {
219 isolate->Throw(*isolate->factory()->NewTypeError(
220 MessageTemplate::kObjectGetterCallable, getter));
221 return false;
222 }
223 // 18d. Set the [[Get]] field of desc to getter.
224 desc->set_get(getter);
225 }
226 { // setter?
227 Handle<Object> setter;
228 // 19 through 21b.
229 if (!GetPropertyIfPresent(obj, isolate->factory()->set_string(),
230 &setter))
231 return false;
232 if (!setter.is_null()) {
233 // 21c. If IsCallable(setter) is false and setter is not undefined,
234 // throw a TypeError exception.
235 if (!setter->IsCallable() && !setter->IsUndefined()) {
236 isolate->Throw(*isolate->factory()->NewTypeError(
237 MessageTemplate::kObjectSetterCallable, setter));
238 return false;
239 }
240 // 21d. Set the [[Set]] field of desc to setter.
241 desc->set_set(setter);
242 }
243 }
244 // 22. If either desc.[[Get]] or desc.[[Set]] is present, then
245 // 22a. If either desc.[[Value]] or desc.[[Writable]] is present,
246 // throw a TypeError exception.
247 if ((desc->has_get() || desc->has_set()) &&
248 (desc->has_value() || desc->has_writable())) {
249 isolate->Throw(*isolate->factory()->NewTypeError(
250 MessageTemplate::kValueAndAccessor, obj));
251 return false;
252 }
253 }
254 } else {
255 DCHECK(obj->IsJSProxy());
256 // Having an UNIMPLEMENTED() here would upset ClusterFuzz, because
257 // --harmony-proxies makes it possible to reach this branch.
258 isolate->Throw(
259 *isolate->factory()->NewTypeError(MessageTemplate::kUnsupported));
260 return false; 168 return false;
261 } 169 }
170 // 6c. Set the [[Enumerable]] field of desc to enum.
171 if (!enumerable.is_null()) {
172 desc->set_enumerable(enumerable->BooleanValue());
173 }
174
175 // configurable?
176 Handle<Object> configurable;
177 // 7 through 9b.
178 if (!GetPropertyIfPresent(obj, isolate->factory()->configurable_string(),
179 &configurable)) {
180 return false;
181 }
182 // 9c. Set the [[Configurable]] field of desc to conf.
183 if (!configurable.is_null()) {
184 desc->set_configurable(configurable->BooleanValue());
185 }
186
187 // value?
188 Handle<Object> value;
189 // 10 through 12b.
190 if (!GetPropertyIfPresent(obj, isolate->factory()->value_string(), &value)) {
191 return false;
192 }
193 // 12c. Set the [[Value]] field of desc to value.
194 if (!value.is_null()) desc->set_value(value);
195
196 // writable?
197 Handle<Object> writable;
198 // 13 through 15b.
199 if (!GetPropertyIfPresent(obj, isolate->factory()->writable_string(),
200 &writable)) {
201 return false;
202 }
203 // 15c. Set the [[Writable]] field of desc to writable.
204 if (!writable.is_null()) desc->set_writable(writable->BooleanValue());
205
206 // getter?
207 Handle<Object> getter;
208 // 16 through 18b.
209 if (!GetPropertyIfPresent(obj, isolate->factory()->get_string(), &getter)) {
210 return false;
211 }
212 if (!getter.is_null()) {
213 // 18c. If IsCallable(getter) is false and getter is not undefined,
214 // throw a TypeError exception.
215 if (!getter->IsCallable() && !getter->IsUndefined()) {
216 isolate->Throw(*isolate->factory()->NewTypeError(
217 MessageTemplate::kObjectGetterCallable, getter));
218 return false;
219 }
220 // 18d. Set the [[Get]] field of desc to getter.
221 desc->set_get(getter);
222 }
223 // setter?
224 Handle<Object> setter;
225 // 19 through 21b.
226 if (!GetPropertyIfPresent(obj, isolate->factory()->set_string(), &setter)) {
227 return false;
228 }
229 if (!setter.is_null()) {
230 // 21c. If IsCallable(setter) is false and setter is not undefined,
231 // throw a TypeError exception.
232 if (!setter->IsCallable() && !setter->IsUndefined()) {
233 isolate->Throw(*isolate->factory()->NewTypeError(
234 MessageTemplate::kObjectSetterCallable, setter));
235 return false;
236 }
237 // 21d. Set the [[Set]] field of desc to setter.
238 desc->set_set(setter);
239 }
240
241 // 22. If either desc.[[Get]] or desc.[[Set]] is present, then
242 // 22a. If either desc.[[Value]] or desc.[[Writable]] is present,
243 // throw a TypeError exception.
244 if ((desc->has_get() || desc->has_set()) &&
245 (desc->has_value() || desc->has_writable())) {
246 isolate->Throw(*isolate->factory()->NewTypeError(
247 MessageTemplate::kValueAndAccessor, obj));
248 return false;
249 }
250
262 // 23. Return desc. 251 // 23. Return desc.
263 return true; 252 return true;
264 } 253 }
265 254
266 255
256 // ES6 6.2.4.6
257 // static
258 void PropertyDescriptor::CompletePropertyDescriptor(Isolate* isolate,
Jakob Kummerow 2015/11/12 13:44:45 I'm not using this yet, but my next CL is going to
259 PropertyDescriptor* desc) {
260 // 1. ReturnIfAbrupt(Desc).
261 // 2. Assert: Desc is a Property Descriptor.
262 // 3. Let like be Record{
263 // [[Value]]: undefined, [[Writable]]: false,
264 // [[Get]]: undefined, [[Set]]: undefined,
265 // [[Enumerable]]: false, [[Configurable]]: false}.
266 // 4. If either IsGenericDescriptor(Desc) or IsDataDescriptor(Desc) is true,
267 // then:
268 if (!IsAccessorDescriptor(desc)) {
269 // 4a. If Desc does not have a [[Value]] field, set Desc.[[Value]] to
270 // like.[[Value]].
271 if (!desc->has_value()) {
272 desc->set_value(isolate->factory()->undefined_value());
273 }
274 // 4b. If Desc does not have a [[Writable]] field, set Desc.[[Writable]]
275 // to like.[[Writable]].
276 if (!desc->has_writable()) desc->set_writable(false);
277 } else {
278 // 5. Else,
279 // 5a. If Desc does not have a [[Get]] field, set Desc.[[Get]] to
280 // like.[[Get]].
281 if (!desc->has_get()) {
282 desc->set_get(isolate->factory()->undefined_value());
283 }
284 // 5b. If Desc does not have a [[Set]] field, set Desc.[[Set]] to
285 // like.[[Set]].
286 if (!desc->has_set()) {
287 desc->set_set(isolate->factory()->undefined_value());
288 }
289 }
290 // 6. If Desc does not have an [[Enumerable]] field, set
291 // Desc.[[Enumerable]] to like.[[Enumerable]].
292 if (!desc->has_enumerable()) desc->set_enumerable(false);
293 // 7. If Desc does not have a [[Configurable]] field, set
294 // Desc.[[Configurable]] to like.[[Configurable]].
295 if (!desc->has_configurable()) desc->set_configurable(false);
296 // 8. Return Desc.
297 }
298
267 } // namespace internal 299 } // namespace internal
268 } // namespace v8 300 } // namespace v8
OLDNEW
« no previous file with comments | « src/property-descriptor.h ('k') | src/runtime/runtime-object.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698