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