summaryrefslogtreecommitdiff
path: root/ractor.c
diff options
context:
space:
mode:
authorÉtienne Barrié <[email protected]>2023-12-01 11:33:00 +0100
committerJean Boussier <[email protected]>2024-03-19 09:26:49 +0100
commit12be40ae6be78ac41e8e3f3c313cc6f63e7fa6c4 (patch)
treef6b81fac770da6b705557623224dbf9b9c2d2847 /ractor.c
parent86b15316a748a579dd4fd4df42b6db42accebdc2 (diff)
Implement chilled strings
[Feature #20205] As a path toward enabling frozen string literals by default in the future, this commit introduce "chilled strings". From a user perspective chilled strings pretend to be frozen, but on the first attempt to mutate them, they lose their frozen status and emit a warning rather than to raise a `FrozenError`. Implementation wise, `rb_compile_option_struct.frozen_string_literal` is no longer a boolean but a tri-state of `enabled/disabled/unset`. When code is compiled with frozen string literals neither explictly enabled or disabled, string literals are compiled with a new `putchilledstring` instruction. This instruction is identical to `putstring` except it marks the String with the `STR_CHILLED (FL_USER3)` and `FL_FREEZE` flags. Chilled strings have the `FL_FREEZE` flag as to minimize the need to check for chilled strings across the codebase, and to improve compatibility with C extensions. Notes: - `String#freeze`: clears the chilled flag. - `String#-@`: acts as if the string was mutable. - `String#+@`: acts as if the string was mutable. - `String#clone`: copies the chilled flag. Co-authored-by: Jean Boussier <[email protected]>
Diffstat (limited to 'ractor.c')
-rw-r--r--ractor.c16
1 files changed, 15 insertions, 1 deletions
diff --git a/ractor.c b/ractor.c
index 4eee3cc731..7b9c088ceb 100644
--- a/ractor.c
+++ b/ractor.c
@@ -2985,7 +2985,10 @@ rb_obj_traverse(VALUE obj,
static int
frozen_shareable_p(VALUE obj, bool *made_shareable)
{
- if (!RB_TYPE_P(obj, T_DATA)) {
+ if (CHILLED_STRING_P(obj)) {
+ return false;
+ }
+ else if (!RB_TYPE_P(obj, T_DATA)) {
return true;
}
else if (RTYPEDDATA_P(obj)) {
@@ -3014,6 +3017,17 @@ make_shareable_check_shareable(VALUE obj)
if (rb_ractor_shareable_p(obj)) {
return traverse_skip;
}
+ else if (CHILLED_STRING_P(obj)) {
+ rb_funcall(obj, idFreeze, 0);
+
+ if (UNLIKELY(!RB_OBJ_FROZEN_RAW(obj))) {
+ rb_raise(rb_eRactorError, "#freeze does not freeze object correctly");
+ }
+
+ if (RB_OBJ_SHAREABLE_P(obj)) {
+ return traverse_skip;
+ }
+ }
else if (!frozen_shareable_p(obj, &made_shareable)) {
if (made_shareable) {
return traverse_skip;