Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: src/runtime/runtime-scopes.cc

Issue 2048703002: change most cases of variable redeclaration from TypeError to SyntaxError (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: rebase Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | test/mjsunit/es6/block-eval-var-over-let.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 enum class RedeclarationType { kSyntaxError = 0, kTypeError = 1 };
20
21 static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name,
22 RedeclarationType redeclaration_type) {
20 HandleScope scope(isolate); 23 HandleScope scope(isolate);
21 THROW_NEW_ERROR_RETURN_FAILURE( 24 if (redeclaration_type == RedeclarationType::kSyntaxError) {
22 isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name)); 25 THROW_NEW_ERROR_RETURN_FAILURE(
26 isolate, NewSyntaxError(MessageTemplate::kVarRedeclaration, name));
27 } else {
28 THROW_NEW_ERROR_RETURN_FAILURE(
29 isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name));
30 }
23 } 31 }
24 32
25 33
26 RUNTIME_FUNCTION(Runtime_ThrowConstAssignError) { 34 RUNTIME_FUNCTION(Runtime_ThrowConstAssignError) {
27 HandleScope scope(isolate); 35 HandleScope scope(isolate);
28 THROW_NEW_ERROR_RETURN_FAILURE(isolate, 36 THROW_NEW_ERROR_RETURN_FAILURE(isolate,
29 NewTypeError(MessageTemplate::kConstAssign)); 37 NewTypeError(MessageTemplate::kConstAssign));
30 } 38 }
31 39
32 40
33 // May throw a RedeclarationError. 41 // May throw a RedeclarationError.
34 static Object* DeclareGlobals(Isolate* isolate, Handle<JSGlobalObject> global, 42 static Object* DeclareGlobals(Isolate* isolate, Handle<JSGlobalObject> global,
35 Handle<String> name, Handle<Object> value, 43 Handle<String> name, Handle<Object> value,
36 PropertyAttributes attr, bool is_var, 44 PropertyAttributes attr, bool is_var,
37 bool is_function) { 45 bool is_function,
46 RedeclarationType redeclaration_type) {
38 Handle<ScriptContextTable> script_contexts( 47 Handle<ScriptContextTable> script_contexts(
39 global->native_context()->script_context_table()); 48 global->native_context()->script_context_table());
40 ScriptContextTable::LookupResult lookup; 49 ScriptContextTable::LookupResult lookup;
41 if (ScriptContextTable::Lookup(script_contexts, name, &lookup) && 50 if (ScriptContextTable::Lookup(script_contexts, name, &lookup) &&
42 IsLexicalVariableMode(lookup.mode)) { 51 IsLexicalVariableMode(lookup.mode)) {
43 return ThrowRedeclarationError(isolate, name); 52 // ES#sec-globaldeclarationinstantiation 6.a:
53 // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError
54 // exception.
55 return ThrowRedeclarationError(isolate, name,
56 RedeclarationType::kSyntaxError);
44 } 57 }
45 58
46 // Do the lookup own properties only, see ES5 erratum. 59 // Do the lookup own properties only, see ES5 erratum.
47 LookupIterator it(global, name, global, LookupIterator::OWN_SKIP_INTERCEPTOR); 60 LookupIterator it(global, name, global, LookupIterator::OWN_SKIP_INTERCEPTOR);
48 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); 61 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
49 if (!maybe.IsJust()) return isolate->heap()->exception(); 62 if (!maybe.IsJust()) return isolate->heap()->exception();
50 63
51 if (it.IsFound()) { 64 if (it.IsFound()) {
52 PropertyAttributes old_attributes = maybe.FromJust(); 65 PropertyAttributes old_attributes = maybe.FromJust();
53 // The name was declared before; check for conflicting re-declarations. 66 // The name was declared before; check for conflicting re-declarations.
54 67
55 // Skip var re-declarations. 68 // Skip var re-declarations.
56 if (is_var) return isolate->heap()->undefined_value(); 69 if (is_var) return isolate->heap()->undefined_value();
57 70
58 DCHECK(is_function); 71 DCHECK(is_function);
59 if ((old_attributes & DONT_DELETE) != 0) { 72 if ((old_attributes & DONT_DELETE) != 0) {
60 // Only allow reconfiguring globals to functions in user code (no 73 // Only allow reconfiguring globals to functions in user code (no
61 // natives, which are marked as read-only). 74 // natives, which are marked as read-only).
62 DCHECK((attr & READ_ONLY) == 0); 75 DCHECK((attr & READ_ONLY) == 0);
63 76
64 // Check whether we can reconfigure the existing property into a 77 // Check whether we can reconfigure the existing property into a
65 // function. 78 // function.
66 PropertyDetails old_details = it.property_details(); 79 PropertyDetails old_details = it.property_details();
67 if (old_details.IsReadOnly() || old_details.IsDontEnum() || 80 if (old_details.IsReadOnly() || old_details.IsDontEnum() ||
68 (it.state() == LookupIterator::ACCESSOR && 81 (it.state() == LookupIterator::ACCESSOR &&
69 it.GetAccessors()->IsAccessorPair())) { 82 it.GetAccessors()->IsAccessorPair())) {
70 return ThrowRedeclarationError(isolate, name); 83 // ES#sec-globaldeclarationinstantiation 5.d:
84 // If hasRestrictedGlobal is true, throw a SyntaxError exception.
85 // ES#sec-evaldeclarationinstantiation 8.a.iv.1.b:
86 // If fnDefinable is false, throw a TypeError exception.
87 return ThrowRedeclarationError(isolate, name, redeclaration_type);
71 } 88 }
72 // If the existing property is not configurable, keep its attributes. Do 89 // If the existing property is not configurable, keep its attributes. Do
73 attr = old_attributes; 90 attr = old_attributes;
74 } 91 }
75 92
76 // If the current state is ACCESSOR, this could mean it's an AccessorInfo 93 // If the current state is ACCESSOR, this could mean it's an AccessorInfo
77 // type property. We are not allowed to call into such setters during global 94 // type property. We are not allowed to call into such setters during global
78 // function declaration since this would break e.g., onload. Meaning 95 // function declaration since this would break e.g., onload. Meaning
79 // 'function onload() {}' would invalidly register that function as the 96 // 'function onload() {}' would invalidly register that function as the
80 // onload callback. To avoid this situation, we first delete the property 97 // onload callback. To avoid this situation, we first delete the property
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 } 140 }
124 141
125 // Compute the property attributes. According to ECMA-262, 142 // Compute the property attributes. According to ECMA-262,
126 // the property must be non-configurable except in eval. 143 // the property must be non-configurable except in eval.
127 bool is_native = DeclareGlobalsNativeFlag::decode(flags); 144 bool is_native = DeclareGlobalsNativeFlag::decode(flags);
128 bool is_eval = DeclareGlobalsEvalFlag::decode(flags); 145 bool is_eval = DeclareGlobalsEvalFlag::decode(flags);
129 int attr = NONE; 146 int attr = NONE;
130 if (is_function && is_native) attr |= READ_ONLY; 147 if (is_function && is_native) attr |= READ_ONLY;
131 if (!is_eval) attr |= DONT_DELETE; 148 if (!is_eval) attr |= DONT_DELETE;
132 149
133 Object* result = DeclareGlobals(isolate, global, name, value, 150 // ES#sec-globaldeclarationinstantiation 5.d:
134 static_cast<PropertyAttributes>(attr), 151 // If hasRestrictedGlobal is true, throw a SyntaxError exception.
135 is_var, is_function); 152 Object* result = DeclareGlobals(
153 isolate, global, name, value, static_cast<PropertyAttributes>(attr),
154 is_var, is_function, RedeclarationType::kSyntaxError);
136 if (isolate->has_pending_exception()) return result; 155 if (isolate->has_pending_exception()) return result;
137 }); 156 });
138 157
139 return isolate->heap()->undefined_value(); 158 return isolate->heap()->undefined_value();
140 } 159 }
141 160
142 161
143 RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) { 162 RUNTIME_FUNCTION(Runtime_InitializeVarGlobal) {
144 HandleScope scope(isolate); 163 HandleScope scope(isolate);
145 DCHECK_EQ(3, args.length()); 164 DCHECK_EQ(3, args.length());
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 bool is_var = !is_function; 226 bool is_var = !is_function;
208 DCHECK(!is_var || value->IsUndefined(isolate)); 227 DCHECK(!is_var || value->IsUndefined(isolate));
209 228
210 int index; 229 int index;
211 PropertyAttributes attributes; 230 PropertyAttributes attributes;
212 BindingFlags binding_flags; 231 BindingFlags binding_flags;
213 232
214 // Check for a conflict with a lexically scoped variable 233 // Check for a conflict with a lexically scoped variable
215 context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes, &binding_flags); 234 context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes, &binding_flags);
216 if (attributes != ABSENT && binding_flags == BINDING_CHECK_INITIALIZED) { 235 if (attributes != ABSENT && binding_flags == BINDING_CHECK_INITIALIZED) {
217 return ThrowRedeclarationError(isolate, name); 236 // ES#sec-evaldeclarationinstantiation 5.a.i.1:
237 // If varEnvRec.HasLexicalDeclaration(name) is true, throw a SyntaxError
238 // exception.
239 // ES#sec-evaldeclarationinstantiation 5.d.ii.2.a.i:
240 // Throw a SyntaxError exception.
241 return ThrowRedeclarationError(isolate, name,
242 RedeclarationType::kSyntaxError);
218 } 243 }
219 244
220 Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, 245 Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index,
221 &attributes, &binding_flags); 246 &attributes, &binding_flags);
222 DCHECK(!isolate->has_pending_exception()); 247 DCHECK(!isolate->has_pending_exception());
223 248
224 Handle<JSObject> object; 249 Handle<JSObject> object;
225 250
226 if (attributes != ABSENT && holder->IsJSGlobalObject()) { 251 if (attributes != ABSENT && holder->IsJSGlobalObject()) {
252 // ES#sec-evaldeclarationinstantiation 8.a.iv.1.b:
253 // If fnDefinable is false, throw a TypeError exception.
227 return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name, 254 return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name,
228 value, NONE, is_var, is_function); 255 value, NONE, is_var, is_function,
256 RedeclarationType::kTypeError);
229 } 257 }
230 if (context_arg->extension()->IsJSGlobalObject()) { 258 if (context_arg->extension()->IsJSGlobalObject()) {
231 Handle<JSGlobalObject> global( 259 Handle<JSGlobalObject> global(
232 JSGlobalObject::cast(context_arg->extension()), isolate); 260 JSGlobalObject::cast(context_arg->extension()), isolate);
233 return DeclareGlobals(isolate, global, name, value, NONE, is_var, 261 return DeclareGlobals(isolate, global, name, value, NONE, is_var,
234 is_function); 262 is_function, RedeclarationType::kTypeError);
235 } else if (context->IsScriptContext()) { 263 } else if (context->IsScriptContext()) {
236 DCHECK(context->global_object()->IsJSGlobalObject()); 264 DCHECK(context->global_object()->IsJSGlobalObject());
237 Handle<JSGlobalObject> global( 265 Handle<JSGlobalObject> global(
238 JSGlobalObject::cast(context->global_object()), isolate); 266 JSGlobalObject::cast(context->global_object()), isolate);
239 return DeclareGlobals(isolate, global, name, value, NONE, is_var, 267 return DeclareGlobals(isolate, global, name, value, NONE, is_var,
240 is_function); 268 is_function, RedeclarationType::kTypeError);
241 } 269 }
242 270
243 if (attributes != ABSENT) { 271 if (attributes != ABSENT) {
244 DCHECK_EQ(NONE, attributes); 272 DCHECK_EQ(NONE, attributes);
245 273
246 // Skip var re-declarations. 274 // Skip var re-declarations.
247 if (is_var) return isolate->heap()->undefined_value(); 275 if (is_var) return isolate->heap()->undefined_value();
248 276
249 DCHECK(is_function); 277 DCHECK(is_function);
250 if (index != Context::kNotFound) { 278 if (index != Context::kNotFound) {
(...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 static Object* FindNameClash(Handle<ScopeInfo> scope_info, 602 static Object* FindNameClash(Handle<ScopeInfo> scope_info,
575 Handle<JSGlobalObject> global_object, 603 Handle<JSGlobalObject> global_object,
576 Handle<ScriptContextTable> script_context) { 604 Handle<ScriptContextTable> script_context) {
577 Isolate* isolate = scope_info->GetIsolate(); 605 Isolate* isolate = scope_info->GetIsolate();
578 for (int var = 0; var < scope_info->ContextLocalCount(); var++) { 606 for (int var = 0; var < scope_info->ContextLocalCount(); var++) {
579 Handle<String> name(scope_info->ContextLocalName(var)); 607 Handle<String> name(scope_info->ContextLocalName(var));
580 VariableMode mode = scope_info->ContextLocalMode(var); 608 VariableMode mode = scope_info->ContextLocalMode(var);
581 ScriptContextTable::LookupResult lookup; 609 ScriptContextTable::LookupResult lookup;
582 if (ScriptContextTable::Lookup(script_context, name, &lookup)) { 610 if (ScriptContextTable::Lookup(script_context, name, &lookup)) {
583 if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(lookup.mode)) { 611 if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(lookup.mode)) {
584 return ThrowRedeclarationError(isolate, name); 612 // ES#sec-globaldeclarationinstantiation 5.b:
613 // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError
614 // exception.
615 return ThrowRedeclarationError(isolate, name,
616 RedeclarationType::kSyntaxError);
585 } 617 }
586 } 618 }
587 619
588 if (IsLexicalVariableMode(mode)) { 620 if (IsLexicalVariableMode(mode)) {
589 LookupIterator it(global_object, name, global_object, 621 LookupIterator it(global_object, name, global_object,
590 LookupIterator::OWN_SKIP_INTERCEPTOR); 622 LookupIterator::OWN_SKIP_INTERCEPTOR);
591 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); 623 Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
592 if (!maybe.IsJust()) return isolate->heap()->exception(); 624 if (!maybe.IsJust()) return isolate->heap()->exception();
593 if ((maybe.FromJust() & DONT_DELETE) != 0) { 625 if ((maybe.FromJust() & DONT_DELETE) != 0) {
594 return ThrowRedeclarationError(isolate, name); 626 // ES#sec-globaldeclarationinstantiation 5.a:
627 // If envRec.HasVarDeclaration(name) is true, throw a SyntaxError
628 // exception.
629 // ES#sec-globaldeclarationinstantiation 5.d:
630 // If hasRestrictedGlobal is true, throw a SyntaxError exception.
631 return ThrowRedeclarationError(isolate, name,
632 RedeclarationType::kSyntaxError);
595 } 633 }
596 634
597 JSGlobalObject::InvalidatePropertyCell(global_object, name); 635 JSGlobalObject::InvalidatePropertyCell(global_object, name);
598 } 636 }
599 } 637 }
600 return isolate->heap()->undefined_value(); 638 return isolate->heap()->undefined_value();
601 } 639 }
602 640
603 641
604 RUNTIME_FUNCTION(Runtime_NewScriptContext) { 642 RUNTIME_FUNCTION(Runtime_NewScriptContext) {
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
990 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) { 1028 RUNTIME_FUNCTION(Runtime_StoreLookupSlot_Strict) {
991 HandleScope scope(isolate); 1029 HandleScope scope(isolate);
992 DCHECK_EQ(2, args.length()); 1030 DCHECK_EQ(2, args.length());
993 CONVERT_ARG_HANDLE_CHECKED(String, name, 0); 1031 CONVERT_ARG_HANDLE_CHECKED(String, name, 0);
994 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1); 1032 CONVERT_ARG_HANDLE_CHECKED(Object, value, 1);
995 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT)); 1033 RETURN_RESULT_OR_FAILURE(isolate, StoreLookupSlot(name, value, STRICT));
996 } 1034 }
997 1035
998 } // namespace internal 1036 } // namespace internal
999 } // namespace v8 1037 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/es6/block-eval-var-over-let.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698