@@ -3806,6 +3806,77 @@ gen_toregexp(jitstate_t* jit, ctx_t* ctx)
3806
3806
return YJIT_KEEP_COMPILING ;
3807
3807
}
3808
3808
3809
+ static codegen_status_t
3810
+ gen_getspecial (jitstate_t * jit , ctx_t * ctx )
3811
+ {
3812
+ // This takes two arguments, key and type
3813
+ // key is only used when type == 0
3814
+ // A non-zero type determines which type of backref to fetch
3815
+ rb_num_t key = jit_get_arg (jit , 0 );
3816
+ rb_num_t type = jit_get_arg (jit , 1 );
3817
+
3818
+ if (type == 0 ) {
3819
+ // not yet implemented
3820
+ return YJIT_CANT_COMPILE ;
3821
+ } else if (type & 0x01 ) {
3822
+ // Fetch a "special" backref based on a char encoded by shifting by 1
3823
+
3824
+ // Can raise if matchdata uninitialized
3825
+ jit_prepare_routine_call (jit , ctx , REG0 );
3826
+
3827
+ // call rb_backref_get()
3828
+ ADD_COMMENT (cb , "rb_backref_get" );
3829
+ call_ptr (cb , REG0 , (void * )rb_backref_get );
3830
+ mov (cb , C_ARG_REGS [0 ], RAX );
3831
+
3832
+ switch (type >> 1 ) {
3833
+ case '&' :
3834
+ ADD_COMMENT (cb , "rb_reg_last_match" );
3835
+ call_ptr (cb , REG0 , (void * )rb_reg_last_match );
3836
+ break ;
3837
+ case '`' :
3838
+ ADD_COMMENT (cb , "rb_reg_match_pre" );
3839
+ call_ptr (cb , REG0 , (void * )rb_reg_match_pre );
3840
+ break ;
3841
+ case '\'' :
3842
+ ADD_COMMENT (cb , "rb_reg_match_post" );
3843
+ call_ptr (cb , REG0 , (void * )rb_reg_match_post );
3844
+ break ;
3845
+ case '+' :
3846
+ ADD_COMMENT (cb , "rb_reg_match_last" );
3847
+ call_ptr (cb , REG0 , (void * )rb_reg_match_last );
3848
+ break ;
3849
+ default :
3850
+ rb_bug ("invalid back-ref" );
3851
+ }
3852
+
3853
+ x86opnd_t stack_ret = ctx_stack_push (ctx , TYPE_UNKNOWN );
3854
+ mov (cb , stack_ret , RAX );
3855
+
3856
+ return YJIT_KEEP_COMPILING ;
3857
+ } else {
3858
+ // Fetch the N-th match from the last backref based on type shifted by 1
3859
+
3860
+ // Can raise if matchdata uninitialized
3861
+ jit_prepare_routine_call (jit , ctx , REG0 );
3862
+
3863
+ // call rb_backref_get()
3864
+ ADD_COMMENT (cb , "rb_backref_get" );
3865
+ call_ptr (cb , REG0 , (void * )rb_backref_get );
3866
+
3867
+ // rb_reg_nth_match((int)(type >> 1), backref);
3868
+ ADD_COMMENT (cb , "rb_reg_nth_match" );
3869
+ mov (cb , C_ARG_REGS [0 ], imm_opnd (type >> 1 ));
3870
+ mov (cb , C_ARG_REGS [1 ], RAX );
3871
+ call_ptr (cb , REG0 , (void * )rb_reg_nth_match );
3872
+
3873
+ x86opnd_t stack_ret = ctx_stack_push (ctx , TYPE_UNKNOWN );
3874
+ mov (cb , stack_ret , RAX );
3875
+
3876
+ return YJIT_KEEP_COMPILING ;
3877
+ }
3878
+ }
3879
+
3809
3880
static codegen_status_t
3810
3881
gen_opt_getinlinecache (jitstate_t * jit , ctx_t * ctx )
3811
3882
{
@@ -4156,6 +4227,7 @@ yjit_init_codegen(void)
4156
4227
yjit_reg_op (BIN (setglobal ), gen_setglobal );
4157
4228
yjit_reg_op (BIN (tostring ), gen_tostring );
4158
4229
yjit_reg_op (BIN (toregexp ), gen_toregexp );
4230
+ yjit_reg_op (BIN (getspecial ), gen_getspecial );
4159
4231
4160
4232
yjit_method_codegen_table = st_init_numtable ();
4161
4233
0 commit comments