1 #include "errno.h"
2 #include "string.h"
3
4 #include "jsctypes-test.h"
5 #include "jsctypes-test-finalizer.h"
6
7 /**
8 * Shared infrastructure
9 */
10
11 /**
12 * An array of integers representing resources.
13 * - 0: unacquired
14 * - 1: acquired
15 * - < 0: error, resource has been released several times.
16 */
17 int* gFinalizerTestResources = nullptr;
18 char** gFinalizerTestNames = nullptr;
19 size_t gFinalizerTestSize;
20
test_finalizer_start(size_t size)21 void test_finalizer_start(size_t size) {
22 gFinalizerTestResources = new int[size];
23 gFinalizerTestNames = new char*[size];
24 gFinalizerTestSize = size;
25 for (size_t i = 0; i < size; ++i) {
26 gFinalizerTestResources[i] = 0;
27 gFinalizerTestNames[i] = nullptr;
28 }
29 }
30
test_finalizer_stop()31 void test_finalizer_stop() { delete[] gFinalizerTestResources; }
32
33 /**
34 * Check if an acquired resource has been released
35 */
test_finalizer_resource_is_acquired(size_t i)36 bool test_finalizer_resource_is_acquired(size_t i) {
37 return gFinalizerTestResources[i] == 1;
38 }
39 // Resource type: size_t
40
41 // Acquire resource i
test_finalizer_acq_size_t(size_t i)42 size_t test_finalizer_acq_size_t(size_t i) {
43 gFinalizerTestResources[i] = 1;
44 return i;
45 }
46
47 // Release resource i
test_finalizer_rel_size_t(size_t i)48 void test_finalizer_rel_size_t(size_t i) {
49 if (--gFinalizerTestResources[i] < 0) {
50 MOZ_CRASH("Assertion failed");
51 }
52 }
53
test_finalizer_rel_size_t_return_size_t(size_t i)54 size_t test_finalizer_rel_size_t_return_size_t(size_t i) {
55 if (--gFinalizerTestResources[i] < 0) {
56 MOZ_CRASH("Assertion failed");
57 }
58 return i;
59 }
60
test_finalizer_rel_size_t_return_struct_t(size_t i)61 myRECT test_finalizer_rel_size_t_return_struct_t(size_t i) {
62 if (--gFinalizerTestResources[i] < 0) {
63 MOZ_CRASH("Assertion failed");
64 }
65 const int32_t narrowed = (int32_t)i;
66 myRECT result = {narrowed, narrowed, narrowed, narrowed};
67 return result;
68 }
69
test_finalizer_cmp_size_t(size_t a,size_t b)70 bool test_finalizer_cmp_size_t(size_t a, size_t b) { return a == b; }
71
72 // Resource type: int32_t
73
74 // Acquire resource i
test_finalizer_acq_int32_t(size_t i)75 int32_t test_finalizer_acq_int32_t(size_t i) {
76 gFinalizerTestResources[i] = 1;
77 return i;
78 }
79
80 // Release resource i
test_finalizer_rel_int32_t(int32_t i)81 void test_finalizer_rel_int32_t(int32_t i) {
82 if (--gFinalizerTestResources[i] < 0) {
83 MOZ_CRASH("Assertion failed");
84 }
85 }
86
test_finalizer_cmp_int32_t(int32_t a,int32_t b)87 bool test_finalizer_cmp_int32_t(int32_t a, int32_t b) { return a == b; }
88
89 // Resource type: int64_t
90
91 // Acquire resource i
test_finalizer_acq_int64_t(size_t i)92 int64_t test_finalizer_acq_int64_t(size_t i) {
93 gFinalizerTestResources[i] = 1;
94 return i;
95 }
96
97 // Release resource i
test_finalizer_rel_int64_t(int64_t i)98 void test_finalizer_rel_int64_t(int64_t i) {
99 if (--gFinalizerTestResources[i] < 0) {
100 MOZ_CRASH("Assertion failed");
101 }
102 }
103
test_finalizer_cmp_int64_t(int64_t a,int64_t b)104 bool test_finalizer_cmp_int64_t(int64_t a, int64_t b) { return a == b; }
105
106 // Resource type: void*
107
108 // Acquire resource i
test_finalizer_acq_ptr_t(size_t i)109 void* test_finalizer_acq_ptr_t(size_t i) {
110 gFinalizerTestResources[i] = 1;
111 return (void*)&gFinalizerTestResources[i];
112 }
113
114 // Release resource i
test_finalizer_rel_ptr_t(void * i)115 void test_finalizer_rel_ptr_t(void* i) {
116 int* as_int = (int*)i;
117 --(*as_int);
118 if (*as_int < 0) {
119 MOZ_CRASH("Assertion failed");
120 }
121 }
122
test_finalizer_cmp_ptr_t(void * a,void * b)123 bool test_finalizer_cmp_ptr_t(void* a, void* b) { return a == b; }
124
125 // Resource type: int32_t*
126
127 // Acquire resource i
test_finalizer_acq_int32_ptr_t(size_t i)128 int32_t* test_finalizer_acq_int32_ptr_t(size_t i) {
129 gFinalizerTestResources[i] = 1;
130 return (int32_t*)&gFinalizerTestResources[i];
131 }
132
133 // Release resource i
test_finalizer_rel_int32_ptr_t(int32_t * i)134 void test_finalizer_rel_int32_ptr_t(int32_t* i) {
135 --(*i);
136 if (*i < 0) {
137 MOZ_CRASH("Assertion failed");
138 }
139 }
140
test_finalizer_cmp_int32_ptr_t(int32_t * a,int32_t * b)141 bool test_finalizer_cmp_int32_ptr_t(int32_t* a, int32_t* b) { return a == b; }
142
143 // Resource type: nullptr
144
145 // Acquire resource i
test_finalizer_acq_null_t(size_t i)146 void* test_finalizer_acq_null_t(size_t i) {
147 gFinalizerTestResources[0] = 1; // Always index 0
148 return nullptr;
149 }
150
151 // Release resource i
test_finalizer_rel_null_t(void * i)152 void test_finalizer_rel_null_t(void* i) {
153 if (i != nullptr) {
154 MOZ_CRASH("Assertion failed");
155 }
156 gFinalizerTestResources[0]--;
157 }
158
test_finalizer_null_resource_is_acquired(size_t)159 bool test_finalizer_null_resource_is_acquired(size_t) {
160 return gFinalizerTestResources[0] == 1;
161 }
162
test_finalizer_cmp_null_t(void * a,void * b)163 bool test_finalizer_cmp_null_t(void* a, void* b) { return a == b; }
164
165 // Resource type: char*
166
167 // Acquire resource i
test_finalizer_acq_string_t(int i)168 char* test_finalizer_acq_string_t(int i) {
169 gFinalizerTestResources[i] = 1;
170 if (!gFinalizerTestNames[i]) {
171 char* buf = new char[12];
172 snprintf(buf, 12, "%d", i);
173 gFinalizerTestNames[i] = buf;
174 return buf;
175 }
176 return gFinalizerTestNames[i];
177 }
178
179 // Release resource i
test_finalizer_rel_string_t(char * i)180 void test_finalizer_rel_string_t(char* i) {
181 int index = atoi(i);
182 if (index < 0 || index >= (int)gFinalizerTestSize) {
183 MOZ_CRASH("Assertion failed");
184 }
185 gFinalizerTestResources[index]--;
186 }
187
test_finalizer_string_resource_is_acquired(size_t i)188 bool test_finalizer_string_resource_is_acquired(size_t i) {
189 return gFinalizerTestResources[i] == 1;
190 }
191
test_finalizer_cmp_string_t(char * a,char * b)192 bool test_finalizer_cmp_string_t(char* a, char* b) {
193 return !strncmp(a, b, 10);
194 }
195
196 // Resource type: myRECT
197
198 // Acquire resource i
test_finalizer_acq_struct_t(int i)199 myRECT test_finalizer_acq_struct_t(int i) {
200 gFinalizerTestResources[i] = 1;
201 myRECT result = {i, i, i, i};
202 return result;
203 }
204
205 // Release resource i
test_finalizer_rel_struct_t(myRECT i)206 void test_finalizer_rel_struct_t(myRECT i) {
207 int index = i.top;
208 if (index < 0 || index >= (int)gFinalizerTestSize) {
209 MOZ_CRASH("Assertion failed");
210 }
211 gFinalizerTestResources[index]--;
212 }
213
test_finalizer_struct_resource_is_acquired(myRECT i)214 bool test_finalizer_struct_resource_is_acquired(myRECT i) {
215 int index = i.top;
216 if (index < 0 || index >= (int)gFinalizerTestSize) {
217 MOZ_CRASH("Assertion failed");
218 }
219 return gFinalizerTestResources[index] == 1;
220 }
221
test_finalizer_cmp_struct_t(myRECT a,myRECT b)222 bool test_finalizer_cmp_struct_t(myRECT a, myRECT b) { return a.top == b.top; }
223
224 // Support for checking that we reject nullptr finalizer
test_finalizer_rel_null_function()225 afun* test_finalizer_rel_null_function() { return nullptr; }
226
test_finalizer_rel_size_t_set_errno(size_t i)227 void test_finalizer_rel_size_t_set_errno(size_t i) {
228 if (--gFinalizerTestResources[i] < 0) {
229 MOZ_CRASH("Assertion failed");
230 }
231 errno = 10;
232 }
233
reset_errno()234 void reset_errno() { errno = 0; }
235