diff --git a/src/aclocal.m4 b/src/aclocal.m4 index 7fa855973..a5d0e065d 100644 --- a/src/aclocal.m4 +++ b/src/aclocal.m4 @@ -573,6 +573,7 @@ case "${host_cpu}" in EXTRA_OBJS="${EXTRA_OBJS} apply_x86.o" AC_DEFINE(ECL_ASM_APPLY) fi + AC_DEFINE(ECL_USE_VARARG_AS_POINTER) dynamic_ffi=yes ;; x86_64 ) diff --git a/src/c/Makefile.in b/src/c/Makefile.in index c60c3c4d8..5f58729e9 100644 --- a/src/c/Makefile.in +++ b/src/c/Makefile.in @@ -55,7 +55,7 @@ OBJS = main.o symbol.o package.o list.o\ all: $(DPP) ../libeclmin.a ../cinit.o -.c.S: $(HFILES) +.c.s: $(HFILES) $(CC) -DECLDIR="\"@ecldir@\"" $(CFLAGS) -S -o $@ $< .c.o: $(HFILES) $(CC) -DECLDIR="\"@ecldir@\"" $(CFLAGS) -o $@ $< diff --git a/src/c/compiler.d b/src/c/compiler.d index 46878df66..00719925e 100644 --- a/src/c/compiler.d +++ b/src/c/compiler.d @@ -2103,6 +2103,11 @@ for special form ~S.", 1, function); static int compile_body(cl_object body, int flags) { if (ENV->lexical_level == 0 && !ecl_endp(body)) { + struct ecl_stack_frame frame; + frame.t = t_frame; + frame.stack = frame.base = 0; + frame.size = 0; + frame.env = ecl_process_env(); while (!ecl_endp(CDR(body))) { struct cl_compiler_env *old_c_env = ENV; struct cl_compiler_env new_c_env = *old_c_env; @@ -2115,7 +2120,7 @@ compile_body(cl_object body, int flags) { VALUES(0) = Cnil; NVALUES = 0; bytecodes = asm_end(handle); - ecl_interpret(Cnil, ENV->lex_env, bytecodes, 0); + ecl_interpret((cl_object)&frame, ENV->lex_env, bytecodes, 0); asm_clear(handle); ENV = old_c_env; #ifdef GBC_BOEHM @@ -2764,13 +2769,19 @@ si_make_lambda(cl_object name, cl_object rest) VALUES(0) = Cnil; NVALUES = 0; { - cl_object output = ecl_interpret(Cnil, interpreter_env, bytecodes, 0); + struct ecl_stack_frame frame; + cl_object output; + frame.t = t_frame; + frame.stack = frame.base = 0; + frame.size = 0; + frame.env = the_env; + output = ecl_interpret((cl_object)&frame, interpreter_env, bytecodes, 0); #ifdef GBC_BOEHM - GC_free(bytecodes->bytecodes.code); - GC_free(bytecodes->bytecodes.data); - GC_free(bytecodes); + GC_free(bytecodes->bytecodes.code); + GC_free(bytecodes->bytecodes.data); + GC_free(bytecodes); #endif - ecl_ihs_pop(the_env); - return output; + ecl_ihs_pop(the_env); + return output; } @) diff --git a/src/c/eval.d b/src/c/eval.d index 67d873b8c..2349105be 100644 --- a/src/c/eval.d +++ b/src/c/eval.d @@ -38,8 +38,8 @@ _ecl_va_sp(cl_narg narg) cl_object ecl_apply_from_stack_frame(cl_object frame, cl_object x) { - cl_object *sp = frame->frame.bottom; - cl_index narg = frame->frame.top - sp; + cl_object *sp = frame->frame.base; + cl_index narg = frame->frame.size; cl_object fun = x; AGAIN: frame->frame.env->function = fun; @@ -150,9 +150,10 @@ cl_funcall(cl_narg narg, cl_object function, ...) } if (type_of(lastarg) == t_frame) { /* This could be replaced with a memcpy() */ - cl_object *p = lastarg->frame.bottom; - while (p != lastarg->frame.top) { - ecl_stack_frame_push(frame, *(p++)); + cl_object *p = lastarg->frame.base; + cl_index i; + for (i = 0; i < lastarg->frame.size; i++) { + ecl_stack_frame_push(frame, lastarg->frame.base[i]); } } else loop_for_in (lastarg) { if (i >= CALL_ARGUMENTS_LIMIT) { diff --git a/src/c/gfun.d b/src/c/gfun.d index d6cce56d8..6ee53a683 100644 --- a/src/c/gfun.d +++ b/src/c/gfun.d @@ -329,8 +329,8 @@ search_method_hash(cl_env_ptr env, cl_object keys) static cl_object get_spec_vector(cl_env_ptr env, cl_object frame, cl_object gf) { - cl_object *args = frame->frame.bottom; - cl_index narg = frame->frame.top - args; + cl_object *args = frame->frame.base; + cl_index narg = frame->frame.size; cl_object spec_how_list = GFUN_SPEC(gf); cl_object vector = env->method_spec_vector; cl_object *argtype = vector->vector.self.t; @@ -360,13 +360,14 @@ compute_applicable_method(cl_object frame, cl_object gf) /* method not cached */ cl_object methods, arglist, func; cl_object *p; - for (p = frame->frame.top, arglist = Cnil; p != frame->frame.bottom; ) { + for (p = frame->frame.base + frame->frame.size, arglist = Cnil; + p != frame->frame.base; ) { arglist = CONS(*(--p), arglist); } methods = funcall(3, @'compute-applicable-methods', gf, arglist); if (methods == Cnil) { func = funcall(3, @'no-applicable-method', gf, arglist); - frame->frame.bottom[0] = OBJNULL; + frame->frame.base[0] = OBJNULL; return func; } else { return funcall(4, @'clos::compute-effective-method', gf, diff --git a/src/c/interpreter.d b/src/c/interpreter.d index fa52213c2..831a6ec4a 100644 --- a/src/c/interpreter.d +++ b/src/c/interpreter.d @@ -138,19 +138,20 @@ ecl_stack_push_list(cl_env_ptr env, cl_object list) cl_object ecl_stack_frame_open(cl_env_ptr env, cl_object f, cl_index size) { - cl_object *top = env->stack_top; + cl_object *base = env->stack_top; if (size) { - if (env->stack_limit - top < size) { + if (env->stack_limit - base < size) { cl_index delta = (size + (LISP_PAGESIZE-1))/LISP_PAGESIZE; ecl_stack_set_size(env, env->stack_size + delta * LISP_PAGESIZE); - top = env->stack_top; + base = env->stack_top; } } f->frame.t = t_frame; f->frame.stack = env->stack; - f->frame.bottom = top; + f->frame.base = base; + f->frame.size = size; f->frame.env = env; - env->stack_top = f->frame.top = (top + size); + env->stack_top = (base + size); return f; } @@ -159,22 +160,17 @@ ecl_stack_frame_enlarge(cl_object f, cl_index size) { cl_object *top; cl_env_ptr env = f->frame.env; - if (f->frame.stack == 0) { - ecl_internal_error("Inconsistency in interpreter stack frame"); - } top = env->stack_top; if ((env->stack_limit - top) < size) { cl_index delta = (size + (LISP_PAGESIZE-1))/LISP_PAGESIZE; ecl_stack_set_size(env, env->stack_size + delta * LISP_PAGESIZE); - f->frame.bottom = (f->frame.bottom - f->frame.stack) + env->stack; - f->frame.stack = env->stack; - top = env->stack_top; - } else if (top != f->frame.top) { - f->frame.bottom = (f->frame.bottom - f->frame.stack) + env->stack; + f->frame.base = (f->frame.base - f->frame.stack) + env->stack; f->frame.stack = env->stack; top = env->stack_top; } - env->stack_top = f->frame.top = (top + size); + env->stack_top = (top += size); + f->frame.base = top - (f->frame.size += size); + f->frame.stack = env->stack; } void @@ -182,75 +178,67 @@ ecl_stack_frame_push(cl_object f, cl_object o) { cl_object *top; cl_env_ptr env = f->frame.env; - if (f->frame.stack == 0) { - ecl_internal_error("Inconsistency in interpreter stack frame"); - } top = env->stack_top; if (top >= env->stack_limit) { ecl_stack_grow(env); - f->frame.bottom = (f->frame.bottom - f->frame.stack) + env->stack; - f->frame.stack = env->stack; - top = env->stack_top; - } else if (top != f->frame.top) { - f->frame.bottom = (f->frame.bottom - f->frame.stack) + env->stack; + f->frame.base = (f->frame.base - f->frame.stack) + env->stack; f->frame.stack = env->stack; top = env->stack_top; } - *(top++) = o; - env->stack_top = f->frame.top = top; + *top = o; + env->stack_top = ++top; + f->frame.base = top - (++(f->frame.size)); + f->frame.stack = env->stack; } void ecl_stack_frame_push_values(cl_object f) { cl_env_ptr env = f->frame.env; - if (f->frame.stack == 0) { - ecl_internal_error("Inconsistency in interpreter stack frame"); - } ecl_stack_push_values(env); - f->frame.bottom = (f->frame.bottom - f->frame.stack) + env->stack; + f->frame.base = env->stack_top - (f->frame.size += env->nvalues); f->frame.stack = env->stack; - f->frame.top = env->stack_top; } cl_object ecl_stack_frame_pop_values(cl_object f) { - cl_index n = f->frame.top - f->frame.bottom; - NVALUES = n; - VALUES(0) = Cnil; + cl_env_ptr env = f->frame.env; + cl_index n = f->frame.size % ECL_MULTIPLE_VALUES_LIMIT; + cl_object o; + env->nvalues = n; + env->values[0] = o = Cnil; while (n--) { - VALUES(n) = f->frame.bottom[n]; + env->values[n] = o = f->frame.base[n]; } - return VALUES(0); + return o; } cl_object ecl_stack_frame_elt(cl_object f, cl_index ndx) { - if (ndx >= (f->frame.top - f->frame.bottom)) { + if (ndx >= f->frame.size) { FEtype_error_index(f, ecl_make_unsigned_integer(ndx)); } - return f->frame.bottom[ndx]; + return f->frame.base[ndx]; } void ecl_stack_frame_elt_set(cl_object f, cl_index ndx, cl_object o) { - if (ndx >= (f->frame.top - f->frame.bottom)) { + if (ndx >= f->frame.size) { FEtype_error_index(f, ecl_make_unsigned_integer(ndx)); } - f->frame.bottom[ndx] = o; + f->frame.base[ndx] = o; } cl_object ecl_stack_frame_from_va_list(cl_env_ptr env, cl_object frame, cl_va_list args) { - cl_index nargs = args[0].narg; + cl_index i, nargs = args[0].narg; ecl_stack_frame_open(env, frame, nargs); - while (nargs) { - *(frame->frame.top-nargs) = cl_va_arg(args); - nargs--; + for (i = 0; i < nargs; i++) { + frame->frame.base[i] = cl_va_arg(args); } return frame; } @@ -259,16 +247,16 @@ void ecl_stack_frame_close(cl_object f) { if (f->frame.stack) { - ecl_stack_set_index(f->frame.env, f->frame.bottom - f->frame.stack); + ecl_stack_set_index(f->frame.env, f->frame.base - f->frame.stack); } } cl_object ecl_stack_frame_copy(cl_object dest, cl_object orig) { - cl_index size = orig->frame.top - orig->frame.bottom; + cl_index size = orig->frame.size; dest = ecl_stack_frame_open(orig->frame.env, dest, size); - memcpy(dest->frame.bottom, orig->frame.bottom, size * sizeof(cl_object)); + memcpy(dest->frame.base, orig->frame.base, size * sizeof(cl_object)); return dest; } @@ -295,48 +283,50 @@ ecl_lex_env_get_record(register cl_object env, register int s) /* -------------------- LAMBDA FUNCTIONS -------------------- */ -static cl_object -lambda_bind_var(cl_object env, cl_object var, cl_object val, cl_object specials) -{ - const cl_env_ptr the_env = ecl_process_env(); - if (!ecl_member_eq(var, specials)) - env = bind_var(env, var, val); - else - ecl_bds_bind(the_env, var, val); - return env; -} +#define LAMBDA_BIND_VAR(env,lex_env,_var,_val,specials) \ + { \ + cl_object var = _var, val = _val; \ + if (!ecl_member_eq(var, specials)) \ + lex_env = bind_var(lex_env, var, val); \ + else \ + ecl_bds_bind(env, var, val); \ + } static cl_object -lambda_bind(cl_object env, cl_narg narg, cl_object lambda, cl_object *sp) +lambda_bind(cl_object frame, cl_object lex_env, cl_object lambda) { cl_object *data = lambda->bytecodes.data; cl_object specials = lambda->bytecodes.specials; int i, n; + cl_narg narg = frame->frame.size; + const cl_object *sp = frame->frame.base; + const cl_env_ptr the_env = frame->frame.env; bool check_remaining = TRUE; /* 1) REQUIRED ARGUMENTS: N var1 ... varN */ n = fix(*(data++)); if (narg < n) FEwrong_num_arguments(lambda->bytecodes.name); - for (; n; n--, narg--) - env = lambda_bind_var(env, *(data++), *(sp++), specials); - + for (; n; n--, narg--) { + LAMBDA_BIND_VAR(the_env, lex_env, *(data++), *(sp++), specials); + } /* 2) OPTIONAL ARGUMENTS: N var1 value1 flag1 ... varN valueN flagN */ for (n = fix(*(data++)); n; n--, data+=3) { if (narg) { - env = lambda_bind_var(env, data[0], *sp, specials); + LAMBDA_BIND_VAR(the_env, lex_env, data[0], *sp, specials); sp++; narg--; if (!Null(data[2])) { - env = lambda_bind_var(env, data[2], Ct, specials); + LAMBDA_BIND_VAR(the_env, lex_env, data[2], Ct, specials); } } else { cl_object defaults = data[1]; if (FIXNUMP(defaults)) { - defaults = ecl_interpret(Cnil, env, lambda, fix(defaults)); + /* Here FRAME is not used */ + defaults = ecl_interpret(frame, lex_env, lambda, fix(defaults)); } - env = lambda_bind_var(env, data[0], defaults, specials); + LAMBDA_BIND_VAR(the_env, lex_env, data[0], defaults, specials); if (!Null(data[2])) { - env = lambda_bind_var(env, data[2], Cnil, specials); + LAMBDA_BIND_VAR(the_env, lex_env, data[2], Cnil, specials); } } } @@ -348,7 +338,7 @@ lambda_bind(cl_object env, cl_narg narg, cl_object lambda, cl_object *sp) for (i=narg; i; ) { rest = CONS(sp[--i], rest); } - env = lambda_bind_var(env, data[0], rest, specials); + LAMBDA_BIND_VAR(the_env, lex_env, data[0], rest, specials); } data++; @@ -417,20 +407,21 @@ lambda_bind(cl_object env, cl_narg narg, cl_object lambda, cl_object *sp) } for (i=0; istack; \ - frame.top = the_env->stack_top; \ - frame.bottom = frame.top - __n; \ - reg0 = ecl_apply_from_stack_frame((cl_object)&frame, fun); \ - the_env->stack_top -= __n; } +#define INTERPRET_FUNCALL(reg0, the_env, frame, narg, fun) { \ + cl_index __n = narg; \ + SETUP_ENV(the_env); \ + frame.stack = the_env->stack; \ + frame.base = the_env->stack_top - (frame.size = __n); \ + reg0 = ecl_apply_from_stack_frame((cl_object)&frame, fun); \ + the_env->stack_top -= __n; } /* -------------------- THE INTERPRETER -------------------- */ cl_object ecl_interpret(cl_object frame, cl_object env, cl_object bytecodes, cl_index offset) { - ECL_OFFSET_TABLE - const cl_env_ptr the_env = ecl_process_env(); + ECL_OFFSET_TABLE; + const cl_env_ptr the_env = frame->frame.env; volatile cl_index old_bds_top_index = the_env->bds_top - the_env->bds_org; cl_opcode *vector = (cl_opcode*)bytecodes->bytecodes.code + offset; cl_object *data = bytecodes->bytecodes.data; @@ -534,7 +524,8 @@ ecl_interpret(cl_object frame, cl_object env, cl_object bytecodes, cl_index offs ecl_ihs_push(the_env, &ihs, bytecodes, lex_env); frame_aux.t = t_frame; - frame_aux.stack = frame_aux.top = frame_aux.bottom = 0; + frame_aux.stack = frame_aux.base = 0; + frame_aux.size = 0; frame_aux.env = the_env; reg0 = Cnil; the_env->nvalues = 0; @@ -729,8 +720,8 @@ ecl_interpret(cl_object frame, cl_object env, cl_object bytecodes, cl_index offs DO_CALL: { cl_object x = reg0; cl_object frame = (cl_object)&frame_aux; - frame_aux.top = the_env->stack_top; - frame_aux.bottom = the_env->stack_top - narg; + frame_aux.size = narg; + frame_aux.base = the_env->stack_top - narg; AGAIN: if (reg0 == OBJNULL || reg0 == Cnil) { FEundefined_function(x); @@ -740,14 +731,14 @@ ecl_interpret(cl_object frame, cl_object env, cl_object bytecodes, cl_index offs if (narg != (cl_index)reg0->cfunfixed.narg) FEwrong_num_arguments(reg0); reg0 = APPLY_fixed(narg, reg0->cfunfixed.entry_fixed, - frame_aux.bottom); + frame_aux.base); break; case t_cfun: - reg0 = APPLY(narg, reg0->cfun.entry, frame_aux.bottom); + reg0 = APPLY(narg, reg0->cfun.entry, frame_aux.base); break; case t_cclosure: the_env->function = reg0; - reg0 = APPLY(narg, reg0->cclosure.entry, frame_aux.bottom); + reg0 = APPLY(narg, reg0->cclosure.entry, frame_aux.base); break; #ifdef CLOS case t_instance: @@ -801,8 +792,7 @@ ecl_interpret(cl_object frame, cl_object env, cl_object bytecodes, cl_index offs CASE(OP_ENTRY); { if (frame == Cnil) ecl_internal_error("Not enough arguments to bytecodes."); - lex_env = lambda_bind(lex_env, frame->frame.top - frame->frame.bottom, - bytecodes, frame->frame.bottom); + lex_env = lambda_bind(frame, lex_env, bytecodes); THREAD_NEXT; } /* OP_EXIT diff --git a/src/c/mapfun.d b/src/c/mapfun.d index 748b5a2ad..d224d99cc 100644 --- a/src/c/mapfun.d +++ b/src/c/mapfun.d @@ -25,7 +25,7 @@ cdrs_frame = ecl_stack_frame_from_va_list(ecl_process_env(),\ (cl_object)&cdrs_frame_aux, list); \ cars_frame = ecl_stack_frame_copy((cl_object)&cars_frame_aux, cdrs_frame); \ - nargs = ECL_STACK_FRAME_SIZE(cars_frame); \ + nargs = cars_frame->frame.size; \ if (nargs == 0) { \ FEprogram_error("MAP*: Too few arguments", 0); \ } diff --git a/src/c/print.d b/src/c/print.d index cdbc60a30..62a258a5f 100644 --- a/src/c/print.d +++ b/src/c/print.d @@ -1570,9 +1570,9 @@ si_write_ugly_object(cl_object x, cl_object stream) case t_frame: if (ecl_print_readably()) FEprint_not_readable(x); write_str("#frame.top - x->frame.bottom, stream); + write_decimal(x->frame.size, stream); write_ch(' ', stream); - write_addr((void*)x->frame.bottom, stream); + write_addr((void*)x->frame.base, stream); write_ch('>', stream); break; #ifdef ECL_THREADS diff --git a/src/configure b/src/configure index f41a5b906..01f2d61a2 100755 --- a/src/configure +++ b/src/configure @@ -8323,6 +8323,10 @@ case "${host_cpu}" in _ACEOF fi + cat >>confdefs.h <<\_ACEOF +#define ECL_USE_VARARG_AS_POINTER 1 +_ACEOF + dynamic_ffi=yes ;; x86_64 ) diff --git a/src/h/external.h b/src/h/external.h index cd0e773e4..c0d735a2c 100644 --- a/src/h/external.h +++ b/src/h/external.h @@ -471,7 +471,6 @@ extern ECL_API cl_object ecl_stack_frame_elt(cl_object f, cl_index n); extern ECL_API void ecl_stack_frame_elt_set(cl_object f, cl_index n, cl_object o); extern ECL_API cl_object ecl_stack_frame_copy(cl_object f, cl_object size); extern ECL_API void ecl_stack_frame_close(cl_object f); -#define ECL_STACK_FRAME_SIZE(f) ((f)->frame.top - (f)->frame.bottom) #define si_apply_from_stack_frame ecl_apply_from_stack_frame extern ECL_API void ecl_stack_push(cl_env_ptr env, cl_object o); diff --git a/src/h/internal.h b/src/h/internal.h index 855d5980b..004317c13 100644 --- a/src/h/internal.h +++ b/src/h/internal.h @@ -106,12 +106,13 @@ typedef struct cl_compiler_env *cl_compiler_env_ptr; frame->frame.t = t_frame; \ frame->frame.stack = 0; \ frame->frame.env = env; \ + frame->frame.size = narg; \ if (narg < C_ARGUMENTS_LIMIT) { \ va_list args; \ va_start(args, lastarg); \ - frame->frame.top = (frame->frame.bottom = (void*)args) + narg; \ + frame->frame.base = (void*)args; \ } else { \ - frame->frame.bottom = (frame->frame.top = env->stack_top) - narg; \ + frame->frame.base = env->stack_top - narg; \ } #define ECL_STACK_FRAME_VARARGS_END(frame) \ /* No stack consumed, no need to close frame */ @@ -122,19 +123,19 @@ typedef struct cl_compiler_env *cl_compiler_env_ptr; const cl_env_ptr env = ecl_process_env(); \ frame->frame.t = t_frame; \ frame->frame.env = env; \ + frame->frame.size = narg; \ if (narg < C_ARGUMENTS_LIMIT) { \ cl_index i; \ - cl_object *p = frame->frame.bottom = env->values; \ + cl_object *p = frame->frame.base = env->values; \ va_list args; \ va_start(args, lastarg); \ while (narg--) { \ *p = va_arg(args, cl_object); \ ++p; \ } \ - frame->frame.top = p; \ frame->frame.stack = (void*)0x1; \ } else { \ - frame->frame.bottom = (frame->frame.top = env->stack_top) - narg; \ + frame->frame.base = env->stack_top - narg; \ frame->frame.stack = 0; \ } #define ECL_STACK_FRAME_VARARGS_END(frame) \ diff --git a/src/h/object.h b/src/h/object.h index adfc66688..b54819b0f 100644 --- a/src/h/object.h +++ b/src/h/object.h @@ -741,9 +741,9 @@ struct ecl_foreign { /* user defined datatype */ struct ecl_stack_frame { HEADER; - cl_object *bottom; /* Bottom part */ - cl_object *top; /* Top part */ cl_object *stack; /* Is this relative to the lisp stack? */ + cl_object *base; /* Start of frame */ + cl_index size; /* Number of arguments */ struct cl_env_struct *env; };