Exemplo n.º 1
0
static st_table *
get_loaded_features_index(void)
{
    VALUE features;
    int i;
    rb_vm_t *vm = GET_VM();

    if (!rb_ary_shared_with_p(vm->loaded_features_snapshot, vm->loaded_features)) {
	/* The sharing was broken; something (other than us in rb_provide_feature())
	   modified loaded_features.  Rebuild the index. */
	st_foreach(vm->loaded_features_index, loaded_features_index_clear_i, 0);
	features = vm->loaded_features;
	for (i = 0; i < RARRAY_LEN(features); i++) {
	    VALUE entry, as_str;
	    as_str = entry = rb_ary_entry(features, i);
	    StringValue(as_str);
	    as_str = rb_fstring(rb_str_freeze(as_str));
	    if (as_str != entry)
		rb_ary_store(features, i, as_str);
	    features_index_add(as_str, INT2FIX(i));
	}
	reset_loaded_features_snapshot();
    }
    return vm->loaded_features_index;
}
Exemplo n.º 2
0
static int
load_encoding(const char *name)
{
    VALUE enclib = rb_sprintf("enc/%s.so", name);
    VALUE verbose = ruby_verbose;
    VALUE debug = ruby_debug;
    VALUE errinfo;
    char *s = RSTRING_PTR(enclib) + 4, *e = RSTRING_END(enclib) - 3;
    int loaded;
    int idx;

    while (s < e) {
	if (!ISALNUM(*s)) *s = '_';
	else if (ISUPPER(*s)) *s = (char)TOLOWER(*s);
	++s;
    }
    FL_UNSET(enclib, FL_TAINT);
    enclib = rb_fstring(enclib);
    ruby_verbose = Qfalse;
    ruby_debug = Qfalse;
    errinfo = rb_errinfo();
    loaded = rb_require_internal(enclib, rb_safe_level());
    ruby_verbose = verbose;
    ruby_debug = debug;
    rb_set_errinfo(errinfo);
    if (loaded < 0 || 1 < loaded) return -1;
    if ((idx = rb_enc_registered(name)) < 0) return -1;
    if (enc_autoload_p(enc_table.list[idx].enc)) return -1;
    return idx;
}
Exemplo n.º 3
0
/* Construct expanded load path and store it to cache.
   We rebuild load path partially if the cache is invalid.
   We don't cache non string object and expand it every time. We ensure that
   string objects in $LOAD_PATH are frozen.
 */
static void
rb_construct_expanded_load_path(int type, int *has_relative, int *has_non_cache)
{
    rb_vm_t *vm = GET_VM();
    VALUE load_path = vm->load_path;
    VALUE expanded_load_path = vm->expanded_load_path;
    VALUE ary;
    long i;
    int level = rb_safe_level();

    ary = rb_ary_tmp_new(RARRAY_LEN(load_path));
    for (i = 0; i < RARRAY_LEN(load_path); ++i) {
	VALUE path, as_str, expanded_path;
	int is_string, non_cache;
	char *as_cstr;
	as_str = path = RARRAY_AREF(load_path, i);
	is_string = RB_TYPE_P(path, T_STRING) ? 1 : 0;
	non_cache = !is_string ? 1 : 0;
	as_str = rb_get_path_check_to_string(path, level);
	as_cstr = RSTRING_PTR(as_str);

	if (!non_cache) {
	    if ((type == EXPAND_RELATIVE &&
		    rb_is_absolute_path(as_cstr)) ||
		(type == EXPAND_HOME &&
		    (!as_cstr[0] || as_cstr[0] != '~')) ||
		(type == EXPAND_NON_CACHE)) {
		    /* Use cached expanded path. */
		    rb_ary_push(ary, RARRAY_AREF(expanded_load_path, i));
		    continue;
	    }
	}
	if (!*has_relative && !rb_is_absolute_path(as_cstr))
	    *has_relative = 1;
	if (!*has_non_cache && non_cache)
	    *has_non_cache = 1;
	/* Freeze only string object. We expand other objects every time. */
	if (is_string)
	    rb_str_freeze(path);
	as_str = rb_get_path_check_convert(path, as_str, level);
	expanded_path = rb_file_expand_path_fast(as_str, Qnil);
	rb_str_freeze(expanded_path);
	rb_ary_push(ary, rb_fstring(expanded_path));
    }
    rb_obj_freeze(ary);
    vm->expanded_load_path = ary;
    rb_ary_replace(vm->load_path_snapshot, vm->load_path);
}
Exemplo n.º 4
0
static void
rb_provide_feature(VALUE feature)
{
    VALUE features;

    features = get_loaded_features();
    if (OBJ_FROZEN(features)) {
	rb_raise(rb_eRuntimeError,
		 "$LOADED_FEATURES is frozen; cannot append feature");
    }
    rb_str_freeze(feature);

    rb_ary_push(features, rb_fstring(feature));
    features_index_add(feature, INT2FIX(RARRAY_LEN(features)-1));
    reset_loaded_features_snapshot();
}