Spec-Zone.ru › Ruby 4.0
  1. RubyVM::
  2. InstructionSequence

class RubyVM::InstructionSequence

Родительский класс:
Object

Класс InstructionSequence представляет скомпилированную последовательность инструкций для виртуальной машины, используемой в MRI. Не все реализации Ruby поддерживают этот класс, а в тех реализациях, где он есть, определённые методы и их поведение могут изменяться в любой версии.

С его помощью можно получить доступ к инструкциям, составляющим метод или proc, скомпилировать строки кода Ruby в инструкции виртуальной машины и дизассемблировать последовательности инструкций в строки для удобного изучения. Класс в основном полезен для изучения принципов работы YARV, но также позволяет управлять различными настройками компилятора iseq Ruby.

Исходный код инструкций виртуальной машины можно найти в insns.def в исходном коде Ruby.

Результаты для последовательностей инструкций почти наверняка будут меняться вместе с Ruby, поэтому примеры вывода в этой документации могут отличаться от того, что вы увидите.

Разумеется, этот класс специфичен для MRI.

Общедоступные методы класса

compile(source[, file[, path[, line[, options]]]]) → iseq Показать исходный код
new(source[, file[, path[, line[, options]]]]) → iseq
static VALUE
iseqw_s_compile(int argc, VALUE *argv, VALUE self)
{
    return iseqw_s_compile_parser(argc, argv, self, rb_ruby_prism_p());
}

Принимает source, которым может быть строка кода Ruby или открытый объект File, содержащий исходный код Ruby.

Необязательно принимает file, path и line, задающие путь к файлу, фактический путь и номер первой строки кода Ruby в source; эти данные являются метаданными, прикрепляемыми к возвращаемому iseq.

file используется для __FILE__ и трассировки стека исключения. path используется как базовый require_relative. Рекомендуется указывать для них один и тот же полный путь.

options, которым может быть true, false или Hash, используется для изменения поведения компилятора iseq Ruby по умолчанию.

Сведения о допустимых параметрах компиляции см. в разделе ::compile_option=.

RubyVM::InstructionSequence.compile("a = 1 + 2")
#=> <RubyVM::InstructionSequence:<compiled>@<compiled>>

path = "test.rb"
RubyVM::InstructionSequence.compile(File.read(path), path, File.expand_path(path))
#=> <RubyVM::InstructionSequence:<compiled>@test.rb:1>

file = File.open("test.rb")
RubyVM::InstructionSequence.compile(file)
#=> <RubyVM::InstructionSequence:<compiled>@<compiled>:1>

path = File.expand_path("test.rb")
RubyVM::InstructionSequence.compile(File.read(path), path, path)
#=> <RubyVM::InstructionSequence:<compiled>@/absolute/path/to/test.rb:1>
compile_file(file[, options]) → iseq Показать исходный код
static VALUE
iseqw_s_compile_file(int argc, VALUE *argv, VALUE self)
{
    VALUE file, opt = Qnil;
    VALUE parser, f, exc = Qnil, ret;
    rb_ast_t *ast;
    VALUE ast_value;
    rb_compile_option_t option;
    int i;

    i = rb_scan_args(argc, argv, "1*:", &file, NULL, &opt);
    if (i > 1+NIL_P(opt)) rb_error_arity(argc, 1, 2);
    switch (i) {
      case 2: opt = argv[--i];
    }
    FilePathValue(file);
    file = rb_fstring(file); /* rb_io_t->pathv gets frozen anyways */

    f = rb_file_open_str(file, "r");

    rb_execution_context_t *ec = GET_EC();
    VALUE v = rb_vm_push_frame_fname(ec, file);

    parser = rb_parser_new();
    rb_parser_set_context(parser, NULL, FALSE);
    ast_value = rb_parser_load_file(parser, file);
    ast = rb_ruby_ast_data_get(ast_value);
    if (!ast->body.root) exc = GET_EC()->errinfo;

    rb_io_close(f);
    if (!ast->body.root) {
        rb_ast_dispose(ast);
        rb_exc_raise(exc);
    }

    make_compile_option(&option, opt);

    ret = iseqw_new(rb_iseq_new_with_opt(ast_value, rb_fstring_lit("<main>"),
                                         file,
                                         rb_realpath_internal(Qnil, file, 1),
                                         1, NULL, 0, ISEQ_TYPE_TOP, &option,
                                         Qnil));
    rb_ast_dispose(ast);
    RB_GC_GUARD(ast_value);

    rb_vm_pop_frame(ec);
    RB_GC_GUARD(v);
    return ret;
}

Принимает file — String, содержащий путь к файлу с исходным кодом Ruby, считывает, анализирует и компилирует файл, а затем возвращает iseq — скомпилированный InstructionSequence с заданными метаданными о расположении исходного кода.

Необязательно принимает options, которым может быть true, false или Hash, чтобы изменить поведение компилятора iseq Ruby по умолчанию.

Сведения о допустимых параметрах компиляции см. в разделе ::compile_option=.

# /tmp/hello.rb
puts "Hello, world!"

# elsewhere
RubyVM::InstructionSequence.compile_file("/tmp/hello.rb")
#=> <RubyVM::InstructionSequence:<main>@/tmp/hello.rb>
compile_file_prism(file[, options]) → iseq Показать исходный код
static VALUE
iseqw_s_compile_file_prism(int argc, VALUE *argv, VALUE self)
{
    VALUE file, opt = Qnil, ret;
    rb_compile_option_t option;
    int i;

    i = rb_scan_args(argc, argv, "1*:", &file, NULL, &opt);
    if (i > 1+NIL_P(opt)) rb_error_arity(argc, 1, 2);
    switch (i) {
      case 2: opt = argv[--i];
    }
    FilePathValue(file);
    file = rb_fstring(file); /* rb_io_t->pathv gets frozen anyways */

    rb_execution_context_t *ec = GET_EC();
    VALUE v = rb_vm_push_frame_fname(ec, file);

    pm_parse_result_t result = { 0 };
    result.options.line = 1;
    result.node.coverage_enabled = 1;

    VALUE script_lines;
    VALUE error = pm_load_parse_file(&result, file, ruby_vm_keep_script_lines ? &script_lines : NULL);

    if (error == Qnil) {
        make_compile_option(&option, opt);

        int error_state;
        rb_iseq_t *iseq = pm_iseq_new_with_opt(&result.node, rb_fstring_lit("<main>"),
                                               file,
                                               rb_realpath_internal(Qnil, file, 1),
                                               1, NULL, 0, ISEQ_TYPE_TOP, &option, &error_state);

        pm_parse_result_free(&result);

        if (error_state) {
            RUBY_ASSERT(iseq == NULL);
            rb_jump_tag(error_state);
        }

        ret = iseqw_new(iseq);
        rb_vm_pop_frame(ec);
        RB_GC_GUARD(v);
        return ret;
    }
    else {
        pm_parse_result_free(&result);
        rb_vm_pop_frame(ec);
        RB_GC_GUARD(v);
        rb_exc_raise(error);
    }
}

Принимает file — String, содержащий путь к файлу с исходным кодом Ruby, считывает, анализирует и компилирует файл, а затем возвращает iseq — скомпилированный InstructionSequence с заданными метаданными о расположении исходного кода. Для анализа и компиляции используется prism.

Необязательно принимает options, которым может быть true, false или Hash, чтобы изменить поведение компилятора iseq Ruby по умолчанию.

Сведения о допустимых параметрах компиляции см. в разделе ::compile_option=.

# /tmp/hello.rb
puts "Hello, world!"

# elsewhere
RubyVM::InstructionSequence.compile_file_prism("/tmp/hello.rb")
#=> <RubyVM::InstructionSequence:<main>@/tmp/hello.rb>
compile_option → options Показать исходный код
static VALUE
iseqw_s_compile_option_get(VALUE self)
{
    return make_compile_option_value(&COMPILE_OPTION_DEFAULT);
}

Возвращает хеш параметров компилятора iseq Ruby, используемых по умолчанию.

Подробности см. в разделе InstructionSequence.compile_option=.

compile_option = options Показать исходный код
static VALUE
iseqw_s_compile_option_set(VALUE self, VALUE opt)
{
    rb_compile_option_t option;
    make_compile_option(&option, opt);
    COMPILE_OPTION_DEFAULT = option;
    return opt;
}

Устанавливает значения по умолчанию для различных оптимизаций компилятора iseq Ruby.

Возможные значения для options: true — включает все параметры; false — отключает все параметры; nil — оставляет все параметры без изменений.

Также можно передать Hash из options, которые требуется изменить; параметры, отсутствующие в хеше, останутся без изменений.

Возможные имена параметров (ключи в options), которым можно присвоить true или false:

  • :inline_const_cache

  • :instructions_unification

  • :operands_unification

  • :peephole_optimization

  • :specialized_instruction

  • :tailcall_optimization

Кроме того, для :debug_level можно задать целое число.

Значения этих параметров по умолчанию можно переопределить для одного запуска компилятора iseq, передав любое из перечисленных выше значений в качестве параметра options методам ::new, ::compile и ::compile_file.

compile_parsey(source[, file[, path[, line[, options]]]]) → iseq Показать исходный код
static VALUE
iseqw_s_compile_parsey(int argc, VALUE *argv, VALUE self)
{
    return iseqw_s_compile_parser(argc, argv, self, false);
}

Принимает source, которым может быть строка кода Ruby или открытый объект File, содержащий исходный код Ruby. Для анализа и компиляции используется parse.y.

Необязательно принимает file, path и line, задающие путь к файлу, фактический путь и номер первой строки кода Ruby в source; эти данные являются метаданными, прикрепляемыми к возвращаемому iseq.

file используется для __FILE__ и трассировки стека исключения. path используется как базовый require_relative. Рекомендуется указывать для них один и тот же полный путь.

options, которым может быть true, false или Hash, используется для изменения поведения компилятора iseq Ruby по умолчанию.

Сведения о допустимых параметрах компиляции см. в разделе ::compile_option=.

RubyVM::InstructionSequence.compile_parsey("a = 1 + 2")
#=> <RubyVM::InstructionSequence:<compiled>@<compiled>>

path = "test.rb"
RubyVM::InstructionSequence.compile_parsey(File.read(path), path, File.expand_path(path))
#=> <RubyVM::InstructionSequence:<compiled>@test.rb:1>

file = File.open("test.rb")
RubyVM::InstructionSequence.compile_parsey(file)
#=> <RubyVM::InstructionSequence:<compiled>@<compiled>:1>

path = File.expand_path("test.rb")
RubyVM::InstructionSequence.compile_parsey(File.read(path), path, path)
#=> <RubyVM::InstructionSequence:<compiled>@/absolute/path/to/test.rb:1>
compile_prism(source[, file[, path[, line[, options]]]]) → iseq Показать исходный код
static VALUE
iseqw_s_compile_prism(int argc, VALUE *argv, VALUE self)
{
    return iseqw_s_compile_parser(argc, argv, self, true);
}

Принимает source, которым может быть строка кода Ruby или открытый объект File, содержащий исходный код Ruby. Для анализа и компиляции используется prism.

Необязательно принимает file, path и line, задающие путь к файлу, фактический путь и номер первой строки кода Ruby в source; эти данные являются метаданными, прикрепляемыми к возвращаемому iseq.

file используется для __FILE__ и трассировки стека исключения. path используется как базовый require_relative. Рекомендуется указывать для них один и тот же полный путь.

options, которым может быть true, false или Hash, используется для изменения поведения компилятора iseq Ruby по умолчанию.

Сведения о допустимых параметрах компиляции см. в разделе ::compile_option=.

RubyVM::InstructionSequence.compile_prism("a = 1 + 2")
#=> <RubyVM::InstructionSequence:<compiled>@<compiled>>

path = "test.rb"
RubyVM::InstructionSequence.compile_prism(File.read(path), path, File.expand_path(path))
#=> <RubyVM::InstructionSequence:<compiled>@test.rb:1>

file = File.open("test.rb")
RubyVM::InstructionSequence.compile_prism(file)
#=> <RubyVM::InstructionSequence:<compiled>@<compiled>:1>

path = File.expand_path("test.rb")
RubyVM::InstructionSequence.compile_prism(File.read(path), path, path)
#=> <RubyVM::InstructionSequence:<compiled>@/absolute/path/to/test.rb:1>
disasm(body) → str Показать исходный код
disassemble(body) → str
static VALUE
iseqw_s_disasm(VALUE klass, VALUE body)
{
    VALUE iseqw = iseqw_s_of(klass, body);
    return NIL_P(iseqw) ? Qnil : rb_iseq_disasm(iseqw_check(iseqw));
}

Принимает body — объект Method или Proc — и возвращает String с удобочитаемым представлением инструкций для body.

Для объекта 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)

Для объекта 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
disasm(body) → str Показать исходный код
disassemble(body) → str
static VALUE
iseqw_s_disasm(VALUE klass, VALUE body)
{
    VALUE iseqw = iseqw_s_of(klass, body);
    return NIL_P(iseqw) ? Qnil : rb_iseq_disasm(iseqw_check(iseqw));
}

Принимает body — объект Method или Proc — и возвращает String с удобочитаемым представлением инструкций для body.

Для объекта 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)

Для объекта 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
RubyVM::InstructionSequence.load_from_binary(binary) → iseq Показать исходный код
static VALUE
iseqw_s_load_from_binary(VALUE self, VALUE str)
{
    return iseqw_new(rb_iseq_ibf_load(str));
}

Загружает объект iseq из объекта String в двоичном формате, созданного методом RubyVM::InstructionSequence.to_binary.

В этом загрузчике нет средства проверки, поэтому загрузка повреждённых или изменённых двоичных данных может привести к критической проблеме.

Не загружайте двоичные данные, предоставленные другими. Используйте двоичные данные, преобразованные самостоятельно.

RubyVM::InstructionSequence.load_from_binary_extra_data(binary) → str Показать исходный код
static VALUE
iseqw_s_load_from_binary_extra_data(VALUE self, VALUE str)
{
    return rb_iseq_ibf_load_extra_data(str);
}

Загружает дополнительные данные, встроенные в объект String в двоичном формате.

compile(source[, file[, path[, line[, options]]]]) → iseq Показать исходный код
new(source[, file[, path[, line[, options]]]]) → iseq
static VALUE
iseqw_s_compile(int argc, VALUE *argv, VALUE self)
{
    return iseqw_s_compile_parser(argc, argv, self, rb_ruby_prism_p());
}

Принимает source, которым может быть строка кода Ruby или открытый объект File, содержащий исходный код Ruby.

Необязательно принимает file, path и line, задающие путь к файлу, фактический путь и номер первой строки кода Ruby в source; эти данные являются метаданными, прикрепляемыми к возвращаемому iseq.

file используется для __FILE__ и трассировки стека исключения. path используется как базовый require_relative. Рекомендуется указывать для них один и тот же полный путь.

options, которым может быть true, false или Hash, используется для изменения поведения компилятора iseq Ruby по умолчанию.

Сведения о допустимых параметрах компиляции см. в разделе ::compile_option=.

RubyVM::InstructionSequence.compile("a = 1 + 2")
#=> <RubyVM::InstructionSequence:<compiled>@<compiled>>

path = "test.rb"
RubyVM::InstructionSequence.compile(File.read(path), path, File.expand_path(path))
#=> <RubyVM::InstructionSequence:<compiled>@test.rb:1>

file = File.open("test.rb")
RubyVM::InstructionSequence.compile(file)
#=> <RubyVM::InstructionSequence:<compiled>@<compiled>:1>

path = File.expand_path("test.rb")
RubyVM::InstructionSequence.compile(File.read(path), path, path)
#=> <RubyVM::InstructionSequence:<compiled>@/absolute/path/to/test.rb:1>
of (p1) Показать исходный код
static VALUE
iseqw_s_of(VALUE klass, VALUE body)
{
    const rb_iseq_t *iseq = NULL;

    if (rb_frame_info_p(body)) {
        iseq = rb_get_iseq_from_frame_info(body);
    }
    else if (rb_obj_is_proc(body)) {
        iseq = vm_proc_iseq(body);

        if (!rb_obj_is_iseq((VALUE)iseq)) {
            iseq = NULL;
        }
    }
    else if (rb_obj_is_method(body)) {
        iseq = rb_method_iseq(body);
    }
    else if (rb_typeddata_is_instance_of(body, &iseqw_data_type)) {
        return body;
    }

    return iseq ? iseqw_new(iseq) : Qnil;
}

Возвращает последовательность инструкций, содержащую указанный proc или метод.

Например, в irb:

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

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

С использованием ::compile_file:

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

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

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

# first the method hello
> RubyVM::InstructionSequence.of(method(:hello))
> #=> #<RubyVM::InstructionSequence:0x007fb73d7cb1d0>

# then the global proc
> RubyVM::InstructionSequence.of($a_global_proc)
> #=> #<RubyVM::InstructionSequence:0x007fb73d7caf78>

Общедоступные методы экземпляра

absolute_path () Показать исходный код
static VALUE
iseqw_absolute_path(VALUE self)
{
    return rb_iseq_realpath(iseqw_check(self));
}

Возвращает абсолютный путь этой последовательности инструкций.

nil, если iseq был вычислен из строки.

Например, с использованием ::compile_file:

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

# in irb
> iseq = RubyVM::InstructionSequence.compile_file('/tmp/method.rb')
> iseq.absolute_path #=> /tmp/method.rb
base_label () Показать исходный код
static VALUE
iseqw_base_label(VALUE self)
{
    return rb_iseq_base_label(iseqw_check(self));
}

Возвращает базовую метку этой последовательности инструкций.

Например, в irb:

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

С использованием ::compile_file:

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

# in irb
> iseq = RubyVM::InstructionSequence.compile_file('/tmp/method.rb')
> iseq.base_label #=> <main>
disasm → str Показать исходный код
static VALUE
iseqw_disasm(VALUE self)
{
    return rb_iseq_disasm(iseqw_check(self));
}

Возвращает последовательность инструкций в удобочитаемом виде как String.

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
Также имеет псевдонимы: disassemble, disassemble
disassemble → str

Возвращает последовательность инструкций в удобочитаемом виде как String.

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
Псевдоним метода: disasm
each_child{|child_iseq| ...} → iseq Показать исходный код
static VALUE
iseqw_each_child(VALUE self)
{
    const rb_iseq_t *iseq = iseqw_check(self);
    iseq_iterate_children(iseq, yield_each_children, NULL);
    return self;
}

Перебирает все непосредственные дочерние последовательности инструкций. Порядок перебора зависит от реализации и версии, поэтому полагаться на него не следует.

eval → obj Показать исходный код
static VALUE
iseqw_eval(VALUE self)
{
    const rb_iseq_t *iseq = iseqw_check(self);
    if (0 == ISEQ_BODY(iseq)->iseq_size) {
        rb_raise(rb_eTypeError, "attempt to evaluate dummy InstructionSequence");
    }
    return rb_iseq_eval(iseq, rb_current_box());
}

Вычисляет последовательность инструкций и возвращает результат.

RubyVM::InstructionSequence.compile("1 + 2").eval #=> 3
first_lineno () Показать исходный код
static VALUE
iseqw_first_lineno(VALUE self)
{
    return rb_iseq_first_lineno(iseqw_check(self));
}

Возвращает номер первой строки исходного кода, из которой была загружена последовательность инструкций.

Например, в irb:

iseq = RubyVM::InstructionSequence.compile('num = 1 + 2')
#=> <RubyVM::InstructionSequence:<compiled>@<compiled>>
iseq.first_lineno
#=> 1
inspect () Показать исходный код
static VALUE
iseqw_inspect(VALUE self)
{
    const rb_iseq_t *iseq = iseqw_check(self);
    const struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
    VALUE klass = rb_class_name(rb_obj_class(self));

    if (!body->location.label) {
        return rb_sprintf("#<%"PRIsVALUE": uninitialized>", klass);
    }
    else {
        return rb_sprintf("<%"PRIsVALUE":%"PRIsVALUE"@%"PRIsVALUE":%d>",
                          klass,
                          body->location.label, rb_iseq_path(iseq),
                          FIX2INT(rb_iseq_first_lineno(iseq)));
    }
}

Возвращает удобочитаемое строковое представление этой последовательности инструкций, включая label и path.

label () Показать исходный код
static VALUE
iseqw_label(VALUE self)
{
    return rb_iseq_label(iseqw_check(self));
}

Возвращает метку этой последовательности инструкций.

<main>, если она находится на верхнем уровне; <compiled>, если она была вычислена из строки.

Например, в irb:

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

С использованием ::compile_file:

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

# in irb
> iseq = RubyVM::InstructionSequence.compile_file('/tmp/method.rb')
> iseq.label #=> <main>
path () Показать исходный код
static VALUE
iseqw_path(VALUE self)
{
    return rb_iseq_path(iseqw_check(self));
}

Возвращает путь этой последовательности инструкций.

<compiled>, если iseq был вычислен из строки.

Например, в irb:

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

С использованием ::compile_file:

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

# in irb
> iseq = RubyVM::InstructionSequence.compile_file('/tmp/method.rb')
> iseq.path #=> /tmp/method.rb
script_lines → array or nil Показать исходный код
static VALUE
iseqw_script_lines(VALUE self)
{
    const rb_iseq_t *iseq = iseqw_check(self);
    return ISEQ_BODY(iseq)->variable.script_lines;
}

Возвращает записанные строки скрипта, если они доступны. Строки скрипта не ограничиваются диапазоном iseq, а представляют собой полные строки исходного файла.

Обратите внимание: этот API предназначен для внутреннего использования в Ruby, отладки и исследований. Не используйте его для других целей. Совместимость не гарантируется.

to_a → ary Показать исходный код
static VALUE
iseqw_to_a(VALUE self)
{
    const rb_iseq_t *iseq = iseqw_check(self);
    return iseq_data_to_ary(iseq);
}

Возвращает Array из 14 элементов, представляющих последовательность инструкций и содержащих следующие данные:

magic

Строка, идентифицирующая формат данных. Всегда YARVInstructionSequence/SimpleDataFormat.

major_version

Основная версия последовательности инструкций.

minor_version

Дополнительная версия последовательности инструкций.

format_type

Число, идентифицирующее формат данных. Всегда 1.

misc

Хеш, содержащий:

:arg_size

общее количество аргументов, принимаемых методом или блоком (0, если iseq не представляет метод или блок)

:local_size

количество локальных переменных + 1

:stack_max

используется при вычислении глубины стека, на которой возникает исключение SystemStackError.

label

Имя контекста (блока, метода, класса, модуля и т. д.), к которому относится эта последовательность инструкций.

<main>, если она находится на верхнем уровне; <compiled>, если она была вычислена из строки.

path

Относительный путь к файлу Ruby, из которого была загружена последовательность инструкций.

<compiled>, если iseq был вычислен из строки.

absolute_path

Абсолютный путь к файлу Ruby, из которого была загружена последовательность инструкций.

nil, если iseq был вычислен из строки.

first_lineno

Номер первой строки исходного кода, из которой была загружена последовательность инструкций.

type

Тип последовательности инструкций.

Допустимые значения: :top, :method, :block, :class, :rescue, :ensure, :eval, :main и plain.

locals

Массив, содержащий имена всех аргументов и локальных переменных в виде символов.

params

Объект Hash, содержащий сведения о параметрах.

Дополнительные сведения об этих значениях приведены в vm_core.h.

catch_table

Список исключений и операторов управления потоком (rescue, next, redo, break и т. д.).

bytecode

Массив массивов, содержащих имена инструкций и операнды, составляющие тело последовательности инструкций.

Обратите внимание: этот формат специфичен для MRI и зависит от версии.

to_binary(extra_data = nil) → binary str Показать исходный код
static VALUE
iseqw_to_binary(int argc, VALUE *argv, VALUE self)
{
    VALUE opt = !rb_check_arity(argc, 0, 1) ? Qnil : argv[0];
    return rb_iseq_ibf_dump(iseqw_check(self), opt);
}

Возвращает сериализованные данные iseq в двоичном формате как объект String. Соответствующий объект iseq создаётся методом RubyVM::InstructionSequence.load_from_binary().

Дополнительные данные String сохраняются вместе с двоичными данными. Получить к ним доступ можно с помощью метода RubyVM::InstructionSequence.load_from_binary_extra_data(binary).

Обратите внимание: преобразованные двоичные данные непереносимы. Их нельзя перенести на другую машину. Нельзя использовать двоичные данные, созданные другой версией или для другой архитектуры Ruby.

trace_points → ary Показать исходный код
static VALUE
iseqw_trace_points(VALUE self)
{
    const rb_iseq_t *iseq = iseqw_check(self);
    const struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq);
    unsigned int i;
    VALUE ary = rb_ary_new();

    for (i=0; i<body->insns_info.size; i++) {
        const struct iseq_insn_info_entry *entry = &body->insns_info.body[i];
        if (entry->events) {
            push_event_info(iseq, entry->events, entry->line_no, ary);
        }
    }
    return ary;
}

Возвращает точки трассировки в последовательности инструкций в виде массива пар [строка, символ_события].

Ruby Core © 1993–2025 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API