1.1 --- a/jitcraft/BytecodeCompiler.cpp Sat Jun 30 20:20:39 2012 -0700
1.2 +++ b/jitcraft/BytecodeCompiler.cpp Sat Jun 30 22:31:14 2012 -0700
1.3 @@ -29,10 +29,11 @@
1.4
1.5 #define __ emitter_.
1.6
1.7 -BytecodeCompiler::BytecodeCompiler(ParseTree *tree)
1.8 +BytecodeCompiler::BytecodeCompiler(ParseTree *tree, Module *module)
1.9 : tree_(tree),
1.10 scope_(NULL),
1.11 - loop_(NULL)
1.12 + loop_(NULL),
1.13 + module_(module)
1.14 {
1.15 }
1.16
1.17 @@ -133,10 +134,22 @@
1.18
1.19 if (var->location() == Variable::STACK) {
1.20 __ getlocal(var->slot());
1.21 + assert(!name->type()->isReference());
1.22 } else {
1.23 assert(var->location() == Variable::PARAMETER);
1.24 __ getarg(var->slot());
1.25 +
1.26 + // If this argument is actually a reference, dereference it now.
1.27 + if (var->type()->isReference()) {
1.28 + if (var->type()->isFloat()) {
1.29 + __ getref_f();
1.30 + } else {
1.31 + assert(name->type()->isInt());
1.32 + __ getref_i();
1.33 + }
1.34 + }
1.35 }
1.36 +
1.37 break;
1.38 }
1.39
1.40 @@ -165,12 +178,32 @@
1.41 NameProxy *proxy = node->lvalue()->toNameProxy();
1.42 Variable *var = proxy->binding()->toVariable();
1.43
1.44 + // Make sure to bind the left-hand side first.
1.45 + if (var->type()->isReference()) {
1.46 + if (var->location() == Variable::STACK) {
1.47 + __ getlocal(var->slot());
1.48 + } else {
1.49 + assert(var->location() == Variable::PARAMETER);
1.50 + __ getarg(var->slot());
1.51 + }
1.52 + }
1.53 +
1.54 node->expression()->accept(this);
1.55 - if (var->location() == Variable::STACK) {
1.56 - __ setlocal(var->slot());
1.57 +
1.58 + if (var->type()->isReference()) {
1.59 + if (var->type()->contained()->isFloat()) {
1.60 + __ setref_f();
1.61 + } else {
1.62 + assert(var->type()->contained()->isInt());
1.63 + __ setref_i();
1.64 + }
1.65 } else {
1.66 - assert(var->location() == Variable::PARAMETER);
1.67 - __ setarg(var->slot());
1.68 + if (var->location() == Variable::STACK) {
1.69 + __ setlocal(var->slot());
1.70 + } else {
1.71 + assert(var->location() == Variable::PARAMETER);
1.72 + __ setarg(var->slot());
1.73 + }
1.74 }
1.75 } else if (node->lvalue()->isIndexExpression()) {
1.76 IndexExpression *index = node->lvalue()->toIndexExpression();
1.77 @@ -408,9 +441,33 @@
1.78 {
1.79 NameProxy *fun = node->callee()->toNameProxy();
1.80
1.81 + // :TODO: use Local
1.82 + Type *funType = node->callee()->type();
1.83 +
1.84 for (size_t i = 0; i < node->arguments()->size(); i++) {
1.85 Expression *arg = node->arguments()->at(i);
1.86 - arg->accept(this);
1.87 +
1.88 + Type *given = arg->type();
1.89 + Type *actual = Type::cast(funType->parameters()->at(i));
1.90 + if (actual->isReference()) {
1.91 + if (given->isReference()) {
1.92 + // The input type is already a reference, so we're just passing
1.93 + // it on to the callee.
1.94 + arg->accept(this);
1.95 + } else if (arg->isNameProxy()) {
1.96 + // :TODO: test with functions and globals
1.97 + // Compute a reference to the name.
1.98 + Variable *var = arg->toNameProxy()->binding()->toVariable();
1.99 + __ newref(var);
1.100 + } else {
1.101 + // We don't know how to, or can't, build a direct reference to
1.102 + // this type. Make an indirect one, by taking the top of the
1.103 + // stack and boxing it up.
1.104 + __ slotref_lifo();
1.105 + }
1.106 + } else {
1.107 + arg->accept(this);
1.108 + }
1.109 }
1.110
1.111 __ callglobal(node->arguments()->size(), 0);
1.112 @@ -438,11 +495,11 @@
1.113 void
1.114 BytecodeCompiler::visit(FunctionStatement *node)
1.115 {
1.116 - BytecodeCompiler child(tree_);
1.117 + BytecodeCompiler child(tree_, module_);
1.118 Code *code = child.compileFunction(module_, node);
1.119
1.120 assert(!module_->getFunction(node->fun()->slot()));
1.121 - module_->setFunction(node->fun()->slot(), code);
1.122 + module_->setFunction(ZONE(), node->fun()->slot(), code);
1.123 }
1.124
1.125 void
1.126 @@ -497,10 +554,10 @@
1.127 Module *
1.128 BytecodeCompiler::compile()
1.129 {
1.130 - Code **functions = new Code *[tree_->scope()->numFunctions()];
1.131 - memset(functions, 0, sizeof(Code *) * tree_->scope()->numFunctions());
1.132 -
1.133 - module_ = new Module(functions, tree_->scope()->numFunctions());
1.134 + // :TODO: root
1.135 + module_ = Module::New(ZONE(), tree_->scope()->numFunctions());
1.136 + if (!module_)
1.137 + return NULL;
1.138
1.139 for (size_t i = 0; i < tree_->statements()->length(); i++) {
1.140 Statement *statement = tree_->statements()->at(i);
1.141 @@ -509,7 +566,7 @@
1.142
1.143 #ifndef NDEBUG
1.144 for (size_t i = 0; i < tree_->scope()->numFunctions(); i++)
1.145 - assert(functions[i]);
1.146 + assert(module_->getFunction(i));
1.147 #endif
1.148
1.149 return module_;