summaryrefslogtreecommitdiff
path: root/internal
diff options
context:
space:
mode:
Diffstat (limited to 'internal')
-rw-r--r--internal/array.h82
-rw-r--r--internal/basic_operators.h63
-rw-r--r--internal/bignum.h3
-rw-r--r--internal/bits.h32
-rw-r--r--internal/class.h199
-rw-r--r--internal/cmdlineopt.h65
-rw-r--r--internal/compar.h33
-rw-r--r--internal/compile.h5
-rw-r--r--internal/compilers.h1
-rw-r--r--internal/complex.h1
-rw-r--r--internal/cont.h15
-rw-r--r--internal/dir.h1
-rw-r--r--internal/enc.h1
-rw-r--r--internal/encoding.h9
-rw-r--r--internal/enum.h1
-rw-r--r--internal/enumerator.h1
-rw-r--r--internal/error.h100
-rw-r--r--internal/eval.h2
-rw-r--r--internal/file.h1
-rw-r--r--internal/fixnum.h3
-rw-r--r--internal/gc.h244
-rw-r--r--internal/hash.h96
-rw-r--r--internal/imemo.h46
-rw-r--r--internal/inits.h4
-rw-r--r--internal/io.h107
-rw-r--r--internal/load.h1
-rw-r--r--internal/loadpath.h1
-rw-r--r--internal/math.h1
-rw-r--r--internal/missing.h2
-rw-r--r--internal/numeric.h31
-rw-r--r--internal/object.h32
-rw-r--r--internal/parse.h105
-rw-r--r--internal/proc.h3
-rw-r--r--internal/process.h20
-rw-r--r--internal/ractor.h6
-rw-r--r--internal/random.h2
-rw-r--r--internal/range.h5
-rw-r--r--internal/rational.h3
-rw-r--r--internal/re.h5
-rw-r--r--internal/ruby_parser.h102
-rw-r--r--internal/sanitizers.h162
-rw-r--r--internal/serial.h1
-rw-r--r--internal/signal.h6
-rw-r--r--internal/st.h11
-rw-r--r--internal/static_assert.h1
-rw-r--r--internal/string.h53
-rw-r--r--internal/struct.h45
-rw-r--r--internal/symbol.h6
-rw-r--r--internal/thread.h31
-rw-r--r--internal/time.h1
-rw-r--r--internal/transcode.h4
-rw-r--r--internal/util.h4
-rw-r--r--internal/variable.h68
-rw-r--r--internal/vm.h40
-rw-r--r--internal/warnings.h1
55 files changed, 1380 insertions, 488 deletions
diff --git a/internal/array.h b/internal/array.h
index 8dcfcdf2d7..39f6fcbea6 100644
--- a/internal/array.h
+++ b/internal/array.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_ARRAY_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_ARRAY_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -19,31 +18,29 @@
# define ARRAY_DEBUG (0+RUBY_DEBUG)
#endif
-#define RARRAY_PTR_IN_USE_FLAG FL_USER14
+#define RARRAY_SHARED_FLAG ELTS_SHARED
+#define RARRAY_SHARED_ROOT_FLAG FL_USER12
+#define RARRAY_PTR_IN_USE_FLAG FL_USER14
/* array.c */
+VALUE rb_ary_hash_values(long len, const VALUE *elements);
VALUE rb_ary_last(int, const VALUE *, VALUE);
void rb_ary_set_len(VALUE, long);
void rb_ary_delete_same(VALUE, VALUE);
-VALUE rb_ary_tmp_new_fill(long capa);
+VALUE rb_ary_hidden_new_fill(long capa);
VALUE rb_ary_at(VALUE, VALUE);
size_t rb_ary_memsize(VALUE);
VALUE rb_to_array_type(VALUE obj);
VALUE rb_to_array(VALUE obj);
void rb_ary_cancel_sharing(VALUE ary);
+size_t rb_ary_size_as_embedded(VALUE ary);
+void rb_ary_make_embedded(VALUE ary);
+bool rb_ary_embeddable_p(VALUE ary);
+VALUE rb_ary_diff(VALUE ary1, VALUE ary2);
static inline VALUE rb_ary_entry_internal(VALUE ary, long offset);
static inline bool ARY_PTR_USING_P(VALUE ary);
-static inline void RARY_TRANSIENT_SET(VALUE ary);
-static inline void RARY_TRANSIENT_UNSET(VALUE ary);
-RUBY_SYMBOL_EXPORT_BEGIN
-/* array.c (export) */
-void rb_ary_detransient(VALUE a);
-void rb_ary_ptr_use_end(VALUE ary);
-RUBY_SYMBOL_EXPORT_END
-
-MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_ary_tmp_new_from_values(VALUE, long, const VALUE *);
VALUE rb_check_to_array(VALUE ary);
VALUE rb_ary_behead(VALUE, long);
@@ -51,13 +48,13 @@ VALUE rb_ary_aref1(VALUE ary, VALUE i);
struct rb_execution_context_struct;
VALUE rb_ec_ary_new_from_values(struct rb_execution_context_struct *ec, long n, const VALUE *elts);
-MJIT_SYMBOL_EXPORT_END
+// YJIT needs this function to never allocate and never raise
static inline VALUE
rb_ary_entry_internal(VALUE ary, long offset)
{
long len = RARRAY_LEN(ary);
- const VALUE *ptr = RARRAY_CONST_PTR_TRANSIENT(ary);
+ const VALUE *ptr = RARRAY_CONST_PTR(ary);
if (len == 0) return Qnil;
if (offset < 0) {
offset += len;
@@ -75,20 +72,48 @@ ARY_PTR_USING_P(VALUE ary)
return FL_TEST_RAW(ary, RARRAY_PTR_IN_USE_FLAG);
}
-static inline void
-RARY_TRANSIENT_SET(VALUE ary)
+RBIMPL_ATTR_MAYBE_UNUSED()
+static inline int
+ary_should_not_be_shared_and_embedded(VALUE ary)
{
-#if USE_TRANSIENT_HEAP
- FL_SET_RAW(ary, RARRAY_TRANSIENT_FLAG);
-#endif
+ return !FL_ALL_RAW(ary, RARRAY_SHARED_FLAG|RARRAY_EMBED_FLAG);
}
-static inline void
-RARY_TRANSIENT_UNSET(VALUE ary)
+static inline bool
+ARY_SHARED_P(VALUE ary)
{
-#if USE_TRANSIENT_HEAP
- FL_UNSET_RAW(ary, RARRAY_TRANSIENT_FLAG);
-#endif
+ assert(RB_TYPE_P(ary, T_ARRAY));
+ assert(ary_should_not_be_shared_and_embedded(ary));
+ return FL_TEST_RAW(ary, RARRAY_SHARED_FLAG);
+}
+
+static inline bool
+ARY_EMBED_P(VALUE ary)
+{
+ assert(RB_TYPE_P(ary, T_ARRAY));
+ assert(ary_should_not_be_shared_and_embedded(ary));
+ return FL_TEST_RAW(ary, RARRAY_EMBED_FLAG);
+}
+
+static inline VALUE
+ARY_SHARED_ROOT(VALUE ary)
+{
+ assert(ARY_SHARED_P(ary));
+ return RARRAY(ary)->as.heap.aux.shared_root;
+}
+
+static inline bool
+ARY_SHARED_ROOT_P(VALUE ary)
+{
+ assert(RB_TYPE_P(ary, T_ARRAY));
+ return FL_TEST_RAW(ary, RARRAY_SHARED_ROOT_FLAG);
+}
+
+static inline long
+ARY_SHARED_ROOT_REFCNT(VALUE ary)
+{
+ assert(ARY_SHARED_ROOT_P(ary));
+ return RARRAY(ary)->as.heap.aux.capa;
}
#undef rb_ary_new_from_args
@@ -111,9 +136,16 @@ RBIMPL_ATTR_ARTIFICIAL()
static inline VALUE
RARRAY_AREF(VALUE ary, long i)
{
+ VALUE val;
RBIMPL_ASSERT_TYPE(ary, RUBY_T_ARRAY);
- return RARRAY_CONST_PTR_TRANSIENT(ary)[i];
+ RBIMPL_WARNING_PUSH();
+#if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 13
+ RBIMPL_WARNING_IGNORED(-Warray-bounds);
+#endif
+ val = RARRAY_CONST_PTR(ary)[i];
+ RBIMPL_WARNING_POP();
+ return val;
}
#endif /* INTERNAL_ARRAY_H */
diff --git a/internal/basic_operators.h b/internal/basic_operators.h
new file mode 100644
index 0000000000..a59403631e
--- /dev/null
+++ b/internal/basic_operators.h
@@ -0,0 +1,63 @@
+#ifndef INTERNAL_BOP_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_BOP_H
+
+#include "internal.h"
+#include "ruby/internal/dllexport.h"
+
+enum ruby_basic_operators {
+ BOP_PLUS,
+ BOP_MINUS,
+ BOP_MULT,
+ BOP_DIV,
+ BOP_MOD,
+ BOP_EQ,
+ BOP_EQQ,
+ BOP_LT,
+ BOP_LE,
+ BOP_LTLT,
+ BOP_AREF,
+ BOP_ASET,
+ BOP_LENGTH,
+ BOP_SIZE,
+ BOP_EMPTY_P,
+ BOP_NIL_P,
+ BOP_SUCC,
+ BOP_GT,
+ BOP_GE,
+ BOP_NOT,
+ BOP_NEQ,
+ BOP_MATCH,
+ BOP_FREEZE,
+ BOP_UMINUS,
+ BOP_MAX,
+ BOP_MIN,
+ BOP_HASH,
+ BOP_CALL,
+ BOP_AND,
+ BOP_OR,
+ BOP_CMP,
+ BOP_DEFAULT,
+
+ BOP_LAST_
+};
+
+RUBY_EXTERN short ruby_vm_redefined_flag[BOP_LAST_];
+
+/* optimize insn */
+#define INTEGER_REDEFINED_OP_FLAG (1 << 0)
+#define FLOAT_REDEFINED_OP_FLAG (1 << 1)
+#define STRING_REDEFINED_OP_FLAG (1 << 2)
+#define ARRAY_REDEFINED_OP_FLAG (1 << 3)
+#define HASH_REDEFINED_OP_FLAG (1 << 4)
+/* #define BIGNUM_REDEFINED_OP_FLAG (1 << 5) */
+#define SYMBOL_REDEFINED_OP_FLAG (1 << 6)
+#define TIME_REDEFINED_OP_FLAG (1 << 7)
+#define REGEXP_REDEFINED_OP_FLAG (1 << 8)
+#define NIL_REDEFINED_OP_FLAG (1 << 9)
+#define TRUE_REDEFINED_OP_FLAG (1 << 10)
+#define FALSE_REDEFINED_OP_FLAG (1 << 11)
+#define PROC_REDEFINED_OP_FLAG (1 << 12)
+
+#define BASIC_OP_UNREDEFINED_P(op, klass) (LIKELY((ruby_vm_redefined_flag[(op)]&(klass)) == 0))
+
+#endif
diff --git a/internal/bignum.h b/internal/bignum.h
index 9b89e61f28..db8d3aee83 100644
--- a/internal/bignum.h
+++ b/internal/bignum.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_BIGNUM_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_BIGNUM_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -164,11 +163,9 @@ VALUE rb_str2big_gmp(VALUE arg, int base, int badcheck);
VALUE rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, int base, int flags);
RUBY_SYMBOL_EXPORT_END
-MJIT_SYMBOL_EXPORT_BEGIN
#if defined(HAVE_INT128_T)
VALUE rb_int128t2big(int128_t n);
#endif
-MJIT_SYMBOL_EXPORT_END
/* sign: positive:1, negative:0 */
static inline bool
diff --git a/internal/bits.h b/internal/bits.h
index 746947bfc2..1fe98fa430 100644
--- a/internal/bits.h
+++ b/internal/bits.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_BITS_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_BITS_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -35,8 +34,7 @@
# include <stdlib.h> /* for _byteswap_uint64 */
#endif
-#if defined(HAVE_X86INTRIN_H) && ! defined(MJIT_HEADER)
-# /* Rule out MJIT_HEADER, which does not interface well with <immintrin.h> */
+#if defined(HAVE_X86INTRIN_H)
# include <x86intrin.h> /* for _lzcnt_u64 */
#elif MSC_VERSION_SINCE(1310)
# include <intrin.h> /* for the following intrinsics */
@@ -120,12 +118,16 @@
MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, FIXNUM_MIN, FIXNUM_MAX)
#endif
-#ifdef MUL_OVERFLOW_P
+#if defined(MUL_OVERFLOW_P) && defined(USE___BUILTIN_MUL_OVERFLOW_LONG_LONG)
# define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_P(a, b)
+#else
+# define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX)
+#endif
+
+#ifdef MUL_OVERFLOW_P
# define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_P(a, b)
# define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_P(a, b)
#else
-# define MUL_OVERFLOW_LONG_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LLONG_MIN, LLONG_MAX)
# define MUL_OVERFLOW_LONG_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, LONG_MIN, LONG_MAX)
# define MUL_OVERFLOW_INT_P(a, b) MUL_OVERFLOW_SIGNED_INTEGER_P(a, b, INT_MIN, INT_MAX)
#endif
@@ -236,7 +238,7 @@ nlz_int32(uint32_t x)
* safety. */
return (unsigned int)__lzcnt(x);
-#elif defined(__x86_64__) && defined(__LZCNT__) && ! defined(MJIT_HEADER)
+#elif defined(__x86_64__) && defined(__LZCNT__)
return (unsigned int)_lzcnt_u32(x);
#elif MSC_VERSION_SINCE(1400) /* &&! defined(__AVX2__) */
@@ -265,7 +267,7 @@ nlz_int64(uint64_t x)
#if defined(_MSC_VER) && defined(__AVX2__)
return (unsigned int)__lzcnt64(x);
-#elif defined(__x86_64__) && defined(__LZCNT__) && ! defined(MJIT_HEADER)
+#elif defined(__x86_64__) && defined(__LZCNT__)
return (unsigned int)_lzcnt_u64(x);
#elif defined(_WIN64) && MSC_VERSION_SINCE(1400) /* &&! defined(__AVX2__) */
@@ -396,9 +398,9 @@ rb_popcount32(uint32_t x)
#else
x = (x & 0x55555555) + (x >> 1 & 0x55555555);
x = (x & 0x33333333) + (x >> 2 & 0x33333333);
- x = (x & 0x0f0f0f0f) + (x >> 4 & 0x0f0f0f0f);
- x = (x & 0x001f001f) + (x >> 8 & 0x001f001f);
- x = (x & 0x0000003f) + (x >>16 & 0x0000003f);
+ x = (x & 0x07070707) + (x >> 4 & 0x07070707);
+ x = (x & 0x000f000f) + (x >> 8 & 0x000f000f);
+ x = (x & 0x0000001f) + (x >>16 & 0x0000001f);
return (unsigned int)x;
#endif
@@ -426,9 +428,9 @@ rb_popcount64(uint64_t x)
x = (x & 0x5555555555555555) + (x >> 1 & 0x5555555555555555);
x = (x & 0x3333333333333333) + (x >> 2 & 0x3333333333333333);
x = (x & 0x0707070707070707) + (x >> 4 & 0x0707070707070707);
- x = (x & 0x001f001f001f001f) + (x >> 8 & 0x001f001f001f001f);
- x = (x & 0x0000003f0000003f) + (x >>16 & 0x0000003f0000003f);
- x = (x & 0x000000000000007f) + (x >>32 & 0x000000000000007f);
+ x = (x & 0x000f000f000f000f) + (x >> 8 & 0x000f000f000f000f);
+ x = (x & 0x0000001f0000001f) + (x >>16 & 0x0000001f0000001f);
+ x = (x & 0x000000000000003f) + (x >>32 & 0x000000000000003f);
return (unsigned int)x;
#endif
@@ -451,7 +453,7 @@ rb_popcount_intptr(uintptr_t x)
static inline int
ntz_int32(uint32_t x)
{
-#if defined(__x86_64__) && defined(__BMI__) && ! defined(MJIT_HEADER)
+#if defined(__x86_64__) && defined(__BMI__)
return (unsigned)_tzcnt_u32(x);
#elif MSC_VERSION_SINCE(1400)
@@ -473,7 +475,7 @@ ntz_int32(uint32_t x)
static inline int
ntz_int64(uint64_t x)
{
-#if defined(__x86_64__) && defined(__BMI__) && ! defined(MJIT_HEADER)
+#if defined(__x86_64__) && defined(__BMI__)
return (unsigned)_tzcnt_u64(x);
#elif defined(_WIN64) && MSC_VERSION_SINCE(1400)
diff --git a/internal/class.h b/internal/class.h
index 6c03a31a4e..8a6c956233 100644
--- a/internal/class.h
+++ b/internal/class.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_CLASS_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_CLASS_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -9,12 +8,19 @@
* file COPYING are met. Consult the file for details.
* @brief Internal header for Class.
*/
+#include "id.h"
#include "id_table.h" /* for struct rb_id_table */
-#include "internal/gc.h" /* for RB_OBJ_WRITE */
#include "internal/serial.h" /* for rb_serial_t */
+#include "internal/static_assert.h"
+#include "internal/variable.h" /* for rb_class_ivar_set */
#include "ruby/internal/stdbool.h" /* for bool */
#include "ruby/intern.h" /* for rb_alloc_func_t */
#include "ruby/ruby.h" /* for struct RBasic */
+#include "shape.h"
+#include "ruby_assert.h"
+#include "vm_core.h"
+#include "vm_sync.h"
+#include "method.h" /* for rb_cref_t */
#ifdef RCLASS_SUPER
# undef RCLASS_SUPER
@@ -23,103 +29,162 @@
struct rb_subclass_entry {
VALUE klass;
struct rb_subclass_entry *next;
+ struct rb_subclass_entry *prev;
};
+typedef struct rb_subclass_entry rb_subclass_entry_t;
-struct rb_iv_index_tbl_entry {
+struct rb_cvar_class_tbl_entry {
uint32_t index;
- rb_serial_t class_serial;
+ rb_serial_t global_cvar_state;
+ const rb_cref_t * cref;
VALUE class_value;
};
struct rb_classext_struct {
- struct st_table *iv_index_tbl; // ID -> struct rb_iv_index_tbl_entry
- struct st_table *iv_tbl;
-#if SIZEOF_SERIAL_T == SIZEOF_VALUE /* otherwise m_tbl is in struct RClass */
- struct rb_id_table *m_tbl;
-#endif
+ VALUE *iv_ptr;
struct rb_id_table *const_tbl;
struct rb_id_table *callable_m_tbl;
- struct rb_id_table *cc_tbl; /* ID -> [[ci, cc1], cc2, ...] */
+ struct rb_id_table *cc_tbl; /* ID -> [[ci1, cc1], [ci2, cc2] ...] */
+ struct rb_id_table *cvc_tbl;
+ size_t superclass_depth;
+ VALUE *superclasses;
struct rb_subclass_entry *subclasses;
- struct rb_subclass_entry **parent_subclasses;
+ struct rb_subclass_entry *subclass_entry;
/**
* In the case that this is an `ICLASS`, `module_subclasses` points to the link
* in the module's `subclasses` list that indicates that the klass has been
* included. Hopefully that makes sense.
*/
- struct rb_subclass_entry **module_subclasses;
-#if SIZEOF_SERIAL_T != SIZEOF_VALUE /* otherwise class_serial is in struct RClass */
- rb_serial_t class_serial;
-#endif
+ struct rb_subclass_entry *module_subclass_entry;
const VALUE origin_;
const VALUE refined_class;
- rb_alloc_func_t allocator;
+ union {
+ struct {
+ rb_alloc_func_t allocator;
+ } class;
+ struct {
+ VALUE attached_object;
+ } singleton_class;
+ } as;
const VALUE includer;
+ attr_index_t max_iv_count;
+ unsigned char variation_count;
+ bool permanent_classpath : 1;
+ bool cloned : 1;
+ VALUE classpath;
};
+typedef struct rb_classext_struct rb_classext_t;
+
+STATIC_ASSERT(shape_max_variations, SHAPE_MAX_VARIATIONS < (1 << (sizeof(((rb_classext_t *)0)->variation_count) * CHAR_BIT)));
struct RClass {
struct RBasic basic;
VALUE super;
- struct rb_classext_struct *ptr;
-#if SIZEOF_SERIAL_T == SIZEOF_VALUE
- /* Class serial is as wide as VALUE. Place it here. */
- rb_serial_t class_serial;
-#else
- /* Class serial does not fit into struct RClass. Place m_tbl instead. */
struct rb_id_table *m_tbl;
-#endif
};
-typedef struct rb_subclass_entry rb_subclass_entry_t;
-typedef struct rb_classext_struct rb_classext_t;
+// Assert that classes can be embedded in size_pools[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 rclass;
+ rb_classext_t classext;
+};
-#define RCLASS_EXT(c) (RCLASS(c)->ptr)
-#define RCLASS_IV_TBL(c) (RCLASS_EXT(c)->iv_tbl)
+#define RCLASS_EXT(c) (&((struct RClass_and_rb_classext_t*)(c))->classext)
#define RCLASS_CONST_TBL(c) (RCLASS_EXT(c)->const_tbl)
-#if SIZEOF_SERIAL_T == SIZEOF_VALUE
-# define RCLASS_M_TBL(c) (RCLASS_EXT(c)->m_tbl)
-#else
-# define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
-#endif
+#define RCLASS_M_TBL(c) (RCLASS(c)->m_tbl)
+#define RCLASS_IVPTR(c) (RCLASS_EXT(c)->iv_ptr)
#define RCLASS_CALLABLE_M_TBL(c) (RCLASS_EXT(c)->callable_m_tbl)
#define RCLASS_CC_TBL(c) (RCLASS_EXT(c)->cc_tbl)
-#define RCLASS_IV_INDEX_TBL(c) (RCLASS_EXT(c)->iv_index_tbl)
+#define RCLASS_CVC_TBL(c) (RCLASS_EXT(c)->cvc_tbl)
#define RCLASS_ORIGIN(c) (RCLASS_EXT(c)->origin_)
#define RCLASS_REFINED_CLASS(c) (RCLASS_EXT(c)->refined_class)
-#if SIZEOF_SERIAL_T == SIZEOF_VALUE
-# define RCLASS_SERIAL(c) (RCLASS(c)->class_serial)
-#else
-# define RCLASS_SERIAL(c) (RCLASS_EXT(c)->class_serial)
-#endif
#define RCLASS_INCLUDER(c) (RCLASS_EXT(c)->includer)
-#define RCLASS_PARENT_SUBCLASSES(c) (RCLASS_EXT(c)->parent_subclasses)
-#define RCLASS_MODULE_SUBCLASSES(c) (RCLASS_EXT(c)->module_subclasses)
-#define RCLASS_ALLOCATOR(c) (RCLASS_EXT(c)->allocator)
+#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_IS_ROOT FL_USER0
+#define RICLASS_IS_ORIGIN FL_USER0
+#define RCLASS_SUPERCLASSES_INCLUDE_SELF FL_USER2
+#define RICLASS_ORIGIN_SHARED_MTBL FL_USER3
-#define RICLASS_IS_ORIGIN FL_USER5
-#define RCLASS_CLONED FL_USER6
-#define RICLASS_ORIGIN_SHARED_MTBL FL_USER8
+static inline st_table *
+RCLASS_IV_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(obj));
+ return (st_table *)RCLASS_IVPTR(obj);
+}
+
+static inline void
+RCLASS_SET_IV_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(obj));
+ RCLASS_IVPTR(obj) = (VALUE *)tbl;
+}
+
+static inline uint32_t
+RCLASS_IV_COUNT(VALUE obj)
+{
+ RUBY_ASSERT(RB_TYPE_P(obj, RUBY_T_CLASS) || RB_TYPE_P(obj, RUBY_T_MODULE));
+ if (rb_shape_obj_too_complex(obj)) {
+ uint32_t count;
+
+ // "Too complex" classes could have their IV hash mutated in
+ // parallel, so lets lock around getting the hash size.
+ RB_VM_LOCK_ENTER();
+ {
+ count = (uint32_t)rb_st_table_size(RCLASS_IV_HASH(obj));
+ }
+ RB_VM_LOCK_LEAVE();
+
+ return count;
+ }
+ else {
+ return rb_shape_get_shape_by_id(RCLASS_SHAPE_ID(obj))->next_iv_index;
+ }
+}
+
+static inline void
+RCLASS_SET_M_TBL(VALUE klass, struct rb_id_table *table)
+{
+ RUBY_ASSERT(!RB_OBJ_PROMOTED(klass));
+ RCLASS_M_TBL(klass) = table;
+}
/* class.c */
void rb_class_subclass_add(VALUE super, VALUE klass);
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);
-int rb_class_has_methods(VALUE c);
void rb_undef_methods_from(VALUE klass, VALUE super);
static inline void RCLASS_SET_ORIGIN(VALUE klass, VALUE origin);
@@ -128,10 +193,30 @@ 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);
-MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_class_inherited(VALUE, VALUE);
VALUE rb_keyword_error_new(const char *, VALUE);
-MJIT_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 rb_alloc_func_t
+RCLASS_ALLOCATOR(VALUE klass)
+{
+ if (RCLASS_SINGLETON_P(klass)) {
+ return 0;
+ }
+ return RCLASS_EXT(klass)->as.class.allocator;
+}
+
+static inline void
+RCLASS_SET_ALLOCATOR(VALUE klass, rb_alloc_func_t allocator)
+{
+ assert(!RCLASS_SINGLETON_P(klass));
+ RCLASS_EXT(klass)->as.class.allocator = allocator;
+}
static inline void
RCLASS_SET_ORIGIN(VALUE klass, VALUE origin)
@@ -172,7 +257,27 @@ RCLASS_SET_SUPER(VALUE klass, VALUE super)
rb_class_subclass_add(super, klass);
}
RB_OBJ_WRITE(klass, &RCLASS(klass)->super, super);
+ rb_class_update_superclasses(klass);
return super;
}
+static inline void
+RCLASS_SET_CLASSPATH(VALUE klass, VALUE classpath, bool permanent)
+{
+ assert(BUILTIN_TYPE(klass) == T_CLASS || BUILTIN_TYPE(klass) == T_MODULE);
+ assert(classpath == 0 || BUILTIN_TYPE(classpath) == T_STRING);
+
+ RB_OBJ_WRITE(klass, &(RCLASS_EXT(klass)->classpath), classpath);
+ RCLASS_EXT(klass)->permanent_classpath = permanent;
+}
+
+static inline VALUE
+RCLASS_SET_ATTACHED_OBJECT(VALUE klass, VALUE attached_object)
+{
+ assert(RCLASS_SINGLETON_P(klass));
+
+ RB_OBJ_WRITE(klass, &RCLASS_EXT(klass)->as.singleton_class.attached_object, attached_object);
+ return attached_object;
+}
+
#endif /* INTERNAL_CLASS_H */
diff --git a/internal/cmdlineopt.h b/internal/cmdlineopt.h
new file mode 100644
index 0000000000..e79b993345
--- /dev/null
+++ b/internal/cmdlineopt.h
@@ -0,0 +1,65 @@
+#ifndef INTERNAL_CMDLINEOPT_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_CMDLINEOPT_H
+
+#include "rjit.h"
+#include "yjit.h"
+
+typedef struct {
+ unsigned int mask;
+ unsigned int set;
+} ruby_features_t;
+
+typedef struct ruby_cmdline_options {
+ const char *script;
+ VALUE script_name;
+ VALUE e_script;
+ struct {
+ struct {
+ VALUE name;
+ int index;
+ } enc;
+ } src, ext, intern;
+ VALUE req_list;
+ ruby_features_t features;
+ ruby_features_t warn;
+ unsigned int dump;
+ long backtrace_length_limit;
+#if USE_RJIT
+ struct rb_rjit_options rjit;
+#endif
+
+ const char *crash_report;
+
+ signed int sflag: 2;
+ unsigned int xflag: 1;
+ unsigned int warning: 1;
+ unsigned int verbose: 1;
+ unsigned int do_loop: 1;
+ unsigned int do_print: 1;
+ unsigned int do_line: 1;
+ unsigned int do_split: 1;
+ unsigned int do_search: 1;
+ unsigned int setids: 2;
+#if USE_YJIT
+ unsigned int yjit: 1;
+#endif
+} ruby_cmdline_options_t;
+
+struct ruby_opt_message {
+ const char *str;
+ unsigned short namelen, secondlen;
+};
+
+#define RUBY_OPT_MESSAGE(shortopt, longopt, desc) { \
+ shortopt " " longopt " " desc, \
+ (unsigned short)sizeof(shortopt), \
+ (unsigned short)sizeof(longopt), \
+}
+
+#define opt_match(s, l, name) \
+ ((((l) > rb_strlen_lit(name)) ? (s)[rb_strlen_lit(name)] == '=' : \
+ (l) == rb_strlen_lit(name)) && \
+ memcmp((s), name, rb_strlen_lit(name)) == 0 && \
+ (((s) += rb_strlen_lit(name)), 1))
+
+#endif
diff --git a/internal/compar.h b/internal/compar.h
index 888a3b5e1e..9115e4bd63 100644
--- a/internal/compar.h
+++ b/internal/compar.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_COMPAR_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_COMPAR_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -9,38 +8,18 @@
* file COPYING are met. Consult the file for details.
* @brief Internal header for Comparable.
*/
-#include "internal/vm.h" /* for rb_method_basic_definition_p */
+#include "internal/basic_operators.h"
#define STRING_P(s) (RB_TYPE_P((s), T_STRING) && CLASS_OF(s) == rb_cString)
-enum {
- cmp_opt_Integer,
- cmp_opt_String,
- cmp_opt_Float,
- cmp_optimizable_count
-};
+#define CMP_OPTIMIZABLE(type) BASIC_OP_UNREDEFINED_P(BOP_CMP, type##_REDEFINED_OP_FLAG)
-struct cmp_opt_data {
- unsigned int opt_methods;
- unsigned int opt_inited;
-};
-
-#define NEW_CMP_OPT_MEMO(type, value) \
- NEW_PARTIAL_MEMO_FOR(type, value, cmp_opt)
-#define CMP_OPTIMIZABLE_BIT(type) (1U << TOKEN_PASTE(cmp_opt_,type))
-#define CMP_OPTIMIZABLE(data, type) \
- (((data).opt_inited & CMP_OPTIMIZABLE_BIT(type)) ? \
- ((data).opt_methods & CMP_OPTIMIZABLE_BIT(type)) : \
- (((data).opt_inited |= CMP_OPTIMIZABLE_BIT(type)), \
- rb_method_basic_definition_p(TOKEN_PASTE(rb_c,type), id_cmp) && \
- ((data).opt_methods |= CMP_OPTIMIZABLE_BIT(type))))
-
-#define OPTIMIZED_CMP(a, b, data) \
- ((FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(data, Integer)) ? \
+#define OPTIMIZED_CMP(a, b) \
+ ((FIXNUM_P(a) && FIXNUM_P(b) && CMP_OPTIMIZABLE(INTEGER)) ? \
(((long)a > (long)b) ? 1 : ((long)a < (long)b) ? -1 : 0) : \
- (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(data, String)) ? \
+ (STRING_P(a) && STRING_P(b) && CMP_OPTIMIZABLE(STRING)) ? \
rb_str_cmp(a, b) : \
- (RB_FLOAT_TYPE_P(a) && RB_FLOAT_TYPE_P(b) && CMP_OPTIMIZABLE(data, Float)) ? \
+ (RB_FLOAT_TYPE_P(a) && RB_FLOAT_TYPE_P(b) && CMP_OPTIMIZABLE(FLOAT)) ? \
rb_float_cmp(a, b) : \
rb_cmpint(rb_funcallv(a, id_cmp, 1, &b), a, b))
diff --git a/internal/compile.h b/internal/compile.h
index 99c15d6a44..2ece5396f6 100644
--- a/internal/compile.h
+++ b/internal/compile.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_COMPILE_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_COMPILE_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -18,6 +17,7 @@ struct rb_iseq_struct; /* in vm_core.h */
/* compile.c */
int rb_dvar_defined(ID, const struct rb_iseq_struct *);
int rb_local_defined(ID, const struct rb_iseq_struct *);
+int rb_insn_len(VALUE insn);
const char *rb_insns_name(int i);
VALUE rb_insns_name_array(void);
int rb_iseq_cdhash_cmp(VALUE val, VALUE lit);
@@ -26,10 +26,9 @@ st_index_t rb_iseq_cdhash_hash(VALUE a);
/* iseq.c */
int rb_vm_insn_addr2insn(const void *);
int rb_vm_insn_decode(const VALUE encoded);
+extern bool ruby_vm_keep_script_lines;
-MJIT_SYMBOL_EXPORT_BEGIN
/* iseq.c (export) */
rb_event_flag_t rb_iseq_event_flags(const struct rb_iseq_struct *iseq, size_t pos);
-MJIT_SYMBOL_EXPORT_END
#endif /* INTERNAL_COMPILE_H */
diff --git a/internal/compilers.h b/internal/compilers.h
index 975bf4575d..26c2f05cc0 100644
--- a/internal/compilers.h
+++ b/internal/compilers.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_COMPILERS_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_COMPILERS_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
diff --git a/internal/complex.h b/internal/complex.h
index 9eae804ddb..42151652b7 100644
--- a/internal/complex.h
+++ b/internal/complex.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_COMPLEX_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_COMPLEX_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
diff --git a/internal/cont.h b/internal/cont.h
index 9e49dd3c8e..3c2528a02a 100644
--- a/internal/cont.h
+++ b/internal/cont.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_CONT_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_CONT_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -10,17 +9,27 @@
* @brief Internal header for Fiber.
*/
#include "ruby/ruby.h" /* for VALUE */
+#include "iseq.h"
struct rb_thread_struct; /* in vm_core.h */
struct rb_fiber_struct; /* in cont.c */
+struct rb_execution_context_struct; /* in vm_core.c */
/* cont.c */
-VALUE rb_obj_is_fiber(VALUE);
void rb_fiber_reset_root_local_storage(struct rb_thread_struct *);
void ruby_register_rollback_func_for_ensure(VALUE (*ensure_func)(VALUE), VALUE (*rollback_func)(VALUE));
-void rb_fiber_init_mjit_cont(struct rb_fiber_struct *fiber);
+void rb_jit_cont_init(void);
+void rb_jit_cont_each_iseq(rb_iseq_callback callback, void *data);
+void rb_jit_cont_finish(void);
+
+/* vm.c */
+void rb_free_shared_fiber_pool(void);
+
+// Copy locals from the current execution to the specified fiber.
+VALUE rb_fiber_inherit_storage(struct rb_execution_context_struct *ec, struct rb_fiber_struct *fiber);
VALUE rb_fiberptr_self(struct rb_fiber_struct *fiber);
unsigned int rb_fiberptr_blocking(struct rb_fiber_struct *fiber);
+struct rb_execution_context_struct * rb_fiberptr_get_ec(struct rb_fiber_struct *fiber);
#endif /* INTERNAL_CONT_H */
diff --git a/internal/dir.h b/internal/dir.h
index ffbdb25208..0a4dc90ece 100644
--- a/internal/dir.h
+++ b/internal/dir.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_DIR_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_DIR_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
diff --git a/internal/enc.h b/internal/enc.h
index 0afc74db5d..a005dc810d 100644
--- a/internal/enc.h
+++ b/internal/enc.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_ENC_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_ENC_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
diff --git a/internal/encoding.h b/internal/encoding.h
index c0cf061bd4..fe9ea10ec4 100644
--- a/internal/encoding.h
+++ b/internal/encoding.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_ENCODING_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_ENCODING_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -13,9 +12,13 @@
#include "ruby/encoding.h" /* for rb_encoding */
#define rb_enc_autoload_p(enc) (!rb_enc_mbmaxlen(enc))
+#define rb_is_usascii_enc(enc) ((enc) == rb_usascii_encoding())
+#define rb_is_ascii8bit_enc(enc) ((enc) == rb_ascii8bit_encoding())
+#define rb_is_locale_enc(enc) ((enc) == rb_locale_encoding())
/* encoding.c */
ID rb_id_encoding(void);
+const char * rb_enc_inspect_name(rb_encoding *enc);
rb_encoding *rb_enc_get_from_index(int index);
rb_encoding *rb_enc_check_str(VALUE str1, VALUE str2);
int rb_encdb_replicate(const char *alias, const char *orig);
@@ -25,7 +28,9 @@ int rb_encdb_dummy(const char *name);
void rb_encdb_declare(const char *name);
void rb_enc_set_base(const char *name, const char *orig);
int rb_enc_set_dummy(int index);
-void rb_encdb_set_unicode(int index);
PUREFUNC(int rb_data_is_encoding(VALUE obj));
+/* vm.c */
+void rb_free_global_enc_table(void);
+
#endif /* INTERNAL_ENCODING_H */
diff --git a/internal/enum.h b/internal/enum.h
index 50890f0c9f..282464436f 100644
--- a/internal/enum.h
+++ b/internal/enum.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_ENUM_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_ENUM_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
diff --git a/internal/enumerator.h b/internal/enumerator.h
index 2e20c37d9e..e11a684c5b 100644
--- a/internal/enumerator.h
+++ b/internal/enumerator.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_ENUMERATOR_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_ENUMERATOR_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
diff --git a/internal/error.h b/internal/error.h
index 0dd629f052..7e41f134d7 100644
--- a/internal/error.h
+++ b/internal/error.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_ERROR_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_ERROR_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -30,26 +29,115 @@
#define rb_raise_static(e, m) \
rb_raise_cstr_i((e), rb_str_new_static((m), rb_strlen_lit(m)))
#ifdef RUBY_FUNCTION_NAME_STRING
-# define rb_sys_fail_path(path) rb_sys_fail_path_in(RUBY_FUNCTION_NAME_STRING, path)
# define rb_syserr_fail_path(err, path) rb_syserr_fail_path_in(RUBY_FUNCTION_NAME_STRING, (err), (path))
# define rb_syserr_new_path(err, path) rb_syserr_new_path_in(RUBY_FUNCTION_NAME_STRING, (err), (path))
#else
-# define rb_sys_fail_path(path) rb_sys_fail_str(path)
# define rb_syserr_fail_path(err, path) rb_syserr_fail_str((err), (path))
# define rb_syserr_new_path(err, path) rb_syserr_new_str((err), (path))
#endif
+#define rb_sys_fail(mesg) \
+do { \
+ int errno_to_fail = errno; \
+ rb_syserr_fail(errno_to_fail, (mesg)); \
+} while (0)
+
+#define rb_sys_fail_str(mesg) \
+do { \
+ int errno_to_fail = errno; \
+ rb_syserr_fail_str(errno_to_fail, (mesg)); \
+} while (0)
+
+#define rb_sys_fail_path(path) \
+do { \
+ int errno_to_fail = errno; \
+ rb_syserr_fail_path(errno_to_fail, (path)); \
+} while (0)
+
+#define rb_sys_fail_sprintf(...) \
+do { \
+ int errno_to_fail = errno; \
+ rb_syserr_fail_str(errno_to_fail, rb_sprintf("" __VA_ARGS__)); \
+} while (0)
+
/* error.c */
extern long rb_backtrace_length_limit;
extern VALUE rb_eEAGAIN;
extern VALUE rb_eEWOULDBLOCK;
extern VALUE rb_eEINPROGRESS;
+RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 3, 0)
void rb_report_bug_valist(VALUE file, int line, const char *fmt, va_list args);
NORETURN(void rb_async_bug_errno(const char *,int));
const char *rb_builtin_type_name(int t);
const char *rb_builtin_class_name(VALUE x);
PRINTF_ARGS(void rb_warn_deprecated(const char *fmt, const char *suggest, ...), 1, 3);
-PRINTF_ARGS(void rb_warn_deprecated_to_remove(const char *fmt, const char *removal, ...), 1, 3);
+PRINTF_ARGS(void rb_warn_deprecated_to_remove(const char *removal, const char *fmt, const char *suggest, ...), 2, 4);
+#if RUBY_DEBUG
+# include "ruby/version.h"
+# define RUBY_VERSION_SINCE(major, minor) (RUBY_API_VERSION_CODE >= (major * 10000) + (minor) * 100)
+# define RUBY_VERSION_BEFORE(major, minor) (RUBY_API_VERSION_CODE < (major * 10000) + (minor) * 100)
+# if defined(RBIMPL_WARNING_PRAGMA0)
+# define RBIMPL_TODO0(x) RBIMPL_WARNING_PRAGMA0(message(x))
+# elif RBIMPL_COMPILER_SINCE(MSVC, 12, 0, 0)
+# define RBIMPL_TODO0(x) __pragma(message(x))
+# endif
+
+# if RBIMPL_HAS_ATTRIBUTE(diagnose_if) || defined(__OPTIMIZE__)
+
+#define RUBY_VERSION_isdigit(c) ('0'<=(c)&&(c)<='9')
+// upto 99
+#define RUBY_VERSION__number_len(v, ofs) \
+ (!RUBY_VERSION_isdigit((v)[ofs]) ? \
+ 0 : !RUBY_VERSION_isdigit((v)[(ofs) + 1]) ? 1 : 2)
+#define RUBY_VERSION__to_number(v, ofs) \
+ (!RUBY_VERSION_isdigit((v)[ofs]) ? \
+ 0 : !RUBY_VERSION_isdigit((v)[(ofs) + 1]) ? \
+ ((v)[ofs]-'0') : \
+ (((v)[ofs]-'0')*10+(v)[(ofs)+1]-'0'))
+
+#define RUBY_VERSION_CODE_FROM_MAJOR_MINOR_STRING(v) \
+ (RUBY_VERSION__to_number(v, 0) * 10000 + \
+ ((v)[RUBY_VERSION__number_len(v, 0)] == '.' ? \
+ RUBY_VERSION__to_number(v, RUBY_VERSION__number_len(v, 0)+1) * 100 : 0))
+#define RUBY_VERSION_STRING_SINCE(v) (RUBY_API_VERSION_CODE >= RUBY_VERSION_CODE_FROM_MAJOR_MINOR_STRING(v))
+#define RUBY_VERSION_STRING_BEFORE(v) (RUBY_API_VERSION_CODE < RUBY_VERSION_CODE_FROM_MAJOR_MINOR_STRING(v))
+
+# if RBIMPL_HAS_ATTRIBUTE(diagnose_if)
+RBIMPL_ATTR_FORCEINLINE()
+static void
+rb_deprecated_method_to_be_removed(const char *removal)
+ RBIMPL_ATTR_DIAGNOSE_IF(!RUBY_VERSION_isdigit(removal[0]), "malformed version number", "error")
+ RBIMPL_ATTR_DIAGNOSE_IF(RUBY_VERSION_STRING_SINCE(removal), "deprecated method to be removed", "error")
+{
+}
+# else
+RBIMPL_ATTR_ERROR(("deprecated"))
+void rb_deprecated_method_to_be_removed(const char *);
+# define rb_deprecated_method_to_be_removed(removal) \
+ (sizeof(char[1-2*(!RUBY_VERSION_isdigit(removal[0]) || RUBY_VERSION_STRING_SINCE(removal))])!=1 ? \
+ rb_deprecated_method_to_be_removed(removal) : \
+ RBIMPL_ASSERT_NOTHING)
+# endif
+# define rb_warn_deprecated_to_remove_at(removal, ...) \
+ (rb_deprecated_method_to_be_removed(#removal), \
+ rb_warn_deprecated_to_remove(#removal, __VA_ARGS__))
+# endif
+#endif
+#ifndef rb_warn_deprecated_to_remove_at
+# define rb_warn_deprecated_to_remove_at(removal, ...) \
+ rb_warn_deprecated_to_remove(#removal, __VA_ARGS__)
+#endif
+#ifndef RUBY_VERSION_SINCE
+# define RUBY_VERSION_SINCE(major, minor) 0
+#endif
+#ifndef RUBY_VERSION_BEFORE
+# define RUBY_VERSION_BEFORE(major, minor) 0
+#endif
+#ifndef RBIMPL_TODO0
+# define RBIMPL_TODO0(x)
+#endif
+#define RBIMPL_TODO(message) RBIMPL_TODO0("TODO: " message)
+RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 6, 0)
VALUE rb_syntax_error_append(VALUE, VALUE, int, int, rb_encoding*, const char*, va_list);
PRINTF_ARGS(void rb_enc_warn(rb_encoding *enc, const char *fmt, ...), 2, 3);
PRINTF_ARGS(void rb_sys_enc_warning(rb_encoding *enc, const char *fmt, ...), 2, 3);
@@ -60,6 +148,7 @@ VALUE rb_name_err_new(VALUE mesg, VALUE recv, VALUE method);
VALUE rb_nomethod_err_new(VALUE mesg, VALUE recv, VALUE method, VALUE args, int priv);
VALUE rb_key_err_new(VALUE mesg, VALUE recv, VALUE name);
PRINTF_ARGS(VALUE rb_warning_string(const char *fmt, ...), 1, 2);
+RBIMPL_ATTR_FORMAT(RBIMPL_PRINTF_FORMAT, 2, 0)
NORETURN(void rb_vraise(VALUE, const char *, va_list));
NORETURN(static inline void rb_raise_cstr(VALUE etype, const char *mesg));
NORETURN(static inline void rb_raise_cstr_i(VALUE etype, VALUE mesg));
@@ -80,6 +169,9 @@ VALUE rb_syserr_new_path_in(const char *func_name, int n, VALUE path);
#endif
RUBY_SYMBOL_EXPORT_END
+/* vm.c */
+void rb_free_warning(void);
+
static inline void
rb_raise_cstr_i(VALUE etype, VALUE mesg)
{
diff --git a/internal/eval.h b/internal/eval.h
index 8dae76b6f8..e594d8516d 100644
--- a/internal/eval.h
+++ b/internal/eval.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_EVAL_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_EVAL_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -22,6 +21,7 @@ extern ID ruby_static_id_status;
VALUE rb_refinement_module_get_refined_class(VALUE module);
void rb_class_modify_check(VALUE);
NORETURN(VALUE rb_f_raise(int argc, VALUE *argv));
+VALUE rb_top_main_class(const char *method);
/* eval_error.c */
VALUE rb_get_backtrace(VALUE info);
diff --git a/internal/file.h b/internal/file.h
index a93c1392f0..9c192ff4d1 100644
--- a/internal/file.h
+++ b/internal/file.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_FILE_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_FILE_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
diff --git a/internal/fixnum.h b/internal/fixnum.h
index 7e0e4be84c..8c251adef1 100644
--- a/internal/fixnum.h
+++ b/internal/fixnum.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_FIXNUM_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_FIXNUM_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -19,7 +18,7 @@
#if HAVE_LONG_LONG && SIZEOF_LONG * 2 <= SIZEOF_LONG_LONG
# define DLONG LONG_LONG
# define DL2NUM(x) LL2NUM(x)
-#elif defined(HAVE_INT128_T)
+#elif defined(HAVE_INT128_T) && !(defined(__OpenBSD__) && defined(__mips64__))
# define DLONG int128_t
# define DL2NUM(x) (RB_FIXABLE(x) ? LONG2FIX(x) : rb_int128t2big(x))
VALUE rb_int128t2big(int128_t n); /* in bignum.c */
diff --git a/internal/gc.h b/internal/gc.h
index 86a2512c85..ecc3f11b2c 100644
--- a/internal/gc.h
+++ b/internal/gc.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_GC_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_GC_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -15,38 +14,119 @@
#include "internal/compilers.h" /* for __has_attribute */
#include "ruby/ruby.h" /* for rb_event_flag_t */
+#include "vm_core.h" /* for GET_EC() */
-struct rb_execution_context_struct; /* in vm_core.h */
-struct rb_objspace; /* in vm_core.h */
+#ifndef USE_SHARED_GC
+# define USE_SHARED_GC 0
+#endif
+
+#if defined(__x86_64__) && !defined(_ILP32) && defined(__GNUC__)
+#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movq\t%%rsp, %0" : "=r" (*(p)))
+#elif defined(__i386) && defined(__GNUC__)
+#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("movl\t%%esp, %0" : "=r" (*(p)))
+#elif (defined(__powerpc__) || defined(__powerpc64__)) && defined(__GNUC__) && !defined(_AIX) && !defined(__APPLE__) // Not Apple is NEEDED to unbreak ppc64 build on Darwin. Don't ask.
+#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mr\t%0, %%r1" : "=r" (*(p)))
+#elif (defined(__powerpc__) || defined(__powerpc64__)) && defined(__GNUC__) && defined(_AIX)
+#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mr %0,1" : "=r" (*(p)))
+#elif defined(__POWERPC__) && defined(__APPLE__) // Darwin ppc and ppc64
+#define SET_MACHINE_STACK_END(p) __asm__ volatile("mr %0, r1" : "=r" (*(p)))
+#elif defined(__aarch64__) && defined(__GNUC__)
+#define SET_MACHINE_STACK_END(p) __asm__ __volatile__ ("mov\t%0, sp" : "=r" (*(p)))
+#else
+NOINLINE(void rb_gc_set_stack_end(VALUE **stack_end_p));
+#define SET_MACHINE_STACK_END(p) rb_gc_set_stack_end(p)
+#define USE_CONSERVATIVE_STACK_END
+#endif
+
+/* for GC debug */
+
+#ifndef RUBY_MARK_FREE_DEBUG
+#define RUBY_MARK_FREE_DEBUG 0
+#endif
+
+#if RUBY_MARK_FREE_DEBUG
+extern int ruby_gc_debug_indent;
+
+static inline void
+rb_gc_debug_indent(void)
+{
+ ruby_debug_printf("%*s", ruby_gc_debug_indent, "");
+}
+
+static inline void
+rb_gc_debug_body(const char *mode, const char *msg, int st, void *ptr)
+{
+ if (st == 0) {
+ ruby_gc_debug_indent--;
+ }
+ rb_gc_debug_indent();
+ ruby_debug_printf("%s: %s %s (%p)\n", mode, st ? "->" : "<-", msg, ptr);
+
+ if (st) {
+ ruby_gc_debug_indent++;
+ }
+
+ fflush(stdout);
+}
+
+#define RUBY_MARK_ENTER(msg) rb_gc_debug_body("mark", (msg), 1, ptr)
+#define RUBY_MARK_LEAVE(msg) rb_gc_debug_body("mark", (msg), 0, ptr)
+#define RUBY_FREE_ENTER(msg) rb_gc_debug_body("free", (msg), 1, ptr)
+#define RUBY_FREE_LEAVE(msg) rb_gc_debug_body("free", (msg), 0, ptr)
+#define RUBY_GC_INFO rb_gc_debug_indent(), ruby_debug_printf
+
+#else
+#define RUBY_MARK_ENTER(msg)
+#define RUBY_MARK_LEAVE(msg)
+#define RUBY_FREE_ENTER(msg)
+#define RUBY_FREE_LEAVE(msg)
+#define RUBY_GC_INFO if(0)printf
+#endif
-#ifndef USE_RVARGC
-#define USE_RVARGC 0
+#define RUBY_FREE_UNLESS_NULL(ptr) if(ptr){ruby_xfree(ptr);(ptr)=NULL;}
+
+#if STACK_GROW_DIRECTION > 0
+# define STACK_UPPER(x, a, b) (a)
+#elif STACK_GROW_DIRECTION < 0
+# define STACK_UPPER(x, a, b) (b)
+#else
+RUBY_EXTERN int ruby_stack_grow_direction;
+int ruby_get_stack_grow_direction(volatile VALUE *addr);
+# define stack_growup_p(x) ( \
+ (ruby_stack_grow_direction ? \
+ ruby_stack_grow_direction : \
+ ruby_get_stack_grow_direction(x)) > 0)
+# define STACK_UPPER(x, a, b) (stack_growup_p(x) ? (a) : (b))
#endif
-#ifdef NEWOBJ_OF
-# undef NEWOBJ_OF
-# undef RB_NEWOBJ_OF
-# undef RB_OBJ_WRITE
+/*
+ STACK_GROW_DIR_DETECTION is used with STACK_DIR_UPPER.
+
+ On most normal systems, stacks grow from high address to lower address. In
+ this case, STACK_DIR_UPPER(a, b) will return (b), but on exotic systems where
+ the stack grows UP (from low address to high address), it will return (a).
+*/
+
+#if STACK_GROW_DIRECTION
+#define STACK_GROW_DIR_DETECTION
+#define STACK_DIR_UPPER(a,b) STACK_UPPER(0, (a), (b))
+#else
+#define STACK_GROW_DIR_DETECTION VALUE stack_grow_dir_detection
+#define STACK_DIR_UPPER(a,b) STACK_UPPER(&stack_grow_dir_detection, (a), (b))
#endif
+#define IS_STACK_DIR_UPPER() STACK_DIR_UPPER(1,0)
-/* optimized version of NEWOBJ() */
-#define RB_NEWOBJ_OF(var, T, c, f) \
- T *(var) = (T *)(((f) & FL_WB_PROTECTED) ? \
- rb_wb_protected_newobj_of((c), (f) & ~FL_WB_PROTECTED, 0) : \
- rb_wb_unprotected_newobj_of((c), (f), 0))
+const char *rb_obj_info(VALUE obj);
+const char *rb_raw_obj_info(char *const buff, const size_t buff_size, VALUE obj);
-#define RB_EC_NEWOBJ_OF(ec, var, T, c, f) \
- T *(var) = (T *)(((f) & FL_WB_PROTECTED) ? \
- rb_ec_wb_protected_newobj_of((ec), (c), (f) & ~FL_WB_PROTECTED, 0) : \
- rb_wb_unprotected_newobj_of((c), (f), 0))
+struct rb_execution_context_struct; /* in vm_core.h */
+struct rb_objspace; /* in vm_core.h */
-#define RB_RVARGC_NEWOBJ_OF(var, T, c, f, s) \
- T *(var) = (T *)(((f) & FL_WB_PROTECTED) ? \
- rb_wb_protected_newobj_of((c), (f) & ~FL_WB_PROTECTED, s) : \
- rb_wb_unprotected_newobj_of((c), (f), s))
+#define NEWOBJ_OF(var, T, c, f, s, ec) \
+ T *(var) = (T *)(((f) & FL_WB_PROTECTED) ? \
+ rb_wb_protected_newobj_of((ec ? ec : GET_EC()), (c), (f) & ~FL_WB_PROTECTED, s) : \
+ rb_wb_unprotected_newobj_of((c), (f), s))
-#define NEWOBJ_OF(var, T, c, f) RB_NEWOBJ_OF((var), T, (c), (f))
-#define RVARGC_NEWOBJ_OF(var, T, c, f, s) RB_RVARGC_NEWOBJ_OF((var), T, (c), (f), (s))
#define RB_OBJ_GC_FLAGS_MAX 6 /* used in ext/objspace */
#ifndef USE_UNALIGNED_MEMBER_ACCESS
@@ -64,64 +144,130 @@ struct rb_objspace; /* in vm_core.h */
COMPILER_WARNING_POP; \
unaligned_member_access_result; \
})
+
+# define UNALIGNED_MEMBER_PTR(ptr, mem) __extension__({ \
+ COMPILER_WARNING_PUSH; \
+ COMPILER_WARNING_IGNORED(-Waddress-of-packed-member); \
+ const volatile void *unaligned_member_ptr_result = &(ptr)->mem; \
+ COMPILER_WARNING_POP; \
+ (__typeof__((ptr)->mem) *)unaligned_member_ptr_result; \
+})
+#endif
+
+#ifndef UNALIGNED_MEMBER_PTR
+# define UNALIGNED_MEMBER_PTR(ptr, mem) UNALIGNED_MEMBER_ACCESS(&(ptr)->mem)
+#endif
+
+#define RB_OBJ_WRITE_UNALIGNED(old, slot, young) do { \
+ VALUE *_slot = UNALIGNED_MEMBER_ACCESS(slot); \
+ RB_OBJ_WRITE(old, _slot, young); \
+} while (0)
+
+// We use SIZE_POOL_COUNT number of shape IDs for transitions out of different size pools
+// The next available shape ID will be the SPECIAL_CONST_SHAPE_ID
+#ifndef SIZE_POOL_COUNT
+# define SIZE_POOL_COUNT 5
#endif
-#define UNALIGNED_MEMBER_PTR(ptr, mem) UNALIGNED_MEMBER_ACCESS(&(ptr)->mem)
-#define RB_OBJ_WRITE(a, slot, b) \
- rb_obj_write((VALUE)(a), UNALIGNED_MEMBER_ACCESS((VALUE *)(slot)), \
- (VALUE)(b), __FILE__, __LINE__)
+/* Used in places that could malloc during, which can cause the GC to run. We
+ * need to temporarily disable the GC to allow the malloc to happen.
+ * Allocating memory during GC is a bad idea, so use this only when absolutely
+ * necessary. */
+#define DURING_GC_COULD_MALLOC_REGION_START() \
+ assert(rb_during_gc()); \
+ VALUE _already_disabled = rb_gc_disable_no_rest()
+
+#define DURING_GC_COULD_MALLOC_REGION_END() \
+ if (_already_disabled == Qfalse) rb_gc_enable()
+
+typedef struct ractor_newobj_size_pool_cache {
+ struct RVALUE *freelist;
+ struct heap_page *using_page;
+} rb_ractor_newobj_size_pool_cache_t;
-#define RVARGC_PAYLOAD_INIT(obj, size) (void *)rb_rvargc_payload_init((VALUE)obj, (size_t)size)
+typedef struct ractor_newobj_cache {
+ size_t incremental_mark_step_allocated_slots;
+ rb_ractor_newobj_size_pool_cache_t size_pool_caches[SIZE_POOL_COUNT];
+} rb_ractor_newobj_cache_t;
/* gc.c */
-extern VALUE *ruby_initial_gc_stress_ptr;
extern int ruby_disable_gc;
RUBY_ATTR_MALLOC void *ruby_mimmalloc(size_t size);
+RUBY_ATTR_MALLOC void *ruby_mimcalloc(size_t num, size_t size);
void ruby_mimfree(void *ptr);
+void rb_gc_prepare_heap(void);
void rb_objspace_set_event_hook(const rb_event_flag_t event);
VALUE rb_objspace_gc_enable(struct rb_objspace *);
VALUE rb_objspace_gc_disable(struct rb_objspace *);
void ruby_gc_set_params(void);
-void rb_copy_wb_protected_attribute(VALUE dest, VALUE obj);
-#if __has_attribute(alloc_align)
-__attribute__((__alloc_align__(1)))
-#endif
-RUBY_ATTR_MALLOC void *rb_aligned_malloc(size_t, size_t) RUBY_ATTR_ALLOC_SIZE((2));
+void rb_gc_copy_attributes(VALUE dest, VALUE obj);
size_t rb_size_mul_or_raise(size_t, size_t, VALUE); /* used in compile.c */
size_t rb_size_mul_add_or_raise(size_t, size_t, size_t, VALUE); /* used in iseq.h */
+size_t rb_malloc_grow_capa(size_t current_capacity, size_t type_size);
RUBY_ATTR_MALLOC void *rb_xmalloc_mul_add(size_t, size_t, size_t);
+RUBY_ATTR_MALLOC void *rb_xcalloc_mul_add(size_t, size_t, size_t);
void *rb_xrealloc_mul_add(const void *, size_t, size_t, size_t);
RUBY_ATTR_MALLOC void *rb_xmalloc_mul_add_mul(size_t, size_t, size_t, size_t);
RUBY_ATTR_MALLOC void *rb_xcalloc_mul_add_mul(size_t, size_t, size_t, size_t);
static inline void *ruby_sized_xrealloc_inlined(void *ptr, size_t new_size, size_t old_size) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2));
static inline void *ruby_sized_xrealloc2_inlined(void *ptr, size_t new_count, size_t elemsiz, size_t old_count) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2, 3));
static inline void ruby_sized_xfree_inlined(void *ptr, size_t size);
-VALUE rb_class_allocate_instance(VALUE klass);
+void rb_gc_ractor_newobj_cache_clear(rb_ractor_newobj_cache_t *newobj_cache);
+bool rb_gc_size_allocatable_p(size_t size);
+size_t *rb_gc_size_pool_sizes(void);
+size_t rb_gc_size_pool_id_for_size(size_t size);
+int rb_objspace_garbage_object_p(VALUE obj);
+bool rb_gc_is_ptr_to_obj(const void *ptr);
+
+void rb_gc_mark_and_move(VALUE *ptr);
+
+void rb_gc_mark_weak(VALUE *ptr);
+void rb_gc_remove_weak(VALUE parent_obj, VALUE *ptr);
+
+void rb_gc_ref_update_table_values_only(st_table *tbl);
+
+void rb_gc_initial_stress_set(VALUE flag);
+
+#define rb_gc_mark_and_move_ptr(ptr) do { \
+ VALUE _obj = (VALUE)*(ptr); \
+ rb_gc_mark_and_move(&_obj); \
+ if (_obj != (VALUE)*(ptr)) *(ptr) = (void *)_obj; \
+} while (0)
RUBY_SYMBOL_EXPORT_BEGIN
+/* exports for objspace module */
+void rb_objspace_reachable_objects_from(VALUE obj, void (func)(VALUE, void *), void *data);
+void rb_objspace_reachable_objects_from_root(void (func)(const char *category, VALUE, void *), void *data);
+int rb_objspace_markable_object_p(VALUE obj);
+int rb_objspace_internal_object_p(VALUE obj);
+
+void rb_objspace_each_objects(
+ int (*callback)(void *start, void *end, size_t stride, void *data),
+ void *data);
+
+size_t rb_gc_obj_slot_size(VALUE obj);
+
+VALUE rb_gc_disable_no_rest(void);
+
+
/* gc.c (export) */
const char *rb_objspace_data_type_name(VALUE obj);
-VALUE rb_wb_protected_newobj_of(VALUE, VALUE, size_t);
+VALUE rb_wb_protected_newobj_of(struct rb_execution_context_struct *, VALUE, VALUE, size_t);
VALUE rb_wb_unprotected_newobj_of(VALUE, VALUE, size_t);
-VALUE rb_ec_wb_protected_newobj_of(struct rb_execution_context_struct *ec, VALUE klass, VALUE flags, size_t);
-VALUE rb_rvargc_payload_init(VALUE obj, size_t size);
-void * rb_rvargc_payload_data_ptr(VALUE obj);
size_t rb_obj_memsize_of(VALUE);
void rb_gc_verify_internal_consistency(void);
size_t rb_obj_gc_flags(VALUE, ID[], size_t);
void rb_gc_mark_values(long n, const VALUE *values);
void rb_gc_mark_vm_stack_values(long n, const VALUE *values);
+void rb_gc_update_values(long n, VALUE *values);
void *ruby_sized_xrealloc(void *ptr, size_t new_size, size_t old_size) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2));
void *ruby_sized_xrealloc2(void *ptr, size_t new_count, size_t element_size, size_t old_count) RUBY_ATTR_RETURNS_NONNULL RUBY_ATTR_ALLOC_SIZE((2, 3));
void ruby_sized_xfree(void *x, size_t size);
-int rb_slot_size(void);
RUBY_SYMBOL_EXPORT_END
-MJIT_SYMBOL_EXPORT_BEGIN
int rb_ec_stack_check(struct rb_execution_context_struct *ec);
void rb_gc_writebarrier_remember(VALUE obj);
const char *rb_obj_info(VALUE obj);
-MJIT_SYMBOL_EXPORT_END
#if defined(HAVE_MALLOC_USABLE_SIZE) || defined(HAVE_MALLOC_SIZE) || defined(_WIN32)
@@ -145,6 +291,12 @@ ruby_sized_xfree_inlined(void *ptr, size_t size)
# define SIZED_REALLOC_N(x, y, z, w) REALLOC_N(x, y, z)
+static inline void *
+ruby_sized_realloc_n(void *ptr, size_t new_count, size_t element_size, size_t old_count)
+{
+ return ruby_xrealloc2(ptr, new_count, element_size);
+}
+
#else
static inline void *
@@ -168,6 +320,12 @@ ruby_sized_xfree_inlined(void *ptr, size_t size)
# define SIZED_REALLOC_N(v, T, m, n) \
((v) = (T *)ruby_sized_xrealloc2((void *)(v), (m), sizeof(T), (n)))
+static inline void *
+ruby_sized_realloc_n(void *ptr, size_t new_count, size_t element_size, size_t old_count)
+{
+ return ruby_sized_xrealloc2(ptr, new_count, element_size, old_count);
+}
+
#endif /* HAVE_MALLOC_USABLE_SIZE */
#define ruby_sized_xrealloc ruby_sized_xrealloc_inlined
diff --git a/internal/hash.h b/internal/hash.h
index a4677c581b..fe859cb716 100644
--- a/internal/hash.h
+++ b/internal/hash.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_HASH_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_HASH_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -29,10 +28,6 @@ enum ruby_rhash_flags {
RHASH_AR_TABLE_BOUND_MASK = (FL_USER8|FL_USER9|FL_USER10|FL_USER11), /* FL 8..11 */
RHASH_AR_TABLE_BOUND_SHIFT = (FL_USHIFT+8),
-#if USE_TRANSIENT_HEAP
- RHASH_TRANSIENT_FLAG = FL_USER12, /* FL 12 */
-#endif
-
// we can not put it in "enum" because it can exceed "int" range.
#define RHASH_LEV_MASK (FL_USER13 | FL_USER14 | FL_USER15 | /* FL 13..19 */ \
FL_USER16 | FL_USER17 | FL_USER18 | FL_USER19)
@@ -41,17 +36,23 @@ enum ruby_rhash_flags {
RHASH_LEV_MAX = 127, /* 7 bits */
};
-struct RHash {
- struct RBasic basic;
- union {
- st_table *st;
- struct ar_table_struct *ar; /* possibly 0 */
- } as;
- const VALUE ifnone;
+typedef struct ar_table_pair_struct {
+ VALUE key;
+ VALUE val;
+} ar_table_pair;
+
+typedef struct ar_table_struct {
union {
ar_hint_t ary[RHASH_AR_TABLE_MAX_SIZE];
VALUE word;
} ar_hint;
+ /* 64bit CPU: 8B * 2 * 8 = 128B */
+ ar_table_pair pairs[RHASH_AR_TABLE_MAX_SIZE];
+} ar_table;
+
+struct RHash {
+ struct RBasic basic;
+ const VALUE ifnone;
};
#define RHASH(obj) ((struct RHash *)(obj))
@@ -74,6 +75,8 @@ VALUE rb_hash_default_value(VALUE hash, VALUE key);
VALUE rb_hash_set_default_proc(VALUE hash, VALUE proc);
long rb_dbl_long_hash(double d);
st_table *rb_init_identtable(void);
+st_index_t rb_any_hash(VALUE a);
+int rb_any_cmp(VALUE a, VALUE b);
VALUE rb_to_hash_type(VALUE obj);
VALUE rb_hash_key_str(VALUE);
VALUE rb_hash_values(VALUE hash);
@@ -83,7 +86,8 @@ VALUE rb_hash_set_pair(VALUE hash, VALUE pair);
int rb_hash_stlike_delete(VALUE hash, st_data_t *pkey, st_data_t *pval);
int rb_hash_stlike_foreach_with_replace(VALUE hash, st_foreach_check_callback_func *func, st_update_callback_func *replace, st_data_t arg);
int rb_hash_stlike_update(VALUE hash, st_data_t key, st_update_callback_func *func, st_data_t arg);
-extern st_table *rb_hash_st_table(VALUE hash);
+VALUE rb_ident_hash_new_with_size(st_index_t size);
+void rb_hash_free(VALUE hash);
static inline unsigned RHASH_AR_TABLE_SIZE_RAW(VALUE h);
static inline VALUE RHASH_IFNONE(VALUE h);
@@ -95,9 +99,6 @@ static inline struct ar_table_struct *RHASH_AR_TABLE(VALUE h);
static inline st_table *RHASH_ST_TABLE(VALUE h);
static inline size_t RHASH_ST_SIZE(VALUE h);
static inline void RHASH_ST_CLEAR(VALUE h);
-static inline bool RHASH_TRANSIENT_P(VALUE h);
-static inline void RHASH_SET_TRANSIENT_FLAG(VALUE h);
-static inline void RHASH_UNSET_TRANSIENT_FLAG(VALUE h);
RUBY_SYMBOL_EXPORT_BEGIN
/* hash.c (export) */
@@ -106,7 +107,6 @@ VALUE rb_ident_hash_new(void);
int rb_hash_stlike_foreach(VALUE hash, st_foreach_callback_func *func, st_data_t arg);
RUBY_SYMBOL_EXPORT_END
-MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_hash_new_with_size(st_index_t size);
VALUE rb_hash_resurrect(VALUE hash);
int rb_hash_stlike_lookup(VALUE hash, st_data_t key, st_data_t *pval);
@@ -116,31 +116,8 @@ VALUE rb_hash_compare_by_id_p(VALUE hash);
st_table *rb_hash_tbl_raw(VALUE hash, const char *file, int line);
#define RHASH_TBL_RAW(h) rb_hash_tbl_raw(h, __FILE__, __LINE__)
-MJIT_SYMBOL_EXPORT_END
-
-#if 0 /* for debug */
-
-static inline bool
-RHASH_AR_TABLE_P(VALUE h)
-{
- extern int rb_hash_ar_table_p(VALUE hash);
- return rb_hash_ar_table_p(h)
-}
-
-static inline struct ar_table_struct *
-RHASH_AR_TABLE(VALUE h)
-{
- extern struct ar_table_struct *rb_hash_ar_table(VALUE hash);
- return rb_hash_ar_table(h)
-}
-static inline st_table *
-RHASH_ST_TABLE(VALUE h)
-{
- return rb_hash_st_table(h)
-}
-
-#else
+VALUE rb_hash_compare_by_id(VALUE hash);
static inline bool
RHASH_AR_TABLE_P(VALUE h)
@@ -148,20 +125,20 @@ RHASH_AR_TABLE_P(VALUE h)
return ! FL_TEST_RAW(h, RHASH_ST_TABLE_FLAG);
}
+RBIMPL_ATTR_RETURNS_NONNULL()
static inline struct ar_table_struct *
RHASH_AR_TABLE(VALUE h)
{
- return RHASH(h)->as.ar;
+ return (struct ar_table_struct *)((uintptr_t)h + sizeof(struct RHash));
}
+RBIMPL_ATTR_RETURNS_NONNULL()
static inline st_table *
RHASH_ST_TABLE(VALUE h)
{
- return RHASH(h)->as.st;
+ return (st_table *)((uintptr_t)h + sizeof(struct RHash));
}
-#endif
-
static inline VALUE
RHASH_IFNONE(VALUE h)
{
@@ -200,8 +177,7 @@ RHASH_ST_SIZE(VALUE h)
static inline void
RHASH_ST_CLEAR(VALUE h)
{
- FL_UNSET_RAW(h, RHASH_ST_TABLE_FLAG);
- RHASH(h)->as.ar = NULL;
+ memset(RHASH_ST_TABLE(h), 0, sizeof(st_table));
}
static inline unsigned
@@ -212,30 +188,4 @@ RHASH_AR_TABLE_SIZE_RAW(VALUE h)
return (unsigned)ret;
}
-static inline bool
-RHASH_TRANSIENT_P(VALUE h)
-{
-#if USE_TRANSIENT_HEAP
- return FL_TEST_RAW(h, RHASH_TRANSIENT_FLAG);
-#else
- return false;
-#endif
-}
-
-static inline void
-RHASH_SET_TRANSIENT_FLAG(VALUE h)
-{
-#if USE_TRANSIENT_HEAP
- FL_SET_RAW(h, RHASH_TRANSIENT_FLAG);
-#endif
-}
-
-static inline void
-RHASH_UNSET_TRANSIENT_FLAG(VALUE h)
-{
-#if USE_TRANSIENT_HEAP
- FL_UNSET_RAW(h, RHASH_TRANSIENT_FLAG);
-#endif
-}
-
#endif /* INTERNAL_HASH_H */
diff --git a/internal/imemo.h b/internal/imemo.h
index a9e2136ac4..36c0776987 100644
--- a/internal/imemo.h
+++ b/internal/imemo.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_IMEMO_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_IMEMO_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -11,8 +10,7 @@
*/
#include "ruby/internal/config.h"
#include <stddef.h> /* for size_t */
-#include "internal/array.h" /* for rb_ary_tmp_new_fill */
-#include "internal/gc.h" /* for RB_OBJ_WRITE */
+#include "internal/array.h" /* for rb_ary_hidden_new_fill */
#include "ruby/internal/stdbool.h" /* for bool */
#include "ruby/ruby.h" /* for rb_block_call_func_t */
@@ -41,7 +39,7 @@ enum imemo_type {
imemo_ment = 6,
imemo_iseq = 7,
imemo_tmpbuf = 8,
- imemo_ast = 9,
+ imemo_ast = 9, // Obsolete due to the universal parser
imemo_parser_strterm = 10,
imemo_callinfo = 11,
imemo_callcache = 12,
@@ -84,7 +82,7 @@ struct vm_ifunc_argc {
/*! IFUNC (Internal FUNCtion) */
struct vm_ifunc {
VALUE flags;
- VALUE reserved;
+ VALUE *svar_lep;
rb_block_call_func_t func;
const void *data;
struct vm_ifunc_argc argc;
@@ -115,24 +113,25 @@ struct MEMO {
} u3;
};
+#define IMEMO_NEW(T, type, v0) ((T *)rb_imemo_new((type), (v0)))
+
/* ment is in method.h */
#define THROW_DATA_P(err) imemo_throw_data_p((VALUE)err)
#define MEMO_CAST(m) ((struct MEMO *)(m))
-#define MEMO_NEW(a, b, c) ((struct MEMO *)rb_imemo_new(imemo_memo, (VALUE)(a), (VALUE)(b), (VALUE)(c), 0))
#define MEMO_FOR(type, value) ((type *)RARRAY_PTR(value))
#define NEW_MEMO_FOR(type, value) \
- ((value) = rb_ary_tmp_new_fill(type_roomof(type, VALUE)), MEMO_FOR(type, value))
+ ((value) = rb_ary_hidden_new_fill(type_roomof(type, VALUE)), MEMO_FOR(type, value))
#define NEW_PARTIAL_MEMO_FOR(type, value, member) \
- ((value) = rb_ary_tmp_new_fill(type_roomof(type, VALUE)), \
+ ((value) = rb_ary_hidden_new_fill(type_roomof(type, VALUE)), \
rb_ary_set_len((value), offsetof(type, member) / sizeof(VALUE)), \
MEMO_FOR(type, value))
+#ifndef RUBY_RUBYPARSER_H
typedef struct rb_imemo_tmpbuf_struct rb_imemo_tmpbuf_t;
-VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0);
+#endif
rb_imemo_tmpbuf_t *rb_imemo_tmpbuf_parser_heap(void *buf, rb_imemo_tmpbuf_t *old_heap, size_t cnt);
struct vm_ifunc *rb_vm_ifunc_new(rb_block_call_func_t func, const void *data, int min_argc, int max_argc);
-void rb_strterm_mark(VALUE obj);
static inline enum imemo_type imemo_type(VALUE imemo);
static inline int imemo_type_p(VALUE imemo, enum imemo_type imemo_type);
static inline bool imemo_throw_data_p(VALUE imemo);
@@ -144,16 +143,33 @@ static inline VALUE rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE
static inline void MEMO_V1_SET(struct MEMO *m, VALUE v);
static inline void MEMO_V2_SET(struct MEMO *m, VALUE v);
+size_t rb_imemo_memsize(VALUE obj);
+void rb_cc_table_mark(VALUE klass);
+void rb_imemo_mark_and_move(VALUE obj, bool reference_updating);
+void rb_cc_table_free(VALUE klass);
+void rb_imemo_free(VALUE obj);
+
RUBY_SYMBOL_EXPORT_BEGIN
#if IMEMO_DEBUG
-VALUE rb_imemo_new_debug(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0, const char *file, int line);
+VALUE rb_imemo_new_debug(enum imemo_type type, VALUE v0, const char *file, int line);
#define rb_imemo_new(type, v1, v2, v3, v0) rb_imemo_new_debug(type, v1, v2, v3, v0, __FILE__, __LINE__)
#else
-VALUE rb_imemo_new(enum imemo_type type, VALUE v1, VALUE v2, VALUE v3, VALUE v0);
+VALUE rb_imemo_new(enum imemo_type type, VALUE v0);
#endif
const char *rb_imemo_name(enum imemo_type type);
RUBY_SYMBOL_EXPORT_END
+static inline struct MEMO *
+MEMO_NEW(VALUE a, VALUE b, VALUE c)
+{
+ struct MEMO *memo = IMEMO_NEW(struct MEMO, imemo_memo, 0);
+ *((VALUE *)&memo->v1) = a;
+ *((VALUE *)&memo->v2) = b;
+ *((VALUE *)&memo->u3.value) = c;
+
+ return memo;
+}
+
static inline enum imemo_type
imemo_type(VALUE imemo)
{
@@ -175,7 +191,7 @@ imemo_type_p(VALUE imemo, enum imemo_type imemo_type)
}
}
-#define IMEMO_TYPE_P(v, t) imemo_type_p((VALUE)v, t)
+#define IMEMO_TYPE_P(v, t) imemo_type_p((VALUE)(v), t)
static inline bool
imemo_throw_data_p(VALUE imemo)
@@ -192,7 +208,7 @@ rb_vm_ifunc_proc_new(rb_block_call_func_t func, const void *data)
static inline VALUE
rb_imemo_tmpbuf_auto_free_pointer(void)
{
- return rb_imemo_new(imemo_tmpbuf, 0, 0, 0, 0);
+ return rb_imemo_new(imemo_tmpbuf, 0);
}
static inline void *
@@ -217,7 +233,7 @@ rb_imemo_tmpbuf_auto_free_pointer_new_from_an_RString(VALUE str)
void *dst;
size_t len;
- SafeStringValue(str);
+ StringValue(str);
/* create tmpbuf to keep the pointer before xmalloc */
imemo = rb_imemo_tmpbuf_auto_free_pointer();
tmpbuf = (rb_imemo_tmpbuf_t *)imemo;
diff --git a/internal/inits.h b/internal/inits.h
index 680c9cc1a5..03de289dd4 100644
--- a/internal/inits.h
+++ b/internal/inits.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_INITS_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_INITS_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -20,9 +19,6 @@ void Init_ext(void);
/* file.c */
void Init_File(void);
-/* gc.c */
-void Init_heap(void);
-
/* localeinit.c */
int Init_enc_set_filesystem_encoding(void);
diff --git a/internal/io.h b/internal/io.h
index b184cec439..1891248a19 100644
--- a/internal/io.h
+++ b/internal/io.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_IO_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_IO_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -10,8 +9,110 @@
* @brief Internal header for IO.
*/
#include "ruby/ruby.h" /* for VALUE */
+
+#define HAVE_RB_IO_T
+struct rb_io;
+
#include "ruby/io.h" /* for rb_io_t */
+#define IO_WITHOUT_GVL(func, arg) rb_thread_call_without_gvl(func, arg, RUBY_UBF_IO, 0)
+#define IO_WITHOUT_GVL_INT(func, arg) (int)(VALUE)IO_WITHOUT_GVL(func, arg)
+
+/** Ruby's IO, metadata and buffers. */
+struct rb_io {
+
+ /** The IO's Ruby level counterpart. */
+ VALUE self;
+
+ /** stdio ptr for read/write, if available. */
+ FILE *stdio_file;
+
+ /** file descriptor. */
+ int fd;
+
+ /** mode flags: FMODE_XXXs */
+ int mode;
+
+ /** child's pid (for pipes) */
+ rb_pid_t pid;
+
+ /** number of lines read */
+ int lineno;
+
+ /** pathname for file */
+ VALUE pathv;
+
+ /** finalize proc */
+ void (*finalize)(struct rb_io*,int);
+
+ /** Write buffer. */
+ rb_io_buffer_t wbuf;
+
+ /**
+ * (Byte) read buffer. Note also that there is a field called
+ * ::rb_io_t::cbuf, which also concerns read IO.
+ */
+ rb_io_buffer_t rbuf;
+
+ /**
+ * Duplex IO object, if set.
+ *
+ * @see rb_io_set_write_io()
+ */
+ VALUE tied_io_for_writing;
+
+ struct rb_io_encoding encs; /**< Decomposed encoding flags. */
+
+ /** Encoding converter used when reading from this IO. */
+ rb_econv_t *readconv;
+
+ /**
+ * rb_io_ungetc() destination. This buffer is read before checking
+ * ::rb_io_t::rbuf
+ */
+ rb_io_buffer_t cbuf;
+
+ /** Encoding converter used when writing to this IO. */
+ rb_econv_t *writeconv;
+
+ /**
+ * This is, when set, an instance of ::rb_cString which holds the "common"
+ * encoding. Write conversion can convert strings twice... In case
+ * conversion from encoding X to encoding Y does not exist, Ruby finds an
+ * encoding Z that bridges the two, so that X to Z to Y conversion happens.
+ */
+ VALUE writeconv_asciicompat;
+
+ /** Whether ::rb_io_t::writeconv is already set up. */
+ int writeconv_initialized;
+
+ /**
+ * Value of ::rb_io_t::rb_io_enc_t::ecflags stored right before
+ * initialising ::rb_io_t::writeconv.
+ */
+ int writeconv_pre_ecflags;
+
+ /**
+ * Value of ::rb_io_t::rb_io_enc_t::ecopts stored right before initialising
+ * ::rb_io_t::writeconv.
+ */
+ VALUE writeconv_pre_ecopts;
+
+ /**
+ * This is a Ruby level mutex. It avoids multiple threads to write to an
+ * IO at once; helps for instance rb_io_puts() to ensure newlines right
+ * next to its arguments.
+ *
+ * This of course doesn't help inter-process IO interleaves, though.
+ */
+ VALUE write_lock;
+
+ /**
+ * The timeout associated with this IO when performing blocking operations.
+ */
+ VALUE timeout;
+};
+
/* io.c */
void ruby_set_inplace_mode(const char *);
void rb_stdio_set_default_encoding(void);
@@ -25,6 +126,10 @@ void rb_io_fptr_finalize_internal(void *ptr);
#define rb_io_fptr_finalize rb_io_fptr_finalize_internal
VALUE rb_io_popen(VALUE pname, VALUE pmode, VALUE env, VALUE opt);
+VALUE rb_io_prep_stdin(void);
+VALUE rb_io_prep_stdout(void);
+VALUE rb_io_prep_stderr(void);
+
RUBY_SYMBOL_EXPORT_BEGIN
/* io.c (export) */
void rb_maygvl_fd_fix_cloexec(int fd);
diff --git a/internal/load.h b/internal/load.h
index 37c1dee351..d4c0bb91ba 100644
--- a/internal/load.h
+++ b/internal/load.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_LOAD_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_LOAD_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
diff --git a/internal/loadpath.h b/internal/loadpath.h
index f89f6694cd..b3a85e7b41 100644
--- a/internal/loadpath.h
+++ b/internal/loadpath.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_LOADPATH_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_LOADPATH_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
diff --git a/internal/math.h b/internal/math.h
index cd8d553790..08f852ffc1 100644
--- a/internal/math.h
+++ b/internal/math.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_MATH_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_MATH_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
diff --git a/internal/missing.h b/internal/missing.h
index 0224075b3d..6ca508c8f9 100644
--- a/internal/missing.h
+++ b/internal/missing.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_MISSING_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_MISSING_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -14,6 +13,7 @@
/* missing/setproctitle.c */
#ifndef HAVE_SETPROCTITLE
extern void ruby_init_setproctitle(int argc, char *argv[]);
+extern void ruby_free_proctitle(void);
#endif
#endif /* INTERNAL_MISSING_H */
diff --git a/internal/numeric.h b/internal/numeric.h
index 32d5bd27fa..6406cfc2fa 100644
--- a/internal/numeric.h
+++ b/internal/numeric.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_NUMERIC_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_NUMERIC_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -36,9 +35,22 @@ enum ruby_num_rounding_mode {
RUBY_NUM_ROUND_DEFAULT = ROUND_DEFAULT,
};
+/* same as internal.h */
+#define numberof(array) ((int)(sizeof(array) / sizeof((array)[0])))
+#define roomof(x, y) (((x) + (y) - 1) / (y))
+#define type_roomof(x, y) roomof(sizeof(x), sizeof(y))
+
+#if SIZEOF_DOUBLE <= SIZEOF_VALUE
+typedef double rb_float_value_type;
+#else
+typedef struct {
+ VALUE values[roomof(SIZEOF_DOUBLE, SIZEOF_VALUE)];
+} rb_float_value_type;
+#endif
+
struct RFloat {
struct RBasic basic;
- double float_value;
+ rb_float_value_type float_value;
};
#define RFLOAT(obj) ((struct RFloat *)(obj))
@@ -74,9 +86,11 @@ VALUE rb_int_equal(VALUE x, VALUE y);
VALUE rb_int_divmod(VALUE x, VALUE y);
VALUE rb_int_and(VALUE x, VALUE y);
VALUE rb_int_lshift(VALUE x, VALUE y);
+VALUE rb_int_rshift(VALUE x, VALUE y);
VALUE rb_int_div(VALUE x, VALUE y);
int rb_int_positive_p(VALUE num);
int rb_int_negative_p(VALUE num);
+VALUE rb_check_integer_type(VALUE);
VALUE rb_num_pow(VALUE x, VALUE y);
VALUE rb_float_ceil(VALUE num, int ndigits);
VALUE rb_float_floor(VALUE x, int ndigits);
@@ -96,10 +110,8 @@ static inline bool FLOAT_ZERO_P(VALUE num);
RUBY_SYMBOL_EXPORT_BEGIN
/* numeric.c (export) */
-VALUE rb_int_positive_pow(long x, unsigned long y);
RUBY_SYMBOL_EXPORT_END
-MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_flo_div_flo(VALUE x, VALUE y);
double ruby_float_mod(double x, double y);
VALUE rb_float_equal(VALUE x, VALUE y);
@@ -113,7 +125,6 @@ VALUE rb_int_abs(VALUE num);
VALUE rb_int_bit_length(VALUE num);
VALUE rb_int_uminus(VALUE num);
VALUE rb_int_comp(VALUE num);
-MJIT_SYMBOL_EXPORT_END
static inline bool
INT_POSITIVE_P(VALUE num)
@@ -148,7 +159,7 @@ rb_num_compare_with_zero(VALUE num, ID mid)
{
VALUE zero = INT2FIX(0);
VALUE r = rb_check_funcall(num, mid, 1, &zero);
- if (r == Qundef) {
+ if (RB_UNDEF_P(r)) {
rb_cmperr(num, zero);
}
return r;
@@ -210,7 +221,15 @@ rb_float_flonum_value(VALUE v)
static inline double
rb_float_noflonum_value(VALUE v)
{
+#if SIZEOF_DOUBLE <= SIZEOF_VALUE
return RFLOAT(v)->float_value;
+#else
+ union {
+ rb_float_value_type v;
+ double d;
+ } u = {RFLOAT(v)->float_value};
+ return u.d;
+#endif
}
static inline double
diff --git a/internal/object.h b/internal/object.h
index 2af90c1fdc..92ad37fdc8 100644
--- a/internal/object.h
+++ b/internal/object.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_OBJECT_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_OBJECT_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -10,31 +9,28 @@
* @brief Internal header for Object.
*/
#include "ruby/ruby.h" /* for VALUE */
-#include "internal/class.h" /* for RCLASS_IV_INDEX_TBL */
-
-#ifdef ROBJECT_IV_INDEX_TBL
-# undef ROBJECT_IV_INDEX_TBL
-#endif
/* object.c */
+size_t rb_obj_embedded_size(uint32_t numiv);
+VALUE rb_class_allocate_instance(VALUE klass);
VALUE rb_class_search_ancestor(VALUE klass, VALUE super);
NORETURN(void rb_undefined_alloc(VALUE klass));
double rb_num_to_dbl(VALUE val);
VALUE rb_obj_dig(int argc, VALUE *argv, VALUE self, VALUE notfound);
+VALUE rb_obj_clone_setup(VALUE obj, VALUE clone, VALUE kwfreeze);
+VALUE rb_obj_dup_setup(VALUE obj, VALUE dup);
VALUE rb_immutable_obj_clone(int, VALUE *, VALUE);
VALUE rb_check_convert_type_with_id(VALUE,int,const char*,ID);
-int rb_bool_expected(VALUE, const char *);
+int rb_bool_expected(VALUE, const char *, int raise);
static inline void RBASIC_CLEAR_CLASS(VALUE obj);
static inline void RBASIC_SET_CLASS_RAW(VALUE obj, VALUE klass);
static inline void RBASIC_SET_CLASS(VALUE obj, VALUE klass);
-static inline struct st_table *ROBJECT_IV_INDEX_TBL_inline(VALUE obj);
RUBY_SYMBOL_EXPORT_BEGIN
/* object.c (export) */
int rb_opts_exception_p(VALUE opts, int default_value);
RUBY_SYMBOL_EXPORT_END
-MJIT_SYMBOL_EXPORT_BEGIN
CONSTFUNC(VALUE rb_obj_equal(VALUE obj1, VALUE obj2));
CONSTFUNC(VALUE rb_obj_not(VALUE obj));
VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
@@ -42,7 +38,7 @@ void rb_obj_copy_ivar(VALUE dest, VALUE obj);
VALUE rb_false(VALUE obj);
VALUE rb_convert_type_with_id(VALUE v, int t, const char* nam, ID mid);
VALUE rb_obj_size(VALUE self, VALUE args, VALUE obj);
-MJIT_SYMBOL_EXPORT_END
+VALUE rb_get_freeze_opt(int argc, VALUE *argv);
static inline void
RBASIC_SET_CLASS_RAW(VALUE obj, VALUE klass)
@@ -64,20 +60,4 @@ RBASIC_SET_CLASS(VALUE obj, VALUE klass)
RBASIC_SET_CLASS_RAW(obj, klass);
RB_OBJ_WRITTEN(obj, oldv, klass);
}
-
-RBIMPL_ATTR_PURE()
-static inline struct st_table *
-ROBJECT_IV_INDEX_TBL_inline(VALUE obj)
-{
- if (RB_FL_ANY_RAW(obj, ROBJECT_EMBED)) {
- VALUE klass = rb_obj_class(obj);
- return RCLASS_IV_INDEX_TBL(klass);
- }
- else {
- const struct RObject *const ptr = ROBJECT(obj);
- return ptr->as.heap.iv_index_tbl;
- }
-}
-#define ROBJECT_IV_INDEX_TBL ROBJECT_IV_INDEX_TBL_inline
-
#endif /* INTERNAL_OBJECT_H */
diff --git a/internal/parse.h b/internal/parse.h
index 588b2b34da..f06020c73f 100644
--- a/internal/parse.h
+++ b/internal/parse.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_PARSE_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_PARSE_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -9,16 +8,110 @@
* file COPYING are met. Consult the file for details.
* @brief Internal header for the parser.
*/
-#include "ruby/ruby.h" /* for VALUE */
+#include <limits.h>
+#include "rubyparser.h"
+#include "internal/static_assert.h"
+
+#ifdef UNIVERSAL_PARSER
+#define rb_encoding void
+#endif
+
struct rb_iseq_struct; /* in vm_core.h */
+/* structs for managing terminator of string literal and heredocment */
+typedef struct rb_strterm_literal_struct {
+ long nest;
+ int func; /* STR_FUNC_* (e.g., STR_FUNC_ESCAPE and STR_FUNC_EXPAND) */
+ int paren; /* '(' of `%q(...)` */
+ int term; /* ')' of `%q(...)` */
+} rb_strterm_literal_t;
+
+typedef struct rb_strterm_heredoc_struct {
+ rb_parser_string_t *lastline; /* the string of line that contains `<<"END"` */
+ long offset; /* the column of END in `<<"END"` */
+ int sourceline; /* lineno of the line that contains `<<"END"` */
+ unsigned length; /* the length of END in `<<"END"` */
+ uint8_t quote;
+ uint8_t func;
+} rb_strterm_heredoc_t;
+
+#define HERETERM_LENGTH_MAX UINT_MAX
+
+typedef struct rb_strterm_struct {
+ bool heredoc;
+ union {
+ rb_strterm_literal_t literal;
+ rb_strterm_heredoc_t heredoc;
+ } u;
+} rb_strterm_t;
+
/* parse.y */
-VALUE rb_parser_set_yydebug(VALUE, VALUE);
-void *rb_parser_load_file(VALUE parser, VALUE name);
-void rb_parser_save_script_lines(VALUE vparser);
+void rb_ruby_parser_mark(void *ptr);
+size_t rb_ruby_parser_memsize(const void *ptr);
+
+void rb_ruby_parser_set_options(rb_parser_t *p, int print, int loop, int chomp, int split);
+rb_parser_t *rb_ruby_parser_set_context(rb_parser_t *p, const struct rb_iseq_struct *base, int main);
+void rb_ruby_parser_set_script_lines(rb_parser_t *p);
+void rb_ruby_parser_error_tolerant(rb_parser_t *p);
+void rb_ruby_parser_keep_tokens(rb_parser_t *p);
+typedef VALUE (rb_parser_lex_gets_func)(struct parser_params*, rb_parser_input_data, int);
+rb_ast_t *rb_parser_compile(rb_parser_t *p, rb_parser_lex_gets_func *gets, VALUE fname, rb_parser_input_data input, int line);
RUBY_SYMBOL_EXPORT_BEGIN
-VALUE rb_parser_set_context(VALUE, const struct rb_iseq_struct *, int);
+
+rb_encoding *rb_ruby_parser_encoding(rb_parser_t *p);
+int rb_ruby_parser_end_seen_p(rb_parser_t *p);
+int rb_ruby_parser_set_yydebug(rb_parser_t *p, int flag);
+rb_parser_string_t *rb_str_to_parser_string(rb_parser_t *p, VALUE str);
+
+int rb_parser_dvar_defined_ref(struct parser_params*, ID, ID**);
+ID rb_parser_internal_id(struct parser_params*);
+int rb_parser_reg_fragment_check(struct parser_params*, rb_parser_string_t*, int);
+int rb_reg_named_capture_assign_iter_impl(struct parser_params *p, const char *s, long len, rb_encoding *enc, NODE **succ_block, const rb_code_location_t *loc);
+int rb_parser_local_defined(struct parser_params *p, ID id, const struct rb_iseq_struct *iseq);
+
RUBY_SYMBOL_EXPORT_END
+#ifndef UNIVERSAL_PARSER
+rb_parser_t *rb_ruby_parser_allocate(void);
+rb_parser_t *rb_ruby_parser_new(void);
+#endif
+
+#ifdef RIPPER
+void ripper_parser_mark(void *ptr);
+void ripper_parser_free(void *ptr);
+size_t ripper_parser_memsize(const void *ptr);
+void ripper_error(struct parser_params *p);
+VALUE ripper_value(struct parser_params *p);
+int rb_ruby_parser_get_yydebug(rb_parser_t *p);
+void rb_ruby_parser_set_value(rb_parser_t *p, VALUE value);
+int rb_ruby_parser_error_p(rb_parser_t *p);
+VALUE rb_ruby_parser_debug_output(rb_parser_t *p);
+void rb_ruby_parser_set_debug_output(rb_parser_t *p, VALUE output);
+VALUE rb_ruby_parser_parsing_thread(rb_parser_t *p);
+void rb_ruby_parser_set_parsing_thread(rb_parser_t *p, VALUE parsing_thread);
+void rb_ruby_parser_ripper_initialize(rb_parser_t *p, rb_parser_lex_gets_func *gets, rb_parser_input_data input, VALUE sourcefile_string, const char *sourcefile, int sourceline);
+VALUE rb_ruby_parser_result(rb_parser_t *p);
+rb_encoding *rb_ruby_parser_enc(rb_parser_t *p);
+VALUE rb_ruby_parser_ruby_sourcefile_string(rb_parser_t *p);
+int rb_ruby_parser_ruby_sourceline(rb_parser_t *p);
+int rb_ruby_parser_lex_state(rb_parser_t *p);
+void rb_ruby_ripper_parse0(rb_parser_t *p);
+int rb_ruby_ripper_dedent_string(rb_parser_t *p, VALUE string, int width);
+int rb_ruby_ripper_initialized_p(rb_parser_t *p);
+void rb_ruby_ripper_parser_initialize(rb_parser_t *p);
+long rb_ruby_ripper_column(rb_parser_t *p);
+long rb_ruby_ripper_token_len(rb_parser_t *p);
+rb_parser_string_t *rb_ruby_ripper_lex_lastline(rb_parser_t *p);
+VALUE rb_ruby_ripper_lex_state_name(struct parser_params *p, int state);
+#ifdef UNIVERSAL_PARSER
+rb_parser_t *rb_ripper_parser_params_allocate(const rb_parser_config_t *config);
+#endif
+struct parser_params *rb_ruby_ripper_parser_allocate(void);
+#endif
+
+#ifdef UNIVERSAL_PARSER
+#undef rb_encoding
+#endif
+
#endif /* INTERNAL_PARSE_H */
diff --git a/internal/proc.h b/internal/proc.h
index 5628a1f1c7..c75f15b283 100644
--- a/internal/proc.h
+++ b/internal/proc.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_PROC_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_PROC_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -23,11 +22,9 @@ int rb_block_min_max_arity(int *max);
VALUE rb_block_to_s(VALUE self, const struct rb_block *block, const char *additional_info);
VALUE rb_callable_receiver(VALUE);
-MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_func_proc_new(rb_block_call_func_t func, VALUE val);
VALUE rb_func_lambda_new(rb_block_call_func_t func, VALUE val, int min_argc, int max_argc);
VALUE rb_iseq_location(const struct rb_iseq_struct *iseq);
VALUE rb_sym_to_proc(VALUE sym);
-MJIT_SYMBOL_EXPORT_END
#endif /* INTERNAL_PROC_H */
diff --git a/internal/process.h b/internal/process.h
index 904c9a5cea..fd4994cb4b 100644
--- a/internal/process.h
+++ b/internal/process.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_PROCESS_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_PROCESS_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -21,12 +20,13 @@
#endif
#include "ruby/ruby.h" /* for VALUE */
+#include "internal/compilers.h" /* for __has_warning */
#include "internal/imemo.h" /* for RB_IMEMO_TMPBUF_PTR */
-#include "internal/warnings.h" /* for COMPILER_WARNING_PUSH */
#define RB_MAX_GROUPS (65536)
struct waitpid_state;
+struct rb_process_status;
struct rb_execarg {
union {
struct {
@@ -57,6 +57,7 @@ struct rb_execarg {
unsigned gid_given : 1;
unsigned exception : 1;
unsigned exception_given : 1;
+ struct rb_process_status *status;
struct waitpid_state *waitpid_state; /* for async process management */
rb_pid_t pgroup_pgid; /* asis(-1), new pgroup(0), specified pgroup (0<V). */
VALUE rlimit_limits; /* Qfalse or [[rtype, softlim, hardlim], ...] */
@@ -74,7 +75,7 @@ struct rb_execarg {
};
/* process.c */
-rb_pid_t rb_fork_ruby(int *status);
+rb_pid_t rb_call_proc__fork(void);
void rb_last_status_clear(void);
static inline char **ARGVSTR2ARGV(VALUE argv_str);
static inline size_t ARGVSTR2ARGC(VALUE argv_str);
@@ -120,17 +121,4 @@ ARGVSTR2ARGC(VALUE argv_str)
return i - 1;
}
-#ifdef HAVE_WORKING_FORK
-COMPILER_WARNING_PUSH
-#if __has_warning("-Wdeprecated-declarations") || RBIMPL_COMPILER_IS(GCC)
-COMPILER_WARNING_IGNORED(-Wdeprecated-declarations)
-#endif
-static inline rb_pid_t
-rb_fork(void)
-{
- return fork();
-}
-COMPILER_WARNING_POP
-#endif
-
#endif /* INTERNAL_PROCESS_H */
diff --git a/internal/ractor.h b/internal/ractor.h
new file mode 100644
index 0000000000..eef5ffdb89
--- /dev/null
+++ b/internal/ractor.h
@@ -0,0 +1,6 @@
+#ifndef INTERNAL_RACTOR_H /*-*-C-*-vi:se ft=c:*/
+#define INTERNAL_RACTOR_H
+
+void rb_ractor_ensure_main_ractor(const char *msg);
+
+#endif /* INTERNAL_RACTOR_H */
diff --git a/internal/random.h b/internal/random.h
index a92e65b8ba..127b908e16 100644
--- a/internal/random.h
+++ b/internal/random.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_RANDOM_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_RANDOM_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -13,5 +12,6 @@
/* random.c */
int ruby_fill_random_bytes(void *, size_t, int);
+void rb_free_default_rand_key(void);
#endif /* INTERNAL_RANDOM_H */
diff --git a/internal/range.h b/internal/range.h
index 4fe6037c89..2394937bf8 100644
--- a/internal/range.h
+++ b/internal/range.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_RANGE_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_RANGE_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -25,13 +24,13 @@ RANGE_BEG(VALUE r)
static inline VALUE
RANGE_END(VALUE r)
{
- return RSTRUCT(r)->as.ary[1];
+ return RSTRUCT_GET(r, 1);
}
static inline VALUE
RANGE_EXCL(VALUE r)
{
- return RSTRUCT(r)->as.ary[2];
+ return RSTRUCT_GET(r, 2);
}
VALUE
diff --git a/internal/rational.h b/internal/rational.h
index 6bbd2a9810..f11fab4583 100644
--- a/internal/rational.h
+++ b/internal/rational.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_RATIONAL_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_RATIONAL_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -11,7 +10,6 @@
*/
#include "ruby/internal/config.h" /* for HAVE_LIBGMP */
#include "ruby/ruby.h" /* for struct RBasic */
-#include "internal/gc.h" /* for RB_OBJ_WRITE */
#include "internal/numeric.h" /* for INT_POSITIVE_P */
#include "ruby_assert.h" /* for assert */
@@ -39,6 +37,7 @@ VALUE rb_rational_cmp(VALUE self, VALUE other);
VALUE rb_rational_pow(VALUE self, VALUE other);
VALUE rb_rational_floor(VALUE self, int ndigits);
VALUE rb_numeric_quo(VALUE x, VALUE y);
+VALUE rb_flo_round_by_rational(int argc, VALUE *argv, VALUE num);
VALUE rb_float_numerator(VALUE x);
VALUE rb_float_denominator(VALUE x);
diff --git a/internal/re.h b/internal/re.h
index a19ad934f7..3e20114665 100644
--- a/internal/re.h
+++ b/internal/re.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_RE_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_RE_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -23,9 +22,7 @@ VALUE rb_reg_equal(VALUE re1, VALUE re2);
void rb_backref_set_string(VALUE string, long pos, long len);
void rb_match_unbusy(VALUE);
int rb_match_count(VALUE match);
-int rb_match_nth_defined(int nth, VALUE match);
-MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_reg_new_ary(VALUE ary, int options);
-MJIT_SYMBOL_EXPORT_END
+VALUE rb_reg_last_defined(VALUE match);
#endif /* INTERNAL_RE_H */
diff --git a/internal/ruby_parser.h b/internal/ruby_parser.h
new file mode 100644
index 0000000000..98c3461954
--- /dev/null
+++ b/internal/ruby_parser.h
@@ -0,0 +1,102 @@
+#ifndef INTERNAL_RUBY_PARSE_H
+#define INTERNAL_RUBY_PARSE_H
+
+#include "internal.h"
+#include "internal/bignum.h"
+#include "internal/compilers.h"
+#include "internal/complex.h"
+#include "internal/parse.h"
+#include "internal/rational.h"
+#include "rubyparser.h"
+#include "vm.h"
+
+struct lex_pointer_string {
+ VALUE str;
+ long ptr;
+};
+
+RUBY_SYMBOL_EXPORT_BEGIN
+#ifdef UNIVERSAL_PARSER
+const rb_parser_config_t *rb_ruby_parser_config(void);
+rb_parser_t *rb_parser_params_new(void);
+#endif
+VALUE rb_parser_set_context(VALUE, const struct rb_iseq_struct *, int);
+VALUE rb_parser_new(void);
+VALUE rb_parser_compile_string_path(VALUE vparser, VALUE fname, VALUE src, int line);
+VALUE rb_str_new_parser_string(rb_parser_string_t *str);
+VALUE rb_str_new_mutable_parser_string(rb_parser_string_t *str);
+VALUE rb_parser_lex_get_str(struct lex_pointer_string *ptr_str);
+
+VALUE rb_node_str_string_val(const NODE *);
+VALUE rb_node_sym_string_val(const NODE *);
+VALUE rb_node_dstr_string_val(const NODE *);
+VALUE rb_node_regx_string_val(const NODE *);
+VALUE rb_node_dregx_string_val(const NODE *);
+VALUE rb_node_line_lineno_val(const NODE *);
+VALUE rb_node_file_path_val(const NODE *);
+VALUE rb_node_encoding_val(const NODE *);
+
+VALUE rb_node_integer_literal_val(const NODE *);
+VALUE rb_node_float_literal_val(const NODE *);
+VALUE rb_node_rational_literal_val(const NODE *);
+VALUE rb_node_imaginary_literal_val(const NODE *);
+RUBY_SYMBOL_EXPORT_END
+
+VALUE rb_parser_end_seen_p(VALUE);
+VALUE rb_parser_encoding(VALUE);
+VALUE rb_parser_set_yydebug(VALUE, VALUE);
+VALUE rb_parser_build_script_lines_from(rb_parser_ary_t *script_lines);
+void rb_parser_set_options(VALUE, int, int, int, int);
+VALUE rb_parser_load_file(VALUE parser, VALUE name);
+void rb_parser_set_script_lines(VALUE vparser);
+void rb_parser_error_tolerant(VALUE vparser);
+void rb_parser_keep_tokens(VALUE vparser);
+
+VALUE rb_parser_compile_string(VALUE, const char*, VALUE, int);
+VALUE rb_parser_compile_file_path(VALUE vparser, VALUE fname, VALUE input, int line);
+VALUE rb_parser_compile_generic(VALUE vparser, rb_parser_lex_gets_func *lex_gets, VALUE fname, VALUE input, int line);
+VALUE rb_parser_compile_array(VALUE vparser, VALUE fname, VALUE array, int start);
+
+enum lex_state_bits {
+ EXPR_BEG_bit, /* ignore newline, +/- is a sign. */
+ EXPR_END_bit, /* newline significant, +/- is an operator. */
+ EXPR_ENDARG_bit, /* ditto, and unbound braces. */
+ EXPR_ENDFN_bit, /* ditto, and unbound braces. */
+ EXPR_ARG_bit, /* newline significant, +/- is an operator. */
+ EXPR_CMDARG_bit, /* newline significant, +/- is an operator. */
+ EXPR_MID_bit, /* newline significant, +/- is an operator. */
+ EXPR_FNAME_bit, /* ignore newline, no reserved words. */
+ EXPR_DOT_bit, /* right after `.', `&.' or `::', no reserved words. */
+ EXPR_CLASS_bit, /* immediate after `class', no here document. */
+ EXPR_LABEL_bit, /* flag bit, label is allowed. */
+ EXPR_LABELED_bit, /* flag bit, just after a label. */
+ EXPR_FITEM_bit, /* symbol literal as FNAME. */
+ EXPR_MAX_STATE
+};
+/* examine combinations */
+enum lex_state_e {
+#define DEF_EXPR(n) EXPR_##n = (1 << EXPR_##n##_bit)
+ DEF_EXPR(BEG),
+ DEF_EXPR(END),
+ DEF_EXPR(ENDARG),
+ DEF_EXPR(ENDFN),
+ DEF_EXPR(ARG),
+ DEF_EXPR(CMDARG),
+ DEF_EXPR(MID),
+ DEF_EXPR(FNAME),
+ DEF_EXPR(DOT),
+ DEF_EXPR(CLASS),
+ DEF_EXPR(LABEL),
+ DEF_EXPR(LABELED),
+ DEF_EXPR(FITEM),
+ EXPR_VALUE = EXPR_BEG,
+ EXPR_BEG_ANY = (EXPR_BEG | EXPR_MID | EXPR_CLASS),
+ EXPR_ARG_ANY = (EXPR_ARG | EXPR_CMDARG),
+ EXPR_END_ANY = (EXPR_END | EXPR_ENDARG | EXPR_ENDFN),
+ EXPR_NONE = 0
+};
+
+VALUE rb_ruby_ast_new(const NODE *const root);
+rb_ast_t *rb_ruby_ast_data_get(VALUE vast);
+
+#endif /* INTERNAL_RUBY_PARSE_H */
diff --git a/internal/sanitizers.h b/internal/sanitizers.h
index b4f5bdeda1..b0eb1fc851 100644
--- a/internal/sanitizers.h
+++ b/internal/sanitizers.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_SANITIZERS_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_SANITIZERS_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -17,11 +16,15 @@
#endif
#ifdef HAVE_SANITIZER_ASAN_INTERFACE_H
-# include <sanitizer/asan_interface.h>
+# if __has_feature(address_sanitizer)
+# define RUBY_ASAN_ENABLED
+# include <sanitizer/asan_interface.h>
+# endif
#endif
#ifdef HAVE_SANITIZER_MSAN_INTERFACE_H
# if __has_feature(memory_sanitizer)
+# define RUBY_MSAN_ENABLED
# include <sanitizer/msan_interface.h>
# endif
#endif
@@ -30,10 +33,10 @@
#include "ruby/ruby.h" /* for VALUE */
#if 0
-#elif __has_feature(memory_sanitizer) && __has_feature(address_sanitizer)
+#elif defined(RUBY_ASAN_ENABLED) && defined(RUBY_MSAN_ENABLED)
# define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
__attribute__((__no_sanitize__("memory, address"), __noinline__)) x
-#elif __has_feature(address_sanitizer)
+#elif defined(RUBY_ASAN_ENABLED)
# define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS(x) \
__attribute__((__no_sanitize__("address"), __noinline__)) x
#elif defined(NO_SANITIZE_ADDRESS)
@@ -61,13 +64,15 @@
# define NO_SANITIZE(x, y) y
#endif
-#if !__has_feature(address_sanitizer)
+#ifndef RUBY_ASAN_ENABLED
# define __asan_poison_memory_region(x, y)
# define __asan_unpoison_memory_region(x, y)
# define __asan_region_is_poisoned(x, y) 0
+# define __asan_get_current_fake_stack() NULL
+# define __asan_addr_is_in_fake_stack(fake_stack, slot, start, end) NULL
#endif
-#if !__has_feature(memory_sanitizer)
+#ifndef RUBY_MSAN_ENABLED
# define __msan_allocated_memory(x, y) ((void)(x), (void)(y))
# define __msan_poison(x, y) ((void)(x), (void)(y))
# define __msan_unpoison(x, y) ((void)(x), (void)(y))
@@ -90,9 +95,7 @@
# define VALGRIND_MAKE_MEM_UNDEFINED(p, n) 0
#endif
-#ifndef MJIT_HEADER
-
-/*!
+/**
* This function asserts that a (continuous) memory region from ptr to size
* being "poisoned". Both read / write access to such memory region are
* prohibited until properly unpoisoned. The region must be previously
@@ -102,8 +105,8 @@
* region to reuse later: poison when you keep it unused, and unpoison when you
* reuse.
*
- * \param[in] ptr pointer to the beginning of the memory region to poison.
- * \param[in] size the length of the memory region to poison.
+ * @param[in] ptr pointer to the beginning of the memory region to poison.
+ * @param[in] size the length of the memory region to poison.
*/
static inline void
asan_poison_memory_region(const volatile void *ptr, size_t size)
@@ -112,10 +115,10 @@ asan_poison_memory_region(const volatile void *ptr, size_t size)
__asan_poison_memory_region(ptr, size);
}
-/*!
+/**
* This is a variant of asan_poison_memory_region that takes a VALUE.
*
- * \param[in] obj target object.
+ * @param[in] obj target object.
*/
static inline void
asan_poison_object(VALUE obj)
@@ -124,20 +127,20 @@ asan_poison_object(VALUE obj)
asan_poison_memory_region(ptr, SIZEOF_VALUE);
}
-#if !__has_feature(address_sanitizer)
-#define asan_poison_object_if(ptr, obj) ((void)(ptr), (void)(obj))
-#else
+#ifdef RUBY_ASAN_ENABLED
#define asan_poison_object_if(ptr, obj) do { \
if (ptr) asan_poison_object(obj); \
} while (0)
+#else
+#define asan_poison_object_if(ptr, obj) ((void)(ptr), (void)(obj))
#endif
-/*!
+/**
* This function predicates if the given object is fully addressable or not.
*
- * \param[in] obj target object.
- * \retval 0 the given object is fully addressable.
- * \retval otherwise pointer to first such byte who is poisoned.
+ * @param[in] obj target object.
+ * @retval 0 the given object is fully addressable.
+ * @retval otherwise pointer to first such byte who is poisoned.
*/
static inline void *
asan_poisoned_object_p(VALUE obj)
@@ -146,7 +149,7 @@ asan_poisoned_object_p(VALUE obj)
return __asan_region_is_poisoned(ptr, SIZEOF_VALUE);
}
-/*!
+/**
* This function asserts that a (formally poisoned) memory region from ptr to
* size is now addressable. Write access to such memory region gets allowed.
* However read access might or might not be possible depending on situations,
@@ -157,9 +160,9 @@ asan_poisoned_object_p(VALUE obj)
* the other hand, that memory region is fully defined and can be read
* immediately.
*
- * \param[in] ptr pointer to the beginning of the memory region to unpoison.
- * \param[in] size the length of the memory region.
- * \param[in] malloc_p if the memory region is like a malloc's return value or not.
+ * @param[in] ptr pointer to the beginning of the memory region to unpoison.
+ * @param[in] size the length of the memory region.
+ * @param[in] malloc_p if the memory region is like a malloc's return value or not.
*/
static inline void
asan_unpoison_memory_region(const volatile void *ptr, size_t size, bool malloc_p)
@@ -173,11 +176,11 @@ asan_unpoison_memory_region(const volatile void *ptr, size_t size, bool malloc_p
}
}
-/*!
+/**
* This is a variant of asan_unpoison_memory_region that takes a VALUE.
*
- * \param[in] obj target object.
- * \param[in] malloc_p if the memory region is like a malloc's return value or not.
+ * @param[in] obj target object.
+ * @param[in] malloc_p if the memory region is like a malloc's return value or not.
*/
static inline void
asan_unpoison_object(VALUE obj, bool newobj_p)
@@ -186,6 +189,109 @@ asan_unpoison_object(VALUE obj, bool newobj_p)
asan_unpoison_memory_region(ptr, SIZEOF_VALUE, newobj_p);
}
-#endif /* MJIT_HEADER */
+static inline void *
+asan_unpoison_object_temporary(VALUE obj)
+{
+ void *ptr = asan_poisoned_object_p(obj);
+ asan_unpoison_object(obj, false);
+ return ptr;
+}
+
+static inline void *
+asan_poison_object_restore(VALUE obj, void *ptr)
+{
+ if (ptr) {
+ asan_poison_object(obj);
+ }
+ return NULL;
+}
+
+
+/**
+ * Checks if the given pointer is on an ASAN fake stack. If so, it returns the
+ * address this variable has on the real frame; if not, it returns the origin
+ * address unmodified.
+ *
+ * n.b. - _dereferencing_ the returned address is meaningless and should not
+ * be done; even though ASAN reserves space for the variable in both the real and
+ * fake stacks, the _value_ of that variable is only in the fake stack.
+ *
+ * n.b. - this only works for addresses passed in from local variables on the same
+ * thread, because the ASAN fake stacks are threadlocal.
+ *
+ * @param[in] slot the address of some local variable
+ * @retval a pointer to something from that frame on the _real_ machine stack
+ */
+static inline void *
+asan_get_real_stack_addr(void* slot)
+{
+ VALUE *addr;
+ addr = __asan_addr_is_in_fake_stack(__asan_get_current_fake_stack(), slot, NULL, NULL);
+ return addr ? addr : slot;
+}
+
+/**
+ * Gets the current thread's fake stack handle, which can be passed into get_fake_stack_extents
+ *
+ * @retval An opaque value which can be passed to asan_get_fake_stack_extents
+ */
+static inline void *
+asan_get_thread_fake_stack_handle(void)
+{
+ return __asan_get_current_fake_stack();
+}
+
+/**
+ * Checks if the given VALUE _actually_ represents a pointer to an ASAN fake stack.
+ *
+ * If the given slot _is_ actually a reference to an ASAN fake stack, and that fake stack
+ * contains the real values for the passed-in range of machine stack addresses, returns true
+ * and the range of the fake stack through the outparams.
+ *
+ * Otherwise, returns false, and sets the outparams to NULL.
+ *
+ * Note that this function expects "start" to be > "end" on downward-growing stack architectures;
+ *
+ * @param[in] thread_fake_stack_handle The asan fake stack reference for the thread we're scanning
+ * @param[in] slot The value on the machine stack we want to inspect
+ * @param[in] machine_stack_start The extents of the real machine stack on which slot lives
+ * @param[in] machine_stack_end The extents of the real machine stack on which slot lives
+ * @param[out] fake_stack_start_out The extents of the fake stack which contains real VALUEs
+ * @param[out] fake_stack_end_out The extents of the fake stack which contains real VALUEs
+ * @return Whether slot is a pointer to a fake stack for the given machine stack range
+*/
+
+static inline bool
+asan_get_fake_stack_extents(void *thread_fake_stack_handle, VALUE slot,
+ void *machine_stack_start, void *machine_stack_end,
+ void **fake_stack_start_out, void **fake_stack_end_out)
+{
+ /* the ifdef is needed here to suppress a warning about fake_frame_{start/end} being
+ uninitialized if __asan_addr_is_in_fake_stack is an empty macro */
+#ifdef RUBY_ASAN_ENABLED
+ void *fake_frame_start;
+ void *fake_frame_end;
+ void *real_stack_frame = __asan_addr_is_in_fake_stack(
+ thread_fake_stack_handle, (void *)slot, &fake_frame_start, &fake_frame_end
+ );
+ if (real_stack_frame) {
+ bool in_range;
+#if STACK_GROW_DIRECTION < 0
+ in_range = machine_stack_start >= real_stack_frame && real_stack_frame >= machine_stack_end;
+#else
+ in_range = machine_stack_start <= real_stack_frame && real_stack_frame <= machine_stack_end;
+#endif
+ if (in_range) {
+ *fake_stack_start_out = fake_frame_start;
+ *fake_stack_end_out = fake_frame_end;
+ return true;
+ }
+ }
+#endif
+ *fake_stack_start_out = 0;
+ *fake_stack_end_out = 0;
+ return false;
+}
+
#endif /* INTERNAL_SANITIZERS_H */
diff --git a/internal/serial.h b/internal/serial.h
index 977cb35477..df9e9a44f0 100644
--- a/internal/serial.h
+++ b/internal/serial.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_SERIAL_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_SERIAL_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
diff --git a/internal/signal.h b/internal/signal.h
index 6b4672f15b..2363bf412c 100644
--- a/internal/signal.h
+++ b/internal/signal.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_SIGNAL_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_SIGNAL_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -14,9 +13,12 @@
extern int ruby_enable_coredump;
int rb_get_next_signal(void);
+#ifdef POSIX_SIGNAL
+void (*ruby_posix_signal(int, void (*)(int)))(int);
+#endif
+
RUBY_SYMBOL_EXPORT_BEGIN
/* signal.c (export) */
-int rb_grantpt(int fd);
RUBY_SYMBOL_EXPORT_END
#endif /* INTERNAL_SIGNAL_H */
diff --git a/internal/st.h b/internal/st.h
new file mode 100644
index 0000000000..a26b224505
--- /dev/null
+++ b/internal/st.h
@@ -0,0 +1,11 @@
+#ifndef INTERNAL_ST_H
+#define INTERNAL_ST_H
+
+#include "include/ruby/st.h"
+
+st_table *rb_st_replace(st_table *new_tab, st_table *old_tab);
+#define st_replace rb_st_replace
+st_table *rb_st_init_existing_table_with_size(st_table *tab, const struct st_hash_type *type, st_index_t size);
+#define st_init_existing_table_with_size rb_st_init_existing_table_with_size
+
+#endif
diff --git a/internal/static_assert.h b/internal/static_assert.h
index 284e410313..70dd0b7a1e 100644
--- a/internal/static_assert.h
+++ b/internal/static_assert.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_STATIC_ASSERT_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_STATIC_ASSERT_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
diff --git a/internal/string.h b/internal/string.h
index 29213537ed..fb37f73114 100644
--- a/internal/string.h
+++ b/internal/string.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_STRING_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_STRING_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -18,6 +17,7 @@
#define STR_NOEMBED FL_USER1
#define STR_SHARED FL_USER2 /* = ELTS_SHARED */
+#define STR_CHILLED FL_USER3
#ifdef rb_fstring_cstr
# undef rb_fstring_cstr
@@ -38,10 +38,15 @@ VALUE rb_external_str_with_enc(VALUE str, rb_encoding *eenc);
VALUE rb_str_cat_conv_enc_opts(VALUE newstr, long ofs, const char *ptr, long len,
rb_encoding *from, int ecflags, VALUE ecopts);
VALUE rb_enc_str_scrub(rb_encoding *enc, VALUE str, VALUE repl);
+VALUE rb_str_escape(VALUE str);
size_t rb_str_memsize(VALUE);
char *rb_str_to_cstr(VALUE str);
const char *ruby_escaped_char(int c);
void rb_str_make_independent(VALUE str);
+int rb_enc_str_coderange_scan(VALUE str, rb_encoding *enc);
+int rb_ascii8bit_appendable_encoding_index(rb_encoding *enc, unsigned int code);
+VALUE rb_str_include(VALUE str, VALUE arg);
+VALUE rb_str_byte_substr(VALUE str, VALUE beg, VALUE len);
static inline bool STR_EMBED_P(VALUE str);
static inline bool STR_SHARED_P(VALUE str);
@@ -54,13 +59,16 @@ static inline VALUE rb_str_eql_internal(const VALUE str1, const VALUE str2);
RUBY_SYMBOL_EXPORT_BEGIN
/* string.c (export) */
VALUE rb_str_tmp_frozen_acquire(VALUE str);
+VALUE rb_str_tmp_frozen_no_embed_acquire(VALUE str);
void rb_str_tmp_frozen_release(VALUE str, VALUE tmp);
VALUE rb_setup_fake_str(struct RString *fake_str, const char *name, long len, rb_encoding *enc);
VALUE rb_str_upto_each(VALUE, VALUE, int, int (*each)(VALUE, VALUE), VALUE);
VALUE rb_str_upto_endless_each(VALUE, int (*each)(VALUE, VALUE), VALUE);
+void rb_str_make_embedded(VALUE);
+size_t rb_str_size_as_embedded(VALUE);
+bool rb_str_reembeddable_p(VALUE);
RUBY_SYMBOL_EXPORT_END
-MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_fstring_new(const char *ptr, long len);
VALUE rb_obj_as_string_result(VALUE str, VALUE obj);
VALUE rb_str_opt_plus(VALUE x, VALUE y);
@@ -70,8 +78,7 @@ VALUE rb_id_quote_unprintable(ID);
VALUE rb_sym_proc_call(ID mid, int argc, const VALUE *argv, int kw_splat, VALUE passed_proc);
struct rb_execution_context_struct;
-VALUE rb_ec_str_resurrect(struct rb_execution_context_struct *ec, VALUE str);
-MJIT_SYMBOL_EXPORT_END
+VALUE rb_ec_str_resurrect(struct rb_execution_context_struct *ec, VALUE str, bool chilled);
#define rb_fstring_lit(str) rb_fstring_new((str), rb_strlen_lit(str))
#define rb_fstring_literal(str) rb_fstring_lit(str)
@@ -99,7 +106,27 @@ STR_EMBED_P(VALUE str)
static inline bool
STR_SHARED_P(VALUE str)
{
- return FL_ALL_RAW(str, STR_NOEMBED | ELTS_SHARED);
+ return FL_ALL_RAW(str, STR_NOEMBED | STR_SHARED);
+}
+
+static inline bool
+CHILLED_STRING_P(VALUE obj)
+{
+ return RB_TYPE_P(obj, T_STRING) && FL_TEST_RAW(obj, STR_CHILLED);
+}
+
+static inline void
+CHILLED_STRING_MUTATED(VALUE str)
+{
+ rb_category_warn(RB_WARN_CATEGORY_DEPRECATED, "literal string will be frozen in the future");
+ FL_UNSET_RAW(str, STR_CHILLED | FL_FREEZE);
+}
+
+static inline void
+STR_CHILL_RAW(VALUE str)
+{
+ // Chilled strings are always also frozen
+ FL_SET_RAW(str, STR_CHILLED | RUBY_FL_FREEZE);
}
static inline bool
@@ -114,7 +141,23 @@ is_broken_string(VALUE str)
return rb_enc_str_coderange(str) == ENC_CODERANGE_BROKEN;
}
+static inline bool
+at_char_boundary(const char *s, const char *p, const char *e, rb_encoding *enc)
+{
+ return rb_enc_left_char_head(s, p, e, enc) == p;
+}
+
+static inline bool
+at_char_right_boundary(const char *s, const char *p, const char *e, rb_encoding *enc)
+{
+ RUBY_ASSERT(s <= p);
+ RUBY_ASSERT(p <= e);
+
+ return rb_enc_right_char_head(s, p, e, enc) == p;
+}
+
/* expect tail call optimization */
+// YJIT needs this function to never allocate and never raise
static inline VALUE
rb_str_eql_internal(const VALUE str1, const VALUE str2)
{
diff --git a/internal/struct.h b/internal/struct.h
index 82b2738b69..6da5bad10a 100644
--- a/internal/struct.h
+++ b/internal/struct.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_STRUCT_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_STRUCT_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -10,14 +9,12 @@
* @brief Internal header for Struct.
*/
#include "ruby/internal/stdbool.h" /* for bool */
-#include "internal/gc.h" /* for RB_OBJ_WRITE */
#include "ruby/ruby.h" /* for struct RBasic */
enum {
- RSTRUCT_EMBED_LEN_MAX = RVALUE_EMBED_LEN_MAX,
- RSTRUCT_EMBED_LEN_MASK = (RUBY_FL_USER2|RUBY_FL_USER1),
+ RSTRUCT_EMBED_LEN_MASK = RUBY_FL_USER7 | RUBY_FL_USER6 | RUBY_FL_USER5 | RUBY_FL_USER4 |
+ RUBY_FL_USER3 | RUBY_FL_USER2 | RUBY_FL_USER1,
RSTRUCT_EMBED_LEN_SHIFT = (RUBY_FL_USHIFT+1),
- RSTRUCT_TRANSIENT_FLAG = FL_USER3,
};
struct RStruct {
@@ -27,7 +24,12 @@ struct RStruct {
long len;
const VALUE *ptr;
} heap;
- const VALUE ary[RSTRUCT_EMBED_LEN_MAX];
+ /* This is a length 1 array because:
+ * 1. GCC has a bug that does not optimize C flexible array members
+ * (https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102452)
+ * 2. Zero length arrays are not supported by all compilers
+ */
+ const VALUE ary[1];
} as;
};
@@ -58,9 +60,6 @@ VALUE rb_struct_init_copy(VALUE copy, VALUE s);
VALUE rb_struct_lookup(VALUE s, VALUE idx);
VALUE rb_struct_s_keyword_init(VALUE klass);
static inline const VALUE *rb_struct_const_heap_ptr(VALUE st);
-static inline bool RSTRUCT_TRANSIENT_P(VALUE st);
-static inline void RSTRUCT_TRANSIENT_SET(VALUE st);
-static inline void RSTRUCT_TRANSIENT_UNSET(VALUE st);
static inline long RSTRUCT_EMBED_LEN(VALUE st);
static inline long RSTRUCT_LEN(VALUE st);
static inline int RSTRUCT_LENINT(VALUE st);
@@ -68,32 +67,6 @@ static inline const VALUE *RSTRUCT_CONST_PTR(VALUE st);
static inline void RSTRUCT_SET(VALUE st, long k, VALUE v);
static inline VALUE RSTRUCT_GET(VALUE st, long k);
-static inline bool
-RSTRUCT_TRANSIENT_P(VALUE st)
-{
-#if USE_TRANSIENT_HEAP
- return FL_TEST_RAW(st, RSTRUCT_TRANSIENT_FLAG);
-#else
- return false;
-#endif
-}
-
-static inline void
-RSTRUCT_TRANSIENT_SET(VALUE st)
-{
-#if USE_TRANSIENT_HEAP
- FL_SET_RAW(st, RSTRUCT_TRANSIENT_FLAG);
-#endif
-}
-
-static inline void
-RSTRUCT_TRANSIENT_UNSET(VALUE st)
-{
-#if USE_TRANSIENT_HEAP
- FL_UNSET_RAW(st, RSTRUCT_TRANSIENT_FLAG);
-#endif
-}
-
static inline long
RSTRUCT_EMBED_LEN(VALUE st)
{
@@ -147,7 +120,7 @@ RSTRUCT_GET(VALUE st, long k)
static inline const VALUE *
rb_struct_const_heap_ptr(VALUE st)
{
- /* TODO: check embed on debug mode */
+ assert(!FL_TEST_RAW(st, RSTRUCT_EMBED_LEN_MASK));
return RSTRUCT(st)->as.heap.ptr;
}
diff --git a/internal/symbol.h b/internal/symbol.h
index 691df66228..e7730cb70f 100644
--- a/internal/symbol.h
+++ b/internal/symbol.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_SYMBOL_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_SYMBOL_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -29,7 +28,12 @@ int rb_is_local_name(VALUE name);
PUREFUNC(int rb_is_const_sym(VALUE sym));
PUREFUNC(int rb_is_attrset_sym(VALUE sym));
ID rb_make_internal_id(void);
+ID rb_make_temporary_id(size_t n);
void rb_gc_free_dsymbol(VALUE);
+int rb_static_id_valid_p(ID id);
+
+/* vm.c */
+void rb_free_static_symid_str(void);
#if __has_builtin(__builtin_constant_p)
#define rb_sym_intern_ascii_cstr(ptr) \
diff --git a/internal/thread.h b/internal/thread.h
index 09b8551b5c..47273436e3 100644
--- a/internal/thread.h
+++ b/internal/thread.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_THREAD_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_THREAD_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -11,9 +10,17 @@
*/
#include "ruby/ruby.h" /* for VALUE */
#include "ruby/intern.h" /* for rb_blocking_function_t */
+#include "ccan/list/list.h" /* for list in rb_io_close_wait_list */
struct rb_thread_struct; /* in vm_core.h */
+#define RB_VM_SAVE_MACHINE_CONTEXT(th) \
+ do { \
+ FLUSH_REGISTER_WINDOWS; \
+ setjmp((th)->ec->machine.regs); \
+ SET_MACHINE_STACK_END(&(th)->ec->machine.stack_end); \
+ } while (0)
+
/* thread.c */
#define COVERAGE_INDEX_LINES 0
#define COVERAGE_INDEX_BRANCHES 1
@@ -21,6 +28,11 @@ struct rb_thread_struct; /* in vm_core.h */
#define COVERAGE_TARGET_BRANCHES 2
#define COVERAGE_TARGET_METHODS 4
#define COVERAGE_TARGET_ONESHOT_LINES 8
+#define COVERAGE_TARGET_EVAL 16
+
+#define RUBY_FATAL_THREAD_KILLED INT2FIX(0)
+#define RUBY_FATAL_THREAD_TERMINATED INT2FIX(1)
+#define RUBY_FATAL_FIBER_KILLED RB_INT2FIX(2)
VALUE rb_obj_is_mutex(VALUE obj);
VALUE rb_suppress_tracing(VALUE (*func)(VALUE), VALUE arg);
@@ -29,6 +41,7 @@ VALUE rb_get_coverages(void);
int rb_get_coverage_mode(void);
VALUE rb_default_coverage(int);
VALUE rb_thread_shield_new(void);
+bool rb_thread_shield_owned(VALUE self);
VALUE rb_thread_shield_wait(VALUE self);
VALUE rb_thread_shield_release(VALUE self);
VALUE rb_thread_shield_destroy(VALUE self);
@@ -36,19 +49,31 @@ int rb_thread_to_be_killed(VALUE thread);
void rb_mutex_allow_trap(VALUE self, int val);
VALUE rb_uninterruptible(VALUE (*b_proc)(VALUE), VALUE data);
VALUE rb_mutex_owned_p(VALUE self);
+VALUE rb_exec_recursive_outer_mid(VALUE (*f)(VALUE g, VALUE h, int r), VALUE g, VALUE h, ID mid);
+void ruby_mn_threads_params(void);
int rb_thread_wait_for_single_fd(int fd, int events, struct timeval * timeout);
+struct rb_io_close_wait_list {
+ struct ccan_list_head pending_fd_users;
+ VALUE closing_thread;
+ VALUE wakeup_mutex;
+};
+int rb_notify_fd_close(int fd, struct rb_io_close_wait_list *busy);
+void rb_notify_fd_close_wait(struct rb_io_close_wait_list *busy);
+
RUBY_SYMBOL_EXPORT_BEGIN
+
/* Temporary. This API will be removed (renamed). */
VALUE rb_thread_io_blocking_region(rb_blocking_function_t *func, void *data1, int fd);
+VALUE rb_thread_io_blocking_call(rb_blocking_function_t *func, void *data1, int fd, int events);
/* thread.c (export) */
int ruby_thread_has_gvl_p(void); /* for ext/fiddle/closure.c */
+
RUBY_SYMBOL_EXPORT_END
-MJIT_SYMBOL_EXPORT_BEGIN
int rb_threadptr_execute_interrupts(struct rb_thread_struct *th, int blocking_timing);
-MJIT_SYMBOL_EXPORT_END
+bool rb_thread_mn_schedulable(VALUE thread);
#endif /* INTERNAL_THREAD_H */
diff --git a/internal/time.h b/internal/time.h
index f9ac084603..a3bf0587ec 100644
--- a/internal/time.h
+++ b/internal/time.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_TIME_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_TIME_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
diff --git a/internal/transcode.h b/internal/transcode.h
index a60ac06d10..ce4f2341be 100644
--- a/internal/transcode.h
+++ b/internal/transcode.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_TRANSCODE_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_TRANSCODE_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -18,4 +17,7 @@
extern VALUE rb_cEncodingConverter;
size_t rb_econv_memsize(rb_econv_t *);
+/* vm.c */
+void rb_free_transcoder_table(void);
+
#endif /* INTERNAL_TRANSCODE_H */
diff --git a/internal/util.h b/internal/util.h
index c28b884d32..6eadbb9f94 100644
--- a/internal/util.h
+++ b/internal/util.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_UTIL_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_UTIL_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -23,9 +22,6 @@ char *ruby_hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign
RUBY_SYMBOL_EXPORT_BEGIN
/* util.c (export) */
-extern const signed char ruby_digit36_to_number_table[];
-extern const char ruby_hexdigits[];
-extern unsigned long ruby_scan_digits(const char *str, ssize_t len, int base, size_t *retlen, int *overflow);
RUBY_SYMBOL_EXPORT_END
#endif /* INTERNAL_UTIL_H */
diff --git a/internal/variable.h b/internal/variable.h
index 057beccfcc..b2a30c7c58 100644
--- a/internal/variable.h
+++ b/internal/variable.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_VARIABLE_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_VARIABLE_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -14,10 +13,7 @@
#include "constant.h" /* for rb_const_entry_t */
#include "ruby/internal/stdbool.h" /* for bool */
#include "ruby/ruby.h" /* for VALUE */
-
-/* global variable */
-
-#define ROBJECT_TRANSIENT_FLAG FL_USER13
+#include "shape.h" /* for rb_shape_t */
/* variable.c */
void rb_gc_mark_global_tbl(void);
@@ -25,7 +21,6 @@ void rb_gc_update_global_tbl(void);
size_t rb_generic_ivar_memsize(VALUE);
VALUE rb_search_class_path(VALUE);
VALUE rb_attr_delete(VALUE, ID);
-VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef);
void rb_autoload_str(VALUE mod, ID id, VALUE file);
VALUE rb_autoload_at_p(VALUE, ID, int);
NORETURN(VALUE rb_mod_const_missing(VALUE,VALUE));
@@ -33,52 +28,45 @@ rb_gvar_getter_t *rb_gvar_getter_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_ractor_local(const char *name);
-static inline bool ROBJ_TRANSIENT_P(VALUE obj);
-static inline void ROBJ_TRANSIENT_SET(VALUE obj);
-static inline void ROBJ_TRANSIENT_UNSET(VALUE obj);
+
+/**
+ * Sets the name of a module.
+ *
+ * Non-permanently named classes can have a temporary name assigned (or
+ * cleared). In that case the name will be used for `#inspect` and `#to_s`, and
+ * nested classes/modules will be named with the temporary name as a prefix.
+ *
+ * After the module is assigned to a constant, the temporary name will be
+ * discarded, and the name will be computed based on the nesting.
+ *
+ * @param[in] mod An instance of ::rb_cModule.
+ * @param[in] name An instance of ::rb_cString.
+ * @retval mod
+ */
+VALUE rb_mod_set_temporary_name(VALUE, VALUE);
+
+struct gen_ivtbl;
+int rb_gen_ivtbl_get(VALUE obj, ID id, struct gen_ivtbl **ivtbl);
+void rb_obj_copy_ivs_to_hash_table(VALUE obj, st_table *table);
+void rb_obj_convert_to_too_complex(VALUE obj, st_table *table);
+void rb_evict_ivars_to_hash(VALUE obj);
RUBY_SYMBOL_EXPORT_BEGIN
/* variable.c (export) */
-void rb_mark_generic_ivar(VALUE);
+void rb_mark_generic_ivar(VALUE obj);
+void rb_ref_update_generic_ivar(VALUE);
void rb_mv_generic_ivar(VALUE src, VALUE dst);
VALUE rb_const_missing(VALUE klass, VALUE name);
int rb_class_ivar_set(VALUE klass, ID vid, VALUE value);
void rb_iv_tbl_copy(VALUE dst, VALUE src);
-void rb_deprecate_constant(VALUE mod, const char *name);
RUBY_SYMBOL_EXPORT_END
-MJIT_SYMBOL_EXPORT_BEGIN
+VALUE rb_ivar_lookup(VALUE obj, ID id, VALUE undef);
VALUE rb_gvar_get(ID);
VALUE rb_gvar_set(ID, VALUE);
VALUE rb_gvar_defined(ID);
void rb_const_warn_if_deprecated(const rb_const_entry_t *, VALUE, ID);
-void rb_init_iv_list(VALUE obj);
-MJIT_SYMBOL_EXPORT_END
-
-static inline bool
-ROBJ_TRANSIENT_P(VALUE obj)
-{
-#if USE_TRANSIENT_HEAP
- return FL_TEST_RAW(obj, ROBJECT_TRANSIENT_FLAG);
-#else
- return false;
-#endif
-}
-
-static inline void
-ROBJ_TRANSIENT_SET(VALUE obj)
-{
-#if USE_TRANSIENT_HEAP
- FL_SET_RAW(obj, ROBJECT_TRANSIENT_FLAG);
-#endif
-}
-
-static inline void
-ROBJ_TRANSIENT_UNSET(VALUE obj)
-{
-#if USE_TRANSIENT_HEAP
- FL_UNSET_RAW(obj, ROBJECT_TRANSIENT_FLAG);
-#endif
-}
+void rb_ensure_iv_list_size(VALUE obj, uint32_t len, uint32_t newsize);
+attr_index_t rb_obj_ivar_set(VALUE obj, ID id, VALUE val);
#endif /* INTERNAL_VARIABLE_H */
diff --git a/internal/vm.h b/internal/vm.h
index 8251b09e98..74635e6ad8 100644
--- a/internal/vm.h
+++ b/internal/vm.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_VM_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_VM_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or
@@ -41,28 +40,25 @@ enum method_missing_reason {
};
/* vm_insnhelper.h */
-rb_serial_t rb_next_class_serial(void);
+VALUE rb_vm_push_frame_fname(struct rb_execution_context_struct *ec, VALUE fname);
/* vm.c */
VALUE rb_obj_is_thread(VALUE obj);
void rb_vm_mark(void *ptr);
+void rb_vm_register_global_object(VALUE obj);
void rb_vm_each_stack_value(void *ptr, void (*cb)(VALUE, void*), void *ctx);
PUREFUNC(VALUE rb_vm_top_self(void));
-void rb_vm_inc_const_missing_count(void);
const void **rb_vm_get_insns_address_table(void);
VALUE rb_source_location(int *pline);
const char *rb_source_location_cstr(int *pline);
-MJIT_STATIC void rb_vm_pop_cfunc_frame(void);
-int rb_vm_add_root_module(VALUE module);
+void rb_vm_pop_cfunc_frame(void);
void rb_vm_check_redefinition_by_prepend(VALUE klass);
int rb_vm_check_optimizable_mid(VALUE mid);
VALUE rb_yield_refine_block(VALUE refinement, VALUE refinements);
-MJIT_STATIC VALUE ruby_vm_special_exception_copy(VALUE);
+VALUE ruby_vm_special_exception_copy(VALUE);
PUREFUNC(st_table *rb_vm_fstring_table(void));
-MJIT_SYMBOL_EXPORT_BEGIN
-VALUE vm_exec(struct rb_execution_context_struct *, bool); /* used in JIT-ed code */
-MJIT_SYMBOL_EXPORT_END
+void rb_lastline_set_up(VALUE val, unsigned int up);
/* vm_eval.c */
VALUE rb_current_realfilepath(void);
@@ -82,23 +78,31 @@ VALUE rb_lambda_call(VALUE obj, ID mid, int argc, const VALUE *argv,
VALUE data2);
void rb_check_stack_overflow(void);
+#if USE_YJIT
+/* vm_exec.c */
+extern uint64_t rb_vm_insns_count;
+#endif
+
+extern bool rb_free_at_exit;
+
+/* miniinit.c and builtin.c */
+void rb_free_loaded_builtin_table(void);
+
/* vm_insnhelper.c */
VALUE rb_equal_opt(VALUE obj1, VALUE obj2);
VALUE rb_eql_opt(VALUE obj1, VALUE obj2);
struct rb_iseq_struct;
-MJIT_SYMBOL_EXPORT_BEGIN
const struct rb_callcache *rb_vm_search_method_slowpath(const struct rb_callinfo *ci, VALUE klass);
-MJIT_SYMBOL_EXPORT_END
/* vm_method.c */
struct rb_execution_context_struct;
-MJIT_SYMBOL_EXPORT_BEGIN
int rb_ec_obj_respond_to(struct rb_execution_context_struct *ec, VALUE obj, ID id, int priv);
-MJIT_SYMBOL_EXPORT_END
+
+void rb_clear_constant_cache(void);
/* vm_dump.c */
-void rb_print_backtrace(void);
+void rb_print_backtrace(FILE *);
/* vm_backtrace.c */
VALUE rb_vm_thread_backtrace(int argc, const VALUE *argv, VALUE thval);
@@ -106,18 +110,18 @@ VALUE rb_vm_thread_backtrace_locations(int argc, const VALUE *argv, VALUE thval)
VALUE rb_vm_backtrace(int argc, const VALUE * argv, struct rb_execution_context_struct * ec);
VALUE rb_vm_backtrace_locations(int argc, const VALUE * argv, struct rb_execution_context_struct * ec);
VALUE rb_make_backtrace(void);
-void rb_backtrace_print_as_bugreport(void);
+void rb_backtrace_print_as_bugreport(FILE*);
int rb_backtrace_p(VALUE obj);
VALUE rb_backtrace_to_str_ary(VALUE obj);
VALUE rb_backtrace_to_location_ary(VALUE obj);
+VALUE rb_location_ary_to_backtrace(VALUE ary);
void rb_backtrace_each(VALUE (*iter)(VALUE recv, VALUE str), VALUE output);
int rb_frame_info_p(VALUE obj);
-void rb_frame_info_get(VALUE obj, VALUE *path, int *node_id);
+int rb_get_node_id_from_frame_info(VALUE obj);
+const struct rb_iseq_struct *rb_get_iseq_from_frame_info(VALUE obj);
-MJIT_SYMBOL_EXPORT_BEGIN
VALUE rb_ec_backtrace_object(const struct rb_execution_context_struct *ec);
void rb_backtrace_use_iseq_first_lineno_for_last_location(VALUE self);
-MJIT_SYMBOL_EXPORT_END
#define RUBY_DTRACE_CREATE_HOOK(name, arg) \
RUBY_DTRACE_HOOK(name##_CREATE, arg)
diff --git a/internal/warnings.h b/internal/warnings.h
index e9de46eb38..020212ebd8 100644
--- a/internal/warnings.h
+++ b/internal/warnings.h
@@ -1,7 +1,6 @@
#ifndef INTERNAL_WARNINGS_H /*-*-C-*-vi:se ft=c:*/
#define INTERNAL_WARNINGS_H
/**
- * @file
* @author Ruby developers <ruby-core@ruby-lang.org>
* @copyright This file is a part of the programming language Ruby.
* Permission is hereby granted, to either redistribute and/or