Hi all,
I seem to have misunderstood some finer point of how the instance
variable tables work. Since for something like this I expect code
speaks louder than words, I have made a small test case using evil.rb
(to keep the file size down) available from:
http://rubyforge.org/cgi-bin/viewvc.cgi/evil/lib/evil.rb?
revision=1.44&root=evil
Unfortunately, due to some error I have made this test case does not
find all the instance variable keys. I’m sure some wizard out there
will easily spot my newbie mistake. Could someone please point out
where I’m going wrong by making this tiny test case work?
Many thanks,
Rob.
Rob Pitt schrieb:
I seem to have misunderstood some finer point of how the instance
variable tables work. (…) Could someone please point out where I’m
going wrong by making this tiny test case work?
Rob, I added the necessary changes to your code below:
require ‘evil’
require ‘test/unit’
module RubyInternal
ST_TABLE_BIN = struct [
“ST_TABLE_ENTRY *entry”
]
end
a.instance_variable_set(key,1)
end
r_object = RObject.new(a.internal_ptr)
table = ST_TABLE.new(r_object.iv_tbl)
chain = 0
while chain < table.num_bins
replace the following line:
table_entry = ST_TABLE_ENTRY.new(table.bins + (chain * DL::sizeof('P')))
with:
table_bin = ST_TABLE_BIN.new(table.bins + (chain *
DL::sizeof(‘P’)))
table_entry = table_bin.entry &&
ST_TABLE_ENTRY.new(table_bin.entry)
while table_entry
sym = table_entry.key.to_sym
located_keys << sym.to_s if sym && sym.to_s[0] == ?@
table_entry = table_entry.next && ST_TABLE_ENTRY.new(table_entry.next)
end
chain += 1
end
assert_equal(created_keys.sort,located_keys.sort)
end
end
“table.bins” points to an array of “table.num_bins” pointers to table
entries. So
table.bins + (chain * DL::sizeof(‘P’))
isn’t the address of a table entry, but the address of a pointer to a
table
entry. In order to dereference these pointers, I added the ST_TABLE_BIN
struct
to your code.
Regards,
Pit