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