mirror of
https://github.com/ruby/ruby.git
synced 2026-08-02 20:49:12 +08:00
Use bounded comparisons for compiler attributes
Compare compiler attribute names using Ruby string lengths. Share attribute handling between the compiler paths to keep their behavior aligned.
This commit is contained in:
parent
878d20ef1b
commit
21b7c7257f
Notes:
git
2026-07-15 04:29:38 +00:00
51
compile.c
51
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);
|
||||
|
||||
@ -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) ? \
|
||||
|
||||
2
iseq.c
2
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;
|
||||
}
|
||||
|
||||
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user