@@ -126,61 +126,60 @@ bool interface_is(n_interface_t *mu, int64_t target_rtype_hash) {
126126}
127127
128128/**
129- * union 参考 env 中的 upvalue 处理超过 8byte 的数据
129+ * interface 参考 any 处理 storage_ind 类型
130+ * @param out
130131 * @param input_rtype_hash
131- * @param value
132- * @return
132+ * @param value_ref
133+ * @param method_count
134+ * @param methods
133135 */
134- n_interface_t * interface_casting (uint64_t input_rtype_hash , void * value_ref , int64_t method_count , int64_t * methods ) {
136+ void interface_casting (n_interface_t * out , uint64_t input_rtype_hash , void * value_ref , int64_t method_count , int64_t * methods ) {
137+ assert (out && "interface_casting out is null" );
135138 // - 根据 input_rtype_hash 找到对应的
136139 rtype_t * rtype = rt_find_rtype (input_rtype_hash );
137140 assert (rtype && "cannot find rtype by hash" );
138141
139142 ASSERT_ADDR (value_ref );
140143
141- TRACEF ("[union_casting] input_kind=%s" , type_kind_str [rtype -> kind ]);
142-
143-
144- rtype_t interface_rtype = GC_RTYPE (TYPE_INTERFACE , 4 , TYPE_GC_SCAN , TYPE_GC_SCAN , TYPE_GC_NOSCAN , TYPE_GC_NOSCAN );
145-
146- // any_t 在 element_rtype list 中是可以预注册的,因为其 gc_bits 不会变来变去的,都是恒定不变的!
147- n_interface_t * mu = rti_gc_malloc (sizeof (n_interface_t ), & interface_rtype );
144+ TRACEF ("[interface_casting] input_kind=%s" , type_kind_str [rtype -> kind ]);
148145
149146 if (method_count > 0 ) {
150- mu -> method_count = method_count ;
151- mu -> methods = (int64_t * ) rti_array_new (& uint64_rtype , method_count );
147+ out -> method_count = method_count ;
148+ out -> methods = (int64_t * ) rti_array_new (& uint64_rtype , method_count );
152149 // 进行数据 copy TODO write barrier
153- memmove (mu -> methods , methods , method_count * POINTER_SIZE );
150+ memmove (out -> methods , methods , method_count * POINTER_SIZE );
151+ } else {
152+ out -> method_count = 0 ;
153+ out -> methods = NULL ;
154154 }
155155
156156 DEBUGF (
157157 "[interface_casting] union_base: %p, memmove value_ref(%p) -> any->value(%p), size=%lu, fetch_value_8byte=%p" ,
158- mu , value_ref ,
159- & mu -> value , rtype -> stack_size , (void * ) fetch_addr_value ((addr_t ) value_ref ));
158+ out , value_ref ,
159+ & out -> value , rtype -> storage_size , (void * ) fetch_addr_value ((addr_t ) value_ref ));
160160
161- mu -> rtype = rtype ;
161+ out -> rtype = rtype ;
162162 uint64_t stack_size = rtype -> storage_size ;
163+ out -> value .i64_value = 0 ;
163164
164165 if (rtype -> storage_kind != STORAGE_KIND_PTR ) {
165166 // TODO number 可以直接存储在 value 中
166167 // union 进行了数据的额外缓存,并进行值 copy,不需要担心 arr/struct 这样的大数据的丢失问题
167168 void * new_value = rti_gc_malloc (rtype -> gc_heap_size , rtype );
168169 memmove (new_value , value_ref , stack_size );
169- rti_write_barrier_ptr ( & mu -> value .ptr_value , new_value , false) ;
170+ out -> value .ptr_value = new_value ;
170171 } else {
171172 // 特殊类型参数处理,为了兼容 fn method 中的 self 自动化参数, self 如果是 int/struct 等类型,会自动转换为 ref<int>
172173 // 如果是 vec/string 等类型,self 的类型依旧是 vec/string 等,而不是 ref<vec>/ref<string> 这有点多余, 因为 vec/string
173174 // 本来就是在堆中分配的, 传递的是一个指针, 虽然后续可以能会进行统一处理,但是目前还是需要进行特殊处理,value 中直接存放可以作为
174175 // fn method 传递的参数
175- memmove (& mu -> value , value_ref , stack_size );
176+ memmove (& out -> value , value_ref , stack_size );
176177 }
177178
178179 DEBUGF ("[interface_casting] success, union_base: %p, union_rtype: %p, union_i64_value: %ld, union_ptr_value: %p" ,
179- mu ,
180- mu -> rtype ,
181- mu -> value .i64_value , mu -> value .ptr_value );
182-
183- return mu ;
180+ out ,
181+ out -> rtype ,
182+ out -> value .i64_value , out -> value .ptr_value );
184183}
185184
186185/**
@@ -488,7 +487,7 @@ void co_throw_error(n_interface_t *error, char *path, char *fn_name, n_int_t lin
488487 };
489488 rt_vec_push (& co -> traces , errort_trace_rtype .hash , & trace );
490489
491- rti_write_barrier_ptr (& co -> error , error , false );
490+ rti_write_barrier_rtype (& co -> error , error , & throwable_rtype );
492491 co -> has_error = true;
493492}
494493
@@ -504,10 +503,10 @@ void throw_index_out_error(n_int_t *index, n_int_t *len, n_bool_t be_catch) {
504503 char * msg = tlsprintf ("index out of range [%d] with length %d" , index , len );
505504
506505 if (be_catch ) {
507- n_interface_t * error = n_error_new (string_new (msg , strlen (msg )), true);
508- assert (error -> method_count == 1 );
506+ n_interface_t error = n_error_new (string_new (msg , strlen (msg )), true);
507+ assert (error . method_count == 1 );
509508
510- DEBUGF ("[runtime.co_throw_error_msg] co=%p, error=%p, msg=%s" , co , (void * ) error , (char * ) msg );
509+ DEBUGF ("[runtime.co_throw_error_msg] co=%p, error=%p, msg=%s" , co , (void * ) & error , (char * ) msg );
511510
512511 assert (co -> traces .data == NULL );
513512
@@ -522,7 +521,7 @@ void throw_index_out_error(n_int_t *index, n_int_t *len, n_bool_t be_catch) {
522521 .column = caller -> column ,
523522 };
524523 rt_vec_push (& co -> traces , errort_trace_rtype .hash , & trace );
525- rti_write_barrier_ptr (& co -> error , error , false );
524+ rti_write_barrier_rtype (& co -> error , & error , & throwable_rtype );
526525 co -> has_error = true;
527526 } else {
528527 char * copy_msg = strdup (msg );
@@ -531,15 +530,16 @@ void throw_index_out_error(n_int_t *index, n_int_t *len, n_bool_t be_catch) {
531530 }
532531}
533532
534- n_interface_t * co_remove_error () {
533+ n_interface_t co_remove_error () {
535534 coroutine_t * co = coroutine_get ();
536535
537- assert (co -> error );
536+ assert (co -> has_error );
538537 co -> has_error = false;
539538
540- n_interface_t * error = co -> error ;
539+ n_interface_t error = co -> error ;
541540
542- rti_write_barrier_ptr (& co -> error , NULL , false);
541+ n_interface_t empty = {0 };
542+ rti_write_barrier_rtype (& co -> error , & empty , & throwable_rtype );
543543 co -> traces = (n_vec_t ){0 };
544544 return error ;
545545}
@@ -569,11 +569,11 @@ uint8_t co_has_panic(bool be_catch, char *path, char *fn_name, n_int_t line, n_i
569569 return 1 ;
570570 }
571571
572- assert (co -> error );
572+ assert (co -> has_error );
573573
574574 // 在 runtime 调用 nature 代码, rti_error_msg 会让 gc scan_stack 异常,不过马上就要退出了,问题不大
575575 // 可以考虑增加 safepoint_lock, 避免进入 safepoint 状态
576- n_string_t msg = rti_error_msg (co -> error );
576+ n_string_t msg = rti_error_msg (& co -> error );
577577
578578 char * dump_msg ;
579579 if (co -> main ) {
0 commit comments