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

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

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