Added clang support. A lot of the motion here is introducing a new offsetof because clang's seems broken?
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/.
19 #include "BytecodeCompiler.h"
26 #include "Environments.h"
31 typedef BytecodeEmitter::Label Label;
35 BytecodeCompiler::BytecodeCompiler(Zone *zone, ParseTree *tree, ModuleData *module)
38 emitter_(zone->pool()),
46 static inline TokenKind
47 ToCompare(Expression *expr)
49 if (expr->isBinaryExpression()) {
50 BinaryExpression *b = expr->toBinaryExpression();
51 if (b->token() >= TOK_EQUALS && b->token() <= TOK_OR)
53 } else if (expr->isUnaryExpression()) {
54 UnaryExpression *u = expr->toUnaryExpression();
55 if (u->token() == TOK_NOT)
62 CompareTokenToJump(TokenKind kind)
76 assert(kind == TOK_LE);
82 TokenToOpcode(TokenKind kind)
118 assert(kind == TOK_BITXOR);
124 BytecodeCompiler::recordLifoSlot(Scope *scope)
129 if (Variable *var = scope->lifoSlot()) {
130 locals_->set(zone_, var->slot(), var->type());
131 __ savelifo(var->slot());
136 BytecodeCompiler::unwindTo(Scope *scope)
138 // Note: we only need to unwind to the outermost scope's LIFO slot.
139 Variable *var = NULL;
140 for (Scope *current = scope_; current != scope; current = current->enclosing()) {
141 if (Variable *slot = current->lifoSlot())
146 __ unwindlifo(var->slot());
150 BytecodeCompiler::visit(NameProxy *name)
152 switch (name->binding()->kind()) {
153 case BoundName::VARIABLE:
155 Variable *var = name->binding()->toVariable();
157 if (var->location() == Variable::STACK) {
159 assert(!name->type()->isReference());
160 } else if (var->location() == Variable::ENVIRONMENT) {
163 assert(var->location() == Variable::PARAMETER);
166 // If this argument is actually a reference, dereference it now.
167 if (var->type()->isReference())
168 __ getref(var->type()->contained()->primitive());
173 case BoundName::FUNCTION:
175 NamedFunction *fun = name->binding()->toNamedFunction();
177 __ getmodule_fn(fun->slot());
183 NamedConstant *constant = name->binding()->toNamedConstant();
184 __ int_(constant->value().toInt());
191 BytecodeCompiler::visit(ExpressionStatement *node)
193 // Expressions leave their value on the top of the stack, so we make sure
194 // to balance the stack if they're used as a statement.
195 node->expression()->accept(this);
196 if (!node->expression()->type()->isVoid())
201 BytecodeCompiler::visit(Assignment *node)
203 // The first step is three sub-steps:
205 // (1) Bind the left-hand side.
206 // -- If a cumulative operation (+=, etc):
207 // (2) Save a copy of the binding on the stack.
208 // (3) Dereference the binding to get a value.
210 if (node->lvalue()->isNameProxy()) {
211 NameProxy *proxy = node->lvalue()->toNameProxy();
212 Variable *var = proxy->binding()->toVariable();
215 if (var->type()->isReference() || var->type()->isArray())
218 // Get the value if needed.
219 if (node->token() != TOK_ASSIGN) {
220 // += etc is not allowed on arrays.
221 assert(!var->type()->isArray());
223 if (var->type()->isReference()) {
225 __ getref(var->type()->contained()->primitive());
231 IndexExpression *index = node->lvalue()->toIndexExpression();
232 __ note_position(index->pos());
234 // Note: Eventually, watch out for a whole here. An expression like:
236 // (a[4] = (5, a = []))
238 // Could shrink array, so we need to either bind a[i] to a Reference,
239 // or keep the bounds check near the set. This is just a semantic
241 index->left()->accept(this);
242 index->right()->accept(this);
244 if (node->token() != TOK_ASSIGN) {
247 if (node->type()->isArray())
250 __ getarray(node->type()->primitive());
254 if (node->token() == TOK_ASSIGN) {
255 node->expression()->accept(this);
257 visitForALU(node->type(), node->expression());
259 TokenKind alu = TokenKind(int(node->token()) - (TOK_ASSIGN_ADD - TOK_PLUS));
260 __ note_position(node->pos());
261 __ binary(TokenToOpcode(alu));
265 if (node->expression()->type()->isArray()) {
266 // Unlike references, which can only be computed from a NamePRoxy,
267 // arrays can be computed from multiple lvalue types.
268 __ note_position(node->pos());
270 } else if (node->lvalue()->isNameProxy()) {
271 NameProxy *proxy = node->lvalue()->toNameProxy();
272 Variable *var = proxy->binding()->toVariable();
274 if (var->type()->isReference())
275 __ setref(var->type()->contained()->primitive());
279 IndexExpression *index = node->lvalue()->toIndexExpression();
280 // :TODO: get rid of the BOUNDS instruction, embed it in g/setarray*?
281 // We can't emit it here because the stack is slightly out of position.
283 __ setarray(index->left()->type()->contained()->primitive());
288 BytecodeCompiler::visit(IncDecExpression *node)
290 // In the postfix case, the logic looks like:
292 // (2) Dup -> REF REF
293 // (3) Fetch -> REF VAL
294 // (4) Swap -> VAL REF
295 // (5) Pick -> VAL REF VAL
296 // (6) Add -> VAL REF VAL+1
297 // (7) Store -> VAL VAL+1
300 // In the prefix case, the logic looks like:
302 // (2) Dup -> REF REF
303 // (3) Fetch -> REF VAL
306 // (6) Add -> REF VAL+1
307 // (7) Store -> VAL+1
310 // This is squirrely enough such that we don't bother sharing too much
313 // Note: We simulate a "Pick" operation with a dup2+pop.
315 // This is steps (1) to (5).
316 Expression *expr = node->expression();
317 if (expr->isNameProxy()) {
318 NameProxy *proxy = expr->toNameProxy();
319 Variable *var = proxy->binding()->toVariable();
322 if (var->type()->isReference() || var->type()->isArray())
326 if (var->type()->isReference()) {
328 __ getref(node->type()->primitive());
329 if (node->postfix()) {
334 assert(!var->type()->isArray());
340 IndexExpression *index = expr->toIndexExpression();
341 __ note_position(index->pos());
343 index->left()->accept(this);
344 index->right()->accept(this);
346 assert(!node->type()->isArray());
349 __ getarray(node->type()->primitive());
351 if (node->postfix()) {
352 // The stack looks like this now:
355 // So we must use a PICK operation to rotate the stack into position.
356 __ roll3(); // INDEX VALUE ARRAY
357 __ roll3(); // VALUE ARRAY INDEX
358 __ pick3(); // VALUE ARRAY INDEX VALUE
363 if (node->type()->isFloat()) {
366 assert(node->type()->isInt32());
370 __ note_position(node->pos());
371 if (node->token() == TOK_INCREMENT)
377 if (expr->isNameProxy()) {
378 NameProxy *proxy = expr->toNameProxy();
379 Variable *var = proxy->binding()->toVariable();
381 if (var->type()->isReference())
382 __ setref(node->type()->primitive());
386 __ setarray(node->type()->primitive());
395 BytecodeCompiler::visitForALU(Type *needed, Expression *node)
398 if (needed->isFloat() && !node->type()->isFloat())
401 assert(needed->primitive() == node->type()->primitive());
405 GetCoercionType(TokenKind tok, Type *left, Type *right)
413 BytecodeCompiler::visit(UnaryExpression *node)
415 switch (node->token()) {
418 Local<Type> type(zone_, node->expression()->type());
419 node->expression()->accept(this);
421 if (node->type()->isFloat())
430 Local<Type> type(zone_, node->expression()->type());
431 node->expression()->accept(this);
433 if (node->type()->isFloat())
441 assert(node->token() == TOK_TILDE);
442 node->expression()->accept(this);
449 BytecodeCompiler::visit(BinaryExpression *node)
451 if (node->token() == TOK_AND || node->token() == TOK_OR) {
452 Label success, failure, done;
453 visitForTest(node, &success, &failure, &success);
456 __ drop(1); // Otherwise, the stack depth will be +1 too much.
464 Local<Type> leftType(zone_, node->left()->type());
465 Local<Type> rightType(zone_, node->right()->type());
466 Local<Type> coerce(zone_, GetCoercionType(node->token(), leftType, rightType));
468 visitForALU(coerce, node->left());
469 visitForALU(coerce, node->right());
471 Opcode op = TokenToOpcode(node->token());
472 if (node->type()->isFloat())
473 op = (Opcode)(int(op) + (OP_ADD_F - OP_ADD));
475 __ note_position(node->pos());
480 BytecodeCompiler::visit(IndexExpression *node)
482 node->left()->accept(this);
483 node->right()->accept(this);
484 __ note_position(node->pos());
487 if (node->type()->isArray())
490 __ getarray(node->type()->primitive());
494 BytecodeCompiler::visit(ReturnStatement *node)
496 if (node->expression()) {
497 node->expression()->accept(this);
505 BytecodeCompiler::visitForTest(Expression *expression,
510 TokenKind token = ToCompare(expression);
511 if (token == TOK_EOF || token == TOK_NOT) {
512 if (token == TOK_EOF)
513 expression->accept(this);
515 expression->toUnaryExpression()->expression()->accept(this);
517 bool jumpOnTrue = (fallthrough == falseBranch) ^ (token == TOK_NOT);
519 Opcode op = jumpOnTrue ? OP_JT : OP_JF;
520 if (expression->type()->isFloat())
521 op = (Opcode)(int(op) + (OP_JL_F - OP_JL));
523 if (fallthrough == falseBranch)
524 __ j(op, trueBranch);
526 __ j(op, falseBranch);
530 BinaryExpression *binary = expression->toBinaryExpression();
532 if (token == TOK_AND || token == TOK_OR) {
534 if (token == TOK_AND)
535 visitForTest(binary->left(), &next, falseBranch, &next);
537 visitForTest(binary->left(), trueBranch, &next, &next);
539 visitForTest(binary->right(), trueBranch, falseBranch, fallthrough);
543 Opcode op = CompareTokenToJump(token);
544 if (fallthrough == trueBranch)
547 Local<Type> leftType(zone_, binary->left()->type());
548 Local<Type> rightType(zone_, binary->right()->type());
549 Local<Type> coerce(zone_, GetCoercionType(binary->token(), leftType, rightType));
551 visitForALU(coerce, binary->left());
552 visitForALU(coerce, binary->right());
553 if (coerce->isFloat())
554 op = (Opcode)(int(op) + (OP_JL_F - OP_JL));
556 if (fallthrough == trueBranch)
557 __ j(op, falseBranch);
559 __ j(op, trueBranch);
563 BytecodeCompiler::visit(ForStatement *node)
565 AutoEnterScope forScope(this, node->scope());
567 recordLifoSlot(node->scope());
570 LoopScope loop(scope_, &join, &update, &loop_);
572 if (node->initialization())
573 node->initialization()->accept(this);
576 if (node->condition())
580 node->body()->accept(this);
584 node->update()->accept(this);
586 if (node->condition()) {
588 visitForTest(node->condition(), &header, &join, &join);
596 unwindTo(node->scope()->enclosing());
597 assert(__ stackDepth() == 0);
601 BytecodeCompiler::visit(WhileStatement *node)
607 LoopScope loop(scope_, &join, &header, &loop_);
609 if (node->token() == TOK_WHILE) {
612 visitForTest(node->condition(), &body, &join, &body);
614 node->body()->accept(this);
617 node->body()->accept(this);
618 visitForTest(node->condition(), &header, &join, &join);
625 BytecodeCompiler::visit(BreakStatement *node)
627 unwindTo(loop_->scope());
628 __ jump(loop_->break_());
632 BytecodeCompiler::visit(ContinueStatement *node)
634 unwindTo(loop_->scope());
635 __ jump(loop_->continue_());
639 BytecodeCompiler::visit(BlockStatement *node)
641 AutoEnterScope blockScope(this, node->scope());
643 recordLifoSlot(node->scope());
645 for (size_t i = 0; i < node->statements()->length(); i++) {
646 Statement *statement = node->statements()->at(i);
647 statement->accept(this);
648 assert(__ stackDepth() == 0);
651 // We don't bother emitting an "unwind" instruction for function scopes,
652 // since this is taken care of by the calling convention.
653 if (node->scope() && node->scope()->enclosing()->kind() != Scope::FUNCTION)
654 unwindTo(node->scope()->enclosing());
658 BytecodeCompiler::visit(IntegerLiteral *node)
660 __ int_(node->value());
664 BytecodeCompiler::visit(FloatLiteral *node)
666 __ float_((float)node->value());
669 static inline ArrayMap *
670 BuildArrayMap(Zone *zone, Handle<Type> type)
672 Local<ArrayMap> contained(zone);
673 if (type->levels() > 1) {
674 Local<Type> containedType(zone, type->contained());
675 contained = BuildArrayMap(zone, containedType);
680 return ArrayMap::New(zone, type, contained);
684 BytecodeCompiler::visit(StringLiteral *node)
686 Local<Type> type(zone_, node->type());
687 Local<ArrayMap> map(zone_, BuildArrayMap(zone_, type));
691 Local<Array> array(zone_, Array::New(zone_, map, node->string()->length(), Heap::Tenure_Old));
695 assert(array->nelements() >= node->string()->length());
696 memcpy(array->chars(), node->string()->raw(), node->string()->length() * sizeof(char));
698 __ note_position(node->pos());
703 BytecodeCompiler::getEnvSlot(Variable *var)
705 assert(var->scope()->kind() == Scope::GLOBAL);
710 BytecodeCompiler::setEnvSlot(Variable *var)
712 assert(var->scope()->kind() == Scope::GLOBAL);
717 BytecodeCompiler::visit(VariableDeclaration *node)
719 Variable *var = node->variable();
721 Local<Type> type(zone_, var->type());
722 if (type->isArray()) {
723 Local<ArrayMap> map(zone_, BuildArrayMap(zone_, type));
724 __ note_position(node->pos());
725 if (var->scope()->kind() == Scope::GLOBAL)
726 __ newarray(map, Heap::Tenure_Old);
727 else if (var->needsHeapAllocation())
728 __ newarray(map, Heap::Tenure_Default);
730 __ newarray(map, Heap::Tenure_Stack);
732 if (node->initialization()) {
733 node->initialization()->accept(this);
734 __ note_position(node->pos());
738 if (node->initialization()) {
739 node->initialization()->accept(this);
741 if (!node->postDimensions())
746 if (var->location() == Variable::STACK) {
748 locals_->set(zone_, var->slot(), var->type());
750 assert(var->location() == Variable::ENVIRONMENT);
758 BytecodeCompiler::visit(CallExpression *node)
760 Local<Type> funType(zone_, node->callee()->type());
762 // Sniff out natives, which have a specific opcode and are guaranteed to
763 // be called via name proxy.
764 NamedFunction *native = NULL;
765 if (funType->isNative()) {
766 native = node->callee()->toNameProxy()->binding()->toNamedFunction();
769 for (size_t i = node->arguments()->length() - 1; i < node->arguments()->length(); i--) {
770 Expression *arg = node->arguments()->at(i);
772 // We need to compute a reference if the parameter was in the form:
774 // Note this form does not allow: f({})
776 // We also need to compute references for all variadic native
777 // arguments, but arrays and references are already in the
779 Local<Type> given(zone_, arg->type());
780 bool mustPushReference = false;
781 if (i >= funType->parameters()->length()) {
782 assert(funType->isNative() && funType->isNativeVariadic());
783 mustPushReference = !given->isArray() && !given->isReference();
784 } else if (funType->parameterAt(i)->isReference()) {
785 mustPushReference = !given->isReference();
788 // If a native is passed to a native, it must only be one level deep.
789 assert(!funType->isNative() || !given->isArray() || given->levels() == 1);
791 if (mustPushReference) {
792 if (arg->isNameProxy()) {
793 // :TODO: test with functions and globals
794 // Compute a reference to the name.
795 Variable *var = arg->toNameProxy()->binding()->toVariable();
796 __ note_position(node->pos());
798 } else if (arg->isIndexExpression()) {
799 IndexExpression *expr = arg->toIndexExpression();
800 expr->left()->accept(this);
801 expr->right()->accept(this);
802 __ note_position(expr->pos());
806 // We don't know how to, or can't, build a direct reference to
807 // this type. Make an indirect one, by taking the top of the
808 // stack and boxing it up.
810 __ note_position(node->pos());
818 __ note_position(node->pos());
820 __ callnative(native->slot(), node->arguments()->length());
821 __ drop(node->arguments()->length());
823 node->callee()->accept(this);
825 __ drop(node->arguments()->length() + 1);
830 BytecodeCompiler::visit(TernaryExpression *node)
832 Label success, failure, join;
834 visitForTest(node->condition(), &success, &failure, &success);
836 node->left()->accept(this);
840 node->right()->accept(this);
845 BytecodeCompiler::visit(IfStatement *node)
848 if (!node->ifFalse()) {
851 visitForTest(node->condition(), &success, &join, &success);
853 node->ifTrue()->accept(this);
857 visitForTest(node->condition(), &success, &next, &success);
859 node->ifTrue()->accept(this);
862 node->ifFalse()->accept(this);
869 BytecodeCompiler::visit(FunctionStatement *node)
871 if (node->fun()->isNative()) {
872 assert(!moduleData_->natives->at(node->fun()->slot()));
874 Local<Type> type(zone_, node->fun()->type());
875 Local<String> name(zone_, node->fun()->name());
876 Local<Native> native(zone_, Native::New(zone_, type, name));
880 moduleData_->natives->set(zone_, node->fun()->slot(), native);
884 // If the function has no body, then it's just a declaration.
886 assert(node->fun()->isForward() || node->fun()->isPublic());
890 BytecodeCompiler child(zone_, tree_, moduleData_);
891 Local<Function> fun(zone_, child.compileFunction(moduleData_, node));
895 assert(!moduleData_->module->getFunction(node->fun()->slot()));
896 moduleData_->module->setFunction(zone_, node->fun()->slot(), fun);
900 BytecodeCompiler::visit(EnumStatement *node)
902 // :TODO: eventually, we'll export these.
906 BytecodeCompiler::compileCode(Scope *scope, unsigned lineno)
908 // STOP doubles as RETURNVOID.
911 if (__ oom() || zone_->hasPendingException())
914 Local<ByteArray> bytes(zone_, ByteArray::New(zone_, __ length() * sizeof(bytecode), Heap::Tenure_Old));
917 memcpy(bytes->raw(), __ buffer(), __ length());
919 for (size_t i = 0; i < scope->maxContainedLocals(); i++)
920 assert(locals_->at(i));
922 Local<FixedArray> objects(zone_, FixedArray::New(zone_, __ objects()->length(), Heap::Tenure_Old));
926 for (size_t i = 0; i < __ objects()->length(); i++)
927 objects->set(zone_, i, *(__ objects()->at(i)));
929 Local<ByteArray> safepoints(zone_);
931 // If any stack slots hold gc pointers at potential failure points in the
932 // bytecode, record them now. We do this by building a list of tuples;
933 // each tuple contains the pc offset, and a bitset containing which stack
934 // slots must be scanned by the gc.
935 if (__ oopRecords()->length()) {
936 size_t bytesPerSafepoint = Code::BytesPerSafepoint(__ maxStackDepth());
937 size_t gcmapSize = bytesPerSafepoint * __ oopRecords()->length();
938 safepoints = ByteArray::New(zone_, gcmapSize, Heap::Tenure_Old);
942 Address cursor = safepoints->raw();
943 for (size_t i = 0; i < __ oopRecords()->length(); i++) {
944 OopRecord *record = __ oopRecords()->at(i);
945 assert(record->depth <= __ maxStackDepth());
947 *reinterpret_cast<unsigned *>(cursor) = record->offset;
949 unsigned char *bits = reinterpret_cast<unsigned char *>(cursor + sizeof(unsigned));
950 for (unsigned i = 0; i < record->depth; i++)
951 bits[i / 8] |= (1 << (i % 8));
953 cursor += bytesPerSafepoint;
956 assert(cursor == safepoints->raw() + gcmapSize);
959 Local<ByteArray> sourcemap(zone_);
960 if (__ sourcemapLength()) {
961 sourcemap = ByteArray::New(zone_, __ sourcemapLength(), Heap::Tenure_Old);
965 memcpy(sourcemap->raw(), __ sourcemap(), __ sourcemapLength());
968 Local<Code> code(zone_);
970 code = Code::New(zone_,
983 BytecodeCompiler::compileFunction(ModuleData *module, FunctionStatement *node)
985 // Note: No need to record a life slot here, since it's part of the Frame.
986 AutoEnterScope functionScope(this, node->scope());
988 // Set the initial line, because line mappings are deltas.
989 __ setFirstLine(node->pos().line);
990 locals_ = FixedArray::New(zone_, node->scope()->maxContainedLocals(), Heap::Tenure_Old);
992 node->body()->accept(this);
994 unsigned nargs = node->scope()->numArguments();
995 Local<FixedArray> args(zone_, FixedArray::New(zone_, nargs, Heap::Tenure_Old));
999 for (size_t i = 0; i < node->scope()->numArguments(); i++)
1000 args->set(zone_, i, node->scope()->getArgument(i)->type());
1003 Local<Code> code(zone_, compileCode(node->scope(), node->pos().line));
1007 Local<Type> type(zone_, node->fun()->type());
1008 Local<String> name(zone_, node->fun()->name());
1009 Local<Function> fun(zone_, Function::New(zone_, code, type, name, node->pos()));
1013 // If this function had a forward, export it as a named public.
1014 if (node->fun()->isPublic()) {
1015 assert(node->fun()->isPublic());
1016 ScopedRoot<Function> root(fun);
1019 if (!moduleData_->publics.append(root))
1023 Disassemble(code, stdout);
1029 BytecodeCompiler::compile()
1031 AutoEnterScope scope(this, tree_->scope());
1033 ModuleData moduleData;
1035 moduleData_ = &moduleData;
1036 moduleData_->module = Module::New(zone_, tree_->scope()->numFunctions());
1041 moduleData_->natives = FixedArray::New(zone_, tree_->scope()->numNatives(), Heap::Tenure_Old);
1042 if (!moduleData_->natives)
1045 for (size_t i = 0; i < tree_->statements()->length(); i++) {
1046 Statement *statement = tree_->statements()->at(i);
1047 statement->accept(this);
1050 if (zone_->hasPendingException())
1054 for (size_t i = 0; i < tree_->scope()->numFunctions(); i++)
1055 assert(moduleData_->module->getFunction(i));
1056 for (size_t i = 0; i < tree_->scope()->numNatives(); i++)
1057 assert(moduleData_->natives->at(i));
1060 if (moduleData_->publics.length()) {
1061 Local<Function> fun(zone_);
1062 Local<FixedArray> list(zone_, FixedArray::New(zone_, moduleData_->publics.length(),
1067 for (size_t i = 0; i < moduleData_->publics.length(); i++)
1068 list->set(zone_, i, moduleData_->publics[i]);
1070 moduleData_->module->setPublics(list);
1073 moduleData_->module->setNatives(moduleData_->natives);
1075 if (scope_->numEnvironmentVars()) {
1076 Local<EnvironmentMap> globalMap(zone_, scope_->createEnvironmentMap(zone_));
1080 Local<Environment> environment(zone_, Environment::New(zone_, globalMap));
1084 moduleData_->module->setEnvironment(environment);
1087 Local<Code> code(zone_, compileCode(tree_->scope(), 1));
1091 Disassemble(code, stdout);
1093 moduleData_->module->setCode(code);
1095 return moduleData_->module;