Main Page   Modules   Alphabetical List   Data Structures   File List   Data Fields   Globals  

eval.c

Go to the documentation of this file.
00001 /**********************************************************************
00002 
00003   eval.c -
00004 
00005   $Author: matz $
00006   $Date: 2004/12/18 02:07:29 $
00007   created at: Thu Jun 10 14:22:17 JST 1993
00008 
00009   Copyright (C) 1993-2003 Yukihiro Matsumoto
00010   Copyright (C) 2000  Network Applied Communication Laboratory, Inc.
00011   Copyright (C) 2000  Information-technology Promotion Agency, Japan
00012 
00013 **********************************************************************/
00014 
00015 #include "ruby.h"
00016 #include "node.h"
00017 #include "env.h"
00018 #include "util.h"
00019 #include "rubysig.h"
00020 
00021 #ifdef HAVE_STDLIB_H
00022 #include <stdlib.h>
00023 #endif
00024 #ifndef EXIT_SUCCESS
00025 #define EXIT_SUCCESS 0
00026 #endif
00027 #ifndef EXIT_FAILURE
00028 #define EXIT_FAILURE 1
00029 #endif
00030 
00031 #include <stdio.h>
00032 #if defined(HAVE_GETCONTEXT) && defined(HAVE_SETCONTEXT)
00033 #include <ucontext.h>
00034 #define USE_CONTEXT
00035 #else
00036 #include <setjmp.h>
00037 #endif
00038 
00039 #include "st.h"
00040 #include "dln.h"
00041 
00042 #ifdef __APPLE__
00043 #include <crt_externs.h>
00044 #endif
00045 
00046 /* Make alloca work the best possible way.  */
00047 #ifdef __GNUC__
00048 # ifndef atarist
00049 #  ifndef alloca
00050 #   define alloca __builtin_alloca
00051 #  endif
00052 # endif /* atarist */
00053 #else
00054 # ifdef HAVE_ALLOCA_H
00055 #  include <alloca.h>
00056 # else
00057 #  ifdef _AIX
00058  #pragma alloca
00059 #  else
00060 #   ifndef alloca /* predefined by HP cc +Olibcalls */
00061 void *alloca ();
00062 #   endif
00063 #  endif /* AIX */
00064 # endif /* HAVE_ALLOCA_H */
00065 #endif /* __GNUC__ */
00066 
00067 #ifdef HAVE_STDARG_PROTOTYPES
00068 #include <stdarg.h>
00069 #define va_init_list(a,b) va_start(a,b)
00070 #else
00071 #include <varargs.h>
00072 #define va_init_list(a,b) va_start(a)
00073 #endif
00074 
00075 #ifndef HAVE_STRING_H
00076 char *strrchr (const char*,const char);
00077 #endif
00078 
00079 #ifdef HAVE_UNISTD_H
00080 #include <unistd.h>
00081 #endif
00082 
00083 #ifdef __BEOS__
00084 #include <net/socket.h>
00085 #endif
00086 
00087 #ifdef __MACOS__
00088 #include "macruby_private.h"
00089 #endif
00090 
00091 #ifdef __VMS
00092 #include "vmsruby_private.h"
00093 #endif
00094 
00095 #ifdef USE_CONTEXT
00096 typedef struct {
00097     ucontext_t context;
00098     volatile int status;
00099 } rb_jmpbuf_t[1];
00100 
00101 #undef longjmp
00102 #undef setjmp
00103 
00104 static void rb_jump_context(rb_jmpbuf_t, int);
00105 static inline void
00106 rb_jump_context(env, val)
00107     rb_jmpbuf_t env;
00108     int val;
00109 {
00110     env->status = val;
00111     setcontext(&env->context);
00112     abort();                    /* ensure noreturn */
00113 }
00114 #define longjmp(env, val) rb_jump_context(env, val)
00115 #define setjmp(j) ((j)->status = 0, getcontext(&(j)->context), (j)->status)
00116 #else
00117 typedef jmp_buf rb_jmpbuf_t;
00118 #ifndef setjmp
00119 #ifdef HAVE__SETJMP
00120 #define setjmp(env) _setjmp(env)
00121 #define longjmp(env,val) _longjmp(env,val)
00122 #endif
00123 #endif
00124 #endif
00125 
00126 #include <sys/types.h>
00127 #include <signal.h>
00128 #include <errno.h>
00129 
00130 #if defined(__VMS)
00131 #pragma nostandard
00132 #endif
00133 
00134 #ifdef HAVE_SYS_SELECT_H
00135 #include <sys/select.h>
00136 #endif
00137 
00138 #include <sys/stat.h>
00139 
00140 VALUE rb_cProc;
00141 static VALUE rb_cBinding;
00142 static VALUE proc_invoke (VALUE,VALUE,VALUE,VALUE);
00143 static VALUE rb_f_binding (VALUE);
00144 static void rb_f_END (void);
00145 static VALUE rb_f_block_given_p (void);
00146 static VALUE block_pass (VALUE,NODE*);
00147 static VALUE rb_cMethod;
00148 static VALUE method_call (int, VALUE*, VALUE);
00149 static VALUE rb_cUnboundMethod;
00150 static VALUE umethod_bind (VALUE, VALUE);
00151 static VALUE rb_mod_define_method (int, VALUE*, VALUE);
00153 static void rb_raise_jump (VALUE);
00154 static VALUE rb_make_exception (int argc, VALUE *argv);
00155 
00156 static int scope_vmode;
00157 #define SCOPE_PUBLIC    0
00158 #define SCOPE_PRIVATE   1
00159 #define SCOPE_PROTECTED 2
00160 #define SCOPE_MODFUNC   5
00161 #define SCOPE_MASK      7
00162 #define SCOPE_SET(f)  (scope_vmode=(f))
00163 #define SCOPE_TEST(f) (scope_vmode&(f))
00164 
00165 NODE* ruby_current_node;
00166 int ruby_safe_level = 0;
00167 /* safe-level:
00168    0 - strings from streams/environment/ARGV are tainted (default)
00169    1 - no dangerous operation by tainted value
00170    2 - process/file operations prohibited
00171    3 - all generated objects are tainted
00172    4 - no global (non-tainted) variable modification/no direct output
00173 */
00174 
00175 static VALUE safe_getter (void);
00176 static void safe_setter (VALUE val);
00177 
00178 void
00179 rb_secure(level)
00180     int level;
00181 {
00182     if (level <= ruby_safe_level) {
00183         if (ruby_frame->last_func) {
00184             rb_raise(rb_eSecurityError, "Insecure operation `%s' at level %d",
00185                      rb_id2name(ruby_frame->last_func), ruby_safe_level);
00186         }
00187         else {
00188             rb_raise(rb_eSecurityError, "Insecure operation at level %d", ruby_safe_level);
00189         }
00190     }
00191 }
00192 
00193 void
00194 rb_secure_update(obj)
00195     VALUE obj;
00196 {
00197     if (!OBJ_TAINTED(obj)) rb_secure(4);
00198 }
00199 
00200 void
00201 rb_check_safe_obj(x)
00202     VALUE x;
00203 {
00204     if (ruby_safe_level > 0 && OBJ_TAINTED(x)){
00205         if (ruby_frame->last_func) {
00206             rb_raise(rb_eSecurityError, "Insecure operation - %s",
00207                      rb_id2name(ruby_frame->last_func));
00208         }
00209         else {
00210             rb_raise(rb_eSecurityError, "Insecure operation: -r");
00211         }
00212     }
00213     rb_secure(4);
00214 }
00215 
00216 void
00217 rb_check_safe_str(x)
00218     VALUE x;
00219 {
00220     rb_check_safe_obj(x);
00221     if (TYPE(x)!= T_STRING) {
00222         rb_raise(rb_eTypeError, "wrong argument type %s (expected String)",
00223                  rb_obj_classname(x));
00224     }
00225 }
00228 static void print_undef (VALUE, ID);
00229 static void
00230 print_undef(klass, id)
00231     VALUE klass;
00232     ID id;
00233 {
00234     rb_name_error(id, "undefined method `%s' for %s `%s'",
00235                   rb_id2name(id),
00236                   (TYPE(klass) == T_MODULE) ? "module" : "class",
00237                   rb_class2name(klass));
00238 }
00239 
00240 static ID removed, singleton_removed, undefined, singleton_undefined;
00241 
00242 #define CACHE_SIZE 0x800
00243 #define CACHE_MASK 0x7ff
00244 #define EXPR1(c,m) ((((c)>>3)^(m))&CACHE_MASK)
00245 
00246 struct cache_entry {            /* method hash table. */
00247     ID mid;                     /* method's id */
00248     ID mid0;                    /* method's original id */
00249     VALUE klass;                /* receiver's class */
00250     VALUE origin;               /* where method defined  */
00251     NODE *method;
00252     int noex;
00253 };
00254 
00255 static struct cache_entry cache[CACHE_SIZE];
00256 static int ruby_running = 0;
00257 
00258 void
00259 rb_clear_cache()
00260 {
00261    struct cache_entry *ent, *end;
00262 
00263     if (!ruby_running) return;
00264     ent = cache; end = ent + CACHE_SIZE;
00265     while (ent < end) {
00266         ent->mid = 0;
00267         ent++;
00268     }
00269 }
00270 
00271 static void
00272 rb_clear_cache_for_undef(klass, id)
00273     VALUE klass;
00274     ID id;
00275 {
00276     struct cache_entry *ent, *end;
00277 
00278     if (!ruby_running) return;
00279     ent = cache; end = ent + CACHE_SIZE;
00280     while (ent < end) {
00281         if (ent->origin == klass && ent->mid == id) {
00282             ent->mid = 0;
00283         }
00284         ent++;
00285     }
00286 }
00287 
00288 static void
00289 rb_clear_cache_by_id(id)
00290     ID id;
00291 {
00292     struct cache_entry *ent, *end;
00293 
00294     if (!ruby_running) return;
00295     ent = cache; end = ent + CACHE_SIZE;
00296     while (ent < end) {
00297         if (ent->mid == id) {
00298             ent->mid = 0;
00299         }
00300         ent++;
00301     }
00302 }
00303 
00304 void
00305 rb_clear_cache_by_class(klass)
00306     VALUE klass;
00307 {
00308     struct cache_entry *ent, *end;
00309 
00310     if (!ruby_running) return;
00311     ent = cache; end = ent + CACHE_SIZE;
00312     while (ent < end) {
00313         if (ent->klass == klass || ent->origin == klass) {
00314             ent->mid = 0;
00315         }
00316         ent++;
00317     }
00318 }
00319 
00320 static ID init, eqq, each, aref, aset, match, missing;
00321 static ID added, singleton_added;
00322 static ID __id__, __send__, respond_to;
00323 
00324 void
00325 rb_add_method(klass, mid, node, noex)
00326     VALUE klass;
00327     ID mid;
00328     NODE *node;
00329     int noex;
00330 {
00331     NODE *body;
00332 
00333     if (NIL_P(klass)) klass = rb_cObject;
00334     if (ruby_safe_level >= 4 && (klass == rb_cObject || !OBJ_TAINTED(klass))) {
00335         rb_raise(rb_eSecurityError, "Insecure: can't define method");
00336     }
00337     if (!FL_TEST(klass, FL_SINGLETON) &&
00338         node && nd_type(node) != NODE_ZSUPER &&
00339         (mid == rb_intern("initialize" )|| mid == rb_intern("initialize_copy"))) {
00340         noex = NOEX_PRIVATE | noex;
00341     }
00342     else if (FL_TEST(klass, FL_SINGLETON) && node && nd_type(node) == NODE_CFUNC &&
00343              mid == rb_intern("allocate")) {
00344         rb_warn("defining %s.allocate is deprecated; use rb_define_alloc_func()",
00345                 rb_class2name(rb_iv_get(klass, "__attached__")));
00346         mid = ID_ALLOCATOR;
00347     }
00348     if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
00349     rb_clear_cache_by_id(mid);
00350     body = NEW_METHOD(node, noex);
00351     st_insert(RCLASS(klass)->m_tbl, mid, (st_data_t)body);
00352     if (node && mid != ID_ALLOCATOR && ruby_running) {
00353         if (FL_TEST(klass, FL_SINGLETON)) {
00354             rb_funcall(rb_iv_get(klass, "__attached__"), singleton_added, 1, ID2SYM(mid));
00355         }
00356         else {
00357             rb_funcall(klass, added, 1, ID2SYM(mid));
00358         }
00359     }
00360 }
00361 
00362 void
00363 rb_define_alloc_func(klass, func)
00364     VALUE klass;
00365     VALUE (*func) (VALUE);
00366 {
00367     Check_Type(klass, T_CLASS);
00368     rb_add_method(CLASS_OF(klass), ID_ALLOCATOR, NEW_CFUNC(func, 0), NOEX_PRIVATE);
00369 }
00370 
00371 void
00372 rb_undef_alloc_func(klass)
00373     VALUE klass;
00374 {
00375     Check_Type(klass, T_CLASS);
00376     rb_add_method(CLASS_OF(klass), ID_ALLOCATOR, 0, NOEX_UNDEF);
00377 }
00378 
00379 static NODE*
00380 search_method(klass, id, origin)
00381     VALUE klass, *origin;
00382     ID id;
00383 {
00384     NODE *body;
00385 
00386     if (!klass) return 0;
00387     while (!st_lookup(RCLASS(klass)->m_tbl, id, (st_data_t *)&body)) {
00388         klass = RCLASS(klass)->super;
00389         if (!klass) return 0;
00390     }
00391 
00392     if (origin) *origin = klass;
00393     return body;
00394 }
00395 
00396 static NODE*
00397 rb_get_method_body(klassp, idp, noexp)
00398     VALUE *klassp;
00399     ID *idp;
00400     int *noexp;
00401 {
00402     ID id = *idp;
00403     VALUE klass = *klassp;
00404     VALUE origin;
00405     NODE * volatile body;
00406     struct cache_entry *ent;
00407 
00408     if ((body = search_method(klass, id, &origin)) == 0 || !body->nd_body) {
00409         /* store empty info in cache */
00410         ent = cache + EXPR1(klass, id);
00411         ent->klass  = klass;
00412         ent->origin = klass;
00413         ent->mid = ent->mid0 = id;
00414         ent->noex   = 0;
00415         ent->method = 0;
00416 
00417         return 0;
00418     }
00419 
00420     if (ruby_running) {
00421         /* store in cache */
00422         ent = cache + EXPR1(klass, id);
00423         ent->klass  = klass;
00424         ent->noex   = body->nd_noex;
00425         if (noexp) *noexp = body->nd_noex;
00426         body = body->nd_body;
00427         if (nd_type(body) == NODE_FBODY) {
00428             ent->mid = id;
00429             *klassp = body->nd_orig;
00430             ent->origin = body->nd_orig;
00431             *idp = ent->mid0 = body->nd_mid;
00432             body = ent->method = body->nd_head;
00433         }
00434         else {
00435             *klassp = origin;
00436             ent->origin = origin;
00437             ent->mid = ent->mid0 = id;
00438             ent->method = body;
00439         }
00440     }
00441     else {
00442         if (noexp) *noexp = body->nd_noex;
00443         body = body->nd_body;
00444         if (nd_type(body) == NODE_FBODY) {
00445             *klassp = body->nd_orig;
00446             *idp = body->nd_mid;
00447             body = body->nd_head;
00448         }
00449         else {
00450             *klassp = origin;
00451         }
00452     }
00453 
00454     return body;
00455 }
00456 
00457 NODE*
00458 rb_method_node(klass, id)
00459     VALUE klass;
00460     ID id;
00461 {
00462     int noex;
00463 
00464     return rb_get_method_body(&klass, &id, &noex);
00465 }
00466 
00467 static void
00468 remove_method(klass, mid)
00469     VALUE klass;
00470     ID mid;
00471 {
00472     NODE *body;
00473 
00474     if (klass == rb_cObject) {
00475         rb_secure(4);
00476     }
00477     if (ruby_safe_level >= 4 && !OBJ_TAINTED(klass)) {
00478         rb_raise(rb_eSecurityError, "Insecure: can't remove method");
00479     }
00480     if (OBJ_FROZEN(klass)) rb_error_frozen("class/module");
00481     if (mid == __id__ || mid == __send__ || mid == init) {
00482         rb_warn("removing `%s' may cause serious problem", rb_id2name(mid));
00483     }
00484     if (!st_delete(RCLASS(klass)->m_tbl, &mid, (st_data_t *)&body) ||
00485         !body->nd_body) {
00486         rb_name_error(mid, "method `%s' not defined in %s",
00487                       rb_id2name(mid), rb_class2name(klass));
00488     }
00489     rb_clear_cache_for_undef(klass, mid);
00490     if (FL_TEST(klass, FL_SINGLETON)) {
00491         rb_funcall(rb_iv_get(klass, "__attached__"), singleton_removed, 1, ID2SYM(mid));
00492     }
00493     else {
00494         rb_funcall(klass, removed, 1, ID2SYM(mid));
00495     }
00496 }
00497 
00498 void
00499 rb_remove_method(klass, name)
00500     VALUE klass;
00501     const char *name;
00502 {
00503     remove_method(klass, rb_intern(name));
00504 }
00505 
00506 /*
00507  *  call-seq:
00508  *     remove_method(symbol)   => self
00509  *  
00510  *  Removes the method identified by _symbol_ from the current
00511  *  class. For an example, see <code>Module.undef_method</code>.
00512  */
00513 
00514 static VALUE
00515 rb_mod_remove_method(argc, argv, mod)
00516     int argc;
00517     VALUE *argv;
00518     VALUE mod;
00519 {
00520     int i;
00521 
00522     for (i=0; i<argc; i++) {
00523         remove_method(mod, rb_to_id(argv[i]));
00524     }
00525     return mod;
00526 }
00527 
00528 #undef rb_disable_super
00529 #undef rb_enable_super
00530 
00531 void
00532 rb_disable_super(klass, name)
00533     VALUE klass;
00534     const char *name;
00535 {
00536     /* obsolete - no use */
00537 }
00538 
00539 void
00540 rb_enable_super(klass, name)
00541     VALUE klass;
00542     const char *name;
00543 {
00544     rb_warn("rb_enable_super() is obsolete");
00545 }
00546 
00547 static void
00548 rb_export_method(klass, name, noex)
00549     VALUE klass;
00550     ID name;
00551     ID noex;
00552 {
00553     NODE *body;
00554     VALUE origin;
00555 
00556     if (klass == rb_cObject) {
00557         rb_secure(4);
00558     }
00559     body = search_method(klass, name, &origin);
00560     if (!body && TYPE(klass) == T_MODULE) {
00561         body = search_method(rb_cObject, name, &origin);
00562     }
00563     if (!body || !body->nd_body) {
00564         print_undef(klass, name);
00565     }
00566     if (body->nd_noex != noex) {
00567         if (klass == origin) {
00568             body->nd_noex = noex;
00569         }
00570         else {
00571             rb_add_method(klass, name, NEW_ZSUPER(), noex);
00572         }
00573     }
00574 }
00575 
00576 int
00577 rb_method_boundp(klass, id, ex)
00578     VALUE klass;
00579     ID id;
00580     int ex;
00581 {
00582     struct cache_entry *ent;
00583     int noex;
00584 
00585     /* is it in the method cache? */
00586     ent = cache + EXPR1(klass, id);
00587     if (ent->mid == id && ent->klass == klass) {
00588         if (ex && (ent->noex & NOEX_PRIVATE))
00589             return Qfalse;
00590         if (!ent->method) return Qfalse;
00591         return Qtrue;
00592     }
00593     if (rb_get_method_body(&klass, &id, &noex)) {
00594         if (ex && (noex & NOEX_PRIVATE))
00595             return Qfalse;
00596         return Qtrue;
00597     }
00598     return Qfalse;
00599 }
00600 
00601 void
00602 rb_attr(klass, id, read, write, ex)
00603     VALUE klass;
00604     ID id;
00605     int read, write, ex;
00606 {
00607     const char *name;
00608     char *buf;
00609     ID attriv;
00610     int noex;
00611 
00612     if (!ex) noex = NOEX_PUBLIC;
00613     else {
00614         if (SCOPE_TEST(SCOPE_PRIVATE)) {
00615             noex = NOEX_PRIVATE;
00616             rb_warning((scope_vmode == SCOPE_MODFUNC) ?
00617                        "attribute accessor as module_function" :
00618                        "private attribute?");
00619         }
00620         else if (SCOPE_TEST(SCOPE_PROTECTED)) {
00621             noex = NOEX_PROTECTED;
00622         }
00623         else {
00624             noex = NOEX_PUBLIC;
00625         }
00626     }
00627 
00628     name = rb_id2name(id);
00629     if (!name) {
00630         rb_raise(rb_eArgError, "argument needs to be symbol or string");
00631     }
00632     buf = ALLOCA_N(char,strlen(name)+2);
00633     sprintf(buf, "@%s", name);
00634     attriv = rb_intern(buf);
00635     if (read) {
00636         rb_add_method(klass, id, NEW_IVAR(attriv), noex);
00637     }
00638     if (write) {
00639         sprintf(buf, "%s=", name);
00640         id = rb_intern(buf);
00641         rb_add_method(klass, id, NEW_ATTRSET(attriv), noex);
00642     }
00643 }
00644 
00645 extern int ruby_in_compile;
00646 
00647 VALUE ruby_errinfo = Qnil;
00648 extern NODE *ruby_eval_tree_begin;
00649 extern NODE *ruby_eval_tree;
00650 extern int ruby_nerrs;
00651 
00652 static VALUE rb_eLocalJumpError;
00653 static VALUE rb_eSysStackError;
00654 
00655 extern VALUE ruby_top_self;
00656 
00657 struct FRAME *ruby_frame;
00658 struct SCOPE *ruby_scope;
00659 static struct FRAME *top_frame;
00660 static struct SCOPE *top_scope;
00661 
00662 static unsigned long frame_unique = 0;
00663 
00664 #define PUSH_FRAME() do {               \
00665     struct FRAME _frame;                \
00666     _frame.prev = ruby_frame;           \
00667     _frame.tmp  = 0;                    \
00668     _frame.node = ruby_current_node;    \
00669     _frame.iter = ruby_iter->iter;      \
00670     _frame.argc = 0;                    \
00671     _frame.argv = 0;                    \
00672     _frame.flags = FRAME_ALLOCA;        \
00673     _frame.uniq = frame_unique++;       \
00674     ruby_frame = &_frame
00675 
00676 #define POP_FRAME()                     \
00677     ruby_current_node = _frame.node;    \
00678     ruby_frame = _frame.prev;           \
00679 } while (0)
00680 
00681 struct BLOCK {
00682     NODE *var;
00683     NODE *body;
00684     VALUE self;
00685     struct FRAME frame;
00686     struct SCOPE *scope;
00687     VALUE klass;
00688     NODE *cref;
00689     int iter;
00690     int vmode;
00691     int flags;
00692     int uniq;
00693     struct RVarmap *dyna_vars;
00694     VALUE orig_thread;
00695     VALUE wrapper;
00696     VALUE block_obj;
00697     struct BLOCK *outer;
00698     struct BLOCK *prev;
00699 };
00700 
00701 #define BLOCK_D_SCOPE 1
00702 #define BLOCK_LAMBDA  2
00703 
00704 static struct BLOCK *ruby_block;
00705 static unsigned long block_unique = 0;
00706 
00707 #define PUSH_BLOCK(v,b) do {            \
00708     struct BLOCK _block;                \
00709     _block.var = (v);                   \
00710     _block.body = (b);                  \
00711     _block.self = self;                 \
00712     _block.frame = *ruby_frame;         \
00713     _block.klass = ruby_class;          \
00714     _block.cref = ruby_cref;            \
00715     _block.frame.node = ruby_current_node;\
00716     _block.scope = ruby_scope;          \
00717     _block.prev = ruby_block;           \
00718     _block.outer = ruby_block;          \
00719     _block.iter = ruby_iter->iter;      \
00720     _block.vmode = scope_vmode;         \
00721     _block.flags = BLOCK_D_SCOPE;       \
00722     _block.dyna_vars = ruby_dyna_vars;  \
00723     _block.wrapper = ruby_wrapper;      \
00724     _block.block_obj = 0;               \
00725     _block.uniq = (b)?block_unique++:0; \
00726     if (b) {                            \
00727         prot_tag->blkid = _block.uniq;  \
00728     }                                   \
00729     ruby_block = &_block
00730 
00731 #define POP_BLOCK() \
00732    ruby_block = _block.prev; \
00733 } while (0)
00734 
00735 struct RVarmap *ruby_dyna_vars;
00736 #define PUSH_VARS() do { \
00737     struct RVarmap * volatile _old; \
00738     _old = ruby_dyna_vars; \
00739     ruby_dyna_vars = 0
00740 
00741 #define POP_VARS() \
00742     if (_old && (ruby_scope->flags & SCOPE_DONT_RECYCLE)) {\
00743         if (RBASIC(_old)->flags) /* unless it's already recycled */ \
00744             FL_SET(_old, DVAR_DONT_RECYCLE); \
00745     }\
00746     ruby_dyna_vars = _old; \
00747 } while (0)
00748 
00749 #define DVAR_DONT_RECYCLE FL_USER2
00750 
00751 static struct RVarmap*
00752 new_dvar(id, value, prev)
00753     ID id;
00754     VALUE value;
00755     struct RVarmap *prev;
00756 {
00757     NEWOBJ(vars, struct RVarmap);
00758     OBJSETUP(vars, 0, T_VARMAP);
00759     vars->id = id;
00760     vars->val = value;
00761     vars->next = prev;
00762 
00763     return vars;
00764 }
00765 
00766 VALUE
00767 rb_dvar_defined(id)
00768     ID id;
00769 {
00770     struct RVarmap *vars = ruby_dyna_vars;
00771 
00772     while (vars) {
00773         if (vars->id == id) return Qtrue;
00774         vars = vars->next;
00775     }
00776     return Qfalse;
00777 }
00778 
00779 VALUE
00780 rb_dvar_curr(id)
00781     ID id;
00782 {
00783     struct RVarmap *vars = ruby_dyna_vars;
00784 
00785     while (vars) {
00786         if (vars->id == 0) break;
00787         if (vars->id == id) return Qtrue;
00788         vars = vars->next;
00789     }
00790     return Qfalse;
00791 }
00792 
00793 VALUE
00794 rb_dvar_ref(id)
00795     ID id;
00796 {
00797     struct RVarmap *vars = ruby_dyna_vars;
00798 
00799     while (vars) {
00800         if (vars->id == id) {
00801             return vars->val;
00802         }
00803         vars = vars->next;
00804     }
00805     return Qnil;
00806 }
00807 
00808 void
00809 rb_dvar_push(id, value)
00810     ID id;
00811     VALUE value;
00812 {
00813     ruby_dyna_vars = new_dvar(id, value, ruby_dyna_vars);
00814 }
00815 
00816 static void
00817 dvar_asgn_internal(id, value, curr)
00818     ID id;
00819     VALUE value;
00820     int curr;
00821 {
00822     int n = 0;
00823     struct RVarmap *vars = ruby_dyna_vars;
00824 
00825     while (vars) {
00826         if (curr && vars->id == 0) {
00827             /* first null is a dvar header */
00828             n++;
00829             if (n == 2) break;
00830         }
00831         if (vars->id == id) {
00832             vars->val = value;
00833             return;
00834         }
00835         vars = vars->next;
00836     }
00837     if (!ruby_dyna_vars) {
00838         ruby_dyna_vars = new_dvar(id, value, 0);
00839     }
00840     else {
00841         vars = new_dvar(id, value, ruby_dyna_vars->next);
00842         ruby_dyna_vars->next = vars;
00843     }
00844 }
00845 
00846 static inline void
00847 dvar_asgn(id, value)
00848     ID id;
00849     VALUE value;
00850 {
00851     dvar_asgn_internal(id, value, 0);
00852 }
00853 
00854 static inline void
00855 dvar_asgn_curr(id, value)
00856     ID id;
00857     VALUE value;
00858 {
00859     dvar_asgn_internal(id, value, 1);
00860 }
00861 
00862 VALUE *
00863 rb_svar(cnt)
00864     int cnt;
00865 {
00866     struct RVarmap *vars = ruby_dyna_vars;
00867     ID id;
00868 
00869     if (!ruby_scope->local_tbl) return NULL;
00870     if (cnt >= ruby_scope->local_tbl[0]) return NULL;
00871     id = ruby_scope->local_tbl[cnt+1];
00872     while (vars) {
00873         if (vars->id == id) return &vars->val;
00874         vars = vars->next;
00875     }
00876     if (ruby_scope->local_vars == 0) return NULL;
00877     return &ruby_scope->local_vars[cnt];
00878 }
00879 
00880 struct iter {
00881     int iter;
00882     struct iter *prev;
00883 };
00884 static struct iter *ruby_iter;
00885 
00886 #define ITER_NOT 0
00887 #define ITER_PRE 1
00888 #define ITER_CUR 2
00889 
00890 #define PUSH_ITER(i) do {               \
00891     struct iter _iter;                  \
00892     _iter.prev = ruby_iter;             \
00893     _iter.iter = (i);                   \
00894     ruby_iter = &_iter
00895 
00896 #define POP_ITER()                      \
00897     ruby_iter = _iter.prev;             \
00898 } while (0)
00899 
00900 struct tag {
00901     rb_jmpbuf_t buf;
00902     struct FRAME *frame;
00903     struct iter *iter;
00904     VALUE tag;
00905     VALUE retval;
00906     struct SCOPE *scope;
00907     VALUE dst;
00908     struct tag *prev;
00909     int blkid;
00910 };
00911 static struct tag *prot_tag;
00912 
00913 #define PUSH_TAG(ptag) do {             \
00914     struct tag _tag;                    \
00915     _tag.retval = Qnil;                 \
00916     _tag.frame = ruby_frame;            \
00917     _tag.iter = ruby_iter;              \
00918     _tag.prev = prot_tag;               \
00919     _tag.scope = ruby_scope;            \
00920     _tag.tag = ptag;                    \
00921     _tag.dst = 0;                       \
00922     _tag.blkid = 0;                     \
00923     prot_tag = &_tag
00924 
00925 #define PROT_NONE   Qfalse      /* 0 */
00926 #define PROT_THREAD Qtrue       /* 2 */
00927 #define PROT_FUNC   INT2FIX(0)  /* 1 */
00928 #define PROT_LOOP   INT2FIX(1)  /* 3 */
00929 #define PROT_LAMBDA INT2FIX(2)  /* 5 */
00930 #define PROT_YIELD  INT2FIX(3)  /* 7 */
00931 
00932 #define EXEC_TAG()    (FLUSH_REGISTER_WINDOWS, setjmp(prot_tag->buf))
00933 
00934 #define JUMP_TAG(st) do {               \
00935     ruby_frame = prot_tag->frame;       \
00936     ruby_iter = prot_tag->iter;         \
00937     longjmp(prot_tag->buf,(st));        \
00938 } while (0)
00939 
00940 #define POP_TAG()                       \
00941     prot_tag = _tag.prev;               \
00942 } while (0)
00943 
00944 #define TAG_DST() (_tag.dst == (VALUE)ruby_frame->uniq)
00945 
00946 #define TAG_RETURN      0x1
00947 #define TAG_BREAK       0x2
00948 #define TAG_NEXT        0x3
00949 #define TAG_RETRY       0x4
00950 #define TAG_REDO        0x5
00951 #define TAG_RAISE       0x6
00952 #define TAG_THROW       0x7
00953 #define TAG_FATAL       0x8
00954 #define TAG_MASK        0xf
00955 
00956 VALUE ruby_class;
00957 static VALUE ruby_wrapper;      /* security wrapper */
00958 
00959 #define PUSH_CLASS(c) do {              \
00960     VALUE _class = ruby_class;          \
00961     ruby_class = (c)
00962 
00963 #define POP_CLASS() ruby_class = _class; \
00964 } while (0)
00965 
00966 static NODE *ruby_cref = 0;
00967 static NODE *top_cref;
00968 #define PUSH_CREF(c) ruby_cref = NEW_NODE(NODE_CREF,(c),0,ruby_cref)
00969 #define POP_CREF() ruby_cref = ruby_cref->nd_next
00970 
00971 #define PUSH_SCOPE() do {               \
00972     volatile int _vmode = scope_vmode;  \
00973     struct SCOPE * volatile _old;       \
00974     NEWOBJ(_scope, struct SCOPE);       \
00975     OBJSETUP(_scope, 0, T_SCOPE);       \
00976     _scope->local_tbl = 0;              \
00977     _scope->local_vars = 0;             \
00978     _scope->flags = 0;                  \
00979     _old = ruby_scope;                  \
00980     ruby_scope = _scope;                \
00981     scope_vmode = SCOPE_PUBLIC
00982 
00983 typedef struct thread * rb_thread_t;
00984 static rb_thread_t curr_thread = 0;
00985 static rb_thread_t main_thread;
00986 static void scope_dup (struct SCOPE *);
00987 
00988 #define POP_SCOPE()                     \
00989     if (ruby_scope->flags & SCOPE_DONT_RECYCLE) {\
00990         if (_old) scope_dup(_old);      \
00991     }                                   \
00992     if (!(ruby_scope->flags & SCOPE_MALLOC)) {\
00993         ruby_scope->local_vars = 0;     \
00994         ruby_scope->local_tbl  = 0;     \
00995         if (!(ruby_scope->flags & SCOPE_DONT_RECYCLE) && \
00996             ruby_scope != top_scope) {  \
00997             rb_gc_force_recycle((VALUE)ruby_scope);\
00998         }                               \
00999     }                                   \
01000     ruby_scope->flags |= SCOPE_NOSTACK; \
01001     ruby_scope = _old;                  \
01002     scope_vmode = _vmode;               \
01003 } while (0)
01004 
01005 static VALUE rb_eval (VALUE,NODE*);
01006 static VALUE eval (VALUE,VALUE,VALUE,char*,int);
01007 static NODE *compile (VALUE, char*, int);
01008 
01009 static VALUE rb_yield_0 (VALUE, VALUE, VALUE, int, int);
01010 
01011 #define YIELD_LAMBDA_CALL 1
01012 #define YIELD_PROC_CALL   2
01013 #define YIELD_PUBLIC_DEF  4
01014 #define YIELD_FUNC_AVALUE 1
01015 #define YIELD_FUNC_SVALUE 2
01016 
01017 static VALUE rb_call (VALUE,VALUE,ID,int,const VALUE*,int);
01018 static VALUE module_setup (VALUE,NODE*);
01019 
01020 static VALUE massign (VALUE,NODE*,VALUE,int);
01021 static void assign (VALUE,NODE*,VALUE,int);
01022 
01023 static VALUE trace_func = 0;
01024 static int tracing = 0;
01025 static void call_trace_func (char*,NODE*,VALUE,ID,VALUE);
01026 
01027 #if 0
01028 #define SET_CURRENT_SOURCE() (ruby_sourcefile = ruby_current_node->nd_file, \
01029                               ruby_sourceline = nd_line(ruby_current_node))
01030 #else
01031 #define SET_CURRENT_SOURCE() ((void)0)
01032 #endif
01033 
01034 void
01035 ruby_set_current_source()
01036 {
01037     if (ruby_current_node) {
01038         ruby_sourcefile = ruby_current_node->nd_file;
01039         ruby_sourceline = nd_line(ruby_current_node);
01040     }
01041 }
01042 
01043 static void
01044 #ifdef HAVE_STDARG_PROTOTYPES
01045 warn_printf(const char *fmt, ...)
01046 #else
01047 warn_printf(fmt, va_alist)
01048     const char *fmt;
01049     va_dcl
01050 #endif
01051 {
01052     char buf[BUFSIZ];
01053     va_list args;
01054 
01055     va_init_list(args, fmt);
01056     vsnprintf(buf, BUFSIZ, fmt, args);
01057     va_end(args);
01058     rb_write_error(buf);
01059 }
01060 
01061 #define warn_print(x) rb_write_error(x)
01062 #define warn_print2(x,l) rb_write_error2(x,l)
01063 
01064 static void
01065 error_pos()
01066 {
01067     ruby_set_current_source();
01068     if (ruby_sourcefile) {
01069         if (ruby_frame->last_func) {
01070             warn_printf("%s:%d:in `%s'", ruby_sourcefile, ruby_sourceline,
01071                         rb_id2name(ruby_frame->last_func));
01072         }
01073         else if (ruby_sourceline == 0) {
01074             warn_printf("%s", ruby_sourcefile);
01075         }
01076         else {
01077             warn_printf("%s:%d", ruby_sourcefile, ruby_sourceline);
01078         }
01079     }
01080 }
01081 
01082 static VALUE
01083 get_backtrace(info)
01084     VALUE info;
01085 {
01086     if (NIL_P(info)) return Qnil;
01087     info = rb_funcall(info, rb_intern("backtrace"), 0);
01088     if (NIL_P(info)) return Qnil;
01089     return rb_check_array_type(info);
01090 }
01091 
01092 static void
01093 set_backtrace(info, bt)
01094     VALUE info, bt;
01095 {
01096     rb_funcall(info, rb_intern("set_backtrace"), 1, bt);
01097 }
01098 
01099 static void
01100 error_print()
01101 {
01102     VALUE errat = Qnil;         /* OK */
01103     volatile VALUE eclass, e;
01104     char *einfo;
01105     long elen;
01106 
01107     if (NIL_P(ruby_errinfo)) return;
01108 
01109     PUSH_TAG(PROT_NONE);
01110     if (EXEC_TAG() == 0) {
01111         errat = get_backtrace(ruby_errinfo);
01112     }
01113     else {
01114         errat = Qnil;
01115     }
01116     if (EXEC_TAG()) goto error;
01117     if (NIL_P(errat)){
01118         ruby_set_current_source();
01119         if (ruby_sourcefile)
01120             warn_printf("%s:%d", ruby_sourcefile, ruby_sourceline);
01121         else
01122             warn_printf("%d", ruby_sourceline);
01123     }
01124     else if (RARRAY(errat)->len == 0) {
01125         error_pos();
01126     }
01127     else {
01128         VALUE mesg = RARRAY(errat)->ptr[0];
01129 
01130         if (NIL_P(mesg)) error_pos();
01131         else {
01132             warn_print2(RSTRING(mesg)->ptr, RSTRING(mesg)->len);
01133         }
01134     }
01135 
01136     eclass = CLASS_OF(ruby_errinfo);
01137     if (EXEC_TAG() == 0) {
01138         e = rb_funcall(ruby_errinfo, rb_intern("message"), 0, 0);
01139         StringValue(e);
01140         einfo = RSTRING(e)->ptr;
01141         elen = RSTRING(e)->len;
01142     }
01143     else {
01144         einfo = "";
01145         elen = 0;
01146     }
01147     if (EXEC_TAG()) goto error;
01148     if (eclass == rb_eRuntimeError && elen == 0) {
01149         warn_print(": unhandled exception\n");
01150     }
01151     else {
01152         VALUE epath;
01153 
01154         epath = rb_class_name(eclass);
01155         if (elen == 0) {
01156             warn_print(": ");
01157             warn_print2(RSTRING(epath)->ptr, RSTRING(epath)->len);
01158             warn_print("\n");
01159         }
01160         else {
01161             char *tail  = 0;
01162             long len = elen;
01163 
01164             if (RSTRING(epath)->ptr[0] == '#') epath = 0;
01165             if (tail = memchr(einfo, '\n', elen)) {
01166                 len = tail - einfo;
01167                 tail++;         /* skip newline */
01168             }
01169             warn_print(": ");
01170             warn_print2(einfo, len);
01171             if (epath) {
01172                 warn_print(" (");
01173                 warn_print2(RSTRING(epath)->ptr, RSTRING(epath)->len);
01174                 warn_print(")\n");
01175             }
01176             if (tail) {
01177                 warn_print2(tail, elen-len-1);
01178             }
01179         }
01180     }
01181 
01182     if (!NIL_P(errat)) {
01183         long i;
01184         struct RArray *ep = RARRAY(errat);
01185 
01186 #define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)
01187 #define TRACE_HEAD 8
01188 #define TRACE_TAIL 5
01189 
01190         ep = RARRAY(errat);
01191         for (i=1; i<ep->len; i++) {
01192             if (TYPE(ep->ptr[i]) == T_STRING) {
01193                 warn_printf("\tfrom %s\n", RSTRING(ep->ptr[i])->ptr);
01194             }
01195             if (i == TRACE_HEAD && ep->len > TRACE_MAX) {
01196                 warn_printf("\t ... %ld levels...\n",
01197                         ep->len - TRACE_HEAD - TRACE_TAIL);
01198                 i = ep->len - TRACE_TAIL;
01199             }
01200         }
01201     }
01202   error:
01203     POP_TAG();
01204 }
01205 
01206 #if defined(__APPLE__)
01207 #define environ (*_NSGetEnviron())
01208 #elif !defined(_WIN32) && !defined(__MACOS__) || defined(_WIN32_WCE)
01209 extern char **environ;
01210 #endif
01211 char **rb_origenviron;
01212 
01213 void rb_call_inits (void);
01214 void Init_stack (VALUE*);
01215 void Init_heap (void);
01216 void Init_ext (void);
01217 
01218 #ifdef HAVE_NATIVETHREAD
01219 static rb_nativethread_t ruby_thid;
01220 int 
01221 is_ruby_native_thread() {
01222     return NATIVETHREAD_EQUAL(ruby_thid, NATIVETHREAD_CURRENT());
01223 }
01224 #endif
01225 
01226 void
01227 ruby_init()
01228 {
01229     static int initialized = 0;
01230     static struct FRAME frame;
01231     static struct iter iter;
01232     int state;
01233 
01234     if (initialized)
01235         return;
01236     initialized = 1;
01237 #ifdef HAVE_NATIVETHREAD
01238     ruby_thid = NATIVETHREAD_CURRENT();
01239 #endif
01240 
01241     ruby_frame = top_frame = &frame;
01242     ruby_iter = &iter;
01243 
01244 #ifdef __MACOS__
01245     rb_origenviron = 0;
01246 #else
01247     rb_origenviron = environ;
01248 #endif
01249 
01250     Init_stack((void*)&state);
01251     Init_heap();
01252     PUSH_SCOPE();
01253     ruby_scope->local_vars = 0;
01254     ruby_scope->local_tbl  = 0;
01255     top_scope = ruby_scope;
01256     /* default visibility is private at toplevel */
01257     SCOPE_SET(SCOPE_PRIVATE);
01258 
01259     PUSH_TAG(PROT_NONE);
01260     if ((state = EXEC_TAG()) == 0) {
01261         rb_call_inits();
01262         ruby_class = rb_cObject;
01263         ruby_frame->self = ruby_top_self;
01264         top_cref = rb_node_newnode(NODE_CREF,rb_cObject,0,0);
01265         ruby_cref = top_cref;
01266         rb_define_global_const("TOPLEVEL_BINDING", rb_f_binding(ruby_top_self));
01267 #ifdef __MACOS__
01268         _macruby_init();
01269 #elif defined(__VMS)
01270     _vmsruby_init();
01271 #endif
01272         ruby_prog_init();
01273         ALLOW_INTS;
01274     }
01275     POP_TAG();
01276     if (state) {
01277         error_print();
01278         exit(EXIT_FAILURE);
01279     }
01280     POP_SCOPE();
01281     ruby_scope = top_scope;
01282     top_scope->flags &= ~SCOPE_NOSTACK;
01283     ruby_running = 1;
01284 }
01285 
01286 static VALUE
01287 eval_node(self, node)
01288     VALUE self;
01289     NODE *node;
01290 {
01291     NODE *beg_tree = ruby_eval_tree_begin;
01292 
01293     ruby_eval_tree_begin = 0;
01294     if (beg_tree) {
01295         rb_eval(self, beg_tree);
01296     }
01297 
01298     if (!node) return Qnil;
01299     return rb_eval(self, node);
01300 }
01301 
01302 int ruby_in_eval;
01303 
01304 static void rb_thread_cleanup (void);
01305 static void rb_thread_wait_other_threads (void);
01306 
01307 static int thread_set_raised();
01308 static int thread_reset_raised();
01309 
01310 static VALUE exception_error;
01311 static VALUE sysstack_error;
01312 
01313 static int
01314 error_handle(ex)
01315     int ex;
01316 {
01317     int status = EXIT_FAILURE;
01318 
01319     if (thread_set_raised()) return EXIT_FAILURE;
01320     switch (ex & TAG_MASK) {
01321       case 0:
01322         status = EXIT_SUCCESS;
01323         break;
01324 
01325       case TAG_RETURN:
01326         error_pos();
01327         warn_print(": unexpected return\n");
01328         break;
01329       case TAG_NEXT:
01330         error_pos();
01331         warn_print(": unexpected next\n");
01332         break;
01333       case TAG_BREAK:
01334         error_pos();
01335         warn_print(": unexpected break\n");
01336         break;
01337       case TAG_REDO:
01338         error_pos();
01339         warn_print(": unexpected redo\n");
01340         break;
01341       case TAG_RETRY:
01342         error_pos();
01343         warn_print(": retry outside of rescue clause\n");
01344         break;
01345       case TAG_THROW:
01346         if (prot_tag && prot_tag->frame && prot_tag->frame->node) {
01347             NODE *tag = prot_tag->frame->node;
01348             warn_printf("%s:%d: uncaught throw\n",
01349                     tag->nd_file, nd_line(tag));
01350