git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@943 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2000-09-18 16:28:40 +00:00
parent e1461461cc
commit 79a8072910
3 changed files with 65 additions and 61 deletions

View File

@ -2,10 +2,24 @@ Mon Sep 18 17:46:11 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
* stable version 1.6.0 released. * stable version 1.6.0 released.
Tue Sep 19 01:14:56 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (rb_provide): better feature handling.
* eval.c (rb_f_require): loading ruby library may be partial
state. checks in rb_thread_loading is integrated.
* eval.c (rb_provided): better thread awareness.
* lib/irb/frame.rb: 6 (not 5) parameters for trace_func proc.
* eval.c (error_print): should print error position even if
get_backtrace() failed.
Sat Sep 16 03:29:59 2000 Yukihiro Matsumoto <matz@ruby-lang.org> Sat Sep 16 03:29:59 2000 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (rb_f_require): rb_provided() called too early; does not * eval.c (rb_f_require): rb_provided() was called too early; does
work well with threads. not work well with threads.
* parse.y (ensure): should distinguish empty ensure and non * parse.y (ensure): should distinguish empty ensure and non
existing ensure. existing ensure.

90
eval.c
View File

@ -862,7 +862,7 @@ set_backtrace(info, bt)
static void static void
error_print() error_print()
{ {
VALUE errat; VALUE errat = Qnil;
VALUE eclass; VALUE eclass;
char *einfo; char *einfo;
int elen; int elen;
@ -877,7 +877,10 @@ error_print()
errat = Qnil; errat = Qnil;
} }
POP_TAG(); POP_TAG();
if (!NIL_P(errat)) { if (NIL_P(errat)) {
fprintf(stderr, "%s:%d", ruby_sourcefile, ruby_sourceline);
}
else {
VALUE mesg = RARRAY(errat)->ptr[0]; VALUE mesg = RARRAY(errat)->ptr[0];
if (NIL_P(mesg)) error_pos(); if (NIL_P(mesg)) error_pos();
@ -5018,6 +5021,7 @@ rb_f_load(argc, argv)
} }
static VALUE rb_features; static VALUE rb_features;
static st_table *loading_tbl;
static int static int
rb_provided(feature) rb_provided(feature)
@ -5031,19 +5035,32 @@ rb_provided(feature)
pend = p + RARRAY(rb_features)->len; pend = p + RARRAY(rb_features)->len;
while (p < pend) { while (p < pend) {
f = STR2CSTR(*p); f = STR2CSTR(*p);
if (strcmp(f, feature) == 0) return Qtrue; if (strcmp(f, feature) == 0) {
goto load_wait;
}
len = strlen(feature); len = strlen(feature);
if (strncmp(f, feature, len) == 0 if (strncmp(f, feature, len) == 0) {
&& (strcmp(f+len, ".rb") == 0 ||strcmp(f+len, ".so") == 0)) { if (strcmp(f+len, ".so") == 0) {
return Qtrue; return Qtrue;
} }
goto load_wait;
}
p++; p++;
} }
return Qfalse; return Qfalse;
}
static int rb_thread_loading _((const char*)); load_wait:
static void rb_thread_loading_done _((const char*)); if (loading_tbl) {
char *ext = strrchr(f, '.');
if (strcmp(ext, ".rb") == 0) {
while (st_lookup(loading_tbl, f, 0)) {
CHECK_INTS;
rb_thread_schedule();
}
}
}
return Qtrue;
}
void void
rb_provide(feature) rb_provide(feature)
@ -5051,17 +5068,20 @@ rb_provide(feature)
{ {
char *buf, *ext; char *buf, *ext;
if (!rb_provided(feature)) {
ext = strrchr(feature, '.'); ext = strrchr(feature, '.');
if (ext && strcmp(DLEXT, ext) == 0) { if (ext && (strcmp(DLEXT, ext) == 0
#ifdef DLEXT2
|| strcmp(DLEXT2, ext) == 0
#endif
)) {
buf = ALLOCA_N(char, strlen(feature)+4); buf = ALLOCA_N(char, strlen(feature)+4);
strcpy(buf, feature); strcpy(buf, feature);
ext = strrchr(buf, '.'); ext = strrchr(buf, '.');
strcpy(ext, ".so"); strcpy(ext, ".so");
feature = buf; feature = buf;
} }
if (rb_provided(feature)) return;
rb_ary_push(rb_features, rb_str_new2(feature)); rb_ary_push(rb_features, rb_str_new2(feature));
}
} }
VALUE VALUE
@ -5074,21 +5094,19 @@ rb_f_require(obj, fname)
volatile int safe = ruby_safe_level; volatile int safe = ruby_safe_level;
Check_SafeStr(fname); Check_SafeStr(fname);
if (rb_provided(RSTRING(fname)->ptr)) return Qfalse;
ext = strrchr(RSTRING(fname)->ptr, '.'); ext = strrchr(RSTRING(fname)->ptr, '.');
if (ext) { if (ext) {
if (strcmp(".rb", ext) == 0) {
feature = file = RSTRING(fname)->ptr; feature = file = RSTRING(fname)->ptr;
if (strcmp(".rb", ext) == 0) {
file = rb_find_file(file); file = rb_find_file(file);
if (file) goto load_rb; if (file) goto load_rb;
} }
else if (strcmp(".so", ext) == 0 || strcmp(".o", ext) == 0) { else if (strcmp(".so", ext) == 0 || strcmp(".o", ext) == 0) {
file = feature = RSTRING(fname)->ptr;
if (strcmp(ext, DLEXT) != 0) { if (strcmp(ext, DLEXT) != 0) {
buf = ALLOCA_N(char, strlen(file)+sizeof(DLEXT)+4); buf = ALLOCA_N(char, strlen(file)+sizeof(DLEXT)+4);
strcpy(buf, feature); strcpy(buf, feature);
ext = strrchr(buf, '.'); ext = strrchr(buf, '.');
strcpy(ext, ".so");
if (rb_provided(buf)) return Qfalse;
strcpy(ext, DLEXT); strcpy(ext, DLEXT);
file = feature = buf; file = feature = buf;
} }
@ -5100,8 +5118,6 @@ rb_f_require(obj, fname)
buf = ALLOCA_N(char, strlen(file)+sizeof(DLEXT2)+4); buf = ALLOCA_N(char, strlen(file)+sizeof(DLEXT2)+4);
strcpy(buf, feature); strcpy(buf, feature);
ext = strrchr(buf, '.'); ext = strrchr(buf, '.');
strcpy(ext, ".so");
if (rb_provided(buf)) return Qfalse;
strcpy(ext, DLEXT2); strcpy(ext, DLEXT2);
file = feature = buf; file = feature = buf;
} }
@ -5150,7 +5166,6 @@ rb_f_require(obj, fname)
RSTRING(fname)->ptr); RSTRING(fname)->ptr);
load_dyna: load_dyna:
if (rb_thread_loading(feature)) return Qfalse;
rb_provide(feature); rb_provide(feature);
PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_NONE);
@ -5160,22 +5175,26 @@ rb_f_require(obj, fname)
dln_load(file); dln_load(file);
} }
POP_TAG(); POP_TAG();
rb_thread_loading_done(feature);
if (state) JUMP_TAG(state); if (state) JUMP_TAG(state);
return Qtrue; return Qtrue;
load_rb: load_rb:
ruby_safe_level = 0; ruby_safe_level = 0;
if (rb_thread_loading(feature)) return Qfalse;
rb_provide(feature); rb_provide(feature);
/* loading ruby library should be serialized. */
if (!loading_tbl) {
loading_tbl = st_init_strtable();
}
st_insert(loading_tbl, strdup(feature), 0); /* partial state */
PUSH_TAG(PROT_NONE); PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) { if ((state = EXEC_TAG()) == 0) {
rb_load(fname, 0); rb_load(fname, 0);
} }
POP_TAG(); POP_TAG();
rb_thread_loading_done(feature); st_delete(loading_tbl, &feature, 0); /* loading done */
free(feature);
ruby_safe_level = safe; ruby_safe_level = safe;
if (state) JUMP_TAG(state); if (state) JUMP_TAG(state);
@ -8013,35 +8032,6 @@ rb_thread_raise(argc, argv, thread)
return Qnil; /* not reached */ return Qnil; /* not reached */
} }
static st_table *loading_tbl;
static int
rb_thread_loading(feature)
const char *feature;
{
if (!loading_tbl) {
loading_tbl = st_init_strtable();
}
if (!rb_provided(feature)) {
st_insert(loading_tbl, feature, 0);
return Qfalse; /* need to load */
}
while (st_lookup(loading_tbl, feature, 0)) {
CHECK_INTS;
rb_thread_schedule();
}
return Qtrue;
}
static void
rb_thread_loading_done(feature)
const char *feature;
{
if (loading_tbl) {
st_delete(loading_tbl, &feature, 0);
}
}
VALUE VALUE
rb_thread_local_aref(thread, id) rb_thread_local_aref(thread, id)
VALUE thread; VALUE thread;

View File

@ -60,7 +60,7 @@ module IRB
end end
@backtrace = Frame.new @backtrace = Frame.new
set_trace_func proc{|event, file, line, id, binding| set_trace_func proc{|event, file, line, id, binding, klass|
@backtrace.trace_func(event, file, line, id, binding) @backtrace.trace_func(event, file, line, id, binding)
} }
end end