eval.c


DEFINITIONS

This source file includes following functions.
  1. rb_secure
  2. rb_check_safe_str
  3. print_undef
  4. rb_clear_cache
  5. rb_clear_cache_by_id
  6. rb_clear_cache_by_class
  7. rb_add_method
  8. search_method
  9. rb_get_method_body
  10. remove_method
  11. rb_remove_method
  12. rb_mod_remove_method
  13. rb_disable_super
  14. rb_enable_super
  15. rb_export_method
  16. rb_method_boundp
  17. rb_attr
  18. new_blktag
  19. new_dvar
  20. rb_dvar_defined
  21. rb_dvar_curr
  22. rb_dvar_ref
  23. rb_dvar_push
  24. dvar_asgn_internal
  25. dvar_asgn
  26. dvar_asgn_curr
  27. rb_svar
  28. ruby_set_current_source
  29. error_pos
  30. get_backtrace
  31. set_backtrace
  32. error_print
  33. ruby_init
  34. eval_node
  35. error_handle
  36. ruby_options
  37. ruby_finalize
  38. ruby_stop
  39. ruby_run
  40. compile_error
  41. rb_eval_string
  42. rb_eval_string_protect
  43. rb_eval_string_wrap
  44. localjump_error
  45. localjump_exitstatus
  46. jump_tag_but_local_jump
  47. rb_eval_cmd
  48. rb_trap_eval
  49. superclass
  50. ev_const_defined
  51. ev_const_get
  52. cvar_cbase
  53. rb_mod_nesting
  54. rb_mod_s_constants
  55. rb_frozen_class_p
  56. rb_undef
  57. rb_mod_undef_method
  58. rb_alias
  59. rb_mod_alias_method
  60. copy_node_scope
  61. TMP_ALLOC
  62. TMP_ALLOC
  63. arg_defined
  64. is_defined
  65. rb_obj_is_block
  66. rb_obj_is_proc
  67. set_trace_func
  68. call_trace_func
  69. svalue_to_avalue
  70. avalue_to_svalue
  71. avalue_to_yvalue
  72. svalue_to_mvalue
  73. mvalue_to_svalue
  74. rb_eval
  75. module_setup
  76. rb_respond_to
  77. rb_obj_respond_to
  78. rb_mod_method_defined
  79. terminate_process
  80. rb_exit
  81. rb_f_exit
  82. rb_f_abort
  83. rb_iter_break
  84. rb_longjmp
  85. rb_exc_raise
  86. rb_exc_fatal
  87. rb_interrupt
  88. rb_f_raise
  89. rb_jump_tag
  90. rb_block_given_p
  91. rb_iterator_p
  92. rb_f_block_given_p
  93. rb_yield_0
  94. rb_yield
  95. rb_f_loop
  96. massign
  97. assign
  98. rb_iterate
  99. handle_rescue
  100. rb_rescue2
  101. rb_rescue
  102. rb_protect
  103. rb_ensure
  104. rb_with_disable_interrupt
  105. stack_check
  106. rb_f_missing
  107. rb_undefined
  108. call_cfunc
  109. rb_call0
  110. rb_call
  111. rb_apply
  112. rb_f_send
  113. rb_funcall
  114. rb_funcall2
  115. rb_funcall3
  116. rb_call_super
  117. backtrace
  118. rb_f_caller
  119. rb_backtrace
  120. make_backtrace
  121. rb_frame_last_func
  122. compile
  123. eval
  124. rb_f_eval
  125. exec_under
  126. eval_under_i
  127. eval_under
  128. yield_under_i
  129. yield_under
  130. specific_eval
  131. rb_obj_instance_eval
  132. rb_mod_module_eval
  133. rb_load
  134. rb_load_protect
  135. rb_f_load
  136. rb_feature_p
  137. rb_provided
  138. rb_provide_feature
  139. rb_provide
  140. rb_f_require
  141. rb_require
  142. secure_visibility
  143. set_method_visibility
  144. rb_mod_public
  145. rb_mod_protected
  146. rb_mod_private
  147. rb_mod_public_method
  148. rb_mod_private_method
  149. top_public
  150. top_private
  151. rb_mod_modfunc
  152. rb_mod_append_features
  153. rb_mod_include
  154. rb_obj_call_init
  155. top_include
  156. rb_extend_object
  157. rb_mod_extend_object
  158. rb_obj_extend
  159. errinfo_setter
  160. errat_getter
  161. errat_setter
  162. rb_f_local_variables
  163. rb_set_end_proc
  164. rb_mark_end_proc
  165. call_end_proc
  166. rb_f_END
  167. rb_f_at_exit
  168. rb_exec_end_proc
  169. Init_eval
  170. Init_load
  171. scope_dup
  172. blk_mark
  173. blk_free
  174. blk_copy_prev
  175. frame_dup
  176. bind_clone
  177. rb_f_binding
  178. proc_save_safe_level
  179. proc_get_safe_level
  180. proc_set_safe_level
  181. proc_new
  182. proc_s_new
  183. rb_f_lambda
  184. blk_orphan
  185. proc_invoke
  186. proc_call
  187. proc_yield
  188. proc_arity
  189. proc_eq
  190. proc_to_s
  191. proc_to_proc
  192. proc_binding
  193. block_pass
  194. bm_mark
  195. mnew
  196. method_eq
  197. method_unbind
  198. umethod_unbind
  199. rb_obj_method
  200. rb_mod_method
  201. method_clone
  202. method_call
  203. umethod_bind
  204. method_arity
  205. method_inspect
  206. mproc
  207. bmcall
  208. umcall
  209. rb_proc_new
  210. method_proc
  211. umethod_proc
  212. rb_mod_define_method
  213. Init_Proc
  214. win32_get_exception_list
  215. win32_set_exception_list
  216. thread_status_name
  217. rb_set_safe_level
  218. safe_getter
  219. safe_setter
  220. timeofday
  221. thread_mark
  222. rb_gc_mark_threads
  223. thread_free
  224. rb_thread_check
  225. rb_thread_save_context
  226. thread_switch
  227. stack_extend
  228. rb_thread_restore_context
  229. rb_thread_ready
  230. rb_thread_remove
  231. rb_thread_dead
  232. rb_thread_fd_close
  233. rb_thread_deadlock
  234. copy_fds
  235. match_fds
  236. intersect_fds
  237. find_bad_fds
  238. rb_thread_schedule
  239. rb_thread_wait_fd
  240. rb_thread_fd_writable
  241. rb_thread_wait_for
  242. rb_thread_alone
  243. rb_thread_select
  244. rb_thread_join
  245. rb_thread_join_m
  246. rb_thread_current
  247. rb_thread_main
  248. rb_thread_list
  249. rb_thread_wakeup
  250. rb_thread_run
  251. rb_thread_kill
  252. rb_thread_s_kill
  253. rb_thread_exit
  254. rb_thread_pass
  255. rb_thread_stop
  256. rb_thread_polling
  257. rb_thread_sleep
  258. pause
  259. pause
  260. rb_thread_sleep_forever
  261. rb_thread_priority
  262. rb_thread_priority_set
  263. rb_thread_safe_level
  264. rb_thread_s_abort_exc
  265. rb_thread_s_abort_exc_set
  266. rb_thread_abort_exc
  267. rb_thread_abort_exc_set
  268. rb_thread_alloc
  269. catch_timer
  270. rb_thread_start_timer
  271. rb_thread_stop_timer
  272. rb_thread_start_0
  273. rb_thread_create
  274. rb_thread_yield
  275. rb_thread_s_new
  276. rb_thread_initialize
  277. rb_thread_start
  278. rb_thread_value
  279. rb_thread_status
  280. rb_thread_alive_p
  281. rb_thread_stop_p
  282. rb_thread_wait_other_threads
  283. rb_thread_cleanup
  284. rb_thread_critical_get
  285. rb_thread_critical_set
  286. rb_thread_interrupt
  287. rb_thread_signal_raise
  288. rb_thread_trap_eval
  289. rb_thread_raise
  290. rb_thread_raise_m
  291. rb_thread_local_aref
  292. rb_thread_aref
  293. rb_thread_local_aset
  294. rb_thread_aset
  295. rb_thread_key_p
  296. thread_keys_i
  297. rb_thread_keys
  298. rb_thread_inspect
  299. rb_thread_atfork
  300. rb_callcc
  301. rb_cont_call
  302. thgroup_s_alloc
  303. thgroup_list
  304. thgroup_add
  305. Init_Thread
  306. rb_f_catch
  307. catch_i
  308. rb_catch
  309. rb_f_throw
  310. rb_throw
  311. return_check


   1  /**********************************************************************
   2  
   3    eval.c -
   4  
   5    $Author: nobu $
   6    $Date: 2002/09/11 09:58:02 $
   7    created at: Thu Jun 10 14:22:17 JST 1993
   8  
   9    Copyright (C) 1993-2002 Yukihiro Matsumoto
  10    Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
  11    Copyright (C) 2000  Information-technology Promotion Agency, Japan
  12  
  13  **********************************************************************/
  14  
  15  #include "ruby.h"
  16  #include "node.h"
  17  #include "env.h"
  18  #include "util.h"
  19  #include "rubysig.h"
  20  
  21  #include <stdio.h>
  22  #include <setjmp.h>
  23  #include "st.h"
  24  #include "dln.h"
  25  
  26  /* Make alloca work the best possible way.  */
  27  #ifdef __GNUC__
  28  # ifndef atarist
  29  #  ifndef alloca
  30  #   define alloca __builtin_alloca
  31  #  endif
  32  # endif /* atarist */
  33  #else
  34  # if defined(HAVE_ALLOCA_H)
  35  #  include <alloca.h>
  36  # elif !defined(alloca)
  37  char *alloca();
  38  # endif
  39  #endif /* __GNUC__ */
  40  
  41  #ifdef _AIX
  42  #pragma alloca
  43  #endif
  44  
  45  #ifdef HAVE_STDARG_PROTOTYPES
  46  #include <stdarg.h>
  47  #define va_init_list(a,b) va_start(a,b)
  48  #else
  49  #include <varargs.h>
  50  #define va_init_list(a,b) va_start(a)
  51  #endif
  52  
  53  #ifndef HAVE_STRING_H
  54  char *strrchr _((const char*,const char));
  55  #endif
  56  
  57  #ifdef HAVE_UNISTD_H
  58  #include <unistd.h>
  59  #endif
  60  
  61  #ifdef __BEOS__
  62  #include <net/socket.h>
  63  #endif
  64  
  65  #ifdef __MACOS__
  66  #include "macruby_private.h"
  67  #endif
  68  
  69  #ifndef setjmp
  70  #ifdef HAVE__SETJMP
  71  #define setjmp(env) _setjmp(env)
  72  #define longjmp(env,val) _longjmp(env,val)
  73  #endif
  74  #endif
  75  
  76  #include <sys/types.h>
  77  #ifdef HAVE_SYS_TIME_H
  78  # include <sys/time.h>
  79  #else
  80  #ifndef NT
  81  struct timeval {
  82          long    tv_sec;         /* seconds */
  83          long    tv_usec;        /* and microseconds */
  84  };
  85  #endif /* NT */
  86  #endif
  87  #include <signal.h>
  88  #include <errno.h>
  89  
  90  #if defined(__VMS)
  91  #pragma nostandard
  92  #endif
  93  
  94  #ifdef HAVE_SYS_SELECT_H
  95  #include <sys/select.h>
  96  #endif
  97  
  98  #include <sys/stat.h>
  99  
 100  VALUE rb_cProc;
 101  static VALUE rb_cBinding;
 102  static VALUE proc_invoke _((VALUE,VALUE,int,VALUE));
 103  static VALUE rb_f_binding _((VALUE));
 104  static void rb_f_END _((void));
 105  static VALUE rb_f_block_given_p _((void));
 106  static VALUE block_pass _((VALUE,NODE*));
 107  static VALUE rb_cMethod;
 108  static VALUE method_call _((int, VALUE*, VALUE));
 109  static VALUE rb_cUnboundMethod;
 110  static VALUE umethod_bind _((VALUE, VALUE));
 111  static VALUE rb_mod_define_method _((int, VALUE*, VALUE));
 112  
 113  static int scope_vmode;
 114  #define SCOPE_PUBLIC    0
 115  #define SCOPE_PRIVATE   1
 116  #define SCOPE_PROTECTED 2
 117  #define SCOPE_MODFUNC   5
 118  #define SCOPE_MASK      7
 119  #define SCOPE_SET(f)  (scope_vmode=(f))
 120  #define SCOPE_TEST(f) (scope_vmode&(f))
 121  
 122  static NODE* ruby_last_node;
 123  NODE* ruby_current_node;
 124  int ruby_safe_level = 0;
 125  /* safe-level:
 126     0 - strings from streams/environment/ARGV are tainted (default)
 127     1 - no dangerous operation by tainted value
 128     2 - process/file operations prohibited
 129     3 - all genetated objects are tainted
 130     4 - no global (non-tainted) variable modification/no direct output
 131  */
 132  
 133  static VALUE safe_getter _((void));
 134  static void safe_setter _((VALUE val));
 135  
 136  void
 137  rb_secure(level)
 138      int level;
 139  {
 140      if (level <= ruby_safe_level) {
 141          rb_raise(rb_eSecurityError, "Insecure operation `%s' at level %d",
 142                   rb_id2name(ruby_frame->last_func), ruby_safe_level);
 143      }
 144  }
 145  
 146  void
 147  rb_check_safe_str(x)
 148      VALUE x;
 149  {
 150      if (ruby_safe_level > 0 && OBJ_TAINTED(x)){
 151          if (ruby_frame->last_func) {
 152              rb_raise(rb_eSecurityError, "Insecure operation - %s",
 153                       rb_id2name(ruby_frame->last_func));
 154          }
 155          else {
 156              rb_raise(rb_eSecurityError, "Insecure operation: -r");
 157          }
 158      }
 159      rb_secure(4);
 160      if (TYPE(x)!= T_STRING) {
 161          rb_raise(rb_eTypeError, "wrong argument type %s (expected String)",
 162                   rb_class2name(CLASS_OF(x)));
 163      }
 164  }
 165  
 166  NORETURN(static void print_undef _((VALUE, ID)));
 167  static void
 168  print_undef(klass, id)
 169      VALUE klass;
 170      ID id;
 171  {
 172      rb_name_error(id, "undefined method `%s' for %s `%s'",
 173                    rb_id2name(id), 
 174                    (TYPE(klass) == T_MODULE) ? "module" : "class",
 175                    rb_class2name(klass));
 176  }
 177  
 178  static ID removed, singleton_removed, undefined, singleton_undefined;
 179  
 180  #define CACHE_SIZE 0x800
 181  #define CACHE_MASK 0x7ff
 182  #define EXPR1(c,m) ((((c)>>3)^(m))&CACHE_MASK)
 183  
 184  struct cache_entry {            /* method hash table. */
 185      ID mid;                     /* method's id */
 186      ID mid0;                    /* method's original id */
 187      VALUE klass;                /* receiver's class */
 188      VALUE origin;               /* where method defined  */
 189      NODE *method;
 190      int noex;
 191  };
 192  
 193  static struct cache_entry cache[CACHE_SIZE];
 194  
 195  void
 196  rb_clear_cache()
 197  {
 198     struct cache_entry *ent, *end;
 199  
 200      ent = cache; end = ent + CACHE_SIZE;
 201      while (ent < end) {
 202          ent->mid = 0;
 203          ent++;
 204      }
 205  }
 206  
 207  static void
 208  rb_clear_cache_by_id(id)
 209      ID id;
 210  {
 211      struct cache_entry *ent, *end;
 212  
 213      ent = cache; end = ent + CACHE_SIZE;
 214      while (ent < end) {
 215          if (ent->mid == id) {
 216              ent->mid = 0;
 217          }
 218          ent++;
 219      }
 220  }
 221  
 222  static void
 223  rb_clear_cache_by_class(klass)
 224      VALUE klass;
 225  {
 226      struct cache_entry *ent, *end;
 227  
 228      ent = cache; end = ent + CACHE_SIZE;
 229      while (ent < end) {
 230          if (ent->origin == klass) {
 231              ent->mid = 0;
 232          }
 233          ent++;
 234      }
 235  }
 236  
 237  void
 238  rb_add_method(klass, mid, node, noex)
 239      VALUE klass;
 240      ID mid;
 241      NODE *node;
 242      int noex;
 243  {
 244      NODE *body;
 245  
 246      if (NIL_P(klass)) klass = rb_cObject;
 247      if (ruby_safe_level >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {
 248          rb_raise(rb_eSecurityError, "Insecure: can't define method");
 249      }
 250      if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
 251      rb_clear_cache_by_id(mid);
 252      body = NEW_METHOD(node, noex);
 253      st_insert(RCLASS(klass)->m_tbl, mid, body);
 254  }
 255  
 256  static NODE*
 257  search_method(klass, id, origin)
 258      VALUE klass, *origin;
 259      ID id;
 260  {
 261      NODE *body;
 262  
 263      if (!klass) return 0;
 264      while (!st_lookup(RCLASS(klass)->m_tbl, id, &body)) {
 265          klass = RCLASS(klass)->super;
 266          if (!klass) return 0;
 267      }
 268  
 269      if (origin) *origin = klass;
 270      return body;
 271  }
 272  
 273  static NODE*
 274  rb_get_method_body(klassp, idp, noexp)
 275      VALUE *klassp;
 276      ID *idp;
 277      int *noexp;
 278  {
 279      ID id = *idp;
 280      VALUE klass = *klassp;
 281      VALUE origin;
 282      NODE * volatile body;
 283      struct cache_entry *ent;
 284  
 285      if ((body = search_method(klass, id, &origin)) == 0 || !body->nd_body) {
 286          /* store empty info in cache */
 287          ent = cache + EXPR1(klass, id);
 288          ent->klass  = klass;
 289          ent->origin = klass;
 290          ent->mid = ent->mid0 = id;
 291          ent->noex   = 0;
 292          ent->method = 0;
 293          
 294          return 0;
 295      }
 296  
 297      /* store in cache */
 298      ent = cache + EXPR1(klass, id);
 299      ent->klass  = klass;
 300      ent->noex   = body->nd_noex;
 301      body = body->nd_body;
 302      if (nd_type(body) == NODE_FBODY) {
 303          ent->mid = id;
 304          *klassp = body->nd_orig;
 305          ent->origin = body->nd_orig;
 306          *idp = ent->mid0 = body->nd_mid;
 307          body = ent->method = body->nd_head;
 308      }
 309      else {
 310          *klassp = origin;
 311          ent->origin = origin;
 312          ent->mid = ent->mid0 = id;
 313          ent->method = body;
 314      }
 315  
 316      if (noexp) *noexp = ent->noex;
 317      return body;
 318  }
 319  
 320  static ID init, alloc, eqq, each, aref, aset, match, missing;
 321  static ID added, singleton_added;
 322  static ID __id__, __send__;
 323  
 324  static void
 325  remove_method(klass, mid)
 326      VALUE klass;
 327      ID mid;
 328  {
 329      NODE *body;
 330  
 331      if (klass == rb_cObject) {
 332          rb_secure(4);
 333      }
 334      if (ruby_safe_level >= 4 && !OBJ_TAINTED(klass)) {
 335          rb_raise(rb_eSecurityError, "Insecure: can't remove method");
 336      }
 337      if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
 338      if (mid == __id__ || mid == __send__ || mid == init) {
 339          rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
 340      }
 341      if (mid == alloc) {
 342          if (klass == rb_cClass ||
 343              (FL_TEST(klass, FL_SINGLETON) &&
 344               rb_obj_is_kind_of(rb_iv_get(klass, "__attached__"), rb_cClass))) {
 345              rb_name_error(mid, "removing `%s'", rb_id2name(mid));
 346          }
 347      }
 348      if (!st_delete(RCLASS(klass)->m_tbl, &mid, &body) || !body->nd_body) {
 349          rb_name_error(mid, "method `%s' not defined in %s",
 350                        rb_id2name(mid), rb_class2name(klass));
 351      }
 352      rb_clear_cache_by_id(mid);
 353      if (FL_TEST(klass, FL_SINGLETON)) {
 354          rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1, ID2SYM(mid));
 355      }
 356      else {
 357          rb_funcall(klass, removed, 1, ID2SYM(mid));
 358      }
 359  }
 360  
 361  void
 362  rb_remove_method(klass, name)
 363      VALUE klass;
 364      const char *name;
 365  {
 366      remove_method(klass, rb_intern(name));
 367  }
 368  
 369  static VALUE
 370  rb_mod_remove_method(mod, name)
 371      VALUE mod, name;
 372  {
 373      remove_method(mod, rb_to_id(name));
 374      return mod;
 375  }
 376  
 377  void
 378  rb_disable_super(klass, name)
 379      VALUE klass;
 380      const char *name;
 381  {
 382      VALUE origin;
 383      NODE *body;
 384      ID mid = rb_intern(name);
 385  
 386      body = search_method(klass, mid, &origin);
 387      if (!body || !body->nd_body) {
 388          print_undef(klass, mid);
 389      }
 390      if (origin == klass) {
 391          body->nd_noex |= NOEX_UNDEF;
 392      }
 393      else {
 394          rb_add_method(klass, mid, 0, NOEX_UNDEF);
 395      }
 396  }
 397  
 398  void
 399  rb_enable_super(klass, name)
 400      VALUE klass;
 401      const char *name;
 402  {
 403      VALUE origin;
 404      NODE *body;
 405      ID mid = rb_intern(name);
 406  
 407      body = search_method(klass, mid, &origin);
 408      if (!body) {
 409          print_undef(klass, mid);
 410      }
 411      if (!body->nd_body) {
 412          remove_method(klass, mid);
 413      }
 414      else {
 415          body->nd_noex &= ~NOEX_UNDEF;
 416      }
 417  }
 418  
 419  static void
 420  rb_export_method(klass, name, noex)
 421      VALUE klass;
 422      ID name;
 423      ID noex;
 424  {
 425      NODE *body;
 426      VALUE origin;
 427  
 428      if (klass == rb_cObject) {
 429          rb_secure(4);
 430      }
 431      body = search_method(klass, name, &origin);
 432      if (!body && TYPE(klass) == T_MODULE) {
 433          body = search_method(rb_cObject, name, &origin);
 434      }
 435      if (!body) {
 436          print_undef(klass, name);
 437      }
 438      if (body->nd_noex != noex) {
 439          if (klass == origin) {
 440              body->nd_noex = noex;
 441          }
 442          else {
 443              rb_add_method(klass, name, NEW_ZSUPER(), noex);
 444          }
 445      }
 446  }
 447  
 448  int
 449  rb_method_boundp(klass, id, ex)
 450      VALUE klass;
 451      ID id;
 452      int ex;
 453  {
 454      struct cache_entry *ent;
 455      int noex;
 456  
 457      /* is it in the method cache? */
 458      ent = cache + EXPR1(klass, id);
 459      if (ent->mid == id && ent->klass == klass) {
 460          if (ex && (ent->noex & NOEX_PRIVATE))
 461              return Qfalse;
 462          if (!ent->method) return Qfalse;
 463          return Qtrue;
 464      }
 465      if (rb_get_method_body(&klass, &id, &noex)) {
 466          if (ex && (noex & NOEX_PRIVATE))
 467              return Qfalse;
 468          return Qtrue;
 469      }
 470      return Qfalse;
 471  }
 472  
 473  void
 474  rb_attr(klass, id, read, write, ex)
 475      VALUE klass;
 476      ID id;
 477      int read, write, ex;
 478  {
 479      const char *name;
 480      char *buf;
 481      ID attriv;
 482      int noex;
 483  
 484      if (!ex) noex = NOEX_PUBLIC;
 485      else {
 486          if (SCOPE_TEST(SCOPE_PRIVATE)) {
 487              noex = NOEX_PRIVATE;
 488              rb_warning((scope_vmode == SCOPE_MODFUNC) ?
 489                         "attribute accessor as module_function" :
 490                         "private attribute?");
 491          }
 492          else if (SCOPE_TEST(SCOPE_PROTECTED)) {
 493              noex = NOEX_PROTECTED;
 494          }
 495          else {
 496              noex = NOEX_PUBLIC;
 497          }
 498      }
 499  
 500      name = rb_id2name(id);
 501      if (!name) {
 502          rb_raise(rb_eArgError, "argument needs to be symbol or string");
 503      }
 504      buf = ALLOCA_N(char,strlen(name)+2);
 505      sprintf(buf, "@%s", name);
 506      attriv = rb_intern(buf);
 507      if (read) {
 508          rb_add_method(klass, id, NEW_IVAR(attriv), noex);
 509          rb_funcall(klass, added, 1, ID2SYM(id));
 510      }
 511      if (write) {
 512          sprintf(buf, "%s=", name);
 513          id = rb_intern(buf);
 514          rb_add_method(klass, id, NEW_ATTRSET(attriv), noex);
 515          rb_funcall(klass, added, 1, ID2SYM(id));
 516      }
 517  }
 518  
 519  extern int ruby_in_compile;
 520  
 521  VALUE ruby_errinfo = Qnil;
 522  extern NODE *ruby_eval_tree_begin;
 523  extern NODE *ruby_eval_tree;
 524  extern int ruby_nerrs;
 525  
 526  static VALUE rb_eLocalJumpError;
 527  static VALUE rb_eSysStackError;
 528  
 529  extern VALUE ruby_top_self;
 530  
 531  struct FRAME *ruby_frame;
 532  struct SCOPE *ruby_scope;
 533  static struct FRAME *top_frame;
 534  static struct SCOPE *top_scope;
 535  
 536  #define PUSH_FRAME() do {               \
 537      struct FRAME _frame;                \
 538      _frame.prev = ruby_frame;           \
 539      _frame.tmp  = 0;                    \
 540      _frame.node = ruby_current_node;    \
 541      _frame.iter = ruby_iter->iter;      \
 542      _frame.cbase = ruby_frame->cbase;   \
 543      _frame.argc = 0;                    \
 544      _frame.argv = 0;                    \
 545      _frame.flags = FRAME_ALLOCA;        \
 546      ruby_frame = &_frame
 547  
 548  #define POP_FRAME()                     \
 549      ruby_current_node = _frame.node;    \
 550      ruby_frame = _frame.prev;           \
 551  } while (0)
 552  
 553  struct BLOCKTAG {
 554      struct RBasic super;
 555      long dst;
 556      long flags;
 557  };
 558  
 559  struct BLOCK {
 560      NODE *var;
 561      NODE *body;
 562      VALUE self;
 563      struct FRAME frame;
 564      struct SCOPE *scope;
 565      struct BLOCKTAG *tag;
 566      VALUE klass;
 567      int iter;
 568      int vmode;
 569      int flags;
 570      struct RVarmap *dyna_vars;
 571      VALUE orig_thread;
 572      VALUE wrapper;
 573      struct BLOCK *prev;
 574  };
 575  
 576  #define BLOCK_D_SCOPE 1
 577  #define BLOCK_DYNAMIC 2
 578  #define BLOCK_ORPHAN  4
 579  
 580  static struct BLOCK *ruby_block;
 581  
 582  static struct BLOCKTAG*
 583  new_blktag()
 584  {
 585      NEWOBJ(blktag, struct BLOCKTAG);
 586      OBJSETUP(blktag, 0, T_BLKTAG);
 587      blktag->dst = 0;
 588      blktag->flags = 0;
 589      return blktag;
 590  }
 591  
 592  #define PUSH_BLOCK(v,b) do {            \
 593      struct BLOCK _block;                \
 594      _block.tag = new_blktag();          \
 595      _block.var = v;                     \
 596      _block.body = b;                    \
 597      _block.self = self;                 \
 598      _block.frame = *ruby_frame;         \
 599      _block.klass = ruby_class;          \
 600      _block.frame.node = ruby_current_node;\
 601      _block.scope = ruby_scope;          \
 602      _block.prev = ruby_block;           \
 603      _block.iter = ruby_iter->iter;      \
 604      _block.vmode = scope_vmode;         \
 605      _block.flags = BLOCK_D_SCOPE;       \
 606      _block.dyna_vars = ruby_dyna_vars;  \
 607      _block.wrapper = ruby_wrapper;      \
 608      ruby_block = &_block
 609  
 610  #define POP_BLOCK()                     \
 611     if (_block.tag->flags & (BLOCK_DYNAMIC)) \
 612         _block.tag->flags |= BLOCK_ORPHAN; \
 613     else if (!(_block.scope->flags & SCOPE_DONT_RECYCLE)) \
 614         rb_gc_force_recycle((VALUE)_block.tag); \
 615     ruby_block = _block.prev;            \
 616  } while (0)
 617  
 618  struct RVarmap *ruby_dyna_vars;
 619  #define PUSH_VARS() do { \
 620      struct RVarmap * volatile _old; \
 621      _old = ruby_dyna_vars; \
 622      ruby_dyna_vars = 0
 623  
 624  #define POP_VARS() \
 625     if (_old && (ruby_scope->flags & SCOPE_DONT_RECYCLE)) {\
 626         if (RBASIC(_old)->flags) /* unless it's already recycled */ \
 627             FL_SET(_old, DVAR_DONT_RECYCLE); \
 628      }\
 629      ruby_dyna_vars = _old; \
 630  } while (0)
 631  
 632  #define DVAR_DONT_RECYCLE FL_USER2
 633  
 634  static struct RVarmap*
 635  new_dvar(id, value, prev)
 636      ID id;
 637      VALUE value;
 638      struct RVarmap *prev;
 639  {
 640      NEWOBJ(vars, struct RVarmap);
 641      OBJSETUP(vars, 0, T_VARMAP);
 642      vars->id = id;
 643      vars->val = value;
 644      vars->next = prev;
 645  
 646      return vars;
 647  }
 648  
 649  VALUE
 650  rb_dvar_defined(id)
 651      ID id;
 652  {
 653      struct RVarmap *vars = ruby_dyna_vars;
 654  
 655      while (vars) {
 656          if (vars->id == id) return Qtrue;
 657          vars = vars->next;
 658      }
 659      return Qfalse;
 660  }
 661  
 662  VALUE
 663  rb_dvar_curr(id)
 664      ID id;
 665  {
 666      struct RVarmap *vars = ruby_dyna_vars;
 667  
 668      while (vars) {
 669          if (vars->id == 0) break;
 670          if (vars->id == id) return Qtrue;
 671          vars = vars->next;
 672      }
 673      return Qfalse;
 674  }
 675  
 676  VALUE
 677  rb_dvar_ref(id)
 678      ID id;
 679  {
 680      struct RVarmap *vars = ruby_dyna_vars;
 681  
 682      while (vars) {
 683          if (vars->id == id) {
 684              return vars->val;
 685          }
 686          vars = vars->next;
 687      }
 688      return Qnil;
 689  }
 690  
 691  void
 692  rb_dvar_push(id, value)
 693      ID id;
 694      VALUE value;
 695  {
 696      ruby_dyna_vars = new_dvar(id, value, ruby_dyna_vars);
 697  }
 698  
 699  static void
 700  dvar_asgn_internal(id, value, curr)
 701      ID id;
 702      VALUE value;
 703      int curr;
 704  {
 705      int n = 0;
 706      struct RVarmap *vars = ruby_dyna_vars;
 707  
 708      while (vars) {
 709          if (curr && vars->id == 0) {
 710              /* first null is a dvar header */
 711              n++;
 712              if (n == 2) break;
 713          }
 714          if (vars->id == id) {
 715              vars->val = value;
 716              return;
 717          }
 718          vars = vars->next;
 719      }
 720      if (!ruby_dyna_vars) {
 721          ruby_dyna_vars = new_dvar(id, value, 0);
 722      }
 723      else {
 724          vars = new_dvar(id, value, ruby_dyna_vars->next);
 725          ruby_dyna_vars->next = vars;
 726      }
 727  }
 728  
 729  static inline void
 730  dvar_asgn(id, value)
 731      ID id;
 732      VALUE value;
 733  {
 734      dvar_asgn_internal(id, value, 0);
 735  }
 736  
 737  static inline void
 738  dvar_asgn_curr(id, value)
 739      ID id;
 740      VALUE value;
 741  {
 742      dvar_asgn_internal(id, value, 1);
 743  }
 744  
 745  VALUE *
 746  rb_svar(cnt)
 747      int cnt;
 748  {
 749      struct RVarmap *vars = ruby_dyna_vars;
 750      ID id;
 751  
 752      if (!ruby_scope->local_tbl) return NULL;
 753      if (cnt >= ruby_scope->local_tbl[0]) return NULL;
 754      id = ruby_scope->local_tbl[cnt+1];
 755      while (vars) {
 756          if (vars->id == id) return &vars->val;
 757          vars = vars->next;
 758      }
 759      if (ruby_scope->local_vars == 0) return NULL;
 760      return &ruby_scope->local_vars[cnt];
 761  }
 762  
 763  struct iter {
 764      int iter;
 765      struct iter *prev;
 766  };
 767  static struct iter *ruby_iter;
 768  
 769  #define ITER_NOT 0
 770  #define ITER_PRE 1
 771  #define ITER_CUR 2
 772  
 773  #define PUSH_ITER(i) do {               \
 774      struct iter _iter;                  \
 775      _iter.prev = ruby_iter;             \
 776      _iter.iter = (i);                   \
 777      ruby_iter = &_iter
 778  
 779  #define POP_ITER()                      \
 780      ruby_iter = _iter.prev;             \
 781  } while (0)
 782  
 783  struct tag {
 784      jmp_buf buf;
 785      struct FRAME *frame;
 786      struct iter *iter;
 787      ID tag;
 788      VALUE retval;
 789      struct SCOPE *scope;
 790      int dst;
 791      struct tag *prev;
 792  };
 793  static struct tag *prot_tag;
 794  
 795  #define PUSH_TAG(ptag) do {             \
 796      struct tag _tag;                    \
 797      _tag.retval = Qnil;                 \
 798      _tag.frame = ruby_frame;            \
 799      _tag.iter = ruby_iter;              \
 800      _tag.prev = prot_tag;               \
 801      _tag.scope = ruby_scope;            \
 802      _tag.tag = ptag;                    \
 803      _tag.dst = 0;                       \
 804      prot_tag = &_tag
 805  
 806  #define PROT_NONE   0
 807  #define PROT_FUNC   -1
 808  #define PROT_THREAD -2
 809  
 810  #define EXEC_TAG()    setjmp(prot_tag->buf)
 811  
 812  #define JUMP_TAG(st) do {               \
 813      ruby_frame = prot_tag->frame;       \
 814      ruby_iter = prot_tag->iter;         \
 815      longjmp(prot_tag->buf,(st));        \
 816  } while (0)
 817  
 818  #define POP_TAG()                       \
 819      if (_tag.prev)                      \
 820          _tag.prev->retval = _tag.retval;\
 821      prot_tag = _tag.prev;               \
 822  } while (0)
 823  
 824  #define POP_TMPTAG()                    \
 825      prot_tag = _tag.prev;               \
 826  } while (0)
 827  
 828  #define TAG_RETURN      0x1
 829  #define TAG_BREAK       0x2
 830  #define TAG_NEXT        0x3
 831  #define TAG_RETRY       0x4
 832  #define TAG_REDO        0x5
 833  #define TAG_RAISE       0x6
 834  #define TAG_THROW       0x7
 835  #define TAG_FATAL       0x8
 836  #define TAG_MASK        0xf
 837  
 838  VALUE ruby_class;
 839  static VALUE ruby_wrapper;      /* security wrapper */
 840  
 841  #define PUSH_CLASS() do {               \
 842      VALUE _class = ruby_class
 843  
 844  #define POP_CLASS() ruby_class = _class; \
 845  } while (0)
 846  
 847  static NODE *ruby_cref = 0;
 848  static NODE *top_cref;
 849  #define PUSH_CREF(c) ruby_cref = rb_node_newnode(NODE_CREF,(c),0,ruby_cref)
 850  #define POP_CREF() ruby_cref = ruby_cref->nd_next
 851  
 852  #define PUSH_SCOPE() do {               \
 853      volatile int _vmode = scope_vmode;  \
 854      struct SCOPE * volatile _old;       \
 855      NEWOBJ(_scope, struct SCOPE);       \
 856      OBJSETUP(_scope, 0, T_SCOPE);       \
 857      _scope->local_tbl = 0;              \
 858      _scope->local_vars = 0;             \
 859      _scope->flags = 0;                  \
 860      _old = ruby_scope;                  \
 861      ruby_scope = _scope;                \
 862      scope_vmode = SCOPE_PUBLIC
 863  
 864  typedef struct thread * rb_thread_t;
 865  static rb_thread_t curr_thread = 0;
 866  static rb_thread_t main_thread;
 867  static void scope_dup _((struct SCOPE *));
 868  
 869  #define POP_SCOPE()                     \
 870      if (ruby_scope->flags & SCOPE_DONT_RECYCLE) {\
 871         if (_old) scope_dup(_old);       \
 872      }                                   \
 873      if (!(ruby_scope->flags & SCOPE_MALLOC)) {\
 874          ruby_scope->local_vars = 0;     \
 875          ruby_scope->local_tbl  = 0;     \
 876          if (!(ruby_scope->flags & SCOPE_DONT_RECYCLE) && \
 877              ruby_scope != top_scope) {  \
 878              rb_gc_force_recycle((VALUE)ruby_scope);\
 879          }                               \
 880      }                                   \
 881      ruby_scope->flags |= SCOPE_NOSTACK; \
 882      ruby_scope = _old;                  \
 883      scope_vmode = _vmode;               \
 884  } while (0)
 885  
 886  static VALUE rb_eval _((VALUE,NODE*));
 887  static VALUE eval _((VALUE,VALUE,VALUE,char*,int));
 888  static NODE *compile _((VALUE, char*, int));
 889  
 890  static VALUE rb_yield_0 _((VALUE, VALUE, VALUE, int));
 891  static VALUE rb_call _((VALUE,VALUE,ID,int,const VALUE*,int));
 892  static VALUE module_setup _((VALUE,NODE*));
 893  
 894  static VALUE massign _((VALUE,NODE*,VALUE,int));
 895  static void assign _((VALUE,NODE*,VALUE,int));
 896  
 897  static VALUE trace_func = 0;
 898  static int tracing = 0;
 899  static void call_trace_func _((char*,NODE*,VALUE,ID,VALUE));
 900  
 901  #define SET_CURRENT_SOURCE() (ruby_sourcefile = ruby_current_node->nd_file, \
 902                                ruby_sourceline = nd_line(ruby_current_node))
 903  
 904  void
 905  ruby_set_current_source()
 906  {
 907      if (ruby_current_node) {
 908          ruby_sourcefile = ruby_current_node->nd_file;
 909          ruby_sourceline = nd_line(ruby_current_node);
 910      }
 911  }
 912  
 913  static void
 914  error_pos()
 915  {
 916      ruby_set_current_source();
 917      if (ruby_sourcefile) {
 918          if (ruby_frame->last_func) {
 919              fprintf(stderr, "%s:%d:in `%s'", ruby_sourcefile, ruby_sourceline,
 920                      rb_id2name(ruby_frame->last_func));
 921          }
 922          else if (ruby_sourceline == 0) {
 923              fprintf(stderr, "%s", ruby_sourcefile);
 924          }
 925          else {
 926              fprintf(stderr, "%s:%d", ruby_sourcefile, ruby_sourceline);
 927          }
 928      }
 929  }
 930  
 931  static VALUE
 932  get_backtrace(info)
 933      VALUE info;
 934  {
 935      if (NIL_P(info)) return Qnil;
 936      return rb_funcall(info, rb_intern("backtrace"), 0);
 937  }
 938  
 939  static void
 940  set_backtrace(info, bt)
 941      VALUE info, bt;
 942  {
 943      rb_funcall(info, rb_intern("set_backtrace"), 1, bt);
 944  }
 945  
 946  static void
 947  error_print()
 948  {
 949      VALUE errat = Qnil;         /* OK */
 950      volatile VALUE eclass;
 951      char *einfo;
 952      long elen;
 953  
 954      if (NIL_P(ruby_errinfo)) return;
 955  
 956      PUSH_TAG(PROT_NONE);
 957      if (EXEC_TAG() == 0) {
 958          errat = get_backtrace(ruby_errinfo);
 959      }
 960      else {
 961          errat = Qnil;
 962      }
 963      POP_TAG();
 964      if (NIL_P(errat)){
 965          ruby_set_current_source();
 966          if (ruby_sourcefile)
 967              fprintf(stderr, "%s:%d", ruby_sourcefile, ruby_sourceline);
 968          else
 969              fprintf(stderr, "%d", ruby_sourceline);
 970      }
 971      else if (RARRAY(errat)->len == 0) {
 972          error_pos();
 973      }
 974      else {
 975          VALUE mesg = RARRAY(errat)->ptr[0];
 976  
 977          if (NIL_P(mesg)) error_pos();
 978          else {
 979              fwrite(RSTRING(mesg)->ptr, 1, RSTRING(mesg)->len, stderr);
 980          }
 981      }
 982  
 983      eclass = CLASS_OF(ruby_errinfo);
 984      PUSH_TAG(PROT_NONE);
 985      if (EXEC_TAG() == 0) {
 986          VALUE e = rb_obj_as_string(ruby_errinfo);
 987          einfo = RSTRING(e)->ptr;
 988          elen = RSTRING(e)->len;
 989      }
 990      else {
 991          einfo = "";
 992          elen = 0;
 993      }
 994      POP_TAG();
 995      if (eclass == rb_eRuntimeError && elen == 0) {
 996          fprintf(stderr, ": unhandled exception\n");
 997      }
 998      else {
 999          VALUE epath;
1000  
1001          epath = rb_class_path(eclass);
1002          if (elen == 0) {
1003              fprintf(stderr, ": ");
1004              fwrite(RSTRING(epath)->ptr, 1, RSTRING(epath)->len, stderr);
1005              putc('\n', stderr);
1006          }
1007          else {
1008              char *tail  = 0;
1009              long len = elen;
1010  
1011              if (RSTRING(epath)->ptr[0] == '#') epath = 0;
1012              if (tail = strchr(einfo, '\n')) {
1013                  len = tail - einfo;
1014                  tail++;         /* skip newline */
1015              }
1016              fprintf(stderr, ": ");
1017              fwrite(einfo, 1, len, stderr);
1018              if (epath) {
1019                  fprintf(stderr, " (");
1020                  fwrite(RSTRING(epath)->ptr, 1, RSTRING(epath)->len, stderr);
1021                  fprintf(stderr, ")\n");
1022              }
1023              if (tail) {
1024                  fwrite(tail, 1, elen-len-1, stderr);
1025                  putc('\n', stderr);
1026              }
1027          }
1028      }
1029  
1030      if (!NIL_P(errat)) {
1031          long i;
1032          struct RArray *ep = RARRAY(errat);
1033  
1034  #define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)
1035  #define TRACE_HEAD 8
1036  #define TRACE_TAIL 5
1037  
1038          ep = RARRAY(errat);
1039          for (i=1; i<ep->len; i++) {
1040              if (TYPE(ep->ptr[i]) == T_STRING) {
1041                  fprintf(stderr, "\tfrom %s\n", RSTRING(ep->ptr[i])->ptr);
1042              }
1043              if (i == TRACE_HEAD && ep->len > TRACE_MAX) {
1044                  fprintf(stderr, "\t ... %ld levels...\n",
1045                          ep->len - TRACE_HEAD - TRACE_TAIL);
1046                  i = ep->len - TRACE_TAIL;
1047              }
1048          }
1049      }
1050  }
1051  
1052  #if !defined(NT) && !defined(__MACOS__)
1053  extern char **environ;
1054  #endif
1055  char **rb_origenviron;
1056  
1057  void rb_call_inits _((void));
1058  void Init_stack _((void*));
1059  void Init_heap _((void));
1060  void Init_ext _((void));
1061  
1062  void
1063  ruby_init()
1064  {
1065      static int initialized = 0;
1066      static struct FRAME frame;
1067      static struct iter iter;
1068      int state;
1069  
1070      if (initialized)
1071          return;
1072      initialized = 1;
1073  
1074      ruby_frame = top_frame = &frame;
1075      ruby_iter = &iter;
1076  
1077  #ifdef __MACOS__
1078      rb_origenviron = 0;
1079  #else
1080      rb_origenviron = environ;
1081  #endif
1082  
1083      Init_stack(0);
1084      Init_heap();
1085      PUSH_SCOPE();
1086      ruby_scope->local_vars = 0;
1087      ruby_scope->local_tbl  = 0;
1088      top_scope = ruby_scope;
1089      /* default visibility is private at toplevel */
1090      SCOPE_SET(SCOPE_PRIVATE);
1091  
1092      PUSH_TAG(PROT_NONE);
1093      if ((state = EXEC_TAG()) == 0) {
1094          rb_call_inits();
1095          ruby_class = rb_cObject;
1096          ruby_frame->self = ruby_top_self;
1097          top_cref = rb_node_newnode(NODE_CREF,rb_cObject,0,0);
1098          ruby_cref = top_cref;
1099          ruby_frame->cbase = (VALUE)ruby_cref;
1100          rb_define_global_const("TOPLEVEL_BINDING", rb_f_binding(ruby_top_self));
1101  #ifdef __MACOS__
1102          _macruby_init();
1103  #endif
1104          ruby_prog_init();
1105      }
1106      POP_TAG();
1107      if (state) error_print();
1108      POP_SCOPE();
1109      ruby_scope = top_scope;
1110  }
1111  
1112  static VALUE
1113  eval_node(self, node)
1114      VALUE self;
1115      NODE *node;
1116  {
1117      NODE *beg_tree = ruby_eval_tree_begin;
1118  
1119      ruby_eval_tree_begin = 0;
1120      if (beg_tree) {
1121          rb_eval(self, beg_tree);
1122      }
1123  
1124      if (!node) return Qnil;
1125      return rb_eval(self, node);
1126  }
1127  
1128  int ruby_in_eval;
1129  
1130  static void rb_thread_cleanup _((void));
1131  static void rb_thread_wait_other_threads _((void));
1132  
1133  static int
1134  error_handle(ex)
1135      int ex;
1136  {
1137      switch (ex & TAG_MASK) {
1138        case 0:
1139          ex = 0;
1140          break;
1141  
1142        case TAG_RETURN:
1143          error_pos();
1144          fprintf(stderr, ": unexpected return\n");
1145          ex = 1;
1146          break;
1147        case TAG_NEXT:
1148          error_pos();
1149          fprintf(stderr, ": unexpected next\n");
1150          ex = 1;
1151          break;
1152        case TAG_BREAK:
1153          error_pos();
1154          fprintf(stderr, ": unexpected break\n");
1155          ex = 1;
1156          break;
1157        case TAG_REDO:
1158          error_pos();
1159          fprintf(stderr, ": unexpected redo\n");
1160          ex = 1;
1161          break;
1162        case TAG_RETRY:
1163          error_pos();
1164          fprintf(stderr, ": retry outside of rescue clause\n");
1165          ex = 1;
1166          break;
1167        case TAG_THROW:
1168          if (prot_tag && prot_tag->frame && prot_tag->frame->node) {
1169              NODE *tag = prot_tag->frame->node;
1170              fprintf(stderr, "%s:%d: uncaught throw\n",
1171                      tag->nd_file, nd_line(tag));
1172          }
1173          else {
1174              error_pos();
1175              fprintf(stderr, ": unexpected throw\n");
1176          }
1177          ex = 1;
1178          break;
1179        case TAG_RAISE:
1180        case TAG_FATAL:
1181          if (rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
1182              VALUE st = rb_iv_get(ruby_errinfo, "status");
1183              ex = NIL_P(st) ? 1 : NUM2INT(st);
1184          }
1185          else {
1186              error_print();
1187              ex = 1;
1188          }
1189          break;
1190        default:
1191          rb_bug("Unknown longjmp status %d", ex);
1192          break;
1193      }
1194      return ex;
1195  }
1196  
1197  void
1198  ruby_options(argc, argv)
1199      int argc;
1200      char **argv;
1201  {
1202      int state;
1203  
1204      PUSH_TAG(PROT_NONE);
1205      if ((state = EXEC_TAG()) == 0) {
1206          ruby_process_options(argc, argv);
1207      }
1208      if (state) {
1209          trace_func = 0;
1210          tracing = 0;
1211          exit(error_handle(state));
1212      }
1213      POP_TAG();
1214  }
1215  
1216  void rb_exec_end_proc _((void));
1217  
1218  void
1219  ruby_finalize()
1220  {
1221      int state;
1222  
1223      PUSH_TAG(PROT_NONE);
1224      if ((state = EXEC_TAG()) == 0) {
1225          rb_trap_exit();
1226          rb_exec_end_proc();
1227          rb_gc_call_finalizer_at_exit();
1228      }
1229      POP_TAG();
1230  }
1231  
1232  void
1233  ruby_stop(ex)
1234      int ex;
1235  {
1236      int state;
1237  
1238      PUSH_TAG(PROT_NONE);
1239      PUSH_ITER(ITER_NOT);
1240      if ((state = EXEC_TAG()) == 0) {
1241          rb_thread_cleanup();
1242          rb_thread_wait_other_threads();
1243      }
1244      else if (ex == 0) {
1245          ex = state;
1246      }   
1247      POP_ITER();
1248  
1249      trace_func = 0;
1250      tracing = 0;
1251      ex = error_handle(ex);
1252      POP_TAG();
1253      ruby_finalize();
1254      exit(ex);
1255  }
1256  
1257  void
1258  ruby_run()
1259  {
1260      int state;
1261      static int ex;
1262      volatile NODE *tmp;
1263  
1264      if (ruby_nerrs > 0) exit(ruby_nerrs);
1265  
1266      Init_stack((void*)&tmp);
1267      PUSH_TAG(PROT_NONE);
1268      PUSH_ITER(ITER_NOT);
1269      if ((state = EXEC_TAG()) == 0) {
1270          eval_node(ruby_top_self, ruby_eval_tree);
1271      }
1272      POP_ITER();
1273      POP_TAG();
1274  
1275      if (state && !ex) ex = state;
1276      ruby_stop(ex);
1277  }
1278  
1279  static void
1280  compile_error(at)
1281      const char *at;
1282  {
1283      VALUE str;
1284  
1285      ruby_nerrs = 0;
1286      str = rb_str_buf_new2("compile error");
1287      if (at) {
1288          rb_str_buf_cat2(str, " in ");
1289          rb_str_buf_cat2(str, at);
1290      }
1291      rb_str_buf_cat(str, "\n", 1);
1292      if (!NIL_P(ruby_errinfo)) {
1293          rb_str_append(str, ruby_errinfo);
1294      }
1295      rb_exc_raise(rb_exc_new3(rb_eSyntaxError, str));
1296  }
1297  
1298  VALUE
1299  rb_eval_string(str)
1300      const char *str;
1301  {
1302      VALUE v;
1303      NODE *oldsrc = ruby_current_node;
1304  
1305      ruby_current_node = 0;
1306      ruby_sourcefile = rb_source_filename("(eval)");
1307      v = eval(ruby_top_self, rb_str_new2(str), Qnil, 0, 0);
1308      ruby_current_node = oldsrc;
1309  
1310      return v;
1311  }
1312  
1313  VALUE
1314  rb_eval_string_protect(str, state)
1315      const char *str;
1316      int *state;
1317  {
1318      VALUE result;               /* OK */
1319      int status;
1320  
1321      PUSH_TAG(PROT_NONE);
1322      if ((status = EXEC_TAG()) == 0) {
1323          result = rb_eval_string(str);
1324      }
1325      POP_TAG();
1326      if (state) {
1327          *state = status;
1328      }
1329      if (status != 0) {
1330          return Qnil;
1331      }
1332  
1333      return result;
1334  }
1335  
1336  VALUE
1337  rb_eval_string_wrap(str, state)
1338      const char *str;
1339      int *state;
1340  {
1341      int status;
1342      VALUE self = ruby_top_self;
1343      VALUE wrapper = ruby_wrapper;
1344      VALUE val;
1345  
1346      PUSH_CLASS();
1347      ruby_class = ruby_wrapper = rb_module_new();
1348      ruby_top_self = rb_obj_clone(ruby_top_self);
1349      rb_extend_object(ruby_top_self, ruby_wrapper);
1350      PUSH_FRAME();
1351      ruby_frame->last_func = 0;
1352      ruby_frame->orig_func = 0;
1353      ruby_frame->last_class = 0;
1354      ruby_frame->self = self;
1355      ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,ruby_wrapper,0,0);
1356      PUSH_SCOPE();
1357  
1358      val = rb_eval_string_protect(str, &status);
1359      ruby_top_self = self;
1360  
1361      POP_SCOPE();
1362      POP_FRAME();
1363      POP_CLASS();
1364      ruby_wrapper = wrapper;
1365      if (state) {
1366          *state = status;
1367      }
1368      else if (status) {
1369          JUMP_TAG(status);
1370      }
1371      return val;
1372  }
1373  
1374  static void
1375  localjump_error(mesg, status)
1376      const char *mesg;
1377      VALUE status;
1378  {
1379      VALUE exc = rb_exc_new2(rb_eLocalJumpError, mesg);
1380      rb_iv_set(exc, "@status", status);
1381      rb_exc_raise(exc);
1382  }
1383  
1384  static VALUE
1385  localjump_exitstatus(exc)
1386      VALUE exc;
1387  {
1388      return rb_iv_get(exc, "@status");
1389  }
1390  
1391  static void
1392  jump_tag_but_local_jump(state)
1393      int state;
1394  {
1395      VALUE val;
1396  
1397      if (prot_tag) val = prot_tag->retval;
1398      else          val = Qnil;
1399      switch (state) {
1400        case 0:
1401          break;
1402        case TAG_RETURN:
1403          localjump_error("unexpected return", val);
1404          break;
1405        case TAG_NEXT:
1406          localjump_error("unexpected next", val);
1407          break;
1408        case TAG_BREAK:
1409          localjump_error("unexpected break", val);
1410          break;
1411        case TAG_REDO:
1412          localjump_error("unexpected redo", Qnil);
1413          break;
1414        case TAG_RETRY:
1415          localjump_error("retry outside of rescue clause", Qnil);
1416          break;
1417        default:
1418          JUMP_TAG(state);
1419          break;
1420      }
1421  }
1422  
1423  VALUE
1424  rb_eval_cmd(cmd, arg, tcheck)
1425      VALUE cmd, arg;
1426      int tcheck;
1427  {
1428      int state;
1429      VALUE val;                  /* OK */
1430      struct SCOPE *saved_scope;
1431      volatile int safe = ruby_safe_level;
1432  
1433      if (TYPE(cmd) != T_STRING) {
1434          PUSH_ITER(ITER_NOT);
1435          val = rb_funcall2(cmd, rb_intern("call"), RARRAY(arg)->len, RARRAY(arg)->ptr);
1436          POP_ITER();
1437          return val;
1438      }
1439  
1440      saved_scope = ruby_scope;
1441      ruby_scope = top_scope;
1442      PUSH_FRAME();
1443      ruby_frame->last_func = 0;
1444      ruby_frame->orig_func = 0;
1445      ruby_frame->last_class = 0;
1446      ruby_frame->self = ruby_top_self;
1447      ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,0,0,0);
1448      RNODE(ruby_frame->cbase)->nd_clss = ruby_wrapper ? ruby_wrapper : rb_cObject;
1449  
1450      if (tcheck && OBJ_TAINTED(cmd)) {
1451          ruby_safe_level = 4;
1452      }
1453  
1454      PUSH_TAG(PROT_NONE);
1455      if ((state = EXEC_TAG()) == 0) {
1456          val = eval(ruby_top_self, cmd, Qnil, 0, 0);
1457      }
1458      if (ruby_scope->flags & SCOPE_DONT_RECYCLE)
1459         scope_dup(saved_scope);
1460      ruby_scope = saved_scope;
1461      ruby_safe_level = safe;
1462      POP_TAG();
1463      POP_FRAME();
1464  
1465      jump_tag_but_local_jump(state);
1466      return val;
1467  }
1468  
1469  static VALUE
1470  rb_trap_eval(cmd, sig)
1471      VALUE cmd;
1472      int sig;
1473  {
1474      int state;
1475      VALUE val;                  /* OK */
1476  
1477      PUSH_TAG(PROT_NONE);
1478      PUSH_ITER(ITER_NOT);
1479      if ((state = EXEC_TAG()) == 0) {
1480          val = rb_eval_cmd(cmd, rb_ary_new3(1, INT2FIX(sig)), 0);
1481      }
1482      POP_ITER();
1483      POP_TAG();
1484      if (state) {
1485          rb_trap_immediate = 0;
1486          JUMP_TAG(state);
1487      }
1488      return val;
1489  }
1490  
1491  static VALUE
1492  superclass(self, node)
1493      VALUE self;
1494      NODE *node;
1495  {
1496      VALUE val;                  /* OK */
1497      int state;
1498  
1499      PUSH_TAG(PROT_NONE);
1500      if ((state = EXEC_TAG()) == 0) {
1501          val = rb_eval(self, node);
1502      }
1503      POP_TAG();
1504      if (state) {
1505          switch (nd_type(node)) {
1506            case NODE_COLON2:
1507              rb_raise(rb_eTypeError, "undefined superclass `%s'",
1508                       rb_id2name(node->nd_mid));
1509            case NODE_CONST:
1510              rb_raise(rb_eTypeError, "undefined superclass `%s'",
1511                       rb_id2name(node->nd_vid));
1512            default:
1513              break;
1514          }
1515          JUMP_TAG(state);
1516      }
1517      if (TYPE(val) != T_CLASS) {
1518          rb_raise(rb_eTypeError, "superclass must be a Class (%s given)",
1519                   rb_class2name(CLASS_OF(val)));
1520      }
1521      if (FL_TEST(val, FL_SINGLETON)) {
1522          rb_raise(rb_eTypeError, "can't make subclass of virtual class");
1523      }
1524  
1525      return val;
1526  }
1527  
1528  #define ruby_cbase (RNODE(ruby_frame->cbase)->nd_clss)
1529  
1530  static VALUE
1531  ev_const_defined(cref, id, self)
1532      NODE *cref;
1533      ID id;
1534      VALUE self;
1535  {
1536      NODE *cbase = cref;
1537  
1538      while (cbase && cbase->nd_next) {
1539          struct RClass *klass = RCLASS(cbase->nd_clss);
1540  
1541          if (NIL_P(klass)) return rb_const_defined(CLASS_OF(self), id);
1542          if (klass->iv_tbl && st_lookup(klass->iv_tbl, id, 0)) {
1543              return Qtrue;
1544          }
1545          cbase = cbase->nd_next;
1546      }
1547      return rb_const_defined(cref->nd_clss, id);
1548  }
1549  
1550  static VALUE
1551  ev_const_get(cref, id, self)
1552      NODE *cref;
1553      ID id;
1554      VALUE self;
1555  {
1556      NODE *cbase = cref;
1557      VALUE result;
1558  
1559      while (cbase && cbase->nd_next) {
1560          VALUE klass = cbase->nd_clss;
1561  
1562          if (NIL_P(klass)) return rb_const_get(CLASS_OF(self), id);
1563          if (RCLASS(klass)->iv_tbl && st_lookup(RCLASS(klass)->iv_tbl, id, &result)) {
1564              return result;
1565          }
1566          cbase = cbase->nd_next;
1567      }
1568      return rb_const_get(cref->nd_clss, id);
1569  }
1570  
1571  static VALUE
1572  cvar_cbase()
1573  {
1574      NODE *cref = RNODE(ruby_frame->cbase);
1575  
1576      while (cref && cref->nd_next && FL_TEST(cref->nd_clss, FL_SINGLETON)) {
1577          cref = cref->nd_next;
1578          if (!cref->nd_next) {
1579              rb_warn("class variable access from toplevel singleton method");
1580          }
1581      }
1582      return cref->nd_clss;
1583  }
1584  
1585  static VALUE
1586  rb_mod_nesting()
1587  {
1588      NODE *cbase = RNODE(ruby_frame->cbase);
1589      VALUE ary = rb_ary_new();
1590  
1591      while (cbase && cbase->nd_next) {
1592          if (!NIL_P(cbase->nd_clss)) rb_ary_push(ary, cbase->nd_clss);
1593          cbase = cbase->nd_next;
1594      }
1595      return ary;
1596  }
1597  
1598  static VALUE
1599  rb_mod_s_constants()
1600  {
1601      NODE *cbase = RNODE(ruby_frame->cbase);
1602      void *data = 0;
1603  
1604      while (cbase) {
1605          if (!NIL_P(cbase->nd_clss)) {
1606              data = rb_mod_const_at(cbase->nd_clss, data);
1607          }
1608          cbase = cbase->nd_next;
1609      }
1610  
1611      if (!NIL_P(ruby_cbase)) {
1612          data = rb_mod_const_of(ruby_cbase, data);
1613      }
1614      return rb_const_list(data);
1615  }
1616  
1617  void
1618  rb_frozen_class_p(klass)
1619      VALUE klass;
1620  {
1621      char *desc = "something(?!)";
1622  
1623      if (OBJ_FROZEN(klass)) {
1624          if (FL_TEST(klass, FL_SINGLETON))
1625              desc = "object";
1626          else {
1627              switch (TYPE(klass)) {
1628                case T_MODULE:
1629                case T_ICLASS:
1630                  desc = "module"; break;
1631                case T_CLASS:
1632                  desc = "class"; break;
1633              }
1634          }
1635          rb_error_frozen(desc);
1636      }
1637  }
1638  
1639  void
1640  rb_undef(klass, id)
1641      VALUE klass;
1642      ID id;
1643  {
1644      VALUE origin;
1645      NODE *body;
1646  
1647      if (ruby_class == rb_cObject && klass == ruby_class) {
1648          rb_secure(4);
1649      }
1650      if (ruby_safe_level >= 4 && !OBJ_TAINTED(klass)) {
1651          rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'", rb_id2name(id));
1652      }
1653      rb_frozen_class_p(klass);
1654      if (id == __id__ || id == __send__ || id == init || id == alloc) {
1655          rb_warn("undefining `%s' may cause serious problem", rb_id2name(id));
1656      }
1657      body = search_method(klass, id, &origin);
1658      if (!body || !body->nd_body) {
1659          char *s0 = " class";
1660          VALUE c = klass;
1661  
1662          if (FL_TEST(c, FL_SINGLETON)) {
1663              VALUE obj = rb_iv_get(klass, "__attached__");
1664  
1665              switch (TYPE(obj)) {
1666                case T_MODULE:
1667                case T_CLASS:
1668                  c = obj;
1669                  s0 = "";
1670              }
1671          }
1672          else if (TYPE(c) == T_MODULE) {
1673              s0 = " module";
1674          }
1675          rb_name_error(id, "undefined method `%s' for%s `%s'",
1676                        rb_id2name(id),s0,rb_class2name(c));
1677      }
1678      rb_add_method(klass, id, 0, NOEX_PUBLIC);
1679      if (FL_TEST(klass, FL_SINGLETON)) {
1680          rb_funcall(rb_iv_get(klass, "__attached__"),
1681                     singleton_undefined, 1, ID2SYM(id));
1682      }
1683      else {
1684          rb_funcall(klass, undefined, 1, ID2SYM(id));
1685      }
1686  }
1687  
1688  static VALUE
1689  rb_mod_undef_method(mod, name)
1690      VALUE mod, name;
1691  {
1692      rb_undef(mod, rb_to_id(name));
1693      return mod;
1694  }
1695  
1696  void
1697  rb_alias(klass, name, def)
1698      VALUE klass;
1699      ID name, def;
1700  {
1701      VALUE origin;
1702      NODE *orig, *body;
1703      VALUE singleton = 0;
1704  
1705      rb_frozen_class_p(klass);
1706      if (name == def) return;
1707      if (klass == rb_cObject) {
1708          rb_secure(4);
1709      }
1710      orig = search_method(klass, def, &origin);
1711      if (!orig || !orig->nd_body) {
1712          if (TYPE(klass) == T_MODULE) {
1713              orig = search_method(rb_cObject, def, &origin);
1714          }
1715      }
1716      if (!orig || !orig->nd_body) {
1717          print_undef(klass, def);
1718      }
1719      if (FL_TEST(klass, FL_SINGLETON)) {
1720          singleton = rb_iv_get(klass, "__attached__");
1721          if (name == alloc && TYPE(singleton) == T_CLASS) {
1722              rb_raise(rb_eNameError, "cannot make alias named `allocate'");
1723          }
1724      }
1725      body = orig->nd_body;
1726      orig->nd_cnt++;
1727      if (nd_type(body) == NODE_FBODY) { /* was alias */
1728          def = body->nd_mid;
1729          origin = body->nd_orig;
1730          body = body->nd_head;
1731      }
1732  
1733      rb_clear_cache_by_id(name);
1734      st_insert(RCLASS(klass)->m_tbl, name,
1735                NEW_METHOD(NEW_FBODY(body, def, origin), orig->nd_noex));
1736      if (singleton) {
1737          rb_funcall(singleton, singleton_added, 1, ID2SYM(name));
1738      }
1739      else {
1740          rb_funcall(klass, added, 1, ID2SYM(name));
1741      }
1742  }
1743  
1744  static VALUE
1745  rb_mod_alias_method(mod, newname, oldname)
1746      VALUE mod, newname, oldname;
1747  {
1748      rb_alias(mod, rb_to_id(newname), rb_to_id(oldname));
1749      return mod;
1750  }
1751  
1752  static NODE*
1753  copy_node_scope(node, rval)
1754      NODE *node;
1755      VALUE rval;
1756  {
1757      NODE *copy = rb_node_newnode(NODE_SCOPE,0,rval,node->nd_next);
1758  
1759      if (node->nd_tbl) {
1760          copy->nd_tbl = ALLOC_N(ID, node->nd_tbl[0]+1);
1761          MEMCPY(copy->nd_tbl, node->nd_tbl, ID, node->nd_tbl[0]+1);
1762      }
1763      else {
1764          copy->nd_tbl = 0;
1765      }
1766      return copy;
1767  }
1768  
1769  #ifdef C_ALLOCA
1770  # define TMP_PROTECT NODE * volatile tmp__protect_tmp=0
1771  # define TMP_ALLOC(n)                                                   \
1772      (tmp__protect_tmp = rb_node_newnode(NODE_ALLOCA,                    \
1773                               ALLOC_N(VALUE,n),tmp__protect_tmp,n),      \
1774       (void*)tmp__protect_tmp->nd_head)
1775  #else
1776  # define TMP_PROTECT typedef int foobazzz
1777  # define TMP_ALLOC(n) ALLOCA_N(VALUE,n)
1778  #endif
1779  
1780  #define SETUP_ARGS(anode) do {\
1781      NODE *n = anode;\
1782      if (!n) {\
1783          argc = 0;\
1784          argv = 0;\
1785      }\
1786      else if (nd_type(n) == NODE_ARRAY) {\
1787          argc=n->nd_alen;\
1788          if (argc > 0) {\
1789              int i;\
1790              n = anode;\
1791              argv = TMP_ALLOC(argc);\
1792              for (i=0;i<argc;i++) {\
1793                  argv[i] = rb_eval(self,n->nd_head);\
1794                  n=n->nd_next;\
1795              }\
1796          }\
1797          else {\
1798              argc = 0;\
1799              argv = 0;\
1800          }\
1801      }\
1802      else {\
1803          VALUE args = rb_eval(self,n);\
1804          if (TYPE(args) != T_ARRAY)\
1805              args = rb_ary_to_ary(args);\
1806          argc = RARRAY(args)->len;\
1807          argv = ALLOCA_N(VALUE, argc);\
1808          MEMCPY(argv, RARRAY(args)->ptr, VALUE, argc);\
1809      }\
1810  } while (0)
1811  
1812  #define BEGIN_CALLARGS do {\
1813      struct BLOCK *tmp_block = ruby_block;\
1814      if (ruby_iter->iter == ITER_PRE) {\
1815          ruby_block = ruby_block->prev;\
1816      }\
1817      PUSH_ITER(ITER_NOT)
1818  
1819  #define END_CALLARGS \
1820      ruby_block = tmp_block;\
1821      POP_ITER();\
1822  } while (0)
1823  
1824  #define MATCH_DATA *rb_svar(node->nd_cnt)
1825  
1826  static char* is_defined _((VALUE, NODE*, char*));
1827  
1828  static char*
1829  arg_defined(self, node, buf, type)
1830      VALUE self;
1831      NODE *node;
1832      char *buf;
1833      char *type;
1834  {
1835      int argc;
1836      int i;
1837  
1838      if (!node) return type;     /* no args */
1839      if (nd_type(node) == NODE_ARRAY) {
1840          argc=node->nd_alen;
1841          if (argc > 0) {
1842              for (i=0;i<argc;i++) {
1843                  if (!is_defined(self, node->nd_head, buf))
1844                      return 0;
1845                  node = node->nd_next;
1846              }
1847          }
1848      }
1849      else if (!is_defined(self, node, buf)) {
1850          return 0;
1851      }
1852      return type;
1853  }
1854      
1855  static char*
1856  is_defined(self, node, buf)
1857      VALUE self;
1858      NODE *node;                 /* OK */
1859      char *buf;
1860  {
1861      VALUE val;                  /* OK */
1862      int state;
1863  
1864    again:
1865      if (!node) return "expression";
1866      switch (nd_type(node)) {
1867        case NODE_SUPER:
1868        case NODE_ZSUPER:
1869          if (ruby_frame->orig_func == 0) return 0;
1870          else if (ruby_frame->last_class == 0) return 0;
1871          else if (rb_method_boundp(RCLASS(ruby_frame->last_class)->super,
1872                                    ruby_frame->orig_func, 0)) {
1873              if (nd_type(node) == NODE_SUPER) {
1874                  return arg_defined(self, node->nd_args, buf, "super");
1875              }
1876              return "super";
1877          }
1878          break;
1879  
1880        case NODE_VCALL:
1881        case NODE_FCALL:
1882          val = self;
1883          goto check_bound;
1884  
1885        case NODE_CALL:
1886          PUSH_TAG(PROT_NONE);
1887          if ((state = EXEC_TAG()) == 0) {
1888              val = rb_eval(self, node->nd_recv);
1889          }
1890          POP_TAG();
1891          if (state) {
1892              ruby_errinfo = Qnil;
1893              return 0;
1894          }
1895        check_bound:
1896          {
1897              int call = nd_type(node)== NODE_CALL;
1898  
1899              val = CLASS_OF(val);
1900              if (call) {
1901                  int noex;
1902                  ID id = node->nd_mid;
1903  
1904                  if (!rb_get_method_body(&val, &id, &noex))
1905                      break;
1906                  if ((noex & NOEX_PRIVATE))
1907                      break;
1908                  if ((noex & NOEX_PROTECTED) &&
1909                      !rb_obj_is_kind_of(self, rb_class_real(val)))
1910                      break;
1911              }
1912              else if (!rb_method_boundp(val, node->nd_mid, call))
1913                  break;
1914              return arg_defined(self, node->nd_args, buf, "method");
1915          }
1916          break;
1917  
1918        case NODE_MATCH2:
1919        case NODE_MATCH3:
1920          return "method";
1921  
1922        case NODE_YIELD:
1923          if (rb_block_given_p()) {
1924              return "yield";
1925          }
1926          break;
1927  
1928        case NODE_SELF:
1929          return "self";
1930  
1931        case NODE_NIL:
1932          return "nil";
1933  
1934        case NODE_TRUE:
1935          return "true";
1936  
1937        case NODE_FALSE:
1938          return "false";
1939  
1940        case NODE_ATTRSET:
1941        case NODE_OP_ASGN1:
1942        case NODE_OP_ASGN2:
1943        case NODE_MASGN:
1944        case NODE_LASGN:
1945        case NODE_DASGN:
1946        case NODE_DASGN_CURR:
1947        case NODE_GASGN:
1948        case NODE_CDECL:
1949        case NODE_CVDECL:
1950        case NODE_CVASGN:
1951          return "assignment";
1952  
1953        case NODE_LVAR:
1954          return "local-variable";
1955        case NODE_DVAR:
1956          return "local-variable(in-block)";
1957  
1958        case NODE_GVAR:
1959          if (rb_gvar_defined(node->nd_entry)) {
1960              return "global-variable";
1961          }
1962          break;
1963  
1964        case NODE_IVAR:
1965          if (rb_ivar_defined(self, node->nd_vid)) {
1966              return "instance-variable";
1967          }
1968          break;
1969  
1970        case NODE_CONST:
1971          if (ev_const_defined(RNODE(ruby_frame->cbase), node->nd_vid, self)) {
1972              return "constant";
1973          }
1974          break;
1975  
1976        case NODE_CVAR:
1977          if (rb_cvar_defined(cvar_cbase(), node->nd_vid)) {
1978              return "class variable";
1979          }
1980          break;
1981  
1982        case NODE_COLON2:
1983          PUSH_TAG(PROT_NONE);
1984          if ((state = EXEC_TAG()) == 0) {
1985              val = rb_eval(self, node->nd_head);
1986          }
1987          POP_TAG();
1988          if (state) {
1989              ruby_errinfo = Qnil;
1990              return 0;
1991          }
1992          else {
1993              switch (TYPE(val)) {
1994                case T_CLASS:
1995                case T_MODULE:
1996                  if (rb_const_defined_at(val, node->nd_mid))
1997                      return "constant";
1998                  break;
1999                default:
2000                  if (rb_method_boundp(CLASS_OF(val), node->nd_mid, 1)) {
2001                      return "method";
2002                  }
2003              }
2004          }
2005          break;
2006  
2007        case NODE_NTH_REF:
2008          if (RTEST(rb_reg_nth_defined(node->nd_nth, MATCH_DATA))) {
2009              sprintf(buf, "$%d", node->nd_nth);
2010              return buf;
2011          }
2012          break;
2013  
2014        case NODE_BACK_REF:
2015          if (RTEST(rb_reg_nth_defined(0, MATCH_DATA))) {
2016              sprintf(buf, "$%c", node->nd_nth);
2017              return buf;
2018          }
2019          break;
2020  
2021        case NODE_NEWLINE:
2022          node = node->nd_next;
2023          goto again;
2024  
2025        default:
2026          PUSH_TAG(PROT_NONE);
2027          if ((state = EXEC_TAG()) == 0) {
2028              rb_eval(self, node);
2029          }
2030          POP_TAG();
2031          if (!state) {
2032              return "expression";
2033          }
2034          ruby_errinfo = Qnil;
2035          break;
2036      }
2037      return 0;
2038  }
2039  
2040  static int handle_rescue _((VALUE,NODE*));
2041  
2042  static void blk_free();
2043  
2044  static VALUE
2045  rb_obj_is_block(block)
2046      VALUE block;
2047  {
2048      if (TYPE(block) == T_DATA && RDATA(block)->dfree == (RUBY_DATA_FUNC)blk_free) {
2049          return Qtrue;
2050      }
2051      return Qfalse;
2052  }
2053  
2054  static VALUE
2055  rb_obj_is_proc(proc)
2056      VALUE proc;
2057  {
2058      if (rb_obj_is_block(proc) && rb_obj_is_kind_of(proc, rb_cProc)) {
2059          return Qtrue;
2060      }
2061      return Qfalse;
2062  }
2063  
2064  static VALUE
2065  set_trace_func(obj, trace)
2066      VALUE obj, trace;
2067  {
2068      if (NIL_P(trace)) {
2069          trace_func = 0;
2070          return Qnil;
2071      }
2072      if (!rb_obj_is_proc(trace)) {
2073          rb_raise(rb_eTypeError, "trace_func needs to be Proc");
2074      }
2075      return trace_func = trace;
2076  }
2077  
2078  static void
2079  call_trace_func(event, node, self, id, klass)
2080      char *event;
2081      NODE *node;
2082      VALUE self;
2083      ID id;
2084      VALUE klass;                /* OK */
2085  {
2086      int state;
2087      struct FRAME *prev;
2088      NODE *node_save[2];
2089      VALUE srcfile;
2090  
2091      if (!trace_func) return;
2092      if (tracing) return;
2093  
2094      node_save[0] = ruby_last_node;
2095      if (!(node_save[1] = ruby_current_node)) {
2096          node_save[1] = NEW_NEWLINE(0);
2097      }
2098      tracing = 1;
2099      prev = ruby_frame;
2100      PUSH_FRAME();
2101      *ruby_frame = *prev;
2102      ruby_frame->prev = prev;
2103      ruby_frame->iter = 0;       /* blocks not available anyway */
2104  
2105      if (node) {
2106          ruby_current_node = node;
2107          ruby_sourcefile = node->nd_file;
2108          ruby_sourceline = nd_line(node);
2109      }
2110      if (klass) {
2111          if (TYPE(klass) == T_ICLASS) {
2112              klass = RBASIC(klass)->klass;
2113          }
2114          else if (FL_TEST(klass, FL_SINGLETON)) {
2115              klass = self;
2116          }
2117      }
2118      PUSH_TAG(PROT_NONE);
2119      if ((state = EXEC_TAG()) == 0) {
2120          srcfile = rb_str_new2(ruby_sourcefile?ruby_sourcefile:"(ruby)");
2121          proc_invoke(trace_func, rb_ary_new3(6, rb_str_new2(event),
2122                                              srcfile,
2123                                              INT2FIX(ruby_sourceline),
2124                                              id?ID2SYM(id):Qnil,
2125                                              self?rb_f_binding(self):Qnil,
2126                                              klass),
2127                      Qtrue, Qundef);
2128      }
2129      POP_TMPTAG();               /* do not propagate retval */
2130      POP_FRAME();
2131  
2132      tracing = 0;
2133      ruby_last_node = node_save[0];
2134      ruby_current_node = node_save[1];
2135      SET_CURRENT_SOURCE();
2136      if (state) JUMP_TAG(state);
2137  }
2138  
2139  static VALUE
2140  svalue_to_avalue(v)
2141      VALUE v;
2142  {
2143      if (NIL_P(v)) return rb_ary_new2(0);
2144      if (v == Qundef) return rb_ary_new2(0);
2145      if (TYPE(v) == T_ARRAY) {
2146          if (RARRAY(v)->len > 1) return v;
2147          return rb_ary_new3(1, v);
2148      }
2149      else {
2150          v = rb_ary_to_ary(v);
2151      }
2152      return v;
2153  }
2154  
2155  static VALUE
2156  avalue_to_svalue(v)
2157      VALUE v;
2158  {
2159      if (TYPE(v) != T_ARRAY) {
2160          v = rb_ary_to_ary(v);
2161      }
2162      if (RARRAY(v)->len == 0) {
2163          return Qnil;
2164      }
2165      if (RARRAY(v)->len == 1) {
2166          return RARRAY(v)->ptr[0];
2167      }
2168      return v;
2169  }
2170  
2171  static VALUE
2172  avalue_to_yvalue(v)
2173      VALUE v;
2174  {
2175      if (TYPE(v) != T_ARRAY) {
2176          v = rb_ary_to_ary(v);
2177      }
2178      if (RARRAY(v)->len == 0) {
2179          return Qundef;
2180      }
2181      if (RARRAY(v)->len == 1) {
2182          return RARRAY(v)->ptr[0];
2183      }
2184      return v;
2185  }
2186  
2187  static VALUE
2188  svalue_to_mvalue(v)
2189      VALUE v;
2190  {
2191      if (v == Qnil || v == Qundef)
2192          return rb_ary_new2(0);
2193      if (TYPE(v) == T_ARRAY) {
2194          return v;
2195      }
2196      else {
2197          v = rb_ary_to_ary(v);
2198      }
2199      return v;
2200  }
2201  
2202  static VALUE
2203  mvalue_to_svalue(v)
2204      VALUE v;
2205  {
2206      if (TYPE(v) != T_ARRAY) {
2207          v = rb_ary_to_ary(v);
2208      }
2209      if (RARRAY(v)->len == 0) {
2210          return Qnil;
2211      }
2212      if (RARRAY(v)->len == 1 && TYPE(RARRAY(v)->ptr[0]) != T_ARRAY) {
2213          return RARRAY(v)->ptr[0];
2214      }
2215      return v;
2216  }
2217  
2218  static void return_check _((void));
2219  #define return_value(v) prot_tag->retval = (v)
2220  
2221  static VALUE
2222  rb_eval(self, n)
2223      VALUE self;
2224      NODE *n;
2225  {
2226      NODE *nodesave = ruby_current_node;
2227      NODE * volatile node = n;
2228      int state;
2229      volatile VALUE result = Qnil;
2230  
2231  #define RETURN(v) do { \
2232      result = (v); \
2233      goto finish; \
2234  } while (0)
2235  
2236    again:
2237      if (!node) RETURN(Qnil);
2238  
2239      ruby_last_node = ruby_current_node = node;
2240      switch (nd_type(node)) {
2241        case NODE_BLOCK:
2242          while (node->nd_next) {
2243              rb_eval(self, node->nd_head);
2244              node = node->nd_next;
2245          }
2246          node = node->nd_head;
2247          goto again;
2248  
2249        case NODE_POSTEXE:
2250          rb_f_END();
2251          nd_set_type(node, NODE_NIL); /* exec just once */
2252          result = Qnil;
2253          break;
2254  
2255          /* begin .. end without clauses */
2256        case NODE_BEGIN:
2257          node = node->nd_body;
2258          goto again;
2259  
2260          /* nodes for speed-up(default match) */
2261        case NODE_MATCH:
2262          result = rb_reg_match2(node->nd_lit);
2263          break;
2264  
2265          /* nodes for speed-up(literal match) */
2266        case NODE_MATCH2:
2267          result = rb_reg_match(rb_eval(self,node->nd_recv),
2268                                rb_eval(self,node->nd_value));
2269          break;
2270  
2271          /* nodes for speed-up(literal match) */
2272        case NODE_MATCH3:
2273          {
2274              VALUE r = rb_eval(self,node->nd_recv);
2275              VALUE l = rb_eval(self,node->nd_value);
2276              if (TYPE(l) == T_STRING) {
2277                  result = rb_reg_match(r, l);
2278              }
2279              else {
2280                  result = rb_funcall(l, match, 1, r);
2281              }
2282          }
2283          break;
2284  
2285          /* node for speed-up(top-level loop for -n/-p) */
2286        case NODE_OPT_N:
2287          PUSH_TAG(PROT_NONE);
2288          switch (state = EXEC_TAG()) {
2289            case 0:
2290            opt_n_next:
2291              while (!NIL_P(rb_gets())) {
2292                opt_n_redo:
2293                  rb_eval(self, node->nd_body);
2294              }
2295              break;
2296  
2297            case TAG_REDO:
2298              state = 0;
2299              goto opt_n_redo;
2300            case TAG_NEXT:
2301              state = 0;
2302              goto opt_n_next;
2303            case TAG_BREAK:
2304              state = 0;
2305            default:
2306              break;
2307          }
2308          POP_TAG();
2309          if (state) JUMP_TAG(state);
2310          RETURN(Qnil);
2311  
2312        case NODE_SELF:
2313          RETURN(self);
2314  
2315        case NODE_NIL:
2316          RETURN(Qnil);
2317  
2318        case NODE_TRUE:
2319          RETURN(Qtrue);
2320  
2321        case NODE_FALSE:
2322          RETURN(Qfalse);
2323  
2324        case NODE_IF:
2325          if (trace_func) {
2326              call_trace_func("line", node, self,
2327                              ruby_frame->last_func,
2328                              ruby_frame->last_class);    
2329          }
2330          if (RTEST(rb_eval(self, node->nd_cond))) {
2331              node = node->nd_body;
2332          }
2333          else {
2334              node = node->nd_else;
2335          }
2336          goto again;
2337  
2338        case NODE_WHEN:
2339          while (node) {
2340              NODE *tag;
2341  
2342              if (nd_type(node) != NODE_WHEN) goto again;
2343              tag = node->nd_head;
2344              while (tag) {
2345                  if (trace_func) {
2346                      call_trace_func("line", tag, self,
2347                                      ruby_frame->last_func,
2348                                      ruby_frame->last_class);    
2349                  }
2350                  if (nd_type(tag->nd_head) == NODE_WHEN) {
2351                      VALUE v = rb_eval(self, tag->nd_head->nd_head);
2352                      long i;
2353  
2354                      if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v);
2355                      for (i=0; i<RARRAY(v)->len; i++) {
2356                          if (RTEST(RARRAY(v)->ptr[i])) {
2357                              node = node->nd_body;
2358                              goto again;
2359                          }
2360                      }
2361                      tag = tag->nd_next;
2362                      continue;
2363                  }
2364                  if (RTEST(rb_eval(self, tag->nd_head))) {
2365                      node = node->nd_body;
2366                      goto again;
2367                  }
2368                  tag = tag->nd_next;
2369              }
2370              node = node->nd_next;
2371          }
2372          RETURN(Qnil);
2373  
2374        case NODE_CASE:
2375          {
2376              VALUE val;
2377  
2378              val = rb_eval(self, node->nd_head);
2379              node = node->nd_body;
2380              while (node) {
2381                  NODE *tag;
2382  
2383                  if (nd_type(node) != NODE_WHEN) {
2384                      goto again;
2385                  }
2386                  tag = node->nd_head;
2387                  while (tag) {
2388                      if (trace_func) {
2389                          call_trace_func("line", tag, self,
2390                                          ruby_frame->last_func,
2391                                          ruby_frame->last_class);        
2392                      }
2393                      if (nd_type(tag->nd_head) == NODE_WHEN) {
2394                          VALUE v = rb_eval(self, tag->nd_head->nd_head);
2395                          long i;
2396  
2397                          if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v);
2398                          for (i=0; i<RARRAY(v)->len; i++) {
2399                              if (RTEST(rb_funcall2(RARRAY(v)->ptr[i], eqq, 1, &val))){
2400                                  node = node->nd_body;
2401                                  goto again;
2402                              }
2403                          }
2404                          tag = tag->nd_next;
2405                          continue;
2406                      }
2407                      if (RTEST(rb_funcall2(rb_eval(self, tag->nd_head), eqq, 1, &val))) {
2408                          node = node->nd_body;
2409                          goto again;
2410                      }
2411                      tag = tag->nd_next;
2412                  }
2413                  node = node->nd_next;
2414              }
2415          }
2416          RETURN(Qnil);
2417  
2418        case NODE_WHILE:
2419          PUSH_TAG(PROT_NONE);
2420          result = Qnil;
2421          switch (state = EXEC_TAG()) {
2422            case 0:
2423              if (node->nd_state && !RTEST(rb_eval(self, node->nd_cond)))
2424                  goto while_out;
2425              do {
2426                while_redo:
2427                  rb_eval(self, node->nd_body);
2428                while_next:
2429                  ;
2430              } while (RTEST(rb_eval(self, node->nd_cond)));
2431              break;
2432  
2433            case TAG_REDO:
2434              state = 0;
2435              goto while_redo;
2436            case TAG_NEXT:
2437              state = 0;
2438              goto while_next;
2439            case TAG_BREAK:
2440              state = 0;
2441              result = prot_tag->retval;
2442            default:
2443              break;
2444          }
2445        while_out:
2446          POP_TAG();
2447          if (state) JUMP_TAG(state);
2448          RETURN(result);
2449  
2450        case NODE_UNTIL:
2451          PUSH_TAG(PROT_NONE);
2452          result = Qnil;
2453          switch (state = EXEC_TAG()) {
2454            case 0:
2455              if (node->nd_state && RTEST(rb_eval(self, node->nd_cond)))
2456                  goto until_out;
2457              do {
2458                until_redo:
2459                  rb_eval(self, node->nd_body);
2460                until_next:
2461                  ;
2462              } while (!RTEST(rb_eval(self, node->nd_cond)));
2463              break;
2464  
2465            case TAG_REDO:
2466              state = 0;
2467              goto until_redo;
2468            case TAG_NEXT:
2469              state = 0;
2470              goto until_next;
2471            case TAG_BREAK:
2472              state = 0;
2473              result = prot_tag->retval;
2474            default:
2475              break;
2476          }
2477        until_out:
2478          POP_TAG();
2479          if (state) JUMP_TAG(state);
2480          RETURN(result);
2481  
2482        case NODE_BLOCK_PASS:
2483          result = block_pass(self, node);
2484          break;
2485  
2486        case NODE_ITER:
2487        case NODE_FOR:
2488          {
2489            iter_retry:
2490              PUSH_TAG(PROT_FUNC);
2491              PUSH_BLOCK(node->nd_var, node->nd_body);
2492  
2493              state = EXEC_TAG();
2494              if (state == 0) {
2495                  PUSH_ITER(ITER_PRE);
2496                  if (nd_type(node) == NODE_ITER) {
2497                      result = rb_eval(self, node->nd_iter);
2498                  }
2499                  else {
2500                      VALUE recv;
2501  
2502                      _block.flags &= ~BLOCK_D_SCOPE;
2503                      BEGIN_CALLARGS;
2504                      recv = rb_eval(self, node->nd_iter);
2505                      END_CALLARGS;
2506                      ruby_current_node = node;
2507                      SET_CURRENT_SOURCE();
2508                      result = rb_call(CLASS_OF(recv),recv,each,0,0,0);
2509                  }
2510                  POP_ITER();
2511              }
2512              else if (_block.tag->dst == state) {
2513                  state &= TAG_MASK;
2514                  if (state == TAG_RETURN || state == TAG_BREAK) {
2515                      result = prot_tag->retval;
2516                  }
2517              }
2518              POP_BLOCK();
2519              POP_TAG();
2520              switch (state) {
2521                case 0:
2522                  break;
2523  
2524                case TAG_RETRY:
2525                  goto iter_retry;
2526  
2527                case TAG_BREAK:
2528                  break;
2529  
2530                case TAG_RETURN:
2531                  return_value(result);
2532                  /* fall through */
2533                default:
2534                  JUMP_TAG(state);
2535              }
2536          }
2537          break;
2538  
2539        case NODE_BREAK:
2540          if (node->nd_stts) {
2541              return_value(avalue_to_svalue(rb_eval(self, node->nd_stts)));
2542          }
2543          else {
2544              return_value(Qnil);
2545          }
2546          JUMP_TAG(TAG_BREAK);
2547          break;
2548  
2549        case NODE_NEXT:
2550          CHECK_INTS;
2551          if (node->nd_stts) {
2552              return_value(avalue_to_svalue(rb_eval(self, node->nd_stts)));
2553          }
2554          else {
2555              return_value(Qnil);
2556          }
2557          JUMP_TAG(TAG_NEXT);
2558          break;
2559  
2560        case NODE_REDO:
2561          CHECK_INTS;
2562          JUMP_TAG(TAG_REDO);
2563          break;
2564  
2565        case NODE_RETRY:
2566          CHECK_INTS;
2567          JUMP_TAG(TAG_RETRY);
2568          break;
2569  
2570        case NODE_RESTARGS:
2571        case NODE_RESTARY:
2572          result = rb_ary_to_ary(rb_eval(self, node->nd_head));
2573          break;
2574  
2575        case NODE_REXPAND:
2576          result = avalue_to_svalue(rb_eval(self, node->nd_head));
2577          break;
2578  
2579        case NODE_YIELD:
2580          if (node->nd_stts) {
2581              result = avalue_to_yvalue(rb_eval(self, node->nd_stts));
2582          }
2583          else {
2584              result = Qundef;    /* no arg */
2585          }
2586          SET_CURRENT_SOURCE();
2587          result = rb_yield_0(result, 0, 0, 0);
2588          break;
2589  
2590        case NODE_RESCUE:
2591        retry_entry:
2592          {
2593              volatile VALUE e_info = ruby_errinfo;
2594  
2595              PUSH_TAG(PROT_NONE);
2596              if ((state = EXEC_TAG()) == 0) {
2597                  result = rb_eval(self, node->nd_head);
2598              }
2599              POP_TAG();
2600              if (state == TAG_RAISE) {
2601                  NODE * volatile resq = node->nd_resq;
2602  
2603                  while (resq) {
2604                      ruby_current_node = resq;
2605                      if (handle_rescue(self, resq)) {
2606                          state = 0;
2607                          PUSH_TAG(PROT_NONE);
2608                          if ((state = EXEC_TAG()) == 0) {
2609                              result = rb_eval(self, resq->nd_body);
2610                          }
2611                          POP_TAG();
2612                          if (state == TAG_RETRY) {
2613                              state = 0;
2614                              ruby_errinfo = Qnil;
2615                              goto retry_entry;
2616                          }
2617                          if (state != TAG_RAISE) {
2618                              ruby_errinfo = e_info;
2619                          }
2620                          break;
2621                      }
2622                      resq = resq->nd_head; /* next rescue */
2623                  }
2624              }
2625              else if (node->nd_else) { /* else clause given */
2626                  if (!state) {   /* no exception raised */
2627                      result = rb_eval(self, node->nd_else);
2628                  }
2629              }
2630              if (state) JUMP_TAG(state);
2631          }
2632          break;
2633  
2634        case NODE_ENSURE:
2635          PUSH_TAG(PROT_NONE);
2636          if ((state = EXEC_TAG()) == 0) {
2637              result = rb_eval(self, node->nd_head);
2638          }
2639          POP_TAG();
2640          if (node->nd_ensr) {
2641              VALUE retval = prot_tag->retval; /* save retval */
2642              VALUE errinfo = ruby_errinfo;
2643  
2644              rb_eval(self, node->nd_ensr);
2645              return_value(retval);
2646              ruby_errinfo = errinfo;
2647          }
2648          if (state) JUMP_TAG(state);
2649          break;
2650  
2651        case NODE_AND:
2652          result = rb_eval(self, node->nd_1st);
2653          if (!RTEST(result)) break;
2654          node = node->nd_2nd;
2655          goto again;
2656  
2657        case NODE_OR:
2658          result = rb_eval(self, node->nd_1st);
2659          if (RTEST(result)) break;
2660          node = node->nd_2nd;
2661          goto again;
2662  
2663        case NODE_NOT:
2664          if (RTEST(rb_eval(self, node->nd_body))) result = Qfalse;
2665          else result = Qtrue;
2666          break;
2667  
2668        case NODE_DOT2:
2669        case NODE_DOT3:
2670          result = rb_range_new(rb_eval(self, node->nd_beg),
2671                                rb_eval(self, node->nd_end),
2672                                nd_type(node) == NODE_DOT3);
2673          if (node->nd_state) break;
2674          if (nd_type(node->nd_beg) == NODE_LIT && FIXNUM_P(node->nd_beg->nd_lit) &&
2675              nd_type(node->nd_end) == NODE_LIT && FIXNUM_P(node->nd_end->nd_lit))
2676          {
2677              nd_set_type(node, NODE_LIT);
2678              node->nd_lit = result;
2679          }
2680          else {
2681              node->nd_state = 1;
2682          }
2683          break;
2684  
2685        case NODE_FLIP2:          /* like AWK */
2686          {
2687              VALUE *flip = rb_svar(node->nd_cnt);
2688              if (!flip) rb_bug("unexpected local variable");
2689              if (!RTEST(*flip)) {
2690                  if (RTEST(rb_eval(self, node->nd_beg))) {
2691                      *flip = RTEST(rb_eval(self, node->nd_end))?Qfalse:Qtrue;
2692                      result = Qtrue;
2693                  }
2694                  else {
2695                      result = Qfalse;
2696                  }
2697              }
2698              else {
2699                  if (RTEST(rb_eval(self, node->nd_end))) {
2700                      *flip = Qfalse;
2701                  }
2702                  result = Qtrue;
2703              }
2704          }
2705          break;
2706  
2707        case NODE_FLIP3:          /* like SED */
2708          {
2709              VALUE *flip = rb_svar(node->nd_cnt);
2710              if (!flip) rb_bug("unexpected local variable");
2711              if (!RTEST(*flip)) {
2712                  result = RTEST(rb_eval(self, node->nd_beg)) ? Qtrue : Qfalse;
2713                  *flip = result;
2714              }
2715              else {
2716                  if (RTEST(rb_eval(self, node->nd_end))) {
2717                      *flip = Qfalse;
2718                  }
2719                  result = Qtrue;
2720              }
2721          }
2722          break;
2723  
2724        case NODE_RETURN:
2725          if (node->nd_stts) {
2726              return_value(avalue_to_svalue(rb_eval(self, node->nd_stts)));
2727          }
2728          else {
2729              return_value(Qnil);
2730          }
2731          return_check();
2732          JUMP_TAG(TAG_RETURN);
2733          break;
2734  
2735        case NODE_ARGSCAT:
2736          result = rb_ary_concat(rb_eval(self, node->nd_head),
2737                                 rb_eval(self, node->nd_body));
2738          break;
2739  
2740        case NODE_ARGSPUSH:
2741          result = rb_ary_push(rb_ary_dup(rb_eval(self, node->nd_head)),
2742                               rb_eval(self, node->nd_body));
2743          break;
2744  
2745        case NODE_CALL:
2746          {
2747              VALUE recv;
2748              int argc; VALUE *argv; /* used in SETUP_ARGS */
2749              TMP_PROTECT;
2750  
2751              BEGIN_CALLARGS;
2752              recv = rb_eval(self, node->nd_recv);
2753              SETUP_ARGS(node->nd_args);
2754              END_CALLARGS;
2755  
2756              SET_CURRENT_SOURCE();
2757              result = rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,0);
2758          }
2759          break;
2760  
2761        case NODE_FCALL:
2762          {
2763              int argc; VALUE *argv; /* used in SETUP_ARGS */
2764              TMP_PROTECT;
2765  
2766              BEGIN_CALLARGS;
2767              SETUP_ARGS(node->nd_args);
2768              END_CALLARGS;
2769  
2770              SET_CURRENT_SOURCE();
2771              result = rb_call(CLASS_OF(self),self,node->nd_mid,argc,argv,1);
2772          }
2773          break;
2774  
2775        case NODE_VCALL:
2776          SET_CURRENT_SOURCE();
2777          result = rb_call(CLASS_OF(self),self,node->nd_mid,0,0,2);
2778          break;
2779  
2780        case NODE_SUPER:
2781        case NODE_ZSUPER:
2782          {
2783              int argc; VALUE *argv; /* used in SETUP_ARGS */
2784              TMP_PROTECT;
2785  
2786              if (ruby_frame->last_class == 0) {  
2787                  if (ruby_frame->orig_func) {
2788                      rb_name_error(ruby_frame->last_func,
2789                                    "superclass method `%s' disabled",
2790                                    rb_id2name(ruby_frame->orig_func));
2791                  }
2792                  else {
2793                      rb_raise(rb_eNoMethodError, "super called outside of method");
2794                  }
2795              }
2796              if (nd_type(node) == NODE_ZSUPER) {
2797                  argc = ruby_frame->argc;
2798                  argv = ruby_frame->argv;
2799              }
2800              else {
2801                  BEGIN_CALLARGS;
2802                  SETUP_ARGS(node->nd_args);
2803                  END_CALLARGS;
2804              }
2805  
2806              PUSH_ITER(ruby_iter->iter?ITER_PRE:ITER_NOT);
2807              SET_CURRENT_SOURCE();
2808              result = rb_call(RCLASS(ruby_frame->last_class)->super,
2809                               ruby_frame->self, ruby_frame->orig_func,
2810                               argc, argv, 3);
2811              POP_ITER();
2812          }
2813          break;
2814  
2815        case NODE_SCOPE:
2816          {
2817              struct FRAME frame;
2818              NODE *saved_cref = 0;
2819  
2820              frame = *ruby_frame;
2821              frame.tmp = ruby_frame;
2822              ruby_frame = &frame;
2823  
2824              PUSH_SCOPE();
2825              PUSH_TAG(PROT_NONE);
2826              if (node->nd_rval) {
2827                  saved_cref = ruby_cref;
2828                  ruby_cref = (NODE*)node->nd_rval;
2829                  ruby_frame->cbase = node->nd_rval;
2830              }
2831              if (node->nd_tbl) {
2832                  VALUE *vars = ALLOCA_N(VALUE, node->nd_tbl[0]+1);
2833                  *vars++ = (VALUE)node;
2834                  ruby_scope->local_vars = vars;
2835                  rb_mem_clear(ruby_scope->local_vars, node->nd_tbl[0]);
2836                  ruby_scope->local_tbl = node->nd_tbl;
2837              }
2838              else {
2839                  ruby_scope->local_vars = 0;
2840                  ruby_scope->local_tbl  = 0;
2841              }
2842              if ((state = EXEC_TAG()) == 0) {
2843                  result = rb_eval(self, node->nd_next);
2844              }
2845              POP_TAG();
2846              POP_SCOPE();
2847              ruby_frame = frame.tmp;
2848              if (saved_cref)
2849                  ruby_cref = saved_cref;
2850              if (state) JUMP_TAG(state);
2851          }
2852          break;
2853  
2854        case NODE_OP_ASGN1:
2855          {
2856              int argc; VALUE *argv; /* used in SETUP_ARGS */
2857              VALUE recv, val;
2858              NODE *rval;
2859              TMP_PROTECT;
2860  
2861              recv = rb_eval(self, node->nd_recv);
2862              rval = node->nd_args->nd_head;
2863              SETUP_ARGS(node->nd_args->nd_next);
2864              val = rb_funcall2(recv, aref, argc-1, argv);
2865              switch (node->nd_mid) {
2866              case 0: /* OR */
2867                  if (RTEST(val)) RETURN(val);
2868                  val = rb_eval(self, rval);
2869                  break;
2870              case 1: /* AND */
2871                  if (!RTEST(val)) RETURN(val);
2872                  val = rb_eval(self, rval);
2873                  break;
2874              default:
2875                  val = rb_funcall(val, node->nd_mid, 1, rb_eval(self, rval));
2876              }
2877              argv[argc-1] = val;
2878              rb_funcall2(recv, aset, argc, argv);
2879              result = val;
2880          }
2881          break;
2882  
2883        case NODE_OP_ASGN2:
2884          {
2885              ID id = node->nd_next->nd_vid;
2886              VALUE recv, val;
2887  
2888              recv = rb_eval(self, node->nd_recv);
2889              val = rb_funcall(recv, id, 0);
2890              switch (node->nd_next->nd_mid) {
2891              case 0: /* OR */
2892                  if (RTEST(val)) RETURN(val);
2893                  val = rb_eval(self, node->nd_value);
2894                  break;
2895              case 1: /* AND */
2896                  if (!RTEST(val)) RETURN(val);
2897                  val = rb_eval(self, node->nd_value);
2898                  break;
2899              default:
2900                  val = rb_funcall(val, node->nd_next->nd_mid, 1,
2901                                   rb_eval(self, node->nd_value));
2902              }
2903  
2904              rb_funcall2(recv, node->nd_next->nd_aid, 1, &val);
2905              result = val;
2906          }
2907          break;
2908  
2909        case NODE_OP_ASGN_AND:
2910          result = rb_eval(self, node->nd_head);
2911          if (!RTEST(result)) break;
2912          node = node->nd_value;
2913          goto again;
2914  
2915        case NODE_OP_ASGN_OR:
2916          if ((node->nd_aid && !rb_ivar_defined(self, node->nd_aid)) ||
2917              !RTEST(result = rb_eval(self, node->nd_head))) {
2918              node = node->nd_value;
2919              goto again;
2920          }
2921          break;
2922  
2923        case NODE_MASGN:
2924          result = massign(self, node, rb_eval(self, node->nd_value),0);
2925          break;
2926  
2927        case NODE_LASGN:
2928          if (ruby_scope->local_vars == 0)
2929              rb_bug("unexpected local variable assignment");
2930          result = rb_eval(self, node->nd_value);
2931          ruby_scope->local_vars[node->nd_cnt] = result;
2932          break;
2933  
2934        case NODE_DASGN:
2935          result = rb_eval(self, node->nd_value);
2936          dvar_asgn(node->nd_vid, result);
2937          break;
2938  
2939        case NODE_DASGN_CURR:
2940          result = rb_eval(self, node->nd_value);
2941          dvar_asgn_curr(node->nd_vid, result);
2942          break;
2943  
2944        case NODE_GASGN:
2945          result = rb_eval(self, node->nd_value);
2946          rb_gvar_set(node->nd_entry, result);
2947          break;
2948  
2949        case NODE_IASGN:
2950          result = rb_eval(self, node->nd_value);
2951          rb_ivar_set(self, node->nd_vid, result);
2952          break;
2953  
2954        case NODE_CDECL:
2955          if (NIL_P(ruby_class)) {
2956              rb_raise(rb_eTypeError, "no class/module to define constant");
2957          }
2958          result = rb_eval(self, node->nd_value);
2959          rb_const_set(ruby_cbase, node->nd_vid, result);
2960          break;
2961  
2962        case NODE_CVDECL:
2963          if (NIL_P(ruby_cbase)) {
2964              rb_raise(rb_eTypeError, "no class/module to define class variable");
2965          }
2966          result = rb_eval(self, node->nd_value);
2967          rb_cvar_set(cvar_cbase(), node->nd_vid, result, Qtrue);
2968          break;
2969  
2970        case NODE_CVASGN:
2971          result = rb_eval(self, node->nd_value);
2972          rb_cvar_set(cvar_cbase(), node->nd_vid, result, Qfalse);
2973          break;
2974  
2975        case NODE_LVAR:
2976          if (ruby_scope->local_vars == 0) {
2977              rb_bug("unexpected local variable");
2978          }
2979          result = ruby_scope->local_vars[node->nd_cnt];
2980          break;
2981  
2982        case NODE_DVAR:
2983          result = rb_dvar_ref(node->nd_vid);
2984          break;
2985  
2986        case NODE_GVAR:
2987          result = rb_gvar_get(node->nd_entry);
2988          break;
2989  
2990        case NODE_IVAR:
2991          result = rb_ivar_get(self, node->nd_vid);
2992          break;
2993  
2994        case NODE_CONST:
2995          result = ev_const_get(RNODE(ruby_frame->cbase), node->nd_vid, self);
2996          break;
2997  
2998        case NODE_CVAR:
2999          result = rb_cvar_get(cvar_cbase(), node->nd_vid);
3000          break;
3001  
3002        case NODE_BLOCK_ARG:
3003          if (ruby_scope->local_vars == 0)
3004              rb_bug("unexpected block argument");
3005          if (rb_block_given_p()) {
3006              result = rb_f_lambda();
3007              ruby_scope->local_vars[node->nd_cnt] = result;
3008          }
3009          else {
3010              result = Qnil;
3011          }
3012          break;
3013  
3014        case NODE_COLON2:
3015          {
3016              VALUE klass;
3017  
3018              klass = rb_eval(self, node->nd_head);
3019              switch (TYPE(klass)) {
3020                case T_CLASS:
3021                case T_MODULE:
3022                  result = rb_const_get(klass, node->nd_mid);
3023                  break;
3024                default:
3025                  result = rb_funcall(klass, node->nd_mid, 0, 0);
3026                  break;
3027              }
3028          }
3029          break;
3030  
3031        case NODE_COLON3:
3032          result = rb_const_get_at(rb_cObject, node->nd_mid);
3033          break;
3034  
3035        case NODE_NTH_REF:
3036          result = rb_reg_nth_match(node->nd_nth, MATCH_DATA);
3037          break;
3038  
3039        case NODE_BACK_REF:
3040          switch (node->nd_nth) {
3041            case '&':
3042              result = rb_reg_last_match(MATCH_DATA);
3043              break;
3044            case '`':
3045              result = rb_reg_match_pre(MATCH_DATA);
3046              break;
3047            case '\'':
3048              result = rb_reg_match_post(MATCH_DATA);
3049              break;
3050            case '+':
3051              result = rb_reg_match_last(MATCH_DATA);
3052              break;
3053            default:
3054              rb_bug("unexpected back-ref");
3055          }
3056          break;
3057  
3058        case NODE_HASH:
3059          {
3060              NODE *list;
3061              VALUE hash = rb_hash_new();
3062              VALUE key, val;
3063  
3064              list = node->nd_head;
3065              while (list) {
3066                  key = rb_eval(self, list->nd_head);
3067                  list = list->nd_next;
3068                  if (list == 0)
3069                      rb_bug("odd number list for Hash");
3070                  val = rb_eval(self, list->nd_head);
3071                  list = list->nd_next;
3072                  rb_hash_aset(hash, key, val);
3073              }
3074              result = hash;
3075          }
3076          break;
3077  
3078        case NODE_ZARRAY:         /* zero length list */
3079          result = rb_ary_new();
3080          break;
3081  
3082        case NODE_ARRAY:
3083          {
3084              VALUE ary;
3085              long i;
3086  
3087              i = node->nd_alen;
3088              ary = rb_ary_new2(i);
3089              for (i=0;node;node=node->nd_next) {
3090                  RARRAY(ary)->ptr[i++] = rb_eval(self, node->nd_head);
3091                  RARRAY(ary)->len = i;
3092              }
3093  
3094              result = ary;
3095          }
3096          break;
3097  
3098        case NODE_STR:
3099          result = rb_str_new3(node->nd_lit);
3100          break;
3101  
3102        case NODE_EVSTR:
3103          result = rb_obj_as_string(rb_eval(self, node->nd_body));
3104          break;
3105  
3106        case NODE_DSTR:
3107        case NODE_DXSTR:
3108        case NODE_DREGX:
3109        case NODE_DREGX_ONCE:
3110          {
3111              VALUE str, str2;
3112              NODE *list = node->nd_next;
3113  
3114              str = rb_str_new3(node->nd_lit);
3115              while (list) {
3116                  if (list->nd_head) {
3117                      switch (nd_type(list->nd_head)) {
3118                        case NODE_STR:
3119                          str2 = list->nd_head->nd_lit;
3120                          break;
3121                        default:
3122                          str2 = rb_eval(self, list->nd_head);
3123                          break;
3124                      }
3125                      rb_str_append(str, str2);
3126                      OBJ_INFECT(str, str2);
3127                  }
3128                  list = list->nd_next;
3129              }
3130              switch (nd_type(node)) {
3131                case NODE_DREGX:
3132                  result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
3133                                   node->nd_cflag);
3134                  break;
3135                case NODE_DREGX_ONCE:     /* regexp expand once */
3136                  result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
3137                                   node->nd_cflag);
3138                  nd_set_type(node, NODE_LIT);
3139                  node->nd_lit = result;
3140                  break;
3141                case NODE_DXSTR:
3142                  result = rb_funcall(self, '`', 1, str);
3143                  break;
3144                default:
3145                  result = str;
3146                  break;
3147              }
3148          }
3149          break;
3150  
3151        case NODE_XSTR:
3152          result = rb_funcall(self, '`', 1, node->nd_lit);
3153          break;
3154  
3155        case NODE_LIT:
3156          result = node->nd_lit;
3157          break;
3158  
3159        case NODE_ATTRSET:
3160          if (ruby_frame->argc != 1)
3161              rb_raise(rb_eArgError, "wrong number of arguments(%d for 1)",
3162                       ruby_frame->argc);
3163          result = rb_ivar_set(self, node->nd_vid, ruby_frame->argv[0]);
3164          break;
3165  
3166        case NODE_DEFN:
3167          if (node->nd_defn) {
3168              NODE *body,  *defn;
3169              VALUE origin;
3170              int noex;
3171  
3172              if (NIL_P(ruby_class)) {
3173                  rb_raise(rb_eTypeError, "no class/module to add method");
3174              }
3175              if (ruby_class == rb_cClass && node->nd_mid == alloc) {
3176                  rb_raise(rb_eNameError, "redefining Class#allocate will cause infinite loop");
3177              }
3178              if (ruby_class == rb_cObject && node->nd_mid == init) {
3179                  rb_warn("redefining Object#initialize may cause infinite loop");
3180              }
3181              if (node->nd_mid == __id__ || node->nd_mid == __send__) {
3182                  rb_warn("redefining `%s' may cause serious problem",
3183                          rb_id2name(node->nd_mid));
3184              }
3185              rb_frozen_class_p(ruby_class);
3186              body = search_method(ruby_class, node->nd_mid, &origin);
3187              if (body){
3188                  if (RTEST(ruby_verbose) && ruby_class == origin && body->nd_cnt == 0) {
3189                      rb_warning("method redefined; discarding old %s", rb_id2name(node->nd_mid));
3190                  }
3191                  if (node->nd_noex) { /* toplevel */
3192                      /* should upgrade to rb_warn() if no super was called inside? */
3193                      rb_warning("overriding global function `%s'",
3194                                 rb_id2name(node->nd_mid));
3195                  }
3196              }
3197  
3198              if (SCOPE_TEST(SCOPE_PRIVATE) || node->nd_mid == init) {
3199                  noex = NOEX_PRIVATE;
3200              }
3201              else if (SCOPE_TEST(SCOPE_PROTECTED)) {
3202                  noex = NOEX_PROTECTED;
3203              }
3204              else if (ruby_class == rb_cObject) {
3205                  noex =  node->nd_noex;
3206              }
3207              else {
3208                  noex = NOEX_PUBLIC;
3209              }
3210              if (body && origin == ruby_class && body->nd_noex & NOEX_UNDEF) {
3211                  noex |= NOEX_UNDEF;
3212              }
3213  
3214              defn = copy_node_scope(node->nd_defn, ruby_cref);
3215              rb_add_method(ruby_class, node->nd_mid, defn, noex);
3216              if (scope_vmode == SCOPE_MODFUNC) {
3217                  rb_add_method(rb_singleton_class(ruby_class),
3218                                node->nd_mid, defn, NOEX_PUBLIC);
3219                  rb_funcall(ruby_class, singleton_added, 1, ID2SYM(node->nd_mid));
3220              }
3221              if (FL_TEST(ruby_class, FL_SINGLETON)) {
3222                  rb_funcall(rb_iv_get(ruby_class, "__attached__"),
3223                             singleton_added, 1, ID2SYM(node->nd_mid));
3224              }
3225              else {
3226                  rb_funcall(ruby_class, added, 1, ID2SYM(node->nd_mid));
3227              }
3228              result = Qnil;
3229          }
3230          break;
3231  
3232        case NODE_DEFS:
3233          if (node->nd_defn) {
3234              VALUE recv = rb_eval(self, node->nd_recv);
3235              VALUE klass;
3236              NODE *body = 0, *defn;
3237  
3238              if (ruby_safe_level >= 4 && !OBJ_TAINTED(recv)) {
3239                  rb_raise(rb_eSecurityError, "Insecure: can't define singleton method");
3240              }
3241              if (FIXNUM_P(recv) || SYMBOL_P(recv)) {
3242                  rb_raise(rb_eTypeError,
3243                           "can't define singleton method \"%s\" for %s",
3244                           rb_id2name(node->nd_mid),
3245                           rb_class2name(CLASS_OF(recv)));
3246              }
3247  
3248              if (OBJ_FROZEN(recv)) rb_error_frozen("object");
3249              klass = rb_singleton_class(recv);
3250              if (st_lookup(RCLASS(klass)->m_tbl, node->nd_mid, &body)) {
3251                  if (ruby_safe_level >= 4) {
3252                      rb_raise(rb_eSecurityError, "redefining method prohibited");
3253                  }
3254                  if (RTEST(ruby_verbose)) {
3255                      rb_warning("redefine %s", rb_id2name(node->nd_mid));
3256                  }
3257              }
3258              defn = copy_node_scope(node->nd_defn, ruby_cref);
3259              defn->nd_rval = (VALUE)ruby_cref;
3260              rb_add_method(klass, node->nd_mid, defn, 
3261                            NOEX_PUBLIC|(body?body->nd_noex&NOEX_UNDEF:0));
3262              rb_funcall(recv, singleton_added, 1, ID2SYM(node->nd_mid));
3263              result = Qnil;
3264          }
3265          break;
3266  
3267        case NODE_UNDEF:
3268          if (NIL_P(ruby_class)) {
3269              rb_raise(rb_eTypeError, "no class to undef method");
3270          }
3271          rb_undef(ruby_class, node->nd_mid);
3272          result = Qnil;
3273          break;
3274  
3275        case NODE_ALIAS:
3276          if (NIL_P(ruby_class)) {
3277              rb_raise(rb_eTypeError, "no class to make alias");
3278          }
3279          rb_alias(ruby_class, node->nd_new, node->nd_old);
3280          result = Qnil;
3281          break;
3282  
3283        case NODE_VALIAS:
3284          rb_alias_variable(node->nd_new, node->nd_old);
3285          result = Qnil;
3286          break;
3287  
3288        case NODE_CLASS:
3289          {
3290              VALUE super, klass, tmp;
3291  
3292              if (NIL_P(ruby_class)) {
3293                  rb_raise(rb_eTypeError, "no outer class/module");
3294              }
3295              if (node->nd_super) {
3296                  super = superclass(self, node->nd_super);
3297              }
3298              else {
3299                  super = 0;
3300              }
3301  
3302              if ((ruby_class == rb_cObject) && rb_autoload_defined(node->nd_cname)) {
3303                  rb_autoload_load(node->nd_cname);
3304              }
3305              if (rb_const_defined_at(ruby_class, node->nd_cname)) {
3306                  klass = rb_const_get(ruby_class, node->nd_cname);
3307                  if (TYPE(klass) != T_CLASS) {
3308                      rb_raise(rb_eTypeError, "%s is not a class",
3309                               rb_id2name(node->nd_cname));
3310                  }
3311                  if (super) {
3312                      tmp = rb_class_real(RCLASS(klass)->super);
3313                      if (tmp != super) {
3314                          goto override_class;
3315                      }
3316                  }
3317                  if (ruby_safe_level >= 4) {
3318                      rb_raise(rb_eSecurityError, "extending class prohibited");
3319                  }
3320              }
3321              else {
3322                override_class:
3323                  if (!super) super = rb_cObject;
3324                  klass = rb_define_class_id(node->nd_cname, super);
3325                  rb_set_class_path(klass,ruby_class,rb_id2name(node->nd_cname));
3326                  rb_class_inherited(super, klass);
3327                  rb_const_set(ruby_cbase, node->nd_cname, klass);
3328              }
3329              if (ruby_wrapper) {
3330                  rb_extend_object(klass, ruby_wrapper);
3331                  rb_include_module(klass, ruby_wrapper);
3332              }
3333  
3334              result = module_setup(klass, node->nd_body);
3335          }
3336          break;
3337  
3338        case NODE_MODULE:
3339          {
3340              VALUE module;
3341  
3342              if (NIL_P(ruby_class)) {
3343                  rb_raise(rb_eTypeError, "no outer class/module");
3344              }
3345              if ((ruby_class == rb_cObject) && rb_autoload_defined(node->nd_cname)) {
3346                  rb_autoload_load(node->nd_cname);
3347              }
3348              if (rb_const_defined_at(ruby_class, node->nd_cname)) {
3349                  module = rb_const_get(ruby_class, node->nd_cname);
3350                  if (TYPE(module) != T_MODULE) {
3351                      rb_raise(rb_eTypeError, "%s is not a module",
3352                               rb_id2name(node->nd_cname));
3353                  }
3354                  if (ruby_safe_level >= 4) {
3355                      rb_raise(rb_eSecurityError, "extending module prohibited");
3356                  }
3357              }
3358              else {
3359                  module = rb_define_module_id(node->nd_cname);
3360                  rb_const_set(ruby_cbase, node->nd_cname, module);
3361                  rb_set_class_path(module,ruby_class,rb_id2name(node->nd_cname));
3362              }
3363              if (ruby_wrapper) {
3364                  rb_extend_object(module, ruby_wrapper);
3365                  rb_include_module(module, ruby_wrapper);
3366              }
3367  
3368              result = module_setup(module, node->nd_body);
3369          }
3370          break;
3371  
3372        case NODE_SCLASS:
3373          {
3374              VALUE klass;
3375  
3376              result = rb_eval(self, node->nd_recv);
3377              if (FIXNUM_P(result) || SYMBOL_P(result)) {
3378                  rb_raise(rb_eTypeError, "no virtual class for %s",
3379                           rb_class2name(CLASS_OF(result)));
3380              }
3381              if (ruby_safe_level >= 4 && !OBJ_TAINTED(result))
3382                  rb_raise(rb_eSecurityError, "Insecure: can't extend object");
3383              klass = rb_singleton_class(result);
3384              
3385              if (ruby_wrapper) {
3386                  rb_extend_object(klass, ruby_wrapper);
3387                  rb_include_module(klass, ruby_wrapper);
3388              }
3389              
3390              result = module_setup(klass, node->nd_body);
3391          }
3392          break;
3393  
3394        case NODE_DEFINED:
3395          {
3396              char buf[20];
3397              char *desc = is_defined(self, node->nd_head, buf);
3398  
3399              if (desc) result = rb_str_new2(desc);
3400              else result = Qnil;
3401          }
3402          break;
3403  
3404        case NODE_NEWLINE:
3405          ruby_sourcefile = node->nd_file;
3406          ruby_sourceline = node->nd_nth;
3407          if (trace_func) {
3408              call_trace_func("line", node, self,
3409                              ruby_frame->last_func,
3410                              ruby_frame->last_class);    
3411          }
3412          node = node->nd_next;
3413          goto again;
3414  
3415        default:
3416          rb_bug("unknown node type %d", nd_type(node));
3417      }
3418    finish:
3419      CHECK_INTS;
3420      ruby_current_node = nodesave;
3421      return result;
3422  }
3423  
3424  static VALUE
3425  module_setup(module, n)
3426      VALUE module;
3427      NODE *n;
3428  {
3429      NODE * volatile node = n;
3430      int state;
3431      struct FRAME frame;
3432      VALUE result;               /* OK */
3433      TMP_PROTECT;
3434  
3435      frame = *ruby_frame;
3436      frame.tmp = ruby_frame;
3437      ruby_frame = &frame;
3438  
3439      PUSH_CLASS();
3440      ruby_class = module;
3441      PUSH_SCOPE();
3442      PUSH_VARS();
3443  
3444      if (node->nd_tbl) {
3445          VALUE *vars = TMP_ALLOC(node->nd_tbl[0]+1);
3446          *vars++ = (VALUE)node;
3447          ruby_scope->local_vars = vars;
3448          rb_mem_clear(ruby_scope->local_vars, node->nd_tbl[0]);
3449          ruby_scope->local_tbl = node->nd_tbl;
3450      }
3451      else {
3452          ruby_scope->local_vars = 0;
3453          ruby_scope->local_tbl  = 0;
3454      }
3455  
3456      PUSH_CREF(module);
3457      ruby_frame->cbase = (VALUE)ruby_cref;
3458      PUSH_TAG(PROT_NONE);
3459      if ((state = EXEC_TAG()) == 0) {
3460          if (trace_func) {
3461              call_trace_func("class", ruby_current_node, ruby_class,
3462                              ruby_frame->last_func,
3463                              ruby_frame->last_class);
3464          }
3465          result = rb_eval(ruby_class, node->nd_next);
3466      }
3467      POP_TAG();
3468      POP_CREF();
3469      POP_VARS();
3470      POP_SCOPE();
3471      POP_CLASS();
3472  
3473      ruby_frame = frame.tmp;
3474      if (trace_func) {
3475          call_trace_func("end", ruby_last_node, 0,
3476                          ruby_frame->last_func, ruby_frame->last_class);
3477      }
3478      if (state) JUMP_TAG(state);
3479  
3480      return result;
3481  }
3482  
3483  int
3484  rb_respond_to(obj, id)
3485      VALUE obj;
3486      ID id;
3487  {
3488      if (rb_method_boundp(CLASS_OF(obj), id, 0)) {
3489          return Qtrue;
3490      }
3491      return Qfalse;
3492  }
3493  
3494  static VALUE
3495  rb_obj_respond_to(argc, argv, obj)
3496      int argc;
3497      VALUE *argv;
3498      VALUE obj;
3499  {
3500      VALUE mid, priv;
3501      ID id;
3502  
3503      rb_scan_args(argc, argv, "11", &mid, &priv);
3504      id = rb_to_id(mid);
3505      if (rb_method_boundp(CLASS_OF(obj), id, !RTEST(priv))) {
3506          return Qtrue;
3507      }
3508      return Qfalse;
3509  }
3510  
3511  static VALUE
3512  rb_mod_method_defined(mod, mid)
3513      VALUE mod, mid;
3514  {
3515      if (rb_method_boundp(mod, rb_to_id(mid), 1)) {
3516          return Qtrue;
3517      }
3518      return Qfalse;
3519  }
3520  
3521  NORETURN(static void terminate_process _((int, const char*, long)));
3522  static void
3523  terminate_process(status, mesg, mlen)
3524      int status;
3525      const char *mesg;
3526      long mlen;
3527  {
3528      VALUE exit = rb_exc_new(rb_eSystemExit, mesg, mlen);
3529  
3530      rb_iv_set(exit, "status", INT2NUM(status));
3531      rb_exc_raise(exit);
3532  }
3533  
3534  void
3535  rb_exit(status)
3536      int status;
3537  {
3538      if (prot_tag) {
3539          terminate_process(status, "exit", 4);
3540      }
3541      ruby_finalize();
3542      exit(status);
3543  }
3544  
3545  static VALUE
3546  rb_f_exit(argc, argv, obj)
3547      int argc;
3548      VALUE *argv;
3549      VALUE obj;
3550  {
3551      VALUE status;
3552      int istatus;
3553  
3554      rb_secure(4);
3555      if (rb_scan_args(argc, argv, "01", &status) == 1) {
3556          istatus = NUM2INT(status);
3557      }
3558      else {
3559          istatus = 0;
3560      }
3561      rb_exit(istatus);
3562      return Qnil;                /* not reached */
3563  }
3564  
3565  static VALUE
3566  rb_f_abort(argc, argv)
3567      int argc;
3568      VALUE *argv;
3569  {
3570      rb_secure(4);
3571      if (argc == 0) {
3572          if (!NIL_P(ruby_errinfo)) {
3573              error_print();
3574          }
3575          rb_exit(1);
3576      }
3577      else {
3578          VALUE mesg;
3579  
3580          rb_scan_args(argc, argv, "1", &mesg);
3581          StringValue(argv[0]);
3582          rb_io_puts(argc, argv, rb_stderr);
3583          terminate_process(1, RSTRING(argv[0])->ptr, RSTRING(argv[0])->len);
3584      }
3585      return Qnil;                /* not reached */
3586  }
3587  
3588  void
3589  rb_iter_break()
3590  {
3591      JUMP_TAG(TAG_BREAK);
3592  }
3593  
3594  NORETURN(static void rb_longjmp _((int, VALUE)));
3595  static VALUE make_backtrace _((void));
3596  
3597  static void
3598  rb_longjmp(tag, mesg)
3599      int tag;
3600      VALUE mesg;
3601  {
3602      VALUE at;
3603  
3604      if (NIL_P(mesg)) mesg = ruby_errinfo;
3605      if (NIL_P(mesg)) {
3606          mesg = rb_exc_new(rb_eRuntimeError, 0, 0);
3607      }
3608  
3609      ruby_set_current_source();
3610      if (ruby_sourcefile && !NIL_P(mesg)) {
3611          at = get_backtrace(mesg);
3612          if (NIL_P(at)) {
3613              at = make_backtrace();
3614              set_backtrace(mesg, at);
3615          }
3616      }
3617      if (!NIL_P(mesg)) {
3618          ruby_errinfo = mesg;
3619      }
3620  
3621      if (RTEST(ruby_debug) && !NIL_P(ruby_errinfo)
3622          && !rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
3623          VALUE e = ruby_errinfo;
3624  
3625          StringValue(e);
3626          fprintf(stderr, "Exception `%s' at %s:%d - %s\n",
3627                  rb_class2name(CLASS_OF(ruby_errinfo)),
3628                  ruby_sourcefile, ruby_sourceline,
3629                  RSTRING(e)->ptr);
3630      }
3631  
3632      rb_trap_restore_mask();
3633      if (trace_func && tag != TAG_FATAL) {
3634          call_trace_func("raise", ruby_current_node,
3635                          ruby_frame->self,
3636                          ruby_frame->last_func,
3637                          ruby_frame->last_class);
3638      }
3639      if (!prot_tag) {
3640          error_print();
3641      }
3642      JUMP_TAG(tag);
3643  }
3644  
3645  void
3646  rb_exc_raise(mesg)
3647      VALUE mesg;
3648  {
3649      rb_longjmp(TAG_RAISE, mesg);
3650  }
3651  
3652  void
3653  rb_exc_fatal(mesg)
3654      VALUE mesg;
3655  {
3656      rb_longjmp(TAG_FATAL, mesg);
3657  }
3658  
3659  void
3660  rb_interrupt()
3661  {
3662      rb_raise(rb_eInterrupt, "");
3663  }
3664  
3665  static VALUE
3666  rb_f_raise(argc, argv)
3667      int argc;
3668      VALUE *argv;
3669  {
3670      VALUE mesg;
3671      ID exception;
3672      int n;
3673  
3674      mesg = Qnil;
3675      switch (argc) {
3676        case 0:
3677          mesg = Qnil;
3678          break;
3679        case 1:
3680          if (NIL_P(argv[0])) break;
3681          if (TYPE(argv[0]) == T_STRING) {
3682              mesg = rb_exc_new3(rb_eRuntimeError, argv[0]);
3683              break;
3684          }
3685          n = 0;
3686          goto exception_call;
3687  
3688        case 2:
3689        case 3:
3690          n = 1;
3691        exception_call:
3692          exception = rb_intern("exception");
3693          if (!rb_respond_to(argv[0], exception)) {
3694              rb_raise(rb_eTypeError, "exception class/object expected");
3695          }
3696          mesg = rb_funcall(argv[0], exception, n, argv[1]);
3697          break;
3698        default:
3699          rb_raise(rb_eArgError, "wrong number of arguments");
3700          break;
3701      }
3702      if (argc > 0) {
3703          if (!rb_obj_is_kind_of(mesg, rb_eException))
3704              rb_raise(rb_eTypeError, "exception object expected");
3705          set_backtrace(mesg, (argc>2)?argv[2]:Qnil);
3706      }
3707  
3708      if (ruby_frame != top_frame) {
3709          PUSH_FRAME();           /* fake frame */
3710          *ruby_frame = *_frame.prev->prev;
3711          rb_longjmp(TAG_RAISE, mesg);
3712          POP_FRAME();
3713      }
3714      rb_longjmp(TAG_RAISE, mesg);
3715  
3716      return Qnil;                /* not reached */
3717  }
3718  
3719  void
3720  rb_jump_tag(tag)
3721      int tag;
3722  {
3723      JUMP_TAG(tag);
3724  }
3725  
3726  int
3727  rb_block_given_p()
3728  {
3729      if (ruby_frame->iter && ruby_block)
3730          return Qtrue;
3731      return Qfalse;
3732  }
3733  
3734  int
3735  rb_iterator_p()
3736  {
3737      return rb_block_given_p();
3738  }
3739  
3740  static VALUE
3741  rb_f_block_given_p()
3742  {
3743      if (ruby_frame->prev && ruby_frame->prev->iter && ruby_block)
3744          return Qtrue;
3745      return Qfalse;
3746  }
3747  
3748  static VALUE
3749  rb_yield_0(val, self, klass, pcall)
3750      VALUE val, self, klass;     /* OK */
3751      int pcall;
3752  {
3753      NODE *node;
3754      volatile VALUE result = Qnil;
3755      volatile VALUE old_cref;
3756      volatile VALUE old_wrapper;
3757      struct BLOCK * volatile block;
3758      struct SCOPE * volatile old_scope;
3759      struct FRAME frame;
3760      NODE *cnode = ruby_current_node;
3761      int state;
3762      static unsigned serial = 1;
3763  
3764      if (!rb_block_given_p()) {
3765          localjump_error("no block given", Qnil);
3766      }
3767  
3768      PUSH_VARS();
3769      PUSH_CLASS();
3770      block = ruby_block;
3771      frame = block->frame;
3772      frame.prev = ruby_frame;
3773      ruby_frame = &(frame);
3774      old_cref = (VALUE)ruby_cref;
3775      ruby_cref = (NODE*)ruby_frame->cbase;
3776      old_wrapper = ruby_wrapper;
3777      ruby_wrapper = block->wrapper;
3778      old_scope = ruby_scope;
3779      ruby_scope = block->scope;
3780      ruby_block = block->prev;
3781      if (block->flags & BLOCK_D_SCOPE) {
3782          /* put place holder for dynamic (in-block) local variables */
3783          ruby_dyna_vars = new_dvar(0, 0, block->dyna_vars);
3784      }
3785      else {
3786          /* FOR does not introduce new scope */
3787          ruby_dyna_vars = block->dyna_vars;
3788      }
3789      ruby_class = klass?klass:block->klass;
3790      if (!klass) self = block->self;
3791      node = block->body;
3792  
3793      if (block->var) {
3794          PUSH_TAG(PROT_NONE);
3795          if ((state = EXEC_TAG()) == 0) {
3796              if (block->var == (NODE*)1) {
3797                  if (pcall && RARRAY(val)->len != 0) {
3798                      rb_raise(rb_eArgError, "wrong number of arguments (%ld for 0)",
3799                               RARRAY(val)->len);
3800                  }
3801              }
3802              else if (block->var == (NODE*)2) {
3803                  if (TYPE(val) == T_ARRAY && RARRAY(val)->len != 0) {
3804                      rb_raise(rb_eArgError, "wrong number of arguments (%ld for 0)",
3805                               RARRAY(val)->len);
3806                  }
3807              }
3808              else if (nd_type(block->var) == NODE_MASGN) {
3809                  massign(self, block->var, val, pcall);
3810              }
3811              else {
3812                  if (pcall) {
3813                      val = avalue_to_yvalue(val);
3814                  }
3815                  assign(self, block->var, val, pcall);
3816              }
3817          }
3818          POP_TAG();
3819          if (state) goto pop_state;
3820      }
3821      else if (pcall) {
3822          val = avalue_to_yvalue(val);
3823      }
3824  
3825      PUSH_ITER(block->iter);
3826      PUSH_TAG(PROT_NONE);
3827      if ((state = EXEC_TAG()) == 0) {
3828        redo:
3829          if (!node) {
3830              result = Qnil;
3831          }
3832          else if (nd_type(node) == NODE_CFUNC || nd_type(node) == NODE_IFUNC) {
3833              result = (*node->nd_cfnc)(val, node->nd_tval, self);
3834          }
3835          else {
3836              result = rb_eval(self, node);
3837          }
3838      }
3839      else {
3840          switch (state) {
3841            case TAG_REDO:
3842              state = 0;
3843              CHECK_INTS;
3844              goto redo;
3845            case TAG_NEXT:
3846              state = 0;
3847              result = prot_tag->retval;
3848              break;
3849            case TAG_BREAK:
3850            case TAG_RETURN:
3851              state |= (serial++ << 8);
3852              state |= 0x10;
3853              block->tag->dst = state;
3854              break;
3855            default:
3856              break;
3857          }
3858      }
3859      POP_TAG();
3860      POP_ITER();
3861    pop_state:
3862      POP_CLASS();
3863      if (ruby_dyna_vars && (block->flags & BLOCK_D_SCOPE) &&
3864          !FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) {
3865          struct RVarmap *vars = ruby_dyna_vars;
3866  
3867          if (ruby_dyna_vars->id == 0) {
3868              vars = ruby_dyna_vars->next;
3869              rb_gc_force_recycle((VALUE)ruby_dyna_vars);
3870              while (vars && vars->id != 0 && vars != block->dyna_vars) {
3871                  struct RVarmap *tmp = vars->next;
3872                  rb_gc_force_recycle((VALUE)vars);
3873                  vars = tmp;
3874              }
3875          }
3876      }
3877      POP_VARS();
3878      ruby_block = block;
3879      ruby_frame = ruby_frame->prev;
3880      ruby_cref = (NODE*)old_cref;
3881      ruby_wrapper = old_wrapper;
3882      if (ruby_scope->flags & SCOPE_DONT_RECYCLE)
3883         scope_dup(old_scope);
3884      ruby_scope = old_scope;
3885      ruby_current_node = cnode;
3886      if (state) {
3887          if (!block->tag) {
3888              switch (state & TAG_MASK) {
3889                case TAG_BREAK:
3890                case TAG_RETURN:
3891                  jump_tag_but_local_jump(state & TAG_MASK);
3892                  break;
3893              }
3894          }
3895          JUMP_TAG(state);
3896      }
3897      return result;
3898  }
3899  
3900  VALUE
3901  rb_yield(val)
3902      VALUE val;
3903  {
3904      return rb_yield_0(val, 0, 0, 0);
3905  }
3906  
3907  static VALUE
3908  rb_f_loop()
3909  {
3910      for (;;) {
3911          rb_yield_0(Qundef, 0, 0, 0);
3912          CHECK_INTS;
3913      }
3914      return Qnil;                /* dummy */
3915  }
3916  
3917  static VALUE
3918  massign(self, node, val, pcall)
3919      VALUE self;
3920      NODE *node;
3921      VALUE val;
3922      int pcall;
3923  {
3924      NODE *list;
3925      long i = 0, len;
3926  
3927      if (!pcall) {
3928          val = svalue_to_mvalue(val);
3929      }
3930      len = RARRAY(val)->len;
3931      list = node->nd_head;
3932      for (i=0; list && i<len; i++) {
3933          assign(self, list->nd_head, RARRAY(val)->ptr[i], pcall);
3934          list = list->nd_next;
3935      }
3936      if (pcall && list) goto arg_error;
3937      if (node->nd_args) {
3938          if (node->nd_args == (NODE*)-1) {
3939              /* no check for mere `*' */
3940          }
3941          else if (!list && i<len) {
3942              assign(self, node->nd_args, rb_ary_new4(len-i, RARRAY(val)->ptr+i), pcall);
3943          }
3944          else {
3945              assign(self, node->nd_args, rb_ary_new2(0), pcall);
3946          }
3947      }
3948      else if (pcall && i < len) {
3949          goto arg_error;
3950      }
3951  
3952      while (list) {
3953          i++;
3954          assign(self, list->nd_head, Qnil, pcall);
3955          list = list->nd_next;
3956      }
3957      return val;
3958  
3959    arg_error:
3960      while (list) {
3961          i++;
3962          list = list->nd_next;
3963      }
3964      rb_raise(rb_eArgError, "wrong number of arguments (%ld for %ld)", len, i);
3965  }
3966  
3967  static void
3968  assign(self, lhs, val, pcall)
3969      VALUE self;
3970      NODE *lhs;
3971      VALUE val;
3972      int pcall;
3973  {
3974      ruby_current_node = lhs;
3975      if (val == Qundef) {
3976          rb_warning("assigning void value");
3977          val = Qnil;
3978      }
3979      switch (nd_type(lhs)) {
3980        case NODE_GASGN:
3981          rb_gvar_set(lhs->nd_entry, val);
3982          break;
3983  
3984        case NODE_IASGN:
3985          rb_ivar_set(self, lhs->nd_vid, val);
3986          break;
3987  
3988        case NODE_LASGN:
3989          if (ruby_scope->local_vars == 0)
3990              rb_bug("unexpected local variable assignment");
3991          ruby_scope->local_vars[lhs->nd_cnt] = val;
3992          break;
3993  
3994        case NODE_DASGN:
3995          dvar_asgn(lhs->nd_vid, val);
3996          break;
3997  
3998        case NODE_DASGN_CURR:
3999          dvar_asgn_curr(lhs->nd_vid, val);
4000          break;
4001  
4002        case NODE_CDECL:
4003          rb_const_set(ruby_cbase, lhs->nd_vid, val);
4004          break;
4005  
4006        case NODE_CVDECL:
4007          if (RTEST(ruby_verbose) && FL_TEST(ruby_cbase, FL_SINGLETON)) {
4008              rb_warn("declaring singleton class variable");
4009          }
4010          rb_cvar_set(cvar_cbase(), lhs->nd_vid, val, Qtrue);
4011          break;
4012  
4013        case NODE_CVASGN:
4014          rb_cvar_set(cvar_cbase(), lhs->nd_vid, val, Qfalse);
4015          break;
4016  
4017        case NODE_MASGN:
4018          massign(self, lhs, svalue_to_mvalue(val), pcall);
4019          break;
4020  
4021        case NODE_CALL:
4022          {
4023              VALUE recv;
4024              recv = rb_eval(self, lhs->nd_recv);
4025              if (!lhs->nd_args) {
4026                  /* attr set */
4027                  ruby_current_node = lhs;
4028                  SET_CURRENT_SOURCE();
4029                  rb_call(CLASS_OF(recv), recv, lhs->nd_mid, 1, &val, 0);
4030              }
4031              else {
4032                  /* array set */
4033                  VALUE args;
4034  
4035                  args = rb_eval(self, lhs->nd_args);
4036                  rb_ary_push(args, val);
4037                  ruby_current_node = lhs;
4038                  SET_CURRENT_SOURCE();
4039                  rb_call(CLASS_OF(recv), recv, lhs->nd_mid,
4040                          RARRAY(args)->len, RARRAY(args)->ptr, 0);
4041              }
4042          }
4043          break;
4044  
4045        default:
4046          rb_bug("bug in variable assignment");
4047          break;
4048      }
4049  }
4050  
4051  VALUE
4052  rb_iterate(it_proc, data1, bl_proc, data2)
4053      VALUE (*it_proc) _((VALUE)), (*bl_proc)(ANYARGS);
4054      VALUE data1, data2;
4055  {
4056      int state;
4057      volatile VALUE retval = Qnil;
4058      NODE *node = NEW_IFUNC(bl_proc, data2);
4059      VALUE self = ruby_top_self;
4060  
4061    iter_retry:
4062      PUSH_ITER(ITER_PRE);
4063      PUSH_BLOCK(0, node);
4064      PUSH_TAG(PROT_NONE);
4065  
4066      state = EXEC_TAG();
4067      if (state == 0) {
4068          retval = (*it_proc)(data1);
4069      }
4070      if (ruby_block->tag->dst == state) {
4071          state &= TAG_MASK;
4072          if (state == TAG_RETURN || state == TAG_BREAK) {
4073              retval = prot_tag->retval;
4074          }
4075      }
4076      POP_TAG();
4077      POP_BLOCK();
4078      POP_ITER();
4079  
4080      switch (state) {
4081        case 0:
4082          break;
4083  
4084        case TAG_RETRY:
4085          goto iter_retry;
4086  
4087        case TAG_BREAK:
4088          break;
4089  
4090        case TAG_RETURN:
4091          return_value(retval);
4092          /* fall through */
4093        default:
4094          JUMP_TAG(state);
4095      }
4096      return retval;
4097  }
4098  
4099  static int
4100  handle_rescue(self, node)
4101      VALUE self;
4102      NODE *node;
4103  {
4104      int argc; VALUE *argv; /* used in SETUP_ARGS */
4105      TMP_PROTECT;
4106  
4107      if (!node->nd_args) {
4108          return rb_obj_is_kind_of(ruby_errinfo, rb_eStandardError);
4109      }
4110  
4111      BEGIN_CALLARGS;
4112      SETUP_ARGS(node->nd_args);
4113      END_CALLARGS;
4114  
4115      while (argc--) {
4116          if (!rb_obj_is_kind_of(argv[0], rb_cModule)) {
4117              rb_raise(rb_eTypeError, "class or module required for rescue clause");
4118          }
4119          if (RTEST(rb_funcall(*argv, eqq, 1, ruby_errinfo))) return 1;
4120          argv++;
4121      }
4122      return 0;
4123  }
4124  
4125  VALUE
4126  #ifdef HAVE_STDARG_PROTOTYPES
4127  rb_rescue2(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*r_proc)(ANYARGS), VALUE data2, ...)
4128  #else
4129  rb_rescue2(b_proc, data1, r_proc, data2, va_alist)
4130      VALUE (*b_proc)(ANYARGS), (*r_proc)(ANYARGS);
4131      VALUE data1, data2;
4132      va_dcl
4133  #endif
4134  {
4135      int state;
4136      volatile VALUE result;
4137      volatile VALUE e_info = ruby_errinfo;
4138      va_list args;
4139  
4140      PUSH_TAG(PROT_NONE);
4141      if ((state = EXEC_TAG()) == 0) {
4142        retry_entry:
4143          result = (*b_proc)(data1);
4144      }
4145      else if (state == TAG_RAISE) {
4146          int handle = Qfalse;
4147          VALUE eclass;
4148  
4149          va_init_list(args, data2);
4150          while (eclass = va_arg(args, VALUE)) {
4151              if (rb_obj_is_kind_of(ruby_errinfo, eclass)) {
4152                  handle = Qtrue;
4153                  break;
4154              }
4155          }
4156          va_end(args);
4157  
4158          if (handle) {
4159              if (r_proc) {
4160                  PUSH_TAG(PROT_NONE);
4161                  if ((state = EXEC_TAG()) == 0) {
4162                      result = (*r_proc)(data2, ruby_errinfo);
4163                  }
4164                  POP_TAG();
4165                  if (state == TAG_RETRY) {
4166                      state = 0;
4167                      ruby_errinfo = Qnil;
4168                      goto retry_entry;
4169                  }
4170              }
4171              else {
4172                  result = Qnil;
4173                  state = 0;
4174              }
4175              if (state == 0) {
4176                  ruby_errinfo = e_info;
4177              }
4178          }
4179      }
4180      POP_TAG();
4181      if (state) JUMP_TAG(state);
4182  
4183      return result;
4184  }
4185  
4186  VALUE
4187  rb_rescue(b_proc, data1, r_proc, data2)
4188      VALUE (*b_proc)(), (*r_proc)();
4189      VALUE data1, data2;
4190  {
4191      return rb_rescue2(b_proc, data1, r_proc, data2, rb_eStandardError, 0);
4192  }
4193  
4194  VALUE
4195  rb_protect(proc, data, state)
4196      VALUE (*proc) _((VALUE));
4197      VALUE data;
4198      int *state;
4199  {
4200      VALUE result;               /* OK */
4201      int status;
4202  
4203      PUSH_TAG(PROT_NONE);
4204      if ((status = EXEC_TAG()) == 0) {
4205          result = (*proc)(data);
4206      }
4207      POP_TAG();
4208      if (state) {
4209          *state = status;
4210      }
4211      if (status != 0) {
4212          return Qnil;
4213      }
4214  
4215      return result;
4216  }
4217  
4218  VALUE
4219  rb_ensure(b_proc, data1, e_proc, data2)
4220      VALUE (*b_proc)();
4221      VALUE data1;
4222      VALUE (*e_proc)();
4223      VALUE data2;
4224  {
4225      int state;
4226      volatile VALUE result = Qnil;
4227      VALUE retval;
4228  
4229      PUSH_TAG(PROT_NONE);
4230      if ((state = EXEC_TAG()) == 0) {
4231          result = (*b_proc)(data1);
4232      }
4233      POP_TAG();
4234      retval = prot_tag ? prot_tag->retval : Qnil;        /* save retval */
4235      (*e_proc)(data2);
4236      if (prot_tag) return_value(retval);
4237  
4238      if (state) JUMP_TAG(state);
4239      return result;
4240  }
4241  
4242  VALUE
4243  rb_with_disable_interrupt(proc, data)
4244      VALUE (*proc)();
4245      VALUE data;
4246  {
4247      VALUE result;               /* OK */
4248      int status;
4249  
4250      DEFER_INTS;
4251      PUSH_TAG(PROT_NONE);
4252      if ((status = EXEC_TAG()) == 0) {
4253          result = (*proc)(data);
4254      }
4255      POP_TAG();
4256      ALLOW_INTS;
4257      if (status) JUMP_TAG(status);
4258  
4259      return result;
4260  }
4261  
4262  static void
4263  stack_check()
4264  {
4265      static int overflowing = 0;
4266  
4267      if (!overflowing && ruby_stack_check()) {
4268          int state;
4269          overflowing = 1;
4270          PUSH_TAG(PROT_NONE);
4271          if ((state = EXEC_TAG()) == 0) {
4272              rb_raise(rb_eSysStackError, "stack level too deep");
4273          }
4274          POP_TAG();
4275          overflowing = 0;
4276          JUMP_TAG(state);
4277      }
4278  }
4279  
4280  static int last_call_status;
4281  
4282  #define CSTAT_PRIV  1
4283  #define CSTAT_PROT  2
4284  #define CSTAT_VCALL 4
4285  
4286  static VALUE
4287  rb_f_missing(argc, argv, obj)
4288      int argc;
4289      VALUE *argv;
4290      VALUE obj;
4291  {
4292      ID id;
4293      VALUE exc = rb_eNoMethodError;
4294      volatile VALUE d = 0;
4295      char *format = 0;
4296      char *desc = "";
4297      NODE *cnode = ruby_current_node;
4298  
4299      if (argc == 0 || !SYMBOL_P(argv[0])) {
4300          rb_raise(rb_eArgError, "no id given");
4301      }
4302  
4303      stack_check();
4304  
4305      id = SYM2ID(argv[0]);
4306  
4307      switch (TYPE(obj)) {
4308        case T_NIL:
4309          desc = "nil";
4310          break;
4311        case T_TRUE:
4312          desc = "true";
4313          break;
4314        case T_FALSE:
4315          desc = "false";
4316          break;
4317        case T_OBJECT:
4318          d = rb_any_to_s(obj);
4319          break;
4320        default:
4321          d = rb_inspect(obj);
4322          break;
4323      }
4324      if (d) {
4325          if (RSTRING(d)->len > 65) {
4326              d = rb_any_to_s(obj);
4327          }
4328          desc = RSTRING(d)->ptr;
4329      }
4330  
4331      if (last_call_status & CSTAT_PRIV) {
4332          format = "private method `%s' called for %s%s%s";
4333      }
4334      if (last_call_status & CSTAT_PROT) {
4335          format = "protected method `%s' called for %s%s%s";
4336      }
4337      else if (last_call_status & CSTAT_VCALL) {
4338          const char *mname = rb_id2name(id);
4339  
4340          if (('a' <= mname[0] && mname[0] <= 'z') || mname[0] == '_') {
4341              format = "undefined local variable or method `%s' for %s%s%s";
4342              exc = rb_eNameError;
4343          }
4344      }
4345      if (!format) {
4346          format = "undefined method `%s' for %s%s%s";
4347      }
4348  
4349      ruby_current_node = cnode;
4350      PUSH_FRAME();               /* fake frame */
4351      *ruby_frame = *_frame.prev->prev;
4352      {
4353          char buf[BUFSIZ];
4354          int noclass = (!d || desc[0]=='#');
4355  
4356          snprintf(buf, BUFSIZ, format, rb_id2name(id),
4357                   desc, noclass ? "" : ":",
4358                   noclass ? "" : rb_class2name(CLASS_OF(obj)));
4359          exc = rb_exc_new2(exc, buf);
4360          rb_iv_set(exc, "name", argv[0]);
4361          rb_iv_set(exc, "args", rb_ary_new4(argc-1, argv+1));
4362          rb_exc_raise(exc);
4363      }
4364      POP_FRAME();
4365  
4366      return Qnil;                /* not reached */
4367  }
4368  
4369  static VALUE
4370  rb_undefined(obj, id, argc, argv, call_status)
4371      VALUE obj;
4372      ID    id;
4373      int   argc;
4374      VALUE*argv;
4375      int   call_status;
4376  {
4377      VALUE *nargv;
4378  
4379      last_call_status = call_status;
4380  
4381      if (id == missing) {
4382          PUSH_FRAME();
4383          rb_f_missing(argc, argv, obj);
4384          POP_FRAME();
4385      }
4386  
4387      nargv = ALLOCA_N(VALUE, argc+1);
4388      nargv[0] = ID2SYM(id);
4389      MEMCPY(nargv+1, argv, VALUE, argc);
4390  
4391      return rb_funcall2(obj, missing, argc+1, nargv);
4392  }
4393  
4394  static VALUE
4395  call_cfunc(func, recv, len, argc, argv)
4396      VALUE (*func)();
4397      VALUE recv;
4398      int len, argc;
4399      VALUE *argv;
4400  {
4401      if (len >= 0 && argc != len) {
4402          rb_raise(rb_eArgError, "wrong number of arguments(%d for %d)",
4403                   argc, len);
4404      }
4405  
4406      switch (len) {
4407        case -2:
4408          return (*func)(recv, rb_ary_new4(argc, argv));
4409          break;
4410        case -1:
4411          return (*func)(argc, argv, recv);
4412          break;
4413        case 0:
4414          return (*func)(recv);
4415          break;
4416        case 1:
4417          return (*func)(recv, argv[0]);
4418          break;
4419        case 2:
4420          return (*func)(recv, argv[0], argv[1]);
4421          break;
4422        case 3:
4423          return (*func)(recv, argv[0], argv[1], argv[2]);
4424          break;
4425        case 4:
4426          return (*func)(recv, argv[0], argv[1], argv[2], argv[3]);
4427          break;
4428        case 5:
4429          return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4]);
4430          break;
4431        case 6:
4432          return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
4433                         argv[5]);
4434          break;
4435        case 7:
4436          return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
4437                         argv[5], argv[6]);
4438          break;
4439        case 8:
4440          return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
4441                         argv[5], argv[6], argv[7]);
4442          break;
4443        case 9:
4444          return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
4445                         argv[5], argv[6], argv[7], argv[8]);
4446          break;
4447        case 10:
4448          return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
4449                         argv[5], argv[6], argv[7], argv[8], argv[9]);
4450          break;
4451        case 11:
4452          return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
4453                         argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
4454          break;
4455        case 12:
4456          return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
4457                         argv[5], argv[6], argv[7], argv[8], argv[9],
4458                         argv[10], argv[11]);
4459          break;
4460        case 13:
4461          return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
4462                         argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
4463                         argv[11], argv[12]);
4464          break;
4465        case 14:
4466          return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
4467                         argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
4468                         argv[11], argv[12], argv[13]);
4469          break;
4470        case 15:
4471          return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
4472                         argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
4473                         argv[11], argv[12], argv[13], argv[14]);
4474          break;
4475        default:
4476          rb_raise(rb_eArgError, "too many arguments(%d)", len);
4477          break;
4478      }
4479      return Qnil;                /* not reached */
4480  }
4481  
4482  static VALUE
4483  rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
4484      VALUE klass, recv;
4485      ID    id;
4486      ID    oid;
4487      int argc;                   /* OK */
4488      VALUE *argv;                /* OK */
4489      NODE *body;                 /* OK */
4490      int nosuper;
4491  {
4492      NODE *b2;           /* OK */
4493      volatile VALUE result = Qnil;
4494      int itr;
4495      static int tick;
4496      TMP_PROTECT;
4497  
4498      switch (ruby_iter->iter) {
4499        case ITER_PRE:
4500          itr = ITER_CUR;
4501          break;
4502        case ITER_CUR:
4503        default:
4504          itr = ITER_NOT;
4505          break;
4506      }
4507  
4508      if ((++tick & 0xff) == 0) {
4509          CHECK_INTS;             /* better than nothing */
4510          stack_check();
4511      }
4512      PUSH_ITER(itr);
4513      PUSH_FRAME();
4514  
4515      ruby_frame->last_func = id;
4516      ruby_frame->orig_func = oid;
4517      ruby_frame->last_class = nosuper?0:klass;
4518      ruby_frame->self = recv;
4519      ruby_frame->argc = argc;
4520      ruby_frame->argv = argv;
4521  
4522      switch (nd_type(body)) {
4523        case NODE_CFUNC:
4524          {
4525              int len = body->nd_argc;
4526  
4527              if (len < -2) {
4528                  rb_bug("bad argc(%d) specified for `%s(%s)'",
4529                         len, rb_class2name(klass), rb_id2name(id));
4530              }
4531              if (trace_func) {
4532                  int state;
4533  
4534                  call_trace_func("c-call", ruby_current_node, recv, id, klass);
4535                  PUSH_TAG(PROT_FUNC);
4536                  if ((state = EXEC_TAG()) == 0) {
4537                      result = call_cfunc(body->nd_cfnc, recv, len, argc, argv);
4538                  }
4539                  POP_TAG();
4540                  call_trace_func("c-return", ruby_current_node, recv, id, klass);
4541                  if (state) JUMP_TAG(state);
4542              }
4543              else {
4544                  result = call_cfunc(body->nd_cfnc, recv, len, argc, argv);
4545              }
4546          }
4547          break;
4548  
4549          /* for attr get/set */
4550        case NODE_IVAR:
4551          if (argc != 0) {
4552              rb_raise(rb_eArgError, "wrong number of arguments(%d for 0)", argc);
4553          }
4554        case NODE_ATTRSET:
4555          /* for re-scoped/renamed method */
4556        case NODE_ZSUPER:
4557          result = rb_eval(recv, body);
4558          break;
4559  
4560        case NODE_DMETHOD:
4561          result = method_call(argc, argv, umethod_bind(body->nd_cval, recv));
4562          break;
4563  
4564        case NODE_BMETHOD:
4565          result = proc_invoke(body->nd_cval, rb_ary_new4(argc, argv), Qtrue, recv);
4566          break;
4567  
4568        case NODE_SCOPE:
4569          {
4570              int state;
4571              VALUE *local_vars;  /* OK */
4572              NODE *saved_cref = 0;
4573  
4574              PUSH_SCOPE();
4575  
4576              if (body->nd_rval) {
4577                  saved_cref = ruby_cref;
4578                  ruby_cref = (NODE*)body->nd_rval;
4579                  ruby_frame->cbase = body->nd_rval;
4580              }
4581              if (body->nd_tbl) {
4582                  local_vars = TMP_ALLOC(body->nd_tbl[0]+1);
4583                  *local_vars++ = (VALUE)body;
4584                  rb_mem_clear(local_vars, body->nd_tbl[0]);
4585                  ruby_scope->local_tbl = body->nd_tbl;
4586                  ruby_scope->local_vars = local_vars;
4587              }
4588              else {
4589                  local_vars = ruby_scope->local_vars = 0;
4590                  ruby_scope->local_tbl  = 0;
4591              }
4592              b2 = body = body->nd_next;
4593  
4594              PUSH_VARS();
4595              PUSH_TAG(PROT_FUNC);
4596  
4597              if ((state = EXEC_TAG()) == 0) {
4598                  NODE *node = 0;
4599                  int i;
4600  
4601                  if (nd_type(body) == NODE_ARGS) {
4602                      node = body;
4603                      body = 0;
4604                  }
4605                  else if (nd_type(body) == NODE_BLOCK) {
4606                      node = body->nd_head;
4607                      body = body->nd_next;
4608                  }
4609                  if (node) {
4610                      if (nd_type(node) != NODE_ARGS) {
4611                          rb_bug("no argument-node");
4612                      }
4613  
4614                      i = node->nd_cnt;
4615                      if (i > argc) {
4616                          rb_raise(rb_eArgError, "wrong number of arguments(%d for %d)",
4617                                   argc, i);
4618                      }
4619                      if (node->nd_rest == -1) {
4620                          int opt = i;
4621                          NODE *optnode = node->nd_opt;
4622  
4623                          while (optnode) {
4624                              opt++;
4625                              optnode = optnode->nd_next;
4626                          }
4627                          if (opt < argc) {
4628                              rb_raise(rb_eArgError, "wrong number of arguments(%d for %d)",
4629                                       argc, opt);
4630                          }
4631                          ruby_frame->argc = opt;
4632                          ruby_frame->argv = local_vars+2;
4633                      }
4634  
4635                      if (local_vars) {
4636                          if (i > 0) {
4637                              /* +2 for $_ and $~ */
4638                              MEMCPY(local_vars+2, argv, VALUE, i);
4639                          }
4640                          argv += i; argc -= i;
4641                          if (node->nd_opt) {
4642                              NODE *opt = node->nd_opt;
4643  
4644                              while (opt && argc) {
4645                                  assign(recv, opt->nd_head, *argv, 1);
4646                                  argv++; argc--;
4647                                  opt = opt->nd_next;
4648                              }
4649                              if (opt) {
4650                                  rb_eval(recv, opt);
4651                              }
4652                          }
4653                          local_vars = ruby_scope->local_vars;
4654                          if (node->nd_rest >= 0) {
4655                              VALUE v;
4656  
4657                              if (argc > 0)
4658                                  v = rb_ary_new4(argc,argv);
4659                              else
4660                                  v = rb_ary_new2(0);
4661                              ruby_scope->local_vars[node->nd_rest] = v;
4662                          }
4663                      }
4664                  }
4665  
4666                  if (trace_func) {
4667                      call_trace_func("call", b2, recv, id, klass);
4668                  }
4669                  ruby_last_node = b2;
4670                  result = rb_eval(recv, body);
4671              }
4672              else if (state == TAG_RETURN) {
4673                  result = prot_tag->retval;
4674                  state = 0;
4675              }
4676              POP_TAG();
4677              POP_VARS();
4678              POP_SCOPE();
4679              ruby_cref = saved_cref;
4680              if (trace_func) {
4681                  call_trace_func("return", ruby_last_node, recv, id, klass);
4682              }
4683              switch (state) {
4684                case 0:
4685                  break;
4686  
4687                case TAG_RETRY:
4688                  if (rb_block_given_p()) {
4689                     JUMP_TAG(state);
4690                  }
4691                  /* fall through */
4692                default:
4693                  jump_tag_but_local_jump(state);
4694                  break;
4695              }
4696          }
4697          break;
4698  
4699        default:
4700          rb_bug("unknown node type %d", nd_type(body));
4701          break;
4702      }
4703      POP_FRAME();
4704      POP_ITER();
4705      return result;
4706  }
4707  
4708  static VALUE
4709  rb_call(klass, recv, mid, argc, argv, scope)
4710      VALUE klass, recv;
4711      ID    mid;
4712      int argc;                   /* OK */
4713      const VALUE *argv;          /* OK */
4714      int scope;
4715  {
4716      NODE  *body;                /* OK */
4717      int    noex;
4718      ID     id = mid;
4719      struct cache_entry *ent;
4720  
4721      if (!klass) {
4722          rb_raise(rb_eNotImpError, "method `%s' called on terminated object (0x%x)",
4723                   rb_id2name(mid), recv);
4724      }
4725      /* is it in the method cache? */
4726      ent = cache + EXPR1(klass, mid);
4727      if (ent->mid == mid && ent->klass == klass) {
4728          if (!ent->method)
4729              return rb_undefined(recv, mid, argc, argv, scope==2?CSTAT_VCALL:0);
4730          klass = ent->origin;
4731          id    = ent->mid0;
4732          noex  = ent->noex;
4733          body  = ent->method;
4734      }
4735      else if ((body = rb_get_method_body(&klass, &id, &noex)) == 0) {
4736          if (scope == 3) {
4737              rb_name_error(mid, "super: no superclass method `%s'",
4738                            rb_id2name(mid));
4739          }
4740          return rb_undefined(recv, mid, argc, argv, scope==2?CSTAT_VCALL:0);
4741      }
4742  
4743      if (mid != missing) {
4744          /* receiver specified form for private method */
4745          if ((noex & NOEX_PRIVATE) && scope == 0)
4746              return rb_undefined(recv, mid, argc, argv, CSTAT_PRIV);
4747  
4748          /* self must be kind of a specified form for private method */
4749          if ((noex & NOEX_PROTECTED)) {
4750              VALUE defined_class = klass;
4751  
4752              if (TYPE(defined_class) == T_ICLASS) {
4753                  defined_class = RBASIC(defined_class)->klass;
4754              }
4755              if (!rb_obj_is_kind_of(ruby_frame->self, rb_class_real(defined_class)))
4756                  return rb_undefined(recv, mid, argc, argv, CSTAT_PROT);
4757          }
4758      }
4759  
4760      return rb_call0(klass, recv, mid, id, argc, argv, body, noex & NOEX_UNDEF);
4761  }
4762  
4763  VALUE
4764  rb_apply(recv, mid, args)
4765      VALUE recv;
4766      ID mid;
4767      VALUE args;
4768  {
4769      int argc;
4770      VALUE *argv;
4771  
4772      argc = RARRAY(args)->len; /* Assigns LONG, but argc is INT */
4773      argv = ALLOCA_N(VALUE, argc);
4774      MEMCPY(argv, RARRAY(args)->ptr, VALUE, argc);
4775      return rb_call(CLASS_OF(recv), recv, mid, argc, argv, 1);
4776  }
4777  
4778  static VALUE
4779  rb_f_send(argc, argv, recv)
4780      int argc;
4781      VALUE *argv;
4782      VALUE recv;
4783  {
4784      VALUE vid;
4785  
4786      if (argc == 0) rb_raise(rb_eArgError, "no method name given");
4787  
4788      vid = *argv++; argc--;
4789      PUSH_ITER(rb_block_given_p()?ITER_PRE:ITER_NOT);
4790      vid = rb_call(CLASS_OF(recv), recv, rb_to_id(vid), argc, argv, 1);
4791      POP_ITER();
4792  
4793      return vid;
4794  }
4795  
4796  #ifdef HAVE_STDARG_PROTOTYPES
4797  #include <stdarg.h>
4798  #define va_init_list(a,b) va_start(a,b)
4799  #else
4800  #include <varargs.h>
4801  #define va_init_list(a,b) va_start(a)
4802  #endif
4803  
4804  VALUE
4805  #ifdef HAVE_STDARG_PROTOTYPES
4806  rb_funcall(VALUE recv, ID mid, int n, ...)
4807  #else
4808  rb_funcall(recv, mid, n, va_alist)
4809      VALUE recv;
4810      ID mid;
4811      int n;
4812      va_dcl
4813  #endif
4814  {
4815      va_list ar;
4816      VALUE *argv;
4817  
4818      if (n > 0) {
4819          long i;
4820  
4821          argv = ALLOCA_N(VALUE, n);
4822  
4823          va_init_list(ar, n);
4824          for (i=0;i<n;i++) {
4825              argv[i] = va_arg(ar, VALUE);
4826          }
4827          va_end(ar);
4828      }
4829      else {
4830          argv = 0;
4831      }
4832  
4833      return rb_call(CLASS_OF(recv), recv, mid, n, argv, 1);
4834  }
4835  
4836  VALUE
4837  rb_funcall2(recv, mid, argc, argv)
4838      VALUE recv;
4839      ID mid;
4840      int argc;
4841      const VALUE *argv;
4842  {
4843      return rb_call(CLASS_OF(recv), recv, mid, argc, argv, 1);
4844  }
4845  
4846  VALUE
4847  rb_funcall3(recv, mid, argc, argv)
4848      VALUE recv;
4849      ID mid;
4850      int argc;
4851      const VALUE *argv;
4852  {
4853      return rb_call(CLASS_OF(recv), recv, mid, argc, argv, 0);
4854  }
4855  
4856  VALUE
4857  rb_call_super(argc, argv)
4858      int argc;
4859      const VALUE *argv;
4860  {
4861      VALUE result;
4862  
4863      if (ruby_frame->last_class == 0) {  
4864          rb_name_error(ruby_frame->last_func, "superclass method `%s' must be enabled by rb_enable_super()",
4865                        rb_id2name(ruby_frame->last_func));
4866      }
4867  
4868      PUSH_ITER(ruby_iter->iter?ITER_PRE:ITER_NOT);
4869      result = rb_call(RCLASS(ruby_frame->last_class)->super,
4870                       ruby_frame->self, ruby_frame->last_func,
4871                       argc, argv, 3);
4872      POP_ITER();
4873  
4874      return result;
4875  }
4876  
4877  static VALUE
4878  backtrace(lev)
4879      int lev;
4880  {
4881      struct FRAME *frame = ruby_frame;
4882      char buf[BUFSIZ];
4883      VALUE ary;
4884      NODE *n;
4885  
4886      ary = rb_ary_new();
4887      if (lev < 0) {
4888          ruby_set_current_source();
4889          if (frame->last_func) {
4890              snprintf(buf, BUFSIZ, "%s:%d:in `%s'",
4891                       ruby_sourcefile, ruby_sourceline,
4892                       rb_id2name(frame->last_func));
4893          }
4894          else if (ruby_sourceline == 0) {
4895              snprintf(buf, BUFSIZ, "%s", ruby_sourcefile);
4896          }
4897          else {
4898              snprintf(buf, BUFSIZ, "%s:%d", ruby_sourcefile, ruby_sourceline);
4899          }
4900          rb_ary_push(ary, rb_str_new2(buf));
4901      }
4902      else {
4903          while (lev-- > 0) {
4904              frame = frame->prev;
4905              if (!frame) {
4906                  ary = Qnil;
4907                  break;
4908              }
4909          }
4910      }
4911      while (frame && (n = frame->node)) {
4912          if (frame->prev && frame->prev->last_func) {
4913              snprintf(buf, BUFSIZ, "%s:%d:in `%s'",
4914                       n->nd_file, nd_line(n),
4915                       rb_id2name(frame->prev->last_func));
4916          }
4917          else {
4918              snprintf(buf, BUFSIZ, "%s:%d", n->nd_file, nd_line(n));
4919          }
4920          rb_ary_push(ary, rb_str_new2(buf));
4921          frame = frame->prev;
4922      }
4923  
4924      return ary;
4925  }
4926  
4927  static VALUE
4928  rb_f_caller(argc, argv)
4929      int argc;
4930      VALUE *argv;
4931  {
4932      VALUE level;
4933      int lev;
4934  
4935      rb_scan_args(argc, argv, "01", &level);
4936  
4937      if (NIL_P(level)) lev = 1;
4938      else lev = NUM2INT(level);
4939      if (lev < 0) rb_raise(rb_eArgError, "negative level(%d)", lev);
4940  
4941      return backtrace(lev);
4942  }
4943  
4944  void
4945  rb_backtrace()
4946  {
4947      long i;
4948      VALUE ary;
4949  
4950      ary = backtrace(-1);
4951      for (i=0; i<RARRAY(ary)->len; i++) {
4952          printf("\tfrom %s\n", RSTRING(RARRAY(ary)->ptr[i])->ptr);
4953      }
4954  }
4955  
4956  static VALUE
4957  make_backtrace()
4958  {
4959      return backtrace(-1);
4960  }
4961  
4962  ID
4963  rb_frame_last_func()
4964  {
4965      return ruby_frame->last_func;
4966  }
4967  
4968  static NODE*
4969  compile(src, file, line)
4970      VALUE src;
4971      char *file;
4972      int line;
4973  {
4974      NODE *node;
4975  
4976      ruby_nerrs = 0;
4977      Check_Type(src, T_STRING);
4978      node = rb_compile_string(file, src, line);
4979  
4980      if (ruby_nerrs == 0) return node;
4981      return 0;
4982  }
4983  
4984  static VALUE
4985  eval(self, src, scope, file, line)
4986      VALUE self, src, scope;
4987      char *file;
4988      int line;
4989  {
4990      struct BLOCK *data = NULL;
4991      volatile VALUE result = Qnil;
4992      struct SCOPE * volatile old_scope;
4993      struct BLOCK * volatile old_block;
4994      struct RVarmap * volatile old_dyna_vars;
4995      VALUE volatile old_cref;
4996      int volatile old_vmode;
4997      volatile VALUE old_wrapper;
4998      struct FRAME frame;
4999      NODE *nodesave = ruby_current_node;
5000      volatile int iter = ruby_frame->iter;
5001      int state;
5002  
5003      if (!NIL_P(scope)) {
5004          if (!rb_obj_is_block(scope)) {
5005              rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc/Binding)",
5006                       rb_class2name(CLASS_OF(scope)));
5007          }
5008  
5009          Data_Get_Struct(scope, struct BLOCK, data);
5010          /* PUSH BLOCK from data */
5011          frame = data->frame;
5012          frame.tmp = ruby_frame; /* gc protection */
5013          ruby_frame = &(frame);
5014          old_scope = ruby_scope;
5015          ruby_scope = data->scope;
5016          old_block = ruby_block;
5017          ruby_block = data->prev;
5018          old_dyna_vars = ruby_dyna_vars;
5019          ruby_dyna_vars = data->dyna_vars;
5020          old_vmode = scope_vmode;
5021          scope_vmode = data->vmode;
5022          old_cref = (VALUE)ruby_cref;
5023          ruby_cref = (NODE*)ruby_frame->cbase;
5024          old_wrapper = ruby_wrapper;
5025          ruby_wrapper = data->wrapper;
5026          if ((file == 0 || (line == 1 && strcmp(file, "(eval)") == 0)) &&
5027              data->body && data->body->nd_file) {
5028              file = data->body->nd_file;
5029              line = nd_line(data->body);
5030          }
5031  
5032          self = data->self;
5033          ruby_frame->iter = data->iter;
5034      }
5035      else {
5036          if (ruby_frame->prev) {
5037              ruby_frame->iter = ruby_frame->prev->iter;
5038          }
5039      }
5040      if (file == 0) {
5041          ruby_set_current_source();
5042          file = ruby_sourcefile;
5043          line = ruby_sourceline;
5044      }
5045      PUSH_CLASS();
5046      ruby_class = ruby_cbase;
5047  
5048      ruby_in_eval++;
5049      if (TYPE(ruby_class) == T_ICLASS) {
5050          ruby_class = RBASIC(ruby_class)->klass;
5051      }
5052      PUSH_TAG(PROT_NONE);
5053      if ((state = EXEC_TAG()) == 0) {
5054          NODE *node;
5055  
5056          result = ruby_errinfo;
5057          ruby_errinfo = Qnil;
5058          node = compile(src, file, line);
5059          if (ruby_nerrs > 0) {
5060              compile_error(0);
5061          }
5062          if (!NIL_P(result)) ruby_errinfo = result;
5063          result = eval_node(self, node); 
5064      }
5065      POP_TAG();
5066      POP_CLASS();
5067      ruby_in_eval--;
5068      if (!NIL_P(scope)) {
5069          int dont_recycle = ruby_scope->flags & SCOPE_DONT_RECYCLE;
5070  
5071          ruby_wrapper = old_wrapper;
5072          ruby_cref  = (NODE*)old_cref;
5073          ruby_frame = frame.tmp;
5074          ruby_scope = old_scope;
5075          ruby_block = old_block;
5076          ruby_dyna_vars = old_dyna_vars;
5077          data->vmode = scope_vmode; /* write back visibility mode */
5078          scope_vmode = old_vmode;
5079          if (dont_recycle) {
5080             struct tag *tag;
5081             struct RVarmap *vars;
5082  
5083             scope_dup(ruby_scope);
5084             for (tag=prot_tag; tag; tag=tag->prev) {
5085                 scope_dup(tag->scope);
5086             }
5087             if (ruby_block) {
5088                 struct BLOCK *block = ruby_block;
5089                 while (block) {
5090                     block->tag->flags |= BLOCK_DYNAMIC;
5091                     block = block->prev;
5092                 }
5093             }
5094             for (vars = ruby_dyna_vars; vars; vars = vars->next) {
5095                 FL_SET(vars, DVAR_DONT_RECYCLE);
5096             }
5097          }
5098      }
5099      else {
5100          ruby_frame->iter = iter;
5101      }
5102      ruby_current_node = nodesave;
5103      ruby_set_current_source();
5104      if (state) {
5105          if (state == TAG_RAISE) {
5106              VALUE err;
5107              VALUE errat;
5108  
5109              if (strcmp(file, "(eval)") == 0) {
5110                  if (ruby_sourceline > 1) {
5111                      errat = get_backtrace(ruby_errinfo);
5112                      err = rb_str_dup(RARRAY(errat)->ptr[0]);
5113                      rb_str_cat2(err, ": ");
5114                      rb_str_append(err, ruby_errinfo);
5115                  }
5116                  else {
5117                      err = rb_str_dup(ruby_errinfo);
5118                  }
5119                  rb_exc_raise(rb_funcall(ruby_errinfo, rb_intern("exception"), 1, err));
5120              }
5121              rb_exc_raise(ruby_errinfo);
5122          }
5123          JUMP_TAG(state);
5124      }
5125  
5126      return result;
5127  }
5128  
5129  static VALUE
5130  rb_f_eval(argc, argv, self)
5131      int argc;
5132      VALUE *argv;
5133      VALUE self;
5134  {
5135      VALUE src, scope, vfile, vline;
5136      char *file = "(eval)";
5137      int line = 1;
5138  
5139      rb_scan_args(argc, argv, "13", &src, &scope, &vfile, &vline);
5140      if (ruby_safe_level >= 4) {
5141          StringValue(src);
5142          if (!NIL_P(scope) && !OBJ_TAINTED(scope)) {
5143              rb_raise(rb_eSecurityError, "Insecure: can't modify trusted binding");
5144          }
5145      }
5146      else {
5147          SafeStringValue(src);
5148      }
5149      if (argc >= 3) {
5150          file = StringValuePtr(vfile);
5151      }
5152      if (argc >= 4) {
5153          line = NUM2INT(vline);
5154      }
5155  
5156      if (NIL_P(scope) && ruby_frame->prev) {
5157          struct FRAME *prev;
5158          VALUE val;
5159  
5160          prev = ruby_frame;
5161          PUSH_FRAME();
5162          *ruby_frame = *prev->prev;
5163          ruby_frame->prev = prev;
5164          val = eval(self, src, scope, file, line);
5165          POP_FRAME();
5166  
5167          return val;
5168      }
5169      return eval(self, src, scope, file, line);
5170  }
5171  
5172  /* function to call func under the specified class/module context */
5173  static VALUE
5174  exec_under(func, under, cbase, args)
5175      VALUE (*func)();
5176      VALUE under, cbase;
5177      void *args;
5178  {
5179      VALUE val;                  /* OK */
5180      int state;
5181      int mode;
5182  
5183      PUSH_CLASS();
5184      ruby_class = under;
5185      PUSH_FRAME();
5186      ruby_frame->self = _frame.prev->self;
5187      ruby_frame->last_func = _frame.prev->last_func;
5188      ruby_frame->last_class = _frame.prev->last_class;
5189      ruby_frame->argc = _frame.prev->argc;
5190      ruby_frame->argv = _frame.prev->argv;
5191      if (cbase) {
5192          if (ruby_cbase != cbase) {
5193              ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,under,0,ruby_frame->cbase);
5194          }
5195          PUSH_CREF(cbase);
5196      }
5197  
5198      mode = scope_vmode;
5199      SCOPE_SET(SCOPE_PUBLIC);
5200      PUSH_TAG(PROT_NONE);
5201      if ((state = EXEC_TAG()) == 0) {
5202          val = (*func)(args);
5203      }
5204      POP_TAG();
5205      if (cbase) POP_CREF();
5206      SCOPE_SET(mode);
5207      POP_FRAME();
5208      POP_CLASS();
5209      if (state) JUMP_TAG(state);
5210  
5211      return val;
5212  }
5213  
5214  static VALUE
5215  eval_under_i(args)
5216      VALUE *args;
5217  {
5218      return eval(args[0], args[1], Qnil, (char*)args[2], (int)args[3]);
5219  }
5220  
5221  /* string eval under the class/module context */
5222  static VALUE
5223  eval_under(under, self, src, file, line)
5224      VALUE under, self, src;
5225      const char *file;
5226      int line;
5227  {
5228      VALUE args[4];
5229  
5230      if (ruby_safe_level >= 4) {
5231          StringValue(src);
5232      }
5233      else {
5234          SafeStringValue(src);
5235      }
5236      args[0] = self;
5237      args[1] = src;
5238      args[2] = (VALUE)file;
5239      args[3] = (VALUE)line;
5240      return exec_under(eval_under_i, under, under, args);
5241  }
5242  
5243  static VALUE
5244  yield_under_i(self)
5245      VALUE self;
5246  {
5247      return rb_yield_0(self, self, ruby_class, 0);
5248  }
5249  
5250  /* block eval under the class/module context */
5251  static VALUE
5252  yield_under(under, self)
5253      VALUE under, self;
5254  {
5255      return exec_under(yield_under_i, under, 0, self);
5256  }
5257  
5258  static VALUE
5259  specific_eval(argc, argv, klass, self)
5260      int argc;
5261      VALUE *argv;
5262      VALUE klass, self;
5263  {
5264      if (rb_block_given_p()) {
5265          if (argc > 0) {
5266              rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
5267          }
5268          return yield_under(klass, self);
5269      }
5270      else {
5271          char *file = "(eval)";
5272          int   line = 1;
5273  
5274          if (argc == 0) {
5275              rb_raise(rb_eArgError, "block not supplied");
5276          }
5277          else {
5278              if (ruby_safe_level >= 4) {
5279                  StringValue(argv[0]);
5280              }
5281              else {
5282                  SafeStringValue(argv[0]);
5283              }
5284              if (argc > 3) {
5285                  rb_raise(rb_eArgError, "wrong number of arguments: %s(src) or %s{..}",
5286                           rb_id2name(ruby_frame->last_func),
5287                           rb_id2name(ruby_frame->last_func));
5288              }
5289              if (argc > 1) {
5290                  file = StringValuePtr(argv[1]);
5291              }
5292              if (argc > 2) line = NUM2INT(argv[2]);
5293          }
5294          return eval_under(klass, self, argv[0], file, line);
5295      }
5296  }
5297  
5298  VALUE
5299  rb_obj_instance_eval(argc, argv, self)
5300      int argc;
5301      VALUE *argv;
5302      VALUE self;
5303  {
5304      VALUE klass;
5305  
5306      if (rb_special_const_p(self)) {
5307          klass = Qnil;
5308      }
5309      else {
5310          klass = rb_singleton_class(self);
5311      }
5312  
5313      return specific_eval(argc, argv, klass, self);
5314  }
5315  
5316  VALUE
5317  rb_mod_module_eval(argc, argv, mod)
5318      int argc;
5319      VALUE *argv;
5320      VALUE mod;
5321  {
5322      return specific_eval(argc, argv, mod, mod);
5323  }
5324  
5325  VALUE rb_load_path;
5326  
5327  void
5328  rb_load(fname, wrap)
5329      VALUE fname;
5330      int wrap;
5331  {
5332      VALUE tmp;
5333      int state;
5334      volatile ID last_func;
5335      volatile VALUE wrapper = 0;
5336      volatile VALUE self = ruby_top_self;
5337      NODE *saved_cref = ruby_cref;
5338      TMP_PROTECT;
5339  
5340      if (wrap && ruby_safe_level >= 4) {
5341          StringValue(fname);
5342      }
5343      else {
5344          SafeStringValue(fname);
5345      }
5346      tmp = rb_find_file(fname);
5347      if (!tmp) {
5348          rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr);
5349      }
5350      fname = tmp;
5351  
5352      ruby_errinfo = Qnil;        /* ensure */
5353      PUSH_VARS();
5354      PUSH_CLASS();
5355      wrapper = ruby_wrapper;
5356      ruby_cref = top_cref;
5357      if (!wrap) {
5358          rb_secure(4);           /* should alter global state */
5359          ruby_class = rb_cObject;
5360          ruby_wrapper = 0;
5361      }
5362      else {
5363          /* load in anonymous module as toplevel */
5364          ruby_class = ruby_wrapper = rb_module_new();
5365          self = rb_obj_clone(ruby_top_self);
5366          rb_extend_object(self, ruby_class);
5367          PUSH_CREF(ruby_wrapper);
5368      }
5369      PUSH_FRAME();
5370      ruby_frame->last_func = 0;
5371      ruby_frame->last_class = 0;
5372      ruby_frame->self = self;
5373      ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,ruby_class,0,0);
5374      PUSH_SCOPE();
5375      /* default visibility is private at loading toplevel */
5376      SCOPE_SET(SCOPE_PRIVATE);
5377      PUSH_TAG(PROT_NONE);
5378      state = EXEC_TAG();
5379      last_func = ruby_frame->last_func;
5380      if (state == 0) {
5381          NODE *node;
5382  
5383          DEFER_INTS;
5384          ruby_in_eval++;
5385          rb_load_file(RSTRING(fname)->ptr);
5386          ruby_in_eval--;
5387          node = ruby_eval_tree;
5388          ALLOW_INTS;
5389          if (ruby_nerrs == 0) {
5390              eval_node(self, node);
5391          }
5392      }
5393      ruby_frame->last_func = last_func;
5394      if (ruby_scope->flags == SCOPE_ALLOCA && ruby_class == rb_cObject) {
5395          if (ruby_scope->local_tbl) /* toplevel was empty */
5396              free(ruby_scope->local_tbl);
5397      }
5398      POP_TAG();
5399      ruby_cref = saved_cref;
5400      POP_SCOPE();
5401      POP_FRAME();
5402      POP_CLASS();
5403      POP_VARS();
5404      ruby_wrapper = wrapper;
5405      if (ruby_nerrs > 0) {
5406          ruby_nerrs = 0;
5407          rb_exc_raise(ruby_errinfo);
5408      }
5409      if (state) jump_tag_but_local_jump(state);
5410      if (!NIL_P(ruby_errinfo))   /* exception during load */
5411          rb_exc_raise(ruby_errinfo);
5412  }
5413  
5414  void
5415  rb_load_protect(fname, wrap, state)
5416      VALUE fname;
5417      int wrap;
5418      int *state;
5419  {
5420      int status;
5421  
5422      PUSH_TAG(PROT_NONE);
5423      if ((status = EXEC_TAG()) == 0) {
5424          rb_load(fname, wrap);
5425      }
5426      POP_TAG();
5427      if (state) *state = status;
5428  }
5429  
5430  static VALUE
5431  rb_f_load(argc, argv)
5432      int argc;
5433      VALUE *argv;
5434  {
5435      VALUE fname, wrap;
5436  
5437      rb_scan_args(argc, argv, "11", &fname, &wrap);
5438      rb_load(fname, RTEST(wrap));
5439      return Qtrue;
5440  }
5441  
5442  VALUE ruby_dln_librefs;
5443  static VALUE rb_features;
5444  static st_table *loading_tbl;
5445  
5446  static int
5447  rb_feature_p(feature, wait)
5448      const char *feature;
5449      int wait;
5450  {
5451      VALUE v;
5452      char *f;
5453      long i, len = strlen(feature);
5454  
5455      for (i = 0; i < RARRAY(rb_features)->len; ++i) {
5456          v = RARRAY(rb_features)->ptr[i];
5457          f = StringValuePtr(v);
5458          if (strcmp(f, feature) == 0) {
5459              goto load_wait;
5460          }
5461          if (strncmp(f, feature, len) == 0) {
5462              if (strcmp(f+len, ".so") == 0) {
5463                  return Qtrue;
5464              }
5465              if (strcmp(f+len, ".rb") == 0) {
5466                  if (wait) goto load_wait;
5467                  return Qtrue;
5468              }
5469          }
5470      }
5471      return Qfalse;
5472  
5473    load_wait:
5474      if (loading_tbl) {
5475          char *ext = strrchr(f, '.');
5476          if (ext && strcmp(ext, ".rb") == 0) {
5477              rb_thread_t th;
5478  
5479              while (st_lookup(loading_tbl, f, &th)) {
5480                  if (th == curr_thread) {
5481                      return Qtrue;
5482                  }
5483                  CHECK_INTS;
5484                  rb_thread_schedule();
5485              }
5486          }
5487      }
5488      return Qtrue;
5489  }
5490  
5491  static const char *const loadable_ext[] = {
5492      ".rb", DLEXT,
5493  #ifdef DLEXT2
5494      DLEXT2,
5495  #endif
5496      0
5497  };
5498  
5499  int
5500  rb_provided(feature)
5501      const char *feature;
5502  {
5503      VALUE f = rb_str_new2(feature);
5504  
5505      if (strrchr(feature, '.') == 0) {
5506          if (rb_find_file_ext(&f, loadable_ext) == 0) {
5507              return rb_feature_p(feature, Qfalse);
5508          }
5509      }
5510      return rb_feature_p(RSTRING(f)->ptr, Qfalse);
5511  }
5512  
5513  static void
5514  rb_provide_feature(feature)
5515      VALUE feature;
5516  {
5517      rb_ary_push(rb_features, feature);
5518  }
5519  
5520  void
5521  rb_provide(feature)
5522      const char *feature;
5523  {
5524      rb_provide_feature(rb_str_new2(feature));
5525  }
5526  
5527  VALUE
5528  rb_f_require(obj, fname)
5529      VALUE obj, fname;
5530  {
5531      VALUE feature, tmp;
5532      char *ext, *ftptr; /* OK */
5533      int state;
5534      volatile int safe = ruby_safe_level;
5535  
5536      SafeStringValue(fname);
5537      ext = strrchr(RSTRING(fname)->ptr, '.');
5538      if (ext) {
5539          if (strcmp(".rb", ext) == 0) {
5540              feature = rb_str_dup(fname);
5541              tmp = rb_find_file(fname);
5542              if (tmp) {
5543                  fname = tmp;
5544                  goto load_rb;
5545              }
5546          }
5547          else if (strcmp(".so", ext) == 0 || strcmp(".o", ext) == 0) {
5548              fname = rb_str_new(RSTRING(fname)->ptr, ext-RSTRING(fname)->ptr);
5549  #ifdef DLEXT2
5550              tmp = fname;
5551              if (rb_find_file_ext(&tmp, loadable_ext+1)) {
5552                  feature = tmp;
5553                  fname = rb_find_file(tmp);
5554                  goto load_dyna;
5555              }
5556  #else
5557              feature = tmp = rb_str_dup(fname);
5558              rb_str_cat2(tmp, DLEXT);
5559              tmp = rb_find_file(tmp);
5560              if (tmp) {
5561                  fname = tmp;
5562                  goto load_dyna;
5563              }
5564  #endif
5565          }
5566          else if (strcmp(DLEXT, ext) == 0) {
5567              tmp = rb_find_file(fname);
5568              if (tmp) {
5569                  feature = fname;
5570                  fname = tmp;
5571                  goto load_dyna;
5572              }
5573          }
5574  #ifdef DLEXT2
5575          else if (strcmp(DLEXT2, ext) == 0) {
5576              tmp = rb_find_file(fname);
5577              if (tmp) {
5578                  feature = fname;
5579                  fname = tmp;
5580                  goto load_dyna;
5581              }
5582          }
5583  #endif
5584      }
5585      tmp = fname;
5586      switch (rb_find_file_ext(&tmp, loadable_ext)) {
5587        case 0:
5588          break;
5589  
5590        case 1:
5591          feature = fname = tmp;
5592          goto load_rb;
5593  
5594        default:
5595          feature = tmp;
5596          fname = rb_find_file(tmp);
5597          goto load_dyna;
5598      }
5599      if (rb_feature_p(RSTRING(fname)->ptr, Qfalse))
5600          return Qfalse;
5601      rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr);
5602  
5603    load_dyna:
5604      if (rb_feature_p(RSTRING(feature)->ptr, Qfalse))
5605          return Qfalse;
5606      rb_provide_feature(feature);
5607      {
5608          int volatile old_vmode = scope_vmode;
5609  
5610          PUSH_TAG(PROT_NONE);
5611          if ((state = EXEC_TAG()) == 0) {
5612              void *handle;
5613  
5614              SCOPE_SET(SCOPE_PUBLIC);
5615              handle = dln_load(RSTRING(fname)->ptr);
5616              rb_ary_push(ruby_dln_librefs, LONG2NUM((long)handle));
5617          }
5618          POP_TAG();
5619          SCOPE_SET(old_vmode);
5620      }
5621      if (state) JUMP_TAG(state);
5622  
5623      return Qtrue;
5624  
5625    load_rb:
5626      if (rb_feature_p(RSTRING(feature)->ptr, Qtrue))
5627          return Qfalse;
5628      ruby_safe_level = 0;
5629      rb_provide_feature(feature);
5630      /* loading ruby library should be serialized. */
5631      if (!loading_tbl) {
5632          loading_tbl = st_init_strtable();
5633      }
5634      /* partial state */
5635      ftptr = ruby_strdup(RSTRING(feature)->ptr);
5636      st_insert(loading_tbl, ftptr, curr_thread);
5637  
5638      PUSH_TAG(PROT_NONE);
5639      if ((state = EXEC_TAG()) == 0) {
5640          rb_load(fname, 0);
5641      }
5642      POP_TAG();
5643      st_delete(loading_tbl, &ftptr, 0); /* loading done */
5644      free(ftptr);
5645      ruby_safe_level = safe;
5646      if (state) JUMP_TAG(state);
5647  
5648      return Qtrue;
5649  }
5650  
5651  VALUE
5652  rb_require(fname)
5653      const char *fname;
5654  {
5655      return rb_f_require(Qnil, rb_str_new2(fname));
5656  }
5657  
5658  static void
5659  secure_visibility(self)
5660      VALUE self;
5661  {
5662      if (ruby_safe_level >= 4 && !OBJ_TAINTED(self)) {
5663          rb_raise(rb_eSecurityError, "Insecure: can't change method visibility");
5664      }
5665  }
5666  
5667  static void
5668  set_method_visibility(self, argc, argv, ex)
5669      VALUE self;
5670      int argc;
5671      VALUE *argv;
5672      ID ex;
5673  {
5674      int i;
5675  
5676      secure_visibility(self);
5677      for (i=0; i<argc; i++) {
5678          rb_export_method(self, rb_to_id(argv[i]), ex);
5679      }
5680      rb_clear_cache_by_class(self);
5681  }
5682  
5683  static VALUE
5684  rb_mod_public(argc, argv, module)
5685      int argc;
5686      VALUE *argv;
5687      VALUE module;
5688  {
5689      secure_visibility(module);
5690      if (argc == 0) {
5691          SCOPE_SET(SCOPE_PUBLIC);
5692      }
5693      else {
5694          set_method_visibility(module, argc, argv, NOEX_PUBLIC);
5695      }
5696      return module;
5697  }
5698  
5699  static VALUE
5700  rb_mod_protected(argc, argv, module)
5701      int argc;
5702      VALUE *argv;
5703      VALUE module;
5704  {
5705      secure_visibility(module);
5706      if (argc == 0) {
5707          SCOPE_SET(SCOPE_PROTECTED);
5708      }
5709      else {
5710          set_method_visibility(module, argc, argv, NOEX_PROTECTED);
5711      }
5712      return module;
5713  }
5714  
5715  static VALUE
5716  rb_mod_private(argc, argv, module)
5717      int argc;
5718      VALUE *argv;
5719      VALUE module;
5720  {
5721      secure_visibility(module);
5722      if (argc == 0) {
5723          SCOPE_SET(SCOPE_PRIVATE);
5724      }
5725      else {
5726          set_method_visibility(module, argc, argv, NOEX_PRIVATE);
5727      }
5728      return module;
5729  }
5730  
5731  static VALUE
5732  rb_mod_public_method(argc, argv, obj)
5733      int argc;
5734      VALUE *argv;
5735      VALUE obj;
5736  {
5737      set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PUBLIC);
5738      return obj;
5739  }
5740  
5741  static VALUE
5742  rb_mod_private_method(argc, argv, obj)
5743      int argc;
5744      VALUE *argv;
5745      VALUE obj;
5746  {
5747      set_method_visibility(CLASS_OF(obj), argc, argv, NOEX_PRIVATE);
5748      return obj;
5749  }
5750  
5751  static VALUE
5752  top_public(argc, argv)
5753      int argc;
5754      VALUE *argv;
5755  {
5756      return rb_mod_public(argc, argv, rb_cObject);
5757  }
5758  
5759  static VALUE
5760  top_private(argc, argv)
5761      int argc;
5762      VALUE *argv;
5763  {
5764      return rb_mod_private(argc, argv, rb_cObject);
5765  }
5766  
5767  static VALUE
5768  rb_mod_modfunc(argc, argv, module)
5769      int argc;
5770      VALUE *argv;
5771      VALUE module;
5772  {
5773      int i;
5774      ID id;
5775      NODE *body;
5776  
5777      if (TYPE(module) != T_MODULE) {
5778          rb_raise(rb_eTypeError, "module_function must be called for modules");
5779      }
5780  
5781      secure_visibility(module);
5782      if (argc == 0) {
5783          SCOPE_SET(SCOPE_MODFUNC);
5784          return module;
5785      }
5786  
5787      set_method_visibility(module, argc, argv, NOEX_PRIVATE);
5788      for (i=0; i<argc; i++) {
5789          VALUE m = module;
5790  
5791          id = rb_to_id(argv[i]);
5792          for (;;) {
5793              body = search_method(m, id, &m);
5794              if (body == 0 || body->nd_body == 0) {
5795                  rb_bug("undefined method `%s'; can't happen", rb_id2name(id));
5796              }
5797              if (nd_type(body->nd_body) != NODE_ZSUPER) {
5798                  break;          /* normal case: need not to follow 'super' link */
5799              }
5800              m = RCLASS(m)->super;
5801          }
5802          rb_add_method(rb_singleton_class(module), id, body->nd_body, NOEX_PUBLIC);
5803          rb_funcall(module, singleton_added, 1, ID2SYM(id));
5804      }
5805      return module;
5806  }
5807  
5808  static VALUE
5809  rb_mod_append_features(module, include)
5810      VALUE module, include;
5811  {
5812      switch (TYPE(include)) {
5813        case T_CLASS:
5814        case T_MODULE:
5815          break;
5816        default:
5817          Check_Type(include, T_CLASS);
5818          break;
5819      }
5820      rb_include_module(include, module);
5821  
5822      return module;
5823  }
5824  
5825  static VALUE
5826  rb_mod_include(argc, argv, module)
5827      int argc;
5828      VALUE *argv;
5829      VALUE module;
5830  {
5831      while (argc--) {
5832          VALUE m = argv[argc];
5833  
5834          Check_Type(m, T_MODULE);
5835          rb_funcall(m, rb_intern("append_features"), 1, module);
5836          rb_funcall(m, rb_intern("included"), 1, module);
5837      }
5838      return module;
5839  }
5840  
5841  void
5842  rb_obj_call_init(obj, argc, argv)
5843      VALUE obj;
5844      int argc;
5845      VALUE *argv;
5846  {
5847      PUSH_ITER(rb_block_given_p()?ITER_PRE:ITER_NOT);
5848      rb_funcall2(obj, init, argc, argv);
5849      POP_ITER();
5850  }
5851  
5852  static VALUE
5853  top_include(argc, argv)
5854      int argc;
5855      VALUE *argv;
5856  {
5857      rb_secure(4);
5858      return rb_mod_include(argc, argv, rb_cObject);
5859  }
5860  
5861  void
5862  rb_extend_object(obj, module)
5863      VALUE obj, module;
5864  {
5865      rb_include_module(rb_singleton_class(obj), module);
5866  }
5867  
5868  static VALUE
5869  rb_mod_extend_object(mod, obj)
5870      VALUE mod, obj;
5871  {
5872      rb_extend_object(obj, mod);
5873      return obj;
5874  }
5875  
5876  static VALUE
5877  rb_obj_extend(argc, argv, obj)
5878      int argc;
5879      VALUE *argv;
5880      VALUE obj;
5881  {
5882      int i;
5883  
5884      if (argc == 0) {
5885          rb_raise(rb_eArgError, "wrong number of arguments(0 for 1)");
5886      }
5887      for (i=0; i<argc; i++) Check_Type(argv[i], T_MODULE);
5888      while (argc--) {
5889          rb_funcall(argv[argc], rb_intern("extend_object"), 1, obj);
5890      }
5891      return obj;
5892  }
5893  
5894  VALUE rb_f_trace_var();
5895  VALUE rb_f_untrace_var();
5896  
5897  static void
5898  errinfo_setter(val, id, var)
5899      VALUE val;
5900      ID id;
5901      VALUE *var;
5902  {
5903      if (!NIL_P(val) && !rb_obj_is_kind_of(val, rb_eException)) {
5904          rb_raise(rb_eTypeError, "assigning non-exception to $!");
5905      }
5906      *var = val;
5907  }
5908  
5909  static VALUE
5910  errat_getter(id)
5911      ID id;
5912  {
5913      return get_backtrace(ruby_errinfo);
5914  }
5915  
5916  static void
5917  errat_setter(val, id, var)
5918      VALUE val;
5919      ID id;
5920      VALUE *var;
5921  {
5922      if (NIL_P(ruby_errinfo)) {
5923          rb_raise(rb_eArgError, "$! not set");
5924      }
5925      set_backtrace(ruby_errinfo, val);
5926  }
5927  
5928  static VALUE
5929  rb_f_local_variables()
5930  {
5931      ID *tbl;
5932      int n, i;
5933      VALUE ary = rb_ary_new();
5934      struct RVarmap *vars;
5935  
5936      tbl = ruby_scope->local_tbl;
5937      if (tbl) {
5938          n = *tbl++;
5939          for (i=2; i<n; i++) {   /* skip first 2 ($_ and $~) */
5940              if (!rb_is_local_id(tbl[i])) continue; /* skip flip states */
5941              rb_ary_push(ary, rb_str_new2(rb_id2name(tbl[i])));
5942          }
5943      }
5944  
5945      vars = ruby_dyna_vars;
5946      while (vars) {
5947          if (vars->id) {
5948              rb_ary_push(ary, rb_str_new2(rb_id2name(vars->id)));
5949          }
5950          vars = vars->next;
5951      }
5952  
5953      return ary;
5954  }
5955  
5956  static VALUE rb_f_catch _((VALUE,VALUE));
5957  NORETURN(static VALUE rb_f_throw _((int,VALUE*)));
5958  
5959  struct end_proc_data {
5960      void (*func)();
5961      VALUE data;
5962      struct end_proc_data *next;
5963  };
5964  
5965  static struct end_proc_data *end_procs, *ephemeral_end_procs;
5966  
5967  void
5968  rb_set_end_proc(func, data)
5969      void (*func) _((VALUE));
5970      VALUE data;
5971  {
5972      struct end_proc_data *link = ALLOC(struct end_proc_data);
5973      struct end_proc_data **list;
5974  
5975      if (ruby_wrapper) list = &ephemeral_end_procs;
5976      else              list = &end_procs;
5977      link->next = *list;
5978      link->func = func;
5979      link->data = data;
5980      *list = link;
5981  }
5982  
5983  void
5984  rb_mark_end_proc()
5985  {
5986      struct end_proc_data *link;
5987  
5988      link = end_procs;
5989      while (link) {
5990          rb_gc_mark(link->data);
5991          link = link->next;
5992      }
5993      link = ephemeral_end_procs;
5994      while (link) {
5995          rb_gc_mark(link->data);
5996          link = link->next;
5997      }
5998  }
5999  
6000  static void call_end_proc _((VALUE data));
6001  
6002  static void
6003  call_end_proc(data)
6004      VALUE data;
6005  {
6006      PUSH_ITER(ITER_NOT);
6007      PUSH_FRAME();
6008      ruby_frame->self = ruby_frame->prev->self;
6009      ruby_frame->last_func = 0;
6010      ruby_frame->last_class = 0;
6011      proc_invoke(data, rb_ary_new2(0), Qfalse, Qundef);
6012      POP_FRAME();
6013      POP_ITER();
6014  }
6015  
6016  static void
6017  rb_f_END()
6018  {
6019      PUSH_FRAME();
6020      ruby_frame->argc = 0;
6021      rb_set_end_proc(call_end_proc, rb_f_lambda());
6022      POP_FRAME();
6023  }
6024  
6025  static VALUE
6026  rb_f_at_exit()
6027  {
6028      VALUE proc;
6029  
6030      proc = rb_f_lambda();
6031  
6032      rb_set_end_proc(call_end_proc, proc);
6033      return proc;
6034  }
6035  
6036  void
6037  rb_exec_end_proc()
6038  {
6039      struct end_proc_data *link, *save;
6040      int status;
6041  
6042      save = link = end_procs;
6043      while (link) {
6044          rb_protect((VALUE(*)_((VALUE)))link->func, link->data, &status);
6045          if (status) {
6046              error_handle(status);
6047          }
6048          link = link->next;
6049      }
6050      link = end_procs;
6051      while (link != save) {
6052          rb_protect((VALUE(*)_((VALUE)))link->func, link->data, &status);
6053          if (status) {
6054              error_handle(status);
6055          }
6056          link = link->next;
6057      }
6058      while (ephemeral_end_procs) {
6059          link = ephemeral_end_procs;
6060          ephemeral_end_procs = link->next;
6061          rb_protect((VALUE(*)_((VALUE)))link->func, link->data, &status);
6062          if (status) {
6063              error_handle(status);
6064          }
6065          free(link);
6066      }
6067  }
6068  
6069  void
6070  Init_eval()
6071  {
6072      init = rb_intern("initialize");
6073      alloc = rb_intern("allocate");
6074      eqq = rb_intern("===");
6075      each = rb_intern("each");
6076  
6077      aref = rb_intern("[]");
6078      aset = rb_intern("[]=");
6079      match = rb_intern("=~");
6080      missing = rb_intern("method_missing");
6081      added = rb_intern("method_added");
6082      singleton_added = rb_intern("singleton_method_added");
6083      removed = rb_intern("method_removed");
6084      singleton_removed = rb_intern("singleton_method_removed");
6085      undefined = rb_intern("method_undefined");
6086      singleton_undefined = rb_intern("singleton_method_undefined");
6087  
6088      __id__ = rb_intern("__id__");
6089      __send__ = rb_intern("__send__");
6090  
6091      rb_global_variable((VALUE*)&top_scope);
6092      rb_global_variable((VALUE*)&ruby_eval_tree_begin);
6093  
6094      rb_global_variable((VALUE*)&ruby_eval_tree);
6095      rb_global_variable((VALUE*)&ruby_dyna_vars);
6096  
6097      rb_define_virtual_variable("$@", errat_getter, errat_setter);
6098      rb_define_hooked_variable("$!", &ruby_errinfo, 0, errinfo_setter);
6099  
6100      rb_define_global_function("eval", rb_f_eval, -1);
6101      rb_define_global_function("iterator?", rb_f_block_given_p, 0);
6102      rb_define_global_function("block_given?", rb_f_block_given_p, 0);
6103      rb_define_global_function("method_missing", rb_f_missing, -1);
6104      rb_define_global_function("loop", rb_f_loop, 0);
6105  
6106      rb_define_method(rb_mKernel, "respond_to?", rb_obj_respond_to, -1);
6107  
6108      rb_define_global_function("raise", rb_f_raise, -1);
6109      rb_define_global_function("fail", rb_f_raise, -1);
6110  
6111      rb_define_global_function("caller", rb_f_caller, -1);
6112  
6113      rb_define_global_function("exit", rb_f_exit, -1);
6114      rb_define_global_function("abort", rb_f_abort, -1);
6115  
6116      rb_define_global_function("at_exit", rb_f_at_exit, 0);
6117  
6118      rb_define_global_function("catch", rb_f_catch, 1);
6119      rb_define_global_function("throw", rb_f_throw, -1);
6120      rb_define_global_function("global_variables", rb_f_global_variables, 0);
6121      rb_define_global_function("local_variables", rb_f_local_variables, 0);
6122  
6123      rb_define_method(rb_mKernel, "send", rb_f_send, -1);
6124      rb_define_method(rb_mKernel, "__send__", rb_f_send, -1);
6125      rb_define_method(rb_mKernel, "instance_eval", rb_obj_instance_eval, -1);
6126  
6127      rb_define_private_method(rb_cModule, "append_features", rb_mod_append_features, 1);
6128      rb_define_private_method(rb_cModule, "extend_object", rb_mod_extend_object, 1);
6129      rb_define_private_method(rb_cModule, "include", rb_mod_include, -1);
6130      rb_define_private_method(rb_cModule, "public", rb_mod_public, -1);
6131      rb_define_private_method(rb_cModule, "protected", rb_mod_protected, -1);
6132      rb_define_private_method(rb_cModule, "private", rb_mod_private, -1);
6133      rb_define_private_method(rb_cModule, "module_function", rb_mod_modfunc, -1);
6134      rb_define_method(rb_cModule, "method_defined?", rb_mod_method_defined, 1);
6135      rb_define_method(rb_cModule, "public_class_method", rb_mod_public_method, -1);
6136      rb_define_method(rb_cModule, "private_class_method", rb_mod_private_method, -1);
6137      rb_define_method(rb_cModule, "module_eval", rb_mod_module_eval, -1);
6138      rb_define_method(rb_cModule, "class_eval", rb_mod_module_eval, -1);
6139  
6140      rb_undef_method(rb_cClass, "module_function");
6141  
6142      rb_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, 1);
6143      rb_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, 1);
6144      rb_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2);
6145      rb_define_private_method(rb_cModule, "define_method", rb_mod_define_method, -1);
6146  
6147      rb_define_singleton_method(rb_cModule, "nesting", rb_mod_nesting, 0);
6148      rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_constants, 0);
6149  
6150      rb_define_singleton_method(ruby_top_self, "include", top_include, -1);
6151      rb_define_singleton_method(ruby_top_self, "public", top_public, -1);
6152      rb_define_singleton_method(ruby_top_self, "private", top_private, -1);
6153  
6154      rb_define_method(rb_mKernel, "extend", rb_obj_extend, -1);
6155  
6156      rb_define_global_function("trace_var", rb_f_trace_var, -1);
6157      rb_define_global_function("untrace_var", rb_f_untrace_var, -1);
6158  
6159      rb_define_global_function("set_trace_func", set_trace_func, 1);
6160      rb_global_variable(&trace_func);
6161  
6162      rb_define_virtual_variable("$SAFE", safe_getter, safe_setter);
6163  }
6164  
6165  VALUE rb_f_autoload();
6166  
6167  void
6168  Init_load()
6169  {
6170      rb_load_path = rb_ary_new();
6171      rb_define_readonly_variable("$:", &rb_load_path);
6172      rb_define_readonly_variable("$-I", &rb_load_path);
6173      rb_define_readonly_variable("$LOAD_PATH", &rb_load_path);
6174  
6175      rb_features = rb_ary_new();
6176      rb_define_readonly_variable("$\"", &rb_features);
6177  
6178      rb_define_global_function("load", rb_f_load, -1);
6179      rb_define_global_function("require", rb_f_require, 1);
6180      rb_define_global_function("autoload", rb_f_autoload, 2);
6181      rb_global_variable(&ruby_wrapper);
6182  
6183      ruby_dln_librefs = rb_ary_new();
6184      rb_global_variable(&ruby_dln_librefs);
6185  }
6186  
6187  static void
6188  scope_dup(scope)
6189      struct SCOPE *scope;
6190  {
6191      ID *tbl;
6192      VALUE *vars;
6193  
6194      scope->flags |= SCOPE_DONT_RECYCLE;
6195      if (scope->flags & SCOPE_MALLOC) return;
6196  
6197      if (scope->local_tbl) {
6198          tbl = scope->local_tbl;
6199          vars = ALLOC_N(VALUE, tbl[0]+1);
6200          *vars++ = scope->local_vars[-1];
6201          MEMCPY(vars, scope->local_vars, VALUE, tbl[0]);
6202          scope->local_vars = vars;
6203          scope->flags |= SCOPE_MALLOC;
6204      }
6205  }
6206  
6207  static void
6208  blk_mark(data)
6209      struct BLOCK *data;
6210  {
6211      while (data) {
6212          rb_gc_mark_frame(&data->frame);
6213          rb_gc_mark((VALUE)data->scope);
6214          rb_gc_mark((VALUE)data->var);
6215          rb_gc_mark((VALUE)data->body);
6216          rb_gc_mark((VALUE)data->self);
6217          rb_gc_mark((VALUE)data->dyna_vars);
6218          rb_gc_mark((VALUE)data->klass);
6219          rb_gc_mark((VALUE)data->tag);
6220          rb_gc_mark(data->wrapper);
6221          data = data->prev;
6222      }
6223  }
6224  
6225  static void
6226  blk_free(data)
6227      struct BLOCK *data;
6228  {
6229      struct FRAME *frame;
6230      void *tmp;
6231  
6232      frame = data->frame.prev;
6233      while (frame) {
6234          if (frame->argc > 0 && (frame->flags & FRAME_MALLOC))
6235              free(frame->argv);
6236          tmp = frame;
6237          frame = frame->prev;
6238          free(tmp);
6239      }
6240      while (data) {
6241          if (data->frame.argc > 0)
6242              free(data->frame.argv);
6243          tmp = data;
6244          data = data->prev;
6245          free(tmp);
6246      }
6247  }
6248  
6249  static void
6250  blk_copy_prev(block)
6251      struct BLOCK *block;
6252  {
6253      struct BLOCK *tmp;
6254      struct RVarmap* vars;
6255  
6256      while (block->prev) {
6257          tmp = ALLOC_N(struct BLOCK, 1);
6258          MEMCPY(tmp, block->prev, struct BLOCK, 1);
6259          if (tmp->frame.argc > 0) {
6260              tmp->frame.argv = ALLOC_N(VALUE, tmp->frame.argc);
6261              MEMCPY(tmp->frame.argv, block->prev->frame.argv, VALUE, tmp->frame.argc);
6262              tmp->frame.flags |= FRAME_MALLOC;
6263          }
6264          scope_dup(tmp->scope);
6265          tmp->tag->flags |= BLOCK_DYNAMIC;
6266  
6267          for (vars = tmp->dyna_vars; vars; vars = vars->next) {
6268              if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
6269              FL_SET(vars, DVAR_DONT_RECYCLE);
6270          }
6271  
6272          block->prev = tmp;
6273          block = tmp;
6274      }
6275  }
6276  
6277  static void
6278  frame_dup(frame)
6279      struct FRAME *frame;
6280  {
6281      VALUE *argv;
6282      struct FRAME *tmp;
6283  
6284      for (;;) {
6285          if (frame->argc > 0) {
6286              argv = ALLOC_N(VALUE, frame->argc);
6287              MEMCPY(argv, frame->argv, VALUE, frame->argc);
6288              frame->argv = argv;
6289              frame->flags |= FRAME_MALLOC;
6290          }
6291          frame->tmp = 0;         /* should not preserve tmp */
6292          if (!frame->prev) break;
6293          tmp = ALLOC(struct FRAME);
6294          *tmp = *frame->prev;
6295          frame->prev = tmp;
6296          frame = tmp;
6297      }
6298  }
6299  
6300  static VALUE
6301  bind_clone(self)
6302      VALUE self;
6303  {
6304      struct BLOCK *orig, *data;
6305      VALUE bind;
6306  
6307      Data_Get_Struct(self, struct BLOCK, orig);
6308      bind = Data_Make_Struct(rb_cBinding,struct BLOCK,blk_mark,blk_free,data);
6309      CLONESETUP(bind, self);
6310      MEMCPY(data, orig, struct BLOCK, 1);
6311      frame_dup(&data->frame);
6312  
6313      if (data->iter) {
6314          blk_copy_prev(data);
6315      }
6316      else {
6317          data->prev = 0;
6318      }
6319  
6320      return bind;
6321  }
6322  
6323  static VALUE
6324  rb_f_binding(self)
6325      VALUE self;
6326  {
6327      struct BLOCK *data, *p;
6328      struct RVarmap *vars;
6329      VALUE bind;
6330  
6331      PUSH_BLOCK(0,0);
6332      bind = Data_Make_Struct(rb_cBinding,struct BLOCK,blk_mark,blk_free,data);
6333      *data = *ruby_block;
6334  
6335      data->orig_thread = rb_thread_current();
6336      data->wrapper = ruby_wrapper;
6337      data->iter = rb_f_block_given_p();
6338      frame_dup(&data->frame);
6339      if (ruby_frame->prev) {
6340          data->frame.last_func = ruby_frame->prev->last_func;
6341          data->frame.last_class = ruby_frame->prev->last_class;
6342      }
6343  
6344      if (data->iter) {
6345          blk_copy_prev(data);
6346      }
6347      else {
6348          data->prev = 0;
6349      }
6350      data->flags |= BLOCK_DYNAMIC;
6351      data->tag->flags |= BLOCK_DYNAMIC;
6352  
6353      for (p = data; p; p = p->prev) {
6354          for (vars = p->dyna_vars; vars; vars = vars->next) {
6355              if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
6356              FL_SET(vars, DVAR_DONT_RECYCLE);
6357          }
6358      }
6359      scope_dup(data->scope);
6360      POP_BLOCK();
6361  
6362      return bind;
6363  }
6364  
6365  #define PROC_T3    FL_USER1
6366  #define PROC_T4    FL_USER2
6367  #define PROC_TMAX  (FL_USER1|FL_USER2)
6368  #define PROC_TMASK (FL_USER1|FL_USER2)
6369  
6370  static void
6371  proc_save_safe_level(data)
6372      VALUE data;
6373  {
6374      if (OBJ_TAINTED(data)) {
6375          switch (ruby_safe_level) {
6376            case 3:
6377              FL_SET(data, PROC_T3);
6378              break;
6379            case 4:
6380              FL_SET(data, PROC_T4);
6381              break;
6382            default:
6383              if (ruby_safe_level > 4) {
6384                  FL_SET(data, PROC_TMAX);
6385              }
6386              break;
6387          }
6388      }
6389  }
6390  
6391  static int
6392  proc_get_safe_level(data)
6393      VALUE data;
6394  {
6395      if (OBJ_TAINTED(data)) {
6396          switch (RBASIC(data)->flags & PROC_TMASK) {
6397            case PROC_T3:
6398              return 3;
6399            case PROC_T4:
6400              return 4;
6401            case PROC_TMAX:
6402              return 5;
6403          }
6404          return 3;
6405      }
6406      return 0;
6407  }
6408  
6409  static void
6410  proc_set_safe_level(data)
6411      VALUE data;
6412  {
6413      if (OBJ_TAINTED(data)) {
6414          ruby_safe_level = proc_get_safe_level(data);
6415      }
6416  }
6417  
6418  static VALUE
6419  proc_new(klass)
6420      VALUE klass;
6421  {
6422      volatile VALUE proc;
6423      struct BLOCK *data, *p;
6424      struct RVarmap *vars;
6425  
6426      if (!rb_block_given_p() && !rb_f_block_given_p()) {
6427          rb_raise(rb_eArgError, "tried to create Proc object without a block");
6428      }
6429  
6430      proc = Data_Make_Struct(klass, struct BLOCK, blk_mark, blk_free, data);
6431      *data = *ruby_block;
6432  
6433      data->orig_thread = rb_thread_current();
6434      data->wrapper = ruby_wrapper;
6435      data->iter = data->prev?Qtrue:Qfalse;
6436      frame_dup(&data->frame);
6437      if (data->iter) {
6438          blk_copy_prev(data);
6439      }
6440      else {
6441          data->prev = 0;
6442      }
6443      data->flags |= BLOCK_DYNAMIC;
6444      data->tag->flags |= BLOCK_DYNAMIC;
6445  
6446      for (p = data; p; p = p->prev) {
6447          for (vars = p->dyna_vars; vars; vars = vars->next) {
6448              if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
6449              FL_SET(vars, DVAR_DONT_RECYCLE);
6450          }
6451      }
6452      scope_dup(data->scope);
6453      proc_save_safe_level(proc);
6454  
6455      return proc;
6456  }
6457  
6458  static VALUE
6459  proc_s_new(argc, argv, klass)
6460      int argc;
6461      VALUE *argv;
6462      VALUE klass;
6463  {
6464      VALUE proc = proc_new(klass);
6465  
6466      rb_obj_call_init(proc, argc, argv);
6467      return proc;
6468  }
6469  
6470  VALUE
6471  rb_f_lambda()
6472  {
6473      return proc_new(rb_cProc);
6474  }
6475  
6476  static int
6477  blk_orphan(data)
6478      struct BLOCK *data;
6479  {
6480      if (!(data->scope->flags & SCOPE_NOSTACK)) {
6481          return 0;
6482      }
6483      if ((data->tag->flags & BLOCK_ORPHAN)) {
6484          return 1;
6485      }
6486      if (data->orig_thread != rb_thread_current()) {
6487          return 1;
6488      }
6489      return 0;
6490  }
6491  
6492  static VALUE
6493  proc_invoke(proc, args, pcall, self)
6494      VALUE proc, args;           /* OK */
6495      int pcall;
6496      VALUE self;
6497  {
6498      struct BLOCK * volatile old_block;
6499      struct BLOCK _block;
6500      struct BLOCK *data;
6501      volatile VALUE result = Qnil;
6502      int state;
6503      volatile int orphan;
6504      volatile int safe = ruby_safe_level;
6505      volatile VALUE old_wrapper = ruby_wrapper;
6506      struct RVarmap * volatile old_dvars = ruby_dyna_vars;
6507  
6508      if (rb_block_given_p() && ruby_frame->last_func) {
6509          rb_warning("block for %s#%s is useless",
6510                     rb_class2name(CLASS_OF(proc)),
6511                     rb_id2name(ruby_frame->last_func));
6512      }
6513  
6514      Data_Get_Struct(proc, struct BLOCK, data);
6515      orphan = blk_orphan(data);
6516  
6517      ruby_wrapper = data->wrapper;
6518      ruby_dyna_vars = data->dyna_vars;
6519      /* PUSH BLOCK from data */
6520      old_block = ruby_block;
6521      _block = *data;
6522      ruby_block = &_block;
6523  
6524      PUSH_ITER(ITER_CUR);
6525      ruby_frame->iter = ITER_CUR;
6526  
6527      if (!pcall) {
6528          args = avalue_to_yvalue(args);
6529      }
6530      PUSH_TAG(PROT_NONE);
6531      state = EXEC_TAG();
6532      if (state == 0) {
6533          proc_set_safe_level(proc);
6534          result = rb_yield_0(args, self, self!=Qundef?CLASS_OF(self):0, pcall);
6535      }
6536      POP_TAG();
6537  
6538      POP_ITER();
6539      if (ruby_block->tag->dst == state) {
6540          state &= TAG_MASK;
6541      }
6542      ruby_block = old_block;
6543      ruby_wrapper = old_wrapper;
6544      ruby_dyna_vars = old_dvars;
6545      ruby_safe_level = safe;
6546  
6547      switch (state) {
6548        case 0:
6549          break;
6550        case TAG_BREAK:
6551          if (!pcall && orphan) {
6552              localjump_error("break from proc-closure", prot_tag->retval);
6553          }
6554          result = prot_tag->retval;
6555          break;
6556        case TAG_RETRY:
6557          localjump_error("retry from proc-closure", Qnil);
6558          break;
6559        case TAG_RETURN:
6560          if (orphan) {   /* orphan procedure */
6561              localjump_error("return from proc-closure", prot_tag->retval);
6562          }
6563          /* fall through */
6564        default:
6565          JUMP_TAG(state);
6566      }
6567      return result;
6568  }
6569  
6570  static VALUE
6571  proc_call(proc, args)
6572      VALUE proc, args;           /* OK */
6573  {
6574      return proc_invoke(proc, args, Qtrue, Qundef);
6575  }
6576  
6577  static VALUE
6578  proc_yield(proc, args)
6579      VALUE proc, args;           /* OK */
6580  {
6581      return proc_invoke(proc, args, Qfalse, Qundef);
6582  }
6583  
6584  static VALUE
6585  proc_arity(proc)
6586      VALUE proc;
6587  {
6588      struct BLOCK *data;
6589      NODE *list;
6590      int n;
6591  
6592      Data_Get_Struct(proc, struct BLOCK, data);
6593      if (data->var == 0) return INT2FIX(-1);
6594      if (data->var == (NODE*)1) return INT2FIX(0);
6595      if (data->var == (NODE*)2) return INT2FIX(0);
6596      switch (nd_type(data->var)) {
6597        default:
6598          return INT2FIX(-1);
6599        case NODE_MASGN:
6600          list = data->var->nd_head;
6601          n = 0;
6602          while (list) {
6603              n++;
6604              list = list->nd_next;
6605          }
6606          if (data->var->nd_args) return INT2FIX(-n-1);
6607          return INT2FIX(n);
6608      }
6609  }
6610  
6611  static VALUE
6612  proc_eq(self, other)
6613      VALUE self, other;
6614  {
6615      struct BLOCK *data, *data2;
6616  
6617      if (self == other) return Qtrue;
6618      if (TYPE(other) != T_DATA) return Qfalse;
6619      if (RDATA(other)->dmark != (RUBY_DATA_FUNC)blk_mark) return Qfalse;
6620      if (CLASS_OF(self) != CLASS_OF(other)) return Qfalse;
6621      Data_Get_Struct(self, struct BLOCK, data);
6622      Data_Get_Struct(other, struct BLOCK, data2);
6623      if (data->tag == data2->tag) return Qtrue;
6624      return Qfalse;
6625  }
6626  
6627  static VALUE
6628  proc_to_s(self, other)
6629      VALUE self, other;
6630  {
6631      struct BLOCK *data;
6632      char *cname = rb_class2name(CLASS_OF(self));
6633      const int w = (SIZEOF_LONG * CHAR_BIT) / 4;
6634      long len = strlen(cname)+6+w; /* 6:tags 16:addr */
6635      VALUE str;
6636  
6637      Data_Get_Struct(self, struct BLOCK, data);
6638      if (data->body) {
6639          len += strlen(data->body->nd_file) + 2 + (SIZEOF_LONG*CHAR_BIT-NODE_LSHIFT)/3;
6640          str = rb_str_new(0, len);
6641          sprintf(RSTRING(str)->ptr, "#<%s:0x%.*lx@%s:%d>", cname, w, (VALUE)data->tag,
6642                  data->body->nd_file, nd_line(data->body));
6643      }
6644      else {
6645          str = rb_str_new(0, len);
6646          sprintf(RSTRING(str)->ptr, "#<%s:0x%.*lx>", cname, w, (VALUE)data->tag);
6647      }
6648      RSTRING(str)->len = strlen(RSTRING(str)->ptr);
6649      if (OBJ_TAINTED(self)) OBJ_TAINT(str);
6650  
6651      return str;
6652  }
6653  
6654  static VALUE
6655  proc_to_proc(proc)
6656      VALUE proc;
6657  {
6658      return proc;
6659  }
6660  
6661  static VALUE
6662  proc_binding(proc)
6663      VALUE proc;
6664  {
6665      struct BLOCK *orig, *data;
6666      VALUE bind;
6667  
6668      Data_Get_Struct(proc, struct BLOCK, orig);
6669      bind = Data_Make_Struct(rb_cBinding,struct BLOCK,blk_mark,blk_free,data);
6670      MEMCPY(data, orig, struct BLOCK, 1);
6671      frame_dup(&data->frame);
6672  
6673      if (data->iter) {
6674          blk_copy_prev(data);
6675      }
6676      else {
6677          data->prev = 0;
6678      }
6679  
6680      return bind;
6681  }
6682  
6683  static VALUE
6684  block_pass(self, node)
6685      VALUE self;
6686      NODE *node;
6687  {
6688      VALUE block = rb_eval(self, node->nd_body); /* OK */
6689      VALUE b;
6690      struct BLOCK * volatile old_block;
6691      struct BLOCK _block;
6692      struct BLOCK *data;
6693      volatile VALUE result = Qnil;
6694      int state;
6695      volatile int orphan;
6696      volatile int safe = ruby_safe_level;
6697  
6698      if (NIL_P(block)) {
6699          PUSH_ITER(ITER_NOT);
6700          result = rb_eval(self, node->nd_iter);
6701          POP_ITER();
6702          return result;
6703      }
6704      if (!rb_obj_is_proc(block)) {
6705          b = rb_check_convert_type(block, T_DATA, "Proc", "to_proc");
6706          if (!rb_obj_is_proc(b)) {
6707              rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc)",
6708                       rb_class2name(CLASS_OF(block)));
6709          }
6710          block = b;
6711      }
6712  
6713      if (ruby_safe_level >= 1 && OBJ_TAINTED(block)) {
6714          if (ruby_safe_level > proc_get_safe_level(block)) {
6715              rb_raise(rb_eSecurityError, "Insecure: tainted block value");
6716          }
6717      }
6718  
6719      Data_Get_Struct(block, struct BLOCK, data);
6720      orphan = blk_orphan(data);
6721  
6722    retry:
6723      /* PUSH BLOCK from data */
6724      old_block = ruby_block;
6725      _block = *data;
6726      ruby_block = &_block;
6727      PUSH_ITER(ITER_PRE);
6728      ruby_frame->iter = ITER_PRE;
6729  
6730      PUSH_TAG(PROT_NONE);
6731      state = EXEC_TAG();
6732      if (state == 0) {
6733          proc_set_safe_level(block);
6734          if (safe > ruby_safe_level)
6735              ruby_safe_level = safe;
6736          result = rb_eval(self, node->nd_iter);
6737      }
6738      POP_TAG();
6739      POP_ITER();
6740      if (_block.tag->dst == state) {
6741          if (orphan) {
6742              state &= TAG_MASK;
6743          }
6744          else {
6745              struct BLOCK *ptr = old_block;
6746  
6747              while (ptr) {
6748                  if (ptr->scope == _block.scope) {
6749                      ptr->tag->dst = state;
6750                      break;
6751                  }
6752                  ptr = ptr->prev;
6753              }
6754              if (!ptr) {
6755                  state &= TAG_MASK;
6756              }
6757          }
6758      }
6759      ruby_block = old_block;
6760      ruby_safe_level = safe;
6761  
6762      switch (state) {/* escape from orphan procedure */
6763        case 0:
6764          break;
6765        case TAG_BREAK:
6766          result = prot_tag->retval;
6767          break;
6768        case TAG_RETRY:
6769          goto retry;
6770        case TAG_RETURN:
6771          if (orphan) {
6772              localjump_error("return from proc-closure", prot_tag->retval);
6773          }
6774        default:
6775          JUMP_TAG(state);
6776      }
6777  
6778      return result;
6779  }
6780  
6781  struct METHOD {
6782      VALUE klass, rklass;
6783      VALUE recv;
6784      ID id, oid;
6785      NODE *body;
6786  };
6787  
6788  static void
6789  bm_mark(data)
6790      struct METHOD *data;
6791  {
6792      rb_gc_mark(data->rklass);
6793      rb_gc_mark(data->klass);
6794      rb_gc_mark(data->recv);
6795      rb_gc_mark((VALUE)data->body);
6796  }
6797  
6798  static VALUE
6799  mnew(klass, obj, id, mklass)
6800      VALUE klass, obj, mklass;
6801      ID id;
6802  {
6803      VALUE method;
6804      NODE *body;
6805      int noex;
6806      struct METHOD *data;
6807      VALUE rklass = klass;
6808      ID oid = id;
6809  
6810    again:
6811      if ((body = rb_get_method_body(&klass, &id, &noex)) == 0) {
6812          print_undef(rklass, oid);
6813      }
6814  
6815      if (nd_type(body) == NODE_ZSUPER) {
6816          klass = RCLASS(klass)->super;
6817          goto again;
6818      }
6819  
6820      method = Data_Make_Struct(mklass, struct METHOD, bm_mark, free, data);
6821      data->klass = klass;
6822      data->recv = obj;
6823      data->id = id;
6824      data->body = body;
6825      data->rklass = rklass;
6826      data->oid = oid;
6827      OBJ_INFECT(method, klass);
6828  
6829      return method;
6830  }
6831  
6832  static VALUE
6833  method_eq(method, other)
6834      VALUE method, other;
6835  {
6836      struct METHOD *m1, *m2;
6837  
6838      if (TYPE(other) != T_DATA || RDATA(other)->dmark != (RUBY_DATA_FUNC)bm_mark)
6839          return Qfalse;
6840      if (CLASS_OF(method) != CLASS_OF(other))
6841          return Qfalse;
6842  
6843      Data_Get_Struct(method, struct METHOD, m1);
6844      Data_Get_Struct(other, struct METHOD, m2);
6845  
6846      if (m1->klass != m2->klass || m1->rklass != m2->rklass ||
6847          m1->recv != m2->recv || m1->body != m2->body)
6848          return Qfalse;
6849  
6850      return Qtrue;
6851  }
6852  
6853  static VALUE
6854  method_unbind(obj)
6855      VALUE obj;
6856  {
6857      VALUE method;
6858      struct METHOD *orig, *data;
6859  
6860      Data_Get_Struct(obj, struct METHOD, orig);
6861      method = Data_Make_Struct(rb_cUnboundMethod, struct METHOD, bm_mark, free, data);
6862      data->klass = orig->klass;
6863      data->recv = Qundef;
6864      data->id = orig->id;
6865      data->body = orig->body;
6866      data->rklass = orig->rklass;
6867      data->oid = orig->oid;
6868      OBJ_INFECT(method, obj);
6869  
6870      return method;
6871  }
6872  
6873  static VALUE
6874  umethod_unbind(obj)
6875      VALUE obj;
6876  {
6877      return obj;
6878  }
6879  
6880  static VALUE
6881  rb_obj_method(obj, vid)
6882      VALUE obj;
6883      VALUE vid;
6884  {
6885      return mnew(CLASS_OF(obj), obj, rb_to_id(vid), rb_cMethod);
6886  }
6887  
6888  static VALUE
6889  rb_mod_method(mod, vid)
6890      VALUE mod;
6891      VALUE vid;
6892  {
6893      return mnew(mod, Qundef, rb_to_id(vid), rb_cUnboundMethod);
6894  }
6895  
6896  static VALUE
6897  method_clone(self)
6898      VALUE self;
6899  {
6900      VALUE clone;
6901      struct METHOD *orig, *data;
6902  
6903      Data_Get_Struct(self, struct METHOD, orig);
6904      clone = Data_Make_Struct(CLASS_OF(self),struct METHOD, bm_mark, free, data);
6905      CLONESETUP(clone, self);
6906      *data = *orig;
6907  
6908      return clone;
6909  }
6910  
6911  static VALUE
6912  method_call(argc, argv, method)
6913      int argc;
6914      VALUE *argv;
6915      VALUE method;
6916  {
6917      VALUE result;
6918      struct METHOD *data;
6919      int state;
6920      volatile int safe = ruby_safe_level;
6921  
6922      Data_Get_Struct(method, struct METHOD, data);
6923      if (data->recv == Qundef) {
6924          rb_raise(rb_eTypeError, "you cannot call unbound method; bind first");
6925      }
6926      PUSH_ITER(rb_block_given_p()?ITER_PRE:ITER_NOT);
6927      PUSH_TAG(PROT_NONE);
6928      if (OBJ_TAINTED(method) && ruby_safe_level < 4) {
6929          ruby_safe_level = 4;
6930      }
6931      if ((state = EXEC_TAG()) == 0) {
6932          result = rb_call0(data->klass,data->recv,data->id,data->oid,argc,argv,data->body,0);
6933      }
6934      POP_TAG();
6935      POP_ITER();
6936      ruby_safe_level = safe;
6937      if (state) JUMP_TAG(state);
6938      return result;
6939  }
6940  
6941  static VALUE
6942  umethod_bind(method, recv)
6943      VALUE method, recv;
6944  {
6945      struct METHOD *data, *bound;
6946  
6947      Data_Get_Struct(method, struct METHOD, data);
6948      if (data->rklass != CLASS_OF(recv)) {
6949          if (FL_TEST(data->rklass, FL_SINGLETON)) {
6950              rb_raise(rb_eTypeError, "singleton method called for a different object");
6951          }
6952          if (FL_TEST(CLASS_OF(recv), FL_SINGLETON) &&
6953              st_lookup(RCLASS(CLASS_OF(recv))->m_tbl, data->oid, 0)) {
6954              rb_raise(rb_eTypeError, "method `%s' overridden", rb_id2name(data->oid));
6955          }
6956          if (!((TYPE(data->rklass) == T_MODULE) ?
6957                rb_obj_is_kind_of(recv, data->rklass) :
6958                rb_obj_is_instance_of(recv, data->rklass))) {
6959              rb_raise(rb_eTypeError, "bind argument must be an instance of %s",
6960                       rb_class2name(data->rklass));
6961          }
6962      }
6963  
6964      method = Data_Make_Struct(rb_cMethod,struct METHOD,bm_mark,free,bound);
6965      *bound = *data;
6966      bound->recv = recv;
6967      bound->rklass = CLASS_OF(recv);
6968  
6969      return method;
6970  }
6971  
6972  static VALUE
6973  method_arity(method)
6974      VALUE method;
6975  {
6976      struct METHOD *data;
6977      NODE *body;
6978      int n;
6979  
6980      Data_Get_Struct(method, struct METHOD, data);
6981  
6982      body = data->body;
6983      switch (nd_type(body)) {
6984        case NODE_CFUNC:
6985          if (body->nd_argc < 0) return INT2FIX(-1);
6986          return INT2FIX(body->nd_argc);
6987        case NODE_ZSUPER:
6988          return INT2FIX(-1);
6989        case NODE_ATTRSET:
6990          return INT2FIX(1);
6991        case NODE_IVAR:
6992          return INT2FIX(0);
6993        default:
6994          body = body->nd_next;   /* skip NODE_SCOPE */
6995          if (nd_type(body) == NODE_BLOCK)
6996              body = body->nd_head;
6997          if (!body) return INT2FIX(0);
6998          n = body->nd_cnt;
6999          if (body->nd_opt || body->nd_rest != -1)
7000              n = -n-1;
7001          return INT2FIX(n);
7002      }
7003  }
7004  
7005  static VALUE
7006  method_inspect(method)
7007      VALUE method;
7008  {
7009      struct METHOD *data;
7010      VALUE str;
7011      const char *s;
7012      char *sharp = "#";
7013  
7014      Data_Get_Struct(method, struct METHOD, data);
7015      str = rb_str_buf_new2("#<");
7016      s = rb_class2name(CLASS_OF(method));
7017      rb_str_buf_cat2(str, s);
7018      rb_str_buf_cat2(str, ": ");
7019  
7020      if (FL_TEST(data->klass, FL_SINGLETON)) {
7021          VALUE v = rb_iv_get(data->klass, "__attached__");
7022  
7023          if (data->recv == Qundef) {
7024              rb_str_buf_append(str, rb_inspect(data->klass));
7025          }
7026          else if (data->recv == v) {
7027              rb_str_buf_append(str, rb_inspect(v));
7028              sharp = ".";
7029          }
7030          else {
7031              rb_str_buf_append(str, rb_inspect(data->recv));
7032              rb_str_buf_cat2(str, "(");
7033              rb_str_buf_append(str, rb_inspect(v));
7034              rb_str_buf_cat2(str, ")");
7035              sharp = ".";
7036          }
7037      }
7038      else {
7039          rb_str_buf_cat2(str, rb_class2name(data->rklass));
7040          if (data->rklass != data->klass) {
7041              rb_str_buf_cat2(str, "(");
7042              rb_str_buf_cat2(str, rb_class2name(data->klass));
7043              rb_str_buf_cat2(str, ")");
7044          }
7045      }
7046      rb_str_buf_cat2(str, sharp);
7047      rb_str_buf_cat2(str, rb_id2name(data->oid));
7048      rb_str_buf_cat2(str, ">");
7049  
7050      return str;
7051  }
7052  
7053  static VALUE
7054  mproc()
7055  {
7056      VALUE proc;
7057  
7058      /* emulate ruby's method call */
7059      PUSH_ITER(ITER_CUR);
7060      PUSH_FRAME();
7061      proc = rb_f_lambda();
7062      POP_FRAME();
7063      POP_ITER();
7064  
7065      return proc;
7066  }
7067  
7068  static VALUE
7069  bmcall(args, method)
7070      VALUE args, method;
7071  {
7072      args = svalue_to_avalue(args);
7073      return method_call(RARRAY(args)->len, RARRAY(args)->ptr, method);
7074  }
7075  
7076  static VALUE
7077  umcall(args, method)
7078      VALUE args, method;
7079  {
7080      return method_call(0, 0, method);
7081  }
7082  
7083  VALUE
7084  rb_proc_new(func, val)
7085      VALUE (*func)(ANYARGS);     /* VALUE yieldarg[, VALUE procarg] */
7086      VALUE val;
7087  {
7088      return rb_iterate((VALUE(*)_((VALUE)))mproc, 0, func, val);
7089  }
7090  
7091  static VALUE
7092  method_proc(method)
7093      VALUE method;
7094  {
7095      return rb_iterate((VALUE(*)_((VALUE)))mproc, 0, bmcall, method);
7096  }
7097  
7098  static VALUE
7099  umethod_proc(method)
7100      VALUE method;
7101  {
7102      return rb_iterate((VALUE(*)_((VALUE)))mproc, 0, umcall, method);
7103  }
7104  
7105  static VALUE
7106  rb_mod_define_method(argc, argv, mod)
7107      int argc;
7108      VALUE *argv;
7109      VALUE mod;
7110  {
7111      ID id;
7112      VALUE body;
7113      NODE *node;
7114      int noex;
7115  
7116      if (argc == 1) {
7117          id = rb_to_id(argv[0]);
7118          body = rb_f_lambda();
7119      }
7120      else if (argc == 2) {
7121          id = rb_to_id(argv[0]);
7122          body = argv[1];
7123          if (!rb_obj_is_kind_of(body, rb_cMethod) && !rb_obj_is_proc(body)) {
7124              rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc/Method)",
7125                       rb_class2name(CLASS_OF(body)));
7126          }
7127      }
7128      else {
7129          rb_raise(rb_eArgError, "wrong number of arguments(%d for 1)", argc);
7130      }
7131      if (RDATA(body)->dmark == (RUBY_DATA_FUNC)bm_mark) {
7132          node = NEW_DMETHOD(method_unbind(body));
7133      }
7134      else if (RDATA(body)->dmark == (RUBY_DATA_FUNC)blk_mark) {
7135          struct BLOCK *block;
7136  
7137          body = bind_clone(body);
7138          Data_Get_Struct(body, struct BLOCK, block);
7139          block->frame.last_func = id;
7140          block->frame.orig_func = id;
7141          block->frame.last_class = mod;
7142          node = NEW_BMETHOD(body);
7143      }
7144      else {
7145          /* type error */
7146          rb_raise(rb_eTypeError, "wrong argument type (expected Proc/Method)");
7147      }
7148  
7149      if (SCOPE_TEST(SCOPE_PRIVATE)) {
7150          noex = NOEX_PRIVATE;
7151      }
7152      else if (SCOPE_TEST(SCOPE_PROTECTED)) {
7153          noex = NOEX_PROTECTED;
7154      }
7155      else {
7156          noex = NOEX_PUBLIC;
7157      }
7158      rb_add_method(mod, id, node, noex);
7159      if (scope_vmode == SCOPE_MODFUNC) {
7160          rb_add_method(rb_singleton_class(mod), id, node, NOEX_PUBLIC);
7161          rb_funcall(mod, singleton_added, 1, ID2SYM(id));
7162      }
7163      if (FL_TEST(mod, FL_SINGLETON)) {
7164          rb_funcall(rb_iv_get(mod, "__attached__"), singleton_added, 1, ID2SYM(id));
7165      }
7166      else {
7167          rb_funcall(mod, added, 1, ID2SYM(id));
7168      }
7169      return body;
7170  }
7171  
7172  void
7173  Init_Proc()
7174  {
7175      rb_eLocalJumpError = rb_define_class("LocalJumpError", rb_eStandardError);
7176      rb_define_method(rb_eLocalJumpError, "exitstatus", localjump_exitstatus, 0);
7177  
7178      rb_eSysStackError = rb_define_class("SystemStackError", rb_eStandardError);
7179  
7180      rb_cProc = rb_define_class("Proc", rb_cObject);
7181      rb_undef_method(CLASS_OF(rb_cProc), "allocate");
7182      rb_define_singleton_method(rb_cProc, "new", proc_s_new, -1);
7183  
7184      rb_define_method(rb_cProc, "call", proc_call, -2);
7185      rb_define_method(rb_cProc, "yield", proc_yield, -2);
7186      rb_define_method(rb_cProc, "arity", proc_arity, 0);
7187      rb_define_method(rb_cProc, "[]", proc_call, -2);
7188      rb_define_method(rb_cProc, "==", proc_eq, 1);
7189      rb_define_method(rb_cProc, "to_s", proc_to_s, 0);
7190      rb_define_method(rb_cProc, "to_proc", proc_to_proc, 0);
7191      rb_define_method(rb_cProc, "binding", proc_binding, 0);
7192      rb_define_global_function("proc", rb_f_lambda, 0);
7193      rb_define_global_function("lambda", rb_f_lambda, 0);
7194      rb_define_global_function("binding", rb_f_binding, 0);
7195      rb_cBinding = rb_define_class("Binding", rb_cObject);
7196      rb_undef_method(CLASS_OF(rb_cBinding), "allocate");
7197      rb_undef_method(CLASS_OF(rb_cBinding), "new");
7198      rb_define_method(rb_cBinding, "clone", bind_clone, 0);
7199  
7200      rb_cMethod = rb_define_class("Method", rb_cObject);
7201      rb_undef_method(CLASS_OF(rb_cMethod), "allocate");
7202      rb_undef_method(CLASS_OF(rb_cMethod), "new");
7203      rb_define_method(rb_cMethod, "==", method_eq, 1);
7204      rb_define_method(rb_cMethod, "clone", method_clone, 0);
7205      rb_define_method(rb_cMethod, "call", method_call, -1);
7206      rb_define_method(rb_cMethod, "[]", method_call, -1);
7207      rb_define_method(rb_cMethod, "arity", method_arity, 0);
7208      rb_define_method(rb_cMethod, "inspect", method_inspect, 0);
7209      rb_define_method(rb_cMethod, "to_s", method_inspect, 0);
7210      rb_define_method(rb_cMethod, "to_proc", method_proc, 0);
7211      rb_define_method(rb_cMethod, "unbind", method_unbind, 0);
7212      rb_define_method(rb_mKernel, "method", rb_obj_method, 1);
7213  
7214      rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cMethod);
7215      rb_define_method(rb_cUnboundMethod, "to_proc", umethod_proc, 0);
7216      rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
7217      rb_define_method(rb_cUnboundMethod, "unbind", umethod_unbind, 0);
7218      rb_define_method(rb_cModule, "instance_method", rb_mod_method, 1);
7219  }
7220  
7221  /* Windows SEH refers data on the stack. */
7222  #undef SAVE_WIN32_EXCEPTION_LIST
7223  #if defined _WIN32 || defined __CYGWIN__
7224  #if defined __CYGWIN__
7225  typedef unsigned long DWORD;
7226  #endif
7227  
7228  static inline DWORD
7229  win32_get_exception_list()
7230  {
7231      DWORD p;
7232  # if defined _MSC_VER
7233  #   ifdef _M_IX86
7234  #   define SAVE_WIN32_EXCEPTION_LIST
7235      __asm mov eax, fs:[0];
7236      __asm mov p, eax;
7237  #   endif
7238  # elif defined __GNUC__
7239  #   ifdef __i386__
7240  #   define SAVE_WIN32_EXCEPTION_LIST
7241      __asm__("movl %%fs:0,%0" : "=r"(p));
7242  #   endif
7243  # elif defined __BORLANDC__
7244  #   define SAVE_WIN32_EXCEPTION_LIST
7245      __emit__(0x64, 0xA1, 0, 0, 0, 0); /* mov eax, fs:[0] */
7246      p = _EAX;
7247  # endif
7248      return p;
7249  }
7250  
7251  static inline void
7252  win32_set_exception_list(p)
7253      DWORD p;
7254  {
7255  # if defined _MSC_VER
7256  #   ifdef _M_IX86
7257      __asm mov eax, p;
7258      __asm mov fs:[0], eax;
7259  #   endif
7260  # elif defined __GNUC__
7261  #   ifdef __i386__
7262      __asm__("movl %0,%%fs:0" :: "r"(p));
7263  #   endif
7264  # elif defined __BORLANDC__
7265      _EAX = p;
7266      __emit__(0x64, 0xA3, 0, 0, 0, 0); /* mov fs:[0], eax */
7267  # endif
7268  }
7269  
7270  #ifndef SAVE_WIN32_EXCEPTION_LIST
7271  # error unsupported platform
7272  #endif
7273  #endif
7274  
7275  static VALUE rb_eThreadError;
7276  
7277  int rb_thread_pending = 0;
7278  
7279  VALUE rb_cThread;
7280  
7281  extern VALUE rb_last_status;
7282  
7283  enum thread_status {
7284      THREAD_TO_KILL,
7285      THREAD_RUNNABLE,
7286      THREAD_STOPPED,
7287      THREAD_KILLED
7288  };
7289  
7290  #define WAIT_FD         (1<<0)
7291  #define WAIT_SELECT     (1<<1)
7292  #define WAIT_TIME       (1<<2)
7293  #define WAIT_JOIN       (1<<3)
7294  #define WAIT_PID        (1<<4)
7295  
7296  /* +infty, for this purpose */
7297  #define DELAY_INFTY 1E30
7298  
7299  /* typedef struct thread * rb_thread_t; */
7300  
7301  struct thread {
7302      struct thread *next, *prev;
7303      jmp_buf context;
7304  #ifdef SAVE_WIN32_EXCEPTION_LIST
7305      DWORD win32_exception_list;
7306  #endif
7307  
7308      VALUE result;
7309  
7310      int   stk_len;
7311      int   stk_max;
7312      VALUE*stk_ptr;
7313      VALUE*stk_pos;
7314  
7315      struct FRAME *frame;
7316      struct SCOPE *scope;
7317      struct RVarmap *dyna_vars;
7318      struct BLOCK *block;
7319      struct iter *iter;
7320      struct tag *tag;
7321      VALUE klass;
7322      VALUE wrapper;
7323      NODE *cref;
7324  
7325      int flags;          /* misc. states (vmode/rb_trap_immediate/raised) */
7326  
7327      NODE *node;
7328  
7329      int tracing;
7330      VALUE errinfo;
7331      VALUE last_status;
7332      VALUE last_line;
7333      VALUE last_match;
7334  
7335      int safe;
7336  
7337      enum thread_status status;
7338      int wait_for;
7339      int fd;
7340      fd_set readfds;
7341      fd_set writefds;
7342      fd_set exceptfds;
7343      int select_value;
7344      double delay;
7345      rb_thread_t join;
7346  
7347      int abort;
7348      int priority;
7349      int gid;
7350  
7351      st_table *locals;
7352  
7353      VALUE thread;
7354  };
7355  
7356  #define THREAD_RAISED 0x200      /* temporary flag */
7357  #define THREAD_TERMINATING 0x400 /* persistent flag */
7358  #define THREAD_FLAGS_MASK  0x400 /* mask for persistent flags */
7359  
7360  #define FOREACH_THREAD_FROM(f,x) x = f; do { x = x->next;
7361  #define END_FOREACH_FROM(f,x) } while (x != f)
7362  
7363  #define FOREACH_THREAD(x) FOREACH_THREAD_FROM(curr_thread,x)
7364  #define END_FOREACH(x)    END_FOREACH_FROM(curr_thread,x)
7365  
7366  static const char *
7367  thread_status_name(status)
7368      enum thread_status status;
7369  {
7370      switch (status) {
7371        case THREAD_RUNNABLE:
7372          return "run";
7373        case THREAD_STOPPED:
7374          return "sleep";
7375        case THREAD_TO_KILL:
7376          return "aborting";
7377        case THREAD_KILLED:
7378          return "dead";
7379        default:
7380          return "unknown";
7381      }
7382  }
7383  
7384  /* $SAFE accessor */
7385  void
7386  rb_set_safe_level(level)
7387      int level;
7388  {
7389      if (level > ruby_safe_level) {
7390          ruby_safe_level = level;
7391          curr_thread->safe = level;
7392      }
7393  }
7394  
7395  static VALUE
7396  safe_getter()
7397  {
7398      return INT2NUM(ruby_safe_level);
7399  }
7400  
7401  static void
7402  safe_setter(val)
7403      VALUE val;
7404  {
7405      int level = NUM2INT(val);
7406  
7407      if (level < ruby_safe_level) {
7408          rb_raise(rb_eSecurityError, "tried to downgrade safe level from %d to %d",
7409                   ruby_safe_level, level);
7410      }
7411      ruby_safe_level = level;
7412      curr_thread->safe = level;
7413  }
7414  
7415  /* Return the current time as a floating-point number */
7416  static double
7417  timeofday()
7418  {
7419      struct timeval tv;
7420      gettimeofday(&tv, NULL);
7421      return (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
7422  }
7423  
7424  #define STACK(addr) (th->stk_pos<(VALUE*)(addr) && (VALUE*)(addr)<th->stk_pos+th->stk_len)
7425  #define ADJ(addr) (void*)(STACK(addr)?(((VALUE*)(addr)-th->stk_pos)+th->stk_ptr):(VALUE*)(addr))
7426  
7427  static void
7428  thread_mark(th)
7429      rb_thread_t th;
7430  {
7431      struct FRAME *frame;
7432      struct BLOCK *block;
7433  
7434      rb_gc_mark(th->result);
7435      rb_gc_mark(th->thread);
7436      if (th->join) rb_gc_mark(th->join->thread);
7437  
7438      rb_gc_mark(th->klass);
7439      rb_gc_mark(th->wrapper);
7440      rb_gc_mark((VALUE)th->cref);
7441  
7442      rb_gc_mark((VALUE)th->scope);
7443      rb_gc_mark((VALUE)th->dyna_vars);
7444      rb_gc_mark(th->errinfo);
7445      rb_gc_mark(th->last_line);
7446      rb_gc_mark(th->last_match);
7447      rb_mark_tbl(th->locals);
7448  
7449      /* mark data in copied stack */
7450      if (th == curr_thread) return;
7451      if (th->status == THREAD_KILLED) return;
7452      if (th->stk_len == 0) return;  /* stack not active, no need to mark. */
7453      if (th->stk_ptr) {
7454          rb_gc_mark_locations(th->stk_ptr, th->stk_ptr+th->stk_len);
7455  #if defined(THINK_C) || defined(__human68k__)
7456          rb_gc_mark_locations(th->stk_ptr+2, th->stk_ptr+th->stk_len+2);
7457  #endif
7458      }
7459      frame = th->frame;
7460      while (frame && frame != top_frame) {
7461          frame = ADJ(frame);
7462          rb_gc_mark_frame(frame);
7463          if (frame->tmp) {
7464              struct FRAME *tmp = frame->tmp;
7465  
7466              while (tmp && tmp != top_frame) {
7467                  tmp = ADJ(tmp);
7468                  rb_gc_mark_frame(tmp);
7469                  tmp = tmp->prev;
7470              }
7471          }
7472          frame = frame->prev;
7473      }
7474      block = th->block;
7475      while (block) {
7476          block = ADJ(block);
7477          rb_gc_mark_frame(&block->frame);
7478          block = block->prev;
7479      }
7480  }
7481  
7482  void
7483  rb_gc_mark_threads()
7484  {
7485      rb_thread_t th;
7486  
7487      /* static global mark */
7488      rb_gc_mark((VALUE)ruby_cref);
7489  
7490      if (!curr_thread) return;
7491      FOREACH_THREAD(th) {
7492          rb_gc_mark(th->thread);
7493      } END_FOREACH(th);
7494  }
7495  
7496  static void
7497  thread_free(th)
7498      rb_thread_t th;
7499  {
7500      if (th->stk_ptr) free(th->stk_ptr);
7501      th->stk_ptr = 0;
7502      if (th->locals) st_free_table(th->locals);
7503      if (th->status != THREAD_KILLED) {
7504          if (th->prev) th->prev->next = th->next;
7505          if (th->next) th->next->prev = th->prev;
7506      }
7507      if (th != main_thread) free(th);
7508  }
7509  
7510  static rb_thread_t
7511  rb_thread_check(data)
7512      VALUE data;
7513  {
7514      if (TYPE(data) != T_DATA || RDATA(data)->dmark != (RUBY_DATA_FUNC)thread_mark) {
7515          rb_raise(rb_eTypeError, "wrong argument type %s (expected Thread)",
7516                   rb_class2name(CLASS_OF(data)));
7517      }
7518      return (rb_thread_t)RDATA(data)->data;
7519  }
7520  
7521  static VALUE rb_thread_raise _((int, VALUE*, rb_thread_t));
7522  
7523  static int   th_raise_argc;
7524  static VALUE th_raise_argv[2];
7525  static NODE *th_raise_node;
7526  static VALUE th_cmd;
7527  static int   th_sig;
7528  static char *th_signm;
7529  
7530  #define RESTORE_NORMAL          1
7531  #define RESTORE_FATAL           2
7532  #define RESTORE_INTERRUPT       3
7533  #define RESTORE_TRAP            4
7534  #define RESTORE_RAISE           5
7535  #define RESTORE_SIGNAL          6
7536  
7537  extern VALUE *rb_gc_stack_start;
7538  
7539  static void
7540  rb_thread_save_context(th)
7541      rb_thread_t th;
7542  {
7543      VALUE *pos;
7544      int len;
7545      static VALUE tval;
7546  
7547      len = ruby_stack_length(&pos);
7548      th->stk_len = 0;
7549      th->stk_pos = (rb_gc_stack_start<pos)?rb_gc_stack_start
7550                                           :rb_gc_stack_start - len;
7551      if (len > th->stk_max) {
7552          REALLOC_N(th->stk_ptr, VALUE, len);
7553          th->stk_max = len;
7554      }
7555      th->stk_len = len;
7556      FLUSH_REGISTER_WINDOWS; 
7557      MEMCPY(th->stk_ptr, th->stk_pos, VALUE, th->stk_len);
7558  #ifdef SAVE_WIN32_EXCEPTION_LIST
7559      th->win32_exception_list = win32_get_exception_list();
7560  #endif
7561  
7562      th->frame = ruby_frame;
7563      th->scope = ruby_scope;
7564      th->klass = ruby_class;
7565      th->wrapper = ruby_wrapper;
7566      th->cref = ruby_cref;
7567      th->dyna_vars = ruby_dyna_vars;
7568      th->block = ruby_block;
7569      th->flags &= THREAD_FLAGS_MASK;
7570      th->flags |= (rb_trap_immediate<<8) | scope_vmode;
7571      th->iter = ruby_iter;
7572      th->tag = prot_tag;
7573      th->tracing = tracing;
7574      th->errinfo = ruby_errinfo;
7575      th->last_status = rb_last_status;
7576      tval = rb_lastline_get();
7577      rb_lastline_set(th->last_line);
7578      th->last_line = tval;
7579      tval = rb_backref_get();
7580      rb_backref_set(th->last_match);
7581      th->last_match = tval;
7582      th->safe = ruby_safe_level;
7583  
7584      th->node = ruby_current_node;
7585  }
7586  
7587  static int
7588  thread_switch(n)
7589      int n;
7590  {
7591      switch (n) {
7592        case 0:
7593          return 0;
7594        case RESTORE_FATAL:
7595          JUMP_TAG(TAG_FATAL);
7596          break;
7597        case RESTORE_INTERRUPT:
7598          rb_interrupt();
7599          break;
7600        case RESTORE_TRAP:
7601          rb_trap_eval(th_cmd, th_sig);
7602          errno = EINTR;
7603          break;
7604        case RESTORE_RAISE:
7605          ruby_frame->last_func = 0;
7606          ruby_current_node = th_raise_node;
7607          rb_f_raise(th_raise_argc, th_raise_argv);
7608          break;
7609        case RESTORE_SIGNAL:
7610          rb_raise(rb_eSignal, "SIG%s", th_signm);
7611          break;
7612        case RESTORE_NORMAL:
7613        default:
7614          break;
7615      }
7616      return 1;
7617  }
7618  
7619  #define THREAD_SAVE_CONTEXT(th) \
7620      (rb_thread_save_context(th),thread_switch(setjmp((th)->context)))
7621  
7622  static void rb_thread_restore_context _((rb_thread_t,int));
7623  
7624  static void
7625  stack_extend(th, exit)
7626      rb_thread_t th;
7627      int exit;
7628  {
7629      VALUE space[1024];
7630  
7631      memset(space, 0, 1);        /* prevent array from optimization */
7632      rb_thread_restore_context(th, exit);
7633  }
7634  
7635  static void
7636  rb_thread_restore_context(th, exit)
7637      rb_thread_t th;
7638      int exit;
7639  {
7640      VALUE v;
7641      static rb_thread_t tmp;
7642      static int ex;
7643      static VALUE tval;
7644  
7645      if (!th->stk_ptr) rb_bug("unsaved context");
7646  
7647      if (&v < rb_gc_stack_start) {
7648          /* Stack grows downward */
7649          if (&v > th->stk_pos) stack_extend(th, exit);
7650      }
7651      else {
7652          /* Stack grows upward */
7653          if (&v < th->stk_pos + th->stk_len) stack_extend(th, exit);
7654      }
7655  
7656      ruby_frame = th->frame;
7657      ruby_scope = th->scope;
7658      ruby_class = th->klass;
7659      ruby_wrapper = th->wrapper;
7660      ruby_cref = th->cref;
7661      ruby_dyna_vars = th->dyna_vars;
7662      ruby_block = th->block;
7663      scope_vmode = th->flags&SCOPE_MASK;
7664      rb_trap_immediate = (th->flags&0x100)?1:0;
7665      ruby_iter = th->iter;
7666      prot_tag = th->tag;
7667      tracing = th->tracing;
7668      ruby_errinfo = th->errinfo;
7669      rb_last_status = th->last_status;
7670      ruby_safe_level = th->safe;
7671  
7672      ruby_current_node = th->node;
7673  
7674  #ifdef SAVE_WIN32_EXCEPTION_LIST
7675      win32_set_exception_list(th->win32_exception_list);
7676  #endif
7677      tmp = th;
7678      ex = exit;
7679      FLUSH_REGISTER_WINDOWS;
7680      MEMCPY(tmp->stk_pos, tmp->stk_ptr, VALUE, tmp->stk_len);
7681  
7682      tval = rb_lastline_get();
7683      rb_lastline_set(tmp->last_line);
7684      tmp->last_line = tval;
7685      tval = rb_backref_get();
7686      rb_backref_set(tmp->last_match);
7687      tmp->last_match = tval;
7688  
7689      longjmp(tmp->context, ex);
7690  }
7691  
7692  static void
7693  rb_thread_ready(th)
7694      rb_thread_t th;
7695  {
7696      th->wait_for = 0;
7697      if (th->status != THREAD_TO_KILL) {
7698          th->status = THREAD_RUNNABLE;
7699      }
7700  }
7701  
7702  static void
7703  rb_thread_remove(th)
7704      rb_thread_t th;
7705  {
7706      if (th->status == THREAD_KILLED) return;
7707  
7708      rb_thread_ready(th);
7709      th->status = THREAD_KILLED;
7710      th->gid = 0;
7711      th->prev->next = th->next;
7712      th->next->prev = th->prev;
7713  }
7714  
7715  static int
7716  rb_thread_dead(th)
7717      rb_thread_t th;
7718  {
7719      return th->status == THREAD_KILLED;
7720  }
7721  
7722  void
7723  rb_thread_fd_close(fd)
7724      int fd;
7725  {
7726      rb_thread_t th;
7727  
7728      FOREACH_THREAD(th) {
7729          if ((th->wait_for & WAIT_FD) && fd == th->fd) {
7730              VALUE exc = rb_exc_new2(rb_eIOError, "stream closed");
7731              rb_thread_raise(1, &exc, th);
7732          }
7733      }
7734      END_FOREACH(th);
7735  }
7736  
7737  static void
7738  rb_thread_deadlock()
7739  {
7740      if (curr_thread == main_thread) {
7741          rb_raise(rb_eFatal, "Thread: deadlock");
7742      }
7743      curr_thread = main_thread;
7744      th_raise_argc = 1;
7745      th_raise_argv[0] = rb_exc_new2(rb_eFatal, "Thread: deadlock");
7746      th_raise_node = ruby_current_node;
7747      rb_thread_restore_context(main_thread, RESTORE_RAISE);
7748  }
7749  
7750  static void
7751  copy_fds(dst, src, max)
7752      fd_set *dst, *src;
7753      int max;
7754  {
7755      int n = 0;
7756      int i;
7757  
7758      for (i=0; i<=max; i++) {
7759          if (FD_ISSET(i, src)) {
7760              n = i;
7761              FD_SET(i, dst);
7762          }
7763      }
7764  }
7765  
7766  static int
7767  match_fds(dst, src, max)
7768      fd_set *dst, *src;
7769      int max;
7770  {
7771      int i;
7772  
7773      for (i=0; i<=max; i++) {
7774          if (FD_ISSET(i, src) && FD_ISSET(i, dst)) {
7775              return Qtrue;
7776          }
7777      }
7778      return Qfalse;
7779  }
7780  
7781  static int
7782  intersect_fds(src, dst, max)
7783      fd_set *src, *dst;
7784      int max;
7785  {
7786      int i, n = 0;
7787  
7788      for (i=0; i<=max; i++) {
7789          if (FD_ISSET(i, dst)) {
7790              if (FD_ISSET(i, src)) {
7791                  /* Wake up only one thread per fd. */
7792                  FD_CLR(i, src);
7793                  ++n;
7794              }
7795              else {
7796                  FD_CLR(i, dst);
7797              }
7798          }
7799      }
7800      return n;
7801  }
7802  
7803  static int
7804  find_bad_fds(dst, src, max)
7805      fd_set *dst, *src;
7806      int max;
7807  {
7808      int i, test = Qfalse;
7809  
7810      for (i=0; i<=max; i++) {
7811          if (FD_ISSET(i, src) && !FD_ISSET(i, dst)) {
7812              FD_CLR(i, src);
7813              test = Qtrue;
7814          }
7815      }
7816      return test;
7817  }
7818  
7819  void
7820  rb_thread_schedule()
7821  {
7822      rb_thread_t next;           /* OK */
7823      rb_thread_t th;
7824      rb_thread_t curr;
7825      int found = 0;
7826  
7827      fd_set readfds;
7828      fd_set writefds;
7829      fd_set exceptfds;
7830      struct timeval delay_tv, *delay_ptr;
7831      double delay, now;  /* OK */
7832      int n, max;
7833      int need_select = 0;
7834      int select_timeout = 0;
7835  
7836      rb_thread_pending = 0;
7837      if (curr_thread == curr_thread->next
7838          && curr_thread->status == THREAD_RUNNABLE)
7839          return;
7840  
7841      next = 0;
7842      curr = curr_thread;         /* starting thread */
7843  
7844      while (curr->status == THREAD_KILLED) {
7845          curr = curr->prev;
7846      }
7847  
7848    again:
7849      max = -1;
7850      FD_ZERO(&readfds);
7851      FD_ZERO(&writefds);
7852      FD_ZERO(&exceptfds);
7853      delay = DELAY_INFTY;
7854      now = -1.0;
7855  
7856      FOREACH_THREAD_FROM(curr, th) {
7857          if (!found && th->status <= THREAD_RUNNABLE) {
7858              found = 1;
7859          }
7860          if (th->status != THREAD_STOPPED) continue;
7861          if (th->wait_for & WAIT_JOIN) {
7862              if (rb_thread_dead(th->join)) {
7863                  th->status = THREAD_RUNNABLE;
7864                  found = 1;
7865              }
7866          }
7867          if (th->wait_for & WAIT_FD) {
7868              FD_SET(th->fd, &readfds);
7869              if (max < th->fd) max = th->fd;
7870              need_select = 1;
7871          }
7872          if (th->wait_for & WAIT_SELECT) {
7873              copy_fds(&readfds, &th->readfds, th->fd);
7874              copy_fds(&writefds, &th->writefds, th->fd);
7875              copy_fds(&exceptfds, &th->exceptfds, th->fd);
7876              if (max < th->fd) max = th->fd;
7877              need_select = 1;
7878              if (th->wait_for & WAIT_TIME) {
7879                  select_timeout = 1;
7880              }
7881              th->select_value = 0;
7882          }
7883          if (th->wait_for & WAIT_TIME) {
7884              double th_delay;
7885  
7886              if (now < 0.0) now = timeofday();
7887              th_delay = th->delay - now;
7888              if (th_delay <= 0.0) {
7889                  th->status = THREAD_RUNNABLE;
7890                  found = 1;
7891              }
7892              else if (th_delay < delay) {
7893                  delay = th_delay;
7894                  need_select = 1;
7895              }
7896              else if (th->delay == DELAY_INFTY) {
7897                  need_select = 1;
7898              }
7899          }
7900      }
7901      END_FOREACH_FROM(curr, th);
7902      
7903      /* Do the select if needed */
7904      if (need_select) {
7905          /* Convert delay to a timeval */
7906          /* If a thread is runnable, just poll */
7907          if (found) {
7908              delay_tv.tv_sec = 0;
7909              delay_tv.tv_usec = 0;
7910              delay_ptr = &delay_tv;
7911          }
7912          else if (delay == DELAY_INFTY) {
7913              delay_ptr = 0;
7914          }
7915          else {
7916              delay_tv.tv_sec = delay;
7917              delay_tv.tv_usec = (delay - (double)delay_tv.tv_sec)*1e6;
7918              delay_ptr = &delay_tv;
7919          }
7920  
7921          n = select(max+1, &readfds, &writefds, &exceptfds, delay_ptr);
7922          if (n < 0) {
7923              int e = errno;
7924  
7925              if (rb_trap_pending) rb_trap_exec();
7926              if (e == EINTR) goto again;
7927  #ifdef ERESTART
7928              if (e == ERESTART) goto again;
7929  #endif
7930              FOREACH_THREAD_FROM(curr, th) {
7931                  if (th->wait_for & WAIT_SELECT) {
7932                      int v = 0;
7933  
7934                      v |= find_bad_fds(&readfds, &th->readfds, th->fd);
7935                      v |= find_bad_fds(&writefds, &th->writefds, th->fd);
7936                      v |= find_bad_fds(&exceptfds, &th->exceptfds, th->fd);
7937                      if (v) {
7938                          th->select_value = n;
7939                          n = max;
7940                      }
7941                  }
7942              }
7943              END_FOREACH_FROM(curr, th);
7944          }
7945          if (select_timeout && n == 0) {
7946              if (now < 0.0) now = timeofday();
7947              FOREACH_THREAD_FROM(curr, th) {
7948                  if (((th->wait_for&(WAIT_SELECT|WAIT_TIME)) == (WAIT_SELECT|WAIT_TIME)) &&
7949                      th->delay <= now) {
7950                      th->status = THREAD_RUNNABLE;
7951                      th->wait_for = 0;
7952                      th->select_value = 0;
7953                      found = 1;
7954                      intersect_fds(&readfds, &th->readfds, max);
7955                      intersect_fds(&writefds, &th->writefds, max);
7956                      intersect_fds(&exceptfds, &th->exceptfds, max);
7957                  }
7958              }
7959              END_FOREACH_FROM(curr, th);
7960          }
7961          if (n > 0) {
7962              now = -1.0;
7963              /* Some descriptors are ready. 
7964                 Make the corresponding threads runnable. */
7965              FOREACH_THREAD_FROM(curr, th) {
7966                  if ((th->wait_for&WAIT_FD) && FD_ISSET(th->fd, &readfds)) {
7967                      /* Wake up only one thread per fd. */
7968                      FD_CLR(th->fd, &readfds);
7969                      th->status = THREAD_RUNNABLE;
7970                      th->fd = 0;
7971                      th->wait_for = 0;
7972                      found = 1;
7973                  }
7974                  if ((th->wait_for&WAIT_SELECT) &&
7975                      (match_fds(&readfds, &th->readfds, max) ||
7976                       match_fds(&writefds, &th->writefds, max) ||
7977                       match_fds(&exceptfds, &th->exceptfds, max))) {
7978                      /* Wake up only one thread per fd. */
7979                      th->status = THREAD_RUNNABLE;
7980                      th->wait_for = 0;
7981                      n = intersect_fds(&readfds, &th->readfds, max) +
7982                          intersect_fds(&writefds, &th->writefds, max) +
7983                          intersect_fds(&exceptfds, &th->exceptfds, max);
7984                      th->select_value = n;
7985                      found = 1;
7986                  }
7987              }
7988              END_FOREACH_FROM(curr, th);
7989          }
7990          /* The delays for some of the threads should have expired.
7991             Go through the loop once more, to check the delays. */
7992          if (!found && delay != DELAY_INFTY)
7993              goto again;
7994      }
7995  
7996      FOREACH_THREAD_FROM(curr, th) {
7997          if (th->status == THREAD_TO_KILL) {
7998              next = th;
7999              break;
8000          }
8001          if (th->status == THREAD_RUNNABLE && th->stk_ptr) {
8002              if (!next || next->priority < th->priority) 
8003                 next = th;
8004          }
8005      }
8006      END_FOREACH_FROM(curr, th); 
8007  
8008      if (!next) {
8009          /* raise fatal error to main thread */
8010          curr_thread->node = ruby_current_node;
8011          FOREACH_THREAD_FROM(curr, th) {
8012              fprintf(stderr, "deadlock 0x%lx: %d:%d %s - %s:%d\n", 
8013                      th->thread, th->status,
8014                      th->wait_for, th==main_thread ? "(main)" : "",
8015                      th->node->nd_file, nd_line(th->node));
8016          }
8017          END_FOREACH_FROM(curr, th);
8018          next = main_thread;
8019          rb_thread_ready(next);
8020          next->status = THREAD_TO_KILL;
8021          rb_thread_save_context(curr_thread);
8022          rb_thread_deadlock();
8023      }
8024      next->wait_for = 0;
8025      if (next->status == THREAD_RUNNABLE && next == curr_thread) {
8026          return;
8027      }
8028  
8029      /* context switch */
8030      if (curr == curr_thread) {
8031          if (THREAD_SAVE_CONTEXT(curr)) {
8032              return;
8033          }
8034      }
8035  
8036      curr_thread = next;
8037      if (next->status == THREAD_TO_KILL) {
8038          if (!(next->flags & THREAD_TERMINATING)) {
8039              next->flags |= THREAD_TERMINATING;
8040              /* terminate; execute ensure-clause if any */
8041              rb_thread_restore_context(next, RESTORE_FATAL);
8042          }
8043      }
8044      rb_thread_restore_context(next, RESTORE_NORMAL);
8045  }
8046  
8047  void
8048  rb_thread_wait_fd(fd)
8049      int fd;
8050  {
8051      if (rb_thread_critical) return;
8052      if (curr_thread == curr_thread->next) return;
8053      if (curr_thread->status == THREAD_TO_KILL) return;
8054  
8055      curr_thread->status = THREAD_STOPPED;
8056      curr_thread->fd = fd;
8057      curr_thread->wait_for = WAIT_FD;
8058      rb_thread_schedule();
8059  }
8060  
8061  int
8062  rb_thread_fd_writable(fd)
8063      int fd;
8064  {
8065      if (rb_thread_critical) return Qtrue;
8066      if (curr_thread == curr_thread->next) return Qtrue;
8067      if (curr_thread->status == THREAD_TO_KILL) return Qtrue;
8068  
8069      curr_thread->status = THREAD_STOPPED;
8070      FD_ZERO(&curr_thread->readfds);
8071      FD_ZERO(&curr_thread->writefds);
8072      FD_SET(fd, &curr_thread->writefds);
8073      FD_ZERO(&curr_thread->exceptfds);
8074      curr_thread->fd = fd+1;
8075      curr_thread->wait_for = WAIT_SELECT;
8076      rb_thread_schedule();
8077      return Qfalse;
8078  }
8079  
8080  void
8081  rb_thread_wait_for(time)
8082      struct timeval time;
8083  {
8084      double date;
8085  
8086      if (rb_thread_critical ||
8087          curr_thread == curr_thread->next ||
8088          curr_thread->status == THREAD_TO_KILL) {
8089          int n;
8090  #ifndef linux
8091          double d, limit;
8092          limit = timeofday()+(double)time.tv_sec+(double)time.tv_usec*1e-6;
8093  #endif
8094          for (;;) {
8095              TRAP_BEG;
8096              n = select(0, 0, 0, 0, &time);
8097              TRAP_END;
8098              if (n == 0) return;
8099              if (n < 0) {
8100                  switch (errno) {
8101                    case EINTR:
8102  #ifdef ERESTART
8103                    case ERESTART:
8104  #endif
8105                      return;
8106                    default:
8107                      rb_sys_fail("sleep");
8108                  }
8109              }
8110  #ifndef linux
8111              d = limit - timeofday();
8112  
8113              time.tv_sec = (int)d;
8114              time.tv_usec = (int)((d - (int)d)*1e6);
8115              if (time.tv_usec < 0) {
8116                  time.tv_usec += (long)1e6;
8117                  time.tv_sec -= 1;
8118              }
8119              if (time.tv_sec < 0) return;
8120  #endif
8121          }
8122      }
8123  
8124      date = timeofday() + (double)time.tv_sec + (double)time.tv_usec*1e-6;
8125      curr_thread->status = THREAD_STOPPED;
8126      curr_thread->delay = date;
8127      curr_thread->wait_for = WAIT_TIME;
8128      rb_thread_schedule();
8129  }
8130  
8131  void rb_thread_sleep_forever _((void));
8132  
8133  int
8134  rb_thread_alone()
8135  {
8136      return curr_thread == curr_thread->next;
8137  }
8138  
8139  int
8140  rb_thread_select(max, read, write, except, timeout)
8141      int max;
8142      fd_set *read, *write, *except;
8143      struct timeval *timeout;
8144  {
8145      double limit;
8146      int n;
8147  
8148      if (!read && !write && !except) {
8149          if (!timeout) {
8150              rb_thread_sleep_forever();
8151              return 0;
8152          }
8153          rb_thread_wait_for(*timeout);
8154          return 0;
8155      }
8156  
8157      if (timeout) {
8158          limit = timeofday()+
8159              (double)timeout->tv_sec+(double)timeout->tv_usec*1e-6;
8160      }
8161  
8162      if (rb_thread_critical ||
8163          curr_thread == curr_thread->next ||
8164          curr_thread->status == THREAD_TO_KILL) {
8165  #ifndef linux
8166          struct timeval tv, *tvp = timeout;
8167  
8168          if (timeout) {
8169              tv = *timeout;
8170              tvp = &tv;
8171          }
8172  #else
8173          struct timeval *const tvp = timeout;
8174  #endif
8175          for (;;) {
8176              TRAP_BEG;
8177              n = select(max, read, write, except, tvp);
8178              TRAP_END;
8179              if (n < 0) {
8180                  switch (errno) {
8181                    case EINTR:
8182  #ifdef ERESTART
8183                    case ERESTART:
8184  #endif
8185  #ifndef linux
8186                      if (timeout) {
8187                          double d = limit - timeofday();
8188  
8189                          tv.tv_sec = (unsigned int)d;
8190                          tv.tv_usec = (long)((d-(double)tv.tv_sec)*1e6);
8191                          if (tv.tv_sec < 0)  tv.tv_sec = 0;
8192                          if (tv.tv_usec < 0) tv.tv_usec = 0;
8193                      }
8194  #endif
8195                      continue;
8196                    default:
8197                      break;
8198                  }
8199              }
8200              return n;
8201          }
8202      }
8203  
8204      curr_thread->status = THREAD_STOPPED;
8205      if (read) curr_thread->readfds = *read;
8206      else FD_ZERO(&curr_thread->readfds);
8207      if (write) curr_thread->writefds = *write;
8208      else FD_ZERO(&curr_thread->writefds);
8209      if (except) curr_thread->exceptfds = *except;
8210      else FD_ZERO(&curr_thread->exceptfds);
8211      curr_thread->fd = max;
8212      curr_thread->wait_for = WAIT_SELECT;
8213      if (timeout) {
8214          curr_thread->delay = timeofday() +
8215              (double)timeout->tv_sec + (double)timeout->tv_usec*1e-6;
8216          curr_thread->wait_for |= WAIT_TIME;
8217      }
8218      rb_thread_schedule();
8219      if (read) *read = curr_thread->readfds;
8220      if (write) *write = curr_thread->writefds;
8221      if (except) *except = curr_thread->exceptfds;
8222      return curr_thread->select_value;
8223  }
8224  
8225  static int rb_thread_join _((rb_thread_t, double));
8226  
8227  static int
8228  rb_thread_join(th, limit)
8229      rb_thread_t th;
8230      double limit;
8231  {
8232      enum thread_status last_status = THREAD_RUNNABLE;
8233  
8234      if (rb_thread_critical) rb_thread_deadlock();
8235      if (!rb_thread_dead(th)) {
8236          if (th == curr_thread)
8237              rb_raise(rb_eThreadError, "thread tried to join itself");
8238          if ((th->wait_for & WAIT_JOIN) && th->join == curr_thread)
8239              rb_raise(rb_eThreadError, "Thread#join: deadlock - mutual join");
8240          if (curr_thread->status == THREAD_TO_KILL)
8241              last_status = THREAD_TO_KILL;
8242          if (limit == 0) return Qfalse;
8243          curr_thread->status = THREAD_STOPPED;
8244          curr_thread->join = th;
8245          curr_thread->wait_for = WAIT_JOIN;
8246          curr_thread->delay = timeofday() + limit;
8247          if (limit < DELAY_INFTY) curr_thread->wait_for |= WAIT_TIME;
8248          rb_thread_schedule();
8249          curr_thread->status = last_status;
8250          if (!rb_thread_dead(th)) return Qfalse;
8251      }
8252  
8253      if (!NIL_P(th->errinfo) && (th->flags & THREAD_RAISED)) {
8254          VALUE oldbt = get_backtrace(th->errinfo);
8255          VALUE errat = make_backtrace();
8256  
8257          if (TYPE(oldbt) == T_ARRAY && RARRAY(oldbt)->len > 0) {
8258              rb_ary_unshift(errat, rb_ary_entry(oldbt, 0));
8259          }
8260          set_backtrace(th->errinfo, errat);
8261          rb_exc_raise(th->errinfo);
8262      }
8263  
8264      return Qtrue;
8265  }
8266  
8267  static VALUE
8268  rb_thread_join_m(argc, argv, thread)
8269      int argc;
8270      VALUE *argv;
8271      VALUE thread;
8272  {
8273      VALUE limit;
8274      double delay = DELAY_INFTY;
8275      rb_thread_t th = rb_thread_check(thread);
8276  
8277      rb_scan_args(argc, argv, "01", &limit);
8278      if (!NIL_P(limit)) delay = rb_num2dbl(limit);
8279      if (!rb_thread_join(th, delay))
8280          return Qnil;
8281      return thread;
8282  }
8283  
8284  VALUE
8285  rb_thread_current()
8286  {
8287      return curr_thread->thread;
8288  }
8289  
8290  VALUE
8291  rb_thread_main()
8292  {
8293      return main_thread->thread;
8294  }
8295  
8296  VALUE
8297  rb_thread_list()
8298  {
8299      rb_thread_t th;
8300      VALUE ary = rb_ary_new();
8301  
8302      FOREACH_THREAD(th) {
8303          switch (th->status) {
8304            case THREAD_RUNNABLE:
8305            case THREAD_STOPPED:
8306            case THREAD_TO_KILL:
8307              rb_ary_push(ary, th->thread);
8308            default:
8309              break;
8310          }
8311      }
8312      END_FOREACH(th);
8313  
8314      return ary;
8315  }
8316  
8317  VALUE
8318  rb_thread_wakeup(thread)
8319      VALUE thread;
8320  {
8321      rb_thread_t th = rb_thread_check(thread);
8322  
8323      if (th->status == THREAD_KILLED)
8324          rb_raise(rb_eThreadError, "killed thread");
8325      rb_thread_ready(th);
8326  
8327      return thread;
8328  }
8329  
8330  VALUE
8331  rb_thread_run(thread)
8332      VALUE thread;
8333  {
8334      rb_thread_wakeup(thread);
8335      if (!rb_thread_critical) rb_thread_schedule();
8336  
8337      return thread;
8338  }
8339  
8340  static VALUE
8341  rb_thread_kill(thread)
8342      VALUE thread;
8343  {
8344      rb_thread_t th = rb_thread_check(thread);
8345  
8346      if (th != curr_thread && th->safe < 4) {
8347          rb_secure(4);
8348      }
8349      if (th->status == THREAD_TO_KILL || th->status == THREAD_KILLED)
8350          return thread; 
8351      if (th == th->next || th == main_thread) rb_exit(0);
8352  
8353      rb_thread_ready(th);
8354      th->gid = 0;
8355      th->status = THREAD_TO_KILL;
8356      if (!rb_thread_critical) rb_thread_schedule();
8357      return thread;
8358  }
8359  
8360  static VALUE
8361  rb_thread_s_kill(obj, th)
8362      VALUE obj, th;
8363  {
8364      return rb_thread_kill(th);
8365  }
8366  
8367  static VALUE
8368  rb_thread_exit()
8369  {
8370      return rb_thread_kill(curr_thread->thread);
8371  }
8372  
8373  static VALUE
8374  rb_thread_pass()
8375  {
8376      rb_thread_schedule();
8377      return Qnil;
8378  }
8379  
8380  VALUE
8381  rb_thread_stop()
8382  {
8383      enum thread_status last_status = THREAD_RUNNABLE;
8384  
8385      rb_thread_critical = 0;
8386      if (curr_thread == curr_thread->next) {
8387          rb_raise(rb_eThreadError, "stopping only thread\n\tnote: use sleep to stop forever");
8388      }
8389      if (curr_thread->status == THREAD_TO_KILL)
8390          last_status = THREAD_TO_KILL;
8391      curr_thread->status = THREAD_STOPPED;
8392      rb_thread_schedule();
8393      curr_thread->status = last_status;
8394  
8395      return Qnil;
8396  }
8397  
8398  struct timeval rb_time_timeval();
8399  
8400  void
8401  rb_thread_polling()
8402  {
8403      if (curr_thread != curr_thread->next) {
8404          curr_thread->status = THREAD_STOPPED;
8405          curr_thread->delay = timeofday() + (double)0.06;
8406          curr_thread->wait_for = WAIT_TIME;
8407          rb_thread_schedule();
8408      }
8409  }
8410  
8411  void
8412  rb_thread_sleep(sec)
8413      int sec;
8414  {
8415      if (curr_thread == curr_thread->next) {
8416          TRAP_BEG;
8417          sleep(sec);
8418          TRAP_END;
8419          return;
8420      }
8421      rb_thread_wait_for(rb_time_timeval(INT2FIX(sec)));
8422  }
8423  
8424  #if !defined HAVE_PAUSE
8425  # if defined _WIN32 && !defined __CYGWIN__
8426  #  define pause() Sleep(INFINITE)
8427  # else
8428  #  define pause() sleep(0x7fffffff)
8429  # endif
8430  #endif
8431  
8432  void
8433  rb_thread_sleep_forever()
8434  {
8435      if (curr_thread == curr_thread->next ||
8436          curr_thread->status == THREAD_TO_KILL) {
8437          TRAP_BEG;
8438          pause();
8439          TRAP_END;
8440          return;
8441      }
8442  
8443      curr_thread->delay = DELAY_INFTY;
8444      curr_thread->wait_for = WAIT_TIME;
8445      curr_thread->status = THREAD_STOPPED;
8446      rb_thread_schedule();
8447  }
8448  
8449  static VALUE
8450  rb_thread_priority(thread)
8451      VALUE thread;
8452  {
8453      return INT2NUM(rb_thread_check(thread)->priority);
8454  }
8455  
8456  static VALUE
8457  rb_thread_priority_set(thread, prio)
8458      VALUE thread, prio;
8459  {
8460      rb_thread_t th;
8461  
8462      rb_secure(4);
8463      th = rb_thread_check(thread);
8464  
8465      th->priority = NUM2INT(prio);
8466      rb_thread_schedule();
8467      return prio;
8468  }
8469  
8470  static VALUE
8471  rb_thread_safe_level(thread)
8472      VALUE thread;
8473  {
8474      rb_thread_t th;
8475  
8476      th = rb_thread_check(thread);
8477      if (th == curr_thread) {
8478          return INT2NUM(ruby_safe_level);
8479      }
8480      return INT2NUM(th->safe);
8481  }
8482  
8483  static int thread_abort;
8484  
8485  static VALUE
8486  rb_thread_s_abort_exc()
8487  {
8488      return thread_abort?Qtrue:Qfalse;
8489  }
8490  
8491  static VALUE
8492  rb_thread_s_abort_exc_set(self, val)
8493      VALUE self, val;
8494  {
8495      rb_secure(4);
8496      thread_abort = RTEST(val);
8497      return val;
8498  }
8499  
8500  static VALUE
8501  rb_thread_abort_exc(thread)
8502      VALUE thread;
8503  {
8504      return rb_thread_check(thread)->abort?Qtrue:Qfalse;
8505  }
8506  
8507  static VALUE
8508  rb_thread_abort_exc_set(thread, val)
8509      VALUE thread, val;
8510  {
8511      rb_secure(4);
8512      rb_thread_check(thread)->abort = RTEST(val);
8513      return val;
8514  }
8515  
8516  #define THREAD_ALLOC(th) do {\
8517      th = ALLOC(struct thread);\
8518  \
8519      th->next = 0;\
8520      th->prev = 0;\
8521  \
8522      th->status = THREAD_RUNNABLE;\
8523      th->result = 0;\
8524      th->flags = 0;\
8525  \
8526      th->stk_ptr = 0;\
8527      th->stk_len = 0;\
8528      th->stk_max = 0;\
8529      th->wait_for = 0;\
8530      FD_ZERO(&th->readfds);\
8531      FD_ZERO(&th->writefds);\
8532      FD_ZERO(&th->exceptfds);\
8533      th->delay = 0.0;\
8534      th->join = 0;\
8535  \
8536      th->frame = 0;\
8537      th->scope = 0;\
8538      th->klass = 0;\
8539      th->wrapper = 0;\
8540      th->cref = ruby_cref;\
8541      th->dyna_vars = ruby_dyna_vars;\
8542      th->block = 0;\
8543      th->iter = 0;\
8544      th->tag = 0;\
8545      th->tracing = 0;\
8546      th->errinfo = Qnil;\
8547      th->last_status = 0;\
8548      th->last_line = 0;\
8549      th->last_match = Qnil;\
8550      th->abort = 0;\
8551      th->priority = 0;\
8552      th->gid = 1;\
8553      th->locals = 0;\
8554  } while (0)
8555  
8556  static rb_thread_t
8557  rb_thread_alloc(klass)
8558      VALUE klass;
8559  {
8560      rb_thread_t th;
8561      struct RVarmap *vars;
8562  
8563      THREAD_ALLOC(th);
8564      th->thread = Data_Wrap_Struct(klass, thread_mark, thread_free, th);
8565  
8566      for (vars = th->dyna_vars; vars; vars = vars->next) {
8567          if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
8568          FL_SET(vars, DVAR_DONT_RECYCLE);
8569      }
8570      return th;
8571  }
8572  
8573  #if defined(HAVE_SETITIMER)
8574  static void
8575  catch_timer(sig)
8576      int sig;
8577  {
8578  #if !defined(POSIX_SIGNAL) && !defined(BSD_SIGNAL)
8579      signal(sig, catch_timer);
8580  #endif
8581      if (!rb_thread_critical) {
8582          if (rb_trap_immediate) {
8583              rb_thread_schedule();
8584          }
8585          else rb_thread_pending = 1;
8586      }
8587  }
8588  #else
8589  int rb_thread_tick = THREAD_TICK;
8590  #endif
8591  
8592  #if defined(HAVE_SETITIMER)
8593  static int thread_init = 0;
8594  
8595  void
8596  rb_thread_start_timer()
8597  {
8598      struct itimerval tval;
8599  
8600      if (!thread_init) return;
8601      tval.it_interval.tv_sec = 0;
8602      tval.it_interval.tv_usec = 10000;
8603      tval.it_value = tval.it_interval;
8604      setitimer(ITIMER_VIRTUAL, &tval, NULL);
8605  }
8606  
8607  void
8608  rb_thread_stop_timer()
8609  {
8610      struct itimerval tval;
8611  
8612      if (!thread_init) return;
8613      tval.it_interval.tv_sec = 0;
8614      tval.it_interval.tv_usec = 0;
8615      tval.it_value = tval.it_interval;
8616      setitimer(ITIMER_VIRTUAL, &tval, NULL);
8617  }
8618  #endif
8619  
8620  static VALUE
8621  rb_thread_start_0(fn, arg, th_arg)
8622      VALUE (*fn)();
8623      void *arg;
8624      rb_thread_t th_arg;
8625  {
8626      volatile rb_thread_t th = th_arg;
8627      volatile VALUE thread = th->thread;
8628      struct BLOCK* saved_block = 0;
8629      enum thread_status status;
8630      int state;
8631  
8632  #if defined(HAVE_SETITIMER)
8633      if (!thread_init) {
8634  #ifdef POSIX_SIGNAL
8635          posix_signal(SIGVTALRM, catch_timer);
8636  #else
8637          signal(SIGVTALRM, catch_timer);
8638  #endif
8639  
8640          thread_init = 1;
8641          rb_thread_start_timer();
8642      }
8643  #endif
8644  
8645      if (THREAD_SAVE_CONTEXT(curr_thread)) {
8646          return thread;
8647      }
8648  
8649      if (ruby_block) {           /* should nail down higher blocks */
8650          struct BLOCK dummy;
8651  
8652          dummy.prev = ruby_block;
8653          blk_copy_prev(&dummy);
8654          saved_block = ruby_block = dummy.prev;
8655      }
8656      scope_dup(ruby_scope);
8657  
8658      if (!th->next) {
8659          /* merge in thread list */
8660          th->prev = curr_thread;
8661          curr_thread->next->prev = th;
8662          th->next = curr_thread->next;
8663          curr_thread->next = th;
8664          th->priority = curr_thread->priority;
8665          th->gid = curr_thread->gid;
8666      }
8667  
8668      PUSH_TAG(PROT_THREAD);
8669      if ((state = EXEC_TAG()) == 0) {
8670          if (THREAD_SAVE_CONTEXT(th) == 0) {
8671              curr_thread = th;
8672              th->result = (*fn)(arg, th);
8673          }
8674      }
8675      POP_TAG();
8676      status = th->status;
8677  
8678      if (th == main_thread) ruby_stop(state);
8679      rb_thread_remove(th);
8680  
8681      while (saved_block) {
8682          struct BLOCK *tmp = saved_block;
8683  
8684          if (tmp->frame.argc > 0)
8685              free(tmp->frame.argv);
8686          saved_block = tmp->prev;
8687          free(tmp);
8688      }
8689  
8690      if (state && status != THREAD_TO_KILL && !NIL_P(ruby_errinfo)) {
8691          th->flags |= THREAD_RAISED;
8692          if (state == TAG_FATAL) { 
8693              /* fatal error within this thread, need to stop whole script */
8694              main_thread->errinfo = ruby_errinfo;
8695              rb_thread_cleanup();
8696          }
8697          else if (rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) {
8698              if (th->safe >= 4) {
8699                  char buf[32];
8700  
8701                  sprintf(buf, "Insecure exit at level %d", th->safe);
8702                  th->errinfo = rb_exc_new2(rb_eSecurityError, buf);
8703              }
8704              else {
8705                  /* delegate exception to main_thread */
8706                  rb_thread_raise(1, &ruby_errinfo, main_thread);
8707              }
8708          }
8709          else if (th->safe < 4 && (thread_abort || th->abort || RTEST(ruby_debug))) {
8710              VALUE err = rb_exc_new(rb_eSystemExit, 0, 0);
8711              error_print();
8712              /* exit on main_thread */
8713              rb_thread_raise(1, &err, main_thread);
8714          }
8715          else {
8716              th->errinfo = ruby_errinfo;
8717          }
8718      }
8719      rb_thread_schedule();
8720      return 0;                   /* not reached */
8721  }
8722  
8723  VALUE
8724  rb_thread_create(fn, arg)
8725      VALUE (*fn)();
8726      void *arg;
8727  {
8728      return rb_thread_start_0(fn, arg, rb_thread_alloc(rb_cThread));
8729  }
8730  
8731  static VALUE
8732  rb_thread_yield(arg, th) 
8733      VALUE arg;
8734      rb_thread_t th;
8735  {
8736      const ID *tbl;
8737  
8738      scope_dup(ruby_block->scope);
8739  
8740      tbl = ruby_scope->local_tbl;
8741      if (tbl) {
8742          int n = *tbl++;
8743          for (tbl += 2, n -= 2; n > 0; --n) { /* skip first 2 ($_ and $~) */
8744              ID id = *tbl++;
8745              if (id != 0 && !rb_is_local_id(id))  /* push flip states */
8746                  rb_dvar_push(id, Qfalse);
8747          }
8748      }
8749      rb_dvar_push('_', Qnil);
8750      rb_dvar_push('~', Qnil);
8751      ruby_block->dyna_vars = ruby_dyna_vars;
8752  
8753      return rb_yield_0(mvalue_to_svalue(arg), 0, 0, Qtrue);
8754  }
8755  
8756  static VALUE
8757  rb_thread_s_new(argc, argv, klass)
8758      int argc;
8759      VALUE *argv;
8760      VALUE klass;
8761  {
8762      rb_thread_t th = rb_thread_alloc(klass);
8763      volatile VALUE *pos;
8764  
8765      pos = th->stk_pos;
8766      rb_obj_call_init(th->thread, argc, argv);
8767      if (th->stk_pos == 0) {
8768          rb_raise(rb_eThreadError, "uninitialized thread - check `%s#initialize'",
8769                   rb_class2name(klass));
8770      }
8771  
8772      return th->thread;
8773  }
8774  
8775  static VALUE
8776  rb_thread_initialize(thread, args)
8777      VALUE thread, args;
8778  {
8779      if (!rb_block_given_p()) {
8780          rb_raise(rb_eThreadError, "must be called with a block");
8781      }
8782      return rb_thread_start_0(rb_thread_yield, args, rb_thread_check(thread));
8783  }
8784  
8785  static VALUE
8786  rb_thread_start(klass, args)
8787      VALUE klass, args;
8788  {
8789      if (!rb_block_given_p()) {
8790          rb_raise(rb_eThreadError, "must be called with a block");
8791      }
8792      return rb_thread_start_0(rb_thread_yield, args, rb_thread_alloc(klass));
8793  }
8794  
8795  static VALUE
8796  rb_thread_value(thread)
8797      VALUE thread;
8798  {
8799      rb_thread_t th = rb_thread_check(thread);
8800  
8801      while (!rb_thread_join(th, DELAY_INFTY));
8802  
8803      return th->result;
8804  }
8805  
8806  static VALUE
8807  rb_thread_status(thread)
8808      VALUE thread;
8809  {
8810      rb_thread_t th = rb_thread_check(thread);
8811  
8812      if (rb_thread_dead(th)) {
8813          if (!NIL_P(th->errinfo) && (th->flags & THREAD_RAISED))
8814              return Qnil;
8815          return Qfalse;
8816      }
8817  
8818      return rb_str_new2(thread_status_name(th->status));
8819  }
8820  
8821  static VALUE
8822  rb_thread_alive_p(thread)
8823      VALUE thread;
8824  {
8825      rb_thread_t th = rb_thread_check(thread);
8826  
8827      if (rb_thread_dead(th)) return Qfalse;
8828      return Qtrue;
8829  }
8830  
8831  static VALUE
8832  rb_thread_stop_p(thread)
8833      VALUE thread;
8834  {
8835      rb_thread_t th = rb_thread_check(thread);
8836  
8837      if (rb_thread_dead(th)) return Qtrue;
8838      if (th->status == THREAD_STOPPED) return Qtrue;
8839      return Qfalse;
8840  }
8841  
8842  static void
8843  rb_thread_wait_other_threads()
8844  {
8845      rb_thread_t th;
8846      int found;
8847  
8848      /* wait other threads to terminate */
8849      while (curr_thread != curr_thread->next) {
8850          found = 0;
8851          FOREACH_THREAD(th) {
8852              if (th != curr_thread && th->status != THREAD_STOPPED) {
8853                  found = 1;
8854                  break;
8855              }
8856          }
8857          END_FOREACH(th);
8858          if (!found) return;
8859          rb_thread_schedule();
8860      }
8861  }
8862  
8863  static void
8864  rb_thread_cleanup()
8865  {
8866      rb_thread_t curr, th;
8867  
8868      curr = curr_thread;
8869      while (curr->status == THREAD_KILLED) {
8870          curr = curr->prev;
8871      }
8872  
8873      FOREACH_THREAD_FROM(curr, th) {
8874          if (th->status != THREAD_KILLED) {
8875              rb_thread_ready(th);
8876              th->gid = 0;
8877              th->priority = 0;
8878              if (th != main_thread) {
8879                  th->status = THREAD_TO_KILL;
8880                  RDATA(th->thread)->dfree = NULL;
8881              }
8882          }
8883      }
8884      END_FOREACH_FROM(curr, th);
8885  }
8886  
8887  int rb_thread_critical;
8888  
8889  static VALUE
8890  rb_thread_critical_get()
8891  {
8892      return rb_thread_critical?Qtrue:Qfalse;
8893  }
8894  
8895  static VALUE
8896  rb_thread_critical_set(obj, val)
8897      VALUE obj, val;
8898  {
8899      rb_thread_critical = RTEST(val);
8900      return val;
8901  }
8902  
8903  void
8904  rb_thread_interrupt()
8905  {
8906      rb_thread_critical = 0;
8907      rb_thread_ready(main_thread);
8908      if (curr_thread == main_thread) {
8909          rb_interrupt();
8910      }
8911      if (THREAD_SAVE_CONTEXT(curr_thread)) {
8912          return;
8913      }
8914      curr_thread = main_thread;
8915      rb_thread_restore_context(curr_thread, RESTORE_INTERRUPT);
8916  }
8917  
8918  void
8919  rb_thread_signal_raise(sig)
8920      char *sig;
8921  {
8922      if (sig == 0) return;       /* should not happen */
8923      rb_thread_critical = 0;
8924      if (curr_thread == main_thread) {
8925          rb_thread_ready(curr_thread);
8926          rb_raise(rb_eSignal, "SIG%s", sig);
8927      }
8928      rb_thread_ready(main_thread);
8929      if (THREAD_SAVE_CONTEXT(curr_thread)) {
8930          return;
8931      }
8932      th_signm = sig;
8933      curr_thread = main_thread;
8934      rb_thread_restore_context(curr_thread, RESTORE_SIGNAL);
8935  }
8936  
8937  void
8938  rb_thread_trap_eval(cmd, sig)
8939      VALUE cmd;
8940      int sig;
8941  {
8942  #if 0
8943      rb_thread_critical = 0;
8944      if (!rb_thread_dead(curr_thread)) {
8945          rb_thread_ready(curr_thread);
8946          rb_trap_eval(cmd, sig);
8947          return;
8948      }
8949      rb_thread_ready(main_thread);
8950      if (THREAD_SAVE_CONTEXT(curr_thread)) {
8951          return;
8952      }
8953      th_cmd = cmd;
8954      th_sig = sig;
8955      curr_thread = main_thread;
8956      rb_thread_restore_context(curr_thread, RESTORE_TRAP);
8957  #else
8958      rb_thread_critical = 0;
8959      if (!rb_thread_dead(curr_thread)) {
8960          if (THREAD_SAVE_CONTEXT(curr_thread)) {
8961              return;
8962          }
8963      }
8964      rb_thread_ready(main_thread);
8965      th_cmd = cmd;
8966      th_sig = sig;
8967      curr_thread = main_thread;
8968      rb_thread_restore_context(curr_thread, RESTORE_TRAP);
8969  #endif
8970  }
8971  
8972  static VALUE
8973  rb_thread_raise(argc, argv, th)
8974      int argc;
8975      VALUE *argv;
8976      rb_thread_t th;
8977  {
8978      if (rb_thread_dead(th)) return Qnil;
8979      if (curr_thread == th) {
8980          rb_f_raise(argc, argv);
8981      }
8982  
8983      if (THREAD_SAVE_CONTEXT(curr_thread)) {
8984          return th->thread;
8985      }
8986  
8987      rb_scan_args(argc, argv, "11", &th_raise_argv[0], &th_raise_argv[1]);
8988      rb_thread_ready(th);
8989      curr_thread = th;
8990  
8991      th_raise_argc = argc;
8992      th_raise_node = ruby_current_node;
8993      rb_thread_restore_context(curr_thread, RESTORE_RAISE);
8994      return Qnil;                /* not reached */
8995  }
8996  
8997  static VALUE
8998  rb_thread_raise_m(argc, argv, thread)
8999      int argc;
9000      VALUE *argv;
9001      VALUE thread;
9002  {
9003      rb_thread_t th = rb_thread_check(thread);
9004  
9005      if (ruby_safe_level > th->safe) {
9006          rb_secure(4);
9007      }
9008      rb_thread_raise(argc, argv, th);
9009      return Qnil;                /* not reached */
9010  }
9011  
9012  VALUE
9013  rb_thread_local_aref(thread, id)
9014      VALUE thread;
9015      ID id;
9016  {
9017      rb_thread_t th;
9018      VALUE val;
9019  
9020      th = rb_thread_check(thread);
9021      if (ruby_safe_level >= 4 && th != curr_thread) {
9022          rb_raise(rb_eSecurityError, "Insecure: thread locals");
9023      }
9024      if (!th->locals) return Qnil;
9025      if (st_lookup(th->locals, id, &val)) {
9026          return val;
9027      }
9028      return Qnil;
9029  }
9030  
9031  static VALUE
9032  rb_thread_aref(thread, id)
9033      VALUE thread, id;
9034  {
9035      return rb_thread_local_aref(thread, rb_to_id(id));
9036  }
9037  
9038  VALUE
9039  rb_thread_local_aset(thread, id, val)
9040      VALUE thread;
9041      ID id;
9042      VALUE val;
9043  {
9044      rb_thread_t th = rb_thread_check(thread);
9045  
9046      if (ruby_safe_level >= 4 && th != curr_thread) {
9047          rb_raise(rb_eSecurityError, "Insecure: can't modify thread locals");
9048      }
9049      if (OBJ_FROZEN(thread)) rb_error_frozen("thread locals");
9050  
9051      if (!th->locals) {
9052          th->locals = st_init_numtable();
9053      }
9054      if (NIL_P(val)) {
9055          st_delete(th->locals, &id, 0);
9056          return Qnil;
9057      }
9058      st_insert(th->locals, id, val);
9059  
9060      return val;
9061  }
9062  
9063  static VALUE
9064  rb_thread_aset(thread, id, val)
9065      VALUE thread, id, val;
9066  {
9067      return rb_thread_local_aset(thread, rb_to_id(id), val);
9068  }
9069  
9070  static VALUE
9071  rb_thread_key_p(thread, id)
9072      VALUE thread, id;
9073  {
9074      rb_thread_t th = rb_thread_check(thread);
9075  
9076      if (!th->locals) return Qfalse;
9077      if (st_lookup(th->locals, rb_to_id(id), 0))
9078          return Qtrue;
9079      return Qfalse;
9080  }
9081  
9082  static int
9083  thread_keys_i(key, value, ary)
9084      ID key;
9085      VALUE value, ary;
9086  {
9087      rb_ary_push(ary, ID2SYM(key));
9088      return ST_CONTINUE;
9089  }
9090  
9091  static VALUE
9092  rb_thread_keys(thread)
9093      VALUE thread;
9094  {
9095      rb_thread_t th = rb_thread_check(thread);
9096      VALUE ary = rb_ary_new();
9097  
9098      if (th->locals) {
9099          st_foreach(th->locals, thread_keys_i, ary);
9100      }
9101      return ary;
9102  }
9103  
9104  static VALUE
9105  rb_thread_inspect(thread)
9106      VALUE thread;
9107  {
9108      char *cname = rb_class2name(CLASS_OF(thread));
9109      rb_thread_t th = rb_thread_check(thread);
9110      const char *status = thread_status_name(th->status);
9111      VALUE str;
9112  
9113      str = rb_str_new(0, strlen(cname)+7+16+9+1); /* 7:tags 16:addr 9:status 1:nul */ 
9114      sprintf(RSTRING(str)->ptr, "#<%s:0x%lx %s>", cname, thread, status);
9115      RSTRING(str)->len = strlen(RSTRING(str)->ptr);
9116      OBJ_INFECT(str, thread);
9117  
9118      return str;
9119  }
9120  
9121  void
9122  rb_thread_atfork()
9123  {
9124      rb_thread_t th;
9125  
9126      if (rb_thread_alone()) return;
9127      FOREACH_THREAD(th) {
9128          if (th != curr_thread) {
9129              th->gid = 0;
9130              th->status = THREAD_KILLED;
9131          }
9132      }
9133      END_FOREACH(th);
9134      main_thread = curr_thread;
9135      curr_thread->next = curr_thread;
9136      curr_thread->prev = curr_thread;
9137  }
9138  
9139  static VALUE rb_cCont;
9140  
9141  static VALUE
9142  rb_callcc(self)
9143      VALUE self;
9144  {
9145      volatile VALUE cont;
9146      rb_thread_t th;
9147      struct tag *tag;
9148      struct RVarmap *vars;
9149  
9150      THREAD_ALLOC(th);
9151      cont = Data_Wrap_Struct(rb_cCont, thread_mark, thread_free, th);
9152  
9153      scope_dup(ruby_scope);
9154      for (tag=prot_tag; tag; tag=tag->prev) {
9155          scope_dup(tag->scope);
9156      }
9157      if (ruby_block) {
9158          struct BLOCK *block = ruby_block;
9159  
9160          while (block) {
9161              block->tag->flags |= BLOCK_DYNAMIC;
9162              block = block->prev;
9163          }
9164      }
9165      th->thread = curr_thread->thread;
9166  
9167      for (vars = th->dyna_vars; vars; vars = vars->next) {
9168          if (FL_TEST(vars, DVAR_DONT_RECYCLE)) break;
9169          FL_SET(vars, DVAR_DONT_RECYCLE);
9170      }
9171  
9172      if (THREAD_SAVE_CONTEXT(th)) {
9173          return th->result;
9174      }
9175      else {
9176          return rb_yield(cont);
9177      }
9178  }
9179  
9180  static VALUE
9181  rb_cont_call(argc, argv, cont)
9182      int argc;
9183      VALUE *argv;
9184      VALUE cont;
9185  {
9186      rb_thread_t th = rb_thread_check(cont);
9187  
9188      if (th->thread != curr_thread->thread) {
9189          rb_raise(rb_eRuntimeError, "continuation called across threads");
9190      }
9191      switch (argc) {
9192        case 0:
9193          th->result = Qnil;
9194          break;
9195        case 1:
9196          th->result = *argv;
9197          break;
9198        default:
9199          th->result = rb_ary_new4(argc, argv);
9200          break;
9201      }
9202  
9203      rb_thread_restore_context(th, RESTORE_NORMAL);
9204      return Qnil;
9205  }
9206  
9207  struct thgroup {
9208      int gid;
9209  };
9210  
9211  static VALUE
9212  thgroup_s_alloc(klass)
9213      VALUE klass;
9214  {
9215      VALUE group;
9216      struct thgroup *data;
9217      static int serial = 1;
9218  
9219      group = Data_Make_Struct(klass, struct thgroup, 0, free, data);
9220      data->gid = serial++;
9221  
9222      return group;
9223  }
9224  
9225  static VALUE
9226  thgroup_list(group)
9227      VALUE group;
9228  {
9229      struct thgroup *data;
9230      rb_thread_t th;
9231      VALUE ary;
9232  
9233      Data_Get_Struct(group, struct thgroup, data);
9234      ary = rb_ary_new();
9235  
9236      FOREACH_THREAD(th) {
9237          if (th->gid == data->gid) {
9238              rb_ary_push(ary, th->thread);
9239          }
9240      }
9241      END_FOREACH(th);
9242  
9243      return ary;
9244  }
9245  
9246  static VALUE
9247  thgroup_add(group, thread)
9248      VALUE group, thread;
9249  {
9250      rb_thread_t th;
9251      struct thgroup *data;
9252  
9253      rb_secure(4);
9254      th = rb_thread_check(thread);
9255      Data_Get_Struct(group, struct thgroup, data);
9256  
9257      th->gid = data->gid;
9258      return group;
9259  }
9260  
9261  void
9262  Init_Thread()
9263  {
9264      VALUE cThGroup;
9265  
9266      rb_eThreadError = rb_define_class("ThreadError", rb_eStandardError);
9267      rb_cThread = rb_define_class("Thread", rb_cObject);
9268      rb_undef_method(CLASS_OF(rb_cThread), "allocate");
9269  
9270      rb_define_singleton_method(rb_cThread, "new", rb_thread_s_new, -1);
9271      rb_define_method(rb_cThread, "initialize", rb_thread_initialize, -2);
9272      rb_define_singleton_method(rb_cThread, "start", rb_thread_start, -2);
9273      rb_define_singleton_method(rb_cThread, "fork", rb_thread_start, -2);
9274  
9275      rb_define_singleton_method(rb_cThread, "stop", rb_thread_stop, 0);
9276      rb_define_singleton_method(rb_cThread, "kill", rb_thread_s_kill, 1);
9277      rb_define_singleton_method(rb_cThread, "exit", rb_thread_exit, 0);
9278      rb_define_singleton_method(rb_cThread, "pass", rb_thread_pass, 0);
9279      rb_define_singleton_method(rb_cThread, "current", rb_thread_current, 0);
9280      rb_define_singleton_method(rb_cThread, "main", rb_thread_main, 0);
9281      rb_define_singleton_method(rb_cThread, "list", rb_thread_list, 0);
9282  
9283      rb_define_singleton_method(rb_cThread, "critical", rb_thread_critical_get, 0);
9284      rb_define_singleton_method(rb_cThread, "critical=", rb_thread_critical_set, 1);
9285  
9286      rb_define_singleton_method(rb_cThread, "abort_on_exception", rb_thread_s_abort_exc, 0);
9287      rb_define_singleton_method(rb_cThread, "abort_on_exception=", rb_thread_s_abort_exc_set, 1);
9288  
9289      rb_define_method(rb_cThread, "run", rb_thread_run, 0);
9290      rb_define_method(rb_cThread, "wakeup", rb_thread_wakeup, 0);
9291      rb_define_method(rb_cThread, "kill", rb_thread_kill, 0);
9292      rb_define_method(rb_cThread, "exit", rb_thread_kill, 0);
9293      rb_define_method(rb_cThread, "value", rb_thread_value, 0);
9294      rb_define_method(rb_cThread, "status", rb_thread_status, 0);
9295      rb_define_method(rb_cThread, "join", rb_thread_join_m, -1);
9296      rb_define_method(rb_cThread, "alive?", rb_thread_alive_p, 0);
9297      rb_define_method(rb_cThread, "stop?", rb_thread_stop_p, 0);
9298      rb_define_method(rb_cThread, "raise", rb_thread_raise_m, -1);
9299  
9300      rb_define_method(rb_cThread, "abort_on_exception", rb_thread_abort_exc, 0);
9301      rb_define_method(rb_cThread, "abort_on_exception=", rb_thread_abort_exc_set, 1);
9302  
9303      rb_define_method(rb_cThread, "priority", rb_thread_priority, 0);
9304      rb_define_method(rb_cThread, "priority=", rb_thread_priority_set, 1);
9305      rb_define_method(rb_cThread, "safe_level", rb_thread_safe_level, 0);
9306  
9307      rb_define_method(rb_cThread, "[]", rb_thread_aref, 1);
9308      rb_define_method(rb_cThread, "[]=", rb_thread_aset, 2);
9309      rb_define_method(rb_cThread, "key?", rb_thread_key_p, 1);
9310      rb_define_method(rb_cThread, "keys", rb_thread_keys, 0);
9311  
9312      rb_define_method(rb_cThread, "inspect", rb_thread_inspect, 0);
9313  
9314      /* allocate main thread */
9315      main_thread = rb_thread_alloc(rb_cThread);
9316      curr_thread = main_thread->prev = main_thread->next = main_thread;
9317  
9318      rb_cCont = rb_define_class("Continuation", rb_cObject);
9319      rb_undef_method(CLASS_OF(rb_cCont), "allocate");
9320      rb_undef_method(CLASS_OF(rb_cCont), "new");
9321      rb_define_method(rb_cCont, "call", rb_cont_call, -1);
9322      rb_define_global_function("callcc", rb_callcc, 0);
9323  
9324      cThGroup = rb_define_class("ThreadGroup", rb_cObject);
9325      rb_define_singleton_method(cThGroup, "allocate", thgroup_s_alloc, 0);
9326      rb_define_method(cThGroup, "list", thgroup_list, 0);
9327      rb_define_method(cThGroup, "add", thgroup_add, 1);
9328      rb_define_const(cThGroup, "Default", rb_obj_alloc(cThGroup));
9329  }
9330  
9331  static VALUE
9332  rb_f_catch(dmy, tag)
9333      VALUE dmy, tag;
9334  {
9335      int state;
9336      ID t;
9337      VALUE val;                  /* OK */
9338  
9339      t = rb_to_id(tag);
9340      PUSH_TAG(t);
9341      if ((state = EXEC_TAG()) == 0) {
9342          val = rb_yield_0(tag, 0, 0, 0);
9343      }
9344      else if (state == TAG_THROW && t == prot_tag->dst) {
9345          val = prot_tag->retval;
9346          state = 0;
9347      }
9348      POP_TAG();
9349      if (state) JUMP_TAG(state);
9350  
9351      return val;
9352  }
9353  
9354  static VALUE
9355  catch_i(tag)
9356      ID tag;
9357  {
9358      return rb_funcall(Qnil, rb_intern("catch"), 1, ID2SYM(tag));
9359  }
9360  
9361  VALUE
9362  rb_catch(tag, proc, data)
9363      const char *tag;
9364      VALUE (*proc)();
9365      VALUE data;
9366  {
9367      return rb_iterate((VALUE(*)_((VALUE)))catch_i, rb_intern(tag), proc, data);
9368  }
9369  
9370  static VALUE
9371  rb_f_throw(argc, argv)
9372      int argc;
9373      VALUE *argv;
9374  {
9375      VALUE tag, value;
9376      ID t;
9377      struct tag *tt = prot_tag;
9378  
9379      rb_scan_args(argc, argv, "11", &tag, &value);
9380      t = rb_to_id(tag);
9381  
9382      while (tt) {
9383          if (tt->tag == t) {
9384              tt->dst = t;
9385              break;
9386          }
9387          if (tt->tag == PROT_THREAD) {
9388              rb_raise(rb_eThreadError, "uncaught throw `%s' in thread 0x%x",
9389                       rb_id2name(t),
9390                       curr_thread);
9391          }
9392          tt = tt->prev;
9393      }
9394      if (!tt) {
9395          rb_name_error(t, "uncaught throw `%s'", rb_id2name(t));
9396      }
9397      return_value(value);
9398      rb_trap_restore_mask();
9399      JUMP_TAG(TAG_THROW);
9400  }
9401  
9402  void
9403  rb_throw(tag, val)
9404      const char *tag;
9405      VALUE val;
9406  {
9407      VALUE argv[2];
9408      ID t = rb_intern(tag);
9409  
9410      argv[0] = ID2SYM(t);
9411      argv[1] = val;
9412      rb_f_throw(2, argv);
9413  }
9414  
9415  static void
9416  return_check()
9417  {
9418      struct tag *tt = prot_tag;
9419  
9420      while (tt) {
9421          if (tt->tag == PROT_FUNC) {
9422              break;
9423          }
9424          if (tt->tag == PROT_THREAD) {
9425              rb_raise(rb_eThreadError, "return from within thread 0x%x",
9426                       curr_thread);
9427          }
9428          tt = tt->prev;
9429      }
9430  }