diff -r eaa43f765cbd -r 06a0015b6a5c jitcraft/BytecodeCompiler.cpp --- a/jitcraft/BytecodeCompiler.cpp Fri Jul 20 00:03:10 2012 -0700 +++ b/jitcraft/BytecodeCompiler.cpp Mon Jul 23 01:19:44 2012 -0700 @@ -23,6 +23,7 @@ #include "Array.h" #include "Strings.h" #include "Zone.h" +#include "Environments.h" #include "Heap-inl.h" using namespace ke; @@ -156,6 +157,8 @@ if (var->location() == Variable::STACK) { __ getlocal(var); assert(!name->type()->isReference()); + } else if (var->location() == Variable::ENVIRONMENT) { + getEnvSlot(var); } else { assert(var->location() == Variable::PARAMETER); __ getarg(var); @@ -697,16 +700,34 @@ } void +BytecodeCompiler::getEnvSlot(Variable *var) +{ + assert(var->scope()->kind() == Scope::GLOBAL); + __ getglobal(var); +} + +void +BytecodeCompiler::setEnvSlot(Variable *var) +{ + assert(var->scope()->kind() == Scope::GLOBAL); + __ setglobal(var); +} + +void BytecodeCompiler::visit(VariableDeclaration *node) { Variable *var = node->variable(); - assert(var->location() == Variable::STACK); Local type(zone_, var->type()); if (type->isArray()) { Local map(zone_, BuildArrayMap(zone_, type)); __ note_position(node->pos()); - __ newarray_lifo(map); + if (var->scope()->kind() == Scope::GLOBAL) + __ newarray(map, Heap::Tenure_Old); + else if (var->needsHeapAllocation()) + __ newarray(map, Heap::Tenure_Default); + else + __ newarray(map, Heap::Tenure_Stack); if (node->initialization()) { node->initialization()->accept(this); @@ -721,10 +742,16 @@ __ int_(0); } } - __ setlocal(var); + + if (var->location() == Variable::STACK) { + __ setlocal(var); + locals_->set(zone_, var->slot(), var->type()); + } else { + assert(var->location() == Variable::ENVIRONMENT); + setEnvSlot(var); + } + __ pop(); - - locals_->set(zone_, var->slot(), var->type()); } void @@ -875,18 +902,9 @@ // :TODO: eventually, we'll export these. } -Function * -BytecodeCompiler::compileFunction(ModuleData *module, FunctionStatement *node) +Code * +BytecodeCompiler::compileCode(Scope *scope, unsigned lineno) { - // Note: No need to record a life slot here, since it's part of the Frame. - AutoEnterScope functionScope(this, node->scope()); - - // Set the initial line, because line mappings are deltas. - __ setFirstLine(node->pos().line); - locals_ = FixedArray::New(zone_, node->scope()->maxContainedLocals(), Heap::Tenure_Old); - - node->body()->accept(this); - // STOP doubles as RETURNVOID. __ stop(); @@ -898,15 +916,7 @@ return NULL; memcpy(bytes->raw(), __ buffer(), __ length()); - unsigned nargs = node->scope()->numArguments(); - Local args(zone_, FixedArray::New(zone_, nargs, Heap::Tenure_Old)); - if (!args) - return NULL; - - for (size_t i = 0; i < node->scope()->numArguments(); i++) - args->set(zone_, i, node->scope()->getArgument(i)->type()); - - for (size_t i = 0; i < node->scope()->maxContainedLocals(); i++) + for (size_t i = 0; i < scope->maxContainedLocals(); i++) assert(locals_->at(i)); Local objects(zone_, FixedArray::New(zone_, __ objects()->length(), Heap::Tenure_Old)); @@ -965,7 +975,32 @@ moduleData_->module, safepoints, sourcemap, - node->pos().line); + lineno); + return code; +} + +Function * +BytecodeCompiler::compileFunction(ModuleData *module, FunctionStatement *node) +{ + // Note: No need to record a life slot here, since it's part of the Frame. + AutoEnterScope functionScope(this, node->scope()); + + // Set the initial line, because line mappings are deltas. + __ setFirstLine(node->pos().line); + locals_ = FixedArray::New(zone_, node->scope()->maxContainedLocals(), Heap::Tenure_Old); + + node->body()->accept(this); + + unsigned nargs = node->scope()->numArguments(); + Local args(zone_, FixedArray::New(zone_, nargs, Heap::Tenure_Old)); + if (!args) + return NULL; + + for (size_t i = 0; i < node->scope()->numArguments(); i++) + args->set(zone_, i, node->scope()->getArgument(i)->type()); + + + Local code(zone_, compileCode(node->scope(), node->pos().line)); if (!code) return NULL; @@ -993,6 +1028,8 @@ Module * BytecodeCompiler::compile() { + AutoEnterScope scope(this, tree_->scope()); + ModuleData moduleData; moduleData_ = &moduleData; @@ -1035,5 +1072,25 @@ moduleData_->module->setNatives(moduleData_->natives); + if (scope_->numEnvironmentVars()) { + Local globalMap(zone_, scope_->createEnvironmentMap(zone_)); + if (!globalMap) + return NULL; + + Local environment(zone_, Environment::New(zone_, globalMap)); + if (!environment) + return NULL; + + moduleData_->module->setEnvironment(environment); + } + + Local code(zone_, compileCode(tree_->scope(), 1)); + if (!code) + return NULL; + + Disassemble(code, stdout); + + moduleData_->module->setCode(code); + return moduleData_->module; }