Forum: Ruby RubyVM::InstructionSequence compiling and loading

Bc341c3fcd0a2aa63bdedc290b17fcce?d=identicon&s=25 Mike Owens (Guest)
on 2013-03-16 05:56
(Received via mailing list)
I recently came across "An Amateur Smalltalk User's Observations on
Ruby Object Model and Bytecode"
I tried his example of enabling iseq_s_load(). I stumbled across a
simple case where the loaded compiled code does not work as the
original compiled code, specifically:

    source = %q{
    args           = {}
    args['q']      = 'test'
    args.to_a.collect {|x| "#{x[0]}=#{x[1]}" }.join('&')

  orig = RubyVM::InstructionSequence.compile source
  loaded = RubyVM::InstructionSequence.load ins.to_a

  other.eval  # <- Exception

The first eval works. The second eval throws an exception:

  <compiled>:in `<compiled>': undefined method `join' for
#<Enumerator: [["q", "test"]]:collect> (NoMethodError)

The result of the first collect method is (and should be) an Array.
However the second is producing an Enumerator.

I was wondering if anyone could explain why this is the case?
Bc341c3fcd0a2aa63bdedc290b17fcce?d=identicon&s=25 Mike Owens (Guest)
on 2013-03-16 17:04
(Received via mailing list)
Actually a better example without having to recompile Ruby is the

#!/usr/bin/env ruby

require 'fiddle'

class RubyVM
  class InstructionSequence
    address = Fiddle::Handle::DEFAULT['rb_iseq_load']
    func = address,
                                 [Fiddle::TYPE_VOIDP] * 3,
                                 Fiddle::TYPE_VOIDP )

    define_singleton_method(:load) do |data, parent = nil, opt = nil|, parent, opt).to_value

source = %q{
  args           = {}
  args['q']      = 'test'
  args.to_a.collect {|x| "#{x[0]}=#{x[1]}" }.join('&')

orig   = source
loaded = RubyVM::InstructionSequence.load orig.to_a


The last eval throws the exception. It would seem like the two
instruction sequences should be equivalent.
Bc341c3fcd0a2aa63bdedc290b17fcce?d=identicon&s=25 Mike Owens (Guest)
on 2013-03-16 17:52
(Received via mailing list)
There is a single line difference between the two sequences:

< {:mid=>:collect, :flag=>0, :orig_argc=>0,
:blockptr=>["YARVInstructionSequence/SimpleDataFormat", 2, 0, 1,
{:arg_size=>1, :local_size=>2, :stack_max=>4}, "block in <compiled>",
"<compiled>", nil, 4, :block, [:x], [1, [], 0, 0, -1, -1, 3], [[:redo,
nil, :label_0, :label_22, :label_0, 0], [:next, nil, :label_0,
:label_22, :label_22, 0]], [:label_0, [:trace, 256], [:trace, 1],
[:getlocal_OP__WC__0, 2], [:putobject_OP_INT2FIX_O_0_C_], [:opt_aref,
{:mid=>:[], :flag=>256, :orig_argc=>1, :blockptr=>nil}], [:tostring],
[:putobject, "="], [:getlocal_OP__WC__0, 2],
[:putobject_OP_INT2FIX_O_1_C_], [:opt_aref, {:mid=>:[], :flag=>256,
:orig_argc=>1, :blockptr=>nil}], [:tostring], [:concatstrings, 3],
[:trace, 512], :label_22, [:leave]]]}
> {:mid=>:collect, :flag=>256, :orig_argc=>0, :blockptr=>nil}

Since I don't have the first clue as to how this part of Ruby works
I'll just move wait until iseq_s_load() is officially supported.
12742703787467362a12e3dcce61661e?d=identicon&s=25 pmros pmros (pmros)
on 2013-11-12 22:25
I think this is the bug:
I hope it would be solved in ruby 2.1.0
Please log in before posting. Registration is free and takes only a minute.
Existing account

NEW: Do you have a Google/GoogleMail, Yahoo or Facebook account? No registration required!
Log in with Google account | Log in with Yahoo account | Log in with Facebook account
No account? Register here.