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

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: 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 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
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
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
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
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
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