namespace on read
This commit is contained in:
parent
49742414f6
commit
382645d440
22
builtin.c
22
builtin.c
@ -32,8 +32,8 @@ builtin_lookup(const char *feature, size_t *psize)
|
|||||||
return bin;
|
return bin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
static void
|
||||||
rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table)
|
load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table)
|
||||||
{
|
{
|
||||||
// search binary
|
// search binary
|
||||||
size_t size;
|
size_t size;
|
||||||
@ -50,8 +50,22 @@ rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin
|
|||||||
ASSUME(iseq); // otherwise an exception should have raised
|
ASSUME(iseq); // otherwise an exception should have raised
|
||||||
vm->builtin_function_table = NULL;
|
vm->builtin_function_table = NULL;
|
||||||
|
|
||||||
|
rb_namespace_enable_builtin();
|
||||||
|
|
||||||
// exec
|
// exec
|
||||||
rb_iseq_eval(rb_iseq_check(iseq));
|
if (rb_namespace_available() && rb_mNamespaceRefiner) {
|
||||||
|
rb_iseq_eval_with_refinement(rb_iseq_check(iseq), rb_mNamespaceRefiner);
|
||||||
|
} else {
|
||||||
|
rb_iseq_eval(rb_iseq_check(iseq));
|
||||||
|
}
|
||||||
|
|
||||||
|
rb_namespace_disable_builtin();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table)
|
||||||
|
{
|
||||||
|
load_with_builtin_functions(feature_name, table);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -71,5 +85,5 @@ Init_builtin(void)
|
|||||||
void
|
void
|
||||||
Init_builtin_features(void)
|
Init_builtin_features(void)
|
||||||
{
|
{
|
||||||
rb_load_with_builtin_functions("gem_prelude", NULL);
|
load_with_builtin_functions("gem_prelude", NULL);
|
||||||
}
|
}
|
||||||
|
255
common.mk
255
common.mk
@ -140,6 +140,7 @@ COMMONOBJS = array.$(OBJEXT) \
|
|||||||
marshal.$(OBJEXT) \
|
marshal.$(OBJEXT) \
|
||||||
math.$(OBJEXT) \
|
math.$(OBJEXT) \
|
||||||
memory_view.$(OBJEXT) \
|
memory_view.$(OBJEXT) \
|
||||||
|
namespace.$(OBJEXT) \
|
||||||
node.$(OBJEXT) \
|
node.$(OBJEXT) \
|
||||||
node_dump.$(OBJEXT) \
|
node_dump.$(OBJEXT) \
|
||||||
numeric.$(OBJEXT) \
|
numeric.$(OBJEXT) \
|
||||||
@ -2116,6 +2117,7 @@ array.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
|||||||
array.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
array.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
array.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
array.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
array.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
array.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
array.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
array.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
array.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
array.$(OBJEXT): $(top_srcdir)/internal/object.h
|
array.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
array.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
array.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
||||||
@ -2333,6 +2335,7 @@ ast.$(OBJEXT): $(top_srcdir)/internal/complex.h
|
|||||||
ast.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
ast.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
||||||
ast.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
ast.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
ast.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
ast.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
ast.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
ast.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
ast.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
ast.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
ast.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
||||||
ast.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
ast.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
||||||
@ -2572,6 +2575,7 @@ bignum.$(OBJEXT): $(top_srcdir)/internal/complex.h
|
|||||||
bignum.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
bignum.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
||||||
bignum.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
bignum.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
bignum.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
bignum.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
bignum.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
bignum.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
bignum.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
bignum.$(OBJEXT): $(top_srcdir)/internal/object.h
|
bignum.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
bignum.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
bignum.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
@ -2777,6 +2781,7 @@ builtin.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
|
|||||||
builtin.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
builtin.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||||
builtin.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
builtin.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
builtin.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
builtin.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
builtin.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
builtin.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
builtin.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
builtin.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
builtin.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
builtin.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
builtin.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
||||||
@ -3008,6 +3013,7 @@ class.$(OBJEXT): $(top_srcdir)/internal/eval.h
|
|||||||
class.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
class.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
class.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
class.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
class.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
class.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
class.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
class.$(OBJEXT): $(top_srcdir)/internal/object.h
|
class.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
class.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
class.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
class.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
class.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
@ -3408,6 +3414,7 @@ compile.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
|||||||
compile.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
compile.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
compile.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
compile.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
compile.$(OBJEXT): $(top_srcdir)/internal/io.h
|
compile.$(OBJEXT): $(top_srcdir)/internal/io.h
|
||||||
|
compile.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
compile.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
compile.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
compile.$(OBJEXT): $(top_srcdir)/internal/object.h
|
compile.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
compile.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
compile.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
||||||
@ -3669,6 +3676,7 @@ complex.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
|||||||
complex.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
complex.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
complex.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
complex.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
complex.$(OBJEXT): $(top_srcdir)/internal/math.h
|
complex.$(OBJEXT): $(top_srcdir)/internal/math.h
|
||||||
|
complex.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
complex.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
complex.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
complex.$(OBJEXT): $(top_srcdir)/internal/object.h
|
complex.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
complex.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
complex.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
||||||
@ -3881,6 +3889,7 @@ cont.$(OBJEXT): $(top_srcdir)/internal/cont.h
|
|||||||
cont.$(OBJEXT): $(top_srcdir)/internal/error.h
|
cont.$(OBJEXT): $(top_srcdir)/internal/error.h
|
||||||
cont.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
cont.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
cont.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
cont.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
cont.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
cont.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
cont.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
||||||
cont.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
cont.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
cont.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
cont.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
@ -4120,6 +4129,7 @@ debug.$(OBJEXT): $(top_srcdir)/internal/class.h
|
|||||||
debug.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
debug.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||||
debug.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
debug.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
debug.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
debug.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
debug.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
debug.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
debug.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
debug.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
debug.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
debug.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
debug.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
||||||
@ -4500,6 +4510,7 @@ dir.$(OBJEXT): $(top_srcdir)/internal/file.h
|
|||||||
dir.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
dir.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
dir.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
dir.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
dir.$(OBJEXT): $(top_srcdir)/internal/io.h
|
dir.$(OBJEXT): $(top_srcdir)/internal/io.h
|
||||||
|
dir.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
dir.$(OBJEXT): $(top_srcdir)/internal/object.h
|
dir.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
dir.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
dir.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
dir.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
dir.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
@ -4701,6 +4712,7 @@ dir.$(OBJEXT): {$(VPATH)}vm_core.h
|
|||||||
dir.$(OBJEXT): {$(VPATH)}vm_opts.h
|
dir.$(OBJEXT): {$(VPATH)}vm_opts.h
|
||||||
dln.$(OBJEXT): $(hdrdir)/ruby/ruby.h
|
dln.$(OBJEXT): $(hdrdir)/ruby/ruby.h
|
||||||
dln.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
dln.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||||
|
dln.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
dln.$(OBJEXT): $(top_srcdir)/internal/warnings.h
|
dln.$(OBJEXT): $(top_srcdir)/internal/warnings.h
|
||||||
dln.$(OBJEXT): {$(VPATH)}assert.h
|
dln.$(OBJEXT): {$(VPATH)}assert.h
|
||||||
dln.$(OBJEXT): {$(VPATH)}backward/2/assume.h
|
dln.$(OBJEXT): {$(VPATH)}backward/2/assume.h
|
||||||
@ -6431,6 +6443,7 @@ enumerator.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
|||||||
enumerator.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
enumerator.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
enumerator.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
enumerator.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
enumerator.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
enumerator.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
enumerator.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
enumerator.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
enumerator.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
enumerator.$(OBJEXT): $(top_srcdir)/internal/range.h
|
enumerator.$(OBJEXT): $(top_srcdir)/internal/range.h
|
||||||
enumerator.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
enumerator.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
||||||
@ -6647,6 +6660,7 @@ error.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
|||||||
error.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
error.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
error.$(OBJEXT): $(top_srcdir)/internal/io.h
|
error.$(OBJEXT): $(top_srcdir)/internal/io.h
|
||||||
error.$(OBJEXT): $(top_srcdir)/internal/load.h
|
error.$(OBJEXT): $(top_srcdir)/internal/load.h
|
||||||
|
error.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
error.$(OBJEXT): $(top_srcdir)/internal/object.h
|
error.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
error.$(OBJEXT): $(top_srcdir)/internal/process.h
|
error.$(OBJEXT): $(top_srcdir)/internal/process.h
|
||||||
error.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
error.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
@ -6871,6 +6885,7 @@ eval.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
|||||||
eval.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
eval.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
eval.$(OBJEXT): $(top_srcdir)/internal/inits.h
|
eval.$(OBJEXT): $(top_srcdir)/internal/inits.h
|
||||||
eval.$(OBJEXT): $(top_srcdir)/internal/io.h
|
eval.$(OBJEXT): $(top_srcdir)/internal/io.h
|
||||||
|
eval.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
eval.$(OBJEXT): $(top_srcdir)/internal/object.h
|
eval.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
eval.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
eval.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
eval.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
eval.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
@ -7350,6 +7365,7 @@ gc.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
|||||||
gc.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
gc.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
gc.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
gc.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
gc.$(OBJEXT): $(top_srcdir)/internal/io.h
|
gc.$(OBJEXT): $(top_srcdir)/internal/io.h
|
||||||
|
gc.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
gc.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
gc.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
gc.$(OBJEXT): $(top_srcdir)/internal/object.h
|
gc.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
gc.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
gc.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
||||||
@ -7614,6 +7630,7 @@ goruby.$(OBJEXT): $(top_srcdir)/internal/complex.h
|
|||||||
goruby.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
goruby.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
||||||
goruby.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
goruby.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
goruby.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
goruby.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
goruby.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
goruby.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
goruby.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
goruby.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
goruby.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
||||||
goruby.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
goruby.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
||||||
@ -7855,6 +7872,7 @@ hash.$(OBJEXT): $(top_srcdir)/internal/error.h
|
|||||||
hash.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
hash.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
hash.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
hash.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
hash.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
hash.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
hash.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
hash.$(OBJEXT): $(top_srcdir)/internal/object.h
|
hash.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
hash.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
hash.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
||||||
hash.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
hash.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
@ -8478,6 +8496,7 @@ io.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
|||||||
io.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
io.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
io.$(OBJEXT): $(top_srcdir)/internal/inits.h
|
io.$(OBJEXT): $(top_srcdir)/internal/inits.h
|
||||||
io.$(OBJEXT): $(top_srcdir)/internal/io.h
|
io.$(OBJEXT): $(top_srcdir)/internal/io.h
|
||||||
|
io.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
io.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
io.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
io.$(OBJEXT): $(top_srcdir)/internal/object.h
|
io.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
io.$(OBJEXT): $(top_srcdir)/internal/process.h
|
io.$(OBJEXT): $(top_srcdir)/internal/process.h
|
||||||
@ -8920,6 +8939,7 @@ iseq.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
|||||||
iseq.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
iseq.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
iseq.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
iseq.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
iseq.$(OBJEXT): $(top_srcdir)/internal/io.h
|
iseq.$(OBJEXT): $(top_srcdir)/internal/io.h
|
||||||
|
iseq.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
iseq.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
iseq.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
iseq.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
iseq.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
||||||
iseq.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
iseq.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
||||||
@ -9406,12 +9426,14 @@ load.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
|||||||
load.$(OBJEXT): $(top_srcdir)/internal/complex.h
|
load.$(OBJEXT): $(top_srcdir)/internal/complex.h
|
||||||
load.$(OBJEXT): $(top_srcdir)/internal/dir.h
|
load.$(OBJEXT): $(top_srcdir)/internal/dir.h
|
||||||
load.$(OBJEXT): $(top_srcdir)/internal/error.h
|
load.$(OBJEXT): $(top_srcdir)/internal/error.h
|
||||||
|
load.$(OBJEXT): $(top_srcdir)/internal/eval.h
|
||||||
load.$(OBJEXT): $(top_srcdir)/internal/file.h
|
load.$(OBJEXT): $(top_srcdir)/internal/file.h
|
||||||
load.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
load.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
||||||
load.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
load.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
load.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
load.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
load.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
load.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
load.$(OBJEXT): $(top_srcdir)/internal/load.h
|
load.$(OBJEXT): $(top_srcdir)/internal/load.h
|
||||||
|
load.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
load.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
load.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
load.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
load.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
||||||
load.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
load.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
||||||
@ -10156,6 +10178,7 @@ marshal.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
|||||||
marshal.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
marshal.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
marshal.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
marshal.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
marshal.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
marshal.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
marshal.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
marshal.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
marshal.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
marshal.$(OBJEXT): $(top_srcdir)/internal/object.h
|
marshal.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
marshal.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
marshal.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
@ -10547,6 +10570,7 @@ memory_view.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
|||||||
memory_view.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
memory_view.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
memory_view.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
memory_view.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
memory_view.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
memory_view.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
memory_view.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
memory_view.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
memory_view.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
memory_view.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
memory_view.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
memory_view.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
memory_view.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
||||||
@ -10757,6 +10781,7 @@ miniinit.$(OBJEXT): $(top_srcdir)/internal/complex.h
|
|||||||
miniinit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
miniinit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
||||||
miniinit.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
miniinit.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
miniinit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
miniinit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
miniinit.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
miniinit.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
miniinit.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
miniinit.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
miniinit.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
||||||
miniinit.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
miniinit.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
||||||
@ -11002,6 +11027,206 @@ miniinit.$(OBJEXT): {$(VPATH)}warning.rb
|
|||||||
miniinit.$(OBJEXT): {$(VPATH)}yjit.rb
|
miniinit.$(OBJEXT): {$(VPATH)}yjit.rb
|
||||||
miniinit.$(OBJEXT): {$(VPATH)}yjit_hook.rb
|
miniinit.$(OBJEXT): {$(VPATH)}yjit_hook.rb
|
||||||
miniinit.$(OBJEXT): {$(VPATH)}zjit.rb
|
miniinit.$(OBJEXT): {$(VPATH)}zjit.rb
|
||||||
|
namespace.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
|
||||||
|
namespace.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
|
||||||
|
namespace.$(OBJEXT): $(CCAN_DIR)/list/list.h
|
||||||
|
namespace.$(OBJEXT): $(CCAN_DIR)/str/str.h
|
||||||
|
namespace.$(OBJEXT): $(hdrdir)/ruby/ruby.h
|
||||||
|
namespace.$(OBJEXT): $(top_srcdir)/internal/array.h
|
||||||
|
namespace.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
|
||||||
|
namespace.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||||
|
namespace.$(OBJEXT): $(top_srcdir)/internal/file.h
|
||||||
|
namespace.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
|
namespace.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
|
namespace.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
namespace.$(OBJEXT): $(top_srcdir)/internal/load.h
|
||||||
|
namespace.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
|
namespace.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
|
namespace.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
|
namespace.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
|
||||||
|
namespace.$(OBJEXT): $(top_srcdir)/internal/vm.h
|
||||||
|
namespace.$(OBJEXT): $(top_srcdir)/internal/warnings.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}assert.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}atomic.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}backward/2/assume.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}backward/2/bool.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}backward/2/limits.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}backward/2/long_long.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}config.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}defines.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}encoding.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}id.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}intern.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/abi.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/anyargs.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/assume.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/cold.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/const.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/error.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/format.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/warning.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/cast.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/compiler_is.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/compiler_since.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/config.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/constant_p.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/core.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/core/rarray.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/core/rclass.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/core/rdata.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/core/rfile.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/core/rhash.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/core/robject.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/core/rstring.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/ctype.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/dllexport.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/dosish.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/error.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/eval.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/event.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/fl_type.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/gc.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/glob.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/globals.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/has/attribute.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/has/builtin.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/has/extension.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/has/feature.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/has/warning.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/array.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/class.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/compar.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/complex.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/cont.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/dir.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/enum.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/error.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/eval.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/file.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/hash.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/io.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/load.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/object.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/parse.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/proc.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/process.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/random.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/range.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/rational.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/re.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/select.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/signal.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/string.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/struct.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/thread.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/time.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/variable.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/intern/vm.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/interpreter.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/iterator.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/memory.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/method.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/module.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/newobj.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/scan_args.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/special_consts.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/static_assert.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/stdalign.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/stdbool.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/symbol.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/value.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/value_type.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/variable.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/warning_push.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}method.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}missing.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}namespace.c
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}node.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}onigmo.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}oniguruma.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}ruby_assert.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}ruby_atomic.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}rubyparser.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}st.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}subst.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}thread_native.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}util.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}vm_core.h
|
||||||
|
namespace.$(OBJEXT): {$(VPATH)}vm_opts.h
|
||||||
node.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
|
node.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
|
||||||
node.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
|
node.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
|
||||||
node.$(OBJEXT): $(CCAN_DIR)/list/list.h
|
node.$(OBJEXT): $(CCAN_DIR)/list/list.h
|
||||||
@ -11013,6 +11238,7 @@ node.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
|||||||
node.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
node.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
node.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
node.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
node.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
node.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
node.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
node.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
node.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
node.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
node.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
node.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
node.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
||||||
@ -11221,6 +11447,7 @@ node_dump.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
|||||||
node_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
node_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
node_dump.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
node_dump.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
node_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
node_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
node_dump.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
node_dump.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
node_dump.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
node_dump.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
node_dump.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
||||||
node_dump.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
node_dump.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
||||||
@ -11436,6 +11663,7 @@ numeric.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
|||||||
numeric.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
numeric.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
numeric.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
numeric.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
numeric.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
numeric.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
numeric.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
numeric.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
numeric.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
numeric.$(OBJEXT): $(top_srcdir)/internal/object.h
|
numeric.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
numeric.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
numeric.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
||||||
@ -11653,6 +11881,7 @@ object.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
|||||||
object.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
object.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
object.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
object.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
object.$(OBJEXT): $(top_srcdir)/internal/inits.h
|
object.$(OBJEXT): $(top_srcdir)/internal/inits.h
|
||||||
|
object.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
object.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
object.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
object.$(OBJEXT): $(top_srcdir)/internal/object.h
|
object.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
object.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
object.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
@ -11873,6 +12102,7 @@ pack.$(OBJEXT): $(top_srcdir)/internal/bits.h
|
|||||||
pack.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
pack.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||||
pack.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
pack.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
pack.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
pack.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
pack.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
pack.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
pack.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
pack.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
pack.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
pack.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
pack.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
||||||
@ -12090,6 +12320,7 @@ parse.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
|||||||
parse.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
parse.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
parse.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
parse.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
parse.$(OBJEXT): $(top_srcdir)/internal/io.h
|
parse.$(OBJEXT): $(top_srcdir)/internal/io.h
|
||||||
|
parse.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
parse.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
parse.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
parse.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
parse.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
||||||
parse.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
parse.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
||||||
@ -13368,6 +13599,7 @@ proc.$(OBJEXT): $(top_srcdir)/internal/eval.h
|
|||||||
proc.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
proc.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
proc.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
proc.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
proc.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
proc.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
proc.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
proc.$(OBJEXT): $(top_srcdir)/internal/object.h
|
proc.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
proc.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
proc.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
||||||
proc.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
proc.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
@ -13614,6 +13846,7 @@ process.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
|||||||
process.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
process.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
process.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
process.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
process.$(OBJEXT): $(top_srcdir)/internal/io.h
|
process.$(OBJEXT): $(top_srcdir)/internal/io.h
|
||||||
|
process.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
process.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
process.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
process.$(OBJEXT): $(top_srcdir)/internal/object.h
|
process.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
process.$(OBJEXT): $(top_srcdir)/internal/process.h
|
process.$(OBJEXT): $(top_srcdir)/internal/process.h
|
||||||
@ -13839,6 +14072,7 @@ ractor.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
|||||||
ractor.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
ractor.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
ractor.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
ractor.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
ractor.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
ractor.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
ractor.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
ractor.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
ractor.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
ractor.$(OBJEXT): $(top_srcdir)/internal/object.h
|
ractor.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
ractor.$(OBJEXT): $(top_srcdir)/internal/ractor.h
|
ractor.$(OBJEXT): $(top_srcdir)/internal/ractor.h
|
||||||
@ -14061,6 +14295,7 @@ random.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
|||||||
random.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
random.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
||||||
random.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
random.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
random.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
random.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
random.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
random.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
random.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
random.$(OBJEXT): $(top_srcdir)/internal/random.h
|
random.$(OBJEXT): $(top_srcdir)/internal/random.h
|
||||||
random.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
random.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
@ -14467,6 +14702,7 @@ rational.$(OBJEXT): $(top_srcdir)/internal/complex.h
|
|||||||
rational.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
rational.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
||||||
rational.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
rational.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
rational.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
rational.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
rational.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
rational.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
rational.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
rational.$(OBJEXT): $(top_srcdir)/internal/object.h
|
rational.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
rational.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
rational.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
||||||
@ -14676,6 +14912,7 @@ re.$(OBJEXT): $(top_srcdir)/internal/encoding.h
|
|||||||
re.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
re.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
re.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
re.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
re.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
re.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
re.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
re.$(OBJEXT): $(top_srcdir)/internal/object.h
|
re.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
re.$(OBJEXT): $(top_srcdir)/internal/ractor.h
|
re.$(OBJEXT): $(top_srcdir)/internal/ractor.h
|
||||||
re.$(OBJEXT): $(top_srcdir)/internal/re.h
|
re.$(OBJEXT): $(top_srcdir)/internal/re.h
|
||||||
@ -15890,6 +16127,7 @@ ruby.$(OBJEXT): $(top_srcdir)/internal/io.h
|
|||||||
ruby.$(OBJEXT): $(top_srcdir)/internal/load.h
|
ruby.$(OBJEXT): $(top_srcdir)/internal/load.h
|
||||||
ruby.$(OBJEXT): $(top_srcdir)/internal/loadpath.h
|
ruby.$(OBJEXT): $(top_srcdir)/internal/loadpath.h
|
||||||
ruby.$(OBJEXT): $(top_srcdir)/internal/missing.h
|
ruby.$(OBJEXT): $(top_srcdir)/internal/missing.h
|
||||||
|
ruby.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
ruby.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
ruby.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
ruby.$(OBJEXT): $(top_srcdir)/internal/object.h
|
ruby.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
ruby.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
ruby.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
||||||
@ -16321,6 +16559,7 @@ scheduler.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
|
|||||||
scheduler.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
scheduler.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||||
scheduler.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
scheduler.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
scheduler.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
scheduler.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
scheduler.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
scheduler.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
scheduler.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
scheduler.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
scheduler.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
scheduler.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
scheduler.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
||||||
@ -16895,6 +17134,7 @@ shape.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
|||||||
shape.$(OBJEXT): $(top_srcdir)/internal/error.h
|
shape.$(OBJEXT): $(top_srcdir)/internal/error.h
|
||||||
shape.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
shape.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
shape.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
shape.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
shape.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
shape.$(OBJEXT): $(top_srcdir)/internal/object.h
|
shape.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
shape.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
shape.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
shape.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
shape.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
@ -17107,6 +17347,7 @@ signal.$(OBJEXT): $(top_srcdir)/internal/error.h
|
|||||||
signal.$(OBJEXT): $(top_srcdir)/internal/eval.h
|
signal.$(OBJEXT): $(top_srcdir)/internal/eval.h
|
||||||
signal.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
signal.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
signal.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
signal.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
signal.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
signal.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
signal.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
signal.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
signal.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
signal.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
signal.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
||||||
@ -17873,6 +18114,7 @@ string.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
|||||||
string.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
string.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
string.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
string.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
string.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
string.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
string.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
string.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
string.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
string.$(OBJEXT): $(top_srcdir)/internal/object.h
|
string.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
string.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
string.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
||||||
@ -18126,6 +18368,7 @@ struct.$(OBJEXT): $(top_srcdir)/internal/error.h
|
|||||||
struct.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
struct.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
struct.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
struct.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
struct.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
struct.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
struct.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
struct.$(OBJEXT): $(top_srcdir)/internal/object.h
|
struct.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
struct.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
struct.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
||||||
struct.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
struct.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
@ -18340,6 +18583,7 @@ symbol.$(OBJEXT): $(top_srcdir)/internal/error.h
|
|||||||
symbol.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
symbol.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
symbol.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
symbol.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
symbol.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
symbol.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
symbol.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
symbol.$(OBJEXT): $(top_srcdir)/internal/object.h
|
symbol.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
symbol.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
symbol.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
symbol.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
symbol.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
@ -18564,6 +18808,7 @@ thread.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
|||||||
thread.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
thread.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
thread.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
thread.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
thread.$(OBJEXT): $(top_srcdir)/internal/io.h
|
thread.$(OBJEXT): $(top_srcdir)/internal/io.h
|
||||||
|
thread.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
thread.$(OBJEXT): $(top_srcdir)/internal/object.h
|
thread.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
thread.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
thread.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
||||||
thread.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
thread.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
@ -18819,6 +19064,7 @@ time.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
|||||||
time.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
time.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
time.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
time.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
time.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
time.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
time.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
time.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
time.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
time.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
time.$(OBJEXT): $(top_srcdir)/internal/rational.h
|
||||||
time.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
time.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
@ -19391,6 +19637,7 @@ variable.$(OBJEXT): $(top_srcdir)/internal/eval.h
|
|||||||
variable.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
variable.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
variable.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
variable.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
variable.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
variable.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
variable.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
variable.$(OBJEXT): $(top_srcdir)/internal/object.h
|
variable.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
variable.$(OBJEXT): $(top_srcdir)/internal/re.h
|
variable.$(OBJEXT): $(top_srcdir)/internal/re.h
|
||||||
variable.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
variable.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
@ -19608,6 +19855,7 @@ version.$(OBJEXT): $(top_srcdir)/internal/cmdlineopt.h
|
|||||||
version.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
version.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||||
version.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
version.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
version.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
version.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
version.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
version.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
version.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
||||||
version.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
version.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
version.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
version.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
@ -19830,6 +20078,7 @@ vm.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
|||||||
vm.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
vm.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
vm.$(OBJEXT): $(top_srcdir)/internal/inits.h
|
vm.$(OBJEXT): $(top_srcdir)/internal/inits.h
|
||||||
vm.$(OBJEXT): $(top_srcdir)/internal/missing.h
|
vm.$(OBJEXT): $(top_srcdir)/internal/missing.h
|
||||||
|
vm.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
vm.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
vm.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
vm.$(OBJEXT): $(top_srcdir)/internal/object.h
|
vm.$(OBJEXT): $(top_srcdir)/internal/object.h
|
||||||
vm.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
vm.$(OBJEXT): $(top_srcdir)/internal/parse.h
|
||||||
@ -20103,6 +20352,7 @@ vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
|||||||
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/error.h
|
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/error.h
|
||||||
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
||||||
@ -20335,6 +20585,7 @@ vm_dump.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
|
|||||||
vm_dump.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
vm_dump.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||||
vm_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
vm_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
vm_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
vm_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
vm_dump.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
vm_dump.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
vm_dump.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
vm_dump.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
vm_dump.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
vm_dump.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
vm_dump.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
||||||
@ -20567,6 +20818,7 @@ vm_sync.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
|
|||||||
vm_sync.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
vm_sync.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
||||||
vm_sync.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
vm_sync.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
vm_sync.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
vm_sync.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
vm_sync.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
vm_sync.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
vm_sync.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
vm_sync.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
vm_sync.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
vm_sync.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
vm_sync.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
||||||
@ -20778,6 +21030,7 @@ vm_trace.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
|||||||
vm_trace.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
vm_trace.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
vm_trace.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
vm_trace.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
vm_trace.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
vm_trace.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
vm_trace.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
vm_trace.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
vm_trace.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
vm_trace.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
vm_trace.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
vm_trace.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
vm_trace.$(OBJEXT): $(top_srcdir)/internal/set_table.h
|
||||||
@ -21016,6 +21269,7 @@ weakmap.$(OBJEXT): $(top_srcdir)/internal/compilers.h
|
|||||||
weakmap.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
weakmap.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
weakmap.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
weakmap.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
weakmap.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
weakmap.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
weakmap.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
weakmap.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
weakmap.$(OBJEXT): $(top_srcdir)/internal/proc.h
|
||||||
weakmap.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
weakmap.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
weakmap.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
weakmap.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
@ -21221,6 +21475,7 @@ yjit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
|
|||||||
yjit.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
yjit.$(OBJEXT): $(top_srcdir)/internal/gc.h
|
||||||
yjit.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
yjit.$(OBJEXT): $(top_srcdir)/internal/hash.h
|
||||||
yjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
yjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h
|
||||||
|
yjit.$(OBJEXT): $(top_srcdir)/internal/namespace.h
|
||||||
yjit.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
yjit.$(OBJEXT): $(top_srcdir)/internal/numeric.h
|
||||||
yjit.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
yjit.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
|
||||||
yjit.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
yjit.$(OBJEXT): $(top_srcdir)/internal/serial.h
|
||||||
|
41
dln.c
41
dln.c
@ -26,6 +26,7 @@ static void dln_loaderror(const char *format, ...);
|
|||||||
#include "dln.h"
|
#include "dln.h"
|
||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "internal/compilers.h"
|
#include "internal/compilers.h"
|
||||||
|
#include "internal/namespace.h"
|
||||||
|
|
||||||
#ifdef HAVE_STDLIB_H
|
#ifdef HAVE_STDLIB_H
|
||||||
# include <stdlib.h>
|
# include <stdlib.h>
|
||||||
@ -382,10 +383,14 @@ dln_open(const char *file)
|
|||||||
# endif
|
# endif
|
||||||
# ifndef RTLD_GLOBAL
|
# ifndef RTLD_GLOBAL
|
||||||
# define RTLD_GLOBAL 0
|
# define RTLD_GLOBAL 0
|
||||||
|
# endif
|
||||||
|
# ifndef RTLD_LOCAL
|
||||||
|
# define RTLD_LOCAL 0 /* TODO: 0??? some systems (including libc) use 0x00100 for RTLD_GLOBAL, 0x00000 for RTLD_LOCAL */
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
/* Load file */
|
/* Load file */
|
||||||
handle = dlopen(file, RTLD_LAZY|RTLD_GLOBAL);
|
int mode = rb_namespace_available() ? RTLD_LAZY|RTLD_LOCAL : RTLD_LAZY|RTLD_GLOBAL;
|
||||||
|
handle = dlopen(file, mode);
|
||||||
if (handle == NULL) {
|
if (handle == NULL) {
|
||||||
error = dln_strerror();
|
error = dln_strerror();
|
||||||
goto failed;
|
goto failed;
|
||||||
@ -497,8 +502,8 @@ abi_check_enabled_p(void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *
|
static void *
|
||||||
dln_load(const char *file)
|
dln_load_and_init(const char *file, const char *init_fct_name)
|
||||||
{
|
{
|
||||||
#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
|
#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
|
||||||
void *handle = dln_open(file);
|
void *handle = dln_open(file);
|
||||||
@ -512,9 +517,6 @@ dln_load(const char *file)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
char *init_fct_name;
|
|
||||||
init_funcname(&init_fct_name, file);
|
|
||||||
|
|
||||||
/* Call the init code */
|
/* Call the init code */
|
||||||
dln_sym_callable(void, (void), handle, init_fct_name)();
|
dln_sym_callable(void, (void), handle, init_fct_name)();
|
||||||
|
|
||||||
@ -524,6 +526,7 @@ dln_load(const char *file)
|
|||||||
{
|
{
|
||||||
void (*init_fct)(void);
|
void (*init_fct)(void);
|
||||||
|
|
||||||
|
/* TODO: check - AIX's load system call will return the first/last symbol/function? */
|
||||||
init_fct = (void(*)(void))load((char*)file, 1, 0);
|
init_fct = (void(*)(void))load((char*)file, 1, 0);
|
||||||
if (init_fct == NULL) {
|
if (init_fct == NULL) {
|
||||||
aix_loaderror(file);
|
aix_loaderror(file);
|
||||||
@ -540,3 +543,29 @@ dln_load(const char *file)
|
|||||||
|
|
||||||
return 0; /* dummy return */
|
return 0; /* dummy return */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
dln_load(const char *file)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
|
||||||
|
char *init_fct_name;
|
||||||
|
init_funcname(&init_fct_name, file);
|
||||||
|
return dln_load_and_init(file, init_fct_name);
|
||||||
|
#else
|
||||||
|
dln_notimplement();
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void *
|
||||||
|
dln_load_feature(const char *file, const char *fname)
|
||||||
|
{
|
||||||
|
#if defined(_WIN32) || defined(USE_DLN_DLOPEN)
|
||||||
|
char *init_fct_name;
|
||||||
|
init_funcname(&init_fct_name, fname);
|
||||||
|
return dln_load_and_init(file, init_fct_name);
|
||||||
|
#else
|
||||||
|
dln_notimplement();
|
||||||
|
return 0;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
1
dln.h
1
dln.h
@ -25,6 +25,7 @@ RUBY_SYMBOL_EXPORT_BEGIN
|
|||||||
char *dln_find_exe_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
|
char *dln_find_exe_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
|
||||||
char *dln_find_file_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
|
char *dln_find_file_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL);
|
||||||
void *dln_load(const char*);
|
void *dln_load(const char*);
|
||||||
|
void *dln_load_feature(const char*, const char*);
|
||||||
void *dln_symbol(void*,const char*);
|
void *dln_symbol(void*,const char*);
|
||||||
|
|
||||||
RUBY_SYMBOL_EXPORT_END
|
RUBY_SYMBOL_EXPORT_END
|
||||||
|
9
dmydln.c
9
dmydln.c
@ -12,6 +12,15 @@ dln_load(const char *file)
|
|||||||
UNREACHABLE_RETURN(NULL);
|
UNREACHABLE_RETURN(NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NORETURN(void *dln_load_feature(const char*,const char*));
|
||||||
|
void*
|
||||||
|
dln_load_feature(const char *file, const char *fname)
|
||||||
|
{
|
||||||
|
rb_loaderror("this executable file can't load extension libraries");
|
||||||
|
|
||||||
|
UNREACHABLE_RETURN(NULL);
|
||||||
|
}
|
||||||
|
|
||||||
NORETURN(void *dln_symbol(void*,const char*));
|
NORETURN(void *dln_symbol(void*,const char*));
|
||||||
void*
|
void*
|
||||||
dln_symbol(void *handle, const char *symbol)
|
dln_symbol(void *handle, const char *symbol)
|
||||||
|
80
eval.c
80
eval.c
@ -1192,6 +1192,8 @@ rb_mod_append_features(VALUE module, VALUE include)
|
|||||||
return module;
|
return module;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE refinement_import_methods(int argc, VALUE *argv, VALUE refinement);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* include(module, ...) -> self
|
* include(module, ...) -> self
|
||||||
@ -1345,9 +1347,9 @@ rb_using_refinement(rb_cref_t *cref, VALUE klass, VALUE module)
|
|||||||
}
|
}
|
||||||
superclass = refinement_superclass(superclass);
|
superclass = refinement_superclass(superclass);
|
||||||
c = iclass = rb_include_class_new(module, superclass);
|
c = iclass = rb_include_class_new(module, superclass);
|
||||||
RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
|
RCLASS_SET_REFINED_CLASS(c, klass);
|
||||||
|
|
||||||
RCLASS_M_TBL(c) = RCLASS_M_TBL(module);
|
RCLASS_WRITE_M_TBL(c, RCLASS_M_TBL(module));
|
||||||
|
|
||||||
rb_hash_aset(CREF_REFINEMENTS(cref), klass, iclass);
|
rb_hash_aset(CREF_REFINEMENTS(cref), klass, iclass);
|
||||||
}
|
}
|
||||||
@ -1402,6 +1404,12 @@ rb_using_module(const rb_cref_t *cref, VALUE module)
|
|||||||
rb_clear_all_refinement_method_cache();
|
rb_clear_all_refinement_method_cache();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_vm_using_module(VALUE module)
|
||||||
|
{
|
||||||
|
rb_using_module(rb_vm_cref_replace_with_duplicated_cref(), module);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* target -> class_or_module
|
* target -> class_or_module
|
||||||
@ -1442,43 +1450,24 @@ add_activated_refinement(VALUE activated_refinements,
|
|||||||
}
|
}
|
||||||
superclass = refinement_superclass(superclass);
|
superclass = refinement_superclass(superclass);
|
||||||
c = iclass = rb_include_class_new(refinement, superclass);
|
c = iclass = rb_include_class_new(refinement, superclass);
|
||||||
RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
|
RCLASS_SET_REFINED_CLASS(c, klass);
|
||||||
refinement = RCLASS_SUPER(refinement);
|
refinement = RCLASS_SUPER(refinement);
|
||||||
while (refinement && refinement != klass) {
|
while (refinement && refinement != klass) {
|
||||||
c = RCLASS_SET_SUPER(c, rb_include_class_new(refinement, RCLASS_SUPER(c)));
|
c = rb_class_set_super(c, rb_include_class_new(refinement, RCLASS_SUPER(c)));
|
||||||
RB_OBJ_WRITE(c, &RCLASS_REFINED_CLASS(c), klass);
|
RCLASS_SET_REFINED_CLASS(c, klass);
|
||||||
refinement = RCLASS_SUPER(refinement);
|
refinement = RCLASS_SUPER(refinement);
|
||||||
}
|
}
|
||||||
rb_hash_aset(activated_refinements, klass, iclass);
|
rb_hash_aset(activated_refinements, klass, iclass);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
void
|
||||||
* call-seq:
|
rb_refinement_setup(struct rb_refinements_data *data, VALUE module, VALUE klass)
|
||||||
* refine(mod) { block } -> module
|
|
||||||
*
|
|
||||||
* Refine <i>mod</i> in the receiver.
|
|
||||||
*
|
|
||||||
* Returns a module, where refined methods are defined.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static VALUE
|
|
||||||
rb_mod_refine(VALUE module, VALUE klass)
|
|
||||||
{
|
{
|
||||||
VALUE refinement;
|
VALUE refinement;
|
||||||
ID id_refinements, id_activated_refinements,
|
ID id_refinements, id_activated_refinements,
|
||||||
id_refined_class, id_defined_at;
|
id_refined_class, id_defined_at;
|
||||||
VALUE refinements, activated_refinements;
|
VALUE refinements, activated_refinements;
|
||||||
rb_thread_t *th = GET_THREAD();
|
|
||||||
VALUE block_handler = rb_vm_frame_block_handler(th->ec->cfp);
|
|
||||||
|
|
||||||
if (block_handler == VM_BLOCK_HANDLER_NONE) {
|
|
||||||
rb_raise(rb_eArgError, "no block given");
|
|
||||||
}
|
|
||||||
if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {
|
|
||||||
rb_raise(rb_eArgError, "can't pass a Proc as a block to Module#refine");
|
|
||||||
}
|
|
||||||
|
|
||||||
ensure_class_or_module(klass);
|
|
||||||
CONST_ID(id_refinements, "__refinements__");
|
CONST_ID(id_refinements, "__refinements__");
|
||||||
refinements = rb_attr_get(module, id_refinements);
|
refinements = rb_attr_get(module, id_refinements);
|
||||||
if (NIL_P(refinements)) {
|
if (NIL_P(refinements)) {
|
||||||
@ -1496,7 +1485,7 @@ rb_mod_refine(VALUE module, VALUE klass)
|
|||||||
if (NIL_P(refinement)) {
|
if (NIL_P(refinement)) {
|
||||||
VALUE superclass = refinement_superclass(klass);
|
VALUE superclass = refinement_superclass(klass);
|
||||||
refinement = rb_refinement_new();
|
refinement = rb_refinement_new();
|
||||||
RCLASS_SET_SUPER(refinement, superclass);
|
rb_class_set_super(refinement, superclass);
|
||||||
RUBY_ASSERT(BUILTIN_TYPE(refinement) == T_MODULE);
|
RUBY_ASSERT(BUILTIN_TYPE(refinement) == T_MODULE);
|
||||||
FL_SET(refinement, RMODULE_IS_REFINEMENT);
|
FL_SET(refinement, RMODULE_IS_REFINEMENT);
|
||||||
CONST_ID(id_refined_class, "__refined_class__");
|
CONST_ID(id_refined_class, "__refined_class__");
|
||||||
@ -1506,8 +1495,41 @@ rb_mod_refine(VALUE module, VALUE klass)
|
|||||||
rb_hash_aset(refinements, klass, refinement);
|
rb_hash_aset(refinements, klass, refinement);
|
||||||
add_activated_refinement(activated_refinements, klass, refinement);
|
add_activated_refinement(activated_refinements, klass, refinement);
|
||||||
}
|
}
|
||||||
rb_yield_refine_block(refinement, activated_refinements);
|
|
||||||
return refinement;
|
data->refinement = refinement;
|
||||||
|
data->refinements = activated_refinements;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* call-seq:
|
||||||
|
* refine(mod) { block } -> module
|
||||||
|
*
|
||||||
|
* Refine <i>mod</i> in the receiver.
|
||||||
|
*
|
||||||
|
* Returns a module, where refined methods are defined.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
rb_mod_refine(VALUE module, VALUE klass)
|
||||||
|
{
|
||||||
|
/* module is the receiver of #refine, klass is a module to be refined (`mod` in the doc) */
|
||||||
|
rb_thread_t *th = GET_THREAD();
|
||||||
|
VALUE block_handler = rb_vm_frame_block_handler(th->ec->cfp);
|
||||||
|
struct rb_refinements_data data;
|
||||||
|
|
||||||
|
if (block_handler == VM_BLOCK_HANDLER_NONE) {
|
||||||
|
rb_raise(rb_eArgError, "no block given");
|
||||||
|
}
|
||||||
|
if (vm_block_handler_type(block_handler) != block_handler_type_iseq) {
|
||||||
|
rb_raise(rb_eArgError, "can't pass a Proc as a block to Module#refine");
|
||||||
|
}
|
||||||
|
|
||||||
|
ensure_class_or_module(klass);
|
||||||
|
|
||||||
|
rb_refinement_setup(&data, module, klass);
|
||||||
|
|
||||||
|
rb_yield_refine_block(data.refinement, data.refinements);
|
||||||
|
return data.refinement;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -296,6 +296,7 @@ VALUE rb_vm_make_jump_tag_but_local_jump(enum ruby_tag_type state, VALUE val);
|
|||||||
rb_cref_t *rb_vm_cref(void);
|
rb_cref_t *rb_vm_cref(void);
|
||||||
rb_cref_t *rb_vm_cref_replace_with_duplicated_cref(void);
|
rb_cref_t *rb_vm_cref_replace_with_duplicated_cref(void);
|
||||||
VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename);
|
VALUE rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg, VALUE block_handler, VALUE filename);
|
||||||
|
VALUE rb_vm_call_cfunc2(VALUE recv, VALUE (*func)(VALUE, VALUE), VALUE arg1, VALUE arg2, VALUE block_handler, VALUE filename);
|
||||||
void rb_vm_set_progname(VALUE filename);
|
void rb_vm_set_progname(VALUE filename);
|
||||||
VALUE rb_vm_cbase(void);
|
VALUE rb_vm_cbase(void);
|
||||||
|
|
||||||
|
1
ext/-test-/namespace/yay1/extconf.rb
Normal file
1
ext/-test-/namespace/yay1/extconf.rb
Normal file
@ -0,0 +1 @@
|
|||||||
|
create_makefile('-test-/namespace/yay1')
|
28
ext/-test-/namespace/yay1/yay1.c
Normal file
28
ext/-test-/namespace/yay1/yay1.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include "yay1.h"
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
yay_value(void)
|
||||||
|
{
|
||||||
|
return rb_str_new_cstr("yay");
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
yay1_f_version(VALUE klass)
|
||||||
|
{
|
||||||
|
return rb_str_new_cstr("1.0.0");
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
yay1_yay(VALUE klass)
|
||||||
|
{
|
||||||
|
return yay_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Init_yay1(void)
|
||||||
|
{
|
||||||
|
VALUE mod = rb_define_module("Yay");
|
||||||
|
rb_define_const(mod, "VERSION", rb_str_new_cstr("1.0.0"));
|
||||||
|
rb_define_singleton_method(mod, "version", yay1_f_version, 0);
|
||||||
|
rb_define_singleton_method(mod, "yay", yay1_yay, 0);
|
||||||
|
}
|
4
ext/-test-/namespace/yay1/yay1.def
Normal file
4
ext/-test-/namespace/yay1/yay1.def
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
LIBRARY yay1
|
||||||
|
EXPORTS
|
||||||
|
Init_yay1
|
||||||
|
yay_value
|
4
ext/-test-/namespace/yay1/yay1.h
Normal file
4
ext/-test-/namespace/yay1/yay1.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#include <ruby.h>
|
||||||
|
#include "ruby/internal/dllexport.h"
|
||||||
|
|
||||||
|
RUBY_EXTERN VALUE yay_value(void);
|
1
ext/-test-/namespace/yay2/extconf.rb
Normal file
1
ext/-test-/namespace/yay2/extconf.rb
Normal file
@ -0,0 +1 @@
|
|||||||
|
create_makefile('-test-/namespace/yay2')
|
28
ext/-test-/namespace/yay2/yay2.c
Normal file
28
ext/-test-/namespace/yay2/yay2.c
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#include "yay2.h"
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
yay_value(void)
|
||||||
|
{
|
||||||
|
return rb_str_new_cstr("yaaay");
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
yay2_f_version(VALUE klass)
|
||||||
|
{
|
||||||
|
return rb_str_new_cstr("2.0.0");
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
yay2_yay(VALUE klass)
|
||||||
|
{
|
||||||
|
return yay_value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Init_yay2(void)
|
||||||
|
{
|
||||||
|
VALUE mod = rb_define_module("Yay");
|
||||||
|
rb_define_const(mod, "VERSION", rb_str_new_cstr("2.0.0"));
|
||||||
|
rb_define_singleton_method(mod, "version", yay2_f_version, 0);
|
||||||
|
rb_define_singleton_method(mod, "yay", yay2_yay, 0);
|
||||||
|
}
|
4
ext/-test-/namespace/yay2/yay2.def
Normal file
4
ext/-test-/namespace/yay2/yay2.def
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
LIBRARY yay2
|
||||||
|
EXPORTS
|
||||||
|
Init_yay2
|
||||||
|
yay_value
|
4
ext/-test-/namespace/yay2/yay2.h
Normal file
4
ext/-test-/namespace/yay2/yay2.h
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
#include <ruby.h>
|
||||||
|
#include "ruby/internal/dllexport.h"
|
||||||
|
|
||||||
|
RUBY_EXTERN VALUE yay_value(void);
|
@ -186,6 +186,7 @@ coverage.o: $(top_srcdir)/internal/compilers.h
|
|||||||
coverage.o: $(top_srcdir)/internal/gc.h
|
coverage.o: $(top_srcdir)/internal/gc.h
|
||||||
coverage.o: $(top_srcdir)/internal/hash.h
|
coverage.o: $(top_srcdir)/internal/hash.h
|
||||||
coverage.o: $(top_srcdir)/internal/imemo.h
|
coverage.o: $(top_srcdir)/internal/imemo.h
|
||||||
|
coverage.o: $(top_srcdir)/internal/namespace.h
|
||||||
coverage.o: $(top_srcdir)/internal/sanitizers.h
|
coverage.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
coverage.o: $(top_srcdir)/internal/serial.h
|
coverage.o: $(top_srcdir)/internal/serial.h
|
||||||
coverage.o: $(top_srcdir)/internal/set_table.h
|
coverage.o: $(top_srcdir)/internal/set_table.h
|
||||||
|
@ -183,6 +183,7 @@ object_tracing.o: $(top_srcdir)/internal/basic_operators.h
|
|||||||
object_tracing.o: $(top_srcdir)/internal/compilers.h
|
object_tracing.o: $(top_srcdir)/internal/compilers.h
|
||||||
object_tracing.o: $(top_srcdir)/internal/gc.h
|
object_tracing.o: $(top_srcdir)/internal/gc.h
|
||||||
object_tracing.o: $(top_srcdir)/internal/imemo.h
|
object_tracing.o: $(top_srcdir)/internal/imemo.h
|
||||||
|
object_tracing.o: $(top_srcdir)/internal/namespace.h
|
||||||
object_tracing.o: $(top_srcdir)/internal/sanitizers.h
|
object_tracing.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
object_tracing.o: $(top_srcdir)/internal/serial.h
|
object_tracing.o: $(top_srcdir)/internal/serial.h
|
||||||
object_tracing.o: $(top_srcdir)/internal/set_table.h
|
object_tracing.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -392,6 +393,7 @@ objspace.o: $(top_srcdir)/internal/compilers.h
|
|||||||
objspace.o: $(top_srcdir)/internal/gc.h
|
objspace.o: $(top_srcdir)/internal/gc.h
|
||||||
objspace.o: $(top_srcdir)/internal/hash.h
|
objspace.o: $(top_srcdir)/internal/hash.h
|
||||||
objspace.o: $(top_srcdir)/internal/imemo.h
|
objspace.o: $(top_srcdir)/internal/imemo.h
|
||||||
|
objspace.o: $(top_srcdir)/internal/namespace.h
|
||||||
objspace.o: $(top_srcdir)/internal/sanitizers.h
|
objspace.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
objspace.o: $(top_srcdir)/internal/serial.h
|
objspace.o: $(top_srcdir)/internal/serial.h
|
||||||
objspace.o: $(top_srcdir)/internal/set_table.h
|
objspace.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -605,6 +607,7 @@ objspace_dump.o: $(top_srcdir)/internal/gc.h
|
|||||||
objspace_dump.o: $(top_srcdir)/internal/hash.h
|
objspace_dump.o: $(top_srcdir)/internal/hash.h
|
||||||
objspace_dump.o: $(top_srcdir)/internal/imemo.h
|
objspace_dump.o: $(top_srcdir)/internal/imemo.h
|
||||||
objspace_dump.o: $(top_srcdir)/internal/io.h
|
objspace_dump.o: $(top_srcdir)/internal/io.h
|
||||||
|
objspace_dump.o: $(top_srcdir)/internal/namespace.h
|
||||||
objspace_dump.o: $(top_srcdir)/internal/sanitizers.h
|
objspace_dump.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
objspace_dump.o: $(top_srcdir)/internal/serial.h
|
objspace_dump.o: $(top_srcdir)/internal/serial.h
|
||||||
objspace_dump.o: $(top_srcdir)/internal/set_table.h
|
objspace_dump.o: $(top_srcdir)/internal/set_table.h
|
||||||
|
@ -792,7 +792,7 @@ objspace_internal_super_of(VALUE self, VALUE obj)
|
|||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
case T_ICLASS:
|
case T_ICLASS:
|
||||||
super = RCLASS_SUPER(obj);
|
super = rb_class_super_of(obj);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
rb_raise(rb_eArgError, "class or module is expected");
|
rb_raise(rb_eArgError, "class or module is expected");
|
||||||
|
@ -537,7 +537,7 @@ dump_object(VALUE obj, struct dump_config *dc)
|
|||||||
|
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
dump_append(dc, ", \"variation_count\":");
|
dump_append(dc, ", \"variation_count\":");
|
||||||
dump_append_d(dc, RCLASS_EXT(obj)->variation_count);
|
dump_append_d(dc, rb_class_variation_count(obj));
|
||||||
|
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
if (rb_class_get_superclass(obj)) {
|
if (rb_class_get_superclass(obj)) {
|
||||||
@ -560,7 +560,7 @@ dump_object(VALUE obj, struct dump_config *dc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RCLASS_SINGLETON_P(obj)) {
|
if (rb_class_singleton_p(obj)) {
|
||||||
dump_append(dc, ", \"singleton\":true");
|
dump_append(dc, ", \"singleton\":true");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -591,6 +591,7 @@ ripper.o: $(top_srcdir)/internal/gc.h
|
|||||||
ripper.o: $(top_srcdir)/internal/hash.h
|
ripper.o: $(top_srcdir)/internal/hash.h
|
||||||
ripper.o: $(top_srcdir)/internal/imemo.h
|
ripper.o: $(top_srcdir)/internal/imemo.h
|
||||||
ripper.o: $(top_srcdir)/internal/io.h
|
ripper.o: $(top_srcdir)/internal/io.h
|
||||||
|
ripper.o: $(top_srcdir)/internal/namespace.h
|
||||||
ripper.o: $(top_srcdir)/internal/numeric.h
|
ripper.o: $(top_srcdir)/internal/numeric.h
|
||||||
ripper.o: $(top_srcdir)/internal/parse.h
|
ripper.o: $(top_srcdir)/internal/parse.h
|
||||||
ripper.o: $(top_srcdir)/internal/rational.h
|
ripper.o: $(top_srcdir)/internal/rational.h
|
||||||
|
@ -200,6 +200,7 @@ ancdata.o: $(top_srcdir)/internal/error.h
|
|||||||
ancdata.o: $(top_srcdir)/internal/gc.h
|
ancdata.o: $(top_srcdir)/internal/gc.h
|
||||||
ancdata.o: $(top_srcdir)/internal/imemo.h
|
ancdata.o: $(top_srcdir)/internal/imemo.h
|
||||||
ancdata.o: $(top_srcdir)/internal/io.h
|
ancdata.o: $(top_srcdir)/internal/io.h
|
||||||
|
ancdata.o: $(top_srcdir)/internal/namespace.h
|
||||||
ancdata.o: $(top_srcdir)/internal/sanitizers.h
|
ancdata.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
ancdata.o: $(top_srcdir)/internal/serial.h
|
ancdata.o: $(top_srcdir)/internal/serial.h
|
||||||
ancdata.o: $(top_srcdir)/internal/set_table.h
|
ancdata.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -412,6 +413,7 @@ basicsocket.o: $(top_srcdir)/internal/error.h
|
|||||||
basicsocket.o: $(top_srcdir)/internal/gc.h
|
basicsocket.o: $(top_srcdir)/internal/gc.h
|
||||||
basicsocket.o: $(top_srcdir)/internal/imemo.h
|
basicsocket.o: $(top_srcdir)/internal/imemo.h
|
||||||
basicsocket.o: $(top_srcdir)/internal/io.h
|
basicsocket.o: $(top_srcdir)/internal/io.h
|
||||||
|
basicsocket.o: $(top_srcdir)/internal/namespace.h
|
||||||
basicsocket.o: $(top_srcdir)/internal/sanitizers.h
|
basicsocket.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
basicsocket.o: $(top_srcdir)/internal/serial.h
|
basicsocket.o: $(top_srcdir)/internal/serial.h
|
||||||
basicsocket.o: $(top_srcdir)/internal/set_table.h
|
basicsocket.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -624,6 +626,7 @@ constants.o: $(top_srcdir)/internal/error.h
|
|||||||
constants.o: $(top_srcdir)/internal/gc.h
|
constants.o: $(top_srcdir)/internal/gc.h
|
||||||
constants.o: $(top_srcdir)/internal/imemo.h
|
constants.o: $(top_srcdir)/internal/imemo.h
|
||||||
constants.o: $(top_srcdir)/internal/io.h
|
constants.o: $(top_srcdir)/internal/io.h
|
||||||
|
constants.o: $(top_srcdir)/internal/namespace.h
|
||||||
constants.o: $(top_srcdir)/internal/sanitizers.h
|
constants.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
constants.o: $(top_srcdir)/internal/serial.h
|
constants.o: $(top_srcdir)/internal/serial.h
|
||||||
constants.o: $(top_srcdir)/internal/set_table.h
|
constants.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -837,6 +840,7 @@ ifaddr.o: $(top_srcdir)/internal/error.h
|
|||||||
ifaddr.o: $(top_srcdir)/internal/gc.h
|
ifaddr.o: $(top_srcdir)/internal/gc.h
|
||||||
ifaddr.o: $(top_srcdir)/internal/imemo.h
|
ifaddr.o: $(top_srcdir)/internal/imemo.h
|
||||||
ifaddr.o: $(top_srcdir)/internal/io.h
|
ifaddr.o: $(top_srcdir)/internal/io.h
|
||||||
|
ifaddr.o: $(top_srcdir)/internal/namespace.h
|
||||||
ifaddr.o: $(top_srcdir)/internal/sanitizers.h
|
ifaddr.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
ifaddr.o: $(top_srcdir)/internal/serial.h
|
ifaddr.o: $(top_srcdir)/internal/serial.h
|
||||||
ifaddr.o: $(top_srcdir)/internal/set_table.h
|
ifaddr.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -1049,6 +1053,7 @@ init.o: $(top_srcdir)/internal/error.h
|
|||||||
init.o: $(top_srcdir)/internal/gc.h
|
init.o: $(top_srcdir)/internal/gc.h
|
||||||
init.o: $(top_srcdir)/internal/imemo.h
|
init.o: $(top_srcdir)/internal/imemo.h
|
||||||
init.o: $(top_srcdir)/internal/io.h
|
init.o: $(top_srcdir)/internal/io.h
|
||||||
|
init.o: $(top_srcdir)/internal/namespace.h
|
||||||
init.o: $(top_srcdir)/internal/sanitizers.h
|
init.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
init.o: $(top_srcdir)/internal/serial.h
|
init.o: $(top_srcdir)/internal/serial.h
|
||||||
init.o: $(top_srcdir)/internal/set_table.h
|
init.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -1261,6 +1266,7 @@ ipsocket.o: $(top_srcdir)/internal/error.h
|
|||||||
ipsocket.o: $(top_srcdir)/internal/gc.h
|
ipsocket.o: $(top_srcdir)/internal/gc.h
|
||||||
ipsocket.o: $(top_srcdir)/internal/imemo.h
|
ipsocket.o: $(top_srcdir)/internal/imemo.h
|
||||||
ipsocket.o: $(top_srcdir)/internal/io.h
|
ipsocket.o: $(top_srcdir)/internal/io.h
|
||||||
|
ipsocket.o: $(top_srcdir)/internal/namespace.h
|
||||||
ipsocket.o: $(top_srcdir)/internal/sanitizers.h
|
ipsocket.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
ipsocket.o: $(top_srcdir)/internal/serial.h
|
ipsocket.o: $(top_srcdir)/internal/serial.h
|
||||||
ipsocket.o: $(top_srcdir)/internal/set_table.h
|
ipsocket.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -1473,6 +1479,7 @@ option.o: $(top_srcdir)/internal/error.h
|
|||||||
option.o: $(top_srcdir)/internal/gc.h
|
option.o: $(top_srcdir)/internal/gc.h
|
||||||
option.o: $(top_srcdir)/internal/imemo.h
|
option.o: $(top_srcdir)/internal/imemo.h
|
||||||
option.o: $(top_srcdir)/internal/io.h
|
option.o: $(top_srcdir)/internal/io.h
|
||||||
|
option.o: $(top_srcdir)/internal/namespace.h
|
||||||
option.o: $(top_srcdir)/internal/sanitizers.h
|
option.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
option.o: $(top_srcdir)/internal/serial.h
|
option.o: $(top_srcdir)/internal/serial.h
|
||||||
option.o: $(top_srcdir)/internal/set_table.h
|
option.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -1685,6 +1692,7 @@ raddrinfo.o: $(top_srcdir)/internal/error.h
|
|||||||
raddrinfo.o: $(top_srcdir)/internal/gc.h
|
raddrinfo.o: $(top_srcdir)/internal/gc.h
|
||||||
raddrinfo.o: $(top_srcdir)/internal/imemo.h
|
raddrinfo.o: $(top_srcdir)/internal/imemo.h
|
||||||
raddrinfo.o: $(top_srcdir)/internal/io.h
|
raddrinfo.o: $(top_srcdir)/internal/io.h
|
||||||
|
raddrinfo.o: $(top_srcdir)/internal/namespace.h
|
||||||
raddrinfo.o: $(top_srcdir)/internal/sanitizers.h
|
raddrinfo.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
raddrinfo.o: $(top_srcdir)/internal/serial.h
|
raddrinfo.o: $(top_srcdir)/internal/serial.h
|
||||||
raddrinfo.o: $(top_srcdir)/internal/set_table.h
|
raddrinfo.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -1897,6 +1905,7 @@ socket.o: $(top_srcdir)/internal/error.h
|
|||||||
socket.o: $(top_srcdir)/internal/gc.h
|
socket.o: $(top_srcdir)/internal/gc.h
|
||||||
socket.o: $(top_srcdir)/internal/imemo.h
|
socket.o: $(top_srcdir)/internal/imemo.h
|
||||||
socket.o: $(top_srcdir)/internal/io.h
|
socket.o: $(top_srcdir)/internal/io.h
|
||||||
|
socket.o: $(top_srcdir)/internal/namespace.h
|
||||||
socket.o: $(top_srcdir)/internal/sanitizers.h
|
socket.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
socket.o: $(top_srcdir)/internal/serial.h
|
socket.o: $(top_srcdir)/internal/serial.h
|
||||||
socket.o: $(top_srcdir)/internal/set_table.h
|
socket.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -2109,6 +2118,7 @@ sockssocket.o: $(top_srcdir)/internal/error.h
|
|||||||
sockssocket.o: $(top_srcdir)/internal/gc.h
|
sockssocket.o: $(top_srcdir)/internal/gc.h
|
||||||
sockssocket.o: $(top_srcdir)/internal/imemo.h
|
sockssocket.o: $(top_srcdir)/internal/imemo.h
|
||||||
sockssocket.o: $(top_srcdir)/internal/io.h
|
sockssocket.o: $(top_srcdir)/internal/io.h
|
||||||
|
sockssocket.o: $(top_srcdir)/internal/namespace.h
|
||||||
sockssocket.o: $(top_srcdir)/internal/sanitizers.h
|
sockssocket.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
sockssocket.o: $(top_srcdir)/internal/serial.h
|
sockssocket.o: $(top_srcdir)/internal/serial.h
|
||||||
sockssocket.o: $(top_srcdir)/internal/set_table.h
|
sockssocket.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -2321,6 +2331,7 @@ tcpserver.o: $(top_srcdir)/internal/error.h
|
|||||||
tcpserver.o: $(top_srcdir)/internal/gc.h
|
tcpserver.o: $(top_srcdir)/internal/gc.h
|
||||||
tcpserver.o: $(top_srcdir)/internal/imemo.h
|
tcpserver.o: $(top_srcdir)/internal/imemo.h
|
||||||
tcpserver.o: $(top_srcdir)/internal/io.h
|
tcpserver.o: $(top_srcdir)/internal/io.h
|
||||||
|
tcpserver.o: $(top_srcdir)/internal/namespace.h
|
||||||
tcpserver.o: $(top_srcdir)/internal/sanitizers.h
|
tcpserver.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
tcpserver.o: $(top_srcdir)/internal/serial.h
|
tcpserver.o: $(top_srcdir)/internal/serial.h
|
||||||
tcpserver.o: $(top_srcdir)/internal/set_table.h
|
tcpserver.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -2533,6 +2544,7 @@ tcpsocket.o: $(top_srcdir)/internal/error.h
|
|||||||
tcpsocket.o: $(top_srcdir)/internal/gc.h
|
tcpsocket.o: $(top_srcdir)/internal/gc.h
|
||||||
tcpsocket.o: $(top_srcdir)/internal/imemo.h
|
tcpsocket.o: $(top_srcdir)/internal/imemo.h
|
||||||
tcpsocket.o: $(top_srcdir)/internal/io.h
|
tcpsocket.o: $(top_srcdir)/internal/io.h
|
||||||
|
tcpsocket.o: $(top_srcdir)/internal/namespace.h
|
||||||
tcpsocket.o: $(top_srcdir)/internal/sanitizers.h
|
tcpsocket.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
tcpsocket.o: $(top_srcdir)/internal/serial.h
|
tcpsocket.o: $(top_srcdir)/internal/serial.h
|
||||||
tcpsocket.o: $(top_srcdir)/internal/set_table.h
|
tcpsocket.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -2745,6 +2757,7 @@ udpsocket.o: $(top_srcdir)/internal/error.h
|
|||||||
udpsocket.o: $(top_srcdir)/internal/gc.h
|
udpsocket.o: $(top_srcdir)/internal/gc.h
|
||||||
udpsocket.o: $(top_srcdir)/internal/imemo.h
|
udpsocket.o: $(top_srcdir)/internal/imemo.h
|
||||||
udpsocket.o: $(top_srcdir)/internal/io.h
|
udpsocket.o: $(top_srcdir)/internal/io.h
|
||||||
|
udpsocket.o: $(top_srcdir)/internal/namespace.h
|
||||||
udpsocket.o: $(top_srcdir)/internal/sanitizers.h
|
udpsocket.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
udpsocket.o: $(top_srcdir)/internal/serial.h
|
udpsocket.o: $(top_srcdir)/internal/serial.h
|
||||||
udpsocket.o: $(top_srcdir)/internal/set_table.h
|
udpsocket.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -2957,6 +2970,7 @@ unixserver.o: $(top_srcdir)/internal/error.h
|
|||||||
unixserver.o: $(top_srcdir)/internal/gc.h
|
unixserver.o: $(top_srcdir)/internal/gc.h
|
||||||
unixserver.o: $(top_srcdir)/internal/imemo.h
|
unixserver.o: $(top_srcdir)/internal/imemo.h
|
||||||
unixserver.o: $(top_srcdir)/internal/io.h
|
unixserver.o: $(top_srcdir)/internal/io.h
|
||||||
|
unixserver.o: $(top_srcdir)/internal/namespace.h
|
||||||
unixserver.o: $(top_srcdir)/internal/sanitizers.h
|
unixserver.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
unixserver.o: $(top_srcdir)/internal/serial.h
|
unixserver.o: $(top_srcdir)/internal/serial.h
|
||||||
unixserver.o: $(top_srcdir)/internal/set_table.h
|
unixserver.o: $(top_srcdir)/internal/set_table.h
|
||||||
@ -3169,6 +3183,7 @@ unixsocket.o: $(top_srcdir)/internal/error.h
|
|||||||
unixsocket.o: $(top_srcdir)/internal/gc.h
|
unixsocket.o: $(top_srcdir)/internal/gc.h
|
||||||
unixsocket.o: $(top_srcdir)/internal/imemo.h
|
unixsocket.o: $(top_srcdir)/internal/imemo.h
|
||||||
unixsocket.o: $(top_srcdir)/internal/io.h
|
unixsocket.o: $(top_srcdir)/internal/io.h
|
||||||
|
unixsocket.o: $(top_srcdir)/internal/namespace.h
|
||||||
unixsocket.o: $(top_srcdir)/internal/sanitizers.h
|
unixsocket.o: $(top_srcdir)/internal/sanitizers.h
|
||||||
unixsocket.o: $(top_srcdir)/internal/serial.h
|
unixsocket.o: $(top_srcdir)/internal/serial.h
|
||||||
unixsocket.o: $(top_srcdir)/internal/set_table.h
|
unixsocket.o: $(top_srcdir)/internal/set_table.h
|
||||||
|
527
gc.c
527
gc.c
@ -1210,9 +1210,68 @@ rb_data_free(void *objspace, VALUE obj)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct classext_foreach_args {
|
||||||
|
VALUE klass;
|
||||||
|
bool obj_too_complex;
|
||||||
|
rb_objspace_t *objspace; // used for update_*
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
classext_free(rb_classext_t *ext, bool is_prime, VALUE namespace, void *arg)
|
||||||
|
{
|
||||||
|
struct rb_id_table *tbl;
|
||||||
|
struct classext_foreach_args *args = (struct classext_foreach_args *)arg;
|
||||||
|
|
||||||
|
rb_id_table_free(RCLASSEXT_M_TBL(ext));
|
||||||
|
rb_cc_tbl_free(RCLASSEXT_CC_TBL(ext), args->klass);
|
||||||
|
if (args->obj_too_complex) {
|
||||||
|
st_free_table((st_table *)RCLASSEXT_FIELDS(ext));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
xfree(RCLASSEXT_FIELDS(ext));
|
||||||
|
}
|
||||||
|
if (!RCLASSEXT_SHARED_CONST_TBL(ext) && (tbl = RCLASSEXT_CONST_TBL(ext)) != NULL) {
|
||||||
|
rb_free_const_table(tbl);
|
||||||
|
}
|
||||||
|
if ((tbl = RCLASSEXT_CVC_TBL(ext)) != NULL) {
|
||||||
|
rb_id_table_foreach_values(tbl, cvar_table_free_i, NULL);
|
||||||
|
rb_id_table_free(tbl);
|
||||||
|
}
|
||||||
|
rb_class_classext_free_subclasses(ext, args->klass);
|
||||||
|
if (RCLASSEXT_SUPERCLASSES_OWNER(ext)) {
|
||||||
|
xfree(RCLASSEXT_SUPERCLASSES(ext));
|
||||||
|
}
|
||||||
|
if (!is_prime) { // the prime classext will be freed with RClass
|
||||||
|
xfree(ext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
classext_iclass_free(rb_classext_t *ext, bool is_prime, VALUE namespace, void *arg)
|
||||||
|
{
|
||||||
|
struct classext_foreach_args *args = (struct classext_foreach_args *)arg;
|
||||||
|
|
||||||
|
if (RCLASSEXT_ICLASS_IS_ORIGIN(ext) && !RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(ext)) {
|
||||||
|
/* Method table is not shared for origin iclasses of classes */
|
||||||
|
rb_id_table_free(RCLASSEXT_M_TBL(ext));
|
||||||
|
}
|
||||||
|
if (RCLASSEXT_CALLABLE_M_TBL(ext) != NULL) {
|
||||||
|
rb_id_table_free(RCLASSEXT_CALLABLE_M_TBL(ext));
|
||||||
|
}
|
||||||
|
rb_cc_tbl_free(RCLASSEXT_CC_TBL(ext), args->klass);
|
||||||
|
|
||||||
|
rb_class_classext_free_subclasses(ext, args->klass);
|
||||||
|
|
||||||
|
if (!is_prime) { // the prime classext will be freed with RClass
|
||||||
|
xfree(ext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
rb_gc_obj_free(void *objspace, VALUE obj)
|
rb_gc_obj_free(void *objspace, VALUE obj)
|
||||||
{
|
{
|
||||||
|
struct classext_foreach_args args;
|
||||||
|
|
||||||
RB_DEBUG_COUNTER_INC(obj_free);
|
RB_DEBUG_COUNTER_INC(obj_free);
|
||||||
|
|
||||||
switch (BUILTIN_TYPE(obj)) {
|
switch (BUILTIN_TYPE(obj)) {
|
||||||
@ -1242,29 +1301,13 @@ rb_gc_obj_free(void *objspace, VALUE obj)
|
|||||||
break;
|
break;
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
rb_id_table_free(RCLASS_M_TBL(obj));
|
args.klass = obj;
|
||||||
rb_cc_table_free(obj);
|
args.obj_too_complex = rb_shape_obj_too_complex_p(obj) ? true : false;
|
||||||
if (rb_shape_obj_too_complex_p(obj)) {
|
|
||||||
st_free_table((st_table *)RCLASS_FIELDS(obj));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
xfree(RCLASS_FIELDS(obj));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RCLASS_CONST_TBL(obj)) {
|
rb_class_classext_foreach(obj, classext_free, (void *)&args);
|
||||||
rb_free_const_table(RCLASS_CONST_TBL(obj));
|
if (RCLASS(obj)->ns_classext_tbl) {
|
||||||
|
st_free_table(RCLASS(obj)->ns_classext_tbl);
|
||||||
}
|
}
|
||||||
if (RCLASS_CVC_TBL(obj)) {
|
|
||||||
rb_id_table_foreach_values(RCLASS_CVC_TBL(obj), cvar_table_free_i, NULL);
|
|
||||||
rb_id_table_free(RCLASS_CVC_TBL(obj));
|
|
||||||
}
|
|
||||||
rb_class_remove_subclass_head(obj);
|
|
||||||
rb_class_remove_from_module_subclasses(obj);
|
|
||||||
rb_class_remove_from_super_subclasses(obj);
|
|
||||||
if (FL_TEST_RAW(obj, RCLASS_SUPERCLASSES_INCLUDE_SELF)) {
|
|
||||||
xfree(RCLASS_SUPERCLASSES(obj));
|
|
||||||
}
|
|
||||||
|
|
||||||
(void)RB_DEBUG_COUNTER_INC_IF(obj_module_ptr, BUILTIN_TYPE(obj) == T_MODULE);
|
(void)RB_DEBUG_COUNTER_INC_IF(obj_module_ptr, BUILTIN_TYPE(obj) == T_MODULE);
|
||||||
(void)RB_DEBUG_COUNTER_INC_IF(obj_class_ptr, BUILTIN_TYPE(obj) == T_CLASS);
|
(void)RB_DEBUG_COUNTER_INC_IF(obj_class_ptr, BUILTIN_TYPE(obj) == T_CLASS);
|
||||||
break;
|
break;
|
||||||
@ -1363,18 +1406,12 @@ rb_gc_obj_free(void *objspace, VALUE obj)
|
|||||||
case T_MOVED:
|
case T_MOVED:
|
||||||
break;
|
break;
|
||||||
case T_ICLASS:
|
case T_ICLASS:
|
||||||
/* Basically , T_ICLASS shares table with the module */
|
args.klass = obj;
|
||||||
if (RICLASS_OWNS_M_TBL_P(obj)) {
|
|
||||||
/* Method table is not shared for origin iclasses of classes */
|
rb_class_classext_foreach(obj, classext_iclass_free, (void *)&args);
|
||||||
rb_id_table_free(RCLASS_M_TBL(obj));
|
if (RCLASS(obj)->ns_classext_tbl) {
|
||||||
|
st_free_table(RCLASS(obj)->ns_classext_tbl);
|
||||||
}
|
}
|
||||||
if (RCLASS_CALLABLE_M_TBL(obj) != NULL) {
|
|
||||||
rb_id_table_free(RCLASS_CALLABLE_M_TBL(obj));
|
|
||||||
}
|
|
||||||
rb_class_remove_subclass_head(obj);
|
|
||||||
rb_cc_table_free(obj);
|
|
||||||
rb_class_remove_from_module_subclasses(obj);
|
|
||||||
rb_class_remove_from_super_subclasses(obj);
|
|
||||||
|
|
||||||
RB_DEBUG_COUNTER_INC(obj_iclass_ptr);
|
RB_DEBUG_COUNTER_INC(obj_iclass_ptr);
|
||||||
break;
|
break;
|
||||||
@ -2124,6 +2161,60 @@ cc_table_memsize(struct rb_id_table *cc_table)
|
|||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
classext_memsize(rb_classext_t *ext, bool prime, VALUE namespace, void *arg)
|
||||||
|
{
|
||||||
|
size_t *size = (size_t *)arg;
|
||||||
|
size_t s = 0;
|
||||||
|
|
||||||
|
if (RCLASSEXT_M_TBL(ext)) {
|
||||||
|
s += rb_id_table_memsize(RCLASSEXT_M_TBL(ext));
|
||||||
|
}
|
||||||
|
if (RCLASSEXT_CVC_TBL(ext)) {
|
||||||
|
s += rb_id_table_memsize(RCLASSEXT_CVC_TBL(ext));
|
||||||
|
}
|
||||||
|
if (RCLASSEXT_CONST_TBL(ext)) {
|
||||||
|
s += rb_id_table_memsize(RCLASSEXT_CONST_TBL(ext));
|
||||||
|
}
|
||||||
|
if (RCLASSEXT_CC_TBL(ext)) {
|
||||||
|
s += cc_table_memsize(RCLASSEXT_CC_TBL(ext));
|
||||||
|
}
|
||||||
|
if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext)) {
|
||||||
|
s += (RCLASSEXT_SUPERCLASS_DEPTH(ext) + 1) * sizeof(VALUE);
|
||||||
|
}
|
||||||
|
if (!prime) {
|
||||||
|
s += sizeof(rb_classext_t);
|
||||||
|
}
|
||||||
|
*size += s;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
classext_fields_hash_memsize(rb_classext_t *ext, bool prime, VALUE namespace, void *arg)
|
||||||
|
{
|
||||||
|
size_t *size = (size_t *)arg;
|
||||||
|
size_t count;
|
||||||
|
RB_VM_LOCK_ENTER();
|
||||||
|
{
|
||||||
|
count = rb_st_table_size((st_table *)RCLASSEXT_FIELDS(ext));
|
||||||
|
}
|
||||||
|
RB_VM_LOCK_LEAVE();
|
||||||
|
// class IV sizes are allocated as powers of two
|
||||||
|
*size += SIZEOF_VALUE << bit_length(count);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
classext_superclasses_memsize(rb_classext_t *ext, bool prime, VALUE namespace, void *arg)
|
||||||
|
{
|
||||||
|
size_t *size = (size_t *)arg;
|
||||||
|
size_t array_size;
|
||||||
|
if (RCLASSEXT_SUPERCLASSES_OWNER(ext)) {
|
||||||
|
array_size = RCLASSEXT_SUPERCLASS_DEPTH(ext);
|
||||||
|
if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext))
|
||||||
|
array_size += 1;
|
||||||
|
*size += array_size * sizeof(VALUE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
rb_obj_memsize_of(VALUE obj)
|
rb_obj_memsize_of(VALUE obj)
|
||||||
{
|
{
|
||||||
@ -2148,23 +2239,16 @@ rb_obj_memsize_of(VALUE obj)
|
|||||||
break;
|
break;
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
if (RCLASS_M_TBL(obj)) {
|
rb_class_classext_foreach(obj, classext_memsize, (void *)&size);
|
||||||
size += rb_id_table_memsize(RCLASS_M_TBL(obj));
|
|
||||||
}
|
if (rb_shape_obj_too_complex_p(obj)) {
|
||||||
// class IV sizes are allocated as powers of two
|
rb_class_classext_foreach(obj, classext_fields_hash_memsize, (void *)&size);
|
||||||
size += SIZEOF_VALUE << bit_length(RCLASS_FIELDS_COUNT(obj));
|
} else {
|
||||||
if (RCLASS_CVC_TBL(obj)) {
|
// class IV sizes are allocated as powers of two
|
||||||
size += rb_id_table_memsize(RCLASS_CVC_TBL(obj));
|
size += SIZEOF_VALUE << bit_length(RCLASS_FIELDS_COUNT(obj));
|
||||||
}
|
|
||||||
if (RCLASS_EXT(obj)->const_tbl) {
|
|
||||||
size += rb_id_table_memsize(RCLASS_EXT(obj)->const_tbl);
|
|
||||||
}
|
|
||||||
if (RCLASS_CC_TBL(obj)) {
|
|
||||||
size += cc_table_memsize(RCLASS_CC_TBL(obj));
|
|
||||||
}
|
|
||||||
if (FL_TEST_RAW(obj, RCLASS_SUPERCLASSES_INCLUDE_SELF)) {
|
|
||||||
size += (RCLASS_SUPERCLASS_DEPTH(obj) + 1) * sizeof(VALUE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rb_class_classext_foreach(obj, classext_superclasses_memsize, (void *)&size);
|
||||||
break;
|
break;
|
||||||
case T_ICLASS:
|
case T_ICLASS:
|
||||||
if (RICLASS_OWNS_M_TBL_P(obj)) {
|
if (RICLASS_OWNS_M_TBL_P(obj)) {
|
||||||
@ -2172,8 +2256,8 @@ rb_obj_memsize_of(VALUE obj)
|
|||||||
size += rb_id_table_memsize(RCLASS_M_TBL(obj));
|
size += rb_id_table_memsize(RCLASS_M_TBL(obj));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (RCLASS_CC_TBL(obj)) {
|
if (RCLASS_WRITABLE_CC_TBL(obj)) {
|
||||||
size += cc_table_memsize(RCLASS_CC_TBL(obj));
|
size += cc_table_memsize(RCLASS_WRITABLE_CC_TBL(obj));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case T_STRING:
|
case T_STRING:
|
||||||
@ -2634,6 +2718,86 @@ mark_m_tbl(void *objspace, struct rb_id_table *tbl)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum rb_id_table_iterator_result
|
||||||
|
mark_const_entry_i(VALUE value, void *objspace)
|
||||||
|
{
|
||||||
|
const rb_const_entry_t *ce = (const rb_const_entry_t *)value;
|
||||||
|
|
||||||
|
gc_mark_internal(ce->value);
|
||||||
|
gc_mark_internal(ce->file);
|
||||||
|
return ID_TABLE_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mark_const_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl)
|
||||||
|
{
|
||||||
|
if (!tbl) return;
|
||||||
|
rb_id_table_foreach_values(tbl, mark_const_entry_i, objspace);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct mark_cc_entry_args {
|
||||||
|
rb_objspace_t *objspace;
|
||||||
|
VALUE klass;
|
||||||
|
};
|
||||||
|
|
||||||
|
static enum rb_id_table_iterator_result
|
||||||
|
mark_cc_entry_i(ID id, VALUE ccs_ptr, void *data)
|
||||||
|
{
|
||||||
|
struct mark_cc_entry_args *args = (struct mark_cc_entry_args *)data;
|
||||||
|
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
|
||||||
|
|
||||||
|
VM_ASSERT(vm_ccs_p(ccs));
|
||||||
|
VM_ASSERT(id == ccs->cme->called_id);
|
||||||
|
|
||||||
|
if (METHOD_ENTRY_INVALIDATED(ccs->cme)) {
|
||||||
|
rb_vm_ccs_free(ccs);
|
||||||
|
return ID_TABLE_DELETE;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
gc_mark_internal((VALUE)ccs->cme);
|
||||||
|
|
||||||
|
for (int i=0; i<ccs->len; i++) {
|
||||||
|
VM_ASSERT(args->klass == ccs->entries[i].cc->klass);
|
||||||
|
VM_ASSERT(vm_cc_check_cme(ccs->entries[i].cc, ccs->cme));
|
||||||
|
|
||||||
|
gc_mark_internal((VALUE)ccs->entries[i].cc);
|
||||||
|
}
|
||||||
|
return ID_TABLE_CONTINUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mark_cc_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl, VALUE klass)
|
||||||
|
{
|
||||||
|
struct mark_cc_entry_args args;
|
||||||
|
|
||||||
|
if (!tbl) return;
|
||||||
|
|
||||||
|
args.objspace = objspace;
|
||||||
|
args.klass = klass;
|
||||||
|
rb_id_table_foreach(tbl, mark_cc_entry_i, (void *)&args);
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum rb_id_table_iterator_result
|
||||||
|
mark_cvc_tbl_i(VALUE cvc_entry, void *objspace)
|
||||||
|
{
|
||||||
|
struct rb_cvar_class_tbl_entry *entry;
|
||||||
|
|
||||||
|
entry = (struct rb_cvar_class_tbl_entry *)cvc_entry;
|
||||||
|
|
||||||
|
RUBY_ASSERT(entry->cref == 0 || (BUILTIN_TYPE((VALUE)entry->cref) == T_IMEMO && IMEMO_TYPE_P(entry->cref, imemo_cref)));
|
||||||
|
gc_mark_internal((VALUE)entry->cref);
|
||||||
|
|
||||||
|
return ID_TABLE_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
mark_cvc_tbl(rb_objspace_t *objspace, struct rb_id_table *tbl)
|
||||||
|
{
|
||||||
|
if (!tbl) return;
|
||||||
|
rb_id_table_foreach_values(tbl, mark_cvc_tbl_i, objspace);
|
||||||
|
}
|
||||||
|
|
||||||
#if STACK_GROW_DIRECTION < 0
|
#if STACK_GROW_DIRECTION < 0
|
||||||
#define GET_STACK_BOUNDS(start, end, appendix) ((start) = STACK_END, (end) = STACK_START)
|
#define GET_STACK_BOUNDS(start, end, appendix) ((start) = STACK_END, (end) = STACK_START)
|
||||||
#elif STACK_GROW_DIRECTION > 0
|
#elif STACK_GROW_DIRECTION > 0
|
||||||
@ -2796,45 +2960,12 @@ rb_mark_tbl_no_pin(st_table *tbl)
|
|||||||
gc_mark_tbl_no_pin(tbl);
|
gc_mark_tbl_no_pin(tbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum rb_id_table_iterator_result
|
|
||||||
mark_cvc_tbl_i(VALUE cvc_entry, void *objspace)
|
|
||||||
{
|
|
||||||
struct rb_cvar_class_tbl_entry *entry;
|
|
||||||
|
|
||||||
entry = (struct rb_cvar_class_tbl_entry *)cvc_entry;
|
|
||||||
|
|
||||||
RUBY_ASSERT(entry->cref == 0 || (BUILTIN_TYPE((VALUE)entry->cref) == T_IMEMO && IMEMO_TYPE_P(entry->cref, imemo_cref)));
|
|
||||||
gc_mark_internal((VALUE)entry->cref);
|
|
||||||
|
|
||||||
return ID_TABLE_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
mark_cvc_tbl(void *objspace, VALUE klass)
|
|
||||||
{
|
|
||||||
struct rb_id_table *tbl = RCLASS_CVC_TBL(klass);
|
|
||||||
if (tbl) {
|
|
||||||
rb_id_table_foreach_values(tbl, mark_cvc_tbl_i, objspace);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
gc_declarative_marking_p(const rb_data_type_t *type)
|
gc_declarative_marking_p(const rb_data_type_t *type)
|
||||||
{
|
{
|
||||||
return (type->flags & RUBY_TYPED_DECL_MARKING) != 0;
|
return (type->flags & RUBY_TYPED_DECL_MARKING) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum rb_id_table_iterator_result
|
|
||||||
mark_const_table_i(VALUE value, void *objspace)
|
|
||||||
{
|
|
||||||
const rb_const_entry_t *ce = (const rb_const_entry_t *)value;
|
|
||||||
|
|
||||||
gc_mark_internal(ce->value);
|
|
||||||
gc_mark_internal(ce->file);
|
|
||||||
|
|
||||||
return ID_TABLE_CONTINUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_gc_mark_roots(void *objspace, const char **categoryp)
|
rb_gc_mark_roots(void *objspace, const char **categoryp)
|
||||||
{
|
{
|
||||||
@ -2875,11 +3006,62 @@ rb_gc_mark_roots(void *objspace, const char **categoryp)
|
|||||||
#undef MARK_CHECKPOINT
|
#undef MARK_CHECKPOINT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct gc_mark_classext_foreach_arg {
|
||||||
|
rb_objspace_t *objspace;
|
||||||
|
VALUE obj;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
gc_mark_classext_module(rb_classext_t *ext, bool prime, VALUE namespace, void *arg)
|
||||||
|
{
|
||||||
|
struct gc_mark_classext_foreach_arg *foreach_arg = (struct gc_mark_classext_foreach_arg *)arg;
|
||||||
|
rb_objspace_t *objspace = foreach_arg->objspace;
|
||||||
|
VALUE obj = foreach_arg->obj;
|
||||||
|
|
||||||
|
if (RCLASSEXT_SUPER(ext)) {
|
||||||
|
gc_mark_internal(RCLASSEXT_SUPER(ext));
|
||||||
|
}
|
||||||
|
mark_m_tbl(objspace, RCLASSEXT_M_TBL(ext));
|
||||||
|
if (rb_shape_obj_too_complex_p(obj)) {
|
||||||
|
gc_mark_tbl_no_pin((st_table *)RCLASSEXT_FIELDS(ext));
|
||||||
|
// for the case ELSE is written in rb_gc_mark_children() because it's per RClass, not classext
|
||||||
|
}
|
||||||
|
if (!RCLASSEXT_SHARED_CONST_TBL(ext) && RCLASSEXT_CONST_TBL(ext)) {
|
||||||
|
mark_const_tbl(objspace, RCLASSEXT_CONST_TBL(ext));
|
||||||
|
}
|
||||||
|
mark_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
|
||||||
|
mark_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext), obj);
|
||||||
|
mark_cvc_tbl(objspace, RCLASSEXT_CVC_TBL(ext));
|
||||||
|
gc_mark_internal(RCLASSEXT_CLASSPATH(ext));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
gc_mark_classext_iclass(rb_classext_t *ext, bool prime, VALUE namespace, void *arg)
|
||||||
|
{
|
||||||
|
struct gc_mark_classext_foreach_arg *foreach_arg = (struct gc_mark_classext_foreach_arg *)arg;
|
||||||
|
rb_objspace_t *objspace = foreach_arg->objspace;
|
||||||
|
VALUE iclass = foreach_arg->obj;
|
||||||
|
|
||||||
|
if (RCLASSEXT_SUPER(ext)) {
|
||||||
|
gc_mark_internal(RCLASSEXT_SUPER(ext));
|
||||||
|
}
|
||||||
|
if (RCLASSEXT_ICLASS_IS_ORIGIN(ext) && !RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(ext)) {
|
||||||
|
mark_m_tbl(objspace, RCLASSEXT_M_TBL(ext));
|
||||||
|
}
|
||||||
|
if (RCLASSEXT_INCLUDER(ext)) {
|
||||||
|
gc_mark_internal(RCLASSEXT_INCLUDER(ext));
|
||||||
|
}
|
||||||
|
mark_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
|
||||||
|
mark_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext), iclass);
|
||||||
|
}
|
||||||
|
|
||||||
#define TYPED_DATA_REFS_OFFSET_LIST(d) (size_t *)(uintptr_t)RTYPEDDATA_TYPE(d)->function.dmark
|
#define TYPED_DATA_REFS_OFFSET_LIST(d) (size_t *)(uintptr_t)RTYPEDDATA_TYPE(d)->function.dmark
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_gc_mark_children(void *objspace, VALUE obj)
|
rb_gc_mark_children(void *objspace, VALUE obj)
|
||||||
{
|
{
|
||||||
|
struct gc_mark_classext_foreach_arg foreach_args;
|
||||||
|
|
||||||
if (FL_TEST_RAW(obj, FL_EXIVAR)) {
|
if (FL_TEST_RAW(obj, FL_EXIVAR)) {
|
||||||
rb_mark_generic_ivar(obj);
|
rb_mark_generic_ivar(obj);
|
||||||
}
|
}
|
||||||
@ -2920,42 +3102,21 @@ rb_gc_mark_children(void *objspace, VALUE obj)
|
|||||||
}
|
}
|
||||||
// Continue to the shared T_CLASS/T_MODULE
|
// Continue to the shared T_CLASS/T_MODULE
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
if (RCLASS_SUPER(obj)) {
|
foreach_args.objspace = objspace;
|
||||||
gc_mark_internal(RCLASS_SUPER(obj));
|
foreach_args.obj = obj;
|
||||||
}
|
rb_class_classext_foreach(obj, gc_mark_classext_module, (void *)&foreach_args);
|
||||||
|
|
||||||
mark_m_tbl(objspace, RCLASS_M_TBL(obj));
|
if (!rb_shape_obj_too_complex_p(obj)) {
|
||||||
mark_cvc_tbl(objspace, obj);
|
|
||||||
rb_cc_table_mark(obj);
|
|
||||||
if (rb_shape_obj_too_complex_p(obj)) {
|
|
||||||
gc_mark_tbl_no_pin((st_table *)RCLASS_FIELDS(obj));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (attr_index_t i = 0; i < RCLASS_FIELDS_COUNT(obj); i++) {
|
for (attr_index_t i = 0; i < RCLASS_FIELDS_COUNT(obj); i++) {
|
||||||
gc_mark_internal(RCLASS_FIELDS(obj)[i]);
|
gc_mark_internal(RCLASS_PRIME_FIELDS(obj)[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (RCLASS_CONST_TBL(obj)) {
|
|
||||||
rb_id_table_foreach_values(RCLASS_CONST_TBL(obj), mark_const_table_i, objspace);
|
|
||||||
}
|
|
||||||
|
|
||||||
gc_mark_internal(RCLASS_EXT(obj)->classpath);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_ICLASS:
|
case T_ICLASS:
|
||||||
if (RICLASS_OWNS_M_TBL_P(obj)) {
|
foreach_args.objspace = objspace;
|
||||||
mark_m_tbl(objspace, RCLASS_M_TBL(obj));
|
foreach_args.obj = obj;
|
||||||
}
|
rb_class_classext_foreach(obj, gc_mark_classext_iclass, (void *)&foreach_args);
|
||||||
if (RCLASS_SUPER(obj)) {
|
|
||||||
gc_mark_internal(RCLASS_SUPER(obj));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (RCLASS_INCLUDER(obj)) {
|
|
||||||
gc_mark_internal(RCLASS_INCLUDER(obj));
|
|
||||||
}
|
|
||||||
mark_m_tbl(objspace, RCLASS_CALLABLE_M_TBL(obj));
|
|
||||||
rb_cc_table_mark(obj);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_ARRAY:
|
case T_ARRAY:
|
||||||
@ -3031,8 +3192,8 @@ rb_gc_mark_children(void *objspace, VALUE obj)
|
|||||||
VALUE klass = RBASIC_CLASS(obj);
|
VALUE klass = RBASIC_CLASS(obj);
|
||||||
|
|
||||||
// Increment max_iv_count if applicable, used to determine size pool allocation
|
// Increment max_iv_count if applicable, used to determine size pool allocation
|
||||||
if (RCLASS_EXT(klass)->max_iv_count < fields_count) {
|
if (RCLASS_MAX_IV_COUNT(klass) < fields_count) {
|
||||||
RCLASS_EXT(klass)->max_iv_count = fields_count;
|
RCLASS_WRITE_MAX_IV_COUNT(klass, fields_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3482,12 +3643,10 @@ update_cc_tbl_i(VALUE ccs_ptr, void *objspace)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_cc_tbl(void *objspace, VALUE klass)
|
update_cc_tbl(void *objspace, struct rb_id_table *tbl)
|
||||||
{
|
{
|
||||||
struct rb_id_table *tbl = RCLASS_CC_TBL(klass);
|
if (!tbl) return;
|
||||||
if (tbl) {
|
rb_id_table_foreach_values(tbl, update_cc_tbl_i, objspace);
|
||||||
rb_id_table_foreach_values(tbl, update_cc_tbl_i, objspace);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum rb_id_table_iterator_result
|
static enum rb_id_table_iterator_result
|
||||||
@ -3507,16 +3666,14 @@ update_cvc_tbl_i(VALUE cvc_entry, void *objspace)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_cvc_tbl(void *objspace, VALUE klass)
|
update_cvc_tbl(void *objspace, struct rb_id_table *tbl)
|
||||||
{
|
{
|
||||||
struct rb_id_table *tbl = RCLASS_CVC_TBL(klass);
|
if (!tbl) return;
|
||||||
if (tbl) {
|
rb_id_table_foreach_values(tbl, update_cvc_tbl_i, objspace);
|
||||||
rb_id_table_foreach_values(tbl, update_cvc_tbl_i, objspace);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static enum rb_id_table_iterator_result
|
static enum rb_id_table_iterator_result
|
||||||
update_const_table(VALUE value, void *objspace)
|
update_const_tbl_i(VALUE value, void *objspace)
|
||||||
{
|
{
|
||||||
rb_const_entry_t *ce = (rb_const_entry_t *)value;
|
rb_const_entry_t *ce = (rb_const_entry_t *)value;
|
||||||
|
|
||||||
@ -3535,35 +3692,93 @@ static void
|
|||||||
update_const_tbl(void *objspace, struct rb_id_table *tbl)
|
update_const_tbl(void *objspace, struct rb_id_table *tbl)
|
||||||
{
|
{
|
||||||
if (!tbl) return;
|
if (!tbl) return;
|
||||||
rb_id_table_foreach_values(tbl, update_const_table, objspace);
|
rb_id_table_foreach_values(tbl, update_const_tbl_i, objspace);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_subclass_entries(void *objspace, rb_subclass_entry_t *entry)
|
update_subclasses(void *objspace, rb_classext_t *ext)
|
||||||
{
|
{
|
||||||
|
rb_subclass_entry_t *entry;
|
||||||
|
rb_subclass_anchor_t *anchor = RCLASSEXT_SUBCLASSES(ext);
|
||||||
|
if (!anchor) return;
|
||||||
|
entry = anchor->head;
|
||||||
while (entry) {
|
while (entry) {
|
||||||
UPDATE_IF_MOVED(objspace, entry->klass);
|
if (entry->klass)
|
||||||
|
UPDATE_IF_MOVED(objspace, entry->klass);
|
||||||
entry = entry->next;
|
entry = entry->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_class_ext(void *objspace, rb_classext_t *ext)
|
update_superclasses(rb_objspace_t *objspace, rb_classext_t *ext)
|
||||||
{
|
{
|
||||||
UPDATE_IF_MOVED(objspace, ext->origin_);
|
size_t array_size = RCLASSEXT_SUPERCLASS_DEPTH(ext);
|
||||||
UPDATE_IF_MOVED(objspace, ext->includer);
|
if (RCLASSEXT_SUPERCLASSES_OWNER(ext)) {
|
||||||
UPDATE_IF_MOVED(objspace, ext->refined_class);
|
if (RCLASSEXT_SUPERCLASSES_WITH_SELF(ext))
|
||||||
update_subclass_entries(objspace, ext->subclasses);
|
array_size += 1;
|
||||||
|
for (size_t i = 0; i < array_size; i++) {
|
||||||
|
UPDATE_IF_MOVED(objspace, RCLASSEXT_SUPERCLASSES(ext)[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
update_superclasses(void *objspace, VALUE obj)
|
update_classext_values(rb_objspace_t *objspace, rb_classext_t *ext)
|
||||||
{
|
{
|
||||||
if (FL_TEST_RAW(obj, RCLASS_SUPERCLASSES_INCLUDE_SELF)) {
|
UPDATE_IF_MOVED(objspace, RCLASSEXT_ORIGIN(ext));
|
||||||
for (size_t i = 0; i < RCLASS_SUPERCLASS_DEPTH(obj) + 1; i++) {
|
UPDATE_IF_MOVED(objspace, RCLASSEXT_REFINED_CLASS(ext));
|
||||||
UPDATE_IF_MOVED(objspace, RCLASS_SUPERCLASSES(obj)[i]);
|
UPDATE_IF_MOVED(objspace, RCLASSEXT_INCLUDER(ext));
|
||||||
|
UPDATE_IF_MOVED(objspace, RCLASSEXT_CLASSPATH(ext));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_classext(rb_classext_t *ext, bool is_prime, VALUE namespace, void *arg)
|
||||||
|
{
|
||||||
|
struct classext_foreach_args *args = (struct classext_foreach_args *)arg;
|
||||||
|
VALUE klass = args->klass;
|
||||||
|
rb_objspace_t *objspace = args->objspace;
|
||||||
|
|
||||||
|
if (RCLASSEXT_SUPER(ext)) {
|
||||||
|
UPDATE_IF_MOVED(objspace, RCLASSEXT_SUPER(ext));
|
||||||
|
}
|
||||||
|
|
||||||
|
update_m_tbl(objspace, RCLASSEXT_M_TBL(ext));
|
||||||
|
|
||||||
|
if (args->obj_too_complex) {
|
||||||
|
gc_ref_update_table_values_only((st_table *)RCLASSEXT_FIELDS(ext));
|
||||||
|
} else {
|
||||||
|
// Classext is not copied in this case
|
||||||
|
for (attr_index_t i = 0; i < RCLASS_FIELDS_COUNT(klass); i++) {
|
||||||
|
UPDATE_IF_MOVED(objspace, RCLASSEXT_FIELDS(RCLASS_EXT(klass))[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!RCLASSEXT_SHARED_CONST_TBL(ext)) {
|
||||||
|
update_const_tbl(objspace, RCLASSEXT_CONST_TBL(ext));
|
||||||
|
}
|
||||||
|
update_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext));
|
||||||
|
update_cvc_tbl(objspace, RCLASSEXT_CVC_TBL(ext));
|
||||||
|
update_superclasses(objspace, ext);
|
||||||
|
update_subclasses(objspace, ext);
|
||||||
|
|
||||||
|
update_classext_values(objspace, ext);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
update_iclass_classext(rb_classext_t *ext, bool is_prime, VALUE namespace, void *arg)
|
||||||
|
{
|
||||||
|
struct classext_foreach_args *args = (struct classext_foreach_args *)arg;
|
||||||
|
rb_objspace_t *objspace = args->objspace;
|
||||||
|
|
||||||
|
if (RCLASSEXT_SUPER(ext)) {
|
||||||
|
UPDATE_IF_MOVED(objspace, RCLASSEXT_SUPER(ext));
|
||||||
|
}
|
||||||
|
update_m_tbl(objspace, RCLASSEXT_M_TBL(ext));
|
||||||
|
update_m_tbl(objspace, RCLASSEXT_CALLABLE_M_TBL(ext));
|
||||||
|
update_cc_tbl(objspace, RCLASSEXT_CC_TBL(ext));
|
||||||
|
update_subclasses(objspace, ext);
|
||||||
|
|
||||||
|
update_classext_values(objspace, ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern rb_symbols_t ruby_global_symbols;
|
extern rb_symbols_t ruby_global_symbols;
|
||||||
@ -3884,6 +4099,8 @@ rb_gc_update_vm_references(void *objspace)
|
|||||||
void
|
void
|
||||||
rb_gc_update_object_references(void *objspace, VALUE obj)
|
rb_gc_update_object_references(void *objspace, VALUE obj)
|
||||||
{
|
{
|
||||||
|
struct classext_foreach_args args;
|
||||||
|
|
||||||
switch (BUILTIN_TYPE(obj)) {
|
switch (BUILTIN_TYPE(obj)) {
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
if (FL_TEST_RAW(obj, FL_SINGLETON)) {
|
if (FL_TEST_RAW(obj, FL_SINGLETON)) {
|
||||||
@ -3891,39 +4108,15 @@ rb_gc_update_object_references(void *objspace, VALUE obj)
|
|||||||
}
|
}
|
||||||
// Continue to the shared T_CLASS/T_MODULE
|
// Continue to the shared T_CLASS/T_MODULE
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
if (RCLASS_SUPER((VALUE)obj)) {
|
args.klass = obj;
|
||||||
UPDATE_IF_MOVED(objspace, RCLASS(obj)->super);
|
args.obj_too_complex = rb_shape_obj_too_complex_p(obj);
|
||||||
}
|
args.objspace = objspace;
|
||||||
update_m_tbl(objspace, RCLASS_M_TBL(obj));
|
rb_class_classext_foreach(obj, update_classext, (void *)&args);
|
||||||
update_cc_tbl(objspace, obj);
|
|
||||||
update_cvc_tbl(objspace, obj);
|
|
||||||
update_superclasses(objspace, obj);
|
|
||||||
|
|
||||||
if (rb_shape_obj_too_complex_p(obj)) {
|
|
||||||
gc_ref_update_table_values_only(RCLASS_FIELDS_HASH(obj));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
for (attr_index_t i = 0; i < RCLASS_FIELDS_COUNT(obj); i++) {
|
|
||||||
UPDATE_IF_MOVED(objspace, RCLASS_FIELDS(obj)[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
update_class_ext(objspace, RCLASS_EXT(obj));
|
|
||||||
update_const_tbl(objspace, RCLASS_CONST_TBL(obj));
|
|
||||||
|
|
||||||
UPDATE_IF_MOVED(objspace, RCLASS_EXT(obj)->classpath);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_ICLASS:
|
case T_ICLASS:
|
||||||
if (RICLASS_OWNS_M_TBL_P(obj)) {
|
args.objspace = objspace;
|
||||||
update_m_tbl(objspace, RCLASS_M_TBL(obj));
|
rb_class_classext_foreach(obj, update_iclass_classext, (void *)&args);
|
||||||
}
|
|
||||||
if (RCLASS_SUPER((VALUE)obj)) {
|
|
||||||
UPDATE_IF_MOVED(objspace, RCLASS(obj)->super);
|
|
||||||
}
|
|
||||||
update_class_ext(objspace, RCLASS_EXT(obj));
|
|
||||||
update_m_tbl(objspace, RCLASS_CALLABLE_M_TBL(obj));
|
|
||||||
update_cc_tbl(objspace, obj);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_IMEMO:
|
case T_IMEMO:
|
||||||
|
19
imemo.c
19
imemo.c
@ -170,13 +170,14 @@ rb_imemo_memsize(VALUE obj)
|
|||||||
static enum rb_id_table_iterator_result
|
static enum rb_id_table_iterator_result
|
||||||
cc_table_mark_i(VALUE ccs_ptr, void *data)
|
cc_table_mark_i(VALUE ccs_ptr, void *data)
|
||||||
{
|
{
|
||||||
|
// looks duplicate to mark_cc_entry_i (gc.c)
|
||||||
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
|
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_ptr;
|
||||||
VM_ASSERT(vm_ccs_p(ccs));
|
VM_ASSERT(vm_ccs_p(ccs));
|
||||||
#if VM_CHECK_MODE > 0
|
#if VM_CHECK_MODE > 0
|
||||||
VALUE klass = (VALUE)data;
|
VALUE klass = (VALUE)data;
|
||||||
|
|
||||||
VALUE lookup_val;
|
VALUE lookup_val;
|
||||||
VM_ASSERT(rb_id_table_lookup(RCLASS_CC_TBL(klass), ccs->cme->called_id, &lookup_val));
|
VM_ASSERT(rb_id_table_lookup(RCLASS_WRITABLE_CC_TBL(klass), ccs->cme->called_id, &lookup_val));
|
||||||
VM_ASSERT(lookup_val == ccs_ptr);
|
VM_ASSERT(lookup_val == ccs_ptr);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -200,7 +201,8 @@ cc_table_mark_i(VALUE ccs_ptr, void *data)
|
|||||||
void
|
void
|
||||||
rb_cc_table_mark(VALUE klass)
|
rb_cc_table_mark(VALUE klass)
|
||||||
{
|
{
|
||||||
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
|
// TODO: delete this (and cc_table_mark_i) if it's ok
|
||||||
|
struct rb_id_table *cc_tbl = RCLASS_WRITABLE_CC_TBL(klass);
|
||||||
if (cc_tbl) {
|
if (cc_tbl) {
|
||||||
rb_id_table_foreach_values(cc_tbl, cc_table_mark_i, (void *)klass);
|
rb_id_table_foreach_values(cc_tbl, cc_table_mark_i, (void *)klass);
|
||||||
}
|
}
|
||||||
@ -492,7 +494,10 @@ cc_table_free_i(VALUE ccs_ptr, void *data)
|
|||||||
void
|
void
|
||||||
rb_cc_table_free(VALUE klass)
|
rb_cc_table_free(VALUE klass)
|
||||||
{
|
{
|
||||||
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
|
// This can be called and work well only for IClass
|
||||||
|
// And classext_iclass_free uses rb_cc_tbl_free now.
|
||||||
|
// TODO: remove this if it's ok
|
||||||
|
struct rb_id_table *cc_tbl = RCLASS_WRITABLE_CC_TBL(klass);
|
||||||
|
|
||||||
if (cc_tbl) {
|
if (cc_tbl) {
|
||||||
rb_id_table_foreach_values(cc_tbl, cc_table_free_i, (void *)klass);
|
rb_id_table_foreach_values(cc_tbl, cc_table_free_i, (void *)klass);
|
||||||
@ -500,6 +505,14 @@ rb_cc_table_free(VALUE klass)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_cc_tbl_free(struct rb_id_table *cc_tbl, VALUE klass)
|
||||||
|
{
|
||||||
|
if (!cc_tbl) return;
|
||||||
|
rb_id_table_foreach_values(cc_tbl, cc_table_free_i, (void *)klass);
|
||||||
|
rb_id_table_free(cc_tbl);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_imemo_free(VALUE obj)
|
rb_imemo_free(VALUE obj)
|
||||||
{
|
{
|
||||||
|
@ -84,6 +84,8 @@ RUBY_EXTERN VALUE rb_cMethod; /**< `Method` class. */
|
|||||||
RUBY_EXTERN VALUE rb_cModule; /**< `Module` class. */
|
RUBY_EXTERN VALUE rb_cModule; /**< `Module` class. */
|
||||||
RUBY_EXTERN VALUE rb_cRefinement; /**< `Refinement` class. */
|
RUBY_EXTERN VALUE rb_cRefinement; /**< `Refinement` class. */
|
||||||
RUBY_EXTERN VALUE rb_cNameErrorMesg; /**< `NameError::Message` class. */
|
RUBY_EXTERN VALUE rb_cNameErrorMesg; /**< `NameError::Message` class. */
|
||||||
|
RUBY_EXTERN VALUE rb_cNamespace; /**< `Namespace` class. */
|
||||||
|
RUBY_EXTERN VALUE rb_mNamespaceRefiner; /**< `Namespace::Refiner` module. */
|
||||||
RUBY_EXTERN VALUE rb_cNilClass; /**< `NilClass` class. */
|
RUBY_EXTERN VALUE rb_cNilClass; /**< `NilClass` class. */
|
||||||
RUBY_EXTERN VALUE rb_cNumeric; /**< `Numeric` class. */
|
RUBY_EXTERN VALUE rb_cNumeric; /**< `Numeric` class. */
|
||||||
RUBY_EXTERN VALUE rb_cProc; /**< `Proc` class. */
|
RUBY_EXTERN VALUE rb_cProc; /**< `Proc` class. */
|
||||||
|
1
inits.c
1
inits.c
@ -77,6 +77,7 @@ rb_call_inits(void)
|
|||||||
CALL(Prism);
|
CALL(Prism);
|
||||||
CALL(unicode_version);
|
CALL(unicode_version);
|
||||||
CALL(Set);
|
CALL(Set);
|
||||||
|
CALL(Namespace);
|
||||||
|
|
||||||
// enable builtin loading
|
// enable builtin loading
|
||||||
CALL(builtin);
|
CALL(builtin);
|
||||||
|
660
internal/class.h
660
internal/class.h
@ -10,6 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "id.h"
|
#include "id.h"
|
||||||
#include "id_table.h" /* for struct rb_id_table */
|
#include "id_table.h" /* for struct rb_id_table */
|
||||||
|
#include "internal/namespace.h" /* for rb_current_namespace */
|
||||||
#include "internal/serial.h" /* for rb_serial_t */
|
#include "internal/serial.h" /* for rb_serial_t */
|
||||||
#include "internal/static_assert.h"
|
#include "internal/static_assert.h"
|
||||||
#include "internal/variable.h" /* for rb_class_ivar_set */
|
#include "internal/variable.h" /* for rb_class_ivar_set */
|
||||||
@ -26,6 +27,41 @@
|
|||||||
# undef RCLASS_SUPER
|
# undef RCLASS_SUPER
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct rb_ns_subclasses {
|
||||||
|
long refcount;
|
||||||
|
struct st_table *tbl;
|
||||||
|
};
|
||||||
|
typedef struct rb_ns_subclasses rb_ns_subclasses_t;
|
||||||
|
|
||||||
|
static inline long
|
||||||
|
rb_ns_subclasses_ref_count(rb_ns_subclasses_t *ns_sub)
|
||||||
|
{
|
||||||
|
return ns_sub->refcount;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline rb_ns_subclasses_t *
|
||||||
|
rb_ns_subclasses_ref_inc(rb_ns_subclasses_t *ns_sub)
|
||||||
|
{
|
||||||
|
ns_sub->refcount++;
|
||||||
|
return ns_sub;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
rb_ns_subclasses_ref_dec(rb_ns_subclasses_t *ns_sub)
|
||||||
|
{
|
||||||
|
ns_sub->refcount--;
|
||||||
|
if (ns_sub->refcount == 0) {
|
||||||
|
st_free_table(ns_sub->tbl);
|
||||||
|
xfree(ns_sub);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct rb_subclass_anchor {
|
||||||
|
rb_ns_subclasses_t *ns_subclasses;
|
||||||
|
struct rb_subclass_entry *head;
|
||||||
|
};
|
||||||
|
typedef struct rb_subclass_anchor rb_subclass_anchor_t;
|
||||||
|
|
||||||
struct rb_subclass_entry {
|
struct rb_subclass_entry {
|
||||||
VALUE klass;
|
VALUE klass;
|
||||||
struct rb_subclass_entry *next;
|
struct rb_subclass_entry *next;
|
||||||
@ -41,21 +77,36 @@ struct rb_cvar_class_tbl_entry {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct rb_classext_struct {
|
struct rb_classext_struct {
|
||||||
|
const rb_namespace_t *ns;
|
||||||
|
VALUE super;
|
||||||
VALUE *fields; // Fields are either ivar or other internal properties stored inline
|
VALUE *fields; // Fields are either ivar or other internal properties stored inline
|
||||||
|
struct rb_id_table *m_tbl;
|
||||||
struct rb_id_table *const_tbl;
|
struct rb_id_table *const_tbl;
|
||||||
struct rb_id_table *callable_m_tbl;
|
struct rb_id_table *callable_m_tbl;
|
||||||
struct rb_id_table *cc_tbl; /* ID -> [[ci1, cc1], [ci2, cc2] ...] */
|
struct rb_id_table *cc_tbl; /* ID -> [[ci1, cc1], [ci2, cc2] ...] */
|
||||||
struct rb_id_table *cvc_tbl;
|
struct rb_id_table *cvc_tbl;
|
||||||
size_t superclass_depth;
|
size_t superclass_depth;
|
||||||
VALUE *superclasses;
|
VALUE *superclasses;
|
||||||
struct rb_subclass_entry *subclasses;
|
|
||||||
struct rb_subclass_entry *subclass_entry;
|
|
||||||
/**
|
/**
|
||||||
* In the case that this is an `ICLASS`, `module_subclasses` points to the link
|
* The head of subclasses is a blank (w/o klass) entry to be referred from anchor (and be never deleted).
|
||||||
|
* (anchor -> head -> 1st-entry)
|
||||||
|
*/
|
||||||
|
struct rb_subclass_anchor *subclasses;
|
||||||
|
/**
|
||||||
|
* The `ns_super_subclasses` points the `ns_subclasses` struct to retreive the subclasses
|
||||||
|
* of the super class in a specific namespace.
|
||||||
|
* In compaction GCs, collecting a classext should trigger the deletion of a rb_subclass_entry
|
||||||
|
* from the super's subclasses. But it may be prevented by the read barrier.
|
||||||
|
* Fetching the super's subclasses for a ns is to avoid the read barrier in that process.
|
||||||
|
*/
|
||||||
|
rb_ns_subclasses_t *ns_super_subclasses;
|
||||||
|
/**
|
||||||
|
* In the case that this is an `ICLASS`, `ns_module_subclasses` points to the link
|
||||||
* in the module's `subclasses` list that indicates that the klass has been
|
* in the module's `subclasses` list that indicates that the klass has been
|
||||||
* included. Hopefully that makes sense.
|
* included. Hopefully that makes sense.
|
||||||
*/
|
*/
|
||||||
struct rb_subclass_entry *module_subclass_entry;
|
rb_ns_subclasses_t *ns_module_subclasses;
|
||||||
|
|
||||||
const VALUE origin_;
|
const VALUE origin_;
|
||||||
const VALUE refined_class;
|
const VALUE refined_class;
|
||||||
union {
|
union {
|
||||||
@ -71,6 +122,11 @@ struct rb_classext_struct {
|
|||||||
unsigned char variation_count;
|
unsigned char variation_count;
|
||||||
bool permanent_classpath : 1;
|
bool permanent_classpath : 1;
|
||||||
bool cloned : 1;
|
bool cloned : 1;
|
||||||
|
bool shared_const_tbl : 1;
|
||||||
|
bool iclass_is_origin : 1;
|
||||||
|
bool iclass_origin_shared_mtbl : 1;
|
||||||
|
bool superclasses_owner : 1;
|
||||||
|
bool superclasses_with_self : 1;
|
||||||
VALUE classpath;
|
VALUE classpath;
|
||||||
};
|
};
|
||||||
typedef struct rb_classext_struct rb_classext_t;
|
typedef struct rb_classext_struct rb_classext_t;
|
||||||
@ -79,46 +135,394 @@ STATIC_ASSERT(shape_max_variations, SHAPE_MAX_VARIATIONS < (1 << (sizeof(((rb_cl
|
|||||||
|
|
||||||
struct RClass {
|
struct RClass {
|
||||||
struct RBasic basic;
|
struct RBasic basic;
|
||||||
VALUE super;
|
st_table *ns_classext_tbl; // ns_object -> (rb_classext_t *)
|
||||||
struct rb_id_table *m_tbl;
|
bool prime_classext_readable : 1;
|
||||||
|
bool prime_classext_writable : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Assert that classes can be embedded in heaps[2] (which has 160B slot size)
|
/** TODO: Update or remove this assertion
|
||||||
STATIC_ASSERT(sizeof_rb_classext_t, sizeof(struct RClass) + sizeof(rb_classext_t) <= 4 * RVALUE_SIZE);
|
* // Assert that classes can be embedded in heaps[2] (which has 160B slot size)
|
||||||
|
* STATIC_ASSERT(sizeof_rb_classext_t, sizeof(struct RClass) + sizeof(rb_classext_t) <= 4 * RVALUE_SIZE);
|
||||||
|
*/
|
||||||
|
|
||||||
struct RClass_and_rb_classext_t {
|
struct RClass_and_rb_classext_t {
|
||||||
struct RClass rclass;
|
struct RClass rclass;
|
||||||
rb_classext_t classext;
|
rb_classext_t classext;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define RCLASS_PRIME_READABLE_P(obj) (RCLASS(obj)->prime_classext_readable)
|
||||||
|
#define RCLASS_PRIME_WRITABLE_P(obj) (RCLASS(obj)->prime_classext_writable)
|
||||||
|
|
||||||
|
static inline bool RCLASS_SINGLETON_P(VALUE klass);
|
||||||
|
|
||||||
|
static inline void RCLASS_SET_CLASSEXT_TABLE(VALUE obj, st_table *tbl);
|
||||||
|
static inline void RCLASS_SET_PRIME_CLASSEXT_READWRITE(VALUE obj, bool readable, bool writable);
|
||||||
|
|
||||||
#define RCLASS_EXT(c) (&((struct RClass_and_rb_classext_t*)(c))->classext)
|
#define RCLASS_EXT(c) (&((struct RClass_and_rb_classext_t*)(c))->classext)
|
||||||
#define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
|
#define RCLASS_EXT_PRIME_P(ext, c) (&((struct RClass_and_rb_classext_t*)(c))->classext == ext)
|
||||||
#define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
|
|
||||||
#define RCLASS_FIELDS(c) (RCLASS_EXT(c)->fields)
|
static inline rb_classext_t * RCLASS_EXT_READABLE_IN_NS(VALUE obj, const rb_namespace_t *ns);
|
||||||
#define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT(c)->callable_m_tbl)
|
static inline rb_classext_t * RCLASS_EXT_READABLE(VALUE obj);
|
||||||
#define RCLASS_CC_TBL(c) (RCLASS_EXT(c)->cc_tbl)
|
static inline rb_classext_t * RCLASS_EXT_WRITABLE_IN_NS(VALUE obj, const rb_namespace_t *ns);
|
||||||
#define RCLASS_CVC_TBL(c) (RCLASS_EXT(c)->cvc_tbl)
|
static inline rb_classext_t * RCLASS_EXT_WRITABLE(VALUE obj);
|
||||||
#define RCLASS_ORIGIN(c) (RCLASS_EXT(c)->origin_)
|
|
||||||
|
// Raw accessor
|
||||||
|
#define RCLASS_CLASSEXT_TBL(klass) (RCLASS(klass)->ns_classext_tbl)
|
||||||
|
|
||||||
|
#define RCLASSEXT_NS(ext) (ext->ns)
|
||||||
|
#define RCLASSEXT_SUPER(ext) (ext->super)
|
||||||
|
#define RCLASSEXT_FIELDS(ext) (ext->fields)
|
||||||
|
#define RCLASSEXT_M_TBL(ext) (ext->m_tbl)
|
||||||
|
#define RCLASSEXT_CONST_TBL(ext) (ext->const_tbl)
|
||||||
|
#define RCLASSEXT_CALLABLE_M_TBL(ext) (ext->callable_m_tbl)
|
||||||
|
#define RCLASSEXT_CC_TBL(ext) (ext->cc_tbl)
|
||||||
|
#define RCLASSEXT_CVC_TBL(ext) (ext->cvc_tbl)
|
||||||
|
#define RCLASSEXT_SUPERCLASS_DEPTH(ext) (ext->superclass_depth)
|
||||||
|
#define RCLASSEXT_SUPERCLASSES(ext) (ext->superclasses)
|
||||||
|
#define RCLASSEXT_SUBCLASSES(ext) (ext->subclasses)
|
||||||
|
#define RCLASSEXT_NS_SUPER_SUBCLASSES(ext) (ext->ns_super_subclasses)
|
||||||
|
#define RCLASSEXT_NS_MODULE_SUBCLASSES(ext) (ext->ns_module_subclasses)
|
||||||
|
#define RCLASSEXT_ORIGIN(ext) (ext->origin_)
|
||||||
|
#define RCLASSEXT_REFINED_CLASS(ext) (ext->refined_class)
|
||||||
|
// class.allocator/singleton_class.attached_object are not accessed directly via RCLASSEXT_*
|
||||||
|
#define RCLASSEXT_INCLUDER(ext) (ext->includer)
|
||||||
|
#define RCLASSEXT_MAX_IV_COUNT(ext) (ext->max_iv_count)
|
||||||
|
#define RCLASSEXT_VARIATION_COUNT(ext) (ext->variation_count)
|
||||||
|
#define RCLASSEXT_PERMANENT_CLASSPATH(ext) (ext->permanent_classpath)
|
||||||
|
#define RCLASSEXT_CLONED(ext) (ext->cloned)
|
||||||
|
#define RCLASSEXT_SHARED_CONST_TBL(ext) (ext->shared_const_tbl)
|
||||||
|
#define RCLASSEXT_ICLASS_IS_ORIGIN(ext) (ext->iclass_is_origin)
|
||||||
|
#define RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(ext) (ext->iclass_origin_shared_mtbl)
|
||||||
|
#define RCLASSEXT_SUPERCLASSES_OWNER(ext) (ext->superclasses_owner)
|
||||||
|
#define RCLASSEXT_SUPERCLASSES_WITH_SELF(ext) (ext->superclasses_with_self)
|
||||||
|
#define RCLASSEXT_CLASSPATH(ext) (ext->classpath)
|
||||||
|
|
||||||
|
static inline void RCLASSEXT_SET_ORIGIN(rb_classext_t *ext, VALUE klass, VALUE origin);
|
||||||
|
static inline void RCLASSEXT_SET_INCLUDER(rb_classext_t *ext, VALUE klass, VALUE includer);
|
||||||
|
|
||||||
|
/* Prime classext entry accessor for very specific reason */
|
||||||
|
#define RCLASS_PRIME_NS(c) (RCLASS_EXT(c)->ns)
|
||||||
|
// To invalidate CC by inserting&invalidating method entry into tables containing the target cme
|
||||||
|
// See clear_method_cache_by_id_in_class()
|
||||||
|
#define RCLASS_PRIME_FIELDS(c) (RCLASS_EXT(c)->fields)
|
||||||
|
#define RCLASS_PRIME_M_TBL(c) (RCLASS_EXT(c)->m_tbl)
|
||||||
|
#define RCLASS_PRIME_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
|
||||||
|
#define RCLASS_PRIME_CALLABLE_M_TBL(c) (RCLASS_EXT(c)->callable_m_tbl)
|
||||||
|
#define RCLASS_PRIME_CC_TBL(c) (RCLASS_EXT(c)->cc_tbl)
|
||||||
|
#define RCLASS_M_TBL_NOT_PRIME_P(c, tbl) (RCLASS_EXT(c)->m_tbl != tbl)
|
||||||
|
#define RCLASS_CALLABLE_M_TBL_NOT_PRIME_P(c, tbl) (RCLASS_EXT(c)->callable_m_tbl != tbl)
|
||||||
|
#define RCLASS_CC_TBL_NOT_PRIME_P(c, tbl) (RCLASS_EXT(c)->cc_tbl != tbl)
|
||||||
|
|
||||||
|
// Read accessor, regarding namespaces
|
||||||
|
#define RCLASS_SUPER(c) (RCLASS_EXT_READABLE(c)->super)
|
||||||
|
#define RCLASS_M_TBL(c) (RCLASS_EXT_READABLE(c)->m_tbl)
|
||||||
|
#define RCLASS_CONST_TBL(c) (RCLASS_EXT_READABLE(c)->const_tbl)
|
||||||
|
/*
|
||||||
|
* Both cc_tbl/callable_m_tbl are cache and always be changed when referreed,
|
||||||
|
* so always should be writable.
|
||||||
|
*/
|
||||||
|
// #define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT_READABLE(c)->callable_m_tbl)
|
||||||
|
// #define RCLASS_CC_TBL(c) (RCLASS_EXT_READABLE(c)->cc_tbl)
|
||||||
|
#define RCLASS_CVC_TBL(c) (RCLASS_EXT_READABLE(c)->cvc_tbl)
|
||||||
|
#define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT_READABLE(c)->superclass_depth)
|
||||||
|
#define RCLASS_SUPERCLASSES(c) (RCLASS_EXT_READABLE(c)->superclasses)
|
||||||
|
#define RCLASS_SUPERCLASSES_WITH_SELF_P(c) (RCLASS_EXT_READABLE(c)->superclasses_with_self)
|
||||||
|
#define RCLASS_SUBCLASSES_X(c) (RCLASS_EXT_READABLE(c)->subclasses)
|
||||||
|
#define RCLASS_SUBCLASSES_FIRST(c) (RCLASS_EXT_READABLE(c)->subclasses->head->next)
|
||||||
|
#define RCLASS_ORIGIN(c) (RCLASS_EXT_READABLE(c)->origin_)
|
||||||
|
#define RICLASS_IS_ORIGIN_P(c) (RCLASS_EXT_READABLE(c)->iclass_is_origin)
|
||||||
|
#define RCLASS_MAX_IV_COUNT(c) (RCLASS_EXT_READABLE(c)->max_iv_count)
|
||||||
|
#define RCLASS_VARIATION_COUNT(c) (RCLASS_EXT_READABLE(c)->variation_count)
|
||||||
|
#define RCLASS_PERMANENT_CLASSPATH_P(c) (RCLASS_EXT_READABLE(c)->permanent_classpath)
|
||||||
|
#define RCLASS_CLONED_P(c) (RCLASS_EXT_READABLE(c)->cloned)
|
||||||
|
#define RCLASS_CLASSPATH(c) (RCLASS_EXT_READABLE(c)->classpath)
|
||||||
|
|
||||||
|
// namespaces don't make changes on these refined_class/attached_object/includer
|
||||||
#define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class)
|
#define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class)
|
||||||
#define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer)
|
|
||||||
#define RCLASS_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->subclass_entry)
|
|
||||||
#define RCLASS_MODULE_SUBCLASS_ENTRY(c) (RCLASS_EXT(c)->module_subclass_entry)
|
|
||||||
#define RCLASS_SUBCLASSES(c) (RCLASS_EXT(c)->subclasses)
|
|
||||||
#define RCLASS_SUPERCLASS_DEPTH(c) (RCLASS_EXT(c)->superclass_depth)
|
|
||||||
#define RCLASS_SUPERCLASSES(c) (RCLASS_EXT(c)->superclasses)
|
|
||||||
#define RCLASS_ATTACHED_OBJECT(c) (RCLASS_EXT(c)->as.singleton_class.attached_object)
|
#define RCLASS_ATTACHED_OBJECT(c) (RCLASS_EXT(c)->as.singleton_class.attached_object)
|
||||||
|
#define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer)
|
||||||
|
|
||||||
|
// Writable classext entries (instead of RCLASS_SET_*) because member data will be operated directly
|
||||||
|
#define RCLASS_WRITABLE_M_TBL(c) (RCLASS_EXT_WRITABLE(c)->m_tbl)
|
||||||
|
#define RCLASS_WRITABLE_CONST_TBL(c) (RCLASS_EXT_WRITABLE(c)->const_tbl)
|
||||||
|
#define RCLASS_WRITABLE_CALLABLE_M_TBL(c) (RCLASS_EXT_WRITABLE(c)->callable_m_tbl)
|
||||||
|
#define RCLASS_WRITABLE_CC_TBL(c) (RCLASS_EXT_WRITABLE(c)->cc_tbl)
|
||||||
|
#define RCLASS_WRITABLE_CVC_TBL(c) (RCLASS_EXT_WRITABLE(c)->cvc_tbl)
|
||||||
|
#define RCLASS_WRITABLE_SUBCLASSES(c) (RCLASS_EXT_WRITABLE(c)->subclasses)
|
||||||
|
|
||||||
|
static inline void RCLASS_SET_SUPER(VALUE klass, VALUE super);
|
||||||
|
static inline void RCLASS_WRITE_SUPER(VALUE klass, VALUE super);
|
||||||
|
static inline st_table * RCLASS_FIELDS_HASH(VALUE obj);
|
||||||
|
static inline st_table * RCLASS_WRITABLE_FIELDS_HASH(VALUE obj);
|
||||||
|
static inline void RCLASS_SET_FIELDS_HASH(VALUE obj, const st_table *table);
|
||||||
|
static inline void RCLASS_WRITE_FIELDS_HASH(VALUE obj, const st_table *table);
|
||||||
|
static inline uint32_t RCLASS_FIELDS_COUNT(VALUE obj);
|
||||||
|
static inline void RCLASS_SET_M_TBL(VALUE klass, struct rb_id_table *table);
|
||||||
|
static inline void RCLASS_WRITE_M_TBL(VALUE klass, struct rb_id_table *table);
|
||||||
|
static inline void RCLASS_SET_CONST_TBL(VALUE klass, struct rb_id_table *table, bool shared);
|
||||||
|
static inline void RCLASS_WRITE_CONST_TBL(VALUE klass, struct rb_id_table *table, bool shared);
|
||||||
|
static inline void RCLASS_WRITE_CALLABLE_M_TBL(VALUE klass, struct rb_id_table *table);
|
||||||
|
static inline void RCLASS_WRITE_CC_TBL(VALUE klass, struct rb_id_table *table);
|
||||||
|
static inline void RCLASS_SET_CVC_TBL(VALUE klass, struct rb_id_table *table);
|
||||||
|
static inline void RCLASS_WRITE_CVC_TBL(VALUE klass, struct rb_id_table *table);
|
||||||
|
|
||||||
|
static inline void RCLASS_WRITE_SUPERCLASSES(VALUE klass, size_t depth, VALUE *superclasses, bool owns_it, bool with_self);
|
||||||
|
static inline void RCLASS_SET_SUBCLASSES(VALUE klass, rb_subclass_anchor_t *anchor);
|
||||||
|
static inline void RCLASS_WRITE_SUBCLASSES(VALUE klass, rb_subclass_anchor_t *anchor);
|
||||||
|
static inline void RCLASS_WRITE_NS_SUPER_SUBCLASSES(VALUE klass, rb_ns_subclasses_t *ns_subclasses);
|
||||||
|
static inline void RCLASS_WRITE_NS_MODULE_SUBCLASSES(VALUE klass, rb_ns_subclasses_t *ns_subclasses);
|
||||||
|
|
||||||
|
static inline void RCLASS_SET_ORIGIN(VALUE klass, VALUE origin);
|
||||||
|
static inline void RCLASS_WRITE_ORIGIN(VALUE klass, VALUE origin);
|
||||||
|
static inline void RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass);
|
||||||
|
static inline void RICLASS_WRITE_ORIGIN_SHARED_MTBL(VALUE iclass);
|
||||||
|
static inline bool RICLASS_OWNS_M_TBL_P(VALUE iclass);
|
||||||
|
|
||||||
|
static inline void RCLASS_SET_REFINED_CLASS(VALUE klass, VALUE refined);
|
||||||
|
static inline rb_alloc_func_t RCLASS_ALLOCATOR(VALUE klass);
|
||||||
|
static inline void RCLASS_SET_ALLOCATOR(VALUE klass, rb_alloc_func_t allocator);
|
||||||
|
static inline VALUE RCLASS_SET_ATTACHED_OBJECT(VALUE klass, VALUE attached_object);
|
||||||
|
|
||||||
|
static inline void RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass);
|
||||||
|
static inline void RCLASS_SET_MAX_IV_COUNT(VALUE klass, attr_index_t count);
|
||||||
|
static inline void RCLASS_WRITE_MAX_IV_COUNT(VALUE klass, attr_index_t count);
|
||||||
|
static inline void RCLASS_SET_CLONED(VALUE klass, bool cloned);
|
||||||
|
static inline void RCLASS_SET_CLASSPATH(VALUE klass, VALUE classpath, bool permanent);
|
||||||
|
static inline void RCLASS_WRITE_CLASSPATH(VALUE klass, VALUE classpath, bool permanent);
|
||||||
|
|
||||||
#define RCLASS_IS_ROOT FL_USER0
|
#define RCLASS_IS_ROOT FL_USER0
|
||||||
#define RICLASS_IS_ORIGIN FL_USER0
|
// #define RICLASS_IS_ORIGIN FL_USER0 // TODO: Delete this
|
||||||
#define RCLASS_SUPERCLASSES_INCLUDE_SELF FL_USER2
|
// #define RCLASS_SUPERCLASSES_INCLUD_SELF FL_USER2 // TODO: Delete this
|
||||||
#define RICLASS_ORIGIN_SHARED_MTBL FL_USER3
|
// #define RICLASS_ORIGIN_SHARED_MTBL FL_USER3 // TODO: Delete this
|
||||||
|
|
||||||
|
VALUE rb_class_debug_duplicate_classext(VALUE klass, VALUE namespace); // TODO: only for development
|
||||||
|
VALUE rb_class_debug_dump_all_classext(VALUE klass); // TODO: only for development
|
||||||
|
VALUE rb_class_debug_dump_all_classext_super(VALUE klass, VALUE upto); // TODO: only for development
|
||||||
|
void rb_class_debug_print_classext(const char *label, const char *opt, VALUE klass);
|
||||||
|
VALUE rb_class_debug_print_module(VALUE);
|
||||||
|
|
||||||
|
/* class.c */
|
||||||
|
rb_classext_t * rb_class_duplicate_classext(rb_classext_t *orig, VALUE obj, const rb_namespace_t *ns);
|
||||||
|
void rb_class_ensure_writable(VALUE obj);
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
RCLASS_SET_NAMESPACE_CLASSEXT(VALUE obj, const rb_namespace_t *ns, rb_classext_t *ext)
|
||||||
|
{
|
||||||
|
int tbl_created = 0;
|
||||||
|
st_table *tbl = RCLASS_CLASSEXT_TBL(obj);
|
||||||
|
VM_ASSERT(NAMESPACE_USER_P(ns)); // non-prime classext is only for user namespace, with ns_object
|
||||||
|
VM_ASSERT(RCLASSEXT_NS(ext) == ns);
|
||||||
|
if (!tbl) {
|
||||||
|
RCLASS_CLASSEXT_TBL(obj) = tbl = st_init_numtable_with_size(1);
|
||||||
|
tbl_created = 1;
|
||||||
|
}
|
||||||
|
rb_st_insert(tbl, (st_data_t)ns->ns_object, (st_data_t)ext);
|
||||||
|
return tbl_created;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_SET_PRIME_CLASSEXT_READWRITE(VALUE obj, bool readable, bool writable)
|
||||||
|
{
|
||||||
|
RCLASS(obj)->prime_classext_readable = readable;
|
||||||
|
RCLASS(obj)->prime_classext_writable = writable;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline rb_classext_t *
|
||||||
|
RCLASS_EXT_TABLE_LOOKUP_INTERNAL(VALUE obj, const rb_namespace_t *ns)
|
||||||
|
{
|
||||||
|
st_data_t classext_ptr;
|
||||||
|
st_table *classext_tbl = RCLASS_CLASSEXT_TBL(obj);
|
||||||
|
if (classext_tbl) {
|
||||||
|
if (rb_st_lookup(classext_tbl, (st_data_t)ns->ns_object, &classext_ptr)) {
|
||||||
|
return (rb_classext_t *)classext_ptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline rb_classext_t *
|
||||||
|
RCLASS_EXT_READABLE_LOOKUP(VALUE obj, const rb_namespace_t *ns)
|
||||||
|
{
|
||||||
|
rb_classext_t *ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(obj, ns);
|
||||||
|
if (ext)
|
||||||
|
return ext;
|
||||||
|
// Classext for the ns not found. Refer the prime one instead.
|
||||||
|
return RCLASS_EXT(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline rb_classext_t *
|
||||||
|
RCLASS_EXT_READABLE_IN_NS(VALUE obj, const rb_namespace_t *ns)
|
||||||
|
{
|
||||||
|
if (!ns
|
||||||
|
|| NAMESPACE_BUILTIN_P(ns)
|
||||||
|
|| RCLASS(obj)->prime_classext_readable) {
|
||||||
|
return RCLASS_EXT(obj);
|
||||||
|
}
|
||||||
|
return RCLASS_EXT_READABLE_LOOKUP(obj, ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline rb_classext_t *
|
||||||
|
RCLASS_EXT_READABLE(VALUE obj)
|
||||||
|
{
|
||||||
|
const rb_namespace_t *ns;
|
||||||
|
if (RCLASS(obj)->prime_classext_readable) {
|
||||||
|
return RCLASS_EXT(obj);
|
||||||
|
}
|
||||||
|
// delay namespace loading to optimize for unmodified classes
|
||||||
|
ns = rb_current_namespace();
|
||||||
|
if (!ns || NAMESPACE_BUILTIN_P(ns)) {
|
||||||
|
return RCLASS_EXT(obj);
|
||||||
|
}
|
||||||
|
return RCLASS_EXT_READABLE_LOOKUP(obj, ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline rb_classext_t *
|
||||||
|
RCLASS_EXT_WRITABLE_LOOKUP(VALUE obj, const rb_namespace_t *ns)
|
||||||
|
{
|
||||||
|
rb_classext_t *ext;
|
||||||
|
int table_created = 0;
|
||||||
|
|
||||||
|
ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(obj, ns);
|
||||||
|
if (ext)
|
||||||
|
return ext;
|
||||||
|
|
||||||
|
if (!rb_shape_obj_too_complex_p(obj)) {
|
||||||
|
// TODO: Handle object shapes properly
|
||||||
|
rb_evict_ivars_to_hash(obj); // fallback to ivptr for ivars from shapes
|
||||||
|
}
|
||||||
|
|
||||||
|
RB_VM_LOCK_ENTER();
|
||||||
|
{
|
||||||
|
// re-check the classext is not created to avoid the multi-thread race
|
||||||
|
ext = RCLASS_EXT_TABLE_LOOKUP_INTERNAL(obj, ns);
|
||||||
|
if (!ext) {
|
||||||
|
ext = rb_class_duplicate_classext(RCLASS_EXT(obj), obj, ns);
|
||||||
|
table_created = RCLASS_SET_NAMESPACE_CLASSEXT(obj, ns, ext);
|
||||||
|
if (table_created) {
|
||||||
|
RCLASS_SET_PRIME_CLASSEXT_READWRITE(obj, false, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
RB_VM_LOCK_LEAVE();
|
||||||
|
return ext;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline rb_classext_t *
|
||||||
|
RCLASS_EXT_WRITABLE_IN_NS(VALUE obj, const rb_namespace_t *ns)
|
||||||
|
{
|
||||||
|
if (!ns
|
||||||
|
|| NAMESPACE_BUILTIN_P(ns)
|
||||||
|
|| RCLASS(obj)->prime_classext_writable) {
|
||||||
|
return RCLASS_EXT(obj);
|
||||||
|
}
|
||||||
|
return RCLASS_EXT_WRITABLE_LOOKUP(obj, ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline rb_classext_t *
|
||||||
|
RCLASS_EXT_WRITABLE(VALUE obj)
|
||||||
|
{
|
||||||
|
const rb_namespace_t *ns;
|
||||||
|
if (RCLASS(obj)->prime_classext_writable) {
|
||||||
|
return RCLASS_EXT(obj);
|
||||||
|
}
|
||||||
|
// delay namespace loading to optimize for unmodified classes
|
||||||
|
ns = rb_current_namespace();
|
||||||
|
if (!ns || NAMESPACE_BUILTIN_P(ns)) {
|
||||||
|
// If no namespace is specified, Ruby VM is in bootstrap
|
||||||
|
// and the clean class definition is under construction.
|
||||||
|
return RCLASS_EXT(obj);
|
||||||
|
}
|
||||||
|
return RCLASS_EXT_WRITABLE_LOOKUP(obj, ns);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASSEXT_SET_ORIGIN(rb_classext_t *ext, VALUE klass, VALUE origin)
|
||||||
|
{
|
||||||
|
RB_OBJ_WRITE(klass, &(RCLASSEXT_ORIGIN(ext)), origin);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASSEXT_SET_INCLUDER(rb_classext_t *ext, VALUE klass, VALUE includer)
|
||||||
|
{
|
||||||
|
RB_OBJ_WRITE(klass, &(RCLASSEXT_INCLUDER(ext)), includer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* class.c */
|
||||||
|
typedef void rb_class_classext_foreach_callback_func(rb_classext_t *classext, bool is_prime, VALUE namespace, void *arg);
|
||||||
|
void rb_class_classext_foreach(VALUE klass, rb_class_classext_foreach_callback_func *func, void *arg);
|
||||||
|
void rb_class_subclass_add(VALUE super, VALUE klass);
|
||||||
|
void rb_class_remove_from_super_subclasses(VALUE);
|
||||||
|
void rb_class_remove_from_module_subclasses(VALUE);
|
||||||
|
void rb_class_classext_free_subclasses(rb_classext_t *, VALUE);
|
||||||
|
void rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE);
|
||||||
|
void rb_class_detach_subclasses(VALUE);
|
||||||
|
void rb_class_detach_module_subclasses(VALUE);
|
||||||
|
void rb_class_update_superclasses(VALUE);
|
||||||
|
size_t rb_class_superclasses_memsize(VALUE);
|
||||||
|
void rb_class_remove_subclass_head(VALUE);
|
||||||
|
int rb_singleton_class_internal_p(VALUE sklass);
|
||||||
|
VALUE rb_class_set_super(VALUE klass, VALUE super);
|
||||||
|
VALUE rb_class_boot(VALUE);
|
||||||
|
VALUE rb_class_s_alloc(VALUE klass);
|
||||||
|
VALUE rb_module_s_alloc(VALUE klass);
|
||||||
|
void rb_module_set_initialized(VALUE module);
|
||||||
|
void rb_module_check_initializable(VALUE module);
|
||||||
|
VALUE rb_make_metaclass(VALUE, VALUE);
|
||||||
|
VALUE rb_include_class_new(VALUE, VALUE);
|
||||||
|
VALUE rb_define_class_id_under_no_pin(VALUE outer, ID id, VALUE super);
|
||||||
|
VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj);
|
||||||
|
VALUE rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj);
|
||||||
|
VALUE rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj);
|
||||||
|
VALUE rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj);
|
||||||
|
VALUE rb_class_undefined_instance_methods(VALUE mod);
|
||||||
|
VALUE rb_special_singleton_class(VALUE);
|
||||||
|
VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach);
|
||||||
|
VALUE rb_singleton_class_get(VALUE obj);
|
||||||
|
void rb_undef_methods_from(VALUE klass, VALUE super);
|
||||||
|
VALUE rb_class_inherited(VALUE, VALUE);
|
||||||
|
VALUE rb_keyword_error_new(const char *, VALUE);
|
||||||
|
|
||||||
|
RUBY_SYMBOL_EXPORT_BEGIN
|
||||||
|
|
||||||
|
/* for objspace */
|
||||||
|
VALUE rb_class_super_of(VALUE klass);
|
||||||
|
VALUE rb_class_singleton_p(VALUE klass);
|
||||||
|
unsigned char rb_class_variation_count(VALUE klass);
|
||||||
|
|
||||||
|
RUBY_SYMBOL_EXPORT_END
|
||||||
|
|
||||||
|
static inline bool
|
||||||
|
RCLASS_SINGLETON_P(VALUE klass)
|
||||||
|
{
|
||||||
|
return RB_TYPE_P(klass, T_CLASS) && FL_TEST_RAW(klass, FL_SINGLETON);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_SET_SUPER(VALUE klass, VALUE super)
|
||||||
|
{
|
||||||
|
RB_OBJ_WRITE(klass, &RCLASSEXT_SUPER(RCLASS_EXT(klass)), super);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_WRITE_SUPER(VALUE klass, VALUE super)
|
||||||
|
{
|
||||||
|
RB_OBJ_WRITE(klass, &RCLASSEXT_SUPER(RCLASS_EXT_WRITABLE(klass)), super);
|
||||||
|
}
|
||||||
|
|
||||||
static inline st_table *
|
static inline st_table *
|
||||||
RCLASS_FIELDS_HASH(VALUE obj)
|
RCLASS_FIELDS_HASH(VALUE obj)
|
||||||
{
|
{
|
||||||
RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
|
RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
|
||||||
RUBY_ASSERT(rb_shape_obj_too_complex_p(obj));
|
RUBY_ASSERT(rb_shape_obj_too_complex_p(obj));
|
||||||
return (st_table *)RCLASS_FIELDS(obj);
|
return (st_table *)RCLASSEXT_FIELDS(RCLASS_EXT_READABLE(obj));
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline st_table *
|
||||||
|
RCLASS_WRITABLE_FIELDS_HASH(VALUE obj)
|
||||||
|
{
|
||||||
|
RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
|
||||||
|
RUBY_ASSERT(rb_shape_obj_too_complex_p(obj));
|
||||||
|
return (st_table *)RCLASSEXT_FIELDS(RCLASS_EXT_WRITABLE(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -126,7 +530,15 @@ RCLASS_SET_FIELDS_HASH(VALUE obj, const st_table *tbl)
|
|||||||
{
|
{
|
||||||
RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
|
RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
|
||||||
RUBY_ASSERT(rb_shape_obj_too_complex_p(obj));
|
RUBY_ASSERT(rb_shape_obj_too_complex_p(obj));
|
||||||
RCLASS_FIELDS(obj) = (VALUE *)tbl;
|
RCLASSEXT_FIELDS(RCLASS_EXT(obj)) = (VALUE *)tbl;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_WRITE_FIELDS_HASH(VALUE obj, const st_table *tbl)
|
||||||
|
{
|
||||||
|
RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
|
||||||
|
RUBY_ASSERT(rb_shape_obj_too_complex_p(obj));
|
||||||
|
RCLASSEXT_FIELDS(RCLASS_EXT_WRITABLE(obj)) = (VALUE *)tbl;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t
|
static inline uint32_t
|
||||||
@ -155,51 +567,62 @@ static inline void
|
|||||||
RCLASS_SET_M_TBL(VALUE klass, struct rb_id_table *table)
|
RCLASS_SET_M_TBL(VALUE klass, struct rb_id_table *table)
|
||||||
{
|
{
|
||||||
RUBY_ASSERT(!RB_OBJ_PROMOTED(klass));
|
RUBY_ASSERT(!RB_OBJ_PROMOTED(klass));
|
||||||
RCLASS_M_TBL(klass) = table;
|
RCLASSEXT_M_TBL(RCLASS_EXT(klass)) = table;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* class.c */
|
static inline void
|
||||||
void rb_class_subclass_add(VALUE super, VALUE klass);
|
RCLASS_WRITE_M_TBL(VALUE klass, struct rb_id_table *table)
|
||||||
void rb_class_remove_from_super_subclasses(VALUE);
|
|
||||||
void rb_class_update_superclasses(VALUE);
|
|
||||||
size_t rb_class_superclasses_memsize(VALUE);
|
|
||||||
void rb_class_remove_subclass_head(VALUE);
|
|
||||||
int rb_singleton_class_internal_p(VALUE sklass);
|
|
||||||
VALUE rb_class_boot(VALUE);
|
|
||||||
VALUE rb_class_s_alloc(VALUE klass);
|
|
||||||
VALUE rb_module_s_alloc(VALUE klass);
|
|
||||||
void rb_module_set_initialized(VALUE module);
|
|
||||||
void rb_module_check_initializable(VALUE module);
|
|
||||||
VALUE rb_make_metaclass(VALUE, VALUE);
|
|
||||||
VALUE rb_include_class_new(VALUE, VALUE);
|
|
||||||
void rb_class_foreach_subclass(VALUE klass, void (*f)(VALUE, VALUE), VALUE);
|
|
||||||
void rb_class_detach_subclasses(VALUE);
|
|
||||||
void rb_class_detach_module_subclasses(VALUE);
|
|
||||||
void rb_class_remove_from_module_subclasses(VALUE);
|
|
||||||
VALUE rb_define_class_id_under_no_pin(VALUE outer, ID id, VALUE super);
|
|
||||||
VALUE rb_obj_methods(int argc, const VALUE *argv, VALUE obj);
|
|
||||||
VALUE rb_obj_protected_methods(int argc, const VALUE *argv, VALUE obj);
|
|
||||||
VALUE rb_obj_private_methods(int argc, const VALUE *argv, VALUE obj);
|
|
||||||
VALUE rb_obj_public_methods(int argc, const VALUE *argv, VALUE obj);
|
|
||||||
VALUE rb_class_undefined_instance_methods(VALUE mod);
|
|
||||||
VALUE rb_special_singleton_class(VALUE);
|
|
||||||
VALUE rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach);
|
|
||||||
VALUE rb_singleton_class_get(VALUE obj);
|
|
||||||
void rb_undef_methods_from(VALUE klass, VALUE super);
|
|
||||||
|
|
||||||
static inline void RCLASS_SET_ORIGIN(VALUE klass, VALUE origin);
|
|
||||||
static inline void RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass);
|
|
||||||
static inline VALUE RCLASS_SUPER(VALUE klass);
|
|
||||||
static inline VALUE RCLASS_SET_SUPER(VALUE klass, VALUE super);
|
|
||||||
static inline void RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass);
|
|
||||||
|
|
||||||
VALUE rb_class_inherited(VALUE, VALUE);
|
|
||||||
VALUE rb_keyword_error_new(const char *, VALUE);
|
|
||||||
|
|
||||||
static inline bool
|
|
||||||
RCLASS_SINGLETON_P(VALUE klass)
|
|
||||||
{
|
{
|
||||||
return RB_TYPE_P(klass, T_CLASS) && FL_TEST_RAW(klass, FL_SINGLETON);
|
RUBY_ASSERT(!RB_OBJ_PROMOTED(klass));
|
||||||
|
RCLASSEXT_M_TBL(RCLASS_EXT_WRITABLE(klass)) = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_SET_CONST_TBL(VALUE klass, struct rb_id_table *table, bool shared)
|
||||||
|
{
|
||||||
|
rb_classext_t *ext = RCLASS_EXT(klass);
|
||||||
|
RCLASSEXT_CONST_TBL(ext) = table;
|
||||||
|
if (shared)
|
||||||
|
RCLASSEXT_SHARED_CONST_TBL(ext) = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_WRITE_CONST_TBL(VALUE klass, struct rb_id_table *table, bool shared)
|
||||||
|
{
|
||||||
|
rb_classext_t *ext = RCLASS_EXT_WRITABLE(klass);
|
||||||
|
RCLASSEXT_CONST_TBL(ext) = table;
|
||||||
|
if (shared)
|
||||||
|
RCLASSEXT_SHARED_CONST_TBL(ext) = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_WRITE_CALLABLE_M_TBL(VALUE klass, struct rb_id_table *table)
|
||||||
|
{
|
||||||
|
RCLASSEXT_CALLABLE_M_TBL(RCLASS_EXT_WRITABLE(klass)) = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_WRITE_CC_TBL(VALUE klass, struct rb_id_table *table)
|
||||||
|
{
|
||||||
|
RCLASSEXT_CC_TBL(RCLASS_EXT_WRITABLE(klass)) = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_SET_CVC_TBL(VALUE klass, struct rb_id_table *table)
|
||||||
|
{
|
||||||
|
RCLASSEXT_CVC_TBL(RCLASS_EXT(klass)) = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_WRITE_CVC_TBL(VALUE klass, struct rb_id_table *table)
|
||||||
|
{
|
||||||
|
RCLASSEXT_CVC_TBL(RCLASS_EXT_WRITABLE(klass)) = table;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_SET_REFINED_CLASS(VALUE klass, VALUE refined)
|
||||||
|
{
|
||||||
|
RB_OBJ_WRITE(klass, &RCLASSEXT_REFINED_CLASS(RCLASS_EXT(klass)), refined);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline rb_alloc_func_t
|
static inline rb_alloc_func_t
|
||||||
@ -215,26 +638,42 @@ static inline void
|
|||||||
RCLASS_SET_ALLOCATOR(VALUE klass, rb_alloc_func_t allocator)
|
RCLASS_SET_ALLOCATOR(VALUE klass, rb_alloc_func_t allocator)
|
||||||
{
|
{
|
||||||
assert(!RCLASS_SINGLETON_P(klass));
|
assert(!RCLASS_SINGLETON_P(klass));
|
||||||
RCLASS_EXT(klass)->as.class.allocator = allocator;
|
RCLASS_EXT(klass)->as.class.allocator = allocator; // Allocator is set only on the initial definition
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
RCLASS_SET_ORIGIN(VALUE klass, VALUE origin)
|
RCLASS_SET_ORIGIN(VALUE klass, VALUE origin)
|
||||||
{
|
{
|
||||||
RB_OBJ_WRITE(klass, &RCLASS_ORIGIN(klass), origin);
|
rb_classext_t *ext = RCLASS_EXT(klass);
|
||||||
if (klass != origin) FL_SET(origin, RICLASS_IS_ORIGIN);
|
RB_OBJ_WRITE(klass, &RCLASSEXT_ORIGIN(ext), origin);
|
||||||
|
if (klass != origin) RCLASSEXT_ICLASS_IS_ORIGIN(RCLASS_EXT_WRITABLE(origin)) = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_WRITE_ORIGIN(VALUE klass, VALUE origin)
|
||||||
|
{
|
||||||
|
rb_classext_t *ext = RCLASS_EXT_WRITABLE(klass);
|
||||||
|
RB_OBJ_WRITE(klass, &RCLASSEXT_ORIGIN(ext), origin);
|
||||||
|
if (klass != origin) RCLASSEXT_ICLASS_IS_ORIGIN(RCLASS_EXT_WRITABLE(origin)) = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass)
|
RICLASS_SET_ORIGIN_SHARED_MTBL(VALUE iclass)
|
||||||
{
|
{
|
||||||
FL_SET(iclass, RICLASS_ORIGIN_SHARED_MTBL);
|
RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(RCLASS_EXT(iclass)) = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RICLASS_WRITE_ORIGIN_SHARED_MTBL(VALUE iclass)
|
||||||
|
{
|
||||||
|
RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(RCLASS_EXT_WRITABLE(iclass)) = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool
|
static inline bool
|
||||||
RICLASS_OWNS_M_TBL_P(VALUE iclass)
|
RICLASS_OWNS_M_TBL_P(VALUE iclass)
|
||||||
{
|
{
|
||||||
return FL_TEST_RAW(iclass, RICLASS_IS_ORIGIN | RICLASS_ORIGIN_SHARED_MTBL) == RICLASS_IS_ORIGIN;
|
rb_classext_t *ext = RCLASS_EXT_READABLE(iclass);
|
||||||
|
return RCLASSEXT_ICLASS_IS_ORIGIN(ext) && !RCLASSEXT_ICLASS_ORIGIN_SHARED_MTBL(ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
@ -243,32 +682,61 @@ RCLASS_SET_INCLUDER(VALUE iclass, VALUE klass)
|
|||||||
RB_OBJ_WRITE(iclass, &RCLASS_INCLUDER(iclass), klass);
|
RB_OBJ_WRITE(iclass, &RCLASS_INCLUDER(iclass), klass);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline VALUE
|
static inline void
|
||||||
RCLASS_SUPER(VALUE klass)
|
RCLASS_WRITE_SUPERCLASSES(VALUE klass, size_t depth, VALUE *superclasses, bool owns_it, bool with_self)
|
||||||
{
|
{
|
||||||
return RCLASS(klass)->super;
|
rb_classext_t *ext = RCLASS_EXT_WRITABLE(klass);
|
||||||
|
RCLASSEXT_SUPERCLASS_DEPTH(ext) = depth;
|
||||||
|
RCLASSEXT_SUPERCLASSES(ext) = superclasses;
|
||||||
|
RCLASSEXT_SUPERCLASSES_OWNER(ext) = owns_it;
|
||||||
|
RCLASSEXT_SUPERCLASSES_WITH_SELF(ext) = with_self;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline VALUE
|
static inline void
|
||||||
RCLASS_SET_SUPER(VALUE klass, VALUE super)
|
RCLASS_SET_SUBCLASSES(VALUE klass, struct rb_subclass_anchor *anchor)
|
||||||
{
|
{
|
||||||
if (super) {
|
rb_classext_t *ext = RCLASS_EXT(klass);
|
||||||
rb_class_remove_from_super_subclasses(klass);
|
RCLASSEXT_SUBCLASSES(ext) = anchor;
|
||||||
rb_class_subclass_add(super, klass);
|
}
|
||||||
}
|
|
||||||
RB_OBJ_WRITE(klass, &RCLASS(klass)->super, super);
|
static inline void
|
||||||
rb_class_update_superclasses(klass);
|
RCLASS_WRITE_NS_SUPER_SUBCLASSES(VALUE klass, rb_ns_subclasses_t *ns_subclasses)
|
||||||
return super;
|
{
|
||||||
|
rb_classext_t *ext = RCLASS_EXT_WRITABLE(klass);
|
||||||
|
if (RCLASSEXT_NS_SUPER_SUBCLASSES(ext))
|
||||||
|
rb_ns_subclasses_ref_dec(RCLASSEXT_NS_SUPER_SUBCLASSES(ext));
|
||||||
|
RCLASSEXT_NS_SUPER_SUBCLASSES(ext) = rb_ns_subclasses_ref_inc(ns_subclasses);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_WRITE_NS_MODULE_SUBCLASSES(VALUE klass, rb_ns_subclasses_t *ns_subclasses)
|
||||||
|
{
|
||||||
|
rb_classext_t *ext = RCLASS_EXT_WRITABLE(klass);
|
||||||
|
if (RCLASSEXT_NS_MODULE_SUBCLASSES(ext))
|
||||||
|
rb_ns_subclasses_ref_dec(RCLASSEXT_NS_MODULE_SUBCLASSES(ext));
|
||||||
|
RCLASSEXT_NS_MODULE_SUBCLASSES(ext) = rb_ns_subclasses_ref_inc(ns_subclasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
RCLASS_SET_CLASSPATH(VALUE klass, VALUE classpath, bool permanent)
|
RCLASS_SET_CLASSPATH(VALUE klass, VALUE classpath, bool permanent)
|
||||||
{
|
{
|
||||||
|
rb_classext_t *ext = RCLASS_EXT_READABLE(klass);
|
||||||
assert(BUILTIN_TYPE(klass) == T_CLASS || BUILTIN_TYPE(klass) == T_MODULE);
|
assert(BUILTIN_TYPE(klass) == T_CLASS || BUILTIN_TYPE(klass) == T_MODULE);
|
||||||
assert(classpath == 0 || BUILTIN_TYPE(classpath) == T_STRING);
|
assert(classpath == 0 || BUILTIN_TYPE(classpath) == T_STRING);
|
||||||
|
|
||||||
RB_OBJ_WRITE(klass, &(RCLASS_EXT(klass)->classpath), classpath);
|
RB_OBJ_WRITE(klass, &(RCLASSEXT_CLASSPATH(ext)), classpath);
|
||||||
RCLASS_EXT(klass)->permanent_classpath = permanent;
|
RCLASSEXT_PERMANENT_CLASSPATH(ext) = permanent;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_WRITE_CLASSPATH(VALUE klass, VALUE classpath, bool permanent)
|
||||||
|
{
|
||||||
|
rb_classext_t *ext = RCLASS_EXT_WRITABLE(klass);
|
||||||
|
assert(BUILTIN_TYPE(klass) == T_CLASS || BUILTIN_TYPE(klass) == T_MODULE);
|
||||||
|
assert(classpath == 0 || BUILTIN_TYPE(classpath) == T_STRING);
|
||||||
|
|
||||||
|
RB_OBJ_WRITE(klass, &(RCLASSEXT_CLASSPATH(ext)), classpath);
|
||||||
|
RCLASSEXT_PERMANENT_CLASSPATH(ext) = permanent;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline VALUE
|
static inline VALUE
|
||||||
@ -280,4 +748,22 @@ RCLASS_SET_ATTACHED_OBJECT(VALUE klass, VALUE attached_object)
|
|||||||
return attached_object;
|
return attached_object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_SET_MAX_IV_COUNT(VALUE klass, attr_index_t count)
|
||||||
|
{
|
||||||
|
RCLASSEXT_MAX_IV_COUNT(RCLASS_EXT(klass)) = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_WRITE_MAX_IV_COUNT(VALUE klass, attr_index_t count)
|
||||||
|
{
|
||||||
|
RCLASSEXT_MAX_IV_COUNT(RCLASS_EXT_WRITABLE(klass)) = count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void
|
||||||
|
RCLASS_SET_CLONED(VALUE klass, bool cloned)
|
||||||
|
{
|
||||||
|
RCLASSEXT_CLONED(RCLASS_EXT(klass)) = cloned;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* INTERNAL_CLASS_H */
|
#endif /* INTERNAL_CLASS_H */
|
||||||
|
@ -16,11 +16,18 @@
|
|||||||
#define id_status ruby_static_id_status
|
#define id_status ruby_static_id_status
|
||||||
|
|
||||||
/* eval.c */
|
/* eval.c */
|
||||||
|
struct rb_refinements_data {
|
||||||
|
VALUE refinement;
|
||||||
|
VALUE refinements;
|
||||||
|
};
|
||||||
|
|
||||||
extern ID ruby_static_id_signo;
|
extern ID ruby_static_id_signo;
|
||||||
extern ID ruby_static_id_status;
|
extern ID ruby_static_id_status;
|
||||||
VALUE rb_refinement_module_get_refined_class(VALUE module);
|
VALUE rb_refinement_module_get_refined_class(VALUE module);
|
||||||
void rb_class_modify_check(VALUE);
|
void rb_class_modify_check(VALUE);
|
||||||
NORETURN(VALUE rb_f_raise(int argc, VALUE *argv));
|
NORETURN(VALUE rb_f_raise(int argc, VALUE *argv));
|
||||||
|
void rb_refinement_setup(struct rb_refinements_data *data, VALUE module, VALUE klass);
|
||||||
|
void rb_vm_using_module(VALUE module);
|
||||||
VALUE rb_top_main_class(const char *method);
|
VALUE rb_top_main_class(const char *method);
|
||||||
|
|
||||||
/* eval_error.c */
|
/* eval_error.c */
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
*/
|
*/
|
||||||
#include "ruby/internal/config.h"
|
#include "ruby/internal/config.h"
|
||||||
#include <stddef.h> /* for size_t */
|
#include <stddef.h> /* for size_t */
|
||||||
|
#include "id_table.h"
|
||||||
#include "internal/array.h" /* for rb_ary_hidden_new_fill */
|
#include "internal/array.h" /* for rb_ary_hidden_new_fill */
|
||||||
#include "ruby/internal/stdbool.h" /* for bool */
|
#include "ruby/internal/stdbool.h" /* for bool */
|
||||||
#include "ruby/ruby.h" /* for rb_block_call_func_t */
|
#include "ruby/ruby.h" /* for rb_block_call_func_t */
|
||||||
@ -24,6 +25,7 @@
|
|||||||
#define IMEMO_FL_USER3 FL_USER7
|
#define IMEMO_FL_USER3 FL_USER7
|
||||||
#define IMEMO_FL_USER4 FL_USER8
|
#define IMEMO_FL_USER4 FL_USER8
|
||||||
#define IMEMO_FL_USER5 FL_USER9
|
#define IMEMO_FL_USER5 FL_USER9
|
||||||
|
#define IMEMO_FL_USER6 FL_USER10
|
||||||
|
|
||||||
enum imemo_type {
|
enum imemo_type {
|
||||||
imemo_env = 0,
|
imemo_env = 0,
|
||||||
@ -149,6 +151,7 @@ size_t rb_imemo_memsize(VALUE obj);
|
|||||||
void rb_cc_table_mark(VALUE klass);
|
void rb_cc_table_mark(VALUE klass);
|
||||||
void rb_imemo_mark_and_move(VALUE obj, bool reference_updating);
|
void rb_imemo_mark_and_move(VALUE obj, bool reference_updating);
|
||||||
void rb_cc_table_free(VALUE klass);
|
void rb_cc_table_free(VALUE klass);
|
||||||
|
void rb_cc_tbl_free(struct rb_id_table *cc_tbl, VALUE klass);
|
||||||
void rb_imemo_free(VALUE obj);
|
void rb_imemo_free(VALUE obj);
|
||||||
|
|
||||||
RUBY_SYMBOL_EXPORT_BEGIN
|
RUBY_SYMBOL_EXPORT_BEGIN
|
||||||
|
@ -12,6 +12,8 @@
|
|||||||
|
|
||||||
/* load.c */
|
/* load.c */
|
||||||
VALUE rb_get_expanded_load_path(void);
|
VALUE rb_get_expanded_load_path(void);
|
||||||
|
VALUE rb_load_entrypoint(VALUE args);
|
||||||
|
VALUE rb_require_relative_entrypoint(VALUE fname);
|
||||||
int rb_require_internal(VALUE fname);
|
int rb_require_internal(VALUE fname);
|
||||||
NORETURN(void rb_load_fail(VALUE, const char*));
|
NORETURN(void rb_load_fail(VALUE, const char*));
|
||||||
|
|
||||||
|
80
internal/namespace.h
Normal file
80
internal/namespace.h
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
#ifndef INTERNAL_NAMESPACE_H /*-*-C-*-vi:se ft=c:*/
|
||||||
|
#define INTERNAL_NAMESPACE_H
|
||||||
|
|
||||||
|
#include "ruby/ruby.h" /* for VALUE */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Satoshi Tagomori <tagomoris@gmail.com>
|
||||||
|
* @copyright This file is a part of the programming language Ruby.
|
||||||
|
* Permission is hereby granted, to either redistribute and/or
|
||||||
|
* modify this file, provided that the conditions mentioned in the
|
||||||
|
* file COPYING are met. Consult the file for details.
|
||||||
|
* @brief Internal header for Fiber.
|
||||||
|
*/
|
||||||
|
struct rb_namespace_struct {
|
||||||
|
/*
|
||||||
|
* To retrieve Namespace object that provides #require and so on.
|
||||||
|
* That is used from load.c, etc., that uses rb_namespace_t internally.
|
||||||
|
*/
|
||||||
|
VALUE ns_object;
|
||||||
|
long ns_id; // namespace id to generate ext filenames
|
||||||
|
|
||||||
|
VALUE top_self;
|
||||||
|
|
||||||
|
VALUE load_path;
|
||||||
|
VALUE load_path_snapshot;
|
||||||
|
VALUE load_path_check_cache;
|
||||||
|
VALUE expanded_load_path;
|
||||||
|
VALUE loaded_features;
|
||||||
|
VALUE loaded_features_snapshot;
|
||||||
|
VALUE loaded_features_realpaths;
|
||||||
|
VALUE loaded_features_realpath_map;
|
||||||
|
struct st_table *loaded_features_index;
|
||||||
|
struct st_table *loading_table;
|
||||||
|
VALUE ruby_dln_libmap;
|
||||||
|
|
||||||
|
VALUE gvar_tbl;
|
||||||
|
|
||||||
|
bool is_builtin;
|
||||||
|
bool is_user;
|
||||||
|
bool is_optional;
|
||||||
|
};
|
||||||
|
typedef struct rb_namespace_struct rb_namespace_t;
|
||||||
|
|
||||||
|
#define NAMESPACE_BUILTIN_P(ns) (ns && ns->is_builtin)
|
||||||
|
#define NAMESPACE_USER_P(ns) (ns && ns->is_user)
|
||||||
|
#define NAMESPACE_OPTIONAL_P(ns) (ns && ns->is_optional)
|
||||||
|
#define NAMESPACE_MAIN_P(ns) (ns && ns->is_user && !ns->is_optional)
|
||||||
|
|
||||||
|
#define NAMESPACE_METHOD_DEFINITION(mdef) (mdef ? mdef->ns : NULL)
|
||||||
|
#define NAMESPACE_METHOD_ENTRY(me) (me ? NAMESPACE_METHOD_DEFINITION(me->def) : NULL)
|
||||||
|
#define NAMESPACE_CC(cc) (cc ? NAMESPACE_METHOD_ENTRY(cc->cme_) : NULL)
|
||||||
|
#define NAMESPACE_CC_ENTRIES(ccs) (ccs ? NAMESPACE_METHOD_ENTRY(ccs->cme) : NULL)
|
||||||
|
|
||||||
|
int rb_namespace_available(void);
|
||||||
|
void rb_namespace_enable_builtin(void);
|
||||||
|
void rb_namespace_disable_builtin(void);
|
||||||
|
void rb_namespace_push_loading_namespace(const rb_namespace_t *);
|
||||||
|
void rb_namespace_pop_loading_namespace(const rb_namespace_t *);
|
||||||
|
rb_namespace_t * rb_root_namespace(void);
|
||||||
|
const rb_namespace_t *rb_builtin_namespace(void);
|
||||||
|
rb_namespace_t * rb_main_namespace(void);
|
||||||
|
const rb_namespace_t * rb_definition_namespace(void);
|
||||||
|
const rb_namespace_t * rb_loading_namespace(void);
|
||||||
|
const rb_namespace_t * rb_current_namespace(void);
|
||||||
|
VALUE rb_current_namespace_details(VALUE);
|
||||||
|
|
||||||
|
void rb_namespace_entry_mark(void *);
|
||||||
|
|
||||||
|
rb_namespace_t * rb_get_namespace_t(VALUE ns);
|
||||||
|
VALUE rb_get_namespace_object(rb_namespace_t *ns);
|
||||||
|
typedef VALUE namespace_exec_func(VALUE arg);
|
||||||
|
VALUE rb_namespace_exec(const rb_namespace_t *ns, namespace_exec_func *func, VALUE arg);
|
||||||
|
|
||||||
|
VALUE rb_namespace_local_extension(VALUE namespace, VALUE fname, VALUE path);
|
||||||
|
|
||||||
|
void rb_initialize_main_namespace(void);
|
||||||
|
|
||||||
|
bool rb_namespace_debug_mode_p(void);
|
||||||
|
|
||||||
|
#endif /* INTERNAL_NAMESPACE_H */
|
@ -23,11 +23,13 @@ VALUE rb_search_class_path(VALUE);
|
|||||||
VALUE rb_attr_delete(VALUE, ID);
|
VALUE rb_attr_delete(VALUE, ID);
|
||||||
void rb_autoload_str(VALUE mod, ID id, VALUE file);
|
void rb_autoload_str(VALUE mod, ID id, VALUE file);
|
||||||
VALUE rb_autoload_at_p(VALUE, ID, int);
|
VALUE rb_autoload_at_p(VALUE, ID, int);
|
||||||
|
void rb_autoload_copy_table_for_namespace(st_table *, const rb_namespace_t *);
|
||||||
NORETURN(VALUE rb_mod_const_missing(VALUE,VALUE));
|
NORETURN(VALUE rb_mod_const_missing(VALUE,VALUE));
|
||||||
rb_gvar_getter_t *rb_gvar_getter_function_of(ID);
|
rb_gvar_getter_t *rb_gvar_getter_function_of(ID);
|
||||||
rb_gvar_setter_t *rb_gvar_setter_function_of(ID);
|
rb_gvar_setter_t *rb_gvar_setter_function_of(ID);
|
||||||
void rb_gvar_readonly_setter(VALUE v, ID id, VALUE *_);
|
void rb_gvar_readonly_setter(VALUE v, ID id, VALUE *_);
|
||||||
void rb_gvar_ractor_local(const char *name);
|
void rb_gvar_ractor_local(const char *name);
|
||||||
|
void rb_gvar_namespace_ready(const char *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the name of a module.
|
* Sets the name of a module.
|
||||||
|
@ -77,6 +77,7 @@ void rb_check_stack_overflow(void);
|
|||||||
#define RB_BLOCK_NO_USE_PACKED_ARGS 2
|
#define RB_BLOCK_NO_USE_PACKED_ARGS 2
|
||||||
VALUE rb_block_call2(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t bl_proc, VALUE data2, long flags);
|
VALUE rb_block_call2(VALUE obj, ID mid, int argc, const VALUE *argv, rb_block_call_func_t bl_proc, VALUE data2, long flags);
|
||||||
struct vm_ifunc *rb_current_ifunc(void);
|
struct vm_ifunc *rb_current_ifunc(void);
|
||||||
|
VALUE rb_gccct_clear_table(VALUE);
|
||||||
|
|
||||||
#if USE_YJIT
|
#if USE_YJIT
|
||||||
/* vm_exec.c */
|
/* vm_exec.c */
|
||||||
|
2
iseq.c
2
iseq.c
@ -2919,7 +2919,7 @@ rb_estimate_iv_count(VALUE klass, const rb_iseq_t * initialize_iseq)
|
|||||||
attr_index_t count = (attr_index_t)rb_id_table_size(iv_names);
|
attr_index_t count = (attr_index_t)rb_id_table_size(iv_names);
|
||||||
|
|
||||||
VALUE superclass = rb_class_superclass(klass);
|
VALUE superclass = rb_class_superclass(klass);
|
||||||
count += RCLASS_EXT(superclass)->max_iv_count;
|
count += RCLASSEXT_MAX_IV_COUNT(RCLASS_EXT_READABLE(superclass));
|
||||||
|
|
||||||
rb_id_table_free(iv_names);
|
rb_id_table_free(iv_names);
|
||||||
|
|
||||||
|
@ -219,6 +219,7 @@ class Gem::Package
|
|||||||
# Adds a checksum for each entry in the gem to checksums.yaml.gz.
|
# Adds a checksum for each entry in the gem to checksums.yaml.gz.
|
||||||
|
|
||||||
def add_checksums(tar)
|
def add_checksums(tar)
|
||||||
|
require 'psych'
|
||||||
Gem.load_yaml
|
Gem.load_yaml
|
||||||
|
|
||||||
checksums_by_algorithm = Hash.new {|h, algorithm| h[algorithm] = {} }
|
checksums_by_algorithm = Hash.new {|h, algorithm| h[algorithm] = {} }
|
||||||
@ -552,6 +553,7 @@ EOM
|
|||||||
# Reads and loads checksums.yaml.gz from the tar file +gem+
|
# Reads and loads checksums.yaml.gz from the tar file +gem+
|
||||||
|
|
||||||
def read_checksums(gem)
|
def read_checksums(gem)
|
||||||
|
require_relative 'safe_yaml'
|
||||||
Gem.load_yaml
|
Gem.load_yaml
|
||||||
|
|
||||||
@checksums = gem.seek "checksums.yaml.gz" do |entry|
|
@checksums = gem.seek "checksums.yaml.gz" do |entry|
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'psych'
|
||||||
|
|
||||||
module Gem
|
module Gem
|
||||||
###
|
###
|
||||||
# This module is used for safely loading YAML specs from a gem. The
|
# This module is used for safely loading YAML specs from a gem. The
|
||||||
|
452
load.c
452
load.c
@ -7,9 +7,11 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "internal/dir.h"
|
#include "internal/dir.h"
|
||||||
#include "internal/error.h"
|
#include "internal/error.h"
|
||||||
|
#include "internal/eval.h"
|
||||||
#include "internal/file.h"
|
#include "internal/file.h"
|
||||||
#include "internal/hash.h"
|
#include "internal/hash.h"
|
||||||
#include "internal/load.h"
|
#include "internal/load.h"
|
||||||
|
#include "internal/namespace.h"
|
||||||
#include "internal/ruby_parser.h"
|
#include "internal/ruby_parser.h"
|
||||||
#include "internal/thread.h"
|
#include "internal/thread.h"
|
||||||
#include "internal/variable.h"
|
#include "internal/variable.h"
|
||||||
@ -19,6 +21,7 @@
|
|||||||
#include "ruby/encoding.h"
|
#include "ruby/encoding.h"
|
||||||
#include "ruby/util.h"
|
#include "ruby/util.h"
|
||||||
#include "ractor_core.h"
|
#include "ractor_core.h"
|
||||||
|
#include "vm_core.h"
|
||||||
|
|
||||||
static VALUE ruby_dln_libmap;
|
static VALUE ruby_dln_libmap;
|
||||||
|
|
||||||
@ -36,6 +39,38 @@ static VALUE ruby_dln_libmap;
|
|||||||
# error Need integer for VALUE
|
# error Need integer for VALUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define IS_NAMESPACE(obj) (CLASS_OF(obj) == rb_cNamespace)
|
||||||
|
|
||||||
|
struct vm_and_namespace_struct {
|
||||||
|
rb_vm_t *vm;
|
||||||
|
rb_namespace_t *ns;
|
||||||
|
};
|
||||||
|
typedef struct vm_and_namespace_struct vm_ns_t;
|
||||||
|
#define GET_vm_ns() vm_ns_t vm_ns_v = { .vm = GET_VM(), .ns = (rb_namespace_t *)rb_current_namespace(), }; vm_ns_t *vm_ns = &vm_ns_v;
|
||||||
|
#define GET_loading_vm_ns() vm_ns_t vm_ns_v = { .vm = GET_VM(), .ns = (rb_namespace_t *)rb_loading_namespace(), }; vm_ns_t *vm_ns = &vm_ns_v;
|
||||||
|
|
||||||
|
#define CURRENT_NS_attr(vm_ns, attr) (NAMESPACE_USER_P(vm_ns->ns) ? vm_ns->ns->attr : vm_ns->vm->attr)
|
||||||
|
#define SET_NS_attr(vm_ns, attr, value) do { \
|
||||||
|
if (NAMESPACE_USER_P(vm_ns->ns)) { vm_ns->ns->attr = value; } \
|
||||||
|
else { vm_ns->vm->attr = value; } \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
|
#define SET_NS_LOAD_PATH_CHECK_CACHE(vm_ns, value) SET_NS_attr(vm_ns, load_path_check_cache, value)
|
||||||
|
#define SET_NS_EXPANDED_LOAD_PATH(vm_ns, value) SET_NS_attr(vm_ns, expanded_load_path, value)
|
||||||
|
|
||||||
|
#define CURRENT_NS_LOAD_PATH(vm_ns) CURRENT_NS_attr(vm_ns, load_path)
|
||||||
|
#define CURRENT_NS_LOAD_PATH_SNAPSHOT(vm_ns) CURRENT_NS_attr(vm_ns, load_path_snapshot)
|
||||||
|
#define CURRENT_NS_LOAD_PATH_CHECK_CACHE(vm_ns) CURRENT_NS_attr(vm_ns, load_path_check_cache)
|
||||||
|
#define CURRENT_NS_EXPANDED_LOAD_PATH(vm_ns) CURRENT_NS_attr(vm_ns, expanded_load_path)
|
||||||
|
#define CURRENT_NS_LOADING_TABLE(vm_ns) CURRENT_NS_attr(vm_ns, loading_table)
|
||||||
|
#define CURRENT_NS_LOADED_FEATURES(vm_ns) CURRENT_NS_attr(vm_ns, loaded_features)
|
||||||
|
#define CURRENT_NS_LOADED_FEATURES_SNAPSHOT(vm_ns) CURRENT_NS_attr(vm_ns, loaded_features_snapshot)
|
||||||
|
#define CURRENT_NS_LOADED_FEATURES_REALPATHS(vm_ns) CURRENT_NS_attr(vm_ns, loaded_features_realpaths)
|
||||||
|
#define CURRENT_NS_LOADED_FEATURES_REALPATH_MAP(vm_ns) CURRENT_NS_attr(vm_ns, loaded_features_realpath_map)
|
||||||
|
#define CURRENT_NS_LOADED_FEATURES_INDEX(vm_ns) CURRENT_NS_attr(vm_ns, loaded_features_index)
|
||||||
|
|
||||||
|
#define CURRENT_NS_RUBY_DLN_LIBMAP(vm_ns, map) (NAMESPACE_USER_P(vm_ns->ns) ? vm_ns->ns->ruby_dln_libmap : map)
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
loadable_ext_rb = (0+ /* .rb extension is the first in both tables */
|
loadable_ext_rb = (0+ /* .rb extension is the first in both tables */
|
||||||
1) /* offset by rb_find_file_ext() */
|
1) /* offset by rb_find_file_ext() */
|
||||||
@ -64,10 +99,11 @@ enum expand_type {
|
|||||||
string objects in $LOAD_PATH are frozen.
|
string objects in $LOAD_PATH are frozen.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
rb_construct_expanded_load_path(rb_vm_t *vm, enum expand_type type, int *has_relative, int *has_non_cache)
|
rb_construct_expanded_load_path(vm_ns_t *vm_ns, enum expand_type type, int *has_relative, int *has_non_cache)
|
||||||
{
|
{
|
||||||
VALUE load_path = vm->load_path;
|
VALUE load_path = CURRENT_NS_LOAD_PATH(vm_ns);
|
||||||
VALUE expanded_load_path = vm->expanded_load_path;
|
VALUE expanded_load_path = CURRENT_NS_EXPANDED_LOAD_PATH(vm_ns);
|
||||||
|
VALUE snapshot;
|
||||||
VALUE ary;
|
VALUE ary;
|
||||||
long i;
|
long i;
|
||||||
|
|
||||||
@ -106,108 +142,117 @@ rb_construct_expanded_load_path(rb_vm_t *vm, enum expand_type type, int *has_rel
|
|||||||
rb_ary_push(ary, rb_fstring(expanded_path));
|
rb_ary_push(ary, rb_fstring(expanded_path));
|
||||||
}
|
}
|
||||||
rb_ary_freeze(ary);
|
rb_ary_freeze(ary);
|
||||||
vm->expanded_load_path = ary;
|
SET_NS_EXPANDED_LOAD_PATH(vm_ns, ary);
|
||||||
rb_ary_replace(vm->load_path_snapshot, vm->load_path);
|
snapshot = CURRENT_NS_LOAD_PATH_SNAPSHOT(vm_ns);
|
||||||
|
load_path = CURRENT_NS_LOAD_PATH(vm_ns);
|
||||||
|
rb_ary_replace(snapshot, load_path);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
get_expanded_load_path(rb_vm_t *vm)
|
get_expanded_load_path(vm_ns_t *vm_ns)
|
||||||
{
|
{
|
||||||
|
VALUE check_cache;
|
||||||
const VALUE non_cache = Qtrue;
|
const VALUE non_cache = Qtrue;
|
||||||
|
const VALUE load_path_snapshot = CURRENT_NS_LOAD_PATH_SNAPSHOT(vm_ns);
|
||||||
|
const VALUE load_path = CURRENT_NS_LOAD_PATH(vm_ns);
|
||||||
|
|
||||||
if (!rb_ary_shared_with_p(vm->load_path_snapshot, vm->load_path)) {
|
if (!rb_ary_shared_with_p(load_path_snapshot, load_path)) {
|
||||||
/* The load path was modified. Rebuild the expanded load path. */
|
/* The load path was modified. Rebuild the expanded load path. */
|
||||||
int has_relative = 0, has_non_cache = 0;
|
int has_relative = 0, has_non_cache = 0;
|
||||||
rb_construct_expanded_load_path(vm, EXPAND_ALL, &has_relative, &has_non_cache);
|
rb_construct_expanded_load_path(vm_ns, EXPAND_ALL, &has_relative, &has_non_cache);
|
||||||
if (has_relative) {
|
if (has_relative) {
|
||||||
vm->load_path_check_cache = rb_dir_getwd_ospath();
|
SET_NS_LOAD_PATH_CHECK_CACHE(vm_ns, rb_dir_getwd_ospath());
|
||||||
}
|
}
|
||||||
else if (has_non_cache) {
|
else if (has_non_cache) {
|
||||||
/* Non string object. */
|
/* Non string object. */
|
||||||
vm->load_path_check_cache = non_cache;
|
SET_NS_LOAD_PATH_CHECK_CACHE(vm_ns, non_cache);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
vm->load_path_check_cache = 0;
|
SET_NS_LOAD_PATH_CHECK_CACHE(vm_ns, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (vm->load_path_check_cache == non_cache) {
|
else if ((check_cache = CURRENT_NS_LOAD_PATH_CHECK_CACHE(vm_ns)) == non_cache) {
|
||||||
int has_relative = 1, has_non_cache = 1;
|
int has_relative = 1, has_non_cache = 1;
|
||||||
/* Expand only non-cacheable objects. */
|
/* Expand only non-cacheable objects. */
|
||||||
rb_construct_expanded_load_path(vm, EXPAND_NON_CACHE,
|
rb_construct_expanded_load_path(vm_ns, EXPAND_NON_CACHE,
|
||||||
&has_relative, &has_non_cache);
|
&has_relative, &has_non_cache);
|
||||||
}
|
}
|
||||||
else if (vm->load_path_check_cache) {
|
else if (check_cache) {
|
||||||
int has_relative = 1, has_non_cache = 1;
|
int has_relative = 1, has_non_cache = 1;
|
||||||
VALUE cwd = rb_dir_getwd_ospath();
|
VALUE cwd = rb_dir_getwd_ospath();
|
||||||
if (!rb_str_equal(vm->load_path_check_cache, cwd)) {
|
if (!rb_str_equal(check_cache, cwd)) {
|
||||||
/* Current working directory or filesystem encoding was changed.
|
/* Current working directory or filesystem encoding was changed.
|
||||||
Expand relative load path and non-cacheable objects again. */
|
Expand relative load path and non-cacheable objects again. */
|
||||||
vm->load_path_check_cache = cwd;
|
SET_NS_LOAD_PATH_CHECK_CACHE(vm_ns, cwd);
|
||||||
rb_construct_expanded_load_path(vm, EXPAND_RELATIVE,
|
rb_construct_expanded_load_path(vm_ns, EXPAND_RELATIVE,
|
||||||
&has_relative, &has_non_cache);
|
&has_relative, &has_non_cache);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* Expand only tilde (User HOME) and non-cacheable objects. */
|
/* Expand only tilde (User HOME) and non-cacheable objects. */
|
||||||
rb_construct_expanded_load_path(vm, EXPAND_HOME,
|
rb_construct_expanded_load_path(vm_ns, EXPAND_HOME,
|
||||||
&has_relative, &has_non_cache);
|
&has_relative, &has_non_cache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return vm->expanded_load_path;
|
return CURRENT_NS_EXPANDED_LOAD_PATH(vm_ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_get_expanded_load_path(void)
|
rb_get_expanded_load_path(void)
|
||||||
{
|
{
|
||||||
return get_expanded_load_path(GET_VM());
|
GET_loading_vm_ns();
|
||||||
|
return get_expanded_load_path(vm_ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
load_path_getter(ID id, VALUE * p)
|
load_path_getter(ID id, VALUE * p)
|
||||||
{
|
{
|
||||||
rb_vm_t *vm = (void *)p;
|
GET_loading_vm_ns();
|
||||||
return vm->load_path;
|
return CURRENT_NS_LOAD_PATH(vm_ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
get_loaded_features(rb_vm_t *vm)
|
get_loaded_features(vm_ns_t *vm_ns)
|
||||||
{
|
{
|
||||||
return vm->loaded_features;
|
return CURRENT_NS_LOADED_FEATURES(vm_ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
get_loaded_features_realpaths(rb_vm_t *vm)
|
get_loaded_features_realpaths(vm_ns_t *vm_ns)
|
||||||
{
|
{
|
||||||
return vm->loaded_features_realpaths;
|
return CURRENT_NS_LOADED_FEATURES_REALPATHS(vm_ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
get_loaded_features_realpath_map(rb_vm_t *vm)
|
get_loaded_features_realpath_map(vm_ns_t *vm_ns)
|
||||||
{
|
{
|
||||||
return vm->loaded_features_realpath_map;
|
return CURRENT_NS_LOADED_FEATURES_REALPATH_MAP(vm_ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
get_LOADED_FEATURES(ID _x, VALUE *_y)
|
get_LOADED_FEATURES(ID _x, VALUE *_y)
|
||||||
{
|
{
|
||||||
return get_loaded_features(GET_VM());
|
GET_loading_vm_ns();
|
||||||
|
return get_loaded_features(vm_ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
reset_loaded_features_snapshot(rb_vm_t *vm)
|
reset_loaded_features_snapshot(vm_ns_t *vm_ns)
|
||||||
{
|
{
|
||||||
rb_ary_replace(vm->loaded_features_snapshot, vm->loaded_features);
|
VALUE snapshot = CURRENT_NS_LOADED_FEATURES_SNAPSHOT(vm_ns);
|
||||||
|
VALUE loaded_features = CURRENT_NS_LOADED_FEATURES(vm_ns);
|
||||||
|
rb_ary_replace(snapshot, loaded_features);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct st_table *
|
static struct st_table *
|
||||||
get_loaded_features_index_raw(rb_vm_t *vm)
|
get_loaded_features_index_raw(vm_ns_t *vm_ns)
|
||||||
{
|
{
|
||||||
return vm->loaded_features_index;
|
return CURRENT_NS_LOADED_FEATURES_INDEX(vm_ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
static st_table *
|
static st_table *
|
||||||
get_loading_table(rb_vm_t *vm)
|
get_loading_table(vm_ns_t *vm_ns)
|
||||||
{
|
{
|
||||||
return vm->loading_table;
|
return CURRENT_NS_LOADING_TABLE(vm_ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
static st_data_t
|
static st_data_t
|
||||||
@ -228,7 +273,7 @@ is_rbext_path(VALUE feature_path)
|
|||||||
typedef rb_darray(long) feature_indexes_t;
|
typedef rb_darray(long) feature_indexes_t;
|
||||||
|
|
||||||
struct features_index_add_single_args {
|
struct features_index_add_single_args {
|
||||||
rb_vm_t *vm;
|
vm_ns_t *vm_ns;
|
||||||
VALUE offset;
|
VALUE offset;
|
||||||
bool rb;
|
bool rb;
|
||||||
};
|
};
|
||||||
@ -237,7 +282,7 @@ static int
|
|||||||
features_index_add_single_callback(st_data_t *key, st_data_t *value, st_data_t raw_args, int existing)
|
features_index_add_single_callback(st_data_t *key, st_data_t *value, st_data_t raw_args, int existing)
|
||||||
{
|
{
|
||||||
struct features_index_add_single_args *args = (struct features_index_add_single_args *)raw_args;
|
struct features_index_add_single_args *args = (struct features_index_add_single_args *)raw_args;
|
||||||
rb_vm_t *vm = args->vm;
|
vm_ns_t *vm_ns = args->vm_ns;
|
||||||
VALUE offset = args->offset;
|
VALUE offset = args->offset;
|
||||||
bool rb = args->rb;
|
bool rb = args->rb;
|
||||||
|
|
||||||
@ -245,7 +290,7 @@ features_index_add_single_callback(st_data_t *key, st_data_t *value, st_data_t r
|
|||||||
VALUE this_feature_index = *value;
|
VALUE this_feature_index = *value;
|
||||||
|
|
||||||
if (FIXNUM_P(this_feature_index)) {
|
if (FIXNUM_P(this_feature_index)) {
|
||||||
VALUE loaded_features = get_loaded_features(vm);
|
VALUE loaded_features = get_loaded_features(vm_ns);
|
||||||
VALUE this_feature_path = RARRAY_AREF(loaded_features, FIX2LONG(this_feature_index));
|
VALUE this_feature_path = RARRAY_AREF(loaded_features, FIX2LONG(this_feature_index));
|
||||||
|
|
||||||
feature_indexes_t feature_indexes;
|
feature_indexes_t feature_indexes;
|
||||||
@ -265,7 +310,7 @@ features_index_add_single_callback(st_data_t *key, st_data_t *value, st_data_t r
|
|||||||
long pos = -1;
|
long pos = -1;
|
||||||
|
|
||||||
if (rb) {
|
if (rb) {
|
||||||
VALUE loaded_features = get_loaded_features(vm);
|
VALUE loaded_features = get_loaded_features(vm_ns);
|
||||||
for (size_t i = 0; i < rb_darray_size(feature_indexes); ++i) {
|
for (size_t i = 0; i < rb_darray_size(feature_indexes); ++i) {
|
||||||
long idx = rb_darray_get(feature_indexes, i);
|
long idx = rb_darray_get(feature_indexes, i);
|
||||||
VALUE this_feature_path = RARRAY_AREF(loaded_features, idx);
|
VALUE this_feature_path = RARRAY_AREF(loaded_features, idx);
|
||||||
@ -297,7 +342,7 @@ features_index_add_single_callback(st_data_t *key, st_data_t *value, st_data_t r
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
features_index_add_single(rb_vm_t *vm, const char* str, size_t len, VALUE offset, bool rb)
|
features_index_add_single(vm_ns_t *vm_ns, const char* str, size_t len, VALUE offset, bool rb)
|
||||||
{
|
{
|
||||||
struct st_table *features_index;
|
struct st_table *features_index;
|
||||||
st_data_t short_feature_key;
|
st_data_t short_feature_key;
|
||||||
@ -305,10 +350,10 @@ features_index_add_single(rb_vm_t *vm, const char* str, size_t len, VALUE offset
|
|||||||
Check_Type(offset, T_FIXNUM);
|
Check_Type(offset, T_FIXNUM);
|
||||||
short_feature_key = feature_key(str, len);
|
short_feature_key = feature_key(str, len);
|
||||||
|
|
||||||
features_index = get_loaded_features_index_raw(vm);
|
features_index = get_loaded_features_index_raw(vm_ns);
|
||||||
|
|
||||||
struct features_index_add_single_args args = {
|
struct features_index_add_single_args args = {
|
||||||
.vm = vm,
|
.vm_ns = vm_ns,
|
||||||
.offset = offset,
|
.offset = offset,
|
||||||
.rb = rb,
|
.rb = rb,
|
||||||
};
|
};
|
||||||
@ -325,7 +370,7 @@ features_index_add_single(rb_vm_t *vm, const char* str, size_t len, VALUE offset
|
|||||||
relies on for its fast lookup.
|
relies on for its fast lookup.
|
||||||
*/
|
*/
|
||||||
static void
|
static void
|
||||||
features_index_add(rb_vm_t *vm, VALUE feature, VALUE offset)
|
features_index_add(vm_ns_t *vm_ns, VALUE feature, VALUE offset)
|
||||||
{
|
{
|
||||||
const char *feature_str, *feature_end, *ext, *p;
|
const char *feature_str, *feature_end, *ext, *p;
|
||||||
bool rb = false;
|
bool rb = false;
|
||||||
@ -351,14 +396,14 @@ features_index_add(rb_vm_t *vm, VALUE feature, VALUE offset)
|
|||||||
if (p < feature_str)
|
if (p < feature_str)
|
||||||
break;
|
break;
|
||||||
/* Now *p == '/'. We reach this point for every '/' in `feature`. */
|
/* Now *p == '/'. We reach this point for every '/' in `feature`. */
|
||||||
features_index_add_single(vm, p + 1, feature_end - p - 1, offset, false);
|
features_index_add_single(vm_ns, p + 1, feature_end - p - 1, offset, false);
|
||||||
if (ext) {
|
if (ext) {
|
||||||
features_index_add_single(vm, p + 1, ext - p - 1, offset, rb);
|
features_index_add_single(vm_ns, p + 1, ext - p - 1, offset, rb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
features_index_add_single(vm, feature_str, feature_end - feature_str, offset, false);
|
features_index_add_single(vm_ns, feature_str, feature_end - feature_str, offset, false);
|
||||||
if (ext) {
|
if (ext) {
|
||||||
features_index_add_single(vm, feature_str, ext - feature_str, offset, rb);
|
features_index_add_single(vm_ns, feature_str, ext - feature_str, offset, rb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,27 +420,31 @@ loaded_features_index_clear_i(st_data_t key, st_data_t val, st_data_t arg)
|
|||||||
void
|
void
|
||||||
rb_free_loaded_features_index(rb_vm_t *vm)
|
rb_free_loaded_features_index(rb_vm_t *vm)
|
||||||
{
|
{
|
||||||
|
/* Destructs vm->loaded_features_index directly because this is only for
|
||||||
|
the VM destruction */
|
||||||
st_foreach(vm->loaded_features_index, loaded_features_index_clear_i, 0);
|
st_foreach(vm->loaded_features_index, loaded_features_index_clear_i, 0);
|
||||||
st_free_table(vm->loaded_features_index);
|
st_free_table(vm->loaded_features_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
static st_table *
|
|
||||||
get_loaded_features_index(rb_vm_t *vm)
|
|
||||||
{
|
|
||||||
VALUE features;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!rb_ary_shared_with_p(vm->loaded_features_snapshot, vm->loaded_features)) {
|
|
||||||
|
static st_table *
|
||||||
|
get_loaded_features_index(vm_ns_t *vm_ns)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
VALUE features = CURRENT_NS_LOADED_FEATURES(vm_ns);
|
||||||
|
const VALUE snapshot = CURRENT_NS_LOADED_FEATURES_SNAPSHOT(vm_ns);
|
||||||
|
|
||||||
|
if (!rb_ary_shared_with_p(snapshot, features)) {
|
||||||
/* The sharing was broken; something (other than us in rb_provide_feature())
|
/* The sharing was broken; something (other than us in rb_provide_feature())
|
||||||
modified loaded_features. Rebuild the index. */
|
modified loaded_features. Rebuild the index. */
|
||||||
st_foreach(vm->loaded_features_index, loaded_features_index_clear_i, 0);
|
st_foreach(CURRENT_NS_LOADED_FEATURES_INDEX(vm_ns), loaded_features_index_clear_i, 0);
|
||||||
|
|
||||||
VALUE realpaths = vm->loaded_features_realpaths;
|
VALUE realpaths = CURRENT_NS_LOADED_FEATURES_REALPATHS(vm_ns);
|
||||||
VALUE realpath_map = vm->loaded_features_realpath_map;
|
VALUE realpath_map = CURRENT_NS_LOADED_FEATURES_REALPATH_MAP(vm_ns);
|
||||||
VALUE previous_realpath_map = rb_hash_dup(realpath_map);
|
VALUE previous_realpath_map = rb_hash_dup(realpath_map);
|
||||||
rb_hash_clear(realpaths);
|
rb_hash_clear(realpaths);
|
||||||
rb_hash_clear(realpath_map);
|
rb_hash_clear(realpath_map);
|
||||||
features = vm->loaded_features;
|
|
||||||
for (i = 0; i < RARRAY_LEN(features); i++) {
|
for (i = 0; i < RARRAY_LEN(features); i++) {
|
||||||
VALUE entry, as_str;
|
VALUE entry, as_str;
|
||||||
as_str = entry = rb_ary_entry(features, i);
|
as_str = entry = rb_ary_entry(features, i);
|
||||||
@ -403,11 +452,11 @@ get_loaded_features_index(rb_vm_t *vm)
|
|||||||
as_str = rb_fstring(as_str);
|
as_str = rb_fstring(as_str);
|
||||||
if (as_str != entry)
|
if (as_str != entry)
|
||||||
rb_ary_store(features, i, as_str);
|
rb_ary_store(features, i, as_str);
|
||||||
features_index_add(vm, as_str, INT2FIX(i));
|
features_index_add(vm_ns, as_str, INT2FIX(i));
|
||||||
}
|
}
|
||||||
reset_loaded_features_snapshot(vm);
|
reset_loaded_features_snapshot(vm_ns);
|
||||||
|
|
||||||
features = rb_ary_dup(vm->loaded_features_snapshot);
|
features = CURRENT_NS_LOADED_FEATURES_SNAPSHOT(vm_ns);
|
||||||
long j = RARRAY_LEN(features);
|
long j = RARRAY_LEN(features);
|
||||||
for (i = 0; i < j; i++) {
|
for (i = 0; i < j; i++) {
|
||||||
VALUE as_str = rb_ary_entry(features, i);
|
VALUE as_str = rb_ary_entry(features, i);
|
||||||
@ -421,7 +470,7 @@ get_loaded_features_index(rb_vm_t *vm)
|
|||||||
rb_hash_aset(realpath_map, as_str, realpath);
|
rb_hash_aset(realpath_map, as_str, realpath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return vm->loaded_features_index;
|
return CURRENT_NS_LOADED_FEATURES_INDEX(vm_ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* This searches `load_path` for a value such that
|
/* This searches `load_path` for a value such that
|
||||||
@ -506,7 +555,7 @@ loaded_feature_path_i(st_data_t v, st_data_t b, st_data_t f)
|
|||||||
* 'u': unsuffixed
|
* 'u': unsuffixed
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
rb_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expanded, const char **fn)
|
rb_feature_p(vm_ns_t *vm_ns, const char *feature, const char *ext, int rb, int expanded, const char **fn)
|
||||||
{
|
{
|
||||||
VALUE features, this_feature_index = Qnil, v, p, load_path = 0;
|
VALUE features, this_feature_index = Qnil, v, p, load_path = 0;
|
||||||
const char *f, *e;
|
const char *f, *e;
|
||||||
@ -527,8 +576,8 @@ rb_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expa
|
|||||||
elen = 0;
|
elen = 0;
|
||||||
type = 0;
|
type = 0;
|
||||||
}
|
}
|
||||||
features = get_loaded_features(vm);
|
features = get_loaded_features(vm_ns);
|
||||||
features_index = get_loaded_features_index(vm);
|
features_index = get_loaded_features_index(vm_ns);
|
||||||
|
|
||||||
key = feature_key(feature, strlen(feature));
|
key = feature_key(feature, strlen(feature));
|
||||||
/* We search `features` for an entry such that either
|
/* We search `features` for an entry such that either
|
||||||
@ -575,7 +624,7 @@ rb_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expa
|
|||||||
if ((n = RSTRING_LEN(v)) < len) continue;
|
if ((n = RSTRING_LEN(v)) < len) continue;
|
||||||
if (strncmp(f, feature, len) != 0) {
|
if (strncmp(f, feature, len) != 0) {
|
||||||
if (expanded) continue;
|
if (expanded) continue;
|
||||||
if (!load_path) load_path = get_expanded_load_path(vm);
|
if (!load_path) load_path = get_expanded_load_path(vm_ns);
|
||||||
if (!(p = loaded_feature_path(f, n, feature, len, type, load_path)))
|
if (!(p = loaded_feature_path(f, n, feature, len, type, load_path)))
|
||||||
continue;
|
continue;
|
||||||
expanded = 1;
|
expanded = 1;
|
||||||
@ -595,14 +644,14 @@ rb_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expa
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
loading_tbl = get_loading_table(vm);
|
loading_tbl = get_loading_table(vm_ns);
|
||||||
f = 0;
|
f = 0;
|
||||||
if (!expanded && !rb_is_absolute_path(feature)) {
|
if (!expanded && !rb_is_absolute_path(feature)) {
|
||||||
struct loaded_feature_searching fs;
|
struct loaded_feature_searching fs;
|
||||||
fs.name = feature;
|
fs.name = feature;
|
||||||
fs.len = len;
|
fs.len = len;
|
||||||
fs.type = type;
|
fs.type = type;
|
||||||
fs.load_path = load_path ? load_path : get_expanded_load_path(vm);
|
fs.load_path = load_path ? load_path : get_expanded_load_path(vm_ns);
|
||||||
fs.result = 0;
|
fs.result = 0;
|
||||||
st_foreach(loading_tbl, loaded_feature_path_i, (st_data_t)&fs);
|
st_foreach(loading_tbl, loaded_feature_path_i, (st_data_t)&fs);
|
||||||
if ((f = fs.result) != 0) {
|
if ((f = fs.result) != 0) {
|
||||||
@ -657,7 +706,7 @@ rb_provided(const char *feature)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
feature_provided(rb_vm_t *vm, const char *feature, const char **loading)
|
feature_provided(vm_ns_t *vm_ns, const char *feature, const char **loading)
|
||||||
{
|
{
|
||||||
const char *ext = strrchr(feature, '.');
|
const char *ext = strrchr(feature, '.');
|
||||||
VALUE fullpath = 0;
|
VALUE fullpath = 0;
|
||||||
@ -669,15 +718,15 @@ feature_provided(rb_vm_t *vm, const char *feature, const char **loading)
|
|||||||
}
|
}
|
||||||
if (ext && !strchr(ext, '/')) {
|
if (ext && !strchr(ext, '/')) {
|
||||||
if (IS_RBEXT(ext)) {
|
if (IS_RBEXT(ext)) {
|
||||||
if (rb_feature_p(vm, feature, ext, TRUE, FALSE, loading)) return TRUE;
|
if (rb_feature_p(vm_ns, feature, ext, TRUE, FALSE, loading)) return TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else if (IS_SOEXT(ext) || IS_DLEXT(ext)) {
|
else if (IS_SOEXT(ext) || IS_DLEXT(ext)) {
|
||||||
if (rb_feature_p(vm, feature, ext, FALSE, FALSE, loading)) return TRUE;
|
if (rb_feature_p(vm_ns, feature, ext, FALSE, FALSE, loading)) return TRUE;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (rb_feature_p(vm, feature, 0, TRUE, FALSE, loading))
|
if (rb_feature_p(vm_ns, feature, 0, TRUE, FALSE, loading))
|
||||||
return TRUE;
|
return TRUE;
|
||||||
RB_GC_GUARD(fullpath);
|
RB_GC_GUARD(fullpath);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
@ -686,35 +735,41 @@ feature_provided(rb_vm_t *vm, const char *feature, const char **loading)
|
|||||||
int
|
int
|
||||||
rb_feature_provided(const char *feature, const char **loading)
|
rb_feature_provided(const char *feature, const char **loading)
|
||||||
{
|
{
|
||||||
return feature_provided(GET_VM(), feature, loading);
|
GET_vm_ns();
|
||||||
|
return feature_provided(vm_ns, feature, loading);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rb_provide_feature(rb_vm_t *vm, VALUE feature)
|
rb_provide_feature(vm_ns_t *vm_ns, VALUE feature)
|
||||||
{
|
{
|
||||||
VALUE features;
|
VALUE features;
|
||||||
|
|
||||||
features = get_loaded_features(vm);
|
features = get_loaded_features(vm_ns);
|
||||||
if (OBJ_FROZEN(features)) {
|
if (OBJ_FROZEN(features)) {
|
||||||
rb_raise(rb_eRuntimeError,
|
rb_raise(rb_eRuntimeError,
|
||||||
"$LOADED_FEATURES is frozen; cannot append feature");
|
"$LOADED_FEATURES is frozen; cannot append feature");
|
||||||
}
|
}
|
||||||
feature = rb_fstring(feature);
|
feature = rb_fstring(feature);
|
||||||
|
|
||||||
get_loaded_features_index(vm);
|
get_loaded_features_index(vm_ns);
|
||||||
// If loaded_features and loaded_features_snapshot share the same backing
|
// If loaded_features and loaded_features_snapshot share the same backing
|
||||||
// array, pushing into it would cause the whole array to be copied.
|
// array, pushing into it would cause the whole array to be copied.
|
||||||
// To avoid this we first clear loaded_features_snapshot.
|
// To avoid this we first clear loaded_features_snapshot.
|
||||||
rb_ary_clear(vm->loaded_features_snapshot);
|
rb_ary_clear(CURRENT_NS_LOADED_FEATURES_SNAPSHOT(vm_ns));
|
||||||
rb_ary_push(features, feature);
|
rb_ary_push(features, feature);
|
||||||
features_index_add(vm, feature, INT2FIX(RARRAY_LEN(features)-1));
|
features_index_add(vm_ns, feature, INT2FIX(RARRAY_LEN(features)-1));
|
||||||
reset_loaded_features_snapshot(vm);
|
reset_loaded_features_snapshot(vm_ns);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_provide(const char *feature)
|
rb_provide(const char *feature)
|
||||||
{
|
{
|
||||||
rb_provide_feature(GET_VM(), rb_fstring_cstr(feature));
|
/*
|
||||||
|
* rb_provide() must use rb_current_namespace to store provided features
|
||||||
|
* in the current namespace's loaded_features, etc.
|
||||||
|
*/
|
||||||
|
GET_vm_ns();
|
||||||
|
rb_provide_feature(vm_ns, rb_fstring_cstr(feature));
|
||||||
}
|
}
|
||||||
|
|
||||||
NORETURN(static void load_failed(VALUE));
|
NORETURN(static void load_failed(VALUE));
|
||||||
@ -732,17 +787,34 @@ realpath_internal_cached(VALUE hash, VALUE path)
|
|||||||
return realpath;
|
return realpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct iseq_eval_in_namespace_data {
|
||||||
|
const rb_iseq_t *iseq;
|
||||||
|
bool in_builtin;
|
||||||
|
};
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
iseq_eval_in_namespace(VALUE arg)
|
||||||
|
{
|
||||||
|
struct iseq_eval_in_namespace_data *data = (struct iseq_eval_in_namespace_data *)arg;
|
||||||
|
if (rb_namespace_available() && data->in_builtin) {
|
||||||
|
return rb_iseq_eval_with_refinement(data->iseq, rb_mNamespaceRefiner);
|
||||||
|
} else {
|
||||||
|
return rb_iseq_eval(data->iseq);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
load_iseq_eval(rb_execution_context_t *ec, VALUE fname)
|
load_iseq_eval(rb_execution_context_t *ec, VALUE fname)
|
||||||
{
|
{
|
||||||
|
GET_loading_vm_ns();
|
||||||
|
const rb_namespace_t *loading_ns = rb_loading_namespace();
|
||||||
const rb_iseq_t *iseq = rb_iseq_load_iseq(fname);
|
const rb_iseq_t *iseq = rb_iseq_load_iseq(fname);
|
||||||
|
|
||||||
if (!iseq) {
|
if (!iseq) {
|
||||||
rb_execution_context_t *ec = GET_EC();
|
rb_execution_context_t *ec = GET_EC();
|
||||||
VALUE v = rb_vm_push_frame_fname(ec, fname);
|
VALUE v = rb_vm_push_frame_fname(ec, fname);
|
||||||
|
|
||||||
rb_thread_t *th = rb_ec_thread_ptr(ec);
|
VALUE realpath_map = get_loaded_features_realpath_map(vm_ns);
|
||||||
VALUE realpath_map = get_loaded_features_realpath_map(th->vm);
|
|
||||||
|
|
||||||
if (rb_ruby_prism_p()) {
|
if (rb_ruby_prism_p()) {
|
||||||
pm_parse_result_t result = { 0 };
|
pm_parse_result_t result = { 0 };
|
||||||
@ -786,13 +858,23 @@ load_iseq_eval(rb_execution_context_t *ec, VALUE fname)
|
|||||||
RB_GC_GUARD(v);
|
RB_GC_GUARD(v);
|
||||||
}
|
}
|
||||||
rb_exec_event_hook_script_compiled(ec, iseq, Qnil);
|
rb_exec_event_hook_script_compiled(ec, iseq, Qnil);
|
||||||
rb_iseq_eval(iseq);
|
|
||||||
|
if (loading_ns) {
|
||||||
|
struct iseq_eval_in_namespace_data arg = {
|
||||||
|
.iseq = iseq,
|
||||||
|
.in_builtin = NAMESPACE_BUILTIN_P(loading_ns),
|
||||||
|
};
|
||||||
|
rb_namespace_exec(loading_ns, iseq_eval_in_namespace, (VALUE)&arg);
|
||||||
|
} else {
|
||||||
|
rb_iseq_eval(iseq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline enum ruby_tag_type
|
static inline enum ruby_tag_type
|
||||||
load_wrapping(rb_execution_context_t *ec, VALUE fname, VALUE load_wrapper)
|
load_wrapping(rb_execution_context_t *ec, VALUE fname, VALUE load_wrapper)
|
||||||
{
|
{
|
||||||
enum ruby_tag_type state;
|
enum ruby_tag_type state;
|
||||||
|
rb_namespace_t *ns;
|
||||||
rb_thread_t *th = rb_ec_thread_ptr(ec);
|
rb_thread_t *th = rb_ec_thread_ptr(ec);
|
||||||
volatile VALUE wrapper = th->top_wrapper;
|
volatile VALUE wrapper = th->top_wrapper;
|
||||||
volatile VALUE self = th->top_self;
|
volatile VALUE self = th->top_self;
|
||||||
@ -803,7 +885,15 @@ load_wrapping(rb_execution_context_t *ec, VALUE fname, VALUE load_wrapper)
|
|||||||
ec->errinfo = Qnil; /* ensure */
|
ec->errinfo = Qnil; /* ensure */
|
||||||
|
|
||||||
/* load in module as toplevel */
|
/* load in module as toplevel */
|
||||||
th->top_self = rb_obj_clone(rb_vm_top_self());
|
if (IS_NAMESPACE(load_wrapper)) {
|
||||||
|
ns = rb_get_namespace_t(load_wrapper);
|
||||||
|
if (!ns->top_self) {
|
||||||
|
ns->top_self = rb_obj_clone(rb_vm_top_self());
|
||||||
|
}
|
||||||
|
th->top_self = ns->top_self;
|
||||||
|
} else {
|
||||||
|
th->top_self = rb_obj_clone(rb_vm_top_self());
|
||||||
|
}
|
||||||
th->top_wrapper = load_wrapper;
|
th->top_wrapper = load_wrapper;
|
||||||
rb_extend_object(th->top_self, th->top_wrapper);
|
rb_extend_object(th->top_self, th->top_wrapper);
|
||||||
|
|
||||||
@ -838,7 +928,9 @@ raise_load_if_failed(rb_execution_context_t *ec, enum ruby_tag_type state)
|
|||||||
static void
|
static void
|
||||||
rb_load_internal(VALUE fname, VALUE wrap)
|
rb_load_internal(VALUE fname, VALUE wrap)
|
||||||
{
|
{
|
||||||
|
VALUE namespace;
|
||||||
rb_execution_context_t *ec = GET_EC();
|
rb_execution_context_t *ec = GET_EC();
|
||||||
|
const rb_namespace_t *ns = rb_loading_namespace();
|
||||||
enum ruby_tag_type state = TAG_NONE;
|
enum ruby_tag_type state = TAG_NONE;
|
||||||
if (RTEST(wrap)) {
|
if (RTEST(wrap)) {
|
||||||
if (!RB_TYPE_P(wrap, T_MODULE)) {
|
if (!RB_TYPE_P(wrap, T_MODULE)) {
|
||||||
@ -846,6 +938,10 @@ rb_load_internal(VALUE fname, VALUE wrap)
|
|||||||
}
|
}
|
||||||
state = load_wrapping(ec, fname, wrap);
|
state = load_wrapping(ec, fname, wrap);
|
||||||
}
|
}
|
||||||
|
else if (NAMESPACE_OPTIONAL_P(ns)) {
|
||||||
|
namespace = ns->ns_object;
|
||||||
|
state = load_wrapping(ec, fname, namespace);
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
load_iseq_eval(ec, fname);
|
load_iseq_eval(ec, fname);
|
||||||
}
|
}
|
||||||
@ -874,6 +970,40 @@ rb_load_protect(VALUE fname, int wrap, int *pstate)
|
|||||||
if (state != TAG_NONE) *pstate = state;
|
if (state != TAG_NONE) *pstate = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
load_entrypoint_internal(VALUE fname, VALUE wrap)
|
||||||
|
{
|
||||||
|
VALUE path, orig_fname;
|
||||||
|
|
||||||
|
orig_fname = rb_get_path_check_to_string(fname);
|
||||||
|
fname = rb_str_encode_ospath(orig_fname);
|
||||||
|
RUBY_DTRACE_HOOK(LOAD_ENTRY, RSTRING_PTR(orig_fname));
|
||||||
|
|
||||||
|
path = rb_find_file(fname);
|
||||||
|
if (!path) {
|
||||||
|
if (!rb_file_load_ok(RSTRING_PTR(fname)))
|
||||||
|
load_failed(orig_fname);
|
||||||
|
path = fname;
|
||||||
|
}
|
||||||
|
rb_load_internal(path, wrap);
|
||||||
|
|
||||||
|
RUBY_DTRACE_HOOK(LOAD_RETURN, RSTRING_PTR(orig_fname));
|
||||||
|
|
||||||
|
return Qtrue;
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_load_entrypoint(VALUE args)
|
||||||
|
{
|
||||||
|
VALUE fname, wrap;
|
||||||
|
if (RARRAY_LEN(args) != 2) {
|
||||||
|
rb_bug("invalid arguments: %ld", RARRAY_LEN(args));
|
||||||
|
}
|
||||||
|
fname = rb_ary_entry(args, 0);
|
||||||
|
wrap = rb_ary_entry(args, 1);
|
||||||
|
return load_entrypoint_internal(fname, wrap);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* load(filename, wrap=false) -> true
|
* load(filename, wrap=false) -> true
|
||||||
@ -907,32 +1037,16 @@ rb_load_protect(VALUE fname, int wrap, int *pstate)
|
|||||||
static VALUE
|
static VALUE
|
||||||
rb_f_load(int argc, VALUE *argv, VALUE _)
|
rb_f_load(int argc, VALUE *argv, VALUE _)
|
||||||
{
|
{
|
||||||
VALUE fname, wrap, path, orig_fname;
|
VALUE fname, wrap;
|
||||||
|
|
||||||
rb_scan_args(argc, argv, "11", &fname, &wrap);
|
rb_scan_args(argc, argv, "11", &fname, &wrap);
|
||||||
|
return load_entrypoint_internal(fname, wrap);
|
||||||
orig_fname = rb_get_path_check_to_string(fname);
|
|
||||||
fname = rb_str_encode_ospath(orig_fname);
|
|
||||||
RUBY_DTRACE_HOOK(LOAD_ENTRY, RSTRING_PTR(orig_fname));
|
|
||||||
|
|
||||||
path = rb_find_file(fname);
|
|
||||||
if (!path) {
|
|
||||||
if (!rb_file_load_ok(RSTRING_PTR(fname)))
|
|
||||||
load_failed(orig_fname);
|
|
||||||
path = fname;
|
|
||||||
}
|
|
||||||
rb_load_internal(path, wrap);
|
|
||||||
|
|
||||||
RUBY_DTRACE_HOOK(LOAD_RETURN, RSTRING_PTR(orig_fname));
|
|
||||||
|
|
||||||
return Qtrue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
load_lock(rb_vm_t *vm, const char *ftptr, bool warn)
|
load_lock(vm_ns_t *vm_ns, const char *ftptr, bool warn)
|
||||||
{
|
{
|
||||||
st_data_t data;
|
st_data_t data;
|
||||||
st_table *loading_tbl = get_loading_table(vm);
|
st_table *loading_tbl = get_loading_table(vm_ns);
|
||||||
|
|
||||||
if (!st_lookup(loading_tbl, (st_data_t)ftptr, &data)) {
|
if (!st_lookup(loading_tbl, (st_data_t)ftptr, &data)) {
|
||||||
/* partial state */
|
/* partial state */
|
||||||
@ -974,11 +1088,11 @@ release_thread_shield(st_data_t *key, st_data_t *value, st_data_t done, int exis
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
load_unlock(rb_vm_t *vm, const char *ftptr, int done)
|
load_unlock(vm_ns_t *vm_ns, const char *ftptr, int done)
|
||||||
{
|
{
|
||||||
if (ftptr) {
|
if (ftptr) {
|
||||||
st_data_t key = (st_data_t)ftptr;
|
st_data_t key = (st_data_t)ftptr;
|
||||||
st_table *loading_tbl = get_loading_table(vm);
|
st_table *loading_tbl = get_loading_table(vm_ns);
|
||||||
|
|
||||||
st_update(loading_tbl, key, release_thread_shield, done);
|
st_update(loading_tbl, key, release_thread_shield, done);
|
||||||
}
|
}
|
||||||
@ -1026,9 +1140,22 @@ static VALUE rb_require_string_internal(VALUE fname, bool resurrect);
|
|||||||
VALUE
|
VALUE
|
||||||
rb_f_require(VALUE obj, VALUE fname)
|
rb_f_require(VALUE obj, VALUE fname)
|
||||||
{
|
{
|
||||||
|
// const rb_namespace_t *ns = rb_loading_namespace();
|
||||||
|
// printf("F:current loading ns: %ld\n", ns->ns_id);
|
||||||
return rb_require_string(fname);
|
return rb_require_string(fname);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_require_relative_entrypoint(VALUE fname)
|
||||||
|
{
|
||||||
|
VALUE base = rb_current_realfilepath();
|
||||||
|
if (NIL_P(base)) {
|
||||||
|
rb_loaderror("cannot infer basepath");
|
||||||
|
}
|
||||||
|
base = rb_file_dirname(base);
|
||||||
|
return rb_require_string_internal(rb_file_absolute_path(fname, base), false);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* call-seq:
|
* call-seq:
|
||||||
* require_relative(string) -> true or false
|
* require_relative(string) -> true or false
|
||||||
@ -1041,18 +1168,13 @@ rb_f_require(VALUE obj, VALUE fname)
|
|||||||
VALUE
|
VALUE
|
||||||
rb_f_require_relative(VALUE obj, VALUE fname)
|
rb_f_require_relative(VALUE obj, VALUE fname)
|
||||||
{
|
{
|
||||||
VALUE base = rb_current_realfilepath();
|
return rb_require_relative_entrypoint(fname);
|
||||||
if (NIL_P(base)) {
|
|
||||||
rb_loaderror("cannot infer basepath");
|
|
||||||
}
|
|
||||||
base = rb_file_dirname(base);
|
|
||||||
return rb_require_string_internal(rb_file_absolute_path(fname, base), false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef int (*feature_func)(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expanded, const char **fn);
|
typedef int (*feature_func)(vm_ns_t *vm_ns, const char *feature, const char *ext, int rb, int expanded, const char **fn);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_feature_p)
|
search_required(vm_ns_t *vm_ns, VALUE fname, volatile VALUE *path, feature_func rb_feature_p)
|
||||||
{
|
{
|
||||||
VALUE tmp;
|
VALUE tmp;
|
||||||
char *ext, *ftptr;
|
char *ext, *ftptr;
|
||||||
@ -1063,20 +1185,20 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
|
|||||||
ext = strrchr(ftptr = RSTRING_PTR(fname), '.');
|
ext = strrchr(ftptr = RSTRING_PTR(fname), '.');
|
||||||
if (ext && !strchr(ext, '/')) {
|
if (ext && !strchr(ext, '/')) {
|
||||||
if (IS_RBEXT(ext)) {
|
if (IS_RBEXT(ext)) {
|
||||||
if (rb_feature_p(vm, ftptr, ext, TRUE, FALSE, &loading)) {
|
if (rb_feature_p(vm_ns, ftptr, ext, TRUE, FALSE, &loading)) {
|
||||||
if (loading) *path = rb_filesystem_str_new_cstr(loading);
|
if (loading) *path = rb_filesystem_str_new_cstr(loading);
|
||||||
return 'r';
|
return 'r';
|
||||||
}
|
}
|
||||||
if ((tmp = rb_find_file(fname)) != 0) {
|
if ((tmp = rb_find_file(fname)) != 0) {
|
||||||
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
|
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
|
||||||
if (!rb_feature_p(vm, ftptr, ext, TRUE, TRUE, &loading) || loading)
|
if (!rb_feature_p(vm_ns, ftptr, ext, TRUE, TRUE, &loading) || loading)
|
||||||
*path = tmp;
|
*path = tmp;
|
||||||
return 'r';
|
return 'r';
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if (IS_SOEXT(ext)) {
|
else if (IS_SOEXT(ext)) {
|
||||||
if (rb_feature_p(vm, ftptr, ext, FALSE, FALSE, &loading)) {
|
if (rb_feature_p(vm_ns, ftptr, ext, FALSE, FALSE, &loading)) {
|
||||||
if (loading) *path = rb_filesystem_str_new_cstr(loading);
|
if (loading) *path = rb_filesystem_str_new_cstr(loading);
|
||||||
return 's';
|
return 's';
|
||||||
}
|
}
|
||||||
@ -1085,25 +1207,25 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
|
|||||||
OBJ_FREEZE(tmp);
|
OBJ_FREEZE(tmp);
|
||||||
if ((tmp = rb_find_file(tmp)) != 0) {
|
if ((tmp = rb_find_file(tmp)) != 0) {
|
||||||
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
|
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
|
||||||
if (!rb_feature_p(vm, ftptr, ext, FALSE, TRUE, &loading) || loading)
|
if (!rb_feature_p(vm_ns, ftptr, ext, FALSE, TRUE, &loading) || loading)
|
||||||
*path = tmp;
|
*path = tmp;
|
||||||
return 's';
|
return 's';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (IS_DLEXT(ext)) {
|
else if (IS_DLEXT(ext)) {
|
||||||
if (rb_feature_p(vm, ftptr, ext, FALSE, FALSE, &loading)) {
|
if (rb_feature_p(vm_ns, ftptr, ext, FALSE, FALSE, &loading)) {
|
||||||
if (loading) *path = rb_filesystem_str_new_cstr(loading);
|
if (loading) *path = rb_filesystem_str_new_cstr(loading);
|
||||||
return 's';
|
return 's';
|
||||||
}
|
}
|
||||||
if ((tmp = rb_find_file(fname)) != 0) {
|
if ((tmp = rb_find_file(fname)) != 0) {
|
||||||
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
|
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
|
||||||
if (!rb_feature_p(vm, ftptr, ext, FALSE, TRUE, &loading) || loading)
|
if (!rb_feature_p(vm_ns, ftptr, ext, FALSE, TRUE, &loading) || loading)
|
||||||
*path = tmp;
|
*path = tmp;
|
||||||
return 's';
|
return 's';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ((ft = rb_feature_p(vm, ftptr, 0, FALSE, FALSE, &loading)) == 'r') {
|
else if ((ft = rb_feature_p(vm_ns, ftptr, 0, FALSE, FALSE, &loading)) == 'r') {
|
||||||
if (loading) *path = rb_filesystem_str_new_cstr(loading);
|
if (loading) *path = rb_filesystem_str_new_cstr(loading);
|
||||||
return 'r';
|
return 'r';
|
||||||
}
|
}
|
||||||
@ -1112,7 +1234,7 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
|
|||||||
|
|
||||||
// Check if it's a statically linked extension when
|
// Check if it's a statically linked extension when
|
||||||
// not already a feature and not found as a dynamic library.
|
// not already a feature and not found as a dynamic library.
|
||||||
if (!ft && type != loadable_ext_rb && vm->static_ext_inits) {
|
if (!ft && type != loadable_ext_rb && vm_ns->vm->static_ext_inits) {
|
||||||
VALUE lookup_name = tmp;
|
VALUE lookup_name = tmp;
|
||||||
// Append ".so" if not already present so for example "etc" can find "etc.so".
|
// Append ".so" if not already present so for example "etc" can find "etc.so".
|
||||||
// We always register statically linked extensions with a ".so" extension.
|
// We always register statically linked extensions with a ".so" extension.
|
||||||
@ -1122,7 +1244,7 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
|
|||||||
rb_str_cat_cstr(lookup_name, ".so");
|
rb_str_cat_cstr(lookup_name, ".so");
|
||||||
}
|
}
|
||||||
ftptr = RSTRING_PTR(lookup_name);
|
ftptr = RSTRING_PTR(lookup_name);
|
||||||
if (st_lookup(vm->static_ext_inits, (st_data_t)ftptr, NULL)) {
|
if (st_lookup(vm_ns->vm->static_ext_inits, (st_data_t)ftptr, NULL)) {
|
||||||
*path = rb_filesystem_str_new_cstr(ftptr);
|
*path = rb_filesystem_str_new_cstr(ftptr);
|
||||||
RB_GC_GUARD(lookup_name);
|
RB_GC_GUARD(lookup_name);
|
||||||
return 's';
|
return 's';
|
||||||
@ -1134,7 +1256,7 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
|
|||||||
if (ft)
|
if (ft)
|
||||||
goto feature_present;
|
goto feature_present;
|
||||||
ftptr = RSTRING_PTR(tmp);
|
ftptr = RSTRING_PTR(tmp);
|
||||||
return rb_feature_p(vm, ftptr, 0, FALSE, TRUE, 0);
|
return rb_feature_p(vm_ns, ftptr, 0, FALSE, TRUE, 0);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (ft) {
|
if (ft) {
|
||||||
@ -1143,7 +1265,7 @@ search_required(rb_vm_t *vm, VALUE fname, volatile VALUE *path, feature_func rb_
|
|||||||
/* fall through */
|
/* fall through */
|
||||||
case loadable_ext_rb:
|
case loadable_ext_rb:
|
||||||
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
|
ext = strrchr(ftptr = RSTRING_PTR(tmp), '.');
|
||||||
if (rb_feature_p(vm, ftptr, ext, type == loadable_ext_rb, TRUE, &loading) && !loading)
|
if (rb_feature_p(vm_ns, ftptr, ext, type == loadable_ext_rb, TRUE, &loading) && !loading)
|
||||||
break;
|
break;
|
||||||
*path = tmp;
|
*path = tmp;
|
||||||
}
|
}
|
||||||
@ -1161,10 +1283,15 @@ load_failed(VALUE fname)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
load_ext(VALUE path)
|
load_ext(VALUE path, VALUE fname)
|
||||||
{
|
{
|
||||||
|
VALUE loaded = path;
|
||||||
|
GET_loading_vm_ns();
|
||||||
|
if (NAMESPACE_USER_P(vm_ns->ns)) {
|
||||||
|
loaded = rb_namespace_local_extension(vm_ns->ns->ns_object, fname, path);
|
||||||
|
}
|
||||||
rb_scope_visibility_set(METHOD_VISI_PUBLIC);
|
rb_scope_visibility_set(METHOD_VISI_PUBLIC);
|
||||||
return (VALUE)dln_load(RSTRING_PTR(path));
|
return (VALUE)dln_load_feature(RSTRING_PTR(loaded), RSTRING_PTR(fname));
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -1181,7 +1308,7 @@ run_static_ext_init(rb_vm_t *vm, const char *feature)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
no_feature_p(rb_vm_t *vm, const char *feature, const char *ext, int rb, int expanded, const char **fn)
|
no_feature_p(vm_ns_t *vm_ns, const char *feature, const char *ext, int rb, int expanded, const char **fn)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1193,10 +1320,11 @@ rb_resolve_feature_path(VALUE klass, VALUE fname)
|
|||||||
VALUE path;
|
VALUE path;
|
||||||
int found;
|
int found;
|
||||||
VALUE sym;
|
VALUE sym;
|
||||||
|
GET_loading_vm_ns();
|
||||||
|
|
||||||
fname = rb_get_path(fname);
|
fname = rb_get_path(fname);
|
||||||
path = rb_str_encode_ospath(fname);
|
path = rb_str_encode_ospath(fname);
|
||||||
found = search_required(GET_VM(), path, &path, no_feature_p);
|
found = search_required(vm_ns, path, &path, no_feature_p);
|
||||||
|
|
||||||
switch (found) {
|
switch (found) {
|
||||||
case 'r':
|
case 'r':
|
||||||
@ -1231,6 +1359,20 @@ rb_ext_ractor_safe(bool flag)
|
|||||||
GET_THREAD()->ext_config.ractor_safe = flag;
|
GET_THREAD()->ext_config.ractor_safe = flag;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct rb_vm_call_cfunc2_data {
|
||||||
|
VALUE recv;
|
||||||
|
VALUE arg1;
|
||||||
|
VALUE arg2;
|
||||||
|
VALUE block_handler;
|
||||||
|
VALUE filename;
|
||||||
|
};
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
call_load_ext_in_ns(VALUE data){
|
||||||
|
struct rb_vm_call_cfunc2_data *arg = (struct rb_vm_call_cfunc2_data *)data;
|
||||||
|
return rb_vm_call_cfunc2(arg->recv, load_ext, arg->arg1, arg->arg2, arg->block_handler, arg->filename);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* returns
|
* returns
|
||||||
* 0: if already loaded (false)
|
* 0: if already loaded (false)
|
||||||
@ -1250,13 +1392,14 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
|
|||||||
th->top_wrapper, th->top_self, ec->errinfo,
|
th->top_wrapper, th->top_self, ec->errinfo,
|
||||||
ec,
|
ec,
|
||||||
};
|
};
|
||||||
|
GET_loading_vm_ns();
|
||||||
enum ruby_tag_type state;
|
enum ruby_tag_type state;
|
||||||
char *volatile ftptr = 0;
|
char *volatile ftptr = 0;
|
||||||
VALUE path;
|
VALUE path;
|
||||||
volatile VALUE saved_path;
|
volatile VALUE saved_path;
|
||||||
volatile VALUE realpath = 0;
|
volatile VALUE realpath = 0;
|
||||||
VALUE realpaths = get_loaded_features_realpaths(th->vm);
|
VALUE realpaths = get_loaded_features_realpaths(vm_ns);
|
||||||
VALUE realpath_map = get_loaded_features_realpath_map(th->vm);
|
VALUE realpath_map = get_loaded_features_realpath_map(vm_ns);
|
||||||
volatile bool reset_ext_config = false;
|
volatile bool reset_ext_config = false;
|
||||||
struct rb_ext_config prev_ext_config;
|
struct rb_ext_config prev_ext_config;
|
||||||
|
|
||||||
@ -1272,12 +1415,12 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
|
|||||||
int found;
|
int found;
|
||||||
|
|
||||||
RUBY_DTRACE_HOOK(FIND_REQUIRE_ENTRY, RSTRING_PTR(fname));
|
RUBY_DTRACE_HOOK(FIND_REQUIRE_ENTRY, RSTRING_PTR(fname));
|
||||||
found = search_required(th->vm, path, &saved_path, rb_feature_p);
|
found = search_required(vm_ns, path, &saved_path, rb_feature_p);
|
||||||
RUBY_DTRACE_HOOK(FIND_REQUIRE_RETURN, RSTRING_PTR(fname));
|
RUBY_DTRACE_HOOK(FIND_REQUIRE_RETURN, RSTRING_PTR(fname));
|
||||||
path = saved_path;
|
path = saved_path;
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
if (!path || !(ftptr = load_lock(th->vm, RSTRING_PTR(path), warn))) {
|
if (!path || !(ftptr = load_lock(vm_ns, RSTRING_PTR(path), warn))) {
|
||||||
result = 0;
|
result = 0;
|
||||||
}
|
}
|
||||||
else if (!*ftptr) {
|
else if (!*ftptr) {
|
||||||
@ -1293,15 +1436,30 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
|
|||||||
else {
|
else {
|
||||||
switch (found) {
|
switch (found) {
|
||||||
case 'r':
|
case 'r':
|
||||||
load_iseq_eval(saved.ec, path);
|
// iseq_eval_in_namespace will be called with the loading namespace eventually
|
||||||
|
if (NAMESPACE_OPTIONAL_P(vm_ns->ns)) {
|
||||||
|
// check with NAMESPACE_OPTIONAL_P (not NAMESPACE_USER_P) for NS1::xxx naming
|
||||||
|
// it is not expected for the main namespace
|
||||||
|
load_wrapping(saved.ec, path, vm_ns->ns->ns_object);
|
||||||
|
} else {
|
||||||
|
load_iseq_eval(saved.ec, path);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 's':
|
case 's':
|
||||||
|
// the loading namespace must be set to the current namespace before calling load_ext
|
||||||
reset_ext_config = true;
|
reset_ext_config = true;
|
||||||
ext_config_push(th, &prev_ext_config);
|
ext_config_push(th, &prev_ext_config);
|
||||||
handle = rb_vm_call_cfunc(rb_vm_top_self(), load_ext,
|
struct rb_vm_call_cfunc2_data arg = {
|
||||||
path, VM_BLOCK_HANDLER_NONE, path);
|
.recv = rb_vm_top_self(),
|
||||||
rb_hash_aset(ruby_dln_libmap, path, SVALUE2NUM((SIGNED_VALUE)handle));
|
.arg1 = path,
|
||||||
|
.arg2 = fname,
|
||||||
|
.block_handler = VM_BLOCK_HANDLER_NONE,
|
||||||
|
.filename = path,
|
||||||
|
};
|
||||||
|
handle = rb_namespace_exec(vm_ns->ns, call_load_ext_in_ns, (VALUE)&arg);
|
||||||
|
rb_hash_aset(CURRENT_NS_RUBY_DLN_LIBMAP(vm_ns, ruby_dln_libmap), path,
|
||||||
|
SVALUE2NUM((SIGNED_VALUE)handle));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
result = TAG_RETURN;
|
result = TAG_RETURN;
|
||||||
@ -1317,7 +1475,7 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
|
|||||||
if (reset_ext_config) ext_config_pop(th2, &prev_ext_config);
|
if (reset_ext_config) ext_config_pop(th2, &prev_ext_config);
|
||||||
|
|
||||||
path = saved_path;
|
path = saved_path;
|
||||||
if (ftptr) load_unlock(th2->vm, RSTRING_PTR(path), !state);
|
if (ftptr) load_unlock(vm_ns, RSTRING_PTR(path), !state);
|
||||||
|
|
||||||
if (state) {
|
if (state) {
|
||||||
if (state == TAG_FATAL || state == TAG_THROW) {
|
if (state == TAG_FATAL || state == TAG_THROW) {
|
||||||
@ -1343,7 +1501,7 @@ require_internal(rb_execution_context_t *ec, VALUE fname, int exception, bool wa
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (result == TAG_RETURN) {
|
if (result == TAG_RETURN) {
|
||||||
rb_provide_feature(th2->vm, path);
|
rb_provide_feature(vm_ns, path);
|
||||||
VALUE real = realpath;
|
VALUE real = realpath;
|
||||||
if (real) {
|
if (real) {
|
||||||
real = rb_fstring(real);
|
real = rb_fstring(real);
|
||||||
@ -1442,15 +1600,15 @@ void
|
|||||||
ruby_init_ext(const char *name, void (*init)(void))
|
ruby_init_ext(const char *name, void (*init)(void))
|
||||||
{
|
{
|
||||||
st_table *inits_table;
|
st_table *inits_table;
|
||||||
rb_vm_t *vm = GET_VM();
|
GET_loading_vm_ns();
|
||||||
|
|
||||||
if (feature_provided(vm, name, 0))
|
if (feature_provided(vm_ns, name, 0))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
inits_table = vm->static_ext_inits;
|
inits_table = vm_ns->vm->static_ext_inits;
|
||||||
if (!inits_table) {
|
if (!inits_table) {
|
||||||
inits_table = st_init_strtable();
|
inits_table = st_init_strtable();
|
||||||
vm->static_ext_inits = inits_table;
|
vm_ns->vm->static_ext_inits = inits_table;
|
||||||
}
|
}
|
||||||
st_update(inits_table, (st_data_t)name, register_init_ext, (st_data_t)init);
|
st_update(inits_table, (st_data_t)name, register_init_ext, (st_data_t)init);
|
||||||
}
|
}
|
||||||
@ -1595,6 +1753,7 @@ rb_ext_resolve_symbol(const char* fname, const char* symbol)
|
|||||||
VALUE path;
|
VALUE path;
|
||||||
char *ext;
|
char *ext;
|
||||||
VALUE fname_str = rb_str_new_cstr(fname);
|
VALUE fname_str = rb_str_new_cstr(fname);
|
||||||
|
GET_loading_vm_ns();
|
||||||
|
|
||||||
resolved = rb_resolve_feature_path((VALUE)NULL, fname_str);
|
resolved = rb_resolve_feature_path((VALUE)NULL, fname_str);
|
||||||
if (NIL_P(resolved)) {
|
if (NIL_P(resolved)) {
|
||||||
@ -1602,7 +1761,7 @@ rb_ext_resolve_symbol(const char* fname, const char* symbol)
|
|||||||
if (!ext || !IS_SOEXT(ext)) {
|
if (!ext || !IS_SOEXT(ext)) {
|
||||||
rb_str_cat_cstr(fname_str, ".so");
|
rb_str_cat_cstr(fname_str, ".so");
|
||||||
}
|
}
|
||||||
if (rb_feature_p(GET_VM(), fname, 0, FALSE, FALSE, 0)) {
|
if (rb_feature_p(vm_ns, fname, 0, FALSE, FALSE, 0)) {
|
||||||
return dln_symbol(NULL, symbol);
|
return dln_symbol(NULL, symbol);
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1611,7 +1770,7 @@ rb_ext_resolve_symbol(const char* fname, const char* symbol)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
path = rb_ary_entry(resolved, 1);
|
path = rb_ary_entry(resolved, 1);
|
||||||
handle = rb_hash_lookup(ruby_dln_libmap, path);
|
handle = rb_hash_lookup(CURRENT_NS_RUBY_DLN_LIBMAP(vm_ns, ruby_dln_libmap), path);
|
||||||
if (NIL_P(handle)) {
|
if (NIL_P(handle)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1626,6 +1785,7 @@ Init_load(void)
|
|||||||
ID id_load_path = rb_intern2(var_load_path, sizeof(var_load_path)-1);
|
ID id_load_path = rb_intern2(var_load_path, sizeof(var_load_path)-1);
|
||||||
|
|
||||||
rb_define_hooked_variable(var_load_path, (VALUE*)vm, load_path_getter, rb_gvar_readonly_setter);
|
rb_define_hooked_variable(var_load_path, (VALUE*)vm, load_path_getter, rb_gvar_readonly_setter);
|
||||||
|
rb_gvar_namespace_ready(var_load_path);
|
||||||
rb_alias_variable(rb_intern_const("$-I"), id_load_path);
|
rb_alias_variable(rb_intern_const("$-I"), id_load_path);
|
||||||
rb_alias_variable(rb_intern_const("$LOAD_PATH"), id_load_path);
|
rb_alias_variable(rb_intern_const("$LOAD_PATH"), id_load_path);
|
||||||
vm->load_path = rb_ary_new();
|
vm->load_path = rb_ary_new();
|
||||||
@ -1635,7 +1795,9 @@ Init_load(void)
|
|||||||
rb_define_singleton_method(vm->load_path, "resolve_feature_path", rb_resolve_feature_path, 1);
|
rb_define_singleton_method(vm->load_path, "resolve_feature_path", rb_resolve_feature_path, 1);
|
||||||
|
|
||||||
rb_define_virtual_variable("$\"", get_LOADED_FEATURES, 0);
|
rb_define_virtual_variable("$\"", get_LOADED_FEATURES, 0);
|
||||||
rb_define_virtual_variable("$LOADED_FEATURES", get_LOADED_FEATURES, 0);
|
rb_gvar_namespace_ready("$\"");
|
||||||
|
rb_define_virtual_variable("$LOADED_FEATURES", get_LOADED_FEATURES, 0); // TODO: rb_alias_variable ?
|
||||||
|
rb_gvar_namespace_ready("$LOADED_FEATURES");
|
||||||
vm->loaded_features = rb_ary_new();
|
vm->loaded_features = rb_ary_new();
|
||||||
vm->loaded_features_snapshot = rb_ary_hidden_new(0);
|
vm->loaded_features_snapshot = rb_ary_hidden_new(0);
|
||||||
vm->loaded_features_index = st_init_numtable();
|
vm->loaded_features_index = st_init_numtable();
|
||||||
|
@ -531,7 +531,7 @@ w_extended(VALUE klass, struct dump_arg *arg, int check)
|
|||||||
klass = RCLASS_SUPER(klass);
|
klass = RCLASS_SUPER(klass);
|
||||||
}
|
}
|
||||||
while (BUILTIN_TYPE(klass) == T_ICLASS) {
|
while (BUILTIN_TYPE(klass) == T_ICLASS) {
|
||||||
if (!FL_TEST(klass, RICLASS_IS_ORIGIN) ||
|
if (!RICLASS_IS_ORIGIN_P(klass) ||
|
||||||
BUILTIN_TYPE(RBASIC(klass)->klass) != T_MODULE) {
|
BUILTIN_TYPE(RBASIC(klass)->klass) != T_MODULE) {
|
||||||
VALUE path = rb_class_name(RBASIC(klass)->klass);
|
VALUE path = rb_class_name(RBASIC(klass)->klass);
|
||||||
w_byte(TYPE_EXTENDED, arg);
|
w_byte(TYPE_EXTENDED, arg);
|
||||||
|
3
method.h
3
method.h
@ -197,6 +197,7 @@ struct rb_method_definition_struct {
|
|||||||
|
|
||||||
ID original_id;
|
ID original_id;
|
||||||
uintptr_t method_serial;
|
uintptr_t method_serial;
|
||||||
|
const rb_namespace_t *ns;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rb_id_table;
|
struct rb_id_table;
|
||||||
@ -247,6 +248,7 @@ const rb_callable_method_entry_t *rb_method_entry_complement_defined_class(const
|
|||||||
void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src);
|
void rb_method_entry_copy(rb_method_entry_t *dst, const rb_method_entry_t *src);
|
||||||
|
|
||||||
void rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me);
|
void rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me);
|
||||||
|
void rb_method_table_insert0(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me, bool iclass_shared_mtbl);
|
||||||
|
|
||||||
void rb_scope_visibility_set(rb_method_visibility_t);
|
void rb_scope_visibility_set(rb_method_visibility_t);
|
||||||
|
|
||||||
@ -254,5 +256,6 @@ VALUE rb_unnamed_parameters(int arity);
|
|||||||
|
|
||||||
void rb_clear_method_cache(VALUE klass_or_module, ID mid);
|
void rb_clear_method_cache(VALUE klass_or_module, ID mid);
|
||||||
void rb_clear_all_refinement_method_cache(void);
|
void rb_clear_all_refinement_method_cache(void);
|
||||||
|
void rb_invalidate_method_caches(struct rb_id_table *cm_tbl, struct rb_id_table *cc_tbl);
|
||||||
|
|
||||||
#endif /* RUBY_METHOD_H */
|
#endif /* RUBY_METHOD_H */
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "internal/array.h"
|
#include "internal/array.h"
|
||||||
|
#include "internal/eval.h"
|
||||||
#include "iseq.h"
|
#include "iseq.h"
|
||||||
#include "vm_core.h"
|
#include "vm_core.h"
|
||||||
#include "builtin.h"
|
#include "builtin.h"
|
||||||
@ -95,9 +96,23 @@ builtin_iseq_load(const char *feature_name, const struct rb_builtin_function *ta
|
|||||||
return iseq;
|
return iseq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table)
|
||||||
|
{
|
||||||
|
const rb_iseq_t *iseq = builtin_iseq_load(feature_name, table);
|
||||||
|
rb_namespace_enable_builtin();
|
||||||
|
rb_iseq_eval_with_refinement(iseq, rb_mNamespaceRefiner);
|
||||||
|
rb_namespace_disable_builtin();
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table)
|
rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table)
|
||||||
{
|
{
|
||||||
const rb_iseq_t *iseq = builtin_iseq_load(feature_name, table);
|
const rb_iseq_t *iseq;
|
||||||
rb_iseq_eval(iseq);
|
if (rb_namespace_available() && rb_mNamespaceRefiner) {
|
||||||
|
load_with_builtin_functions(feature_name, table);
|
||||||
|
} else {
|
||||||
|
iseq = builtin_iseq_load(feature_name, table);
|
||||||
|
rb_iseq_eval(iseq);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
1139
namespace.c
Normal file
1139
namespace.c
Normal file
File diff suppressed because it is too large
Load Diff
21
object.c
21
object.c
@ -121,7 +121,7 @@ rb_obj_reveal(VALUE obj, VALUE klass)
|
|||||||
VALUE
|
VALUE
|
||||||
rb_class_allocate_instance(VALUE klass)
|
rb_class_allocate_instance(VALUE klass)
|
||||||
{
|
{
|
||||||
uint32_t index_tbl_num_entries = RCLASS_EXT(klass)->max_iv_count;
|
uint32_t index_tbl_num_entries = RCLASS_MAX_IV_COUNT(klass);
|
||||||
|
|
||||||
size_t size = rb_obj_embedded_size(index_tbl_num_entries);
|
size_t size = rb_obj_embedded_size(index_tbl_num_entries);
|
||||||
if (!rb_gc_size_allocatable_p(size)) {
|
if (!rb_gc_size_allocatable_p(size)) {
|
||||||
@ -2097,7 +2097,7 @@ rb_class_initialize(int argc, VALUE *argv, VALUE klass)
|
|||||||
rb_raise(rb_eTypeError, "can't inherit uninitialized class");
|
rb_raise(rb_eTypeError, "can't inherit uninitialized class");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RCLASS_SET_SUPER(klass, super);
|
rb_class_set_super(klass, super);
|
||||||
rb_make_metaclass(klass, RBASIC(super)->klass);
|
rb_make_metaclass(klass, RBASIC(super)->klass);
|
||||||
rb_class_inherited(super, klass);
|
rb_class_inherited(super, klass);
|
||||||
rb_mod_initialize_exec(klass);
|
rb_mod_initialize_exec(klass);
|
||||||
@ -2269,17 +2269,21 @@ rb_class_superclass(VALUE klass)
|
|||||||
RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS));
|
RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS));
|
||||||
|
|
||||||
VALUE super = RCLASS_SUPER(klass);
|
VALUE super = RCLASS_SUPER(klass);
|
||||||
|
VALUE *superclasses;
|
||||||
|
size_t superclasses_depth;
|
||||||
|
|
||||||
if (!super) {
|
if (!super) {
|
||||||
if (klass == rb_cBasicObject) return Qnil;
|
if (klass == rb_cBasicObject) return Qnil;
|
||||||
rb_raise(rb_eTypeError, "uninitialized class");
|
rb_raise(rb_eTypeError, "uninitialized class");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!RCLASS_SUPERCLASS_DEPTH(klass)) {
|
superclasses_depth = RCLASS_SUPERCLASS_DEPTH(klass);
|
||||||
|
if (!superclasses_depth) {
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
super = RCLASS_SUPERCLASSES(klass)[RCLASS_SUPERCLASS_DEPTH(klass) - 1];
|
superclasses = RCLASS_SUPERCLASSES(klass);
|
||||||
|
super = superclasses[superclasses_depth - 1];
|
||||||
RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS));
|
RUBY_ASSERT(RB_TYPE_P(klass, T_CLASS));
|
||||||
return super;
|
return super;
|
||||||
}
|
}
|
||||||
@ -2288,7 +2292,7 @@ rb_class_superclass(VALUE klass)
|
|||||||
VALUE
|
VALUE
|
||||||
rb_class_get_superclass(VALUE klass)
|
rb_class_get_superclass(VALUE klass)
|
||||||
{
|
{
|
||||||
return RCLASS(klass)->super;
|
return RCLASS_SUPER(klass);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char bad_instance_name[] = "'%1$s' is not allowed as an instance variable name";
|
static const char bad_instance_name[] = "'%1$s' is not allowed as an instance variable name";
|
||||||
@ -4599,6 +4603,13 @@ InitVM_Object(void)
|
|||||||
rb_define_method(rb_cModule, "deprecate_constant", rb_mod_deprecate_constant, -1); /* in variable.c */
|
rb_define_method(rb_cModule, "deprecate_constant", rb_mod_deprecate_constant, -1); /* in variable.c */
|
||||||
rb_define_method(rb_cModule, "singleton_class?", rb_mod_singleton_p, 0);
|
rb_define_method(rb_cModule, "singleton_class?", rb_mod_singleton_p, 0);
|
||||||
|
|
||||||
|
// TODO: only for development
|
||||||
|
rb_define_method(rb_cModule, "debug_duplicate_classext", rb_class_debug_duplicate_classext, 1);
|
||||||
|
rb_define_method(rb_cModule, "debug_dump_all_classext", rb_class_debug_dump_all_classext, 0);
|
||||||
|
rb_define_method(rb_cModule, "debug_dump_all_classext_super", rb_class_debug_dump_all_classext_super, 1);
|
||||||
|
|
||||||
|
rb_define_method(rb_cBasicObject, "debug_print_module", rb_class_debug_print_module, 0);
|
||||||
|
|
||||||
rb_define_method(rb_singleton_class(rb_cClass), "allocate", rb_class_alloc_m, 0);
|
rb_define_method(rb_singleton_class(rb_cClass), "allocate", rb_class_alloc_m, 0);
|
||||||
rb_define_method(rb_cClass, "allocate", rb_class_alloc_m, 0);
|
rb_define_method(rb_cClass, "allocate", rb_class_alloc_m, 0);
|
||||||
rb_define_method(rb_cClass, "new", rb_class_new_instance_pass_kw, -1);
|
rb_define_method(rb_cClass, "new", rb_class_new_instance_pass_kw, -1);
|
||||||
|
20
proc.c
20
proc.c
@ -678,6 +678,7 @@ cfunc_proc_new(VALUE klass, VALUE ifunc)
|
|||||||
{
|
{
|
||||||
rb_proc_t *proc;
|
rb_proc_t *proc;
|
||||||
cfunc_proc_t *sproc;
|
cfunc_proc_t *sproc;
|
||||||
|
const rb_namespace_t *ns = rb_current_namespace();
|
||||||
VALUE procval = TypedData_Make_Struct(klass, cfunc_proc_t, &proc_data_type, sproc);
|
VALUE procval = TypedData_Make_Struct(klass, cfunc_proc_t, &proc_data_type, sproc);
|
||||||
VALUE *ep;
|
VALUE *ep;
|
||||||
|
|
||||||
@ -692,6 +693,7 @@ cfunc_proc_new(VALUE klass, VALUE ifunc)
|
|||||||
|
|
||||||
/* self? */
|
/* self? */
|
||||||
RB_OBJ_WRITE(procval, &proc->block.as.captured.code.ifunc, ifunc);
|
RB_OBJ_WRITE(procval, &proc->block.as.captured.code.ifunc, ifunc);
|
||||||
|
proc->ns = ns;
|
||||||
proc->is_lambda = TRUE;
|
proc->is_lambda = TRUE;
|
||||||
return procval;
|
return procval;
|
||||||
}
|
}
|
||||||
@ -727,6 +729,7 @@ sym_proc_new(VALUE klass, VALUE sym)
|
|||||||
GetProcPtr(procval, proc);
|
GetProcPtr(procval, proc);
|
||||||
|
|
||||||
vm_block_type_set(&proc->block, block_type_symbol);
|
vm_block_type_set(&proc->block, block_type_symbol);
|
||||||
|
// No namespace specified: similar to built-in methods
|
||||||
proc->is_lambda = TRUE;
|
proc->is_lambda = TRUE;
|
||||||
RB_OBJ_WRITE(procval, &proc->block.as.symbol, sym);
|
RB_OBJ_WRITE(procval, &proc->block.as.symbol, sym);
|
||||||
return procval;
|
return procval;
|
||||||
@ -2006,6 +2009,21 @@ method_owner(VALUE obj)
|
|||||||
return data->owner;
|
return data->owner;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
method_namespace(VALUE obj)
|
||||||
|
{
|
||||||
|
struct METHOD *data;
|
||||||
|
const rb_namespace_t *ns;
|
||||||
|
|
||||||
|
TypedData_Get_Struct(obj, struct METHOD, &method_data_type, data);
|
||||||
|
ns = data->me->def->ns;
|
||||||
|
if (!ns) return Qfalse;
|
||||||
|
if (ns->ns_object) return ns->ns_object;
|
||||||
|
// This should not happen
|
||||||
|
rb_bug("Unexpected namespace on the method definition: %p", ns);
|
||||||
|
return Qtrue;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_method_name_error(VALUE klass, VALUE str)
|
rb_method_name_error(VALUE klass, VALUE str)
|
||||||
{
|
{
|
||||||
@ -4466,6 +4484,8 @@ Init_Proc(void)
|
|||||||
rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1);
|
rb_define_method(rb_mKernel, "public_method", rb_obj_public_method, 1);
|
||||||
rb_define_method(rb_mKernel, "singleton_method", rb_obj_singleton_method, 1);
|
rb_define_method(rb_mKernel, "singleton_method", rb_obj_singleton_method, 1);
|
||||||
|
|
||||||
|
rb_define_method(rb_cMethod, "namespace", method_namespace, 0);
|
||||||
|
|
||||||
/* UnboundMethod */
|
/* UnboundMethod */
|
||||||
rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject);
|
rb_cUnboundMethod = rb_define_class("UnboundMethod", rb_cObject);
|
||||||
rb_undef_alloc_func(rb_cUnboundMethod);
|
rb_undef_alloc_func(rb_cUnboundMethod);
|
||||||
|
3
ruby.c
3
ruby.c
@ -1824,6 +1824,9 @@ ruby_opt_init(ruby_cmdline_options_t *opt)
|
|||||||
|
|
||||||
ruby_init_prelude();
|
ruby_init_prelude();
|
||||||
|
|
||||||
|
if (rb_namespace_available())
|
||||||
|
rb_initialize_main_namespace();
|
||||||
|
|
||||||
// Initialize JITs after prelude because JITing prelude is typically not optimal.
|
// Initialize JITs after prelude because JITing prelude is typically not optimal.
|
||||||
#if USE_YJIT
|
#if USE_YJIT
|
||||||
rb_yjit_init(opt->yjit);
|
rb_yjit_init(opt->yjit);
|
||||||
|
12
shape.c
12
shape.c
@ -656,7 +656,7 @@ rb_shape_transition_remove_ivar(VALUE obj, ID id, VALUE *removed)
|
|||||||
switch(BUILTIN_TYPE(obj)) {
|
switch(BUILTIN_TYPE(obj)) {
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
fields = RCLASS_FIELDS(obj);
|
fields = RCLASS_PRIME_FIELDS(obj);
|
||||||
break;
|
break;
|
||||||
case T_OBJECT:
|
case T_OBJECT:
|
||||||
fields = ROBJECT_FIELDS(obj);
|
fields = ROBJECT_FIELDS(obj);
|
||||||
@ -803,7 +803,7 @@ shape_get_next(rb_shape_t *shape, VALUE obj, ID id, bool emit_warnings)
|
|||||||
|
|
||||||
if (BUILTIN_TYPE(obj) == T_OBJECT) {
|
if (BUILTIN_TYPE(obj) == T_OBJECT) {
|
||||||
VALUE klass = rb_obj_class(obj);
|
VALUE klass = rb_obj_class(obj);
|
||||||
allow_new_shape = RCLASS_EXT(klass)->variation_count < SHAPE_MAX_VARIATIONS;
|
allow_new_shape = RCLASS_VARIATION_COUNT(klass) < SHAPE_MAX_VARIATIONS;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool variation_created = false;
|
bool variation_created = false;
|
||||||
@ -812,14 +812,14 @@ shape_get_next(rb_shape_t *shape, VALUE obj, ID id, bool emit_warnings)
|
|||||||
// Check if we should update max_iv_count on the object's class
|
// Check if we should update max_iv_count on the object's class
|
||||||
if (BUILTIN_TYPE(obj) == T_OBJECT) {
|
if (BUILTIN_TYPE(obj) == T_OBJECT) {
|
||||||
VALUE klass = rb_obj_class(obj);
|
VALUE klass = rb_obj_class(obj);
|
||||||
if (new_shape->next_field_index > RCLASS_EXT(klass)->max_iv_count) {
|
if (new_shape->next_field_index > RCLASS_MAX_IV_COUNT(klass)) {
|
||||||
RCLASS_EXT(klass)->max_iv_count = new_shape->next_field_index;
|
RCLASS_SET_MAX_IV_COUNT(klass, new_shape->next_field_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (variation_created) {
|
if (variation_created) {
|
||||||
RCLASS_EXT(klass)->variation_count++;
|
RCLASS_VARIATION_COUNT(klass)++;
|
||||||
if (emit_warnings && rb_warning_category_enabled_p(RB_WARN_CATEGORY_PERFORMANCE)) {
|
if (emit_warnings && rb_warning_category_enabled_p(RB_WARN_CATEGORY_PERFORMANCE)) {
|
||||||
if (RCLASS_EXT(klass)->variation_count >= SHAPE_MAX_VARIATIONS) {
|
if (RCLASS_VARIATION_COUNT(klass) >= SHAPE_MAX_VARIATIONS) {
|
||||||
rb_category_warn(
|
rb_category_warn(
|
||||||
RB_WARN_CATEGORY_PERFORMANCE,
|
RB_WARN_CATEGORY_PERFORMANCE,
|
||||||
"The class %"PRIsVALUE" reached %d shape variations, instance variables accesses will be slower and memory usage increased.\n"
|
"The class %"PRIsVALUE" reached %d shape variations, instance variables accesses will be slower and memory usage increased.\n"
|
||||||
|
@ -7,10 +7,17 @@ describe "Module#ancestors" do
|
|||||||
ModuleSpecs.ancestors.should == [ModuleSpecs]
|
ModuleSpecs.ancestors.should == [ModuleSpecs]
|
||||||
ModuleSpecs::Basic.ancestors.should == [ModuleSpecs::Basic]
|
ModuleSpecs::Basic.ancestors.should == [ModuleSpecs::Basic]
|
||||||
ModuleSpecs::Super.ancestors.should == [ModuleSpecs::Super, ModuleSpecs::Basic]
|
ModuleSpecs::Super.ancestors.should == [ModuleSpecs::Super, ModuleSpecs::Basic]
|
||||||
ModuleSpecs.without_test_modules(ModuleSpecs::Parent.ancestors).should ==
|
if Namespace.enabled?
|
||||||
[ModuleSpecs::Parent, Object, Kernel, BasicObject]
|
ModuleSpecs.without_test_modules(ModuleSpecs::Parent.ancestors).should ==
|
||||||
ModuleSpecs.without_test_modules(ModuleSpecs::Child.ancestors).should ==
|
[ModuleSpecs::Parent, Object, Namespace::Loader, Kernel, BasicObject]
|
||||||
[ModuleSpecs::Child, ModuleSpecs::Super, ModuleSpecs::Basic, ModuleSpecs::Parent, Object, Kernel, BasicObject]
|
ModuleSpecs.without_test_modules(ModuleSpecs::Child.ancestors).should ==
|
||||||
|
[ModuleSpecs::Child, ModuleSpecs::Super, ModuleSpecs::Basic, ModuleSpecs::Parent, Object, Namespace::Loader, Kernel, BasicObject]
|
||||||
|
else
|
||||||
|
ModuleSpecs.without_test_modules(ModuleSpecs::Parent.ancestors).should ==
|
||||||
|
[ModuleSpecs::Parent, Object, Kernel, BasicObject]
|
||||||
|
ModuleSpecs.without_test_modules(ModuleSpecs::Child.ancestors).should ==
|
||||||
|
[ModuleSpecs::Child, ModuleSpecs::Super, ModuleSpecs::Basic, ModuleSpecs::Parent, Object, Kernel, BasicObject]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
it "returns only modules and classes" do
|
it "returns only modules and classes" do
|
||||||
|
97
test/-ext-/namespace/test_load_ext.rb
Normal file
97
test/-ext-/namespace/test_load_ext.rb
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
require 'test/unit'
|
||||||
|
|
||||||
|
class Test_Load_Extensions < Test::Unit::TestCase
|
||||||
|
ENV_ENABLE_NAMESPACE = {'RUBY_NAMESPACE' => '1'}
|
||||||
|
|
||||||
|
def test_load_extension
|
||||||
|
pend
|
||||||
|
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||||
|
begin;
|
||||||
|
require '-test-/namespace/yay1'
|
||||||
|
assert_equal "1.0.0", Yay.version
|
||||||
|
assert_equal "yay", Yay.yay
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_extension_contamination_in_global
|
||||||
|
pend
|
||||||
|
assert_separately([], "#{<<~"begin;"}\n#{<<~'end;'}", ignore_stderr: true)
|
||||||
|
begin;
|
||||||
|
require '-test-/namespace/yay1'
|
||||||
|
yay1 = Yay
|
||||||
|
assert_equal "1.0.0", Yay.version
|
||||||
|
assert_equal "yay", Yay.yay
|
||||||
|
|
||||||
|
require '-test-/namespace/yay2'
|
||||||
|
assert_equal "2.0.0", Yay.version
|
||||||
|
v = Yay.yay
|
||||||
|
assert(v == "yay" || v == "yaaay") # "yay" on Linux, "yaaay" on macOS, Win32
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_load_extension_in_namespace
|
||||||
|
pend
|
||||||
|
assert_separately([ENV_ENABLE_NAMESPACE], "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||||
|
begin;
|
||||||
|
ns = Namespace.new
|
||||||
|
ns.require '-test-/namespace/yay1'
|
||||||
|
assert_equal "1.0.0", ns::Yay.version
|
||||||
|
assert_raise(NameError) { Yay }
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_different_version_extensions
|
||||||
|
pend
|
||||||
|
assert_separately([ENV_ENABLE_NAMESPACE], "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||||
|
begin;
|
||||||
|
ns1 = Namespace.new
|
||||||
|
ns2 = Namespace.new
|
||||||
|
ns1.require('-test-/namespace/yay1')
|
||||||
|
ns2.require('-test-/namespace/yay2')
|
||||||
|
|
||||||
|
assert_raise(NameError) { Yay }
|
||||||
|
assert_not_nil ns1::Yay
|
||||||
|
assert_not_nil ns2::Yay
|
||||||
|
assert_equal "1.0.0", ns1::Yay::VERSION
|
||||||
|
assert_equal "2.0.0", ns2::Yay::VERSION
|
||||||
|
assert_equal "1.0.0", ns1::Yay.version
|
||||||
|
assert_equal "2.0.0", ns2::Yay.version
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_loading_extensions_from_global_to_local
|
||||||
|
pend
|
||||||
|
assert_separately([ENV_ENABLE_NAMESPACE], "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||||
|
begin;
|
||||||
|
require '-test-/namespace/yay1'
|
||||||
|
assert_equal "1.0.0", Yay.version
|
||||||
|
assert_equal "yay", Yay.yay
|
||||||
|
|
||||||
|
ns = Namespace.new
|
||||||
|
ns.require '-test-/namespace/yay2'
|
||||||
|
assert_equal "2.0.0", ns::Yay.version
|
||||||
|
assert_equal "yaaay", ns::Yay.yay
|
||||||
|
|
||||||
|
assert_equal "yay", Yay.yay
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_loading_extensions_from_local_to_global
|
||||||
|
pend
|
||||||
|
assert_separately([ENV_ENABLE_NAMESPACE], "#{<<~"begin;"}\n#{<<~'end;'}")
|
||||||
|
begin;
|
||||||
|
ns = Namespace.new
|
||||||
|
ns.require '-test-/namespace/yay1'
|
||||||
|
assert_equal "1.0.0", ns::Yay.version
|
||||||
|
assert_equal "yay", ns::Yay.yay
|
||||||
|
|
||||||
|
|
||||||
|
require '-test-/namespace/yay2'
|
||||||
|
assert_equal "2.0.0", Yay.version
|
||||||
|
assert_equal "yaaay", Yay.yay
|
||||||
|
|
||||||
|
assert_equal "yay", ns::Yay.yay
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
end
|
@ -9,7 +9,11 @@ class TestABI < Test::Unit::TestCase
|
|||||||
assert_separately [], <<~RUBY
|
assert_separately [], <<~RUBY
|
||||||
err = assert_raise(LoadError) { require "-test-/abi" }
|
err = assert_raise(LoadError) { require "-test-/abi" }
|
||||||
assert_match(/incompatible ABI version/, err.message)
|
assert_match(/incompatible ABI version/, err.message)
|
||||||
assert_include err.message, "/-test-/abi."
|
if Namespace.enabled?
|
||||||
|
assert_include err.message, "_-test-+abi."
|
||||||
|
else
|
||||||
|
assert_include err.message, "/-test-/abi."
|
||||||
|
end
|
||||||
RUBY
|
RUBY
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -27,7 +31,11 @@ class TestABI < Test::Unit::TestCase
|
|||||||
assert_separately [{ "RUBY_ABI_CHECK" => "1" }], <<~RUBY
|
assert_separately [{ "RUBY_ABI_CHECK" => "1" }], <<~RUBY
|
||||||
err = assert_raise(LoadError) { require "-test-/abi" }
|
err = assert_raise(LoadError) { require "-test-/abi" }
|
||||||
assert_match(/incompatible ABI version/, err.message)
|
assert_match(/incompatible ABI version/, err.message)
|
||||||
assert_include err.message, "/-test-/abi."
|
if Namespace.enabled?
|
||||||
|
assert_include err.message, "_-test-+abi."
|
||||||
|
else
|
||||||
|
assert_include err.message, "/-test-/abi."
|
||||||
|
end
|
||||||
RUBY
|
RUBY
|
||||||
end
|
end
|
||||||
|
|
||||||
|
17
test/ruby/namespace/a.1_1_0.rb
Normal file
17
test/ruby/namespace/a.1_1_0.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class NS_A
|
||||||
|
VERSION = "1.1.0"
|
||||||
|
|
||||||
|
def yay
|
||||||
|
"yay #{VERSION}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module NS_B
|
||||||
|
VERSION = "1.1.0"
|
||||||
|
|
||||||
|
def self.yay
|
||||||
|
"yay_b1"
|
||||||
|
end
|
||||||
|
end
|
17
test/ruby/namespace/a.1_2_0.rb
Normal file
17
test/ruby/namespace/a.1_2_0.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class NS_A
|
||||||
|
VERSION = "1.2.0"
|
||||||
|
|
||||||
|
def yay
|
||||||
|
"yay #{VERSION}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module NS_B
|
||||||
|
VERSION = "1.2.0"
|
||||||
|
|
||||||
|
def self.yay
|
||||||
|
"yay_b1"
|
||||||
|
end
|
||||||
|
end
|
15
test/ruby/namespace/a.rb
Normal file
15
test/ruby/namespace/a.rb
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
class NS_A
|
||||||
|
FOO = "foo_a1"
|
||||||
|
|
||||||
|
def yay
|
||||||
|
"yay_a1"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module NS_B
|
||||||
|
BAR = "bar_b1"
|
||||||
|
|
||||||
|
def self.yay
|
||||||
|
"yay_b1"
|
||||||
|
end
|
||||||
|
end
|
8
test/ruby/namespace/autoloading.rb
Normal file
8
test/ruby/namespace/autoloading.rb
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
autoload :NS_A, File.join(__dir__, 'a.1_1_0')
|
||||||
|
NS_A.new.yay
|
||||||
|
|
||||||
|
module NS_B
|
||||||
|
autoload :BAR, File.join(__dir__, 'a')
|
||||||
|
end
|
2
test/ruby/namespace/blank.rb
Normal file
2
test/ruby/namespace/blank.rb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
module Blank1
|
||||||
|
end
|
2
test/ruby/namespace/blank1.rb
Normal file
2
test/ruby/namespace/blank1.rb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
module Blank1
|
||||||
|
end
|
2
test/ruby/namespace/blank2.rb
Normal file
2
test/ruby/namespace/blank2.rb
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
module Blank2
|
||||||
|
end
|
5
test/ruby/namespace/call_proc.rb
Normal file
5
test/ruby/namespace/call_proc.rb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module Bar
|
||||||
|
def self.caller(proc_value)
|
||||||
|
proc_value.call
|
||||||
|
end
|
||||||
|
end
|
8
test/ruby/namespace/call_toplevel.rb
Normal file
8
test/ruby/namespace/call_toplevel.rb
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
foo
|
||||||
|
|
||||||
|
#### TODO: this code should be valid, but can't be for now
|
||||||
|
# module Foo
|
||||||
|
# def self.wow
|
||||||
|
# foo
|
||||||
|
# end
|
||||||
|
# end
|
147
test/ruby/namespace/consts.rb
Normal file
147
test/ruby/namespace/consts.rb
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
class String
|
||||||
|
STR_CONST1 = 111
|
||||||
|
STR_CONST2 = 222
|
||||||
|
STR_CONST3 = 333
|
||||||
|
end
|
||||||
|
|
||||||
|
class String
|
||||||
|
STR_CONST1 = 112
|
||||||
|
|
||||||
|
def self.set0(val)
|
||||||
|
const_set(:STR_CONST0, val)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.remove0
|
||||||
|
remove_const(:STR_CONST0)
|
||||||
|
end
|
||||||
|
|
||||||
|
def refer0
|
||||||
|
STR_CONST0
|
||||||
|
end
|
||||||
|
|
||||||
|
def refer1
|
||||||
|
STR_CONST1
|
||||||
|
end
|
||||||
|
|
||||||
|
def refer2
|
||||||
|
STR_CONST2
|
||||||
|
end
|
||||||
|
|
||||||
|
def refer3
|
||||||
|
STR_CONST3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module ForConsts
|
||||||
|
CONST1 = 111
|
||||||
|
end
|
||||||
|
|
||||||
|
TOP_CONST = 10
|
||||||
|
|
||||||
|
module ForConsts
|
||||||
|
CONST1 = 112
|
||||||
|
CONST2 = 222
|
||||||
|
CONST3 = 333
|
||||||
|
|
||||||
|
def self.refer_all
|
||||||
|
ForConsts::CONST1
|
||||||
|
ForConsts::CONST2
|
||||||
|
ForConsts::CONST3
|
||||||
|
String::STR_CONST1
|
||||||
|
String::STR_CONST2
|
||||||
|
String::STR_CONST3
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.refer1
|
||||||
|
CONST1
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.get1
|
||||||
|
const_get(:CONST1)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.refer2
|
||||||
|
CONST2
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.get2
|
||||||
|
const_get(:CONST2)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.refer3
|
||||||
|
CONST3
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.get3
|
||||||
|
const_get(:CONST3)
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.refer_top_const
|
||||||
|
TOP_CONST
|
||||||
|
end
|
||||||
|
|
||||||
|
# for String
|
||||||
|
class Proxy
|
||||||
|
def call_str_refer0
|
||||||
|
String.new.refer0
|
||||||
|
end
|
||||||
|
|
||||||
|
def call_str_get0
|
||||||
|
String.const_get(:STR_CONST0)
|
||||||
|
end
|
||||||
|
|
||||||
|
def call_str_set0(val)
|
||||||
|
String.set0(val)
|
||||||
|
end
|
||||||
|
|
||||||
|
def call_str_remove0
|
||||||
|
String.remove0
|
||||||
|
end
|
||||||
|
|
||||||
|
def call_str_refer1
|
||||||
|
String.new.refer1
|
||||||
|
end
|
||||||
|
|
||||||
|
def call_str_get1
|
||||||
|
String.const_get(:STR_CONST1)
|
||||||
|
end
|
||||||
|
|
||||||
|
String::STR_CONST2 = 223
|
||||||
|
|
||||||
|
def call_str_refer2
|
||||||
|
String.new.refer2
|
||||||
|
end
|
||||||
|
|
||||||
|
def call_str_get2
|
||||||
|
String.const_get(:STR_CONST2)
|
||||||
|
end
|
||||||
|
|
||||||
|
def call_str_set3
|
||||||
|
String.const_set(:STR_CONST3, 334)
|
||||||
|
end
|
||||||
|
|
||||||
|
def call_str_refer3
|
||||||
|
String.new.refer3
|
||||||
|
end
|
||||||
|
|
||||||
|
def call_str_get3
|
||||||
|
String.const_get(:STR_CONST3)
|
||||||
|
end
|
||||||
|
|
||||||
|
# for Integer
|
||||||
|
Integer::INT_CONST1 = 1
|
||||||
|
|
||||||
|
def refer_int_const1
|
||||||
|
Integer::INT_CONST1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# should not raise errors
|
||||||
|
ForConsts.refer_all
|
||||||
|
String::STR_CONST1
|
||||||
|
Integer::INT_CONST1
|
||||||
|
|
||||||
|
# If we execute this sentence once, the constant value will be cached on ISeq inline constant cache.
|
||||||
|
# And it changes the behavior of ForConsts.refer_consts_directly called from global.
|
||||||
|
# ForConsts.refer_consts_directly # should not raise errors too
|
13
test/ruby/namespace/current.rb
Normal file
13
test/ruby/namespace/current.rb
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
$ns_in_ns = ::Namespace.current
|
||||||
|
|
||||||
|
module CurrentNamespace
|
||||||
|
def self.in_require
|
||||||
|
$ns_in_ns
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.in_method_call
|
||||||
|
::Namespace.current
|
||||||
|
end
|
||||||
|
end
|
5
test/ruby/namespace/define_toplevel.rb
Normal file
5
test/ruby/namespace/define_toplevel.rb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
def foo
|
||||||
|
"foooooooooo"
|
||||||
|
end
|
||||||
|
|
||||||
|
foo # should not raise errors
|
37
test/ruby/namespace/global_vars.rb
Normal file
37
test/ruby/namespace/global_vars.rb
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
module LineSplitter
|
||||||
|
def self.read
|
||||||
|
$-0
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.write(char)
|
||||||
|
$-0 = char
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module FieldSplitter
|
||||||
|
def self.read
|
||||||
|
$,
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.write(char)
|
||||||
|
$, = char
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module UniqueGvar
|
||||||
|
def self.read
|
||||||
|
$used_only_in_ns
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.write(val)
|
||||||
|
$used_only_in_ns = val
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.write_only(val)
|
||||||
|
$write_only_var_in_ns = val
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.gvars_in_ns
|
||||||
|
global_variables
|
||||||
|
end
|
||||||
|
end
|
9
test/ruby/namespace/line_splitter.rb
Normal file
9
test/ruby/namespace/line_splitter.rb
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
module LineSplitter
|
||||||
|
def self.read
|
||||||
|
$-0
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.write(char)
|
||||||
|
$-0 = char
|
||||||
|
end
|
||||||
|
end
|
26
test/ruby/namespace/load_path.rb
Normal file
26
test/ruby/namespace/load_path.rb
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
module LoadPathCheck
|
||||||
|
FIRST_LOAD_PATH = $LOAD_PATH.dup
|
||||||
|
FIRST_LOAD_PATH_RESPOND_TO_RESOLVE = $LOAD_PATH.respond_to?(:resolve_feature_path)
|
||||||
|
FIRST_LOADED_FEATURES = $LOADED_FEATURES.dup
|
||||||
|
|
||||||
|
HERE = File.dirname(__FILE__)
|
||||||
|
|
||||||
|
def self.current_load_path
|
||||||
|
$LOAD_PATH
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.current_loaded_features
|
||||||
|
$LOADED_FEATURES
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.require_blank1
|
||||||
|
$LOAD_PATH << HERE
|
||||||
|
require 'blank1'
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.require_blank2
|
||||||
|
require 'blank2'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
LoadPathCheck.require_blank1
|
10
test/ruby/namespace/ns.rb
Normal file
10
test/ruby/namespace/ns.rb
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
NS1 = Namespace.new
|
||||||
|
NS1.require_relative('a.1_1_0')
|
||||||
|
|
||||||
|
def yay
|
||||||
|
NS1::NS_B::yay
|
||||||
|
end
|
||||||
|
|
||||||
|
yay
|
31
test/ruby/namespace/open_class_with_include.rb
Normal file
31
test/ruby/namespace/open_class_with_include.rb
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
module StringExt
|
||||||
|
FOO = "foo 1"
|
||||||
|
def say_foo
|
||||||
|
"I'm saying " + FOO
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class String
|
||||||
|
include StringExt
|
||||||
|
def say
|
||||||
|
say_foo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module OpenClassWithInclude
|
||||||
|
def self.say
|
||||||
|
String.new.say
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.say_foo
|
||||||
|
String.new.say_foo
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.say_with_obj(str)
|
||||||
|
str.say
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.refer_foo
|
||||||
|
String::FOO
|
||||||
|
end
|
||||||
|
end
|
14
test/ruby/namespace/proc_callee.rb
Normal file
14
test/ruby/namespace/proc_callee.rb
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
module Target
|
||||||
|
def self.foo
|
||||||
|
"fooooo"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module Foo
|
||||||
|
def self.callee
|
||||||
|
lambda do
|
||||||
|
Target.foo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
5
test/ruby/namespace/proc_caller.rb
Normal file
5
test/ruby/namespace/proc_caller.rb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module Bar
|
||||||
|
def self.caller(proc_value)
|
||||||
|
proc_value.call
|
||||||
|
end
|
||||||
|
end
|
64
test/ruby/namespace/procs.rb
Normal file
64
test/ruby/namespace/procs.rb
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
class String
|
||||||
|
FOO = "foo"
|
||||||
|
def yay
|
||||||
|
"yay"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module ProcLookupTestA
|
||||||
|
module B
|
||||||
|
VALUE = 222
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module ProcInNS
|
||||||
|
def self.make_proc_from_block(&b)
|
||||||
|
b
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.call_proc(proc_arg)
|
||||||
|
proc_arg.call
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.make_str_proc(type)
|
||||||
|
case type
|
||||||
|
when :proc_new then Proc.new { String.new.yay }
|
||||||
|
when :proc_f then proc { String.new.yay }
|
||||||
|
when :lambda_f then lambda { String.new.yay }
|
||||||
|
when :lambda_l then ->(){ String.new.yay }
|
||||||
|
when :block then make_proc_from_block { String.new.yay }
|
||||||
|
else
|
||||||
|
raise "invalid type :#{type}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.make_const_proc(type)
|
||||||
|
case type
|
||||||
|
when :proc_new then Proc.new { ProcLookupTestA::B::VALUE }
|
||||||
|
when :proc_f then proc { ProcLookupTestA::B::VALUE }
|
||||||
|
when :lambda_f then lambda { ProcLookupTestA::B::VALUE }
|
||||||
|
when :lambda_l then ->(){ ProcLookupTestA::B::VALUE }
|
||||||
|
when :block then make_proc_from_block { ProcLookupTestA::B::VALUE }
|
||||||
|
else
|
||||||
|
raise "invalid type :#{type}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.make_str_const_proc(type)
|
||||||
|
case type
|
||||||
|
when :proc_new then Proc.new { String::FOO }
|
||||||
|
when :proc_f then proc { String::FOO }
|
||||||
|
when :lambda_f then lambda { String::FOO }
|
||||||
|
when :lambda_l then ->(){ String::FOO }
|
||||||
|
when :block then make_proc_from_block { String::FOO }
|
||||||
|
else
|
||||||
|
raise "invalid type :#{type}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
CONST_PROC_NEW = Proc.new { [String.new.yay, String::FOO, ProcLookupTestA::B::VALUE.to_s].join(',') }
|
||||||
|
CONST_PROC_F = proc { [String.new.yay, String::FOO, ProcLookupTestA::B::VALUE.to_s].join(',') }
|
||||||
|
CONST_LAMBDA_F = lambda { [String.new.yay, String::FOO, ProcLookupTestA::B::VALUE.to_s].join(',') }
|
||||||
|
CONST_LAMBDA_L = ->() { [String.new.yay, String::FOO, ProcLookupTestA::B::VALUE.to_s].join(',') }
|
||||||
|
CONST_BLOCK = make_proc_from_block { [String.new.yay, String::FOO, ProcLookupTestA::B::VALUE.to_s].join(',') }
|
||||||
|
end
|
3
test/ruby/namespace/raise.rb
Normal file
3
test/ruby/namespace/raise.rb
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
raise "Yay!"
|
12
test/ruby/namespace/returns_proc.rb
Normal file
12
test/ruby/namespace/returns_proc.rb
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
module Foo
|
||||||
|
def self.foo
|
||||||
|
"fooooo"
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.callee
|
||||||
|
lambda do
|
||||||
|
Foo.foo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
65
test/ruby/namespace/singleton_methods.rb
Normal file
65
test/ruby/namespace/singleton_methods.rb
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
class String
|
||||||
|
def self.greeting
|
||||||
|
"Good evening!"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Integer
|
||||||
|
class << self
|
||||||
|
def answer
|
||||||
|
42
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Array
|
||||||
|
def a
|
||||||
|
size
|
||||||
|
end
|
||||||
|
def self.blank
|
||||||
|
[]
|
||||||
|
end
|
||||||
|
def b
|
||||||
|
size
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Hash
|
||||||
|
def a
|
||||||
|
size
|
||||||
|
end
|
||||||
|
class << self
|
||||||
|
def http_200
|
||||||
|
{status: 200, body: 'OK'}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def b
|
||||||
|
size
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module SingletonMethods
|
||||||
|
def self.string_greeing
|
||||||
|
String.greeting
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.integer_answer
|
||||||
|
Integer.answer
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.array_blank
|
||||||
|
Array.blank
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.hash_http_200
|
||||||
|
Hash.http_200
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.array_instance_methods_return_size(ary)
|
||||||
|
[ary.a, ary.b]
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.hash_instance_methods_return_size(hash)
|
||||||
|
[hash.a, hash.b]
|
||||||
|
end
|
||||||
|
end
|
13
test/ruby/namespace/string_ext.rb
Normal file
13
test/ruby/namespace/string_ext.rb
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
class String
|
||||||
|
def yay
|
||||||
|
"yay"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
String.new.yay # check this doesn't raise NoMethodError
|
||||||
|
|
||||||
|
module Bar
|
||||||
|
def self.yay
|
||||||
|
String.new.yay
|
||||||
|
end
|
||||||
|
end
|
5
test/ruby/namespace/string_ext_caller.rb
Normal file
5
test/ruby/namespace/string_ext_caller.rb
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
module Foo
|
||||||
|
def self.yay
|
||||||
|
String.new.yay
|
||||||
|
end
|
||||||
|
end
|
1
test/ruby/namespace/string_ext_calling.rb
Normal file
1
test/ruby/namespace/string_ext_calling.rb
Normal file
@ -0,0 +1 @@
|
|||||||
|
Foo.yay
|
12
test/ruby/namespace/string_ext_eval_caller.rb
Normal file
12
test/ruby/namespace/string_ext_eval_caller.rb
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
module Baz
|
||||||
|
def self.yay
|
||||||
|
eval 'String.new.yay'
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.yay_with_binding
|
||||||
|
suffix = ", yay!"
|
||||||
|
eval 'String.new.yay + suffix', binding
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Baz.yay # should not raise NeMethodError
|
33
test/ruby/namespace/top_level.rb
Normal file
33
test/ruby/namespace/top_level.rb
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
def yaaay
|
||||||
|
"yay!"
|
||||||
|
end
|
||||||
|
|
||||||
|
module Foo
|
||||||
|
def self.foo
|
||||||
|
yaaay
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
eval 'def foo; "foo"; end'
|
||||||
|
|
||||||
|
Foo.foo # Should not raise NameError
|
||||||
|
|
||||||
|
foo
|
||||||
|
|
||||||
|
module Bar
|
||||||
|
def self.bar
|
||||||
|
foo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
Bar.bar
|
||||||
|
|
||||||
|
$def_retval_in_namespace = def boooo
|
||||||
|
"boo"
|
||||||
|
end
|
||||||
|
|
||||||
|
module Baz
|
||||||
|
def self.baz
|
||||||
|
raise "#{$def_retval_in_namespace}"
|
||||||
|
end
|
||||||
|
end
|
@ -224,11 +224,18 @@ p Foo::Bar
|
|||||||
Kernel.module_eval do
|
Kernel.module_eval do
|
||||||
alias old_require require
|
alias old_require require
|
||||||
end
|
end
|
||||||
|
Namespace.module_eval do
|
||||||
|
alias old_require require
|
||||||
|
end
|
||||||
called_with = []
|
called_with = []
|
||||||
Kernel.send :define_method, :require do |path|
|
Kernel.send :define_method, :require do |path|
|
||||||
called_with << path
|
called_with << path
|
||||||
old_require path
|
old_require path
|
||||||
end
|
end
|
||||||
|
Namespace.send :define_method, :require do |path|
|
||||||
|
called_with << path
|
||||||
|
old_require path
|
||||||
|
end
|
||||||
yield called_with
|
yield called_with
|
||||||
ensure
|
ensure
|
||||||
Kernel.module_eval do
|
Kernel.module_eval do
|
||||||
@ -236,6 +243,11 @@ p Foo::Bar
|
|||||||
alias require old_require
|
alias require old_require
|
||||||
undef old_require
|
undef old_require
|
||||||
end
|
end
|
||||||
|
Namespace.module_eval do
|
||||||
|
undef require
|
||||||
|
alias require old_require
|
||||||
|
undef old_require
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def test_require_implemented_in_ruby_is_called
|
def test_require_implemented_in_ruby_is_called
|
||||||
@ -249,7 +261,8 @@ p Foo::Bar
|
|||||||
ensure
|
ensure
|
||||||
remove_autoload_constant
|
remove_autoload_constant
|
||||||
end
|
end
|
||||||
assert_equal [file.path], called_with
|
# .dup to prevent breaking called_with by autoloading pp, etc
|
||||||
|
assert_equal [file.path], called_with.dup
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -267,7 +280,8 @@ p Foo::Bar
|
|||||||
ensure
|
ensure
|
||||||
remove_autoload_constant
|
remove_autoload_constant
|
||||||
end
|
end
|
||||||
assert_equal [a.path, b.path], called_with
|
# .dup to prevent breaking called_with by autoloading pp, etc
|
||||||
|
assert_equal [a.path, b.path], called_with.dup
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
516
test/ruby/test_namespace.rb
Normal file
516
test/ruby/test_namespace.rb
Normal file
@ -0,0 +1,516 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require 'test/unit'
|
||||||
|
|
||||||
|
class TestNamespace < Test::Unit::TestCase
|
||||||
|
ENV_ENABLE_NAMESPACE = {'RUBY_NAMESPACE' => '1'}
|
||||||
|
|
||||||
|
def setup
|
||||||
|
@n = Namespace.new if Namespace.enabled?
|
||||||
|
end
|
||||||
|
|
||||||
|
def teardown
|
||||||
|
@n = nil
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_namespace_availability
|
||||||
|
env_has_RUBY_NAMESPACE = (ENV['RUBY_NAMESPACE'].to_i == 1)
|
||||||
|
assert_equal env_has_RUBY_NAMESPACE, Namespace.enabled?
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_current_namespace
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
main = Namespace.current
|
||||||
|
assert main.inspect.include?("main")
|
||||||
|
|
||||||
|
@n.require_relative('namespace/current')
|
||||||
|
|
||||||
|
assert_equal @n, @n::CurrentNamespace.in_require
|
||||||
|
assert_equal @n, @n::CurrentNamespace.in_method_call
|
||||||
|
assert_equal main, Namespace.current
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_require_rb_separately
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
assert_raise(NameError) { NS_A }
|
||||||
|
assert_raise(NameError) { NS_B }
|
||||||
|
|
||||||
|
@n.require(File.join(__dir__, 'namespace', 'a.1_1_0'))
|
||||||
|
|
||||||
|
assert_not_nil @n::NS_A
|
||||||
|
assert_not_nil @n::NS_B
|
||||||
|
assert_equal "1.1.0", @n::NS_A::VERSION
|
||||||
|
assert_equal "yay 1.1.0", @n::NS_A.new.yay
|
||||||
|
assert_equal "1.1.0", @n::NS_B::VERSION
|
||||||
|
assert_equal "yay_b1", @n::NS_B.yay
|
||||||
|
|
||||||
|
assert_raise(NameError) { NS_A }
|
||||||
|
assert_raise(NameError) { NS_B }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_require_relative_rb_separately
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
assert_raise(NameError) { NS_A }
|
||||||
|
assert_raise(NameError) { NS_B }
|
||||||
|
|
||||||
|
@n.require_relative('namespace/a.1_1_0')
|
||||||
|
|
||||||
|
assert_not_nil @n::NS_A
|
||||||
|
assert_not_nil @n::NS_B
|
||||||
|
assert_equal "1.1.0", @n::NS_A::VERSION
|
||||||
|
assert_equal "yay 1.1.0", @n::NS_A.new.yay
|
||||||
|
assert_equal "1.1.0", @n::NS_B::VERSION
|
||||||
|
assert_equal "yay_b1", @n::NS_B.yay
|
||||||
|
|
||||||
|
assert_raise(NameError) { NS_A }
|
||||||
|
assert_raise(NameError) { NS_B }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_load_separately
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
assert_raise(NameError) { NS_A }
|
||||||
|
assert_raise(NameError) { NS_B }
|
||||||
|
|
||||||
|
@n.load(File.join(__dir__, 'namespace', 'a.1_1_0.rb'))
|
||||||
|
|
||||||
|
assert_not_nil @n::NS_A
|
||||||
|
assert_not_nil @n::NS_B
|
||||||
|
assert_equal "1.1.0", @n::NS_A::VERSION
|
||||||
|
assert_equal "yay 1.1.0", @n::NS_A.new.yay
|
||||||
|
assert_equal "1.1.0", @n::NS_B::VERSION
|
||||||
|
assert_equal "yay_b1", @n::NS_B.yay
|
||||||
|
|
||||||
|
assert_raise(NameError) { NS_A }
|
||||||
|
assert_raise(NameError) { NS_B }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_namespace_in_namespace
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
assert_raise(NameError) { NS1 }
|
||||||
|
assert_raise(NameError) { NS_A }
|
||||||
|
assert_raise(NameError) { NS_B }
|
||||||
|
|
||||||
|
@n.require_relative('namespace/ns')
|
||||||
|
|
||||||
|
assert_not_nil @n::NS1
|
||||||
|
assert_not_nil @n::NS1::NS_A
|
||||||
|
assert_not_nil @n::NS1::NS_B
|
||||||
|
assert_equal "1.1.0", @n::NS1::NS_A::VERSION
|
||||||
|
assert_equal "yay 1.1.0", @n::NS1::NS_A.new.yay
|
||||||
|
assert_equal "1.1.0", @n::NS1::NS_B::VERSION
|
||||||
|
assert_equal "yay_b1", @n::NS1::NS_B.yay
|
||||||
|
|
||||||
|
assert_raise(NameError) { NS1 }
|
||||||
|
assert_raise(NameError) { NS_A }
|
||||||
|
assert_raise(NameError) { NS_B }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_require_rb_2versions
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
assert_raise(NameError) { NS_A }
|
||||||
|
|
||||||
|
@n.require(File.join(__dir__, 'namespace', 'a.1_2_0'))
|
||||||
|
assert_equal "1.2.0", @n::NS_A::VERSION
|
||||||
|
assert_equal "yay 1.2.0", @n::NS_A.new.yay
|
||||||
|
|
||||||
|
n2 = Namespace.new
|
||||||
|
n2.require(File.join(__dir__, 'namespace', 'a.1_1_0'))
|
||||||
|
assert_equal "1.1.0", n2::NS_A::VERSION
|
||||||
|
assert_equal "yay 1.1.0", n2::NS_A.new.yay
|
||||||
|
|
||||||
|
# recheck @n is not affected by the following require
|
||||||
|
assert_equal "1.2.0", @n::NS_A::VERSION
|
||||||
|
assert_equal "yay 1.2.0", @n::NS_A.new.yay
|
||||||
|
|
||||||
|
assert_raise(NameError) { NS_A }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_raising_errors_in_require
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
assert_raise(RuntimeError, "Yay!") { @n.require(File.join(__dir__, 'namespace', 'raise')) }
|
||||||
|
assert Namespace.current.inspect.include?("main")
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_autoload_in_namespace
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
assert_raise(NameError) { NS_A }
|
||||||
|
|
||||||
|
@n.require_relative('namespace/autoloading')
|
||||||
|
# autoloaded A is visible from global
|
||||||
|
assert_equal '1.1.0', @n::NS_A::VERSION
|
||||||
|
|
||||||
|
assert_raise(NameError) { NS_A }
|
||||||
|
|
||||||
|
# autoload trigger NS_B::BAR is valid even from global
|
||||||
|
assert_equal 'bar_b1', @n::NS_B::BAR
|
||||||
|
|
||||||
|
assert_raise(NameError) { NS_A }
|
||||||
|
assert_raise(NameError) { NS_B }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_continuous_top_level_method_in_a_namespace
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
@n.require_relative('namespace/define_toplevel')
|
||||||
|
@n.require_relative('namespace/call_toplevel')
|
||||||
|
|
||||||
|
assert_raise(NameError) { foo }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_top_level_methods_in_namespace
|
||||||
|
pend # TODO: fix loading/current namespace detection
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
@n.require_relative('namespace/top_level')
|
||||||
|
assert_equal "yay!", @n::Foo.foo
|
||||||
|
assert_raise(NameError) { yaaay }
|
||||||
|
assert_equal "foo", @n::Bar.bar
|
||||||
|
assert_raise_with_message(RuntimeError, "boooo") { @n::Baz.baz }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_proc_defined_in_namespace_refers_module_in_namespace
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
# require_relative dosn't work well in assert_separately even with __FILE__ and __LINE__
|
||||||
|
assert_separately([ENV_ENABLE_NAMESPACE], __FILE__, __LINE__, "here = '#{__dir__}'; #{<<~"begin;"}\n#{<<~'end;'}")
|
||||||
|
begin;
|
||||||
|
ns1 = Namespace.new
|
||||||
|
ns1.require(File.join("#{here}", 'namespace/proc_callee'))
|
||||||
|
proc_v = ns1::Foo.callee
|
||||||
|
assert_raise(NameError) { Target }
|
||||||
|
assert ns1::Target
|
||||||
|
assert_equal "fooooo", proc_v.call # refers Target in the namespace ns1
|
||||||
|
ns1.require(File.join("#{here}", 'namespace/proc_caller'))
|
||||||
|
assert_equal "fooooo", ns1::Bar.caller(proc_v)
|
||||||
|
|
||||||
|
ns2 = Namespace.new
|
||||||
|
ns2.require(File.join("#{here}", 'namespace/proc_caller'))
|
||||||
|
assert_raise(NameError) { ns2::Target }
|
||||||
|
assert_equal "fooooo", ns2::Bar.caller(proc_v) # refers Target in the namespace ns1
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_proc_defined_globally_refers_global_module
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
# require_relative dosn't work well in assert_separately even with __FILE__ and __LINE__
|
||||||
|
assert_separately([ENV_ENABLE_NAMESPACE], __FILE__, __LINE__, "here = '#{__dir__}'; #{<<~"begin;"}\n#{<<~'end;'}", ignore_stderr: true)
|
||||||
|
begin;
|
||||||
|
require(File.join("#{here}", 'namespace/proc_callee'))
|
||||||
|
def Target.foo
|
||||||
|
"yay"
|
||||||
|
end
|
||||||
|
proc_v = Foo.callee
|
||||||
|
assert Target
|
||||||
|
assert_equal "yay", proc_v.call # refers global Foo
|
||||||
|
ns1 = Namespace.new
|
||||||
|
ns1.require(File.join("#{here}", 'namespace/proc_caller'))
|
||||||
|
assert_equal "yay", ns1::Bar.caller(proc_v)
|
||||||
|
|
||||||
|
ns2 = Namespace.new
|
||||||
|
ns2.require(File.join("#{here}", 'namespace/proc_callee'))
|
||||||
|
ns2.require(File.join("#{here}", 'namespace/proc_caller'))
|
||||||
|
assert_equal "fooooo", ns2::Foo.callee.call
|
||||||
|
assert_equal "yay", ns2::Bar.caller(proc_v) # should refer the global Target, not Foo in ns2
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_methods_added_in_namespace_are_invisible_globally
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
@n.require_relative('namespace/string_ext')
|
||||||
|
|
||||||
|
assert_equal "yay", @n::Bar.yay
|
||||||
|
|
||||||
|
assert_raise(NoMethodError){ String.new.yay }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_continuous_method_definitions_in_a_namespace
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
@n.require_relative('namespace/string_ext')
|
||||||
|
assert_equal "yay", @n::Bar.yay
|
||||||
|
|
||||||
|
@n.require_relative('namespace/string_ext_caller')
|
||||||
|
assert_equal "yay", @n::Foo.yay
|
||||||
|
|
||||||
|
@n.require_relative('namespace/string_ext_calling')
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_methods_added_in_namespace_later_than_caller_code
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
@n.require_relative('namespace/string_ext_caller')
|
||||||
|
@n.require_relative('namespace/string_ext')
|
||||||
|
|
||||||
|
assert_equal "yay", @n::Bar.yay
|
||||||
|
assert_equal "yay", @n::Foo.yay
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_method_added_in_namespace_are_available_on_eval
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
@n.require_relative('namespace/string_ext')
|
||||||
|
@n.require_relative('namespace/string_ext_eval_caller')
|
||||||
|
|
||||||
|
assert_equal "yay", @n::Baz.yay
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_method_added_in_namespace_are_available_on_eval_with_binding
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
@n.require_relative('namespace/string_ext')
|
||||||
|
@n.require_relative('namespace/string_ext_eval_caller')
|
||||||
|
|
||||||
|
assert_equal "yay, yay!", @n::Baz.yay_with_binding
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_methods_and_constants_added_by_include
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
@n.require_relative('namespace/open_class_with_include')
|
||||||
|
|
||||||
|
assert_equal "I'm saying foo 1", @n::OpenClassWithInclude.say
|
||||||
|
assert_equal "I'm saying foo 1", @n::OpenClassWithInclude.say_foo
|
||||||
|
assert_equal "I'm saying foo 1", @n::OpenClassWithInclude.say_with_obj("wow")
|
||||||
|
|
||||||
|
assert_raise(NameError) { String::FOO }
|
||||||
|
|
||||||
|
assert_equal "foo 1", @n::OpenClassWithInclude.refer_foo
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
module ProcLookupTestA
|
||||||
|
module B
|
||||||
|
VALUE = 111
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class TestNamespace < Test::Unit::TestCase
|
||||||
|
def make_proc_from_block(&b)
|
||||||
|
b
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_proc_from_main_works_with_global_definitions
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
@n.require_relative('namespace/procs')
|
||||||
|
|
||||||
|
proc_and_labels = [
|
||||||
|
[Proc.new { String.new.yay }, "Proc.new"],
|
||||||
|
[proc { String.new.yay }, "proc{}"],
|
||||||
|
[lambda { String.new.yay }, "lambda{}"],
|
||||||
|
[->(){ String.new.yay }, "->(){}"],
|
||||||
|
[make_proc_from_block { String.new.yay }, "make_proc_from_block"],
|
||||||
|
[@n::ProcInNS.make_proc_from_block { String.new.yay }, "make_proc_from_block in @n"],
|
||||||
|
]
|
||||||
|
|
||||||
|
proc_and_labels.each do |str_pr|
|
||||||
|
pr, pr_label = str_pr
|
||||||
|
assert_raise(NoMethodError, "NoMethodError expected: #{pr_label}, called in main") { pr.call }
|
||||||
|
assert_raise(NoMethodError, "NoMethodError expected: #{pr_label}, called in @n") { @n::ProcInNS.call_proc(pr) }
|
||||||
|
end
|
||||||
|
|
||||||
|
const_and_labels = [
|
||||||
|
[Proc.new { ProcLookupTestA::B::VALUE }, "Proc.new"],
|
||||||
|
[proc { ProcLookupTestA::B::VALUE }, "proc{}"],
|
||||||
|
[lambda { ProcLookupTestA::B::VALUE }, "lambda{}"],
|
||||||
|
[->(){ ProcLookupTestA::B::VALUE }, "->(){}"],
|
||||||
|
[make_proc_from_block { ProcLookupTestA::B::VALUE }, "make_proc_from_block"],
|
||||||
|
[@n::ProcInNS.make_proc_from_block { ProcLookupTestA::B::VALUE }, "make_proc_from_block in @n"],
|
||||||
|
]
|
||||||
|
|
||||||
|
const_and_labels.each do |const_pr|
|
||||||
|
pr, pr_label = const_pr
|
||||||
|
assert_equal 111, pr.call, "111 expected, #{pr_label} called in main"
|
||||||
|
assert_equal 111, @n::ProcInNS.call_proc(pr), "111 expected, #{pr_label} called in @n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_proc_from_namespace_works_with_definitions_in_namespace
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
@n.require_relative('namespace/procs')
|
||||||
|
|
||||||
|
proc_types = [:proc_new, :proc_f, :lambda_f, :lambda_l, :block]
|
||||||
|
|
||||||
|
proc_types.each do |proc_type|
|
||||||
|
assert_equal 222, @n::ProcInNS.make_const_proc(proc_type).call, "ProcLookupTestA::B::VALUE should be 222 in @n"
|
||||||
|
assert_equal "foo", @n::ProcInNS.make_str_const_proc(proc_type).call, "String::FOO should be \"foo\" in @n"
|
||||||
|
assert_equal "yay", @n::ProcInNS.make_str_proc(proc_type).call, "String#yay should be callable in @n"
|
||||||
|
#
|
||||||
|
# TODO: method calls not-in-methods nor procs can't handle the current namespace correctly.
|
||||||
|
#
|
||||||
|
# assert_equal "yay,foo,222",
|
||||||
|
# @n::ProcInNS.const_get(('CONST_' + proc_type.to_s.upcase).to_sym).call,
|
||||||
|
# "Proc assigned to constants should refer constants correctly in @n"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_class_module_singleton_methods
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
@n.require_relative('namespace/singleton_methods')
|
||||||
|
|
||||||
|
assert_equal "Good evening!", @n::SingletonMethods.string_greeing # def self.greeting
|
||||||
|
assert_equal 42, @n::SingletonMethods.integer_answer # class << self; def answer
|
||||||
|
assert_equal([], @n::SingletonMethods.array_blank) # def self.blank w/ instance methods
|
||||||
|
assert_equal({status: 200, body: 'OK'}, @n::SingletonMethods.hash_http_200) # class << self; def ... w/ instance methods
|
||||||
|
|
||||||
|
assert_equal([4, 4], @n::SingletonMethods.array_instance_methods_return_size([1, 2, 3, 4]))
|
||||||
|
assert_equal([3, 3], @n::SingletonMethods.hash_instance_methods_return_size({a: 2, b: 4, c: 8}))
|
||||||
|
|
||||||
|
assert_raise(NoMethodError) { String.greeting }
|
||||||
|
assert_raise(NoMethodError) { Integer.answer }
|
||||||
|
assert_raise(NoMethodError) { Array.blank }
|
||||||
|
assert_raise(NoMethodError) { Hash.http_200 }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_add_constants_in_namespace
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
String.const_set(:STR_CONST0, 999)
|
||||||
|
assert_equal 999, String::STR_CONST0
|
||||||
|
assert_equal 999, String.const_get(:STR_CONST0)
|
||||||
|
|
||||||
|
assert_raise(NameError) { String.const_get(:STR_CONST1) }
|
||||||
|
assert_raise(NameError) { String::STR_CONST2 }
|
||||||
|
assert_raise(NameError) { String::STR_CONST3 }
|
||||||
|
assert_raise(NameError) { Integer.const_get(:INT_CONST1) }
|
||||||
|
|
||||||
|
EnvUtil.suppress_warning do
|
||||||
|
@n.require_relative('namespace/consts')
|
||||||
|
end
|
||||||
|
assert_equal 999, String::STR_CONST0
|
||||||
|
assert_raise(NameError) { String::STR_CONST1 }
|
||||||
|
assert_raise(NameError) { String::STR_CONST2 }
|
||||||
|
assert_raise(NameError) { Integer::INT_CONST1 }
|
||||||
|
|
||||||
|
assert_not_nil @n::ForConsts.refer_all
|
||||||
|
|
||||||
|
assert_equal 112, @n::ForConsts.refer1
|
||||||
|
assert_equal 112, @n::ForConsts.get1
|
||||||
|
assert_equal 112, @n::ForConsts::CONST1
|
||||||
|
assert_equal 222, @n::ForConsts.refer2
|
||||||
|
assert_equal 222, @n::ForConsts.get2
|
||||||
|
assert_equal 222, @n::ForConsts::CONST2
|
||||||
|
assert_equal 333, @n::ForConsts.refer3
|
||||||
|
assert_equal 333, @n::ForConsts.get3
|
||||||
|
assert_equal 333, @n::ForConsts::CONST3
|
||||||
|
|
||||||
|
EnvUtil.suppress_warning do
|
||||||
|
@n::ForConsts.const_set(:CONST3, 334)
|
||||||
|
end
|
||||||
|
assert_equal 334, @n::ForConsts::CONST3
|
||||||
|
assert_equal 334, @n::ForConsts.refer3
|
||||||
|
assert_equal 334, @n::ForConsts.get3
|
||||||
|
|
||||||
|
assert_equal 10, @n::ForConsts.refer_top_const
|
||||||
|
|
||||||
|
# use Proxy object to use usual methods instead of singleton methods
|
||||||
|
proxy = @n::ForConsts::Proxy.new
|
||||||
|
|
||||||
|
assert_raise(NameError){ proxy.call_str_refer0 }
|
||||||
|
assert_raise(NameError){ proxy.call_str_get0 }
|
||||||
|
|
||||||
|
proxy.call_str_set0(30)
|
||||||
|
assert_equal 30, proxy.call_str_refer0
|
||||||
|
assert_equal 30, proxy.call_str_get0
|
||||||
|
assert_equal 999, String::STR_CONST0
|
||||||
|
|
||||||
|
proxy.call_str_remove0
|
||||||
|
assert_raise(NameError){ proxy.call_str_refer0 }
|
||||||
|
assert_raise(NameError){ proxy.call_str_get0 }
|
||||||
|
|
||||||
|
assert_equal 112, proxy.call_str_refer1
|
||||||
|
assert_equal 112, proxy.call_str_get1
|
||||||
|
assert_equal 223, proxy.call_str_refer2
|
||||||
|
assert_equal 223, proxy.call_str_get2
|
||||||
|
assert_equal 333, proxy.call_str_refer3
|
||||||
|
assert_equal 333, proxy.call_str_get3
|
||||||
|
|
||||||
|
EnvUtil.suppress_warning do
|
||||||
|
proxy.call_str_set3
|
||||||
|
end
|
||||||
|
assert_equal 334, proxy.call_str_refer3
|
||||||
|
assert_equal 334, proxy.call_str_get3
|
||||||
|
|
||||||
|
assert_equal 1, proxy.refer_int_const1
|
||||||
|
|
||||||
|
assert_equal 999, String::STR_CONST0
|
||||||
|
assert_raise(NameError) { String::STR_CONST1 }
|
||||||
|
assert_raise(NameError) { String::STR_CONST2 }
|
||||||
|
assert_raise(NameError) { String::STR_CONST3 }
|
||||||
|
assert_raise(NameError) { Integer::INT_CONST1 }
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_global_variables
|
||||||
|
default_l = $-0
|
||||||
|
default_f = $,
|
||||||
|
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
assert_equal "\n", $-0 # equal to $/, line splitter
|
||||||
|
assert_equal nil, $, # field splitter
|
||||||
|
|
||||||
|
@n.require_relative('namespace/global_vars')
|
||||||
|
|
||||||
|
# read first
|
||||||
|
assert_equal "\n", @n::LineSplitter.read
|
||||||
|
@n::LineSplitter.write("\r\n")
|
||||||
|
assert_equal "\r\n", @n::LineSplitter.read
|
||||||
|
assert_equal "\n", $-0
|
||||||
|
|
||||||
|
# write first
|
||||||
|
@n::FieldSplitter.write(",")
|
||||||
|
assert_equal ",", @n::FieldSplitter.read
|
||||||
|
assert_equal nil, $,
|
||||||
|
|
||||||
|
# used only in ns
|
||||||
|
assert !global_variables.include?(:$used_only_in_ns)
|
||||||
|
@n::UniqueGvar.write(123)
|
||||||
|
assert_equal 123, @n::UniqueGvar.read
|
||||||
|
assert_nil $used_only_in_ns
|
||||||
|
|
||||||
|
# Kernel#global_variables returns the sum of all gvars.
|
||||||
|
global_gvars = global_variables.sort
|
||||||
|
assert_equal global_gvars, @n::UniqueGvar.gvars_in_ns.sort
|
||||||
|
@n::UniqueGvar.write_only(456)
|
||||||
|
assert_equal (global_gvars + [:$write_only_var_in_ns]).sort, @n::UniqueGvar.gvars_in_ns.sort
|
||||||
|
assert_equal (global_gvars + [:$write_only_var_in_ns]).sort, global_variables.sort
|
||||||
|
ensure
|
||||||
|
EnvUtil.suppress_warning do
|
||||||
|
$-0 = default_l
|
||||||
|
$, = default_f
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_load_path_and_loaded_features
|
||||||
|
pend unless Namespace.enabled?
|
||||||
|
|
||||||
|
assert $LOAD_PATH.respond_to?(:resolve_feature_path)
|
||||||
|
|
||||||
|
@n.require_relative('namespace/load_path')
|
||||||
|
|
||||||
|
assert_not_equal $LOAD_PATH, @n::LoadPathCheck::FIRST_LOAD_PATH
|
||||||
|
|
||||||
|
assert @n::LoadPathCheck::FIRST_LOAD_PATH_RESPOND_TO_RESOLVE
|
||||||
|
|
||||||
|
namespace_dir = File.join(__dir__, 'namespace')
|
||||||
|
# TODO: $LOADED_FEATURES in method calls should refer the current namespace in addition to the loading namespace.
|
||||||
|
# assert @n::LoadPathCheck.current_loaded_features.include?(File.join(namespace_dir, 'blank1.rb'))
|
||||||
|
# assert !@n::LoadPathCheck.current_loaded_features.include?(File.join(namespace_dir, 'blank2.rb'))
|
||||||
|
# assert @n::LoadPathCheck.require_blank2
|
||||||
|
# assert @n::LoadPathCheck.current_loaded_features.include?(File.join(namespace_dir, 'blank2.rb'))
|
||||||
|
|
||||||
|
assert !$LOADED_FEATURES.include?(File.join(namespace_dir, 'blank1.rb'))
|
||||||
|
assert !$LOADED_FEATURES.include?(File.join(namespace_dir, 'blank2.rb'))
|
||||||
|
end
|
||||||
|
end
|
@ -260,6 +260,8 @@ class TestRubyOptions < Test::Unit::TestCase
|
|||||||
end
|
end
|
||||||
|
|
||||||
def test_parser_flag
|
def test_parser_flag
|
||||||
|
omit if ENV["RUBYOPT"]&.include?("--parser=")
|
||||||
|
|
||||||
assert_in_out_err(%w(--parser=prism -e) + ["puts :hi"], "", %w(hi), [])
|
assert_in_out_err(%w(--parser=prism -e) + ["puts :hi"], "", %w(hi), [])
|
||||||
assert_in_out_err(%w(--parser=prism --dump=parsetree -e _=:hi), "", /"hi"/, [])
|
assert_in_out_err(%w(--parser=prism --dump=parsetree -e _=:hi), "", /"hi"/, [])
|
||||||
|
|
||||||
|
263
variable.c
263
variable.c
@ -25,6 +25,7 @@
|
|||||||
#include "internal/error.h"
|
#include "internal/error.h"
|
||||||
#include "internal/eval.h"
|
#include "internal/eval.h"
|
||||||
#include "internal/hash.h"
|
#include "internal/hash.h"
|
||||||
|
#include "internal/namespace.h"
|
||||||
#include "internal/object.h"
|
#include "internal/object.h"
|
||||||
#include "internal/gc.h"
|
#include "internal/gc.h"
|
||||||
#include "internal/re.h"
|
#include "internal/re.h"
|
||||||
@ -109,10 +110,10 @@ classname(VALUE klass, bool *permanent)
|
|||||||
{
|
{
|
||||||
*permanent = false;
|
*permanent = false;
|
||||||
|
|
||||||
VALUE classpath = RCLASS_EXT(klass)->classpath;
|
VALUE classpath = RCLASS_CLASSPATH(klass);
|
||||||
if (classpath == 0) return Qnil;
|
if (classpath == 0) return Qnil;
|
||||||
|
|
||||||
*permanent = RCLASS_EXT(klass)->permanent_classpath;
|
*permanent = RCLASS_PERMANENT_CLASSPATH_P(klass);
|
||||||
|
|
||||||
return classpath;
|
return classpath;
|
||||||
}
|
}
|
||||||
@ -210,7 +211,7 @@ static enum rb_id_table_iterator_result
|
|||||||
set_sub_temporary_name_i(ID id, VALUE val, void *data)
|
set_sub_temporary_name_i(ID id, VALUE val, void *data)
|
||||||
{
|
{
|
||||||
val = ((rb_const_entry_t *)val)->value;
|
val = ((rb_const_entry_t *)val)->value;
|
||||||
if (rb_namespace_p(val) && !RCLASS_EXT(val)->permanent_classpath) {
|
if (rb_namespace_p(val) && !RCLASS_PERMANENT_CLASSPATH_P(val)) {
|
||||||
VALUE arg = (VALUE)data;
|
VALUE arg = (VALUE)data;
|
||||||
struct sub_temporary_name_args *args = data;
|
struct sub_temporary_name_args *args = data;
|
||||||
args->last = id;
|
args->last = id;
|
||||||
@ -222,7 +223,7 @@ set_sub_temporary_name_i(ID id, VALUE val, void *data)
|
|||||||
static void
|
static void
|
||||||
set_sub_temporary_name_foreach(VALUE mod, struct sub_temporary_name_args *args, VALUE name)
|
set_sub_temporary_name_foreach(VALUE mod, struct sub_temporary_name_args *args, VALUE name)
|
||||||
{
|
{
|
||||||
RCLASS_SET_CLASSPATH(mod, name, FALSE);
|
RCLASS_WRITE_CLASSPATH(mod, name, FALSE);
|
||||||
struct rb_id_table *tbl = RCLASS_CONST_TBL(mod);
|
struct rb_id_table *tbl = RCLASS_CONST_TBL(mod);
|
||||||
if (!tbl) return;
|
if (!tbl) return;
|
||||||
if (!name) {
|
if (!name) {
|
||||||
@ -296,7 +297,7 @@ VALUE
|
|||||||
rb_mod_set_temporary_name(VALUE mod, VALUE name)
|
rb_mod_set_temporary_name(VALUE mod, VALUE name)
|
||||||
{
|
{
|
||||||
// We don't allow setting the name if the classpath is already permanent:
|
// We don't allow setting the name if the classpath is already permanent:
|
||||||
if (RCLASS_EXT(mod)->permanent_classpath) {
|
if (RCLASS_PERMANENT_CLASSPATH_P(mod)) {
|
||||||
rb_raise(rb_eRuntimeError, "can't change permanent name");
|
rb_raise(rb_eRuntimeError, "can't change permanent name");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -529,6 +530,7 @@ struct rb_global_variable {
|
|||||||
rb_gvar_marker_t *marker;
|
rb_gvar_marker_t *marker;
|
||||||
rb_gvar_compact_t *compactor;
|
rb_gvar_compact_t *compactor;
|
||||||
struct trace_var *trace;
|
struct trace_var *trace;
|
||||||
|
bool namespace_ready;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct rb_global_entry {
|
struct rb_global_entry {
|
||||||
@ -604,6 +606,13 @@ rb_gvar_ractor_local(const char *name)
|
|||||||
entry->ractor_local = true;
|
entry->ractor_local = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_gvar_namespace_ready(const char *name)
|
||||||
|
{
|
||||||
|
struct rb_global_entry *entry = rb_find_global_entry(rb_intern(name));
|
||||||
|
entry->var->namespace_ready = true;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rb_gvar_undef_compactor(void *var)
|
rb_gvar_undef_compactor(void *var)
|
||||||
{
|
{
|
||||||
@ -629,6 +638,7 @@ rb_global_entry(ID id)
|
|||||||
|
|
||||||
var->block_trace = 0;
|
var->block_trace = 0;
|
||||||
var->trace = 0;
|
var->trace = 0;
|
||||||
|
var->namespace_ready = false;
|
||||||
rb_id_table_insert(rb_global_tbl, id, (VALUE)entry);
|
rb_id_table_insert(rb_global_tbl, id, (VALUE)entry);
|
||||||
}
|
}
|
||||||
return entry;
|
return entry;
|
||||||
@ -982,13 +992,27 @@ rb_gvar_set_entry(struct rb_global_entry *entry, VALUE val)
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define USE_NAMESPACE_GVAR_TBL(ns,entry) \
|
||||||
|
(NAMESPACE_OPTIONAL_P(ns) && \
|
||||||
|
(!entry || !entry->var->namespace_ready || entry->var->setter != rb_gvar_readonly_setter))
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_gvar_set(ID id, VALUE val)
|
rb_gvar_set(ID id, VALUE val)
|
||||||
{
|
{
|
||||||
|
VALUE retval;
|
||||||
struct rb_global_entry *entry;
|
struct rb_global_entry *entry;
|
||||||
|
const rb_namespace_t *ns = rb_current_namespace();
|
||||||
|
|
||||||
entry = rb_global_entry(id);
|
entry = rb_global_entry(id);
|
||||||
|
|
||||||
return rb_gvar_set_entry(entry, val);
|
if (USE_NAMESPACE_GVAR_TBL(ns, entry)) {
|
||||||
|
rb_hash_aset(ns->gvar_tbl, rb_id2sym(entry->id), val);
|
||||||
|
retval = val;
|
||||||
|
// TODO: think about trace
|
||||||
|
} else {
|
||||||
|
retval = rb_gvar_set_entry(entry, val);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
@ -1000,9 +1024,27 @@ rb_gv_set(const char *name, VALUE val)
|
|||||||
VALUE
|
VALUE
|
||||||
rb_gvar_get(ID id)
|
rb_gvar_get(ID id)
|
||||||
{
|
{
|
||||||
|
VALUE retval, gvars, key;
|
||||||
struct rb_global_entry *entry = rb_global_entry(id);
|
struct rb_global_entry *entry = rb_global_entry(id);
|
||||||
struct rb_global_variable *var = entry->var;
|
struct rb_global_variable *var = entry->var;
|
||||||
return (*var->getter)(entry->id, var->data);
|
const rb_namespace_t *ns = rb_current_namespace();
|
||||||
|
|
||||||
|
if (USE_NAMESPACE_GVAR_TBL(ns, entry)) {
|
||||||
|
gvars = ns->gvar_tbl;
|
||||||
|
key = rb_id2sym(entry->id);
|
||||||
|
if (RTEST(rb_hash_has_key(gvars, key))) { // this gvar is already cached
|
||||||
|
retval = rb_hash_aref(gvars, key);
|
||||||
|
} else {
|
||||||
|
retval = (*var->getter)(entry->id, var->data);
|
||||||
|
if (rb_obj_respond_to(retval, rb_intern("clone"), 1)) {
|
||||||
|
retval = rb_funcall(retval, rb_intern("clone"), 0);
|
||||||
|
}
|
||||||
|
rb_hash_aset(gvars, key, retval);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
retval = (*var->getter)(entry->id, var->data);
|
||||||
|
}
|
||||||
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
@ -1056,6 +1098,7 @@ rb_f_global_variables(void)
|
|||||||
if (!rb_ractor_main_p()) {
|
if (!rb_ractor_main_p()) {
|
||||||
rb_raise(rb_eRactorIsolationError, "can not access global variables from non-main Ractors");
|
rb_raise(rb_eRactorIsolationError, "can not access global variables from non-main Ractors");
|
||||||
}
|
}
|
||||||
|
/* gvar access (get/set) in namespaces creates gvar entries globally */
|
||||||
|
|
||||||
rb_id_table_foreach(rb_global_tbl, gvar_i, (void *)ary);
|
rb_id_table_foreach(rb_global_tbl, gvar_i, (void *)ary);
|
||||||
if (!NIL_P(backref)) {
|
if (!NIL_P(backref)) {
|
||||||
@ -1335,7 +1378,7 @@ rb_obj_field_get(VALUE obj, rb_shape_t *target_shape)
|
|||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
ASSERT_vm_locking();
|
ASSERT_vm_locking();
|
||||||
fields = RCLASS_FIELDS(obj);
|
fields = RCLASS_PRIME_FIELDS(obj);
|
||||||
break;
|
break;
|
||||||
case T_OBJECT:
|
case T_OBJECT:
|
||||||
fields = ROBJECT_FIELDS(obj);
|
fields = ROBJECT_FIELDS(obj);
|
||||||
@ -1392,7 +1435,7 @@ rb_ivar_lookup(VALUE obj, ID id, VALUE undef)
|
|||||||
found = rb_shape_get_iv_index(shape, id, &index);
|
found = rb_shape_get_iv_index(shape, id, &index);
|
||||||
|
|
||||||
if (found) {
|
if (found) {
|
||||||
ivar_list = RCLASS_FIELDS(obj);
|
ivar_list = RCLASS_PRIME_FIELDS(obj);
|
||||||
RUBY_ASSERT(ivar_list);
|
RUBY_ASSERT(ivar_list);
|
||||||
|
|
||||||
val = ivar_list[index];
|
val = ivar_list[index];
|
||||||
@ -1501,7 +1544,7 @@ rb_ivar_delete(VALUE obj, ID id, VALUE undef)
|
|||||||
switch (BUILTIN_TYPE(obj)) {
|
switch (BUILTIN_TYPE(obj)) {
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
table = RCLASS_FIELDS_HASH(obj);
|
table = RCLASS_WRITABLE_FIELDS_HASH(obj);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_OBJECT:
|
case T_OBJECT:
|
||||||
@ -1551,7 +1594,7 @@ obj_transition_too_complex(VALUE obj, st_table *table)
|
|||||||
break;
|
break;
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
old_fields = RCLASS_FIELDS(obj);
|
old_fields = RCLASS_PRIME_FIELDS(obj);
|
||||||
rb_shape_set_shape_id(obj, shape_id);
|
rb_shape_set_shape_id(obj, shape_id);
|
||||||
RCLASS_SET_FIELDS_HASH(obj, table);
|
RCLASS_SET_FIELDS_HASH(obj, table);
|
||||||
break;
|
break;
|
||||||
@ -2124,7 +2167,7 @@ rb_ivar_defined(VALUE obj, ID id)
|
|||||||
switch (BUILTIN_TYPE(obj)) {
|
switch (BUILTIN_TYPE(obj)) {
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
table = (st_table *)RCLASS_FIELDS(obj);
|
table = (st_table *)RCLASS_FIELDS_HASH(obj);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_OBJECT:
|
case T_OBJECT:
|
||||||
@ -2188,7 +2231,8 @@ iterate_over_shapes_with_callback(rb_shape_t *shape, rb_ivar_foreach_callback_fu
|
|||||||
break;
|
break;
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
iv_list = RCLASS_FIELDS(itr_data->obj);
|
RUBY_ASSERT(!rb_shape_obj_too_complex_p(itr_data->obj));
|
||||||
|
iv_list = RCLASS_PRIME_FIELDS(itr_data->obj);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
iv_list = itr_data->fields_tbl->as.shape.fields;
|
iv_list = itr_data->fields_tbl->as.shape.fields;
|
||||||
@ -2280,7 +2324,7 @@ class_fields_each(VALUE obj, rb_ivar_foreach_callback_func *func, st_data_t arg,
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (rb_shape_obj_too_complex_p(obj)) {
|
if (rb_shape_obj_too_complex_p(obj)) {
|
||||||
rb_st_foreach(RCLASS_FIELDS_HASH(obj), each_hash_iv, (st_data_t)&itr_data);
|
rb_st_foreach(RCLASS_WRITABLE_FIELDS_HASH(obj), each_hash_iv, (st_data_t)&itr_data);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
iterate_over_shapes_with_callback(shape, func, &itr_data);
|
iterate_over_shapes_with_callback(shape, func, &itr_data);
|
||||||
@ -2701,7 +2745,7 @@ autoload_data(VALUE mod, ID id)
|
|||||||
// If we are called with a non-origin ICLASS, fetch the autoload data from
|
// If we are called with a non-origin ICLASS, fetch the autoload data from
|
||||||
// the original module.
|
// the original module.
|
||||||
if (RB_TYPE_P(mod, T_ICLASS)) {
|
if (RB_TYPE_P(mod, T_ICLASS)) {
|
||||||
if (FL_TEST_RAW(mod, RICLASS_IS_ORIGIN)) {
|
if (RICLASS_IS_ORIGIN_P(mod)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -2729,6 +2773,10 @@ struct autoload_const {
|
|||||||
// The shared "autoload_data" if multiple constants are defined from the same feature.
|
// The shared "autoload_data" if multiple constants are defined from the same feature.
|
||||||
VALUE autoload_data_value;
|
VALUE autoload_data_value;
|
||||||
|
|
||||||
|
// The namespace object when the autoload is called in a user namespace
|
||||||
|
// Otherwise, Qnil means the builtin namespace, Qfalse means unspecified.
|
||||||
|
VALUE namespace;
|
||||||
|
|
||||||
// The module we are loading a constant into.
|
// The module we are loading a constant into.
|
||||||
VALUE module;
|
VALUE module;
|
||||||
|
|
||||||
@ -2866,6 +2914,70 @@ get_autoload_data(VALUE autoload_const_value, struct autoload_const **autoload_c
|
|||||||
return autoload_data;
|
return autoload_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct autoload_copy_table_data {
|
||||||
|
VALUE dst_tbl_value;
|
||||||
|
struct st_table *dst_tbl;
|
||||||
|
const rb_namespace_t *ns;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
autoload_copy_table_for_namespace_i(st_data_t key, st_data_t value, st_data_t arg)
|
||||||
|
{
|
||||||
|
struct autoload_const *autoload_const;
|
||||||
|
struct autoload_copy_table_data *data = (struct autoload_copy_table_data *)arg;
|
||||||
|
struct st_table *tbl = data->dst_tbl;
|
||||||
|
VALUE tbl_value = data->dst_tbl_value;
|
||||||
|
const rb_namespace_t *ns = data->ns;
|
||||||
|
|
||||||
|
VALUE src_value = (VALUE)value;
|
||||||
|
struct autoload_const *src_const = rb_check_typeddata(src_value, &autoload_const_type);
|
||||||
|
// autoload_data can be shared between copies because the feature is equal between copies.
|
||||||
|
VALUE autoload_data_value = src_const->autoload_data_value;
|
||||||
|
struct autoload_data *autoload_data = rb_check_typeddata(autoload_data_value, &autoload_data_type);
|
||||||
|
|
||||||
|
VALUE new_value = TypedData_Make_Struct(0, struct autoload_const, &autoload_const_type, autoload_const);
|
||||||
|
autoload_const->namespace = rb_get_namespace_object((rb_namespace_t *)ns);
|
||||||
|
autoload_const->module = src_const->module;
|
||||||
|
autoload_const->name = src_const->name;
|
||||||
|
autoload_const->value = src_const->value;
|
||||||
|
autoload_const->flag = src_const->flag;
|
||||||
|
autoload_const->autoload_data_value = autoload_data_value;
|
||||||
|
ccan_list_add_tail(&autoload_data->constants, &autoload_const->cnode);
|
||||||
|
|
||||||
|
st_insert(tbl, (st_data_t)autoload_const->name, (st_data_t)new_value);
|
||||||
|
RB_OBJ_WRITTEN(tbl_value, Qundef, new_value);
|
||||||
|
|
||||||
|
return ST_CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_autoload_copy_table_for_namespace(st_table *iv_ptr, const rb_namespace_t *ns)
|
||||||
|
{
|
||||||
|
struct st_table *src_tbl, *dst_tbl;
|
||||||
|
VALUE src_tbl_value, dst_tbl_value;
|
||||||
|
if (!rb_st_lookup(iv_ptr, (st_data_t)autoload, (st_data_t *)&src_tbl_value)) {
|
||||||
|
// the class has no autoload table yet.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!RTEST(src_tbl_value) || !(src_tbl = check_autoload_table(src_tbl_value))) {
|
||||||
|
// the __autoload__ ivar value isn't autoload table value.
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
src_tbl = check_autoload_table(src_tbl_value);
|
||||||
|
|
||||||
|
dst_tbl_value = TypedData_Wrap_Struct(0, &autoload_table_type, NULL);
|
||||||
|
RTYPEDDATA_DATA(dst_tbl_value) = dst_tbl = st_init_numtable();
|
||||||
|
|
||||||
|
struct autoload_copy_table_data data = {
|
||||||
|
.dst_tbl_value = dst_tbl_value,
|
||||||
|
.dst_tbl = dst_tbl,
|
||||||
|
.ns = ns,
|
||||||
|
};
|
||||||
|
|
||||||
|
st_foreach(src_tbl, autoload_copy_table_for_namespace_i, (st_data_t)&data);
|
||||||
|
st_insert(iv_ptr, (st_data_t)autoload, (st_data_t)dst_tbl_value);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
rb_autoload(VALUE module, ID name, const char *feature)
|
rb_autoload(VALUE module, ID name, const char *feature)
|
||||||
{
|
{
|
||||||
@ -2883,6 +2995,7 @@ struct autoload_arguments {
|
|||||||
VALUE module;
|
VALUE module;
|
||||||
ID name;
|
ID name;
|
||||||
VALUE feature;
|
VALUE feature;
|
||||||
|
VALUE namespace;
|
||||||
};
|
};
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
@ -2952,6 +3065,7 @@ autoload_synchronized(VALUE _arguments)
|
|||||||
{
|
{
|
||||||
struct autoload_const *autoload_const;
|
struct autoload_const *autoload_const;
|
||||||
VALUE autoload_const_value = TypedData_Make_Struct(0, struct autoload_const, &autoload_const_type, autoload_const);
|
VALUE autoload_const_value = TypedData_Make_Struct(0, struct autoload_const, &autoload_const_type, autoload_const);
|
||||||
|
autoload_const->namespace = arguments->namespace;
|
||||||
autoload_const->module = arguments->module;
|
autoload_const->module = arguments->module;
|
||||||
autoload_const->name = arguments->name;
|
autoload_const->name = arguments->name;
|
||||||
autoload_const->value = Qundef;
|
autoload_const->value = Qundef;
|
||||||
@ -2968,6 +3082,9 @@ autoload_synchronized(VALUE _arguments)
|
|||||||
void
|
void
|
||||||
rb_autoload_str(VALUE module, ID name, VALUE feature)
|
rb_autoload_str(VALUE module, ID name, VALUE feature)
|
||||||
{
|
{
|
||||||
|
const rb_namespace_t *ns = rb_current_namespace();
|
||||||
|
VALUE current_namespace = rb_get_namespace_object((rb_namespace_t *)ns);
|
||||||
|
|
||||||
if (!rb_is_const_id(name)) {
|
if (!rb_is_const_id(name)) {
|
||||||
rb_raise(rb_eNameError, "autoload must be constant name: %"PRIsVALUE"", QUOTE_ID(name));
|
rb_raise(rb_eNameError, "autoload must be constant name: %"PRIsVALUE"", QUOTE_ID(name));
|
||||||
}
|
}
|
||||||
@ -2981,6 +3098,7 @@ rb_autoload_str(VALUE module, ID name, VALUE feature)
|
|||||||
.module = module,
|
.module = module,
|
||||||
.name = name,
|
.name = name,
|
||||||
.feature = feature,
|
.feature = feature,
|
||||||
|
.namespace = current_namespace,
|
||||||
};
|
};
|
||||||
|
|
||||||
VALUE result = rb_mutex_synchronize(autoload_mutex, autoload_synchronized, (VALUE)&arguments);
|
VALUE result = rb_mutex_synchronize(autoload_mutex, autoload_synchronized, (VALUE)&arguments);
|
||||||
@ -3241,22 +3359,82 @@ autoload_apply_constants(VALUE _arguments)
|
|||||||
return Qtrue;
|
return Qtrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct autoload_feature_require_data {
|
||||||
|
struct autoload_load_arguments *arguments;
|
||||||
|
VALUE receiver;
|
||||||
|
VALUE feature;
|
||||||
|
};
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
autoload_feature_require_in_builtin(VALUE arg)
|
||||||
|
{
|
||||||
|
struct autoload_feature_require_data *data = (struct autoload_feature_require_data *)arg;
|
||||||
|
|
||||||
|
VALUE result = rb_funcall(data->receiver, rb_intern("require"), 1, data->feature);
|
||||||
|
if (RTEST(result)) {
|
||||||
|
return rb_mutex_synchronize(autoload_mutex, autoload_apply_constants, (VALUE)data->arguments);
|
||||||
|
}
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
autoload_feature_require_ensure_in_builtin(VALUE _arg)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* The gccct should be cleared again after the rb_funcall() to remove
|
||||||
|
* the inconsistent cache entry against the current namespace.
|
||||||
|
*/
|
||||||
|
rb_gccct_clear_table(Qnil);
|
||||||
|
rb_namespace_disable_builtin();
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
|
static VALUE
|
||||||
|
autoload_feature_require_in_builtin_wrap(VALUE arg)
|
||||||
|
{
|
||||||
|
return rb_ensure(autoload_feature_require_in_builtin, arg,
|
||||||
|
autoload_feature_require_ensure_in_builtin, Qnil);
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
autoload_feature_require(VALUE _arguments)
|
autoload_feature_require(VALUE _arguments)
|
||||||
{
|
{
|
||||||
|
VALUE receiver = rb_vm_top_self();
|
||||||
|
|
||||||
struct autoload_load_arguments *arguments = (struct autoload_load_arguments*)_arguments;
|
struct autoload_load_arguments *arguments = (struct autoload_load_arguments*)_arguments;
|
||||||
|
|
||||||
struct autoload_const *autoload_const = arguments->autoload_const;
|
struct autoload_const *autoload_const = arguments->autoload_const;
|
||||||
|
VALUE autoload_namespace = autoload_const->namespace;
|
||||||
|
|
||||||
// We save this for later use in autoload_apply_constants:
|
// We save this for later use in autoload_apply_constants:
|
||||||
arguments->autoload_data = rb_check_typeddata(autoload_const->autoload_data_value, &autoload_data_type);
|
arguments->autoload_data = rb_check_typeddata(autoload_const->autoload_data_value, &autoload_data_type);
|
||||||
|
|
||||||
VALUE result = rb_funcall(rb_vm_top_self(), rb_intern("require"), 1, arguments->autoload_data->feature);
|
if (NIL_P(autoload_namespace)) {
|
||||||
|
rb_namespace_enable_builtin();
|
||||||
|
/*
|
||||||
|
* Clear the global cc cache table because the require method can be different from the current
|
||||||
|
* namespace's one and it may cause inconsistent cc-cme states.
|
||||||
|
* For example, the assertion below may fail in gccct_method_search();
|
||||||
|
* VM_ASSERT(vm_cc_check_cme(cc, rb_callable_method_entry(klass, mid)))
|
||||||
|
*/
|
||||||
|
rb_gccct_clear_table(Qnil);
|
||||||
|
struct autoload_feature_require_data data = {
|
||||||
|
.arguments = arguments,
|
||||||
|
.receiver = receiver,
|
||||||
|
.feature = arguments->autoload_data->feature,
|
||||||
|
};
|
||||||
|
return rb_namespace_exec(rb_builtin_namespace(), autoload_feature_require_in_builtin_wrap, (VALUE)&data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (RTEST(autoload_namespace) && NAMESPACE_OPTIONAL_P(rb_get_namespace_t(autoload_namespace))) {
|
||||||
|
receiver = autoload_namespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE result = rb_funcall(receiver, rb_intern("require"), 1, arguments->autoload_data->feature);
|
||||||
|
|
||||||
if (RTEST(result)) {
|
if (RTEST(result)) {
|
||||||
return rb_mutex_synchronize(autoload_mutex, autoload_apply_constants, _arguments);
|
return rb_mutex_synchronize(autoload_mutex, autoload_apply_constants, _arguments);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3580,6 +3758,8 @@ rb_mod_remove_const(VALUE mod, VALUE name)
|
|||||||
return rb_const_remove(mod, id);
|
return rb_const_remove(mod, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static rb_const_entry_t * const_lookup(struct rb_id_table *tbl, ID id);
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_const_remove(VALUE mod, ID id)
|
rb_const_remove(VALUE mod, ID id)
|
||||||
{
|
{
|
||||||
@ -3589,7 +3769,7 @@ rb_const_remove(VALUE mod, ID id)
|
|||||||
rb_check_frozen(mod);
|
rb_check_frozen(mod);
|
||||||
|
|
||||||
ce = rb_const_lookup(mod, id);
|
ce = rb_const_lookup(mod, id);
|
||||||
if (!ce || !rb_id_table_delete(RCLASS_CONST_TBL(mod), id)) {
|
if (!ce || !rb_id_table_delete(RCLASS_WRITABLE_CONST_TBL(mod), id)) {
|
||||||
if (rb_const_defined_at(mod, id)) {
|
if (rb_const_defined_at(mod, id)) {
|
||||||
rb_name_err_raise("cannot remove %2$s::%1$s", mod, ID2SYM(id));
|
rb_name_err_raise("cannot remove %2$s::%1$s", mod, ID2SYM(id));
|
||||||
}
|
}
|
||||||
@ -3607,7 +3787,11 @@ rb_const_remove(VALUE mod, ID id)
|
|||||||
val = Qnil;
|
val = Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
ruby_xfree(ce);
|
if (ce == const_lookup(RCLASS_PRIME_CONST_TBL(mod), id)) {
|
||||||
|
// skip free'ing the ce because it still exists in the prime classext
|
||||||
|
} else {
|
||||||
|
ruby_xfree(ce);
|
||||||
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@ -3829,8 +4013,8 @@ set_namespace_path_i(ID id, VALUE v, void *payload)
|
|||||||
}
|
}
|
||||||
set_namespace_path(value, build_const_path(parental_path, id));
|
set_namespace_path(value, build_const_path(parental_path, id));
|
||||||
|
|
||||||
if (!RCLASS_EXT(value)->permanent_classpath) {
|
if (!RCLASS_PERMANENT_CLASSPATH_P(value)) {
|
||||||
RCLASS_SET_CLASSPATH(value, 0, false);
|
RCLASS_WRITE_CLASSPATH(value, 0, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ID_TABLE_CONTINUE;
|
return ID_TABLE_CONTINUE;
|
||||||
@ -3848,7 +4032,7 @@ set_namespace_path(VALUE named_namespace, VALUE namespace_path)
|
|||||||
|
|
||||||
RB_VM_LOCK_ENTER();
|
RB_VM_LOCK_ENTER();
|
||||||
{
|
{
|
||||||
RCLASS_SET_CLASSPATH(named_namespace, namespace_path, true);
|
RCLASS_WRITE_CLASSPATH(named_namespace, namespace_path, true);
|
||||||
|
|
||||||
if (const_table) {
|
if (const_table) {
|
||||||
rb_id_table_foreach(const_table, set_namespace_path_i, &namespace_path);
|
rb_id_table_foreach(const_table, set_namespace_path_i, &namespace_path);
|
||||||
@ -3884,9 +4068,10 @@ const_set(VALUE klass, ID id, VALUE val)
|
|||||||
|
|
||||||
RB_VM_LOCK_ENTER();
|
RB_VM_LOCK_ENTER();
|
||||||
{
|
{
|
||||||
struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
|
struct rb_id_table *tbl = RCLASS_WRITABLE_CONST_TBL(klass);
|
||||||
if (!tbl) {
|
if (!tbl) {
|
||||||
RCLASS_CONST_TBL(klass) = tbl = rb_id_table_create(0);
|
tbl = rb_id_table_create(0);
|
||||||
|
RCLASS_WRITE_CONST_TBL(klass, tbl, false);
|
||||||
rb_clear_constant_cache_for_id(id);
|
rb_clear_constant_cache_for_id(id);
|
||||||
ce = ZALLOC(rb_const_entry_t);
|
ce = ZALLOC(rb_const_entry_t);
|
||||||
rb_id_table_insert(tbl, id, (VALUE)ce);
|
rb_id_table_insert(tbl, id, (VALUE)ce);
|
||||||
@ -4010,6 +4195,7 @@ const_tbl_update(struct autoload_const *ac, int autoload_force)
|
|||||||
setup_const_entry(ce, klass, val, visibility);
|
setup_const_entry(ce, klass, val, visibility);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
tbl = RCLASS_WRITABLE_CONST_TBL(klass);
|
||||||
rb_clear_constant_cache_for_id(id);
|
rb_clear_constant_cache_for_id(id);
|
||||||
|
|
||||||
ce = ZALLOC(rb_const_entry_t);
|
ce = ZALLOC(rb_const_entry_t);
|
||||||
@ -4172,7 +4358,7 @@ static int
|
|||||||
cvar_lookup_at(VALUE klass, ID id, st_data_t *v)
|
cvar_lookup_at(VALUE klass, ID id, st_data_t *v)
|
||||||
{
|
{
|
||||||
if (RB_TYPE_P(klass, T_ICLASS)) {
|
if (RB_TYPE_P(klass, T_ICLASS)) {
|
||||||
if (FL_TEST_RAW(klass, RICLASS_IS_ORIGIN)) {
|
if (RICLASS_IS_ORIGIN_P(klass)) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -4277,10 +4463,11 @@ rb_cvar_set(VALUE klass, ID id, VALUE val)
|
|||||||
|
|
||||||
int result = rb_class_ivar_set(target, id, val);
|
int result = rb_class_ivar_set(target, id, val);
|
||||||
|
|
||||||
struct rb_id_table *rb_cvc_tbl = RCLASS_CVC_TBL(target);
|
struct rb_id_table *rb_cvc_tbl = RCLASS_WRITABLE_CVC_TBL(target);
|
||||||
|
|
||||||
if (!rb_cvc_tbl) {
|
if (!rb_cvc_tbl) {
|
||||||
rb_cvc_tbl = RCLASS_CVC_TBL(target) = rb_id_table_create(2);
|
rb_cvc_tbl = rb_id_table_create(2);
|
||||||
|
RCLASS_WRITE_CVC_TBL(target, rb_cvc_tbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct rb_cvar_class_tbl_entry *ent;
|
struct rb_cvar_class_tbl_entry *ent;
|
||||||
@ -4304,7 +4491,7 @@ rb_cvar_set(VALUE klass, ID id, VALUE val)
|
|||||||
// cvar in this lookup.
|
// cvar in this lookup.
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
if (RB_TYPE_P(target, T_CLASS)) {
|
if (RB_TYPE_P(target, T_CLASS)) {
|
||||||
if (RCLASS_SUBCLASSES(target)) {
|
if (RCLASS_SUBCLASSES_FIRST(target)) {
|
||||||
rb_class_foreach_subclass(target, check_for_cvar_table, id);
|
rb_class_foreach_subclass(target, check_for_cvar_table, id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4538,13 +4725,13 @@ class_ivar_set_shape_fields(VALUE obj, void *_data)
|
|||||||
{
|
{
|
||||||
RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
|
RUBY_ASSERT(!rb_shape_obj_too_complex_p(obj));
|
||||||
|
|
||||||
return RCLASS_FIELDS(obj);
|
return RCLASS_PRIME_FIELDS(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
class_ivar_set_shape_resize_fields(VALUE obj, attr_index_t _old_capa, attr_index_t new_capa, void *_data)
|
class_ivar_set_shape_resize_fields(VALUE obj, attr_index_t _old_capa, attr_index_t new_capa, void *_data)
|
||||||
{
|
{
|
||||||
REALLOC_N(RCLASS_FIELDS(obj), VALUE, new_capa);
|
REALLOC_N(RCLASS_PRIME_FIELDS(obj), VALUE, new_capa);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
@ -4564,7 +4751,7 @@ class_ivar_set_too_complex_table(VALUE obj, void *_data)
|
|||||||
{
|
{
|
||||||
RUBY_ASSERT(rb_shape_obj_too_complex_p(obj));
|
RUBY_ASSERT(rb_shape_obj_too_complex_p(obj));
|
||||||
|
|
||||||
return RCLASS_FIELDS_HASH(obj);
|
return RCLASS_WRITABLE_FIELDS_HASH(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -4574,6 +4761,8 @@ rb_class_ivar_set(VALUE obj, ID id, VALUE val)
|
|||||||
bool existing = false;
|
bool existing = false;
|
||||||
rb_check_frozen(obj);
|
rb_check_frozen(obj);
|
||||||
|
|
||||||
|
rb_class_ensure_writable(obj);
|
||||||
|
|
||||||
RB_VM_LOCK_ENTER();
|
RB_VM_LOCK_ENTER();
|
||||||
{
|
{
|
||||||
existing = general_ivar_set(obj, id, val, NULL,
|
existing = general_ivar_set(obj, id, val, NULL,
|
||||||
@ -4620,11 +4809,9 @@ rb_fields_tbl_copy(VALUE dst, VALUE src)
|
|||||||
rb_ivar_foreach(src, tbl_copy_i, dst);
|
rb_ivar_foreach(src, tbl_copy_i, dst);
|
||||||
}
|
}
|
||||||
|
|
||||||
rb_const_entry_t *
|
static rb_const_entry_t *
|
||||||
rb_const_lookup(VALUE klass, ID id)
|
const_lookup(struct rb_id_table *tbl, ID id)
|
||||||
{
|
{
|
||||||
struct rb_id_table *tbl = RCLASS_CONST_TBL(klass);
|
|
||||||
|
|
||||||
if (tbl) {
|
if (tbl) {
|
||||||
VALUE val;
|
VALUE val;
|
||||||
bool r;
|
bool r;
|
||||||
@ -4638,3 +4825,9 @@ rb_const_lookup(VALUE klass, ID id)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rb_const_entry_t *
|
||||||
|
rb_const_lookup(VALUE klass, ID id)
|
||||||
|
{
|
||||||
|
return const_lookup(RCLASS_CONST_TBL(klass), id);
|
||||||
|
}
|
||||||
|
63
vm.c
63
vm.c
@ -21,6 +21,7 @@
|
|||||||
#include "internal/gc.h"
|
#include "internal/gc.h"
|
||||||
#include "internal/inits.h"
|
#include "internal/inits.h"
|
||||||
#include "internal/missing.h"
|
#include "internal/missing.h"
|
||||||
|
#include "internal/namespace.h"
|
||||||
#include "internal/object.h"
|
#include "internal/object.h"
|
||||||
#include "internal/proc.h"
|
#include "internal/proc.h"
|
||||||
#include "internal/re.h"
|
#include "internal/re.h"
|
||||||
@ -1164,6 +1165,7 @@ vm_proc_create_from_captured(VALUE klass,
|
|||||||
{
|
{
|
||||||
VALUE procval = rb_proc_alloc(klass);
|
VALUE procval = rb_proc_alloc(klass);
|
||||||
rb_proc_t *proc = RTYPEDDATA_DATA(procval);
|
rb_proc_t *proc = RTYPEDDATA_DATA(procval);
|
||||||
|
const rb_namespace_t *ns = rb_current_namespace();
|
||||||
|
|
||||||
VM_ASSERT(VM_EP_IN_HEAP_P(GET_EC(), captured->ep));
|
VM_ASSERT(VM_EP_IN_HEAP_P(GET_EC(), captured->ep));
|
||||||
|
|
||||||
@ -1173,6 +1175,7 @@ vm_proc_create_from_captured(VALUE klass,
|
|||||||
rb_vm_block_ep_update(procval, &proc->block, captured->ep);
|
rb_vm_block_ep_update(procval, &proc->block, captured->ep);
|
||||||
|
|
||||||
vm_block_type_set(&proc->block, block_type);
|
vm_block_type_set(&proc->block, block_type);
|
||||||
|
proc->ns = ns;
|
||||||
proc->is_from_method = is_from_method;
|
proc->is_from_method = is_from_method;
|
||||||
proc->is_lambda = is_lambda;
|
proc->is_lambda = is_lambda;
|
||||||
|
|
||||||
@ -1204,10 +1207,12 @@ proc_create(VALUE klass, const struct rb_block *block, int8_t is_from_method, in
|
|||||||
{
|
{
|
||||||
VALUE procval = rb_proc_alloc(klass);
|
VALUE procval = rb_proc_alloc(klass);
|
||||||
rb_proc_t *proc = RTYPEDDATA_DATA(procval);
|
rb_proc_t *proc = RTYPEDDATA_DATA(procval);
|
||||||
|
const rb_namespace_t *ns = rb_current_namespace();
|
||||||
|
|
||||||
VM_ASSERT(VM_EP_IN_HEAP_P(GET_EC(), vm_block_ep(block)));
|
VM_ASSERT(VM_EP_IN_HEAP_P(GET_EC(), vm_block_ep(block)));
|
||||||
rb_vm_block_copy(procval, &proc->block, block);
|
rb_vm_block_copy(procval, &proc->block, block);
|
||||||
vm_block_type_set(&proc->block, block->type);
|
vm_block_type_set(&proc->block, block->type);
|
||||||
|
proc->ns = ns;
|
||||||
proc->is_from_method = is_from_method;
|
proc->is_from_method = is_from_method;
|
||||||
proc->is_lambda = is_lambda;
|
proc->is_lambda = is_lambda;
|
||||||
|
|
||||||
@ -2182,7 +2187,7 @@ static void
|
|||||||
rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me, VALUE klass)
|
rb_vm_check_redefinition_opt_method(const rb_method_entry_t *me, VALUE klass)
|
||||||
{
|
{
|
||||||
st_data_t bop;
|
st_data_t bop;
|
||||||
if (RB_TYPE_P(klass, T_ICLASS) && FL_TEST(klass, RICLASS_IS_ORIGIN) &&
|
if (RB_TYPE_P(klass, T_ICLASS) && RICLASS_IS_ORIGIN_P(klass) &&
|
||||||
RB_TYPE_P(RBASIC_CLASS(klass), T_CLASS)) {
|
RB_TYPE_P(RBASIC_CLASS(klass), T_CLASS)) {
|
||||||
klass = RBASIC_CLASS(klass);
|
klass = RBASIC_CLASS(klass);
|
||||||
}
|
}
|
||||||
@ -2871,6 +2876,19 @@ rb_iseq_eval(const rb_iseq_t *iseq)
|
|||||||
rb_execution_context_t *ec = GET_EC();
|
rb_execution_context_t *ec = GET_EC();
|
||||||
VALUE val;
|
VALUE val;
|
||||||
vm_set_top_stack(ec, iseq);
|
vm_set_top_stack(ec, iseq);
|
||||||
|
// TODO: set the namespace frame like require/load
|
||||||
|
val = vm_exec(ec);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_iseq_eval_with_refinement(const rb_iseq_t *iseq, VALUE mod)
|
||||||
|
{
|
||||||
|
rb_execution_context_t *ec = GET_EC();
|
||||||
|
VALUE val;
|
||||||
|
vm_set_top_stack(ec, iseq);
|
||||||
|
rb_vm_using_module(mod);
|
||||||
|
// TODO: set the namespace frame like require/load
|
||||||
val = vm_exec(ec);
|
val = vm_exec(ec);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@ -2880,8 +2898,8 @@ rb_iseq_eval_main(const rb_iseq_t *iseq)
|
|||||||
{
|
{
|
||||||
rb_execution_context_t *ec = GET_EC();
|
rb_execution_context_t *ec = GET_EC();
|
||||||
VALUE val;
|
VALUE val;
|
||||||
|
|
||||||
vm_set_main_stack(ec, iseq);
|
vm_set_main_stack(ec, iseq);
|
||||||
|
// TODO: set the namespace frame like require/load
|
||||||
val = vm_exec(ec);
|
val = vm_exec(ec);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
@ -2934,6 +2952,26 @@ rb_vm_call_cfunc(VALUE recv, VALUE (*func)(VALUE), VALUE arg,
|
|||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_vm_call_cfunc2(VALUE recv, VALUE (*func)(VALUE, VALUE), VALUE arg1, VALUE arg2,
|
||||||
|
VALUE block_handler, VALUE filename)
|
||||||
|
{
|
||||||
|
rb_execution_context_t *ec = GET_EC();
|
||||||
|
const rb_control_frame_t *reg_cfp = ec->cfp;
|
||||||
|
const rb_iseq_t *iseq = rb_iseq_new(Qnil, filename, filename, Qnil, 0, ISEQ_TYPE_TOP);
|
||||||
|
VALUE val;
|
||||||
|
|
||||||
|
vm_push_frame(ec, iseq, VM_FRAME_MAGIC_TOP | VM_ENV_FLAG_LOCAL | VM_FRAME_FLAG_FINISH,
|
||||||
|
recv, block_handler,
|
||||||
|
(VALUE)vm_cref_new_toplevel(ec), /* cref or me */
|
||||||
|
0, reg_cfp->sp, 0, 0);
|
||||||
|
|
||||||
|
val = (*func)(arg1, arg2);
|
||||||
|
|
||||||
|
rb_vm_pop_frame(ec);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
/* vm */
|
/* vm */
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2956,6 +2994,7 @@ rb_vm_update_references(void *ptr)
|
|||||||
vm->loaded_features_realpaths = rb_gc_location(vm->loaded_features_realpaths);
|
vm->loaded_features_realpaths = rb_gc_location(vm->loaded_features_realpaths);
|
||||||
vm->loaded_features_realpath_map = rb_gc_location(vm->loaded_features_realpath_map);
|
vm->loaded_features_realpath_map = rb_gc_location(vm->loaded_features_realpath_map);
|
||||||
vm->top_self = rb_gc_location(vm->top_self);
|
vm->top_self = rb_gc_location(vm->top_self);
|
||||||
|
vm->require_stack = rb_gc_location(vm->require_stack);
|
||||||
vm->orig_progname = rb_gc_location(vm->orig_progname);
|
vm->orig_progname = rb_gc_location(vm->orig_progname);
|
||||||
|
|
||||||
rb_gc_update_values(RUBY_NSIG, vm->trap_list.cmd);
|
rb_gc_update_values(RUBY_NSIG, vm->trap_list.cmd);
|
||||||
@ -3027,6 +3066,10 @@ rb_vm_mark(void *ptr)
|
|||||||
rb_gc_mark_maybe(*list->varptr);
|
rb_gc_mark_maybe(*list->varptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (vm->main_namespace) {
|
||||||
|
rb_namespace_entry_mark((void *)vm->main_namespace);
|
||||||
|
}
|
||||||
|
|
||||||
rb_gc_mark_movable(vm->mark_object_ary);
|
rb_gc_mark_movable(vm->mark_object_ary);
|
||||||
rb_gc_mark_movable(vm->load_path);
|
rb_gc_mark_movable(vm->load_path);
|
||||||
rb_gc_mark_movable(vm->load_path_snapshot);
|
rb_gc_mark_movable(vm->load_path_snapshot);
|
||||||
@ -3036,6 +3079,7 @@ rb_vm_mark(void *ptr)
|
|||||||
rb_gc_mark_movable(vm->loaded_features_snapshot);
|
rb_gc_mark_movable(vm->loaded_features_snapshot);
|
||||||
rb_gc_mark_movable(vm->loaded_features_realpaths);
|
rb_gc_mark_movable(vm->loaded_features_realpaths);
|
||||||
rb_gc_mark_movable(vm->loaded_features_realpath_map);
|
rb_gc_mark_movable(vm->loaded_features_realpath_map);
|
||||||
|
rb_gc_mark_movable(vm->require_stack);
|
||||||
rb_gc_mark_movable(vm->top_self);
|
rb_gc_mark_movable(vm->top_self);
|
||||||
rb_gc_mark_movable(vm->orig_progname);
|
rb_gc_mark_movable(vm->orig_progname);
|
||||||
rb_gc_mark_movable(vm->coverages);
|
rb_gc_mark_movable(vm->coverages);
|
||||||
@ -3113,7 +3157,8 @@ ruby_vm_destruct(rb_vm_t *vm)
|
|||||||
rb_id_table_free(vm->negative_cme_table);
|
rb_id_table_free(vm->negative_cme_table);
|
||||||
st_free_table(vm->overloaded_cme_table);
|
st_free_table(vm->overloaded_cme_table);
|
||||||
|
|
||||||
rb_id_table_free(RCLASS(rb_mRubyVMFrozenCore)->m_tbl);
|
// TODO: Is this ignorable for classext->m_tbl ?
|
||||||
|
// rb_id_table_free(RCLASS(rb_mRubyVMFrozenCore)->m_tbl);
|
||||||
|
|
||||||
rb_shape_free_all();
|
rb_shape_free_all();
|
||||||
|
|
||||||
@ -3505,6 +3550,8 @@ thread_mark(void *ptr)
|
|||||||
rb_gc_mark(th->pending_interrupt_mask_stack);
|
rb_gc_mark(th->pending_interrupt_mask_stack);
|
||||||
rb_gc_mark(th->top_self);
|
rb_gc_mark(th->top_self);
|
||||||
rb_gc_mark(th->top_wrapper);
|
rb_gc_mark(th->top_wrapper);
|
||||||
|
rb_gc_mark(th->namespaces);
|
||||||
|
if (NAMESPACE_USER_P(th->ns)) rb_namespace_entry_mark(th->ns);
|
||||||
if (th->root_fiber) rb_fiber_mark_self(th->root_fiber);
|
if (th->root_fiber) rb_fiber_mark_self(th->root_fiber);
|
||||||
|
|
||||||
RUBY_ASSERT(th->ec == rb_fiberptr_get_ec(th->ec->fiber_ptr));
|
RUBY_ASSERT(th->ec == rb_fiberptr_get_ec(th->ec->fiber_ptr));
|
||||||
@ -3653,6 +3700,8 @@ th_init(rb_thread_t *th, VALUE self, rb_vm_t *vm)
|
|||||||
th->last_status = Qnil;
|
th->last_status = Qnil;
|
||||||
th->top_wrapper = 0;
|
th->top_wrapper = 0;
|
||||||
th->top_self = vm->top_self; // 0 while self == 0
|
th->top_self = vm->top_self; // 0 while self == 0
|
||||||
|
th->namespaces = 0;
|
||||||
|
th->ns = 0;
|
||||||
th->value = Qundef;
|
th->value = Qundef;
|
||||||
|
|
||||||
th->ec->errinfo = Qnil;
|
th->ec->errinfo = Qnil;
|
||||||
@ -3682,10 +3731,16 @@ th_init(rb_thread_t *th, VALUE self, rb_vm_t *vm)
|
|||||||
VALUE
|
VALUE
|
||||||
rb_thread_alloc(VALUE klass)
|
rb_thread_alloc(VALUE klass)
|
||||||
{
|
{
|
||||||
|
rb_namespace_t *ns;
|
||||||
|
rb_execution_context_t *ec = GET_EC();
|
||||||
VALUE self = thread_alloc(klass);
|
VALUE self = thread_alloc(klass);
|
||||||
rb_thread_t *target_th = rb_thread_ptr(self);
|
rb_thread_t *target_th = rb_thread_ptr(self);
|
||||||
target_th->ractor = GET_RACTOR();
|
target_th->ractor = GET_RACTOR();
|
||||||
th_init(target_th, self, target_th->vm = GET_VM());
|
th_init(target_th, self, target_th->vm = GET_VM());
|
||||||
|
if ((ns = rb_ec_thread_ptr(ec)->ns) == 0) {
|
||||||
|
ns = rb_main_namespace();
|
||||||
|
}
|
||||||
|
target_th->ns = ns;
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4234,6 +4289,8 @@ Init_VM(void)
|
|||||||
th->vm = vm;
|
th->vm = vm;
|
||||||
th->top_wrapper = 0;
|
th->top_wrapper = 0;
|
||||||
th->top_self = rb_vm_top_self();
|
th->top_self = rb_vm_top_self();
|
||||||
|
th->namespaces = 0;
|
||||||
|
th->ns = 0;
|
||||||
|
|
||||||
rb_vm_register_global_object((VALUE)iseq);
|
rb_vm_register_global_object((VALUE)iseq);
|
||||||
th->ec->cfp->iseq = iseq;
|
th->ec->cfp->iseq = iseq;
|
||||||
|
@ -597,10 +597,13 @@ vm_cc_check_cme(const struct rb_callcache *cc, const rb_callable_method_entry_t
|
|||||||
#if 1
|
#if 1
|
||||||
// debug print
|
// debug print
|
||||||
|
|
||||||
fprintf(stderr, "iseq_overload:%d\n", (int)cme->def->iseq_overload);
|
fprintf(stderr, "iseq_overload:%d, cme:%p (def:%p), cm_cc_cme(cc):%p (def:%p)\n",
|
||||||
|
(int)cme->def->iseq_overload,
|
||||||
|
cme, cme->def,
|
||||||
|
vm_cc_cme(cc), vm_cc_cme(cc)->def);
|
||||||
rp(cme);
|
rp(cme);
|
||||||
rp(vm_cc_cme(cc));
|
rp(vm_cc_cme(cc));
|
||||||
rb_vm_lookup_overloaded_cme(cme);
|
rp(rb_vm_lookup_overloaded_cme(cme));
|
||||||
#endif
|
#endif
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
24
vm_core.h
24
vm_core.h
@ -118,6 +118,7 @@ extern int ruby_assert_critical_section_entered;
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
#include "internal/array.h"
|
#include "internal/array.h"
|
||||||
#include "internal/basic_operators.h"
|
#include "internal/basic_operators.h"
|
||||||
|
#include "internal/namespace.h"
|
||||||
#include "internal/sanitizers.h"
|
#include "internal/sanitizers.h"
|
||||||
#include "internal/serial.h"
|
#include "internal/serial.h"
|
||||||
#include "internal/set_table.h"
|
#include "internal/set_table.h"
|
||||||
@ -312,6 +313,7 @@ struct rb_calling_info {
|
|||||||
int argc;
|
int argc;
|
||||||
bool kw_splat;
|
bool kw_splat;
|
||||||
VALUE heap_argv;
|
VALUE heap_argv;
|
||||||
|
const rb_namespace_t *proc_ns;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifndef VM_ARGC_STACK_MAX
|
#ifndef VM_ARGC_STACK_MAX
|
||||||
@ -743,6 +745,9 @@ typedef struct rb_vm_struct {
|
|||||||
struct global_object_list *global_object_list;
|
struct global_object_list *global_object_list;
|
||||||
const VALUE special_exceptions[ruby_special_error_count];
|
const VALUE special_exceptions[ruby_special_error_count];
|
||||||
|
|
||||||
|
/* namespace */
|
||||||
|
rb_namespace_t *main_namespace;
|
||||||
|
|
||||||
/* load */
|
/* load */
|
||||||
VALUE top_self;
|
VALUE top_self;
|
||||||
VALUE load_path;
|
VALUE load_path;
|
||||||
@ -818,6 +823,8 @@ typedef struct rb_vm_struct {
|
|||||||
size_t fiber_machine_stack_size;
|
size_t fiber_machine_stack_size;
|
||||||
} default_params;
|
} default_params;
|
||||||
|
|
||||||
|
// TODO: a single require_stack can't support multi-threaded require trees
|
||||||
|
VALUE require_stack;
|
||||||
} rb_vm_t;
|
} rb_vm_t;
|
||||||
|
|
||||||
/* default values */
|
/* default values */
|
||||||
@ -1119,6 +1126,9 @@ typedef struct rb_thread_struct {
|
|||||||
/* for load(true) */
|
/* for load(true) */
|
||||||
VALUE top_self;
|
VALUE top_self;
|
||||||
VALUE top_wrapper;
|
VALUE top_wrapper;
|
||||||
|
/* for namespace */
|
||||||
|
VALUE namespaces; // Stack of namespaces
|
||||||
|
rb_namespace_t *ns; // The current one
|
||||||
|
|
||||||
/* thread control */
|
/* thread control */
|
||||||
|
|
||||||
@ -1258,6 +1268,7 @@ RUBY_SYMBOL_EXPORT_END
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const struct rb_block block;
|
const struct rb_block block;
|
||||||
|
const rb_namespace_t *ns;
|
||||||
unsigned int is_from_method: 1; /* bool */
|
unsigned int is_from_method: 1; /* bool */
|
||||||
unsigned int is_lambda: 1; /* bool */
|
unsigned int is_lambda: 1; /* bool */
|
||||||
unsigned int is_isolated: 1; /* bool */
|
unsigned int is_isolated: 1; /* bool */
|
||||||
@ -1349,11 +1360,11 @@ typedef rb_control_frame_t *
|
|||||||
|
|
||||||
enum vm_frame_env_flags {
|
enum vm_frame_env_flags {
|
||||||
/* Frame/Environment flag bits:
|
/* Frame/Environment flag bits:
|
||||||
* MMMM MMMM MMMM MMMM ____ FFFF FFFE EEEX (LSB)
|
* MMMM MMMM MMMM MMMM __FF FFFF FFFE EEEX (LSB)
|
||||||
*
|
*
|
||||||
* X : tag for GC marking (It seems as Fixnum)
|
* X : tag for GC marking (It seems as Fixnum)
|
||||||
* EEE : 4 bits Env flags
|
* EEE : 4 bits Env flags
|
||||||
* FF..: 7 bits Frame flags
|
* FF..: 9 bits Frame flags
|
||||||
* MM..: 15 bits frame magic (to check frame corruption)
|
* MM..: 15 bits frame magic (to check frame corruption)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -1378,6 +1389,8 @@ enum vm_frame_env_flags {
|
|||||||
VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM = 0x0200,
|
VM_FRAME_FLAG_MODIFIED_BLOCK_PARAM = 0x0200,
|
||||||
VM_FRAME_FLAG_CFRAME_KW = 0x0400,
|
VM_FRAME_FLAG_CFRAME_KW = 0x0400,
|
||||||
VM_FRAME_FLAG_PASSED = 0x0800,
|
VM_FRAME_FLAG_PASSED = 0x0800,
|
||||||
|
VM_FRAME_FLAG_NS_SWITCH = 0x1000,
|
||||||
|
VM_FRAME_FLAG_LOAD_ISEQ = 0x2000,
|
||||||
|
|
||||||
/* env flag */
|
/* env flag */
|
||||||
VM_ENV_FLAG_LOCAL = 0x0002,
|
VM_ENV_FLAG_LOCAL = 0x0002,
|
||||||
@ -1476,6 +1489,12 @@ VM_FRAME_RUBYFRAME_P(const rb_control_frame_t *cfp)
|
|||||||
return !VM_FRAME_CFRAME_P(cfp);
|
return !VM_FRAME_CFRAME_P(cfp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline int
|
||||||
|
VM_FRAME_NS_SWITCH_P(const rb_control_frame_t *cfp)
|
||||||
|
{
|
||||||
|
return VM_ENV_FLAGS(cfp->ep, VM_FRAME_FLAG_NS_SWITCH) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
#define RUBYVM_CFUNC_FRAME_P(cfp) \
|
#define RUBYVM_CFUNC_FRAME_P(cfp) \
|
||||||
(VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC)
|
(VM_FRAME_TYPE(cfp) == VM_FRAME_MAGIC_CFUNC)
|
||||||
|
|
||||||
@ -1823,6 +1842,7 @@ NORETURN(void rb_bug_for_fatal_signal(ruby_sighandler_t default_sighandler, int
|
|||||||
/* functions about thread/vm execution */
|
/* functions about thread/vm execution */
|
||||||
RUBY_SYMBOL_EXPORT_BEGIN
|
RUBY_SYMBOL_EXPORT_BEGIN
|
||||||
VALUE rb_iseq_eval(const rb_iseq_t *iseq);
|
VALUE rb_iseq_eval(const rb_iseq_t *iseq);
|
||||||
|
VALUE rb_iseq_eval_with_refinement(const rb_iseq_t *iseq, VALUE mod);
|
||||||
VALUE rb_iseq_eval_main(const rb_iseq_t *iseq);
|
VALUE rb_iseq_eval_main(const rb_iseq_t *iseq);
|
||||||
VALUE rb_iseq_path(const rb_iseq_t *iseq);
|
VALUE rb_iseq_path(const rb_iseq_t *iseq);
|
||||||
VALUE rb_iseq_realpath(const rb_iseq_t *iseq);
|
VALUE rb_iseq_realpath(const rb_iseq_t *iseq);
|
||||||
|
29
vm_eval.c
29
vm_eval.c
@ -400,9 +400,9 @@ static inline const rb_callable_method_entry_t *rb_search_method_entry(VALUE rec
|
|||||||
static inline enum method_missing_reason rb_method_call_status(rb_execution_context_t *ec, const rb_callable_method_entry_t *me, call_type scope, VALUE self);
|
static inline enum method_missing_reason rb_method_call_status(rb_execution_context_t *ec, const rb_callable_method_entry_t *me, call_type scope, VALUE self);
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
gccct_hash(VALUE klass, ID mid)
|
gccct_hash(VALUE klass, VALUE namespace, ID mid)
|
||||||
{
|
{
|
||||||
return (klass >> 3) ^ (VALUE)mid;
|
return ((klass ^ namespace) >> 3) ^ (VALUE)mid;
|
||||||
}
|
}
|
||||||
|
|
||||||
NOINLINE(static const struct rb_callcache *gccct_method_search_slowpath(rb_vm_t *vm, VALUE klass, unsigned int index, const struct rb_callinfo * ci));
|
NOINLINE(static const struct rb_callcache *gccct_method_search_slowpath(rb_vm_t *vm, VALUE klass, unsigned int index, const struct rb_callinfo * ci));
|
||||||
@ -447,7 +447,8 @@ scope_to_ci(call_type scope, ID mid, int argc, struct rb_callinfo *ci)
|
|||||||
static inline const struct rb_callcache *
|
static inline const struct rb_callcache *
|
||||||
gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, const struct rb_callinfo *ci)
|
gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, const struct rb_callinfo *ci)
|
||||||
{
|
{
|
||||||
VALUE klass;
|
VALUE klass, ns_value;
|
||||||
|
const rb_namespace_t *ns = rb_current_namespace();
|
||||||
|
|
||||||
if (!SPECIAL_CONST_P(recv)) {
|
if (!SPECIAL_CONST_P(recv)) {
|
||||||
klass = RBASIC_CLASS(recv);
|
klass = RBASIC_CLASS(recv);
|
||||||
@ -457,8 +458,13 @@ gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, const struct
|
|||||||
klass = CLASS_OF(recv);
|
klass = CLASS_OF(recv);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NAMESPACE_USER_P(ns)) {
|
||||||
|
ns_value = ns->ns_object;
|
||||||
|
} else {
|
||||||
|
ns_value = 0;
|
||||||
|
}
|
||||||
// search global method cache
|
// search global method cache
|
||||||
unsigned int index = (unsigned int)(gccct_hash(klass, mid) % VM_GLOBAL_CC_CACHE_TABLE_SIZE);
|
unsigned int index = (unsigned int)(gccct_hash(klass, ns_value, mid) % VM_GLOBAL_CC_CACHE_TABLE_SIZE);
|
||||||
rb_vm_t *vm = rb_ec_vm_ptr(ec);
|
rb_vm_t *vm = rb_ec_vm_ptr(ec);
|
||||||
const struct rb_callcache *cc = vm->global_cc_cache_table[index];
|
const struct rb_callcache *cc = vm->global_cc_cache_table[index];
|
||||||
|
|
||||||
@ -483,6 +489,17 @@ gccct_method_search(rb_execution_context_t *ec, VALUE recv, ID mid, const struct
|
|||||||
return gccct_method_search_slowpath(vm, klass, index, ci);
|
return gccct_method_search_slowpath(vm, klass, index, ci);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VALUE
|
||||||
|
rb_gccct_clear_table(VALUE _self)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
rb_vm_t *vm = GET_VM();
|
||||||
|
for (i=0; i<VM_GLOBAL_CC_CACHE_TABLE_SIZE; i++) {
|
||||||
|
vm->global_cc_cache_table[i] = NULL;
|
||||||
|
}
|
||||||
|
return Qnil;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @internal
|
* @internal
|
||||||
* calls the specified method.
|
* calls the specified method.
|
||||||
@ -1978,6 +1995,7 @@ eval_string_with_cref(VALUE self, VALUE src, rb_cref_t *cref, VALUE file, int li
|
|||||||
cref = vm_cref_dup(orig_cref);
|
cref = vm_cref_dup(orig_cref);
|
||||||
}
|
}
|
||||||
vm_set_eval_stack(ec, iseq, cref, &block);
|
vm_set_eval_stack(ec, iseq, cref, &block);
|
||||||
|
// TODO: set the namespace frame
|
||||||
|
|
||||||
/* kick */
|
/* kick */
|
||||||
return vm_exec(ec);
|
return vm_exec(ec);
|
||||||
@ -2000,6 +2018,8 @@ eval_string_with_scope(VALUE scope, VALUE src, VALUE file, int line)
|
|||||||
vm_bind_update_env(scope, bind, vm_make_env_object(ec, ec->cfp));
|
vm_bind_update_env(scope, bind, vm_make_env_object(ec, ec->cfp));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: set the namespace frame
|
||||||
|
|
||||||
/* kick */
|
/* kick */
|
||||||
return vm_exec(ec);
|
return vm_exec(ec);
|
||||||
}
|
}
|
||||||
@ -2865,6 +2885,7 @@ Init_vm_eval(void)
|
|||||||
rb_define_method(rb_eUncaughtThrow, "value", uncaught_throw_value, 0);
|
rb_define_method(rb_eUncaughtThrow, "value", uncaught_throw_value, 0);
|
||||||
rb_define_method(rb_eUncaughtThrow, "to_s", uncaught_throw_to_s, 0);
|
rb_define_method(rb_eUncaughtThrow, "to_s", uncaught_throw_to_s, 0);
|
||||||
|
|
||||||
|
rb_define_singleton_method(rb_cModule, "gccct_clear_table", rb_gccct_clear_table, 0);
|
||||||
id_result = rb_intern_const("result");
|
id_result = rb_intern_const("result");
|
||||||
id_tag = rb_intern_const("tag");
|
id_tag = rb_intern_const("tag");
|
||||||
id_value = rb_intern_const("value");
|
id_value = rb_intern_const("value");
|
||||||
|
@ -134,7 +134,7 @@ callable_method_entry_p(const rb_callable_method_entry_t *cme)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
VM_ASSERT(IMEMO_TYPE_P((VALUE)cme, imemo_ment));
|
VM_ASSERT(IMEMO_TYPE_P((VALUE)cme, imemo_ment), "imemo_type:%s", rb_imemo_name(imemo_type((VALUE)cme)));
|
||||||
|
|
||||||
if (callable_class_p(cme->defined_class)) {
|
if (callable_class_p(cme->defined_class)) {
|
||||||
return TRUE;
|
return TRUE;
|
||||||
@ -418,7 +418,7 @@ vm_push_frame(rb_execution_context_t *ec,
|
|||||||
#if VM_DEBUG_BP_CHECK
|
#if VM_DEBUG_BP_CHECK
|
||||||
.bp_check = sp,
|
.bp_check = sp,
|
||||||
#endif
|
#endif
|
||||||
.jit_return = NULL
|
.jit_return = NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Ensure the initialization of `*cfp` above never gets reordered with the update of `ec->cfp` below.
|
/* Ensure the initialization of `*cfp` above never gets reordered with the update of `ec->cfp` below.
|
||||||
@ -963,7 +963,7 @@ vm_get_const_key_cref(const VALUE *ep)
|
|||||||
|
|
||||||
while (cref) {
|
while (cref) {
|
||||||
if (RCLASS_SINGLETON_P(CREF_CLASS(cref)) ||
|
if (RCLASS_SINGLETON_P(CREF_CLASS(cref)) ||
|
||||||
RCLASS_EXT(CREF_CLASS(cref))->cloned) {
|
RCLASS_CLONED_P(CREF_CLASS(cref)) ) {
|
||||||
return key_cref;
|
return key_cref;
|
||||||
}
|
}
|
||||||
cref = CREF_NEXT(cref);
|
cref = CREF_NEXT(cref);
|
||||||
@ -1256,7 +1256,7 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ivar_list = RCLASS_FIELDS(obj);
|
ivar_list = RCLASS_PRIME_FIELDS(obj);
|
||||||
|
|
||||||
#if !SHAPE_IN_BASIC_FLAGS
|
#if !SHAPE_IN_BASIC_FLAGS
|
||||||
shape_id = RCLASS_SHAPE_ID(obj);
|
shape_id = RCLASS_SHAPE_ID(obj);
|
||||||
@ -1335,7 +1335,7 @@ vm_getivar(VALUE obj, ID id, const rb_iseq_t *iseq, IVC ic, const struct rb_call
|
|||||||
switch (BUILTIN_TYPE(obj)) {
|
switch (BUILTIN_TYPE(obj)) {
|
||||||
case T_CLASS:
|
case T_CLASS:
|
||||||
case T_MODULE:
|
case T_MODULE:
|
||||||
table = (st_table *)RCLASS_FIELDS(obj);
|
table = (st_table *)RCLASS_FIELDS_HASH(obj);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case T_OBJECT:
|
case T_OBJECT:
|
||||||
@ -2079,7 +2079,7 @@ static const struct rb_callcache *
|
|||||||
vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
|
vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
|
||||||
{
|
{
|
||||||
const ID mid = vm_ci_mid(ci);
|
const ID mid = vm_ci_mid(ci);
|
||||||
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
|
struct rb_id_table *cc_tbl = RCLASS_WRITABLE_CC_TBL(klass);
|
||||||
struct rb_class_cc_entries *ccs = NULL;
|
struct rb_class_cc_entries *ccs = NULL;
|
||||||
VALUE ccs_data;
|
VALUE ccs_data;
|
||||||
|
|
||||||
@ -2125,7 +2125,8 @@ vm_search_cc(const VALUE klass, const struct rb_callinfo * const ci)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
cc_tbl = RCLASS_CC_TBL(klass) = rb_id_table_create(2);
|
cc_tbl = rb_id_table_create(2);
|
||||||
|
RCLASS_WRITE_CC_TBL(klass, cc_tbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
RB_DEBUG_COUNTER_INC(cc_not_found_in_ccs);
|
RB_DEBUG_COUNTER_INC(cc_not_found_in_ccs);
|
||||||
@ -4123,7 +4124,7 @@ rb_find_defined_class_by_owner(VALUE current_class, VALUE target_owner)
|
|||||||
VALUE klass = current_class;
|
VALUE klass = current_class;
|
||||||
|
|
||||||
/* for prepended Module, then start from cover class */
|
/* for prepended Module, then start from cover class */
|
||||||
if (RB_TYPE_P(klass, T_ICLASS) && FL_TEST(klass, RICLASS_IS_ORIGIN) &&
|
if (RB_TYPE_P(klass, T_ICLASS) && RICLASS_IS_ORIGIN_P(klass) &&
|
||||||
RB_TYPE_P(RBASIC_CLASS(klass), T_CLASS)) {
|
RB_TYPE_P(RBASIC_CLASS(klass), T_CLASS)) {
|
||||||
klass = RBASIC_CLASS(klass);
|
klass = RBASIC_CLASS(klass);
|
||||||
}
|
}
|
||||||
@ -5109,6 +5110,20 @@ block_proc_is_lambda(const VALUE procval)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline const rb_namespace_t *
|
||||||
|
block_proc_namespace(const VALUE procval)
|
||||||
|
{
|
||||||
|
rb_proc_t *proc;
|
||||||
|
|
||||||
|
if (procval) {
|
||||||
|
GetProcPtr(procval, proc);
|
||||||
|
return proc->ns;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static VALUE
|
static VALUE
|
||||||
vm_yield_with_cfunc(rb_execution_context_t *ec,
|
vm_yield_with_cfunc(rb_execution_context_t *ec,
|
||||||
const struct rb_captured_block *captured,
|
const struct rb_captured_block *captured,
|
||||||
@ -5259,11 +5274,16 @@ vm_invoke_iseq_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
|
|||||||
VALUE * const rsp = GET_SP() - calling->argc;
|
VALUE * const rsp = GET_SP() - calling->argc;
|
||||||
VALUE * const argv = rsp;
|
VALUE * const argv = rsp;
|
||||||
int opt_pc = vm_callee_setup_block_arg(ec, calling, ci, iseq, argv, is_lambda ? arg_setup_method : arg_setup_block);
|
int opt_pc = vm_callee_setup_block_arg(ec, calling, ci, iseq, argv, is_lambda ? arg_setup_method : arg_setup_block);
|
||||||
|
int frame_flag = VM_FRAME_MAGIC_BLOCK | (is_lambda ? VM_FRAME_FLAG_LAMBDA : 0);
|
||||||
|
|
||||||
SET_SP(rsp);
|
SET_SP(rsp);
|
||||||
|
|
||||||
|
if (calling->proc_ns) {
|
||||||
|
frame_flag |= VM_FRAME_FLAG_NS_SWITCH;
|
||||||
|
}
|
||||||
|
|
||||||
vm_push_frame(ec, iseq,
|
vm_push_frame(ec, iseq,
|
||||||
VM_FRAME_MAGIC_BLOCK | (is_lambda ? VM_FRAME_FLAG_LAMBDA : 0),
|
frame_flag,
|
||||||
captured->self,
|
captured->self,
|
||||||
VM_GUARDED_PREV_EP(captured->ep), 0,
|
VM_GUARDED_PREV_EP(captured->ep), 0,
|
||||||
ISEQ_BODY(iseq)->iseq_encoded + opt_pc,
|
ISEQ_BODY(iseq)->iseq_encoded + opt_pc,
|
||||||
@ -5362,6 +5382,9 @@ vm_invoke_proc_block(rb_execution_context_t *ec, rb_control_frame_t *reg_cfp,
|
|||||||
{
|
{
|
||||||
while (vm_block_handler_type(block_handler) == block_handler_type_proc) {
|
while (vm_block_handler_type(block_handler) == block_handler_type_proc) {
|
||||||
VALUE proc = VM_BH_TO_PROC(block_handler);
|
VALUE proc = VM_BH_TO_PROC(block_handler);
|
||||||
|
if (!calling->proc_ns) {
|
||||||
|
calling->proc_ns = block_proc_namespace(proc);
|
||||||
|
}
|
||||||
is_lambda = block_proc_is_lambda(proc);
|
is_lambda = block_proc_is_lambda(proc);
|
||||||
block_handler = vm_proc_to_block_handler(proc);
|
block_handler = vm_proc_to_block_handler(proc);
|
||||||
}
|
}
|
||||||
@ -5812,6 +5835,7 @@ vm_define_class(ID id, rb_num_t flags, VALUE cbase, VALUE super)
|
|||||||
|
|
||||||
/* find klass */
|
/* find klass */
|
||||||
rb_autoload_load(cbase, id);
|
rb_autoload_load(cbase, id);
|
||||||
|
|
||||||
if ((klass = vm_const_get_under(id, flags, cbase)) != 0) {
|
if ((klass = vm_const_get_under(id, flags, cbase)) != 0) {
|
||||||
if (!vm_check_if_class(id, flags, super, klass))
|
if (!vm_check_if_class(id, flags, super, klass))
|
||||||
unmatched_redefinition("class", cbase, id, klass);
|
unmatched_redefinition("class", cbase, id, klass);
|
||||||
@ -5913,8 +5937,7 @@ vm_define_method(const rb_execution_context_t *ec, VALUE obj, ID id, VALUE iseqv
|
|||||||
rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, visi);
|
rb_add_method_iseq(klass, id, (const rb_iseq_t *)iseqval, cref, visi);
|
||||||
// Set max_iv_count on klasses based on number of ivar sets that are in the initialize method
|
// Set max_iv_count on klasses based on number of ivar sets that are in the initialize method
|
||||||
if (id == idInitialize && klass != rb_cObject && RB_TYPE_P(klass, T_CLASS) && (rb_get_alloc_func(klass) == rb_class_allocate_instance)) {
|
if (id == idInitialize && klass != rb_cObject && RB_TYPE_P(klass, T_CLASS) && (rb_get_alloc_func(klass) == rb_class_allocate_instance)) {
|
||||||
|
RCLASS_WRITE_MAX_IV_COUNT(klass, rb_estimate_iv_count(klass, (const rb_iseq_t *)iseqval));
|
||||||
RCLASS_EXT(klass)->max_iv_count = rb_estimate_iv_count(klass, (const rb_iseq_t *)iseqval);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_singleton && vm_scope_module_func_check(ec)) {
|
if (!is_singleton && vm_scope_module_func_check(ec)) {
|
||||||
|
197
vm_method.c
197
vm_method.c
@ -39,7 +39,7 @@ vm_ccs_dump_i(ID mid, VALUE val, void *data)
|
|||||||
static void
|
static void
|
||||||
vm_ccs_dump(VALUE klass, ID target_mid)
|
vm_ccs_dump(VALUE klass, ID target_mid)
|
||||||
{
|
{
|
||||||
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
|
struct rb_id_table *cc_tbl = RCLASS_WRITABLE_CC_TBL(klass);
|
||||||
if (cc_tbl) {
|
if (cc_tbl) {
|
||||||
VALUE ccs;
|
VALUE ccs;
|
||||||
if (target_mid) {
|
if (target_mid) {
|
||||||
@ -87,18 +87,18 @@ vm_mtbl_dump(VALUE klass, ID target_mid)
|
|||||||
else {
|
else {
|
||||||
fprintf(stderr, " MTBL: NULL\n");
|
fprintf(stderr, " MTBL: NULL\n");
|
||||||
}
|
}
|
||||||
if (RCLASS_CALLABLE_M_TBL(klass)) {
|
if (RCLASS_WRITABLE_CALLABLE_M_TBL(klass)) {
|
||||||
if (target_mid != 0) {
|
if (target_mid != 0) {
|
||||||
if (rb_id_table_lookup(RCLASS_CALLABLE_M_TBL(klass), target_mid, &me)) {
|
if (rb_id_table_lookup(RCLASS_WRITABLE_CALLABLE_M_TBL(klass), target_mid, &me)) {
|
||||||
rp_m(" [CM**] ", me);
|
rp_m(" [CM**] ", me);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
fprintf(stderr, " ## RCLASS_CALLABLE_M_TBL\n");
|
fprintf(stderr, " ## RCLASS_CALLABLE_M_TBL\n");
|
||||||
rb_id_table_foreach(RCLASS_CALLABLE_M_TBL(klass), vm_cme_dump_i, NULL);
|
rb_id_table_foreach(RCLASS_WRITABLE_CALLABLE_M_TBL(klass), vm_cme_dump_i, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (RCLASS_CC_TBL(klass)) {
|
if (RCLASS_WRITABLE_CC_TBL(klass)) {
|
||||||
vm_ccs_dump(klass, target_mid);
|
vm_ccs_dump(klass, target_mid);
|
||||||
}
|
}
|
||||||
klass = RCLASS_SUPER(klass);
|
klass = RCLASS_SUPER(klass);
|
||||||
@ -166,6 +166,78 @@ const rb_method_entry_t * rb_method_entry_clone(const rb_method_entry_t *src_me)
|
|||||||
static const rb_callable_method_entry_t *complemented_callable_method_entry(VALUE klass, ID id);
|
static const rb_callable_method_entry_t *complemented_callable_method_entry(VALUE klass, ID id);
|
||||||
static const rb_callable_method_entry_t *lookup_overloaded_cme(const rb_callable_method_entry_t *cme);
|
static const rb_callable_method_entry_t *lookup_overloaded_cme(const rb_callable_method_entry_t *cme);
|
||||||
|
|
||||||
|
static void
|
||||||
|
invalidate_method_cache_in_cc_table(struct rb_id_table *tbl, ID mid)
|
||||||
|
{
|
||||||
|
VALUE ccs_data;
|
||||||
|
if (tbl && rb_id_table_lookup(tbl, mid, &ccs_data)) {
|
||||||
|
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data;
|
||||||
|
rb_yjit_cme_invalidate((rb_callable_method_entry_t *)ccs->cme);
|
||||||
|
if (NIL_P(ccs->cme->owner)) invalidate_negative_cache(mid);
|
||||||
|
rb_vm_ccs_free(ccs);
|
||||||
|
rb_id_table_delete(tbl, mid);
|
||||||
|
RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_ccs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
invalidate_callable_method_entry_in_callable_m_table(struct rb_id_table *tbl, ID mid)
|
||||||
|
{
|
||||||
|
VALUE cme;
|
||||||
|
if (tbl && rb_id_table_lookup(tbl, mid, &cme)) {
|
||||||
|
if (rb_yjit_enabled_p) {
|
||||||
|
rb_yjit_cme_invalidate((rb_callable_method_entry_t *)cme);
|
||||||
|
}
|
||||||
|
rb_id_table_delete(tbl, mid);
|
||||||
|
RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_callable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
struct invalidate_callable_method_entry_foreach_arg {
|
||||||
|
VALUE klass;
|
||||||
|
ID mid;
|
||||||
|
const rb_method_entry_t *cme;
|
||||||
|
const rb_method_entry_t *newer;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
invalidate_callable_method_entry_in_every_m_table_i(rb_classext_t *ext, bool is_prime, VALUE namespace, void *data)
|
||||||
|
{
|
||||||
|
st_data_t me;
|
||||||
|
struct invalidate_callable_method_entry_foreach_arg *arg = (struct invalidate_callable_method_entry_foreach_arg *)data;
|
||||||
|
struct rb_id_table *tbl = RCLASSEXT_M_TBL(ext);
|
||||||
|
|
||||||
|
if (rb_id_table_lookup(tbl, arg->mid, &me) && arg->cme == (const rb_method_entry_t *)me) {
|
||||||
|
rb_method_table_insert(arg->klass, tbl, arg->mid, arg->newer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
invalidate_callable_method_entry_in_every_m_table(VALUE klass, ID mid, const rb_callable_method_entry_t *cme)
|
||||||
|
{
|
||||||
|
// The argument cme must be invalidated later in the caller side
|
||||||
|
const rb_method_entry_t *newer = rb_method_entry_clone((const rb_method_entry_t *)cme);
|
||||||
|
struct invalidate_callable_method_entry_foreach_arg arg = {
|
||||||
|
.klass = klass,
|
||||||
|
.mid = mid,
|
||||||
|
.cme = (const rb_method_entry_t *) cme,
|
||||||
|
.newer = newer,
|
||||||
|
};
|
||||||
|
rb_class_classext_foreach(klass, invalidate_callable_method_entry_in_every_m_table_i, (void *)&arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
invalidate_complemented_method_entry_in_callable_m_table(struct rb_id_table *tbl, ID mid)
|
||||||
|
{
|
||||||
|
VALUE cme;
|
||||||
|
if (tbl && rb_id_table_lookup(tbl, mid, &cme)) {
|
||||||
|
if (rb_yjit_enabled_p) {
|
||||||
|
rb_yjit_cme_invalidate((rb_callable_method_entry_t *)cme);
|
||||||
|
}
|
||||||
|
rb_id_table_delete(tbl, mid);
|
||||||
|
RB_DEBUG_COUNTER_INC(cc_invalidate_tree_callable);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clear_method_cache_by_id_in_class(VALUE klass, ID mid)
|
clear_method_cache_by_id_in_class(VALUE klass, ID mid)
|
||||||
@ -174,33 +246,24 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
|
|||||||
if (rb_objspace_garbage_object_p(klass)) return;
|
if (rb_objspace_garbage_object_p(klass)) return;
|
||||||
|
|
||||||
RB_VM_LOCK_ENTER();
|
RB_VM_LOCK_ENTER();
|
||||||
if (LIKELY(RCLASS_SUBCLASSES(klass) == NULL)) {
|
if (LIKELY(RCLASS_SUBCLASSES_FIRST(klass) == NULL)) {
|
||||||
// no subclasses
|
// no subclasses
|
||||||
// check only current class
|
// check only current class
|
||||||
|
|
||||||
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
|
|
||||||
VALUE ccs_data;
|
|
||||||
|
|
||||||
// invalidate CCs
|
// invalidate CCs
|
||||||
if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
|
struct rb_id_table *cc_tbl = RCLASS_WRITABLE_CC_TBL(klass);
|
||||||
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)ccs_data;
|
invalidate_method_cache_in_cc_table(cc_tbl, mid);
|
||||||
rb_yjit_cme_invalidate((rb_callable_method_entry_t *)ccs->cme);
|
if (RCLASS_CC_TBL_NOT_PRIME_P(klass, cc_tbl)) {
|
||||||
if (NIL_P(ccs->cme->owner)) invalidate_negative_cache(mid);
|
invalidate_method_cache_in_cc_table(RCLASS_PRIME_CC_TBL(klass), mid);
|
||||||
rb_vm_ccs_free(ccs);
|
|
||||||
rb_id_table_delete(cc_tbl, mid);
|
|
||||||
RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_ccs);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// remove from callable_m_tbl, if exists
|
// remove from callable_m_tbl, if exists
|
||||||
struct rb_id_table *cm_tbl;
|
struct rb_id_table *cm_tbl = RCLASS_WRITABLE_CALLABLE_M_TBL(klass);
|
||||||
if ((cm_tbl = RCLASS_CALLABLE_M_TBL(klass)) != NULL) {
|
invalidate_callable_method_entry_in_callable_m_table(cm_tbl, mid);
|
||||||
VALUE cme;
|
if (RCLASS_CALLABLE_M_TBL_NOT_PRIME_P(klass, cm_tbl)) {
|
||||||
if (rb_yjit_enabled_p && rb_id_table_lookup(cm_tbl, mid, &cme)) {
|
invalidate_callable_method_entry_in_callable_m_table(RCLASS_PRIME_CALLABLE_M_TBL(klass), mid);
|
||||||
rb_yjit_cme_invalidate((rb_callable_method_entry_t *)cme);
|
|
||||||
}
|
|
||||||
rb_id_table_delete(cm_tbl, mid);
|
|
||||||
RB_DEBUG_COUNTER_INC(cc_invalidate_leaf_callable);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RB_DEBUG_COUNTER_INC(cc_invalidate_leaf);
|
RB_DEBUG_COUNTER_INC(cc_invalidate_leaf);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -223,10 +286,9 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
|
|||||||
else {
|
else {
|
||||||
klass_housing_cme = RCLASS_ORIGIN(owner);
|
klass_housing_cme = RCLASS_ORIGIN(owner);
|
||||||
}
|
}
|
||||||
// replace the cme that will be invalid
|
|
||||||
VM_ASSERT(lookup_method_table(klass_housing_cme, mid) == (const rb_method_entry_t *)cme);
|
// replace the cme that will be invalid in the all classexts
|
||||||
const rb_method_entry_t *new_cme = rb_method_entry_clone((const rb_method_entry_t *)cme);
|
invalidate_callable_method_entry_in_every_m_table(klass_housing_cme, mid, cme);
|
||||||
rb_method_table_insert(klass_housing_cme, RCLASS_M_TBL(klass_housing_cme), mid, new_cme);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vm_cme_invalidate((rb_callable_method_entry_t *)cme);
|
vm_cme_invalidate((rb_callable_method_entry_t *)cme);
|
||||||
@ -234,7 +296,7 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
|
|||||||
|
|
||||||
// In case of refinement ME, also invalidate the wrapped ME that
|
// In case of refinement ME, also invalidate the wrapped ME that
|
||||||
// could be cached at some callsite and is unreachable from any
|
// could be cached at some callsite and is unreachable from any
|
||||||
// RCLASS_CC_TBL.
|
// RCLASS_WRITABLE_CC_TBL.
|
||||||
if (cme->def->type == VM_METHOD_TYPE_REFINED && cme->def->body.refined.orig_me) {
|
if (cme->def->type == VM_METHOD_TYPE_REFINED && cme->def->body.refined.orig_me) {
|
||||||
vm_cme_invalidate((rb_callable_method_entry_t *)cme->def->body.refined.orig_me);
|
vm_cme_invalidate((rb_callable_method_entry_t *)cme->def->body.refined.orig_me);
|
||||||
}
|
}
|
||||||
@ -250,11 +312,12 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
|
|||||||
// invalidate complement tbl
|
// invalidate complement tbl
|
||||||
if (METHOD_ENTRY_COMPLEMENTED(cme)) {
|
if (METHOD_ENTRY_COMPLEMENTED(cme)) {
|
||||||
VALUE defined_class = cme->defined_class;
|
VALUE defined_class = cme->defined_class;
|
||||||
struct rb_id_table *cm_tbl = RCLASS_CALLABLE_M_TBL(defined_class);
|
struct rb_id_table *cm_tbl = RCLASS_WRITABLE_CALLABLE_M_TBL(defined_class);
|
||||||
VM_ASSERT(cm_tbl != NULL);
|
invalidate_complemented_method_entry_in_callable_m_table(cm_tbl, mid);
|
||||||
int r = rb_id_table_delete(cm_tbl, mid);
|
if (RCLASS_CALLABLE_M_TBL_NOT_PRIME_P(defined_class, cm_tbl)) {
|
||||||
VM_ASSERT(r == TRUE); (void)r;
|
struct rb_id_table *prime_cm_table = RCLASS_PRIME_CALLABLE_M_TBL(defined_class);
|
||||||
RB_DEBUG_COUNTER_INC(cc_invalidate_tree_callable);
|
invalidate_complemented_method_entry_in_callable_m_table(prime_cm_table, mid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RB_DEBUG_COUNTER_INC(cc_invalidate_tree);
|
RB_DEBUG_COUNTER_INC(cc_invalidate_tree);
|
||||||
@ -263,6 +326,9 @@ clear_method_cache_by_id_in_class(VALUE klass, ID mid)
|
|||||||
invalidate_negative_cache(mid);
|
invalidate_negative_cache(mid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rb_gccct_clear_table(Qnil);
|
||||||
|
|
||||||
RB_VM_LOCK_LEAVE();
|
RB_VM_LOCK_LEAVE();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -302,6 +368,32 @@ rb_clear_method_cache(VALUE klass_or_module, ID mid)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static enum rb_id_table_iterator_result
|
||||||
|
invalidate_method_entry_in_iclass_callable_m_tbl(VALUE cme, void *data)
|
||||||
|
{
|
||||||
|
vm_cme_invalidate((rb_callable_method_entry_t *)cme);
|
||||||
|
return ID_TABLE_DELETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static enum rb_id_table_iterator_result
|
||||||
|
invalidate_ccs_in_iclass_cc_tbl(VALUE value, void *data)
|
||||||
|
{
|
||||||
|
struct rb_class_cc_entries *ccs = (struct rb_class_cc_entries *)value;
|
||||||
|
vm_cme_invalidate((rb_callable_method_entry_t *)ccs->cme);
|
||||||
|
return ID_TABLE_DELETE;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_invalidate_method_caches(struct rb_id_table *cm_tbl, struct rb_id_table *cc_tbl)
|
||||||
|
{
|
||||||
|
if (cm_tbl) {
|
||||||
|
rb_id_table_foreach_values(cm_tbl, invalidate_method_entry_in_iclass_callable_m_tbl, NULL);
|
||||||
|
}
|
||||||
|
if (cc_tbl) {
|
||||||
|
rb_id_table_foreach_values(cc_tbl, invalidate_ccs_in_iclass_cc_tbl, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
invalidate_all_refinement_cc(void *vstart, void *vend, size_t stride, void *data)
|
invalidate_all_refinement_cc(void *vstart, void *vend, size_t stride, void *data)
|
||||||
{
|
{
|
||||||
@ -446,13 +538,18 @@ rb_clear_all_refinement_method_cache(void)
|
|||||||
|
|
||||||
void
|
void
|
||||||
rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me)
|
rb_method_table_insert(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me)
|
||||||
|
{
|
||||||
|
rb_method_table_insert0(klass, table, method_id, me, RB_TYPE_P(klass, T_ICLASS) && !RICLASS_OWNS_M_TBL_P(klass));
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rb_method_table_insert0(VALUE klass, struct rb_id_table *table, ID method_id, const rb_method_entry_t *me, bool iclass_shared_mtbl)
|
||||||
{
|
{
|
||||||
VALUE table_owner = klass;
|
VALUE table_owner = klass;
|
||||||
if (RB_TYPE_P(klass, T_ICLASS) && !RICLASS_OWNS_M_TBL_P(klass)) {
|
if (iclass_shared_mtbl) {
|
||||||
table_owner = RBASIC(table_owner)->klass;
|
table_owner = RBASIC(table_owner)->klass;
|
||||||
}
|
}
|
||||||
VM_ASSERT_TYPE3(table_owner, T_CLASS, T_ICLASS, T_MODULE);
|
VM_ASSERT_TYPE3(table_owner, T_CLASS, T_ICLASS, T_MODULE);
|
||||||
VM_ASSERT(table == RCLASS_M_TBL(table_owner));
|
|
||||||
rb_id_table_insert(table, method_id, (VALUE)me);
|
rb_id_table_insert(table, method_id, (VALUE)me);
|
||||||
RB_OBJ_WRITTEN(table_owner, Qundef, (VALUE)me);
|
RB_OBJ_WRITTEN(table_owner, Qundef, (VALUE)me);
|
||||||
}
|
}
|
||||||
@ -760,6 +857,7 @@ rb_method_definition_create(rb_method_type_t type, ID mid)
|
|||||||
def->original_id = mid;
|
def->original_id = mid;
|
||||||
static uintptr_t method_serial = 1;
|
static uintptr_t method_serial = 1;
|
||||||
def->method_serial = method_serial++;
|
def->method_serial = method_serial++;
|
||||||
|
def->ns = rb_current_namespace();
|
||||||
return def;
|
return def;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1003,7 +1101,7 @@ rb_method_entry_make(VALUE klass, ID mid, VALUE defined_class, rb_method_visibil
|
|||||||
rb_clear_method_cache(orig_klass, mid);
|
rb_clear_method_cache(orig_klass, mid);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mtbl = RCLASS_M_TBL(klass);
|
mtbl = RCLASS_WRITABLE_M_TBL(klass);
|
||||||
|
|
||||||
/* check re-definition */
|
/* check re-definition */
|
||||||
if (rb_id_table_lookup(mtbl, mid, &data)) {
|
if (rb_id_table_lookup(mtbl, mid, &data)) {
|
||||||
@ -1331,7 +1429,11 @@ search_method0(VALUE klass, ID id, VALUE *defined_class_ptr, bool skip_refined)
|
|||||||
|
|
||||||
if (me == NULL) RB_DEBUG_COUNTER_INC(mc_search_notfound);
|
if (me == NULL) RB_DEBUG_COUNTER_INC(mc_search_notfound);
|
||||||
|
|
||||||
VM_ASSERT(me == NULL || !METHOD_ENTRY_INVALIDATED(me));
|
VM_ASSERT(me == NULL || !METHOD_ENTRY_INVALIDATED(me),
|
||||||
|
"invalid me, mid:%s, klass:%s(%s)",
|
||||||
|
rb_id2name(id),
|
||||||
|
RTEST(rb_mod_name(klass)) ? RSTRING_PTR(rb_mod_name(klass)) : "anonymous",
|
||||||
|
rb_obj_info(klass));
|
||||||
return me;
|
return me;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1366,23 +1468,27 @@ prepare_callable_method_entry(VALUE defined_class, ID id, const rb_method_entry_
|
|||||||
struct rb_id_table *mtbl;
|
struct rb_id_table *mtbl;
|
||||||
const rb_callable_method_entry_t *cme;
|
const rb_callable_method_entry_t *cme;
|
||||||
VALUE cme_data;
|
VALUE cme_data;
|
||||||
|
int cme_found = 0;
|
||||||
|
|
||||||
if (me) {
|
if (me) {
|
||||||
if (me->defined_class == 0) {
|
if (me->defined_class == 0) {
|
||||||
RB_DEBUG_COUNTER_INC(mc_cme_complement);
|
RB_DEBUG_COUNTER_INC(mc_cme_complement);
|
||||||
VM_ASSERT_TYPE2(defined_class, T_ICLASS, T_MODULE);
|
VM_ASSERT_TYPE2(defined_class, T_ICLASS, T_MODULE);
|
||||||
|
|
||||||
mtbl = RCLASS_CALLABLE_M_TBL(defined_class);
|
mtbl = RCLASS_WRITABLE_CALLABLE_M_TBL(defined_class);
|
||||||
|
|
||||||
if (mtbl && rb_id_table_lookup(mtbl, id, &cme_data)) {
|
if (mtbl && rb_id_table_lookup(mtbl, id, &cme_data)) {
|
||||||
cme = (rb_callable_method_entry_t *)cme_data;
|
cme = (rb_callable_method_entry_t *)cme_data;
|
||||||
|
cme_found = 1;
|
||||||
|
}
|
||||||
|
if (cme_found) {
|
||||||
RB_DEBUG_COUNTER_INC(mc_cme_complement_hit);
|
RB_DEBUG_COUNTER_INC(mc_cme_complement_hit);
|
||||||
VM_ASSERT(callable_method_entry_p(cme));
|
VM_ASSERT(callable_method_entry_p(cme));
|
||||||
VM_ASSERT(!METHOD_ENTRY_INVALIDATED(cme));
|
VM_ASSERT(!METHOD_ENTRY_INVALIDATED(cme));
|
||||||
}
|
}
|
||||||
else if (create) {
|
else if (create) {
|
||||||
if (!mtbl) {
|
if (!mtbl) {
|
||||||
mtbl = RCLASS_EXT(defined_class)->callable_m_tbl = rb_id_table_create(0);
|
mtbl = rb_id_table_create(0);
|
||||||
|
RCLASS_WRITE_CALLABLE_M_TBL(defined_class, mtbl);
|
||||||
}
|
}
|
||||||
cme = rb_method_entry_complement_defined_class(me, me->called_id, defined_class);
|
cme = rb_method_entry_complement_defined_class(me, me->called_id, defined_class);
|
||||||
rb_id_table_insert(mtbl, id, (VALUE)cme);
|
rb_id_table_insert(mtbl, id, (VALUE)cme);
|
||||||
@ -1418,7 +1524,7 @@ cached_callable_method_entry(VALUE klass, ID mid)
|
|||||||
{
|
{
|
||||||
ASSERT_vm_locking();
|
ASSERT_vm_locking();
|
||||||
|
|
||||||
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
|
struct rb_id_table *cc_tbl = RCLASS_WRITABLE_CC_TBL(klass);
|
||||||
VALUE ccs_data;
|
VALUE ccs_data;
|
||||||
|
|
||||||
if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
|
if (cc_tbl && rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
|
||||||
@ -1446,11 +1552,12 @@ cache_callable_method_entry(VALUE klass, ID mid, const rb_callable_method_entry_
|
|||||||
ASSERT_vm_locking();
|
ASSERT_vm_locking();
|
||||||
VM_ASSERT(cme != NULL);
|
VM_ASSERT(cme != NULL);
|
||||||
|
|
||||||
struct rb_id_table *cc_tbl = RCLASS_CC_TBL(klass);
|
struct rb_id_table *cc_tbl = RCLASS_WRITABLE_CC_TBL(klass);
|
||||||
VALUE ccs_data;
|
VALUE ccs_data;
|
||||||
|
|
||||||
if (!cc_tbl) {
|
if (!cc_tbl) {
|
||||||
cc_tbl = RCLASS_CC_TBL(klass) = rb_id_table_create(2);
|
cc_tbl = rb_id_table_create(2);
|
||||||
|
RCLASS_WRITE_CC_TBL(klass, cc_tbl);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
|
if (rb_id_table_lookup(cc_tbl, mid, &ccs_data)) {
|
||||||
@ -1694,7 +1801,7 @@ remove_method(VALUE klass, ID mid)
|
|||||||
rb_clear_method_cache(self, mid);
|
rb_clear_method_cache(self, mid);
|
||||||
}
|
}
|
||||||
rb_clear_method_cache(klass, mid);
|
rb_clear_method_cache(klass, mid);
|
||||||
rb_id_table_delete(RCLASS_M_TBL(klass), mid);
|
rb_id_table_delete(RCLASS_WRITABLE_M_TBL(klass), mid);
|
||||||
|
|
||||||
rb_vm_check_redefinition_opt_method(me, klass);
|
rb_vm_check_redefinition_opt_method(me, klass);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user