| 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 |