1 /*
2 Ypsilon Scheme System
3 Copyright (c) 2004-2008 Y.FUJITA / LittleWing Company Limited.
4 See license.txt for terms and conditions of use
5 */
6
7 #include "core.h"
8 #include "hash.h"
9 #include "heap.h"
10 #include "list.h"
11 #include "arith.h"
12 #include "port.h"
13 #include "socket.h"
14
swap(T & lhs,T & rhs)15 template <typename T> void swap(T& lhs, T& rhs) { T tmp = lhs; lhs = rhs; rhs = tmp; }
16
17 scm_symbol_t
make_symbol(object_heap_t * heap,const char * name,int len)18 make_symbol(object_heap_t* heap, const char *name, int len)
19 {
20 #if USE_PARALLEL_VM
21 heap->m_symbol.lock();
22 scm_symbol_t obj = (scm_symbol_t)heap->m_symbol.get(name, len);
23 if (obj == scm_undef) {
24 if (heap != heap->m_primordial) {
25 heap->m_primordial->m_symbol.lock();
26 obj = (scm_symbol_t)heap->m_primordial->m_symbol.get(name, len);
27 heap->m_primordial->m_symbol.unlock();
28 if (obj != scm_undef) {
29 heap->m_symbol.unlock();
30 return obj;
31 }
32 }
33 int bytes = sizeof(scm_symbol_rec_t) + len + 1;
34 if (bytes <= INTERNAL_PRIVATE_THRESHOLD) {
35 obj = (scm_symbol_t)heap->allocate_collectible(bytes);
36 obj->name = (char*)((uintptr_t)obj + sizeof(scm_symbol_rec_t));
37 } else {
38 obj = (scm_symbol_t)heap->allocate_collectible(sizeof(scm_symbol_rec_t));
39 obj->name = (char*)heap->allocate_private(len + 1);
40 }
41 obj->hdr = scm_hdr_symbol | MAKEBITS(len, HDR_SYMBOL_SIZE_SHIFT) ;
42 memcpy(obj->name, name, len);
43 obj->name[len] = 0;
44 heap->m_symbol.put(obj);
45 }
46 heap->m_symbol.unlock();
47 return obj;
48 #else
49 heap->m_symbol.lock();
50 scm_symbol_t obj = (scm_symbol_t)heap->m_symbol.get(name, len);
51 if (obj == scm_undef) {
52 int bytes = sizeof(scm_symbol_rec_t) + len + 1;
53 if (bytes <= INTERNAL_PRIVATE_THRESHOLD) {
54 obj = (scm_symbol_t)heap->allocate_collectible(bytes);
55 obj->name = (char*)((uintptr_t)obj + sizeof(scm_symbol_rec_t));
56 } else {
57 obj = (scm_symbol_t)heap->allocate_collectible(sizeof(scm_symbol_rec_t));
58 obj->name = (char*)heap->allocate_private(len + 1);
59 }
60 obj->hdr = scm_hdr_symbol | MAKEBITS(len, HDR_SYMBOL_SIZE_SHIFT) ;
61 memcpy(obj->name, name, len);
62 obj->name[len] = 0;
63 heap->m_symbol.put(obj);
64 }
65 heap->m_symbol.unlock();
66 return obj;
67 #endif
68 }
69
70 scm_symbol_t
make_symbol_uninterned(object_heap_t * heap,const char * name,int len)71 make_symbol_uninterned(object_heap_t* heap, const char *name, int len)
72 {
73 scm_symbol_t obj;
74 int bytes = sizeof(scm_symbol_rec_t) + len + 2;
75 if (bytes <= INTERNAL_PRIVATE_THRESHOLD) {
76 obj = (scm_symbol_t)heap->allocate_collectible(bytes);
77 obj->name = (char*)((uintptr_t)obj + sizeof(scm_symbol_rec_t));
78 } else {
79 obj = (scm_symbol_t)heap->allocate_collectible(sizeof(scm_symbol_rec_t));
80 obj->name = (char*)heap->allocate_private(len + 2);
81 }
82 obj->hdr = scm_hdr_symbol | MAKEBITS(len, HDR_SYMBOL_SIZE_SHIFT) | HDR_SYMBOL_UNINTERNED_BIT;
83 memcpy(obj->name, name, len);
84 obj->name[len] = 0;
85 obj->name[len + 1] = len;
86 return obj;
87 }
88
89 scm_symbol_t
make_symbol_uninterned(object_heap_t * heap,const char * name,int len,int prefix)90 make_symbol_uninterned(object_heap_t* heap, const char *name, int len, int prefix)
91 {
92 scm_symbol_t obj;
93 int bytes = sizeof(scm_symbol_rec_t) + len + 2;
94 if (bytes <= INTERNAL_PRIVATE_THRESHOLD) {
95 obj = (scm_symbol_t)heap->allocate_collectible(bytes);
96 obj->name = (char*)((uintptr_t)obj + sizeof(scm_symbol_rec_t));
97 } else {
98 obj = (scm_symbol_t)heap->allocate_collectible(sizeof(scm_symbol_rec_t));
99 obj->name = (char*)heap->allocate_private(len + 2);
100 }
101 obj->hdr = scm_hdr_symbol | MAKEBITS(len, HDR_SYMBOL_SIZE_SHIFT) | HDR_SYMBOL_UNINTERNED_BIT;
102 memcpy(obj->name, name, len);
103 obj->name[len] = 0;
104 obj->name[len + 1] = prefix;
105 return obj;
106 }
107
108 scm_symbol_t
make_symbol(object_heap_t * heap,const char * name)109 make_symbol(object_heap_t* heap, const char *name)
110 {
111 return make_symbol(heap, name, strlen(name));
112 }
113
114 scm_symbol_t
make_symbol_inherent(object_heap_t * heap,const char * name,int code)115 make_symbol_inherent(object_heap_t* heap, const char* name, int code)
116 {
117 assert(code < 256);
118 assert(code < INHERENT_TOTAL_COUNT);
119 assert(heap->m_inherents[code] == scm_undef);
120 scm_symbol_t obj = (scm_symbol_t)heap->allocate_collectible(sizeof(scm_symbol_rec_t));
121 int len = strlen(name);
122 obj->hdr = scm_hdr_symbol
123 | MAKEBITS(len, HDR_SYMBOL_SIZE_SHIFT)
124 | MAKEBITS(code, HDR_SYMBOL_CODE_SHIFT)
125 | HDR_SYMBOL_INHERENT_BIT;
126 obj->name = (char*)heap->allocate_private(len + 1);
127 strcpy(obj->name, name);
128 heap->m_inherents[code] = obj;
129 heap->m_symbol.lock();
130 assert(heap->m_symbol.get(name, len) == scm_undef);
131 heap->m_symbol.put(obj);
132 heap->m_symbol.unlock();
133 return obj;
134 }
135
136 scm_string_t
make_string(object_heap_t * heap,const char * name,int len)137 make_string(object_heap_t* heap, const char *name, int len)
138 {
139 if (len == 0) return (scm_string_t)heap->m_inherents[NIL_STRING];
140 scm_string_t obj;
141 int bytes = sizeof(scm_string_rec_t) + len + 1;
142 if (bytes <= INTERNAL_PRIVATE_THRESHOLD) {
143 obj = (scm_string_t)heap->allocate_collectible(bytes);
144 obj->name = (char*)((uintptr_t)obj + sizeof(scm_string_rec_t));
145 } else {
146 obj = (scm_string_t)heap->allocate_collectible(sizeof(scm_string_rec_t));
147 obj->name = (char*)heap->allocate_private(len + 1);
148 }
149 obj->hdr = scm_hdr_string;
150 obj->size = len;
151 memcpy(obj->name, name, len);
152 obj->name[len] = 0;
153 return obj;
154 }
155
156 scm_string_t
make_string(object_heap_t * heap,const char * name)157 make_string(object_heap_t* heap, const char *name)
158 {
159 return make_string(heap, name, strlen(name));
160 }
161
162 scm_string_t
make_string_literal(object_heap_t * heap,const char * name,int len)163 make_string_literal(object_heap_t* heap, const char* name, int len)
164 {
165 heap->m_string.lock();
166 scm_string_t obj = (scm_string_t)heap->m_string.get(name, len);
167 if (obj == scm_undef) {
168 int bytes = sizeof(scm_string_rec_t) + len + 1;
169 if (bytes <= INTERNAL_PRIVATE_THRESHOLD) {
170 obj = (scm_string_t)heap->allocate_collectible(bytes);
171 obj->name = (char*)((uintptr_t)obj + sizeof(scm_string_rec_t));
172 } else {
173 obj = (scm_string_t)heap->allocate_collectible(sizeof(scm_string_rec_t));
174 obj->name = (char*)heap->allocate_private(len + 1);
175 }
176 obj->hdr = scm_hdr_string | MAKEBITS(1, HDR_STRING_LITERAL_SHIFT);
177 obj->size = len;
178 memcpy(obj->name, name, len);
179 obj->name[len] = 0;
180 heap->m_string.put(obj);
181 }
182 heap->m_string.unlock();
183 return obj;
184 }
185
186 scm_string_t
make_string_literal(object_heap_t * heap,const char * name)187 make_string_literal(object_heap_t* heap, const char *name)
188 {
189 return make_string_literal(heap, name, strlen(name));
190 }
191
192 scm_string_t
make_string(object_heap_t * heap,int n,char c)193 make_string(object_heap_t* heap, int n, char c)
194 {
195 if (n == 0) return (scm_string_t)heap->m_inherents[NIL_STRING];
196 scm_string_t obj = (scm_string_t)heap->allocate_collectible(sizeof(scm_string_rec_t));
197 obj->hdr = scm_hdr_string;
198 obj->size = n;
199 obj->name = (char*)heap->allocate_private(n + 1);
200 memset(obj->name, c, n);
201 obj->name[n] = 0;
202 return obj;
203 }
204
205 scm_vector_t
make_vector(object_heap_t * heap,scm_obj_t lst)206 make_vector(object_heap_t* heap, scm_obj_t lst)
207 {
208 if (lst == scm_nil) return (scm_vector_t)heap->m_inherents[NIL_VECTOR];
209 int n = list_length(lst);
210 int bytes = sizeof(scm_vector_rec_t) + sizeof(scm_obj_t) * n;
211 scm_vector_t obj;
212 if (bytes <= INTERNAL_PRIVATE_THRESHOLD) {
213 obj = (scm_vector_t)heap->allocate_collectible(bytes);
214 obj->hdr = scm_hdr_vector;
215 obj->count = n;
216 obj->elts = (scm_obj_t*)((uintptr_t)obj + sizeof(scm_vector_rec_t));
217 } else {
218 obj = (scm_vector_t)heap->allocate_collectible(sizeof(scm_vector_rec_t));
219 obj->hdr = scm_hdr_vector;
220 obj->count = n;
221 obj->elts = (scm_obj_t*)heap->allocate_private(sizeof(scm_obj_t) * n);
222 }
223 for (int i = 0; i < n; i++) {
224 obj->elts[i] = CAR(lst);
225 lst = CDR(lst);
226 }
227 return obj;
228 }
229
230 scm_vector_t
make_vector(object_heap_t * heap,int n,scm_obj_t elt)231 make_vector(object_heap_t* heap, int n, scm_obj_t elt)
232 {
233 if (n == 0) return (scm_vector_t)heap->m_inherents[NIL_VECTOR];
234 int bytes = sizeof(scm_vector_rec_t) + sizeof(scm_obj_t) * n;
235 scm_vector_t obj;
236 if (bytes <= INTERNAL_PRIVATE_THRESHOLD) {
237 obj = (scm_vector_t)heap->allocate_collectible(bytes);
238 obj->hdr = scm_hdr_vector;
239 obj->count = n;
240 obj->elts = (scm_obj_t*)((uintptr_t)obj + sizeof(scm_vector_rec_t));
241 } else {
242 obj = (scm_vector_t)heap->allocate_collectible(sizeof(scm_vector_rec_t));
243 obj->hdr = scm_hdr_vector;
244 obj->count = n;
245 obj->elts = (scm_obj_t*)heap->allocate_private(sizeof(scm_obj_t) * n);
246 }
247 for (int i = 0; i < n; i++) obj->elts[i] = elt;
248 return obj;
249 }
250
251 scm_bvector_t
make_bvector(object_heap_t * heap,int n)252 make_bvector(object_heap_t* heap, int n)
253 {
254 if (n == 0) return (scm_bvector_t)heap->m_inherents[NIL_BVECTOR];
255 scm_bvector_t obj = (scm_bvector_t)heap->allocate_collectible(sizeof(scm_bvector_rec_t));
256 obj->hdr = scm_hdr_bvector;
257 obj->count = n;
258 obj->elts = (uint8_t*)heap->allocate_private(n);
259 memset(obj->elts, 0, n);
260 return obj;
261 }
262
263 scm_bvector_t
make_bvector_mapping(object_heap_t * heap,void * p,int n)264 make_bvector_mapping(object_heap_t* heap, void* p, int n)
265 {
266 scm_bvector_t obj = (scm_bvector_t)heap->allocate_collectible(sizeof(scm_bvector_rec_t));
267 obj->hdr = scm_hdr_bvector | MAKEBITS(1, HDR_BVECTOR_MAPPING_SHIFT);
268 obj->count = n;
269 obj->elts = (uint8_t*)p;
270 return obj;
271 }
272
273 scm_port_t
make_temp_file_port(object_heap_t * heap,scm_obj_t name,int buffer_mode,scm_obj_t transcoder)274 make_temp_file_port(object_heap_t* heap, scm_obj_t name, int buffer_mode, scm_obj_t transcoder)
275 {
276 scm_port_t obj = (scm_port_t)heap->allocate_collectible(sizeof(scm_port_rec_t));
277 memset(obj, 0, sizeof(scm_port_rec_t));
278 obj->hdr = scm_hdr_port;
279 obj->lock.init(true);
280 scoped_lock lock(obj->lock);
281 port_open_temp_file(obj, name, buffer_mode, transcoder);
282 return obj;
283 }
284
285 scm_port_t
make_std_port(object_heap_t * heap,fd_t fd,scm_obj_t name,int direction,int file_options,int buffer_mode,scm_obj_t transcoder)286 make_std_port(object_heap_t* heap, fd_t fd, scm_obj_t name, int direction, int file_options, int buffer_mode, scm_obj_t transcoder)
287 {
288 scm_port_t obj = (scm_port_t)heap->allocate_collectible(sizeof(scm_port_rec_t));
289 memset(obj, 0, sizeof(scm_port_rec_t));
290 obj->hdr = scm_hdr_port;
291 obj->lock.init(true);
292 scoped_lock lock(obj->lock);
293 port_open_std(obj, fd, name, direction, file_options, buffer_mode, transcoder);
294 return obj;
295 }
296
297 scm_port_t
make_file_port(object_heap_t * heap,scm_obj_t name,int direction,int file_options,int buffer_mode,scm_obj_t transcoder)298 make_file_port(object_heap_t* heap, scm_obj_t name, int direction, int file_options, int buffer_mode, scm_obj_t transcoder)
299 {
300 scm_port_t obj = (scm_port_t)heap->allocate_collectible(sizeof(scm_port_rec_t));
301 memset(obj, 0, sizeof(scm_port_rec_t));
302 obj->hdr = scm_hdr_port;
303 obj->lock.init(true);
304 scoped_lock lock(obj->lock);
305 port_open_file(obj, name, direction, file_options, buffer_mode, transcoder);
306 return obj;
307 }
308
309 scm_port_t
make_bytevector_port(object_heap_t * heap,scm_obj_t name,int direction,scm_obj_t bytes,scm_obj_t transcoder)310 make_bytevector_port(object_heap_t* heap, scm_obj_t name, int direction, scm_obj_t bytes, scm_obj_t transcoder)
311 {
312 assert(SYMBOLP(name));
313 scm_port_t obj = (scm_port_t)heap->allocate_collectible(sizeof(scm_port_rec_t));
314 memset(obj, 0, sizeof(scm_port_rec_t));
315 obj->hdr = scm_hdr_port;
316 obj->lock.init(true);
317 scoped_lock lock(obj->lock);
318 port_open_bytevector(obj, name, direction, bytes, transcoder);
319 return obj;
320 }
321
322 scm_port_t
make_custom_port(object_heap_t * heap,scm_obj_t name,int direction,scm_obj_t handlers,scm_obj_t transcoder)323 make_custom_port(object_heap_t* heap, scm_obj_t name, int direction, scm_obj_t handlers, scm_obj_t transcoder)
324 {
325 scm_port_t obj = (scm_port_t)heap->allocate_collectible(sizeof(scm_port_rec_t));
326 memset(obj, 0, sizeof(scm_port_rec_t));
327 obj->hdr = scm_hdr_port;
328 obj->lock.init(true);
329 scoped_lock lock(obj->lock);
330 port_make_custom_port(obj, name, direction, handlers, transcoder);
331 return obj;
332 }
333
334 scm_port_t
make_socket_port(object_heap_t * heap,scm_socket_t socket,scm_obj_t transcoder)335 make_socket_port(object_heap_t* heap, scm_socket_t socket, scm_obj_t transcoder)
336 {
337 scm_port_t obj = (scm_port_t)heap->allocate_collectible(sizeof(scm_port_rec_t));
338 memset(obj, 0, sizeof(scm_port_rec_t));
339 obj->hdr = scm_hdr_port;
340 obj->lock.init(true);
341 scoped_lock lock(obj->lock);
342 port_make_socket_port(obj, socket, transcoder);
343 return obj;
344 }
345
346 scm_port_t
make_transcoded_port(object_heap_t * heap,scm_obj_t name,scm_port_t port,scm_bvector_t transcoder)347 make_transcoded_port(object_heap_t* heap, scm_obj_t name, scm_port_t port, scm_bvector_t transcoder)
348 {
349 port->lock.verify_locked();
350 scm_port_t obj = (scm_port_t)heap->allocate_collectible(sizeof(scm_port_rec_t));
351 memset(obj, 0, sizeof(scm_port_rec_t));
352 obj->hdr = scm_hdr_port;
353 obj->lock.init(true);
354 scoped_lock lock(obj->lock);
355 port_make_transcoded_port(name, port, obj, transcoder);
356 return obj;
357 }
358
359 scm_values_t
make_values(object_heap_t * heap,int n)360 make_values(object_heap_t* heap, int n)
361 {
362 int bytes = sizeof(scm_values_rec_t) + sizeof(scm_obj_t) * n;
363 scm_values_t obj;
364 if (bytes <= INTERNAL_PRIVATE_THRESHOLD) {
365 obj = (scm_values_t)heap->allocate_collectible(bytes);
366 obj->hdr = scm_hdr_values | MAKEBITS(n, HDR_VALUES_COUNT_SHIFT);
367 obj->elts = (scm_obj_t*)((uintptr_t)obj + sizeof(scm_values_rec_t));
368 } else {
369 obj = (scm_values_t)heap->allocate_collectible(sizeof(scm_values_rec_t));
370 obj->hdr = scm_hdr_values | MAKEBITS(n, HDR_VALUES_COUNT_SHIFT);
371 obj->elts = (scm_obj_t*)heap->allocate_private(sizeof(scm_obj_t) * n);
372 }
373 for (int i = 0; i < n; i++) obj->elts[i] = scm_unspecified;
374 return obj;
375 }
376
377 scm_cont_t
make_cont(object_heap_t * heap,scm_obj_t rec,void * lnk)378 make_cont(object_heap_t* heap, scm_obj_t rec, void* lnk)
379 {
380 scm_cont_t obj = (scm_cont_t)heap->allocate_collectible(sizeof(scm_cont_rec_t));
381 obj->hdr = scm_hdr_cont;
382 obj->wind_rec = rec;
383 obj->cont = lnk;
384 return obj;
385 }
386
387 scm_hashtable_t
make_hashtable(object_heap_t * heap,int type,int n)388 make_hashtable(object_heap_t* heap, int type, int n)
389 {
390 assert(n > 0);
391 scm_hashtable_t obj = (scm_hashtable_t)heap->allocate_collectible(sizeof(scm_hashtable_rec_t));
392 int datum_size = sizeof(hashtable_rec_t) + sizeof(scm_obj_t) * ((n + n) - 1);
393 hashtable_rec_t* ht_datum = (hashtable_rec_t*)heap->allocate_private(datum_size);
394 ht_datum->capacity = n;
395 ht_datum->live = 0;
396 ht_datum->used = 0;
397 for (int i = 0; i < (n + n); i++) ht_datum->elts[i] = scm_hash_free;
398 switch (type) {
399 case SCM_HASHTABLE_TYPE_EQ:
400 obj->hash = NULL;
401 obj->equiv = NULL;
402 break;
403 case SCM_HASHTABLE_TYPE_EQV:
404 obj->hash = eqv_hash;
405 obj->equiv = eqv_hash_equiv;
406 break;
407 case SCM_HASHTABLE_TYPE_EQUAL:
408 obj->hash = equal_hash;
409 obj->equiv = equal_hash_equiv;
410 break;
411 case SCM_HASHTABLE_TYPE_STRING:
412 obj->hash = string_hash;
413 obj->equiv = string_hash_equiv;
414 break;
415 default:
416 assert(false);
417 }
418 obj->hdr = scm_hdr_hashtable;
419 obj->type = type;
420 obj->handlers = scm_false;
421 obj->datum = ht_datum;
422 obj->lock.init();
423 return obj;
424 }
425
426 scm_hashtable_t
make_shared_hashtable(object_heap_t * heap,int type,int n)427 make_shared_hashtable(object_heap_t* heap, int type, int n)
428 {
429 scm_hashtable_t ht = make_hashtable(heap, type, n);
430 ht->hdr |= MAKEBITS(1, HDR_HASHTABLE_SHARED_SHIFT);
431 return ht;
432 }
433
434 scm_hashtable_t
make_generic_hashtable(object_heap_t * heap,scm_vector_t handlers)435 make_generic_hashtable(object_heap_t* heap, scm_vector_t handlers)
436 {
437 assert(VECTORP(handlers));
438 scm_hashtable_t obj = (scm_hashtable_t)heap->allocate_collectible(sizeof(scm_hashtable_rec_t));
439 obj->hdr = scm_hdr_hashtable;
440 obj->type = SCM_HASHTABLE_TYPE_GENERIC;
441 obj->handlers = handlers;
442 obj->hash = NULL;
443 obj->equiv = NULL;
444 obj->datum = NULL;
445 obj->lock.init();
446 return obj;
447 }
448
449 scm_environment_t
make_environment(object_heap_t * heap,const char * name)450 make_environment(object_heap_t* heap, const char* name)
451 {
452 scm_environment_t obj = (scm_environment_t)heap->allocate_collectible(sizeof(scm_environment_rec_t));
453 obj->hdr = scm_hdr_environment;
454 obj->variable = make_hashtable(heap, SCM_HASHTABLE_TYPE_EQ, lookup_mutable_hashtable_size(0));
455 obj->macro = make_hashtable(heap, SCM_HASHTABLE_TYPE_EQ, lookup_mutable_hashtable_size(0));
456 if (name) {
457 obj->name = make_string_literal(heap, name);
458 } else {
459 char buf[32];
460 snprintf(buf, sizeof(buf), "0x%p", obj);
461 obj->name = make_string_literal(heap, buf);
462 }
463 return obj;
464 }
465
466 scm_subr_t
make_subr(object_heap_t * heap,subr_proc_t adrs,scm_obj_t doc)467 make_subr(object_heap_t* heap, subr_proc_t adrs, scm_obj_t doc)
468 {
469 scm_subr_t obj = (scm_subr_t)heap->allocate_collectible(sizeof(scm_subr_rec_t));
470 obj->hdr = scm_hdr_subr;
471 obj->adrs = adrs;
472 obj->doc = doc;
473 #if PROFILE_SUBR
474 obj->c_push = 0;
475 obj->c_load = 0;
476 obj->c_apply = 0;
477 #endif
478 return obj;
479 }
480
481 scm_closure_t
make_closure(object_heap_t * heap,int argc,int rest,void * env,scm_obj_t code,scm_obj_t doc)482 make_closure(object_heap_t* heap, int argc, int rest, void* env, scm_obj_t code, scm_obj_t doc)
483 {
484 int args = rest ? (- 1 - argc) : argc;
485 scm_closure_t obj = (scm_closure_t)heap->allocate_collectible(sizeof(scm_closure_rec_t));
486 obj->hdr = scm_hdr_closure | MAKEBITS(args, HDR_CLOSURE_ARGS_SHIFT);
487 obj->env = env;
488 obj->code = code;
489 obj->doc = doc;
490 return obj;
491 }
492
493 scm_closure_t
make_closure(object_heap_t * heap,scm_closure_t tmpl,void * env)494 make_closure(object_heap_t* heap, scm_closure_t tmpl, void* env)
495 {
496 if (env) {
497 scm_closure_t obj = (scm_closure_t)heap->allocate_collectible(sizeof(scm_closure_rec_t));
498 obj->hdr = tmpl->hdr;
499 obj->env = env;
500 obj->code = tmpl->code;
501 obj->doc = tmpl->doc;
502 return obj;
503 }
504 return tmpl;
505 }
506
507 scm_flonum_t
make_flonum(object_heap_t * heap,double num)508 make_flonum(object_heap_t* heap, double num)
509 {
510 #if USE_FLONUM_CONST
511 if (num == 0.0) {
512 union { double f64; int64_t i64; } datum;
513 datum.f64 = num;
514 if (datum.i64 < 0) {
515 return (scm_flonum_t)heap->m_inherents[FL_NEGATIVE_ZERO];
516 } else {
517 return (scm_flonum_t)heap->m_inherents[FL_POSITIVE_ZERO];
518 }
519 }
520 if (isnan(num)) return (scm_flonum_t)heap->m_inherents[FL_NAN];
521 #endif
522 scm_flonum_t obj = heap->allocate_flonum();
523 obj->hdr = scm_hdr_flonum;
524 obj->value = num;
525 return obj;
526 }
527
528 scm_flonum_t
make_flonum_32bit(object_heap_t * heap,double num)529 make_flonum_32bit(object_heap_t* heap, double num)
530 {
531 scm_flonum_t obj = heap->allocate_flonum();
532 obj->hdr = scm_hdr_flonum | MAKEBITS(1, HDR_FLONUM_32BIT_SHIFT);
533 obj->value = num;
534 return obj;
535 }
536
537 scm_bignum_t
make_bignum(object_heap_t * heap,scm_bignum_t bn)538 make_bignum(object_heap_t* heap, scm_bignum_t bn)
539 {
540 int count = HDR_BIGNUM_COUNT(bn->hdr);
541 scm_bignum_t obj = make_bignum(heap, count);
542 obj->hdr = bn->hdr;
543 memcpy(obj->elts, bn->elts, sizeof(digit_t) * count);
544 return obj;
545 }
546
547 scm_bignum_t
make_bignum(object_heap_t * heap,int n)548 make_bignum(object_heap_t* heap, int n)
549 {
550 int bytes = sizeof(scm_bignum_rec_t) + sizeof(digit_t) * n;
551 scm_bignum_t obj;
552 if (bytes <= INTERNAL_PRIVATE_THRESHOLD) {
553 obj = (scm_bignum_t)heap->allocate_collectible(bytes);
554 obj->hdr = scm_hdr_bignum | MAKEBITS(n, HDR_BIGNUM_COUNT_SHIFT);
555 if (n) obj->elts = (digit_t*)((uintptr_t)obj + sizeof(scm_bignum_rec_t));
556 else obj->elts = NULL;
557 } else {
558 obj = (scm_bignum_t)heap->allocate_collectible(sizeof(scm_bignum_rec_t));
559 obj->hdr = scm_hdr_bignum | MAKEBITS(n, HDR_BIGNUM_COUNT_SHIFT);
560 if (n) obj->elts = (digit_t*)heap->allocate_private(sizeof(digit_t) * n);
561 else obj->elts = NULL;
562 }
563 return obj;
564 }
565
566 scm_complex_t
make_complex(object_heap_t * heap,double real,double imag)567 make_complex(object_heap_t* heap, double real, double imag)
568 {
569 scm_complex_t obj = (scm_complex_t)heap->allocate_collectible(sizeof(scm_complex_rec_t));
570 obj->hdr = scm_hdr_complex;
571 obj->real = make_flonum(heap, real);
572 obj->imag = make_flonum(heap, imag);
573 return obj;
574 }
575
576 scm_complex_t
make_complex(object_heap_t * heap,scm_obj_t real,scm_obj_t imag)577 make_complex(object_heap_t* heap, scm_obj_t real, scm_obj_t imag)
578 {
579 assert(!COMPLEXP(real));
580 assert(!COMPLEXP(imag));
581 scm_complex_t obj = (scm_complex_t)heap->allocate_collectible(sizeof(scm_complex_rec_t));
582 obj->hdr = scm_hdr_complex;
583 obj->real = real;
584 obj->imag = imag;
585 return obj;
586 }
587
588 scm_rational_t
make_rational(object_heap_t * heap,scm_obj_t numerator,scm_obj_t denominator)589 make_rational(object_heap_t* heap, scm_obj_t numerator, scm_obj_t denominator)
590 {
591 assert(n_negative_pred(denominator) == false);
592 assert(n_exact_pred(numerator));
593 assert(n_exact_pred(denominator));
594 scm_rational_t obj = (scm_rational_t)heap->allocate_collectible(sizeof(scm_rational_rec_t));
595 obj->hdr = scm_hdr_rational;
596 obj->nume = numerator;
597 obj->deno = denominator;
598 return obj;
599 }
600
601 scm_gloc_t
make_gloc(object_heap_t * heap,scm_environment_t environment,scm_symbol_t symbol)602 make_gloc(object_heap_t* heap, scm_environment_t environment, scm_symbol_t symbol)
603 {
604 scm_gloc_t obj = (scm_gloc_t)heap->allocate_collectible(sizeof(scm_gloc_rec_t));
605 obj->hdr = scm_hdr_gloc;
606 obj->variable = symbol;
607 #if GLOC_DEBUG_INFO
608 obj->environment = environment->name;
609 #endif
610 obj->value = scm_undef;
611 return obj;
612 }
613
614 scm_tuple_t
make_tuple(object_heap_t * heap,int n,scm_obj_t elt)615 make_tuple(object_heap_t* heap, int n, scm_obj_t elt)
616 {
617 if (n == 0) return (scm_tuple_t)heap->m_inherents[NIL_TUPLE];
618 int bytes = sizeof(scm_tuple_rec_t) + sizeof(scm_obj_t) * n;
619 scm_tuple_t obj;
620 if (bytes <= INTERNAL_PRIVATE_THRESHOLD) {
621 obj = (scm_tuple_t)heap->allocate_collectible(bytes);
622 obj->hdr = scm_hdr_tuple | MAKEBITS(n, HDR_TUPLE_COUNT_SHIFT);
623 obj->elts = (scm_obj_t*)((uintptr_t)obj + sizeof(scm_tuple_rec_t));
624 } else {
625 obj = (scm_tuple_t)heap->allocate_collectible(sizeof(scm_tuple_rec_t));
626 obj->hdr = scm_hdr_tuple | MAKEBITS(n, HDR_TUPLE_COUNT_SHIFT);
627 obj->elts = (scm_obj_t*)heap->allocate_private(sizeof(scm_obj_t) * n);
628 }
629 for (int i = 0; i < n; i++) obj->elts[i] = elt;
630 return obj;
631 }
632
633 scm_tuple_t
make_tuple(object_heap_t * heap,int len,...)634 make_tuple(object_heap_t* heap, int len, ...)
635 {
636 va_list ap;
637 va_start(ap, len);
638 scm_tuple_t tuple = make_tuple(heap, len, scm_unspecified);
639 for (int i = 0; i < len; i++) tuple->elts[i] = va_arg(ap, scm_obj_t);
640 va_end(ap);
641 return tuple;
642 }
643
644 scm_weakmapping_t
make_weakmapping(object_heap_t * heap,scm_obj_t key,scm_obj_t value)645 make_weakmapping(object_heap_t* heap, scm_obj_t key, scm_obj_t value)
646 {
647 scm_weakmapping_t obj = (scm_weakmapping_t)heap->allocate_weakmapping();
648 obj->hdr = scm_hdr_weakmapping;
649 obj->key = key;
650 obj->value = value;
651 return obj;
652 }
653
654 scm_weakhashtable_t
make_weakhashtable(object_heap_t * heap,int n)655 make_weakhashtable(object_heap_t* heap, int n)
656 {
657 assert(n > 0);
658 scm_weakhashtable_t obj = (scm_weakhashtable_t)heap->allocate_collectible(sizeof(scm_weakhashtable_rec_t));
659 int datum_size = sizeof(weakhashtable_rec_t) + sizeof(scm_obj_t) * (n - 1);
660 weakhashtable_rec_t* ht_datum = (weakhashtable_rec_t*)heap->allocate_private(datum_size);
661 ht_datum->capacity = n;
662 ht_datum->live = 0;
663 ht_datum->used = 0;
664 for (int i = 0; i < n; i++) ht_datum->elts[i] = scm_hash_free;
665 obj->hdr = scm_hdr_weakhashtable;
666 obj->datum = ht_datum;
667 obj->lock.init();
668 return obj;
669 }
670
671 scm_weakhashtable_t
make_shared_weakhashtable(object_heap_t * heap,int n)672 make_shared_weakhashtable(object_heap_t* heap, int n)
673 {
674 scm_weakhashtable_t ht = make_weakhashtable(heap, n);
675 ht->hdr |= MAKEBITS(1, HDR_WEAKHASHTABLE_SHARED_SHIFT);
676 return ht;
677 }
678
679 scm_socket_t
make_socket(object_heap_t * heap,const char * node,const char * service,int family,int type,int protocol,int flags)680 make_socket(object_heap_t* heap, const char* node, const char* service, int family, int type, int protocol, int flags)
681 {
682 scm_socket_t obj = (scm_socket_t)heap->allocate_collectible(sizeof(scm_socket_rec_t));
683 memset(obj, 0 , sizeof(scm_socket_rec_t));
684 obj->hdr = scm_hdr_socket;
685 obj->fd = INVALID_SOCKET;
686 obj->lock.init(true);
687 scoped_lock lock(obj->lock);
688 socket_open(obj, node, service, family, type, protocol, flags);
689 return obj;
690 }
691
692 scm_socket_t
make_socket(object_heap_t * heap)693 make_socket(object_heap_t* heap)
694 {
695 scm_socket_t obj = (scm_socket_t)heap->allocate_collectible(sizeof(scm_socket_rec_t));
696 memset(obj, 0 , sizeof(scm_socket_rec_t));
697 obj->hdr = scm_hdr_socket;
698 obj->fd = INVALID_SOCKET;
699 obj->lock.init(true);
700 return obj;
701 }
702
703 scm_sharedqueue_t
make_sharedqueue(object_heap_t * heap,int n)704 make_sharedqueue(object_heap_t* heap, int n)
705 {
706 assert(n);
707 scm_sharedqueue_t obj = (scm_sharedqueue_t)heap->allocate_collectible(sizeof(scm_sharedqueue_rec_t));
708 obj->hdr = scm_hdr_sharedqueue;
709 obj->buf.init(n + MAX_VIRTUAL_MACHINE);
710 obj->queue.init(n);
711 return obj;
712 }
713
714 scm_sharedbag_t
make_sharedbag(object_heap_t * heap,int depth)715 make_sharedbag(object_heap_t* heap, int depth)
716 {
717 scm_sharedbag_t obj = (scm_sharedbag_t)heap->allocate_collectible(sizeof(scm_sharedbag_rec_t));
718 sharedbag_slot_t** datum = (sharedbag_slot_t**)malloc(sizeof(sharedbag_slot_t*) * MAX_VIRTUAL_MACHINE);
719 for (int i = 0; i < MAX_VIRTUAL_MACHINE; i++) {
720 datum[i] = (sharedbag_slot_t*)malloc(sizeof(sharedbag_slot_t));
721 datum[i]->key = NULL;
722 datum[i]->buf.init(depth + MAX_VIRTUAL_MACHINE);
723 datum[i]->queue.init(depth);
724 }
725 obj->hdr = scm_hdr_sharedbag;
726 obj->capacity = MAX_VIRTUAL_MACHINE;
727 obj->depth = depth;
728 obj->datum = datum;
729 obj->lock.init();
730 return obj;
731 }
732
733 scm_obj_t
make_list(object_heap_t * heap,int len,...)734 make_list(object_heap_t* heap, int len, ...)
735 {
736 va_list ap;
737 va_start(ap, len);
738 if (len == 0) return scm_nil;
739 scm_obj_t obj = make_pair(heap, va_arg(ap, scm_obj_t), scm_nil);
740 scm_obj_t tail = obj;
741 for (int i = 1; i < len; i++) {
742 scm_obj_t e = make_pair(heap, va_arg(ap, scm_obj_t), scm_nil);
743 CDR(tail) = e;
744 tail = e;
745 }
746 va_end(ap);
747 return obj;
748 }
749
750 void
rehash_hashtable(object_heap_t * heap,scm_hashtable_t ht,int nsize)751 rehash_hashtable(object_heap_t* heap, scm_hashtable_t ht, int nsize)
752 {
753 assert(HASHTABLEP(ht));
754 ht->lock.verify_locked();
755 hashtable_rec_t* ht_datum = ht->datum;
756 int nelts = ht_datum->capacity;
757 assert(HASH_DENSE_THRESHOLD(nsize) > ht_datum->live);
758 scm_hashtable_t ht2 = make_hashtable(heap, ht->type, nsize);
759 scoped_lock lock(ht2->lock);
760 for (int i = 0; i < nelts; i++) {
761 if (ht_datum->elts[i] == scm_hash_free) continue;
762 if (ht_datum->elts[i] == scm_hash_deleted) continue;
763 put_hashtable(ht2, ht_datum->elts[i], ht_datum->elts[i + nelts]);
764 }
765 swap(ht->datum, ht2->datum);
766 }
767
768 void
inplace_rehash_hashtable(object_heap_t * heap,scm_hashtable_t ht)769 inplace_rehash_hashtable(object_heap_t* heap, scm_hashtable_t ht)
770 {
771 assert(HASHTABLEP(ht));
772 ht->lock.verify_locked();
773 hashtable_rec_t* ht_datum = ht->datum;
774 int nelts = ht_datum->capacity;
775 int datum_size = sizeof(hashtable_rec_t) + sizeof(scm_obj_t) * ((nelts + nelts) - 1);
776 hashtable_rec_t* save_datum = (hashtable_rec_t*)malloc(datum_size);
777 memcpy(save_datum, ht_datum, datum_size);
778 clear_volatile_hashtable(ht);
779 for (int i = 0; i < nelts; i++) {
780 if (save_datum->elts[i] == scm_hash_free) continue;
781 if (save_datum->elts[i] == scm_hash_deleted) continue;
782 put_hashtable(ht, save_datum->elts[i], save_datum->elts[i + nelts]);
783 }
784 free(save_datum);
785 }
786
787 void
rehash_weakhashtable(object_heap_t * heap,scm_weakhashtable_t ht,int nsize)788 rehash_weakhashtable(object_heap_t* heap, scm_weakhashtable_t ht, int nsize)
789 {
790 assert(WEAKHASHTABLEP(ht));
791 ht->lock.verify_locked();
792 weakhashtable_rec_t* ht_datum = ht->datum;
793 int nelts = ht_datum->capacity;
794 assert(HASH_DENSE_THRESHOLD(nsize) > ht_datum->live);
795 scm_weakhashtable_t ht2 = make_weakhashtable(heap, nsize);
796 scoped_lock lock(ht2->lock);
797 for (int i = 0; i < nelts; i++) {
798 scm_obj_t obj = ht_datum->elts[i];
799 if (obj == scm_hash_free) continue;
800 if (obj == scm_hash_deleted) continue;
801 assert(WEAKMAPPINGP(obj));
802 if (((scm_weakmapping_t)obj)->key == scm_false) continue;
803 put_weakhashtable(ht2, (scm_weakmapping_t)obj);
804 }
805 swap(ht->datum, ht2->datum);
806 }
807
808 void
inplace_rehash_weakhashtable(object_heap_t * heap,scm_weakhashtable_t ht)809 inplace_rehash_weakhashtable(object_heap_t* heap, scm_weakhashtable_t ht)
810 {
811 assert(WEAKHASHTABLEP(ht));
812 ht->lock.verify_locked();
813 weakhashtable_rec_t* ht_datum = ht->datum;
814 int nelts = ht_datum->capacity;
815 int datum_size = sizeof(weakhashtable_rec_t) + sizeof(scm_obj_t) * (nelts - 1);
816 weakhashtable_rec_t* save_datum = (weakhashtable_rec_t*)malloc(datum_size);
817 memcpy(save_datum, ht_datum, datum_size);
818 clear_volatile_weakhashtable(ht);
819 for (int i = 0; i < nelts; i++) {
820 scm_obj_t obj = save_datum->elts[i];
821 if (obj == scm_hash_free) continue;
822 if (obj == scm_hash_deleted) continue;
823 assert(WEAKMAPPINGP(obj));
824 if (((scm_weakmapping_t)obj)->key == scm_false) continue;
825 put_weakhashtable(ht, (scm_weakmapping_t)obj);
826 }
827 free(save_datum);
828 }
829
830 scm_hashtable_t
copy_hashtable(object_heap_t * heap,scm_hashtable_t ht,bool immutable)831 copy_hashtable(object_heap_t* heap, scm_hashtable_t ht, bool immutable)
832 {
833 assert(HASHTABLEP(ht));
834 ht->lock.verify_locked();
835 hashtable_rec_t* ht_datum = ht->datum;
836 int nelts = ht_datum->capacity;
837 scm_hashtable_t ht2 = make_hashtable(heap, ht->type, lookup_immutable_hashtable_size(HASH_IMMUTABLE_SIZE(ht_datum->live)));
838 scoped_lock lock(ht2->lock);
839 for (int i = 0; i < nelts; i++) {
840 if (ht_datum->elts[i] == scm_hash_free) continue;
841 if (ht_datum->elts[i] == scm_hash_deleted) continue;
842 put_hashtable(ht2, ht_datum->elts[i], ht_datum->elts[i + nelts]);
843 }
844 if (HDR_HASHTABLE_SHARED(ht->hdr)) ht2->hdr |= MAKEBITS(1, HDR_HASHTABLE_SHARED_SHIFT);
845 if (immutable) ht2->hdr |= MAKEBITS(1, HDR_HASHTABLE_IMMUTABLE_SHIFT);
846 return ht2;
847 }
848
849 scm_weakhashtable_t
copy_weakhashtable(object_heap_t * heap,scm_weakhashtable_t ht,bool immutable)850 copy_weakhashtable(object_heap_t* heap, scm_weakhashtable_t ht, bool immutable)
851 {
852 assert(WEAKHASHTABLEP(ht));
853 ht->lock.verify_locked();
854 weakhashtable_rec_t* ht_datum = ht->datum;
855 int nelts = ht_datum->capacity;
856 scm_weakhashtable_t ht2 = make_weakhashtable(heap, lookup_immutable_hashtable_size(HASH_IMMUTABLE_SIZE(ht_datum->live)));
857 scoped_lock lock(ht2->lock);
858 for (int i = 0; i < nelts; i++) {
859 scm_obj_t obj = ht_datum->elts[i];
860 if (obj == scm_hash_free) continue;
861 if (obj == scm_hash_deleted) continue;
862 assert(WEAKMAPPINGP(obj));
863 if (((scm_weakmapping_t)obj)->key == scm_false) continue;
864 put_weakhashtable(ht2, (scm_weakmapping_t)obj);
865 }
866 if (HDR_WEAKHASHTABLE_SHARED(ht->hdr)) ht2->hdr |= MAKEBITS(1, HDR_WEAKHASHTABLE_SHARED_SHIFT);
867 if (immutable) ht2->hdr |= MAKEBITS(1, HDR_WEAKHASHTABLE_IMMUTABLE_SHIFT);
868 return ht2;
869 }
870
871 scm_weakhashtable_t
clone_weakhashtable(object_heap_t * heap,scm_weakhashtable_t ht,bool immutable)872 clone_weakhashtable(object_heap_t* heap, scm_weakhashtable_t ht, bool immutable)
873 {
874 assert(WEAKHASHTABLEP(ht));
875 ht->lock.verify_locked();
876 weakhashtable_rec_t* ht_datum = ht->datum;
877 int nelts = ht_datum->capacity;
878 scm_weakhashtable_t ht2 = make_weakhashtable(heap, lookup_immutable_hashtable_size(HASH_IMMUTABLE_SIZE(ht_datum->live)));
879 scoped_lock lock(ht2->lock);
880 for (int i = 0; i < nelts; i++) {
881 scm_obj_t obj = ht_datum->elts[i];
882 if (obj == scm_hash_free) continue;
883 if (obj == scm_hash_deleted) continue;
884 assert(WEAKMAPPINGP(obj));
885 scm_weakmapping_t wmap = (scm_weakmapping_t)obj;
886 if (wmap->key == scm_false) continue;
887 put_weakhashtable(ht2, make_weakmapping(heap, wmap->key, wmap->value));
888 }
889 if (HDR_WEAKHASHTABLE_SHARED(ht->hdr)) ht2->hdr |= MAKEBITS(1, HDR_WEAKHASHTABLE_SHARED_SHIFT);
890 if (immutable) ht2->hdr |= MAKEBITS(1, HDR_WEAKHASHTABLE_IMMUTABLE_SHIFT);
891 return ht2;
892 }
893
894 void
clear_hashtable(object_heap_t * heap,scm_hashtable_t ht,int n)895 clear_hashtable(object_heap_t* heap, scm_hashtable_t ht, int n)
896 {
897 assert(HASHTABLEP(ht));
898 ht->lock.verify_locked();
899 scm_hashtable_t ht2 = make_hashtable(heap, ht->type, n);
900 swap(ht->datum, ht2->datum);
901 }
902
903 void
clear_weakhashtable(object_heap_t * heap,scm_weakhashtable_t ht,int n)904 clear_weakhashtable(object_heap_t* heap, scm_weakhashtable_t ht, int n)
905 {
906 assert(WEAKHASHTABLEP(ht));
907 ht->lock.verify_locked();
908 scm_weakhashtable_t ht2 = make_weakhashtable(heap, n);
909 swap(ht->datum, ht2->datum);
910 }
911
912 void
clear_volatile_hashtable(scm_hashtable_t ht)913 clear_volatile_hashtable(scm_hashtable_t ht)
914 {
915 assert(HASHTABLEP(ht));
916 ht->lock.verify_locked();
917 hashtable_rec_t* ht_datum = ht->datum;
918 int n = ht_datum->capacity;
919 ht_datum->live = 0;
920 ht_datum->used = 0;
921 for (int i = 0; i < (n + n); i++) ht_datum->elts[i] = scm_hash_free;
922 }
923
924 void
clear_volatile_weakhashtable(scm_weakhashtable_t ht)925 clear_volatile_weakhashtable(scm_weakhashtable_t ht)
926 {
927 assert(WEAKHASHTABLEP(ht));
928 ht->lock.verify_locked();
929 weakhashtable_rec_t* ht_datum = ht->datum;
930 int n = ht_datum->capacity;
931 ht_datum->live = 0;
932 ht_datum->used = 0;
933 for (int i = 0; i < n; i++) ht_datum->elts[i] = scm_hash_free;
934 }
935
936 void
finalize(object_heap_t * heap,void * obj)937 finalize(object_heap_t* heap, void* obj)
938 {
939 // do not access shared object during finalize, it may collected.
940 assert(heap->is_collectible(obj));
941 if (PAIRP(obj)) {
942 assert(false);
943 }
944 if (FLONUMP(obj)) {
945 assert(false);
946 }
947
948 int tc = HDR_TC(HDR(obj));
949 assert(tc >= 0);
950 assert(tc <= TC_MASKBITS);
951 switch (tc) {
952 case TC_BIGNUM: {
953 scm_bignum_t bignum = (scm_bignum_t)obj;
954 if (bignum->elts != (digit_t*)((uintptr_t)bignum + sizeof(scm_bignum_rec_t))) {
955 heap->deallocate_private(bignum->elts);
956 }
957 break;
958 }
959 case TC_SYMBOL: {
960 scm_symbol_t symbol = (scm_symbol_t)obj;
961 if (symbol->name != (char*)((uintptr_t)symbol + sizeof(scm_symbol_rec_t))) {
962 heap->deallocate_private(symbol->name);
963 }
964 break;
965 }
966 case TC_STRING: {
967 scm_string_t string = (scm_string_t)obj;
968 if (string->name != (char*)((uintptr_t)string + sizeof(scm_string_rec_t))) {
969 heap->deallocate_private(string->name);
970 }
971 break;
972 }
973 case TC_VECTOR: {
974 scm_vector_t vector = (scm_vector_t)obj;
975 if (vector->elts != (scm_obj_t*)((uintptr_t)vector + sizeof(scm_vector_rec_t))) {
976 heap->deallocate_private(vector->elts);
977 }
978 break;
979 }
980 case TC_BVECTOR: {
981 scm_bvector_t bvector = (scm_bvector_t)obj;
982 if (HDR_BVECTOR_MAPPING(bvector->hdr) == 0) heap->deallocate_private(bvector->elts);
983 break;
984 }
985 case TC_TUPLE: {
986 scm_tuple_t tuple = (scm_tuple_t)obj;
987 if (tuple->elts != (scm_obj_t*)((uintptr_t)tuple + sizeof(scm_tuple_rec_t))) {
988 heap->deallocate_private(tuple->elts);
989 }
990 break;
991 }
992 case TC_VALUES: {
993 scm_values_t values = (scm_values_t)obj;
994 if (values->elts != (scm_obj_t*)((uintptr_t)values + sizeof(scm_values_rec_t))) {
995 heap->deallocate_private(values->elts);
996 }
997 break;
998 }
999 case TC_HASHTABLE: {
1000 scm_hashtable_t ht = (scm_hashtable_t)obj;
1001 heap->deallocate_private(ht->datum);
1002 ht->lock.destroy();
1003 break;
1004 }
1005 case TC_WEAKHASHTABLE: {
1006 scm_weakhashtable_t ht = (scm_weakhashtable_t)obj;
1007 heap->deallocate_private(ht->datum);
1008 ht->lock.destroy();
1009 break;
1010 }
1011 case TC_PORT: {
1012 scm_port_t port = (scm_port_t)obj;
1013 {
1014 scoped_lock lock(port->lock);
1015 if (port->type != SCM_PORT_TYPE_CUSTOM) port_close(port);
1016 // todo: finalizer for custom port
1017 }
1018 port->lock.destroy();
1019 break;
1020 }
1021 case TC_SOCKET: {
1022 scm_socket_t socket = (scm_socket_t)obj;
1023 {
1024 scoped_lock lock(socket->lock);
1025 socket_close(socket);
1026 }
1027 socket->lock.destroy();
1028 break;
1029 }
1030 case TC_SHAREDQUEUE: {
1031 scm_sharedqueue_t queue = (scm_sharedqueue_t)obj;
1032 queue->buf.destroy();
1033 queue->queue.destroy();
1034 break;
1035 }
1036 case TC_SHAREDBAG: {
1037 scm_sharedbag_t bag = (scm_sharedbag_t)obj;
1038 for (int i = 0; i < bag->capacity; i++) {
1039 bag->datum[i]->buf.destroy();
1040 bag->datum[i]->queue.destroy();
1041 free(bag->datum[i]->key);
1042 free(bag->datum[i]);
1043 }
1044 free(bag->datum);
1045 bag->lock.destroy();
1046 break;
1047 }
1048 }
1049 }
1050
1051 void
renounce(void * obj,int size,void * refcon)1052 renounce(void* obj, int size, void* refcon)
1053 {
1054 if (PAIRP(obj)) return;
1055 int tc = HDR_TC(HDR(obj));
1056 assert(tc >= 0);
1057 assert(tc <= TC_MASKBITS);
1058 switch (tc) {
1059 case TC_HASHTABLE: {
1060 scm_hashtable_t ht = (scm_hashtable_t)obj;
1061 ht->lock.destroy();
1062 break;
1063 }
1064 case TC_WEAKHASHTABLE: {
1065 scm_weakhashtable_t ht = (scm_weakhashtable_t)obj;
1066 ht->lock.destroy();
1067 break;
1068 }
1069 case TC_PORT: {
1070 scm_port_t port = (scm_port_t)obj;
1071 {
1072 scoped_lock lock(port->lock);
1073 if (port->type != SCM_PORT_TYPE_CUSTOM) port_close(port);
1074 }
1075 port->lock.destroy();
1076 break;
1077 }
1078 case TC_SOCKET: {
1079 scm_socket_t socket = (scm_socket_t)obj;
1080 {
1081 scoped_lock lock(socket->lock);
1082 socket_close(socket);
1083 }
1084 socket->lock.destroy();
1085 break;
1086 }
1087 case TC_SHAREDQUEUE: {
1088 scm_sharedqueue_t queue = (scm_sharedqueue_t)obj;
1089 queue->buf.destroy();
1090 queue->queue.destroy();
1091 break;
1092 }
1093 case TC_SHAREDBAG: {
1094 scm_sharedbag_t bag = (scm_sharedbag_t)obj;
1095 for (int i = 0; i < bag->capacity; i++) {
1096 bag->datum[i]->buf.destroy();
1097 bag->datum[i]->queue.destroy();
1098 free(bag->datum[i]->key);
1099 free(bag->datum[i]);
1100 }
1101 free(bag->datum);
1102 bag->lock.destroy();
1103 break;
1104 }
1105 }
1106 }
1107