diff options
-rw-r--r-- | compile.c | 24 | ||||
-rw-r--r-- | tool/mk_builtin_loader.rb | 76 |
2 files changed, 76 insertions, 24 deletions
@@ -6920,17 +6920,30 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in } else { char inline_func[0x20]; + bool cconst = false; retry:; const struct rb_builtin_function *bf = iseq_builtin_function_lookup(iseq, builtin_func); if (bf == NULL) { - if (strcmp("inline!", builtin_func) == 0) { + if (strcmp("cstmt!", builtin_func) == 0 || + strcmp("cexpr!", builtin_func) == 0) { + inlinec:; int inline_index = GET_VM()->builtin_inline_index++; - snprintf(inline_func, 0x20, "rb_compiled_inline%d", inline_index); + snprintf(inline_func, 0x20, "builtin_inline%d", inline_index); builtin_func = inline_func; args_node = NULL; goto retry; } + else if (strcmp("cconst!", builtin_func) == 0) { + cconst = true; + goto inlinec; + } + else if (strcmp("cinit!", builtin_func) == 0) { + // ignore + GET_VM()->builtin_inline_index++; + return COMPILE_OK; + } + if (1) { rb_bug("can't find builtin function:%s", builtin_func); } @@ -6940,6 +6953,13 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in return COMPILE_NG; } + if (cconst) { + typedef VALUE(*builtin_func0)(void *, VALUE); + VALUE const_val = (*(builtin_func0)bf->func_ptr)(NULL, Qnil); + ADD_INSN1(ret, line, putobject, const_val); + return COMPILE_OK; + } + // fprintf(stderr, "func_name:%s -> %p\n", builtin_func, bf->func_ptr); argc = setup_args(iseq, args, args_node, &flag, &keywords); diff --git a/tool/mk_builtin_loader.rb b/tool/mk_builtin_loader.rb index 87eb042145..5419c1167f 100644 --- a/tool/mk_builtin_loader.rb +++ b/tool/mk_builtin_loader.rb @@ -1,4 +1,10 @@ +def inline_text argc, prev_insn + raise "argc (#{argc}) of inline! should be 1" unless argc == 1 + raise "1st argument should be string literal" unless prev_insn[0] == :putstring + prev_insn[1].rstrip +end + def collect_builtin base, iseq_ary, bs, inlines code = iseq_ary[13] params = iseq_ary[10] @@ -24,14 +30,29 @@ def collect_builtin base, iseq_ary, bs, inlines func_name = $1 argc = ci[:orig_argc] - if func_name == 'inline!' - raise "argc (#{argc}) of inline! should be 1" unless argc == 1 - raise "1st argument should be string literal" unless prev_insn[0] == :putstring - text = prev_insn[1].rstrip - - func_name = "rb_compiled_inline#{inlines.size}" - inlines << [func_name, [lineno, text, params]] - argc -= 1 + if /(.+)\!\z/ =~ func_name + case $1 + when 'cstmt' + text = inline_text argc, prev_insn + + func_name = "builtin_inline#{inlines.size}" + inlines << [func_name, [lineno, text, params]] + argc -= 1 + + when 'cexpr', 'cconst' + text = inline_text argc, prev_insn + code = "return #{text};" + + func_name = "builtin_inline#{inlines.size}" + params = [] if $1 == 'cconst' + inlines << [func_name, [lineno, code, params]] + argc -= 1 + when 'cinit' + text = inline_text argc, prev_insn + func_name = nil + inlines << [nil, [lineno, text, nil]] + argc -= 1 + end end if bs[func_name] && @@ -39,7 +60,7 @@ def collect_builtin base, iseq_ary, bs, inlines raise "same builtin function \"#{func_name}\", but different arity (was #{bs[func_name]} but #{argc})" end - bs[func_name] = argc + bs[func_name] = argc if func_name end else insn[1..-1].each{|op| @@ -76,25 +97,36 @@ def mk_builtin_header file f.puts "// with #{file}" f.puts lineno = 6 + line_file = file.gsub('\\', '/') inlines.each{|name, (body_lineno, text, params)| - f.puts "static VALUE #{name}(rb_execution_context_t *ec, const VALUE self) {" - lineno += 1 + if name + f.puts "static VALUE #{name}(rb_execution_context_t *ec, const VALUE self) {" + lineno += 1 - params.reverse_each.with_index{|param, i| - next unless Symbol === param - f.puts "MAYBE_UNUSED(const VALUE) #{param} = rb_vm_lvar(ec, #{-3 - i});" + params.reverse_each.with_index{|param, i| + next unless Symbol === param + f.puts "MAYBE_UNUSED(const VALUE) #{param} = rb_vm_lvar(ec, #{-3 - i});" + lineno += 1 + } + f.puts "#line #{body_lineno} \"#{line_file}\"" lineno += 1 - } - f.puts "#line #{body_lineno} \"#{file}\"" - lineno += 1 - f.puts text - lineno += text.count("\n") + 1 + f.puts text + lineno += text.count("\n") + 1 - f.puts "#line #{lineno + 2} \"#{ofile}\"" # TODO: restore line number. - f.puts "}" - lineno += 2 + f.puts "#line #{lineno + 2} \"#{ofile}\"" # TODO: restore line number. + f.puts "}" + lineno += 2 + else + # cinit! + f.puts "#line #{body_lineno} \"#{line_file}\"" + lineno += 1 + f.puts text + lineno += text.count("\n") + 1 + f.puts "#line #{lineno + 2} \"#{ofile}\"" # TODO: restore line number. + lineno += 1 + end } f.puts "static void load_#{base}(void)" |