class RubyVM::InstructionSequence
Die Klasse InstructionSequence repräsentiert eine kompilierte Sequenz von Anweisungen für die virtuelle Maschine, die in MRI verwendet wird. Nicht alle Implementierungen von Ruby implementieren diese Klasse möglicherweise, und für Implementierungen, die sie implementieren, können die definierten Methoden und das Verhalten der Methoden in jeder Version geändert werden.
Mit ihr können Sie einen Griff auf die Anweisungen erhalten, aus denen eine Methode oder ein Proc besteht, Ruby-Code-Strings zu VM-Anweisungen kompilieren und Anweisungssequenzen zur einfachen Inspektion in Strings disassemblieren. Sie ist hauptsächlich nützlich, wenn Sie lernen möchten, wie YARV funktioniert, aber sie ermöglicht Ihnen auch, verschiedene Einstellungen für den Ruby iseq-Compiler zu steuern.
Den Quellcode für die VM-Anweisungen finden Sie in insns.def im Ruby-Quellcode.
Die Ergebnisse der Anweisungssequenz werden sich mit der Änderung von Ruby mit ziemlicher Sicherheit ändern, daher kann die Beispielausgabe in dieser Dokumentation von dem abweichen, was Sie sehen.
Natürlich ist diese Klasse MRI-spezifisch.
Öffentliche Klassenmethoden
Source
static VALUE
iseqw_s_compile(int argc, VALUE *argv, VALUE self)
{
return iseqw_s_compile_parser(argc, argv, self, rb_ruby_prism_p());
}
Nimmt source, was ein String von Ruby-Code oder ein offenes File-Objekt sein kann. das Ruby-Quellcode enthält.
Nimmt optional file, path und line, die den Dateipfad, den tatsächlichen Pfad und die erste Zeilennummer des Ruby-Codes in source beschreiben, welche Metadaten an das zurückgegebene iseq angehängt sind.
file wird für __FILE__ und Exception-Backtraces verwendet. path wird als Basis für require_relative verwendet. Es wird empfohlen, dass diese denselben vollständigen Pfad haben.
options, was true, false oder ein Hash sein kann, wird verwendet, um das Standardverhalten des Ruby iseq-Compilers zu ändern.
Details zu gültigen Kompilierungsoptionen finden Sie unter ::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>
Source
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;
}
Nimmt file, einen String mit dem Speicherort einer Ruby-Quelldatei, liest, parst und kompiliert die Datei und gibt iseq zurück, die kompilierte InstructionSequence mit gesetzten Metadaten zum Quellcode-Speicherort.
Nimmt optional options, was true, false oder ein Hash sein kann, um das Standardverhalten des Ruby iseq-Compilers zu ändern.
Details zu gültigen Kompilierungsoptionen finden Sie unter ::compile_option=.
# /tmp/hello.rb puts "Hello, world!" # elsewhere RubyVM::InstructionSequence.compile_file("/tmp/hello.rb") #=> <RubyVM::InstructionSequence:<main>@/tmp/hello.rb>
Source
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);
}
}
Nimmt file, einen String mit dem Speicherort einer Ruby-Quelldatei, liest, parst und kompiliert die Datei und gibt iseq zurück, die kompilierte InstructionSequence mit gesetzten Metadaten zum Quellcode-Speicherort. Es parst und kompiliert mit prism.
Nimmt optional options, was true, false oder ein Hash sein kann, um das Standardverhalten des Ruby iseq-Compilers zu ändern.
Details zu gültigen Kompilierungsoptionen finden Sie unter ::compile_option=.
# /tmp/hello.rb puts "Hello, world!" # elsewhere RubyVM::InstructionSequence.compile_file_prism("/tmp/hello.rb") #=> <RubyVM::InstructionSequence:<main>@/tmp/hello.rb>
Source
static VALUE
iseqw_s_compile_option_get(VALUE self)
{
return make_compile_option_value(&COMPILE_OPTION_DEFAULT);
}
Gibt einen Hash der Standardoptionen zurück, die vom Ruby iseq-Compiler verwendet werden.
Details finden Sie unter InstructionSequence.compile_option=.
Source
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;
}
Setzt die Standardwerte für verschiedene Optimierungen im Ruby iseq-Compiler.
Mögliche Werte für options sind true, was alle Optionen aktiviert, false, was alle Optionen deaktiviert, und nil, was alle Optionen unverändert lässt.
Sie können auch einen Hash von options übergeben, die Sie ändern möchten. Alle Optionen, die nicht im Hash vorhanden sind, bleiben unverändert.
Mögliche Optionsnamen (die Schlüssel in options sind), die auf true oder false gesetzt werden können, sind
-
:inline_const_cache -
:instructions_unification -
:operands_unification -
:peephole_optimization -
:specialized_instruction -
:tailcall_optimization
Zusätzlich kann :debug_level auf eine Ganzzahl gesetzt werden.
Diese Standardoptionen können für einen einzelnen Durchlauf des iseq-Compilers überschrieben werden, indem Sie einen der oben genannten Werte als Parameter options an ::new, ::compile und ::compile_file übergeben.
Source
static VALUE
iseqw_s_compile_parsey(int argc, VALUE *argv, VALUE self)
{
return iseqw_s_compile_parser(argc, argv, self, false);
}
Nimmt source, was ein String von Ruby-Code oder ein offenes File-Objekt sein kann. das Ruby-Quellcode enthält. Es parst und kompiliert mit parse.y.
Nimmt optional file, path und line, die den Dateipfad, den tatsächlichen Pfad und die erste Zeilennummer des Ruby-Codes in source beschreiben, welche Metadaten an das zurückgegebene iseq angehängt sind.
file wird für __FILE__ und Exception-Backtraces verwendet. path wird als Basis für require_relative verwendet. Es wird empfohlen, dass diese denselben vollständigen Pfad haben.
options, was true, false oder ein Hash sein kann, wird verwendet, um das Standardverhalten des Ruby iseq-Compilers zu ändern.
Details zu gültigen Kompilierungsoptionen finden Sie unter ::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>
Source
static VALUE
iseqw_s_compile_prism(int argc, VALUE *argv, VALUE self)
{
return iseqw_s_compile_parser(argc, argv, self, true);
}
Nimmt source, was ein String von Ruby-Code oder ein offenes File-Objekt sein kann. das Ruby-Quellcode enthält. Es parst und kompiliert mit prism.
Nimmt optional file, path und line, die den Dateipfad, den tatsächlichen Pfad und die erste Zeilennummer des Ruby-Codes in source beschreiben, welche Metadaten an das zurückgegebene iseq angehängt sind.
file wird für __FILE__ und Exception-Backtraces verwendet. path wird als Basis für require_relative verwendet. Es wird empfohlen, dass diese denselben vollständigen Pfad haben.
options, was true, false oder ein Hash sein kann, wird verwendet, um das Standardverhalten des Ruby iseq-Compilers zu ändern.
Details zu gültigen Kompilierungsoptionen finden Sie unter ::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>
Source
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));
}
Nimmt body, ein Method- oder Proc-Objekt, und gibt einen String mit den menschenlesbaren Anweisungen für body zurück.
Für ein Method-Objekt
# /tmp/method.rb def hello puts "hello, world" end puts RubyVM::InstructionSequence.disasm(method(:hello))
Produziert
== 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)
Für ein Proc-Objekt
# /tmp/proc.rb p = proc { num = 1 + 2 } puts RubyVM::InstructionSequence.disasm(p)
Produziert
== 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
Source
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));
}
Nimmt body, ein Method- oder Proc-Objekt, und gibt einen String mit den menschenlesbaren Anweisungen für body zurück.
Für ein Method-Objekt
# /tmp/method.rb def hello puts "hello, world" end puts RubyVM::InstructionSequence.disasm(method(:hello))
Produziert
== 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)
Für ein Proc-Objekt
# /tmp/proc.rb p = proc { num = 1 + 2 } puts RubyVM::InstructionSequence.disasm(p)
Produziert
== 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
Source
static VALUE
iseqw_s_load_from_binary(VALUE self, VALUE str)
{
return iseqw_new(rb_iseq_ibf_load(str));
}
Lädt ein iseq-Objekt aus dem Binärformat, einem von RubyVM::InstructionSequence.to_binary erstellten String-Objekt.
Dieser Lader hat keinen Verifier, sodass das Laden von fehlerhaften/modifizierten Binärdaten zu kritischen Problemen führen kann.
Sie sollten keine Binärdaten laden, die von anderen bereitgestellt werden. Sie sollten Binärdaten verwenden, die Sie selbst übersetzt haben.
Source
static VALUE
iseqw_s_load_from_binary_extra_data(VALUE self, VALUE str)
{
return rb_iseq_ibf_load_extra_data(str);
}
Lädt zusätzliche Daten, die in ein Binärformat String-Objekt eingebettet sind.
Source
static VALUE
iseqw_s_compile(int argc, VALUE *argv, VALUE self)
{
return iseqw_s_compile_parser(argc, argv, self, rb_ruby_prism_p());
}
Nimmt source, was ein String von Ruby-Code oder ein offenes File-Objekt sein kann. das Ruby-Quellcode enthält.
Nimmt optional file, path und line, die den Dateipfad, den tatsächlichen Pfad und die erste Zeilennummer des Ruby-Codes in source beschreiben, welche Metadaten an das zurückgegebene iseq angehängt sind.
file wird für __FILE__ und Exception-Backtraces verwendet. path wird als Basis für require_relative verwendet. Es wird empfohlen, dass diese denselben vollständigen Pfad haben.
options, was true, false oder ein Hash sein kann, wird verwendet, um das Standardverhalten des Ruby iseq-Compilers zu ändern.
Details zu gültigen Kompilierungsoptionen finden Sie unter ::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>
Source
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;
}
Gibt die Anweisungssequenz zurück, die den gegebenen Proc oder die Methode enthält.
Zum Beispiel bei Verwendung von 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)>
Verwendung von ::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>
Öffentliche Instanzmethoden
Source
static VALUE
iseqw_absolute_path(VALUE self)
{
return rb_iseq_realpath(iseqw_check(self));
}
Gibt den absoluten Pfad dieser Anweisungssequenz zurück.
nil, wenn das iseq aus einem String ausgewertet wurde.
Zum Beispiel bei Verwendung von ::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
Source
static VALUE
iseqw_base_label(VALUE self)
{
return rb_iseq_base_label(iseqw_check(self));
}
Gibt das Basislabe dieser Anweisungssequenz zurück.
Zum Beispiel bei Verwendung von irb
iseq = RubyVM::InstructionSequence.compile('num = 1 + 2') #=> <RubyVM::InstructionSequence:<compiled>@<compiled>> iseq.base_label #=> "<compiled>"
Verwendung von ::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>
Source
static VALUE
iseqw_disasm(VALUE self)
{
return rb_iseq_disasm(iseqw_check(self));
}
Gibt die Anweisungssequenz als String in menschenlesbarer Form zurück.
puts RubyVM::InstructionSequence.compile('1 + 2').disasm
Produziert
== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>========== 0000 trace 1 ( 1) 0002 putobject 1 0004 putobject 2 0006 opt_plus <ic:1> 0008 leave
Gibt die Anweisungssequenz als String in menschenlesbarer Form zurück.
puts RubyVM::InstructionSequence.compile('1 + 2').disasm
Produziert
== disasm: <RubyVM::InstructionSequence:<compiled>@<compiled>>========== 0000 trace 1 ( 1) 0002 putobject 1 0004 putobject 2 0006 opt_plus <ic:1> 0008 leave
Source
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;
}
Iteriert über alle direkten Kind-Anweisungssequenzen. Die Reihenfolge der Iteration ist implementierungs-/versionsabhängig, daher sollten sich die Leute nicht auf die Reihenfolge verlassen.
Source
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());
}
Wertet die Anweisungssequenz aus und gibt das Ergebnis zurück.
RubyVM::InstructionSequence.compile("1 + 2").eval #=> 3
Source
static VALUE
iseqw_first_lineno(VALUE self)
{
return rb_iseq_first_lineno(iseqw_check(self));
}
Gibt die Nummer der ersten Quellcodezeile zurück, aus der die Anweisungssequenz geladen wurde.
Zum Beispiel bei Verwendung von irb
iseq = RubyVM::InstructionSequence.compile('num = 1 + 2') #=> <RubyVM::InstructionSequence:<compiled>@<compiled>> iseq.first_lineno #=> 1
Source
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)));
}
}
Source
static VALUE
iseqw_label(VALUE self)
{
return rb_iseq_label(iseqw_check(self));
}
Gibt das Labe dieser Anweisungssequenz zurück.
<main>, wenn es auf oberster Ebene ist, <compiled>, wenn es aus einem String ausgewertet wurde.
Zum Beispiel bei Verwendung von irb
iseq = RubyVM::InstructionSequence.compile('num = 1 + 2') #=> <RubyVM::InstructionSequence:<compiled>@<compiled>> iseq.label #=> "<compiled>"
Verwendung von ::compile_file
# /tmp/method.rb
def hello
puts "hello, world"
end
# in irb
> iseq = RubyVM::InstructionSequence.compile_file('/tmp/method.rb')
> iseq.label #=> <main>
Source
static VALUE
iseqw_path(VALUE self)
{
return rb_iseq_path(iseqw_check(self));
}
Gibt den Pfad dieser Anweisungssequenz zurück.
<compiled>, wenn das iseq aus einem String ausgewertet wurde.
Zum Beispiel bei Verwendung von irb
iseq = RubyVM::InstructionSequence.compile('num = 1 + 2') #=> <RubyVM::InstructionSequence:<compiled>@<compiled>> iseq.path #=> "<compiled>"
Verwendung von ::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
Source
static VALUE
iseqw_script_lines(VALUE self)
{
const rb_iseq_t *iseq = iseqw_check(self);
return ISEQ_BODY(iseq)->variable.script_lines;
}
Gibt aufgezeichnete Skriptzeilen zurück, falls verfügbar. Die Skriptzeilen sind nicht auf den iseq-Bereich beschränkt, sondern sind ganze Zeilen der Quelldatei.
Beachten Sie, dass dies eine API für die interne Verwendung von Ruby, für Debugging und Forschung ist. Verwenden Sie dies nicht für andere Zwecke. Die Kompatibilität ist nicht garantiert.
Source
static VALUE
iseqw_to_a(VALUE self)
{
const rb_iseq_t *iseq = iseqw_check(self);
return iseq_data_to_ary(iseq);
}
Gibt ein Array mit 14 Elementen zurück, das die Anweisungssequenz mit den folgenden Daten darstellt
- magic
-
Ein String, der das Datenformat identifiziert. Immer
YARVInstructionSequence/SimpleDataFormat. - major_version
-
Die Hauptversion der Anweisungssequenz.
- minor_version
-
Die Nebenversion der Anweisungssequenz.
- format_type
-
Eine Nummer, die das Datenformat identifiziert. Immer 1.
- misc
-
Ein Hash, der Folgendes enthält
:arg_size-
die Gesamtzahl der Argumente, die von der Methode oder dem Block übernommen werden (0, wenn iseq keine Methode oder keinen Block darstellt)
:local_size-
die Anzahl der lokalen Variablen + 1
:stack_max-
wird zur Berechnung der Stack-Tiefe verwendet, bei der ein
SystemStackErrorausgelöst wird.
label-
Der Name des Kontexts (Block, Methode, Klasse, Modul usw.), zu dem diese Anweisungssequenz gehört.
<main>, wenn es auf oberster Ebene ist,<compiled>, wenn es aus einem String ausgewertet wurde. path-
Der relative Pfad zur Ruby-Datei, aus der die Anweisungssequenz geladen wurde.
<compiled>, wenn das iseq aus einem String ausgewertet wurde. absolute_path-
Der absolute Pfad zur Ruby-Datei, aus der die Anweisungssequenz geladen wurde.
nil, wenn das iseq aus einem String ausgewertet wurde. first_lineno-
Die Nummer der ersten Quellcodezeile, aus der die Anweisungssequenz geladen wurde.
- type
-
Der Typ der Anweisungssequenz.
Gültige Werte sind
:top,:method,:block,:class,:rescue,:ensure,:eval,:mainundplain. - locals
-
Ein Array, das die Namen aller Argumente und lokalen Variablen als Symbole enthält.
- params
-
Ein
Hash-Objekt, das Parameterinformationen enthält.Weitere Informationen zu diesen Werten finden Sie in
vm_core.h. - catch_table
-
Eine Liste von Ausnahmen und Kontrollflussoperatoren (rescue, next, redo, break usw.).
- bytecode
-
Ein Array von Arrays, das die Anweisungsnamen und Operanden enthält, aus denen der Körper der Anweisungssequenz besteht.
Beachten Sie, dass dieses Format MRI-spezifisch und versionsabhängig ist.
Source
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);
}
Gibt serialisierte iseq-Binärformatdaten als String-Objekt zurück. Ein entsprechendes iseq-Objekt wird von der Methode RubyVM::InstructionSequence.load_from_binary() erstellt.
Der String extra_data wird zusammen mit den Binärdaten gespeichert. Sie können auf diese Daten mit RubyVM::InstructionSequence.load_from_binary_extra_data(binary) zugreifen.
Beachten Sie, dass die übersetzten Binärdaten nicht portierbar sind. Sie können diese Binärdaten nicht auf einen anderen Computer übertragen. Sie können keine Binärdaten verwenden, die von einer anderen Version/Architektur von Ruby erstellt wurden.
Source
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;
}
Gibt Trace-Punkte in der Anweisungssequenz zurück. Gibt ein Array von [Zeile, Ereignissymbol]-Paaren zurück.