1
0
Fork 0
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:
Nobuyoshi Nakada 2020-11-13 14:03:25 +09:00
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
View file

@ -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)
{

View file

@ -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 = []