Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require "fiddle/import"
- class RubyVM::InstructionSequence
- module InternalFunction
- extend Fiddle::Importer
- dlload Fiddle::Handle::DEFAULT
- if Fiddle::SIZEOF_LONG == Fiddle::SIZEOF_VOIDP
- typealias "VALUE", "unsigned long"
- elsif Fiddle::SIZEOF_LONG_LONG == Fiddle::SIZEOF_VOIDP
- typealias "VALUE", "unsigned long long"
- end
- extern "const rb_iseq_t *rb_iseqw_to_iseq(VALUE iseqw)"
- begin
- extern "void rb_iseq_code_location(const rb_iseq_t *iseq, int *first_lineno, int *first_column, int *last_lineno, int *last_column)"
- rescue Fiddle::DLError
- extern "void rb_iseq_code_range(const rb_iseq_t *iseq, int *first_lineno, int *first_column, int *last_lineno, int *last_column)"
- singleton_class.alias_method :rb_iseq_code_location, :rb_iseq_code_range
- end
- end
- def first_column
- code_locations[1]
- end
- def last_lineno
- code_locations[2]
- end
- def last_column
- code_locations[3]
- end
- def code_locations
- size = Fiddle::SIZEOF_INT
- buf = "\0" * (size * 4)
- ptr = Fiddle::Pointer[buf]
- iseq = InternalFunction.rb_iseqw_to_iseq(Fiddle.dlwrap(self))
- InternalFunction.rb_iseq_code_location(iseq, ptr, ptr + size, ptr + size * 2, ptr + size * 3)
- buf.unpack("i4")
- end
- end
- if $0 == __FILE__
- b1 = ->(){ foo() }; a = 1; b2 = ->(){ bar() }
- p RubyVM::InstructionSequence.of(b1).code_locations
- p RubyVM::InstructionSequence.of(b2).yield_self {|iseq| [iseq.first_lineno, iseq.first_column, iseq.last_lineno, iseq.last_column] }
- end
Add Comment
Please, Sign In to add comment