diff options
| author | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-06-08 18:52:34 +0900 |
|---|---|---|
| committer | Yukihiro "Matz" Matsumoto <[email protected]> | 2020-10-12 16:21:07 +0900 |
| commit | ad15e59cd942486d87e2fb38d30993f15dc29433 (patch) | |
| tree | 504c26ae1d06d52c2d6d62335940a4613c16c7e5 /src/dump.c | |
| parent | 71eb4b2b227c083f187c634212f5fc557f392fb9 (diff) | |
| download | mruby-ad15e59cd942486d87e2fb38d30993f15dc29433.tar.gz mruby-ad15e59cd942486d87e2fb38d30993f15dc29433.zip | |
Add `irep` C struct dump from `mrbc` with `-S` option.
But we need more work:
- recursive `irep` dump (`irep->reps`)
- pool values dump (`irep->pool`)
Diffstat (limited to 'src/dump.c')
| -rw-r--r-- | src/dump.c | 148 |
1 files changed, 148 insertions, 0 deletions
diff --git a/src/dump.c b/src/dump.c index 770c133fb..093e4c256 100644 --- a/src/dump.c +++ b/src/dump.c @@ -918,4 +918,152 @@ mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *f return result; } +static struct { + const char *op; + const char *name; +} op_table[] = { + {"!", "not"}, + {"!=", "neq"}, + {"!~", "nmatch"}, + {"%", "mod"}, + {"&", "and"}, + {"&&", "andand"}, + {"*", "mul"}, + {"**", "pow"}, + {"+", "add"}, + {"+@", "plus"}, + {"-", "sub"}, + {"-@", "minus"}, + {"/", "div"}, + {"<", "lt"}, + {"<=", "le"}, + {"<<", "lshift"}, + {"<=>", "cmp"}, + {"==", "eq"}, + {"===", "eqq"}, + {"=~", "match"}, + {">", "gt"}, + {">=", "ge"}, + {">>", "rshift"}, + {"[]", "aref"}, + {"[]=", "aset"}, + {"^", "xor"}, + {"`", "tick"}, + {"|", "or"}, + {"||", "oror"}, + {"~", "neg"}, + {0}, +}; + +static int +dump_sym(mrb_state *mrb, mrb_sym sym, FILE *fp) +{ + mrb_int len; + const char *name = mrb_sym_name_len(mrb, sym, &len); + int i; + + if (len == 0 || len != strlen(name)) + return MRB_DUMP_INVALID_ARGUMENT; + for (i=0; op_table[i].op; i++) { + if (strcmp(name, op_table[i].op) == 0) { + fprintf(fp, "MRB_QSYM(%s),", op_table[i].name); + return MRB_DUMP_OK; + } + } + if (name[0] == '@') { + fprintf(fp, "MRB_QSYM(a_%s),", name+1); + } + else if (name[0] == '$') { + fprintf(fp, "MRB_QSYM(d_%s),", name+1); + } + else if (name[len-1] == '!') { + fprintf(fp, "MRB_QSYM(%.*s_b),", (int)len-1, name); + } + else if (name[len-1] == '?') { + fprintf(fp, "MRB_QSYM(%.*s_p),", (int)len-1, name); + } + else { + fprintf(fp, "MRB_SYM(%s),", name); + } + return MRB_DUMP_OK; +} + +static int +dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, const char *name, int *np) +{ + int n = *np; /* this level */ + int i, len; + + /* dump reps */ + /* dump pool */ + /* dump syms */ + if (irep->syms) { + fprintf(fp, "static const mrb_sym %s_syms_%d = {", name, n); + for (i=0,len=irep->slen; i<len; i++) { + if (dump_sym(mrb, irep->syms[i], fp) != MRB_DUMP_OK) + return MRB_DUMP_INVALID_ARGUMENT; + } + fputs("};\n", fp); + } + /* dump iseq */ + fprintf(fp, "static const mrb_code %s_iseq_%d[] = {", name, n); + for (i=0,len=irep->ilen; i<len; i++) { + if (i%8 == 0) fputs("\n", fp); + fprintf(fp, "0x%02x,", irep->iseq[i]); + } + fputs("};\n", fp); + /* dump irep */ + if (n == 0) { /* topleve irep */ + fprintf(fp, "static const mrb_irep %s = {\n", name); + } + else { + fprintf(fp, "static const mrb_irep %s_%d = {\n", name, n); + } + fprintf(fp, " %d,\t\t\t\t\t/* nlocals */\n", irep->nlocals); + fprintf(fp, " %d,\t\t\t\t\t/* nregs */\n", irep->nregs); + fputs( " MRB_ISEQ_NO_FREE|MRB_IREP_NO_FREE,\t/* flags */\n", fp); + fprintf(fp, " %s_iseq_%d,\t\t\t/* iseq */\n", name, n); + if (irep->pool) { + fprintf(fp, " %s_pool_%d,\t\t/* pool */\n", name, n); + } + else { + fputs( " NULL,\t\t\t\t\t/* pool */\n", fp); + } + if (irep->syms) { + fprintf(fp, " %s_syms_%d,\t\t\t/* syms */\n", name, n); + } + else { + fputs( " NULL,\t\t\t\t\t/* syms */\n", fp); + } + if (irep->reps) { + fprintf(fp, " %s_reps_%d,\t\t\t/* reps */\n", name, n); + } + else { + fputs( " NULL,\t\t\t\t\t/* reps */\n", fp); + } + fputs( " NULL,\t\t\t\t\t/* lv */\n", fp); + fputs( " NULL,\t\t\t\t\t/* debug_info */\n", fp); + fprintf(fp, " %d,\t\t\t\t\t/* ilen */\n", irep->ilen); + fprintf(fp, " %d,\t\t\t\t\t/* plen */\n", irep->plen); + fprintf(fp, " %d,\t\t\t\t\t/* slen */\n", irep->slen); + fprintf(fp, " %d,\t\t\t\t\t/* rlen */\n", irep->rlen); + fputs( " 0,\t\t\t\t\t/* refcnt */\n};\n", fp); + + return MRB_DUMP_OK; +} + +int +mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, const char *initname) +{ + int n = 0; + + if (fp == NULL || initname == NULL || initname[0] == '\0') { + return MRB_DUMP_INVALID_ARGUMENT; + } + if (fprintf(fp, "#include <mruby.h>\n" "#include <mruby/irep.h>\n\n") < 0) { + return MRB_DUMP_WRITE_FAULT; + } + return dump_irep_struct(mrb, irep, flags, fp, initname, &n); +} + #endif /* MRB_DISABLE_STDIO */ |
