duplicate and cycle detection for places_deserialize_worker
This commit is contained in:
parent
79778e0a1e
commit
c9c02f3fb0
|
@ -236,7 +236,8 @@
|
||||||
(test-long (lambda (x) 3) "Listof ints")
|
(test-long (lambda (x) 3) "Listof ints")
|
||||||
(test-long (lambda (x) #(1 2)) "Listof vectors")
|
(test-long (lambda (x) #(1 2)) "Listof vectors")
|
||||||
(test-long (lambda (x) (intern-num-sym (modulo x 1000))) "Listof symbols")
|
(test-long (lambda (x) (intern-num-sym (modulo x 1000))) "Listof symbols")
|
||||||
(test-long (lambda (x) #s(clown "Binky" "pie")) "Listof prefabs"))
|
(test-long (lambda (x) #s(clown "Binky" "pie")) "Listof prefabs")
|
||||||
|
(test-long (lambda (x) (read (open-input-string "#0=(#0# . #0#)"))) "Listof cycles"))
|
||||||
|
|
||||||
|
|
||||||
;(report-errs)
|
;(report-errs)
|
||||||
|
|
|
@ -1665,23 +1665,27 @@ Scheme_Object *scheme_places_deep_copy_to_master(Scheme_Object *so) {
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DO_STACK_CHECK
|
#ifdef DO_STACK_CHECK
|
||||||
static void places_deserialize_worker(Scheme_Object **pso);
|
static void places_deserialize_worker(Scheme_Object **pso, Scheme_Hash_Table **ht);
|
||||||
|
|
||||||
static Scheme_Object *places_deserialize_worker_k(void)
|
static Scheme_Object *places_deserialize_worker_k(void)
|
||||||
{
|
{
|
||||||
Scheme_Thread *p = scheme_current_thread;
|
Scheme_Thread *p = scheme_current_thread;
|
||||||
Scheme_Object *pso = (Scheme_Object **)p->ku.k.p1;
|
Scheme_Object *pso = (Scheme_Object *)p->ku.k.p1;
|
||||||
|
Scheme_Hash_Table*ht = (Scheme_Hash_Table *)p->ku.k.p2;
|
||||||
|
|
||||||
p->ku.k.p1 = NULL;
|
p->ku.k.p1 = NULL;
|
||||||
|
p->ku.k.p2 = NULL;
|
||||||
|
|
||||||
places_deserialize_worker(&pso);
|
places_deserialize_worker(&pso, &ht);
|
||||||
|
p = scheme_current_thread;
|
||||||
|
p->ku.k.p1 = ht;
|
||||||
|
|
||||||
return pso;
|
return pso;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
static void places_deserialize_worker(Scheme_Object **pso)
|
static void places_deserialize_worker(Scheme_Object **pso, Scheme_Hash_Table **ht)
|
||||||
{
|
{
|
||||||
Scheme_Object *so;
|
Scheme_Object *so;
|
||||||
Scheme_Object *tmp;
|
Scheme_Object *tmp;
|
||||||
|
@ -1695,10 +1699,15 @@ static void places_deserialize_worker(Scheme_Object **pso)
|
||||||
{
|
{
|
||||||
# include "mzstkchk.h"
|
# include "mzstkchk.h"
|
||||||
{
|
{
|
||||||
Scheme_Thread *p = scheme_current_thread;
|
Scheme_Thread *p;
|
||||||
|
p = scheme_current_thread;
|
||||||
p->ku.k.p1 = *pso;
|
p->ku.k.p1 = *pso;
|
||||||
|
p->ku.k.p2 = *ht;
|
||||||
tmp = scheme_handle_stack_overflow(places_deserialize_worker_k);
|
tmp = scheme_handle_stack_overflow(places_deserialize_worker_k);
|
||||||
*pso = tmp;
|
*pso = tmp;
|
||||||
|
p = scheme_current_thread;
|
||||||
|
*ht = p->ku.k.p1;
|
||||||
|
p->ku.k.p1 = NULL;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1736,35 +1745,69 @@ static void places_deserialize_worker(Scheme_Object **pso)
|
||||||
*pso = tmp;
|
*pso = tmp;
|
||||||
break;
|
break;
|
||||||
case scheme_pair_type:
|
case scheme_pair_type:
|
||||||
|
if (*ht) {
|
||||||
|
if ((st = (Scheme_Structure *) scheme_hash_get(*ht, so)))
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
scheme_hash_set(*ht, so, so);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tmp = (Scheme_Object *) scheme_make_hash_table(SCHEME_hash_ptr);
|
||||||
|
*ht = (Scheme_Hash_Table *) tmp;
|
||||||
|
scheme_hash_set(*ht, so, so);
|
||||||
|
}
|
||||||
tmp = SCHEME_CAR(so);
|
tmp = SCHEME_CAR(so);
|
||||||
places_deserialize_worker(&tmp);
|
places_deserialize_worker(&tmp, ht);
|
||||||
SCHEME_CAR(so) = tmp;
|
SCHEME_CAR(so) = tmp;
|
||||||
tmp = SCHEME_CDR(so);
|
tmp = SCHEME_CDR(so);
|
||||||
places_deserialize_worker(&tmp);
|
places_deserialize_worker(&tmp, ht);
|
||||||
SCHEME_CDR(so) = tmp;
|
SCHEME_CDR(so) = tmp;
|
||||||
break;
|
break;
|
||||||
case scheme_vector_type:
|
case scheme_vector_type:
|
||||||
|
if (*ht) {
|
||||||
|
if ((st = (Scheme_Structure *) scheme_hash_get(*ht, so)))
|
||||||
|
break;
|
||||||
|
else
|
||||||
|
scheme_hash_set(*ht, so, so);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tmp = (Scheme_Object *) scheme_make_hash_table(SCHEME_hash_ptr);
|
||||||
|
*ht = (Scheme_Hash_Table *) tmp;
|
||||||
|
scheme_hash_set(*ht, so, so);
|
||||||
|
}
|
||||||
size = SCHEME_VEC_SIZE(so);
|
size = SCHEME_VEC_SIZE(so);
|
||||||
for (i = 0; i <size ; i++) {
|
for (i = 0; i <size ; i++) {
|
||||||
tmp = SCHEME_VEC_ELS(so)[i];
|
tmp = SCHEME_VEC_ELS(so)[i];
|
||||||
places_deserialize_worker(&tmp);
|
places_deserialize_worker(&tmp, ht);
|
||||||
SCHEME_VEC_ELS(so)[i] = tmp;
|
SCHEME_VEC_ELS(so)[i] = tmp;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case scheme_structure_type:
|
case scheme_structure_type:
|
||||||
break;
|
break;
|
||||||
case scheme_serialized_structure_type:
|
case scheme_serialized_structure_type:
|
||||||
|
if (*ht) {
|
||||||
|
if ((st = (Scheme_Structure *) scheme_hash_get(*ht, so))) {
|
||||||
|
*pso = (Scheme_Object *) st;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
tmp = (Scheme_Object *) scheme_make_hash_table(SCHEME_hash_ptr);
|
||||||
|
*ht = (Scheme_Hash_Table *) tmp;
|
||||||
|
}
|
||||||
|
|
||||||
sst = (Scheme_Serialized_Structure*)so;
|
sst = (Scheme_Serialized_Structure*)so;
|
||||||
size = sst->num_slots;
|
size = sst->num_slots;
|
||||||
tmp = sst->prefab_key;
|
tmp = sst->prefab_key;
|
||||||
places_deserialize_worker(&tmp);
|
places_deserialize_worker(&tmp, ht);
|
||||||
sst->prefab_key = tmp;
|
sst->prefab_key = tmp;
|
||||||
stype = scheme_lookup_prefab_type(sst->prefab_key, size);
|
stype = scheme_lookup_prefab_type(sst->prefab_key, size);
|
||||||
st = (Scheme_Structure *) scheme_make_blank_prefab_struct_instance(stype);
|
st = (Scheme_Structure *) scheme_make_blank_prefab_struct_instance(stype);
|
||||||
|
scheme_hash_set(*ht, so, (Scheme_Object *) st);
|
||||||
|
|
||||||
for (i = 0; i <size ; i++) {
|
for (i = 0; i <size ; i++) {
|
||||||
tmp = sst->slots[i];
|
tmp = sst->slots[i];
|
||||||
places_deserialize_worker(&tmp);
|
places_deserialize_worker(&tmp, ht);
|
||||||
st->slots[i] = tmp;
|
st->slots[i] = tmp;
|
||||||
}
|
}
|
||||||
*pso = (Scheme_Object *) st;
|
*pso = (Scheme_Object *) st;
|
||||||
|
@ -1808,10 +1851,11 @@ Scheme_Object *scheme_places_deserialize(Scheme_Object *so, void *msg_memory) {
|
||||||
GC_dispose_short_message_allocator(msg_memory);
|
GC_dispose_short_message_allocator(msg_memory);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
Scheme_Object *ht = NULL;
|
||||||
GC_adopt_message_allocator(msg_memory);
|
GC_adopt_message_allocator(msg_memory);
|
||||||
#if !defined(SHARED_TABLES)
|
#if !defined(SHARED_TABLES)
|
||||||
new_so = so;
|
new_so = so;
|
||||||
places_deserialize_worker(&new_so);
|
places_deserialize_worker(&new_so, (Scheme_Hash_Table **) &ht);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return new_so;
|
return new_so;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user