Rewrite the stack

This commit is contained in:
2026-07-18 22:31:01 -07:00
parent 891e5359bf
commit bd7ca2fa25
9 changed files with 343 additions and 200 deletions
+20 -16
View File
@@ -240,10 +240,10 @@ static ALWAYS_INLINE LispVal *evaluate_function_arguments(LispVal *args) {
LispVal *end;
DOLIST(arg, args) {
if (NILP(start)) {
start = CONS(Feval(arg, PARENT_LEXENV()), Qnil);
start = CONS(Feval(arg, Vlexical_environment), Qnil);
end = start;
} else {
RPLACD(end, CONS(Feval(arg, PARENT_LEXENV()), Qnil));
RPLACD(end, CONS(Feval(arg, Vlexical_environment), Qnil));
end = XCDR(end);
}
}
@@ -330,11 +330,12 @@ process_complex_native_args(LispFunction *fobj, LispVal *args,
static ALWAYS_INLINE LispVal *call_native(LispVal *orig_func,
LispFunction *fobj, LispVal *args) {
push_stack_frame(orig_func, fobj, args);
StackFrame *stack_ref = LISP_STACK_REF();
push_call_frame(orig_func, fobj, args);
if (!fobj->impl.native.no_eval_args) {
args = evaluate_function_arguments(args);
}
set_stack_evaluated_args(args);
set_stack_evaluated_args(LISP_STACK_REF(), args);
LispVal *arg_arr[MAX_NATIVE_FUNCTION_ARGS] = {NULL};
size_t count = NATIVE_FUNCTION_TOTAL_ARG_COUNT(fobj);
intptr_t rest_idx;
@@ -351,7 +352,7 @@ static ALWAYS_INLINE LispVal *call_native(LispVal *orig_func,
if (!arg_arr[i]) {
arg_arr[i] = Qnil;
}
add_local_reference(arg_arr[i]);
add_local_reference(LISP_STACK_REF(), arg_arr[i]);
}
LispVal *retval;
switch (count) {
@@ -380,8 +381,8 @@ static ALWAYS_INLINE LispVal *call_native(LispVal *orig_func,
abort();
}
the_stack.nogc_retval = retval;
pop_stack_frame();
add_local_reference(the_stack.nogc_retval);
unwind_to(stack_ref);
add_local_reference(LISP_STACK_REF(), the_stack.nogc_retval);
return retval;
}
@@ -395,7 +396,7 @@ static ALWAYS_INLINE void push_optional_argument_to_lexenv(LispVal *spec,
static ALWAYS_INLINE void
push_missing_optional_argument_to_lexenv(LispVal *spec) {
new_lexical_variable(XCAR(spec), Feval(SECOND(spec), TOP_LEXENV()));
new_lexical_variable(XCAR(spec), Feval(SECOND(spec), Vlexical_environment));
if (!NILP(THIRD(spec))) {
new_lexical_variable(THIRD(spec), Qnil);
}
@@ -403,7 +404,6 @@ push_missing_optional_argument_to_lexenv(LispVal *spec) {
static ALWAYS_INLINE enum ProcessArgsResult
push_interpreted_args_to_lexenv(LispFunction *fobj, LispVal *args) {
LISP_STACK_TOP()->lexenv = fobj->impl.interp.lexenv;
LispVal *rem_req = fobj->args.req;
LispVal *rem_opt = fobj->args.opt;
while (!NILP(rem_req)) {
@@ -459,10 +459,13 @@ push_interpreted_args_to_lexenv(LispFunction *fobj, LispVal *args) {
static ALWAYS_INLINE LispVal *
call_interpreted(LispVal *orig_func, LispFunction *fobj, LispVal *args) {
push_stack_frame(orig_func, fobj, args);
StackFrame *stack_ref = LISP_STACK_REF();
push_call_frame(orig_func, fobj, args);
LispVal *evaled_args = evaluate_function_arguments(args);
set_stack_evaluated_args(evaled_args);
enum ProcessArgsResult par = push_interpreted_args_to_lexenv(fobj, args);
set_stack_evaluated_args(LISP_STACK_REF(), evaled_args);
push_dynamic_binding(Qlexical_environment, fobj->impl.interp.lexenv);
enum ProcessArgsResult par =
push_interpreted_args_to_lexenv(fobj, evaled_args);
if (par != PROCESS_ARGS_OK) {
// TODO better error handling
fprintf(stderr, "Bad args to interp func: %s\n",
@@ -471,8 +474,8 @@ call_interpreted(LispVal *orig_func, LispFunction *fobj, LispVal *args) {
}
LispVal *rval = Fprogn(fobj->impl.interp.body);
the_stack.nogc_retval = rval;
pop_stack_frame();
add_local_reference(rval);
unwind_to(stack_ref);
add_local_reference(LISP_STACK_REF(), rval);
return rval;
}
@@ -482,10 +485,11 @@ DEFUN(funcall, "funcall", (LispVal * func, LispVal *args), "(func &rest args)",
if (SYMBOLP(func)) {
fobj = Fsymbol_function(func, Qt);
} else if (CONSP(func) && EQ(XCAR(func), Qlambda)) {
fobj = Feval(func, TOP_LEXENV());
fobj = Feval(func, Vlexical_environment);
}
// include symbol here for the error message
CHECK_TYPE(fobj, TYPE_FUNCTION, TYPE_SYMBOL);
assert(FUNCTIONP(fobj));
switch (fobj->type) {
case FUNCTION_NATIVE:
return call_native(func, fobj, args);
@@ -542,7 +546,7 @@ DEFSPECIAL(lambda, "lambda", (LispVal * args, LispVal *body),
}
body = parse_lambda_declare_form(fobj, body);
fobj->impl.interp.body = body;
fobj->impl.interp.lexenv = PARENT_LEXENV();
fobj->impl.interp.lexenv = Vlexical_environment;
return fobj;
}