@@ -27,7 +27,7 @@ typedef void (*each_backtrace_func)(mrb_state*, const struct backtrace_location*
2727
2828static const mrb_data_type bt_type = { "Backtrace" , mrb_free };
2929
30- static mrb_value mrb_unpack_backtrace (mrb_state * mrb , mrb_value backtrace );
30+ struct RObject * mrb_unpack_backtrace (mrb_state * mrb , struct RObject * backtrace );
3131
3232static void
3333each_backtrace (mrb_state * mrb , ptrdiff_t ciidx , each_backtrace_func func , void * data )
@@ -97,17 +97,17 @@ each_backtrace(mrb_state *mrb, ptrdiff_t ciidx, each_backtrace_func func, void *
9797#ifndef MRB_NO_STDIO
9898
9999static void
100- print_backtrace (mrb_state * mrb , struct RObject * exc , mrb_value backtrace )
100+ print_backtrace (mrb_state * mrb , struct RObject * exc , struct RArray * backtrace )
101101{
102102 mrb_int i ;
103- mrb_int n = RARRAY_LEN (backtrace );
103+ mrb_int n = ARY_LEN (backtrace );
104104 mrb_value * loc , mesg ;
105105
106106 if (n != 0 ) {
107107 if (n > 1 ) {
108108 fprintf (stderr , "trace (most recent call last):\n" );
109109 }
110- for (i = n - 1 ,loc = & RARRAY_PTR (backtrace )[i ]; i > 0 ; i -- ,loc -- ) {
110+ for (i = n - 1 ,loc = & ARY_PTR (backtrace )[i ]; i > 0 ; i -- ,loc -- ) {
111111 if (mrb_string_p (* loc )) {
112112 fprintf (stderr , "\t[%d] %.*s\n" ,
113113 (int )i , (int )RSTRING_LEN (* loc ), RSTRING_PTR (* loc ));
@@ -130,16 +130,14 @@ print_backtrace(mrb_state *mrb, struct RObject *exc, mrb_value backtrace)
130130MRB_API void
131131mrb_print_backtrace (mrb_state * mrb )
132132{
133- mrb_value backtrace ;
134-
135133 if (!mrb -> exc ) {
136134 return ;
137135 }
138136
139- backtrace = mrb_obj_iv_get ( mrb , mrb -> exc , MRB_SYM ( backtrace )) ;
140- if (mrb_nil_p ( backtrace ) ) return ;
141- if (! mrb_array_p ( backtrace ) ) backtrace = mrb_unpack_backtrace (mrb , backtrace );
142- print_backtrace (mrb , mrb -> exc , backtrace );
137+ struct RObject * backtrace = (( struct RException * ) mrb -> exc ) -> backtrace ;
138+ if (! backtrace ) return ;
139+ if (backtrace -> tt != MRB_TT_ARRAY ) backtrace = mrb_unpack_backtrace (mrb , backtrace );
140+ print_backtrace (mrb , mrb -> exc , ( struct RArray * ) backtrace );
143141}
144142#else
145143
@@ -172,7 +170,7 @@ pack_backtrace_i(mrb_state *mrb,
172170 * pptr = ptr + 1 ;
173171}
174172
175- static mrb_value
173+ static struct RObject *
176174packed_backtrace (mrb_state * mrb )
177175{
178176 struct RData * backtrace ;
@@ -183,44 +181,51 @@ packed_backtrace(mrb_state *mrb)
183181
184182 each_backtrace (mrb , ciidx , count_backtrace_i , & len );
185183 size = len * sizeof (struct backtrace_location );
184+ backtrace = mrb_data_object_alloc (mrb , NULL , NULL , & bt_type );
186185 ptr = mrb_malloc (mrb , size );
187- backtrace = mrb_data_object_alloc ( mrb , NULL , ptr , & bt_type ) ;
186+ backtrace -> data = ptr ;
188187 backtrace -> flags = (uint32_t )len ;
189188 each_backtrace (mrb , ciidx , pack_backtrace_i , & ptr );
190- return mrb_obj_value (backtrace );
189+ return (struct RObject * )backtrace ;
190+ }
191+
192+ static void
193+ store_backtrace (mrb_state * mrb , mrb_value exc , struct RObject * backtrace )
194+ {
195+ struct RException * e = mrb_exc_ptr (exc );
196+ e -> backtrace = backtrace ;
197+ mrb_field_write_barrier (mrb , (struct RBasic * )e , (struct RBasic * )backtrace );
191198}
192199
193200void
194201mrb_keep_backtrace (mrb_state * mrb , mrb_value exc )
195202{
196- mrb_sym sym = MRB_SYM (backtrace );
197- mrb_value backtrace ;
198203 int ai ;
199204
200- if (mrb_iv_defined ( mrb , exc , sym ) ) return ;
205+ if (mrb_exc_ptr ( exc ) -> backtrace ) return ;
201206 ai = mrb_gc_arena_save (mrb );
202- backtrace = packed_backtrace (mrb );
203- mrb_iv_set (mrb , exc , sym , backtrace );
207+ struct RObject * backtrace = packed_backtrace (mrb );
208+ store_backtrace (mrb , exc , backtrace );
204209 mrb_gc_arena_restore (mrb , ai );
205210}
206211
207- static mrb_value
208- mrb_unpack_backtrace (mrb_state * mrb , mrb_value backtrace )
212+ struct RObject *
213+ mrb_unpack_backtrace (mrb_state * mrb , struct RObject * backtrace )
209214{
210215 const struct backtrace_location * bt ;
211216 mrb_int n , i ;
212217 int ai ;
213218
214- if (mrb_nil_p ( backtrace ) ) {
219+ if (backtrace == NULL ) {
215220 empty_backtrace :
216- return mrb_ary_new_capa (mrb , 0 );
221+ return mrb_obj_ptr ( mrb_ary_new_capa (mrb , 0 ) );
217222 }
218- if (mrb_array_p ( backtrace ) ) return backtrace ;
219- bt = (struct backtrace_location * )mrb_data_check_get_ptr (mrb , backtrace , & bt_type );
223+ if (backtrace -> tt == MRB_TT_ARRAY ) return backtrace ;
224+ bt = (struct backtrace_location * )mrb_data_check_get_ptr (mrb , mrb_obj_value ( backtrace ) , & bt_type );
220225 if (bt == NULL ) goto empty_backtrace ;
221- n = (mrb_int )RDATA ( backtrace ) -> flags ;
226+ n = (mrb_int )backtrace -> flags ;
222227 if (n == 0 ) goto empty_backtrace ;
223- backtrace = mrb_ary_new_capa (mrb , n );
228+ backtrace = mrb_obj_ptr ( mrb_ary_new_capa (mrb , n ) );
224229 ai = mrb_gc_arena_save (mrb );
225230 for (i = 0 ; i < n ; i ++ ) {
226231 const struct backtrace_location * entry = & bt [i ];
@@ -236,7 +241,7 @@ mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace)
236241 mrb_str_cat_lit (mrb , btline , ":in " );
237242 mrb_str_cat_cstr (mrb , btline , mrb_sym_name (mrb , entry -> method_id ));
238243 }
239- mrb_ary_push (mrb , backtrace , btline );
244+ mrb_ary_push (mrb , mrb_obj_value ( backtrace ) , btline );
240245 mrb_gc_arena_restore (mrb , ai );
241246 }
242247
@@ -246,20 +251,21 @@ mrb_unpack_backtrace(mrb_state *mrb, mrb_value backtrace)
246251mrb_value
247252mrb_exc_backtrace (mrb_state * mrb , mrb_value exc )
248253{
249- mrb_value backtrace ;
250-
251- backtrace = mrb_iv_get (mrb , exc , MRB_SYM (backtrace ));
252- if (mrb_nil_p (backtrace ) || mrb_array_p (backtrace )) {
253- return backtrace ;
254+ struct RObject * backtrace = mrb_exc_ptr (exc )-> backtrace ;
255+ if (backtrace == NULL ) {
256+ return mrb_nil_value ();
257+ }
258+ if (backtrace -> tt == MRB_TT_ARRAY ) {
259+ return mrb_obj_value (backtrace );
254260 }
255261 /* unpack packed-backtrace */
256262 backtrace = mrb_unpack_backtrace (mrb , backtrace );
257- mrb_iv_set (mrb , exc , MRB_SYM ( backtrace ) , backtrace );
258- return backtrace ;
263+ store_backtrace (mrb , exc , backtrace );
264+ return mrb_obj_value ( backtrace ) ;
259265}
260266
261267mrb_value
262268mrb_get_backtrace (mrb_state * mrb )
263269{
264- return mrb_unpack_backtrace (mrb , packed_backtrace (mrb ));
270+ return mrb_obj_value ( mrb_unpack_backtrace (mrb , packed_backtrace (mrb ) ));
265271}
0 commit comments