| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/runtime/runtime-utils.h" | 5 #include "src/runtime/runtime-utils.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "src/accessors.h" | 9 #include "src/accessors.h" |
| 10 #include "src/arguments.h" | 10 #include "src/arguments.h" |
| (...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 259 DCHECK(context->IsFunctionContext() || context->IsNativeContext() || | 259 DCHECK(context->IsFunctionContext() || context->IsNativeContext() || |
| 260 context->IsScriptContext() || | 260 context->IsScriptContext() || |
| 261 (context->IsBlockContext() && context->has_extension())); | 261 (context->IsBlockContext() && context->has_extension())); |
| 262 | 262 |
| 263 bool is_function = value->IsJSFunction(); | 263 bool is_function = value->IsJSFunction(); |
| 264 bool is_var = !is_function; | 264 bool is_var = !is_function; |
| 265 DCHECK(!is_var || value->IsUndefined(isolate)); | 265 DCHECK(!is_var || value->IsUndefined(isolate)); |
| 266 | 266 |
| 267 int index; | 267 int index; |
| 268 PropertyAttributes attributes; | 268 PropertyAttributes attributes; |
| 269 BindingFlags binding_flags; | 269 InitializationFlag init_flag; |
| 270 VariableMode mode; | 270 VariableMode mode; |
| 271 | 271 |
| 272 // Check for a conflict with a lexically scoped variable | 272 // Check for a conflict with a lexically scoped variable |
| 273 context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes, &binding_flags, | 273 context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes, &init_flag, |
| 274 &mode); | 274 &mode); |
| 275 if (attributes != ABSENT && IsLexicalVariableMode(mode)) { | 275 if (attributes != ABSENT && IsLexicalVariableMode(mode)) { |
| 276 // ES#sec-evaldeclarationinstantiation 5.a.i.1: | 276 // ES#sec-evaldeclarationinstantiation 5.a.i.1: |
| 277 // If varEnvRec.HasLexicalDeclaration(name) is true, throw a SyntaxError | 277 // If varEnvRec.HasLexicalDeclaration(name) is true, throw a SyntaxError |
| 278 // exception. | 278 // exception. |
| 279 // ES#sec-evaldeclarationinstantiation 5.d.ii.2.a.i: | 279 // ES#sec-evaldeclarationinstantiation 5.d.ii.2.a.i: |
| 280 // Throw a SyntaxError exception. | 280 // Throw a SyntaxError exception. |
| 281 return ThrowRedeclarationError(isolate, name, | 281 return ThrowRedeclarationError(isolate, name, |
| 282 RedeclarationType::kSyntaxError); | 282 RedeclarationType::kSyntaxError); |
| 283 } | 283 } |
| 284 | 284 |
| 285 Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, | 285 Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, |
| 286 &attributes, &binding_flags, &mode); | 286 &attributes, &init_flag, &mode); |
| 287 DCHECK(!isolate->has_pending_exception()); | 287 DCHECK(!isolate->has_pending_exception()); |
| 288 | 288 |
| 289 Handle<JSObject> object; | 289 Handle<JSObject> object; |
| 290 | 290 |
| 291 if (attributes != ABSENT && holder->IsJSGlobalObject()) { | 291 if (attributes != ABSENT && holder->IsJSGlobalObject()) { |
| 292 // ES#sec-evaldeclarationinstantiation 8.a.iv.1.b: | 292 // ES#sec-evaldeclarationinstantiation 8.a.iv.1.b: |
| 293 // If fnDefinable is false, throw a TypeError exception. | 293 // If fnDefinable is false, throw a TypeError exception. |
| 294 return DeclareGlobal(isolate, Handle<JSGlobalObject>::cast(holder), name, | 294 return DeclareGlobal(isolate, Handle<JSGlobalObject>::cast(holder), name, |
| 295 value, NONE, is_var, is_function, | 295 value, NONE, is_var, is_function, |
| 296 RedeclarationType::kTypeError); | 296 RedeclarationType::kTypeError); |
| (...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 765 } | 765 } |
| 766 | 766 |
| 767 | 767 |
| 768 RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) { | 768 RUNTIME_FUNCTION(Runtime_DeleteLookupSlot) { |
| 769 HandleScope scope(isolate); | 769 HandleScope scope(isolate); |
| 770 DCHECK_EQ(1, args.length()); | 770 DCHECK_EQ(1, args.length()); |
| 771 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 771 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
| 772 | 772 |
| 773 int index; | 773 int index; |
| 774 PropertyAttributes attributes; | 774 PropertyAttributes attributes; |
| 775 BindingFlags flags; | 775 InitializationFlag flag; |
| 776 VariableMode mode; | 776 VariableMode mode; |
| 777 Handle<Object> holder = isolate->context()->Lookup( | 777 Handle<Object> holder = isolate->context()->Lookup( |
| 778 name, FOLLOW_CHAINS, &index, &attributes, &flags, &mode); | 778 name, FOLLOW_CHAINS, &index, &attributes, &flag, &mode); |
| 779 | 779 |
| 780 // If the slot was not found the result is true. | 780 // If the slot was not found the result is true. |
| 781 if (holder.is_null()) { | 781 if (holder.is_null()) { |
| 782 // In case of JSProxy, an exception might have been thrown. | 782 // In case of JSProxy, an exception might have been thrown. |
| 783 if (isolate->has_pending_exception()) return isolate->heap()->exception(); | 783 if (isolate->has_pending_exception()) return isolate->heap()->exception(); |
| 784 return isolate->heap()->true_value(); | 784 return isolate->heap()->true_value(); |
| 785 } | 785 } |
| 786 | 786 |
| 787 // If the slot was found in a context, it should be DONT_DELETE. | 787 // If the slot was found in a context, it should be DONT_DELETE. |
| 788 if (holder->IsContext()) { | 788 if (holder->IsContext()) { |
| (...skipping 12 matching lines...) Expand all Loading... |
| 801 | 801 |
| 802 namespace { | 802 namespace { |
| 803 | 803 |
| 804 MaybeHandle<Object> LoadLookupSlot(Handle<String> name, | 804 MaybeHandle<Object> LoadLookupSlot(Handle<String> name, |
| 805 Object::ShouldThrow should_throw, | 805 Object::ShouldThrow should_throw, |
| 806 Handle<Object>* receiver_return = nullptr) { | 806 Handle<Object>* receiver_return = nullptr) { |
| 807 Isolate* const isolate = name->GetIsolate(); | 807 Isolate* const isolate = name->GetIsolate(); |
| 808 | 808 |
| 809 int index; | 809 int index; |
| 810 PropertyAttributes attributes; | 810 PropertyAttributes attributes; |
| 811 BindingFlags flags; | 811 InitializationFlag flag; |
| 812 VariableMode mode; | 812 VariableMode mode; |
| 813 Handle<Object> holder = isolate->context()->Lookup( | 813 Handle<Object> holder = isolate->context()->Lookup( |
| 814 name, FOLLOW_CHAINS, &index, &attributes, &flags, &mode); | 814 name, FOLLOW_CHAINS, &index, &attributes, &flag, &mode); |
| 815 if (isolate->has_pending_exception()) return MaybeHandle<Object>(); | 815 if (isolate->has_pending_exception()) return MaybeHandle<Object>(); |
| 816 | 816 |
| 817 if (index != Context::kNotFound) { | 817 if (index != Context::kNotFound) { |
| 818 DCHECK(holder->IsContext()); | 818 DCHECK(holder->IsContext()); |
| 819 // If the "property" we were looking for is a local variable, the | 819 // If the "property" we were looking for is a local variable, the |
| 820 // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3. | 820 // receiver is the global object; see ECMA-262, 3rd., 10.1.6 and 10.2.3. |
| 821 Handle<Object> receiver = isolate->factory()->undefined_value(); | 821 Handle<Object> receiver = isolate->factory()->undefined_value(); |
| 822 Handle<Object> value = handle(Context::cast(*holder)->get(index), isolate); | 822 Handle<Object> value = handle(Context::cast(*holder)->get(index), isolate); |
| 823 // Check for uninitialized bindings. | 823 // Check for uninitialized bindings. |
| 824 switch (flags) { | 824 if (flag == kNeedsInitialization && value->IsTheHole(isolate)) { |
| 825 case BINDING_CHECK_INITIALIZED: | 825 THROW_NEW_ERROR(isolate, |
| 826 if (value->IsTheHole(isolate)) { | 826 NewReferenceError(MessageTemplate::kNotDefined, name), |
| 827 THROW_NEW_ERROR(isolate, | 827 Object); |
| 828 NewReferenceError(MessageTemplate::kNotDefined, name), | |
| 829 Object); | |
| 830 } | |
| 831 // FALLTHROUGH | |
| 832 case BINDING_IS_INITIALIZED: | |
| 833 DCHECK(!value->IsTheHole(isolate)); | |
| 834 if (receiver_return) *receiver_return = receiver; | |
| 835 return value; | |
| 836 case MISSING_BINDING: | |
| 837 break; | |
| 838 } | 828 } |
| 839 UNREACHABLE(); | 829 DCHECK(!value->IsTheHole(isolate)); |
| 830 if (receiver_return) *receiver_return = receiver; |
| 831 return value; |
| 840 } | 832 } |
| 841 | 833 |
| 842 // Otherwise, if the slot was found the holder is a context extension | 834 // Otherwise, if the slot was found the holder is a context extension |
| 843 // object, subject of a with, or a global object. We read the named | 835 // object, subject of a with, or a global object. We read the named |
| 844 // property from it. | 836 // property from it. |
| 845 if (!holder.is_null()) { | 837 if (!holder.is_null()) { |
| 846 // No need to unhole the value here. This is taken care of by the | 838 // No need to unhole the value here. This is taken care of by the |
| 847 // GetProperty function. | 839 // GetProperty function. |
| 848 Handle<Object> value; | 840 Handle<Object> value; |
| 849 ASSIGN_RETURN_ON_EXCEPTION( | 841 ASSIGN_RETURN_ON_EXCEPTION( |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 905 | 897 |
| 906 namespace { | 898 namespace { |
| 907 | 899 |
| 908 MaybeHandle<Object> StoreLookupSlot(Handle<String> name, Handle<Object> value, | 900 MaybeHandle<Object> StoreLookupSlot(Handle<String> name, Handle<Object> value, |
| 909 LanguageMode language_mode) { | 901 LanguageMode language_mode) { |
| 910 Isolate* const isolate = name->GetIsolate(); | 902 Isolate* const isolate = name->GetIsolate(); |
| 911 Handle<Context> context(isolate->context(), isolate); | 903 Handle<Context> context(isolate->context(), isolate); |
| 912 | 904 |
| 913 int index; | 905 int index; |
| 914 PropertyAttributes attributes; | 906 PropertyAttributes attributes; |
| 915 BindingFlags flags; | 907 InitializationFlag flag; |
| 916 VariableMode mode; | 908 VariableMode mode; |
| 917 Handle<Object> holder = | 909 Handle<Object> holder = |
| 918 context->Lookup(name, FOLLOW_CHAINS, &index, &attributes, &flags, &mode); | 910 context->Lookup(name, FOLLOW_CHAINS, &index, &attributes, &flag, &mode); |
| 919 if (holder.is_null()) { | 911 if (holder.is_null()) { |
| 920 // In case of JSProxy, an exception might have been thrown. | 912 // In case of JSProxy, an exception might have been thrown. |
| 921 if (isolate->has_pending_exception()) return MaybeHandle<Object>(); | 913 if (isolate->has_pending_exception()) return MaybeHandle<Object>(); |
| 922 } | 914 } |
| 923 | 915 |
| 924 // The property was found in a context slot. | 916 // The property was found in a context slot. |
| 925 if (index != Context::kNotFound) { | 917 if (index != Context::kNotFound) { |
| 926 if (flags == BINDING_CHECK_INITIALIZED && | 918 if (flag == kNeedsInitialization && |
| 927 Handle<Context>::cast(holder)->is_the_hole(index)) { | 919 Handle<Context>::cast(holder)->is_the_hole(index)) { |
| 928 THROW_NEW_ERROR(isolate, | 920 THROW_NEW_ERROR(isolate, |
| 929 NewReferenceError(MessageTemplate::kNotDefined, name), | 921 NewReferenceError(MessageTemplate::kNotDefined, name), |
| 930 Object); | 922 Object); |
| 931 } | 923 } |
| 932 if ((attributes & READ_ONLY) == 0) { | 924 if ((attributes & READ_ONLY) == 0) { |
| 933 Handle<Context>::cast(holder)->set(index, *value); | 925 Handle<Context>::cast(holder)->set(index, *value); |
| 934 } else if (is_strict(language_mode)) { | 926 } else if (is_strict(language_mode)) { |
| 935 // Setting read only property in strict mode. | 927 // Setting read only property in strict mode. |
| 936 THROW_NEW_ERROR(isolate, | 928 THROW_NEW_ERROR(isolate, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 977 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { | 969 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { |
| 978 HandleScope scope(isolate); | 970 HandleScope scope(isolate); |
| 979 DCHECK_EQ(2, args.length()); | 971 DCHECK_EQ(2, args.length()); |
| 980 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 972 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
| 981 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); | 973 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |
| 982 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); | 974 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); |
| 983 } | 975 } |
| 984 | 976 |
| 985 } // namespace internal | 977 } // namespace internal |
| 986 } // namespace v8 | 978 } // namespace v8 |
| OLD | NEW |