класс RubyVM::InstructionSequence
Класс InstructionSequence представляет собой скомпилированную последовательность инструкций для виртуальной машины, используемой в MRI. Не все реализации Ruby могут реализовывать этот класс, и для реализаций, которые его реализуют, методы и поведение методов могут изменяться в любой версии.
С помощью него вы можете получить доступ к инструкциям, составляющим метод или процедуру, скомпилировать строки кода Ruby до инструкций VM и дизассемблировать последовательности инструкций в строки для удобного просмотра. Он в основном полезен, если вы хотите узнать, как работает YARV, но также позволяет управлять различными настройками компилятора Ruby iseq.
Исходный код инструкций VM можно найти в insns.def в исходном коде Ruby.
Результаты последовательности инструкций почти наверняка будут меняться по мере изменения Ruby, поэтому примеры вывода в этой документации могут отличаться от того, что вы видите.
Конечно, этот класс специфичен для MRI.
Публичные методы класса
Исходный код
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>
Исходный код
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_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>
Исходный код
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>
Исходный код
static VALUE
iseqw_s_compile_option_get(VALUE self)
{
return make_compile_option_value(&COMPILE_OPTION_DEFAULT);
} Возвращает хэш параметров по умолчанию, используемых компилятором iseq Ruby.
Подробности см. в InstructionSequence.compile_option=.
Исходный код
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.
Исходный код
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>
Исходный код
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>
Исходный код
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
Исходный код
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
Исходный код
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.
Этот загрузчик не имеет верификатора, поэтому загрузка повреждённого/изменённого двоичного файла может привести к критической ошибке.
Не следует загружать двоичные данные, предоставленные другими. Нужно использовать двоичные данные, переведённые самостоятельно.
Исходный код
static VALUE
iseqw_s_load_from_binary_extra_data(VALUE self, VALUE str)
{
return rb_iseq_ibf_load_extra_data(str);
} Загружает дополнительные данные, встроенные в двоичный формат String объекта.
Исходный код
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, используется для изменения стандартного поведения компилятора Ruby iseq.
Подробнее о допустимых параметрах компиляции см. ::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>
Исходный код
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> Общедоступные методы экземпляра
Исходный код
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 Исходный код
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> Исходный код
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
Возвращает последовательность инструкций в удобочитаемом виде как 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
Исходный код
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;
} Итерирует все прямые дочерние последовательности инструкций. Порядок итерации определяется реализацией/версией, поэтому люди не должны полагаться на этот порядок.
Исходный код
static VALUE
iseqw_eval(VALUE self)
{
return rb_iseq_eval(iseqw_check(self));
} Вычисляет последовательность инструкций и возвращает результат.
RubyVM::InstructionSequence.compile("1 + 2").eval #=> 3
Исходный код
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
Исходный код
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.
Исходный код
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> Исходный код
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 Исходный код
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, отладки и исследований. Не используйте его для других целей. Совместимость не гарантируется.
Исходный код
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-
Имя контекста (блок, метод, класс, модуль и т.д.), к которому относится эта последовательность инструкций.
<compiled>если это на верхнем уровне,<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 и зависит от версии.
Исходный код
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.
Исходный код
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–2024 Yukihiro Matsumoto
Licensed under the Ruby License.
Ruby Standard Library © contributors
Licensed under their own licenses.