diff options
Diffstat (limited to 'tool/ruby_vm/models')
-rw-r--r-- | tool/ruby_vm/models/attribute.rb | 19 | ||||
-rwxr-xr-x | tool/ruby_vm/models/bare_instructions.rb | 21 | ||||
-rw-r--r-- | tool/ruby_vm/models/typemap.rb | 3 |
3 files changed, 34 insertions, 9 deletions
diff --git a/tool/ruby_vm/models/attribute.rb b/tool/ruby_vm/models/attribute.rb index cc16a5f898..de35e7234a 100644 --- a/tool/ruby_vm/models/attribute.rb +++ b/tool/ruby_vm/models/attribute.rb @@ -21,6 +21,13 @@ class RubyVM::Attribute @key = opts[:name] @expr = RubyVM::CExpr.new location: opts[:location], expr: opts[:expr] @type = opts[:type] + @ope_decls = @insn.opes.map do |operand| + decl = operand[:decl] + if @key == 'comptime_sp_inc' && operand[:type] == 'CALL_DATA' + decl = decl.gsub('CALL_DATA', 'CALL_INFO').gsub('cd', 'ci') + end + decl + end end def name @@ -32,22 +39,20 @@ class RubyVM::Attribute end def declaration - opes = @insn.opes - if opes.empty? + if @ope_decls.empty? argv = "void" else - argv = opes.map {|o| o[:decl] }.join(', ') + argv = @ope_decls.join(', ') end sprintf '%s %s(%s)', @type, name, argv end def definition - opes = @insn.opes - if opes.empty? + if @ope_decls.empty? argv = "void" else - argv = opes.map {|o| "MAYBE_UNUSED(#{o[:decl]})" }.join(",\n ") - argv = "\n #{argv}\n" if opes.size > 1 + argv = @ope_decls.map {|decl| "MAYBE_UNUSED(#{decl})" }.join(",\n ") + argv = "\n #{argv}\n" if @ope_decls.size > 1 end sprintf "%s\n%s(%s)", @type, name, argv end diff --git a/tool/ruby_vm/models/bare_instructions.rb b/tool/ruby_vm/models/bare_instructions.rb index e0fac5ff91..b0cc83a65a 100755 --- 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 + check_attribute_consistency predefine_attributes end @@ -139,8 +140,28 @@ class RubyVM::BareInstructions return @pops.any? {|i| i[:name] == var[:name] } end + def use_call_data? + @use_call_data ||= + @variables.find { |_, var_info| var_info[:type] == 'CALL_DATA' } + end + private + def check_attribute_consistency + if has_attribute?('sp_inc') \ + && use_call_data? \ + && !has_attribute?('comptime_sp_inc') + # As the call cache caches information that can only be obtained at + # runtime, we do not need it when compiling from AST to bytecode. This + # attribute defines an expression that computes the stack pointer + # increase based on just the call info to avoid reserving space for the + # call cache at compile time. In the expression, all call data operands + # are mapped to their call info counterpart. Additionally, all mentions + # of `cd` in the operand name are replaced with `ci`. + raise "Please define attribute `comptime_sp_inc` for `#{@name}`" + end + end + def generate_attribute t, k, v @attrs[k] ||= RubyVM::Attribute.new \ insn: self, \ diff --git a/tool/ruby_vm/models/typemap.rb b/tool/ruby_vm/models/typemap.rb index 65ddfea41d..1125c4bbf6 100644 --- a/tool/ruby_vm/models/typemap.rb +++ b/tool/ruby_vm/models/typemap.rb @@ -12,8 +12,7 @@ RubyVM::Typemap = { "..." => %w[. TS_VARIABLE], - "CALL_CACHE" => %w[E TS_CALLCACHE], - "CALL_INFO" => %w[C TS_CALLINFO], + "CALL_DATA" => %w[C TS_CALLDATA], "CDHASH" => %w[H TS_CDHASH], "GENTRY" => %w[G TS_GENTRY], "IC" => %w[K TS_IC], |