diff --git a/doc/zjit.md b/doc/zjit.md index d0d3e361913039..f3db94448d4513 100644 --- a/doc/zjit.md +++ b/doc/zjit.md @@ -32,11 +32,17 @@ Note that tests link against CRuby, so directly calling `cargo test`, or `cargo First, ensure you have `cargo` installed. If you do not already have it, you can use [rustup.rs](https://rustup.rs/). +Also install cargo-binstall with: + +```bash +cargo install cargo-binstall +``` + Make sure to add `--enable-zjit=dev` when you run `configure`, then install the following tools: ```bash -cargo install cargo-nextest -cargo install cargo-insta +cargo binstall --secure cargo-nextest +cargo binstall --secure cargo-insta ``` `cargo-insta` is used for updating snapshots. `cargo-nextest` runs each test in its own process, which is valuable since CRuby only supports booting once per process, and most APIs are not thread safe. diff --git a/lib/prism.rb b/lib/prism.rb index 2cbe196b57e2b4..f6ad0c1fd10155 100644 --- a/lib/prism.rb +++ b/lib/prism.rb @@ -42,13 +42,12 @@ class CurrentVersionError < ArgumentError # Initialize a new exception for the given ruby version string. def initialize(version) message = +"invalid version: Requested to parse as `version: 'current'`; " - gem_version = - begin - Gem::Version.new(version) - rescue ArgumentError + segments = + if version.match?(/\A\d+\.\d+.\d+\z/) + version.split(".").map(&:to_i) end - if gem_version && gem_version < Gem::Version.new("3.3.0") + if segments && ((segments[0] < 3) || (segments[0] == 3 && segments[1] < 3)) message << " #{version} is below the minimum supported syntax." else message << " #{version} is unknown. Please update the `prism` gem." diff --git a/prism/extension.c b/prism/extension.c index 0c9d04225da1fe..71c2d91b98d0f0 100644 --- a/prism/extension.c +++ b/prism/extension.c @@ -201,10 +201,9 @@ build_options_i(VALUE key, VALUE value, VALUE argument) { const char *version = check_string(value); if (RSTRING_LEN(value) == 7 && strncmp(version, "current", 7) == 0) { - VALUE current_ruby_value = rb_const_get(rb_cObject, rb_intern("RUBY_VERSION")); - const char *current_version = RSTRING_PTR(current_ruby_value); + const char *current_version = RSTRING_PTR(rb_const_get(rb_cObject, rb_intern("RUBY_VERSION"))); if (!pm_options_version_set(options, current_version, 3)) { - rb_exc_raise(rb_exc_new_str(rb_cPrismCurrentVersionError, current_ruby_value)); + rb_exc_raise(rb_exc_new_cstr(rb_cPrismCurrentVersionError, current_version)); } } else if (!pm_options_version_set(options, version, RSTRING_LEN(value))) { rb_raise(rb_eArgError, "invalid version: %" PRIsVALUE, value); diff --git a/test/prism/api/parse_test.rb b/test/prism/api/parse_test.rb index 67a252c5895541..1f885fa4935302 100644 --- a/test/prism/api/parse_test.rb +++ b/test/prism/api/parse_test.rb @@ -146,17 +146,6 @@ def test_version_current else assert_raise(CurrentVersionError) { Prism.parse_success?("1 + 1", version: "current") } end - - version = RUBY_VERSION.split(".").tap { |segments| segments[0] = segments[0].succ }.join(".") - stub_ruby_version(version) do - error = assert_raise(CurrentVersionError) { Prism.parse("1 + 1", version: "current") } - assert_includes error.message, "unknown" - end - - stub_ruby_version("2.7.0") do - error = assert_raise(CurrentVersionError) { Prism.parse("1 + 1", version: "current") } - assert_includes error.message, "minimum" - end end def test_scopes @@ -186,16 +175,5 @@ def find_source_file_node(program) queue.concat(node.compact_child_nodes) end end - - def stub_ruby_version(version) - old_version = RUBY_VERSION - - Object.send(:remove_const, :RUBY_VERSION) - Object.const_set(:RUBY_VERSION, version) - yield - ensure - Object.send(:remove_const, :RUBY_VERSION) - Object.const_set(:RUBY_VERSION, old_version) - end end end diff --git a/zjit/src/cruby_methods.rs b/zjit/src/cruby_methods.rs index 11496f7b9874a0..ea9f1beffce3f8 100644 --- a/zjit/src/cruby_methods.rs +++ b/zjit/src/cruby_methods.rs @@ -205,7 +205,7 @@ pub fn init() -> Annotations { annotate!(rb_mKernel, "nil?", types::FalseClass, no_gc, leaf, elidable); annotate!(rb_cBasicObject, "==", types::BoolExact, no_gc, leaf, elidable); annotate!(rb_cBasicObject, "!", types::BoolExact, no_gc, leaf, elidable); - annotate!(rb_cBasicObject, "initialize", types::NilClass, no_gc, leaf, elidable); + annotate!(rb_cBasicObject, "initialize", inline_basic_object_initialize); annotate!(rb_cInteger, "succ", inline_integer_succ); annotate!(rb_cString, "to_s", inline_string_to_s); let thread_singleton = unsafe { rb_singleton_class(rb_cThread) }; @@ -282,3 +282,9 @@ fn inline_integer_succ(fun: &mut hir::Function, block: hir::BlockId, recv: hir:: } None } + +fn inline_basic_object_initialize(fun: &mut hir::Function, block: hir::BlockId, _recv: hir::InsnId, args: &[hir::InsnId], _state: hir::InsnId) -> Option { + if !args.is_empty() { return None; } + let result = fun.push_insn(block, hir::Insn::Const { val: hir::Const::Value(Qnil) }); + Some(result) +} diff --git a/zjit/src/hir.rs b/zjit/src/hir.rs index a87a416e9e5408..633e4d64f7b024 100644 --- a/zjit/src/hir.rs +++ b/zjit/src/hir.rs @@ -10626,7 +10626,7 @@ mod opt_tests { v43:HeapObject[class_exact:C] = ObjectAllocClass C:VALUE(0x1008) PatchPoint MethodRedefined(C@0x1008, initialize@0x1040, cme:0x1048) PatchPoint NoSingletonClass(C@0x1008) - v47:NilClass = CCall initialize@0x1070, v43 + v47:NilClass = Const Value(nil) CheckInterrupts CheckInterrupts Return v43 @@ -10694,7 +10694,7 @@ mod opt_tests { v43:ObjectExact = ObjectAllocClass Object:VALUE(0x1008) PatchPoint MethodRedefined(Object@0x1008, initialize@0x1040, cme:0x1048) PatchPoint NoSingletonClass(Object@0x1008) - v47:NilClass = CCall initialize@0x1070, v43 + v47:NilClass = Const Value(nil) CheckInterrupts CheckInterrupts Return v43 @@ -10725,7 +10725,7 @@ mod opt_tests { v43:BasicObjectExact = ObjectAllocClass BasicObject:VALUE(0x1008) PatchPoint MethodRedefined(BasicObject@0x1008, initialize@0x1040, cme:0x1048) PatchPoint NoSingletonClass(BasicObject@0x1008) - v47:NilClass = CCall initialize@0x1070, v43 + v47:NilClass = Const Value(nil) CheckInterrupts CheckInterrupts Return v43