* eval.c (eval): do not re-raise exception to avoid unnecessary

exception copying, instead modify exception and internal
  information to adjust eval().

* eval.c (backtrace): can return the current frame information
  only if lev < -1.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@4962 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 2003-11-15 23:45:26 +00:00
Родитель abbffef10c
Коммит 8eb537a88a
3 изменённых файлов: 79 добавлений и 51 удалений

Просмотреть файл

@ -1,3 +1,12 @@
Sun Nov 16 04:41:33 2003 Yukihiro Matsumoto <matz@ruby-lang.org>
* eval.c (eval): do not re-raise exception to avoid unnecessary
exception copying, instead modify exception and internal
information to adjust eval().
* eval.c (backtrace): can return the current frame information
only if lev < -1.
Sat Nov 15 22:16:42 2003 GOTOU Yuuzou <gotoyuzo@notwork.org>
* /ext/openssl/ossl_x509ext.c (ossl_x509extfactory_create_ext):

Просмотреть файл

@ -479,8 +479,9 @@ name_err_initialize(argc, argv, self)
VALUE *argv;
VALUE self;
{
VALUE name = (argc > 1) ? argv[--argc] : Qnil;
VALUE name;
name = (argc > 1) ? argv[--argc] : Qnil;
exc_initialize(argc, argv, self);
rb_iv_set(self, "name", name);
return self;

118
eval.c
Просмотреть файл

@ -1328,7 +1328,6 @@ void rb_exec_end_proc _((void));
static void
ruby_finalize_0()
{
ruby_errinfo = 0;
PUSH_TAG(PROT_NONE);
if (EXEC_TAG() == 0) {
rb_trap_exit();
@ -4719,6 +4718,58 @@ static int last_call_status;
#define CSTAT_VCALL 4
#define CSTAT_SUPER 8
static VALUE
name_err_to_s(exc)
VALUE exc;
{
VALUE mesg = rb_attr_get(exc, rb_intern("mesg"));
ID id_recv = rb_intern("recv");
if (NIL_P(mesg)) return rb_class_path(CLASS_OF(exc));
if (rb_ivar_defined(exc, id_recv)) {
char buf[BUFSIZ];
char *desc = "";
volatile VALUE d = 0;
int noclass;
VALUE obj = rb_ivar_get(exc, id_recv);
int state;
switch (TYPE(obj)) {
case T_NIL:
desc = "nil";
break;
case T_TRUE:
desc = "true";
break;
case T_FALSE:
desc = "false";
break;
default:
PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
d = rb_inspect(obj);
}
POP_TAG();
if (!d || RSTRING(d)->len > 65) {
d = rb_any_to_s(obj);
}
break;
}
if (d) {
desc = RSTRING(d)->ptr;
}
noclass = (!desc || desc[0]=='#');
snprintf(buf, BUFSIZ, RSTRING(mesg)->ptr, desc,
noclass ? "" : ":",
noclass ? "" : rb_obj_classname(obj));
mesg = rb_str_new2(buf);
rb_iv_set(exc, "mesg", mesg);
st_delete(ROBJECT(exc)->iv_tbl, (st_data_t*)&id_recv, 0);
}
if (OBJ_TAINTED(exc)) OBJ_TAINT(mesg);
return mesg;
}
static VALUE
rb_method_missing(argc, argv, obj)
int argc;
@ -4727,11 +4778,8 @@ rb_method_missing(argc, argv, obj)
{
ID id;
VALUE exc = rb_eNoMethodError;
volatile VALUE d = 0;
char *format = 0;
char *desc = "";
NODE *cnode = ruby_current_node;
int state;
if (argc == 0 || !SYMBOL_P(argv[0])) {
rb_raise(rb_eArgError, "no id given");
@ -4741,64 +4789,37 @@ rb_method_missing(argc, argv, obj)
id = SYM2ID(argv[0]);
switch (TYPE(obj)) {
case T_NIL:
desc = "nil";
break;
case T_TRUE:
desc = "true";
break;
case T_FALSE:
desc = "false";
break;
default:
PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
d = rb_inspect(obj);
}
POP_TAG();
if (!d || RSTRING(d)->len > 65) {
d = rb_any_to_s(obj);
}
break;
}
if (d) {
desc = RSTRING(d)->ptr;
}
if (last_call_status & CSTAT_PRIV) {
format = "private method `%s' called for %s%s%s";
format = "private method `%s' called for %%s%%s%%s";
}
else if (last_call_status & CSTAT_PROT) {
format = "protected method `%s' called for %s%s%s";
format = "protected method `%s' called for %%s%%s%%s";
}
else if (last_call_status & CSTAT_VCALL) {
format = "undefined local variable or method `%s' for %s%s%s";
format = "undefined local variable or method `%s' for %%s%%s%%s";
exc = rb_eNameError;
}
else if (last_call_status & CSTAT_SUPER) {
format = "super: no superclass method `%s'";
}
if (!format) {
format = "undefined method `%s' for %s%s%s";
format = "undefined method `%s' for %%s%%s%%s";
}
ruby_current_node = cnode;
{
char buf[BUFSIZ];
int noclass = (!desc || desc[0]=='#');
int n = 0;
VALUE args[3];
snprintf(buf, BUFSIZ, format, rb_id2name(id),
desc, noclass ? "" : ":",
noclass ? "" : rb_obj_classname(obj));
snprintf(buf, BUFSIZ, format, rb_id2name(id));
args[n++] = rb_str_new2(buf);
args[n++] = argv[0];
if (exc == rb_eNoMethodError) {
args[n++] = rb_ary_new4(argc-1, argv+1);
}
exc = rb_class_new_instance(n, args, exc);
rb_iv_set(exc, "recv", obj);
ruby_frame = ruby_frame->prev; /* pop frame for "method_missing" */
rb_exc_raise(exc);
}
@ -5357,6 +5378,7 @@ backtrace(lev)
snprintf(buf, BUFSIZ, "%s:%d", ruby_sourcefile, ruby_sourceline);
}
rb_ary_push(ary, rb_str_new2(buf));
if (lev < -1) return ary;
}
else {
while (lev-- > 0) {
@ -5557,20 +5579,13 @@ eval(self, src, scope, file, line)
ruby_set_current_source();
if (state) {
if (state == TAG_RAISE) {
VALUE err, errat, mesg;
mesg = rb_obj_as_string(ruby_errinfo);
if (strcmp(file, "(eval)") == 0) {
if (ruby_sourceline > 1) {
errat = get_backtrace(ruby_errinfo);
err = rb_str_dup(RARRAY(errat)->ptr[0]);
rb_str_cat2(err, ": ");
rb_str_append(err, mesg);
}
else {
err = mesg;
}
rb_exc_raise(rb_funcall(ruby_errinfo, rb_intern("exception"), 1, err));
VALUE mesg, errat;
errat = get_backtrace(ruby_errinfo);
mesg = rb_obj_as_string(ruby_errinfo);
rb_str_update(mesg, 0, 0, RARRAY(errat)->ptr[0]);
RARRAY(errat)->ptr[0] = RARRAY(backtrace(-2))->ptr[0];
}
rb_exc_raise(ruby_errinfo);
}
@ -6757,6 +6772,9 @@ Init_load()
ruby_dln_librefs = rb_ary_new();
rb_global_variable(&ruby_dln_librefs);
/* not really a right place */
rb_define_method(rb_eNameError, "to_s", name_err_to_s, 0);
}
static void