Chromium Code Reviews| Index: src/scopes.cc |
| diff --git a/src/scopes.cc b/src/scopes.cc |
| index faedb5f085871a358807675d50a543666ae27bb9..55c219fc9cffc41bc5c8f088b622229fe39dc387 100644 |
| --- a/src/scopes.cc |
| +++ b/src/scopes.cc |
| @@ -29,6 +29,7 @@ |
| #include "scopes.h" |
| +#include "accessors.h" |
| #include "bootstrapper.h" |
| #include "compiler.h" |
| #include "messages.h" |
| @@ -226,6 +227,12 @@ Scope* Scope::DeserializeScopeChain(Context* context, Scope* global_scope, |
| for (Scope* s = innermost_scope; s != NULL; s = s->outer_scope()) { |
| s->scope_inside_with_ = true; |
| } |
| + } else if (context->IsModuleContext()) { |
| + ScopeInfo* scope_info = ScopeInfo::cast(context->module()->scope_info()); |
| + current_scope = new(zone) Scope(current_scope, |
| + MODULE_SCOPE, |
| + Handle<ScopeInfo>(scope_info), |
| + zone); |
| } else if (context->IsFunctionContext()) { |
| ScopeInfo* scope_info = context->closure()->shared()->scope_info(); |
| current_scope = new(zone) Scope(current_scope, |
| @@ -634,6 +641,14 @@ bool Scope::AllocateVariables(CompilationInfo* info, |
| // 3) Allocate variables. |
| AllocateVariablesRecursively(); |
| + // 4) Allocate and link module instance objects. |
| + if (FLAG_harmony_modules) { |
| + if (is_global_scope() || is_module_scope()) { |
|
Michael Starzinger
2012/07/06 10:53:22
Can we merge that into one condition?
rossberg
2012/07/06 15:39:28
Done.
|
| + AllocateModules(info); |
| + LinkModules(info); |
| + } |
| + } |
| + |
| return true; |
| } |
| @@ -1111,7 +1126,8 @@ bool Scope::MustAllocate(Variable* var) { |
| inner_scope_calls_eval_ || |
| scope_contains_with_ || |
| is_catch_scope() || |
| - is_block_scope())) { |
| + is_block_scope() || |
| + is_module_scope())) { |
| var->set_is_used(true); |
| } |
| // Global variables do not need to be allocated. |
| @@ -1299,4 +1315,76 @@ int Scope::ContextLocalCount() const { |
| (function_ != NULL && function_->proxy()->var()->IsContextSlot() ? 1 : 0); |
| } |
| + |
| +void Scope::AllocateModules(CompilationInfo* info) { |
| + ASSERT(is_global_scope() || is_module_scope()); |
| + |
| + if (is_module_scope()) { |
| + ASSERT(interface_->IsFrozen()); |
| + ASSERT(scope_info_.is_null()); |
| + |
| + // TODO(rossberg): This has to be the initial compilation of this code. |
| + // We currently do not allow recompiling any module definitions. |
| + Handle<ScopeInfo> scope_info = GetScopeInfo(); |
| + Factory* factory = info->isolate()->factory(); |
| + Handle<Context> context = factory->NewModuleContext(scope_info); |
| + Handle<JSModule> instance = factory->NewJSModule(context, scope_info); |
| + context->set_module(*instance); |
| + |
| + bool ok; |
| + interface_->MakeSingleton(instance, &ok); |
| + ASSERT(ok); |
| + } |
| + |
| + // Allocate nested modules. |
| + for (int i = 0; i < inner_scopes_.length(); i++) { |
| + Scope* inner_scope = inner_scopes_.at(i); |
| + if (inner_scope->is_module_scope()) { |
| + inner_scope->AllocateModules(info); |
| + } |
| + } |
| +} |
| + |
| + |
| +void Scope::LinkModules(CompilationInfo* info) { |
| + ASSERT(is_global_scope() || is_module_scope()); |
| + |
| + if (is_module_scope()) { |
| + Handle<JSModule> instance = interface_->Instance(); |
| + |
| + // Populate the module instance object. |
| + const PropertyAttributes ro_attr = |
| + static_cast<PropertyAttributes>(READ_ONLY | DONT_DELETE | DONT_ENUM); |
| + const PropertyAttributes rw_attr = |
| + static_cast<PropertyAttributes>(DONT_DELETE | DONT_ENUM); |
| + for (Interface::Iterator it = interface_->iterator(); |
| + !it.done(); it.Advance()) { |
| + if (it.interface()->IsModule()) { |
| + Handle<Object> value = it.interface()->Instance(); |
| + ASSERT(!value.is_null()); |
| + JSReceiver::SetProperty( |
| + instance, it.name(), value, ro_attr, kStrictMode); |
| + } else { |
| + Variable* var = LocalLookup(it.name()); |
| + ASSERT(var != NULL && var->IsContextSlot()); |
| + PropertyAttributes attr = var->is_const_mode() ? ro_attr : rw_attr; |
| + Handle<AccessorInfo> info = |
| + Accessors::MakeModuleExport(it.name(), var->index(), attr); |
| + Handle<Object> result = SetAccessor(instance, info); |
| + ASSERT(!(result.is_null() || result->IsUndefined())); |
| + } |
| + } |
| + USE(instance->PreventExtensions()); |
|
Michael Starzinger
2012/07/06 10:53:22
This might request a GC, so you should use JSObjec
rossberg
2012/07/06 15:39:28
Done.
|
| + } |
| + |
| + // Link nested modules. |
| + for (int i = 0; i < inner_scopes_.length(); i++) { |
| + Scope* inner_scope = inner_scopes_.at(i); |
| + if (inner_scope->is_module_scope()) { |
| + inner_scope->LinkModules(info); |
| + } |
| + } |
| +} |
| + |
| + |
| } } // namespace v8::internal |