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 "src/accessors.h" | 7 #include "src/accessors.h" |
8 #include "src/arguments.h" | 8 #include "src/arguments.h" |
9 #include "src/ast/scopeinfo.h" | 9 #include "src/ast/scopeinfo.h" |
10 #include "src/ast/scopes.h" | 10 #include "src/ast/scopes.h" |
11 #include "src/deoptimizer.h" | 11 #include "src/deoptimizer.h" |
12 #include "src/frames-inl.h" | 12 #include "src/frames-inl.h" |
13 #include "src/isolate-inl.h" | 13 #include "src/isolate-inl.h" |
14 #include "src/messages.h" | 14 #include "src/messages.h" |
15 | 15 |
16 namespace v8 { | 16 namespace v8 { |
17 namespace internal { | 17 namespace internal { |
18 | 18 |
| 19 RUNTIME_FUNCTION(Runtime_ThrowConstAssignError) { |
| 20 HandleScope scope(isolate); |
| 21 THROW_NEW_ERROR_RETURN_FAILURE(isolate, |
| 22 NewTypeError(MessageTemplate::kConstAssign)); |
| 23 } |
| 24 |
| 25 namespace { |
| 26 |
19 enum class RedeclarationType { kSyntaxError = 0, kTypeError = 1 }; | 27 enum class RedeclarationType { kSyntaxError = 0, kTypeError = 1 }; |
20 | 28 |
21 static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name, | 29 Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name, |
22 RedeclarationType redeclaration_type) { | 30 RedeclarationType redeclaration_type) { |
23 HandleScope scope(isolate); | 31 HandleScope scope(isolate); |
24 if (redeclaration_type == RedeclarationType::kSyntaxError) { | 32 if (redeclaration_type == RedeclarationType::kSyntaxError) { |
25 THROW_NEW_ERROR_RETURN_FAILURE( | 33 THROW_NEW_ERROR_RETURN_FAILURE( |
26 isolate, NewSyntaxError(MessageTemplate::kVarRedeclaration, name)); | 34 isolate, NewSyntaxError(MessageTemplate::kVarRedeclaration, name)); |
27 } else { | 35 } else { |
28 THROW_NEW_ERROR_RETURN_FAILURE( | 36 THROW_NEW_ERROR_RETURN_FAILURE( |
29 isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name)); | 37 isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name)); |
30 } | 38 } |
31 } | 39 } |
32 | 40 |
33 | 41 |
34 RUNTIME_FUNCTION(Runtime_ThrowConstAssignError) { | |
35 HandleScope scope(isolate); | |
36 THROW_NEW_ERROR_RETURN_FAILURE(isolate, | |
37 NewTypeError(MessageTemplate::kConstAssign)); | |
38 } | |
39 | |
40 | |
41 // May throw a RedeclarationError. | 42 // May throw a RedeclarationError. |
42 static Object* DeclareGlobals(Isolate* isolate, Handle<JSGlobalObject> global, | 43 Object* DeclareGlobal( |
43 Handle<String> name, Handle<Object> value, | 44 Isolate* isolate, Handle<JSGlobalObject> global, Handle<String> name, |
44 PropertyAttributes attr, bool is_var, | 45 Handle<Object> value, PropertyAttributes attr, bool is_var, |
45 bool is_function, | 46 bool is_function, RedeclarationType redeclaration_type, |
46 RedeclarationType redeclaration_type) { | 47 Handle<TypeFeedbackVector> feedback_vector = Handle<TypeFeedbackVector>(), |
| 48 FeedbackVectorSlot slot = FeedbackVectorSlot::Invalid()) { |
47 Handle<ScriptContextTable> script_contexts( | 49 Handle<ScriptContextTable> script_contexts( |
48 global->native_context()->script_context_table()); | 50 global->native_context()->script_context_table()); |
49 ScriptContextTable::LookupResult lookup; | 51 ScriptContextTable::LookupResult lookup; |
50 if (ScriptContextTable::Lookup(script_contexts, name, &lookup) && | 52 if (ScriptContextTable::Lookup(script_contexts, name, &lookup) && |
51 IsLexicalVariableMode(lookup.mode)) { | 53 IsLexicalVariableMode(lookup.mode)) { |
52 // ES#sec-globaldeclarationinstantiation 6.a: | 54 // ES#sec-globaldeclarationinstantiation 6.a: |
53 // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError | 55 // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError |
54 // exception. | 56 // exception. |
55 return ThrowRedeclarationError(isolate, name, | 57 return ThrowRedeclarationError(isolate, name, |
56 RedeclarationType::kSyntaxError); | 58 RedeclarationType::kSyntaxError); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 // 'function onload() {}' would invalidly register that function as the | 98 // 'function onload() {}' would invalidly register that function as the |
97 // onload callback. To avoid this situation, we first delete the property | 99 // onload callback. To avoid this situation, we first delete the property |
98 // before readding it as a regular data property below. | 100 // before readding it as a regular data property below. |
99 if (it.state() == LookupIterator::ACCESSOR) it.Delete(); | 101 if (it.state() == LookupIterator::ACCESSOR) it.Delete(); |
100 } | 102 } |
101 | 103 |
102 // Define or redefine own property. | 104 // Define or redefine own property. |
103 RETURN_FAILURE_ON_EXCEPTION( | 105 RETURN_FAILURE_ON_EXCEPTION( |
104 isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr)); | 106 isolate, JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, attr)); |
105 | 107 |
| 108 if (!feedback_vector.is_null()) { |
| 109 DCHECK_EQ(*global, *it.GetHolder<Object>()); |
| 110 // Preinitialize the feedback slot if the global object does not have |
| 111 // named interceptor or the interceptor is not masking. |
| 112 if (!global->HasNamedInterceptor() || |
| 113 global->GetNamedInterceptor()->non_masking()) { |
| 114 LoadGlobalICNexus nexus(feedback_vector, slot); |
| 115 nexus.ConfigurePropertyCellMode(it.GetPropertyCell()); |
| 116 } |
| 117 } |
106 return isolate->heap()->undefined_value(); | 118 return isolate->heap()->undefined_value(); |
107 } | 119 } |
108 | 120 |
109 | 121 Object* DeclareGlobals(Isolate* isolate, Handle<FixedArray> pairs, int flags, |
110 RUNTIME_FUNCTION(Runtime_DeclareGlobals) { | 122 Handle<TypeFeedbackVector> feedback_vector) { |
111 HandleScope scope(isolate); | 123 HandleScope scope(isolate); |
112 DCHECK_EQ(2, args.length()); | |
113 Handle<JSGlobalObject> global(isolate->global_object()); | 124 Handle<JSGlobalObject> global(isolate->global_object()); |
114 Handle<Context> context(isolate->context()); | 125 Handle<Context> context(isolate->context()); |
115 | 126 |
116 CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 0); | |
117 CONVERT_SMI_ARG_CHECKED(flags, 1); | |
118 | |
119 // Traverse the name/value pairs and set the properties. | 127 // Traverse the name/value pairs and set the properties. |
120 int length = pairs->length(); | 128 int length = pairs->length(); |
121 FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i += 2, { | 129 FOR_WITH_HANDLE_SCOPE(isolate, int, i = 0, i, i < length, i += 2, { |
122 Handle<String> name(String::cast(pairs->get(i))); | 130 FeedbackVectorSlot slot(Smi::cast(pairs->get(i))->value()); |
| 131 Handle<String> name(feedback_vector->GetName(slot), isolate); |
123 Handle<Object> initial_value(pairs->get(i + 1), isolate); | 132 Handle<Object> initial_value(pairs->get(i + 1), isolate); |
124 | 133 |
125 bool is_var = initial_value->IsUndefined(isolate); | 134 bool is_var = initial_value->IsUndefined(isolate); |
126 bool is_function = initial_value->IsSharedFunctionInfo(); | 135 bool is_function = initial_value->IsSharedFunctionInfo(); |
127 DCHECK_EQ(1, BoolToInt(is_var) + BoolToInt(is_function)); | 136 DCHECK_EQ(1, BoolToInt(is_var) + BoolToInt(is_function)); |
128 | 137 |
129 Handle<Object> value; | 138 Handle<Object> value; |
130 if (is_function) { | 139 if (is_function) { |
131 // Copy the function and update its context. Use it as value. | 140 // Copy the function and update its context. Use it as value. |
132 Handle<SharedFunctionInfo> shared = | 141 Handle<SharedFunctionInfo> shared = |
133 Handle<SharedFunctionInfo>::cast(initial_value); | 142 Handle<SharedFunctionInfo>::cast(initial_value); |
134 Handle<JSFunction> function = | 143 Handle<JSFunction> function = |
135 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, | 144 isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context, |
136 TENURED); | 145 TENURED); |
137 value = function; | 146 value = function; |
138 } else { | 147 } else { |
139 value = isolate->factory()->undefined_value(); | 148 value = isolate->factory()->undefined_value(); |
140 } | 149 } |
141 | 150 |
142 // Compute the property attributes. According to ECMA-262, | 151 // Compute the property attributes. According to ECMA-262, |
143 // the property must be non-configurable except in eval. | 152 // the property must be non-configurable except in eval. |
144 bool is_native = DeclareGlobalsNativeFlag::decode(flags); | 153 bool is_native = DeclareGlobalsNativeFlag::decode(flags); |
145 bool is_eval = DeclareGlobalsEvalFlag::decode(flags); | 154 bool is_eval = DeclareGlobalsEvalFlag::decode(flags); |
146 int attr = NONE; | 155 int attr = NONE; |
147 if (is_function && is_native) attr |= READ_ONLY; | 156 if (is_function && is_native) attr |= READ_ONLY; |
148 if (!is_eval) attr |= DONT_DELETE; | 157 if (!is_eval) attr |= DONT_DELETE; |
149 | 158 |
150 // ES#sec-globaldeclarationinstantiation 5.d: | 159 // ES#sec-globaldeclarationinstantiation 5.d: |
151 // If hasRestrictedGlobal is true, throw a SyntaxError exception. | 160 // If hasRestrictedGlobal is true, throw a SyntaxError exception. |
152 Object* result = DeclareGlobals( | 161 Object* result = DeclareGlobal( |
153 isolate, global, name, value, static_cast<PropertyAttributes>(attr), | 162 isolate, global, name, value, static_cast<PropertyAttributes>(attr), |
154 is_var, is_function, RedeclarationType::kSyntaxError); | 163 is_var, is_function, RedeclarationType::kSyntaxError, feedback_vector, |
| 164 slot); |
155 if (isolate->has_pending_exception()) return result; | 165 if (isolate->has_pending_exception()) return result; |
156 }); | 166 }); |
157 | 167 |
158 return isolate->heap()->undefined_value(); | 168 return isolate->heap()->undefined_value(); |
159 } | 169 } |
160 | 170 |
| 171 } // namespace |
| 172 |
| 173 RUNTIME_FUNCTION(Runtime_DeclareGlobals) { |
| 174 HandleScope scope(isolate); |
| 175 DCHECK_EQ(3, args.length()); |
| 176 |
| 177 CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 0); |
| 178 CONVERT_SMI_ARG_CHECKED(flags, 1); |
| 179 CONVERT_ARG_HANDLE_CHECKED(TypeFeedbackVector, feedback_vector, 2); |
| 180 |
| 181 return DeclareGlobals(isolate, pairs, flags, feedback_vector); |
| 182 } |
| 183 |
| 184 // TODO(ishell): merge this with Runtime::kDeclareGlobals once interpreter |
| 185 // is able to pass feedback vector. |
| 186 RUNTIME_FUNCTION(Runtime_DeclareGlobalsForInterpreter) { |
| 187 HandleScope scope(isolate); |
| 188 DCHECK_EQ(3, args.length()); |
| 189 |
| 190 CONVERT_ARG_HANDLE_CHECKED(FixedArray, pairs, 0); |
| 191 CONVERT_SMI_ARG_CHECKED(flags, 1); |
| 192 CONVERT_ARG_HANDLE_CHECKED(JSFunction, closure, 2); |
| 193 |
| 194 Handle<TypeFeedbackVector> feedback_vector(closure->feedback_vector(), |
| 195 isolate); |
| 196 return DeclareGlobals(isolate, pairs, flags, feedback_vector); |
| 197 } |
161 | 198 |
162 RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) { | 199 RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) { |
163 HandleScope scope(isolate); | 200 HandleScope scope(isolate); |
164 DCHECK_EQ(3, args.length()); | 201 DCHECK_EQ(3, args.length()); |
165 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 202 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
166 CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 1); | 203 CONVERT_LANGUAGE_MODE_ARG_CHECKED(language_mode, 1); |
167 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); | 204 CONVERT_ARG_HANDLE_CHECKED(Object, value, 2); |
168 | 205 |
169 Handle<JSGlobalObject> global(isolate->context()->global_object()); | 206 Handle<JSGlobalObject> global(isolate->global_object()); |
170 RETURN_RESULT_OR_FAILURE( | 207 RETURN_RESULT_OR_FAILURE( |
171 isolate, Object::SetProperty(global, name, value, language_mode)); | 208 isolate, Object::SetProperty(global, name, value, language_mode)); |
172 } | 209 } |
173 | 210 |
174 | 211 |
175 RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) { | 212 RUNTIME_FUNCTION(Runtime_InitializeConstGlobal) { |
176 HandleScope handle_scope(isolate); | 213 HandleScope handle_scope(isolate); |
177 DCHECK_EQ(2, args.length()); | 214 DCHECK_EQ(2, args.length()); |
178 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 215 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
179 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); | 216 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |
180 | 217 |
181 Handle<JSGlobalObject> global = isolate->global_object(); | 218 Handle<JSGlobalObject> global(isolate->global_object()); |
182 | 219 |
183 // Lookup the property as own on the global object. | 220 // Lookup the property as own on the global object. |
184 LookupIterator it(global, name, global, LookupIterator::OWN_SKIP_INTERCEPTOR); | 221 LookupIterator it(global, name, global, LookupIterator::OWN_SKIP_INTERCEPTOR); |
185 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 222 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
186 DCHECK(maybe.IsJust()); | 223 DCHECK(maybe.IsJust()); |
187 PropertyAttributes old_attributes = maybe.FromJust(); | 224 PropertyAttributes old_attributes = maybe.FromJust(); |
188 | 225 |
189 PropertyAttributes attr = | 226 PropertyAttributes attr = |
190 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); | 227 static_cast<PropertyAttributes>(DONT_DELETE | READ_ONLY); |
191 // Set the value if the property is either missing, or the property attributes | 228 // Set the value if the property is either missing, or the property attributes |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 | 281 |
245 Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, | 282 Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, |
246 &attributes, &binding_flags); | 283 &attributes, &binding_flags); |
247 DCHECK(!isolate->has_pending_exception()); | 284 DCHECK(!isolate->has_pending_exception()); |
248 | 285 |
249 Handle<JSObject> object; | 286 Handle<JSObject> object; |
250 | 287 |
251 if (attributes != ABSENT && holder->IsJSGlobalObject()) { | 288 if (attributes != ABSENT && holder->IsJSGlobalObject()) { |
252 // ES#sec-evaldeclarationinstantiation 8.a.iv.1.b: | 289 // ES#sec-evaldeclarationinstantiation 8.a.iv.1.b: |
253 // If fnDefinable is false, throw a TypeError exception. | 290 // If fnDefinable is false, throw a TypeError exception. |
254 return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name, | 291 return DeclareGlobal(isolate, Handle<JSGlobalObject>::cast(holder), name, |
255 value, NONE, is_var, is_function, | 292 value, NONE, is_var, is_function, |
256 RedeclarationType::kTypeError); | 293 RedeclarationType::kTypeError); |
257 } | 294 } |
258 if (context_arg->extension()->IsJSGlobalObject()) { | 295 if (context_arg->extension()->IsJSGlobalObject()) { |
259 Handle<JSGlobalObject> global( | 296 Handle<JSGlobalObject> global( |
260 JSGlobalObject::cast(context_arg->extension()), isolate); | 297 JSGlobalObject::cast(context_arg->extension()), isolate); |
261 return DeclareGlobals(isolate, global, name, value, NONE, is_var, | 298 return DeclareGlobal(isolate, global, name, value, NONE, is_var, |
262 is_function, RedeclarationType::kTypeError); | 299 is_function, RedeclarationType::kTypeError); |
263 } else if (context->IsScriptContext()) { | 300 } else if (context->IsScriptContext()) { |
264 DCHECK(context->global_object()->IsJSGlobalObject()); | 301 DCHECK(context->global_object()->IsJSGlobalObject()); |
265 Handle<JSGlobalObject> global( | 302 Handle<JSGlobalObject> global( |
266 JSGlobalObject::cast(context->global_object()), isolate); | 303 JSGlobalObject::cast(context->global_object()), isolate); |
267 return DeclareGlobals(isolate, global, name, value, NONE, is_var, | 304 return DeclareGlobal(isolate, global, name, value, NONE, is_var, |
268 is_function, RedeclarationType::kTypeError); | 305 is_function, RedeclarationType::kTypeError); |
269 } | 306 } |
270 | 307 |
271 if (attributes != ABSENT) { | 308 if (attributes != ABSENT) { |
272 DCHECK_EQ(NONE, attributes); | 309 DCHECK_EQ(NONE, attributes); |
273 | 310 |
274 // Skip var re-declarations. | 311 // Skip var re-declarations. |
275 if (is_var) return isolate->heap()->undefined_value(); | 312 if (is_var) return isolate->heap()->undefined_value(); |
276 | 313 |
277 DCHECK(is_function); | 314 DCHECK(is_function); |
278 if (index != Context::kNotFound) { | 315 if (index != Context::kNotFound) { |
(...skipping 656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
935 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { | 972 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { |
936 HandleScope scope(isolate); | 973 HandleScope scope(isolate); |
937 DCHECK_EQ(2, args.length()); | 974 DCHECK_EQ(2, args.length()); |
938 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 975 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
939 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); | 976 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |
940 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); | 977 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); |
941 } | 978 } |
942 | 979 |
943 } // namespace internal | 980 } // namespace internal |
944 } // namespace v8 | 981 } // namespace v8 |
OLD | NEW |