This post originated from an RSS feed registered with Ruby Buzz
by Eigen Class.
Original Post: A taste of evil.rb: using DL to unfreeze objects
Feed Title: Eigenclass
Feed URL: http://feeds.feedburner.com/eigenclass
Feed Description: Ruby stuff --- trying to stay away from triviality.
More people are getting interested in ruby's
internals*1, perhaps thanks to Caleb Tennis'
latestseries.
So maybe the time has come to unveil
evil.rb*2 as quite an useful learning tool,
allowing you to mess with the interpreter's internal data structures at runtime.
I will show how evil.rb manages to unfreeze an object, introducing DL along the way.
That's one of the simplest low-level manipulations one can do, just the
first step towards better understanding of the runtime structures, but this is
the sort of things happening under the hood in the interpreter all the
time.
evil.rb
The idea behind evil.rb was conceived by Florian GroÃ: it's
as simple as using DL to access internal objects. That is, it allows
you to manipulate them at the C-struct level. This enables you to do things like:
changing the class of an object
manipulating the inheritance chain for fun and profit
grabbing instance variables or singleton methods
swapping objects (ever heard of Object#become?)
changing the self context of a Proc (the way 1.9's instance_exec does)
messing with the flags of an object
Using DL
Ruby VALUES for non-immediate objects are pointers to RVALUE slots
inside heaps managed by Ruby. RVALUE is a union type taking 5 words (20
bytes), whose contents can be interpreted as any of the "RStructs":
it turns out that the interpreter distinguishes internally between
different object types (and other things like NODEs that correspond to
executable code, or scopes).