なかだです。

At Thu, 3 Oct 2002 16:33:47 +0900,
Yukihiro Matsumoto wrote:
> |> むう、修正しておきます。
> |
> |rb_f_lambda()を使うようになってますが、これでできるんでしたっけ。
> |たしかPUSH_ITER(ITER_CUR)してなくてできないので、rb_proc_new()
> |が必要だったような気がするのですが。
> |
> |      *(q->result) = rb_funcall(rb_iterate(rb_f_lambda, 0, ivq_safelevel_handler, 
> |					   Data_Wrap_Struct(rb_cData,0,0,q)), 
> |				rb_intern("call"), 0);
> 
> あれえ、できなかったっけか。

ように思うんですが。そもそもこのivq_safelevel_handlerがどういう
ときに呼ばれるかよく分かってなくてテストしてないんですが、こう
いうサンプルではエラーになります。

$ cat lambda.c
#include <ruby.h>

static VALUE
callback(VALUE arg)
{
    rb_p(arg);
}

void
Init_lambda()
{
    VALUE l = rb_iterate((VALUE (*)_((VALUE)))rb_f_lambda, 0, callback, Qnil);
    rb_gvar_set("$lambda", l);
}

$ ruby-1.6 -v -rlambda -e0
ruby-1.6: tried to create Proc object without a block (ArgumentError)
ruby 1.6.8 (2002-10-02) [i686-linux]

うーん、拡張ライブラリで例外が起きたときのファイル名がおかしい…。


Index: eval.c =================================================================== RCS file: /cvs/ruby/src/ruby/eval.c,v retrieving revision 1.338 diff -u -2 -p -r1.338 eval.c --- eval.c 27 Sep 2002 09:42:24 -0000 1.338 +++ eval.c 3 Oct 2002 08:28:54 -0000 @@ -888,4 +888,6 @@ static VALUE trace_func = 0; static int tracing = 0; static void call_trace_func _((char*,NODE*,VALUE,ID,VALUE)); +#define ENABLE_TRACE() (tracing &= ~2) +#define DISABLE_TRACE() (tracing |= 2) #define SET_CURRENT_SOURCE() (ruby_sourcefile = ruby_current_node->nd_file, \ @@ -1867,5 +1869,5 @@ is_defined(self, node, buf) check_bound: { - int call = nd_type(node)== NODE_CALL; + int call = nd_type(node)==NODE_CALL; val = CLASS_OF(val); @@ -4500,6 +4502,8 @@ rb_call0(klass, recv, id, oid, argc, arg if (trace_func) { int state; + volatile int old_tracing = tracing; call_trace_func("c-call", ruby_current_node, recv, id, klass); + DISABLE_TRACE(); PUSH_TAG(PROT_FUNC); if ((state = EXEC_TAG()) == 0) { @@ -4507,4 +4511,5 @@ rb_call0(klass, recv, id, oid, argc, arg } POP_TAG(); + tracing = old_tracing; ruby_current_node = ruby_frame->node; call_trace_func("c-return", ruby_current_node, recv, id, klass); @@ -4969,4 +4974,5 @@ eval(self, src, scope, file, line) NODE *nodesave = ruby_current_node; volatile int iter = ruby_frame->iter; + volatile int old_tracing = tracing; int state; @@ -5031,4 +5037,5 @@ eval(self, src, scope, file, line) } if (!NIL_P(result)) ruby_errinfo = result; + ENABLE_TRACE(); result = eval_node(self, node); } @@ -5072,4 +5079,5 @@ eval(self, src, scope, file, line) ruby_current_node = nodesave; ruby_set_current_source(); + tracing = old_tracing; if (state) { if (state == TAG_RAISE) { @@ -5305,4 +5313,5 @@ rb_load(fname, wrap) volatile VALUE wrapper = 0; volatile VALUE self = ruby_top_self; + volatile int old_tracing = tracing; NODE *saved_cref = ruby_cref; TMP_PROTECT; @@ -5358,4 +5367,5 @@ rb_load(fname, wrap) ALLOW_INTS; if (ruby_nerrs == 0) { + ENABLE_TRACE(); eval_node(self, node); } @@ -5373,4 +5383,5 @@ rb_load(fname, wrap) POP_VARS(); ruby_wrapper = wrapper; + tracing = old_tracing; if (ruby_nerrs > 0) { ruby_nerrs = 0; @@ -5577,5 +5588,11 @@ rb_f_require(obj, fname) { int volatile old_vmode = scope_vmode; + NODE *const volatile old_node = ruby_current_node; + const volatile old_func = ruby_frame->last_func; + ruby_current_node = 0; + ruby_sourcefile = rb_source_filename(RSTRING(fname)->ptr); + ruby_sourceline = 0; + ruby_frame->last_func = 0; PUSH_TAG(PROT_NONE); if ((state = EXEC_TAG()) == 0) { @@ -5587,4 +5604,7 @@ rb_f_require(obj, fname) } POP_TAG(); + ruby_current_node = old_node; + ruby_set_current_source(); + ruby_frame->last_func = old_func; SCOPE_SET(old_vmode); }
-- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦