mirror of
https://github.com/ruby/ruby.git
synced 2022-11-09 12:17:21 -05:00
Make shareable_constant_value tri-state
This commit is contained in:
parent
7060aeedbd
commit
89e489d51d
Notes:
git
2020-12-14 19:19:43 +09:00
2 changed files with 76 additions and 22 deletions
90
parse.y
90
parse.y
|
@ -26,18 +26,11 @@
|
|||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -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 = []
|
||||
|
|
Loading…
Add table
Reference in a new issue