summaryrefslogtreecommitdiff
path: root/compile.c
diff options
context:
space:
mode:
authorTakashi Kokubun <takashikkbn@gmail.com>2023-03-11 13:32:58 -0800
committerTakashi Kokubun <takashikkbn@gmail.com>2023-03-11 14:19:46 -0800
commit0c0c88d383a09fef18d8cf8a1457d1649a2cbd46 (patch)
tree4c625c35cb6835b7c3e55de39d5087e393fd4cda /compile.c
parent3a02c7818cb6cbcc70957dfc449ebf32f9dd9e0b (diff)
downloadruby-0c0c88d383a09fef18d8cf8a1457d1649a2cbd46.tar.gz
Support multiple attributes with Primitive.attr!
Diffstat (limited to 'compile.c')
-rw-r--r--compile.c51
1 files changed, 45 insertions, 6 deletions
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;