Ruby
2.7.2p137(2020-10-01revision5445e0435260b449decf2ac16f9d09bae3cafe72)
|
Go to the documentation of this file.
13 static VALUE ruby_dln_librefs;
15 #define IS_RBEXT(e) (strcmp((e), ".rb") == 0)
16 #define IS_SOEXT(e) (strcmp((e), ".so") == 0 || strcmp((e), ".o") == 0)
18 #define IS_DLEXT(e) (strcmp((e), DLEXT) == 0 || strcmp((e), DLEXT2) == 0)
20 #define IS_DLEXT(e) (strcmp((e), DLEXT) == 0)
23 static const char *
const loadable_ext[] = {
44 rb_construct_expanded_load_path(
enum expand_type type,
int *has_relative,
int *has_non_cache)
55 int is_string, non_cache;
59 non_cache = !is_string ? 1 : 0;
67 (!as_cstr[0] || as_cstr[0] !=
'~')) ||
76 if (!*has_non_cache && non_cache)
83 if (
NIL_P(expanded_path)) expanded_path = as_str;
99 int has_relative = 0, has_non_cache = 0;
100 rb_construct_expanded_load_path(
EXPAND_ALL, &has_relative, &has_non_cache);
104 else if (has_non_cache) {
113 int has_relative = 1, has_non_cache = 1;
116 &has_relative, &has_non_cache);
119 int has_relative = 1, has_non_cache = 1;
126 &has_relative, &has_non_cache);
131 &has_relative, &has_non_cache);
138 load_path_getter(
ID id,
VALUE * p)
145 get_loaded_features(
void)
147 return GET_VM()->loaded_features;
151 get_LOADED_FEATURES(
ID _x,
VALUE *_y)
153 return get_loaded_features();
157 reset_loaded_features_snapshot(
void)
164 get_loaded_features_index_raw(
void)
166 return GET_VM()->loaded_features_index;
170 get_loading_table(
void)
172 return GET_VM()->loading_table;
176 feature_key(
const char *
str,
size_t len)
182 features_index_add_single(
const char*
str,
size_t len,
VALUE offset)
189 short_feature_key = feature_key(
str,
len);
191 features_index = get_loaded_features_index_raw();
194 if (
NIL_P(this_feature_index)) {
198 VALUE feature_indexes[2];
199 feature_indexes[0] = this_feature_index;
200 feature_indexes[1] = offset;
221 features_index_add(
VALUE feature,
VALUE offset)
223 const char *feature_str, *feature_end, *ext, *p;
228 for (ext = feature_end; ext > feature_str; ext--)
229 if (*ext ==
'.' || *ext ==
'/')
236 p = ext ? ext : feature_end;
239 while (p >= feature_str && *p !=
'/')
244 features_index_add_single(p + 1, feature_end - p - 1, offset);
246 features_index_add_single(p + 1, ext - p - 1, offset);
249 features_index_add_single(feature_str, feature_end - feature_str, offset);
251 features_index_add_single(feature_str, ext - feature_str, offset);
267 get_loaded_features_index(
void)
285 features_index_add(as_str,
INT2FIX(
i));
287 reset_loaded_features_snapshot();
304 loaded_feature_path(
const char *
name,
long vlen,
const char *feature,
long len,
311 if (vlen <
len+1)
return 0;
316 for (e =
name + vlen;
name != e && *e !=
'.' && *e !=
'/'; --e);
323 if (plen > 0 &&
name[plen-1] !=
'/') {
334 if (plen > 0) --plen;
340 if (
n != plen)
continue;
358 const char *s = (
const char *)
v;
368 rb_feature_p(
const char *feature,
const char *ext,
int rb,
int expanded,
const char **fn)
372 long i,
len, elen,
n;
373 st_table *loading_tbl, *features_index;
382 type = rb ?
'r' :
's';
389 features = get_loaded_features();
390 features_index = get_loaded_features_index();
392 key = feature_key(feature,
strlen(feature));
420 if (!
NIL_P(this_feature_index)) {
430 entry = this_feature_index;
438 if (expanded)
continue;
445 if (!*(e =
f +
len)) {
449 if (*e !=
'.')
continue;
453 if ((rb || !ext) && (
IS_RBEXT(e))) {
459 loading_tbl = get_loading_table();
469 if ((
f = fs.result) != 0) {
475 if (fn) *fn = (
const char*)data;
477 if (!ext)
return 'u';
483 static const char so_ext[][4] = {
487 if (ext && *ext)
return 0;
491 for (
i = 0; (e = loadable_ext[
i]) != 0;
i++) {
495 if (fn) *fn = (
const char*)data;
496 return i ?
's' :
'r';
503 if (fn) *fn = (
const char*)data;
521 const char *ext =
strrchr(feature,
'.');
524 if (*feature ==
'.' &&
525 (feature[1] ==
'/' ||
strncmp(feature+1,
"./", 2) == 0)) {
529 if (ext && !
strchr(ext,
'/')) {
531 if (rb_feature_p(feature, ext,
TRUE,
FALSE, loading))
return TRUE;
535 if (rb_feature_p(feature, ext,
FALSE,
FALSE, loading))
return TRUE;
539 if (rb_feature_p(feature, 0,
TRUE,
FALSE, loading))
546 rb_provide_feature(
VALUE feature)
550 features = get_loaded_features();
553 "$LOADED_FEATURES is frozen; cannot append feature");
559 reset_loaded_features_snapshot();
584 rb_exec_event_hook_script_compiled(ec,
iseq,
Qnil);
595 #if !defined __GNUC__
609 load_iseq_eval(ec, fname);
613 #if !defined __GNUC__
635 rb_load_internal(
VALUE fname,
int wrap)
640 state = load_wrapping(ec, fname);
643 load_iseq_eval(ec, fname);
645 raise_load_if_failed(ec, state);
652 if (!tmp) load_failed(fname);
653 rb_load_internal(tmp, wrap);
667 if (state !=
TAG_NONE) *pstate = state;
698 load_failed(orig_fname);
709 load_lock(
const char *ftptr)
712 st_table *loading_tbl = get_loading_table();
719 return (
char *)ftptr;
730 VALUE warning =
rb_warning_string(
"loading in progress, circular require considered harmful - %s", ftptr);
739 return (
char *)ftptr;
761 load_unlock(
const char *ftptr,
int done)
765 st_table *loading_tbl = get_loading_table();
767 st_update(loading_tbl,
key, release_thread_shield, done);
833 typedef int (*
feature_func)(
const char *feature,
const char *ext,
int rb,
int expanded,
const char **fn);
845 if (ext && !
strchr(ext,
'/')) {
847 if (rb_feature_p(ftptr, ext,
TRUE,
FALSE, &loading)) {
853 if (!rb_feature_p(ftptr, ext,
TRUE,
TRUE, &loading) || loading)
860 if (rb_feature_p(ftptr, ext,
FALSE,
FALSE, &loading)) {
869 if (!rb_feature_p(ftptr, ext,
FALSE,
TRUE, &loading) || loading)
878 if (!rb_feature_p(ftptr, ext,
FALSE,
TRUE, &loading) || loading)
885 if (rb_feature_p(ftptr, ext,
FALSE,
FALSE, &loading)) {
891 if (!rb_feature_p(ftptr, ext,
FALSE,
TRUE, &loading) || loading)
897 else if ((ft = rb_feature_p(ftptr, 0,
FALSE,
FALSE, &loading)) ==
'r') {
906 goto statically_linked;
908 return rb_feature_p(ftptr, 0,
FALSE,
TRUE, 0);
919 if (rb_feature_p(ftptr, ext, !--
type,
TRUE, &loading) && !loading)
923 return type ?
's' :
'r';
927 load_failed(
VALUE fname)
940 no_feature_p(
const char *feature,
const char *ext,
int rb,
int expanded,
const char **fn)
955 found = search_required(
path, &
path, no_feature_p);
981 volatile int result = -1;
987 char *
volatile ftptr = 0;
1002 found = search_required(
path, &
path, rb_feature_p);
1015 load_iseq_eval(ec,
path);
1029 th = rb_ec_thread_ptr(ec);
1038 else if (exception) {
1069 return require_internal(ec, fname, 1);
1078 int result = require_internal(ec,
str, 0);
1080 return result ==
TAG_RETURN ? 1 : result ? -1 : 0;
1086 rb_warn(
"rb_require_safe will be removed in Ruby 3.0");
1088 int result = require_internal(ec, fname, 1);
1104 int result = require_internal(ec, fname, 1);
1125 const char *
name = (
char *)*
key;
1140 st_table *loading_tbl = get_loading_table();
1228 return rb_mod_autoload(
klass,
sym, file);
1257 #define rb_intern(str) rb_intern2((str), strlen(str))
1259 static const char var_load_path[] =
"$:";
1260 ID id_load_path =
rb_intern2(var_load_path,
sizeof(var_load_path)-1);
1268 vm->load_path_check_cache = 0;
int rb_feature_provided(const char *feature, const char **loading)
VALUE rb_parser_new(void)
struct st_table * loaded_features_index
VALUE rb_str_freeze(VALUE)
void rb_vm_jump_tag_but_local_jump(int state)
VALUE rb_iseq_eval(const rb_iseq_t *iseq)
ID rb_check_id(volatile VALUE *)
Returns ID for the given name if it is interned already, or 0.
VALUE rb_file_expand_path_fast(VALUE fname, VALUE dname)
VALUE rb_dir_getwd_ospath(void)
VALUE rb_f_require_relative(VALUE obj, VALUE fname)
VALUE rb_f_require(VALUE obj, VALUE fname)
void rb_gc_register_mark_object(VALUE obj)
void rb_warn(const char *fmt,...)
void rb_backtrace_each(VALUE(*iter)(VALUE recv, VALUE str), VALUE output)
VALUE rb_ary_shared_with_p(VALUE ary1, VALUE ary2)
void rb_warning(const char *fmt,...)
void rb_ary_free(VALUE ary)
void rb_ast_dispose(rb_ast_t *ast)
char * strchr(char *, char)
st_index_t st_hash(const void *ptr, size_t len, st_index_t h)
rb_iseq_t * rb_iseq_new_top(const rb_ast_body_t *ast, VALUE name, VALUE path, VALUE realpath, const rb_iseq_t *parent)
st_table * st_init_numtable(void)
void rb_gvar_readonly_setter(VALUE v, ID id, VALUE *_)
VALUE rb_get_expanded_load_path(void)
void rb_scope_visibility_set(rb_method_visibility_t)
VALUE rb_module_new(void)
VALUE rb_ary_replace(VALUE copy, VALUE orig)
void rb_ary_store(VALUE ary, long idx, VALUE val)
#define RB_TYPE_P(obj, type)
RUBY_EXTERN VALUE rb_cModule
void rb_define_global_function(const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a global function.
#define EC_JUMP_TAG(ec, st)
void rb_load_protect(VALUE fname, int wrap, int *pstate)
void rb_define_singleton_method(VALUE obj, const char *name, VALUE(*func)(ANYARGS), int argc)
Defines a singleton method for obj.
void rb_define_method(VALUE klass, const char *name, VALUE(*func)(ANYARGS), int argc)
int(* feature_func)(const char *feature, const char *ext, int rb, int expanded, const char **fn)
void rb_loaderror(const char *fmt,...)
VALUE rb_get_path(VALUE obj)
#define SPECIAL_CONST_P(x)
RUBY_SYMBOL_EXPORT_END void * rb_parser_load_file(VALUE parser, VALUE name)
VALUE rb_filesystem_str_new_cstr(const char *)
VALUE rb_check_realpath(VALUE basedir, VALUE path, rb_encoding *enc)
int st_insert(st_table *tab, st_data_t key, st_data_t value)
size_t strlen(const char *)
VALUE rb_autoload_at_p(VALUE, ID, int)
#define RUBY_FUNC_EXPORTED
#define VM_BLOCK_HANDLER_NONE
VALUE rb_str_resize(VALUE, long)
void rb_raise(VALUE exc, const char *fmt,...)
VALUE rb_ary_entry(VALUE ary, long offset)
void rb_define_virtual_variable(const char *q, type *w, void_type *e)
Define a function-backended global variable.
void rb_alias_variable(ID, ID)
void rb_load_fail(VALUE path, const char *err)
VALUE rb_thread_shield_new(void)
VALUE rb_thread_shield_wait(VALUE self)
VALUE rb_require_string(VALUE fname)
VALUE rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encoding *enc)
const rb_iseq_t * rb_iseq_load_iseq(VALUE fname)
VALUE rb_ary_cat(VALUE ary, const VALUE *argv, long len)
VALUE rb_ary_tmp_new(long capa)
VALUE rb_file_absolute_path(VALUE fname, VALUE dname)
VALUE rb_vm_top_self(void)
RUBY_SYMBOL_EXPORT_BEGIN typedef unsigned long st_data_t
VALUE rb_realpath_internal(VALUE basedir, VALUE path, int strict)
int rb_file_load_ok(const char *path)
VALUE rb_str_equal(VALUE str1, VALUE str2)
VALUE rb_ary_push(VALUE ary, VALUE item)
VALUE load_path_check_cache
VALUE rb_obj_freeze(VALUE)
Make the object unmodifiable.
#define RARRAY_AREF(a, i)
int rb_provided(const char *feature)
int rb_require_internal(VALUE fname)
RUBY_FUNC_EXPORTED void ruby_init_ext(const char *name, void(*init)(void))
VALUE rb_file_dirname(VALUE fname)
VALUE rb_require(const char *fname)
#define MEMO_NEW(a, b, c)
VALUE rb_get_path_check_convert(VALUE obj)
#define StringValuePtr(v)
RUBY_EXTERN size_t strlcpy(char *, const char *, size_t)
VALUE rb_thread_shield_destroy(VALUE self)
int st_update(st_table *tab, st_data_t key, st_update_callback_func *func, st_data_t arg)
void rb_extend_object(VALUE obj, VALUE module)
Extend the object with the module.
void rb_define_hooked_variable(const char *q, VALUE *w, type *e, void_type *r)
Define a function-backended global variable.
VALUE rb_vm_make_jump_tag_but_local_jump(int state, VALUE val)
int st_foreach(st_table *tab, st_foreach_callback_func *func, st_data_t arg)
VALUE rb_current_realfilepath(void)
unsigned char buf[MIME_BUF_SIZE]
void rb_exc_raise(VALUE mesg)
Raises an exception in the current thread.
ID rb_intern2(const char *, long)
VALUE rb_str_append(VALUE, VALUE)
VALUE rb_require_safe(VALUE fname, int safe)
void rb_set_errinfo(VALUE err)
Sets the current exception ($!) to the given value.
VALUE loaded_features_snapshot
VALUE rb_str_subseq(VALUE, long, long)
VALUE rb_get_path_check_to_string(VALUE obj)
char * strrchr(const char *, const char)
char str[HTML_ESCAPE_MAX_LEN+1]
#define MEMCPY(p1, p2, type, n)
VALUE rb_parser_set_context(VALUE vparser, const struct rb_iseq_struct *base, int main)
void * dln_load(const char *file)
void rb_autoload_str(VALUE mod, ID id, VALUE file)
VALUE rb_str_encode_ospath(VALUE path)
VALUE rb_warning_string(const char *fmt,...)
NORETURN(static void load_failed(VALUE))
VALUE rb_vm_call_cfunc(VALUE recv, VALUE(*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename)
VALUE rb_thread_shield_release(VALUE self)
#define RUBY_DTRACE_HOOK(name, arg)
char * ruby_strdup(const char *)
int rb_is_absolute_path(const char *path)
void rb_provide(const char *feature)
int ruby_require_internal(const char *fname, unsigned int len)
VALUE rb_resolve_feature_path(VALUE klass, VALUE fname)
VALUE rb_find_file(VALUE path)
void rb_load(VALUE fname, int wrap)
#define rb_fstring_lit(str)
int st_lookup(st_table *tab, st_data_t key, st_data_t *value)
int rb_find_file_ext(VALUE *filep, const char *const *ext)
VALUE rb_str_tmp_new(long)
VALUE type(ANYARGS)
ANYARGS-ed function type.
VALUE rb_obj_clone(VALUE)
Almost same as Object::clone.
int st_get_key(st_table *tab, st_data_t key, st_data_t *result)
VALUE rb_class_real(VALUE cl)
Looks up the nearest ancestor of cl, skipping singleton classes or module inclusions.