From: Simen Edvardsen Date: 2017-08-22T14:45:48+02:00 Subject: [ruby-core:82448] Exposing rb_iseq_load as a ruby method? --===============1995647758== Content-Type: multipart/alternative; boundary="001a11440eb886dc4f055756f930" --001a11440eb886dc4f055756f930 Content-Type: text/plain; charset="UTF-8" RubyVM::InstructionSequence is great, it's great that you can compile code and disassemble. But for my current project (which is currently a toy, but this may have other useful applications), what I'd really like is to feed an instruction sequence constructed in Ruby into the iseq assembler. On the C level, such a function exists and it works, namely, rb_iseq_load, but it's not exposed on the Ruby level. Other people apparently found this function useful too, because I found the following snippet online to dynamically load it: require "fiddle" class RubyVM::InstructionSequence # Retrieve Ruby Core's C-ext `iseq_load' function address # I had to modify this line for my system load_fn_addr = Fiddle::Handle.new("x64-msvcrt-ruby240.dll")['rb_iseq_load'] # Retrieve `iseq_load' C function representation load_fn = Fiddle::Function.new(load_fn_addr, [Fiddle::TYPE_VOIDP] * 3, Fiddle::TYPE_VOIDP) # Make `iseq_load' accessible as `load' class method define_singleton_method(:load) do |data, parent = nil, opt = nil| load_fn.call(Fiddle.dlwrap(data), parent, opt).to_value end end The original hack was written for Linux, I think, so I had to manually find the right DLL for my system and swap it in there. But it works, kinda, in a hacky way. Would you ever consider exposing rb_iseq_load as a singleton method of RubyVM::InstructionSequence? The function already performs quite a few checks on the validity of the input, and there is already an unsafe way to load ISeqs via ::from_binary. And that would make it easier to do interesting things with Ruby codegen. -- - Simen --001a11440eb886dc4f055756f930 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
RubyVM::InstructionSequence is great, it's great that = you can compile code and disassemble. But for my current project (which is = currently a toy, but this may have other useful applications), what I'd= really like is to feed an instruction sequence constructed in Ruby into th= e iseq assembler. On the C level, such a function exists and it works, name= ly, rb_iseq_load, but it's not exposed on the Ruby level. Other people = apparently found this function useful too, because I found the following sn= ippet online to dynamically load it:

require "fiddl= e"
class RubyVM::InstructionSequence
=C2=A0 #= Retrieve Ruby Core's C-ext `iseq_load' function address
= =C2=A0 # I had to modify this line for my system
=C2=A0 load_fn_a= ddr =C2=A0=3D Fiddle::Handle.new("x64-msvcrt-ruby240.dll")['r= b_iseq_load']
=C2=A0 # Retrieve `iseq_load' C function re= presentation
=C2=A0 load_fn =C2=A0 =C2=A0 =C2=A0 =3D Fiddle::Func= tion.new(load_fn_addr,
=C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0[Fiddle::TYPE_VOIDP] * 3,
=C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0Fiddle::TYPE_VOIDP)

=C2=A0 # Make `iseq_load' accessible as `load'= ; class method
=C2=A0 define_singleton_method(:load) do |data, pa= rent =3D nil, opt =3D nil|
=C2=A0 =C2=A0 load_fn.call(Fiddle.dlwr= ap(data), parent, opt).to_value
=C2=A0 end
end

The original hack was written for Linux, I think, so I had= to manually find the right DLL for my system and swap it in there. But it = works, kinda, in a hacky way.

Would you ever consi= der exposing rb_iseq_load as a singleton method of RubyVM::InstructionSeque= nce? The function already performs quite a few checks on the validity of th= e input, and there is already an unsafe way to load ISeqs via ::from_binary= . And that would make it easier to do interesting things with Ruby codegen.=

--
- Simen
--001a11440eb886dc4f055756f930-- --===============1995647758== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline Unsubscribe: --===============1995647758==--