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