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 |