Ruby 1.9.2p136(2010-12-25revision30365)

- Main Page
- Modules
- Data Structures
- Files

- File List
- Globals

# vm_core.h

Go to the documentation of this file.

    00001 /**********************************************************************
    00002
    00003   vm_core.h -
    00004
    00005   $Author: yugui $
    00006   created at: 04/01/01 19:41:38 JST
    00007
    00008   Copyright (C) 2004-2007 Koichi Sasada
    00009
    00010 **********************************************************************/
    00011
    00012 #ifndef RUBY_VM_CORE_H
    00013 #define RUBY_VM_CORE_H
    00014
    00015 #define RUBY_VM_THREAD_MODEL 2
    00016
    00017 #include "ruby/ruby.h"
    00018 #include "ruby/st.h"
    00019
    00020 #include "node.h"
    00021 #include "debug.h"
    00022 #include "vm_opts.h"
    00023 #include "id.h"
    00024 #include "method.h"
    00025
    00026 #if   defined(_WIN32)
    00027 #include "thread_win32.h"
    00028 #elif defined(HAVE_PTHREAD_H)
    00029 #include "thread_pthread.h"
    00030 #else
    00031 #error "unsupported thread type"
    00032 #endif
    00033
    00034 #ifndef ENABLE_VM_OBJSPACE
    00035 #ifdef _WIN32
    00036 /*
    00037  * TODO: object space indenpendent st_table.
    00038  * socklist needs st_table in rb_w32_sysinit(), before object space
    00039  * initialization.
    00040  * It is too early now to change st_hash_type, since it breaks binary
    00041  * compatibility.
    00042  */
    00043 #define ENABLE_VM_OBJSPACE 0
    00044 #else
    00045 #define ENABLE_VM_OBJSPACE 1
    00046 #endif
    00047 #endif
    00048
    00049 #include <setjmp.h>
    00050 #include <signal.h>
    00051
    00052 #ifndef NSIG
    00053 # define NSIG (_SIGMAX + 1)      /* For QNX */
    00054 #endif
    00055
    00056 #define RUBY_NSIG NSIG
    00057
    00058 #ifdef HAVE_STDARG_PROTOTYPES
    00059 #include <stdarg.h>
    00060 #define va_init_list(a,b) va_start(a,b)
    00061 #else
    00062 #include <varargs.h>
    00063 #define va_init_list(a,b) va_start(a)
    00064 #endif
    00065
    00066 #if defined(SIGSEGV) && defined(HAVE_SIGALTSTACK) && defined(SA_SIGINFO) && !defined(__NetBSD__)
    00067 #define USE_SIGALTSTACK
    00068 #endif
    00069
    00070 /*****************/
    00071 /* configuration */
    00072 /*****************/
    00073
    00074 /* gcc ver. check */
    00075 #if defined(__GNUC__) && __GNUC__ >= 2
    00076
    00077 #if OPT_TOKEN_THREADED_CODE
    00078 #if OPT_DIRECT_THREADED_CODE
    00079 #undef OPT_DIRECT_THREADED_CODE
    00080 #endif
    00081 #endif
    00082
    00083 #else /* defined(__GNUC__) && __GNUC__ >= 2 */
    00084
    00085 /* disable threaded code options */
    00086 #if OPT_DIRECT_THREADED_CODE
    00087 #undef OPT_DIRECT_THREADED_CODE
    00088 #endif
    00089 #if OPT_TOKEN_THREADED_CODE
    00090 #undef OPT_TOKEN_THREADED_CODE
    00091 #endif
    00092 #endif
    00093
    00094 /* call threaded code */
    00095 #if    OPT_CALL_THREADED_CODE
    00096 #if    OPT_DIRECT_THREADED_CODE
    00097 #undef OPT_DIRECT_THREADED_CODE
    00098 #endif /* OPT_DIRECT_THREADED_CODE */
    00099 #if    OPT_STACK_CACHING
    00100 #undef OPT_STACK_CACHING
    00101 #endif /* OPT_STACK_CACHING */
    00102 #endif /* OPT_CALL_THREADED_CODE */
    00103
    00104 /* likely */
    00105 #if __GNUC__ >= 3
    00106 #define LIKELY(x)   (__builtin_expect((x), 1))
    00107 #define UNLIKELY(x) (__builtin_expect((x), 0))
    00108 #else /* __GNUC__ >= 3 */
    00109 #define LIKELY(x)   (x)
    00110 #define UNLIKELY(x) (x)
    00111 #endif /* __GNUC__ >= 3 */
    00112
    00113 #if __GNUC__ >= 3
    00114 #define UNINITIALIZED_VAR(x) x = x
    00115 #else
    00116 #define UNINITIALIZED_VAR(x) x
    00117 #endif
    00118
    00119 typedef unsigned long rb_num_t;
    00120
    00121 /* iseq data type */
    00122
    00123 struct iseq_compile_data_ensure_node_stack;
    00124
    00125 typedef struct rb_compile_option_struct {
    00126     int inline_const_cache;
    00127     int peephole_optimization;
    00128     int tailcall_optimization;
    00129     int specialized_instruction;
    00130     int operands_unification;
    00131     int instructions_unification;
    00132     int stack_caching;
    00133     int trace_instruction;
    00134     int debug_level;
    00135 } rb_compile_option_t;
    00136
    00137 struct iseq_inline_cache_entry {
    00138     VALUE ic_vmstat;
    00139     VALUE ic_class;
    00140     union {
    00141         VALUE value;
    00142         rb_method_entry_t *method;
    00143         long index;
    00144     } ic_value;
    00145 };
    00146
    00147 #if 1
    00148 #define GetCoreDataFromValue(obj, type, ptr) do { \
    00149     ptr = (type*)DATA_PTR(obj); \
    00150 } while (0)
    00151 #else
    00152 #define GetCoreDataFromValue(obj, type, ptr) Data_Get_Struct(obj, type, ptr)
    00153 #endif
    00154
    00155 #define GetISeqPtr(obj, ptr) \
    00156   GetCoreDataFromValue(obj, rb_iseq_t, ptr)
    00157
    00158 struct rb_iseq_struct;
    00159
    00160 struct rb_iseq_struct {
    00161     /***************/
    00162     /* static data */
    00163     /***************/
    00164
    00165     VALUE type;          /* instruction sequence type */
    00166     VALUE name;          /* String: iseq name */
    00167     VALUE filename;      /* file information where this sequence from */
    00168     VALUE filepath;      /* real file path or nil */
    00169     VALUE *iseq;         /* iseq (insn number and openrads) */
    00170     VALUE *iseq_encoded; /* encoded iseq */
    00171     unsigned long iseq_size;
    00172     VALUE mark_ary;     /* Array: includes operands which should be GC marked */
    00173     VALUE coverage;     /* coverage array */
    00174     unsigned short line_no;
    00175
    00176     /* insn info, must be freed */
    00177     struct iseq_insn_info_entry *insn_info_table;
    00178     size_t insn_info_size;
    00179
    00180     ID *local_table;            /* must free */
    00181     int local_table_size;
    00182
    00183     /* method, class frame: sizeof(vars) + 1, block frame: sizeof(vars) */
    00184     int local_size;
    00185
    00186     struct iseq_inline_cache_entry *ic_entries;
    00187     int ic_size;
    00188
    00212     int argc;
    00213     int arg_simple;
    00214     int arg_rest;
    00215     int arg_block;
    00216     int arg_opts;
    00217     int arg_post_len;
    00218     int arg_post_start;
    00219     int arg_size;
    00220     VALUE *arg_opt_table;
    00221
    00222     size_t stack_max; /* for stack overflow check */
    00223
    00224     /* catch table */
    00225     struct iseq_catch_table_entry *catch_table;
    00226     int catch_table_size;
    00227
    00228     /* for child iseq */
    00229     struct rb_iseq_struct *parent_iseq;
    00230     struct rb_iseq_struct *local_iseq;
    00231
    00232     /****************/
    00233     /* dynamic data */
    00234     /****************/
    00235
    00236     VALUE self;
    00237     VALUE orig;                 /* non-NULL if its data have origin */
    00238
    00239     /* block inlining */
    00240     /*
    00241      * NODE *node;
    00242      * void *special_block_builder;
    00243      * void *cached_special_block_builder;
    00244      * VALUE cached_special_block;
    00245      */
    00246
    00247     /* klass/module nest information stack (cref) */
    00248     NODE *cref_stack;
    00249     VALUE klass;
    00250
    00251     /* misc */
    00252     ID defined_method_id;       /* for define_method */
    00253
    00254     /* used at compile time */
    00255     struct iseq_compile_data *compile_data;
    00256 };
    00257
    00258 enum ruby_special_exceptions {
    00259     ruby_error_reenter,
    00260     ruby_error_nomemory,
    00261     ruby_error_sysstack,
    00262     ruby_special_error_count
    00263 };
    00264
    00265 #define GetVMPtr(obj, ptr) \
    00266   GetCoreDataFromValue(obj, rb_vm_t, ptr)
    00267
    00268 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
    00269 struct rb_objspace;
    00270 void rb_objspace_free(struct rb_objspace *);
    00271 #endif
    00272
    00273 typedef struct rb_vm_struct {
    00274     VALUE self;
    00275
    00276     rb_thread_lock_t global_vm_lock;
    00277
    00278     struct rb_thread_struct *main_thread;
    00279     struct rb_thread_struct *running_thread;
    00280
    00281     st_table *living_threads;
    00282     VALUE thgroup_default;
    00283
    00284     int running;
    00285     int thread_abort_on_exception;
    00286     unsigned long trace_flag;
    00287     volatile int sleeper;
    00288
    00289     /* object management */
    00290     VALUE mark_object_ary;
    00291
    00292     VALUE special_exceptions[ruby_special_error_count];
    00293
    00294     /* load */
    00295     VALUE top_self;
    00296     VALUE load_path;
    00297     VALUE loaded_features;
    00298     struct st_table *loading_table;
    00299
    00300     /* signal */
    00301     struct {
    00302         VALUE cmd;
    00303         int safe;
    00304     } trap_list[RUBY_NSIG];
    00305
    00306     /* hook */
    00307     rb_event_hook_t *event_hooks;
    00308
    00309     int src_encoding_index;
    00310
    00311     VALUE verbose, debug, progname;
    00312     VALUE coverages;
    00313
    00314     struct unlinked_method_entry_list_entry *unlinked_method_entry_list;
    00315
    00316 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE
    00317     struct rb_objspace *objspace;
    00318 #endif
    00319 } rb_vm_t;
    00320
    00321 typedef struct {
    00322     VALUE *pc;                  /* cfp[0] */
    00323     VALUE *sp;                  /* cfp[1] */
    00324     VALUE *bp;                  /* cfp[2] */
    00325     rb_iseq_t *iseq;            /* cfp[3] */
    00326     VALUE flag;                 /* cfp[4] */
    00327     VALUE self;                 /* cfp[5] / block[0] */
    00328     VALUE *lfp;                 /* cfp[6] / block[1] */
    00329     VALUE *dfp;                 /* cfp[7] / block[2] */
    00330     rb_iseq_t *block_iseq;      /* cfp[8] / block[3] */
    00331     VALUE proc;                 /* cfp[9] / block[4] */
    00332     const rb_method_entry_t *me;/* cfp[10] */
    00333 } rb_control_frame_t;
    00334
    00335 typedef struct rb_block_struct {
    00336     VALUE self;                 /* share with method frame if it's only block */
    00337     VALUE *lfp;                 /* share with method frame if it's only block */
    00338     VALUE *dfp;                 /* share with method frame if it's only block */
    00339     rb_iseq_t *iseq;
    00340     VALUE proc;
    00341 } rb_block_t;
    00342
    00343 #define GetThreadPtr(obj, ptr) \
    00344   GetCoreDataFromValue(obj, rb_thread_t, ptr)
    00345
    00346 enum rb_thread_status {
    00347     THREAD_TO_KILL,
    00348     THREAD_RUNNABLE,
    00349     THREAD_STOPPED,
    00350     THREAD_STOPPED_FOREVER,
    00351     THREAD_KILLED
    00352 };
    00353
    00354 typedef RUBY_JMP_BUF rb_jmpbuf_t;
    00355
    00356 struct rb_vm_tag {
    00357     rb_jmpbuf_t buf;
    00358     VALUE tag;
    00359     VALUE retval;
    00360     struct rb_vm_tag *prev;
    00361 };
    00362
    00363 struct rb_vm_protect_tag {
    00364     struct rb_vm_protect_tag *prev;
    00365 };
    00366
    00367 #define RUBY_VM_VALUE_CACHE_SIZE 0x1000
    00368 #define USE_VALUE_CACHE 0
    00369
    00370 struct rb_unblock_callback {
    00371     rb_unblock_function_t *func;
    00372     void *arg;
    00373 };
    00374
    00375 struct rb_mutex_struct;
    00376
    00377 typedef struct rb_thread_struct
    00378 {
    00379     VALUE self;
    00380     rb_vm_t *vm;
    00381
    00382     /* execution information */
    00383     VALUE *stack;               /* must free, must mark */
    00384     unsigned long stack_size;
    00385     rb_control_frame_t *cfp;
    00386     int safe_level;
    00387     int raised_flag;
    00388     VALUE last_status; /* $? */
    00389
    00390     /* passing state */
    00391     int state;
    00392
    00393     /* for rb_iterate */
    00394     const rb_block_t *passed_block;
    00395
    00396     /* for bmethod */
    00397     const rb_method_entry_t *passed_me;
    00398
    00399     /* for load(true) */
    00400     VALUE top_self;
    00401     VALUE top_wrapper;
    00402
    00403     /* eval env */
    00404     rb_block_t *base_block;
    00405
    00406     VALUE *local_lfp;
    00407     VALUE local_svar;
    00408
    00409     /* thread control */
    00410     rb_thread_id_t thread_id;
    00411     enum rb_thread_status status;
    00412     int priority;
    00413     int slice;
    00414
    00415     native_thread_data_t native_thread_data;
    00416     void *blocking_region_buffer;
    00417
    00418     VALUE thgroup;
    00419     VALUE value;
    00420
    00421     VALUE errinfo;
    00422     VALUE thrown_errinfo;
    00423     int exec_signal;
    00424
    00425     int interrupt_flag;
    00426     rb_thread_lock_t interrupt_lock;
    00427     struct rb_unblock_callback unblock;
    00428     VALUE locking_mutex;
    00429     struct rb_mutex_struct *keeping_mutexes;
    00430     int transition_for_lock;
    00431
    00432     struct rb_vm_tag *tag;
    00433     struct rb_vm_protect_tag *protect_tag;
    00434
    00435     int parse_in_eval;
    00436     int mild_compile_error;
    00437
    00438     /* storage */
    00439     st_table *local_storage;
    00440 #if USE_VALUE_CACHE
    00441     VALUE value_cache[RUBY_VM_VALUE_CACHE_SIZE + 1];
    00442     VALUE *value_cache_ptr;
    00443 #endif
    00444
    00445     struct rb_thread_struct *join_list_next;
    00446     struct rb_thread_struct *join_list_head;
    00447
    00448     VALUE first_proc;
    00449     VALUE first_args;
    00450     VALUE (*first_func)(ANYARGS);
    00451
    00452     /* for GC */
    00453     VALUE *machine_stack_start;
    00454     VALUE *machine_stack_end;
    00455     size_t machine_stack_maxsize;
    00456 #ifdef __ia64
    00457     VALUE *machine_register_stack_start;
    00458     VALUE *machine_register_stack_end;
    00459     size_t machine_register_stack_maxsize;
    00460 #endif
    00461     jmp_buf machine_regs;
    00462     int mark_stack_len;
    00463
    00464     /* statistics data for profiler */
    00465     VALUE stat_insn_usage;
    00466
    00467     /* tracer */
    00468     rb_event_hook_t *event_hooks;
    00469     rb_event_flag_t event_flags;
    00470     int tracing;
    00471
    00472     /* fiber */
    00473     VALUE fiber;
    00474     VALUE root_fiber;
    00475     rb_jmpbuf_t root_jmpbuf;
    00476
    00477     /* misc */
    00478     int method_missing_reason;
    00479     int abort_on_exception;
    00480 #ifdef USE_SIGALTSTACK
    00481     void *altstack;
    00482 #endif
    00483 } rb_thread_t;
    00484
    00485 /* iseq.c */
    00486 VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE);
    00487 VALUE rb_iseq_new_top(NODE *node, VALUE name, VALUE filename, VALUE filepath, VALUE parent);
    00488 VALUE rb_iseq_new_main(NODE *node, VALUE filename, VALUE filepath);
    00489 VALUE rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE);
    00490 VALUE rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, VALUE, const rb_compile_option_t*);
    00491 VALUE rb_iseq_compile(VALUE src, VALUE file, VALUE line);
    00492 VALUE rb_iseq_disasm(VALUE self);
    00493 int rb_iseq_disasm_insn(VALUE str, VALUE *iseqval, size_t pos, rb_iseq_t *iseq, VALUE child);
    00494 const char *ruby_node_name(int node);
    00495 int rb_iseq_first_lineno(rb_iseq_t *iseq);
    00496
    00497 RUBY_EXTERN VALUE rb_cISeq;
    00498 RUBY_EXTERN VALUE rb_cRubyVM;
    00499 RUBY_EXTERN VALUE rb_cEnv;
    00500 RUBY_EXTERN VALUE rb_mRubyVMFrozenCore;
    00501
    00502 /* each thread has this size stack : 128KB */
    00503 #define RUBY_VM_THREAD_STACK_SIZE (128 * 1024)
    00504
    00505 #define GetProcPtr(obj, ptr) \
    00506   GetCoreDataFromValue(obj, rb_proc_t, ptr)
    00507
    00508 typedef struct {
    00509     rb_block_t block;
    00510
    00511     VALUE envval;               /* for GC mark */
    00512     VALUE blockprocval;
    00513     int safe_level;
    00514     int is_from_method;
    00515     int is_lambda;
    00516 } rb_proc_t;
    00517
    00518 #define GetEnvPtr(obj, ptr) \
    00519   GetCoreDataFromValue(obj, rb_env_t, ptr)
    00520
    00521 typedef struct {
    00522     VALUE *env;
    00523     int env_size;
    00524     int local_size;
    00525     VALUE prev_envval;          /* for GC mark */
    00526     rb_block_t block;
    00527 } rb_env_t;
    00528
    00529 #define GetBindingPtr(obj, ptr) \
    00530   GetCoreDataFromValue(obj, rb_binding_t, ptr)
    00531
    00532 typedef struct {
    00533     VALUE env;
    00534     VALUE filename;
    00535     unsigned short line_no;
    00536 } rb_binding_t;
    00537
    00538 /* used by compile time and send insn */
    00539 #define VM_CALL_ARGS_SPLAT_BIT     (0x01 << 1)
    00540 #define VM_CALL_ARGS_BLOCKARG_BIT  (0x01 << 2)
    00541 #define VM_CALL_FCALL_BIT          (0x01 << 3)
    00542 #define VM_CALL_VCALL_BIT          (0x01 << 4)
    00543 #define VM_CALL_TAILCALL_BIT       (0x01 << 5)
    00544 #define VM_CALL_TAILRECURSION_BIT  (0x01 << 6)
    00545 #define VM_CALL_SUPER_BIT          (0x01 << 7)
    00546 #define VM_CALL_OPT_SEND_BIT       (0x01 << 8)
    00547
    00548 #define VM_SPECIAL_OBJECT_VMCORE       0x01
    00549 #define VM_SPECIAL_OBJECT_CBASE        0x02
    00550 #define VM_SPECIAL_OBJECT_CONST_BASE  0x03
    00551
    00552 #define VM_FRAME_MAGIC_METHOD 0x11
    00553 #define VM_FRAME_MAGIC_BLOCK  0x21
    00554 #define VM_FRAME_MAGIC_CLASS  0x31
    00555 #define VM_FRAME_MAGIC_TOP    0x41
    00556 #define VM_FRAME_MAGIC_FINISH 0x51
    00557 #define VM_FRAME_MAGIC_CFUNC  0x61
    00558 #define VM_FRAME_MAGIC_PROC   0x71
    00559 #define VM_FRAME_MAGIC_IFUNC  0x81
    00560 #define VM_FRAME_MAGIC_EVAL   0x91
    00561 #define VM_FRAME_MAGIC_LAMBDA 0xa1
    00562 #define VM_FRAME_MAGIC_MASK_BITS   8
    00563 #define VM_FRAME_MAGIC_MASK   (~(~0<<VM_FRAME_MAGIC_MASK_BITS))
    00564
    00565 #define VM_FRAME_TYPE(cfp) ((cfp)->flag & VM_FRAME_MAGIC_MASK)
    00566
    00567 /* other frame flag */
    00568 #define VM_FRAME_FLAG_PASSED 0x0100
    00569
    00570 #define RUBYVM_CFUNC_FRAME_P(cfp) \
    00571   (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC)
    00572
    00573 /* inline cache */
    00574 typedef struct iseq_inline_cache_entry *IC;
    00575
    00576 extern VALUE ruby_vm_global_state_version;
    00577
    00578 #define GET_VM_STATE_VERSION() (ruby_vm_global_state_version)
    00579 #define INC_VM_STATE_VERSION() \
    00580   (ruby_vm_global_state_version = (ruby_vm_global_state_version+1) & 0x8fffffff)
    00581 void rb_vm_change_state(void);
    00582
    00583 typedef VALUE CDHASH;
    00584
    00585 #ifndef FUNC_FASTCALL
    00586 #define FUNC_FASTCALL(x) x
    00587 #endif
    00588
    00589 typedef rb_control_frame_t *
    00590   (FUNC_FASTCALL(*rb_insn_func_t))(rb_thread_t *, rb_control_frame_t *);
    00591
    00592 #define GC_GUARDED_PTR(p)     ((VALUE)((VALUE)(p) | 0x01))
    00593 #define GC_GUARDED_PTR_REF(p) ((void *)(((VALUE)p) & ~0x03))
    00594 #define GC_GUARDED_PTR_P(p)   (((VALUE)p) & 0x01)
    00595
    00596 #define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp) (cfp+1)
    00597 #define RUBY_VM_NEXT_CONTROL_FRAME(cfp) (cfp-1)
    00598 #define RUBY_VM_END_CONTROL_FRAME(th) \
    00599   ((rb_control_frame_t *)((th)->stack + (th)->stack_size))
    00600 #define RUBY_VM_VALID_CONTROL_FRAME_P(cfp, ecfp) \
    00601   ((void *)(ecfp) > (void *)(cfp))
    00602 #define RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp) \
    00603   (!RUBY_VM_VALID_CONTROL_FRAME_P((cfp), RUBY_VM_END_CONTROL_FRAME(th)))
    00604
    00605 #define RUBY_VM_IFUNC_P(ptr)        (BUILTIN_TYPE(ptr) == T_NODE)
    00606 #define RUBY_VM_NORMAL_ISEQ_P(ptr) \
    00607   (ptr && !RUBY_VM_IFUNC_P(ptr))
    00608
    00609 #define RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp) ((rb_block_t *)(&(cfp)->self))
    00610 #define RUBY_VM_GET_CFP_FROM_BLOCK_PTR(b) \
    00611   ((rb_control_frame_t *)((VALUE *)(b) - 5))
    00612
    00613 /* VM related object allocate functions */
    00614 VALUE rb_thread_alloc(VALUE klass);
    00615 VALUE rb_proc_alloc(VALUE klass);
    00616
    00617 /* for debug */
    00618 extern void rb_vmdebug_stack_dump_raw(rb_thread_t *, rb_control_frame_t *);
    00619 #define SDR() rb_vmdebug_stack_dump_raw(GET_THREAD(), GET_THREAD()->cfp)
    00620 #define SDR2(cfp) rb_vmdebug_stack_dump_raw(GET_THREAD(), (cfp))
    00621 void rb_vm_bugreport(void);
    00622
    00623 /* functions about thread/vm execution */
    00624 VALUE rb_iseq_eval(VALUE iseqval);
    00625 VALUE rb_iseq_eval_main(VALUE iseqval);
    00626 void rb_enable_interrupt(void);
    00627 void rb_disable_interrupt(void);
    00628 int rb_thread_method_id_and_class(rb_thread_t *th, ID *idp, VALUE *klassp);
    00629
    00630 VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, VALUE self,
    00631                         int argc, const VALUE *argv, const rb_block_t *blockptr);
    00632 VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass);
    00633 VALUE rb_vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp);
    00634
    00635 void rb_thread_start_timer_thread(void);
    00636 void rb_thread_stop_timer_thread(void);
    00637 void rb_thread_reset_timer_thread(void);
    00638 void *rb_thread_call_with_gvl(void *(*func)(void *), void *data1);
    00639 int ruby_thread_has_gvl_p(void);
    00640 VALUE rb_make_backtrace(void);
    00641 typedef int rb_backtrace_iter_func(void *, VALUE, int, VALUE);
    00642 int rb_backtrace_each(rb_backtrace_iter_func *iter, void *arg);
    00643 rb_control_frame_t *rb_vm_get_ruby_level_next_cfp(rb_thread_t *th, rb_control_frame_t *cfp);
    00644 int rb_vm_get_sourceline(const rb_control_frame_t *);
    00645 VALUE rb_name_err_mesg_new(VALUE obj, VALUE mesg, VALUE recv, VALUE method);
    00646
    00647 NOINLINE(void rb_gc_save_machine_context(rb_thread_t *));
    00648
    00649 #define sysstack_error GET_VM()->special_exceptions[ruby_error_sysstack]
    00650
    00651 VALUE rb_str_resurrect(VALUE str);
    00652 VALUE rb_ary_resurrect(VALUE ary);
    00653
    00654 /* for thread */
    00655
    00656 #if RUBY_VM_THREAD_MODEL == 2
    00657 RUBY_EXTERN rb_thread_t *ruby_current_thread;
    00658 extern rb_vm_t *ruby_current_vm;
    00659
    00660 #define GET_VM() ruby_current_vm
    00661 #define GET_THREAD() ruby_current_thread
    00662 #define rb_thread_set_current_raw(th) (void)(ruby_current_thread = (th))
    00663 #define rb_thread_set_current(th) do { \
    00664     rb_thread_set_current_raw(th); \
    00665     th->vm->running_thread = th; \
    00666 } while (0)
    00667
    00668 #else
    00669 #error "unsupported thread model"
    00670 #endif
    00671
    00672 #define RUBY_VM_SET_INTERRUPT(th) ((th)->interrupt_flag |= 0x02)
    00673 #define RUBY_VM_SET_TIMER_INTERRUPT(th) ((th)->interrupt_flag |= 0x01)
    00674 #define RUBY_VM_SET_FINALIZER_INTERRUPT(th) ((th)->interrupt_flag |= 0x04)
    00675 #define RUBY_VM_INTERRUPTED(th) ((th)->interrupt_flag & 0x02)
    00676
    00677 void rb_threadptr_check_signal(rb_thread_t *mth);
    00678 void rb_threadptr_signal_raise(rb_thread_t *th, int sig);
    00679 void rb_threadptr_signal_exit(rb_thread_t *th);
    00680 void rb_threadptr_execute_interrupts(rb_thread_t *);
    00681
    00682 void rb_thread_lock_unlock(rb_thread_lock_t *);
    00683 void rb_thread_lock_destroy(rb_thread_lock_t *);
    00684
    00685 #define RUBY_VM_CHECK_INTS_TH(th) do { \
    00686   if (UNLIKELY(th->interrupt_flag)) { \
    00687     rb_threadptr_execute_interrupts(th); \
    00688   } \
    00689 } while (0)
    00690
    00691 #define RUBY_VM_CHECK_INTS() \
    00692   RUBY_VM_CHECK_INTS_TH(GET_THREAD())
    00693
    00694 /* tracer */
    00695 void
    00696 rb_threadptr_exec_event_hooks(rb_thread_t *th, rb_event_flag_t flag, VALUE self, ID id, VALUE klass);
    00697
    00698 #define EXEC_EVENT_HOOK(th, flag, self, id, klass) do { \
    00699     rb_event_flag_t wait_event__ = th->event_flags; \
    00700     if (UNLIKELY(wait_event__)) { \
    00701         if (wait_event__ & (flag | RUBY_EVENT_VM)) { \
    00702             rb_threadptr_exec_event_hooks(th, flag, self, id, klass); \
    00703         } \
    00704     } \
    00705 } while (0)
    00706
    00707 #endif /* RUBY_VM_CORE_H */
    00708