Initial import of prototype.
2 * Copyright (C) 2012 David Anderson
4 * This file is part of JITCraft.
6 * JITCraft is free software: you can redistribute it and/or modify it under
7 * the terms of the GNU General Public License as published by the Free
8 * Software Foundation, either version 3 of the License, or (at your option)
11 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along with
16 * JITCraft. If not, see http://www.gnu.org/licenses/.
18 #include "BytecodeCompiler.h"
25 typedef BytecodeEmitter::Label Label;
29 BytecodeCompiler::BytecodeCompiler(ParseTree *tree)
34 static inline TokenKind
35 ToCompare(Expression *expr)
37 if (expr->isBinaryExpression()) {
38 BinaryExpression *b = expr->toBinaryExpression();
39 if (b->token() >= TOK_EQUALS && b->token() <= TOK_GE)
46 CompareTokenToJump(TokenKind kind)
67 TokenToOpcode(TokenKind kind)
84 BytecodeCompiler::visit(NameProxy *name)
86 Variable *var = name->binding()->toVariable();
88 if (var->location() == Variable::STACK) {
89 __ getlocal(var->slot());
91 assert(var->location() == Variable::PARAMETER);
92 __ getarg(var->slot());
97 BytecodeCompiler::visit(ExpressionStatement *node)
99 // Expressions leave their value on the top of the stack, so we make sure
100 // to balance the stack if they're used as a statement.
101 node->expression()->accept(this);
106 BytecodeCompiler::visit(Assignment *node)
108 if (node->lvalue()->isNameProxy()) {
109 NameProxy *proxy = node->lvalue()->toNameProxy();
110 Variable *var = proxy->binding()->toVariable();
112 node->expression()->accept(this);
113 if (var->location() == Variable::STACK) {
114 __ setlocal(var->slot());
116 assert(var->location() == Variable::PARAMETER);
117 __ setarg(var->slot());
119 } else if (node->lvalue()->isIndexExpression()) {
120 IndexExpression *index = node->lvalue()->toIndexExpression();
122 index->left()->accept(this);
123 index->right()->accept(this);
125 node->expression()->accept(this);
131 BytecodeCompiler::visit(BinaryExpression *node)
133 node->left()->accept(this);
134 node->right()->accept(this);
136 Opcode op = TokenToOpcode(node->token());
141 BytecodeCompiler::visit(IndexExpression *node)
143 node->left()->accept(this);
144 node->right()->accept(this);
147 if (node->type()->isArray())
154 BytecodeCompiler::visit(ReturnStatement *node)
156 if (node->expression())
157 node->expression()->accept(this);
165 BytecodeCompiler::visitForTest(Expression *expression, Label *label, bool onTrue)
167 TokenKind token = ToCompare(expression);
168 if (token == TOK_EOF) {
169 expression->accept(this);
177 Opcode op = CompareTokenToJump(token);
181 assert(expression->isBinaryExpression());
182 BinaryExpression *binary = expression->toBinaryExpression();
183 binary->left()->accept(this);
184 binary->right()->accept(this);
189 BytecodeCompiler::visit(ForStatement *node)
191 if (node->declaration())
192 node->declaration()->accept(this);
195 if (node->condition())
199 node->body()->accept(this);
202 node->update()->accept(this);
204 if (node->condition()) {
206 visitForTest(node->condition(), &header, true);
211 assert(__ stackDepth() == 0);
215 BytecodeCompiler::visit(BlockStatement *node)
217 for (size_t i = 0; i < node->statements()->length(); i++) {
218 Statement *statement = node->statements()->at(i);
219 statement->accept(this);
220 assert(__ stackDepth() == 0);
225 BytecodeCompiler::visit(IntegerLiteralExpression *node)
227 __ int_(node->value());
231 BytecodeCompiler::visit(VariableDeclaration *node)
233 Variable *var = node->variable();
234 assert(var->location() == Variable::STACK);
236 Type *type = var->type();
237 if (type->isArray()) {
238 bool isConstant = true;
239 for (Type *child = type; child->isArray(); child = child->contained()) {
240 if (child->elements() == Type::UNKNOWN_SIZE) {
247 for (size_t i = 0; i < node->postDimensions()->size(); i++) {
248 Expression *expr = node->postDimensions()->at(i);
255 if (node->initialization()) {
256 node->initialization()->accept(this);
258 if (!node->postDimensions())
262 __ setlocal(var->slot());
265 locals_[var->slot()] = var->type();
269 BytecodeCompiler::visit(CallExpression *node)
271 NameProxy *fun = node->callee()->toNameProxy();
273 for (size_t i = 0; i < node->arguments()->size(); i++) {
274 Expression *arg = node->arguments()->at(i);
278 __ callglobal(node->arguments()->size(), 0);
282 BytecodeCompiler::visit(IfStatement *node)
284 if (!node->ifFalse()) {
286 visitForTest(node->condition(), &fail, false);
287 node->ifTrue()->accept(this);
291 visitForTest(node->condition(), &fail, false);
292 node->ifTrue()->accept(this);
295 node->ifFalse()->accept(this);
301 BytecodeCompiler::visit(FunctionStatement *node)
303 BytecodeCompiler child(tree_);
304 Code *code = child.compileFunction(module_, node);
306 assert(!module_->getFunction(node->fun()->slot()));
307 module_->setFunction(node->fun()->slot(), code);
311 BytecodeCompiler::compileFunction(Module *module, FunctionStatement *node)
313 locals_ = new Type *[node->scope()->maxContainedLocals()];
314 memset(locals_, 0, sizeof(Type *) * node->scope()->maxContainedLocals());
316 node->body()->accept(this);
323 bytecode *start = (bytecode *)malloc(__ length() * sizeof(bytecode));
324 memcpy(start, __ buffer(), __ length());
326 unsigned nargs = node->scope()->numArguments();
327 Type **args = new Type *[nargs];
328 for (size_t i = 0; i < node->scope()->numArguments(); i++)
329 args[i] = node->scope()->getArgument(i)->type();
331 for (size_t i = 0; i < node->scope()->maxContainedLocals(); i++)
334 Code *code = new Code(module,
340 node->scope()->maxContainedLocals(),
347 BytecodeCompiler::compile()
349 Code **functions = new Code *[tree_->scope()->numFunctions()];
350 memset(functions, 0, sizeof(Code *) * tree_->scope()->numFunctions());
352 module_ = new Module(functions, tree_->scope()->numFunctions());
354 for (size_t i = 0; i < tree_->statements()->length(); i++) {
355 Statement *statement = tree_->statements()->at(i);
356 statement->accept(this);
360 for (size_t i = 0; i < tree_->scope()->numFunctions(); i++)
361 assert(functions[i]);