@@ -111,7 +111,7 @@ REBVAL *N_watch(REBFRM *frame, REBVAL **inter_block)
111
111
#endif
112
112
113
113
static void Mark_Series (REBSER * series , REBCNT depth );
114
-
114
+ static void Mark_Value ( REBVAL * val , REBCNT depth );
115
115
116
116
/***********************************************************************
117
117
**
@@ -149,6 +149,69 @@ static void Mark_Series(REBSER *series, REBCNT depth);
149
149
}
150
150
}
151
151
152
+ /***********************************************************************
153
+ **
154
+ */ static void Mark_Struct_Field (REBSTU * stu , struct Struct_Field * field , REBCNT depth )
155
+ /*
156
+ ***********************************************************************/
157
+ {
158
+ if (field -> type == STRUCT_TYPE_STRUCT ) {
159
+ int len = 0 ;
160
+ REBSER * series = NULL ;
161
+
162
+ CHECK_MARK (field -> fields , depth );
163
+ CHECK_MARK (field -> spec , depth );
164
+
165
+ series = field -> fields ;
166
+ for (len = 0 ; len < series -> tail ; len ++ ) {
167
+ Mark_Struct_Field (stu , (struct Struct_Field * )SERIES_SKIP (series , len ), depth + 1 );
168
+ }
169
+ }
170
+ else if (field -> type == STRUCT_TYPE_REBVAL ) {
171
+ REBCNT i ;
172
+ ASSERT2 (field -> size == sizeof (REBVAL ), RP_BAD_SIZE );
173
+ for (i = 0 ; i < field -> dimension ; i ++ ) {
174
+ REBVAL * data = (REBVAL * )SERIES_SKIP (STRUCT_DATA_BIN (stu ),
175
+ STRUCT_OFFSET (stu ) + field -> offset + i * field -> size );
176
+ if (field -> done ) {
177
+ Mark_Value (data , depth );
178
+ }
179
+ }
180
+ }
181
+
182
+ /* ignore primitive datatypes */
183
+ }
184
+
185
+ /***********************************************************************
186
+ **
187
+ */ static void Mark_Struct (REBSTU * stu , REBCNT depth )
188
+ /*
189
+ ***********************************************************************/
190
+ {
191
+ int len = 0 ;
192
+ REBSER * series = NULL ;
193
+ if (IS_MARK_SERIES (STRUCT_DATA_BIN (stu ))) return ;
194
+
195
+ CHECK_MARK (stu -> spec , depth );
196
+ CHECK_MARK (stu -> fields , depth );
197
+ CHECK_MARK (STRUCT_DATA_BIN (stu ), depth );
198
+
199
+ Debug_Num ("mark spec: " , (int )stu -> spec );
200
+ Debug_Num ("mark fields:" , (int )stu -> fields );
201
+ Debug_Num ("mark bin: " , (int )STRUCT_DATA_BIN (stu ));
202
+
203
+ ASSERT2 (IS_BARE_SERIES (stu -> data ), RP_BAD_SERIES );
204
+ ASSERT2 (!IS_EXT_SERIES (stu -> data ), RP_BAD_SERIES );
205
+ ASSERT2 (SERIES_TAIL (stu -> data ) == 1 , RP_BAD_SERIES );
206
+ CHECK_MARK (stu -> data , depth );
207
+
208
+ series = stu -> fields ;
209
+ for (len = 0 ; len < series -> tail ; len ++ ) {
210
+ struct Struct_Field * field = (struct Struct_Field * )SERIES_SKIP (series , len );
211
+ Mark_Struct_Field (stu , field , depth + 1 );
212
+ }
213
+ }
214
+
152
215
153
216
/***********************************************************************
154
217
**
@@ -426,9 +489,7 @@ static void Mark_Series(REBSER *series, REBCNT depth);
426
489
break ;
427
490
428
491
case REB_STRUCT :
429
- CHECK_MARK (VAL_STRUCT_SPEC (val ), depth ); // is a block
430
- CHECK_MARK (VAL_STRUCT_VALS (val ), depth ); // " "
431
- MARK_SERIES (VAL_STRUCT_DATA (val ));
492
+ Mark_Struct (& VAL_STRUCT (val ), depth );
432
493
break ;
433
494
434
495
case REB_GOB :
0 commit comments