MIPS: Implement rudimentary module linking.

Port r11336 (6dd4e844)

Original commit message:

Implement rudimentary module linking.

Constructs the (generally cyclic) graph of module instance objects
and populates their exports. Any exports other than nested modules
are currently set to 'undefined' (but already present as properties).

Details:
- Added new type JSModule for instance objects: a JSObject carrying a context.
- Statically allocate instance objects for all module literals (in parser 8-}).
- Extend interfaces to record and unify concrete instance objects,
and to support iteration over members.
- Introduce new runtime function for pushing module contexts.
- Generate code for allocating, initializing, and setting module contexts,
and for populating instance objects from module literals.
Currently, all non-module exports are still initialized with 'undefined'.
- Module aliases are resolved statically, so no special code is required.
- Make sure that code containing module constructs is never optimized
(macrofy AST node construction flag setting while we're at it).
- Add test case checking linkage.

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/10035028

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11374 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
rossberg@chromium.org 2012-04-18 15:48:01 +00:00
parent 1aa16d8689
commit 977b602727

View File

@ -817,10 +817,10 @@ void FullCodeGenerator::VisitVariableDeclaration(
bool hole_init = mode == CONST || mode == CONST_HARMONY || mode == LET;
switch (variable->location()) {
case Variable::UNALLOCATED:
globals_.Add(variable->name());
globals_.Add(variable->binding_needs_init()
? isolate()->factory()->the_hole_value()
: isolate()->factory()->undefined_value());
globals_->Add(variable->name());
globals_->Add(variable->binding_needs_init()
? isolate()->factory()->the_hole_value()
: isolate()->factory()->undefined_value());
break;
case Variable::PARAMETER:
@ -877,12 +877,12 @@ void FullCodeGenerator::VisitFunctionDeclaration(
Variable* variable = proxy->var();
switch (variable->location()) {
case Variable::UNALLOCATED: {
globals_.Add(variable->name());
globals_->Add(variable->name());
Handle<SharedFunctionInfo> function =
Compiler::BuildFunctionInfo(declaration->fun(), script());
// Check for stack-overflow exception.
if (function.is_null()) return SetStackOverflow();
globals_.Add(function);
globals_->Add(function);
break;
}
@ -930,15 +930,24 @@ void FullCodeGenerator::VisitFunctionDeclaration(
void FullCodeGenerator::VisitModuleDeclaration(ModuleDeclaration* declaration) {
VariableProxy* proxy = declaration->proxy();
Variable* variable = proxy->var();
Handle<JSModule> instance = declaration->module()->interface()->Instance();
ASSERT(!instance.is_null());
switch (variable->location()) {
case Variable::UNALLOCATED:
// TODO(rossberg): initialize module instance object
case Variable::UNALLOCATED: {
Comment cmnt(masm_, "[ ModuleDeclaration");
globals_->Add(variable->name());
globals_->Add(instance);
Visit(declaration->module());
break;
}
case Variable::CONTEXT: {
Comment cmnt(masm_, "[ ModuleDeclaration");
EmitDebugCheckDeclarationContext(variable);
// TODO(rossberg): initialize module instance object
__ li(a1, Operand(instance));
__ sw(a1, ContextOperand(cp, variable->index()));
Visit(declaration->module());
break;
}
@ -4575,7 +4584,8 @@ void FullCodeGenerator::LoadContextField(Register dst, int context_index) {
void FullCodeGenerator::PushFunctionArgumentForContextAllocation() {
Scope* declaration_scope = scope()->DeclarationScope();
if (declaration_scope->is_global_scope()) {
if (declaration_scope->is_global_scope() ||
declaration_scope->is_module_scope()) {
// Contexts nested in the global context have a canonical empty function
// as their closure, not the anonymous closure containing the global
// code. Pass a smi sentinel and let the runtime look up the empty