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 static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) { | 19 struct RedeclarationError { |
20 enum Type { kSyntaxError = 0, kTypeError = 1 }; | |
21 }; | |
22 | |
23 static Object* ThrowRedeclarationError( | |
24 Isolate* isolate, Handle<String> name, | |
25 RedeclarationError::Type redeclaration_error_type) { | |
20 HandleScope scope(isolate); | 26 HandleScope scope(isolate); |
21 THROW_NEW_ERROR_RETURN_FAILURE( | 27 if (redeclaration_error_type == RedeclarationError::kSyntaxError) { |
22 isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name)); | 28 THROW_NEW_ERROR_RETURN_FAILURE( |
29 isolate, NewSyntaxError(MessageTemplate::kVarRedeclaration, name)); | |
30 } else { | |
31 THROW_NEW_ERROR_RETURN_FAILURE( | |
32 isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name)); | |
33 } | |
23 } | 34 } |
24 | 35 |
25 | 36 |
26 RUNTIME_FUNCTION(Runtime_ThrowConstAssignError) { | 37 RUNTIME_FUNCTION(Runtime_ThrowConstAssignError) { |
27 HandleScope scope(isolate); | 38 HandleScope scope(isolate); |
28 THROW_NEW_ERROR_RETURN_FAILURE(isolate, | 39 THROW_NEW_ERROR_RETURN_FAILURE(isolate, |
29 NewTypeError(MessageTemplate::kConstAssign)); | 40 NewTypeError(MessageTemplate::kConstAssign)); |
30 } | 41 } |
31 | 42 |
32 | 43 |
33 // May throw a RedeclarationError. | 44 // May throw a RedeclarationError. |
34 static Object* DeclareGlobals(Isolate* isolate, Handle<JSGlobalObject> global, | 45 static Object* DeclareGlobals( |
35 Handle<String> name, Handle<Object> value, | 46 Isolate* isolate, Handle<JSGlobalObject> global, Handle<String> name, |
36 PropertyAttributes attr, bool is_var, | 47 Handle<Object> value, PropertyAttributes attr, bool is_var, bool is_const, |
37 bool is_const, bool is_function) { | 48 bool is_function, RedeclarationError::Type redeclaration_error_type) { |
38 Handle<ScriptContextTable> script_contexts( | 49 Handle<ScriptContextTable> script_contexts( |
39 global->native_context()->script_context_table()); | 50 global->native_context()->script_context_table()); |
40 ScriptContextTable::LookupResult lookup; | 51 ScriptContextTable::LookupResult lookup; |
41 if (ScriptContextTable::Lookup(script_contexts, name, &lookup) && | 52 if (ScriptContextTable::Lookup(script_contexts, name, &lookup) && |
42 IsLexicalVariableMode(lookup.mode)) { | 53 IsLexicalVariableMode(lookup.mode)) { |
43 return ThrowRedeclarationError(isolate, name); | 54 return ThrowRedeclarationError(isolate, name, |
55 RedeclarationError::kSyntaxError); | |
jwolfe
2016/06/07 17:42:02
15.1.11:6.a: "If envRec.HasLexicalDeclaration(name
| |
44 } | 56 } |
45 | 57 |
46 // Do the lookup own properties only, see ES5 erratum. | 58 // Do the lookup own properties only, see ES5 erratum. |
47 LookupIterator it(global, name, global, LookupIterator::OWN_SKIP_INTERCEPTOR); | 59 LookupIterator it(global, name, global, LookupIterator::OWN_SKIP_INTERCEPTOR); |
48 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 60 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
49 if (!maybe.IsJust()) return isolate->heap()->exception(); | 61 if (!maybe.IsJust()) return isolate->heap()->exception(); |
50 | 62 |
51 if (it.IsFound()) { | 63 if (it.IsFound()) { |
52 PropertyAttributes old_attributes = maybe.FromJust(); | 64 PropertyAttributes old_attributes = maybe.FromJust(); |
53 // The name was declared before; check for conflicting re-declarations. | 65 // The name was declared before; check for conflicting re-declarations. |
54 if (is_const) return ThrowRedeclarationError(isolate, name); | 66 if (is_const) { |
67 return ThrowRedeclarationError(isolate, name, | |
68 RedeclarationError::kSyntaxError); | |
jwolfe
2016/06/07 17:42:02
I was unable to get this code to run. It does not
| |
69 } | |
55 | 70 |
56 // Skip var re-declarations. | 71 // Skip var re-declarations. |
57 if (is_var) return isolate->heap()->undefined_value(); | 72 if (is_var) return isolate->heap()->undefined_value(); |
58 | 73 |
59 DCHECK(is_function); | 74 DCHECK(is_function); |
60 if ((old_attributes & DONT_DELETE) != 0) { | 75 if ((old_attributes & DONT_DELETE) != 0) { |
61 // Only allow reconfiguring globals to functions in user code (no | 76 // Only allow reconfiguring globals to functions in user code (no |
62 // natives, which are marked as read-only). | 77 // natives, which are marked as read-only). |
63 DCHECK((attr & READ_ONLY) == 0); | 78 DCHECK((attr & READ_ONLY) == 0); |
64 | 79 |
65 // Check whether we can reconfigure the existing property into a | 80 // Check whether we can reconfigure the existing property into a |
66 // function. | 81 // function. |
67 PropertyDetails old_details = it.property_details(); | 82 PropertyDetails old_details = it.property_details(); |
68 if (old_details.IsReadOnly() || old_details.IsDontEnum() || | 83 if (old_details.IsReadOnly() || old_details.IsDontEnum() || |
69 (it.state() == LookupIterator::ACCESSOR && | 84 (it.state() == LookupIterator::ACCESSOR && |
70 it.GetAccessors()->IsAccessorPair())) { | 85 it.GetAccessors()->IsAccessorPair())) { |
71 return ThrowRedeclarationError(isolate, name); | 86 return ThrowRedeclarationError(isolate, name, redeclaration_error_type); |
jwolfe
2016/06/07 17:42:02
15.1.11:5.d: "If hasRestrictedGlobal is true, thro
| |
72 } | 87 } |
73 // If the existing property is not configurable, keep its attributes. Do | 88 // If the existing property is not configurable, keep its attributes. Do |
74 attr = old_attributes; | 89 attr = old_attributes; |
75 } | 90 } |
76 | 91 |
77 // If the current state is ACCESSOR, this could mean it's an AccessorInfo | 92 // If the current state is ACCESSOR, this could mean it's an AccessorInfo |
78 // type property. We are not allowed to call into such setters during global | 93 // type property. We are not allowed to call into such setters during global |
79 // function declaration since this would break e.g., onload. Meaning | 94 // function declaration since this would break e.g., onload. Meaning |
80 // 'function onload() {}' would invalidly register that function as the | 95 // 'function onload() {}' would invalidly register that function as the |
81 // onload callback. To avoid this situation, we first delete the property | 96 // onload callback. To avoid this situation, we first delete the property |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
130 | 145 |
131 // Compute the property attributes. According to ECMA-262, | 146 // Compute the property attributes. According to ECMA-262, |
132 // the property must be non-configurable except in eval. | 147 // the property must be non-configurable except in eval. |
133 bool is_native = DeclareGlobalsNativeFlag::decode(flags); | 148 bool is_native = DeclareGlobalsNativeFlag::decode(flags); |
134 bool is_eval = DeclareGlobalsEvalFlag::decode(flags); | 149 bool is_eval = DeclareGlobalsEvalFlag::decode(flags); |
135 int attr = NONE; | 150 int attr = NONE; |
136 if (is_const) attr |= READ_ONLY; | 151 if (is_const) attr |= READ_ONLY; |
137 if (is_function && is_native) attr |= READ_ONLY; | 152 if (is_function && is_native) attr |= READ_ONLY; |
138 if (!is_const && !is_eval) attr |= DONT_DELETE; | 153 if (!is_const && !is_eval) attr |= DONT_DELETE; |
139 | 154 |
140 Object* result = DeclareGlobals(isolate, global, name, value, | 155 Object* result = DeclareGlobals( |
141 static_cast<PropertyAttributes>(attr), | 156 isolate, global, name, value, static_cast<PropertyAttributes>(attr), |
142 is_var, is_const, is_function); | 157 is_var, is_const, is_function, RedeclarationError::kSyntaxError); |
jwolfe
2016/06/07 17:42:02
15.1.11:5.d: "If hasRestrictedGlobal is true, thro
| |
143 if (isolate->has_pending_exception()) return result; | 158 if (isolate->has_pending_exception()) return result; |
144 }); | 159 }); |
145 | 160 |
146 return isolate->heap()->undefined_value(); | 161 return isolate->heap()->undefined_value(); |
147 } | 162 } |
148 | 163 |
149 | 164 |
150 RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) { | 165 RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) { |
151 HandleScope scope(isolate); | 166 HandleScope scope(isolate); |
152 // args[0] == name | 167 // args[0] == name |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
227 | 242 |
228 int index; | 243 int index; |
229 PropertyAttributes attributes; | 244 PropertyAttributes attributes; |
230 BindingFlags binding_flags; | 245 BindingFlags binding_flags; |
231 | 246 |
232 if ((attr & EVAL_DECLARED) != 0) { | 247 if ((attr & EVAL_DECLARED) != 0) { |
233 // Check for a conflict with a lexically scoped variable | 248 // Check for a conflict with a lexically scoped variable |
234 context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes, | 249 context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes, |
235 &binding_flags); | 250 &binding_flags); |
236 if (attributes != ABSENT && binding_flags == BINDING_CHECK_INITIALIZED) { | 251 if (attributes != ABSENT && binding_flags == BINDING_CHECK_INITIALIZED) { |
237 return ThrowRedeclarationError(isolate, name); | 252 return ThrowRedeclarationError(isolate, name, |
253 RedeclarationError::kSyntaxError); | |
jwolfe
2016/06/07 17:42:02
18.2.1.3:5.a.i.1: "If varEnvRec.HasLexicalDeclarat
| |
238 } | 254 } |
239 attr = static_cast<PropertyAttributes>(attr & ~EVAL_DECLARED); | 255 attr = static_cast<PropertyAttributes>(attr & ~EVAL_DECLARED); |
240 } | 256 } |
241 | 257 |
242 Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, | 258 Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, |
243 &attributes, &binding_flags); | 259 &attributes, &binding_flags); |
244 if (holder.is_null()) { | 260 if (holder.is_null()) { |
245 // In case of JSProxy, an exception might have been thrown. | 261 // In case of JSProxy, an exception might have been thrown. |
246 if (isolate->has_pending_exception()) return isolate->heap()->exception(); | 262 if (isolate->has_pending_exception()) return isolate->heap()->exception(); |
247 } | 263 } |
248 | 264 |
249 Handle<JSObject> object; | 265 Handle<JSObject> object; |
250 Handle<Object> value = | 266 Handle<Object> value = |
251 is_function ? initial_value | 267 is_function ? initial_value |
252 : Handle<Object>::cast(isolate->factory()->undefined_value()); | 268 : Handle<Object>::cast(isolate->factory()->undefined_value()); |
253 | 269 |
254 // TODO(verwaest): This case should probably not be covered by this function, | 270 // TODO(verwaest): This case should probably not be covered by this function, |
255 // but by DeclareGlobals instead. | 271 // but by DeclareGlobals instead. |
256 if (attributes != ABSENT && holder->IsJSGlobalObject()) { | 272 if (attributes != ABSENT && holder->IsJSGlobalObject()) { |
257 return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name, | 273 return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name, |
258 value, attr, is_var, is_const, is_function); | 274 value, attr, is_var, is_const, is_function, |
275 RedeclarationError::kTypeError); | |
jwolfe
2016/06/07 17:42:02
18.2.1.3:8.a.iv.1.b: "If fnDefinable is false, thr
| |
259 } | 276 } |
260 if (context_arg->extension()->IsJSGlobalObject()) { | 277 if (context_arg->extension()->IsJSGlobalObject()) { |
261 Handle<JSGlobalObject> global( | 278 Handle<JSGlobalObject> global( |
262 JSGlobalObject::cast(context_arg->extension()), isolate); | 279 JSGlobalObject::cast(context_arg->extension()), isolate); |
263 return DeclareGlobals(isolate, global, name, value, attr, is_var, is_const, | 280 return DeclareGlobals(isolate, global, name, value, attr, is_var, is_const, |
264 is_function); | 281 is_function, RedeclarationError::kSyntaxError); |
jwolfe
2016/06/07 17:42:02
I believe, this call can never cause the redeclara
| |
265 } else if (context->IsScriptContext()) { | 282 } else if (context->IsScriptContext()) { |
266 DCHECK(context->global_object()->IsJSGlobalObject()); | 283 DCHECK(context->global_object()->IsJSGlobalObject()); |
267 Handle<JSGlobalObject> global( | 284 Handle<JSGlobalObject> global( |
268 JSGlobalObject::cast(context->global_object()), isolate); | 285 JSGlobalObject::cast(context->global_object()), isolate); |
269 return DeclareGlobals(isolate, global, name, value, attr, is_var, is_const, | 286 return DeclareGlobals(isolate, global, name, value, attr, is_var, is_const, |
270 is_function); | 287 is_function, RedeclarationError::kSyntaxError); |
jwolfe
2016/06/07 17:42:02
18.2.1.3:8.a.iv.1.b: "If fnDefinable is false, thr
| |
271 } | 288 } |
272 | 289 |
273 if (attributes != ABSENT) { | 290 if (attributes != ABSENT) { |
274 // The name was declared before; check for conflicting re-declarations. | 291 // The name was declared before; check for conflicting re-declarations. |
275 if (is_const || (attributes & READ_ONLY) != 0) { | 292 if (is_const || (attributes & READ_ONLY) != 0) { |
276 return ThrowRedeclarationError(isolate, name); | 293 return ThrowRedeclarationError(isolate, name, |
294 RedeclarationError::kSyntaxError); | |
jwolfe
2016/06/07 17:42:02
I was unable to get this code to run. It does not
| |
277 } | 295 } |
278 | 296 |
279 // Skip var re-declarations. | 297 // Skip var re-declarations. |
280 if (is_var) return isolate->heap()->undefined_value(); | 298 if (is_var) return isolate->heap()->undefined_value(); |
281 | 299 |
282 DCHECK(is_function); | 300 DCHECK(is_function); |
283 if (index != Context::kNotFound) { | 301 if (index != Context::kNotFound) { |
284 DCHECK(holder.is_identical_to(context)); | 302 DCHECK(holder.is_identical_to(context)); |
285 context->set(index, *initial_value); | 303 context->set(index, *initial_value); |
286 return isolate->heap()->undefined_value(); | 304 return isolate->heap()->undefined_value(); |
(...skipping 318 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
605 static Object* FindNameClash(Handle<ScopeInfo> scope_info, | 623 static Object* FindNameClash(Handle<ScopeInfo> scope_info, |
606 Handle<JSGlobalObject> global_object, | 624 Handle<JSGlobalObject> global_object, |
607 Handle<ScriptContextTable> script_context) { | 625 Handle<ScriptContextTable> script_context) { |
608 Isolate* isolate = scope_info->GetIsolate(); | 626 Isolate* isolate = scope_info->GetIsolate(); |
609 for (int var = 0; var < scope_info->ContextLocalCount(); var++) { | 627 for (int var = 0; var < scope_info->ContextLocalCount(); var++) { |
610 Handle<String> name(scope_info->ContextLocalName(var)); | 628 Handle<String> name(scope_info->ContextLocalName(var)); |
611 VariableMode mode = scope_info->ContextLocalMode(var); | 629 VariableMode mode = scope_info->ContextLocalMode(var); |
612 ScriptContextTable::LookupResult lookup; | 630 ScriptContextTable::LookupResult lookup; |
613 if (ScriptContextTable::Lookup(script_context, name, &lookup)) { | 631 if (ScriptContextTable::Lookup(script_context, name, &lookup)) { |
614 if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(lookup.mode)) { | 632 if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(lookup.mode)) { |
615 return ThrowRedeclarationError(isolate, name); | 633 return ThrowRedeclarationError(isolate, name, |
634 RedeclarationError::kSyntaxError); | |
jwolfe
2016/06/07 17:42:02
15.1.11:5.b: "If envRec.HasLexicalDeclaration(name
| |
616 } | 635 } |
617 } | 636 } |
618 | 637 |
619 if (IsLexicalVariableMode(mode)) { | 638 if (IsLexicalVariableMode(mode)) { |
620 LookupIterator it(global_object, name, global_object, | 639 LookupIterator it(global_object, name, global_object, |
621 LookupIterator::OWN_SKIP_INTERCEPTOR); | 640 LookupIterator::OWN_SKIP_INTERCEPTOR); |
622 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); | 641 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
623 if (!maybe.IsJust()) return isolate->heap()->exception(); | 642 if (!maybe.IsJust()) return isolate->heap()->exception(); |
624 if ((maybe.FromJust() & DONT_DELETE) != 0) { | 643 if ((maybe.FromJust() & DONT_DELETE) != 0) { |
625 return ThrowRedeclarationError(isolate, name); | 644 return ThrowRedeclarationError(isolate, name, |
645 RedeclarationError::kSyntaxError); | |
jwolfe
2016/06/07 17:42:02
15.1.11:5.a: "If envRec.HasVarDeclaration(name) is
| |
626 } | 646 } |
627 | 647 |
628 JSGlobalObject::InvalidatePropertyCell(global_object, name); | 648 JSGlobalObject::InvalidatePropertyCell(global_object, name); |
629 } | 649 } |
630 } | 650 } |
631 return isolate->heap()->undefined_value(); | 651 return isolate->heap()->undefined_value(); |
632 } | 652 } |
633 | 653 |
634 | 654 |
635 RUNTIME_FUNCTION(Runtime_NewScriptContext) { | 655 RUNTIME_FUNCTION(Runtime_NewScriptContext) { |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1021 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { | 1041 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { |
1022 HandleScope scope(isolate); | 1042 HandleScope scope(isolate); |
1023 DCHECK_EQ(2, args.length()); | 1043 DCHECK_EQ(2, args.length()); |
1024 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); | 1044 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); |
1025 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); | 1045 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); |
1026 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); | 1046 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); |
1027 } | 1047 } |
1028 | 1048 |
1029 } // namespace internal | 1049 } // namespace internal |
1030 } // namespace v8 | 1050 } // namespace v8 |
OLD | NEW |