jitcraft/Opcodes.cpp
author David Anderson <dvander@alliedmods.net>
Tue Jul 03 00:43:29 2012 -0700 (2012-07-03)
changeset 34 9aafaf3797e6
parent 26 a48382113da6
child 43 f6b1a68e7ebb
permissions -rw-r--r--
Handle-ize Code.
     1 /*
     2  * Copyright (C) 2012 David Anderson
     3  *
     4  * This file is part of JITCraft.
     5  *
     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)
     9  * any later version.
    10  * 
    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.
    14  *
    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/.
    17  */
    18 #include "Opcodes.h"
    19 #include "Utility.h"
    20 #include "Code.h"
    21 #include "Zone.h"
    22 #include "Array.h"
    23 #include "Heap-inl.h"
    24 
    25 using namespace jc;
    26 
    27 OpInfo jc::OpcodeInfo[] =
    28 {
    29 #define OPDEF(name, number, text, length, uses, defs) \
    30     {text, length, uses, defs},
    31 #include "Opcodes.tbl"
    32 #undef OPDEF
    33 };
    34 
    35 Code *
    36 Code::New(Zone *zone, Handle<ByteArray> bytecode, Handle<FixedArray> locals,
    37           Handle<FixedArray> objects, unsigned maxStackDepth, Handle<Module> module)
    38 {
    39     Local<Code> code(zone, Code::cast(zone->allocate(MapKind_Code, sizeof(Code), Heap::Tenure_Old)));
    40     if (!code)
    41         return NULL;
    42 
    43     code->bytecode_ = bytecode;
    44     code->locals_ = locals;
    45     code->objects_ = objects;
    46     code->maxStackDepth_ = maxStackDepth;
    47     code->module_ = module;
    48     return code;
    49 }
    50 
    51 // All jumps must be the same length.
    52 STATIC_ASSERT(OP_JL_LENGTH == OP_JUMP_LENGTH);
    53 STATIC_ASSERT(OP_JLE_LENGTH == OP_JUMP_LENGTH);
    54 STATIC_ASSERT(OP_JG_LENGTH == OP_JUMP_LENGTH);
    55 STATIC_ASSERT(OP_JGE_LENGTH == OP_JUMP_LENGTH);
    56 STATIC_ASSERT(OP_JEQ_LENGTH == OP_JUMP_LENGTH);
    57 STATIC_ASSERT(OP_JNE_LENGTH == OP_JUMP_LENGTH);
    58 STATIC_ASSERT(OP_JT_LENGTH == OP_JUMP_LENGTH);
    59 STATIC_ASSERT(OP_JF_LENGTH == OP_JUMP_LENGTH);
    60 
    61 void
    62 jc::Disassemble(Code *code, FILE *fp)
    63 {
    64     bytecode *pc = code->start();
    65     for (;;) {
    66         Opcode op = Opcode(*pc);
    67 
    68         fprintf(fp, "%-4d %s ", int(pc - code->start()), OpcodeInfo[op].name);
    69 
    70         switch (op) {
    71           case OP_NOP:
    72           case OP_RETURN:
    73           case OP_ADD:
    74           case OP_SUB:
    75           case OP_MUL:
    76           case OP_DIV:
    77           case OP_ADD_F:
    78           case OP_SUB_F:
    79           case OP_MUL_F:
    80           case OP_DIV_F:
    81           case OP_CVT_I2F:
    82           case OP_POP:
    83           case OP_GETARRAY_I:
    84           case OP_SETARRAY_I:
    85           case OP_GETARRAY_F:
    86           case OP_SETARRAY_F:
    87           case OP_GETARRAY_C:
    88           case OP_SETARRAY_C:
    89           case OP_GETARRAY_O:
    90           case OP_BOUNDS:
    91           case OP_SHL:
    92           case OP_SHR:
    93           case OP_USHR:
    94           case OP_BITAND:
    95           case OP_BITOR:
    96           case OP_BITXOR:
    97           case OP_GETREF_I:
    98           case OP_SETREF_I:
    99           case OP_GETREF_F:
   100           case OP_SETREF_F:
   101           case OP_SLOTREF_LIFO:
   102           case OP_ARRAYREF_LIFO:
   103           case OP_OBJECT:
   104           case OP_ARRAYCOPY:
   105           case OP_DUP:
   106           case OP_DUP2:
   107           case OP_SWAP:
   108           case OP_ROLL3:
   109           case OP_PICK2:
   110           case OP_PICK3:
   111             break;
   112 
   113           case OP_STOP:
   114             fprintf(fp, "\n");
   115             return;
   116 
   117           case OP_INT:
   118             fprintf(fp, "%d", READ_INT32(pc));
   119             break;
   120 
   121           case OP_FLOAT:
   122             fprintf(fp, "%f", READ_FLOAT(pc));
   123             break;
   124 
   125           case OP_JL:
   126           case OP_JLE:
   127           case OP_JG:
   128           case OP_JGE:
   129           case OP_JEQ:
   130           case OP_JNE:
   131           case OP_JT:
   132           case OP_JF:
   133           case OP_JUMP:
   134             fprintf(fp, "%u (%+d)", unsigned((pc + READ_INT32(pc)) - code->start()), READ_INT32(pc));
   135             break;
   136 
   137           case OP_NEWARRAY_LIFO:
   138           {
   139             // :TODO: use Local
   140             ArrayMap *map = ArrayMap::cast(code->map(READ_UINT32(pc)));
   141             fprintf(fp, "%s:", map->type()->innermost()->tag()
   142                                ? map->type()->innermost()->tag()
   143                                : "_");
   144             for (; map; map = map->contained()) {
   145                 Type *type = map->type();
   146                 fprintf(fp, "[%d]", type->elements());
   147             }
   148             break;
   149           }
   150 
   151           case OP_GETLOCAL:
   152           case OP_SETLOCAL:
   153           case OP_GETARG:
   154           case OP_SETARG:
   155           case OP_SAVELIFO:
   156           case OP_UNWINDLIFO:
   157           case OP_CALLGLOBAL:
   158           case OP_VARREF_LIFO:
   159           case OP_ARGREF_LIFO:
   160             fprintf(fp, "%u", READ_UINT32(pc));
   161             break;
   162 
   163           default:
   164             // Unknown opcode!
   165             assert(false);
   166             return;
   167         }
   168 
   169         fprintf(fp, "\n");
   170         pc += OpcodeInfo[op].length;
   171         assert(pc < code->start() + code->length());
   172     }
   173 }