1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

readable function names for inline functions.

Now, C functions written by __builtin_cexpr!(code) and others are
named as "__builtin_inline#{n}". However, it is difficult to know
what the function is. This patch rename them into
"__builtin_foo_#{lineno}" when cexpr! is in 'foo' method.
This commit is contained in:
Koichi Sasada 2019-12-13 17:26:12 +09:00
parent 1140625cd3
commit 97a17a51b8
4 changed files with 62 additions and 23 deletions

View file

@ -13,7 +13,12 @@ struct rb_builtin_function {
const char * const name;
};
#define RB_BUILTIN_FUNCTION(_i, _name, _arity) { .name = #_name, .func_ptr = (void *)_name, .argc = _arity, .index = _i }
#define RB_BUILTIN_FUNCTION(_i, _name, _fname, _arity) { \
.name = #_name, \
.func_ptr = (void *)_fname, \
.argc = _arity, \
.index = _i \
}
void rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table);

View file

@ -6954,7 +6954,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
strcmp("cexpr!", builtin_func) == 0) {
inlinec:;
int inline_index = GET_VM()->builtin_inline_index++;
snprintf(inline_func, 0x20, "builtin_inline%d", inline_index);
snprintf(inline_func, 0x20, "_bi%d", inline_index);
builtin_func = inline_func;
args_node = NULL;
goto retry;

View file

@ -18,8 +18,10 @@ builtin_iseq_load(const char *feature_name, const struct rb_builtin_function *ta
{
VALUE name_str = 0;
rb_ast_t *ast = rb_builtin_ast(feature_name, &name_str);
rb_vm_t *vm = GET_VM();
GET_VM()->builtin_function_table = table;
vm->builtin_function_table = table;
vm->builtin_inline_index = 0;
const rb_iseq_t *iseq = rb_iseq_new(&ast->body, name_str, name_str, Qnil, NULL, ISEQ_TYPE_TOP);
GET_VM()->builtin_function_table = NULL;

View file

@ -5,7 +5,37 @@ def inline_text argc, prev_insn
prev_insn[1].rstrip
end
def collect_builtin base, iseq_ary, bs, inlines
def make_cfunc_name inlines, name, lineno
case name
when /\[\]/
name = '_GETTER'
when /\[\]=/
name = '_SETTER'
else
name = name.tr('!?', 'EP')
end
base = "builtin_inline_#{name}_#{lineno}"
if inlines[base]
1000.times{|i|
name = "#{base}_#{i}"
return name unless inlines[name]
}
raise "too many functions in same line..."
else
base
end
end
def collect_builtin base, iseq_ary, name, bs, inlines
case type = iseq_ary[9]
when :method
name = iseq_ary[5]
when :class
name = 'class'
else
end
code = iseq_ary[13]
params = iseq_ary[10]
prev_insn = nil
@ -27,7 +57,7 @@ def collect_builtin base, iseq_ary, bs, inlines
when :send
ci = insn[1]
if /\A__builtin_(.+)/ =~ ci[:mid]
func_name = $1
cfunc_name = func_name = $1
argc = ci[:orig_argc]
if /(.+)\!\z/ =~ func_name
@ -35,37 +65,39 @@ def collect_builtin base, iseq_ary, bs, inlines
when 'cstmt'
text = inline_text argc, prev_insn
func_name = "builtin_inline#{inlines.size}"
inlines << [func_name, [lineno, text, params]]
func_name = "_bi#{inlines.size}"
cfunc_name = make_cfunc_name(inlines, name, lineno)
inlines[cfunc_name] = [lineno, text, params, func_name]
argc -= 1
when 'cexpr', 'cconst'
text = inline_text argc, prev_insn
code = "return #{text};"
func_name = "builtin_inline#{inlines.size}"
func_name = "_bi#{inlines.size}"
cfunc_name = make_cfunc_name(inlines, name, lineno)
params = [] if $1 == 'cconst'
inlines << [func_name, [lineno, code, params]]
inlines[cfunc_name] = [lineno, code, params, func_name]
argc -= 1
when 'cinit'
text = inline_text argc, prev_insn
func_name = nil
inlines << [nil, [lineno, text, nil]]
inlines[inlines.size] = [nil, [lineno, text, nil, nil]]
argc -= 1
end
end
if bs[func_name] &&
bs[func_name] != argc
bs[func_name] != [argc, cfunc_name]
raise "same builtin function \"#{func_name}\", but different arity (was #{bs[func_name]} but #{argc})"
end
bs[func_name] = argc if func_name
bs[func_name] = [argc, cfunc_name] if func_name
end
else
insn[1..-1].each{|op|
if op.is_a?(Array) && op[0] == "YARVInstructionSequence/SimpleDataFormat"
collect_builtin base, op, bs, inlines
collect_builtin base, op, name, bs, inlines
end
}
end
@ -81,7 +113,7 @@ def mk_builtin_header file
ofile = "#{file}inc"
# bs = { func_name => argc }
collect_builtin(base, RubyVM::InstructionSequence.compile_file(file, false).to_a, bs = {}, inlines = [])
collect_builtin(base, RubyVM::InstructionSequence.compile_file(file, false).to_a, 'top', bs = {}, inlines = {})
begin
f = open(ofile, 'w')
@ -99,9 +131,9 @@ def mk_builtin_header file
lineno = 6
line_file = file.gsub('\\', '/')
inlines.each{|name, (body_lineno, text, params)|
if name
f.puts "static VALUE #{name}(rb_execution_context_t *ec, const VALUE self) {"
inlines.each{|cfunc_name, (body_lineno, text, params, func_name)|
if String === cfunc_name
f.puts "static VALUE #{cfunc_name}(rb_execution_context_t *ec, const VALUE self) {"
lineno += 1
params.reverse_each.with_index{|param, i|
@ -135,10 +167,10 @@ def mk_builtin_header file
table = "#{base}_table"
f.puts " // table definition"
f.puts " static const struct rb_builtin_function #{table}[] = {"
bs.each.with_index{|(func, argc), i|
f.puts " RB_BUILTIN_FUNCTION(#{i}, #{func}, #{argc}),"
bs.each.with_index{|(func, (argc, cfunc_name)), i|
f.puts " RB_BUILTIN_FUNCTION(#{i}, #{func}, #{cfunc_name}, #{argc}),"
}
f.puts " RB_BUILTIN_FUNCTION(-1, NULL, 0),"
f.puts " RB_BUILTIN_FUNCTION(-1, NULL, NULL, 0),"
f.puts " };"
f.puts
@ -147,8 +179,8 @@ def mk_builtin_header file
f.puts "#if GCC_VERSION_SINCE(5, 1, 0) || __clang__"
f.puts "COMPILER_WARNING_ERROR(-Wincompatible-pointer-types)"
f.puts "#endif"
bs.each{|func, argc|
f.puts " if (0) rb_builtin_function_check_arity#{argc}(#{func});"
bs.each{|func, (argc, cfunc_name)|
f.puts " if (0) rb_builtin_function_check_arity#{argc}(#{cfunc_name});"
}
f.puts "COMPILER_WARNING_POP"