Ruby  2.5.0dev(2017-10-22revision60238)
load.c
Go to the documentation of this file.
1 /*
2  * load methods from eval.c
3  */
4 
5 #include "internal.h"
6 #include "ruby/util.h"
7 #include "dln.h"
8 #include "eval_intern.h"
9 #include "probes.h"
10 
11 static VALUE ruby_dln_librefs;
12 
13 #define IS_RBEXT(e) (strcmp((e), ".rb") == 0)
14 #define IS_SOEXT(e) (strcmp((e), ".so") == 0 || strcmp((e), ".o") == 0)
15 #ifdef DLEXT2
16 #define IS_DLEXT(e) (strcmp((e), DLEXT) == 0 || strcmp((e), DLEXT2) == 0)
17 #else
18 #define IS_DLEXT(e) (strcmp((e), DLEXT) == 0)
19 #endif
20 
21 static const char *const loadable_ext[] = {
22  ".rb", DLEXT,
23 #ifdef DLEXT2
24  DLEXT2,
25 #endif
26  0
27 };
28 
29 VALUE
31 {
32  VALUE load_path = GET_VM()->load_path;
33  return load_path;
34 }
35 
41 };
42 
43 /* Construct expanded load path and store it to cache.
44  We rebuild load path partially if the cache is invalid.
45  We don't cache non string object and expand it every time. We ensure that
46  string objects in $LOAD_PATH are frozen.
47  */
48 static void
49 rb_construct_expanded_load_path(enum expand_type type, int *has_relative, int *has_non_cache)
50 {
51  rb_vm_t *vm = GET_VM();
52  VALUE load_path = vm->load_path;
53  VALUE expanded_load_path = vm->expanded_load_path;
54  VALUE ary;
55  long i;
56  int level = rb_safe_level();
57 
58  ary = rb_ary_tmp_new(RARRAY_LEN(load_path));
59  for (i = 0; i < RARRAY_LEN(load_path); ++i) {
60  VALUE path, as_str, expanded_path;
61  int is_string, non_cache;
62  char *as_cstr;
63  as_str = path = RARRAY_AREF(load_path, i);
64  is_string = RB_TYPE_P(path, T_STRING) ? 1 : 0;
65  non_cache = !is_string ? 1 : 0;
66  as_str = rb_get_path_check_to_string(path, level);
67  as_cstr = RSTRING_PTR(as_str);
68 
69  if (!non_cache) {
70  if ((type == EXPAND_RELATIVE &&
71  rb_is_absolute_path(as_cstr)) ||
72  (type == EXPAND_HOME &&
73  (!as_cstr[0] || as_cstr[0] != '~')) ||
74  (type == EXPAND_NON_CACHE)) {
75  /* Use cached expanded path. */
76  rb_ary_push(ary, RARRAY_AREF(expanded_load_path, i));
77  continue;
78  }
79  }
80  if (!*has_relative && !rb_is_absolute_path(as_cstr))
81  *has_relative = 1;
82  if (!*has_non_cache && non_cache)
83  *has_non_cache = 1;
84  /* Freeze only string object. We expand other objects every time. */
85  if (is_string)
86  rb_str_freeze(path);
87  as_str = rb_get_path_check_convert(path, as_str, level);
88  expanded_path = rb_check_realpath(Qnil, as_str);
89  if (NIL_P(expanded_path)) expanded_path = as_str;
90  rb_ary_push(ary, rb_fstring(expanded_path));
91  }
92  rb_obj_freeze(ary);
93  vm->expanded_load_path = ary;
95 }
96 
97 static VALUE
98 load_path_getcwd(void)
99 {
100  char *cwd = my_getcwd();
101  VALUE cwd_str = rb_filesystem_str_new_cstr(cwd);
102  xfree(cwd);
103  return cwd_str;
104 }
105 
106 VALUE
108 {
109  rb_vm_t *vm = GET_VM();
110  const VALUE non_cache = Qtrue;
111 
113  /* The load path was modified. Rebuild the expanded load path. */
114  int has_relative = 0, has_non_cache = 0;
115  rb_construct_expanded_load_path(EXPAND_ALL, &has_relative, &has_non_cache);
116  if (has_relative) {
117  vm->load_path_check_cache = load_path_getcwd();
118  }
119  else if (has_non_cache) {
120  /* Non string object. */
121  vm->load_path_check_cache = non_cache;
122  }
123  else {
124  vm->load_path_check_cache = 0;
125  }
126  }
127  else if (vm->load_path_check_cache == non_cache) {
128  int has_relative = 1, has_non_cache = 1;
129  /* Expand only non-cacheable objects. */
130  rb_construct_expanded_load_path(EXPAND_NON_CACHE,
131  &has_relative, &has_non_cache);
132  }
133  else if (vm->load_path_check_cache) {
134  int has_relative = 1, has_non_cache = 1;
135  VALUE cwd = load_path_getcwd();
136  if (!rb_str_equal(vm->load_path_check_cache, cwd)) {
137  /* Current working directory or filesystem encoding was changed.
138  Expand relative load path and non-cacheable objects again. */
139  vm->load_path_check_cache = cwd;
140  rb_construct_expanded_load_path(EXPAND_RELATIVE,
141  &has_relative, &has_non_cache);
142  }
143  else {
144  /* Expand only tilde (User HOME) and non-cacheable objects. */
145  rb_construct_expanded_load_path(EXPAND_HOME,
146  &has_relative, &has_non_cache);
147  }
148  }
149  return vm->expanded_load_path;
150 }
151 
152 static VALUE
153 load_path_getter(ID id, rb_vm_t *vm)
154 {
155  return vm->load_path;
156 }
157 
158 static VALUE
159 get_loaded_features(void)
160 {
161  return GET_VM()->loaded_features;
162 }
163 
164 static void
165 reset_loaded_features_snapshot(void)
166 {
167  rb_vm_t *vm = GET_VM();
169 }
170 
171 static struct st_table *
172 get_loaded_features_index_raw(void)
173 {
174  return GET_VM()->loaded_features_index;
175 }
176 
177 static st_table *
178 get_loading_table(void)
179 {
180  return GET_VM()->loading_table;
181 }
182 
183 static void
184 features_index_add_single(VALUE short_feature, VALUE offset)
185 {
186  struct st_table *features_index;
187  VALUE this_feature_index = Qnil;
188  char *short_feature_cstr;
189 
190  Check_Type(offset, T_FIXNUM);
191  Check_Type(short_feature, T_STRING);
192  short_feature_cstr = StringValueCStr(short_feature);
193 
194  features_index = get_loaded_features_index_raw();
195  st_lookup(features_index, (st_data_t)short_feature_cstr, (st_data_t *)&this_feature_index);
196 
197  if (NIL_P(this_feature_index)) {
198  st_insert(features_index, (st_data_t)ruby_strdup(short_feature_cstr), (st_data_t)offset);
199  }
200  else if (RB_TYPE_P(this_feature_index, T_FIXNUM)) {
201  VALUE feature_indexes[2];
202  feature_indexes[0] = this_feature_index;
203  feature_indexes[1] = offset;
204  this_feature_index = (VALUE)xcalloc(1, sizeof(struct RArray));
205  RBASIC(this_feature_index)->flags = T_ARRAY; /* fake VALUE, do not mark/sweep */
206  rb_ary_cat(this_feature_index, feature_indexes, numberof(feature_indexes));
207  st_insert(features_index, (st_data_t)short_feature_cstr, (st_data_t)this_feature_index);
208  }
209  else {
210  Check_Type(this_feature_index, T_ARRAY);
211  rb_ary_push(this_feature_index, offset);
212  }
213 }
214 
215 /* Add to the loaded-features index all the required entries for
216  `feature`, located at `offset` in $LOADED_FEATURES. We add an
217  index entry at each string `short_feature` for which
218  feature == "#{prefix}#{short_feature}#{ext}"
219  where `ext` is empty or matches %r{^\.[^./]*$}, and `prefix` is empty
220  or ends in '/'. This maintains the invariant that `rb_feature_p()`
221  relies on for its fast lookup.
222 */
223 static void
224 features_index_add(VALUE feature, VALUE offset)
225 {
226  VALUE short_feature;
227  const char *feature_str, *feature_end, *ext, *p;
228 
229  feature_str = StringValuePtr(feature);
230  feature_end = feature_str + RSTRING_LEN(feature);
231 
232  for (ext = feature_end; ext > feature_str; ext--)
233  if (*ext == '.' || *ext == '/')
234  break;
235  if (*ext != '.')
236  ext = NULL;
237  /* Now `ext` points to the only string matching %r{^\.[^./]*$} that is
238  at the end of `feature`, or is NULL if there is no such string. */
239 
240  p = ext ? ext : feature_end;
241  while (1) {
242  long beg;
243 
244  p--;
245  while (p >= feature_str && *p != '/')
246  p--;
247  if (p < feature_str)
248  break;
249  /* Now *p == '/'. We reach this point for every '/' in `feature`. */
250  beg = p + 1 - feature_str;
251  short_feature = rb_str_subseq(feature, beg, feature_end - p - 1);
252  features_index_add_single(short_feature, offset);
253  if (ext) {
254  short_feature = rb_str_subseq(feature, beg, ext - p - 1);
255  features_index_add_single(short_feature, offset);
256  }
257  }
258  features_index_add_single(feature, offset);
259  if (ext) {
260  short_feature = rb_str_subseq(feature, 0, ext - feature_str);
261  features_index_add_single(short_feature, offset);
262  }
263 }
264 
265 static int
266 loaded_features_index_clear_i(st_data_t key, st_data_t val, st_data_t arg)
267 {
268  VALUE obj = (VALUE)val;
269  if (!SPECIAL_CONST_P(obj)) {
270  rb_ary_free(obj);
271  xfree((void *)obj);
272  }
273  xfree((char *)key);
274  return ST_DELETE;
275 }
276 
277 static st_table *
278 get_loaded_features_index(void)
279 {
280  VALUE features;
281  int i;
282  rb_vm_t *vm = GET_VM();
283 
285  /* The sharing was broken; something (other than us in rb_provide_feature())
286  modified loaded_features. Rebuild the index. */
287  st_foreach(vm->loaded_features_index, loaded_features_index_clear_i, 0);
288  features = vm->loaded_features;
289  for (i = 0; i < RARRAY_LEN(features); i++) {
290  VALUE entry, as_str;
291  as_str = entry = rb_ary_entry(features, i);
292  StringValue(as_str);
293  as_str = rb_fstring(rb_str_freeze(as_str));
294  if (as_str != entry)
295  rb_ary_store(features, i, as_str);
296  features_index_add(as_str, INT2FIX(i));
297  }
298  reset_loaded_features_snapshot();
299  }
300  return vm->loaded_features_index;
301 }
302 
303 /* This searches `load_path` for a value such that
304  name == "#{load_path[i]}/#{feature}"
305  if `feature` is a suffix of `name`, or otherwise
306  name == "#{load_path[i]}/#{feature}#{ext}"
307  for an acceptable string `ext`. It returns
308  `load_path[i].to_str` if found, else 0.
309 
310  If type is 's', then `ext` is acceptable only if IS_DLEXT(ext);
311  if 'r', then only if IS_RBEXT(ext); otherwise `ext` may be absent
312  or have any value matching `%r{^\.[^./]*$}`.
313 */
314 static VALUE
315 loaded_feature_path(const char *name, long vlen, const char *feature, long len,
316  int type, VALUE load_path)
317 {
318  long i;
319  long plen;
320  const char *e;
321 
322  if (vlen < len+1) return 0;
323  if (strchr(feature, '.') && !strncmp(name+(vlen-len), feature, len)) {
324  plen = vlen - len;
325  }
326  else {
327  for (e = name + vlen; name != e && *e != '.' && *e != '/'; --e);
328  if (*e != '.' ||
329  e-name < len ||
330  strncmp(e-len, feature, len))
331  return 0;
332  plen = e - name - len;
333  }
334  if (plen > 0 && name[plen-1] != '/') {
335  return 0;
336  }
337  if (type == 's' ? !IS_DLEXT(&name[plen+len]) :
338  type == 'r' ? !IS_RBEXT(&name[plen+len]) :
339  0) {
340  return 0;
341  }
342  /* Now name == "#{prefix}/#{feature}#{ext}" where ext is acceptable
343  (possibly empty) and prefix is some string of length plen. */
344 
345  if (plen > 0) --plen; /* exclude '.' */
346  for (i = 0; i < RARRAY_LEN(load_path); ++i) {
347  VALUE p = RARRAY_AREF(load_path, i);
348  const char *s = StringValuePtr(p);
349  long n = RSTRING_LEN(p);
350 
351  if (n != plen) continue;
352  if (n && strncmp(name, s, n)) continue;
353  return p;
354  }
355  return 0;
356 }
357 
359  const char *name;
360  long len;
361  int type;
363  const char *result;
364 };
365 
366 static int
367 loaded_feature_path_i(st_data_t v, st_data_t b, st_data_t f)
368 {
369  const char *s = (const char *)v;
370  struct loaded_feature_searching *fp = (struct loaded_feature_searching *)f;
371  VALUE p = loaded_feature_path(s, strlen(s), fp->name, fp->len,
372  fp->type, fp->load_path);
373  if (!p) return ST_CONTINUE;
374  fp->result = s;
375  return ST_STOP;
376 }
377 
378 static int
379 rb_feature_p(const char *feature, const char *ext, int rb, int expanded, const char **fn)
380 {
381  VALUE features, this_feature_index = Qnil, v, p, load_path = 0;
382  const char *f, *e;
383  long i, len, elen, n;
384  st_table *loading_tbl, *features_index;
385  st_data_t data;
386  int type;
387 
388  if (fn) *fn = 0;
389  if (ext) {
390  elen = strlen(ext);
391  len = strlen(feature) - elen;
392  type = rb ? 'r' : 's';
393  }
394  else {
395  len = strlen(feature);
396  elen = 0;
397  type = 0;
398  }
399  features = get_loaded_features();
400  features_index = get_loaded_features_index();
401 
402  st_lookup(features_index, (st_data_t)feature, (st_data_t *)&this_feature_index);
403  /* We search `features` for an entry such that either
404  "#{features[i]}" == "#{load_path[j]}/#{feature}#{e}"
405  for some j, or
406  "#{features[i]}" == "#{feature}#{e}"
407  Here `e` is an "allowed" extension -- either empty or one
408  of the extensions accepted by IS_RBEXT, IS_SOEXT, or
409  IS_DLEXT. Further, if `ext && rb` then `IS_RBEXT(e)`,
410  and if `ext && !rb` then `IS_SOEXT(e) || IS_DLEXT(e)`.
411 
412  If `expanded`, then only the latter form (without load_path[j])
413  is accepted. Otherwise either form is accepted, *unless* `ext`
414  is false and an otherwise-matching entry of the first form is
415  preceded by an entry of the form
416  "#{features[i2]}" == "#{load_path[j2]}/#{feature}#{e2}"
417  where `e2` matches %r{^\.[^./]*$} but is not an allowed extension.
418  After a "distractor" entry of this form, only entries of the
419  form "#{feature}#{e}" are accepted.
420 
421  In `rb_provide_feature()` and `get_loaded_features_index()` we
422  maintain an invariant that the array `this_feature_index` will
423  point to every entry in `features` which has the form
424  "#{prefix}#{feature}#{e}"
425  where `e` is empty or matches %r{^\.[^./]*$}, and `prefix` is empty
426  or ends in '/'. This includes both match forms above, as well
427  as any distractors, so we may ignore all other entries in `features`.
428  */
429  if (!NIL_P(this_feature_index)) {
430  for (i = 0; ; i++) {
431  VALUE entry;
432  long index;
433  if (RB_TYPE_P(this_feature_index, T_ARRAY)) {
434  if (i >= RARRAY_LEN(this_feature_index)) break;
435  entry = RARRAY_AREF(this_feature_index, i);
436  }
437  else {
438  if (i > 0) break;
439  entry = this_feature_index;
440  }
441  index = FIX2LONG(entry);
442 
443  v = RARRAY_AREF(features, index);
444  f = StringValuePtr(v);
445  if ((n = RSTRING_LEN(v)) < len) continue;
446  if (strncmp(f, feature, len) != 0) {
447  if (expanded) continue;
448  if (!load_path) load_path = rb_get_expanded_load_path();
449  if (!(p = loaded_feature_path(f, n, feature, len, type, load_path)))
450  continue;
451  expanded = 1;
452  f += RSTRING_LEN(p) + 1;
453  }
454  if (!*(e = f + len)) {
455  if (ext) continue;
456  return 'u';
457  }
458  if (*e != '.') continue;
459  if ((!rb || !ext) && (IS_SOEXT(e) || IS_DLEXT(e))) {
460  return 's';
461  }
462  if ((rb || !ext) && (IS_RBEXT(e))) {
463  return 'r';
464  }
465  }
466  }
467 
468  loading_tbl = get_loading_table();
469  f = 0;
470  if (!expanded) {
471  struct loaded_feature_searching fs;
472  fs.name = feature;
473  fs.len = len;
474  fs.type = type;
475  fs.load_path = load_path ? load_path : rb_get_expanded_load_path();
476  fs.result = 0;
477  st_foreach(loading_tbl, loaded_feature_path_i, (st_data_t)&fs);
478  if ((f = fs.result) != 0) {
479  if (fn) *fn = f;
480  goto loading;
481  }
482  }
483  if (st_get_key(loading_tbl, (st_data_t)feature, &data)) {
484  if (fn) *fn = (const char*)data;
485  loading:
486  if (!ext) return 'u';
487  return !IS_RBEXT(ext) ? 's' : 'r';
488  }
489  else {
490  VALUE bufstr;
491  char *buf;
492  static const char so_ext[][4] = {
493  ".so", ".o",
494  };
495 
496  if (ext && *ext) return 0;
497  bufstr = rb_str_tmp_new(len + DLEXT_MAXLEN);
498  buf = RSTRING_PTR(bufstr);
499  MEMCPY(buf, feature, char, len);
500  for (i = 0; (e = loadable_ext[i]) != 0; i++) {
501  strlcpy(buf + len, e, DLEXT_MAXLEN + 1);
502  if (st_get_key(loading_tbl, (st_data_t)buf, &data)) {
503  rb_str_resize(bufstr, 0);
504  if (fn) *fn = (const char*)data;
505  return i ? 's' : 'r';
506  }
507  }
508  for (i = 0; i < numberof(so_ext); i++) {
509  strlcpy(buf + len, so_ext[i], DLEXT_MAXLEN + 1);
510  if (st_get_key(loading_tbl, (st_data_t)buf, &data)) {
511  rb_str_resize(bufstr, 0);
512  if (fn) *fn = (const char*)data;
513  return 's';
514  }
515  }
516  rb_str_resize(bufstr, 0);
517  }
518  return 0;
519 }
520 
521 int
522 rb_provided(const char *feature)
523 {
524  return rb_feature_provided(feature, 0);
525 }
526 
527 int
528 rb_feature_provided(const char *feature, const char **loading)
529 {
530  const char *ext = strrchr(feature, '.');
531  VALUE fullpath = 0;
532 
533  if (*feature == '.' &&
534  (feature[1] == '/' || strncmp(feature+1, "./", 2) == 0)) {
535  fullpath = rb_file_expand_path_fast(rb_get_path(rb_str_new2(feature)), Qnil);
536  feature = RSTRING_PTR(fullpath);
537  }
538  if (ext && !strchr(ext, '/')) {
539  if (IS_RBEXT(ext)) {
540  if (rb_feature_p(feature, ext, TRUE, FALSE, loading)) return TRUE;
541  return FALSE;
542  }
543  else if (IS_SOEXT(ext) || IS_DLEXT(ext)) {
544  if (rb_feature_p(feature, ext, FALSE, FALSE, loading)) return TRUE;
545  return FALSE;
546  }
547  }
548  if (rb_feature_p(feature, 0, TRUE, FALSE, loading))
549  return TRUE;
550  RB_GC_GUARD(fullpath);
551  return FALSE;
552 }
553 
554 static void
555 rb_provide_feature(VALUE feature)
556 {
557  VALUE features;
558 
559  features = get_loaded_features();
560  if (OBJ_FROZEN(features)) {
562  "$LOADED_FEATURES is frozen; cannot append feature");
563  }
564  rb_str_freeze(feature);
565 
566  rb_ary_push(features, rb_fstring(feature));
567  features_index_add(feature, INT2FIX(RARRAY_LEN(features)-1));
568  reset_loaded_features_snapshot();
569 }
570 
571 void
572 rb_provide(const char *feature)
573 {
574  rb_provide_feature(rb_fstring_cstr(feature));
575 }
576 
577 NORETURN(static void load_failed(VALUE));
578 const rb_iseq_t *rb_iseq_load_iseq(VALUE fname);
579 
580 static int
581 rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap)
582 {
583  enum ruby_tag_type state;
584  volatile VALUE wrapper = th->top_wrapper;
585  volatile VALUE self = th->top_self;
586 #if !defined __GNUC__
587  rb_thread_t *volatile th0 = th;
588 #endif
589 
590  th->ec.errinfo = Qnil; /* ensure */
591 
592  if (!wrap) {
593  th->top_wrapper = 0;
594  }
595  else {
596  /* load in anonymous module as toplevel */
598  th->top_wrapper = rb_module_new();
600  }
601 
602  TH_PUSH_TAG(th);
603  state = EXEC_TAG();
604  if (state == TAG_NONE) {
605  NODE *node;
606  const rb_iseq_t *iseq;
607 
608  if ((iseq = rb_iseq_load_iseq(fname)) != NULL) {
609  /* OK */
610  }
611  else {
612  VALUE parser = rb_parser_new();
613  rb_parser_set_context(parser, NULL, FALSE);
614  node = (NODE *)rb_parser_load_file(parser, fname);
615  iseq = rb_iseq_new_top(node, rb_fstring_cstr("<top (required)>"),
616  fname, rb_realpath_internal(Qnil, fname, 1), NULL);
617  }
618  rb_iseq_eval(iseq);
619  }
620  TH_POP_TAG();
621 
622 #if !defined __GNUC__
623  th = th0;
624  fname = RB_GC_GUARD(fname);
625 #endif
626  th->top_self = self;
627  th->top_wrapper = wrapper;
628 
629  if (state) {
630  /* usually state == TAG_RAISE only, except for
631  * rb_iseq_load_iseq case */
633  if (NIL_P(exc)) return state;
634  th->ec.errinfo = exc;
635  return TAG_RAISE;
636  }
637 
638  if (!NIL_P(th->ec.errinfo)) {
639  /* exception during load */
640  return TAG_RAISE;
641  }
642  return state;
643 }
644 
645 static void
646 rb_load_internal(VALUE fname, int wrap)
647 {
648  rb_thread_t *curr_th = GET_THREAD();
649  int state = rb_load_internal0(curr_th, fname, wrap);
650  if (state) {
651  if (state == TAG_RAISE) rb_exc_raise(curr_th->ec.errinfo);
652  TH_JUMP_TAG(curr_th, state);
653  }
654 }
655 
656 static VALUE
657 file_to_load(VALUE fname)
658 {
659  VALUE tmp = rb_find_file(FilePathValue(fname));
660  if (!tmp) load_failed(fname);
661  return tmp;
662 }
663 
664 void
665 rb_load(VALUE fname, int wrap)
666 {
667  rb_load_internal(file_to_load(fname), wrap);
668 }
669 
670 void
671 rb_load_protect(VALUE fname, int wrap, int *pstate)
672 {
673  enum ruby_tag_type state;
674  volatile VALUE path = 0;
675 
676  PUSH_TAG();
677  if ((state = EXEC_TAG()) == TAG_NONE) {
678  path = file_to_load(fname);
679  }
680  POP_TAG();
681 
682  if (state == TAG_NONE) state = rb_load_internal0(GET_THREAD(), path, wrap);
683  if (state != TAG_NONE) *pstate = state;
684 }
685 
686 /*
687  * call-seq:
688  * load(filename, wrap=false) -> true
689  *
690  * Loads and executes the Ruby
691  * program in the file _filename_. If the filename does not
692  * resolve to an absolute path, the file is searched for in the library
693  * directories listed in <code>$:</code>. If the optional _wrap_
694  * parameter is +true+, the loaded script will be executed
695  * under an anonymous module, protecting the calling program's global
696  * namespace. In no circumstance will any local variables in the loaded
697  * file be propagated to the loading environment.
698  */
699 
700 static VALUE
701 rb_f_load(int argc, VALUE *argv)
702 {
703  VALUE fname, wrap, path, orig_fname;
704 
705  rb_scan_args(argc, argv, "11", &fname, &wrap);
706 
707  orig_fname = rb_get_path_check_to_string(fname, rb_safe_level());
708  fname = rb_str_encode_ospath(orig_fname);
709  RUBY_DTRACE_HOOK(LOAD_ENTRY, RSTRING_PTR(orig_fname));
710 
711  path = rb_find_file(fname);
712  if (!path) {
713  if (!rb_file_load_ok(RSTRING_PTR(fname)))
714  load_failed(orig_fname);
715  path = fname;
716  }
717  rb_load_internal(path, RTEST(wrap));
718 
719  RUBY_DTRACE_HOOK(LOAD_RETURN, RSTRING_PTR(orig_fname));
720 
721  return Qtrue;
722 }
723 
724 extern VALUE rb_mWarning;
725 
726 static char *
727 load_lock(const char *ftptr)
728 {
729  st_data_t data;
730  st_table *loading_tbl = get_loading_table();
731 
732  if (!st_lookup(loading_tbl, (st_data_t)ftptr, &data)) {
733  /* partial state */
734  ftptr = ruby_strdup(ftptr);
736  st_insert(loading_tbl, (st_data_t)ftptr, data);
737  return (char *)ftptr;
738  }
739  else if (imemo_type_p(data, imemo_memo)) {
740  struct MEMO *memo = MEMO_CAST(data);
741  void (*init)(void) = (void (*)(void))memo->u3.func;
743  st_insert(loading_tbl, (st_data_t)ftptr, data);
744  (*init)();
745  return (char *)"";
746  }
747  if (RTEST(ruby_verbose)) {
748  VALUE warning = rb_warning_string("loading in progress, circular require considered harmful - %s", ftptr);
750  rb_warning_warn(rb_mWarning, warning);
751  }
752  switch (rb_thread_shield_wait((VALUE)data)) {
753  case Qfalse:
754  case Qnil:
755  return 0;
756  }
757  return (char *)ftptr;
758 }
759 
760 static int
761 release_thread_shield(st_data_t *key, st_data_t *value, st_data_t done, int existing)
762 {
763  VALUE thread_shield = (VALUE)*value;
764  if (!existing) return ST_STOP;
765  if (done) {
766  rb_thread_shield_destroy(thread_shield);
767  /* Delete the entry even if there are waiting threads, because they
768  * won't load the file and won't delete the entry. */
769  }
770  else if (rb_thread_shield_release(thread_shield)) {
771  /* still in-use */
772  return ST_CONTINUE;
773  }
774  xfree((char *)*key);
775  return ST_DELETE;
776 }
777 
778 static void
779 load_unlock(const char *ftptr, int done)
780 {
781  if (ftptr) {
782  st_data_t key = (st_data_t)ftptr;
783  st_table *loading_tbl = get_loading_table();
784 
785  st_update(loading_tbl, key, release_thread_shield, done);
786  }
787 }
788 
789 
790 /*
791  * call-seq:
792  * require(name) -> true or false
793  *
794  * Loads the given +name+, returning +true+ if successful and +false+ if the
795  * feature is already loaded.
796  *
797  * If the filename does not resolve to an absolute path, it will be searched
798  * for in the directories listed in <code>$LOAD_PATH</code> (<code>$:</code>).
799  *
800  * If the filename has the extension ".rb", it is loaded as a source file; if
801  * the extension is ".so", ".o", or ".dll", or the default shared library
802  * extension on the current platform, Ruby loads the shared library as a
803  * Ruby extension. Otherwise, Ruby tries adding ".rb", ".so", and so on
804  * to the name until found. If the file named cannot be found, a LoadError
805  * will be raised.
806  *
807  * For Ruby extensions the filename given may use any shared library
808  * extension. For example, on Linux the socket extension is "socket.so" and
809  * <code>require 'socket.dll'</code> will load the socket extension.
810  *
811  * The absolute path of the loaded file is added to
812  * <code>$LOADED_FEATURES</code> (<code>$"</code>). A file will not be
813  * loaded again if its path already appears in <code>$"</code>. For example,
814  * <code>require 'a'; require './a'</code> will not load <code>a.rb</code>
815  * again.
816  *
817  * require "my-library.rb"
818  * require "db-driver"
819  *
820  * Any constants or globals within the loaded source file will be available
821  * in the calling program's global namespace. However, local variables will
822  * not be propagated to the loading environment.
823  *
824  */
825 
826 VALUE
828 {
829  return rb_require_safe(fname, rb_safe_level());
830 }
831 
832 /*
833  * call-seq:
834  * require_relative(string) -> true or false
835  *
836  * Ruby tries to load the library named _string_ relative to the requiring
837  * file's path. If the file's path cannot be determined a LoadError is raised.
838  * If a file is loaded +true+ is returned and false otherwise.
839  */
840 VALUE
842 {
844  if (NIL_P(base)) {
845  rb_loaderror("cannot infer basepath");
846  }
847  base = rb_file_dirname(base);
848  return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
849 }
850 
851 static int
852 search_required(VALUE fname, volatile VALUE *path, int safe_level)
853 {
854  VALUE tmp;
855  char *ext, *ftptr;
856  int type, ft = 0;
857  const char *loading;
858 
859  *path = 0;
860  ext = strrchr(ftptr = RSTRING_PTR(fname), '.');
861  if (ext && !strchr(ext, '/')) {
862  if (IS_RBEXT(ext)) {
863  if (rb_feature_p(ftptr, ext, TRUE, FALSE, &loading)) {
864  if (loading) *path = rb_filesystem_str_new_cstr(loading);
865  return 'r';
866  }
867  if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) {
868  ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
869  if (!rb_feature_p(ftptr, ext, TRUE, TRUE, &loading) || loading)
870  *path = tmp;
871  return 'r';
872  }
873  return 0;
874  }
875  else if (IS_SOEXT(ext)) {
876  if (rb_feature_p(ftptr, ext, FALSE, FALSE, &loading)) {
877  if (loading) *path = rb_filesystem_str_new_cstr(loading);
878  return 's';
879  }
880  tmp = rb_str_subseq(fname, 0, ext - RSTRING_PTR(fname));
881 #ifdef DLEXT2
882  OBJ_FREEZE(tmp);
883  if (rb_find_file_ext_safe(&tmp, loadable_ext + 1, safe_level)) {
884  ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
885  if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
886  *path = tmp;
887  return 's';
888  }
889 #else
890  rb_str_cat2(tmp, DLEXT);
891  OBJ_FREEZE(tmp);
892  if ((tmp = rb_find_file_safe(tmp, safe_level)) != 0) {
893  ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
894  if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
895  *path = tmp;
896  return 's';
897  }
898 #endif
899  }
900  else if (IS_DLEXT(ext)) {
901  if (rb_feature_p(ftptr, ext, FALSE, FALSE, &loading)) {
902  if (loading) *path = rb_filesystem_str_new_cstr(loading);
903  return 's';
904  }
905  if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) {
906  ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
907  if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
908  *path = tmp;
909  return 's';
910  }
911  }
912  }
913  else if ((ft = rb_feature_p(ftptr, 0, FALSE, FALSE, &loading)) == 'r') {
914  if (loading) *path = rb_filesystem_str_new_cstr(loading);
915  return 'r';
916  }
917  tmp = fname;
918  type = rb_find_file_ext_safe(&tmp, loadable_ext, safe_level);
919  switch (type) {
920  case 0:
921  if (ft)
922  goto statically_linked;
923  ftptr = RSTRING_PTR(tmp);
924  return rb_feature_p(ftptr, 0, FALSE, TRUE, 0);
925 
926  default:
927  if (ft) {
928  statically_linked:
929  if (loading) *path = rb_filesystem_str_new_cstr(loading);
930  return ft;
931  }
932  case 1:
933  ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
934  if (rb_feature_p(ftptr, ext, !--type, TRUE, &loading) && !loading)
935  break;
936  *path = tmp;
937  }
938  return type ? 's' : 'r';
939 }
940 
941 static void
942 load_failed(VALUE fname)
943 {
944  rb_load_fail(fname, "cannot load such file");
945 }
946 
947 static VALUE
948 load_ext(VALUE path)
949 {
951  return (VALUE)dln_load(RSTRING_PTR(path));
952 }
953 
954 /*
955  * returns
956  * 0: if already loaded (false)
957  * 1: successfully loaded (true)
958  * <0: not found (LoadError)
959  * >1: exception
960  */
961 int
962 rb_require_internal(VALUE fname, int safe)
963 {
964  volatile int result = -1;
965  rb_thread_t *th = GET_THREAD();
966  volatile VALUE errinfo = th->ec.errinfo;
967  enum ruby_tag_type state;
968  struct {
969  int safe;
970  } volatile saved;
971  char *volatile ftptr = 0;
972  VALUE path;
973 
974  fname = rb_get_path_check(fname, safe);
975  path = rb_str_encode_ospath(fname);
976  RUBY_DTRACE_HOOK(REQUIRE_ENTRY, RSTRING_PTR(fname));
977 
978  TH_PUSH_TAG(th);
979  saved.safe = rb_safe_level();
980  if ((state = EXEC_TAG()) == TAG_NONE) {
981  long handle;
982  int found;
983 
985 
986  RUBY_DTRACE_HOOK(FIND_REQUIRE_ENTRY, RSTRING_PTR(fname));
987  found = search_required(path, &path, safe);
988  RUBY_DTRACE_HOOK(FIND_REQUIRE_RETURN, RSTRING_PTR(fname));
989 
990  if (found) {
991  if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) {
992  result = 0;
993  }
994  else if (!*ftptr) {
995  rb_provide_feature(path);
996  result = TAG_RETURN;
997  }
998  else {
999  switch (found) {
1000  case 'r':
1001  state = rb_load_internal0(th, path, 0);
1002  break;
1003 
1004  case 's':
1005  handle = (long)rb_vm_call_cfunc(rb_vm_top_self(), load_ext,
1006  path, VM_BLOCK_HANDLER_NONE, path);
1007  rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
1008  break;
1009  }
1010  if (!state) {
1011  rb_provide_feature(path);
1012  result = TAG_RETURN;
1013  }
1014  }
1015  }
1016  }
1017  TH_POP_TAG();
1018  load_unlock(ftptr, !state);
1019 
1020  rb_set_safe_level_force(saved.safe);
1021  if (state) {
1022  RB_GC_GUARD(fname);
1023  /* never TAG_RETURN */
1024  return state;
1025  }
1026 
1027  th->ec.errinfo = errinfo;
1028 
1029  RUBY_DTRACE_HOOK(REQUIRE_RETURN, RSTRING_PTR(fname));
1030 
1031  return result;
1032 }
1033 
1034 int
1035 ruby_require_internal(const char *fname, unsigned int len)
1036 {
1037  struct RString fake;
1038  VALUE str = rb_setup_fake_str(&fake, fname, len, 0);
1039  int result = rb_require_internal(str, 0);
1041  return result == TAG_RETURN ? 1 : result ? -1 : 0;
1042 }
1043 
1044 VALUE
1045 rb_require_safe(VALUE fname, int safe)
1046 {
1047  int result = rb_require_internal(fname, safe);
1048 
1049  if (result > TAG_RETURN) {
1050  if (result == TAG_RAISE) rb_exc_raise(rb_errinfo());
1051  JUMP_TAG(result);
1052  }
1053  if (result < 0) {
1054  load_failed(fname);
1055  }
1056 
1057  return result ? Qtrue : Qfalse;
1058 }
1059 
1060 VALUE
1061 rb_require(const char *fname)
1062 {
1063  VALUE fn = rb_str_new_cstr(fname);
1064  return rb_require_safe(fn, rb_safe_level());
1065 }
1066 
1067 static int
1068 register_init_ext(st_data_t *key, st_data_t *value, st_data_t init, int existing)
1069 {
1070  const char *name = (char *)*key;
1071  if (existing) {
1072  /* already registered */
1073  rb_warn("%s is already registered", name);
1074  }
1075  else {
1076  *value = (st_data_t)MEMO_NEW(0, 0, init);
1077  *key = (st_data_t)ruby_strdup(name);
1078  }
1079  return ST_CONTINUE;
1080 }
1081 
1082 RUBY_FUNC_EXPORTED void
1083 ruby_init_ext(const char *name, void (*init)(void))
1084 {
1085  st_table *loading_tbl = get_loading_table();
1086 
1087  if (rb_provided(name))
1088  return;
1089  st_update(loading_tbl, (st_data_t)name, register_init_ext, (st_data_t)init);
1090 }
1091 
1092 /*
1093  * call-seq:
1094  * mod.autoload(module, filename) -> nil
1095  *
1096  * Registers _filename_ to be loaded (using <code>Kernel::require</code>)
1097  * the first time that _module_ (which may be a <code>String</code> or
1098  * a symbol) is accessed in the namespace of _mod_.
1099  *
1100  * module A
1101  * end
1102  * A.autoload(:B, "b")
1103  * A::B.doit # autoloads "b"
1104  */
1105 
1106 static VALUE
1107 rb_mod_autoload(VALUE mod, VALUE sym, VALUE file)
1108 {
1109  ID id = rb_to_id(sym);
1110 
1111  FilePathValue(file);
1112  rb_autoload_str(mod, id, file);
1113  return Qnil;
1114 }
1115 
1116 /*
1117  * call-seq:
1118  * mod.autoload?(name) -> String or nil
1119  *
1120  * Returns _filename_ to be loaded if _name_ is registered as
1121  * +autoload+ in the namespace of _mod_.
1122  *
1123  * module A
1124  * end
1125  * A.autoload(:B, "b")
1126  * A.autoload?(:B) #=> "b"
1127  */
1128 
1129 static VALUE
1130 rb_mod_autoload_p(VALUE mod, VALUE sym)
1131 {
1132  ID id = rb_check_id(&sym);
1133  if (!id) {
1134  return Qnil;
1135  }
1136  return rb_autoload_p(mod, id);
1137 }
1138 
1139 /*
1140  * call-seq:
1141  * autoload(module, filename) -> nil
1142  *
1143  * Registers _filename_ to be loaded (using <code>Kernel::require</code>)
1144  * the first time that _module_ (which may be a <code>String</code> or
1145  * a symbol) is accessed.
1146  *
1147  * autoload(:MyModule, "/usr/local/lib/modules/my_module.rb")
1148  */
1149 
1150 static VALUE
1151 rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
1152 {
1153  VALUE klass = rb_class_real(rb_vm_cbase());
1154  if (NIL_P(klass)) {
1155  rb_raise(rb_eTypeError, "Can not set autoload on singleton class");
1156  }
1157  return rb_mod_autoload(klass, sym, file);
1158 }
1159 
1160 /*
1161  * call-seq:
1162  * autoload?(name) -> String or nil
1163  *
1164  * Returns _filename_ to be loaded if _name_ is registered as
1165  * +autoload+.
1166  *
1167  * autoload(:B, "b")
1168  * autoload?(:B) #=> "b"
1169  */
1170 
1171 static VALUE
1172 rb_f_autoload_p(VALUE obj, VALUE sym)
1173 {
1174  /* use rb_vm_cbase() as same as rb_f_autoload. */
1175  VALUE klass = rb_vm_cbase();
1176  if (NIL_P(klass)) {
1177  return Qnil;
1178  }
1179  return rb_mod_autoload_p(klass, sym);
1180 }
1181 
1182 void
1184 {
1185 #undef rb_intern
1186 #define rb_intern(str) rb_intern2((str), strlen(str))
1187  rb_vm_t *vm = GET_VM();
1188  static const char var_load_path[] = "$:";
1189  ID id_load_path = rb_intern2(var_load_path, sizeof(var_load_path)-1);
1190 
1191  rb_define_hooked_variable(var_load_path, (VALUE*)vm, load_path_getter, rb_gvar_readonly_setter);
1192  rb_alias_variable(rb_intern("$-I"), id_load_path);
1193  rb_alias_variable(rb_intern("$LOAD_PATH"), id_load_path);
1194  vm->load_path = rb_ary_new();
1195  vm->expanded_load_path = rb_ary_tmp_new(0);
1196  vm->load_path_snapshot = rb_ary_tmp_new(0);
1197  vm->load_path_check_cache = 0;
1198 
1199  rb_define_virtual_variable("$\"", get_loaded_features, 0);
1200  rb_define_virtual_variable("$LOADED_FEATURES", get_loaded_features, 0);
1201  vm->loaded_features = rb_ary_new();
1202  vm->loaded_features_snapshot = rb_ary_tmp_new(0);
1203  vm->loaded_features_index = st_init_strtable();
1204 
1205  rb_define_global_function("load", rb_f_load, -1);
1206  rb_define_global_function("require", rb_f_require, 1);
1207  rb_define_global_function("require_relative", rb_f_require_relative, 1);
1208  rb_define_method(rb_cModule, "autoload", rb_mod_autoload, 2);
1209  rb_define_method(rb_cModule, "autoload?", rb_mod_autoload_p, 1);
1210  rb_define_global_function("autoload", rb_f_autoload, 2);
1211  rb_define_global_function("autoload?", rb_f_autoload_p, 1);
1212 
1213  ruby_dln_librefs = rb_ary_tmp_new(0);
1214  rb_gc_register_mark_object(ruby_dln_librefs);
1215 }
VALUE rb_get_path_check_convert(VALUE obj, VALUE tmp, int level)
Definition: file.c:197
ID rb_check_id(volatile VALUE *)
Returns ID for the given name if it is interned already, or 0.
Definition: symbol.c:915
Definition: st.h:99
VALUE rb_get_path(VALUE obj)
Definition: file.c:226
VALUE expanded_load_path
Definition: vm_core.h:543
void rb_warn(const char *fmt,...)
Definition: error.c:246
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1215
#define RARRAY_LEN(a)
Definition: ruby.h:1019
#define FALSE
Definition: nkf.h:174
ruby_tag_type
Definition: vm_core.h:151
VALUE rb_str_equal(VALUE str1, VALUE str2)
Definition: string.c:3214
size_t strlen(const char *)
#define T_FIXNUM
Definition: ruby.h:503
Definition: st.h:79
Definition: st.h:99
void rb_load_protect(VALUE fname, int wrap, int *pstate)
Definition: load.c:671
void rb_define_virtual_variable(const char *, VALUE(*)(ANYARGS), void(*)(ANYARGS))
Definition: variable.c:648
ID rb_intern2(const char *, long)
Definition: symbol.c:604
int rb_is_absolute_path(const char *path)
Definition: file.c:5719
NORETURN(static void load_failed(VALUE))
VALUE rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encoding *enc)
Definition: string.c:368
#define TAG_NONE
Definition: vm_core.h:164
#define FilePathValue(v)
Definition: ruby.h:594
VALUE rb_fstring_cstr(const char *str)
Definition: string.c:388
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:2284
#define st_foreach
Definition: regint.h:186
#define Qtrue
Definition: ruby.h:437
VALUE rb_current_realfilepath(void)
Definition: vm_eval.c:2145
struct st_table * loaded_features_index
Definition: vm_core.h:546
void Init_load(void)
Definition: load.c:1183
int rb_provided(const char *feature)
Definition: load.c:522
Definition: st.h:99
#define OBJ_FREEZE(x)
Definition: ruby.h:1306
VALUE rb_vm_call_cfunc(VALUE recv, VALUE(*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename)
Definition: vm.c:2100
VALUE rb_get_path_check_to_string(VALUE obj, int level)
Definition: file.c:178
int ruby_require_internal(const char *fname, unsigned int len)
Definition: load.c:1035
#define MEMO_CAST(m)
Definition: internal.h:961
#define TH_JUMP_TAG(th, st)
Definition: eval_intern.h:204
const char * result
Definition: load.c:363
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:924
#define VM_BLOCK_HANDLER_NONE
Definition: vm_core.h:1135
void rb_backtrace_each(VALUE(*iter)(VALUE recv, VALUE str), VALUE output)
Definition: vm_backtrace.c:796
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:544
VALUE rb_ary_shared_with_p(VALUE ary1, VALUE ary2)
Definition: array.c:437
int st_get_key(st_table *, st_data_t, st_data_t *)
Definition: st.c:1062
int rb_require_internal(VALUE fname, int safe)
Definition: load.c:962
#define Check_Type(v, t)
Definition: ruby.h:562
#define RB_GC_GUARD(v)
Definition: ruby.h:552
VALUE rb_f_require_relative(VALUE obj, VALUE fname)
Definition: load.c:841
RUBY_FUNC_EXPORTED void ruby_init_ext(const char *name, void(*init)(void))
Definition: load.c:1083
VALUE(* func)(ANYARGS)
Definition: internal.h:954
VALUE rb_get_load_path(void)
Definition: load.c:30
union MEMO::@80 u3
#define T_ARRAY
Definition: ruby.h:498
#define st_lookup
Definition: regint.h:185
#define PUSH_TAG()
Definition: eval_intern.h:147
int st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg)
Definition: st.c:1393
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1745
#define IS_DLEXT(e)
Definition: load.c:18
#define RUBY_DTRACE_HOOK(name, arg)
Definition: internal.h:1934
#define MEMO_NEW(a, b, c)
Definition: internal.h:963
#define st_init_strtable
Definition: regint.h:180
VALUE rb_str_tmp_new(long)
Definition: string.c:1310
VALUE rb_ary_cat(VALUE ary, const VALUE *argv, long len)
Definition: array.c:936
void rb_load_fail(VALUE path, const char *err)
Definition: error.c:2575
const rb_iseq_t * rb_iseq_load_iseq(VALUE fname)
Definition: iseq.c:512
#define GET_THREAD()
Definition: vm_core.h:1583
#define sym(x)
Definition: date_core.c:3721
VALUE rb_f_require(VALUE obj, VALUE fname)
Definition: load.c:827
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
Definition: st.h:22
Definition: node.h:233
VALUE rb_warning_warn(VALUE mod, VALUE str)
Definition: error.c:179
#define DLEXT_MAXLEN
Definition: defines.h:321
#define RB_TYPE_P(obj, type)
Definition: ruby.h:527
#define TH_POP_TAG()
Definition: eval_intern.h:138
void * rb_parser_load_file(VALUE parser, VALUE name)
Definition: ruby.c:2036
Definition: ruby.h:954
#define IS_SOEXT(e)
Definition: load.c:14
void rb_ary_free(VALUE ary)
Definition: array.c:559
VALUE rb_find_file(VALUE path)
Definition: file.c:5965
#define EXEC_TAG()
Definition: eval_intern.h:201
VALUE rb_str_encode_ospath(VALUE path)
Definition: file.c:232
#define level
char * ruby_strdup(const char *)
Definition: util.c:496
VALUE rb_require(const char *fname)
Definition: load.c:1061
VALUE rb_ary_replace(VALUE copy, VALUE orig)
Definition: array.c:3451
VALUE rb_str_cat2(VALUE, const char *)
void rb_set_errinfo(VALUE err)
Sets the current exception ($!) to the given value.
Definition: eval.c:1792
VALUE rb_thread_shield_release(VALUE self)
Definition: thread.c:4467
VALUE rb_ary_new(void)
Definition: array.c:499
rb_iseq_t * rb_iseq_new_top(NODE *node, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent)
Definition: iseq.c:466
VALUE load_path_check_cache
Definition: vm_core.h:542
Definition: ruby.h:1002
#define JUMP_TAG(st)
Definition: eval_intern.h:206
#define NIL_P(v)
Definition: ruby.h:451
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:815
MEMO.
Definition: internal.h:945
VALUE top_self
Definition: vm_core.h:804
int argc
Definition: ruby.c:187
#define Qfalse
Definition: ruby.h:436
#define rb_intern(str)
VALUE rb_parser_set_context(VALUE vparser, const struct rb_block *base, int main)
Definition: ripper.c:17367
RUBY_EXTERN VALUE rb_cModule
Definition: ruby.h:1916
void rb_gc_register_mark_object(VALUE obj)
Definition: gc.c:6227
#define RUBY_FUNC_EXPORTED
Definition: defines.h:263
#define MEMCPY(p1, p2, type, n)
Definition: ruby.h:1661
void rb_provide(const char *feature)
Definition: load.c:572
#define rb_str_new2
Definition: intern.h:835
VALUE rb_find_file_safe(VALUE path, int safe_level)
Definition: file.c:5971
#define POP_TAG()
Definition: eval_intern.h:148
#define numberof(array)
Definition: etc.c:618
VALUE rb_file_absolute_path(VALUE fname, VALUE dname)
Definition: file.c:3823
VALUE rb_str_resize(VALUE, long)
Definition: string.c:2644
VALUE rb_str_subseq(VALUE, long, long)
Definition: string.c:2406
void rb_alias_variable(ID, ID)
Definition: variable.c:912
#define RSTRING_LEN(str)
Definition: ruby.h:971
#define TRUE
Definition: nkf.h:175
VALUE rb_obj_freeze(VALUE)
call-seq: obj.freeze -> obj
Definition: object.c:1331
VALUE rb_vm_cbase(void)
Definition: vm.c:1368
void rb_gvar_readonly_setter(VALUE v, ID id, void *d, struct rb_global_variable *g)
Definition: variable.c:572
VALUE loaded_features
Definition: vm_core.h:544
VALUE rb_file_dirname(VALUE fname)
Definition: file.c:4317
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1908
VALUE rb_thread_shield_destroy(VALUE self)
Definition: thread.c:4478
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4309
unsigned long ID
Definition: ruby.h:86
long state
Definition: internal.h:952
void rb_load(VALUE fname, int wrap)
Definition: load.c:665
#define Qnil
Definition: ruby.h:438
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
Definition: eval.c:615
VALUE rb_check_realpath(VALUE basedir, VALUE path)
Definition: file.c:4086
unsigned long VALUE
Definition: ruby.h:85
VALUE rb_vm_top_self(void)
Definition: vm.c:3166
#define RBASIC(obj)
Definition: ruby.h:1197
char * strchr(char *, char)
VALUE rb_eTypeError
Definition: error.c:801
#define TH_PUSH_TAG(th)
Definition: eval_intern.h:131
RUBY_EXTERN size_t strlcpy(char *, const char *, size_t)
Definition: strlcpy.c:29
VALUE rb_str_new_cstr(const char *)
Definition: string.c:771
VALUE rb_fstring(VALUE)
Definition: string.c:306
void * dln_load(const char *file)
Definition: dln.c:1246
void rb_define_hooked_variable(const char *, VALUE *, VALUE(*)(ANYARGS), void(*)(ANYARGS))
Definition: variable.c:617
#define LONG2NUM(x)
Definition: ruby.h:1573
#define my_getcwd()
Definition: util.h:73
register unsigned int len
Definition: zonetab.h:51
VALUE rb_str_freeze(VALUE)
Definition: string.c:2549
#define StringValueCStr(v)
Definition: ruby.h:571
void rb_set_safe_level_force(int)
Definition: safe.c:41
expand_type
Definition: load.c:36
#define RSTRING_PTR(str)
Definition: ruby.h:975
VALUE rb_thread_shield_new(void)
Definition: thread.c:4422
#define f
#define INT2FIX(i)
Definition: ruby.h:232
VALUE top_wrapper
Definition: vm_core.h:805
int rb_safe_level(void)
Definition: safe.c:35
VALUE rb_module_new(void)
Definition: class.c:749
#define RARRAY_AREF(a, i)
Definition: ruby.h:1033
VALUE rb_eRuntimeError
Definition: error.c:800
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
Definition: eval.c:1596
VALUE rb_warning_string(const char *fmt,...)
Definition: error.c:277
VALUE rb_mWarning
Definition: error.c:55
VALUE rb_iseq_eval(const rb_iseq_t *iseq)
Definition: vm.c:2027
#define RTEST(v)
Definition: ruby.h:450
#define T_STRING
Definition: ruby.h:496
#define OBJ_FROZEN(x)
Definition: ruby.h:1304
VALUE load_path_snapshot
Definition: vm_core.h:541
void rb_scope_visibility_set(rb_method_visibility_t)
Definition: vm_method.c:1125
VALUE rb_errinfo(void)
The current exception in the current thread.
Definition: eval.c:1777
const struct st_hash_type * type
Definition: st.h:84
VALUE loaded_features_snapshot
Definition: vm_core.h:545
#define st_insert
Definition: regint.h:184
VALUE rb_filesystem_str_new_cstr(const char *)
Definition: string.c:1085
VALUE rb_parser_new(void)
Definition: ripper.c:17357
VALUE rb_thread_shield_wait(VALUE self)
Definition: thread.c:4438
VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict)
Definition: file.c:4078
#define TAG_RETURN
Definition: vm_core.h:165
const char * name
Definition: load.c:359
rb_execution_context_t ec
Definition: vm_core.h:790
int rb_feature_provided(const char *feature, const char **loading)
Definition: load.c:528
const char * name
Definition: nkf.c:208
int rb_find_file_ext_safe(VALUE *filep, const char *const *ext, int safe_level)
Definition: file.c:5899
int rb_file_load_ok(const char *path)
Definition: file.c:5852
void rb_autoload_str(VALUE mod, ID id, VALUE file)
Definition: variable.c:1895
#define StringValuePtr(v)
Definition: ruby.h:570
VALUE rb_get_expanded_load_path(void)
Definition: load.c:107
#define SPECIAL_CONST_P(x)
Definition: ruby.h:1242
void void xfree(void *)
VALUE load_path
Definition: vm_core.h:540
#define IS_RBEXT(e)
Definition: load.c:13
VALUE rb_vm_make_jump_tag_but_local_jump(int state, VALUE val)
Definition: vm.c:1421
VALUE rb_get_path_check(VALUE obj, int level)
Definition: file.c:213
#define mod(x, y)
Definition: date_strftime.c:28
#define TAG_RAISE
Definition: vm_core.h:170
#define NULL
Definition: _sdbm.c:102
#define FIX2LONG(x)
Definition: ruby.h:363
#define Qundef
Definition: ruby.h:439
VALUE rb_class_real(VALUE cl)
Looks up the nearest ancestor of cl, skipping singleton classes or module inclusions.
Definition: object.c:251
VALUE rb_obj_clone(VALUE)
:nodoc Almost same as Object::clone ++
Definition: object.c:475
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1515
#define ruby_verbose
Definition: ruby.h:1813
VALUE rb_str_append(VALUE, VALUE)
Definition: string.c:2900
const VALUE value
Definition: internal.h:953
ID rb_to_id(VALUE)
Definition: string.c:10496
void rb_loaderror(const char *fmt,...)
Definition: error.c:2306
VALUE rb_require_safe(VALUE fname, int safe)
Definition: load.c:1045
char * strrchr(const char *, const char)
char ** argv
Definition: ruby.c:188
#define StringValue(v)
Definition: ruby.h:569
VALUE rb_file_expand_path_fast(VALUE fname, VALUE dname)
Definition: file.c:3782
VALUE rb_autoload_p(VALUE, ID)
Definition: variable.c:2201
#define xcalloc
Definition: defines.h:185
#define GET_VM()
Definition: vm_core.h:1582