@@ -81,20 +81,46 @@ void union_assert(n_union_t *mu, int64_t target_rtype_hash, void *value_ref) {
8181
8282 rtype_t * rtype = rt_find_rtype (target_rtype_hash );
8383 if (rtype -> storage_kind == STORAGE_KIND_IND ) {
84- memmove (value_ref , mu -> value .ptr_value , rtype -> storage_size );
84+ memmove (value_ref , & mu -> value .struct_ , rtype -> storage_size );
8585 } else {
8686 memmove (value_ref , & mu -> value , rtype -> storage_size );
8787 }
8888 DEBUGF (
8989 "[union_assert] success, union_base: %p, union_rtype_kind: %s, heap_out_size: %lu, union_i64_value: %ld, "
9090 "values_ref: %p" ,
91- mu , type_kind_str [mu -> rtype -> kind ], size , mu -> value .i64_value , value_ref );
91+ mu , type_kind_str [mu -> rtype -> kind ], rtype -> storage_size , mu -> value .i64_value , value_ref );
92+ }
93+
94+ void any_assert (n_any_t * mu , int64_t target_rtype_hash , void * value_ref ) {
95+ if (mu -> rtype -> hash != target_rtype_hash ) {
96+ DEBUGF ("[any_assert] type assert failed, mu->rtype->kind: %s, target_rtype_hash: %ld" ,
97+ type_kind_str [mu -> rtype -> kind ],
98+ target_rtype_hash );
99+
100+ rti_throw ("type assert failed" , true);
101+ return ;
102+ }
103+
104+ rtype_t * rtype = rt_find_rtype (target_rtype_hash );
105+ if (rtype -> storage_kind == STORAGE_KIND_IND ) {
106+ memmove (value_ref , mu -> value .ptr_value , rtype -> storage_size );
107+ } else {
108+ memmove (value_ref , & mu -> value , rtype -> storage_size );
109+ }
110+ DEBUGF (
111+ "[any_assert] success, any_base: %p, any_rtype_kind: %s, heap_out_size: %lu, any_i64_value: %ld, "
112+ "values_ref: %p" ,
113+ mu , type_kind_str [mu -> rtype -> kind ], rtype -> storage_size , mu -> value .i64_value , value_ref );
92114}
93115
94116bool union_is (n_union_t * mu , int64_t target_rtype_hash ) {
95117 return mu -> rtype -> hash == target_rtype_hash ;
96118}
97119
120+ bool any_is (n_any_t * mu , int64_t target_rtype_hash ) {
121+ return mu -> rtype -> hash == target_rtype_hash ;
122+ }
123+
98124bool interface_is (n_interface_t * mu , int64_t target_rtype_hash ) {
99125 return mu -> rtype -> hash == target_rtype_hash ;
100126}
@@ -163,7 +189,8 @@ n_interface_t *interface_casting(uint64_t input_rtype_hash, void *value_ref, int
163189 * @param value
164190 * @return
165191 */
166- n_union_t union_casting (int64_t input_rtype_hash , void * value_ref ) {
192+ void union_casting (n_union_t * out , int64_t input_rtype_hash , void * value_ref ) {
193+ assert (out && "union_casting out is null" );
167194 // - 根据 input_rtype_hash 找到对应的
168195 rtype_t * rtype = rt_find_rtype (input_rtype_hash );
169196 assert (rtype && "cannot find rtype by hash" );
@@ -172,41 +199,92 @@ n_union_t union_casting(int64_t input_rtype_hash, void *value_ref) {
172199
173200 TRACEF ("[union_casting] input_kind=%s" , type_kind_str [rtype -> kind ]);
174201
202+ DEBUGF ("[union_casting] union_base: %p, memmove value_ref(%p) -> any->value(%p), size=%lu, fetch_value_8byte=%p" ,
203+ out , value_ref ,
204+ & out -> value , rtype -> storage_size , (void * ) fetch_addr_value ((addr_t ) value_ref ));
205+ out -> rtype = rtype ;
206+
207+ uint64_t storage_size = rtype -> storage_size ;
208+ out -> value .i64_value = 0 ;
209+
210+ if (rtype -> storage_kind == STORAGE_KIND_IND ) {
211+ memmove (& out -> value .struct_ , value_ref , storage_size );
212+ } else {
213+ memmove (& out -> value , value_ref , storage_size );
214+ }
175215
176- n_union_t mu = {0 };
177216
178- DEBUGF ("[union_casting] union_base: %p, memmove value_ref(%p) -> any->value(%p), size=%lu, fetch_value_8byte=%p" ,
179- & mu , value_ref ,
180- & mu .value , rtype -> storage_size , (void * ) fetch_addr_value ((addr_t ) value_ref ));
181- mu .rtype = rtype ;
217+ DEBUGF ("[union_casting] success, union_base: %p, union_rtype: %p, union_i64_value: %ld" , out , out -> rtype ,
218+ out -> value .i64_value );
219+ }
220+
221+ /**
222+ * any 参考旧版 union 处理 storage_ind 类型
223+ * @param input_rtype_hash
224+ * @param value_ref
225+ * @return
226+ */
227+ void any_casting (n_any_t * out , int64_t input_rtype_hash , void * value_ref ) {
228+ assert (out && "any_casting out is null" );
229+ // - 根据 input_rtype_hash 找到对应的
230+ rtype_t * rtype = rt_find_rtype (input_rtype_hash );
231+ assert (rtype && "cannot find rtype by hash" );
232+
233+ ASSERT_ADDR (value_ref );
234+
235+ TRACEF ("[any_casting] input_kind=%s" , type_kind_str [rtype -> kind ]);
236+
237+ DEBUGF ("[any_casting] any_base: %p, memmove value_ref(%p) -> any->value(%p), size=%lu, fetch_value_8byte=%p" ,
238+ out , value_ref ,
239+ & out -> value , rtype -> storage_size , (void * ) fetch_addr_value ((addr_t ) value_ref ));
240+ out -> rtype = rtype ;
182241
183242 uint64_t storage_size = rtype -> storage_size ;
243+ out -> value .i64_value = 0 ;
184244
185- // TODO union 产生了 GC? 这个问题稍后再解决。甚至现在总是会产生 GC。
186- // 甚至 return union 类型变得寸步难行。
187245 if (rtype -> storage_kind == STORAGE_KIND_IND ) {
188- // union 进行了数据的额外缓存,并进行值 copy,不需要担心 arr/struct 这样的大数据的丢失问题
189246 void * new_value = rti_gc_malloc (rtype -> gc_heap_size , rtype );
190247 memmove (new_value , value_ref , storage_size );
191- mu . value .ptr_value = new_value ;
248+ out -> value .ptr_value = new_value ;
192249 } else {
193- memmove (& mu . value , value_ref , storage_size );
250+ memmove (& out -> value , value_ref , storage_size );
194251 }
195252
253+ DEBUGF ("[any_casting] success, any_base: %p, any_rtype: %p, any_i64_value: %ld" , out , out -> rtype ,
254+ out -> value .i64_value );
255+ }
196256
197- DEBUGF ("[union_casting] success, union_base: %p, union_rtype: %p, union_i64_value: %ld" , & mu , mu .rtype ,
198- mu .value .i64_value );
257+ /**
258+ * union -> any: 提取 union 的 rtype 和 value 传递给 any_casting
259+ */
260+ void union_to_any (n_any_t * out , n_union_t * input ) {
261+ assert (out && "union_to_any out is null" );
262+ assert (input && "union_to_any input is null" );
263+ assert (input -> rtype && "union_to_any input rtype is null" );
199264
200- return mu ;
265+ rtype_t * rtype = input -> rtype ;
266+
267+ DEBUGF ("[union_to_any] input rtype kind=%s, hash=%ld" , type_kind_str [rtype -> kind ], rtype -> hash );
268+
269+ // union value 根据 storage_kind 确定 value_ref
270+ void * value_ref ;
271+ if (rtype -> storage_kind == STORAGE_KIND_IND ) {
272+ value_ref = & input -> value .struct_ ;
273+ } else {
274+ value_ref = & input -> value ;
275+ }
276+
277+ any_casting (out , rtype -> hash , value_ref );
201278}
202279
203- n_tagged_union_t tagged_union_casting (int64_t tag_hash , int64_t value_rtype_hash , void * value_ref ) {
280+ void tagged_union_casting (n_tagged_union_t * out , int64_t tag_hash , int64_t value_rtype_hash , void * value_ref ) {
281+ assert (out && "tagged_union_casting out is null" );
204282 DEBUGF ("[tagged_union_casting] tag_hash=%ld, value_hash=%ld" , tag_hash , value_rtype_hash );
205283
206- n_tagged_union_t mu = { 0 } ;
207- mu . tag_hash = tag_hash ;
284+ out -> tag_hash = tag_hash ;
285+ out -> value . i64_value = 0 ;
208286 if (value_rtype_hash == 0 ) {
209- return mu ;
287+ return ;
210288 }
211289
212290 // - 根据 input_rtype_hash 找到对应的
@@ -217,24 +295,18 @@ n_tagged_union_t tagged_union_casting(int64_t tag_hash, int64_t value_rtype_hash
217295
218296 DEBUGF (
219297 "[tagged_union_casting] union_base: %p, memmove value_ref(%p) -> any->value(%p), kind=%s, size=%lu, fetch_value_8byte=%p" ,
220- & mu , value_ref ,
221- & mu . value , type_kind_str [rtype -> kind ], rtype -> storage_size , (void * ) fetch_addr_value ((addr_t ) value_ref ));
298+ out , value_ref ,
299+ & out -> value , type_kind_str [rtype -> kind ], rtype -> storage_size , (void * ) fetch_addr_value ((addr_t ) value_ref ));
222300
223301 uint64_t storage_size = rtype -> storage_size ;
224302 if (rtype -> storage_kind == STORAGE_KIND_IND ) {
225- // union 进行了数据的额外缓存,并进行值 copy,不需要担心 arr/struct 这样的大数据的丢失问题
226- void * new_value = rti_gc_malloc (rtype -> gc_heap_size , rtype );
227- memmove (new_value , value_ref , storage_size );
228-
229- mu .value .ptr_value = new_value ;
303+ memmove (& out -> value .struct_ , value_ref , storage_size );
230304 } else {
231- memmove (& mu . value , value_ref , storage_size );
305+ memmove (& out -> value , value_ref , storage_size );
232306 }
233307
234- DEBUGF ("[tagged_union_casting] success, base: %p, id: %ld, union_i64_value: %ld" , & mu , mu .tag_hash ,
235- mu .value .i64_value );
236-
237- return mu ;
308+ DEBUGF ("[tagged_union_casting] success, base: %p, id: %ld, union_i64_value: %ld" , out , out -> tag_hash ,
309+ out -> value .i64_value );
238310}
239311
240312
@@ -400,9 +472,9 @@ void co_throw_error(n_interface_t *error, char *path, char *fn_name, n_int_t lin
400472
401473 n_string_t err_msg = rti_error_msg (error );
402474 DEBUGF ("[runtime.co_throw_error] co=%p, error=%p, path=%s, fn_name=%s, line=%ld, column=%ld, msg=%s" , co ,
403- (void * ) error , path , fn_name ,
404- line ,
405- column , (char * ) rt_string_ref (& err_msg ));
475+ (void * ) error , path , fn_name ,
476+ line ,
477+ column , (char * ) rt_string_ref (& err_msg ));
406478
407479 assert (co -> traces .data == NULL );
408480 n_vec_t traces = rti_vec_new (& errort_trace_rtype , 0 , 0 );
0 commit comments