Example #1
0
static int
rb_load_internal0(rb_thread_t *th, VALUE fname, int wrap)
{
    int state;
    volatile VALUE wrapper = th->top_wrapper;
    volatile VALUE self = th->top_self;
    volatile int loaded = FALSE;
    volatile int mild_compile_error;
#if !defined __GNUC__
    rb_thread_t *volatile th0 = th;
#endif

    th->errinfo = Qnil; /* ensure */

    if (!wrap) {
	th->top_wrapper = 0;
    }
    else {
	/* load in anonymous module as toplevel */
	th->top_self = rb_obj_clone(rb_vm_top_self());
	th->top_wrapper = rb_module_new();
	rb_extend_object(th->top_self, th->top_wrapper);
    }

    mild_compile_error = th->mild_compile_error;
    TH_PUSH_TAG(th);
    state = EXEC_TAG();
    if (state == 0) {
	NODE *node;
	rb_iseq_t *iseq;

	th->mild_compile_error++;
	node = (NODE *)rb_load_file_str(fname);
	loaded = TRUE;
	iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, rb_realpath_internal(Qnil, fname, 1), NULL);
	th->mild_compile_error--;
	rb_iseq_eval(iseq);
    }
    TH_POP_TAG();

#if !defined __GNUC__
    th = th0;
    fname = RB_GC_GUARD(fname);
#endif
    th->mild_compile_error = mild_compile_error;
    th->top_self = self;
    th->top_wrapper = wrapper;

    if (!loaded && !FIXNUM_P(th->errinfo)) {
	/* an error on loading don't include INT2FIX(TAG_FATAL) see r35625 */
	return TAG_RAISE;
    }
    if (state) {
	VALUE exc = rb_vm_make_jump_tag_but_local_jump(state, Qundef);
	if (NIL_P(exc)) return state;
	th->errinfo = exc;
	return TAG_RAISE;
    }

    if (!NIL_P(th->errinfo)) {
	/* exception during load */
	return TAG_RAISE;
    }
    return state;
}
Example #2
0
File: ruby.c Project: ayumin/ruby
void
ruby_init_loadpath_safe(int safe_level)
{
    VALUE load_path;
    ID id_initial_load_path_mark;
    extern const char ruby_initial_load_paths[];
    const char *paths = ruby_initial_load_paths;
#if defined LOAD_RELATIVE
# if defined HAVE_DLADDR || defined HAVE_CYGWIN_CONV_PATH
#   define VARIABLE_LIBPATH 1
# else
#   define VARIABLE_LIBPATH 0
# endif
# if VARIABLE_LIBPATH
    char *libpath;
    VALUE sopath;
# else
    char libpath[MAXPATHLEN + 1];
# endif
    size_t baselen;
    char *p;

#if defined _WIN32 || defined __CYGWIN__
# if VARIABLE_LIBPATH
    sopath = rb_str_new(0, MAXPATHLEN);
    libpath = RSTRING_PTR(sopath);
    GetModuleFileName(libruby, libpath, MAXPATHLEN);
# else
    GetModuleFileName(libruby, libpath, sizeof libpath);
# endif
#elif defined(__EMX__)
    _execname(libpath, sizeof(libpath) - 1);
#elif defined(HAVE_DLADDR)
    Dl_info dli;
    if (dladdr((void *)(VALUE)expand_include_path, &dli)) {
	char fbuf[MAXPATHLEN];
	char *f = dln_find_file_r(dli.dli_fname, getenv(PATH_ENV), fbuf, sizeof(fbuf));
	VALUE fname = rb_str_new_cstr(f ? f : dli.dli_fname);
	rb_str_freeze(fname);
	sopath = rb_realpath_internal(Qnil, fname, 1);
    }
    else {
	sopath = rb_str_new(0, 0);
    }
    libpath = RSTRING_PTR(sopath);
#endif

#if !VARIABLE_LIBPATH
    libpath[sizeof(libpath) - 1] = '\0';
#endif
#if defined DOSISH
    translit_char(libpath, '\\', '/');
#elif defined __CYGWIN__
    {
# if VARIABLE_LIBPATH
	const int win_to_posix = CCP_WIN_A_TO_POSIX | CCP_RELATIVE;
	size_t newsize = cygwin_conv_path(win_to_posix, libpath, 0, 0);
	if (newsize > 0) {
	    VALUE rubylib = rb_str_new(0, newsize);
	    p = RSTRING_PTR(rubylib);
	    if (cygwin_conv_path(win_to_posix, libpath, p, newsize) == 0) {
		rb_str_resize(sopath, 0);
		sopath = rubylib;
		libpath = p;
	    }
	}
# else
	char rubylib[FILENAME_MAX];
	cygwin_conv_to_posix_path(libpath, rubylib);
	strncpy(libpath, rubylib, sizeof(libpath));
# endif
    }
#endif
    p = strrchr(libpath, '/');
    if (p) {
	*p = 0;
	if (p - libpath > 3 && !(STRCASECMP(p - 4, "/bin") && strcmp(p - 4, "/lib"))) {
	    p -= 4;
	    *p = 0;
	}
    }
#if !VARIABLE_LIBPATH
    else {
	strlcpy(libpath, ".", sizeof(libpath));
	p = libpath + 1;
    }
    baselen = p - libpath;
#define PREFIX_PATH() rb_str_new(libpath, baselen)
#else
    baselen = p - libpath;
    rb_str_resize(sopath, baselen);
    libpath = RSTRING_PTR(sopath);
#define PREFIX_PATH() sopath
#endif

#define BASEPATH() rb_str_buf_cat(rb_str_buf_new(baselen+len), libpath, baselen)

#define RUBY_RELATIVE(path, len) rb_str_buf_cat(BASEPATH(), (path), (len))
#else
    static const char exec_prefix[] = RUBY_EXEC_PREFIX;
#define RUBY_RELATIVE(path, len) rubylib_mangled_path((path), (len))
#define PREFIX_PATH() RUBY_RELATIVE(exec_prefix, sizeof(exec_prefix)-1)
#endif
    load_path = GET_VM()->load_path;

    if (safe_level == 0) {
#ifdef MANGLED_PATH
	rubylib_mangled_path("", 0);
#endif
	ruby_push_include(getenv("RUBYLIB"), identical_path);
    }

    id_initial_load_path_mark = rb_intern_const("@gem_prelude_index");
    while (*paths) {
	size_t len = strlen(paths);
	VALUE path = RUBY_RELATIVE(paths, len);
	rb_ivar_set(path, id_initial_load_path_mark, path);
	rb_ary_push(load_path, path);
	paths += len + 1;
    }

    rb_const_set(rb_cObject, rb_intern_const("TMP_RUBY_PREFIX"), rb_obj_freeze(PREFIX_PATH()));
}
Example #3
0
static int
rb_load_internal0(rb_execution_context_t *ec, VALUE fname, int wrap)
{
    enum ruby_tag_type state;
    rb_thread_t *th = rb_ec_thread_ptr(ec);
    volatile VALUE wrapper = th->top_wrapper;
    volatile VALUE self = th->top_self;
#if !defined __GNUC__
    rb_thread_t *volatile th0 = th;
#endif

    th->ec->errinfo = Qnil; /* ensure */

    if (!wrap) {
	th->top_wrapper = 0;
    }
    else {
	/* load in anonymous module as toplevel */
	th->top_self = rb_obj_clone(rb_vm_top_self());
	th->top_wrapper = rb_module_new();
	rb_extend_object(th->top_self, th->top_wrapper);
    }

    EC_PUSH_TAG(th->ec);
    state = EC_EXEC_TAG();
    if (state == TAG_NONE) {
	rb_ast_t *ast;
	const rb_iseq_t *iseq;

	if ((iseq = rb_iseq_load_iseq(fname)) != NULL) {
	    /* OK */
	}
	else {
	    VALUE parser = rb_parser_new();
	    rb_parser_set_context(parser, NULL, FALSE);
	    ast = (rb_ast_t *)rb_parser_load_file(parser, fname);
	    iseq = rb_iseq_new_top(&ast->body, rb_fstring_lit("<top (required)>"),
			    fname, rb_realpath_internal(Qnil, fname, 1), NULL);
	    rb_ast_dispose(ast);
	}
        rb_exec_event_hook_script_compiled(ec, iseq, Qnil);
        rb_iseq_eval(iseq);
    }
    EC_POP_TAG();

#if !defined __GNUC__
    th = th0;
    fname = RB_GC_GUARD(fname);
#endif
    th->top_self = self;
    th->top_wrapper = wrapper;

    if (state) {
	/* usually state == TAG_RAISE only, except for
	 * rb_iseq_load_iseq case */
	VALUE exc = rb_vm_make_jump_tag_but_local_jump(state, Qundef);
	if (NIL_P(exc)) return state;
	th->ec->errinfo = exc;
	return TAG_RAISE;
    }

    if (!NIL_P(th->ec->errinfo)) {
	/* exception during load */
	return TAG_RAISE;
    }
    return state;
}
Example #4
0
static void
rb_load_internal(VALUE fname, int wrap)
{
    int state;
    rb_thread_t *th = GET_THREAD();
    volatile VALUE wrapper = th->top_wrapper;
    volatile VALUE self = th->top_self;
    volatile int loaded = FALSE;
    volatile int mild_compile_error;
#ifndef __GNUC__
    rb_thread_t *volatile th0 = th;
#endif

    th->errinfo = Qnil; /* ensure */

    if (!wrap) {
	rb_secure(4);		/* should alter global state */
	th->top_wrapper = 0;
    }
    else {
	/* load in anonymous module as toplevel */
	th->top_self = rb_obj_clone(rb_vm_top_self());
	th->top_wrapper = rb_module_new();
	rb_extend_object(th->top_self, th->top_wrapper);
    }

    mild_compile_error = th->mild_compile_error;
    PUSH_TAG();
    state = EXEC_TAG();
    if (state == 0) {
	NODE *node;
	VALUE iseq;

	th->mild_compile_error++;
	node = (NODE *)rb_load_file(RSTRING_PTR(fname));
	loaded = TRUE;
	iseq = rb_iseq_new_top(node, rb_str_new2("<top (required)>"), fname, rb_realpath_internal(Qnil, fname, 1), Qfalse);
	th->mild_compile_error--;
	rb_iseq_eval(iseq);
    }
    POP_TAG();

#ifndef __GNUC__
    th = th0;
    fname = RB_GC_GUARD(fname);
#endif
    th->mild_compile_error = mild_compile_error;
    th->top_self = self;
    th->top_wrapper = wrapper;

    if (!loaded) {
	rb_exc_raise(GET_THREAD()->errinfo);
    }
    if (state) {
	rb_vm_jump_tag_but_local_jump(state, Qundef);
    }

    if (!NIL_P(GET_THREAD()->errinfo)) {
	/* exception during load */
	rb_exc_raise(th->errinfo);
    }
}