summaryrefslogtreecommitdiff
path: root/tool/ruby_vm/models
diff options
context:
space:
mode:
Diffstat (limited to 'tool/ruby_vm/models')
-rw-r--r--tool/ruby_vm/models/attribute.rb19
-rwxr-xr-xtool/ruby_vm/models/bare_instructions.rb21
-rw-r--r--tool/ruby_vm/models/typemap.rb3
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],