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 26 matching lines...) Expand all Loading... |
37 THROW_NEW_ERROR_RETURN_FAILURE( | 37 THROW_NEW_ERROR_RETURN_FAILURE( |
38 isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name)); | 38 isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name)); |
39 } | 39 } |
40 } | 40 } |
41 | 41 |
42 | 42 |
43 // May throw a RedeclarationError. | 43 // May throw a RedeclarationError. |
44 Object* DeclareGlobal( | 44 Object* DeclareGlobal( |
45 Isolate* isolate, Handle<JSGlobalObject> global, Handle<String> name, | 45 Isolate* isolate, Handle<JSGlobalObject> global, Handle<String> name, |
46 Handle<Object> value, PropertyAttributes attr, bool is_var, | 46 Handle<Object> value, PropertyAttributes attr, bool is_var, |
47 bool is_function, RedeclarationType redeclaration_type, | 47 bool is_function_declaration, RedeclarationType redeclaration_type, |
48 Handle<TypeFeedbackVector> feedback_vector = Handle<TypeFeedbackVector>(), | 48 Handle<TypeFeedbackVector> feedback_vector = Handle<TypeFeedbackVector>(), |
49 FeedbackVectorSlot slot = FeedbackVectorSlot::Invalid()) { | 49 FeedbackVectorSlot slot = FeedbackVectorSlot::Invalid()) { |
50 Handle<ScriptContextTable> script_contexts( | 50 Handle<ScriptContextTable> script_contexts( |
51 global->native_context()->script_context_table()); | 51 global->native_context()->script_context_table()); |
52 ScriptContextTable::LookupResult lookup; | 52 ScriptContextTable::LookupResult lookup; |
53 if (ScriptContextTable::Lookup(script_contexts, name, &lookup) && | 53 if (ScriptContextTable::Lookup(script_contexts, name, &lookup) && |
54 IsLexicalVariableMode(lookup.mode)) { | 54 IsLexicalVariableMode(lookup.mode)) { |
55 // ES#sec-globaldeclarationinstantiation 6.a: | 55 // ES#sec-globaldeclarationinstantiation 6.a: |
56 // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError | 56 // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError |
57 // exception. | 57 // exception. |
58 return ThrowRedeclarationError(isolate, name, | 58 return ThrowRedeclarationError(isolate, name, |
59 RedeclarationType::kSyntaxError); | 59 RedeclarationType::kSyntaxError); |
60 } | 60 } |
61 | 61 |
62 // Do the lookup own properties only, see ES5 erratum. | 62 // Do the lookup own properties only, see ES5 erratum. |
63 LookupIterator it(global, name, global, LookupIterator::OWN_SKIP_INTERCEPTOR); | 63 LookupIterator::Configuration lookup_config( |
| 64 LookupIterator::Configuration::OWN_SKIP_INTERCEPTOR); |
| 65 if (is_function_declaration) { |
| 66 // For function declarations, use the interceptor on the declaration. For |
| 67 // non-functions, use it only on initialization. |
| 68 lookup_config = LookupIterator::Configuration::OWN; |
| 69 } |
| 70 LookupIterator it(global, name, global, lookup_config); |
64 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 71 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
65 if (!maybe.IsJust()) return isolate->heap()->exception(); | 72 if (!maybe.IsJust()) return isolate->heap()->exception(); |
66 | 73 |
67 if (it.IsFound()) { | 74 if (it.IsFound()) { |
68 PropertyAttributes old_attributes = maybe.FromJust(); | 75 PropertyAttributes old_attributes = maybe.FromJust(); |
69 // The name was declared before; check for conflicting re-declarations. | 76 // The name was declared before; check for conflicting re-declarations. |
70 | 77 |
71 // Skip var re-declarations. | 78 // Skip var re-declarations. |
72 if (is_var) return isolate->heap()->undefined_value(); | 79 if (is_var) return isolate->heap()->undefined_value(); |
73 | 80 |
74 DCHECK(is_function); | 81 DCHECK(is_function_declaration); |
75 if ((old_attributes & DONT_DELETE) != 0) { | 82 if ((old_attributes & DONT_DELETE) != 0) { |
76 // Only allow reconfiguring globals to functions in user code (no | 83 // Only allow reconfiguring globals to functions in user code (no |
77 // natives, which are marked as read-only). | 84 // natives, which are marked as read-only). |
78 DCHECK((attr & READ_ONLY) == 0); | 85 DCHECK((attr & READ_ONLY) == 0); |
79 | 86 |
80 // Check whether we can reconfigure the existing property into a | 87 // Check whether we can reconfigure the existing property into a |
81 // function. | 88 // function. |
82 PropertyDetails old_details = it.property_details(); | 89 PropertyDetails old_details = it.property_details(); |
83 if (old_details.IsReadOnly() || old_details.IsDontEnum() || | 90 if (old_details.IsReadOnly() || old_details.IsDontEnum() || |
84 (it.state() == LookupIterator::ACCESSOR && | 91 (it.state() == LookupIterator::ACCESSOR && |
85 it.GetAccessors()->IsAccessorPair())) { | 92 it.GetAccessors()->IsAccessorPair())) { |
86 // ES#sec-globaldeclarationinstantiation 5.d: | 93 // ECMA-262 section 15.1.11 GlobalDeclarationInstantiation 5.d: |
87 // If hasRestrictedGlobal is true, throw a SyntaxError exception. | 94 // If hasRestrictedGlobal is true, throw a SyntaxError exception. |
88 // ES#sec-evaldeclarationinstantiation 8.a.iv.1.b: | 95 // ECMA-262 section 18.2.1.3 EvalDeclarationInstantiation 8.a.iv.1.b: |
89 // If fnDefinable is false, throw a TypeError exception. | 96 // If fnDefinable is false, throw a TypeError exception. |
90 return ThrowRedeclarationError(isolate, name, redeclaration_type); | 97 return ThrowRedeclarationError(isolate, name, redeclaration_type); |
91 } | 98 } |
92 // If the existing property is not configurable, keep its attributes. Do | 99 // If the existing property is not configurable, keep its attributes. Do |
93 attr = old_attributes; | 100 attr = old_attributes; |
94 } | 101 } |
95 | 102 |
96 // If the current state is ACCESSOR, this could mean it's an AccessorInfo | 103 // If the current state is ACCESSOR, this could mean it's an AccessorInfo |
97 // type property. We are not allowed to call into such setters during global | 104 // type property. We are not allowed to call into such setters during global |
98 // function declaration since this would break e.g., onload. Meaning | 105 // function declaration since this would break e.g., onload. Meaning |
99 // 'function onload() {}' would invalidly register that function as the | 106 // 'function onload() {}' would invalidly register that function as the |
100 // onload callback. To avoid this situation, we first delete the property | 107 // onload callback. To avoid this situation, we first delete the property |
101 // before readding it as a regular data property below. | 108 // before readding it as a regular data property below. |
102 if (it.state() == LookupIterator::ACCESSOR) it.Delete(); | 109 if (it.state() == LookupIterator::ACCESSOR) it.Delete(); |
103 } | 110 } |
104 | 111 |
| 112 if (is_function_declaration) { |
| 113 it.Restart(); |
| 114 } |
| 115 |
105 // Define or redefine own property. | 116 // Define or redefine own property. |
106 RETURN_FAILURE_ON_EXCEPTION( | 117 RETURN_FAILURE_ON_EXCEPTION( |
107 isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr)); | 118 isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr)); |
108 | 119 |
109 if (!feedback_vector.is_null()) { | 120 if (!feedback_vector.is_null()) { |
110 DCHECK_EQ(*global, *it.GetHolder<Object>()); | 121 DCHECK_EQ(*global, *it.GetHolder<Object>()); |
111 // Preinitialize the feedback slot if the global object does not have | 122 // Preinitialize the feedback slot if the global object does not have |
112 // named interceptor or the interceptor is not masking. | 123 // named interceptor or the interceptor is not masking. |
113 if (!global->HasNamedInterceptor() || | 124 if (!global->HasNamedInterceptor() || |
114 global->GetNamedInterceptor()->non_masking()) { | 125 global->GetNamedInterceptor()->non_masking()) { |
(...skipping 830 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
945 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { | 956 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { |
946 HandleScope scope(isolate); | 957 HandleScope scope(isolate); |
947 DCHECK_EQ(2, args.length()); | 958 DCHECK_EQ(2, args.length()); |
948 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 959 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
949 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); | 960 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |
950 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); | 961 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); |
951 } | 962 } |
952 | 963 |
953 } // namespace internal | 964 } // namespace internal |
954 } // namespace v8 | 965 } // namespace v8 |
OLD | NEW |