@@ -796,6 +796,8 @@ impl std::fmt::Display for Insn {
796
796
/// An extended basic block in a [`Function`].
797
797
#[ derive( Default , Debug ) ]
798
798
pub struct Block {
799
+ /// The index of the first YARV instruction for the Block in the ISEQ
800
+ pub insn_idx : u32 ,
799
801
params : Vec < InsnId > ,
800
802
insns : Vec < InsnId > ,
801
803
}
@@ -1024,9 +1026,11 @@ impl Function {
1024
1026
}
1025
1027
}
1026
1028
1027
- fn new_block ( & mut self ) -> BlockId {
1029
+ fn new_block ( & mut self , insn_idx : u32 ) -> BlockId {
1028
1030
let id = BlockId ( self . blocks . len ( ) ) ;
1029
- self . blocks . push ( Block :: default ( ) ) ;
1031
+ let mut block = Block :: default ( ) ;
1032
+ block. insn_idx = insn_idx;
1033
+ self . blocks . push ( block) ;
1030
1034
id
1031
1035
}
1032
1036
@@ -2543,7 +2547,7 @@ pub fn iseq_to_hir(iseq: *const rb_iseq_t) -> Result<Function, ParseError> {
2543
2547
if insn_idx == 0 {
2544
2548
todo ! ( "Separate entry block for param/self/..." ) ;
2545
2549
}
2546
- insn_idx_to_block. insert ( insn_idx, fun. new_block ( ) ) ;
2550
+ insn_idx_to_block. insert ( insn_idx, fun. new_block ( insn_idx ) ) ;
2547
2551
}
2548
2552
2549
2553
// Iteratively fill out basic blocks using a queue
@@ -3243,7 +3247,7 @@ mod rpo_tests {
3243
3247
fn jump ( ) {
3244
3248
let mut function = Function :: new ( std:: ptr:: null ( ) ) ;
3245
3249
let entry = function. entry_block ;
3246
- let exit = function. new_block ( ) ;
3250
+ let exit = function. new_block ( 0 ) ;
3247
3251
function. push_insn ( entry, Insn :: Jump ( BranchEdge { target : exit, args : vec ! [ ] } ) ) ;
3248
3252
let val = function. push_insn ( entry, Insn :: Const { val : Const :: Value ( Qnil ) } ) ;
3249
3253
function. push_insn ( entry, Insn :: Return { val } ) ;
@@ -3254,8 +3258,8 @@ mod rpo_tests {
3254
3258
fn diamond_iftrue ( ) {
3255
3259
let mut function = Function :: new ( std:: ptr:: null ( ) ) ;
3256
3260
let entry = function. entry_block ;
3257
- let side = function. new_block ( ) ;
3258
- let exit = function. new_block ( ) ;
3261
+ let side = function. new_block ( 0 ) ;
3262
+ let exit = function. new_block ( 0 ) ;
3259
3263
function. push_insn ( side, Insn :: Jump ( BranchEdge { target : exit, args : vec ! [ ] } ) ) ;
3260
3264
let val = function. push_insn ( entry, Insn :: Const { val : Const :: Value ( Qnil ) } ) ;
3261
3265
function. push_insn ( entry, Insn :: IfTrue { val, target : BranchEdge { target : side, args : vec ! [ ] } } ) ;
@@ -3269,8 +3273,8 @@ mod rpo_tests {
3269
3273
fn diamond_iffalse ( ) {
3270
3274
let mut function = Function :: new ( std:: ptr:: null ( ) ) ;
3271
3275
let entry = function. entry_block ;
3272
- let side = function. new_block ( ) ;
3273
- let exit = function. new_block ( ) ;
3276
+ let side = function. new_block ( 0 ) ;
3277
+ let exit = function. new_block ( 0 ) ;
3274
3278
function. push_insn ( side, Insn :: Jump ( BranchEdge { target : exit, args : vec ! [ ] } ) ) ;
3275
3279
let val = function. push_insn ( entry, Insn :: Const { val : Const :: Value ( Qnil ) } ) ;
3276
3280
function. push_insn ( entry, Insn :: IfFalse { val, target : BranchEdge { target : side, args : vec ! [ ] } } ) ;
@@ -3325,7 +3329,7 @@ mod validation_tests {
3325
3329
fn iftrue_mismatch_args ( ) {
3326
3330
let mut function = Function :: new ( std:: ptr:: null ( ) ) ;
3327
3331
let entry = function. entry_block ;
3328
- let side = function. new_block ( ) ;
3332
+ let side = function. new_block ( 0 ) ;
3329
3333
let val = function. push_insn ( entry, Insn :: Const { val : Const :: Value ( Qnil ) } ) ;
3330
3334
function. push_insn ( entry, Insn :: IfTrue { val, target : BranchEdge { target : side, args : vec ! [ val, val, val] } } ) ;
3331
3335
assert_matches_err ( function. validate ( ) , ValidationError :: MismatchedBlockArity ( entry, 0 , 3 ) ) ;
@@ -3335,7 +3339,7 @@ mod validation_tests {
3335
3339
fn iffalse_mismatch_args ( ) {
3336
3340
let mut function = Function :: new ( std:: ptr:: null ( ) ) ;
3337
3341
let entry = function. entry_block ;
3338
- let side = function. new_block ( ) ;
3342
+ let side = function. new_block ( 0 ) ;
3339
3343
let val = function. push_insn ( entry, Insn :: Const { val : Const :: Value ( Qnil ) } ) ;
3340
3344
function. push_insn ( entry, Insn :: IfFalse { val, target : BranchEdge { target : side, args : vec ! [ val, val, val] } } ) ;
3341
3345
assert_matches_err ( function. validate ( ) , ValidationError :: MismatchedBlockArity ( entry, 0 , 3 ) ) ;
@@ -3345,7 +3349,7 @@ mod validation_tests {
3345
3349
fn jump_mismatch_args ( ) {
3346
3350
let mut function = Function :: new ( std:: ptr:: null ( ) ) ;
3347
3351
let entry = function. entry_block ;
3348
- let side = function. new_block ( ) ;
3352
+ let side = function. new_block ( 0 ) ;
3349
3353
let val = function. push_insn ( entry, Insn :: Const { val : Const :: Value ( Qnil ) } ) ;
3350
3354
function. push_insn ( entry, Insn :: Jump ( BranchEdge { target : side, args : vec ! [ val, val, val] } ) ) ;
3351
3355
assert_matches_err ( function. validate ( ) , ValidationError :: MismatchedBlockArity ( entry, 0 , 3 ) ) ;
@@ -3377,8 +3381,8 @@ mod validation_tests {
3377
3381
// This tests that one branch is missing a definition which fails.
3378
3382
let mut function = Function :: new ( std:: ptr:: null ( ) ) ;
3379
3383
let entry = function. entry_block ;
3380
- let side = function. new_block ( ) ;
3381
- let exit = function. new_block ( ) ;
3384
+ let side = function. new_block ( 0 ) ;
3385
+ let exit = function. new_block ( 0 ) ;
3382
3386
let v0 = function. push_insn ( side, Insn :: Const { val : Const :: Value ( VALUE :: fixnum_from_usize ( 3 ) ) } ) ;
3383
3387
function. push_insn ( side, Insn :: Jump ( BranchEdge { target : exit, args : vec ! [ ] } ) ) ;
3384
3388
let val1 = function. push_insn ( entry, Insn :: Const { val : Const :: CBool ( false ) } ) ;
@@ -3396,8 +3400,8 @@ mod validation_tests {
3396
3400
// This tests that both branches with a definition succeeds.
3397
3401
let mut function = Function :: new ( std:: ptr:: null ( ) ) ;
3398
3402
let entry = function. entry_block ;
3399
- let side = function. new_block ( ) ;
3400
- let exit = function. new_block ( ) ;
3403
+ let side = function. new_block ( 0 ) ;
3404
+ let exit = function. new_block ( 0 ) ;
3401
3405
let v0 = function. push_insn ( entry, Insn :: Const { val : Const :: Value ( VALUE :: fixnum_from_usize ( 3 ) ) } ) ;
3402
3406
function. push_insn ( side, Insn :: Jump ( BranchEdge { target : exit, args : vec ! [ ] } ) ) ;
3403
3407
let val = function. push_insn ( entry, Insn :: Const { val : Const :: CBool ( false ) } ) ;
@@ -3437,7 +3441,7 @@ mod validation_tests {
3437
3441
let mut function = Function :: new ( std:: ptr:: null ( ) ) ;
3438
3442
let entry = function. entry_block ;
3439
3443
let val = function. push_insn ( entry, Insn :: Const { val : Const :: Value ( Qnil ) } ) ;
3440
- let exit = function. new_block ( ) ;
3444
+ let exit = function. new_block ( 0 ) ;
3441
3445
function. push_insn ( entry, Insn :: Jump ( BranchEdge { target : exit, args : vec ! [ ] } ) ) ;
3442
3446
function. push_insn_id ( exit, val) ;
3443
3447
function. push_insn ( exit, Insn :: Return { val } ) ;
@@ -3532,8 +3536,8 @@ mod infer_tests {
3532
3536
fn diamond_iffalse_merge_fixnum ( ) {
3533
3537
let mut function = Function :: new ( std:: ptr:: null ( ) ) ;
3534
3538
let entry = function. entry_block ;
3535
- let side = function. new_block ( ) ;
3536
- let exit = function. new_block ( ) ;
3539
+ let side = function. new_block ( 0 ) ;
3540
+ let exit = function. new_block ( 0 ) ;
3537
3541
let v0 = function. push_insn ( side, Insn :: Const { val : Const :: Value ( VALUE :: fixnum_from_usize ( 3 ) ) } ) ;
3538
3542
function. push_insn ( side, Insn :: Jump ( BranchEdge { target : exit, args : vec ! [ v0] } ) ) ;
3539
3543
let val = function. push_insn ( entry, Insn :: Const { val : Const :: CBool ( false ) } ) ;
@@ -3551,8 +3555,8 @@ mod infer_tests {
3551
3555
fn diamond_iffalse_merge_bool ( ) {
3552
3556
let mut function = Function :: new ( std:: ptr:: null ( ) ) ;
3553
3557
let entry = function. entry_block ;
3554
- let side = function. new_block ( ) ;
3555
- let exit = function. new_block ( ) ;
3558
+ let side = function. new_block ( 0 ) ;
3559
+ let exit = function. new_block ( 0 ) ;
3556
3560
let v0 = function. push_insn ( side, Insn :: Const { val : Const :: Value ( Qtrue ) } ) ;
3557
3561
function. push_insn ( side, Insn :: Jump ( BranchEdge { target : exit, args : vec ! [ v0] } ) ) ;
3558
3562
let val = function. push_insn ( entry, Insn :: Const { val : Const :: CBool ( false ) } ) ;
0 commit comments