1 /* { dg-additional-options "-std=gnu99 -fpic" }  */
2 /* { dg-do compile }  */
3 
4 typedef unsigned long VALUE;
5 typedef unsigned long ID;
6 
7 typedef struct rb_callable_method_entry_struct
8 {
9   ID called_id;
10   const VALUE owner;
11 } rb_callable_method_entry_t;
12 
13 typedef struct rb_iseq_struct rb_iseq_t;
14 
15 struct __jmp_buf_tag { int xx; };
16 typedef struct __jmp_buf_tag jmp_buf[1];
17 
18 struct rb_iseq_struct
19 {
20   const struct iseq_catch_table *catch_table;
21 };
22 
23 typedef struct rb_control_frame_struct
24 {
25   const VALUE *pc;
26   VALUE *sp;
27   const rb_iseq_t *iseq;
28   VALUE flag;
29   VALUE *ep;
30 } rb_control_frame_t;
31 
32 typedef jmp_buf rb_jmpbuf_t;
33 struct rb_vm_tag
34 {
35   rb_jmpbuf_t buf;
36 }rb_ensure_list_t;
37 
38 typedef struct rb_thread_struct
39 {
40   rb_control_frame_t *cfp;
41   struct rb_vm_tag *tag;
42 } rb_thread_t;
43 
44 struct iseq_catch_table_entry
45 {
46   const rb_iseq_t *iseq;
47 };
48 
49 struct iseq_catch_table
50 {
51   unsigned int size;
52 };
53 
54 extern unsigned long long __sdt_unsp;
55 extern unsigned short ruby_cmethod__return_semaphore;
56 
57 struct ruby_dtrace_method_hook_args
58 {
59   const char *classname;
60   const char *methodname;
61   const char *filename;
62   int line_no;
63 };
64 
65 int ruby_th_dtrace_setup(rb_thread_t *th, VALUE klass, ID id, struct ruby_dtrace_method_hook_args *args);
66 int rb_threadptr_tag_state (rb_thread_t *th);
67 VALUE vm_exec_core (rb_thread_t *th, VALUE initial);
68 const rb_callable_method_entry_t *rb_vm_frame_method_entry (const rb_control_frame_t *cfp);
69 
70 struct vm_throw_data;
71 const rb_control_frame_t * THROW_DATA_CATCH_FRAME(const struct vm_throw_data *obj);
72 rb_control_frame_t * vm_push_frame(rb_thread_t *th, const rb_iseq_t *iseq, VALUE type, VALUE self, VALUE specval, VALUE cref_or_me, const VALUE *pc, VALUE *sp, int local_size, int stack_max);
73 
74 
vm_exec(rb_thread_t * th)75 VALUE vm_exec(rb_thread_t *th)
76 {
77   int state;
78   VALUE result;
79   VALUE initial = 0;
80   struct vm_throw_data *err;
81   rb_thread_t * const _th = (th);
82   struct rb_vm_tag _tag;
83 
84   if ((state = (__builtin_setjmp((_tag.buf)) ? rb_threadptr_tag_state((_th)) : ((void)(_th->tag = &_tag), 0))) == 0)
85   {
86     result = vm_exec_core(th, initial);
87   }
88   else
89   {
90     unsigned int i;
91     const struct iseq_catch_table_entry *entry;
92     const struct iseq_catch_table *ct;
93     unsigned long epc, cont_pc, cont_sp;
94     const rb_iseq_t *catch_iseq;
95     rb_control_frame_t *cfp;
96     const rb_control_frame_t *escape_cfp;
97 
98     while (th->cfp->pc == 0 || th->cfp->iseq == 0)
99     {
100       if (ruby_cmethod__return_semaphore)
101       {
102         struct ruby_dtrace_method_hook_args args;
103         if (ruby_th_dtrace_setup(th, rb_vm_frame_method_entry(th->cfp)->owner, rb_vm_frame_method_entry(th->cfp)->called_id, &args))
104         {
105           __asm__ __volatile__ (
106              ".asciz \"%n[_SDT_S1]@%[_SDT_A1] %n[_SDT_S2]@%[_SDT_A2] %n[_SDT_S3]@%[_SDT_A3] %n[_SDT_S4]@%[_SDT_A4]\"\n"
107              :
108              : [_SDT_S1] "n" (((!__extension__ (__builtin_constant_p ((((unsigned long long) (__typeof (__builtin_choose_expr (((__builtin_classify_type ( args.classname ) + 3) & -4) == 4, ( args.classname ), 0U))) __sdt_unsp) & ((unsigned long long)1 << (sizeof (unsigned long long) * 8 - 1))) == 0) || (__typeof (__builtin_choose_expr (((__builtin_classify_type ( args.classname ) + 3) & -4) == 4, ( args.classname ), 0U))) -1 > (__typeof (__builtin_choose_expr (((__builtin_classify_type ( args.classname ) + 3) & -4) == 4, ( args.classname ), 0U))) 0)) ? 1 : -1) * (int) ((__builtin_classify_type ( args.classname ) == 14 || __builtin_classify_type ( args.classname ) == 5) ? sizeof (void *) : sizeof ( args.classname ))),
109                [_SDT_A1] "nor" (( args.classname )),
110                [_SDT_S2] "n" (((!__extension__ (__builtin_constant_p ((((unsigned long long) (__typeof (__builtin_choose_expr (((__builtin_classify_type ( args.methodname ) + 3) & -4) == 4, ( args.methodname ), 0U))) __sdt_unsp) & ((unsigned long long)1 << (sizeof (unsigned long long) * 8 - 1))) == 0) || (__typeof (__builtin_choose_expr (((__builtin_classify_type ( args.methodname ) + 3) & -4) == 4, ( args.methodname ), 0U))) -1 > (__typeof (__builtin_choose_expr (((__builtin_classify_type ( args.methodname ) + 3) & -4) == 4, ( args.methodname ), 0U))) 0)) ? 1 : -1) * (int) ((__builtin_classify_type ( args.methodname ) == 14 || __builtin_classify_type ( args.methodname ) == 5) ? sizeof (void *) : sizeof ( args.methodname ))),
111                [_SDT_A2] "nor" (( args.methodname )),
112                [_SDT_S3] "n" (((!__extension__ (__builtin_constant_p ((((unsigned long long) (__typeof (__builtin_choose_expr (((__builtin_classify_type ( args.filename ) + 3) & -4) == 4, ( args.filename ), 0U))) __sdt_unsp) & ((unsigned long long)1 << (sizeof (unsigned long long) * 8 - 1))) == 0) || (__typeof (__builtin_choose_expr (((__builtin_classify_type ( args.filename ) + 3) & -4) == 4, ( args.filename ), 0U))) -1 > (__typeof (__builtin_choose_expr (((__builtin_classify_type ( args.filename ) + 3) & -4) == 4, ( args.filename ), 0U))) 0)) ? 1 : -1) * (int) ((__builtin_classify_type ( args.filename ) == 14 || __builtin_classify_type ( args.filename ) == 5) ? sizeof (void *) : sizeof ( args.filename ))),
113                [_SDT_A3] "nor" (( args.filename )),
114                [_SDT_S4] "n" (((!__extension__ (__builtin_constant_p ((((unsigned long long) (__typeof (__builtin_choose_expr (((__builtin_classify_type ( args.line_no ) + 3) & -4) == 4, ( args.line_no ), 0U))) __sdt_unsp) & ((unsigned long long)1 << (sizeof (unsigned long long) * 8 - 1))) == 0) || (__typeof (__builtin_choose_expr (((__builtin_classify_type ( args.line_no ) + 3) & -4) == 4, ( args.line_no ), 0U))) -1 > (__typeof (__builtin_choose_expr (((__builtin_classify_type ( args.line_no ) + 3) & -4) == 4, ( args.line_no ), 0U))) 0)) ? 1 : -1) * (int) ((__builtin_classify_type ( args.line_no ) == 14 || __builtin_classify_type ( args.line_no ) == 5) ? sizeof (void *) : sizeof ( args.line_no ))),
115                [_SDT_A4] "nor" (( args.line_no ))
116           );
117         }
118       }
119     }
120 
121     if (cfp == escape_cfp && !(((cfp)->flag & 0x0200) != 0))
122       catch_iseq = entry->iseq;
123 
124     if (state == 6)
125     {
126       escape_cfp = THROW_DATA_CATCH_FRAME(err);
127 
128       if (ct)
129         for (i = 0; i < ct->size; i++) { }
130     }
131     else
132       ct = cfp->iseq->catch_table;
133 
134     vm_push_frame(th, catch_iseq, 0xb1, 0, 1, 0, 0, 0, 5, 123);
135   }
136 }
137