jitcraft/BytecodeCompiler.cpp
changeset 85 06a0015b6a5c
parent 83 79265b56316e
     1.1 --- a/jitcraft/BytecodeCompiler.cpp	Fri Jul 20 00:03:10 2012 -0700
     1.2 +++ b/jitcraft/BytecodeCompiler.cpp	Mon Jul 23 01:19:44 2012 -0700
     1.3 @@ -23,6 +23,7 @@
     1.4  #include "Array.h"
     1.5  #include "Strings.h"
     1.6  #include "Zone.h"
     1.7 +#include "Environments.h"
     1.8  #include "Heap-inl.h"
     1.9  
    1.10  using namespace ke;
    1.11 @@ -156,6 +157,8 @@
    1.12          if (var->location() == Variable::STACK) {
    1.13              __ getlocal(var);
    1.14              assert(!name->type()->isReference());
    1.15 +        } else if (var->location() == Variable::ENVIRONMENT) {
    1.16 +            getEnvSlot(var);
    1.17          } else {
    1.18              assert(var->location() == Variable::PARAMETER);
    1.19              __ getarg(var);
    1.20 @@ -697,16 +700,34 @@
    1.21  }
    1.22  
    1.23  void
    1.24 +BytecodeCompiler::getEnvSlot(Variable *var)
    1.25 +{
    1.26 +    assert(var->scope()->kind() == Scope::GLOBAL);
    1.27 +    __ getglobal(var);
    1.28 +}
    1.29 +
    1.30 +void
    1.31 +BytecodeCompiler::setEnvSlot(Variable *var)
    1.32 +{
    1.33 +    assert(var->scope()->kind() == Scope::GLOBAL);
    1.34 +    __ setglobal(var);
    1.35 +}
    1.36 +
    1.37 +void
    1.38  BytecodeCompiler::visit(VariableDeclaration *node)
    1.39  {
    1.40      Variable *var = node->variable();
    1.41 -    assert(var->location() == Variable::STACK);
    1.42      
    1.43      Local<Type> type(zone_, var->type());
    1.44      if (type->isArray()) {
    1.45          Local<ArrayMap> map(zone_, BuildArrayMap(zone_, type));
    1.46          __ note_position(node->pos());
    1.47 -        __ newarray_lifo(map);
    1.48 +        if (var->scope()->kind() == Scope::GLOBAL)
    1.49 +            __ newarray(map, Heap::Tenure_Old);
    1.50 +        else if (var->needsHeapAllocation())
    1.51 +            __ newarray(map, Heap::Tenure_Default);
    1.52 +        else
    1.53 +            __ newarray(map, Heap::Tenure_Stack);
    1.54  
    1.55          if (node->initialization()) {
    1.56              node->initialization()->accept(this);
    1.57 @@ -721,10 +742,16 @@
    1.58                  __ int_(0);
    1.59          }
    1.60      }
    1.61 -    __ setlocal(var);
    1.62 +
    1.63 +    if (var->location() == Variable::STACK) {
    1.64 +        __ setlocal(var);
    1.65 +        locals_->set(zone_, var->slot(), var->type());
    1.66 +    } else {
    1.67 +        assert(var->location() == Variable::ENVIRONMENT);
    1.68 +        setEnvSlot(var);
    1.69 +    }
    1.70 +
    1.71      __ pop();
    1.72 -
    1.73 -    locals_->set(zone_, var->slot(), var->type());
    1.74  }
    1.75  
    1.76  void
    1.77 @@ -875,18 +902,9 @@
    1.78      // :TODO: eventually, we'll export these.
    1.79  }
    1.80  
    1.81 -Function *
    1.82 -BytecodeCompiler::compileFunction(ModuleData *module, FunctionStatement *node)
    1.83 +Code *
    1.84 +BytecodeCompiler::compileCode(Scope *scope, unsigned lineno)
    1.85  {
    1.86 -    // Note: No need to record a life slot here, since it's part of the Frame.
    1.87 -    AutoEnterScope functionScope(this, node->scope());
    1.88 -
    1.89 -    // Set the initial line, because line mappings are deltas.
    1.90 -    __ setFirstLine(node->pos().line);
    1.91 -    locals_ = FixedArray::New(zone_, node->scope()->maxContainedLocals(), Heap::Tenure_Old);
    1.92 -
    1.93 -    node->body()->accept(this);
    1.94 -
    1.95      // STOP doubles as RETURNVOID.
    1.96      __ stop();
    1.97  
    1.98 @@ -898,15 +916,7 @@
    1.99          return NULL;
   1.100      memcpy(bytes->raw(), __ buffer(), __ length());
   1.101  
   1.102 -    unsigned nargs = node->scope()->numArguments();
   1.103 -    Local<FixedArray> args(zone_, FixedArray::New(zone_, nargs, Heap::Tenure_Old));
   1.104 -    if (!args)
   1.105 -        return NULL;
   1.106 -
   1.107 -    for (size_t i = 0; i < node->scope()->numArguments(); i++)
   1.108 -        args->set(zone_, i, node->scope()->getArgument(i)->type());
   1.109 -
   1.110 -    for (size_t i = 0; i < node->scope()->maxContainedLocals(); i++)
   1.111 +    for (size_t i = 0; i < scope->maxContainedLocals(); i++)
   1.112          assert(locals_->at(i));
   1.113  
   1.114      Local<FixedArray> objects(zone_, FixedArray::New(zone_, __ objects()->length(), Heap::Tenure_Old));
   1.115 @@ -965,7 +975,32 @@
   1.116                       moduleData_->module,
   1.117                       safepoints,
   1.118                       sourcemap,
   1.119 -                     node->pos().line);
   1.120 +                     lineno);
   1.121 +    return code;
   1.122 +}
   1.123 +
   1.124 +Function *
   1.125 +BytecodeCompiler::compileFunction(ModuleData *module, FunctionStatement *node)
   1.126 +{
   1.127 +    // Note: No need to record a life slot here, since it's part of the Frame.
   1.128 +    AutoEnterScope functionScope(this, node->scope());
   1.129 +
   1.130 +    // Set the initial line, because line mappings are deltas.
   1.131 +    __ setFirstLine(node->pos().line);
   1.132 +    locals_ = FixedArray::New(zone_, node->scope()->maxContainedLocals(), Heap::Tenure_Old);
   1.133 +
   1.134 +    node->body()->accept(this);
   1.135 +
   1.136 +    unsigned nargs = node->scope()->numArguments();
   1.137 +    Local<FixedArray> args(zone_, FixedArray::New(zone_, nargs, Heap::Tenure_Old));
   1.138 +    if (!args)
   1.139 +        return NULL;
   1.140 +
   1.141 +    for (size_t i = 0; i < node->scope()->numArguments(); i++)
   1.142 +        args->set(zone_, i, node->scope()->getArgument(i)->type());
   1.143 +
   1.144 +
   1.145 +    Local<Code> code(zone_, compileCode(node->scope(), node->pos().line));
   1.146      if (!code)
   1.147          return NULL;
   1.148  
   1.149 @@ -993,6 +1028,8 @@
   1.150  Module *
   1.151  BytecodeCompiler::compile()
   1.152  {
   1.153 +    AutoEnterScope scope(this, tree_->scope());
   1.154 +
   1.155      ModuleData moduleData;
   1.156  
   1.157      moduleData_ = &moduleData;
   1.158 @@ -1035,5 +1072,25 @@
   1.159  
   1.160      moduleData_->module->setNatives(moduleData_->natives);
   1.161  
   1.162 +    if (scope_->numEnvironmentVars()) {
   1.163 +        Local<EnvironmentMap> globalMap(zone_, scope_->createEnvironmentMap(zone_));
   1.164 +        if (!globalMap)
   1.165 +            return NULL;
   1.166 +
   1.167 +        Local<Environment> environment(zone_, Environment::New(zone_, globalMap));
   1.168 +        if (!environment)
   1.169 +            return NULL;
   1.170 +
   1.171 +        moduleData_->module->setEnvironment(environment);
   1.172 +    }
   1.173 +
   1.174 +    Local<Code> code(zone_, compileCode(tree_->scope(), 1));
   1.175 +    if (!code)
   1.176 +        return NULL;
   1.177 +
   1.178 +    Disassemble(code, stdout);
   1.179 +
   1.180 +    moduleData_->module->setCode(code);
   1.181 +
   1.182      return moduleData_->module;
   1.183  }