summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--insns.def3
-rw-r--r--tool/ruby_vm/models/bare_instructions.rb13
-rw-r--r--tool/ruby_vm/views/_insn_entry.erb8
3 files changed, 19 insertions, 5 deletions
diff --git a/insns.def b/insns.def
index 8f43e55b8a..cad686fee6 100644
--- a/insns.def
+++ b/insns.def
@@ -680,6 +680,7 @@ defineclass
(ID id, ISEQ class_iseq, rb_num_t flags)
(VALUE cbase, VALUE super)
(VALUE val)
+// attr bool handles_frame = true;
{
VALUE klass = vm_find_or_create_class_by_id(id, flags, cbase, super);
@@ -829,6 +830,7 @@ leave
()
(VALUE val)
(VALUE val)
+// attr bool handles_frame = true;
{
if (OPT_CHECKED_RUN) {
const VALUE *const bp = vm_base_ptr(reg_cfp);
@@ -1380,6 +1382,7 @@ opt_call_c_function
(rb_insn_func_t funcptr)
()
()
+// attr bool handles_frame = true;
{
reg_cfp = (funcptr)(ec, reg_cfp);
diff --git a/tool/ruby_vm/models/bare_instructions.rb b/tool/ruby_vm/models/bare_instructions.rb
index 16d5782e2f..5ed27520ea 100644
--- a/tool/ruby_vm/models/bare_instructions.rb
+++ b/tool/ruby_vm/models/bare_instructions.rb
@@ -33,6 +33,7 @@ class RubyVM::BareInstructions
h[a.key] = a
}
@attrs_orig = @attrs.dup
+ predefine_attributes
end
def pretty_name
@@ -109,8 +110,8 @@ class RubyVM::BareInstructions
}.join
end
- def pushs_frame?
- opes.any? {|o| /CALL_INFO/ =~ o[:type] }
+ def handles_frame?
+ /\b(false|0)\b/ !~ @attrs['handles_frame'].expr.expr
end
def inspect
@@ -126,7 +127,13 @@ class RubyVM::BareInstructions
type: t, \
location: [], \
expr: v.to_s + ';'
- return @attrs[k] = attr
+ return @attrs[k] ||= attr
+ end
+
+ def predefine_attributes
+ generate_attribute 'sp_inc', 'rb_snum_t', rets.size - pops.size
+ generate_attribute 'handles_frame', 'bool', \
+ opes.any? {|o| /CALL_INFO/ =~ o[:type] }
end
def typesplit a
diff --git a/tool/ruby_vm/views/_insn_entry.erb b/tool/ruby_vm/views/_insn_entry.erb
index cebca8b8d0..f2f0f6418e 100644
--- a/tool/ruby_vm/views/_insn_entry.erb
+++ b/tool/ruby_vm/views/_insn_entry.erb
@@ -28,8 +28,9 @@ INSN_ENTRY(<%= insn.name %>)
<%= pop[:name] %> = <%= insn.cast_from_VALUE pop, "TOPN(#{i})"%>;
% end
DEBUG_ENTER_INSN(<%=cstr insn.name %>);
+% if insn.handles_frame?
ADD_PC(<%= insn.width %>);
- PREFETCH(GET_PC());
+% end
% unless insn.pops.empty?
POPN(<%= insn.pops.size %>);
% end
@@ -44,7 +45,10 @@ INSN_ENTRY(<%= insn.name %>)
PUSH(<%= insn.cast_to_VALUE ret %>);
% end
% end
-%
+% unless insn.handles_frame?
+ ADD_PC(<%= insn.width %>);
+ PREFETCH(GET_PC());
+% end
END_INSN(<%= insn.name %>);
}
#undef NAME_OF_CURRENT_INSN