From 89e489d51d164cf22bce3a7580e5695da22fb347 Mon Sep 17 00:00:00 2001 From: Nobuyoshi Nakada Date: Fri, 13 Nov 2020 14:03:25 +0900 Subject: Make shareable_constant_value tri-state --- parse.y | 90 +++++++++++++++++++++++++++++++++++++++---------- test/ruby/test_parse.rb | 8 ++--- 2 files changed, 76 insertions(+), 22 deletions(-) diff --git a/parse.y b/parse.y index fa2139b721..0e1ed592c7 100644 --- a/parse.y +++ b/parse.y @@ -26,18 +26,11 @@ #include #include -struct lex_context { - unsigned int in_defined: 1; - unsigned int in_kwarg: 1; - unsigned int in_def: 1; - unsigned int in_class: 1; - unsigned int shareable_constant_value: 1; -}; - -#define NO_LEX_CTXT (struct lex_context){0} +struct lex_context; #include "internal.h" #include "internal/compile.h" +#include "internal/compilers.h" #include "internal/complex.h" #include "internal/error.h" #include "internal/hash.h" @@ -52,7 +45,6 @@ struct lex_context { #include "internal/util.h" #include "internal/variable.h" #include "node.h" -#include "parse.h" #include "probes.h" #include "regenc.h" #include "ruby/encoding.h" @@ -63,6 +55,24 @@ struct lex_context { #include "ruby/ractor.h" #include "symbol.h" +enum shareability { + shareable_none, + shareable_literal, + shareable_everything, +}; + +struct lex_context { + unsigned int in_defined: 1; + unsigned int in_kwarg: 1; + unsigned int in_def: 1; + unsigned int in_class: 1; + BITFIELD(enum shareability, shareable_constant_value, 2); +}; + +#include "parse.h" + +#define NO_LEX_CTXT (struct lex_context){0} + #define AREF(ary, i) RARRAY_AREF(ary, i) #ifndef WARN_PAST_SCOPE @@ -7942,6 +7952,8 @@ comment_at_top(struct parser_params *p) typedef long (*rb_magic_comment_length_t)(struct parser_params *p, const char *name, long len); typedef void (*rb_magic_comment_setter_t)(struct parser_params *p, const char *name, const char *val); +static int parser_invalid_pragma_value(struct parser_params *p, const char *name, const char *val); + static void magic_comment_encoding(struct parser_params *p, const char *name, const char *val) { @@ -7966,6 +7978,12 @@ parser_get_bool(struct parser_params *p, const char *name, const char *val) } break; } + return parser_invalid_pragma_value(p, name, val); +} + +static int +parser_invalid_pragma_value(struct parser_params *p, const char *name, const char *val) +{ rb_warning2("invalid value for %s: %s", WARN_S(name), WARN_S(val)); return -1; } @@ -8006,8 +8024,27 @@ parser_set_shareable_constant_value(struct parser_params *p, const char *name, c return; } - int b = parser_get_bool(p, name, val); - if (b >= 0) p->ctxt.shareable_constant_value = b; + switch (*val) { + case 'n': case 'N': + if (STRCASECMP(val, "none") == 0) { + p->ctxt.shareable_constant_value = shareable_none; + return; + } + break; + case 'l': case 'L': + if (STRCASECMP(val, "literal") == 0) { + p->ctxt.shareable_constant_value = shareable_literal; + return; + } + break; + case 'e': case 'E': + if (STRCASECMP(val, "experimental_everything") == 0) { + p->ctxt.shareable_constant_value = shareable_everything; + return; + } + break; + } + parser_invalid_pragma_value(p, name, val); } # if WARN_PAST_SCOPE @@ -10948,16 +10985,33 @@ mark_lvar_used(struct parser_params *p, NODE *rhs) extern VALUE rb_mRubyVMFrozenCore; static NODE * -shareable_constant_value(struct parser_params *p, NODE *value, int shareable, const YYLTYPE *loc) +shareable_literal_constant(struct parser_params *p, NODE *value) { - if (shareable) { - NODE *fcore = NEW_LIT(rb_mRubyVMFrozenCore, loc); - value = NEW_CALL(fcore, rb_intern("make_shareable"), - NEW_LIST(value, loc), loc); - } return value; } +static NODE * +shareable_constant_value(struct parser_params *p, NODE *value, enum shareability shareable, const YYLTYPE *loc) +{ + switch (shareable) { + case shareable_none: + return value; + + case shareable_literal: + return shareable_literal_constant(p, value); + + case shareable_everything: + break; + + default: + UNREACHABLE_RETURN(0); + } + + NODE *fcore = NEW_LIT(rb_mRubyVMFrozenCore, loc); + return NEW_CALL(fcore, rb_intern("make_shareable"), + NEW_LIST(value, loc), loc); +} + static NODE * node_assign(struct parser_params *p, NODE *lhs, NODE *rhs, struct lex_context ctxt, const YYLTYPE *loc) { diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb index 8a644ad6a8..61551a2c96 100644 --- a/test/ruby/test_parse.rb +++ b/test/ruby/test_parse.rb @@ -1183,9 +1183,9 @@ x = __ENCODING__ end a, b, c = Class.new.class_eval("#{<<~"begin;"}\n#{<<~'end;'}") begin; - # shareable_constant_value: true + # shareable_constant_value: experimental_everything A = [[1]] - # shareable_constant_value: false + # shareable_constant_value: none B = [[2]] [A, B] @@ -1196,9 +1196,9 @@ x = __ENCODING__ assert_send([Ractor, :shareable?, a[0]]) a, b = Class.new.class_eval("#{<<~"begin;"}\n#{<<~'end;'}") begin; - # shareable_constant_value: false + # shareable_constant_value: none class X - # shareable_constant_value: true + # shareable_constant_value: experimental_everything A = [[1]] end B = [] -- cgit v1.2.3