OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 PropertyAttributes* attributes) { | 163 PropertyAttributes* attributes) { |
164 LookupResult lookup(name->GetIsolate()); | 164 LookupResult lookup(name->GetIsolate()); |
165 object->Lookup(*name, &lookup); | 165 object->Lookup(*name, &lookup); |
166 MaybeHandle<Object> result = | 166 MaybeHandle<Object> result = |
167 GetProperty(object, receiver, &lookup, name, attributes); | 167 GetProperty(object, receiver, &lookup, name, attributes); |
168 ASSERT(*attributes <= ABSENT); | 168 ASSERT(*attributes <= ABSENT); |
169 return result; | 169 return result; |
170 } | 170 } |
171 | 171 |
172 | 172 |
173 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, | |
174 Name* name, | |
175 PropertyAttributes* attributes) { | |
176 LookupResult result(name->GetIsolate()); | |
177 Lookup(name, &result); | |
178 MaybeObject* value = GetProperty(receiver, &result, name, attributes); | |
179 ASSERT(*attributes <= ABSENT); | |
180 return value; | |
181 } | |
182 | |
183 | |
184 bool Object::ToInt32(int32_t* value) { | 173 bool Object::ToInt32(int32_t* value) { |
185 if (IsSmi()) { | 174 if (IsSmi()) { |
186 *value = Smi::cast(this)->value(); | 175 *value = Smi::cast(this)->value(); |
187 return true; | 176 return true; |
188 } | 177 } |
189 if (IsHeapNumber()) { | 178 if (IsHeapNumber()) { |
190 double num = HeapNumber::cast(this)->value(); | 179 double num = HeapNumber::cast(this)->value(); |
191 if (FastI2D(FastD2I(num)) == num) { | 180 if (FastI2D(FastD2I(num)) == num) { |
192 *value = FastD2I(num); | 181 *value = FastD2I(num); |
193 return true; | 182 return true; |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 if (getter->IsSpecFunction()) { | 456 if (getter->IsSpecFunction()) { |
468 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 457 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
469 return Object::GetPropertyWithDefinedGetter( | 458 return Object::GetPropertyWithDefinedGetter( |
470 object, receiver, Handle<JSReceiver>::cast(getter)); | 459 object, receiver, Handle<JSReceiver>::cast(getter)); |
471 } | 460 } |
472 // Getter is not a function. | 461 // Getter is not a function. |
473 return isolate->factory()->undefined_value(); | 462 return isolate->factory()->undefined_value(); |
474 } | 463 } |
475 | 464 |
476 | 465 |
477 MaybeObject* JSProxy::GetPropertyWithHandler(Object* receiver_raw, | 466 MaybeHandle<Object> JSProxy::GetPropertyWithHandler(Handle<JSProxy> proxy, |
478 Name* name_raw) { | 467 Handle<Object> receiver, |
479 Isolate* isolate = GetIsolate(); | 468 Handle<Name> name) { |
480 HandleScope scope(isolate); | 469 Isolate* isolate = proxy->GetIsolate(); |
481 Handle<Object> receiver(receiver_raw, isolate); | |
482 Handle<Object> name(name_raw, isolate); | |
483 | 470 |
484 // TODO(rossberg): adjust once there is a story for symbols vs proxies. | 471 // TODO(rossberg): adjust once there is a story for symbols vs proxies. |
485 if (name->IsSymbol()) return isolate->heap()->undefined_value(); | 472 if (name->IsSymbol()) return isolate->factory()->undefined_value(); |
486 | 473 |
487 Handle<Object> args[] = { receiver, name }; | 474 Handle<Object> args[] = { receiver, name }; |
488 Handle<Object> result; | 475 return CallTrap( |
489 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 476 proxy, "get", isolate->derived_get_trap(), ARRAY_SIZE(args), args); |
490 isolate, result, | |
491 CallTrap(handle(this), | |
492 "get", | |
493 isolate->derived_get_trap(), | |
494 ARRAY_SIZE(args), | |
495 args)); | |
496 return *result; | |
497 } | 477 } |
498 | 478 |
499 | 479 |
500 MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> object, | |
501 Handle<Name> name) { | |
502 uint32_t index; | |
503 Isolate* isolate = name->GetIsolate(); | |
504 if (name->AsArrayIndex(&index)) return GetElement(isolate, object, index); | |
505 return GetProperty(object, name); | |
506 } | |
507 | |
508 | |
509 Handle<Object> Object::GetProperty(Handle<Object> object, | |
510 Handle<Name> name) { | |
511 CALL_HEAP_FUNCTION(name->GetIsolate(), object->GetProperty(*name), Object); | |
512 } | |
513 | |
514 | |
515 MaybeObject* JSProxy::GetElementWithHandler(Object* receiver, | |
516 uint32_t index) { | |
517 String* name; | |
518 MaybeObject* maybe = GetHeap()->Uint32ToString(index); | |
519 if (!maybe->To<String>(&name)) return maybe; | |
520 return GetPropertyWithHandler(receiver, name); | |
521 } | |
522 | |
523 | |
524 MaybeHandle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy, | |
525 Handle<JSReceiver> receiver, | |
526 uint32_t index, | |
527 Handle<Object> value, | |
528 StrictMode strict_mode) { | |
529 Isolate* isolate = proxy->GetIsolate(); | |
530 Handle<String> name = isolate->factory()->Uint32ToString(index); | |
531 return SetPropertyWithHandler( | |
532 proxy, receiver, name, value, NONE, strict_mode); | |
533 } | |
534 | |
535 | |
536 bool JSProxy::HasElementWithHandler(Handle<JSProxy> proxy, uint32_t index) { | |
537 Isolate* isolate = proxy->GetIsolate(); | |
538 Handle<String> name = isolate->factory()->Uint32ToString(index); | |
539 return HasPropertyWithHandler(proxy, name); | |
540 } | |
541 | |
542 | |
543 MaybeHandle<Object> Object::GetPropertyWithDefinedGetter( | 480 MaybeHandle<Object> Object::GetPropertyWithDefinedGetter( |
544 Handle<Object> object, | 481 Handle<Object> object, |
545 Handle<Object> receiver, | 482 Handle<Object> receiver, |
546 Handle<JSReceiver> getter) { | 483 Handle<JSReceiver> getter) { |
547 Isolate* isolate = getter->GetIsolate(); | 484 Isolate* isolate = getter->GetIsolate(); |
548 #ifdef ENABLE_DEBUGGER_SUPPORT | 485 #ifdef ENABLE_DEBUGGER_SUPPORT |
549 Debug* debug = isolate->debug(); | 486 Debug* debug = isolate->debug(); |
550 // Handle stepping into a getter if step into is active. | 487 // Handle stepping into a getter if step into is active. |
551 // TODO(rossberg): should this apply to getters that are function proxies? | 488 // TODO(rossberg): should this apply to getters that are function proxies? |
552 if (debug->StepInActive() && getter->IsJSFunction()) { | 489 if (debug->StepInActive() && getter->IsJSFunction()) { |
(...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
829 // created with then no changes can have been made to it. | 766 // created with then no changes can have been made to it. |
830 return map() != fun->initial_map() | 767 return map() != fun->initial_map() |
831 || !HasFastObjectElements() | 768 || !HasFastObjectElements() |
832 || !HasFastProperties(); | 769 || !HasFastProperties(); |
833 } | 770 } |
834 | 771 |
835 | 772 |
836 MaybeHandle<Object> Object::GetProperty(Handle<Object> object, | 773 MaybeHandle<Object> Object::GetProperty(Handle<Object> object, |
837 Handle<Object> receiver, | 774 Handle<Object> receiver, |
838 LookupResult* result, | 775 LookupResult* result, |
839 Handle<Name> key, | 776 Handle<Name> name, |
840 PropertyAttributes* attributes) { | 777 PropertyAttributes* attributes) { |
841 Isolate* isolate = result->isolate(); | |
842 CALL_HEAP_FUNCTION( | |
843 isolate, | |
844 object->GetProperty(*receiver, result, *key, attributes), | |
845 Object); | |
846 } | |
847 | |
848 | |
849 // TODO(yangguo): handlify this and get rid of. | |
850 MaybeObject* Object::GetProperty(Object* receiver, | |
851 LookupResult* result, | |
852 Name* name, | |
853 PropertyAttributes* attributes) { | |
854 Isolate* isolate = name->GetIsolate(); | 778 Isolate* isolate = name->GetIsolate(); |
855 Heap* heap = isolate->heap(); | 779 Factory* factory = isolate->factory(); |
856 | |
857 #ifdef DEBUG | |
858 // TODO(mstarzinger): Only because of the AssertNoContextChange, drop as soon | |
859 // as this method has been fully handlified. | |
860 HandleScope scope(isolate); | |
861 #endif | |
862 | 780 |
863 // Make sure that the top context does not change when doing | 781 // Make sure that the top context does not change when doing |
864 // callbacks or interceptor calls. | 782 // callbacks or interceptor calls. |
865 AssertNoContextChange ncc(isolate); | 783 AssertNoContextChange ncc(isolate); |
866 | 784 |
867 // Traverse the prototype chain from the current object (this) to | 785 // Traverse the prototype chain from the current object (this) to |
868 // the holder and check for access rights. This avoids traversing the | 786 // the holder and check for access rights. This avoids traversing the |
869 // objects more than once in case of interceptors, because the | 787 // objects more than once in case of interceptors, because the |
870 // holder will always be the interceptor holder and the search may | 788 // holder will always be the interceptor holder and the search may |
871 // only continue with a current object just after the interceptor | 789 // only continue with a current object just after the interceptor |
872 // holder in the prototype chain. | 790 // holder in the prototype chain. |
873 // Proxy handlers do not use the proxy's prototype, so we can skip this. | 791 // Proxy handlers do not use the proxy's prototype, so we can skip this. |
874 if (!result->IsHandler()) { | 792 if (!result->IsHandler()) { |
875 Object* last = result->IsProperty() | 793 ASSERT(*object != object->GetPrototype(isolate)); |
876 ? result->holder() | 794 Handle<Object> last = result->IsProperty() |
877 : Object::cast(heap->null_value()); | 795 ? Handle<Object>(result->holder(), isolate) |
878 ASSERT(this != this->GetPrototype(isolate)); | 796 : Handle<Object>::cast(factory->null_value()); |
879 for (Object* current = this; | 797 for (Handle<Object> current = object; |
880 true; | 798 true; |
881 current = current->GetPrototype(isolate)) { | 799 current = Handle<Object>(current->GetPrototype(isolate), isolate)) { |
882 if (current->IsAccessCheckNeeded()) { | 800 if (current->IsAccessCheckNeeded()) { |
883 // Check if we're allowed to read from the current object. Note | 801 // Check if we're allowed to read from the current object. Note |
884 // that even though we may not actually end up loading the named | 802 // that even though we may not actually end up loading the named |
885 // property from the current object, we still check that we have | 803 // property from the current object, we still check that we have |
886 // access to it. | 804 // access to it. |
887 JSObject* checked = JSObject::cast(current); | 805 Handle<JSObject> checked = Handle<JSObject>::cast(current); |
888 if (!isolate->MayNamedAccess(checked, name, v8::ACCESS_GET)) { | 806 if (!isolate->MayNamedAccessWrapper(checked, name, v8::ACCESS_GET)) { |
889 HandleScope scope(isolate); | 807 return JSObject::GetPropertyWithFailedAccessCheck( |
890 Handle<Object> value; | 808 checked, receiver, result, name, attributes); |
891 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
892 isolate, value, | |
893 JSObject::GetPropertyWithFailedAccessCheck( | |
894 handle(checked, isolate), | |
895 handle(receiver, isolate), | |
896 result, | |
897 handle(name, isolate), | |
898 attributes)); | |
899 return *value; | |
900 } | 809 } |
901 } | 810 } |
902 // Stop traversing the chain once we reach the last object in the | 811 // Stop traversing the chain once we reach the last object in the |
903 // chain; either the holder of the result or null in case of an | 812 // chain; either the holder of the result or null in case of an |
904 // absent property. | 813 // absent property. |
905 if (current == last) break; | 814 if (current.is_identical_to(last)) break; |
906 } | 815 } |
907 } | 816 } |
908 | 817 |
909 if (!result->IsProperty()) { | 818 if (!result->IsProperty()) { |
910 *attributes = ABSENT; | 819 *attributes = ABSENT; |
911 return heap->undefined_value(); | 820 return factory->undefined_value(); |
912 } | 821 } |
913 *attributes = result->GetAttributes(); | 822 *attributes = result->GetAttributes(); |
914 Object* value; | 823 |
| 824 Handle<Object> value; |
| 825 Handle<JSObject> holder(result->holder(), isolate); |
915 switch (result->type()) { | 826 switch (result->type()) { |
916 case NORMAL: | 827 case NORMAL: { |
917 value = result->holder()->GetNormalizedProperty(result); | 828 DisallowHeapAllocation no_gc; |
918 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 829 value = handle(holder->GetNormalizedProperty(result), isolate); |
919 return value->IsTheHole() ? heap->undefined_value() : value; | 830 break; |
920 case FIELD: { | |
921 MaybeObject* maybe_result = result->holder()->FastPropertyAt( | |
922 result->representation(), | |
923 result->GetFieldIndex().field_index()); | |
924 if (!maybe_result->To(&value)) return maybe_result; | |
925 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | |
926 return value->IsTheHole() ? heap->undefined_value() : value; | |
927 } | 831 } |
| 832 case FIELD: |
| 833 value = JSObject::FastPropertyAt(holder, |
| 834 result->representation(), |
| 835 result->GetFieldIndex().field_index()); |
| 836 break; |
928 case CONSTANT: | 837 case CONSTANT: |
929 return result->GetConstant(); | 838 return handle(result->GetConstant(), isolate); |
930 case CALLBACKS: { | 839 case CALLBACKS: |
931 HandleScope scope(isolate); | 840 return JSObject::GetPropertyWithCallback( |
932 Handle<Object> value; | 841 holder, receiver, handle(result->GetCallbackObject(), isolate), name); |
933 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
934 isolate, value, | |
935 JSObject::GetPropertyWithCallback( | |
936 handle(result->holder(), isolate), | |
937 handle(receiver, isolate), | |
938 handle(result->GetCallbackObject(), isolate), | |
939 handle(name, isolate))); | |
940 return *value; | |
941 } | |
942 case HANDLER: | 842 case HANDLER: |
943 return result->proxy()->GetPropertyWithHandler(receiver, name); | 843 return JSProxy::GetPropertyWithHandler( |
944 case INTERCEPTOR: { | 844 handle(result->proxy(), isolate), receiver, name); |
945 HandleScope scope(isolate); | 845 case INTERCEPTOR: |
946 Handle<Object> value; | 846 return JSObject::GetPropertyWithInterceptor( |
947 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 847 holder, receiver, name, attributes); |
948 isolate, value, | |
949 JSObject::GetPropertyWithInterceptor( | |
950 handle(result->holder(), isolate), | |
951 handle(receiver, isolate), | |
952 handle(name, isolate), | |
953 attributes)); | |
954 return *value; | |
955 } | |
956 case NONEXISTENT: | 848 case NONEXISTENT: |
957 UNREACHABLE(); | 849 UNREACHABLE(); |
958 break; | 850 break; |
959 } | 851 } |
960 UNREACHABLE(); | 852 ASSERT(!value->IsTheHole() || result->IsReadOnly()); |
961 return NULL; | 853 return value->IsTheHole() ? Handle<Object>::cast(factory->undefined_value()) |
| 854 : value; |
962 } | 855 } |
963 | 856 |
964 | 857 |
965 MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate, | 858 MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate, |
966 Handle<Object> object, | 859 Handle<Object> object, |
967 Handle<Object> receiver, | 860 Handle<Object> receiver, |
968 uint32_t index) { | 861 uint32_t index) { |
969 Handle<Object> holder; | 862 Handle<Object> holder; |
970 | 863 |
971 // Iterate up the prototype chain until an element is found or the null | 864 // Iterate up the prototype chain until an element is found or the null |
972 // prototype is encountered. | 865 // prototype is encountered. |
973 for (holder = object; | 866 for (holder = object; |
974 !holder->IsNull(); | 867 !holder->IsNull(); |
975 holder = Handle<Object>(holder->GetPrototype(isolate), isolate)) { | 868 holder = Handle<Object>(holder->GetPrototype(isolate), isolate)) { |
976 if (!holder->IsJSObject()) { | 869 if (!holder->IsJSObject()) { |
977 Context* native_context = isolate->context()->native_context(); | 870 Context* native_context = isolate->context()->native_context(); |
978 if (holder->IsNumber()) { | 871 if (holder->IsNumber()) { |
979 holder = Handle<Object>( | 872 holder = Handle<Object>( |
980 native_context->number_function()->instance_prototype(), isolate); | 873 native_context->number_function()->instance_prototype(), isolate); |
981 } else if (holder->IsString()) { | 874 } else if (holder->IsString()) { |
982 holder = Handle<Object>( | 875 holder = Handle<Object>( |
983 native_context->string_function()->instance_prototype(), isolate); | 876 native_context->string_function()->instance_prototype(), isolate); |
984 } else if (holder->IsSymbol()) { | 877 } else if (holder->IsSymbol()) { |
985 holder = Handle<Object>( | 878 holder = Handle<Object>( |
986 native_context->symbol_function()->instance_prototype(), isolate); | 879 native_context->symbol_function()->instance_prototype(), isolate); |
987 } else if (holder->IsBoolean()) { | 880 } else if (holder->IsBoolean()) { |
988 holder = Handle<Object>( | 881 holder = Handle<Object>( |
989 native_context->boolean_function()->instance_prototype(), isolate); | 882 native_context->boolean_function()->instance_prototype(), isolate); |
990 } else if (holder->IsJSProxy()) { | 883 } else if (holder->IsJSProxy()) { |
991 CALL_HEAP_FUNCTION(isolate, | 884 return JSProxy::GetElementWithHandler( |
992 Handle<JSProxy>::cast(holder)->GetElementWithHandler( | 885 Handle<JSProxy>::cast(holder), receiver, index); |
993 *receiver, index), | |
994 Object); | |
995 } else { | 886 } else { |
996 // Undefined and null have no indexed properties. | 887 // Undefined and null have no indexed properties. |
997 ASSERT(holder->IsUndefined() || holder->IsNull()); | 888 ASSERT(holder->IsUndefined() || holder->IsNull()); |
998 return isolate->factory()->undefined_value(); | 889 return isolate->factory()->undefined_value(); |
999 } | 890 } |
1000 } | 891 } |
1001 | 892 |
1002 // Inline the case for JSObjects. Doing so significantly improves the | 893 // Inline the case for JSObjects. Doing so significantly improves the |
1003 // performance of fetching elements where checking the prototype chain is | 894 // performance of fetching elements where checking the prototype chain is |
1004 // necessary. | 895 // necessary. |
(...skipping 2610 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3615 isolate->to_complete_property_descriptor(), | 3506 isolate->to_complete_property_descriptor(), |
3616 result, | 3507 result, |
3617 ARRAY_SIZE(argv), | 3508 ARRAY_SIZE(argv), |
3618 argv), | 3509 argv), |
3619 Object); | 3510 Object); |
3620 | 3511 |
3621 // [[GetProperty]] requires to check that all properties are configurable. | 3512 // [[GetProperty]] requires to check that all properties are configurable. |
3622 Handle<String> configurable_name = | 3513 Handle<String> configurable_name = |
3623 isolate->factory()->InternalizeOneByteString( | 3514 isolate->factory()->InternalizeOneByteString( |
3624 STATIC_ASCII_VECTOR("configurable_")); | 3515 STATIC_ASCII_VECTOR("configurable_")); |
3625 Handle<Object> configurable = Object::GetProperty(desc, configurable_name); | 3516 Handle<Object> configurable = |
3626 ASSERT(!configurable.is_null()); | 3517 Object::GetProperty(desc, configurable_name).ToHandleChecked(); |
3627 ASSERT(configurable->IsTrue() || configurable->IsFalse()); | 3518 ASSERT(configurable->IsBoolean()); |
3628 if (configurable->IsFalse()) { | 3519 if (configurable->IsFalse()) { |
3629 Handle<String> trap = | 3520 Handle<String> trap = |
3630 isolate->factory()->InternalizeOneByteString( | 3521 isolate->factory()->InternalizeOneByteString( |
3631 STATIC_ASCII_VECTOR("getPropertyDescriptor")); | 3522 STATIC_ASCII_VECTOR("getPropertyDescriptor")); |
3632 Handle<Object> args[] = { handler, trap, name }; | 3523 Handle<Object> args[] = { handler, trap, name }; |
3633 Handle<Object> error = isolate->factory()->NewTypeError( | 3524 Handle<Object> error = isolate->factory()->NewTypeError( |
3634 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); | 3525 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); |
3635 return isolate->Throw<Object>(error); | 3526 return isolate->Throw<Object>(error); |
3636 } | 3527 } |
3637 ASSERT(configurable->IsTrue()); | 3528 ASSERT(configurable->IsTrue()); |
3638 | 3529 |
3639 // Check for DataDescriptor. | 3530 // Check for DataDescriptor. |
3640 Handle<String> hasWritable_name = | 3531 Handle<String> hasWritable_name = |
3641 isolate->factory()->InternalizeOneByteString( | 3532 isolate->factory()->InternalizeOneByteString( |
3642 STATIC_ASCII_VECTOR("hasWritable_")); | 3533 STATIC_ASCII_VECTOR("hasWritable_")); |
3643 Handle<Object> hasWritable = Object::GetProperty(desc, hasWritable_name); | 3534 Handle<Object> hasWritable = |
3644 ASSERT(!hasWritable.is_null()); | 3535 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); |
3645 ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse()); | 3536 ASSERT(hasWritable->IsBoolean()); |
3646 if (hasWritable->IsTrue()) { | 3537 if (hasWritable->IsTrue()) { |
3647 Handle<String> writable_name = | 3538 Handle<String> writable_name = |
3648 isolate->factory()->InternalizeOneByteString( | 3539 isolate->factory()->InternalizeOneByteString( |
3649 STATIC_ASCII_VECTOR("writable_")); | 3540 STATIC_ASCII_VECTOR("writable_")); |
3650 Handle<Object> writable = Object::GetProperty(desc, writable_name); | 3541 Handle<Object> writable = |
3651 ASSERT(!writable.is_null()); | 3542 Object::GetProperty(desc, writable_name).ToHandleChecked(); |
3652 ASSERT(writable->IsTrue() || writable->IsFalse()); | 3543 ASSERT(writable->IsBoolean()); |
3653 *done = writable->IsFalse(); | 3544 *done = writable->IsFalse(); |
3654 if (!*done) return isolate->factory()->the_hole_value(); | 3545 if (!*done) return isolate->factory()->the_hole_value(); |
3655 if (strict_mode == SLOPPY) return value; | 3546 if (strict_mode == SLOPPY) return value; |
3656 Handle<Object> args[] = { name, receiver }; | 3547 Handle<Object> args[] = { name, receiver }; |
3657 Handle<Object> error = isolate->factory()->NewTypeError( | 3548 Handle<Object> error = isolate->factory()->NewTypeError( |
3658 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | 3549 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); |
3659 return isolate->Throw<Object>(error); | 3550 return isolate->Throw<Object>(error); |
3660 } | 3551 } |
3661 | 3552 |
3662 // We have an AccessorDescriptor. | 3553 // We have an AccessorDescriptor. |
3663 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( | 3554 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( |
3664 STATIC_ASCII_VECTOR("set_")); | 3555 STATIC_ASCII_VECTOR("set_")); |
3665 Handle<Object> setter = Object::GetProperty(desc, set_name); | 3556 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); |
3666 ASSERT(!setter.is_null()); | |
3667 if (!setter->IsUndefined()) { | 3557 if (!setter->IsUndefined()) { |
3668 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 3558 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
3669 return SetPropertyWithDefinedSetter( | 3559 return SetPropertyWithDefinedSetter( |
3670 receiver, Handle<JSReceiver>::cast(setter), value); | 3560 receiver, Handle<JSReceiver>::cast(setter), value); |
3671 } | 3561 } |
3672 | 3562 |
3673 if (strict_mode == SLOPPY) return value; | 3563 if (strict_mode == SLOPPY) return value; |
3674 Handle<Object> args2[] = { name, proxy }; | 3564 Handle<Object> args2[] = { name, proxy }; |
3675 Handle<Object> error = isolate->factory()->NewTypeError( | 3565 Handle<Object> error = isolate->factory()->NewTypeError( |
3676 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); | 3566 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3748 Execution::Call(isolate, | 3638 Execution::Call(isolate, |
3749 isolate->to_complete_property_descriptor(), | 3639 isolate->to_complete_property_descriptor(), |
3750 result, | 3640 result, |
3751 ARRAY_SIZE(argv), | 3641 ARRAY_SIZE(argv), |
3752 argv), | 3642 argv), |
3753 NONE); | 3643 NONE); |
3754 | 3644 |
3755 // Convert result to PropertyAttributes. | 3645 // Convert result to PropertyAttributes. |
3756 Handle<String> enum_n = isolate->factory()->InternalizeOneByteString( | 3646 Handle<String> enum_n = isolate->factory()->InternalizeOneByteString( |
3757 STATIC_ASCII_VECTOR("enumerable_")); | 3647 STATIC_ASCII_VECTOR("enumerable_")); |
3758 Handle<Object> enumerable = Object::GetProperty(desc, enum_n); | 3648 Handle<Object> enumerable; |
3759 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, enumerable, NONE); | 3649 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 3650 isolate, enumerable, Object::GetProperty(desc, enum_n), NONE); |
3760 Handle<String> conf_n = isolate->factory()->InternalizeOneByteString( | 3651 Handle<String> conf_n = isolate->factory()->InternalizeOneByteString( |
3761 STATIC_ASCII_VECTOR("configurable_")); | 3652 STATIC_ASCII_VECTOR("configurable_")); |
3762 Handle<Object> configurable = Object::GetProperty(desc, conf_n); | 3653 Handle<Object> configurable; |
3763 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, configurable, NONE); | 3654 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 3655 isolate, configurable, Object::GetProperty(desc, conf_n), NONE); |
3764 Handle<String> writ_n = isolate->factory()->InternalizeOneByteString( | 3656 Handle<String> writ_n = isolate->factory()->InternalizeOneByteString( |
3765 STATIC_ASCII_VECTOR("writable_")); | 3657 STATIC_ASCII_VECTOR("writable_")); |
3766 Handle<Object> writable = Object::GetProperty(desc, writ_n); | 3658 Handle<Object> writable; |
3767 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, writable, NONE); | 3659 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 3660 isolate, writable, Object::GetProperty(desc, writ_n), NONE); |
3768 if (!writable->BooleanValue()) { | 3661 if (!writable->BooleanValue()) { |
3769 Handle<String> set_n = isolate->factory()->InternalizeOneByteString( | 3662 Handle<String> set_n = isolate->factory()->InternalizeOneByteString( |
3770 STATIC_ASCII_VECTOR("set_")); | 3663 STATIC_ASCII_VECTOR("set_")); |
3771 Handle<Object> setter = Object::GetProperty(desc, set_n); | 3664 Handle<Object> setter; |
3772 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, setter, NONE); | 3665 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 3666 isolate, setter, Object::GetProperty(desc, set_n), NONE); |
3773 writable = isolate->factory()->ToBoolean(!setter->IsUndefined()); | 3667 writable = isolate->factory()->ToBoolean(!setter->IsUndefined()); |
3774 } | 3668 } |
3775 | 3669 |
3776 if (configurable->IsFalse()) { | 3670 if (configurable->IsFalse()) { |
3777 Handle<Object> handler(proxy->handler(), isolate); | 3671 Handle<Object> handler(proxy->handler(), isolate); |
3778 Handle<String> trap = isolate->factory()->InternalizeOneByteString( | 3672 Handle<String> trap = isolate->factory()->InternalizeOneByteString( |
3779 STATIC_ASCII_VECTOR("getPropertyDescriptor")); | 3673 STATIC_ASCII_VECTOR("getPropertyDescriptor")); |
3780 Handle<Object> args[] = { handler, trap, name }; | 3674 Handle<Object> args[] = { handler, trap, name }; |
3781 Handle<Object> error = isolate->factory()->NewTypeError( | 3675 Handle<Object> error = isolate->factory()->NewTypeError( |
3782 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); | 3676 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); |
(...skipping 1430 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5213 } | 5107 } |
5214 | 5108 |
5215 Handle<Object> old_value; | 5109 Handle<Object> old_value; |
5216 bool should_enqueue_change_record = false; | 5110 bool should_enqueue_change_record = false; |
5217 if (object->map()->is_observed()) { | 5111 if (object->map()->is_observed()) { |
5218 should_enqueue_change_record = HasLocalElement(object, index); | 5112 should_enqueue_change_record = HasLocalElement(object, index); |
5219 if (should_enqueue_change_record) { | 5113 if (should_enqueue_change_record) { |
5220 if (!GetLocalElementAccessorPair(object, index).is_null()) { | 5114 if (!GetLocalElementAccessorPair(object, index).is_null()) { |
5221 old_value = Handle<Object>::cast(factory->the_hole_value()); | 5115 old_value = Handle<Object>::cast(factory->the_hole_value()); |
5222 } else { | 5116 } else { |
5223 old_value = Object::GetElementNoExceptionThrown(isolate, object, index); | 5117 old_value = Object::GetElement( |
| 5118 isolate, object, index).ToHandleChecked(); |
5224 } | 5119 } |
5225 } | 5120 } |
5226 } | 5121 } |
5227 | 5122 |
5228 // Skip interceptor if forcing deletion. | 5123 // Skip interceptor if forcing deletion. |
5229 MaybeHandle<Object> maybe_result; | 5124 MaybeHandle<Object> maybe_result; |
5230 if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) { | 5125 if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) { |
5231 maybe_result = DeleteElementWithInterceptor(object, index); | 5126 maybe_result = DeleteElementWithInterceptor(object, index); |
5232 } else { | 5127 } else { |
5233 maybe_result = object->GetElementsAccessor()->Delete(object, index, mode); | 5128 maybe_result = object->GetElementsAccessor()->Delete(object, index, mode); |
(...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5814 copy->GetLocalPropertyNames(*names, 0); | 5709 copy->GetLocalPropertyNames(*names, 0); |
5815 for (int i = 0; i < names->length(); i++) { | 5710 for (int i = 0; i < names->length(); i++) { |
5816 ASSERT(names->get(i)->IsString()); | 5711 ASSERT(names->get(i)->IsString()); |
5817 Handle<String> key_string(String::cast(names->get(i))); | 5712 Handle<String> key_string(String::cast(names->get(i))); |
5818 PropertyAttributes attributes = | 5713 PropertyAttributes attributes = |
5819 JSReceiver::GetLocalPropertyAttribute(copy, key_string); | 5714 JSReceiver::GetLocalPropertyAttribute(copy, key_string); |
5820 // Only deep copy fields from the object literal expression. | 5715 // Only deep copy fields from the object literal expression. |
5821 // In particular, don't try to copy the length attribute of | 5716 // In particular, don't try to copy the length attribute of |
5822 // an array. | 5717 // an array. |
5823 if (attributes != NONE) continue; | 5718 if (attributes != NONE) continue; |
5824 Handle<Object> value = Object::GetProperty(copy, key_string); | 5719 Handle<Object> value = |
5825 CHECK_NOT_EMPTY_HANDLE(isolate, value); | 5720 Object::GetProperty(copy, key_string).ToHandleChecked(); |
5826 if (value->IsJSObject()) { | 5721 if (value->IsJSObject()) { |
5827 Handle<JSObject> result = VisitElementOrProperty( | 5722 Handle<JSObject> result = VisitElementOrProperty( |
5828 copy, Handle<JSObject>::cast(value)); | 5723 copy, Handle<JSObject>::cast(value)); |
5829 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5724 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
5830 if (copying) { | 5725 if (copying) { |
5831 // Creating object copy for literals. No strict mode needed. | 5726 // Creating object copy for literals. No strict mode needed. |
5832 JSObject::SetProperty( | 5727 JSObject::SetProperty( |
5833 copy, key_string, result, NONE, SLOPPY).Assert(); | 5728 copy, key_string, result, NONE, SLOPPY).Assert(); |
5834 } | 5729 } |
5835 } | 5730 } |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6378 bool is_element = name->AsArrayIndex(&index); | 6273 bool is_element = name->AsArrayIndex(&index); |
6379 | 6274 |
6380 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 6275 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
6381 bool is_observed = object->map()->is_observed() && | 6276 bool is_observed = object->map()->is_observed() && |
6382 *name != isolate->heap()->hidden_string(); | 6277 *name != isolate->heap()->hidden_string(); |
6383 bool preexists = false; | 6278 bool preexists = false; |
6384 if (is_observed) { | 6279 if (is_observed) { |
6385 if (is_element) { | 6280 if (is_element) { |
6386 preexists = HasLocalElement(object, index); | 6281 preexists = HasLocalElement(object, index); |
6387 if (preexists && GetLocalElementAccessorPair(object, index).is_null()) { | 6282 if (preexists && GetLocalElementAccessorPair(object, index).is_null()) { |
6388 old_value = Object::GetElementNoExceptionThrown(isolate, object, index); | 6283 old_value = |
| 6284 Object::GetElement(isolate, object, index).ToHandleChecked(); |
6389 } | 6285 } |
6390 } else { | 6286 } else { |
6391 LookupResult lookup(isolate); | 6287 LookupResult lookup(isolate); |
6392 object->LocalLookup(*name, &lookup, true); | 6288 object->LocalLookup(*name, &lookup, true); |
6393 preexists = lookup.IsProperty(); | 6289 preexists = lookup.IsProperty(); |
6394 if (preexists && lookup.IsDataProperty()) { | 6290 if (preexists && lookup.IsDataProperty()) { |
6395 old_value = | 6291 old_value = |
6396 Object::GetPropertyOrElement(object, name).ToHandleChecked(); | 6292 Object::GetPropertyOrElement(object, name).ToHandleChecked(); |
6397 } | 6293 } |
6398 } | 6294 } |
(...skipping 4887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11286 List<Handle<Object> >* old_values, | 11182 List<Handle<Object> >* old_values, |
11287 List<uint32_t>* indices) { | 11183 List<uint32_t>* indices) { |
11288 PropertyAttributes attributes = | 11184 PropertyAttributes attributes = |
11289 JSReceiver::GetLocalElementAttribute(object, index); | 11185 JSReceiver::GetLocalElementAttribute(object, index); |
11290 ASSERT(attributes != ABSENT); | 11186 ASSERT(attributes != ABSENT); |
11291 if (attributes == DONT_DELETE) return false; | 11187 if (attributes == DONT_DELETE) return false; |
11292 Handle<Object> value; | 11188 Handle<Object> value; |
11293 if (!JSObject::GetLocalElementAccessorPair(object, index).is_null()) { | 11189 if (!JSObject::GetLocalElementAccessorPair(object, index).is_null()) { |
11294 value = Handle<Object>::cast(isolate->factory()->the_hole_value()); | 11190 value = Handle<Object>::cast(isolate->factory()->the_hole_value()); |
11295 } else { | 11191 } else { |
11296 value = Object::GetElementNoExceptionThrown(isolate, object, index); | 11192 value = Object::GetElement(isolate, object, index).ToHandleChecked(); |
11297 } | 11193 } |
11298 old_values->Add(value); | 11194 old_values->Add(value); |
11299 indices->Add(index); | 11195 indices->Add(index); |
11300 return true; | 11196 return true; |
11301 } | 11197 } |
11302 | 11198 |
11303 static void EnqueueSpliceRecord(Handle<JSArray> object, | 11199 static void EnqueueSpliceRecord(Handle<JSArray> object, |
11304 uint32_t index, | 11200 uint32_t index, |
11305 Handle<JSArray> deleted, | 11201 Handle<JSArray> deleted, |
11306 uint32_t add_count) { | 11202 uint32_t add_count) { |
(...skipping 1230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12537 } | 12433 } |
12538 | 12434 |
12539 PropertyAttributes old_attributes = | 12435 PropertyAttributes old_attributes = |
12540 JSReceiver::GetLocalElementAttribute(object, index); | 12436 JSReceiver::GetLocalElementAttribute(object, index); |
12541 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 12437 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
12542 Handle<Object> old_length_handle; | 12438 Handle<Object> old_length_handle; |
12543 Handle<Object> new_length_handle; | 12439 Handle<Object> new_length_handle; |
12544 | 12440 |
12545 if (old_attributes != ABSENT) { | 12441 if (old_attributes != ABSENT) { |
12546 if (GetLocalElementAccessorPair(object, index).is_null()) { | 12442 if (GetLocalElementAccessorPair(object, index).is_null()) { |
12547 old_value = Object::GetElementNoExceptionThrown(isolate, object, index); | 12443 old_value = Object::GetElement(isolate, object, index).ToHandleChecked(); |
12548 } | 12444 } |
12549 } else if (object->IsJSArray()) { | 12445 } else if (object->IsJSArray()) { |
12550 // Store old array length in case adding an element grows the array. | 12446 // Store old array length in case adding an element grows the array. |
12551 old_length_handle = handle(Handle<JSArray>::cast(object)->length(), | 12447 old_length_handle = handle(Handle<JSArray>::cast(object)->length(), |
12552 isolate); | 12448 isolate); |
12553 } | 12449 } |
12554 | 12450 |
12555 // Check for lookup interceptor | 12451 // Check for lookup interceptor |
12556 Handle<Object> result; | 12452 Handle<Object> result; |
12557 ASSIGN_RETURN_ON_EXCEPTION( | 12453 ASSIGN_RETURN_ON_EXCEPTION( |
(...skipping 28 matching lines...) Expand all Loading... |
12586 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 12482 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
12587 EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted, | 12483 EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted, |
12588 new_length - old_length); | 12484 new_length - old_length); |
12589 } else { | 12485 } else { |
12590 EnqueueChangeRecord(object, "add", name, old_value); | 12486 EnqueueChangeRecord(object, "add", name, old_value); |
12591 } | 12487 } |
12592 } else if (old_value->IsTheHole()) { | 12488 } else if (old_value->IsTheHole()) { |
12593 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 12489 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
12594 } else { | 12490 } else { |
12595 Handle<Object> new_value = | 12491 Handle<Object> new_value = |
12596 Object::GetElementNoExceptionThrown(isolate, object, index); | 12492 Object::GetElement(isolate, object, index).ToHandleChecked(); |
12597 bool value_changed = !old_value->SameValue(*new_value); | 12493 bool value_changed = !old_value->SameValue(*new_value); |
12598 if (old_attributes != new_attributes) { | 12494 if (old_attributes != new_attributes) { |
12599 if (!value_changed) old_value = isolate->factory()->the_hole_value(); | 12495 if (!value_changed) old_value = isolate->factory()->the_hole_value(); |
12600 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 12496 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
12601 } else if (value_changed) { | 12497 } else if (value_changed) { |
12602 EnqueueChangeRecord(object, "update", name, old_value); | 12498 EnqueueChangeRecord(object, "update", name, old_value); |
12603 } | 12499 } |
12604 } | 12500 } |
12605 | 12501 |
12606 return result; | 12502 return result; |
(...skipping 4001 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16608 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16504 #define ERROR_MESSAGES_TEXTS(C, T) T, |
16609 static const char* error_messages_[] = { | 16505 static const char* error_messages_[] = { |
16610 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16506 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
16611 }; | 16507 }; |
16612 #undef ERROR_MESSAGES_TEXTS | 16508 #undef ERROR_MESSAGES_TEXTS |
16613 return error_messages_[reason]; | 16509 return error_messages_[reason]; |
16614 } | 16510 } |
16615 | 16511 |
16616 | 16512 |
16617 } } // namespace v8::internal | 16513 } } // namespace v8::internal |
OLD | NEW |