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