Chromium Code Reviews| 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, | 480 MaybeHandle<Object> Object::GetPropertyOrElement(Handle<Object> object, |
| 501 Handle<Name> name) { | 481 Handle<Name> name) { |
| 502 uint32_t index; | 482 uint32_t index; |
| 503 Isolate* isolate = name->GetIsolate(); | 483 Isolate* isolate = name->GetIsolate(); |
| 504 if (name->AsArrayIndex(&index)) return GetElement(isolate, object, index); | 484 if (name->AsArrayIndex(&index)) return GetElement(isolate, object, index); |
| 505 return GetProperty(object, name); | 485 return GetProperty(object, name); |
| 506 } | 486 } |
| 507 | 487 |
| 508 | 488 |
| 509 Handle<Object> Object::GetProperty(Handle<Object> object, | 489 MaybeHandle<Object> Object::GetProperty(Handle<Object> object, |
|
Igor Sheludko
2014/04/11 10:52:13
Non-handlified version was defined in objects-inl.
| |
| 510 Handle<Name> name) { | 490 Handle<Name> name) { |
| 511 CALL_HEAP_FUNCTION(name->GetIsolate(), object->GetProperty(*name), Object); | 491 PropertyAttributes attributes; |
| 492 return GetPropertyWithReceiver(object, object, name, &attributes); | |
| 512 } | 493 } |
| 513 | 494 |
| 514 | 495 |
| 515 MaybeObject* JSProxy::GetElementWithHandler(Object* receiver, | 496 MaybeHandle<Object> JSProxy::GetElementWithHandler(Handle<JSProxy> proxy, |
|
Igor Sheludko
2014/04/11 10:52:13
Simple enough for inlining.
Yang
2014/04/11 11:21:42
Done. Also moved GetPropertyOrElement and GetPrope
| |
| 516 uint32_t index) { | 497 Handle<Object> receiver, |
| 517 String* name; | 498 uint32_t index) { |
| 518 MaybeObject* maybe = GetHeap()->Uint32ToString(index); | 499 return GetPropertyWithHandler( |
| 519 if (!maybe->To<String>(&name)) return maybe; | 500 proxy, receiver, proxy->GetIsolate()->factory()->Uint32ToString(index)); |
| 520 return GetPropertyWithHandler(receiver, name); | |
| 521 } | 501 } |
| 522 | 502 |
| 523 | 503 |
| 524 MaybeHandle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy, | 504 MaybeHandle<Object> JSProxy::SetElementWithHandler(Handle<JSProxy> proxy, |
| 525 Handle<JSReceiver> receiver, | 505 Handle<JSReceiver> receiver, |
| 526 uint32_t index, | 506 uint32_t index, |
| 527 Handle<Object> value, | 507 Handle<Object> value, |
| 528 StrictMode strict_mode) { | 508 StrictMode strict_mode) { |
| 529 Isolate* isolate = proxy->GetIsolate(); | 509 Isolate* isolate = proxy->GetIsolate(); |
| 530 Handle<String> name = isolate->factory()->Uint32ToString(index); | 510 Handle<String> name = isolate->factory()->Uint32ToString(index); |
| (...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 834 // created with then no changes can have been made to it. | 814 // created with then no changes can have been made to it. |
| 835 return map() != fun->initial_map() | 815 return map() != fun->initial_map() |
| 836 || !HasFastObjectElements() | 816 || !HasFastObjectElements() |
| 837 || !HasFastProperties(); | 817 || !HasFastProperties(); |
| 838 } | 818 } |
| 839 | 819 |
| 840 | 820 |
| 841 MaybeHandle<Object> Object::GetProperty(Handle<Object> object, | 821 MaybeHandle<Object> Object::GetProperty(Handle<Object> object, |
| 842 Handle<Object> receiver, | 822 Handle<Object> receiver, |
| 843 LookupResult* result, | 823 LookupResult* result, |
| 844 Handle<Name> key, | 824 Handle<Name> name, |
| 845 PropertyAttributes* attributes) { | 825 PropertyAttributes* attributes) { |
| 846 Isolate* isolate = result->isolate(); | |
| 847 CALL_HEAP_FUNCTION( | |
| 848 isolate, | |
| 849 object->GetProperty(*receiver, result, *key, attributes), | |
| 850 Object); | |
| 851 } | |
| 852 | |
| 853 | |
| 854 // TODO(yangguo): handlify this and get rid of. | |
| 855 MaybeObject* Object::GetProperty(Object* receiver, | |
| 856 LookupResult* result, | |
| 857 Name* name, | |
| 858 PropertyAttributes* attributes) { | |
| 859 Isolate* isolate = name->GetIsolate(); | 826 Isolate* isolate = name->GetIsolate(); |
| 860 Heap* heap = isolate->heap(); | 827 Factory* factory = isolate->factory(); |
| 861 | |
| 862 #ifdef DEBUG | |
| 863 // TODO(mstarzinger): Only because of the AssertNoContextChange, drop as soon | |
| 864 // as this method has been fully handlified. | |
| 865 HandleScope scope(isolate); | |
| 866 #endif | |
| 867 | 828 |
| 868 // Make sure that the top context does not change when doing | 829 // Make sure that the top context does not change when doing |
| 869 // callbacks or interceptor calls. | 830 // callbacks or interceptor calls. |
| 870 AssertNoContextChange ncc(isolate); | 831 AssertNoContextChange ncc(isolate); |
| 871 | 832 |
| 872 // Traverse the prototype chain from the current object (this) to | 833 // Traverse the prototype chain from the current object (this) to |
| 873 // the holder and check for access rights. This avoids traversing the | 834 // the holder and check for access rights. This avoids traversing the |
| 874 // objects more than once in case of interceptors, because the | 835 // objects more than once in case of interceptors, because the |
| 875 // holder will always be the interceptor holder and the search may | 836 // holder will always be the interceptor holder and the search may |
| 876 // only continue with a current object just after the interceptor | 837 // only continue with a current object just after the interceptor |
| 877 // holder in the prototype chain. | 838 // holder in the prototype chain. |
| 878 // Proxy handlers do not use the proxy's prototype, so we can skip this. | 839 // Proxy handlers do not use the proxy's prototype, so we can skip this. |
| 879 if (!result->IsHandler()) { | 840 if (!result->IsHandler()) { |
| 880 Object* last = result->IsProperty() | 841 ASSERT(*object != object->GetPrototype(isolate)); |
| 881 ? result->holder() | 842 Handle<Object> last = result->IsProperty() |
| 882 : Object::cast(heap->null_value()); | 843 ? Handle<Object>(result->holder(), isolate) |
| 883 ASSERT(this != this->GetPrototype(isolate)); | 844 : Handle<Object>::cast(factory->null_value()); |
| 884 for (Object* current = this; | 845 for (Handle<Object> current = object; |
| 885 true; | 846 true; |
| 886 current = current->GetPrototype(isolate)) { | 847 current = Handle<Object>(current->GetPrototype(isolate), isolate)) { |
| 887 if (current->IsAccessCheckNeeded()) { | 848 if (current->IsAccessCheckNeeded()) { |
| 888 // Check if we're allowed to read from the current object. Note | 849 // Check if we're allowed to read from the current object. Note |
| 889 // that even though we may not actually end up loading the named | 850 // that even though we may not actually end up loading the named |
| 890 // property from the current object, we still check that we have | 851 // property from the current object, we still check that we have |
| 891 // access to it. | 852 // access to it. |
| 892 JSObject* checked = JSObject::cast(current); | 853 Handle<JSObject> checked = Handle<JSObject>::cast(current); |
| 893 if (!isolate->MayNamedAccess(checked, name, v8::ACCESS_GET)) { | 854 if (!isolate->MayNamedAccessWrapper(checked, name, v8::ACCESS_GET)) { |
| 894 HandleScope scope(isolate); | 855 return JSObject::GetPropertyWithFailedAccessCheck( |
| 895 Handle<Object> value; | 856 checked, receiver, result, name, attributes); |
| 896 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 897 isolate, value, | |
| 898 JSObject::GetPropertyWithFailedAccessCheck( | |
| 899 handle(checked, isolate), | |
| 900 handle(receiver, isolate), | |
| 901 result, | |
| 902 handle(name, isolate), | |
| 903 attributes)); | |
| 904 return *value; | |
| 905 } | 857 } |
| 906 } | 858 } |
| 907 // Stop traversing the chain once we reach the last object in the | 859 // Stop traversing the chain once we reach the last object in the |
| 908 // chain; either the holder of the result or null in case of an | 860 // chain; either the holder of the result or null in case of an |
| 909 // absent property. | 861 // absent property. |
| 910 if (current == last) break; | 862 if (current.is_identical_to(last)) break; |
| 911 } | 863 } |
| 912 } | 864 } |
| 913 | 865 |
| 914 if (!result->IsProperty()) { | 866 if (!result->IsProperty()) { |
| 915 *attributes = ABSENT; | 867 *attributes = ABSENT; |
| 916 return heap->undefined_value(); | 868 return factory->undefined_value(); |
| 917 } | 869 } |
| 918 *attributes = result->GetAttributes(); | 870 *attributes = result->GetAttributes(); |
| 919 Object* value; | 871 |
| 872 Handle<Object> value; | |
| 873 Handle<JSObject> holder(result->holder(), isolate); | |
| 920 switch (result->type()) { | 874 switch (result->type()) { |
| 921 case NORMAL: | 875 case NORMAL: { |
| 922 value = result->holder()->GetNormalizedProperty(result); | 876 DisallowHeapAllocation no_gc; |
| 923 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 877 value = Handle<Object>(holder->GetNormalizedProperty(result), isolate); |
|
Igor Sheludko
2014/04/11 10:52:13
To be uniform: handle(...)
Yang
2014/04/11 11:21:42
Done.
| |
| 924 return value->IsTheHole() ? heap->undefined_value() : value; | 878 break; |
| 925 case FIELD: { | |
| 926 MaybeObject* maybe_result = result->holder()->FastPropertyAt( | |
| 927 result->representation(), | |
| 928 result->GetFieldIndex().field_index()); | |
| 929 if (!maybe_result->To(&value)) return maybe_result; | |
| 930 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | |
| 931 return value->IsTheHole() ? heap->undefined_value() : value; | |
| 932 } | 879 } |
| 880 case FIELD: | |
| 881 value = JSObject::FastPropertyAt(holder, | |
| 882 result->representation(), | |
| 883 result->GetFieldIndex().field_index()); | |
| 884 break; | |
| 933 case CONSTANT: | 885 case CONSTANT: |
| 934 return result->GetConstant(); | 886 return Handle<Object>(result->GetConstant(), isolate); |
|
Igor Sheludko
2014/04/11 10:52:13
Same here.
Yang
2014/04/11 11:21:42
Done.
| |
| 935 case CALLBACKS: { | 887 case CALLBACKS: |
| 936 HandleScope scope(isolate); | 888 return JSObject::GetPropertyWithCallback( |
| 937 Handle<Object> value; | 889 holder, receiver, handle(result->GetCallbackObject(), isolate), name); |
| 938 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | |
| 939 isolate, value, | |
| 940 JSObject::GetPropertyWithCallback( | |
| 941 handle(result->holder(), isolate), | |
| 942 handle(receiver, isolate), | |
| 943 handle(result->GetCallbackObject(), isolate), | |
| 944 handle(name, isolate))); | |
| 945 return *value; | |
| 946 } | |
| 947 case HANDLER: | 890 case HANDLER: |
| 948 return result->proxy()->GetPropertyWithHandler(receiver, name); | 891 return JSProxy::GetPropertyWithHandler( |
| 949 case INTERCEPTOR: { | 892 handle(result->proxy(), isolate), receiver, name); |
| 950 HandleScope scope(isolate); | 893 case INTERCEPTOR: |
| 951 Handle<Object> value; | 894 return JSObject::GetPropertyWithInterceptor( |
| 952 ASSIGN_RETURN_FAILURE_ON_EXCEPTION( | 895 holder, receiver, name, attributes); |
| 953 isolate, value, | |
| 954 JSObject::GetPropertyWithInterceptor( | |
| 955 handle(result->holder(), isolate), | |
| 956 handle(receiver, isolate), | |
| 957 handle(name, isolate), | |
| 958 attributes)); | |
| 959 return *value; | |
| 960 } | |
| 961 case NONEXISTENT: | 896 case NONEXISTENT: |
| 962 UNREACHABLE(); | 897 UNREACHABLE(); |
| 963 break; | 898 break; |
| 964 } | 899 } |
| 965 UNREACHABLE(); | 900 ASSERT(!value->IsTheHole() || result->IsReadOnly()); |
| 966 return NULL; | 901 return value->IsTheHole() ? Handle<Object>::cast(factory->undefined_value()) |
| 902 : value; | |
| 967 } | 903 } |
| 968 | 904 |
| 969 | 905 |
| 970 MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate, | 906 MaybeHandle<Object> Object::GetElementWithReceiver(Isolate* isolate, |
| 971 Handle<Object> object, | 907 Handle<Object> object, |
| 972 Handle<Object> receiver, | 908 Handle<Object> receiver, |
| 973 uint32_t index) { | 909 uint32_t index) { |
| 974 Handle<Object> holder; | 910 Handle<Object> holder; |
| 975 | 911 |
| 976 // Iterate up the prototype chain until an element is found or the null | 912 // Iterate up the prototype chain until an element is found or the null |
| 977 // prototype is encountered. | 913 // prototype is encountered. |
| 978 for (holder = object; | 914 for (holder = object; |
| 979 !holder->IsNull(); | 915 !holder->IsNull(); |
| 980 holder = Handle<Object>(holder->GetPrototype(isolate), isolate)) { | 916 holder = Handle<Object>(holder->GetPrototype(isolate), isolate)) { |
| 981 if (!holder->IsJSObject()) { | 917 if (!holder->IsJSObject()) { |
| 982 Context* native_context = isolate->context()->native_context(); | 918 Context* native_context = isolate->context()->native_context(); |
| 983 if (holder->IsNumber()) { | 919 if (holder->IsNumber()) { |
| 984 holder = Handle<Object>( | 920 holder = Handle<Object>( |
| 985 native_context->number_function()->instance_prototype(), isolate); | 921 native_context->number_function()->instance_prototype(), isolate); |
| 986 } else if (holder->IsString()) { | 922 } else if (holder->IsString()) { |
| 987 holder = Handle<Object>( | 923 holder = Handle<Object>( |
| 988 native_context->string_function()->instance_prototype(), isolate); | 924 native_context->string_function()->instance_prototype(), isolate); |
| 989 } else if (holder->IsSymbol()) { | 925 } else if (holder->IsSymbol()) { |
| 990 holder = Handle<Object>( | 926 holder = Handle<Object>( |
| 991 native_context->symbol_function()->instance_prototype(), isolate); | 927 native_context->symbol_function()->instance_prototype(), isolate); |
| 992 } else if (holder->IsBoolean()) { | 928 } else if (holder->IsBoolean()) { |
| 993 holder = Handle<Object>( | 929 holder = Handle<Object>( |
| 994 native_context->boolean_function()->instance_prototype(), isolate); | 930 native_context->boolean_function()->instance_prototype(), isolate); |
| 995 } else if (holder->IsJSProxy()) { | 931 } else if (holder->IsJSProxy()) { |
| 996 CALL_HEAP_FUNCTION(isolate, | 932 return JSProxy::GetElementWithHandler( |
| 997 Handle<JSProxy>::cast(holder)->GetElementWithHandler( | 933 Handle<JSProxy>::cast(holder), receiver, index); |
| 998 *receiver, index), | |
| 999 Object); | |
| 1000 } else { | 934 } else { |
| 1001 // Undefined and null have no indexed properties. | 935 // Undefined and null have no indexed properties. |
| 1002 ASSERT(holder->IsUndefined() || holder->IsNull()); | 936 ASSERT(holder->IsUndefined() || holder->IsNull()); |
| 1003 return isolate->factory()->undefined_value(); | 937 return isolate->factory()->undefined_value(); |
| 1004 } | 938 } |
| 1005 } | 939 } |
| 1006 | 940 |
| 1007 // Inline the case for JSObjects. Doing so significantly improves the | 941 // Inline the case for JSObjects. Doing so significantly improves the |
| 1008 // performance of fetching elements where checking the prototype chain is | 942 // performance of fetching elements where checking the prototype chain is |
| 1009 // necessary. | 943 // necessary. |
| (...skipping 2684 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3694 Handle<Object> argv[] = { result }; | 3628 Handle<Object> argv[] = { result }; |
| 3695 Handle<Object> desc = Execution::Call( | 3629 Handle<Object> desc = Execution::Call( |
| 3696 isolate, isolate->to_complete_property_descriptor(), result, | 3630 isolate, isolate->to_complete_property_descriptor(), result, |
| 3697 ARRAY_SIZE(argv), argv, &has_pending_exception); | 3631 ARRAY_SIZE(argv), argv, &has_pending_exception); |
| 3698 if (has_pending_exception) return MaybeHandle<Object>(); | 3632 if (has_pending_exception) return MaybeHandle<Object>(); |
| 3699 | 3633 |
| 3700 // [[GetProperty]] requires to check that all properties are configurable. | 3634 // [[GetProperty]] requires to check that all properties are configurable. |
| 3701 Handle<String> configurable_name = | 3635 Handle<String> configurable_name = |
| 3702 isolate->factory()->InternalizeOneByteString( | 3636 isolate->factory()->InternalizeOneByteString( |
| 3703 STATIC_ASCII_VECTOR("configurable_")); | 3637 STATIC_ASCII_VECTOR("configurable_")); |
| 3704 Handle<Object> configurable = Object::GetProperty(desc, configurable_name); | 3638 Handle<Object> configurable = |
| 3705 ASSERT(!configurable.is_null()); | 3639 Object::GetProperty(desc, configurable_name).ToHandleChecked(); |
| 3706 ASSERT(configurable->IsTrue() || configurable->IsFalse()); | 3640 ASSERT(configurable->IsBoolean()); |
| 3707 if (configurable->IsFalse()) { | 3641 if (configurable->IsFalse()) { |
| 3708 Handle<String> trap = | 3642 Handle<String> trap = |
| 3709 isolate->factory()->InternalizeOneByteString( | 3643 isolate->factory()->InternalizeOneByteString( |
| 3710 STATIC_ASCII_VECTOR("getPropertyDescriptor")); | 3644 STATIC_ASCII_VECTOR("getPropertyDescriptor")); |
| 3711 Handle<Object> args[] = { handler, trap, name }; | 3645 Handle<Object> args[] = { handler, trap, name }; |
| 3712 Handle<Object> error = isolate->factory()->NewTypeError( | 3646 Handle<Object> error = isolate->factory()->NewTypeError( |
| 3713 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); | 3647 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); |
| 3714 return isolate->Throw<Object>(error); | 3648 return isolate->Throw<Object>(error); |
| 3715 } | 3649 } |
| 3716 ASSERT(configurable->IsTrue()); | 3650 ASSERT(configurable->IsTrue()); |
| 3717 | 3651 |
| 3718 // Check for DataDescriptor. | 3652 // Check for DataDescriptor. |
| 3719 Handle<String> hasWritable_name = | 3653 Handle<String> hasWritable_name = |
| 3720 isolate->factory()->InternalizeOneByteString( | 3654 isolate->factory()->InternalizeOneByteString( |
| 3721 STATIC_ASCII_VECTOR("hasWritable_")); | 3655 STATIC_ASCII_VECTOR("hasWritable_")); |
| 3722 Handle<Object> hasWritable = Object::GetProperty(desc, hasWritable_name); | 3656 Handle<Object> hasWritable = |
| 3723 ASSERT(!hasWritable.is_null()); | 3657 Object::GetProperty(desc, hasWritable_name).ToHandleChecked(); |
| 3724 ASSERT(hasWritable->IsTrue() || hasWritable->IsFalse()); | 3658 ASSERT(hasWritable->IsBoolean()); |
| 3725 if (hasWritable->IsTrue()) { | 3659 if (hasWritable->IsTrue()) { |
| 3726 Handle<String> writable_name = | 3660 Handle<String> writable_name = |
| 3727 isolate->factory()->InternalizeOneByteString( | 3661 isolate->factory()->InternalizeOneByteString( |
| 3728 STATIC_ASCII_VECTOR("writable_")); | 3662 STATIC_ASCII_VECTOR("writable_")); |
| 3729 Handle<Object> writable = Object::GetProperty(desc, writable_name); | 3663 Handle<Object> writable = |
| 3730 ASSERT(!writable.is_null()); | 3664 Object::GetProperty(desc, writable_name).ToHandleChecked(); |
| 3731 ASSERT(writable->IsTrue() || writable->IsFalse()); | 3665 ASSERT(writable->IsBoolean()); |
| 3732 *done = writable->IsFalse(); | 3666 *done = writable->IsFalse(); |
| 3733 if (!*done) return isolate->factory()->the_hole_value(); | 3667 if (!*done) return isolate->factory()->the_hole_value(); |
| 3734 if (strict_mode == SLOPPY) return value; | 3668 if (strict_mode == SLOPPY) return value; |
| 3735 Handle<Object> args[] = { name, receiver }; | 3669 Handle<Object> args[] = { name, receiver }; |
| 3736 Handle<Object> error = isolate->factory()->NewTypeError( | 3670 Handle<Object> error = isolate->factory()->NewTypeError( |
| 3737 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); | 3671 "strict_read_only_property", HandleVector(args, ARRAY_SIZE(args))); |
| 3738 return isolate->Throw<Object>(error); | 3672 return isolate->Throw<Object>(error); |
| 3739 } | 3673 } |
| 3740 | 3674 |
| 3741 // We have an AccessorDescriptor. | 3675 // We have an AccessorDescriptor. |
| 3742 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( | 3676 Handle<String> set_name = isolate->factory()->InternalizeOneByteString( |
| 3743 STATIC_ASCII_VECTOR("set_")); | 3677 STATIC_ASCII_VECTOR("set_")); |
| 3744 Handle<Object> setter = Object::GetProperty(desc, set_name); | 3678 Handle<Object> setter = Object::GetProperty(desc, set_name).ToHandleChecked(); |
| 3745 ASSERT(!setter.is_null()); | |
| 3746 if (!setter->IsUndefined()) { | 3679 if (!setter->IsUndefined()) { |
| 3747 // TODO(rossberg): nicer would be to cast to some JSCallable here... | 3680 // TODO(rossberg): nicer would be to cast to some JSCallable here... |
| 3748 return SetPropertyWithDefinedSetter( | 3681 return SetPropertyWithDefinedSetter( |
| 3749 receiver, Handle<JSReceiver>::cast(setter), value); | 3682 receiver, Handle<JSReceiver>::cast(setter), value); |
| 3750 } | 3683 } |
| 3751 | 3684 |
| 3752 if (strict_mode == SLOPPY) return value; | 3685 if (strict_mode == SLOPPY) return value; |
| 3753 Handle<Object> args2[] = { name, proxy }; | 3686 Handle<Object> args2[] = { name, proxy }; |
| 3754 Handle<Object> error = isolate->factory()->NewTypeError( | 3687 Handle<Object> error = isolate->factory()->NewTypeError( |
| 3755 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); | 3688 "no_setter_in_callback", HandleVector(args2, ARRAY_SIZE(args2))); |
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3823 bool has_pending_exception; | 3756 bool has_pending_exception; |
| 3824 Handle<Object> argv[] = { result }; | 3757 Handle<Object> argv[] = { result }; |
| 3825 Handle<Object> desc = Execution::Call( | 3758 Handle<Object> desc = Execution::Call( |
| 3826 isolate, isolate->to_complete_property_descriptor(), result, | 3759 isolate, isolate->to_complete_property_descriptor(), result, |
| 3827 ARRAY_SIZE(argv), argv, &has_pending_exception); | 3760 ARRAY_SIZE(argv), argv, &has_pending_exception); |
| 3828 if (has_pending_exception) return NONE; | 3761 if (has_pending_exception) return NONE; |
| 3829 | 3762 |
| 3830 // Convert result to PropertyAttributes. | 3763 // Convert result to PropertyAttributes. |
| 3831 Handle<String> enum_n = isolate->factory()->InternalizeOneByteString( | 3764 Handle<String> enum_n = isolate->factory()->InternalizeOneByteString( |
| 3832 STATIC_ASCII_VECTOR("enumerable_")); | 3765 STATIC_ASCII_VECTOR("enumerable_")); |
| 3833 Handle<Object> enumerable = Object::GetProperty(desc, enum_n); | 3766 Handle<Object> enumerable; |
| 3834 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, enumerable, NONE); | 3767 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 3768 isolate, enumerable, Object::GetProperty(desc, enum_n), NONE); | |
| 3835 Handle<String> conf_n = isolate->factory()->InternalizeOneByteString( | 3769 Handle<String> conf_n = isolate->factory()->InternalizeOneByteString( |
| 3836 STATIC_ASCII_VECTOR("configurable_")); | 3770 STATIC_ASCII_VECTOR("configurable_")); |
| 3837 Handle<Object> configurable = Object::GetProperty(desc, conf_n); | 3771 Handle<Object> configurable; |
| 3838 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, configurable, NONE); | 3772 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 3773 isolate, configurable, Object::GetProperty(desc, conf_n), NONE); | |
| 3839 Handle<String> writ_n = isolate->factory()->InternalizeOneByteString( | 3774 Handle<String> writ_n = isolate->factory()->InternalizeOneByteString( |
| 3840 STATIC_ASCII_VECTOR("writable_")); | 3775 STATIC_ASCII_VECTOR("writable_")); |
| 3841 Handle<Object> writable = Object::GetProperty(desc, writ_n); | 3776 Handle<Object> writable; |
| 3842 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, writable, NONE); | 3777 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 3778 isolate, writable, Object::GetProperty(desc, writ_n), NONE); | |
| 3843 if (!writable->BooleanValue()) { | 3779 if (!writable->BooleanValue()) { |
| 3844 Handle<String> set_n = isolate->factory()->InternalizeOneByteString( | 3780 Handle<String> set_n = isolate->factory()->InternalizeOneByteString( |
| 3845 STATIC_ASCII_VECTOR("set_")); | 3781 STATIC_ASCII_VECTOR("set_")); |
| 3846 Handle<Object> setter = Object::GetProperty(desc, set_n); | 3782 Handle<Object> setter; |
| 3847 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, setter, NONE); | 3783 ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
| 3784 isolate, setter, Object::GetProperty(desc, set_n), NONE); | |
| 3848 writable = isolate->factory()->ToBoolean(!setter->IsUndefined()); | 3785 writable = isolate->factory()->ToBoolean(!setter->IsUndefined()); |
| 3849 } | 3786 } |
| 3850 | 3787 |
| 3851 if (configurable->IsFalse()) { | 3788 if (configurable->IsFalse()) { |
| 3852 Handle<Object> handler(proxy->handler(), isolate); | 3789 Handle<Object> handler(proxy->handler(), isolate); |
| 3853 Handle<String> trap = isolate->factory()->InternalizeOneByteString( | 3790 Handle<String> trap = isolate->factory()->InternalizeOneByteString( |
| 3854 STATIC_ASCII_VECTOR("getPropertyDescriptor")); | 3791 STATIC_ASCII_VECTOR("getPropertyDescriptor")); |
| 3855 Handle<Object> args[] = { handler, trap, name }; | 3792 Handle<Object> args[] = { handler, trap, name }; |
| 3856 Handle<Object> error = isolate->factory()->NewTypeError( | 3793 Handle<Object> error = isolate->factory()->NewTypeError( |
| 3857 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); | 3794 "proxy_prop_not_configurable", HandleVector(args, ARRAY_SIZE(args))); |
| (...skipping 1432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5290 } | 5227 } |
| 5291 | 5228 |
| 5292 Handle<Object> old_value; | 5229 Handle<Object> old_value; |
| 5293 bool should_enqueue_change_record = false; | 5230 bool should_enqueue_change_record = false; |
| 5294 if (object->map()->is_observed()) { | 5231 if (object->map()->is_observed()) { |
| 5295 should_enqueue_change_record = HasLocalElement(object, index); | 5232 should_enqueue_change_record = HasLocalElement(object, index); |
| 5296 if (should_enqueue_change_record) { | 5233 if (should_enqueue_change_record) { |
| 5297 if (!GetLocalElementAccessorPair(object, index).is_null()) { | 5234 if (!GetLocalElementAccessorPair(object, index).is_null()) { |
| 5298 old_value = Handle<Object>::cast(factory->the_hole_value()); | 5235 old_value = Handle<Object>::cast(factory->the_hole_value()); |
| 5299 } else { | 5236 } else { |
| 5300 old_value = Object::GetElementNoExceptionThrown(isolate, object, index); | 5237 old_value = Object::GetElement( |
| 5238 isolate, object, index).ToHandleChecked(); | |
| 5301 } | 5239 } |
| 5302 } | 5240 } |
| 5303 } | 5241 } |
| 5304 | 5242 |
| 5305 // Skip interceptor if forcing deletion. | 5243 // Skip interceptor if forcing deletion. |
| 5306 MaybeHandle<Object> maybe_result; | 5244 MaybeHandle<Object> maybe_result; |
| 5307 if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) { | 5245 if (object->HasIndexedInterceptor() && mode != FORCE_DELETION) { |
| 5308 maybe_result = DeleteElementWithInterceptor(object, index); | 5246 maybe_result = DeleteElementWithInterceptor(object, index); |
| 5309 } else { | 5247 } else { |
| 5310 maybe_result = object->GetElementsAccessor()->Delete(object, index, mode); | 5248 maybe_result = object->GetElementsAccessor()->Delete(object, index, mode); |
| (...skipping 580 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 5891 copy->GetLocalPropertyNames(*names, 0); | 5829 copy->GetLocalPropertyNames(*names, 0); |
| 5892 for (int i = 0; i < names->length(); i++) { | 5830 for (int i = 0; i < names->length(); i++) { |
| 5893 ASSERT(names->get(i)->IsString()); | 5831 ASSERT(names->get(i)->IsString()); |
| 5894 Handle<String> key_string(String::cast(names->get(i))); | 5832 Handle<String> key_string(String::cast(names->get(i))); |
| 5895 PropertyAttributes attributes = | 5833 PropertyAttributes attributes = |
| 5896 JSReceiver::GetLocalPropertyAttribute(copy, key_string); | 5834 JSReceiver::GetLocalPropertyAttribute(copy, key_string); |
| 5897 // Only deep copy fields from the object literal expression. | 5835 // Only deep copy fields from the object literal expression. |
| 5898 // In particular, don't try to copy the length attribute of | 5836 // In particular, don't try to copy the length attribute of |
| 5899 // an array. | 5837 // an array. |
| 5900 if (attributes != NONE) continue; | 5838 if (attributes != NONE) continue; |
| 5901 Handle<Object> value = Object::GetProperty(copy, key_string); | 5839 Handle<Object> value = |
| 5902 CHECK_NOT_EMPTY_HANDLE(isolate, value); | 5840 Object::GetProperty(copy, key_string).ToHandleChecked(); |
| 5903 if (value->IsJSObject()) { | 5841 if (value->IsJSObject()) { |
| 5904 Handle<JSObject> result = VisitElementOrProperty( | 5842 Handle<JSObject> result = VisitElementOrProperty( |
| 5905 copy, Handle<JSObject>::cast(value)); | 5843 copy, Handle<JSObject>::cast(value)); |
| 5906 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); | 5844 RETURN_IF_EMPTY_HANDLE_VALUE(isolate, result, Handle<JSObject>()); |
| 5907 if (copying) { | 5845 if (copying) { |
| 5908 // Creating object copy for literals. No strict mode needed. | 5846 // Creating object copy for literals. No strict mode needed. |
| 5909 JSObject::SetProperty( | 5847 JSObject::SetProperty( |
| 5910 copy, key_string, result, NONE, SLOPPY).Assert(); | 5848 copy, key_string, result, NONE, SLOPPY).Assert(); |
| 5911 } | 5849 } |
| 5912 } | 5850 } |
| (...skipping 554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 6467 bool is_element = name->AsArrayIndex(&index); | 6405 bool is_element = name->AsArrayIndex(&index); |
| 6468 | 6406 |
| 6469 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 6407 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| 6470 bool is_observed = object->map()->is_observed() && | 6408 bool is_observed = object->map()->is_observed() && |
| 6471 *name != isolate->heap()->hidden_string(); | 6409 *name != isolate->heap()->hidden_string(); |
| 6472 bool preexists = false; | 6410 bool preexists = false; |
| 6473 if (is_observed) { | 6411 if (is_observed) { |
| 6474 if (is_element) { | 6412 if (is_element) { |
| 6475 preexists = HasLocalElement(object, index); | 6413 preexists = HasLocalElement(object, index); |
| 6476 if (preexists && GetLocalElementAccessorPair(object, index).is_null()) { | 6414 if (preexists && GetLocalElementAccessorPair(object, index).is_null()) { |
| 6477 old_value = Object::GetElementNoExceptionThrown(isolate, object, index); | 6415 old_value = |
| 6416 Object::GetElement(isolate, object, index).ToHandleChecked(); | |
| 6478 } | 6417 } |
| 6479 } else { | 6418 } else { |
| 6480 LookupResult lookup(isolate); | 6419 LookupResult lookup(isolate); |
| 6481 object->LocalLookup(*name, &lookup, true); | 6420 object->LocalLookup(*name, &lookup, true); |
| 6482 preexists = lookup.IsProperty(); | 6421 preexists = lookup.IsProperty(); |
| 6483 if (preexists && lookup.IsDataProperty()) { | 6422 if (preexists && lookup.IsDataProperty()) { |
| 6484 old_value = | 6423 old_value = |
| 6485 Object::GetPropertyOrElement(object, name).ToHandleChecked(); | 6424 Object::GetPropertyOrElement(object, name).ToHandleChecked(); |
| 6486 } | 6425 } |
| 6487 } | 6426 } |
| (...skipping 4841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 11329 List<Handle<Object> >* old_values, | 11268 List<Handle<Object> >* old_values, |
| 11330 List<uint32_t>* indices) { | 11269 List<uint32_t>* indices) { |
| 11331 PropertyAttributes attributes = | 11270 PropertyAttributes attributes = |
| 11332 JSReceiver::GetLocalElementAttribute(object, index); | 11271 JSReceiver::GetLocalElementAttribute(object, index); |
| 11333 ASSERT(attributes != ABSENT); | 11272 ASSERT(attributes != ABSENT); |
| 11334 if (attributes == DONT_DELETE) return false; | 11273 if (attributes == DONT_DELETE) return false; |
| 11335 Handle<Object> value; | 11274 Handle<Object> value; |
| 11336 if (!JSObject::GetLocalElementAccessorPair(object, index).is_null()) { | 11275 if (!JSObject::GetLocalElementAccessorPair(object, index).is_null()) { |
| 11337 value = Handle<Object>::cast(isolate->factory()->the_hole_value()); | 11276 value = Handle<Object>::cast(isolate->factory()->the_hole_value()); |
| 11338 } else { | 11277 } else { |
| 11339 value = Object::GetElementNoExceptionThrown(isolate, object, index); | 11278 value = Object::GetElement(isolate, object, index).ToHandleChecked(); |
| 11340 } | 11279 } |
| 11341 old_values->Add(value); | 11280 old_values->Add(value); |
| 11342 indices->Add(index); | 11281 indices->Add(index); |
| 11343 return true; | 11282 return true; |
| 11344 } | 11283 } |
| 11345 | 11284 |
| 11346 static void EnqueueSpliceRecord(Handle<JSArray> object, | 11285 static void EnqueueSpliceRecord(Handle<JSArray> object, |
| 11347 uint32_t index, | 11286 uint32_t index, |
| 11348 Handle<JSArray> deleted, | 11287 Handle<JSArray> deleted, |
| 11349 uint32_t add_count) { | 11288 uint32_t add_count) { |
| (...skipping 1200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 12550 } | 12489 } |
| 12551 | 12490 |
| 12552 PropertyAttributes old_attributes = | 12491 PropertyAttributes old_attributes = |
| 12553 JSReceiver::GetLocalElementAttribute(object, index); | 12492 JSReceiver::GetLocalElementAttribute(object, index); |
| 12554 Handle<Object> old_value = isolate->factory()->the_hole_value(); | 12493 Handle<Object> old_value = isolate->factory()->the_hole_value(); |
| 12555 Handle<Object> old_length_handle; | 12494 Handle<Object> old_length_handle; |
| 12556 Handle<Object> new_length_handle; | 12495 Handle<Object> new_length_handle; |
| 12557 | 12496 |
| 12558 if (old_attributes != ABSENT) { | 12497 if (old_attributes != ABSENT) { |
| 12559 if (GetLocalElementAccessorPair(object, index).is_null()) { | 12498 if (GetLocalElementAccessorPair(object, index).is_null()) { |
| 12560 old_value = Object::GetElementNoExceptionThrown(isolate, object, index); | 12499 old_value = Object::GetElement(isolate, object, index).ToHandleChecked(); |
| 12561 } | 12500 } |
| 12562 } else if (object->IsJSArray()) { | 12501 } else if (object->IsJSArray()) { |
| 12563 // Store old array length in case adding an element grows the array. | 12502 // Store old array length in case adding an element grows the array. |
| 12564 old_length_handle = handle(Handle<JSArray>::cast(object)->length(), | 12503 old_length_handle = handle(Handle<JSArray>::cast(object)->length(), |
| 12565 isolate); | 12504 isolate); |
| 12566 } | 12505 } |
| 12567 | 12506 |
| 12568 // Check for lookup interceptor | 12507 // Check for lookup interceptor |
| 12569 Handle<Object> result; | 12508 Handle<Object> result; |
| 12570 ASSIGN_RETURN_ON_EXCEPTION( | 12509 ASSIGN_RETURN_ON_EXCEPTION( |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 12599 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); | 12538 Handle<JSArray> deleted = isolate->factory()->NewJSArray(0); |
| 12600 EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted, | 12539 EnqueueSpliceRecord(Handle<JSArray>::cast(object), old_length, deleted, |
| 12601 new_length - old_length); | 12540 new_length - old_length); |
| 12602 } else { | 12541 } else { |
| 12603 EnqueueChangeRecord(object, "add", name, old_value); | 12542 EnqueueChangeRecord(object, "add", name, old_value); |
| 12604 } | 12543 } |
| 12605 } else if (old_value->IsTheHole()) { | 12544 } else if (old_value->IsTheHole()) { |
| 12606 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 12545 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
| 12607 } else { | 12546 } else { |
| 12608 Handle<Object> new_value = | 12547 Handle<Object> new_value = |
| 12609 Object::GetElementNoExceptionThrown(isolate, object, index); | 12548 Object::GetElement(isolate, object, index).ToHandleChecked(); |
| 12610 bool value_changed = !old_value->SameValue(*new_value); | 12549 bool value_changed = !old_value->SameValue(*new_value); |
| 12611 if (old_attributes != new_attributes) { | 12550 if (old_attributes != new_attributes) { |
| 12612 if (!value_changed) old_value = isolate->factory()->the_hole_value(); | 12551 if (!value_changed) old_value = isolate->factory()->the_hole_value(); |
| 12613 EnqueueChangeRecord(object, "reconfigure", name, old_value); | 12552 EnqueueChangeRecord(object, "reconfigure", name, old_value); |
| 12614 } else if (value_changed) { | 12553 } else if (value_changed) { |
| 12615 EnqueueChangeRecord(object, "update", name, old_value); | 12554 EnqueueChangeRecord(object, "update", name, old_value); |
| 12616 } | 12555 } |
| 12617 } | 12556 } |
| 12618 | 12557 |
| 12619 return result; | 12558 return result; |
| (...skipping 4022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 16642 #define ERROR_MESSAGES_TEXTS(C, T) T, | 16581 #define ERROR_MESSAGES_TEXTS(C, T) T, |
| 16643 static const char* error_messages_[] = { | 16582 static const char* error_messages_[] = { |
| 16644 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) | 16583 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) |
| 16645 }; | 16584 }; |
| 16646 #undef ERROR_MESSAGES_TEXTS | 16585 #undef ERROR_MESSAGES_TEXTS |
| 16647 return error_messages_[reason]; | 16586 return error_messages_[reason]; |
| 16648 } | 16587 } |
| 16649 | 16588 |
| 16650 | 16589 |
| 16651 } } // namespace v8::internal | 16590 } } // namespace v8::internal |
| OLD | NEW |