Commit 00f3484f authored by Yukihiro "Matz" Matsumoto's avatar Yukihiro "Matz" Matsumoto

Merge pull request #1986 from take-cheeze/proc_macro

REnv macros.
parents d7c29322 755ded2e
...@@ -20,6 +20,10 @@ struct REnv { ...@@ -20,6 +20,10 @@ struct REnv {
int cioff; int cioff;
}; };
#define MRB_ENV_STACK_LEN(e) ((e)->flags)
#define MRB_ENV_UNSHARE_STACK(e) ((e)->cioff = -1)
#define MRB_ENV_STACK_SHARED_P(e) ((e)->cioff >= 0)
struct RProc { struct RProc {
MRB_OBJECT_HEADER; MRB_OBJECT_HEADER;
union { union {
......
...@@ -17,8 +17,8 @@ mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t f, mrb_int argc, const mr ...@@ -17,8 +17,8 @@ mrb_proc_new_cfunc_with_env(mrb_state *mrb, mrb_func_t f, mrb_int argc, const mr
p->env = e; p->env = e;
mrb_gc_arena_restore(mrb, ai); mrb_gc_arena_restore(mrb, ai);
e->cioff = -1; MRB_ENV_UNSHARE_STACK(e);
e->flags = argc; MRB_ENV_STACK_LEN(e) = argc;
e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc); e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc);
for (i = 0; i < argc; ++i) { for (i = 0; i < argc; ++i) {
e->stack[i] = argv[i]; e->stack[i] = argv[i];
...@@ -39,9 +39,9 @@ mrb_cfunc_env_get(mrb_state *mrb, mrb_int idx) ...@@ -39,9 +39,9 @@ mrb_cfunc_env_get(mrb_state *mrb, mrb_int idx)
if (!e) { if (!e) {
mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from cfunc Proc without REnv."); mrb_raise(mrb, E_TYPE_ERROR, "Can't get cfunc env from cfunc Proc without REnv.");
} }
if (idx < 0 || e->flags <= idx) { if (idx < 0 || MRB_ENV_STACK_LEN(e) <= idx) {
mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %S (expected: 0 <= index < %S)", mrb_raisef(mrb, E_INDEX_ERROR, "Env index out of range: %S (expected: 0 <= index < %S)",
mrb_fixnum_value(idx), mrb_fixnum_value(e->flags)); mrb_fixnum_value(idx), mrb_fixnum_value(MRB_ENV_STACK_LEN(e)));
} }
return e->stack[idx]; return e->stack[idx];
......
...@@ -515,10 +515,10 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj) ...@@ -515,10 +515,10 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
{ {
struct REnv *e = (struct REnv*)obj; struct REnv *e = (struct REnv*)obj;
if (e->cioff < 0) { if (!MRB_ENV_STACK_SHARED_P(e)) {
int i, len; int i, len;
len = (int)e->flags; len = (int)MRB_ENV_STACK_LEN(e);
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
mrb_gc_mark_value(mrb, e->stack[i]); mrb_gc_mark_value(mrb, e->stack[i]);
} }
...@@ -612,7 +612,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj) ...@@ -612,7 +612,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
{ {
struct REnv *e = (struct REnv*)obj; struct REnv *e = (struct REnv*)obj;
if (e->cioff < 0) { if (!MRB_ENV_STACK_SHARED_P(e)) {
mrb_free(mrb, e->stack); mrb_free(mrb, e->stack);
e->stack = NULL; e->stack = NULL;
} }
......
...@@ -41,7 +41,7 @@ closure_setup(mrb_state *mrb, struct RProc *p, int nlocals) ...@@ -41,7 +41,7 @@ closure_setup(mrb_state *mrb, struct RProc *p, int nlocals)
if (!mrb->c->ci->env) { if (!mrb->c->ci->env) {
e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci->proc->env); e = (struct REnv*)mrb_obj_alloc(mrb, MRB_TT_ENV, (struct RClass*)mrb->c->ci->proc->env);
e->flags= (unsigned int)nlocals; MRB_ENV_STACK_LEN(e)= (unsigned int)nlocals;
e->mid = mrb->c->ci->mid; e->mid = mrb->c->ci->mid;
e->cioff = mrb->c->ci - mrb->c->cibase; e->cioff = mrb->c->ci - mrb->c->cibase;
e->stack = mrb->c->stack; e->stack = mrb->c->stack;
......
...@@ -121,7 +121,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase) ...@@ -121,7 +121,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase)
if (newbase == oldbase) return; if (newbase == oldbase) return;
while (ci <= mrb->c->ci) { while (ci <= mrb->c->ci) {
struct REnv *e = ci->env; struct REnv *e = ci->env;
if (e && e->cioff >= 0) { if (e && MRB_ENV_STACK_SHARED_P(e)) {
ptrdiff_t off = e->stack - oldbase; ptrdiff_t off = e->stack - oldbase;
e->stack = newbase + off; e->stack = newbase + off;
...@@ -188,7 +188,7 @@ is_strict(mrb_state *mrb, struct REnv *e) ...@@ -188,7 +188,7 @@ is_strict(mrb_state *mrb, struct REnv *e)
{ {
int cioff = e->cioff; int cioff = e->cioff;
if (cioff >= 0 && mrb->c->cibase[cioff].proc && if (MRB_ENV_STACK_SHARED_P(e) && mrb->c->cibase[cioff].proc &&
MRB_PROC_STRICT_P(mrb->c->cibase[cioff].proc)) { MRB_PROC_STRICT_P(mrb->c->cibase[cioff].proc)) {
return TRUE; return TRUE;
} }
...@@ -245,10 +245,10 @@ cipop(mrb_state *mrb) ...@@ -245,10 +245,10 @@ cipop(mrb_state *mrb)
if (c->ci->env) { if (c->ci->env) {
struct REnv *e = c->ci->env; struct REnv *e = c->ci->env;
size_t len = (size_t)e->flags; size_t len = (size_t)MRB_ENV_STACK_LEN(e);
mrb_value *p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len); mrb_value *p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len);
e->cioff = -1; MRB_ENV_UNSHARE_STACK(e);
stack_copy(p, e->stack, len); stack_copy(p, e->stack, len);
e->stack = p; e->stack = p;
} }
...@@ -1406,7 +1406,7 @@ RETRY_TRY_BLOCK: ...@@ -1406,7 +1406,7 @@ RETRY_TRY_BLOCK:
if (proc->env && !MRB_PROC_STRICT_P(proc)) { if (proc->env && !MRB_PROC_STRICT_P(proc)) {
struct REnv *e = top_env(mrb, proc); struct REnv *e = top_env(mrb, proc);
if (e->cioff < 0) { if (!MRB_ENV_STACK_SHARED_P(e)) {
localjump_error(mrb, LOCALJUMP_ERROR_RETURN); localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
goto L_RAISE; goto L_RAISE;
} }
...@@ -1437,7 +1437,7 @@ RETRY_TRY_BLOCK: ...@@ -1437,7 +1437,7 @@ RETRY_TRY_BLOCK:
ci = mrb->c->ci; ci = mrb->c->ci;
break; break;
case OP_R_BREAK: case OP_R_BREAK:
if (!proc->env || proc->env->cioff < 0) { if (!proc->env || !MRB_ENV_STACK_SHARED_P(proc->env)) {
localjump_error(mrb, LOCALJUMP_ERROR_BREAK); localjump_error(mrb, LOCALJUMP_ERROR_BREAK);
goto L_RAISE; goto L_RAISE;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment