1 /*
2
3 Copyright (c) 2006-2013 uim Project https://github.com/uim/uim
4
5 All rights reserved.
6
7 Redistribution and use in source and binary forms, with or without
8 modification, are permitted provided that the following conditions
9 are met:
10
11 1. Redistributions of source code must retain the above copyright
12 notice, this list of conditions and the following disclaimer.
13 2. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the
15 documentation and/or other materials provided with the distribution.
16 3. Neither the name of authors nor the names of its contributors
17 may be used to endorse or promote products derived from this software
18 without specific prior written permission.
19
20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND
21 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
24 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 SUCH DAMAGE.
31
32 */
33
34 #include <assert.h>
35 #include <stdlib.h>
36 #include <stdio.h>
37
38 #include "uim.h"
39 #include "uim-scm.h"
40
41 #define TEST_STACK_START(protected, actual) \
42 fprintf(stderr, "stack growth dir = %s, protected = %p, actual = %p\n", \
43 (stack_dir == STACK_GROWS_DOWNWARDS) ? "downwards" : "upwards", \
44 protected, actual); \
45 if (stack_dir == STACK_GROWS_DOWNWARDS) { \
46 assert(actual <= protected); \
47 } else { \
48 assert(actual >= protected); \
49 }
50
51 enum stack_growth_dir {
52 STACK_GROWS_DOWNWARDS,
53 STACK_GROWS_UPWARDS
54 };
55
56
57 static enum stack_growth_dir stack_dir;
58 static void *volatile stack_start_protected;
59 static void *volatile stack_start_actual;
60
61 static void (*volatile fvv_internal)(void);
62 static int (*volatile fiv_internal)(void);
63 static void (*volatile fvi_internal)(int);
64 static int (*volatile fii_internal)(int);
65 static uim_lisp *(*volatile fspv_internal)(void);
66 static uim_lisp *(*volatile fspsp_internal)(uim_lisp *dummy);
67
68 static enum stack_growth_dir probe_stack_growth_dir(void);
69 static enum stack_growth_dir probe_stack_growth_dir2(void *upper_frame);
70 static void fvv(void);
71 static int fiv(void);
72 static void fvi(int dummy);
73 static int fii(int dummy);
74 static uim_lisp *fspv(void);
75 static uim_lisp *fspsp(uim_lisp *dummy);
76
77
78 static enum stack_growth_dir
probe_stack_growth_dir(void)79 probe_stack_growth_dir(void)
80 {
81 int stack_start;
82
83 return probe_stack_growth_dir2(&stack_start);
84 }
85
86 static enum stack_growth_dir
probe_stack_growth_dir2(void * upper_frame)87 probe_stack_growth_dir2(void *upper_frame)
88 {
89 int stack_start;
90
91 if ((void *)&stack_start < upper_frame)
92 return STACK_GROWS_DOWNWARDS;
93 else
94 return STACK_GROWS_UPWARDS;
95 }
96
97 static void
fvv(void)98 fvv(void)
99 {
100 uim_lisp stack_start;
101
102 stack_start_actual = &stack_start;
103 }
104
105 static int
fiv(void)106 fiv(void)
107 {
108 uim_lisp stack_start;
109
110 stack_start_actual = &stack_start;
111 return 0;
112 }
113
114 static void
fvi(int dummy)115 fvi(int dummy)
116 {
117 uim_lisp stack_start;
118
119 stack_start_actual = &stack_start;
120 }
121
122 static int
fii(int dummy)123 fii(int dummy)
124 {
125 uim_lisp stack_start;
126
127 stack_start_actual = &stack_start;
128 return 0;
129 }
130
131 static uim_lisp *
fspv(void)132 fspv(void)
133 {
134 uim_lisp stack_start;
135
136 stack_start_actual = &stack_start;
137 return NULL;
138 }
139
140 static uim_lisp *
fspsp(uim_lisp * dummy)141 fspsp(uim_lisp *dummy)
142 {
143 uim_lisp stack_start;
144
145 stack_start_actual = &stack_start;
146 return dummy;
147 }
148
149 int
main(void)150 main(void)
151 {
152 uim_init();
153
154 stack_dir = probe_stack_growth_dir();
155 fvv_internal = fvv;
156 fiv_internal = fiv;
157 fvi_internal = fvi;
158 fii_internal = fii;
159 fspv_internal = fspv;
160 fspsp_internal = fspsp;
161
162 stack_start_protected = uim_scm_gc_current_stack();
163 uim_scm_gc_protect_stack(stack_start_protected);
164 (*fvv_internal)();
165 uim_scm_gc_unprotect_stack(stack_start_protected);
166 TEST_STACK_START(stack_start_protected, stack_start_actual);
167
168 stack_start_protected = uim_scm_gc_current_stack();
169 uim_scm_gc_protect_stack(stack_start_protected);
170 (*fiv_internal)();
171 uim_scm_gc_unprotect_stack(stack_start_protected);
172 TEST_STACK_START(stack_start_protected, stack_start_actual);
173
174 stack_start_protected = uim_scm_gc_current_stack();
175 uim_scm_gc_protect_stack(stack_start_protected);
176 (*fvi_internal)(0);
177 uim_scm_gc_unprotect_stack(stack_start_protected);
178 TEST_STACK_START(stack_start_protected, stack_start_actual);
179
180 stack_start_protected = uim_scm_gc_current_stack();
181 uim_scm_gc_protect_stack(stack_start_protected);
182 (*fii_internal)(0);
183 uim_scm_gc_unprotect_stack(stack_start_protected);
184 TEST_STACK_START(stack_start_protected, stack_start_actual);
185
186 stack_start_protected = uim_scm_gc_current_stack();
187 uim_scm_gc_protect_stack(stack_start_protected);
188 (*fspv_internal)();
189 uim_scm_gc_unprotect_stack(stack_start_protected);
190 TEST_STACK_START(stack_start_protected, stack_start_actual);
191
192 stack_start_protected = uim_scm_gc_current_stack();
193 uim_scm_gc_protect_stack(stack_start_protected);
194 (*fspsp_internal)((uim_lisp *)NULL);
195 uim_scm_gc_unprotect_stack(stack_start_protected);
196 TEST_STACK_START(stack_start_protected, stack_start_actual);
197
198 uim_quit();
199
200 fprintf(stderr, "tests succeeded.\n");
201
202 return EXIT_SUCCESS;
203 }
204