ruby-changes:52500
From: shyouhei <ko1@a...>
Date: Thu, 13 Sep 2018 12:46:52 +0900 (JST)
Subject: [ruby-changes:52500] shyouhei:r64709 (trunk): move canary-related statements into macros
shyouhei 2018-09-13 12:46:46 +0900 (Thu, 13 Sep 2018) New Revision: 64709 https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=64709 Log: move canary-related statements into macros This is mostly cosmetic. Should generate a slightly readable vm.inc output. Modified files: trunk/tool/ruby_vm/models/bare_instructions.rb trunk/tool/ruby_vm/views/_insn_entry.erb trunk/vm_insnhelper.h Index: tool/ruby_vm/views/_insn_entry.erb =================================================================== --- tool/ruby_vm/views/_insn_entry.erb (revision 64708) +++ tool/ruby_vm/views/_insn_entry.erb (revision 64709) @@ -13,16 +13,11 @@ INSN_ENTRY(<%= insn.name %>) https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_insn_entry.erb#L13 %# NAME_OF_CURRENT_INSN is used in vm_exec.h # define NAME_OF_CURRENT_INSN <%= insn.name %> # define INSN_ATTR(x) <%= insn.call_attribute(' ## x ## ') %> -% unless insn.complicated_return_values? -# if VM_CHECK_MODE > 0 - bool leaf; - VALUE *canary; -# endif -% end % unless insn.declarations.empty? <%= insn.declarations.join(";\n ") %>; % end +<%= insn.handle_canary "DECLARE_CANARY" -%> START_OF_ORIGINAL_INSN(<%= insn.name %>); % insn.preamble.each do |konst| <%= render_c_expr konst -%> @@ -39,27 +34,14 @@ INSN_ENTRY(<%= insn.name %>) https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/views/_insn_entry.erb#L34 % if insn.handles_sp? POPN(INSN_ATTR(popn)); % end -% unless insn.complicated_return_values? -#if VM_CHECK_MODE > 0 - if ((leaf = INSN_ATTR(leaf))) { - canary = STACK_ADDR_FROM_TOP(-1); - *canary = vm_stack_canary; - } -#endif -% end +<%= insn.handle_canary "SETUP_CANARY()" -%> COLLECT_USAGE_INSN(INSN_ATTR(bin)); % insn.opes.each_with_index do |ope, i| COLLECT_USAGE_OPERAND(INSN_ATTR(bin), <%= i %>, <%= ope[:name] %>); % end <%= render_c_expr insn.expr -%> CHECK_VM_STACK_OVERFLOW_FOR_INSN(VM_REG_CFP, INSN_ATTR(retn)); -% unless insn.complicated_return_values? -#if VM_CHECK_MODE > 0 - if (leaf && (*canary != vm_stack_canary)) { - vm_canary_is_found_dead(INSN_ATTR(bin), *canary); - } -#endif -% end +<%= insn.handle_canary "CHECK_CANARY()" -%> % if insn.handles_sp? % insn.rets.reverse_each do |ret| PUSH(<%= insn.cast_to_VALUE ret %>); Index: tool/ruby_vm/models/bare_instructions.rb =================================================================== --- tool/ruby_vm/models/bare_instructions.rb (revision 64708) +++ tool/ruby_vm/models/bare_instructions.rb (revision 64709) @@ -109,8 +109,20 @@ class RubyVM::BareInstructions https://github.com/ruby/ruby/blob/trunk/tool/ruby_vm/models/bare_instructions.rb#L109 @attrs.fetch('leaf').expr.expr == 'true;' end - def complicated_return_values? - @sig[:ret].any? {|i| i == '...' } + def handle_canary stmt + # Stack canary is basically a good thing that we want to add, however: + # + # - When the instruction returns variadic number of return values, + # it is not easy to tell where is the stack top. We can't but + # skip it. + # + # - When the instruction body is empty (like putobject), we can + # say for 100% sure that canary is a waste of time. + # + # So we skip canary for those cases. + return '' if @sig[:ret].any? {|i| i == '...' } + return '' if @expr.blank? + return " #{stmt};\n" end def inspect Index: vm_insnhelper.h =================================================================== --- vm_insnhelper.h (revision 64708) +++ vm_insnhelper.h (revision 64709) @@ -201,6 +201,27 @@ enum vm_regan_acttype { https://github.com/ruby/ruby/blob/trunk/vm_insnhelper.h#L201 /**********************************************************/ +/* deal with stack canary */ +/**********************************************************/ + +#if VM_CHECK_MODE > 0 +#define DECLARE_CANARY bool leaf; VALUE *canary +#define SETUP_CANARY() \ + if ((leaf = INSN_ATTR(leaf))) { \ + canary = GET_SP(); \ + SET_SV(vm_stack_canary); \ + } +#define CHECK_CANARY() \ + if (leaf && (*canary != vm_stack_canary)) { \ + vm_canary_is_found_dead(INSN_ATTR(bin), *canary); \ + } +#else +#define DECLARE_CANARY /* void */ +#define SETUP_CANARY() /* void */ +#define CHECK_CANARY() /* void */ +#endif + +/**********************************************************/ /* others */ /**********************************************************/ -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/