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

Side by Side Diff: src/runtime/runtime-classes.cc

Issue 2311413002: Super property loads and stores should throw if [[Prototype]] is null (Closed)
Patch Set: Created 4 years, 3 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
« no previous file with comments | « src/objects.cc ('k') | test/mjsunit/es6/super.js » ('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 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/runtime/runtime-utils.h" 5 #include "src/runtime/runtime-utils.h"
6 6
7 #include <stdlib.h> 7 #include <stdlib.h>
8 #include <limits> 8 #include <limits>
9 9
10 #include "src/arguments.h" 10 #include "src/arguments.h"
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 0); 180 CONVERT_ARG_HANDLE_CHECKED(Object, super_class, 0);
181 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 1); 181 CONVERT_ARG_HANDLE_CHECKED(JSFunction, constructor, 1);
182 CONVERT_SMI_ARG_CHECKED(start_position, 2); 182 CONVERT_SMI_ARG_CHECKED(start_position, 2);
183 CONVERT_SMI_ARG_CHECKED(end_position, 3); 183 CONVERT_SMI_ARG_CHECKED(end_position, 3);
184 184
185 RETURN_RESULT_OR_FAILURE( 185 RETURN_RESULT_OR_FAILURE(
186 isolate, DefineClass(isolate, super_class, constructor, start_position, 186 isolate, DefineClass(isolate, super_class, constructor, start_position,
187 end_position)); 187 end_position));
188 } 188 }
189 189
190 namespace {
190 191
191 static MaybeHandle<Object> LoadFromSuper(Isolate* isolate, 192 enum class SuperMode { kLoad, kStore };
192 Handle<Object> receiver, 193
193 Handle<JSObject> home_object, 194 MaybeHandle<JSReceiver> GetSuperHolder(
194 Handle<Name> name) { 195 Isolate* isolate, Handle<Object> receiver, Handle<JSObject> home_object,
196 SuperMode mode, MaybeHandle<Name> maybe_name, uint32_t index) {
195 if (home_object->IsAccessCheckNeeded() && 197 if (home_object->IsAccessCheckNeeded() &&
196 !isolate->MayAccess(handle(isolate->context()), home_object)) { 198 !isolate->MayAccess(handle(isolate->context()), home_object)) {
197 isolate->ReportFailedAccessCheck(home_object); 199 isolate->ReportFailedAccessCheck(home_object);
198 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 200 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, JSReceiver);
199 } 201 }
200 202
201 PrototypeIterator iter(isolate, home_object); 203 PrototypeIterator iter(isolate, home_object);
202 Handle<Object> proto = PrototypeIterator::GetCurrent(iter); 204 Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
203 if (!proto->IsJSReceiver()) { 205 if (!proto->IsJSReceiver()) {
204 return Object::ReadAbsentProperty(isolate, proto, name); 206 MessageTemplate::Template message =
207 mode == SuperMode::kLoad ? MessageTemplate::kNonObjectPropertyLoad
208 : MessageTemplate::kNonObjectPropertyStore;
209 Handle<Name> name;
210 if (!maybe_name.ToHandle(&name)) {
211 name = isolate->factory()->Uint32ToString(index);
212 }
213 THROW_NEW_ERROR(isolate, NewTypeError(message, name, proto), JSReceiver);
205 } 214 }
215 return Handle<JSReceiver>::cast(proto);
216 }
206 217
207 LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto)); 218 MaybeHandle<Object> LoadFromSuper(Isolate* isolate, Handle<Object> receiver,
219 Handle<JSObject> home_object,
220 Handle<Name> name) {
221 Handle<JSReceiver> holder;
222 ASSIGN_RETURN_ON_EXCEPTION(
223 isolate, holder,
224 GetSuperHolder(isolate, receiver, home_object, SuperMode::kLoad, name, 0),
225 Object);
226 LookupIterator it(receiver, name, holder);
208 Handle<Object> result; 227 Handle<Object> result;
209 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, Object::GetProperty(&it), Object); 228 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, Object::GetProperty(&it), Object);
210 return result; 229 return result;
211 } 230 }
212 231
213 static MaybeHandle<Object> LoadElementFromSuper(Isolate* isolate, 232 MaybeHandle<Object> LoadElementFromSuper(Isolate* isolate,
214 Handle<Object> receiver, 233 Handle<Object> receiver,
215 Handle<JSObject> home_object, 234 Handle<JSObject> home_object,
216 uint32_t index) { 235 uint32_t index) {
217 if (home_object->IsAccessCheckNeeded() && 236 Handle<JSReceiver> holder;
218 !isolate->MayAccess(handle(isolate->context()), home_object)) { 237 ASSIGN_RETURN_ON_EXCEPTION(
219 isolate->ReportFailedAccessCheck(home_object); 238 isolate, holder,
220 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); 239 GetSuperHolder(isolate, receiver, home_object, SuperMode::kLoad,
221 } 240 MaybeHandle<Name>(), index),
222 241 Object);
223 PrototypeIterator iter(isolate, home_object); 242 LookupIterator it(isolate, receiver, index, holder);
224 Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
225 if (!proto->IsJSReceiver()) {
226 Handle<Object> name = isolate->factory()->NewNumberFromUint(index);
227 return Object::ReadAbsentProperty(isolate, proto, name);
228 }
229
230 LookupIterator it(isolate, receiver, index, Handle<JSReceiver>::cast(proto));
231 Handle<Object> result; 243 Handle<Object> result;
232 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, Object::GetProperty(&it), Object); 244 ASSIGN_RETURN_ON_EXCEPTION(isolate, result, Object::GetProperty(&it), Object);
233 return result; 245 return result;
234 } 246 }
235 247
248 } // anonymous namespace
236 249
237 RUNTIME_FUNCTION(Runtime_LoadFromSuper) { 250 RUNTIME_FUNCTION(Runtime_LoadFromSuper) {
238 HandleScope scope(isolate); 251 HandleScope scope(isolate);
239 DCHECK_EQ(3, args.length()); 252 DCHECK_EQ(3, args.length());
240 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); 253 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
241 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); 254 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
242 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2); 255 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
243 256
244 RETURN_RESULT_OR_FAILURE(isolate, 257 RETURN_RESULT_OR_FAILURE(isolate,
245 LoadFromSuper(isolate, receiver, home_object, name)); 258 LoadFromSuper(isolate, receiver, home_object, name));
(...skipping 19 matching lines...) Expand all
265 Object::ToName(isolate, key)); 278 Object::ToName(isolate, key));
266 // TODO(verwaest): Unify using LookupIterator. 279 // TODO(verwaest): Unify using LookupIterator.
267 if (name->AsArrayIndex(&index)) { 280 if (name->AsArrayIndex(&index)) {
268 RETURN_RESULT_OR_FAILURE( 281 RETURN_RESULT_OR_FAILURE(
269 isolate, LoadElementFromSuper(isolate, receiver, home_object, index)); 282 isolate, LoadElementFromSuper(isolate, receiver, home_object, index));
270 } 283 }
271 RETURN_RESULT_OR_FAILURE(isolate, 284 RETURN_RESULT_OR_FAILURE(isolate,
272 LoadFromSuper(isolate, receiver, home_object, name)); 285 LoadFromSuper(isolate, receiver, home_object, name));
273 } 286 }
274 287
288 namespace {
275 289
276 static Object* StoreToSuper(Isolate* isolate, Handle<JSObject> home_object, 290 MaybeHandle<Object> StoreToSuper(Isolate* isolate, Handle<JSObject> home_object,
277 Handle<Object> receiver, Handle<Name> name, 291 Handle<Object> receiver, Handle<Name> name,
278 Handle<Object> value, LanguageMode language_mode) { 292 Handle<Object> value,
279 if (home_object->IsAccessCheckNeeded() && 293 LanguageMode language_mode) {
280 !isolate->MayAccess(handle(isolate->context()), home_object)) { 294 Handle<JSReceiver> holder;
281 isolate->ReportFailedAccessCheck(home_object); 295 ASSIGN_RETURN_ON_EXCEPTION(isolate, holder,
282 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); 296 GetSuperHolder(isolate, receiver, home_object,
283 } 297 SuperMode::kStore, name, 0),
284 298 Object);
285 PrototypeIterator iter(isolate, home_object); 299 LookupIterator it(receiver, name, holder);
286 Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
287 if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
288
289 LookupIterator it(receiver, name, Handle<JSReceiver>::cast(proto));
290 MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode, 300 MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode,
291 Object::CERTAINLY_NOT_STORE_FROM_KEYED), 301 Object::CERTAINLY_NOT_STORE_FROM_KEYED),
292 isolate->heap()->exception()); 302 MaybeHandle<Object>());
293 return *value; 303 return value;
294 } 304 }
295 305
296 306 MaybeHandle<Object> StoreElementToSuper(Isolate* isolate,
297 static Object* StoreElementToSuper(Isolate* isolate, 307 Handle<JSObject> home_object,
298 Handle<JSObject> home_object, 308 Handle<Object> receiver, uint32_t index,
299 Handle<Object> receiver, uint32_t index, 309 Handle<Object> value,
300 Handle<Object> value, 310 LanguageMode language_mode) {
301 LanguageMode language_mode) { 311 Handle<JSReceiver> holder;
302 if (home_object->IsAccessCheckNeeded() && 312 ASSIGN_RETURN_ON_EXCEPTION(
303 !isolate->MayAccess(handle(isolate->context()), home_object)) { 313 isolate, holder,
304 isolate->ReportFailedAccessCheck(home_object); 314 GetSuperHolder(isolate, receiver, home_object, SuperMode::kStore,
305 RETURN_FAILURE_IF_SCHEDULED_EXCEPTION(isolate); 315 MaybeHandle<Name>(), index),
306 } 316 Object);
307 317 LookupIterator it(isolate, receiver, index, holder);
308 PrototypeIterator iter(isolate, home_object);
309 Handle<Object> proto = PrototypeIterator::GetCurrent(iter);
310 if (!proto->IsJSReceiver()) return isolate->heap()->undefined_value();
311
312 LookupIterator it(isolate, receiver, index, Handle<JSReceiver>::cast(proto));
313 MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode, 318 MAYBE_RETURN(Object::SetSuperProperty(&it, value, language_mode,
314 Object::MAY_BE_STORE_FROM_KEYED), 319 Object::MAY_BE_STORE_FROM_KEYED),
315 isolate->heap()->exception()); 320 MaybeHandle<Object>());
316 return *value; 321 return value;
317 } 322 }
318 323
324 } // anonymous namespace
319 325
320 RUNTIME_FUNCTION(Runtime_StoreToSuper_Strict) { 326 RUNTIME_FUNCTION(Runtime_StoreToSuper_Strict) {
321 HandleScope scope(isolate); 327 HandleScope scope(isolate);
322 DCHECK(args.length() == 4); 328 DCHECK(args.length() == 4);
323 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); 329 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
324 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); 330 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
325 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2); 331 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
326 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); 332 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
327 333
328 return StoreToSuper(isolate, home_object, receiver, name, value, STRICT); 334 RETURN_RESULT_OR_FAILURE(isolate, StoreToSuper(isolate, home_object, receiver,
335 name, value, STRICT));
329 } 336 }
330 337
331 338
332 RUNTIME_FUNCTION(Runtime_StoreToSuper_Sloppy) { 339 RUNTIME_FUNCTION(Runtime_StoreToSuper_Sloppy) {
333 HandleScope scope(isolate); 340 HandleScope scope(isolate);
334 DCHECK(args.length() == 4); 341 DCHECK(args.length() == 4);
335 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); 342 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
336 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); 343 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
337 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2); 344 CONVERT_ARG_HANDLE_CHECKED(Name, name, 2);
338 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); 345 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
339 346
340 return StoreToSuper(isolate, home_object, receiver, name, value, SLOPPY); 347 RETURN_RESULT_OR_FAILURE(isolate, StoreToSuper(isolate, home_object, receiver,
348 name, value, SLOPPY));
341 } 349 }
342 350
343 351 static MaybeHandle<Object> StoreKeyedToSuper(
344 static Object* StoreKeyedToSuper(Isolate* isolate, Handle<JSObject> home_object, 352 Isolate* isolate, Handle<JSObject> home_object, Handle<Object> receiver,
345 Handle<Object> receiver, Handle<Object> key, 353 Handle<Object> key, Handle<Object> value, LanguageMode language_mode) {
346 Handle<Object> value,
347 LanguageMode language_mode) {
348 uint32_t index = 0; 354 uint32_t index = 0;
349 355
350 if (key->ToArrayIndex(&index)) { 356 if (key->ToArrayIndex(&index)) {
351 return StoreElementToSuper(isolate, home_object, receiver, index, value, 357 return StoreElementToSuper(isolate, home_object, receiver, index, value,
352 language_mode); 358 language_mode);
353 } 359 }
354 Handle<Name> name; 360 Handle<Name> name;
355 ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, name, 361 ASSIGN_RETURN_ON_EXCEPTION(isolate, name, Object::ToName(isolate, key),
356 Object::ToName(isolate, key)); 362 Object);
357 // TODO(verwaest): Unify using LookupIterator. 363 // TODO(verwaest): Unify using LookupIterator.
358 if (name->AsArrayIndex(&index)) { 364 if (name->AsArrayIndex(&index)) {
359 return StoreElementToSuper(isolate, home_object, receiver, index, value, 365 return StoreElementToSuper(isolate, home_object, receiver, index, value,
360 language_mode); 366 language_mode);
361 } 367 }
362 return StoreToSuper(isolate, home_object, receiver, name, value, 368 return StoreToSuper(isolate, home_object, receiver, name, value,
363 language_mode); 369 language_mode);
364 } 370 }
365 371
366 372
367 RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Strict) { 373 RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Strict) {
368 HandleScope scope(isolate); 374 HandleScope scope(isolate);
369 DCHECK(args.length() == 4); 375 DCHECK(args.length() == 4);
370 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); 376 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
371 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); 377 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
372 CONVERT_ARG_HANDLE_CHECKED(Object, key, 2); 378 CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
373 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); 379 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
374 380
375 return StoreKeyedToSuper(isolate, home_object, receiver, key, value, STRICT); 381 RETURN_RESULT_OR_FAILURE(
382 isolate,
383 StoreKeyedToSuper(isolate, home_object, receiver, key, value, STRICT));
376 } 384 }
377 385
378 386
379 RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Sloppy) { 387 RUNTIME_FUNCTION(Runtime_StoreKeyedToSuper_Sloppy) {
380 HandleScope scope(isolate); 388 HandleScope scope(isolate);
381 DCHECK(args.length() == 4); 389 DCHECK(args.length() == 4);
382 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0); 390 CONVERT_ARG_HANDLE_CHECKED(Object, receiver, 0);
383 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1); 391 CONVERT_ARG_HANDLE_CHECKED(JSObject, home_object, 1);
384 CONVERT_ARG_HANDLE_CHECKED(Object, key, 2); 392 CONVERT_ARG_HANDLE_CHECKED(Object, key, 2);
385 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3); 393 CONVERT_ARG_HANDLE_CHECKED(Object, value, 3);
386 394
387 return StoreKeyedToSuper(isolate, home_object, receiver, key, value, SLOPPY); 395 RETURN_RESULT_OR_FAILURE(
396 isolate,
397 StoreKeyedToSuper(isolate, home_object, receiver, key, value, SLOPPY));
388 } 398 }
389 399
390 400
391 RUNTIME_FUNCTION(Runtime_GetSuperConstructor) { 401 RUNTIME_FUNCTION(Runtime_GetSuperConstructor) {
392 SealHandleScope shs(isolate); 402 SealHandleScope shs(isolate);
393 DCHECK_EQ(1, args.length()); 403 DCHECK_EQ(1, args.length());
394 CONVERT_ARG_CHECKED(JSFunction, active_function, 0); 404 CONVERT_ARG_CHECKED(JSFunction, active_function, 0);
395 return active_function->map()->prototype(); 405 return active_function->map()->prototype();
396 } 406 }
397 407
398 } // namespace internal 408 } // namespace internal
399 } // namespace v8 409 } // namespace v8
OLDNEW
« no previous file with comments | « src/objects.cc ('k') | test/mjsunit/es6/super.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698