Skip to content

Instantly share code, notes, and snippets.

@kddnewton
Last active December 22, 2022 20:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kddnewton/a943951e8d48b5d21a9679412a35f5ab to your computer and use it in GitHub Desktop.
Save kddnewton/a943951e8d48b5d21a9679412a35f5ab to your computer and use it in GitHub Desktop.
Indexing classes/modules/methods
#!/usr/bin/env ruby
# frozen_string_literal: true
VM_DEFINECLASS_TYPE_CLASS = 0x00
VM_DEFINECLASS_TYPE_SINGLETON_CLASS = 0x01
VM_DEFINECLASS_TYPE_MODULE = 0x02
VM_DEFINECLASS_FLAG_SCOPED = 0x08
VM_DEFINECLASS_FLAG_HAS_SUPERCLASS = 0x10
def log(line, event, message)
puts "%04d %-20s %s" % [line, event, message]
end
def index(iseq, nesting = [:Object])
line = iseq[9]
iseq[13].each_with_index do |insn, index|
case insn
in Integer
line = insn
in [:defineclass, name, class_iseq, ^(VM_DEFINECLASS_TYPE_SINGLETON_CLASS)]
if iseq[13][index - 2] == [:putself]
index(class_iseq, nesting + [name])
else
raise NotImplementedError, "singleton class with non-self receiver"
end
in [:defineclass, name, class_iseq, flags] if flags & VM_DEFINECLASS_TYPE_MODULE > 0
log(line, :"module-definition", (nesting + [name]).join("::"))
index(class_iseq, nesting + [name])
in [:defineclass, name, class_iseq, flags]
log(line, :"class-definition", (nesting + [name]).join("::"))
index(class_iseq, nesting + [name])
in [:definemethod, name, method_iseq]
log(line, :"method-definition", "#{nesting.join("::")}##{name}")
in [:definesmethod, name, method_iseq]
log(line, :"method-definition", (nesting + [name]).join("::"))
else
# skip other instructions
end
end
end
Dir[ARGV.first].each do |filepath|
puts "=== #{filepath} ==="
index(RubyVM::InstructionSequence.compile_file(filepath).to_a)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment