yarv-diff:7
From: ko1 atdot.net
Date: 4 Jun 2005 06:56:10 -0000
Subject: [yarv-diff:7] r162 - in trunk: . benchmark
Author: ko1
Date: 2005-06-04 15:56:09 +0900 (Sat, 04 Jun 2005)
New Revision: 162
Modified:
trunk/ChangeLog
trunk/benchmark/bmx_temp.rb
trunk/compile.c
trunk/test.rb
Log:
* compile.c : fix stack caching (after jump state)
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-06-04 00:12:20 UTC (rev 161)
+++ trunk/ChangeLog 2005-06-04 06:56:09 UTC (rev 162)
@@ -4,9 +4,14 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2005-06-04(Sat) 15:56:21 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * compile.c : fix stack caching (after jump state)
+
+
2005-06-04(Sat) 09:12:13 +0900 Koichi Sasada <ko1 atdot.net>
- * compile.c : fix some point
+ * compile.c : fix some point for previous commit
2005-06-04(Sat) 07:31:21 +0900 Koichi Sasada <ko1 atdot.net>
Modified: trunk/benchmark/bmx_temp.rb
===================================================================
--- trunk/benchmark/bmx_temp.rb 2005-06-04 00:12:20 UTC (rev 161)
+++ trunk/benchmark/bmx_temp.rb 2005-06-04 06:56:09 UTC (rev 162)
@@ -1,10 +1,199 @@
+#
+# RubiMaVM
+#
-i=0
-while i<1000000
- i+=1
- case :x
- when :x
- when :y
- when :z
+module RubiMaVM
+ class Instruction
+ def initialize code, opts
+ @code = code
+ @opts = opts
+ end
+ attr_reader :code, :opts
+
+ def inspect
+ "#{code} <#{opts.join ', '}>"
+ end
end
+
+ class Label
+ @@id = 0
+ def initialize label
+ @label = label
+ @pos = -1
+ @id = @@id+=1
+ end
+ attr_accessor :pos
+
+ def inspect
+ "#{@label} <#{@id}@#{@pos}>"
+ end
+ alias to_s inspect
+ end
+
+ class Evaluator
+ def initialize
+ @stack = []
+ @pc = 0
+ end
+
+ def evaluate sequence
+ while insn = sequence[@pc]
+ dispatch insn
+ end
+ @stack[0]
+ end
+
+ def dispatch insn
+ case insn.code
+ when :nop
+
+ when :push
+ push insn.opts[0]
+
+ when :pop
+ pop
+
+ when :dup
+ popped = pop
+ push popped
+ push popped
+
+ when :add
+ push pop + pop
+
+ when :sub
+ push pop - pop
+
+ when :mul
+ push pop * pop
+
+ when :div
+ push pop / pop
+
+ when :not
+ push !pop
+
+ when :smaller
+ push pop < pop
+
+ when :bigger
+ push pop > pop
+
+ when :getlocal
+ getlocal insn.opts[0]
+ when :goto
+ @pc = insn.opts[0].pos
+ return
+
+ when :if
+ if pop
+ @pc = insn.opts[0].pos
+ return
+ end
+
+ when :send
+ args = []
+ insn.opts[1].times{
+ args << pop
+ }
+ pop.__send__ *args
+
+ else
+ raise "Unknown Opcode: #{insn}"
+
+ end
+
+ @pc += 1
+ end
+
+ def push obj
+ @stack.push obj
+ end
+
+ def pop
+ @stack.pop
+ end
+ end
+
+ class Parser
+ def self.parse program
+ pc = 0
+ labels = {}
+ program.map{|line|
+ line = line.strip
+ insn = []
+
+ if /\A:\w+\z/ =~ line
+ label = $~[0].intern
+ unless lobj = labels[label]
+ lobj = ::RubiMaVM::Label.new label
+ labels[label] = lobj
+ end
+ next lobj
+ end
+
+ while line.size > 0
+ case line
+ when /\A:[a-z]+/
+ # label
+ label = $~[0].intern
+ unless lobj = labels[label]
+ lobj = ::RubiMaVM::Label.new label
+ labels[label] = lobj
+ end
+ insn << lobj
+
+ when /\A\s+/, /\A\#.*/
+ # ignore
+
+ when /\A[a-z]+/
+ insn << $~[0].intern
+
+ when /\A\d+/
+ insn << $~[0].to_i
+
+ else
+ raise "Parse Error: #{line}"
+
+ end
+ line = $~.post_match
+ end
+
+ insn.size > 0 ? insn : nil
+ }.compact.map{|insn|
+ if insn.kind_of? ::RubiMaVM::Label
+ insn.pos = pc
+ nil
+ else
+ pc += 1
+ ::RubiMaVM::Instruction.new insn[0], insn[1..-1]
+ end
+ }.compact
+ end
+ end
end
+
+
+if true || $0 == __FILE__
+ program = <<-EOP
+ #
+ push 1
+ :label
+ push 1
+ add
+ dup
+ push 100000
+ bigger
+ if :label
+ EOP
+
+ parsed_program = RubiMaVM::Parser.parse program
+ parsed_program.each_with_index{|insn, idx|
+ #puts "#{'%04d' % idx}\t#{insn.inspect}"
+ }
+
+ result = RubiMaVM::Evaluator.new.evaluate parsed_program
+# puts result
+end
+
+
Modified: trunk/compile.c
===================================================================
--- trunk/compile.c 2005-06-04 00:12:20 UTC (rev 161)
+++ trunk/compile.c 2005-06-04 06:56:09 UTC (rev 162)
@@ -816,6 +816,7 @@
else{
lobj->sc_state = nstate;
}
+ nstate = SCS_XX;
}
else if(insn_id == BIN(end)){
nstate = SCS_XX;
@@ -866,9 +867,8 @@
unsigned long size;
#ifdef OPT_STACK_CACHING
- size = RARRAY(ary)->len;
- seq = RARRAY(ary)->ptr;
-
+ size = RARRAY(ary)->len;
+ seq = RARRAY(ary)->ptr;
state = SCS_XX;
for(i=0; i<size; i++){
redo_point:
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-06-04 00:12:20 UTC (rev 161)
+++ trunk/test.rb 2005-06-04 06:56:09 UTC (rev 162)
@@ -9,110 +9,203 @@
###########################################################
$prog =<<'__EOP__'
+#
+# RubiMaVM
+#
-i=0
-while i<100000
- i+=1
- case 'xxx'
- when 'aaa'
- when 'bbb'
- when 'ccc'
- when 'ddd'
- when 'eee'
- when 'fff'
- when 'ggg'
- when 'hhh'
- when 'iii'
- when 'jjj'
- when 'kkk'
- when 'lll'
- when 'mmm'
- when 'nnn'
- else
+module RubiMaVM
+ class Instruction
+ def initialize code, opts
+ @code = code
+ @opts = opts
+ end
+ attr_reader :code, :opts
+
+ def inspect
+ "#{code} <#{opts.join ', '}>"
+ end
end
-end
-__END__
-case :z
-when :x
- p :x
-when /x/
- p :y
-when :z
- p :z
-else
- p :else
-end
+ class Label
+ @@id = 0
+ def initialize label
+ @label = label
+ @pos = -1
+ @id = @@id+=1
+ end
+ attr_accessor :pos
-__END__
-a = b = c = :b
+ def inspect
+ "#{@label} <#{@id}@#{@pos}>"
+ end
+ alias to_s inspect
+ end
+
+ class Evaluator
+ def initialize
+ @stack = []
+ @pc = 0
+ end
+
+ def evaluate sequence
+ while insn = sequence[@pc]
+ dispatch insn
+ end
+ @stack[0]
+ end
-case a
-when :a
- p :a
-when :b
- p :b
-else
- p :else
-end
+ def dispatch insn
+ case insn.code
+ when :nop
+
+ when :push
+ push insn.opts[0]
+
+ when :pop
+ pop
-case a
-when :a
- p :a
-when :b
- p :b
-end
+ when :dup
+ popped = pop
+ push popped
+ push popped
+
+ when :add
+ push pop + pop
+
+ when :sub
+ push pop - pop
+
+ when :mul
+ push pop * pop
+
+ when :div
+ push pop / pop
+
+ when :not
+ push !pop
+
+ when :smaller
+ push pop < pop
+
+ when :bigger
+ push pop > pop
+
+ when :getlocal
+ getlocal insn.opts[0]
+ when :goto
+ @pc = insn.opts[0].pos
+ return
+
+ when :if
+ if pop
+ @pc = insn.opts[0].pos
+ return
+ end
-__END__
-i = 0
-while i<3
- i+=1
- p i
-end
+ when :send
+ args = []
+ insn.opts[1].times{
+ args << pop
+ }
+ pop.__send__ *args
+ else
+ raise "Unknown Opcode: #{insn}"
-__END__
-def foo
- 3.timed do return
- end
-end
+ end
-foo
+ @pc += 1
+ end
-__END__
-def foo
- 3.times{|i|
- return
- }
+ def push obj
+ @stack.push obj
+ end
+
+ def pop
+ @stack.pop
+ end
+ end
+
+ class Parser
+ def self.parse program
+ pc = 0
+ labels = {}
+ program.map{|line|
+ line = line.strip
+ insn = []
+
+ if /\A:\w+\z/ =~ line
+ label = $~[0].intern
+ unless lobj = labels[label]
+ lobj = Label.new label
+ labels[label] = lobj
+ end
+ next lobj
+ end
+
+ while line.size > 0
+ case line
+ when /\A:[a-z]+/
+ # label
+ label = $~[0].intern
+ unless lobj = labels[label]
+ lobj = Label.new label
+ labels[label] = lobj
+ end
+ insn << lobj
+ when /\A\s+/, /\A\#.*/
+ # ignore
+ when /\A[a-z]+/
+ insn << $~[0].intern
+ when /\A\d+/
+ insn << $~[0].to_i
+ else
+ raise "Parse Error: #{line}"
+ end
+ line = $~.post_match
+ end
+
+ insn.size > 0 ? insn : nil
+ }.compact.map{|insn|
+ if insn.kind_of? Label
+ insn.pos = pc
+ nil
+ else
+ pc += 1
+ Instruction.new insn[0], insn[1..-1]
+ end
+ }.compact
+ end
+ end
end
-foo
-__END__
-p 'hello yasm'
+if $0 == __FILE__
+ program = <<-EOP
+ #
+ push 1
+ :label
+ push 1
+ add
+ dup
+ push 100#000
+ bigger
+ if :label
+ EOP
-def m1 a, b
- p [a, b]
-end
-
-m1 100, 200
-
-__END__
-def test(arg)
- case 1
- when 2
- 3
+ parsed_program = RubiMaVM::Parser.parse program
+ if false
+ parsed_program.each_with_index{|insn, idx|
+ puts "#{'%04d' % idx}\t#{insn.inspect}"
+ }
+
+ result = RubiMaVM::Evaluator.new.evaluate parsed_program
+ puts result
end
- return arg
end
-test(100)
-__END__
-a = {1 => 10}
-a[0] ||= 1
-
__EOP__
###########################################################
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml