Ruby
2.0.0p247(2013-06-27revision41674)
|
00001 /********************************************************************** 00002 00003 vm_core.h - 00004 00005 $Author: nagachika $ 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 "vm_debug.h" 00022 #include "vm_opts.h" 00023 #include "id.h" 00024 #include "method.h" 00025 #include "ruby_atomic.h" 00026 00027 #if defined(_WIN32) 00028 #include "thread_win32.h" 00029 #elif defined(HAVE_PTHREAD_H) 00030 #include "thread_pthread.h" 00031 #else 00032 #error "unsupported thread type" 00033 #endif 00034 00035 #ifndef ENABLE_VM_OBJSPACE 00036 #ifdef _WIN32 00037 /* 00038 * TODO: object space independent st_table. 00039 * socklist needs st_table in rb_w32_sysinit(), before object space 00040 * initialization. 00041 * It is too early now to change st_hash_type, since it breaks binary 00042 * compatibility. 00043 */ 00044 #define ENABLE_VM_OBJSPACE 0 00045 #else 00046 #define ENABLE_VM_OBJSPACE 1 00047 #endif 00048 #endif 00049 00050 #include <setjmp.h> 00051 #include <signal.h> 00052 00053 #ifndef NSIG 00054 # define NSIG (_SIGMAX + 1) /* For QNX */ 00055 #endif 00056 00057 #define RUBY_NSIG NSIG 00058 00059 #ifdef HAVE_STDARG_PROTOTYPES 00060 #include <stdarg.h> 00061 #define va_init_list(a,b) va_start((a),(b)) 00062 #else 00063 #include <varargs.h> 00064 #define va_init_list(a,b) va_start((a)) 00065 #endif 00066 00067 #if defined(SIGSEGV) && defined(HAVE_SIGALTSTACK) && defined(SA_SIGINFO) && !defined(__NetBSD__) 00068 #define USE_SIGALTSTACK 00069 #endif 00070 00071 /*****************/ 00072 /* configuration */ 00073 /*****************/ 00074 00075 /* gcc ver. check */ 00076 #if defined(__GNUC__) && __GNUC__ >= 2 00077 00078 #if OPT_TOKEN_THREADED_CODE 00079 #if OPT_DIRECT_THREADED_CODE 00080 #undef OPT_DIRECT_THREADED_CODE 00081 #endif 00082 #endif 00083 00084 #else /* defined(__GNUC__) && __GNUC__ >= 2 */ 00085 00086 /* disable threaded code options */ 00087 #if OPT_DIRECT_THREADED_CODE 00088 #undef OPT_DIRECT_THREADED_CODE 00089 #endif 00090 #if OPT_TOKEN_THREADED_CODE 00091 #undef OPT_TOKEN_THREADED_CODE 00092 #endif 00093 #endif 00094 00095 #ifdef __native_client__ 00096 #undef OPT_DIRECT_THREADED_CODE 00097 #endif 00098 00099 /* call threaded code */ 00100 #if OPT_CALL_THREADED_CODE 00101 #if OPT_DIRECT_THREADED_CODE 00102 #undef OPT_DIRECT_THREADED_CODE 00103 #endif /* OPT_DIRECT_THREADED_CODE */ 00104 #if OPT_STACK_CACHING 00105 #undef OPT_STACK_CACHING 00106 #endif /* OPT_STACK_CACHING */ 00107 #endif /* OPT_CALL_THREADED_CODE */ 00108 00109 /* likely */ 00110 #if __GNUC__ >= 3 00111 #define LIKELY(x) (__builtin_expect((x), 1)) 00112 #define UNLIKELY(x) (__builtin_expect((x), 0)) 00113 #else /* __GNUC__ >= 3 */ 00114 #define LIKELY(x) (x) 00115 #define UNLIKELY(x) (x) 00116 #endif /* __GNUC__ >= 3 */ 00117 00118 #if __GNUC__ >= 3 00119 #define UNINITIALIZED_VAR(x) x = x 00120 #else 00121 #define UNINITIALIZED_VAR(x) x 00122 #endif 00123 00124 typedef unsigned long rb_num_t; 00125 00126 /* iseq data type */ 00127 00128 struct iseq_compile_data_ensure_node_stack; 00129 00130 typedef struct rb_compile_option_struct rb_compile_option_t; 00131 00132 struct iseq_inline_cache_entry { 00133 VALUE ic_vmstat; 00134 VALUE ic_class; 00135 union { 00136 VALUE value; 00137 long index; 00138 } ic_value; 00139 }; 00140 00141 /* to avoid warning */ 00142 struct rb_thread_struct; 00143 struct rb_control_frame_struct; 00144 00145 /* rb_call_info_t contains calling information including inline cache */ 00146 typedef struct rb_call_info_struct { 00147 /* fixed at compile time */ 00148 ID mid; 00149 VALUE flag; 00150 int orig_argc; 00151 rb_iseq_t *blockiseq; 00152 00153 /* inline cache: keys */ 00154 VALUE vmstat; 00155 VALUE klass; 00156 00157 /* inline cache: values */ 00158 const rb_method_entry_t *me; 00159 VALUE defined_class; 00160 00161 /* temporary values for method calling */ 00162 int argc; 00163 struct rb_block_struct *blockptr; 00164 VALUE recv; 00165 union { 00166 int opt_pc; /* used by iseq */ 00167 long index; /* used by ivar */ 00168 int missing_reason; /* used by method_missing */ 00169 int inc_sp; /* used by cfunc */ 00170 } aux; 00171 00172 VALUE (*call)(struct rb_thread_struct *th, struct rb_control_frame_struct *cfp, struct rb_call_info_struct *ci); 00173 } rb_call_info_t; 00174 00175 #if 1 00176 #define GetCoreDataFromValue(obj, type, ptr) do { \ 00177 (ptr) = (type*)DATA_PTR(obj); \ 00178 } while (0) 00179 #else 00180 #define GetCoreDataFromValue(obj, type, ptr) Data_Get_Struct((obj), type, (ptr)) 00181 #endif 00182 00183 #define GetISeqPtr(obj, ptr) \ 00184 GetCoreDataFromValue((obj), rb_iseq_t, (ptr)) 00185 00186 typedef struct rb_iseq_location_struct { 00187 VALUE path; 00188 VALUE absolute_path; 00189 VALUE base_label; 00190 VALUE label; 00191 size_t first_lineno; 00192 } rb_iseq_location_t; 00193 00194 struct rb_iseq_struct; 00195 00196 struct rb_iseq_struct { 00197 /***************/ 00198 /* static data */ 00199 /***************/ 00200 00201 enum iseq_type { 00202 ISEQ_TYPE_TOP, 00203 ISEQ_TYPE_METHOD, 00204 ISEQ_TYPE_BLOCK, 00205 ISEQ_TYPE_CLASS, 00206 ISEQ_TYPE_RESCUE, 00207 ISEQ_TYPE_ENSURE, 00208 ISEQ_TYPE_EVAL, 00209 ISEQ_TYPE_MAIN, 00210 ISEQ_TYPE_DEFINED_GUARD 00211 } type; /* instruction sequence type */ 00212 00213 rb_iseq_location_t location; 00214 00215 VALUE *iseq; /* iseq (insn number and operands) */ 00216 VALUE *iseq_encoded; /* encoded iseq */ 00217 unsigned long iseq_size; 00218 VALUE mark_ary; /* Array: includes operands which should be GC marked */ 00219 VALUE coverage; /* coverage array */ 00220 00221 /* insn info, must be freed */ 00222 struct iseq_line_info_entry *line_info_table; 00223 size_t line_info_size; 00224 00225 ID *local_table; /* must free */ 00226 int local_table_size; 00227 00228 /* sizeof(vars) + 1 */ 00229 int local_size; 00230 00231 struct iseq_inline_cache_entry *ic_entries; 00232 int ic_size; 00233 00234 rb_call_info_t *callinfo_entries; 00235 int callinfo_size; 00236 00264 int argc; 00265 int arg_simple; 00266 int arg_rest; 00267 int arg_block; 00268 int arg_opts; 00269 int arg_post_len; 00270 int arg_post_start; 00271 int arg_size; 00272 VALUE *arg_opt_table; 00273 int arg_keyword; 00274 int arg_keyword_check; /* if this is true, raise an ArgumentError when unknown keyword argument is passed */ 00275 int arg_keywords; 00276 ID *arg_keyword_table; 00277 00278 size_t stack_max; /* for stack overflow check */ 00279 00280 /* catch table */ 00281 struct iseq_catch_table_entry *catch_table; 00282 int catch_table_size; 00283 00284 /* for child iseq */ 00285 struct rb_iseq_struct *parent_iseq; 00286 struct rb_iseq_struct *local_iseq; 00287 00288 /****************/ 00289 /* dynamic data */ 00290 /****************/ 00291 00292 VALUE self; 00293 VALUE orig; /* non-NULL if its data have origin */ 00294 00295 /* block inlining */ 00296 /* 00297 * NODE *node; 00298 * void *special_block_builder; 00299 * void *cached_special_block_builder; 00300 * VALUE cached_special_block; 00301 */ 00302 00303 /* klass/module nest information stack (cref) */ 00304 NODE *cref_stack; 00305 VALUE klass; 00306 00307 /* misc */ 00308 ID defined_method_id; /* for define_method */ 00309 rb_num_t flip_cnt; 00310 00311 /* used at compile time */ 00312 struct iseq_compile_data *compile_data; 00313 }; 00314 00315 enum ruby_special_exceptions { 00316 ruby_error_reenter, 00317 ruby_error_nomemory, 00318 ruby_error_sysstack, 00319 ruby_error_closed_stream, 00320 ruby_special_error_count 00321 }; 00322 00323 #define GetVMPtr(obj, ptr) \ 00324 GetCoreDataFromValue((obj), rb_vm_t, (ptr)) 00325 00326 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE 00327 struct rb_objspace; 00328 void rb_objspace_free(struct rb_objspace *); 00329 #endif 00330 00331 typedef struct rb_hook_list_struct { 00332 struct rb_event_hook_struct *hooks; 00333 rb_event_flag_t events; 00334 int need_clean; 00335 } rb_hook_list_t; 00336 00337 typedef struct rb_vm_struct { 00338 VALUE self; 00339 00340 rb_global_vm_lock_t gvl; 00341 rb_thread_lock_t thread_destruct_lock; 00342 00343 struct rb_thread_struct *main_thread; 00344 struct rb_thread_struct *running_thread; 00345 00346 st_table *living_threads; 00347 VALUE thgroup_default; 00348 00349 int running; 00350 int thread_abort_on_exception; 00351 int trace_running; 00352 volatile int sleeper; 00353 00354 /* object management */ 00355 VALUE mark_object_ary; 00356 00357 VALUE special_exceptions[ruby_special_error_count]; 00358 00359 /* load */ 00360 VALUE top_self; 00361 VALUE load_path; 00362 VALUE load_path_snapshot; 00363 VALUE load_path_check_cache; 00364 VALUE expanded_load_path; 00365 VALUE loaded_features; 00366 VALUE loaded_features_snapshot; 00367 struct st_table *loaded_features_index; 00368 struct st_table *loading_table; 00369 00370 /* signal */ 00371 struct { 00372 VALUE cmd; 00373 int safe; 00374 } trap_list[RUBY_NSIG]; 00375 00376 /* hook */ 00377 rb_hook_list_t event_hooks; 00378 00379 int src_encoding_index; 00380 00381 VALUE verbose, debug, progname; 00382 VALUE coverages; 00383 00384 struct unlinked_method_entry_list_entry *unlinked_method_entry_list; 00385 00386 #if defined(ENABLE_VM_OBJSPACE) && ENABLE_VM_OBJSPACE 00387 struct rb_objspace *objspace; 00388 #endif 00389 00390 /* 00391 * @shyouhei notes that this is not for storing normal Ruby 00392 * objects so do *NOT* mark this when you GC. 00393 */ 00394 struct RArray at_exit; 00395 00396 VALUE *defined_strings; 00397 00398 /* params */ 00399 struct { /* size in byte */ 00400 size_t thread_vm_stack_size; 00401 size_t thread_machine_stack_size; 00402 size_t fiber_vm_stack_size; 00403 size_t fiber_machine_stack_size; 00404 } default_params; 00405 } rb_vm_t; 00406 00407 /* default values */ 00408 00409 #define RUBY_VM_SIZE_ALIGN 4096 00410 00411 #define RUBY_VM_THREAD_VM_STACK_SIZE ( 128 * 1024 * sizeof(VALUE)) /* 512 KB or 1024 KB */ 00412 #define RUBY_VM_THREAD_VM_STACK_SIZE_MIN ( 2 * 1024 * sizeof(VALUE)) /* 8 KB or 16 KB */ 00413 #define RUBY_VM_THREAD_MACHINE_STACK_SIZE ( 128 * 1024 * sizeof(VALUE)) /* 512 KB or 1024 KB */ 00414 #define RUBY_VM_THREAD_MACHINE_STACK_SIZE_MIN ( 16 * 1024 * sizeof(VALUE)) /* 64 KB or 128 KB */ 00415 00416 #define RUBY_VM_FIBER_VM_STACK_SIZE ( 16 * 1024 * sizeof(VALUE)) /* 64 KB or 128 KB */ 00417 #define RUBY_VM_FIBER_VM_STACK_SIZE_MIN ( 2 * 1024 * sizeof(VALUE)) /* 8 KB or 16 KB */ 00418 #define RUBY_VM_FIBER_MACHINE_STACK_SIZE ( 64 * 1024 * sizeof(VALUE)) /* 256 KB or 512 KB */ 00419 #define RUBY_VM_FIBER_MACHINE_STACK_SIZE_MIN ( 16 * 1024 * sizeof(VALUE)) /* 64 KB or 128 KB */ 00420 00421 #ifndef VM_DEBUG_BP_CHECK 00422 #define VM_DEBUG_BP_CHECK 0 00423 #endif 00424 00425 typedef struct rb_control_frame_struct { 00426 VALUE *pc; /* cfp[0] */ 00427 VALUE *sp; /* cfp[1] */ 00428 rb_iseq_t *iseq; /* cfp[2] */ 00429 VALUE flag; /* cfp[3] */ 00430 VALUE self; /* cfp[4] / block[0] */ 00431 VALUE klass; /* cfp[5] / block[1] */ 00432 VALUE *ep; /* cfp[6] / block[2] */ 00433 rb_iseq_t *block_iseq; /* cfp[7] / block[3] */ 00434 VALUE proc; /* cfp[8] / block[4] */ 00435 const rb_method_entry_t *me;/* cfp[9] */ 00436 00437 #if VM_DEBUG_BP_CHECK 00438 VALUE *bp_check; /* cfp[10] */ 00439 #endif 00440 } rb_control_frame_t; 00441 00442 typedef struct rb_block_struct { 00443 VALUE self; /* share with method frame if it's only block */ 00444 VALUE klass; /* share with method frame if it's only block */ 00445 VALUE *ep; /* share with method frame if it's only block */ 00446 rb_iseq_t *iseq; 00447 VALUE proc; 00448 } rb_block_t; 00449 00450 extern const rb_data_type_t ruby_threadptr_data_type; 00451 00452 #define GetThreadPtr(obj, ptr) \ 00453 TypedData_Get_Struct((obj), rb_thread_t, &ruby_threadptr_data_type, (ptr)) 00454 00455 enum rb_thread_status { 00456 THREAD_RUNNABLE, 00457 THREAD_STOPPED, 00458 THREAD_STOPPED_FOREVER, 00459 THREAD_KILLED 00460 }; 00461 00462 typedef RUBY_JMP_BUF rb_jmpbuf_t; 00463 00464 /* 00465 the members which are written in TH_PUSH_TAG() should be placed at 00466 the beginning and the end, so that entire region is accessible. 00467 */ 00468 struct rb_vm_tag { 00469 VALUE tag; 00470 VALUE retval; 00471 rb_jmpbuf_t buf; 00472 struct rb_vm_tag *prev; 00473 }; 00474 00475 struct rb_vm_protect_tag { 00476 struct rb_vm_protect_tag *prev; 00477 }; 00478 00479 struct rb_unblock_callback { 00480 rb_unblock_function_t *func; 00481 void *arg; 00482 }; 00483 00484 struct rb_mutex_struct; 00485 00486 struct rb_thread_struct; 00487 typedef struct rb_thread_list_struct{ 00488 struct rb_thread_list_struct *next; 00489 struct rb_thread_struct *th; 00490 } rb_thread_list_t; 00491 00492 00493 typedef struct rb_thread_struct { 00494 VALUE self; 00495 rb_vm_t *vm; 00496 00497 /* execution information */ 00498 VALUE *stack; /* must free, must mark */ 00499 size_t stack_size; /* size in word (byte size / sizeof(VALUE)) */ 00500 rb_control_frame_t *cfp; 00501 int safe_level; 00502 int raised_flag; 00503 VALUE last_status; /* $? */ 00504 00505 /* passing state */ 00506 int state; 00507 00508 int waiting_fd; 00509 00510 /* for rb_iterate */ 00511 const rb_block_t *passed_block; 00512 00513 /* for bmethod */ 00514 const rb_method_entry_t *passed_me; 00515 00516 /* for cfunc */ 00517 rb_call_info_t *passed_ci; 00518 00519 /* for load(true) */ 00520 VALUE top_self; 00521 VALUE top_wrapper; 00522 00523 /* eval env */ 00524 rb_block_t *base_block; 00525 00526 VALUE *root_lep; 00527 VALUE root_svar; 00528 00529 /* thread control */ 00530 rb_thread_id_t thread_id; 00531 enum rb_thread_status status; 00532 int to_kill; 00533 int priority; 00534 00535 native_thread_data_t native_thread_data; 00536 void *blocking_region_buffer; 00537 00538 VALUE thgroup; 00539 VALUE value; 00540 00541 /* temporary place of errinfo */ 00542 VALUE errinfo; 00543 00544 /* temporary place of retval on OPT_CALL_THREADED_CODE */ 00545 #if OPT_CALL_THREADED_CODE 00546 VALUE retval; 00547 #endif 00548 00549 /* async errinfo queue */ 00550 VALUE pending_interrupt_queue; 00551 int pending_interrupt_queue_checked; 00552 VALUE pending_interrupt_mask_stack; 00553 00554 rb_atomic_t interrupt_flag; 00555 unsigned long interrupt_mask; 00556 rb_thread_lock_t interrupt_lock; 00557 struct rb_unblock_callback unblock; 00558 VALUE locking_mutex; 00559 struct rb_mutex_struct *keeping_mutexes; 00560 00561 struct rb_vm_tag *tag; 00562 struct rb_vm_protect_tag *protect_tag; 00563 00570 int parse_in_eval; 00571 00576 int mild_compile_error; 00577 00578 /* storage */ 00579 st_table *local_storage; 00580 00581 rb_thread_list_t *join_list; 00582 00583 VALUE first_proc; 00584 VALUE first_args; 00585 VALUE (*first_func)(ANYARGS); 00586 00587 /* for GC */ 00588 VALUE *machine_stack_start; 00589 VALUE *machine_stack_end; 00590 size_t machine_stack_maxsize; 00591 #ifdef __ia64 00592 VALUE *machine_register_stack_start; 00593 VALUE *machine_register_stack_end; 00594 size_t machine_register_stack_maxsize; 00595 #endif 00596 jmp_buf machine_regs; 00597 int mark_stack_len; 00598 00599 /* statistics data for profiler */ 00600 VALUE stat_insn_usage; 00601 00602 /* tracer */ 00603 rb_hook_list_t event_hooks; 00604 struct rb_trace_arg_struct *trace_arg; /* trace information */ 00605 00606 /* fiber */ 00607 VALUE fiber; 00608 VALUE root_fiber; 00609 rb_jmpbuf_t root_jmpbuf; 00610 00611 /* misc */ 00612 int method_missing_reason; 00613 int abort_on_exception; 00614 #ifdef USE_SIGALTSTACK 00615 void *altstack; 00616 #endif 00617 unsigned long running_time_us; 00618 } rb_thread_t; 00619 00620 typedef enum { 00621 VM_DEFINECLASS_TYPE_CLASS = 0x00, 00622 VM_DEFINECLASS_TYPE_SINGLETON_CLASS = 0x01, 00623 VM_DEFINECLASS_TYPE_MODULE = 0x02, 00624 /* 0x03..0x06 is reserved */ 00625 VM_DEFINECLASS_TYPE_MASK = 0x07, 00626 } rb_vm_defineclass_type_t; 00627 00628 #define VM_DEFINECLASS_TYPE(x) ((rb_vm_defineclass_type_t)(x) & VM_DEFINECLASS_TYPE_MASK) 00629 #define VM_DEFINECLASS_FLAG_SCOPED 0x08 00630 #define VM_DEFINECLASS_FLAG_HAS_SUPERCLASS 0x10 00631 #define VM_DEFINECLASS_SCOPED_P(x) ((x) & VM_DEFINECLASS_FLAG_SCOPED) 00632 #define VM_DEFINECLASS_HAS_SUPERCLASS_P(x) \ 00633 ((x) & VM_DEFINECLASS_FLAG_HAS_SUPERCLASS) 00634 00635 /* iseq.c */ 00636 #if defined __GNUC__ && __GNUC__ >= 4 00637 #pragma GCC visibility push(default) 00638 #endif 00639 00640 /* node -> iseq */ 00641 VALUE rb_iseq_new(NODE*, VALUE, VALUE, VALUE, VALUE, enum iseq_type); 00642 VALUE rb_iseq_new_top(NODE *node, VALUE name, VALUE path, VALUE absolute_path, VALUE parent); 00643 VALUE rb_iseq_new_main(NODE *node, VALUE path, VALUE absolute_path); 00644 VALUE rb_iseq_new_with_bopt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, enum iseq_type, VALUE); 00645 VALUE rb_iseq_new_with_opt(NODE*, VALUE, VALUE, VALUE, VALUE, VALUE, enum iseq_type, const rb_compile_option_t*); 00646 00647 /* src -> iseq */ 00648 VALUE rb_iseq_compile(VALUE src, VALUE file, VALUE line); 00649 VALUE rb_iseq_compile_on_base(VALUE src, VALUE file, VALUE line, rb_block_t *base_block); 00650 VALUE rb_iseq_compile_with_option(VALUE src, VALUE file, VALUE absolute_path, VALUE line, rb_block_t *base_block, VALUE opt); 00651 00652 VALUE rb_iseq_disasm(VALUE self); 00653 int rb_iseq_disasm_insn(VALUE str, VALUE *iseqval, size_t pos, rb_iseq_t *iseq, VALUE child); 00654 const char *ruby_node_name(int node); 00655 int rb_iseq_first_lineno(const rb_iseq_t *iseq); 00656 00657 RUBY_EXTERN VALUE rb_cISeq; 00658 RUBY_EXTERN VALUE rb_cRubyVM; 00659 RUBY_EXTERN VALUE rb_cEnv; 00660 RUBY_EXTERN VALUE rb_mRubyVMFrozenCore; 00661 #if defined __GNUC__ && __GNUC__ >= 4 00662 #pragma GCC visibility pop 00663 #endif 00664 00665 #define GetProcPtr(obj, ptr) \ 00666 GetCoreDataFromValue((obj), rb_proc_t, (ptr)) 00667 00668 typedef struct { 00669 rb_block_t block; 00670 00671 VALUE envval; /* for GC mark */ 00672 VALUE blockprocval; 00673 int safe_level; 00674 int is_from_method; 00675 int is_lambda; 00676 } rb_proc_t; 00677 00678 #define GetEnvPtr(obj, ptr) \ 00679 GetCoreDataFromValue((obj), rb_env_t, (ptr)) 00680 00681 typedef struct { 00682 VALUE *env; 00683 int env_size; 00684 int local_size; 00685 VALUE prev_envval; /* for GC mark */ 00686 rb_block_t block; 00687 } rb_env_t; 00688 00689 #define GetBindingPtr(obj, ptr) \ 00690 GetCoreDataFromValue((obj), rb_binding_t, (ptr)) 00691 00692 typedef struct { 00693 VALUE env; 00694 VALUE path; 00695 unsigned short first_lineno; 00696 } rb_binding_t; 00697 00698 /* used by compile time and send insn */ 00699 00700 enum vm_check_match_type { 00701 VM_CHECKMATCH_TYPE_WHEN = 1, 00702 VM_CHECKMATCH_TYPE_CASE = 2, 00703 VM_CHECKMATCH_TYPE_RESCUE = 3 00704 }; 00705 00706 #define VM_CHECKMATCH_TYPE_MASK 0x03 00707 #define VM_CHECKMATCH_ARRAY 0x04 00708 00709 #define VM_CALL_ARGS_SPLAT (0x01 << 1) /* m(*args) */ 00710 #define VM_CALL_ARGS_BLOCKARG (0x01 << 2) /* m(&block) */ 00711 #define VM_CALL_FCALL (0x01 << 3) /* m(...) */ 00712 #define VM_CALL_VCALL (0x01 << 4) /* m */ 00713 #define VM_CALL_TAILCALL (0x01 << 5) /* located at tail position */ 00714 #define VM_CALL_SUPER (0x01 << 6) /* super */ 00715 #define VM_CALL_OPT_SEND (0x01 << 7) /* internal flag */ 00716 #define VM_CALL_ARGS_SKIP_SETUP (0x01 << 8) /* (flag & (SPLAT|BLOCKARG)) && blockiseq == 0 */ 00717 00718 enum vm_special_object_type { 00719 VM_SPECIAL_OBJECT_VMCORE = 1, 00720 VM_SPECIAL_OBJECT_CBASE, 00721 VM_SPECIAL_OBJECT_CONST_BASE 00722 }; 00723 00724 #define VM_FRAME_MAGIC_METHOD 0x11 00725 #define VM_FRAME_MAGIC_BLOCK 0x21 00726 #define VM_FRAME_MAGIC_CLASS 0x31 00727 #define VM_FRAME_MAGIC_TOP 0x41 00728 #define VM_FRAME_MAGIC_CFUNC 0x61 00729 #define VM_FRAME_MAGIC_PROC 0x71 00730 #define VM_FRAME_MAGIC_IFUNC 0x81 00731 #define VM_FRAME_MAGIC_EVAL 0x91 00732 #define VM_FRAME_MAGIC_LAMBDA 0xa1 00733 #define VM_FRAME_MAGIC_MASK_BITS 8 00734 #define VM_FRAME_MAGIC_MASK (~(~0<<VM_FRAME_MAGIC_MASK_BITS)) 00735 00736 #define VM_FRAME_TYPE(cfp) ((cfp)->flag & VM_FRAME_MAGIC_MASK) 00737 00738 /* other frame flag */ 00739 #define VM_FRAME_FLAG_PASSED 0x0100 00740 #define VM_FRAME_FLAG_FINISH 0x0200 00741 #define VM_FRAME_TYPE_FINISH_P(cfp) (((cfp)->flag & VM_FRAME_FLAG_FINISH) != 0) 00742 00743 #define RUBYVM_CFUNC_FRAME_P(cfp) \ 00744 (VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC) 00745 00746 /* inline cache */ 00747 typedef struct iseq_inline_cache_entry *IC; 00748 typedef rb_call_info_t *CALL_INFO; 00749 00750 void rb_vm_change_state(void); 00751 00752 typedef VALUE CDHASH; 00753 00754 #ifndef FUNC_FASTCALL 00755 #define FUNC_FASTCALL(x) x 00756 #endif 00757 00758 typedef rb_control_frame_t * 00759 (FUNC_FASTCALL(*rb_insn_func_t))(rb_thread_t *, rb_control_frame_t *); 00760 00761 #define GC_GUARDED_PTR(p) ((VALUE)((VALUE)(p) | 0x01)) 00762 #define GC_GUARDED_PTR_REF(p) ((void *)(((VALUE)(p)) & ~0x03)) 00763 #define GC_GUARDED_PTR_P(p) (((VALUE)(p)) & 0x01) 00764 00765 /* 00766 * block frame: 00767 * ep[ 0]: prev frame 00768 * ep[-1]: CREF (for *_eval) 00769 * 00770 * method frame: 00771 * ep[ 0]: block pointer (ptr | VM_ENVVAL_BLOCK_PTR_FLAG) 00772 */ 00773 00774 #define VM_ENVVAL_BLOCK_PTR_FLAG 0x02 00775 #define VM_ENVVAL_BLOCK_PTR(v) (GC_GUARDED_PTR(v) | VM_ENVVAL_BLOCK_PTR_FLAG) 00776 #define VM_ENVVAL_BLOCK_PTR_P(v) ((v) & VM_ENVVAL_BLOCK_PTR_FLAG) 00777 #define VM_ENVVAL_PREV_EP_PTR(v) ((VALUE)GC_GUARDED_PTR(v)) 00778 #define VM_ENVVAL_PREV_EP_PTR_P(v) (!(VM_ENVVAL_BLOCK_PTR_P(v))) 00779 00780 #define VM_EP_PREV_EP(ep) ((VALUE *)GC_GUARDED_PTR_REF((ep)[0])) 00781 #define VM_EP_BLOCK_PTR(ep) ((rb_block_t *)GC_GUARDED_PTR_REF((ep)[0])) 00782 #define VM_EP_LEP_P(ep) VM_ENVVAL_BLOCK_PTR_P((ep)[0]) 00783 00784 VALUE *rb_vm_ep_local_ep(VALUE *ep); 00785 rb_block_t *rb_vm_control_frame_block_ptr(rb_control_frame_t *cfp); 00786 00787 #define RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp) ((cfp)+1) 00788 #define RUBY_VM_NEXT_CONTROL_FRAME(cfp) ((cfp)-1) 00789 #define RUBY_VM_END_CONTROL_FRAME(th) \ 00790 ((rb_control_frame_t *)((th)->stack + (th)->stack_size)) 00791 #define RUBY_VM_VALID_CONTROL_FRAME_P(cfp, ecfp) \ 00792 ((void *)(ecfp) > (void *)(cfp)) 00793 #define RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(th, cfp) \ 00794 (!RUBY_VM_VALID_CONTROL_FRAME_P((cfp), RUBY_VM_END_CONTROL_FRAME(th))) 00795 00796 #define RUBY_VM_IFUNC_P(ptr) (BUILTIN_TYPE(ptr) == T_NODE) 00797 #define RUBY_VM_NORMAL_ISEQ_P(ptr) \ 00798 ((ptr) && !RUBY_VM_IFUNC_P(ptr)) 00799 00800 #define RUBY_VM_GET_BLOCK_PTR_IN_CFP(cfp) ((rb_block_t *)(&(cfp)->self)) 00801 #define RUBY_VM_GET_CFP_FROM_BLOCK_PTR(b) \ 00802 ((rb_control_frame_t *)((VALUE *)(b) - 4)) 00803 /* magic number `4' is depend on rb_control_frame_t layout. */ 00804 00805 /* VM related object allocate functions */ 00806 VALUE rb_thread_alloc(VALUE klass); 00807 VALUE rb_proc_alloc(VALUE klass); 00808 00809 /* for debug */ 00810 extern void rb_vmdebug_stack_dump_raw(rb_thread_t *, rb_control_frame_t *); 00811 extern void rb_vmdebug_debug_print_pre(rb_thread_t *th, rb_control_frame_t *cfp); 00812 extern void rb_vmdebug_debug_print_post(rb_thread_t *th, rb_control_frame_t *cfp); 00813 00814 #define SDR() rb_vmdebug_stack_dump_raw(GET_THREAD(), GET_THREAD()->cfp) 00815 #define SDR2(cfp) rb_vmdebug_stack_dump_raw(GET_THREAD(), (cfp)) 00816 void rb_vm_bugreport(void); 00817 00818 /* functions about thread/vm execution */ 00819 #if defined __GNUC__ && __GNUC__ >= 4 00820 #pragma GCC visibility push(default) 00821 #endif 00822 VALUE rb_iseq_eval(VALUE iseqval); 00823 VALUE rb_iseq_eval_main(VALUE iseqval); 00824 #if defined __GNUC__ && __GNUC__ >= 4 00825 #pragma GCC visibility pop 00826 #endif 00827 int rb_thread_method_id_and_class(rb_thread_t *th, ID *idp, VALUE *klassp); 00828 00829 VALUE rb_vm_invoke_proc(rb_thread_t *th, rb_proc_t *proc, 00830 int argc, const VALUE *argv, const rb_block_t *blockptr); 00831 VALUE rb_vm_make_proc(rb_thread_t *th, const rb_block_t *block, VALUE klass); 00832 VALUE rb_vm_make_env_object(rb_thread_t *th, rb_control_frame_t *cfp); 00833 VALUE rb_binding_new_with_cfp(rb_thread_t *th, const rb_control_frame_t *src_cfp); 00834 void rb_vm_inc_const_missing_count(void); 00835 void rb_vm_gvl_destroy(rb_vm_t *vm); 00836 VALUE rb_vm_call(rb_thread_t *th, VALUE recv, VALUE id, int argc, 00837 const VALUE *argv, const rb_method_entry_t *me, 00838 VALUE defined_class); 00839 void rb_unlink_method_entry(rb_method_entry_t *me); 00840 void rb_gc_mark_unlinked_live_method_entries(void *pvm); 00841 00842 void rb_thread_start_timer_thread(void); 00843 void rb_thread_stop_timer_thread(int); 00844 void rb_thread_reset_timer_thread(void); 00845 void rb_thread_wakeup_timer_thread(void); 00846 00847 int ruby_thread_has_gvl_p(void); 00848 typedef int rb_backtrace_iter_func(void *, VALUE, int, VALUE); 00849 rb_control_frame_t *rb_vm_get_ruby_level_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp); 00850 rb_control_frame_t *rb_vm_get_binding_creatable_next_cfp(rb_thread_t *th, const rb_control_frame_t *cfp); 00851 int rb_vm_get_sourceline(const rb_control_frame_t *); 00852 VALUE rb_name_err_mesg_new(VALUE obj, VALUE mesg, VALUE recv, VALUE method); 00853 void rb_vm_stack_to_heap(rb_thread_t *th); 00854 void ruby_thread_init_stack(rb_thread_t *th); 00855 int rb_vm_control_frame_id_and_class(const rb_control_frame_t *cfp, ID *idp, VALUE *klassp); 00856 00857 void rb_gc_mark_machine_stack(rb_thread_t *th); 00858 00859 int rb_autoloading_value(VALUE mod, ID id, VALUE* value); 00860 00861 #define sysstack_error GET_VM()->special_exceptions[ruby_error_sysstack] 00862 00863 #define CHECK_VM_STACK_OVERFLOW(cfp, margin) do \ 00864 if ((VALUE *)((char *)(((VALUE *)(cfp)->sp) + (margin)) + sizeof(rb_control_frame_t)) >= ((VALUE *)(cfp))) { \ 00865 vm_stackoverflow(); \ 00866 } \ 00867 while (0) 00868 00869 /* for thread */ 00870 00871 #if RUBY_VM_THREAD_MODEL == 2 00872 extern rb_thread_t *ruby_current_thread; 00873 extern rb_vm_t *ruby_current_vm; 00874 extern rb_event_flag_t ruby_vm_event_flags; 00875 00876 #define GET_VM() ruby_current_vm 00877 00878 #ifndef OPT_CALL_CFUNC_WITHOUT_FRAME 00879 #define OPT_CALL_CFUNC_WITHOUT_FRAME 0 00880 #endif 00881 00882 static inline rb_thread_t * 00883 GET_THREAD(void) 00884 { 00885 rb_thread_t *th = ruby_current_thread; 00886 #if OPT_CALL_CFUNC_WITHOUT_FRAME 00887 if (UNLIKELY(th->passed_ci != 0)) { 00888 void vm_call_cfunc_push_frame(rb_thread_t *th); 00889 vm_call_cfunc_push_frame(th); 00890 } 00891 #endif 00892 return th; 00893 } 00894 00895 #define rb_thread_set_current_raw(th) (void)(ruby_current_thread = (th)) 00896 #define rb_thread_set_current(th) do { \ 00897 if ((th)->vm->running_thread != (th)) { \ 00898 (th)->running_time_us = 0; \ 00899 } \ 00900 rb_thread_set_current_raw(th); \ 00901 (th)->vm->running_thread = (th); \ 00902 } while (0) 00903 00904 #else 00905 #error "unsupported thread model" 00906 #endif 00907 00908 enum { 00909 TIMER_INTERRUPT_MASK = 0x01, 00910 PENDING_INTERRUPT_MASK = 0x02, 00911 FINALIZER_INTERRUPT_MASK = 0x04, 00912 TRAP_INTERRUPT_MASK = 0x08 00913 }; 00914 00915 #define RUBY_VM_SET_TIMER_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, TIMER_INTERRUPT_MASK) 00916 #define RUBY_VM_SET_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, PENDING_INTERRUPT_MASK) 00917 #define RUBY_VM_SET_FINALIZER_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, FINALIZER_INTERRUPT_MASK) 00918 #define RUBY_VM_SET_TRAP_INTERRUPT(th) ATOMIC_OR((th)->interrupt_flag, TRAP_INTERRUPT_MASK) 00919 #define RUBY_VM_INTERRUPTED(th) ((th)->interrupt_flag & ~(th)->interrupt_mask & (PENDING_INTERRUPT_MASK|TRAP_INTERRUPT_MASK)) 00920 #define RUBY_VM_INTERRUPTED_ANY(th) ((th)->interrupt_flag & ~(th)->interrupt_mask) 00921 00922 int rb_signal_buff_size(void); 00923 void rb_signal_exec(rb_thread_t *th, int sig); 00924 void rb_threadptr_check_signal(rb_thread_t *mth); 00925 void rb_threadptr_signal_raise(rb_thread_t *th, int sig); 00926 void rb_threadptr_signal_exit(rb_thread_t *th); 00927 void rb_threadptr_execute_interrupts(rb_thread_t *, int); 00928 void rb_threadptr_interrupt(rb_thread_t *th); 00929 void rb_threadptr_unlock_all_locking_mutexes(rb_thread_t *th); 00930 void rb_threadptr_pending_interrupt_clear(rb_thread_t *th); 00931 void rb_threadptr_pending_interrupt_enque(rb_thread_t *th, VALUE v); 00932 int rb_threadptr_pending_interrupt_active_p(rb_thread_t *th); 00933 00934 void rb_thread_lock_unlock(rb_thread_lock_t *); 00935 void rb_thread_lock_destroy(rb_thread_lock_t *); 00936 00937 #define RUBY_VM_CHECK_INTS_BLOCKING(th) do { \ 00938 if (UNLIKELY(!rb_threadptr_pending_interrupt_empty_p(th))) { \ 00939 th->pending_interrupt_queue_checked = 0; \ 00940 RUBY_VM_SET_INTERRUPT(th); \ 00941 rb_threadptr_execute_interrupts(th, 1); \ 00942 } \ 00943 else if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(th))) { \ 00944 rb_threadptr_execute_interrupts(th, 1); \ 00945 } \ 00946 } while (0) 00947 00948 #define RUBY_VM_CHECK_INTS(th) do { \ 00949 if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(th))) { \ 00950 rb_threadptr_execute_interrupts(th, 0); \ 00951 } \ 00952 } while (0) 00953 00954 /* tracer */ 00955 struct rb_trace_arg_struct { 00956 rb_event_flag_t event; 00957 rb_thread_t *th; 00958 rb_control_frame_t *cfp; 00959 VALUE self; 00960 ID id; 00961 VALUE klass; 00962 VALUE data; 00963 00964 int klass_solved; 00965 00966 /* calc from cfp */ 00967 int lineno; 00968 VALUE path; 00969 }; 00970 00971 void rb_threadptr_exec_event_hooks(struct rb_trace_arg_struct *trace_arg); 00972 void rb_threadptr_exec_event_hooks_and_pop_frame(struct rb_trace_arg_struct *trace_arg); 00973 00974 #define EXEC_EVENT_HOOK_ORIG(th_, flag_, self_, id_, klass_, data_, pop_p_) do { \ 00975 if (UNLIKELY(ruby_vm_event_flags & (flag_))) { \ 00976 if (((th)->event_hooks.events | (th)->vm->event_hooks.events) & (flag_)) { \ 00977 struct rb_trace_arg_struct trace_arg; \ 00978 trace_arg.event = (flag_); \ 00979 trace_arg.th = (th_); \ 00980 trace_arg.cfp = (trace_arg.th)->cfp; \ 00981 trace_arg.self = (self_); \ 00982 trace_arg.id = (id_); \ 00983 trace_arg.klass = (klass_); \ 00984 trace_arg.data = (data_); \ 00985 trace_arg.path = Qundef; \ 00986 trace_arg.klass_solved = 0; \ 00987 if (pop_p_) rb_threadptr_exec_event_hooks_and_pop_frame(&trace_arg); \ 00988 else rb_threadptr_exec_event_hooks(&trace_arg); \ 00989 } \ 00990 } \ 00991 } while (0) 00992 00993 #define EXEC_EVENT_HOOK(th_, flag_, self_, id_, klass_, data_) \ 00994 EXEC_EVENT_HOOK_ORIG(th_, flag_, self_, id_, klass_, data_, 0) 00995 00996 #define EXEC_EVENT_HOOK_AND_POP_FRAME(th_, flag_, self_, id_, klass_, data_) \ 00997 EXEC_EVENT_HOOK_ORIG(th_, flag_, self_, id_, klass_, data_, 1) 00998 00999 #if defined __GNUC__ && __GNUC__ >= 4 01000 #pragma GCC visibility push(default) 01001 #endif 01002 01003 int rb_thread_check_trap_pending(void); 01004 01005 extern VALUE rb_get_coverages(void); 01006 extern void rb_set_coverages(VALUE); 01007 extern void rb_reset_coverages(void); 01008 01009 #if defined __GNUC__ && __GNUC__ >= 4 01010 #pragma GCC visibility pop 01011 #endif 01012 01013 #endif /* RUBY_VM_CORE_H */ 01014