[前][次][番号順一覧][スレッド一覧][生データ]

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

[前][次][番号順一覧][スレッド一覧][生データ]