Skip to content

Instantly share code, notes, and snippets.

@k-tsj
Last active April 29, 2023 09:54
Show Gist options
  • Save k-tsj/1e4c48d985c2fa2e08de842a3bc3f47a to your computer and use it in GitHub Desktop.
Save k-tsj/1e4c48d985c2fa2e08de842a3bc3f47a to your computer and use it in GitHub Desktop.
calc sp
source = %q{
case 0
in a: 0
end
}
RubyVM::InstructionSequence.compile_option = RubyVM::InstructionSequence.compile_option.transform_values do |v|
(v == true or v == false) ? false : v
end
iseq = RubyVM::InstructionSequence.compile(source)
sps = iseq.to_a[-1].filter_map do |i|
case i
in [:branchif | :branchunless | :branchnil | :pop | :leave | :setlocal | :checkmatch | :getconstant, *]
-1
in [:nop | :swap | :jump | :checktype | :setn , *]
0
in [x, *] if /putobject/ =~ x.to_s
1
in [:putnil | :putspecialobject | :dup | :topn | :putself | :duparray | :duphash, *]
1
in [:dupn, n]
n
in [:adjuststack, n]
-n
in [:newarray | :newhash, n]
1 - n
in [:opt_send_without_block | :send, {orig_argc:, kw_arg:}, *]
1 - (1 + orig_argc + kw_arg.length)
in [:opt_send_without_block | :send, {orig_argc:}, *]
1 - (1 + orig_argc)
in [*]
raise "unknown insn: #{i.inspect}"
in _
nil
end
end
sps = sps.inject([[0, 0]]) do |r, i|
r << [i, r[-1][1] + i]
end
sps.shift
puts source
puts
iseq.disasm.each_line.drop_while {|i| !(/\A0000 / =~ i)}.zip(sps) do |l, (sp, sum)|
print('%2d -> %2d (%2d) %s' % [sum - sp, sum, sp, l])
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment