summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bootstraptest/test_ractor.rb59
-rw-r--r--common.mk3
-rw-r--r--eval.c3
-rw-r--r--io.c3
-rw-r--r--process.c4
-rw-r--r--ractor.c4
-rw-r--r--ractor.h2
-rw-r--r--re.c7
-rw-r--r--ruby.c50
-rw-r--r--vm.c18
-rw-r--r--vm_core.h2
11 files changed, 131 insertions, 24 deletions
diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
index eaa265fcfa..94570597ba 100644
--- a/bootstraptest/test_ractor.rb
+++ b/bootstraptest/test_ractor.rb
@@ -611,6 +611,65 @@ assert_equal 'ok', %q{
'ok'
}
+# $DEBUG, $VERBOSE are Ractor local
+assert_equal 'true', %q{
+ $DEBUG = true
+ $VERBOSE = true
+
+ def ractor_local_globals
+ /a(b)(c)d/ =~ 'abcd' # for $~
+ `echo foo`
+
+ {
+ # ractor-local (derived from created ractor): debug
+ '$DEBUG' => $DEBUG,
+ '$-d' => $-d,
+
+ # ractor-local (derived from created ractor): verbose
+ '$VERBOSE' => $VERBOSE,
+ '$-w' => $-w,
+ '$-W' => $-W,
+ '$-v' => $-v,
+
+ # process-local (readonly): other commandline parameters
+ '$-p' => $-p,
+ '$-l' => $-l,
+ '$-a' => $-a,
+
+ # process-local (readonly): getpid
+ '$$' => $$,
+
+ # thread local: process result
+ '$?' => $?,
+
+ # scope local: match
+ '$~' => $~.inspect,
+ '$&' => $&,
+ '$`' => $`,
+ '$\'' => $',
+ '$+' => $+,
+ '$1' => $1,
+
+ # scope local: last line
+ '$_' => $_,
+
+ # scope local: last backtrace
+ '$@' => $@,
+ '$!' => $!,
+
+ # ractor local: stdin, out, err
+ '$stdin' => $stdin.inspect,
+ '$stdout' => $stdout.inspect,
+ '$stderr' => $stderr.inspect,
+ }
+ end
+
+ h = Ractor.new do
+ ractor_local_globals
+ end.take
+ ractor_local_globals == h #=> true
+}
+
# selfs are different objects
assert_equal 'false', %q{
r = Ractor.new do
diff --git a/common.mk b/common.mk
index 10910d1775..a8719ca4e6 100644
--- a/common.mk
+++ b/common.mk
@@ -10943,6 +10943,7 @@ re.$(OBJEXT): $(top_srcdir)/internal/imemo.h
re.$(OBJEXT): $(top_srcdir)/internal/re.h
re.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
re.$(OBJEXT): $(top_srcdir)/internal/string.h
+re.$(OBJEXT): $(top_srcdir)/internal/variable.h
re.$(OBJEXT): $(top_srcdir)/internal/warnings.h
re.$(OBJEXT): {$(VPATH)}assert.h
re.$(OBJEXT): {$(VPATH)}backward/2/assume.h
@@ -10955,9 +10956,11 @@ re.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
re.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
re.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
re.$(OBJEXT): {$(VPATH)}config.h
+re.$(OBJEXT): {$(VPATH)}constant.h
re.$(OBJEXT): {$(VPATH)}defines.h
re.$(OBJEXT): {$(VPATH)}encindex.h
re.$(OBJEXT): {$(VPATH)}encoding.h
+re.$(OBJEXT): {$(VPATH)}id_table.h
re.$(OBJEXT): {$(VPATH)}intern.h
re.$(OBJEXT): {$(VPATH)}internal.h
re.$(OBJEXT): {$(VPATH)}internal/anyargs.h
diff --git a/eval.c b/eval.c
index 87c048be3f..9a10cb46b1 100644
--- a/eval.c
+++ b/eval.c
@@ -2084,6 +2084,9 @@ Init_eval(void)
rb_define_virtual_variable("$@", errat_getter, errat_setter);
rb_define_virtual_variable("$!", errinfo_getter, 0);
+ rb_gvar_ractor_local("$@");
+ rb_gvar_ractor_local("$!");
+
rb_define_global_function("raise", f_raise, -1);
rb_define_global_function("fail", f_raise, -1);
diff --git a/io.c b/io.c
index c986ffbc47..3b4ae6d60b 100644
--- a/io.c
+++ b/io.c
@@ -13543,6 +13543,7 @@ Init_IO(void)
rb_define_hooked_variable("$\\", &rb_output_rs, 0, deprecated_str_setter);
rb_define_virtual_variable("$_", get_LAST_READ_LINE, set_LAST_READ_LINE);
+ rb_gvar_ractor_local("$_");
rb_define_method(rb_cIO, "initialize_copy", rb_io_init_copy, 1);
rb_define_method(rb_cIO, "reopen", rb_io_reopen, -1);
@@ -13764,6 +13765,8 @@ Init_IO(void)
ARGF.filename = rb_str_new2("-");
rb_define_hooked_variable("$-i", &argf, opt_i_get, opt_i_set);
+ rb_gvar_ractor_local("$-i");
+
rb_define_hooked_variable("$*", &argf, argf_argv_getter, rb_gvar_readonly_setter);
#if defined (_WIN32) || defined(__CYGWIN__)
diff --git a/process.c b/process.c
index 8abb3ea86f..90db3c5677 100644
--- a/process.c
+++ b/process.c
@@ -8445,6 +8445,10 @@ InitVM_process(void)
#define rb_intern(str) rb_intern_const(str)
rb_define_virtual_variable("$?", get_CHILD_STATUS, 0);
rb_define_virtual_variable("$$", get_PROCESS_ID, 0);
+
+ rb_gvar_ractor_local("$$");
+ rb_gvar_ractor_local("$?");
+
rb_define_global_function("exec", f_exec, -1);
rb_define_global_function("fork", rb_f_fork, 0);
rb_define_global_function("exit!", rb_f_exit_bang, -1);
diff --git a/ractor.c b/ractor.c
index 5bc65a0491..68ac5a25fe 100644
--- a/ractor.c
+++ b/ractor.c
@@ -1373,6 +1373,10 @@ ractor_create(rb_execution_context_t *ec, VALUE self, VALUE loc, VALUE name, VAL
r->r_stdout = rb_io_prep_stdout();
r->r_stderr = rb_io_prep_stderr();
+ rb_ractor_t *cr = rb_ec_ractor_ptr(ec);
+ r->verbose = cr->verbose;
+ r->debug = cr->debug;
+
rb_thread_create_ractor(r, args, block);
RB_GC_GUARD(rv);
diff --git a/ractor.h b/ractor.h
index d3de06b559..1afd91b77c 100644
--- a/ractor.h
+++ b/ractor.h
@@ -125,6 +125,8 @@ struct rb_ractor_struct {
VALUE r_stdin;
VALUE r_stdout;
VALUE r_stderr;
+ VALUE verbose;
+ VALUE debug;
}; // rb_ractor_t is defined in vm_core.h
rb_ractor_t *rb_ractor_main_alloc(void);
diff --git a/re.c b/re.c
index badd321782..020ba7b6d6 100644
--- a/re.c
+++ b/re.c
@@ -19,6 +19,7 @@
#include "internal/imemo.h"
#include "internal/re.h"
#include "internal/string.h"
+#include "internal/variable.h"
#include "regint.h"
#include "ruby/encoding.h"
#include "ruby/re.h"
@@ -4052,6 +4053,12 @@ Init_Regexp(void)
rb_define_virtual_variable("$'", postmatch_getter, 0);
rb_define_virtual_variable("$+", last_paren_match_getter, 0);
+ rb_gvar_ractor_local("$~");
+ rb_gvar_ractor_local("$&");
+ rb_gvar_ractor_local("$`");
+ rb_gvar_ractor_local("$'");
+ rb_gvar_ractor_local("$+");
+
rb_define_virtual_variable("$=", ignorecase_getter, ignorecase_setter);
rb_define_virtual_variable("$KCODE", kcode_getter, kcode_setter);
rb_define_virtual_variable("$-K", kcode_getter, kcode_setter);
diff --git a/ruby.c b/ruby.c
index 9ca980dfbd..4feae7757a 100644
--- a/ruby.c
+++ b/ruby.c
@@ -63,6 +63,7 @@
#include "ruby/thread.h"
#include "ruby/util.h"
#include "ruby/version.h"
+#include "ruby/internal/error.h"
#ifndef MAXPATHLEN
# define MAXPATHLEN 1024
@@ -2021,6 +2022,10 @@ process_options(int argc, char **argv, ruby_cmdline_options_t *opt)
rb_define_readonly_boolean("$-l", opt->do_line);
rb_define_readonly_boolean("$-a", opt->do_split);
+ rb_gvar_ractor_local("$-p");
+ rb_gvar_ractor_local("$-l");
+ rb_gvar_ractor_local("$-a");
+
if ((rb_e_script = opt->e_script) != 0) {
rb_gc_register_mark_object(opt->e_script);
}
@@ -2430,16 +2435,24 @@ forbid_setid(const char *s, const ruby_cmdline_options_t *opt)
rb_raise(rb_eSecurityError, "no %s allowed while running setgid", s);
}
+static VALUE
+verbose_getter(ID id, VALUE *ptr)
+{
+ return *rb_ruby_verbose_ptr();
+}
+
static void
verbose_setter(VALUE val, ID id, VALUE *variable)
{
- *variable = RTEST(val) ? Qtrue : val;
+ *rb_ruby_verbose_ptr() = RTEST(val) ? Qtrue : val;
}
static VALUE
-opt_W_getter(ID id, VALUE *variable)
+opt_W_getter(ID id, VALUE *dmy)
{
- switch (*variable) {
+ VALUE v = *rb_ruby_verbose_ptr();
+
+ switch (v) {
case Qnil:
return INT2FIX(0);
case Qfalse:
@@ -2451,16 +2464,35 @@ opt_W_getter(ID id, VALUE *variable)
}
}
+static VALUE
+debug_getter(ID id, VALUE *dmy)
+{
+ return *rb_ruby_debug_ptr();
+}
+
+static void
+debug_setter(VALUE val, ID id, VALUE *dmy)
+{
+ *rb_ruby_debug_ptr() = val;
+}
+
/*! Defines built-in variables */
void
ruby_prog_init(void)
{
- rb_define_hooked_variable("$VERBOSE", &ruby_verbose, 0, verbose_setter);
- rb_define_hooked_variable("$-v", &ruby_verbose, 0, verbose_setter);
- rb_define_hooked_variable("$-w", &ruby_verbose, 0, verbose_setter);
- rb_define_hooked_variable("$-W", &ruby_verbose, opt_W_getter, rb_gvar_readonly_setter);
- rb_define_variable("$DEBUG", &ruby_debug);
- rb_define_variable("$-d", &ruby_debug);
+ rb_define_virtual_variable("$VERBOSE", verbose_getter, verbose_setter);
+ rb_define_virtual_variable("$-v", verbose_getter, verbose_setter);
+ rb_define_virtual_variable("$-w", verbose_getter, verbose_setter);
+ rb_define_virtual_variable("$-W", opt_W_getter, rb_gvar_readonly_setter);
+ rb_define_virtual_variable("$DEBUG", debug_getter, debug_setter);
+ rb_define_virtual_variable("$-d", debug_getter, debug_setter);
+
+ rb_gvar_ractor_local("$VERBOSE");
+ rb_gvar_ractor_local("$-v");
+ rb_gvar_ractor_local("$-w");
+ rb_gvar_ractor_local("$-W");
+ rb_gvar_ractor_local("$DEBUG");
+ rb_gvar_ractor_local("$-d");
rb_define_hooked_variable("$0", &rb_progname, 0, set_arg0);
rb_define_hooked_variable("$PROGRAM_NAME", &rb_progname, 0, set_arg0);
diff --git a/vm.c b/vm.c
index 879814a14b..ada33ae87b 100644
--- a/vm.c
+++ b/vm.c
@@ -3515,28 +3515,18 @@ Init_top_self(void)
rb_define_alias(rb_singleton_class(rb_vm_top_self()), "inspect", "to_s");
}
-static VALUE *
-ruby_vm_verbose_ptr(rb_vm_t *vm)
-{
- return &vm->verbose;
-}
-
-static VALUE *
-ruby_vm_debug_ptr(rb_vm_t *vm)
-{
- return &vm->debug;
-}
-
VALUE *
rb_ruby_verbose_ptr(void)
{
- return ruby_vm_verbose_ptr(GET_VM());
+ rb_ractor_t *cr = GET_RACTOR();
+ return &cr->verbose;
}
VALUE *
rb_ruby_debug_ptr(void)
{
- return ruby_vm_debug_ptr(GET_VM());
+ rb_ractor_t *cr = GET_RACTOR();
+ return &cr->debug;
}
/* iseq.c */
diff --git a/vm_core.h b/vm_core.h
index f644e8a6bc..8525bfcf3e 100644
--- a/vm_core.h
+++ b/vm_core.h
@@ -633,7 +633,7 @@ typedef struct rb_vm_struct {
struct list_head workqueue; /* <=> rb_workqueue_job.jnode */
rb_nativethread_lock_t workqueue_lock;
- VALUE verbose, debug, orig_progname, progname;
+ VALUE orig_progname, progname;
VALUE coverages;
int coverage_mode;