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