mirror of
				https://github.com/ruby/ruby.git
				synced 2022-11-09 12:17:21 -05:00 
			
		
		
		
	on test message. "torexp" insn does not exist. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@58926 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
		
			
				
	
	
		
			389 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			389 lines
		
	
	
	
		
			12 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
# C0 coverage of each instructions
 | 
						|
 | 
						|
# :NOTE: This is for development purpose; never consider this file as
 | 
						|
# ISeq compilation specification.
 | 
						|
 | 
						|
begin
 | 
						|
  # This library brings some additional coverage.
 | 
						|
  # Not mandatory.
 | 
						|
  require 'rbconfig/sizeof'
 | 
						|
rescue LoadError
 | 
						|
  # OK, just skip
 | 
						|
else
 | 
						|
  $FIXNUM_MAX = RbConfig::LIMITS["FIXNUM_MAX"]
 | 
						|
  $FIXNUM_MIN = RbConfig::LIMITS["FIXNUM_MIN"]
 | 
						|
end
 | 
						|
 | 
						|
fsl   = { frozen_string_literal: true } # used later
 | 
						|
tests = [
 | 
						|
  # insn ,   expression to generate such insn
 | 
						|
  [ 'nop',   %q{ raise rescue true }, ],
 | 
						|
  [ 'trace', %q{ true }, ],
 | 
						|
 | 
						|
  [ 'setlocal *, 0', %q{ x = true }, ],
 | 
						|
  [ 'setlocal *, 1', %q{ x = nil; -> { x = true }.call }, ],
 | 
						|
  [ 'setlocal',      %q{ x = nil; -> { -> { x = true }.() }.() }, ],
 | 
						|
  [ 'getlocal *, 0', %q{ x = true; x }, ],
 | 
						|
  [ 'getlocal *, 1', %q{ x = true; -> { x }.call }, ],
 | 
						|
  [ 'getlocal',      %q{ x = true; -> { -> { x }.() }.() }, ],
 | 
						|
 | 
						|
  [ 'setspecial', %q{ true if true..true }, ],
 | 
						|
  [ 'getspecial', %q{ $&.nil? }, ],
 | 
						|
  [ 'getspecial', %q{ $`.nil? }, ],
 | 
						|
  [ 'getspecial', %q{ $'.nil? }, ],
 | 
						|
  [ 'getspecial', %q{ $+.nil? }, ],
 | 
						|
  [ 'getspecial', %q{ $1.nil? }, ],
 | 
						|
  [ 'getspecial', %q{ $128.nil? }, ],
 | 
						|
 | 
						|
  [ 'getglobal', %q{ String === $0 }, ],
 | 
						|
  [ 'getglobal', %q{ $_.nil? }, ],
 | 
						|
  [ 'setglobal', %q{ $0 = "true" }, ],
 | 
						|
 | 
						|
  [ 'setinstancevariable', %q{ @x = true }, ],
 | 
						|
  [ 'getinstancevariable', %q{ @x = true; @x }, ],
 | 
						|
 | 
						|
  [ 'setclassvariable', %q{ @@x = true }, ],
 | 
						|
  [ 'getclassvariable', %q{ @@x = true; @@x }, ],
 | 
						|
 | 
						|
  [ 'setconstant', %q{ X = true }, ],
 | 
						|
  [ 'setconstant', %q{ Object::X = true }, ],
 | 
						|
  [ 'getconstant', %q{ X = true; X }, ],
 | 
						|
  [ 'getconstant', %q{ X = true; Object::X }, ],
 | 
						|
 | 
						|
  [ 'getinlinecache / setinlinecache', %q{ def x; X; end; X = true; x; x; x }, ],
 | 
						|
 | 
						|
  [ 'putnil',               %q{ $~ == nil }, ],
 | 
						|
  [ 'putself',              %q{ $~ != self }, ],
 | 
						|
  [ 'putobject INT2FIX(0)', %q{ $~ != 0 }, ],
 | 
						|
  [ 'putobject INT2FIX(1)', %q{ $~ != 1 }, ],
 | 
						|
  [ 'putobject',            %q{ $~ != -1 }, ],
 | 
						|
  [ 'putobject',            %q{ $~ != /x/ }, ],
 | 
						|
  [ 'putobject',            %q{ $~ != :x }, ],
 | 
						|
  [ 'putobject',            %q{ $~ != (1..2) }, ],
 | 
						|
  [ 'putobject',            %q{ $~ != true }, ],
 | 
						|
  [ 'putobject',            %q{ /(?<x>x)/ =~ "x"; x == "x" }, ],
 | 
						|
 | 
						|
  [ 'putspecialobject',         %q{ {//=>true}[//] }, ],
 | 
						|
  [ 'putiseq',                  %q{ -> { true }.() }, ],
 | 
						|
  [ 'putstring',                %q{ "true" }, ],
 | 
						|
  [ 'tostring / concatstrings', %q{ "#{true}" }, ],
 | 
						|
  [ 'freezestring',             %q{ "#{true}"}, fsl, ],
 | 
						|
  [ 'freezestring',             %q{ "#{true}"}, '-d', fsl, ],
 | 
						|
  [ 'toregexp',                 %q{ /#{true}/ =~ "true" && $~ }, ],
 | 
						|
 | 
						|
  [ 'newarray',    %q{ ["true"][0] }, ],
 | 
						|
  [ 'duparray',    %q{ [ true ][0] }, ],
 | 
						|
  [ 'expandarray', %q{ y = [ true, false, nil ]; x, = y; x }, ],
 | 
						|
  [ 'expandarray', %q{ y = [ true, false, nil ]; x, *z = y; x }, ],
 | 
						|
  [ 'expandarray', %q{ y = [ true, false, nil ]; x, *z, w = y; x }, ],
 | 
						|
  [ 'splatarray',  %q{ x, = *(y = true), false; x }, ],
 | 
						|
  [ 'concatarray', %q{ ["t", "r", *x = "u", "e"].join }, ],
 | 
						|
  [ 'concatarray', <<~'},', ],  # {
 | 
						|
    class X; def to_a; ['u']; end; end
 | 
						|
    ['t', 'r', *X.new, 'e'].join
 | 
						|
  },
 | 
						|
  [ 'concatarray', <<~'},', ],  # {
 | 
						|
    r = false
 | 
						|
    t = [true, nil]
 | 
						|
    q, w, e = r, *t             # here
 | 
						|
    w
 | 
						|
  },
 | 
						|
 | 
						|
  [ 'newhash',  %q{ x = {}; x[x] = true }, ],
 | 
						|
  [ 'newhash',  %q{ x = true; { x => x }[x] }, ],
 | 
						|
  [ 'newrange', %q{ x = 1; [*(0..x)][0] == 0 }, ],
 | 
						|
  [ 'newrange', %q{ x = 1; [*(0...x)][0] == 0 }, ],
 | 
						|
 | 
						|
  [ 'pop',     %q{ def x; true; end; x }, ],
 | 
						|
  [ 'dup',     %q{ x = y = true; x }, ],
 | 
						|
  [ 'dupn',    %q{ Object::X ||= true }, ],
 | 
						|
  [ 'dupn',    %q{ Object::X ||= true }, ],
 | 
						|
  [ 'reverse', %q{ q, (w, e), r = 1, [2, 3], 4; e == 3 }, ],
 | 
						|
  [ 'swap',    <<~'},', ],      # {
 | 
						|
    x = [[false, true]]
 | 
						|
    for i, j in x               # here
 | 
						|
      ;
 | 
						|
    end
 | 
						|
    j
 | 
						|
  },
 | 
						|
 | 
						|
  [ 'topn',        %q{ x, y = [], 0; x[*y], = [true, false]; x[0] }, ],
 | 
						|
  [ 'setn',        %q{ x, y = [], 0; x[*y]  =  true        ; x[0] }, ],
 | 
						|
  [ 'adjuststack', %q{ x = [true]; x[0] ||= nil; x[0] }, ],
 | 
						|
 | 
						|
  [ 'defined',      %q{ !defined?(x) }, ],
 | 
						|
  [ 'checkkeyword', %q{ def x x:rand;x end; x x: true }, ],
 | 
						|
  [ 'checkmatch',   <<~'},', ], # {
 | 
						|
    x = y = true
 | 
						|
    case x
 | 
						|
    when false
 | 
						|
      y = false
 | 
						|
    when true                   # here
 | 
						|
      y = nil
 | 
						|
    end
 | 
						|
    y == nil
 | 
						|
  },
 | 
						|
  [ 'checkmatch',   <<~'},', ], # {
 | 
						|
    x, y = true, [false]
 | 
						|
    case x
 | 
						|
    when *y                     # here
 | 
						|
      z = false
 | 
						|
    else
 | 
						|
      z = true
 | 
						|
    end
 | 
						|
    z
 | 
						|
  },
 | 
						|
  [ 'checkmatch',   <<~'},', ], # {
 | 
						|
    x = false
 | 
						|
    begin
 | 
						|
      raise
 | 
						|
    rescue                      # here
 | 
						|
      x = true
 | 
						|
    end
 | 
						|
    x
 | 
						|
  },
 | 
						|
 | 
						|
  [ 'defineclass', %q{                 module X;    true end }, ],
 | 
						|
  [ 'defineclass', %q{ X = Module.new; module X;    true end }, ],
 | 
						|
  [ 'defineclass', %q{                 class X;     true end }, ],
 | 
						|
  [ 'defineclass', %q{ X = Class.new;  class X;     true end }, ],
 | 
						|
  [ 'defineclass', %q{ X = Class.new;  class Y < X; true end }, ],
 | 
						|
  [ 'defineclass', %q{ X = Class.new;  class << X;  true end }, ],
 | 
						|
  [ 'defineclass', <<~'},', ], # {
 | 
						|
    X = Class.new
 | 
						|
    Y = Class.new(X)
 | 
						|
    class Y < X
 | 
						|
      true
 | 
						|
    end
 | 
						|
  },
 | 
						|
 | 
						|
  [ 'opt_send_without_block', %q{ true.to_s }, ],
 | 
						|
  [ 'send',                   %q{ true.tap {|i| i.to_s } }, ],
 | 
						|
  [ 'leave',                  %q{ def x; true; end; x }, ],
 | 
						|
  [ 'invokesuper',            <<~'},', ], # {
 | 
						|
    class X < String
 | 
						|
      def empty?
 | 
						|
        super                   # here
 | 
						|
      end
 | 
						|
    end
 | 
						|
   X.new.empty?
 | 
						|
  },
 | 
						|
  [ 'invokeblock',            <<~'},', ], # {
 | 
						|
    def x
 | 
						|
      return yield self         # here
 | 
						|
    end
 | 
						|
    x do
 | 
						|
      true
 | 
						|
    end
 | 
						|
  },
 | 
						|
 | 
						|
  [ 'opt_str_freeze', %q{ 'true'.freeze }, ],
 | 
						|
  [ 'opt_str_uminus', %q{ -'true' }, ],
 | 
						|
  [ 'opt_str_freeze', <<~'},', ], # {
 | 
						|
    class String
 | 
						|
      def freeze
 | 
						|
        true
 | 
						|
      end
 | 
						|
    end
 | 
						|
    'true'.freeze
 | 
						|
  },
 | 
						|
 | 
						|
  [ 'opt_newarray_max', %q{ [ ].max.nil? }, ],
 | 
						|
  [ 'opt_newarray_max', %q{ [1, x = 2, 3].max == 3 }, ],
 | 
						|
  [ 'opt_newarray_max', <<~'},', ], # {
 | 
						|
    class Array
 | 
						|
      def max
 | 
						|
        true
 | 
						|
      end
 | 
						|
    end
 | 
						|
    [1, x = 2, 3].max
 | 
						|
  },
 | 
						|
  [ 'opt_newarray_min', %q{ [ ].min.nil? }, ],
 | 
						|
  [ 'opt_newarray_min', %q{ [3, x = 2, 1].min == 1 }, ],
 | 
						|
  [ 'opt_newarray_min', <<~'},', ], # {
 | 
						|
    class Array
 | 
						|
      def min
 | 
						|
        true
 | 
						|
      end
 | 
						|
    end
 | 
						|
    [3, x = 2, 1].min
 | 
						|
  },
 | 
						|
 | 
						|
  [ 'throw',        %q{ false.tap { break true } }, ],
 | 
						|
  [ 'branchif',     %q{ x = nil;  x ||= true }, ],
 | 
						|
  [ 'branchif',     %q{ x = true; x ||= nil; x }, ],
 | 
						|
  [ 'branchunless', %q{ x = 1;    x &&= true }, ],
 | 
						|
  [ 'branchunless', %q{ x = nil;  x &&= true; x.nil? }, ],
 | 
						|
  [ 'branchnil',    %q{ x = true; x&.to_s }, ],
 | 
						|
  [ 'branchnil',    %q{ x = nil;  (x&.to_s).nil? }, ],
 | 
						|
  [ 'jump',         <<~'},', ], # {
 | 
						|
    y = 1
 | 
						|
    x = if y == 0 then nil elsif y == 1 then true else nil end
 | 
						|
    x
 | 
						|
  },
 | 
						|
  [ 'jump',         <<~'},', ], # {
 | 
						|
    # ultra complicated situation: this ||= assignment only generates
 | 
						|
    # 15 instructions, not including the class definition.
 | 
						|
    class X; attr_accessor :x; end
 | 
						|
    x = X.new
 | 
						|
    x&.x ||= true               # here
 | 
						|
  },
 | 
						|
 | 
						|
  [ 'once', %q{ /#{true}/o =~ "true" && $~ }, ],
 | 
						|
  [ 'once', <<~'},', ],         # {
 | 
						|
    def once expr
 | 
						|
      return /#{expr}/o         # here
 | 
						|
    end
 | 
						|
    x = once(true); x = once(false); x = once(nil);
 | 
						|
    x =~ "true" && $~
 | 
						|
  },
 | 
						|
  [ 'once', <<~'},', ],         # {
 | 
						|
    # recursive once
 | 
						|
    def once n
 | 
						|
      return %r/#{
 | 
						|
        if n == 0
 | 
						|
          true
 | 
						|
        else
 | 
						|
          once(n-1)             # here
 | 
						|
        end
 | 
						|
      }/ox
 | 
						|
    end
 | 
						|
    x = once(128); x = once(7); x = once(16);
 | 
						|
    x =~ "true" && $~
 | 
						|
  },
 | 
						|
  [ 'once', <<~'},', ],         # {
 | 
						|
    # inter-thread lockup situation
 | 
						|
    def once n
 | 
						|
      return Thread.start n do |m|
 | 
						|
        Thread.pass
 | 
						|
        next %r/#{
 | 
						|
          sleep m               # here
 | 
						|
          true
 | 
						|
        }/ox
 | 
						|
      end
 | 
						|
    end
 | 
						|
    x = once(1); y = once(0.1); z = y.value
 | 
						|
    z =~ "true" && $~
 | 
						|
  },
 | 
						|
 | 
						|
  [ 'opt_case_dispatch', %q{ case   0 when 1.1 then false else true end }, ],
 | 
						|
  [ 'opt_case_dispatch', %q{ case 1.0 when 1.1 then false else true end }, ],
 | 
						|
 | 
						|
  [ 'opt_plus',    %q{ 1 + 1 == 2 }, ],
 | 
						|
  if defined? $FIXNUM_MAX then
 | 
						|
    [ 'opt_plus',  %Q{ #{ $FIXNUM_MAX } + 1 == #{ $FIXNUM_MAX + 1 } }, ]
 | 
						|
  end,
 | 
						|
  [ 'opt_plus',    %q{ 1.0 + 1.0 == 2.0 }, ],
 | 
						|
  [ 'opt_plus',    %q{ x = +0.0.next_float; x + x >= x }, ],
 | 
						|
  [ 'opt_plus',    %q{ 't' + 'rue' }, ],
 | 
						|
  [ 'opt_plus',    %q{ ( ['t'] + ['r', ['u', ['e'], ], ] ).join }, ],
 | 
						|
  [ 'opt_plus',    %q{ Time.at(1) + 1 == Time.at(2) }, ],
 | 
						|
  [ 'opt_minus',   %q{ 1 - 1 == 0 }, ],
 | 
						|
  if defined? $FIXNUM_MIN then
 | 
						|
    [ 'opt_minus', %Q{ #{ $FIXNUM_MIN } - 1 == #{ $FIXNUM_MIN - 1 } }, ]
 | 
						|
  end,
 | 
						|
  [ 'opt_minus',   %q{ 1.0 - 1.0 == 0.0 }, ],
 | 
						|
  [ 'opt_minus',   %q{ x = -0.0.prev_float; x - x == 0.0 }, ],
 | 
						|
  [ 'opt_minus',   %q{ ( [false, true] - [false] )[0] }, ],
 | 
						|
  [ 'opt_mult',    %q{ 1 * 1 == 1 }, ],
 | 
						|
  [ 'opt_mult',    %q{ 1.0 * 1.0 == 1.0 }, ],
 | 
						|
  [ 'opt_mult',    %q{ x = +0.0.next_float; x * x <= x }, ],
 | 
						|
  [ 'opt_mult',    %q{ ( "ruet" * 3 )[7,4] }, ],
 | 
						|
  [ 'opt_div',     %q{ 1 / 1 == 1 }, ],
 | 
						|
  [ 'opt_div',     %q{ 1.0 / 1.0 == 1.0 }, ],
 | 
						|
  [ 'opt_div',     %q{ x = +0.0.next_float; x / x >= x }, ],
 | 
						|
  [ 'opt_div',     %q{ x = 1/2r; x / x == 1 }, ],
 | 
						|
  [ 'opt_mod',     %q{ 1 % 1 == 0 }, ],
 | 
						|
  [ 'opt_mod',     %q{ 1.0 % 1.0 == 0.0 }, ],
 | 
						|
  [ 'opt_mod',     %q{ x = +0.0.next_float; x % x == 0.0 }, ],
 | 
						|
  [ 'opt_mod',     %q{ '%s' % [ true ] }, ],
 | 
						|
 | 
						|
  [ 'opt_eq', %q{ 1 == 1 }, ],
 | 
						|
  [ 'opt_eq', <<~'},', ],       # {
 | 
						|
    class X; def == other; true; end; end
 | 
						|
    X.new == true
 | 
						|
  },
 | 
						|
  [ 'opt_neq', %q{ 1 != 0 }, ],
 | 
						|
  [ 'opt_neq', <<~'},', ],       # {
 | 
						|
    class X; def != other; true; end; end
 | 
						|
    X.new != true
 | 
						|
  },
 | 
						|
 | 
						|
  [ 'opt_lt', %q{            -1   <  0 }, ],
 | 
						|
  [ 'opt_lt', %q{            -1.0 <  0.0 }, ],
 | 
						|
  [ 'opt_lt', %q{ -0.0.prev_float <  0.0 }, ],
 | 
						|
  [ 'opt_lt', %q{              ?a <  ?z }, ],
 | 
						|
  [ 'opt_le', %q{            -1   <= 0 }, ],
 | 
						|
  [ 'opt_le', %q{            -1.0 <= 0.0 }, ],
 | 
						|
  [ 'opt_le', %q{ -0.0.prev_float <= 0.0 }, ],
 | 
						|
  [ 'opt_le', %q{              ?a <= ?z }, ],
 | 
						|
  [ 'opt_gt', %q{             1   >  0 }, ],
 | 
						|
  [ 'opt_gt', %q{             1.0 >  0.0 }, ],
 | 
						|
  [ 'opt_gt', %q{ +0.0.next_float >  0.0 }, ],
 | 
						|
  [ 'opt_gt', %q{              ?z >  ?a }, ],
 | 
						|
  [ 'opt_ge', %q{             1   >= 0 }, ],
 | 
						|
  [ 'opt_ge', %q{             1.0 >= 0.0 }, ],
 | 
						|
  [ 'opt_ge', %q{ +0.0.next_float >= 0.0 }, ],
 | 
						|
  [ 'opt_ge', %q{              ?z >= ?a }, ],
 | 
						|
 | 
						|
  [ 'opt_ltlt', %q{  '' << 'true' }, ],
 | 
						|
  [ 'opt_ltlt', %q{ ([] << 'true').join }, ],
 | 
						|
  [ 'opt_ltlt', %q{ (1 << 31) == 2147483648 }, ],
 | 
						|
 | 
						|
  [ 'opt_aref', %q{ ['true'][0] }, ],
 | 
						|
  [ 'opt_aref', %q{ { 0 => 'true'}[0] }, ],
 | 
						|
  [ 'opt_aref', %q{ 'true'[0] == ?t }, ],
 | 
						|
  [ 'opt_aset', %q{ [][0] = true }, ],
 | 
						|
  [ 'opt_aset', %q{ {}[0] = true }, ],
 | 
						|
  [ 'opt_aset', %q{ x = 'frue'; x[0] = 't'; x }, ],
 | 
						|
  [ 'opt_aset', <<~'},', ], # {
 | 
						|
    # opt_aref / opt_aset mixup situation
 | 
						|
    class X; def x; {}; end; end
 | 
						|
    x = X.new
 | 
						|
    x&.x[true] ||= true         # here
 | 
						|
  },
 | 
						|
 | 
						|
  [ 'opt_aref_with', %q{ { 'true' => true }['true'] }, ],
 | 
						|
  [ 'opt_aref_with', %q{ Struct.new(:nil).new['nil'].nil? }, ],
 | 
						|
  [ 'opt_aset_with', %q{ {}['true'] = true }, ],
 | 
						|
  [ 'opt_aset_with', %q{ Struct.new(:true).new['true'] = true }, ],
 | 
						|
 | 
						|
  [ 'opt_length',  %q{   'true'       .length == 4 }, ],
 | 
						|
  [ 'opt_length',  %q{   :true        .length == 4 }, ],
 | 
						|
  [ 'opt_length',  %q{ [ 'true' ]     .length == 1 }, ],
 | 
						|
  [ 'opt_length',  %q{ { 'true' => 1 }.length == 1 }, ],
 | 
						|
  [ 'opt_size',    %q{   'true'       .size   == 4 }, ],
 | 
						|
  [ 'opt_size',    %q{               1.size   >= 4 }, ],
 | 
						|
  [ 'opt_size',    %q{ [ 'true' ]     .size   == 1 }, ],
 | 
						|
  [ 'opt_size',    %q{ { 'true' => 1 }.size   == 1 }, ],
 | 
						|
  [ 'opt_empty_p', %q{ ''.empty? }, ],
 | 
						|
  [ 'opt_empty_p', %q{ [].empty? }, ],
 | 
						|
  [ 'opt_empty_p', %q{ {}.empty? }, ],
 | 
						|
  [ 'opt_empty_p', %q{ Queue.new.empty? }, ],
 | 
						|
 | 
						|
  [ 'opt_succ',  %q{ 1.succ == 2 }, ],
 | 
						|
  if defined? $FIXNUM_MAX then
 | 
						|
    [ 'opt_succ',%Q{ #{ $FIXNUM_MAX }.succ == #{ $FIXNUM_MAX + 1 } }, ]
 | 
						|
  end,
 | 
						|
  [ 'opt_succ',  %q{ '1'.succ == '2' }, ],
 | 
						|
  [ 'opt_succ',  %q{ x = Time.at(0); x.succ == Time.at(1) }, ],
 | 
						|
 | 
						|
  [ 'opt_not',  %q{ ! false }, ],
 | 
						|
  [ 'opt_neq', <<~'},', ],       # {
 | 
						|
    class X; def !; true; end; end
 | 
						|
    ! X.new
 | 
						|
  },
 | 
						|
 | 
						|
  [ 'opt_regexpmatch1',  %q{ /true/ =~ 'true' && $~ }, ],
 | 
						|
  [ 'opt_regexpmatch1', <<~'},', ],       # {
 | 
						|
    class Regexp; def =~ other; true; end; end
 | 
						|
    /true/ =~ 'true'
 | 
						|
  },
 | 
						|
  [ 'opt_regexpmatch2',  %q{ 'true' =~ /true/ && $~ }, ],
 | 
						|
  [ 'opt_regexpmatch2', <<~'},', ],       # {
 | 
						|
    class String; def =~ other; true; end; end
 | 
						|
    'true' =~ /true/
 | 
						|
  },
 | 
						|
]
 | 
						|
 | 
						|
tests.compact.each {|(insn, expr, *a)| assert_equal 'true', expr, insn, *a }
 |