eval.c
DEFINITIONS
This source file includes following functions.
- rb_secure
- rb_check_safe_str
- print_undef
- rb_clear_cache
- rb_clear_cache_by_id
- rb_clear_cache_by_class
- rb_add_method
- search_method
- rb_get_method_body
- remove_method
- rb_remove_method
- rb_mod_remove_method
- rb_disable_super
- rb_enable_super
- rb_export_method
- rb_method_boundp
- rb_attr
- new_blktag
- new_dvar
- rb_dvar_defined
- rb_dvar_curr
- rb_dvar_ref
- rb_dvar_push
- dvar_asgn_internal
- dvar_asgn
- dvar_asgn_curr
- rb_svar
- ruby_set_current_source
- error_pos
- get_backtrace
- set_backtrace
- error_print
- ruby_init
- eval_node
- error_handle
- ruby_options
- ruby_finalize
- ruby_stop
- ruby_run
- compile_error
- rb_eval_string
- rb_eval_string_protect
- rb_eval_string_wrap
- localjump_error
- localjump_exitstatus
- jump_tag_but_local_jump
- rb_eval_cmd
- rb_trap_eval
- superclass
- ev_const_defined
- ev_const_get
- cvar_cbase
- rb_mod_nesting
- rb_mod_s_constants
- rb_frozen_class_p
- rb_undef
- rb_mod_undef_method
- rb_alias
- rb_mod_alias_method
- copy_node_scope
- TMP_ALLOC
- TMP_ALLOC
- arg_defined
- is_defined
- rb_obj_is_block
- rb_obj_is_proc
- set_trace_func
- call_trace_func
- svalue_to_avalue
- avalue_to_svalue
- avalue_to_yvalue
- svalue_to_mvalue
- mvalue_to_svalue
- rb_eval
- module_setup
- rb_respond_to
- rb_obj_respond_to
- rb_mod_method_defined
- terminate_process
- rb_exit
- rb_f_exit
- rb_f_abort
- rb_iter_break
- rb_longjmp
- rb_exc_raise
- rb_exc_fatal
- rb_interrupt
- rb_f_raise
- rb_jump_tag
- rb_block_given_p
- rb_iterator_p
- rb_f_block_given_p
- rb_yield_0
- rb_yield
- rb_f_loop
- massign
- assign
- rb_iterate
- handle_rescue
- rb_rescue2
- rb_rescue
- rb_protect
- rb_ensure
- rb_with_disable_interrupt
- stack_check
- rb_f_missing
- rb_undefined
- call_cfunc
- rb_call0
- rb_call
- rb_apply
- rb_f_send
- rb_funcall
- rb_funcall2
- rb_funcall3
- rb_call_super
- backtrace
- rb_f_caller
- rb_backtrace
- make_backtrace
- rb_frame_last_func
- compile
- eval
- rb_f_eval
- exec_under
- eval_under_i
- eval_under
- yield_under_i
- yield_under
- specific_eval
- rb_obj_instance_eval
- rb_mod_module_eval
- rb_load
- rb_load_protect
- rb_f_load
- rb_feature_p
- rb_provided
- rb_provide_feature
- rb_provide
- rb_f_require
- rb_require
- secure_visibility
- set_method_visibility
- rb_mod_public
- rb_mod_protected
- rb_mod_private
- rb_mod_public_method
- rb_mod_private_method
- top_public
- top_private
- rb_mod_modfunc
- rb_mod_append_features
- rb_mod_include
- rb_obj_call_init
- top_include
- rb_extend_object
- rb_mod_extend_object
- rb_obj_extend
- errinfo_setter
- errat_getter
- errat_setter
- rb_f_local_variables
- rb_set_end_proc
- rb_mark_end_proc
- call_end_proc
- rb_f_END
- rb_f_at_exit
- rb_exec_end_proc
- Init_eval
- Init_load
- scope_dup
- blk_mark
- blk_free
- blk_copy_prev
- frame_dup
- bind_clone
- rb_f_binding
- proc_save_safe_level
- proc_get_safe_level
- proc_set_safe_level
- proc_new
- proc_s_new
- rb_f_lambda
- blk_orphan
- proc_invoke
- proc_call
- proc_yield
- proc_arity
- proc_eq
- proc_to_s
- proc_to_proc
- proc_binding
- block_pass
- bm_mark
- mnew
- method_eq
- method_unbind
- umethod_unbind
- rb_obj_method
- rb_mod_method
- method_clone
- method_call
- umethod_bind
- method_arity
- method_inspect
- mproc
- bmcall
- umcall
- rb_proc_new
- method_proc
- umethod_proc
- rb_mod_define_method
- Init_Proc
- win32_get_exception_list
- win32_set_exception_list
- thread_status_name
- rb_set_safe_level
- safe_getter
- safe_setter
- timeofday
- thread_mark
- rb_gc_mark_threads
- thread_free
- rb_thread_check
- rb_thread_save_context
- thread_switch
- stack_extend
- rb_thread_restore_context
- rb_thread_ready
- rb_thread_remove
- rb_thread_dead
- rb_thread_fd_close
- rb_thread_deadlock
- copy_fds
- match_fds
- intersect_fds
- find_bad_fds
- rb_thread_schedule
- rb_thread_wait_fd
- rb_thread_fd_writable
- rb_thread_wait_for
- rb_thread_alone
- rb_thread_select
- rb_thread_join
- rb_thread_join_m
- rb_thread_current
- rb_thread_main
- rb_thread_list
- rb_thread_wakeup
- rb_thread_run
- rb_thread_kill
- rb_thread_s_kill
- rb_thread_exit
- rb_thread_pass
- rb_thread_stop
- rb_thread_polling
- rb_thread_sleep
- pause
- pause
- rb_thread_sleep_forever
- rb_thread_priority
- rb_thread_priority_set
- rb_thread_safe_level
- rb_thread_s_abort_exc
- rb_thread_s_abort_exc_set
- rb_thread_abort_exc
- rb_thread_abort_exc_set
- rb_thread_alloc
- catch_timer
- rb_thread_start_timer
- rb_thread_stop_timer
- rb_thread_start_0
- rb_thread_create
- rb_thread_yield
- rb_thread_s_new
- rb_thread_initialize
- rb_thread_start
- rb_thread_value
- rb_thread_status
- rb_thread_alive_p
- rb_thread_stop_p
- rb_thread_wait_other_threads
- rb_thread_cleanup
- rb_thread_critical_get
- rb_thread_critical_set
- rb_thread_interrupt
- rb_thread_signal_raise
- rb_thread_trap_eval
- rb_thread_raise
- rb_thread_raise_m
- rb_thread_local_aref
- rb_thread_aref
- rb_thread_local_aset
- rb_thread_aset
- rb_thread_key_p
- thread_keys_i
- rb_thread_keys
- rb_thread_inspect
- rb_thread_atfork
- rb_callcc
- rb_cont_call
- thgroup_s_alloc
- thgroup_list
- thgroup_add
- Init_Thread
- rb_f_catch
- catch_i
- rb_catch
- rb_f_throw
- rb_throw
- return_check
1
2
3
4
5
6
7
8
9
10
11
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
27 #ifdef __GNUC__
28 # ifndef atarist
29 # ifndef alloca
30 # define alloca __builtin_alloca
31 # endif
32 # endif
33 #else
34 # if defined(HAVE_ALLOCA_H)
35 # include <alloca.h>
36 # elif !defined(alloca)
37 char *alloca();
38 # endif
39 #endif
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;
83 long tv_usec;
84 };
85 #endif
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
126
127
128
129
130
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 {
185 ID mid;
186 ID mid0;
187 VALUE klass;
188 VALUE origin;
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
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
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
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) \
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
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;
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;
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++;
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
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;
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;
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;
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;
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) {
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;
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;
1859 char *buf;
1860 {
1861 VALUE val;
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;
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;
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();
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);
2252 result = Qnil;
2253 break;
2254
2255
2256 case NODE_BEGIN:
2257 node = node->nd_body;
2258 goto again;
2259
2260
2261 case NODE_MATCH:
2262 result = rb_reg_match2(node->nd_lit);
2263 break;
2264
2265
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
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
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
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;
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;
2623 }
2624 }
2625 else if (node->nd_else) {
2626 if (!state) {
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;
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:
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:
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;
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;
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;
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;
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:
2867 if (RTEST(val)) RETURN(val);
2868 val = rb_eval(self, rval);
2869 break;
2870 case 1:
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:
2892 if (RTEST(val)) RETURN(val);
2893 val = rb_eval(self, node->nd_value);
2894 break;
2895 case 1:
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:
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:
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) {
3192
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;
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;
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;
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();
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;
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;
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
3783 ruby_dyna_vars = new_dvar(0, 0, block->dyna_vars);
3784 }
3785 else {
3786
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;
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
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
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
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
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;
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;
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;
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;
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();
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;
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;
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;
4488 VALUE *argv;
4489 NODE *body;
4490 int nosuper;
4491 {
4492 NODE *b2;
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;
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
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
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;
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
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
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;
4713 const VALUE *argv;
4714 int scope;
4715 {
4716 NODE *body;
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
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
4745 if ((noex & NOEX_PRIVATE) && scope == 0)
4746 return rb_undefined(recv, mid, argc, argv, CSTAT_PRIV);
4747
4748
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;
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
5011 frame = data->frame;
5012 frame.tmp = ruby_frame;
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;
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
5173 static VALUE
5174 exec_under(func, under, cbase, args)
5175 VALUE (*func)();
5176 VALUE under, cbase;
5177 void *args;
5178 {
5179 VALUE val;
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
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
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;
5353 PUSH_VARS();
5354 PUSH_CLASS();
5355 wrapper = ruby_wrapper;
5356 ruby_cref = top_cref;
5357 if (!wrap) {
5358 rb_secure(4);
5359 ruby_class = rb_cObject;
5360 ruby_wrapper = 0;
5361 }
5362 else {
5363
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
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)
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))
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;
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
5631 if (!loading_tbl) {
5632 loading_tbl = st_init_strtable();
5633 }
5634
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);
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;
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++) {
5940 if (!rb_is_local_id(tbl[i])) continue;
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;
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;
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
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) {
6561 localjump_error("return from proc-closure", prot_tag->retval);
6562 }
6563
6564 default:
6565 JUMP_TAG(state);
6566 }
6567 return result;
6568 }
6569
6570 static VALUE
6571 proc_call(proc, args)
6572 VALUE proc, args;
6573 {
6574 return proc_invoke(proc, args, Qtrue, Qundef);
6575 }
6576
6577 static VALUE
6578 proc_yield(proc, args)
6579 VALUE proc, args;
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;
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);
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
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) {
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;
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
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);
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
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
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);
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);
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
7297 #define DELAY_INFTY 1E30
7298
7299
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;
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
7357 #define THREAD_TERMINATING 0x400
7358 #define THREAD_FLAGS_MASK 0x400
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
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
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
7450 if (th == curr_thread) return;
7451 if (th->status == THREAD_KILLED) return;
7452 if (th->stk_len == 0) return;
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
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);
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
7649 if (&v > th->stk_pos) stack_extend(th, exit);
7650 }
7651 else {
7652
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
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;
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;
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;
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
7904 if (need_select) {
7905
7906
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
7964
7965 FOREACH_THREAD_FROM(curr, th) {
7966 if ((th->wait_for&WAIT_FD) && FD_ISSET(th->fd, &readfds)) {
7967
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
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
7991
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
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
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
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) {
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
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
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
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
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;
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) {
8744 ID id = *tbl++;
8745 if (id != 0 && !rb_is_local_id(id))
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
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;
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;
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;
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);
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
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;
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 }