mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
* vm.c (callee_setup_arg): added. support correct post arg.
* vm_macro.def (macro_eval_invoke_func): fix to use callee_setup_arg. * compile.c (set_arguments): adjust for above changes. * compile.c (iseq_compile_each): ditto. * iseq.c (ruby_iseq_disasm): ditto. * yarvcore.h: add rb_iseq_t#post_arg_start and arg_size. * bootstraptest/test_method.rb: add post arg tests. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@12594 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
a5c9bf7d63
commit
68e02f2c2c
7 changed files with 691 additions and 210 deletions
17
ChangeLog
17
ChangeLog
|
@ -1,3 +1,20 @@
|
|||
Sun Jun 24 16:05:45 2007 Koichi Sasada <ko1@atdot.net>
|
||||
|
||||
* vm.c (callee_setup_arg): added. support correct post arg.
|
||||
|
||||
* vm_macro.def (macro_eval_invoke_func): fix to use
|
||||
callee_setup_arg.
|
||||
|
||||
* compile.c (set_arguments): adjust for above changes.
|
||||
|
||||
* compile.c (iseq_compile_each): ditto.
|
||||
|
||||
* iseq.c (ruby_iseq_disasm): ditto.
|
||||
|
||||
* yarvcore.h: add rb_iseq_t#post_arg_start and arg_size.
|
||||
|
||||
* bootstraptest/test_method.rb: add post arg tests.
|
||||
|
||||
Sun Jun 24 16:10:43 2007 Nobuyoshi Nakada <nobu@ruby-lang.org>
|
||||
|
||||
* proc.c (proc_to_s): suppress warning, and reduced duplicated code.
|
||||
|
|
|
@ -1,11 +1,25 @@
|
|||
# regular argument
|
||||
assert_equal '1', 'def m() 1 end; m()'
|
||||
assert_equal '1', 'def m(a) a end; m(1)'
|
||||
assert_equal '1', 'def m(a,b) a end; m(1,7)'
|
||||
assert_equal '1', 'def m(a,b) b end; m(7,1)'
|
||||
assert_equal '1', 'def m(a,b,c) a end; m(1,7,7)'
|
||||
assert_equal '1', 'def m(a,b,c) b end; m(7,1,7)'
|
||||
assert_equal '1', 'def m(a,b,c) c end; m(7,7,1)'
|
||||
assert_equal '[1, 2]', 'def m(a,b) [a, b] end; m(1,2)'
|
||||
assert_equal '[1, 2, 3]', 'def m(a,b,c) [a, b, c] end; m(1,2,3)'
|
||||
assert_equal 'wrong number of arguments (1 for 0)', %q{
|
||||
def m; end
|
||||
begin
|
||||
m(1)
|
||||
rescue => e
|
||||
e.message
|
||||
end
|
||||
}
|
||||
|
||||
assert_equal 'wrong number of arguments (0 for 1)', %q{
|
||||
def m a; end
|
||||
begin
|
||||
m
|
||||
rescue => e
|
||||
e.message
|
||||
end
|
||||
}
|
||||
|
||||
# default argument
|
||||
assert_equal '1', 'def m(x=1) x end; m()'
|
||||
|
@ -303,3 +317,487 @@ assert_equal '1', %q( class C; def m() 7 end; private :m end
|
|||
begin C.new.send(:m); rescue NoMethodError; 1 end )
|
||||
assert_equal '1', %q( class C; def m() 1 end; private :m end
|
||||
C.new.funcall(:m) )
|
||||
|
||||
|
||||
# post test
|
||||
assert_equal %q{[1, 2, :o1, :o2, [], 3, 4, NilClass, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4)}
|
||||
|
||||
assert_equal %q{[1, 2, 3, :o2, [], 4, 5, NilClass, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5)}
|
||||
|
||||
assert_equal %q{[1, 2, 3, 4, [], 5, 6, NilClass, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5, 6)}
|
||||
|
||||
assert_equal %q{[1, 2, 3, 4, [5], 6, 7, NilClass, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5, 6, 7)}
|
||||
|
||||
assert_equal %q{[1, 2, 3, 4, [5, 6], 7, 8, NilClass, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5, 6, 7, 8)}
|
||||
|
||||
assert_equal %q{[1, 2, 3, 4, [5, 6, 7], 8, 9, NilClass, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5, 6, 7, 8, 9)}
|
||||
|
||||
assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8], 9, 10, NilClass, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)}
|
||||
|
||||
assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8, 9], 10, 11, NilClass, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11)}
|
||||
|
||||
assert_equal %q{[1, 2, :o1, :o2, [], 3, 4, Proc, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4){}}
|
||||
|
||||
assert_equal %q{[1, 2, 3, :o2, [], 4, 5, Proc, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5){}}
|
||||
|
||||
assert_equal %q{[1, 2, 3, 4, [], 5, 6, Proc, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5, 6){}}
|
||||
|
||||
assert_equal %q{[1, 2, 3, 4, [5], 6, 7, Proc, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5, 6, 7){}}
|
||||
|
||||
assert_equal %q{[1, 2, 3, 4, [5, 6], 7, 8, Proc, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5, 6, 7, 8){}}
|
||||
|
||||
assert_equal %q{[1, 2, 3, 4, [5, 6, 7], 8, 9, Proc, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5, 6, 7, 8, 9){}}
|
||||
|
||||
assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8], 9, 10, Proc, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10){}}
|
||||
|
||||
assert_equal %q{[1, 2, 3, 4, [5, 6, 7, 8, 9], 10, 11, Proc, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2, &b)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, b.class, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11){}}
|
||||
|
||||
assert_equal %q{[1, 2, :o1, :o2, [], 3, 4, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4)}
|
||||
|
||||
assert_equal %q{[1, 2, 3, :o2, [], 4, 5, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5)}
|
||||
|
||||
assert_equal %q{[1, 2, 3, 4, [], 5, 6, nil, nil]}, %q{
|
||||
def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2)
|
||||
x, y = :x, :y if $foo
|
||||
[m1, m2, o1, o2, r, p1, p2, x, y]
|
||||
end
|
||||
; m(1, 2, 3, 4, 5, 6)}
|
||||
|
||||
|
||||
#
|
||||
# super
|
||||
#
|
||||
=begin
|
||||
# below programs are generated by this program:
|
||||
|
||||
BASE = <<EOS__
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; <TEST>; super; end; end
|
||||
EOS__
|
||||
|
||||
tests = {
|
||||
%q{
|
||||
def m
|
||||
} => %q{
|
||||
C1.new.m
|
||||
},
|
||||
#
|
||||
%q{
|
||||
def m a
|
||||
} => %q{
|
||||
C1.new.m 1
|
||||
},
|
||||
%q{
|
||||
def m a
|
||||
a = :a
|
||||
} => %q{
|
||||
C1.new.m 1
|
||||
},
|
||||
#
|
||||
%q{
|
||||
def m a, o=:o
|
||||
} => %q{
|
||||
C1.new.m 1
|
||||
C1.new.m 1, 2
|
||||
},
|
||||
%q{
|
||||
def m a, o=:o
|
||||
a = :a
|
||||
} => %q{
|
||||
C1.new.m 1
|
||||
C1.new.m 1, 2
|
||||
},
|
||||
%q{
|
||||
def m a, o=:o
|
||||
o = :x
|
||||
} => %q{
|
||||
C1.new.m 1
|
||||
C1.new.m 1, 2
|
||||
},
|
||||
#
|
||||
%q{
|
||||
def m a, *r
|
||||
} => %q{
|
||||
C1.new.m 1
|
||||
C1.new.m 1, 2
|
||||
C1.new.m 1, 2, 3
|
||||
},
|
||||
%q{
|
||||
def m a, *r
|
||||
r = [:x, :y]
|
||||
} => %q{
|
||||
C1.new.m 1
|
||||
C1.new.m 1, 2
|
||||
C1.new.m 1, 2, 3
|
||||
},
|
||||
#
|
||||
%q{
|
||||
def m a, o=:o, *r
|
||||
} => %q{
|
||||
C1.new.m 1
|
||||
C1.new.m 1, 2
|
||||
C1.new.m 1, 2, 3
|
||||
C1.new.m 1, 2, 3, 4
|
||||
},
|
||||
#
|
||||
%q{
|
||||
def m a, o=:o, *r, &b
|
||||
} => %q{
|
||||
C1.new.m 1
|
||||
C1.new.m 1, 2
|
||||
C1.new.m 1, 2, 3
|
||||
C1.new.m 1, 2, 3, 4
|
||||
C1.new.m(1){}
|
||||
C1.new.m(1, 2){}
|
||||
C1.new.m(1, 2, 3){}
|
||||
C1.new.m(1, 2, 3, 4){}
|
||||
},
|
||||
#
|
||||
"def m(m1, m2, o1=:o1, o2=:o2, p1, p2)" =>
|
||||
%q{
|
||||
C1.new.m(1,2,3,4)
|
||||
C1.new.m(1,2,3,4,5)
|
||||
C1.new.m(1,2,3,4,5,6)
|
||||
},
|
||||
#
|
||||
"def m(m1, m2, *r, p1, p2)" =>
|
||||
%q{
|
||||
C1.new.m(1,2,3,4)
|
||||
C1.new.m(1,2,3,4,5)
|
||||
C1.new.m(1,2,3,4,5,6)
|
||||
C1.new.m(1,2,3,4,5,6,7)
|
||||
C1.new.m(1,2,3,4,5,6,7,8)
|
||||
},
|
||||
#
|
||||
"def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2)" =>
|
||||
%q{
|
||||
C1.new.m(1,2,3,4)
|
||||
C1.new.m(1,2,3,4,5)
|
||||
C1.new.m(1,2,3,4,5,6)
|
||||
C1.new.m(1,2,3,4,5,6,7)
|
||||
C1.new.m(1,2,3,4,5,6,7,8)
|
||||
C1.new.m(1,2,3,4,5,6,7,8,9)
|
||||
},
|
||||
|
||||
###
|
||||
}
|
||||
|
||||
|
||||
tests.each{|setup, methods| setup = setup.dup; setup.strip!
|
||||
setup = BASE.gsub(/<TEST>/){setup}
|
||||
methods.split(/\n/).each{|m| m = m.dup; m.strip!
|
||||
next if m.empty?
|
||||
expr = "#{setup}; #{m}"
|
||||
result = eval(expr)
|
||||
puts "assert_equal %q{#{result.inspect}}, %q{\n#{expr}}"
|
||||
puts
|
||||
}
|
||||
}
|
||||
|
||||
=end
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, :o1, :o2, 3, 4]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, p1, p2); super; end; end
|
||||
; C1.new.m(1,2,3,4)}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, :o2, 4, 5]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, p1, p2); super; end; end
|
||||
; C1.new.m(1,2,3,4,5)}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, p1, p2); super; end; end
|
||||
; C1.new.m(1,2,3,4,5,6)}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, :o]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o, *r; super; end; end
|
||||
; C1.new.m 1}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o, *r; super; end; end
|
||||
; C1.new.m 1, 2}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o, *r; super; end; end
|
||||
; C1.new.m 1, 2, 3}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o, *r; super; end; end
|
||||
; C1.new.m 1, 2, 3, 4}
|
||||
|
||||
assert_equal %q{[:C0_m, [:a]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a
|
||||
a = :a; super; end; end
|
||||
; C1.new.m 1}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
|
||||
; C1.new.m(1,2,3,4)}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, 4, 5]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
|
||||
; C1.new.m(1,2,3,4,5)}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
|
||||
; C1.new.m(1,2,3,4,5,6)}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
|
||||
; C1.new.m(1,2,3,4,5,6,7)}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7, 8]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m(m1, m2, *r, p1, p2); super; end; end
|
||||
; C1.new.m(1,2,3,4,5,6,7,8)}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, :o]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o, *r, &b; super; end; end
|
||||
; C1.new.m 1}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o, *r, &b; super; end; end
|
||||
; C1.new.m 1, 2}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o, *r, &b; super; end; end
|
||||
; C1.new.m 1, 2, 3}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o, *r, &b; super; end; end
|
||||
; C1.new.m 1, 2, 3, 4}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, :o]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o, *r, &b; super; end; end
|
||||
; C1.new.m(1){}}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o, *r, &b; super; end; end
|
||||
; C1.new.m(1, 2){}}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o, *r, &b; super; end; end
|
||||
; C1.new.m(1, 2, 3){}}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, 4]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o, *r, &b; super; end; end
|
||||
; C1.new.m(1, 2, 3, 4){}}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, :x]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o
|
||||
o = :x; super; end; end
|
||||
; C1.new.m 1}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, :x]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o
|
||||
o = :x; super; end; end
|
||||
; C1.new.m 1, 2}
|
||||
|
||||
assert_equal %q{[:C0_m, [:a, :o]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o
|
||||
a = :a; super; end; end
|
||||
; C1.new.m 1}
|
||||
|
||||
assert_equal %q{[:C0_m, [:a, 2]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o
|
||||
a = :a; super; end; end
|
||||
; C1.new.m 1, 2}
|
||||
|
||||
assert_equal %q{[:C0_m, [1]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a; super; end; end
|
||||
; C1.new.m 1}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, :x, :y]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, *r
|
||||
r = [:x, :y]; super; end; end
|
||||
; C1.new.m 1}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, :x, :y]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, *r
|
||||
r = [:x, :y]; super; end; end
|
||||
; C1.new.m 1, 2}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, :x, :y]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, *r
|
||||
r = [:x, :y]; super; end; end
|
||||
; C1.new.m 1, 2, 3}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, :o1, :o2, 3, 4]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
|
||||
; C1.new.m(1,2,3,4)}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, :o2, 4, 5]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
|
||||
; C1.new.m(1,2,3,4,5)}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
|
||||
; C1.new.m(1,2,3,4,5,6)}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
|
||||
; C1.new.m(1,2,3,4,5,6,7)}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7, 8]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
|
||||
; C1.new.m(1,2,3,4,5,6,7,8)}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3, 4, 5, 6, 7, 8, 9]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m(m1, m2, o1=:o1, o2=:o2, *r, p1, p2); super; end; end
|
||||
; C1.new.m(1,2,3,4,5,6,7,8,9)}
|
||||
|
||||
assert_equal %q{[:C0_m, [1]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, *r; super; end; end
|
||||
; C1.new.m 1}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, *r; super; end; end
|
||||
; C1.new.m 1, 2}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2, 3]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, *r; super; end; end
|
||||
; C1.new.m 1, 2, 3}
|
||||
|
||||
assert_equal %q{[:C0_m, []]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m; super; end; end
|
||||
; C1.new.m}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, :o]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o; super; end; end
|
||||
; C1.new.m 1}
|
||||
|
||||
assert_equal %q{[:C0_m, [1, 2]]}, %q{
|
||||
class C0; def m *args; [:C0_m, args]; end; end
|
||||
class C1 < C0; def m a, o=:o; super; end; end
|
||||
; C1.new.m 1, 2}
|
||||
|
||||
|
||||
|
||||
|
|
148
compile.c
148
compile.c
|
@ -783,8 +783,6 @@ set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
|
|||
NODE *node_opt = node_args->nd_opt;
|
||||
ID rest_id = 0;
|
||||
ID block_id = 0;
|
||||
ID post_start_id = 0;
|
||||
int post_len = 0;
|
||||
NODE *node_init = 0;
|
||||
int d = iseq->local_size - iseq->local_table_size;
|
||||
|
||||
|
@ -813,8 +811,9 @@ set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
|
|||
node_aux = node_aux->nd_next;
|
||||
|
||||
if (node_aux) {
|
||||
post_start_id = node_aux->nd_pid;
|
||||
post_len = node_aux->nd_plen;
|
||||
ID post_start_id = node_aux->nd_pid;
|
||||
iseq->arg_post_start = get_dyna_var_idx_at_raw(iseq, post_start_id);
|
||||
iseq->arg_post_len = node_aux->nd_plen;
|
||||
node_init = node_aux->nd_next;
|
||||
}
|
||||
}
|
||||
|
@ -861,99 +860,45 @@ set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *optargs, NODE *node_args)
|
|||
}
|
||||
|
||||
if (rest_id) {
|
||||
iseq->arg_rest = get_dyna_var_idx_at_raw(iseq, rest_id) + d;
|
||||
iseq->arg_rest = get_dyna_var_idx_at_raw(iseq, rest_id);
|
||||
|
||||
if (iseq->arg_rest == -1) {
|
||||
rb_bug("arg_rest: -1");
|
||||
}
|
||||
|
||||
if (post_len) {
|
||||
/*
|
||||
* if rest.length < post_len
|
||||
* raise ArgumentError
|
||||
* end
|
||||
* post1 = rest.shift
|
||||
* post2 = rest.shift
|
||||
* ...
|
||||
*
|
||||
* #=> yarv insns
|
||||
* push rest
|
||||
* call :length
|
||||
* put 1
|
||||
* call :<
|
||||
* branchunless :success
|
||||
* put ArgumentsError
|
||||
* put "wrong number of arugments (%d of %d)"
|
||||
* call :new, 1
|
||||
* call :raise
|
||||
* success:
|
||||
* push rest
|
||||
* call :shift
|
||||
* set post1
|
||||
* push rest
|
||||
* call :shift
|
||||
* set post2
|
||||
* ...
|
||||
*/
|
||||
LABEL *lsuccess = NEW_LABEL(nd_line(node_args));
|
||||
int i;
|
||||
|
||||
#define GET_LOCAL(idx) do { \
|
||||
if (iseq->type == ISEQ_TYPE_METHOD) { \
|
||||
ADD_INSN1(optargs, nd_line(node_args), getlocal, INT2FIX(iseq->local_size - (idx) + 1)); \
|
||||
} \
|
||||
else { \
|
||||
ADD_INSN2(optargs, nd_line(node_args), getdynamic, INT2FIX(iseq->local_size - (idx)), INT2FIX(0)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define SET_LOCAL(idx) do { \
|
||||
if (iseq->type == ISEQ_TYPE_METHOD) { \
|
||||
ADD_INSN1(optargs, nd_line(node_args), setlocal, INT2FIX(iseq->local_size - (idx) + 1)); \
|
||||
} \
|
||||
else { \
|
||||
ADD_INSN2(optargs, nd_line(node_args), setdynamic, INT2FIX(iseq->local_size - (idx)), INT2FIX(0)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
GET_LOCAL(iseq->arg_rest);
|
||||
ADD_SEND (optargs, nd_line(node_args), ID2SYM(idLength), INT2FIX(0));
|
||||
ADD_INSN1(optargs, nd_line(node_args), putobject, INT2FIX(1));
|
||||
ADD_SEND (optargs, nd_line(node_args), ID2SYM(idLT), INT2FIX(1));
|
||||
ADD_INSNL(optargs, nd_line(node_args), branchunless, lsuccess);
|
||||
ADD_CALL_RECEIVER(optargs, nd_line(node_args));
|
||||
|
||||
/* error */
|
||||
ADD_INSN1(optargs, nd_line(node_args), putobject, rb_eArgError);
|
||||
ADD_INSN1(optargs, nd_line(node_args), putstring, rb_str_new2("wrong number of arguments"));
|
||||
ADD_SEND (optargs, nd_line(node_args), ID2SYM(rb_intern("new")), INT2FIX(1));
|
||||
ADD_CALL (optargs, nd_line(node_args), ID2SYM(rb_intern("raise")), INT2FIX(1));
|
||||
ADD_INSN (optargs, nd_line(node_args), pop); /* dummy */
|
||||
|
||||
ADD_LABEL(optargs, lsuccess);
|
||||
|
||||
for (i=0; i<post_len; i++) {
|
||||
GET_LOCAL(iseq->arg_rest);
|
||||
ADD_SEND (optargs, nd_line(node_args), ID2SYM(rb_intern("pop")),
|
||||
INT2FIX(0));
|
||||
SET_LOCAL(iseq->arg_rest + i + 1);
|
||||
if (iseq->arg_post_start == 0) {
|
||||
iseq->arg_post_start = iseq->arg_rest + 1;
|
||||
}
|
||||
|
||||
iseq->arg_post_len = post_len;
|
||||
}
|
||||
#undef GET_LOCAL
|
||||
#undef SET_LOCAL
|
||||
}
|
||||
|
||||
if (block_id) {
|
||||
iseq->arg_block = get_dyna_var_idx_at_raw(iseq, block_id) + d;
|
||||
iseq->arg_block = get_dyna_var_idx_at_raw(iseq, block_id);
|
||||
}
|
||||
|
||||
if (iseq->arg_opts != 0 || iseq->arg_rest != -1 || iseq->arg_block != -1) {
|
||||
if (iseq->arg_opts != 0 || iseq->arg_post_len != 0 ||
|
||||
iseq->arg_rest != -1 || iseq->arg_block != -1) {
|
||||
iseq->arg_simple = 0;
|
||||
|
||||
/* set arg_size: size of arguments */
|
||||
if (iseq->arg_block != -1) {
|
||||
iseq->arg_size = iseq->arg_block + 1;
|
||||
}
|
||||
else if (iseq->arg_post_len) {
|
||||
iseq->arg_size = iseq->arg_post_start + iseq->arg_post_len;
|
||||
}
|
||||
else if (iseq->arg_rest != -1) {
|
||||
iseq->arg_size = iseq->arg_rest + 1;
|
||||
}
|
||||
else if (iseq->arg_opts) {
|
||||
iseq->arg_size = iseq->argc + iseq->arg_opts - 1;
|
||||
}
|
||||
else {
|
||||
iseq->arg_size = iseq->argc;
|
||||
}
|
||||
}
|
||||
else {
|
||||
iseq->arg_simple = 1;
|
||||
iseq->arg_size = iseq->argc;
|
||||
}
|
||||
}
|
||||
return COMPILE_OK;
|
||||
|
@ -3632,29 +3577,46 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE * node, int poped)
|
|||
int j;
|
||||
for (j = 0; j < liseq->arg_opts - 1; j++) {
|
||||
int idx = liseq->local_size - (i + j);
|
||||
ADD_INSN1(args, nd_line(node), getlocal,
|
||||
INT2FIX(idx));
|
||||
ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
|
||||
}
|
||||
i += j;
|
||||
argc = INT2FIX(i);
|
||||
}
|
||||
|
||||
if (liseq->arg_rest) {
|
||||
/* rest arguments */
|
||||
if (liseq->arg_rest != -1) {
|
||||
/* rest argument */
|
||||
int idx = liseq->local_size - liseq->arg_rest;
|
||||
ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
|
||||
argc = INT2FIX(liseq->arg_rest + 1);
|
||||
flag |= VM_CALL_ARGS_SPLAT_BIT;
|
||||
}
|
||||
|
||||
if (liseq->arg_rest == -1) {
|
||||
/* TODO */
|
||||
if (liseq->arg_post_len) {
|
||||
/* post arguments */
|
||||
int post_len = liseq->arg_post_len;
|
||||
int post_start = liseq->arg_post_start;
|
||||
|
||||
if (liseq->arg_rest != -1) {
|
||||
int j;
|
||||
for (j=0; j<post_len; j++) {
|
||||
int idx = liseq->local_size - (post_start + j);
|
||||
ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
|
||||
}
|
||||
ADD_INSN1(args, nd_line(node), newarray, INT2FIX(j));
|
||||
ADD_INSN (args, nd_line(node), concatarray);
|
||||
/* argc is setteled at above */
|
||||
}
|
||||
else {
|
||||
int idx = liseq->local_size - liseq->arg_rest + 1;
|
||||
ADD_INSN1(args, nd_line(node), getlocal,
|
||||
INT2FIX(idx));
|
||||
argc = INT2FIX(liseq->arg_rest);
|
||||
flag |= VM_CALL_ARGS_SPLAT_BIT;
|
||||
int j;
|
||||
for (j=0; j<post_len; j++) {
|
||||
int idx = liseq->local_size - (post_start + j);
|
||||
ADD_INSN1(args, nd_line(node), getlocal, INT2FIX(idx));
|
||||
}
|
||||
argc = INT2FIX(post_len + post_start);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* dummy reciever */
|
||||
ADD_INSN1(ret, nd_line(node), putobject,
|
||||
|
|
8
iseq.c
8
iseq.c
|
@ -782,11 +782,13 @@ ruby_iseq_disasm(VALUE self)
|
|||
}
|
||||
}
|
||||
|
||||
snprintf(argi, sizeof(argi), "%s%s%s%s", /* arg, opts, rest, block */
|
||||
snprintf(argi, sizeof(argi), "%s%s%s%s%s", /* arg, opts, rest, post block */
|
||||
iseqdat->argc > i ? "Arg" : "",
|
||||
opti,
|
||||
iseqdat->arg_rest - d == i ? "Rest" : "",
|
||||
iseqdat->arg_block - d == i ? "Block" : "");
|
||||
iseqdat->arg_rest == i ? "Rest" : "",
|
||||
(iseqdat->arg_post_start <= i &&
|
||||
i < iseqdat->arg_post_start + iseqdat->arg_post_len) ? "Post" : "",
|
||||
iseqdat->arg_block == i ? "Block" : "");
|
||||
|
||||
snprintf(info, sizeof(info), "%s%s%s%s", name ? name : "?",
|
||||
*argi ? "<" : "", argi, *argi ? ">" : "");
|
||||
|
|
97
vm.c
97
vm.c
|
@ -184,6 +184,103 @@ th_set_eval_stack(rb_thread_t *th, VALUE iseqval)
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* return opt_pc */
|
||||
static inline int
|
||||
callee_setup_arg(rb_thread_t *th, rb_iseq_t *iseq,
|
||||
int argc, VALUE *argv, rb_block_t **block)
|
||||
{
|
||||
const int m = iseq->argc;
|
||||
const int orig_argc = argc;
|
||||
|
||||
if (iseq->arg_simple) {
|
||||
/* simple check */
|
||||
if (argc != m) {
|
||||
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
|
||||
argc, m);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
VALUE * const dst = argv;
|
||||
int opt_pc = 0;
|
||||
|
||||
/* mandatory */
|
||||
if (argc < (m + iseq->arg_post_len)) { /* check with post arg */
|
||||
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)",
|
||||
argc, m + iseq->arg_post_len);
|
||||
}
|
||||
|
||||
argv += m;
|
||||
argc -= m;
|
||||
|
||||
/* post arguments */
|
||||
if (iseq->arg_post_len) {
|
||||
int i;
|
||||
|
||||
if (!(orig_argc < iseq->arg_post_start)) {
|
||||
VALUE *new_argv = ALLOCA_N(VALUE, argc);
|
||||
MEMCPY(new_argv, argv, VALUE, argc);
|
||||
argv = new_argv;
|
||||
}
|
||||
|
||||
for (i=0; i<iseq->arg_post_len; i++) {
|
||||
dst[iseq->arg_post_start + iseq->arg_post_len - (i + 1)] = argv[argc - 1];
|
||||
argc = argc - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* opt arguments */
|
||||
if (iseq->arg_opts) {
|
||||
const int opts = iseq->arg_opts - 1 /* no opt */;
|
||||
|
||||
if (iseq->arg_rest == -1 && argc > opts) {
|
||||
rb_raise(rb_eArgError, "wrong number of arguments (%d for %d)", orig_argc, m + opts);
|
||||
}
|
||||
|
||||
if (argc > opts) {
|
||||
argc -= opts;
|
||||
argv += opts;
|
||||
opt_pc = iseq->arg_opt_tbl[opts]; /* no opt */
|
||||
}
|
||||
else {
|
||||
opt_pc = iseq->arg_opt_tbl[argc];
|
||||
argc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* rest arguments */
|
||||
if (iseq->arg_rest != -1) {
|
||||
dst[iseq->arg_rest] = rb_ary_new4(argc, argv);
|
||||
}
|
||||
|
||||
/* block arguments */
|
||||
if (iseq->arg_block != -1) {
|
||||
VALUE blockval = Qnil;
|
||||
rb_block_t * const blockptr = *block;
|
||||
|
||||
if (blockptr) {
|
||||
/* make Proc object */
|
||||
if (blockptr->proc == 0) {
|
||||
rb_proc_t *proc;
|
||||
|
||||
th->mark_stack_len = orig_argc; /* for GC */
|
||||
blockval = th_make_proc(th, th->cfp, blockptr);
|
||||
th->mark_stack_len = 0;
|
||||
|
||||
GetProcPtr(blockval, proc);
|
||||
*block = &proc->block;
|
||||
}
|
||||
else {
|
||||
blockval = blockptr->proc;
|
||||
}
|
||||
}
|
||||
|
||||
dst[iseq->arg_block] = blockval; /* Proc or nil */
|
||||
}
|
||||
|
||||
return opt_pc;
|
||||
}
|
||||
}
|
||||
|
||||
/* Env */
|
||||
|
||||
|
|
120
vm_macro.def
120
vm_macro.def
|
@ -2,7 +2,6 @@
|
|||
/* do not use C++ style comment */
|
||||
/* */
|
||||
|
||||
|
||||
MACRO macro_eval_setup_send_arguments(num, blockptr, flag, blockiseq)
|
||||
{
|
||||
if (flag & VM_CALL_ARGS_BLOCKARG_BIT) {
|
||||
|
@ -83,115 +82,15 @@ MACRO macro_eval_invoke_cfunc(num, id, recv, klass, mn, blockptr)
|
|||
MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
|
||||
{
|
||||
rb_iseq_t *niseq;
|
||||
VALUE *sp = GET_SP();
|
||||
VALUE *rsp = sp - num - 1;
|
||||
int opt_pc = 0, clear_local_size, i;
|
||||
int opt_pc, i;
|
||||
VALUE *rsp = GET_SP() - num;
|
||||
VALUE *sp;
|
||||
|
||||
/* TODO: eliminate it */
|
||||
GetISeqPtr(niseqval, niseq);
|
||||
|
||||
clear_local_size = niseq->local_size - num;
|
||||
|
||||
/* simple (only mandatory) arguments */
|
||||
if (niseq->arg_simple) {
|
||||
if (niseq->argc != num) {
|
||||
rb_raise(rb_eArgError, "%d - wrong number of arguments (%lu for %d)",
|
||||
0, (unsigned long)num, niseq->argc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* optional arguments */
|
||||
if (niseq->arg_opts) {
|
||||
int iseq_argc = niseq->argc;
|
||||
int opts = niseq->arg_opts - 1;
|
||||
|
||||
if (num < iseq_argc ||
|
||||
(niseq->arg_rest == -1 && num > iseq_argc + opts)) {
|
||||
if (0) {
|
||||
printf("num: %lu, iseq_argc: %d, opts: %d\n",
|
||||
(unsigned long)num, iseq_argc, opts);
|
||||
}
|
||||
rb_raise(rb_eArgError,
|
||||
"%d - wrong number of arguments (%lu for %d)",
|
||||
1, (unsigned long)num, iseq_argc);
|
||||
}
|
||||
|
||||
if (0) printf("num: %lu, opts: %d, iseq_argc: %d\n",
|
||||
(unsigned long)num, opts, iseq_argc);
|
||||
|
||||
if (num - iseq_argc < opts) {
|
||||
opt_pc = niseq->arg_opt_tbl[num - iseq_argc];
|
||||
sp += opts - (num - iseq_argc);
|
||||
num += opts - (num - iseq_argc);
|
||||
clear_local_size = niseq->local_size - (iseq_argc + opts);
|
||||
}
|
||||
else {
|
||||
opt_pc = niseq->arg_opt_tbl[opts];
|
||||
}
|
||||
}
|
||||
|
||||
/* rest argument */
|
||||
if (niseq->arg_rest != -1) {
|
||||
int rest = niseq->arg_rest - 1 /* spec val */;
|
||||
int pack_size = num - rest;
|
||||
|
||||
if (0) {
|
||||
printf("num: %lu, rest: %d, ps: %d\n",
|
||||
(unsigned long)num, rest, pack_size);
|
||||
}
|
||||
|
||||
if (pack_size < 0) {
|
||||
rb_raise(rb_eArgError,
|
||||
"%d - wrong number of arguments (%lu for %d)",
|
||||
2, (unsigned long)num, rest - niseq->arg_opts);
|
||||
}
|
||||
|
||||
/*
|
||||
* def m(x, y, z, *a) (rest: 3) =>
|
||||
* x, y, z, a, b, c <SP> (num: 6, pack_size = 3)
|
||||
* => x, y, z, [a,b,c] <SP> (num: 4)
|
||||
*/
|
||||
rsp[rest + 1] = rb_ary_new4(pack_size, &rsp[rest + 1]);
|
||||
sp = &rsp[rest + 1 + 1];
|
||||
num = rest + 1;
|
||||
clear_local_size = niseq->local_size - (rest + 1);
|
||||
}
|
||||
|
||||
/* block argument */
|
||||
if (niseq->arg_block != -1) {
|
||||
VALUE arg_block_val = Qnil;
|
||||
|
||||
if (!((num == niseq->arg_rest) ||
|
||||
(niseq->arg_opts && num == niseq->argc + niseq->arg_opts - 1)
|
||||
|| num == niseq->argc)) {
|
||||
|
||||
if (0) printf("num: %d, rest: %d, opts: %d, argc: %d\n",
|
||||
num, niseq->arg_rest, niseq->arg_opts, niseq->argc);
|
||||
|
||||
rb_raise(rb_eArgError,
|
||||
"%d - wrong number of arguments (%lu for %d)",
|
||||
3, (unsigned long)num, niseq->argc);
|
||||
}
|
||||
|
||||
if (blockptr) {
|
||||
/* make Proc object */
|
||||
if (blockptr->proc == 0) {
|
||||
rb_proc_t *proc;
|
||||
reg_cfp->sp = sp;
|
||||
arg_block_val = th_make_proc(th, GET_CFP(), blockptr);
|
||||
GetProcPtr(arg_block_val, proc);
|
||||
blockptr = &proc->block;
|
||||
}
|
||||
else {
|
||||
arg_block_val = blockptr->proc;
|
||||
}
|
||||
}
|
||||
|
||||
rsp[1 + niseq->arg_block - 1] = arg_block_val;
|
||||
sp++;
|
||||
clear_local_size--;
|
||||
}
|
||||
}
|
||||
opt_pc = callee_setup_arg(th, niseq, num, rsp, &blockptr);
|
||||
sp = rsp + niseq->arg_size;
|
||||
|
||||
/* stack overflow check */
|
||||
if (CHECK_STACK_OVERFLOW(th, GET_CFP(), niseq->stack_max + 0x100)) {
|
||||
|
@ -210,7 +109,7 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
|
|||
|
||||
sp -= rsp - p_rsp;
|
||||
|
||||
for (i = 0; i < clear_local_size; i++) {
|
||||
for (i = 0; i < niseq->local_size - niseq->arg_size; i++) {
|
||||
*sp++ = Qnil;
|
||||
}
|
||||
|
||||
|
@ -219,7 +118,10 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
|
|||
niseq->iseq_encoded + opt_pc, sp, 0, 0);
|
||||
}
|
||||
else {
|
||||
for (i = 0; i < clear_local_size; i++) {
|
||||
if (0) printf("local_size: %d, arg_size: %d\n",
|
||||
niseq->local_size, niseq->arg_size);
|
||||
|
||||
for (i = 0; i < niseq->local_size - niseq->arg_size; i++) {
|
||||
*sp++ = Qnil;
|
||||
}
|
||||
|
||||
|
@ -227,7 +129,7 @@ MACRO macro_eval_invoke_func(niseqval, recv, klass, blockptr, num)
|
|||
FRAME_MAGIC_METHOD, recv, (VALUE) blockptr,
|
||||
niseq->iseq_encoded + opt_pc, sp, 0, 0);
|
||||
|
||||
reg_cfp->sp = rsp;
|
||||
reg_cfp->sp = rsp - 1 /* recv */;
|
||||
}
|
||||
|
||||
RESTORE_REGS();
|
||||
|
|
|
@ -277,6 +277,9 @@ struct rb_iseq_struct {
|
|||
int arg_block;
|
||||
int arg_opts;
|
||||
int arg_post_len;
|
||||
int arg_post_start;
|
||||
int arg_size;
|
||||
|
||||
VALUE *arg_opt_tbl;
|
||||
|
||||
/* for stack overflow check */
|
||||
|
|
Loading…
Reference in a new issue