diff --git a/src/c/interpreter.d b/src/c/interpreter.d index cb2074e78..52b1fbef0 100644 --- a/src/c/interpreter.d +++ b/src/c/interpreter.d @@ -121,9 +121,34 @@ VEclose_around_arg_type() * sym_macro = ( si::symbol-macro macro_function[bytecodes] . macro_name ) */ -#define bind_var(env, var, val) CONS(CONS(var, val), (env)) -#define bind_function(env, fun) CONS(fun, (env)) -#define bind_frame(env, id, name) CONS(CONS(id, name), (env)) +#define bind_lcl(env, entry) push_lcl(&env, entry) +#define tack_lcl(env, entries) foot_lcl(&env, entries) + +#define bind_var(env, var, val) bind_lcl(env, CONS(var, val)) +#define bind_function(env, fun) bind_lcl(env, fun) +#define bind_frame(env, id, name) bind_lcl(env, CONS(id, name)) + +#define unbind_lcl(env, n) drop_lcl(&env, n) +#define tangle_lcl(stack) (stack) +#define unwind_lcl(stack, where) (stack = where) + +static void +push_lcl(cl_object *stack, cl_object new) +{ + *stack = ecl_cons(new, *stack); +} + +static void +foot_lcl(cl_object *stack, cl_object list) +{ + *stack = ecl_append(list, *stack); +} + +static void +drop_lcl(cl_object *stack, cl_fixnum n) +{ + while (n--) *stack = ECL_CONS_CDR(*stack); +} static cl_object ecl_lcl_env_get_record(cl_object env, int s) @@ -697,10 +722,10 @@ ecl_interpret(cl_object frame, cl_object closure, cl_object bytecodes) for(idx = 0; idxnvalues) ? the_env->values[n] : ECL_NIL); + bind_var(lcl_env, var_name, + (n < the_env->nvalues) ? the_env->values[n] : ECL_NIL); THREAD_NEXT; } CASE(OP_BINDS); { @@ -1070,24 +1090,24 @@ ecl_interpret(cl_object frame, cl_object closure, cl_object bytecodes) CASE(OP_BLOCK); { GET_DATA(reg0, vector, data); reg1 = ecl_make_fixnum(the_env->frame_id++); - lcl_env = bind_frame(lcl_env, reg1, reg0); + bind_frame(lcl_env, reg1, reg0); THREAD_NEXT; } CASE(OP_DO); { reg0 = ECL_NIL; reg1 = ecl_make_fixnum(the_env->frame_id++); - lcl_env = bind_frame(lcl_env, reg1, reg0); + bind_frame(lcl_env, reg1, reg0); THREAD_NEXT; } CASE(OP_CATCH); { reg1 = reg0; - lcl_env = bind_frame(lcl_env, reg1, reg0); + bind_frame(lcl_env, reg1, reg0); THREAD_NEXT; } CASE(OP_FRAME); { cl_opcode *exit; GET_LABEL(exit, vector); - ECL_STACK_PUSH(the_env, lcl_env); + ECL_STACK_PUSH(the_env, tangle_lcl(lcl_env)); ECL_STACK_PUSH(the_env, (cl_object)exit); ecl_frs_push(the_env,reg1); if (__ecl_frs_push_result == 0) { @@ -1095,7 +1115,7 @@ ecl_interpret(cl_object frame, cl_object closure, cl_object bytecodes) } else { reg0 = the_env->values[0]; vector = (cl_opcode *)ECL_STACK_REF(the_env,-1); /* FIXME! */ - lcl_env = ECL_STACK_REF(the_env,-2); + unwind_lcl(lcl_env, ECL_STACK_REF(the_env, -2)); goto DO_EXIT_FRAME; } } @@ -1115,7 +1135,7 @@ ecl_interpret(cl_object frame, cl_object closure, cl_object bytecodes) CASE(OP_TAGBODY); { int n; GET_OPARG(n, vector); - ECL_STACK_PUSH(the_env, lcl_env); + ECL_STACK_PUSH(the_env, tangle_lcl(lcl_env)); ECL_STACK_PUSH(the_env, (cl_object)vector); /* FIXME! */ vector += n * OPARG_SIZE; ecl_frs_push(the_env,reg1); @@ -1124,7 +1144,7 @@ ecl_interpret(cl_object frame, cl_object closure, cl_object bytecodes) ranges from 0 to ntags-1, depending on the tag. These numbers are indices into the jump table and are computed at compile time. */ cl_opcode *table = (cl_opcode *)ECL_STACK_REF(the_env,-1); - lcl_env = ECL_STACK_REF(the_env,-2); + unwind_lcl(lcl_env, ECL_STACK_REF(the_env,-2)); table = table + ecl_fixnum(the_env->values[0]) * OPARG_SIZE; vector = table + *(cl_oparg *)table; } @@ -1137,7 +1157,7 @@ ecl_interpret(cl_object frame, cl_object closure, cl_object bytecodes) DO_EXIT_FRAME: ecl_frs_pop(the_env); ECL_STACK_POP_N_UNSAFE(the_env, 2); - lcl_env = ECL_CONS_CDR(lcl_env); + unbind_lcl(lcl_env, 1); THREAD_NEXT; } CASE(OP_NIL); { @@ -1241,13 +1261,13 @@ ecl_interpret(cl_object frame, cl_object closure, cl_object bytecodes) CASE(OP_PROTECT); { cl_opcode *exit; GET_LABEL(exit, vector); - ECL_STACK_PUSH(the_env, lcl_env); + ECL_STACK_PUSH(the_env, tangle_lcl(lcl_env)); ECL_STACK_PUSH(the_env, (cl_object)exit); ecl_frs_push(the_env,ECL_PROTECT_TAG); if (__ecl_frs_push_result != 0) { ecl_frs_pop(the_env); vector = (cl_opcode *)ECL_STACK_POP_UNSAFE(the_env); - lcl_env = ECL_STACK_POP_UNSAFE(the_env); + unwind_lcl(lcl_env, ECL_STACK_POP_UNSAFE(the_env)); reg0 = the_env->values[0]; ECL_STACK_PUSH(the_env, ecl_make_fixnum(the_env->nlj_fr - the_env->frs_top)); goto PUSH_VALUES; @@ -1258,7 +1278,7 @@ ecl_interpret(cl_object frame, cl_object closure, cl_object bytecodes) ecl_bds_unwind(the_env, the_env->frs_top->frs_bds_top_index); ecl_frs_pop(the_env); (void)ECL_STACK_POP_UNSAFE(the_env); - lcl_env = ECL_STACK_POP_UNSAFE(the_env); + unwind_lcl(lcl_env, ECL_STACK_POP_UNSAFE(the_env)); ECL_STACK_PUSH(the_env, ecl_make_fixnum(1)); goto PUSH_VALUES; }