summaryrefslogtreecommitdiffstats
path: root/bytecode.c
diff options
context:
space:
mode:
authorDavid Tolnay <dtolnay@gmail.com>2015-08-23 20:36:11 -0700
committerDavid Tolnay <dtolnay@gmail.com>2015-08-23 20:36:11 -0700
commit0c93eb3379241dc4775718a9d39f54a6c4de20d6 (patch)
tree67bb5510adb707d54c6f72b51b0718578a2caf5c /bytecode.c
parent891f28ef5e406a8d2156ad88d0244ab03fe490eb (diff)
Move source files to src/
Diffstat (limited to 'bytecode.c')
-rw-r--r--bytecode.c161
1 files changed, 0 insertions, 161 deletions
diff --git a/bytecode.c b/bytecode.c
deleted file mode 100644
index 0ef154b8..00000000
--- a/bytecode.c
+++ /dev/null
@@ -1,161 +0,0 @@
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-
-#include "bytecode.h"
-#include "jv_alloc.h"
-
-// flags, length
-#define NONE 0, 1
-#define CONSTANT OP_HAS_CONSTANT, 2
-#define VARIABLE (OP_HAS_VARIABLE | OP_HAS_BINDING), 3
-#define GLOBAL (OP_HAS_CONSTANT | OP_HAS_VARIABLE | OP_HAS_BINDING | OP_IS_CALL_PSEUDO), 4
-#define BRANCH OP_HAS_BRANCH, 2
-#define CFUNC (OP_HAS_CFUNC | OP_HAS_BINDING), 3
-#define UFUNC (OP_HAS_UFUNC | OP_HAS_BINDING | OP_IS_CALL_PSEUDO), 4
-#define DEFINITION (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 0
-#define CLOSURE_REF_IMM (OP_IS_CALL_PSEUDO | OP_HAS_BINDING), 2
-
-#define OP(name, imm, in, out) \
- {name, #name, imm, in, out},
-
-static const struct opcode_description opcode_descriptions[] = {
-#include "opcode_list.h"
-};
-
-static const struct opcode_description invalid_opcode_description = {
- -1, "#INVALID", 0, 0, 0, 0
-};
-
-
-const struct opcode_description* opcode_describe(opcode op) {
- if ((int)op >= 0 && (int)op < NUM_OPCODES) {
- return &opcode_descriptions[op];
- } else {
- return &invalid_opcode_description;
- }
-}
-
-
-int bytecode_operation_length(uint16_t* codeptr) {
- int length = opcode_describe(*codeptr)->length;
- if (*codeptr == CALL_JQ || *codeptr == TAIL_CALL_JQ) {
- length += codeptr[1] * 2;
- }
- return length;
-}
-
-static void dump_code(int indent, struct bytecode* bc) {
- int pc = 0;
- while (pc < bc->codelen) {
- printf("%*s", indent, "");
- dump_operation(bc, bc->code + pc);
- printf("\n");
- pc += bytecode_operation_length(bc->code + pc);
- }
-}
-
-static void symbol_table_free(struct symbol_table* syms) {
- jv_mem_free(syms->cfunctions);
- jv_free(syms->cfunc_names);
- jv_mem_free(syms);
-}
-
-void dump_disassembly(int indent, struct bytecode* bc) {
- if (bc->nclosures > 0) {
- printf("%*s[params: ", indent, "");
- jv params = jv_object_get(jv_copy(bc->debuginfo), jv_string("params"));
- for (int i=0; i<bc->nclosures; i++) {
- if (i) printf(", ");
- jv name = jv_array_get(jv_copy(params), i);
- printf("%s", jv_string_value(name));
- jv_free(name);
- }
- jv_free(params);
- printf("]\n");
- }
- dump_code(indent, bc);
- for (int i=0; i<bc->nsubfunctions; i++) {
- struct bytecode* subfn = bc->subfunctions[i];
- jv name = jv_object_get(jv_copy(subfn->debuginfo), jv_string("name"));
- printf("%*s%s:%d:\n", indent, "", jv_string_value(name), i);
- jv_free(name);
- dump_disassembly(indent+2, subfn);
- }
-}
-
-static struct bytecode* getlevel(struct bytecode* bc, int level) {
- while (level > 0) {
- bc = bc->parent;
- level--;
- }
- return bc;
-}
-
-void dump_operation(struct bytecode* bc, uint16_t* codeptr) {
- int pc = codeptr - bc->code;
- printf("%04d ", pc);
- const struct opcode_description* op = opcode_describe(bc->code[pc++]);
- printf("%s", op->name);
- if (op->length > 1) {
- uint16_t imm = bc->code[pc++];
- if (op->op == CALL_JQ || op->op == TAIL_CALL_JQ) {
- for (int i=0; i<imm+1; i++) {
- uint16_t level = bc->code[pc++];
- uint16_t idx = bc->code[pc++];
- jv name;
- if (idx & ARG_NEWCLOSURE) {
- idx &= ~ARG_NEWCLOSURE;
- name = jv_object_get(jv_copy(getlevel(bc,level)->subfunctions[idx]->debuginfo),
- jv_string("name"));
- } else {
- name = jv_array_get(jv_object_get(jv_copy(getlevel(bc,level)->debuginfo),
- jv_string("params")), idx);
- }
- printf(" %s:%d",
- jv_string_value(name),
- idx);
- jv_free(name);
- if (level) {
- printf("^%d", level);
- }
- }
- } else if (op->op == CALL_BUILTIN) {
- int func = bc->code[pc++];
- jv name = jv_array_get(jv_copy(bc->globals->cfunc_names), func);
- printf(" %s", jv_string_value(name));
- jv_free(name);
- } else if (op->flags & OP_HAS_BRANCH) {
- printf(" %04d", pc + imm);
- } else if (op->flags & OP_HAS_CONSTANT) {
- printf(" ");
- jv_dump(jv_array_get(jv_copy(bc->constants), imm), 0);
- } else if (op->flags & OP_HAS_VARIABLE) {
- uint16_t v = bc->code[pc++];
- jv name = jv_array_get(jv_object_get(jv_copy(getlevel(bc,imm)->debuginfo), jv_string("locals")), v);
- printf(" $%s:%d",
- jv_string_value(name),
- v);
- jv_free(name);
- if (imm) {
- printf("^%d", imm);
- }
- } else {
- printf(" %d", imm);
- }
- }
-}
-
-void bytecode_free(struct bytecode* bc) {
- if (!bc)
- return;
- jv_mem_free(bc->code);
- jv_free(bc->constants);
- for (int i=0; i<bc->nsubfunctions; i++)
- bytecode_free(bc->subfunctions[i]);
- if (!bc->parent)
- symbol_table_free(bc->globals);
- jv_mem_free(bc->subfunctions);
- jv_free(bc->debuginfo);
- jv_mem_free(bc);
-}