From 1e666eae3b76b0b2ec78bb15061700b4d57e3f39 Mon Sep 17 00:00:00 2001 From: Jonathan Ringer Date: Mon, 23 Feb 2026 11:27:36 -0800 Subject: [PATCH 1/6] ext: fixes for Clang 21 --- ext/mruby_engine/host.c | 1 + mruby_engine.gemspec | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ext/mruby_engine/host.c b/ext/mruby_engine/host.c index 055e742a9..5878daceb 100644 --- a/ext/mruby_engine/host.c +++ b/ext/mruby_engine/host.c @@ -4,6 +4,7 @@ #include #include #include +#include #include const intptr_t ME_HOST_NIL = Qnil; diff --git a/mruby_engine.gemspec b/mruby_engine.gemspec index c1e651b4c..c14abb82f 100644 --- a/mruby_engine.gemspec +++ b/mruby_engine.gemspec @@ -48,8 +48,8 @@ Gem::Specification.new do |spec| spec.add_runtime_dependency "getoptlong" spec.add_development_dependency "bundler", ">= 1.6" - spec.add_development_dependency "rake", "~> 10.4" - spec.add_development_dependency "rake-compiler", "~> 0.9" + spec.add_development_dependency "rake", ">= 12.0" + spec.add_development_dependency "rake-compiler", ">= 1.2" spec.add_development_dependency "rspec", "~> 3.3" spec.add_development_dependency "pry", "~> 0.10.0" spec.add_development_dependency "pry-byebug", "~> 3.1" From 4275d66e8ed06fa066970725678be62228e70cfe Mon Sep 17 00:00:00 2001 From: Jonathan Ringer Date: Mon, 23 Feb 2026 14:30:00 -0800 Subject: [PATCH 2/6] Updates for clang21, ruby 3.4.5, and newer rake --- .gitignore | 2 ++ .gitmodules | 2 +- ext/mruby_engine/mruby | 2 +- ext/mruby_engine/mruby-mpdecimal/src/ext.c | 4 +++- ext/mruby_engine/mruby-mpdecimal/tests/Makefile | 4 ++-- ext/mruby_engine/mruby_engine.c | 8 ++++---- ext/mruby_engine/value_guest.c | 15 +++++++-------- mruby_engine.gemspec | 1 + spec/arbitrary.rb | 6 +++--- spec/mruby_engine_spec.rb | 8 ++++---- spec/time_spec.rb | 2 +- 11 files changed, 29 insertions(+), 25 deletions(-) diff --git a/.gitignore b/.gitignore index ebe20fa85..dd7e55ada 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ mkmf.log /ext/mruby_engine/mruby-mpdecimal/tests/runtest /ext/mruby_engine/mruby-mpdecimal/tests/runtest_alloc + +mruby_config.rb.lock diff --git a/.gitmodules b/.gitmodules index b332c546e..f053377b3 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,4 +1,4 @@ [submodule "ext/mruby_engine/mruby"] path = ext/mruby_engine/mruby url = https://github.com/Shopify/mruby.git - branch = mruby-engine-submodule + branch = jringer/better-distinguish-clang diff --git a/ext/mruby_engine/mruby b/ext/mruby_engine/mruby index 8f6b22b53..ad8eb41e6 160000 --- a/ext/mruby_engine/mruby +++ b/ext/mruby_engine/mruby @@ -1 +1 @@ -Subproject commit 8f6b22b53d0a11f4f1146cbc6de372ed8126e1b8 +Subproject commit ad8eb41e668043b5c8ef56bbd864460714acad70 diff --git a/ext/mruby_engine/mruby-mpdecimal/src/ext.c b/ext/mruby_engine/mruby-mpdecimal/src/ext.c index c231e5c6d..1e92d9e8b 100644 --- a/ext/mruby_engine/mruby-mpdecimal/src/ext.c +++ b/ext/mruby_engine/mruby-mpdecimal/src/ext.c @@ -267,11 +267,13 @@ void mrb_mruby_mpdecimal_gem_init(mrb_state *state) { struct RClass *c_decimal = mrb_define_class(state, "Decimal", state->object_class); MRB_SET_INSTANCE_TT(c_decimal, MRB_TT_DATA); + mrb_method_t method; + MRB_METHOD_FROM_PROC(method, mrb_proc_new_cfunc_with_env(state, ext_decimal_initialize, 1, &context)); mrb_define_method_raw( state, c_decimal, mrb_intern_cstr(state, "initialize"), - mrb_proc_new_cfunc_with_env(state, ext_decimal_initialize, 1, &context)); + method); mrb_define_method(state, c_decimal, "+", ext_decimal_add, MRB_ARGS_REQ(1)); mrb_define_method(state, c_decimal, "-", ext_decimal_sub, MRB_ARGS_REQ(1)); mrb_define_method(state, c_decimal, "*", ext_decimal_mul, MRB_ARGS_REQ(1)); diff --git a/ext/mruby_engine/mruby-mpdecimal/tests/Makefile b/ext/mruby_engine/mruby-mpdecimal/tests/Makefile index 6591a67da..f9bd07918 100644 --- a/ext/mruby_engine/mruby-mpdecimal/tests/Makefile +++ b/ext/mruby_engine/mruby-mpdecimal/tests/Makefile @@ -5,9 +5,9 @@ LD = gcc AR = ar MPD_WARN = -Wall -W -Wno-unknown-pragmas -std=c99 -pedantic -MPD_CONFIG = -DCONFIG_64 -DASM +MPD_CONFIG = -DCONFIG_64 -DANSI -DHAVE_UINT128_T -CONFIGURE_CFLAGS = -ggdb -Wall -W -Wno-unknown-pragmas -std=c99 -pedantic -DCONFIG_64 -DASM -O0 +CONFIGURE_CFLAGS = -ggdb -Wall -W -Wno-unknown-pragmas -std=c99 -pedantic -DCONFIG_64 -DANSI -DHAVE_UINT128_T -O0 CFLAGS ?= $(CONFIGURE_CFLAGS) HEADERS = $(wildcard $(SRCDIR)/*.h) diff --git a/ext/mruby_engine/mruby_engine.c b/ext/mruby_engine/mruby_engine.c index 60d448029..020e0fe5c 100644 --- a/ext/mruby_engine/mruby_engine.c +++ b/ext/mruby_engine/mruby_engine.c @@ -102,7 +102,7 @@ me_host_exception_t me_mruby_engine_get_exception(struct me_mruby_engine *self) intptr_t host_backtrace = me_host_backtrace_new(); mrb_value backtrace = mrb_exc_backtrace(self->state, exception); - mrb_int backtrace_len = mrb_ary_len(self->state, backtrace); + mrb_int backtrace_len = RARRAY_LEN(backtrace); for (int i = 0; i < backtrace_len; ++i) { mrb_value location = mrb_ary_entry(backtrace, i); me_host_backtrace_push_location(host_backtrace, mrb_string_value_cstr(self->state, &location)); @@ -139,7 +139,7 @@ static void mruby_engine_check_stack( static void mruby_engine_code_fetch_hook( struct mrb_state* mrb, struct mrb_irep *irep, - mrb_code *pc, + const mrb_code *pc, mrb_value *regs) { (void)irep; @@ -244,7 +244,7 @@ static struct RProc *generate_code( if (parser_state->nerr > 0) { *err = me_host_syntax_error_new( - parser_state->filename, + mrb_sym_name(state, parser_state->filename_sym), parser_state->error_buffer[0].lineno, parser_state->error_buffer[0].column, parser_state->error_buffer[0].message); @@ -393,7 +393,7 @@ struct me_iseq *me_iseq_new( int status = mrb_dump_irep( engine->state, irep, - DUMP_DEBUG_INFO | DUMP_ENDIAN_NAT, + DUMP_DEBUG_INFO, &irep_data, &irep_data_size); if (status == MRB_DUMP_OK) { diff --git a/ext/mruby_engine/value_guest.c b/ext/mruby_engine/value_guest.c index 2b0e3279a..42f7b562e 100644 --- a/ext/mruby_engine/value_guest.c +++ b/ext/mruby_engine/value_guest.c @@ -48,7 +48,7 @@ static me_host_value_t me_value_to_host_r( return ME_HOST_NIL; } - for (mrb_int i = 0, f = mrb_ary_len(self->state, value); i < f; ++i) { + for (mrb_int i = 0, f = RARRAY_LEN(value); i < f; ++i) { me_host_value_t element = me_value_to_host_r( self, mrb_ary_ref(self->state, value, i), depth + 1, err); if (err->type != ME_VALUE_NO_ERR) { @@ -69,20 +69,19 @@ static me_host_value_t me_value_to_host_r( return ME_HOST_NIL; } - struct kh_ht *kh = mrb_hash_tbl(self->state, value); - for (int i = kh_begin(kh), f = kh_end(kh); i < f; ++i) { - if (!kh_exist(kh, i)) { - continue; - } + mrb_value keys = mrb_hash_keys(self->state, value); + mrb_int len = RARRAY_LEN(keys); + for (mrb_int i = 0; i < len; ++i) { + mrb_value k = mrb_ary_ref(self->state, keys, i); me_host_value_t key = me_value_to_host_r( - self, kh_key(kh, i), depth + 1, err); + self, k, depth + 1, err); if (err->type != ME_VALUE_NO_ERR) { return ME_HOST_NIL; } me_host_value_t element = me_value_to_host_r( - self, kh_value(kh, i).v, depth + 1, err); + self, mrb_hash_get(self->state, value, k), depth + 1, err); if (err->type != ME_VALUE_NO_ERR) { return ME_HOST_NIL; } diff --git a/mruby_engine.gemspec b/mruby_engine.gemspec index c14abb82f..1e3ef8f6e 100644 --- a/mruby_engine.gemspec +++ b/mruby_engine.gemspec @@ -47,6 +47,7 @@ Gem::Specification.new do |spec| spec.add_runtime_dependency "getoptlong" + spec.add_development_dependency "bigdecimal" spec.add_development_dependency "bundler", ">= 1.6" spec.add_development_dependency "rake", ">= 12.0" spec.add_development_dependency "rake-compiler", ">= 1.2" diff --git a/spec/arbitrary.rb b/spec/arbitrary.rb index 423b7663d..1b3b3dab1 100644 --- a/spec/arbitrary.rb +++ b/spec/arbitrary.rb @@ -3,7 +3,7 @@ require "securerandom" module Arbitrary - refine Fixnum.singleton_class do + refine Integer.singleton_class do def arbitrary lambda do if SecureRandom.random_number(2) == 0 @@ -21,7 +21,7 @@ def arbitrary_natural end end - refine Fixnum do + refine Integer do def shrink if self > 2 || -2 < self [(self / 2).to_i] @@ -34,7 +34,7 @@ def shrink refine BigDecimal.singleton_class do def arbitrary lambda do - "#{Fixnum.arbitrary.call}.#{Fixnum.arbitrary_natural.call}".to_d + "#{Integer.arbitrary.call}.#{Integer.arbitrary_natural.call}".to_d end end end diff --git a/spec/mruby_engine_spec.rb b/spec/mruby_engine_spec.rb index 2ef18a5f1..ce77da877 100644 --- a/spec/mruby_engine_spec.rb +++ b/spec/mruby_engine_spec.rb @@ -144,8 +144,8 @@ def bar SOURCE }.to raise_error(MRubyEngine::EngineRuntimeError) do |e| expect(e.guest_backtrace).to eq([ - "backtrace.rb:2:in Object.foo", - "backtrace.rb:6:in Object.bar", + "backtrace.rb:2:in foo", + "backtrace.rb:6:in bar", "backtrace.rb:9", ]) end @@ -183,7 +183,7 @@ def self.to_s raise(TransmogrificationError, "This looks bad.") SOURCE }.to raise_error(MRubyEngine::EngineRuntimeError) do |e| - expect(e.type).to match(/\A#\z/) + expect(e.type).to match(/\ATransmogrificationError\z|\A#\z/) end end @@ -508,7 +508,7 @@ def initialize it "returns the compiled instructions" do iseq = MRubyEngine::InstructionSequence.new([["sample.rb", "@foo = 42"]]) expect(iseq.data.encoding).to eq(Encoding::ASCII_8BIT) - expect(iseq.data.size).to eq(127) + expect(iseq.data.size).to eq(136) end end diff --git a/spec/time_spec.rb b/spec/time_spec.rb index 7fb47fe67..d56d40f5c 100644 --- a/spec/time_spec.rb +++ b/spec/time_spec.rb @@ -80,7 +80,7 @@ def eval_test(source) it "raises if time is out of range" do eval_test(<<-SOURCE) - assert_raises(ArgumentError, "9.3674872249306e+17 out of Time range") do + assert_raises(ArgumentError, "9.367487224930632e+17 out of Time range") do Time.at(0xd00000000000000) end SOURCE From 1401cb5b7934da71b4ab3f923555658429ad4b08 Mon Sep 17 00:00:00 2001 From: Jonathan Ringer Date: Mon, 23 Feb 2026 16:43:26 -0800 Subject: [PATCH 3/6] Update CI for ruby 3.2+ --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1bbeafaa6..e79057ba9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,7 +8,7 @@ jobs: strategy: fail-fast: false matrix: - ruby: [ ruby-head, '3.0', '2.7', '2.6' ] + ruby: [ '3.2', '3.3', '3.4' ] env: W_ERROR: '1' steps: From d1949899b7fc7ce990a10ef9047dc62f9aab5eea Mon Sep 17 00:00:00 2001 From: Jonathan Ringer Date: Mon, 23 Feb 2026 16:51:21 -0800 Subject: [PATCH 4/6] Support ruby 3.2 --- ext/mruby_engine/mruby-mpdecimal/src/ext.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ext/mruby_engine/mruby-mpdecimal/src/ext.c b/ext/mruby_engine/mruby-mpdecimal/src/ext.c index 1e92d9e8b..c231e5c6d 100644 --- a/ext/mruby_engine/mruby-mpdecimal/src/ext.c +++ b/ext/mruby_engine/mruby-mpdecimal/src/ext.c @@ -267,13 +267,11 @@ void mrb_mruby_mpdecimal_gem_init(mrb_state *state) { struct RClass *c_decimal = mrb_define_class(state, "Decimal", state->object_class); MRB_SET_INSTANCE_TT(c_decimal, MRB_TT_DATA); - mrb_method_t method; - MRB_METHOD_FROM_PROC(method, mrb_proc_new_cfunc_with_env(state, ext_decimal_initialize, 1, &context)); mrb_define_method_raw( state, c_decimal, mrb_intern_cstr(state, "initialize"), - method); + mrb_proc_new_cfunc_with_env(state, ext_decimal_initialize, 1, &context)); mrb_define_method(state, c_decimal, "+", ext_decimal_add, MRB_ARGS_REQ(1)); mrb_define_method(state, c_decimal, "-", ext_decimal_sub, MRB_ARGS_REQ(1)); mrb_define_method(state, c_decimal, "*", ext_decimal_mul, MRB_ARGS_REQ(1)); From 6e2a00cae162df027884d5d2cb77b728f256b03d Mon Sep 17 00:00:00 2001 From: Jonathan Ringer Date: Mon, 23 Feb 2026 16:58:53 -0800 Subject: [PATCH 5/6] Avoid potential redifinitions of HAVE_REMAP --- ext/mruby_engine/dlmalloc_config.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/ext/mruby_engine/dlmalloc_config.h b/ext/mruby_engine/dlmalloc_config.h index 1671068e4..57537279c 100644 --- a/ext/mruby_engine/dlmalloc_config.h +++ b/ext/mruby_engine/dlmalloc_config.h @@ -2,7 +2,11 @@ #define MRUBY_ENGINE_DLMALLOC_CONFIG_H #define ONLY_MSPACES 1 + +// Ruby may also define this +#ifndef HAVE_MREMAP #define HAVE_MREMAP 0 +#endif //#define FOOTERS 1 #include "host.h" From 123923d33806105275dc16728fd98e5ad168bd2f Mon Sep 17 00:00:00 2001 From: Jonathan Ringer Date: Tue, 24 Feb 2026 10:46:50 -0800 Subject: [PATCH 6/6] inherit HAVE_MREMAP from ruby.h --- ext/mruby_engine/dlmalloc_config.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/ext/mruby_engine/dlmalloc_config.h b/ext/mruby_engine/dlmalloc_config.h index 57537279c..0682267b8 100644 --- a/ext/mruby_engine/dlmalloc_config.h +++ b/ext/mruby_engine/dlmalloc_config.h @@ -3,10 +3,6 @@ #define ONLY_MSPACES 1 -// Ruby may also define this -#ifndef HAVE_MREMAP -#define HAVE_MREMAP 0 -#endif //#define FOOTERS 1 #include "host.h"