9236a48844aa87a12f805bb736e17aba315561dc
[sbcl.git] / src / runtime / funcall.c
1 /* funcall0 -- funcall3: we can get by with just two sets of these:
2  * for platforms where the control stack is the C-stack, and all others.
3  */
4
5 /*
6  * This software is part of the SBCL system. See the README file for
7  * more information.
8  *
9  * This software is derived from the CMU CL system, which was
10  * written at Carnegie Mellon University and released into the
11  * public domain. The software is in the public domain and is
12  * provided with absolutely no warranty. See the COPYING and CREDITS
13  * files for more information.
14  */
15
16 #include <stdio.h>
17
18 #include "sbcl.h"
19 #include "runtime.h"
20 #include "globals.h"
21 #include "os.h"
22 #include "interrupt.h"
23
24 /* This is implemented in assembly language and called from C: */
25 extern lispobj call_into_lisp(lispobj fun, lispobj *args, int nargs);
26
27 static inline lispobj
28 safe_call_into_lisp(lispobj fun, lispobj *args, int nargs)
29 {
30 #ifndef LISP_FEATURE_SB_SAFEPOINT
31     /* SIG_STOP_FOR_GC needs to be enabled before we can call lisp:
32      * otherwise two threads racing here may deadlock: the other will
33      * wait on the GC lock, and the other cannot stop the first
34      * one... */
35     check_gc_signals_unblocked_or_lose(0);
36 #endif
37     return call_into_lisp(fun, args, nargs);
38 }
39
40 #ifdef LISP_FEATURE_C_STACK_IS_CONTROL_STACK
41 /* These functions are an interface to the Lisp call-in facility.
42  * Since this is C we can know nothing about the calling environment.
43  * The control stack might be the C stack if called from the monitor
44  * or the Lisp stack if called as a result of an interrupt or maybe
45  * even a separate stack. The args are most likely on that stack but
46  * could be in registers depending on what the compiler likes. So we
47  * copy the args into a portable vector and let the assembly language
48  * call-in function figure it out. */
49
50 lispobj
51 funcall0(lispobj function)
52 {
53     lispobj *args = NULL;
54
55     FSHOW((stderr, "/entering funcall0(0x%lx)\n", (long)function));
56     return safe_call_into_lisp(function, args, 0);
57 }
58 lispobj
59 funcall1(lispobj function, lispobj arg0)
60 {
61     lispobj args[1];
62     args[0] = arg0;
63     return safe_call_into_lisp(function, args, 1);
64 }
65
66 lispobj
67 funcall2(lispobj function, lispobj arg0, lispobj arg1)
68 {
69     lispobj args[2];
70     args[0] = arg0;
71     args[1] = arg1;
72     return safe_call_into_lisp(function, args, 2);
73 }
74
75 lispobj
76 funcall3(lispobj function, lispobj arg0, lispobj arg1, lispobj arg2)
77 {
78     lispobj args[3];
79     args[0] = arg0;
80     args[1] = arg1;
81     args[2] = arg2;
82     return safe_call_into_lisp(function, args, 3);
83 }
84
85 #else
86
87 lispobj
88 funcall0(lispobj function)
89 {
90     lispobj **stack_pointer
91         = &access_control_stack_pointer(arch_os_get_current_thread());
92     lispobj *args = *stack_pointer;
93
94     return safe_call_into_lisp(function, args, 0);
95 }
96
97 lispobj
98 funcall1(lispobj function, lispobj arg0)
99 {
100     lispobj **stack_pointer
101         = &access_control_stack_pointer(arch_os_get_current_thread());
102     lispobj *args = *stack_pointer;
103
104     *stack_pointer += 1;
105     args[0] = arg0;
106
107     return safe_call_into_lisp(function, args, 1);
108 }
109
110 lispobj
111 funcall2(lispobj function, lispobj arg0, lispobj arg1)
112 {
113     lispobj **stack_pointer
114         = &access_control_stack_pointer(arch_os_get_current_thread());
115     lispobj *args = *stack_pointer;
116
117     *stack_pointer += 2;
118     args[0] = arg0;
119     args[1] = arg1;
120
121     return safe_call_into_lisp(function, args, 2);
122 }
123
124 lispobj
125 funcall3(lispobj function, lispobj arg0, lispobj arg1, lispobj arg2)
126 {
127     lispobj **stack_pointer
128         = &access_control_stack_pointer(arch_os_get_current_thread());
129     lispobj *args = *stack_pointer;
130
131     *stack_pointer += 3;
132     args[0] = arg0;
133     args[1] = arg1;
134     args[2] = arg2;
135
136     return safe_call_into_lisp(function, args, 3);
137 }
138 #endif