| Index: src/runtime/runtime-scopes.cc
|
| diff --git a/src/runtime/runtime-scopes.cc b/src/runtime/runtime-scopes.cc
|
| index c935cdabef7728503710995105291e5da72eca51..af23dec1cd80df897965eb80972554e02c4423e9 100644
|
| --- a/src/runtime/runtime-scopes.cc
|
| +++ b/src/runtime/runtime-scopes.cc
|
| @@ -27,6 +27,14 @@ static Object* DeclareGlobals(Isolate* isolate, Handle<GlobalObject> global,
|
| Handle<String> name, Handle<Object> value,
|
| PropertyAttributes attr, bool is_var,
|
| bool is_const, bool is_function) {
|
| + Handle<GlobalContextTable> global_contexts(
|
| + global->native_context()->global_context_table());
|
| + GlobalContextTable::LookupResult lookup;
|
| + if (GlobalContextTable::Lookup(global_contexts, name, &lookup) &&
|
| + IsLexicalVariableMode(lookup.mode)) {
|
| + return ThrowRedeclarationError(isolate, name);
|
| + }
|
| +
|
| // Do the lookup own properties only, see ES5 erratum.
|
| LookupIterator it(global, name, LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
|
| Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
|
| @@ -507,6 +515,35 @@ RUNTIME_FUNCTION(Runtime_NewClosure) {
|
| pretenure_flag);
|
| }
|
|
|
| +static Object* FindNameClash(Handle<ScopeInfo> scope_info,
|
| + Handle<GlobalObject> global_object,
|
| + Handle<GlobalContextTable> global_context) {
|
| + Isolate* isolate = scope_info->GetIsolate();
|
| + for (int var = 0; var < scope_info->ContextLocalCount(); var++) {
|
| + Handle<String> name(scope_info->ContextLocalName(var));
|
| + VariableMode mode = scope_info->ContextLocalMode(var);
|
| + GlobalContextTable::LookupResult lookup;
|
| + if (GlobalContextTable::Lookup(global_context, name, &lookup)) {
|
| + if (IsLexicalVariableMode(mode) || IsLexicalVariableMode(lookup.mode)) {
|
| + return ThrowRedeclarationError(isolate, name);
|
| + }
|
| + }
|
| +
|
| + if (IsLexicalVariableMode(mode)) {
|
| + LookupIterator it(global_object, name,
|
| + LookupIterator::HIDDEN_SKIP_INTERCEPTOR);
|
| + Maybe<PropertyAttributes> maybe = JSReceiver::GetPropertyAttributes(&it);
|
| + if (!maybe.has_value) return isolate->heap()->exception();
|
| + if ((maybe.value & DONT_DELETE) != 0) {
|
| + return ThrowRedeclarationError(isolate, name);
|
| + }
|
| +
|
| + GlobalObject::InvalidatePropertyCell(global_object, name);
|
| + }
|
| + }
|
| + return isolate->heap()->undefined_value();
|
| +}
|
| +
|
|
|
| RUNTIME_FUNCTION(Runtime_NewGlobalContext) {
|
| HandleScope scope(isolate);
|
| @@ -514,12 +551,25 @@ RUNTIME_FUNCTION(Runtime_NewGlobalContext) {
|
|
|
| CONVERT_ARG_HANDLE_CHECKED(JSFunction, function, 0);
|
| CONVERT_ARG_HANDLE_CHECKED(ScopeInfo, scope_info, 1);
|
| + Handle<GlobalObject> global_object(function->context()->global_object());
|
| + Handle<Context> native_context(global_object->native_context());
|
| + Handle<GlobalContextTable> global_context_table(
|
| + native_context->global_context_table());
|
| +
|
| + Handle<String> clashed_name;
|
| + Object* name_clash_result =
|
| + FindNameClash(scope_info, global_object, global_context_table);
|
| + if (isolate->has_pending_exception()) return name_clash_result;
|
| +
|
| Handle<Context> result =
|
| isolate->factory()->NewGlobalContext(function, scope_info);
|
|
|
| DCHECK(function->context() == isolate->context());
|
| DCHECK(function->context()->global_object() == result->global_object());
|
| - result->global_object()->set_global_context(*result);
|
| +
|
| + Handle<GlobalContextTable> new_global_context_table =
|
| + GlobalContextTable::Extend(global_context_table, result);
|
| + native_context->set_global_context_table(*new_global_context_table);
|
| return *result;
|
| }
|
|
|
|
|