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

[Feature #16254] Allow __builtin.func style

This commit is contained in:
Nobuyoshi Nakada 2020-05-18 10:09:28 +09:00
parent f3e081c6b6
commit c8703a17ce
Notes: git 2020-06-19 18:47:20 +09:00
2 changed files with 38 additions and 10 deletions

View file

@ -7039,18 +7039,30 @@ iseq_builtin_function_lookup(const rb_iseq_t *iseq, const char *name)
} }
static const char * static const char *
iseq_builtin_function_name(ID mid) iseq_builtin_function_name(const enum node_type type, const NODE *recv, ID mid)
{ {
const char *name = rb_id2name(mid); const char *name = rb_id2name(mid);
static const char prefix[] = "__builtin_"; static const char prefix[] = "__builtin_";
const size_t prefix_len = sizeof(prefix) - 1; const size_t prefix_len = sizeof(prefix) - 1;
if (UNLIKELY(strncmp(prefix, name, prefix_len) == 0)) { if (type == NODE_CALL) {
return &name[prefix_len]; if (recv) {
switch (nd_type(recv)) {
case NODE_VCALL:
if (recv->nd_mid == rb_intern("__builtin")) {
return name;
}
break;
default: break;
}
}
} }
else { else if (type == NODE_VCALL || type == NODE_FCALL) {
return NULL; if (UNLIKELY(strncmp(prefix, name, prefix_len) == 0)) {
return &name[prefix_len];
}
} }
return NULL;
} }
static int static int
@ -7204,8 +7216,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co
NODE *args_node = node->nd_args; NODE *args_node = node->nd_args;
if (UNLIKELY(iseq_has_builtin_function_table(iseq)) && if (UNLIKELY(iseq_has_builtin_function_table(iseq)) &&
(type == NODE_VCALL || type == NODE_FCALL) && (builtin_func = iseq_builtin_function_name(type, node->nd_recv, mid)) != NULL) {
(builtin_func = iseq_builtin_function_name(mid)) != NULL) {
if (parent_block != NULL) { if (parent_block != NULL) {
COMPILE_ERROR(iseq, line, "should not call builtins here."); COMPILE_ERROR(iseq, line, "should not call builtins here.");

View file

@ -72,7 +72,7 @@ end
def collect_builtin base, tree, name, bs, inlines, params = nil def collect_builtin base, tree, name, bs, inlines, params = nil
while tree while tree
call = sep = mid = args = nil call = recv = sep = mid = args = nil
case tree.first case tree.first
when :def when :def
params = collect_params(tree[2]) params = collect_params(tree[2])
@ -93,6 +93,8 @@ def collect_builtin base, tree, name, bs, inlines, params = nil
when :method_add_arg when :method_add_arg
_, mid, (_, (_, args)) = tree _, mid, (_, (_, args)) = tree
case mid.first case mid.first
when :call
_, recv, sep, mid = mid
when :fcall when :fcall
_, mid = mid _, mid = mid
else else
@ -102,12 +104,27 @@ def collect_builtin base, tree, name, bs, inlines, params = nil
_, mid = tree _, mid = tree
when :command # FCALL when :command # FCALL
_, mid, (_, args) = tree _, mid, (_, args) = tree
when :call, :command_call # CALL
_, recv, sep, mid, (_, args) = tree
end end
if mid if mid
raise "unknown sexp: #{mid.inspect}" unless mid.first == :@ident raise "unknown sexp: #{mid.inspect}" unless mid.first == :@ident
_, mid, (lineno,) = mid _, mid, (lineno,) = mid
if /\A__builtin_(.+)/ =~ mid if recv
cfunc_name = func_name = $1 func_name = nil
case recv.first
when :vcall
_, recv = recv
if recv.first == :@ident and recv[1] == "__builtin"
func_name = mid.to_s
end
end
collect_builtin(base, recv, name, bs, inlines) unless func_name
else
func_name = mid[/\A__builtin_(.+)/, 1]
end
if func_name
cfunc_name = func_name
args.pop unless (args ||= []).last args.pop unless (args ||= []).last
argc = args.size argc = args.size