@@ -7,6 +7,28 @@ module YARV
7
7
# list of instructions along with the metadata pertaining to them. It also
8
8
# functions as a builder for the instruction sequence.
9
9
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
+
10
32
# When the list of instructions is first being created, it's stored as a
11
33
# linked list. This is to make it easier to perform peephole optimizations
12
34
# and other transformations like instruction specialization.
@@ -60,19 +82,6 @@ def push(instruction)
60
82
61
83
MAGIC = "YARVInstructionSequence/SimpleDataFormat"
62
84
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
-
76
85
# This object is used to track the size of the stack at any given time. It
77
86
# is effectively a mini symbolic interpreter. It's necessary because when
78
87
# instruction sequences get serialized they include a :stack_max field on
@@ -221,8 +230,7 @@ def length
221
230
end
222
231
223
232
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
226
234
end
227
235
228
236
def to_a
0 commit comments