Some global variables can be accessed from ractors

Some global variables should be used from non-main Ractors.
[Bug #17268]

```ruby
     # 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,
```
This commit is contained in:
Koichi Sasada 2020-10-20 10:46:43 +09:00
parent 9ced5fae6d
commit 99310e3eb5
Notes: git 2020-10-20 15:39:18 +09:00
11 changed files with 131 additions and 24 deletions

50
ruby.c
View file

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