summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNobuyoshi Nakada <nobu@ruby-lang.org>2020-10-09 23:06:13 +0900
committerNobuyoshi Nakada <nobu@ruby-lang.org>2020-12-14 19:19:16 +0900
commitf43c71abe07b4b2b0f8f9a69c567fcd0f38faef6 (patch)
tree5174f18c9bd83ed60537a44c455a1b3369f49c88
parentb1bd223085d7b97d8de8679894a81b7993c26b28 (diff)
downloadruby-f43c71abe07b4b2b0f8f9a69c567fcd0f38faef6.tar.gz
Implemented shareable_constant_value
It does shallow freeze only for now.
-rw-r--r--parse.y16
-rw-r--r--ractor.rb4
-rw-r--r--test/ruby/test_parse.rb17
3 files changed, 36 insertions, 1 deletions
diff --git a/parse.y b/parse.y
index 3c9b9e0d43..da66c5637a 100644
--- a/parse.y
+++ b/parse.y
@@ -10926,18 +10926,32 @@ mark_lvar_used(struct parser_params *p, NODE *rhs)
}
static NODE *
+shareable_constant_value(struct parser_params *p, NODE *value, const YYLTYPE *loc)
+{
+ if (p->ctxt.shareable_constant_value) {
+ NODE *ractor = NEW_COLON3(rb_intern("Ractor"), loc);
+ value = NEW_CALL(ractor, rb_intern("make_shareable"),
+ NEW_LIST(value, loc), loc);
+ }
+ return value;
+}
+
+static NODE *
node_assign(struct parser_params *p, NODE *lhs, NODE *rhs, const YYLTYPE *loc)
{
if (!lhs) return 0;
switch (nd_type(lhs)) {
+ case NODE_CDECL:
+ rhs = shareable_constant_value(p, rhs, loc);
+ /* fallthru */
+
case NODE_GASGN:
case NODE_IASGN:
case NODE_LASGN:
case NODE_DASGN:
case NODE_DASGN_CURR:
case NODE_MASGN:
- case NODE_CDECL:
case NODE_CVASGN:
lhs->nd_value = rhs;
nd_set_loc(lhs, loc);
diff --git a/ractor.rb b/ractor.rb
index ca09aee7be..0867f1a9d1 100644
--- a/ractor.rb
+++ b/ractor.rb
@@ -51,6 +51,10 @@ class Ractor
}
end
+ def self.make_shareable(obj)
+ obj.freeze
+ end
+
# Multiplex multiple Ractor communications.
#
# r, obj = Ractor.select(r1, r2)
diff --git a/test/ruby/test_parse.rb b/test/ruby/test_parse.rb
index 1ed92d59a4..f12b61019b 100644
--- a/test/ruby/test_parse.rb
+++ b/test/ruby/test_parse.rb
@@ -1178,6 +1178,23 @@ x = __ENCODING__
assert_warning(/invalid value/) do
assert_valid_syntax("# shareable_constant_value: invalid-option", verbose: true)
end
+ a = Class.new.class_eval("#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ # shareable_constant_value: true
+ A = []
+ end;
+ assert_predicate(a, :frozen?)
+ a, b = Class.new.class_eval("#{<<~"begin;"}\n#{<<~'end;'}")
+ begin;
+ # shareable_constant_value: false
+ class X # shareable_constant_value: true
+ A = []
+ end
+ B = []
+ [X::A, B]
+ end;
+ assert_predicate(a, :frozen?)
+ assert_not_predicate(b, :frozen?)
end
=begin