@@ -7,6 +7,28 @@ module YARV
77 # list of instructions along with the metadata pertaining to them. It also
88 # functions as a builder for the instruction sequence.
99 class InstructionSequence
10+ # This provides a handle to the rb_iseq_load function, which allows you
11+ # to pass a serialized iseq to Ruby and have it return a
12+ # RubyVM::InstructionSequence object.
13+ def self . iseq_load ( iseq )
14+ require "fiddle"
15+
16+ @iseq_load_function ||=
17+ Fiddle ::Function . new (
18+ Fiddle ::Handle ::DEFAULT [ "rb_iseq_load" ] ,
19+ [ Fiddle ::TYPE_VOIDP ] * 3 ,
20+ Fiddle ::TYPE_VOIDP
21+ )
22+
23+ Fiddle . dlunwrap ( @iseq_load_function . call ( Fiddle . dlwrap ( iseq ) , 0 , nil ) )
24+ rescue LoadError
25+ raise "Could not load the Fiddle library"
26+ rescue NameError
27+ raise "Unable to find rb_iseq_load"
28+ rescue Fiddle ::DLError
29+ raise "Unable to perform a dynamic load"
30+ end
31+
1032 # When the list of instructions is first being created, it's stored as a
1133 # linked list. This is to make it easier to perform peephole optimizations
1234 # and other transformations like instruction specialization.
@@ -60,19 +82,6 @@ def push(instruction)
6082
6183 MAGIC = "YARVInstructionSequence/SimpleDataFormat"
6284
63- # This provides a handle to the rb_iseq_load function, which allows you to
64- # pass a serialized iseq to Ruby and have it return a
65- # RubyVM::InstructionSequence object.
66- ISEQ_LOAD =
67- begin
68- Fiddle ::Function . new (
69- Fiddle ::Handle ::DEFAULT [ "rb_iseq_load" ] ,
70- [ Fiddle ::TYPE_VOIDP ] * 3 ,
71- Fiddle ::TYPE_VOIDP
72- )
73- rescue NameError , Fiddle ::DLError
74- end
75-
7685 # This object is used to track the size of the stack at any given time. It
7786 # is effectively a mini symbolic interpreter. It's necessary because when
7887 # instruction sequences get serialized they include a :stack_max field on
@@ -221,8 +230,7 @@ def length
221230 end
222231
223232 def eval
224- raise "Unsupported platform" if ISEQ_LOAD . nil?
225- Fiddle . dlunwrap ( ISEQ_LOAD . call ( Fiddle . dlwrap ( to_a ) , 0 , nil ) ) . eval
233+ InstructionSequence . iseq_load ( to_a ) . eval
226234 end
227235
228236 def to_a
0 commit comments