summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorYukihiro "Matz" Matsumoto <[email protected]>2020-06-09 22:30:14 +0900
committerYukihiro "Matz" Matsumoto <[email protected]>2020-10-12 16:21:09 +0900
commit7deb41b0e88b3670476ed86bab541340f5551b52 (patch)
tree67f3688de3a1c4c31be6c9074d0dcd273556fc90
parentf1c06eef7c17a5bf2ea4a35021d563af5f3147a9 (diff)
downloadmruby-7deb41b0e88b3670476ed86bab541340f5551b52.tar.gz
mruby-7deb41b0e88b3670476ed86bab541340f5551b52.zip
Generate C source file to represent `mrb_irep` structures.
Type `mrbc -S -B<init> -o<outfile> <rbfiles...>` to generate the C source code that holds compiled `mrb_irep`. Appending the following code to the bottom of the generated code, `mruby` executes the compiled code: ```C int main() { mrb_state *mrb = mrb_open(); struct RProc *p = mrb_proc_new(mrb, &init_irep); mrb_vm_run(mrb, p, mrb_top_self(mrb), 0); mrb_close(mrb); return 0; } ``` Eventually static compile should use this representation, instead of `uint8_t` array that holds `mrb` data, so that we can skip interpreting `mrb` data.
-rw-r--r--include/mruby/irep.h1
-rw-r--r--src/dump.c99
2 files changed, 74 insertions, 26 deletions
diff --git a/include/mruby/irep.h b/include/mruby/irep.h
index 359fb6796..64a38227c 100644
--- a/include/mruby/irep.h
+++ b/include/mruby/irep.h
@@ -65,6 +65,7 @@ typedef struct mrb_irep {
#define MRB_ISEQ_NO_FREE 1
#define MRB_IREP_NO_FREE 2
+#define MRB_IREP_STATIC 3
MRB_API mrb_irep *mrb_add_irep(mrb_state *mrb);
diff --git a/src/dump.c b/src/dump.c
index 3aade76a3..8aa7b4edb 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -930,6 +930,34 @@ mrb_dump_irep_cfunc(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *f
return result;
}
+static int
+dump_pool(mrb_state *mrb, const mrb_pool_value *p, FILE *fp)
+{
+ if (p->tt & IREP_TT_NFLAG) { /* number */
+ switch (p->tt) {
+ case IREP_TT_INT32:
+ fprintf(fp, "{IREP_TT_INT32, {.i32=%"PRId32"}},\n", p->u.i32);
+ break;
+ case IREP_TT_INT64:
+ fprintf(fp, "{IREP_TT_INT64, {.i64=%"PRId64"}},\n", p->u.i64);
+ break;
+ case IREP_TT_FLOAT:
+ fprintf(fp, "{IREP_TT_FLOAT, {.f="MRB_FLOAT_FMT"}},\n", p->u.f);
+ break;
+ }
+ }
+ else { /* string */
+ int i, len = p->tt>>2;
+ const char *s = p->u.str;
+ fprintf(fp, "{IREP_TT_STR|(%d<<2), {.str=\"", len);
+ for (i=0; i<len; i++) {
+ fprintf(fp, "\\%03o", (int)s[i]);
+ }
+ fputs("\"}},\n", fp);
+ }
+ return MRB_DUMP_OK;
+}
+
static struct {
const char *op;
const char *name;
@@ -994,6 +1022,9 @@ dump_sym(mrb_state *mrb, mrb_sym sym, FILE *fp)
else if (name[len-1] == '?') {
fprintf(fp, "MRB_QSYM(%.*s_p),", (int)len-1, name);
}
+ else if (name[len-1] == '=') {
+ fprintf(fp, "MRB_QSYM(%.*s_e),", (int)len-1, name);
+ }
else {
fprintf(fp, "MRB_SYM(%s),", name);
}
@@ -1001,26 +1032,49 @@ dump_sym(mrb_state *mrb, mrb_sym sym, FILE *fp)
}
static int
-dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, const char *name, int *np)
+dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, const char *name, int n, int *mp)
{
- int n = *np; /* this level */
int i, len;
+ int max = *mp;
/* dump reps */
+ if (irep->reps) {
+ for (i=0,len=irep->rlen; i<len; i++) {
+ *mp += len;
+ if (dump_irep_struct(mrb, irep->reps[i], flags, fp, name, max+i, mp) != MRB_DUMP_OK)
+ return MRB_DUMP_INVALID_ARGUMENT;
+ }
+ fprintf(fp, "static const mrb_irep *%s_reps_%d[%d] = {\n", name, n, len);
+ for (i=0,len=irep->rlen; i<len; i++) {
+ fprintf(fp, " &%s_irep_%d,\n", name, max+i);
+ }
+ fputs("};\n", fp);
+ }
/* dump pool */
+ if (irep->pool) {
+ len=irep->plen;
+ fprintf(fp, "static const mrb_pool_value %s_pool_%d[%d] = {\n", name, n, len);
+ for (i=0; i<len; i++) {
+ if (dump_pool(mrb, &irep->pool[i], fp) != MRB_DUMP_OK)
+ return MRB_DUMP_INVALID_ARGUMENT;
+ }
+ fputs("};\n", fp);
+ }
/* 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++) {
+ len=irep->slen;
+ fprintf(fp, "static const mrb_sym %s_syms_%d[%d] = {", name, n, len);
+ for (i=0; 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);
+ len=irep->ilen;
+ fprintf(fp, "static const mrb_code %s_iseq_%d[%d] = {", name, n, len);
+ for (i=0; i<len; i++) {
+ if (i%20 == 0) fputs("\n", fp);
fprintf(fp, "0x%02x,", irep->iseq[i]);
}
fputs("};\n", fp);
@@ -1029,37 +1083,31 @@ dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp,
fprintf(fp, "static const mrb_irep %s = {\n", name);
}
else {
- fprintf(fp, "static const mrb_irep %s_%d = {\n", name, n);
+ fprintf(fp, "static const mrb_irep %s_irep_%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);
+ fprintf(fp, " %d,%d,\n", irep->nlocals, irep->nregs);
+ fprintf(fp, " MRB_IREP_STATIC,%s_iseq_%d,\n", name, n);
if (irep->pool) {
- fprintf(fp, " %s_pool_%d,\t\t/* pool */\n", name, n);
+ fprintf(fp, " %s_pool_%d,", name, n);
}
else {
- fputs( " NULL,\t\t\t\t\t/* pool */\n", fp);
+ fputs( " NULL,", fp);
}
if (irep->syms) {
- fprintf(fp, " %s_syms_%d,\t\t\t/* syms */\n", name, n);
+ fprintf(fp, "%s_syms_%d,", name, n);
}
else {
- fputs( " NULL,\t\t\t\t\t/* syms */\n", fp);
+ fputs( "NULL,", fp);
}
if (irep->reps) {
- fprintf(fp, " %s_reps_%d,\t\t\t/* reps */\n", name, n);
+ fprintf(fp, "%s_reps_%d,\n", name, n);
}
else {
- fputs( " NULL,\t\t\t\t\t/* reps */\n", fp);
+ fputs( "NULL,\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);
+ fprintf(fp, " %d,%d,%d,%d,0\n};", irep->ilen, irep->plen, irep->slen, irep->rlen);
return MRB_DUMP_OK;
}
@@ -1067,15 +1115,14 @@ dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp,
int
mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, const char *initname)
{
- int n = 0;
-
+ int max = 1;
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);
+ return dump_irep_struct(mrb, irep, flags, fp, initname, 0, &max);
}
#endif /* MRB_DISABLE_STDIO */