diff --git a/compile.c b/compile.c index 1d762c485e..8f10ce0cbe 100644 --- a/compile.c +++ b/compile.c @@ -9273,12 +9273,37 @@ delegate_call_p(const rb_iseq_t *iseq, unsigned int argc, const LINK_ANCHOR *arg } } +static int +compile_builtin_attr_symbol(rb_iseq_t *iseq, VALUE symbol) +{ + VALUE string = rb_sym2str(symbol); + if (rb_streql_lit(string, "leaf")) { + ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_LEAF; + } + else if (rb_streql_lit(string, "inline_block")) { + ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_INLINE_BLOCK; + } + else if (rb_streql_lit(string, "use_block")) { + iseq_set_use_block(iseq); + } + else if (rb_streql_lit(string, "c_trace")) { + // Let the iseq act like a C method in backtraces + ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_C_TRACE; + } + else if (rb_streql_lit(string, "without_interrupts")) { + ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_WITHOUT_INTERRUPTS; + } + else { + return COMPILE_NG; + } + return COMPILE_OK; +} + // Compile Primitive.attr! :leaf, ... 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; @@ -9295,27 +9320,7 @@ compile_builtin_attr(rb_iseq_t *iseq, const NODE *node) } if (!SYMBOL_P(symbol)) goto non_symbol_arg; - - string = rb_sym2str(symbol); - if (strcmp(RSTRING_PTR(string), "leaf") == 0) { - ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_LEAF; - } - else if (strcmp(RSTRING_PTR(string), "inline_block") == 0) { - ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_INLINE_BLOCK; - } - else if (strcmp(RSTRING_PTR(string), "use_block") == 0) { - iseq_set_use_block(iseq); - } - else if (strcmp(RSTRING_PTR(string), "c_trace") == 0) { - // Let the iseq act like a C method in backtraces - ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_C_TRACE; - } - else if (strcmp(RSTRING_PTR(string), "without_interrupts") == 0) { - ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_WITHOUT_INTERRUPTS; - } - else { - goto unknown_arg; - } + if (compile_builtin_attr_symbol(iseq, symbol) != COMPILE_OK) goto unknown_arg; node = next; } return COMPILE_OK; @@ -9326,7 +9331,7 @@ compile_builtin_attr(rb_iseq_t *iseq, const NODE *node) 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)); + COMPILE_ERROR(ERROR_ARGS "unknown argument to attr!: %" PRIsVALUE, symbol); return COMPILE_NG; bad_arg: UNKNOWN_NODE("attr!", node, COMPILE_NG); diff --git a/internal/string.h b/internal/string.h index 060703e285..6dd6c2e4dd 100644 --- a/internal/string.h +++ b/internal/string.h @@ -220,6 +220,14 @@ rb_str_eql_internal(const VALUE str1, const VALUE str2) return Qfalse; } +static inline bool +rb_streql_cstr(VALUE str, const char *lit, size_t len) +{ + if ((size_t)RSTRING_LEN(str) != len) return false; + return memcmp(RSTRING_PTR(str), lit, len) == 0; +} +#define rb_streql_lit(str, lit) rb_streql_cstr(str, lit, rb_strlen_lit(lit)) + #if __has_builtin(__builtin_constant_p) # define rb_fstring_cstr(str) \ (__builtin_constant_p(str) ? \ diff --git a/iseq.c b/iseq.c index 720c8f976b..be10f5d90c 100644 --- a/iseq.c +++ b/iseq.c @@ -616,7 +616,7 @@ iseq_location_setup(rb_iseq_t *iseq, VALUE name, VALUE path, VALUE realpath, int RB_OBJ_WRITE(iseq, &loc->base_label, name); loc->first_lineno = first_lineno; - if (ISEQ_BODY(iseq)->local_iseq == iseq && strcmp(RSTRING_PTR(name), "initialize") == 0) { + if (ISEQ_BODY(iseq)->local_iseq == iseq && rb_streql_lit(name, "initialize")) { ISEQ_BODY(iseq)->param.flags.use_block = 1; } diff --git a/prism_compile.c b/prism_compile.c index 6a0422c4f4..bba486c972 100644 --- a/prism_compile.c +++ b/prism_compile.c @@ -3534,26 +3534,8 @@ pm_compile_builtin_attr(rb_iseq_t *iseq, pm_scope_node_t *scope_node, const pm_a } VALUE symbol = pm_static_literal_value(iseq, argument, scope_node); - VALUE string = rb_sym2str(symbol); - - if (strcmp(RSTRING_PTR(string), "leaf") == 0) { - ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_LEAF; - } - else if (strcmp(RSTRING_PTR(string), "inline_block") == 0) { - ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_INLINE_BLOCK; - } - else if (strcmp(RSTRING_PTR(string), "use_block") == 0) { - iseq_set_use_block(iseq); - } - else if (strcmp(RSTRING_PTR(string), "c_trace") == 0) { - // Let the iseq act like a C method in backtraces - ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_C_TRACE; - } - else if (strcmp(RSTRING_PTR(string), "without_interrupts") == 0) { - ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_WITHOUT_INTERRUPTS; - } - else { - COMPILE_ERROR(iseq, node_location->line, "unknown argument to attr!: %s", RSTRING_PTR(string)); + if (compile_builtin_attr_symbol(iseq, symbol) != COMPILE_OK) { + COMPILE_ERROR(iseq, node_location->line, "unknown argument to attr!: %" PRIsVALUE, symbol); return COMPILE_NG; } }