summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--insns.def11
-rwxr-xr-xtool/ruby_vm/models/bare_instructions.rb24
2 files changed, 23 insertions, 12 deletions
diff --git a/insns.def b/insns.def
index 629a2f1bc9..132ce2f179 100644
--- a/insns.def
+++ b/insns.def
@@ -44,9 +44,11 @@
`insn_stack_increase`.
* handles_sp: If it is true, VM deals with sp in the insn.
+ Default is if the instruction takes ISEQ operand or not.
* leaf: indicates that the instruction is "leaf" i.e. it does
- not introduce new stack frame on top of it. Default true.
+ not introduce new stack frame on top of it.
+ If an instruction handles sp, that can never be a leaf.
- Attributes can access operands, but not stack (push/pop) variables.
@@ -357,7 +359,7 @@ putiseq
(ISEQ iseq)
()
(VALUE ret)
-// attr bool leaf = true; /* yes it is */
+// attr bool handles_sp = false; /* of course it doesn't */
{
ret = (VALUE)iseq;
}
@@ -713,7 +715,6 @@ defineclass
(ID id, ISEQ class_iseq, rb_num_t flags)
(VALUE cbase, VALUE super)
(VALUE val)
-// attr bool handles_sp = true;
{
VALUE klass = vm_find_or_create_class_by_id(id, flags, cbase, super);
@@ -740,7 +741,6 @@ send
(CALL_INFO ci, CALL_CACHE cc, ISEQ blockiseq)
(...)
(VALUE val)
-// attr bool handles_sp = true;
// attr rb_snum_t sp_inc = - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG) ? 1 : 0));
{
struct rb_calling_info calling;
@@ -757,7 +757,6 @@ opt_send_without_block
(CALL_INFO ci, CALL_CACHE cc)
(...)
(VALUE val)
-// attr bool leaf = false; /* Of course it isn't. */
// attr bool handles_sp = true;
// attr rb_snum_t sp_inc = -ci->orig_argc;
{
@@ -828,7 +827,6 @@ invokesuper
(CALL_INFO ci, CALL_CACHE cc, ISEQ blockiseq)
(...)
(VALUE val)
-// attr bool handles_sp = true;
// attr rb_snum_t sp_inc = - (int)(ci->orig_argc + ((ci->flag & VM_CALL_ARGS_BLOCKARG) ? 1 : 0));
{
struct rb_calling_info calling;
@@ -845,7 +843,6 @@ invokeblock
(CALL_INFO ci)
(...)
(VALUE val)
-// attr bool leaf = false; /* Of course it isn't. */
// attr bool handles_sp = true;
// attr rb_snum_t sp_inc = 1 - ci->orig_argc;
{
diff --git a/tool/ruby_vm/models/bare_instructions.rb b/tool/ruby_vm/models/bare_instructions.rb
index 7d9ed6da5a..2767f383e6 100755
--- a/tool/ruby_vm/models/bare_instructions.rb
+++ b/tool/ruby_vm/models/bare_instructions.rb
@@ -144,6 +144,7 @@ class RubyVM::BareInstructions
end
def predefine_attributes
+ # Beware: order matters here because some attribute depends another.
generate_attribute 'const char*', 'name', "insn_name(#{bin})"
generate_attribute 'enum ruby_vminsn_type', 'bin', bin
generate_attribute 'rb_num_t', 'open', opes.size
@@ -151,11 +152,24 @@ class RubyVM::BareInstructions
generate_attribute 'rb_num_t', 'retn', rets.size
generate_attribute 'rb_num_t', 'width', width
generate_attribute 'rb_snum_t', 'sp_inc', rets.size - pops.size
- generate_attribute 'bool', 'handles_sp', false
- generate_attribute 'bool', 'leaf', opes.all? {|o|
- # Insn with ISEQ should yield it; can never be a leaf.
- o[:type] != 'ISEQ'
- }
+ generate_attribute 'bool', 'handles_sp', default_definition_of_handles_sp
+ generate_attribute 'bool', 'leaf', default_definition_of_leaf
+ end
+
+ def default_definition_of_handles_sp
+ # Insn with ISEQ should yield it; can handle sp.
+ return opes.any? {|o| o[:type] == 'ISEQ' }
+ end
+
+ def default_definition_of_leaf
+ # Insn that handles SP can never be a leaf.
+ if not has_attribute? 'handles_sp' then
+ return ! default_definition_of_handles_sp
+ elsif handles_sp? then
+ return "! #{call_attribute 'handles_sp'}"
+ else
+ return true
+ end
end
def typesplit a