Index: src/full-codegen.cc |
diff --git a/src/full-codegen.cc b/src/full-codegen.cc |
index 6b260531cbc8a375ca44f723ecd068e698716370..a6f4c49578298beacceead305ffa8fd5f347eae8 100644 |
--- a/src/full-codegen.cc |
+++ b/src/full-codegen.cc |
@@ -570,32 +570,94 @@ void FullCodeGenerator::DoTest(const TestContext* context) { |
void FullCodeGenerator::VisitDeclarations( |
ZoneList<Declaration*>* declarations) { |
- ASSERT(globals_.is_empty()); |
+ ZoneList<Handle<Object> >* saved_globals = globals_; |
+ ZoneList<Handle<Object> > inner_globals(10); |
+ globals_ = &inner_globals; |
+ |
AstVisitor::VisitDeclarations(declarations); |
- if (!globals_.is_empty()) { |
+ if (!globals_->is_empty()) { |
// Invoke the platform-dependent code generator to do the actual |
// declaration the global functions and variables. |
Handle<FixedArray> array = |
- isolate()->factory()->NewFixedArray(globals_.length(), TENURED); |
- for (int i = 0; i < globals_.length(); ++i) array->set(i, *globals_.at(i)); |
+ isolate()->factory()->NewFixedArray(globals_->length(), TENURED); |
+ for (int i = 0; i < globals_->length(); ++i) |
+ array->set(i, *globals_->at(i)); |
DeclareGlobals(array); |
- globals_.Clear(); |
} |
+ |
+ globals_ = saved_globals; |
} |
void FullCodeGenerator::VisitModuleLiteral(ModuleLiteral* module) { |
- // TODO(rossberg) |
+ Handle<JSModule> instance = module->interface()->Instance(); |
+ ASSERT(!instance.is_null()); |
+ |
+ // Allocate a module context statically. |
+ Block* block = module->body(); |
+ Scope* saved_scope = scope(); |
+ scope_ = block->scope(); |
+ Handle<ScopeInfo> scope_info = scope_->GetScopeInfo(); |
+ |
+ // Generate code for module creation and linking. |
+ Comment cmnt(masm_, "[ ModuleLiteral"); |
+ SetStatementPosition(block); |
+ |
+ if (scope_info->HasContext()) { |
+ // Set up module context. |
+ __ Push(scope_info); |
+ __ Push(instance); |
+ __ CallRuntime(Runtime::kPushModuleContext, 2); |
+ StoreToFrameField( |
+ StandardFrameConstants::kContextOffset, context_register()); |
+ } |
+ |
+ { |
+ Comment cmnt(masm_, "[ Declarations"); |
+ VisitDeclarations(scope_->declarations()); |
+ } |
+ |
+ scope_ = saved_scope; |
+ if (scope_info->HasContext()) { |
+ // Pop module context. |
+ LoadContextField(context_register(), Context::PREVIOUS_INDEX); |
+ // Update local stack frame context field. |
+ StoreToFrameField( |
+ StandardFrameConstants::kContextOffset, context_register()); |
+ } |
+ |
+ // Populate module instance object. |
+ const PropertyAttributes attr = |
+ static_cast<PropertyAttributes>(READ_ONLY + DONT_DELETE + DONT_ENUM); |
Sven Panne
2012/03/30 11:42:20
Style nit: In the rest of the code we use '|' inst
rossberg
2012/04/10 14:01:15
Done.
|
+ for (Interface::Iterator it = module->interface()->iterator(); |
+ !it.done(); it.Advance()) { |
+ if (it.interface()->IsModule()) { |
+ Handle<Object> value = it.interface()->Instance(); |
+ // TODO(rossberg): temporary hack until URL import is implemented: |
+ if (value.is_null()) |
+ value = Handle<Object>(isolate()->heap()->undefined_value()); |
+ ASSERT(!value.is_null()); |
Sven Panne
2012/03/30 11:42:20
Do we really need this after the test in the previ
rossberg
2012/04/10 14:01:15
Well, the assertion is supposed to stay, while the
|
+ JSReceiver::SetProperty(instance, it.name(), value, attr, kStrictMode); |
+ } else { |
+ // TODO(rossberg): set proper getters instead of undefined... |
+ // instance->DefineAccessor(*it.name(), ACCESSOR_GETTER, *getter, attr); |
+ Handle<Object> value(isolate()->heap()->undefined_value()); |
+ JSReceiver::SetProperty(instance, it.name(), value, attr, kStrictMode); |
+ } |
+ } |
+ USE(instance->PreventExtensions()); |
} |
void FullCodeGenerator::VisitModuleVariable(ModuleVariable* module) { |
- // TODO(rossberg) |
+ // Noting to do. |
+ // The instance object is resolved statically through the module's interface. |
} |
void FullCodeGenerator::VisitModulePath(ModulePath* module) { |
- // TODO(rossberg) |
+ // Noting to do. |
+ // The instance object is resolved statically through the module's interface. |
} |
@@ -857,9 +919,9 @@ void FullCodeGenerator::VisitBlock(Block* stmt) { |
Scope* saved_scope = scope(); |
// Push a block context when entering a block with block scoped variables. |
- if (stmt->block_scope() != NULL) { |
+ if (stmt->scope() != NULL) { |
{ Comment cmnt(masm_, "[ Extend block context"); |
- scope_ = stmt->block_scope(); |
+ scope_ = stmt->scope(); |
Handle<ScopeInfo> scope_info = scope_->GetScopeInfo(); |
int heap_slots = scope_info->ContextLength() - Context::MIN_CONTEXT_SLOTS; |
__ Push(scope_info); |
@@ -886,7 +948,7 @@ void FullCodeGenerator::VisitBlock(Block* stmt) { |
PrepareForBailoutForId(stmt->ExitId(), NO_REGISTERS); |
// Pop block context if necessary. |
- if (stmt->block_scope() != NULL) { |
+ if (stmt->scope() != NULL) { |
LoadContextField(context_register(), Context::PREVIOUS_INDEX); |
// Update local stack frame context field. |
StoreToFrameField(StandardFrameConstants::kContextOffset, |