From 0c0c88d383a09fef18d8cf8a1457d1649a2cbd46 Mon Sep 17 00:00:00 2001 From: Takashi Kokubun Date: Sat, 11 Mar 2023 13:32:58 -0800 Subject: Support multiple attributes with Primitive.attr! --- compile.c | 51 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 45 insertions(+), 6 deletions(-) (limited to 'compile.c') diff --git a/compile.c b/compile.c index 7a6f324601..76658fc153 100644 --- a/compile.c +++ b/compile.c @@ -8214,6 +8214,47 @@ delegate_call_p(const rb_iseq_t *iseq, unsigned int argc, const LINK_ANCHOR *arg } } +// Compile Primitive.attr! :inline, ... +static int +compile_builtin_attr(rb_iseq_t *iseq, const NODE *node) +{ + VALUE symbol; + VALUE string; + if (!node) goto no_arg; + while (node) { + if (!nd_type_p(node, NODE_LIST)) goto bad_arg; + const NODE *next = node->nd_next; + + node = node->nd_head; + if (!node) goto no_arg; + if (!nd_type_p(node, NODE_LIT)) goto bad_arg; + + symbol = node->nd_lit; + if (!SYMBOL_P(symbol)) goto non_symbol_arg; + + string = rb_sym_to_s(symbol); + if (strcmp(RSTRING_PTR(string), "inline") == 0) { + ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_INLINE; + } + else { + goto unknown_arg; + } + node = next; + } + return COMPILE_OK; + no_arg: + COMPILE_ERROR(ERROR_ARGS "attr!: no argument"); + return COMPILE_NG; + non_symbol_arg: + COMPILE_ERROR(ERROR_ARGS "non symbol argument to attr!: %s", rb_builtin_class_name(symbol)); + return COMPILE_NG; + unknown_arg: + COMPILE_ERROR(ERROR_ARGS "unknown argument to attr!: %s", RSTRING_PTR(string)); + return COMPILE_NG; + bad_arg: + UNKNOWN_NODE("attr!", node, COMPILE_NG); +} + static int compile_builtin_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, const NODE *line_node, int popped) { @@ -8337,9 +8378,7 @@ compile_builtin_function_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NOD return COMPILE_OK; } else if (strcmp("attr!", builtin_func) == 0) { - // There's only "inline" attribute for now - ISEQ_BODY(iseq)->builtin_inline_p = true; - return COMPILE_OK; + return compile_builtin_attr(iseq, args_node); } else if (strcmp("arg!", builtin_func) == 0) { return compile_builtin_arg(iseq, ret, args_node, line_node, popped); @@ -12122,7 +12161,7 @@ ibf_dump_iseq_each(struct ibf_dump *dump, const rb_iseq_t *iseq) ibf_dump_write_small_value(dump, body->ci_size); ibf_dump_write_small_value(dump, body->stack_max); ibf_dump_write_small_value(dump, body->catch_except_p); - ibf_dump_write_small_value(dump, body->builtin_inline_p); + ibf_dump_write_small_value(dump, body->builtin_attrs); #undef IBF_BODY_OFFSET @@ -12235,7 +12274,7 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset) const unsigned int ci_size = (unsigned int)ibf_load_small_value(load, &reading_pos); const unsigned int stack_max = (unsigned int)ibf_load_small_value(load, &reading_pos); const char catch_except_p = (char)ibf_load_small_value(load, &reading_pos); - const bool builtin_inline_p = (bool)ibf_load_small_value(load, &reading_pos); + const unsigned int builtin_attrs = (unsigned int)ibf_load_small_value(load, &reading_pos); // setup fname and dummy frame VALUE path = ibf_load_object(load, location_pathobj_index); @@ -12308,7 +12347,7 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset) load_body->location.code_location.end_pos.lineno = location_code_location_end_pos_lineno; load_body->location.code_location.end_pos.column = location_code_location_end_pos_column; load_body->catch_except_p = catch_except_p; - load_body->builtin_inline_p = builtin_inline_p; + load_body->builtin_attrs = builtin_attrs; load_body->ivc_size = ivc_size; load_body->icvarc_size = icvarc_size; -- cgit v1.2.1