summaryrefslogtreecommitdiff
path: root/spec/ruby/core/hash/initialize_spec.rb
diff options
context:
space:
mode:
authorKoichi Sasada <ko1@atdot.net>2020-06-26 10:21:56 +0900
committerGitHub <noreply@github.com>2020-06-26 10:21:56 +0900
commit8070cb56db18966b7186255d46eef869e7fdd9cb (patch)
tree367b593b0fa77d93530136c6d0f626c0c7257a44 /spec/ruby/core/hash/initialize_spec.rb
parent289a28e68f30e879760fd000833b512d506a0805 (diff)
fix return event and opt_invokebuiltin_delegate_leave (#3256)
If :return event is specified for a opt_invokebuiltin_delegate_leave and leave combination, the instructions should be opt_invokebuiltin_delegate trace_return instructions. To make it, opt_invokebuiltin_delegate_leave instruction will be changed to opt_invokebuiltin_delegate even if it is not an event target instruction.
Notes
Notes: Merged-By: ko1 <ko1@atdot.net>
Diffstat (limited to 'spec/ruby/core/hash/initialize_spec.rb')
0 files changed, 0 insertions, 0 deletions
0c'>.github/workflows/bundled_gems.yml15
-rw-r--r--.github/workflows/check_dependencies.yml22
-rw-r--r--.github/workflows/check_misc.yml122
-rw-r--r--.github/workflows/cirrus-notify.yml46
-rw-r--r--.github/workflows/codeql-analysis.yml17
-rw-r--r--.github/workflows/compilers.yml63
-rw-r--r--.github/workflows/macos.yml27
-rw-r--r--.github/workflows/mingw.yml21
-rw-r--r--.github/workflows/mjit-bindgen.yml25
-rw-r--r--.github/workflows/mjit.yml21
-rw-r--r--.github/workflows/publish.yml18
-rw-r--r--.github/workflows/scorecards.yml8
-rw-r--r--.github/workflows/spec_guards.yml31
-rw-r--r--.github/workflows/ubuntu.yml22
-rw-r--r--.github/workflows/wasm.yml31
-rw-r--r--.github/workflows/windows.yml76
-rw-r--r--.github/workflows/yjit-ubuntu.yml33
-rw-r--r--.gitignore2
-rw-r--r--.travis.yml235
-rw-r--r--LEGAL10
-rw-r--r--NEWS.md331
-rw-r--r--README.ja.md1
-rw-r--r--README.md1
-rw-r--r--addr2line.c425
-rw-r--r--array.c17
-rw-r--r--ast.c5
-rw-r--r--ast.rb42
-rw-r--r--bignum.c6
-rw-r--r--bootstraptest/test_ractor.rb7
-rw-r--r--bootstraptest/test_yjit.rb78
-rw-r--r--class.c62
-rw-r--r--common.mk119
-rw-r--r--compile.c119
-rw-r--r--complex.c7
-rw-r--r--configure.ac59
-rw-r--r--cont.c84
-rw-r--r--coroutine/asyncify/Context.h8
-rw-r--r--cygwin/GNUmakefile.in5
-rw-r--r--defs/gmake.mk6
-rw-r--r--defs/id.def1
-rw-r--r--doc/.document1
-rw-r--r--doc/encodings.rdoc11
-rw-r--r--doc/mjit.md78
-rw-r--r--doc/mjit/mjit.md39
-rw-r--r--doc/net-http/examples.rdoc3
-rw-r--r--doc/net-http/included_getters.rdoc3
-rw-r--r--doc/packed_data.rdoc4
-rw-r--r--doc/syntax/literals.rdoc6
-rw-r--r--doc/yjit/yjit.md159
-rw-r--r--enc/Makefile.in2
-rw-r--r--enc/cesu_8.c23
-rw-r--r--enc/depend1
-rw-r--r--encoding.c9
-rw-r--r--enum.c2
-rw-r--r--enumerator.c78
-rw-r--r--error.c20
-rw-r--r--eval.c26
-rw-r--r--eval_error.c18
-rw-r--r--ext/-test-/string/fstring.c4
-rw-r--r--ext/-test-/string/set_len.c10
-rw-r--r--ext/date/date_core.c12
-rw-r--r--ext/date/date_strptime.c105
-rw-r--r--ext/date/lib/date.rb2
-rwxr-xr-xext/extmk.rb22
-rw-r--r--ext/io/console/depend2
-rw-r--r--ext/io/console/win32_vk.inc327
-rw-r--r--ext/io/console/win32_vk.list2
-rw-r--r--ext/io/wait/extconf.rb2
-rw-r--r--ext/json/parser/extconf.rb4
-rw-r--r--ext/objspace/depend15
-rw-r--r--ext/objspace/object_tracing.c7
-rw-r--r--ext/openssl/History.md65
-rw-r--r--ext/openssl/extconf.rb89
-rw-r--r--ext/openssl/lib/openssl/ssl.rb5
-rw-r--r--ext/openssl/lib/openssl/version.rb2
-rw-r--r--ext/openssl/openssl.gemspec2
-rw-r--r--ext/openssl/ossl.h6
-rw-r--r--ext/openssl/ossl_pkey.h2
-rw-r--r--ext/openssl/ossl_pkey_dh.c12
-rw-r--r--ext/openssl/ossl_pkey_dsa.c14
-rw-r--r--ext/openssl/ossl_pkey_ec.c64
-rw-r--r--ext/openssl/ossl_pkey_rsa.c12
-rw-r--r--ext/openssl/ossl_ssl.c42
-rw-r--r--ext/openssl/ossl_ssl_session.c4
-rw-r--r--ext/racc/cparse/cparse.c4
-rw-r--r--ext/ripper/lib/ripper/lexer.rb9
-rw-r--r--ext/socket/raddrinfo.c5
-rw-r--r--ext/stringio/stringio.c5
-rw-r--r--ext/strscan/extconf.rb3
-rw-r--r--ext/strscan/strscan.c118
-rw-r--r--ext/win32/lib/win32/registry.rb13
-rw-r--r--gc.c365
-rw-r--r--gc.h4
-rw-r--r--gc.rb50
-rw-r--r--gems/bundled_gems18
-rw-r--r--gems/lib/core_assertions.rb1
-rw-r--r--gems/lib/envutil.rb1
-rw-r--r--gems/lib/rake/extensiontask.rb (renamed from tool/dummy-rake-compiler/rake/extensiontask.rb)5
-rw-r--r--hash.c186
-rw-r--r--include/ruby/internal/abi.h7
-rw-r--r--include/ruby/internal/anyargs.h22
-rw-r--r--include/ruby/internal/attr/nonstring.h32
-rw-r--r--include/ruby/internal/gc.h13
-rw-r--r--include/ruby/internal/intern/cont.h6
-rw-r--r--include/ruby/io/buffer.h8
-rw-r--r--include/ruby/st.h2
-rw-r--r--include/ruby/win32.h7
-rw-r--r--internal/basic_operators.h1
-rw-r--r--internal/class.h5
-rw-r--r--internal/eval.h1
-rw-r--r--internal/hash.h1
-rw-r--r--internal/thread.h1
-rw-r--r--internal/time.h5
-rw-r--r--internal/variable.h2
-rw-r--r--io.c135
-rw-r--r--io_buffer.c1415
-rw-r--r--iseq.c42
-rw-r--r--iseq.h1
-rw-r--r--lib/bundler.rb31
-rw-r--r--lib/bundler/cli.rb47
-rw-r--r--lib/bundler/cli/binstubs.rb8
-rw-r--r--lib/bundler/cli/common.rb1
-rw-r--r--lib/bundler/cli/gem.rb55
-rw-r--r--lib/bundler/cli/info.rb2
-rw-r--r--lib/bundler/cli/init.rb4
-rw-r--r--lib/bundler/cli/install.rb2
-rw-r--r--lib/bundler/cli/lock.rb7
-rw-r--r--lib/bundler/cli/open.rb10
-rw-r--r--lib/bundler/cli/outdated.rb6
-rw-r--r--lib/bundler/cli/platform.rb12
-rw-r--r--lib/bundler/current_ruby.rb2
-rw-r--r--lib/bundler/definition.rb274
-rw-r--r--lib/bundler/dependency.rb8
-rw-r--r--lib/bundler/dsl.rb6
-rw-r--r--lib/bundler/endpoint_specification.rb4
-rw-r--r--lib/bundler/env.rb2
-rw-r--r--lib/bundler/environment_preserver.rb4
-rw-r--r--lib/bundler/feature_flag.rb1
-rw-r--r--lib/bundler/fetcher.rb16
-rw-r--r--lib/bundler/fetcher/compact_index.rb6
-rw-r--r--lib/bundler/fetcher/dependency.rb8
-rw-r--r--lib/bundler/fetcher/downloader.rb2
-rw-r--r--lib/bundler/fetcher/index.rb3
-rw-r--r--lib/bundler/force_platform.rb18
-rw-r--r--lib/bundler/friendly_errors.rb2
-rw-r--r--lib/bundler/gem_helper.rb7
-rw-r--r--lib/bundler/gem_version_promoter.rb35
-rw-r--r--lib/bundler/index.rb4
-rw-r--r--lib/bundler/injector.rb2
-rw-r--r--lib/bundler/inline.rb14
-rw-r--r--lib/bundler/installer.rb12
-rw-r--r--lib/bundler/installer/parallel_installer.rb38
-rw-r--r--lib/bundler/installer/standalone.rb20
-rw-r--r--lib/bundler/lazy_specification.rb84
-rw-r--r--lib/bundler/lockfile_generator.rb4
-rw-r--r--lib/bundler/lockfile_parser.rb23
-rw-r--r--lib/bundler/man/bundle-add.12
-rw-r--r--lib/bundler/man/bundle-binstubs.12
-rw-r--r--lib/bundler/man/bundle-cache.16
-rw-r--r--lib/bundler/man/bundle-cache.1.ronn4
-rw-r--r--lib/bundler/man/bundle-check.12
-rw-r--r--lib/bundler/man/bundle-clean.12
-rw-r--r--lib/bundler/man/bundle-config.17
-rw-r--r--lib/bundler/man/bundle-config.1.ronn5
-rw-r--r--lib/bundler/man/bundle-console.12
-rw-r--r--lib/bundler/man/bundle-doctor.12
-rw-r--r--lib/bundler/man/bundle-exec.110
-rw-r--r--lib/bundler/man/bundle-exec.1.ronn10
-rw-r--r--lib/bundler/man/bundle-gem.164
-rw-r--r--lib/bundler/man/bundle-gem.1.ronn10
-rw-r--r--lib/bundler/man/bundle-help.12
-rw-r--r--lib/bundler/man/bundle-info.16
-rw-r--r--lib/bundler/man/bundle-info.1.ronn6
-rw-r--r--lib/bundler/man/bundle-init.16
-rw-r--r--lib/bundler/man/bundle-init.1.ronn2
-rw-r--r--lib/bundler/man/bundle-inject.12
-rw-r--r--lib/bundler/man/bundle-install.12
-rw-r--r--lib/bundler/man/bundle-list.12
-rw-r--r--lib/bundler/man/bundle-lock.12
-rw-r--r--lib/bundler/man/bundle-open.124
-rw-r--r--lib/bundler/man/bundle-open.1.ronn10
-rw-r--r--lib/bundler/man/bundle-outdated.122
-rw-r--r--lib/bundler/man/bundle-outdated.1.ronn21
-rw-r--r--lib/bundler/man/bundle-platform.12
-rw-r--r--lib/bundler/man/bundle-plugin.12
-rw-r--r--lib/bundler/man/bundle-pristine.12
-rw-r--r--lib/bundler/man/bundle-remove.12
-rw-r--r--lib/bundler/man/bundle-show.12
-rw-r--r--lib/bundler/man/bundle-update.12
-rw-r--r--lib/bundler/man/bundle-version.12
-rw-r--r--lib/bundler/man/bundle-viz.12
-rw-r--r--lib/bundler/man/bundle.12
-rw-r--r--lib/bundler/man/gemfile.517
-rw-r--r--lib/bundler/man/gemfile.5.ronn7
-rw-r--r--lib/bundler/plugin.rb2
-rw-r--r--lib/bundler/plugin/index.rb2
-rw-r--r--lib/bundler/plugin/installer.rb7
-rw-r--r--lib/bundler/remote_specification.rb8
-rw-r--r--lib/bundler/resolver.rb185
-rw-r--r--lib/bundler/resolver/base.rb79
-rw-r--r--lib/bundler/resolver/candidate.rb26
-rw-r--r--lib/bundler/resolver/package.rb13
-rw-r--r--lib/bundler/ruby_dsl.rb6
-rw-r--r--lib/bundler/ruby_version.rb6
-rw-r--r--lib/bundler/rubygems_ext.rb19
-rw-r--r--lib/bundler/rubygems_integration.rb16
-rw-r--r--lib/bundler/runtime.rb2
-rw-r--r--lib/bundler/safe_marshal.rb31
-rw-r--r--lib/bundler/settings.rb8
-rw-r--r--lib/bundler/setup.rb5
-rw-r--r--lib/bundler/shared_helpers.rb4
-rw-r--r--lib/bundler/source.rb2
-rw-r--r--lib/bundler/source/git.rb57
-rw-r--r--lib/bundler/source/git/git_proxy.rb185
-rw-r--r--lib/bundler/source/path.rb2
-rw-r--r--lib/bundler/source/rubygems.rb31
-rw-r--r--lib/bundler/source_list.rb12
-rw-r--r--lib/bundler/spec_set.rb30
-rw-r--r--lib/bundler/templates/Executable.bundler2
-rw-r--r--lib/bundler/templates/gems.rb5
-rw-r--r--lib/bundler/templates/newgem/Cargo.toml.tt7
-rw-r--r--lib/bundler/templates/newgem/Gemfile.tt3
-rw-r--r--lib/bundler/templates/newgem/README.md.tt10
-rw-r--r--lib/bundler/templates/newgem/Rakefile.tt13
-rw-r--r--lib/bundler/templates/newgem/bin/console.tt4
-rw-r--r--lib/bundler/templates/newgem/circleci/config.yml.tt12
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/Cargo.toml.tt15
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/extconf-c.rb.tt10
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/extconf-rust.rb.tt6
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/extconf.rb.tt5
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/newgem.c.tt2
-rw-r--r--lib/bundler/templates/newgem/ext/newgem/src/lib.rs.tt12
-rw-r--r--lib/bundler/templates/newgem/github/workflows/main.yml.tt10
-rw-r--r--lib/bundler/templates/newgem/gitignore.tt3
-rw-r--r--lib/bundler/templates/newgem/gitlab-ci.yml.tt8
-rw-r--r--lib/bundler/templates/newgem/newgem.gemspec.tt11
-rw-r--r--lib/bundler/templates/newgem/travis.yml.tt6
-rw-r--r--lib/bundler/ui/rg_proxy.rb2
-rw-r--r--lib/bundler/uri_normalizer.rb23
-rw-r--r--lib/bundler/vendor/fileutils/lib/fileutils.rb2
-rw-r--r--lib/bundler/vendor/pub_grub/LICENSE.txt21
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/incompatibility.rb8
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/static_package_source.rb9
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/version_constraint.rb5
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/version_range.rb8
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/version_solver.rb18
-rw-r--r--lib/bundler/vendor/pub_grub/lib/pub_grub/version_union.rb6
-rw-r--r--lib/bundler/vendor/uri/lib/uri/rfc2396_parser.rb4
-rw-r--r--lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb6
-rw-r--r--lib/bundler/vendor/uri/lib/uri/version.rb2
-rw-r--r--lib/bundler/version.rb2
-rw-r--r--lib/cgi.rb2
-rw-r--r--lib/cgi/cookie.rb5
-rw-r--r--lib/cgi/util.rb4
-rw-r--r--lib/did_you_mean/version.rb2
-rw-r--r--lib/erb.gemspec2
-rw-r--r--lib/irb/cmd/debug.rb9
-rw-r--r--lib/irb/version.rb2
-rw-r--r--lib/net/http.rb1408
-rw-r--r--lib/net/http/backward.rb2
-rw-r--r--lib/net/http/exceptions.rb2
-rw-r--r--lib/net/http/generic_request.rb106
-rw-r--r--lib/net/http/header.rb231
-rw-r--r--lib/net/http/net-http.gemspec13
-rw-r--r--lib/net/http/proxy_delta.rb2
-rw-r--r--lib/net/http/request.rb55
-rw-r--r--lib/net/http/requests.rb32
-rw-r--r--lib/net/http/response.rb64
-rw-r--r--lib/net/http/responses.rb627
-rw-r--r--lib/net/http/status.rb13
-rw-r--r--lib/net/https.rb2
-rw-r--r--lib/optparse.rb21
-rw-r--r--lib/racc/info.rb2
-rw-r--r--lib/racc/statetransitiontable.rb2
-rw-r--r--lib/rdoc/store.rb45
-rw-r--r--lib/rdoc/version.rb2
-rw-r--r--lib/resolv.gemspec2
-rw-r--r--lib/resolv.rb6
-rw-r--r--lib/ruby_vm/mjit/c_pointer.rb (renamed from lib/mjit/c_pointer.rb)6
-rw-r--r--lib/ruby_vm/mjit/c_type.rb (renamed from lib/mjit/c_type.rb)2
-rw-r--r--lib/ruby_vm/mjit/compiler.rb (renamed from lib/mjit/compiler.rb)23
-rw-r--r--lib/ruby_vm/mjit/hooks.rb32
-rw-r--r--lib/rubygems.rb38
-rw-r--r--lib/rubygems/available_set.rb1
-rw-r--r--lib/rubygems/basic_specification.rb1
-rw-r--r--lib/rubygems/bundler_version_finder.rb4
-rw-r--r--lib/rubygems/command.rb23
-rw-r--r--lib/rubygems/command_manager.rb27
-rw-r--r--lib/rubygems/commands/build_command.rb4
-rw-r--r--lib/rubygems/commands/cert_command.rb1
-rw-r--r--lib/rubygems/commands/check_command.rb1
-rw-r--r--lib/rubygems/commands/cleanup_command.rb1
-rw-r--r--lib/rubygems/commands/contents_command.rb1
-rw-r--r--lib/rubygems/commands/dependency_command.rb1
-rw-r--r--lib/rubygems/commands/environment_command.rb1
-rw-r--r--lib/rubygems/commands/exec_command.rb249
-rw-r--r--lib/rubygems/commands/fetch_command.rb1
-rw-r--r--lib/rubygems/commands/generate_index_command.rb1
-rw-r--r--lib/rubygems/commands/help_command.rb7
-rw-r--r--lib/rubygems/commands/install_command.rb1
-rw-r--r--lib/rubygems/commands/list_command.rb1
-rw-r--r--lib/rubygems/commands/lock_command.rb1
-rw-r--r--lib/rubygems/commands/mirror_command.rb1
-rw-r--r--lib/rubygems/commands/open_command.rb1
-rw-r--r--lib/rubygems/commands/outdated_command.rb1
-rw-r--r--lib/rubygems/commands/owner_command.rb9
-rw-r--r--lib/rubygems/commands/pristine_command.rb10
-rw-r--r--lib/rubygems/commands/push_command.rb1
-rw-r--r--lib/rubygems/commands/query_command.rb1
-rw-r--r--lib/rubygems/commands/rdoc_command.rb1
-rw-r--r--lib/rubygems/commands/search_command.rb1
-rw-r--r--lib/rubygems/commands/server_command.rb1
-rw-r--r--lib/rubygems/commands/setup_command.rb3
-rw-r--r--lib/rubygems/commands/signin_command.rb1
-rw-r--r--lib/rubygems/commands/signout_command.rb1
-rw-r--r--lib/rubygems/commands/sources_command.rb1
-rw-r--r--lib/rubygems/commands/specification_command.rb1
-rw-r--r--lib/rubygems/commands/stale_command.rb1
-rw-r--r--lib/rubygems/commands/uninstall_command.rb4
-rw-r--r--lib/rubygems/commands/unpack_command.rb1
-rw-r--r--lib/rubygems/commands/update_command.rb1
-rw-r--r--lib/rubygems/commands/which_command.rb1
-rw-r--r--lib/rubygems/commands/yank_command.rb1
-rw-r--r--lib/rubygems/config_file.rb1
-rw-r--r--lib/rubygems/core_ext/kernel_gem.rb5
-rw-r--r--lib/rubygems/core_ext/kernel_require.rb222
-rw-r--r--lib/rubygems/core_ext/kernel_warn.rb69
-rw-r--r--lib/rubygems/core_ext/tcpsocket_init.rb2
-rw-r--r--lib/rubygems/defaults.rb5
-rw-r--r--lib/rubygems/dependency.rb8
-rw-r--r--lib/rubygems/dependency_installer.rb1
-rw-r--r--lib/rubygems/dependency_list.rb1
-rw-r--r--lib/rubygems/deprecate.rb5
-rw-r--r--lib/rubygems/doctor.rb1
-rw-r--r--lib/rubygems/errors.rb1
-rw-r--r--lib/rubygems/exceptions.rb10
-rw-r--r--lib/rubygems/ext.rb1
-rw-r--r--lib/rubygems/ext/build_error.rb1
-rw-r--r--lib/rubygems/ext/builder.rb28
-rw-r--r--lib/rubygems/ext/cargo_builder.rb237
-rw-r--r--lib/rubygems/ext/cargo_builder/link_flag_converter.rb14
-rw-r--r--lib/rubygems/ext/configure_builder.rb1
-rw-r--r--lib/rubygems/ext/ext_conf_builder.rb6
-rw-r--r--lib/rubygems/ext/rake_builder.rb8
-rw-r--r--lib/rubygems/gem_runner.rb1
-rw-r--r--lib/rubygems/gemcutter_utilities.rb62
-rw-r--r--lib/rubygems/gemcutter_utilities/webauthn_listener.rb105
-rw-r--r--lib/rubygems/gemcutter_utilities/webauthn_listener/response.rb163
-rw-r--r--lib/rubygems/gemcutter_utilities/webauthn_poller.rb78
-rw-r--r--lib/rubygems/indexer.rb1
-rw-r--r--lib/rubygems/install_default_message.rb1
-rw-r--r--lib/rubygems/install_message.rb1
-rw-r--r--lib/rubygems/install_update_options.rb1
-rw-r--r--lib/rubygems/installer.rb18
-rw-r--r--lib/rubygems/local_remote_options.rb1
-rw-r--r--lib/rubygems/mock_gem_ui.rb1
-rw-r--r--lib/rubygems/name_tuple.rb1
-rw-r--r--lib/rubygems/package.rb4
-rw-r--r--lib/rubygems/package/digest_io.rb1
-rw-r--r--lib/rubygems/package/file_source.rb1
-rw-r--r--lib/rubygems/package/io_source.rb1
-rw-r--r--lib/rubygems/package/old.rb1
-rw-r--r--lib/rubygems/package/source.rb1
-rw-r--r--lib/rubygems/package/tar_header.rb3
-rw-r--r--lib/rubygems/package/tar_reader.rb29
-rw-r--r--lib/rubygems/package/tar_reader/entry.rb96
-rw-r--r--lib/rubygems/package/tar_writer.rb1
-rw-r--r--lib/rubygems/package_task.rb1
-rw-r--r--lib/rubygems/path_support.rb1
-rw-r--r--lib/rubygems/platform.rb7
-rw-r--r--lib/rubygems/psych_tree.rb1
-rw-r--r--lib/rubygems/rdoc.rb1
-rw-r--r--lib/rubygems/remote_fetcher.rb1
-rw-r--r--lib/rubygems/request.rb1
-rw-r--r--lib/rubygems/request/http_pool.rb1
-rw-r--r--lib/rubygems/request/https_pool.rb1
-rw-r--r--lib/rubygems/request_set.rb5
-rw-r--r--lib/rubygems/request_set/gem_dependency_api.rb2
-rw-r--r--lib/rubygems/request_set/lockfile.rb1
-rw-r--r--lib/rubygems/request_set/lockfile/parser.rb3
-rw-r--r--lib/rubygems/request_set/lockfile/tokenizer.rb2
-rw-r--r--lib/rubygems/requirement.rb3
-rw-r--r--lib/rubygems/resolver.rb1
-rw-r--r--lib/rubygems/resolver/activation_request.rb1
-rw-r--r--lib/rubygems/resolver/api_set.rb1
-rw-r--r--lib/rubygems/resolver/api_specification.rb1
-rw-r--r--lib/rubygems/resolver/best_set.rb1
-rw-r--r--lib/rubygems/resolver/composed_set.rb1
-rw-r--r--lib/rubygems/resolver/conflict.rb1
-rw-r--r--lib/rubygems/resolver/current_set.rb1
-rw-r--r--lib/rubygems/resolver/dependency_request.rb1
-rw-r--r--lib/rubygems/resolver/git_set.rb1
-rw-r--r--lib/rubygems/resolver/git_specification.rb1
-rw-r--r--lib/rubygems/resolver/index_set.rb1
-rw-r--r--lib/rubygems/resolver/index_specification.rb1
-rw-r--r--lib/rubygems/resolver/installed_specification.rb1
-rw-r--r--lib/rubygems/resolver/installer_set.rb5
-rw-r--r--lib/rubygems/resolver/local_specification.rb1
-rw-r--r--lib/rubygems/resolver/lock_set.rb1
-rw-r--r--lib/rubygems/resolver/lock_specification.rb1
-rw-r--r--lib/rubygems/resolver/molinillo.rb1
-rw-r--r--lib/rubygems/resolver/requirement_list.rb1
-rw-r--r--lib/rubygems/resolver/set.rb1
-rw-r--r--lib/rubygems/resolver/source_set.rb2
-rw-r--r--lib/rubygems/resolver/spec_specification.rb1
-rw-r--r--lib/rubygems/resolver/specification.rb1
-rw-r--r--lib/rubygems/resolver/stats.rb3
-rw-r--r--lib/rubygems/resolver/vendor_set.rb1
-rw-r--r--lib/rubygems/resolver/vendor_specification.rb1
-rw-r--r--lib/rubygems/s3_uri_signer.rb6
-rw-r--r--lib/rubygems/safe_yaml.rb2
-rw-r--r--lib/rubygems/security.rb1
-rw-r--r--lib/rubygems/security/policies.rb1
-rw-r--r--lib/rubygems/security/policy.rb1
-rw-r--r--lib/rubygems/security/signer.rb1
-rw-r--r--lib/rubygems/security/trust_dir.rb1
-rw-r--r--lib/rubygems/security_option.rb1
-rw-r--r--lib/rubygems/shellwords.rb3
-rw-r--r--lib/rubygems/source/git.rb2
-rw-r--r--lib/rubygems/source/installed.rb1
-rw-r--r--lib/rubygems/source/local.rb1
-rw-r--r--lib/rubygems/source/lock.rb1
-rw-r--r--lib/rubygems/source/specific_file.rb1
-rw-r--r--lib/rubygems/source/vendor.rb1
-rw-r--r--lib/rubygems/spec_fetcher.rb1
-rw-r--r--lib/rubygems/specification.rb28
-rw-r--r--lib/rubygems/specification_policy.rb21
-rw-r--r--lib/rubygems/stub_specification.rb18
-rw-r--r--lib/rubygems/text.rb2
-rw-r--r--lib/rubygems/uninstaller.rb1
-rw-r--r--lib/rubygems/user_interaction.rb6
-rw-r--r--lib/rubygems/util.rb1
-rw-r--r--lib/rubygems/util/licenses.rb5
-rw-r--r--lib/rubygems/util/list.rb1
-rw-r--r--lib/rubygems/validator.rb1
-rw-r--r--lib/rubygems/version.rb4
-rw-r--r--lib/rubygems/version_option.rb1
-rw-r--r--lib/syntax_suggest/api.rb6
-rw-r--r--lib/syntax_suggest/around_block_scan.rb290
-rw-r--r--lib/syntax_suggest/block_expand.rb111
-rw-r--r--lib/syntax_suggest/capture/before_after_keyword_ends.rb85
-rw-r--r--lib/syntax_suggest/capture/falling_indent_lines.rb71
-rw-r--r--lib/syntax_suggest/capture_code_context.rb24
-rw-r--r--lib/syntax_suggest/clean_document.rb6
-rw-r--r--lib/syntax_suggest/code_line.rb8
-rw-r--r--lib/syntax_suggest/core_ext.rb6
-rw-r--r--lib/syntax_suggest/parse_blocks_from_indent_line.rb4
-rw-r--r--lib/syntax_suggest/scan_history.rb134
-rw-r--r--lib/syntax_suggest/syntax_suggest.gemspec2
-rw-r--r--lib/syntax_suggest/version.rb2
-rw-r--r--lib/time.gemspec2
-rw-r--r--lib/time.rb4
-rw-r--r--lib/uri/common.rb2
-rw-r--r--lib/uri/generic.rb15
-rw-r--r--lib/uri/rfc2396_parser.rb4
-rw-r--r--lib/uri/rfc3986_parser.rb6
-rw-r--r--lib/uri/version.rb2
-rwxr-xr-xlibexec/bundle20
-rw-r--r--load.c74
-rw-r--r--main.c6
-rw-r--r--marshal.c23
-rw-r--r--method.h11
-rw-r--r--mjit.c127
-rw-r--r--mjit.h14
-rw-r--r--mjit.rb14
-rw-r--r--mjit_c.rb19
-rw-r--r--numeric.c37
-rw-r--r--object.c10
-rw-r--r--parse.y261
-rw-r--r--proc.c53
-rw-r--r--process.c54
-rw-r--r--ractor.c45
-rw-r--r--range.c154
-rw-r--r--re.c266
-rw-r--r--regenc.c2
-rw-r--r--regenc.h5
-rw-r--r--regexec.c96
-rw-r--r--regint.h9
-rw-r--r--regparse.c3
-rw-r--r--ruby.c28
-rw-r--r--sample/trick2022/01-tompng/Gemfile2
-rw-r--r--sample/trick2022/01-tompng/Gemfile.lock13
-rw-r--r--sample/trick2022/01-tompng/authors.markdown3
-rw-r--r--sample/trick2022/01-tompng/entry.rb40
-rw-r--r--sample/trick2022/01-tompng/remarks.markdown51
-rw-r--r--sample/trick2022/02-tompng/authors.markdown3
-rw-r--r--sample/trick2022/02-tompng/entry.rb32
-rw-r--r--sample/trick2022/02-tompng/remarks.markdown32
-rw-r--r--sample/trick2022/03-mame/authors.markdown3
-rw-r--r--sample/trick2022/03-mame/entry.rb27
-rw-r--r--sample/trick2022/03-mame/remarks.markdown96
-rw-r--r--sample/trick2022/03-mame/test.txt13
-rw-r--r--sample/trick2022/README.md14
-rw-r--r--scheduler.c94
-rw-r--r--shape.c153
-rw-r--r--shape.h20
-rw-r--r--signal.c3
-rw-r--r--siphash.c3
-rw-r--r--spec/bundler/bundler/bundler_spec.rb65
-rw-r--r--spec/bundler/bundler/cli_spec.rb46
-rw-r--r--spec/bundler/bundler/definition_spec.rb2
-rw-r--r--spec/bundler/bundler/dependency_spec.rb16
-rw-r--r--spec/bundler/bundler/dsl_spec.rb11
-rw-r--r--spec/bundler/bundler/env_spec.rb2
-rw-r--r--spec/bundler/bundler/fetcher/dependency_spec.rb18
-rw-r--r--spec/bundler/bundler/fetcher/downloader_spec.rb10
-rw-r--r--spec/bundler/bundler/fetcher/index_spec.rb23
-rw-r--r--spec/bundler/bundler/fetcher_spec.rb30
-rw-r--r--spec/bundler/bundler/gem_version_promoter_spec.rb240
-rw-r--r--spec/bundler/bundler/installer/parallel_installer_spec.rb38
-rw-r--r--spec/bundler/bundler/plugin/index_spec.rb10
-rw-r--r--spec/bundler/bundler/resolver/candidate_spec.rb15
-rw-r--r--spec/bundler/bundler/ruby_dsl_spec.rb27
-rw-r--r--spec/bundler/bundler/ruby_version_spec.rb10
-rw-r--r--spec/bundler/bundler/rubygems_integration_spec.rb11
-rw-r--r--spec/bundler/bundler/settings_spec.rb2
-rw-r--r--spec/bundler/bundler/shared_helpers_spec.rb4
-rw-r--r--spec/bundler/bundler/source/git/git_proxy_spec.rb30
-rw-r--r--spec/bundler/cache/git_spec.rb53
-rw-r--r--spec/bundler/commands/add_spec.rb6
-rw-r--r--spec/bundler/commands/binstubs_spec.rb56
-rw-r--r--spec/bundler/commands/cache_spec.rb2
-rw-r--r--spec/bundler/commands/check_spec.rb6
-rw-r--r--spec/bundler/commands/clean_spec.rb2
-rw-r--r--spec/bundler/commands/doctor_spec.rb2
-rw-r--r--spec/bundler/commands/exec_spec.rb39
-rw-r--r--spec/bundler/commands/info_spec.rb2
-rw-r--r--spec/bundler/commands/init_spec.rb13
-rw-r--r--spec/bundler/commands/inject_spec.rb2
-rw-r--r--spec/bundler/commands/install_spec.rb27
-rw-r--r--spec/bundler/commands/lock_spec.rb621
-rw-r--r--spec/bundler/commands/newgem_spec.rb201
-rw-r--r--spec/bundler/commands/open_spec.rb58
-rw-r--r--spec/bundler/commands/outdated_spec.rb2
-rw-r--r--spec/bundler/commands/platform_spec.rb8
-rw-r--r--spec/bundler/commands/show_spec.rb2
-rw-r--r--spec/bundler/commands/update_spec.rb206
-rw-r--r--spec/bundler/commands/viz_spec.rb2
-rw-r--r--spec/bundler/install/deploy_spec.rb125
-rw-r--r--spec/bundler/install/gemfile/gemspec_spec.rb4
-rw-r--r--spec/bundler/install/gemfile/git_spec.rb44
-rw-r--r--spec/bundler/install/gemfile/path_spec.rb109
-rw-r--r--spec/bundler/install/gemfile/platform_spec.rb22
-rw-r--r--spec/bundler/install/gemfile/sources_spec.rb38
-rw-r--r--spec/bundler/install/gemfile/specific_platform_spec.rb392
-rw-r--r--spec/bundler/install/gems/compact_index_spec.rb23
-rw-r--r--spec/bundler/install/gems/dependency_api_spec.rb12
-rw-r--r--spec/bundler/install/gems/flex_spec.rb2
-rw-r--r--spec/bundler/install/gems/resolving_spec.rb2
-rw-r--r--spec/bundler/install/gems/standalone_spec.rb33
-rw-r--r--spec/bundler/install/git_spec.rb72
-rw-r--r--spec/bundler/install/global_cache_spec.rb4
-rw-r--r--spec/bundler/install/yanked_spec.rb6
-rw-r--r--spec/bundler/lock/git_spec.rb112
-rw-r--r--spec/bundler/lock/lockfile_spec.rb261
-rw-r--r--spec/bundler/other/major_deprecation_spec.rb2
-rw-r--r--spec/bundler/plugins/install_spec.rb7
-rw-r--r--spec/bundler/quality_spec.rb1
-rw-r--r--spec/bundler/realworld/edgecases_spec.rb342
-rw-r--r--spec/bundler/realworld/ffi_spec.rb2
-rw-r--r--spec/bundler/realworld/git_spec.rb11
-rw-r--r--spec/bundler/realworld/slow_perf_spec.rb2
-rw-r--r--spec/bundler/resolver/basic_spec.rb46
-rw-r--r--spec/bundler/resolver/platform_spec.rb35
-rw-r--r--spec/bundler/runtime/inline_spec.rb157
-rw-r--r--spec/bundler/runtime/platform_spec.rb2
-rw-r--r--spec/bundler/runtime/self_management_spec.rb2
-rw-r--r--spec/bundler/runtime/setup_spec.rb39
-rw-r--r--spec/bundler/support/api_request_limit_hax.rb16
-rw-r--r--spec/bundler/support/artifice/compact_index_strict_basic_authentication.rb2
-rw-r--r--spec/bundler/support/artifice/endpoint_strict_basic_authentication.rb2
-rw-r--r--spec/bundler/support/artifice/used_cassettes.txt20908
-rw-r--r--spec/bundler/support/artifice/vcr.rb26
-rw-r--r--spec/bundler/support/builders.rb22
-rw-r--r--spec/bundler/support/hax.rb19
-rw-r--r--spec/bundler/support/helpers.rb18
-rw-r--r--spec/bundler/support/indexes.rb21
-rw-r--r--spec/bundler/support/matchers.rb2
-rw-r--r--spec/bundler/support/path.rb10
-rw-r--r--spec/bundler/support/platforms.rb16
-rwxr-xr-xspec/mspec/tool/tag_from_output.rb2
-rw-r--r--spec/ruby/core/array/keep_if_spec.rb1
-rw-r--r--spec/ruby/core/array/pack/c_spec.rb14
-rw-r--r--spec/ruby/core/array/pack/shared/basic.rb40
-rw-r--r--spec/ruby/core/array/pack/shared/float.rb66
-rw-r--r--spec/ruby/core/array/pack/shared/integer.rb96
-rw-r--r--spec/ruby/core/array/pack/shared/numeric_basic.rb10
-rw-r--r--spec/ruby/core/array/pack/shared/unicode.rb14
-rw-r--r--spec/ruby/core/array/pack/w_spec.rb14
-rw-r--r--spec/ruby/core/array/shared/unshift.rb18
-rw-r--r--spec/ruby/core/array/values_at_spec.rb1
-rw-r--r--spec/ruby/core/array/zip_spec.rb6
-rw-r--r--spec/ruby/core/class/subclasses_spec.rb22
-rw-r--r--spec/ruby/core/dir/home_spec.rb43
-rw-r--r--spec/ruby/core/dir/mkdir_spec.rb18
-rw-r--r--spec/ruby/core/enumerable/zip_spec.rb5
-rw-r--r--spec/ruby/core/fiber/storage_spec.rb48
-rw-r--r--spec/ruby/core/file/atime_spec.rb2
-rw-r--r--spec/ruby/core/file/ctime_spec.rb2
-rw-r--r--spec/ruby/core/file/mtime_spec.rb2
-rw-r--r--spec/ruby/core/file/utime_spec.rb34
-rw-r--r--spec/ruby/core/float/comparison_spec.rb35
-rw-r--r--spec/ruby/core/float/divmod_spec.rb2
-rw-r--r--spec/ruby/core/float/gt_spec.rb21
-rw-r--r--spec/ruby/core/float/gte_spec.rb21
-rw-r--r--spec/ruby/core/float/lt_spec.rb21
-rw-r--r--spec/ruby/core/float/lte_spec.rb21
-rw-r--r--spec/ruby/core/float/shared/equal.rb21
-rw-r--r--spec/ruby/core/io/gets_spec.rb4
-rw-r--r--spec/ruby/core/io/lineno_spec.rb9
-rw-r--r--spec/ruby/core/io/new_spec.rb2
-rw-r--r--spec/ruby/core/io/readline_spec.rb4
-rw-r--r--spec/ruby/core/io/readlines_spec.rb4
-rw-r--r--spec/ruby/core/io/shared/each.rb4
-rw-r--r--spec/ruby/core/io/shared/new.rb2
-rw-r--r--spec/ruby/core/io/shared/pos.rb8
-rw-r--r--spec/ruby/core/io/shared/readlines.rb4
-rw-r--r--spec/ruby/core/io/sysseek_spec.rb2
-rw-r--r--spec/ruby/core/kernel/shared/load.rb31
-rw-r--r--spec/ruby/core/kernel/shared/require.rb11
-rw-r--r--spec/ruby/core/kernel/singleton_class_spec.rb2
-rw-r--r--spec/ruby/core/marshal/dump_spec.rb45
-rw-r--r--spec/ruby/core/marshal/fixtures/classes.rb4
-rw-r--r--spec/ruby/core/marshal/shared/load.rb11
-rw-r--r--spec/ruby/core/matchdata/values_at_spec.rb73
-rw-r--r--spec/ruby/core/module/fixtures/classes.rb1
-rw-r--r--spec/ruby/core/module/include_spec.rb4
-rw-r--r--spec/ruby/core/module/prepend_spec.rb12
-rw-r--r--spec/ruby/core/objectspace/define_finalizer_spec.rb22
-rw-r--r--spec/ruby/core/process/constants_spec.rb1
-rw-r--r--spec/ruby/core/process/daemon_spec.rb3
-rw-r--r--spec/ruby/core/process/detach_spec.rb29
-rw-r--r--spec/ruby/core/process/spawn_spec.rb10
-rw-r--r--spec/ruby/core/process/times_spec.rb2
-rw-r--r--spec/ruby/core/queue/initialize_spec.rb13
-rw-r--r--spec/ruby/core/range/case_compare_spec.rb6
-rw-r--r--spec/ruby/core/refinement/import_methods_spec.rb34
-rw-r--r--spec/ruby/core/refinement/include_spec.rb27
-rw-r--r--spec/ruby/core/refinement/prepend_spec.rb27
-rw-r--r--spec/ruby/core/regexp/initialize_spec.rb2
-rw-r--r--spec/ruby/core/regexp/shared/new.rb82
-rw-r--r--spec/ruby/core/signal/trap_spec.rb12
-rw-r--r--spec/ruby/core/string/byteindex_spec.rb16
-rw-r--r--spec/ruby/core/string/byteslice_spec.rb6
-rw-r--r--spec/ruby/core/string/capitalize_spec.rb4
-rw-r--r--spec/ruby/core/string/chars_spec.rb7
-rw-r--r--spec/ruby/core/string/chomp_spec.rb4
-rw-r--r--spec/ruby/core/string/chop_spec.rb4
-rw-r--r--spec/ruby/core/string/clone_spec.rb4
-rw-r--r--spec/ruby/core/string/delete_prefix_spec.rb4
-rw-r--r--spec/ruby/core/string/delete_spec.rb4
-rw-r--r--spec/ruby/core/string/delete_suffix_spec.rb4
-rw-r--r--spec/ruby/core/string/downcase_spec.rb4
-rw-r--r--spec/ruby/core/string/dump_spec.rb10
-rw-r--r--spec/ruby/core/string/dup_spec.rb4
-rw-r--r--spec/ruby/core/string/lines_spec.rb1
-rw-r--r--spec/ruby/core/string/reverse_spec.rb4
-rw-r--r--spec/ruby/core/string/rindex_spec.rb9
-rw-r--r--spec/ruby/core/string/scan_spec.rb6
-rw-r--r--spec/ruby/core/string/scrub_spec.rb10
-rw-r--r--spec/ruby/core/string/shared/each_line.rb6
-rw-r--r--spec/ruby/core/string/shared/partition.rb15
-rw-r--r--spec/ruby/core/string/shared/slice.rb13
-rw-r--r--spec/ruby/core/string/shared/strip.rb4
-rw-r--r--spec/ruby/core/string/shared/succ.rb4
-rw-r--r--spec/ruby/core/string/split_spec.rb17
-rw-r--r--spec/ruby/core/string/squeeze_spec.rb5
-rw-r--r--spec/ruby/core/string/swapcase_spec.rb4
-rw-r--r--spec/ruby/core/string/undump_spec.rb2
-rw-r--r--spec/ruby/core/string/unpack/b_spec.rb28
-rw-r--r--spec/ruby/core/string/unpack/c_spec.rb14
-rw-r--r--spec/ruby/core/string/unpack/h_spec.rb28
-rw-r--r--spec/ruby/core/string/unpack/shared/basic.rb28
-rw-r--r--spec/ruby/core/string/unpack/shared/float.rb60
-rw-r--r--spec/ruby/core/string/unpack/shared/integer.rb88
-rw-r--r--spec/ruby/core/string/unpack/shared/unicode.rb14
-rw-r--r--spec/ruby/core/string/unpack/w_spec.rb14
-rw-r--r--spec/ruby/core/string/unpack1_spec.rb12
-rw-r--r--spec/ruby/core/string/unpack_spec.rb34
-rw-r--r--spec/ruby/core/string/upcase_spec.rb4
-rw-r--r--spec/ruby/core/string/valid_encoding/utf_8_spec.rb214
-rw-r--r--spec/ruby/core/struct/values_at_spec.rb55
-rw-r--r--spec/ruby/core/symbol/shared/id2name.rb7
-rw-r--r--spec/ruby/core/time/at_spec.rb16
-rw-r--r--spec/ruby/core/time/localtime_spec.rb16
-rw-r--r--spec/ruby/core/time/new_spec.rb94
-rw-r--r--spec/ruby/core/time/shared/gmtime.rb4
-rw-r--r--spec/ruby/core/time/shared/time_params.rb11
-rw-r--r--spec/ruby/core/time/strftime_spec.rb40
-rw-r--r--spec/ruby/core/time/utc_spec.rb41
-rw-r--r--spec/ruby/core/time/zone_spec.rb20
-rw-r--r--spec/ruby/core/tracepoint/inspect_spec.rb9
-rw-r--r--spec/ruby/fixtures/code/concurrent_require_fixture.rb4
-rw-r--r--spec/ruby/fixtures/code/load_wrap_fixture.rb (renamed from spec/ruby/fixtures/code/wrap_fixture.rb)3
-rw-r--r--spec/ruby/language/case_spec.rb4
-rw-r--r--spec/ruby/language/regexp/character_classes_spec.rb5
-rw-r--r--spec/ruby/language/return_spec.rb15
-rw-r--r--spec/ruby/library/coverage/running_spec.rb20
-rw-r--r--spec/ruby/library/coverage/start_spec.rb8
-rw-r--r--spec/ruby/library/date/civil_spec.rb7
-rw-r--r--spec/ruby/library/objectspace/fixtures/trace.rb5
-rw-r--r--spec/ruby/library/objectspace/trace_spec.rb15
-rw-r--r--spec/ruby/library/openssl/x509/name/verify_spec.rb4
-rw-r--r--spec/ruby/library/stringio/initialize_spec.rb85
-rw-r--r--spec/ruby/library/stringio/new_spec.rb8
-rw-r--r--spec/ruby/library/stringio/shared/write.rb22
-rw-r--r--spec/ruby/optional/capi/ext/gc_spec.c6
-rw-r--r--spec/ruby/optional/capi/ext/io_spec.c43
-rw-r--r--spec/ruby/optional/capi/ext/string_spec.c14
-rw-r--r--spec/ruby/optional/capi/io_spec.rb15
-rw-r--r--spec/ruby/optional/capi/string_spec.rb63
-rw-r--r--spec/ruby/shared/rational/Rational.rb48
-rw-r--r--spec/syntax_suggest/integration/exe_cli_spec.rb3
-rw-r--r--spec/syntax_suggest/integration/ruby_command_line_spec.rb43
-rw-r--r--spec/syntax_suggest/integration/syntax_suggest_spec.rb40
-rw-r--r--spec/syntax_suggest/spec_helper.rb6
-rw-r--r--spec/syntax_suggest/unit/around_block_scan_spec.rb12
-rw-r--r--spec/syntax_suggest/unit/block_expand_spec.rb30
-rw-r--r--spec/syntax_suggest/unit/capture/before_after_keyword_ends_spec.rb47
-rw-r--r--spec/syntax_suggest/unit/capture/falling_indent_lines_spec.rb44
-rw-r--r--spec/syntax_suggest/unit/capture_code_context_spec.rb31
-rw-r--r--spec/syntax_suggest/unit/clean_document_spec.rb43
-rw-r--r--spec/syntax_suggest/unit/code_line_spec.rb1
-rw-r--r--spec/syntax_suggest/unit/core_ext_spec.rb34
-rw-r--r--spec/syntax_suggest/unit/display_invalid_blocks_spec.rb2
-rw-r--r--spec/syntax_suggest/unit/scan_history_spec.rb114
-rw-r--r--sprintf.c5
-rw-r--r--st.c74
-rw-r--r--string.c189
-rw-r--r--struct.c123
-rw-r--r--symbol.c52
-rw-r--r--template/Makefile.in7
-rw-r--r--template/extinit.c.tmpl2
-rw-r--r--template/fake.rb.in4
-rw-r--r--template/id.c.tmpl3
-rw-r--r--template/prelude.c.tmpl5
-rw-r--r--test/-ext-/bug_reporter/test_bug_reporter.rb2
-rw-r--r--test/-ext-/string/test_fstring.rb8
-rw-r--r--test/-ext-/string/test_set_len.rb29
-rw-r--r--test/-ext-/symbol/test_type.rb5
-rw-r--r--test/cgi/test_cgi_util.rb18
-rw-r--r--test/coverage/autostart.rb2
-rw-r--r--test/coverage/main.rb1
-rw-r--r--test/coverage/test_coverage.rb7
-rw-r--r--test/fiber/test_enumerator.rb8
-rw-r--r--test/fiber/test_io.rb28
-rw-r--r--test/fiber/test_io_buffer.rb33
-rw-r--r--test/fiber/test_process.rb21
-rw-r--r--test/fiber/test_queue.rb54
-rw-r--r--test/fiber/test_scheduler.rb41
-rw-r--r--test/fiber/test_storage.rb22
-rw-r--r--test/fiber/test_thread.rb22
-rw-r--r--test/irb/test_debug_cmd.rb7
-rw-r--r--test/mkmf/test_config.rb4
-rw-r--r--test/net/fixtures/Makefile6
-rw-r--r--test/net/fixtures/cacert.pem44
-rw-r--r--test/net/fixtures/server.crt99
-rw-r--r--test/net/fixtures/server.key55
-rw-r--r--test/net/http/test_http.rb16
-rw-r--r--test/net/http/test_httpresponse.rb39
-rw-r--r--test/net/http/test_https.rb8
-rw-r--r--test/objspace/test_objspace.rb7
-rw-r--r--test/objspace/test_ractor.rb17
-rw-r--r--test/openssl/fixtures/pkey/p256_too_large.pem5
-rw-r--r--test/openssl/fixtures/pkey/p384_invalid.pem6
-rw-r--r--test/openssl/test_asn1.rb16
-rw-r--r--test/openssl/test_pair.rb2
-rw-r--r--test/openssl/test_pkey.rb5
-rw-r--r--test/openssl/test_pkey_ec.rb7
-rw-r--r--test/openssl/test_ssl.rb26
-rw-r--r--test/openssl/test_ssl_session.rb2
-rw-r--r--test/openssl/test_x509req.rb7
-rw-r--r--test/optparse/test_optparse.rb3
-rw-r--r--test/psych/test_yaml.rb2
-rw-r--r--test/rdoc/support/test_case.rb4
-rw-r--r--test/rdoc/test_rdoc_generator_json_index.rb14
-rw-r--r--test/rdoc/test_rdoc_ri_driver.rb17
-rw-r--r--test/rdoc/test_rdoc_store.rb3
-rw-r--r--test/readline/test_readline.rb7
-rw-r--r--test/resolv/test_dns.rb7
-rw-r--r--test/ripper/test_lexer.rb62
-rw-r--r--test/ripper/test_parser_events.rb17
-rw-r--r--test/ripper/test_ripper.rb22
-rw-r--r--test/ripper/test_scanner_events.rb13
-rw-r--r--test/ruby/enc/test_cesu8.rb4
-rw-r--r--test/ruby/test_argf.rb1
-rw-r--r--test/ruby/test_array.rb4
-rw-r--r--test/ruby/test_assignment.rb10
-rw-r--r--test/ruby/test_ast.rb6
-rw-r--r--test/ruby/test_class.rb7
-rw-r--r--test/ruby/test_clone.rb7
-rw-r--r--test/ruby/test_complex.rb40
-rw-r--r--test/ruby/test_data.rb59
-rw-r--r--test/ruby/test_dir.rb53
-rw-r--r--test/ruby/test_enumerator.rb81
-rw-r--r--test/ruby/test_env.rb16
-rw-r--r--test/ruby/test_exception.rb12
-rw-r--r--test/ruby/test_float.rb14
-rw-r--r--test/ruby/test_gc.rb14
-rw-r--r--test/ruby/test_gc_compact.rb196
-rw-r--r--test/ruby/test_hash.rb71
-rw-r--r--test/ruby/test_integer.rb26
-rw-r--r--test/ruby/test_io.rb58
-rw-r--r--test/ruby/test_io_buffer.rb161
-rw-r--r--test/ruby/test_iseq.rb45
-rw-r--r--test/ruby/test_method.rb21
-rw-r--r--test/ruby/test_mjit.rb39
-rw-r--r--test/ruby/test_module.rb76
-rw-r--r--test/ruby/test_numeric.rb3
-rw-r--r--test/ruby/test_optimization.rb14
-rw-r--r--test/ruby/test_parse.rb22
-rw-r--r--test/ruby/test_proc.rb44
-rw-r--r--test/ruby/test_process.rb132
-rw-r--r--test/ruby/test_range.rb65
-rw-r--r--test/ruby/test_regexp.rb150
-rw-r--r--test/ruby/test_require.rb67
-rw-r--r--test/ruby/test_rubyoptions.rb19
-rw-r--r--test/ruby/test_settracefunc.rb170
-rw-r--r--test/ruby/test_shapes.rb38
-rw-r--r--test/ruby/test_sprintf.rb12
-rw-r--r--test/ruby/test_string.rb28
-rw-r--r--test/ruby/test_struct.rb14
-rw-r--r--test/ruby/test_super.rb29
-rw-r--r--test/ruby/test_syntax.rb38
-rw-r--r--test/ruby/test_time.rb55
-rw-r--r--test/ruby/test_time_tz.rb10
-rw-r--r--test/ruby/test_variable.rb25
-rw-r--r--test/ruby/test_vm_dump.rb2
-rw-r--r--test/ruby/test_weakmap.rb46
-rw-r--r--test/ruby/test_yjit.rb173
-rw-r--r--test/rubygems/bad_rake.rb1
-rw-r--r--test/rubygems/bundler_test_gem.rb421
-rw-r--r--test/rubygems/fake_certlib/openssl.rb1
-rw-r--r--test/rubygems/good_rake.rb1
-rw-r--r--test/rubygems/helper.rb21
-rw-r--r--test/rubygems/installer_test_case.rb1
-rw-r--r--test/rubygems/multifactor_auth_utilities.rb111
-rw-r--r--test/rubygems/package/tar_test_case.rb66
-rw-r--r--test/rubygems/plugin/exception/rubygems_plugin.rb1
-rw-r--r--test/rubygems/plugin/load/rubygems_plugin.rb1
-rw-r--r--test/rubygems/plugin/standarderror/rubygems_plugin.rb1
-rw-r--r--test/rubygems/rubygems/commands/crash_command.rb1
-rw-r--r--test/rubygems/rubygems_plugin.rb1
-rw-r--r--test/rubygems/simple_gem.rb3
-rw-r--r--test/rubygems/specifications/bar-0.0.2.gemspec2
-rw-r--r--test/rubygems/specifications/rubyforge-0.0.1.gemspec2
-rw-r--r--test/rubygems/test_bundled_ca.rb3
-rw-r--r--test/rubygems/test_config.rb3
-rw-r--r--test/rubygems/test_deprecate.rb3
-rw-r--r--test/rubygems/test_exit.rb2
-rw-r--r--test/rubygems/test_gem.rb449
-rw-r--r--test/rubygems/test_gem_available_set.rb1
-rw-r--r--test/rubygems/test_gem_bundler_version_finder.rb6
-rw-r--r--test/rubygems/test_gem_command.rb1
-rw-r--r--test/rubygems/test_gem_command_manager.rb66
-rw-r--r--test/rubygems/test_gem_commands_build_command.rb11
-rw-r--r--test/rubygems/test_gem_commands_cert_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_check_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_cleanup_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_contents_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_dependency_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_environment_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_exec_command.rb853
-rw-r--r--test/rubygems/test_gem_commands_fetch_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_generate_index_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_help_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_info_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_install_command.rb3
-rw-r--r--test/rubygems/test_gem_commands_list_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_lock_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_mirror.rb1
-rw-r--r--test/rubygems/test_gem_commands_open_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_outdated_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_owner_command.rb110
-rw-r--r--test/rubygems/test_gem_commands_pristine_command.rb51
-rw-r--r--test/rubygems/test_gem_commands_push_command.rb116
-rw-r--r--test/rubygems/test_gem_commands_query_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_search_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_server_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_setup_command.rb6
-rw-r--r--test/rubygems/test_gem_commands_signin_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_sources_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_specification_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_stale_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_uninstall_command.rb46
-rw-r--r--test/rubygems/test_gem_commands_unpack_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_update_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_which_command.rb1
-rw-r--r--test/rubygems/test_gem_commands_yank_command.rb121
-rw-r--r--test/rubygems/test_gem_config_file.rb1
-rw-r--r--test/rubygems/test_gem_dependency.rb3
-rw-r--r--test/rubygems/test_gem_dependency_installer.rb35
-rw-r--r--test/rubygems/test_gem_dependency_list.rb1
-rw-r--r--test/rubygems/test_gem_dependency_resolution_error.rb1
-rw-r--r--test/rubygems/test_gem_doctor.rb1
-rw-r--r--test/rubygems/test_gem_ext_builder.rb15
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder.rb71
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/build.rb21
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/custom_name.gemspec8
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.lock (renamed from test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.lock)8
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/Cargo.toml (renamed from test/rubygems/test_gem_ext_cargo_builder/custom_name/Cargo.toml)2
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/ext/custom_name_lib/src/lib.rs (renamed from test/rubygems/test_gem_ext_cargo_builder/custom_name/src/lib.rs)2
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/custom_name/lib/custom_name.rb3
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.lock26
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/Cargo.toml2
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/build.rb21
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/rust_ruby_example.gemspec2
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder/rust_ruby_example/src/lib.rs12
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder_link_flag_converter.rb15
-rw-r--r--test/rubygems/test_gem_ext_cargo_builder_unit.rb15
-rw-r--r--test/rubygems/test_gem_ext_cmake_builder.rb3
-rw-r--r--test/rubygems/test_gem_ext_configure_builder.rb1
-rw-r--r--test/rubygems/test_gem_ext_rake_builder.rb1
-rw-r--r--test/rubygems/test_gem_gem_runner.rb10
-rw-r--r--test/rubygems/test_gem_gemcutter_utilities.rb178
-rw-r--r--test/rubygems/test_gem_impossible_dependencies_error.rb1
-rw-r--r--test/rubygems/test_gem_indexer.rb1
-rw-r--r--test/rubygems/test_gem_install_update_options.rb1
-rw-r--r--test/rubygems/test_gem_installer.rb94
-rw-r--r--test/rubygems/test_gem_local_remote_options.rb1
-rw-r--r--test/rubygems/test_gem_name_tuple.rb1
-rw-r--r--test/rubygems/test_gem_package.rb25
-rw-r--r--test/rubygems/test_gem_package_old.rb1
-rw-r--r--test/rubygems/test_gem_package_tar_header.rb1
-rw-r--r--test/rubygems/test_gem_package_tar_reader.rb50
-rw-r--r--test/rubygems/test_gem_package_tar_reader_entry.rb158
-rw-r--r--test/rubygems/test_gem_package_tar_writer.rb1
-rw-r--r--test/rubygems/test_gem_package_task.rb1
-rw-r--r--test/rubygems/test_gem_path_support.rb1
-rw-r--r--test/rubygems/test_gem_platform.rb1
-rw-r--r--test/rubygems/test_gem_rdoc.rb1
-rw-r--r--test/rubygems/test_gem_remote_fetcher.rb3
-rw-r--r--test/rubygems/test_gem_request.rb14
-rw-r--r--test/rubygems/test_gem_request_connection_pools.rb1
-rw-r--r--test/rubygems/test_gem_request_set.rb1
-rw-r--r--test/rubygems/test_gem_request_set_gem_dependency_api.rb21
-rw-r--r--test/rubygems/test_gem_request_set_lockfile.rb1
-rw-r--r--test/rubygems/test_gem_request_set_lockfile_parser.rb13
-rw-r--r--test/rubygems/test_gem_request_set_lockfile_tokenizer.rb1
-rw-r--r--test/rubygems/test_gem_requirement.rb1
-rw-r--r--test/rubygems/test_gem_resolver.rb1
-rw-r--r--test/rubygems/test_gem_resolver_activation_request.rb1
-rw-r--r--test/rubygems/test_gem_resolver_api_set.rb1
-rw-r--r--test/rubygems/test_gem_resolver_api_specification.rb1
-rw-r--r--test/rubygems/test_gem_resolver_best_set.rb1
-rw-r--r--test/rubygems/test_gem_resolver_composed_set.rb1
-rw-r--r--test/rubygems/test_gem_resolver_conflict.rb1
-rw-r--r--test/rubygems/test_gem_resolver_dependency_request.rb1
-rw-r--r--test/rubygems/test_gem_resolver_git_set.rb19
-rw-r--r--test/rubygems/test_gem_resolver_git_specification.rb5
-rw-r--r--test/rubygems/test_gem_resolver_index_set.rb1
-rw-r--r--test/rubygems/test_gem_resolver_index_specification.rb1
-rw-r--r--test/rubygems/test_gem_resolver_installed_specification.rb1
-rw-r--r--test/rubygems/test_gem_resolver_installer_set.rb1
-rw-r--r--test/rubygems/test_gem_resolver_local_specification.rb1
-rw-r--r--test/rubygems/test_gem_resolver_lock_set.rb1
-rw-r--r--test/rubygems/test_gem_resolver_lock_specification.rb1
-rw-r--r--test/rubygems/test_gem_resolver_requirement_list.rb1
-rw-r--r--test/rubygems/test_gem_resolver_specification.rb1
-rw-r--r--test/rubygems/test_gem_resolver_vendor_set.rb1
-rw-r--r--test/rubygems/test_gem_resolver_vendor_specification.rb1
-rw-r--r--test/rubygems/test_gem_security.rb1
-rw-r--r--test/rubygems/test_gem_security_signer.rb1
-rw-r--r--test/rubygems/test_gem_security_trust_dir.rb1
-rw-r--r--test/rubygems/test_gem_silent_ui.rb1
-rw-r--r--test/rubygems/test_gem_source.rb3
-rw-r--r--test/rubygems/test_gem_source_fetch_problem.rb1
-rw-r--r--test/rubygems/test_gem_source_git.rb26
-rw-r--r--test/rubygems/test_gem_source_installed.rb3
-rw-r--r--test/rubygems/test_gem_source_list.rb1
-rw-r--r--test/rubygems/test_gem_source_local.rb1
-rw-r--r--test/rubygems/test_gem_source_lock.rb7
-rw-r--r--test/rubygems/test_gem_source_specific_file.rb1
-rw-r--r--test/rubygems/test_gem_source_subpath_problem.rb1
-rw-r--r--test/rubygems/test_gem_source_vendor.rb3
-rw-r--r--test/rubygems/test_gem_spec_fetcher.rb1
-rw-r--r--test/rubygems/test_gem_specification.rb80
-rw-r--r--test/rubygems/test_gem_stream_ui.rb37
-rw-r--r--test/rubygems/test_gem_stub_specification.rb1
-rw-r--r--test/rubygems/test_gem_text.rb1
-rw-r--r--test/rubygems/test_gem_uninstaller.rb9
-rw-r--r--test/rubygems/test_gem_unsatisfiable_dependency_error.rb1
-rw-r--r--test/rubygems/test_gem_update_suggestion.rb1
-rw-r--r--test/rubygems/test_gem_uri.rb2
-rw-r--r--test/rubygems/test_gem_uri_formatter.rb1
-rw-r--r--test/rubygems/test_gem_util.rb1
-rw-r--r--test/rubygems/test_gem_version.rb5
-rw-r--r--test/rubygems/test_gem_version_option.rb1
-rw-r--r--test/rubygems/test_kernel.rb13
-rw-r--r--test/rubygems/test_project_sanity.rb35
-rw-r--r--test/rubygems/test_remote_fetch_error.rb3
-rw-r--r--test/rubygems/test_require.rb24
-rw-r--r--test/rubygems/test_rubygems.rb2
-rw-r--r--test/rubygems/test_webauthn_listener.rb143
-rw-r--r--test/rubygems/test_webauthn_listener_response.rb93
-rw-r--r--test/rubygems/test_webauthn_poller.rb124
-rw-r--r--test/rubygems/utilities.rb48
-rw-r--r--test/socket/test_addrinfo.rb4
-rw-r--r--test/stringio/test_stringio.rb2
-rw-r--r--test/strscan/test_stringscanner.rb56
-rw-r--r--test/test_rbconfig.rb9
-rw-r--r--test/test_time.rb9
-rw-r--r--test/test_trick.rb23
-rw-r--r--test/uri/test_common.rb11
-rw-r--r--test/uri/test_generic.rb18
-rw-r--r--test/uri/test_parser.rb22
-rw-r--r--thread.c59
-rw-r--r--thread_pthread.h35
-rw-r--r--thread_sync.c60
-rw-r--r--time.c204
-rw-r--r--timev.h11
-rw-r--r--tool/bundler/dev_gems.rb1
-rw-r--r--tool/bundler/dev_gems.rb.lock20
-rw-r--r--tool/bundler/rubocop_gems.rb1
-rw-r--r--tool/bundler/rubocop_gems.rb.lock10
-rw-r--r--tool/bundler/standard_gems.rb1
-rw-r--r--tool/bundler/standard_gems.rb.lock10
-rw-r--r--tool/bundler/test_gems.rb1
-rw-r--r--tool/bundler/test_gems.rb.lock4
-rwxr-xr-xtool/expand-config.rb12
-rw-r--r--tool/fake.rb9
-rw-r--r--tool/lib/bundled_gem.rb13
-rw-r--r--tool/lib/core_assertions.rb74
-rw-r--r--tool/lib/envutil.rb18
-rw-r--r--tool/lib/leakchecker.rb5
-rw-r--r--tool/m4/ruby_wasm_tools.m413
-rwxr-xr-xtool/make-snapshot2
-rwxr-xr-xtool/merger.rb189
-rwxr-xr-xtool/mjit/bindgen.rb3
-rwxr-xr-xtool/mkconfig.rb4
-rwxr-xr-xtool/rbinstall.rb34
-rw-r--r--tool/rbs_skip_tests11
-rwxr-xr-xtool/redmine-backporter.rb158
-rw-r--r--tool/ruby_vm/views/lib/ruby_vm/mjit/instruction.rb.erb (renamed from tool/ruby_vm/views/lib/mjit/instruction.rb.erb)2
-rwxr-xr-xtool/sync_default_gems.rb40
-rw-r--r--tool/test-bundled-gems.rb18
-rwxr-xr-xtool/test/test_sync_default_gems.rb10
-rw-r--r--tool/update-NEWS-refs.rb25
-rw-r--r--trace_point.rb51
-rw-r--r--variable.c57
-rw-r--r--version.h4
-rw-r--r--vm.c36
-rw-r--r--vm_args.c3
-rw-r--r--vm_backtrace.c9
-rw-r--r--vm_core.h9
-rw-r--r--vm_dump.c19
-rw-r--r--vm_eval.c3
-rw-r--r--vm_insnhelper.c107
-rw-r--r--vm_method.c119
-rw-r--r--vm_trace.c19
-rw-r--r--win32/Makefile.sub16
-rw-r--r--win32/file.c3
-rwxr-xr-xwin32/mkexports.rb1
-rw-r--r--win32/win32.c28
-rw-r--r--win32/winmain.c4
-rw-r--r--yjit.c3
-rw-r--r--yjit.rb15
-rw-r--r--yjit/bindgen/src/main.rs3
-rw-r--r--yjit/src/asm/mod.rs131
-rw-r--r--yjit/src/backend/arm64/mod.rs245
-rw-r--r--yjit/src/codegen.rs115
-rw-r--r--yjit/src/core.rs2
-rw-r--r--yjit/src/cruby_bindings.inc.rs47
-rw-r--r--yjit/src/stats.rs3
-rw-r--r--yjit/src/virtualmem.rs25
-rw-r--r--yjit/src/yjit.rs29
1072 files changed, 44914 insertions, 8366 deletions
diff --git a/.appveyor.yml b/.appveyor.yml
index 6803edff9b..05ff204541 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -26,8 +26,9 @@ environment:
# is limited, and compatibility issues that happen only in newer versions are rare.
# You may test some other stuff on GitHub Actions instead.
- build: vs
- vs: 120
+ vs: 120 # Visual Studio 2013
ssl: OpenSSL-v111
+ # The worker image name. This is NOT the Visual Studio version we're using here.
APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2015
GEMS_FOR_TEST: ""
RELINE_TEST_ENCODING: "UTF-8"
@@ -47,6 +48,7 @@ for:
- cd C:\Tools\vcpkg
- git pull -q
- .\bootstrap-vcpkg.bat
+ - ps: Start-FileDownload 'https://github.com/microsoft/vcpkg-tool/releases/download/2023-08-09/vcpkg.exe' -FileName 'C:\Tools\vcpkg\vcpkg.exe'
- cd %APPVEYOR_BUILD_FOLDER%
- vcpkg --triplet %Platform%-windows install --x-use-aria2 libffi libyaml readline zlib
- CALL SET vcvars=%%^VS%VS%COMNTOOLS^%%..\..\VC\vcvarsall.bat
@@ -75,6 +77,7 @@ for:
- attrib +r /s /d
- mkdir %Platform%-mswin_%vs%
build_script:
+ - set HAVE_GIT=no
- cd %APPVEYOR_BUILD_FOLDER%
- cd %Platform%-mswin_%vs%
- >-
@@ -91,7 +94,7 @@ for:
- nmake -l "TESTOPTS=-v -q" btest
- nmake -l "TESTOPTS=-v -q" test-basic
- >-
- nmake -l "TESTOPTS=-v --timeout-scale=3.0
+ nmake -l "TESTOPTS=--timeout-scale=3.0
--excludes=../test/excludes/_appveyor -j%JOBS%
--exclude win32ole
--exclude test_bignum
@@ -102,7 +105,7 @@ for:
# separately execute tests without -j which may crash worker with -j.
- >-
nmake -l
- "TESTOPTS=-v --timeout-scale=3.0 --excludes=../test/excludes/_appveyor"
+ "TESTOPTS=--timeout-scale=3.0 --excludes=../test/excludes/_appveyor"
TESTS="
../test/win32ole
../test/ruby/test_bignum.rb
diff --git a/.cirrus.yml b/.cirrus.yml
deleted file mode 100644
index 6c47159921..0000000000
--- a/.cirrus.yml
+++ /dev/null
@@ -1,133 +0,0 @@
-# This CI is used to test Arm cases. We can set the maximum 16 tasks.
-# The entire testing design is inspired from .github/workflows/compilers.yml.
-
-# By default, Cirrus mounts an empty volume to `/tmp`
-# which triggers all sorts of warnings like "system temporary path is world-writable: /tmp".
-# Lets workaround it by specifying a custom volume mount point.
-env:
- CIRRUS_VOLUME: /cirrus-ci-volume
- LANG: C.UTF-8
-
-task:
- name: Arm64 Graviton2 / $CC
- skip: "changesIncludeOnly('doc/**', '**.{md,rdoc,ronn,[1-8]}', '.document')"
- arm_container:
- # We use the arm64 images at https://github.com/ruby/ruby-ci-image/pkgs/container/ruby-ci-image .
- image: ghcr.io/ruby/ruby-ci-image:$CC
- # Define the used cpu core in each matrix task. We can use total 16 cpu
- # cores in entire matrix. [cpu] = [total cpu: 16] / [number of tasks]
- cpu: 8
- # We can request maximum 4 GB per cpu.
- # [memory per task] = [memory per cpu: 4 GB] * [cpu]
- memory: 32G
- env:
- CIRRUS_CLONE_DEPTH: 50
- optflags: '-O1'
- debugflags: '-ggdb3'
- RUBY_PREFIX: /tmp/ruby-prefix
- RUBY_DEBUG: ci rgengc
- RUBY_TESTOPTS: >-
- -q
- --color=always
- --tty=no
- matrix:
- CC: clang-12
- CC: gcc-11
- id_script: id
- set_env_script:
- # Set `GNUMAKEFLAGS`, because the flags are GNU make specific. Note using
- # the `make` environment variable used in compilers.yml causes some rubygems
- # tests to fail.
- # https://github.com/rubygems/rubygems/issues/4921
- - echo "GNUMAKEFLAGS=-s -j$((1 + $CIRRUS_CPU))" >> "$CIRRUS_ENV"
- - cat "$CIRRUS_ENV"
- # Arm containers are executed in AWS's EKS, and it's not yet supporting IPv6
- # See https://github.com/aws/containers-roadmap/issues/835
- disable_ipv6_script: sudo ./tool/disable_ipv6.sh
- autogen_script: ./autogen.sh
- configure_script: >-
- ./configure -C
- --enable-debug-env
- --disable-install-doc
- --with-ext=-test-/cxxanyargs,+
- --prefix="$RUBY_PREFIX"
- make_extract-extlibs_script: make extract-extlibs
- make_incs_script: make incs
- make_script: make
- make_leaked-globals_script: make leaked-globals
- make_test_script: make test
- make_install_script: make install
- install_gems_for_test_script: $RUBY_PREFIX/bin/gem install --no-doc timezone tzinfo
- make_test-tool_script: make test-tool
- make_test-all_script: make test-all
- make_test-spec_script: make test-spec
-
-# The following is to test YJIT on ARM64 CPUs available on Cirrus CI
-yjit_task:
- name: Arm64 Graviton2 / $CC YJIT
- auto_cancellation: $CIRRUS_BRANCH != 'master'
- skip: "changesIncludeOnly('doc/**', '**.{md,rdoc,ronn,[1-8]}', '.document')"
- arm_container:
- # We use the arm64 images at https://github.com/ruby/ruby-ci-image/pkgs/container/ruby-ci-image .
- image: ghcr.io/ruby/ruby-ci-image:$CC
- # Define the used cpu core in each matrix task. We can use total 16 cpu
- # cores in entire matrix. [cpu] = [total cpu: 16] / [number of tasks]
- cpu: 8
- # We can request maximum 4 GB per cpu.
- # [memory per task] = [memory per cpu: 4 GB] * [cpu]
- memory: 32G
- env:
- CIRRUS_CLONE_DEPTH: 50
- optflags: '-O1'
- debugflags: '-ggdb3'
- RUBY_PREFIX: /tmp/ruby-prefix
- RUBY_DEBUG: ci rgengc
- RUBY_TESTOPTS: >-
- -q
- --color=always
- --tty=no
- matrix:
- - CC: clang-12
- configure: --enable-yjit=dev
- rustup_init: --default-toolchain=1.58.0
- - CC: gcc-11
- configure: --enable-yjit
- id_script: id
- set_env_script:
- # Set `GNUMAKEFLAGS`, because the flags are GNU make specific. Note using
- # the `make` environment variable used in compilers.yml causes some rubygems
- # tests to fail.
- # https://github.com/rubygems/rubygems/issues/4921
- - echo "GNUMAKEFLAGS=-s -j$((1 + $CIRRUS_CPU))" >> "$CIRRUS_ENV"
- - echo RUST_BACKTRACE=1 >> "$CIRRUS_ENV"
- - cat "$CIRRUS_ENV"
- # Arm containers are executed in AWS's EKS, and it's not yet supporting IPv6
- # See https://github.com/aws/containers-roadmap/issues/835
- disable_ipv6_script: sudo ./tool/disable_ipv6.sh
- install_rust_script:
- - sudo apt-get update -y
- - sudo apt-get install -y curl
- - "curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y $rustup_init"
- autogen_script: ./autogen.sh
- configure_script: >-
- source $HOME/.cargo/env && ./configure -C
- --enable-debug-env
- --disable-install-doc
- --with-ext=-test-/cxxanyargs,+
- --prefix="$RUBY_PREFIX"
- $configure
- make_miniruby_script: source $HOME/.cargo/env && make miniruby
- make_bindgen_script: |
- if [[ "$CC" = "clang-12" ]]; then
- source $HOME/.cargo/env && make yjit-bindgen
- else
- echo "only running bindgen on clang image"
- fi
- boot_miniruby_script: ./miniruby --yjit-call-threshold=1 -e0
- test_dump_insns_script: ./miniruby --yjit-call-threshold=1 --yjit-dump-insns -e0
- output_stats_script: ./miniruby --yjit-call-threshold=1 --yjit-stats -e0
- full_build_script: source $HOME/.cargo/env && make
- cargo_test_script: source $HOME/.cargo/env && cd yjit && cargo test
- make_test_script: source $HOME/.cargo/env && make test RUN_OPTS="--yjit-call-threshold=1 --yjit-verify-ctx"
- make_test_all_script: source $HOME/.cargo/env && make test-all RUN_OPTS="--yjit-call-threshold=1 --yjit-verify-ctx" TESTOPTS="$RUBY_TESTOPTS"
- make_test_spec_script: source $HOME/.cargo/env && make test-spec RUN_OPTS="--yjit-call-threshold=1 --yjit-verify-ctx"
diff --git a/.document b/.document
index 7c6d9967b1..3a6b0c238c 100644
--- a/.document
+++ b/.document
@@ -18,6 +18,7 @@ gc.rb
io.rb
kernel.rb
marshal.rb
+mjit.rb
numeric.rb
nilclass.rb
pack.rb
@@ -28,6 +29,7 @@ timev.rb
thread_sync.rb
trace_point.rb
warning.rb
+yjit.rb
# the lib/ directory (which has its own .document file)
lib
diff --git a/.github/auto_request_review.yml b/.github/auto_request_review.yml
deleted file mode 100644
index d058b6ca00..0000000000
--- a/.github/auto_request_review.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-files:
- 'yjit*': [team:yjit]
- 'yjit/**/*': [team:yjit]
- 'doc/yjit/*': [team:yjit]
- 'bootstraptest/test_yjit*': [team:yjit]
- 'test/ruby/test_yjit*': [team:yjit]
- '.github/workflows/yjit*': [team:yjit]
-options:
- ignore_draft: true
diff --git a/.github/workflows/auto_request_review.yml b/.github/workflows/auto_request_review.yml
deleted file mode 100644
index f837905fe6..0000000000
--- a/.github/workflows/auto_request_review.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-name: Auto Request Review
-on:
- pull_request_target:
- types: [opened, ready_for_review, reopened]
-
-permissions:
- contents: read
-
-jobs:
- auto-request-review:
- name: Auto Request Review
- runs-on: ubuntu-latest
- if: ${{ github.repository == 'ruby/ruby' }}
- steps:
- - name: Request review based on files changes and/or groups the author belongs to
- uses: necojackarc/auto-request-review@b5e81876454003a4ccb9b89cb205c67d77d7035b # v0.8.0
- with:
- # scope: public_repo
- token: ${{ secrets.MATZBOT_GITHUB_TOKEN }}
diff --git a/.github/workflows/baseruby.yml b/.github/workflows/baseruby.yml
index 620847597d..ebaafe3bf0 100644
--- a/.github/workflows/baseruby.yml
+++ b/.github/workflows/baseruby.yml
@@ -4,19 +4,24 @@ on:
push:
paths-ignore:
- 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
pull_request:
paths-ignore:
- 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -28,7 +33,7 @@ permissions:
jobs:
baseruby:
name: BASERUBY
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
strategy:
matrix:
@@ -43,12 +48,12 @@ jobs:
- ruby-3.1
steps:
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: .downloaded-cache
key: downloaded-cache
- - uses: ruby/setup-ruby@c7079efafd956afb5d823e8999c2506e1053aefa # v1.126.0
+ - uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
with:
ruby-version: ${{ matrix.ruby }}
bundler: none
@@ -60,7 +65,7 @@ jobs:
- run: make incs
- run: make all
- run: make test
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
diff --git a/.github/workflows/bundled_gems.yml b/.github/workflows/bundled_gems.yml
index c273c9d57d..070c0fa1dd 100644
--- a/.github/workflows/bundled_gems.yml
+++ b/.github/workflows/bundled_gems.yml
@@ -2,10 +2,17 @@ name: bundled_gems
on:
push:
+ branches: [ "master" ]
paths:
- '.github/workflows/bundled_gems.yml'
- 'gems/bundled_gems'
pull_request:
+ branches: [ "master" ]
+ paths:
+ - '.github/workflows/bundled_gems.yml'
+ - 'gems/bundled_gems'
+ merge_group:
+ branches: [ "master" ]
paths:
- '.github/workflows/bundled_gems.yml'
- 'gems/bundled_gems'
@@ -34,9 +41,9 @@ jobs:
echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
echo "TODAY=$(date +%F)" >> $GITHUB_ENV
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: .downloaded-cache
key: downloaded-cache-${{ github.sha }}
@@ -81,7 +88,7 @@ jobs:
news.sub!(/^\*( +)The following default gems are now bundled gems\.\n+\K(?: \1\*( +).*\n)*/) do
mark = "#{$1} *#{$2}"
added.map {|g, v|"#{mark}#{g} #{v}\n"}.join("")
- end or next if added
+ end or next unless added.empty?
File.write("NEWS.md", news)
end
shell: ruby {0}
@@ -144,7 +151,7 @@ jobs:
GIT_COMMITTER_NAME: git
if: ${{ github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull') && steps.show.outcome == 'failure' }}
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml
index cf9b5e8b60..79b2916feb 100644
--- a/.github/workflows/check_dependencies.yml
+++ b/.github/workflows/check_dependencies.yml
@@ -3,19 +3,24 @@ on:
push:
paths-ignore:
- 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
pull_request:
paths-ignore:
- 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -28,7 +33,7 @@ jobs:
update-deps:
strategy:
matrix:
- os: [ubuntu-20.04]
+ os: [ubuntu-22.04]
fail-fast: true
runs-on: ${{ matrix.os }}
if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
@@ -41,15 +46,14 @@ jobs:
if: ${{ contains(matrix.os, 'ubuntu') }}
- name: Install libraries
run: |
- brew upgrade
brew install gmp libffi openssl@1.1 zlib autoconf automake libtool readline
if: ${{ contains(matrix.os, 'macos') }}
- name: git config
run: |
git config --global advice.detachedHead 0
git config --global init.defaultBranch garbage
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: .downloaded-cache
key: downloaded-cache
@@ -59,7 +63,7 @@ jobs:
- run: make all golf
- run: ruby tool/update-deps --fix
- run: git diff --no-ext-diff --ignore-submodules --exit-code
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
diff --git a/.github/workflows/check_misc.yml b/.github/workflows/check_misc.yml
deleted file mode 100644
index 2a8cfabefd..0000000000
--- a/.github/workflows/check_misc.yml
+++ /dev/null
@@ -1,122 +0,0 @@
-name: Miscellaneous checks
-on: [push, pull_request]
-
-concurrency:
- group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
- cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }}
-
-permissions:
- contents: read
-
-jobs:
- checks:
- permissions:
- contents: write # for Git to git push
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
- - name: Check if C-sources are US-ASCII
- run: |
- ! grep -r -n '[^ -~]' -- *.[chy] include internal win32/*.[ch]
- - name: Check for trailing spaces
- run: |
- ! git grep -n '[ ]$' -- '*.rb' '*.[chy]'
- ! git grep -n '^[ ][ ]*$' -- '*.md'
- - name: Check for bash specific substitution in configure.ac
- run: |
- ! git grep -n '\${[A-Za-z_0-9]*/' -- configure.ac
- - name: Check for header macros
- run: |
- ! for header in ruby/*.h; do \
- git grep -l -F -e $header -e HAVE_`echo $header | tr a-z./ A-Z__` -- . > /dev/null || echo $header
- done | grep -F .
- working-directory: include
-
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
- with:
- path: .downloaded-cache
- key: downloaded-cache-${{ github.sha }}
- restore-keys: |
- downloaded-cache
-
- - name: Download previous gems list
- run: |
- data=default_gems.json
- mkdir -p .downloaded-cache
- ln -s .downloaded-cache/$data .
- curl -O -R -z ./$data https://stdgems.org/$data
-
- - name: Make default gems list
- run: |
- #!ruby
- require 'rubygems'
- $:.unshift "lib"
- rgver = File.foreach("lib/rubygems.rb") do |line|
- break $1 if /^\s*VERSION\s*=\s*"([^"]+)"/ =~ line
- end
- gems = Dir.glob("{ext,lib}/**/*.gemspec").map do |f|
- spec = Gem::Specification.load(f)
- "#{spec.name} #{spec.version}"
- end.sort
- File.open("gems/default_gems", "w") do |f|
- f.puts "RubyGems #{rgver}"
- f.puts gems
- end
- shell: ruby --disable=gems {0}
-
- - name: Maintain updated gems list in NEWS
- run: |
- #!ruby
- require 'json'
- news = File.read("NEWS.md")
- prev = news[/since the \*+(\d+\.\d+\.\d+)\*+/, 1]
- prevs = [prev, prev.sub(/\.\d+\z/, '')]
- %W[default].each do |type|
- last = JSON.parse(File.read("#{type}_gems.json"))['gems'].filter_map do |g|
- v = g['versions'].values_at(*prevs).compact.first
- g = g['gem']
- g = 'RubyGems' if g == 'rubygems'
- [g, v] if v
- end.to_h
- changed = File.foreach("gems/#{type}_gems").filter_map do |l|
- next if l.start_with?("#")
- g, v = l.split(" ", 3)
- [g, v] unless last[g] == v
- end
- news.sub!(/^\*( +)The following #{type} gems? are updated\.\n+\K(?: \1\* .*\n)*/) do
- mark = "#{$1} * "
- changed.map {|g, v|"#{mark}#{g} #{v}\n"}.join("")
- end or next
- File.write("NEWS.md", news)
- end
- shell: ruby {0}
-
- - name: Check diffs
- id: diff
- run: |
- git diff --color --no-ext-diff --ignore-submodules --exit-code NEWS.md
- continue-on-error: true
- - name: Commit
- run: |
- git pull --ff-only origin ${GITHUB_REF#refs/heads/}
- git commit --message="Update default gems list at ${GITHUB_SHA:0:30} [ci skip]" NEWS.md
- git push origin ${GITHUB_REF#refs/heads/}
- env:
- EMAIL: svn-admin@ruby-lang.org
- GIT_AUTHOR_NAME: git
- GIT_COMMITTER_NAME: git
- if: ${{ github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull') && steps.diff.outcome == 'failure' }}
-
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
- with:
- payload: |
- {
- "ci": "GitHub Actions",
- "env": "${{ github.workflow }}",
- "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}",
- "commit": "${{ github.sha }}",
- "branch": "${{ github.ref_name }}"
- }
- env:
- SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() && github.event_name == 'push' }}
diff --git a/.github/workflows/cirrus-notify.yml b/.github/workflows/cirrus-notify.yml
deleted file mode 100644
index 5edba0ae8f..0000000000
--- a/.github/workflows/cirrus-notify.yml
+++ /dev/null
@@ -1,46 +0,0 @@
-on:
- check_suite:
- type: ['completed']
-name: Cirrus CI failure notification
-
-permissions:
- contents: read
-
-jobs:
- cirrus-notify:
- name: After Cirrus CI Failure
- if: >-
- github.event.check_suite.app.name == 'Cirrus CI'
- && github.event.check_suite.conclusion != 'success'
- && github.event.check_suite.conclusion != 'cancelled'
- && github.event.check_suite.conclusion != 'skipped'
- && github.event.check_suite.head_branch == 'master'
- runs-on: ubuntu-latest
- steps:
- - uses: octokit/request-action@52ce92ce3185e00e2425f043c3e9509121929aea # v2.x
- id: get_failed_check_run
- with:
- route: GET /repos/${{ github.repository }}/check-suites/${{ github.event.check_suite.id }}/check-runs?status=completed
- mediaType: '{"previews": ["antiope"]}'
- env:
- GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- - name: Dump GitHub context
- env:
- GITHUB_CONTEXT: ${{ toJson(github) }}
- run: echo "$GITHUB_CONTEXT"
- - name: Dump check_runs
- env:
- CHECK_RUNS: ${{ steps.get_failed_check_run.outputs.data }}
- run: echo "$CHECK_RUNS"
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
- with:
- payload: |
- {
- "ci": "Cirrus CI",
- "env": "Cirrus CI",
- "url": "${{ fromJson(steps.get_failed_check_run.outputs.data).check_runs[0].html_url }}",
- "commit": "${{ github.event.check_suite.head_commit.id }}",
- "branch": "${{ github.event.check_suite.head_branch }}"
- }
- env:
- SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 643d6ddf92..8dba76fbe2 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -4,19 +4,17 @@ on:
# push:
# paths-ignore:
# - 'doc/**'
+ # - '**/man'
# - '**.md'
# - '**.rdoc'
# - '**/.document'
- # - '**.[1-8]'
- # - '**.ronn'
# pull_request:
# paths-ignore:
# - 'doc/**'
+ # - '**/man'
# - '**.md'
# - '**.rdoc'
# - '**/.document'
- # - '**.[1-8]'
- # - '**.ronn'
schedule:
- cron: '0 12 * * *'
workflow_dispatch:
@@ -51,9 +49,9 @@ jobs:
sudo apt-get install --no-install-recommends -q -y build-essential libssl-dev libyaml-dev libreadline6-dev zlib1g-dev libncurses5-dev libffi-dev bison autoconf ruby
- name: Checkout repository
- uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: .downloaded-cache
key: downloaded-cache
@@ -62,15 +60,16 @@ jobs:
run: sudo rm /usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb
- name: Initialize CodeQL
- uses: github/codeql-action/init@b2a92eb56d8cb930006a1c6ed86b0782dd8a4297 # v2.1.35
+ uses: github/codeql-action/init@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
with:
config-file: ./.github/codeql/codeql-config.yml
+ trap-caching: false
- name: Set ENV
run: echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV
- name: Autobuild
- uses: github/codeql-action/autobuild@b2a92eb56d8cb930006a1c6ed86b0782dd8a4297 # v2.1.35
+ uses: github/codeql-action/autobuild@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@b2a92eb56d8cb930006a1c6ed86b0782dd8a4297 # v2.1.35
+ uses: github/codeql-action/analyze@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37
diff --git a/.github/workflows/compilers.yml b/.github/workflows/compilers.yml
index b6db2138fd..caf12cc0f4 100644
--- a/.github/workflows/compilers.yml
+++ b/.github/workflows/compilers.yml
@@ -4,19 +4,22 @@ on:
push:
paths-ignore:
- 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
pull_request:
paths-ignore:
- 'doc/**'
- - '**.md'
+ - '**/man'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -77,27 +80,13 @@ jobs:
- { name: gcc-9, env: { default_cc: gcc-9 } }
- { name: gcc-8, env: { default_cc: gcc-8 } }
- { name: gcc-7, env: { default_cc: gcc-7 } }
- - { name: gcc-6, env: { default_cc: gcc-6 } }
- - { name: gcc-5, env: { default_cc: gcc-5 } }
- - { name: gcc-4.8, env: { default_cc: gcc-4.8 } }
- - name: 'gcc-11 LTO'
- container: gcc-11
+ - name: 'gcc-13 LTO'
+ container: gcc-13
env:
- default_cc: 'gcc-11 -flto=auto -ffat-lto-objects'
+ default_cc: 'gcc-13 -flto=auto -ffat-lto-objects -Werror=lto-type-mismatch'
optflags: '-O2'
shared: disable
# check: true
- - name: 'gcc-11 annocheck'
- container: gcc-11
- env:
- # Minimal flags to pass the check.
- default_cc: 'gcc-11 -O2 -fcf-protection -Wa,--generate-missing-build-notes=yes'
- LDFLAGS: '-Wl,-z,now'
- # FIXME: Drop skipping options
- # https://bugs.ruby-lang.org/issues/18061
- # https://sourceware.org/annobin/annobin.html/Test-pie.html
- TEST_ANNOCHECK_OPTS: "--skip-pie"
- check: true
- { name: clang-16, env: { default_cc: clang-16 } }
- { name: clang-15, env: { default_cc: clang-15 } }
- { name: clang-14, env: { default_cc: clang-14 } }
@@ -105,17 +94,15 @@ jobs:
- { name: clang-12, env: { default_cc: clang-12 } }
- { name: clang-11, env: { default_cc: clang-11 } }
- { name: clang-10, env: { default_cc: clang-10 } }
- - { name: clang-9, env: { default_cc: clang-9 } }
- - { name: clang-8, env: { default_cc: clang-8 } }
- - { name: clang-7, env: { default_cc: clang-7 } }
- - { name: clang-6.0, env: { default_cc: clang-6.0 } }
- - { name: clang-5.0, env: { default_cc: clang-5.0 } }
- - { name: clang-4.0, env: { default_cc: clang-4.0 } }
- - { name: clang-3.9, env: { default_cc: clang-3.9 } }
- - name: 'clang-14 LTO'
- container: clang-14
+ # llvm-objcopy<=9 doesn't have --wildcard. It compiles, but leaves Rust symbols in libyjit.o.
+ - { name: clang-9, env: { default_cc: clang-9, append_configure: '--disable-yjit' } }
+ - { name: clang-8, env: { default_cc: clang-8, append_configure: '--disable-yjit' } }
+ - { name: clang-7, env: { default_cc: clang-7, append_configure: '--disable-yjit' } }
+ - { name: clang-6.0, env: { default_cc: clang-6.0, append_configure: '--disable-yjit' } }
+ - name: 'clang-16 LTO'
+ container: clang-16
env:
- default_cc: 'clang-14 -flto=auto'
+ default_cc: 'clang-16 -flto=auto'
optflags: '-O2'
shared: disable
# check: true
@@ -181,7 +168,11 @@ jobs:
# - { name: VM_CHECK_MODE, env: { cppflags: '-DVM_CHECK_MODE' } }
- { name: USE_EMBED_CI=0, env: { cppflags: '-DUSE_EMBED_CI=0' } }
- - { name: USE_FLONUM=0, env: { cppflags: '-DUSE_FLONUM=0' } }
+ - name: USE_FLONUM=0,
+ env:
+ cppflags: '-DUSE_FLONUM=0'
+ # yjit requires FLONUM for the pointer tagging scheme
+ append_configure: '--disable-yjit'
# - { name: USE_GC_MALLOC_OBJ_INFO_DETAILS, env: { cppflags: '-DUSE_GC_MALLOC_OBJ_INFO_DETAILS' } }
- { name: USE_LAZY_LOAD, env: { cppflags: '-DUSE_LAZY_LOAD' } }
# - { name: USE_RINCGC=0, env: { cppflags: '-DUSE_RINCGC=0' } }
@@ -234,10 +225,10 @@ jobs:
- name: setenv
run: |
echo "GNUMAKEFLAGS=-sj$((1 + $(nproc --all)))" >> $GITHUB_ENV
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: src/.downloaded-cache
key: downloaded-cache
@@ -271,7 +262,7 @@ jobs:
- run: make test-annocheck
if: ${{ matrix.entry.check && endsWith(matrix.entry.name, 'annocheck') }}
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml
index 92ea46388e..d8dc58b119 100644
--- a/.github/workflows/macos.yml
+++ b/.github/workflows/macos.yml
@@ -3,19 +3,24 @@ on:
push:
paths-ignore:
- 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
pull_request:
paths-ignore:
- 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -30,8 +35,9 @@ jobs:
matrix:
test_task: ["check"] # "test-bundler-parallel", "test-bundled-gems"
os:
- - macos-11
- - macos-12
+ - macos-13
+ - macos-14
+ - macos-15
fail-fast: false
env:
GITPULLOPTIONS: --no-tags origin ${{github.ref}}
@@ -44,22 +50,21 @@ jobs:
run: |
git config --global advice.detachedHead 0
git config --global init.defaultBranch garbage
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: src/.downloaded-cache
key: downloaded-cache
- name: Install libraries
run: |
- brew upgrade
brew install gmp libffi openssl@1.1 zlib autoconf automake libtool readline bison
working-directory: src
- name: Set ENV
run: |
echo "MAKEFLAGS=-j$((1 + $(sysctl -n hw.activecpu)))" >> $GITHUB_ENV
- echo "PATH="/usr/local/opt/bison/bin:$PATH"" >> $GITHUB_ENV
+ echo "PATH="/usr/local/opt/bison/bin:/opt/homebrew/opt/bison/bin:$PATH"" >> $GITHUB_ENV
- run: ./autogen.sh
working-directory: src
- name: Run configure
@@ -89,7 +94,7 @@ jobs:
PRECHECK_BUNDLED_GEMS: "no"
if: ${{ matrix.test_task == 'check' && matrix.skipped_tests != '' }}
continue-on-error: ${{ matrix.continue-on-skipped_tests || false }}
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml
index c5c24d9c17..0df917d3d8 100644
--- a/.github/workflows/mingw.yml
+++ b/.github/workflows/mingw.yml
@@ -3,19 +3,24 @@ on:
push:
paths-ignore:
- 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
pull_request:
paths-ignore:
- 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -60,15 +65,15 @@ jobs:
git config --global core.eol lf
git config --global advice.detachedHead 0
git config --global init.defaultBranch garbage
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: src/.downloaded-cache
key: downloaded-cache
- name: Set up Ruby & MSYS2
- uses: ruby/setup-ruby@c7079efafd956afb5d823e8999c2506e1053aefa # v1.126.0
+ uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
with:
ruby-version: ${{ matrix.base_ruby }}
- name: set env
@@ -154,7 +159,7 @@ jobs:
make ${{ StartsWith(matrix.test_task, 'spec/') && matrix.test_task || 'test-spec' }}
if: ${{matrix.test_task == 'check' || matrix.test_task == 'test-spec' || StartsWith(matrix.test_task, 'spec/')}}
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
diff --git a/.github/workflows/mjit-bindgen.yml b/.github/workflows/mjit-bindgen.yml
index f6d3ff793a..26f8a1b2aa 100644
--- a/.github/workflows/mjit-bindgen.yml
+++ b/.github/workflows/mjit-bindgen.yml
@@ -3,19 +3,24 @@ on:
push:
paths-ignore:
- 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
pull_request:
paths-ignore:
- 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -31,7 +36,7 @@ jobs:
include:
- task: mjit-bindgen
fail-fast: false
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
- run: mkdir build
@@ -47,21 +52,21 @@ jobs:
build-essential \
libssl-dev libyaml-dev libreadline6-dev \
zlib1g-dev libncurses5-dev libffi-dev \
- libclang1-10 \
+ libclang1-14 \
bison autoconf
sudo apt-get install -q -y pkg-config || :
- name: Set up Ruby
- uses: ruby/setup-ruby@c7079efafd956afb5d823e8999c2506e1053aefa # v1.126.0
+ uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
with:
ruby-version: '3.1'
- name: git config
run: |
git config --global advice.detachedHead 0
git config --global init.defaultBranch garbage
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: src/.downloaded-cache
key: downloaded-cache
@@ -80,7 +85,7 @@ jobs:
- run: make ${{ matrix.task }}
- run: git diff --exit-code
working-directory: src
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
diff --git a/.github/workflows/mjit.yml b/.github/workflows/mjit.yml
index f2fd9ad076..6f7181489a 100644
--- a/.github/workflows/mjit.yml
+++ b/.github/workflows/mjit.yml
@@ -3,12 +3,20 @@ on:
push:
paths-ignore:
- 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ pull_request:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- '**.[1-8]'
- '**.ronn'
- pull_request:
+ merge_group:
paths-ignore:
- 'doc/**'
- '**.md'
@@ -49,10 +57,10 @@ jobs:
run: |
git config --global advice.detachedHead 0
git config --global init.defaultBranch garbage
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: src/.downloaded-cache
key: downloaded-cache
@@ -71,10 +79,9 @@ jobs:
- run: make incs
- run: make
- run: sudo make -s install
- - run: sudo apt-get install gdb # used by test / test-all failure
- name: Run test
run: |
- ulimit -c unlimited
+ unset GNUMAKEFLAGS
make -s test RUN_OPTS="$RUN_OPTS"
timeout-minutes: 60
# - name: Run test-all
@@ -84,10 +91,10 @@ jobs:
# timeout-minutes: 60
- name: Run test-spec
run: |
- ulimit -c unlimited
+ unset GNUMAKEFLAGS
make -s test-spec RUN_OPTS="$RUN_OPTS"
timeout-minutes: 60
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml
new file mode 100644
index 0000000000..5d4474d978
--- /dev/null
+++ b/.github/workflows/publish.yml
@@ -0,0 +1,18 @@
+name: Start release workflow
+on:
+ push:
+ tags:
+ - '*'
+
+jobs:
+ notify:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Build release package
+ run: |
+ curl -L -X POST \
+ -H "Authorization: Bearer ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }}" \
+ -H "Accept: application/vnd.github+json" \
+ -H "X-GitHub-Api-Version: 2022-11-28" \
+ https://api.github.com/repos/ruby/actions/dispatches \
+ -d '{"event_type": "${{ github.ref }}"}'
diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml
index 8236a2cd1a..c12a95362d 100644
--- a/.github/workflows/scorecards.yml
+++ b/.github/workflows/scorecards.yml
@@ -32,12 +32,12 @@ jobs:
steps:
- name: "Checkout code"
- uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
+ uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
persist-credentials: false
- name: "Run analysis"
- uses: ossf/scorecard-action@99c53751e09b9529366343771cc321ec74e9bd3d # v2.0.6
+ uses: ossf/scorecard-action@ea651e62978af7915d09fe2e282747c798bf2dab # v2.4.1
with:
results_file: results.sarif
results_format: sarif
@@ -59,7 +59,7 @@ jobs:
# Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
# format to the repository Actions tab.
- name: "Upload artifact"
- uses: actions/upload-artifact@83fd05a356d7e2593de66fc9913b3002723633cb # v3.1.1
+ uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
with:
name: SARIF file
path: results.sarif
@@ -67,6 +67,6 @@ jobs:
# Upload the results to GitHub's code scanning dashboard.
- name: "Upload to code-scanning"
- uses: github/codeql-action/upload-sarif@b2a92eb56d8cb930006a1c6ed86b0782dd8a4297 # v2.1.27
+ uses: github/codeql-action/upload-sarif@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.27
with:
sarif_file: results.sarif
diff --git a/.github/workflows/spec_guards.yml b/.github/workflows/spec_guards.yml
index 2936e892a3..4521195a2b 100644
--- a/.github/workflows/spec_guards.yml
+++ b/.github/workflows/spec_guards.yml
@@ -6,9 +6,10 @@ on:
- 'spec/**'
- '!spec/*.md'
pull_request:
- paths-ignore:
+ paths:
- 'spec/**'
- '!spec/*.md'
+ merge_group:
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -20,28 +21,42 @@ permissions:
jobs:
rubyspec:
name: Rubyspec
- runs-on: ubuntu-20.04
- if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
+
+ runs-on: ubuntu-22.04
+
+ if: >-
+ ${{!(false
+ || contains(github.event.head_commit.message, '[DOC]')
+ || contains(github.event.head_commit.message, 'Document')
+ || contains(github.event.pull_request.title, '[DOC]')
+ || contains(github.event.pull_request.title, 'Document')
+ || contains(github.event.pull_request.labels.*.name, 'Document')
+ || (github.event_name == 'push' && github.actor == 'dependabot[bot]')
+ )}}
+
strategy:
matrix:
# Specs from ruby/spec should still run on all supported Ruby versions.
# This also ensures the needed ruby_version_is guards are there, see spec/README.md.
ruby:
- - ruby-2.7
- ruby-3.1
+ - ruby-3.2
steps:
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
- - uses: ruby/setup-ruby@c7079efafd956afb5d823e8999c2506e1053aefa # v1.126.0
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
+
+ - uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
with:
ruby-version: ${{ matrix.ruby }}
bundler: none
+
- run: gem install webrick
+
- run: ruby ../mspec/bin/mspec
working-directory: spec/ruby
env:
CHECK_LEAKS: true
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
@@ -53,4 +68,4 @@ jobs:
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot
- if: ${{ failure() && github.event_name == 'push' }}
+ if: ${{ failure() }}
diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml
index f5b259c84a..4fbca1170e 100644
--- a/.github/workflows/ubuntu.yml
+++ b/.github/workflows/ubuntu.yml
@@ -3,19 +3,24 @@ on:
push:
paths-ignore:
- 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
pull_request:
paths-ignore:
- 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -41,7 +46,6 @@ jobs:
- test_task: check
configure: "--enable-shared --enable-load-relative"
- test_task: test-all TESTS=--repeat-count=2
- - test_task: test-syntax-suggest
- test_task: test-bundler-parallel
- test_task: test-bundled-gems
fail-fast: false
@@ -49,7 +53,7 @@ jobs:
GITPULLOPTIONS: --no-tags origin ${{github.ref}}
RUBY_DEBUG: ci
SETARCH: ${{ matrix.arch && format('setarch {0}', matrix.arch) }}
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
- run: mkdir build
@@ -75,10 +79,10 @@ jobs:
run: |
git config --global advice.detachedHead 0
git config --global init.defaultBranch garbage
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: src/.downloaded-cache
key: downloaded-cache
@@ -123,7 +127,7 @@ jobs:
TESTS: ${{ matrix.skipped_tests }}
if: ${{ matrix.test_task == 'check' && matrix.skipped_tests != '' }}
continue-on-error: ${{ matrix.continue-on-skipped_tests || false }}
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml
index 44e10f01c3..27920b5821 100644
--- a/.github/workflows/wasm.yml
+++ b/.github/workflows/wasm.yml
@@ -3,19 +3,24 @@ on:
push:
paths-ignore:
- 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
pull_request:
paths-ignore:
- 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -45,7 +50,7 @@ jobs:
WASI_SDK_VERSION_MINOR: 0
BINARYEN_VERSION: 109
WASMTIME_VERSION: v0.33.0
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
- run: mkdir build
@@ -54,7 +59,7 @@ jobs:
run: |
git config --global advice.detachedHead 0
git config --global init.defaultBranch garbage
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
- name: Install libraries
@@ -86,6 +91,18 @@ jobs:
echo "WASI_SDK_PATH=/opt/wasi-sdk" >> $GITHUB_ENV
- run: ./autogen.sh
working-directory: src
+
+ - uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0
+ with:
+ ruby-version: '3.0'
+ bundler: none
+
+ - name: Download config.guess with wasi version
+ run: |
+ rm tool/config.guess tool/config.sub
+ ruby tool/downloader.rb -d tool -e gnu config.guess config.sub
+ working-directory: src
+
- name: Run configure
run: |
../src/configure \
@@ -110,7 +127,7 @@ jobs:
ruby ./bootstraptest/runner.rb --ruby="$(which wasmtime) run $PWD/../build/ruby --mapdir /::./ -- " --verbose "--sets=$NO_THREAD_TESTS"
working-directory: src
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml
index 674f627ef9..c2bd4881c2 100644
--- a/.github/workflows/windows.yml
+++ b/.github/workflows/windows.yml
@@ -3,19 +3,24 @@ on:
push:
paths-ignore:
- 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
pull_request:
paths-ignore:
- 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -29,85 +34,68 @@ jobs:
strategy:
matrix:
include:
- - vs: 2019
- vs: 2022
+ vcvers: -vcvars_ver=14.2
fail-fast: false
- runs-on: windows-${{ matrix.vs < 2022 && '2019' || matrix.vs }}
+ runs-on: windows-${{ matrix.vs }}
if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
name: VisualStudio ${{ matrix.vs }}
env:
GITPULLOPTIONS: --no-tags origin ${{github.ref}}
PATCH: C:\msys64\usr\bin\patch.exe
- OS_VER: windows-${{ matrix.vs < 2022 && '2019' || matrix.vs }}
+ OS_VER: windows-${{ matrix.vs }}
steps:
- run: md build
working-directory:
- - uses: msys2/setup-msys2@d40200dc2db4c351366b048a9565ad82919e1c24 # v2
+ - uses: msys2/setup-msys2@61f9e5e925871ba6c9e3e8da24ede83ea27fa91f # v2.27.0
id: setup-msys2
with:
update: true
- install: >-
- patch
- if: ${{ env.OS_VER != 'windows-2019' }}
+ install: bison patch
- name: patch path
shell: msys2 {0}
run: echo PATCH=$(cygpath -wa $(command -v patch)) >> $GITHUB_ENV
if: ${{ steps.setup-msys2.outcome == 'success' }}
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
- with:
- path: C:\vcpkg\downloads
- key: ${{ runner.os }}-vcpkg-download-${{ env.OS_VER }}-${{ github.sha }}
- restore-keys: |
- ${{ runner.os }}-vcpkg-download-${{ env.OS_VER }}-
- ${{ runner.os }}-vcpkg-download-
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: C:\vcpkg\installed
- key: ${{ runner.os }}-vcpkg-installed-${{ matrix.os }}-${{ github.sha }}
+ key: ${{ runner.os }}-vcpkg-installed-windows-${{ matrix.vs }}-${{ github.sha }}
restore-keys: |
- ${{ runner.os }}-vcpkg-installed-${{ matrix.os }}-
- ${{ runner.os }}-vcpkg-installed-
+ ${{ runner.os }}-vcpkg-installed-windows-${{ matrix.vs }}-
+ ${{ runner.os }}-vcpkg-installed-windows-
- name: Install libraries with vcpkg
run: |
+ iex "& {$(irm get.scoop.sh)} -RunAsAdmin"
+ Join-Path (Resolve-Path ~).Path "scoop\shims" >> $Env:GITHUB_PATH
+ scoop install cmake@3.31.6
vcpkg --triplet x64-windows install libffi libyaml openssl readline zlib
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
- with:
- path: C:\Users\runneradmin\AppData\Local\Temp\chocolatey
- key: ${{ runner.os }}-chocolatey-${{ env.OS_VER }}-${{ github.sha }}
- restore-keys: |
- ${{ runner.os }}-chocolatey-${{ env.OS_VER }}-
- ${{ runner.os }}-chocolatey-
- - name: Install libraries with chocolatey
- run: |
- # Using Choco-Install for retries, but it doesn't detect failures properly
- # if you pass multiple package names in a single command.
- Choco-Install -PackageName winflexbison3
- shell: pwsh
+ shell:
+ pwsh
- name: git config
run: |
git config --global core.autocrlf false
git config --global core.eol lf
git config --global advice.detachedHead 0
git config --global init.defaultBranch garbage
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: src/.downloaded-cache
key: downloaded-cache
- name: setup env
# %TEMP% is inconsistent with %TMP% and test-all expects they are consistent.
# https://github.com/actions/virtual-environments/issues/712#issuecomment-613004302
+ # msys2/setup-msys2 installs MSYS2 to D:/a/_temp/msys64/usr/bin
run: |
- set VS=${{ matrix.vs }}
- set VCVARS=${{ matrix.vcvars }}
+ set Path=D:/a/_temp/msys64/usr/bin;%Path%
if not "%VCVARS%" == "" goto :vcset
- set VCVARS="C:\Program Files (x86)\Microsoft Visual Studio\%VS%\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
- if not exist %VCVARS% set VCVARS="C:\Program Files\Microsoft Visual Studio\%VS%\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
+ set VCVARS="C:\Program Files (x86)\Microsoft Visual Studio\${{ matrix.vs }}\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
+ if not exist %VCVARS% set VCVARS="C:\Program Files\Microsoft Visual Studio\${{ matrix.vs }}\Enterprise\VC\Auxiliary\Build\vcvars64.bat"
:vcset
set | C:\msys64\usr\bin\sort > old.env
- call %VCVARS%
+ call %VCVARS% ${{ matrix.vcvers || ''}}
set TMP=%USERPROFILE%\AppData\Local\Temp
set TEMP=%USERPROFILE%\AppData\Local\Temp
set /a TEST_JOBS=(15 * %NUMBER_OF_PROCESSORS% / 10) > nul
@@ -132,7 +120,7 @@ jobs:
- run: nmake extract-extlibs
- run: nmake
env:
- YACC: win_bison
+ YACC: bison.exe
- run: nmake test
timeout-minutes: 5
- run: nmake test-spec
@@ -141,7 +129,7 @@ jobs:
env:
RUBY_TESTOPTS: -j${{env.TEST_JOBS}} --job-status=normal
timeout-minutes: 60
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
diff --git a/.github/workflows/yjit-ubuntu.yml b/.github/workflows/yjit-ubuntu.yml
index 011420c157..0b7b9046e9 100644
--- a/.github/workflows/yjit-ubuntu.yml
+++ b/.github/workflows/yjit-ubuntu.yml
@@ -3,19 +3,24 @@ on:
push:
paths-ignore:
- 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
pull_request:
paths-ignore:
- 'doc/**'
+ - '**/man'
+ - '**.md'
+ - '**.rdoc'
+ - '**/.document'
+ merge_group:
+ paths-ignore:
+ - 'doc/**'
+ - '**/man'
- '**.md'
- '**.rdoc'
- '**/.document'
- - '**.[1-8]'
- - '**.ronn'
concurrency:
group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }}
@@ -28,9 +33,9 @@ jobs:
cargo:
name: Rust cargo test
# GitHub Action's image seems to already contain a Rust 1.58.0.
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
steps:
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
# For now we can't run cargo test --offline because it complains about the
# capstone dependency, even though the dependency is optional
#- run: cargo test --offline
@@ -47,9 +52,10 @@ jobs:
fail-fast: false
matrix:
include:
- - test_task: "yjit-bindgen"
- hint: "To fix: use patch in logs"
- configure: "--with-gcc=clang-12 --enable-yjit=dev"
+ - test_task: 'yjit-bindgen'
+ hint: 'To fix: use patch in logs'
+ configure: '--with-gcc=clang-14 --enable-yjit=dev'
+ libclang_path: '/usr/lib/llvm-14/lib/libclang.so.1'
- test_task: "check"
# YJIT should be automatically built in release mode on x86-64 Linux with rustc present
@@ -79,7 +85,7 @@ jobs:
YJIT_BENCH_OPTS: ${{ matrix.yjit_bench_opts }}
RUBY_DEBUG: ci
BUNDLE_JOBS: 8 # for yjit-bench
- runs-on: ubuntu-20.04
+ runs-on: ubuntu-22.04
if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }}
steps:
- run: mkdir build
@@ -96,10 +102,10 @@ jobs:
run: |
git config --global advice.detachedHead 0
git config --global init.defaultBranch garbage
- - uses: actions/checkout@93ea575cb5d8a053eaa0ac8fa3b40d7e05a33cc8 # v3.1.0
+ - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
with:
path: src
- - uses: actions/cache@9b0c1fce7a93df8e3bb8926b0d6e9d89e92f20a7 # v3.0.11
+ - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
with:
path: src/.downloaded-cache
key: downloaded-cache
@@ -137,6 +143,7 @@ jobs:
RUBY_TESTOPTS: "-q --tty=no"
TEST_BUNDLED_GEMS_ALLOW_FAILURES: ""
PRECHECK_BUNDLED_GEMS: "no"
+ LIBCLANG_PATH: ${{ matrix.libclang_path }}
continue-on-error: ${{ matrix.test_task == 'yjit-bench' }}
- name: Show ${{ github.event.pull_request.base.ref }} GitHub URL for yjit-bench comparison
run: echo "https://github.com/${BASE_REPO}/commit/${BASE_SHA}"
@@ -144,7 +151,7 @@ jobs:
BASE_REPO: ${{ github.event.pull_request.base.repo.full_name }}
BASE_SHA: ${{ github.event.pull_request.base.sha }}
if: ${{ matrix.test_task == 'yjit-bench' && startsWith(github.event_name, 'pull') }}
- - uses: ruby/action-slack@b6882ea6ef8f556f9f9af9ec1220d3f1ced74acf # v3.0.0
+ - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1
with:
payload: |
{
diff --git a/.gitignore b/.gitignore
index 535c4fb789..99d32a1825 100644
--- a/.gitignore
+++ b/.gitignore
@@ -238,7 +238,7 @@ lcov*.info
# MJIT
/include/ruby-*/*/rb_mjit_min_header-*.h
-/lib/mjit/instruction.rb
+/lib/ruby_vm/mjit/instruction.rb
/mjit_config.h
/rb_mjit_header.h
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 665feba914..0000000000
--- a/.travis.yml
+++ /dev/null
@@ -1,235 +0,0 @@
-# -*- YAML -*-
-# Copyright (C) 2011 Urabe, Shyouhei. All rights reserved.
-#
-# This file is a part of the programming language Ruby. Permission is hereby
-# granted, to either redistribute or modify this file, provided that the
-# conditions mentioned in the file COPYING are met. Consult the file for
-# details.
-
-# We only manage non-amd64 free pipelines.
-# https://docs.travis-ci.com/user/billing-overview/
-
-language: c
-
-os: linux
-
-if: commit_message !~ /\[DOC\]/
-
-dist: focal
-
-git:
- quiet: true
-
-cache:
- ccache: true
- directories:
- - $HOME/config_2nd
- - $HOME/.downloaded-cache
-
-env:
- global:
- # The tests skipped in `make test-all`.
- - TEST_ALL_SKIPPED_TESTS=
- # The tests executed separately by `make test-all`.
- - TEST_ALL_SEPARATED_TESTS=
- # Reset timestamps early
- - _=$(touch NEWS && find . -type f -exec touch -r NEWS {} +)
- - CONFIGURE_TTY=no
- - CCACHE_COMPILERCHECK=none
- - CCACHE_NOCOMPRESS=1
- - CCACHE_MAXSIZE=512Mi
- - NPROC="`nproc`"
- # JOBS and SETARCH are overridden when necessary; see below.
- - JOBS=-j$((1+${NPROC}))
- - SETARCH=
- - RUBY_PREFIX=/tmp/ruby-prefix
- - GEMS_FOR_TEST='timezone tzinfo'
- # https://github.com/travis-ci/travis-build/blob/e411371dda21430a60f61b8f3f57943d2fe4d344/lib/travis/build/bash/travis_apt_get_options.bash#L7
- - travis_apt_get_options='--allow-downgrades --allow-remove-essential --allow-change-held-packages'
- - travis_apt_get_options="-yq --no-install-suggests --no-install-recommends $travis_apt_get_options"
- # -O1 is faster than -O3 in our tests.
- - optflags=-O1
- # -g0 disables backtraces when SEGV. Do not set that.
- - debugflags=-ggdb3
-
-.org.ruby-lang.ci.matrix-definitions:
-
- - &gcc-10
- compiler: gcc-10
- before_install:
- - tool/travis_retry.sh sudo bash -c "rm -rf '${TRAVIS_ROOT}/var/lib/apt/lists/'* && exec apt-get update -yq"
- - >-
- tool/travis_retry.sh sudo -E apt-get $travis_apt_get_options install
- ccache
- gcc-10
- g++-10
- libffi-dev
- libncurses-dev
- libncursesw5-dev
- libreadline-dev
- libssl-dev
- libyaml-dev
- openssl
- zlib1g-dev
-
- # --------
-
- - &arm64-linux
- name: arm64-linux
- arch: arm64
- <<: *gcc-10
-
- - &ppc64le-linux
- name: ppc64le-linux
- arch: ppc64le
- <<: *gcc-10
-
- - &s390x-linux
- name: s390x-linux
- arch: s390x
- <<: *gcc-10
-
- - &arm32-linux
- name: arm32-linux
- arch: arm64
- # https://packages.ubuntu.com/focal/crossbuild-essential-armhf
- compiler: arm-linux-gnueabihf-gcc
- env:
- - SETARCH='setarch linux32 --verbose --32bit'
- # The "TestReadline#test_interrupt_in_other_thread" started failing on arm32
- # from https://www.travis-ci.com/github/ruby/ruby/jobs/529005145
- - TEST_ALL_SKIPPED_TESTS=test_interrupt_in_other_thread
- before_install:
- - sudo dpkg --add-architecture armhf
- - tool/travis_retry.sh sudo bash -c "rm -rf '${TRAVIS_ROOT}/var/lib/apt/lists/'* && exec apt-get update -yq"
- - >-
- tool/travis_retry.sh sudo -E apt-get $travis_apt_get_options install
- ccache
- crossbuild-essential-armhf
- libc6:armhf
- libstdc++-10-dev:armhf
- libffi-dev:armhf
- libncurses-dev:armhf
- libncursesw5-dev:armhf
- libreadline-dev:armhf
- libssl-dev:armhf
- libyaml-dev:armhf
- linux-libc-dev:armhf
- zlib1g-dev:armhf
-
-matrix:
- include:
- # Build every commit (Allowed Failures):
- - <<: *arm32-linux
- # Comment out as the 2nd arm64 pipeline is unstable.
- # - <<: *arm64-linux
- - <<: *ppc64le-linux
- - <<: *s390x-linux
- allow_failures:
- # We see multiple errors indicating errors on the Travis environment itself in a short while:
- # https://app.travis-ci.com/github/ruby/ruby/jobs/544382885
- # https://app.travis-ci.com/github/ruby/ruby/jobs/544361370
- # It's not a fault of Ruby's arm32 support but just Travis arm32 seems unsable.
- - name: arm32-linux
- # - name: arm64-linux
- # We see "Some worker was crashed." in about 40% of recent ppc64le-linux jobs
- # e.g. https://app.travis-ci.com/github/ruby/ruby/jobs/530959548
- - name: ppc64le-linux
- # Tentatively disable, because often hungs up **after** all tests
- # have finished successfully and saving caches.
- - name: s390x-linux
- fast_finish: true
-
-before_script:
- - . tool/ci_functions.sh
- - |-
- if [ -n "${TEST_ALL_SKIPPED_TESTS}" ]; then
- TEST_ALL_OPTS="${TEST_ALL_OPTS} $(ci_to_excluded_test_opts "${TEST_ALL_SKIPPED_TESTS}")"
- if [ -z "${TEST_ALL_SEPARATED_TESTS}" ]; then
- TEST_ALL_SEPARATED_TESTS="${TEST_ALL_SKIPPED_TESTS}"
- fi
- fi
- - |-
- if [ -n "${TEST_ALL_SEPARATED_TESTS}" ]; then
- TEST_ALL_OPTS_SEPARATED="$(ci_to_included_test_opts "${TEST_ALL_SEPARATED_TESTS}")"
- fi
- - echo TEST_ALL_OPTS="${TEST_ALL_OPTS}" TEST_ALL_OPTS_SEPARATED="${TEST_ALL_OPTS_SEPARATED}"
- - rm -fr .ext autom4te.cache
- - |-
- [ -d ~/.downloaded-cache ] ||
- mkdir ~/.downloaded-cache
- - ln -s ~/.downloaded-cache
- - "> config.status"
- - "> .rbconfig.time"
- - sed -f tool/prereq.status template/Makefile.in common.mk > Makefile
- - make -s $JOBS up
- - make -s $JOBS srcs
- - rm -f config.status Makefile rbconfig.rb .rbconfig.time
- - |-
- if [ -d ~/config_2nd ]; then
- cp -pr ~/config_2nd build
- else
- mkdir build
- fi
- - mkdir config_1st config_2nd gems/src
- - chmod -R a-w .
- - chmod -R u+w build config_1st config_2nd gems/src
- - cd build
- - |-
- case "$CC" in
- gcc*) CC="ccache $CC${GCC_FLAGS:+ }$GCC_FLAGS -fno-diagnostics-color";;
- clang*) CC="ccache $CC${GCC_FLAGS:+ }$GCC_FLAGS -fno-color-diagnostics";;
- esac
- - |-
- [ ! -f config.cache ] ||
- [ "$CC" = "`sed -n s/^ac_cv_prog_CC=//p config.cache`" ] ||
- (set -x; exec rm config.cache)
- - $SETARCH ../configure -C --disable-install-doc --prefix=$RUBY_PREFIX $CONFIG_FLAG
- - cp -pr config.cache config.status .ext/include ../config_1st
- - $SETARCH make reconfig
- - cp -pr config.cache config.status .ext/include ../config_2nd
- - (cd .. && exec diff -ru config_1st config_2nd)
- - chmod u+w ..
- - rm -rf ~/config_2nd
- - mv ../config_2nd ~
- - chmod u-w ..
- - $SETARCH make -s $JOBS
- - make -s install
- - |-
- [ -z "${GEMS_FOR_TEST}" ] ||
- $RUBY_PREFIX/bin/gem install --no-document $GEMS_FOR_TEST
- - echo "raise 'do not load ~/.irbrc in test'" > ~/.irbrc
-
-script:
- - $SETARCH make -s test -o showflags TESTOPTS="${TESTOPTS=$JOBS -q --tty=no}"
- - ../tool/travis_wait.sh $SETARCH make -s test-all -o exts TESTOPTS="$JOBS -q --tty=no ${TEST_ALL_OPTS}" RUBYOPT="-w"
- # Run the failing tests separately returning ok status to check if it works,
- # visualize them.
- - |
- if [ -n "${TEST_ALL_OPTS_SEPARATED}" ]; then
- $SETARCH make -s test-all -o exts TESTOPTS="$JOBS -v --tty=no ${TEST_ALL_OPTS_SEPARATED}" RUBYOPT="-w" || :
- fi
- - $SETARCH make -s test-spec MSPECOPT=-ff # not using `-j` because sometimes `mspec -j` silently dies
- - $SETARCH make -s -o showflags leaked-globals
-
-# We enable Travis on the specific branches or forked repositories here.
-if: (repo = ruby/ruby AND (branch = master OR branch =~ /^ruby_\d_\d$/)) OR repo != ruby/ruby
-
-# We want to be notified when something happens.
-notifications:
- irc:
- channels:
- - "chat.freenode.net#ruby-core"
- on_success: change # [always|never|change] # default: always
- on_failure: always # [always|never|change] # default: always
- template:
- - "%{message} by @%{author}: See %{build_url}"
-
- webhooks:
- urls:
- - secure: mRsoS/UbqDkKkW5p3AEqM27d4SZnV6Gsylo3bm8T/deltQzTsGzZwrm7OIBXZv0UFZdE68XmPlyHfZFLSP2V9QZ7apXMf9/vw0GtcSe1gchtnjpAPF6lYBn7nMCbVPPx9cS0dwL927fjdRM1vj7IKZ2bk4F0lAJ25R25S6teqdk= # ruby-lang slack: ruby/simpler-alerts-bot (travis)
- on_success: never
- on_failure: always
-
- email:
- - jaruga@ruby-lang.org
diff --git a/LEGAL b/LEGAL
index 9645728efe..0423d57ac9 100644
--- a/LEGAL
+++ b/LEGAL
@@ -979,7 +979,6 @@ mentioned below.
{MIT License}[rdoc-label:label-MIT+License]
[lib/rubygems/resolver/molinillo]
-[lib/bundler/vendor/molinillo]
molinillo is under the following license.
@@ -988,6 +987,15 @@ mentioned below.
{MIT License}[rdoc-label:label-MIT+License]
+[lib/bundler/vendor/pub_grub]
+
+ pub_grub is under the following license.
+
+ >>>
+ Copyright (c) 2018 John Hawthorn
+
+ {MIT License}[rdoc-label:label-MIT+License]
+
[lib/bundler/vendor/connection_pool]
connection_pool is under the following license.
diff --git a/NEWS.md b/NEWS.md
index 95df31809e..f6c3c6fc97 100644
--- a/NEWS.md
+++ b/NEWS.md
@@ -90,14 +90,6 @@ Note that each entry is kept to a minimum, see links for details.
foo(k: 1)
```
-* `eval` and related methods are able to generate code coverage. Enabled using
- `Coverage.setup(:all)` or `Coverage.setup(eval: true)`. [[Feature #19008]]
-
-* `Coverage.supported?(mode)` enables detection of what coverage modes are
- supported. [[Feature #19026]]
-
-## Command line options
-
## Core classes updates
Note: We're only listing outstanding class updates.
@@ -111,8 +103,8 @@ Note: We're only listing outstanding class updates.
fiber. [[Feature #19078]]
Existing Thread and Fiber local variables can be tricky to use.
- Thread local variables are shared between all fibers, making it
- hard to isolate, while Fiber local variables can be hard to
+ Thread-local variables are shared between all fibers, making it
+ hard to isolate, while Fiber-local variables can be hard to
share. It is often desirable to define unit of execution
("execution context") such that some state is shared between all
fibers and threads created in that context. This is what Fiber
@@ -159,11 +151,8 @@ Note: We're only listing outstanding class updates.
STDIN.read # => Blocking operation timed out! (IO::TimeoutError)
```
-* UNIXSocket
-
- * Add support for UNIXSocket on Windows. Emulate anonymous sockets. Add
- support for File.socket? and File::Stat#socket? where possible.
- [[Feature #19135]]
+ * Introduce `IO.new(..., path:)` and promote `File#path` to `IO#path`.
+ [[Feature #19036]]
* Class
@@ -191,6 +180,7 @@ Note: We're only listing outstanding class updates.
Measure = Data.define(:amount, :unit)
distance = Measure.new(100, 'km') #=> #<data Measure amount=100, unit="km">
weight = Measure.new(amount: 50, unit: 'kg') #=> #<data Measure amount=50, unit="kg">
+ weight.with(amount: 40) #=> #<data Measure amount=40, unit="kg">
weight.amount #=> 50
weight.amount = 40 #=> NoMethodError: undefined method `amount='
```
@@ -256,7 +246,7 @@ Note: We're only listing outstanding class updates.
* The cache-based optimization is introduced.
Many (but not all) Regexp matching is now in linear time, which
will prevent regular expression denial of service (ReDoS)
- vulnearbility. [[Feature #19104]]
+ vulnerability. [[Feature #19104]]
* Regexp.linear_time? is introduced. [[Feature #19194]]
@@ -330,17 +320,6 @@ Note: We're only listing outstanding class updates.
* Set is now available as a built-in class without the need for `require "set"`. [[Feature #16989]]
It is currently autoloaded via the Set constant or a call to Enumerable#to_set.
-* Socket
-
- * Added the following constants for supported platforms.
- * `SO_INCOMING_CPU`
- * `SO_INCOMING_NAPI_ID`
- * `SO_RTABLE`
- * `SO_SETFIB`
- * `SO_USER_COOKIE`
- * `TCP_KEEPALIVE`
- * `TCP_CONNECTION_INFO`
-
* String
* String#byteindex and String#byterindex have been added. [[Feature #13110]]
@@ -363,22 +342,26 @@ Note: We're only listing outstanding class updates.
* Thread
- * Thread#each_caller_location is added. [[Feature #16663]]
+ * Thread.each_caller_location is added. [[Feature #16663]]
* Thread::Queue
- * Thread::Queue.pop(timeout: sec) is added. [[Feature #18774]]
+ * Thread::Queue#pop(timeout: sec) is added. [[Feature #18774]]
* Thread::SizedQueue
- * Thread::SizedQueue.pop(timeout: sec) is added. [[Feature #18774]]
- * Thread::SizedQueue.push(timeout: sec) is added. [[Feature #18944]]
+ * Thread::SizedQueue#pop(timeout: sec) is added. [[Feature #18774]]
+ * Thread::SizedQueue#push(timeout: sec) is added. [[Feature #18944]]
* Time
* Time#deconstruct_keys is added, allowing to use Time instances
in pattern-matching expressions [[Feature #19071]]
+ * Time.new now can parse a string like generated by Time#inspect
+ and return a Time instance based on the given argument.
+ [[Feature #18033]]
+
* SyntaxError
* SyntaxError#path has been added. [[Feature #19138]]
@@ -387,8 +370,8 @@ Note: We're only listing outstanding class updates.
* TracePoint#binding now returns `nil` for `c_call`/`c_return` TracePoints.
[[Bug #18487]]
* TracePoint#enable `target_thread` keyword argument now defaults to the
- current thread if `target` and `target_line` keyword arguments are not
- passed. [[Bug #16889]]
+ current thread if a block is given and `target` and `target_line` keyword
+ arguments are not passed. [[Bug #16889]]
* UnboundMethod
@@ -401,13 +384,44 @@ Note: We're only listing outstanding class updates.
`"#<UnboundMethod: Kernel#object_id()>"`
(was `"#<UnboundMethod: String(Kernel)#object_id()>"`).
+* GC
+
+ * Expose `need_major_gc` via `GC.latest_gc_info`. [GH-6791]
+
+* ObjectSpace
+
+ * `ObjectSpace.dump_all` dump shapes as well. [GH-6868]
+
## Stdlib updates
+* Bundler
+
+ * Bundler now uses [PubGrub] resolver instead of [Molinillo] for performance improvement.
+ * Add --ext=rust support to bundle gem for creating simple gems with Rust extensions.
+ [[GH-rubygems-6149]]
+ * Make cloning git repos faster [[GH-rubygems-4475]]
+
+* RubyGems
+
+ * Add mswin support for cargo builder. [[GH-rubygems-6167]]
+
* CGI
* `CGI.escapeURIComponent` and `CGI.unescapeURIComponent` are added.
[[Feature #18822]]
+* Coverage
+
+ * `Coverage.setup` now accepts `eval: true`. By this, `eval` and related methods are
+ able to generate code coverage. [[Feature #19008]]
+
+ * `Coverage.supported?(mode)` enables detection of what coverage modes are
+ supported. [[Feature #19026]]
+
+* Date
+
+ * Added `Date#deconstruct_keys` and `DateTime#deconstruct_keys` same as [[Feature #19071]]
+
* ERB
* `ERB::Util.html_escape` is made faster than `CGI.escapeHTML`.
@@ -423,23 +437,60 @@ Note: We're only listing outstanding class updates.
* Add FileUtils.ln_sr method and `relative:` option to FileUtils.ln_s.
[[Feature #18925]]
+* IRB
+
+ * debug.gem integration commands have been added: `debug`, `break`, `catch`,
+ `next`, `delete`, `step`, `continue`, `finish`, `backtrace`, `info`
+ * They work even if you don't have `gem "debug"` in your Gemfile.
+ * See also: [What's new in Ruby 3.2's IRB?](https://st0012.dev/whats-new-in-ruby-3-2-irb)
+ * More Pry-like commands and features have been added.
+ * `edit` and `show_cmds` (like Pry's `help`) are added.
+ * `ls` takes `-g` or `-G` option to filter out outputs.
+ * `show_source` is aliased from `$` and accepts unquoted inputs.
+ * `whereami` is aliased from `@`.
+
+* Net::Protocol
+
+ * Improve `Net::BufferedIO` performance. [[GH-net-protocol-14]]
+
+* Pathname
+
+ * Added `Pathname#lutime`. [[GH-pathname-20]]
+
+* Socket
+
+ * Added the following constants for supported platforms.
+ * `SO_INCOMING_CPU`
+ * `SO_INCOMING_NAPI_ID`
+ * `SO_RTABLE`
+ * `SO_SETFIB`
+ * `SO_USER_COOKIE`
+ * `TCP_KEEPALIVE`
+ * `TCP_CONNECTION_INFO`
+
* SyntaxSuggest
* The feature of `syntax_suggest` formerly `dead_end` is integrated in Ruby.
[[Feature #18159]]
+* UNIXSocket
+
+ * Add support for UNIXSocket on Windows. Emulate anonymous sockets. Add
+ support for File.socket? and File::Stat#socket? where possible.
+ [[Feature #19135]]
+
* The following default gems are updated.
- * RubyGems 3.4.0.dev
+ * RubyGems 3.4.1
* abbrev 0.1.1
* benchmark 0.2.1
* bigdecimal 3.1.3
- * bundler 2.4.0.dev
+ * bundler 2.4.1
* cgi 0.3.6
* csv 3.2.6
- * date 3.3.2
+ * date 3.3.3
* delegate 0.3.0
- * did_you_mean 1.6.2
+ * did_you_mean 1.6.3
* digest 3.1.1
* drb 2.1.1
* english 0.7.2
@@ -455,23 +506,23 @@ Note: We're only listing outstanding class updates.
* io-nonblock 0.2.0
* io-wait 0.3.0
* ipaddr 1.2.5
- * irb 1.6.1
+ * irb 1.6.2
* json 2.6.3
* logger 1.5.3
* mutex_m 0.1.2
- * net-http 0.3.1
+ * net-http 0.4.0
* net-protocol 0.2.1
* nkf 0.1.2
* open-uri 0.3.0
* open3 0.1.2
- * openssl 3.1.0.pre
- * optparse 0.3.0
+ * openssl 3.1.0
+ * optparse 0.3.1
* ostruct 0.5.5
* pathname 0.2.1
* pp 0.4.0
* pstore 0.1.2
* psych 5.0.1
- * racc 1.6.1
+ * racc 1.6.2
* rdoc 6.5.0
* readline-ext 0.1.5
* reline 0.3.2
@@ -481,7 +532,7 @@ Note: We're only listing outstanding class updates.
* set 1.0.3
* stringio 3.0.4
* strscan 3.0.5
- * syntax_suggest 1.0.1
+ * syntax_suggest 1.0.2
* syslog 0.1.1
* tempfile 0.1.3
* time 0.2.1
@@ -498,21 +549,21 @@ Note: We're only listing outstanding class updates.
* The following bundled gems are updated.
* minitest 5.16.3
- * power_assert 2.0.2
+ * power_assert 2.0.3
* test-unit 3.5.7
* net-ftp 0.2.0
- * net-imap 0.3.2
+ * net-imap 0.3.4
* net-pop 0.1.2
* net-smtp 0.3.3
- * rbs 2.8.1
+ * rbs 2.8.2
* typeprof 0.21.3
- * debug 1.7.0
+ * debug 1.7.1
-* The following default gems are now bundled gems.
+See GitHub releases like [GitHub Releases of Logger](https://github.com/ruby/logger/releases) or changelog for details of the default gems or bundled gems.
## Supported platforms
-* WebAssembly/WASI is added. [[Feature #18462]]
+* WebAssembly/WASI is added. See [wasm/README.md] and [ruby.wasm] for more details. [[Feature #18462]]
## Compatibility issues
@@ -558,9 +609,9 @@ The following deprecated methods are removed.
### Constant lookup when defining a class/module
* When defining a class/module directly under the Object class by class/module
- statement, if there is already a class/module with the same name, the statement
- was handled as "open class" in Ruby 3.1 or before. Since Ruby 3.2, a new class
- is defined instead. [[Feature #18832]]
+ statement, if there is already a class/module defined by `Module#include`
+ with the same name, the statement was handled as "open class" in Ruby 3.1 or before.
+ Since Ruby 3.2, a new class is defined instead. [[Feature #18832]]
## Stdlib compatibility issues
@@ -584,6 +635,10 @@ The following deprecated methods are removed.
[[Feature #18571]]
+* Check cookie name/path/domain characters in `CGI::Cookie`. [[CVE-2021-33621]]
+
+* `URI.parse` return empty string in host instead of nil. [[sec-156615]]
+
## C API updates
### Updated C APIs
@@ -592,9 +647,9 @@ The following APIs are updated.
* PRNG update
- `rb_random_interface_t` updated and versioned.
- Extension libraries which use this interface and built for older versions.
- Also `init_int32` function needs to be defined.
+ `rb_random_interface_t` in ruby/random.h updated and versioned.
+ Extension libraries which use this interface and built for older
+ versions need to rebuild with adding `init_int32` function.
### Added C APIs
@@ -606,6 +661,7 @@ The following APIs are updated.
* `RUBY_INTERNAL_THREAD_EVENT_RESUMED`
* `RUBY_INTERNAL_THREAD_EVENT_SUSPENDED`
* `RUBY_INTERNAL_THREAD_EVENT_EXITED`
+* `rb_debug_inspector_current_depth` and `rb_debug_inspector_frame_depth` are added for debuggers.
### Removed C APIs
@@ -626,8 +682,8 @@ The following deprecated APIs are removed.
[[Feature #18589]]
* The cache-based optimization for Regexp matching is introduced.
[[Feature #19104]]
-* Variable Width Allocation is now enabled by default.
- [[Feature #18239]].
+* [Variable Width Allocation](https://shopify.engineering/ruby-variable-width-allocation)
+ is now enabled by default. [[Feature #18239]]
* Added a new instance variable caching mechanism, called object shapes, which
improves inline cache hits for most objects and allows us to generate very
efficient JIT code. Objects whose instance variables are defined in a
@@ -667,7 +723,7 @@ The following deprecated APIs are removed.
### MJIT
-* The MJIT compiler is re-implemented in Ruby as a standard library `mjit`.
+* The MJIT compiler is re-implemented in Ruby as `ruby_vm/mjit/compiler`.
* MJIT compiler is executed under a forked Ruby process instead of
doing it in a native thread called MJIT worker. [[Feature #18968]]
* As a result, Microsoft Visual Studio (MSWIN) is no longer supported.
@@ -675,75 +731,90 @@ The following deprecated APIs are removed.
* Rename `--mjit-min-calls` to `--mjit-call-threshold`.
* Change default `--mjit-max-cache` back from 10000 to 100.
-[Feature #12005]: https://bugs.ruby-lang.org/issues/12005
-[Feature #12084]: https://bugs.ruby-lang.org/issues/12084
-[Feature #12655]: https://bugs.ruby-lang.org/issues/12655
-[Feature #12737]: https://bugs.ruby-lang.org/issues/12737
-[Feature #13110]: https://bugs.ruby-lang.org/issues/13110
-[Feature #14332]: https://bugs.ruby-lang.org/issues/14332
-[Feature #15231]: https://bugs.ruby-lang.org/issues/15231
-[Feature #15357]: https://bugs.ruby-lang.org/issues/15357
-[Bug #15928]: https://bugs.ruby-lang.org/issues/15928
-[Feature #16122]: https://bugs.ruby-lang.org/issues/16122
-[Feature #16131]: https://bugs.ruby-lang.org/issues/16131
-[Bug #16466]: https://bugs.ruby-lang.org/issues/16466
-[Feature #16663]: https://bugs.ruby-lang.org/issues/16663
-[Feature #16806]: https://bugs.ruby-lang.org/issues/16806
-[Bug #16889]: https://bugs.ruby-lang.org/issues/16889
-[Bug #16908]: https://bugs.ruby-lang.org/issues/16908
-[Feature #16989]: https://bugs.ruby-lang.org/issues/16989
-[Feature #17351]: https://bugs.ruby-lang.org/issues/17351
-[Feature #17391]: https://bugs.ruby-lang.org/issues/17391
-[Bug #17545]: https://bugs.ruby-lang.org/issues/17545
-[Bug #17767]: https://bugs.ruby-lang.org/issues/17767
-[Feature #17837]: https://bugs.ruby-lang.org/issues/17837
-[Feature #17881]: https://bugs.ruby-lang.org/issues/17881
-[Feature #18159]: https://bugs.ruby-lang.org/issues/18159
-[Feature #18239]: https://bugs.ruby-lang.org/issues/18239#note-17
-[Feature #18351]: https://bugs.ruby-lang.org/issues/18351
-[Feature #18367]: https://bugs.ruby-lang.org/issues/18367
-[Bug #18435]: https://bugs.ruby-lang.org/issues/18435
-[Feature #18462]: https://bugs.ruby-lang.org/issues/18462
-[Feature #18481]: https://bugs.ruby-lang.org/issues/18481
-[Bug #18487]: https://bugs.ruby-lang.org/issues/18487
-[Feature #18564]: https://bugs.ruby-lang.org/issues/18564
-[Feature #18571]: https://bugs.ruby-lang.org/issues/18571
-[Feature #18585]: https://bugs.ruby-lang.org/issues/18585
-[Feature #18589]: https://bugs.ruby-lang.org/issues/18589
-[Feature #18595]: https://bugs.ruby-lang.org/issues/18595
-[Feature #18598]: https://bugs.ruby-lang.org/issues/18598
-[Bug #18625]: https://bugs.ruby-lang.org/issues/18625
-[Feature #18630]: https://bugs.ruby-lang.org/issues/18630
-[Bug #18633]: https://bugs.ruby-lang.org/issues/18633
-[Feature #18639]: https://bugs.ruby-lang.org/issues/18639
-[Feature #18685]: https://bugs.ruby-lang.org/issues/18685
-[Bug #18729]: https://bugs.ruby-lang.org/issues/18729
-[Bug #18751]: https://bugs.ruby-lang.org/issues/18751
-[Feature #18774]: https://bugs.ruby-lang.org/issues/18774
-[Feature #18776]: https://bugs.ruby-lang.org/issues/18776
-[Bug #18782]: https://bugs.ruby-lang.org/issues/18782
-[Feature #18788]: https://bugs.ruby-lang.org/issues/18788
-[Feature #18798]: https://bugs.ruby-lang.org/issues/18798
-[Feature #18809]: https://bugs.ruby-lang.org/issues/18809
-[Feature #18821]: https://bugs.ruby-lang.org/issues/18821
-[Feature #18822]: https://bugs.ruby-lang.org/issues/18822
-[Feature #18824]: https://bugs.ruby-lang.org/issues/18824
-[Feature #18832]: https://bugs.ruby-lang.org/issues/18832
-[Feature #18875]: https://bugs.ruby-lang.org/issues/18875
-[Feature #18925]: https://bugs.ruby-lang.org/issues/18925
-[Feature #18944]: https://bugs.ruby-lang.org/issues/18944
-[Feature #18949]: https://bugs.ruby-lang.org/issues/18949
-[Feature #18968]: https://bugs.ruby-lang.org/issues/18968
-[Feature #19008]: https://bugs.ruby-lang.org/issues/19008
-[Feature #19013]: https://bugs.ruby-lang.org/issues/19013
-[Feature #19026]: https://bugs.ruby-lang.org/issues/19026
-[Feature #19060]: https://bugs.ruby-lang.org/issues/19060
-[Feature #19070]: https://bugs.ruby-lang.org/issues/19070
-[Feature #19071]: https://bugs.ruby-lang.org/issues/19071
-[Feature #19078]: https://bugs.ruby-lang.org/issues/19078
-[Bug #19087]: https://bugs.ruby-lang.org/issues/19087
-[Bug #19100]: https://bugs.ruby-lang.org/issues/19100
-[Feature #19104]: https://bugs.ruby-lang.org/issues/19104
-[Feature #19135]: https://bugs.ruby-lang.org/issues/19135
-[Feature #19138]: https://bugs.ruby-lang.org/issues/19138
-[Feature #19194]: https://bugs.ruby-lang.org/issues/19194
+[Feature #12005]: https://bugs.ruby-lang.org/issues/12005
+[Feature #12084]: https://bugs.ruby-lang.org/issues/12084
+[Feature #12655]: https://bugs.ruby-lang.org/issues/12655
+[Feature #12737]: https://bugs.ruby-lang.org/issues/12737
+[Feature #13110]: https://bugs.ruby-lang.org/issues/13110
+[Feature #14332]: https://bugs.ruby-lang.org/issues/14332
+[Feature #15231]: https://bugs.ruby-lang.org/issues/15231
+[Feature #15357]: https://bugs.ruby-lang.org/issues/15357
+[Bug #15928]: https://bugs.ruby-lang.org/issues/15928
+[Feature #16122]: https://bugs.ruby-lang.org/issues/16122
+[Feature #16131]: https://bugs.ruby-lang.org/issues/16131
+[Bug #16466]: https://bugs.ruby-lang.org/issues/16466
+[Feature #16663]: https://bugs.ruby-lang.org/issues/16663
+[Feature #16806]: https://bugs.ruby-lang.org/issues/16806
+[Bug #16889]: https://bugs.ruby-lang.org/issues/16889
+[Bug #16908]: https://bugs.ruby-lang.org/issues/16908
+[Feature #16989]: https://bugs.ruby-lang.org/issues/16989
+[Feature #17351]: https://bugs.ruby-lang.org/issues/17351
+[Feature #17391]: https://bugs.ruby-lang.org/issues/17391
+[Bug #17545]: https://bugs.ruby-lang.org/issues/17545
+[Bug #17767]: https://bugs.ruby-lang.org/issues/17767
+[Feature #17837]: https://bugs.ruby-lang.org/issues/17837
+[Feature #17881]: https://bugs.ruby-lang.org/issues/17881
+[Feature #18033]: https://bugs.ruby-lang.org/issues/18033
+[Feature #18159]: https://bugs.ruby-lang.org/issues/18159
+[Feature #18239]: https://bugs.ruby-lang.org/issues/18239#note-17
+[Feature #18351]: https://bugs.ruby-lang.org/issues/18351
+[Feature #18367]: https://bugs.ruby-lang.org/issues/18367
+[Bug #18435]: https://bugs.ruby-lang.org/issues/18435
+[Feature #18462]: https://bugs.ruby-lang.org/issues/18462
+[Feature #18481]: https://bugs.ruby-lang.org/issues/18481
+[Bug #18487]: https://bugs.ruby-lang.org/issues/18487
+[Feature #18564]: https://bugs.ruby-lang.org/issues/18564
+[Feature #18571]: https://bugs.ruby-lang.org/issues/18571
+[Feature #18585]: https://bugs.ruby-lang.org/issues/18585
+[Feature #18589]: https://bugs.ruby-lang.org/issues/18589
+[Feature #18595]: https://bugs.ruby-lang.org/issues/18595
+[Feature #18598]: https://bugs.ruby-lang.org/issues/18598
+[Bug #18625]: https://bugs.ruby-lang.org/issues/18625
+[Feature #18630]: https://bugs.ruby-lang.org/issues/18630
+[Bug #18633]: https://bugs.ruby-lang.org/issues/18633
+[Feature #18639]: https://bugs.ruby-lang.org/issues/18639
+[Feature #18685]: https://bugs.ruby-lang.org/issues/18685
+[Bug #18729]: https://bugs.ruby-lang.org/issues/18729
+[Bug #18751]: https://bugs.ruby-lang.org/issues/18751
+[Feature #18774]: https://bugs.ruby-lang.org/issues/18774
+[Feature #18776]: https://bugs.ruby-lang.org/issues/18776
+[Bug #18782]: https://bugs.ruby-lang.org/issues/18782
+[Feature #18788]: https://bugs.ruby-lang.org/issues/18788
+[Feature #18798]: https://bugs.ruby-lang.org/issues/18798
+[Feature #18809]: https://bugs.ruby-lang.org/issues/18809
+[Feature #18821]: https://bugs.ruby-lang.org/issues/18821
+[Feature #18822]: https://bugs.ruby-lang.org/issues/18822
+[Feature #18824]: https://bugs.ruby-lang.org/issues/18824
+[Feature #18832]: https://bugs.ruby-lang.org/issues/18832
+[Feature #18875]: https://bugs.ruby-lang.org/issues/18875
+[Feature #18925]: https://bugs.ruby-lang.org/issues/18925
+[Feature #18944]: https://bugs.ruby-lang.org/issues/18944
+[Feature #18949]: https://bugs.ruby-lang.org/issues/18949
+[Feature #18968]: https://bugs.ruby-lang.org/issues/18968
+[Feature #19008]: https://bugs.ruby-lang.org/issues/19008
+[Feature #19013]: https://bugs.ruby-lang.org/issues/19013
+[Feature #19026]: https://bugs.ruby-lang.org/issues/19026
+[Feature #19036]: https://bugs.ruby-lang.org/issues/19036
+[Feature #19060]: https://bugs.ruby-lang.org/issues/19060
+[Feature #19070]: https://bugs.ruby-lang.org/issues/19070
+[Feature #19071]: https://bugs.ruby-lang.org/issues/19071
+[Feature #19078]: https://bugs.ruby-lang.org/issues/19078
+[Bug #19087]: https://bugs.ruby-lang.org/issues/19087
+[Bug #19100]: https://bugs.ruby-lang.org/issues/19100
+[Feature #19104]: https://bugs.ruby-lang.org/issues/19104
+[Feature #19135]: https://bugs.ruby-lang.org/issues/19135
+[Feature #19138]: https://bugs.ruby-lang.org/issues/19138
+[Feature #19194]: https://bugs.ruby-lang.org/issues/19194
+[Molinillo]: https://github.com/CocoaPods/Molinillo
+[PubGrub]: https://github.com/jhawthorn/pub_grub
+[GH-net-protocol-14]: https://github.com/ruby/net-protocol/pull/14
+[GH-pathname-20]: https://github.com/ruby/pathname/pull/20
+[GH-6791]: https://github.com/ruby/ruby/pull/6791
+[GH-6868]: https://github.com/ruby/ruby/pull/6868
+[GH-rubygems-4475]: https://github.com/rubygems/rubygems/pull/4475
+[GH-rubygems-6149]: https://github.com/rubygems/rubygems/pull/6149
+[GH-rubygems-6167]: https://github.com/rubygems/rubygems/pull/6167
+[sec-156615]: https://hackerone.com/reports/156615
+[CVE-2021-33621]: https://www.ruby-lang.org/en/news/2022/11/22/http-response-splitting-in-cgi-cve-2021-33621/
+[wasm/README.md]: https://github.com/ruby/ruby/blob/master/wasm/README.md
+[ruby.wasm]: https://github.com/ruby/ruby.wasm
diff --git a/README.ja.md b/README.ja.md
index bb69c09055..93c0131690 100644
--- a/README.ja.md
+++ b/README.ja.md
@@ -4,7 +4,6 @@
[![Actions Status: Windows](https://github.com/ruby/ruby/workflows/Windows/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Windows")
[![AppVeyor status](https://ci.appveyor.com/api/projects/status/0sy8rrxut4o0k960/branch/master?svg=true)](https://ci.appveyor.com/project/ruby/ruby/branch/master)
[![Travis Status](https://app.travis-ci.com/ruby/ruby.svg?branch=master)](https://app.travis-ci.com/ruby/ruby)
-[![Cirrus Status](https://api.cirrus-ci.com/github/ruby/ruby.svg)](https://cirrus-ci.com/github/ruby/ruby/master)
# Rubyとは
diff --git a/README.md b/README.md
index 35ef2d9e89..c445448c71 100644
--- a/README.md
+++ b/README.md
@@ -4,7 +4,6 @@
[![Actions Status: Windows](https://github.com/ruby/ruby/workflows/Windows/badge.svg)](https://github.com/ruby/ruby/actions?query=workflow%3A"Windows")
[![AppVeyor status](https://ci.appveyor.com/api/projects/status/0sy8rrxut4o0k960/branch/master?svg=true)](https://ci.appveyor.com/project/ruby/ruby/branch/master)
[![Travis Status](https://app.travis-ci.com/ruby/ruby.svg?branch=master)](https://app.travis-ci.com/ruby/ruby)
-[![Cirrus Status](https://api.cirrus-ci.com/github/ruby/ruby.svg)](https://cirrus-ci.com/github/ruby/ruby/master)
# What is Ruby?
diff --git a/addr2line.c b/addr2line.c
index 0d45ec9414..e5f25293e2 100644
--- a/addr2line.c
+++ b/addr2line.c
@@ -159,12 +159,15 @@ typedef struct obj_info {
struct dwarf_section debug_info;
struct dwarf_section debug_line;
struct dwarf_section debug_ranges;
+ struct dwarf_section debug_str_offsets;
+ struct dwarf_section debug_addr;
struct dwarf_section debug_rnglists;
struct dwarf_section debug_str;
+ struct dwarf_section debug_line_str;
struct obj_info *next;
} obj_info_t;
-#define DWARF_SECTION_COUNT 6
+#define DWARF_SECTION_COUNT 9
static struct dwarf_section *
obj_dwarf_section_at(obj_info_t *obj, int n)
@@ -174,8 +177,11 @@ obj_dwarf_section_at(obj_info_t *obj, int n)
&obj->debug_info,
&obj->debug_line,
&obj->debug_ranges,
+ &obj->debug_str_offsets,
+ &obj->debug_addr,
&obj->debug_rnglists,
- &obj->debug_str
+ &obj->debug_str,
+ &obj->debug_line_str
};
if (n < 0 || DWARF_SECTION_COUNT <= n) {
abort();
@@ -248,39 +254,51 @@ get_nth_dirname(unsigned long dir, const char *p)
return p;
}
+static const char *parse_ver5_debug_line_header(const char *p, int idx, uint8_t format, obj_info_t *obj, const char **out_path, uint64_t *out_directory_index);
+
static void
-fill_filename(int file, const char *include_directories, const char *filenames, line_info_t *line, obj_info_t *obj)
+fill_filename(int file, uint8_t format, uint16_t version, const char *include_directories, const char *filenames, line_info_t *line, obj_info_t *obj)
{
int i;
const char *p = filenames;
const char *filename;
unsigned long dir;
- for (i = 1; i <= file; i++) {
- filename = p;
- if (!*p) {
- /* Need to output binary file name? */
- kprintf("Unexpected file number %d in %s at %tx\n",
- file, binary_filename, filenames - obj->mapped);
- return;
- }
- while (*p) p++;
- p++;
- dir = uleb128(&p);
- /* last modified. */
- uleb128(&p);
- /* size of the file. */
- uleb128(&p);
-
- if (i == file) {
- line->filename = filename;
- line->dirname = get_nth_dirname(dir, include_directories);
- }
+ if (version >= 5) {
+ const char *path;
+ uint64_t directory_index = -1;
+ parse_ver5_debug_line_header(filenames, file, format, obj, &path, &directory_index);
+ line->filename = path;
+ parse_ver5_debug_line_header(include_directories, (int)directory_index, format, obj, &path, NULL);
+ line->dirname = path;
+ }
+ else {
+ for (i = 1; i <= file; i++) {
+ filename = p;
+ if (!*p) {
+ /* Need to output binary file name? */
+ kprintf("Unexpected file number %d in %s at %tx\n",
+ file, binary_filename, filenames - obj->mapped);
+ return;
+ }
+ while (*p) p++;
+ p++;
+ dir = uleb128(&p);
+ /* last modified. */
+ uleb128(&p);
+ /* size of the file. */
+ uleb128(&p);
+
+ if (i == file) {
+ line->filename = filename;
+ line->dirname = get_nth_dirname(dir, include_directories);
+ }
+ }
}
}
static void
fill_line(int num_traces, void **traces, uintptr_t addr, int file, int line,
- const char *include_directories, const char *filenames,
+ uint8_t format, uint16_t version, const char *include_directories, const char *filenames,
obj_info_t *obj, line_info_t *lines, int offset)
{
int i;
@@ -290,7 +308,7 @@ fill_line(int num_traces, void **traces, uintptr_t addr, int file, int line,
/* We assume one line code doesn't result >100 bytes of native code.
We may want more reliable way eventually... */
if (addr < a && a < addr + 100) {
- fill_filename(file, include_directories, filenames, &lines[i], obj);
+ fill_filename(file, format, version, include_directories, filenames, &lines[i], obj);
lines[i].line = line;
}
}
@@ -315,7 +333,7 @@ struct LineNumberProgramHeader {
};
static int
-parse_debug_line_header(const char **pp, struct LineNumberProgramHeader *header)
+parse_debug_line_header(obj_info_t *obj, const char **pp, struct LineNumberProgramHeader *header)
{
const char *p = *pp;
header->unit_length = *(uint32_t *)p;
@@ -332,7 +350,13 @@ parse_debug_line_header(const char **pp, struct LineNumberProgramHeader *header)
header->version = *(uint16_t *)p;
p += sizeof(uint16_t);
- if (header->version > 4) return -1;
+ if (header->version > 5) return -1;
+
+ if (header->version >= 5) {
+ /* address_size = *(uint8_t *)p++; */
+ /* segment_selector_size = *(uint8_t *)p++; */
+ p += 2;
+ }
header->header_length = header->format == 4 ? *(uint32_t *)p : *(uint64_t *)p;
p += header->format;
@@ -353,20 +377,27 @@ parse_debug_line_header(const char **pp, struct LineNumberProgramHeader *header)
/* header->standard_opcode_lengths = (uint8_t *)p - 1; */
p += header->opcode_base - 1;
- header->include_directories = p;
+ if (header->version >= 5) {
+ header->include_directories = p;
+ p = parse_ver5_debug_line_header(p, -1, header->format, obj, NULL, NULL);
+ header->filenames = p;
+ }
+ else {
+ header->include_directories = p;
- /* temporary measure for compress-debug-sections */
- if (p >= header->cu_end) return -1;
+ /* temporary measure for compress-debug-sections */
+ if (p >= header->cu_end) return -1;
- /* skip include directories */
- while (*p) {
- p = memchr(p, '\0', header->cu_end - p);
- if (!p) return -1;
- p++;
- }
- p++;
+ /* skip include directories */
+ while (*p) {
+ p = memchr(p, '\0', header->cu_end - p);
+ if (!p) return -1;
+ p++;
+ }
+ p++;
- header->filenames = p;
+ header->filenames = p;
+ }
*pp = header->cu_start;
@@ -392,13 +423,15 @@ parse_debug_line_cu(int num_traces, void **traces, const char **debug_line,
/* int epilogue_begin = 0; */
/* unsigned int isa = 0; */
- if (parse_debug_line_header(&p, &header))
+ if (parse_debug_line_header(obj, &p, &header))
return -1;
is_stmt = header.default_is_stmt;
#define FILL_LINE() \
do { \
fill_line(num_traces, traces, addr, file, line, \
+ header.format, \
+ header.version, \
header.include_directories, \
header.filenames, \
obj, lines, offset); \
@@ -827,16 +860,23 @@ enum {
VAL_cstr = 1,
VAL_data = 2,
VAL_uint = 3,
- VAL_int = 4
+ VAL_int = 4,
+ VAL_addr = 5
};
# define ABBREV_TABLE_SIZE 256
typedef struct {
obj_info_t *obj;
const char *file;
+ uint8_t current_version;
const char *current_cu;
uint64_t current_low_pc;
+ uint64_t current_str_offsets_base;
+ uint64_t current_addr_base;
+ uint64_t current_rnglists_base;
const char *debug_line_cu_end;
+ uint8_t debug_line_format;
+ uint16_t debug_line_version;
const char *debug_line_files;
const char *debug_line_directories;
const char *p;
@@ -861,6 +901,7 @@ typedef struct {
const char *ptr;
uint64_t uint64;
int64_t int64;
+ uint64_t addr_idx;
} as;
uint64_t off;
uint64_t at;
@@ -976,6 +1017,9 @@ debug_info_reader_init(DebugInfoReader *reader, obj_info_t *obj)
reader->pend = obj->debug_info.ptr + obj->debug_info.size;
reader->debug_line_cu_end = obj->debug_line.ptr;
reader->current_low_pc = 0;
+ reader->current_str_offsets_base = 0;
+ reader->current_addr_base = 0;
+ reader->current_rnglists_base = 0;
}
static void
@@ -1020,10 +1064,12 @@ di_read_debug_line_cu(DebugInfoReader *reader)
struct LineNumberProgramHeader header;
p = (const char *)reader->debug_line_cu_end;
- if (parse_debug_line_header(&p, &header))
+ if (parse_debug_line_header(reader->obj, &p, &header))
return -1;
reader->debug_line_cu_end = (char *)header.cu_end;
+ reader->debug_line_format = header.format;
+ reader->debug_line_version = header.version;
reader->debug_line_directories = (char *)header.include_directories;
reader->debug_line_files = (char *)header.filenames;
@@ -1031,6 +1077,13 @@ di_read_debug_line_cu(DebugInfoReader *reader)
}
static void
+set_addr_idx_value(DebugInfoValue *v, uint64_t n)
+{
+ v->as.addr_idx = n;
+ v->type = VAL_addr;
+}
+
+static void
set_uint_value(DebugInfoValue *v, uint64_t n)
{
v->as.uint64 = n;
@@ -1077,19 +1130,39 @@ get_cstr_value(DebugInfoValue *v)
}
}
+static const char *
+resolve_strx(DebugInfoReader *reader, uint64_t idx)
+{
+ const char *p = reader->obj->debug_str_offsets.ptr + reader->current_str_offsets_base;
+ uint64_t off;
+ if (reader->format == 4) {
+ off = ((uint32_t *)p)[idx];
+ }
+ else {
+ off = ((uint64_t *)p)[idx];
+ }
+ return reader->obj->debug_str.ptr + off;
+}
+
+static void
+debug_info_reader_read_addr_value(DebugInfoReader *reader, DebugInfoValue *v)
+{
+ if (reader->address_size == 4) {
+ set_uint_value(v, read_uint32(&reader->p));
+ } else if (reader->address_size == 8) {
+ set_uint_value(v, read_uint64(&reader->p));
+ } else {
+ fprintf(stderr,"unknown address_size:%d", reader->address_size);
+ abort();
+ }
+}
+
static void
debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoValue *v)
{
switch (form) {
case DW_FORM_addr:
- if (reader->address_size == 4) {
- set_uint_value(v, read_uint32(&reader->p));
- } else if (reader->address_size == 8) {
- set_uint_value(v, read_uint64(&reader->p));
- } else {
- fprintf(stderr,"unknown address_size:%d", reader->address_size);
- abort();
- }
+ debug_info_reader_read_addr_value(reader, v);
break;
case DW_FORM_block2:
v->size = read_uint16(&reader->p);
@@ -1141,13 +1214,19 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa
set_uint_value(v, read_uleb128(reader));
break;
case DW_FORM_ref_addr:
- if (reader->format == 4) {
- set_uint_value(v, read_uint32(&reader->p));
- } else if (reader->format == 8) {
- set_uint_value(v, read_uint64(&reader->p));
+ if (reader->current_version <= 2) {
+ // DWARF Version 2 specifies that references have
+ // the same size as an address on the target system
+ debug_info_reader_read_addr_value(reader, v);
} else {
- fprintf(stderr,"unknown format:%d", reader->format);
- abort();
+ if (reader->format == 4) {
+ set_uint_value(v, read_uint32(&reader->p));
+ } else if (reader->format == 8) {
+ set_uint_value(v, read_uint64(&reader->p));
+ } else {
+ fprintf(stderr,"unknown format:%d", reader->format);
+ abort();
+ }
}
break;
case DW_FORM_ref1:
@@ -1189,11 +1268,10 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa
set_uint_value(v, 1);
break;
case DW_FORM_strx:
- set_uint_value(v, uleb128(&reader->p));
+ set_cstr_value(v, resolve_strx(reader, uleb128(&reader->p)));
break;
case DW_FORM_addrx:
- /* TODO: read .debug_addr */
- set_uint_value(v, uleb128(&reader->p));
+ set_addr_idx_value(v, uleb128(&reader->p));
break;
case DW_FORM_ref_sup4:
set_uint_value(v, read_uint32(&reader->p));
@@ -1208,8 +1286,7 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa
reader->p += v->size;
break;
case DW_FORM_line_strp:
- set_uint_value(v, read_uint(reader));
- /* *p = reader->file + reader->line->sh_offset + ret; */
+ set_cstrp_value(v, reader->obj->debug_line_str.ptr, read_uint(reader));
break;
case DW_FORM_ref_sig8:
set_uint_value(v, read_uint64(&reader->p));
@@ -1227,28 +1304,28 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa
set_uint_value(v, read_uint64(&reader->p));
break;
case DW_FORM_strx1:
- set_uint_value(v, read_uint8(&reader->p));
+ set_cstr_value(v, resolve_strx(reader, read_uint8(&reader->p)));
break;
case DW_FORM_strx2:
- set_uint_value(v, read_uint16(&reader->p));
+ set_cstr_value(v, resolve_strx(reader, read_uint16(&reader->p)));
break;
case DW_FORM_strx3:
- set_uint_value(v, read_uint24(&reader->p));
+ set_cstr_value(v, resolve_strx(reader, read_uint24(&reader->p)));
break;
case DW_FORM_strx4:
- set_uint_value(v, read_uint32(&reader->p));
+ set_cstr_value(v, resolve_strx(reader, read_uint32(&reader->p)));
break;
case DW_FORM_addrx1:
- set_uint_value(v, read_uint8(&reader->p));
+ set_addr_idx_value(v, read_uint8(&reader->p));
break;
case DW_FORM_addrx2:
- set_uint_value(v, read_uint16(&reader->p));
+ set_addr_idx_value(v, read_uint16(&reader->p));
break;
case DW_FORM_addrx3:
- set_uint_value(v, read_uint24(&reader->p));
+ set_addr_idx_value(v, read_uint24(&reader->p));
break;
case DW_FORM_addrx4:
- set_uint_value(v, read_uint32(&reader->p));
+ set_addr_idx_value(v, read_uint32(&reader->p));
break;
case 0:
goto fail;
@@ -1376,6 +1453,76 @@ di_skip_records(DebugInfoReader *reader)
}
}
+typedef struct addr_header {
+ const char *ptr;
+ uint64_t unit_length;
+ uint8_t format;
+ uint8_t address_size;
+ /* uint8_t segment_selector_size; */
+} addr_header_t;
+
+static void
+addr_header_init(obj_info_t *obj, addr_header_t *header) {
+ const char *p = obj->debug_addr.ptr;
+
+ header->ptr = p;
+
+ if (!p) return;
+
+ header->unit_length = *(uint32_t *)p;
+ p += sizeof(uint32_t);
+
+ header->format = 4;
+ if (header->unit_length == 0xffffffff) {
+ header->unit_length = *(uint64_t *)p;
+ p += sizeof(uint64_t);
+ header->format = 8;
+ }
+
+ p += 2; /* version */
+ header->address_size = *p++;
+ p++; /* segment_selector_size */
+}
+
+static uint64_t
+read_addr(addr_header_t *header, uint64_t addr_base, uint64_t idx) {
+ if (header->address_size == 4) {
+ return ((uint32_t*)(header->ptr + addr_base))[idx];
+ }
+ else {
+ return ((uint64_t*)(header->ptr + addr_base))[idx];
+ }
+}
+
+typedef struct rnglists_header {
+ uint64_t unit_length;
+ uint8_t format;
+ uint8_t address_size;
+ uint32_t offset_entry_count;
+} rnglists_header_t;
+
+static void
+rnglists_header_init(obj_info_t *obj, rnglists_header_t *header) {
+ const char *p = obj->debug_rnglists.ptr;
+
+ if (!p) return;
+
+ header->unit_length = *(uint32_t *)p;
+ p += sizeof(uint32_t);
+
+ header->format = 4;
+ if (header->unit_length == 0xffffffff) {
+ header->unit_length = *(uint64_t *)p;
+ p += sizeof(uint64_t);
+ header->format = 8;
+ }
+
+ p += 2; /* version */
+ header->address_size = *p++;
+ p++; /* segment_selector_size */
+ header->offset_entry_count = *(uint32_t *)p;
+}
+
typedef struct {
uint64_t low_pc;
uint64_t high_pc;
@@ -1386,24 +1533,31 @@ typedef struct {
} ranges_t;
static void
-ranges_set(ranges_t *ptr, DebugInfoValue *v)
+ranges_set(ranges_t *ptr, DebugInfoValue *v, addr_header_t *addr_header, uint64_t addr_base)
{
+ uint64_t n = 0;
+ if (v->type == VAL_uint) {
+ n = v->as.uint64;
+ }
+ else if (v->type == VAL_addr) {
+ n = read_addr(addr_header, addr_base, v->as.addr_idx);
+ }
switch (v->at) {
case DW_AT_low_pc:
- ptr->low_pc = v->as.uint64;
+ ptr->low_pc = n;
ptr->low_pc_set = true;
break;
case DW_AT_high_pc:
if (v->form == DW_FORM_addr) {
- ptr->high_pc = v->as.uint64;
+ ptr->high_pc = n;
}
else {
- ptr->high_pc = ptr->low_pc + v->as.uint64;
+ ptr->high_pc = ptr->low_pc + n;
}
ptr->high_pc_set = true;
break;
case DW_AT_ranges:
- ptr->ranges = v->as.uint64;
+ ptr->ranges = n;
ptr->ranges_set = true;
break;
}
@@ -1425,7 +1579,7 @@ read_dw_form_addr(DebugInfoReader *reader, const char **ptr)
}
static uintptr_t
-ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
+ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr, rnglists_header_t *rnglists_header)
{
if (ptr->high_pc_set) {
if (ptr->ranges_set || !ptr->low_pc_set) {
@@ -1440,8 +1594,21 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr)
const char *p;
uint64_t base = ptr->low_pc_set ? ptr->low_pc : reader->current_low_pc;
bool base_valid = true;
- if (reader->obj->debug_rnglists.ptr) {
- p = reader->obj->debug_rnglists.ptr + ptr->ranges;
+ if (reader->current_version >= 5) {
+ if (rnglists_header->offset_entry_count == 0) {
+ // DW_FORM_sec_offset
+ p = reader->obj->debug_rnglists.ptr + ptr->ranges + reader->current_rnglists_base;
+ }
+ else {
+ // DW_FORM_rnglistx
+ const char *offset_array = reader->obj->debug_rnglists.ptr + reader->current_rnglists_base;
+ if (rnglists_header->format == 4) {
+ p = offset_array + ((uint32_t *)offset_array)[ptr->ranges];
+ }
+ else {
+ p = offset_array + ((uint64_t *)offset_array)[ptr->ranges];
+ }
+ }
for (;;) {
uint8_t rle = read_uint8(&p);
uintptr_t from = 0, to = 0;
@@ -1551,6 +1718,7 @@ di_read_cu(DebugInfoReader *reader)
}
reader->cu_end = reader->p + unit_length;
version = read_uint16(&reader->p);
+ reader->current_version = version;
if (version > 5) {
return -1;
}
@@ -1583,16 +1751,45 @@ di_read_cu(DebugInfoReader *reader)
break;
}
+ reader->current_str_offsets_base = 0;
+ reader->current_addr_base = 0;
+ reader->current_rnglists_base = 0;
+
+ DebugInfoValue low_pc = {{}};
/* enumerate abbrev */
for (;;) {
DebugInfoValue v = {{}};
if (!di_read_record(reader, &v)) break;
switch (v.at) {
case DW_AT_low_pc:
- reader->current_low_pc = v.as.uint64;
+ // clang may output DW_AT_addr_base after DW_AT_low_pc.
+ // We need to resolve the DW_FORM_addr* after DW_AT_addr_base is parsed.
+ low_pc = v;
+ break;
+ case DW_AT_str_offsets_base:
+ reader->current_str_offsets_base = v.as.uint64;
+ break;
+ case DW_AT_addr_base:
+ reader->current_addr_base = v.as.uint64;
+ break;
+ case DW_AT_rnglists_base:
+ reader->current_rnglists_base = v.as.uint64;
break;
}
}
+ // Resolve the DW_FORM_addr of DW_AT_low_pc
+ switch (low_pc.type) {
+ case VAL_uint:
+ reader->current_low_pc = low_pc.as.uint64;
+ break;
+ case VAL_addr:
+ {
+ addr_header_t header;
+ addr_header_init(reader->obj, &header);
+ reader->current_low_pc = read_addr(&header, reader->current_addr_base, low_pc.as.addr_idx);
+ }
+ break;
+ }
} while (0);
#endif
return 0;
@@ -1646,6 +1843,13 @@ read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_o
static void
debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
line_info_t *lines, int offset) {
+
+ addr_header_t addr_header = {};
+ addr_header_init(reader->obj, &addr_header);
+
+ rnglists_header_t rnglists_header = {};
+ rnglists_header_init(reader->obj, &rnglists_header);
+
while (reader->p < reader->cu_end) {
DIE die;
ranges_t ranges = {};
@@ -1672,7 +1876,7 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
line.sname = get_cstr_value(&v);
break;
case DW_AT_call_file:
- fill_filename((int)v.as.uint64, reader->debug_line_directories, reader->debug_line_files, &line, reader->obj);
+ fill_filename((int)v.as.uint64, reader->debug_line_format, reader->debug_line_version, reader->debug_line_directories, reader->debug_line_files, &line, reader->obj);
break;
case DW_AT_call_line:
line.line = (int)v.as.uint64;
@@ -1680,7 +1884,7 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
case DW_AT_low_pc:
case DW_AT_high_pc:
case DW_AT_ranges:
- ranges_set(&ranges, &v);
+ ranges_set(&ranges, &v, &addr_header, reader->current_addr_base);
break;
case DW_AT_declaration:
goto skip_die;
@@ -1697,9 +1901,9 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
for (int i=offset; i < num_traces; i++) {
uintptr_t addr = (uintptr_t)traces[i];
uintptr_t offset = addr - reader->obj->base_addr + reader->obj->vmaddr;
- uintptr_t saddr = ranges_include(reader, &ranges, offset);
+ uintptr_t saddr = ranges_include(reader, &ranges, offset, &rnglists_header);
if (saddr) {
- /* fprintf(stderr, "%d:%tx: %d %lx->%lx %x %s: %s/%s %d %s %s %s\n",__LINE__,die.pos, i,addr,offset, die.tag,line.sname,line.dirname,line.filename,line.line,reader->obj->path,line.sname,lines[i].sname); */
+ /* fprintf(stdout, "%d:%tx: %d %lx->%lx %x %s: %s/%s %d %s %s %s\n",__LINE__,die.pos, i,addr,offset, die.tag,line.sname,line.dirname,line.filename,line.line,reader->obj->path,line.sname,lines[i].sname); */
if (lines[i].sname) {
line_info_t *lp = malloc(sizeof(line_info_t));
memcpy(lp, &lines[i], sizeof(line_info_t));
@@ -1718,6 +1922,54 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces,
}
}
+// This function parses the following attributes of Line Number Program Header in DWARF 5:
+//
+// * directory_entry_format_count
+// * directory_entry_format
+// * directories_count
+// * directories
+//
+// or
+//
+// * file_name_entry_format_count
+// * file_name_entry_format
+// * file_names_count
+// * file_names
+//
+// It records DW_LNCT_path and DW_LNCT_directory_index at the index "idx".
+static const char *
+parse_ver5_debug_line_header(const char *p, int idx, uint8_t format, obj_info_t *obj, const char **out_path, uint64_t *out_directory_index) {
+ int i, j;
+ int entry_format_count = *(uint8_t *)p++;
+ const char *entry_format = p;
+
+ /* skip the part of entry_format */
+ for (i = 0; i < entry_format_count * 2; i++) uleb128(&p);
+
+ int entry_count = (int)uleb128(&p);
+
+ DebugInfoReader reader;
+ debug_info_reader_init(&reader, obj);
+ reader.format = format;
+ reader.p = p;
+ for (j = 0; j < entry_count; j++) {
+ const char *format = entry_format;
+ for (i = 0; i < entry_format_count; i++) {
+ DebugInfoValue v = {{}};
+ unsigned long dw_lnct = uleb128(&format);
+ unsigned long dw_form = uleb128(&format);
+ debug_info_reader_read_value(&reader, dw_form, &v);
+ if (dw_lnct == 1 /* DW_LNCT_path */ && v.type == VAL_cstr && out_path)
+ *out_path = v.as.ptr + v.off;
+ if (dw_lnct == 2 /* DW_LNCT_directory_index */ && v.type == VAL_uint && out_directory_index)
+ *out_directory_index = v.as.uint64;
+ }
+ if (j == idx) return 0;
+ }
+
+ return reader.p;
+}
+
#ifdef USE_ELF
static unsigned long
uncompress_debug_section(ElfW(Shdr) *shdr, char *file, char **ptr)
@@ -1846,8 +2098,11 @@ fill_lines(int num_traces, void **traces, int check_debuglink,
".debug_info",
".debug_line",
".debug_ranges",
+ ".debug_str_offsets",
+ ".debug_addr",
".debug_rnglists",
- ".debug_str"
+ ".debug_str",
+ ".debug_line_str"
};
for (j=0; j < DWARF_SECTION_COUNT; j++) {
@@ -2103,8 +2358,11 @@ found_mach_header:
"__debug_info",
"__debug_line",
"__debug_ranges",
+ "__debug_str_offsets",
+ "__debug_addr",
"__debug_rnglists",
- "__debug_str"
+ "__debug_str",
+ "__debug_line_str",
};
struct LP(segment_command) *scmd = (struct LP(segment_command) *)lcmd;
if (strcmp(scmd->segname, "__TEXT") == 0) {
@@ -2302,6 +2560,7 @@ rb_dump_backtrace_with_lines(int num_traces, void **traces)
obj_info_t *obj = NULL;
/* 2 is NULL + main executable */
void **dladdr_fbases = (void **)calloc(num_traces+2, sizeof(void *));
+
#ifdef HAVE_MAIN_EXE_PATH
char *main_path = NULL; /* used on printing backtrace */
ssize_t len;
diff --git a/array.c b/array.c
index ae032fb127..b76e9a64a3 100644
--- a/array.c
+++ b/array.c
@@ -226,8 +226,15 @@ ary_embeddable_p(long capa)
bool
rb_ary_embeddable_p(VALUE ary)
{
- // if the array is shared or a shared root then it's not moveable
- return !(ARY_SHARED_P(ary) || ARY_SHARED_ROOT_P(ary));
+ /* An array cannot be turned embeddable when the array is:
+ * - Shared root: other objects may point to the buffer of this array
+ * so we cannot make it embedded.
+ * - Frozen: this array may also be a shared root without the shared root
+ * flag.
+ * - Shared: we don't want to re-embed an array that points to a shared
+ * root (to save memory).
+ */
+ return !(ARY_SHARED_ROOT_P(ary) || OBJ_FROZEN(ary) || ARY_SHARED_P(ary));
}
size_t
@@ -242,7 +249,7 @@ rb_ary_size_as_embedded(VALUE ary)
real_size = ary_embed_size(ARY_HEAP_CAPA(ary));
}
else {
- real_size = sizeof(struct RString);
+ real_size = sizeof(struct RArray);
}
return real_size;
}
@@ -3729,8 +3736,8 @@ rb_ary_bsearch_index(VALUE ary)
const VALUE zero = INT2FIX(0);
switch (rb_cmpint(rb_funcallv(v, id_cmp, 1, &zero), v, zero)) {
case 0: return INT2FIX(mid);
- case 1: smaller = 1; break;
- case -1: smaller = 0;
+ case 1: smaller = 0; break;
+ case -1: smaller = 1;
}
}
else {
diff --git a/ast.c b/ast.c
index bf3781d820..adb7287ed3 100644
--- a/ast.c
+++ b/ast.c
@@ -202,6 +202,11 @@ static VALUE
node_id_for_backtrace_location(rb_execution_context_t *ec, VALUE module, VALUE location)
{
int node_id;
+
+ if (!rb_frame_info_p(location)) {
+ rb_raise(rb_eTypeError, "Thread::Backtrace::Location object expected");
+ }
+
node_id = rb_get_node_id_from_frame_info(location);
if (node_id == -1) {
return Qnil;
diff --git a/ast.rb b/ast.rb
index 2b803461ed..f3f72c747f 100644
--- a/ast.rb
+++ b/ast.rb
@@ -20,21 +20,47 @@
module RubyVM::AbstractSyntaxTree
# call-seq:
- # RubyVM::AbstractSyntaxTree.parse(string) -> RubyVM::AbstractSyntaxTree::Node
+ # RubyVM::AbstractSyntaxTree.parse(string, keep_script_lines: false, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
#
# Parses the given _string_ into an abstract syntax tree,
# returning the root node of that tree.
#
- # SyntaxError is raised if the given _string_ is invalid syntax.
- #
# RubyVM::AbstractSyntaxTree.parse("x = 1 + 2")
# # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-1:9>
+ #
+ # If <tt>keep_script_lines: true</tt> option is provided, the text of the parsed
+ # source is associated with nodes and is available via Node#script_lines.
+ #
+ # If <tt>keep_tokens: true</tt> option is provided, Node#tokens are populated.
+ #
+ # SyntaxError is raised if the given _string_ is invalid syntax. To overwrite this
+ # behavior, <tt>error_tolerant: true</tt> can be provided. In this case, the parser
+ # will produce a tree where expressions with syntax errors would be represented by
+ # Node with <tt>type=:ERROR</tt>.
+ #
+ # root = RubyVM::AbstractSyntaxTree.parse("x = 1; p(x; y=2")
+ # # <internal:ast>:33:in `parse': syntax error, unexpected ';', expecting ')' (SyntaxError)
+ # # x = 1; p(x; y=2
+ # # ^
+ #
+ # root = RubyVM::AbstractSyntaxTree.parse("x = 1; p(x; y=2", error_tolerant: true)
+ # # (SCOPE@1:0-1:15
+ # # tbl: [:x, :y]
+ # # args: nil
+ # # body: (BLOCK@1:0-1:15 (LASGN@1:0-1:5 :x (LIT@1:4-1:5 1)) (ERROR@1:7-1:11) (LASGN@1:12-1:15 :y (LIT@1:14-1:15 2))))
+ # root.children.last.children
+ # # [(LASGN@1:0-1:5 :x (LIT@1:4-1:5 1)),
+ # # (ERROR@1:7-1:11),
+ # # (LASGN@1:12-1:15 :y (LIT@1:14-1:15 2))]
+ #
+ # Note that parsing continues even after the errored expresion.
+ #
def self.parse string, keep_script_lines: false, error_tolerant: false, keep_tokens: false
Primitive.ast_s_parse string, keep_script_lines, error_tolerant, keep_tokens
end
# call-seq:
- # RubyVM::AbstractSyntaxTree.parse_file(pathname) -> RubyVM::AbstractSyntaxTree::Node
+ # RubyVM::AbstractSyntaxTree.parse_file(pathname, keep_script_lines: false, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
#
# Reads the file from _pathname_, then parses it like ::parse,
# returning the root node of the abstract syntax tree.
@@ -44,13 +70,15 @@ module RubyVM::AbstractSyntaxTree
#
# RubyVM::AbstractSyntaxTree.parse_file("my-app/app.rb")
# # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-31:3>
+ #
+ # See ::parse for explanation of keyword argument meaning and usage.
def self.parse_file pathname, keep_script_lines: false, error_tolerant: false, keep_tokens: false
Primitive.ast_s_parse_file pathname, keep_script_lines, error_tolerant, keep_tokens
end
# call-seq:
- # RubyVM::AbstractSyntaxTree.of(proc) -> RubyVM::AbstractSyntaxTree::Node
- # RubyVM::AbstractSyntaxTree.of(method) -> RubyVM::AbstractSyntaxTree::Node
+ # RubyVM::AbstractSyntaxTree.of(proc, keep_script_lines: false, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
+ # RubyVM::AbstractSyntaxTree.of(method, keep_script_lines: false, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node
#
# Returns AST nodes of the given _proc_ or _method_.
#
@@ -63,6 +91,8 @@ module RubyVM::AbstractSyntaxTree
#
# RubyVM::AbstractSyntaxTree.of(method(:hello))
# # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-3:3>
+ #
+ # See ::parse for explanation of keyword argument meaning and usage.
def self.of body, keep_script_lines: false, error_tolerant: false, keep_tokens: false
Primitive.ast_s_of body, keep_script_lines, error_tolerant, keep_tokens
end
diff --git a/bignum.c b/bignum.c
index 4f8349dd17..cb2c3b6f07 100644
--- a/bignum.c
+++ b/bignum.c
@@ -4184,7 +4184,6 @@ rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits,
}
if (!c || ISSPACE(c)) --str;
if (end) len = end - str;
- ASSERT_LEN();
}
c = *str;
c = conv_digit(c);
@@ -4587,11 +4586,14 @@ big_shift3(VALUE x, int lshift_p, size_t shift_numdigits, int shift_numbits)
if (lshift_p) {
if (LONG_MAX < shift_numdigits) {
- rb_raise(rb_eArgError, "too big number");
+ too_big:
+ rb_raise(rb_eRangeError, "shift width too big");
}
s1 = shift_numdigits;
s2 = shift_numbits;
+ if ((size_t)s1 != shift_numdigits) goto too_big;
xn = BIGNUM_LEN(x);
+ if (LONG_MAX/SIZEOF_BDIGIT <= xn+s1) goto too_big;
z = bignew(xn+s1+1, BIGNUM_SIGN(x));
zds = BDIGITS(z);
BDIGITS_ZERO(zds, s1);
diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb
index 4f659374f2..67e66b03ee 100644
--- a/bootstraptest/test_ractor.rb
+++ b/bootstraptest/test_ractor.rb
@@ -480,7 +480,6 @@ assert_equal 'ok', %q{
}
# multiple Ractors can receive (wait) from one Ractor
-yjit_enabled = ENV.key?('RUBY_YJIT_ENABLE') || ENV.fetch('RUN_OPTS', '').include?('yjit')
assert_equal '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', %q{
pipe = Ractor.new do
loop do
@@ -503,7 +502,7 @@ assert_equal '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]', %q{
rs.delete r
n
}.sort
-} unless yjit_enabled # flaky with YJIT https://github.com/ruby/ruby/actions/runs/3603398545/jobs/6071549328#step:18:33
+} unless /mswin/ =~ RUBY_PLATFORM # randomly hangs on mswin https://github.com/ruby/ruby/actions/runs/3753871445/jobs/6377551069#step:20:131
# Ractor.select also support multiple take, receive and yield
assert_equal '[true, true, true]', %q{
@@ -1502,7 +1501,7 @@ assert_equal "#{n}#{n}", %Q{
end
end
}.map{|r| r.take}.join
-} unless yjit_enabled # flaky with YJIT https://github.com/ruby/ruby/actions/runs/3692339025/jobs/6251137785
+}
# NameError
assert_equal "ok", %q{
@@ -1543,7 +1542,7 @@ assert_equal "ok", %q{
1_000.times { idle_worker, tmp_reporter = Ractor.select(*workers) }
"ok"
-} unless yjit_enabled # flaky with YJIT https://github.com/ruby/ruby/actions/runs/3575374374/jobs/6011846425
+}
assert_equal "ok", %q{
def foo(*); ->{ super }; end
diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb
index 349417595f..5c655b8f25 100644
--- a/bootstraptest/test_yjit.rb
+++ b/bootstraptest/test_yjit.rb
@@ -1,3 +1,33 @@
+# Regression test for yielding with autosplat to block with
+# optional parameters. https://github.com/Shopify/yjit/issues/313
+assert_equal '[:a, :b, :a, :b]', %q{
+ def yielder(arg) = yield(arg) + yield(arg)
+
+ yielder([:a, :b]) do |c = :c, d = :d|
+ [c, d]
+ end
+}
+
+# Regression test for GC mishap while doing shape transition
+assert_equal '[:ok]', %q{
+ # [Bug #19601]
+ class RegressionTest
+ def initialize
+ @a = @b = @fourth_ivar_does_shape_transition = nil
+ end
+
+ def extender
+ @first_extended_ivar = [:ok]
+ end
+ end
+
+ GC.stress = true
+
+ # Used to crash due to GC run in rb_ensure_iv_list_size()
+ # not marking the newly allocated [:ok].
+ RegressionTest.new.extender.itself
+}
+
assert_equal 'true', %q{
# regression test for tracking type of locals for too long
def local_setting_cmp(five)
@@ -221,6 +251,8 @@ assert_equal 'string', %q{
# Check that exceptions work when getting global variable
assert_equal 'rescued', %q{
+ Warning[:deprecated] = true
+
module Warning
def warn(message)
raise
@@ -1141,6 +1173,38 @@ assert_equal '42', %q{
run
}
+# splatting an empty array on a specialized method
+assert_equal 'ok', %q{
+ def run
+ "ok".to_s(*[])
+ end
+
+ run
+ run
+}
+
+# splatting an single element array on a specialized method
+assert_equal '[1]', %q{
+ def run
+ [].<<(*[1])
+ end
+
+ run
+ run
+}
+
+# specialized method with wrong args
+assert_equal 'ok', %q{
+ def run(x)
+ "bad".to_s(123) if x
+ rescue
+ :ok
+ end
+
+ run(false)
+ run(true)
+}
+
# getinstancevariable on Symbol
assert_equal '[nil, nil]', %q{
# @foo to exercise the getinstancevariable instruction
@@ -2173,7 +2237,7 @@ assert_equal '[[:c_return, :String, :string_alias, "events_to_str"]]', %q{
events.compiled(events)
events
-}
+} unless defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # MJIT calls extra Ruby methods
# test enabling a TracePoint that targets a particular line in a C method call
assert_equal '[true]', %q{
@@ -2255,7 +2319,7 @@ assert_equal '[[:c_call, :itself]]', %q{
tp.enable { shouldnt_compile }
events
-}
+} unless defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # MJIT calls extra Ruby methods
# test enabling c_return tracing before compiling
assert_equal '[[:c_return, :itself, main]]', %q{
@@ -2270,7 +2334,7 @@ assert_equal '[[:c_return, :itself, main]]', %q{
tp.enable { shouldnt_compile }
events
-}
+} unless defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # MJIT calls extra Ruby methods
# test c_call invalidation
assert_equal '[[:c_call, :itself]]', %q{
@@ -3456,3 +3520,11 @@ assert_equal 'ok', %q{
cw(4)
}
+
+assert_normal_exit %{
+ class Bug20997
+ def foo(&) = self.class.name(&)
+
+ new.foo
+ end
+}
diff --git a/class.c b/class.c
index 847c4d0a57..cf0b7b821f 100644
--- a/class.c
+++ b/class.c
@@ -404,6 +404,30 @@ class_init_copy_check(VALUE clone, VALUE orig)
}
}
+struct cvc_table_copy_ctx {
+ VALUE clone;
+ struct rb_id_table * new_table;
+};
+
+static enum rb_id_table_iterator_result
+cvc_table_copy(ID id, VALUE val, void *data) {
+ struct cvc_table_copy_ctx *ctx = (struct cvc_table_copy_ctx *)data;
+ struct rb_cvar_class_tbl_entry * orig_entry;
+ orig_entry = (struct rb_cvar_class_tbl_entry *)val;
+
+ struct rb_cvar_class_tbl_entry *ent;
+
+ ent = ALLOC(struct rb_cvar_class_tbl_entry);
+ ent->class_value = ctx->clone;
+ ent->cref = orig_entry->cref;
+ ent->global_cvar_state = orig_entry->global_cvar_state;
+ rb_id_table_insert(ctx->new_table, id, (VALUE)ent);
+
+ RB_OBJ_WRITTEN(ctx->clone, Qundef, ent->cref);
+
+ return ID_TABLE_CONTINUE;
+}
+
static void
copy_tables(VALUE clone, VALUE orig)
{
@@ -411,6 +435,17 @@ copy_tables(VALUE clone, VALUE orig)
rb_free_const_table(RCLASS_CONST_TBL(clone));
RCLASS_CONST_TBL(clone) = 0;
}
+ if (RCLASS_CVC_TBL(orig)) {
+ struct rb_id_table *rb_cvc_tbl = RCLASS_CVC_TBL(orig);
+ struct rb_id_table *rb_cvc_tbl_dup = rb_id_table_create(rb_id_table_size(rb_cvc_tbl));
+
+ struct cvc_table_copy_ctx ctx;
+ ctx.clone = clone;
+ ctx.new_table = rb_cvc_tbl_dup;
+ rb_id_table_foreach(rb_cvc_tbl, cvc_table_copy, &ctx);
+ RCLASS_CVC_TBL(clone) = rb_cvc_tbl_dup;
+ }
+ rb_id_table_free(RCLASS_M_TBL(clone));
RCLASS_M_TBL(clone) = 0;
if (!RB_TYPE_P(clone, T_ICLASS)) {
st_data_t id;
@@ -923,7 +958,7 @@ rb_define_class_under(VALUE outer, const char *name, VALUE super)
}
VALUE
-rb_define_class_id_under(VALUE outer, ID id, VALUE super)
+rb_define_class_id_under_no_pin(VALUE outer, ID id, VALUE super)
{
VALUE klass;
@@ -940,8 +975,6 @@ rb_define_class_id_under(VALUE outer, ID id, VALUE super)
" (%"PRIsVALUE" is given but was %"PRIsVALUE")",
outer, rb_id2str(id), RCLASS_SUPER(klass), super);
}
- /* Class may have been defined in Ruby and not pin-rooted */
- rb_vm_add_root_module(klass);
return klass;
}
@@ -953,12 +986,19 @@ rb_define_class_id_under(VALUE outer, ID id, VALUE super)
rb_set_class_path_string(klass, outer, rb_id2str(id));
rb_const_set(outer, id, klass);
rb_class_inherited(super, klass);
- rb_vm_add_root_module(klass);
return klass;
}
VALUE
+rb_define_class_id_under(VALUE outer, ID id, VALUE super)
+{
+ VALUE klass = rb_define_class_id_under_no_pin(outer, id, super);
+ rb_vm_add_root_module(klass);
+ return klass;
+}
+
+VALUE
rb_module_s_alloc(VALUE klass)
{
VALUE mod = class_alloc(T_MODULE, klass);
@@ -1105,8 +1145,8 @@ rb_include_module(VALUE klass, VALUE module)
iclass = iclass->next;
}
- int do_include = 1;
while (iclass) {
+ int do_include = 1;
VALUE check_class = iclass->klass;
/* During lazy sweeping, iclass->klass could be a dead object that
* has not yet been swept. */
@@ -1173,7 +1213,7 @@ static int
do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super, bool check_cyclic)
{
VALUE p, iclass, origin_stack = 0;
- int method_changed = 0, add_subclass;
+ int method_changed = 0;
long origin_len;
VALUE klass_origin = RCLASS_ORIGIN(klass);
VALUE original_klass = klass;
@@ -1237,7 +1277,6 @@ do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super
iclass = rb_include_class_new(module, super_class);
c = RCLASS_SET_SUPER(c, iclass);
RCLASS_SET_INCLUDER(iclass, klass);
- add_subclass = TRUE;
if (module != RCLASS_ORIGIN(module)) {
if (!origin_stack) origin_stack = rb_ary_hidden_new(2);
VALUE origin[2] = {iclass, RCLASS_ORIGIN(module)};
@@ -1248,14 +1287,11 @@ do_include_modules_at(const VALUE klass, VALUE c, VALUE module, int search_super
RCLASS_SET_ORIGIN(RARRAY_AREF(origin_stack, (origin_len -= 2)), iclass);
RICLASS_SET_ORIGIN_SHARED_MTBL(iclass);
rb_ary_resize(origin_stack, origin_len);
- add_subclass = FALSE;
}
- if (add_subclass) {
- VALUE m = module;
- if (BUILTIN_TYPE(m) == T_ICLASS) m = METACLASS_OF(m);
- rb_module_add_to_subclasses_list(m, iclass);
- }
+ VALUE m = module;
+ if (BUILTIN_TYPE(m) == T_ICLASS) m = METACLASS_OF(m);
+ rb_module_add_to_subclasses_list(m, iclass);
if (BUILTIN_TYPE(klass) == T_MODULE && FL_TEST(klass, RMODULE_IS_REFINEMENT)) {
VALUE refined_class =
diff --git a/common.mk b/common.mk
index 59fe911db5..126053c9c8 100644
--- a/common.mk
+++ b/common.mk
@@ -43,7 +43,7 @@ RUN_OPTS = --disable-gems
# GITPULLOPTIONS = --no-tags
-INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir) -I$(UNICODE_HDR_DIR)
+INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir) -I$(UNICODE_HDR_DIR) $(incflags)
GEM_HOME =
GEM_PATH =
@@ -235,9 +235,9 @@ all: $(SHOWFLAGS) main docs
main: $(SHOWFLAGS) exts $(ENCSTATIC:static=lib)encs
@$(NULLCMD)
-main: $(srcdir)/lib/mjit/instruction.rb
-srcs: $(srcdir)/lib/mjit/instruction.rb
-$(srcdir)/lib/mjit/instruction.rb: $(tooldir)/insns2vm.rb $(tooldir)/ruby_vm/views/lib/mjit/instruction.rb.erb $(srcdir)/insns.def
+main: $(srcdir)/lib/ruby_vm/mjit/instruction.rb
+srcs: $(srcdir)/lib/ruby_vm/mjit/instruction.rb
+$(srcdir)/lib/ruby_vm/mjit/instruction.rb: $(tooldir)/insns2vm.rb $(tooldir)/ruby_vm/views/lib/ruby_vm/mjit/instruction.rb.erb $(srcdir)/insns.def
$(ECHO) generating $@
$(Q) $(BASERUBY) -Ku $(tooldir)/insns2vm.rb --basedir="$(srcdir)" $(INSNS2VMOPT) $@
@@ -640,7 +640,7 @@ clean-local:: clean-runnable
$(Q)$(RM) probes.h probes.$(OBJEXT) probes.stamp ruby-glommed.$(OBJEXT) ruby.imp ChangeLog $(STATIC_RUBY)$(EXEEXT)
$(Q)$(RM) GNUmakefile.old Makefile.old $(arch)-fake.rb bisect.sh $(ENC_TRANS_D) builtin_binary.inc
-$(Q)$(RMALL) yjit/target
- -$(Q) $(RMDIR) enc/jis enc/trans enc $(COROUTINE_H:/Context.h=) coroutine 2> $(NULL) || $(NULLCMD)
+ -$(Q) $(RMDIR) enc/jis enc/trans enc $(COROUTINE_H:/Context.h=) coroutine yjit 2> $(NULL) || $(NULLCMD)
bin/clean-runnable:: PHONY
$(Q)$(CHDIR) bin 2>$(NULL) && $(RM) $(PROGRAM) $(WPROGRAM) $(GORUBY)$(EXEEXT) bin/*.$(DLEXT) 2>$(NULL) || $(NULLCMD)
@@ -766,7 +766,7 @@ clean-spec: PHONY
-$(Q) $(RMDIRS) $(RUBYSPEC_CAPIEXT) 2> $(NULL) || $(NULLCMD)
-$(Q) $(RMALL) rubyspec_temp
-check: main $(DOT_WAIT) test $(DOT_WAIT) test-tool $(DOT_WAIT) test-all $(DOT_WAIT) test-spec
+check: main $(DOT_WAIT) test $(DOT_WAIT) test-tool $(DOT_WAIT) test-all
$(ECHO) check succeeded
-$(Q) : : "run only on sh"; \
if [ x"$(GIT)" != x ] && $(CHDIR) "$(srcdir)" && \
@@ -790,10 +790,11 @@ $(arch:noarch=ignore)-fake.rb: $(srcdir)/template/fake.rb.in $(tooldir)/generic_
$(ECHO) generating $@
$(Q) $(CPP) -DRUBY_EXPORT $(INCFLAGS) $(CPPFLAGS) "$(srcdir)/version.c" | \
$(BOOTSTRAPRUBY) "$(tooldir)/generic_erb.rb" -o $@ "$(srcdir)/template/fake.rb.in" \
- i=- srcdir="$(srcdir)" BASERUBY="$(BASERUBY)"
+ i=- srcdir="$(srcdir)" BASERUBY="$(BASERUBY)" \
+ LIBPATHENV="$(LIBPATHENV)" PRELOADENV="$(PRELOADENV)" LIBRUBY_SO="$(LIBRUBY_SO)"
noarch-fake.rb: # prerequisite of yes-fake
- touch $@
+ $(Q) exit > $@
btest: $(TEST_RUNNABLE)-btest
no-btest: PHONY
@@ -902,6 +903,8 @@ yes-test-spec: test-spec-precheck
$(ACTIONS_ENDGROUP)
no-test-spec:
+check: $(DOT_WAIT) test-spec
+
RUNNABLE = $(LIBRUBY_RELATIVE:no=un)-runnable
runnable: $(RUNNABLE) prog $(tooldir)/mkrunnable.rb PHONY
$(Q) $(MINIRUBY) $(tooldir)/mkrunnable.rb -v $(EXTOUT)
@@ -1221,7 +1224,7 @@ $(srcdir)/revision.h$(no_baseruby:no=~disabled~): $(REVISION_H)
$(REVISION_H)$(no_baseruby:no=~disabled~):
$(Q) $(BASERUBY) $(tooldir)/file2lastrev.rb -q --revision.h --srcdir="$(srcdir)" --output=revision.h --timestamp=$@
$(REVISION_H)$(yes_baseruby:yes=~disabled~):
- $(Q) touch $@
+ $(Q) exit > $@
$(srcdir)/ext/ripper/ripper.c: $(srcdir)/ext/ripper/tools/preproc.rb $(srcdir)/parse.y $(srcdir)/defs/id.def $(srcdir)/ext/ripper/depend
$(ECHO) generating $@
@@ -1357,7 +1360,7 @@ after-update:: extract-gems
update-src::
$(Q) $(RM) $(REVISION_H) revision.h "$(srcdir)/$(REVISION_H)" "$(srcdir)/revision.h"
- $(Q) touch "$(srcdir)/revision.h"
+ $(Q) exit > "$(srcdir)/revision.h"
update-remote:: update-src update-download
update-download:: $(ALWAYS_UPDATE_UNICODE:yes=update-unicode)
@@ -1373,7 +1376,6 @@ update-config_files: PHONY
refresh-gems: update-bundled_gems prepare-gems
prepare-gems: $(HAVE_BASERUBY:yes=update-gems) $(HAVE_BASERUBY:yes=extract-gems)
-prepare-gems: $(DOT_WAIT) $(HAVE_BASERUBY:yes=outdate-bundled-gems)
extract-gems: $(HAVE_BASERUBY:yes=update-gems)
update-gems$(gnumake:yes=-sequential): PHONY
@@ -1435,7 +1437,7 @@ no-test-bundled-gems-prepare: no-test-bundled-gems-precheck
yes-test-bundled-gems-prepare: yes-test-bundled-gems-precheck
$(ACTIONS_GROUP)
$(XRUBY) -C "$(srcdir)" bin/gem install --no-document \
- --install-dir .bundle --conservative "bundler" "minitest:~> 5" "test-unit" "rake" "hoe" "yard" "pry" "packnga" "rexml" "json-schema" "test-unit-rr"
+ --install-dir .bundle --conservative "bundler" "minitest:~> 5" "test-unit" "rake" "hoe" "rexml" "json-schema:5.1.0" "test-unit-rr"
$(ACTIONS_ENDGROUP)
PREPARE_BUNDLED_GEMS = test-bundled-gems-prepare
@@ -1454,6 +1456,7 @@ test-syntax-suggest-precheck: $(TEST_RUNNABLE)-test-syntax-suggest-precheck
no-test-syntax-suggest-precheck:
yes-test-syntax-suggest-precheck: main
+test-syntax-suggest-prepare: $(TEST_RUNNABLE)-test-syntax-suggest-prepare
no-test-syntax-suggest-prepare: no-test-syntax-suggest-precheck
yes-test-syntax-suggest-prepare: yes-test-syntax-suggest-precheck
$(ACTIONS_GROUP)
@@ -1463,12 +1466,15 @@ yes-test-syntax-suggest-prepare: yes-test-syntax-suggest-precheck
RSPECOPTS =
SYNTAX_SUGGEST_SPECS =
+PREPARE_SYNTAX_SUGGEST = test-syntax-suggest-prepare
test-syntax-suggest: $(TEST_RUNNABLE)-test-syntax-suggest
-yes-test-syntax-suggest: yes-test-syntax-suggest-prepare
+yes-test-syntax-suggest: yes-$(PREPARE_SYNTAX_SUGGEST)
$(XRUBY) -C $(srcdir) -Ispec/syntax_suggest .bundle/bin/rspec \
--require spec_helper $(RSPECOPTS) spec/syntax_suggest/$(SYNTAX_SUGGEST_SPECS)
no-test-syntax-suggest:
+check: $(DOT_WAIT) $(TEST_RUNNABLE)-$(PREPARE_SYNTAX_SUGGEST) test-syntax-suggest
+
test-bundler-precheck: $(TEST_RUNNABLE)-test-bundler-precheck
no-test-bundler-precheck:
yes-test-bundler-precheck: main $(arch)-fake.rb
@@ -1614,7 +1620,7 @@ $(UNICODE_SRC_DATA_DIR)/$(ALWAYS_UPDATE_UNICODE:yes=.unicode-tables.time): \
touch-unicode-files:
$(MAKEDIRS) $(UNICODE_SRC_DATA_DIR)
- touch $(UNICODE_SRC_DATA_DIR)/.unicode-tables.time $(UNICODE_DATA_HEADERS)
+ $(Q) $(TOUCH) $(UNICODE_SRC_DATA_DIR)/.unicode-tables.time $(UNICODE_DATA_HEADERS)
UNICODE_TABLES_DATA_FILES = \
$(UNICODE_SRC_DATA_DIR)/UnicodeData.txt \
@@ -1626,7 +1632,7 @@ UNICODE_TABLES_DEPENDENTS = $(UNICODE_TABLES_DEPENDENTS_1:noneyes=force)
UNICODE_TABLES_TIMESTAMP = yes
$(UNICODE_SRC_DATA_DIR)/.unicode-tables.$(UNICODE_TABLES_DEPENDENTS:none=time):
$(Q) $(MAKEDIRS) $(@D)
- touch $(@) || $(NULLCMD)
+ $(Q) exit > $(@) || $(NULLCMD)
$(UNICODE_SRC_DATA_DIR)/.unicode-tables.$(UNICODE_TABLES_DEPENDENTS:force=time): \
$(tooldir)/generic_erb.rb \
$(srcdir)/template/unicode_norm_gen.tmpl \
@@ -3215,8 +3221,13 @@ compile.$(OBJEXT): {$(VPATH)}vm_callinfo.h
compile.$(OBJEXT): {$(VPATH)}vm_core.h
compile.$(OBJEXT): {$(VPATH)}vm_debug.h
compile.$(OBJEXT): {$(VPATH)}vm_opts.h
+complex.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+complex.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+complex.$(OBJEXT): $(CCAN_DIR)/list/list.h
+complex.$(OBJEXT): $(CCAN_DIR)/str/str.h
complex.$(OBJEXT): $(hdrdir)/ruby/ruby.h
complex.$(OBJEXT): $(top_srcdir)/internal/array.h
+complex.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
complex.$(OBJEXT): $(top_srcdir)/internal/bignum.h
complex.$(OBJEXT): $(top_srcdir)/internal/bits.h
complex.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -3224,6 +3235,7 @@ complex.$(OBJEXT): $(top_srcdir)/internal/compilers.h
complex.$(OBJEXT): $(top_srcdir)/internal/complex.h
complex.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
complex.$(OBJEXT): $(top_srcdir)/internal/gc.h
+complex.$(OBJEXT): $(top_srcdir)/internal/imemo.h
complex.$(OBJEXT): $(top_srcdir)/internal/math.h
complex.$(OBJEXT): $(top_srcdir)/internal/numeric.h
complex.$(OBJEXT): $(top_srcdir)/internal/object.h
@@ -3234,6 +3246,7 @@ complex.$(OBJEXT): $(top_srcdir)/internal/variable.h
complex.$(OBJEXT): $(top_srcdir)/internal/vm.h
complex.$(OBJEXT): $(top_srcdir)/internal/warnings.h
complex.$(OBJEXT): {$(VPATH)}assert.h
+complex.$(OBJEXT): {$(VPATH)}atomic.h
complex.$(OBJEXT): {$(VPATH)}backward/2/assume.h
complex.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
complex.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -3391,11 +3404,18 @@ complex.$(OBJEXT): {$(VPATH)}internal/value_type.h
complex.$(OBJEXT): {$(VPATH)}internal/variable.h
complex.$(OBJEXT): {$(VPATH)}internal/warning_push.h
complex.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+complex.$(OBJEXT): {$(VPATH)}method.h
complex.$(OBJEXT): {$(VPATH)}missing.h
+complex.$(OBJEXT): {$(VPATH)}node.h
complex.$(OBJEXT): {$(VPATH)}ruby_assert.h
+complex.$(OBJEXT): {$(VPATH)}ruby_atomic.h
complex.$(OBJEXT): {$(VPATH)}shape.h
complex.$(OBJEXT): {$(VPATH)}st.h
complex.$(OBJEXT): {$(VPATH)}subst.h
+complex.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+complex.$(OBJEXT): {$(VPATH)}thread_native.h
+complex.$(OBJEXT): {$(VPATH)}vm_core.h
+complex.$(OBJEXT): {$(VPATH)}vm_opts.h
cont.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
cont.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
cont.$(OBJEXT): $(CCAN_DIR)/list/list.h
@@ -3406,12 +3426,14 @@ cont.$(OBJEXT): $(top_srcdir)/internal/array.h
cont.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
cont.$(OBJEXT): $(top_srcdir)/internal/compilers.h
cont.$(OBJEXT): $(top_srcdir)/internal/cont.h
+cont.$(OBJEXT): $(top_srcdir)/internal/error.h
cont.$(OBJEXT): $(top_srcdir)/internal/gc.h
cont.$(OBJEXT): $(top_srcdir)/internal/imemo.h
cont.$(OBJEXT): $(top_srcdir)/internal/proc.h
cont.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h
cont.$(OBJEXT): $(top_srcdir)/internal/serial.h
cont.$(OBJEXT): $(top_srcdir)/internal/static_assert.h
+cont.$(OBJEXT): $(top_srcdir)/internal/string.h
cont.$(OBJEXT): $(top_srcdir)/internal/variable.h
cont.$(OBJEXT): $(top_srcdir)/internal/vm.h
cont.$(OBJEXT): $(top_srcdir)/internal/warnings.h
@@ -3432,6 +3454,7 @@ cont.$(OBJEXT): {$(VPATH)}constant.h
cont.$(OBJEXT): {$(VPATH)}cont.c
cont.$(OBJEXT): {$(VPATH)}debug_counter.h
cont.$(OBJEXT): {$(VPATH)}defines.h
+cont.$(OBJEXT): {$(VPATH)}encoding.h
cont.$(OBJEXT): {$(VPATH)}eval_intern.h
cont.$(OBJEXT): {$(VPATH)}fiber/scheduler.h
cont.$(OBJEXT): {$(VPATH)}gc.h
@@ -3509,6 +3532,15 @@ cont.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h
cont.$(OBJEXT): {$(VPATH)}internal/ctype.h
cont.$(OBJEXT): {$(VPATH)}internal/dllexport.h
cont.$(OBJEXT): {$(VPATH)}internal/dosish.h
+cont.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h
+cont.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h
+cont.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h
+cont.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h
+cont.$(OBJEXT): {$(VPATH)}internal/encoding/re.h
+cont.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h
+cont.$(OBJEXT): {$(VPATH)}internal/encoding/string.h
+cont.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h
+cont.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h
cont.$(OBJEXT): {$(VPATH)}internal/error.h
cont.$(OBJEXT): {$(VPATH)}internal/eval.h
cont.$(OBJEXT): {$(VPATH)}internal/event.h
@@ -3584,6 +3616,8 @@ cont.$(OBJEXT): {$(VPATH)}method.h
cont.$(OBJEXT): {$(VPATH)}missing.h
cont.$(OBJEXT): {$(VPATH)}mjit.h
cont.$(OBJEXT): {$(VPATH)}node.h
+cont.$(OBJEXT): {$(VPATH)}onigmo.h
+cont.$(OBJEXT): {$(VPATH)}oniguruma.h
cont.$(OBJEXT): {$(VPATH)}ractor.h
cont.$(OBJEXT): {$(VPATH)}ractor_core.h
cont.$(OBJEXT): {$(VPATH)}ruby_assert.h
@@ -5870,8 +5904,13 @@ enum.$(OBJEXT): {$(VPATH)}st.h
enum.$(OBJEXT): {$(VPATH)}subst.h
enum.$(OBJEXT): {$(VPATH)}symbol.h
enum.$(OBJEXT): {$(VPATH)}util.h
+enumerator.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+enumerator.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+enumerator.$(OBJEXT): $(CCAN_DIR)/list/list.h
+enumerator.$(OBJEXT): $(CCAN_DIR)/str/str.h
enumerator.$(OBJEXT): $(hdrdir)/ruby/ruby.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/array.h
+enumerator.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/bignum.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/bits.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -5892,6 +5931,7 @@ enumerator.$(OBJEXT): $(top_srcdir)/internal/struct.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/vm.h
enumerator.$(OBJEXT): $(top_srcdir)/internal/warnings.h
enumerator.$(OBJEXT): {$(VPATH)}assert.h
+enumerator.$(OBJEXT): {$(VPATH)}atomic.h
enumerator.$(OBJEXT): {$(VPATH)}backward/2/assume.h
enumerator.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
enumerator.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -6058,13 +6098,20 @@ enumerator.$(OBJEXT): {$(VPATH)}internal/value_type.h
enumerator.$(OBJEXT): {$(VPATH)}internal/variable.h
enumerator.$(OBJEXT): {$(VPATH)}internal/warning_push.h
enumerator.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
+enumerator.$(OBJEXT): {$(VPATH)}method.h
enumerator.$(OBJEXT): {$(VPATH)}missing.h
+enumerator.$(OBJEXT): {$(VPATH)}node.h
enumerator.$(OBJEXT): {$(VPATH)}onigmo.h
enumerator.$(OBJEXT): {$(VPATH)}oniguruma.h
enumerator.$(OBJEXT): {$(VPATH)}ruby_assert.h
+enumerator.$(OBJEXT): {$(VPATH)}ruby_atomic.h
enumerator.$(OBJEXT): {$(VPATH)}shape.h
enumerator.$(OBJEXT): {$(VPATH)}st.h
enumerator.$(OBJEXT): {$(VPATH)}subst.h
+enumerator.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+enumerator.$(OBJEXT): {$(VPATH)}thread_native.h
+enumerator.$(OBJEXT): {$(VPATH)}vm_core.h
+enumerator.$(OBJEXT): {$(VPATH)}vm_opts.h
error.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
error.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
error.$(OBJEXT): $(CCAN_DIR)/list/list.h
@@ -7033,6 +7080,7 @@ goruby.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
goruby.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
goruby.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
goruby.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+goruby.$(OBJEXT): {$(VPATH)}internal/attr/nonstring.h
goruby.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
goruby.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
goruby.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
@@ -8536,7 +8584,6 @@ loadpath.$(OBJEXT): {$(VPATH)}internal/warning_push.h
loadpath.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
loadpath.$(OBJEXT): {$(VPATH)}loadpath.c
loadpath.$(OBJEXT): {$(VPATH)}missing.h
-loadpath.$(OBJEXT): {$(VPATH)}revision.h
loadpath.$(OBJEXT): {$(VPATH)}st.h
loadpath.$(OBJEXT): {$(VPATH)}subst.h
loadpath.$(OBJEXT): {$(VPATH)}verconf.h
@@ -8871,8 +8918,13 @@ main.$(OBJEXT): {$(VPATH)}missing.h
main.$(OBJEXT): {$(VPATH)}st.h
main.$(OBJEXT): {$(VPATH)}subst.h
main.$(OBJEXT): {$(VPATH)}vm_debug.h
+marshal.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+marshal.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+marshal.$(OBJEXT): $(CCAN_DIR)/list/list.h
+marshal.$(OBJEXT): $(CCAN_DIR)/str/str.h
marshal.$(OBJEXT): $(hdrdir)/ruby/ruby.h
marshal.$(OBJEXT): $(top_srcdir)/internal/array.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
marshal.$(OBJEXT): $(top_srcdir)/internal/bignum.h
marshal.$(OBJEXT): $(top_srcdir)/internal/bits.h
marshal.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -8882,6 +8934,7 @@ marshal.$(OBJEXT): $(top_srcdir)/internal/error.h
marshal.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
marshal.$(OBJEXT): $(top_srcdir)/internal/gc.h
marshal.$(OBJEXT): $(top_srcdir)/internal/hash.h
+marshal.$(OBJEXT): $(top_srcdir)/internal/imemo.h
marshal.$(OBJEXT): $(top_srcdir)/internal/numeric.h
marshal.$(OBJEXT): $(top_srcdir)/internal/object.h
marshal.$(OBJEXT): $(top_srcdir)/internal/serial.h
@@ -8894,6 +8947,7 @@ marshal.$(OBJEXT): $(top_srcdir)/internal/variable.h
marshal.$(OBJEXT): $(top_srcdir)/internal/vm.h
marshal.$(OBJEXT): $(top_srcdir)/internal/warnings.h
marshal.$(OBJEXT): {$(VPATH)}assert.h
+marshal.$(OBJEXT): {$(VPATH)}atomic.h
marshal.$(OBJEXT): {$(VPATH)}backward/2/assume.h
marshal.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
marshal.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -8909,6 +8963,7 @@ marshal.$(OBJEXT): {$(VPATH)}constant.h
marshal.$(OBJEXT): {$(VPATH)}defines.h
marshal.$(OBJEXT): {$(VPATH)}encindex.h
marshal.$(OBJEXT): {$(VPATH)}encoding.h
+marshal.$(OBJEXT): {$(VPATH)}id.h
marshal.$(OBJEXT): {$(VPATH)}id_table.h
marshal.$(OBJEXT): {$(VPATH)}intern.h
marshal.$(OBJEXT): {$(VPATH)}internal.h
@@ -8949,6 +9004,7 @@ marshal.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
marshal.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
marshal.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
marshal.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+marshal.$(OBJEXT): {$(VPATH)}internal/attr/nonstring.h
marshal.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
marshal.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
marshal.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
@@ -9064,13 +9120,21 @@ marshal.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
marshal.$(OBJEXT): {$(VPATH)}io.h
marshal.$(OBJEXT): {$(VPATH)}marshal.c
marshal.$(OBJEXT): {$(VPATH)}marshal.rbinc
+marshal.$(OBJEXT): {$(VPATH)}method.h
marshal.$(OBJEXT): {$(VPATH)}missing.h
+marshal.$(OBJEXT): {$(VPATH)}node.h
marshal.$(OBJEXT): {$(VPATH)}onigmo.h
marshal.$(OBJEXT): {$(VPATH)}oniguruma.h
+marshal.$(OBJEXT): {$(VPATH)}ruby_assert.h
+marshal.$(OBJEXT): {$(VPATH)}ruby_atomic.h
marshal.$(OBJEXT): {$(VPATH)}shape.h
marshal.$(OBJEXT): {$(VPATH)}st.h
marshal.$(OBJEXT): {$(VPATH)}subst.h
+marshal.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+marshal.$(OBJEXT): {$(VPATH)}thread_native.h
marshal.$(OBJEXT): {$(VPATH)}util.h
+marshal.$(OBJEXT): {$(VPATH)}vm_core.h
+marshal.$(OBJEXT): {$(VPATH)}vm_opts.h
math.$(OBJEXT): $(hdrdir)/ruby/ruby.h
math.$(OBJEXT): $(top_srcdir)/internal/bignum.h
math.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -9495,6 +9559,7 @@ miniinit.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
miniinit.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
miniinit.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
miniinit.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+miniinit.$(OBJEXT): {$(VPATH)}internal/attr/nonstring.h
miniinit.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
miniinit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
miniinit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
@@ -10462,8 +10527,13 @@ numeric.$(OBJEXT): {$(VPATH)}shape.h
numeric.$(OBJEXT): {$(VPATH)}st.h
numeric.$(OBJEXT): {$(VPATH)}subst.h
numeric.$(OBJEXT): {$(VPATH)}util.h
+object.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
+object.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
+object.$(OBJEXT): $(CCAN_DIR)/list/list.h
+object.$(OBJEXT): $(CCAN_DIR)/str/str.h
object.$(OBJEXT): $(hdrdir)/ruby/ruby.h
object.$(OBJEXT): $(top_srcdir)/internal/array.h
+object.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
object.$(OBJEXT): $(top_srcdir)/internal/bignum.h
object.$(OBJEXT): $(top_srcdir)/internal/bits.h
object.$(OBJEXT): $(top_srcdir)/internal/class.h
@@ -10472,6 +10542,7 @@ object.$(OBJEXT): $(top_srcdir)/internal/error.h
object.$(OBJEXT): $(top_srcdir)/internal/eval.h
object.$(OBJEXT): $(top_srcdir)/internal/fixnum.h
object.$(OBJEXT): $(top_srcdir)/internal/gc.h
+object.$(OBJEXT): $(top_srcdir)/internal/imemo.h
object.$(OBJEXT): $(top_srcdir)/internal/inits.h
object.$(OBJEXT): $(top_srcdir)/internal/numeric.h
object.$(OBJEXT): $(top_srcdir)/internal/object.h
@@ -10484,6 +10555,7 @@ object.$(OBJEXT): $(top_srcdir)/internal/variable.h
object.$(OBJEXT): $(top_srcdir)/internal/vm.h
object.$(OBJEXT): $(top_srcdir)/internal/warnings.h
object.$(OBJEXT): {$(VPATH)}assert.h
+object.$(OBJEXT): {$(VPATH)}atomic.h
object.$(OBJEXT): {$(VPATH)}backward/2/assume.h
object.$(OBJEXT): {$(VPATH)}backward/2/attributes.h
object.$(OBJEXT): {$(VPATH)}backward/2/bool.h
@@ -10652,18 +10724,26 @@ object.$(OBJEXT): {$(VPATH)}internal/variable.h
object.$(OBJEXT): {$(VPATH)}internal/warning_push.h
object.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
object.$(OBJEXT): {$(VPATH)}kernel.rbinc
+object.$(OBJEXT): {$(VPATH)}method.h
object.$(OBJEXT): {$(VPATH)}missing.h
object.$(OBJEXT): {$(VPATH)}nilclass.rbinc
+object.$(OBJEXT): {$(VPATH)}node.h
object.$(OBJEXT): {$(VPATH)}object.c
object.$(OBJEXT): {$(VPATH)}onigmo.h
object.$(OBJEXT): {$(VPATH)}oniguruma.h
object.$(OBJEXT): {$(VPATH)}probes.dmyh
object.$(OBJEXT): {$(VPATH)}probes.h
+object.$(OBJEXT): {$(VPATH)}ruby_assert.h
+object.$(OBJEXT): {$(VPATH)}ruby_atomic.h
object.$(OBJEXT): {$(VPATH)}shape.h
object.$(OBJEXT): {$(VPATH)}st.h
object.$(OBJEXT): {$(VPATH)}subst.h
+object.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h
+object.$(OBJEXT): {$(VPATH)}thread_native.h
object.$(OBJEXT): {$(VPATH)}util.h
object.$(OBJEXT): {$(VPATH)}variable.h
+object.$(OBJEXT): {$(VPATH)}vm_core.h
+object.$(OBJEXT): {$(VPATH)}vm_opts.h
pack.$(OBJEXT): $(hdrdir)/ruby/ruby.h
pack.$(OBJEXT): $(top_srcdir)/internal/array.h
pack.$(OBJEXT): $(top_srcdir)/internal/bits.h
@@ -11077,6 +11157,7 @@ proc.$(OBJEXT): $(top_srcdir)/internal/compilers.h
proc.$(OBJEXT): $(top_srcdir)/internal/error.h
proc.$(OBJEXT): $(top_srcdir)/internal/eval.h
proc.$(OBJEXT): $(top_srcdir)/internal/gc.h
+proc.$(OBJEXT): $(top_srcdir)/internal/hash.h
proc.$(OBJEXT): $(top_srcdir)/internal/imemo.h
proc.$(OBJEXT): $(top_srcdir)/internal/object.h
proc.$(OBJEXT): $(top_srcdir)/internal/proc.h
@@ -11500,6 +11581,7 @@ ractor.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h
ractor.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h
ractor.$(OBJEXT): $(CCAN_DIR)/list/list.h
ractor.$(OBJEXT): $(CCAN_DIR)/str/str.h
+ractor.$(OBJEXT): $(hdrdir)/ruby.h
ractor.$(OBJEXT): $(hdrdir)/ruby/ruby.h
ractor.$(OBJEXT): $(top_srcdir)/internal/array.h
ractor.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h
@@ -11695,6 +11777,7 @@ ractor.$(OBJEXT): {$(VPATH)}internal/warning_push.h
ractor.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
ractor.$(OBJEXT): {$(VPATH)}method.h
ractor.$(OBJEXT): {$(VPATH)}missing.h
+ractor.$(OBJEXT): {$(VPATH)}mjit.h
ractor.$(OBJEXT): {$(VPATH)}node.h
ractor.$(OBJEXT): {$(VPATH)}onigmo.h
ractor.$(OBJEXT): {$(VPATH)}oniguruma.h
@@ -14324,6 +14407,7 @@ signal.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
signal.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
signal.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
signal.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+signal.$(OBJEXT): {$(VPATH)}internal/attr/nonstring.h
signal.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
signal.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
signal.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
@@ -14814,6 +14898,7 @@ st.$(OBJEXT): {$(VPATH)}internal/variable.h
st.$(OBJEXT): {$(VPATH)}internal/warning_push.h
st.$(OBJEXT): {$(VPATH)}internal/xmalloc.h
st.$(OBJEXT): {$(VPATH)}missing.h
+st.$(OBJEXT): {$(VPATH)}ruby_assert.h
st.$(OBJEXT): {$(VPATH)}st.c
st.$(OBJEXT): {$(VPATH)}st.h
st.$(OBJEXT): {$(VPATH)}subst.h
@@ -15079,6 +15164,7 @@ string.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
string.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
string.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
string.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+string.$(OBJEXT): {$(VPATH)}internal/attr/nonstring.h
string.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
string.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
string.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
@@ -15520,6 +15606,7 @@ symbol.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h
symbol.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h
symbol.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h
symbol.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h
+symbol.$(OBJEXT): {$(VPATH)}internal/attr/nonstring.h
symbol.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h
symbol.$(OBJEXT): {$(VPATH)}internal/attr/pure.h
symbol.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h
diff --git a/compile.c b/compile.c
index f252339ee5..0452305923 100644
--- a/compile.c
+++ b/compile.c
@@ -1243,6 +1243,32 @@ new_adjust_body(rb_iseq_t *iseq, LABEL *label, int line)
return adjust;
}
+static void
+iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE *, VALUE), VALUE data)
+{
+ const char *types = insn_op_types(insn->insn_id);
+ for (int j = 0; types[j]; j++) {
+ char type = types[j];
+ switch (type) {
+ case TS_CDHASH:
+ case TS_ISEQ:
+ case TS_VALUE:
+ case TS_IC: // constant path array
+ case TS_CALLDATA: // ci is stored.
+ func(&OPERAND_AT(insn, j), data);
+ break;
+ default:
+ break;
+ }
+ }
+}
+
+static void
+iseq_insn_each_object_write_barrier(VALUE *obj_ptr, VALUE iseq)
+{
+ RB_OBJ_WRITTEN(iseq, Qundef, *obj_ptr);
+}
+
static INSN *
new_insn_core(rb_iseq_t *iseq, const NODE *line_node,
int insn_id, int argc, VALUE *argv)
@@ -1260,6 +1286,9 @@ new_insn_core(rb_iseq_t *iseq, const NODE *line_node,
iobj->operands = argv;
iobj->operand_size = argc;
iobj->sc_state = 0;
+
+ iseq_insn_each_markable_object(iobj, iseq_insn_each_object_write_barrier, (VALUE)iseq);
+
return iobj;
}
@@ -2631,9 +2660,11 @@ iseq_set_exception_table(rb_iseq_t *iseq)
struct iseq_catch_table_entry *entry;
ISEQ_BODY(iseq)->catch_table = NULL;
- if (NIL_P(ISEQ_COMPILE_DATA(iseq)->catch_table_ary)) return COMPILE_OK;
- tlen = (int)RARRAY_LEN(ISEQ_COMPILE_DATA(iseq)->catch_table_ary);
- tptr = RARRAY_CONST_PTR_TRANSIENT(ISEQ_COMPILE_DATA(iseq)->catch_table_ary);
+
+ VALUE catch_table_ary = ISEQ_COMPILE_DATA(iseq)->catch_table_ary;
+ if (NIL_P(catch_table_ary)) return COMPILE_OK;
+ tlen = (int)RARRAY_LEN(catch_table_ary);
+ tptr = RARRAY_CONST_PTR_TRANSIENT(catch_table_ary);
if (tlen > 0) {
struct iseq_catch_table *table = xmalloc(iseq_catch_table_bytes(tlen));
@@ -2669,6 +2700,8 @@ iseq_set_exception_table(rb_iseq_t *iseq)
RB_OBJ_WRITE(iseq, &ISEQ_COMPILE_DATA(iseq)->catch_table_ary, 0); /* free */
}
+ RB_GC_GUARD(catch_table_ary);
+
return COMPILE_OK;
}
@@ -2807,7 +2840,6 @@ remove_unreachable_chunk(rb_iseq_t *iseq, LINK_ELEMENT *i)
break;
}
else if ((lab = find_destination((INSN *)i)) != 0) {
- if (lab->unremovable) break;
unref_counts[lab->label_no]++;
}
}
@@ -2824,8 +2856,7 @@ remove_unreachable_chunk(rb_iseq_t *iseq, LINK_ELEMENT *i)
/* do nothing */
}
else if (IS_ADJUST(i)) {
- LABEL *dest = ((ADJUST *)i)->label;
- if (dest && dest->unremovable) return 0;
+ return 0;
}
end = i;
} while ((i = i->next) != 0);
@@ -4589,7 +4620,12 @@ compile_array_1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node)
}
else {
CHECK(COMPILE_(ret, "array element", node, FALSE));
- ADD_INSN1(ret, node, newarray, INT2FIX(1));
+ if (keyword_node_p(node)) {
+ ADD_INSN1(ret, node, newarraykwsplat, INT2FIX(1));
+ }
+ else {
+ ADD_INSN1(ret, node, newarray, INT2FIX(1));
+ }
}
return 1;
@@ -5040,12 +5076,17 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const
CHECK(COMPILE_POPPED(pre, "masgn lhs (NODE_ATTRASGN)", node));
+ bool safenav_call = false;
LINK_ELEMENT *insn_element = LAST_ELEMENT(pre);
iobj = (INSN *)get_prev_insn((INSN *)insn_element); /* send insn */
ASSUME(iobj);
- ELEM_REMOVE(LAST_ELEMENT(pre));
- ELEM_REMOVE((LINK_ELEMENT *)iobj);
- pre->last = iobj->link.prev;
+ ELEM_REMOVE(insn_element);
+ if (!IS_INSN_ID(iobj, send)) {
+ safenav_call = true;
+ iobj = (INSN *)get_prev_insn(iobj);
+ ELEM_INSERT_NEXT(&iobj->link, insn_element);
+ }
+ (pre->last = iobj->link.prev)->next = 0;
const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(iobj, 0);
int argc = vm_ci_argc(ci) + 1;
@@ -5064,7 +5105,9 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const
return COMPILE_NG;
}
- ADD_ELEM(lhs, (LINK_ELEMENT *)iobj);
+ iobj->link.prev = lhs->last;
+ lhs->last->next = &iobj->link;
+ for (lhs->last = &iobj->link; lhs->last->next; lhs->last = lhs->last->next);
if (vm_ci_flag(ci) & VM_CALL_ARGS_SPLAT) {
int argc = vm_ci_argc(ci);
ci = ci_argc_set(iseq, ci, argc - 1);
@@ -5073,9 +5116,11 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const
INSERT_BEFORE_INSN1(iobj, line_node, newarray, INT2FIX(1));
INSERT_BEFORE_INSN(iobj, line_node, concatarray);
}
- ADD_INSN(lhs, line_node, pop);
- if (argc != 1) {
+ if (!safenav_call) {
ADD_INSN(lhs, line_node, pop);
+ if (argc != 1) {
+ ADD_INSN(lhs, line_node, pop);
+ }
}
for (int i=0; i < argc; i++) {
ADD_INSN(post, line_node, pop);
@@ -7612,7 +7657,6 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in
add_ensure_iseq(ret, iseq, 0);
ADD_INSNL(ret, line_node, jump, ISEQ_COMPILE_DATA(iseq)->end_label);
ADD_ADJUST_RESTORE(ret, splabel);
- splabel->unremovable = FALSE;
if (!popped) {
ADD_INSN(ret, line_node, putnil);
@@ -9277,7 +9321,8 @@ compile_attrasgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node
/* optimization shortcut
* obj["literal"] = value -> opt_aset_with(obj, "literal", value)
*/
- if (mid == idASET && !private_recv_p(node) && node->nd_args &&
+ if (!ISEQ_COMPILE_DATA(iseq)->in_masgn &&
+ mid == idASET && !private_recv_p(node) && node->nd_args &&
nd_type_p(node->nd_args, NODE_LIST) && node->nd_args->nd_alen == 2 &&
nd_type_p(node->nd_args->nd_head, NODE_STR) &&
ISEQ_COMPILE_DATA(iseq)->current_block == NULL &&
@@ -9475,7 +9520,10 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
}
case NODE_MASGN:{
+ bool prev_in_masgn = ISEQ_COMPILE_DATA(iseq)->in_masgn;
+ ISEQ_COMPILE_DATA(iseq)->in_masgn = true;
compile_massign(iseq, ret, node, popped);
+ ISEQ_COMPILE_DATA(iseq)->in_masgn = prev_in_masgn;
break;
}
@@ -9717,7 +9765,12 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no
case NODE_LIT:{
debugp_param("lit", node->nd_lit);
if (!popped) {
- ADD_INSN1(ret, node, putobject, node->nd_lit);
+ if (UNLIKELY(node->nd_lit == rb_mRubyVMFrozenCore)) {
+ ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); // [Bug #20569]
+ }
+ else {
+ ADD_INSN1(ret, node, putobject, node->nd_lit);
+ }
RB_OBJ_WRITTEN(iseq, Qundef, node->nd_lit);
}
break;
@@ -10735,6 +10788,12 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords)
return keyword;
}
+static void
+iseq_insn_each_object_mark(VALUE *obj_ptr, VALUE _)
+{
+ rb_gc_mark(*obj_ptr);
+}
+
void
rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *storage)
{
@@ -10761,29 +10820,7 @@ rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *storage)
iobj = (INSN *)&storage->buff[pos];
if (iobj->operands) {
- int j;
- const char *types = insn_op_types(iobj->insn_id);
-
- for (j = 0; types[j]; j++) {
- char type = types[j];
- switch (type) {
- case TS_CDHASH:
- case TS_ISEQ:
- case TS_VALUE:
- case TS_IC: // constant path array
- case TS_CALLDATA: // ci is stored.
- {
- VALUE op = OPERAND_AT(iobj, j);
-
- if (!SPECIAL_CONST_P(op)) {
- rb_gc_mark(op);
- }
- }
- break;
- default:
- break;
- }
- }
+ iseq_insn_each_markable_object(iobj, iseq_insn_each_object_mark, (VALUE)0);
}
pos += (int)size;
}
@@ -12311,7 +12348,7 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset)
verify_call_cache(iseq);
RB_GC_GUARD(dummy_frame);
- rb_vm_pop_frame(ec);
+ rb_vm_pop_frame_no_int(ec);
}
struct ibf_dump_iseq_list_arg
@@ -13062,7 +13099,7 @@ ibf_dump_memsize(const void *ptr)
static const rb_data_type_t ibf_dump_type = {
"ibf_dump",
{ibf_dump_mark, ibf_dump_free, ibf_dump_memsize,},
- 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY
+ 0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
static void
diff --git a/complex.c b/complex.c
index 57962f9013..a227cb0a58 100644
--- a/complex.c
+++ b/complex.c
@@ -2116,8 +2116,11 @@ nucomp_convert(VALUE klass, VALUE a1, VALUE a2, int raise)
return a1;
/* should raise exception for consistency */
if (!k_numeric_p(a1)) {
- if (!raise)
- return rb_protect(to_complex, a1, NULL);
+ if (!raise) {
+ a1 = rb_protect(to_complex, a1, NULL);
+ rb_set_errinfo(Qnil);
+ return a1;
+ }
return to_complex(a1);
}
}
diff --git a/configure.ac b/configure.ac
index ce47ab7b16..220392d120 100644
--- a/configure.ac
+++ b/configure.ac
@@ -214,15 +214,23 @@ AS_CASE(["/${rb_CC} "],
[*clang*], [
# Ditto for LLVM. Note however that llvm-as is a LLVM-IR to LLVM bitcode
# assembler that does not target your machine native binary.
- : ${LD:="${CC}"} # ... try -fuse-ld=lld ?
- RUBY_CHECK_PROG_FOR_CC([AR], [s/clang/llvm-ar/])
-# RUBY_CHECK_PROG_FOR_CC([AS], [s/clang/llvm-as/])
+
+ # Xcode has its own version tools that may be incompatible with
+ # genuine LLVM tools, use the tools in the same directory.
+
+ AS_IF([$rb_CC -E -dM -xc - < /dev/null | grep -F __apple_build_version__ > /dev/null],
+ [llvm_prefix=], [llvm_prefix=llvm-])
+ # AC_PREPROC_IFELSE cannot be used before AC_USE_SYSTEM_EXTENSIONS
+
+ RUBY_CHECK_PROG_FOR_CC([LD], [s/clang/ld/]) # ... maybe try lld ?
+ RUBY_CHECK_PROG_FOR_CC([AR], [s/clang/${llvm_prefix}ar/])
+# RUBY_CHECK_PROG_FOR_CC([AS], [s/clang/${llvm_prefix}as/])
RUBY_CHECK_PROG_FOR_CC([CXX], [s/clang/clang++/])
- RUBY_CHECK_PROG_FOR_CC([NM], [s/clang/llvm-nm/])
- RUBY_CHECK_PROG_FOR_CC([OBJCOPY], [s/clang/llvm-objcopy/])
- RUBY_CHECK_PROG_FOR_CC([OBJDUMP], [s/clang/llvm-objdump/])
- RUBY_CHECK_PROG_FOR_CC([RANLIB], [s/clang/llvm-ranlib/])
- RUBY_CHECK_PROG_FOR_CC([STRIP], [s/clang/llvm-strip/])
+ RUBY_CHECK_PROG_FOR_CC([NM], [s/clang/${llvm_prefix}nm/])
+ RUBY_CHECK_PROG_FOR_CC([OBJCOPY], [s/clang/${llvm_prefix}objcopy/])
+ RUBY_CHECK_PROG_FOR_CC([OBJDUMP], [s/clang/${llvm_prefix}objdump/])
+ RUBY_CHECK_PROG_FOR_CC([RANLIB], [s/clang/${llvm_prefix}ranlib/])
+ RUBY_CHECK_PROG_FOR_CC([STRIP], [s/clang/${llvm_prefix}strip/])
])
AS_UNSET(rb_CC)
AS_UNSET(rb_dummy)
@@ -366,12 +374,6 @@ AS_CASE(["$target_os"],
[AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)
AC_MSG_ERROR([Unsupported OS X version is required])])
- AC_CACHE_CHECK([if thread-local storage is supported], [rb_cv_tls_supported],
- [AC_LINK_IFELSE([AC_LANG_PROGRAM([[int __thread conftest;]])],
- [rb_cv_tls_supported=yes],
- [rb_cv_tls_supported=no])])
- AS_IF([test x"$rb_cv_tls_supported" != xyes],
- [AC_DEFINE(RB_THREAD_LOCAL_SPECIFIER_IS_UNSUPPORTED)])
])
RUBY_MINGW32
@@ -391,6 +393,13 @@ AS_IF([test "$GCC" = yes], [
AS_IF([test "$gcc_major" -lt 4], [
AC_MSG_ERROR([too old GCC: $gcc_major.$gcc_minor])
])
+
+ AC_CACHE_CHECK([if thread-local storage is supported], [rb_cv_tls_supported],
+ [AC_LINK_IFELSE([AC_LANG_PROGRAM([[int __thread conftest;]])],
+ [rb_cv_tls_supported=yes],
+ [rb_cv_tls_supported=no])])
+ AS_IF([test x"$rb_cv_tls_supported" != xyes],
+ [AC_DEFINE(RB_THREAD_LOCAL_SPECIFIER_IS_UNSUPPORTED)])
], [
linker_flag=
])
@@ -524,7 +533,9 @@ AS_IF([test "$cross_compiling:$ac_cv_prog_DTRACE" = no: -a -n "$ac_tool_prefix"]
AC_CHECK_PROGS(DOT, dot)
AC_CHECK_PROGS(DOXYGEN, doxygen)
+tool_warned=$ac_tool_warned ac_tool_warned=no
AC_CHECK_TOOL(PKG_CONFIG, pkg-config)
+ac_tool_warned=$tool_warned
AS_IF([test -z "$PKG_CONFIG"], [],
["$PKG_CONFIG" --print-errors --version > /dev/null 2>&1], [],
[
@@ -964,9 +975,10 @@ AS_IF([test "x$OPT_DIR" != x], [
LDFLAGS="${LDFLAGS:+$LDFLAGS }$val"
DLDFLAGS="${DLDFLAGS:+$DLDFLAGS }$val"
LDFLAGS_OPTDIR="$val"
- CPPFLAGS="${CPPFLAGS:+$CPPFLAGS }"`echo "$OPT_DIR" | tr "${PATH_SEPARATOR}" '\012' |
+ INCFLAGS="${INCFLAGS:+$INCFLAGS }"`echo "$OPT_DIR" | tr "${PATH_SEPARATOR}" '\012' |
sed '/^$/d;s|^|-I|;s|$|/include|' | tr '\012' ' ' | sed 's/ *$//'`
])
+AC_SUBST(incflags, "$INCFLAGS")
test -z "${ac_env_CFLAGS_set}" -a -n "${cflags+set}" && eval CFLAGS="\"$cflags $ARCH_FLAG\""
test -z "${ac_env_CXXFLAGS_set}" -a -n "${cxxflags+set}" && eval CXXFLAGS="\"$cxxflags $ARCH_FLAG\""
@@ -1191,8 +1203,6 @@ main()
ac_cv_func_gmtime_r=yes
rb_cv_large_fd_select=yes
ac_cv_type_struct_timeval=yes
- ac_cv_func_clock_gettime=yes
- ac_cv_func_clock_getres=yes
ac_cv_func_malloc_usable_size=no
ac_cv_type_off_t=yes
ac_cv_sizeof_off_t=8
@@ -1338,6 +1348,8 @@ AC_CHECK_HEADERS(syscall.h)
AC_CHECK_HEADERS(time.h)
AC_CHECK_HEADERS(ucontext.h)
AC_CHECK_HEADERS(utime.h)
+AC_CHECK_HEADERS(stdatomic.h)
+
AS_CASE("$target_cpu", [x64|x86_64|i[3-6]86*], [
AC_CHECK_HEADERS(x86intrin.h)
])
@@ -1354,6 +1366,8 @@ AC_ARG_WITH([jemalloc],
[with_jemalloc=$withval], [with_jemalloc=no])
AS_IF([test "x$with_jemalloc" != xno],[
# find jemalloc header first
+ save_CPPFLAGS="${CPPFLAGS}"
+ CPPFLAGS="${INCFLAGS} ${CPPFLAGS}"
malloc_header=
AC_CHECK_HEADER(jemalloc/jemalloc.h, [malloc_header=jemalloc/jemalloc.h], [
AC_CHECK_HEADER(jemalloc.h, [malloc_header=jemalloc.h])
@@ -1385,6 +1399,8 @@ AS_IF([test "x$with_jemalloc" != xno],[
done
done
])
+ CPPFLAGS="${save_CPPFLAGS}"
+ unset save_CPPFLAGS
with_jemalloc=${rb_cv_jemalloc_library}
AS_CASE(["$with_jemalloc"],
[no],
@@ -1995,6 +2011,7 @@ AC_CHECK_FUNCS(_longjmp) # used for AC_ARG_WITH(setjmp-type)
test x$ac_cv_func__longjmp = xno && ac_cv_func__setjmp=no
AC_CHECK_FUNCS(arc4random_buf)
AC_CHECK_FUNCS(atan2l atan2f)
+AC_CHECK_DECLS(atomic_signal_fence, [], [], [#include <stdatomic.h>])
AC_CHECK_FUNCS(chmod)
AC_CHECK_FUNCS(chown)
AC_CHECK_FUNCS(chroot)
@@ -3049,7 +3066,7 @@ AC_SUBST(EXTOBJS)
[darwin*], [ : ${LDSHARED='$(CC) -dynamic -bundle'}
: ${DLDSHARED='$(CC) -dynamiclib'}
: ${LDFLAGS=""}
- : ${LIBPATHENV=DYLD_FALLBACK_LIBRARY_PATH}
+ : ${LIBPATHENV=DYLD_LIBRARY_PATH}
: ${PRELOADENV=DYLD_INSERT_LIBRARIES}
AS_IF([test x"$enable_shared" = xyes], [
# Resolve symbols from libruby.dylib when --enable-shared
@@ -3352,6 +3369,10 @@ AS_IF([test x"$cross_compiling" = xyes], [
AC_SUBST(XRUBY_RUBYLIBDIR)
AC_SUBST(XRUBY_RUBYHDRDIR)
PREP='$(arch)-fake.rb'
+ AS_CASE(["$enable_shared:$EXTSTATIC:$target_os"], [no::darwin*], [
+ # darwin target requires miniruby for linking ext bundles
+ PREP="$PREP"' miniruby$(EXEEXT)'
+ ])
RUNRUBY_COMMAND='$(MINIRUBY) -I`cd $(srcdir)/lib; pwd`'
RUNRUBY='$(RUNRUBY_COMMAND)'
XRUBY='$(MINIRUBY)'
@@ -3785,7 +3806,7 @@ AS_IF([test "$cross_compiling" = no],
dnl build YJIT in release mode if rustc >= 1.58.0 is present and we are on a supported platform
AC_ARG_ENABLE(yjit,
AS_HELP_STRING([--enable-yjit],
- [enable in-process JIT compiler that requires Rust build tools [default=no]]),
+ [enable in-process JIT compiler that requires Rust build tools. enabled by default on supported platforms if rustc 1.58.0+ is available]),
[YJIT_SUPPORT=$enableval],
[AS_CASE(["$enable_jit_support:$YJIT_TARGET_OK:$YJIT_RUSTC_OK"],
[yes:yes:yes|:yes:yes], [
diff --git a/cont.c b/cont.c
index 49629efd90..5375d1945b 100644
--- a/cont.c
+++ b/cont.c
@@ -29,6 +29,7 @@ extern int madvise(caddr_t, size_t, int);
#include "gc.h"
#include "internal.h"
#include "internal/cont.h"
+#include "internal/error.h"
#include "internal/proc.h"
#include "internal/sanitizers.h"
#include "internal/warnings.h"
@@ -1254,6 +1255,8 @@ jit_cont_new(rb_execution_context_t *ec)
static void
jit_cont_free(struct rb_jit_cont *cont)
{
+ if (!cont) return;
+
rb_native_mutex_lock(&jit_cont_lock);
if (cont == first_jit_cont) {
first_jit_cont = cont->next;
@@ -1578,7 +1581,7 @@ cont_restore_1(rb_context_t *cont)
cont_restore_thread(cont);
/* restore machine stack */
-#ifdef _M_AMD64
+#if defined(_M_AMD64) && !defined(__MINGW64__)
{
/* workaround for x64 SEH */
jmp_buf buf;
@@ -1958,7 +1961,7 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval)
* the current thread, blocking and non-blocking fibers' behavior is identical.
*
* Ruby doesn't provide a scheduler class: it is expected to be implemented by
- * the user and correspond to Fiber::SchedulerInterface.
+ * the user and correspond to Fiber::Scheduler.
*
* There is also Fiber.schedule method, which is expected to immediately perform
* the given block in a non-blocking manner. Its actual implementation is up to
@@ -2068,21 +2071,33 @@ fiber_storage_get(rb_fiber_t *fiber)
return storage;
}
+static void
+storage_access_must_be_from_same_fiber(VALUE self)
+{
+ rb_fiber_t *fiber = fiber_ptr(self);
+ rb_fiber_t *current = fiber_current();
+ if (fiber != current) {
+ rb_raise(rb_eArgError, "Fiber storage can only be accessed from the Fiber it belongs to");
+ }
+}
+
/**
- * call-seq: Fiber.current.storage -> hash (dup)
+ * call-seq: fiber.storage -> hash (dup)
*
- * Returns a copy of the storage hash for the current fiber.
+ * Returns a copy of the storage hash for the fiber. The method can only be called on the
+ * Fiber.current.
*/
static VALUE
rb_fiber_storage_get(VALUE self)
{
+ storage_access_must_be_from_same_fiber(self);
return rb_obj_dup(fiber_storage_get(fiber_ptr(self)));
}
static int
fiber_storage_validate_each(VALUE key, VALUE value, VALUE _argument)
{
- rb_check_id(&key);
+ Check_Type(key, T_SYMBOL);
return ST_CONTINUE;
}
@@ -2105,16 +2120,17 @@ fiber_storage_validate(VALUE value)
}
/**
- * call-seq: Fiber.current.storage = hash
+ * call-seq: fiber.storage = hash
*
- * Sets the storage hash for the current fiber. This feature is experimental
- * and may change in the future.
+ * Sets the storage hash for the fiber. This feature is experimental
+ * and may change in the future. The method can only be called on the
+ * Fiber.current.
*
* You should be careful about using this method as you may inadvertently clear
* important fiber-storage state. You should mostly prefer to assign specific
- * keys in the storage using Fiber#[]=.
+ * keys in the storage using Fiber::[]=.
*
- * You can also use Fiber.new(storage: nil) to create a fiber with an empty
+ * You can also use <tt>Fiber.new(storage: nil)</tt> to create a fiber with an empty
* storage.
*
* Example:
@@ -2128,6 +2144,12 @@ fiber_storage_validate(VALUE value)
static VALUE
rb_fiber_storage_set(VALUE self, VALUE value)
{
+ if (rb_warning_category_enabled_p(RB_WARN_CATEGORY_EXPERIMENTAL)) {
+ rb_category_warn(RB_WARN_CATEGORY_EXPERIMENTAL,
+ "Fiber#storage= is experimental and may be removed in the future!");
+ }
+
+ storage_access_must_be_from_same_fiber(self);
fiber_storage_validate(value);
fiber_ptr(self)->cont.saved_ec.storage = rb_obj_dup(value);
@@ -2137,18 +2159,17 @@ rb_fiber_storage_set(VALUE self, VALUE value)
/**
* call-seq: Fiber[key] -> value
*
- * Returns the value of the fiber-local variable identified by +key+.
+ * Returns the value of the fiber storage variable identified by +key+.
*
* The +key+ must be a symbol, and the value is set by Fiber#[]= or
* Fiber#store.
*
- * See also Fiber[]=.
+ * See also Fiber::[]=.
*/
static VALUE
rb_fiber_storage_aref(VALUE class, VALUE key)
{
- ID id = rb_check_id(&key);
- if (!id) return Qnil;
+ Check_Type(key, T_SYMBOL);
VALUE storage = fiber_storage_get(fiber_current());
@@ -2160,18 +2181,17 @@ rb_fiber_storage_aref(VALUE class, VALUE key)
/**
* call-seq: Fiber[key] = value
*
- * Assign +value+ to the fiber-local variable identified by +key+.
+ * Assign +value+ to the fiber storage variable identified by +key+.
* The variable is created if it doesn't exist.
*
* +key+ must be a Symbol, otherwise a TypeError is raised.
*
- * See also Fiber[].
+ * See also Fiber::[].
*/
static VALUE
rb_fiber_storage_aset(VALUE class, VALUE key, VALUE value)
{
- ID id = rb_check_id(&key);
- if (!id) return Qnil;
+ Check_Type(key, T_SYMBOL);
VALUE storage = fiber_storage_get(fiber_current());
@@ -2185,9 +2205,6 @@ fiber_initialize(VALUE self, VALUE proc, struct fiber_pool * fiber_pool, unsigne
// The default, inherit storage (dup) from the current fiber:
storage = inherit_fiber_storage();
}
- else if (storage == Qfalse) {
- storage = current_fiber_storage();
- }
else /* nil, hash, etc. */ {
fiber_storage_validate(storage);
storage = rb_obj_dup(storage);
@@ -2299,18 +2316,6 @@ rb_fiber_initialize_kw(int argc, VALUE* argv, VALUE self, int kw_splat)
* end.resume
* Fiber[:x] # => 1
*
- * If the <tt>storage</tt> is <tt>false</tt>, this function uses the current
- * fiber's storage by reference. This is used for Enumerator to create
- * hidden fiber.
- *
- * Fiber[:count] = 0
- * enumerator = Enumerator.new do |y|
- * loop{y << (Fiber[:count] += 1)}
- * end
- * Fiber[:count] # => 0
- * enumerator.next # => 1
- * Fiber[:count] # => 1
- *
* If the given <tt>storage</tt> is <tt>nil</tt>, this function will lazy
* initialize the internal storage, which starts as an empty hash.
*
@@ -2322,7 +2327,7 @@ rb_fiber_initialize_kw(int argc, VALUE* argv, VALUE self, int kw_splat)
* Otherwise, the given <tt>storage</tt> is used as the new fiber's storage,
* and it must be an instance of Hash.
*
- * Explicitly using `storage: true/false` is currently experimental and may
+ * Explicitly using <tt>storage: true</tt> is currently experimental and may
* change in the future.
*/
static VALUE
@@ -2334,7 +2339,7 @@ rb_fiber_initialize(int argc, VALUE* argv, VALUE self)
VALUE
rb_fiber_new_storage(rb_block_call_func_t func, VALUE obj, VALUE storage)
{
- return fiber_initialize(fiber_alloc(rb_cFiber), rb_proc_new(func, obj), rb_fiber_pool_default(Qnil), 1, storage);
+ return fiber_initialize(fiber_alloc(rb_cFiber), rb_proc_new(func, obj), rb_fiber_pool_default(Qnil), 0, storage);
}
VALUE
@@ -2394,7 +2399,7 @@ rb_fiber_s_schedule_kw(int argc, VALUE* argv, int kw_splat)
*
* Note that the behavior described above is how the method is <em>expected</em>
* to behave, actual behavior is up to the current scheduler's implementation of
- * Fiber::SchedulerInterface#fiber method. Ruby doesn't enforce this method to
+ * Fiber::Scheduler#fiber method. Ruby doesn't enforce this method to
* behave in any particular way.
*
* If the scheduler is not set, the method raises
@@ -2413,7 +2418,7 @@ rb_fiber_s_schedule(int argc, VALUE *argv, VALUE obj)
*
* Returns the Fiber scheduler, that was last set for the current thread with Fiber.set_scheduler.
* Returns +nil+ if no scheduler is set (which is the default), and non-blocking fibers'
- # behavior is the same as blocking.
+ * behavior is the same as blocking.
* (see "Non-blocking fibers" section in class docs for details about the scheduler concept).
*
*/
@@ -2447,7 +2452,7 @@ rb_fiber_current_scheduler(VALUE klass)
* thread will call scheduler's +close+ method on finalization (allowing the scheduler to
* properly manage all non-finished fibers).
*
- * +scheduler+ can be an object of any class corresponding to Fiber::SchedulerInterface. Its
+ * +scheduler+ can be an object of any class corresponding to Fiber::Scheduler. Its
* implementation is up to the user.
*
* See also the "Non-blocking fibers" section in class docs.
@@ -2794,7 +2799,8 @@ rb_fiber_blocking(VALUE class)
// If we are already blocking, this is essentially a no-op:
if (fiber->blocking) {
return rb_yield(fiber_value);
- } else {
+ }
+ else {
return rb_ensure(fiber_blocking_yield, fiber_value, fiber_blocking_ensure, fiber_value);
}
}
diff --git a/coroutine/asyncify/Context.h b/coroutine/asyncify/Context.h
index 7dba829a1d..71791a4004 100644
--- a/coroutine/asyncify/Context.h
+++ b/coroutine/asyncify/Context.h
@@ -13,6 +13,7 @@
#include <stddef.h>
#include <stdio.h>
+#include <stdint.h>
#include "wasm/asyncify.h"
#include "wasm/machine.h"
#include "wasm/fiber.h"
@@ -47,10 +48,13 @@ static inline void coroutine_initialize_main(struct coroutine_context * context)
static inline void coroutine_initialize(struct coroutine_context *context, coroutine_start start, void *stack, size_t size)
{
- if (ASYNCIFY_CORO_DEBUG) fprintf(stderr, "[%s] entry (context = %p, stack = %p ... %p)\n", __func__, context, stack, (char *)stack + size);
+ // Linear stack pointer must be always aligned down to 16 bytes.
+ // https://github.com/WebAssembly/tool-conventions/blob/c74267a5897c1bdc9aa60adeaf41816387d3cd12/BasicCABI.md#the-linear-stack
+ uintptr_t sp = ((uintptr_t)stack + size) & ~0xF;
+ if (ASYNCIFY_CORO_DEBUG) fprintf(stderr, "[%s] entry (context = %p, stack = %p ... %p)\n", __func__, context, stack, (char *)sp);
rb_wasm_init_context(&context->fc, coroutine_trampoline, start, context);
// record the initial stack pointer position to restore it after resumption
- context->current_sp = (char *)stack + size;
+ context->current_sp = (char *)sp;
context->stack_base = stack;
context->size = size;
}
diff --git a/cygwin/GNUmakefile.in b/cygwin/GNUmakefile.in
index 43e92a27f0..f342d2fcf7 100644
--- a/cygwin/GNUmakefile.in
+++ b/cygwin/GNUmakefile.in
@@ -2,6 +2,9 @@ gnumake = yes
include Makefile
+MUNICODE_FLAG := $(if $(filter mingw%,$(target_os)),-municode)
+override EXE_LDFLAGS += $(MUNICODE_FLAG)
+
DLLWRAP = @DLLWRAP@ --target=$(target_os) --driver-name="$(CC)"
windres-cpp := $(CPP) -xc
windres-cpp := --preprocessor=$(firstword $(windres-cpp)) \
@@ -63,7 +66,7 @@ $(PROGRAM): $(RUBY_INSTALL_NAME).res.$(OBJEXT)
$(WPROGRAM): $(RUBYW_INSTALL_NAME).res.$(OBJEXT)
@rm -f $@
$(ECHO) linking $@
- $(Q) $(PURIFY) $(CC) -mwindows -e $(SYMBOL_PREFIX)mainCRTStartup $(LDFLAGS) $(XLDFLAGS) \
+ $(Q) $(PURIFY) $(CC) $(MUNICODE_FLAG) -mwindows -e $(SYMBOL_PREFIX)mainCRTStartup $(LDFLAGS) $(XLDFLAGS) \
$(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@
$(STUBPROGRAM): $(RUBY_INSTALL_NAME).res.$(OBJEXT)
diff --git a/defs/gmake.mk b/defs/gmake.mk
index dc9d31f49e..54fef6685f 100644
--- a/defs/gmake.mk
+++ b/defs/gmake.mk
@@ -27,7 +27,7 @@ TEST_DEPENDS := $(filter-out commit $(TEST_TARGETS),$(MAKECMDGOALS))
TEST_TARGETS := $(patsubst great,exam,$(TEST_TARGETS))
TEST_DEPENDS := $(filter-out great $(TEST_TARGETS),$(TEST_DEPENDS))
TEST_TARGETS := $(patsubst exam,check,$(TEST_TARGETS))
-TEST_TARGETS := $(patsubst check,test-spec test-all test-tool test-short,$(TEST_TARGETS))
+TEST_TARGETS := $(patsubst check,test-syntax-suggest test-spec test-all test-tool test-short,$(TEST_TARGETS))
TEST_TARGETS := $(patsubst test-rubyspec,test-spec,$(TEST_TARGETS))
TEST_DEPENDS := $(filter-out exam check test-spec $(TEST_TARGETS),$(TEST_DEPENDS))
TEST_TARGETS := $(patsubst love,check,$(TEST_TARGETS))
@@ -40,6 +40,7 @@ TEST_TARGETS := $(patsubst test-short,btest-ruby test-knownbug test-basic,$(TEST
TEST_TARGETS := $(patsubst test-bundled-gems,test-bundled-gems-run,$(TEST_TARGETS))
TEST_TARGETS := $(patsubst test-bundled-gems-run,test-bundled-gems-run $(PREPARE_BUNDLED_GEMS),$(TEST_TARGETS))
TEST_TARGETS := $(patsubst test-bundled-gems-prepare,test-bundled-gems-prepare $(PRECHECK_BUNDLED_GEMS) test-bundled-gems-fetch,$(TEST_TARGETS))
+TEST_TARGETS := $(patsubst test-syntax-suggest,test-syntax-suggest $(PREPARE_SYNTAX_SUGGEST),$(TEST_TARGETS))
TEST_DEPENDS := $(filter-out test-short $(TEST_TARGETS),$(TEST_DEPENDS))
TEST_DEPENDS += $(if $(filter great exam love check,$(MAKECMDGOALS)),all exts)
endif
@@ -83,7 +84,8 @@ endif
ORDERED_TEST_TARGETS := $(filter $(TEST_TARGETS), \
btest-ruby test-knownbug test-basic \
test-testframework test-tool test-ruby test-all \
- test-spec test-bundler-prepare test-bundler test-bundler-parallel \
+ test-spec test-syntax-suggest-prepare test-syntax-suggest \
+ test-bundler-prepare test-bundler test-bundler-parallel \
test-bundled-gems-precheck test-bundled-gems-fetch \
test-bundled-gems-prepare test-bundled-gems-run \
)
diff --git a/defs/id.def b/defs/id.def
index a3a383f532..ebf00506ea 100644
--- a/defs/id.def
+++ b/defs/id.def
@@ -76,6 +76,7 @@ firstline, predefined = __LINE__+1, %[\
"/*NULL*/" NULL
empty?
eql?
+ default
respond_to? Respond_to
respond_to_missing? Respond_to_missing
<IFUNC>
diff --git a/doc/.document b/doc/.document
index 5ef2d99651..f589dda07c 100644
--- a/doc/.document
+++ b/doc/.document
@@ -6,3 +6,4 @@ NEWS
syntax
optparse
rdoc
+yjit
diff --git a/doc/encodings.rdoc b/doc/encodings.rdoc
index c61ab11e9a..1f3c54d740 100644
--- a/doc/encodings.rdoc
+++ b/doc/encodings.rdoc
@@ -467,12 +467,13 @@ These keyword-value pairs specify encoding options:
with a carriage-return character (<tt>"\r"</tt>).
- <tt>:crlf_newline: true</tt>: Replace each line-feed character (<tt>"\n"</tt>)
with a carriage-return/line-feed string (<tt>"\r\n"</tt>).
- - <tt>:universal_newline: true</tt>: Replace each carriage-return/line-feed string
+ - <tt>:universal_newline: true</tt>: Replace each carriage-return
+ character (<tt>"\r"</tt>) and each carriage-return/line-feed string
(<tt>"\r\n"</tt>) with a line-feed character (<tt>"\n"</tt>).
Examples:
- s = "\n \r\n" # => "\n \r\n"
- s.encode('ASCII', cr_newline: true) # => "\r \r\r"
- s.encode('ASCII', crlf_newline: true) # => "\r\n \r\r\n"
- s.encode('ASCII', universal_newline: true) # => "\n \n"
+ s = "\n \r \r\n" # => "\n \r \r\n"
+ s.encode('ASCII', cr_newline: true) # => "\r \r \r\r"
+ s.encode('ASCII', crlf_newline: true) # => "\r\n \r \r\r\n"
+ s.encode('ASCII', universal_newline: true) # => "\n \n \n"
diff --git a/doc/mjit.md b/doc/mjit.md
deleted file mode 100644
index 9622a3bc26..0000000000
--- a/doc/mjit.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# MJIT
-
-This document has some tips that might be useful when you work on MJIT.
-
-## Supported platforms
-
-The following platforms are either tested on CI or assumed to work.
-
-* OS: Linux, macOS
-* Arch: x86\_64, aarch64, arm64, i686, i386
-
-### Not supported
-
-The MJIT support for the following platforms is no longer maintained.
-
-* OS: Windows (mswin, MinGW), Solaris
-* Arch: SPARC, s390x
-
-### Architectures
-
-## Bindgen
-
-If you see an "MJIT bindgen" GitHub Actions failure, please commit the `git diff` shown on the failed job.
-
-Refer to the following instructions for doing the same thing locally.
-Similar to `make yjit-bindgen`, `make mjit-bindgen` requires libclang.
-See also: [mjit-bindgen.yml](../.github/workflows/mjit-bindgen.yml)
-
-macOS seems to have libclang by default, but I'm not sure how to deal with 32bit architectures.
-For now, you may generate c\_64.rb with a 64bit binary, and then manually modify c\_32.rb accordingly.
-
-### x86\_64-linux
-
-```sh
-sudo apt install \
- build-essential \
- libssl-dev libyaml-dev libreadline6-dev \
- zlib1g-dev libncurses5-dev libffi-dev \
- libclang1
-./autogen.sh
-./configure --enable-yjit=dev_nodebug --disable-install-doc
-make -j
-make mjit-bindgen
-```
-
-### i686-linux
-
-```sh
-sudo dpkg --add-architecture i386
-sudo apt install \
- crossbuild-essential:i386 \
- libssl-dev:i386 libyaml-dev:i386 libreadline6-dev:i386 \
- zlib1g-dev:i386 libncurses5-dev:i386 libffi-dev:i386 \
- libclang1:i386
-./autogen.sh
-./configure --disable-install-doc
-make -j
-make mjit-bindgen
-```
-
-Note that you cannot run x86\_64 bindgen with an i686 binary, and vice versa.
-Also, when you install libclang1:i386, libclang1 will be uninstalled.
-You can have only either of these at a time.
-
-## Local development
-
-### Always run make install
-
-Always run `make install` before running MJIT. It could easily cause a SEGV if you don't.
-MJIT looks for the installed header for security reasons.
-
-### --mjit-debug vs --mjit-debug=-ggdb3
-
-`--mjit-debug=[flags]` allows you to specify arbitrary flags while keeping other compiler flags like `-O3`,
-which is useful for profiling benchmarks.
-
-`--mjit-debug` alone, on the other hand, disables `-O3` and adds debug flags.
-If you're debugging MJIT, what you need to use is not `--mjit-debug=-ggdb3` but `--mjit-debug`.
diff --git a/doc/mjit/mjit.md b/doc/mjit/mjit.md
new file mode 100644
index 0000000000..6f19ab3ea7
--- /dev/null
+++ b/doc/mjit/mjit.md
@@ -0,0 +1,39 @@
+# MJIT
+
+This document has some tips that might be useful when you work on MJIT.
+
+## Supported platforms
+
+The following platforms are either tested on CI or assumed to work.
+
+* OS: Linux, macOS
+* Arch: x86\_64, aarch64, arm64, i686, i386
+
+### Not supported
+
+The MJIT support for the following platforms is no longer maintained.
+
+* OS: Windows (mswin, MinGW), Solaris
+* Arch: SPARC, s390x
+
+## Developing MJIT
+
+### Bindgen
+
+If you see an "MJIT bindgen" GitHub Actions failure, please commit the `git diff` shown on the failed job.
+
+For doing the same thing locally, run `make mjit-bindgen` after installing libclang.
+macOS seems to have libclang by default. On Ubuntu, you can install it with `apt install libclang1`.
+
+### Always run make install
+
+Always run `make install` before running MJIT. It could easily cause a SEGV if you don't.
+MJIT looks for the installed header for security reasons.
+
+### --mjit-debug vs --mjit-debug=-ggdb3
+
+`--mjit-debug=[flags]` allows you to specify arbitrary flags while keeping other compiler flags like `-O3`,
+which is useful for profiling benchmarks.
+
+`--mjit-debug` alone, on the other hand, disables `-O3` and adds debug flags.
+If you're debugging MJIT, what you need to use is not `--mjit-debug=-ggdb3` but `--mjit-debug`.
diff --git a/doc/net-http/examples.rdoc b/doc/net-http/examples.rdoc
index dd4acecda6..c1366e7ad1 100644
--- a/doc/net-http/examples.rdoc
+++ b/doc/net-http/examples.rdoc
@@ -10,9 +10,10 @@ Many code examples here use these example websites:
Some examples also assume these variables:
- uri = URI('https://jsonplaceholder.typicode.com')
+ uri = URI('https://jsonplaceholder.typicode.com/')
uri.freeze # Examples may not modify.
hostname = uri.hostname # => "jsonplaceholder.typicode.com"
+ path = uri.path # => "/"
port = uri.port # => 443
So that example requests may be written as:
diff --git a/doc/net-http/included_getters.rdoc b/doc/net-http/included_getters.rdoc
new file mode 100644
index 0000000000..7ac327f4b4
--- /dev/null
+++ b/doc/net-http/included_getters.rdoc
@@ -0,0 +1,3 @@
+This class also includes (indirectly) module Net::HTTPHeader,
+which gives access to its
+{methods for getting headers}[rdoc-ref:Net::HTTPHeader@Getters].
diff --git a/doc/packed_data.rdoc b/doc/packed_data.rdoc
index 9ba585c90b..ec13b24c69 100644
--- a/doc/packed_data.rdoc
+++ b/doc/packed_data.rdoc
@@ -60,6 +60,10 @@ Any directive may be followed by either of these modifiers:
Note: Directives in <tt>%w[A a Z m]</tt> use +count+ differently;
see {String Directives}[rdoc-ref:packed_data.rdoc@String+Directives].
+If elements don't fit the provided directive, only least significant bits are encoded:
+
+ [257].pack("C").unpack("C") # => [1]
+
=== Packing \Method
\Method Array#pack accepts optional keyword argument
diff --git a/doc/syntax/literals.rdoc b/doc/syntax/literals.rdoc
index 5e10e6a140..b641433249 100644
--- a/doc/syntax/literals.rdoc
+++ b/doc/syntax/literals.rdoc
@@ -277,6 +277,12 @@ the content. Note that empty lines and lines consisting solely of literal tabs
and spaces will be ignored for the purposes of determining indentation, but
escaped tabs and spaces are considered non-indentation characters.
+For the purpose of measuring an indentation, a horizontal tab is regarded as a
+sequence of one to eight spaces such that the column position corresponding to
+its end is a multiple of eight. The amount to be removed is counted in terms
+of the number of spaces. If the boundary appears in the middle of a tab, that
+tab is not removed.
+
A heredoc allows interpolation and escaped characters. You may disable
interpolation and escaping by surrounding the opening identifier with single
quotes:
diff --git a/doc/yjit/yjit.md b/doc/yjit/yjit.md
index 1af5aeb417..67b2ffa5f0 100644
--- a/doc/yjit/yjit.md
+++ b/doc/yjit/yjit.md
@@ -9,9 +9,9 @@ YJIT - Yet Another Ruby JIT
===========================
YJIT is a lightweight, minimalistic Ruby JIT built inside CRuby.
-It lazily compiles code using a Basic Block Versioning (BBV) architecture. The target use case is that of servers running
-Ruby on Rails, an area where MJIT has not yet managed to deliver speedups.
-YJIT is currently supported for macOS and Linux on x86-64 and arm64/aarch64 CPUs.
+It lazily compiles code using a Basic Block Versioning (BBV) architecture.
+The target use case is that of servers running Ruby on Rails.
+YJIT is currently supported for macOS, Linux and BSD on x86-64 and arm64/aarch64 CPUs.
This project is open source and falls under the same license as CRuby.
<p align="center"><b>
@@ -20,6 +20,8 @@ This project is open source and falls under the same license as CRuby.
</b></p>
If you wish to learn more about the approach taken, here are some conference talks and publications:
+- RubyKaigi 2022 keynote: [Stories from developing YJIT](https://www.youtube.com/watch?v=EMchdR9C8XM)
+- RubyKaigi 2022 talk: [Building a Lightweight IR and Backend for YJIT](https://www.youtube.com/watch?v=BbLGqTxTRp0)
- RubyKaigi 2021 talk: [YJIT: Building a New JIT Compiler Inside CRuby](https://www.youtube.com/watch?v=PBVLf3yfMs8)
- Blog post: [YJIT: Building a New JIT Compiler Inside CRuby](https://pointersgonewild.com/2021/06/02/yjit-building-a-new-jit-compiler-inside-cruby/)
- VMIL 2021 paper: [YJIT: A Basic Block Versioning JIT Compiler for CRuby](https://dl.acm.org/doi/10.1145/3486606.3486781)
@@ -52,8 +54,7 @@ series = {VMIL 2021}
## Current Limitations
-YJIT may not be suitable for certain applications. It currently only supports macOS and Linux on x86-64 and arm64/aarch64 CPUs. YJIT will use more memory than the Ruby interpreter because the JIT compiler needs to generate machine code in memory and maintain additional state
-information.
+YJIT may not be suitable for certain applications. It currently only supports macOS and Linux on x86-64 and arm64/aarch64 CPUs. YJIT will use more memory than the Ruby interpreter because the JIT compiler needs to generate machine code in memory and maintain additional state information.
You can change how much executable memory is allocated using [YJIT's command-line options](#command-line-options). There is a slight performance tradeoff because allocating less executable memory could result in the generated machine code being collected more often.
## Installation
@@ -75,44 +76,53 @@ To install the Rust build toolchain, we suggest following the [recommended insta
Start by cloning the `ruby/ruby` repository:
-```
+```sh
git clone https://github.com/ruby/ruby yjit
cd yjit
```
-The YJIT `ruby` binary can be built with either GCC or Clang. It can be built either in dev (debug) mode or in release mode. For maximum performance, compile YJIT in release mode with GCC. More detailed build instructions are provided in the [Ruby README](https://github.com/ruby/ruby#how-to-compile-and-install).
+The YJIT `ruby` binary can be built with either GCC or Clang. It can be built either in dev (debug) mode or in release mode. For maximum performance, compile YJIT in release mode with GCC. More detailed build instructions are provided in the [Ruby README](https://github.com/ruby/ruby#how-to-build).
-```
+```sh
# Configure in release mode for maximum performance, build and install
./autogen.sh
./configure --enable-yjit --prefix=$HOME/.rubies/ruby-yjit --disable-install-doc
-make -j install
+make -j && make install
```
or
-```
-# Configure in dev (debug) mode for development, build and install
+```sh
+# Configure in lower-performance dev (debug) mode for development, build and install
./autogen.sh
./configure --enable-yjit=dev --prefix=$HOME/.rubies/ruby-yjit --disable-install-doc
-make -j install
+make -j && make install
```
-On macOS, you may need to specify where to find some libraries:
+Dev mode includes extended YJIT statistics, but can be slow. For only statistics you can configure in stats mode:
+```sh
+# Configure in extended-stats mode without slow runtime checks, build and install
+./autogen.sh
+./configure --enable-yjit=stats --prefix=$HOME/.rubies/ruby-yjit --disable-install-doc
+make -j && make install
```
+
+On macOS, you may need to specify where to find some libraries:
+
+```sh
# Install dependencies
brew install openssl readline libyaml
# Configure in dev (debug) mode for development, build and install
./autogen.sh
./configure --enable-yjit=dev --prefix=$HOME/.rubies/ruby-yjit --disable-install-doc --with-opt-dir="$(brew --prefix openssl):$(brew --prefix readline):$(brew --prefix libyaml)"
-make -j install
+make -j && make install
```
Typically configure will choose the default C compiler. To specify the C compiler, use
-```
+```sh
# Choosing a specific c compiler
export CC=/path/to/my/chosen/c/compiler
```
@@ -121,7 +131,7 @@ before running `./configure`.
You can test that YJIT works correctly by running:
-```
+```sh
# Quick tests found in /bootstraptest
make btest
@@ -136,14 +146,14 @@ make -j test-all
Once YJIT is built, you can either use `./miniruby` from within your build directory, or switch to the YJIT version of `ruby`
by using the `chruby` tool:
-```
+```sh
chruby ruby-yjit
ruby myscript.rb
```
You can dump statistics about compilation and execution by running YJIT with the `--yjit-stats` command-line option:
-```
+```sh
./miniruby --yjit-stats myscript.rb
```
@@ -155,11 +165,9 @@ YJIT supports all command-line options supported by upstream CRuby, but also add
- `--yjit`: enable YJIT (disabled by default)
- `--yjit-call-threshold=N`: number of calls after which YJIT begins to compile a function (default 30)
-- `--yjit-exec-mem-size=N`: size of the executable memory block to allocate, in MiB (default 128 MiB)
-- `--yjit-stats`: produce statistics after the execution of a program
-- `--yjit-trace-exits`: produce a Marshal dump of backtraces from specific exits. Automatically enables `--yjit-stats` (must configure and build with `--enable-yjit=stats` to use this)
-- `--yjit-max-versions=N`: maximum number of versions to generate per basic block (default 4)
-- `--yjit-greedy-versioning`: greedy versioning mode (disabled by default, may increase code size)
+- `--yjit-exec-mem-size=N`: size of the executable memory block to allocate, in MiB (default 64 MiB)
+- `--yjit-stats`: print statistics after the execution of a program (incurs a run-time cost)
+- `--yjit-trace-exits`: produce a Marshal dump of backtraces from specific exits. Automatically enables `--yjit-stats`
Note that there is also an environment variable `RUBY_YJIT_ENABLE` which can be used to enable YJIT.
This can be useful for some deployment scripts where specifying an extra command-line option to Ruby is not practical.
@@ -168,28 +176,79 @@ This can be useful for some deployment scripts where specifying an extra command
We have collected a set of benchmarks and implemented a simple benchmarking harness in the [yjit-bench](https://github.com/Shopify/yjit-bench) repository. This benchmarking harness is designed to disable CPU frequency scaling, set process affinity and disable address space randomization so that the variance between benchmarking runs will be as small as possible. Please kindly note that we are at an early stage in this project.
-### Performance Tips
+## Performance Tips for Production Deployments
+
+While YJIT options default to what we think would work well for most workloads,
+they might not necessarily be the best configuration for your application.
+
+This section covers tips on improving YJIT performance in case YJIT does not
+speed up your application in production.
+
+### Increasing --yjit-exec-mem-size
+
+When JIT code size (`RubyVM::YJIT.runtime_stats[:code_region_size]`) reaches this value,
+YJIT triggers "code GC" that frees all JIT code and starts recompiling everything.
+Compiling code takes some time, so scheduling code GC too frequently slows down your application.
+Increasing `--yjit-exec-mem-size` may speed up your application if `RubyVM::YJIT.runtime_stats[:code_gc_count]` is not 0 or 1.
+
+### Running workers as long as possible
+
+It's helpful to call the same code as many times as possible before a process restarts.
+If a process is killed too frequently, the time taken for compiling methods may outweigh
+the speedup obtained by compiling them.
+
+You should monitor the number of requests each process has served.
+If you're periodically killing worker processes, e.g. with `unicorn-worker-killer` or `puma_worker_killer`,
+you may want to reduce the killing frequency or increase the limit.
+
+## Saving YJIT Memory Usage
+
+YJIT allocates memory for JIT code and metadata. Enabling YJIT generally results in more memory usage.
-This section contains tips on writing Ruby code that will run as fast as possible on YJIT. Some of this advice is based on current limitations of YJIT, while other advice is broadly applicable. It probably won't be practical to apply these tips everywhere in your codebase, but you can profile your code using a tool such as [stackprof](https://github.com/tmm1/stackprof) and refactor the specific methods that make up the largest fractions of the execution time.
+This section goes over tips on minimizing YJIT memory usage in case it uses more than your capacity.
-- Use exceptions for error recovery only, not as part of normal control-flow
+### Increasing --yjit-call-threshold
+
+As of Ruby 3.2, `--yjit-call-threshold` defaults to 30. With this default, some applications end up
+compiling methods that are used only during the application boot. Increasing this option may help
+you reduce the size of JIT code and metadata. It's worth trying different values like `--yjit-call-threshold=100`.
+
+Note that increasing the value too much may result in compiling code too late.
+You should monitor how many requests each worker processes before it's restarted. For example,
+if each process only handles 1000 requests, `--yjit-call-threshold=1000` might be too large for your application.
+
+### Decreasing --yjit-exec-mem-size
+
+`--yjit-exec-mem-size` specifies the JIT code size, but YJIT also uses memory for its metadata,
+which often consumes more memory than JIT code. Generally, YJIT adds memory overhead by roughly
+3-4x of `--yjit-exec-mem-size` in production as of Ruby 3.2. You should multiply that by the number
+of worker processes to estimate the worst case memory overhead.
+
+Running code GC adds overhead, but it could be still faster than recovering from a whole process killed by OOM.
+
+## Code Optimization Tips
+
+This section contains tips on writing Ruby code that will run as fast as possible on YJIT. Some of this advice is based on current limitations of YJIT, while other advice is broadly applicable. It probably won't be practical to apply these tips everywhere in your codebase. You should ideally start by profiling your application using a tool such as [stackprof](https://github.com/tmm1/stackprof) so that you can determine which methods make up most of the execution time. You can then refactor the specific methods that make up the largest fractions of the execution time. We do not recommend modifying your entire codebase based on the current limitations of YJIT.
+
+- Avoid using `OpenStruct`
- Avoid redefining basic integer operations (i.e. +, -, <, >, etc.)
- Avoid redefining the meaning of `nil`, equality, etc.
- Avoid allocating objects in the hot parts of your code
-- Use while loops if you can, instead of `integer.times`
- Minimize layers of indirection
- Avoid classes that wrap objects if you can
- Avoid methods that just call another method, trivial one liner methods
-- CRuby method calls are costly. Favor larger methods over smaller methods.
- Try to write code so that the same variables always have the same type
+- Use `while` loops if you can, instead of C methods like `Array#each`
+ - This is not idiomatic Ruby, but could help in hot methods
+- CRuby method calls are costly. Avoid things such as methods that only return a value from a hash or return a constant.
You can also use the `--yjit-stats` command-line option to see which bytecodes cause YJIT to exit, and refactor your code to avoid using these instructions in the hottest methods of your code.
### Other Statistics
-If you compile Ruby with `RUBY_DEBUG` and/or `YJIT_STATS` defined and run with `--yjit --yjit-stats`, YJIT will track and return performance statistics in `RubyVM::YJIT.runtime_stats`.
+If you run `ruby` with `--yjit --yjit-stats`, YJIT will track and return performance statistics in `RubyVM::YJIT.runtime_stats`.
-```
+```rb
$ RUBYOPT="--yjit --yjit-stats" irb
irb(main):001:0> RubyVM::YJIT.runtime_stats
=>
@@ -205,16 +264,24 @@ irb(main):001:0> RubyVM::YJIT.runtime_stats
Some of the counters include:
-:exec_instruction - how many Ruby bytecode instructions have been executed
-:binding_allocations - number of bindings allocated
-:binding_set - number of variables set via a binding
-:vm_insns_count - number of instructions executed by the Ruby interpreter
-:compiled_iseq_count - number of bytecode sequences compiled
+* :exec_instruction - how many Ruby bytecode instructions have been executed
+* :binding_allocations - number of bindings allocated
+* :binding_set - number of variables set via a binding
+* :code_gc_count - number of garbage collections of compiled code since process start
+* :vm_insns_count - number of instructions executed by the Ruby interpreter
+* :compiled_iseq_count - number of bytecode sequences compiled
+* :inline_code_size - size in bytes of compiled YJIT blocks
+* :outline_code_size - size in bytes of YJIT error-handling compiled code
+* :side_exit_count - number of side exits taken at runtime
+* :total_exit_count - number of exits, including side exits, taken at runtime
+* :avg_len_in_yjit - avg. number of instructions in compiled blocks before exiting to interpreter
Counters starting with "exit_" show reasons for YJIT code taking a side exit (return to the interpreter.) See yjit_hacking.md for more details.
Performance counter names are not guaranteed to remain the same between Ruby versions. If you're curious what one does, it's usually best to search the source code for it &mdash; but it may change in a later Ruby version.
+The printed text after a --yjit-stats run includes other information that may be named differently than the information in runtime_stats.
+
## Contributing
We welcome open source contributors. You should feel free to open new issues to report bugs or just to ask questions.
@@ -242,8 +309,6 @@ The YJIT source code is divided between:
- `yjit/src/options.rs`: handling of command-line options
- `yjit/bindgen/src/main.rs`: C bindings exposed to the Rust codebase through bindgen
- `yjit/src/cruby.rs`: C bindings manually exposed to the Rust codebase
-- `misc/test_yjit_asm.sh`: script to compile and run the in-memory assembler tests
-- `misc/yjit_asm_tests.c`: tests for the in-memory assembler
The core of CRuby's interpreter logic is found in:
- `insns.def`: defines Ruby's bytecode instructions (gets compiled into `vm.inc`)
@@ -274,38 +339,38 @@ There are 3 test suites:
The tests can be run in parallel like this:
-```
+```sh
make -j test-all RUN_OPTS="--yjit-call-threshold=1"
```
Or single-threaded like this, to more easily identify which specific test is failing:
-```
+```sh
make test-all TESTOPTS=--verbose RUN_OPTS="--yjit-call-threshold=1"
```
To debug a single test in `test-all`:
-```
+```sh
make test-all TESTS='test/-ext-/marshal/test_usrmarshal.rb' RUNRUBYOPT=--debugger=lldb RUN_OPTS="--yjit-call-threshold=1"
```
You can also run one specific test in `btest`:
-```
+```sh
make btest BTESTS=bootstraptest/test_ractor.rb RUN_OPTS="--yjit-call-threshold=1"
```
There are shortcuts to run/debug your own test/repro in `test.rb`:
-```
+```sh
make run # runs ./miniruby test.rb
make lldb # launches ./miniruby test.rb in lldb
```
You can use the Intel syntax for disassembly in LLDB, keeping it consistent with YJIT's disassembly:
-```
+```sh
echo "settings set target.x86-disassembly-flavor intel" >> ~/.lldbinit
```
@@ -316,7 +381,7 @@ instructions below, but there are a few caveats listed further down.
First, install Rosetta:
-```
+```sh
$ softwareupdate --install-rosetta
```
@@ -324,13 +389,13 @@ Now any command can be run with Rosetta via the `arch` command line tool.
Then you can start your shell in an x86 environment:
-```
+```sh
$ arch -x86_64 zsh
```
You can double check your current architecture via the `arch` command:
-```
+```sh
$ arch -x86_64 zsh
$ arch
i386
@@ -338,7 +403,7 @@ i386
You may need to set the default target for `rustc` to x86-64, e.g.
-```
+```sh
$ rustup default stable-x86_64-apple-darwin
```
diff --git a/enc/Makefile.in b/enc/Makefile.in
index dd8ca1b528..9d0c367134 100644
--- a/enc/Makefile.in
+++ b/enc/Makefile.in
@@ -51,7 +51,7 @@ optflags = @optflags@
debugflags = @debugflags@
warnflags = @warnflags@
CCDLFLAGS = @CCDLFLAGS@
-INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(top_srcdir)
+INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(top_srcdir) @incflags@
DEFS = @DEFS@
CPPFLAGS = @CPPFLAGS@ -DONIG_ENC_REGISTER=rb_enc_register
LDFLAGS = @LDFLAGS@
diff --git a/enc/cesu_8.c b/enc/cesu_8.c
index decbb928f4..75f62df280 100644
--- a/enc/cesu_8.c
+++ b/enc/cesu_8.c
@@ -42,6 +42,8 @@
#define VALID_CODE_LIMIT 0x0010ffff
#define utf8_islead(c) ((UChar )((c) & 0xc0) != 0x80)
+#define utf16_is_high_surrogate(v) ((v >> 10) == 0x36)
+#define utf16_is_low_surrogate(v) ((v >> 10) == 0x37)
static const int EncLen_CESU8[] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
@@ -283,6 +285,12 @@ is_mbc_newline(const UChar* p, const UChar* end, OnigEncoding enc)
return 0;
}
+static int
+utf8_decode_3byte_sequence(const UChar* p)
+{
+ return ((p[0] & 0xF) << 12) | ((p[1] & 0x3f) << 6) | (p[2] & 0x3f);
+}
+
static OnigCodePoint
mbc_to_code(const UChar* p, const UChar* end, OnigEncoding enc)
{
@@ -295,11 +303,11 @@ mbc_to_code(const UChar* p, const UChar* end, OnigEncoding enc)
case 2:
return ((p[0] & 0x1F) << 6) | (p[1] & 0x3f);
case 3:
- return ((p[0] & 0xF) << 12) | ((p[1] & 0x3f) << 6) | (p[2] & 0x3f);
+ return utf8_decode_3byte_sequence(p);
case 6:
{
- int high = ((p[0] & 0xF) << 12) | ((p[1] & 0x3f) << 6) | (p[2] & 0x3f);
- int low = ((p[3] & 0xF) << 12) | ((p[4] & 0x3f) << 6) | (p[5] & 0x3f);
+ int high = utf8_decode_3byte_sequence(p);
+ int low = utf8_decode_3byte_sequence(p + 3);
return ((high & 0x03ff) << 10) + (low & 0x03ff) + 0x10000;
}
}
@@ -410,7 +418,6 @@ get_ctype_code_range(OnigCtype ctype, OnigCodePoint *sb_out,
return onigenc_unicode_ctype_code_range(ctype, ranges);
}
-
static UChar*
left_adjust_char_head(const UChar* start, const UChar* s, const UChar* end, OnigEncoding enc ARG_UNUSED)
{
@@ -420,6 +427,14 @@ left_adjust_char_head(const UChar* start, const UChar* s, const UChar* end, Onig
p = s;
while (!utf8_islead(*p) && p > start) p--;
+
+ if (p > start && s - p == 2 && utf16_is_low_surrogate(utf8_decode_3byte_sequence(p))) {
+ const UChar *p_surrogate_pair = p - 1;
+ while (!utf8_islead(*p_surrogate_pair) && p_surrogate_pair > start) p_surrogate_pair--;
+ if (p - p_surrogate_pair == 3 && utf16_is_high_surrogate(utf8_decode_3byte_sequence(p_surrogate_pair))) {
+ return (UChar* )p_surrogate_pair;
+ }
+ }
return (UChar* )p;
}
diff --git a/enc/depend b/enc/depend
index 60c5a3ebb2..973ad93010 100644
--- a/enc/depend
+++ b/enc/depend
@@ -7018,6 +7018,7 @@ enc/trans/iso2022.$(OBJEXT): internal/attr/nodiscard.h
enc/trans/iso2022.$(OBJEXT): internal/attr/noexcept.h
enc/trans/iso2022.$(OBJEXT): internal/attr/noinline.h
enc/trans/iso2022.$(OBJEXT): internal/attr/nonnull.h
+enc/trans/iso2022.$(OBJEXT): internal/attr/nonstring.h
enc/trans/iso2022.$(OBJEXT): internal/attr/noreturn.h
enc/trans/iso2022.$(OBJEXT): internal/attr/pure.h
enc/trans/iso2022.$(OBJEXT): internal/attr/restrict.h
diff --git a/encoding.c b/encoding.c
index 39a47f2b8c..2f4b47bdfa 100644
--- a/encoding.c
+++ b/encoding.c
@@ -1556,7 +1556,14 @@ enc_set_default_encoding(struct default_encoding *def, VALUE encoding, const cha
if (NIL_P(encoding)) {
def->index = -1;
def->enc = 0;
- st_insert(enc_table->names, (st_data_t)strdup(name),
+ char *name_dup = strdup(name);
+
+ st_data_t existing_name = (st_data_t)name_dup;
+ if (st_delete(enc_table->names, &existing_name, NULL)) {
+ xfree((void *)existing_name);
+ }
+
+ st_insert(enc_table->names, (st_data_t)name_dup,
(st_data_t)UNSPECIFIED_ENCODING);
}
else {
diff --git a/enum.c b/enum.c
index 391de0b337..b3c715e0a1 100644
--- a/enum.c
+++ b/enum.c
@@ -4459,7 +4459,7 @@ sum_iter(VALUE i, struct enum_sum_memo *memo)
}
else switch (TYPE(memo->v)) {
default: sum_iter_some_value(i, memo); return;
- case T_FLOAT: sum_iter_Kahan_Babuska(i, memo); return;
+ case T_FLOAT:
case T_FIXNUM:
case T_BIGNUM:
case T_RATIONAL:
diff --git a/enumerator.c b/enumerator.c
index 5cbaaee04b..d587b63d32 100644
--- a/enumerator.c
+++ b/enumerator.c
@@ -73,6 +73,8 @@
* puts %w[foo bar baz].map.with_index { |w, i| "#{i}:#{w}" }
* # => ["0:foo", "1:bar", "2:baz"]
*
+ * == External Iteration
+ *
* An Enumerator can also be used as an external iterator.
* For example, Enumerator#next returns the next value of the iterator
* or raises StopIteration if the Enumerator is at the end.
@@ -83,15 +85,44 @@
* puts e.next # => 3
* puts e.next # raises StopIteration
*
- * Note that enumeration sequence by +next+, +next_values+, +peek+ and
- * +peek_values+ do not affect other non-external
- * enumeration methods, unless the underlying iteration method itself has
- * side-effect, e.g. IO#each_line.
+ * +next+, +next_values+, +peek+ and +peek_values+ are the only methods
+ * which use external iteration (and Array#zip(Enumerable-not-Array) which uses +next+).
+ *
+ * These methods do not affect other internal enumeration methods,
+ * unless the underlying iteration method itself has side-effect, e.g. IO#each_line.
+ *
+ * External iteration differs *significantly* from internal iteration
+ * due to using a Fiber:
+ * - The Fiber adds some overhead compared to internal enumeration.
+ * - The stacktrace will only include the stack from the Enumerator, not above.
+ * - Fiber-local variables are *not* inherited inside the Enumerator Fiber,
+ * which instead starts with no Fiber-local variables.
+ * - Fiber storage variables *are* inherited and are designed
+ * to handle Enumerator Fibers. Assigning to a Fiber storage variable
+ * only affects the current Fiber, so if you want to change state
+ * in the caller Fiber of the Enumerator Fiber, you need to use an
+ * extra indirection (e.g., use some object in the Fiber storage
+ * variable and mutate some ivar of it).
+ *
+ * Concretely:
+ * Thread.current[:fiber_local] = 1
+ * Fiber[:storage_var] = 1
+ * e = Enumerator.new do |y|
+ * p Thread.current[:fiber_local] # for external iteration: nil, for internal iteration: 1
+ * p Fiber[:storage_var] # => 1, inherited
+ * Fiber[:storage_var] += 1
+ * y << 42
+ * end
+ *
+ * p e.next # => 42
+ * p Fiber[:storage_var] # => 1 (it ran in a different Fiber)
*
- * Moreover, implementation typically uses fibers so performance could be
- * slower and exception stacktraces different than expected.
+ * e.each { p _1 }
+ * p Fiber[:storage_var] # => 2 (it ran in the same Fiber/"stack" as the current Fiber)
*
- * You can use this to implement an internal iterator as follows:
+ * == Convert External Iteration to Internal Iteration
+ *
+ * You can use an external iterator to implement an internal iterator as follows:
*
* def ext_each(e)
* while true
@@ -133,7 +164,10 @@ static VALUE sym_each, sym_cycle, sym_yield;
static VALUE lazy_use_super_method;
+extern ID ruby_static_id_cause;
+
#define id_call idCall
+#define id_cause ruby_static_id_cause
#define id_each idEach
#define id_eqq idEqq
#define id_initialize idInitialize
@@ -767,8 +801,7 @@ next_init(VALUE obj, struct enumerator *e)
{
VALUE curr = rb_fiber_current();
e->dst = curr;
- // We inherit the fiber storage by reference, not by copy, by specifying Qfalse here.
- e->fib = rb_fiber_new_storage(next_i, obj, Qfalse);
+ e->fib = rb_fiber_new(next_i, obj);
e->lookahead = Qundef;
}
@@ -777,8 +810,16 @@ get_next_values(VALUE obj, struct enumerator *e)
{
VALUE curr, vs;
- if (e->stop_exc)
- rb_exc_raise(e->stop_exc);
+ if (e->stop_exc) {
+ VALUE exc = e->stop_exc;
+ VALUE result = rb_attr_get(exc, id_result);
+ VALUE mesg = rb_attr_get(exc, idMesg);
+ if (!NIL_P(mesg)) mesg = rb_str_dup(mesg);
+ VALUE stop_exc = rb_exc_new_str(rb_eStopIteration, mesg);
+ rb_ivar_set(stop_exc, id_cause, exc);
+ rb_ivar_set(stop_exc, id_result, result);
+ rb_exc_raise(stop_exc);
+ }
curr = rb_fiber_current();
@@ -3404,7 +3445,7 @@ enumerator_plus(VALUE obj, VALUE eobj)
*
* The method used against each enumerable object is `each_entry`
* instead of `each` so that the product of N enumerable objects
- * yields exactly N arguments in each iteration.
+ * yields an array of exactly N elements in each iteration.
*
* When no enumerator is given, it calls a given block once yielding
* an empty argument list.
@@ -3597,7 +3638,7 @@ product_each(VALUE obj, struct product_state *pstate)
rb_block_call(eobj, id_each_entry, 0, NULL, product_each_i, (VALUE)pstate);
}
else {
- rb_funcallv(pstate->block, id_call, pstate->argc, pstate->argv);
+ rb_funcall(pstate->block, id_call, 1, rb_ary_new_from_values(pstate->argc, pstate->argv));
}
return obj;
@@ -3695,6 +3736,7 @@ enum_product_inspect(VALUE obj)
/*
* call-seq:
* Enumerator.product(*enums) -> enumerator
+ * Enumerator.product(*enums) { |elts| ... } -> enumerator
*
* Generates a new enumerator object that generates a Cartesian
* product of given enumerable objects. This is equivalent to
@@ -3703,6 +3745,9 @@ enum_product_inspect(VALUE obj)
* e = Enumerator.product(1..3, [4, 5])
* e.to_a #=> [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]
* e.size #=> 6
+ *
+ * When a block is given, calls the block with each N-element array
+ * generated and returns +nil+.
*/
static VALUE
enumerator_s_product(int argc, VALUE *argv, VALUE klass)
@@ -3717,9 +3762,12 @@ enumerator_s_product(int argc, VALUE *argv, VALUE klass)
VALUE obj = enum_product_initialize(argc, argv, enum_product_allocate(rb_cEnumProduct));
- if (NIL_P(block)) return obj;
+ if (!NIL_P(block)) {
+ enum_product_run(obj, block);
+ return Qnil;
+ }
- return enum_product_run(obj, block);
+ return obj;
}
/*
diff --git a/error.c b/error.c
index bf3725bc47..726f57a4c0 100644
--- a/error.c
+++ b/error.c
@@ -420,7 +420,7 @@ rb_warn(const char *fmt, ...)
void
rb_category_warn(rb_warning_category_t category, const char *fmt, ...)
{
- if (!NIL_P(ruby_verbose)) {
+ if (!NIL_P(ruby_verbose) && rb_warning_category_enabled_p(category)) {
with_warning_string(mesg, 0, fmt) {
rb_warn_category(mesg, rb_warning_category_to_name(category));
}
@@ -452,7 +452,7 @@ rb_warning(const char *fmt, ...)
void
rb_category_warning(rb_warning_category_t category, const char *fmt, ...)
{
- if (RTEST(ruby_verbose)) {
+ if (RTEST(ruby_verbose) && rb_warning_category_enabled_p(category)) {
with_warning_string(mesg, 0, fmt) {
rb_warn_category(mesg, rb_warning_category_to_name(category));
}
@@ -1818,7 +1818,9 @@ name_err_init_attr(VALUE exc, VALUE recv, VALUE method)
cfp = rb_vm_get_ruby_level_next_cfp(ec, cfp);
rb_ivar_set(exc, id_name, method);
err_init_recv(exc, recv);
- if (cfp) rb_ivar_set(exc, id_iseq, rb_iseqw_new(cfp->iseq));
+ if (cfp && VM_FRAME_TYPE(cfp) != VM_FRAME_MAGIC_DUMMY) {
+ rb_ivar_set(exc, id_iseq, rb_iseqw_new(cfp->iseq));
+ }
return exc;
}
@@ -2959,6 +2961,8 @@ ivar_copy_i(st_data_t key, st_data_t val, st_data_t exc)
return ST_CONTINUE;
}
+void rb_exc_check_circular_cause(VALUE exc);
+
static VALUE
exception_loader(VALUE exc, VALUE obj)
{
@@ -2973,6 +2977,8 @@ exception_loader(VALUE exc, VALUE obj)
rb_ivar_foreach(obj, ivar_copy_i, exc);
+ rb_exc_check_circular_cause(exc);
+
if (rb_attr_get(exc, id_bt) == rb_attr_get(exc, id_bt_locations)) {
rb_ivar_set(exc, id_bt_locations, Qnil);
}
@@ -3024,12 +3030,16 @@ Init_Exception(void)
rb_eSyntaxError = rb_define_class("SyntaxError", rb_eScriptError);
rb_define_method(rb_eSyntaxError, "initialize", syntax_error_initialize, -1);
+ /* RDoc will use literal name value while parsing rb_attr,
+ * and will render `idPath` as an attribute name without this trick */
+ ID path = idPath;
+
/* the path failed to parse */
- rb_attr(rb_eSyntaxError, idPath, TRUE, FALSE, FALSE);
+ rb_attr(rb_eSyntaxError, path, TRUE, FALSE, FALSE);
rb_eLoadError = rb_define_class("LoadError", rb_eScriptError);
/* the path failed to load */
- rb_attr(rb_eLoadError, idPath, TRUE, FALSE, FALSE);
+ rb_attr(rb_eLoadError, path, TRUE, FALSE, FALSE);
rb_eNotImpError = rb_define_class("NotImplementedError", rb_eScriptError);
diff --git a/eval.c b/eval.c
index e1bbf6f2c3..a61dfb1289 100644
--- a/eval.c
+++ b/eval.c
@@ -537,12 +537,16 @@ exc_setup_message(const rb_execution_context_t *ec, VALUE mesg, VALUE *cause)
}
if (!nocircular && !NIL_P(*cause) && !UNDEF_P(*cause) && *cause != mesg) {
+#if 0 /* maybe critical for some cases */
+ rb_exc_check_circular_cause(*cause);
+#else
VALUE c = *cause;
while (!NIL_P(c = rb_attr_get(c, id_cause))) {
if (c == mesg) {
rb_raise(rb_eArgError, "circular causes");
}
}
+#endif
}
return mesg;
}
@@ -643,6 +647,10 @@ rb_ec_setup_exception(const rb_execution_context_t *ec, VALUE mesg, VALUE cause)
cause = get_ec_errinfo(ec);
}
if (cause != mesg) {
+ if (THROW_DATA_P(cause)) {
+ cause = Qnil;
+ }
+
rb_ivar_set(mesg, id_cause, cause);
}
}
@@ -1769,6 +1777,16 @@ rb_obj_extend(int argc, VALUE *argv, VALUE obj)
return obj;
}
+VALUE
+rb_top_main_class(const char *method)
+{
+ VALUE klass = GET_THREAD()->top_wrapper;
+
+ if (!klass) return rb_cObject;
+ rb_warning("main.%s in the wrapped load is effective only in wrapper module", method);
+ return klass;
+}
+
/*
* call-seq:
* include(module, ...) -> self
@@ -1781,13 +1799,7 @@ rb_obj_extend(int argc, VALUE *argv, VALUE obj)
static VALUE
top_include(int argc, VALUE *argv, VALUE self)
{
- rb_thread_t *th = GET_THREAD();
-
- if (th->top_wrapper) {
- rb_warning("main.include in the wrapped load is effective only in wrapper module");
- return rb_mod_include(argc, argv, th->top_wrapper);
- }
- return rb_mod_include(argc, argv, rb_cObject);
+ return rb_mod_include(argc, argv, rb_top_main_class("include"));
}
/*
diff --git a/eval_error.c b/eval_error.c
index e02f54e8e6..9806683000 100644
--- a/eval_error.c
+++ b/eval_error.c
@@ -291,6 +291,17 @@ show_cause(VALUE errinfo, VALUE str, VALUE opt, VALUE highlight, VALUE reverse,
}
void
+rb_exc_check_circular_cause(VALUE exc)
+{
+ VALUE cause = exc, shown_causes = 0;
+ do {
+ if (shown_cause_p(cause, &shown_causes)) {
+ rb_raise(rb_eArgError, "circular causes");
+ }
+ } while (!NIL_P(cause = rb_attr_get(cause, id_cause)));
+}
+
+void
rb_error_write(VALUE errinfo, VALUE emesg, VALUE errat, VALUE str, VALUE opt, VALUE highlight, VALUE reverse)
{
volatile VALUE eclass;
@@ -444,7 +455,12 @@ exiting_split(VALUE errinfo, volatile int *exitcode, volatile int *sigstatus)
if (NIL_P(errinfo)) return 0;
- if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) {
+ if (THROW_DATA_P(errinfo)) {
+ int throw_state = ((const struct vm_throw_data *)errinfo)->throw_state;
+ ex = throw_state & VM_THROW_STATE_MASK;
+ result |= EXITING_WITH_STATUS;
+ }
+ else if (rb_obj_is_kind_of(errinfo, rb_eSystemExit)) {
ex = sysexit_status(errinfo);
result |= EXITING_WITH_STATUS;
}
diff --git a/ext/-test-/string/fstring.c b/ext/-test-/string/fstring.c
index 2374319fe3..64f079251d 100644
--- a/ext/-test-/string/fstring.c
+++ b/ext/-test-/string/fstring.c
@@ -12,13 +12,13 @@ bug_s_fstring(VALUE self, VALUE str)
VALUE
bug_s_rb_enc_interned_str(VALUE self, VALUE encoding)
{
- return rb_enc_interned_str("foo", 3, RDATA(encoding)->data);
+ return rb_enc_interned_str("foo", 3, NIL_P(encoding) ? NULL : RDATA(encoding)->data);
}
VALUE
bug_s_rb_enc_str_new(VALUE self, VALUE encoding)
{
- return rb_enc_str_new("foo", 3, RDATA(encoding)->data);
+ return rb_enc_str_new("foo", 3, NIL_P(encoding) ? NULL : RDATA(encoding)->data);
}
void
diff --git a/ext/-test-/string/set_len.c b/ext/-test-/string/set_len.c
index 219cea404c..049da2cdb5 100644
--- a/ext/-test-/string/set_len.c
+++ b/ext/-test-/string/set_len.c
@@ -7,8 +7,18 @@ bug_str_set_len(VALUE str, VALUE len)
return str;
}
+static VALUE
+bug_str_append(VALUE str, VALUE addendum)
+{
+ StringValue(addendum);
+ rb_str_modify_expand(str, RSTRING_LEN(addendum));
+ memcpy(RSTRING_END(str), RSTRING_PTR(addendum), RSTRING_LEN(addendum));
+ return str;
+}
+
void
Init_string_set_len(VALUE klass)
{
rb_define_method(klass, "set_len", bug_str_set_len, 1);
+ rb_define_method(klass, "append", bug_str_append, 1);
}
diff --git a/ext/date/date_core.c b/ext/date/date_core.c