Skip to content

Instantly share code, notes, and snippets.

@brixen
Created June 15, 2019 20:11
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 brixen/ef4e475e0b83292338493104e3a7307e to your computer and use it in GitHub Desktop.
Save brixen/ef4e475e0b83292338493104e3a7307e to your computer and use it in GitHub Desktop.
Illustration of Rubinius tagged nil that enables tracing where a nil value originated
rbx tagged_nil.rb
main # Rubinius::Loader at core/loader.rb:852 (+90)
script # Rubinius::Loader at core/loader.rb:667 (+343)
load_script # Rubinius::CodeLoader at
core/code_loader.rb:280 (+60)
load # Rubinius::CodeLoader::Source(Rubinius::CodeLoader::Script) at
core/code_loader.rb:119 (+81)
run_script # Rubinius::CodeLoader::Source(Rubinius::CodeLoader::Script) at
core/code_loader.rb:132 (+21)
__script__ # Object at tagged_nil.rb:50 (+153)
m # B at tagged_nil.rb:40 (+31)
m # C at tagged_nil.rb:46 (+3)
catch_me_if_you_can! (method_missing) # NilClass at tagged_nil.rb:34 (+361)
undefined method catch_me_if_you_can! called on an instance of NilClass originating in 'who_me?' at (dynamic):1 (NoMethodError)
An exception occurred running tagged_nil.rb
class A
dynamic_method :who_me? do |g|
r0 = g.new_register
g.noop
g.noop
g.r_load_nil r0, 0
g.r_store_stack r0
g.ret
end
end
class NilClass
def method_missing(*_, **)
sym, = _
m = Rubinius::Mirror::Object.reflect self
code_id = m.nil_code_id.to_s 16
ip = m.nil_ip
cc = nil
ObjectSpace.each_object(Rubinius::CompiledCode) do |c|
cc = c if c.code_id.start_with? code_id
end
if cc
msg = "undefined method #{sym} called on an instance of NilClass originating in '#{cc.name}' at #{cc.file}:#{cc.line_from_ip(ip)}"
else
msg = "undefined method #{sym} called on an instance of NilClass"
end
raise NoMethodError, msg
end
end
class B
def m(a)
C.new.m a
end
end
class C
def m(a)
a.catch_me_if_you_can!
end
end
B.new.m A.new.who_me?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment