yarv-diff:141
From: ko1 atdot.net
Date: 29 Nov 2005 16:17:32 -0000
Subject: [yarv-diff:141] r300 - trunk
Author: ko1
Date: 2005-11-30 01:17:31 +0900 (Wed, 30 Nov 2005)
New Revision: 300
Modified:
trunk/ChangeLog
trunk/common.mk
trunk/eval.c
trunk/eval_proc.c
trunk/insns.def
trunk/test.rb
trunk/vm.c
trunk/vm_macro.def
Log:
* common.mk : add vm_opts.h rule
* vm.c, insns.def : fix proc creation under class and block
environment
* eval.c, eval_proc.c, vm.c, vm_macro.def :
support define_method and invoke NODE_BMETHOD method
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-11-29 04:26:15 UTC (rev 299)
+++ trunk/ChangeLog 2005-11-29 16:17:31 UTC (rev 300)
@@ -4,6 +4,20 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2005-11-30(Wed) 01:13:57 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * common.mk : add vm_opts.h rule
+
+ * vm.c, insns.def : fix proc creation under class and block
+ environment
+
+
+2005-11-29(Tue) 16:39:07 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * eval.c, eval_proc.c, vm.c, vm_macro.def :
+ support define_method and invoke NODE_BMETHOD method
+
+
2005-11-29(Tue) 13:18:06 +0900 Koichi Sasada <ko1 atdot.net>
* compile.c : add iseq_add_mark_object, iseq_add_mark_object_compile_time
Modified: trunk/common.mk
===================================================================
--- trunk/common.mk 2005-11-29 04:26:15 UTC (rev 299)
+++ trunk/common.mk 2005-11-29 16:17:31 UTC (rev 300)
@@ -252,7 +252,7 @@
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h
error.$(OBJEXT): {$(VPATH)}error.c {$(VPATH)}ruby.h config.h \
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
- {$(VPATH)}env.h {$(VPATH)}st.h
+ {$(VPATH)}env.h {$(VPATH)}st.h vm_opts.h
euc_jp.$(OBJEXT): {$(VPATH)}euc_jp.c {$(VPATH)}regenc.h \
{$(VPATH)}oniguruma.h
@@ -373,11 +373,11 @@
compile.$(OBJEXT): {$(VPATH)}compile.c {$(VPATH)}yarvcore.h \
{$(VPATH)}compile.h {$(VPATH)}debug.h \
- insns.inc insns_info.inc optinsn.inc opt_sc.inc optunifs.inc
-disasm.$(OBJEXT): {$(VPATH)}disasm.c {$(VPATH)}yarvcore.h {$(VPATH)}debug.h
+ insns.inc insns_info.inc optinsn.inc opt_sc.inc optunifs.inc vm_opts.h
+disasm.$(OBJEXT): {$(VPATH)}disasm.c {$(VPATH)}yarvcore.h {$(VPATH)}debug.h vm_opts.h
vm.$(OBJEXT): {$(VPATH)}vm.c {$(VPATH)}vm.h {$(VPATH)}insnhelper.h \
{$(VPATH)}yarvcore.h {$(VPATH)}debug.h {$(VPATH)}vm_evalbody.h \
- insns.inc vm.inc vmtc.inc vm_macro.inc
+ insns.inc vm.inc vmtc.inc vm_macro.inc vm_opts.h
vm_dump.$(OBJEXT): {$(VPATH)}yarvcore.h {$(VPATH)}vm.h
yarvcore.$(OBJEXT): {$(VPATH)}yarvcore.c {$(VPATH)}yarvcore.h \
{$(VPATH)}yarv_version.h {$(VPATH)}debug.h rev.inc
@@ -416,6 +416,9 @@
rev.inc: $(srcdir)/ChangeLog
$(BASERUBY) $(srcdir)/rb/getrev.rb $(srcdir)/ChangeLog > rev.inc
+vm_opts.h: $(srcdir)/vm_opts.h.base
+ $(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
+
incs:
$(BASERUBY) $(srcdir)/rb/getrev.rb $(srcdir)/ChangeLog > rev.inc
$(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
Modified: trunk/eval.c
===================================================================
--- trunk/eval.c 2005-11-29 04:26:15 UTC (rev 299)
+++ trunk/eval.c 2005-11-29 16:17:31 UTC (rev 300)
@@ -27,7 +27,6 @@
VALUE rb_f_block_given_p(void);
static VALUE umethod_bind(VALUE, VALUE);
-static VALUE rb_mod_define_method(int, VALUE*, VALUE);
ID rb_frame_callee();
static VALUE rb_frame_self();
@@ -2739,53 +2738,6 @@
}
-/*
- * call-seq:
- * define_method(symbol, method) => new_method
- * define_method(symbol) { block } => proc
- *
- * Defines an instance method in the receiver. The _method_
- * parameter can be a +Proc+ or +Method+ object.
- * If a block is specified, it is used as the method body. This block
- * is evaluated using <code>instance_eval</code>, a point that is
- * tricky to demonstrate because <code>define_method</code> is private.
- * (This is why we resort to the +send+ hack in this example.)
- *
- * class A
- * def fred
- * puts "In Fred"
- * end
- * def create_method(name, &block)
- * self.class.send(:define_method, name, &block)
- * end
- * define_method(:wilma) { puts "Charge it!" }
- * end
- * class B < A
- * define_method(:barney, instance_method(:fred))
- * end
- * a = B.new
- * a.barney
- * a.wilma
- * a.create_method(:betty) { p self }
- * a.betty
- *
- * <em>produces:</em>
- *
- * In Fred
- * Charge it!
- * #<B:0x401b39e8>
- */
-
-static VALUE
-rb_mod_define_method(argc, argv, mod)
- int argc;
- VALUE *argv;
- VALUE mod;
-{
- UNSUPPORTED(rb_mod_define_method);
- return Qnil;
-}
-
void
Init_eval()
{
@@ -2856,7 +2808,6 @@
rb_define_private_method(rb_cModule, "remove_method", rb_mod_remove_method, -1);
rb_define_private_method(rb_cModule, "undef_method", rb_mod_undef_method, -1);
rb_define_private_method(rb_cModule, "alias_method", rb_mod_alias_method, 2);
- rb_define_private_method(rb_cModule, "define_method", rb_mod_define_method, -1);
rb_define_singleton_method(rb_cModule, "nesting", rb_mod_nesting, 0);
rb_define_singleton_method(rb_cModule, "constants", rb_mod_s_constants, 0);
Modified: trunk/eval_proc.c
===================================================================
--- trunk/eval_proc.c 2005-11-29 04:26:15 UTC (rev 299)
+++ trunk/eval_proc.c 2005-11-29 16:17:31 UTC (rev 300)
@@ -14,8 +14,9 @@
static VALUE rb_cUnboundMethod;
static VALUE rb_cMethod;
-static VALUE bmcall _((VALUE, VALUE));
-static int method_arity _((VALUE));
+static VALUE bmcall(VALUE, VALUE);
+static int method_arity(VALUE);
+static VALUE rb_obj_is_method(VALUE m);
/*
* MISSING: documentation
@@ -201,6 +202,12 @@
}
VALUE
+rb_block_lambda()
+{
+ return proc_alloc(rb_cProc, Qtrue);
+}
+
+VALUE
rb_f_lambda()
{
rb_warn("rb_f_lambda() is deprecated; use rb_block_proc() instead");
@@ -656,6 +663,98 @@
}
/*
+ * call-seq:
+ * define_method(symbol, method) => new_method
+ * define_method(symbol) { block } => proc
+ *
+ * Defines an instance method in the receiver. The _method_
+ * parameter can be a +Proc+ or +Method+ object.
+ * If a block is specified, it is used as the method body. This block
+ * is evaluated using <code>instance_eval</code>, a point that is
+ * tricky to demonstrate because <code>define_method</code> is private.
+ * (This is why we resort to the +send+ hack in this example.)
+ *
+ * class A
+ * def fred
+ * puts "In Fred"
+ * end
+ * def create_method(name, &block)
+ * self.class.send(:define_method, name, &block)
+ * end
+ * define_method(:wilma) { puts "Charge it!" }
+ * end
+ * class B < A
+ * define_method(:barney, instance_method(:fred))
+ * end
+ * a = B.new
+ * a.barney
+ * a.wilma
+ * a.create_method(:betty) { p self }
+ * a.betty
+ *
+ * <em>produces:</em>
+ *
+ * In Fred
+ * Charge it!
+ * #<B:0x401b39e8>
+ */
+
+static VALUE
+rb_mod_define_method(int argc, VALUE *argv, VALUE mod)
+{
+ ID id;
+ VALUE body;
+ NODE *node;
+ int noex = NOEX_PUBLIC;
+
+ if(argc == 1){
+ id = rb_to_id(argv[0]);
+ body = rb_block_lambda();
+ }
+ else if(argc == 2){
+ id = rb_to_id(argv[0]);
+ body = argv[1];
+ if (!rb_obj_is_method(body) && !yarv_obj_is_proc(body)) {
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc/Method)",
+ rb_obj_classname(body));
+ }
+ }
+ else{
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
+ }
+
+ if(RDATA(body)->dmark == (RUBY_DATA_FUNC)bm_mark){
+ struct METHOD *method = (struct METHOD *)DATA_PTR(body);
+ VALUE rklass = method->rklass;
+ if (rklass != mod) {
+ if (FL_TEST(rklass, FL_SINGLETON)) {
+ rb_raise(rb_eTypeError, "can't bind singleton method to a different class");
+ }
+ if (!RTEST(rb_class_inherited_p(mod, rklass))) {
+ rb_raise(rb_eTypeError, "bind argument must be a subclass of %s",
+ rb_class2name(rklass));
+ }
+ }
+ node = method->body;
+ }
+ else if(yarv_obj_is_proc(body)){
+ struct BLOCK *block;
+ // TODO: body = proc_clone(body); why?
+ node = NEW_BMETHOD(body);
+ }
+ else{
+ /* type error */
+ rb_raise(rb_eTypeError, "wrong argument type (expected Proc/Method)");
+ }
+
+ /* TODO: visibility */
+
+ rb_add_method(mod, id, node, noex);
+ return body;
+}
+
+
+/*
* MISSING: documentation
*/
@@ -1100,65 +1199,68 @@
void
Init_Proc()
{
- rb_eLocalJumpError = rb_define_class("LocalJumpError", rb_eStandardError);
- rb_define_method(rb_eLocalJumpError, "exit_value", localjump_xvalue, 0);
- rb_define_method(rb_eLocalJumpError, "reason", localjump_reason, 0);
+ rb_eLocalJumpError = rb_define_class("LocalJumpError", rb_eStandardError);
+ rb_define_method(rb_eLocalJumpError, "exit_value", localjump_xvalue, 0);
+ rb_define_method(rb_eLocalJumpError, "reason", localjump_reason, 0);
- exception_error = rb_exc_new2(rb_eFatal, "exception reentered");
- rb_global_variable(&exception_error);
+ exception_error = rb_exc_new2(rb_eFatal, "exception reentered");
+ rb_global_variable(&exception_error);
- rb_eSysStackError = rb_define_class("SystemStackError", rb_eException);
- sysstack_error = rb_exc_new2(rb_eSysStackError, "stack level too deep");
- OBJ_TAINT(sysstack_error);
- rb_global_variable(&sysstack_error);
+ rb_eSysStackError = rb_define_class("SystemStackError", rb_eException);
+ sysstack_error = rb_exc_new2(rb_eSysStackError, "stack level too deep");
+ OBJ_TAINT(sysstack_error);
+ rb_global_variable(&sysstack_error);
- rb_cProc = rb_define_class("Proc", rb_cObject);
- rb_undef_alloc_func(rb_cProc);
- rb_define_singleton_method(rb_cProc, "new", proc_s_new, -1);
+ rb_cProc = rb_define_class("Proc", rb_cObject);
+ rb_undef_alloc_func(rb_cProc);
+ rb_define_singleton_method(rb_cProc, "new", proc_s_new, -1);
- rb_define_method(rb_cProc, "clone", proc_clone, 0);
- rb_define_method(rb_cProc, "dup", proc_dup, 0);
- rb_define_method(rb_cProc, "call", rb_proc_call, -2);
- rb_define_method(rb_cProc, "arity", proc_arity, 0);
- rb_define_method(rb_cProc, "[]", rb_proc_call, -2);
- rb_define_method(rb_cProc, "==", proc_eq, 1);
- rb_define_method(rb_cProc, "eql?", proc_eq, 1);
- rb_define_method(rb_cProc, "hash", proc_hash, 0);
- rb_define_method(rb_cProc, "to_s", proc_to_s, 0);
- rb_define_method(rb_cProc, "to_proc", proc_to_self, 0);
- rb_define_method(rb_cProc, "binding", proc_binding, 0);
+ rb_define_method(rb_cProc, "clone", proc_clone, 0);
+ rb_define_method(rb_cProc, "dup", proc_dup, 0);
+ rb_define_method(rb_cProc, "call", rb_proc_call, -2);
+ rb_define_method(rb_cProc, "arity", proc_arity, 0);
+ rb_define_method(rb_cProc, "[]", rb_proc_call, -2);
+ rb_define_method(rb_cProc, "==", proc_eq, 1);
+ rb_define_method(rb_cProc, "eql?", proc_eq, 1);
+ rb_define_method(rb_cProc, "hash", proc_hash, 0);
+ rb_define_method(rb_cProc, "to_s", proc_to_s, 0);
+ rb_define_method(rb_cProc, "to_proc", proc_to_self, 0);
+ rb_define_method(rb_cProc, "binding", proc_binding, 0);
- rb_define_global_function("proc", rb_block_proc, 0);
- rb_define_global_function("lambda", proc_lambda, 0);
+ rb_define_global_function("proc", rb_block_proc, 0);
+ rb_define_global_function("lambda", proc_lambda, 0);
- rb_cMethod = rb_define_class("Method", rb_cObject);
- rb_undef_alloc_func(rb_cMethod);
- rb_undef_method(CLASS_OF(rb_cMethod), "new");
- rb_define_method(rb_cMethod, "==", method_eq, 1);
- rb_define_method(rb_cMethod, "eql?", method_eq, 1);
- rb_define_method(rb_cMethod, "hash", method_hash, 0);
- rb_define_method(rb_cMethod, "clone", method_clone, 0);
- rb_define_method(rb_cMethod, "call", rb_method_call, -1);
- rb_define_method(rb_cMethod, "[]", rb_method_call, -1);
- rb_define_method(rb_cMethod, "arity", method_arity_m, 0);
- rb_define_method(rb_cMethod, "inspect", method_inspect, 0);
- rb_define_method(rb_cMethod, "to_s", method_inspect, 0);
- rb_define_method(rb_cMethod, "to_proc", method_proc, 0);
- rb_define_method(rb_cMethod, "unbind", method_unbind, 0);
- rb_define_method(rb_mKernel, "method", rb_obj_method, 1);
+ rb_cMethod = rb_define_class("Method", rb_cObject);
+ rb_undef_alloc_func(rb_cMethod);
+ rb_undef_method(CLASS_OF(rb_cMethod), "new");
+ rb_define_method(rb_cMethod, "==", method_eq, 1);
+ rb_define_method(rb_cMethod, "eql?", method_eq, 1);
+ rb_define_method(rb_cMethod, "hash", method_hash, 0);
+ rb_define_method(rb_cMethod, "clone", method_clone, 0);
+ rb_define_method(rb_cMethod, "call", rb_method_call, -1);
+ rb_define_method(rb_cMethod, "[]", rb_method_call, -1);
+ rb_define_method(rb_cMethod, "arity", method_arity_m, 0);
+ rb_define_method(rb_cMethod, "inspect", method_inspect, 0);
+ rb_define_method(rb_cMethod, "to_s", method_inspect, 0);
+ rb_define_method(rb_cMethod, "to_proc", method_proc, 0);
+ rb_define_method(rb_cMethod, "unbind", method_unbind, 0);
+ rb_define_method(rb_mKernel, "method", rb_obj_method, 1);
- rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject);
- rb_undef_alloc_func(rb_cUnboundMethod);
- rb_undef_method(CLASS_OF(rb_cUnboundMethod), "new");
- rb_define_method(rb_cUnboundMethod, "==", method_eq, 1);
- rb_define_method(rb_cUnboundMethod, "eql?", method_eq, 1);
- rb_define_method(rb_cUnboundMethod, "hash", method_hash, 0);
- rb_define_method(rb_cUnboundMethod, "clone", method_clone, 0);
- rb_define_method(rb_cUnboundMethod, "arity", method_arity_m, 0);
- rb_define_method(rb_cUnboundMethod, "inspect", method_inspect, 0);
- rb_define_method(rb_cUnboundMethod, "to_s", method_inspect, 0);
- rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
- rb_define_method(rb_cModule, "instance_method", rb_mod_method, 1);
+ rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject);
+ rb_undef_alloc_func(rb_cUnboundMethod);
+ rb_undef_method(CLASS_OF(rb_cUnboundMethod), "new");
+ rb_define_method(rb_cUnboundMethod, "==", method_eq, 1);
+ rb_define_method(rb_cUnboundMethod, "eql?", method_eq, 1);
+ rb_define_method(rb_cUnboundMethod, "hash", method_hash, 0);
+ rb_define_method(rb_cUnboundMethod, "clone", method_clone, 0);
+ rb_define_method(rb_cUnboundMethod, "arity", method_arity_m, 0);
+ rb_define_method(rb_cUnboundMethod, "inspect", method_inspect, 0);
+ rb_define_method(rb_cUnboundMethod, "to_s", method_inspect, 0);
+ rb_define_method(rb_cUnboundMethod, "bind", umethod_bind, 1);
+
+ rb_define_method(rb_cModule, "instance_method", rb_mod_method, 1);
+ rb_define_private_method(rb_cModule, "define_method", rb_mod_define_method, -1);
+
}
/*
@@ -1206,3 +1308,5 @@
rb_define_method(rb_cBinding, "eval", bind_eval, -1);
rb_define_global_function("binding", rb_f_binding, 0);
}
+
+
Modified: trunk/insns.def
===================================================================
--- trunk/insns.def 2005-11-29 04:26:15 UTC (rev 299)
+++ trunk/insns.def 2005-11-29 16:17:31 UTC (rev 300)
@@ -1085,7 +1085,7 @@
/* enter scope */
GetISeqVal(klass_iseqval, klass_iseq);
th_set_env(th, klass_iseq,
- FRAME_MAGIC_CLASS, klass, (VALUE)GET_DFP(),
+ FRAME_MAGIC_CLASS, klass, (VALUE)GET_DFP() | 0x02,
klass_iseq->iseq_encoded, GET_SP(), 0,
klass_iseq->local_size, 0, 0);
RESTORE_REGS();
@@ -1116,7 +1116,7 @@
/* enter scope */
GetISeqVal(sclass_iseqval, klass_iseq);
th_set_env(th, klass_iseq,
- FRAME_MAGIC_CLASS, klass, (VALUE)GET_DFP(),
+ FRAME_MAGIC_CLASS, klass, (VALUE)GET_DFP() | 0x02,
klass_iseq->iseq_encoded, GET_SP(), 0,
klass_iseq->local_size, 0, 0);
RESTORE_REGS();
@@ -1163,7 +1163,7 @@
/* enter scope */
GetISeqVal(module_iseqval, module_iseq);
th_set_env(th, module_iseq,
- FRAME_MAGIC_CLASS, module, (VALUE)GET_DFP(),
+ FRAME_MAGIC_CLASS, module, (VALUE)GET_DFP() | 0x02,
module_iseq->iseq_encoded, GET_SP(), 0,
module_iseq->local_size, 0, 0);
RESTORE_REGS();
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-11-29 04:26:15 UTC (rev 299)
+++ trunk/test.rb 2005-11-29 16:17:31 UTC (rev 300)
@@ -1,3 +1,29 @@
+module QueryExtension
+
+ %w[ CONTENT_LENGTH SERVER_PORT ].each do |env|
+ sym = env.sub(/^HTTP_/n, '').downcase
+ p sym
+ define_method(sym.to_sym){|e|
+ (val = env_table[env]) && Integer(val)
+ }
+ end
+end
+
+__END__
+class Object
+ define_method(:m){|a|
+ p [a, self]
+ }
+end
+
+ary = [1,2,3]
+m(ary)
+p 1
+
+__send__ :m, 1
+
+__END__
+
require 'optparse'
require 'optparse/time'
require 'ostruct'
Modified: trunk/vm.c
===================================================================
--- trunk/vm.c 2005-11-29 04:26:15 UTC (rev 299)
+++ trunk/vm.c 2005-11-29 16:17:31 UTC (rev 300)
@@ -25,6 +25,10 @@
void vm_analysis_register(int reg, int isset);
void vm_analysis_insn(int insn);
+static inline VALUE
+thread_invoke_yield_cfunc(yarv_thread_t *th,
+ yarv_block_t *block, int argc, VALUE *argv);
+
VALUE th_eval_body(yarv_thread_t *th);
#if OPT_STACK_CACHING
@@ -313,7 +317,7 @@
VALUE procval;
yarv_control_frame_t *bcfp;
VALUE *bdfp; /* to gc mark */
-
+
if(block->proc){
return block->proc;
}
@@ -333,11 +337,10 @@
yarv_proc_t *proc;
if(GC_GUARDED_PTR_REF(cfp->lfp[0]) != 0 &&
- cfp->iseq->type != ISEQ_TYPE_CLASS){
+ !(cfp->lfp[0] & 0x02) /* not class scope */){
yarv_proc_t *p;
blockprocval =
th_make_proc_from_block(th, cfp, (yarv_block_t *)GC_GUARDED_PTR_REF(*cfp->lfp));
-
GetProcVal(blockprocval, p);
*cfp->lfp = GC_GUARDED_PTR(&p->block);
}
@@ -391,13 +394,10 @@
const int flag = 0;
th_set_finish_env(th);
-
reg_cfp = th->cfp;
-
for(i=0; i<argc; i++){
*reg_cfp->sp++ = argv[i];
}
-
macro_eval_invoke_func(body->nd_body, recv, klass, blockptr, argc);
val = th_eval_body(th);
break;
@@ -428,6 +428,22 @@
val = rb_attr_get(recv, body->nd_vid);
break;
}
+ case NODE_BMETHOD:{
+ yarv_control_frame_t *reg_cfp;
+ int i;
+ const int flag = 0;
+
+ th_set_finish_env(th);
+
+ reg_cfp = th->cfp;
+
+ for(i=0; i<argc; i++){
+ *reg_cfp->sp++ = argv[i];
+ }
+ macro_eval_invoke_bmethod(body->nd_cval, recv, klass, blockptr, argc);
+ val = th_eval_body(th);
+ break;
+ }
default:
rb_bug("unsupported: thread_call0");
}
@@ -645,8 +661,9 @@
}
-VALUE
-th_invoke_proc(yarv_thread_t *th, yarv_proc_t *proc, int argc, VALUE *argv)
+static VALUE
+th_invoke_proc_under(yarv_thread_t *th, yarv_proc_t *proc,
+ int argc, VALUE *argv, VALUE self)
{
if(BUILTIN_TYPE(proc->block.iseq) == T_NODE){
return thread_invoke_yield_cfunc(th, &proc->block, argc, argv);
@@ -654,16 +671,26 @@
else{
th_set_finish_env(th);
th_set_env(th, proc->block.iseq,
- FRAME_MAGIC_PROC, proc->block.self, (VALUE)proc->block.dfp,
+ FRAME_MAGIC_PROC, self, (VALUE)proc->block.dfp,
proc->block.iseq->iseq_encoded, th->cfp->sp, proc->block.lfp,
proc->block.iseq->local_size, argc, argv);
}
- //proc_dump_raw(proc);
-
return th_eval_body(th);
}
+VALUE
+th_invoke_proc(yarv_thread_t *th, yarv_proc_t *proc, int argc, VALUE *argv)
+{
+ if(BUILTIN_TYPE(proc->block.iseq) == T_NODE){
+ return thread_invoke_yield_cfunc(th, &proc->block, argc, argv);
+ }
+ else{
+ return th_invoke_proc_under(th, proc, argc, argv, proc->block.self);
+ }
+}
+
+
VALUE
thread_invoke_proc_call(VALUE self, VALUE procval, int argc, VALUE *argv)
{
Modified: trunk/vm_macro.def
===================================================================
--- trunk/vm_macro.def 2005-11-29 04:26:15 UTC (rev 299)
+++ trunk/vm_macro.def 2005-11-29 16:17:31 UTC (rev 300)
@@ -205,6 +205,27 @@
}
}
+MACRO macro_eval_invoke_bmethod(procval, recv, klass, blockptr, num)
+{
+ yarv_proc_t *proc;
+ GetProcVal(procval, proc);
+
+ if(BUILTIN_TYPE(proc->block.iseq) == T_NODE){
+ val = thread_invoke_yield_cfunc(th, &proc->block, num, STACK_ADDR_FROM_TOP(num));
+ }
+ else{
+ if(proc->block.iseq->argc != num){
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
+ num, proc->block.iseq->argc);
+ }
+ th_set_env(th, proc->block.iseq,
+ FRAME_MAGIC_PROC, recv, (VALUE)proc->block.dfp,
+ proc->block.iseq->iseq_encoded, th->cfp->sp, proc->block.lfp,
+ proc->block.iseq->local_size - num, 0, 0);
+ RESTORE_REGS();
+ }
+}
+
MACRO macro_eval_invoke_method(recv, klass, id, num, mn, noex, blockptr)
{
/* method missing */
@@ -249,6 +270,11 @@
POP();
break;
}
+ case NODE_BMETHOD:{
+ macro_eval_invoke_bmethod(mn->nd_cval, recv, klass, blockptr, num);
+ NEXT_INSN();
+ break;
+ }
case NODE_SCOPE:{
dpi(id);
SDR();
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml