@@ -1170,17 +1170,17 @@ rb_make_backtrace(void)
1170
1170
return rb_ec_backtrace_str_ary (GET_EC (), BACKTRACE_START , ALL_BACKTRACE_LINES );
1171
1171
}
1172
1172
1173
- static VALUE
1174
- ec_backtrace_to_ary (const rb_execution_context_t * ec , int argc , const VALUE * argv , int lev_default , int lev_plus , int to_str )
1173
+ static long
1174
+ ec_backtrace_range (const rb_execution_context_t * ec , int argc , const VALUE * argv , int lev_default , int lev_plus , long * len_ptr )
1175
1175
{
1176
- VALUE level , vn ;
1176
+ VALUE level , vn , opts ;
1177
1177
long lev , n ;
1178
- VALUE btval ;
1179
- VALUE r ;
1180
- int too_large ;
1181
1178
1182
- rb_scan_args (argc , argv , "02" , & level , & vn );
1179
+ rb_scan_args (argc , argv , "02: " , & level , & vn , & opts );
1183
1180
1181
+ if (!NIL_P (opts )) {
1182
+ rb_get_kwargs (opts , (ID []){0 }, 0 , 0 , NULL );
1183
+ }
1184
1184
if (argc == 2 && NIL_P (vn )) argc -- ;
1185
1185
1186
1186
switch (argc ) {
@@ -1201,7 +1201,7 @@ ec_backtrace_to_ary(const rb_execution_context_t *ec, int argc, const VALUE *arg
1201
1201
n = ALL_BACKTRACE_LINES ;
1202
1202
break ;
1203
1203
case Qnil :
1204
- return Qnil ;
1204
+ return -1 ;
1205
1205
default :
1206
1206
lev = beg + lev_plus ;
1207
1207
n = len ;
@@ -1225,6 +1225,20 @@ ec_backtrace_to_ary(const rb_execution_context_t *ec, int argc, const VALUE *arg
1225
1225
break ;
1226
1226
}
1227
1227
1228
+ * len_ptr = n ;
1229
+ return lev ;
1230
+ }
1231
+
1232
+ static VALUE
1233
+ ec_backtrace_to_ary (const rb_execution_context_t * ec , int argc , const VALUE * argv , int lev_default , int lev_plus , int to_str )
1234
+ {
1235
+ long lev , n ;
1236
+ VALUE btval , r ;
1237
+ int too_large ;
1238
+
1239
+ lev = ec_backtrace_range (ec , argc , argv , lev_default , lev_plus , & n );
1240
+ if (lev < 0 ) return Qnil ;
1241
+
1228
1242
if (n == 0 ) {
1229
1243
return rb_ary_new ();
1230
1244
}
@@ -1354,15 +1368,19 @@ rb_f_caller_locations(int argc, VALUE *argv, VALUE _)
1354
1368
1355
1369
/*
1356
1370
* call-seq:
1357
- * Thread.each_caller_location{ |loc| ... } -> nil
1371
+ * Thread.each_caller_location(...) { |loc| ... } -> nil
1358
1372
*
1359
1373
* Yields each frame of the current execution stack as a
1360
1374
* backtrace location object.
1361
1375
*/
1362
1376
static VALUE
1363
- each_caller_location (VALUE unused )
1377
+ each_caller_location (int argc , VALUE * argv , VALUE _ )
1364
1378
{
1365
- rb_ec_partial_backtrace_object (GET_EC (), 2 , ALL_BACKTRACE_LINES , NULL , FALSE, TRUE);
1379
+ rb_execution_context_t * ec = GET_EC ();
1380
+ long n , lev = ec_backtrace_range (ec , argc , argv , 1 , 1 , & n );
1381
+ if (lev >= 0 && n != 0 ) {
1382
+ rb_ec_partial_backtrace_object (ec , lev , n , NULL , FALSE, TRUE);
1383
+ }
1366
1384
return Qnil ;
1367
1385
}
1368
1386
@@ -1442,7 +1460,7 @@ Init_vm_backtrace(void)
1442
1460
rb_define_global_function ("caller" , rb_f_caller , -1 );
1443
1461
rb_define_global_function ("caller_locations" , rb_f_caller_locations , -1 );
1444
1462
1445
- rb_define_singleton_method (rb_cThread , "each_caller_location" , each_caller_location , 0 );
1463
+ rb_define_singleton_method (rb_cThread , "each_caller_location" , each_caller_location , -1 );
1446
1464
}
1447
1465
1448
1466
/* debugger API */
0 commit comments