yarv-diff:75
From: ko1 atdot.net
Date: 15 Aug 2005 00:55:31 -0000
Subject: [yarv-diff:75] r231 - in trunk: . benchmark yarvext yarvtest
Author: ko1
Date: 2005-08-15 09:55:30 +0900 (Mon, 15 Aug 2005)
New Revision: 231
Added:
trunk/benchmark/run_rite.rb
trunk/test.rb
Modified:
trunk/ChangeLog
trunk/Makefile.in
trunk/benchmark/bmx_temp.rb
trunk/common.mk
trunk/depend
trunk/eval.c
trunk/inits.c
trunk/vm.c
trunk/vm.h
trunk/vm_dump.c
trunk/yarv.h
trunk/yarvcore.c
trunk/yarvcore.h
trunk/yarvext/test.rb
trunk/yarvtest/yarvtest.rb
Log:
* yarvcore.h : define SDR()
* vm_dump.c : stack_dump_raw() -> vm_stack_dump_raw()
* yarvtest/yarvtest.rb : add rite test scheme
* benchmark/run_rite.rb : added
* yarvcore.c, inits.c : add Init_vm()
* yarv.h : add some prototype declarations, GET_THREAD()
* eval.c : remove unused functions
* eval.c : support Kernel.eval, some schemes (same as evalc.patch)
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/ChangeLog 2005-08-15 00:55:30 UTC (rev 231)
@@ -4,6 +4,25 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2005-08-15(Mon) 09:42:01 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * yarvcore.h : define SDR()
+
+ * vm_dump.c : stack_dump_raw() -> vm_stack_dump_raw()
+
+ * yarvtest/yarvtest.rb : add rite test scheme
+
+ * benchmark/run_rite.rb : added
+
+ * yarvcore.c, inits.c : add Init_vm()
+
+ * yarv.h : add some prototype declarations, GET_THREAD()
+
+ * eval.c : remove unused functions
+
+ * eval.c : support Kernel.eval, some schemes (same as evalc.patch)
+
+
2005-08-15(Mon) 00:53:28 +0900 Koichi Sasada <ko1 atdot.net>
* yarv_version.h : move configurations to yarvcore.h
Modified: trunk/Makefile.in
===================================================================
--- trunk/Makefile.in 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/Makefile.in 2005-08-15 00:55:30 UTC (rev 231)
@@ -168,63 +168,59 @@
-BASE_RUBY = ruby
+BASERUBY = ruby
INSNS2VMOPT = $(CPPFLAGS) --srcdir=$(srcdir)
minsns.inc:
- $(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
+ $(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
opt_sc.inc:
- $(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
+ $(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
optinsn.inc:
- $(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) optinsn.inc
+ $(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) optinsn.inc
optunifs.inc:
- $(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) optunifs.inc
+ $(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) optunifs.inc
insns.inc:
- $(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
+ $(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
vmtc.inc:
- $(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) vmtc.inc
+ $(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) vmtc.inc
vm.inc: $(srcdir)/insns.def
- $(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) vm.inc
+ $(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) vm.inc
vm_macro.inc: $(srcdir)/vm_macro.def
- $(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) vm_macro.inc
+ $(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT) vm_macro.inc
rev.inc: $(srcdir)/ChangeLog
- $(BASE_RUBY) $(srcdir)/rb/getrev.rb $(srcdir)/ChangeLog > rev.inc
+ $(BASERUBY) $(srcdir)/rb/getrev.rb $(srcdir)/ChangeLog > rev.inc
incs:
- $(BASE_RUBY) $(srcdir)/rb/getrev.rb $(srcdir)/ChangeLog > rev.inc
- $(BASE_RUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
+ $(BASERUBY) $(srcdir)/rb/getrev.rb $(srcdir)/ChangeLog > rev.inc
+ $(BASERUBY) $(srcdir)/rb/insns2vm.rb $(INSNS2VMOPT)
docs:
- $(BASE_RUBY) -I$(srcdir) $(srcdir)/rb/makedocs.rb $(INSNS2VMOPT)
+ $(BASERUBY) -I$(srcdir) $(srcdir)/rb/makedocs.rb $(INSNS2VMOPT)
yarv-test-all: all
- $(BASE_RUBY) -I$(srcdir) $(srcdir)/test/runner.rb $(OPT)
+ $(BASERUBY) -I$(srcdir) $(srcdir)/yarvtest/runner.rb $(OPT) yarv=$(MINIRUBY) ruby=$(BASERUBY)
yarv-test-each: all
- $(BASE_RUBY) -I$(srcdir) $(srcdir)/test/test_$(ITEM).rb $(OPT)
+ $(BASERUBY) -I$(srcdir) $(srcdir)/yarvtest/test_$(ITEM).rb $(OPT) yarv=$(MINIRUBY) ruby=$(BASERUBY)
run: all
- @echo "Ruby --"
- @$(BASE_RUBY) $(srcdir)/test.rb $(RUNOPT)
- @echo "YARV --"
- @$(MINIRUBY) $(srcdir)/test.rb $(RUNOPT)
+ $(BASERUBY) $(srcdir)/test.rb $(RUNOPT) $(MINIRUBY) $(BASERUBY)
benchmark: all
- $(BASE_RUBY) -I$(srcdir) $(srcdir)/benchmark/run.rb $(OPT) $(ITEMS)
+ $(BASERUBY) -I$(srcdir) $(srcdir)/benchmark/run_rite.rb $(OPT) $(ITEMS) --yarv-program=$(MINIRUBY) --ruby-program=$(BASERUBY)
ITEM=bmx_temp
tbench: all
- $(RUBY) -I$(srcdir) $(srcdir)/benchmark/run.rb $(ITEM) $(OPT)
-
+ $(RUBY) -I$(srcdir) $(srcdir)/benchmark/run_rite.rb $(ITEM) $(OPT) --yarv-program=$(MINIRUBY) --ruby-program=$(BASERUBY)
aotc:
$(RUBY) -I$(srcdir) -I. $(srcdir)/rb/aotcompile.rb $(INSNS2VMOPT)
@@ -232,4 +228,4 @@
echo run > run.gdb
gdb: all run.gdb
- gdb -x run.gdb --quiet --args $(RUBY) -I$(srcdir) $(srcdir)/test.rb
+ gdb -x run.gdb --quiet --args $(MINIRUBY) -I$(srcdir) $(srcdir)/test.rb
Modified: trunk/benchmark/bmx_temp.rb
===================================================================
--- trunk/benchmark/bmx_temp.rb 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/benchmark/bmx_temp.rb 2005-08-15 00:55:30 UTC (rev 231)
@@ -1,19 +1,5 @@
i = 0
-ary = (1..100).to_a
-
-class Array
- def map
- i = 0
- ret = []
- while i<self.length
- ret << yield(self[i])
- i+=1
- end
- ret
- end
-end
-
-while i<30000
+while i < 1000000
i+=1
- ary.map{|x| x * 1}
end
+
Added: trunk/benchmark/run_rite.rb
===================================================================
--- trunk/benchmark/run_rite.rb 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/benchmark/run_rite.rb 2005-08-15 00:55:30 UTC (rev 231)
@@ -0,0 +1,112 @@
+#
+# YARV benchmark driver
+#
+
+require 'benchmark'
+require 'rbconfig'
+
+$yarvonly = false
+$rubyonly = false
+
+$results = []
+
+def bm file
+ prog = File.read(file).map{|e| e.rstrip}.join("\n")
+ return if prog.empty?
+
+ /[a-z]+_(.+)\.rb/ =~ file
+ bm_name = $1
+ puts '-----------------------------------------------------------' unless $yarvonly || $rubyonly
+ puts "#{bm_name}: "
+
+
+puts <<EOS unless $yarvonly || $rubyonly
+#{prog}
+--
+EOS
+ #iseq = YARVUtil.parse(File.read(file))
+ #vm = YARVCore::VM.new
+ begin
+ result = [bm_name]
+ result << ruby_exec(file) unless $yarvonly
+ result << yarv_exec(file) unless $rubyonly
+ $results << result
+
+ # puts YARVUtil.parse(File.read(file), file, 1).disasm
+
+ # x.report("ruby"){ load(file, false) }
+ # x.report("yarv"){ vm.eval iseq }
+ rescue Exception => e
+ puts
+ puts "** benchmark failure: #{e}"
+ puts e.backtrace
+ end
+end
+
+def benchmark file, bin
+ m = Benchmark.measure{
+ `#{bin} #{file}`
+ }
+ sec = '%.3f' % m.real
+ puts " #{sec}"
+ sec
+end
+
+def ruby_exec file
+ print 'ruby'
+ benchmark file, $ruby_program
+end
+
+def yarv_exec file
+ print 'yarv'
+ benchmark file, $yarv_program
+end
+
+if $0 == __FILE__
+ ARGV.each{|arg|
+ case arg
+ when /\A--yarv-program=(.+)/
+ $yarv_program = $1
+ when /\A--ruby-program=(.+)/
+ $ruby_program = $1
+ when /\A(--yarv)|(-y)/
+ $yarvonly = true
+ when /\A(--ruby)|(-r)/
+ $rubyonly = true
+ end
+ }
+ ARGV.delete_if{|arg|
+ /\A-/ =~ arg
+ }
+
+ puts "Ruby:"
+ system("#{$ruby_program} -v")
+ puts
+ puts "YARV:"
+ system("#{$yarv_program} -v")
+
+ if ARGV.empty?
+ Dir.glob(File.dirname(__FILE__) + '/bm_*.rb').sort.each{|file|
+ bm file
+ }
+ else
+ ARGV.each{|file|
+ Dir.glob(File.join(File.dirname(__FILE__), file + '*')){|ef|
+ # file = "#{File.dirname(__FILE__)}/#{file}.rb"
+ bm ef
+ }
+ }
+ end
+
+ puts
+ puts "-- benchmark summary ---------------------------"
+ $results.each{|res|
+ print res.shift, "\t"
+ (res||[]).each{|result|
+ /([\d\.]+)/ =~ result
+ print $1 + "\t" if $1
+ }
+ puts
+ }
+end
+
Property changes on: trunk/benchmark/run_rite.rb
___________________________________________________________________
Name: svn:executable
+ *
Modified: trunk/common.mk
===================================================================
--- trunk/common.mk 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/common.mk 2005-08-15 00:55:30 UTC (rev 231)
@@ -251,7 +251,7 @@
eval.$(OBJEXT): {$(VPATH)}eval.c {$(VPATH)}ruby.h config.h \
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
{$(VPATH)}node.h {$(VPATH)}env.h {$(VPATH)}util.h \
- {$(VPATH)}rubysig.h {$(VPATH)}st.h {$(VPATH)}dln.h
+ {$(VPATH)}rubysig.h {$(VPATH)}st.h {$(VPATH)}dln.h {$(VPATH)}yarv.h
file.$(OBJEXT): {$(VPATH)}file.c {$(VPATH)}ruby.h config.h \
{$(VPATH)}defines.h {$(VPATH)}intern.h {$(VPATH)}missing.h \
{$(VPATH)}rubyio.h {$(VPATH)}rubysig.h {$(VPATH)}util.h \
Modified: trunk/depend
===================================================================
--- trunk/depend 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/depend 2005-08-15 00:55:30 UTC (rev 231)
@@ -57,11 +57,11 @@
$(RUBY) -I$(srcdir)/yarvext $(srcdir)/yarvext/test.rb $(RUNOPT)
benchmark: all
- $(RUBY) -I$(srcdir) $(srcdir)/benchmark/run.rb $(OPT) $(ITEMS)
+ $(RUBY) -I$(srcdir)/yarvext $(srcdir)/benchmark/run.rb $(OPT) $(ITEMS)
ITEM=bmx_temp
tbench: all
- $(RUBY) -I$(srcdir) $(srcdir)/benchmark/run.rb $(ITEM) $(OPT)
+ $(RUBY) -I$(srcdir)/yarvext $(srcdir)/benchmark/run.rb $(ITEM) $(OPT)
test-compiler: all
Modified: trunk/eval.c
===================================================================
--- trunk/eval.c 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/eval.c 2005-08-15 00:55:30 UTC (rev 231)
@@ -17,6 +17,7 @@
#include "env.h"
#include "util.h"
#include "rubysig.h"
+#include "yarv.h"
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
@@ -202,7 +203,6 @@
static VALUE rb_f_binding _((VALUE));
static void rb_f_END _((void));
static VALUE rb_f_block_given_p _((void));
-static VALUE block_pass _((VALUE,NODE*));
static VALUE rb_cMethod;
static VALUE rb_cUnboundMethod;
static VALUE umethod_bind _((VALUE, VALUE));
@@ -924,18 +924,7 @@
rb_svar(cnt)
int cnt;
{
- struct RVarmap *vars = ruby_dyna_vars;
- ID id;
-
- if (!ruby_scope->local_tbl) return NULL;
- if (cnt >= ruby_scope->local_tbl[0]) return NULL;
- id = ruby_scope->local_tbl[cnt+1];
- while (vars) {
- if (vars->id == id) return &vars->val;
- vars = vars->next;
- }
- if (ruby_scope->local_vars == 0) return NULL;
- return &ruby_scope->local_vars[cnt];
+ return yarv_svar(cnt);
}
struct iter {
@@ -1089,7 +1078,6 @@
} while (0); \
POP_TAG()
-static VALUE rb_eval _((VALUE,NODE*));
static VALUE eval _((VALUE,VALUE,VALUE,char*,int));
static NODE *compile _((VALUE, char*, int));
@@ -1102,12 +1090,7 @@
#define YIELD_FUNC_SVALUE 2
static VALUE rb_call _((VALUE,VALUE,ID,int,const VALUE*,int));
-static VALUE module_setup _((VALUE,NODE*));
-static VALUE massign _((VALUE,NODE*,VALUE,int));
-static void assign _((VALUE,NODE*,VALUE,int));
-static int formal_assign _((VALUE, NODE*, int, VALUE*, VALUE*));
-
typedef struct event_hook {
rb_event_hook_func_t func;
rb_event_t events;
@@ -1399,20 +1382,6 @@
ruby_running = 1;
}
-static VALUE
-eval_node(self, node)
- VALUE self;
- NODE *node;
-{
- if (!node) return Qnil;
- if (nd_type(node) == NODE_PRELUDE) {
- rb_eval(self, node->nd_head);
- node = node->nd_body;
- }
- if (!node) return Qnil;
- return rb_eval(self, node);
-}
-
int ruby_in_eval;
static void rb_thread_cleanup _((void));
@@ -1587,10 +1556,10 @@
ruby_exec_internal()
{
int state;
+ VALUE val;
PUSH_TAG(0);
if((state = EXEC_TAG()) == 0) {
- // VM start
- yarvcore_eval_parsed(ruby_eval_tree, ruby_sourcefile);
+ val = yarvcore_eval_parsed((VALUE)ruby_eval_tree, rb_str_new2(ruby_sourcefile));
}
POP_TAG();
return state;
@@ -2213,40 +2182,6 @@
# define TMP_ALLOC(n) ALLOCA_N(VALUE,n)
#endif
-#define SETUP_ARGS0(anode,alen) do {\
- NODE *n = anode;\
- if (!n) {\
- argc = 0;\
- argv = 0;\
- }\
- else if (nd_type(n) == NODE_ARRAY) {\
- argc=alen;\
- if (argc > 0) {\
- int i;\
- n = anode;\
- argv = TMP_ALLOC(argc);\
- for (i=0;i<argc;i++) {\
- argv[i] = rb_eval(self,n->nd_head);\
- n=n->nd_next;\
- }\
- }\
- else {\
- argc = 0;\
- argv = 0;\
- }\
- }\
- else {\
- VALUE args = rb_eval(self,n);\
- if (TYPE(args) != T_ARRAY)\
- args = rb_ary_to_ary(args);\
- argc = RARRAY(args)->len;\
- argv = ALLOCA_N(VALUE, argc);\
- MEMCPY(argv, RARRAY(args)->ptr, VALUE, argc);\
- }\
-} while (0)
-
-#define SETUP_ARGS(anode) SETUP_ARGS0(anode, anode->nd_alen)
-
#define BEGIN_CALLARGS do {\
struct BLOCK *tmp_block = ruby_block;\
int tmp_iter = ruby_iter->iter;\
@@ -2263,219 +2198,6 @@
#define MATCH_DATA *rb_svar(node->nd_cnt)
-static const char* is_defined _((VALUE, NODE*, char*, int));
-
-static char*
-arg_defined(self, node, buf, type)
- VALUE self;
- NODE *node;
- char *buf;
- char *type;
-{
- int argc;
- int i;
-
- if (!node) return type; /* no args */
- if (nd_type(node) == NODE_ARRAY) {
- argc=node->nd_alen;
- if (argc > 0) {
- for (i=0;i<argc;i++) {
- if (!is_defined(self, node->nd_head, buf, 0))
- return 0;
- node = node->nd_next;
- }
- }
- }
- else if (!is_defined(self, node, buf, 0)) {
- return 0;
- }
- return type;
-}
-
-static const char*
-is_defined(self, node, buf, noeval)
- VALUE self;
- NODE *node; /* OK */
- char *buf;
- int noeval;
-{
- VALUE val; /* OK */
- int state;
- static const char *ex = "expression";
-
- if (!node) return ex;
- switch (nd_type(node)) {
- case NODE_SUPER:
- case NODE_ZSUPER:
- if (ruby_frame->this_func == 0) return 0;
- else if (ruby_frame->this_class == 0) return 0;
- val = ruby_frame->this_class;
- if (rb_method_boundp(RCLASS(val)->super, ruby_frame->this_func, 0)) {
- if (nd_type(node) == NODE_SUPER) {
- return arg_defined(self, node->nd_args, buf, "super");
- }
- return "super";
- }
- break;
-
- case NODE_VCALL:
- case NODE_FCALL:
- val = self;
- goto check_bound;
-
- case NODE_ATTRASGN:
- val = self;
- if (node->nd_recv == (NODE *)1) goto check_bound;
- case NODE_CALL:
- if (!is_defined(self, node->nd_recv, buf, Qtrue)) return 0;
- if (noeval) return ex;
- val = rb_eval(self, node->nd_recv);
- check_bound:
- {
- int call = nd_type(node)==NODE_CALL;
-
- val = CLASS_OF(val);
- if (call) {
- int noex;
- ID id = node->nd_mid;
-
- if (!rb_get_method_body(&val, &id, &noex))
- break;
- if ((noex & NOEX_PRIVATE))
- break;
- if ((noex & NOEX_PROTECTED) &&
- !rb_obj_is_kind_of(self, rb_class_real(val)))
- break;
- }
- else if (!rb_method_boundp(val, node->nd_mid, call))
- break;
- return arg_defined(self, node->nd_args, buf,
- nd_type(node) == NODE_ATTRASGN ?
- "assignment" : "method");
- }
- break;
-
- case NODE_MATCH2:
- case NODE_MATCH3:
- return "method";
-
- case NODE_YIELD:
- if (rb_block_given_p()) {
- return "yield";
- }
- break;
-
- case NODE_SELF:
- return "self";
-
- case NODE_NIL:
- return "nil";
-
- case NODE_TRUE:
- return "true";
-
- case NODE_FALSE:
- return "false";
-
- case NODE_ATTRSET:
- case NODE_OP_ASGN1:
- case NODE_OP_ASGN2:
- case NODE_MASGN:
- case NODE_LASGN:
- case NODE_DASGN:
- case NODE_DASGN_CURR:
- case NODE_GASGN:
- case NODE_IASGN:
- case NODE_CDECL:
- case NODE_CVDECL:
- case NODE_CVASGN:
- return "assignment";
-
- case NODE_LVAR:
- return "local-variable";
- case NODE_DVAR:
- return "local-variable(in-block)";
-
- case NODE_GVAR:
- if (rb_gvar_defined(node->nd_entry)) {
- return "global-variable";
- }
- break;
-
- case NODE_IVAR:
- if (rb_ivar_defined(self, node->nd_vid)) {
- return "instance-variable";
- }
- break;
-
- case NODE_CONST:
- if (ev_const_defined(ruby_cref, node->nd_vid, self)) {
- return "constant";
- }
- break;
-
- case NODE_CVAR:
- if (rb_cvar_defined(cvar_cbase(), node->nd_vid)) {
- return "class variable";
- }
- break;
-
- case NODE_COLON2:
- if (!is_defined(self, node->nd_recv, buf, Qtrue)) return 0;
- if (noeval) return ex;
- val = rb_eval(self, node->nd_recv);
- switch (TYPE(val)) {
- case T_CLASS:
- case T_MODULE:
- if (rb_const_defined_from(val, node->nd_mid))
- return "constant";
- break;
- default:
- if (rb_method_boundp(CLASS_OF(val), node->nd_mid, 1)) {
- return "method";
- }
- }
- break;
-
- case NODE_COLON3:
- if (rb_const_defined_from(rb_cObject, node->nd_mid)) {
- return "constant";
- }
- break;
-
- case NODE_NTH_REF:
- if (RTEST(rb_reg_nth_defined(node->nd_nth, MATCH_DATA))) {
- if (!buf) return ex;
- sprintf(buf, "$%d", (int)node->nd_nth);
- return buf;
- }
- break;
-
- case NODE_BACK_REF:
- if (RTEST(rb_reg_nth_defined(0, MATCH_DATA))) {
- if (!buf) return ex;
- sprintf(buf, "$%c", (char)node->nd_nth);
- return buf;
- }
- break;
-
- default:
- PUSH_TAG(PROT_NONE);
- if ((state = EXEC_TAG()) == 0) {
- rb_eval(self, node);
- }
- POP_TAG();
- if (!state) {
- return ex;
- }
- ruby_errinfo = Qnil;
- break;
- }
- return 0;
-}
-
-static int handle_rescue _((VALUE,NODE*));
-
static void blk_free();
static VALUE
@@ -2775,37 +2497,6 @@
return rb_values_from_ary(val);
}
-static VALUE
-class_prefix(self, cpath)
- VALUE self;
- NODE *cpath;
-{
- if (!cpath) {
- rb_bug("class path missing");
- }
- if (cpath->nd_head) {
- VALUE c = rb_eval(self, cpath->nd_head);
- switch (TYPE(c)) {
- case T_CLASS:
- case T_MODULE:
- break;
- default:
- rb_raise(rb_eTypeError, "%s is not a class/module",
- RSTRING(rb_obj_as_string(c))->ptr);
- }
- return c;
- }
- else if (nd_type(cpath) == NODE_COLON2) {
- return ruby_cbase;
- }
- else if (ruby_wrapper) {
- return ruby_wrapper;
- }
- else {
- return rb_cObject;
- }
-}
-
#define return_value(v) do {\
if ((prot_tag->retval = (v)) == Qundef) {\
prot_tag->retval = Qnil;\
@@ -2832,1316 +2523,6 @@
}
}
-static VALUE
-rb_eval(self, n)
- VALUE self;
- NODE *n;
-{
- NODE * volatile contnode = 0;
- NODE * volatile node = n;
- int state;
- volatile VALUE result = Qnil;
-
-#define RETURN(v) do { \
- result = (v); \
- goto finish; \
-} while (0)
-
- again:
- if (!node) RETURN(Qnil);
-
- ruby_current_node = node;
- if (node->flags & NODE_NEWLINE) {
- EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self,
- ruby_frame->this_func,
- ruby_frame->this_class);
- }
- switch (nd_type(node)) {
- case NODE_BLOCK:
- if (contnode) {
- result = rb_eval(self, node);
- break;
- }
- contnode = node->nd_next;
- node = node->nd_head;
- goto again;
-
- case NODE_POSTEXE:
- rb_f_END();
- nd_set_type(node, NODE_NIL); /* exec just once */
- result = Qnil;
- break;
-
- /* begin .. end without clauses */
- case NODE_BEGIN:
- node = node->nd_body;
- goto again;
-
- /* nodes for speed-up(default match) */
- case NODE_MATCH:
- result = rb_reg_match2(node->nd_lit);
- break;
-
- /* nodes for speed-up(literal match) */
- case NODE_MATCH2:
- {
- VALUE l = rb_eval(self,node->nd_recv);
- VALUE r = rb_eval(self,node->nd_value);
- result = rb_reg_match(l, r);
- }
- break;
-
- /* nodes for speed-up(literal match) */
- case NODE_MATCH3:
- {
- VALUE r = rb_eval(self,node->nd_recv);
- VALUE l = rb_eval(self,node->nd_value);
- if (TYPE(l) == T_STRING) {
- result = rb_reg_match(r, l);
- }
- else {
- result = rb_funcall(l, match, 1, r);
- }
- }
- break;
-
- /* node for speed-up(top-level loop for -n/-p) */
- case NODE_OPT_N:
- PUSH_TAG(PROT_LOOP);
- switch (state = EXEC_TAG()) {
- case 0:
- opt_n_next:
- while (!NIL_P(rb_gets())) {
- opt_n_redo:
- rb_eval(self, node->nd_body);
- }
- break;
-
- case TAG_REDO:
- state = 0;
- goto opt_n_redo;
- case TAG_NEXT:
- state = 0;
- goto opt_n_next;
- case TAG_BREAK:
- state = 0;
- default:
- break;
- }
- POP_TAG();
- if (state) JUMP_TAG(state);
- RETURN(Qnil);
-
- case NODE_SELF:
- RETURN(self);
-
- case NODE_NIL:
- RETURN(Qnil);
-
- case NODE_TRUE:
- RETURN(Qtrue);
-
- case NODE_FALSE:
- RETURN(Qfalse);
-
- case NODE_ERRINFO:
- RETURN(ruby_errinfo);
-
- case NODE_IF:
- EXEC_EVENT_HOOK(RUBY_EVENT_LINE, node, self,
- ruby_frame->this_func,
- ruby_frame->this_class);
- if (RTEST(rb_eval(self, node->nd_cond))) {
- node = node->nd_body;
- }
- else {
- node = node->nd_else;
- }
- goto again;
-
- case NODE_WHEN:
- while (node) {
- NODE *tag;
-
- if (nd_type(node) != NODE_WHEN) goto again;
- tag = node->nd_head;
- while (tag) {
- EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self,
- ruby_frame->this_func,
- ruby_frame->this_class);
- if (tag->nd_head && nd_type(tag->nd_head) == NODE_WHEN) {
- VALUE v = rb_eval(self, tag->nd_head->nd_head);
- long i;
-
- if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v);
- for (i=0; i<RARRAY(v)->len; i++) {
- if (RTEST(RARRAY(v)->ptr[i])) {
- node = node->nd_body;
- goto again;
- }
- }
- tag = tag->nd_next;
- continue;
- }
- if (RTEST(rb_eval(self, tag->nd_head))) {
- node = node->nd_body;
- goto again;
- }
- tag = tag->nd_next;
- }
- node = node->nd_next;
- }
- RETURN(Qnil);
-
- case NODE_CASE:
- {
- VALUE val;
-
- val = rb_eval(self, node->nd_head);
- node = node->nd_body;
- while (node) {
- NODE *tag;
-
- if (nd_type(node) != NODE_WHEN) {
- goto again;
- }
- tag = node->nd_head;
- while (tag) {
- EXEC_EVENT_HOOK(RUBY_EVENT_LINE, tag, self,
- ruby_frame->this_func,
- ruby_frame->this_class);
- if (tag->nd_head && nd_type(tag->nd_head) == NODE_WHEN) {
- VALUE v = rb_eval(self, tag->nd_head->nd_head);
- long i;
-
- if (TYPE(v) != T_ARRAY) v = rb_ary_to_ary(v);
- for (i=0; i<RARRAY(v)->len; i++) {
- if (RTEST(rb_funcall2(RARRAY(v)->ptr[i], eqq, 1, &val))){
- node = node->nd_body;
- goto again;
- }
- }
- tag = tag->nd_next;
- continue;
- }
- if (RTEST(rb_funcall2(rb_eval(self, tag->nd_head), eqq, 1, &val))) {
- node = node->nd_body;
- goto again;
- }
- tag = tag->nd_next;
- }
- node = node->nd_next;
- }
- }
- RETURN(Qnil);
-
- case NODE_WHILE:
- PUSH_TAG(PROT_LOOP);
- result = Qnil;
- switch (state = EXEC_TAG()) {
- case 0:
- if (node->nd_state && !RTEST(rb_eval(self, node->nd_cond)))
- goto while_out;
- do {
- while_redo:
- rb_eval(self, node->nd_body);
- while_next:
- ;
- } while (RTEST(rb_eval(self, node->nd_cond)));
- break;
-
- case TAG_REDO:
- state = 0;
- goto while_redo;
- case TAG_NEXT:
- state = 0;
- goto while_next;
- case TAG_BREAK:
- if (TAG_DST()) {
- state = 0;
- result = prot_tag->retval;
- }
- /* fall through */
- default:
- break;
- }
- while_out:
- POP_TAG();
- if (state) JUMP_TAG(state);
- RETURN(result);
-
- case NODE_UNTIL:
- PUSH_TAG(PROT_LOOP);
- result = Qnil;
- switch (state = EXEC_TAG()) {
- case 0:
- if (node->nd_state && RTEST(rb_eval(self, node->nd_cond)))
- goto until_out;
- do {
- until_redo:
- rb_eval(self, node->nd_body);
- until_next:
- ;
- } while (!RTEST(rb_eval(self, node->nd_cond)));
- break;
-
- case TAG_REDO:
- state = 0;
- goto until_redo;
- case TAG_NEXT:
- state = 0;
- goto until_next;
- case TAG_BREAK:
- if (TAG_DST()) {
- state = 0;
- result = prot_tag->retval;
- }
- /* fall through */
- default:
- break;
- }
- until_out:
- POP_TAG();
- if (state) JUMP_TAG(state);
- RETURN(result);
-
- case NODE_BLOCK_PASS:
- result = block_pass(self, node);
- break;
-
- case NODE_LAMBDA:
- PUSH_TAG(PROT_LOOP);
- PUSH_BLOCK(node->nd_var, node->nd_body);
-
- state = EXEC_TAG();
- PUSH_ITER(ITER_PRE);
- ruby_iter->iter = ruby_frame->iter = ITER_CUR;
- result = proc_lambda();
- POP_ITER();
- POP_BLOCK();
- POP_TAG();
- break;
-
- case NODE_ITER:
- case NODE_FOR:
- {
- PUSH_TAG(PROT_LOOP);
- PUSH_BLOCK(node->nd_var, node->nd_body);
-
- state = EXEC_TAG();
- if (state == 0) {
- iter_retry:
- PUSH_ITER(ITER_PRE);
- if (nd_type(node) == NODE_ITER) {
- result = rb_eval(self, node->nd_iter);
- }
- else if (nd_type(node) == NODE_LAMBDA) {
- ruby_iter->iter = ruby_frame->iter = ITER_CUR;
- result = rb_block_proc();
- }
- else {
- VALUE recv;
-
- _block.flags &= ~BLOCK_D_SCOPE;
- BEGIN_CALLARGS;
- recv = rb_eval(self, node->nd_iter);
- END_CALLARGS;
- ruby_current_node = node;
- SET_CURRENT_SOURCE();
- result = rb_call(CLASS_OF(recv),recv,each,0,0,0);
- }
- POP_ITER();
- }
- else if (state == TAG_BREAK && TAG_DST()) {
- result = prot_tag->retval;
- state = 0;
- }
- else if (state == TAG_RETRY && ruby_block == &_block) {
- state = 0;
- goto iter_retry;
- }
- POP_BLOCK();
- POP_TAG();
- switch (state) {
- case 0:
- break;
- default:
- JUMP_TAG(state);
- }
- }
- break;
-
- case NODE_BREAK:
- break_jump(rb_eval(self, node->nd_stts));
- break;
-
- case NODE_NEXT:
- CHECK_INTS;
- return_value(rb_eval(self, node->nd_stts));
- JUMP_TAG(TAG_NEXT);
- break;
-
- case NODE_REDO:
- CHECK_INTS;
- JUMP_TAG(TAG_REDO);
- break;
-
- case NODE_RETRY:
- CHECK_INTS;
- JUMP_TAG(TAG_RETRY);
- break;
-
- case NODE_SPLAT:
- result = splat_value(rb_eval(self, node->nd_head));
- break;
-
- case NODE_TO_ARY:
- result = rb_ary_to_ary(rb_eval(self, node->nd_head));
- break;
-
- case NODE_SVALUE:
- result = avalue_splat(rb_eval(self, node->nd_head));
- if (result == Qundef) result = Qnil;
- break;
-
- case NODE_YIELD:
- if (node->nd_head) {
- result = rb_eval(self, node->nd_head);
- ruby_current_node = node;
- }
- else {
- result = Qundef; /* no arg */
- }
- SET_CURRENT_SOURCE();
- result = rb_yield_0(result, 0, 0, 0, node->nd_state);
- break;
-
- case NODE_RESCUE:
- {
- volatile VALUE e_info = ruby_errinfo;
- volatile int rescuing = 0;
-
- PUSH_TAG(PROT_NONE);
- if ((state = EXEC_TAG()) == 0) {
- retry_entry:
- result = rb_eval(self, node->nd_head);
- }
- else if (rescuing) {
- if (rescuing < 0) {
- /* in rescue argument, just reraise */
- }
- else if (state == TAG_RETRY) {
- rescuing = state = 0;
- ruby_errinfo = e_info;
- goto retry_entry;
- }
- else if (state != TAG_RAISE) {
- result = prot_tag->retval;
- }
- }
- else if (state == TAG_RAISE) {
- NODE *resq = node->nd_resq;
-
- rescuing = -1;
- while (resq) {
- ruby_current_node = resq;
- if (handle_rescue(self, resq)) {
- state = 0;
- rescuing = 1;
- result = rb_eval(self, resq->nd_body);
- break;
- }
- resq = resq->nd_head; /* next rescue */
- }
- }
- else {
- result = prot_tag->retval;
- }
- POP_TAG();
- if (state != TAG_RAISE) ruby_errinfo = e_info;
- if (state) {
- if (state == TAG_NEXT) prot_tag->retval = result;
- JUMP_TAG(state);
- }
- /* no exception raised */
- if (!rescuing && (node = node->nd_else)) { /* else clause given */
- goto again;
- }
- }
- break;
-
- case NODE_ENSURE:
- PUSH_TAG(PROT_NONE);
- if ((state = EXEC_TAG()) == 0) {
- result = rb_eval(self, node->nd_head);
- }
- POP_TAG();
- if (node->nd_ensr) {
- VALUE retval = prot_tag->retval; /* save retval */
- VALUE errinfo = ruby_errinfo;
-
- rb_eval(self, node->nd_ensr);
- return_value(retval);
- ruby_errinfo = errinfo;
- }
- if (state) JUMP_TAG(state);
- break;
-
- case NODE_AND:
- result = rb_eval(self, node->nd_1st);
- if (!RTEST(result)) break;
- node = node->nd_2nd;
- goto again;
-
- case NODE_OR:
- result = rb_eval(self, node->nd_1st);
- if (RTEST(result)) break;
- node = node->nd_2nd;
- goto again;
-
- case NODE_NOT:
- if (RTEST(rb_eval(self, node->nd_body))) result = Qfalse;
- else result = Qtrue;
- break;
-
- case NODE_DOT2:
- case NODE_DOT3:
- {
- VALUE beg = rb_eval(self, node->nd_beg);
- VALUE end = rb_eval(self, node->nd_end);
- result = rb_range_new(beg, end, nd_type(node) == NODE_DOT3);
- }
- break;
-
- case NODE_FLIP2: /* like AWK */
- {
- VALUE *flip = rb_svar(node->nd_cnt);
- if (!flip) rb_bug("unexpected local variable");
- if (!RTEST(*flip)) {
- if (RTEST(rb_eval(self, node->nd_beg))) {
- *flip = RTEST(rb_eval(self, node->nd_end))?Qfalse:Qtrue;
- result = Qtrue;
- }
- else {
- result = Qfalse;
- }
- }
- else {
- if (RTEST(rb_eval(self, node->nd_end))) {
- *flip = Qfalse;
- }
- result = Qtrue;
- }
- }
- break;
-
- case NODE_FLIP3: /* like SED */
- {
- VALUE *flip = rb_svar(node->nd_cnt);
- if (!flip) rb_bug("unexpected local variable");
- if (!RTEST(*flip)) {
- result = RTEST(rb_eval(self, node->nd_beg)) ? Qtrue : Qfalse;
- *flip = result;
- }
- else {
- if (RTEST(rb_eval(self, node->nd_end))) {
- *flip = Qfalse;
- }
- result = Qtrue;
- }
- }
- break;
-
- case NODE_RETURN:
- return_jump(rb_eval(self, node->nd_stts));
- break;
-
- case NODE_ARGSCAT:
- {
- VALUE args = rb_eval(self, node->nd_head);
- result = rb_ary_concat(args, splat_value(rb_eval(self, node->nd_body)));
- }
- break;
-
- case NODE_ARGSPUSH:
- {
- VALUE args = rb_ary_dup(rb_eval(self, node->nd_head));
- result = rb_ary_push(args, rb_eval(self, node->nd_body));
- }
- break;
-
- case NODE_ATTRASGN:
- {
- VALUE recv;
- int argc; VALUE *argv; /* used in SETUP_ARGS */
- int scope;
- TMP_PROTECT;
-
- BEGIN_CALLARGS;
- if (node->nd_recv == (NODE *)1) {
- recv = self;
- scope = 1;
- }
- else {
- recv = rb_eval(self, node->nd_recv);
- scope = 0;
- }
- SETUP_ARGS(node->nd_args);
- END_CALLARGS;
-
- ruby_current_node = node;
- SET_CURRENT_SOURCE();
- rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,scope);
- result = argv[argc-1];
- }
- break;
-
- case NODE_CALL:
- {
- VALUE recv;
- int argc; VALUE *argv; /* used in SETUP_ARGS */
- TMP_PROTECT;
-
- BEGIN_CALLARGS;
- recv = rb_eval(self, node->nd_recv);
- SETUP_ARGS(node->nd_args);
- END_CALLARGS;
-
- ruby_current_node = node;
- SET_CURRENT_SOURCE();
- result = rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,0);
- }
- break;
-
- case NODE_FCALL:
- {
- int argc; VALUE *argv; /* used in SETUP_ARGS */
- TMP_PROTECT;
-
- BEGIN_CALLARGS;
- SETUP_ARGS(node->nd_args);
- END_CALLARGS;
-
- ruby_current_node = node;
- SET_CURRENT_SOURCE();
- result = rb_call(CLASS_OF(self),self,node->nd_mid,argc,argv,1);
- }
- break;
-
- case NODE_VCALL:
- SET_CURRENT_SOURCE();
- result = rb_call(CLASS_OF(self),self,node->nd_mid,0,0,2);
- break;
-
- case NODE_SUPER:
- case NODE_ZSUPER:
- {
- int argc; VALUE *argv; /* used in SETUP_ARGS */
- TMP_PROTECT;
-
- if (ruby_frame->this_class == 0) {
- if (ruby_frame->this_func) {
- rb_name_error(ruby_frame->callee,
- "superclass method `%s' disabled",
- rb_id2name(ruby_frame->this_func));
- }
- else {
- rb_raise(rb_eNoMethodError, "super called outside of method");
- }
- }
- if (nd_type(node) == NODE_ZSUPER) {
- argc = ruby_frame->argc;
- if (argc && ruby_frame->prev &&
- (ruby_frame->prev->flags & FRAME_DMETH)) {
- if (TYPE(RBASIC(ruby_scope)->klass) != T_ARRAY ||
- RARRAY(RBASIC(ruby_scope)->klass)->len != argc) {
- rb_raise(rb_eRuntimeError,
- "super: specify arguments explicitly");
- }
- argv = RARRAY(RBASIC(ruby_scope)->klass)->ptr;
- }
- else {
- argv = ruby_scope->local_vars + 2;
- }
- }
- else {
- BEGIN_CALLARGS;
- SETUP_ARGS(node->nd_args);
- END_CALLARGS;
- ruby_current_node = node;
- }
-
- SET_CURRENT_SOURCE();
- result = rb_call_super(argc, argv);
- }
- break;
-
- case NODE_SCOPE:
- {
- struct FRAME frame;
- NODE *saved_cref = 0;
-
- frame = *ruby_frame;
- frame.tmp = ruby_frame;
- ruby_frame = &frame;
-
- PUSH_SCOPE();
- PUSH_TAG(PROT_NONE);
- if (node->nd_rval) {
- saved_cref = ruby_cref;
- ruby_cref = (NODE*)node->nd_rval;
- }
- if (node->nd_tbl) {
- VALUE *vars = ALLOCA_N(VALUE, node->nd_tbl[0]+1);
- *vars++ = (VALUE)node;
- ruby_scope->local_vars = vars;
- rb_mem_clear(ruby_scope->local_vars, node->nd_tbl[0]);
- ruby_scope->local_tbl = node->nd_tbl;
- }
- else {
- ruby_scope->local_vars = 0;
- ruby_scope->local_tbl = 0;
- }
- if ((state = EXEC_TAG()) == 0) {
- result = rb_eval(self, node->nd_next);
- }
- POP_TAG();
- POP_SCOPE();
- ruby_frame = frame.tmp;
- if (saved_cref)
- ruby_cref = saved_cref;
- if (state) JUMP_TAG(state);
- }
- break;
-
- case NODE_OP_ASGN1:
- {
- int argc; VALUE *argv; /* used in SETUP_ARGS */
- VALUE recv, val;
- NODE *rval;
- TMP_PROTECT;
-
- recv = rb_eval(self, node->nd_recv);
- rval = node->nd_args->nd_head;
- SETUP_ARGS0(node->nd_args->nd_next, node->nd_args->nd_alen - 1);
- val = rb_funcall2(recv, aref, argc-1, argv);
- switch (node->nd_mid) {
- case 0: /* OR */
- if (RTEST(val)) RETURN(val);
- val = rb_eval(self, rval);
- break;
- case 1: /* AND */
- if (!RTEST(val)) RETURN(val);
- val = rb_eval(self, rval);
- break;
- default:
- val = rb_funcall(val, node->nd_mid, 1, rb_eval(self, rval));
- }
- argv[argc-1] = val;
- rb_funcall2(recv, aset, argc, argv);
- result = val;
- }
- break;
-
- case NODE_OP_ASGN2:
- {
- ID id = node->nd_next->nd_vid;
- VALUE recv, val;
-
- recv = rb_eval(self, node->nd_recv);
- val = rb_funcall(recv, id, 0);
- switch (node->nd_next->nd_mid) {
- case 0: /* OR */
- if (RTEST(val)) RETURN(val);
- val = rb_eval(self, node->nd_value);
- break;
- case 1: /* AND */
- if (!RTEST(val)) RETURN(val);
- val = rb_eval(self, node->nd_value);
- break;
- default:
- val = rb_funcall(val, node->nd_next->nd_mid, 1,
- rb_eval(self, node->nd_value));
- }
-
- rb_funcall2(recv, node->nd_next->nd_aid, 1, &val);
- result = val;
- }
- break;
-
- case NODE_OP_ASGN_AND:
- result = rb_eval(self, node->nd_head);
- if (!RTEST(result)) break;
- node = node->nd_value;
- goto again;
-
- case NODE_OP_ASGN_OR:
- if ((node->nd_aid && !is_defined(self, node->nd_head, 0, 0)) ||
- !RTEST(result = rb_eval(self, node->nd_head))) {
- node = node->nd_value;
- goto again;
- }
- break;
-
- case NODE_MASGN:
- result = massign(self, node, rb_eval(self, node->nd_value), 0);
- break;
-
- case NODE_LASGN:
- if (ruby_scope->local_vars == 0)
- rb_bug("unexpected local variable assignment");
- result = rb_eval(self, node->nd_value);
- ruby_scope->local_vars[node->nd_cnt] = result;
- break;
-
- case NODE_DASGN:
- result = rb_eval(self, node->nd_value);
- dvar_asgn(node->nd_vid, result);
- break;
-
- case NODE_DASGN_CURR:
- result = rb_eval(self, node->nd_value);
- dvar_asgn_curr(node->nd_vid, result);
- break;
-
- case NODE_GASGN:
- result = rb_eval(self, node->nd_value);
- rb_gvar_set(node->nd_entry, result);
- break;
-
- case NODE_IASGN:
- result = rb_eval(self, node->nd_value);
- rb_ivar_set(self, node->nd_vid, result);
- break;
-
- case NODE_CDECL:
- result = rb_eval(self, node->nd_value);
- if (node->nd_vid == 0) {
- rb_const_set(class_prefix(self, node->nd_else), node->nd_else->nd_mid, result);
- }
- else {
- if (NIL_P(ruby_cbase)) {
- rb_raise(rb_eTypeError, "no class/module to define constant");
- }
- rb_const_set(ruby_cbase, node->nd_vid, result);
- }
- break;
-
- case NODE_CVDECL:
- if (NIL_P(ruby_cbase)) {
- rb_raise(rb_eTypeError, "no class/module to define class variable");
- }
- result = rb_eval(self, node->nd_value);
- rb_cvar_set(cvar_cbase(), node->nd_vid, result, Qtrue);
- break;
-
- case NODE_CVASGN:
- result = rb_eval(self, node->nd_value);
- rb_cvar_set(cvar_cbase(), node->nd_vid, result, Qfalse);
- break;
-
- case NODE_LVAR:
- if (ruby_scope->local_vars == 0) {
- rb_bug("unexpected local variable");
- }
- result = ruby_scope->local_vars[node->nd_cnt];
- break;
-
- case NODE_DVAR:
- result = rb_dvar_ref(node->nd_vid);
- break;
-
- case NODE_GVAR:
- result = rb_gvar_get(node->nd_entry);
- break;
-
- case NODE_IVAR:
- result = rb_ivar_get(self, node->nd_vid);
- break;
-
- case NODE_CONST:
- result = ev_const_get(ruby_cref, node->nd_vid, self);
- break;
-
- case NODE_CVAR:
- result = rb_cvar_get(cvar_cbase(), node->nd_vid);
- break;
-
- case NODE_BLOCK_ARG:
- if (ruby_scope->local_vars == 0)
- rb_bug("unexpected block argument");
- if (rb_block_given_p()) {
- result = rb_block_proc();
- ruby_scope->local_vars[node->nd_cnt] = result;
- }
- else {
- result = Qnil;
- }
- break;
-
- case NODE_COLON2:
- {
- VALUE klass;
-
- klass = rb_eval(self, node->nd_head);
- if (rb_is_const_id(node->nd_mid)) {
- switch (TYPE(klass)) {
- case T_CLASS:
- case T_MODULE:
- result = rb_const_get_from(klass, node->nd_mid);
- break;
- default:
- rb_raise(rb_eTypeError, "%s is not a class/module",
- RSTRING(rb_obj_as_string(klass))->ptr);
- break;
- }
- }
- else {
- result = rb_funcall(klass, node->nd_mid, 0, 0);
- }
- }
- break;
-
- case NODE_COLON3:
- result = rb_const_get_from(rb_cObject, node->nd_mid);
- break;
-
- case NODE_NTH_REF:
- result = rb_reg_nth_match(node->nd_nth, MATCH_DATA);
- break;
-
- case NODE_BACK_REF:
- switch (node->nd_nth) {
- case '&':
- result = rb_reg_last_match(MATCH_DATA);
- break;
- case '`':
- result = rb_reg_match_pre(MATCH_DATA);
- break;
- case '\'':
- result = rb_reg_match_post(MATCH_DATA);
- break;
- case '+':
- result = rb_reg_match_last(MATCH_DATA);
- break;
- default:
- rb_bug("unexpected back-ref");
- }
- break;
-
- case NODE_HASH:
- {
- NODE *list;
- VALUE hash = rb_hash_new();
- VALUE key, val;
-
- list = node->nd_head;
- while (list) {
- key = rb_eval(self, list->nd_head);
- list = list->nd_next;
- if (list == 0)
- rb_bug("odd number list for Hash");
- val = rb_eval(self, list->nd_head);
- list = list->nd_next;
- rb_hash_aset(hash, key, val);
- }
- result = hash;
- }
- break;
-
- case NODE_ZARRAY: /* zero length list */
- result = rb_ary_new();
- break;
-
- case NODE_ARRAY:
- {
- VALUE ary;
- long i;
-
- i = node->nd_alen;
- ary = rb_ary_new2(i);
- for (i=0;node;node=node->nd_next) {
- RARRAY(ary)->ptr[i++] = rb_eval(self, node->nd_head);
- RARRAY(ary)->len = i;
- }
-
- result = ary;
- }
- break;
-
- case NODE_VALUES:
- {
- VALUE val;
- long i;
-
- i = node->nd_alen;
- val = rb_values_new2(i, 0);
- for (i=0;node;node=node->nd_next) {
- RARRAY(val)->ptr[i++] = rb_eval(self, node->nd_head);
- RARRAY(val)->len = i;
- }
-
- result = val;
- }
- break;
-
- case NODE_STR:
- result = rb_str_new3(node->nd_lit);
- break;
-
- case NODE_EVSTR:
- result = rb_obj_as_string(rb_eval(self, node->nd_body));
- break;
-
- case NODE_DSTR:
- case NODE_DXSTR:
- case NODE_DREGX:
- case NODE_DREGX_ONCE:
- case NODE_DSYM:
- {
- VALUE str, str2;
- NODE *list = node->nd_next;
-
- str = rb_str_new3(node->nd_lit);
- while (list) {
- if (list->nd_head) {
- switch (nd_type(list->nd_head)) {
- case NODE_STR:
- str2 = list->nd_head->nd_lit;
- break;
- default:
- str2 = rb_eval(self, list->nd_head);
- break;
- }
- rb_str_append(str, str2);
- OBJ_INFECT(str, str2);
- }
- list = list->nd_next;
- }
- switch (nd_type(node)) {
- case NODE_DREGX:
- result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
- node->nd_cflag);
- break;
- case NODE_DREGX_ONCE: /* regexp expand once */
- result = rb_reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
- node->nd_cflag);
- nd_set_type(node, NODE_LIT);
- node->nd_lit = result;
- break;
- case NODE_LIT:
- /* other thread may replace NODE_DREGX_ONCE to NODE_LIT */
- goto again;
- case NODE_DXSTR:
- result = rb_funcall(self, '`', 1, str);
- break;
- case NODE_DSYM:
- result = rb_str_intern(str);
- break;
- default:
- result = str;
- break;
- }
- }
- break;
-
- case NODE_XSTR:
- result = rb_funcall(self, '`', 1, rb_str_new3(node->nd_lit));
- break;
-
- case NODE_LIT:
- result = node->nd_lit;
- break;
-
- case NODE_DEFN:
- if (node->nd_defn) {
- NODE *body, *defn;
- VALUE origin;
- int noex;
-
- if (NIL_P(ruby_class)) {
- rb_raise(rb_eTypeError, "no class/module to add method");
- }
- if (ruby_class == rb_cObject && node->nd_mid == init) {
- rb_warn("redefining Object#initialize may cause infinite loop");
- }
- if (node->nd_mid == __id__ || node->nd_mid == __send__) {
- rb_warn("redefining `%s' may cause serious problem",
- rb_id2name(node->nd_mid));
- }
- rb_frozen_class_p(ruby_class);
- body = search_method(ruby_class, node->nd_mid, &origin);
- if (body){
- if (RTEST(ruby_verbose) && ruby_class == origin && body->nd_cnt == 0 && body->nd_body) {
- rb_warning("method redefined; discarding old %s", rb_id2name(node->nd_mid));
- }
- }
-
- if (SCOPE_TEST(SCOPE_PRIVATE) || node->nd_mid == init) {
- noex = NOEX_PRIVATE;
- }
- else if (SCOPE_TEST(SCOPE_PROTECTED)) {
- noex = NOEX_PROTECTED;
- }
- else {
- noex = NOEX_PUBLIC;
- }
- if (body && origin == ruby_class && body->nd_body == 0) {
- noex |= NOEX_NOSUPER;
- }
-
- defn = copy_node_scope(node->nd_defn, ruby_cref);
- rb_add_method(ruby_class, node->nd_mid, defn, noex);
- if (scope_vmode == SCOPE_MODFUNC) {
- rb_add_method(rb_singleton_class(ruby_class),
- node->nd_mid, defn, NOEX_PUBLIC);
- }
- result = Qnil;
- }
- break;
-
- case NODE_DEFS:
- if (node->nd_defn) {
- VALUE recv = rb_eval(self, node->nd_recv);
- VALUE klass;
- NODE *body = 0, *defn;
-
- if (ruby_safe_level >= 4 && !OBJ_TAINTED(recv)) {
- rb_raise(rb_eSecurityError, "Insecure: can't define singleton method");
- }
- if (FIXNUM_P(recv) || SYMBOL_P(recv)) {
- rb_raise(rb_eTypeError,
- "can't define singleton method \"%s\" for %s",
- rb_id2name(node->nd_mid),
- rb_obj_classname(recv));
- }
-
- if (OBJ_FROZEN(recv)) rb_error_frozen("object");
- klass = rb_singleton_class(recv);
- if (st_lookup(RCLASS(klass)->m_tbl, node->nd_mid, (st_data_t *)&body)) {
- if (ruby_safe_level >= 4) {
- rb_raise(rb_eSecurityError, "redefining method prohibited");
- }
- if (RTEST(ruby_verbose)) {
- rb_warning("redefine %s", rb_id2name(node->nd_mid));
- }
- }
- defn = copy_node_scope(node->nd_defn, ruby_cref);
- rb_add_method(klass, node->nd_mid, defn,
- NOEX_PUBLIC|(body?body->nd_noex&NOEX_UNDEF:0));
- result = Qnil;
- }
- break;
-
- case NODE_UNDEF:
- if (NIL_P(ruby_class)) {
- rb_raise(rb_eTypeError, "no class to undef method");
- }
- rb_undef(ruby_class, rb_to_id(rb_eval(self, node->u2.node)));
- result = Qnil;
- break;
-
- case NODE_ALIAS:
- if (NIL_P(ruby_class)) {
- rb_raise(rb_eTypeError, "no class to make alias");
- }
- rb_alias(ruby_class, rb_to_id(rb_eval(self, node->u1.node)),
- rb_to_id(rb_eval(self, node->u2.node)));
- result = Qnil;
- break;
-
- case NODE_VALIAS:
- rb_alias_variable(node->u1.id, node->u2.id);
- result = Qnil;
- break;
-
- case NODE_CLASS:
- {
- VALUE super, klass, tmp, cbase;
- ID cname;
- int gen = Qfalse;
-
- cbase = class_prefix(self, node->nd_cpath);
- cname = node->nd_cpath->nd_mid;
-
- if (NIL_P(ruby_cbase)) {
- rb_raise(rb_eTypeError, "no outer class/module");
- }
- if (node->nd_super) {
- super = rb_eval(self, node->nd_super);
- rb_check_inheritable(super);
- }
- else {
- super = 0;
- }
-
- if (rb_const_defined_at(cbase, cname)) {
- klass = rb_const_get_at(cbase, cname);
- if (TYPE(klass) != T_CLASS) {
- rb_raise(rb_eTypeError, "%s is not a class",
- rb_id2name(cname));
- }
- if (super) {
- tmp = rb_class_real(RCLASS(klass)->super);
- if (tmp != super) {
- rb_raise(rb_eTypeError, "superclass mismatch for class %s",
- rb_id2name(cname));
- }
- super = 0;
- }
- if (ruby_safe_level >= 4) {
- rb_raise(rb_eSecurityError, "extending class prohibited");
- }
- }
- else {
- if (!super) super = rb_cObject;
- klass = rb_define_class_id(cname, super);
- rb_set_class_path(klass, cbase, rb_id2name(cname));
- rb_const_set(cbase, cname, klass);
- gen = Qtrue;
- }
- if (ruby_wrapper) {
- rb_extend_object(klass, ruby_wrapper);
- rb_include_module(klass, ruby_wrapper);
- }
- if (super && gen) {
- rb_class_inherited(super, klass);
- }
- result = module_setup(klass, node);
- }
- break;
-
- case NODE_MODULE:
- {
- VALUE module, cbase;
- ID cname;
-
- if (NIL_P(ruby_cbase)) {
- rb_raise(rb_eTypeError, "no outer class/module");
- }
- cbase = class_prefix(self, node->nd_cpath);
- cname = node->nd_cpath->nd_mid;
- if (rb_const_defined_at(cbase, cname)) {
- module = rb_const_get_at(cbase, cname);
- if (TYPE(module) != T_MODULE) {
- rb_raise(rb_eTypeError, "%s is not a module",
- rb_id2name(cname));
- }
- if (ruby_safe_level >= 4) {
- rb_raise(rb_eSecurityError, "extending module prohibited");
- }
- }
- else {
- module = rb_define_module_id(cname);
- rb_set_class_path(module, cbase, rb_id2name(cname));
- rb_const_set(cbase, cname, module);
- }
- if (ruby_wrapper) {
- rb_extend_object(module, ruby_wrapper);
- rb_include_module(module, ruby_wrapper);
- }
-
- result = module_setup(module, node);
- }
- break;
-
- case NODE_SCLASS:
- {
- VALUE klass;
-
- result = rb_eval(self, node->nd_recv);
- if (FIXNUM_P(result) || SYMBOL_P(result)) {
- rb_raise(rb_eTypeError, "no singleton class for %s",
- rb_obj_classname(result));
- }
- if (ruby_safe_level >= 4 && !OBJ_TAINTED(result))
- rb_raise(rb_eSecurityError, "Insecure: can't extend object");
- klass = rb_singleton_class(result);
-
- if (ruby_wrapper) {
- rb_extend_object(klass, ruby_wrapper);
- rb_include_module(klass, ruby_wrapper);
- }
-
- result = module_setup(klass, node);
- }
- break;
-
- case NODE_DEFINED:
- {
- char buf[20];
- const char *desc = is_defined(self, node->nd_head, buf, 0);
-
- if (desc) result = rb_str_new2(desc);
- else result = Qnil;
- }
- break;
-
- default:
- unknown_node(node);
- }
- finish:
- CHECK_INTS;
- if (contnode) {
- node = contnode;
- contnode = 0;
- goto again;
- }
- return result;
-}
-
-static VALUE
-module_setup(module, n)
- VALUE module;
- NODE *n;
-{
- NODE * volatile node = n->nd_body;
- int state;
- struct FRAME frame;
- VALUE result = Qnil; /* OK */
- TMP_PROTECT;
-
- frame = *ruby_frame;
- frame.tmp = ruby_frame;
- ruby_frame = &frame;
-
- PUSH_CLASS(module);
- PUSH_SCOPE();
- PUSH_VARS();
-
- if (node->nd_tbl) {
- VALUE *vars = TMP_ALLOC(node->nd_tbl[0]+1);
- *vars++ = (VALUE)node;
- ruby_scope->local_vars = vars;
- rb_mem_clear(ruby_scope->local_vars, node->nd_tbl[0]);
- ruby_scope->local_tbl = node->nd_tbl;
- }
- else {
- ruby_scope->local_vars = 0;
- ruby_scope->local_tbl = 0;
- }
-
- PUSH_CREF(module);
- PUSH_TAG(PROT_NONE);
- if ((state = EXEC_TAG()) == 0) {
- EXEC_EVENT_HOOK(RUBY_EVENT_CLASS, n, ruby_cbase,
- ruby_frame->this_func, ruby_frame->this_class);
- result = rb_eval(ruby_cbase, node->nd_next);
- }
- POP_TAG();
- POP_CREF();
- POP_VARS();
- POP_SCOPE();
- POP_CLASS();
-
- ruby_frame = frame.tmp;
- EXEC_EVENT_HOOK(RUBY_EVENT_END, n, 0, ruby_frame->this_func,
- ruby_frame->this_class);
- if (state) JUMP_TAG(state);
-
- return result;
-}
-
static NODE *basic_respond_to = 0;
int
@@ -4670,9 +3051,12 @@
int
rb_block_given_p()
{
- if (ruby_frame->iter == ITER_CUR && ruby_block)
- return Qtrue;
+ if(GC_GUARDED_PTR_REF(GET_THREAD()->cfp->lfp[0])){
+ return Qtrue;
+ }
+ else{
return Qfalse;
+ }
}
int
@@ -4809,259 +3193,20 @@
VALUE val, self, klass; /* OK */
int flags, avalue;
{
- NODE *node, *var;
- volatile VALUE result = Qnil;
- volatile VALUE old_cref;
- volatile VALUE old_wrapper;
- struct BLOCK * volatile block;
- struct SCOPE * volatile old_scope;
- int old_vmode;
- struct FRAME frame;
- NODE *cnode = ruby_current_node;
- int lambda = flags & YIELD_LAMBDA_CALL;
- int state;
-
- rb_need_block();
-
- PUSH_VARS();
- block = ruby_block;
- frame = block->frame;
- frame.prev = ruby_frame;
- frame.node = cnode;
- ruby_frame = &(frame);
- old_cref = (VALUE)ruby_cref;
- ruby_cref = block->cref;
- old_wrapper = ruby_wrapper;
- ruby_wrapper = block->wrapper;
- old_scope = ruby_scope;
- ruby_scope = block->scope;
- old_vmode = scope_vmode;
- scope_vmode = (flags & YIELD_PUBLIC_DEF) ? SCOPE_PUBLIC : block->vmode;
- ruby_block = block->prev;
- if (block->flags & BLOCK_D_SCOPE) {
- /* put place holder for dynamic (in-block) local variables */
- ruby_dyna_vars = new_dvar(0, 0, block->dyna_vars);
- }
- else {
- /* FOR does not introduce new scope */
- ruby_dyna_vars = block->dyna_vars;
- }
- PUSH_CLASS(klass ? klass : block->klass);
- if (!klass) {
- self = block->self;
- }
- node = block->body;
- var = block->var;
-
- if (var) {
- PUSH_TAG(PROT_NONE);
- if ((state = EXEC_TAG()) == 0) {
- NODE *bvar = NULL;
- block_var:
- if (var == (NODE*)1) { /* no parameter || */
- if (lambda && RARRAY(val)->len != 0) {
- rb_raise(rb_eArgError, "wrong number of arguments (%ld for 0)",
- RARRAY(val)->len);
- }
- }
- else if (var == (NODE*)2) {
- if (TYPE(val) == T_ARRAY && RARRAY(val)->len != 0) {
- rb_raise(rb_eArgError, "wrong number of arguments (%ld for 0)",
- RARRAY(val)->len);
- }
- }
- else if (!bvar && nd_type(var) == NODE_BLOCK_PASS) {
- bvar = var->nd_body;
- var = var->nd_args;
- goto block_var;
- }
- else if (nd_type(var) == NODE_MASGN) {
- if (!avalue) {
- val = svalue_to_mrhs(val, var->nd_head);
- }
- massign(self, var, val, lambda);
- }
- else if (nd_type(var) == NODE_ARGS) {
- if (!avalue) {
- val = svalue_to_mrhs(val, var->nd_head);
- }
- formal_assign(self, var, RARRAY(val)->len, RARRAY(val)->ptr, 0);
- }
- else if (nd_type(var) == NODE_BLOCK) {
- if (var->nd_next) {
- bvar = var->nd_next->nd_head;
- }
- var = var->nd_head;
- goto block_var;
- }
- else {
- int len = 0;
- if (avalue) {
- len = RARRAY(val)->len;
- if (len == 0) {
- goto zero_arg;
- }
- if (len == 1) {
- val = RARRAY(val)->ptr[0];
- }
- else {
- goto multi_values;
- }
- }
- else if (val == Qundef) {
- zero_arg:
- val = Qnil;
- multi_values:
- {
- ruby_current_node = var;
- rb_warn("multiple values for a block parameter (%d for 1)\n\tfrom %s:%d",
- len, cnode->nd_file, nd_line(cnode));
- ruby_current_node = cnode;
- }
- }
- assign(self, var, val, lambda);
- }
- if (bvar) {
- VALUE blk;
- if (flags & YIELD_PROC_CALL)
- blk = block->block_obj;
- else
- blk = rb_block_proc();
- assign(self, bvar, blk, 0);
- }
- }
- POP_TAG();
- if (state) goto pop_state;
- }
- else if (lambda && RARRAY(val)->len != 0 &&
- (!node || nd_type(node) != NODE_IFUNC ||
- node->nd_cfnc != bmcall)) {
- rb_raise(rb_eArgError, "wrong number of arguments (%ld for 0)",
- RARRAY(val)->len);
- }
- if (!node) {
- state = 0;
- goto pop_state;
- }
- ruby_current_node = node;
-
- PUSH_ITER(block->iter);
- PUSH_TAG(lambda ? PROT_NONE : PROT_YIELD);
- if ((state = EXEC_TAG()) == 0) {
- redo:
- if (nd_type(node) == NODE_CFUNC || nd_type(node) == NODE_IFUNC) {
- if (node->nd_state == YIELD_FUNC_AVALUE) {
- if (!avalue) {
- val = svalue_to_avalue(val);
- }
- }
- else {
- if (avalue) {
- val = avalue_to_svalue(val);
- }
- if (val == Qundef && node->nd_state != YIELD_FUNC_SVALUE)
- val = Qnil;
- }
- if ((block->flags&BLOCK_FROM_METHOD) && RTEST(block->block_obj)) {
- struct BLOCK *data, _block;
- Data_Get_Struct(block->block_obj, struct BLOCK, data);
- _block = *data;
- _block.outer = ruby_block;
- _block.uniq = block_unique++;
- ruby_block = &_block;
- PUSH_ITER(ITER_PRE);
- ruby_frame->iter = ITER_CUR;
- result = (*node->nd_cfnc)(val, node->nd_tval, self);
- POP_ITER();
- }
- else {
- result = (*node->nd_cfnc)(val, node->nd_tval, self);
- }
- }
- else {
- result = rb_eval(self, node);
- }
- }
- else {
- switch (state) {
- case TAG_REDO:
- state = 0;
- CHECK_INTS;
- goto redo;
- case TAG_NEXT:
- state = 0;
- result = prot_tag->retval;
- break;
- case TAG_BREAK:
- if (TAG_DST()) {
- result = prot_tag->retval;
- }
- else {
- lambda = Qtrue; /* just pass TAG_BREAK */
- }
- break;
- default:
- break;
- }
- }
- POP_TAG();
- POP_ITER();
- pop_state:
- POP_CLASS();
- if (ruby_dyna_vars && (block->flags & BLOCK_D_SCOPE) &&
- !FL_TEST(ruby_dyna_vars, DVAR_DONT_RECYCLE)) {
- struct RVarmap *vars = ruby_dyna_vars;
-
- if (ruby_dyna_vars->id == 0) {
- vars = ruby_dyna_vars->next;
- rb_gc_force_recycle((VALUE)ruby_dyna_vars);
- while (vars && vars->id != 0 && vars != block->dyna_vars) {
- struct RVarmap *tmp = vars->next;
- rb_gc_force_recycle((VALUE)vars);
- vars = tmp;
- }
- }
- }
- POP_VARS();
- ruby_block = block;
- ruby_frame = ruby_frame->prev;
- ruby_cref = (NODE*)old_cref;
- ruby_wrapper = old_wrapper;
- if (ruby_scope->flags & SCOPE_DONT_RECYCLE)
- scope_dup(old_scope);
- ruby_scope = old_scope;
- scope_vmode = old_vmode;
- switch (state) {
- case 0:
- break;
- case TAG_BREAK:
- if (!lambda) {
- struct tag *tt = prot_tag;
-
- while (tt) {
- if (tt->tag == PROT_LOOP && tt->blkid == ruby_block->uniq) {
- tt->dst = (VALUE)tt->frame->uniq;
- tt->retval = result;
- JUMP_TAG(TAG_BREAK);
- }
- tt = tt->prev;
- }
- proc_jump_error(TAG_BREAK, result);
- }
- /* fall through */
- default:
- JUMP_TAG(state);
- break;
- }
- ruby_current_node = cnode;
- return result;
+ if(avalue){
+ return th_invoke_yield(GET_THREAD(),
+ RARRAY(val)->len, RARRAY(val)->ptr);
+ }
+ else{
+ return th_invoke_yield(GET_THREAD(), 1, &val);
+ }
}
VALUE
rb_yield(val)
VALUE val;
{
- return rb_yield_0(val, 0, 0, 0, Qfalse);
+ return rb_yield_0(val, 0, 0, 0, Qfalse);
}
VALUE
@@ -5131,216 +3276,41 @@
return Qnil; /* dummy */
}
-static VALUE
-massign(self, node, val, pcall)
- VALUE self;
- NODE *node;
- VALUE val;
- int pcall;
-{
- NODE *list;
- long i = 0, len;
-
- len = RARRAY(val)->len;
- list = node->nd_head;
- for (; list && i<len; i++) {
- assign(self, list->nd_head, RARRAY(val)->ptr[i], pcall);
- list = list->nd_next;
- }
- if (pcall && list) goto arg_error;
- if (node->nd_args) {
- if ((long)(node->nd_args) == -1) {
- /* no check for mere `*' */
- }
- else if (!list && i<len) {
- assign(self, node->nd_args, rb_ary_new4(len-i, RARRAY(val)->ptr+i), pcall);
- }
- else {
- assign(self, node->nd_args, rb_ary_new2(0), pcall);
- }
- }
- else if (pcall && i < len) {
- goto arg_error;
- }
-
- while (list) {
- i++;
- assign(self, list->nd_head, Qnil, pcall);
- list = list->nd_next;
- }
- return val;
-
- arg_error:
- while (list) {
- i++;
- list = list->nd_next;
- }
- rb_raise(rb_eArgError, "wrong number of arguments (%ld for %ld)", len, i);
-}
-
-static void
-assign(self, lhs, val, pcall)
- VALUE self;
- NODE *lhs;
- VALUE val;
- int pcall;
-{
- ruby_current_node = lhs;
- if (val == Qundef) {
- rb_warning("assigning void value");
- val = Qnil;
- }
- switch (nd_type(lhs)) {
- case NODE_GASGN:
- rb_gvar_set(lhs->nd_entry, val);
- break;
-
- case NODE_IASGN:
- rb_ivar_set(self, lhs->nd_vid, val);
- break;
-
- case NODE_LASGN:
- if (ruby_scope->local_vars == 0)
- rb_bug("unexpected local variable assignment");
- ruby_scope->local_vars[lhs->nd_cnt] = val;
- break;
-
- case NODE_DASGN:
- dvar_asgn(lhs->nd_vid, val);
- break;
-
- case NODE_DASGN_CURR:
- dvar_asgn_curr(lhs->nd_vid, val);
- break;
-
- case NODE_CDECL:
- if (lhs->nd_vid == 0) {
- rb_const_set(class_prefix(self, lhs->nd_else), lhs->nd_else->nd_mid, val);
- }
- else {
- rb_const_set(ruby_cbase, lhs->nd_vid, val);
- }
- break;
-
- case NODE_CVDECL:
- if (RTEST(ruby_verbose) && FL_TEST(ruby_cbase, FL_SINGLETON)) {
- rb_warn("declaring singleton class variable");
- }
- rb_cvar_set(cvar_cbase(), lhs->nd_vid, val, Qtrue);
- break;
-
- case NODE_CVASGN:
- rb_cvar_set(cvar_cbase(), lhs->nd_vid, val, Qfalse);
- break;
-
- case NODE_MASGN:
- massign(self, lhs, svalue_to_mrhs(val, lhs->nd_head), pcall);
- break;
-
- case NODE_CALL:
- case NODE_ATTRASGN:
- {
- VALUE recv;
- int scope;
- if (lhs->nd_recv == (NODE *)1) {
- recv = self;
- scope = 1;
- }
- else {
- recv = rb_eval(self, lhs->nd_recv);
- scope = 0;
- }
- if (!lhs->nd_args) {
- /* attr set */
- ruby_current_node = lhs;
- SET_CURRENT_SOURCE();
- rb_call(CLASS_OF(recv), recv, lhs->nd_mid, 1, &val, scope);
- }
- else {
- /* array set */
- VALUE args;
-
- args = rb_eval(self, lhs->nd_args);
- rb_ary_push(args, val);
- ruby_current_node = lhs;
- SET_CURRENT_SOURCE();
- rb_call(CLASS_OF(recv), recv, lhs->nd_mid,
- RARRAY(args)->len, RARRAY(args)->ptr, scope);
- }
- }
- break;
-
- default:
- rb_bug("bug in variable assignment");
- break;
- }
-}
-
VALUE
rb_iterate(it_proc, data1, bl_proc, data2)
VALUE (*it_proc) _((VALUE)), (*bl_proc)(ANYARGS);
VALUE data1, data2;
{
- int state;
- volatile VALUE retval = Qnil;
- NODE *node = NEW_IFUNC(bl_proc, data2);
- VALUE self = ruby_top_self;
+ int state;
+ volatile VALUE retval = Qnil;
+ NODE *node = NEW_IFUNC(bl_proc, data2);
- PUSH_ITER(ITER_PRE);
- PUSH_TAG(PROT_LOOP);
- PUSH_BLOCK(0, node);
- state = EXEC_TAG();
- if (state == 0) {
+ PUSH_TAG(PROT_LOOP);
+ state = EXEC_TAG();
+ if (state == 0) {
iter_retry:
- retval = (*it_proc)(data1);
- }
- else if (state == TAG_BREAK && TAG_DST()) {
- retval = prot_tag->retval;
- state = 0;
- }
- else if (state == TAG_RETRY) {
- state = 0;
- goto iter_retry;
- }
- POP_BLOCK();
- POP_TAG();
- POP_ITER();
+ GET_THREAD()->ifuncnode = node;
+ retval = (*it_proc)(data1);
+ }
+ else if (state == TAG_BREAK && TAG_DST()) {
+ retval = prot_tag->retval;
+ state = 0;
+ }
+ else if (state == TAG_RETRY) {
+ state = 0;
+ goto iter_retry;
+ }
+ POP_TAG();
- switch (state) {
- case 0:
- break;
- default:
- JUMP_TAG(state);
- }
- return retval;
+ switch (state) {
+ case 0:
+ break;
+ default:
+ JUMP_TAG(state);
+ }
+ return retval;
}
-static int
-handle_rescue(self, node)
- VALUE self;
- NODE *node;
-{
- int argc; VALUE *argv; /* used in SETUP_ARGS */
- TMP_PROTECT;
-
- if (!node->nd_args) {
- return rb_obj_is_kind_of(ruby_errinfo, rb_eStandardError);
- }
-
- BEGIN_CALLARGS;
- SETUP_ARGS(node->nd_args);
- END_CALLARGS;
-
- while (argc--) {
- if (!rb_obj_is_kind_of(argv[0], rb_cModule)) {
- rb_raise(rb_eTypeError, "class or module required for rescue clause");
- }
- if (RTEST(rb_funcall(*argv, eqq, 1, ruby_errinfo))) return 1;
- argv++;
- }
- return 0;
-}
-
VALUE
#ifdef HAVE_STDARG_PROTOTYPES
rb_rescue2(VALUE (*b_proc)(ANYARGS), VALUE data1, VALUE (*r_proc)(ANYARGS), VALUE data2, ...)
@@ -5628,360 +3598,8 @@
return rb_funcall2(obj, missing, argc+1, nargv);
}
-static inline VALUE
-call_cfunc(func, recv, len, argc, argv)
- VALUE (*func)();
- VALUE recv;
- int len, argc;
- VALUE *argv;
-{
- if (len >= 0 && argc != len) {
- rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
- argc, len);
- }
- switch (len) {
- case -2:
- return (*func)(recv, rb_ary_new4(argc, argv));
- break;
- case -1:
- return (*func)(argc, argv, recv);
- break;
- case 0:
- return (*func)(recv);
- break;
- case 1:
- return (*func)(recv, argv[0]);
- break;
- case 2:
- return (*func)(recv, argv[0], argv[1]);
- break;
- case 3:
- return (*func)(recv, argv[0], argv[1], argv[2]);
- break;
- case 4:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3]);
- break;
- case 5:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4]);
- break;
- case 6:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5]);
- break;
- case 7:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6]);
- break;
- case 8:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7]);
- break;
- case 9:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8]);
- break;
- case 10:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9]);
- break;
- case 11:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9], argv[10]);
- break;
- case 12:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9],
- argv[10], argv[11]);
- break;
- case 13:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
- argv[11], argv[12]);
- break;
- case 14:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
- argv[11], argv[12], argv[13]);
- break;
- case 15:
- return (*func)(recv, argv[0], argv[1], argv[2], argv[3], argv[4],
- argv[5], argv[6], argv[7], argv[8], argv[9], argv[10],
- argv[11], argv[12], argv[13], argv[14]);
- break;
- default:
- rb_raise(rb_eArgError, "too many arguments (%d)", len);
- break;
- }
- return Qnil; /* not reached */
-}
-
-static int
-formal_assign(recv, node, argc, argv, local_vars)
- VALUE recv;
- NODE *node;
- int argc;
- VALUE *argv;
- VALUE *local_vars;
-{
- int i;
- int nopt = 0;
-
- if (nd_type(node) != NODE_ARGS) {
- rb_bug("no argument-node");
- }
-
- i = node->nd_frml ? RARRAY(node->nd_frml)->len : 0;
- if (i > argc) {
- rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, i);
- }
- if (!node->nd_rest) {
- NODE *optnode = node->nd_opt;
-
- nopt = i;
- while (optnode) {
- nopt++;
- optnode = optnode->nd_next;
- }
- if (nopt < argc) {
- rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", argc, nopt);
- }
- }
- if (local_vars) {
- if (i > 0) {
- /* +2 for $_ and $~ */
- MEMCPY(local_vars+2, argv, VALUE, i);
- }
- }
- else {
- int j;
- VALUE a = node->nd_frml;
-
- for (j=0; j<i; j++) {
- dvar_asgn_curr(SYM2ID(RARRAY(a)->ptr[j]), argv[j]);
- }
- }
- argv += i; argc -= i;
- if (node->nd_opt) {
- NODE *opt = node->nd_opt;
-
- while (opt && argc) {
- assign(recv, opt->nd_head, *argv, 1);
- argv++; argc--;
- ++i;
- opt = opt->nd_next;
- }
- if (opt) {
- rb_eval(recv, opt);
- }
- }
- if (!node->nd_rest) {
- i = nopt;
- }
- else {
- VALUE v;
-
- if (argc > 0) {
- v = rb_ary_new4(argc,argv);
- i = -i - 1;
- }
- else {
- v = rb_ary_new2(0);
- }
- assign(recv, node->nd_rest, v, 1);
- }
- return i;
-}
-
static VALUE
-rb_call0(klass, recv, id, oid, argc, argv, body, nosuper)
- VALUE klass, recv;
- ID id;
- ID oid;
- int argc; /* OK */
- VALUE *argv; /* OK */
- NODE * volatile body;
- int nosuper;
-{
- NODE *b2; /* OK */
- volatile VALUE result = Qnil;
- int itr;
- static int tick;
- volatile VALUE args;
- TMP_PROTECT;
-
- switch (ruby_iter->iter) {
- case ITER_PRE:
- itr = ITER_CUR;
- break;
- case ITER_CUR:
- default:
- itr = ITER_NOT;
- break;
- }
-
- if ((++tick & 0xff) == 0) {
- CHECK_INTS; /* better than nothing */
- stack_check();
- rb_gc_finalize_deferred();
- }
- if (argc < 0) {
- argc = -argc-1;
- args = rb_ary_concat(rb_ary_new4(argc, argv), splat_value(argv[argc]));
- argc = RARRAY(args)->len;
- argv = RARRAY(args)->ptr;
- }
- PUSH_ITER(itr);
- PUSH_FRAME();
- ruby_frame->callee = id;
- ruby_frame->this_func = oid;
- ruby_frame->this_class = nosuper?0:klass;
- ruby_frame->self = recv;
- ruby_frame->argc = argc;
-
- switch (nd_type(body)) {
- case NODE_CFUNC:
- {
- int len = body->nd_argc;
-
- if (len < -2) {
- rb_bug("bad argc (%d) specified for `%s(%s)'",
- len, rb_class2name(klass), rb_id2name(id));
- }
- if (event_hooks) {
- int state;
-
- EXEC_EVENT_HOOK(RUBY_EVENT_C_CALL, ruby_current_node,
- recv, id, klass);
- PUSH_TAG(PROT_FUNC);
- if ((state = EXEC_TAG()) == 0) {
- result = call_cfunc(body->nd_cfnc, recv, len, argc, argv);
- }
- POP_TAG();
- ruby_current_node = ruby_frame->node;
- EXEC_EVENT_HOOK(RUBY_EVENT_C_RETURN, ruby_current_node,
- recv, id, klass);
- if (state) JUMP_TAG(state);
- }
- else {
- result = call_cfunc(body->nd_cfnc, recv, len, argc, argv);
- }
- }
- break;
-
- /* for attr get/set */
- case NODE_IVAR:
- if (argc != 0) {
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 0)", argc);
- }
- result = rb_attr_get(recv, body->nd_vid);
- break;
-
- case NODE_ATTRSET:
- if (argc != 1)
- rb_raise(rb_eArgError, "wrong number of arguments (%d for 1)", argc);
- result = rb_ivar_set(recv, body->nd_vid, argv[0]);
- break;
-
- case NODE_ZSUPER: /* visibility override */
- result = rb_call_super(argc, argv);
- break;
-
- case NODE_BMETHOD:
- ruby_frame->flags |= FRAME_DMETH;
- result = proc_invoke(body->nd_cval, rb_ary_new4(argc, argv), recv, klass);
- break;
-
- case NODE_SCOPE:
- {
- int state;
- VALUE *local_vars; /* OK */
- NODE *saved_cref = 0;
-
- PUSH_SCOPE();
-
- if (body->nd_rval) {
- saved_cref = ruby_cref;
- ruby_cref = (NODE*)body->nd_rval;
- }
- PUSH_CLASS(ruby_cbase);
- if (body->nd_tbl) {
- local_vars = TMP_ALLOC(body->nd_tbl[0]+1);
- *local_vars++ = (VALUE)body;
- rb_mem_clear(local_vars, body->nd_tbl[0]);
- ruby_scope->local_tbl = body->nd_tbl;
- ruby_scope->local_vars = local_vars;
- }
- else {
- local_vars = ruby_scope->local_vars = 0;
- ruby_scope->local_tbl = 0;
- }
- b2 = body = body->nd_next;
-
- PUSH_VARS();
- PUSH_TAG(PROT_FUNC);
-
- if ((state = EXEC_TAG()) == 0) {
- NODE *node = 0;
-
- if (nd_type(body) == NODE_ARGS) {
- node = body;
- body = 0;
- }
- else if (nd_type(body) == NODE_BLOCK) {
- node = body->nd_head;
- body = body->nd_next;
- }
- if (node) {
- ruby_frame->argc = formal_assign(recv, node, argc, argv, local_vars);
- }
-
- if (event_hooks) {
- EXEC_EVENT_HOOK(RUBY_EVENT_CALL, b2, recv, id, klass);
- }
- result = rb_eval(recv, body);
- }
- else if (state == TAG_RETURN && TAG_DST()) {
- result = prot_tag->retval;
- state = 0;
- }
- POP_TAG();
- POP_VARS();
- POP_CLASS();
- POP_SCOPE();
- ruby_cref = saved_cref;
- if (event_hooks) {
- EXEC_EVENT_HOOK(RUBY_EVENT_RETURN, body, recv, id, klass);
- }
- switch (state) {
- case 0:
- break;
-
- case TAG_BREAK:
- case TAG_RETURN:
- JUMP_TAG(state);
- break;
-
- case TAG_RETRY:
- if (rb_block_given_p()) JUMP_TAG(state);
- /* fall through */
- default:
- jump_tag_but_local_jump(state, result);
- break;
- }
- }
- break;
-
- default:
- unknown_node(body);
- break;
- }
- POP_FRAME();
- POP_ITER();
- return result;
-}
-
-static VALUE
rb_call(klass, recv, mid, argc, argv, scope)
VALUE klass, recv;
ID mid;
@@ -6032,7 +3650,19 @@
}
}
- return rb_call0(klass, recv, mid, id, argc, argv, body, noex & NOEX_NOSUPER);
+ {
+ VALUE val;
+ static int level;
+ int i;
+ //for(i=0; i<level; i++){printf(" ");}
+ //printf("invoke %s (%s)\n", rb_id2name(mid), node_name(nd_type(body)));
+ //level++;
+ val = th_call0(GET_THREAD(), klass, recv, mid, id, argc, argv, body, noex & NOEX_NOSUPER);
+ //level--;
+ //for(i=0; i<level; i++){printf(" ");}
+ //printf("done %s (%s)\n", rb_id2name(mid), node_name(nd_type(body)));
+ return val;
+ }
}
VALUE
@@ -6143,73 +3773,14 @@
int argc;
const VALUE *argv;
{
- VALUE result, self, klass;
-
- if (ruby_frame->this_class == 0) {
- rb_name_error(ruby_frame->callee, "calling `super' from `%s' is prohibited",
- rb_id2name(ruby_frame->this_func));
- }
-
- self = ruby_frame->self;
- klass = ruby_frame->this_class;
-
- PUSH_ITER(ruby_iter->iter ? ITER_PRE : ITER_NOT);
- result = rb_call(RCLASS(klass)->super, self, ruby_frame->this_func, argc, argv, 3);
- POP_ITER();
-
- return result;
+ return th_call_super(GET_THREAD(), argc, argv);
}
static VALUE
backtrace(lev)
int lev;
{
- struct FRAME *frame = ruby_frame;
- VALUE str;
- volatile VALUE ary;
- NODE *n;
-
- ary = rb_ary_new();
- if (frame->this_func == ID_ALLOCATOR) {
- frame = frame->prev;
- }
- if (lev < 0) {
- ruby_set_current_source();
- if (frame->this_func) {
- str = rb_sprintf("%s:%d:in `%s'", ruby_sourcefile, ruby_sourceline,
- rb_id2name(frame->this_func));
- }
- else if (ruby_sourceline == 0) {
- str = rb_str_new2(ruby_sourcefile);
- }
- else {
- str = rb_sprintf("%s:%d", ruby_sourcefile, ruby_sourceline);
- }
- rb_ary_push(ary, str);
- if (lev < -1) return ary;
- }
- else {
- while (lev-- > 0) {
- frame = frame->prev;
- if (!frame) {
- ary = Qnil;
- break;
- }
- }
- }
- for (; frame && (n = frame->node); frame = frame->prev) {
- if (frame->prev && frame->prev->this_func) {
- if (frame->prev->node == n) continue;
- str = rb_sprintf("%s:%d:in `%s'", n->nd_file, nd_line(n),
- rb_id2name(frame->prev->this_func));
- }
- else {
- str = rb_sprintf("%s:%d", n->nd_file, nd_line(n));
- }
- rb_ary_push(ary, str);
- }
-
- return ary;
+ return yarv_backtrace(lev);
}
/*
@@ -6304,136 +3875,43 @@
char *file;
int line;
{
- struct BLOCK *data = NULL;
- volatile VALUE result = Qnil;
- struct SCOPE * volatile old_scope;
- struct BLOCK * volatile old_block;
- struct RVarmap * volatile old_dyna_vars;
- VALUE volatile old_cref;
- int volatile old_vmode;
- volatile VALUE old_wrapper;
- struct FRAME frame;
- NODE *nodesave = ruby_current_node;
- volatile int iter = ruby_frame->iter;
- volatile int safe = ruby_safe_level;
- int state;
-
- if (!NIL_P(scope)) {
- if (!rb_obj_is_proc(scope)) {
- rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc/Binding)",
- rb_obj_classname(scope));
- }
-
- Data_Get_Struct(scope, struct BLOCK, data);
- /* PUSH BLOCK from data */
- frame = data->frame;
- frame.tmp = ruby_frame; /* gc protection */
- ruby_frame = &(frame);
- old_scope = ruby_scope;
- ruby_scope = data->scope;
- old_block = ruby_block;
- ruby_block = data->prev;
- old_dyna_vars = ruby_dyna_vars;
- ruby_dyna_vars = data->dyna_vars;
- old_vmode = scope_vmode;
- scope_vmode = data->vmode;
- old_cref = (VALUE)ruby_cref;
- ruby_cref = data->cref;
- old_wrapper = ruby_wrapper;
- ruby_wrapper = data->wrapper;
- if ((file == 0 || (line == 1 && strcmp(file, "(eval)") == 0)) && data->frame.node) {
- file = data->frame.node->nd_file;
- if (!file) file = "__builtin__";
- line = nd_line(data->frame.node);
- }
-
- self = data->self;
- ruby_frame->iter = data->iter;
- }
- else {
- if (ruby_frame->prev) {
- ruby_frame->iter = ruby_frame->prev->iter;
- }
- }
- if (file == 0) {
- ruby_set_current_source();
- file = ruby_sourcefile;
- line = ruby_sourceline;
- }
- PUSH_CLASS(ruby_cbase);
- ruby_in_eval++;
- if (TYPE(ruby_class) == T_ICLASS) {
- ruby_class = RBASIC(ruby_class)->klass;
- }
- PUSH_TAG(PROT_NONE);
- if ((state = EXEC_TAG()) == 0) {
- NODE *node;
-
- ruby_safe_level = 0;
- result = ruby_errinfo;
- ruby_errinfo = Qnil;
- node = compile(src, file, line);
- ruby_safe_level = safe;
- if (ruby_nerrs > 0) {
- compile_error(0);
- }
- if (!NIL_P(result)) ruby_errinfo = result;
- result = eval_node(self, node);
- }
- POP_TAG();
- POP_CLASS();
- ruby_in_eval--;
- ruby_safe_level = safe;
- if (!NIL_P(scope)) {
- int dont_recycle = ruby_scope->flags & SCOPE_DONT_RECYCLE;
-
- ruby_wrapper = old_wrapper;
- ruby_cref = (NODE*)old_cref;
- ruby_frame = frame.tmp;
- ruby_scope = old_scope;
- ruby_block = old_block;
- ruby_dyna_vars = old_dyna_vars;
- data->vmode = scope_vmode; /* write back visibility mode */
- scope_vmode = old_vmode;
- if (dont_recycle) {
- struct tag *tag;
- struct RVarmap *vars;
-
- scope_dup(ruby_scope);
- for (tag=prot_tag; tag; tag=tag->prev) {
- scope_dup(tag->scope);
- }
- for (vars = ruby_dyna_vars; vars; vars = vars->next) {
- FL_SET(vars, DVAR_DONT_RECYCLE);
- }
- }
- }
- else {
- ruby_frame->iter = iter;
- }
- ruby_current_node = nodesave;
+ volatile int safe = ruby_safe_level;
+ int state;
+ VALUE result;
+
+ if (file == 0) {
ruby_set_current_source();
- if (state) {
- if (state == TAG_RAISE) {
- if (strcmp(file, "(eval)") == 0) {
- VALUE mesg, errat;
+ file = ruby_sourcefile;
+ line = ruby_sourceline;
+ }
- errat = get_backtrace(ruby_errinfo);
- mesg = rb_attr_get(ruby_errinfo, rb_intern("mesg"));
- if (!NIL_P(errat) && TYPE(errat) == T_ARRAY) {
- if (!NIL_P(mesg) && TYPE(mesg) == T_STRING) {
- rb_str_update(mesg, 0, 0, rb_str_new2(": "));
- rb_str_update(mesg, 0, 0, RARRAY(errat)->ptr[0]);
- }
- RARRAY(errat)->ptr[0] = RARRAY(backtrace(-2))->ptr[0];
- }
- }
- rb_exc_raise(ruby_errinfo);
- }
- JUMP_TAG(state);
- }
+ PUSH_TAG(PROT_NONE);
+ if ((state = EXEC_TAG()) == 0) {
+ NODE *node;
+ result = yarvcore_eval(0, src, rb_str_new2(file), INT2FIX(line));
+ }
+ POP_TAG();
+
+ if (state) {
+ if (state == TAG_RAISE) {
+ if (strcmp(file, "(eval)") == 0) {
+ VALUE mesg, errat;
- return result;
+ errat = get_backtrace(ruby_errinfo);
+ mesg = rb_attr_get(ruby_errinfo, rb_intern("mesg"));
+ if (!NIL_P(errat) && TYPE(errat) == T_ARRAY) {
+ if (!NIL_P(mesg) && TYPE(mesg) == T_STRING) {
+ rb_str_update(mesg, 0, 0, rb_str_new2(": "));
+ rb_str_update(mesg, 0, 0, RARRAY(errat)->ptr[0]);
+ }
+ RARRAY(errat)->ptr[0] = RARRAY(backtrace(-2))->ptr[0];
+ }
+ }
+ rb_exc_raise(ruby_errinfo);
+ }
+ JUMP_TAG(state);
+ }
+ return result;
}
/*
@@ -6770,7 +4248,7 @@
rb_thread_critical = critical;
ALLOW_INTS;
if (ruby_nerrs == 0) {
- eval_node(self, node);
+ rb_bug("load");
}
}
ruby_frame->callee = callee;
@@ -8873,25 +6351,6 @@
NODE *iter;
};
-static VALUE
-call_block(arg)
- struct block_arg *arg;
-{
- return rb_eval(arg->self, arg->iter);
-}
-
-static VALUE
-block_pass(self, node)
- VALUE self;
- NODE *node;
-{
- struct block_arg arg;
- arg.self = self;
- arg.iter = node->nd_iter;
- return rb_block_pass((VALUE (*)_((VALUE)))call_block,
- (VALUE)&arg, rb_eval(self, node->nd_body));
-}
-
struct METHOD {
VALUE klass, rklass;
VALUE recv;
@@ -9185,7 +6644,8 @@
if (ruby_safe_level < 4) ruby_safe_level = 4;
}
if ((state = EXEC_TAG()) == 0) {
- result = rb_call0(data->klass,data->recv,data->id,data->oid,argc,argv,data->body,0);
+ result = th_call0(GET_THREAD(),
+ data->klass,data->recv,data->id,data->oid,argc,argv,data->body,0);
}
POP_TAG();
POP_ITER();
Modified: trunk/inits.c
===================================================================
--- trunk/inits.c 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/inits.c 2005-08-15 00:55:30 UTC (rev 231)
@@ -47,10 +47,12 @@
void Init_var_tables _((void));
void Init_version _((void));
void Init_yarvcore _((void));
+void Init_vm _((void));
void
rb_call_inits()
{
+ Init_vm();
Init_sym();
Init_var_tables();
Init_Object();
Added: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/test.rb 2005-08-15 00:55:30 UTC (rev 231)
@@ -0,0 +1,35 @@
+
+$prog = <<'__EOP__'
+
+p 1
+100
+
+__EOP__
+
+$prog = <<__EOP__
+p eval(%q{
+#{$prog}})
+__EOP__
+
+def exec program
+ r = nil
+ IO.popen("#{program}", 'r+'){|io|
+ #
+ io.write $prog
+ io.close_write
+ r = io.read
+ }
+ r
+end
+
+puts "=========================================================="
+puts "YARV"
+puts "----------------------------------------------------------"
+puts exec(ARGV[0])
+
+puts
+puts "=========================================================="
+puts "Ruby"
+puts "----------------------------------------------------------"
+puts exec(ARGV[1])
+
Property changes on: trunk/test.rb
___________________________________________________________________
Name: svn:executable
+ *
Modified: trunk/vm.c
===================================================================
--- trunk/vm.c 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/vm.c 2005-08-15 00:55:30 UTC (rev 231)
@@ -552,7 +552,7 @@
file, line_no);
str = rb_str_new2(buf);
}
-
+
if(th->cfp != cfp){
th_backtrace_each(th, cfp-1, file, line_no, ary);
}
@@ -583,7 +583,7 @@
}
ary = rb_ary_new();
}
-
+
th_backtrace_each(th, top_of_cfp, "", 0, ary);
return ary;
}
Modified: trunk/vm.h
===================================================================
--- trunk/vm.h 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/vm.h 2005-08-15 00:55:30 UTC (rev 231)
@@ -75,8 +75,7 @@
#define throwdebug if(0)printf
//#define throwdebug printf
-#define SDR() stack_dump_raw(th, GET_CFP());
-#define SDR2(cfp) stack_dump_raw(th, (cfp));
+#define SDR2(cfp) vm_stack_dump_raw(GET_THREAD(), (cfp))
/************************************************/
Modified: trunk/vm_dump.c
===================================================================
--- trunk/vm_dump.c 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/vm_dump.c 2005-08-15 00:55:30 UTC (rev 231)
@@ -4,8 +4,9 @@
#include "yarvcore.h"
#include "vm.h"
-
-void control_frame_dump(yarv_thread_t *th, yarv_control_frame_t *cfp){
+static void
+control_frame_dump(yarv_thread_t *th, yarv_control_frame_t *cfp)
+{
int pc = -1, bp = -1;
int lfp = cfp->lfp - th->stack;
int dfp = cfp->dfp - th->stack;
@@ -66,7 +67,9 @@
printf("\n");
}
-void stack_dump_raw(yarv_thread_t *th, yarv_control_frame_t *cfp){
+void
+vm_stack_dump_raw(yarv_thread_t *th, yarv_control_frame_t *cfp)
+{
VALUE *sp = cfp->sp, *bp = cfp->bp;
VALUE *lfp = cfp->lfp;
VALUE *dfp = cfp->dfp;
@@ -95,7 +98,9 @@
printf("---------------------------\n");
}
-void env_dump_raw(yarv_env_t *env, VALUE *lfp, VALUE *dfp){
+void
+env_dump_raw(yarv_env_t *env, VALUE *lfp, VALUE *dfp)
+{
int i;
printf("-- env --------------------\n");
@@ -118,7 +123,9 @@
printf("---------------------------\n");
}
-void proc_dump_raw(yarv_proc_t *proc){
+void
+proc_dump_raw(yarv_proc_t *proc)
+{
yarv_env_t *env;
char *selfstr;
VALUE val = rb_inspect(proc->block.self);
@@ -131,13 +138,17 @@
env_dump_raw(env, proc->block.lfp, proc->block.dfp);
}
-void stack_dump_th(VALUE thval){
+void
+stack_dump_th(VALUE thval)
+{
yarv_thread_t *th;
GetThreadVal(thval, th);
- stack_dump_raw(th, th->cfp);
+ vm_stack_dump_raw(th, th->cfp);
}
-void stack_dump_each(yarv_thread_t *th, yarv_control_frame_t *cfp){
+void
+stack_dump_each(yarv_thread_t *th, yarv_control_frame_t *cfp)
+{
int i, lim = 1;
VALUE rstr;
@@ -211,7 +222,9 @@
}
-void debug_print_register(yarv_thread_t *th){
+void
+debug_print_register(yarv_thread_t *th)
+{
yarv_control_frame_t *cfp = th->cfp;
int pc = -1;
int lfp = cfp->lfp - th->stack;
@@ -230,13 +243,17 @@
pc, cfp->sp - th->stack, lfp, dfp, cfpi);
}
-void thread_dump_regs(VALUE thval){
+void
+thread_dump_regs(VALUE thval)
+{
yarv_thread_t *th;
GetThreadVal(thval, th);
debug_print_register(th);
}
-void debug_print_pre(yarv_thread_t *th, yarv_control_frame_t *cfp){
+void
+debug_print_pre(yarv_thread_t *th, yarv_control_frame_t *cfp)
+{
yarv_iseq_t *iseq = cfp->iseq;
if(iseq != 0 && cfp->magic != FRAME_MAGIC_FINISH){
@@ -252,11 +269,13 @@
#endif
}
-void debug_print_post(yarv_thread_t *th, yarv_control_frame_t *cfp
+void
+debug_print_post(yarv_thread_t *th, yarv_control_frame_t *cfp
#ifdef OPT_STACK_CACHING
, VALUE reg_a, VALUE reg_b
#endif
- ){
+ )
+{
#if VMDEBUG > 9
SDR2(cfp);
#endif
@@ -298,7 +317,9 @@
* val(interned string) => count(Fixnum)
* }
*/
-void vm_analysis_insn(int insn){
+void
+vm_analysis_insn(int insn)
+{
static ID usage_hash;
static ID bigram_hash;
static int prev_insn = -1;
@@ -345,10 +366,12 @@
}
/* from disasm.c */
-VALUE insn_operand_intern(int insn, int op_no, VALUE op,
- int len, int pos, VALUE child);
+extern VALUE insn_operand_intern(int insn, int op_no, VALUE op,
+ int len, int pos, VALUE child);
-void vm_analysis_operand(int insn, int n, VALUE op){
+void
+vm_analysis_operand(int insn, int n, VALUE op)
+{
static ID usage_hash;
VALUE uh;
@@ -384,7 +407,9 @@
SET_YARV_START();
}
-void vm_analysis_register(int reg, int isset){
+void
+vm_analysis_register(int reg, int isset)
+{
static ID usage_hash;
VALUE uh;
VALUE rhash;
@@ -436,7 +461,10 @@
#endif
-VALUE thread_dump_state(VALUE self){
+
+VALUE
+thread_dump_state(VALUE self)
+{
yarv_thread_t* th;
yarv_control_frame_t *cfp;
GetThreadVal(self, th);
Modified: trunk/yarv.h
===================================================================
--- trunk/yarv.h 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/yarv.h 2005-08-15 00:55:30 UTC (rev 231)
@@ -27,6 +27,7 @@
yarv_vm_t *yarv_get_current_running_vm _(());
yarv_thread_t *yarv_get_current_running_thread _(());
+#define GET_THREAD() yarv_get_current_running_thread()
struct yarv_yield_data{
yarv_thread_t *th;
@@ -40,5 +41,18 @@
VALUE thread_yield_light_prepare _((VALUE self, int argc, VALUE *argv,
struct yarv_yield_data *data));
+VALUE th_invoke_yield(yarv_thread_t *th, int argc, VALUE *argv);
+VALUE th_call0(yarv_thread_t *th, VALUE klass, VALUE recv,
+ VALUE id, ID oid, int argc, const VALUE *argv,
+ NODE *body, int nosuper);
+
+VALUE *yarv_svar(int);
+
+VALUE th_call_super(yarv_thread_t *th, int argc, const VALUE *argv);
+
+VALUE yarv_backtrace(int lev);
+
+VALUE yarvcore_eval_parsed(VALUE node, VALUE file);
+
#endif
Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/yarvcore.c 2005-08-15 00:55:30 UTC (rev 231)
@@ -107,7 +107,7 @@
/* rb_block_given */
int yarv_block_given_p(){
- if(GC_GUARDED_PTR_REF(yarv_get_current_running_thread()->cfp->lfp[0])){
+ if(GC_GUARDED_PTR_REF(GET_THREAD()->cfp->lfp[0])){
return 1;
}
else{
@@ -119,7 +119,7 @@
/* rb_yield_values */
VALUE yarv_yield_values(int argc, VALUE *argv){
- yarv_thread_t *th = yarv_get_current_running_thread();
+ yarv_thread_t *th = GET_THREAD();
if(argc == 1 && CLASS_OF(argv[0]) == rb_cValues){
argc = RARRAY(argv[0])->len;
@@ -135,20 +135,20 @@
/* rb_call0 continued for yarv function */
VALUE yarv_call0(VALUE klass, VALUE recv, VALUE id, ID oid,
int argc, VALUE *argv, NODE *body, int nosuper){
- return th_call0(yarv_get_current_running_thread(), klass, recv, id, oid, argc, argv, body, nosuper);
+ return th_call0(GET_THREAD(), klass, recv, id, oid, argc, argv, body, nosuper);
}
-VALUE thread_call_super(VALUE self, int argc, const VALUE *argv);
+VALUE th_call_super(yarv_thread_t *th, int argc, const VALUE *argv);
VALUE yarv_call_super(int argc, const VALUE *argv){
- return th_call_super(yarv_get_current_running_thread(), argc, argv);
+ return th_call_super(GET_THREAD(), argc, argv);
}
VALUE thread_backtrace(VALUE th, int level);
VALUE yarv_backtrace(int level){
- return th_backtrace(yarv_get_current_running_thread(), level);
+ return th_backtrace(GET_THREAD(), level);
}
VALUE yarv_caller(VALUE self, VALUE level){
@@ -202,11 +202,11 @@
VALUE *th_svar(yarv_thread_t *self, int cnt);
VALUE *yarv_svar(int cnt){
- return th_svar(yarv_get_current_running_thread(), cnt);
+ return th_svar(GET_THREAD(), cnt);
}
static int yarv_iterate(NODE *node){
- yarv_thread_t *th = yarv_get_current_running_thread();
+ yarv_thread_t *th = GET_THREAD();
th->ifuncnode = node;
return 0;
}
@@ -366,7 +366,7 @@
iseq->klass_nest_stack = rb_ary_new();
}
- iseq->compile_data = ALLOC_N(struct iseq_compile_data, 1);
+ iseq->compile_data = ALLOC(struct iseq_compile_data);
MEMZERO(iseq->compile_data, struct iseq_compile_data, 1);
iseq->compile_data->mark_ary = rb_ary_new();
@@ -534,15 +534,9 @@
return obj;
}
-extern VALUE thread_set_top_stack(VALUE self, VALUE iseq);
-
-static VALUE thread_init(VALUE self, VALUE vmval){
- yarv_thread_t *th;
- yarv_vm_t *vm;
-
- GetThreadVal(self, th);
- GetVMVal(vmval, vm);
-
+static void
+th_init(yarv_thread_t *th)
+{
/* allocate thread stack */
th->stack = ALLOC_N(VALUE, YARV_THREAD_STACK_SIZE);
th->stack_size = YARV_THREAD_STACK_SIZE;
@@ -554,11 +548,22 @@
th->cfp->pc = 0;
th->cfp->sp = th->stack;
th->cfp->bp = 0;
- th->cfp->lfp = 0;
- th->cfp->dfp = 0;
+ th->cfp->lfp = th->stack;
+ th->cfp->dfp = th->stack;
th->cfp->self = Qnil;
th->cfp->magic = 0;
+}
+
+static VALUE
+thread_init(VALUE self, VALUE vmval)
+{
+ yarv_thread_t *th;
+ yarv_vm_t *vm;
+ GetThreadVal(self, th);
+ GetVMVal(vmval, vm);
+
+ th_init(th);
th->self = self;
th->vm_value = vmval;
@@ -568,6 +573,7 @@
}
VALUE th_eval_body(yarv_thread_t *th);
+extern VALUE thread_set_top_stack(VALUE self, VALUE iseq);
static VALUE thread_eval(VALUE self, VALUE iseq){
VALUE val;
@@ -657,7 +663,7 @@
yarv_proc_t *proc;
GetProcVal(procval, proc);
- return th_invoke_proc(yarv_get_current_running_thread(), proc, argc, argv);
+ return th_invoke_proc(GET_THREAD(), proc, argc, argv);
}
@@ -843,7 +849,27 @@
GetVMVal(vmval, vm);
GetThreadVal(vm->main_thread, th);
+ thread_free(GET_THREAD());
yarv_set_current_running_thread(th);
}
}
+static void
+test()
+{
+ int i; int *p;
+ printf("!test!\n");
+ for(i=0; i<1000000; i++){
+ p = ALLOC(int);
+ }
+}
+
+void
+Init_vm()
+{
+ /* initialize main thread */
+ yarv_thread_t *th = ALLOC(yarv_thread_t);
+ th_init(th);
+ yarv_set_current_running_thread(th);
+}
+
Modified: trunk/yarvcore.h
===================================================================
--- trunk/yarvcore.h 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/yarvcore.h 2005-08-15 00:55:30 UTC (rev 231)
@@ -389,6 +389,10 @@
#define DEFINED_CONST INT2FIX(4)
#define DEFINED_METHOD INT2FIX(5)
+/* for debug */
+extern void vm_stack_dump_raw(yarv_thread_t *, yarv_control_frame_t *);
+#define SDR() vm_stack_dump_raw(GET_THREAD(), GET_THREAD()->cfp)
+
#include "yarv.h"
#endif // _YARVCORE_H_INCLUDED_
Modified: trunk/yarvext/test.rb
===================================================================
--- trunk/yarvext/test.rb 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/yarvext/test.rb 2005-08-15 00:55:30 UTC (rev 231)
@@ -8,57 +8,19 @@
###########################################################
$prog =<<'__EOP__'
-def m a, b, &c
- c.call(a, b)
+def m
+ puts caller
end
-m(10, 20){|x, y|
- [x+y, x*y]
-}
+m
+
__END__
-module Enumerable
- def all_?
- self.each{|e|
- unless yield(e)
- return false
- end
- }
- true
- end
-end
-GC.start
-100000.times{|x|
- x.to_s
+p [1,2,3].map{|e|
+ e+1
}
-GC.start
-xxx = 0
-[1,2].each{|bi|
- [3,4].each{|bj|
- [true, nil, true].all_?{|be| be}
- break
- }
- xxx += 1
-}
-xxx
-__END__
-
-__END__
-
-
-def m
- /a/ =~ 'a'
-end
-m
-__END__
-def m
- /a(b)(c)d/ =~ 'xyzabcdefgabcdefg'
- [$1, $2, $3, $~.class, $&, $`, $', $+]
-end
-m
-
__EOP__
###########################################################
Modified: trunk/yarvtest/yarvtest.rb
===================================================================
--- trunk/yarvtest/yarvtest.rb 2005-08-14 16:03:58 UTC (rev 230)
+++ trunk/yarvtest/yarvtest.rb 2005-08-15 00:55:30 UTC (rev 231)
@@ -1,4 +1,6 @@
require 'test/unit'
+
+if defined? YARV_PATCHED
require 'yarvutil'
class YarvTestBase < Test::Unit::TestCase
@@ -33,3 +35,51 @@
end
+else
+
+class YarvTestBase < Test::Unit::TestCase
+ def initialize *args
+ super
+
+ @yarv = ARGV.each{|e| break $1 if /^yarv=(.+)/ =~ ARGV[0]} or raise
+ @ruby = ARGV.each{|e| break $1 if /^ruby=(.+)/ =~ ARGV[1]} or raise
+ end
+
+ def remove_const sym
+ Object.module_eval{
+ remove_const sym
+ }
+ end
+
+ def remove_method sym
+ Object.module_eval{
+ undef sym
+ }
+ end
+
+ def exec exec_file, program
+ r = nil
+ IO.popen("#{exec_file}", 'r+'){|io|
+ #
+ io.write program
+ io.close_write
+ r = io.read
+ }
+ r
+ end
+
+ def ae str
+ # puts str
+ # puts YARVUtil.parse(str, $0, 0).disasm
+
+ ruby = exec(@ruby, str)
+ yarv = exec(@yarv, str)
+
+ assert_equal(ruby, yarv)
+ end
+
+ def test_
+ end
+end
+
+end
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml