Ruby 2.2.0 リファレンスマニュアル > ライブラリ一覧 > 組み込みライブラリ > RubyVM::InstructionSequenceクラス

class RubyVM::InstructionSequence

クラスの継承リスト: RubyVM::InstructionSequence < Object < Kernel < BasicObject

要約

Ruby の Virtual Machine のコンパイル済みの命令シーケンスを表すクラスです。

MethodProc オブジェクトや Ruby のソースコードを表す文字列 から VM の命令シーケンスを得る事ができます。また、 RubyVM::InstructionSequence オブジェクトを元に命令シーケンスを読みやす い文字列に変換する事もできます。Ruby の命令シーケンスコンパイラの設定を 扱う必要がありますが、Ruby の VM がどのように働くかを知るのに有用です。

VM の命令シーケンスの一覧はRuby のソースコード中の insns.def から参照で きます。

目次

特異メソッド
compile new compile_file compile_option compile_option= disasm disassemble of
インスタンスメソッド
absolute_path base_label disasm disassemble eval first_lineno inspect label path to_a

特異メソッド

compile(source, file = nil, path = nil, line = 1, options = nil) -> RubyVM::InstructionSequence[permalink][rdoc]
new(source, file = nil, path = nil, line = 1, options = nil) -> RubyVM::InstructionSequence

引数 source で指定した Ruby のソースコードを元にコンパイル済みの RubyVM::InstructionSequence オブジェクトを作成して返します。

[PARAM] source:
Ruby のソースコードを文字列で指定します。
[PARAM] file:
ファイル名を文字列で指定します。
[PARAM] path:
引数 file の絶対パスファイル名を文字列で指定します。
[PARAM] line:
引数 source の 1 行目の行番号を指定します。
[PARAM] options:
コンパイル時のオプションを true、false、Hash オブ ジェクトのいずれかで指定します。詳細は RubyVM::InstructionSequence.compile_option= を参照 してください。
RubyVM::InstructionSequence.compile("a = 1 + 2")
# => <RubyVM::InstructionSequence:<compiled>@<compiled>>

[SEE_ALSO] RubyVM::InstructionSequence.compile_file

compile_file(file, options = nil) -> RubyVM::InstructionSequence[permalink][rdoc]

引数 file で指定した Ruby のソースコードを元にコンパイル済みの RubyVM::InstructionSequence オブジェクトを作成して返します。

RubyVM::InstructionSequence.compile とは異なり、file、path などの メタデータは自動的に取得します。

[PARAM] file:
ファイル名を文字列で指定します。
[PARAM] options:
コンパイル時のオプションを true、false、Hash オブ ジェクトのいずれかで指定します。詳細は RubyVM::InstructionSequence.compile_option= を参照 してください。
# /tmp/hello.rb
puts "Hello, world!"

# irb
RubyVM::InstructionSequence.compile_file("/tmp/hello.rb")
# => <RubyVM::InstructionSequence:<main>@/tmp/hello.rb>

[SEE_ALSO] RubyVM::InstructionSequence.compile

compile_option -> Hash[permalink][rdoc]

命令シーケンスのコンパイル時のデフォルトの最適化オプションを Hash で返 します。

[SEE_ALSO] RubyVM::InstructionSequence.compile_option=

compile_option=(options)[permalink][rdoc]

命令シーケンスのコンパイル時のデフォルトの最適化オプションを引数 options で指定します。

[PARAM] options:
コンパイル時の最適化オプションを true、false、nil、 Hash のいずれかで指定します。true を指定した場合は 全てのオプションを有効にします。false を指定した場合は全 てのオプションを無効にします。nil を指定した場合はいずれ のオプションも変更しません。また、Hash を指定した 場合は以下のキーに対して、true か false を指定する事で個 別に有効、無効を指定します。
  * :inline_const_cache
  * :instructions_unification
  * :operands_unification
  * :peephole_optimization
  * :specialized_instruction
  * :stack_caching
  * :tailcall_optimization
  * :trace_instruction
:debug_level をキーに指定した場合は値を数値で指定します。

.new、.compile、.compile_file メソッドの実行の際に option 引数を指定し た場合はその実行のみ最適化オプションを変更する事もできます。

[SEE_ALSO] RubyVM::InstructionSequence.new, RubyVM::InstructionSequence.compile, RubyVM::InstructionSequence.compile_file

disasm(body) -> String[permalink][rdoc]
disassemble(body) -> String

引数 body で指定したオブジェクトから作成した RubyVM::InstructionSequence オブジェクトを人間が読める形式の文字 列に変換して返します。

[PARAM] body:
ProcMethod オブジェクトを指定します。

例1:Proc オブジェクトを指定した場合

# /tmp/proc.rb
p = proc { num = 1 + 2 }
puts RubyVM::InstructionSequence.disasm(p)

出力:

== disasm: <RubyVM::InstructionSequence:block in <main>@/tmp/proc.rb>===
== catch table
| catch type: redo   st: 0000 ed: 0012 sp: 0000 cont: 0000
| catch type: next   st: 0000 ed: 0012 sp: 0000 cont: 0012
|------------------------------------------------------------------------
local table (size: 2, argc: 0 [opts: 0, rest: -1, post: 0, block: -1] s1)
[ 2] num
0000 trace            1                                               (   1)
0002 putobject        1
0004 putobject        2
0006 opt_plus         <ic:1>
0008 dup
0009 setlocal         num, 0
0012 leave

例2:Method オブジェクトを指定した場合

# /tmp/method.rb
def hello
  puts "hello, world"
end

puts RubyVM::InstructionSequence.disasm(method(:hello))

出力:

== disasm: <RubyVM::InstructionSequence:hello@/tmp/method.rb>============
0000 trace            8                                               (   1)
0002 trace            1                                               (   2)
0004 putself
0005 putstring        "hello, world"
0007 send             :puts, 1, nil, 8, <ic:0>
0013 trace            16                                              (   3)
0015 leave                                                            (   2)

[SEE_ALSO] RubyVM::InstructionSequence#disasm

of(body) -> RubyVM::InstructionSequence[permalink][rdoc]

引数 body で指定した ProcMethod オブジェクトを元に RubyVM::InstructionSequence オブジェクトを作成して返します。

[PARAM] body:
ProcMethod オブジェクトを指定します。

例1:irb で実行した場合

# proc
> p = proc { num = 1 + 2 }
> RubyVM::InstructionSequence.of(p)
> # => <RubyVM::InstructionSequence:block in irb_binding@(irb)>

# method
> def foo(bar); puts bar; end
> RubyVM::InstructionSequence.of(method(:foo))
> # => <RubyVM::InstructionSequence:foo@(irb)>

例2: RubyVM::InstructionSequence.compile_file を使用した場合

# /tmp/iseq_of.rb
def hello
  puts "hello, world"
end

$a_global_proc = proc { str = 'a' + 'b' }

# irb
> require '/tmp/iseq_of.rb'

# hello メソッド
> RubyVM::InstructionSequence.of(method(:hello))
> # => #<RubyVM::InstructionSequence:0x007fb73d7cb1d0>

# グローバル proc
> RubyVM::InstructionSequence.of($a_global_proc)
> # => #<RubyVM::InstructionSequence:0x007fb73d7caf78>

インスタンスメソッド

absolute_path -> String | nil[permalink][rdoc]

self が表す命令シーケンスの絶対パスを返します。

self を文字列から作成していた場合は nil を返します。

例1:irb で実行した場合

iseq = RubyVM::InstructionSequence.compile('num = 1 + 2')
# => <RubyVM::InstructionSequence:<compiled>@<compiled>>
iseq.absolute_path
# => nil

例2: RubyVM::InstructionSequence.compile_file を使用した場合

# /tmp/method.rb
def hello
  puts "hello, world"
end

# irb
> iseq = RubyVM::InstructionSequence.compile_file('/tmp/method.rb')
> iseq.absolute_path # => "/tmp/method.rb"

[SEE_ALSO] RubyVM::InstructionSequence#path

base_label -> String[permalink][rdoc]

self が表す命令シーケンスの基本ラベルを返します。

例1:irb で実行した場合

iseq = RubyVM::InstructionSequence.compile('num = 1 + 2')
# => <RubyVM::InstructionSequence:<compiled>@<compiled>>
iseq.base_label
# => "<compiled>"

例2: RubyVM::InstructionSequence.compile_file を使用した場合

# /tmp/method.rb
def hello
  puts "hello, world"
end

# irb
> iseq = RubyVM::InstructionSequence.compile_file('/tmp/method.rb')
> iseq.base_label # => "<main>"

例3:

# /tmp/method2.rb
def hello
  puts "hello, world"
end

RubyVM::InstructionSequence.of(method(:hello)).base_label
# => "hello"

[SEE_ALSO] RubyVM::InstructionSequence#label

disasm -> String[permalink][rdoc]
disassemble -> String

self が表す命令シーケンスを人間が読める形式の文字列に変換して返します。

puts RubyVM::InstructionSequence.compile('1 + 2').disasm

出力:

== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>==========
0000 trace            1                                               (   1)
0002 putobject        1
0004 putobject        2
0006 opt_plus         <ic:1>
0008 leave

[SEE_ALSO] RubyVM::InstructionSequence.disasm

eval -> object[permalink][rdoc]

self の命令シーケンスを評価してその結果を返します。

RubyVM::InstructionSequence.compile("1 + 2").eval # => 3
first_lineno -> Integer[permalink][rdoc]

self が表す命令シーケンスの 1 行目の行番号を返します。

例1:irb で実行した場合

RubyVM::InstructionSequence.compile('num = 1 + 2').first_lineno
# => 1

例2:

# /tmp/method.rb
require "foo-library"
def foo
  p :foo
end

RubyVM::InstructionSequence.of(method(:foo)).first_lineno
# => 2
inspect -> String[permalink][rdoc]

self の情報をラベルとパスを含んだ人間に読みやすい文字列にして返します。



iseq = RubyVM::InstructionSequence.compile('num = 1 + 2')
iseq.inspect # => "<RubyVM::InstructionSequence:<compiled>@<compiled>>"

[SEE_ALSO] RubyVM::InstructionSequence#label, RubyVM::InstructionSequence#path

label -> String[permalink][rdoc]

self が表す命令シーケンスのラベルを返します。通常、メソッド名、クラス名、 モジュール名などで構成されます。

トップレベルでは "<main>" を返します。self を文字列から作成していた場合 は "<compiled>" を返します。

例1:irb で実行した場合

iseq = RubyVM::InstructionSequence.compile('num = 1 + 2')
# => <RubyVM::InstructionSequence:<compiled>@<compiled>>
iseq.label
# => "<compiled>"

例2: RubyVM::InstructionSequence.compile_file を使用した場合

# /tmp/method.rb
def hello
  puts "hello, world"
end

# irb
> iseq = RubyVM::InstructionSequence.compile_file('/tmp/method.rb')
> iseq.label # => "<main>"

例3:

# /tmp/method2.rb
def hello
  puts "hello, world"
end

RubyVM::InstructionSequence.of(method(:hello)).label
# => "hello"

[SEE_ALSO] RubyVM::InstructionSequence#base_label

path -> String[permalink][rdoc]

self が表す命令シーケンスの相対パスを返します。

self の作成時に指定した文字列を返します。self を文字列から作成していた 場合は "<compiled>" を返します。

例1:irb で実行した場合

iseq = RubyVM::InstructionSequence.compile('num = 1 + 2')
# => <RubyVM::InstructionSequence:<compiled>@<compiled>>
iseq.path
# => "<compiled>"

例2: RubyVM::InstructionSequence.compile_file を使用した場合

# /tmp/method.rb
def hello
  puts "hello, world"
end

# irb
> iseq = RubyVM::InstructionSequence.compile_file('method.rb')
> iseq.path # => "method.rb"

[SEE_ALSO] RubyVM::InstructionSequence#absolute_path

to_a -> Array[permalink][rdoc]

self の情報を 14 要素の配列にして返します。

命令シーケンスを以下の情報で表します。

magic

データフォーマットを示す文字列。常に "YARVInstructionSequence/SimpleDataFormat"。

major_version

命令シーケンスのメジャーバージョン。

minor_version

命令シーケンスのマイナーバージョン。

format_type

データフォーマットを示す数値。常に 1。

misc

以下の要素から構成される Hash オブジェクト。

:arg_size: メソッド、ブロックが取る引数の総数(1 つもない場合は 0)。

:local_size: ローカル変数の総数 + 1。

:stack_max: スタックの深さ。(SystemStackError を検出するために使用)

#label

メソッド名、クラス名、モジュール名などで構成される命令シーケンスのラ ベル。トップレベルでは "<main>"。文字列から作成していた場合は "<compiled>"。

#path

命令シーケンスの相対パス。文字列から作成していた場合は "<compiled>"。

#absolute_path

命令シーケンスの絶対パス。文字列から作成していた場合は nil。

#first_lineno

命令シーケンスの 1 行目の行番号。

type

命令シーケンスの種別。 :top、:method、:block、:class、:rescue、:ensure、:eval、:main、 :defined_guard のいずれか。

locals

全ての引数名、ローカル変数名からなる Symbol の配列。

args

引数の指定が必須のメソッド、ブロックの引数の個数。あるいは以下のよう な配列。

[required_argc, [optional_arg_labels, ...], splat_index, post_splat_argc, post_splat_index, block_index, simple]

より詳細な情報については、vm_core.h を参照。

catch_table

例外や制御構造のオペレータ(rescue、next、redo、break など)の一覧。

bytecode

命令シーケンスを構成する命令とオペランドの配列の配列。



require 'pp'

iseq = RubyVM::InstructionSequence.compile('num = 1 + 2')
pp iseq.to_a
# ※ Ruby 2.5.0 での実行結果
# => ["YARVInstructionSequence/SimpleDataFormat",
# 2,
# 0,
# 1,
# {:arg_size=>0, :local_size=>2, :stack_max=>2},
# "<compiled>",
# "<compiled>",
# nil,
# 1,
# :top,
# [:num],
# 0,
# [],
# [1,
#  [:trace, 1],
#  [:putobject_OP_INT2FIX_O_1_C_],
#  [:putobject, 2],
#  [:opt_plus, {:mid=>:+, :flag=>256, :orig_argc=>1, :blockptr=>nil}],
#  [:dup],
#  [:setlocal_OP__WC__0, 2],
#  [:leave]]]