Ruby  2.0.0p594(2014-10-27revision48167)
load.c
Go to the documentation of this file.
1 /*
2  * load methods from eval.c
3  */
4 
5 #include "ruby/ruby.h"
6 #include "ruby/util.h"
7 #include "internal.h"
8 #include "dln.h"
9 #include "eval_intern.h"
10 #include "probes.h"
11 #include "node.h"
12 
14 
15 #define numberof(array) (int)(sizeof(array) / sizeof((array)[0]))
16 
17 #define IS_RBEXT(e) (strcmp((e), ".rb") == 0)
18 #define IS_SOEXT(e) (strcmp((e), ".so") == 0 || strcmp((e), ".o") == 0)
19 #ifdef DLEXT2
20 #define IS_DLEXT(e) (strcmp((e), DLEXT) == 0 || strcmp((e), DLEXT2) == 0)
21 #else
22 #define IS_DLEXT(e) (strcmp((e), DLEXT) == 0)
23 #endif
24 
25 static const char *const loadable_ext[] = {
26  ".rb", DLEXT,
27 #ifdef DLEXT2
28  DLEXT2,
29 #endif
30  0
31 };
32 
33 VALUE
35 {
36  VALUE load_path = GET_VM()->load_path;
37  return load_path;
38 }
39 
45 };
46 
47 /* Construct expanded load path and store it to cache.
48  We rebuild load path partially if the cache is invalid.
49  We don't cache non string object and expand it every time. We ensure that
50  string objects in $LOAD_PATH are frozen.
51  */
52 static void
53 rb_construct_expanded_load_path(int type, int *has_relative, int *has_non_cache)
54 {
55  rb_vm_t *vm = GET_VM();
56  VALUE load_path = vm->load_path;
57  VALUE expanded_load_path = vm->expanded_load_path;
58  VALUE ary;
59  long i;
60  int level = rb_safe_level();
61 
62  ary = rb_ary_tmp_new(RARRAY_LEN(load_path));
63  for (i = 0; i < RARRAY_LEN(load_path); ++i) {
64  VALUE path, as_str, expanded_path;
65  int is_string, non_cache;
66  char *as_cstr;
67  as_str = path = RARRAY_PTR(load_path)[i];
68  is_string = RB_TYPE_P(path, T_STRING) ? 1 : 0;
69  non_cache = !is_string ? 1 : 0;
70  as_str = rb_get_path_check_to_string(path, level);
71  as_cstr = RSTRING_PTR(as_str);
72 
73  if (!non_cache) {
74  if ((type == EXPAND_RELATIVE &&
75  rb_is_absolute_path(as_cstr)) ||
76  (type == EXPAND_HOME &&
77  (!as_cstr[0] || as_cstr[0] != '~')) ||
78  (type == EXPAND_NON_CACHE)) {
79  /* Use cached expanded path. */
80  rb_ary_push(ary, RARRAY_PTR(expanded_load_path)[i]);
81  continue;
82  }
83  }
84  if (!*has_relative && !rb_is_absolute_path(as_cstr))
85  *has_relative = 1;
86  if (!*has_non_cache && non_cache)
87  *has_non_cache = 1;
88  /* Freeze only string object. We expand other objects every time. */
89  if (is_string)
90  rb_str_freeze(path);
91  as_str = rb_get_path_check_convert(path, as_str, level);
92  expanded_path = rb_file_expand_path_fast(as_str, Qnil);
93  rb_str_freeze(expanded_path);
94  rb_ary_push(ary, expanded_path);
95  }
96  rb_obj_freeze(ary);
97  vm->expanded_load_path = ary;
99 }
100 
101 static VALUE
103 {
104  char *cwd = my_getcwd();
105  VALUE cwd_str = rb_filesystem_str_new_cstr(cwd);
106  xfree(cwd);
107  return cwd_str;
108 }
109 
110 VALUE
112 {
113  rb_vm_t *vm = GET_VM();
114  const VALUE non_cache = Qtrue;
115 
117  /* The load path was modified. Rebuild the expanded load path. */
118  int has_relative = 0, has_non_cache = 0;
119  rb_construct_expanded_load_path(EXPAND_ALL, &has_relative, &has_non_cache);
120  if (has_relative) {
122  }
123  else if (has_non_cache) {
124  /* Non string object. */
125  vm->load_path_check_cache = non_cache;
126  }
127  else {
128  vm->load_path_check_cache = 0;
129  }
130  }
131  else if (vm->load_path_check_cache == non_cache) {
132  int has_relative = 1, has_non_cache = 1;
133  /* Expand only non-cacheable objects. */
135  &has_relative, &has_non_cache);
136  }
137  else if (vm->load_path_check_cache) {
138  int has_relative = 1, has_non_cache = 1;
139  VALUE cwd = load_path_getcwd();
140  if (!rb_str_equal(vm->load_path_check_cache, cwd)) {
141  /* Current working directory or filesystem encoding was changed.
142  Expand relative load path and non-cacheable objects again. */
143  vm->load_path_check_cache = cwd;
145  &has_relative, &has_non_cache);
146  }
147  else {
148  /* Expand only tilde (User HOME) and non-cacheable objects. */
150  &has_relative, &has_non_cache);
151  }
152  }
153  return vm->expanded_load_path;
154 }
155 
156 static VALUE
158 {
159  return vm->load_path;
160 }
161 
162 static VALUE
164 {
165  return GET_VM()->loaded_features;
166 }
167 
168 static void
170 {
171  rb_vm_t *vm = GET_VM();
173 }
174 
175 static struct st_table *
177 {
178  return GET_VM()->loaded_features_index;
179 }
180 
181 static st_table *
183 {
184  return GET_VM()->loading_table;
185 }
186 
187 static void
188 features_index_add_single(VALUE short_feature, VALUE offset)
189 {
190  struct st_table *features_index;
191  VALUE this_feature_index = Qnil;
192  char *short_feature_cstr;
193 
194  Check_Type(offset, T_FIXNUM);
195  Check_Type(short_feature, T_STRING);
196  short_feature_cstr = StringValueCStr(short_feature);
197 
198  features_index = get_loaded_features_index_raw();
199  st_lookup(features_index, (st_data_t)short_feature_cstr, (st_data_t *)&this_feature_index);
200 
201  if (NIL_P(this_feature_index)) {
202  st_insert(features_index, (st_data_t)ruby_strdup(short_feature_cstr), (st_data_t)offset);
203  }
204  else if (RB_TYPE_P(this_feature_index, T_FIXNUM)) {
205  VALUE feature_indexes[2];
206  feature_indexes[0] = this_feature_index;
207  feature_indexes[1] = offset;
208  this_feature_index = rb_ary_tmp_new(numberof(feature_indexes));
209  rb_ary_cat(this_feature_index, feature_indexes, numberof(feature_indexes));
210  st_insert(features_index, (st_data_t)short_feature_cstr, (st_data_t)this_feature_index);
211  }
212  else {
213  Check_Type(this_feature_index, T_ARRAY);
214  rb_ary_push(this_feature_index, offset);
215  }
216 }
217 
218 /* Add to the loaded-features index all the required entries for
219  `feature`, located at `offset` in $LOADED_FEATURES. We add an
220  index entry at each string `short_feature` for which
221  feature == "#{prefix}#{short_feature}#{e}"
222  where `e` is empty or matches %r{^\.[^./]*$}, and `prefix` is empty
223  or ends in '/'. This maintains the invariant that `rb_feature_p()`
224  relies on for its fast lookup.
225 */
226 static void
228 {
229  VALUE short_feature;
230  const char *feature_str, *feature_end, *ext, *p;
231 
232  feature_str = StringValuePtr(feature);
233  feature_end = feature_str + RSTRING_LEN(feature);
234 
235  for (ext = feature_end; ext > feature_str; ext--)
236  if (*ext == '.' || *ext == '/')
237  break;
238  if (*ext != '.')
239  ext = NULL;
240  /* Now `ext` points to the only string matching %r{^\.[^./]*$} that is
241  at the end of `feature`, or is NULL if there is no such string. */
242 
243  p = ext ? ext : feature_end;
244  while (1) {
245  p--;
246  while (p >= feature_str && *p != '/')
247  p--;
248  if (p < feature_str)
249  break;
250  /* Now *p == '/'. We reach this point for every '/' in `feature`. */
251  short_feature = rb_str_subseq(feature, p + 1 - feature_str, feature_end - p - 1);
252  features_index_add_single(short_feature, offset);
253  if (ext) {
254  short_feature = rb_str_subseq(feature, p + 1 - feature_str, 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
267 {
268  xfree((char *)key);
269  return ST_DELETE;
270 }
271 
272 static st_table *
274 {
275  VALUE features;
276  int i;
277  rb_vm_t *vm = GET_VM();
278 
280  /* The sharing was broken; something (other than us in rb_provide_feature())
281  modified loaded_features. Rebuild the index. */
283  features = vm->loaded_features;
284  for (i = 0; i < RARRAY_LEN(features); i++) {
285  VALUE entry, as_str;
286  as_str = entry = rb_ary_entry(features, i);
287  StringValue(as_str);
288  if (as_str != entry)
289  rb_ary_store(features, i, as_str);
290  rb_str_freeze(as_str);
291  features_index_add(as_str, INT2FIX(i));
292  }
294  }
295  return vm->loaded_features_index;
296 }
297 
298 /* This searches `load_path` for a value such that
299  name == "#{load_path[i]}/#{feature}"
300  if `feature` is a suffix of `name`, or otherwise
301  name == "#{load_path[i]}/#{feature}#{ext}"
302  for an acceptable string `ext`. It returns
303  `load_path[i].to_str` if found, else 0.
304 
305  If type is 's', then `ext` is acceptable only if IS_DLEXT(ext);
306  if 'r', then only if IS_RBEXT(ext); otherwise `ext` may be absent
307  or have any value matching `%r{^\.[^./]*$}`.
308 */
309 static VALUE
310 loaded_feature_path(const char *name, long vlen, const char *feature, long len,
311  int type, VALUE load_path)
312 {
313  long i;
314  long plen;
315  const char *e;
316 
317  if (vlen < len+1) return 0;
318  if (!strncmp(name+(vlen-len), feature, len)) {
319  plen = vlen - len;
320  }
321  else {
322  for (e = name + vlen; name != e && *e != '.' && *e != '/'; --e);
323  if (*e != '.' ||
324  e-name < len ||
325  strncmp(e-len, feature, len))
326  return 0;
327  plen = e - name - len;
328  }
329  if (plen > 0 && name[plen-1] != '/') {
330  return 0;
331  }
332  if (type == 's' ? !IS_DLEXT(&name[plen+len]) :
333  type == 'r' ? !IS_RBEXT(&name[plen+len]) :
334  0) {
335  return 0;
336  }
337  /* Now name == "#{prefix}/#{feature}#{ext}" where ext is acceptable
338  (possibly empty) and prefix is some string of length plen. */
339 
340  if (plen > 0) --plen; /* exclude '.' */
341  for (i = 0; i < RARRAY_LEN(load_path); ++i) {
342  VALUE p = RARRAY_PTR(load_path)[i];
343  const char *s = StringValuePtr(p);
344  long n = RSTRING_LEN(p);
345 
346  if (n != plen) continue;
347  if (n && strncmp(name, s, n)) continue;
348  return p;
349  }
350  return 0;
351 }
352 
354  const char *name;
355  long len;
356  int type;
358  const char *result;
359 };
360 
361 static int
363 {
364  const char *s = (const char *)v;
365  struct loaded_feature_searching *fp = (struct loaded_feature_searching *)f;
366  VALUE p = loaded_feature_path(s, strlen(s), fp->name, fp->len,
367  fp->type, fp->load_path);
368  if (!p) return ST_CONTINUE;
369  fp->result = s;
370  return ST_STOP;
371 }
372 
373 static int
374 rb_feature_p(const char *feature, const char *ext, int rb, int expanded, const char **fn)
375 {
376  VALUE features, this_feature_index = Qnil, v, p, load_path = 0;
377  const char *f, *e;
378  long i, len, elen, n;
379  st_table *loading_tbl, *features_index;
380  st_data_t data;
381  int type;
382 
383  if (fn) *fn = 0;
384  if (ext) {
385  elen = strlen(ext);
386  len = strlen(feature) - elen;
387  type = rb ? 'r' : 's';
388  }
389  else {
390  len = strlen(feature);
391  elen = 0;
392  type = 0;
393  }
394  features = get_loaded_features();
395  features_index = get_loaded_features_index();
396 
397  st_lookup(features_index, (st_data_t)feature, (st_data_t *)&this_feature_index);
398  /* We search `features` for an entry such that either
399  "#{features[i]}" == "#{load_path[j]}/#{feature}#{e}"
400  for some j, or
401  "#{features[i]}" == "#{feature}#{e}"
402  Here `e` is an "allowed" extension -- either empty or one
403  of the extensions accepted by IS_RBEXT, IS_SOEXT, or
404  IS_DLEXT. Further, if `ext && rb` then `IS_RBEXT(e)`,
405  and if `ext && !rb` then `IS_SOEXT(e) || IS_DLEXT(e)`.
406 
407  If `expanded`, then only the latter form (without load_path[j])
408  is accepted. Otherwise either form is accepted, *unless* `ext`
409  is false and an otherwise-matching entry of the first form is
410  preceded by an entry of the form
411  "#{features[i2]}" == "#{load_path[j2]}/#{feature}#{e2}"
412  where `e2` matches %r{^\.[^./]*$} but is not an allowed extension.
413  After a "distractor" entry of this form, only entries of the
414  form "#{feature}#{e}" are accepted.
415 
416  In `rb_provide_feature()` and `get_loaded_features_index()` we
417  maintain an invariant that the array `this_feature_index` will
418  point to every entry in `features` which has the form
419  "#{prefix}#{feature}#{e}"
420  where `e` is empty or matches %r{^\.[^./]*$}, and `prefix` is empty
421  or ends in '/'. This includes both match forms above, as well
422  as any distractors, so we may ignore all other entries in `features`.
423  */
424  for (i = 0; !NIL_P(this_feature_index); i++) {
425  VALUE entry;
426  long index;
427  if (RB_TYPE_P(this_feature_index, T_ARRAY)) {
428  if (i >= RARRAY_LEN(this_feature_index)) break;
429  entry = RARRAY_PTR(this_feature_index)[i];
430  }
431  else {
432  if (i > 0) break;
433  entry = this_feature_index;
434  }
435  index = FIX2LONG(entry);
436 
437  v = RARRAY_PTR(features)[index];
438  f = StringValuePtr(v);
439  if ((n = RSTRING_LEN(v)) < len) continue;
440  if (strncmp(f, feature, len) != 0) {
441  if (expanded) continue;
442  if (!load_path) load_path = rb_get_expanded_load_path();
443  if (!(p = loaded_feature_path(f, n, feature, len, type, load_path)))
444  continue;
445  expanded = 1;
446  f += RSTRING_LEN(p) + 1;
447  }
448  if (!*(e = f + len)) {
449  if (ext) continue;
450  return 'u';
451  }
452  if (*e != '.') continue;
453  if ((!rb || !ext) && (IS_SOEXT(e) || IS_DLEXT(e))) {
454  return 's';
455  }
456  if ((rb || !ext) && (IS_RBEXT(e))) {
457  return 'r';
458  }
459  }
460 
461  loading_tbl = get_loading_table();
462  if (loading_tbl) {
463  f = 0;
464  if (!expanded) {
465  struct loaded_feature_searching fs;
466  fs.name = feature;
467  fs.len = len;
468  fs.type = type;
469  fs.load_path = load_path ? load_path : rb_get_expanded_load_path();
470  fs.result = 0;
471  st_foreach(loading_tbl, loaded_feature_path_i, (st_data_t)&fs);
472  if ((f = fs.result) != 0) {
473  if (fn) *fn = f;
474  goto loading;
475  }
476  }
477  if (st_get_key(loading_tbl, (st_data_t)feature, &data)) {
478  if (fn) *fn = (const char*)data;
479  loading:
480  if (!ext) return 'u';
481  return !IS_RBEXT(ext) ? 's' : 'r';
482  }
483  else {
484  VALUE bufstr;
485  char *buf;
486  static const char so_ext[][4] = {
487  ".so", ".o",
488  };
489 
490  if (ext && *ext) return 0;
491  bufstr = rb_str_tmp_new(len + DLEXT_MAXLEN);
492  buf = RSTRING_PTR(bufstr);
493  MEMCPY(buf, feature, char, len);
494  for (i = 0; (e = loadable_ext[i]) != 0; i++) {
495  strlcpy(buf + len, e, DLEXT_MAXLEN + 1);
496  if (st_get_key(loading_tbl, (st_data_t)buf, &data)) {
497  rb_str_resize(bufstr, 0);
498  if (fn) *fn = (const char*)data;
499  return i ? 's' : 'r';
500  }
501  }
502  for (i = 0; i < numberof(so_ext); i++) {
503  strlcpy(buf + len, so_ext[i], DLEXT_MAXLEN + 1);
504  if (st_get_key(loading_tbl, (st_data_t)buf, &data)) {
505  rb_str_resize(bufstr, 0);
506  if (fn) *fn = (const char*)data;
507  return 's';
508  }
509  }
510  rb_str_resize(bufstr, 0);
511  }
512  }
513  return 0;
514 }
515 
516 int
517 rb_provided(const char *feature)
518 {
519  return rb_feature_provided(feature, 0);
520 }
521 
522 int
523 rb_feature_provided(const char *feature, const char **loading)
524 {
525  const char *ext = strrchr(feature, '.');
526  volatile VALUE fullpath = 0;
527 
528  if (*feature == '.' &&
529  (feature[1] == '/' || strncmp(feature+1, "./", 2) == 0)) {
530  fullpath = rb_file_expand_path_fast(rb_get_path(rb_str_new2(feature)), Qnil);
531  feature = RSTRING_PTR(fullpath);
532  }
533  if (ext && !strchr(ext, '/')) {
534  if (IS_RBEXT(ext)) {
535  if (rb_feature_p(feature, ext, TRUE, FALSE, loading)) return TRUE;
536  return FALSE;
537  }
538  else if (IS_SOEXT(ext) || IS_DLEXT(ext)) {
539  if (rb_feature_p(feature, ext, FALSE, FALSE, loading)) return TRUE;
540  return FALSE;
541  }
542  }
543  if (rb_feature_p(feature, 0, TRUE, FALSE, loading))
544  return TRUE;
545  return FALSE;
546 }
547 
548 static void
550 {
551  VALUE features;
552 
553  features = get_loaded_features();
554  if (OBJ_FROZEN(features)) {
556  "$LOADED_FEATURES is frozen; cannot append feature");
557  }
558  rb_str_freeze(feature);
559 
560  rb_ary_push(features, feature);
561  features_index_add(feature, INT2FIX(RARRAY_LEN(features)-1));
563 }
564 
565 void
566 rb_provide(const char *feature)
567 {
569 }
570 
571 NORETURN(static void load_failed(VALUE));
572 
573 static void
574 rb_load_internal(VALUE fname, int wrap)
575 {
576  int state;
578  volatile VALUE wrapper = th->top_wrapper;
579  volatile VALUE self = th->top_self;
580  volatile int loaded = FALSE;
581  volatile int mild_compile_error;
582 #ifndef __GNUC__
583  rb_thread_t *volatile th0 = th;
584 #endif
585 
586  th->errinfo = Qnil; /* ensure */
587 
588  if (!wrap) {
589  rb_secure(4); /* should alter global state */
590  th->top_wrapper = 0;
591  }
592  else {
593  /* load in anonymous module as toplevel */
595  th->top_wrapper = rb_module_new();
597  }
598 
599  mild_compile_error = th->mild_compile_error;
600  PUSH_TAG();
601  state = EXEC_TAG();
602  if (state == 0) {
603  NODE *node;
604  VALUE iseq;
605 
606  th->mild_compile_error++;
607  node = (NODE *)rb_load_file(RSTRING_PTR(fname));
608  loaded = TRUE;
609  iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, rb_realpath_internal(Qnil, fname, 1), Qfalse);
610  th->mild_compile_error--;
611  rb_iseq_eval(iseq);
612  }
613  POP_TAG();
614 
615 #ifndef __GNUC__
616  th = th0;
617  fname = RB_GC_GUARD(fname);
618 #endif
619  th->mild_compile_error = mild_compile_error;
620  th->top_self = self;
621  th->top_wrapper = wrapper;
622 
623  if (!loaded && !FIXNUM_P(GET_THREAD()->errinfo)) {
624  /* an error on loading don't include INT2FIX(TAG_FATAL) see r35625 */
625  rb_exc_raise(GET_THREAD()->errinfo);
626  }
627  if (state) {
629  }
630 
631  if (!NIL_P(GET_THREAD()->errinfo)) {
632  /* exception during load */
633  rb_exc_raise(th->errinfo);
634  }
635 }
636 
637 void
638 rb_load(VALUE fname, int wrap)
639 {
641  if (!tmp) load_failed(fname);
642  rb_load_internal(tmp, wrap);
643 }
644 
645 void
646 rb_load_protect(VALUE fname, int wrap, int *state)
647 {
648  int status;
649 
650  PUSH_TAG();
651  if ((status = EXEC_TAG()) == 0) {
652  rb_load(fname, wrap);
653  }
654  POP_TAG();
655  if (state)
656  *state = status;
657 }
658 
659 /*
660  * call-seq:
661  * load(filename, wrap=false) -> true
662  *
663  * Loads and executes the Ruby
664  * program in the file _filename_. If the filename does not
665  * resolve to an absolute path, the file is searched for in the library
666  * directories listed in <code>$:</code>. If the optional _wrap_
667  * parameter is +true+, the loaded script will be executed
668  * under an anonymous module, protecting the calling program's global
669  * namespace. In no circumstance will any local variables in the loaded
670  * file be propagated to the loading environment.
671  */
672 
673 static VALUE
675 {
676  VALUE fname, wrap, path;
677 
678  rb_scan_args(argc, argv, "11", &fname, &wrap);
679 
682  rb_sourcefile(),
683  rb_sourceline());
684  }
685 
686  path = rb_find_file(FilePathValue(fname));
687  if (!path) {
688  if (!rb_file_load_ok(RSTRING_PTR(fname)))
689  load_failed(fname);
690  path = fname;
691  }
692  rb_load_internal(path, RTEST(wrap));
693 
696  rb_sourcefile(),
697  rb_sourceline());
698  }
699 
700  return Qtrue;
701 }
702 
703 static char *
704 load_lock(const char *ftptr)
705 {
706  st_data_t data;
707  st_table *loading_tbl = get_loading_table();
708 
709  if (!loading_tbl || !st_lookup(loading_tbl, (st_data_t)ftptr, &data)) {
710  /* loading ruby library should be serialized. */
711  if (!loading_tbl) {
712  GET_VM()->loading_table = loading_tbl = st_init_strtable();
713  }
714  /* partial state */
715  ftptr = ruby_strdup(ftptr);
717  st_insert(loading_tbl, (st_data_t)ftptr, data);
718  return (char *)ftptr;
719  }
720  else if (RB_TYPE_P((VALUE)data, T_NODE) && nd_type((VALUE)data) == NODE_MEMO) {
721  NODE *memo = RNODE(data);
722  void (*init)(void) = (void (*)(void))memo->nd_cfnc;
724  st_insert(loading_tbl, (st_data_t)ftptr, data);
725  (*init)();
726  return (char *)"";
727  }
728  if (RTEST(ruby_verbose)) {
729  rb_warning("loading in progress, circular require considered harmful - %s", ftptr);
730  /* TODO: display to $stderr, not stderr in C */
731  rb_backtrace();
732  }
733  switch (rb_thread_shield_wait((VALUE)data)) {
734  case Qfalse:
735  data = (st_data_t)ftptr;
736  st_insert(loading_tbl, data, (st_data_t)rb_thread_shield_new());
737  return 0;
738  case Qnil:
739  return 0;
740  }
741  return (char *)ftptr;
742 }
743 
744 static int
746 {
747  VALUE thread_shield = (VALUE)*value;
748  if (!existing) return ST_STOP;
749  if (done ? rb_thread_shield_destroy(thread_shield) : rb_thread_shield_release(thread_shield)) {
750  /* still in-use */
751  return ST_CONTINUE;
752  }
753  xfree((char *)*key);
754  return ST_DELETE;
755 }
756 
757 static void
758 load_unlock(const char *ftptr, int done)
759 {
760  if (ftptr) {
761  st_data_t key = (st_data_t)ftptr;
762  st_table *loading_tbl = get_loading_table();
763 
764  st_update(loading_tbl, key, release_thread_shield, done);
765  }
766 }
767 
768 
769 /*
770  * call-seq:
771  * require(name) -> true or false
772  *
773  * Loads the given +name+, returning +true+ if successful and +false+ if the
774  * feature is already loaded.
775  *
776  * If the filename does not resolve to an absolute path, it will be searched
777  * for in the directories listed in <code>$LOAD_PATH</code> (<code>$:</code>).
778  *
779  * If the filename has the extension ".rb", it is loaded as a source file; if
780  * the extension is ".so", ".o", or ".dll", or the default shared library
781  * extension on the current platform, Ruby loads the shared library as a
782  * Ruby extension. Otherwise, Ruby tries adding ".rb", ".so", and so on
783  * to the name until found. If the file named cannot be found, a LoadError
784  * will be raised.
785  *
786  * For Ruby extensions the filename given may use any shared library
787  * extension. For example, on Linux the socket extension is "socket.so" and
788  * <code>require 'socket.dll'</code> will load the socket extension.
789  *
790  * The absolute path of the loaded file is added to
791  * <code>$LOADED_FEATURES</code> (<code>$"</code>). A file will not be
792  * loaded again if its path already appears in <code>$"</code>. For example,
793  * <code>require 'a'; require './a'</code> will not load <code>a.rb</code>
794  * again.
795  *
796  * require "my-library.rb"
797  * require "db-driver"
798  *
799  * Any constants or globals within the loaded source file will be available
800  * in the calling program's global namespace. However, local variables will
801  * not be propagated to the loading environment.
802  *
803  */
804 
805 VALUE
807 {
808  return rb_require_safe(fname, rb_safe_level());
809 }
810 
811 /*
812  * call-seq:
813  * require_relative(string) -> true or false
814  *
815  * Ruby tries to load the library named _string_ relative to the requiring
816  * file's path. If the file's path cannot be determined a LoadError is raised.
817  * If a file is loaded +true+ is returned and false otherwise.
818  */
819 VALUE
821 {
823  if (NIL_P(base)) {
824  rb_loaderror("cannot infer basepath");
825  }
826  base = rb_file_dirname(base);
827  return rb_require_safe(rb_file_absolute_path(fname, base), rb_safe_level());
828 }
829 
830 static int
831 search_required(VALUE fname, volatile VALUE *path, int safe_level)
832 {
833  VALUE tmp;
834  char *ext, *ftptr;
835  int type, ft = 0;
836  const char *loading;
837 
838  *path = 0;
839  ext = strrchr(ftptr = RSTRING_PTR(fname), '.');
840  if (ext && !strchr(ext, '/')) {
841  if (IS_RBEXT(ext)) {
842  if (rb_feature_p(ftptr, ext, TRUE, FALSE, &loading)) {
843  if (loading) *path = rb_filesystem_str_new_cstr(loading);
844  return 'r';
845  }
846  if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) {
847  ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
848  if (!rb_feature_p(ftptr, ext, TRUE, TRUE, &loading) || loading)
849  *path = tmp;
850  return 'r';
851  }
852  return 0;
853  }
854  else if (IS_SOEXT(ext)) {
855  if (rb_feature_p(ftptr, ext, FALSE, FALSE, &loading)) {
856  if (loading) *path = rb_filesystem_str_new_cstr(loading);
857  return 's';
858  }
859  tmp = rb_str_subseq(fname, 0, ext - RSTRING_PTR(fname));
860 #ifdef DLEXT2
861  OBJ_FREEZE(tmp);
862  if (rb_find_file_ext_safe(&tmp, loadable_ext + 1, safe_level)) {
863  ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
864  if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
865  *path = tmp;
866  return 's';
867  }
868 #else
869  rb_str_cat2(tmp, DLEXT);
870  OBJ_FREEZE(tmp);
871  if ((tmp = rb_find_file_safe(tmp, safe_level)) != 0) {
872  ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
873  if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
874  *path = tmp;
875  return 's';
876  }
877 #endif
878  }
879  else if (IS_DLEXT(ext)) {
880  if (rb_feature_p(ftptr, ext, FALSE, FALSE, &loading)) {
881  if (loading) *path = rb_filesystem_str_new_cstr(loading);
882  return 's';
883  }
884  if ((tmp = rb_find_file_safe(fname, safe_level)) != 0) {
885  ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
886  if (!rb_feature_p(ftptr, ext, FALSE, TRUE, &loading) || loading)
887  *path = tmp;
888  return 's';
889  }
890  }
891  }
892  else if ((ft = rb_feature_p(ftptr, 0, FALSE, FALSE, &loading)) == 'r') {
893  if (loading) *path = rb_filesystem_str_new_cstr(loading);
894  return 'r';
895  }
896  tmp = fname;
897  type = rb_find_file_ext_safe(&tmp, loadable_ext, safe_level);
898  switch (type) {
899  case 0:
900  if (ft)
901  goto statically_linked;
902  ftptr = RSTRING_PTR(tmp);
903  return rb_feature_p(ftptr, 0, FALSE, TRUE, 0);
904 
905  default:
906  if (ft) {
907  statically_linked:
908  if (loading) *path = rb_filesystem_str_new_cstr(loading);
909  return ft;
910  }
911  case 1:
912  ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
913  if (rb_feature_p(ftptr, ext, !--type, TRUE, &loading) && !loading)
914  break;
915  *path = tmp;
916  }
917  return type ? 's' : 'r';
918 }
919 
920 static void
922 {
923  rb_load_fail(fname, "cannot load such file");
924 }
925 
926 static VALUE
928 {
930  return (VALUE)dln_load(RSTRING_PTR(path));
931 }
932 
933 VALUE
935 {
936  volatile VALUE result = Qnil;
938  volatile VALUE errinfo = th->errinfo;
939  int state;
940  struct {
941  int safe;
942  } volatile saved;
943  char *volatile ftptr = 0;
944 
947  rb_sourcefile(),
948  rb_sourceline());
949  }
950 
951  PUSH_TAG();
952  saved.safe = rb_safe_level();
953  if ((state = EXEC_TAG()) == 0) {
954  VALUE path;
955  long handle;
956  int found;
957 
959  FilePathValue(fname);
961 
964  rb_sourcefile(),
965  rb_sourceline());
966  }
967 
968  found = search_required(fname, &path, safe);
969 
972  rb_sourcefile(),
973  rb_sourceline());
974  }
975  if (found) {
976  if (!path || !(ftptr = load_lock(RSTRING_PTR(path)))) {
977  result = Qfalse;
978  }
979  else if (!*ftptr) {
980  rb_provide_feature(path);
981  result = Qtrue;
982  }
983  else {
984  switch (found) {
985  case 'r':
986  rb_load_internal(path, 0);
987  break;
988 
989  case 's':
990  handle = (long)rb_vm_call_cfunc(rb_vm_top_self(), load_ext,
991  path, 0, path);
993  break;
994  }
995  rb_provide_feature(path);
996  result = Qtrue;
997  }
998  }
999  }
1000  POP_TAG();
1001  load_unlock(ftptr, !state);
1002 
1003  rb_set_safe_level_force(saved.safe);
1004  if (state) {
1005  JUMP_TAG(state);
1006  }
1007 
1008  if (NIL_P(result)) {
1009  load_failed(fname);
1010  }
1011 
1012  th->errinfo = errinfo;
1013 
1016  rb_sourcefile(),
1017  rb_sourceline());
1018  }
1019 
1020  return result;
1021 }
1022 
1023 VALUE
1024 rb_require(const char *fname)
1025 {
1026  VALUE fn = rb_str_new2(fname);
1027  OBJ_FREEZE(fn);
1028  return rb_require_safe(fn, rb_safe_level());
1029 }
1030 
1031 static int
1033 {
1034  const char *name = (char *)*key;
1035  if (existing) {
1036  /* already registered */
1037  rb_warn("%s is already registered", name);
1038  }
1039  else {
1040  *value = (st_data_t)NEW_MEMO(init, 0, 0);
1041  *key = (st_data_t)ruby_strdup(name);
1042  }
1043  return ST_CONTINUE;
1044 }
1045 
1046 RUBY_FUNC_EXPORTED void
1047 ruby_init_ext(const char *name, void (*init)(void))
1048 {
1049  st_table *loading_tbl = get_loading_table();
1050 
1051  if (!loading_tbl) {
1052  GET_VM()->loading_table = loading_tbl = st_init_strtable();
1053  }
1054  st_update(loading_tbl, (st_data_t)name, register_init_ext, (st_data_t)init);
1055 }
1056 
1057 /*
1058  * call-seq:
1059  * mod.autoload(module, filename) -> nil
1060  *
1061  * Registers _filename_ to be loaded (using <code>Kernel::require</code>)
1062  * the first time that _module_ (which may be a <code>String</code> or
1063  * a symbol) is accessed in the namespace of _mod_.
1064  *
1065  * module A
1066  * end
1067  * A.autoload(:B, "b")
1068  * A::B.doit # autoloads "b"
1069  */
1070 
1071 static VALUE
1073 {
1074  ID id = rb_to_id(sym);
1075 
1076  FilePathValue(file);
1077  rb_autoload(mod, id, RSTRING_PTR(file));
1078  return Qnil;
1079 }
1080 
1081 /*
1082  * call-seq:
1083  * mod.autoload?(name) -> String or nil
1084  *
1085  * Returns _filename_ to be loaded if _name_ is registered as
1086  * +autoload+ in the namespace of _mod_.
1087  *
1088  * module A
1089  * end
1090  * A.autoload(:B, "b")
1091  * A.autoload?(:B) #=> "b"
1092  */
1093 
1094 static VALUE
1096 {
1097  ID id = rb_check_id(&sym);
1098  if (!id) {
1099  return Qnil;
1100  }
1101  return rb_autoload_p(mod, id);
1102 }
1103 
1104 /*
1105  * call-seq:
1106  * autoload(module, filename) -> nil
1107  *
1108  * Registers _filename_ to be loaded (using <code>Kernel::require</code>)
1109  * the first time that _module_ (which may be a <code>String</code> or
1110  * a symbol) is accessed.
1111  *
1112  * autoload(:MyModule, "/usr/local/lib/modules/my_module.rb")
1113  */
1114 
1115 static VALUE
1117 {
1119  if (NIL_P(klass)) {
1120  rb_raise(rb_eTypeError, "Can not set autoload on singleton class");
1121  }
1122  return rb_mod_autoload(klass, sym, file);
1123 }
1124 
1125 /*
1126  * call-seq:
1127  * autoload?(name) -> String or nil
1128  *
1129  * Returns _filename_ to be loaded if _name_ is registered as
1130  * +autoload+.
1131  *
1132  * autoload(:B, "b")
1133  * autoload?(:B) #=> "b"
1134  */
1135 
1136 static VALUE
1138 {
1139  /* use rb_vm_cbase() as same as rb_f_autoload. */
1140  VALUE klass = rb_vm_cbase();
1141  if (NIL_P(klass)) {
1142  return Qnil;
1143  }
1144  return rb_mod_autoload_p(klass, sym);
1145 }
1146 
1147 void
1149 {
1150 #undef rb_intern
1151 #define rb_intern(str) rb_intern2((str), strlen(str))
1152  rb_vm_t *vm = GET_VM();
1153  static const char var_load_path[] = "$:";
1154  ID id_load_path = rb_intern2(var_load_path, sizeof(var_load_path)-1);
1155 
1157  rb_alias_variable(rb_intern("$-I"), id_load_path);
1158  rb_alias_variable(rb_intern("$LOAD_PATH"), id_load_path);
1159  vm->load_path = rb_ary_new();
1162  vm->load_path_check_cache = 0;
1163 
1165  rb_define_virtual_variable("$LOADED_FEATURES", get_loaded_features, 0);
1166  vm->loaded_features = rb_ary_new();
1169 
1170  rb_define_global_function("load", rb_f_load, -1);
1171  rb_define_global_function("require", rb_f_require, 1);
1172  rb_define_global_function("require_relative", rb_f_require_relative, 1);
1173  rb_define_method(rb_cModule, "autoload", rb_mod_autoload, 2);
1174  rb_define_method(rb_cModule, "autoload?", rb_mod_autoload_p, 1);
1175  rb_define_global_function("autoload", rb_f_autoload, 2);
1176  rb_define_global_function("autoload?", rb_f_autoload_p, 1);
1177 
1180 }
VALUE data
Definition: tcltklib.c:3367
VALUE ruby_dln_librefs
Definition: load.c:13
#define RB_TYPE_P(obj, type)
#define nd_type(n)
RARRAY_PTR(q->result)[0]
volatile VALUE tmp
Definition: tcltklib.c:10208
static void features_index_add(VALUE feature, VALUE offset)
Definition: load.c:227
#define FilePathValue(v)
ssize_t n
Definition: bigdecimal.c:5676
VALUE expanded_load_path
Definition: vm_core.h:364
VALUE sym
Definition: tkutil.c:1298
volatile VALUE ary
Definition: tcltklib.c:9712
static VALUE get_loaded_features(void)
Definition: load.c:163
VALUE rb_ary_entry(VALUE ary, long offset)
Definition: array.c:1088
int rb_is_absolute_path(const char *)
Definition: file.c:5160
VALUE rb_require_safe(VALUE, int)
Definition: load.c:934
#define FALSE
Definition: nkf.h:174
RUBY_EXTERN VALUE rb_cModule
Definition: ripper.y:1445
static VALUE VALUE th
Definition: tcltklib.c:2947
size_t strlen(const char *)
#define RUBY_DTRACE_REQUIRE_ENTRY_ENABLED()
Definition: probes.h:23
Win32OLEIDispatch * p
Definition: win32ole.c:786
VALUE rb_get_path(VALUE)
Definition: file.c:224
static int register_init_ext(st_data_t *key, st_data_t *value, st_data_t init, int existing)
Definition: load.c:1032
VALUE rb_get_expanded_load_path(void)
Definition: load.c:111
int st_lookup(st_table *, st_data_t, st_data_t *)
VALUE rb_str_tmp_new(long)
#define RUBY_DTRACE_FIND_REQUIRE_ENTRY(arg0, arg1, arg2)
Definition: probes.h:32
int rb_file_load_ok(const char *)
Definition: file.c:5270
static void rb_load_internal(VALUE fname, int wrap)
Definition: load.c:574
#define rb_usascii_str_new2
void rb_secure(int)
Definition: safe.c:79
#define RUBY_DTRACE_LOAD_RETURN_ENABLED()
Definition: probes.h:43
struct st_table * loaded_features_index
Definition: vm_core.h:367
static void rb_provide_feature(VALUE feature)
Definition: load.c:549
ssize_t i
Definition: bigdecimal.c:5676
#define RUBY_DTRACE_FIND_REQUIRE_RETURN_ENABLED()
Definition: probes.h:35
#define T_NODE
#define SCOPE_SET(f)
Definition: eval_intern.h:186
#define RUBY_DTRACE_FIND_REQUIRE_ENTRY_ENABLED()
Definition: probes.h:31
VALUE rb_str_subseq(VALUE, long, long)
Definition: string.c:1669
int status
Definition: tcltklib.c:2196
VALUE rb_obj_freeze(VALUE)
Definition: object.c:1012
VALUE rb_eTypeError
Definition: error.c:516
void rb_define_hooked_variable(const char *, VALUE *, VALUE(*)(ANYARGS), void(*)(ANYARGS))
Definition: variable.c:575
#define OBJ_FREEZE(x)
const char * result
Definition: load.c:358
int rb_find_file_ext_safe(VALUE *, const char *const *, int)
Definition: file.c:5313
static VALUE load_ext(VALUE path)
Definition: load.c:927
VALUE rb_file_expand_path_fast(VALUE, VALUE)
Definition: file.c:3332
VALUE rb_ary_push(VALUE ary, VALUE item)
Definition: array.c:822
VALUE rb_require(const char *)
Definition: load.c:1024
#define numberof(array)
Definition: load.c:15
gz path
Definition: zlib.c:2277
VALUE rb_ary_tmp_new(long capa)
Definition: array.c:465
#define RSTRING_PTR(str)
NIL_P(eventloop_thread)
Definition: tcltklib.c:4067
#define T_ARRAY
VALUE rb_ary_shared_with_p(VALUE ary1, VALUE ary2)
Definition: array.c:358
VALUE rb_get_load_path(void)
Definition: load.c:34
int safe
Definition: tcltklib.c:6403
callq safe_level
Definition: tcltklib.c:7195
VALUE rb_find_file_safe(VALUE, int)
Definition: file.c:5388
#define xfree
VALUE rb_autoload_p(VALUE, ID)
Definition: variable.c:1810
void rb_raise(VALUE exc, const char *fmt,...)
Definition: error.c:1788
return Qtrue
Definition: tcltklib.c:9609
void rb_backtrace(void)
Definition: vm_backtrace.c:766
VALUE rb_f_require_relative(VALUE obj, VALUE fname)
Definition: load.c:820
st_table * st_init_strtable(void)
Definition: st.c:284
int index
Definition: tcltklib.c:4477
#define PUSH_TAG()
Definition: eval_intern.h:136
#define rb_str_new2
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
Definition: class.c:1530
#define IS_DLEXT(e)
Definition: load.c:22
int state
Definition: tcltklib.c:1461
void * rb_load_file(const char *)
Definition: pepper_main.c:824
ID rb_check_id(volatile VALUE *namep)
Returns ID for the given name if it is interned already, or 0.
Definition: ripper.c:17100
void rb_load_fail(VALUE path, const char *err)
Definition: error.c:1971
void rb_loaderror(const char *fmt,...)
Definition: error.c:1810
static int loaded_features_index_clear_i(st_data_t key, st_data_t val, st_data_t arg)
Definition: load.c:266
#define RUBY_DTRACE_REQUIRE_ENTRY(arg0, arg1, arg2)
Definition: probes.h:24
#define LONG2NUM(x)
static void reset_loaded_features_snapshot(void)
Definition: load.c:169
static int rb_feature_p(const char *feature, const char *ext, int rb, int expanded, const char **fn)
Definition: load.c:374
#define RUBY_DTRACE_LOAD_ENTRY_ENABLED()
Definition: probes.h:39
#define RUBY_DTRACE_LOAD_ENTRY(arg0, arg1, arg2)
Definition: probes.h:40
VALUE rb_str_equal(VALUE str1, VALUE str2)
Definition: string.c:2363
RUBY_EXTERN size_t strlcpy(char *, const char *, size_t)
static const char *const loadable_ext[]
Definition: load.c:25
static char * load_lock(const char *ftptr)
Definition: load.c:704
Definition: ripper.y:240
RUBY_EXTERN void ruby_init_ext(const char *name, void(*init)(void))
Definition: load.c:1047
#define NORETURN(x)
Definition: ruby.h:31
int rb_feature_provided(const char *, const char **)
Definition: load.c:523
void rb_exc_raise(VALUE mesg)
Definition: eval.c:527
static struct st_table * get_loaded_features_index_raw(void)
Definition: load.c:176
int st_update(st_table *table, st_data_t key, st_update_callback_func *func, st_data_t arg)
Definition: st.c:839
unsigned long st_data_t
Definition: ripper.y:35
#define DLEXT_MAXLEN
Definition: defines.h:233
*q done
Definition: tcltklib.c:2928
VALUE rb_find_file(VALUE)
Definition: file.c:5382
VALUE rb_file_dirname(VALUE fname)
Definition: file.c:3803
void rb_provide(const char *)
Definition: load.c:566
#define IS_SOEXT(e)
Definition: load.c:18
#define FIXNUM_P(f)
return Qfalse
Definition: tcltklib.c:6778
VALUE rb_iseq_new_top(NODE *node, VALUE name, VALUE path, VALUE absolute_path, VALUE parent)
Definition: iseq.c:418
#define RUBY_DTRACE_REQUIRE_RETURN_ENABLED()
Definition: probes.h:27
#define EXEC_TAG()
Definition: eval_intern.h:141
#define RARRAY_LEN(a)
VALUE rb_ary_cat(VALUE ary, const VALUE *ptr, long len)
Definition: array.c:833
#define Qnil
Definition: tcltklib.c:1895
#define StringValuePtr(v)
#define val
Definition: tcltklib.c:1948
VALUE rb_eRuntimeError
Definition: error.c:515
#define RUBY_DTRACE_LOAD_RETURN(arg0, arg1, arg2)
Definition: probes.h:44
char * ruby_strdup(const char *)
Definition: util.c:456
VALUE rb_get_path_check_convert(VALUE, VALUE, int)
Definition: file.c:197
VALUE rb_ary_replace(VALUE copy, VALUE orig)
Definition: array.c:3156
static VALUE load_path_getter(ID id, rb_vm_t *vm)
Definition: load.c:157
VALUE rb_ary_new(void)
Definition: array.c:424
#define Check_Type(v, t)
#define StringValueCStr(v)
unsigned long ID
Definition: ripper.y:105
static VALUE loaded_feature_path(const char *name, long vlen, const char *feature, long len, int type, VALUE load_path)
Definition: load.c:310
VALUE load_path_check_cache
Definition: vm_core.h:363
#define JUMP_TAG(st)
Definition: eval_intern.h:148
VALUE rb_str_cat2(VALUE, const char *)
Definition: string.c:1986
static VALUE VALUE obj
Definition: tcltklib.c:3157
#define RSTRING_LEN(str)
static int release_thread_shield(st_data_t *key, st_data_t *value, st_data_t done, int existing)
Definition: load.c:745
#define INT2FIX(i)
void rb_ary_store(VALUE ary, long idx, VALUE val)
Definition: array.c:719
#define FIX2LONG(x)
#define T_STRING
void rb_gvar_readonly_setter(VALUE val, ID id, void *data, struct rb_global_variable *gvar)
VALUE rb_thread_shield_wait(VALUE self)
Definition: thread.c:4629
VALUE top_self
Definition: vm_core.h:520
#define rb_sourcefile()
Definition: tcltklib.c:97
VALUE rb_str_freeze(VALUE)
Definition: string.c:1798
static VALUE rb_f_autoload(VALUE obj, VALUE sym, VALUE file)
Definition: load.c:1116
VALUE rb_thread_shield_release(VALUE self)
Definition: thread.c:4649
#define RUBY_FUNC_EXPORTED
Definition: defines.h:184
unsigned char buf[MIME_BUF_SIZE]
Definition: nkf.c:4308
#define POP_TAG()
Definition: eval_intern.h:137
int rb_provided(const char *)
Definition: load.c:517
static int VALUE key
Definition: tkutil.c:265
VALUE rb_vm_top_self()
Definition: vm.c:2494
static st_table * get_loading_table(void)
Definition: load.c:182
VALUE rb_file_absolute_path(VALUE, VALUE)
Definition: file.c:3368
VALUE rb_vm_call_cfunc(VALUE recv, VALUE(*func)(VALUE), VALUE arg, const rb_block_t *blockptr, VALUE filename)
Definition: vm.c:1588
gz level
Definition: zlib.c:2262
VALUE * argv
Definition: tcltklib.c:1970
#define NODE_MEMO
VALUE rb_str_resize(VALUE, long)
Definition: string.c:1854
VALUE rb_thread_shield_destroy(VALUE self)
Definition: thread.c:4660
#define RTEST(v)
int st_foreach(st_table *, int(*)(ANYARGS), st_data_t)
Definition: st.c:1006
VALUE rb_obj_clone(VALUE)
Definition: object.c:305
static VALUE load_path_getcwd(void)
Definition: load.c:102
#define TRUE
Definition: nkf.h:175
q result
Definition: tcltklib.c:7069
VALUE rb_f_require(VALUE, VALUE)
Definition: load.c:806
volatile VALUE value
Definition: tcltklib.c:9441
#define StringValue(v)
VALUE rb_vm_cbase(void)
Definition: vm.c:922
VALUE loaded_features
Definition: vm_core.h:365
register char * s
Definition: os2.c:56
void rb_gc_register_mark_object(VALUE)
Definition: gc.c:2982
VP_EXPORT void
Definition: bigdecimal.c:5104
int rb_scan_args(int argc, const VALUE *argv, const char *fmt,...)
Definition: class.c:1574
int st_get_key(st_table *, st_data_t, st_data_t *)
static int loaded_feature_path_i(st_data_t v, st_data_t b, st_data_t f)
Definition: load.c:362
#define OBJ_FROZEN(x)
#define RB_GC_GUARD(v)
int type
Definition: tcltklib.c:111
#define T_FIXNUM
static VALUE rb_mod_autoload_p(VALUE mod, VALUE sym)
Definition: load.c:1095
int argc
Definition: tcltklib.c:1969
VALUE rb_iseq_eval(VALUE iseqval)
Definition: vm.c:1498
void rb_set_safe_level_force(int)
Definition: safe.c:34
char * strchr(char *, char)
void rb_extend_object(VALUE obj, VALUE module)
Definition: eval.c:1227
static VALUE rb_f_load(int argc, VALUE *argv)
Definition: load.c:674
static st_table * get_loaded_features_index(void)
Definition: load.c:273
int rb_sourceline(void)
Definition: vm.c:884
void rb_load(VALUE, int)
Definition: load.c:638
ruby_verbose
Definition: tcltklib.c:5817
Real * b
Definition: bigdecimal.c:1196
void * dln_load(const char *file)
Definition: dln.c:1249
#define RUBY_DTRACE_FIND_REQUIRE_RETURN(arg0, arg1, arg2)
Definition: probes.h:36
#define my_getcwd()
Definition: util.h:72
#define MEMCPY(p1, p2, type, n)
#define NEW_MEMO(a, b, c)
ID rb_to_id(VALUE)
Definition: string.c:8169
static void features_index_add_single(VALUE short_feature, VALUE offset)
Definition: load.c:188
expand_type
Definition: load.c:40
arg
Definition: ripper.y:1317
VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict)
Definition: file.c:3513
#define f
VALUE top_wrapper
Definition: vm_core.h:521
static VALUE rb_mod_autoload(VALUE mod, VALUE sym, VALUE file)
Definition: load.c:1072
VALUE rb_module_new(void)
Definition: class.c:600
int mild_compile_error
Thread-local state of compiling context.
Definition: vm_core.h:576
VALUE rb_thread_shield_new(void)
Definition: thread.c:4613
klass
Definition: tcltklib.c:3503
static void rb_construct_expanded_load_path(int type, int *has_relative, int *has_non_cache)
Definition: load.c:53
VALUE load_path_snapshot
Definition: vm_core.h:362
int st_insert(st_table *, st_data_t, st_data_t)
void rb_define_virtual_variable(const char *, VALUE(*)(ANYARGS), void(*)(ANYARGS))
Definition: variable.c:606
VALUE loaded_features_snapshot
Definition: vm_core.h:366
#define rb_safe_level()
Definition: tcltklib.c:94
const char * name
Definition: load.c:354
#define RUBY_DTRACE_REQUIRE_RETURN(arg0, arg1, arg2)
Definition: probes.h:28
static int search_required(VALUE fname, volatile VALUE *path, int safe_level)
Definition: load.c:831
VALUE rb_class_real(VALUE)
Definition: object.c:171
BDIGIT e
Definition: bigdecimal.c:5106
static void load_failed(VALUE fname)
Definition: load.c:921
unsigned long VALUE
Definition: ripper.y:104
void rb_warning(const char *fmt,...)
Definition: error.c:234
VALUE rb_current_realfilepath(void)
Definition: vm_eval.c:1934
static VALUE rb_f_autoload_p(VALUE obj, VALUE sym)
Definition: load.c:1137
VALUE load_path
Definition: vm_core.h:361
VALUE rb_get_path_check_to_string(VALUE, int)
Definition: file.c:175
#define IS_RBEXT(e)
Definition: load.c:17
#define rb_intern(str)
BDIGIT v
Definition: bigdecimal.c:5677
#define mod(x, y)
Definition: date_strftime.c:28
ID rb_intern2(const char *name, long len)
Definition: ripper.c:16917
VALUE rb_filesystem_str_new_cstr(const char *)
Definition: string.c:614
static void load_unlock(const char *ftptr, int done)
Definition: load.c:758
void Init_load()
Definition: load.c:1148
#define NULL
Definition: _sdbm.c:103
void rb_load_protect(VALUE, int, int *)
Definition: load.c:646
const char * name
Definition: nkf.c:208
#define RNODE(obj)
void rb_vm_jump_tag_but_local_jump(int state)
Definition: vm.c:1007
static rb_thread_t * GET_THREAD(void)
Definition: vm_core.h:888
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
Definition: class.c:1348
void rb_warn(const char *fmt,...)
Definition: error.c:221
char * strrchr(const char *, const char)
void rb_alias_variable(ID, ID)
Definition: variable.c:863
#define GET_VM()
Definition: vm_core.h:881
void rb_autoload(VALUE, ID, const char *)
Definition: variable.c:1604
size_t len
Definition: tcltklib.c:3567