Skip to content

Instantly share code, notes, and snippets.

@wanabe
Created June 19, 2018 23:56
Show Gist options
  • Select an option

  • Save wanabe/04f07b2c5b7a6d4ca0d90b1fc49ebcb1 to your computer and use it in GitHub Desktop.

Select an option

Save wanabe/04f07b2c5b7a6d4ca0d90b1fc49ebcb1 to your computer and use it in GitHub Desktop.
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment