Skip to content

Do not rely on fiddle being present #301

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion lib/syntax_tree.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

require "cgi"
require "etc"
require "fiddle"
require "json"
require "pp"
require "prettier_print"
Expand Down
38 changes: 23 additions & 15 deletions lib/syntax_tree/yarv/instruction_sequence.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,28 @@ module YARV
# list of instructions along with the metadata pertaining to them. It also
# functions as a builder for the instruction sequence.
class InstructionSequence
# This provides a handle to the rb_iseq_load function, which allows you
# to pass a serialized iseq to Ruby and have it return a
# RubyVM::InstructionSequence object.
def self.iseq_load(iseq)
require "fiddle"

@iseq_load_function ||=
Fiddle::Function.new(
Fiddle::Handle::DEFAULT["rb_iseq_load"],
[Fiddle::TYPE_VOIDP] * 3,
Fiddle::TYPE_VOIDP
)

Fiddle.dlunwrap(@iseq_load_function.call(Fiddle.dlwrap(iseq), 0, nil))
rescue LoadError
raise "Could not load the Fiddle library"
rescue NameError
raise "Unable to find rb_iseq_load"
rescue Fiddle::DLError
raise "Unable to perform a dynamic load"
end

# When the list of instructions is first being created, it's stored as a
# linked list. This is to make it easier to perform peephole optimizations
# and other transformations like instruction specialization.
Expand Down Expand Up @@ -60,19 +82,6 @@ def push(instruction)

MAGIC = "YARVInstructionSequence/SimpleDataFormat"

# This provides a handle to the rb_iseq_load function, which allows you to
# pass a serialized iseq to Ruby and have it return a
# RubyVM::InstructionSequence object.
ISEQ_LOAD =
begin
Fiddle::Function.new(
Fiddle::Handle::DEFAULT["rb_iseq_load"],
[Fiddle::TYPE_VOIDP] * 3,
Fiddle::TYPE_VOIDP
)
rescue NameError, Fiddle::DLError
end

# This object is used to track the size of the stack at any given time. It
# is effectively a mini symbolic interpreter. It's necessary because when
# instruction sequences get serialized they include a :stack_max field on
Expand Down Expand Up @@ -221,8 +230,7 @@ def length
end

def eval
raise "Unsupported platform" if ISEQ_LOAD.nil?
Fiddle.dlunwrap(ISEQ_LOAD.call(Fiddle.dlwrap(to_a), 0, nil)).eval
InstructionSequence.iseq_load(to_a).eval
end

def to_a
Expand Down