Re-add line and column information to bytecode.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of JITCraft.
7 * JITCraft is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * JITCraft. If not, see http://www.gnu.org/licenses/.
21 #include "BytecodeEmitter.h"
22 #include "../Heap-inl.h"
23 #include "../Handles-inl.h"
27 class HIRTranslator : public HIRVisitor
30 HIRTranslator(Zone *zone, BytecodeEmitter &emitter)
36 void translate(HIR *hir) {
40 void visitFloat(HFloat *hir);
41 void visitInteger(HInteger *hir);
42 void visitCall(HCall *call);
43 void visitStore(HStore *store);
44 void visitBinary(HBinary *binary);
45 void visitLocal(HLocal *local);
46 void visitGlobal(HGlobal *global);
47 void visitConvert(HConvert *convert);
48 void visitIndex(HIndex *index);
49 void visitPostIncDec(HPostIncDec *hir);
53 BytecodeEmitter &emitter_;
59 HIRTranslator::visitFloat(HFloat *hir)
61 __ float_(hir->value());
65 HIRTranslator::visitInteger(HInteger *hir)
67 __ int_(hir->value());
71 HIRTranslator::visitCall(HCall *call)
73 Local<FunctionType> fun(zone_, FunctionType::cast(call->callee()->type()));
75 assert(call->args()->length() == fun->parameters()->length());
77 __ note_position(call->node()->pos());
79 unsigned argc = call->args()->length();
80 for (size_t i = call->args()->length() - 1; i < call->args()->length(); i--) {
81 HIR *hir = call->args()->at(i);
85 call->callee()->accept(this);
90 HGlobal::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
95 HGlobal::hold(BytecodeEmitter &emitter_)
100 HGlobal::swapAndPick(BytecodeEmitter &emitter_)
106 HGlobal::store(BytecodeEmitter &emitter_)
112 HGlobal::load(BytecodeEmitter &emitter_)
118 HLocal::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
120 if (sym_->type()->isReference()) {
121 if (sym_->storage() == VariableSymbol::Local)
123 else if (sym_->storage() == VariableSymbol::Arg)
131 HLocal::hold(BytecodeEmitter &emitter_)
133 if (sym_->type()->isReference())
138 HLocal::swapAndPick(BytecodeEmitter &emitter_)
140 if (sym_->type()->isReference()) {
149 HLocal::store(BytecodeEmitter &emitter_)
151 if (sym_->type()->isReference()) {
152 __ setref(sym_->type()->contained_ref());
154 if (sym_->storage() == VariableSymbol::Local)
156 else if (sym_->storage() == VariableSymbol::Arg)
164 HLocal::load(BytecodeEmitter &emitter_)
166 if (sym_->type()->isReference())
167 __ getref(sym_->type());
168 else if (sym_->storage() == VariableSymbol::Local)
170 else if (sym_->storage() == VariableSymbol::Arg)
177 HIndex::bind(HIRVisitor *visitor, BytecodeEmitter &emitter_)
179 __ note_position(node()->pos());
180 left_->accept(visitor);
181 right_->accept(visitor);
185 HIndex::hold(BytecodeEmitter &emitter_)
191 HIndex::swapAndPick(BytecodeEmitter &emitter_)
194 __ roll3(); // INDEX VALUE BASE
195 __ roll3(); // VALUE BASE INDEX
196 __ pick3(); // VALUE BASE INDEX VALUE
200 HIndex::store(BytecodeEmitter &emitter_)
206 HIndex::load(BytecodeEmitter &emitter_)
212 HIRTranslator::visitLocal(HLocal *local)
214 local->bind(this, emitter_);
215 local->load(emitter_);
219 HIRTranslator::visitIndex(HIndex *index)
221 index->bind(this, emitter_);
222 index->load(emitter_);
226 HIRTranslator::visitGlobal(HGlobal *global)
228 global->bind(this, emitter_);
229 global->load(emitter_);
233 TokenToOpcode(TokenKind kind)
257 case TOK_ASSIGN_USHR:
263 case TOK_ASSIGN_BITAND:
266 case TOK_ASSIGN_BITOR:
281 assert(kind == TOK_BITXOR);
287 HIRTranslator::visitStore(HStore *store)
289 store->lval()->bind(this, emitter_);
290 if (store->kind() == TOK_ASSIGN) {
291 store->rval()->accept(this);
293 // Advanced case: dup the ref, load, op, store.
294 store->lval()->hold(emitter_);
295 store->lval()->load(emitter_);
296 store->rval()->accept(this);
297 __ binary(TokenToOpcode(store->kind()));
299 store->lval()->store(emitter_);
303 HIRTranslator::visitPostIncDec(HPostIncDec *hir)
305 hir->lval()->bind(this, emitter_);
306 hir->lval()->hold(emitter_);
307 hir->lval()->load(emitter_);
308 hir->lval()->swapAndPick(emitter_);
309 hir->rval()->accept(this);
310 __ binary(TokenToOpcode(hir->kind()));
311 hir->lval()->store(emitter_);
316 HIRTranslator::visitBinary(HBinary *binary)
318 binary->left()->accept(this);
319 binary->right()->accept(this);
321 // We define three sets of math operators:
323 // (1) ADD, SUB, MUL, DIV, MOD, which take two equal types and produce
325 // (2) LT, LE, GE, GT, EQ, NE, which take two equal types and produce
327 // (3) SHL, SR, USHR, BITAND, BITOR, BITXOR, BITNOT, which take two
328 // equal integer types and return that integer type.
330 Opcode op = TokenToOpcode(binary->token());
333 __ note_position(binary->node()->pos());
335 if (op >= OP_ADD && op <= OP_NE) {
336 if (binary->type()->isFloat())
337 op = Opcode(int(op) + int(OP_ADD_F - OP_ADD));
339 assert(binary->type()->isInt32());
346 HIRTranslator::visitConvert(HConvert *convert)
348 convert->in()->accept(this);
349 __ unary(convert->opcode());
353 ke::EmitHIR(Zone *zone, BytecodeEmitter &emitter, HIR *hir)
355 HIRTranslator translator(zone, emitter);
356 translator.translate(hir);