summaryrefslogtreecommitdiff
path: root/include/ruby
diff options
context:
space:
mode:
Diffstat (limited to 'include/ruby')
-rw-r--r--include/ruby/assert.h2
-rw-r--r--include/ruby/backward.h52
-rw-r--r--include/ruby/backward/2/assume.h2
-rw-r--r--include/ruby/debug.h35
-rw-r--r--include/ruby/fiber/scheduler.h176
-rw-r--r--include/ruby/internal/abi.h58
-rw-r--r--include/ruby/internal/anyargs.h15
-rw-r--r--include/ruby/internal/arithmetic.h3
-rw-r--r--include/ruby/internal/arithmetic/long.h2
-rw-r--r--include/ruby/internal/assume.h5
-rw-r--r--include/ruby/internal/attr/nodiscard.h2
-rw-r--r--include/ruby/internal/config.h6
-rw-r--r--include/ruby/internal/core/rarray.h45
-rw-r--r--include/ruby/internal/core/rclass.h49
-rw-r--r--include/ruby/internal/core/rdata.h24
-rw-r--r--include/ruby/internal/core/robject.h61
-rw-r--r--include/ruby/internal/core/rstring.h42
-rw-r--r--include/ruby/internal/encoding/ctype.h101
-rw-r--r--include/ruby/internal/encoding/encoding.h30
-rw-r--r--include/ruby/internal/encoding/string.h2
-rw-r--r--include/ruby/internal/encoding/transcode.h18
-rw-r--r--include/ruby/internal/eval.h33
-rw-r--r--include/ruby/internal/fl_type.h27
-rw-r--r--include/ruby/internal/has/builtin.h8
-rw-r--r--include/ruby/internal/intern/array.h6
-rw-r--r--include/ruby/internal/intern/class.h40
-rw-r--r--include/ruby/internal/intern/cont.h22
-rw-r--r--include/ruby/internal/intern/error.h14
-rw-r--r--include/ruby/internal/intern/file.h21
-rw-r--r--include/ruby/internal/intern/gc.h8
-rw-r--r--include/ruby/internal/intern/hash.h20
-rw-r--r--include/ruby/internal/intern/object.h72
-rw-r--r--include/ruby/internal/intern/select/largesize.h3
-rw-r--r--include/ruby/internal/intern/select/posix.h5
-rw-r--r--include/ruby/internal/intern/string.h76
-rw-r--r--include/ruby/internal/intern/thread.h4
-rw-r--r--include/ruby/internal/intern/vm.h14
-rw-r--r--include/ruby/internal/memory.h12
-rw-r--r--include/ruby/internal/scan_args.h2
-rw-r--r--include/ruby/internal/special_consts.h87
-rw-r--r--include/ruby/internal/stdbool.h2
-rw-r--r--include/ruby/internal/variable.h2
-rw-r--r--include/ruby/io.h159
-rw-r--r--include/ruby/io/buffer.h92
-rw-r--r--include/ruby/memory_view.h14
-rw-r--r--include/ruby/missing.h113
-rw-r--r--include/ruby/onigmo.h15
-rw-r--r--include/ruby/ractor.h2
-rw-r--r--include/ruby/random.h63
-rw-r--r--include/ruby/ruby.h39
-rw-r--r--include/ruby/st.h2
-rw-r--r--include/ruby/thread.h44
-rw-r--r--include/ruby/thread_native.h6
-rw-r--r--include/ruby/util.h4
-rw-r--r--include/ruby/version.h5
-rw-r--r--include/ruby/win32.h53
56 files changed, 1181 insertions, 638 deletions
diff --git a/include/ruby/assert.h b/include/ruby/assert.h
index c9f2c3fbef..0c052363bc 100644
--- a/include/ruby/assert.h
+++ b/include/ruby/assert.h
@@ -103,7 +103,7 @@
# /* keep NDEBUG undefined */
#elif (RBIMPL_NDEBUG == 0) && (RBIMPL_RUBY_DEBUG == 0)
-# /* The (*1) situation in avobe diagram. */
+# /* The (*1) situation in above diagram. */
# define RUBY_DEBUG 0
# define RUBY_NDEBUG 1
# define NDEBUG
diff --git a/include/ruby/backward.h b/include/ruby/backward.h
index e12f98ac47..f804c2c36e 100644
--- a/include/ruby/backward.h
+++ b/include/ruby/backward.h
@@ -13,59 +13,13 @@
#define RBIMPL_ATTR_DEPRECATED_SINCE(ver) RBIMPL_ATTR_DEPRECATED(("since " #ver))
#define RBIMPL_ATTR_DEPRECATED_INTERNAL(ver) RBIMPL_ATTR_DEPRECATED(("since "#ver", also internal"))
+#define RBIMPL_ATTR_DEPRECATED_INTERNAL_ONLY() RBIMPL_ATTR_DEPRECATED(("only for internal use"))
-/* eval.c */
-RBIMPL_ATTR_DEPRECATED_SINCE(2.2) void rb_disable_super();
-RBIMPL_ATTR_DEPRECATED_SINCE(2.2) void rb_enable_super();
-
-/* hash.c */
-RBIMPL_ATTR_DEPRECATED_SINCE(2.2) void rb_hash_iter_lev();
-RBIMPL_ATTR_DEPRECATED_SINCE(2.2) void rb_hash_ifnone();
-
-/* string.c */
-RBIMPL_ATTR_DEPRECATED_SINCE(2.2) void rb_str_associate();
-RBIMPL_ATTR_DEPRECATED_SINCE(2.2) void rb_str_associated();
-
-/* variable.c */
-RBIMPL_ATTR_DEPRECATED_SINCE(2.5) void rb_autoload();
-
-/* eval.c */
-RBIMPL_ATTR_DEPRECATED_INTERNAL(2.6) void rb_frozen_class_p();
-RBIMPL_ATTR_DEPRECATED_INTERNAL(2.7) void rb_exec_end_proc();
-
-/* error.c */
-RBIMPL_ATTR_DEPRECATED_INTERNAL(2.3) void rb_compile_error();
-RBIMPL_ATTR_DEPRECATED_INTERNAL(2.3) void rb_compile_error_with_enc();
-RBIMPL_ATTR_DEPRECATED_INTERNAL(2.3) void rb_compile_error_append();
-
-/* gc.c */
-RBIMPL_ATTR_DEPRECATED_INTERNAL(2.7) void rb_gc_call_finalizer_at_exit();
-
-/* signal.c */
-RBIMPL_ATTR_DEPRECATED_INTERNAL(2.7) void rb_trap_exit();
-
-/* struct.c */
-RBIMPL_ATTR_DEPRECATED_INTERNAL(2.4) void rb_struct_ptr();
-
-/* thread.c */
-RBIMPL_ATTR_DEPRECATED_INTERNAL(2.7) void rb_clear_trace_func();
-
-/* variable.c */
-RBIMPL_ATTR_DEPRECATED_INTERNAL(2.7) void rb_generic_ivar_table();
-RBIMPL_ATTR_DEPRECATED_INTERNAL(2.6) NORETURN(VALUE rb_mod_const_missing(VALUE, VALUE));
+RBIMPL_ATTR_DEPRECATED_INTERNAL_ONLY() void rb_clear_constant_cache(void);
/* from version.c */
#if defined(RUBY_SHOW_COPYRIGHT_TO_DIE) && !!(RUBY_SHOW_COPYRIGHT_TO_DIE+0)
-/* for source code backward compatibility */
-RBIMPL_ATTR_DEPRECATED_SINCE(2.4)
-static inline int
-ruby_show_copyright_to_die(int exitcode)
-{
- ruby_show_copyright();
- return exitcode;
-}
-#define ruby_show_copyright() /* defer EXIT_SUCCESS */ \
- (exit(ruby_show_copyright_to_die(EXIT_SUCCESS)))
+# error RUBY_SHOW_COPYRIGHT_TO_DIE is deprecated
#endif
#endif /* RUBY_RUBY_BACKWARD_H */
diff --git a/include/ruby/backward/2/assume.h b/include/ruby/backward/2/assume.h
index 265421df79..d148710127 100644
--- a/include/ruby/backward/2/assume.h
+++ b/include/ruby/backward/2/assume.h
@@ -24,8 +24,6 @@
#include "ruby/internal/assume.h"
#include "ruby/internal/has/builtin.h"
-#undef ASSUME /* Kill config.h definition */
-#undef UNREACHABLE /* Kill config.h definition */
#define ASSUME RBIMPL_ASSUME /**< @old{RBIMPL_ASSUME} */
#define UNREACHABLE RBIMPL_UNREACHABLE() /**< @old{RBIMPL_UNREACHABLE} */
#define UNREACHABLE_RETURN RBIMPL_UNREACHABLE_RETURN /**< @old{RBIMPL_UNREACHABLE_RETURN} */
diff --git a/include/ruby/debug.h b/include/ruby/debug.h
index c88da9c43d..f95acdb17e 100644
--- a/include/ruby/debug.h
+++ b/include/ruby/debug.h
@@ -207,6 +207,17 @@ typedef VALUE (*rb_debug_inspector_func_t)(const rb_debug_inspector_t *dc, void
VALUE rb_debug_inspector_open(rb_debug_inspector_func_t func, void *data);
/**
+ * Queries the backtrace object of the context. This is as if you call
+ * `caller_locations` at the point of debugger.
+ *
+ * @param[in] dc A debug context.
+ * @return An array of `Thread::Backtrace::Location` which represents the
+ * current point of execution at `dc`.
+
+ */
+VALUE rb_debug_inspector_backtrace_locations(const rb_debug_inspector_t *dc);
+
+/**
* Queries the current receiver of the passed context's upper frame.
*
* @param[in] dc A debug context.
@@ -250,15 +261,27 @@ VALUE rb_debug_inspector_frame_binding_get(const rb_debug_inspector_t *dc, long
VALUE rb_debug_inspector_frame_iseq_get(const rb_debug_inspector_t *dc, long index);
/**
- * Queries the backtrace object of the context. This is as if you call
- * `caller_locations` at the point of debugger.
+ * Queries the depth of the passed context's upper frame.
*
- * @param[in] dc A debug context.
- * @return An array of `Thread::Backtrace::Location` which represents the
- * current point of execution at `dc`.
+ * Note that the depth is not same as the frame index because debug_inspector
+ * skips some special frames but the depth counts all frames.
+ *
+ * @param[in] dc A debug context.
+ * @param[in] index Index of the frame from top to bottom.
+ * @exception rb_eArgError `index` out of range.
+ * @retval The depth at `index`-th frame in Integer.
+ */
+VALUE rb_debug_inspector_frame_depth(const rb_debug_inspector_t *dc, long index);
+
+// A macro to recognize `rb_debug_inspector_frame_depth()` is available or not
+#define RB_DEBUG_INSPECTOR_FRAME_DEPTH(dc, index) rb_debug_inspector_frame_depth(dc, index)
+/**
+ * Return current frmae depth.
+ *
+ * @retval The depth of the current frame in Integer.
*/
-VALUE rb_debug_inspector_backtrace_locations(const rb_debug_inspector_t *dc);
+VALUE rb_debug_inspector_current_depth(void);
/** @} */
diff --git a/include/ruby/fiber/scheduler.h b/include/ruby/fiber/scheduler.h
index 093b936475..250b39b6df 100644
--- a/include/ruby/fiber/scheduler.h
+++ b/include/ruby/fiber/scheduler.h
@@ -11,18 +11,74 @@
*/
#include "ruby/internal/config.h"
+#include <errno.h>
+
#ifdef STDC_HEADERS
#include <stddef.h> /* size_t */
#endif
#include "ruby/ruby.h"
#include "ruby/internal/dllexport.h"
+#include "ruby/internal/arithmetic.h"
RBIMPL_SYMBOL_EXPORT_BEGIN()
+#define RUBY_FIBER_SCHEDULER_VERSION 2
+
struct timeval;
/**
+ * Wrap a `ssize_t` and `int errno` into a single `VALUE`. This interface should
+ * be used to safely capture results from system calls like `read` and `write`.
+ *
+ * You should use `rb_fiber_scheduler_io_result_apply` to unpack the result of
+ * this value and update `int errno`.
+ *
+ * You should not directly try to interpret the result value as it is considered
+ * an opaque representation. However, the general representation is an integer
+ * in the range of `[-int errno, size_t size]`. Linux generally restricts the
+ * result of system calls like `read` and `write` to `<= 2^31` which means this
+ * will typically fit within a single FIXNUM.
+ *
+ * @param[in] result The result of the system call.
+ * @param[in] error The value of `errno`.
+ * @return A `VALUE` which contains the result and/or errno.
+ */
+static inline VALUE
+rb_fiber_scheduler_io_result(ssize_t result, int error)
+{
+ if (result == -1) {
+ return RB_INT2NUM(-error);
+ }
+ else {
+ return RB_SIZE2NUM(result);
+ }
+}
+
+/**
+ * Apply an io result to the local thread, returning the value of the original
+ * system call that created it and updating `int errno`.
+ *
+ * You should not directly try to interpret the result value as it is considered
+ * an opaque representation.
+ *
+ * @param[in] result The `VALUE` which contains an errno and/or result size.
+ * @post Updates `int errno` with the value if negative.
+ * @return The original result of the system call.
+ */
+static inline ssize_t
+rb_fiber_scheduler_io_result_apply(VALUE result)
+{
+ if (RB_FIXNUM_P(result) && RB_NUM2INT(result) < 0) {
+ errno = -RB_NUM2INT(result);
+ return -1;
+ }
+ else {
+ return RB_NUM2SIZE(result);
+ }
+}
+
+/**
* Queries the current scheduler of the current thread that is calling this
* function.
*
@@ -90,7 +146,7 @@ VALUE rb_fiber_scheduler_make_timeout(struct timeval *timeout);
VALUE rb_fiber_scheduler_close(VALUE scheduler);
/**
- * Nonblocking `sleep`. Depending on scheduler implementation, this for
+ * Non-blocking `sleep`. Depending on scheduler implementation, this for
* instance switches to another fiber etc.
*
* @param[in] scheduler Target scheduler.
@@ -118,7 +174,7 @@ int rb_fiber_scheduler_supports_process_wait(VALUE scheduler);
#endif
/**
- * Nonblocking `waitpid`. Depending on scheduler implementation, this for
+ * Non-blocking `waitpid`. Depending on scheduler implementation, this for
* instance switches to another fiber etc.
*
* @param[in] scheduler Target scheduler.
@@ -129,7 +185,7 @@ int rb_fiber_scheduler_supports_process_wait(VALUE scheduler);
VALUE rb_fiber_scheduler_process_wait(VALUE scheduler, rb_pid_t pid, int flags);
/**
- * Nonblocking wait for the passed "blocker", which is for instance
+ * Non-blocking wait for the passed "blocker", which is for instance
* `Thread.join` or `Mutex.lock`. Depending on scheduler implementation, this
* for instance switches to another fiber etc.
*
@@ -151,11 +207,11 @@ VALUE rb_fiber_scheduler_block(VALUE scheduler, VALUE blocker, VALUE timeout);
VALUE rb_fiber_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber);
/**
- * Nonblocking version of rb_io_wait(). Depending on scheduler implementation,
- * this for instance switches to another fiber etc.
+ * Non-blocking version of rb_io_wait(). Depending on scheduler
+ * implementation, this for instance switches to another fiber etc.
*
* The "events" here is a Ruby level integer, which is an OR-ed value of
- * `IO::READABLE`, `IO::WRITable`, and `IO::PRIORITY`.
+ * `IO::READABLE`, `IO::WRITABLE`, and `IO::PRIORITY`.
*
* @param[in] scheduler Target scheduler.
* @param[in] io An io object to wait.
@@ -166,7 +222,7 @@ VALUE rb_fiber_scheduler_unblock(VALUE scheduler, VALUE blocker, VALUE fiber);
VALUE rb_fiber_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE timeout);
/**
- * Nonblocking wait until the passed IO is ready for reading. This is a
+ * Non-blocking wait until the passed IO is ready for reading. This is a
* special case of rb_fiber_scheduler_io_wait(), where the interest is
* `IO::READABLE` and timeout is never.
*
@@ -177,7 +233,7 @@ VALUE rb_fiber_scheduler_io_wait(VALUE scheduler, VALUE io, VALUE events, VALUE
VALUE rb_fiber_scheduler_io_wait_readable(VALUE scheduler, VALUE io);
/**
- * Nonblocking wait until the passed IO is ready for writing. This is a
+ * Non-blocking wait until the passed IO is ready for writing. This is a
* special case of rb_fiber_scheduler_io_wait(), where the interest is
* `IO::WRITABLE` and timeout is never.
*
@@ -188,33 +244,117 @@ VALUE rb_fiber_scheduler_io_wait_readable(VALUE scheduler, VALUE io);
VALUE rb_fiber_scheduler_io_wait_writable(VALUE scheduler, VALUE io);
/**
- * Nonblocking read from the passed IO.
+ * Non-blocking version of `IO.select`.
+ *
+ * It's possible that this will be emulated using a thread, so you should not
+ * rely on it for high performance.
+ *
+ * @param[in] scheduler Target scheduler.
+ * @param[in] readables An array of readable objects.
+ * @param[in] writables An array of writable objects.
+ * @param[in] exceptables An array of objects that might encounter exceptional conditions.
+ * @param[in] timeout Numeric timeout or nil.
+ * @return What `scheduler.io_select` returns, normally a 3-tuple of arrays of ready objects.
+ */
+VALUE rb_fiber_scheduler_io_select(VALUE scheduler, VALUE readables, VALUE writables, VALUE exceptables, VALUE timeout);
+
+/**
+ * Non-blocking version of `IO.select`, `argv` variant.
+ */
+VALUE rb_fiber_scheduler_io_selectv(VALUE scheduler, int argc, VALUE *argv);
+
+/**
+ * Non-blocking read from the passed IO.
*
* @param[in] scheduler Target scheduler.
* @param[out] io An io object to read from.
* @param[out] buffer Return buffer.
- * @param[in] offset Offset inside of `buffer`.
* @param[in] length Requested number of bytes to read.
+ * @param[in] offset The offset in the buffer to read to.
+ * @retval RUBY_Qundef `scheduler` doesn't have `#io_read`.
+ * @return otherwise What `scheduler.io_read` returns `[-errno, size]`.
+ */
+VALUE rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t length, size_t offset);
+
+/**
+ * Non-blocking write to the passed IO.
+ *
+ * @param[in] scheduler Target scheduler.
+ * @param[out] io An io object to write to.
+ * @param[in] buffer What to write.
+ * @param[in] length Number of bytes to write.
+ * @param[in] offset The offset in the buffer to write from.
+ * @retval RUBY_Qundef `scheduler` doesn't have `#io_write`.
+ * @return otherwise What `scheduler.io_write` returns `[-errno, size]`.
+ */
+VALUE rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t length, size_t offset);
+
+/**
+ * Non-blocking read from the passed IO at the specified offset.
+ *
+ * @param[in] scheduler Target scheduler.
+ * @param[out] io An io object to read from.
+ * @param[in] from The offset in the given IO to read the data from.
+ * @param[out] buffer The buffer to read the data to.
+ * @param[in] length Requested number of bytes to read.
+ * @param[in] offset The offset in the buffer to read to.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_read`.
* @return otherwise What `scheduler.io_read` returns.
*/
-VALUE rb_fiber_scheduler_io_read(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length);
+VALUE rb_fiber_scheduler_io_pread(VALUE scheduler, VALUE io, rb_off_t from, VALUE buffer, size_t length, size_t offset);
/**
- * Nonblocking write to the passed IO.
+ * Non-blocking write to the passed IO at the specified offset.
+ *
+ * @param[in] scheduler Target scheduler.
+ * @param[out] io An io object to write to.
+ * @param[in] from The offset in the given IO to write the data to.
+ * @param[in] buffer The buffer to write the data from.
+ * @param[in] length Number of bytes to write.
+ * @param[in] offset The offset in the buffer to write from.
+ * @retval RUBY_Qundef `scheduler` doesn't have `#io_write`.
+ * @return otherwise What `scheduler.io_write` returns.
+ */
+VALUE rb_fiber_scheduler_io_pwrite(VALUE scheduler, VALUE io, rb_off_t from, VALUE buffer, size_t length, size_t offset);
+
+/**
+ * Non-blocking read from the passed IO using a native buffer.
+ *
+ * @param[in] scheduler Target scheduler.
+ * @param[out] io An io object to read from.
+ * @param[out] buffer Return buffer.
+ * @param[in] size Size of the return buffer.
+ * @param[in] length Requested number of bytes to read.
+ * @retval RUBY_Qundef `scheduler` doesn't have `#io_read`.
+ * @return otherwise What `scheduler.io_read` returns.
+ */
+VALUE rb_fiber_scheduler_io_read_memory(VALUE scheduler, VALUE io, void *buffer, size_t size, size_t length);
+
+/**
+ * Non-blocking write to the passed IO using a native buffer.
*
* @param[in] scheduler Target scheduler.
* @param[out] io An io object to write to.
* @param[in] buffer What to write.
- * @param[in] offset Offset inside of `buffer`.
+ * @param[in] size Size of the buffer.
* @param[in] length Number of bytes to write.
* @retval RUBY_Qundef `scheduler` doesn't have `#io_write`.
* @return otherwise What `scheduler.io_write` returns.
*/
-VALUE rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_t offset, size_t length);
+VALUE rb_fiber_scheduler_io_write_memory(VALUE scheduler, VALUE io, const void *buffer, size_t size, size_t length);
+
+/**
+ * Non-blocking close the given IO.
+ *
+ * @param[in] scheduler Target scheduler.
+ * @param[in] io An io object to close.
+ * @retval RUBY_Qundef `scheduler` doesn't have `#io_close`.
+ * @return otherwise What `scheduler.io_close` returns.
+ */
+VALUE rb_fiber_scheduler_io_close(VALUE scheduler, VALUE io);
/**
- * Nonblocking DNS lookup.
+ * Non-blocking DNS lookup.
*
* @param[in] scheduler Target scheduler.
* @param[in] hostname A host name to query.
@@ -223,6 +363,12 @@ VALUE rb_fiber_scheduler_io_write(VALUE scheduler, VALUE io, VALUE buffer, size_
*/
VALUE rb_fiber_scheduler_address_resolve(VALUE scheduler, VALUE hostname);
+/**
+ * Create and schedule a non-blocking fiber.
+ *
+ */
+VALUE rb_fiber_scheduler_fiber(VALUE scheduler, int argc, VALUE *argv, int kw_splat);
+
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_FIBER_SCHEDULER_H */
diff --git a/include/ruby/internal/abi.h b/include/ruby/internal/abi.h
new file mode 100644
index 0000000000..44111a0055
--- /dev/null
+++ b/include/ruby/internal/abi.h
@@ -0,0 +1,58 @@
+#ifndef RUBY_ABI_H
+#define RUBY_ABI_H
+
+#ifdef RUBY_ABI_VERSION /* should match the definition in config.h */
+
+/* This number represents Ruby's ABI version.
+ *
+ * In development Ruby, it should be bumped every time an ABI incompatible
+ * change is introduced. This will force other developers to rebuild extension
+ * gems.
+ *
+ * The following cases are considered as ABI incompatible changes:
+ * - Changing any data structures.
+ * - Changing macros or inline functions causing a change in behavior.
+ * - Deprecating or removing function declarations.
+ *
+ * The following cases are NOT considered as ABI incompatible changes:
+ * - Any changes that does not involve the header files in the `include`
+ * directory.
+ * - Adding macros, inline functions, or function declarations.
+ * - Backwards compatible refactors.
+ * - Editing comments.
+ *
+ * In released versions of Ruby, this number is not defined since teeny
+ * versions of Ruby should guarantee ABI compatibility.
+ */
+#define RUBY_ABI_VERSION 3
+
+/* Windows does not support weak symbols so ruby_abi_version will not exist
+ * in the shared library. */
+#if defined(HAVE_FUNC_WEAK) && !defined(_WIN32) && !defined(__MINGW32__) && !defined(__CYGWIN__)
+# define RUBY_DLN_CHECK_ABI
+#endif
+#endif /* RUBY_ABI_VERSION */
+
+#ifdef RUBY_DLN_CHECK_ABI
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+RUBY_FUNC_EXPORTED unsigned long long __attribute__((weak))
+ruby_abi_version(void)
+{
+# ifdef RUBY_ABI_VERSION
+ return RUBY_ABI_VERSION;
+# else
+ return 0;
+# endif
+}
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+#endif
diff --git a/include/ruby/internal/anyargs.h b/include/ruby/internal/anyargs.h
index 9d8d16fdab..e3e1b6166d 100644
--- a/include/ruby/internal/anyargs.h
+++ b/include/ruby/internal/anyargs.h
@@ -239,15 +239,16 @@
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_13(n) RBIMPL_ANYARGS_DISPATCH((n) == 13, rb_define_method_13, RBIMPL_ANYARGS_DISPATCH_rb_define_method_12(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_14(n) RBIMPL_ANYARGS_DISPATCH((n) == 14, rb_define_method_14, RBIMPL_ANYARGS_DISPATCH_rb_define_method_13(n))
# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_15(n) RBIMPL_ANYARGS_DISPATCH((n) == 15, rb_define_method_15, RBIMPL_ANYARGS_DISPATCH_rb_define_method_14(n))
-# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_singleton_method_m3, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_15(n))
-# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_protected_method_m3, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_15(n))
-# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_private_method_m3, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_15(n))
-# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_module_function_m3, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_15(n))
-# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_global_function_m3, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_15(n))
-# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_method_id_m3, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_15(n))
-# define RBIMPL_ANYARGS_DISPATCH_rb_define_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_method_m3, RBIMPL_ANYARGS_DISPATCH_rb_define_method_15(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_singleton_method_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_singleton_method_15(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_protected_method_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_protected_method_15(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_private_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_private_method_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_private_method_15(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_module_function(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_module_function_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_module_function_15(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_global_function(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_global_function_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_global_function_15(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method_id(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_method_id_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_method_id_15(n))
+# define RBIMPL_ANYARGS_DISPATCH_rb_define_method(n, f) RBIMPL_ANYARGS_DISPATCH(RBIMPL_CFUNC_IS_rb_f_notimplement(f), rb_define_method_notimpl, RBIMPL_ANYARGS_DISPATCH_rb_define_method_15(n))
# define RBIMPL_ANYARGS_ATTRSET(sym) RBIMPL_ATTR_MAYBE_UNUSED() RBIMPL_ATTR_NONNULL(()) RBIMPL_ATTR_WEAKREF(sym)
# define RBIMPL_ANYARGS_DECL(sym, ...) \
+RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _notimpl(__VA_ARGS__, VALUE(*)(int, const VALUE *, VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m3(__VA_ARGS__, VALUE(*)(ANYARGS), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m2(__VA_ARGS__, VALUE(*)(VALUE, VALUE), int); \
RBIMPL_ANYARGS_ATTRSET(sym) static void sym ## _m1(__VA_ARGS__, VALUE(*)(int, union { VALUE *x; const VALUE *y; } __attribute__((__transparent_union__)), VALUE), int); \
diff --git a/include/ruby/internal/arithmetic.h b/include/ruby/internal/arithmetic.h
index 3f7840c384..7ebb4a86f1 100644
--- a/include/ruby/internal/arithmetic.h
+++ b/include/ruby/internal/arithmetic.h
@@ -18,7 +18,8 @@
* Do not expect for instance `__VA_ARGS__` is always available.
* We assume C99 for ruby itself but we don't assume languages of
* extension libraries. They could be written in C++98.
- * @brief Conversion between C's arithmtic types and Ruby's numeric types.
+ * @brief Conversion between C's arithmetic types and Ruby's numeric
+ * types.
*/
#include "ruby/internal/arithmetic/char.h"
#include "ruby/internal/arithmetic/double.h"
diff --git a/include/ruby/internal/arithmetic/long.h b/include/ruby/internal/arithmetic/long.h
index 792f7be179..6b8fd8ffc3 100644
--- a/include/ruby/internal/arithmetic/long.h
+++ b/include/ruby/internal/arithmetic/long.h
@@ -115,7 +115,7 @@ RB_INT2FIX(long i)
/* :NOTE: VALUE can be wider than long. As j being unsigned, 2j+1 is fully
* defined. Also it can be compiled into a single LEA instruction. */
const unsigned long j = i;
- const unsigned long k = 2 * j + RUBY_FIXNUM_FLAG;
+ const unsigned long k = (j << 1) + RUBY_FIXNUM_FLAG;
const long l = k;
const SIGNED_VALUE m = l; /* Sign extend */
const VALUE n = m;
diff --git a/include/ruby/internal/assume.h b/include/ruby/internal/assume.h
index 65d34d4ac8..4c183e8af9 100644
--- a/include/ruby/internal/assume.h
+++ b/include/ruby/internal/assume.h
@@ -32,10 +32,7 @@
#include "ruby/internal/warning_push.h"
/** @cond INTERNAL_MACRO */
-#if RBIMPL_COMPILER_SINCE(MSVC, 13, 10, 0)
-# define RBIMPL_HAVE___ASSUME
-
-#elif RBIMPL_COMPILER_SINCE(Intel, 13, 0, 0)
+#if defined(HAVE___ASSUME)
# define RBIMPL_HAVE___ASSUME
#endif
/** @endcond */
diff --git a/include/ruby/internal/attr/nodiscard.h b/include/ruby/internal/attr/nodiscard.h
index 087192a7a8..c3ae118942 100644
--- a/include/ruby/internal/attr/nodiscard.h
+++ b/include/ruby/internal/attr/nodiscard.h
@@ -26,7 +26,7 @@
/**
* Wraps (or simulates) `[[nodiscard]]`. In C++ (at least since C++20) a
- * nodiscard attribute can have a message why the result shall not be ignoed.
+ * nodiscard attribute can have a message why the result shall not be ignored.
* However GCC attribute and SAL annotation cannot take them.
*/
#if RBIMPL_HAS_CPP_ATTRIBUTE(nodiscard)
diff --git a/include/ruby/internal/config.h b/include/ruby/internal/config.h
index b6134c6165..aa63376d7c 100644
--- a/include/ruby/internal/config.h
+++ b/include/ruby/internal/config.h
@@ -113,6 +113,8 @@
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__powerpc64__)
# define UNALIGNED_WORD_ACCESS 1
+#elif defined(__POWERPC__) // __POWERPC__ is defined for ppc and ppc64 on Darwin
+# define UNALIGNED_WORD_ACCESS 1
#elif defined(__aarch64__)
# define UNALIGNED_WORD_ACCESS 1
#elif defined(__mc68020__)
@@ -146,4 +148,8 @@
# undef RBIMPL_TEST3
#endif /* HAVE_VA_ARGS_MACRO */
+#ifndef USE_RVARGC
+# define USE_RVARGC 1
+#endif
+
#endif /* RBIMPL_CONFIG_H */
diff --git a/include/ruby/internal/core/rarray.h b/include/ruby/internal/core/rarray.h
index 9f1d0509ea..c3bb40be25 100644
--- a/include/ruby/internal/core/rarray.h
+++ b/include/ruby/internal/core/rarray.h
@@ -130,7 +130,13 @@ enum ruby_rarray_flags {
* 3rd parties must not be aware that there even is more than one way to
* store array elements. It was a bad idea to expose this to them.
*/
+#if USE_RVARGC
+ RARRAY_EMBED_LEN_MASK = RUBY_FL_USER9 | RUBY_FL_USER8 | RUBY_FL_USER7 | RUBY_FL_USER6 |
+ RUBY_FL_USER5 | RUBY_FL_USER4 | RUBY_FL_USER3
+#else
RARRAY_EMBED_LEN_MASK = RUBY_FL_USER4 | RUBY_FL_USER3
+#endif
+
#if USE_TRANSIENT_HEAP
,
@@ -156,10 +162,14 @@ enum ruby_rarray_flags {
*/
enum ruby_rarray_consts {
/** Where ::RARRAY_EMBED_LEN_MASK resides. */
- RARRAY_EMBED_LEN_SHIFT = RUBY_FL_USHIFT + 3,
+ RARRAY_EMBED_LEN_SHIFT = RUBY_FL_USHIFT + 3
+
+#if !USE_RVARGC
+ ,
/** Max possible number elements that can be embedded. */
RARRAY_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(VALUE)
+#endif
};
/** Ruby's array. */
@@ -218,7 +228,16 @@ struct RArray {
* to store its elements. In this case the length is encoded into the
* flags.
*/
+#if USE_RVARGC
+ /* 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];
+#else
const VALUE ary[RARRAY_EMBED_LEN_MAX];
+#endif
} as;
};
@@ -469,14 +488,6 @@ rb_array_ptr_use_end(VALUE a,
* This is an implementation detail of #RARRAY_PTR_USE. People do not use it
* directly.
*/
-#define RARRAY_PTR_USE_START(a) rb_array_ptr_use_start(a, 0)
-
-/**
- * @private
- *
- * This is an implementation detail of #RARRAY_PTR_USE. People do not use it
- * directly.
- */
#define RARRAY_PTR_USE_END(a) rb_array_ptr_use_end(a, 0)
/**
@@ -508,22 +519,6 @@ rb_array_ptr_use_end(VALUE a,
RBIMPL_RARRAY_STMT(0, ary, ptr_name, expr)
/**
- * @private
- *
- * This is an implementation detail of #RARRAY_PTR_USE_TRANSIENT. People do
- * not use it directly.
- */
-#define RARRAY_PTR_USE_START_TRANSIENT(a) rb_array_ptr_use_start(a, 1)
-
-/**
- * @private
- *
- * This is an implementation detail of #RARRAY_PTR_USE_TRANSIENT. People do
- * not use it directly.
- */
-#define RARRAY_PTR_USE_END_TRANSIENT(a) rb_array_ptr_use_end(a, 1)
-
-/**
* Identical to #RARRAY_PTR_USE, except the pointer can be a transient one.
*
* @param ary An object of ::RArray.
diff --git a/include/ruby/internal/core/rclass.h b/include/ruby/internal/core/rclass.h
index 13a33a28bd..b0b6bfc80c 100644
--- a/include/ruby/internal/core/rclass.h
+++ b/include/ruby/internal/core/rclass.h
@@ -26,9 +26,7 @@
#include "ruby/internal/cast.h"
/** @cond INTERNAL_MACRO */
-#define RMODULE_IS_OVERLAID RMODULE_IS_OVERLAID
#define RMODULE_IS_REFINEMENT RMODULE_IS_REFINEMENT
-#define RMODULE_INCLUDED_INTO_REFINEMENT RMODULE_INCLUDED_INTO_REFINEMENT
/** @endcond */
/**
@@ -55,57 +53,12 @@
* Why is it here, given RClass itself is not?
*/
enum ruby_rmodule_flags {
-
- /**
- * This flag has something to do with refinements... I guess? It is set on
- * occasions for modules that are refined by refinements, but it seems
- * ... nobody cares about such things? Not sure but this flag could
- * perhaps be a write-only information.
- */
- RMODULE_IS_OVERLAID = RUBY_FL_USER2,
-
/**
* This flag has something to do with refinements. A module created using
* rb_mod_refine() has this flag set. This is the bit which controls
* difference between normal inclusion versus refinements.
*/
- RMODULE_IS_REFINEMENT = RUBY_FL_USER3,
-
- /**
- * This flag has something to do with refinements. This is set when a
- * (non-refinement) module is included into another module, which is a
- * refinement. This amends the way `super` searches for a super method.
- *
- * ```ruby
- * class Foo
- * def foo
- * "Foo"
- * end
- * end
- *
- * module Bar
- * def foo
- * "[#{super}]" # this
- * end
- * end
- *
- * module Baz
- * refine Foo do
- * include Bar
- * def foo
- * "<#{super}>"
- * end
- * end
- * end
- *
- * using Baz
- * Foo.new.foo # => "[<Foo>]"
- * ```
- *
- * The `super` marked with "this" comment shall look for overlaid
- * `Foo#foo`, which is not the ordinal method lookup direction.
- */
- RMODULE_INCLUDED_INTO_REFINEMENT = RUBY_FL_USER4
+ RMODULE_IS_REFINEMENT = RUBY_FL_USER3
};
struct RClass; /* Opaque, declared here for RCLASS() macro. */
diff --git a/include/ruby/internal/core/rdata.h b/include/ruby/internal/core/rdata.h
index f6656b6546..43ab3c01e7 100644
--- a/include/ruby/internal/core/rdata.h
+++ b/include/ruby/internal/core/rdata.h
@@ -369,30 +369,6 @@ rb_data_object_alloc(VALUE klass, void *data, RUBY_DATA_FUNC dmark, RUBY_DATA_FU
return rb_data_object_wrap(klass, data, dmark, dfree);
}
-RBIMPL_ATTR_DEPRECATED(("by: rb_cObject. Will be removed in 3.1."))
-RBIMPL_ATTR_PURE()
-/**
- * @private
- *
- * @deprecated There once was a variable called rb_cData, which no longer
- * exists today. This function is a function because we want
- * warnings for the usages.
- */
-static inline VALUE
-rb_cData(void)
-{
- return rb_cObject;
-}
-
-/**
- * @private
- *
- * @deprecated This macro once was a thing in the old days, but makes no sense
- * any longer today. Exists here for backwards compatibility
- * only. You can safely forget about it.
- */
-#define rb_cData rb_cData()
-
/** @cond INTERNAL_MACRO */
#define rb_data_object_wrap_0 rb_data_object_wrap
#define rb_data_object_wrap_1 rb_data_object_wrap_warning
diff --git a/include/ruby/internal/core/robject.h b/include/ruby/internal/core/robject.h
index f2028063a6..b1c2e1b0a9 100644
--- a/include/ruby/internal/core/robject.h
+++ b/include/ruby/internal/core/robject.h
@@ -37,16 +37,15 @@
/**
* Convenient casting macro.
*
- * @param obj An object, which is in fact an ::RRegexp.
- * @return The passed object casted to ::RRegexp.
+ * @param obj An object, which is in fact an ::RObject.
+ * @return The passed object casted to ::RObject.
*/
#define ROBJECT(obj) RBIMPL_CAST((struct RObject *)(obj))
/** @cond INTERNAL_MACRO */
#define ROBJECT_EMBED_LEN_MAX ROBJECT_EMBED_LEN_MAX
#define ROBJECT_EMBED ROBJECT_EMBED
-#define ROBJECT_NUMIV ROBJECT_NUMIV
+#define ROBJECT_IV_CAPACITY ROBJECT_IV_CAPACITY
#define ROBJECT_IVPTR ROBJECT_IVPTR
-#define ROBJECT_IV_INDEX_TBL ROBJECT_IV_INDEX_TBL
/** @endcond */
/**
@@ -75,6 +74,7 @@ enum ruby_robject_flags {
ROBJECT_EMBED = RUBY_FL_USER1
};
+#if !USE_RVARGC
/**
* This is an enum because GDB wants it (rather than a macro). People need not
* bother.
@@ -83,6 +83,7 @@ enum ruby_robject_consts {
/** Max possible number of instance variables that can be embedded. */
ROBJECT_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(VALUE)
};
+#endif
struct st_table;
@@ -103,13 +104,6 @@ struct RObject {
* this pattern.
*/
struct {
-
- /**
- * Number of instance variables. This is per object; objects might
- * differ in this field even if they have the identical classes.
- */
- uint32_t numiv;
-
/** Pointer to a C array that holds instance variables. */
VALUE *ivptr;
@@ -121,38 +115,35 @@ struct RObject {
*
* This is a shortcut for `RCLASS_IV_INDEX_TBL(rb_obj_class(obj))`.
*/
- struct st_table *iv_index_tbl;
+ struct rb_id_table *iv_index_tbl;
} heap;
- /**
- * Embedded instance variables. When an object is small enough, it
+#if USE_RVARGC
+ /* Embedded instance variables. When an object is small enough, it
* uses this area to store the instance variables.
+ *
+ * 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
*/
+ VALUE ary[1];
+#else
+ /**
+ * Embedded instance variables. When an object is small enough, it
+ * uses this area to store the instance variables.
+ */
VALUE ary[ROBJECT_EMBED_LEN_MAX];
+#endif
} as;
};
-RBIMPL_ATTR_PURE_UNLESS_DEBUG()
-RBIMPL_ATTR_ARTIFICIAL()
-/**
- * Queries the number of instance variables.
- *
- * @param[in] obj Object in question.
- * @return Its number of instance variables.
- * @pre `obj` must be an instance of ::RObject.
- */
-static inline uint32_t
-ROBJECT_NUMIV(VALUE obj)
-{
- RBIMPL_ASSERT_TYPE(obj, RUBY_T_OBJECT);
-
- if (RB_FL_ANY_RAW(obj, ROBJECT_EMBED)) {
- return ROBJECT_EMBED_LEN_MAX;
- }
- else {
- return ROBJECT(obj)->as.heap.numiv;
- }
-}
+/* Offsets for YJIT */
+#ifndef __cplusplus
+static const int32_t ROBJECT_OFFSET_AS_HEAP_IVPTR = offsetof(struct RObject, as.heap.ivptr);
+static const int32_t ROBJECT_OFFSET_AS_HEAP_IV_INDEX_TBL = offsetof(struct RObject, as.heap.iv_index_tbl);
+static const int32_t ROBJECT_OFFSET_AS_ARY = offsetof(struct RObject, as.ary);
+#endif
RBIMPL_ATTR_PURE_UNLESS_DEBUG()
RBIMPL_ATTR_ARTIFICIAL()
diff --git a/include/ruby/internal/core/rstring.h b/include/ruby/internal/core/rstring.h
index d16a57b1c4..e394ab7dca 100644
--- a/include/ruby/internal/core/rstring.h
+++ b/include/ruby/internal/core/rstring.h
@@ -42,9 +42,11 @@
/** @cond INTERNAL_MACRO */
#define RSTRING_NOEMBED RSTRING_NOEMBED
+#if !USE_RVARGC
#define RSTRING_EMBED_LEN_MASK RSTRING_EMBED_LEN_MASK
#define RSTRING_EMBED_LEN_SHIFT RSTRING_EMBED_LEN_SHIFT
#define RSTRING_EMBED_LEN_MAX RSTRING_EMBED_LEN_MAX
+#endif
#define RSTRING_FSTR RSTRING_FSTR
#define RSTRING_EMBED_LEN RSTRING_EMBED_LEN
#define RSTRING_LEN RSTRING_LEN
@@ -160,6 +162,7 @@ enum ruby_rstring_flags {
*/
RSTRING_NOEMBED = RUBY_FL_USER1,
+#if !USE_RVARGC
/**
* When a string employs embedded strategy (see ::RSTRING_NOEMBED), these
* bits are used to store the number of bytes actually filled into
@@ -172,6 +175,7 @@ enum ruby_rstring_flags {
*/
RSTRING_EMBED_LEN_MASK = RUBY_FL_USER2 | RUBY_FL_USER3 | RUBY_FL_USER4 |
RUBY_FL_USER5 | RUBY_FL_USER6,
+#endif
/* Actually, string encodings are also encoded into the flags, using
* remaining bits.*/
@@ -198,6 +202,7 @@ enum ruby_rstring_flags {
RSTRING_FSTR = RUBY_FL_USER17
};
+#if !USE_RVARGC
/**
* This is an enum because GDB wants it (rather than a macro). People need not
* bother.
@@ -209,6 +214,7 @@ enum ruby_rstring_consts {
/** Max possible number of characters that can be embedded. */
RSTRING_EMBED_LEN_MAX = RBIMPL_EMBED_LEN_MAX_OF(char) - 1
};
+#endif
/**
* Ruby's String. A string in ruby conceptually has these information:
@@ -271,14 +277,27 @@ struct RString {
} aux;
} heap;
- /**
- * Embedded contents. When a string is short enough, it uses this area
- * to store the contents themselves. This was impractical in the 20th
- * century, but these days 64 bit machines can typically hold 48 bytes
- * here. Could be sufficiently large. In this case the length is
- * encoded into the flags.
- */
- char ary[RSTRING_EMBED_LEN_MAX + 1];
+ /** Embedded contents. */
+ struct {
+#if USE_RVARGC
+ long len;
+ /* 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
+ */
+ char ary[1];
+#else
+ /**
+ * When a string is short enough, it uses this area to store the
+ * contents themselves. This was impractical in the 20th century,
+ * but these days 64 bit machines can typically hold 24 bytes here.
+ * Could be sufficiently large. In this case the length is encoded
+ * into the flags.
+ */
+ char ary[RSTRING_EMBED_LEN_MAX + 1];
+#endif
+ } embed;
} as;
};
@@ -406,10 +425,15 @@ RSTRING_EMBED_LEN(VALUE str)
RBIMPL_ASSERT_TYPE(str, RUBY_T_STRING);
RBIMPL_ASSERT_OR_ASSUME(! RB_FL_ANY_RAW(str, RSTRING_NOEMBED));
+#if USE_RVARGC
+ long f = RSTRING(str)->as.embed.len;
+ return f;
+#else
VALUE f = RBASIC(str)->flags;
f &= RSTRING_EMBED_LEN_MASK;
f >>= RSTRING_EMBED_LEN_SHIFT;
return RBIMPL_CAST((long)f);
+#endif
}
RBIMPL_WARNING_PUSH()
@@ -440,7 +464,7 @@ rbimpl_rstring_getmem(VALUE str)
/* Expecting compilers to optimize this on-stack struct away. */
struct RString retval;
retval.as.heap.len = RSTRING_EMBED_LEN(str);
- retval.as.heap.ptr = RSTRING(str)->as.ary;
+ retval.as.heap.ptr = RSTRING(str)->as.embed.ary;
return retval;
}
}
diff --git a/include/ruby/internal/encoding/ctype.h b/include/ruby/internal/encoding/ctype.h
index 64aaf0a990..05c314aeb3 100644
--- a/include/ruby/internal/encoding/ctype.h
+++ b/include/ruby/internal/encoding/ctype.h
@@ -36,8 +36,8 @@ RBIMPL_SYMBOL_EXPORT_BEGIN()
* @param[in] p Pointer to a possibly-middle of a character.
* @param[in] end End of the string.
* @param[in] enc Encoding.
- * @retval 0 It isn't.
- * @retval otherwise It is.
+ * @retval false It isn't.
+ * @retval true It is.
*/
static inline bool
rb_enc_is_newline(const char *p, const char *e, rb_encoding *enc)
@@ -53,11 +53,11 @@ rb_enc_is_newline(const char *p, const char *e, rb_encoding *enc)
* encoding. The "character type" here is a set of macros defined in onigmo.h,
* like `ONIGENC_CTYPE_PUNCT`.
*
- * @param[in] c An `OnigCodePoint` value.
- * @param[in] t An `OnigCtype` value.
- * @param[in] enc A `rb_encoding*` value.
- * @retval 1 `c` is of `t` in `enc`.
- * @retval 0 Otherwise.
+ * @param[in] c An `OnigCodePoint` value.
+ * @param[in] t An `OnigCtype` value.
+ * @param[in] enc A `rb_encoding*` value.
+ * @retval true `c` is of `t` in `enc`.
+ * @retval false Otherwise.
*/
static inline bool
rb_enc_isctype(OnigCodePoint c, OnigCtype t, rb_encoding *enc)
@@ -68,10 +68,10 @@ rb_enc_isctype(OnigCodePoint c, OnigCtype t, rb_encoding *enc)
/**
* Identical to rb_isascii(), except it additionally takes an encoding.
*
- * @param[in] c A code point.
- * @param[in] enc An encoding.
- * @retval 0 `c` is out of range of ASCII character set in `enc`.
- * @retval 1 Otherwise.
+ * @param[in] c A code point.
+ * @param[in] enc An encoding.
+ * @retval false `c` is out of range of ASCII character set in `enc`.
+ * @retval true Otherwise.
*
* @internal
*
@@ -87,10 +87,10 @@ rb_enc_isascii(OnigCodePoint c, rb_encoding *enc)
/**
* Identical to rb_isalpha(), except it additionally takes an encoding.
*
- * @param[in] c A code point.
- * @param[in] enc An encoding.
- * @retval 1 `enc` classifies `c` as "ALPHA".
- * @retval 0 Otherwise.
+ * @param[in] c A code point.
+ * @param[in] enc An encoding.
+ * @retval true `enc` classifies `c` as "ALPHA".
+ * @retval false Otherwise.
*/
static inline bool
rb_enc_isalpha(OnigCodePoint c, rb_encoding *enc)
@@ -101,10 +101,10 @@ rb_enc_isalpha(OnigCodePoint c, rb_encoding *enc)
/**
* Identical to rb_islower(), except it additionally takes an encoding.
*
- * @param[in] c A code point.
- * @param[in] enc An encoding.
- * @retval 1 `enc` classifies `c` as "LOWER".
- * @retval 0 Otherwise.
+ * @param[in] c A code point.
+ * @param[in] enc An encoding.
+ * @retval true `enc` classifies `c` as "LOWER".
+ * @retval false Otherwise.
*/
static inline bool
rb_enc_islower(OnigCodePoint c, rb_encoding *enc)
@@ -115,10 +115,10 @@ rb_enc_islower(OnigCodePoint c, rb_encoding *enc)
/**
* Identical to rb_isupper(), except it additionally takes an encoding.
*
- * @param[in] c A code point.
- * @param[in] enc An encoding.
- * @retval 1 `enc` classifies `c` as "UPPER".
- * @retval 0 Otherwise.
+ * @param[in] c A code point.
+ * @param[in] enc An encoding.
+ * @retval true `enc` classifies `c` as "UPPER".
+ * @retval false Otherwise.
*/
static inline bool
rb_enc_isupper(OnigCodePoint c, rb_encoding *enc)
@@ -127,12 +127,26 @@ rb_enc_isupper(OnigCodePoint c, rb_encoding *enc)
}
/**
+ * Identical to rb_iscntrl(), except it additionally takes an encoding.
+ *
+ * @param[in] c A code point.
+ * @param[in] enc An encoding.
+ * @retval true `enc` classifies `c` as "CNTRL".
+ * @retval false Otherwise.
+ */
+static inline bool
+rb_enc_iscntrl(OnigCodePoint c, rb_encoding *enc)
+{
+ return ONIGENC_IS_CODE_CNTRL(enc, c);
+}
+
+/**
* Identical to rb_ispunct(), except it additionally takes an encoding.
*
- * @param[in] c A code point.
- * @param[in] enc An encoding.
- * @retval 1 `enc` classifies `c` as "PUNCT".
- * @retval 0 Otherwise.
+ * @param[in] c A code point.
+ * @param[in] enc An encoding.
+ * @retval true `enc` classifies `c` as "PUNCT".
+ * @retval false Otherwise.
*/
static inline bool
rb_enc_ispunct(OnigCodePoint c, rb_encoding *enc)
@@ -143,10 +157,10 @@ rb_enc_ispunct(OnigCodePoint c, rb_encoding *enc)
/**
* Identical to rb_isalnum(), except it additionally takes an encoding.
*
- * @param[in] c A code point.
- * @param[in] enc An encoding.
- * @retval 1 `enc` classifies `c` as "ANUM".
- * @retval 0 Otherwise.
+ * @param[in] c A code point.
+ * @param[in] enc An encoding.
+ * @retval true `enc` classifies `c` as "ANUM".
+ * @retval false Otherwise.
*/
static inline bool
rb_enc_isalnum(OnigCodePoint c, rb_encoding *enc)
@@ -157,10 +171,10 @@ rb_enc_isalnum(OnigCodePoint c, rb_encoding *enc)
/**
* Identical to rb_isprint(), except it additionally takes an encoding.
*
- * @param[in] c A code point.
- * @param[in] enc An encoding.
- * @retval 1 `enc` classifies `c` as "PRINT".
- * @retval 0 Otherwise.
+ * @param[in] c A code point.
+ * @param[in] enc An encoding.
+ * @retval true `enc` classifies `c` as "PRINT".
+ * @retval false Otherwise.
*/
static inline bool
rb_enc_isprint(OnigCodePoint c, rb_encoding *enc)
@@ -171,10 +185,10 @@ rb_enc_isprint(OnigCodePoint c, rb_encoding *enc)
/**
* Identical to rb_isspace(), except it additionally takes an encoding.
*
- * @param[in] c A code point.
- * @param[in] enc An encoding.
- * @retval 1 `enc` classifies `c` as "PRINT".
- * @retval 0 Otherwise.
+ * @param[in] c A code point.
+ * @param[in] enc An encoding.
+ * @retval true `enc` classifies `c` as "PRINT".
+ * @retval false Otherwise.
*/
static inline bool
rb_enc_isspace(OnigCodePoint c, rb_encoding *enc)
@@ -185,10 +199,10 @@ rb_enc_isspace(OnigCodePoint c, rb_encoding *enc)
/**
* Identical to rb_isdigit(), except it additionally takes an encoding.
*
- * @param[in] c A code point.
- * @param[in] enc An encoding.
- * @retval 1 `enc` classifies `c` as "DIGIT".
- * @retval 0 Otherwise.
+ * @param[in] c A code point.
+ * @param[in] enc An encoding.
+ * @retval true `enc` classifies `c` as "DIGIT".
+ * @retval false Otherwise.
*/
static inline bool
rb_enc_isdigit(OnigCodePoint c, rb_encoding *enc)
@@ -235,6 +249,7 @@ RBIMPL_SYMBOL_EXPORT_END()
#define rb_enc_isdigit rb_enc_isdigit
#define rb_enc_islower rb_enc_islower
#define rb_enc_isprint rb_enc_isprint
+#define rb_enc_iscntrl rb_enc_iscntrl
#define rb_enc_ispunct rb_enc_ispunct
#define rb_enc_isspace rb_enc_isspace
#define rb_enc_isupper rb_enc_isupper
diff --git a/include/ruby/internal/encoding/encoding.h b/include/ruby/internal/encoding/encoding.h
index 33f7f27fc1..4748ca806b 100644
--- a/include/ruby/internal/encoding/encoding.h
+++ b/include/ruby/internal/encoding/encoding.h
@@ -65,16 +65,16 @@ enum ruby_encoding_consts {
#define ENCODING_INLINE_MAX RUBY_ENCODING_INLINE_MAX /**< @old{RUBY_ENCODING_INLINE_MAX} */
#define ENCODING_SHIFT RUBY_ENCODING_SHIFT /**< @old{RUBY_ENCODING_SHIFT} */
-#define ENCODING_MASK RUBY_ENCODING_MASK /**< @old{RUBY_ENCODING_SHIFT} */
+#define ENCODING_MASK RUBY_ENCODING_MASK /**< @old{RUBY_ENCODING_MASK} */
/**
* Destructively assigns the passed encoding to the passed object. The object
* must be capable of having inline encoding. Using this macro needs deep
* understanding of bit level object binary layout.
*
- * @param[out] obj Target object to modify.
- * @param[in] i Encoding in encindex format.
- * @post `obj`'s encoding is `i`.
+ * @param[out] obj Target object to modify.
+ * @param[in] ecindex Encoding in encindex format.
+ * @post `obj`'s encoding is `encindex`.
*/
static inline void
RB_ENCODING_SET_INLINED(VALUE obj, int encindex)
@@ -375,8 +375,8 @@ rb_encoding *rb_enc_check(VALUE str1,VALUE str2);
VALUE rb_enc_associate_index(VALUE obj, int encindex);
/**
- * Identical to rb_enc_associate(), except it takes an encoding itself instead
- * of its index.
+ * Identical to rb_enc_associate_index(), except it takes an encoding itself
+ * instead of its index.
*
* @param[out] obj Object in question.
* @param[in] enc An encoding.
@@ -626,10 +626,10 @@ int rb_enc_codelen(int code, rb_encoding *enc);
/**
* Identical to rb_enc_codelen(), except it returns 0 for invalid code points.
*
- * @param[in] code Code point in question.
- * @param[in] enc Encoding to convert the code into a byte sequence.
- * @retval 0 `code` is invalid.
- * @return otherwise Number of bytes used for `enc` to encode `code`.
+ * @param[in] c Code point in question.
+ * @param[in] enc Encoding to convert `c` into a byte sequence.
+ * @retval 0 `c` is invalid.
+ * @return otherwise Number of bytes needed for `enc` to encode `c`.
*/
static inline int
rb_enc_code_to_mbclen(int c, rb_encoding *enc)
@@ -643,10 +643,12 @@ rb_enc_code_to_mbclen(int c, rb_encoding *enc)
* Identical to rb_enc_uint_chr(), except it writes back to the passed buffer
* instead of allocating one.
*
- * @param[in] c Code point.
- * @param[out] buf Return buffer.
- * @param[in] enc Target encoding scheme.
- * @post `c` is encoded according to `enc`, then written to `buf`.
+ * @param[in] c Code point.
+ * @param[out] buf Return buffer.
+ * @param[in] enc Target encoding scheme.
+ * @retval <= 0 `c` is invalid in `enc`.
+ * @return otherwise Number of bytes written to `buf`.
+ * @post `c` is encoded according to `enc`, then written to `buf`.
*
* @internal
*
diff --git a/include/ruby/internal/encoding/string.h b/include/ruby/internal/encoding/string.h
index f8ce809199..6ed7ca1c90 100644
--- a/include/ruby/internal/encoding/string.h
+++ b/include/ruby/internal/encoding/string.h
@@ -190,7 +190,7 @@ VALUE rb_enc_str_buf_cat(VALUE str, const char *ptr, long len, rb_encoding *enc)
* In other languages, APIs like this one could be seen as the primitive
* routines where encodings' "encode" feature are implemented. However in case
* of Ruby this is not the primitive one. We directly manipulate encoded
- * strings. Encoding conversion routines transocde an encoded string directly
+ * strings. Encoding conversion routines transcode an encoded string directly
* to another one; not via a code point array.
*/
VALUE rb_enc_uint_chr(unsigned int code, rb_encoding *enc);
diff --git a/include/ruby/internal/encoding/transcode.h b/include/ruby/internal/encoding/transcode.h
index 60c96a41c9..7f26d2eae9 100644
--- a/include/ruby/internal/encoding/transcode.h
+++ b/include/ruby/internal/encoding/transcode.h
@@ -476,16 +476,16 @@ enum ruby_econv_flag_type {
RUBY_ECONV_UNDEF_HEX_CHARREF = 0x00000030,
/** Decorators are there. */
- RUBY_ECONV_DECORATOR_MASK = 0x0000ff00,
+ RUBY_ECONV_DECORATOR_MASK = 0x0001ff00,
/** Newline converters are there. */
- RUBY_ECONV_NEWLINE_DECORATOR_MASK = 0x00003f00,
+ RUBY_ECONV_NEWLINE_DECORATOR_MASK = 0x00007f00,
/** (Unclear; seems unused). */
RUBY_ECONV_NEWLINE_DECORATOR_READ_MASK = 0x00000f00,
/** (Unclear; seems unused). */
- RUBY_ECONV_NEWLINE_DECORATOR_WRITE_MASK = 0x00003000,
+ RUBY_ECONV_NEWLINE_DECORATOR_WRITE_MASK = 0x00007000,
/** Universal newline mode. */
RUBY_ECONV_UNIVERSAL_NEWLINE_DECORATOR = 0x00000100,
@@ -496,11 +496,14 @@ enum ruby_econv_flag_type {
/** CRLF to CR conversion shall happen. */
RUBY_ECONV_CR_NEWLINE_DECORATOR = 0x00002000,
+ /** CRLF to LF conversion shall happen. */
+ RUBY_ECONV_LF_NEWLINE_DECORATOR = 0x00004000,
+
/** Texts shall be XML-escaped. */
- RUBY_ECONV_XML_TEXT_DECORATOR = 0x00004000,
+ RUBY_ECONV_XML_TEXT_DECORATOR = 0x00008000,
/** Texts shall be AttrValue escaped */
- RUBY_ECONV_XML_ATTR_CONTENT_DECORATOR = 0x00008000,
+ RUBY_ECONV_XML_ATTR_CONTENT_DECORATOR = 0x00010000,
/** (Unclear; seems unused). */
RUBY_ECONV_STATEFUL_DECORATOR_MASK = 0x00f00000,
@@ -529,6 +532,7 @@ enum ruby_econv_flag_type {
#define ECONV_UNIVERSAL_NEWLINE_DECORATOR RUBY_ECONV_UNIVERSAL_NEWLINE_DECORATOR /**< @old{RUBY_ECONV_UNIVERSAL_NEWLINE_DECORATOR} */
#define ECONV_CRLF_NEWLINE_DECORATOR RUBY_ECONV_CRLF_NEWLINE_DECORATOR /**< @old{RUBY_ECONV_CRLF_NEWLINE_DECORATOR} */
#define ECONV_CR_NEWLINE_DECORATOR RUBY_ECONV_CR_NEWLINE_DECORATOR /**< @old{RUBY_ECONV_CR_NEWLINE_DECORATOR} */
+#define ECONV_LF_NEWLINE_DECORATOR RUBY_ECONV_LF_NEWLINE_DECORATOR /**< @old{RUBY_ECONV_LF_NEWLINE_DECORATOR} */
#define ECONV_XML_TEXT_DECORATOR RUBY_ECONV_XML_TEXT_DECORATOR /**< @old{RUBY_ECONV_XML_TEXT_DECORATOR} */
#define ECONV_XML_ATTR_CONTENT_DECORATOR RUBY_ECONV_XML_ATTR_CONTENT_DECORATOR /**< @old{RUBY_ECONV_XML_ATTR_CONTENT_DECORATOR} */
#define ECONV_STATEFUL_DECORATOR_MASK RUBY_ECONV_STATEFUL_DECORATOR_MASK /**< @old{RUBY_ECONV_STATEFUL_DECORATOR_MASK} */
@@ -543,10 +547,10 @@ enum ruby_econv_flag_type {
*/
/** Indicates the input is a part of much larger one. */
- RUBY_ECONV_PARTIAL_INPUT = 0x00010000,
+ RUBY_ECONV_PARTIAL_INPUT = 0x00020000,
/** Instructs the converter to stop after output. */
- RUBY_ECONV_AFTER_OUTPUT = 0x00020000,
+ RUBY_ECONV_AFTER_OUTPUT = 0x00040000,
#define ECONV_PARTIAL_INPUT RUBY_ECONV_PARTIAL_INPUT /**< @old{RUBY_ECONV_PARTIAL_INPUT} */
#define ECONV_AFTER_OUTPUT RUBY_ECONV_AFTER_OUTPUT /**< @old{RUBY_ECONV_AFTER_OUTPUT} */
diff --git a/include/ruby/internal/eval.h b/include/ruby/internal/eval.h
index 34a53849da..5bcbb97746 100644
--- a/include/ruby/internal/eval.h
+++ b/include/ruby/internal/eval.h
@@ -28,10 +28,12 @@ RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NONNULL(())
/**
- * Evaluates the given string in an isolated binding.
+ * Evaluates the given string.
*
- * Here "isolated" means that the binding does not inherit any other
- * bindings. This behaves same as the binding for required libraries.
+ * In case it is called from within a C-backended method, the evaluation is
+ * done under the current binding. However there can be no method. On such
+ * situation this function evaluates in an isolated binding, like `require`
+ * runs in a separate one.
*
* `__FILE__` will be `"(eval)"`, and `__LINE__` starts from 1 in the
* evaluation.
@@ -39,6 +41,31 @@ RBIMPL_ATTR_NONNULL(())
* @param[in] str Ruby code to evaluate.
* @exception rb_eException Raises an exception on error.
* @return The evaluated result.
+ *
+ * @internal
+ *
+ * @shyouhei's old tale about the birth and growth of this function:
+ *
+ * At the beginning, there was no rb_eval_string(). @shyouhei heard that
+ * @shugo, author of Apache httpd's mod_ruby module, requested @matz for this
+ * API. He wanted a way so that mod_ruby can evaluate ruby scripts one by one,
+ * separately, in each different contexts. So this function was made. It was
+ * designed to be a global interpreter entry point like ruby_run_node().
+ *
+ * The way it is implemented however allows extension libraries (not just
+ * programs like Apache httpd) to call this function. Because its name says
+ * nothing about the initial design, people started to think of it as an
+ * orthodox way to call ruby level `eval` method from their extension
+ * libraries. Even our `extension.rdoc` has had a description of this function
+ * basically according to this understanding.
+ *
+ * The old (mod_ruby like) usage still works. But over time, usages of this
+ * function from extension libraries got popular, while mod_ruby faded out; is
+ * no longer maintained now. Devs decided to actively support both. This
+ * function now auto-detects how it is called, and switches how it works
+ * depending on it.
+ *
+ * @see https://bugs.ruby-lang.org/issues/18780
*/
VALUE rb_eval_string(const char *str);
diff --git a/include/ruby/internal/fl_type.h b/include/ruby/internal/fl_type.h
index 47f054256b..7383426b23 100644
--- a/include/ruby/internal/fl_type.h
+++ b/include/ruby/internal/fl_type.h
@@ -183,7 +183,7 @@ RB_GNUC_EXTENSION
* @note About the `FL_USER` terminology: the "user" here does not necessarily
* mean only you. For instance struct ::RString instances use these
* bits to cache their encodings etc. Devs discussed about this topic,
- * reached their concensus that ::RUBY_T_DATA is the only valid data
+ * reached their consensus that ::RUBY_T_DATA is the only valid data
* structure that can use these bits; other data structures including
* ::RUBY_T_OBJECT use these bits for their own purpose. See also
* https://bugs.ruby-lang.org/issues/18059
@@ -451,12 +451,6 @@ enum {
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
- * @deprecated Does nothing. This method is deprecated and will be removed in
- * Ruby 3.2.
- */
-void rb_obj_infect(VALUE victim, VALUE carrier);
-
-/**
* This is an implementation detail of #RB_OBJ_FREEZE(). People don't use it
* directly.
*
@@ -947,21 +941,8 @@ RB_OBJ_FREEZE_RAW(VALUE obj)
RB_FL_SET_RAW(obj, RUBY_FL_FREEZE);
}
-/**
- * Prevents further modifications to the given object. ::rb_eFrozenError shall
- * be raised if modification is attempted.
- *
- * @param[out] x Object in question.
- */
-static inline void
-rb_obj_freeze_inline(VALUE x)
-{
- if (RB_FL_ABLE(x)) {
- RB_OBJ_FREEZE_RAW(x);
- if (RBASIC_CLASS(x) && !(RBASIC(x)->flags & RUBY_FL_SINGLETON)) {
- rb_freeze_singleton_class(x);
- }
- }
-}
+RUBY_SYMBOL_EXPORT_BEGIN
+void rb_obj_freeze_inline(VALUE obj);
+RUBY_SYMBOL_EXPORT_END
#endif /* RBIMPL_FL_TYPE_H */
diff --git a/include/ruby/internal/has/builtin.h b/include/ruby/internal/has/builtin.h
index 957aff8375..243ba2a34c 100644
--- a/include/ruby/internal/has/builtin.h
+++ b/include/ruby/internal/has/builtin.h
@@ -53,8 +53,10 @@
# define RBIMPL_HAS_BUILTIN___builtin_assume 0
# /* See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52624 for bswap16. */
# define RBIMPL_HAS_BUILTIN___builtin_bswap16 RBIMPL_COMPILER_SINCE(GCC, 4, 8, 0)
+#ifndef __OpenBSD__
# define RBIMPL_HAS_BUILTIN___builtin_bswap32 RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_bswap64 RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
+#endif
# define RBIMPL_HAS_BUILTIN___builtin_clz RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_clzl RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
# define RBIMPL_HAS_BUILTIN___builtin_clzll RBIMPL_COMPILER_SINCE(GCC, 3, 6, 0)
@@ -76,10 +78,6 @@
# define RBIMPL_HAS_BUILTIN___builtin_unreachable RBIMPL_COMPILER_SINCE(GCC, 4, 5, 0)
# /* Note that "0, 0, 0" might be inaccurate. */
-#elif RBIMPL_COMPILER_IS(MSVC)
-# /* MSVC has UNREACHABLE, but that is not __builtin_unreachable. */
-# define RBIMPL_HAS_BUILTIN(_) 0
-
#else
# /* Take config.h definition when available */
# define RBIMPL_HAS_BUILTIN(_) ((RBIMPL_HAS_BUILTIN_ ## _)+0)
@@ -109,7 +107,7 @@
# define RBIMPL_HAS_BUILTIN___builtin_rotateright64 0
# define RBIMPL_HAS_BUILTIN___builtin_popcountll HAVE_BUILTIN___BUILTIN_POPCOUNTLL
# define RBIMPL_HAS_BUILTIN___builtin_sub_overflow HAVE_BUILTIN___BUILTIN_SUB_OVERFLOW
-# if defined(UNREACHABLE)
+# if defined(HAVE___BUILTIN_UNREACHABLE)
# define RBIMPL_HAS_BUILTIN___builtin_unreachable 1
# else
# define RBIMPL_HAS_BUILTIN___builtin_unreachable 0
diff --git a/include/ruby/internal/intern/array.h b/include/ruby/internal/intern/array.h
index 17964bf810..2262c6f0c6 100644
--- a/include/ruby/internal/intern/array.h
+++ b/include/ruby/internal/intern/array.h
@@ -107,14 +107,14 @@ VALUE rb_ary_new_from_args(long n, ...);
VALUE rb_ary_new_from_values(long n, const VALUE *elts);
/**
- * Allocates a "temporary" array. This is a hidden empty array. Handy on
- * occasions.
+ * Allocates a hidden (no class) empty array.
*
* @param[in] capa Designed capacity of the array.
* @return A hidden, empty array.
* @see rb_obj_hide()
*/
-VALUE rb_ary_tmp_new(long capa);
+VALUE rb_ary_hidden_new(long capa);
+#define rb_ary_tmp_new rb_ary_hidden_new
/**
* Destroys the given array for no reason.
diff --git a/include/ruby/internal/intern/class.h b/include/ruby/internal/intern/class.h
index 60baf98472..0fb2d001bc 100644
--- a/include/ruby/internal/intern/class.h
+++ b/include/ruby/internal/intern/class.h
@@ -158,7 +158,7 @@ VALUE rb_mod_included_modules(VALUE mod);
VALUE rb_mod_include_p(VALUE child, VALUE parent);
/**
- * Queries the module's ancestors. This routine gathers classes and modules
+ * Queries the module's ancestors. This routine gathers classes and modules
* that the passed module either inherits, includes, or prepends, then
* recursively applies that routine again and again to the collected entries
* until the list doesn't grow up.
@@ -175,6 +175,44 @@ VALUE rb_mod_include_p(VALUE child, VALUE parent);
VALUE rb_mod_ancestors(VALUE mod);
/**
+ * Queries the class's descendants. This routine gathers classes that are
+ * subclasses of the given class (or subclasses of those subclasses, etc.),
+ * returning an array of classes that have the given class as an ancestor.
+ * The returned array does not include the given class or singleton classes.
+ *
+ * @param[in] klass A class.
+ * @return An array of classes where `klass` is an ancestor.
+ *
+ * @internal
+ */
+VALUE rb_class_descendants(VALUE klass);
+
+/**
+ * Queries the class's direct descendants. This routine gathers classes that are
+ * direct subclasses of the given class,
+ * returning an array of classes that have the given class as a superclass.
+ * The returned array does not include singleton classes.
+ *
+ * @param[in] klass A class.
+ * @return An array of classes where `klass` is the `superclass`.
+ *
+ * @internal
+ */
+VALUE rb_class_subclasses(VALUE klass);
+
+
+/**
+ * Returns the attached object for a singleton class.
+ * If the given class is not a singleton class, raises a TypeError.
+ *
+ * @param[in] klass A class.
+ * @return The object which has the singleton class `klass`.
+ *
+ * @internal
+ */
+VALUE rb_class_attached_object(VALUE klass);
+
+/**
* Generates an array of symbols, which are the list of method names defined in
* the passed class.
*
diff --git a/include/ruby/internal/intern/cont.h b/include/ruby/internal/intern/cont.h
index 37493009f5..32647f48aa 100644
--- a/include/ruby/internal/intern/cont.h
+++ b/include/ruby/internal/intern/cont.h
@@ -39,6 +39,28 @@ RBIMPL_SYMBOL_EXPORT_BEGIN()
VALUE rb_fiber_new(rb_block_call_func_t func, VALUE callback_obj);
/**
+ * Creates a Fiber instance from a C-backended block with the specified
+ * storage.
+ *
+ * If the given storage is Qundef or Qtrue, this function is equivalent to
+ * rb_fiber_new() which inherits storage from the current fiber.
+ *
+ * Specifying Qtrue is experimental and may be changed in the future.
+ *
+ * If the given storage is Qnil, this function will lazy initialize the
+ * internal storage which starts of empty (without any inheritance).
+ *
+ * Otherwise, the given storage is used as the internal storage.
+ *
+ * @param[in] func A function, to become the fiber's body.
+ * @param[in] callback_obj Passed as-is to `func`.
+ * @param[in] storage The way to set up the storage for the fiber.
+ * @return An allocated new instance of rb_cFiber, which is ready to be
+ * "resume"d.
+ */
+VALUE rb_fiber_new_storage(rb_block_call_func_t func, VALUE callback_obj, VALUE storage);
+
+/**
* Queries the fiber which is calling this function. Any ruby execution
* context has its fiber, either explicitly or implicitly.
*
diff --git a/include/ruby/internal/intern/error.h b/include/ruby/internal/intern/error.h
index 37d3b8592b..9c153cbac5 100644
--- a/include/ruby/internal/intern/error.h
+++ b/include/ruby/internal/intern/error.h
@@ -38,8 +38,6 @@
#define rb_exc_new3 rb_exc_new_str /**< @old{rb_exc_new_str} */
/** @cond INTERNAL_MACRO */
-#define rb_check_trusted rb_check_trusted
-#define rb_check_trusted_inline rb_check_trusted
#define rb_check_arity rb_check_arity
/** @endcond */
@@ -204,12 +202,6 @@ RBIMPL_ATTR_NORETURN()
void rb_error_frozen_object(VALUE what);
/**
- * @deprecated Does nothing. This method is deprecated and will be removed in
- * Ruby 3.2.
- */
-void rb_error_untrusted(VALUE);
-
-/**
* Queries if the passed object is frozen.
*
* @param[in] obj Target object to test frozen-ness.
@@ -219,12 +211,6 @@ void rb_error_untrusted(VALUE);
void rb_check_frozen(VALUE obj);
/**
- * @deprecated Does nothing. This method is deprecated and will be removed in
- * Ruby 3.2.
- */
-void rb_check_trusted(VALUE);
-
-/**
* Ensures that the passed object can be `initialize_copy` relationship. When
* you implement your own one you would better call this at the right beginning
* of your implementation.
diff --git a/include/ruby/internal/intern/file.h b/include/ruby/internal/intern/file.h
index 8e98ba08f8..79820fdc61 100644
--- a/include/ruby/internal/intern/file.h
+++ b/include/ruby/internal/intern/file.h
@@ -187,6 +187,27 @@ RBIMPL_ATTR_PURE()
*/
int rb_is_absolute_path(const char *path);
+/**
+ * Queries the file size of the given file. Because this function calls
+ * `fstat(2)` internally, it is a failure to pass a closed file to this
+ * function.
+ *
+ * This function flushes the passed file's buffer if any. Can take time.
+ *
+ * @param[in] file A file object.
+ * @exception rb_eFrozenError `file` is frozen.
+ * @exception rb_eIOError `file` is closed.
+ * @exception rb_eSystemCallError Permission denied etc.
+ * @exception rb_eNoMethodError The given non-file object doesn't respond
+ * to `#size`.
+ * @return The size of the passed file.
+ * @note Passing a non-regular file such as a UNIX domain socket to this
+ * function is not a failure. But the return value is
+ * unpredictable. POSIX's `<sys/stat.h>` states that "the use of
+ * this field is unspecified" then.
+ */
+rb_off_t rb_file_size(VALUE file);
+
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RBIMPL_INTERN_FILE_H */
diff --git a/include/ruby/internal/intern/gc.h b/include/ruby/internal/intern/gc.h
index 1617a7cef6..2ee1d257db 100644
--- a/include/ruby/internal/intern/gc.h
+++ b/include/ruby/internal/intern/gc.h
@@ -26,7 +26,7 @@
# include <stddef.h> /* size_t */
#endif
-#if HAVE_SYS_TYPES_H
+#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h> /* ssize_t */
#endif
@@ -71,7 +71,7 @@ RBIMPL_ATTR_NONNULL((1))
* addressable.
* @param[out] start Pointer to an array of objects.
* @param[out] end Pointer that terminates the array of objects.
- * @post Objects from `start` to `end`, both inclusive, are marked.
+ * @post Objects from `start` (included) to `end` (excluded) are marked.
*
* @internal
*
@@ -208,7 +208,9 @@ VALUE rb_gc_location(VALUE obj);
* @post `obj` could be invalidated.
* @warning It is a failure to pass an object multiple times to this
* function.
+ * @deprecated This is now a no-op function.
*/
+RBIMPL_ATTR_DEPRECATED(("this is now a no-op function"))
void rb_gc_force_recycle(VALUE obj);
/**
@@ -249,7 +251,7 @@ void rb_gc(void);
*
* @internal
*
- * But isn't it easier for you to call super, and let `Object#intialize_copy`
+ * But isn't it easier for you to call super, and let `Object#initialize_copy`
* call this function instead?
*/
void rb_gc_copy_finalizer(VALUE dst, VALUE src);
diff --git a/include/ruby/internal/intern/hash.h b/include/ruby/internal/intern/hash.h
index 9d2ce8279a..af8dfd5d8f 100644
--- a/include/ruby/internal/intern/hash.h
+++ b/include/ruby/internal/intern/hash.h
@@ -107,6 +107,17 @@ VALUE rb_hash(VALUE obj);
VALUE rb_hash_new(void);
/**
+ * Identical to rb_hash_new(), except it additionally specifies how many keys
+ * it is expected to contain. This way you can create a hash that is large enough
+ * for your need. For large hashes it means it won't need to be reallocated and
+ * rehashed as much, improving performance.
+ *
+ * @param[in] capa Designed capacity of the hash.
+ * @return An empty Hash, whose capacity is `capa`.
+ */
+VALUE rb_hash_new_capa(long capa);
+
+/**
* Duplicates a hash.
*
* @param[in] hash An instance of ::rb_cHash.
@@ -288,15 +299,6 @@ int rb_path_check(const char *path);
/* hash.c */
/**
- * @deprecated This function once was a thing in the old days, but makes no
- * sense any longer today. Exists here for backwards
- * compatibility only. You can safely forget about it.
- *
- * @return 0 always.
- */
-int rb_env_path_tainted(void);
-
-/**
* Destructively removes every environment variables of the running process.
*
* @return The `ENV` object.
diff --git a/include/ruby/internal/intern/object.h b/include/ruby/internal/intern/object.h
index 6bb4ccb2fe..b9ffa57c06 100644
--- a/include/ruby/internal/intern/object.h
+++ b/include/ruby/internal/intern/object.h
@@ -92,8 +92,8 @@ VALUE rb_class_new_instance_kw(int argc, const VALUE *argv, VALUE klass, int kw_
*
* @param[in] lhs Comparison left hand side.
* @param[in] rhs Comparison right hand side.
- * @retval RUBY_Qtrue They are equal.
- * @retval RUBY_Qfalse Otherwise.
+ * @retval non-zero They are equal.
+ * @retval 0 Otherwise.
* @note This function actually calls `lhs.eql?(rhs)` so you cannot
* implement your class' `#eql?` method using it.
*/
@@ -202,74 +202,6 @@ VALUE rb_obj_dup(VALUE obj);
*/
VALUE rb_obj_init_copy(VALUE src, VALUE dst);
-RBIMPL_ATTR_DEPRECATED_EXT(("taintedness turned out to be a wrong idea."))
-/**
- * @deprecated This function once was a thing in the old days, but makes no
- * sense any longer today. Exists here for backwards
- * compatibility only. You can safely forget about it.
- *
- * @param[in] obj Object in question.
- * @return Verbatim `obj`.
- */
-VALUE rb_obj_taint(VALUE obj);
-
-RBIMPL_ATTR_PURE()
-RBIMPL_ATTR_DEPRECATED_EXT(("taintedness turned out to be a wrong idea."))
-/**
- * @deprecated This function once was a thing in the old days, but makes no
- * sense any longer today. Exists here for backwards
- * compatibility only. You can safely forget about it.
- *
- * @param[in] obj Object in question.
- * @return Always returns ::RUBY_Qfalse.
- */
-VALUE rb_obj_tainted(VALUE obj);
-
-RBIMPL_ATTR_DEPRECATED_EXT(("taintedness turned out to be a wrong idea."))
-/**
- * @deprecated This function once was a thing in the old days, but makes no
- * sense any longer today. Exists here for backwards
- * compatibility only. You can safely forget about it.
- *
- * @param[in] obj Object in question.
- * @return Verbatim `obj`.
- */
-VALUE rb_obj_untaint(VALUE obj);
-
-RBIMPL_ATTR_DEPRECATED_EXT(("trustedness turned out to be a wrong idea."))
-/**
- * @deprecated This function once was a thing in the old days, but makes no
- * sense any longer today. Exists here for backwards
- * compatibility only. You can safely forget about it.
- *
- * @param[in] obj Object in question.
- * @return Verbatim `obj`.
- */
-VALUE rb_obj_untrust(VALUE obj);
-
-RBIMPL_ATTR_PURE()
-RBIMPL_ATTR_DEPRECATED_EXT(("trustedness turned out to be a wrong idea."))
-/**
- * @deprecated This function once was a thing in the old days, but makes no
- * sense any longer today. Exists here for backwards
- * compatibility only. You can safely forget about it.
- *
- * @param[in] obj Object in question.
- * @return Always returns ::RUBY_Qfalse.
- */
-VALUE rb_obj_untrusted(VALUE obj);
-
-RBIMPL_ATTR_DEPRECATED_EXT(("trustedness turned out to be a wrong idea."))
-/**
- * @deprecated This function once was a thing in the old days, but makes no
- * sense any longer today. Exists here for backwards
- * compatibility only. You can safely forget about it.
- *
- * @param[in] obj Object in question.
- * @return Verbatim `obj`.
- */
-VALUE rb_obj_trust(VALUE obj);
-
/**
* Just calls rb_obj_freeze_inline() inside. Does this make any sens to
* extension libraries?
diff --git a/include/ruby/internal/intern/select/largesize.h b/include/ruby/internal/intern/select/largesize.h
index d156f62034..d65f088c06 100644
--- a/include/ruby/internal/intern/select/largesize.h
+++ b/include/ruby/internal/intern/select/largesize.h
@@ -35,9 +35,6 @@
* `select(2)` documents how to allocate fd_set dynamically.
* http://www.openbsd.org/cgi-bin/man.cgi?query=select&manpath=OpenBSD+4.4
*
- * - HP-UX documents how to allocate fd_set dynamically.
- * http://docs.hp.com/en/B2355-60105/select.2.html
- *
* - Solaris 8 has `select_large_fdset`
*
* - Mac OS X 10.7 (Lion)
diff --git a/include/ruby/internal/intern/select/posix.h b/include/ruby/internal/intern/select/posix.h
index bfde159890..0a9b0b2e51 100644
--- a/include/ruby/internal/intern/select/posix.h
+++ b/include/ruby/internal/intern/select/posix.h
@@ -95,11 +95,10 @@ RBIMPL_ATTR_NOALIAS()
*
* @param[out] dst Target fdset.
* @param[in] src Source fdset.
- * @param[in] n Unused parameter.
* @post `dst` is a copy of `src`.
*/
static inline void
-rb_fd_dup(rb_fdset_t *dst, const fd_set *src, int n)
+rb_fd_dup(rb_fdset_t *dst, const fd_set *src)
{
*dst = *src;
}
@@ -137,7 +136,7 @@ rb_fd_max(const rb_fdset_t *f)
}
/** @cond INTERNAL_MACRO */
-/* :FIXME: What are these? They don't exist for shibling implementations. */
+/* :FIXME: What are these? They don't exist for sibling implementations. */
#define rb_fd_init_copy(d, s) (*(d) = *(s))
#define rb_fd_term(f) ((void)(f))
/** @endcond */
diff --git a/include/ruby/internal/intern/string.h b/include/ruby/internal/intern/string.h
index 0e2e6d6af7..3083125e56 100644
--- a/include/ruby/internal/intern/string.h
+++ b/include/ruby/internal/intern/string.h
@@ -62,13 +62,13 @@ RBIMPL_SYMBOL_EXPORT_BEGIN()
*/
VALUE rb_str_new(const char *ptr, long len);
-RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_str_new(), except it assumes the passed pointer is a pointer
* to a C string.
*
* @param[in] ptr A C string.
* @exception rb_eNoMemError Failed to allocate memory.
+ * @exception rb_eArgError `ptr` is a null pointer.
* @return An instance of ::rb_cString, of "binary" encoding, whose
* contents are verbatim copy of `ptr`.
* @pre `ptr` must not be a null pointer.
@@ -122,37 +122,6 @@ VALUE rb_str_new_frozen(VALUE str);
*/
VALUE rb_str_new_with_class(VALUE obj, const char *ptr, long len);
-RBIMPL_ATTR_NONNULL(())
-/**
- * @deprecated This function once was a thing in the old days, but makes no
- * sense any longer today. Exists here for backwards
- * compatibility only. You can safely forget about it.
- *
- * @param[in] ptr A C string.
- * @exception rb_eNoMemError Failed to allocate memory.
- * @return An instance of ::rb_cString, of "binary" encoding, whose
- * contents are verbatim copy of `ptr`.
- * @pre `ptr` must not be a null pointer.
- */
-VALUE rb_tainted_str_new_cstr(const char *ptr);
-
-/**
- * @deprecated This function once was a thing in the old days, but makes no
- * sense any longer today. Exists here for backwards
- * compatibility only. You can safely forget about it.
- *
- * @param[in] ptr A memory region of `len` bytes length.
- * @param[in] len Length of `ptr`, in bytes, not including the
- * terminating NUL character.
- * @exception rb_eNoMemError Failed to allocate `len+1` bytes.
- * @exception rb_eArgError `len` is negative.
- * @return An instance of ::rb_cString, of `len` bytes length, of
- * "binary" encoding, whose contents are verbatim copy of `ptr`.
- * @pre At least `len` bytes of continuous memory region shall be
- * accessible via `ptr`.
- */
-VALUE rb_tainted_str_new(const char *ptr, long len);
-
/**
* Identical to rb_str_new(), except it generates a string of "default
* external" encoding.
@@ -333,7 +302,6 @@ VALUE rb_str_tmp_new(long len);
*/
VALUE rb_usascii_str_new(const char *ptr, long len);
-RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_str_new_cstr(), except it generates a string of "US ASCII"
* encoding. It can also be seen as a routine Identical to
@@ -342,6 +310,7 @@ RBIMPL_ATTR_NONNULL(())
*
* @param[in] ptr A C string.
* @exception rb_eNoMemError Failed to allocate memory.
+ * @exception rb_eArgError `ptr` is a null pointer.
* @return An instance of ::rb_cString, of "US ASCII" encoding, whose
* contents are verbatim copy of `ptr`.
* @pre `ptr` must not be a null pointer.
@@ -361,7 +330,6 @@ VALUE rb_usascii_str_new_cstr(const char *ptr);
*/
VALUE rb_utf8_str_new(const char *ptr, long len);
-RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_str_new_cstr(), except it generates a string of "UTF-8"
* encoding. It can also be seen as a routine Identical to
@@ -370,6 +338,7 @@ RBIMPL_ATTR_NONNULL(())
*
* @param[in] ptr A C string.
* @exception rb_eNoMemError Failed to allocate memory.
+ * @exception rb_eArgError `ptr` is a null pointer.
* @return An instance of ::rb_cString, of "UTF-8" encoding, whose contents
* are verbatim copy of `ptr`.
* @pre `ptr` must not be a null pointer.
@@ -553,7 +522,6 @@ VALUE rb_str_buf_append(VALUE dst, VALUE src);
/** @alias{rb_str_cat} */
VALUE rb_str_buf_cat(VALUE, const char*, long);
-RBIMPL_ATTR_NONNULL(())
/** @alias{rb_str_cat_cstr} */
VALUE rb_str_buf_cat2(VALUE, const char*);
@@ -874,7 +842,6 @@ VALUE rb_str_resize(VALUE str, long len);
*/
VALUE rb_str_cat(VALUE dst, const char *src, long srclen);
-RBIMPL_ATTR_NONNULL(())
/**
* Identical to rb_str_cat(), except it assumes the passed pointer is a pointer
* to a C string.
@@ -882,6 +849,7 @@ RBIMPL_ATTR_NONNULL(())
* @param[out] dst Destination object.
* @param[in] src Contents to append.
* @exception rb_eArgError Result string too big.
+ * @exception rb_eArgError `src` is a null pointer.
* @return The passed `dst`.
* @pre `dst` must not be any arbitrary objects except ::RString.
* @pre `src` must not be a null pointer.
@@ -889,7 +857,6 @@ RBIMPL_ATTR_NONNULL(())
*/
VALUE rb_str_cat_cstr(VALUE dst, const char *src);
-RBIMPL_ATTR_NONNULL(())
/** @alias{rb_str_cat_cstr} */
VALUE rb_str_cat2(VALUE, const char*);
@@ -1153,7 +1120,6 @@ VALUE rb_str_inspect(VALUE str);
*/
VALUE rb_str_dump(VALUE str);
-RBIMPL_ATTR_NONNULL(())
/**
* Divides the given string based on the given delimiter. This is the
* 1-argument 0-block version of `String#split`.
@@ -1161,6 +1127,7 @@ RBIMPL_ATTR_NONNULL(())
* @param[in] str Object in question to split.
* @param[in] delim Delimiter, in C string.
* @exception rb_eTypeError `str` has no implicit conversion to String.
+ * @exception rb_eArgError `delim` is a null pointer.
* @return An array of strings, which are substrings of the passed `str`.
* If `delim` is an empty C string (i.e. `""`), `str` is split into
* each characters. If `delim` is a C string whose sole content is
@@ -1400,22 +1367,6 @@ rbimpl_str_new_cstr(const char *str)
return rb_str_new_static(str, len);
}
-RBIMPL_ATTR_DEPRECATED(("taintedness turned out to be a wrong idea."))
-/**
- * @private
- *
- * This is an implementation detail. Don't bother.
- *
- * @param[in] str A C string literal.
- * @return Corresponding Ruby string.
- */
-static inline VALUE
-rbimpl_tainted_str_new_cstr(const char *str)
-{
- long len = rbimpl_strlen(str);
- return rb_tainted_str_new(str, len);
-}
-
RBIMPL_ATTR_NONNULL(())
/**
* @private
@@ -1602,22 +1553,6 @@ rbimpl_exc_new_cstr(VALUE exc, const char *str)
rb_utf8_str_new) ((str), (len)))
/**
- * @deprecated This macro once was a thing in the old days, but makes no sense
- * any longer today. Exists here for backwards compatibility
- * only. You can safely forget about it.
- *
- * @param[in] str A C string.
- * @exception rb_eNoMemError Failed to allocate memory.
- * @return An instance of ::rb_cString, of "binary" encoding, whose
- * contents are verbatim copy of `str`.
- * @pre `str` must not be a null pointer.
- */
-#define rb_tainted_str_new_cstr(str) \
- ((RBIMPL_CONSTANT_P(str) ? \
- rbimpl_tainted_str_new_cstr : \
- rb_tainted_str_new_cstr) (str))
-
-/**
* Identical to #rb_str_new_cstr, except it generates a string of "US ASCII"
* encoding. It can also be seen as a routine Identical to
* #rb_usascii_str_new, except it assumes the passed pointer is a pointer to a
@@ -1741,7 +1676,6 @@ rbimpl_exc_new_cstr(VALUE exc, const char *str)
#define rb_str_new3 rb_str_new_shared /**< @old{rb_str_new_shared} */
#define rb_str_new4 rb_str_new_frozen /**< @old{rb_str_new_frozen} */
#define rb_str_new5 rb_str_new_with_class /**< @old{rb_str_new_with_class} */
-#define rb_tainted_str_new2 rb_tainted_str_new_cstr /**< @old{rb_tainted_str_new_cstr} */
#define rb_str_buf_new2 rb_str_buf_new_cstr /**< @old{rb_str_buf_new_cstr} */
#define rb_usascii_str_new2 rb_usascii_str_new_cstr /**< @old{rb_usascii_str_new_cstr} */
#define rb_str_buf_cat rb_str_cat /**< @alias{rb_str_cat} */
diff --git a/include/ruby/internal/intern/thread.h b/include/ruby/internal/intern/thread.h
index 294e552fe9..716375acd7 100644
--- a/include/ruby/internal/intern/thread.h
+++ b/include/ruby/internal/intern/thread.h
@@ -46,7 +46,7 @@ void rb_thread_schedule(void);
*
* @param[in] fd A file descriptor.
* @exception rb_eIOError Closed stream.
- * @exception rb_eSystemCalleError Situations like EBADF.
+ * @exception rb_eSystemCallError Situations like EBADF.
*/
int rb_thread_wait_fd(int fd);
@@ -56,7 +56,7 @@ int rb_thread_wait_fd(int fd);
*
* @param[in] fd A file descriptor.
* @exception rb_eIOError Closed stream.
- * @exception rb_eSystemCalleError Situations like EBADF.
+ * @exception rb_eSystemCallError Situations like EBADF.
*/
int rb_thread_fd_writable(int fd);
diff --git a/include/ruby/internal/intern/vm.h b/include/ruby/internal/intern/vm.h
index 562d30a6fe..76af796b54 100644
--- a/include/ruby/internal/intern/vm.h
+++ b/include/ruby/internal/intern/vm.h
@@ -247,21 +247,17 @@ void rb_undef_alloc_func(VALUE klass);
*
* @internal
*
- * Who cares? @shyouhei fins no practical usage of the return value. Maybe we
+ * Who cares? @shyouhei finds no practical usage of the return value. Maybe we
* need KonMari.
*/
rb_alloc_func_t rb_get_alloc_func(VALUE klass);
/**
- * Clears the constant cache. Extension libraries should not bother such
- * things. Just forget about this API (or even, the presence of constant
- * cache).
- *
- * @internal
- *
- * Completely no idea why this function is defined in vm_method.c.
+ * Clears the inline constant caches associated with a particular ID. Extension
+ * libraries should not bother with such things. Just forget about this API (or
+ * even, the presence of constant caches).
*/
-void rb_clear_constant_cache(void);
+void rb_clear_constant_cache_for_id(ID id);
/**
* Resembles `alias`.
diff --git a/include/ruby/internal/memory.h b/include/ruby/internal/memory.h
index aa3464465d..6884db195d 100644
--- a/include/ruby/internal/memory.h
+++ b/include/ruby/internal/memory.h
@@ -287,12 +287,12 @@ typedef uint128_t DSIZE_T;
RBIMPL_CAST((type *)alloca(rbimpl_size_mul_or_raise(sizeof(type), (n))))
/**
- * Identical to #RB_ALLOCV_N(), except it implicitly assumes the type of array
- * is ::VALUE.
+ * Identical to #RB_ALLOCV_N(), except that it allocates a number of bytes and
+ * returns a void* .
*
* @param v A variable to hold the just-in-case opaque Ruby object.
* @param n Size of allocation, in bytes.
- * @return An array of `n` bytes of ::VALUE.
+ * @return A void pointer to `n` bytes storage.
* @note `n` may be evaluated twice.
*/
#define RB_ALLOCV(v, n) \
@@ -363,7 +363,7 @@ typedef uint128_t DSIZE_T;
* @return `p1`.
* @post First `n` elements of `p2` are copied into `p1`.
*/
-#define MEMCPY(p1,p2,type,n) memcpy((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))
+#define MEMCPY(p1,p2,type,n) ruby_nonempty_memcpy((p1), (p2), rbimpl_size_mul_or_raise(sizeof(type), (n)))
/**
* Handy macro to call memmove.
@@ -644,7 +644,6 @@ rb_alloc_tmp_buffer2(volatile VALUE *store, long count, size_t elsize)
return rb_alloc_tmp_buffer_with_count(store, total_size, cnt);
}
-#if ! defined(__MINGW32__) && ! defined(__DOXYGEN__)
RBIMPL_SYMBOL_EXPORT_BEGIN()
RBIMPL_ATTR_NOALIAS()
RBIMPL_ATTR_NONNULL((1))
@@ -663,8 +662,5 @@ ruby_nonempty_memcpy(void *dest, const void *src, size_t n)
}
}
RBIMPL_SYMBOL_EXPORT_END()
-#undef memcpy
-#define memcpy ruby_nonempty_memcpy
-#endif
#endif /* RBIMPL_MEMORY_H */
diff --git a/include/ruby/internal/scan_args.h b/include/ruby/internal/scan_args.h
index cf5b18f77d..1ed2bf6368 100644
--- a/include/ruby/internal/scan_args.h
+++ b/include/ruby/internal/scan_args.h
@@ -100,7 +100,7 @@ RBIMPL_ATTR_NONNULL((2, 3))
* param-arg-spec := pre-arg-spec [post-arg-spec] / post-arg-spec /
* pre-opt-post-arg-spec
* pre-arg-spec := num-of-leading-mandatory-args
- [num-of-optional-args]
+ * [num-of-optional-args]
* post-arg-spec := sym-for-variable-length-args
* [num-of-trailing-mandatory-args]
* pre-opt-post-arg-spec := num-of-leading-mandatory-args num-of-optional-args
diff --git a/include/ruby/internal/special_consts.h b/include/ruby/internal/special_consts.h
index 38934e4da3..dc0a6b41d6 100644
--- a/include/ruby/internal/special_consts.h
+++ b/include/ruby/internal/special_consts.h
@@ -76,6 +76,8 @@
#define RB_SPECIAL_CONST_P RB_SPECIAL_CONST_P
#define RB_STATIC_SYM_P RB_STATIC_SYM_P
#define RB_TEST RB_TEST
+#define RB_UNDEF_P RB_UNDEF_P
+#define RB_NIL_OR_UNDEF_P RB_NIL_OR_UNDEF_P
/** @endcond */
/** special constants - i.e. non-zero and non-fixnum constants */
@@ -94,9 +96,9 @@ ruby_special_consts {
RUBY_SYMBOL_FLAG, /**< Flag to denote a static symbol. */
#elif USE_FLONUM
RUBY_Qfalse = 0x00, /* ...0000 0000 */
+ RUBY_Qnil = 0x04, /* ...0000 0100 */
RUBY_Qtrue = 0x14, /* ...0001 0100 */
- RUBY_Qnil = 0x08, /* ...0000 1000 */
- RUBY_Qundef = 0x34, /* ...0011 0100 */
+ RUBY_Qundef = 0x24, /* ...0010 0100 */
RUBY_IMMEDIATE_MASK = 0x07, /* ...0000 0111 */
RUBY_FIXNUM_FLAG = 0x01, /* ...xxxx xxx1 */
RUBY_FLONUM_MASK = 0x03, /* ...0000 0011 */
@@ -104,14 +106,14 @@ ruby_special_consts {
RUBY_SYMBOL_FLAG = 0x0c, /* ...xxxx 1100 */
#else
RUBY_Qfalse = 0x00, /* ...0000 0000 */
- RUBY_Qtrue = 0x02, /* ...0000 0010 */
- RUBY_Qnil = 0x04, /* ...0000 0100 */
- RUBY_Qundef = 0x06, /* ...0000 0110 */
+ RUBY_Qnil = 0x02, /* ...0000 0010 */
+ RUBY_Qtrue = 0x06, /* ...0000 0110 */
+ RUBY_Qundef = 0x0a, /* ...0000 1010 */
RUBY_IMMEDIATE_MASK = 0x03, /* ...0000 0011 */
RUBY_FIXNUM_FLAG = 0x01, /* ...xxxx xxx1 */
RUBY_FLONUM_MASK = 0x00, /* any values ANDed with FLONUM_MASK cannot be FLONUM_FLAG */
RUBY_FLONUM_FLAG = 0x02, /* ...0000 0010 */
- RUBY_SYMBOL_FLAG = 0x0e, /* ...0000 1110 */
+ RUBY_SYMBOL_FLAG = 0x0e, /* ...xxxx 1110 */
#endif
RUBY_SPECIAL_SHIFT = 8 /**< Least significant 8 bits are reserved. */
@@ -136,12 +138,21 @@ static inline bool
RB_TEST(VALUE obj)
{
/*
+ * if USE_FLONUM
* Qfalse: ....0000 0000
- * Qnil: ....0000 1000
- * ~Qnil: ....1111 0111
+ * Qnil: ....0000 0100
+ * ~Qnil: ....1111 1011
* v ....xxxx xxxx
* ----------------------------
- * RTEST(v) ....xxxx 0xxx
+ * RTEST(v) ....xxxx x0xx
+ *
+ * if ! USE_FLONUM
+ * Qfalse: ....0000 0000
+ * Qnil: ....0000 0010
+ * ~Qnil: ....1111 1101
+ * v ....xxxx xxxx
+ * ----------------------------
+ * RTEST(v) ....xxxx xx0x
*
* RTEST(v) can be 0 if and only if (v == Qfalse || v == Qnil).
*/
@@ -168,6 +179,62 @@ RBIMPL_ATTR_CONST()
RBIMPL_ATTR_CONSTEXPR(CXX11)
RBIMPL_ATTR_ARTIFICIAL()
/**
+ * Checks if the given object is undef.
+ *
+ * @param[in] obj An arbitrary ruby object.
+ * @retval true `obj` is ::RUBY_Qundef.
+ * @retval false Anything else.
+ */
+static inline bool
+RB_UNDEF_P(VALUE obj)
+{
+ return obj == RUBY_Qundef;
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX14)
+RBIMPL_ATTR_ARTIFICIAL()
+/**
+ * Checks if the given object is nil or undef. Can be used to see if
+ * a keyword argument is not given or given `nil`.
+ *
+ * @param[in] obj An arbitrary ruby object.
+ * @retval true `obj` is ::RUBY_Qnil or ::RUBY_Qundef.
+ * @retval false Anything else.
+ */
+static inline bool
+RB_NIL_OR_UNDEF_P(VALUE obj)
+{
+ /*
+ * if USE_FLONUM
+ * Qundef: ....0010 0100
+ * Qnil: ....0000 0100
+ * mask: ....1101 1111
+ * common_bits: ....0000 0100
+ * ---------------------------------
+ * Qnil & mask ....0000 0100
+ * Qundef & mask ....0000 0100
+ *
+ * if ! USE_FLONUM
+ * Qundef: ....0000 1010
+ * Qnil: ....0000 0010
+ * mask: ....1111 0111
+ * common_bits: ....0000 0010
+ * ----------------------------
+ * Qnil & mask ....0000 0010
+ * Qundef & mask ....0000 0010
+ *
+ * NIL_OR_UNDEF_P(v) can be true only when v is Qundef or Qnil.
+ */
+ const VALUE mask = ~(RUBY_Qundef ^ RUBY_Qnil);
+ const VALUE common_bits = RUBY_Qundef & RUBY_Qnil;
+ return (obj & mask) == common_bits;
+}
+
+RBIMPL_ATTR_CONST()
+RBIMPL_ATTR_CONSTEXPR(CXX11)
+RBIMPL_ATTR_ARTIFICIAL()
+/**
* Checks if the given object is a so-called Fixnum.
*
* @param[in] obj An arbitrary ruby object.
@@ -259,7 +326,7 @@ RBIMPL_ATTR_ARTIFICIAL()
static inline bool
RB_SPECIAL_CONST_P(VALUE obj)
{
- return RB_IMMEDIATE_P(obj) || ! RB_TEST(obj);
+ return RB_IMMEDIATE_P(obj) || obj == RUBY_Qfalse;
}
RBIMPL_ATTR_CONST()
diff --git a/include/ruby/internal/stdbool.h b/include/ruby/internal/stdbool.h
index b15321cb00..1ca61136ba 100644
--- a/include/ruby/internal/stdbool.h
+++ b/include/ruby/internal/stdbool.h
@@ -39,7 +39,7 @@
# /* Take stdbool.h definition. */
# include <stdbool.h>
-#else
+#elif !defined(HAVE__BOOL)
typedef unsigned char _Bool;
# /* See also http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2229.htm */
# define bool _Bool
diff --git a/include/ruby/internal/variable.h b/include/ruby/internal/variable.h
index 1f84b92db0..c017ffe3f7 100644
--- a/include/ruby/internal/variable.h
+++ b/include/ruby/internal/variable.h
@@ -147,7 +147,7 @@ RBIMPL_ATTR_NONNULL(())
* init_Foo(void)
* {
* foo = rb_eval_string("...");
- * rb_define_global_variable("$foo", &foo);
+ * rb_define_variable("$foo", &foo);
* }
* ```
*
diff --git a/include/ruby/io.h b/include/ruby/io.h
index c117087d6a..88029b1bb9 100644
--- a/include/ruby/io.h
+++ b/include/ruby/io.h
@@ -35,7 +35,11 @@
# undef revents
# endif
# define RB_WAITFD_IN POLLIN
-# define RB_WAITFD_PRI POLLPRI
+# if defined(POLLPRI)
+# define RB_WAITFD_PRI POLLPRI
+# else
+# define RB_WAITFD_PRI 0
+# endif
# define RB_WAITFD_OUT POLLOUT
#else
# define RB_WAITFD_IN 0x001
@@ -51,12 +55,23 @@
#include "ruby/internal/value.h"
#include "ruby/backward/2/attributes.h" /* PACKED_STRUCT_UNALIGNED */
+// IO#wait, IO#wait_readable, IO#wait_writable, IO#wait_priority are defined by this implementation.
+#define RUBY_IO_WAIT_METHODS
+
+// Used as the default timeout argument to `rb_io_wait` to use the `IO#timeout` value.
+#define RUBY_IO_TIMEOUT_DEFAULT Qnil
+
RBIMPL_SYMBOL_EXPORT_BEGIN()
struct stat;
struct timeval;
/**
+ * Indicates that a timeout has occurred while performing an IO operation.
+ */
+RUBY_EXTERN VALUE rb_eIOTimeoutError;
+
+/**
* Type of events that an IO can wait.
*
* @internal
@@ -91,6 +106,34 @@ PACKED_STRUCT_UNALIGNED(struct rb_io_buffer_t {
/** @alias{rb_io_buffer_t} */
typedef struct rb_io_buffer_t rb_io_buffer_t;
+/** Decomposed encoding flags (e.g. `"enc:enc2""`). */
+/*
+ * enc enc2 read action write action
+ * NULL NULL force_encoding(default_external) write the byte sequence of str
+ * e1 NULL force_encoding(e1) convert str.encoding to e1
+ * e1 e2 convert from e2 to e1 convert str.encoding to e2
+ */
+struct rb_io_enc_t {
+ /** Internal encoding. */
+ rb_encoding *enc;
+ /** External encoding. */
+ rb_encoding *enc2;
+ /**
+ * Flags.
+ *
+ * @see enum ::ruby_econv_flag_type
+ */
+ int ecflags;
+ /**
+ * Flags as Ruby hash.
+ *
+ * @internal
+ *
+ * This is set. But used from nowhere maybe?
+ */
+ VALUE ecopts;
+};
+
/** Ruby's IO, metadata and buffers. */
typedef struct rb_io_t {
@@ -134,36 +177,7 @@ typedef struct rb_io_t {
*/
VALUE tied_io_for_writing;
- /** Decomposed encoding flags (e.g. `"enc:enc2""`). */
- /*
- * enc enc2 read action write action
- * NULL NULL force_encoding(default_external) write the byte sequence of str
- * e1 NULL force_encoding(e1) convert str.encoding to e1
- * e1 e2 convert from e2 to e1 convert str.encoding to e2
- */
- struct rb_io_enc_t {
- /** Internal encoding. */
- rb_encoding *enc;
-
- /** External encoding. */
- rb_encoding *enc2;
-
- /**
- * Flags.
- *
- * @see enum ::ruby_econv_flag_type
- */
- int ecflags;
-
- /**
- * Flags as Ruby hash.
- *
- * @internal
- *
- * This is set. But used from nowhere maybe?
- */
- VALUE ecopts;
- } encs; /**< Decomposed encoding flags. */
+ struct rb_io_enc_t encs; /**< Decomposed encoding flags. */
/** Encoding converter used when reading from this IO. */
rb_econv_t *readconv;
@@ -208,6 +222,11 @@ typedef struct rb_io_t {
* 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;
} rb_io_t;
/** @alias{rb_io_enc_t} */
@@ -470,7 +489,7 @@ int rb_io_modestr_fmode(const char *modestr);
/**
* Identical to rb_io_modestr_fmode(), except it returns a mixture of `O_`
- * flags. This for instnce returns `O_WRONLY | O_TRUNC | O_CREAT | O_EXCL` for
+ * flags. This for instance returns `O_WRONLY | O_TRUNC | O_CREAT | O_EXCL` for
* `"wx"`.
*
* @param[in] modestr File mode, in C's string.
@@ -648,10 +667,23 @@ VALUE rb_io_get_write_io(VALUE io);
VALUE rb_io_set_write_io(VALUE io, VALUE w);
/**
- * Sets an IO to a "nonblock mode". This amends the way an IO operates so that
- * instead of waiting for rooms for read/write, it returns errors. In case of
- * multiplexed IO situations it can be vital for IO operations not to block.
- * This is the key API to achieve that property.
+ * Instructs the OS to put its internal file structure into "nonblocking mode".
+ * This is an in-Kernel concept. Reading from/writing to that file using C
+ * function calls would return -1 with errno set. However when it comes to a
+ * ruby program, we hide that error behind our `IO#read` method. Ruby level
+ * `IO#read` blocks regardless of this flag. If you want to avoid blocking,
+ * you should consider using methods like `IO#readpartial`.
+ *
+ * ```ruby
+ * require 'io/nonblock'
+ * STDIN.nonblock = true
+ * STDIN.gets # blocks.
+ * ```
+ *
+ * As of writing there is a room of this API in Fiber schedulers. A Fiber
+ * scheduler could be written in a way its behaviour depends on this property.
+ * You need an in-depth understanding of how schedulers work to properly
+ * leverage this, though.
*
* @note Note however that nonblocking-ness propagates across process
* boundaries. You must really carefully watch your step when turning
@@ -671,6 +703,15 @@ VALUE rb_io_set_write_io(VALUE io, VALUE w);
void rb_io_set_nonblock(rb_io_t *fptr);
/**
+ * Returns an integer representing the numeric file descriptor for
+ * <em>io</em>.
+ *
+ * @param[in] io An IO.
+ * @retval int A file descriptor.
+ */
+int rb_io_descriptor(VALUE io);
+
+/**
* This function breaks down the option hash that `IO#initialize` takes into
* components. This is an implementation detail of rb_io_extract_modeenc()
* today. People prefer that API instead.
@@ -735,8 +776,8 @@ int rb_io_extract_encoding_option(VALUE opt, rb_encoding **enc_p, rb_encoding **
* class File
* def initialize: (
* (String | int) path,
- * ?(Strig | int) fmode,
- * ?(Strig | int) perm,
+ * ?(String | int) fmode,
+ * ?(String | int) perm,
* ?mode: (String | int),
* ?flags: int,
* ?external_encoding: (Encoding | String),
@@ -817,13 +858,37 @@ int rb_io_wait_writable(int fd);
int rb_wait_for_single_fd(int fd, int events, struct timeval *tv);
/**
+ * Get the timeout associated with the specified io object.
+ *
+ * @param[in] io An IO object.
+ * @retval RUBY_Qnil There is no associated timeout.
+ * @retval Otherwise The timeout value.
+ */
+VALUE rb_io_timeout(VALUE io);
+
+/**
+ * Set the timeout associated with the specified io object. This timeout is
+ * used as a best effort timeout to prevent operations from blocking forever.
+ *
+ * @param[in] io An IO object.
+ * @param[in] timeout A timeout value. Must respond to #to_f.
+ * @
+ */
+VALUE rb_io_set_timeout(VALUE io, VALUE timeout);
+
+/**
* Blocks until the passed IO is ready for the passed events. The "events"
* here is a Ruby level integer, which is an OR-ed value of `IO::READABLE`,
* `IO::WRITable`, and `IO::PRIORITY`.
*
+ * If timeout is `Qnil`, it will use the default timeout as given by
+ * `rb_io_timeout(io)`.
+ *
* @param[in] io An IO object to wait.
* @param[in] events See above.
* @param[in] timeout Time, or numeric seconds since UNIX epoch.
+ * If Qnil, use the default timeout. If Qfalse
+ * or Qundef, wait forever.
* @exception rb_eIOError `io` is not open.
* @exception rb_eRangeError `timeout` is out of range.
* @exception rb_eSystemCallError `select(2)` failed for some reason.
@@ -875,13 +940,8 @@ VALUE rb_io_maybe_wait(int error, VALUE io, VALUE events, VALUE timeout);
* @exception rb_eIOError `io` is not open.
* @exception rb_eRangeError `timeout` is out of range.
* @exception rb_eSystemCallError `select(2)` failed for some reason.
- * @exception rb_eTypeError Operation timed out.
- * @return Always returns ::RUBY_IO_READABLE.
- *
- * @internal
- *
- * Because rb_io_maybe_wait() returns ::RUBY_Qfalse on timeout, this function
- * fails to convert that value to `int`, and raises ::rb_eTypeError.
+ * @retval 0 Operation timed out.
+ * @retval Otherwise Always returns ::RUBY_IO_READABLE.
*/
int rb_io_maybe_wait_readable(int error, VALUE io, VALUE timeout);
@@ -896,13 +956,8 @@ int rb_io_maybe_wait_readable(int error, VALUE io, VALUE timeout);
* @exception rb_eIOError `io` is not open.
* @exception rb_eRangeError `timeout` is out of range.
* @exception rb_eSystemCallError `select(2)` failed for some reason.
- * @exception rb_eTypeError Operation timed out.
- * @return Always returns ::RUBY_IO_WRITABLE.
- *
- * @internal
- *
- * Because rb_io_maybe_wait() returns ::RUBY_Qfalse on timeout, this function
- * fails to convert that value to `int`, and raises ::rb_eTypeError.
+ * @retval 0 Operation timed out.
+ * @retval Otherwise Always returns ::RUBY_IO_WRITABLE.
*/
int rb_io_maybe_wait_writable(int error, VALUE io, VALUE timeout);
diff --git a/include/ruby/io/buffer.h b/include/ruby/io/buffer.h
new file mode 100644
index 0000000000..e4b855d8e7
--- /dev/null
+++ b/include/ruby/io/buffer.h
@@ -0,0 +1,92 @@
+#ifndef RUBY_IO_BUFFER_H
+#define RUBY_IO_BUFFER_H
+/**
+ * @file
+ * @author Samuel Williams
+ * @date Fri 2 Jul 2021 16:29:01 NZST
+ * @copyright Copyright (C) 2021 Samuel Williams
+ * @copyright This file is a part of the programming language Ruby.
+ * Permission is hereby granted, to either redistribute and/or
+ * modify this file, provided that the conditions mentioned in the
+ * file COPYING are met. Consult the file for details.
+ */
+
+#pragma once
+
+#include "ruby/ruby.h"
+#include "ruby/internal/config.h"
+
+RBIMPL_SYMBOL_EXPORT_BEGIN()
+
+// WARNING: This entire interface is experimental and may change in the future!
+#define RB_IO_BUFFER_EXPERIMENTAL 1
+
+#define RUBY_IO_BUFFER_VERSION 2
+
+RUBY_EXTERN VALUE rb_cIOBuffer;
+RUBY_EXTERN size_t RUBY_IO_BUFFER_PAGE_SIZE;
+RUBY_EXTERN size_t RUBY_IO_BUFFER_DEFAULT_SIZE;
+
+enum rb_io_buffer_flags {
+ // The memory in the buffer is owned by someone else.
+ // More specifically, it means that someone else owns the buffer and we shouldn't try to resize it.
+ RB_IO_BUFFER_EXTERNAL = 1,
+ // The memory in the buffer is allocated internally.
+ RB_IO_BUFFER_INTERNAL = 2,
+ // The memory in the buffer is mapped.
+ // A non-private mapping is marked as external.
+ RB_IO_BUFFER_MAPPED = 4,
+
+ // A mapped buffer that is also shared.
+ RB_IO_BUFFER_SHARED = 8,
+
+ // The buffer is locked and cannot be resized.
+ // More specifically, it means we can't change the base address or size.
+ // A buffer is typically locked before a system call that uses the data.
+ RB_IO_BUFFER_LOCKED = 32,
+
+ // The buffer mapping is private and will not impact other processes or the underlying file.
+ RB_IO_BUFFER_PRIVATE = 64,
+
+ // The buffer is read-only and cannot be modified.
+ RB_IO_BUFFER_READONLY = 128
+};
+
+enum rb_io_buffer_endian {
+ RB_IO_BUFFER_LITTLE_ENDIAN = 4,
+ RB_IO_BUFFER_BIG_ENDIAN = 8,
+
+#if defined(WORDS_BIGENDIAN)
+ RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_BIG_ENDIAN,
+#else
+ RB_IO_BUFFER_HOST_ENDIAN = RB_IO_BUFFER_LITTLE_ENDIAN,
+#endif
+
+ RB_IO_BUFFER_NETWORK_ENDIAN = RB_IO_BUFFER_BIG_ENDIAN
+};
+
+VALUE rb_io_buffer_new(void *base, size_t size, enum rb_io_buffer_flags flags);
+VALUE rb_io_buffer_map(VALUE io, size_t size, rb_off_t offset, enum rb_io_buffer_flags flags);
+
+VALUE rb_io_buffer_lock(VALUE self);
+VALUE rb_io_buffer_unlock(VALUE self);
+int rb_io_buffer_try_unlock(VALUE self);
+VALUE rb_io_buffer_free(VALUE self);
+
+int rb_io_buffer_get_bytes(VALUE self, void **base, size_t *size);
+void rb_io_buffer_get_bytes_for_reading(VALUE self, const void **base, size_t *size);
+void rb_io_buffer_get_bytes_for_writing(VALUE self, void **base, size_t *size);
+
+VALUE rb_io_buffer_transfer(VALUE self);
+void rb_io_buffer_resize(VALUE self, size_t size);
+void rb_io_buffer_clear(VALUE self, uint8_t value, size_t offset, size_t length);
+
+// The length is the minimum required length.
+VALUE rb_io_buffer_read(VALUE self, VALUE io, size_t length, size_t offset);
+VALUE rb_io_buffer_pread(VALUE self, VALUE io, rb_off_t from, size_t length, size_t offset);
+VALUE rb_io_buffer_write(VALUE self, VALUE io, size_t length, size_t offset);
+VALUE rb_io_buffer_pwrite(VALUE self, VALUE io, rb_off_t from, size_t length, size_t offset);
+
+RBIMPL_SYMBOL_EXPORT_END()
+
+#endif /* RUBY_IO_BUFFER_H */
diff --git a/include/ruby/memory_view.h b/include/ruby/memory_view.h
index bac49e363e..1ddca2d46f 100644
--- a/include/ruby/memory_view.h
+++ b/include/ruby/memory_view.h
@@ -16,7 +16,7 @@
# include <stddef.h> /* size_t */
#endif
-#if HAVE_SYS_TYPES_H
+#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h> /* ssize_t */
#endif
@@ -146,8 +146,11 @@ typedef struct {
* Or, NULL when this memory view exposes a flat array. */
const ssize_t *sub_offsets;
- /** the private data for managing this exported memory */
+ /** The private data for managing this exported memory */
void *private_data;
+
+ /** DO NOT TOUCH THIS: The memory view entry for the internal use */
+ const struct rb_memory_view_entry *_memory_view_entry;
} rb_memory_view_t;
/** Type of function of ::rb_memory_view_entry_t::get_func. */
@@ -160,9 +163,10 @@ typedef bool (* rb_memory_view_release_func_t)(VALUE obj, rb_memory_view_t *view
typedef bool (* rb_memory_view_available_p_func_t)(VALUE obj);
/** Operations applied to a specific kind of a memory view. */
-typedef struct {
-
- /** Exports a memory view from a Ruby object. */
+typedef struct rb_memory_view_entry {
+ /**
+ * Exports a memory view from a Ruby object.
+ */
rb_memory_view_get_func_t get_func;
/**
diff --git a/include/ruby/missing.h b/include/ruby/missing.h
index 1e97e294f1..aea6c9088d 100644
--- a/include/ruby/missing.h
+++ b/include/ruby/missing.h
@@ -33,6 +33,18 @@
# include <sys/time.h>
#endif
+#ifdef HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_STDIO_H
+# include <stdio.h>
+#endif
+
#ifdef HAVE_IEEEFP_H
# include <ieeefp.h>
#endif
@@ -224,6 +236,107 @@ RUBY_EXTERN void setproctitle(const char *fmt, ...);
RUBY_EXTERN void explicit_bzero(void *b, size_t len);
#endif
+#ifndef HAVE_TZSET
+RUBY_EXTERN void tzset(void);
+#endif
+
+#ifndef HAVE_POSIX_MADVISE
+RUBY_EXTERN int posix_madvise(void *, size_t, int);
+#endif
+
+#ifndef HAVE_GETEUID
+RUBY_EXTERN rb_uid_t geteuid(void);
+#endif
+
+#ifndef HAVE_GETUID
+RUBY_EXTERN rb_uid_t getuid(void);
+#endif
+
+#ifndef HAVE_GETEGID
+RUBY_EXTERN rb_gid_t getegid(void);
+#endif
+
+#ifndef HAVE_GETGID
+RUBY_EXTERN rb_gid_t getgid(void);
+#endif
+
+#ifndef HAVE_GETLOGIN
+RUBY_EXTERN char *getlogin(void);
+#endif
+
+#ifndef HAVE_GETPPID
+RUBY_EXTERN rb_pid_t getppid(void);
+#endif
+
+#ifndef HAVE_UMASK
+RUBY_EXTERN rb_mode_t umask(rb_mode_t);
+#endif
+
+#ifndef HAVE_CHMOD
+RUBY_EXTERN int chmod(const char *, rb_mode_t);
+#endif
+
+#ifndef HAVE_CHOWN
+RUBY_EXTERN int chown(const char *, rb_uid_t, rb_gid_t);
+#endif
+
+#ifndef HAVE_PCLOSE
+RUBY_EXTERN int pclose(FILE *);
+#endif
+
+#ifndef HAVE_POPEN
+RUBY_EXTERN FILE *popen(const char *, const char *);
+#endif
+
+#ifndef HAVE_PIPE
+RUBY_EXTERN int pipe(int [2]);
+#endif
+
+#ifndef HAVE_DUP
+RUBY_EXTERN int dup(int);
+#endif
+
+#ifndef HAVE_DUP2
+RUBY_EXTERN int dup2(int, int);
+#endif
+
+#ifndef HAVE_KILL
+RUBY_EXTERN int kill(rb_pid_t, int);
+#endif
+
+#ifndef HAVE_EXECL
+RUBY_EXTERN int execl(const char *, const char *, ...);
+#endif
+
+#ifndef HAVE_EXECLE
+RUBY_EXTERN int execle(const char *, const char *, ...);
+#endif
+
+#ifndef HAVE_EXECV
+RUBY_EXTERN int execv(const char *, char *const []);
+#endif
+
+#ifndef HAVE_EXECVE
+RUBY_EXTERN int execve(const char *, char *const [], char *const []);
+#endif
+
+#ifndef HAVE_SHUTDOWN
+RUBY_EXTERN int shutdown(int, int);
+#endif
+
+#ifndef HAVE_SYSTEM
+RUBY_EXTERN int system(const char *);
+#endif
+
+#ifndef WNOHANG
+# define WNOHANG 0
+#endif
+
+#ifndef HAVE_WAITPID
+# define HAVE_WAITPID 1
+RUBY_EXTERN rb_pid_t waitpid(rb_pid_t, int *, int);
+#endif
+
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_MISSING_H */
diff --git a/include/ruby/onigmo.h b/include/ruby/onigmo.h
index 6187b37dc3..8d7c601703 100644
--- a/include/ruby/onigmo.h
+++ b/include/ruby/onigmo.h
@@ -356,9 +356,9 @@ int onigenc_ascii_only_case_map(OnigCaseFoldType* flagP, const OnigUChar** pp, c
#define ONIGENC_PRECISE_MBC_ENC_LEN(enc,p,e) (enc)->precise_mbc_enc_len(p,e,enc)
ONIG_EXTERN
-int onigenc_mbclen_approximate(const OnigUChar* p,const OnigUChar* e, const struct OnigEncodingTypeST* enc);
+int onigenc_mbclen(const OnigUChar* p,const OnigUChar* e, const struct OnigEncodingTypeST* enc);
-#define ONIGENC_MBC_ENC_LEN(enc,p,e) onigenc_mbclen_approximate(p,e,enc)
+#define ONIGENC_MBC_ENC_LEN(enc,p,e) onigenc_mbclen(p,e,enc)
#define ONIGENC_MBC_MAXLEN(enc) ((enc)->max_enc_len)
#define ONIGENC_MBC_MAXLEN_DIST(enc) ONIGENC_MBC_MAXLEN(enc)
#define ONIGENC_MBC_MINLEN(enc) ((enc)->min_enc_len)
@@ -744,6 +744,8 @@ typedef struct {
typedef struct {
int lower;
int upper;
+ long base_num;
+ long inner_num;
} OnigRepeatRange;
typedef void (*OnigWarnFunc)(const char* s);
@@ -793,6 +795,13 @@ typedef struct re_pattern_buffer {
OnigDistance dmin; /* min-distance of exact or map */
OnigDistance dmax; /* max-distance of exact or map */
+ /* rb_hrtime_t from hrtime.h */
+#ifdef MY_RUBY_BUILD_MAY_TIME_TRAVEL
+ int128_t timelimit;
+#else
+ uint64_t timelimit;
+#endif
+
/* regex_t link chain */
struct re_pattern_buffer* chain; /* escape compile-conflict */
} OnigRegexType;
@@ -845,6 +854,8 @@ OnigPosition onig_search_gpos(OnigRegex, const OnigUChar* str, const OnigUChar*
ONIG_EXTERN
OnigPosition onig_match(OnigRegex, const OnigUChar* str, const OnigUChar* end, const OnigUChar* at, OnigRegion* region, OnigOptionType option);
ONIG_EXTERN
+int onig_check_linear_time(OnigRegex reg);
+ONIG_EXTERN
OnigRegion* onig_region_new(void);
ONIG_EXTERN
void onig_region_init(OnigRegion* region);
diff --git a/include/ruby/ractor.h b/include/ruby/ractor.h
index 687ddcadec..7811616f6d 100644
--- a/include/ruby/ractor.h
+++ b/include/ruby/ractor.h
@@ -145,7 +145,7 @@ bool rb_ractor_local_storage_value_lookup(rb_ractor_local_key_t key, VALUE *val)
* Associates the passed value to the passed key.
*
* @param[in] key A ractor-local storage key.
- * @param[in] val Arbitary ruby object.
+ * @param[in] val Arbitrary ruby object.
* @post `val` corresponds to `key` in the current Ractor.
*/
void rb_ractor_local_storage_value_set(rb_ractor_local_key_t key, VALUE val);
diff --git a/include/ruby/random.h b/include/ruby/random.h
index 657b37f034..39bdb6f3e3 100644
--- a/include/ruby/random.h
+++ b/include/ruby/random.h
@@ -16,6 +16,26 @@
#include "ruby/ruby.h"
+/*
+ * version
+ * 0: before versioning; deprecated
+ * 1: added version, flags and init_32bit function
+ */
+#define RUBY_RANDOM_INTERFACE_VERSION_MAJOR 1
+#define RUBY_RANDOM_INTERFACE_VERSION_MINOR 0
+
+#define RUBY_RANDOM_PASTE_VERSION_SUFFIX(x, y, z) x##_##y##_##z
+#define RUBY_RANDOM_WITH_VERSION_SUFFIX(name, major, minor) \
+ RUBY_RANDOM_PASTE_VERSION_SUFFIX(name, major, minor)
+#define rb_random_data_type \
+ RUBY_RANDOM_WITH_VERSION_SUFFIX(rb_random_data_type, \
+ RUBY_RANDOM_INTERFACE_VERSION_MAJOR, \
+ RUBY_RANDOM_INTERFACE_VERSION_MINOR)
+#define RUBY_RANDOM_INTERFACE_VERSION_INITIALIZER \
+ {RUBY_RANDOM_INTERFACE_VERSION_MAJOR, RUBY_RANDOM_INTERFACE_VERSION_MINOR}
+#define RUBY_RANDOM_INTERFACE_VERSION_MAJOR_MAX 0xff
+#define RUBY_RANDOM_INTERFACE_VERSION_MINOR_MAX 0xff
+
RBIMPL_SYMBOL_EXPORT_BEGIN()
/**
@@ -48,6 +68,17 @@ typedef void rb_random_init_func(rb_random_t *rng, const uint32_t *buf, size_t l
RBIMPL_ATTR_NONNULL(())
/**
+ * This is the type of functions called when your random object is initialised.
+ * Passed data is the seed integer.
+ *
+ * @param[out] rng Your random struct to fill in.
+ * @param[in] data Seed, single word.
+ * @post `rng` is initialised using the passed seeds.
+ */
+typedef void rb_random_init_int32_func(rb_random_t *rng, uint32_t data);
+
+RBIMPL_ATTR_NONNULL(())
+/**
* This is the type of functions called from your object's `#rand` method.
*
* @param[out] rng Your random struct to extract an integer from.
@@ -84,9 +115,24 @@ typedef struct {
/** Number of bits of seed numbers. */
size_t default_seed_bits;
- /** Initialiser function. */
+ /**
+ * Major/minor versions of this interface
+ */
+ struct {
+ uint8_t major, minor;
+ } version;
+
+ /**
+ * Reserved flags
+ */
+ uint16_t flags;
+
+ /** Function to initialize from uint32_t array. */
rb_random_init_func *init;
+ /** Function to initialize from single uint32_t. */
+ rb_random_init_int32_func *init_int32;
+
/** Function to obtain a random integer. */
rb_random_get_int32_func *get_int32;
@@ -130,11 +176,12 @@ typedef struct {
} rb_random_interface_t;
/**
- * This utility macro defines 3 functions named prefix_init, prefix_get_int32,
- * prefix_get_bytes.
+ * This utility macro defines 4 functions named prefix_init, prefix_init_int32,
+ * prefix_get_int32, prefix_get_bytes.
*/
#define RB_RANDOM_INTERFACE_DECLARE(prefix) \
static void prefix##_init(rb_random_t *, const uint32_t *, size_t); \
+ static void prefix##_init_int32(rb_random_t *, uint32_t); \
static unsigned int prefix##_get_int32(rb_random_t *); \
static void prefix##_get_bytes(rb_random_t *, void *, size_t)
@@ -161,7 +208,9 @@ typedef struct {
* ```
*/
#define RB_RANDOM_INTERFACE_DEFINE(prefix) \
+ RUBY_RANDOM_INTERFACE_VERSION_INITIALIZER, 0, \
prefix##_init, \
+ prefix##_init_int32, \
prefix##_get_int32, \
prefix##_get_bytes
@@ -173,6 +222,12 @@ typedef struct {
RB_RANDOM_INTERFACE_DEFINE(prefix), \
prefix##_get_real
+#define RB_RANDOM_DEFINE_INIT_INT32_FUNC(prefix) \
+ static void prefix##_init_int32(rb_random_t *rnd, uint32_t data) \
+ { \
+ prefix##_init(rnd, &data, 1); \
+ }
+
#if defined _WIN32 && !defined __CYGWIN__
typedef rb_data_type_t rb_random_data_type_t;
# define RB_RANDOM_PARENT 0
@@ -189,7 +244,7 @@ typedef const rb_data_type_t rb_random_data_type_t;
* 0, RB_RANDOM_INTERFACE_DEFINE(your),
* };
*
- * static inline constexpr your_prng = {
+ * static inline constexpr rb_random_data_type_t your_prng_type = {
* "your PRNG",
* { rb_random_mark, },
* RB_RANDOM_PARENT, // <<-- HERE
diff --git a/include/ruby/ruby.h b/include/ruby/ruby.h
index f35d13685c..444940ca3a 100644
--- a/include/ruby/ruby.h
+++ b/include/ruby/ruby.h
@@ -23,6 +23,7 @@
#include <stdarg.h>
#include "defines.h"
+#include "ruby/internal/abi.h"
#include "ruby/internal/anyargs.h"
#include "ruby/internal/arithmetic.h"
#include "ruby/internal/core.h"
@@ -107,7 +108,7 @@ VALUE rb_get_path_no_checksafe(VALUE);
# define rb_varargs_argc_check_runtime(argc, vargc) \
(((argc) <= (vargc)) ? (argc) : \
(rb_fatal("argc(%d) exceeds actual arguments(%d)", \
- argc, vargc), 0))
+ argc, vargc), 0))
# define rb_varargs_argc_valid_p(argc, vargc) \
((argc) == 0 ? (vargc) <= 1 : /* [ruby-core:85266] [Bug #14425] */ \
(argc) == (vargc))
@@ -116,16 +117,16 @@ VALUE rb_get_path_no_checksafe(VALUE);
ERRORFUNC((" argument length doesn't match"), int rb_varargs_bad_length(int,int));
# else
# define rb_varargs_bad_length(argc, vargc) \
- ((argc)/rb_varargs_argc_valid_p(argc, vargc))
+ ((argc)/rb_varargs_argc_valid_p(argc, vargc))
# endif
# define rb_varargs_argc_check(argc, vargc) \
__builtin_choose_expr(__builtin_constant_p(argc), \
- (rb_varargs_argc_valid_p(argc, vargc) ? (argc) : \
- rb_varargs_bad_length(argc, vargc)), \
- rb_varargs_argc_check_runtime(argc, vargc))
+ (rb_varargs_argc_valid_p(argc, vargc) ? (argc) : \
+ rb_varargs_bad_length(argc, vargc)), \
+ rb_varargs_argc_check_runtime(argc, vargc))
# else
# define rb_varargs_argc_check(argc, vargc) \
- rb_varargs_argc_check_runtime(argc, vargc)
+ rb_varargs_argc_check_runtime(argc, vargc)
# endif
#endif
/** @endcond */
@@ -276,24 +277,24 @@ int ruby_vsnprintf(char *str, size_t n, char const *fmt, va_list ap);
#elif defined(__GNUC__) && defined(HAVE_VA_ARGS_MACRO) && defined(__OPTIMIZE__)
# define rb_yield_values(argc, ...) \
__extension__({ \
- const int rb_yield_values_argc = (argc); \
- const VALUE rb_yield_values_args[] = {__VA_ARGS__}; \
- const int rb_yield_values_nargs = \
- (int)(sizeof(rb_yield_values_args) / sizeof(VALUE)); \
- rb_yield_values2( \
- rb_varargs_argc_check(rb_yield_values_argc, rb_yield_values_nargs), \
- rb_yield_values_nargs ? rb_yield_values_args : NULL); \
+ const int rb_yield_values_argc = (argc); \
+ const VALUE rb_yield_values_args[] = {__VA_ARGS__}; \
+ const int rb_yield_values_nargs = \
+ (int)(sizeof(rb_yield_values_args) / sizeof(VALUE)); \
+ rb_yield_values2( \
+ rb_varargs_argc_check(rb_yield_values_argc, rb_yield_values_nargs), \
+ rb_yield_values_nargs ? rb_yield_values_args : NULL); \
})
# define rb_funcall(recv, mid, argc, ...) \
__extension__({ \
- const int rb_funcall_argc = (argc); \
- const VALUE rb_funcall_args[] = {__VA_ARGS__}; \
- const int rb_funcall_nargs = \
- (int)(sizeof(rb_funcall_args) / sizeof(VALUE)); \
+ const int rb_funcall_argc = (argc); \
+ const VALUE rb_funcall_args[] = {__VA_ARGS__}; \
+ const int rb_funcall_nargs = \
+ (int)(sizeof(rb_funcall_args) / sizeof(VALUE)); \
rb_funcallv(recv, mid, \
- rb_varargs_argc_check(rb_funcall_argc, rb_funcall_nargs), \
- rb_funcall_nargs ? rb_funcall_args : NULL); \
+ rb_varargs_argc_check(rb_funcall_argc, rb_funcall_nargs), \
+ rb_funcall_nargs ? rb_funcall_args : NULL); \
})
#endif
/** @endcond */
diff --git a/include/ruby/st.h b/include/ruby/st.h
index 1e4bb80686..f35ab43603 100644
--- a/include/ruby/st.h
+++ b/include/ruby/st.h
@@ -98,6 +98,8 @@ struct st_table {
enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE, ST_CHECK, ST_REPLACE};
+size_t rb_st_table_size(const struct st_table *tbl);
+#define st_table_size rb_st_table_size
st_table *rb_st_init_table(const struct st_hash_type *);
#define st_init_table rb_st_init_table
st_table *rb_st_init_table_with_size(const struct st_hash_type *, st_index_t);
diff --git a/include/ruby/thread.h b/include/ruby/thread.h
index 18c792b386..0b5b1ca0f3 100644
--- a/include/ruby/thread.h
+++ b/include/ruby/thread.h
@@ -128,7 +128,7 @@ RBIMPL_ATTR_NONNULL((1))
* your code to see if it is actually worth releasing the GVL.
*/
void *rb_thread_call_without_gvl(void *(*func)(void *), void *data1,
- rb_unblock_function_t *ubf, void *data2);
+ rb_unblock_function_t *ubf, void *data2);
RBIMPL_ATTR_NONNULL((1))
/**
@@ -152,7 +152,7 @@ RBIMPL_ATTR_NONNULL((1))
* @return What `func` returned, or 0 in case `func` did not return.
*/
void *rb_thread_call_without_gvl2(void *(*func)(void *), void *data1,
- rb_unblock_function_t *ubf, void *data2);
+ rb_unblock_function_t *ubf, void *data2);
/*
* XXX: unstable/unapproved - out-of-tree code should NOT not depend
@@ -190,6 +190,46 @@ void *rb_nogvl(void *(*func)(void *), void *data1,
*/
#define RUBY_CALL_WO_GVL_FLAG_SKIP_CHECK_INTS_
+#define RUBY_INTERNAL_THREAD_EVENT_STARTED 1 << 0 /** thread started */
+#define RUBY_INTERNAL_THREAD_EVENT_READY 1 << 1 /** acquiring GVL */
+#define RUBY_INTERNAL_THREAD_EVENT_RESUMED 1 << 2 /** acquired GVL */
+#define RUBY_INTERNAL_THREAD_EVENT_SUSPENDED 1 << 3 /** released GVL */
+#define RUBY_INTERNAL_THREAD_EVENT_EXITED 1 << 4 /** thread terminated */
+#define RUBY_INTERNAL_THREAD_EVENT_MASK 0xff /** All Thread events */
+
+typedef void rb_internal_thread_event_data_t; // for future extension.
+
+typedef void (*rb_internal_thread_event_callback)(rb_event_flag_t event,
+ const rb_internal_thread_event_data_t *event_data,
+ void *user_data);
+typedef struct rb_internal_thread_event_hook rb_internal_thread_event_hook_t;
+
+/**
+ * Registers a thread event hook function.
+ *
+ * @param[in] func A callback.
+ * @param[in] events A set of events that `func` should run.
+ * @param[in] data Passed as-is to `func`.
+ * @return An opaque pointer to the hook, to unregister it later.
+ * @note This functionality is a noop on Windows.
+ * @warning This function MUST not be called from a thread event callback.
+ */
+rb_internal_thread_event_hook_t *rb_internal_thread_add_event_hook(
+ rb_internal_thread_event_callback func, rb_event_flag_t events,
+ void *data);
+
+
+/**
+ * Unregister the passed hook.
+ *
+ * @param[in] hook. The hook to unregister.
+ * @return Wether the hook was found and unregistered.
+ * @note This functionality is a noop on Windows.
+ * @warning This function MUST not be called from a thread event callback.
+*/
+bool rb_internal_thread_remove_event_hook(
+ rb_internal_thread_event_hook_t * hook);
+
RBIMPL_SYMBOL_EXPORT_END()
#endif /* RUBY_THREAD_H */
diff --git a/include/ruby/thread_native.h b/include/ruby/thread_native.h
index 2945ff1e4d..c23b15e133 100644
--- a/include/ruby/thread_native.h
+++ b/include/ruby/thread_native.h
@@ -37,6 +37,12 @@ typedef pthread_t rb_nativethread_id_t;
typedef pthread_mutex_t rb_nativethread_lock_t;
typedef pthread_cond_t rb_nativethread_cond_t;
+#elif defined(__wasi__) // no-thread platforms
+
+typedef struct rb_nativethread_id_t *rb_nativethread_id_t;
+typedef struct rb_nativethread_lock_t *rb_nativethread_lock_t;
+typedef struct rb_nativethread_cond_t *rb_nativethread_cond_t;
+
#elif defined(__DOXYGEN__)
/** Opaque type that holds an ID of a native thread. */
diff --git a/include/ruby/util.h b/include/ruby/util.h
index b2bc1a09f6..e8727a3200 100644
--- a/include/ruby/util.h
+++ b/include/ruby/util.h
@@ -19,7 +19,7 @@
# include <stddef.h> /* size_t */
#endif
-#if HAVE_SYS_TYPES_H
+#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h> /* ssize_t */
#endif
@@ -124,7 +124,7 @@ unsigned long ruby_scan_hex(const char *str, size_t len, size_t *ret);
# define ruby_qsort qsort_r
#else
void ruby_qsort(void *, const size_t, const size_t,
- int (*)(const void *, const void *, void *), void *);
+ int (*)(const void *, const void *, void *), void *);
#endif
RBIMPL_ATTR_NONNULL((1))
diff --git a/include/ruby/version.h b/include/ruby/version.h
index 104f78a0c6..18b3abc8d7 100644
--- a/include/ruby/version.h
+++ b/include/ruby/version.h
@@ -67,7 +67,7 @@
* Minor version. As of writing this version changes annually. Greater
* version doesn't mean "better"; they just mean years passed.
*/
-#define RUBY_API_VERSION_MINOR 1
+#define RUBY_API_VERSION_MINOR 2
/**
* Teeny version. This digit is kind of reserved these days. Kept 0 for the
@@ -137,7 +137,8 @@ RUBY_EXTERN const int ruby_patchlevel;
/**
* This is what `ruby -v` prints to the standard error. Something like:
- * `"ruby 2.5.9p229 (2021-04-05 revision 67829) [x86_64-linux]"`
+ * `"ruby 2.5.9p229 (2021-04-05 revision 67829) [x86_64-linux]"`. This doesn't
+ * include runtime options like a JIT being enabled.
*/
RUBY_EXTERN const char ruby_description[];
diff --git a/include/ruby/win32.h b/include/ruby/win32.h
index c8ae599f2f..197eb8a802 100644
--- a/include/ruby/win32.h
+++ b/include/ruby/win32.h
@@ -19,11 +19,6 @@ RUBY_SYMBOL_EXPORT_BEGIN
*/
/*
- * Definitions for NT port of Perl
- */
-
-
-/*
* Ok now we can include the normal include files.
*/
@@ -155,10 +150,14 @@ typedef int clockid_t;
#define read(f, b, s) rb_w32_read(f, b, s)
#define write(f, b, s) rb_w32_write(f, b, s)
#define getpid() rb_w32_getpid()
+#undef HAVE_GETPPID
+#define HAVE_GETPPID 1
#define getppid() rb_w32_getppid()
#define sleep(x) rb_w32_Sleep((x)*1000)
#define Sleep(msec) (void)rb_w32_Sleep(msec)
+#undef HAVE_EXECV
+#define HAVE_EXECV 1
#undef execv
#define execv(path,argv) rb_w32_uaspawn(P_OVERLAY,path,argv)
#undef isatty
@@ -191,7 +190,6 @@ struct stati128 {
long st_ctimensec;
};
-#define off_t __int64
#define stat stati128
#undef SIZEOF_STRUCT_STAT_ST_INO
#define SIZEOF_STRUCT_STAT_ST_INO sizeof(unsigned __int64)
@@ -299,7 +297,6 @@ extern DWORD rb_w32_osver(void);
extern int rb_w32_uchown(const char *, int, int);
extern int rb_w32_ulink(const char *, const char *);
extern ssize_t rb_w32_ureadlink(const char *, char *, size_t);
-extern ssize_t rb_w32_wreadlink(const WCHAR *, WCHAR *, size_t);
extern int rb_w32_usymlink(const char *src, const char *link);
extern int gettimeofday(struct timeval *, struct timezone *);
extern int clock_gettime(clockid_t, struct timespec *);
@@ -309,7 +306,9 @@ extern rb_pid_t wait(int *);
extern rb_pid_t rb_w32_uspawn(int, const char *, const char*);
extern rb_pid_t rb_w32_uaspawn(int, const char *, char *const *);
extern rb_pid_t rb_w32_uaspawn_flags(int, const char *, char *const *, DWORD);
-extern int kill(int, int);
+#undef HAVE_KILL
+#define HAVE_KILL 1
+extern int kill(rb_pid_t, int);
extern int fcntl(int, int, ...);
extern int rb_w32_set_nonblock(int);
extern rb_pid_t rb_w32_getpid(void);
@@ -388,6 +387,7 @@ scalb(double a, long b)
#endif
#define S_IFLNK 0xa000
+#define S_IFSOCK 0xc000
/*
* define this so we can do inplace editing
@@ -395,9 +395,9 @@ scalb(double a, long b)
#define SUFFIX
-extern int rb_w32_ftruncate(int fd, off_t length);
-extern int rb_w32_truncate(const char *path, off_t length);
-extern int rb_w32_utruncate(const char *path, off_t length);
+extern int rb_w32_ftruncate(int fd, rb_off_t length);
+extern int rb_w32_truncate(const char *path, rb_off_t length);
+extern int rb_w32_utruncate(const char *path, rb_off_t length);
#undef HAVE_FTRUNCATE
#define HAVE_FTRUNCATE 1
@@ -647,6 +647,8 @@ extern char *rb_w32_strerror(int);
#undef setsockopt
#define setsockopt(s, v, n, o, l) rb_w32_setsockopt(s, v, n, o, l)
+#undef HAVE_SHUTDOWN
+#define HAVE_SHUTDOWN 1
#undef shutdown
#define shutdown(s, h) rb_w32_shutdown(s, h)
@@ -694,10 +696,10 @@ extern char *rb_w32_strerror(int);
#endif
struct tms {
- long tms_utime;
- long tms_stime;
- long tms_cutime;
- long tms_cstime;
+ long tms_utime;
+ long tms_stime;
+ long tms_cutime;
+ long tms_cstime;
};
int rb_w32_times(struct tms *);
@@ -714,7 +716,7 @@ int rb_w32_fclose(FILE*);
int rb_w32_pipe(int[2]);
ssize_t rb_w32_read(int, void *, size_t);
ssize_t rb_w32_write(int, const void *, size_t);
-off_t rb_w32_lseek(int, off_t, int);
+rb_off_t rb_w32_lseek(int, rb_off_t, int);
int rb_w32_uutime(const char *, const struct utimbuf *);
int rb_w32_uutimes(const char *, const struct timeval *);
int rb_w32_uutimensat(int /* must be AT_FDCWD */, const char *, const struct timespec *, int /* must be 0 */);
@@ -796,6 +798,25 @@ double rb_w32_pow(double x, double y);
#define pow rb_w32_pow
#endif
+// mmap tiny emulation
+#define MAP_FAILED ((void *)-1)
+
+#define PROT_READ 0x01
+#define PROT_WRITE 0x02
+#define PROT_EXEC 0x04
+
+#define MAP_PRIVATE 0x0002
+#define MAP_ANON 0x1000
+#define MAP_ANONYMOUS MAP_ANON
+
+extern void *rb_w32_mmap(void *, size_t, int, int, int, rb_off_t);
+extern int rb_w32_munmap(void *, size_t);
+extern int rb_w32_mprotect(void *, size_t, int);
+
+#define mmap(a, l, p, f, d, o) rb_w32_mmap(a, l, p, f, d, o)
+#define munmap(a, l) rb_w32_munmap(a, l)
+#define mprotect(a, l, prot) rb_w32_mprotect(a, l, prot)
+
#if defined(__cplusplus)
#if 0
{ /* satisfy cc-mode */