summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/class.c3
-rw-r--r--src/dump.c123
-rw-r--r--src/gc.c11
-rw-r--r--src/kernel.c4
-rw-r--r--src/load.c6
-rw-r--r--src/proc.c4
-rw-r--r--src/symbol.c9
-rw-r--r--src/variable.c12
-rw-r--r--src/vm.c26
9 files changed, 96 insertions, 102 deletions
diff --git a/src/class.c b/src/class.c
index daba6f649..38b9c6740 100644
--- a/src/class.c
+++ b/src/class.c
@@ -2334,6 +2334,9 @@ init_class_new(mrb_state *mrb, struct RClass *cls)
mrb_define_method_raw(mrb, cls, MRB_SYM(new), m);
}
+/* implementation of #send method */
+mrb_value mrb_f_send(mrb_state *mrb, mrb_value self);
+
void
mrb_init_class(mrb_state *mrb)
{
diff --git a/src/dump.c b/src/dump.c
index 8aa7b4edb..4991ebd82 100644
--- a/src/dump.c
+++ b/src/dump.c
@@ -942,7 +942,12 @@ dump_pool(mrb_state *mrb, const mrb_pool_value *p, FILE *fp)
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);
+ if (p->u.f == 0) {
+ fprintf(fp, "{IREP_TT_FLOAT, {.f=%#.1f}},\n", p->u.f);
+ }
+ else {
+ fprintf(fp, "{IREP_TT_FLOAT, {.f="MRB_FLOAT_FMT"}},\n", p->u.f);
+ }
break;
}
}
@@ -951,83 +956,28 @@ dump_pool(mrb_state *mrb, const mrb_pool_value *p, FILE *fp)
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]);
+ fprintf(fp, "\\x%02x", (int)s[i]&0xff);
}
fputs("\"}},\n", fp);
}
return MRB_DUMP_OK;
}
-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},
-};
-
+mrb_bool mrb_sym_static_p(mrb_state *mrb, mrb_sym sym);
+
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 if (name[len-1] == '=') {
- fprintf(fp, "MRB_QSYM(%.*s_e),", (int)len-1, name);
+ const char *name;
+ if (sym == 0) return MRB_DUMP_INVALID_ARGUMENT;
+ name = mrb_sym_name(mrb, sym);
+ if (!name) {
+ fprintf(stderr, "undefined symbol (%d) - define presym\n", sym);
}
- else {
- fprintf(fp, "MRB_SYM(%s),", name);
+ if (!mrb_sym_static_p(mrb, sym)) {
+ fprintf(stderr, "no static symbol (%s) - define presym\n", name);
}
+ fprintf(fp, "%d /* %s */,", sym, name);
return MRB_DUMP_OK;
}
@@ -1065,8 +1015,7 @@ dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp,
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;
+ dump_sym(mrb, irep->syms[i], fp);
}
fputs("};\n", fp);
}
@@ -1078,13 +1027,17 @@ dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *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_irep_%d = {\n", name, n);
+ /* dump lv */
+ if (irep->lv) {
+ len=irep->nlocals;
+ fprintf(fp, "static const struct mrb_lvinfo %s_lv_%d[%d] = {", name, n, len);
+ for (i=0; i+1<len; i++) {
+ fprintf(fp, "{%d,%d},\n", irep->lv[i].name, irep->lv[i].r);
+ }
+ fputs("};\n", fp);
}
+ /* dump irep */
+ fprintf(fp, "static const mrb_irep %s_irep_%d = {\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) {
@@ -1105,9 +1058,14 @@ dump_irep_struct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp,
else {
fputs( "NULL,\n", fp);
}
- fputs( " NULL,\t\t\t\t\t/* lv */\n", fp);
+ if (irep->lv) {
+ fprintf(fp, "%s_lv_%d,\n", name, n);
+ }
+ else {
+ fputs( " NULL,\t\t\t\t\t/* lv */\n", fp);
+ }
fputs( " NULL,\t\t\t\t\t/* debug_info */\n", fp);
- fprintf(fp, " %d,%d,%d,%d,0\n};", irep->ilen, irep->plen, irep->slen, irep->rlen);
+ fprintf(fp, " %d,%d,%d,%d,0\n};\n", irep->ilen, irep->plen, irep->slen, irep->rlen);
return MRB_DUMP_OK;
}
@@ -1116,13 +1074,20 @@ int
mrb_dump_irep_cstruct(mrb_state *mrb, const mrb_irep *irep, uint8_t flags, FILE *fp, const char *initname)
{
int max = 1;
+ int n;
+
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) {
+ if (fprintf(fp, "#include <mruby.h>\n" "#include <mruby/proc.h>\n\n") < 0) {
return MRB_DUMP_WRITE_FAULT;
}
- return dump_irep_struct(mrb, irep, flags, fp, initname, 0, &max);
+ n = dump_irep_struct(mrb, irep, flags, fp, initname, 0, &max);
+ if (n != MRB_DUMP_OK) return n;
+ fprintf(fp, "#ifdef __cplusplus\nextern struct RProc %s[];\n#endif\n", initname);
+ fprintf(fp, "struct RProc %s[] = {{\n", initname);
+ fprintf(fp, "NULL,NULL,MRB_TT_PROC,7,0,{&%s_irep_0},NULL,{NULL},\n}};\n", initname);
+ return MRB_DUMP_OK;
}
#endif /* MRB_DISABLE_STDIO */
diff --git a/src/gc.c b/src/gc.c
index 897fa256f..4bee82364 100644
--- a/src/gc.c
+++ b/src/gc.c
@@ -35,6 +35,11 @@
* Gray - Marked, But the child objects are unmarked.
* Black - Marked, the child objects are also marked.
+ Extra color
+
+ * Red - Static (ROM object) no need to be collected.
+ - All child objects should be Red as well.
+
== Two White Types
There're two white color types in a flip-flop fashion: White-A and White-B,
@@ -185,6 +190,7 @@ gettimeofday_time(void)
#define GC_WHITE_A 1
#define GC_WHITE_B (1 << 1)
#define GC_BLACK (1 << 2)
+#define GC_RED 7
#define GC_WHITES (GC_WHITE_A | GC_WHITE_B)
#define GC_COLOR_MASK 7
@@ -194,7 +200,8 @@ gettimeofday_time(void)
#define paint_partial_white(s, o) ((o)->color = (s)->current_white_part)
#define is_gray(o) ((o)->color == GC_GRAY)
#define is_white(o) ((o)->color & GC_WHITES)
-#define is_black(o) ((o)->color & GC_BLACK)
+#define is_black(o) ((o)->color == GC_BLACK)
+#define is_red(o) ((o)->color == GC_RED)
#define flip_white_part(s) ((s)->current_white_part = other_white_part(s))
#define other_white_part(s) ((s)->current_white_part ^ GC_WHITES)
#define is_dead(s, o) (((o)->color & other_white_part(s) & GC_WHITES) || (o)->tt == MRB_TT_FREE)
@@ -584,7 +591,7 @@ add_gray_list(mrb_state *mrb, mrb_gc *gc, struct RBasic *obj)
static int
ci_nregs(mrb_callinfo *ci)
{
- struct RProc *p = ci->proc;
+ const struct RProc *p = ci->proc;
int n = 0;
if (!p) {
diff --git a/src/kernel.c b/src/kernel.c
index 519052f4b..e4948143d 100644
--- a/src/kernel.c
+++ b/src/kernel.c
@@ -19,7 +19,7 @@ mrb_func_basic_p(mrb_state *mrb, mrb_value obj, mrb_sym mid, mrb_func_t func)
{
struct RClass *c = mrb_class(mrb, obj);
mrb_method_t m = mrb_method_search_vm(mrb, &c, mid);
- struct RProc *p;
+ const struct RProc *p;
if (MRB_METHOD_UNDEF_P(m)) return FALSE;
if (MRB_METHOD_FUNC_P(m))
@@ -143,7 +143,7 @@ mrb_f_block_given_p_m(mrb_state *mrb, mrb_value self)
mrb_value *bp;
int bidx;
struct REnv *e = NULL;
- struct RProc *p;
+ const struct RProc *p;
if (ci <= cibase) {
/* toplevel does not have block */
diff --git a/src/load.c b/src/load.c
index 39644c34b..31059e833 100644
--- a/src/load.c
+++ b/src/load.c
@@ -676,6 +676,12 @@ mrb_load_irep_buf(mrb_state *mrb, const void *buf, size_t bufsize)
return mrb_load_irep_buf_cxt(mrb, buf, bufsize, NULL);
}
+MRB_API mrb_value
+mrb_load_proc(mrb_state *mrb, const struct RProc *proc)
+{
+ return mrb_vm_run(mrb, proc, mrb_top_self(mrb), 0);
+}
+
#ifndef MRB_DISABLE_STDIO
mrb_irep*
diff --git a/src/proc.c b/src/proc.c
index 2da2ec77e..14ba407d8 100644
--- a/src/proc.c
+++ b/src/proc.c
@@ -80,7 +80,7 @@ static void
closure_setup(mrb_state *mrb, struct RProc *p)
{
mrb_callinfo *ci = mrb->c->ci;
- struct RProc *up = p->upper;
+ const struct RProc *up = p->upper;
struct REnv *e = NULL;
if (ci && ci->env) {
@@ -170,7 +170,7 @@ mrb_closure_new_cfunc(mrb_state *mrb, mrb_func_t func, int nlocals)
MRB_API mrb_value
mrb_proc_cfunc_env_get(mrb_state *mrb, mrb_int idx)
{
- struct RProc *p = mrb->c->ci->proc;
+ const struct RProc *p = mrb->c->ci->proc;
struct REnv *e;
if (!p || !MRB_PROC_CFUNC_P(p)) {
diff --git a/src/symbol.c b/src/symbol.c
index 9981bad7c..3723335cd 100644
--- a/src/symbol.c
+++ b/src/symbol.c
@@ -330,6 +330,15 @@ mrb_sym_name_len(mrb_state *mrb, mrb_sym sym, mrb_int *lenp)
return sym2name_len(mrb, sym, mrb->symbuf, lenp);
}
+mrb_bool
+mrb_sym_static_p(mrb_state *mrb, mrb_sym sym)
+{
+ if (SYMBOL_INLINE_P(sym)) return TRUE;
+ sym >>= SYMBOL_NORMAL_SHIFT;
+ if (sym > MRB_PRESYM_MAX) return FALSE;
+ return TRUE;
+}
+
void
mrb_free_symtbl(mrb_state *mrb)
{
diff --git a/src/variable.c b/src/variable.c
index 8fcbd6427..526d88c80 100644
--- a/src/variable.c
+++ b/src/variable.c
@@ -741,11 +741,11 @@ mrb_vm_cv_get(mrb_state *mrb, mrb_sym sym)
{
struct RClass *c;
- struct RProc *p = mrb->c->ci->proc;
+ const struct RProc *p = mrb->c->ci->proc;
for (;;) {
c = MRB_PROC_TARGET_CLASS(p);
- if (c->tt != MRB_TT_SCLASS) break;
+ if (c && c->tt != MRB_TT_SCLASS) break;
p = p->upper;
}
return mrb_mod_cv_get(mrb, c, sym);
@@ -755,11 +755,11 @@ void
mrb_vm_cv_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
{
struct RClass *c;
- struct RProc *p = mrb->c->ci->proc;
+ const struct RProc *p = mrb->c->ci->proc;
for (;;) {
c = MRB_PROC_TARGET_CLASS(p);
- if (c->tt != MRB_TT_SCLASS) break;
+ if (c && c->tt != MRB_TT_SCLASS) break;
p = p->upper;
}
mrb_mod_cv_set(mrb, c, sym, v);
@@ -817,9 +817,10 @@ mrb_vm_const_get(mrb_state *mrb, mrb_sym sym)
struct RClass *c;
struct RClass *c2;
mrb_value v;
- struct RProc *proc;
+ const struct RProc *proc;
c = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
+ if (!c) c = mrb->object_class;
if (iv_get(mrb, c->iv, sym, &v)) {
return v;
}
@@ -862,6 +863,7 @@ mrb_vm_const_set(mrb_state *mrb, mrb_sym sym, mrb_value v)
struct RClass *c;
c = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
+ if (!c) c = mrb->object_class;
mrb_obj_iv_set(mrb, (struct RObject*)c, sym, v);
}
diff --git a/src/vm.c b/src/vm.c
index c3fa12d3d..62805b7ed 100644
--- a/src/vm.c
+++ b/src/vm.c
@@ -224,7 +224,7 @@ mrb_stack_extend(mrb_state *mrb, mrb_int room)
static inline struct REnv*
uvenv(mrb_state *mrb, int up)
{
- struct RProc *proc = mrb->c->ci->proc;
+ const struct RProc *proc = mrb->c->ci->proc;
struct REnv *e;
while (up--) {
@@ -247,8 +247,8 @@ uvenv(mrb_state *mrb, int up)
return NULL;
}
-static inline struct RProc*
-top_proc(mrb_state *mrb, struct RProc *proc)
+static inline const struct RProc*
+top_proc(mrb_state *mrb, const struct RProc *proc)
{
while (proc->upper) {
if (MRB_PROC_SCOPE_P(proc) || MRB_PROC_STRICT_P(proc))
@@ -327,7 +327,7 @@ cipop(mrb_state *mrb)
}
void mrb_exc_set(mrb_state *mrb, mrb_value exc);
-static mrb_value mrb_run(mrb_state *mrb, struct RProc* proc, mrb_value self);
+static mrb_value mrb_run(mrb_state *mrb, const struct RProc* proc, mrb_value self);
static void
ecall(mrb_state *mrb)
@@ -423,7 +423,7 @@ mrb_funcall_id(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, ...)
static int
ci_nregs(mrb_callinfo *ci)
{
- struct RProc *p;
+ const struct RProc *p;
int n = 0;
if (!ci) return 3;
@@ -821,7 +821,7 @@ mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const
}
static struct RBreak*
-break_new(mrb_state *mrb, struct RProc *p, mrb_value val)
+break_new(mrb_state *mrb, const struct RProc *p, mrb_value val)
{
struct RBreak *brk;
@@ -918,7 +918,7 @@ argnum_error(mrb_state *mrb, mrb_int num)
#endif
MRB_API mrb_value
-mrb_vm_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
+mrb_vm_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, unsigned int stack_keep)
{
const mrb_irep *irep = proc->body.irep;
mrb_value result;
@@ -961,7 +961,7 @@ check_target_class(mrb_state *mrb)
void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self);
MRB_API mrb_value
-mrb_vm_exec(mrb_state *mrb, struct RProc *proc, const mrb_code *pc)
+mrb_vm_exec(mrb_state *mrb, const struct RProc *proc, const mrb_code *pc)
{
/* mrb_assert(MRB_PROC_CFUNC_P(proc)) */
const mrb_code *pc0 = pc;
@@ -1534,7 +1534,7 @@ RETRY_TRY_BLOCK:
struct RClass *cls;
mrb_callinfo *ci = mrb->c->ci;
mrb_value recv, blk;
- struct RProc *p = ci->proc;
+ const struct RProc *p = ci->proc;
mrb_sym mid = ci->mid;
struct RClass* target_class = MRB_PROC_TARGET_CLASS(p);
@@ -1975,7 +1975,7 @@ RETRY_TRY_BLOCK:
else {
int acc;
mrb_value v;
- struct RProc *dst;
+ const struct RProc *dst;
ci = mrb->c->ci;
v = regs[a];
@@ -2612,6 +2612,7 @@ RETRY_TRY_BLOCK:
super = regs[a+1];
if (mrb_nil_p(base)) {
baseclass = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
+ if (!baseclass) baseclass = mrb->object_class;
base = mrb_obj_value(baseclass);
}
c = mrb_vm_define_class(mrb, base, super, id);
@@ -2628,6 +2629,7 @@ RETRY_TRY_BLOCK:
base = regs[a];
if (mrb_nil_p(base)) {
baseclass = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc);
+ if (!baseclass) baseclass = mrb->object_class;
base = mrb_obj_value(baseclass);
}
cls = mrb_vm_define_module(mrb, base, id);
@@ -2782,7 +2784,7 @@ RETRY_TRY_BLOCK:
}
static mrb_value
-mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
+mrb_run(mrb_state *mrb, const struct RProc *proc, mrb_value self)
{
if (mrb->c->ci->argc < 0) {
return mrb_vm_run(mrb, proc, self, 3); /* receiver, args and block) */
@@ -2793,7 +2795,7 @@ mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
}
MRB_API mrb_value
-mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
+mrb_top_run(mrb_state *mrb, const struct RProc *proc, mrb_value self, unsigned int stack_keep)
{
mrb_value v;