OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 "v8.h" | 5 #include "v8.h" |
6 | 6 |
7 #include "accessors.h" | 7 #include "accessors.h" |
8 #include "allocation-site-scopes.h" | 8 #include "allocation-site-scopes.h" |
9 #include "api.h" | 9 #include "api.h" |
10 #include "arguments.h" | 10 #include "arguments.h" |
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
354 Handle<FixedArray> elems(FixedArray::cast(object->elements()), isolate); | 354 Handle<FixedArray> elems(FixedArray::cast(object->elements()), isolate); |
355 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; | 355 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems; |
356 Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap( | 356 Handle<FixedArray> writable_elems = isolate->factory()->CopyFixedArrayWithMap( |
357 elems, isolate->factory()->fixed_array_map()); | 357 elems, isolate->factory()->fixed_array_map()); |
358 object->set_elements(*writable_elems); | 358 object->set_elements(*writable_elems); |
359 isolate->counters()->cow_arrays_converted()->Increment(); | 359 isolate->counters()->cow_arrays_converted()->Increment(); |
360 return writable_elems; | 360 return writable_elems; |
361 } | 361 } |
362 | 362 |
363 | 363 |
364 MaybeHandle<Object> JSObject::GetPropertyWithCallback(Handle<JSObject> object, | 364 MaybeHandle<Object> JSProxy::GetPropertyWithHandler(Handle<JSProxy> proxy, |
365 Handle<Object> receiver, | 365 Handle<Object> receiver, |
366 Handle<Object> structure, | 366 Handle<Name> name) { |
367 Handle<Name> name) { | 367 Isolate* isolate = proxy->GetIsolate(); |
| 368 |
| 369 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
| 370 if (name->IsSymbol()) return isolate->factory()->undefined_value(); |
| 371 |
| 372 Handle<Object> args[] = { receiver, name }; |
| 373 return CallTrap( |
| 374 proxy, "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args); |
| 375 } |
| 376 |
| 377 |
| 378 MaybeHandle<Object> Object::GetPropertyWithCallback(Handle<Object> receiver, |
| 379 Handle<Name> name, |
| 380 Handle<JSObject> holder, |
| 381 Handle<Object> structure) { |
368 Isolate* isolate = name->GetIsolate(); | 382 Isolate* isolate = name->GetIsolate(); |
369 ASSERT(!structure->IsForeign()); | 383 ASSERT(!structure->IsForeign()); |
370 // api style callbacks. | 384 // api style callbacks. |
371 if (structure->IsAccessorInfo()) { | 385 if (structure->IsAccessorInfo()) { |
372 Handle<AccessorInfo> accessor_info = Handle<AccessorInfo>::cast(structure); | 386 Handle<AccessorInfo> accessor_info = Handle<AccessorInfo>::cast(structure); |
373 if (!accessor_info->IsCompatibleReceiver(*receiver)) { | 387 if (!accessor_info->IsCompatibleReceiver(*receiver)) { |
374 Handle<Object> args[2] = { name, receiver }; | 388 Handle<Object> args[2] = { name, receiver }; |
375 Handle<Object> error = | 389 Handle<Object> error = |
376 isolate->factory()->NewTypeError("incompatible_method_receiver", | 390 isolate->factory()->NewTypeError("incompatible_method_receiver", |
377 HandleVector(args, | 391 HandleVector(args, |
(...skipping 10 matching lines...) Expand all Loading... |
388 isolate); | 402 isolate); |
389 } | 403 } |
390 | 404 |
391 Handle<ExecutableAccessorInfo> data = | 405 Handle<ExecutableAccessorInfo> data = |
392 Handle<ExecutableAccessorInfo>::cast(structure); | 406 Handle<ExecutableAccessorInfo>::cast(structure); |
393 v8::AccessorGetterCallback call_fun = | 407 v8::AccessorGetterCallback call_fun = |
394 v8::ToCData<v8::AccessorGetterCallback>(data->getter()); | 408 v8::ToCData<v8::AccessorGetterCallback>(data->getter()); |
395 if (call_fun == NULL) return isolate->factory()->undefined_value(); | 409 if (call_fun == NULL) return isolate->factory()->undefined_value(); |
396 | 410 |
397 Handle<String> key = Handle<String>::cast(name); | 411 Handle<String> key = Handle<String>::cast(name); |
398 LOG(isolate, ApiNamedPropertyAccess("load", *object, *name)); | 412 LOG(isolate, ApiNamedPropertyAccess("load", *holder, *name)); |
399 PropertyCallbackArguments args(isolate, data->data(), *receiver, *object); | 413 PropertyCallbackArguments args(isolate, data->data(), *receiver, *holder); |
400 v8::Handle<v8::Value> result = | 414 v8::Handle<v8::Value> result = |
401 args.Call(call_fun, v8::Utils::ToLocal(key)); | 415 args.Call(call_fun, v8::Utils::ToLocal(key)); |
402 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | 416 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
403 if (result.IsEmpty()) { | 417 if (result.IsEmpty()) { |
404 return isolate->factory()->undefined_value(); | 418 return isolate->factory()->undefined_value(); |
405 } | 419 } |
406 Handle<Object> return_value = v8::Utils::OpenHandle(*result); | 420 Handle<Object> return_value = v8::Utils::OpenHandle(*result); |
407 return_value->VerifyApiCallResultType(); | 421 return_value->VerifyApiCallResultType(); |
408 // Rebox handle before return. | 422 // Rebox handle before return. |
409 return handle(*return_value, isolate); | 423 return handle(*return_value, isolate); |
410 } | 424 } |
411 | 425 |
412 // __defineGetter__ callback | 426 // __defineGetter__ callback |
413 Handle<Object> getter(Handle<AccessorPair>::cast(structure)->getter(), | 427 Handle<Object> getter(Handle<AccessorPair>::cast(structure)->getter(), |
414 isolate); | 428 isolate); |
415 if (getter->IsSpecFunction()) { | 429 if (getter->IsSpecFunction()) { |
416 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 430 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
417 return Object::GetPropertyWithDefinedGetter( | 431 return Object::GetPropertyWithDefinedGetter( |
418 object, receiver, Handle<JSReceiver>::cast(getter)); | 432 receiver, Handle<JSReceiver>::cast(getter)); |
419 } | 433 } |
420 // Getter is not a function. | 434 // Getter is not a function. |
421 return isolate->factory()->undefined_value(); | 435 return isolate->factory()->undefined_value(); |
422 } | 436 } |
423 | 437 |
424 | 438 |
425 MaybeHandle<Object> JSProxy::GetPropertyWithHandler(Handle<JSProxy> proxy, | 439 MaybeHandle<Object> Object::SetPropertyWithCallback(Handle<Object> receiver, |
426 Handle<Object> receiver, | 440 Handle<Name> name, |
427 Handle<Name> name) { | 441 Handle<Object> value, |
428 Isolate* isolate = proxy->GetIsolate(); | 442 Handle<JSObject> holder, |
| 443 Handle<Object> structure, |
| 444 StrictMode strict_mode) { |
| 445 Isolate* isolate = name->GetIsolate(); |
429 | 446 |
430 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 447 // We should never get here to initialize a const with the hole |
431 if (name->IsSymbol()) return isolate->factory()->undefined_value(); | 448 // value since a const declaration would conflict with the setter. |
| 449 ASSERT(!value->IsTheHole()); |
| 450 ASSERT(!structure->IsForeign()); |
| 451 if (structure->IsExecutableAccessorInfo()) { |
| 452 // api style callbacks |
| 453 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(*structure); |
| 454 if (!data->IsCompatibleReceiver(*receiver)) { |
| 455 Handle<Object> args[2] = { name, receiver }; |
| 456 Handle<Object> error = |
| 457 isolate->factory()->NewTypeError("incompatible_method_receiver", |
| 458 HandleVector(args, |
| 459 ARRAY_SIZE(args))); |
| 460 return isolate->Throw<Object>(error); |
| 461 } |
| 462 // TODO(rossberg): Support symbols in the API. |
| 463 if (name->IsSymbol()) return value; |
| 464 Object* call_obj = data->setter(); |
| 465 v8::AccessorSetterCallback call_fun = |
| 466 v8::ToCData<v8::AccessorSetterCallback>(call_obj); |
| 467 if (call_fun == NULL) return value; |
| 468 Handle<String> key = Handle<String>::cast(name); |
| 469 LOG(isolate, ApiNamedPropertyAccess("store", *holder, *name)); |
| 470 PropertyCallbackArguments args(isolate, data->data(), *receiver, *holder); |
| 471 args.Call(call_fun, |
| 472 v8::Utils::ToLocal(key), |
| 473 v8::Utils::ToLocal(value)); |
| 474 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); |
| 475 return value; |
| 476 } |
432 | 477 |
433 Handle<Object> args[] = { receiver, name }; | 478 if (structure->IsAccessorPair()) { |
434 return CallTrap( | 479 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); |
435 proxy, "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args); | 480 if (setter->IsSpecFunction()) { |
| 481 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 482 return SetPropertyWithDefinedSetter( |
| 483 receiver, Handle<JSReceiver>::cast(setter), value); |
| 484 } else { |
| 485 if (strict_mode == SLOPPY) return value; |
| 486 Handle<Object> args[2] = { name, holder }; |
| 487 Handle<Object> error = |
| 488 isolate->factory()->NewTypeError("no_setter_in_callback", |
| 489 HandleVector(args, 2)); |
| 490 return isolate->Throw<Object>(error); |
| 491 } |
| 492 } |
| 493 |
| 494 // TODO(dcarney): Handle correctly. |
| 495 if (structure->IsDeclaredAccessorInfo()) { |
| 496 return value; |
| 497 } |
| 498 |
| 499 UNREACHABLE(); |
| 500 return MaybeHandle<Object>(); |
436 } | 501 } |
437 | 502 |
438 | 503 |
439 MaybeHandle<Object> Object::GetPropertyWithDefinedGetter( | 504 MaybeHandle<Object> Object::GetPropertyWithDefinedGetter( |
440 Handle<Object> object, | |
441 Handle<Object> receiver, | 505 Handle<Object> receiver, |
442 Handle<JSReceiver> getter) { | 506 Handle<JSReceiver> getter) { |
443 Isolate* isolate = getter->GetIsolate(); | 507 Isolate* isolate = getter->GetIsolate(); |
444 Debug* debug = isolate->debug(); | 508 Debug* debug = isolate->debug(); |
445 // Handle stepping into a getter if step into is active. | 509 // Handle stepping into a getter if step into is active. |
446 // TODO(rossberg): should this apply to getters that are function proxies? | 510 // TODO(rossberg): should this apply to getters that are function proxies? |
447 if (debug->StepInActive() && getter->IsJSFunction()) { | 511 if (debug->StepInActive() && getter->IsJSFunction()) { |
448 debug->HandleStepIn( | 512 debug->HandleStepIn( |
449 Handle<JSFunction>::cast(getter), Handle<Object>::null(), 0, false); | 513 Handle<JSFunction>::cast(getter), Handle<Object>::null(), 0, false); |
450 } | 514 } |
451 | 515 |
452 return Execution::Call(isolate, getter, receiver, 0, NULL, true); | 516 return Execution::Call(isolate, getter, receiver, 0, NULL, true); |
453 } | 517 } |
454 | 518 |
455 | 519 |
| 520 MaybeHandle<Object> Object::SetPropertyWithDefinedSetter( |
| 521 Handle<Object> receiver, |
| 522 Handle<JSReceiver> setter, |
| 523 Handle<Object> value) { |
| 524 Isolate* isolate = setter->GetIsolate(); |
| 525 |
| 526 Debug* debug = isolate->debug(); |
| 527 // Handle stepping into a setter if step into is active. |
| 528 // TODO(rossberg): should this apply to getters that are function proxies? |
| 529 if (debug->StepInActive() && setter->IsJSFunction()) { |
| 530 debug->HandleStepIn( |
| 531 Handle<JSFunction>::cast(setter), Handle<Object>::null(), 0, false); |
| 532 } |
| 533 |
| 534 Handle<Object> argv[] = { value }; |
| 535 RETURN_ON_EXCEPTION( |
| 536 isolate, |
| 537 Execution::Call(isolate, setter, receiver, ARRAY_SIZE(argv), argv), |
| 538 Object); |
| 539 return value; |
| 540 } |
| 541 |
| 542 |
456 // Only deal with CALLBACKS and INTERCEPTOR | 543 // Only deal with CALLBACKS and INTERCEPTOR |
457 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( | 544 MaybeHandle<Object> JSObject::GetPropertyWithFailedAccessCheck( |
458 Handle<JSObject> object, | 545 Handle<JSObject> object, |
459 Handle<Object> receiver, | 546 Handle<Object> receiver, |
460 LookupResult* result, | 547 LookupResult* result, |
461 Handle<Name> name, | 548 Handle<Name> name, |
462 PropertyAttributes* attributes) { | 549 PropertyAttributes* attributes) { |
463 Isolate* isolate = name->GetIsolate(); | 550 Isolate* isolate = name->GetIsolate(); |
464 if (result->IsProperty()) { | 551 if (result->IsProperty()) { |
465 switch (result->type()) { | 552 switch (result->type()) { |
466 case CALLBACKS: { | 553 case CALLBACKS: { |
467 // Only allow API accessors. | 554 // Only allow API accessors. |
468 Handle<Object> callback_obj(result->GetCallbackObject(), isolate); | 555 Handle<Object> callback_obj(result->GetCallbackObject(), isolate); |
469 if (callback_obj->IsAccessorInfo()) { | 556 if (callback_obj->IsAccessorInfo()) { |
470 if (!AccessorInfo::cast(*callback_obj)->all_can_read()) break; | 557 if (!AccessorInfo::cast(*callback_obj)->all_can_read()) break; |
471 *attributes = result->GetAttributes(); | 558 *attributes = result->GetAttributes(); |
472 // Fall through to GetPropertyWithCallback. | 559 // Fall through to GetPropertyWithCallback. |
473 } else if (callback_obj->IsAccessorPair()) { | 560 } else if (callback_obj->IsAccessorPair()) { |
474 if (!AccessorPair::cast(*callback_obj)->all_can_read()) break; | 561 if (!AccessorPair::cast(*callback_obj)->all_can_read()) break; |
475 // Fall through to GetPropertyWithCallback. | 562 // Fall through to GetPropertyWithCallback. |
476 } else { | 563 } else { |
477 break; | 564 break; |
478 } | 565 } |
479 Handle<JSObject> holder(result->holder(), isolate); | 566 Handle<JSObject> holder(result->holder(), isolate); |
480 return GetPropertyWithCallback(holder, receiver, callback_obj, name); | 567 return GetPropertyWithCallback(receiver, name, holder, callback_obj); |
481 } | 568 } |
482 case NORMAL: | 569 case NORMAL: |
483 case FIELD: | 570 case FIELD: |
484 case CONSTANT: { | 571 case CONSTANT: { |
485 // Search ALL_CAN_READ accessors in prototype chain. | 572 // Search ALL_CAN_READ accessors in prototype chain. |
486 LookupResult r(isolate); | 573 LookupResult r(isolate); |
487 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); | 574 result->holder()->LookupRealNamedPropertyInPrototypes(name, &r); |
488 if (r.IsProperty()) { | 575 if (r.IsProperty()) { |
489 return GetPropertyWithFailedAccessCheck( | 576 return GetPropertyWithFailedAccessCheck( |
490 object, receiver, &r, name, attributes); | 577 object, receiver, &r, name, attributes); |
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
784 break; | 871 break; |
785 } | 872 } |
786 case FIELD: | 873 case FIELD: |
787 value = JSObject::FastPropertyAt(handle(result->holder(), isolate), | 874 value = JSObject::FastPropertyAt(handle(result->holder(), isolate), |
788 result->representation(), | 875 result->representation(), |
789 result->GetFieldIndex().field_index()); | 876 result->GetFieldIndex().field_index()); |
790 break; | 877 break; |
791 case CONSTANT: | 878 case CONSTANT: |
792 return handle(result->GetConstant(), isolate); | 879 return handle(result->GetConstant(), isolate); |
793 case CALLBACKS: | 880 case CALLBACKS: |
794 return JSObject::GetPropertyWithCallback( | 881 return GetPropertyWithCallback( |
795 handle(result->holder(), isolate), | 882 receiver, name, handle(result->holder(), isolate), |
796 receiver, | 883 handle(result->GetCallbackObject(), isolate)); |
797 handle(result->GetCallbackObject(), isolate), | |
798 name); | |
799 case HANDLER: | 884 case HANDLER: |
800 return JSProxy::GetPropertyWithHandler( | 885 return JSProxy::GetPropertyWithHandler( |
801 handle(result->proxy(), isolate), receiver, name); | 886 handle(result->proxy(), isolate), receiver, name); |
802 case INTERCEPTOR: | 887 case INTERCEPTOR: |
803 return JSObject::GetPropertyWithInterceptor( | 888 return JSObject::GetPropertyWithInterceptor( |
804 handle(result->holder(), isolate), receiver, name, attributes); | 889 handle(result->holder(), isolate), receiver, name, attributes); |
805 case NONEXISTENT: | 890 case NONEXISTENT: |
806 UNREACHABLE(); | 891 UNREACHABLE(); |
807 break; | 892 break; |
808 } | 893 } |
(...skipping 2189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2998 LookupResult result(object->GetIsolate()); | 3083 LookupResult result(object->GetIsolate()); |
2999 object->LookupOwn(name, &result, true); | 3084 object->LookupOwn(name, &result, true); |
3000 if (!result.IsFound()) { | 3085 if (!result.IsFound()) { |
3001 object->map()->LookupTransition(JSObject::cast(*object), *name, &result); | 3086 object->map()->LookupTransition(JSObject::cast(*object), *name, &result); |
3002 } | 3087 } |
3003 return SetProperty(object, &result, name, value, attributes, strict_mode, | 3088 return SetProperty(object, &result, name, value, attributes, strict_mode, |
3004 store_mode); | 3089 store_mode); |
3005 } | 3090 } |
3006 | 3091 |
3007 | 3092 |
3008 MaybeHandle<Object> JSObject::SetPropertyWithCallback(Handle<JSObject> object, | |
3009 Handle<Object> structure, | |
3010 Handle<Name> name, | |
3011 Handle<Object> value, | |
3012 Handle<JSObject> holder, | |
3013 StrictMode strict_mode) { | |
3014 Isolate* isolate = object->GetIsolate(); | |
3015 | |
3016 // We should never get here to initialize a const with the hole | |
3017 // value since a const declaration would conflict with the setter. | |
3018 ASSERT(!value->IsTheHole()); | |
3019 ASSERT(!structure->IsForeign()); | |
3020 if (structure->IsExecutableAccessorInfo()) { | |
3021 // api style callbacks | |
3022 ExecutableAccessorInfo* data = ExecutableAccessorInfo::cast(*structure); | |
3023 if (!data->IsCompatibleReceiver(*object)) { | |
3024 Handle<Object> args[2] = { name, object }; | |
3025 Handle<Object> error = | |
3026 isolate->factory()->NewTypeError("incompatible_method_receiver", | |
3027 HandleVector(args, | |
3028 ARRAY_SIZE(args))); | |
3029 return isolate->Throw<Object>(error); | |
3030 } | |
3031 // TODO(rossberg): Support symbols in the API. | |
3032 if (name->IsSymbol()) return value; | |
3033 Object* call_obj = data->setter(); | |
3034 v8::AccessorSetterCallback call_fun = | |
3035 v8::ToCData<v8::AccessorSetterCallback>(call_obj); | |
3036 if (call_fun == NULL) return value; | |
3037 Handle<String> key = Handle<String>::cast(name); | |
3038 LOG(isolate, ApiNamedPropertyAccess("store", *object, *name)); | |
3039 PropertyCallbackArguments args(isolate, data->data(), *object, *holder); | |
3040 args.Call(call_fun, | |
3041 v8::Utils::ToLocal(key), | |
3042 v8::Utils::ToLocal(value)); | |
3043 RETURN_EXCEPTION_IF_SCHEDULED_EXCEPTION(isolate, Object); | |
3044 return value; | |
3045 } | |
3046 | |
3047 if (structure->IsAccessorPair()) { | |
3048 Handle<Object> setter(AccessorPair::cast(*structure)->setter(), isolate); | |
3049 if (setter->IsSpecFunction()) { | |
3050 // TODO(rossberg): nicer would be to cast to some JSCallable here... | |
3051 return SetPropertyWithDefinedSetter( | |
3052 object, Handle<JSReceiver>::cast(setter), value); | |
3053 } else { | |
3054 if (strict_mode == SLOPPY) return value; | |
3055 Handle<Object> args[2] = { name, holder }; | |
3056 Handle<Object> error = | |
3057 isolate->factory()->NewTypeError("no_setter_in_callback", | |
3058 HandleVector(args, 2)); | |
3059 return isolate->Throw<Object>(error); | |
3060 } | |
3061 } | |
3062 | |
3063 // TODO(dcarney): Handle correctly. | |
3064 if (structure->IsDeclaredAccessorInfo()) { | |
3065 return value; | |
3066 } | |
3067 | |
3068 UNREACHABLE(); | |
3069 return MaybeHandle<Object>(); | |
3070 } | |
3071 | |
3072 | |
3073 MaybeHandle<Object> JSReceiver::SetPropertyWithDefinedSetter( | |
3074 Handle<JSReceiver> object, | |
3075 Handle<JSReceiver> setter, | |
3076 Handle<Object> value) { | |
3077 Isolate* isolate = object->GetIsolate(); | |
3078 | |
3079 Debug* debug = isolate->debug(); | |
3080 // Handle stepping into a setter if step into is active. | |
3081 // TODO(rossberg): should this apply to getters that are function proxies? | |
3082 if (debug->StepInActive() && setter->IsJSFunction()) { | |
3083 debug->HandleStepIn( | |
3084 Handle<JSFunction>::cast(setter), Handle<Object>::null(), 0, false); | |
3085 } | |
3086 | |
3087 Handle<Object> argv[] = { value }; | |
3088 RETURN_ON_EXCEPTION( | |
3089 isolate, | |
3090 Execution::Call(isolate, setter, object, ARRAY_SIZE(argv), argv), | |
3091 Object); | |
3092 return value; | |
3093 } | |
3094 | |
3095 | |
3096 MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( | 3093 MaybeHandle<Object> JSObject::SetElementWithCallbackSetterInPrototypes( |
3097 Handle<JSObject> object, | 3094 Handle<JSObject> object, |
3098 uint32_t index, | 3095 uint32_t index, |
3099 Handle<Object> value, | 3096 Handle<Object> value, |
3100 bool* found, | 3097 bool* found, |
3101 StrictMode strict_mode) { | 3098 StrictMode strict_mode) { |
3102 Isolate *isolate = object->GetIsolate(); | 3099 Isolate *isolate = object->GetIsolate(); |
3103 for (Handle<Object> proto = handle(object->GetPrototype(), isolate); | 3100 for (Handle<Object> proto = handle(object->GetPrototype(), isolate); |
3104 !proto->IsNull(); | 3101 !proto->IsNull(); |
3105 proto = handle(proto->GetPrototype(isolate), isolate)) { | 3102 proto = handle(proto->GetPrototype(isolate), isolate)) { |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3159 case INTERCEPTOR: { | 3156 case INTERCEPTOR: { |
3160 PropertyAttributes attr = GetPropertyAttributeWithInterceptor( | 3157 PropertyAttributes attr = GetPropertyAttributeWithInterceptor( |
3161 handle(result.holder()), object, name, true); | 3158 handle(result.holder()), object, name, true); |
3162 *done = !!(attr & READ_ONLY); | 3159 *done = !!(attr & READ_ONLY); |
3163 break; | 3160 break; |
3164 } | 3161 } |
3165 case CALLBACKS: { | 3162 case CALLBACKS: { |
3166 *done = true; | 3163 *done = true; |
3167 if (!result.IsReadOnly()) { | 3164 if (!result.IsReadOnly()) { |
3168 Handle<Object> callback_object(result.GetCallbackObject(), isolate); | 3165 Handle<Object> callback_object(result.GetCallbackObject(), isolate); |
3169 return SetPropertyWithCallback(object, callback_object, name, value, | 3166 return SetPropertyWithCallback(object, name, value, |
3170 handle(result.holder()), strict_mode); | 3167 handle(result.holder()), |
| 3168 callback_object, strict_mode); |
3171 } | 3169 } |
3172 break; | 3170 break; |
3173 } | 3171 } |
3174 case HANDLER: { | 3172 case HANDLER: { |
3175 Handle<JSProxy> proxy(result.proxy()); | 3173 Handle<JSProxy> proxy(result.proxy()); |
3176 return JSProxy::SetPropertyViaPrototypesWithHandler( | 3174 return JSProxy::SetPropertyViaPrototypesWithHandler( |
3177 proxy, object, name, value, attributes, strict_mode, done); | 3175 proxy, object, name, value, attributes, strict_mode, done); |
3178 } | 3176 } |
3179 case NONEXISTENT: | 3177 case NONEXISTENT: |
3180 UNREACHABLE(); | 3178 UNREACHABLE(); |
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3618 } | 3616 } |
3619 | 3617 |
3620 if (result->IsProperty()) { | 3618 if (result->IsProperty()) { |
3621 if (!result->IsReadOnly()) { | 3619 if (!result->IsReadOnly()) { |
3622 switch (result->type()) { | 3620 switch (result->type()) { |
3623 case CALLBACKS: { | 3621 case CALLBACKS: { |
3624 Object* obj = result->GetCallbackObject(); | 3622 Object* obj = result->GetCallbackObject(); |
3625 if (obj->IsAccessorInfo()) { | 3623 if (obj->IsAccessorInfo()) { |
3626 Handle<AccessorInfo> info(AccessorInfo::cast(obj)); | 3624 Handle<AccessorInfo> info(AccessorInfo::cast(obj)); |
3627 if (info->all_can_write()) { | 3625 if (info->all_can_write()) { |
3628 return SetPropertyWithCallback(object, | 3626 return SetPropertyWithCallback(object, name, value, |
3629 info, | |
3630 name, | |
3631 value, | |
3632 handle(result->holder()), | 3627 handle(result->holder()), |
3633 strict_mode); | 3628 info, strict_mode); |
3634 } | 3629 } |
3635 } else if (obj->IsAccessorPair()) { | 3630 } else if (obj->IsAccessorPair()) { |
3636 Handle<AccessorPair> pair(AccessorPair::cast(obj)); | 3631 Handle<AccessorPair> pair(AccessorPair::cast(obj)); |
3637 if (pair->all_can_read()) { | 3632 if (pair->all_can_read()) { |
3638 return SetPropertyWithCallback(object, | 3633 return SetPropertyWithCallback(object, name, value, |
3639 pair, | |
3640 name, | |
3641 value, | |
3642 handle(result->holder()), | 3634 handle(result->holder()), |
3643 strict_mode); | 3635 pair, strict_mode); |
3644 } | 3636 } |
3645 } | 3637 } |
3646 break; | 3638 break; |
3647 } | 3639 } |
3648 case INTERCEPTOR: { | 3640 case INTERCEPTOR: { |
3649 // Try lookup real named properties. Note that only property can be | 3641 // Try lookup real named properties. Note that only property can be |
3650 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. | 3642 // set is callbacks marked as ALL_CAN_WRITE on the prototype chain. |
3651 LookupResult r(object->GetIsolate()); | 3643 LookupResult r(object->GetIsolate()); |
3652 object->LookupRealNamedProperty(name, &r); | 3644 object->LookupRealNamedProperty(name, &r); |
3653 if (r.IsProperty()) { | 3645 if (r.IsProperty()) { |
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4293 case FIELD: | 4285 case FIELD: |
4294 SetPropertyToField(lookup, value); | 4286 SetPropertyToField(lookup, value); |
4295 break; | 4287 break; |
4296 case CONSTANT: | 4288 case CONSTANT: |
4297 // Only replace the constant if necessary. | 4289 // Only replace the constant if necessary. |
4298 if (*value == lookup->GetConstant()) return value; | 4290 if (*value == lookup->GetConstant()) return value; |
4299 SetPropertyToField(lookup, value); | 4291 SetPropertyToField(lookup, value); |
4300 break; | 4292 break; |
4301 case CALLBACKS: { | 4293 case CALLBACKS: { |
4302 Handle<Object> callback_object(lookup->GetCallbackObject(), isolate); | 4294 Handle<Object> callback_object(lookup->GetCallbackObject(), isolate); |
4303 return SetPropertyWithCallback(object, callback_object, name, value, | 4295 return SetPropertyWithCallback(object, name, value, |
4304 handle(lookup->holder()), strict_mode); | 4296 handle(lookup->holder()), |
| 4297 callback_object, strict_mode); |
4305 } | 4298 } |
4306 case INTERCEPTOR: | 4299 case INTERCEPTOR: |
4307 maybe_result = SetPropertyWithInterceptor( | 4300 maybe_result = SetPropertyWithInterceptor( |
4308 handle(lookup->holder()), name, value, attributes, strict_mode); | 4301 handle(lookup->holder()), name, value, attributes, strict_mode); |
4309 break; | 4302 break; |
4310 case HANDLER: | 4303 case HANDLER: |
4311 case NONEXISTENT: | 4304 case NONEXISTENT: |
4312 UNREACHABLE(); | 4305 UNREACHABLE(); |
4313 } | 4306 } |
4314 } | 4307 } |
(...skipping 8266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12581 return handle(*result_internal, isolate); | 12574 return handle(*result_internal, isolate); |
12582 } | 12575 } |
12583 | 12576 |
12584 // __defineGetter__ callback | 12577 // __defineGetter__ callback |
12585 if (structure->IsAccessorPair()) { | 12578 if (structure->IsAccessorPair()) { |
12586 Handle<Object> getter(Handle<AccessorPair>::cast(structure)->getter(), | 12579 Handle<Object> getter(Handle<AccessorPair>::cast(structure)->getter(), |
12587 isolate); | 12580 isolate); |
12588 if (getter->IsSpecFunction()) { | 12581 if (getter->IsSpecFunction()) { |
12589 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 12582 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
12590 return GetPropertyWithDefinedGetter( | 12583 return GetPropertyWithDefinedGetter( |
12591 object, receiver, Handle<JSReceiver>::cast(getter)); | 12584 receiver, Handle<JSReceiver>::cast(getter)); |
12592 } | 12585 } |
12593 // Getter is not a function. | 12586 // Getter is not a function. |
12594 return isolate->factory()->undefined_value(); | 12587 return isolate->factory()->undefined_value(); |
12595 } | 12588 } |
12596 | 12589 |
12597 if (structure->IsDeclaredAccessorInfo()) { | 12590 if (structure->IsDeclaredAccessorInfo()) { |
12598 return GetDeclaredAccessorProperty( | 12591 return GetDeclaredAccessorProperty( |
12599 receiver, Handle<DeclaredAccessorInfo>::cast(structure), isolate); | 12592 receiver, Handle<DeclaredAccessorInfo>::cast(structure), isolate); |
12600 } | 12593 } |
12601 | 12594 |
(...skipping 4667 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
17269 #define ERROR_MESSAGES_TEXTS(C, T) T, | 17262 #define ERROR_MESSAGES_TEXTS(C, T) T, |
17270 static const char* error_messages_[] = { | 17263 static const char* error_messages_[] = { |
17271 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 17264 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
17272 }; | 17265 }; |
17273 #undef ERROR_MESSAGES_TEXTS | 17266 #undef ERROR_MESSAGES_TEXTS |
17274 return error_messages_[reason]; | 17267 return error_messages_[reason]; |
17275 } | 17268 } |
17276 | 17269 |
17277 | 17270 |
17278 } } // namespace v8::internal | 17271 } } // namespace v8::internal |
OLD | NEW |