1 /* foreign3.c
2  * Copyright 1984-2017 Cisco Systems, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <stdio.h>
18 #include <stdlib.h>
19 
20 #ifndef WIN32
21 #include <string.h>
22 #endif
23 
24 #ifdef _WIN32
25 #  define SCHEME_IMPORT
26 #  include "scheme.h"
27 #  undef EXPORT
28 #  define EXPORT extern __declspec (dllexport)
29 #else
30 #include "scheme.h"
31 #endif
32 
chk_data(void)33 EXPORT int chk_data(void) {
34     static char c[10]="ABCDEFGH";
35 
36     return('A' == c[0] && 'B' == c[1] && 'C' == c[2] && 'D' == c[3] &&
37            'E' == c[4] && 'F' == c[5] && 'G' == c[6] && 'H' == c[7]);
38 }
39 
chk_bss(void)40 EXPORT int chk_bss(void) {
41     static int j[2000];
42     int i;
43 
44     for (i=0; i<2000; i++) if (j[i] != 0) break;
45 
46     return i == 2000;
47 }
48 
chk_malloc(void)49 EXPORT int chk_malloc(void) {
50     int *j, i;
51 
52     j = (int *)malloc(2000 * sizeof(int));
53 
54     for (i=0; i<2000; i++) j[i] = 0;
55 
56     for (i=0; i<2000; i++) if (j[i] != 0) break;
57 
58     free(j);
59 
60     return i == 2000;
61 }
62 
sxstos(float x,float y)63 EXPORT float sxstos(float x, float y) {
64     return x * y;
65 }
66 
singlesum12(float x1,float x2,float x3,float x4,float x5,float x6,float x7,float x8,float x9,float x10,float x11,float x12)67 EXPORT float singlesum12(float x1, float x2, float x3, float x4,
68                          float x5, float x6, float x7, float x8,
69                          float x9, float x10, float x11, float x12) {
70     return x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12;
71 }
72 
73 /* these are taken from SYSTEM V Application Binary Interface
74  * MIPS Processor Supplement, 1991
75  * page 3-21
76  */
77 
d1d2(double d1,double d2)78 EXPORT double d1d2(double d1, double d2) {
79     return d1 + d2;
80 }
s1s2(float s1,float s2)81 EXPORT double s1s2(float s1, float s2) {
82     return s1 + s2;
83 }
s1d1(float s1,double d1)84 EXPORT double s1d1(float s1, double d1) {
85     return s1 + d1;
86 }
d1s1(double d1,float s1)87 EXPORT double d1s1(double d1, float s1) {
88     return d1 + s1;
89 }
n1n2n3n4(int n1,int n2,int n3,int n4)90 EXPORT double n1n2n3n4(int n1, int n2, int n3, int n4) {
91     return (double)(n1 + n2 + n3 + n4);
92 }
d1n1d2(double d1,int n1,double d2)93 EXPORT double d1n1d2(double d1, int n1, double d2) {
94     return d1 + n1 + d2;
95 }
d1n1n2(double d1,int n1,int n2)96 EXPORT double d1n1n2(double d1, int n1, int n2) {
97     return d1 + n1 + n2;
98 }
s1n1n2(float s1,int n1,int n2)99 EXPORT double s1n1n2(float s1, int n1, int n2) {
100     return s1 + n1 + n2;
101 }
n1n2n3d1(int n1,int n2,int n3,double d1)102 EXPORT double n1n2n3d1(int n1, int n2, int n3, double d1) {
103     return n1 + n2 + n3 + d1;
104 }
n1n2n3s1(int n1,int n2,int n3,float s1)105 EXPORT double n1n2n3s1(int n1, int n2, int n3, float s1) {
106     return n1 + n2 + n3 + s1;
107 }
n1n2d1(int n1,int n2,double d1)108 EXPORT double n1n2d1(int n1, int n2, double d1) {
109     return n1 + n2 + d1;
110 }
n1d1(int n1,double d1)111 EXPORT double n1d1(int n1, double d1) {
112     return n1 + d1;
113 }
s1s2s3s4(float s1,float s2,float s3,float s4)114 EXPORT double s1s2s3s4(float s1, float s2, float s3, float s4) {
115     return s1 + s2 + s3 + s4;
116 }
s1n1s2n2(float s1,int n1,float s2,int n2)117 EXPORT double s1n1s2n2(float s1, int n1, float s2, int n2) {
118     return s1 + n1 + s2 + n2;
119 }
d1s1s2(double d1,float s1,float s2)120 EXPORT double d1s1s2(double d1, float s1, float s2) {
121     return d1 + s1 + s2;
122 }
s1s2d1(float s1,float s2,double d1)123 EXPORT double s1s2d1(float s1, float s2, double d1) {
124     return s1 + s2 + d1;
125 }
n1s1n2s2(int n1,float s1,int n2,float s2)126 EXPORT double n1s1n2s2(int n1, float s1, int n2, float s2) {
127     return n1 + s1 + n2 + s2;
128 }
n1s1n2n3(int n1,float s1,int n2,int n3)129 EXPORT double n1s1n2n3(int n1, float s1, int n2, int n3) {
130     return n1 + s1 + n2 + n3;
131 }
n1n2s1n3(int n1,int n2,float s1,int n3)132 EXPORT double n1n2s1n3(int n1, int n2, float s1, int n3) {
133     return n1 + n2 + s1 + n3;
134 }
135 
136 /* a few more for good measure */
d1d2s1s2(double d1,double d2,float s1,float s2)137 EXPORT double d1d2s1s2(double d1, double d2, float s1, float s2) {
138     return d1 + d2 + s1 + s2;
139 }
d1d2n1n2(double d1,double d2,int n1,int n2)140 EXPORT double d1d2n1n2(double d1, double d2, int n1, int n2) {
141     return d1 + d2 + n1 + n2;
142 }
s1d1s2s3(float s1,double d1,float s2,float s3)143 EXPORT double s1d1s2s3(float s1, double d1, float s2, float s3) {
144     return s1 + d1 + s2 + s3;
145 }
146 
147 /* support for testing foreign-callable */
Sinvoke2(ptr code,ptr x1,iptr x2)148 EXPORT ptr Sinvoke2(ptr code, ptr x1, iptr x2) {
149     return (*((ptr (*) PROTO((ptr, iptr)))Sforeign_callable_entry_point(code)))(x1, x2);
150 }
151 
Sargtest(iptr f,int x1,int x2,iptr x3,double x4,float x5,char * x6)152 EXPORT ptr Sargtest(iptr f, int x1, int x2, iptr x3, double x4, float x5, char *x6) {
153     return (*((ptr (*) PROTO((int, int, iptr, double, float, char *)))f))(x1, x2, x3, x4, x5, x6);
154 }
155 
Sargtest2(iptr f,short x1,int x2,char x3,double x4,short x5,char x6)156 EXPORT ptr Sargtest2(iptr f, short x1, int x2, char x3, double x4, short x5, char x6) {
157     return (*((ptr (*) PROTO((short, int, char, double, short, char)))f))(x1, x2, x3, x4, x5, x6);
158 }
159 
Srvtest_int32(ptr code,ptr x1)160 EXPORT int Srvtest_int32(ptr code, ptr x1) {
161     return (*((int (*) PROTO((ptr)))Sforeign_callable_entry_point(code)))(x1);
162 }
163 
Srvtest_uns32(ptr code,ptr x1)164 EXPORT unsigned Srvtest_uns32(ptr code, ptr x1) {
165     return (*((unsigned (*) PROTO((ptr)))Sforeign_callable_entry_point(code)))(x1);
166 }
167 
Srvtest_single(ptr code,ptr x1)168 EXPORT float Srvtest_single(ptr code, ptr x1) {
169     return (*((float (*) PROTO((ptr)))Sforeign_callable_entry_point(code)))(x1);
170 }
171 
Srvtest_double(ptr code,ptr x1)172 EXPORT double Srvtest_double(ptr code, ptr x1) {
173     return (*((double (*) PROTO((ptr)))Sforeign_callable_entry_point(code)))(x1);
174 }
175 
Srvtest_char(ptr code,ptr x1)176 EXPORT char Srvtest_char(ptr code, ptr x1) {
177     return (*((char (*) PROTO((ptr)))Sforeign_callable_entry_point(code)))(x1);
178 }
179 
180 #ifdef WIN32
sum_stdcall(int a,int b)181 EXPORT int __stdcall sum_stdcall(int a, int b) {
182     return a + b;
183 }
184 
Sinvoke2_stdcall(ptr code,ptr x1,iptr x2)185 EXPORT ptr Sinvoke2_stdcall(ptr code, ptr x1, iptr x2) {
186     return (*((ptr (__stdcall *) PROTO((ptr, iptr)))Sforeign_callable_entry_point(code)))(x1, x2);
187 }
188 
189 typedef int (__stdcall *comfunc) (void *, int);
190 typedef struct { comfunc *vtable; int data; } com_instance_t;
191 
192 static comfunc com_vtable[2];
193 static com_instance_t com_instance;
194 
com_method0(void * inst,int val)195 extern int __stdcall com_method0(void *inst, int val) {
196   return ((com_instance_t *)inst)->data = val;
197 }
198 
com_method1(void * inst,int val)199 extern int __stdcall com_method1(void *inst, int val) {
200   return val * 2 + ((com_instance_t *)inst)->data;
201 }
202 
get_com_instance(void)203 EXPORT com_instance_t *get_com_instance(void) {
204   com_instance.vtable = com_vtable;
205   com_vtable[0] = com_method0;
206   com_vtable[1] = com_method1;
207   com_instance.data = -31;
208   return &com_instance;
209 }
210 #endif /* WIN32 */
211 
212 /* foreign_callable example adapted from foreign.stex */
213 typedef void (*CB)(char);
214 
215 static CB callbacks[256];
216 
cb_init(void)217 EXPORT void cb_init(void) {
218    int i;
219 
220    for (i = 0; i < 256; i += 1)
221        callbacks[i] = (CB)0;
222 }
223 
register_callback(char c,iptr cb)224 EXPORT void register_callback(char c, iptr cb) {
225     callbacks[(int)c] = (CB)cb;
226 }
227 
event_loop(char * s)228 EXPORT void event_loop(char *s) {
229     char buf[10];
230     CB f; char c;
231 
232   /* create a local copy, since s points into an unlocked Scheme string */
233     strncpy(buf, s, 9);
234     buf[9] = '0';
235     s = buf;
236     for (;;) {
237         c = *s++;
238         if (c == 0) break;
239         f = callbacks[(int)c];
240         if (f != (CB)0) f(c);
241     }
242 }
243 
call_twice(void (* foo)(int),int x,int y)244 EXPORT void call_twice(void (*foo)(int), int x, int y) {
245   foo(x);
246   foo(y);
247 }
248 
unlock_callback(int (* f)(int))249 EXPORT void unlock_callback(int (* f)(int)) {
250   Sunlock_object(Sforeign_callable_code_object(f));
251 }
252 
call_and_unlock(int (* f)(int),int arg)253 EXPORT int call_and_unlock(int (* f)(int), int arg) {
254   int ans = f(arg);
255   Sunlock_object(Sforeign_callable_code_object(f));
256   return ans;
257 }
258 
init_lock(uptr * u)259 EXPORT void init_lock (uptr *u) {
260   INITLOCK(u);
261 }
262 
spinlock(uptr * u)263 EXPORT void spinlock (uptr *u) {
264   SPINLOCK(u);
265 }
266 
unlock(uptr * u)267 EXPORT void unlock (uptr *u) {
268   UNLOCK(u);
269 }
270 
locked_incr(uptr * u)271 EXPORT int locked_incr (uptr *u) {
272   int ret;
273   LOCKED_INCR(u, ret);
274   return ret;
275 }
276 
locked_decr(uptr * u)277 EXPORT int locked_decr (uptr *u) {
278   int ret;
279   LOCKED_DECR(u, ret);
280   return ret;
281 }
282