Update function call stuff

This commit is contained in:
2026-07-19 00:14:16 -07:00
parent bd7ca2fa25
commit 67b68f8c61
10 changed files with 177 additions and 115 deletions
+15 -15
View File
@@ -331,11 +331,10 @@ process_complex_native_args(LispFunction *fobj, LispVal *args,
static ALWAYS_INLINE LispVal *call_native(LispVal *orig_func,
LispFunction *fobj, LispVal *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(LISP_STACK_REF(), args);
set_stack_evaluated_args(LISP_STACK_REF(), fobj, args);
LispVal *arg_arr[MAX_NATIVE_FUNCTION_ARGS] = {NULL};
size_t count = NATIVE_FUNCTION_TOTAL_ARG_COUNT(fobj);
intptr_t rest_idx;
@@ -380,10 +379,7 @@ static ALWAYS_INLINE LispVal *call_native(LispVal *orig_func,
default:
abort();
}
the_stack.nogc_retval = retval;
unwind_to(stack_ref);
add_local_reference(LISP_STACK_REF(), the_stack.nogc_retval);
return retval;
return UNWIND_AND_RETURN(stack_ref, retval);
}
static ALWAYS_INLINE void push_optional_argument_to_lexenv(LispVal *spec,
@@ -460,9 +456,8 @@ push_interpreted_args_to_lexenv(LispFunction *fobj, LispVal *args) {
static ALWAYS_INLINE LispVal *
call_interpreted(LispVal *orig_func, LispFunction *fobj, LispVal *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(LISP_STACK_REF(), evaled_args);
set_stack_evaluated_args(LISP_STACK_REF(), fobj, evaled_args);
push_dynamic_binding(Qlexical_environment, fobj->impl.interp.lexenv);
enum ProcessArgsResult par =
push_interpreted_args_to_lexenv(fobj, evaled_args);
@@ -472,29 +467,34 @@ call_interpreted(LispVal *orig_func, LispFunction *fobj, LispVal *args) {
process_args_strerror(par));
abort();
}
LispVal *rval = Fprogn(fobj->impl.interp.body);
the_stack.nogc_retval = rval;
unwind_to(stack_ref);
add_local_reference(LISP_STACK_REF(), rval);
return rval;
return UNWIND_AND_RETURN(stack_ref, Fprogn(fobj->impl.interp.body));
}
DEFUN(funcall, "funcall", (LispVal * func, LispVal *args), "(func &rest args)",
"") {
StackFrame *stack_ref = LISP_STACK_REF();
push_call_frame(func, args);
LispFunction *fobj = func;
if (SYMBOLP(func)) {
fobj = Fsymbol_function(func, Qt);
} else if (CONSP(func) && EQ(XCAR(func), Qlambda)) {
fobj = Feval(func, Vlexical_environment);
}
if (NILP(fobj)) {
// TODO throw exception
fprintf(stderr, "Not a function: ");
debug_print(stderr, func);
fputc('\n', stderr);
abort();
}
// 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);
return UNWIND_AND_RETURN(stack_ref, call_native(func, fobj, args));
case FUNCTION_INTERP:
return call_interpreted(func, fobj, args);
return UNWIND_AND_RETURN(stack_ref, call_interpreted(func, fobj, args));
default:
abort();
}