diff options
Diffstat (limited to 'tool/ruby_vm')
48 files changed, 0 insertions, 2728 deletions
diff --git a/tool/ruby_vm/controllers/application_controller.rb b/tool/ruby_vm/controllers/application_controller.rb deleted file mode 100644 index 25c10947ed..0000000000 --- a/tool/ruby_vm/controllers/application_controller.rb +++ /dev/null @@ -1,25 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/dumper' -require_relative '../models/instructions' -require_relative '../models/typemap' -require_relative '../loaders/vm_opts_h' - -class ApplicationController - def generate i, destdir - path = Pathname.new i - dst = destdir ? Pathname.new(destdir).join(i) : Pathname.new(i) - dumper = RubyVM::Dumper.new dst - return [path, dumper] - end -end diff --git a/tool/ruby_vm/helpers/c_escape.rb b/tool/ruby_vm/helpers/c_escape.rb deleted file mode 100644 index 34fafd1e34..0000000000 --- a/tool/ruby_vm/helpers/c_escape.rb +++ /dev/null @@ -1,128 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require 'securerandom' - -module RubyVM::CEscape - module_function - - # generate comment, with escaps. - def commentify str - return "/* #{str.b.gsub('*/', '*\\/').gsub('/*', '/\\*')} */" - end - - # Mimic gensym of CL. - def gensym prefix = 'gensym_' - return as_tr_cpp "#{prefix}#{SecureRandom.uuid}" - end - - # Mimic AS_TR_CPP() of autoconf. - def as_tr_cpp name - q = name.b - q.gsub! %r/[^a-zA-Z0-9_]/m, '_' - q.gsub! %r/_+/, '_' - return q - end - - # Section 6.10.4 of ISO/IEC 9899:1999 specifies that the file name used for - # #line directive shall be a "character string literal". So this is needed. - # - # I'm not sure how many chars are allowed here, though. The standard - # specifies 4095 chars at most, after string concatenation (section 5.2.4.1). - # But it is easy to have a path that is longer than that. - # - # Here we ignore the standard. Just create single string literal of any - # needed length. - def rstring2cstr str - # I believe this is the fastest implementation done in pure-ruby. - # Constants cached, gsub skips block evaluation, string literal optimized. - buf = str.b - buf.gsub! %r/./nm, RString2CStr - return %'"#{buf}"' - end - - RString2CStr = { - "\x00"=> "\\0", "\x01"=> "\\x1", "\x02"=> "\\x2", "\x03"=> "\\x3", - "\x04"=> "\\x4", "\x05"=> "\\x5", "\x06"=> "\\x6", "\a"=> "\\a", - "\b"=> "\\b", "\t"=> "\\t", "\n"=> "\\n", "\v"=> "\\v", - "\f"=> "\\f", "\r"=> "\\r", "\x0E"=> "\\xe", "\x0F"=> "\\xf", - "\x10"=>"\\x10", "\x11"=>"\\x11", "\x12"=>"\\x12", "\x13"=>"\\x13", - "\x14"=>"\\x14", "\x15"=>"\\x15", "\x16"=>"\\x16", "\x17"=>"\\x17", - "\x18"=>"\\x18", "\x19"=>"\\x19", "\x1A"=>"\\x1a", "\e"=>"\\x1b", - "\x1C"=>"\\x1c", "\x1D"=>"\\x1d", "\x1E"=>"\\x1e", "\x1F"=>"\\x1f", - " "=> " ", "!"=> "!", "\""=> "\\\"", "#"=> "#", - "$"=> "$", "%"=> "%", "&"=> "&", "'"=> "'", - "("=> "(", ")"=> ")", "*"=> "*", "+"=> "+", - ","=> ",", "-"=> "-", "."=> ".", "/"=> "/", - "0"=> "0", "1"=> "1", "2"=> "2", "3"=> "3", - "4"=> "4", "5"=> "5", "6"=> "6", "7"=> "7", - "8"=> "8", "9"=> "9", ":"=> ":", ";"=> ";", - "<"=> "<", "="=> "=", ">"=> ">", "?"=> "?", - "@"=> "@", "A"=> "A", "B"=> "B", "C"=> "C", - "D"=> "D", "E"=> "E", "F"=> "F", "G"=> "G", - "H"=> "H", "I"=> "I", "J"=> "J", "K"=> "K", - "L"=> "L", "M"=> "M", "N"=> "N", "O"=> "O", - "P"=> "P", "Q"=> "Q", "R"=> "R", "S"=> "S", - "T"=> "T", "U"=> "U", "V"=> "V", "W"=> "W", - "X"=> "X", "Y"=> "Y", "Z"=> "Z", "["=> "[", - "\\"=> "\\\\", "]"=> "]", "^"=> "^", "_"=> "_", - "`"=> "`", "a"=> "a", "b"=> "b", "c"=> "c", - "d"=> "d", "e"=> "e", "f"=> "f", "g"=> "g", - "h"=> "h", "i"=> "i", "j"=> "j", "k"=> "k", - "l"=> "l", "m"=> "m", "n"=> "n", "o"=> "o", - "p"=> "p", "q"=> "q", "r"=> "r", "s"=> "s", - "t"=> "t", "u"=> "u", "v"=> "v", "w"=> "w", - "x"=> "x", "y"=> "y", "z"=> "z", "{"=> "{", - "|"=> "|", "}"=> "}", "~"=> "~", "\x7F"=>"\\x7f", - "\x80"=>"\\x80", "\x81"=>"\\x81", "\x82"=>"\\x82", "\x83"=>"\\x83", - "\x84"=>"\\x84", "\x85"=>"\\x85", "\x86"=>"\\x86", "\x87"=>"\\x87", - "\x88"=>"\\x88", "\x89"=>"\\x89", "\x8A"=>"\\x8a", "\x8B"=>"\\x8b", - "\x8C"=>"\\x8c", "\x8D"=>"\\x8d", "\x8E"=>"\\x8e", "\x8F"=>"\\x8f", - "\x90"=>"\\x90", "\x91"=>"\\x91", "\x92"=>"\\x92", "\x93"=>"\\x93", - "\x94"=>"\\x94", "\x95"=>"\\x95", "\x96"=>"\\x96", "\x97"=>"\\x97", - "\x98"=>"\\x98", "\x99"=>"\\x99", "\x9A"=>"\\x9a", "\x9B"=>"\\x9b", - "\x9C"=>"\\x9c", "\x9D"=>"\\x9d", "\x9E"=>"\\x9e", "\x9F"=>"\\x9f", - "\xA0"=>"\\xa0", "\xA1"=>"\\xa1", "\xA2"=>"\\xa2", "\xA3"=>"\\xa3", - "\xA4"=>"\\xa4", "\xA5"=>"\\xa5", "\xA6"=>"\\xa6", "\xA7"=>"\\xa7", - "\xA8"=>"\\xa8", "\xA9"=>"\\xa9", "\xAA"=>"\\xaa", "\xAB"=>"\\xab", - "\xAC"=>"\\xac", "\xAD"=>"\\xad", "\xAE"=>"\\xae", "\xAF"=>"\\xaf", - "\xB0"=>"\\xb0", "\xB1"=>"\\xb1", "\xB2"=>"\\xb2", "\xB3"=>"\\xb3", - "\xB4"=>"\\xb4", "\xB5"=>"\\xb5", "\xB6"=>"\\xb6", "\xB7"=>"\\xb7", - "\xB8"=>"\\xb8", "\xB9"=>"\\xb9", "\xBA"=>"\\xba", "\xBB"=>"\\xbb", - "\xBC"=>"\\xbc", "\xBD"=>"\\xbd", "\xBE"=>"\\xbe", "\xBF"=>"\\xbf", - "\xC0"=>"\\xc0", "\xC1"=>"\\xc1", "\xC2"=>"\\xc2", "\xC3"=>"\\xc3", - "\xC4"=>"\\xc4", "\xC5"=>"\\xc5", "\xC6"=>"\\xc6", "\xC7"=>"\\xc7", - "\xC8"=>"\\xc8", "\xC9"=>"\\xc9", "\xCA"=>"\\xca", "\xCB"=>"\\xcb", - "\xCC"=>"\\xcc", "\xCD"=>"\\xcd", "\xCE"=>"\\xce", "\xCF"=>"\\xcf", - "\xD0"=>"\\xd0", "\xD1"=>"\\xd1", "\xD2"=>"\\xd2", "\xD3"=>"\\xd3", - "\xD4"=>"\\xd4", "\xD5"=>"\\xd5", "\xD6"=>"\\xd6", "\xD7"=>"\\xd7", - "\xD8"=>"\\xd8", "\xD9"=>"\\xd9", "\xDA"=>"\\xda", "\xDB"=>"\\xdb", - "\xDC"=>"\\xdc", "\xDD"=>"\\xdd", "\xDE"=>"\\xde", "\xDF"=>"\\xdf", - "\xE0"=>"\\xe0", "\xE1"=>"\\xe1", "\xE2"=>"\\xe2", "\xE3"=>"\\xe3", - "\xE4"=>"\\xe4", "\xE5"=>"\\xe5", "\xE6"=>"\\xe6", "\xE7"=>"\\xe7", - "\xE8"=>"\\xe8", "\xE9"=>"\\xe9", "\xEA"=>"\\xea", "\xEB"=>"\\xeb", - "\xEC"=>"\\xec", "\xED"=>"\\xed", "\xEE"=>"\\xee", "\xEF"=>"\\xef", - "\xF0"=>"\\xf0", "\xF1"=>"\\xf1", "\xF2"=>"\\xf2", "\xF3"=>"\\xf3", - "\xF4"=>"\\xf4", "\xF5"=>"\\xf5", "\xF6"=>"\\xf6", "\xF7"=>"\\xf7", - "\xF8"=>"\\xf8", "\xF9"=>"\\xf9", "\xFA"=>"\\xfa", "\xFB"=>"\\xfb", - "\xFC"=>"\\xfc", "\xFD"=>"\\xfd", "\xFE"=>"\\xfe", "\xFF"=>"\\xff", - }.freeze - private_constant :RString2CStr -end - -unless defined? ''.b - class String - def b - return dup.force_encoding 'binary' - end - end -end diff --git a/tool/ruby_vm/helpers/dumper.rb b/tool/ruby_vm/helpers/dumper.rb deleted file mode 100644 index 98104f4b92..0000000000 --- a/tool/ruby_vm/helpers/dumper.rb +++ /dev/null @@ -1,113 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require 'pathname' -require 'erb' -require_relative 'c_escape' - -class RubyVM::Dumper - include RubyVM::CEscape - private - - def new_binding - # This `eval 'binding'` does not return the current binding - # but creates one on top of it. - return eval 'binding' - end - - def new_erb spec - path = Pathname.new(__FILE__) - path = (path.relative_path_from(Pathname.pwd) rescue path).dirname - path += '../views' - path += spec - src = path.read mode: 'rt:utf-8:utf-8' - rescue Errno::ENOENT - raise "don't know how to generate #{path}" - else - if ERB.instance_method(:initialize).parameters.assoc(:key) # Ruby 2.6+ - erb = ERB.new(src, trim_mode: '%-') - else - erb = ERB.new(src, nil, '%-') - end - erb.filename = path.to_path - return erb - end - - def finderb spec - return @erb.fetch spec do |k| - erb = new_erb k - @erb[k] = erb - end - end - - def replace_pragma_line str, lineno - if /#(\s*)pragma RubyVM reset source\n/ =~ str then - return "##{$1}line #{lineno + 2} #{@file}\n" - else - return str - end - end - - def local_variable_set bnd, var, val - eval '__locals__ ||= {}', bnd - locals = eval '__locals__', bnd - locals[var] = val - eval "#{var} = __locals__[:#{var}]", bnd - test = eval "#{var}", bnd - raise unless test == val - end - - public - - def do_render source, locals - erb = finderb source - bnd = @empty.dup - locals.each_pair do |k, v| - local_variable_set bnd, k, v - end - return erb.result bnd - end - - def replace_pragma str - return str \ - . each_line \ - . with_index \ - . map {|i, j| replace_pragma_line i, j } \ - . join - end - - def initialize dst - @erb = {} - @empty = new_binding - @file = cstr dst.to_path - end - - def render partial, opts = { :locals => {} } - return do_render "_#{partial}.erb", opts[:locals] - end - - def generate template - str = do_render "#{template}.erb", {} - return replace_pragma str - end - - private - - # view helpers - - alias cstr rstring2cstr - alias comm commentify - - def render_c_expr expr - render 'c_expr', locals: { expr: expr, } - end -end diff --git a/tool/ruby_vm/helpers/scanner.rb b/tool/ruby_vm/helpers/scanner.rb deleted file mode 100644 index ef6de8120e..0000000000 --- a/tool/ruby_vm/helpers/scanner.rb +++ /dev/null @@ -1,53 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require 'pathname' - -# Poor man's StringScanner. -# Sadly https://bugs.ruby-lang.org/issues/8343 is not backported to 2.0. We -# have to do it by hand. -class RubyVM::Scanner - attr_reader :__FILE__ - attr_reader :__LINE__ - - def initialize path - src = Pathname.new(__FILE__) - src = (src.relative_path_from(Pathname.pwd) rescue src).dirname - src += path - @__LINE__ = 1 - @__FILE__ = src.to_path - @str = src.read mode: 'rt:utf-8:utf-8' - @pos = 0 - end - - def eos? - return @pos >= @str.length - end - - def scan re - ret = @__LINE__ - @last_match = @str.match re, @pos - return unless @last_match - @__LINE__ += @last_match.to_s.count "\n" - @pos = @last_match.end 0 - return ret - end - - def scan! re - scan re or raise sprintf "parse error at %s:%d near:\n %s...", \ - @__FILE__, @__LINE__, @str[@pos, 32] - end - - def [] key - return @last_match[key] - end -end diff --git a/tool/ruby_vm/loaders/insns_def.rb b/tool/ruby_vm/loaders/insns_def.rb deleted file mode 100644 index 034905f74e..0000000000 --- a/tool/ruby_vm/loaders/insns_def.rb +++ /dev/null @@ -1,100 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/scanner' -require_relative './vm_opts_h' - -json = [] -scanner = RubyVM::Scanner.new '../../../insns.def' -path = scanner.__FILE__ -grammar = %r' - (?<comment> /[*] [^*]* [*]+ (?: [^*/] [^*]* [*]+ )* / ){0} - (?<keyword> typedef | extern | static | auto | register | - struct | union | enum ){0} - (?<C> (?: \g<block> | [^{}]+ )* ){0} - (?<block> \{ \g<ws>* \g<C> \g<ws>* \} ){0} - (?<ws> \g<comment> | \s ){0} - (?<ident> [_a-zA-Z] [0-9_a-zA-Z]* ){0} - (?<type> (?: \g<keyword> \g<ws>+ )* \g<ident> ){0} - (?<arg> \g<type> \g<ws>+ \g<ident> ){0} - (?<argv> (?# empty ) | - void | - (?: \.\.\. | \g<arg>) (?: \g<ws>* , \g<ws>* \g<arg> \g<ws>* )* ){0} - (?<pragma> \g<ws>* // \s* attr \g<ws>+ - (?<pragma:type> \g<type> ) \g<ws>+ - (?<pragma:name> \g<ident> ) \g<ws>* - = \g<ws>* - (?<pragma:expr> .+?; ) \g<ws>* ){0} - (?<insn> DEFINE_INSN(_IF\((?<insn:if>\w+)\))? \g<ws>+ - (?<insn:name> \g<ident> ) \g<ws>* - [(] \g<ws>* (?<insn:opes> \g<argv> ) \g<ws>* [)] \g<ws>* - [(] \g<ws>* (?<insn:pops> \g<argv> ) \g<ws>* [)] \g<ws>* - [(] \g<ws>* (?<insn:rets> \g<argv> ) \g<ws>* [)] \g<ws>* ){0} -'x - -until scanner.eos? do - next if scanner.scan(/\G#{grammar}\g<ws>+/o) - split = lambda {|v| - case v when /\Avoid\z/ then - [] - else - v.split(/, */) - end - } - - l1 = scanner.scan!(/\G#{grammar}\g<insn>/o) - name = scanner["insn:name"] - opt = scanner["insn:if"] - ope = split.(scanner["insn:opes"]) - pop = split.(scanner["insn:pops"]) - ret = split.(scanner["insn:rets"]) - if ope.include?("...") - raise sprintf("parse error at %s:%d:%s: operands cannot be variadic", - scanner.__FILE__, scanner.__LINE__, name) - end - - attrs = [] - while l2 = scanner.scan(/\G#{grammar}\g<pragma>/o) do - attrs << { - location: [path, l2], - name: scanner["pragma:name"], - type: scanner["pragma:type"], - expr: scanner["pragma:expr"], - } - end - - l3 = scanner.scan!(/\G#{grammar}\g<block>/o) - if opt.nil? || RubyVM::VmOptsH[opt] - json << { - name: name, - location: [path, l1], - signature: { - name: name, - ope: ope, - pop: pop, - ret: ret, - }, - attributes: attrs, - expr: { - location: [path, l3], - expr: scanner["block"], - }, - } - end -end - -RubyVM::InsnsDef = json - -if __FILE__ == $0 then - require 'json' - JSON.dump RubyVM::InsnsDef, STDOUT -end diff --git a/tool/ruby_vm/loaders/opt_insn_unif_def.rb b/tool/ruby_vm/loaders/opt_insn_unif_def.rb deleted file mode 100644 index aa6fd79e79..0000000000 --- a/tool/ruby_vm/loaders/opt_insn_unif_def.rb +++ /dev/null @@ -1,34 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/scanner' - -json = [] -scanner = RubyVM::Scanner.new '../../../defs/opt_insn_unif.def' -path = scanner.__FILE__ -until scanner.eos? do - next if scanner.scan(/\G ^ (?: \#.* )? \n /x) - break if scanner.scan(/\G ^ __END__ $ /x) - - pos = scanner.scan!(/\G (?<series> (?: [\ \t]* \w+ )+ ) \n /mx) - json << { - location: [path, pos], - signature: scanner["series"].strip.split - } -end - -RubyVM::OptInsnUnifDef = json - -if __FILE__ == $0 then - require 'json' - JSON.dump RubyVM::OptInsnUnifDef, STDOUT -end diff --git a/tool/ruby_vm/loaders/opt_operand_def.rb b/tool/ruby_vm/loaders/opt_operand_def.rb deleted file mode 100644 index 29aef8a325..0000000000 --- a/tool/ruby_vm/loaders/opt_operand_def.rb +++ /dev/null @@ -1,56 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/scanner' - -json = [] -scanner = RubyVM::Scanner.new '../../../defs/opt_operand.def' -path = scanner.__FILE__ -grammar = %r/ - (?<comment> \# .+? \n ){0} - (?<ws> \g<comment> | \s ){0} - (?<insn> \w+ ){0} - (?<paren> \( (?: \g<paren> | [^()]+)* \) ){0} - (?<expr> (?: \g<paren> | [^(),\ \n] )+ ){0} - (?<remain> \g<expr> ){0} - (?<arg> \g<expr> ){0} - (?<extra> , \g<ws>* \g<remain> ){0} - (?<args> \g<arg> \g<extra>* ){0} - (?<decl> \g<insn> \g<ws>+ \g<args> \n ){0} -/mx - -until scanner.eos? do - break if scanner.scan(/\G ^ __END__ $ /x) - next if scanner.scan(/\G#{grammar} \g<ws>+ /ox) - - line = scanner.scan!(/\G#{grammar} \g<decl> /mox) - insn = scanner["insn"] - args = scanner["args"] - ary = [] - until args.strip.empty? do - md = /\G#{grammar} \g<args> /mox.match(args) - ary << md["arg"] - args = md["remain"] - break unless args - end - json << { - location: [path, line], - signature: [insn, ary] - } -end - -RubyVM::OptOperandDef = json - -if __FILE__ == $0 then - require 'json' - JSON.dump RubyVM::OptOperandDef, STDOUT -end diff --git a/tool/ruby_vm/loaders/vm_opts_h.rb b/tool/ruby_vm/loaders/vm_opts_h.rb deleted file mode 100644 index 3f05c270ee..0000000000 --- a/tool/ruby_vm/loaders/vm_opts_h.rb +++ /dev/null @@ -1,37 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/scanner' - -json = {} -scanner = RubyVM::Scanner.new '../../../vm_opts.h' -grammar = %r/ - (?<ws> \u0020 ){0} - (?<key> \w+ ){0} - (?<value> 0|1 ){0} - (?<define> \G \#define \g<ws>+ OPT_\g<key> \g<ws>+ \g<value> \g<ws>*\n ) -/mx - -until scanner.eos? do - if scanner.scan grammar then - json[scanner['key']] = ! scanner['value'].to_i.zero? # not nonzero? - else - scanner.scan(/\G.*\n/) - end -end - -RubyVM::VmOptsH = json - -if __FILE__ == $0 then - require 'json' - JSON.dump RubyVM::VmOptsH, STDOUT -end diff --git a/tool/ruby_vm/models/attribute.rb b/tool/ruby_vm/models/attribute.rb deleted file mode 100644 index de35e7234a..0000000000 --- a/tool/ruby_vm/models/attribute.rb +++ /dev/null @@ -1,59 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative 'c_expr' - -class RubyVM::Attribute - include RubyVM::CEscape - attr_reader :insn, :key, :type, :expr - - def initialize opts = {} - @insn = opts[:insn] - @key = opts[:name] - @expr = RubyVM::CExpr.new location: opts[:location], expr: opts[:expr] - @type = opts[:type] - @ope_decls = @insn.opes.map do |operand| - decl = operand[:decl] - if @key == 'comptime_sp_inc' && operand[:type] == 'CALL_DATA' - decl = decl.gsub('CALL_DATA', 'CALL_INFO').gsub('cd', 'ci') - end - decl - end - end - - def name - as_tr_cpp "attr #{@key} @ #{@insn.name}" - end - - def pretty_name - "attr #{type} #{key} @ #{insn.pretty_name}" - end - - def declaration - if @ope_decls.empty? - argv = "void" - else - argv = @ope_decls.join(', ') - end - sprintf '%s %s(%s)', @type, name, argv - end - - def definition - if @ope_decls.empty? - argv = "void" - else - argv = @ope_decls.map {|decl| "MAYBE_UNUSED(#{decl})" }.join(",\n ") - argv = "\n #{argv}\n" if @ope_decls.size > 1 - end - sprintf "%s\n%s(%s)", @type, name, argv - end -end diff --git a/tool/ruby_vm/models/bare_instructions.rb b/tool/ruby_vm/models/bare_instructions.rb deleted file mode 100755 index 6b5f1f6cf8..0000000000 --- a/tool/ruby_vm/models/bare_instructions.rb +++ /dev/null @@ -1,240 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../loaders/insns_def' -require_relative 'c_expr' -require_relative 'typemap' -require_relative 'attribute' - -class RubyVM::BareInstructions - attr_reader :template, :name, :opes, :pops, :rets, :decls, :expr - - def initialize opts = {} - @template = opts[:template] - @name = opts[:name] - @loc = opts[:location] - @sig = opts[:signature] - @expr = RubyVM::CExpr.new opts[:expr] - @opes = typesplit @sig[:ope] - @pops = typesplit @sig[:pop].reject {|i| i == '...' } - @rets = typesplit @sig[:ret].reject {|i| i == '...' } - @attrs = opts[:attributes].map {|i| - RubyVM::Attribute.new i.merge(:insn => self) - }.each_with_object({}) {|a, h| - h[a.key] = a - } - @attrs_orig = @attrs.dup - check_attribute_consistency - predefine_attributes - end - - def pretty_name - n = @sig[:name] - o = @sig[:ope].map{|i| i[/\S+$/] }.join ', ' - p = @sig[:pop].map{|i| i[/\S+$/] }.join ', ' - r = @sig[:ret].map{|i| i[/\S+$/] }.join ', ' - return sprintf "%s(%s)(%s)(%s)", n, o, p, r - end - - def bin - return "BIN(#{name})" - end - - def call_attribute name - return sprintf 'attr_%s_%s(%s)', name, @name, \ - @opes.map {|i| i[:name] }.compact.join(', ') - end - - def has_attribute? k - @attrs_orig.has_key? k - end - - def attributes - return @attrs \ - . sort_by {|k, _| k } \ - . map {|_, v| v } - end - - def width - return 1 + opes.size - end - - def declarations - return @variables \ - . values \ - . group_by {|h| h[:type] } \ - . sort_by {|t, v| t } \ - . map {|t, v| [t, v.map {|i| i[:name] }.sort ] } \ - . map {|t, v| - sprintf("MAYBE_UNUSED(%s) %s", t, v.join(', ')) - } - end - - def preamble - # preamble makes sense for operand unifications - return [] - end - - def sc? - # sc stands for stack caching. - return false - end - - def cast_to_VALUE var, expr = var[:name] - RubyVM::Typemap.typecast_to_VALUE var[:type], expr - end - - def cast_from_VALUE var, expr = var[:name] - RubyVM::Typemap.typecast_from_VALUE var[:type], expr - end - - def operands_info - opes.map {|o| - c, _ = RubyVM::Typemap.fetch o[:type] - next c - }.join - end - - def handles_sp? - /\b(false|0)\b/ !~ @attrs.fetch('handles_sp').expr.expr - end - - def always_leaf? - @attrs.fetch('leaf').expr.expr == 'true;' - end - - def leaf_without_check_ints? - @attrs.fetch('leaf').expr.expr == 'leafness_of_check_ints;' - end - - def handle_canary stmt - # Stack canary is basically a good thing that we want to add, however: - # - # - When the instruction returns variadic number of return values, - # it is not easy to tell where is the stack top. We can't but - # skip it. - # - # - When the instruction body is empty (like putobject), we can - # say for 100% sure that canary is a waste of time. - # - # So we skip canary for those cases. - return '' if @sig[:ret].any? {|i| i == '...' } - return '' if @expr.blank? - return " #{stmt};\n" - end - - def inspect - sprintf "#<%s %s@%s:%d>", self.class.name, @name, @loc[0], @loc[1] - end - - def has_ope? var - return @opes.any? {|i| i[:name] == var[:name] } - end - - def has_pop? var - return @pops.any? {|i| i[:name] == var[:name] } - end - - def use_call_data? - @use_call_data ||= - @variables.find { |_, var_info| var_info[:type] == 'CALL_DATA' } - end - - private - - def check_attribute_consistency - if has_attribute?('sp_inc') \ - && use_call_data? \ - && !has_attribute?('comptime_sp_inc') - # As the call cache caches information that can only be obtained at - # runtime, we do not need it when compiling from AST to bytecode. This - # attribute defines an expression that computes the stack pointer - # increase based on just the call info to avoid reserving space for the - # call cache at compile time. In the expression, all call data operands - # are mapped to their call info counterpart. Additionally, all mentions - # of `cd` in the operand name are replaced with `ci`. - raise "Please define attribute `comptime_sp_inc` for `#{@name}`" - end - end - - def generate_attribute t, k, v - @attrs[k] ||= RubyVM::Attribute.new \ - insn: self, \ - name: k, \ - type: t, \ - location: [], \ - expr: v.to_s + ';' - return @attrs[k] ||= attr - end - - def predefine_attributes - # Beware: order matters here because some attribute depends another. - generate_attribute 'const char*', 'name', "insn_name(#{bin})" - generate_attribute 'enum ruby_vminsn_type', 'bin', bin - generate_attribute 'rb_num_t', 'open', opes.size - generate_attribute 'rb_num_t', 'popn', pops.size - generate_attribute 'rb_num_t', 'retn', rets.size - generate_attribute 'rb_num_t', 'width', width - generate_attribute 'rb_snum_t', 'sp_inc', rets.size - pops.size - generate_attribute 'bool', 'handles_sp', default_definition_of_handles_sp - generate_attribute 'bool', 'leaf', default_definition_of_leaf - end - - def default_definition_of_handles_sp - # Insn with ISEQ should yield it; can handle sp. - return opes.any? {|o| o[:type] == 'ISEQ' } - end - - def default_definition_of_leaf - # Insn that handles SP can never be a leaf. - if not has_attribute? 'handles_sp' then - return ! default_definition_of_handles_sp - elsif handles_sp? then - return "! #{call_attribute 'handles_sp'}" - else - return true - end - end - - def typesplit a - @variables ||= {} - a.map do |decl| - md = %r' - (?<comment> /[*] [^*]* [*]+ (?: [^*/] [^*]* [*]+ )* / ){0} - (?<ws> \g<comment> | \s ){0} - (?<ident> [_a-zA-Z] [0-9_a-zA-Z]* ){0} - (?<type> (?: \g<ident> \g<ws>+ )* \g<ident> ){0} - (?<var> \g<ident> ){0} - \G \g<ws>* \g<type> \g<ws>+ \g<var> - 'x.match(decl) - @variables[md['var']] ||= { - decl: decl, - type: md['type'], - name: md['var'], - } - end - end - - @instances = RubyVM::InsnsDef.map {|h| - new h.merge(:template => h) - } - - def self.fetch name - @instances.find do |insn| - insn.name == name - end or raise IndexError, "instruction not found: #{name}" - end - - def self.to_a - @instances - end -end diff --git a/tool/ruby_vm/models/c_expr.rb b/tool/ruby_vm/models/c_expr.rb deleted file mode 100644 index 073112f545..0000000000 --- a/tool/ruby_vm/models/c_expr.rb +++ /dev/null @@ -1,41 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/c_escape.rb' - -class RubyVM::CExpr - include RubyVM::CEscape - - attr_reader :__FILE__, :__LINE__, :expr - - def initialize opts = {} - @__FILE__ = opts[:location][0] - @__LINE__ = opts[:location][1] - @expr = opts[:expr] - end - - # blank, in sense of C program. - RE = %r'\A{\g<s>*}\z|\A(?<s>\s|/[*][^*]*[*]+([^*/][^*]*[*]+)*/)*\z' - if RUBY_VERSION > '2.4' then - def blank? - RE.match? @expr - end - else - def blank? - RE =~ @expr - end - end - - def inspect - sprintf "#<%s:%d %s>", @__FILE__, @__LINE__, @expr - end -end diff --git a/tool/ruby_vm/models/instructions.rb b/tool/ruby_vm/models/instructions.rb deleted file mode 100644 index 1198c7a4a6..0000000000 --- a/tool/ruby_vm/models/instructions.rb +++ /dev/null @@ -1,22 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative 'bare_instructions' -require_relative 'operands_unifications' -require_relative 'instructions_unifications' - -RubyVM::Instructions = RubyVM::BareInstructions.to_a + \ - RubyVM::OperandsUnifications.to_a + \ - RubyVM::InstructionsUnifications.to_a - -require_relative 'trace_instructions' -RubyVM::Instructions.freeze diff --git a/tool/ruby_vm/models/instructions_unifications.rb b/tool/ruby_vm/models/instructions_unifications.rb deleted file mode 100644 index 214ba5fcc2..0000000000 --- a/tool/ruby_vm/models/instructions_unifications.rb +++ /dev/null @@ -1,43 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/c_escape' -require_relative '../loaders/opt_insn_unif_def' -require_relative 'bare_instructions' - -class RubyVM::InstructionsUnifications - include RubyVM::CEscape - - attr_reader :name - - def initialize opts = {} - @location = opts[:location] - @name = namegen opts[:signature] - @series = opts[:signature].map do |i| - RubyVM::BareInstructions.fetch i # Misshit is fatal - end - end - - private - - def namegen signature - as_tr_cpp ['UNIFIED', *signature].join('_') - end - - @instances = RubyVM::OptInsnUnifDef.map do |h| - new h - end - - def self.to_a - @instances - end -end diff --git a/tool/ruby_vm/models/operands_unifications.rb b/tool/ruby_vm/models/operands_unifications.rb deleted file mode 100644 index ee4e3a695d..0000000000 --- a/tool/ruby_vm/models/operands_unifications.rb +++ /dev/null @@ -1,142 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/c_escape' -require_relative '../loaders/opt_operand_def' -require_relative 'bare_instructions' - -class RubyVM::OperandsUnifications < RubyVM::BareInstructions - include RubyVM::CEscape - - attr_reader :preamble, :original, :spec - - def initialize opts = {} - name = opts[:signature][0] - @original = RubyVM::BareInstructions.fetch name - template = @original.template - parts = compose opts[:location], opts[:signature], template[:signature] - json = template.dup - json[:location] = opts[:location] - json[:signature] = parts[:signature] - json[:name] = parts[:name] - @preamble = parts[:preamble] - @spec = parts[:spec] - super json.merge(:template => template) - @konsts = parts[:vars] - @konsts.each do |v| - @variables[v[:name]] ||= v - end - end - - def operand_shift_of var - before = @original.opes.find_index var - after = @opes.find_index var - raise "no #{var} for #{@name}" unless before and after - return before - after - end - - def condition ptr - # :FIXME: I'm not sure if this method should be in model? - exprs = @spec.each_with_index.map do |(var, val), i| - case val when '*' then - next nil - else - type = @original.opes[i][:type] - expr = RubyVM::Typemap.typecast_to_VALUE type, val - next "#{ptr}[#{i}] == #{expr}" - end - end - exprs.compact! - if exprs.size == 1 then - return exprs[0] - else - exprs.map! {|i| "(#{i})" } - return exprs.join ' && ' - end - end - - def has_ope? var - super or @konsts.any? {|i| i[:name] == var[:name] } - end - - private - - def namegen signature - insn, argv = *signature - wcary = argv.map do |i| - case i when '*' then - 'WC' - else - i - end - end - as_tr_cpp [insn, *wcary].join(', ') - end - - def compose location, spec, template - name = namegen spec - *, argv = *spec - opes = @original.opes - if opes.size != argv.size - raise sprintf("operand size mismatch for %s (%s's: %d, given: %d)", - name, template[:name], opes.size, argv.size) - else - src = [] - mod = [] - spec = [] - vars = [] - argv.each_index do |i| - j = argv[i] - k = opes[i] - spec[i] = [k, j] - case j when '*' then - # operand is from iseq - mod << k[:decl] - else - # operand is inside C - vars << k - src << { - location: location, - expr: " const #{k[:decl]} = #{j};" - } - end - end - src.map! {|i| RubyVM::CExpr.new i } - return { - name: name, - signature: { - name: name, - ope: mod, - pop: template[:pop], - ret: template[:ret], - }, - preamble: src, - vars: vars, - spec: spec - } - end - end - - @instances = RubyVM::OptOperandDef.map do |h| - new h - end - - def self.to_a - @instances - end - - def self.each_group - to_a.group_by(&:original).each_pair do |k, v| - yield k, v - end - end -end diff --git a/tool/ruby_vm/models/trace_instructions.rb b/tool/ruby_vm/models/trace_instructions.rb deleted file mode 100644 index 4ed4c8cb42..0000000000 --- a/tool/ruby_vm/models/trace_instructions.rb +++ /dev/null @@ -1,71 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require_relative '../helpers/c_escape' -require_relative 'bare_instructions' - -class RubyVM::TraceInstructions - include RubyVM::CEscape - - attr_reader :name - - def initialize orig - @orig = orig - @name = as_tr_cpp "trace @ #{@orig.name}" - end - - def pretty_name - return sprintf "%s(...)(...)(...)", @name - end - - def jump_destination - return @orig.name - end - - def bin - return sprintf "BIN(%s)", @name - end - - def width - return @orig.width - end - - def operands_info - return @orig.operands_info - end - - def rets - return ['...'] - end - - def pops - return ['...'] - end - - def attributes - return [] - end - - def has_attribute? *; - return false - end - - private - - @instances = RubyVM::Instructions.map {|i| new i } - - def self.to_a - @instances - end - - RubyVM::Instructions.push(*to_a) -end diff --git a/tool/ruby_vm/models/typemap.rb b/tool/ruby_vm/models/typemap.rb deleted file mode 100644 index ed3aea7d2e..0000000000 --- a/tool/ruby_vm/models/typemap.rb +++ /dev/null @@ -1,62 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -RubyVM::Typemap = { - "..." => %w[. TS_VARIABLE], - "CALL_DATA" => %w[C TS_CALLDATA], - "CDHASH" => %w[H TS_CDHASH], - "IC" => %w[K TS_IC], - "IVC" => %w[A TS_IVC], - "ID" => %w[I TS_ID], - "ISE" => %w[T TS_ISE], - "ISEQ" => %w[S TS_ISEQ], - "OFFSET" => %w[O TS_OFFSET], - "VALUE" => %w[V TS_VALUE], - "lindex_t" => %w[L TS_LINDEX], - "rb_insn_func_t" => %w[F TS_FUNCPTR], - "rb_num_t" => %w[N TS_NUM], - "RB_BUILTIN" => %w[R TS_BUILTIN], -} - -# :FIXME: should this method be here? -class << RubyVM::Typemap - def typecast_from_VALUE type, val - # see also iseq_set_sequence() - case type - when '...' - raise "cast not possible: #{val}" - when 'VALUE' then - return val - when 'rb_num_t', 'lindex_t' then - return "NUM2LONG(#{val})" - when 'ID' then - return "SYM2ID(#{val})" - else - return "(#{type})(#{val})" - end - end - - def typecast_to_VALUE type, val - case type - when 'VALUE' then - return val - when 'ISEQ', 'rb_insn_func_t' then - return "(VALUE)(#{val})" - when 'rb_num_t', 'lindex_t' - "LONG2NUM(#{val})" - when 'ID' then - return "ID2SYM(#{val})" - else - raise ":FIXME: TBW for #{type}" - end - end -end diff --git a/tool/ruby_vm/scripts/converter.rb b/tool/ruby_vm/scripts/converter.rb deleted file mode 100644 index 4e7c28d67b..0000000000 --- a/tool/ruby_vm/scripts/converter.rb +++ /dev/null @@ -1,29 +0,0 @@ -# This script was needed only once when I converted the old insns.def. -# Consider historical. -# -# ruby converter.rb insns.def | sponge insns.def - -BEGIN { $str = ARGF.read } -END { puts $str } - -# deal with spaces -$str.gsub! %r/\r\n|\r|\n|\z/, "\n" -$str.gsub! %r/([^\t\n]*)\t/ do - x = $1 - y = 8 - x.length % 8 - next x + ' ' * y -end -$str.gsub! %r/\s+$/, "\n" - -# deal with comments -$str.gsub! %r/@c.*?@e/m, '' -$str.gsub! %r/@j.*?\*\//m, '*/' -$str.gsub! %r/\n(\s*\n)+/, "\n\n" -$str.gsub! %r/\/\*\*?\s*\n\s*/, "/* " -$str.gsub! %r/\n\s+\*\//, " */" -$str.gsub! %r/^(?!.*\/\*.+\*\/$)(.+?)\s*\*\//, "\\1\n */" - -# deal with sp_inc -$str.gsub! %r/ \/\/ inc -= (.*)/, ' // inc += -\\1' -$str.gsub! %r/\s+\/\/ inc \+= (.*)/, "\n// attr rb_snum_t sp_inc = \\1;" -$str.gsub! %r/;;$/, ";" diff --git a/tool/ruby_vm/scripts/insns2vm.rb b/tool/ruby_vm/scripts/insns2vm.rb deleted file mode 100644 index 8325dd364f..0000000000 --- a/tool/ruby_vm/scripts/insns2vm.rb +++ /dev/null @@ -1,93 +0,0 @@ -#! /your/favourite/path/to/ruby -# -*- Ruby -*- -# -*- frozen_string_literal: true; -*- -# -*- warn_indent: true; -*- -# -# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -require 'optparse' -require_relative '../controllers/application_controller.rb' - -module RubyVM::Insns2VM - def self.router argv - options = { destdir: nil } - targets = generate_parser(options).parse argv - return targets.map do |i| - next ApplicationController.new.generate i, options[:destdir] - end - end - - def self.generate_parser(options) - OptionParser.new do |this| - this.on "-I", "--srcdir=DIR", <<-'end' - Historically this option has been passed to the script. This is - supposedly because at the beginning the script was placed - outside of the ruby source tree. Decades passed since the merge - of YARV, now I can safely assume this feature is obsolescent. - Just ignore the passed value here. - end - - this.on "-L", "--vpath=SPEC", <<-'end' - Likewise, this option is no longer supported. - end - - this.on "--path-separator=SEP", /\A(?:\W\z|\.(\W).+)/, <<-'end' - Old script says this option is a "separator for vpath". I am - confident we no longer need this option. - end - - this.on "-Dname", "--enable=name[,name...]", Array, <<-'end' - This option was used to override VM option that is defined in - vm_opts.h. Now it is officially unsupported because vm_opts.h to - remain mismatched with this option must break things. Just edit - vm_opts.h directly. - end - - this.on "-Uname", "--disable=name[,name...]", Array, <<-'end' - This option was used to override VM option that is defined in - vm_opts.h. Now it is officially unsupported because vm_opts.h to - remain mismatched with this option must break things. Just edit - vm_opts.h directly. - end - - this.on "-i", "--insnsdef=FILE", "--instructions-def", <<-'end' - This option was used to specify alternative path to insns.def. For - the same reason to ignore -I, we no longer support this. - end - - this.on "-o", "--opt-operanddef=FILE", "--opt-operand-def", <<-'end' - This option was used to specify alternative path to opt_operand.def. - For the same reason to ignore -I, we no longer support this. - end - - this.on "-u", "--opt-insnunifdef=FILE", "--opt-insn-unif-def", <<-'end' - This option was used to specify alternative path to - opt_insn_unif.def. For the same reason to ignore -I, we no - longer support this. - end - - this.on "-C", "--[no-]use-const", <<-'end' - We use const whenever possible now so this option is ignored. - The author believes that C compilers can constant-fold. - end - - this.on "-d", "--destdir", "--output-directory=DIR", <<-'begin' do |dir| - THIS IS THE ONLY OPTION THAT WORKS today. Change destination - directory from the current working directory to the given path. - begin - raise "directory was not found in '#{dir}'" unless Dir.exist?(dir) - options[:destdir] = dir - end - - this.on "-V", "--[no-]verbose", <<-'end' - Please let us ignore this and be modest. - end - end - end - private_class_method :generate_parser -end diff --git a/tool/ruby_vm/tests/.gitkeep b/tool/ruby_vm/tests/.gitkeep deleted file mode 100644 index e69de29bb2..0000000000 --- a/tool/ruby_vm/tests/.gitkeep +++ /dev/null diff --git a/tool/ruby_vm/views/_attributes.erb b/tool/ruby_vm/views/_attributes.erb deleted file mode 100644 index 89a89817af..0000000000 --- a/tool/ruby_vm/views/_attributes.erb +++ /dev/null @@ -1,35 +0,0 @@ -%# -*- C -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# -#ifndef RUBY_VM_EXEC_H -/* can't #include "vm_exec.h" here... */ -typedef long OFFSET; -typedef unsigned long lindex_t; -typedef VALUE GENTRY; -typedef rb_iseq_t *ISEQ; -#endif - -% attrs = RubyVM::Instructions.map(&:attributes).flatten -% -% attrs.each do |a| -PUREFUNC(MAYBE_UNUSED(static <%= a.declaration %>)); -% end -% -% attrs.each do |a| - -/* <%= a.pretty_name %> */ -<%= a.definition %> -{ -% str = render_c_expr a.expr -% case str when /\A#/ then - return -<%= str -%> -% else - return <%= str -%> -% end -} -% end diff --git a/tool/ruby_vm/views/_c_expr.erb b/tool/ruby_vm/views/_c_expr.erb deleted file mode 100644 index 4e1b0ec883..0000000000 --- a/tool/ruby_vm/views/_c_expr.erb +++ /dev/null @@ -1,17 +0,0 @@ -%# -*- C -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%; -% if expr.blank? -% # empty -% elsif ! expr.__LINE__ -<%= expr.expr %> -% else -#line <%= expr.__LINE__ %> <%=cstr expr.__FILE__ %> -<%= expr.expr %> -#pragma RubyVM reset source -% end diff --git a/tool/ruby_vm/views/_comptime_insn_stack_increase.erb b/tool/ruby_vm/views/_comptime_insn_stack_increase.erb deleted file mode 100644 index b633ab4d32..0000000000 --- a/tool/ruby_vm/views/_comptime_insn_stack_increase.erb +++ /dev/null @@ -1,62 +0,0 @@ -%# -*- C -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%# -PUREFUNC(MAYBE_UNUSED(static int comptime_insn_stack_increase(int depth, int insn, const VALUE *opes))); -PUREFUNC(static rb_snum_t comptime_insn_stack_increase_dispatch(enum ruby_vminsn_type insn, const VALUE *opes)); - -rb_snum_t -comptime_insn_stack_increase_dispatch(enum ruby_vminsn_type insn, const VALUE *opes) -{ - static const signed char t[] = { -% RubyVM::Instructions.each_slice 8 do |a| - <%= a.map { |i| - if i.has_attribute?('sp_inc') - '-127' - else - sprintf("%4d", i.rets.size - i.pops.size) - end - }.join(', ') -%>, -% end - }; - signed char c = t[insn]; - - ASSERT_VM_INSTRUCTION_SIZE(t); - if (c != -127) { - return c; - } - else switch(insn) { - default: - UNREACHABLE; -% RubyVM::Instructions.each do |i| -% next unless i.has_attribute?('sp_inc') -% attr_function = -% if i.has_attribute?('comptime_sp_inc') -% "attr_comptime_sp_inc_#{i.name}" -% else -% "attr_sp_inc_#{i.name}" -% end - case <%= i.bin %>: - return <%= attr_function %>(<%= - i.opes.map.with_index do |v, j| - if v[:type] == 'CALL_DATA' && i.has_attribute?('comptime_sp_inc') - v = v.dup - v[:type] = 'CALL_INFO' - end - i.cast_from_VALUE v, "opes[#{j}]" - end.join(", ") - %>); -% end - } -} - -int -comptime_insn_stack_increase(int depth, int insn, const VALUE *opes) -{ - enum ruby_vminsn_type itype = (enum ruby_vminsn_type)insn; - return depth + (int)comptime_insn_stack_increase_dispatch(itype, opes); -} diff --git a/tool/ruby_vm/views/_copyright.erb b/tool/ruby_vm/views/_copyright.erb deleted file mode 100644 index 2154146f0d..0000000000 --- a/tool/ruby_vm/views/_copyright.erb +++ /dev/null @@ -1,31 +0,0 @@ -%# -*- C -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%; -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%; -%; -%# Below is the licensing term for the generated output, not this erb file. -/* This is an auto-generated file and is a part of the programming language - * Ruby. The person who created a program to generate this file (``I'' - * hereafter) would like to refrain from defining licensing of this generated - * source code. - * - * This file consists of many small parts of codes copyrighted by each author, - * not only the ``I'' person. Those original authors agree with some - * open-source license. I believe that the license we agree is the condition - * mentioned in the file COPYING. It states "4. You may modify and include - * the part of the software into any other software ...". But the problem is, - * the license never makes it clear if such modified parts still remain in the - * same license, or not. The fact that we agree with the source code's - * licensing terms does not automatically define that of generated ones. This - * is the reason why this file is under an unclear situation. All what I know - * is that above provision guarantees this file to exist. - * - * Please let me hesitate to declare something about this nuanced contract. I - * am not in the position to take over other authors' license to merge into my - * one. Changing them to (say) GPLv3 is not doable by myself. Perhaps someday - * it might turn out to be okay to say this file is under a license. I wish - * the situation would become more clear in the future. */ diff --git a/tool/ruby_vm/views/_insn_entry.erb b/tool/ruby_vm/views/_insn_entry.erb deleted file mode 100644 index bdd0fa3c7c..0000000000 --- a/tool/ruby_vm/views/_insn_entry.erb +++ /dev/null @@ -1,76 +0,0 @@ -%# -*- C -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%; -% body = render_c_expr(insn.expr).gsub(/^#/, '# ') - -/* insn <%= insn.pretty_name %> */ -INSN_ENTRY(<%= insn.name %>) -{ - /* ### Declare that we have just entered into an instruction. ### */ - START_OF_ORIGINAL_INSN(<%= insn.name %>); - DEBUG_ENTER_INSN(<%=cstr insn.name %>); - - /* ### Declare and assign variables. ### */ -% insn.preamble.each do |konst| -<%= render_c_expr konst -%> -% end -% -% insn.opes.each_with_index do |ope, i| - <%= ope[:decl] %> = (<%= ope[:type] %>)GET_OPERAND(<%= i + 1 %>); -% end -# define INSN_ATTR(x) <%= insn.call_attribute(' ## x ## ') %> - bool leaf = INSN_ATTR(leaf); -% insn.pops.reverse_each.with_index.reverse_each do |pop, i| - <%= pop[:decl] %> = <%= insn.cast_from_VALUE pop, "TOPN(#{i})"%>; -% end -% -% insn.rets.each do |ret| -% next if insn.has_ope?(ret) or insn.has_pop?(ret) - <%= ret[:decl] %>; -% end - - /* ### Instruction preambles. ### */ - if (! leaf) ADD_PC(INSN_ATTR(width)); -% if insn.handles_sp? - POPN(INSN_ATTR(popn)); -% end -<%= insn.handle_canary "SETUP_CANARY(leaf)" -%> - COLLECT_USAGE_INSN(INSN_ATTR(bin)); -% insn.opes.each_with_index do |ope, i| - COLLECT_USAGE_OPERAND(INSN_ATTR(bin), <%= i %>, <%= ope[:name] %>); -% end -% unless body.empty? - - /* ### Here we do the instruction body. ### */ -%# NAME_OF_CURRENT_INSN is used in vm_exec.h -# define NAME_OF_CURRENT_INSN <%= insn.name %> -<%= body -%> -# undef NAME_OF_CURRENT_INSN -% end - - /* ### Instruction trailers. ### */ - CHECK_VM_STACK_OVERFLOW_FOR_INSN(VM_REG_CFP, INSN_ATTR(retn)); -<%= insn.handle_canary "CHECK_CANARY(leaf, INSN_ATTR(bin))" -%> -% if insn.handles_sp? -% insn.rets.reverse_each do |ret| - PUSH(<%= insn.cast_to_VALUE ret %>); -% end -% else - INC_SP(INSN_ATTR(sp_inc)); -% insn.rets.reverse_each.with_index do |ret, i| - TOPN(<%= i %>) = <%= insn.cast_to_VALUE ret %>; - VM_ASSERT(!RB_TYPE_P(TOPN(<%= i %>), T_NONE)); - VM_ASSERT(!RB_TYPE_P(TOPN(<%= i %>), T_MOVED)); -% end -% end - if (leaf) ADD_PC(INSN_ATTR(width)); -# undef INSN_ATTR - - /* ### Leave the instruction. ### */ - END_INSN(<%= insn.name %>); -} diff --git a/tool/ruby_vm/views/_insn_len_info.erb b/tool/ruby_vm/views/_insn_len_info.erb deleted file mode 100644 index b292f42fb5..0000000000 --- a/tool/ruby_vm/views/_insn_len_info.erb +++ /dev/null @@ -1,21 +0,0 @@ -%# -*- C -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -CONSTFUNC(MAYBE_UNUSED(static int insn_len(VALUE insn))); - -int -insn_len(VALUE i) -{ - static const char t[] = { -% RubyVM::Instructions.each_slice 23 do |a| - <%= a.map(&:width).join(', ') -%>, -% end - }; - - ASSERT_VM_INSTRUCTION_SIZE(t); - return t[i]; -} diff --git a/tool/ruby_vm/views/_insn_name_info.erb b/tool/ruby_vm/views/_insn_name_info.erb deleted file mode 100644 index 767346093e..0000000000 --- a/tool/ruby_vm/views/_insn_name_info.erb +++ /dev/null @@ -1,38 +0,0 @@ -%# -*- C -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -% -% a = RubyVM::Instructions.map {|i| i.name } -% b = (0...a.size) -% c = a.inject([0]) {|r, i| r << (r[-1] + i.length + 1) } -% c.pop -% -CONSTFUNC(MAYBE_UNUSED(static const char *insn_name(VALUE insn))); - -#ifdef RUBY_VM_INSNS_INFO -const int rb_vm_max_insn_name_size = <%= a.map(&:size).max %>; -#endif - -const char * -insn_name(VALUE i) -{ - static const char x[] = -% a.each do |i| - <%=cstr i%> "\0" -% end - ; - - static const unsigned short y[] = { -% c.each_slice 12 do |d| - <%= d.map {|i| sprintf("%4d", i) }.join(', ') %>, -% end - }; - - ASSERT_VM_INSTRUCTION_SIZE(y); - - return &x[y[i]]; -} diff --git a/tool/ruby_vm/views/_insn_operand_info.erb b/tool/ruby_vm/views/_insn_operand_info.erb deleted file mode 100644 index 69d361521a..0000000000 --- a/tool/ruby_vm/views/_insn_operand_info.erb +++ /dev/null @@ -1,46 +0,0 @@ -%# -*- C -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -% -% a = RubyVM::Instructions.map {|i| i.operands_info } -% b = (0...a.size) -% c = a.inject([0]) {|r, i| r << (r[-1] + i.length + 1) } -% c.pop -% -CONSTFUNC(MAYBE_UNUSED(static const char *insn_op_types(VALUE insn))); -CONSTFUNC(MAYBE_UNUSED(static int insn_op_type(VALUE insn, long pos))); - -const char * -insn_op_types(VALUE i) -{ - static const char x[] = -% a.each_slice 5 do |d| - <%= d.map {|i| sprintf("%-6s", cstr(i)) }.join(' "\0" ') %> "\0" -% end - ; - - static const unsigned short y[] = { -% c.each_slice 12 do |d| - <%= d.map {|i| sprintf("%3d", i) }.join(', ') %>, -% end - }; - - ASSERT_VM_INSTRUCTION_SIZE(y); - - return &x[y[i]]; -} - -int -insn_op_type(VALUE i, long j) -{ - if (j >= insn_len(i)) { - return 0; - } - else { - return insn_op_types(i)[j]; - } -} diff --git a/tool/ruby_vm/views/_insn_sp_pc_dependency.erb b/tool/ruby_vm/views/_insn_sp_pc_dependency.erb deleted file mode 100644 index 95528fbbf4..0000000000 --- a/tool/ruby_vm/views/_insn_sp_pc_dependency.erb +++ /dev/null @@ -1,27 +0,0 @@ -%# -*- C -*- -%# Copyright (c) 2019 Takashi Kokubun. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%# -PUREFUNC(MAYBE_UNUSED(static bool insn_may_depend_on_sp_or_pc(int insn, const VALUE *opes))); - -static bool -insn_may_depend_on_sp_or_pc(int insn, const VALUE *opes) -{ - switch (insn) { -% RubyVM::Instructions.each do |insn| -% # handles_sp?: If true, it requires to move sp in JIT -% # always_leaf?: If false, it may call an arbitrary method. pc should be moved -% # before the call, and the method may refer to caller's pc (lineno). -% unless !insn.is_a?(RubyVM::TraceInstructions) && !insn.handles_sp? && insn.always_leaf? - case <%= insn.bin %>: -% end -% end - return true; - default: - return false; - } -} diff --git a/tool/ruby_vm/views/_insn_type_chars.erb b/tool/ruby_vm/views/_insn_type_chars.erb deleted file mode 100644 index 4e1f63e660..0000000000 --- a/tool/ruby_vm/views/_insn_type_chars.erb +++ /dev/null @@ -1,13 +0,0 @@ -%# -*- C -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -% -enum ruby_insn_type_chars { -% RubyVM::Typemap.each_value do |(c, t)| - <%= t %> = '<%= c %>', -% end -}; diff --git a/tool/ruby_vm/views/_leaf_helpers.erb b/tool/ruby_vm/views/_leaf_helpers.erb deleted file mode 100644 index cbb7373e1c..0000000000 --- a/tool/ruby_vm/views/_leaf_helpers.erb +++ /dev/null @@ -1,55 +0,0 @@ -%# -*- C -*- -%# Copyright (c) 2018 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%; -#line <%= __LINE__ + 1 %> <%=cstr __FILE__ %> - -#include "iseq.h" - -// This is used to tell MJIT that this insn would be leaf if CHECK_INTS didn't exist. -// It should be used only when RUBY_VM_CHECK_INTS is directly written in insns.def. -static bool leafness_of_check_ints = false; - -static bool -leafness_of_defined(rb_num_t op_type) -{ - /* see also: vm_insnhelper.c:vm_defined() */ - switch (op_type) { - case DEFINED_IVAR: - case DEFINED_IVAR2: - case DEFINED_GVAR: - case DEFINED_CVAR: - case DEFINED_YIELD: - case DEFINED_REF: - case DEFINED_ZSUPER: - return false; - case DEFINED_CONST: - case DEFINED_CONST_FROM: - /* has rb_autoload_load(); */ - return false; - case DEFINED_FUNC: - case DEFINED_METHOD: - /* calls #respond_to_missing? */ - return false; - default: - rb_bug("unknown operand %ld: blame @shyouhei.", op_type); - } -} - -static bool -leafness_of_checkmatch(rb_num_t flag) -{ - /* see also: vm_insnhelper.c:check_match() */ - if (flag == VM_CHECKMATCH_TYPE_WHEN) { - return true; - } - else { - /* has rb_funcallv() */ - return false; - } -} -#pragma RubyVM reset source diff --git a/tool/ruby_vm/views/_mjit_compile_getinlinecache.erb b/tool/ruby_vm/views/_mjit_compile_getinlinecache.erb deleted file mode 100644 index 44b7f3286a..0000000000 --- a/tool/ruby_vm/views/_mjit_compile_getinlinecache.erb +++ /dev/null @@ -1,36 +0,0 @@ -% # -*- C -*- -% # Copyright (c) 2020 Takashi Kokubun. All rights reserved. -% # -% # This file is a part of the programming language Ruby. Permission is hereby -% # granted, to either redistribute and/or modify this file, provided that the -% # conditions mentioned in the file COPYING are met. Consult the file for -% # details. -% -% # compiler: Declare dst and ic -% insn.opes.each_with_index do |ope, i| - <%= ope.fetch(:decl) %> = (<%= ope.fetch(:type) %>)operands[<%= i %>]; -% end - -% # compiler: Capture IC values, locking getinlinecache - rb_mjit_before_vm_ic_update(); - rb_serial_t ic_serial = ic->ic_serial; - const rb_cref_t *ic_cref = ic->ic_cref; - VALUE ic_value = ic->value; - rb_mjit_after_vm_ic_update(); - - if (ic_serial && !status->compile_info->disable_const_cache) { -% # JIT: Inline everything in IC, and cancel the slow path - fprintf(f, " if (vm_ic_hit_p((rb_serial_t)%"PRI_SERIALT_PREFIX"u, (const rb_cref_t *)0x%"PRIxVALUE", reg_cfp->ep)) {", ic_serial, (VALUE)ic_cref); - fprintf(f, " stack[%d] = 0x%"PRIxVALUE";\n", b->stack_size, ic_value); - fprintf(f, " goto label_%d;\n", pos + insn_len(insn) + (int)dst); - fprintf(f, " }"); - fprintf(f, " else {"); - fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size); - fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", pos); - fprintf(f, " goto const_cancel;\n"); - fprintf(f, " }"); - -% # compiler: Move JIT compiler's internal stack pointer - b->stack_size += <%= insn.call_attribute('sp_inc') %>; - break; - } diff --git a/tool/ruby_vm/views/_mjit_compile_insn.erb b/tool/ruby_vm/views/_mjit_compile_insn.erb deleted file mode 100644 index f54d1b0e0e..0000000000 --- a/tool/ruby_vm/views/_mjit_compile_insn.erb +++ /dev/null @@ -1,92 +0,0 @@ -% # -*- C -*- -% # Copyright (c) 2018 Takashi Kokubun. All rights reserved. -% # -% # This file is a part of the programming language Ruby. Permission is hereby -% # granted, to either redistribute and/or modify this file, provided that the -% # conditions mentioned in the file COPYING are met. Consult the file for -% # details. - fprintf(f, "{\n"); - { -% # compiler: Prepare operands which may be used by `insn.call_attribute` -% insn.opes.each_with_index do |ope, i| - MAYBE_UNUSED(<%= ope.fetch(:decl) %>) = (<%= ope.fetch(:type) %>)operands[<%= i %>]; -% end -% -% # JIT: Declare stack_size to be used in some macro of _mjit_compile_insn_body.erb - if (status->local_stack_p) { - fprintf(f, " MAYBE_UNUSED(unsigned int) stack_size = %u;\n", b->stack_size); - } -% -% # JIT: Declare variables for operands, popped values and return values -% insn.declarations.each do |decl| - fprintf(f, " <%= decl %>;\n"); -% end - -% # JIT: Set const expressions for `RubyVM::OperandsUnifications` insn -% insn.preamble.each do |amble| - fprintf(f, "<%= amble.expr.sub(/const \S+\s+/, '') %>\n"); -% end -% -% # JIT: Initialize operands -% insn.opes.each_with_index do |ope, i| - fprintf(f, " <%= ope.fetch(:name) %> = (<%= ope.fetch(:type) %>)0x%"PRIxVALUE";", operands[<%= i %>]); -% case ope.fetch(:type) -% when 'ID' - comment_id(f, (ID)operands[<%= i %>]); -% when 'CALL_DATA' - comment_id(f, vm_ci_mid(((CALL_DATA)operands[<%= i %>])->ci)); -% when 'VALUE' - if (SYMBOL_P((VALUE)operands[<%= i %>])) comment_id(f, SYM2ID((VALUE)operands[<%= i %>])); -% end - fprintf(f, "\n"); -% end -% -% # JIT: Initialize popped values -% insn.pops.reverse_each.with_index.reverse_each do |pop, i| - fprintf(f, " <%= pop.fetch(:name) %> = stack[%d];\n", b->stack_size - <%= i + 1 %>); -% end -% -% # JIT: move sp and pc if necessary -<%= render 'mjit_compile_pc_and_sp', locals: { insn: insn } -%> -% -% # JIT: Print insn body in insns.def -<%= render 'mjit_compile_insn_body', locals: { insn: insn } -%> -% -% # JIT: Set return values -% insn.rets.reverse_each.with_index do |ret, i| -% # TOPN(n) = ... - fprintf(f, " stack[%d] = <%= ret.fetch(:name) %>;\n", b->stack_size + (int)<%= insn.call_attribute('sp_inc') %> - <%= i + 1 %>); -% end -% -% # JIT: We should evaluate ISeq modified for TracePoint if it's enabled. Note: This is slow. -% # leaf insn may not cancel JIT. leaf_without_check_ints is covered in RUBY_VM_CHECK_INTS of _mjit_compile_insn_body.erb. -% unless insn.always_leaf? || insn.leaf_without_check_ints? - fprintf(f, " if (UNLIKELY(!mjit_call_p)) {\n"); - fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size + (int)<%= insn.call_attribute('sp_inc') %>); - if (!pc_moved_p) { - fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", next_pos); - } - fprintf(f, " RB_DEBUG_COUNTER_INC(mjit_cancel_invalidate_all);\n"); - fprintf(f, " goto cancel;\n"); - fprintf(f, " }\n"); -% end -% -% # compiler: Move JIT compiler's internal stack pointer - b->stack_size += <%= insn.call_attribute('sp_inc') %>; - } - fprintf(f, "}\n"); -% -% # compiler: If insn has conditional JUMP, the code should go to the branch not targeted by JUMP next. -% if insn.expr.expr =~ /if\s+\([^{}]+\)\s+\{[^{}]+JUMP\([^)]+\);[^{}]+\}/ - if (ALREADY_COMPILED_P(status, pos + insn_len(insn))) { - fprintf(f, "goto label_%d;\n", pos + insn_len(insn)); - } - else { - compile_insns(f, body, b->stack_size, pos + insn_len(insn), status); - } -% end -% -% # compiler: If insn returns (leave) or does longjmp (throw), the branch should no longer be compiled. TODO: create attr for it? -% if insn.expr.expr =~ /\sTHROW_EXCEPTION\([^)]+\);/ || insn.expr.expr =~ /\bvm_pop_frame\(/ - b->finish_p = TRUE; -% end diff --git a/tool/ruby_vm/views/_mjit_compile_insn_body.erb b/tool/ruby_vm/views/_mjit_compile_insn_body.erb deleted file mode 100644 index 187e043837..0000000000 --- a/tool/ruby_vm/views/_mjit_compile_insn_body.erb +++ /dev/null @@ -1,129 +0,0 @@ -% # -*- C -*- -% # Copyright (c) 2018 Takashi Kokubun. All rights reserved. -% # -% # This file is a part of the programming language Ruby. Permission is hereby -% # granted, to either redistribute and/or modify this file, provided that the -% # conditions mentioned in the file COPYING are met. Consult the file for -% # details. -% -% to_cstr = lambda do |line| -% normalized = line.gsub(/\t/, ' ' * 8) -% indented = normalized.sub(/\A(?!#)/, ' ') # avoid indenting preprocessor -% rstring2cstr(indented.rstrip).sub(/"\z/, '\\n"') -% end -% -% # -% # Expand simple macro, which doesn't require dynamic C code. -% # -% expand_simple_macros = lambda do |arg_expr| -% arg_expr.dup.tap do |expr| -% # For `leave`. We can't proceed next ISeq in the same JIT function. -% expr.gsub!(/^(?<indent>\s*)RESTORE_REGS\(\);\n/) do -% indent = Regexp.last_match[:indent] -% <<-end.gsub(/^ +/, '') -% #if OPT_CALL_THREADED_CODE -% #{indent}rb_ec_thread_ptr(ec)->retval = val; -% #{indent}return 0; -% #else -% #{indent}return val; -% #endif -% end -% end -% expr.gsub!(/^(?<indent>\s*)NEXT_INSN\(\);\n/) do -% indent = Regexp.last_match[:indent] -% <<-end.gsub(/^ +/, '') -% #{indent}UNREACHABLE_RETURN(Qundef); -% end -% end -% end -% end -% -% # -% # Print a body of insn, but with macro expansion. -% # -% expand_simple_macros.call(insn.expr.expr).each_line do |line| -% # -% # Expand dynamic macro here (only JUMP for now) -% # -% # TODO: support combination of following macros in the same line -% case line -% when /\A\s+RUBY_VM_CHECK_INTS\(ec\);\s+\z/ -% if insn.leaf_without_check_ints? # lazily move PC and optionalize mjit_call_p here - fprintf(f, " if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(ec))) {\n"); - fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", next_pos); /* ADD_PC(INSN_ATTR(width)); */ - fprintf(f, " rb_threadptr_execute_interrupts(rb_ec_thread_ptr(ec), 0);\n"); - fprintf(f, " if (UNLIKELY(!mjit_call_p)) {\n"); - fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size); - fprintf(f, " RB_DEBUG_COUNTER_INC(mjit_cancel_invalidate_all);\n"); - fprintf(f, " goto cancel;\n"); - fprintf(f, " }\n"); - fprintf(f, " }\n"); -% else - fprintf(f, <%= to_cstr.call(line) %>); -% end -% when /\A\s+JUMP\((?<dest>[^)]+)\);\s+\z/ -% dest = Regexp.last_match[:dest] -% -% if insn.name == 'opt_case_dispatch' # special case... TODO: use another macro to avoid checking name - { - struct case_dispatch_var arg; - arg.f = f; - arg.base_pos = pos + insn_len(insn); - arg.last_value = Qundef; - - fprintf(f, " switch (<%= dest %>) {\n"); - st_foreach(RHASH_TBL_RAW(hash), compile_case_dispatch_each, (VALUE)&arg); - fprintf(f, " case %lu:\n", else_offset); - fprintf(f, " goto label_%lu;\n", arg.base_pos + else_offset); - fprintf(f, " }\n"); - } -% else -% # Before we `goto` next insn, we need to set return values, especially for getinlinecache -% insn.rets.reverse_each.with_index do |ret, i| -% # TOPN(n) = ... - fprintf(f, " stack[%d] = <%= ret.fetch(:name) %>;\n", b->stack_size + (int)<%= insn.call_attribute('sp_inc') %> - <%= i + 1 %>); -% end -% - next_pos = pos + insn_len(insn) + (unsigned int)<%= dest %>; - fprintf(f, " goto label_%d;\n", next_pos); -% end -% when /\A\s+CALL_SIMPLE_METHOD\(\);\s+\z/ -% # For `opt_xxx`'s fallbacks. - if (status->local_stack_p) { - fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size); - } - fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", pos); - fprintf(f, " RB_DEBUG_COUNTER_INC(mjit_cancel_opt_insn);\n"); - fprintf(f, " goto cancel;\n"); -% when /\A(?<prefix>.+\b)INSN_LABEL\((?<name>[^)]+)\)(?<suffix>.+)\z/m -% prefix, name, suffix = Regexp.last_match[:prefix], Regexp.last_match[:name], Regexp.last_match[:suffix] - fprintf(f, " <%= prefix.gsub(/\t/, ' ' * 8) %>INSN_LABEL(<%= name %>_%d)<%= suffix.sub(/\n/, '\n') %>", pos); -% else -% if insn.handles_sp? -% # If insn.handles_sp? is true, cfp->sp might be changed inside insns (like vm_caller_setup_arg_block) -% # and thus we need to use cfp->sp, even when local_stack_p is TRUE. When insn.handles_sp? is true, -% # cfp->sp should be available too because _mjit_compile_pc_and_sp.erb sets it. - fprintf(f, <%= to_cstr.call(line) %>); -% else -% # If local_stack_p is TRUE and insn.handles_sp? is false, stack values are only available in local variables -% # for stack. So we need to replace those macros if local_stack_p is TRUE here. -% case line -% when /\bGET_SP\(\)/ -% # reg_cfp->sp - fprintf(f, <%= to_cstr.call(line.sub(/\bGET_SP\(\)/, '%s')) %>, (status->local_stack_p ? "(stack + stack_size)" : "GET_SP()")); -% when /\bSTACK_ADDR_FROM_TOP\((?<num>[^)]+)\)/ -% # #define STACK_ADDR_FROM_TOP(n) (GET_SP()-(n)) -% num = Regexp.last_match[:num] - fprintf(f, <%= to_cstr.call(line.sub(/\bSTACK_ADDR_FROM_TOP\(([^)]+)\)/, '%s')) %>, - (status->local_stack_p ? "(stack + (stack_size - (<%= num %>)))" : "STACK_ADDR_FROM_TOP(<%= num %>)")); -% when /\bTOPN\((?<num>[^)]+)\)/ -% # #define TOPN(n) (*(GET_SP()-(n)-1)) -% num = Regexp.last_match[:num] - fprintf(f, <%= to_cstr.call(line.sub(/\bTOPN\(([^)]+)\)/, '%s')) %>, - (status->local_stack_p ? "*(stack + (stack_size - (<%= num %>) - 1))" : "TOPN(<%= num %>)")); -% else - fprintf(f, <%= to_cstr.call(line) %>); -% end -% end -% end -% end diff --git a/tool/ruby_vm/views/_mjit_compile_invokebuiltin.erb b/tool/ruby_vm/views/_mjit_compile_invokebuiltin.erb deleted file mode 100644 index a3796ffc5e..0000000000 --- a/tool/ruby_vm/views/_mjit_compile_invokebuiltin.erb +++ /dev/null @@ -1,29 +0,0 @@ -% # -*- C -*- -% # Copyright (c) 2020 Urabe, Shyouhei. All rights reserved. -% # -% # This file is a part of the programming language Ruby. Permission is hereby -% # granted, to either redistribute and/or modify this file, provided that the -% # conditions mentioned in the file COPYING are met. Consult the file for -% # details. -% -% insn.opes.each_with_index do |ope, i| - <%= ope.fetch(:decl) %> = (<%= ope.fetch(:type) %>)operands[<%= i %>]; -% end - rb_snum_t sp_inc = <%= insn.call_attribute('sp_inc') %>; - unsigned sp = b->stack_size + (unsigned)sp_inc; - VM_ASSERT(b->stack_size > -sp_inc); - VM_ASSERT(sp_inc < UINT_MAX - b->stack_size); - - if (bf->compiler) { - fprintf(f, "{\n"); - fprintf(f, " VALUE val;\n"); - bf->compiler(f, <%= - insn.name == 'invokebuiltin' ? '-1' : '(rb_num_t)operands[1]' - %>, b->stack_size, body->builtin_inline_p); - fprintf(f, " stack[%u] = val;\n", sp - 1); - fprintf(f, "}\n"); -% if insn.name != 'opt_invokebuiltin_delegate_leave' - b->stack_size = sp; - break; -% end - } diff --git a/tool/ruby_vm/views/_mjit_compile_ivar.erb b/tool/ruby_vm/views/_mjit_compile_ivar.erb deleted file mode 100644 index 5105584ba3..0000000000 --- a/tool/ruby_vm/views/_mjit_compile_ivar.erb +++ /dev/null @@ -1,101 +0,0 @@ -% # -*- C -*- -% # Copyright (c) 2018 Takashi Kokubun. All rights reserved. -% # -% # This file is a part of the programming language Ruby. Permission is hereby -% # granted, to either redistribute and/or modify this file, provided that the -% # conditions mentioned in the file COPYING are met. Consult the file for -% # details. -% -% # Optimized case of get_instancevariable instruction. -#if OPT_IC_FOR_IVAR -{ -% # compiler: Prepare operands which may be used by `insn.call_attribute` -% insn.opes.each_with_index do |ope, i| - MAYBE_UNUSED(<%= ope.fetch(:decl) %>) = (<%= ope.fetch(:type) %>)operands[<%= i %>]; -% end -% # compiler: Use copied IVC to avoid race condition - IVC ic_copy = &(status->is_entries + ((union iseq_inline_storage_entry *)ic - body->is_entries))->iv_cache; -% - if (!status->compile_info->disable_ivar_cache && ic_copy->entry) { // Only ic_copy is enabled. -% # JIT: optimize away motion of sp and pc. This path does not call rb_warning() and so it's always leaf and not `handles_sp`. -% # <%= render 'mjit_compile_pc_and_sp', locals: { insn: insn } -%> -% -% # JIT: prepare vm_getivar/vm_setivar arguments and variables - fprintf(f, "{\n"); - fprintf(f, " VALUE obj = GET_SELF();\n"); - fprintf(f, " const uint32_t index = %u;\n", (ic_copy->entry->index)); - if (status->merge_ivar_guards_p) { -% # JIT: Access ivar without checking these VM_ASSERTed prerequisites as we checked them in the beginning of `mjit_compile_body` - fprintf(f, " VM_ASSERT(RB_TYPE_P(obj, T_OBJECT));\n"); - fprintf(f, " VM_ASSERT((rb_serial_t)%"PRI_SERIALT_PREFIX"u == RCLASS_SERIAL(RBASIC(obj)->klass));\n", ic_copy->entry->class_serial); - fprintf(f, " VM_ASSERT(index < ROBJECT_NUMIV(obj));\n"); -% if insn.name == 'setinstancevariable' - fprintf(f, " if (LIKELY(!RB_OBJ_FROZEN_RAW(obj) && %s)) {\n", status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "true" : "RB_FL_ANY_RAW(obj, ROBJECT_EMBED)"); - fprintf(f, " RB_OBJ_WRITE(obj, &ROBJECT(obj)->as.%s, stack[%d]);\n", - status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "heap.ivptr[index]" : "ary[index]", b->stack_size - 1); - fprintf(f, " }\n"); -% else - fprintf(f, " VALUE val;\n"); - fprintf(f, " if (LIKELY(%s && (val = ROBJECT(obj)->as.%s) != Qundef)) {\n", - status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "true" : "RB_FL_ANY_RAW(obj, ROBJECT_EMBED)", - status->max_ivar_index >= ROBJECT_EMBED_LEN_MAX ? "heap.ivptr[index]" : "ary[index]"); - fprintf(f, " stack[%d] = val;\n", b->stack_size); - fprintf(f, " }\n"); -%end - } - else { - fprintf(f, " const rb_serial_t ic_serial = (rb_serial_t)%"PRI_SERIALT_PREFIX"u;\n", ic_copy->entry->class_serial); -% # JIT: cache hit path of vm_getivar/vm_setivar, or cancel JIT (recompile it with exivar) -% if insn.name == 'setinstancevariable' - fprintf(f, " if (LIKELY(RB_TYPE_P(obj, T_OBJECT) && ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass) && index < ROBJECT_NUMIV(obj) && !RB_OBJ_FROZEN_RAW(obj))) {\n"); - fprintf(f, " VALUE *ptr = ROBJECT_IVPTR(obj);\n"); - fprintf(f, " RB_OBJ_WRITE(obj, &ptr[index], stack[%d]);\n", b->stack_size - 1); - fprintf(f, " }\n"); -% else - fprintf(f, " VALUE val;\n"); - fprintf(f, " if (LIKELY(RB_TYPE_P(obj, T_OBJECT) && ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass) && index < ROBJECT_NUMIV(obj) && (val = ROBJECT_IVPTR(obj)[index]) != Qundef)) {\n"); - fprintf(f, " stack[%d] = val;\n", b->stack_size); - fprintf(f, " }\n"); -% end - } - fprintf(f, " else {\n"); - fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", pos); - fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size); - fprintf(f, " goto ivar_cancel;\n"); - fprintf(f, " }\n"); - -% # compiler: Move JIT compiler's internal stack pointer - b->stack_size += <%= insn.call_attribute('sp_inc') %>; - fprintf(f, "}\n"); - break; - } -% if insn.name == 'getinstancevariable' - else if (!status->compile_info->disable_exivar_cache && ic_copy->entry) { -% # JIT: optimize away motion of sp and pc. This path does not call rb_warning() and so it's always leaf and not `handles_sp`. -% # <%= render 'mjit_compile_pc_and_sp', locals: { insn: insn } -%> -% -% # JIT: prepare vm_getivar's arguments and variables - fprintf(f, "{\n"); - fprintf(f, " VALUE obj = GET_SELF();\n"); - fprintf(f, " const rb_serial_t ic_serial = (rb_serial_t)%"PRI_SERIALT_PREFIX"u;\n", ic_copy->entry->class_serial); - fprintf(f, " const uint32_t index = %u;\n", ic_copy->entry->index); -% # JIT: cache hit path of vm_getivar, or cancel JIT (recompile it without any ivar optimization) - fprintf(f, " struct gen_ivtbl *ivtbl;\n"); - fprintf(f, " VALUE val;\n"); - fprintf(f, " if (LIKELY(FL_TEST_RAW(obj, FL_EXIVAR) && ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass) && rb_ivar_generic_ivtbl_lookup(obj, &ivtbl) && index < ivtbl->numiv && (val = ivtbl->ivptr[index]) != Qundef)) {\n"); - fprintf(f, " stack[%d] = val;\n", b->stack_size); - fprintf(f, " }\n"); - fprintf(f, " else {\n"); - fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", pos); - fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size); - fprintf(f, " goto exivar_cancel;\n"); - fprintf(f, " }\n"); - -% # compiler: Move JIT compiler's internal stack pointer - b->stack_size += <%= insn.call_attribute('sp_inc') %>; - fprintf(f, "}\n"); - break; - } -% end -} -#endif // OPT_IC_FOR_IVAR diff --git a/tool/ruby_vm/views/_mjit_compile_pc_and_sp.erb b/tool/ruby_vm/views/_mjit_compile_pc_and_sp.erb deleted file mode 100644 index 390b3ce525..0000000000 --- a/tool/ruby_vm/views/_mjit_compile_pc_and_sp.erb +++ /dev/null @@ -1,38 +0,0 @@ -% # Copyright (c) 2018 Takashi Kokubun. All rights reserved. -% # -% # This file is a part of the programming language Ruby. Permission is hereby -% # granted, to either redistribute and/or modify this file, provided that the -% # conditions mentioned in the file COPYING are met. Consult the file for -% # details. -% -% # JIT: When an insn is leaf, we don't need to Move pc for a catch table on catch_except_p, #caller_locations, -% # and rb_profile_frames. For check_ints, we lazily move PC when we have interruptions. - MAYBE_UNUSED(bool pc_moved_p) = false; - if (<%= !(insn.always_leaf? || insn.leaf_without_check_ints?) %>) { - fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", next_pos); /* ADD_PC(INSN_ATTR(width)); */ - pc_moved_p = true; - } -% -% # JIT: move sp to use or preserve stack variables - if (status->local_stack_p) { -% # sp motion is optimized away for `handles_sp? #=> false` case. -% # Thus sp should be set properly before `goto cancel`. -% if insn.handles_sp? -% # JIT-only behavior (pushing JIT's local variables to VM's stack): - { - rb_snum_t i, push_size; - push_size = -<%= insn.call_attribute('sp_inc') %> + <%= insn.rets.size %> - <%= insn.pops.size %>; - fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %ld;\n", push_size); /* POPN(INSN_ATTR(popn)); */ - for (i = 0; i < push_size; i++) { - fprintf(f, " *(reg_cfp->sp + %ld) = stack[%ld];\n", i - push_size, (rb_snum_t)b->stack_size - push_size + i); - } - } -% end - } - else { -% if insn.handles_sp? - fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size - <%= insn.pops.size %>); /* POPN(INSN_ATTR(popn)); */ -% else - fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size); -% end - } diff --git a/tool/ruby_vm/views/_mjit_compile_send.erb b/tool/ruby_vm/views/_mjit_compile_send.erb deleted file mode 100644 index d1540f69bb..0000000000 --- a/tool/ruby_vm/views/_mjit_compile_send.erb +++ /dev/null @@ -1,117 +0,0 @@ -% # -*- C -*- -% # Copyright (c) 2018 Takashi Kokubun. All rights reserved. -% # -% # This file is a part of the programming language Ruby. Permission is hereby -% # granted, to either redistribute and/or modify this file, provided that the -% # conditions mentioned in the file COPYING are met. Consult the file for -% # details. -% -% # Optimized case of send / opt_send_without_block instructions. -{ -% # compiler: Prepare operands which may be used by `insn.call_attribute` -% insn.opes.each_with_index do |ope, i| - MAYBE_UNUSED(<%= ope.fetch(:decl) %>) = (<%= ope.fetch(:type) %>)operands[<%= i %>]; -% end -% # compiler: Use captured cc to avoid race condition - const struct rb_callcache *captured_cc = captured_cc_entries(status)[call_data_index(cd, body)]; -% -% # compiler: Inline send insn where some supported fastpath is used. - const rb_iseq_t *iseq = NULL; - const CALL_INFO ci = cd->ci; - int kw_splat = IS_ARGS_KW_SPLAT(ci) > 0; - extern bool rb_splat_or_kwargs_p(const struct rb_callinfo *restrict ci); - if (!status->compile_info->disable_send_cache && has_valid_method_type(captured_cc) && ( -% # `CC_SET_FASTPATH(cd->cc, vm_call_cfunc_with_frame, ...)` in `vm_call_cfunc` - (vm_cc_cme(captured_cc)->def->type == VM_METHOD_TYPE_CFUNC - && !rb_splat_or_kwargs_p(ci) && !kw_splat) -% # `CC_SET_FASTPATH(cc, vm_call_iseq_setup_func(...), vm_call_iseq_optimizable_p(...))` in `vm_callee_setup_arg`, -% # and support only non-VM_CALL_TAILCALL path inside it - || (vm_cc_cme(captured_cc)->def->type == VM_METHOD_TYPE_ISEQ - && fastpath_applied_iseq_p(ci, captured_cc, iseq = def_iseq_ptr(vm_cc_cme(captured_cc)->def)) - && !(vm_ci_flag(ci) & VM_CALL_TAILCALL)) - )) { - const bool cfunc_debug = false; // Set true when you want to see inlined cfunc - if (cfunc_debug && vm_cc_cme(captured_cc)->def->type == VM_METHOD_TYPE_CFUNC) - fprintf(stderr, " * %s\n", rb_id2name(vm_ci_mid(ci))); - - int sp_inc = (int)sp_inc_of_sendish(ci); - fprintf(f, "{\n"); - -% # JIT: Invalidate call cache if it requires vm_search_method. This allows to inline some of following things. - bool opt_class_of = !maybe_special_const_class_p(captured_cc->klass); // If true, use RBASIC_CLASS instead of CLASS_OF to reduce code size - fprintf(f, " const struct rb_callcache *cc = (const struct rb_callcache *)0x%"PRIxVALUE";\n", (VALUE)captured_cc); - fprintf(f, " const rb_callable_method_entry_t *cc_cme = (const rb_callable_method_entry_t *)0x%"PRIxVALUE";\n", (VALUE)vm_cc_cme(captured_cc)); - fprintf(f, " const VALUE recv = stack[%d];\n", b->stack_size + sp_inc - 1); - fprintf(f, " if (UNLIKELY(%s || !vm_cc_valid_p(cc, cc_cme, %s(recv)))) {\n", opt_class_of ? "RB_SPECIAL_CONST_P(recv)" : "false", opt_class_of ? "RBASIC_CLASS" : "CLASS_OF"); - fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", pos); - fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size); - fprintf(f, " goto send_cancel;\n"); - fprintf(f, " }\n"); - -% # JIT: move sp and pc if necessary -<%= render 'mjit_compile_pc_and_sp', locals: { insn: insn } -%> - -% # JIT: If ISeq is inlinable, call the inlined method without pushing a frame. - if (iseq && status->inlined_iseqs != NULL && iseq->body == status->inlined_iseqs[pos]) { - fprintf(f, " {\n"); - fprintf(f, " VALUE orig_self = reg_cfp->self;\n"); - fprintf(f, " reg_cfp->self = stack[%d];\n", b->stack_size + sp_inc - 1); - fprintf(f, " stack[%d] = _mjit%d_inlined_%d(ec, reg_cfp, orig_self, original_iseq);\n", b->stack_size + sp_inc - 1, status->compiled_id, pos); - fprintf(f, " reg_cfp->self = orig_self;\n"); - fprintf(f, " }\n"); - } - else { -% # JIT: Forked `vm_sendish` (except method_explorer = vm_search_method_wrap) to inline various things - fprintf(f, " {\n"); - fprintf(f, " VALUE val;\n"); - fprintf(f, " struct rb_calling_info calling;\n"); -% if insn.name == 'send' - fprintf(f, " calling.block_handler = vm_caller_setup_arg_block(ec, reg_cfp, (const struct rb_callinfo *)0x%"PRIxVALUE", (rb_iseq_t *)0x%"PRIxVALUE", FALSE);\n", (VALUE)ci, (VALUE)blockiseq); -% else - fprintf(f, " calling.block_handler = VM_BLOCK_HANDLER_NONE;\n"); -% end - fprintf(f, " calling.kw_splat = %d;\n", kw_splat); - fprintf(f, " calling.recv = stack[%d];\n", b->stack_size + sp_inc - 1); - fprintf(f, " calling.argc = %d;\n", vm_ci_argc(ci)); - - if (vm_cc_cme(captured_cc)->def->type == VM_METHOD_TYPE_CFUNC) { -% # TODO: optimize this more - fprintf(f, " calling.ci = (CALL_INFO)0x%"PRIxVALUE";\n", (VALUE)ci); // creating local cd here because operand's cd->cc may not be the same as inlined cc. - fprintf(f, " calling.cc = cc;"); - fprintf(f, " val = vm_call_cfunc_with_frame(ec, reg_cfp, &calling);\n"); - } - else { // VM_METHOD_TYPE_ISEQ -% # fastpath_applied_iseq_p checks rb_simple_iseq_p, which ensures has_opt == FALSE - fprintf(f, " vm_call_iseq_setup_normal(ec, reg_cfp, &calling, cc_cme, 0, %d, %d);\n", iseq->body->param.size, iseq->body->local_table_size); - if (iseq->body->catch_except_p) { - fprintf(f, " VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);\n"); - fprintf(f, " val = vm_exec(ec, true);\n"); - } - else { - fprintf(f, " if ((val = mjit_exec(ec)) == Qundef) {\n"); - fprintf(f, " VM_ENV_FLAGS_SET(ec->cfp->ep, VM_FRAME_FLAG_FINISH);\n"); // This is vm_call0_body's code after vm_call_iseq_setup - fprintf(f, " val = vm_exec(ec, false);\n"); - fprintf(f, " }\n"); - } - } - fprintf(f, " stack[%d] = val;\n", b->stack_size + sp_inc - 1); - fprintf(f, " }\n"); - -% # JIT: We should evaluate ISeq modified for TracePoint if it's enabled. Note: This is slow. - fprintf(f, " if (UNLIKELY(!mjit_call_p)) {\n"); - fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size + (int)<%= insn.call_attribute('sp_inc') %>); - if (!pc_moved_p) { - fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", next_pos); - } - fprintf(f, " RB_DEBUG_COUNTER_INC(mjit_cancel_invalidate_all);\n"); - fprintf(f, " goto cancel;\n"); - fprintf(f, " }\n"); - } - -% # compiler: Move JIT compiler's internal stack pointer - b->stack_size += <%= insn.call_attribute('sp_inc') %>; - - fprintf(f, "}\n"); - break; - } -} diff --git a/tool/ruby_vm/views/_notice.erb b/tool/ruby_vm/views/_notice.erb deleted file mode 100644 index d17e019727..0000000000 --- a/tool/ruby_vm/views/_notice.erb +++ /dev/null @@ -1,22 +0,0 @@ -%# -*- C -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%; -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%; -%; -/*******************************************************************/ -/*******************************************************************/ -/*******************************************************************/ -/** - This file <%= this_file %>. - - ---- - This file is auto generated by insns2vm.rb - DO NOT TOUCH! - - If you want to fix something, you must edit <%= cstr edit %> - or tool/insns2vm.rb - */ diff --git a/tool/ruby_vm/views/_sp_inc_helpers.erb b/tool/ruby_vm/views/_sp_inc_helpers.erb deleted file mode 100644 index d0b0bd79ef..0000000000 --- a/tool/ruby_vm/views/_sp_inc_helpers.erb +++ /dev/null @@ -1,37 +0,0 @@ -%# -*- C -*- -%# Copyright (c) 2018 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%; -#line <%= __LINE__ + 1 %> <%=cstr __FILE__ %> - -static rb_snum_t -sp_inc_of_sendish(const struct rb_callinfo *ci) -{ - /* Send-ish instructions will: - * - * 1. Pop block argument, if any. - * 2. Pop ordinal arguments. - * 3. Pop receiver. - * 4. Push return value. - */ - const int argb = (vm_ci_flag(ci) & VM_CALL_ARGS_BLOCKARG) ? 1 : 0; - const int argc = vm_ci_argc(ci); - const int recv = 1; - const int retn = 1; - - /* 1. 2. 3. 4. */ - return 0 - argb - argc - recv + retn; -} - -static rb_snum_t -sp_inc_of_invokeblock(const struct rb_callinfo *ci) -{ - /* sp_inc of invokeblock is almost identical to that of sendish - * instructions, except that it does not pop receiver. */ - return sp_inc_of_sendish(ci) + 1; -} -#pragma RubyVM reset source diff --git a/tool/ruby_vm/views/_trace_instruction.erb b/tool/ruby_vm/views/_trace_instruction.erb deleted file mode 100644 index d604e0318b..0000000000 --- a/tool/ruby_vm/views/_trace_instruction.erb +++ /dev/null @@ -1,16 +0,0 @@ -%# -*- C -*- -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -%; - -/* insn <%= insn.pretty_name %> */ -INSN_ENTRY(<%= insn.name %>) -{ - vm_trace(ec, GET_CFP()); - DISPATCH_ORIGINAL_INSN(<%= insn.jump_destination %>); - END_INSN(<%= insn.name %>); -} diff --git a/tool/ruby_vm/views/insns.inc.erb b/tool/ruby_vm/views/insns.inc.erb deleted file mode 100644 index 29981a8a2d..0000000000 --- a/tool/ruby_vm/views/insns.inc.erb +++ /dev/null @@ -1,26 +0,0 @@ -/* -*- C -*- */ - -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -<%= render 'copyright' %> -<%= render 'notice', locals: { - this_file: 'contains YARV instruction list', - edit: __FILE__, -} -%> - -/* BIN : Basic Instruction Name */ -#define BIN(n) YARVINSN_##n - -enum ruby_vminsn_type { -% RubyVM::Instructions.each do |i| - <%= i.bin %>, -% end - VM_INSTRUCTION_SIZE -}; - -#define ASSERT_VM_INSTRUCTION_SIZE(array) \ - STATIC_ASSERT(numberof_##array, numberof(array) == VM_INSTRUCTION_SIZE) diff --git a/tool/ruby_vm/views/insns_info.inc.erb b/tool/ruby_vm/views/insns_info.inc.erb deleted file mode 100644 index 2ca5aca7cf..0000000000 --- a/tool/ruby_vm/views/insns_info.inc.erb +++ /dev/null @@ -1,22 +0,0 @@ -/* -*- C -*- */ - -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -<%= render 'copyright' %> -<%= render 'notice', locals: { - this_file: 'contains instruction information for yarv instruction sequence.', - edit: __FILE__, -} %> -<%= render 'insn_type_chars' %> -<%= render 'insn_name_info' %> -<%= render 'insn_len_info' %> -<%= render 'insn_operand_info' %> -<%= render 'leaf_helpers' %> -<%= render 'sp_inc_helpers' %> -<%= render 'attributes' %> -<%= render 'comptime_insn_stack_increase' %> -<%= render 'insn_sp_pc_dependency' %> diff --git a/tool/ruby_vm/views/mjit_compile.inc.erb b/tool/ruby_vm/views/mjit_compile.inc.erb deleted file mode 100644 index 937cb4a6d0..0000000000 --- a/tool/ruby_vm/views/mjit_compile.inc.erb +++ /dev/null @@ -1,111 +0,0 @@ -/* -*- C -*- */ - -% # Copyright (c) 2018 Takashi Kokubun. All rights reserved. -% # -% # This file is a part of the programming language Ruby. Permission is hereby -% # granted, to either redistribute and/or modify this file, provided that the -% # conditions mentioned in the file COPYING are met. Consult the file for -% # details. -<%= render 'copyright' %> -% -% # This is an ERB template that generates Ruby code that generates C code that -% # generates JIT-ed C code. -<%= render 'notice', locals: { - this_file: 'is the main part of compile_insn() in mjit_compile.c', - edit: __FILE__, -} -%> -% -% unsupported_insns = [ -% 'defineclass', # low priority -% ] -% -% opt_send_without_block = RubyVM::Instructions.find { |i| i.name == 'opt_send_without_block' } -% if opt_send_without_block.nil? -% raise 'opt_send_without_block not found' -% end -% -% send_compatible_opt_insns = RubyVM::BareInstructions.to_a.select do |insn| -% insn.name.start_with?('opt_') && opt_send_without_block.opes == insn.opes && -% insn.expr.expr.lines.any? { |l| l.match(/\A\s+CALL_SIMPLE_METHOD\(\);\s+\z/) } -% end.map(&:name) -% -% # Available variables and macros in JIT-ed function: -% # ec: the first argument of _mjitXXX -% # reg_cfp: the second argument of _mjitXXX -% # GET_CFP(): refers to `reg_cfp` -% # GET_EP(): refers to `reg_cfp->ep` -% # GET_SP(): refers to `reg_cfp->sp`, or `(stack + stack_size)` if local_stack_p -% # GET_SELF(): refers to `cfp_self` -% # GET_LEP(): refers to `VM_EP_LEP(reg_cfp->ep)` -% # EXEC_EC_CFP(): refers to `val = vm_exec(ec, true)` with frame setup -% # CALL_METHOD(): using `GET_CFP()` and `EXEC_EC_CFP()` -% # TOPN(): refers to `reg_cfp->sp`, or `*(stack + (stack_size - num - 1))` if local_stack_p -% # STACK_ADDR_FROM_TOP(): refers to `reg_cfp->sp`, or `stack + (stack_size - num)` if local_stack_p -% # DISPATCH_ORIGINAL_INSN(): expanded in _mjit_compile_insn.erb -% # THROW_EXCEPTION(): specially defined for JIT -% # RESTORE_REGS(): specially defined for `leave` - -switch (insn) { -% (RubyVM::BareInstructions.to_a + RubyVM::OperandsUnifications.to_a).each do |insn| -% next if unsupported_insns.include?(insn.name) - case BIN(<%= insn.name %>): { -% # Instruction-specific behavior in JIT -% case insn.name -% when 'opt_send_without_block', 'send' -<%= render 'mjit_compile_send', locals: { insn: insn } -%> -% when *send_compatible_opt_insns -% # To avoid cancel, just emit `opt_send_without_block` instead of `opt_*` insn if call cache is populated. -% cd_index = insn.opes.index { |o| o.fetch(:type) == 'CALL_DATA' } - if (has_cache_for_send(captured_cc_entries(status)[call_data_index((CALL_DATA)operands[<%= cd_index %>], body)], BIN(<%= insn.name %>))) { -<%= render 'mjit_compile_send', locals: { insn: opt_send_without_block } -%> -<%= render 'mjit_compile_insn', locals: { insn: opt_send_without_block } -%> - break; - } -% when 'getinstancevariable', 'setinstancevariable' -<%= render 'mjit_compile_ivar', locals: { insn: insn } -%> -% when 'invokebuiltin', 'opt_invokebuiltin_delegate' -<%= render 'mjit_compile_invokebuiltin', locals: { insn: insn } -%> -% when 'opt_getinlinecache' -<%= render 'mjit_compile_getinlinecache', locals: { insn: insn } -%> -% when 'leave', 'opt_invokebuiltin_delegate_leave' -% # opt_invokebuiltin_delegate_leave also implements leave insn. We need to handle it here for inlining. -% if insn.name == 'opt_invokebuiltin_delegate_leave' -<%= render 'mjit_compile_invokebuiltin', locals: { insn: insn } -%> -% else - if (b->stack_size != 1) { - if (mjit_opts.warnings || mjit_opts.verbose) - fprintf(stderr, "MJIT warning: Unexpected JIT stack_size on leave: %d\n", b->stack_size); - status->success = false; - } -% end -% # Skip vm_pop_frame for inlined call - if (status->inlined_iseqs != NULL) { // the current ISeq is NOT being inlined -% # Cancel on interrupts to make leave insn leaf - fprintf(f, " if (UNLIKELY(RUBY_VM_INTERRUPTED_ANY(ec))) {\n"); - fprintf(f, " reg_cfp->sp = vm_base_ptr(reg_cfp) + %d;\n", b->stack_size); - fprintf(f, " reg_cfp->pc = original_body_iseq + %d;\n", pos); - fprintf(f, " RB_DEBUG_COUNTER_INC(mjit_cancel_leave);\n"); - fprintf(f, " goto cancel;\n"); - fprintf(f, " }\n"); - fprintf(f, " ec->cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(reg_cfp);\n"); // vm_pop_frame - } - fprintf(f, " return stack[0];\n"); - b->stack_size += <%= insn.call_attribute('sp_inc') %>; - b->finish_p = TRUE; - break; -% end -% -% # Main insn implementation generated by insns.def -<%= render 'mjit_compile_insn', locals: { insn: insn } -%> - break; - } -% end -% -% # We don't support InstructionsUnifications yet because it's not used for now. -% # We don't support TraceInstructions yet. There is no blocker for it but it's just not implemented. - default: - if (mjit_opts.warnings || mjit_opts.verbose) - fprintf(stderr, "MJIT warning: Skipped to compile unsupported instruction: %s\n", insn_name(insn)); - status->success = false; - break; -} diff --git a/tool/ruby_vm/views/opt_sc.inc.erb b/tool/ruby_vm/views/opt_sc.inc.erb deleted file mode 100644 index e58c81989f..0000000000 --- a/tool/ruby_vm/views/opt_sc.inc.erb +++ /dev/null @@ -1,40 +0,0 @@ -/* -*- C -*- */ - -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -% raise ':FIXME:TBW' if RubyVM::VmOptsH['STACK_CACHING'] -<%= render 'copyright' %> -<%= render 'notice', locals: { - this_file: 'is for threaded code', - edit: __FILE__, -} -%> - -#define SC_STATE_SIZE 6 - -#define SCS_XX 1 -#define SCS_AX 2 -#define SCS_BX 3 -#define SCS_AB 4 -#define SCS_BA 5 - -#define SC_ERROR 0xffffffff - -static const VALUE sc_insn_info[][SC_STATE_SIZE] = { -#define NO_SC { SC_ERROR, SC_ERROR, SC_ERROR, SC_ERROR, SC_ERROR, SC_ERROR } -% RubyVM::Instructions.each_slice 8 do |a| - <%= a.map{|i| 'NO_SC' }.join(', ') %>, -% end -#undef NO_SC -}; - -static const VALUE sc_insn_next[] = { -% RubyVM::Instructions.each_slice 8 do |a| - <%= a.map{|i| 'SCS_XX' }.join(', ') %>, -% end -}; - -ASSERT_VM_INSTRUCTION_SIZE(sc_insn_next); diff --git a/tool/ruby_vm/views/optinsn.inc.erb b/tool/ruby_vm/views/optinsn.inc.erb deleted file mode 100644 index 676f1edaba..0000000000 --- a/tool/ruby_vm/views/optinsn.inc.erb +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- C -*- */ - -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -<%= render 'copyright' -%> -<%= render 'notice', locals: { - this_file: 'is for threaded code', - edit: __FILE__, -} -%> - -static INSN * -insn_operands_unification(INSN *iobj) -{ -#ifdef OPT_OPERANDS_UNIFICATION - VALUE *op = iobj->operands; - - switch (iobj->insn_id) { - default: - /* do nothing */; - break; - -% RubyVM::OperandsUnifications.each_group do |orig, unifs| - case <%= orig.bin %>: -% unifs.each do |insn| - - /* <%= insn.pretty_name %> */ - if ( <%= insn.condition('op') %> ) { -% insn.opes.each_with_index do |o, x| -% n = insn.operand_shift_of(o) -% if n != 0 then - op[<%= x %>] = op[<%= x + n %>]; -% end -% end - iobj->insn_id = <%= insn.bin %>; - iobj->operand_size = <%= insn.opes.size %>; - break; - } -% end - - break; -% end - } -#endif - return iobj; -} - -int -rb_insn_unified_local_var_level(VALUE insn) -{ -#ifdef OPT_OPERANDS_UNIFICATION - /* optimize rule */ - switch (insn) { - default: - return -1; /* do nothing */; -% RubyVM::OperandsUnifications.each_group do |orig, unifs| -% unifs.each do|insn| - case <%= insn.bin %>: -% insn.spec.map{|(var,val)|val}.reject{|i| i == '*' }.each do |val| - return <%= val %>; -% break -% end -% end -% end - } -#endif - return -1; -} diff --git a/tool/ruby_vm/views/optunifs.inc.erb b/tool/ruby_vm/views/optunifs.inc.erb deleted file mode 100644 index e92a95beff..0000000000 --- a/tool/ruby_vm/views/optunifs.inc.erb +++ /dev/null @@ -1,21 +0,0 @@ -/* -*- C -*- */ - -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -% raise ':FIXME:TBW' if RubyVM::VmOptsH['INSTRUCTIONS_UNIFICATION'] -% n = RubyVM::Instructions.size -<%= render 'copyright' %> -<%= render 'notice', locals: { - this_file: 'is for threaded code', - edit: __FILE__, -} -%> - -/* Let .bss section automatically initialize this variable */ -/* cf. Section 6.7.8 of ISO/IEC 9899:1999 */ -static const int *const *const unified_insns_data[<%= n %>]; - -ASSERT_VM_INSTRUCTION_SIZE(unified_insns_data); diff --git a/tool/ruby_vm/views/vm.inc.erb b/tool/ruby_vm/views/vm.inc.erb deleted file mode 100644 index c1a3faf60a..0000000000 --- a/tool/ruby_vm/views/vm.inc.erb +++ /dev/null @@ -1,30 +0,0 @@ -/* -*- C -*- */ - -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -<%= render 'copyright' %> -<%= render 'notice', locals: { - this_file: 'is VM main loop', - edit: __FILE__, -} -%> - -#include "vm_insnhelper.h" -% RubyVM::BareInstructions.to_a.each do |insn| -<%= render 'insn_entry', locals: { insn: insn } -%> -% end -% -% RubyVM::OperandsUnifications.to_a.each do |insn| -<%= render 'insn_entry', locals: { insn: insn } -%> -% end -% -% RubyVM::InstructionsUnifications.to_a.each do |insn| -<%= render 'insn_entry', locals: { insn: insn } -%> -% end -% -% RubyVM::TraceInstructions.to_a.each do |insn| -<%= render 'trace_instruction', locals: { insn: insn } -%> -% end diff --git a/tool/ruby_vm/views/vmtc.inc.erb b/tool/ruby_vm/views/vmtc.inc.erb deleted file mode 100644 index 99cbd92614..0000000000 --- a/tool/ruby_vm/views/vmtc.inc.erb +++ /dev/null @@ -1,21 +0,0 @@ -/* -*- C -*- */ - -%# Copyright (c) 2017 Urabe, Shyouhei. All rights reserved. -%# -%# This file is a part of the programming language Ruby. Permission is hereby -%# granted, to either redistribute and/or modify this file, provided that the -%# conditions mentioned in the file COPYING are met. Consult the file for -%# details. -<%= render 'copyright' -%> -<%= render 'notice', locals: { - this_file: 'is for threaded code', - edit: __FILE__, -} -%> - -static const void *const insns_address_table[] = { -% RubyVM::Instructions.each do |i| - LABEL_PTR(<%= i.name %>), -% end -}; - -ASSERT_VM_INSTRUCTION_SIZE(insns_address_table); |
