mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
vm.inc now in C99
This changeset modifies the VM generator so that vm.inc is written in C99. Also added some comments in _insn_entry.erb so that the intention of each parts to be made more clear. I think this improves overall readability of the generated VM. Confirmed that the exact same binary is generated before/after this changeset. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@66923 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
parent
24b57b102c
commit
0a5b4c13ad
6 changed files with 50 additions and 22 deletions
|
@ -49,8 +49,8 @@ class RubyVM::Dumper
|
|||
end
|
||||
|
||||
def replace_pragma_line str, lineno
|
||||
if str == "#pragma RubyVM reset source\n" then
|
||||
return "#line #{lineno + 2} #{@file}\n"
|
||||
if /#(\s*)pragma RubyVM reset source\n/ =~ str then
|
||||
return "##{$1}line #{lineno + 2} #{@file}\n"
|
||||
else
|
||||
return str
|
||||
end
|
||||
|
|
|
@ -131,6 +131,14 @@ class RubyVM::BareInstructions
|
|||
sprintf "#<%s %s@%s:%d>", self.class.name, @name, @loc[0], @loc[1]
|
||||
end
|
||||
|
||||
def has_ope? var
|
||||
return @opes.any? {|i| i[:name] == var[:name] }
|
||||
end
|
||||
|
||||
def has_pop? var
|
||||
return @pops.any? {|i| i[:name] == var[:name] }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def generate_attribute t, k, v
|
||||
|
|
|
@ -31,7 +31,8 @@ class RubyVM::OperandsUnifications < RubyVM::BareInstructions
|
|||
@preamble = parts[:preamble]
|
||||
@spec = parts[:spec]
|
||||
super json.merge(:template => template)
|
||||
parts[:vars].each do |v|
|
||||
@konsts = parts[:vars]
|
||||
@konsts.each do |v|
|
||||
@variables[v[:name]] ||= v
|
||||
end
|
||||
end
|
||||
|
@ -63,6 +64,10 @@ class RubyVM::OperandsUnifications < RubyVM::BareInstructions
|
|||
end
|
||||
end
|
||||
|
||||
def has_ope? var
|
||||
super or @konsts.any? {|i| i[:name] == var[:name] }
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def namegen signature
|
||||
|
@ -101,7 +106,7 @@ class RubyVM::OperandsUnifications < RubyVM::BareInstructions
|
|||
vars << k
|
||||
src << {
|
||||
location: location,
|
||||
expr: " #{k[:name]} = #{j};"
|
||||
expr: " const #{k[:decl]} = #{j};"
|
||||
}
|
||||
end
|
||||
end
|
||||
|
|
|
@ -6,32 +6,36 @@
|
|||
%# conditions mentioned in the file COPYING are met. Consult the file for
|
||||
%# details.
|
||||
%;
|
||||
% body = render_c_expr(insn.expr).gsub(/^#/, '# ')
|
||||
|
||||
/* insn <%= insn.pretty_name %> */
|
||||
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 ## ') %>
|
||||
bool leaf;
|
||||
MAYBE_UNUSED(VALUE *) canary;
|
||||
% unless insn.declarations.empty?
|
||||
<%= insn.declarations.join(";\n ") %>;
|
||||
|
||||
% end
|
||||
/* ### Declare that we have just entered into an instruction. ### */
|
||||
START_OF_ORIGINAL_INSN(<%= insn.name %>);
|
||||
DEBUG_ENTER_INSN(<%=cstr insn.name %>);
|
||||
|
||||
/* ### Declare and assign variables. ### */
|
||||
% insn.preamble.each do |konst|
|
||||
<%= render_c_expr konst -%>
|
||||
% end
|
||||
%
|
||||
% insn.opes.each_with_index do |ope, i|
|
||||
<%= ope[:name] %> = (<%= ope[:type] %>)GET_OPERAND(<%= i + 1 %>);
|
||||
<%= ope[:decl] %> = (<%= ope[:type] %>)GET_OPERAND(<%= i + 1 %>);
|
||||
% end
|
||||
# define INSN_ATTR(x) <%= insn.call_attribute(' ## x ## ') %>
|
||||
bool leaf = INSN_ATTR(leaf);
|
||||
% insn.pops.reverse_each.with_index.reverse_each do |pop, i|
|
||||
<%= pop[:decl] %> = <%= insn.cast_from_VALUE pop, "TOPN(#{i})"%>;
|
||||
% end
|
||||
%
|
||||
% insn.pops.reverse_each.with_index.reverse_each do |pop, i|
|
||||
<%= pop[:name] %> = <%= insn.cast_from_VALUE pop, "TOPN(#{i})"%>;
|
||||
% insn.rets.each do |ret|
|
||||
% next if insn.has_ope?(ret) or insn.has_pop?(ret)
|
||||
<%= ret[:decl] %>;
|
||||
% end
|
||||
DEBUG_ENTER_INSN(INSN_ATTR(name));
|
||||
if (! (leaf = INSN_ATTR(leaf))) ADD_PC(INSN_ATTR(width));
|
||||
|
||||
/* ### Instruction preambles. ### */
|
||||
if (! leaf) ADD_PC(INSN_ATTR(width));
|
||||
% if insn.handles_sp?
|
||||
POPN(INSN_ATTR(popn));
|
||||
% end
|
||||
|
@ -40,7 +44,16 @@ INSN_ENTRY(<%= insn.name %>)
|
|||
% insn.opes.each_with_index do |ope, i|
|
||||
COLLECT_USAGE_OPERAND(INSN_ATTR(bin), <%= i %>, <%= ope[:name] %>);
|
||||
% end
|
||||
<%= render_c_expr insn.expr -%>
|
||||
% unless body.empty?
|
||||
|
||||
/* ### Here we do the instruction body. ### */
|
||||
%# NAME_OF_CURRENT_INSN is used in vm_exec.h
|
||||
# define NAME_OF_CURRENT_INSN <%= insn.name %>
|
||||
<%= body -%>
|
||||
# undef NAME_OF_CURRENT_INSN
|
||||
% end
|
||||
|
||||
/* ### Instruction trailers. ### */
|
||||
CHECK_VM_STACK_OVERFLOW_FOR_INSN(VM_REG_CFP, INSN_ATTR(retn));
|
||||
<%= insn.handle_canary "CHECK_CANARY()" -%>
|
||||
% if insn.handles_sp?
|
||||
|
@ -54,7 +67,8 @@ INSN_ENTRY(<%= insn.name %>)
|
|||
% end
|
||||
% end
|
||||
if (leaf) ADD_PC(INSN_ATTR(width));
|
||||
END_INSN(<%= insn.name %>);
|
||||
# undef INSN_ATTR
|
||||
# undef NAME_OF_CURRENT_INSN
|
||||
|
||||
/* ### Leave the instruction. ### */
|
||||
END_INSN(<%= insn.name %>);
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
% # JIT: Set const expressions for `RubyVM::OperandsUnifications` insn
|
||||
% insn.preamble.each do |amble|
|
||||
fprintf(f, "<%= amble.expr %>\n");
|
||||
fprintf(f, "<%= amble.expr.sub(/const \S+\s+/, '') %>\n");
|
||||
% end
|
||||
%
|
||||
% # JIT: Initialize operands
|
||||
|
|
|
@ -137,6 +137,7 @@ enum vm_regan_acttype {
|
|||
|
||||
#if VM_CHECK_MODE > 0
|
||||
#define SETUP_CANARY() \
|
||||
VALUE * canary; \
|
||||
if (leaf) { \
|
||||
canary = GET_SP(); \
|
||||
SET_SV(vm_stack_canary); \
|
||||
|
|
Loading…
Reference in a new issue