Added support for arrays of Floats.
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)
35 static inline TokenKind
36 ToCompare(Expression *expr)
38 if (expr->isBinaryExpression()) {
39 BinaryExpression *b = expr->toBinaryExpression();
40 if (b->token() >= TOK_EQUALS && b->token() <= TOK_GE)
47 CompareTokenToJump(TokenKind kind)
68 TokenToOpcode(TokenKind kind)
85 BytecodeCompiler::leaveScope(Scope *scope)
90 if (Variable *var = scope->firstUnsafeArray())
91 __ unwind(var->slot());
95 BytecodeCompiler::visit(NameProxy *name)
97 switch (name->binding()->kind()) {
98 case BoundName::VARIABLE:
100 Variable *var = name->binding()->toVariable();
102 if (var->location() == Variable::STACK) {
103 __ getlocal(var->slot());
105 assert(var->location() == Variable::PARAMETER);
106 __ getarg(var->slot());
113 NamedConstant *constant = name->binding()->toNamedConstant();
114 __ int_(constant->value().toInt());
121 BytecodeCompiler::visit(ExpressionStatement *node)
123 // Expressions leave their value on the top of the stack, so we make sure
124 // to balance the stack if they're used as a statement.
125 node->expression()->accept(this);
130 BytecodeCompiler::visit(Assignment *node)
132 if (node->lvalue()->isNameProxy()) {
133 NameProxy *proxy = node->lvalue()->toNameProxy();
134 Variable *var = proxy->binding()->toVariable();
136 node->expression()->accept(this);
137 if (var->location() == Variable::STACK) {
138 __ setlocal(var->slot());
140 assert(var->location() == Variable::PARAMETER);
141 __ setarg(var->slot());
143 } else if (node->lvalue()->isIndexExpression()) {
144 IndexExpression *index = node->lvalue()->toIndexExpression();
146 index->left()->accept(this);
147 index->right()->accept(this);
149 node->expression()->accept(this);
150 if (index->left()->type()->contained()->isFloat()) {
153 assert(index->left()->type()->contained()->isInt());
160 BytecodeCompiler::visitForALU(Type *needed, Expression *node)
163 if (needed->isFloat() && !node->type()->isFloat())
168 BytecodeCompiler::visit(BinaryExpression *node)
170 visitForALU(node->type(), node->left());
171 visitForALU(node->type(), node->right());
173 Opcode op = TokenToOpcode(node->token());
174 if (node->type()->isFloat())
175 op = (Opcode)(int(op) + (OP_ADD_F - OP_ADD));
180 BytecodeCompiler::visit(IndexExpression *node)
182 node->left()->accept(this);
183 node->right()->accept(this);
186 if (node->type()->isArray()) {
188 } else if (node->type()->isFloat()) {
192 assert(node->type()->isInt());
197 BytecodeCompiler::visit(ReturnStatement *node)
199 if (node->expression())
200 node->expression()->accept(this);
208 BytecodeCompiler::visitForTest(Expression *expression, Label *label, bool onTrue)
210 TokenKind token = ToCompare(expression);
211 if (token == TOK_EOF) {
212 expression->accept(this);
220 Opcode op = CompareTokenToJump(token);
224 assert(expression->isBinaryExpression());
225 BinaryExpression *binary = expression->toBinaryExpression();
226 binary->left()->accept(this);
227 binary->right()->accept(this);
232 BytecodeCompiler::visit(ForStatement *node)
234 AutoEnterScope forScope(this, node->scope());
236 if (node->declaration())
237 node->declaration()->accept(this);
240 if (node->condition())
244 node->body()->accept(this);
247 node->update()->accept(this);
249 if (node->condition()) {
251 visitForTest(node->condition(), &header, true);
256 leaveScope(node->scope());
257 assert(__ stackDepth() == 0);
261 BytecodeCompiler::visit(BlockStatement *node)
263 AutoEnterScope blockScope(this, node->scope());
265 for (size_t i = 0; i < node->statements()->length(); i++) {
266 Statement *statement = node->statements()->at(i);
267 statement->accept(this);
268 assert(__ stackDepth() == 0);
271 // We don't bother emitting an "unwind" instruction for function scopes,
272 // since this is taken care of by the calling convention.
273 if (node->scope() && node->scope()->enclosing()->kind() != Scope::FUNCTION)
274 leaveScope(node->scope());
278 BytecodeCompiler::visit(IntegerLiteral *node)
280 __ int_(node->value());
284 BytecodeCompiler::visit(FloatLiteral *node)
286 __ float_((float)node->value());
290 BytecodeCompiler::visit(VariableDeclaration *node)
292 Variable *var = node->variable();
293 assert(var->location() == Variable::STACK);
295 Type *type = var->type();
296 if (type->isArray()) {
297 bool isConstant = true;
298 for (Type *child = type; child->isArray(); child = child->contained()) {
299 if (child->elements() == Type::UNKNOWN_SIZE) {
306 for (size_t i = 0; i < node->postDimensions()->size(); i++) {
307 Expression *expr = node->postDimensions()->at(i);
314 if (node->initialization()) {
315 node->initialization()->accept(this);
317 if (!node->postDimensions())
321 __ setlocal(var->slot());
324 locals_[var->slot()] = var->type();
328 BytecodeCompiler::visit(CallExpression *node)
330 NameProxy *fun = node->callee()->toNameProxy();
332 for (size_t i = 0; i < node->arguments()->size(); i++) {
333 Expression *arg = node->arguments()->at(i);
337 __ callglobal(node->arguments()->size(), 0);
341 BytecodeCompiler::visit(IfStatement *node)
343 if (!node->ifFalse()) {
345 visitForTest(node->condition(), &fail, false);
346 node->ifTrue()->accept(this);
350 visitForTest(node->condition(), &fail, false);
351 node->ifTrue()->accept(this);
354 node->ifFalse()->accept(this);
360 BytecodeCompiler::visit(FunctionStatement *node)
362 BytecodeCompiler child(tree_);
363 Code *code = child.compileFunction(module_, node);
365 assert(!module_->getFunction(node->fun()->slot()));
366 module_->setFunction(node->fun()->slot(), code);
370 BytecodeCompiler::visit(EnumStatement *node)
372 // :TODO: eventually, we'll export these.
376 BytecodeCompiler::compileFunction(Module *module, FunctionStatement *node)
378 AutoEnterScope functionScope(this, node->scope());
380 locals_ = new Type *[node->scope()->maxContainedLocals()];
381 memset(locals_, 0, sizeof(Type *) * node->scope()->maxContainedLocals());
383 node->body()->accept(this);
390 bytecode *start = (bytecode *)malloc(__ length() * sizeof(bytecode));
391 memcpy(start, __ buffer(), __ length());
393 unsigned nargs = node->scope()->numArguments();
394 Type **args = new Type *[nargs];
395 for (size_t i = 0; i < node->scope()->numArguments(); i++)
396 args[i] = node->scope()->getArgument(i)->type();
398 for (size_t i = 0; i < node->scope()->maxContainedLocals(); i++)
401 Code *code = new Code(module,
407 node->scope()->maxContainedLocals(),
414 BytecodeCompiler::compile()
416 Code **functions = new Code *[tree_->scope()->numFunctions()];
417 memset(functions, 0, sizeof(Code *) * tree_->scope()->numFunctions());
419 module_ = new Module(functions, tree_->scope()->numFunctions());
421 for (size_t i = 0; i < tree_->statements()->length(); i++) {
422 Statement *statement = tree_->statements()->at(i);
423 statement->accept(this);
427 for (size_t i = 0; i < tree_->scope()->numFunctions(); i++)
428 assert(functions[i]);