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 {
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 {
MRB_OBJECT_HEADER;
union {
......
......@@ -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;
mrb_gc_arena_restore(mrb, ai);
e->cioff = -1;
e->flags = argc;
MRB_ENV_UNSHARE_STACK(e);
MRB_ENV_STACK_LEN(e) = argc;
e->stack = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value) * argc);
for (i = 0; i < argc; ++i) {
e->stack[i] = argv[i];
......@@ -39,9 +39,9 @@ mrb_cfunc_env_get(mrb_state *mrb, mrb_int idx)
if (!e) {
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_fixnum_value(idx), mrb_fixnum_value(e->flags));
mrb_fixnum_value(idx), mrb_fixnum_value(MRB_ENV_STACK_LEN(e)));
}
return e->stack[idx];
......
......@@ -515,10 +515,10 @@ gc_mark_children(mrb_state *mrb, struct RBasic *obj)
{
struct REnv *e = (struct REnv*)obj;
if (e->cioff < 0) {
if (!MRB_ENV_STACK_SHARED_P(e)) {
int i, len;
len = (int)e->flags;
len = (int)MRB_ENV_STACK_LEN(e);
for (i=0; i<len; i++) {
mrb_gc_mark_value(mrb, e->stack[i]);
}
......@@ -612,7 +612,7 @@ obj_free(mrb_state *mrb, struct RBasic *obj)
{
struct REnv *e = (struct REnv*)obj;
if (e->cioff < 0) {
if (!MRB_ENV_STACK_SHARED_P(e)) {
mrb_free(mrb, e->stack);
e->stack = NULL;
}
......
......@@ -41,7 +41,7 @@ closure_setup(mrb_state *mrb, struct RProc *p, int nlocals)
if (!mrb->c->ci->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->cioff = mrb->c->ci - mrb->c->cibase;
e->stack = mrb->c->stack;
......
......@@ -121,7 +121,7 @@ envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase)
if (newbase == oldbase) return;
while (ci <= mrb->c->ci) {
struct REnv *e = ci->env;
if (e && e->cioff >= 0) {
if (e && MRB_ENV_STACK_SHARED_P(e)) {
ptrdiff_t off = e->stack - oldbase;
e->stack = newbase + off;
......@@ -188,7 +188,7 @@ is_strict(mrb_state *mrb, struct REnv *e)
{
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)) {
return TRUE;
}
......@@ -245,10 +245,10 @@ cipop(mrb_state *mrb)
if (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);
e->cioff = -1;
MRB_ENV_UNSHARE_STACK(e);
stack_copy(p, e->stack, len);
e->stack = p;
}
......@@ -1406,7 +1406,7 @@ RETRY_TRY_BLOCK:
if (proc->env && !MRB_PROC_STRICT_P(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);
goto L_RAISE;
}
......@@ -1437,7 +1437,7 @@ RETRY_TRY_BLOCK:
ci = mrb->c->ci;
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);
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