Index: src/runtime/runtime-scopes.cc |
diff --git a/src/runtime/runtime-scopes.cc b/src/runtime/runtime-scopes.cc |
index 5ba0f5871abfabac7d7027c4ba3ff4df9b9dc65a..0bdbe2e44172da6f9a0efd3bac703ba0aafc8a5e 100644 |
--- a/src/runtime/runtime-scopes.cc |
+++ b/src/runtime/runtime-scopes.cc |
@@ -16,10 +16,18 @@ |
namespace v8 { |
namespace internal { |
-static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name) { |
+enum class RedeclarationType { kSyntaxError = 0, kTypeError = 1 }; |
+ |
+static Object* ThrowRedeclarationError(Isolate* isolate, Handle<String> name, |
+ RedeclarationType redeclaration_type) { |
HandleScope scope(isolate); |
- THROW_NEW_ERROR_RETURN_FAILURE( |
- isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name)); |
+ if (redeclaration_type == RedeclarationType::kSyntaxError) { |
+ THROW_NEW_ERROR_RETURN_FAILURE( |
+ isolate, NewSyntaxError(MessageTemplate::kVarRedeclaration, name)); |
+ } else { |
+ THROW_NEW_ERROR_RETURN_FAILURE( |
+ isolate, NewTypeError(MessageTemplate::kVarRedeclaration, name)); |
+ } |
} |
@@ -34,13 +42,18 @@ RUNTIME_FUNCTION(Runtime_ThrowConstAssignError) { |
static Object* DeclareGlobals(Isolate* isolate, Handle<JSGlobalObject> global, |
Handle<String> name, Handle<Object> value, |
PropertyAttributes attr, bool is_var, |
- bool is_function) { |
+ bool is_function, |
+ RedeclarationType redeclaration_type) { |
Handle<ScriptContextTable> script_contexts( |
global->native_context()->script_context_table()); |
ScriptContextTable::LookupResult lookup; |
if (ScriptContextTable::Lookup(script_contexts, name, &lookup) && |
IsLexicalVariableMode(lookup.mode)) { |
- return ThrowRedeclarationError(isolate, name); |
+ // ES#sec-globaldeclarationinstantiation 6.a: |
+ // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError |
+ // exception. |
+ return ThrowRedeclarationError(isolate, name, |
+ RedeclarationType::kSyntaxError); |
} |
// Do the lookup own properties only, see ES5 erratum. |
@@ -67,7 +80,11 @@ static Object* DeclareGlobals(Isolate* isolate, Handle<JSGlobalObject> global, |
if (old_details.IsReadOnly() || old_details.IsDontEnum() || |
(it.state() == LookupIterator::ACCESSOR && |
it.GetAccessors()->IsAccessorPair())) { |
- return ThrowRedeclarationError(isolate, name); |
+ // ES#sec-globaldeclarationinstantiation 5.d: |
+ // If hasRestrictedGlobal is true, throw a SyntaxError exception. |
+ // ES#sec-evaldeclarationinstantiation 8.a.iv.1.b: |
+ // If fnDefinable is false, throw a TypeError exception. |
+ return ThrowRedeclarationError(isolate, name, redeclaration_type); |
} |
// If the existing property is not configurable, keep its attributes. Do |
attr = old_attributes; |
@@ -130,9 +147,11 @@ RUNTIME_FUNCTION(Runtime_DeclareGlobals) { |
if (is_function && is_native) attr |= READ_ONLY; |
if (!is_eval) attr |= DONT_DELETE; |
- Object* result = DeclareGlobals(isolate, global, name, value, |
- static_cast<PropertyAttributes>(attr), |
- is_var, is_function); |
+ // ES#sec-globaldeclarationinstantiation 5.d: |
+ // If hasRestrictedGlobal is true, throw a SyntaxError exception. |
+ Object* result = DeclareGlobals( |
+ isolate, global, name, value, static_cast<PropertyAttributes>(attr), |
+ is_var, is_function, RedeclarationType::kSyntaxError); |
if (isolate->has_pending_exception()) return result; |
}); |
@@ -214,7 +233,13 @@ Object* DeclareEvalHelper(Isolate* isolate, Handle<String> name, |
// Check for a conflict with a lexically scoped variable |
context_arg->Lookup(name, LEXICAL_TEST, &index, &attributes, &binding_flags); |
if (attributes != ABSENT && binding_flags == BINDING_CHECK_INITIALIZED) { |
- return ThrowRedeclarationError(isolate, name); |
+ // ES#sec-evaldeclarationinstantiation 5.a.i.1: |
+ // If varEnvRec.HasLexicalDeclaration(name) is true, throw a SyntaxError |
+ // exception. |
+ // ES#sec-evaldeclarationinstantiation 5.d.ii.2.a.i: |
+ // Throw a SyntaxError exception. |
+ return ThrowRedeclarationError(isolate, name, |
+ RedeclarationType::kSyntaxError); |
} |
Handle<Object> holder = context->Lookup(name, DONT_FOLLOW_CHAINS, &index, |
@@ -224,20 +249,23 @@ Object* DeclareEvalHelper(Isolate* isolate, Handle<String> name, |
Handle<JSObject> object; |
if (attributes != ABSENT && holder->IsJSGlobalObject()) { |
+ // ES#sec-evaldeclarationinstantiation 8.a.iv.1.b: |
+ // If fnDefinable is false, throw a TypeError exception. |
return DeclareGlobals(isolate, Handle<JSGlobalObject>::cast(holder), name, |
- value, NONE, is_var, is_function); |
+ value, NONE, is_var, is_function, |
+ RedeclarationType::kTypeError); |
} |
if (context_arg->extension()->IsJSGlobalObject()) { |
Handle<JSGlobalObject> global( |
JSGlobalObject::cast(context_arg->extension()), isolate); |
return DeclareGlobals(isolate, global, name, value, NONE, is_var, |
- is_function); |
+ is_function, RedeclarationType::kTypeError); |
} else if (context->IsScriptContext()) { |
DCHECK(context->global_object()->IsJSGlobalObject()); |
Handle<JSGlobalObject> global( |
JSGlobalObject::cast(context->global_object()), isolate); |
return DeclareGlobals(isolate, global, name, value, NONE, is_var, |
- is_function); |
+ is_function, RedeclarationType::kTypeError); |
} |
if (attributes != ABSENT) { |
@@ -581,7 +609,11 @@ static Object* FindNameClash(Handle<ScopeInfo> scope_info, |
ScriptContextTable::LookupResult lookup; |
if (ScriptContextTable::Lookup(script_context, name, &lookup)) { |
if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(lookup.mode)) { |
- return ThrowRedeclarationError(isolate, name); |
+ // ES#sec-globaldeclarationinstantiation 5.b: |
+ // If envRec.HasLexicalDeclaration(name) is true, throw a SyntaxError |
+ // exception. |
+ return ThrowRedeclarationError(isolate, name, |
+ RedeclarationType::kSyntaxError); |
} |
} |
@@ -591,7 +623,13 @@ static Object* FindNameClash(Handle<ScopeInfo> scope_info, |
Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it); |
if (!maybe.IsJust()) return isolate->heap()->exception(); |
if ((maybe.FromJust() & DONT_DELETE) != 0) { |
- return ThrowRedeclarationError(isolate, name); |
+ // ES#sec-globaldeclarationinstantiation 5.a: |
+ // If envRec.HasVarDeclaration(name) is true, throw a SyntaxError |
+ // exception. |
+ // ES#sec-globaldeclarationinstantiation 5.d: |
+ // If hasRestrictedGlobal is true, throw a SyntaxError exception. |
+ return ThrowRedeclarationError(isolate, name, |
+ RedeclarationType::kSyntaxError); |
} |
JSGlobalObject::InvalidatePropertyCell(global_object, name); |