aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--builtin.h7
-rw-r--r--compile.c2
-rw-r--r--mini_builtin.c4
-rw-r--r--tool/mk_builtin_loader.rb72
4 files changed, 62 insertions, 23 deletions
diff --git a/builtin.h b/builtin.h
index 0d2b13e290..f4d485e08d 100644
--- a/builtin.h
+++ b/builtin.h
@@ -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);
diff --git a/compile.c b/compile.c
index d8fff33493..1e6400448c 100644
--- a/compile.c
+++ b/compile.c
@@ -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;
diff --git a/mini_builtin.c b/mini_builtin.c
index 3db640cf01..ad289bf896 100644
--- a/mini_builtin.c
+++ b/mini_builtin.c
@@ -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;
diff --git a/tool/mk_builtin_loader.rb b/tool/mk_builtin_loader.rb
index 5419c1167f..b7d7c17291 100644
--- a/tool/mk_builtin_loader.rb
+++ b/tool/mk_builtin_loader.rb
@@ -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"