summaryrefslogtreecommitdiff
path: root/tool/ruby_vm/views/_insn_entry.erb
diff options
context:
space:
mode:
Diffstat (limited to 'tool/ruby_vm/views/_insn_entry.erb')
-rw-r--r--tool/ruby_vm/views/_insn_entry.erb21
1 files changed, 21 insertions, 0 deletions
diff --git a/tool/ruby_vm/views/_insn_entry.erb b/tool/ruby_vm/views/_insn_entry.erb
index e3e3ea42ea..90a489f624 100644
--- a/tool/ruby_vm/views/_insn_entry.erb
+++ b/tool/ruby_vm/views/_insn_entry.erb
@@ -13,6 +13,12 @@ INSN_ENTRY(<%= insn.name %>)
%# 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 ") %>;
@@ -33,12 +39,27 @@ INSN_ENTRY(<%= insn.name %>)
% 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
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
% if insn.handles_sp?
% insn.rets.reverse_each do |ret|
PUSH(<%= insn.cast_to_VALUE ret %>);