From: Mike Owens Date: 2013-03-17T01:51:16+09:00 Subject: Re: RubyVM::InstructionSequence compiling and loading There is a single line difference between the two sequences: 44c44 < {:mid=>:collect, :flag=>0, :orig_argc=>0, :blockptr=>["YARVInstructionSequence/SimpleDataFormat", 2, 0, 1, {:arg_size=>1, :local_size=>2, :stack_max=>4}, "block in ", "", 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. On Sat, Mar 16, 2013 at 11:03 AM, Mike Owens wrote: > Actually a better example without having to recompile Ruby is the following: > > #!/usr/bin/env ruby > > require 'fiddle' > > class RubyVM > class InstructionSequence > address = Fiddle::Handle::DEFAULT['rb_iseq_load'] > func = Fiddle::Function.new( address, > [Fiddle::TYPE_VOIDP] * 3, > Fiddle::TYPE_VOIDP ) > > define_singleton_method(:load) do |data, parent = nil, opt = nil| > func.call(Fiddle.dlwrap(data), parent, opt).to_value > end > end > end > > source = %q{ > args = {} > args['q'] = 'test' > args.to_a.collect {|x| "#{x[0]}=#{x[1]}" }.join('&') > } > > orig = RubyVM::InstructionSequence.new source > loaded = RubyVM::InstructionSequence.load orig.to_a > > orig.eval > loaded.eval > > The last eval throws the exception. It would seem like the two > instruction sequences should be equivalent. > > On Fri, Mar 15, 2013 at 11:53 PM, Mike Owens wrote: >> I recently came across "An Amateur Smalltalk User's Observations on >> Ruby Object Model and Bytecode" >> (http://www.slideshare.net/kstan2/smalltalk-and-ruby-20121208-15542185). >> 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 >> >> orig.eval >> other.eval # <- Exception >> >> The first eval works. The second eval throws an exception: >> >> :in `': undefined method `join' for >> # (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? >> >> -- >> Mike >> > > > > -- > Mike > -- Mike