diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..05ff204541 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,134 @@ +--- +version: '{build}' +init: + - git config --global user.name git + - git config --global user.email svn-admin@ruby-lang.org + - git config --global core.autocrlf false + - git config --global core.eol lf + - git config --global advice.detachedHead 0 +shallow_clone: true +clone_depth: 10 +platform: + - x64 +skip_commits: + message: /\[DOC\]/ + files: + - doc/* + - '**/*.md' + - '**/*.rdoc' + - '**/.document' + - '**/*.[1-8]' + - '**/*.ronn' +environment: + ruby_version: "24-%Platform%" + matrix: + # Test only the oldest supported version because AppVeyor is unstable, its concurrency + # 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 # 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" +cache: + - c:\Tools\vcpkg\installed\ +for: +- + matrix: + only: + - build: vs + install: + - ver + - chcp + - SET BITS=%Platform:x86=32% + - SET BITS=%BITS:x=% + - SET OPENSSL_DIR=C:\%ssl%-Win%BITS% + - 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 + - SET vcvars + - '"%vcvars%" %Platform:x64=amd64%' + - SET ruby_path=C:\Ruby%ruby_version:-x86=% + - SET PATH=\usr\local\bin;%ruby_path%\bin;%PATH%;C:\msys64\mingw64\bin;C:\msys64\usr\bin + - ruby --version + - 'cl' + - echo> Makefile srcdir=. + - echo>> Makefile MSC_VER=0 + - echo>> Makefile RT=none + - echo>> Makefile RT_VER=0 + - echo>> Makefile BUILTIN_ENCOBJS=nul + - type win32\Makefile.sub >> Makefile + - nmake %mflags% up VCSUP="echo Update OK" + - nmake %mflags% extract-extlibs + - del Makefile + - mkdir \usr\local\bin + - mkdir \usr\local\include + - mkdir \usr\local\lib + - for %%I in (%OPENSSL_DIR%\*.dll) do mklink /h \usr\local\bin\%%~nxI %%I + - for %%I in (c:\Tools\vcpkg\installed\%Platform%-windows\bin\*.dll) do ( + if not %%~nI == readline mklink \usr\local\bin\%%~nxI %%I + ) + - attrib +r /s /d + - mkdir %Platform%-mswin_%vs% + build_script: + - set HAVE_GIT=no + - cd %APPVEYOR_BUILD_FOLDER% + - cd %Platform%-mswin_%vs% + - >- + ..\win32\configure.bat + --with-opt-dir="/usr/local;c:/Tools/vcpkg/installed/%Platform%-windows" + --with-openssl-dir=%OPENSSL_DIR:\=/% + - nmake -l + - nmake install-nodoc + - \usr\bin\ruby -v -e "p :locale => Encoding.find('locale'), :filesystem => Encoding.find('filesystem')" + - if not "%GEMS_FOR_TEST%" == "" \usr\bin\gem install --no-document %GEMS_FOR_TEST% + - \usr\bin\ruby -ropenssl -e "puts 'Build ' + OpenSSL::OPENSSL_VERSION, 'Runtime ' + OpenSSL::OPENSSL_LIBRARY_VERSION" + test_script: + - set /a JOBS=%NUMBER_OF_PROCESSORS% + - nmake -l "TESTOPTS=-v -q" btest + - nmake -l "TESTOPTS=-v -q" test-basic + - >- + nmake -l "TESTOPTS=--timeout-scale=3.0 + --excludes=../test/excludes/_appveyor -j%JOBS% + --exclude win32ole + --exclude test_bignum + --exclude test_syntax + --exclude test_open-uri + --exclude test_bundled_ca + " test-all + # separately execute tests without -j which may crash worker with -j. + - >- + nmake -l + "TESTOPTS=--timeout-scale=3.0 --excludes=../test/excludes/_appveyor" + TESTS=" + ../test/win32ole + ../test/ruby/test_bignum.rb + ../test/ruby/test_syntax.rb + ../test/open-uri/test_open-uri.rb + ../test/rubygems/test_bundled_ca.rb + " test-all + - nmake -l test-spec MSPECOPT=-fs # not using `-j` because sometimes `mspec -j` silently dies on Windows +notifications: + - provider: Webhook + method: POST + url: + secure: CcFlJNDJ/a6to7u3Z4Fnz6dScEPNx7hTha2GkSRlV+1U6dqmxY/7uBcLXYb9gR3jfQk6w+2o/HrjNAyXMNGU/JOka3s2WRI4VKitzM+lQ08owvJIh0R7LxrGH0J2e81U # ruby-lang slack: ruby/simpler-alerts-bot + body: >- + {{^isPullRequest}} + { + "ci": "AppVeyor CI", + "env": "Visual Studio 2013", + "url": "{{buildUrl}}", + "commit": "{{commitId}}", + "branch": "{{branch}}" + } + {{/isPullRequest}} + on_build_success: false + on_build_failure: true + on_build_status_changed: false @@ -15,11 +15,10 @@ array.rb ast.rb dir.rb gc.rb -hash.rb io.rb kernel.rb marshal.rb -rjit.rb +mjit.rb numeric.rb nilclass.rb pack.rb @@ -32,9 +31,6 @@ trace_point.rb warning.rb yjit.rb -# Errno::* -known_errors.inc - # the lib/ directory (which has its own .document file) lib @@ -52,4 +48,7 @@ COPYING.ja LEGAL +# win32/README.win32 linked from README.md +win32 + doc @@ -1,3 +1,5 @@ +set startup-with-shell off + define hook-run set $color_type = 0 set $color_highlite = 0 @@ -65,7 +67,7 @@ define rp printf "%sT_OBJECT%s: ", $color_type, $color_end print ((struct RObject *)($arg0))->basic if ($flags & ROBJECT_EMBED) - print/x *((VALUE*)((struct RObject*)($arg0))->as.ary) @ (rb_shape_get_shape($arg0)->capacity) + print/x *((VALUE*)((struct RObject*)($arg0))->as.ary) @ (ROBJECT_EMBED_LEN_MAX+0) else print (((struct RObject *)($arg0))->as.heap) if (((struct RObject*)($arg0))->as.heap.numiv) > 0 @@ -102,8 +104,8 @@ define rp (($rsflags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2) set print address off output *(char *)(($rsflags & RUBY_FL_USER1) ? \ - ((struct RString*)$regsrc)->as.heap.ptr : \ - ((struct RString*)$regsrc)->as.ary) @ $len + ((struct RString*)$regsrc)->as.heap.ptr : \ + ((struct RString*)$regsrc)->as.ary) @ $len set print address on printf " len:%ld ", $len if $flags & RUBY_FL_USER6 @@ -124,26 +126,26 @@ define rp printf "%sT_ARRAY%s: len=%ld ", $color_type, $color_end, $len printf "(embed) " if ($len == 0) - printf "{(empty)} " + printf "{(empty)} " else - print/x *((VALUE*)((struct RArray*)($arg0))->as.ary) @ $len - printf " " + print/x *((VALUE*)((struct RArray*)($arg0))->as.ary) @ $len + printf " " end else set $len = ((struct RArray*)($arg0))->as.heap.len printf "%sT_ARRAY%s: len=%ld ", $color_type, $color_end, $len if ($flags & RUBY_FL_USER2) - printf "(shared) shared=" - output/x ((struct RArray*)($arg0))->as.heap.aux.shared_root - printf " " + printf "(shared) shared=" + output/x ((struct RArray*)($arg0))->as.heap.aux.shared_root + printf " " else - printf "(ownership) capa=%ld ", ((struct RArray*)($arg0))->as.heap.aux.capa + printf "(ownership) capa=%ld ", ((struct RArray*)($arg0))->as.heap.aux.capa end if ($len == 0) - printf "{(empty)} " + printf "{(empty)} " else - print/x *((VALUE*)((struct RArray*)($arg0))->as.heap.ptr) @ $len - printf " " + print/x *((VALUE*)((struct RArray*)($arg0))->as.heap.ptr) @ $len + printf " " end end print (struct RArray *)($arg0) @@ -443,8 +445,8 @@ define output_string (($flags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2) if $len > 0 output *(char *)(($flags & RUBY_FL_USER1) ? \ - ((struct RString*)($arg0))->as.heap.ptr : \ - ((struct RString*)($arg0))->as.ary) @ $len + ((struct RString*)($arg0))->as.heap.ptr : \ + ((struct RString*)($arg0))->as.ary) @ $len else output "" end @@ -457,8 +459,8 @@ define print_string (($flags & (RUBY_FL_USER2|RUBY_FL_USER3|RUBY_FL_USER4|RUBY_FL_USER5|RUBY_FL_USER6)) >> RUBY_FL_USHIFT+2) if $len > 0 printf "%s", *(char *)(($flags & RUBY_FL_USER1) ? \ - ((struct RString*)($arg0))->as.heap.ptr : \ - ((struct RString*)($arg0))->as.ary) @ $len + ((struct RString*)($arg0))->as.heap.ptr : \ + ((struct RString*)($arg0))->as.ary) @ $len end end @@ -687,6 +689,11 @@ define nd_stts end +define nd_entry + printf "%su3.entry%s: ", $color_highlite, $color_end + p ($arg0).u3.entry +end + define nd_vid printf "%su1.id%s: ", $color_highlite, $color_end p ($arg0).u1.id @@ -861,22 +868,22 @@ define rb_numtable_entry set $rb_numtable_p = $rb_numtable_tbl->as.packed.bins while $rb_numtable_p && $rb_numtable_p < $rb_numtable_tbl->as.packed.bins+$rb_numtable_tbl->num_entries if $rb_numtable_p.k == $rb_numtable_id - set $rb_numtable_key = $rb_numtable_p.k - set $rb_numtable_rec = $rb_numtable_p.v - set $rb_numtable_p = 0 + set $rb_numtable_key = $rb_numtable_p.k + set $rb_numtable_rec = $rb_numtable_p.v + set $rb_numtable_p = 0 else - set $rb_numtable_p = $rb_numtable_p + 1 + set $rb_numtable_p = $rb_numtable_p + 1 end end else set $rb_numtable_p = $rb_numtable_tbl->as.big.bins[st_numhash($rb_numtable_id) % $rb_numtable_tbl->num_bins] while $rb_numtable_p if $rb_numtable_p->key == $rb_numtable_id - set $rb_numtable_key = $rb_numtable_p->key - set $rb_numtable_rec = $rb_numtable_p->record - set $rb_numtable_p = 0 + set $rb_numtable_key = $rb_numtable_p->key + set $rb_numtable_rec = $rb_numtable_p->record + set $rb_numtable_p = 0 else - set $rb_numtable_p = $rb_numtable_p->next + set $rb_numtable_p = $rb_numtable_p->next end end end @@ -954,7 +961,7 @@ define iseq set $operand_size = ((INSN*)($arg0))->operand_size set $operands = ((INSN*)($arg0))->operands while $i < $operand_size - rp $operands[$i++] + rp $operands[$i++] end end end @@ -1272,9 +1279,9 @@ document rb_count_objects Counts all objects grouped by type. end -# Details: https://github.com/ruby/ruby/wiki/Machine-Instructions-Trace-with-GDB +# Details: https://bugs.ruby-lang.org/projects/ruby-master/wiki/MachineInstructionsTraceWithGDB define trace_machine_instructions - set logging enabled + set logging on set height 0 set width 0 display/i $pc @@ -1341,8 +1348,3 @@ define print_flags printf "RUBY_FL_USER17 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER17 ? "1" : "0" printf "RUBY_FL_USER18 : %s\n", ((struct RBasic*)($arg0))->flags & RUBY_FL_USER18 ? "1" : "0" end - -source -s misc/gdb.py - -# Moved from beginning, since it fails on older gdbs -set startup-with-shell off diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs index 60721014f7..6c5eac5a0f 100644 --- a/.git-blame-ignore-revs +++ b/.git-blame-ignore-revs @@ -5,10 +5,6 @@ # Expand tabs 5b21e94bebed90180d8ff63dad03b8b948361089 -c5e9af9c9d890578182a21e7b71b50334cd5579e -e63a2115f64433b21cb5dd67c5bf8b30f87ef293 -712ac99e4d0384a941c80a9f48f62943ba7d97c0 -d1474affa8e105bece209cc9d594bb0a989859e1 # Enable Style/StringLiterals cop for RubyGems/Bundler d7ffd3fea402239b16833cc434404a7af82d44f3 @@ -25,11 +21,3 @@ f28287d34c03f472ffe90ea262bdde9affd4b965 # Make benchmark indentation consistent fc4acf8cae82e5196186d3278d831f2438479d91 - -# Make prism_compile.c indentation consistent -40b2c8e5e7e6e5f83cee9276dc9c1922a69292d6 -d2c5867357ed88eccc28c2b3bd4a46e206e7ff85 - -# Miss-and-revived commits -a0f7de814ae5c299d6ce99bed5fb308a05d50ba0 -d4e24021d39e1f80f0055b55d91f8d5f22e15084 diff --git a/.github/actions/compilers/action.yml b/.github/actions/compilers/action.yml deleted file mode 100644 index aa23365e49..0000000000 --- a/.github/actions/compilers/action.yml +++ /dev/null @@ -1,101 +0,0 @@ -name: Compiles ruby in a container -description: >- - Makes ruby using a dedicated container - -inputs: - tag: - required: false - default: clang-18 - description: >- - container image tag to use in this run. - - with_gcc: - required: false - description: >- - override compiler path & flags. - - CFLAGS: - required: false - description: >- - C compiler flags to override. - - CXXFLAGS: - required: false - description: >- - C++ compiler flags to override. - - optflags: - required: false - # -O1 is faster than -O3 in our tests... Majority of time are consumed trying - # to optimize binaries. Also GitHub Actions run on relatively modern CPUs - # compared to, say, GCC 4 or Clang 3. We don't specify `-march=native` - # because compilers tend not understand what the CPU is. - default: '-O1' - description: >- - Compiler flags for optimisations. - - cppflags: - required: false - description: >- - Additional preprocessor flags. - - append_configure: - required: false - default: >- - --without-valgrind - --without-jemalloc - --without-gmp - description: >- - flags to append to configure. - - enable_shared: - required: false - default: true - description: >- - Whether to build libruby.so. - - check: - required: false - default: '' - description: >- - Whether to run `make check` - - mspecopt: - required: false - default: '' - description: >- - Additional options for mspec. - - static_exts: - required: false - description: >- - whitespace separated list of extensions that need be linked statically. - -runs: - using: composite - steps: - - shell: bash - run: docker pull --quiet 'ghcr.io/ruby/ruby-ci-image:${{ inputs.tag }}' - - - name: compile - shell: bash - run: >- - docker run - --rm - --user=root - --volume '${{ github.workspace }}:/github/workspace:ro' - --workdir=/github/workspace - --entrypoint=/github/workspace/.github/actions/compilers/entrypoint.sh - --env CI - --env GITHUB_ACTION - --env INPUT_WITH_GCC='${{ inputs.with_gcc || inputs.tag }}' - --env INPUT_CFLAGS='${{ inputs.CFLAGS }}' - --env INPUT_CXXFLAGS='${{ inputs.CXXFLAGS }}' - --env INPUT_OPTFLAGS='${{ inputs.OPTFLAGS }}' - --env INPUT_CPPFLAGS='${{ inputs.cppflags }}' - --env INPUT_APPEND_CONFIGURE='${{ inputs.append_configure }}' - --env INPUT_CHECK='${{ inputs.check }}' - --env INPUT_MSPECOPT='${{ inputs.mspecopt }}' - --env INPUT_ENABLE_SHARED='${{ inputs.enable_shared }}' - --env INPUT_STATIC_EXTS='${{ inputs.static_exts }}' - 'ghcr.io/ruby/ruby-ci-image:${{ inputs.tag }}' diff --git a/.github/actions/compilers/entrypoint.sh b/.github/actions/compilers/entrypoint.sh deleted file mode 100755 index 198ac0e174..0000000000 --- a/.github/actions/compilers/entrypoint.sh +++ /dev/null @@ -1,96 +0,0 @@ -#! /bin/bash - -# Copyright (c) 2024 Ruby developers. All rights reserved. -# -# This file is a part of the programming language Ruby. Permission is hereby -# granted, to either redistribute and/or modify this file, provided that the -# conditions mentioned in the file COPYING are met. Consult the file for -# details. - -grouped() -{ - echo "::group::${@}" - "${@}" - echo "::endgroup::" -} - -set -e -set -u -set -o pipefail - -srcdir="/github/workspace/src" -builddir="$(mktemp -dt)" - -export GITHUB_WORKFLOW='Compilations' -export CONFIGURE_TTY='never' -export RUBY_DEBUG='ci rgengc' -export RUBY_TESTOPTS='-q --color=always --tty=no' -export RUBY_DEBUG_COUNTER_DISABLE='1' -export GNUMAKEFLAGS="-j$((1 + $(nproc --all)))" - -case "x${INPUT_ENABLE_SHARED}" in -x | xno | xfalse ) - enable_shared='--disable-shared' - ;; -*) - enable_shared='--enable-shared' - ;; -esac - -pushd ${builddir} - -grouped ${srcdir}/configure \ - -C \ - --with-gcc="${INPUT_WITH_GCC}" \ - --enable-debug-env \ - --disable-install-doc \ - --with-ext=-test-/cxxanyargs,+ \ - ${enable_shared} \ - ${INPUT_APPEND_CONFIGURE} \ - CFLAGS="${INPUT_CFLAGS}" \ - CXXFLAGS="${INPUT_CXXFLAGS}" \ - optflags="${INPUT_OPTFLAGS}" \ - cppflags="${INPUT_CPPFLAGS}" \ - debugflags='-ggdb3' # -g0 disables backtraces when SEGV. Do not set that. - -popd - -if [[ -n "${INPUT_STATIC_EXTS}" ]]; then - echo "::group::ext/Setup" - set -x - mkdir ${builddir}/ext - ( - for ext in ${INPUT_STATIC_EXTS}; do - echo "${ext}" - done - ) >> ${builddir}/ext/Setup - set +x - echo "::endgroup::" -fi - -pushd ${builddir} - -case "${INPUT_APPEND_CONFIGURE}" in -*--with-shared-gc*) - export RUBY_GC_LIBRARY='librubygc.default.so' - mkdir -p /home/runner/shared-gc - grouped make shared-gc SHARED_GC=default - ;; -esac - -grouped make showflags -grouped make all -grouped make test - -[[ -z "${INPUT_CHECK}" ]] && exit 0 - -if [ "$INPUT_CHECK" = "true" ]; then - tests="ruby -ext-" -else - tests="$INPUT_CHECK" -fi - -grouped make install -grouped make test-tool -grouped make test-all TESTS="-- $tests" -grouped env CHECK_LEAKS=true make test-spec MSPECOPT="$INPUT_MSPECOPT" diff --git a/.github/actions/launchable/setup/action.yml b/.github/actions/launchable/setup/action.yml deleted file mode 100644 index 4b469ccd64..0000000000 --- a/.github/actions/launchable/setup/action.yml +++ /dev/null @@ -1,165 +0,0 @@ -name: Set up Launchable -description: >- - Install the required dependencies and execute the necessary Launchable commands for test recording - -inputs: - report-path: - default: launchable_reports.json - required: true - description: The file path of the test report for uploading to Launchable - - os: - required: true - description: The operating system that CI runs on. This value is used in Launchable flavor. - - test-opts: - default: none - required: false - description: >- - Test options that determine how tests are run. - This value is used in the Launchable flavor. - - launchable-token: - required: false - description: >- - Launchable token is needed if you want to run Launchable on your forked repository. - See https://github.com/ruby/ruby/wiki/CI-Servers#launchable-ci for details. - - builddir: - required: false - default: ${{ github.workspace }} - description: >- - Directory to create Launchable report file. - - srcdir: - required: false - default: ${{ github.workspace }} - description: >- - Directory to (re-)checkout source codes. Launchable retrives the commit information - from the directory. - - launchable-workspace: - required: true - default: ${{ github.event.repository.name }} - description: >- - A workspace name in Launchable - - test-task: - required: true - default: ${{ matrix.test_task }} - description: >- - A test task that determine which tests are executed. - This value is used in the Launchable flavor. - -runs: - using: composite - - steps: - - name: Enable Launchable conditionally - id: enable-launchable - run: echo "enable-launchable=true" >> $GITHUB_OUTPUT - shell: bash - if: >- - ${{ - (github.repository == 'ruby/ruby' || - (github.repository != 'ruby/ruby' && env.LAUNCHABLE_TOKEN)) && - (inputs.test-task == 'check' || - inputs.test-task == 'test-all' || - inputs.test-task == 'test') - }} - - # Launchable CLI requires Python and Java. - # https://www.launchableinc.com/docs/resources/cli-reference/ - - name: Set up Python - uses: actions/setup-python@871daa956ca9ea99f3c3e30acb424b7960676734 # v5.0.0 - with: - python-version: "3.x" - if: steps.enable-launchable.outputs.enable-launchable - - - name: Set up Java - uses: actions/setup-java@7a445ee88d4e23b52c33fdc7601e40278616c7f8 # v4.0.0 - with: - distribution: 'temurin' - java-version: '17' - if: steps.enable-launchable.outputs.enable-launchable - - - name: Set environment variables for Launchable - shell: bash - run: | - : # GITHUB_PULL_REQUEST_URL are used for commenting test reports in Launchable Github App. - : # https://github.com/launchableinc/cli/blob/v1.80.1/launchable/utils/link.py#L42 - echo "GITHUB_PULL_REQUEST_URL=${{ github.event.pull_request.html_url }}" >> $GITHUB_ENV - : # The following envs are necessary in Launchable tokenless authentication. - : # https://github.com/launchableinc/cli/blob/v1.80.1/launchable/utils/authentication.py#L20 - echo "LAUNCHABLE_ORGANIZATION=${{ github.repository_owner }}" >> $GITHUB_ENV - echo "LAUNCHABLE_WORKSPACE=${{ inputs.launchable-workspace }}" >> $GITHUB_ENV - : # https://github.com/launchableinc/cli/blob/v1.80.1/launchable/utils/authentication.py#L71 - echo "GITHUB_PR_HEAD_SHA=${{ github.event.pull_request.head.sha || github.sha }}" >> $GITHUB_ENV - echo "LAUNCHABLE_TOKEN=${{ inputs.launchable-token }}" >> $GITHUB_ENV - if: steps.enable-launchable.outputs.enable-launchable - - - name: Set up path - shell: bash - working-directory: ${{ inputs.srcdir }} - # Since updated PATH variable will be available in only subsequent actions, we need to add the path beforehand. - # https://docs.github.com/en/actions/using-workflows/workflow-commands-for-github-actions#adding-a-system-path - run: echo "$(python -msite --user-base)/bin" >> $GITHUB_PATH - if: steps.enable-launchable.outputs.enable-launchable && startsWith(inputs.os, 'macos') - - - name: Set up Launchable - shell: bash - working-directory: ${{ inputs.srcdir }} - run: | - set -x - pip install --user launchable - launchable verify || true - : # The build name cannot include a slash, so we replace the string here. - github_ref="${{ github.ref }}" - github_ref="${github_ref//\//_}" - : # With the --name option, we need to configure a unique identifier for this build. - : # To avoid setting the same build name as the CI which runs on other branches, we use the branch name here. - : # - : # FIXME: Need to fix `WARNING: Failed to process a change to a file`. - : # https://github.com/launchableinc/cli/issues/786 - launchable record build --name ${github_ref}_${GITHUB_PR_HEAD_SHA} - echo "TESTS=${TESTS} --launchable-test-reports=${{ inputs.report-path }}" >> $GITHUB_ENV - if: steps.enable-launchable.outputs.enable-launchable - - - name: Variables to report Launchable - id: variables - shell: bash - run: | - set -x - : # flavor - test_opts="${{ inputs.test-opts }}" - test_opts="${test_opts// /}" - test_opts="${test_opts//=/:}" - echo test-opts="$test_opts" >> $GITHUB_OUTPUT - : # report-path from srcdir - if [ "${srcdir}" = "${{ github.workspace }}" ]; then - dir= - else - # srcdir must be equal to or under workspace - dir=$(echo ${srcdir:+${srcdir}/} | sed 's:[^/][^/]*/:../:g') - fi - report_path="${dir}${builddir:+${builddir}/}${report_path}" - echo report-path="${report_path}" >> $GITHUB_OUTPUT - if: steps.enable-launchable.outputs.enable-launchable - env: - srcdir: ${{ inputs.srcdir }} - builddir: ${{ inputs.builddir }} - report_path: ${{ inputs.report-path }} - - - name: Record test results in Launchable - uses: gacts/run-and-post-run@674528335da98a7afc80915ff2b4b860a0b3553a # v1.4.0 - with: - shell: bash - working-directory: ${{ inputs.srcdir }} - post: | - : # record - launchable record tests --flavor os=${{ inputs.os }} --flavor test_task=${{ inputs.test-task }} --flavor test_opts=${test_opts} raw ${report_path} - rm -f ${report_path} - if: ${{ always() && steps.enable-launchable.outputs.enable-launchable }} - env: - test_opts: ${{ steps.variables.outputs.test-opts }} - report_path: ${{ steps.variables.outputs.report-path }} diff --git a/.github/actions/setup/directories/action.yml b/.github/actions/setup/directories/action.yml deleted file mode 100644 index d54c0f93f8..0000000000 --- a/.github/actions/setup/directories/action.yml +++ /dev/null @@ -1,176 +0,0 @@ -name: Setup directories etc. -description: >- - Set up the source code and build directories (plus some - environmental tweaks) - -inputs: - srcdir: - required: false - default: ${{ github.workspace }} - description: >- - Directory to (re-)checkout source codes. This will be created - if absent. If there is no `configure` file that is also - generated inside. - - builddir: - required: false - default: ${{ github.workspace }} - description: >- - Where binaries and other generated contents go. This will be - created if absent. - - makeup: - required: false - type: boolean - # Note that `default: false` evaluates to a string constant - # `'false'`, which is a truthy value :sigh: - # https://github.com/actions/runner/issues/2238 - default: '' - description: >- - If set to true, additionally runs `make up`. - - checkout: - required: false - type: boolean - default: true - description: >- - If set to '' (false), skip running actions/checkout. This is useful when - you don't want to overwrite a GitHub token that is already set up. - - dummy-files: - required: false - type: boolean - default: '' - description: >- - If set to true, creates dummy files in build dir. - - fetch-depth: - required: false - default: '1' - description: The depth of commit history fetched from the remote repository - - clean: - required: false - type: boolean - default: '' - description: >- - If set to true, clean build directory. - -outputs: {} # nothing? - -runs: - using: composite - - steps: - # Note that `shell: bash` works on both Windows and Linux, but not - # `shell: sh`. This is because GitHub hosted Windows runners have - # their bash manually installed. - - shell: bash - run: | - mkdir -p ${{ inputs.srcdir }} - mkdir -p ${{ inputs.builddir }} - - # Did you know that actions/checkout works without git(1)? We are - # checking that here. - - id: which - shell: bash - run: | - echo "git=`command -v git`" >> "$GITHUB_OUTPUT" - echo "sudo=`command -v sudo`" >> "$GITHUB_OUTPUT" - echo "autoreconf=`command -v autoreconf`" >> "$GITHUB_OUTPUT" - - - if: steps.which.outputs.git - shell: bash - 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 - - - if: inputs.checkout - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: - path: ${{ inputs.srcdir }} - fetch-depth: ${{ inputs.fetch-depth }} - - - uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2 - with: - path: ${{ inputs.srcdir }}/.downloaded-cache - key: downloaded-cache - - - if: steps.which.outputs.autoreconf - shell: bash - working-directory: ${{ inputs.srcdir }} - run: ./autogen.sh --install - - # This is for MinGW. - - if: runner.os == 'Windows' - shell: bash - run: echo "GNUMAKEFLAGS=-j$((2 * NUMBER_OF_PROCESSORS))" >> $GITHUB_ENV - - - if: runner.os == 'Linux' - shell: bash - run: echo "GNUMAKEFLAGS=-sj$((1 + $(nproc --all)))" >> "$GITHUB_ENV" - - # macOS' GNU make is so old that they doesn't understand `GNUMAKEFLAGS`. - - if: runner.os == 'macOS' - shell: bash - run: echo "MAKEFLAGS=-j$((1 + $(sysctl -n hw.activecpu)))" >> "$GITHUB_ENV" - - - if: inputs.makeup - shell: bash - working-directory: ${{ inputs.srcdir }} - run: | - touch config.status - touch .rbconfig.time - sed -f tool/prereq.status template/Makefile.in > Makefile - sed -f tool/prereq.status template/GNUmakefile.in > GNUmakefile - make up - - # Cleanup, runs even on failure - - if: always() && inputs.makeup - shell: bash - working-directory: ${{ inputs.srcdir }} - run: rm -f config.status Makefile rbconfig.rb .rbconfig.time - - - if: steps.which.outputs.sudo - shell: bash - run: | - sudo chmod -R go-w /usr/share - chmod -v go-w $HOME $HOME/.config || : - SAVE_IFS="$IFS" IFS=:; set $PATH; dirs=() IFS="$SAVE_IFS" - for d do [ ! -d "$d" ] || dirs+=("$d"); done - sudo chmod -v go-w "${dirs[@]}" || : - - - if: inputs.dummy-files == 'true' - shell: bash - id: dummy-files - working-directory: ${{ inputs.builddir }} - run: | - : Create dummy files in build dir - set {{a..z},{A..Z},{0..9},foo,bar,test,zzz}.rb - for file; do \ - echo > $file "raise 'do not load $file'"; \ - done - # drop {a..z}.rb if case-insensitive filesystem - grep -F A.rb a.rb > /dev/null && set "${@:27}" - echo clean="cd ${{ inputs.builddir }} && rm $*" >> $GITHUB_OUTPUT - - - if: inputs.clean == 'true' - shell: bash - id: clean - run: | - echo distclean='make -C ${{ inputs.builddir }} distclean' >> $GITHUB_OUTPUT - echo remained-files='find ${{ inputs.builddir }} -ls' >> $GITHUB_OUTPUT - [ "${{ inputs.builddir }}" = "${{ inputs.srcdir }}" ] || - echo final='rmdir ${{ inputs.builddir }}' >> $GITHUB_OUTPUT - - - name: clean - uses: gacts/run-and-post-run@4683764dd706df847f57b9bed39d08164bcd2690 # v1.4.1 - with: - working-directory: - post: | - ${{ steps.dummy-files.outputs.clean }} - ${{ steps.clean.outputs.distclean }} - ${{ steps.clean.outputs.remained-files }} - ${{ steps.clean.outputs.final }} diff --git a/.github/actions/setup/macos/action.yml b/.github/actions/setup/macos/action.yml deleted file mode 100644 index 24ba48139a..0000000000 --- a/.github/actions/setup/macos/action.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Setup macOS environment -description: >- - Installs necessary packages via Homebrew. - -inputs: {} # nothing? - -outputs: {} # nothing? - -runs: - using: composite - - steps: - - name: brew - shell: bash - run: | - brew install --quiet gmp libffi openssl@3 zlib autoconf automake libtool - - - name: Set ENV - shell: bash - run: | - for lib in gmp; do - ruby_configure_args="${ruby_configure_args:+$ruby_configure_args }--with-${lib%@*}-dir=$(brew --prefix $lib)" - done - for lib in openssl@3; do - CONFIGURE_ARGS="${CONFIGURE_ARGS:+$CONFIGURE_ARGS }--with-${lib%@*}-dir=$(brew --prefix $lib)" - done - echo ruby_configure_args="${ruby_configure_args}" >> $GITHUB_ENV - echo CONFIGURE_ARGS="${CONFIGURE_ARGS}" >> $GITHUB_ENV diff --git a/.github/actions/setup/ubuntu/action.yml b/.github/actions/setup/ubuntu/action.yml deleted file mode 100644 index a9e5b41951..0000000000 --- a/.github/actions/setup/ubuntu/action.yml +++ /dev/null @@ -1,53 +0,0 @@ -name: Setup ubuntu environment -description: >- - At the beginning there was no way but to copy & paste `apt-get` - everywhere. But now that we have composite actions, it seems better - merge them into one. - -inputs: - arch: - required: false - default: '' - description: >- - Architecture. Because we run this on a GitHub-hosted runner - acceptable value for this input is very limited. - -outputs: - arch: - value: ${{ steps.uname.outputs.uname }} - description: >- - Actual architecture. This could be different from the one - passed to the `inputs.arch`. For instance giving `i386` to this - action yields `i686`. - -runs: - using: composite - - steps: - - name: set SETARCH - shell: bash - run: echo "SETARCH=${setarch}" >> "$GITHUB_ENV" - env: - setarch: ${{ inputs.arch && format('setarch {0} --', inputs.arch) }} - - - id: uname - name: uname - shell: bash - run: | - echo uname=`${SETARCH} uname -m` >> "$GITHUB_OUTPUT" - echo dpkg=`${SETARCH} uname -m | sed s/686/386/` >> "$GITHUB_OUTPUT" - - - name: apt-get - shell: bash - env: - arch: ${{ inputs.arch && format(':{0}', steps.uname.outputs.dpkg) || '' }} - run: | - set -x - ${arch:+sudo dpkg --add-architecture ${arch#:}} - sudo apt-get update -qq || : - sudo apt-get install --no-install-recommends -qq -y -o=Dpkg::Use-Pty=0 \ - ${arch:+cross}build-essential${arch/:/-} \ - libssl-dev${arch} libyaml-dev${arch} libreadline6-dev${arch} \ - zlib1g-dev${arch} libncurses5-dev${arch} libffi-dev${arch} \ - autoconf ruby - sudo apt-get install -qq -y pkg-config${arch} || : diff --git a/.github/actions/slack/action.yml b/.github/actions/slack/action.yml deleted file mode 100644 index f0481f5bc2..0000000000 --- a/.github/actions/slack/action.yml +++ /dev/null @@ -1,39 +0,0 @@ -name: Post a message to slack -description: >- - We have our ruby/action-slack webhook. However its arguments are - bit verbose to be listed in every workflow files. Better merge them - into one. - -inputs: - SLACK_WEBHOOK_URL: - required: true - description: >- - The URL to post the payload. This is an input because it tends - to be stored in a secrets valut and a composite action cannot - look into one. - - label: - required: false - description: >- - Human-readable description of the run, something like "DEBUG=1". - This need not be unique among runs. - -outputs: {} # Nothing? - -runs: - using: composite - - steps: - - uses: ruby/action-slack@54175162371f1f7c8eb94d7c8644ee2479fcd375 # v3.2.2 - with: - payload: | - { - "ci": "GitHub Actions", - "env": "${{ github.workflow }}${{ inputs.label && format(' / {0}', inputs.label) }}", - "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}", - "commit": "${{ github.sha }}", - "branch": "${{ github.ref_name }}" - } - env: - SLACK_WEBHOOK_URL: ${{ inputs.SLACK_WEBHOOK_URL }} - if: ${{github.event_name == 'push' && startsWith(github.repository, 'ruby/')}} diff --git a/.github/auto_request_review.yml b/.github/auto_request_review.yml deleted file mode 100644 index 8726df577d..0000000000 --- a/.github/auto_request_review.yml +++ /dev/null @@ -1,13 +0,0 @@ -files: - 'yjit*': [team:yjit] - 'yjit/**/*': [team:yjit] - 'yjit/src/cruby_bindings.inc.rs': [] - 'doc/yjit/*': [team:yjit] - 'bootstraptest/test_yjit*': [team:yjit] - 'test/ruby/test_yjit*': [team:yjit] -options: - ignore_draft: true - # This currently doesn't work as intended. We want to skip reviews when only - # cruby_bingings.inc.rs is modified, but this skips reviews even when other - # yjit files are modified as well. To be enabled after fixing the behavior. - #last_files_match_only: true diff --git a/.github/codeql/codeql-config.yml b/.github/codeql/codeql-config.yml new file mode 100644 index 0000000000..91f82b842b --- /dev/null +++ b/.github/codeql/codeql-config.yml @@ -0,0 +1,3 @@ +name: "CodeQL config for the Ruby language" + +languages: cpp diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 426893be2a..bc63aca35b 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,16 +3,4 @@ updates: - package-ecosystem: 'github-actions' directory: '/' schedule: - interval: 'daily' - - package-ecosystem: 'github-actions' - directory: '/.github/actions/slack' - schedule: - interval: 'daily' - - package-ecosystem: 'github-actions' - directory: '/.github/actions/setup/directories' - schedule: - interval: 'daily' - - package-ecosystem: 'cargo' - directory: '/yjit' - schedule: - interval: 'daily' + interval: 'monthly' diff --git a/.github/workflows/annocheck.yml b/.github/workflows/annocheck.yml deleted file mode 100644 index c9fefbb022..0000000000 --- a/.github/workflows/annocheck.yml +++ /dev/null @@ -1,112 +0,0 @@ -name: Annocheck - -on: - push: - paths-ignore: - - 'doc/**' - - '**/man/*' - - '**.md' - - '**.rdoc' - - '**/.document' - - '.*.yml' - pull_request: - paths-ignore: - - 'doc/**' - - '**/man/*' - - '**.md' - - '**.rdoc' - - '**/.document' - - '.*.yml' - merge_group: - -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: - compile: - name: test-annocheck - - runs-on: ubuntu-latest - - container: - image: ghcr.io/ruby/ruby-ci-image:gcc-11 - options: --user root - - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - - env: - CONFIGURE_TTY: never - GITPULLOPTIONS: --no-tags origin ${{ github.ref }} - RUBY_DEBUG: ci rgengc - RUBY_TESTOPTS: >- - -q - --color=always - --tty=no - # 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 --skip-gaps' - - steps: - - run: id - working-directory: - - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: - sparse-checkout-cone-mode: false - sparse-checkout: /.github - - - uses: ./.github/actions/setup/directories - with: - srcdir: src - builddir: build - makeup: true - - - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 - with: - ruby-version: '3.0' - bundler: none - - # Minimal flags to pass the check. - # -g0 disables backtraces when SEGV. Do not set that. - - name: Run configure - run: > - ../src/configure -C - --enable-debug-env - --disable-install-doc - --with-ext=-test-/cxxanyargs,+ - --without-valgrind - --without-jemalloc - --without-gmp - --with-gcc="gcc-11 -fcf-protection -Wa,--generate-missing-build-notes=yes" - --enable-shared - debugflags=-ggdb3 - optflags=-O2 - LDFLAGS=-Wl,-z,now - - - run: make showflags - - - run: make - - - run: make test-annocheck - - - uses: ./.github/actions/slack - with: - SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() }} - -defaults: - run: - working-directory: build diff --git a/.github/workflows/auto_request_review.yml b/.github/workflows/auto_request_review.yml deleted file mode 100644 index ca27244b46..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' && github.base_ref == 'master' }} - steps: - - name: Request review based on files changes and/or groups the author belongs to - uses: necojackarc/auto-request-review@e89da1a8cd7c8c16d9de9c6e763290b6b0e3d424 # v0.13.0 - with: - # scope: public_repo - token: ${{ secrets.MATZBOT_GITHUB_TOKEN }} diff --git a/.github/workflows/baseruby.yml b/.github/workflows/baseruby.yml index 3894c85d97..ebaafe3bf0 100644 --- a/.github/workflows/baseruby.yml +++ b/.github/workflows/baseruby.yml @@ -4,20 +4,24 @@ on: push: paths-ignore: - 'doc/**' - - '**/man/*' + - '**/man' - '**.md' - '**.rdoc' - '**/.document' - - '.*.yml' pull_request: paths-ignore: - 'doc/**' - - '**/man/*' + - '**/man' - '**.md' - '**.rdoc' - '**/.document' - - '.*.yml' merge_group: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' concurrency: group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} @@ -29,49 +33,48 @@ permissions: jobs: baseruby: name: BASERUBY - - runs-on: ubuntu-20.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.event.pull_request.user.login == 'dependabot[bot]') - )}} - + runs-on: ubuntu-22.04 + if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }} strategy: matrix: ruby: + - ruby-2.2 +# - ruby-2.3 +# - ruby-2.4 +# - ruby-2.5 +# - ruby-2.6 +# - ruby-2.7 - ruby-3.0 - ruby-3.1 - - ruby-3.2 - - ruby-3.3 steps: - - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 + - 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@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0 with: ruby-version: ${{ matrix.ruby }} bundler: none - - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - - - uses: ./.github/actions/setup/ubuntu - - - uses: ./.github/actions/setup/directories - with: - makeup: true - + - run: echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV + - run: sudo apt-get install build-essential autoconf bison libyaml-dev + - run: ./autogen.sh - run: ./configure --disable-install-doc - + - run: make common-srcs + - run: make incs - run: make all - - run: make test - - - uses: ./.github/actions/slack + - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1 with: - label: ${{ matrix.ruby }} + payload: | + { + "ci": "GitHub Actions", + "env": "${{ github.workflow }} / BASERUBY @ ${{ matrix.ruby }}", + "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() }} + if: ${{ failure() && github.event_name == 'push' }} diff --git a/.github/workflows/bundled_gems.yml b/.github/workflows/bundled_gems.yml index 7d452ea876..070c0fa1dd 100644 --- a/.github/workflows/bundled_gems.yml +++ b/.github/workflows/bundled_gems.yml @@ -2,48 +2,54 @@ name: bundled_gems on: push: - branches: ['master'] + branches: [ "master" ] paths: - '.github/workflows/bundled_gems.yml' - 'gems/bundled_gems' pull_request: - branches: ['master'] + branches: [ "master" ] paths: - '.github/workflows/bundled_gems.yml' - 'gems/bundled_gems' merge_group: + branches: [ "master" ] + paths: + - '.github/workflows/bundled_gems.yml' + - 'gems/bundled_gems' schedule: - cron: '45 6 * * *' workflow_dispatch: -permissions: # added using https://github.com/step-security/secure-workflows +permissions: # added using https://github.com/step-security/secure-workflows contents: read jobs: update: permissions: - contents: write # for Git to git push - + contents: write # for Git to git push if: ${{ github.event_name != 'schedule' || github.repository == 'ruby/ruby' }} - name: update ${{ github.workflow }} - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: - token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - - uses: ./.github/actions/setup/directories - with: - # Skip overwriting MATZBOT_GITHUB_TOKEN - checkout: '' # false (ref: https://github.com/actions/runner/issues/2238) + - name: git config + run: | + git config --global advice.detachedHead 0 + git config --global init.defaultBranch garbage - name: Set ENV run: | + echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV echo "TODAY=$(date +%F)" >> $GITHUB_ENV + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + with: + path: .downloaded-cache + key: downloaded-cache-${{ github.sha }} + restore-keys: | + downloaded-cache + - name: Download previous gems list run: | data=bundled_gems.json @@ -52,84 +58,109 @@ jobs: curl -O -R -z ./$data https://stdgems.org/$data - name: Update bundled gems list - id: bundled_gems - run: | - ruby -i~ tool/update-bundled_gems.rb gems/bundled_gems >> $GITHUB_OUTPUT - - - name: Update spec/bundler/support/builders.rb run: | - #!ruby - rake_version = File.read("gems/bundled_gems")[/^rake\s+(\S+)/, 1] - print ARGF.read.sub(/^ *def rake_version\s*\K".*?"/) {rake_version.dump} - shell: ruby -i~ {0} spec/bundler/support/builders.rb + ruby -i~ tool/update-bundled_gems.rb gems/bundled_gems - name: Maintain updated gems list in NEWS run: | - ruby tool/update-NEWS-gemlist.rb bundled + #!ruby + require 'json' + news = File.read("NEWS.md") + prev = news[/since the \*+(\d+\.\d+\.\d+)\*+/, 1] + prevs = [prev, prev.sub(/\.\d+\z/, '')] + %W[bundled].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 + changed, added = changed.partition {|g, _| last[g]} + news.sub!(/^\*( +)The following #{type} gems? are updated\.\n+\K(?: \1\*( +).*\n)*/) do + mark = "#{$1} *#{$2}" + changed.map {|g, v|"#{mark}#{g} #{v}\n"}.join("") + end or next + 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 unless added.empty? + File.write("NEWS.md", news) + end + shell: ruby {0} - name: Check diffs id: diff run: | - news= gems= - git diff --color --no-ext-diff --ignore-submodules --exit-code -- NEWS.md || - news=true - git diff --color --no-ext-diff --ignore-submodules --exit-code -- gems/bundled_gems || - gems=true - git add -- NEWS.md gems/bundled_gems - git add -- spec/bundler/support/builders.rb - echo news=$news >> $GITHUB_OUTPUT - echo gems=$gems >> $GITHUB_OUTPUT - echo update=${news:-$gems} >> $GITHUB_OUTPUT + git add -- NEWS.md + git diff --no-ext-diff --ignore-submodules --quiet -- gems/bundled_gems + continue-on-error: true - name: Install libraries - uses: ./.github/actions/setup/ubuntu - if: ${{ steps.diff.outputs.gems }} + run: | + set -x + sudo apt-get update -q || : + 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 + if: ${{ steps.diff.outcome == 'failure' }} - name: Build run: | ./autogen.sh ./configure -C --disable-install-doc make - if: ${{ steps.diff.outputs.gems }} + if: ${{ steps.diff.outcome == 'failure' }} - name: Prepare bundled gems run: | make -s prepare-gems - if: ${{ steps.diff.outputs.gems }} + if: ${{ steps.diff.outcome == 'failure' }} - name: Test bundled gems run: | make -s test-bundled-gems + git add -- gems/bundled_gems timeout-minutes: 30 env: - RUBY_TESTOPTS: '-q --tty=no' - TEST_BUNDLED_GEMS_ALLOW_FAILURES: 'typeprof' - if: ${{ steps.diff.outputs.gems }} + RUBY_TESTOPTS: "-q --tty=no" + TEST_BUNDLED_GEMS_ALLOW_FAILURES: "" + if: ${{ steps.diff.outcome == 'failure' }} + + - name: Show diffs + id: show + run: | + git diff --cached --color --no-ext-diff --ignore-submodules --exit-code -- + continue-on-error: true - name: Commit run: | git pull --ff-only origin ${GITHUB_REF#refs/heads/} - message="Update bundled gems list" - if [ -z "${gems}" ]; then - git commit --message="${message} at ${GITHUB_SHA:0:30} [ci skip]" + message="Update bundled gems list at " + if [ ${{ steps.diff.outcome }} = success ]; then + git commit --message="${message}${GITHUB_SHA:0:30} [ci skip]" else - git commit --message="${message} as of ${TODAY}" + git commit --message="${message}${TODAY}" fi git push origin ${GITHUB_REF#refs/heads/} env: - TODAY: ${{ steps.bundled_gems.outputs.latest_date || env.TODAY }} EMAIL: svn-admin@ruby-lang.org GIT_AUTHOR_NAME: git GIT_COMMITTER_NAME: git - gems: ${{ steps.diff.outputs.gems }} - if: >- - ${{ - github.repository == 'ruby/ruby' && - !startsWith(github.event_name, 'pull') && - steps.diff.outputs.update - }} - - - uses: ./.github/actions/slack + if: ${{ github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull') && steps.show.outcome == 'failure' }} + + - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1 with: + payload: | + { + "ci": "GitHub Actions", + "env": "${{ github.workflow }} / update", + "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() }} + if: ${{ failure() && github.event_name == 'push' }} diff --git a/.github/workflows/check_dependencies.yml b/.github/workflows/check_dependencies.yml index b416b36597..79b2916feb 100644 --- a/.github/workflows/check_dependencies.yml +++ b/.github/workflows/check_dependencies.yml @@ -3,20 +3,24 @@ on: push: paths-ignore: - 'doc/**' - - '**/man/*' + - '**/man' - '**.md' - '**.rdoc' - '**/.document' - - '.*.yml' pull_request: paths-ignore: - 'doc/**' - - '**/man/*' + - '**/man' - '**.md' - '**.rdoc' - '**/.document' - - '.*.yml' merge_group: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' concurrency: group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} @@ -29,50 +33,46 @@ jobs: update-deps: strategy: matrix: - os: [ubuntu-20.04] + os: [ubuntu-22.04] fail-fast: true - runs-on: ${{ matrix.os }} - - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - + if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }} steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - - - uses: ./.github/actions/setup/ubuntu + - name: Install libraries + run: | + set -x + sudo apt-get update -q || : + 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 if: ${{ contains(matrix.os, 'ubuntu') }} - - - uses: ./.github/actions/setup/macos + - name: Install libraries + run: | + brew install gmp libffi openssl@1.1 zlib autoconf automake libtool readline if: ${{ contains(matrix.os, 'macos') }} - - - uses: ./.github/actions/setup/directories - - - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 + - name: git config + run: | + git config --global advice.detachedHead 0 + git config --global init.defaultBranch garbage + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: - ruby-version: '3.0' - bundler: none - + path: .downloaded-cache + key: downloaded-cache + - run: ./autogen.sh - name: Run configure run: ./configure -C --disable-install-doc --disable-rubygems --with-gcc 'optflags=-O0' 'debugflags=-save-temps=obj -g' - - run: make all golf - - - run: ./goruby -veh - - run: ruby tool/update-deps --fix - - run: git diff --no-ext-diff --ignore-submodules --exit-code - - - uses: ./.github/actions/slack + - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1 with: - label: ${{ matrix.os }} / Dependencies need to update + payload: | + { + "ci": "GitHub Actions", + "env": "${{ matrix.os }} / Dependencies need to update", + "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() }} + if: ${{ failure() && github.event_name == 'push' }} diff --git a/.github/workflows/check_misc.yml b/.github/workflows/check_misc.yml deleted file mode 100644 index 7da7dd0af7..0000000000 --- a/.github/workflows/check_misc.yml +++ /dev/null @@ -1,117 +0,0 @@ -name: Misc -on: [push, pull_request, merge_group] - -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: - name: Miscellaneous checks - - permissions: - contents: write # for Git to git push - - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: - token: ${{ (github.repository == 'ruby/ruby' && !startsWith(github.event_name, 'pull')) && secrets.MATZBOT_GITHUB_TOKEN || secrets.GITHUB_TOKEN }} - - - uses: ./.github/actions/setup/directories - with: - makeup: true - # Skip overwriting MATZBOT_GITHUB_TOKEN - checkout: '' # false (ref: https://github.com/actions/runner/issues/2238) - - - name: Check if C-sources are US-ASCII - run: | - grep -r -n --include='*.[chyS]' --include='*.asm' $'[^\t-~]' -- . && exit 1 || : - - - name: Check for trailing spaces - run: | - git grep -I -n $'[\t ]$' -- '*.rb' '*.[chy]' '*.rs' '*.yml' && exit 1 || : - git grep -n $'^[\t ][\t ]*$' -- '*.md' && exit 1 || : - - - name: Check for bash specific substitution in configure.ac - run: | - git grep -n '\${[A-Za-z_0-9]*/' -- configure.ac && exit 1 || : - - - name: Check for header macros - run: | - fail= - for header in ruby/*.h; do - git grep -l -F -e $header -e HAVE_`echo $header | tr a-z./ A-Z__` -- . > /dev/null && continue - fail=1 - echo $header - done - exit $fail - working-directory: include - - - id: gems - run: true - if: ${{ github.ref == 'refs/heads/master' }} - - - 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 - if: ${{ steps.gems.outcome == 'success' }} - - - 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} - if: ${{ steps.gems.outcome == 'success' }} - - - name: Maintain updated gems list in NEWS - run: | - ruby tool/update-NEWS-gemlist.rb default - if: ${{ steps.gems.outcome == 'success' }} - - - name: Check diffs - id: diff - run: | - git diff --color --no-ext-diff --ignore-submodules --exit-code NEWS.md || - echo update=true >> $GITHUB_OUTPUT - if: ${{ steps.gems.outcome == 'success' }} - - - 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.outputs.update - }} - - - uses: ./.github/actions/slack - with: - SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() }} diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 676047cc9c..8dba76fbe2 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -1,23 +1,20 @@ -name: 'CodeQL' +name: "Code scanning - action" on: - push: - branches: ['master'] - paths-ignore: - - 'doc/**' - - '**/man/*' - - '**.md' - - '**.rdoc' - - '**/.document' - - '.*.yml' - pull_request: - paths-ignore: - - 'doc/**' - - '**/man/*' - - '**.md' - - '**.rdoc' - - '**/.document' - - '.*.yml' + # push: + # paths-ignore: + # - 'doc/**' + # - '**/man' + # - '**.md' + # - '**.rdoc' + # - '**/.document' + # pull_request: + # paths-ignore: + # - 'doc/**' + # - '**/man' + # - '**.md' + # - '**.rdoc' + # - '**/.document' schedule: - cron: '0 12 * * *' workflow_dispatch: @@ -26,96 +23,53 @@ concurrency: group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} -permissions: # added using https://github.com/step-security/secure-workflows +permissions: # added using https://github.com/step-security/secure-workflows contents: read jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest + CodeQL-Build: + + # CodeQL runs on ubuntu-latest and windows-latest permissions: - actions: read # for github/codeql-action/init to get workflow details - contents: read # for actions/checkout to fetch code - security-events: write # for github/codeql-action/autobuild to send a status report + actions: read # for github/codeql-action/init to get workflow details + contents: read # for actions/checkout to fetch code + security-events: write # for github/codeql-action/autobuild to send a status report + runs-on: ubuntu-latest # CodeQL fails to run pull requests from dependabot due to missing write access to upload results. - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} + if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') && github.event.head_commit.pusher.name != 'dependabot[bot]' }} env: enable_install_doc: no - strategy: - fail-fast: false - matrix: - include: - - language: cpp - - language: ruby - steps: - - name: Checkout repository - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - - - name: Install libraries - if: ${{ contains(matrix.os, 'macos') }} - uses: ./.github/actions/setup/macos - - - name: Install libraries - if : ${{ matrix.os == 'ubuntu-latest' }} - uses: ./.github/actions/setup/ubuntu + - name: Install libraries + run: | + set -x + sudo apt-get update -q || : + 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 - - uses: ./.github/actions/setup/directories + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - name: Remove an obsolete rubygems vendored file - if: ${{ matrix.os == 'ubuntu-latest' }} - run: sudo rm /usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + with: + path: .downloaded-cache + key: downloaded-cache - - name: Initialize CodeQL - uses: github/codeql-action/init@6db8d6351fd0be61f9ed8ebd12ccd35dcec51fea # v3.26.11 - with: - languages: ${{ matrix.language }} + - name: Remove an obsolete rubygems vendored file + run: sudo rm /usr/lib/ruby/vendor_ruby/rubygems/defaults/operating_system.rb - - name: Autobuild - uses: github/codeql-action/autobuild@6db8d6351fd0be61f9ed8ebd12ccd35dcec51fea # v3.26.11 + - name: Initialize CodeQL + uses: github/codeql-action/init@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37 + with: + config-file: ./.github/codeql/codeql-config.yml + trap-caching: false - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@6db8d6351fd0be61f9ed8ebd12ccd35dcec51fea # v3.26.11 - with: - category: '/language:${{ matrix.language }}' - upload: False - output: sarif-results + - name: Set ENV + run: echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV - - name: filter-sarif - uses: advanced-security/filter-sarif@f3b8118a9349d88f7b1c0c488476411145b6270d # v1.0.1 - with: - patterns: | - +**/*.rb - -lib/uri/mailto.rb:rb/overly-large-range - -lib/uri/rfc3986_parser.rb:rb/overly-large-range - -lib/bundler/vendor/uri/lib/uri/mailto.rb:rb/overly-large-range - -lib/bundler/vendor/uri/lib/uri/rfc3986_parser.rb:rb/overly-large-range - -test/ruby/test_io.rb:rb/non-constant-kernel-open - -test/open-uri/test_open-uri.rb:rb/non-constant-kernel-open - -test/open-uri/test_ssl.rb:rb/non-constant-kernel-open - -spec/ruby/core/io/binread_spec.rb:rb/non-constant-kernel-open - -spec/ruby/core/io/readlines_spec.rb:rb/non-constant-kernel-open - -spec/ruby/core/io/foreach_spec.rb:rb/non-constant-kernel-open - -spec/ruby/core/io/write_spec.rb:rb/non-constant-kernel-open - -spec/ruby/core/io/read_spec.rb:rb/non-constant-kernel-open - -spec/ruby/core/kernel/open_spec.rb:rb/non-constant-kernel-open - input: sarif-results/${{ matrix.language }}.sarif - output: sarif-results/${{ matrix.language }}.sarif - if: ${{ matrix.language == 'ruby' }} - continue-on-error: true + - name: Autobuild + uses: github/codeql-action/autobuild@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37 - - name: Upload SARIF - uses: github/codeql-action/upload-sarif@6db8d6351fd0be61f9ed8ebd12ccd35dcec51fea # v3.26.11 - with: - sarif_file: sarif-results/${{ matrix.language }}.sarif - continue-on-error: true + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@959cbb7472c4d4ad70cdfe6f4976053fe48ab394 # v2.1.37 diff --git a/.github/workflows/compilers.yml b/.github/workflows/compilers.yml index 3fb3813d0c..caf12cc0f4 100644 --- a/.github/workflows/compilers.yml +++ b/.github/workflows/compilers.yml @@ -1,386 +1,280 @@ -# Some tests depending on this name 'Compilations' via $GITHUB_WORKFLOW. Make sure to update such tests when renaming this workflow. name: Compilations on: push: paths-ignore: - 'doc/**' - - '**/man/*' + - '**/man' - '**.md' - '**.rdoc' - '**/.document' - - '.*.yml' pull_request: paths-ignore: - 'doc/**' - - '**/man/*' - - '**.md' + - '**/man' - '**.rdoc' - '**/.document' - - '.*.yml' merge_group: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.rdoc' + - '**/.document' concurrency: group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} +# GitHub actions does not support YAML anchors. This creative use of +# environment variables (plus the "echo $GITHUB_ENV" hack) is to reroute that +# restriction. +env: + default_cc: clang-15 + append_cc: '' + + # -O1 is faster than -O3 in our tests... Majority of time are consumed trying + # to optimize binaries. Also GitHub Actions run on relatively modern CPUs + # compared to, say, GCC 4 or Clang 3. We don't specify `-march=native` + # because compilers tend not understand what the CPU is. + optflags: '-O1' + + # -g0 disables backtraces when SEGV. Do not set that. + debugflags: '-ggdb3' + + default_configure: >- + --enable-debug-env + --disable-install-doc + --with-ext=-test-/cxxanyargs,+ + append_configure: >- + --without-valgrind + --without-jemalloc + --without-gmp + + UPDATE_UNICODE: >- + UNICODE_FILES=. + UNICODE_PROPERTY_FILES=. + UNICODE_AUXILIARY_FILES=. + UNICODE_EMOJI_FILES=. + CONFIGURE_TTY: never + GITPULLOPTIONS: --no-tags origin ${{github.ref}} + RUBY_DEBUG: ci rgengc + RUBY_TESTOPTS: >- + -q + --color=always + --tty=no + permissions: contents: read -# Each job is split so that they roughly take 30min to run through. jobs: - compile1: - name: 'omnibus compilations, #1' - runs-on: ubuntu-latest - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } - - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true } } - - name: 'clang 18 LTO' - uses: './.github/actions/compilers' - with: - tag: clang-18 - with_gcc: 'clang-18 -flto=auto' - optflags: '-O2' - enable_shared: false - - name: 'GCC 13 LTO' - uses: './.github/actions/compilers' - with: - tag: gcc-13 - with_gcc: 'gcc-13 -flto=auto -ffat-lto-objects -Werror=lto-type-mismatch' - optflags: '-O2' - enable_shared: false + compile: + strategy: + fail-fast: false + matrix: + env: + - {} + entry: + - { name: gcc-12, env: { default_cc: gcc-12 } } + - { name: gcc-11, env: { default_cc: gcc-11 } } + - { name: gcc-10, env: { default_cc: gcc-10 } } + - { 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-13 LTO' + container: gcc-13 + env: + default_cc: 'gcc-13 -flto=auto -ffat-lto-objects -Werror=lto-type-mismatch' + optflags: '-O2' + shared: disable + # 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 } } + - { name: clang-13, env: { default_cc: clang-13 } } + - { name: clang-12, env: { default_cc: clang-12 } } + - { name: clang-11, env: { default_cc: clang-11 } } + - { name: clang-10, env: { default_cc: clang-10 } } + # 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-16 -flto=auto' + optflags: '-O2' + shared: disable + # check: true - compile2: - name: 'omnibus compilations, #2' - runs-on: ubuntu-latest - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } - - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true } } - - { uses: './.github/actions/compilers', name: 'GCC 13', with: { tag: 'gcc-13' } } - - { uses: './.github/actions/compilers', name: 'GCC 12', with: { tag: 'gcc-12' } } - - { uses: './.github/actions/compilers', name: 'GCC 11', with: { tag: 'gcc-11' } } - - { uses: './.github/actions/compilers', name: 'GCC 10', with: { tag: 'gcc-10' } } - - { uses: './.github/actions/compilers', name: 'GCC 9', with: { tag: 'gcc-9' } } - - { uses: './.github/actions/compilers', name: 'GCC 8', with: { tag: 'gcc-8' } } - - { uses: './.github/actions/compilers', name: 'GCC 7', with: { tag: 'gcc-7' } } +# - { name: aarch64-linux-gnu, crosshost: aarch64-linux-gnu, container: crossbuild-essential-arm64 } +# - { name: arm-linux-gnueabi, crosshost: arm-linux-gnueabi } +# - { name: arm-linux-gnueabihf, crosshost: arm-linux-gnueabihf } +# - { name: i686-w64-mingw32, crosshost: i686-w64-mingw32 } +# - { name: powerpc-linux-gnu, crosshost: powerpc-linux-gnu } +# - { name: powerpc64le-linux-gnu, crosshost: powerpc64le-linux-gnu, container: crossbuild-essential-ppc64el } +# - { name: s390x-linux-gnu, crosshost: s390x-linux-gnu, container: crossbuild-essential-s390x } +# - { name: x86_64-w64-mingw32, crosshost: x86_64-w64-mingw32, container: mingw-w64 } - compile3: - name: 'omnibus compilations, #3' - runs-on: ubuntu-latest - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } - - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true } } - - { uses: './.github/actions/compilers', name: 'clang 20', with: { tag: 'clang-20' } } - - { uses: './.github/actions/compilers', name: 'clang 19', with: { tag: 'clang-19' } } - - { uses: './.github/actions/compilers', name: 'clang 18', with: { tag: 'clang-18' } } - - { uses: './.github/actions/compilers', name: 'clang 17', with: { tag: 'clang-17' } } - - { uses: './.github/actions/compilers', name: 'clang 16', with: { tag: 'clang-16' } } - - { uses: './.github/actions/compilers', name: 'clang 15', with: { tag: 'clang-15' } } - - { uses: './.github/actions/compilers', name: 'clang 14', with: { tag: 'clang-14' } } - - { uses: './.github/actions/compilers', name: 'clang 13', with: { tag: 'clang-13' } } - - { uses: './.github/actions/compilers', name: 'clang 12', with: { tag: 'clang-12' } } + # -Wno-strict-prototypes is necessary with current clang-15 since + # older autoconf generate functions without prototype and -pedantic + # now implies strict-prototypes. Disabling the error but leaving the + # warning generates a lot of noise from use of ANYARGS in + # rb_define_method() and friends. + # See: https://github.com/llvm/llvm-project/commit/11da1b53d8cd3507959022cd790d5a7ad4573d94 + - { name: c99, env: { append_cc: '-std=c99 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } +# - { name: c11, env: { append_cc: '-std=c11 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } +# - { name: c17, env: { append_cc: '-std=c17 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } + - { name: c2x, env: { append_cc: '-std=c2x -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } + - { name: c++98, env: { CXXFLAGS: '-std=c++98 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } +# - { name: c++11, env: { CXXFLAGS: '-std=c++11 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } +# - { name: c++14, env: { CXXFLAGS: '-std=c++14 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } +# - { name: c++17, env: { CXXFLAGS: '-std=c++17 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } + - { name: c++2a, env: { CXXFLAGS: '-std=c++2a -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } - compile4: - name: 'omnibus compilations, #4' - runs-on: ubuntu-latest - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } - - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true } } - - { uses: './.github/actions/compilers', name: 'clang 11', with: { tag: 'clang-11' } } - - { uses: './.github/actions/compilers', name: 'clang 10', with: { tag: 'clang-10' } } - # llvm-objcopy<=9 doesn't have --wildcard. It compiles, but leaves Rust symbols in libyjit.o. - - { uses: './.github/actions/compilers', name: 'clang 9', with: { tag: 'clang-9', append_configure: '--disable-yjit' } } - - { uses: './.github/actions/compilers', name: 'clang 8', with: { tag: 'clang-8', append_configure: '--disable-yjit' } } - - { uses: './.github/actions/compilers', name: 'clang 7', with: { tag: 'clang-7', append_configure: '--disable-yjit' } } - - { uses: './.github/actions/compilers', name: 'clang 6', with: { tag: 'clang-6.0', append_configure: '--disable-yjit' } } - - { uses: './.github/actions/compilers', name: 'ext/Setup', with: { static_exts: 'etc json/* */escape' } } + - { name: '-O0', env: { optflags: '-O0 -march=x86-64 -mtune=generic' } } +# - { name: '-O3', env: { optflags: '-O3 -march=x86-64 -mtune=generic' }, check: true } - compile5: - name: 'omnibus compilations, #5' - runs-on: ubuntu-latest - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } - - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true } } - # -Wno-strict-prototypes is necessary with current clang-15 since - # older autoconf generate functions without prototype and -pedantic - # now implies strict-prototypes. Disabling the error but leaving the - # warning generates a lot of noise from use of ANYARGS in - # rb_define_method() and friends. - # See: https://github.com/llvm/llvm-project/commit/11da1b53d8cd3507959022cd790d5a7ad4573d94 - - { uses: './.github/actions/compilers', name: 'C99', with: { CFLAGS: '-std=c99 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } - - { uses: './.github/actions/compilers', name: 'C11', with: { CFLAGS: '-std=c11 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } - - { uses: './.github/actions/compilers', name: 'C17', with: { CFLAGS: '-std=c17 -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } - - { uses: './.github/actions/compilers', name: 'C23', with: { CFLAGS: '-std=c2x -Werror=pedantic -pedantic-errors -Wno-strict-prototypes' } } - - { uses: './.github/actions/compilers', name: 'C++98', with: { CXXFLAGS: '-std=c++98 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } - - { uses: './.github/actions/compilers', name: 'C++11', with: { CXXFLAGS: '-std=c++11 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } - - { uses: './.github/actions/compilers', name: 'C++14', with: { CXXFLAGS: '-std=c++14 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } - - { uses: './.github/actions/compilers', name: 'C++17', with: { CXXFLAGS: '-std=c++17 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } - - { uses: './.github/actions/compilers', name: 'C++20', with: { CXXFLAGS: '-std=c++20 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } - - { uses: './.github/actions/compilers', name: 'C++23', with: { CXXFLAGS: '-std=c++23 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } - - { uses: './.github/actions/compilers', name: 'C++26', with: { CXXFLAGS: '-std=c++26 -Werror=pedantic -pedantic-errors -Wno-c++11-long-long' } } + - { name: gmp, env: { append_configure: '--with-gmp' } } + - { name: jemalloc, env: { append_configure: '--with-jemalloc' } } + - { name: valgrind, env: { append_configure: '--with-valgrind' } } + - { name: 'coroutine=ucontext', env: { append_configure: '--with-coroutine=ucontext' } } + - { name: 'coroutine=pthread', env: { append_configure: '--with-coroutine=pthread' } } + - { name: disable-jit-support, env: { append_configure: '--disable-jit-support' } } + - { name: disable-dln, env: { append_configure: '--disable-dln' } } + - { name: enable-mkmf-verbose, env: { append_configure: '--enable-mkmf-verbose' } } + - { name: disable-rubygems, env: { append_configure: '--disable-rubygems' } } + - { name: RUBY_DEVEL, env: { append_configure: '--enable-devel' } } - compile6: - name: 'omnibus compilations, #6' - runs-on: ubuntu-latest - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } - - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true } } - - { uses: './.github/actions/compilers', name: '-O0', with: { optflags: '-O0 -march=x86-64 -mtune=generic' } } - # - { uses: './.github/actions/compilers', name: '-O3', with: { optflags: '-O3 -march=x86-64 -mtune=generic', check: true } } - - { uses: './.github/actions/compilers', name: 'gmp', with: { append_configure: '--with-gmp', check: 'ruby/test_bignum.rb', mspecopt: "/github/workspace/src/spec/ruby/core/integer" } } - - { uses: './.github/actions/compilers', name: 'jemalloc', with: { append_configure: '--with-jemalloc' } } - - { uses: './.github/actions/compilers', name: 'valgrind', with: { append_configure: '--with-valgrind' } } - - { uses: './.github/actions/compilers', name: 'coroutine=ucontext', with: { append_configure: '--with-coroutine=ucontext' } } - - { uses: './.github/actions/compilers', name: 'coroutine=pthread', with: { append_configure: '--with-coroutine=pthread' } } + - { name: OPT_THREADED_CODE=1, env: { cppflags: '-DOPT_THREADED_CODE=1' } } + - { name: OPT_THREADED_CODE=2, env: { cppflags: '-DOPT_THREADED_CODE=2' } } + - { name: OPT_THREADED_CODE=3, env: { cppflags: '-DOPT_THREADED_CODE=3' } } - compile7: - name: 'omnibus compilations, #7' - runs-on: ubuntu-latest - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } - - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true } } - - { uses: './.github/actions/compilers', name: 'disable-jit', with: { append_configure: '--disable-yjit --disable-rjit' } } - - { uses: './.github/actions/compilers', name: 'disable-dln', with: { append_configure: '--disable-dln' } } - - { uses: './.github/actions/compilers', name: 'enable-mkmf-verbose', with: { append_configure: '--enable-mkmf-verbose' } } - - { uses: './.github/actions/compilers', name: 'disable-rubygems', with: { append_configure: '--disable-rubygems' } } - - { uses: './.github/actions/compilers', name: 'RUBY_DEVEL', with: { append_configure: '--enable-devel' } } - - { uses: './.github/actions/compilers', name: 'OPT_THREADED_CODE=0', with: { cppflags: '-DOPT_THREADED_CODE=0' } } - - { uses: './.github/actions/compilers', name: 'OPT_THREADED_CODE=1', with: { cppflags: '-DOPT_THREADED_CODE=1' } } - - { uses: './.github/actions/compilers', name: 'OPT_THREADED_CODE=2', with: { cppflags: '-DOPT_THREADED_CODE=2' } } + - { name: NDEBUG, env: { cppflags: '-DNDEBUG' } } + - { name: RUBY_DEBUG, env: { cppflags: '-DRUBY_DEBUG' } } +# - { name: ARRAY_DEBUG, env: { cppflags: '-DARRAY_DEBUG' } } +# - { name: BIGNUM_DEBUG, env: { cppflags: '-DBIGNUM_DEBUG' } } +# - { name: CCAN_LIST_DEBUG, env: { cppflags: '-DCCAN_LIST_DEBUG' } } +# - { name: CPDEBUG=-1, env: { cppflags: '-DCPDEBUG=-1' } } +# - { name: ENC_DEBUG, env: { cppflags: '-DENC_DEBUG' } } +# - { name: GC_DEBUG, env: { cppflags: '-DGC_DEBUG' } } +# - { name: HASH_DEBUG, env: { cppflags: '-DHASH_DEBUG' } } +# - { name: ID_TABLE_DEBUG, env: { cppflags: '-DID_TABLE_DEBUG' } } +# - { name: RGENGC_DEBUG=-1, env: { cppflags: '-DRGENGC_DEBUG=-1' } } +# - { name: SYMBOL_DEBUG, env: { cppflags: '-DSYMBOL_DEBUG' } } - compile8: - name: 'omnibus compilations, #8' - runs-on: ubuntu-latest - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } - - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true } } - - { uses: './.github/actions/compilers', name: 'NDEBUG', with: { cppflags: '-DNDEBUG' } } - - { uses: './.github/actions/compilers', name: 'RUBY_DEBUG', with: { cppflags: '-DRUBY_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'ARRAY_DEBUG', with: { cppflags: '-DARRAY_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'BIGNUM_DEBUG', with: { cppflags: '-DBIGNUM_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'CCAN_LIST_DEBUG', with: { cppflags: '-DCCAN_LIST_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'CPDEBUG=-1', with: { cppflags: '-DCPDEBUG=-1' } } - - { uses: './.github/actions/compilers', name: 'ENC_DEBUG', with: { cppflags: '-DENC_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'GC_DEBUG', with: { cppflags: '-DGC_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'HASH_DEBUG', with: { cppflags: '-DHASH_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'ID_TABLE_DEBUG', with: { cppflags: '-DID_TABLE_DEBUG' } } +# - { name: RGENGC_CHECK_MODE, env: { cppflags: '-DRGENGC_CHECK_MODE' } } +# - { name: TRANSIENT_HEAP_CHECK_MODE, env: { cppflags: '-DTRANSIENT_HEAP_CHECK_MODE' } } +# - { name: VM_CHECK_MODE, env: { cppflags: '-DVM_CHECK_MODE' } } - compile9: - name: 'omnibus compilations, #9' - runs-on: ubuntu-latest - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } - - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true } } - - { uses: './.github/actions/compilers', name: 'RGENGC_DEBUG=-1', with: { cppflags: '-DRGENGC_DEBUG=-1' } } - - { uses: './.github/actions/compilers', name: 'SYMBOL_DEBUG', with: { cppflags: '-DSYMBOL_DEBUG' } } - - { uses: './.github/actions/compilers', name: 'RGENGC_CHECK_MODE', with: { cppflags: '-DRGENGC_CHECK_MODE' } } - - { uses: './.github/actions/compilers', name: 'VM_CHECK_MODE', with: { cppflags: '-DVM_CHECK_MODE' } } - - { uses: './.github/actions/compilers', name: 'USE_EMBED_CI=0', with: { cppflags: '-DUSE_EMBED_CI=0' } } - - { uses: './.github/actions/compilers', name: 'USE_FLONUM=0', with: { cppflags: '-DUSE_FLONUM=0', append_configure: '--disable-yjit' } } - - { uses: './.github/actions/compilers', name: 'USE_LAZY_LOAD', with: { cppflags: '-DUSE_LAZY_LOAD' } } - - { uses: './.github/actions/compilers', name: 'USE_SYMBOL_GC=0', with: { cppflags: '-DUSE_SYMBOL_GC=0' } } - - { uses: './.github/actions/compilers', name: 'USE_THREAD_CACHE=0', with: { cppflags: '-DUSE_THREAD_CACHE=0' } } + - { name: USE_EMBED_CI=0, env: { cppflags: '-DUSE_EMBED_CI=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' } } +# - { name: USE_SYMBOL_GC=0, env: { cppflags: '-DUSE_SYMBOL_GC=0' } } +# - { name: USE_THREAD_CACHE=0, env: { cppflags: '-DUSE_THREAD_CACHE=0' } } +# - { name: USE_TRANSIENT_HEAP=0, env: { cppflags: '-DUSE_TRANSIENT_HEAP=0' } } +# - { name: USE_RUBY_DEBUG_LOG=1, env: { cppflags: '-DUSE_RUBY_DEBUG_LOG=1' } } + - { name: USE_RVARGC=0, env: { cppflags: '-DUSE_RVARGC=0' } } +# - { name: USE_RVARGC=1, env: { cppflags: '-DUSE_RVARGC=1' } } +# - { name: USE_DEBUG_COUNTER, env: { cppflags: '-DUSE_DEBUG_COUNTER=1', RUBY_DEBUG_COUNTER_DISABLE: '1' } } - compileX: - name: 'omnibus compilations, #10' - runs-on: ubuntu-latest - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } - - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true } } - - { uses: './.github/actions/compilers', name: 'USE_RUBY_DEBUG_LOG=1', with: { cppflags: '-DUSE_RUBY_DEBUG_LOG=1' } } - - { uses: './.github/actions/compilers', name: 'USE_DEBUG_COUNTER', with: { cppflags: '-DUSE_DEBUG_COUNTER=1' } } - - { uses: './.github/actions/compilers', name: 'SHARABLE_MIDDLE_SUBSTRING', with: { cppflags: '-DSHARABLE_MIDDLE_SUBSTRING=1' } } - - { uses: './.github/actions/compilers', name: 'DEBUG_FIND_TIME_NUMGUESS', with: { cppflags: '-DDEBUG_FIND_TIME_NUMGUESS' } } - - { uses: './.github/actions/compilers', name: 'DEBUG_INTEGER_PACK', with: { cppflags: '-DDEBUG_INTEGER_PACK' } } - - { uses: './.github/actions/compilers', name: 'GC_DEBUG_STRESS_TO_CLASS', with: { cppflags: '-DGC_DEBUG_STRESS_TO_CLASS' } } - - { uses: './.github/actions/compilers', name: 'GC_ENABLE_LAZY_SWEEP=0', with: { cppflags: '-DGC_ENABLE_LAZY_SWEEP=0' } } - - { uses: './.github/actions/compilers', name: 'GC_PROFILE_DETAIL_MEMORY', with: { cppflags: '-DGC_PROFILE_DETAIL_MEMORY' } } + - { name: DEBUG_FIND_TIME_NUMGUESS, env: { cppflags: '-DDEBUG_FIND_TIME_NUMGUESS' } } + - { name: DEBUG_INTEGER_PACK, env: { cppflags: '-DDEBUG_INTEGER_PACK' } } +# - { name: ENABLE_PATH_CHECK, env: { cppflags: '-DENABLE_PATH_CHECK' } } - compileB: - name: 'omnibus compilations, #11' - runs-on: ubuntu-latest - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } - - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true } } - - { uses: './.github/actions/compilers', name: 'GC_PROFILE_MORE_DETAIL', with: { cppflags: '-DGC_PROFILE_MORE_DETAIL' } } - - { uses: './.github/actions/compilers', name: 'MALLOC_ALLOCATED_SIZE_CHECK', with: { cppflags: '-DMALLOC_ALLOCATED_SIZE_CHECK' } } - - { uses: './.github/actions/compilers', name: 'RGENGC_ESTIMATE_OLDMALLOC', with: { cppflags: '-DRGENGC_ESTIMATE_OLDMALLOC' } } - # - { uses: './.github/actions/compilers', name: 'RGENGC_FORCE_MAJOR_GC', with: { cppflags: '-DRGENGC_FORCE_MAJOR_GC' } } - - { uses: './.github/actions/compilers', name: 'RGENGC_OBJ_INFO', with: { cppflags: '-DRGENGC_OBJ_INFO' } } - - { uses: './.github/actions/compilers', name: 'RGENGC_PROFILE', with: { cppflags: '-DRGENGC_PROFILE' } } - - { uses: './.github/actions/compilers', name: 'VM_DEBUG_BP_CHECK', with: { cppflags: '-DVM_DEBUG_BP_CHECK' } } - - { uses: './.github/actions/compilers', name: 'VM_DEBUG_VERIFY_METHOD_CACHE', with: { cppflags: '-DVM_DEBUG_VERIFY_METHOD_CACHE' } } + - { name: GC_DEBUG_STRESS_TO_CLASS, env: { cppflags: '-DGC_DEBUG_STRESS_TO_CLASS' } } +# - { name: GC_ENABLE_LAZY_SWEEP=0, env: { cppflags: '-DGC_ENABLE_LAZY_SWEEP=0' } } +# - { name: GC_PROFILE_DETAIL_MEMOTY, env: { cppflags: '-DGC_PROFILE_DETAIL_MEMOTY' } } +# - { name: GC_PROFILE_MORE_DETAIL, env: { cppflags: '-DGC_PROFILE_MORE_DETAIL' } } - compileC: - name: 'omnibus compilations, #12' - runs-on: ubuntu-latest - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - services: { docuum: { image: 'stephanmisc/docuum', options: '--init', volumes: [ '/root', '/var/run/docker.sock:/var/run/docker.sock' ] } } - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: { sparse-checkout-cone-mode: false, sparse-checkout: /.github } - - { uses: './.github/actions/setup/directories', with: { srcdir: 'src', builddir: 'build', makeup: true } } - - { uses: './.github/actions/compilers', name: 'enable-yjit', with: { append_configure: '--enable-yjit --disable-rjit' } } - - { uses: './.github/actions/compilers', name: 'enable-rjit', with: { append_configure: '--enable-rjit --disable-yjit' } } - - { uses: './.github/actions/compilers', name: 'YJIT_FORCE_ENABLE', with: { cppflags: '-DYJIT_FORCE_ENABLE' } } - - { uses: './.github/actions/compilers', name: 'RJIT_FORCE_ENABLE', with: { cppflags: '-DRJIT_FORCE_ENABLE' } } - - { uses: './.github/actions/compilers', name: 'UNIVERSAL_PARSER', with: { cppflags: '-DUNIVERSAL_PARSER' } } +# - { name: CALC_EXACT_MALLOC_SIZE, env: { cppflags: '-DCALC_EXACT_MALLOC_SIZE' } } +# - { name: MALLOC_ALLOCATED_SIZE_CHECK, env: { cppflags: '-DMALLOC_ALLOCATED_SIZE_CHECK' } } + +# - { name: IBF_ISEQ_ENABLE_LOCAL_BUFFER, env: { cppflags: '-DIBF_ISEQ_ENABLE_LOCAL_BUFFER' } } + +# - { name: RGENGC_ESTIMATE_OLDMALLOC, env: { cppflags: '-DRGENGC_ESTIMATE_OLDMALLOC' } } +# - { name: RGENGC_FORCE_MAJOR_GC, env: { cppflags: '-DRGENGC_FORCE_MAJOR_GC' } } +# - { name: RGENGC_OBJ_INFO, env: { cppflags: '-DRGENGC_OBJ_INFO' } } +# - { name: RGENGC_OLD_NEWOBJ_CHECK, env: { cppflags: '-DRGENGC_OLD_NEWOBJ_CHECK' } } +# - { name: RGENGC_PROFILE, env: { cppflags: '-DRGENGC_PROFILE' } } - compilemax: - name: 'omnibus compilations, result' +# - { name: VM_DEBUG_BP_CHECK, env: { cppflags: '-DVM_DEBUG_BP_CHECK' } } +# - { name: VM_DEBUG_VERIFY_METHOD_CACHE, env: { cppflags: '-DVM_DEBUG_VERIFY_METHOD_CACHE' } } + + - { name: MJIT_FORCE_ENABLE, env: { cppflags: '-DMJIT_FORCE_ENABLE' } } + - { name: YJIT_FORCE_ENABLE, env: { cppflags: '-DYJIT_FORCE_ENABLE' } } + + name: ${{ matrix.entry.name }} runs-on: ubuntu-latest - if: ${{ always() }} - needs: - - 'compile1' - - 'compile2' - - 'compile3' - - 'compile4' - - 'compile5' - - 'compile6' - - 'compile7' - - 'compile8' - - 'compile9' - - 'compileX' - - 'compileB' - - 'compileC' + container: + image: ghcr.io/ruby/ruby-ci-image:${{ matrix.entry.container || matrix.entry.env.default_cc || 'clang-15' }} + options: --user root + if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }} + env: ${{ matrix.entry.env || matrix.env }} steps: - - uses: ./.github/actions/slack + - run: id + working-directory: + - run: mkdir build + working-directory: + - name: setenv + run: | + echo "GNUMAKEFLAGS=-sj$((1 + $(nproc --all)))" >> $GITHUB_ENV + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + path: src + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: - label: 'omnibus' + path: src/.downloaded-cache + key: downloaded-cache + - run: ./autogen.sh + working-directory: src + - name: Run configure + run: > + ../src/configure -C ${default_configure} ${append_configure} + --${{ + matrix.entry.crosshost && 'host' || 'with-gcc' + }}=${{ + matrix.entry.crosshost || '"${default_cc}${append_cc:+ $append_cc}"' + }} + --${{ matrix.entry.shared || 'enable' }}-shared + - run: make extract-extlibs + - run: make incs + - run: make showflags + - run: make + - run: make leaked-globals + - run: make test + - run: make install + if: ${{ matrix.entry.check }} + - run: make test-tool + if: ${{ matrix.entry.check }} + - run: make test-all TESTS='-- ruby -ext-' + if: ${{ matrix.entry.check }} + - run: make test-spec + env: + CHECK_LEAKS: true + if: ${{ matrix.entry.check }} + - run: make test-annocheck + if: ${{ matrix.entry.check && endsWith(matrix.entry.name, 'annocheck') }} + + - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1 + with: + payload: | + { + "ci": "GitHub Actions", + "env": "${{ github.workflow }} / ${{ matrix.entry.name }}", + "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: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} - - run: false - working-directory: - if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} + if: ${{ failure() && github.event_name == 'push' }} defaults: run: diff --git a/.github/workflows/dependabot_automerge.yml b/.github/workflows/dependabot_automerge.yml deleted file mode 100644 index 69ab5d9131..0000000000 --- a/.github/workflows/dependabot_automerge.yml +++ /dev/null @@ -1,30 +0,0 @@ -# from https://github.com/gofiber/swagger/blob/main/.github/workflows/dependabot_automerge.yml -name: Dependabot auto-merge -on: - pull_request_target: - -jobs: - automerge: - runs-on: ubuntu-latest - - if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' }} - - steps: - - name: Dependabot metadata - uses: dependabot/fetch-metadata@dbb049abf0d677abbd7f7eee0375145b417fdd34 # v2.2.0 - id: metadata - - - name: Wait for status checks - uses: lewagon/wait-on-check-action@ccfb013c15c8afb7bf2b7c028fb74dc5a068cccc # v1.3.4 - with: - repo-token: ${{ secrets.MATZBOT_GITHUB_TOKEN }} - ref: ${{ github.event.pull_request.head.sha || github.sha }} - check-regexp: 'make \(check, .*\)' - wait-interval: 30 - - - name: Auto-merge for Dependabot PRs - if: ${{ steps.metadata.outputs.update-type == 'version-update:semver-minor' || steps.metadata.outputs.update-type == 'version-update:semver-patch' }} - run: gh pr merge --auto --rebase "$PR_URL" - env: - PR_URL: ${{ github.event.pull_request.html_url }} - GITHUB_TOKEN: ${{ secrets.MATZBOT_GITHUB_TOKEN }} diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index dfdfa3c011..d8dc58b119 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -3,15 +3,24 @@ on: push: paths-ignore: - 'doc/**' - - '**/man/*' + - '**/man' - '**.md' - '**.rdoc' - '**/.document' - - '.*.yml' pull_request: - # Do not use paths-ignore for required status checks - # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' merge_group: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' concurrency: group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} @@ -24,164 +33,80 @@ jobs: make: strategy: matrix: - include: - - test_task: check - os: macos-14 - - test_task: test-all - test_opts: --repeat-count=2 - os: macos-14 - - test_task: test-bundler-parallel - os: macos-14 - - test_task: test-bundled-gems - os: macos-14 - - test_task: check - os: macos-12 - - test_task: check - os: macos-13 + test_task: ["check"] # "test-bundler-parallel", "test-bundled-gems" + os: + - macos-13 + - macos-14 + - macos-15 fail-fast: false - env: - GITPULLOPTIONS: --no-tags origin ${{ github.ref }} - + GITPULLOPTIONS: --no-tags origin ${{github.ref}} runs-on: ${{ matrix.os }} - - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - + if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }} steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - run: mkdir build + working-directory: + - name: git config + run: | + git config --global advice.detachedHead 0 + git config --global init.defaultBranch garbage + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - sparse-checkout-cone-mode: false - sparse-checkout: /.github - - - name: Install libraries - uses: ./.github/actions/setup/macos - - - uses: ./.github/actions/setup/directories + path: src + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: - srcdir: src - builddir: build - makeup: true - clean: true - dummy-files: ${{ matrix.test_task == 'check' }} - # Set fetch-depth: 0 so that Launchable can receive commits information. - fetch-depth: 10 - - - name: make sure that kern.coredump=1 + path: src/.downloaded-cache + key: downloaded-cache + - name: Install libraries run: | - sysctl -n kern.coredump - sudo sysctl -w kern.coredump=1 - sudo chmod -R +rwx /cores/ - - - name: Delete unused SDKs - # To free up disk space to not run out during the run + brew install gmp libffi openssl@1.1 zlib autoconf automake libtool readline bison + working-directory: src + - name: Set ENV run: | - sudo rm -rf ~/.dotnet - sudo rm -rf /Library/Android - sudo rm -rf /Library/Developer/CoreSimulator - continue-on-error: true - + echo "MAKEFLAGS=-j$((1 + $(sysctl -n hw.activecpu)))" >> $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 - run: ../src/configure -C --disable-install-doc ${ruby_configure_args} - + run: ../src/configure -C --disable-install-doc --with-openssl-dir=$(brew --prefix openssl@1.1) --with-readline-dir=$(brew --prefix readline) + - run: make incs - run: make prepare-gems if: ${{ matrix.test_task == 'test-bundled-gems' }} - - run: make - - - run: | - make golf - case "${{ matrix.configure }}" in - *'--enable-shared'*) - make runnable - ./bin/goruby -veh - ;; - *) - ./goruby -veh - ;; - esac - - - name: Set test options for skipped tests - run: | - set -x - TESTS="$(echo "${{ matrix.skipped_tests }}" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|')" - echo "TESTS=${TESTS}" >> $GITHUB_ENV - if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }} - - - name: Set up Launchable - uses: ./.github/actions/launchable/setup - with: - os: ${{ matrix.os }} - test-opts: ${{ matrix.test_opts }} - launchable-token: ${{ secrets.LAUNCHABLE_TOKEN }} - builddir: build - srcdir: src - continue-on-error: true - - - name: Set extra test options - run: | - echo "TESTS=$TESTS ${{ matrix.test_opts }}" >> $GITHUB_ENV - echo "RUBY_TEST_TIMEOUT_SCALE=10" >> $GITHUB_ENV # With --repeat-count=2, flaky test by timeout occurs frequently for some reason - if: matrix.test_opts - + - run: make leaked-globals + if: ${{ matrix.test_task == 'check' }} - name: make ${{ matrix.test_task }} run: | - ulimit -c unlimited - make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"} - timeout-minutes: 60 + make -s ${{ matrix.test_task }} ${TESTS:+TESTS=`echo "$TESTS" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|'`} + timeout-minutes: 40 env: - RUBY_TESTOPTS: '-q --tty=no' - TEST_BUNDLED_GEMS_ALLOW_FAILURES: 'typeprof' - PRECHECK_BUNDLED_GEMS: 'no' - + RUBY_TESTOPTS: "-q --tty=no" + TESTS: ${{ matrix.test_task == 'check' && matrix.skipped_tests || '' }} + TEST_BUNDLED_GEMS_ALLOW_FAILURES: "" + PRECHECK_BUNDLED_GEMS: "no" - name: make skipped tests run: | - make -s test-all TESTS="${TESTS//-n!\//-n/}" + make -s test-all TESTS=`echo "$TESTS" | sed 's| |$$/ -n/|g;s|^|-n/|;s|$|$$/|'` env: - GNUMAKEFLAGS: '' - RUBY_TESTOPTS: '-v --tty=no' - PRECHECK_BUNDLED_GEMS: 'no' - if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }} + GNUMAKEFLAGS: "" + RUBY_TESTOPTS: "-v --tty=no" + TESTS: ${{ matrix.skipped_tests }} + PRECHECK_BUNDLED_GEMS: "no" + if: ${{ matrix.test_task == 'check' && matrix.skipped_tests != '' }} continue-on-error: ${{ matrix.continue-on-skipped_tests || false }} - - - uses: ./.github/actions/slack + - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1 with: - label: ${{ matrix.os }} / ${{ matrix.test_task }} - SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() }} - - - name: Resolve job ID - id: job_id - uses: actions/github-script@main + payload: | + { + "ci": "GitHub Actions", + "env": "${{ matrix.os }} / ${{ matrix.test_task }}${{ matrix.configure }}", + "url": "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}", + "commit": "${{ github.sha }}", + "branch": "${{ github.ref_name }}" + } env: - matrix: ${{ toJson(matrix) }} - with: - script: | - const { data: workflow_run } = await github.rest.actions.listJobsForWorkflowRun({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.runId - }); - const matrix = JSON.parse(process.env.matrix); - const job_name = `${context.job}${matrix ? ` (${Object.values(matrix).join(", ")})` : ""}`; - return workflow_run.jobs.find((job) => job.name === job_name).id; - - result: - if: ${{ always() }} - name: ${{ github.workflow }} result - runs-on: macos-latest - needs: [make] - steps: - - run: exit 1 - working-directory: - if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} + SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot + if: ${{ failure() && github.event_name == 'push' }} defaults: run: diff --git a/.github/workflows/mingw.yml b/.github/workflows/mingw.yml index 149f9fbe83..0df917d3d8 100644 --- a/.github/workflows/mingw.yml +++ b/.github/workflows/mingw.yml @@ -3,20 +3,24 @@ on: push: paths-ignore: - 'doc/**' - - '**/man/*' + - '**/man' - '**.md' - '**.rdoc' - '**/.document' - - '.*.yml' pull_request: paths-ignore: - 'doc/**' - - '**/man/*' + - '**/man' - '**.md' - '**.rdoc' - '**/.document' - - '.*.yml' merge_group: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' concurrency: group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} @@ -31,140 +35,143 @@ permissions: jobs: make: runs-on: windows-2022 - name: ${{ github.workflow }} (${{ matrix.msystem }}) - env: MSYSTEM: ${{ matrix.msystem }} MSYS2_ARCH: x86_64 - CHOST: 'x86_64-w64-mingw32' - CFLAGS: '-march=x86-64 -mtune=generic -O3 -pipe' - CXXFLAGS: '-march=x86-64 -mtune=generic -O3 -pipe' - CPPFLAGS: '-D_FORTIFY_SOURCE=2 -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048' - LDFLAGS: '-pipe' - GITPULLOPTIONS: --no-tags origin ${{ github.ref }} - + CHOST: "x86_64-w64-mingw32" + CFLAGS: "-march=x86-64 -mtune=generic -O3 -pipe" + CXXFLAGS: "-march=x86-64 -mtune=generic -O3 -pipe" + CPPFLAGS: "-D_FORTIFY_SOURCE=2 -D__USE_MINGW_ANSI_STDIO=1 -DFD_SETSIZE=2048" + LDFLAGS: "-pipe" + UPDATE_UNICODE: "UNICODE_FILES=. UNICODE_PROPERTY_FILES=. UNICODE_AUXILIARY_FILES=. UNICODE_EMOJI_FILES=." + GITPULLOPTIONS: --no-tags origin ${{github.ref}} strategy: matrix: include: # To mitigate flakiness of MinGW CI, we test only one runtime that newer MSYS2 uses. - # Ruby 3.2 is the first Windows Ruby to use OpenSSL 3.x - - msystem: 'UCRT64' - baseruby: '3.2' - test_task: 'check' - test-all-opts: '--name=!/TestObjSpace#test_reachable_objects_during_iteration/' + - msystem: "UCRT64" + base_ruby: head + test_task: "check" + test-all-opts: "--name=!/TestObjSpace#test_reachable_objects_during_iteration/" fail-fast: false - - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - + if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }} steps: + - run: mkdir build + working-directory: + - 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + path: src + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + with: + path: src/.downloaded-cache + key: downloaded-cache - name: Set up Ruby & MSYS2 - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 + uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0 with: - ruby-version: ${{ matrix.baseruby }} + ruby-version: ${{ matrix.base_ruby }} + - name: set env + run: | + echo "GNUMAKEFLAGS=-j$((2 * NUMBER_OF_PROCESSORS))" >> $GITHUB_ENV - - name: Misc system & package info - working-directory: + - name: where check run: | # show where + mv /c/Windows/System32/libcrypto-1_1-x64.dll /c/Windows/System32/libcrypto-1_1-x64.dll_ + mv /c/Windows/System32/libssl-1_1-x64.dll /c/Windows/System32/libssl-1_1-x64.dll_ result=true - for e in gcc.exe ragel.exe make.exe libcrypto-3-x64.dll libssl-3-x64.dll; do - echo ::group::$'\033[93m'$e$'\033[m' + for e in gcc.exe ragel.exe make.exe bison.exe libcrypto-1_1-x64.dll libssl-1_1-x64.dll; do + echo '##['group']'$'\033[93m'$e$'\033[m' where $e || result=false - echo ::endgroup:: + echo '##['endgroup']' done + $result + + - name: version check + run: | # show version - for e in gcc ragel make "openssl version"; do + result=true + for e in gcc ragel make bison "openssl version"; do case "$e" in *" "*) ;; *) e="$e --version";; esac - echo ::group::$'\033[93m'$e$'\033[m' + echo '##['group']'$'\033[93m'$e$'\033[m' $e || result=false - echo ::endgroup:: + echo '##['endgroup']' done - # show packages - echo ::group::$'\033[93m'Packages$'\033[m' - pacman -Qs mingw-w64-ucrt-x86_64-* | sed -n "s,local/mingw-w64-ucrt-x86_64-,,p" - echo ::endgroup:: $result - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: - sparse-checkout-cone-mode: false - sparse-checkout: /.github - - - uses: ./.github/actions/setup/directories - with: - srcdir: src - builddir: build - makeup: true - # Set fetch-depth: 10 so that Launchable can receive commits information. - fetch-depth: 10 + - name: autogen + run: | + ./autogen.sh + working-directory: src - name: configure run: > ../src/configure --disable-install-doc --prefix=/. --build=$CHOST --host=$CHOST --target=$CHOST + - name: update + run: | + make incs + + - name: download gems + run: | + make update-gems + - name: make all timeout-minutes: 30 - run: make + run: | + make - - name: make install - run: make DESTDIR=../install install-nodoc + - run: make leaked-globals - - name: Set up Launchable - uses: ./.github/actions/launchable/setup - with: - os: windows-2022 - # If we support new test task, we need to change this test-opts. - test-opts: --retry --job-status=normal --show-skip --timeout-scale=1.5 - ${{ matrix.test-all-opts }} - launchable-token: ${{ secrets.LAUNCHABLE_TOKEN }} - builddir: build - srcdir: src - continue-on-error: true + - name: make install + run: | + make DESTDIR=../install install-nodoc - name: test - timeout-minutes: 30 - run: make test - shell: cmd - env: - GNUMAKEFLAGS: '' - RUBY_TESTOPTS: '-v --tty=no' - if: ${{ matrix.test_task == 'check' || matrix.test_task == 'test' }} + timeout-minutes: 5 + run: | + make test + if: ${{matrix.test_task == 'check' || matrix.test_task == 'test'}} - name: test-all timeout-minutes: 45 - shell: cmd run: | + # Actions uses UTF8, causes test failures, similar to normal OS setup + chcp.com 437 make ${{ StartsWith(matrix.test_task, 'test/') && matrix.test_task || 'test-all' }} env: RUBY_TESTOPTS: >- --retry --job-status=normal --show-skip --timeout-scale=1.5 ${{ matrix.test-all-opts }} - ${{ env.TESTS }} BUNDLER_VERSION: - if: ${{ matrix.test_task == 'check' || matrix.test_task == 'test-all' || StartsWith(matrix.test_task, 'test/') }} + if: ${{matrix.test_task == 'check' || matrix.test_task == 'test-all' || StartsWith(matrix.test_task, 'test/')}} - name: test-spec timeout-minutes: 10 run: | make ${{ StartsWith(matrix.test_task, 'spec/') && matrix.test_task || 'test-spec' }} - shell: cmd - if: ${{ matrix.test_task == 'check' || matrix.test_task == 'test-spec' || StartsWith(matrix.test_task, 'spec/') }} + if: ${{matrix.test_task == 'check' || matrix.test_task == 'test-spec' || StartsWith(matrix.test_task, 'spec/')}} - - uses: ./src/.github/actions/slack + - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1 with: - label: ${{ matrix.msystem }} / ${{ matrix.test_task }} + payload: | + { + "ci": "GitHub Actions", + "env": "${{ github.workflow }} ${{ matrix.msystem }} / ${{ matrix.test_task }}", + "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() }} + if: ${{ failure() && github.event_name == 'push' }} defaults: run: diff --git a/.github/workflows/mjit-bindgen.yml b/.github/workflows/mjit-bindgen.yml new file mode 100644 index 0000000000..26f8a1b2aa --- /dev/null +++ b/.github/workflows/mjit-bindgen.yml @@ -0,0 +1,104 @@ +name: MJIT bindgen +on: + push: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + pull_request: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + merge_group: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + +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: + make: + strategy: + matrix: + include: + - task: mjit-bindgen + fail-fast: false + 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 + working-directory: + - name: Set ENV + run: | + echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV + - name: Install libraries + run: | + set -x + sudo apt-get update -q || : + sudo apt-get install --no-install-recommends -q -y \ + build-essential \ + libssl-dev libyaml-dev libreadline6-dev \ + zlib1g-dev libncurses5-dev libffi-dev \ + libclang1-14 \ + bison autoconf + sudo apt-get install -q -y pkg-config || : + - name: Set up Ruby + 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + path: src + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + with: + path: src/.downloaded-cache + key: downloaded-cache + - name: Fixed world writable dirs + run: | + chmod -v go-w $HOME $HOME/.config + sudo chmod -R go-w /usr/share + sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || : + - run: ./autogen.sh + working-directory: src + - name: Run configure + run: ../src/configure -C --disable-install-doc --prefix=$(pwd)/install --enable-yjit=dev_nodebug + - run: make incs + - run: make + - run: make install + - run: make ${{ matrix.task }} + - run: git diff --exit-code + working-directory: src + - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1 + with: + payload: | + { + "ci": "GitHub Actions", + "env": "${{ matrix.os }} / ${{ matrix.test_task }}${{ matrix.configure }}", + "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' }} + +defaults: + run: + working-directory: build diff --git a/.github/workflows/mjit.yml b/.github/workflows/mjit.yml new file mode 100644 index 0000000000..6f7181489a --- /dev/null +++ b/.github/workflows/mjit.yml @@ -0,0 +1,113 @@ +name: MJIT +on: + push: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + pull_request: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' + - '**.[1-8]' + - '**.ronn' + merge_group: + paths-ignore: + - 'doc/**' + - '**.md' + - '**.rdoc' + - '**/.document' + - '**.[1-8]' + - '**.ronn' + +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: + make: + strategy: + matrix: + test_task: [check] # to make job names consistent + mjit_opts: [--mjit-wait] + fail-fast: false + runs-on: ubuntu-latest + if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }} + env: + TESTOPTS: '-q --tty=no' + RUN_OPTS: '--disable-gems ${{ matrix.mjit_opts }} --mjit-debug=-ggdb3' + GITPULLOPTIONS: --no-tags origin ${{github.ref}} + steps: + - run: mkdir build + working-directory: + - name: Install libraries + run: | + set -x + sudo apt-get update -q || : + 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: git config + run: | + git config --global advice.detachedHead 0 + git config --global init.defaultBranch garbage + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + path: src + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + with: + path: src/.downloaded-cache + key: downloaded-cache + - name: Fixed world writable dirs + run: | + chmod -v go-w $HOME $HOME/.config + sudo chmod -R go-w /usr/share + sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || : + - name: Set ENV + run: | + echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV + - run: ./autogen.sh + working-directory: src + - name: Run configure + run: ../src/configure -C --disable-install-doc cppflags=-DVM_CHECK_MODE + - run: make incs + - run: make + - run: sudo make -s install + - name: Run test + run: | + unset GNUMAKEFLAGS + make -s test RUN_OPTS="$RUN_OPTS" + timeout-minutes: 60 + # - name: Run test-all + # run: | + # ulimit -c unlimited + # make -s test-all RUN_OPTS="$RUN_OPTS" + # timeout-minutes: 60 + - name: Run test-spec + run: | + unset GNUMAKEFLAGS + make -s test-spec RUN_OPTS="$RUN_OPTS" + timeout-minutes: 60 + - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1 + with: + payload: | + { + "ci": "GitHub Actions", + "env": "${{ github.workflow }} / ${{ matrix.test_task }} ${{ matrix.mjit_opts }}", + "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' }} + +defaults: + run: + working-directory: build diff --git a/.github/workflows/parsey.yml b/.github/workflows/parsey.yml deleted file mode 100644 index 7bfcf27166..0000000000 --- a/.github/workflows/parsey.yml +++ /dev/null @@ -1,94 +0,0 @@ -name: parse.y -on: - push: - paths-ignore: - - 'doc/**' - - '**/man/*' - - '**.md' - - '**.rdoc' - - '**/.document' - - '.*.yml' - pull_request: - paths-ignore: - - 'doc/**' - - '**/man/*' - - '**.md' - - '**.rdoc' - - '**/.document' - - '.*.yml' - merge_group: - -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: - make: - strategy: - matrix: - include: - - test_task: check - - test_task: test-bundler-parallel - - test_task: test-bundled-gems - fail-fast: false - - env: - GITPULLOPTIONS: --no-tags origin ${{ github.ref }} - RUBY_DEBUG: ci - SETARCH: ${{ matrix.arch && format('setarch {0}', matrix.arch) }} - - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: - sparse-checkout-cone-mode: false - sparse-checkout: /.github - - - uses: ./.github/actions/setup/ubuntu - - - uses: ./.github/actions/setup/directories - with: - srcdir: src - builddir: build - makeup: true - clean: true - dummy-files: ${{ matrix.test_task == 'check' }} - - - name: Run configure - run: ../src/configure -C --disable-install-doc cppflags=-DRUBY_DEBUG - - - run: make - - - name: make ${{ matrix.test_task }} - run: make -s ${{ matrix.test_task }} RUN_OPTS="$RUN_OPTS" SPECOPTS="$SPECOPTS" - timeout-minutes: ${{ matrix.timeout }} - env: - RUBY_TESTOPTS: ${{ matrix.testopts }} - EXCLUDES: '../src/test/.excludes-parsey' - RUN_OPTS: ${{ matrix.run_opts || '--parser=parse.y' }} - SPECOPTS: ${{ matrix.specopts || '-T --parser=parse.y' }} - TEST_BUNDLED_GEMS_ALLOW_FAILURES: 'typeprof' - - - uses: ./.github/actions/slack - with: - label: ${{ matrix.run_opts }} - SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() }} - -defaults: - run: - working-directory: build diff --git a/.github/workflows/pr-playground.yml b/.github/workflows/pr-playground.yml deleted file mode 100644 index cc06006142..0000000000 --- a/.github/workflows/pr-playground.yml +++ /dev/null @@ -1,127 +0,0 @@ -name: Post Playground link to PR -on: - pull_request_target: - types: [labeled] - workflow_run: - workflows: ["WebAssembly"] - types: [completed] - -jobs: - post-summary: - name: Post Playground link - runs-on: ubuntu-latest - permissions: - pull-requests: write - # Post a comment only if the PR status check is passed and the PR is labeled with `Playground`. - # Triggered twice: when the PR is labeled and when PR build is passed. - if: >- - ${{ false - || (true - && github.event_name == 'pull_request_target' - && contains(github.event.pull_request.labels.*.name, 'Playground')) - || (true - && github.event_name == 'workflow_run' - && github.event.workflow_run.conclusion == 'success' - && github.event.workflow_run.event == 'pull_request') - }} - steps: - - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - script: | - const fs = require('fs/promises'); - - const buildWorkflowPath = '.github/workflows/wasm.yml'; - const findSuccessfuBuildRun = async (pr) => { - const opts = github.rest.actions.listWorkflowRunsForRepo.endpoint.merge({ - owner: context.repo.owner, - repo: context.repo.repo, - status: 'success', - branch: pr.head.ref, - }); - const runs = await github.paginate(opts); - const buildRun = runs.find(run => run.path == buildWorkflowPath); - return buildRun; - } - - const postComment = async (body, pr) => { - const { data: comments } = await github.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: pr.number, - }); - - const commentOpts = { owner: context.repo.owner, repo: context.repo.repo, body: comment }; - - const existingComment = comments.find(comment => comment.body.startsWith(magicComment)); - if (existingComment) { - core.info(`Updating existing comment: ${existingComment.html_url}`); - await github.rest.issues.updateComment({ - ...commentOpts, comment_id: existingComment.id - }); - } else { - await github.rest.issues.createComment({ - ...commentOpts, issue_number: pr.number - }); - } - } - - const derivePRNumber = async () => { - if (context.payload.pull_request) { - return context.payload.pull_request.number; - } - // Workaround for https://github.com/orgs/community/discussions/25220 - - const { data: { artifacts } } = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.payload.workflow_run.id, - }); - const artifact = artifacts.find(artifact => artifact.name == 'github-pr-info'); - if (!artifact) { - throw new Error('Cannot find github-pr-info.txt artifact'); - } - - const { data } = await github.rest.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: artifact.id, - archive_format: 'zip', - }); - - await fs.writeFile('pr-info.zip', Buffer.from(data)); - await exec.exec('unzip', ['pr-info.zip']); - return await fs.readFile('github-pr-info.txt', 'utf8'); - } - - const prNumber = await derivePRNumber(); - - const { data: pr } = await github.rest.pulls.get({ - owner: context.repo.owner, - repo: context.repo.repo, - pull_number: prNumber, - }); - - core.info(`Checking if the PR ${prNumber} is labeled with Playground...`); - if (!pr.labels.some(label => label.name == 'Playground')) { - core.info(`The PR is not labeled with Playground.`); - return; - } - - core.info(`Checking if the build is successful for ${pr.head.ref} in ${pr.head.repo.owner.login}/${pr.head.repo.name}...`); - const buildRun = await findSuccessfuBuildRun(pr); - if (!buildRun) { - core.info(`No successful build run found for ${buildWorkflowPath} on ${pr.head.ref} yet.`); - return; - } - core.info(`Found a successful build run: ${buildRun.html_url}`); - - const runLink = `${process.env.GITHUB_SERVER_URL}/${process.env.GITHUB_REPOSITORY}/actions/runs/${process.env.GITHUB_RUN_ID}`; - const magicComment = `<!-- AUTO-GENERATED-COMMENT-PR-PLAYGROUND -->`; - const comment = `${magicComment} - **Try on Playground**: https://ruby.github.io/play-ruby?run=${buildRun.id} - This is an automated comment by [\`pr-playground.yml\`](${runLink}) workflow. - `; - core.info(`Comment: ${comment}`); - await postComment(comment, pr); - diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index 5534e3defe..0000000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,108 +0,0 @@ -name: Publish Ruby packages - -on: - repository_dispatch: - types: - - release - workflow_dispatch: - inputs: - version: - description: 'Version of the Ruby package to release' - required: true - default: '3.3.4' - -jobs: - release: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - uses: ruby/setup-ruby@v1 - with: - ruby-version: 3.3.4 - - - name: Store Ruby version - run: | - echo "RUBY_VERSION=${{ github.event.client_payload.version || github.event.inputs.version }}" >> $GITHUB_ENV - - - name: Store ABI version - run: echo "ABI_VERSION=$(echo ${{ env.RUBY_VERSION }} | cut -d '.' -f 1-2)" >> $GITHUB_ENV - - - name: Copy draft package `/tmp` to `/pub` directory - run: tool/release.sh ${{ env.RUBY_VERSION }} - env: - AWS_ACCESS_KEY_ID: ${{ secrets.FTP_R_L_O_AWS_ACCESS_KEY_ID }} - AWS_SECRET_ACCESS_KEY: ${{ secrets.FTP_R_L_O_AWS_SECRET_ACCESS_KEY }} - AWS_DEFAULT_REGION: us-west-2 - - - name: Purge URLs of release package - run: | - curl -X POST \ - -H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \ - https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${{ env.ABI_VERSION }}/ruby-${{ env.RUBY_VERSION }}.tar.gz - curl -X POST \ - -H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \ - https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${{ env.ABI_VERSION }}/ruby-${{ env.RUBY_VERSION }}.tar.xz - curl -X POST \ - -H "Fastly-Key: ${{ secrets.FASTLY_PURGE_TOKEN }}" \ - https://api.fastly.com/purge/cache.ruby-lang.org/pub/ruby/${{ env.ABI_VERSION }}/ruby-${{ env.RUBY_VERSION }}.zip - - - name: Create a release on GitHub - run: | - RELEASE_TAG=$(echo v${{ env.RUBY_VERSION }} | sed 's/\./_/g') - echo $RELEASE_TAG - PREVIOUS_RELEASE_TAG=$(echo $RELEASE_TAG | awk 'BEGIN {FS="_"; OFS="_"}{ $NF=$NF-1; print }') - echo $PREVIOUS_RELEASE_TAG - tool/gen-github-release.rb $PREVIOUS_RELEASE_TAG $RELEASE_TAG --no-dry-run - env: - GITHUB_TOKEN: ${{ secrets.MATZBOT_GITHUB_WORKFLOW_TOKEN }} - - - name: Update versions index - 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": "update_index"}' - - - name: Set latest flag for Ruby 3.3 - if: contains(${{ env.RUBY_VERSION }}, '3.3.') - run: | - echo "LATEST=true" >> $GITHUB_ENV - - - name: Build and push Docker images - 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/docker-images/dispatches \ - -d '{"event_type": "build", "client_payload": {"ruby_version": "${{ env.RUBY_VERSION }}", "arch": "amd64", "latest": "${{ env.LATEST }}"}}' - - - name: Build snapcraft packages - 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/snap.ruby/dispatches \ - -d '{"event_type": "build", "client_payload": {"ruby_version": "${{ env.RUBY_VERSION }}"}}' - - - name: Update ruby-build definition - run: | - curl -L -X POST \ - -H "Authorization: Bearer ${{ secrets.RUBY_BUILD_WORKFLOW_TOKEN }}" \ - -H "Accept: application/vnd.github+json" \ - -H "X-GitHub-Api-Version: 2022-11-28" \ - https://api.github.com/repos/rbenv/ruby-build/dispatches \ - -d '{"event_type": "update-ruby", "client_payload": {"ruby_version": "${{ env.RUBY_VERSION }}", "openssl_version": "3.0.15"}}' - - - name: Update all-ruby definition - 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/all-ruby/dispatches \ - -d '{"event_type": "update"}' diff --git a/.github/workflows/rjit-bindgen.yml b/.github/workflows/rjit-bindgen.yml deleted file mode 100644 index 65ef44ee8d..0000000000 --- a/.github/workflows/rjit-bindgen.yml +++ /dev/null @@ -1,86 +0,0 @@ -name: RJIT bindgen -on: - push: - paths-ignore: - - 'doc/**' - - '**/man/*' - - '**.md' - - '**.rdoc' - - '**/.document' - - '.*.yml' - pull_request: - paths-ignore: - - 'doc/**' - - '**/man/*' - - '**.md' - - '**.rdoc' - - '**/.document' - - '.*.yml' - merge_group: - -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: - make: - strategy: - matrix: - include: - - task: rjit-bindgen - fail-fast: false - - runs-on: ubuntu-20.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.event.pull_request.user.login == 'dependabot[bot]') - )}} - - steps: - - name: Set up Ruby - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 - with: - ruby-version: '3.1' - - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: - sparse-checkout-cone-mode: false - sparse-checkout: /.github - - - uses: ./.github/actions/setup/ubuntu - - - uses: ./.github/actions/setup/directories - with: - srcdir: src - builddir: build - makeup: true - - - name: Run configure - run: ../src/configure -C --disable-install-doc --prefix=$(pwd)/install --enable-yjit=dev_nodebug - - - run: make - - - run: make install - - - run: make ${{ matrix.task }} - - - run: git diff --exit-code - working-directory: src - - - uses: ./.github/actions/slack - with: - SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() }} - -defaults: - run: - working-directory: build diff --git a/.github/workflows/rjit.yml b/.github/workflows/rjit.yml deleted file mode 100644 index 9cec3bcd86..0000000000 --- a/.github/workflows/rjit.yml +++ /dev/null @@ -1,130 +0,0 @@ -name: RJIT -on: - push: - paths-ignore: - - 'doc/**' - - '**.md' - - '**.rdoc' - - '**/.document' - - '**.[1-8]' - - '**.ronn' - - '.*.yml' - pull_request: - paths-ignore: - - 'doc/**' - - '**.md' - - '**.rdoc' - - '**/.document' - - '**.[1-8]' - - '**.ronn' - - '.*.yml' - merge_group: - -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: - make: - strategy: - matrix: - # main variables included in the job name - test_task: [check] - run_opts: ['--rjit-call-threshold=1'] - arch: [''] - fail-fast: false - - env: - GITPULLOPTIONS: --no-tags origin ${{ github.ref }} - RUBY_DEBUG: ci - SETARCH: ${{ matrix.arch && format('setarch {0}', matrix.arch) }} - - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: - sparse-checkout-cone-mode: false - sparse-checkout: /.github - - - uses: ./.github/actions/setup/ubuntu - - - uses: ./.github/actions/setup/directories - with: - srcdir: src - builddir: build - makeup: true - # Set fetch-depth: 10 so that Launchable can receive commits information. - fetch-depth: 10 - - - name: Run configure - env: - arch: ${{ matrix.arch }} - run: >- - $SETARCH ../src/configure -C --disable-install-doc cppflags=-DRUBY_DEBUG - ${arch:+--target=$arch-$OSTYPE --host=$arch-$OSTYPE} - - - run: $SETARCH make - - - name: Set up Launchable - uses: ./.github/actions/launchable/setup - with: - os: ubuntu-22.04 - test-task: test - launchable-token: ${{ secrets.LAUNCHABLE_TOKEN }} - builddir: build - srcdir: src - launchable-workspace: ruby-make-btest - test-opts: ${{ matrix.run_opts }} - continue-on-error: true - - - name: make test - run: | - $SETARCH make -s test RUN_OPTS="$RUN_OPTS" - timeout-minutes: 30 - env: - GNUMAKEFLAGS: '' - RUBY_TESTOPTS: >- - ${{ env.TESTS }} - --tty=no - RUN_OPTS: ${{ matrix.run_opts }} - - - name: make test-all - run: | - $SETARCH make -s test-all RUN_OPTS="$RUN_OPTS" - timeout-minutes: 60 - env: - GNUMAKEFLAGS: '' - RUBY_TESTOPTS: '-q --tty=no' - RUN_OPTS: ${{ matrix.run_opts }} - - - name: make test-spec - run: | - $SETARCH make -s test-spec RUN_OPTS="$RUN_OPTS" - timeout-minutes: 10 - env: - GNUMAKEFLAGS: '' - RUN_OPTS: ${{ matrix.run_opts }} - - - uses: ./.github/actions/slack - with: - label: ${{ matrix.run_opts }} - SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() }} - -defaults: - run: - working-directory: build diff --git a/.github/workflows/scorecards.yml b/.github/workflows/scorecards.yml index 40f86480c2..c12a95362d 100644 --- a/.github/workflows/scorecards.yml +++ b/.github/workflows/scorecards.yml @@ -11,8 +11,8 @@ on: # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained schedule: - cron: '22 4 * * 2' - # push: - # branches: [ "master" ] + push: + branches: [ "master" ] # Declare default permissions as read only. permissions: read-all @@ -31,13 +31,13 @@ jobs: # actions: read steps: - - name: 'Checkout code' - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - name: "Checkout code" + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: persist-credentials: false - - name: 'Run analysis' - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 + - name: "Run analysis" + uses: ossf/scorecard-action@ea651e62978af7915d09fe2e282747c798bf2dab # v2.4.1 with: results_file: results.sarif results_format: sarif @@ -58,15 +58,15 @@ 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@0b7f8abb1508181956e8e162db84b466c27e18ce # v3.1.2 - # with: - # name: SARIF file - # path: results.sarif - # retention-days: 5 + - name: "Upload artifact" + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: SARIF file + path: results.sarif + retention-days: 5 # Upload the results to GitHub's code scanning dashboard. - - name: 'Upload to code-scanning' - uses: github/codeql-action/upload-sarif@6db8d6351fd0be61f9ed8ebd12ccd35dcec51fea # v3.26.11 + - name: "Upload to code-scanning" + 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 86abe44034..4521195a2b 100644 --- a/.github/workflows/spec_guards.yml +++ b/.github/workflows/spec_guards.yml @@ -22,7 +22,7 @@ jobs: rubyspec: name: Rubyspec - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 if: >- ${{!(false @@ -31,7 +31,7 @@ jobs: || 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.event.pull_request.user.login == 'dependabot[bot]') + || (github.event_name == 'push' && github.actor == 'dependabot[bot]') )}} strategy: @@ -39,15 +39,13 @@ jobs: # 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-3.0 - ruby-3.1 - ruby-3.2 - - ruby-3.3 steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 - - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 + - uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0 with: ruby-version: ${{ matrix.ruby }} bundler: none @@ -58,9 +56,16 @@ jobs: working-directory: spec/ruby env: CHECK_LEAKS: true - - - uses: ./.github/actions/slack + - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1 with: - label: ${{ matrix.ruby }} + payload: | + { + "ci": "GitHub Actions", + "env": "${{ github.workflow }} / rubyspec @ ${{ matrix.ruby }}", + "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() }} diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index e829596165..4fbca1170e 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -3,15 +3,24 @@ on: push: paths-ignore: - 'doc/**' - - '**/man/*' + - '**/man' - '**.md' - '**.rdoc' - '**/.document' - - '.*.yml' pull_request: - # Do not use paths-ignore for required status checks - # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' merge_group: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' concurrency: group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} @@ -24,151 +33,113 @@ jobs: make: strategy: matrix: + # main variables included in the job name + test_task: [check] + configure: [cppflags=-DRUBY_DEBUG] # default to use more assertions + arch: [''] + # specify all jobs with `include` to avoid testing duplicated things include: - test_task: check - configure: 'cppflags=-DVM_CHECK_MODE' - test_task: check arch: i686 + configure: '' # test without -DRUBY_DEBUG as well - test_task: check - configure: '--disable-yjit' - - test_task: check - configure: '--enable-shared --enable-load-relative' - - test_task: check - shared_gc: true - configure: '--with-shared-gc=/home/runner/ruby_gc' + configure: "--enable-shared --enable-load-relative" + - test_task: test-all TESTS=--repeat-count=2 - test_task: test-bundler-parallel - timeout: 50 - test_task: test-bundled-gems - - test_task: check - os: ubuntu-20.04 - - test_task: check - os: ubuntu-24.04 fail-fast: false - env: - GITPULLOPTIONS: --no-tags origin ${{ github.ref }} + GITPULLOPTIONS: --no-tags origin ${{github.ref}} RUBY_DEBUG: ci - - runs-on: ${{ matrix.os || '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.event.pull_request.user.login == 'dependabot[bot]') - )}} - + SETARCH: ${{ matrix.arch && format('setarch {0}', matrix.arch) }} + runs-on: ubuntu-22.04 + if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }} steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: - sparse-checkout-cone-mode: false - sparse-checkout: /.github - - - uses: ./.github/actions/setup/ubuntu - with: - arch: ${{ matrix.arch }} - - - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 + - run: mkdir build + working-directory: + - name: Set ENV + run: | + echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV + - name: Install libraries + env: + arch: ${{matrix.arch}} + run: | + set -x + arch=${arch:+:${arch/i[3-6]86/i386}} + ${arch:+sudo dpkg --add-architecture ${arch#:}} + sudo apt-get update -q || : + sudo apt-get install --no-install-recommends -q -y \ + ${arch:+cross}build-essential${arch/:/-} \ + libssl-dev${arch} libyaml-dev${arch} libreadline6-dev${arch} \ + zlib1g-dev${arch} libncurses5-dev${arch} libffi-dev${arch} \ + bison autoconf ruby + sudo apt-get install -q -y pkg-config${arch} || : + - name: git config + run: | + git config --global advice.detachedHead 0 + git config --global init.defaultBranch garbage + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - ruby-version: '3.0' - bundler: none - - - uses: ./.github/actions/setup/directories + path: src + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: - srcdir: src - builddir: build - makeup: true - clean: true - dummy-files: ${{ matrix.test_task == 'check' }} - # Set fetch-depth: 10 so that Launchable can receive commits information. - fetch-depth: 10 - + path: src/.downloaded-cache + key: downloaded-cache + - name: Fixed world writable dirs + run: | + chmod -v go-w $HOME $HOME/.config + sudo chmod -R go-w /usr/share + sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || : + - run: ./autogen.sh + working-directory: src - name: Run configure env: - arch: ${{ matrix.arch }} - configure: ${{ matrix.configure }} + arch: ${{matrix.arch}} run: >- - $SETARCH ../src/configure -C --disable-install-doc ${configure:-cppflags=-DRUBY_DEBUG} + $SETARCH ../src/configure -C --disable-install-doc ${{ matrix.configure }} ${arch:+--target=$arch-$OSTYPE --host=$arch-$OSTYPE} - + - run: $SETARCH make incs - run: $SETARCH make prepare-gems if: ${{ matrix.test_task == 'test-bundled-gems' }} - - - name: Build shared GC - run: | - echo "RUBY_GC_LIBRARY=librubygc.default.so" >> $GITHUB_ENV - make shared-gc SHARED_GC=default - if: ${{ matrix.shared_gc }} - - run: $SETARCH make - - - run: | - $SETARCH make golf - case "${{ matrix.configure }}" in - *'--enable-shared'*) - $SETARCH make runnable - ./bin/goruby -veh - ;; - *) - ./goruby -veh - ;; - esac - - - name: Set test options for skipped tests + - run: $SETARCH make leaked-globals + if: ${{ matrix.test_task == 'check' }} + - name: Create dummy files in build dir run: | - set -x - TESTS="$(echo "${{ matrix.skipped_tests }}" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|')" - echo "TESTS=${TESTS}" >> $GITHUB_ENV - if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }} - - - name: Set up Launchable - uses: ./.github/actions/launchable/setup - with: - os: ${{ matrix.os || 'ubuntu-22.04' }} - test-opts: ${{ matrix.configure }} - launchable-token: ${{ secrets.LAUNCHABLE_TOKEN }} - builddir: build - srcdir: src - continue-on-error: true - + $SETARCH ./miniruby -e '(("a".."z").to_a+("A".."Z").to_a+("0".."9").to_a+%w[foo bar test zzz]).each{|basename|File.write("#{basename}.rb", "raise %(do not load #{basename}.rb)")}' + if: ${{ matrix.test_task == 'check' }} - name: make ${{ matrix.test_task }} - run: >- - $SETARCH make -s ${{ matrix.test_task }} - ${TESTS:+TESTS="$TESTS"} - ${{ !contains(matrix.test_task, 'bundle') && 'RUBYOPT=-w' || '' }} - timeout-minutes: ${{ matrix.timeout || 40 }} + run: | + $SETARCH make -s ${{ matrix.test_task }} ${TESTS:+TESTS=`echo "$TESTS" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|'`} + timeout-minutes: 40 env: - RUBY_TESTOPTS: '-q --tty=no' - TEST_BUNDLED_GEMS_ALLOW_FAILURES: 'typeprof' - PRECHECK_BUNDLED_GEMS: 'no' - + RUBY_TESTOPTS: "-q --tty=no" + TESTS: ${{ matrix.test_task == 'check' && matrix.skipped_tests || '' }} + TEST_BUNDLED_GEMS_ALLOW_FAILURES: "" + PRECHECK_BUNDLED_GEMS: "no" - name: make skipped tests run: | - $SETARCH make -s test-all TESTS="${TESTS//-n!\//-n/}" + $SETARCH make -s test-all TESTS=`echo "$TESTS" | sed 's| |$$/ -n/|g;s|^|-n/|;s|$|$$/|'` env: - GNUMAKEFLAGS: '' - RUBY_TESTOPTS: '-v --tty=no' - if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }} + GNUMAKEFLAGS: "" + RUBY_TESTOPTS: "-v --tty=no" + TESTS: ${{ matrix.skipped_tests }} + if: ${{ matrix.test_task == 'check' && matrix.skipped_tests != '' }} continue-on-error: ${{ matrix.continue-on-skipped_tests || false }} - - - uses: ./.github/actions/slack + - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1 with: - label: ${{ matrix.test_task }} ${{ matrix.configure }}${{ matrix.arch }} + payload: | + { + "ci": "GitHub Actions", + "env": "${{ github.workflow }} / ${{ matrix.test_task }} ${{ matrix.configure }}${{ matrix.arch }}", + "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() }} - - result: - if: ${{ always() }} - name: ${{ github.workflow }} result - runs-on: ubuntu-latest - needs: [make] - steps: - - run: exit 1 - working-directory: - if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} + if: ${{ failure() && github.event_name == 'push' }} defaults: run: diff --git a/.github/workflows/wasm.yml b/.github/workflows/wasm.yml index dac107c57b..27920b5821 100644 --- a/.github/workflows/wasm.yml +++ b/.github/workflows/wasm.yml @@ -3,26 +3,30 @@ on: push: paths-ignore: - 'doc/**' - - '**/man/*' + - '**/man' - '**.md' - '**.rdoc' - '**/.document' - - '.*.yml' pull_request: paths-ignore: - 'doc/**' - - '**/man/*' + - '**/man' - '**.md' - '**.rdoc' - '**/.document' - - '.*.yml' merge_group: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' concurrency: group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} cancel-in-progress: ${{ startsWith(github.event_name, 'pull') }} -permissions: # added using https://github.com/step-security/secure-workflows +permissions: # added using https://github.com/step-security/secure-workflows contents: read jobs: @@ -31,52 +35,38 @@ jobs: matrix: entry: # # wasmtime can't compile non-optimized Asyncified binary due to locals explosion -# - { name: O0-debuginfo, optflags: '-O0', debugflags: '-g', wasmoptflags: '-O1' } -# - { name: O1, optflags: '-O1', debugflags: '' , wasmoptflags: '-O1' } - - { name: O2, optflags: '-O2', debugflags: '', wasmoptflags: '-O2' } -# - { name: O3, optflags: '-O3', debugflags: '' , wasmoptflags: '-O3' } +# - { name: O0-debuginfo, optflags: "-O0", debugflags: "-g", wasmoptflags: "-O1" } +# - { name: O1, optflags: "-O1", debugflags: "" , wasmoptflags: "-O1" } + - { name: O2, optflags: "-O2", debugflags: "" , wasmoptflags: "-O2" } +# - { name: O3, optflags: "-O3", debugflags: "" , wasmoptflags: "-O3" } # # -O4 is equivalent to -O3 in clang, but it's different in wasm-opt -# - { name: O4, optflags: '-O3', debugflags: '' , wasmoptflags: '-O4' } -# - { name: Oz, optflags: '-Oz', debugflags: '' , wasmoptflags: '-Oz' } +# - { name: O4, optflags: "-O3", debugflags: "" , wasmoptflags: "-O4" } +# - { name: Oz, optflags: "-Oz", debugflags: "" , wasmoptflags: "-Oz" } fail-fast: false - env: RUBY_TESTOPTS: '-q --tty=no' - GITPULLOPTIONS: --no-tags origin ${{ github.ref }} - WASI_SDK_VERSION_MAJOR: 20 + GITPULLOPTIONS: --no-tags origin ${{github.ref}} + WASI_SDK_VERSION_MAJOR: 14 WASI_SDK_VERSION_MINOR: 0 - BINARYEN_VERSION: 113 - WASMTIME_VERSION: v15.0.0 - - runs-on: ubuntu-20.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.event.pull_request.user.login == 'dependabot[bot]') - )}} - + BINARYEN_VERSION: 109 + WASMTIME_VERSION: v0.33.0 + runs-on: ubuntu-22.04 + if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }} steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: - sparse-checkout-cone-mode: false - sparse-checkout: /.github - - - uses: ./.github/actions/setup/directories + - run: mkdir build + working-directory: + - name: git config + run: | + git config --global advice.detachedHead 0 + git config --global init.defaultBranch garbage + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - srcdir: src - builddir: build - makeup: true - + path: src - name: Install libraries run: | set -ex sudo apt-get update -q || : - sudo apt-get install --no-install-recommends -q -y ruby make autoconf git wget + sudo apt-get install --no-install-recommends -q -y ruby bison make autoconf git wget wasi_sdk_deb="wasi-sdk_${WASI_SDK_VERSION_MAJOR}.${WASI_SDK_VERSION_MINOR}_amd64.deb" wget "https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-${WASI_SDK_VERSION_MAJOR}/${wasi_sdk_deb}" @@ -95,32 +85,29 @@ jobs: wget -O - "$binaryen_url" | tar xfz - sudo ln -fs "$PWD/binaryen-version_${BINARYEN_VERSION}/bin/wasm-opt" /usr/local/bin/wasm-opt working-directory: src - - name: Set ENV run: | + echo "MAKEFLAGS=-j$((1 + $(sysctl -n hw.activecpu)))" >> $GITHUB_ENV echo "WASI_SDK_PATH=/opt/wasi-sdk" >> $GITHUB_ENV + - run: ./autogen.sh + working-directory: src - - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 + - uses: ruby/setup-ruby@13e7a03dc3ac6c3798f4570bfead2aed4d96abfb # v1.244.0 with: ruby-version: '3.0' bundler: none - - name: Build baseruby + - name: Download config.guess with wasi version run: | - set -ex - mkdir ../baseruby - pushd ../baseruby - ../src/configure --prefix=$PWD/install - make - make install + 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 \ --host wasm32-unknown-wasi \ - --with-baseruby=$PWD/../baseruby/install/bin/ruby \ --with-static-linked-ext \ - --with-ext=cgi/escape,continuation,coverage,date,digest/bubblebabble,digest,digest/md5,digest/rmd160,digest/sha1,digest/sha2,etc,fcntl,json,json/generator,json/parser,objspace,pathname,rbconfig/sizeof,ripper,stringio,strscan,monitor \ LDFLAGS=" \ -Xlinker --stack-first \ -Xlinker -z -Xlinker stack-size=16777216 \ @@ -131,44 +118,28 @@ jobs: # miniruby may not be built when cross-compling - run: make mini ruby - - - run: make install DESTDIR=$PWD/../install - - run: tar cfz ../install.tar.gz -C ../install . - - - name: Upload artifacts - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 - with: - name: ruby-wasm-install - path: ${{ github.workspace }}/install.tar.gz - - name: Show Playground URL to try the build - run: | - echo "Try on Playground: https://ruby.github.io/play-ruby?run=$GITHUB_RUN_ID" >> $GITHUB_STEP_SUMMARY - - name: Run basictest run: wasmtime run ./../build/miniruby --mapdir /::./ -- basictest/test.rb working-directory: src - - name: Run bootstraptest (no thread) run: | NO_THREAD_TESTS="$(grep -L Thread -R ./bootstraptest | awk -F/ '{ print $NF }' | uniq | sed -n 's/test_\(.*\).rb/\1/p' | paste -s -d, -)" ruby ./bootstraptest/runner.rb --ruby="$(which wasmtime) run $PWD/../build/ruby --mapdir /::./ -- " --verbose "--sets=$NO_THREAD_TESTS" working-directory: src - - uses: ./.github/actions/slack + - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1 with: - label: ${{ matrix.entry.name }} + payload: | + { + "ci": "GitHub Actions", + "env": "${{ github.workflow }} / ${{ matrix.name }}", + "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() }} - - # Workaround for https://github.com/orgs/community/discussions/25220 - - name: Save Pull Request number - if: ${{ github.event_name == 'pull_request' }} - run: echo "${{ github.event.pull_request.number }}" >> ${{ github.workspace }}/github-pr-info.txt - - uses: actions/upload-artifact@50769540e7f4bd5e21e526ee35c689e35e0d6874 # v4.4.0 - if: ${{ github.event_name == 'pull_request' }} - with: - name: github-pr-info - path: ${{ github.workspace }}/github-pr-info.txt + if: ${{ failure() && github.event_name == 'push' }} defaults: run: diff --git a/.github/workflows/windows.yml b/.github/workflows/windows.yml index e821883157..c2bd4881c2 100644 --- a/.github/workflows/windows.yml +++ b/.github/workflows/windows.yml @@ -3,15 +3,24 @@ on: push: paths-ignore: - 'doc/**' - - '**/man/*' + - '**/man' - '**.md' - '**.rdoc' - '**/.document' - - '.*.yml' pull_request: - # Do not use paths-ignore for required status checks - # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' merge_group: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' concurrency: group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} @@ -25,190 +34,114 @@ jobs: strategy: matrix: include: - - vc: 2015 - vs: 2019 - vcvars: '10.0.14393.0 -vcvars_ver=14.0' # The oldest Windows 10 SDK w/ VC++ 2015 toolset (v140) - - vs: 2019 - vs: 2022 + vcvers: -vcvars_ver=14.2 fail-fast: false - - runs-on: windows-${{ matrix.vs < 2022 && '2019' || matrix.vs }} - - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - - name: VisualStudio ${{ matrix.vc || 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 }} - OS_VER: windows-${{ matrix.vs < 2022 && '2019' || matrix.vs }} - VCPKG_DEFAULT_TRIPLET: ${{ matrix.target || 'x64' }}-windows - + GITPULLOPTIONS: --no-tags origin ${{github.ref}} + PATCH: C:\msys64\usr\bin\patch.exe + OS_VER: windows-${{ matrix.vs }} steps: - run: md build working-directory: - - - name: find tools - id: find-tools - run: | - ::- find needed tools - set NEEDS= - for %%I in (%NEEDED_TOOLS%) do if "%%~$PATH:I" == "" ( - call set NEEDS=%%NEEDS%% %%~nI - ) else ( - echo %%I: %%~$PATH:I - ) - echo.needs=%NEEDS%>>%GITHUB_OUTPUT% - if "%NEEDS%" == "" ( - echo [debug] All needed tools found - ) else ( - echo [warning^]Needs%NEEDS% - ) - env: - NEEDED_TOOLS: >- - patch.exe - - - uses: msys2/setup-msys2@d40200dc2db4c351366b048a9565ad82919e1c24 # v2 + - uses: msys2/setup-msys2@61f9e5e925871ba6c9e3e8da24ede83ea27fa91f # v2.27.0 id: setup-msys2 with: update: true - install: >- - ${{ steps.find-tools.outputs.needs }} - if: ${{ steps.find-tools.outputs.needs != '' }} - - - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 - with: - ruby-version: '3.0' - bundler: none - windows-toolchain: none - - - name: Export GitHub Actions cache environment variables - uses: actions/github-script@v7 + 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@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: - script: | - core.exportVariable('ACTIONS_CACHE_URL', process.env.ACTIONS_CACHE_URL || ''); - core.exportVariable('ACTIONS_RUNTIME_TOKEN', process.env.ACTIONS_RUNTIME_TOKEN || ''); - - - name: Install libraries with scoop + path: C:\vcpkg\installed + key: ${{ runner.os }}-vcpkg-installed-windows-${{ matrix.vs }}-${{ github.sha }} + restore-keys: | + ${{ 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 - shell: pwsh - - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 + scoop install cmake@3.31.6 + vcpkg --triplet x64-windows install libffi libyaml openssl readline zlib + 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@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 with: - sparse-checkout-cone-mode: false - sparse-checkout: /.github - - - uses: ./.github/actions/setup/directories + path: src + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 with: - srcdir: src - builddir: build - + path: src/.downloaded-cache + key: downloaded-cache - name: setup env - # Available Ruby versions: https://github.com/actions/runner-images/blob/main/images/windows/Windows2019-Readme.md#ruby # %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 up VC ${{ matrix.vc || matrix.vs }} - set vswhere="%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" - for /f "delims=;" %%I in ('%vswhere% -latest -property installationPath') do ( - set VCVARS="%%I\VC\Auxiliary\Build\vcvars64.bat" - ) - set VCVARS + set Path=D:/a/_temp/msys64/usr/bin;%Path% + if not "%VCVARS%" == "" goto :vcset + 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% ${{ matrix.vcvars || '' }} - nmake -f nul + call %VCVARS% ${{ matrix.vcvers || ''}} set TMP=%USERPROFILE%\AppData\Local\Temp set TEMP=%USERPROFILE%\AppData\Local\Temp - set MAKEFLAGS=l set /a TEST_JOBS=(15 * %NUMBER_OF_PROCESSORS% / 10) > nul set | C:\msys64\usr\bin\sort > new.env C:\msys64\usr\bin\comm -13 old.env new.env >> %GITHUB_ENV% del *.env - - - name: baseruby version - run: ruby -v - - name: compiler version run: cl - - - name: volume info - run: Get-Volume - shell: pwsh - - - name: Install libraries with vcpkg + - name: link libraries run: | - vcpkg install - working-directory: src - env: - VCPKG_BINARY_SOURCES: "clear;x-gha,readwrite" - - # TODO: We should use `../src` instead of `D:/a/ruby/ruby/src` + for %%I in (C:\vcpkg\installed\x64-windows\bin\*.dll) do ( + if not %%~nI == readline mklink %%~nxI %%I + ) + for %%I in (libcrypto-1_1-x64 libssl-1_1-x64) do ( + ren c:\Windows\System32\%%I.dll %%I.dll_ + ) - name: Configure run: >- ../src/win32/configure.bat --disable-install-doc - --with-opt-dir=D:/a/ruby/ruby/src/vcpkg_installed/%VCPKG_DEFAULT_TRIPLET% - - - run: nmake prepare-vcpkg - + --with-opt-dir=C:/vcpkg/installed/x64-windows - run: nmake incs - - run: nmake extract-extlibs - - # On all other platforms, test-spec depending on extract-gems (in common.mk) is enough. - # But not for this Visual Studio workflow. So here we extract gems before building. - - run: nmake extract-gems - - run: nmake - + env: + YACC: bison.exe - run: nmake test timeout-minutes: 5 - - run: nmake test-spec timeout-minutes: 10 - - - name: Set up Launchable - uses: ./.github/actions/launchable/setup - with: - os: windows-${{ matrix.vs < 2022 && '2019' || matrix.vs }} - test-task: test-all - # If we support a new test task, we need to change this test-opts. - test-opts: -j${{ env.TEST_JOBS || 4 }} --job-status=normal - launchable-token: ${{ secrets.LAUNCHABLE_TOKEN }} - builddir: build - srcdir: src - continue-on-error: true - - run: nmake test-all env: - RUBY_TESTOPTS: >- - -j${{ env.TEST_JOBS || 4 }} - --job-status=normal + RUBY_TESTOPTS: -j${{env.TEST_JOBS}} --job-status=normal timeout-minutes: 60 - - - uses: ./.github/actions/slack + - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1 with: - label: VS${{ matrix.vc || matrix.vs }} / ${{ matrix.test_task || 'check' }} + payload: | + { + "ci": "GitHub Actions", + "env": "VS${{ matrix.vs }} / ${{ matrix.test_task || 'check' }}", + "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() }} - - result: - if: ${{ always() }} - name: ${{ github.workflow }} result - runs-on: windows-latest - needs: [make] - steps: - - run: exit 1 - working-directory: - if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} + if: ${{ failure() && github.event_name == 'push' }} defaults: run: diff --git a/.github/workflows/yjit-macos.yml b/.github/workflows/yjit-macos.yml deleted file mode 100644 index 9c1e75a95d..0000000000 --- a/.github/workflows/yjit-macos.yml +++ /dev/null @@ -1,170 +0,0 @@ -name: YJIT macOS Arm64 -on: - push: - paths-ignore: - - 'doc/**' - - '**/man/*' - - '**.md' - - '**.rdoc' - - '**/.document' - - '.*.yml' - pull_request: - # Do not use paths-ignore for required status checks - # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks - merge_group: - -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: - cargo: - name: cargo test - - runs-on: macos-14 - - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - - - run: RUST_BACKTRACE=1 cargo test - working-directory: yjit - - # Also compile and test with all features enabled - - run: RUST_BACKTRACE=1 cargo test --all-features - working-directory: yjit - - # Check that we can build in release mode too - - run: cargo build --release - working-directory: yjit - - make: - strategy: - matrix: - include: - - test_task: 'check' - configure: '--enable-yjit' - yjit_opts: '--yjit' - - test_task: 'check' - configure: '--enable-yjit=dev' - yjit_opts: '--yjit-call-threshold=1 --yjit-verify-ctx --yjit-code-gc' - specopts: '-T --yjit-call-threshold=1 -T --yjit-verify-ctx -T --yjit-code-gc' - fail-fast: false - - env: - GITPULLOPTIONS: --no-tags origin ${{ github.ref }} - RUN_OPTS: ${{ matrix.yjit_opts }} - SPECOPTS: ${{ matrix.specopts }} - - runs-on: macos-14 - - 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.event.pull_request.user.login == 'dependabot[bot]') - )}} - - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: - sparse-checkout-cone-mode: false - sparse-checkout: /.github - - - name: Install libraries - uses: ./.github/actions/setup/macos - - - uses: ./.github/actions/setup/directories - with: - srcdir: src - builddir: build - makeup: true - dummy-files: ${{ matrix.test_task == 'check' }} - # Set fetch-depth: 10 so that Launchable can receive commits information. - fetch-depth: 10 - - - name: Run configure - run: ../src/configure -C --disable-install-doc ${{ matrix.configure }} - - - run: make prepare-gems - if: ${{ matrix.test_task == 'test-bundled-gems' }} - - - run: make - - - name: Enable YJIT through ENV - run: echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV - - - name: Set test options for skipped tests - run: | - set -x - TESTS="$(echo "${{ matrix.skipped_tests }}" | sed 's| |$$/ -n!/|g;s|^|-n!/|;s|$|$$/|')" - echo "TESTS=${TESTS}" >> $GITHUB_ENV - if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }} - - - name: Set up Launchable - uses: ./.github/actions/launchable/setup - with: - os: macos-14 - test-opts: ${{ matrix.configure }} - launchable-token: ${{ secrets.LAUNCHABLE_TOKEN }} - builddir: build - srcdir: src - continue-on-error: true - - - name: make ${{ matrix.test_task }} - run: >- - make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"} - RUN_OPTS="$RUN_OPTS" - SPECOPTS="$SPECOPTS" - timeout-minutes: 60 - env: - RUBY_TESTOPTS: '-q --tty=no' - TEST_BUNDLED_GEMS_ALLOW_FAILURES: 'typeprof' - SYNTAX_SUGGEST_TIMEOUT: '5' - PRECHECK_BUNDLED_GEMS: 'no' - continue-on-error: ${{ matrix.continue-on-test_task || false }} - - - name: make skipped tests - run: | - make -s test-all TESTS="${TESTS//-n!\//-n/}" - env: - GNUMAKEFLAGS: '' - RUBY_TESTOPTS: '-v --tty=no' - PRECHECK_BUNDLED_GEMS: 'no' - if: ${{ matrix.test_task == 'check' && matrix.skipped_tests }} - continue-on-error: ${{ matrix.continue-on-skipped_tests || false }} - - - uses: ./.github/actions/slack - with: - label: ${{ matrix.test_task }} ${{ matrix.configure }} ${{ matrix.yjit_opts }} - SLACK_WEBHOOK_URL: ${{ secrets.SIMPLER_ALERTS_URL }} # ruby-lang slack: ruby/simpler-alerts-bot - if: ${{ failure() }} - - result: - if: ${{ always() }} - name: ${{ github.workflow }} result - runs-on: macos-14 - needs: [make] - steps: - - run: exit 1 - working-directory: - if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} - -defaults: - run: - working-directory: build diff --git a/.github/workflows/yjit-ubuntu.yml b/.github/workflows/yjit-ubuntu.yml index d67ea8d49e..0b7b9046e9 100644 --- a/.github/workflows/yjit-ubuntu.yml +++ b/.github/workflows/yjit-ubuntu.yml @@ -3,15 +3,24 @@ on: push: paths-ignore: - 'doc/**' - - '**/man/*' + - '**/man' - '**.md' - '**.rdoc' - '**/.document' - - '.*.yml' pull_request: - # Do not use paths-ignore for required status checks - # https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/collaborating-on-repositories-with-code-quality-features/troubleshooting-required-status-checks#handling-skipped-but-required-checks + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' merge_group: + paths-ignore: + - 'doc/**' + - '**/man' + - '**.md' + - '**.rdoc' + - '**/.document' concurrency: group: ${{ github.workflow }} / ${{ startsWith(github.event_name, 'pull') && github.ref_name || github.sha }} @@ -22,58 +31,22 @@ permissions: jobs: cargo: - name: cargo test - + name: Rust cargo test # GitHub Action's image seems to already contain a Rust 1.58.0. - runs-on: ubuntu-20.04 - - if: >- - ${{!(false - || contains(github.event.head_commit.message, '[DOC]') - || contains(github.event.pull_request.title, '[DOC]') - || contains(github.event.pull_request.labels.*.name, 'Document') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') - )}} - + runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.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 - - run: RUST_BACKTRACE=1 cargo test working-directory: yjit - # Also compile and test with all features enabled - run: RUST_BACKTRACE=1 cargo test --all-features working-directory: yjit - # Check that we can build in release mode too - run: cargo build --release working-directory: yjit - - lint: - name: cargo clippy - - # GitHub Action's image seems to already contain a Rust 1.58.0. - runs-on: ubuntu-20.04 - - if: >- - ${{!(false - || contains(github.event.head_commit.message, '[DOC]') - || contains(github.event.pull_request.title, '[DOC]') - || contains(github.event.pull_request.labels.*.name, 'Document') - || (github.event_name == 'push' && github.event.pull_request.user.login == 'dependabot[bot]') - )}} - - steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - - # Check that we don't have linting errors in release mode, too - - run: cargo clippy --all-targets --all-features - working-directory: yjit - make: strategy: fail-fast: false @@ -81,140 +54,116 @@ jobs: include: - test_task: 'yjit-bindgen' hint: 'To fix: use patch in logs' - configure: '--with-gcc=clang-12 --enable-yjit=dev' + configure: '--with-gcc=clang-14 --enable-yjit=dev' + libclang_path: '/usr/lib/llvm-14/lib/libclang.so.1' - - test_task: 'check' + - test_task: "check" # YJIT should be automatically built in release mode on x86-64 Linux with rustc present #configure: "--enable-yjit RUSTC='rustc +1.58.0'" configure: "RUSTC='rustc +1.58.0'" - rust_version: '1.58.0' + rust_version: "1.58.0" - - test_task: 'check' - configure: '--enable-yjit=dev' + - test_task: "check" + configure: "--enable-yjit=dev" - - test_task: 'check' - configure: '--enable-yjit=dev' - yjit_opts: '--yjit-call-threshold=1 --yjit-verify-ctx --yjit-code-gc' - specopts: '-T --yjit-call-threshold=1 -T --yjit-verify-ctx -T --yjit-code-gc' + - test_task: "check" + configure: "--enable-yjit=dev" + yjit_opts: "--yjit-call-threshold=1 --yjit-verify-ctx" - - test_task: 'test-bundled-gems' - configure: '--enable-yjit=dev' + - test_task: "test-all TESTS=--repeat-count=2" + configure: "--enable-yjit=dev" - - test_task: 'yjit-bench' - configure: '--enable-yjit=dev' - yjit_bench_opts: '--yjit-stats' - continue-on-test_task: true + - test_task: "test-bundled-gems" + configure: "--enable-yjit=dev" + - test_task: "yjit-bench" + configure: "--enable-yjit=dev" + yjit_bench_opts: "--yjit-stats" env: - GITPULLOPTIONS: --no-tags origin ${{ github.ref }} + GITPULLOPTIONS: --no-tags origin ${{github.ref}} RUN_OPTS: ${{ matrix.yjit_opts }} YJIT_BENCH_OPTS: ${{ matrix.yjit_bench_opts }} - SPECOPTS: ${{ matrix.specopts }} RUBY_DEBUG: ci BUNDLE_JOBS: 8 # for yjit-bench - RUST_BACKTRACE: 1 - - runs-on: ubuntu-20.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.event.pull_request.user.login == 'dependabot[bot]') - )}} - + runs-on: ubuntu-22.04 + if: ${{ !contains(github.event.head_commit.message, '[DOC]') && !contains(github.event.pull_request.labels.*.name, 'Documentation') }} steps: - - uses: actions/checkout@d632683dd7b4114ad314bca15554477dd762a938 # v4.2.0 - with: - sparse-checkout-cone-mode: false - sparse-checkout: /.github - - - uses: ./.github/actions/setup/ubuntu - - - uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0 - with: - ruby-version: '3.0' - bundler: none - - - uses: ./.github/actions/setup/directories - with: - srcdir: src - builddir: build - makeup: true - dummy-files: ${{ matrix.test_task == 'check' }} - # Set fetch-depth: 10 so that Launchable can receive commits information. - fetch-depth: 10 - + - run: mkdir build + working-directory: + - name: Install libraries + run: | + set -x + sudo apt-get update -q || : + 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: Install Rust if: ${{ matrix.rust_version }} run: rustup install ${{ matrix.rust_version }} --profile minimal - + - name: git config + run: | + git config --global advice.detachedHead 0 + git config --global init.defaultBranch garbage + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + path: src + - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3 + with: + path: src/.downloaded-cache + key: downloaded-cache + - name: Fixed world writable dirs + run: | + chmod -v go-w $HOME $HOME/.config + sudo chmod -R go-w /usr/share + sudo bash -c 'IFS=:; for d in '"$PATH"'; do chmod -v go-w $d; done' || : + - name: Set ENV + run: | + echo "GNUMAKEFLAGS=-j$((1 + $(nproc --all)))" >> $GITHUB_ENV + - run: ./autogen.sh + working-directory: src - name: Run configure run: ../src/configure -C --disable-install-doc --prefix=$(pwd)/install ${{ matrix.configure }} - - run: make incs - - run: make prepare-gems if: ${{ matrix.test_task == 'test-bundled-gems' }} - - - run: make - + - run: make -j + - run: make leaked-globals + if: ${{ matrix.test_task == 'check' }} + - name: Create dummy files in build dir + run: | + ./miniruby -e '(("a".."z").to_a+("A".."Z").to_a+("0".."9").to_a+%w[foo bar test zzz]).each{|basename|File.write("#{basename}.rb", "raise %(do not load #{basename}.rb)")}' + if: ${{ matrix.test_task == 'check' }} - name: Enable YJIT through ENV run: echo "RUBY_YJIT_ENABLE=1" >> $GITHUB_ENV - # Check that the binary was built with YJIT - name: Check YJIT enabled run: ./miniruby --yjit -v | grep "+YJIT" - - - name: Set up Launchable - uses: ./.github/actions/launchable/setup - with: - os: ubuntu-20.04 - test-opts: ${{ matrix.configure }} - launchable-token: ${{ secrets.LAUNCHABLE_TOKEN }} - builddir: build - srcdir: src - continue-on-error: true - - name: make ${{ matrix.test_task }} - run: >- - make -s ${{ matrix.test_task }} ${TESTS:+TESTS="$TESTS"} - RUN_OPTS="$RUN_OPTS" MSPECOPT=--debug SPECOPTS="$SPECOPTS" - YJIT_BENCH_OPTS="$YJIT_BENCH_OPTS" YJIT_BINDGEN_DIFF_OPTS="$YJIT_BINDGEN_DIFF_OPTS" - timeout-minutes: 90 + run: make -s -j ${{ matrix.test_task }} RUN_OPTS="$RUN_OPTS" YJIT_BENCH_OPTS="$YJIT_BENCH_OPTS" + timeout-minutes: 60 env: - RUBY_TESTOPTS: '-q --tty=no' - TEST_BUNDLED_GEMS_ALLOW_FAILURES: 'typeprof' - PRECHECK_BUNDLED_GEMS: 'no' - SYNTAX_SUGGEST_TIMEOUT: '5' - YJIT_BINDGEN_DIFF_OPTS: '--exit-code' - continue-on-error: ${{ matrix.continue-on-test_task || false }} - + 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}" env: 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: ./.github/actions/slack + - uses: ruby/action-slack@0bd85c72233cdbb6a0fe01d37aaeff1d21b5fce1 # v3.2.1 with: - label: ${{ matrix.test_task }} ${{ matrix.configure }} + payload: | + { + "ci": "GitHub Actions", + "env": "${{ github.workflow }} / ${{ matrix.test_task }} ${{ matrix.configure }}", + "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() }} - - result: - if: ${{ always() }} - name: ${{ github.workflow }} result - runs-on: ubuntu-latest - needs: [make] - steps: - - run: exit 1 - working-directory: - if: ${{ contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled') }} + if: ${{ failure() && github.event_name == 'push' }} defaults: run: diff --git a/.gitignore b/.gitignore index b6beba3b3e..99d32a1825 100644 --- a/.gitignore +++ b/.gitignore @@ -50,7 +50,6 @@ y.tab.c *.gcno *.gcov *.vscode -!misc/.vscode lcov*.info # / @@ -124,7 +123,6 @@ lcov*.info /repack /revision.h /revision.tmp -/ripper.tmp.y /riscos /rubicon /ruby @@ -138,7 +136,6 @@ lcov*.info /test.rb /test-coverage.dat /tmp -/vcpkg_installed /transdb.h /uncommon.mk /verconf.h @@ -167,7 +164,6 @@ lcov*.info # /coroutine/ !/coroutine/**/*.s -!/coroutine/**/*.S # /enc/trans/ /enc/trans/*.c @@ -207,10 +203,8 @@ lcov*.info # /ext/ripper/ /ext/ripper/eventids1.c -/ext/ripper/eventids1.h /ext/ripper/.eventids2-check /ext/ripper/eventids2table.c -/ext/ripper/ripper_init.c /ext/ripper/ripper.* /ext/ripper/ids1 /ext/ripper/ids2 @@ -232,9 +226,8 @@ lcov*.info # /misc/ /misc/**/__pycache__ -# for `make test-bundler` +# /spec/bundler /.rspec_status -/tool/bundler/*.lock # /tool/ /tool/config.guess @@ -243,12 +236,11 @@ lcov*.info # /win32/ /win32/*.ico -# RJIT -/include/ruby-*/*/rb_rjit_min_header-*.h -/lib/ruby_vm/rjit/instruction.rb -/lib/ruby_vm/rjit/instruction.rb -/rjit_config.h -/rb_rjit_header.h* +# MJIT +/include/ruby-*/*/rb_mjit_min_header-*.h +/lib/ruby_vm/mjit/instruction.rb +/mjit_config.h +/rb_mjit_header.h # YJIT /yjit-bench @@ -256,28 +248,3 @@ lcov*.info # /wasm/ /wasm/tests/*.wasm - -# prism -/lib/prism/compiler.rb -/lib/prism/dispatcher.rb -/lib/prism/dot_visitor.rb -/lib/prism/dsl.rb -/lib/prism/inspect_visitor.rb -/lib/prism/mutation_compiler.rb -/lib/prism/node.rb -/lib/prism/reflection.rb -/lib/prism/serialize.rb -/lib/prism/visitor.rb -/prism/api_node.c -/prism/ast.h -/prism/diagnostic.c -/prism/diagnostic.h -/prism/node.c -/prism/prettyprint.c -/prism/serialize.c -/prism/token_type.c - -# tool/update-NEWS-gemlist.rb -/bundled_gems.json -/default_gems.json -/gems/default_gems diff --git a/.mailmap b/.mailmap deleted file mode 100644 index 213a0f4916..0000000000 --- a/.mailmap +++ /dev/null @@ -1,431 +0,0 @@ -git[bot] <svn-admin@ruby-lang.org> -git[bot] <svn-admin@ruby-lang.org> git <svn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> -svn[bot] <svn-admin@ruby-lang.org> svn <svn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# a_matsuda -Akira Matsuda <ronnie@dio.jp> -Akira Matsuda <ronnie@dio.jp> <a_matsuda@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# aamine -Minero Aoki <aamine@loveruby.net> -Minero Aoki <aamine@loveruby.net> <aamine@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# akira -akira yamada <akira@ruby-lang.org> -## akira yamada <akira@ruby-lang.org> <akira@rice.p.arika.org> -akira yamada <akira@ruby-lang.org> <akira@arika.org> -akira yamada <akira@ruby-lang.org> <akira@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# akiyoshi -AKIYOSHI, Masamichi <masamichi.akiyoshi@hp.com> -AKIYOSHI, Masamichi <masamichi.akiyoshi@hp.com> <akiyoshi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# akr -Tanaka Akira <akr@fsij.org> -Tanaka Akira <akr@fsij.org> <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# arai -Koji Arai <jca02266@nifty.ne.jp> -Koji Arai <jca02266@nifty.ne.jp> <arai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# arton -Akio Tajima <artonx@yahoo.co.jp> -Akio Tajima <artonx@yahoo.co.jp> <arton@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# aycabta -aycabta <aycabta@gmail.com> -aycabta <aycabta@gmail.com> <aycabta@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# ayumin -Ayumu AIZAWA <ayumu.aizawa@gmail.com> -Ayumu AIZAWA <ayumu.aizawa@gmail.com> <ayumin@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# azav -Alexander Zavorine <alexandre.zavorine@nokia.com> -Alexander Zavorine <alexandre.zavorine@nokia.com> <azav@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# charliesome -Charlie Somerville <charliesome@ruby-lang.org> -Charlie Somerville <charliesome@ruby-lang.org> <charliesome@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# dave -Dave Thomas <dave@pragprog.com> -Dave Thomas <dave@pragprog.com> <dave@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# davidflanagan -David Flanagan <davidflanagan@ruby-lang.org> -David Flanagan <davidflanagan@ruby-lang.org> <david@think32> -David Flanagan <davidflanagan@ruby-lang.org> <david@davidflanagan.com> -David Flanagan <davidflanagan@ruby-lang.org> <davidflanagan@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# dblack -David A. Black <dblack@rubypal.com> -David A. Black <dblack@rubypal.com> <dblack@wobblini.net> -David A. Black <dblack@rubypal.com> <dblack@superlink.net> -David A. Black <dblack@rubypal.com> <dblack@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# drbrain -Eric Hodel <drbrain@segment7.net> -Eric Hodel <drbrain@segment7.net> <drbrain@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# duerst -Martin Dürst <duerst@it.aoyama.ac.jp> -Martin Dürst <duerst@it.aoyama.ac.jp> <duerst@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# eban -WATANABE Hirofumi <eban@ruby-lang.org> -WATANABE Hirofumi <eban@ruby-lang.org> <eban@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# emboss -Martin Bosslet <Martin.Bosslet@gmail.com> -Martin Bosslet <Martin.Bosslet@gmail.com> <Martin.Bosslet@googlemail.com> -Martin Bosslet <Martin.Bosslet@gmail.com> <emboss@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# eregon -Benoit Daloze <eregontp@gmail.com> -Benoit Daloze <eregontp@gmail.com> <eregon@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# evan -Evan Phoenix <evan@ruby-lang.org> -Evan Phoenix <evan@ruby-lang.org> <evan@fallingsnow.net> -Evan Phoenix <evan@ruby-lang.org> <evan@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# glass -Masaki Matsushita <glass.saga@gmail.com> -Masaki Matsushita <glass.saga@gmail.com> <glass@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# gogotanaka -Kazuki Tanaka <gogotanaka@ruby-lang.org> -Kazuki Tanaka <gogotanaka@ruby-lang.org> <gogotanaka@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# gotoken -Kentaro Goto <gotoken@gmail.com> -Kentaro Goto <gotoken@gmail.com> <gotoken@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# gotoyuzo -GOTOU Yuuzou <gotoyuzo@notwork.org> -GOTOU Yuuzou <gotoyuzo@notwork.org> <gotoyuzo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# gsinclair -Gavin Sinclair <gsinclair@soyabean.com.au> -Gavin Sinclair <gsinclair@soyabean.com.au> <gsinclair@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# H_Konishi -KONISHI Hiromasa <konishih@fd6.so-net.ne.jp> -KONISHI Hiromasa <konishih@fd6.so-net.ne.jp> <H_Konishi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# headius -Charles Oliver Nutter <headius@headius.com> -Charles Oliver Nutter <headius@headius.com> <headius@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# hone -Terence Lee <hone@heroku.com> -Terence Lee <hone@heroku.com> <hone@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# hsbt -Hiroshi SHIBATA <hsbt@ruby-lang.org> -Hiroshi SHIBATA <hsbt@ruby-lang.org> <hsbt@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# iwamatsu -Nobuhiro Iwamatsu <iwamatsu@nigauri.org> -Nobuhiro Iwamatsu <iwamatsu@nigauri.org> <iwamatsu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# jeg2 -James Edward Gray II <james@graysoftinc.com> -James Edward Gray II <james@graysoftinc.com> <jeg2@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# jim -Jim Weirich <jim@tardis.local> -Jim Weirich <jim@tardis.local> <jim@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# k0kubun -Takashi Kokubun <takashikkbn@gmail.com> -Takashi Kokubun <takashikkbn@gmail.com> <k0kubun@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# kanemoto -Yutaka Kanemoto <kanemoto@ruby-lang.org> -Yutaka Kanemoto <kanemoto@ruby-lang.org> <kanemoto@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# katsu -UENO Katsuhiro <katsu@blue.sky.or.jp> -UENO Katsuhiro <katsu@blue.sky.or.jp> <katsu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# kazu -Kazuhiro NISHIYAMA <zn@mbf.nifty.com> -Kazuhiro NISHIYAMA <zn@mbf.nifty.com> <kazu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# keiju -Keiju Ishitsuka <keiju@ishitsuka.com> -Keiju Ishitsuka <keiju@ishitsuka.com> <keiju@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# knu -Akinori MUSHA <knu@iDaemons.org> -Akinori MUSHA <knu@iDaemons.org> <knu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# ko1 -Koichi Sasada <ko1@atdot.net> -Koichi Sasada <ko1@atdot.net> <ko1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# kosaki -KOSAKI Motohiro <kosaki.motohiro@gmail.com> -KOSAKI Motohiro <kosaki.motohiro@gmail.com> <kosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# kosako -K.Kosako <sndgk393@ybb.ne.jp> -K.Kosako <sndgk393@ybb.ne.jp> <kosako@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# kou -Sutou Kouhei <kou@clear-code.com> -Sutou Kouhei <kou@clear-code.com> <kou@cozmixng.org> -Sutou Kouhei <kou@clear-code.com> <kou@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# kouji -Kouji Takao <kouji.takao@gmail.com> -Kouji Takao <kouji.takao@gmail.com> <kouji@takao7.net> -Kouji Takao <kouji.takao@gmail.com> <kouji@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# ksaito -Kazuo Saito <ksaito@uranus.dti.ne.jp> -Kazuo Saito <ksaito@uranus.dti.ne.jp> <ksaito@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# ktsj -Kazuki Tsujimoto <kazuki@callcc.net> -Kazuki Tsujimoto <kazuki@callcc.net> <ktsj@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# luislavena -Luis Lavena <luislavena@gmail.com> -Luis Lavena <luislavena@gmail.com> <luislavena@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# mame -Yusuke Endoh <mame@ruby-lang.org> -## Yusuke Endoh <mame@ruby-lang.org> <mame@tsg.ne.jp> -Yusuke Endoh <mame@ruby-lang.org> <mame@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# marcandre -Marc-Andre Lafortune <github@marc-andre.ca> -Marc-Andre Lafortune <ruby-core@marc-andre.ca> -Marc-Andre Lafortune <ruby-core@marc-andre.ca> <marcandre@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# matz -Yukihiro "Matz" Matsumoto <matz@ruby.or.jp> -Yukihiro "Matz" Matsumoto <matz@ruby.or.jp> <matz@ruby-lang.org> -Yukihiro "Matz" Matsumoto <matz@ruby.or.jp> <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# michal -Michal Rokos <michal@ruby-lang.org> -Michal Rokos <michal@ruby-lang.org> <michal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# mneumann -Michael Neumann <mneumann@ruby-lang.org> -Michael Neumann <mneumann@ruby-lang.org> <mneumann@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# mrkn -Kenta Murata <mrkn@mrkn.jp> -Kenta Murata <mrkn@mrkn.jp> <muraken@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> -Kenta Murata <mrkn@mrkn.jp> <3959+mrkn@users.noreply.github.com> -Kenta Murata <mrkn@mrkn.jp> <mrkn@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# nagachika -nagachika <nagachika@ruby-lang.org> -nagachika <nagachika@ruby-lang.org> <nagachika@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# nagai -Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp> -Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp> <nagai@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# nahi -Hiroshi Nakamura <nahi@ruby-lang.org> -Hiroshi Nakamura <nahi@ruby-lang.org> <nahi@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# nari -Narihiro Nakamura <authornari@gmail.com> -Narihiro Nakamura <authornari@gmail.com> <nari@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# naruse -NARUSE, Yui <naruse@airemix.jp> -NARUSE, Yui <naruse@airemix.jp> <naruse@ruby-lang.org> -NARUSE, Yui <naruse@airemix.jp> <naruse@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# ngoto -Naohisa Goto <ngotogenome@gmail.com> -Naohisa Goto <ngotogenome@gmail.com> <ngoto@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# nobu -Nobuyoshi Nakada <nobu@ruby-lang.org> -Nobuyoshi Nakada <nobu@ruby-lang.org> <nobu@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# normal -Eric Wong <normal@ruby-lang.org> -Eric Wong <normal@ruby-lang.org> <e@80x24.org> -Eric Wong <normal@ruby-lang.org> <normal@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# ntalbott -Nathaniel Talbott <ntalbott@ruby-lang.org> -Nathaniel Talbott <ntalbott@ruby-lang.org> <ntalbott@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# ocean -Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp> -Hirokazu Yamamoto <ocean@m2.ccsnet.ne.jp> <ocean@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# odaira -Rei Odaira <rodaira@us.ibm.com> -Rei Odaira <rodaira@us.ibm.com> <Rei.Odaira@gmail.com> -Rei Odaira <rodaira@us.ibm.com> <odaira@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# okkez -okkez <okkez000@gmail.com> -okkez <okkez000@gmail.com> <okkez@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# rhe -Kazuki Yamaguchi <k@rhe.jp> -Kazuki Yamaguchi <k@rhe.jp> <rhe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# ryan -Ryan Davis <ryand-github@zenspider.com> -Ryan Davis <ryand-github@zenspider.com> <ryand-ruby@zenspider.com> -Ryan Davis <ryand-github@zenspider.com> <ryan@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# samuel -Samuel Williams <samuel.williams@oriontransfer.co.nz> -Samuel Williams <samuel.williams@oriontransfer.co.nz> <samuel@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# seki -Masatoshi SEKI <m_seki@mva.biglobe.ne.jp> -Masatoshi SEKI <m_seki@mva.biglobe.ne.jp> <seki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# ser -Sean Russell <ser@germane-software.com> -Sean Russell <ser@germane-software.com> <ser@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# shigek -Shigeo Kobayashi <shigek@ruby-lang.org> -Shigeo Kobayashi <shigek@ruby-lang.org> <shigek@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# shirosaki -Hiroshi Shirosaki <h.shirosaki@gmail.com> -Hiroshi Shirosaki <h.shirosaki@gmail.com> <shirosaki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# sho-h -Sho Hashimoto <sho-h@ruby-lang.org> -Sho Hashimoto <sho-h@ruby-lang.org> <sho-h@netlab.jp> -Sho Hashimoto <sho-h@ruby-lang.org> <sho.hsmt@gmail.com> -Sho Hashimoto <sho-h@ruby-lang.org> <sho-h@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# shugo -Shugo Maeda <shugo@ruby-lang.org> -Shugo Maeda <shugo@ruby-lang.org> <shugo@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# shyouhei -卜部昌平 <shyouhei@ruby-lang.org> -卜部昌平 <shyouhei@ruby-lang.org> <shyouhei@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# siena -Siena. <siena@faculty.chiba-u.jp> -Siena. <siena@faculty.chiba-u.jp> <siena@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# sonots -sonots <sonots@gmail.com> -sonots <sonots@gmail.com> <sonots@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# sorah -Sorah Fukumori <her@sorah.jp> -Sorah Fukumori <her@sorah.jp> <sorah@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# stomar -Marcus Stollsteimer <sto.mar@web.de> -Marcus Stollsteimer <sto.mar@web.de> <stomar@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# suke -Masaki Suketa <masaki.suketa@nifty.ne.jp> -Masaki Suketa <masaki.suketa@nifty.ne.jp> <suke@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# tadd -Tadashi Saito <tad.a.digger@gmail.com> -Tadashi Saito <tad.a.digger@gmail.com> <tadd@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# tadf -Tadayoshi Funaba <tadf@dotrb.org> -Tadayoshi Funaba <tadf@dotrb.org> <tadf@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# takano32 -TAKANO Mitsuhiro <takano32@gmail.com> -TAKANO Mitsuhiro <takano32@gmail.com> <takano32@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# tarui -Masaya Tarui <tarui@ruby-lang.org> -Masaya Tarui <tarui@ruby-lang.org> <tarui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# technorama -Technorama Ltd. <oss-ruby@technorama.net> -Technorama Ltd. <oss-ruby@technorama.net> <technorama@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# tenderlove -Aaron Patterson <tenderlove@ruby-lang.org> -Aaron Patterson <tenderlove@ruby-lang.org> <tenderlove@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# tmm1 -Aman Gupta <ruby@tmm1.net> -Aman Gupta <ruby@tmm1.net> <tmm1@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# ts -Guy Decoux <ts@moulon.inra.fr> -Guy Decoux <ts@moulon.inra.fr> <ts@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# ttate -Takaaki Tateishi <ttate@ttsky.net> -## Takaaki Tateishi <ttate@ttsky.net> <ttate@kt.jaist.ac.jp> -Takaaki Tateishi <ttate@ttsky.net> <ttate@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# uema2 -Takaaki Uematsu <uema2x@jcom.home.ne.jp> -Takaaki Uematsu <uema2x@jcom.home.ne.jp> <uema2@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# usa -U.Nakamura <usa@ruby-lang.org> -U.Nakamura <usa@ruby-lang.org> <usa@garbagecollect.jp> -U.Nakamura <usa@ruby-lang.org> <usa@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# wakou -Wakou Aoyama <wakou@ruby-lang.org> -Wakou Aoyama <wakou@ruby-lang.org> <wakou@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# wanabe -wanabe <s.wanabe@gmail.com> -wanabe <s.wanabe@gmail.com> <wanabe@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# watson1978 -Watson <watson1978@gmail.com> -Watson <watson1978@gmail.com> <watson1978@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# wew -William Webber <william@williamwebber.com> -William Webber <william@williamwebber.com> <wew@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# why -why the lucky stiff <why@ruby-lang.org> -why the lucky stiff <why@ruby-lang.org> <why@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# xibbar -Takeyuki FUJIOKA <xibbar@ruby-lang.org> -Takeyuki FUJIOKA <xibbar@ruby-lang.org> <xibbar@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# yugui -Yuki Yugui Sonoda <yugui@yugui.jp> -Yuki Yugui Sonoda <yugui@yugui.jp> <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# yui-knk -yui-knk <spiketeika@gmail.com> -yui-knk <spiketeika@gmail.com> <yui-knk@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# yuki -Yuki Nishijima <yuki24@hey.com> -Yuki Nishijima <yuki24@hey.com> <mail@yukinishijima.net> -Yuki Nishijima <yuki24@hey.com> <yuki@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# zsombor -Dee Zsombor <zsombor@ruby-lang.org> -Dee Zsombor <zsombor@ruby-lang.org> <zsombor@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> - -# zzak -zzak <zzakscott@gmail.com> -zzak <zzakscott@gmail.com> <zzak@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> diff --git a/.rdoc_options b/.rdoc_options index 4dfbfa140c..760507c7a2 100644 --- a/.rdoc_options +++ b/.rdoc_options @@ -1,9 +1,4 @@ --- page_dir: doc -charset: UTF-8 -encoding: UTF-8 main_page: README.md title: Documentation for Ruby development version -visibility: :private -rdoc_include: -- doc @@ -58,12 +58,12 @@ mentioned below. [ccan/list/list.h] - This file is licensed under the {MIT License}[rdoc-ref:@MIT+License]. + This file is licensed under the {MIT License}[rdoc-label:label-MIT+License]. [coroutine] Unless otherwise specified, these files are licensed under the - {MIT License}[rdoc-ref:@MIT+License]. + {MIT License}[rdoc-label:label-MIT+License]. [include/ruby/onigmo.h] [include/ruby/oniguruma.h] @@ -546,7 +546,7 @@ mentioned below. [vsnprintf.c] - This file is under the {old-style BSD license}[rdoc-ref:@Old-style+BSD+license]. + This file is under the {old-style BSD license}[rdoc-label:label-Old-style+BSD+license]. >>> Copyright (c) 1990, 1993:: @@ -577,7 +577,7 @@ mentioned below. [missing/crypt.c] - This file is under the {old-style BSD license}[rdoc-ref:@Old-style+BSD+license]. + This file is under the {old-style BSD license}[rdoc-label:label-Old-style+BSD+license]. >>> Copyright (c) 1989, 1993:: @@ -588,7 +588,7 @@ mentioned below. [missing/setproctitle.c] - This file is under the {old-style BSD license}[rdoc-ref:@Old-style+BSD+license]. + This file is under the {old-style BSD license}[rdoc-label:label-Old-style+BSD+license]. >>> Copyright 2003:: Damien Miller @@ -727,10 +727,29 @@ mentioned below. for internal or external distribution as long as this notice remains attached. +[ext/nkf/nkf-utf8/config.h] +[ext/nkf/nkf-utf8/nkf.c] +[ext/nkf/nkf-utf8/utf8tbl.c] + + These files are under the following license. So to speak, it is + copyrighted semi-public-domain software. + + >>> + Copyright (C) 1987:: Fujitsu LTD. (Itaru ICHIKAWA) + + Everyone is permitted to do anything on this program + including copying, modifying, improving, + as long as you don't try to pretend that you wrote it. + i.e., the above copyright notice has to appear in all copies. + Binary distribution requires original version messages. + You don't have to ask before copying, redistribution or publishing. + THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE. + [ext/psych] [test/psych] - The files under these directories are under the following license. + The files under these directories are under the following license, except for + ext/psych/yaml. >>> Copyright 2009:: Aaron Patterson, et al. @@ -753,6 +772,31 @@ mentioned below. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +[ext/psych/yaml] + + The files under this directory are under the following license. + + >>> + Copyright (c) 2006:: Kirill Simonov + + Permission is hereby granted, free of charge, to any person obtaining a copy of + this software and associated documentation files (the "Software"), to deal in + the Software without restriction, including without limitation the rights to + use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is furnished to do + so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + [ext/pty/pty.c] >>> @@ -861,7 +905,7 @@ mentioned below. >>> RubyGems is copyrighted free software by Chad Fowler, Rich Kilmer, Jim Weirich and others. You can redistribute it and/or modify it under - either the terms of the {MIT license}[rdoc-ref:@MIT+License], or the conditions + either the terms of the {MIT license}[rdoc-label:label-MIT+License], or the conditions below: 1. You may make and give away verbatim copies of the source form of the @@ -923,7 +967,7 @@ mentioned below. Portions copyright (c) 2010:: Andre Arko Portions copyright (c) 2009:: Engine Yard - {MIT License}[rdoc-ref:@MIT+License] + {MIT License}[rdoc-label:label-MIT+License] [lib/bundler/vendor/thor] @@ -932,16 +976,16 @@ mentioned below. >>> Copyright (c) 2008 Yehuda Katz, Eric Hodel, et al. - {MIT License}[rdoc-ref:@MIT+License] + {MIT License}[rdoc-label:label-MIT+License] -[lib/rubygems/vendor/molinillo] +[lib/rubygems/resolver/molinillo] molinillo is under the following license. >>> Copyright (c) 2014 Samuel E. Giddins segiddins@segiddins.me - {MIT License}[rdoc-ref:@MIT+License] + {MIT License}[rdoc-label:label-MIT+License] [lib/bundler/vendor/pub_grub] @@ -950,7 +994,7 @@ mentioned below. >>> Copyright (c) 2018 John Hawthorn - {MIT License}[rdoc-ref:@MIT+License] + {MIT License}[rdoc-label:label-MIT+License] [lib/bundler/vendor/connection_pool] @@ -959,7 +1003,7 @@ mentioned below. >>> Copyright (c) 2011 Mike Perham - {MIT License}[rdoc-ref:@MIT+License] + {MIT License}[rdoc-label:label-MIT+License] [lib/bundler/vendor/net-http-persistent] @@ -968,7 +1012,7 @@ mentioned below. >>> Copyright (c) Eric Hodel, Aaron Patterson - {MIT License}[rdoc-ref:@MIT+License] + {MIT License}[rdoc-label:label-MIT+License] [lib/did_you_mean] [lib/did_you_mean.rb] @@ -979,7 +1023,7 @@ mentioned below. >>> Copyright (c) 2014-2016 Yuki Nishijima - {MIT License}[rdoc-ref:@MIT+License] + {MIT License}[rdoc-label:label-MIT+License] [lib/error_highlight] [lib/error_highlight.rb] @@ -990,7 +1034,7 @@ mentioned below. >>> Copyright (c) 2021 Yusuke Endoh - {MIT License}[rdoc-ref:@MIT+License] + {MIT License}[rdoc-label:label-MIT+License] [benchmark/so_ackermann.rb] [benchmark/so_array.rb] @@ -1,185 +1,820 @@ -# NEWS for Ruby 3.4.0 +# NEWS for Ruby 3.2.0 This document is a list of user-visible feature changes -since the **3.3.0** release, except for bug fixes. +since the **3.1.0** release, except for bug fixes. Note that each entry is kept to a minimum, see links for details. ## Language changes -* String literals in files without a `frozen_string_literal` comment now emit a deprecation warning - when they are mutated. - These warnings can be enabled with `-W:deprecated` or by setting `Warning[:deprecated] = true`. - To disable this change, you can run Ruby with the `--disable-frozen-string-literal` - command line argument. [[Feature #20205]] +* Anonymous rest and keyword rest arguments can now be passed as + arguments, instead of just used in method parameters. + [[Feature #18351]] -* `it` is added to reference a block parameter. [[Feature #18980]] + ```ruby + def foo(*) + bar(*) + end + def baz(**) + quux(**) + end + ``` + +* A proc that accepts a single positional argument and keywords will + no longer autosplat. [[Bug #18633]] + + ```ruby + proc{|a, **k| a}.call([1, 2]) + # Ruby 3.1 and before + # => 1 + # Ruby 3.2 and after + # => [1, 2] + ``` + +* Constant assignment evaluation order for constants set on explicit + objects has been made consistent with single attribute assignment + evaluation order. With this code: + + ```ruby + foo::BAR = baz + ``` + + `foo` is now called before `baz`. Similarly, for multiple assignments + to constants, left-to-right evaluation order is used. With this + code: + + ```ruby + foo1::BAR1, foo2::BAR2 = baz1, baz2 + ``` -* Keyword splatting `nil` when calling methods is now supported. - `**nil` is treated similarly to `**{}`, passing no keywords, - and not calling any conversion methods. [[Bug #20064]] + The following evaluation order is now used: -* Block passing is no longer allowed in index assignment - (e.g. `a[0, &b] = 1`). [[Bug #19918]] + 1. `foo1` + 2. `foo2` + 3. `baz1` + 4. `baz2` -* Keyword arguments are no longer allowed in index assignment - (e.g. `a[0, kw: 1] = 2`). [[Bug #20218]] + [[Bug #15928]] -* `GC.config` added to allow setting configuration variables on the Garbage - Collector. [[Feature #20443]] +* "Find pattern" is no longer experimental. + [[Feature #18585]] -* GC configuration parameter `rgengc_allow_full_mark` introduced. When `false` - GC will only mark young objects. Default is `true`. [[Feature #20443]] +* Methods taking a rest parameter (like `*args`) and wishing to delegate keyword + arguments through `foo(*args)` must now be marked with `ruby2_keywords` + (if not already the case). In other words, all methods wishing to delegate + keyword arguments through `*args` must now be marked with `ruby2_keywords`, + with no exception. This will make it easier to transition to other ways of + delegation once a library can require Ruby 3+. Previously, the `ruby2_keywords` + flag was kept if the receiving method took `*args`, but this was a bug and an + inconsistency. A good technique to find the potentially-missing `ruby2_keywords` + is to run the test suite, for where it fails find the last method which must + receive keyword arguments, use `puts nil, caller, nil` there, and check each + method/block on the call chain which must delegate keywords is correctly marked + as `ruby2_keywords`. [[Bug #18625]] [[Bug #16466]] + + ```ruby + def target(**kw) + end + + # Accidentally worked without ruby2_keywords in Ruby 2.7-3.1, ruby2_keywords + # needed in 3.2+. Just like (*args, **kwargs) or (...) would be needed on + # both #foo and #bar when migrating away from ruby2_keywords. + ruby2_keywords def bar(*args) + target(*args) + end + + ruby2_keywords def foo(*args) + bar(*args) + end + + foo(k: 1) + ``` ## Core classes updates Note: We're only listing outstanding class updates. +* Fiber + + * Introduce Fiber.[] and Fiber.[]= for inheritable fiber storage. + Introduce Fiber#storage and Fiber#storage= (experimental) for + getting and resetting the current storage. Introduce + `Fiber.new(storage:)` for setting the storage when creating a + 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 + 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 + storage provides. + + ```ruby + def log(message) + puts "#{Fiber[:request_id]}: #{message}" + end + + def handle_requests + while request = read_request + Fiber.schedule do + Fiber[:request_id] = SecureRandom.uuid + + request.messages.each do |message| + Fiber.schedule do + log("Handling #{message}") # Log includes inherited request_id. + end + end + end + end + end + ``` + + You should generally consider Fiber storage for any state which + you want to be shared implicitly between all fibers and threads + created in a given context, e.g. a connection pool, a request + id, a logger level, environment variables, configuration, etc. + +* Fiber::Scheduler + + * Introduce `Fiber::Scheduler#io_select` for non-blocking IO.select. + [[Feature #19060]] + +* IO + + * Introduce IO#timeout= and IO#timeout which can cause + IO::TimeoutError to be raised if a blocking operation exceeds the + specified timeout. [[Feature #18630]] + + ```ruby + STDIN.timeout = 1 + STDIN.read # => Blocking operation timed out! (IO::TimeoutError) + ``` + + * Introduce `IO.new(..., path:)` and promote `File#path` to `IO#path`. + [[Feature #19036]] + +* Class + + * Class#attached_object, which returns the object for which + the receiver is the singleton class. Raises TypeError if the + receiver is not a singleton class. + [[Feature #12084]] + + ```ruby + class Foo; end + + Foo.singleton_class.attached_object #=> Foo + Foo.new.singleton_class.attached_object #=> #<Foo:0x000000010491a370> + Foo.attached_object #=> TypeError: `Foo' is not a singleton class + nil.singleton_class.attached_object #=> TypeError: `NilClass' is not a singleton class + ``` + +* Data + + * New core class to represent simple immutable value object. The class is + similar to Struct and partially shares an implementation, but has more + lean and strict API. [[Feature #16122]] + + ```ruby + 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=' + ``` + +* Encoding + + * Encoding#replicate has been deprecated and will be removed in 3.3. [[Feature #18949]] + * The dummy `Encoding::UTF_16` and `Encoding::UTF_32` encodings no longer + try to dynamically guess the endian based on a byte order mark. + Use `Encoding::UTF_16BE`/`UTF_16LE` and `Encoding::UTF_32BE`/`UTF_32LE` instead. + This change speeds up getting the encoding of a String. [[Feature #18949]] + * Limit maximum encoding set size by 256. + If exceeding maximum size, `EncodingError` will be raised. [[Feature #18949]] + +* Enumerator + + * Enumerator.product has been added. Enumerator::Product is the implementation. [[Feature #18685]] + * Exception - * Exception#set_backtrace now accepts arrays of `Thread::Backtrace::Location`. - `Kernel#raise`, `Thread#raise` and `Fiber#raise` also accept this new format. [[Feature #13557]] + * Exception#detailed_message has been added. + The default error printer calls this method on the Exception object + instead of #message. [[Feature #18564]] -* Range +* Hash - * Range#size now raises TypeError if the range is not iterable. [[Misc #18984]] - * Range#step now consistently has a semantics of iterating by using `+` operator - for all types, not only numerics. [[Feature #18368]] + * Hash#shift now always returns nil if the hash is + empty, instead of returning the default value or + calling the default proc. [[Bug #16908]] - ```ruby - (Time.utc(2022, 2, 24)..).step(24*60*60).take(3) - #=> [2022-02-24 00:00:00 UTC, 2022-02-25 00:00:00 UTC, 2022-02-26 00:00:00 UTC] - ``` +* Integer + + * Integer#ceildiv has been added. [[Feature #18809]] + +* Kernel + + * Kernel#binding raises RuntimeError if called from a non-Ruby frame + (such as a method defined in C). [[Bug #18487]] + +* MatchData + + * MatchData#byteoffset has been added. [[Feature #13110]] + * MatchData#deconstruct has been added. [[Feature #18821]] + * MatchData#deconstruct_keys has been added. [[Feature #18821]] + +* Module + + * Module.used_refinements has been added. [[Feature #14332]] + * Module#refinements has been added. [[Feature #12737]] + * Module#const_added has been added. [[Feature #17881]] + * Module#undefined_instance_methods has been added. [[Feature #12655]] + +* Proc + + * Proc#dup returns an instance of subclass. [[Bug #17545]] + * Proc#parameters now accepts lambda keyword. [[Feature #15357]] + +* Process + * Added `RLIMIT_NPTS` constant to FreeBSD platform + +* Regexp + + * 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) + vulnerability. [[Feature #19104]] + + * Regexp.linear_time? is introduced. [[Feature #19194]] + + * Regexp.new now supports passing the regexp flags not only as an Integer, + but also as a String. Unknown flags raise ArgumentError. + Otherwise, anything other than `true`, `false`, `nil` or Integer will be warned. + [[Feature #18788]] + + * Regexp.timeout= has been added. Also, Regexp.new new supports timeout keyword. + See [[Feature #17837]] + +* Refinement + + * Refinement#refined_class has been added. [[Feature #12737]] * RubyVM::AbstractSyntaxTree - * Add `RubyVM::AbstractSyntaxTree::Node#locations` method which returns location objects - associated with the AST node. [[Feature #20624]] - * Add `RubyVM::AbstractSyntaxTree::Location` class which holds location information. [[Feature #20624]] + * Add `error_tolerant` option for `parse`, `parse_file` and `of`. [[Feature #19013]] + With this option + + 1. SyntaxError is suppressed + 2. AST is returned for invalid input + 3. `end` is complemented when a parser reaches to the end of input but `end` is insufficient + 4. `end` is treated as keyword based on indent + + ```ruby + # Without error_tolerant option + root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY) + def m + a = 10 + if + end + RUBY + # => <internal:ast>:33:in `parse': syntax error, unexpected `end' (SyntaxError) + + # With error_tolerant option + root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY, error_tolerant: true) + def m + a = 10 + if + end + RUBY + p root # => #<RubyVM::AbstractSyntaxTree::Node:SCOPE@1:0-4:3> + + # `end` is treated as keyword based on indent + root = RubyVM::AbstractSyntaxTree.parse(<<~RUBY, error_tolerant: true) + module Z + class Foo + foo. + end + + def bar + end + end + RUBY + p root.children[-1].children[-1].children[-1].children[-2..-1] + # => [#<RubyVM::AbstractSyntaxTree::Node:CLASS@2:2-4:5>, #<RubyVM::AbstractSyntaxTree::Node:DEFN@6:2-7:5>] + ``` + + * Add `keep_tokens` option for `parse`, `parse_file` and `of`. Add `#tokens` and `#all_tokens` + for RubyVM::AbstractSyntaxTree::Node [[Feature #19070]] + + ```ruby + root = RubyVM::AbstractSyntaxTree.parse("x = 1 + 2", keep_tokens: true) + root.tokens # => [[0, :tIDENTIFIER, "x", [1, 0, 1, 1]], [1, :tSP, " ", [1, 1, 1, 2]], ...] + root.tokens.map{_1[2]}.join # => "x = 1 + 2" + ``` + +* Set + + * 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. + +* String + + * String#byteindex and String#byterindex have been added. [[Feature #13110]] + * Update Unicode to Version 15.0.0 and Emoji Version 15.0. [[Feature #18639]] + (also applies to Regexp) + * String#bytesplice has been added. [[Feature #18598]] + * String#dedup has been added as an alias to String#-@. [[Feature #18595]] + +* Struct + + * A Struct class can also be initialized with keyword arguments + without `keyword_init: true` on Struct.new [[Feature #16806]] + + ```ruby + Post = Struct.new(:id, :name) + Post.new(1, "hello") #=> #<struct Post id=1, name="hello"> + # From Ruby 3.2, the following code also works without keyword_init: true. + Post.new(id: 1, name: "hello") #=> #<struct Post id=1, name="hello"> + ``` + +* Thread + + * Thread.each_caller_location is added. [[Feature #16663]] + +* Thread::Queue + + * 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]] + +* 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]] + +* TracePoint + + * 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 a block is given and `target` and `target_line` keyword + arguments are not passed. [[Bug #16889]] + +* UnboundMethod + + * `UnboundMethod#==` returns `true` if the actual method is same. For example, + `String.instance_method(:object_id) == Array.instance_method(:object_id)` + returns `true`. [[Feature #18798]] + + * `UnboundMethod#inspect` does not show the receiver of `instance_method`. + For example `String.instance_method(:object_id).inspect` returns + `"#<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 -* Tempfile - - * The keyword argument `anonymous: true` is implemented for `Tempfile.create`. - `Tempfile.create(anonymous: true)` removes the created temporary file immediately. - So applications don't need to remove the file. - [[Feature #20497]] - -The following default gems are updated. - -* RubyGems 3.6.0.dev -* bundler 2.6.0.dev -* erb 4.0.4 -* fiddle 1.1.3.dev -* io-console 0.7.2 -* irb 1.14.1 -* json 2.7.2 -* logger 1.6.1 -* net-http 0.4.1 -* optparse 0.5.0 -* prism 1.0.0 -* psych 5.2.0.beta1 -* rdoc 6.7.0 -* reline 0.5.10 -* resolv 0.4.0 -* stringio 3.1.2.dev -* strscan 3.1.1.dev -* time 0.4.0 -* uri 0.13.1 -* zlib 3.1.1 - -The following bundled gems are updated. - -* minitest 5.25.1 -* power_assert 2.0.4 -* rake 13.2.1 -* test-unit 3.6.2 -* rexml 3.3.8 -* rss 0.3.1 -* net-ftp 0.3.8 -* net-imap 0.4.16 -* net-smtp 0.5.0 -* rbs 3.6.1 -* typeprof 0.21.11 -* debug 1.9.2 -* racc 1.8.1 - -The following bundled gems are promoted from default gems. - -* mutex_m 0.2.0 -* getoptlong 0.2.1 -* base64 0.2.0 -* bigdecimal 3.1.8 -* observer 0.1.2 -* abbrev 0.1.2 -* resolv-replace 0.1.1 -* rinda 0.2.0 -* drb 2.2.1 -* nkf 0.2.0 -* syslog 0.1.2 -* csv 3.3.0 -* repl_type_completor 0.1.7 +* 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`. + * It no longer allocates a String object when no character needs to be escaped. + * It skips calling `#to_s` method when an argument is already a String. + * `ERB::Escape.html_escape` is added as an alias to `ERB::Util.html_escape`, + which has not been monkey-patched by Rails. + * `ERB::Util.url_encode` is made faster using `CGI.escapeURIComponent`. + * `-S` option is removed from `erb` command. + +* FileUtils + + * 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.1 + * abbrev 0.1.1 + * benchmark 0.2.1 + * bigdecimal 3.1.3 + * bundler 2.4.1 + * cgi 0.3.6 + * csv 3.2.6 + * date 3.3.3 + * delegate 0.3.0 + * did_you_mean 1.6.3 + * digest 3.1.1 + * drb 2.1.1 + * english 0.7.2 + * erb 4.0.2 + * error_highlight 0.5.1 + * etc 1.4.2 + * fcntl 1.0.2 + * fiddle 1.1.1 + * fileutils 1.7.0 + * forwardable 1.3.3 + * getoptlong 0.2.0 + * io-console 0.6.0 + * io-nonblock 0.2.0 + * io-wait 0.3.0 + * ipaddr 1.2.5 + * irb 1.6.2 + * json 2.6.3 + * logger 1.5.3 + * mutex_m 0.1.2 + * 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 + * 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.2 + * rdoc 6.5.0 + * readline-ext 0.1.5 + * reline 0.3.2 + * resolv 0.2.2 + * resolv-replace 0.1.1 + * securerandom 0.2.2 + * set 1.0.3 + * stringio 3.0.4 + * strscan 3.0.5 + * syntax_suggest 1.0.2 + * syslog 0.1.1 + * tempfile 0.1.3 + * time 0.2.1 + * timeout 0.3.1 + * tmpdir 0.1.3 + * tsort 0.1.1 + * un 0.2.1 + * uri 0.12.0 + * weakref 0.1.2 + * win32ole 1.8.9 + * yaml 0.2.1 + * zlib 3.0.0 + +* The following bundled gems are updated. + + * minitest 5.16.3 + * power_assert 2.0.3 + * test-unit 3.5.7 + * net-ftp 0.2.0 + * net-imap 0.3.4 + * net-pop 0.1.2 + * net-smtp 0.3.3 + * rbs 2.8.2 + * typeprof 0.21.3 + * debug 1.7.1 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. See [wasm/README.md] and [ruby.wasm] for more details. [[Feature #18462]] + ## Compatibility issues -* Error messages and backtrace displays have been changed. - * Use a single quote instead of a backtick as a opening quote. [[Feature #16495]] - * Display a class name before a method name (only when the class has a permanent name). [[Feature #19117]] - * `Kernel#caller`, `Thread::Backtrace::Location`'s methods, etc. are also changed accordingly. - ``` - Old: - test.rb:1:in `foo': undefined method `time' for an instance of Integer - from test.rb:2:in `<main>' +* `String#to_c` currently treat a sequence of underscores as an end of Complex + string. [[Bug #19087]] + +* Now `ENV.clone` raises `TypeError` as well as `ENV.dup` [[Bug #17767]] + +### Removed constants + +The following deprecated constants are removed. - New: - test.rb:1:in 'Object#foo': undefined method 'time' for an instance of Integer - from test.rb:2:in `<main>' - ``` +* `Fixnum` and `Bignum` [[Feature #12005]] +* `Random::DEFAULT` [[Feature #17351]] +* `Struct::Group` +* `Struct::Passwd` + +### Removed methods + +The following deprecated methods are removed. + +* `Dir.exists?` [[Feature #17391]] +* `File.exists?` [[Feature #17391]] +* `Kernel#=~` [[Feature #15231]] +* `Kernel#taint`, `Kernel#untaint`, `Kernel#tainted?` + [[Feature #16131]] +* `Kernel#trust`, `Kernel#untrust`, `Kernel#untrusted?` + [[Feature #16131]] +* `Method#public?`, `Method#private?`, `Method#protected?`, + `UnboundMethod#public?`, `UnboundMethod#private?`, `UnboundMethod#protected?` + [[Bug #18729]] [[Bug #18751]] [[Bug #18435]] + +### Source code incompatibility of extension libraries + +* Extension libraries provide PRNG, subclasses of Random, need updates. + See [PRNG update] below for more information. [[Bug #19100]] + +### Error printer + +* Ruby no longer escapes control characters and backslashes in an + error message. [[Feature #18367]] + +### 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 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 +* Psych no longer bundles libyaml sources. + And also Fiddle no longer bundles libffi sources. + Users need to install the libyaml/libffi library themselves via the package + manager like apt, yum, brew, etc. + + Psych and fiddle supported the static build with specific version of libyaml + and libffi sources. You can build psych with libyaml-0.2.5 like this. + + ```bash + $ ./configure --with-libyaml-source-dir=/path/to/libyaml-0.2.5 + ``` + + And you can build fiddle with libffi-3.4.4 like this. + + ```bash + $ ./configure --with-libffi-source-dir=/path/to/libffi-3.4.4 + ``` + + [[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 -* `rb_newobj` and `rb_newobj_of` (and corresponding macros `RB_NEWOBJ`, `RB_NEWOBJ_OF`, `NEWOBJ`, `NEWOBJ_OF`) have been removed. [[Feature #20265]] -* Removed deprecated function `rb_gc_force_recycle`. [[Feature #18290]] +### Updated C APIs + +The following APIs are updated. + +* PRNG update + + `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 + +* `VALUE rb_hash_new_capa(long capa)` was added to created hashes with the desired capacity. +* `rb_internal_thread_add_event_hook` and `rb_internal_thread_add_event_hook` were added to instrument threads scheduling. + The following events are available: + * `RUBY_INTERNAL_THREAD_EVENT_STARTED` + * `RUBY_INTERNAL_THREAD_EVENT_READY` + * `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 + +The following deprecated APIs are removed. + +* `rb_cData` variable. +* "taintedness" and "trustedness" functions. [[Feature #16131]] ## Implementation improvements -* `Array#each` is rewritten in Ruby for better performance [[Feature #20182]]. +* Fixed several race conditions in Kernel#autoload. [[Bug #18782]] +* Cache invalidation for expressions referencing constants is now + more fine-grained. `RubyVM.stat(:global_constant_state)` was + removed because it was closely tied to the previous caching scheme + where setting any constant invalidates all caches in the system. + New keys, `:constant_cache_invalidations` and `:constant_cache_misses`, + were introduced to help with use cases for `:global_constant_state`. + [[Feature #18589]] +* The cache-based optimization for Regexp matching is introduced. + [[Feature #19104]] +* [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 + consistent order will see the most performance benefits. + [[Feature #18776]] +* Speed up marking instruction sequences by using a bitmap to find "markable" + objects. This change results in faster major collections. + [[Feature #18875]] ## JIT -## Miscellaneous changes - -* Passing a block to a method which doesn't use the passed block will show - a warning on verbose mode (`-w`). - [[Feature #15554]] - -* Redefining some core methods that are specially optimized by the interpreter - and JIT like `String.freeze` or `Integer#+` now emits a performance class - warning (`-W:performance` or `Warning[:performance] = true`). - [[Feature #20429]] - -[Feature #13557]: https://bugs.ruby-lang.org/issues/13557 -[Feature #15554]: https://bugs.ruby-lang.org/issues/15554 -[Feature #16495]: https://bugs.ruby-lang.org/issues/16495 -[Feature #18290]: https://bugs.ruby-lang.org/issues/18290 -[Feature #18368]: https://bugs.ruby-lang.org/issues/18368 -[Feature #18980]: https://bugs.ruby-lang.org/issues/18980 -[Misc #18984]: https://bugs.ruby-lang.org/issues/18984 -[Feature #19117]: https://bugs.ruby-lang.org/issues/19117 -[Bug #19918]: https://bugs.ruby-lang.org/issues/19918 -[Bug #20064]: https://bugs.ruby-lang.org/issues/20064 -[Feature #20182]: https://bugs.ruby-lang.org/issues/20182 -[Feature #20205]: https://bugs.ruby-lang.org/issues/20205 -[Bug #20218]: https://bugs.ruby-lang.org/issues/20218 -[Feature #20265]: https://bugs.ruby-lang.org/issues/20265 -[Feature #20429]: https://bugs.ruby-lang.org/issues/20429 -[Feature #20443]: https://bugs.ruby-lang.org/issues/20443 -[Feature #20497]: https://bugs.ruby-lang.org/issues/20497 -[Feature #20624]: https://bugs.ruby-lang.org/issues/20624 +### YJIT + +* YJIT is no longer experimental + * Has been tested on production workloads for over a year and proven to be quite stable. +* YJIT now supports both x86-64 and arm64/aarch64 CPUs on Linux, MacOS, BSD and other UNIX platforms. + * This release brings support for Mac M1/M2, AWS Graviton and Raspberry Pi 4. +* Building YJIT now requires Rust 1.58.0+. [[Feature #18481]] + * In order to ensure that CRuby is built with YJIT, please install `rustc` >= 1.58.0 + before running `./configure` + * Please reach out to the YJIT team should you run into any issues. +* Physical memory for JIT code is lazily allocated. Unlike Ruby 3.1, + the RSS of a Ruby process is minimized because virtual memory pages + allocated by `--yjit-exec-mem-size` will not be mapped to physical + memory pages until actually utilized by JIT code. +* Introduce Code GC that frees all code pages when the memory consumption + by JIT code reaches `--yjit-exec-mem-size`. + * `RubyVM::YJIT.runtime_stats` returns Code GC metrics in addition to + existing `inline_code_size` and `outlined_code_size` keys: + `code_gc_count`, `live_page_count`, `freed_page_count`, and `freed_code_size`. +* Most of the statistics produced by `RubyVM::YJIT.runtime_stats` are now available in release builds. + * Simply run ruby with `--yjit-stats` to compute and dump stats (incurs some run-time overhead). +* YJIT is now optimized to take advantage of object shapes. [[Feature #18776]] +* Take advantage of finer-grained constant invalidation to invalidate less code when defining new constants. [[Feature #18589]] +* The default `--yjit-exec-mem-size` is changed to 64 (MiB). +* The default `--yjit-call-threshold` is changed to 30. + +### 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. +* MinGW is no longer supported. [[Feature #18824]] +* 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 #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 49cf72b5fd..93c0131690 100644 --- a/README.ja.md +++ b/README.ja.md @@ -1,5 +1,5 @@ [](https://github.com/ruby/ruby/actions?query=workflow%3A"MinGW") -[](https://github.com/ruby/ruby/actions?query=workflow%3A"RJIT") +[](https://github.com/ruby/ruby/actions?query=workflow%3A"MJIT") [](https://github.com/ruby/ruby/actions?query=workflow%3A"Ubuntu") [](https://github.com/ruby/ruby/actions?query=workflow%3A"Windows") [](https://ci.appveyor.com/project/ruby/ruby/branch/master) @@ -25,7 +25,7 @@ Rubyはテキスト処理関係の能力などに優れ,Perlと同じくらい * ダイナミックローディング (アーキテクチャによる) * 移植性が高い.多くのUnix-like/POSIX互換プラットフォーム上で動くだけでなく,Windows, macOS, Haikuなどの上でも動く cf. - https://docs.ruby-lang.org/en/master/maintainers_md.html#label-Platform+Maintainers + https://github.com/ruby/ruby/blob/master/doc/contributing.rdoc#platform-maintainers ## 入手法 @@ -49,6 +49,17 @@ https://www.ruby-lang.org/ja/downloads/ Rubyリポジトリの本来のmasterは https://git.ruby-lang.org/ruby.git にあります. コミッタはこちらを使います. +### Subversion + +古いRubyのバージョンのソースコードは次のコマンドでも取得できます. + + $ svn co https://svn.ruby-lang.org/repos/ruby/branches/ruby_2_6/ ruby + +他のブランチの一覧は次のコマンドで見られます. + + $ svn ls https://svn.ruby-lang.org/repos/ruby/branches/ + + ## ホームページ RubyのホームページのURLは @@ -59,20 +70,20 @@ https://www.ruby-lang.org/ ## メーリングリスト -Rubyのメーリングリストがあります.参加希望の方は [ruby-list-request@ml.ruby-lang.org] まで件名に +Rubyのメーリングリストがあります.参加希望の方は [ruby-list-request@ruby-lang.org] まで本文に - join + subscribe と書いて送って下さい. Ruby開発者向けメーリングリストもあります.こちらではrubyのバグ,将来の仕様拡張など実装上の問題について議論されています. -参加希望の方は [ruby-dev-request@ml.ruby-lang.org] までruby-listと同様の方法でメールしてください. +参加希望の方は [ruby-dev-request@ruby-lang.org] までruby-listと同様の方法でメールしてください. Ruby拡張モジュールについて話し合うruby-extメーリングリストと数学関係の話題について話し合うruby-mathメーリングリストと 英語でrubyについて話し合うruby-talkメーリングリストもあります.参加方法はどれも同じです. -[ruby-list-request@ml.ruby-lang.org]: mailto:ruby-list-request@ml.ruby-lang.org?subject=join -[ruby-dev-request@ml.ruby-lang.org]: mailto:ruby-dev-request@ml.ruby-lang.org?subject=join +[ruby-list-request@ruby-lang.org]: mailto:ruby-list-request@ruby-lang.org?subject=Join%20Ruby%20Mailing%20List&body=subscribe +[ruby-dev-request@ruby-lang.org]: mailto:ruby-dev-request@ruby-lang.org?subject=Join%20Ruby%20Mailing%20List&body=subscribe ## コンパイル・インストール @@ -151,7 +162,7 @@ UNIXであれば `configure` がほとんどの差異を吸収してくれるは ## 配布条件 -[COPYING.ja](https://docs.ruby-lang.org/en/master/COPYING_ja.html) ファイルを参照してください. +[COPYING.ja](COPYING.ja) ファイルを参照してください. ## フィードバック @@ -1,7 +1,8 @@ [](https://github.com/ruby/ruby/actions?query=workflow%3A"MinGW") -[](https://github.com/ruby/ruby/actions?query=workflow%3A"RJIT") +[](https://github.com/ruby/ruby/actions?query=workflow%3A"MJIT") [](https://github.com/ruby/ruby/actions?query=workflow%3A"Ubuntu") [](https://github.com/ruby/ruby/actions?query=workflow%3A"Windows") +[](https://ci.appveyor.com/project/ruby/ruby/branch/master) [](https://app.travis-ci.com/ruby/ruby) # What is Ruby? @@ -23,20 +24,15 @@ It is simple, straightforward, and extensible. * Dynamic Loading of Object Files (on some architectures) * Highly Portable (works on many Unix-like/POSIX compatible platforms as well as Windows, macOS, etc.) cf. - https://docs.ruby-lang.org/en/master/maintainers_md.html#label-Platform+Maintainers + https://github.com/ruby/ruby/blob/master/doc/maintainers.rdoc#label-Platform+Maintainers -## How to get Ruby +## How to get Ruby with Git For a complete list of ways to install Ruby, including using third-party tools like rvm, see: https://www.ruby-lang.org/en/downloads/ -You can download release packages and the snapshot of the repository. If you want to -download whole versions of Ruby, please visit https://www.ruby-lang.org/en/downloads/releases/. - -### Download with Git - The mirror of the Ruby source tree can be checked out with the following command: $ git clone https://github.com/ruby/ruby.git @@ -51,7 +47,7 @@ if you are a committer. ## How to build -See [Building Ruby](https://docs.ruby-lang.org/en/master/contributing/building_ruby_md.html) +see [Building Ruby](doc/contributing/building_ruby.md) ## Ruby home page @@ -67,11 +63,11 @@ https://www.ruby-lang.org/ There is a mailing list to discuss Ruby. To subscribe to this list, please send the following phrase: - join + subscribe -in the mail subject (not body) to the address [ruby-talk-request@ml.ruby-lang.org]. +in the mail body (not subject) to the address [ruby-talk-request@ruby-lang.org]. -[ruby-talk-request@ml.ruby-lang.org]: mailto:ruby-talk-request@ml.ruby-lang.org?subject=join +[ruby-talk-request@ruby-lang.org]: mailto:ruby-talk-request@ruby-lang.org?subject=Join%20Ruby%20Mailing%20List&body=subscribe ## Copying diff --git a/addr2line.c b/addr2line.c index 02a3e617a6..e5f25293e2 100644 --- a/addr2line.c +++ b/addr2line.c @@ -8,14 +8,10 @@ **********************************************************************/ -#if defined(__clang__) && defined(__has_warning) -#if __has_warning("-Wgnu-empty-initializer") +#if defined(__clang__) #pragma clang diagnostic ignored "-Wgnu-empty-initializer" -#endif -#if __has_warning("-Wgcc-compat") #pragma clang diagnostic ignored "-Wgcc-compat" #endif -#endif #include "ruby/internal/config.h" #include "ruby/defines.h" @@ -61,21 +57,8 @@ void *alloca(); # endif # endif /* AIX */ # endif /* HAVE_ALLOCA_H */ -# ifndef UNREACHABLE -# define UNREACHABLE __builtin_unreachable() -# endif -# ifndef UNREACHABLE_RETURN -# define UNREACHABLE_RETURN(_) __builtin_unreachable() -# endif #endif /* __GNUC__ */ -#ifndef UNREACHABLE -# define UNREACHABLE abort() -#endif -#ifndef UNREACHABLE_RETURN -# define UNREACHABLE_RETURN(_) return (abort(), (_)) -#endif - #ifdef HAVE_DLADDR # include <dlfcn.h> #endif @@ -144,7 +127,7 @@ void *alloca(); #define DW_LNE_define_file 0x03 #define DW_LNE_set_discriminator 0x04 /* DWARF4 */ -#define kprintf(...) fprintf(errout, "" __VA_ARGS__) +PRINTF_ARGS(static int kprintf(const char *fmt, ...), 1, 2); typedef struct line_info { const char *dirname; @@ -201,7 +184,7 @@ obj_dwarf_section_at(obj_info_t *obj, int n) &obj->debug_line_str }; if (n < 0 || DWARF_SECTION_COUNT <= n) { - UNREACHABLE_RETURN(0); + abort(); } return ary[n]; } @@ -254,7 +237,7 @@ sleb128(const char **p) } static const char * -get_nth_dirname(unsigned long dir, const char *p, FILE *errout) +get_nth_dirname(unsigned long dir, const char *p) { if (!dir--) { return ""; @@ -271,14 +254,10 @@ get_nth_dirname(unsigned long dir, const char *p, FILE *errout) 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, FILE *errout); +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, uint8_t format, uint16_t version, const char *include_directories, - const char *filenames, line_info_t *line, obj_info_t *obj, FILE *errout) +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; @@ -287,9 +266,9 @@ fill_filename(int file, uint8_t format, uint16_t version, const char *include_di if (version >= 5) { const char *path; uint64_t directory_index = -1; - parse_ver5_debug_line_header(filenames, file, format, obj, &path, &directory_index, errout); + 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, errout); + parse_ver5_debug_line_header(include_directories, (int)directory_index, format, obj, &path, NULL); line->dirname = path; } else { @@ -311,7 +290,7 @@ fill_filename(int file, uint8_t format, uint16_t version, const char *include_di if (i == file) { line->filename = filename; - line->dirname = get_nth_dirname(dir, include_directories, errout); + line->dirname = get_nth_dirname(dir, include_directories); } } } @@ -320,7 +299,7 @@ fill_filename(int file, uint8_t format, uint16_t version, const char *include_di static void fill_line(int num_traces, void **traces, uintptr_t addr, int file, int line, uint8_t format, uint16_t version, const char *include_directories, const char *filenames, - obj_info_t *obj, line_info_t *lines, int offset, FILE *errout) + obj_info_t *obj, line_info_t *lines, int offset) { int i; addr += obj->base_addr - obj->vmaddr; @@ -329,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, format, version, include_directories, filenames, &lines[i], obj, errout); + fill_filename(file, format, version, include_directories, filenames, &lines[i], obj); lines[i].line = line; } } @@ -354,7 +333,7 @@ struct LineNumberProgramHeader { }; static int -parse_debug_line_header(obj_info_t *obj, const char **pp, struct LineNumberProgramHeader *header, FILE *errout) +parse_debug_line_header(obj_info_t *obj, const char **pp, struct LineNumberProgramHeader *header) { const char *p = *pp; header->unit_length = *(uint32_t *)p; @@ -400,7 +379,7 @@ parse_debug_line_header(obj_info_t *obj, const char **pp, struct LineNumberProgr if (header->version >= 5) { header->include_directories = p; - p = parse_ver5_debug_line_header(p, -1, header->format, obj, NULL, NULL, errout); + p = parse_ver5_debug_line_header(p, -1, header->format, obj, NULL, NULL); header->filenames = p; } else { @@ -427,7 +406,7 @@ parse_debug_line_header(obj_info_t *obj, const char **pp, struct LineNumberProgr static int parse_debug_line_cu(int num_traces, void **traces, const char **debug_line, - obj_info_t *obj, line_info_t *lines, int offset, FILE *errout) + obj_info_t *obj, line_info_t *lines, int offset) { const char *p = (const char *)*debug_line; struct LineNumberProgramHeader header; @@ -444,7 +423,7 @@ 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(obj, &p, &header, errout)) + if (parse_debug_line_header(obj, &p, &header)) return -1; is_stmt = header.default_is_stmt; @@ -455,7 +434,7 @@ parse_debug_line_cu(int num_traces, void **traces, const char **debug_line, header.version, \ header.include_directories, \ header.filenames, \ - obj, lines, offset, errout); \ + obj, lines, offset); \ /*basic_block = prologue_end = epilogue_begin = 0;*/ \ } while (0) @@ -555,11 +534,11 @@ parse_debug_line_cu(int num_traces, void **traces, const char **debug_line, static int parse_debug_line(int num_traces, void **traces, const char *debug_line, unsigned long size, - obj_info_t *obj, line_info_t *lines, int offset, FILE *errout) + obj_info_t *obj, line_info_t *lines, int offset) { const char *debug_line_end = debug_line + size; while (debug_line < debug_line_end) { - if (parse_debug_line_cu(num_traces, traces, &debug_line, obj, lines, offset, errout)) + if (parse_debug_line_cu(num_traces, traces, &debug_line, obj, lines, offset)) return -1; } if (debug_line != debug_line_end) { @@ -572,7 +551,7 @@ parse_debug_line(int num_traces, void **traces, /* read file and fill lines */ static uintptr_t fill_lines(int num_traces, void **traces, int check_debuglink, - obj_info_t **objp, line_info_t *lines, int offset, FILE *errout); + obj_info_t **objp, line_info_t *lines, int offset); static void append_obj(obj_info_t **objp) @@ -600,7 +579,7 @@ append_obj(obj_info_t **objp) // check the path pattern of "/usr/lib/debug/usr/bin/ruby.debug" static void follow_debuglink(const char *debuglink, int num_traces, void **traces, - obj_info_t **objp, line_info_t *lines, int offset, FILE *errout) + obj_info_t **objp, line_info_t *lines, int offset) { static const char global_debug_dir[] = "/usr/lib/debug"; const size_t global_debug_dir_len = sizeof(global_debug_dir) - 1; @@ -626,13 +605,13 @@ follow_debuglink(const char *debuglink, int num_traces, void **traces, o2 = *objp; o2->base_addr = o1->base_addr; o2->path = o1->path; - fill_lines(num_traces, traces, 0, objp, lines, offset, errout); + fill_lines(num_traces, traces, 0, objp, lines, offset); } // check the path pattern of "/usr/lib/debug/.build-id/ab/cdef1234.debug" static void follow_debuglink_build_id(const char *build_id, size_t build_id_size, int num_traces, void **traces, - obj_info_t **objp, line_info_t *lines, int offset, FILE *errout) + obj_info_t **objp, line_info_t *lines, int offset) { static const char global_debug_dir[] = "/usr/lib/debug/.build-id/"; const size_t global_debug_dir_len = sizeof(global_debug_dir) - 1; @@ -657,7 +636,7 @@ follow_debuglink_build_id(const char *build_id, size_t build_id_size, int num_tr o2 = *objp; o2->base_addr = o1->base_addr; o2->path = o1->path; - fill_lines(num_traces, traces, 0, objp, lines, offset, errout); + fill_lines(num_traces, traces, 0, objp, lines, offset); } #endif @@ -861,11 +840,7 @@ enum DW_FORM_addrx1 = 0x29, DW_FORM_addrx2 = 0x2a, DW_FORM_addrx3 = 0x2b, - DW_FORM_addrx4 = 0x2c, - - /* GNU extensions for referring to .gnu_debugaltlink dwz-compressed info */ - DW_FORM_GNU_ref_alt = 0x1f20, - DW_FORM_GNU_strp_alt = 0x1f21 + DW_FORM_addrx4 = 0x2c }; /* Range list entry encodings */ @@ -1083,13 +1058,13 @@ di_read_debug_abbrev_cu(DebugInfoReader *reader) } static int -di_read_debug_line_cu(DebugInfoReader *reader, FILE *errout) +di_read_debug_line_cu(DebugInfoReader *reader) { const char *p; struct LineNumberProgramHeader header; p = (const char *)reader->debug_line_cu_end; - if (parse_debug_line_header(reader->obj, &p, &header, errout)) + if (parse_debug_line_header(reader->obj, &p, &header)) return -1; reader->debug_line_cu_end = (char *)header.cu_end; @@ -1169,32 +1144,25 @@ resolve_strx(DebugInfoReader *reader, uint64_t idx) return reader->obj->debug_str.ptr + off; } -static bool -debug_info_reader_read_addr_value_member(DebugInfoReader *reader, DebugInfoValue *v, int size) +static void +debug_info_reader_read_addr_value(DebugInfoReader *reader, DebugInfoValue *v) { - if (size == 4) { + if (reader->address_size == 4) { set_uint_value(v, read_uint32(&reader->p)); - } else if (size == 8) { + } else if (reader->address_size == 8) { set_uint_value(v, read_uint64(&reader->p)); } else { - return false; + fprintf(stderr,"unknown address_size:%d", reader->address_size); + abort(); } - return true; } -#define debug_info_reader_read_addr_value(reader, v, mem) \ - if (!debug_info_reader_read_addr_value_member((reader), (v), (reader)->mem)) { \ - kprintf("unknown " #mem ":%d", (reader)->mem); \ - return false; \ - } - - -static bool -debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoValue *v, FILE *errout) +static void +debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoValue *v) { switch (form) { case DW_FORM_addr: - debug_info_reader_read_addr_value(reader, v, address_size); + debug_info_reader_read_addr_value(reader, v); break; case DW_FORM_block2: v->size = read_uint16(&reader->p); @@ -1249,9 +1217,16 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa 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, address_size); + debug_info_reader_read_addr_value(reader, v); } else { - debug_info_reader_read_addr_value(reader, v, format); + 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: @@ -1352,28 +1327,20 @@ debug_info_reader_read_value(DebugInfoReader *reader, uint64_t form, DebugInfoVa case DW_FORM_addrx4: set_addr_idx_value(v, read_uint32(&reader->p)); break; - /* we have no support for actually reading the real values of these refs out - * of the .gnu_debugaltlink dwz-compressed debuginfo at the moment, but "read" - * them anyway so that we advance the reader by the right amount. */ - case DW_FORM_GNU_ref_alt: - case DW_FORM_GNU_strp_alt: - read_uint(reader); - set_uint_value(v, 0); - break; case 0: goto fail; break; } - return true; + return; fail: - kprintf("%d: unsupported form: %#"PRIx64"\n", __LINE__, form); - return false; + fprintf(stderr, "%d: unsupported form: %#"PRIx64"\n", __LINE__, form); + exit(1); } /* find abbrev in current compilation unit */ static const char * -di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number, FILE *errout) +di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number) { const char *p; if (abbrev_number < ABBREV_TABLE_SIZE) { @@ -1386,8 +1353,8 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number, FILE *errout) di_skip_die_attributes(&p); for (uint64_t n = uleb128(&p); abbrev_number != n; n = uleb128(&p)) { if (n == 0) { - kprintf("%d: Abbrev Number %"PRId64" not found\n",__LINE__, abbrev_number); - return NULL; + fprintf(stderr,"%d: Abbrev Number %"PRId64" not found\n",__LINE__, abbrev_number); + exit(1); } uleb128(&p); /* tag */ p++; /* has_children */ @@ -1398,52 +1365,52 @@ di_find_abbrev(DebugInfoReader *reader, uint64_t abbrev_number, FILE *errout) #if 0 static void -hexdump0(const unsigned char *p, size_t n, FILE *errout) +hexdump0(const unsigned char *p, size_t n) { size_t i; - kprintf(" 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); + fprintf(stderr, " 0 1 2 3 4 5 6 7 8 9 A B C D E F\n"); for (i=0; i < n; i++){ switch (i & 15) { case 0: - kprintf("%02" PRIdSIZE ": %02X ", i/16, p[i]); + fprintf(stderr, "%02" PRIdSIZE ": %02X ", i/16, p[i]); break; case 15: - kprintf("%02X\n", p[i]); + fprintf(stderr, "%02X\n", p[i]); break; default: - kprintf("%02X ", p[i]); + fprintf(stderr, "%02X ", p[i]); break; } } if ((i & 15) != 15) { - kprintf("\n"); + fprintf(stderr, "\n"); } } -#define hexdump(p,n,e) hexdump0((const unsigned char *)p, n, e) +#define hexdump(p,n) hexdump0((const unsigned char *)p, n) static void -div_inspect(DebugInfoValue *v, FILE *errout) +div_inspect(DebugInfoValue *v) { switch (v->type) { case VAL_uint: - kprintf("%d: type:%d size:%" PRIxSIZE " v:%"PRIx64"\n",__LINE__,v->type,v->size,v->as.uint64); + fprintf(stderr,"%d: type:%d size:%" PRIxSIZE " v:%"PRIx64"\n",__LINE__,v->type,v->size,v->as.uint64); break; case VAL_int: - kprintf("%d: type:%d size:%" PRIxSIZE " v:%"PRId64"\n",__LINE__,v->type,v->size,(int64_t)v->as.uint64); + fprintf(stderr,"%d: type:%d size:%" PRIxSIZE " v:%"PRId64"\n",__LINE__,v->type,v->size,(int64_t)v->as.uint64); break; case VAL_cstr: - kprintf("%d: type:%d size:%" PRIxSIZE " v:'%s'\n",__LINE__,v->type,v->size,v->as.ptr); + fprintf(stderr,"%d: type:%d size:%" PRIxSIZE " v:'%s'\n",__LINE__,v->type,v->size,v->as.ptr); break; case VAL_data: - kprintf("%d: type:%d size:%" PRIxSIZE " v:\n",__LINE__,v->type,v->size); - hexdump(v->as.ptr, 16, errout); + fprintf(stderr,"%d: type:%d size:%" PRIxSIZE " v:\n",__LINE__,v->type,v->size); + hexdump(v->as.ptr, 16); break; } } #endif static DIE * -di_read_die(DebugInfoReader *reader, DIE *die, FILE *errout) +di_read_die(DebugInfoReader *reader, DIE *die) { uint64_t abbrev_number = uleb128(&reader->p); if (abbrev_number == 0) { @@ -1451,7 +1418,7 @@ di_read_die(DebugInfoReader *reader, DIE *die, FILE *errout) return NULL; } - if (!(reader->q = di_find_abbrev(reader, abbrev_number, errout))) return NULL; + reader->q = di_find_abbrev(reader, abbrev_number); die->pos = reader->p - reader->obj->debug_info.ptr - 1; die->tag = (int)uleb128(&reader->q); /* tag */ @@ -1463,26 +1430,26 @@ di_read_die(DebugInfoReader *reader, DIE *die, FILE *errout) } static DebugInfoValue * -di_read_record(DebugInfoReader *reader, DebugInfoValue *vp, FILE *errout) +di_read_record(DebugInfoReader *reader, DebugInfoValue *vp) { uint64_t at = uleb128(&reader->q); uint64_t form = uleb128(&reader->q); if (!at || !form) return NULL; vp->at = at; vp->form = form; - if (!debug_info_reader_read_value(reader, form, vp, errout)) return NULL; + debug_info_reader_read_value(reader, form, vp); return vp; } -static bool -di_skip_records(DebugInfoReader *reader, FILE *errout) +static void +di_skip_records(DebugInfoReader *reader) { for (;;) { - DebugInfoValue v = {{0}}; + DebugInfoValue v = {{}}; uint64_t at = uleb128(&reader->q); uint64_t form = uleb128(&reader->q); - if (!at || !form) return true; - if (!debug_info_reader_read_value(reader, form, &v, errout)) return false; + if (!at || !form) return; + debug_info_reader_read_value(reader, form, &v); } } @@ -1494,14 +1461,13 @@ typedef struct addr_header { /* uint8_t segment_selector_size; */ } addr_header_t; -static bool -addr_header_init(obj_info_t *obj, addr_header_t *header, FILE *errout) -{ +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 true; + if (!p) return; header->unit_length = *(uint32_t *)p; p += sizeof(uint32_t); @@ -1515,12 +1481,7 @@ addr_header_init(obj_info_t *obj, addr_header_t *header, FILE *errout) p += 2; /* version */ header->address_size = *p++; - if (header->address_size != 4 && header->address_size != 8) { - kprintf("unknown address_size:%d", header->address_size); - return false; - } p++; /* segment_selector_size */ - return true; } static uint64_t @@ -1540,12 +1501,11 @@ typedef struct rnglists_header { uint32_t offset_entry_count; } rnglists_header_t; -static bool -rnglists_header_init(obj_info_t *obj, rnglists_header_t *header, FILE *errout) -{ +static void +rnglists_header_init(obj_info_t *obj, rnglists_header_t *header) { const char *p = obj->debug_rnglists.ptr; - if (!p) return true; + if (!p) return; header->unit_length = *(uint32_t *)p; p += sizeof(uint32_t); @@ -1559,13 +1519,8 @@ rnglists_header_init(obj_info_t *obj, rnglists_header_t *header, FILE *errout) p += 2; /* version */ header->address_size = *p++; - if (header->address_size != 4 && header->address_size != 8) { - kprintf("unknown address_size:%d", header->address_size); - return false; - } p++; /* segment_selector_size */ header->offset_entry_count = *(uint32_t *)p; - return true; } typedef struct { @@ -1609,23 +1564,26 @@ ranges_set(ranges_t *ptr, DebugInfoValue *v, addr_header_t *addr_header, uint64_ } static uint64_t -read_dw_form_addr(DebugInfoReader *reader, const char **ptr, FILE *errout) +read_dw_form_addr(DebugInfoReader *reader, const char **ptr) { const char *p = *ptr; *ptr = p + reader->address_size; if (reader->address_size == 4) { return read_uint32(&p); - } else { + } else if (reader->address_size == 8) { return read_uint64(&p); + } else { + fprintf(stderr,"unknown address_size:%d", reader->address_size); + abort(); } } static uintptr_t -ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr, rnglists_header_t *rnglists_header, FILE *errout) +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) { - return UINTPTR_MAX; + exit(1); } if (ptr->low_pc <= addr && addr <= ptr->high_pc) { return (uintptr_t)ptr->low_pc; @@ -1674,15 +1632,15 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr, rnglists_h to = (uintptr_t)base + uleb128(&p); break; case DW_RLE_base_address: - base = read_dw_form_addr(reader, &p, errout); + base = read_dw_form_addr(reader, &p); base_valid = true; break; case DW_RLE_start_end: - from = (uintptr_t)read_dw_form_addr(reader, &p, errout); - to = (uintptr_t)read_dw_form_addr(reader, &p, errout); + from = (uintptr_t)read_dw_form_addr(reader, &p); + to = (uintptr_t)read_dw_form_addr(reader, &p); break; case DW_RLE_start_length: - from = (uintptr_t)read_dw_form_addr(reader, &p, errout); + from = (uintptr_t)read_dw_form_addr(reader, &p); to = from + uleb128(&p); break; } @@ -1690,7 +1648,7 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr, rnglists_h return from; } } - return 0; + return false; } p = reader->obj->debug_ranges.ptr + ptr->ranges; for (;;) { @@ -1711,42 +1669,42 @@ ranges_include(DebugInfoReader *reader, ranges_t *ptr, uint64_t addr, rnglists_h return (uintptr_t)ptr->low_pc; } } - return 0; + return false; } #if 0 static void -ranges_inspect(DebugInfoReader *reader, ranges_t *ptr, FILE *errout) +ranges_inspect(DebugInfoReader *reader, ranges_t *ptr) { if (ptr->high_pc_set) { if (ptr->ranges_set || !ptr->low_pc_set) { - kprintf("low_pc_set:%d high_pc_set:%d ranges_set:%d\n",ptr->low_pc_set,ptr->high_pc_set,ptr->ranges_set); - return; + fprintf(stderr,"low_pc_set:%d high_pc_set:%d ranges_set:%d\n",ptr->low_pc_set,ptr->high_pc_set,ptr->ranges_set); + exit(1); } - kprintf("low_pc:%"PRIx64" high_pc:%"PRIx64"\n",ptr->low_pc,ptr->high_pc); + fprintf(stderr,"low_pc:%"PRIx64" high_pc:%"PRIx64"\n",ptr->low_pc,ptr->high_pc); } else if (ptr->ranges_set) { char *p = reader->obj->debug_ranges.ptr + ptr->ranges; - kprintf("low_pc:%"PRIx64" ranges:%"PRIx64" %lx ",ptr->low_pc,ptr->ranges, p-reader->obj->mapped); + fprintf(stderr,"low_pc:%"PRIx64" ranges:%"PRIx64" %lx ",ptr->low_pc,ptr->ranges, p-reader->obj->mapped); for (;;) { uintptr_t from = read_uintptr(&p); uintptr_t to = read_uintptr(&p); if (!from && !to) break; - kprintf("%"PRIx64"-%"PRIx64" ",ptr->low_pc+from,ptr->low_pc+to); + fprintf(stderr,"%"PRIx64"-%"PRIx64" ",ptr->low_pc+from,ptr->low_pc+to); } - kprintf("\n"); + fprintf(stderr,"\n"); } else if (ptr->low_pc_set) { - kprintf("low_pc:%"PRIx64"\n",ptr->low_pc); + fprintf(stderr,"low_pc:%"PRIx64"\n",ptr->low_pc); } else { - kprintf("empty\n"); + fprintf(stderr,"empty\n"); } } #endif static int -di_read_cu(DebugInfoReader *reader, FILE *errout) +di_read_cu(DebugInfoReader *reader) { uint64_t unit_length; uint16_t version; @@ -1773,23 +1731,23 @@ di_read_cu(DebugInfoReader *reader, FILE *errout) debug_abbrev_offset = read_uint(reader); reader->address_size = read_uint8(&reader->p); } - if (reader->address_size != 4 && reader->address_size != 8) { - kprintf("unknown address_size:%d", reader->address_size); - return -1; - } reader->q0 = reader->obj->debug_abbrev.ptr + debug_abbrev_offset; reader->level = 0; di_read_debug_abbrev_cu(reader); - if (di_read_debug_line_cu(reader, errout)) return -1; + if (di_read_debug_line_cu(reader)) return -1; +#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER_BUILD_DATE) + /* Though DWARF specifies "the applicable base address defaults to the base + address of the compilation unit", but GCC seems to use zero as default */ +#else do { DIE die; - if (!di_read_die(reader, &die, errout)) continue; + if (!di_read_die(reader, &die)) continue; if (die.tag != DW_TAG_compile_unit) { - if (!di_skip_records(reader, errout)) return -1; + di_skip_records(reader); break; } @@ -1797,11 +1755,11 @@ di_read_cu(DebugInfoReader *reader, FILE *errout) reader->current_addr_base = 0; reader->current_rnglists_base = 0; - DebugInfoValue low_pc = {{0}}; + DebugInfoValue low_pc = {{}}; /* enumerate abbrev */ for (;;) { - DebugInfoValue v = {{0}}; - if (!di_read_record(reader, &v, errout)) break; + DebugInfoValue v = {{}}; + if (!di_read_record(reader, &v)) break; switch (v.at) { case DW_AT_low_pc: // clang may output DW_AT_addr_base after DW_AT_low_pc. @@ -1826,19 +1784,19 @@ di_read_cu(DebugInfoReader *reader, FILE *errout) break; case VAL_addr: { - addr_header_t header = {0}; - if (!addr_header_init(reader->obj, &header, errout)) return -1; + 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; } static void -read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_origin, line_info_t *line, FILE *errout) +read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_origin, line_info_t *line) { const char *p = reader->p; const char *q = reader->q; @@ -1863,12 +1821,12 @@ read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_o default: goto finish; } - if (!di_read_die(reader, &die, errout)) goto finish; + if (!di_read_die(reader, &die)) goto finish; /* enumerate abbrev */ for (;;) { - DebugInfoValue v = {{0}}; - if (!di_read_record(reader, &v, errout)) break; + DebugInfoValue v = {{}}; + if (!di_read_record(reader, &v)) break; switch (v.at) { case DW_AT_name: line->sname = get_cstr_value(&v); @@ -1882,44 +1840,43 @@ read_abstract_origin(DebugInfoReader *reader, uint64_t form, uint64_t abstract_o reader->level = level; } -static bool +static void debug_info_read(DebugInfoReader *reader, int num_traces, void **traces, - line_info_t *lines, int offset, FILE *errout) -{ + line_info_t *lines, int offset) { - addr_header_t addr_header = {0}; - if (!addr_header_init(reader->obj, &addr_header, errout)) return false; + addr_header_t addr_header = {}; + addr_header_init(reader->obj, &addr_header); - rnglists_header_t rnglists_header = {0}; - if (!rnglists_header_init(reader->obj, &rnglists_header, errout)) return false; + rnglists_header_t rnglists_header = {}; + rnglists_header_init(reader->obj, &rnglists_header); while (reader->p < reader->cu_end) { DIE die; - ranges_t ranges = {0}; - line_info_t line = {0}; + ranges_t ranges = {}; + line_info_t line = {}; - if (!di_read_die(reader, &die, errout)) continue; - /* kprintf("%d:%tx: <%d>\n",__LINE__,die.pos,reader->level,die.tag); */ + if (!di_read_die(reader, &die)) continue; + /* fprintf(stderr,"%d:%tx: <%d>\n",__LINE__,die.pos,reader->level,die.tag); */ if (die.tag != DW_TAG_subprogram && die.tag != DW_TAG_inlined_subroutine) { skip_die: - if (!di_skip_records(reader, errout)) return false; + di_skip_records(reader); continue; } /* enumerate abbrev */ for (;;) { - DebugInfoValue v = {{0}}; + DebugInfoValue v = {{}}; /* ptrdiff_t pos = reader->p - reader->p0; */ - if (!di_read_record(reader, &v, errout)) break; - /* kprintf("\n%d:%tx: AT:%lx FORM:%lx\n",__LINE__,pos,v.at,v.form); */ - /* div_inspect(&v, errout); */ + if (!di_read_record(reader, &v)) break; + /* fprintf(stderr,"\n%d:%tx: AT:%lx FORM:%lx\n",__LINE__,pos,v.at,v.form); */ + /* div_inspect(&v); */ switch (v.at) { case DW_AT_name: line.sname = get_cstr_value(&v); break; case DW_AT_call_file: - 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, errout); + 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; @@ -1935,19 +1892,18 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces, /* 1 or 3 */ break; /* goto skip_die; */ case DW_AT_abstract_origin: - read_abstract_origin(reader, v.form, v.as.uint64, &line, errout); + read_abstract_origin(reader, v.form, v.as.uint64, &line); break; /* goto skip_die; */ } } - /* ranges_inspect(reader, &ranges, errout); */ - /* kprintf("%d:%tx: %x ",__LINE__,diepos,die.tag); */ + /* ranges_inspect(reader, &ranges); */ + /* fprintf(stderr,"%d:%tx: %x ",__LINE__,diepos,die.tag); */ 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, &rnglists_header, errout); - if (saddr == UINTPTR_MAX) return false; + uintptr_t saddr = ranges_include(reader, &ranges, offset, &rnglists_header); if (saddr) { - /* kprintf("%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)); @@ -1964,7 +1920,6 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces, } } } - return true; } // This function parses the following attributes of Line Number Program Header in DWARF 5: @@ -1983,10 +1938,7 @@ debug_info_read(DebugInfoReader *reader, int num_traces, void **traces, // // 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, FILE *errout) -{ +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; @@ -1996,17 +1948,17 @@ parse_ver5_debug_line_header(const char *p, int idx, uint8_t format, int entry_count = (int)uleb128(&p); - DebugInfoReader reader = {0}; + 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 = {{0}}; + DebugInfoValue v = {{}}; unsigned long dw_lnct = uleb128(&format); unsigned long dw_form = uleb128(&format); - if (!debug_info_reader_read_value(&reader, dw_form, &v, errout)) return 0; + 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) @@ -2051,7 +2003,7 @@ fail: /* read file and fill lines */ static uintptr_t fill_lines(int num_traces, void **traces, int check_debuglink, - obj_info_t **objp, line_info_t *lines, int offset, FILE *errout) + obj_info_t **objp, line_info_t *lines, int offset) { int i, j; char *shstr; @@ -2211,10 +2163,9 @@ fill_lines(int num_traces, void **traces, int check_debuglink, debug_info_reader_init(&reader, obj); i = 0; while (reader.p < reader.pend) { - /* kprintf("%d:%tx: CU[%d]\n", __LINE__, reader.p - reader.obj->debug_info.ptr, i++); */ - if (di_read_cu(&reader, errout)) goto use_symtab; - if (!debug_info_read(&reader, num_traces, traces, lines, offset, errout)) - goto use_symtab; + /* fprintf(stderr, "%d:%tx: CU[%d]\n", __LINE__, reader.p - reader.obj->debug_info.ptr, i++); */ + if (di_read_cu(&reader)) goto use_symtab; + debug_info_read(&reader, num_traces, traces, lines, offset); } } else { @@ -2254,14 +2205,14 @@ use_symtab: if (gnu_debuglink_shdr && check_debuglink) { follow_debuglink(file + gnu_debuglink_shdr->sh_offset, num_traces, traces, - objp, lines, offset, errout); + objp, lines, offset); } if (note_gnu_build_id && check_debuglink) { ElfW(Nhdr) *nhdr = (ElfW(Nhdr)*) (file + note_gnu_build_id->sh_offset); const char *build_id = (char *)(nhdr + 1) + nhdr->n_namesz; follow_debuglink_build_id(build_id, nhdr->n_descsz, num_traces, traces, - objp, lines, offset, errout); + objp, lines, offset); } goto finish; } @@ -2269,7 +2220,7 @@ use_symtab: if (parse_debug_line(num_traces, traces, obj->debug_line.ptr, obj->debug_line.size, - obj, lines, offset, errout) == -1) + obj, lines, offset) == -1) goto fail; finish: @@ -2281,7 +2232,7 @@ fail: /* read file and fill lines */ static uintptr_t fill_lines(int num_traces, void **traces, int check_debuglink, - obj_info_t **objp, line_info_t *lines, int offset, FILE *errout) + obj_info_t **objp, line_info_t *lines, int offset) { # ifdef __LP64__ # define LP(x) x##_64 @@ -2360,13 +2311,13 @@ fill_lines(int num_traces, void **traces, int check_debuglink, struct fat_header *fat = (struct fat_header *)file; char *q = file + sizeof(*fat); uint32_t nfat_arch = __builtin_bswap32(fat->nfat_arch); - /* kprintf("%d: fat:%s %d\n",__LINE__, binary_filename,nfat_arch); */ + /* fprintf(stderr,"%d: fat:%s %d\n",__LINE__, binary_filename,nfat_arch); */ for (uint32_t i = 0; i < nfat_arch; i++) { struct fat_arch *arch = (struct fat_arch *)q; cpu_type_t cputype = __builtin_bswap32(arch->cputype); cpu_subtype_t cpusubtype = __builtin_bswap32(arch->cpusubtype); uint32_t offset = __builtin_bswap32(arch->offset); - /* kprintf("%d: fat %d %x/%x %x/%x\n",__LINE__, i, mhp->cputype,mhp->cpusubtype, cputype,cpusubtype); */ + /* fprintf(stderr,"%d: fat %d %x/%x %x/%x\n",__LINE__, i, mhp->cputype,mhp->cpusubtype, cputype,cpusubtype); */ if (mhp->cputype == cputype && (cpu_subtype_t)(mhp->cpusubtype & ~CPU_SUBTYPE_MASK) == cpusubtype) { p = file + offset; @@ -2384,14 +2335,13 @@ fill_lines(int num_traces, void **traces, int check_debuglink, goto fail; } else { + kprintf("'%s' is not a " # ifdef __LP64__ -# define bitsize "64" + "64" # else -# define bitsize "32" + "32" # endif - kprintf("'%s' is not a " bitsize "-bit Mach-O file!\n",binary_filename); -# undef bitsize close(fd); goto fail; } @@ -2483,16 +2433,15 @@ found_mach_header: DebugInfoReader reader; debug_info_reader_init(&reader, obj); while (reader.p < reader.pend) { - if (di_read_cu(&reader, errout)) goto fail; - if (!debug_info_read(&reader, num_traces, traces, lines, offset, errout)) - goto fail; + if (di_read_cu(&reader)) goto fail; + debug_info_read(&reader, num_traces, traces, lines, offset); } } if (parse_debug_line(num_traces, traces, obj->debug_line.ptr, obj->debug_line.size, - obj, lines, offset, errout) == -1) + obj, lines, offset) == -1) goto fail; return dladdr_fbase; @@ -2505,7 +2454,7 @@ fail: #if defined(__FreeBSD__) || defined(__DragonFly__) # include <sys/sysctl.h> #endif -/* ssize_t main_exe_path(FILE *errout) +/* ssize_t main_exe_path(void) * * store the path of the main executable to `binary_filename`, * and returns strlen(binary_filename). @@ -2513,7 +2462,7 @@ fail: */ #if defined(__linux__) || defined(__NetBSD__) static ssize_t -main_exe_path(FILE *errout) +main_exe_path(void) { # if defined(__linux__) # define PROC_SELF_EXE "/proc/self/exe" @@ -2527,7 +2476,7 @@ main_exe_path(FILE *errout) } #elif defined(__FreeBSD__) || defined(__DragonFly__) static ssize_t -main_exe_path(FILE *errout) +main_exe_path(void) { int mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; size_t len = PATH_MAX; @@ -2541,7 +2490,7 @@ main_exe_path(FILE *errout) } #elif defined(HAVE_LIBPROC_H) static ssize_t -main_exe_path(FILE *errout) +main_exe_path(void) { int len = proc_pidpath(getpid(), binary_filename, PATH_MAX); if (len == 0) return 0; @@ -2553,7 +2502,7 @@ main_exe_path(FILE *errout) #endif static void -print_line0(line_info_t *line, void *address, FILE *errout) +print_line0(line_info_t *line, void *address) { uintptr_t addr = (uintptr_t)address; uintptr_t d = addr - line->saddr; @@ -2594,16 +2543,16 @@ print_line0(line_info_t *line, void *address, FILE *errout) } static void -print_line(line_info_t *line, void *address, FILE *errout) +print_line(line_info_t *line, void *address) { - print_line0(line, address, errout); + print_line0(line, address); if (line->next) { - print_line(line->next, NULL, errout); + print_line(line->next, NULL); } } void -rb_dump_backtrace_with_lines(int num_traces, void **traces, FILE *errout) +rb_dump_backtrace_with_lines(int num_traces, void **traces) { int i; /* async-signal unsafe */ @@ -2615,14 +2564,14 @@ rb_dump_backtrace_with_lines(int num_traces, void **traces, FILE *errout) #ifdef HAVE_MAIN_EXE_PATH char *main_path = NULL; /* used on printing backtrace */ ssize_t len; - if ((len = main_exe_path(errout)) > 0) { + if ((len = main_exe_path()) > 0) { main_path = (char *)alloca(len + 1); if (main_path) { uintptr_t addr; memcpy(main_path, binary_filename, len+1); append_obj(&obj); obj->path = main_path; - addr = fill_lines(num_traces, traces, 1, &obj, lines, -1, errout); + addr = fill_lines(num_traces, traces, 1, &obj, lines, -1); if (addr != (uintptr_t)-1) { dladdr_fbases[0] = (void *)addr; } @@ -2659,7 +2608,7 @@ rb_dump_backtrace_with_lines(int num_traces, void **traces, FILE *errout) lines[i].saddr = (uintptr_t)info.dli_saddr; } strlcpy(binary_filename, path, PATH_MAX); - if (fill_lines(num_traces, traces, 1, &obj, lines, i, errout) == (uintptr_t)-1) + if (fill_lines(num_traces, traces, 1, &obj, lines, i) == (uintptr_t)-1) break; } next_line: @@ -2668,7 +2617,7 @@ next_line: /* output */ for (i = 0; i < num_traces; i++) { - print_line(&lines[i], traces[i], errout); + print_line(&lines[i], traces[i]); /* FreeBSD's backtrace may show _start and so on */ if (lines[i].sname && strcmp("main", lines[i].sname) == 0) @@ -2702,8 +2651,435 @@ next_line: free(dladdr_fbases); } -#undef kprintf +/* From FreeBSD's lib/libstand/printf.c */ +/*- + * Copyright (c) 1986, 1988, 1991, 1993 + * The Regents of the University of California. All rights reserved. + * (c) UNIX System Laboratories, Inc. + * All or some portions of this file are derived from material licensed + * to the University of California by American Telephone and Telegraph + * Co. or Unix System Laboratories, Inc. and are reproduced herein with + * the permission of UNIX System Laboratories, Inc. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)subr_prf.c 8.3 (Berkeley) 1/21/94 + */ + +#include <stdarg.h> +#define MAXNBUF (sizeof(intmax_t) * CHAR_BIT + 1) +static inline int toupper(int c) { return ('A' <= c && c <= 'Z') ? (c&0x5f) : c; } +#define hex2ascii(hex) (hex2ascii_data[hex]) +static const char hex2ascii_data[] = "0123456789abcdefghijklmnopqrstuvwxyz"; +static inline int imax(int a, int b) { return (a > b ? a : b); } +static int kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap); + +static void putce(int c) +{ + char s[1]; + ssize_t ret; + + s[0] = (char)c; + ret = write(2, s, 1); + (void)ret; +} + +static int +kprintf(const char *fmt, ...) +{ + va_list ap; + int retval; + va_start(ap, fmt); + retval = kvprintf(fmt, putce, NULL, 10, ap); + va_end(ap); + return retval; +} + +/* + * Put a NUL-terminated ASCII number (base <= 36) in a buffer in reverse + * order; return an optional length and a pointer to the last character + * written in the buffer (i.e., the first character of the string). + * The buffer pointed to by `nbuf' must have length >= MAXNBUF. + */ +static char * +ksprintn(char *nbuf, uintmax_t num, int base, int *lenp, int upper) +{ + char *p, c; + + p = nbuf; + *p = '\0'; + do { + c = hex2ascii(num % base); + *++p = upper ? toupper(c) : c; + } while (num /= base); + if (lenp) + *lenp = (int)(p - nbuf); + return (p); +} + +/* + * Scaled down version of printf(3). + * + * Two additional formats: + * + * The format %b is supported to decode error registers. + * Its usage is: + * + * printf("reg=%b\n", regval, "<base><arg>*"); + * + * where <base> is the output base expressed as a control character, e.g. + * \10 gives octal; \20 gives hex. Each arg is a sequence of characters, + * the first of which gives the bit number to be inspected (origin 1), and + * the next characters (up to a control character, i.e. a character <= 32), + * give the name of the register. Thus: + * + * kvprintf("reg=%b\n", 3, "\10\2BITTWO\1BITONE\n"); + * + * would produce output: + * + * reg=3<BITTWO,BITONE> + * + * XXX: %D -- Hexdump, takes pointer and separator string: + * ("%6D", ptr, ":") -> XX:XX:XX:XX:XX:XX + * ("%*D", len, ptr, " " -> XX XX XX XX ... + */ +static int +kvprintf(char const *fmt, void (*func)(int), void *arg, int radix, va_list ap) +{ +#define PCHAR(c) {int cc=(c); if (func) (*func)(cc); else *d++ = cc; retval++; } + char nbuf[MAXNBUF]; + char *d; + const char *p, *percent, *q; + unsigned char *up; + int ch, n; + uintmax_t num; + int base, lflag, qflag, tmp, width, ladjust, sharpflag, neg, sign, dot; + int cflag, hflag, jflag, tflag, zflag; + int dwidth, upper; + char padc; + int stop = 0, retval = 0; + + num = 0; + if (!func) + d = (char *) arg; + else + d = NULL; + + if (fmt == NULL) + fmt = "(fmt null)\n"; + + if (radix < 2 || radix > 36) + radix = 10; + + for (;;) { + padc = ' '; + width = 0; + while ((ch = (unsigned char)*fmt++) != '%' || stop) { + if (ch == '\0') + return (retval); + PCHAR(ch); + } + percent = fmt - 1; + qflag = 0; lflag = 0; ladjust = 0; sharpflag = 0; neg = 0; + sign = 0; dot = 0; dwidth = 0; upper = 0; + cflag = 0; hflag = 0; jflag = 0; tflag = 0; zflag = 0; +reswitch: switch (ch = (unsigned char)*fmt++) { + case '.': + dot = 1; + goto reswitch; + case '#': + sharpflag = 1; + goto reswitch; + case '+': + sign = 1; + goto reswitch; + case '-': + ladjust = 1; + goto reswitch; + case '%': + PCHAR(ch); + break; + case '*': + if (!dot) { + width = va_arg(ap, int); + if (width < 0) { + ladjust = !ladjust; + width = -width; + } + } else { + dwidth = va_arg(ap, int); + } + goto reswitch; + case '0': + if (!dot) { + padc = '0'; + goto reswitch; + } + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + for (n = 0;; ++fmt) { + n = n * 10 + ch - '0'; + ch = *fmt; + if (ch < '0' || ch > '9') + break; + } + if (dot) + dwidth = n; + else + width = n; + goto reswitch; + case 'b': + num = (unsigned int)va_arg(ap, int); + p = va_arg(ap, char *); + for (q = ksprintn(nbuf, num, *p++, NULL, 0); *q;) + PCHAR(*q--); + + if (num == 0) + break; + + for (tmp = 0; *p;) { + n = *p++; + if (num & (1 << (n - 1))) { + PCHAR(tmp ? ',' : '<'); + for (; (n = *p) > ' '; ++p) + PCHAR(n); + tmp = 1; + } else + for (; *p > ' '; ++p) + continue; + } + if (tmp) + PCHAR('>'); + break; + case 'c': + PCHAR(va_arg(ap, int)); + break; + case 'D': + up = va_arg(ap, unsigned char *); + p = va_arg(ap, char *); + if (!width) + width = 16; + while(width--) { + PCHAR(hex2ascii(*up >> 4)); + PCHAR(hex2ascii(*up & 0x0f)); + up++; + if (width) + for (q=p;*q;q++) + PCHAR(*q); + } + break; + case 'd': + case 'i': + base = 10; + sign = 1; + goto handle_sign; + case 'h': + if (hflag) { + hflag = 0; + cflag = 1; + } else + hflag = 1; + goto reswitch; + case 'j': + jflag = 1; + goto reswitch; + case 'l': + if (lflag) { + lflag = 0; + qflag = 1; + } else + lflag = 1; + goto reswitch; + case 'n': + if (jflag) + *(va_arg(ap, intmax_t *)) = retval; + else if (qflag) + *(va_arg(ap, int64_t *)) = retval; + else if (lflag) + *(va_arg(ap, long *)) = retval; + else if (zflag) + *(va_arg(ap, size_t *)) = retval; + else if (hflag) + *(va_arg(ap, short *)) = retval; + else if (cflag) + *(va_arg(ap, char *)) = retval; + else + *(va_arg(ap, int *)) = retval; + break; + case 'o': + base = 8; + goto handle_nosign; + case 'p': + base = 16; + sharpflag = (width == 0); + sign = 0; + num = (uintptr_t)va_arg(ap, void *); + goto number; + case 'q': + qflag = 1; + goto reswitch; + case 'r': + base = radix; + if (sign) + goto handle_sign; + goto handle_nosign; + case 's': + p = va_arg(ap, char *); + if (p == NULL) + p = "(null)"; + if (!dot) + n = (int)strlen (p); + else + for (n = 0; n < dwidth && p[n]; n++) + continue; + + width -= n; + + if (!ladjust && width > 0) + while (width--) + PCHAR(padc); + while (n--) + PCHAR(*p++); + if (ladjust && width > 0) + while (width--) + PCHAR(padc); + break; + case 't': + tflag = 1; + goto reswitch; + case 'u': + base = 10; + goto handle_nosign; + case 'X': + upper = 1; + case 'x': + base = 16; + goto handle_nosign; + case 'y': + base = 16; + sign = 1; + goto handle_sign; + case 'z': + zflag = 1; + goto reswitch; +handle_nosign: + sign = 0; + if (jflag) + num = va_arg(ap, uintmax_t); + else if (qflag) + num = va_arg(ap, uint64_t); + else if (tflag) + num = va_arg(ap, ptrdiff_t); + else if (lflag) + num = va_arg(ap, unsigned long); + else if (zflag) + num = va_arg(ap, size_t); + else if (hflag) + num = (unsigned short)va_arg(ap, int); + else if (cflag) + num = (unsigned char)va_arg(ap, int); + else + num = va_arg(ap, unsigned int); + goto number; +handle_sign: + if (jflag) + num = va_arg(ap, intmax_t); + else if (qflag) + num = va_arg(ap, int64_t); + else if (tflag) + num = va_arg(ap, ptrdiff_t); + else if (lflag) + num = va_arg(ap, long); + else if (zflag) + num = va_arg(ap, ssize_t); + else if (hflag) + num = (short)va_arg(ap, int); + else if (cflag) + num = (char)va_arg(ap, int); + else + num = va_arg(ap, int); +number: + if (sign && (intmax_t)num < 0) { + neg = 1; + num = -(intmax_t)num; + } + p = ksprintn(nbuf, num, base, &n, upper); + tmp = 0; + if (sharpflag && num != 0) { + if (base == 8) + tmp++; + else if (base == 16) + tmp += 2; + } + if (neg) + tmp++; + + if (!ladjust && padc == '0') + dwidth = width - tmp; + width -= tmp + imax(dwidth, n); + dwidth -= n; + if (!ladjust) + while (width-- > 0) + PCHAR(' '); + if (neg) + PCHAR('-'); + if (sharpflag && num != 0) { + if (base == 8) { + PCHAR('0'); + } else if (base == 16) { + PCHAR('0'); + PCHAR('x'); + } + } + while (dwidth-- > 0) + PCHAR('0'); + + while (*p) + PCHAR(*p--); + + if (ladjust) + while (width-- > 0) + PCHAR(' '); + + break; + default: + while (percent < fmt) + PCHAR(*percent++); + /* + * Since we ignore an formatting argument it is no + * longer safe to obey the remaining formatting + * arguments as the arguments will no longer match + * the format specs. + */ + stop = 1; + break; + } + } +#undef PCHAR +} #else /* defined(USE_ELF) */ #error not supported #endif diff --git a/addr2line.h b/addr2line.h index ff8e476b92..f09b665800 100644 --- a/addr2line.h +++ b/addr2line.h @@ -12,10 +12,8 @@ #if (defined(USE_ELF) || defined(HAVE_MACH_O_LOADER_H)) -#include <stdio.h> - void -rb_dump_backtrace_with_lines(int num_traces, void **traces, FILE *errout); +rb_dump_backtrace_with_lines(int num_traces, void **traces); #endif /* USE_ELF */ @@ -28,7 +28,7 @@ #include "ruby/encoding.h" #include "ruby/st.h" #include "ruby/util.h" -#include "vm_core.h" +#include "transient_heap.h" #include "builtin.h" #if !ARRAY_DEBUG @@ -38,7 +38,6 @@ #include "ruby_assert.h" VALUE rb_cArray; -VALUE rb_cArray_empty_frozen; /* Flags of RArray * @@ -48,8 +47,13 @@ VALUE rb_cArray_empty_frozen; * 2: RARRAY_SHARED_FLAG (equal to ELTS_SHARED) * The array is shared. The buffer this array points to is owned by * another array (the shared root). + * if USE_RVARGC * 3-9: RARRAY_EMBED_LEN * The length of the array when RARRAY_EMBED_FLAG is set. + * else + * 3-4: RARRAY_EMBED_LEN + * The length of the array when RARRAY_EMBED_FLAG is set. + * endif * 12: RARRAY_SHARED_ROOT_FLAG * The array is a shared root that does reference counting. The buffer * this array points to is owned by this array but may be pointed to @@ -59,6 +63,8 @@ VALUE rb_cArray_empty_frozen; * they cannot be modified. Not updating the reference count * improves copy-on-write performance. Their reference count is * assumed to be infinity. + * 13: RARRAY_TRANSIENT_FLAG + * The buffer of the array is allocated on the transient heap. * 14: RARRAY_PTR_IN_USE_FLAG * The buffer of the array is in use. This is only used during * debugging. @@ -78,47 +84,48 @@ should_be_T_ARRAY(VALUE ary) return RB_TYPE_P(ary, T_ARRAY); } -#define ARY_HEAP_PTR(a) (RUBY_ASSERT(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.ptr) -#define ARY_HEAP_LEN(a) (RUBY_ASSERT(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.len) -#define ARY_HEAP_CAPA(a) (RUBY_ASSERT(!ARY_EMBED_P(a)), RUBY_ASSERT(!ARY_SHARED_ROOT_P(a)), \ +#define ARY_HEAP_PTR(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.ptr) +#define ARY_HEAP_LEN(a) (assert(!ARY_EMBED_P(a)), RARRAY(a)->as.heap.len) +#define ARY_HEAP_CAPA(a) (assert(!ARY_EMBED_P(a)), assert(!ARY_SHARED_ROOT_P(a)), \ RARRAY(a)->as.heap.aux.capa) -#define ARY_EMBED_PTR(a) (RUBY_ASSERT(ARY_EMBED_P(a)), RARRAY(a)->as.ary) +#define ARY_EMBED_PTR(a) (assert(ARY_EMBED_P(a)), RARRAY(a)->as.ary) #define ARY_EMBED_LEN(a) \ - (RUBY_ASSERT(ARY_EMBED_P(a)), \ + (assert(ARY_EMBED_P(a)), \ (long)((RBASIC(a)->flags >> RARRAY_EMBED_LEN_SHIFT) & \ (RARRAY_EMBED_LEN_MASK >> RARRAY_EMBED_LEN_SHIFT))) -#define ARY_HEAP_SIZE(a) (RUBY_ASSERT(!ARY_EMBED_P(a)), RUBY_ASSERT(ARY_OWNS_HEAP_P(a)), ARY_CAPA(a) * sizeof(VALUE)) +#define ARY_HEAP_SIZE(a) (assert(!ARY_EMBED_P(a)), assert(ARY_OWNS_HEAP_P(a)), ARY_CAPA(a) * sizeof(VALUE)) -#define ARY_OWNS_HEAP_P(a) (RUBY_ASSERT(should_be_T_ARRAY((VALUE)(a))), \ +#define ARY_OWNS_HEAP_P(a) (assert(should_be_T_ARRAY((VALUE)(a))), \ !FL_TEST_RAW((a), RARRAY_SHARED_FLAG|RARRAY_EMBED_FLAG)) #define FL_SET_EMBED(a) do { \ - RUBY_ASSERT(!ARY_SHARED_P(a)); \ + assert(!ARY_SHARED_P(a)); \ FL_SET((a), RARRAY_EMBED_FLAG); \ + RARY_TRANSIENT_UNSET(a); \ ary_verify(a); \ } while (0) #define FL_UNSET_EMBED(ary) FL_UNSET((ary), RARRAY_EMBED_FLAG|RARRAY_EMBED_LEN_MASK) #define FL_SET_SHARED(ary) do { \ - RUBY_ASSERT(!ARY_EMBED_P(ary)); \ + assert(!ARY_EMBED_P(ary)); \ FL_SET((ary), RARRAY_SHARED_FLAG); \ } while (0) #define FL_UNSET_SHARED(ary) FL_UNSET((ary), RARRAY_SHARED_FLAG) #define ARY_SET_PTR(ary, p) do { \ - RUBY_ASSERT(!ARY_EMBED_P(ary)); \ - RUBY_ASSERT(!OBJ_FROZEN(ary)); \ + assert(!ARY_EMBED_P(ary)); \ + assert(!OBJ_FROZEN(ary)); \ RARRAY(ary)->as.heap.ptr = (p); \ } while (0) #define ARY_SET_EMBED_LEN(ary, n) do { \ long tmp_n = (n); \ - RUBY_ASSERT(ARY_EMBED_P(ary)); \ + assert(ARY_EMBED_P(ary)); \ RBASIC(ary)->flags &= ~RARRAY_EMBED_LEN_MASK; \ RBASIC(ary)->flags |= (tmp_n) << RARRAY_EMBED_LEN_SHIFT; \ } while (0) #define ARY_SET_HEAP_LEN(ary, n) do { \ - RUBY_ASSERT(!ARY_EMBED_P(ary)); \ + assert(!ARY_EMBED_P(ary)); \ RARRAY(ary)->as.heap.len = (n); \ } while (0) #define ARY_SET_LEN(ary, n) do { \ @@ -128,15 +135,15 @@ should_be_T_ARRAY(VALUE ary) else { \ ARY_SET_HEAP_LEN((ary), (n)); \ } \ - RUBY_ASSERT(RARRAY_LEN(ary) == (n)); \ + assert(RARRAY_LEN(ary) == (n)); \ } while (0) #define ARY_INCREASE_PTR(ary, n) do { \ - RUBY_ASSERT(!ARY_EMBED_P(ary)); \ - RUBY_ASSERT(!OBJ_FROZEN(ary)); \ + assert(!ARY_EMBED_P(ary)); \ + assert(!OBJ_FROZEN(ary)); \ RARRAY(ary)->as.heap.ptr += (n); \ } while (0) #define ARY_INCREASE_LEN(ary, n) do { \ - RUBY_ASSERT(!OBJ_FROZEN(ary)); \ + assert(!OBJ_FROZEN(ary)); \ if (ARY_EMBED_P(ary)) { \ ARY_SET_EMBED_LEN((ary), RARRAY_LEN(ary)+(n)); \ } \ @@ -148,30 +155,41 @@ should_be_T_ARRAY(VALUE ary) #define ARY_CAPA(ary) (ARY_EMBED_P(ary) ? ary_embed_capa(ary) : \ ARY_SHARED_ROOT_P(ary) ? RARRAY_LEN(ary) : ARY_HEAP_CAPA(ary)) #define ARY_SET_CAPA(ary, n) do { \ - RUBY_ASSERT(!ARY_EMBED_P(ary)); \ - RUBY_ASSERT(!ARY_SHARED_P(ary)); \ - RUBY_ASSERT(!OBJ_FROZEN(ary)); \ + assert(!ARY_EMBED_P(ary)); \ + assert(!ARY_SHARED_P(ary)); \ + assert(!OBJ_FROZEN(ary)); \ RARRAY(ary)->as.heap.aux.capa = (n); \ } while (0) +#define ARY_SET_SHARED(ary, value) do { \ + const VALUE _ary_ = (ary); \ + const VALUE _value_ = (value); \ + assert(!ARY_EMBED_P(_ary_)); \ + assert(ARY_SHARED_P(_ary_)); \ + assert(!OBJ_FROZEN(_ary_)); \ + assert(ARY_SHARED_ROOT_P(_value_) || OBJ_FROZEN(_value_)); \ + RB_OBJ_WRITE(_ary_, &RARRAY(_ary_)->as.heap.aux.shared_root, _value_); \ +} while (0) + #define ARY_SHARED_ROOT_OCCUPIED(ary) (!OBJ_FROZEN(ary) && ARY_SHARED_ROOT_REFCNT(ary) == 1) #define ARY_SET_SHARED_ROOT_REFCNT(ary, value) do { \ - RUBY_ASSERT(ARY_SHARED_ROOT_P(ary)); \ - RUBY_ASSERT(!OBJ_FROZEN(ary)); \ - RUBY_ASSERT((value) >= 0); \ + assert(ARY_SHARED_ROOT_P(ary)); \ + assert(!OBJ_FROZEN(ary)); \ + assert((value) >= 0); \ RARRAY(ary)->as.heap.aux.capa = (value); \ } while (0) #define FL_SET_SHARED_ROOT(ary) do { \ - RUBY_ASSERT(!OBJ_FROZEN(ary)); \ - RUBY_ASSERT(!ARY_EMBED_P(ary)); \ + assert(!OBJ_FROZEN(ary)); \ + assert(!ARY_EMBED_P(ary)); \ + assert(!RARRAY_TRANSIENT_P(ary)); \ FL_SET((ary), RARRAY_SHARED_ROOT_FLAG); \ } while (0) static inline void ARY_SET(VALUE a, long i, VALUE v) { - RUBY_ASSERT(!ARY_SHARED_P(a)); - RUBY_ASSERT(!OBJ_FROZEN(a)); + assert(!ARY_SHARED_P(a)); + assert(!OBJ_FROZEN(a)); RARRAY_ASET(a, i, v); } @@ -180,9 +198,13 @@ ARY_SET(VALUE a, long i, VALUE v) static long ary_embed_capa(VALUE ary) { +#if USE_RVARGC size_t size = rb_gc_obj_slot_size(ary) - offsetof(struct RArray, as.ary); - RUBY_ASSERT(size % sizeof(VALUE) == 0); + assert(size % sizeof(VALUE) == 0); return size / sizeof(VALUE); +#else + return RARRAY_EMBED_LEN_MAX; +#endif } static size_t @@ -194,7 +216,11 @@ ary_embed_size(long capa) static bool ary_embeddable_p(long capa) { +#if USE_RVARGC return rb_gc_size_allocatable_p(ary_embed_size(capa)); +#else + return capa <= RARRAY_EMBED_LEN_MAX; +#endif } bool @@ -235,23 +261,25 @@ rb_ary_size_as_embedded(VALUE ary) static VALUE ary_verify_(VALUE ary, const char *file, int line) { - RUBY_ASSERT(RB_TYPE_P(ary, T_ARRAY)); + assert(RB_TYPE_P(ary, T_ARRAY)); if (ARY_SHARED_P(ary)) { VALUE root = ARY_SHARED_ROOT(ary); const VALUE *ptr = ARY_HEAP_PTR(ary); - const VALUE *root_ptr = RARRAY_CONST_PTR(root); + const VALUE *root_ptr = RARRAY_CONST_PTR_TRANSIENT(root); long len = ARY_HEAP_LEN(ary), root_len = RARRAY_LEN(root); - RUBY_ASSERT(ARY_SHARED_ROOT_P(root) || OBJ_FROZEN(root)); - RUBY_ASSERT(root_ptr <= ptr && ptr + len <= root_ptr + root_len); + assert(ARY_SHARED_ROOT_P(root) || OBJ_FROZEN(root)); + assert(root_ptr <= ptr && ptr + len <= root_ptr + root_len); ary_verify(root); } else if (ARY_EMBED_P(ary)) { - RUBY_ASSERT(!ARY_SHARED_P(ary)); - RUBY_ASSERT(RARRAY_LEN(ary) <= ary_embed_capa(ary)); + assert(!RARRAY_TRANSIENT_P(ary)); + assert(!ARY_SHARED_P(ary)); + assert(RARRAY_LEN(ary) <= ary_embed_capa(ary)); } else { - const VALUE *ptr = RARRAY_CONST_PTR(ary); +#if 1 + const VALUE *ptr = RARRAY_CONST_PTR_TRANSIENT(ary); long i, len = RARRAY_LEN(ary); volatile VALUE v; if (len > 1) len = 1; /* check only HEAD */ @@ -259,7 +287,16 @@ ary_verify_(VALUE ary, const char *file, int line) v = ptr[i]; /* access check */ } v = v; +#endif + } + +#if USE_TRANSIENT_HEAP + if (RARRAY_TRANSIENT_P(ary)) { + assert(rb_transient_heap_managed_ptr_p(RARRAY_CONST_PTR_TRANSIENT(ary))); } +#endif + + rb_transient_heap_verify(); return ary; } @@ -279,7 +316,7 @@ rb_ary_ptr_use_start(VALUE ary) #if ARRAY_DEBUG FL_SET_RAW(ary, RARRAY_PTR_IN_USE_FLAG); #endif - return (VALUE *)RARRAY_CONST_PTR(ary); + return (VALUE *)RARRAY_CONST_PTR_TRANSIENT(ary); } void @@ -301,7 +338,7 @@ rb_mem_clear(VALUE *mem, long size) static void ary_mem_clear(VALUE ary, long beg, long size) { - RARRAY_PTR_USE(ary, ptr, { + RARRAY_PTR_USE_TRANSIENT(ary, ptr, { rb_mem_clear(ptr + beg, size); }); } @@ -317,7 +354,7 @@ memfill(register VALUE *mem, register long size, register VALUE val) static void ary_memfill(VALUE ary, long beg, long size, VALUE val) { - RARRAY_PTR_USE(ary, ptr, { + RARRAY_PTR_USE_TRANSIENT(ary, ptr, { memfill(ptr + beg, size, val); RB_OBJ_WRITTEN(ary, Qundef, val); }); @@ -326,17 +363,17 @@ ary_memfill(VALUE ary, long beg, long size, VALUE val) static void ary_memcpy0(VALUE ary, long beg, long argc, const VALUE *argv, VALUE buff_owner_ary) { - RUBY_ASSERT(!ARY_SHARED_P(buff_owner_ary)); + assert(!ARY_SHARED_P(buff_owner_ary)); if (argc > (int)(128/sizeof(VALUE)) /* is magic number (cache line size) */) { rb_gc_writebarrier_remember(buff_owner_ary); - RARRAY_PTR_USE(ary, ptr, { + RARRAY_PTR_USE_TRANSIENT(ary, ptr, { MEMCPY(ptr+beg, argv, VALUE, argc); }); } else { int i; - RARRAY_PTR_USE(ary, ptr, { + RARRAY_PTR_USE_TRANSIENT(ary, ptr, { for (i=0; i<argc; i++) { RB_OBJ_WRITE(buff_owner_ary, &ptr[i+beg], argv[i]); } @@ -351,62 +388,158 @@ ary_memcpy(VALUE ary, long beg, long argc, const VALUE *argv) } static VALUE * -ary_heap_alloc_buffer(size_t capa) +ary_heap_alloc(VALUE ary, size_t capa) { - return ALLOC_N(VALUE, capa); + VALUE *ptr = rb_transient_heap_alloc(ary, sizeof(VALUE) * capa); + + if (ptr != NULL) { + RARY_TRANSIENT_SET(ary); + } + else { + RARY_TRANSIENT_UNSET(ary); + ptr = ALLOC_N(VALUE, capa); + } + + return ptr; } static void ary_heap_free_ptr(VALUE ary, const VALUE *ptr, long size) { - ruby_sized_xfree((void *)ptr, size); + if (RARRAY_TRANSIENT_P(ary)) { + /* ignore it */ + } + else { + ruby_sized_xfree((void *)ptr, size); + } } static void ary_heap_free(VALUE ary) { - ary_heap_free_ptr(ary, ARY_HEAP_PTR(ary), ARY_HEAP_SIZE(ary)); + if (RARRAY_TRANSIENT_P(ary)) { + RARY_TRANSIENT_UNSET(ary); + } + else { + ary_heap_free_ptr(ary, ARY_HEAP_PTR(ary), ARY_HEAP_SIZE(ary)); + } } static size_t ary_heap_realloc(VALUE ary, size_t new_capa) { - RUBY_ASSERT(!OBJ_FROZEN(ary)); - SIZED_REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, new_capa, ARY_HEAP_CAPA(ary)); + size_t alloc_capa = new_capa; + size_t old_capa = ARY_HEAP_CAPA(ary); + + if (RARRAY_TRANSIENT_P(ary)) { + if (new_capa <= old_capa) { + /* do nothing */ + alloc_capa = old_capa; + } + else { + VALUE *new_ptr = rb_transient_heap_alloc(ary, sizeof(VALUE) * new_capa); + + if (new_ptr == NULL) { + new_ptr = ALLOC_N(VALUE, new_capa); + RARY_TRANSIENT_UNSET(ary); + } + + MEMCPY(new_ptr, ARY_HEAP_PTR(ary), VALUE, old_capa); + ARY_SET_PTR(ary, new_ptr); + } + } + else { + SIZED_REALLOC_N(RARRAY(ary)->as.heap.ptr, VALUE, new_capa, old_capa); + } ary_verify(ary); - return new_capa; + return alloc_capa; +} + +#if USE_TRANSIENT_HEAP +static inline void +rb_ary_transient_heap_evacuate_(VALUE ary, int transient, int promote) +{ + if (transient) { + assert(!ARY_SHARED_ROOT_P(ary)); + + VALUE *new_ptr; + const VALUE *old_ptr = ARY_HEAP_PTR(ary); + long capa = ARY_HEAP_CAPA(ary); + + assert(ARY_OWNS_HEAP_P(ary)); + assert(RARRAY_TRANSIENT_P(ary)); + assert(!ARY_PTR_USING_P(ary)); + + if (promote) { + new_ptr = ALLOC_N(VALUE, capa); + RARY_TRANSIENT_UNSET(ary); + } + else { + new_ptr = ary_heap_alloc(ary, capa); + } + + MEMCPY(new_ptr, old_ptr, VALUE, capa); + /* do not use ARY_SET_PTR() because they assert !frozen */ + RARRAY(ary)->as.heap.ptr = new_ptr; + } + + ary_verify(ary); +} + +void +rb_ary_transient_heap_evacuate(VALUE ary, int promote) +{ + rb_ary_transient_heap_evacuate_(ary, RARRAY_TRANSIENT_P(ary), promote); +} + +void +rb_ary_detransient(VALUE ary) +{ + assert(RARRAY_TRANSIENT_P(ary)); + rb_ary_transient_heap_evacuate_(ary, TRUE, TRUE); } +#else +void +rb_ary_detransient(VALUE ary) +{ + /* do nothing */ +} +#endif void rb_ary_make_embedded(VALUE ary) { - RUBY_ASSERT(rb_ary_embeddable_p(ary)); + assert(rb_ary_embeddable_p(ary)); if (!ARY_EMBED_P(ary)) { const VALUE *buf = ARY_HEAP_PTR(ary); long len = ARY_HEAP_LEN(ary); + bool was_transient = RARRAY_TRANSIENT_P(ary); + // FL_SET_EMBED also unsets the transient flag FL_SET_EMBED(ary); ARY_SET_EMBED_LEN(ary, len); MEMCPY((void *)ARY_EMBED_PTR(ary), (void *)buf, VALUE, len); - ary_heap_free_ptr(ary, buf, len * sizeof(VALUE)); + if (!was_transient) { + ary_heap_free_ptr(ary, buf, len * sizeof(VALUE)); + } } } static void ary_resize_capa(VALUE ary, long capacity) { - RUBY_ASSERT(RARRAY_LEN(ary) <= capacity); - RUBY_ASSERT(!OBJ_FROZEN(ary)); - RUBY_ASSERT(!ARY_SHARED_P(ary)); + assert(RARRAY_LEN(ary) <= capacity); + assert(!OBJ_FROZEN(ary)); + assert(!ARY_SHARED_P(ary)); if (capacity > ary_embed_capa(ary)) { size_t new_capa = capacity; if (ARY_EMBED_P(ary)) { long len = ARY_EMBED_LEN(ary); - VALUE *ptr = ary_heap_alloc_buffer(capacity); + VALUE *ptr = ary_heap_alloc(ary, capacity); MEMCPY(ptr, ARY_EMBED_PTR(ary), VALUE, len); FL_UNSET_EMBED(ary); @@ -441,12 +574,9 @@ ary_shrink_capa(VALUE ary) { long capacity = ARY_HEAP_LEN(ary); long old_capa = ARY_HEAP_CAPA(ary); - RUBY_ASSERT(!ARY_SHARED_P(ary)); - RUBY_ASSERT(old_capa >= capacity); - if (old_capa > capacity) { - size_t new_capa = ary_heap_realloc(ary, capacity); - ARY_SET_CAPA(ary, new_capa); - } + assert(!ARY_SHARED_P(ary)); + assert(old_capa >= capacity); + if (old_capa > capacity) ary_heap_realloc(ary, capacity); ary_verify(ary); } @@ -504,7 +634,7 @@ rb_ary_increment_share(VALUE shared_root) { if (!OBJ_FROZEN(shared_root)) { long num = ARY_SHARED_ROOT_REFCNT(shared_root); - RUBY_ASSERT(num >= 0); + assert(num >= 0); ARY_SET_SHARED_ROOT_REFCNT(shared_root, num + 1); } return shared_root; @@ -513,15 +643,10 @@ rb_ary_increment_share(VALUE shared_root) static void rb_ary_set_shared(VALUE ary, VALUE shared_root) { - RUBY_ASSERT(!ARY_EMBED_P(ary)); - RUBY_ASSERT(!OBJ_FROZEN(ary)); - RUBY_ASSERT(ARY_SHARED_ROOT_P(shared_root) || OBJ_FROZEN(shared_root)); - rb_ary_increment_share(shared_root); FL_SET_SHARED(ary); - RB_OBJ_WRITE(ary, &RARRAY(ary)->as.heap.aux.shared_root, shared_root); - RB_DEBUG_COUNTER_INC(obj_ary_shared_create); + ARY_SET_SHARED(ary, shared_root); } static inline void @@ -549,18 +674,18 @@ rb_ary_cancel_sharing(VALUE ary) ARY_SET_EMBED_LEN(ary, len); } else if (ARY_SHARED_ROOT_OCCUPIED(shared_root) && len > ((shared_len = RARRAY_LEN(shared_root))>>1)) { - long shift = RARRAY_CONST_PTR(ary) - RARRAY_CONST_PTR(shared_root); + long shift = RARRAY_CONST_PTR_TRANSIENT(ary) - RARRAY_CONST_PTR_TRANSIENT(shared_root); FL_UNSET_SHARED(ary); - ARY_SET_PTR(ary, RARRAY_CONST_PTR(shared_root)); + ARY_SET_PTR(ary, RARRAY_CONST_PTR_TRANSIENT(shared_root)); ARY_SET_CAPA(ary, shared_len); - RARRAY_PTR_USE(ary, ptr, { + RARRAY_PTR_USE_TRANSIENT(ary, ptr, { MEMMOVE(ptr, ptr+shift, VALUE, len); }); FL_SET_EMBED(shared_root); rb_ary_decrement_share(shared_root); } else { - VALUE *ptr = ary_heap_alloc_buffer(len); + VALUE *ptr = ary_heap_alloc(ary, len); MEMCPY(ptr, ARY_HEAP_PTR(ary), VALUE, len); rb_ary_unshare(ary); ARY_SET_CAPA(ary, len); @@ -593,7 +718,7 @@ ary_ensure_room_for_push(VALUE ary, long add_len) if (new_len > ary_embed_capa(ary)) { VALUE shared_root = ARY_SHARED_ROOT(ary); if (ARY_SHARED_ROOT_OCCUPIED(shared_root)) { - if (ARY_HEAP_PTR(ary) - RARRAY_CONST_PTR(shared_root) + new_len <= RARRAY_LEN(shared_root)) { + if (ARY_HEAP_PTR(ary) - RARRAY_CONST_PTR_TRANSIENT(shared_root) + new_len <= RARRAY_LEN(shared_root)) { rb_ary_modify_check(ary); ary_verify(ary); @@ -629,32 +754,21 @@ ary_ensure_room_for_push(VALUE ary, long add_len) /* * call-seq: - * freeze -> self + * array.freeze -> self * - * Freezes +self+ (if not already frozen); returns +self+: + * Freezes +self+; returns +self+: * * a = [] * a.frozen? # => false * a.freeze * a.frozen? # => true * - * No further changes may be made to +self+; - * raises FrozenError if a change is attempted. - * - * Related: Kernel#frozen?. + * An attempt to modify a frozen \Array raises FrozenError. */ VALUE rb_ary_freeze(VALUE ary) { - RUBY_ASSERT(RB_TYPE_P(ary, T_ARRAY)); - - if (OBJ_FROZEN(ary)) return ary; - - if (!ARY_EMBED_P(ary) && !ARY_SHARED_P(ary) && !ARY_SHARED_ROOT_P(ary)) { - ary_shrink_capa(ary); - } - return rb_obj_freeze(ary); } @@ -681,10 +795,13 @@ static VALUE ary_alloc_embed(VALUE klass, long capa) { size_t size = ary_embed_size(capa); - RUBY_ASSERT(rb_gc_size_allocatable_p(size)); - NEWOBJ_OF(ary, struct RArray, klass, + assert(rb_gc_size_allocatable_p(size)); +#if !USE_RVARGC + assert(size <= sizeof(struct RArray)); +#endif + RVARGC_NEWOBJ_OF(ary, struct RArray, klass, T_ARRAY | RARRAY_EMBED_FLAG | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0), - size, 0); + size); /* Created array is: * FL_SET_EMBED((VALUE)ary); * ARY_SET_EMBED_LEN((VALUE)ary, 0); @@ -695,9 +812,9 @@ ary_alloc_embed(VALUE klass, long capa) static VALUE ary_alloc_heap(VALUE klass) { - NEWOBJ_OF(ary, struct RArray, klass, + RVARGC_NEWOBJ_OF(ary, struct RArray, klass, T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0), - sizeof(struct RArray), 0); + sizeof(struct RArray)); return (VALUE)ary; } @@ -711,7 +828,7 @@ empty_ary_alloc(VALUE klass) static VALUE ary_new(VALUE klass, long capa) { - VALUE ary; + VALUE ary,*ptr; if (capa < 0) { rb_raise(rb_eArgError, "negative array size (or size too big)"); @@ -728,9 +845,10 @@ ary_new(VALUE klass, long capa) else { ary = ary_alloc_heap(klass); ARY_SET_CAPA(ary, capa); - RUBY_ASSERT(!ARY_EMBED_P(ary)); + assert(!ARY_EMBED_P(ary)); - ARY_SET_PTR(ary, ary_heap_alloc_buffer(capa)); + ptr = ary_heap_alloc(ary, capa); + ARY_SET_PTR(ary, ptr); ARY_SET_HEAP_LEN(ary, 0); } @@ -768,7 +886,7 @@ VALUE return ary; } -VALUE +MJIT_FUNC_EXPORTED VALUE rb_ary_tmp_new_from_values(VALUE klass, long n, const VALUE *elts) { VALUE ary; @@ -792,10 +910,13 @@ static VALUE ec_ary_alloc_embed(rb_execution_context_t *ec, VALUE klass, long capa) { size_t size = ary_embed_size(capa); - RUBY_ASSERT(rb_gc_size_allocatable_p(size)); - NEWOBJ_OF(ary, struct RArray, klass, - T_ARRAY | RARRAY_EMBED_FLAG | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0), - size, ec); + assert(rb_gc_size_allocatable_p(size)); +#if !USE_RVARGC + assert(size <= sizeof(struct RArray)); +#endif + RB_RVARGC_EC_NEWOBJ_OF(ec, ary, struct RArray, klass, + T_ARRAY | RARRAY_EMBED_FLAG | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0), + size); /* Created array is: * FL_SET_EMBED((VALUE)ary); * ARY_SET_EMBED_LEN((VALUE)ary, 0); @@ -806,16 +927,16 @@ ec_ary_alloc_embed(rb_execution_context_t *ec, VALUE klass, long capa) static VALUE ec_ary_alloc_heap(rb_execution_context_t *ec, VALUE klass) { - NEWOBJ_OF(ary, struct RArray, klass, - T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0), - sizeof(struct RArray), ec); + RB_RVARGC_EC_NEWOBJ_OF(ec, ary, struct RArray, klass, + T_ARRAY | (RGENGC_WB_PROTECTED_ARRAY ? FL_WB_PROTECTED : 0), + sizeof(struct RArray)); return (VALUE)ary; } static VALUE ec_ary_new(rb_execution_context_t *ec, VALUE klass, long capa) { - VALUE ary; + VALUE ary,*ptr; if (capa < 0) { rb_raise(rb_eArgError, "negative array size (or size too big)"); @@ -832,9 +953,10 @@ ec_ary_new(rb_execution_context_t *ec, VALUE klass, long capa) else { ary = ec_ary_alloc_heap(ec, klass); ARY_SET_CAPA(ary, capa); - RUBY_ASSERT(!ARY_EMBED_P(ary)); + assert(!ARY_EMBED_P(ary)); - ARY_SET_PTR(ary, ary_heap_alloc_buffer(capa)); + ptr = ary_heap_alloc(ary, capa); + ARY_SET_PTR(ary, ptr); ARY_SET_HEAP_LEN(ary, 0); } @@ -859,6 +981,7 @@ VALUE rb_ary_hidden_new(long capa) { VALUE ary = ary_new(0, capa); + rb_ary_transient_heap_evacuate(ary, TRUE); return ary; } @@ -881,8 +1004,13 @@ rb_ary_free(VALUE ary) RB_DEBUG_COUNTER_INC(obj_ary_extracapa); } - RB_DEBUG_COUNTER_INC(obj_ary_ptr); - ary_heap_free(ary); + if (RARRAY_TRANSIENT_P(ary)) { + RB_DEBUG_COUNTER_INC(obj_ary_transient); + } + else { + RB_DEBUG_COUNTER_INC(obj_ary_ptr); + ary_heap_free(ary); + } } else { RB_DEBUG_COUNTER_INC(obj_ary_embed); @@ -896,32 +1024,7 @@ rb_ary_free(VALUE ary) } } -static VALUE fake_ary_flags; - -static VALUE -init_fake_ary_flags(void) -{ - struct RArray fake_ary = {0}; - fake_ary.basic.flags = T_ARRAY; - VALUE ary = (VALUE)&fake_ary; - rb_ary_freeze(ary); - return fake_ary.basic.flags; -} - -VALUE -rb_setup_fake_ary(struct RArray *fake_ary, const VALUE *list, long len) -{ - fake_ary->basic.flags = fake_ary_flags; - RBASIC_CLEAR_CLASS((VALUE)fake_ary); - - // bypass frozen checks - fake_ary->as.heap.ptr = list; - fake_ary->as.heap.len = len; - fake_ary->as.heap.aux.capa = len; - return (VALUE)fake_ary; -} - -size_t +RUBY_FUNC_EXPORTED size_t rb_ary_memsize(VALUE ary) { if (ARY_OWNS_HEAP_P(ary)) { @@ -935,6 +1038,7 @@ rb_ary_memsize(VALUE ary) static VALUE ary_make_shared(VALUE ary) { + assert(USE_RVARGC || !ARY_EMBED_P(ary)); ary_verify(ary); if (ARY_SHARED_P(ary)) { @@ -944,9 +1048,15 @@ ary_make_shared(VALUE ary) return ary; } else if (OBJ_FROZEN(ary)) { + if (!ARY_EMBED_P(ary)) { + rb_ary_transient_heap_evacuate(ary, TRUE); + ary_shrink_capa(ary); + } return ary; } else { + rb_ary_transient_heap_evacuate(ary, TRUE); + long capa = ARY_CAPA(ary); long len = RARRAY_LEN(ary); @@ -956,21 +1066,26 @@ ary_make_shared(VALUE ary) FL_SET_SHARED_ROOT(shared); if (ARY_EMBED_P(ary)) { - VALUE *ptr = ary_heap_alloc_buffer(capa); + /* Cannot use ary_heap_alloc because we don't want to allocate + * on the transient heap. */ + VALUE *ptr = ALLOC_N(VALUE, capa); ARY_SET_PTR(shared, ptr); - ary_memcpy(shared, 0, len, RARRAY_CONST_PTR(ary)); + ary_memcpy(shared, 0, len, RARRAY_PTR(ary)); FL_UNSET_EMBED(ary); ARY_SET_HEAP_LEN(ary, len); ARY_SET_PTR(ary, ptr); } else { - ARY_SET_PTR(shared, RARRAY_CONST_PTR(ary)); + ARY_SET_PTR(shared, RARRAY_PTR(ary)); } ARY_SET_LEN(shared, capa); ary_mem_clear(shared, len, capa - len); - rb_ary_set_shared(ary, shared); + ARY_SET_SHARED_ROOT_REFCNT(shared, 1); + FL_SET_SHARED(ary); + RB_DEBUG_COUNTER_INC(obj_ary_shared_create); + ARY_SET_SHARED(ary, shared); ary_verify(shared); ary_verify(ary); @@ -986,9 +1101,9 @@ ary_make_substitution(VALUE ary) if (ary_embeddable_p(len)) { VALUE subst = rb_ary_new_capa(len); - RUBY_ASSERT(ARY_EMBED_P(subst)); + assert(ARY_EMBED_P(subst)); - ary_memcpy(subst, 0, len, RARRAY_CONST_PTR(ary)); + ary_memcpy(subst, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary)); ARY_SET_EMBED_LEN(subst, len); return subst; } @@ -1016,7 +1131,7 @@ rb_check_array_type(VALUE ary) return rb_check_convert_type_with_id(ary, T_ARRAY, "Array", idTo_ary); } -VALUE +MJIT_FUNC_EXPORTED VALUE rb_check_to_array(VALUE ary) { return rb_check_convert_type_with_id(ary, T_ARRAY, "Array", idTo_a); @@ -1032,18 +1147,14 @@ rb_to_array(VALUE ary) * call-seq: * Array.try_convert(object) -> object, new_array, or nil * - * Attempts to return an array, based on the given +object+. - * - * If +object+ is an array, returns +object+. + * If +object+ is an \Array object, returns +object+. * - * Otherwise if +object+ responds to <tt>:to_ary</tt>. - * calls <tt>object.to_ary</tt>: - * if the return value is an array or +nil+, returns that value; - * if not, raises TypeError. + * Otherwise if +object+ responds to <tt>:to_ary</tt>, + * calls <tt>object.to_ary</tt> and returns the result. * - * Otherwise returns +nil+. + * Returns +nil+ if +object+ does not respond to <tt>:to_ary</tt> * - * Related: see {Methods for Creating an Array}[rdoc-ref:Array@Methods+for+Creating+an+Array]. + * Raises an exception unless <tt>object.to_ary</tt> returns an \Array object. */ static VALUE @@ -1080,51 +1191,48 @@ rb_ary_s_new(int argc, VALUE *argv, VALUE klass) * call-seq: * Array.new -> new_empty_array * Array.new(array) -> new_array - * Array.new(size, default_value = nil) -> new_array - * Array.new(size = 0) {|index| ... } -> new_array + * Array.new(size) -> new_array + * Array.new(size, default_value) -> new_array + * Array.new(size) {|index| ... } -> new_array * - * Returns a new array. + * Returns a new \Array. * - * With no block and no argument given, returns a new empty array: + * With no block and no arguments, returns a new empty \Array object. * - * Array.new # => [] + * With no block and a single \Array argument +array+, + * returns a new \Array formed from +array+: * - * With no block and array argument given, returns a new array with the same elements: - * - * Array.new([:foo, 'bar', 2]) # => [:foo, "bar", 2] - * - * With no block and integer argument given, returns a new array containing - * that many instances of the given +default_value+: - * - * Array.new(0) # => [] - * Array.new(3) # => [nil, nil, nil] - * Array.new(2, 3) # => [3, 3] + * a = Array.new([:foo, 'bar', 2]) + * a.class # => Array + * a # => [:foo, "bar", 2] * - * With a block given, returns an array of the given +size+; - * calls the block with each +index+ in the range <tt>(0...size)</tt>; - * the element at that +index+ in the returned array is the blocks return value: + * With no block and a single \Integer argument +size+, + * returns a new \Array of the given size + * whose elements are all +nil+: * - * Array.new(3) {|index| "Element #{index}" } # => ["Element 0", "Element 1", "Element 2"] + * a = Array.new(3) + * a # => [nil, nil, nil] * - * A common pitfall for new Rubyists is providing an expression as +default_value+: + * With no block and arguments +size+ and +default_value+, + * returns an \Array of the given size; + * each element is that same +default_value+: * - * array = Array.new(2, {}) - * array # => [{}, {}] - * array[0][:a] = 1 - * array # => [{a: 1}, {a: 1}], as array[0] and array[1] are same object + * a = Array.new(3, 'x') + * a # => ['x', 'x', 'x'] * - * If you want the elements of the array to be distinct, you should pass a block: + * With a block and argument +size+, + * returns an \Array of the given size; + * the block is called with each successive integer +index+; + * the element for that +index+ is the return value from the block: * - * array = Array.new(2) { {} } - * array # => [{}, {}] - * array[0][:a] = 1 - * array # => [{a: 1}, {}], as array[0] and array[1] are different objects + * a = Array.new(3) {|index| "Element #{index}" } + * a # => ["Element 0", "Element 1", "Element 2"] * - * Raises TypeError if the first argument is not either an array - * or an {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects]). - * Raises ArgumentError if the first argument is a negative integer. + * Raises ArgumentError if +size+ is negative. * - * Related: see {Methods for Creating an Array}[rdoc-ref:Array@Methods+for+Creating+an+Array]. + * With a block and no argument, + * or a single argument +0+, + * ignores the block and returns a new empty \Array. */ static VALUE @@ -1136,8 +1244,8 @@ rb_ary_initialize(int argc, VALUE *argv, VALUE ary) rb_ary_modify(ary); if (argc == 0) { rb_ary_reset(ary); - RUBY_ASSERT(ARY_EMBED_P(ary)); - RUBY_ASSERT(ARY_EMBED_LEN(ary) == 0); + assert(ARY_EMBED_P(ary)); + assert(ARY_EMBED_LEN(ary) == 0); if (rb_block_given_p()) { rb_warning("given block not used"); } @@ -1182,13 +1290,11 @@ rb_ary_initialize(int argc, VALUE *argv, VALUE ary) } /* - * Returns a new array, populated with the given objects: + * Returns a new array populated with the given objects. * - * Array[1, 'a', /^A/] # => [1, "a", /^A/] - * Array[] # => [] - * Array.[](1, 'a', /^A/) # => [1, "a", /^A/] - * - * Related: see {Methods for Creating an Array}[rdoc-ref:Array@Methods+for+Creating+an+Array]. + * Array.[]( 1, 'a', /^A/) # => [1, "a", /^A/] + * Array[ 1, 'a', /^A/ ] # => [1, "a", /^A/] + * [ 1, 'a', /^A/ ] # => [1, "a", /^A/] */ static VALUE @@ -1236,26 +1342,25 @@ rb_ary_store(VALUE ary, long idx, VALUE val) static VALUE ary_make_partial(VALUE ary, VALUE klass, long offset, long len) { - RUBY_ASSERT(offset >= 0); - RUBY_ASSERT(len >= 0); - RUBY_ASSERT(offset+len <= RARRAY_LEN(ary)); + assert(offset >= 0); + assert(len >= 0); + assert(offset+len <= RARRAY_LEN(ary)); + + const size_t rarray_embed_capa_max = (sizeof(struct RArray) - offsetof(struct RArray, as.ary)) / sizeof(VALUE); - VALUE result = ary_alloc_heap(klass); - size_t embed_capa = ary_embed_capa(result); - if ((size_t)len <= embed_capa) { - FL_SET_EMBED(result); - ary_memcpy(result, 0, len, RARRAY_CONST_PTR(ary) + offset); + if ((size_t)len <= rarray_embed_capa_max && ary_embeddable_p(len)) { + VALUE result = ary_alloc_embed(klass, len); + ary_memcpy(result, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary) + offset); ARY_SET_EMBED_LEN(result, len); + return result; } else { VALUE shared = ary_make_shared(ary); - /* The ary_make_shared call may allocate, which can trigger a GC - * compaction. This can cause the array to be embedded because it has - * a length of 0. */ - FL_UNSET_EMBED(result); + VALUE result = ary_alloc_heap(klass); + assert(!ARY_EMBED_P(result)); - ARY_SET_PTR(result, RARRAY_CONST_PTR(ary)); + ARY_SET_PTR(result, RARRAY_CONST_PTR_TRANSIENT(ary)); ARY_SET_LEN(result, RARRAY_LEN(ary)); rb_ary_set_shared(result, shared); @@ -1263,27 +1368,25 @@ ary_make_partial(VALUE ary, VALUE klass, long offset, long len) ARY_SET_LEN(result, len); ary_verify(shared); + ary_verify(result); + return result; } - - ary_verify(result); - return result; } static VALUE ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step) { - RUBY_ASSERT(offset >= 0); - RUBY_ASSERT(len >= 0); - RUBY_ASSERT(offset+len <= RARRAY_LEN(ary)); - RUBY_ASSERT(step != 0); + assert(offset >= 0); + assert(len >= 0); + assert(offset+len <= RARRAY_LEN(ary)); + assert(step != 0); + const VALUE *values = RARRAY_CONST_PTR_TRANSIENT(ary); const long orig_len = len; if (step > 0 && step >= len) { VALUE result = ary_new(klass, 1); VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result); - const VALUE *values = RARRAY_CONST_PTR(ary); - RB_OBJ_WRITE(result, ptr, values[offset]); ARY_SET_EMBED_LEN(result, 1); return result; @@ -1301,8 +1404,6 @@ ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step) VALUE result = ary_new(klass, len); if (ARY_EMBED_P(result)) { VALUE *ptr = (VALUE *)ARY_EMBED_PTR(result); - const VALUE *values = RARRAY_CONST_PTR(ary); - for (i = 0; i < len; ++i) { RB_OBJ_WRITE(result, ptr+i, values[j]); j += step; @@ -1310,9 +1411,7 @@ ary_make_partial_step(VALUE ary, VALUE klass, long offset, long len, long step) ARY_SET_EMBED_LEN(result, len); } else { - const VALUE *values = RARRAY_CONST_PTR(ary); - - RARRAY_PTR_USE(result, ptr, { + RARRAY_PTR_USE_TRANSIENT(result, ptr, { for (i = 0; i < len; ++i) { RB_OBJ_WRITE(result, ptr+i, values[j]); j += step; @@ -1337,11 +1436,20 @@ enum ary_take_pos_flags }; static VALUE -ary_take_first_or_last_n(VALUE ary, long n, enum ary_take_pos_flags last) +ary_take_first_or_last(int argc, const VALUE *argv, VALUE ary, enum ary_take_pos_flags last) { - long len = RARRAY_LEN(ary); + long n; + long len; long offset = 0; + argc = rb_check_arity(argc, 0, 1); + /* the case optional argument is omitted should be handled in + * callers of this function. if another arity case is added, + * this arity check needs to rewrite. */ + RUBY_ASSERT_ALWAYS(argc == 1); + + n = NUM2LONG(argv[0]); + len = RARRAY_LEN(ary); if (n > len) { n = len; } @@ -1354,30 +1462,21 @@ ary_take_first_or_last_n(VALUE ary, long n, enum ary_take_pos_flags last) return ary_make_partial(ary, rb_cArray, offset, n); } -static VALUE -ary_take_first_or_last(int argc, const VALUE *argv, VALUE ary, enum ary_take_pos_flags last) -{ - argc = rb_check_arity(argc, 0, 1); - /* the case optional argument is omitted should be handled in - * callers of this function. if another arity case is added, - * this arity check needs to rewrite. */ - RUBY_ASSERT_ALWAYS(argc == 1); - return ary_take_first_or_last_n(ary, NUM2LONG(argv[0]), last); -} - /* * call-seq: - * self << object -> self + * array << object -> self * - * Appends +object+ as the last element in +self+; returns +self+: + * Appends +object+ to +self+; returns +self+: * - * [:foo, 'bar', 2] << :baz # => [:foo, "bar", 2, :baz] + * a = [:foo, 'bar', 2] + * a << :baz # => [:foo, "bar", 2, :baz] * - * Appends +object+ as a single element, even if it is another array: + * Appends +object+ as one element, even if it is another \Array: * - * [:foo, 'bar', 2] << [3, 4] # => [:foo, "bar", 2, [3, 4]] + * a = [:foo, 'bar', 2] + * a1 = a << [3, 4] + * a1 # => [:foo, "bar", 2, [3, 4]] * - * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning]. */ VALUE @@ -1385,7 +1484,7 @@ rb_ary_push(VALUE ary, VALUE item) { long idx = RARRAY_LEN((ary_verify(ary), ary)); VALUE target_ary = ary_ensure_room_for_push(ary, 1); - RARRAY_PTR_USE(ary, ptr, { + RARRAY_PTR_USE_TRANSIENT(ary, ptr, { RB_OBJ_WRITE(target_ary, &ptr[idx], item); }); ARY_SET_LEN(ary, idx + 1); @@ -1405,20 +1504,24 @@ rb_ary_cat(VALUE ary, const VALUE *argv, long len) /* * call-seq: - * push(*objects) -> self - * append(*objects) -> self + * array.push(*objects) -> self * - * Appends each argument in +objects+ to +self+; returns +self+: + * Appends trailing elements. * - * a = [:foo, 'bar', 2] # => [:foo, "bar", 2] - * a.push(:baz, :bat) # => [:foo, "bar", 2, :baz, :bat] + * Appends each argument in +objects+ to +self+; returns +self+: * - * Appends each argument as a single element, even if it is another array: + * a = [:foo, 'bar', 2] + * a.push(:baz, :bat) # => [:foo, "bar", 2, :baz, :bat] + * + * Appends each argument as one element, even if it is another \Array: + * + * a = [:foo, 'bar', 2] + * a1 = a.push([:baz, :bat], [:bam, :bad]) + * a1 # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]] * - * a = [:foo, 'bar', 2] # => [:foo, "bar", 2] - a.push([:baz, :bat], [:bam, :bad]) # => [:foo, "bar", 2, [:baz, :bat], [:bam, :bad]] + * Array#append is an alias for Array#push. * - * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning]. + * Related: #pop, #shift, #unshift. */ static VALUE @@ -1462,9 +1565,9 @@ rb_ary_pop(VALUE ary) * * Returns +nil+ if the array is empty. * - * When a non-negative Integer argument +n+ is given and is in range, + * When a non-negative \Integer argument +n+ is given and is in range, * - * removes and returns the last +n+ elements in a new +Array+: + * removes and returns the last +n+ elements in a new \Array: * a = [:foo, 'bar', 2] * a.pop(2) # => ["bar", 2] * @@ -1526,20 +1629,20 @@ rb_ary_shift(VALUE ary) * * Returns +nil+ if +self+ is empty. * - * When positive Integer argument +n+ is given, removes the first +n+ elements; - * returns those elements in a new +Array+: + * When positive \Integer argument +n+ is given, removes the first +n+ elements; + * returns those elements in a new \Array: * * a = [:foo, 'bar', 2] * a.shift(2) # => [:foo, 'bar'] * a # => [2] * * If +n+ is as large as or larger than <tt>self.length</tt>, - * removes all elements; returns those elements in a new +Array+: + * removes all elements; returns those elements in a new \Array: * * a = [:foo, 'bar', 2] * a.shift(3) # => [:foo, 'bar', 2] * - * If +n+ is zero, returns a new empty +Array+; +self+ is unmodified. + * If +n+ is zero, returns a new empty \Array; +self+ is unmodified. * * Related: #push, #pop, #unshift. */ @@ -1562,7 +1665,7 @@ rb_ary_shift_m(int argc, VALUE *argv, VALUE ary) return result; } -VALUE +MJIT_FUNC_EXPORTED VALUE rb_ary_behead(VALUE ary, long n) { if (n <= 0) { @@ -1573,7 +1676,7 @@ rb_ary_behead(VALUE ary, long n) if (!ARY_SHARED_P(ary)) { if (ARY_EMBED_P(ary) || RARRAY_LEN(ary) < ARY_DEFAULT_SIZE) { - RARRAY_PTR_USE(ary, ptr, { + RARRAY_PTR_USE_TRANSIENT(ary, ptr, { MEMMOVE(ptr, ptr + n, VALUE, RARRAY_LEN(ary) - n); }); /* WB: no new reference */ ARY_INCREASE_LEN(ary, -n); @@ -1606,7 +1709,7 @@ make_room_for_unshift(VALUE ary, const VALUE *head, VALUE *sharedp, int argc, lo head = sharedp + argc + room; } ARY_SET_PTR(ary, head - argc); - RUBY_ASSERT(ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))); + assert(ARY_SHARED_ROOT_OCCUPIED(ARY_SHARED_ROOT(ary))); ary_verify(ary); return ARY_SHARED_ROOT(ary); @@ -1634,12 +1737,12 @@ ary_modify_for_unshift(VALUE ary, int argc) capa = ARY_CAPA(ary); ary_make_shared(ary); - head = sharedp = RARRAY_CONST_PTR(ary); + head = sharedp = RARRAY_CONST_PTR_TRANSIENT(ary); return make_room_for_unshift(ary, head, (void *)sharedp, argc, capa, len); } else { /* sliding items */ - RARRAY_PTR_USE(ary, ptr, { + RARRAY_PTR_USE_TRANSIENT(ary, ptr, { MEMMOVE(ptr + argc, ptr, VALUE, len); }); @@ -1671,8 +1774,8 @@ ary_ensure_room_for_unshift(VALUE ary, int argc) return ary_modify_for_unshift(ary, argc); } else { - const VALUE * head = RARRAY_CONST_PTR(ary); - void *sharedp = (void *)RARRAY_CONST_PTR(shared_root); + const VALUE * head = RARRAY_CONST_PTR_TRANSIENT(ary); + void *sharedp = (void *)RARRAY_CONST_PTR_TRANSIENT(shared_root); rb_ary_modify_check(ary); return make_room_for_unshift(ary, head, sharedp, argc, capa, len); @@ -1689,10 +1792,12 @@ ary_ensure_room_for_unshift(VALUE ary, int argc) * a = [:foo, 'bar', 2] * a.unshift(:bam, :bat) # => [:bam, :bat, :foo, "bar", 2] * + * Array#prepend is an alias for Array#unshift. + * * Related: #push, #pop, #shift. */ -VALUE +static VALUE rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary) { long len = RARRAY_LEN(ary); @@ -1712,7 +1817,7 @@ rb_ary_unshift_m(int argc, VALUE *argv, VALUE ary) VALUE rb_ary_unshift(VALUE ary, VALUE item) { - return rb_ary_unshift_m(1, &item, ary); + return rb_ary_unshift_m(1,&item,ary); } /* faster version - use this if you don't need to treat negative offset */ @@ -1765,42 +1870,25 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e); /* * call-seq: - * self[index] -> object or nil - * self[start, length] -> object or nil - * self[range] -> object or nil - * self[aseq] -> object or nil - * slice(index) -> object or nil - * slice(start, length) -> object or nil - * slice(range) -> object or nil - * slice(aseq) -> object or nil + * array[index] -> object or nil + * array[start, length] -> object or nil + * array[range] -> object or nil + * array[aseq] -> object or nil + * array.slice(index) -> object or nil + * array.slice(start, length) -> object or nil + * array.slice(range) -> object or nil + * array.slice(aseq) -> object or nil * * Returns elements from +self+; does not modify +self+. * - * In brief: - * - * a = [:foo, 'bar', 2] - * - * # Single argument index: returns one element. - * a[0] # => :foo # Zero-based index. - * a[-1] # => 2 # Negative index counts backwards from end. - * - * # Arguments start and length: returns an array. - * a[1, 2] # => ["bar", 2] - * a[-2, 2] # => ["bar", 2] # Negative start counts backwards from end. - * - * # Single argument range: returns an array. - * a[0..1] # => [:foo, "bar"] - * a[0..-2] # => [:foo, "bar"] # Negative range-begin counts backwards from end. - * a[-2..2] # => ["bar", 2] # Negative range-end counts backwards from end. - * - * When a single integer argument +index+ is given, returns the element at offset +index+: + * When a single \Integer argument +index+ is given, returns the element at offset +index+: * * a = [:foo, 'bar', 2] * a[0] # => :foo * a[2] # => 2 * a # => [:foo, "bar", 2] * - * If +index+ is negative, counts backwards from the end of +self+: + * If +index+ is negative, counts relative to the end of +self+: * * a = [:foo, 'bar', 2] * a[-1] # => 2 @@ -1808,8 +1896,8 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e); * * If +index+ is out of range, returns +nil+. * - * When two Integer arguments +start+ and +length+ are given, - * returns a new +Array+ of size +length+ containing successive elements beginning at offset +start+: + * When two \Integer arguments +start+ and +length+ are given, + * returns a new \Array of size +length+ containing successive elements beginning at offset +start+: * * a = [:foo, 'bar', 2] * a[0, 2] # => [:foo, "bar"] @@ -1824,11 +1912,11 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e); * a[2, 2] # => [2] * * If <tt>start == self.size</tt> and <tt>length >= 0</tt>, - * returns a new empty +Array+. + * returns a new empty \Array. * * If +length+ is negative, returns +nil+. * - * When a single Range argument +range+ is given, + * When a single \Range argument +range+ is given, * treats <tt>range.min</tt> as +start+ above * and <tt>range.size</tt> as +length+ above: * @@ -1836,7 +1924,7 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e); * a[0..1] # => [:foo, "bar"] * a[1..2] # => ["bar", 2] * - * Special case: If <tt>range.start == a.size</tt>, returns a new empty +Array+. + * Special case: If <tt>range.start == a.size</tt>, returns a new empty \Array. * * If <tt>range.end</tt> is negative, calculates the end index from the end: * @@ -1860,7 +1948,7 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e); * a[4..-1] # => nil * * When a single Enumerator::ArithmeticSequence argument +aseq+ is given, - * returns an +Array+ of elements corresponding to the indexes produced by + * returns an \Array of elements corresponding to the indexes produced by * the sequence. * * a = ['--', 'data1', '--', 'data2', '--', 'data3'] @@ -1882,7 +1970,7 @@ static VALUE rb_ary_aref2(VALUE ary, VALUE b, VALUE e); * # Raises TypeError (no implicit conversion of Symbol into Integer): * a[:foo] * - * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. + * Array#slice is an alias for Array#[]. */ VALUE @@ -1906,7 +1994,7 @@ rb_ary_aref2(VALUE ary, VALUE b, VALUE e) return rb_ary_subseq(ary, beg, len); } -VALUE +MJIT_FUNC_EXPORTED VALUE rb_ary_aref1(VALUE ary, VALUE arg) { long beg, len, step; @@ -1930,26 +2018,13 @@ rb_ary_aref1(VALUE ary, VALUE arg) /* * call-seq: - * at(index) -> object or nil - * - * Returns the element of +self+ specified by the given +index+ - * or +nil+ if there is no such element; - * +index+ must be an - * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects]. - * - * For non-negative +index+, returns the element of +self+ at offset +index+: + * array.at(index) -> object * + * Returns the element at \Integer offset +index+; does not modify +self+. * a = [:foo, 'bar', 2] - * a.at(0) # => :foo - * a.at(2) # => 2 - * a.at(2.0) # => 2 - * - * For negative +index+, counts backwards from the end of +self+: + * a.at(0) # => :foo + * a.at(2) # => 2 * - * a.at(-2) # => "bar" - * - * Related: Array#[]; - * see also {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. */ VALUE @@ -1958,7 +2033,39 @@ rb_ary_at(VALUE ary, VALUE pos) return rb_ary_entry(ary, NUM2LONG(pos)); } -#if 0 +/* + * call-seq: + * array.first -> object or nil + * array.first(n) -> new_array + * + * Returns elements from +self+; does not modify +self+. + * + * When no argument is given, returns the first element: + * + * a = [:foo, 'bar', 2] + * a.first # => :foo + * a # => [:foo, "bar", 2] + * + * If +self+ is empty, returns +nil+. + * + * When non-negative \Integer argument +n+ is given, + * returns the first +n+ elements in a new \Array: + * + * a = [:foo, 'bar', 2] + * a.first(2) # => [:foo, "bar"] + * + * If <tt>n >= array.size</tt>, returns all elements: + * + * a = [:foo, 'bar', 2] + * a.first(50) # => [:foo, "bar", 2] + * + * If <tt>n == 0</tt> returns an new empty \Array: + * + * a = [:foo, 'bar', 2] + * a.first(0) # [] + * + * Related: #last. + */ static VALUE rb_ary_first(int argc, VALUE *argv, VALUE ary) { @@ -1970,26 +2077,48 @@ rb_ary_first(int argc, VALUE *argv, VALUE ary) return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_FIRST); } } -#endif -static VALUE -ary_first(VALUE self) -{ - return (RARRAY_LEN(self) == 0) ? Qnil : RARRAY_AREF(self, 0); -} - -static VALUE -ary_last(VALUE self) -{ - long len = RARRAY_LEN(self); - return (len == 0) ? Qnil : RARRAY_AREF(self, len-1); -} +/* + * call-seq: + * array.last -> object or nil + * array.last(n) -> new_array + * + * Returns elements from +self+; +self+ is not modified. + * + * When no argument is given, returns the last element: + * + * a = [:foo, 'bar', 2] + * a.last # => 2 + * a # => [:foo, "bar", 2] + * + * If +self+ is empty, returns +nil+. + * + * When non-negative \Integer argument +n+ is given, + * returns the last +n+ elements in a new \Array: + * + * a = [:foo, 'bar', 2] + * a.last(2) # => ["bar", 2] + * + * If <tt>n >= array.size</tt>, returns all elements: + * + * a = [:foo, 'bar', 2] + * a.last(50) # => [:foo, "bar", 2] + * + * If <tt>n == 0</tt>, returns an new empty \Array: + * + * a = [:foo, 'bar', 2] + * a.last(0) # [] + * + * Related: #first. + */ VALUE -rb_ary_last(int argc, const VALUE *argv, VALUE ary) // used by parse.y +rb_ary_last(int argc, const VALUE *argv, VALUE ary) { if (argc == 0) { - return ary_last(ary); + long len = RARRAY_LEN(ary); + if (len == 0) return Qnil; + return RARRAY_AREF(ary, len-1); } else { return ary_take_first_or_last(argc, argv, ary, ARY_TAKE_LAST); @@ -1998,19 +2127,17 @@ rb_ary_last(int argc, const VALUE *argv, VALUE ary) // used by parse.y /* * call-seq: - * fetch(index) -> element - * fetch(index, default_value) -> element or default_value - * fetch(index) {|index| ... } -> element or block_return_value + * array.fetch(index) -> element + * array.fetch(index, default_value) -> element + * array.fetch(index) {|index| ... } -> element * - * Returns the element of +self+ at offset +index+ if +index+ is in range; +index+ must be an - * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects]. + * Returns the element at offset +index+. * - * With the single argument +index+ and no block, + * With the single \Integer argument +index+, * returns the element at offset +index+: * * a = [:foo, 'bar', 2] - * a.fetch(1) # => "bar" - * a.fetch(1.1) # => "bar" + * a.fetch(1) # => "bar" * * If +index+ is negative, counts from the end of the array: * @@ -2018,12 +2145,12 @@ rb_ary_last(int argc, const VALUE *argv, VALUE ary) // used by parse.y * a.fetch(-1) # => 2 * a.fetch(-2) # => "bar" * - * With arguments +index+ and +default_value+ (which may be any object) and no block, - * returns +default_value+ if +index+ is out-of-range: + * With arguments +index+ and +default_value+, + * returns the element at offset +index+ if index is in range, + * otherwise returns +default_value+: * * a = [:foo, 'bar', 2] - * a.fetch(1, nil) # => "bar" - * a.fetch(3, :foo) # => :foo + * a.fetch(1, nil) # => "bar" * * With argument +index+ and a block, * returns the element at offset +index+ if index is in range @@ -2033,7 +2160,6 @@ rb_ary_last(int argc, const VALUE *argv, VALUE ary) // used by parse.y * a.fetch(1) {|index| raise 'Cannot happen' } # => "bar" * a.fetch(50) {|index| "Value for #{index}" } # => "Value for 50" * - * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. */ static VALUE @@ -2066,16 +2192,13 @@ rb_ary_fetch(int argc, VALUE *argv, VALUE ary) /* * call-seq: - * find_index(object) -> integer or nil - * find_index {|element| ... } -> integer or nil - * find_index -> new_enumerator - * index(object) -> integer or nil - * index {|element| ... } -> integer or nil - * index -> new_enumerator + * array.index(object) -> integer or nil + * array.index {|element| ... } -> integer or nil + * array.index -> new_enumerator * - * Returns the zero-based integer index of a specified element, or +nil+. + * Returns the index of a specified element. * - * With only argument +object+ given, + * When argument +object+ is given but no block, * returns the index of the first element +element+ * for which <tt>object == element</tt>: * @@ -2084,7 +2207,7 @@ rb_ary_fetch(int argc, VALUE *argv, VALUE ary) * * Returns +nil+ if no such element found. * - * With only a block given, + * When both argument +object+ and a block are given, * calls the block with each successive element; * returns the index of the first element for which the block returns a truthy value: * @@ -2093,9 +2216,16 @@ rb_ary_fetch(int argc, VALUE *argv, VALUE ary) * * Returns +nil+ if the block never returns a truthy value. * - * With neither an argument nor a block given, returns a new Enumerator. + * When neither an argument nor a block is given, returns a new Enumerator: + * + * a = [:foo, 'bar', 2] + * e = a.index + * e # => #<Enumerator: [:foo, "bar", 2]:index> + * e.each {|element| element == 'bar' } # => 1 * - * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying]. + * Array#find_index is an alias for Array#index. + * + * Related: #rindex. */ static VALUE @@ -2149,7 +2279,7 @@ rb_ary_index(int argc, VALUE *argv, VALUE ary) * * Returns +nil+ if the block never returns a truthy value. * - * When neither an argument nor a block is given, returns a new Enumerator: + * When neither an argument nor a block is given, returns a new \Enumerator: * * a = [:foo, 'bar', 2, 'bar'] * e = a.rindex @@ -2221,7 +2351,7 @@ rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen) } { - const VALUE *optr = RARRAY_CONST_PTR(ary); + const VALUE *optr = RARRAY_CONST_PTR_TRANSIENT(ary); rofs = (rptr >= optr && rptr < optr + olen) ? rptr - optr : -1; } @@ -2234,7 +2364,7 @@ rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen) len = beg + rlen; ary_mem_clear(ary, olen, beg - olen); if (rlen > 0) { - if (rofs != -1) rptr = RARRAY_CONST_PTR(ary) + rofs; + if (rofs != -1) rptr = RARRAY_CONST_PTR_TRANSIENT(ary) + rofs; ary_memcpy0(ary, beg, rlen, rptr, target_ary); } ARY_SET_LEN(ary, len); @@ -2252,25 +2382,20 @@ rb_ary_splice(VALUE ary, long beg, long len, const VALUE *rptr, long rlen) } if (len != rlen) { - RARRAY_PTR_USE(ary, ptr, + RARRAY_PTR_USE_TRANSIENT(ary, ptr, MEMMOVE(ptr + beg + rlen, ptr + beg + len, VALUE, olen - (beg + len))); ARY_SET_LEN(ary, alen); } if (rlen > 0) { - if (rofs == -1) { - rb_gc_writebarrier_remember(ary); - } - else { - /* In this case, we're copying from a region in this array, so - * we don't need to fire the write barrier. */ - rptr = RARRAY_CONST_PTR(ary) + rofs; - } + if (rofs != -1) rptr = RARRAY_CONST_PTR_TRANSIENT(ary) + rofs; + /* give up wb-protected ary */ + RB_OBJ_WB_UNPROTECT_FOR(ARRAY, ary); /* do not use RARRAY_PTR() because it can causes GC. * ary can contain T_NONE object because it is not cleared. */ - RARRAY_PTR_USE(ary, ptr, + RARRAY_PTR_USE_TRANSIENT(ary, ptr, MEMMOVE(ptr + beg, rptr, VALUE, rlen)); } } @@ -2315,8 +2440,9 @@ rb_ary_resize(VALUE ary, long len) else if (len <= ary_embed_capa(ary)) { const VALUE *ptr = ARY_HEAP_PTR(ary); long ptr_capa = ARY_HEAP_SIZE(ary); - bool is_malloc_ptr = !ARY_SHARED_P(ary); + bool is_malloc_ptr = !ARY_SHARED_P(ary) && !RARRAY_TRANSIENT_P(ary); + FL_UNSET(ary, RARRAY_TRANSIENT_FLAG); FL_SET_EMBED(ary); MEMCPY((VALUE *)ARY_EMBED_PTR(ary), ptr, VALUE, len); /* WB: no new reference */ @@ -2346,48 +2472,20 @@ static VALUE ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val) { VALUE rpl = rb_ary_to_ary(val); - rb_ary_splice(ary, beg, len, RARRAY_CONST_PTR(rpl), RARRAY_LEN(rpl)); + rb_ary_splice(ary, beg, len, RARRAY_CONST_PTR_TRANSIENT(rpl), RARRAY_LEN(rpl)); RB_GC_GUARD(rpl); return val; } /* * call-seq: - * self[index] = object -> object - * self[start, length] = object -> object - * self[range] = object -> object - * - * Assigns elements in +self+, based on the given +object+; returns +object+. - * - * In brief: - * - * a_orig = [:foo, 'bar', 2] - * - * # With argument index. - * a = a_orig.dup - * a[0] = 'foo' # => "foo" - * a # => ["foo", "bar", 2] - * a = a_orig.dup - * a[7] = 'foo' # => "foo" - * a # => [:foo, "bar", 2, nil, nil, nil, nil, "foo"] - * - * # With arguments start and length. - * a = a_orig.dup - * a[0, 2] = 'foo' # => "foo" - * a # => ["foo", 2] - * a = a_orig.dup - * a[6, 50] = 'foo' # => "foo" - * a # => [:foo, "bar", 2, nil, nil, nil, "foo"] - * - * # With argument range. - * a = a_orig.dup - * a[0..1] = 'foo' # => "foo" - * a # => ["foo", 2] - * a = a_orig.dup - * a[6..50] = 'foo' # => "foo" - * a # => [:foo, "bar", 2, nil, nil, nil, "foo"] - * - * When Integer argument +index+ is given, assigns +object+ to an element in +self+. + * array[index] = object -> object + * array[start, length] = object -> object + * array[range] = object -> object + * + * Assigns elements in +self+; returns the given +object+. + * + * When \Integer argument +index+ is given, assigns +object+ to an element in +self+. * * If +index+ is non-negative, assigns +object+ the element at offset +index+: * @@ -2407,7 +2505,7 @@ ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val) * a[-1] = 'two' # => "two" * a # => [:foo, "bar", "two"] * - * When Integer arguments +start+ and +length+ are given and +object+ is not an +Array+, + * When \Integer arguments +start+ and +length+ are given and +object+ is not an \Array, * removes <tt>length - 1</tt> elements beginning at offset +start+, * and assigns +object+ at offset +start+: * @@ -2442,7 +2540,7 @@ ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val) * a[1, 5] = 'foo' # => "foo" * a # => [:foo, "foo"] * - * When Range argument +range+ is given and +object+ is not an +Array+, + * When \Range argument +range+ is given and +object+ is an \Array, * removes <tt>length - 1</tt> elements beginning at offset +start+, * and assigns +object+ at offset +start+: * @@ -2457,8 +2555,7 @@ ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val) * a # => [:foo, "foo"] * * If the array length is less than <tt>range.begin</tt>, - * extends the array with +nil+, assigns +object+ at offset <tt>range.begin</tt>, - * and ignores +length+: + * assigns +object+ at offset <tt>range.begin</tt>, and ignores +length+: * * a = [:foo, 'bar', 2] * a[6..50] = 'foo' # => "foo" @@ -2492,7 +2589,6 @@ ary_aset_by_rb_ary_splice(VALUE ary, long beg, long len, VALUE val) * a[1..5] = 'foo' # => "foo" * a # => [:foo, "foo"] * - * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning]. */ static VALUE @@ -2522,38 +2618,38 @@ rb_ary_aset(int argc, VALUE *argv, VALUE ary) /* * call-seq: - * insert(index, *objects) -> self + * array.insert(index, *objects) -> self * - * Inserts the given +objects+ as elements of +self+; + * Inserts given +objects+ before or after the element at \Integer index +offset+; * returns +self+. * - * When +index+ is non-negative, inserts +objects+ - * _before_ the element at offset +index+: + * When +index+ is non-negative, inserts all given +objects+ + * before the element at offset +index+: * - * a = ['a', 'b', 'c'] # => ["a", "b", "c"] - * a.insert(1, :x, :y, :z) # => ["a", :x, :y, :z, "b", "c"] + * a = [:foo, 'bar', 2] + * a.insert(1, :bat, :bam) # => [:foo, :bat, :bam, "bar", 2] * * Extends the array if +index+ is beyond the array (<tt>index >= self.size</tt>): * - * a = ['a', 'b', 'c'] # => ["a", "b", "c"] - * a.insert(5, :x, :y, :z) # => ["a", "b", "c", nil, nil, :x, :y, :z] - * - * When +index+ is negative, inserts +objects+ - * _after_ the element at offset <tt>index + self.size</tt>: + * a = [:foo, 'bar', 2] + * a.insert(5, :bat, :bam) + * a # => [:foo, "bar", 2, nil, nil, :bat, :bam] * - * a = ['a', 'b', 'c'] # => ["a", "b", "c"] - * a.insert(-2, :x, :y, :z) # => ["a", "b", :x, :y, :z, "c"] + * Does nothing if no objects given: * - * With no +objects+ given, does nothing: + * a = [:foo, 'bar', 2] + * a.insert(1) + * a.insert(50) + * a.insert(-50) + * a # => [:foo, "bar", 2] * - * a = ['a', 'b', 'c'] # => ["a", "b", "c"] - * a.insert(1) # => ["a", "b", "c"] - * a.insert(50) # => ["a", "b", "c"] - * a.insert(-50) # => ["a", "b", "c"] + * When +index+ is negative, inserts all given +objects+ + * _after_ the element at offset <tt>index+self.size</tt>: * - * Raises IndexError if +objects+ are given and +index+ is negative and out of range. + * a = [:foo, 'bar', 2] + * a.insert(-2, :bat, :bam) + * a # => [:foo, "bar", :bat, :bam, 2] * - * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning]. */ static VALUE @@ -2589,19 +2685,50 @@ ary_enum_length(VALUE ary, VALUE args, VALUE eobj) return rb_ary_length(ary); } -// Primitive to avoid a race condition in Array#each. -// Return `true` and write `value` and `index` if the element exists. -static VALUE -ary_fetch_next(VALUE self, VALUE *index, VALUE *value) -{ - long i = NUM2LONG(*index); - if (i >= RARRAY_LEN(self)) { - return Qfalse; - } - *value = RARRAY_AREF(self, i); - *index = LONG2NUM(i + 1); - return Qtrue; -} +/* + * call-seq: + * array.each {|element| ... } -> self + * array.each -> Enumerator + * + * Iterates over array elements. + * + * When a block given, passes each successive array element to the block; + * returns +self+: + * + * a = [:foo, 'bar', 2] + * a.each {|element| puts "#{element.class} #{element}" } + * + * Output: + * + * Symbol foo + * String bar + * Integer 2 + * + * Allows the array to be modified during iteration: + * + * a = [:foo, 'bar', 2] + * a.each {|element| puts element; a.clear if element.to_s.start_with?('b') } + * + * Output: + * + * foo + * bar + * + * When no block given, returns a new \Enumerator: + * a = [:foo, 'bar', 2] + * + * e = a.each + * e # => #<Enumerator: [:foo, "bar", 2]:each> + * a1 = e.each {|element| puts "#{element.class} #{element}" } + * + * Output: + * + * Symbol foo + * String bar + * Integer 2 + * + * Related: #each_index, #reverse_each. + */ VALUE rb_ary_each(VALUE ary) @@ -2617,11 +2744,12 @@ rb_ary_each(VALUE ary) /* * call-seq: - * each_index {|index| ... } -> self - * each_index -> new_enumerator + * array.each_index {|index| ... } -> self + * array.each_index -> Enumerator * - * With a block given, iterates over the elements of +self+, - * passing each <i>array index</i> to the block; + * Iterates over array indexes. + * + * When a block given, passes each successive array index to the block; * returns +self+: * * a = [:foo, 'bar', 2] @@ -2643,9 +2771,20 @@ rb_ary_each(VALUE ary) * 0 * 1 * - * With no block given, returns a new Enumerator. + * When no block given, returns a new \Enumerator: + * + * a = [:foo, 'bar', 2] + * e = a.each_index + * e # => #<Enumerator: [:foo, "bar", 2]:each_index> + * a1 = e.each {|index| puts "#{index} #{a[index]}"} + * + * Output: * - * Related: see {Methods for Iterating}[rdoc-ref:Array@Methods+for+Iterating]. + * 0 foo + * 1 bar + * 2 2 + * + * Related: #each, #reverse_each. */ static VALUE @@ -2689,7 +2828,7 @@ rb_ary_each_index(VALUE ary) * 2 * bar * - * When no block given, returns a new Enumerator: + * When no block given, returns a new \Enumerator: * * a = [:foo, 'bar', 2] * e = a.reverse_each @@ -2725,15 +2864,9 @@ rb_ary_reverse_each(VALUE ary) /* * call-seq: - * length -> integer - * size -> integer + * array.length -> an_integer * - * Returns the count of elements in +self+: - * - * [0, 1, 2].length # => 3 - * [].length # => 0 - * - * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying]. + * Returns the count of elements in +self+. */ static VALUE @@ -2749,8 +2882,6 @@ rb_ary_length(VALUE ary) * * Returns +true+ if the count of elements in +self+ is zero, * +false+ otherwise. - * - * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying]. */ static VALUE @@ -2764,7 +2895,7 @@ rb_ary_dup(VALUE ary) { long len = RARRAY_LEN(ary); VALUE dup = rb_ary_new2(len); - ary_memcpy(dup, 0, len, RARRAY_CONST_PTR(ary)); + ary_memcpy(dup, 0, len, RARRAY_CONST_PTR_TRANSIENT(ary)); ARY_SET_LEN(dup, len); ary_verify(ary); @@ -2914,32 +3045,31 @@ rb_ary_join(VALUE ary, VALUE sep) /* * call-seq: + * array.join ->new_string * array.join(separator = $,) -> new_string * - * Returns the new string formed by joining the converted elements of +self+; - * for each element +element+: + * Returns the new \String formed by joining the array elements after conversion. + * For each element +element+: * - * - Converts recursively using <tt>element.join(separator)</tt> - * if +element+ is a <tt>kind_of?(Array)</tt>. - * - Otherwise, converts using <tt>element.to_s</tt>. + * - Uses <tt>element.to_s</tt> if +element+ is not a <tt>kind_of?(Array)</tt>. + * - Uses recursive <tt>element.join(separator)</tt> if +element+ is a <tt>kind_of?(Array)</tt>. * - * With no argument given, joins using the output field separator, <tt>$,</tt>: + * With no argument, joins using the output field separator, <tt>$,</tt>: * * a = [:foo, 'bar', 2] * $, # => nil * a.join # => "foobar2" * - * With string argument +separator+ given, joins using that separator: + * With \string argument +separator+, joins using that separator: * * a = [:foo, 'bar', 2] * a.join("\n") # => "foo\nbar\n2" * - * Joins recursively for nested arrays: + * Joins recursively for nested Arrays: * * a = [:foo, [:bar, [:baz, :bat]]] * a.join # => "foobarbazbat" * - * Related: see {Methods for Converting}[rdoc-ref:Array@Methods+for+Converting]. */ static VALUE rb_ary_join_m(int argc, VALUE *argv, VALUE ary) @@ -2976,15 +3106,15 @@ inspect_ary(VALUE ary, VALUE dummy, int recur) /* * call-seq: - * inspect -> new_string + * array.inspect -> new_string * - * Returns the new string formed by calling method <tt>#inspect</tt> + * Returns the new \String formed by calling method <tt>#inspect</tt> * on each array element: * * a = [:foo, 'bar', 2] * a.inspect # => "[:foo, \"bar\", 2]" * - * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying]. + * Array#to_s is an alias for Array#inspect. */ static VALUE @@ -3004,12 +3134,12 @@ rb_ary_to_s(VALUE ary) * call-seq: * to_a -> self or new_array * - * When +self+ is an instance of +Array+, returns +self+: + * When +self+ is an instance of \Array, returns +self+: * * a = [:foo, 'bar', 2] * a.to_a # => [:foo, "bar", 2] * - * Otherwise, returns a new +Array+ containing the elements of +self+: + * Otherwise, returns a new \Array containing the elements of +self+: * * class MyArray < Array; end * a = MyArray.new(['foo', 'bar', 'two']) @@ -3037,18 +3167,18 @@ rb_ary_to_a(VALUE ary) * array.to_h -> new_hash * array.to_h {|item| ... } -> new_hash * - * Returns a new Hash formed from +self+. + * Returns a new \Hash formed from +self+. * * When a block is given, calls the block with each array element; - * the block must return a 2-element +Array+ whose two elements - * form a key-value pair in the returned Hash: + * the block must return a 2-element \Array whose two elements + * form a key-value pair in the returned \Hash: * * a = ['foo', :bar, 1, [2, 3], {baz: 4}] * h = a.to_h {|item| [item, item] } * h # => {"foo"=>"foo", :bar=>:bar, 1=>1, [2, 3]=>[2, 3], {:baz=>4}=>{:baz=>4}} * - * When no block is given, +self+ must be an +Array+ of 2-element sub-arrays, - * each sub-array is formed into a key-value pair in the new Hash: + * When no block is given, +self+ must be an \Array of 2-element sub-arrays, + * each sub-array is formed into a key-value pair in the new \Hash: * * [].to_h # => {} * a = [['foo', 'zero'], ['bar', 'one'], ['baz', 'two']] @@ -3112,7 +3242,7 @@ rb_ary_reverse(VALUE ary) rb_ary_modify(ary); if (len > 1) { - RARRAY_PTR_USE(ary, p1, { + RARRAY_PTR_USE_TRANSIENT(ary, p1, { p2 = p1 + len - 1; /* points last item */ ary_reverse(p1, p2); }); /* WB: no new reference */ @@ -3141,7 +3271,7 @@ rb_ary_reverse_bang(VALUE ary) * call-seq: * array.reverse -> new_array * - * Returns a new +Array+ with the elements of +self+ in reverse order: + * Returns a new \Array with the elements of +self+ in reverse order: * * a = ['foo', 'bar', 'two'] * a1 = a.reverse @@ -3156,8 +3286,8 @@ rb_ary_reverse_m(VALUE ary) VALUE dup = rb_ary_new2(len); if (len > 0) { - const VALUE *p1 = RARRAY_CONST_PTR(ary); - VALUE *p2 = (VALUE *)RARRAY_CONST_PTR(dup) + len - 1; + const VALUE *p1 = RARRAY_CONST_PTR_TRANSIENT(ary); + VALUE *p2 = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(dup) + len - 1; do *p2-- = *p1++; while (--len > 0); } ARY_SET_LEN(dup, RARRAY_LEN(ary)); @@ -3199,7 +3329,7 @@ rb_ary_rotate(VALUE ary, long cnt) if (cnt != 0) { long len = RARRAY_LEN(ary); if (len > 1 && (cnt = rotate_count(cnt, len)) > 0) { - RARRAY_PTR_USE(ary, ptr, ary_rotate_ptr(ptr, len, cnt)); + RARRAY_PTR_USE_TRANSIENT(ary, ptr, ary_rotate_ptr(ptr, len, cnt)); return ary; } } @@ -3218,7 +3348,7 @@ rb_ary_rotate(VALUE ary, long cnt) * a = [:foo, 'bar', 2, 'bar'] * a.rotate! # => ["bar", 2, "bar", :foo] * - * When given a non-negative Integer +count+, + * When given a non-negative \Integer +count+, * rotates +count+ elements from the beginning to the end: * * a = [:foo, 'bar', 2] @@ -3265,18 +3395,18 @@ rb_ary_rotate_bang(int argc, VALUE *argv, VALUE ary) * array.rotate -> new_array * array.rotate(count) -> new_array * - * Returns a new +Array+ formed from +self+ with elements + * Returns a new \Array formed from +self+ with elements * rotated from one end to the other. * - * When no argument given, returns a new +Array+ that is like +self+, + * When no argument given, returns a new \Array that is like +self+, * except that the first element has been rotated to the last position: * * a = [:foo, 'bar', 2, 'bar'] * a1 = a.rotate * a1 # => ["bar", 2, "bar", :foo] * - * When given a non-negative Integer +count+, - * returns a new +Array+ with +count+ elements rotated from the beginning to the end: + * When given a non-negative \Integer +count+, + * returns a new \Array with +count+ elements rotated from the beginning to the end: * * a = [:foo, 'bar', 2] * a1 = a.rotate(2) @@ -3294,7 +3424,7 @@ rb_ary_rotate_bang(int argc, VALUE *argv, VALUE ary) * a1 = a.rotate(0) * a1 # => [:foo, "bar", 2] * - * When given a negative Integer +count+, rotates in the opposite direction, + * When given a negative \Integer +count+, rotates in the opposite direction, * from end to beginning: * * a = [:foo, 'bar', 2] @@ -3321,7 +3451,7 @@ rb_ary_rotate_m(int argc, VALUE *argv, VALUE ary) rotated = rb_ary_new2(len); if (len > 0) { cnt = rotate_count(cnt, len); - ptr = RARRAY_CONST_PTR(ary); + ptr = RARRAY_CONST_PTR_TRANSIENT(ary); len -= cnt; ary_memcpy(rotated, 0, len, ptr + cnt); ary_memcpy(rotated, len, cnt, ptr); @@ -3404,7 +3534,7 @@ sort_2(const void *ap, const void *bp, void *dummy) * * Returns +self+ with its elements sorted in place. * - * With no block, compares elements using operator <tt>#<=></tt> + * With no block, compares elements using operator <tt><=></tt> * (see Comparable): * * a = 'abcde'.split('').shuffle @@ -3442,7 +3572,7 @@ VALUE rb_ary_sort_bang(VALUE ary) { rb_ary_modify(ary); - RUBY_ASSERT(!ARY_SHARED_P(ary)); + assert(!ARY_SHARED_P(ary)); if (RARRAY_LEN(ary) > 1) { VALUE tmp = ary_make_substitution(ary); /* only ary refers tmp */ struct ary_sort_data data; @@ -3460,9 +3590,6 @@ rb_ary_sort_bang(VALUE ary) rb_ary_unshare(ary); FL_SET_EMBED(ary); } - if (ARY_EMBED_LEN(tmp) > ARY_CAPA(ary)) { - ary_resize_capa(ary, ARY_EMBED_LEN(tmp)); - } ary_memcpy(ary, 0, ARY_EMBED_LEN(tmp), ARY_EMBED_PTR(tmp)); ARY_SET_LEN(ary, ARY_EMBED_LEN(tmp)); } @@ -3472,7 +3599,7 @@ rb_ary_sort_bang(VALUE ary) ARY_SET_CAPA(ary, RARRAY_LEN(tmp)); } else { - RUBY_ASSERT(!ARY_SHARED_P(tmp)); + assert(!ARY_SHARED_P(tmp)); if (ARY_EMBED_P(ary)) { FL_UNSET_EMBED(ary); } @@ -3505,9 +3632,9 @@ rb_ary_sort_bang(VALUE ary) * array.sort -> new_array * array.sort {|a, b| ... } -> new_array * - * Returns a new +Array+ whose elements are those from +self+, sorted. + * Returns a new \Array whose elements are those from +self+, sorted. * - * With no block, compares elements using operator <tt>#<=></tt> + * With no block, compares elements using operator <tt><=></tt> * (see Comparable): * * a = 'abcde'.split('').shuffle @@ -3554,15 +3681,12 @@ static VALUE rb_ary_bsearch_index(VALUE ary); /* * call-seq: - * bsearch {|element| ... } -> found_element or nil - * bsearch -> new_enumerator + * array.bsearch {|element| ... } -> object + * array.bsearch -> new_enumerator * - * Returns the element from +self+ found by a binary search, - * or +nil+ if the search found no suitable element. + * Returns an element from +self+ selected by a binary search. * * See {Binary Searching}[rdoc-ref:bsearch.rdoc]. - * - * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. */ static VALUE @@ -3578,15 +3702,11 @@ rb_ary_bsearch(VALUE ary) /* * call-seq: - * bsearch_index {|element| ... } -> integer or nil - * bsearch_index -> new_enumerator - * - * Returns the integer index of the element from +self+ found by a binary search, - * or +nil+ if the search found no suitable element. - * - * See {Binary Searching}[rdoc-ref:bsearch.rdoc]. + * array.bsearch_index {|element| ... } -> integer or nil + * array.bsearch_index -> new_enumerator * - * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. + * Searches +self+ as described at method #bsearch, + * but returns the _index_ of the found element instead of the element itself. */ static VALUE @@ -3662,7 +3782,7 @@ sort_by_i(RB_BLOCK_CALL_FUNC_ARGLIST(i, dummy)) * a.sort_by! {|element| element.size } * a # => ["d", "cc", "bbb", "aaaa"] * - * Returns a new Enumerator if no block given: + * Returns a new \Enumerator if no block given: * * a = ['aaaa', 'bbb', 'cc', 'd'] * a.sort_by! # => #<Enumerator: ["aaaa", "bbb", "cc", "d"]:sort_by!> @@ -3684,22 +3804,22 @@ rb_ary_sort_by_bang(VALUE ary) /* * call-seq: - * collect {|element| ... } -> new_array - * collect -> new_enumerator - * map {|element| ... } -> new_array - * map -> new_enumerator + * array.map {|element| ... } -> new_array + * array.map -> new_enumerator * - * With a block given, calls the block with each element of +self+; - * returns a new array whose elements are the return values from the block: + * Calls the block, if given, with each element of +self+; + * returns a new \Array whose elements are the return values from the block: * * a = [:foo, 'bar', 2] * a1 = a.map {|element| element.class } * a1 # => [Symbol, String, Integer] * - * With no block given, returns a new Enumerator. + * Returns a new \Enumerator if no block given: + * a = [:foo, 'bar', 2] + * a1 = a.map + * a1 # => #<Enumerator: [:foo, "bar", 2]:map> * - * Related: #collect!; - * see also {Methods for Converting}[rdoc-ref:Array@Methods+for+Converting]. + * Array#collect is an alias for Array#map. */ static VALUE @@ -3719,22 +3839,22 @@ rb_ary_collect(VALUE ary) /* * call-seq: - * collect! {|element| ... } -> new_array - * collect! -> new_enumerator - * map! {|element| ... } -> new_array - * map! -> new_enumerator + * array.map! {|element| ... } -> self + * array.map! -> new_enumerator * - * With a block given, calls the block with each element of +self+ - * and replaces the element with the block's return value; - * returns +self+: + * Calls the block, if given, with each element; + * replaces the element with the block's return value: * * a = [:foo, 'bar', 2] * a.map! { |element| element.class } # => [Symbol, String, Integer] * - * With no block given, returns a new Enumerator. + * Returns a new \Enumerator if no block given: + * + * a = [:foo, 'bar', 2] + * a1 = a.map! + * a1 # => #<Enumerator: [:foo, "bar", 2]:map!> * - * Related: #collect; - * see also {Methods for Converting}[rdoc-ref:Array@Methods+for+Converting]. + * Array#collect! is an alias for Array#map!. */ static VALUE @@ -3786,7 +3906,7 @@ append_values_at_single(VALUE result, VALUE ary, long olen, VALUE idx) /* check if idx is Range */ else if (rb_range_beg_len(idx, &beg, &len, olen, 1)) { if (len > 0) { - const VALUE *const src = RARRAY_CONST_PTR(ary); + const VALUE *const src = RARRAY_CONST_PTR_TRANSIENT(ary); const long end = beg + len; const long prevlen = RARRAY_LEN(result); if (beg < olen) { @@ -3808,8 +3928,8 @@ append_values_at_single(VALUE result, VALUE ary, long olen, VALUE idx) * call-seq: * array.values_at(*indexes) -> new_array * - * Returns a new +Array+ whose elements are the elements - * of +self+ at the given Integer or Range +indexes+. + * Returns a new \Array whose elements are the elements + * of +self+ at the given \Integer or \Range +indexes+. * * For each positive +index+, returns the element at offset +index+: * @@ -3828,7 +3948,7 @@ append_values_at_single(VALUE result, VALUE ary, long olen, VALUE idx) * a = [:foo, 'bar', 2] * a.values_at(0, 3, 1, 3) # => [:foo, nil, "bar", nil] * - * Returns a new empty +Array+ if no arguments given. + * Returns a new empty \Array if no arguments given. * * For each negative +index+, counts backward from the end of the array: * @@ -3862,22 +3982,23 @@ rb_ary_values_at(int argc, VALUE *argv, VALUE ary) /* * call-seq: - * select {|element| ... } -> new_array - * select -> new_enumerator - * filter {|element| ... } -> new_array - * filter -> new_enumerator + * array.select {|element| ... } -> new_array + * array.select -> new_enumerator * - * With a block given, calls the block with each element of +self+; - * returns a new array containing those elements of +self+ + * Calls the block, if given, with each element of +self+; + * returns a new \Array containing those elements of +self+ * for which the block returns a truthy value: * * a = [:foo, 'bar', 2, :bam] - * a.select {|element| element.to_s.start_with?('b') } - * # => ["bar", :bam] + * a1 = a.select {|element| element.to_s.start_with?('b') } + * a1 # => ["bar", :bam] * - * With no block given, returns a new Enumerator. + * Returns a new \Enumerator if no block given: * - * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. + * a = [:foo, 'bar', 2, :bam] + * a.select # => #<Enumerator: [:foo, "bar", 2, :bam]:select> + * + * Array#filter is an alias for Array#select. */ static VALUE @@ -3932,7 +4053,7 @@ select_bang_ensure(VALUE a) rb_ary_modify(ary); if (i1 < len) { tail = len - i1; - RARRAY_PTR_USE(ary, ptr, { + RARRAY_PTR_USE_TRANSIENT(ary, ptr, { MEMMOVE(ptr + i2, ptr + i1, VALUE, tail); }); } @@ -3943,12 +4064,10 @@ select_bang_ensure(VALUE a) /* * call-seq: - * select! {|element| ... } -> self or nil - * select! -> new_enumerator - * filter! {|element| ... } -> self or nil - * filter! -> new_enumerator + * array.select! {|element| ... } -> self or nil + * array.select! -> new_enumerator * - * With a block given, calls the block with each element of +self+; + * Calls the block, if given with each element of +self+; * removes from +self+ those elements for which the block returns +false+ or +nil+. * * Returns +self+ if any elements were removed: @@ -3958,9 +4077,12 @@ select_bang_ensure(VALUE a) * * Returns +nil+ if no elements were removed. * - * With no block given, returns a new Enumerator. + * Returns a new \Enumerator if no block given: + * + * a = [:foo, 'bar', 2, :bam] + * a.select! # => #<Enumerator: [:foo, "bar", 2, :bam]:select!> * - * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting]. + * Array#filter! is an alias for Array#select!. */ static VALUE @@ -3978,18 +4100,20 @@ rb_ary_select_bang(VALUE ary) /* * call-seq: - * keep_if {|element| ... } -> self - * keep_if -> new_enumerator + * array.keep_if {|element| ... } -> self + * array.keep_if -> new_enumeration * - * With a block given, calls the block with each element of +self+; - * removes the element from +self+ if the block does not return a truthy value: + * Retains those elements for which the block returns a truthy value; + * deletes all other elements; returns +self+: * * a = [:foo, 'bar', 2, :bam] * a.keep_if {|element| element.to_s.start_with?('b') } # => ["bar", :bam] * - * With no block given, returns a new Enumerator. + * Returns a new \Enumerator if no block given: + * + * a = [:foo, 'bar', 2, :bam] + * a.keep_if # => #<Enumerator: [:foo, "bar", 2, :bam]:keep_if> * - * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting]. */ static VALUE @@ -4015,39 +4139,38 @@ ary_resize_smaller(VALUE ary, long len) /* * call-seq: - * delete(object) -> last_removed_object - * delete(object) {|element| ... } -> last_removed_object or block_return + * array.delete(obj) -> deleted_object + * array.delete(obj) {|nosuch| ... } -> deleted_object or block_return * * Removes zero or more elements from +self+. * - * With no block given, - * removes from +self+ each element +ele+ such that <tt>ele == object</tt>; - * returns the last removed element: - * - * a = [0, 1, 2, 2.0] - * a.delete(2) # => 2.0 - * a # => [0, 1] + * When no block is given, + * removes from +self+ each element +ele+ such that <tt>ele == obj</tt>; + * returns the last deleted element: * - * Returns +nil+ if no elements removed: + * s1 = 'bar'; s2 = 'bar' + * a = [:foo, s1, 2, s2] + * a.delete('bar') # => "bar" + * a # => [:foo, 2] * - * a.delete(2) # => nil + * Returns +nil+ if no elements removed. * - * With a block given, - * removes from +self+ each element +ele+ such that <tt>ele == object</tt>. + * When a block is given, + * removes from +self+ each element +ele+ such that <tt>ele == obj</tt>. * * If any such elements are found, ignores the block - * and returns the last removed element: + * and returns the last deleted element: * - * a = [0, 1, 2, 2.0] - * a.delete(2) {|element| fail 'Cannot happen' } # => 2.0 - * a # => [0, 1] + * s1 = 'bar'; s2 = 'bar' + * a = [:foo, s1, 2, s2] + * deleted_obj = a.delete('bar') {|obj| fail 'Cannot happen' } + * a # => [:foo, 2] * - * If no such element is found, returns the block's return value: + * If no such elements are found, returns the block's return value: * - * a.delete(2) {|element| "Element #{element} not found." } - * # => "Element 2 not found." + * a = [:foo, 'bar', 2] + * a.delete(:nosuch) {|obj| "#{obj} not found" } # => "nosuch not found" * - * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting]. */ VALUE @@ -4118,7 +4241,7 @@ rb_ary_delete_at(VALUE ary, long pos) rb_ary_modify(ary); del = RARRAY_AREF(ary, pos); - RARRAY_PTR_USE(ary, ptr, { + RARRAY_PTR_USE_TRANSIENT(ary, ptr, { MEMMOVE(ptr+pos, ptr+pos+1, VALUE, len-pos-1); }); ARY_INCREASE_LEN(ary, -1); @@ -4128,10 +4251,9 @@ rb_ary_delete_at(VALUE ary, long pos) /* * call-seq: - * delete_at(index) -> removed_object or nil + * array.delete_at(index) -> deleted_object or nil * - * Removes the element of +self+ at the given +index+, which must be an - * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects]. + * Deletes an element from +self+, per the given \Integer +index+. * * When +index+ is non-negative, deletes the element at offset +index+: * @@ -4139,19 +4261,15 @@ rb_ary_delete_at(VALUE ary, long pos) * a.delete_at(1) # => "bar" * a # => [:foo, 2] * + * If index is too large, returns +nil+. + * * When +index+ is negative, counts backward from the end of the array: * * a = [:foo, 'bar', 2] * a.delete_at(-2) # => "bar" * a # => [:foo, 2] * - * When +index+ is out of range, returns +nil+. - * - * a = [:foo, 'bar', 2] - * a.delete_at(3) # => nil - * a.delete_at(-4) # => nil - * - * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting]. + * If +index+ is too small (far from zero), returns nil. */ static VALUE @@ -4184,7 +4302,7 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len) return rb_ary_new2(0); } else { - VALUE arg2 = rb_ary_new4(len, RARRAY_CONST_PTR(ary)+pos); + VALUE arg2 = rb_ary_new4(len, RARRAY_CONST_PTR_TRANSIENT(ary)+pos); rb_ary_splice(ary, pos, len, 0, 0); return arg2; } @@ -4198,7 +4316,7 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len) * * Removes and returns elements from +self+. * - * When the only argument is an Integer +n+, + * When the only argument is an \Integer +n+, * removes and returns the _nth_ element in +self+: * * a = [:foo, 'bar', 2] @@ -4215,7 +4333,7 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len) * * When the only arguments are Integers +start+ and +length+, * removes +length+ elements from +self+ beginning at offset +start+; - * returns the deleted objects in a new +Array+: + * returns the deleted objects in a new \Array: * * a = [:foo, 'bar', 2] * a.slice!(0, 2) # => [:foo, "bar"] @@ -4229,18 +4347,18 @@ ary_slice_bang_by_rb_ary_splice(VALUE ary, long pos, long len) * a # => [:foo] * * If <tt>start == a.size</tt> and +length+ is non-negative, - * returns a new empty +Array+. + * returns a new empty \Array. * * If +length+ is negative, returns +nil+. * - * When the only argument is a Range object +range+, + * When the only argument is a \Range object +range+, * treats <tt>range.min</tt> as +start+ above and <tt>range.size</tt> as +length+ above: * * a = [:foo, 'bar', 2] * a.slice!(1..2) # => ["bar", 2] * a # => [:foo] * - * If <tt>range.start == a.size</tt>, returns a new empty +Array+. + * If <tt>range.start == a.size</tt>, returns a new empty \Array. * * If <tt>range.start</tt> is larger than the array size, returns +nil+. * @@ -4349,7 +4467,7 @@ ary_reject_bang(VALUE ary) * * Returns +nil+ if no elements removed. * - * Returns a new Enumerator if no block given: + * Returns a new \Enumerator if no block given: * * a = [:foo, 'bar', 2] * a.reject! # => #<Enumerator: [:foo, "bar", 2]:reject!> @@ -4369,14 +4487,14 @@ rb_ary_reject_bang(VALUE ary) * array.reject {|element| ... } -> new_array * array.reject -> new_enumerator * - * Returns a new +Array+ whose elements are all those from +self+ + * Returns a new \Array whose elements are all those from +self+ * for which the block returns +false+ or +nil+: * * a = [:foo, 'bar', 2, 'bat'] * a1 = a.reject {|element| element.to_s.start_with?('b') } * a1 # => [:foo, 2] * - * Returns a new Enumerator if no block given: + * Returns a new \Enumerator if no block given: * * a = [:foo, 'bar', 2] * a.reject # => #<Enumerator: [:foo, "bar", 2]:reject> @@ -4396,20 +4514,21 @@ rb_ary_reject(VALUE ary) /* * call-seq: - * delete_if {|element| ... } -> self - * delete_if -> new_numerator + * array.delete_if {|element| ... } -> self + * array.delete_if -> Enumerator * - * With a block given, calls the block with each element of +self+; - * removes the element if the block returns a truthy value; + * Removes each element in +self+ for which the block returns a truthy value; * returns +self+: * * a = [:foo, 'bar', 2, 'bat'] * a.delete_if {|element| element.to_s.start_with?('b') } # => [:foo, 2] * - * With no block given, returns a new Enumerator. + * Returns a new \Enumerator if no block given: * - * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting]. - */ + * a = [:foo, 'bar', 2] + * a.delete_if # => #<Enumerator: [:foo, "bar", 2]:delete_if> + * +3 */ static VALUE rb_ary_delete_if(VALUE ary) @@ -4452,7 +4571,7 @@ take_items(VALUE obj, long n) * array.zip(*other_arrays) -> new_array * array.zip(*other_arrays) {|other_array| ... } -> nil * - * When no block given, returns a new +Array+ +new_array+ of size <tt>self.size</tt> + * When no block given, returns a new \Array +new_array+ of size <tt>self.size</tt> * whose elements are Arrays. * * Each nested array <tt>new_array[n]</tt> is of size <tt>other_arrays.size+1</tt>, @@ -4487,13 +4606,6 @@ take_items(VALUE obj, long n) * d = a.zip(b, c) * d # => [[:a0, :b0, :c0], [:a1, :b1, :c1], [:a2, :b2, :c2], [:a3, :b3, :c3]] * - * If an argument is not an array, it extracts the values by calling #each: - * - * a = [:a0, :a1, :a2, :a2] - * b = 1..4 - * c = a.zip(b) - * c # => [[:a0, 1], [:a1, 2], [:a2, 3], [:a2, 4]] - * * When a block is given, calls the block with each of the sub-arrays (formed as above); returns +nil+: * * a = [:a0, :a1, :a2, :a3] @@ -4572,7 +4684,7 @@ rb_ary_zip(int argc, VALUE *argv, VALUE ary) * call-seq: * array.transpose -> new_array * - * Transposes the rows and columns in an +Array+ of Arrays; + * Transposes the rows and columns in an \Array of Arrays; * the nested Arrays must all be the same size: * * a = [[:a0, :a1], [:b0, :b1], [:c0, :c1]] @@ -4610,17 +4722,13 @@ rb_ary_transpose(VALUE ary) /* * call-seq: - * initialize_copy(other_array) -> self - * replace(other_array) -> self + * array.replace(other_array) -> self * - * Replaces the elements of +self+ with the elements of +other_array+, which must be an - * {array-convertible object}[rdoc-ref:implicit_conversion.rdoc@Array-Convertible+Objects]; - * returns +self+: + * Replaces the content of +self+ with the content of +other_array+; returns +self+: * - * a = ['a', 'b', 'c'] # => ["a", "b", "c"] - * a.replace(['d', 'e']) # => ["d", "e"] + * a = [:foo, 'bar', 2] + * a.replace(['foo', :bar, 3]) # => ["foo", :bar, 3] * - * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning]. */ VALUE @@ -4634,15 +4742,16 @@ rb_ary_replace(VALUE copy, VALUE orig) /* orig has enough space to embed the contents of orig. */ if (RARRAY_LEN(orig) <= ary_embed_capa(copy)) { - RUBY_ASSERT(ARY_EMBED_P(copy)); - ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR(orig)); + assert(ARY_EMBED_P(copy)); + ary_memcpy(copy, 0, RARRAY_LEN(orig), RARRAY_CONST_PTR_TRANSIENT(orig)); ARY_SET_EMBED_LEN(copy, RARRAY_LEN(orig)); } +#if USE_RVARGC /* orig is embedded but copy does not have enough space to embed the * contents of orig. */ else if (ARY_EMBED_P(orig)) { long len = ARY_EMBED_LEN(orig); - VALUE *ptr = ary_heap_alloc_buffer(len); + VALUE *ptr = ary_heap_alloc(copy, len); FL_UNSET_EMBED(copy); ARY_SET_PTR(copy, ptr); @@ -4651,8 +4760,9 @@ rb_ary_replace(VALUE copy, VALUE orig) // No allocation and exception expected that could leave `copy` in a // bad state from the edits above. - ary_memcpy(copy, 0, len, RARRAY_CONST_PTR(orig)); + ary_memcpy(copy, 0, len, RARRAY_CONST_PTR_TRANSIENT(orig)); } +#endif /* Otherwise, orig is on heap and copy does not have enough space to embed * the contents of orig. */ else { @@ -4668,14 +4778,13 @@ rb_ary_replace(VALUE copy, VALUE orig) /* * call-seq: - * clear -> self + * array.clear -> self * - * Removes all elements from +self+; returns +self+: + * Removes all elements from +self+: * * a = [:foo, 'bar', 2] * a.clear # => [] * - * Related: see {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting]. */ VALUE @@ -4683,9 +4792,11 @@ rb_ary_clear(VALUE ary) { rb_ary_modify_check(ary); if (ARY_SHARED_P(ary)) { - rb_ary_unshare(ary); - FL_SET_EMBED(ary); - ARY_SET_EMBED_LEN(ary, 0); + if (!ARY_EMBED_P(ary)) { + rb_ary_unshare(ary); + FL_SET_EMBED(ary); + ARY_SET_EMBED_LEN(ary, 0); + } } else { ARY_SET_LEN(ary, 0); @@ -4699,182 +4810,198 @@ rb_ary_clear(VALUE ary) /* * call-seq: - * fill(object, start = nil, count = nil) -> new_array - * fill(object, range) -> new_array - * fill(start = nil, count = nil) {|element| ... } -> new_array - * fill(range) {|element| ... } -> new_array + * array.fill(obj) -> self + * array.fill(obj, start) -> self + * array.fill(obj, start, length) -> self + * array.fill(obj, range) -> self + * array.fill {|index| ... } -> self + * array.fill(start) {|index| ... } -> self + * array.fill(start, length) {|index| ... } -> self + * array.fill(range) {|index| ... } -> self + * + * Replaces specified elements in +self+ with specified objects; returns +self+. * - * Replaces selected elements in +self+; - * may add elements to +self+; - * always returns +self+ (never a new array). + * With argument +obj+ and no block given, replaces all elements with that one object: * - * In brief: + * a = ['a', 'b', 'c', 'd'] + * a # => ["a", "b", "c", "d"] + * a.fill(:X) # => [:X, :X, :X, :X] * - * # Non-negative start. - * ['a', 'b', 'c', 'd'].fill('-', 1, 2) # => ["a", "-", "-", "d"] - * ['a', 'b', 'c', 'd'].fill(1, 2) {|e| e.to_s } # => ["a", "1", "2", "d"] + * With arguments +obj+ and \Integer +start+, and no block given, + * replaces elements based on the given start. * - * # Extends with specified values if necessary. - * ['a', 'b', 'c', 'd'].fill('-', 3, 2) # => ["a", "b", "c", "-", "-"] - * ['a', 'b', 'c', 'd'].fill(3, 2) {|e| e.to_s } # => ["a", "b", "c", "3", "4"] + * If +start+ is in range (<tt>0 <= start < array.size</tt>), + * replaces all elements from offset +start+ through the end: * - * # Fills with nils if necessary. - * ['a', 'b', 'c', 'd'].fill('-', 6, 2) # => ["a", "b", "c", "d", nil, nil, "-", "-"] - * ['a', 'b', 'c', 'd'].fill(6, 2) {|e| e.to_s } # => ["a", "b", "c", "d", nil, nil, "6", "7"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, 2) # => ["a", "b", :X, :X] * - * # For negative start, counts backwards from the end. - * ['a', 'b', 'c', 'd'].fill('-', -3, 3) # => ["a", "-", "-", "-"] - * ['a', 'b', 'c', 'd'].fill(-3, 3) {|e| e.to_s } # => ["a", "1", "2", "3"] + * If +start+ is too large (<tt>start >= array.size</tt>), does nothing: * - * # Range. - * ['a', 'b', 'c', 'd'].fill('-', 1..2) # => ["a", "-", "-", "d"] - * ['a', 'b', 'c', 'd'].fill(1..2) {|e| e.to_s } # => ["a", "1", "2", "d"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, 4) # => ["a", "b", "c", "d"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, 5) # => ["a", "b", "c", "d"] * - * When arguments +start+ and +count+ are given, - * they select the elements of +self+ to be replaced; - * each must be an - * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects] - * (or +nil+): + * If +start+ is negative, counts from the end (starting index is <tt>start + array.size</tt>): * - * - +start+ specifies the zero-based offset of the first element to be replaced; - * +nil+ means zero. - * - +count+ is the number of consecutive elements to be replaced; - * +nil+ means "all the rest." + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, -2) # => ["a", "b", :X, :X] * - * With argument +object+ given, - * that one object is used for all replacements: + * If +start+ is too small (less than and far from zero), replaces all elements: * - * o = Object.new # => #<Object:0x0000014e7bff7600> - * a = ['a', 'b', 'c', 'd'] # => ["a", "b", "c", "d"] - * a.fill(o, 1, 2) - * # => ["a", #<Object:0x0000014e7bff7600>, #<Object:0x0000014e7bff7600>, "d"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, -6) # => [:X, :X, :X, :X] + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, -50) # => [:X, :X, :X, :X] * - * With a block given, the block is called once for each element to be replaced; - * the value passed to the block is the _index_ of the element to be replaced - * (not the element itself); - * the block's return value replaces the element: + * With arguments +obj+, \Integer +start+, and \Integer +length+, and no block given, + * replaces elements based on the given +start+ and +length+. * - * a = ['a', 'b', 'c', 'd'] # => ["a", "b", "c", "d"] - * a.fill(1, 2) {|element| element.to_s } # => ["a", "1", "2", "d"] + * If +start+ is in range, replaces +length+ elements beginning at offset +start+: * - * For arguments +start+ and +count+: + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, 1, 1) # => ["a", :X, "c", "d"] * - * - If +start+ is non-negative, - * replaces +count+ elements beginning at offset +start+: + * If +start+ is negative, counts from the end: * - * ['a', 'b', 'c', 'd'].fill('-', 0, 2) # => ["-", "-", "c", "d"] - * ['a', 'b', 'c', 'd'].fill('-', 1, 2) # => ["a", "-", "-", "d"] - * ['a', 'b', 'c', 'd'].fill('-', 2, 2) # => ["a", "b", "-", "-"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, -2, 1) # => ["a", "b", :X, "d"] * - * ['a', 'b', 'c', 'd'].fill(0, 2) {|e| e.to_s } # => ["0", "1", "c", "d"] - * ['a', 'b', 'c', 'd'].fill(1, 2) {|e| e.to_s } # => ["a", "1", "2", "d"] - * ['a', 'b', 'c', 'd'].fill(2, 2) {|e| e.to_s } # => ["a", "b", "2", "3"] + * If +start+ is large (<tt>start >= array.size</tt>), extends +self+ with +nil+: * - * Extends +self+ if necessary: + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, 5, 0) # => ["a", "b", "c", "d", nil] + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, 5, 2) # => ["a", "b", "c", "d", nil, :X, :X] * - * ['a', 'b', 'c', 'd'].fill('-', 3, 2) # => ["a", "b", "c", "-", "-"] - * ['a', 'b', 'c', 'd'].fill('-', 4, 2) # => ["a", "b", "c", "d", "-", "-"] + * If +length+ is zero or negative, replaces no elements: * - * ['a', 'b', 'c', 'd'].fill(3, 2) {|e| e.to_s } # => ["a", "b", "c", "3", "4"] - * ['a', 'b', 'c', 'd'].fill(4, 2) {|e| e.to_s } # => ["a", "b", "c", "d", "4", "5"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, 1, 0) # => ["a", "b", "c", "d"] + * a.fill(:X, 1, -1) # => ["a", "b", "c", "d"] * - * Fills with +nil+ if necessary: + * With arguments +obj+ and \Range +range+, and no block given, + * replaces elements based on the given range. * - * ['a', 'b', 'c', 'd'].fill('-', 5, 2) # => ["a", "b", "c", "d", nil, "-", "-"] - * ['a', 'b', 'c', 'd'].fill('-', 6, 2) # => ["a", "b", "c", "d", nil, nil, "-", "-"] + * If the range is positive and ascending (<tt>0 < range.begin <= range.end</tt>), + * replaces elements from <tt>range.begin</tt> to <tt>range.end</tt>: * - * ['a', 'b', 'c', 'd'].fill(5, 2) {|e| e.to_s } # => ["a", "b", "c", "d", nil, "5", "6"] - * ['a', 'b', 'c', 'd'].fill(6, 2) {|e| e.to_s } # => ["a", "b", "c", "d", nil, nil, "6", "7"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, (1..1)) # => ["a", :X, "c", "d"] * - * Does nothing if +count+ is non-positive: + * If <tt>range.first</tt> is negative, replaces no elements: * - * ['a', 'b', 'c', 'd'].fill('-', 2, 0) # => ["a", "b", "c", "d"] - * ['a', 'b', 'c', 'd'].fill('-', 2, -100) # => ["a", "b", "c", "d"] - * ['a', 'b', 'c', 'd'].fill('-', 6, -100) # => ["a", "b", "c", "d"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, (-1..1)) # => ["a", "b", "c", "d"] * - * ['a', 'b', 'c', 'd'].fill(2, 0) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"] - * ['a', 'b', 'c', 'd'].fill(2, -100) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"] - * ['a', 'b', 'c', 'd'].fill(6, -100) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"] + * If <tt>range.last</tt> is negative, counts from the end: * - * - If +start+ is negative, counts backwards from the end of +self+: + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, (0..-2)) # => [:X, :X, :X, "d"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, (1..-2)) # => ["a", :X, :X, "d"] * - * ['a', 'b', 'c', 'd'].fill('-', -4, 3) # => ["-", "-", "-", "d"] - * ['a', 'b', 'c', 'd'].fill('-', -3, 3) # => ["a", "-", "-", "-"] + * If <tt>range.last</tt> and <tt>range.last</tt> are both negative, + * both count from the end of the array: * - * ['a', 'b', 'c', 'd'].fill(-4, 3) {|e| e.to_s } # => ["0", "1", "2", "d"] - * ['a', 'b', 'c', 'd'].fill(-3, 3) {|e| e.to_s } # => ["a", "1", "2", "3"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, (-1..-1)) # => ["a", "b", "c", :X] + * a = ['a', 'b', 'c', 'd'] + * a.fill(:X, (-2..-2)) # => ["a", "b", :X, "d"] * - * Extends +self+ if necessary: + * With no arguments and a block given, calls the block with each index; + * replaces the corresponding element with the block's return value: * - * ['a', 'b', 'c', 'd'].fill('-', -2, 3) # => ["a", "b", "-", "-", "-"] - * ['a', 'b', 'c', 'd'].fill('-', -1, 3) # => ["a", "b", "c", "-", "-", "-"] + * a = ['a', 'b', 'c', 'd'] + * a.fill { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"] * - * ['a', 'b', 'c', 'd'].fill(-2, 3) {|e| e.to_s } # => ["a", "b", "2", "3", "4"] - * ['a', 'b', 'c', 'd'].fill(-1, 3) {|e| e.to_s } # => ["a", "b", "c", "3", "4", "5"] + * With argument +start+ and a block given, calls the block with each index + * from offset +start+ to the end; replaces the corresponding element + * with the block's return value. * - * Starts at the beginning of +self+ if +start+ is negative and out-of-range: + * If start is in range (<tt>0 <= start < array.size</tt>), + * replaces from offset +start+ to the end: * - * ['a', 'b', 'c', 'd'].fill('-', -5, 2) # => ["-", "-", "c", "d"] - * ['a', 'b', 'c', 'd'].fill('-', -6, 2) # => ["-", "-", "c", "d"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(1) { |index| "new_#{index}" } # => ["a", "new_1", "new_2", "new_3"] * - * ['a', 'b', 'c', 'd'].fill(-5, 2) {|e| e.to_s } # => ["0", "1", "c", "d"] - * ['a', 'b', 'c', 'd'].fill(-6, 2) {|e| e.to_s } # => ["0", "1", "c", "d"] + * If +start+ is too large(<tt>start >= array.size</tt>), does nothing: * - * Does nothing if +count+ is non-positive: + * a = ['a', 'b', 'c', 'd'] + * a.fill(4) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(4) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"] * - * ['a', 'b', 'c', 'd'].fill('-', -2, 0) # => ["a", "b", "c", "d"] - * ['a', 'b', 'c', 'd'].fill('-', -2, -1) # => ["a", "b", "c", "d"] + * If +start+ is negative, counts from the end: * - * ['a', 'b', 'c', 'd'].fill(-2, 0) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"] - * ['a', 'b', 'c', 'd'].fill(-2, -1) {|e| fail 'Cannot happen' } # => ["a", "b", "c", "d"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(-2) { |index| "new_#{index}" } # => ["a", "b", "new_2", "new_3"] * - * When argument +range+ is given, - * it must be a Range object whose members are numeric; - * its +begin+ and +end+ values determine the elements of +self+ - * to be replaced: + * If start is too small (<tt>start <= -array.size</tt>, replaces all elements: * - * - If both +begin+ and +end+ are positive, they specify the first and last elements - * to be replaced: + * a = ['a', 'b', 'c', 'd'] + * a.fill(-6) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(-50) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "new_3"] * - * ['a', 'b', 'c', 'd'].fill('-', 1..2) # => ["a", "-", "-", "d"] - * ['a', 'b', 'c', 'd'].fill(1..2) {|e| e.to_s } # => ["a", "1", "2", "d"] + * With arguments +start+ and +length+, and a block given, + * calls the block for each index specified by start length; + * replaces the corresponding element with the block's return value. * - * If +end+ is smaller than +begin+, replaces no elements: + * If +start+ is in range, replaces +length+ elements beginning at offset +start+: * - * ['a', 'b', 'c', 'd'].fill('-', 2..1) # => ["a", "b", "c", "d"] - * ['a', 'b', 'c', 'd'].fill(2..1) {|e| e.to_s } # => ["a", "b", "c", "d"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(1, 1) { |index| "new_#{index}" } # => ["a", "new_1", "c", "d"] * - * - If either is negative (or both are negative), counts backwards from the end of +self+: + * If start is negative, counts from the end: * - * ['a', 'b', 'c', 'd'].fill('-', -3..2) # => ["a", "-", "-", "d"] - * ['a', 'b', 'c', 'd'].fill('-', 1..-2) # => ["a", "-", "-", "d"] - * ['a', 'b', 'c', 'd'].fill('-', -3..-2) # => ["a", "-", "-", "d"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(-2, 1) { |index| "new_#{index}" } # => ["a", "b", "new_2", "d"] * - * ['a', 'b', 'c', 'd'].fill(-3..2) {|e| e.to_s } # => ["a", "1", "2", "d"] - * ['a', 'b', 'c', 'd'].fill(1..-2) {|e| e.to_s } # => ["a", "1", "2", "d"] - * ['a', 'b', 'c', 'd'].fill(-3..-2) {|e| e.to_s } # => ["a", "1", "2", "d"] + * If +start+ is large (<tt>start >= array.size</tt>), extends +self+ with +nil+: * - * - If the +end+ value is excluded (see Range#exclude_end?), omits the last replacement: + * a = ['a', 'b', 'c', 'd'] + * a.fill(5, 0) { |index| "new_#{index}" } # => ["a", "b", "c", "d", nil] + * a = ['a', 'b', 'c', 'd'] + * a.fill(5, 2) { |index| "new_#{index}" } # => ["a", "b", "c", "d", nil, "new_5", "new_6"] * - * ['a', 'b', 'c', 'd'].fill('-', 1...2) # => ["a", "-", "c", "d"] - * ['a', 'b', 'c', 'd'].fill('-', 1...-2) # => ["a", "-", "c", "d"] + * If +length+ is zero or less, replaces no elements: * - * ['a', 'b', 'c', 'd'].fill(1...2) {|e| e.to_s } # => ["a", "1", "c", "d"] - * ['a', 'b', 'c', 'd'].fill(1...-2) {|e| e.to_s } # => ["a", "1", "c", "d"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(1, 0) { |index| "new_#{index}" } # => ["a", "b", "c", "d"] + * a.fill(1, -1) { |index| "new_#{index}" } # => ["a", "b", "c", "d"] * - * - If the range is endless (see {Endless Ranges}[rdoc-ref:Range@Endless+Ranges]), - * replaces elements to the end of +self+: + * With arguments +obj+ and +range+, and a block given, + * calls the block with each index in the given range; + * replaces the corresponding element with the block's return value. * - * ['a', 'b', 'c', 'd'].fill('-', 1..) # => ["a", "-", "-", "-"] - * ['a', 'b', 'c', 'd'].fill(1..) {|e| e.to_s } # => ["a", "1", "2", "3"] + * If the range is positive and ascending (<tt>range 0 < range.begin <= range.end</tt>, + * replaces elements from <tt>range.begin</tt> to <tt>range.end</tt>: * - * - If the range is beginless (see {Beginless Ranges}[rdoc-ref:Range@Beginless+Ranges]), - * replaces elements from the beginning of +self+: + * a = ['a', 'b', 'c', 'd'] + * a.fill(1..1) { |index| "new_#{index}" } # => ["a", "new_1", "c", "d"] * - * ['a', 'b', 'c', 'd'].fill('-', ..2) # => ["-", "-", "-", "d"] - * ['a', 'b', 'c', 'd'].fill(..2) {|e| e.to_s } # => ["0", "1", "2", "d"] + * If +range.first+ is negative, does nothing: + * + * a = ['a', 'b', 'c', 'd'] + * a.fill(-1..1) { |index| fail 'Cannot happen' } # => ["a", "b", "c", "d"] + * + * If <tt>range.last</tt> is negative, counts from the end: + * + * a = ['a', 'b', 'c', 'd'] + * a.fill(0..-2) { |index| "new_#{index}" } # => ["new_0", "new_1", "new_2", "d"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(1..-2) { |index| "new_#{index}" } # => ["a", "new_1", "new_2", "d"] + * + * If <tt>range.first</tt> and <tt>range.last</tt> are both negative, + * both count from the end: + * + * a = ['a', 'b', 'c', 'd'] + * a.fill(-1..-1) { |index| "new_#{index}" } # => ["a", "b", "c", "new_3"] + * a = ['a', 'b', 'c', 'd'] + * a.fill(-2..-2) { |index| "new_#{index}" } # => ["a", "b", "new_2", "d"] * - * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning]. */ static VALUE @@ -4943,15 +5070,15 @@ rb_ary_fill(int argc, VALUE *argv, VALUE ary) /* * call-seq: - * self + other_array -> new_array + * array + other_array -> new_array * - * Returns a new array containing all elements of +self+ + * Returns a new \Array containing all elements of +array+ * followed by all elements of +other_array+: * * a = [0, 1] + [2, 3] * a # => [0, 1, 2, 3] * - * Related: see {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining]. + * Related: #concat. */ VALUE @@ -4966,8 +5093,8 @@ rb_ary_plus(VALUE x, VALUE y) len = xlen + ylen; z = rb_ary_new2(len); - ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR(x)); - ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR(y)); + ary_memcpy(z, 0, xlen, RARRAY_CONST_PTR_TRANSIENT(x)); + ary_memcpy(z, xlen, ylen, RARRAY_CONST_PTR_TRANSIENT(y)); ARY_SET_LEN(z, len); return z; } @@ -4977,7 +5104,7 @@ ary_append(VALUE x, VALUE y) { long n = RARRAY_LEN(y); if (n > 0) { - rb_ary_splice(x, RARRAY_LEN(x), 0, RARRAY_CONST_PTR(y), n); + rb_ary_splice(x, RARRAY_LEN(x), 0, RARRAY_CONST_PTR_TRANSIENT(y), n); } RB_GC_GUARD(y); return x; @@ -4985,15 +5112,12 @@ ary_append(VALUE x, VALUE y) /* * call-seq: - * concat(*other_arrays) -> self + * array.concat(*other_arrays) -> self * - * Adds to +self+ all elements from each array in +other_arrays+; returns +self+: + * Adds to +array+ all elements from each \Array in +other_arrays+; returns +self+: * * a = [0, 1] - * a.concat(['two', 'three'], [:four, :five], a) - * # => [0, 1, "two", "three", :four, :five, 0, 1] - * - * Related: see {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning]. + * a.concat([2, 3], [4, 5]) # => [0, 1, 2, 3, 4, 5] */ static VALUE @@ -5025,17 +5149,17 @@ rb_ary_concat(VALUE x, VALUE y) /* * call-seq: - * self * n -> new_array - * self * string_separator -> new_string + * array * n -> new_array + * array * string_separator -> new_string * - * When non-negative integer argument +n+ is given, - * returns a new array built by concatenating +n+ copies of +self+: + * When non-negative argument \Integer +n+ is given, + * returns a new \Array built by concatenating the +n+ copies of +self+: * * a = ['x', 'y'] * a * 3 # => ["x", "y", "x", "y", "x", "y"] * - * When string argument +string_separator+ is given, - * equivalent to <tt>self.join(string_separator)</tt>: + * When \String argument +string_separator+ is given, + * equivalent to <tt>array.join(string_separator)</tt>: * * [0, [0, 1], {foo: 0}] * ', ' # => "0, 0, 1, {:foo=>0}" * @@ -5069,16 +5193,16 @@ rb_ary_times(VALUE ary, VALUE times) ary2 = ary_new(rb_cArray, len); ARY_SET_LEN(ary2, len); - ptr = RARRAY_CONST_PTR(ary); + ptr = RARRAY_CONST_PTR_TRANSIENT(ary); t = RARRAY_LEN(ary); if (0 < t) { ary_memcpy(ary2, 0, t, ptr); while (t <= len/2) { - ary_memcpy(ary2, t, t, RARRAY_CONST_PTR(ary2)); + ary_memcpy(ary2, t, t, RARRAY_CONST_PTR_TRANSIENT(ary2)); t *= 2; } if (t < len) { - ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR(ary2)); + ary_memcpy(ary2, t, len-t, RARRAY_CONST_PTR_TRANSIENT(ary2)); } } out: @@ -5087,18 +5211,17 @@ rb_ary_times(VALUE ary, VALUE times) /* * call-seq: - * assoc(object) -> found_array or nil + * array.assoc(obj) -> found_array or nil * - * Returns the first element +ele+ in +self+ such that +ele+ is an array - * and <tt>ele[0] == object</tt>: + * Returns the first element in +self+ that is an \Array + * whose first element <tt>==</tt> +obj+: * * a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]] * a.assoc(4) # => [4, 5, 6] * * Returns +nil+ if no such element is found. * - * Related: Array#rassoc; - * see also {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. + * Related: #rassoc. */ VALUE @@ -5120,7 +5243,7 @@ rb_ary_assoc(VALUE ary, VALUE key) * call-seq: * array.rassoc(obj) -> found_array or nil * - * Returns the first element in +self+ that is an +Array+ + * Returns the first element in +self+ that is an \Array * whose second element <tt>==</tt> +obj+: * * a = [{foo: 0}, [2, 4], [4, 5, 6], [4, 5]] @@ -5138,7 +5261,7 @@ rb_ary_rassoc(VALUE ary, VALUE value) VALUE v; for (i = 0; i < RARRAY_LEN(ary); ++i) { - v = rb_check_array_type(RARRAY_AREF(ary, i)); + v = RARRAY_AREF(ary, i); if (RB_TYPE_P(v, T_ARRAY) && RARRAY_LEN(v) > 1 && rb_equal(RARRAY_AREF(v, 1), value)) @@ -5183,26 +5306,20 @@ recursive_equal(VALUE ary1, VALUE ary2, int recur) /* * call-seq: - * self == other_array -> true or false - * - * Returns whether both: + * array == other_array -> true or false * - * - +self+ and +other_array+ are the same size. - * - Their corresponding elements are the same; - * that is, for each index +i+ in <tt>(0...self.size)</tt>, - * <tt>self[i] == other_array[i]</tt>. + * Returns +true+ if both <tt>array.size == other_array.size</tt> + * and for each index +i+ in +array+, <tt>array[i] == other_array[i]</tt>: * - * Examples: + * a0 = [:foo, 'bar', 2] + * a1 = [:foo, 'bar', 2.0] + * a1 == a0 # => true + * [] == [] # => true * - * [:foo, 'bar', 2] == [:foo, 'bar', 2] # => true - * [:foo, 'bar', 2] == [:foo, 'bar', 2.0] # => true - * [:foo, 'bar', 2] == [:foo, 'bar'] # => false # Different sizes. - * [:foo, 'bar', 2] == [:foo, 'bar', 3] # => false # Different elements. + * Otherwise, returns +false+. * * This method is different from method Array#eql?, * which compares elements using <tt>Object#eql?</tt>. - * - * Related: see {Methods for Comparing}[rdoc-ref:Array@Methods+for+Comparing]. */ static VALUE @@ -5216,7 +5333,7 @@ rb_ary_equal(VALUE ary1, VALUE ary2) return rb_equal(ary2, ary1); } if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse; - if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue; + if (RARRAY_CONST_PTR_TRANSIENT(ary1) == RARRAY_CONST_PTR_TRANSIENT(ary2)) return Qtrue; return rb_exec_recursive_paired(recursive_equal, ary1, ary2, ary2); } @@ -5235,10 +5352,10 @@ recursive_eql(VALUE ary1, VALUE ary2, int recur) /* * call-seq: - * eql?(other_array) -> true or false + * array.eql? other_array -> true or false * * Returns +true+ if +self+ and +other_array+ are the same size, - * and if, for each index +i+ in +self+, <tt>self[i].eql?(other_array[i])</tt>: + * and if, for each index +i+ in +self+, <tt>self[i].eql? other_array[i]</tt>: * * a0 = [:foo, 'bar', 2] * a1 = [:foo, 'bar', 2] @@ -5248,8 +5365,6 @@ recursive_eql(VALUE ary1, VALUE ary2, int recur) * * This method is different from method Array#==, * which compares using method <tt>Object#==</tt>. - * - * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying]. */ static VALUE @@ -5258,60 +5373,49 @@ rb_ary_eql(VALUE ary1, VALUE ary2) if (ary1 == ary2) return Qtrue; if (!RB_TYPE_P(ary2, T_ARRAY)) return Qfalse; if (RARRAY_LEN(ary1) != RARRAY_LEN(ary2)) return Qfalse; - if (RARRAY_CONST_PTR(ary1) == RARRAY_CONST_PTR(ary2)) return Qtrue; + if (RARRAY_CONST_PTR_TRANSIENT(ary1) == RARRAY_CONST_PTR_TRANSIENT(ary2)) return Qtrue; return rb_exec_recursive_paired(recursive_eql, ary1, ary2, ary2); } -VALUE -rb_ary_hash_values(long len, const VALUE *elements) -{ - long i; - st_index_t h; - VALUE n; - - h = rb_hash_start(len); - h = rb_hash_uint(h, (st_index_t)rb_ary_hash_values); - for (i=0; i<len; i++) { - n = rb_hash(elements[i]); - h = rb_hash_uint(h, NUM2LONG(n)); - } - h = rb_hash_end(h); - return ST2FIX(h); -} - /* * call-seq: - * hash -> integer + * array.hash -> integer * * Returns the integer hash value for +self+. * - * Two arrays with the same content will have the same hash value - * (and will compare using eql?): + * Two arrays with the same content will have the same hash code (and will compare using eql?): * - * ['a', 'b'].hash == ['a', 'b'].hash # => true - * ['a', 'b'].hash == ['a', 'c'].hash # => false - * ['a', 'b'].hash == ['a'].hash # => false + * [0, 1, 2].hash == [0, 1, 2].hash # => true + * [0, 1, 2].hash == [0, 1, 3].hash # => false * */ static VALUE rb_ary_hash(VALUE ary) { - return rb_ary_hash_values(RARRAY_LEN(ary), RARRAY_CONST_PTR(ary)); + long i; + st_index_t h; + VALUE n; + + h = rb_hash_start(RARRAY_LEN(ary)); + h = rb_hash_uint(h, (st_index_t)rb_ary_hash); + for (i=0; i<RARRAY_LEN(ary); i++) { + n = rb_hash(RARRAY_AREF(ary, i)); + h = rb_hash_uint(h, NUM2LONG(n)); + } + h = rb_hash_end(h); + return ST2FIX(h); } /* * call-seq: - * include?(object) -> true or false + * array.include?(obj) -> true or false * - * Returns whether for some element +element+ in +self+, - * <tt>object == element</tt>: + * Returns +true+ if for some index +i+ in +self+, <tt>obj == self[i]</tt>; + * otherwise +false+: * - * [0, 1, 2].include?(2) # => true - * [0, 1, 2].include?(2.0) # => true - * [0, 1, 2].include?(2.1) # => false - * - * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying]. + * [0, 1, 2].include?(2) # => true + * [0, 1, 2].include?(3) # => false */ VALUE @@ -5366,40 +5470,33 @@ recursive_cmp(VALUE ary1, VALUE ary2, int recur) /* * call-seq: - * self <=> other_array -> -1, 0, or 1 + * array <=> other_array -> -1, 0, or 1 + * + * Returns -1, 0, or 1 as +self+ is less than, equal to, or greater than +other_array+. + * For each index +i+ in +self+, evaluates <tt>result = self[i] <=> other_array[i]</tt>. * - * Returns -1, 0, or 1 as +self+ is determined - * to be less than, equal to, or greater than +other_array+. + * Returns -1 if any result is -1: * - * Iterates over each index +i+ in <tt>(0...self.size)</tt>: + * [0, 1, 2] <=> [0, 1, 3] # => -1 * - * - Computes <tt>result[i]</tt> as <tt>self[i] <=> other_array[i]</tt>. - * - Immediately returns 1 if <tt>result[i]</tt> is 1: + * Returns 1 if any result is 1: * - * [0, 1, 2] <=> [0, 0, 2] # => 1 + * [0, 1, 2] <=> [0, 1, 1] # => 1 * - * - Immediately returns -1 if <tt>result[i]</tt> is -1: + * When all results are zero: * - * [0, 1, 2] <=> [0, 2, 2] # => -1 + * - Returns -1 if +array+ is smaller than +other_array+: * - * - Continues if <tt>result[i]</tt> is 0. + * [0, 1, 2] <=> [0, 1, 2, 3] # => -1 * - * When every +result+ is 0, - * returns <tt>self.size <=> other_array.size</tt> - * (see Integer#<=>): + * - Returns 1 if +array+ is larger than +other_array+: * - * [0, 1, 2] <=> [0, 1] # => 1 - * [0, 1, 2] <=> [0, 1, 2] # => 0 - * [0, 1, 2] <=> [0, 1, 2, 3] # => -1 + * [0, 1, 2] <=> [0, 1] # => 1 * - * Note that when +other_array+ is larger than +self+, - * its trailing elements do not affect the result: + * - Returns 0 if +array+ and +other_array+ are the same size: * - * [0, 1, 2] <=> [0, 1, 2, -3] # => -1 - * [0, 1, 2] <=> [0, 1, 2, 0] # => -1 - * [0, 1, 2] <=> [0, 1, 2, 3] # => -1 + * [0, 1, 2] <=> [0, 1, 2] # => 0 * - * Related: see {Methods for Comparing}[rdoc-ref:Array@Methods+for+Comparing]. */ VALUE @@ -5467,22 +5564,31 @@ ary_make_hash_by(VALUE ary) return ary_add_hash_by(hash, ary); } +static inline void +ary_recycle_hash(VALUE hash) +{ + assert(RBASIC_CLASS(hash) == 0); + if (RHASH_ST_TABLE_P(hash)) { + st_table *tbl = RHASH_ST_TABLE(hash); + st_free_table(tbl); + RHASH_ST_CLEAR(hash); + } +} + /* * call-seq: - * self - other_array -> new_array + * array - other_array -> new_array * - * Returns a new array containing only those elements of +self+ - * that are not found in +other_array+; - * the order from +self+ is preserved: + * Returns a new \Array containing only those elements from +array+ + * that are not found in \Array +other_array+; + * items are compared using <tt>eql?</tt>; + * the order from +array+ is preserved: * - * [0, 1, 1, 2, 1, 1, 3, 1, 1] - [1] # => [0, 2, 3] - * [0, 1, 1, 2, 1, 1, 3, 1, 1] - [3, 2, 0, :foo] # => [1, 1, 1, 1, 1, 1] - * [0, 1, 2] - [:foo] # => [0, 1, 2] + * [0, 1, 1, 2, 1, 1, 3, 1, 1] - [1] # => [0, 2, 3] + * [0, 1, 2, 3] - [3, 0] # => [1, 2] + * [0, 1, 2] - [4] # => [0, 1, 2] * - * Element are compared using method <tt>#eql?</tt> - * (as defined in each element of +self+). - * - * Related: see {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining]. + * Related: Array#difference. */ VALUE @@ -5510,27 +5616,25 @@ rb_ary_diff(VALUE ary1, VALUE ary2) if (rb_hash_stlike_lookup(hash, RARRAY_AREF(ary1, i), NULL)) continue; rb_ary_push(ary3, rb_ary_elt(ary1, i)); } - + ary_recycle_hash(hash); return ary3; } /* * call-seq: - * difference(*other_arrays = []) -> new_array + * array.difference(*other_arrays) -> new_array * - * Returns a new array containing only those elements from +self+ - * that are not found in any of the given +other_arrays+; + * Returns a new \Array containing only those elements from +self+ + * that are not found in any of the Arrays +other_arrays+; * items are compared using <tt>eql?</tt>; order from +self+ is preserved: * * [0, 1, 1, 2, 1, 1, 3, 1, 1].difference([1]) # => [0, 2, 3] - * [0, 1, 2, 3].difference([3, 0], [1, 3]) # => [2] - * [0, 1, 2].difference([4]) # => [0, 1, 2] - * [0, 1, 2].difference # => [0, 1, 2] + * [0, 1, 2, 3].difference([3, 0], [1, 3]) # => [2] + * [0, 1, 2].difference([4]) # => [0, 1, 2] * - * Returns a copy of +self+ if no arguments are given. + * Returns a copy of +self+ if no arguments given. * - * Related: Array#-; - * see also {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining]. + * Related: Array#-. */ static VALUE @@ -5572,25 +5676,19 @@ rb_ary_difference_multi(int argc, VALUE *argv, VALUE ary) /* * call-seq: - * self & other_array -> new_array + * array & other_array -> new_array * - * Returns a new array containing the _intersection_ of +self+ and +other_array+; - * that is, containing those elements found in both +self+ and +other_array+: + * Returns a new \Array containing each element found in both +array+ and \Array +other_array+; + * duplicates are omitted; items are compared using <tt>eql?</tt>: * * [0, 1, 2, 3] & [1, 2] # => [1, 2] + * [0, 1, 0, 1] & [0, 1] # => [0, 1] * - * Omits duplicates: - * - * [0, 1, 1, 0] & [0, 1] # => [0, 1] - * - * Preserves order from +self+: + * Preserves order from +array+: * * [0, 1, 2] & [3, 2, 1, 0] # => [0, 1, 2] * - * Identifies common elements using method <tt>#eql?</tt> - * (as defined in each element of +self+). - * - * Related: see {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining]. + * Related: Array#intersection. */ @@ -5624,29 +5722,29 @@ rb_ary_and(VALUE ary1, VALUE ary2) rb_ary_push(ary3, v); } } + ary_recycle_hash(hash); return ary3; } /* * call-seq: - * intersection(*other_arrays) -> new_array + * array.intersection(*other_arrays) -> new_array * - * Returns a new array containing each element in +self+ that is +#eql?+ - * to at least one element in each of the given +other_arrays+; - * duplicates are omitted: + * Returns a new \Array containing each element found both in +self+ + * and in all of the given Arrays +other_arrays+; + * duplicates are omitted; items are compared using <tt>eql?</tt>: * + * [0, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1] * [0, 0, 1, 1, 2, 3].intersection([0, 1, 2], [0, 1, 3]) # => [0, 1] * - * Each element must correctly implement method <tt>#hash</tt>. - * - * Order from +self+ is preserved: + * Preserves order from +self+: * * [0, 1, 2].intersection([2, 1, 0]) # => [0, 1, 2] * - * Returns a copy of +self+ if no arguments are given. + * Returns a copy of +self+ if no arguments given. * - * Related: see {Methods for Combining}[rdoc-ref:Array@Methods+for+Combining]. + * Related: Array#&. */ static VALUE @@ -5697,7 +5795,7 @@ rb_ary_union_hash(VALUE hash, VALUE ary2) * call-seq: * array | other_array -> new_array * - * Returns the union of +array+ and +Array+ +other_array+; + * Returns the union of +array+ and \Array +other_array+; * duplicates are removed; order is preserved; * items are compared using <tt>eql?</tt>: * @@ -5711,11 +5809,11 @@ rb_ary_union_hash(VALUE hash, VALUE ary2) static VALUE rb_ary_or(VALUE ary1, VALUE ary2) { - VALUE hash; + VALUE hash, ary3; ary2 = to_ary(ary2); if (RARRAY_LEN(ary1) + RARRAY_LEN(ary2) <= SMALL_ARRAY_LEN) { - VALUE ary3 = rb_ary_new(); + ary3 = rb_ary_new(); rb_ary_union(ary3, ary1); rb_ary_union(ary3, ary2); return ary3; @@ -5724,14 +5822,16 @@ rb_ary_or(VALUE ary1, VALUE ary2) hash = ary_make_hash(ary1); rb_ary_union_hash(hash, ary2); - return rb_hash_values(hash); + ary3 = rb_hash_values(hash); + ary_recycle_hash(hash); + return ary3; } /* * call-seq: * array.union(*other_arrays) -> new_array * - * Returns a new +Array+ that is the union of +self+ and all given Arrays +other_arrays+; + * Returns a new \Array that is the union of +self+ and all given Arrays +other_arrays+; * duplicates are removed; order is preserved; items are compared using <tt>eql?</tt>: * * [0, 1, 2, 3].union([4, 5], [6, 7]) # => [0, 1, 2, 3, 4, 5, 6, 7] @@ -5748,7 +5848,7 @@ rb_ary_union_multi(int argc, VALUE *argv, VALUE ary) { int i; long sum; - VALUE hash; + VALUE hash, ary_union; sum = RARRAY_LEN(ary); for (i = 0; i < argc; i++) { @@ -5757,7 +5857,7 @@ rb_ary_union_multi(int argc, VALUE *argv, VALUE ary) } if (sum <= SMALL_ARRAY_LEN) { - VALUE ary_union = rb_ary_new(); + ary_union = rb_ary_new(); rb_ary_union(ary_union, ary); for (i = 0; i < argc; i++) rb_ary_union(ary_union, argv[i]); @@ -5768,21 +5868,24 @@ rb_ary_union_multi(int argc, VALUE *argv, VALUE ary) hash = ary_make_hash(ary); for (i = 0; i < argc; i++) rb_ary_union_hash(hash, argv[i]); - return rb_hash_values(hash); + ary_union = rb_hash_values(hash); + ary_recycle_hash(hash); + return ary_union; } /* * call-seq: - * intersect?(other_array) -> true or false - * - * Returns whether +other_array+ has at least one element that is +#eql?+ to some element of +self+: + * ary.intersect?(other_ary) -> true or false * - * [1, 2, 3].intersect?([3, 4, 5]) # => true - * [1, 2, 3].intersect?([4, 5, 6]) # => false + * Returns +true+ if the array and +other_ary+ have at least one element in + * common, otherwise returns +false+: * - * Each element must correctly implement method <tt>#hash</tt>. + * a = [ 1, 2, 3 ] + * b = [ 3, 4, 5 ] + * c = [ 5, 6, 7 ] + * a.intersect?(b) #=> true + * a.intersect?(c) #=> false * - * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying]. */ static VALUE @@ -5821,6 +5924,7 @@ rb_ary_intersect_p(VALUE ary1, VALUE ary2) break; } } + ary_recycle_hash(hash); return result; } @@ -5916,51 +6020,42 @@ ary_max_opt_string(VALUE ary, long i, VALUE vmax) /* * call-seq: - * max -> element - * max(n) -> new_array - * max {|a, b| ... } -> element - * max(n) {|a, b| ... } -> new_array + * array.max -> element + * array.max {|a, b| ... } -> element + * array.max(n) -> new_array + * array.max(n) {|a, b| ... } -> new_array * * Returns one of the following: * * - The maximum-valued element from +self+. - * - A new array of maximum-valued elements from +self+. + * - A new \Array of maximum-valued elements selected from +self+. * - * Does not modify +self+. - * - * With no block given, each element in +self+ must respond to method <tt>#<=></tt> - * with a numeric. + * When no block is given, each element in +self+ must respond to method <tt><=></tt> + * with an \Integer. * * With no argument and no block, returns the element in +self+ - * having the maximum value per method <tt>#<=></tt>: + * having the maximum value per method <tt><=></tt>: * - * [1, 0, 3, 2].max # => 3 + * [0, 1, 2].max # => 2 * - * With non-negative numeric argument +n+ and no block, - * returns a new array with at most +n+ elements, - * in descending order, per method <tt>#<=></tt>: + * With an argument \Integer +n+ and no block, returns a new \Array with at most +n+ elements, + * in descending order per method <tt><=></tt>: * - * [1, 0, 3, 2].max(3) # => [3, 2, 1] - * [1, 0, 3, 2].max(3.0) # => [3, 2, 1] - * [1, 0, 3, 2].max(9) # => [3, 2, 1, 0] - * [1, 0, 3, 2].max(0) # => [] + * [0, 1, 2, 3].max(3) # => [3, 2, 1] + * [0, 1, 2, 3].max(6) # => [3, 2, 1, 0] * - * With a block given, the block must return a numeric. + * When a block is given, the block must return an \Integer. * - * With a block and no argument, calls the block <tt>self.size - 1</tt> times to compare elements; + * With a block and no argument, calls the block <tt>self.size-1</tt> times to compare elements; * returns the element having the maximum value per the block: * - * ['0', '', '000', '00'].max {|a, b| a.size <=> b.size } - * # => "000" + * ['0', '00', '000'].max {|a, b| a.size <=> b.size } # => "000" * - * With non-negative numeric argument +n+ and a block, - * returns a new array with at most +n+ elements, - * in descending order, per the block: + * With an argument +n+ and a block, returns a new \Array with at most +n+ elements, + * in descending order per the block: * - * ['0', '', '000', '00'].max(2) {|a, b| a.size <=> b.size } - * # => ["000", "00"] + * ['0', '00', '000'].max(2) {|a, b| a.size <=> b.size } # => ["000", "00"] * - * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. */ static VALUE rb_ary_max(int argc, VALUE *argv, VALUE ary) @@ -6093,51 +6188,42 @@ ary_min_opt_string(VALUE ary, long i, VALUE vmin) /* * call-seq: - * min -> element - * min(n) -> new_array - * min {|a, b| ... } -> element - * min(n) {|a, b| ... } -> new_array + * array.min -> element + * array.min { |a, b| ... } -> element + * array.min(n) -> new_array + * array.min(n) { |a, b| ... } -> new_array * * Returns one of the following: * * - The minimum-valued element from +self+. - * - A new array of minimum-valued elements from +self+. - * - * Does not modify +self+. + * - A new \Array of minimum-valued elements selected from +self+. * - * With no block given, each element in +self+ must respond to method <tt>#<=></tt> - * with a numeric. + * When no block is given, each element in +self+ must respond to method <tt><=></tt> + * with an \Integer. * * With no argument and no block, returns the element in +self+ - * having the minimum value per method <tt>#<=></tt>: + * having the minimum value per method <tt><=></tt>: * - * [1, 0, 3, 2].min # => 0 + * [0, 1, 2].min # => 0 * - * With non-negative numeric argument +n+ and no block, - * returns a new array with at most +n+ elements, - * in ascending order, per method <tt>#<=></tt>: + * With \Integer argument +n+ and no block, returns a new \Array with at most +n+ elements, + * in ascending order per method <tt><=></tt>: * - * [1, 0, 3, 2].min(3) # => [0, 1, 2] - * [1, 0, 3, 2].min(3.0) # => [0, 1, 2] - * [1, 0, 3, 2].min(9) # => [0, 1, 2, 3] - * [1, 0, 3, 2].min(0) # => [] + * [0, 1, 2, 3].min(3) # => [0, 1, 2] + * [0, 1, 2, 3].min(6) # => [0, 1, 2, 3] * - * With a block given, the block must return a numeric. + * When a block is given, the block must return an Integer. * - * With a block and no argument, calls the block <tt>self.size - 1</tt> times to compare elements; + * With a block and no argument, calls the block <tt>self.size-1</tt> times to compare elements; * returns the element having the minimum value per the block: * - * ['0', '', '000', '00'].min {|a, b| a.size <=> b.size } - * # => "" + * ['0', '00', '000'].min { |a, b| a.size <=> b.size } # => "0" * - * With non-negative numeric argument +n+ and a block, - * returns a new array with at most +n+ elements, - * in ascending order, per the block: + * With an argument +n+ and a block, returns a new \Array with at most +n+ elements, + * in ascending order per the block: * - * ['0', '', '000', '00'].min(2) {|a, b| a.size <=> b.size } - * # => ["", "0"] + * ['0', '00', '000'].min(2) {|a, b| a.size <=> b.size } # => ["0", "00"] * - * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. */ static VALUE rb_ary_min(int argc, VALUE *argv, VALUE ary) @@ -6181,25 +6267,26 @@ rb_ary_min(int argc, VALUE *argv, VALUE ary) /* * call-seq: - * minmax -> array - * minmax {|a, b| ... } -> array + * array.minmax -> [min_val, max_val] + * array.minmax {|a, b| ... } -> [min_val, max_val] * - * Returns a 2-element array containing the minimum-valued and maximum-valued - * elements from +self+; - * does not modify +self+. + * Returns a new 2-element \Array containing the minimum and maximum values + * from +self+, either per method <tt><=></tt> or per a given block:. * - * With no block given, the minimum and maximum values are determined using method <tt>#<=></tt>: + * When no block is given, each element in +self+ must respond to method <tt><=></tt> + * with an \Integer; + * returns a new 2-element \Array containing the minimum and maximum values + * from +self+, per method <tt><=></tt>: * - * [1, 0, 3, 2].minmax # => [0, 3] + * [0, 1, 2].minmax # => [0, 2] * - * With a block given, the block must return a numeric; - * the block is called <tt>self.size - 1</tt> times to compare elements; - * returns the elements having the minimum and maximum values per the block: + * When a block is given, the block must return an \Integer; + * the block is called <tt>self.size-1</tt> times to compare elements; + * returns a new 2-element \Array containing the minimum and maximum values + * from +self+, per the block: * - * ['0', '', '000', '00'].minmax {|a, b| a.size <=> b.size } - * # => ["", "000"] + * ['0', '00', '000'].minmax {|a, b| a.size <=> b.size } # => ["0", "000"] * - * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. */ static VALUE rb_ary_minmax(VALUE ary) @@ -6266,12 +6353,13 @@ rb_ary_uniq_bang(VALUE ary) } rb_ary_modify_check(ary); ARY_SET_LEN(ary, 0); - if (ARY_SHARED_P(ary)) { + if (ARY_SHARED_P(ary) && !ARY_EMBED_P(ary)) { rb_ary_unshare(ary); FL_SET_EMBED(ary); } ary_resize_capa(ary, hash_size); rb_hash_foreach(hash, push_value, ary); + ary_recycle_hash(hash); return ary; } @@ -6281,7 +6369,7 @@ rb_ary_uniq_bang(VALUE ary) * array.uniq -> new_array * array.uniq {|element| ... } -> new_array * - * Returns a new +Array+ containing those elements from +self+ that are not duplicates, + * Returns a new \Array containing those elements from +self+ that are not duplicates, * the first occurrence always being retained. * * With no block given, identifies and omits duplicates using method <tt>eql?</tt> @@ -6316,24 +6404,20 @@ rb_ary_uniq(VALUE ary) hash = ary_make_hash(ary); uniq = rb_hash_values(hash); } + if (hash) { + ary_recycle_hash(hash); + } return uniq; } /* * call-seq: - * compact! -> self or nil + * array.compact! -> self or nil * - * Removes all +nil+ elements from +self+; - * Returns +self+ if any elements are removed, +nil+ otherwise: + * Removes all +nil+ elements from +self+. * - * a = [nil, 0, nil, false, nil, '', nil, [], nil, {}] - * a.compact! # => [0, false, "", [], {}] - * a # => [0, false, "", [], {}] - * a.compact! # => nil - * - * Related: Array#compact; - * see also {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting]. + * Returns +self+ if any elements removed, otherwise +nil+. */ static VALUE @@ -6343,14 +6427,14 @@ rb_ary_compact_bang(VALUE ary) long n; rb_ary_modify(ary); - p = t = (VALUE *)RARRAY_CONST_PTR(ary); /* WB: no new reference */ + p = t = (VALUE *)RARRAY_CONST_PTR_TRANSIENT(ary); /* WB: no new reference */ end = p + RARRAY_LEN(ary); while (t < end) { if (NIL_P(*t)) t++; else *p++ = *t++; } - n = p - RARRAY_CONST_PTR(ary); + n = p - RARRAY_CONST_PTR_TRANSIENT(ary); if (RARRAY_LEN(ary) == n) { return Qnil; } @@ -6361,16 +6445,12 @@ rb_ary_compact_bang(VALUE ary) /* * call-seq: - * compact -> new_array - * - * Returns a new array containing only the non-+nil+ elements from +self+; - * element order is preserved: + * array.compact -> new_array * - * a = [nil, 0, nil, false, nil, '', nil, [], nil, {}] - * a.compact # => [0, false, "", [], {}] + * Returns a new \Array containing all non-+nil+ elements from +self+: * - * Related: Array#compact!; - * see also {Methods for Deleting}[rdoc-ref:Array@Methods+for+Deleting]. + * a = [nil, 0, nil, 1, nil, 2, nil] + * a.compact # => [0, 1, 2] */ static VALUE @@ -6383,29 +6463,29 @@ rb_ary_compact(VALUE ary) /* * call-seq: - * count -> integer - * count(object) -> integer - * count {|element| ... } -> integer + * array.count -> an_integer + * array.count(obj) -> an_integer + * array.count {|element| ... } -> an_integer * * Returns a count of specified elements. * * With no argument and no block, returns the count of all elements: * - * [0, :one, 'two', 3, 3.0].count # => 5 + * [0, 1, 2].count # => 3 + * [].count # => 0 * - * With argument +object+ given, returns the count of elements <tt>==</tt> to +object+: + * With argument +obj+, returns the count of elements <tt>==</tt> to +obj+: * - * [0, :one, 'two', 3, 3.0].count(3) # => 2 + * [0, 1, 2, 0.0].count(0) # => 2 + * [0, 1, 2].count(3) # => 0 * * With no argument and a block given, calls the block with each element; * returns the count of elements for which the block returns a truthy value: * - * [0, 1, 2, 3].count {|element| element > 1 } # => 2 + * [0, 1, 2, 3].count {|element| element > 1} # => 2 * - * With argument +object+ and a block given, issues a warning, ignores the block, - * and returns the count of elements <tt>==</tt> to +object+. - * - * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying]. + * With argument +obj+ and a block given, issues a warning, ignores the block, + * and returns the count of elements <tt>==</tt> to +obj+. */ static VALUE @@ -6442,8 +6522,9 @@ static VALUE flatten(VALUE ary, int level) { long i; - VALUE stack, result, tmp = 0, elt; - VALUE memo = Qfalse; + VALUE stack, result, tmp = 0, elt, vmemo; + st_table *memo = 0; + st_data_t id; for (i = 0; i < RARRAY_LEN(ary); i++) { elt = RARRAY_AREF(ary, i); @@ -6457,7 +6538,7 @@ flatten(VALUE ary, int level) } result = ary_new(0, RARRAY_LEN(ary)); - ary_memcpy(result, 0, i, RARRAY_CONST_PTR(ary)); + ary_memcpy(result, 0, i, RARRAY_CONST_PTR_TRANSIENT(ary)); ARY_SET_LEN(result, i); stack = ary_new(0, ARY_DEFAULT_SIZE); @@ -6465,9 +6546,12 @@ flatten(VALUE ary, int level) rb_ary_push(stack, LONG2NUM(i + 1)); if (level < 0) { - memo = rb_obj_hide(rb_ident_hash_new()); - rb_hash_aset(memo, ary, Qtrue); - rb_hash_aset(memo, tmp, Qtrue); + vmemo = rb_hash_new(); + RBASIC_CLEAR_CLASS(vmemo); + memo = st_init_numtable(); + rb_hash_st_table_set(vmemo, memo); + st_insert(memo, (st_data_t)ary, (st_data_t)Qtrue); + st_insert(memo, (st_data_t)tmp, (st_data_t)Qtrue); } ary = tmp; @@ -6482,8 +6566,9 @@ flatten(VALUE ary, int level) } tmp = rb_check_array_type(elt); if (RBASIC(result)->klass) { - if (RTEST(memo)) { - rb_hash_clear(memo); + if (memo) { + RB_GC_GUARD(vmemo); + st_clear(memo); } rb_raise(rb_eRuntimeError, "flatten reentered"); } @@ -6492,11 +6577,12 @@ flatten(VALUE ary, int level) } else { if (memo) { - if (rb_hash_aref(memo, tmp) == Qtrue) { - rb_hash_clear(memo); + id = (st_data_t)tmp; + if (st_is_member(memo, id)) { + st_clear(memo); rb_raise(rb_eArgError, "tried to flatten recursive array"); } - rb_hash_aset(memo, tmp, Qtrue); + st_insert(memo, id, (st_data_t)Qtrue); } rb_ary_push(stack, ary); rb_ary_push(stack, LONG2NUM(i)); @@ -6508,7 +6594,8 @@ flatten(VALUE ary, int level) break; } if (memo) { - rb_hash_delete(memo, ary); + id = (st_data_t)ary; + st_delete(memo, &id, 0); } tmp = rb_ary_pop(stack); i = NUM2LONG(tmp); @@ -6516,7 +6603,7 @@ flatten(VALUE ary, int level) } if (memo) { - rb_hash_clear(memo); + st_clear(memo); } RBASIC_SET_CLASS(result, rb_cArray); @@ -6525,37 +6612,33 @@ flatten(VALUE ary, int level) /* * call-seq: - * flatten!(depth = nil) -> self or nil + * array.flatten! -> self or nil + * array.flatten!(level) -> self or nil * - * Returns +self+ as a recursively flattening of +self+ to +depth+ levels of recursion; - * +depth+ must be an - * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects], - * or +nil+. - * At each level of recursion: + * Replaces each nested \Array in +self+ with the elements from that \Array; + * returns +self+ if any changes, +nil+ otherwise. * - * - Each element that is an array is "flattened" - * (that is, replaced by its individual array elements). - * - Each element that is not an array is unchanged - * (even if the element is an object that has instance method +flatten+). + * With non-negative \Integer argument +level+, flattens recursively through +level+ levels: * - * Returns +nil+ if no elements were flattened. + * a = [ 0, [ 1, [2, 3], 4 ], 5 ] + * a.flatten!(1) # => [0, 1, [2, 3], 4, 5] + * a = [ 0, [ 1, [2, 3], 4 ], 5 ] + * a.flatten!(2) # => [0, 1, 2, 3, 4, 5] + * a = [ 0, [ 1, [2, 3], 4 ], 5 ] + * a.flatten!(3) # => [0, 1, 2, 3, 4, 5] + * [0, 1, 2].flatten!(1) # => nil * - * With non-negative integer argument +depth+, flattens recursively through +depth+ levels: + * With no argument, a +nil+ argument, or with negative argument +level+, flattens all levels: * - * a = [ 0, [ 1, [2, 3], 4 ], 5, {foo: 0}, Set.new([6, 7]) ] - * a # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>] - * a.dup.flatten!(1) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>] - * a.dup.flatten!(1.1) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>] - * a.dup.flatten!(2) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>] - * a.dup.flatten!(3) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>] + * a = [ 0, [ 1, [2, 3], 4 ], 5 ] + * a.flatten! # => [0, 1, 2, 3, 4, 5] + * [0, 1, 2].flatten! # => nil + * a = [ 0, [ 1, [2, 3], 4 ], 5 ] + * a.flatten!(-1) # => [0, 1, 2, 3, 4, 5] + * a = [ 0, [ 1, [2, 3], 4 ], 5 ] + * a.flatten!(-2) # => [0, 1, 2, 3, 4, 5] + * [0, 1, 2].flatten!(-1) # => nil * - * With +nil+ or negative argument +depth+, flattens all levels: - * - * a.dup.flatten! # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>] - * a.dup.flatten!(-1) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>] - * - * Related: Array#flatten; - * see also {Methods for Assigning}[rdoc-ref:Array@Methods+for+Assigning]. */ static VALUE @@ -6573,7 +6656,7 @@ rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary) if (result == ary) { return Qnil; } - if (!(mod = ARY_EMBED_P(result))) rb_ary_freeze(result); + if (!(mod = ARY_EMBED_P(result))) rb_obj_freeze(result); rb_ary_replace(ary, result); if (mod) ARY_SET_EMBED_LEN(result, 0); @@ -6582,37 +6665,35 @@ rb_ary_flatten_bang(int argc, VALUE *argv, VALUE ary) /* * call-seq: - * flatten(depth = nil) -> new_array - * - * Returns a new array that is a recursive flattening of +self+ - * to +depth+ levels of recursion; - * +depth+ must be an - * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects] - * or +nil+. - * At each level of recursion: + * array.flatten -> new_array + * array.flatten(level) -> new_array + * + * Returns a new \Array that is a recursive flattening of +self+: + * - Each non-Array element is unchanged. + * - Each \Array is replaced by its individual elements. + * + * With non-negative \Integer argument +level+, flattens recursively through +level+ levels: + * + * a = [ 0, [ 1, [2, 3], 4 ], 5 ] + * a.flatten(0) # => [0, [1, [2, 3], 4], 5] + * a = [ 0, [ 1, [2, 3], 4 ], 5 ] + * a.flatten(1) # => [0, 1, [2, 3], 4, 5] + * a = [ 0, [ 1, [2, 3], 4 ], 5 ] + * a.flatten(2) # => [0, 1, 2, 3, 4, 5] + * a = [ 0, [ 1, [2, 3], 4 ], 5 ] + * a.flatten(3) # => [0, 1, 2, 3, 4, 5] + * + * With no argument, a +nil+ argument, or with negative argument +level+, flattens all levels: + * + * a = [ 0, [ 1, [2, 3], 4 ], 5 ] + * a.flatten # => [0, 1, 2, 3, 4, 5] + * [0, 1, 2].flatten # => [0, 1, 2] + * a = [ 0, [ 1, [2, 3], 4 ], 5 ] + * a.flatten(-1) # => [0, 1, 2, 3, 4, 5] + * a = [ 0, [ 1, [2, 3], 4 ], 5 ] + * a.flatten(-2) # => [0, 1, 2, 3, 4, 5] + * [0, 1, 2].flatten(-1) # => [0, 1, 2] * - * - Each element that is an array is "flattened" - * (that is, replaced by its individual array elements). - * - Each element that is not an array is unchanged - * (even if the element is an object that has instance method +flatten+). - * - * With non-negative integer argument +depth+, flattens recursively through +depth+ levels: - * - * a = [ 0, [ 1, [2, 3], 4 ], 5, {foo: 0}, Set.new([6, 7]) ] - * a # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>] - * a.flatten(0) # => [0, [1, [2, 3], 4], 5, {:foo=>0}, #<Set: {6, 7}>] - * a.flatten(1 ) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>] - * a.flatten(1.1) # => [0, 1, [2, 3], 4, 5, {:foo=>0}, #<Set: {6, 7}>] - * a.flatten(2) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>] - * a.flatten(3) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>] - * - * With +nil+ or negative +depth+, flattens all levels. - * - * a.flatten # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>] - * a.flatten(-1) # => [0, 1, 2, 3, 4, 5, {:foo=>0}, #<Set: {6, 7}>] - * - * Related: Array#flatten!; - * see also {Methods for Converting}[rdoc-ref:Array@Methods+for+Converting]. */ static VALUE @@ -6647,7 +6728,7 @@ rb_ary_shuffle_bang(rb_execution_context_t *ec, VALUE ary, VALUE randgen) while (i) { long j = RAND_UPTO(i); VALUE tmp; - if (len != RARRAY_LEN(ary) || ptr != RARRAY_CONST_PTR(ary)) { + if (len != RARRAY_LEN(ary) || ptr != RARRAY_CONST_PTR_TRANSIENT(ary)) { rb_raise(rb_eRuntimeError, "modified during shuffle"); } tmp = ptr[--i]; @@ -6666,14 +6747,6 @@ rb_ary_shuffle(rb_execution_context_t *ec, VALUE ary, VALUE randgen) return ary; } -static const rb_data_type_t ary_sample_memo_type = { - .wrap_struct_name = "ary_sample_memo", - .function = { - .dfree = (RUBY_DATA_FUNC)st_free_table, - }, - .flags = RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY -}; - static VALUE ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VALUE to_array) { @@ -6747,7 +6820,7 @@ ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VALUE sorted[j] = idx[i] = k; } result = rb_ary_new_capa(n); - RARRAY_PTR_USE(result, ptr_result, { + RARRAY_PTR_USE_TRANSIENT(result, ptr_result, { for (i=0; i<n; i++) { ptr_result[i] = RARRAY_AREF(ary, idx[i]); } @@ -6755,9 +6828,11 @@ ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VALUE } else if (n <= memo_threshold / 2) { long max_idx = 0; - VALUE vmemo = TypedData_Wrap_Struct(0, &ary_sample_memo_type, 0); +#undef RUBY_UNTYPED_DATA_WARNING +#define RUBY_UNTYPED_DATA_WARNING 0 + VALUE vmemo = Data_Wrap_Struct(0, 0, st_free_table, 0); st_table *memo = st_init_numtable_with_size(n); - RTYPEDDATA_DATA(vmemo) = memo; + DATA_PTR(vmemo) = memo; result = rb_ary_new_capa(n); RARRAY_PTR_USE(result, ptr_result, { for (i=0; i<n; i++) { @@ -6768,7 +6843,7 @@ ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VALUE len = RARRAY_LEN(ary); if (len <= max_idx) n = 0; else if (n > len) n = len; - RARRAY_PTR_USE(ary, ptr_ary, { + RARRAY_PTR_USE_TRANSIENT(ary, ptr_ary, { for (i=0; i<n; i++) { long j2 = j = ptr_result[i]; long i2 = i; @@ -6780,9 +6855,8 @@ ary_sample(rb_execution_context_t *ec, VALUE ary, VALUE randgen, VALUE nv, VALUE } }); }); - RTYPEDDATA_DATA(vmemo) = 0; + DATA_PTR(vmemo) = 0; st_free_table(memo); - RB_GC_GUARD(vmemo); } else { result = rb_ary_dup(ary); @@ -6827,36 +6901,36 @@ rb_ary_cycle_size(VALUE self, VALUE args, VALUE eobj) /* * call-seq: - * cycle(count = nil) {|element| ... } -> nil - * cycle(count = nil) -> new_enumerator + * array.cycle {|element| ... } -> nil + * array.cycle(count) {|element| ... } -> nil + * array.cycle -> new_enumerator + * array.cycle(count) -> new_enumerator * - * With a block given, may call the block, depending on the value of argument +count+; - * +count+ must be an - * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects], - * or +nil+. - * - * When +count+ is positive, - * calls the block with each element, then does so repeatedly, + * When called with positive \Integer argument +count+ and a block, + * calls the block with each element, then does so again, * until it has done so +count+ times; returns +nil+: * * output = [] * [0, 1].cycle(2) {|element| output.push(element) } # => nil * output # => [0, 1, 0, 1] * - * When +count+ is zero or negative, does not call the block: + * If +count+ is zero or negative, does not call the block: * - * [0, 1].cycle(0) {|element| fail 'Cannot happen' } # => nil + * [0, 1].cycle(0) {|element| fail 'Cannot happen' } # => nil * [0, 1].cycle(-1) {|element| fail 'Cannot happen' } # => nil * - * When +count+ is +nil+, cycles forever: + * When a block is given, and argument is omitted or +nil+, cycles forever: * * # Prints 0 and 1 forever. * [0, 1].cycle {|element| puts element } * [0, 1].cycle(nil) {|element| puts element } * - * With no block given, returns a new Enumerator. + * When no block is given, returns a new \Enumerator: + * + * [0, 1].cycle(2) # => #<Enumerator: [0, 1]:cycle(2)> + * [0, 1].cycle # => # => #<Enumerator: [0, 1]:cycle> + * [0, 1].cycle.first(5) # => [0, 1, 0, 1, 0] * - * Related: see {Methods for Iterating}[rdoc-ref:Array@Methods+for+Iterating]. */ static VALUE rb_ary_cycle(int argc, VALUE *argv, VALUE ary) @@ -7008,7 +7082,7 @@ rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj) * When invoked with a block, yield all permutations of elements of +self+; returns +self+. * The order of permutations is indeterminate. * - * When a block and an in-range positive Integer argument +n+ (<tt>0 < n <= self.size</tt>) + * When a block and an in-range positive \Integer argument +n+ (<tt>0 < n <= self.size</tt>) * are given, calls the block with all +n+-tuple permutations of +self+. * * Example: @@ -7039,7 +7113,7 @@ rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj) * [2, 0, 1] * [2, 1, 0] * - * When +n+ is zero, calls the block once with a new empty +Array+: + * When +n+ is zero, calls the block once with a new empty \Array: * * a = [0, 1, 2] * a.permutation(0) {|permutation| p permutation } @@ -7070,7 +7144,7 @@ rb_ary_permutation_size(VALUE ary, VALUE args, VALUE eobj) * [2, 0, 1] * [2, 1, 0] * - * Returns a new Enumerator if no block given: + * Returns a new \Enumerator if no block given: * * a = [0, 1, 2] * a.permutation # => #<Enumerator: [0, 1, 2]:permutation> @@ -7148,46 +7222,56 @@ rb_ary_combination_size(VALUE ary, VALUE args, VALUE eobj) /* * call-seq: - * combination(n) {|element| ... } -> self - * combination(n) -> new_enumerator + * array.combination(n) {|element| ... } -> self + * array.combination(n) -> new_enumerator * - * When a block and a positive - * {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects] - * argument +n+ (<tt>0 < n <= self.size</tt>) - * are given, calls the block with all +n+-tuple combinations of +self+; - * returns +self+: + * Calls the block, if given, with combinations of elements of +self+; + * returns +self+. The order of combinations is indeterminate. + * + * When a block and an in-range positive \Integer argument +n+ (<tt>0 < n <= self.size</tt>) + * are given, calls the block with all +n+-tuple combinations of +self+. + * + * Example: * - * a = %w[a b c] # => ["a", "b", "c"] - * a.combination(2) {|combination| p combination } # => ["a", "b", "c"] + * a = [0, 1, 2] + * a.combination(2) {|combination| p combination } * * Output: * - * ["a", "b"] - * ["a", "c"] - * ["b", "c"] + * [0, 1] + * [0, 2] + * [1, 2] * - * The order of the yielded combinations is not guaranteed. + * Another example: * - * When +n+ is zero, calls the block once with a new empty array: + * a = [0, 1, 2] + * a.combination(3) {|combination| p combination } * - * a.combination(0) {|combination| p combination } - * [].combination(0) {|combination| p combination } + * Output: + * + * [0, 1, 2] + * + * When +n+ is zero, calls the block once with a new empty \Array: + * + * a = [0, 1, 2] + * a1 = a.combination(0) {|combination| p combination } * * Output: * * [] - * [] * - * When +n+ is negative or larger than +self.size+ and +self+ is non-empty, + * When +n+ is out of range (negative or larger than <tt>self.size</tt>), * does not call the block: * - * a.combination(-1) {|combination| fail 'Cannot happen' } # => ["a", "b", "c"] - * a.combination(4) {|combination| fail 'Cannot happen' } # => ["a", "b", "c"] + * a = [0, 1, 2] + * a.combination(-1) {|combination| fail 'Cannot happen' } + * a.combination(4) {|combination| fail 'Cannot happen' } + * + * Returns a new \Enumerator if no block given: * - * With no block given, returns a new Enumerator. + * a = [0, 1, 2] + * a.combination(2) # => #<Enumerator: [0, 1, 2]:combination(2)> * - * Related: Array#permutation; - * see also {Methods for Iterating}[rdoc-ref:Array@Methods+for+Iterating]. */ static VALUE @@ -7278,10 +7362,10 @@ rb_ary_repeated_permutation_size(VALUE ary, VALUE args, VALUE eobj) * array.repeated_permutation(n) -> new_enumerator * * Calls the block with each repeated permutation of length +n+ of the elements of +self+; - * each permutation is an +Array+; + * each permutation is an \Array; * returns +self+. The order of the permutations is indeterminate. * - * When a block and a positive Integer argument +n+ are given, calls the block with each + * When a block and a positive \Integer argument +n+ are given, calls the block with each * +n+-tuple repeated permutation of the elements of +self+. * The number of permutations is <tt>self.size**n</tt>. * @@ -7312,13 +7396,13 @@ rb_ary_repeated_permutation_size(VALUE ary, VALUE args, VALUE eobj) * [2, 1] * [2, 2] * - * If +n+ is zero, calls the block once with an empty +Array+. + * If +n+ is zero, calls the block once with an empty \Array. * * If +n+ is negative, does not call the block: * * a.repeated_permutation(-1) {|permutation| fail 'Cannot happen' } * - * Returns a new Enumerator if no block given: + * Returns a new \Enumerator if no block given: * * a = [0, 1, 2] * a.repeated_permutation(2) # => #<Enumerator: [0, 1, 2]:permutation(2)> @@ -7410,10 +7494,10 @@ rb_ary_repeated_combination_size(VALUE ary, VALUE args, VALUE eobj) * array.repeated_combination(n) -> new_enumerator * * Calls the block with each repeated combination of length +n+ of the elements of +self+; - * each combination is an +Array+; + * each combination is an \Array; * returns +self+. The order of the combinations is indeterminate. * - * When a block and a positive Integer argument +n+ are given, calls the block with each + * When a block and a positive \Integer argument +n+ are given, calls the block with each * +n+-tuple repeated combination of the elements of +self+. * The number of combinations is <tt>(n+1)(n+2)/2</tt>. * @@ -7441,13 +7525,13 @@ rb_ary_repeated_combination_size(VALUE ary, VALUE args, VALUE eobj) * [1, 2] * [2, 2] * - * If +n+ is zero, calls the block once with an empty +Array+. + * If +n+ is zero, calls the block once with an empty \Array. * * If +n+ is negative, does not call the block: * * a.repeated_combination(-1) {|combination| fail 'Cannot happen' } * - * Returns a new Enumerator if no block given: + * Returns a new \Enumerator if no block given: * * a = [0, 1, 2] * a.repeated_combination(2) # => #<Enumerator: [0, 1, 2]:combination(2)> @@ -7514,7 +7598,7 @@ rb_ary_repeated_combination(VALUE ary, VALUE num) * including both +self+ and +other_arrays+. * - The order of the returned combinations is indeterminate. * - * When no block is given, returns the combinations as an +Array+ of Arrays: + * When no block is given, returns the combinations as an \Array of Arrays: * * a = [0, 1, 2] * a1 = [3, 4] @@ -7526,14 +7610,14 @@ rb_ary_repeated_combination(VALUE ary, VALUE num) * p.size # => 12 # a.size * a1.size * a2.size * p # => [[0, 3, 5], [0, 3, 6], [0, 4, 5], [0, 4, 6], [1, 3, 5], [1, 3, 6], [1, 4, 5], [1, 4, 6], [2, 3, 5], [2, 3, 6], [2, 4, 5], [2, 4, 6]] * - * If any argument is an empty +Array+, returns an empty +Array+. + * If any argument is an empty \Array, returns an empty \Array. * - * If no argument is given, returns an +Array+ of 1-element Arrays, + * If no argument is given, returns an \Array of 1-element Arrays, * each containing an element of +self+: * * a.product # => [[0], [1], [2]] * - * When a block is given, yields each combination as an +Array+; returns +self+: + * When a block is given, yields each combination as an \Array; returns +self+: * * a.product(a1) {|combination| p combination } * @@ -7546,11 +7630,11 @@ rb_ary_repeated_combination(VALUE ary, VALUE num) * [2, 3] * [2, 4] * - * If any argument is an empty +Array+, does not call the block: + * If any argument is an empty \Array, does not call the block: * * a.product(a1, a2, []) {|combination| fail 'Cannot happen' } * - * If no argument is given, yields each element of +self+ as a 1-element +Array+: + * If no argument is given, yields each element of +self+ as a 1-element \Array: * * a.product {|combination| p combination } * @@ -7654,8 +7738,8 @@ done: * call-seq: * array.take(n) -> new_array * - * Returns a new +Array+ containing the first +n+ element of +self+, - * where +n+ is a non-negative Integer; + * Returns a new \Array containing the first +n+ element of +self+, + * where +n+ is a non-negative \Integer; * does not modify +self+. * * Examples: @@ -7683,19 +7767,19 @@ rb_ary_take(VALUE obj, VALUE n) * array.take_while {|element| ... } -> new_array * array.take_while -> new_enumerator * - * Returns a new +Array+ containing zero or more leading elements of +self+; + * Returns a new \Array containing zero or more leading elements of +self+; * does not modify +self+. * * With a block given, calls the block with each successive element of +self+; * stops if the block returns +false+ or +nil+; - * returns a new +Array+ containing those elements for which the block returned a truthy value: + * returns a new \Array containing those elements for which the block returned a truthy value: * * a = [0, 1, 2, 3, 4, 5] * a.take_while {|element| element < 3 } # => [0, 1, 2] * a.take_while {|element| true } # => [0, 1, 2, 3, 4, 5] * a # => [0, 1, 2, 3, 4, 5] * - * With no block given, returns a new Enumerator: + * With no block given, returns a new \Enumerator: * * [0, 1].take_while # => #<Enumerator: [0, 1]:take_while> * @@ -7715,10 +7799,10 @@ rb_ary_take_while(VALUE ary) /* * call-seq: - * drop(n) -> new_array + * array.drop(n) -> new_array * - * Returns a new array containing all but the first +n+ element of +self+, - * where +n+ is a non-negative Integer; + * Returns a new \Array containing all but the first +n+ element of +self+, + * where +n+ is a non-negative \Integer; * does not modify +self+. * * Examples: @@ -7727,9 +7811,7 @@ rb_ary_take_while(VALUE ary) * a.drop(0) # => [0, 1, 2, 3, 4, 5] * a.drop(1) # => [1, 2, 3, 4, 5] * a.drop(2) # => [2, 3, 4, 5] - * a.drop(9) # => [] * - * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. */ static VALUE @@ -7748,20 +7830,23 @@ rb_ary_drop(VALUE ary, VALUE n) /* * call-seq: - * drop_while {|element| ... } -> new_array - * drop_while -> new_enumerator + * array.drop_while {|element| ... } -> new_array + * array.drop_while -> new_enumerator + + * Returns a new \Array containing zero or more trailing elements of +self+; + * does not modify +self+. * * With a block given, calls the block with each successive element of +self+; * stops if the block returns +false+ or +nil+; - * returns a new array _omitting_ those elements for which the block returned a truthy value; - * does not modify +self+: + * returns a new \Array _omitting_ those elements for which the block returned a truthy value: * * a = [0, 1, 2, 3, 4, 5] * a.drop_while {|element| element < 3 } # => [3, 4, 5] * - * With no block given, returns a new Enumerator. + * With no block given, returns a new \Enumerator: + * + * [0, 1].drop_while # => # => #<Enumerator: [0, 1]:drop_while> * - * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. */ static VALUE @@ -7778,41 +7863,35 @@ rb_ary_drop_while(VALUE ary) /* * call-seq: - * any? -> true or false - * any?(object) -> true or false - * any? {|element| ... } -> true or false - * - * Returns whether for any element of +self+, a given criterion is satisfied. + * array.any? -> true or false + * array.any? {|element| ... } -> true or false + * array.any?(obj) -> true or false * - * With no block and no argument, returns whether any element of +self+ is truthy: + * Returns +true+ if any element of +self+ meets a given criterion. * - * [nil, false, []].any? # => true # Array object is truthy. - * [nil, false, {}].any? # => true # Hash object is truthy. - * [nil, false, ''].any? # => true # String object is truthy. - * [nil, false].any? # => false # Nil and false are not truthy. - * - * With argument +object+ given, - * returns whether <tt>object === ele</tt> for any element +ele+ in +self+: + * With no block given and no argument, returns +true+ if +self+ has any truthy element, + * +false+ otherwise: * - * [nil, false, 0].any?(0) # => true - * [nil, false, 1].any?(0) # => false - * [nil, false, 'food'].any?(/foo/) # => true - * [nil, false, 'food'].any?(/bar/) # => false + * [nil, 0, false].any? # => true + * [nil, false].any? # => false + * [].any? # => false * - * With a block given, - * calls the block with each element in +self+; - * returns whether the block returns any truthy value: + * With a block given and no argument, calls the block with each element in +self+; + * returns +true+ if the block returns any truthy value, +false+ otherwise: * - * [0, 1, 2].any? {|ele| ele < 1 } # => true - * [0, 1, 2].any? {|ele| ele < 0 } # => false + * [0, 1, 2].any? {|element| element > 1 } # => true + * [0, 1, 2].any? {|element| element > 2 } # => false * - * With both a block and argument +object+ given, - * ignores the block and uses +object+ as above. + * If argument +obj+ is given, returns +true+ if +obj+.<tt>===</tt> any element, + * +false+ otherwise: * - * <b>Special case</b>: returns +false+ if +self+ is empty - * (regardless of any given argument or block). + * ['food', 'drink'].any?(/foo/) # => true + * ['food', 'drink'].any?(/bar/) # => false + * [].any?(/foo/) # => false + * [0, 1, 2].any?(1) # => true + * [0, 1, 2].any?(3) # => false * - * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying]. + * Related: Enumerable#any? */ static VALUE @@ -7845,41 +7924,34 @@ rb_ary_any_p(int argc, VALUE *argv, VALUE ary) /* * call-seq: - * all? -> true or false - * all?(object) -> true or false - * all? {|element| ... } -> true or false - * - * Returns whether for every element of +self+, - * a given criterion is satisfied. - * - * With no block and no argument, - * returns whether every element of +self+ is truthy: + * array.all? -> true or false + * array.all? {|element| ... } -> true or false + * array.all?(obj) -> true or false * - * [[], {}, '', 0, 0.0, Object.new].all? # => true # All truthy objects. - * [[], {}, '', 0, 0.0, nil].all? # => false # nil is not truthy. - * [[], {}, '', 0, 0.0, false].all? # => false # false is not truthy. + * Returns +true+ if all elements of +self+ meet a given criterion. * - * With argument +object+ given, returns whether <tt>object === ele</tt> - * for every element +ele+ in +self+: + * With no block given and no argument, returns +true+ if +self+ contains only truthy elements, + * +false+ otherwise: * - * [0, 0, 0].all?(0) # => true - * [0, 1, 2].all?(1) # => false - * ['food', 'fool', 'foot'].all?(/foo/) # => true - * ['food', 'drink'].all?(/foo/) # => false + * [0, 1, :foo].all? # => true + * [0, nil, 2].all? # => false + * [].all? # => true * - * With a block given, calls the block with each element in +self+; - * returns whether the block returns only truthy values: + * With a block given and no argument, calls the block with each element in +self+; + * returns +true+ if the block returns only truthy values, +false+ otherwise: * - * [0, 1, 2].all? { |ele| ele < 3 } # => true - * [0, 1, 2].all? { |ele| ele < 2 } # => false + * [0, 1, 2].all? { |element| element < 3 } # => true + * [0, 1, 2].all? { |element| element < 2 } # => false * - * With both a block and argument +object+ given, - * ignores the block and uses +object+ as above. + * If argument +obj+ is given, returns +true+ if <tt>obj.===</tt> every element, +false+ otherwise: * - * <b>Special case</b>: returns +true+ if +self+ is empty - * (regardless of any given argument or block). + * ['food', 'fool', 'foot'].all?(/foo/) # => true + * ['food', 'drink'].all?(/bar/) # => false + * [].all?(/foo/) # => true + * [0, 0, 0].all?(0) # => true + * [0, 1, 2].all?(1) # => false * - * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying]. + * Related: Enumerable#all? */ static VALUE @@ -7912,35 +7984,34 @@ rb_ary_all_p(int argc, VALUE *argv, VALUE ary) /* * call-seq: - * none? -> true or false - * none?(object) -> true or false - * none? {|element| ... } -> true or false + * array.none? -> true or false + * array.none? {|element| ... } -> true or false + * array.none?(obj) -> true or false * - * Returns +true+ if no element of +self+ meets a given criterion, +false+ otherwise. + * Returns +true+ if no element of +self+ meet a given criterion. * * With no block given and no argument, returns +true+ if +self+ has no truthy elements, * +false+ otherwise: * - * [nil, false].none? # => true + * [nil, false].none? # => true * [nil, 0, false].none? # => false - * [].none? # => true - * - * With argument +object+ given, returns +false+ if for any element +element+, - * <tt>object === element</tt>; +true+ otherwise: - * - * ['food', 'drink'].none?(/bar/) # => true - * ['food', 'drink'].none?(/foo/) # => false - * [].none?(/foo/) # => true - * [0, 1, 2].none?(3) # => true - * [0, 1, 2].none?(1) # => false + * [].none? # => true * - * With a block given, calls the block with each element in +self+; + * With a block given and no argument, calls the block with each element in +self+; * returns +true+ if the block returns no truthy value, +false+ otherwise: * * [0, 1, 2].none? {|element| element > 3 } # => true * [0, 1, 2].none? {|element| element > 1 } # => false * - * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying]. + * If argument +obj+ is given, returns +true+ if <tt>obj.===</tt> no element, +false+ otherwise: + * + * ['food', 'drink'].none?(/bar/) # => true + * ['food', 'drink'].none?(/foo/) # => false + * [].none?(/foo/) # => true + * [0, 1, 2].none?(3) # => true + * [0, 1, 2].none?(1) # => false + * + * Related: Enumerable#none? */ static VALUE @@ -7973,9 +8044,9 @@ rb_ary_none_p(int argc, VALUE *argv, VALUE ary) /* * call-seq: - * one? -> true or false - * one? {|element| ... } -> true or false - * one?(object) -> true or false + * array.one? -> true or false + * array.one? {|element| ... } -> true or false + * array.one?(obj) -> true or false * * Returns +true+ if exactly one element of +self+ meets a given criterion. * @@ -7987,14 +8058,14 @@ rb_ary_none_p(int argc, VALUE *argv, VALUE ary) * [nil, nil].one? # => false * [].one? # => false * - * With a block given, calls the block with each element in +self+; + * With a block given and no argument, calls the block with each element in +self+; * returns +true+ if the block a truthy value for exactly one element, +false+ otherwise: * * [0, 1, 2].one? {|element| element > 0 } # => false * [0, 1, 2].one? {|element| element > 1 } # => true * [0, 1, 2].one? {|element| element > 2 } # => false * - * With argument +object+ given, returns +true+ if for exactly one element +element+, <tt>object === element</tt>; + * If argument +obj+ is given, returns +true+ if <tt>obj.===</tt> exactly one element, * +false+ otherwise: * * [0, 1, 2].one?(0) # => true @@ -8004,7 +8075,7 @@ rb_ary_none_p(int argc, VALUE *argv, VALUE ary) * ['food', 'drink'].one?(/foo/) # => true * [].one?(/foo/) # => false * - * Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying]. + * Related: Enumerable#one? */ static VALUE @@ -8049,9 +8120,9 @@ rb_ary_one_p(int argc, VALUE *argv, VALUE ary) * call-seq: * array.dig(index, *identifiers) -> object * - * Finds and returns the object in nested object - * specified by +index+ and +identifiers+; - * the nested objects may be instances of various classes. + * Finds and returns the object in nested objects + * that is specified by +index+ and +identifiers+. + * The nested objects may be instances of various classes. * See {Dig Methods}[rdoc-ref:dig_methods.rdoc]. * * Examples: @@ -8062,7 +8133,6 @@ rb_ary_one_p(int argc, VALUE *argv, VALUE ary) * a.dig(1, 2, 0) # => :bat * a.dig(1, 2, 3) # => nil * - * Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. */ static VALUE @@ -8124,7 +8194,7 @@ finish_exact_sum(long n, VALUE r, VALUE v, int z) * Notes: * * - Array#join and Array#flatten may be faster than Array#sum - * for an +Array+ of Strings or an +Array+ of Arrays. + * for an \Array of Strings or an \Array of Arrays. * - Array#sum method may not respect method redefinition of "+" methods such as Integer#+. * */ @@ -8145,12 +8215,6 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary) n = 0; r = Qundef; - - if (!FIXNUM_P(v) && !RB_BIGNUM_TYPE_P(v) && !RB_TYPE_P(v, T_RATIONAL)) { - i = 0; - goto init_is_a_value; - } - for (i = 0; i < RARRAY_LEN(ary); i++) { e = RARRAY_AREF(ary, i); if (block_given) @@ -8235,7 +8299,6 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary) } goto has_some_value; - init_is_a_value: for (; i < RARRAY_LEN(ary); i++) { e = RARRAY_AREF(ary, i); if (block_given) @@ -8246,7 +8309,6 @@ rb_ary_sum(int argc, VALUE *argv, VALUE ary) return v; } -/* :nodoc: */ static VALUE rb_ary_deconstruct(VALUE ary) { @@ -8254,13 +8316,13 @@ rb_ary_deconstruct(VALUE ary) } /* - * An +Array+ is an ordered, integer-indexed collection of objects, called _elements_. + * An \Array is an ordered, integer-indexed collection of objects, called _elements_. * Any object (even another array) may be an array element, * and an array can contain objects of different types. * - * == +Array+ Indexes + * == \Array Indexes * - * +Array+ indexing starts at 0, as in C or Java. + * \Array indexing starts at 0, as in C or Java. * * A positive index is an offset from the first element: * @@ -8287,14 +8349,14 @@ rb_ary_deconstruct(VALUE ary) * - Index -4 is out of range. * * Although the effective index into an array is always an integer, - * some methods (both within and outside of class +Array+) + * some methods (both within and outside of class \Array) * accept one or more non-integer arguments that are * {integer-convertible objects}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects]. * * * == Creating Arrays * - * You can create an +Array+ object explicitly with: + * You can create an \Array object explicitly with: * * - An {array literal}[rdoc-ref:literals.rdoc@Array+Literals]: * @@ -8375,7 +8437,7 @@ rb_ary_deconstruct(VALUE ary) * == Example Usage * * In addition to the methods it mixes in through the Enumerable module, the - * +Array+ class has proprietary methods for accessing, searching and otherwise + * \Array class has proprietary methods for accessing, searching and otherwise * manipulating arrays. * * Some of the more common ones are illustrated below. @@ -8423,7 +8485,7 @@ rb_ary_deconstruct(VALUE ary) * * arr.drop(3) #=> [4, 5, 6] * - * == Obtaining Information about an +Array+ + * == Obtaining Information about an \Array * * Arrays keep track of their own length at all times. To query an array * about the number of elements it contains, use #length, #count or #size. @@ -8461,7 +8523,7 @@ rb_ary_deconstruct(VALUE ary) * arr.insert(3, 'orange', 'pear', 'grapefruit') * #=> [0, 1, 2, "orange", "pear", "grapefruit", "apple", 3, 4, 5, 6] * - * == Removing Items from an +Array+ + * == Removing Items from an \Array * * The method #pop removes the last element in an array and returns it: * @@ -8503,9 +8565,9 @@ rb_ary_deconstruct(VALUE ary) * * == Iterating over Arrays * - * Like all classes that include the Enumerable module, +Array+ has an each + * Like all classes that include the Enumerable module, \Array has an each * method, which defines what elements should be iterated over and how. In - * case of Array's #each, all elements in the +Array+ instance are yielded to + * case of Array's #each, all elements in the \Array instance are yielded to * the supplied block in sequence. * * Note that this operation leaves the array unchanged. @@ -8532,7 +8594,7 @@ rb_ary_deconstruct(VALUE ary) * arr #=> [1, 4, 9, 16, 25] * * - * == Selecting Items from an +Array+ + * == Selecting Items from an \Array * * Elements can be selected from an array according to criteria defined in a * block. The selection can happen in a destructive or a non-destructive @@ -8565,13 +8627,13 @@ rb_ary_deconstruct(VALUE ary) * * == What's Here * - * First, what's elsewhere. \Class +Array+: + * First, what's elsewhere. \Class \Array: * * - Inherits from {class Object}[rdoc-ref:Object@What-27s+Here]. * - Includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here], * which provides dozens of additional methods. * - * Here, class +Array+ provides methods that are useful for: + * Here, class \Array provides methods that are useful for: * * - {Creating an Array}[rdoc-ref:Array@Methods+for+Creating+an+Array] * - {Querying}[rdoc-ref:Array@Methods+for+Querying] @@ -8584,17 +8646,15 @@ rb_ary_deconstruct(VALUE ary) * - {Converting}[rdoc-ref:Array@Methods+for+Converting] * - {And more....}[rdoc-ref:Array@Other+Methods] * - * === Methods for Creating an +Array+ + * === Methods for Creating an \Array * * - ::[]: Returns a new array populated with given objects. * - ::new: Returns a new array. * - ::try_convert: Returns a new array created from a given object. * - * See also {Creating Arrays}[rdoc-ref:Array@Creating+Arrays]. - * * === Methods for Querying * - * - #length (aliased as #size): Returns the count of elements. + * - #length, #size: Returns the count of elements. * - #include?: Returns whether any element <tt>==</tt> a given object. * - #empty?: Returns whether there are no elements. * - #all?: Returns whether all elements meet a given criterion. @@ -8602,13 +8662,13 @@ rb_ary_deconstruct(VALUE ary) * - #none?: Returns whether no element <tt>==</tt> a given object. * - #one?: Returns whether exactly one element <tt>==</tt> a given object. * - #count: Returns the count of elements that meet a given criterion. - * - #find_index (aliased as #index): Returns the index of the first element that meets a given criterion. + * - #find_index, #index: Returns the index of the first element that meets a given criterion. * - #rindex: Returns the index of the last element that meets a given criterion. * - #hash: Returns the integer hash code. * * === Methods for Comparing * - * - #<=>: Returns -1, 0, or 1, as +self+ is less than, equal to, or + * - #<=>: Returns -1, 0, or 1 * as +self+ is less than, equal to, or * greater than a given object. * - #==: Returns whether each element in +self+ is <tt>==</tt> to the corresponding element * in a given object. @@ -8619,17 +8679,16 @@ rb_ary_deconstruct(VALUE ary) * * These methods do not modify +self+. * - * - #[] (aliased as #slice): Returns consecutive elements as determined by a given argument. + * - #[]: Returns one or more elements. * - #fetch: Returns the element at a given offset. - * - #fetch_values: Returns elements at given offsets. * - #first: Returns one or more leading elements. * - #last: Returns one or more trailing elements. * - #max: Returns one or more maximum-valued elements, - * as determined by <tt>#<=></tt> or a given block. + * as determined by <tt><=></tt> or a given block. * - #min: Returns one or more minimum-valued elements, - * as determined by <tt>#<=></tt> or a given block. + * as determined by <tt><=></tt> or a given block. * - #minmax: Returns the minimum-valued and maximum-valued elements, - * as determined by <tt>#<=></tt> or a given block. + * as determined by <tt><=></tt> or a given block. * - #assoc: Returns the first element that is an array * whose first element <tt>==</tt> a given object. * - #rassoc: Returns the first element that is an array @@ -8642,10 +8701,11 @@ rb_ary_deconstruct(VALUE ary) * - #take: Returns leading elements as determined by a given index. * - #drop_while: Returns trailing elements as determined by a given block. * - #take_while: Returns leading elements as determined by a given block. - * - #sort: Returns all elements in an order determined by <tt>#<=></tt> or a given block. + * - #slice: Returns consecutive elements as determined by a given argument. + * - #sort: Returns all elements in an order determined by <tt><=></tt> or a given block. * - #reverse: Returns all elements in reverse order. * - #compact: Returns an array containing all non-+nil+ elements. - * - #select (aliased as #filter): Returns an array containing elements selected by a given block. + * - #select, #filter: Returns an array containing elements selected by a given block. * - #uniq: Returns an array containing non-duplicate elements. * - #rotate: Returns all elements with some rotated from one end to the other. * - #bsearch: Returns an element selected via a binary search @@ -8660,19 +8720,17 @@ rb_ary_deconstruct(VALUE ary) * These methods add, replace, or reorder elements in +self+. * * - #[]=: Assigns specified elements with a given object. - * - #<<: Appends an element. - * - #push (aliased as #append): Appends elements. - * - #unshift (aliased as #prepend): Prepends leading elements. + * - #push, #append, #<<: Appends trailing elements. + * - #unshift, #prepend: Prepends leading elements. * - #insert: Inserts given objects at a given offset; does not replace elements. * - #concat: Appends all elements from given arrays. * - #fill: Replaces specified elements with specified objects. - * - #flatten!: Replaces each nested array in +self+ with the elements from that array. - * - #initialize_copy (aliased as #replace): Replaces the content of +self+ with the content of a given array. + * - #replace: Replaces the content of +self+ with the content of a given array. * - #reverse!: Replaces +self+ with its elements reversed. * - #rotate!: Replaces +self+ with its elements rotated. * - #shuffle!: Replaces +self+ with its elements in random order. * - #sort!: Replaces +self+ with its elements sorted, - * as determined by <tt>#<=></tt> or a given block. + * as determined by <tt><=></tt> or a given block. * - #sort_by!: Replaces +self+ with its elements sorted, as determined by a given block. * * === Methods for Deleting @@ -8685,10 +8743,9 @@ rb_ary_deconstruct(VALUE ary) * - #delete: Removes elements equal to a given object. * - #delete_at: Removes the element at a given offset. * - #delete_if: Removes elements specified by a given block. - * - #clear: Removes all elements. * - #keep_if: Removes elements not specified by a given block. * - #reject!: Removes elements specified by a given block. - * - #select! (aliased as #filter!): Removes elements not specified by a given block. + * - #select!, #filter!: Removes elements not specified by a given block. * - #slice!: Removes and returns a sequence of elements. * - #uniq!: Removes duplicates. * @@ -8725,10 +8782,11 @@ rb_ary_deconstruct(VALUE ary) * * === Methods for Converting * - * - #collect (aliased as #map): Returns an array containing the block return-value for each element. - * - #collect! (aliased as #map!): Replaces each element with a block return-value. + * - #map, #collect: Returns an array containing the block return-value for each element. + * - #map!, #collect!: Replaces each element with a block return-value. * - #flatten: Returns an array that is a recursive flattening of +self+. - * - #inspect (aliased as #to_s): Returns a new String containing the elements. + * - #flatten!: Replaces each nested array in +self+ with the elements from that array. + * - #inspect, #to_s: Returns a new String containing the elements. * - #join: Returns a newsString containing the elements joined by the field separator. * - #to_a: Returns +self+ or a new array containing all elements. * - #to_ary: Returns +self+. @@ -8746,6 +8804,7 @@ rb_ary_deconstruct(VALUE ary) * - With string argument +field_separator+, a new string that is equivalent to * <tt>join(field_separator)</tt>. * + * - #abbrev: Returns a hash of unambiguous abbreviations for elements. * - #pack: Packs the elements into a binary sequence. * - #sum: Returns a sum of elements according to either <tt>+</tt> or a given block. */ @@ -8753,8 +8812,6 @@ rb_ary_deconstruct(VALUE ary) void Init_Array(void) { - fake_ary_flags = init_fake_ary_flags(); - rb_cArray = rb_define_class("Array", rb_cObject); rb_include_module(rb_cArray, rb_mEnumerable); @@ -8779,6 +8836,8 @@ Init_Array(void) rb_define_method(rb_cArray, "[]=", rb_ary_aset, -1); rb_define_method(rb_cArray, "at", rb_ary_at, 1); rb_define_method(rb_cArray, "fetch", rb_ary_fetch, -1); + rb_define_method(rb_cArray, "first", rb_ary_first, -1); + rb_define_method(rb_cArray, "last", rb_ary_last, -1); rb_define_method(rb_cArray, "concat", rb_ary_concat_multi, -1); rb_define_method(rb_cArray, "union", rb_ary_union_multi, -1); rb_define_method(rb_cArray, "difference", rb_ary_difference_multi, -1); @@ -8792,6 +8851,7 @@ Init_Array(void) rb_define_method(rb_cArray, "unshift", rb_ary_unshift_m, -1); rb_define_alias(rb_cArray, "prepend", "unshift"); rb_define_method(rb_cArray, "insert", rb_ary_insert, -1); + rb_define_method(rb_cArray, "each", rb_ary_each, 0); rb_define_method(rb_cArray, "each_index", rb_ary_each_index, 0); rb_define_method(rb_cArray, "reverse_each", rb_ary_reverse_each, 0); rb_define_method(rb_cArray, "length", rb_ary_length, 0); @@ -8874,12 +8934,8 @@ Init_Array(void) rb_define_method(rb_cArray, "one?", rb_ary_one_p, -1); rb_define_method(rb_cArray, "dig", rb_ary_dig, -1); rb_define_method(rb_cArray, "sum", rb_ary_sum, -1); - rb_define_method(rb_cArray, "freeze", rb_ary_freeze, 0); rb_define_method(rb_cArray, "deconstruct", rb_ary_deconstruct, 0); - - rb_cArray_empty_frozen = rb_ary_freeze(rb_ary_new()); - rb_vm_register_global_object(rb_cArray_empty_frozen); } #include "array.rbinc" @@ -1,50 +1,5 @@ class Array # call-seq: - # each {|element| ... } -> self - # each -> new_enumerator - # - # With a block given, iterates over the elements of +self+, - # passing each element to the block; - # returns +self+: - # - # a = [:foo, 'bar', 2] - # a.each {|element| puts "#{element.class} #{element}" } - # - # Output: - # - # Symbol foo - # String bar - # Integer 2 - # - # Allows the array to be modified during iteration: - # - # a = [:foo, 'bar', 2] - # a.each {|element| puts element; a.clear if element.to_s.start_with?('b') } - # - # Output: - # - # foo - # bar - # - # With no block given, returns a new Enumerator. - # - # Related: see {Methods for Iterating}[rdoc-ref:Array@Methods+for+Iterating]. - - def each - Primitive.attr! :inline_block - - unless defined?(yield) - return Primitive.cexpr! 'SIZED_ENUMERATOR(self, 0, 0, ary_enum_length)' - end - _i = 0 - value = nil - while Primitive.cexpr!(%q{ ary_fetch_next(self, LOCAL_PTR(_i), LOCAL_PTR(value)) }) - yield value - end - self - end - - # call-seq: # array.shuffle!(random: Random) -> array # # Shuffles the elements of +self+ in place. @@ -84,7 +39,7 @@ class Array # a.sample # => 8 # If +self+ is empty, returns +nil+. # - # When argument +n+ is given, returns a new +Array+ containing +n+ random + # When argument +n+ is given, returns a new \Array containing +n+ random # elements from +self+: # a.sample(3) # => [8, 9, 2] # a.sample(6) # => [9, 6, 10, 3, 1, 4] @@ -96,7 +51,7 @@ class Array # a.sample(a.size * 2) # => [1, 1, 3, 2, 1, 2] # The argument +n+ must be a non-negative numeric value. # The order of the result array is unrelated to the order of +self+. - # Returns a new empty +Array+ if +self+ is empty. + # Returns a new empty \Array if +self+ is empty. # # The optional +random+ argument will be used as the random number generator: # a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] @@ -111,115 +66,4 @@ class Array Primitive.ary_sample(random, n, ary) end end - - # call-seq: - # first -> object or nil - # first(count) -> new_array - # - # Returns elements from +self+, or +nil+; does not modify +self+. - # - # With no argument given, returns the first element (if available): - # - # a = [:foo, 'bar', 2] - # a.first # => :foo - # a # => [:foo, "bar", 2] - # - # If +self+ is empty, returns +nil+. - # - # [].first # => nil - # - # With non-negative integer argument +count+ given, - # returns the first +count+ elements (as available) in a new array: - # - # a.first(0) # => [] - # a.first(2) # => [:foo, "bar"] - # a.first(50) # => [:foo, "bar", 2] - # - # Related: see {Methods for Querying}[rdoc-ref:Array@Methods+for+Querying]. - def first n = unspecified = true - if Primitive.mandatory_only? - Primitive.attr! :leaf - Primitive.cexpr! %q{ ary_first(self) } - else - if unspecified - Primitive.cexpr! %q{ ary_first(self) } - else - Primitive.cexpr! %q{ ary_take_first_or_last_n(self, NUM2LONG(n), ARY_TAKE_FIRST) } - end - end - end - - # call-seq: - # last -> last_object or nil - # last(n) -> new_array - # - # Returns elements from +self+, or +nil+; +self+ is not modified. - # - # With no argument given, returns the last element, or +nil+ if +self+ is empty: - # - # a = [:foo, 'bar', 2] - # a.last # => 2 - # a # => [:foo, "bar", 2] - # [].last # => nil - # - # - # With non-negative integer argument +n+ is given, - # returns a new array containing the trailing +n+ elements of +self+, as available: - # - # a = [:foo, 'bar', 2] - # a.last(2) # => ["bar", 2] - # a.last(50) # => [:foo, "bar", 2] - # a.last(0) # => [] - # [].last(3) # => [] - # - # Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. - def last n = unspecified = true - if Primitive.mandatory_only? - Primitive.attr! :leaf - Primitive.cexpr! %q{ ary_last(self) } - else - if unspecified - Primitive.cexpr! %q{ ary_last(self) } - else - Primitive.cexpr! %q{ ary_take_first_or_last_n(self, NUM2LONG(n), ARY_TAKE_LAST) } - end - end - end - - # call-seq: - # fetch_values(*indexes) -> new_array - # fetch_values(*indexes) {|index| ... } -> new_array - # - # With no block given, returns a new array containing the elements of +self+ - # at the offsets given by +indexes+; - # each of the +indexes+ must be an - # {integer-convertible object}[rdoc-ref:implicit_conversion.rdoc@Integer-Convertible+Objects]: - # - # a = [:foo, :bar, :baz] - # a.fetch_values(3, 1) # => [:baz, :foo] - # a.fetch_values(3.1, 1) # => [:baz, :foo] - # a.fetch_values # => [] - # - # For a negative index, counts backwards from the end of the array: - # - # a.fetch_values([-2, -1]) # [:bar, :baz] - # - # When no block is given, raises an exception if any index is out of range. - # - # With a block given, for each index: - # - # - If the index in in range, uses an element of +self+ (as above). - # - Otherwise calls, the block with the index, and uses the block's return value. - # - # Example: - # - # a = [:foo, :bar, :baz] - # a.fetch_values(1, 0, 42, 777) {|index| index.to_s} - # # => [:bar, :foo, "42", "777"] - # - # Related: see {Methods for Fetching}[rdoc-ref:Array@Methods+for+Fetching]. - def fetch_values(*indexes, &block) - indexes.map! { |i| fetch(i, &block) } - indexes - end end @@ -1,6 +1,6 @@ /* indent-tabs-mode: nil */ #include "internal.h" -#include "internal/ruby_parser.h" +#include "internal/parse.h" #include "internal/symbol.h" #include "internal/warnings.h" #include "iseq.h" @@ -14,10 +14,9 @@ static VALUE rb_mAST; static VALUE rb_cNode; -static VALUE rb_cLocation; struct ASTNodeData { - VALUE ast_value; + rb_ast_t *ast; const NODE *node; }; @@ -25,16 +24,14 @@ static void node_gc_mark(void *ptr) { struct ASTNodeData *data = (struct ASTNodeData *)ptr; - rb_gc_mark(data->ast_value); + rb_gc_mark((VALUE)data->ast); } static size_t node_memsize(const void *ptr) { struct ASTNodeData *data = (struct ASTNodeData *)ptr; - rb_ast_t *ast = rb_ruby_ast_data_get(data->ast_value); - - return sizeof(struct ASTNodeData) + rb_ast_memsize(ast); + return rb_ast_memsize(data->ast); } static const rb_data_type_t rb_node_type = { @@ -44,51 +41,25 @@ static const rb_data_type_t rb_node_type = { RUBY_TYPED_FREE_IMMEDIATELY, }; -struct ASTLocationData { - int first_lineno; - int first_column; - int last_lineno; - int last_column; -}; - -static void -location_gc_mark(void *ptr) -{ -} - -static size_t -location_memsize(const void *ptr) -{ - return sizeof(struct ASTLocationData); -} - -static const rb_data_type_t rb_location_type = { - "AST/location", - {location_gc_mark, RUBY_TYPED_DEFAULT_FREE, location_memsize,}, - 0, 0, - RUBY_TYPED_FREE_IMMEDIATELY, -}; - - static VALUE rb_ast_node_alloc(VALUE klass); static void -setup_node(VALUE obj, VALUE ast_value, const NODE *node) +setup_node(VALUE obj, rb_ast_t *ast, const NODE *node) { struct ASTNodeData *data; TypedData_Get_Struct(obj, struct ASTNodeData, &rb_node_type, data); - data->ast_value = ast_value; + data->ast = ast; data->node = node; } static VALUE -ast_new_internal(VALUE ast_value, const NODE *node) +ast_new_internal(rb_ast_t *ast, const NODE *node) { VALUE obj; obj = rb_ast_node_alloc(rb_cNode); - setup_node(obj, ast_value, node); + setup_node(obj, ast, node); return obj; } @@ -103,16 +74,14 @@ ast_parse_new(void) } static VALUE -ast_parse_done(VALUE ast_value) +ast_parse_done(rb_ast_t *ast) { - rb_ast_t *ast = rb_ruby_ast_data_get(ast_value); - if (!ast->body.root) { rb_ast_dispose(ast); rb_exc_raise(GET_EC()->errinfo); } - return ast_new_internal(ast_value, (NODE *)ast->body.root); + return ast_new_internal(ast, (NODE *)ast->body.root); } static VALUE @@ -124,15 +93,15 @@ ast_s_parse(rb_execution_context_t *ec, VALUE module, VALUE str, VALUE keep_scri static VALUE rb_ast_parse_str(VALUE str, VALUE keep_script_lines, VALUE error_tolerant, VALUE keep_tokens) { - VALUE ast_value; + rb_ast_t *ast = 0; StringValue(str); VALUE vparser = ast_parse_new(); - if (RTEST(keep_script_lines)) rb_parser_set_script_lines(vparser); + if (RTEST(keep_script_lines)) rb_parser_keep_script_lines(vparser); if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser); if (RTEST(keep_tokens)) rb_parser_keep_tokens(vparser); - ast_value = rb_parser_compile_string_path(vparser, Qnil, str, 1); - return ast_parse_done(ast_value); + ast = rb_parser_compile_string_path(vparser, Qnil, str, 1); + return ast_parse_done(ast); } static VALUE @@ -145,35 +114,49 @@ static VALUE rb_ast_parse_file(VALUE path, VALUE keep_script_lines, VALUE error_tolerant, VALUE keep_tokens) { VALUE f; - VALUE ast_value = Qnil; + rb_ast_t *ast = 0; rb_encoding *enc = rb_utf8_encoding(); + FilePathValue(path); f = rb_file_open_str(path, "r"); rb_funcall(f, rb_intern("set_encoding"), 2, rb_enc_from_encoding(enc), rb_str_new_cstr("-")); VALUE vparser = ast_parse_new(); - if (RTEST(keep_script_lines)) rb_parser_set_script_lines(vparser); + if (RTEST(keep_script_lines)) rb_parser_keep_script_lines(vparser); if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser); if (RTEST(keep_tokens)) rb_parser_keep_tokens(vparser); - ast_value = rb_parser_compile_file_path(vparser, Qnil, f, 1); + ast = rb_parser_compile_file_path(vparser, Qnil, f, 1); rb_io_close(f); - return ast_parse_done(ast_value); + return ast_parse_done(ast); +} + +static VALUE +lex_array(VALUE array, int index) +{ + VALUE str = rb_ary_entry(array, index); + if (!NIL_P(str)) { + StringValue(str); + if (!rb_enc_asciicompat(rb_enc_get(str))) { + rb_raise(rb_eArgError, "invalid source encoding"); + } + } + return str; } static VALUE rb_ast_parse_array(VALUE array, VALUE keep_script_lines, VALUE error_tolerant, VALUE keep_tokens) { - VALUE ast_value = Qnil; + rb_ast_t *ast = 0; array = rb_check_array_type(array); VALUE vparser = ast_parse_new(); - if (RTEST(keep_script_lines)) rb_parser_set_script_lines(vparser); + if (RTEST(keep_script_lines)) rb_parser_keep_script_lines(vparser); if (RTEST(error_tolerant)) rb_parser_error_tolerant(vparser); if (RTEST(keep_tokens)) rb_parser_keep_tokens(vparser); - ast_value = rb_parser_compile_array(vparser, Qnil, array, 1); - return ast_parse_done(ast_value); + ast = rb_parser_compile_generic(vparser, lex_array, Qnil, array, 1); + return ast_parse_done(ast); } -static VALUE node_children(VALUE, const NODE*); +static VALUE node_children(rb_ast_t*, const NODE*); static VALUE node_find(VALUE self, const int node_id) @@ -185,7 +168,7 @@ node_find(VALUE self, const int node_id) if (nd_node_id(data->node) == node_id) return self; - ary = node_children(data->ast_value, data->node); + ary = node_children(data->ast, data->node); for (i = 0; i < RARRAY_LEN(ary); i++) { VALUE child = RARRAY_AREF(ary, i); @@ -202,6 +185,20 @@ node_find(VALUE self, const int node_id) extern VALUE rb_e_script; static VALUE +script_lines(VALUE path) +{ + VALUE hash, lines; + ID script_lines; + CONST_ID(script_lines, "SCRIPT_LINES__"); + if (!rb_const_defined_at(rb_cObject, script_lines)) return Qnil; + hash = rb_const_get_at(rb_cObject, script_lines); + if (!RB_TYPE_P(hash, T_HASH)) return Qnil; + lines = rb_hash_lookup(hash, path); + if (!RB_TYPE_P(lines, T_ARRAY)) return Qnil; + return lines; +} + +static VALUE node_id_for_backtrace_location(rb_execution_context_t *ec, VALUE module, VALUE location) { int node_id; @@ -248,11 +245,6 @@ ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body, VALUE keep_script if (!iseq) { return Qnil; } - - if (ISEQ_BODY(iseq)->prism) { - rb_raise(rb_eRuntimeError, "cannot get AST for ISEQ compiled by prism"); - } - lines = ISEQ_BODY(iseq)->variable.script_lines; VALUE path = rb_iseq_path(iseq); @@ -262,7 +254,7 @@ ast_s_of(rb_execution_context_t *ec, VALUE module, VALUE body, VALUE keep_script rb_raise(rb_eArgError, "cannot get AST for method defined in eval"); } - if (!NIL_P(lines)) { + if (!NIL_P(lines) || !NIL_P(lines = script_lines(path))) { node = rb_ast_parse_array(lines, keep_script_lines, error_tolerant, keep_tokens); } else if (e_option) { @@ -308,10 +300,10 @@ ast_node_node_id(rb_execution_context_t *ec, VALUE self) return INT2FIX(nd_node_id(data->node)); } -#define NEW_CHILD(ast_value, node) (node ? ast_new_internal(ast_value, node) : Qnil) +#define NEW_CHILD(ast, node) node ? ast_new_internal(ast, node) : Qnil static VALUE -rb_ary_new_from_node_args(VALUE ast_value, long n, ...) +rb_ary_new_from_node_args(rb_ast_t *ast, long n, ...) { va_list ar; VALUE ary; @@ -323,57 +315,39 @@ rb_ary_new_from_node_args(VALUE ast_value, long n, ...) for (i=0; i<n; i++) { NODE *node; node = va_arg(ar, NODE *); - rb_ary_push(ary, NEW_CHILD(ast_value, node)); + rb_ary_push(ary, NEW_CHILD(ast, node)); } va_end(ar); return ary; } static VALUE -dump_block(VALUE ast_value, const struct RNode_BLOCK *node) +dump_block(rb_ast_t *ast, const NODE *node) { VALUE ary = rb_ary_new(); do { - rb_ary_push(ary, NEW_CHILD(ast_value, node->nd_head)); + rb_ary_push(ary, NEW_CHILD(ast, node->nd_head)); } while (node->nd_next && nd_type_p(node->nd_next, NODE_BLOCK) && - (node = RNODE_BLOCK(node->nd_next), 1)); + (node = node->nd_next, 1)); if (node->nd_next) { - rb_ary_push(ary, NEW_CHILD(ast_value, node->nd_next)); + rb_ary_push(ary, NEW_CHILD(ast, node->nd_next)); } return ary; } static VALUE -dump_array(VALUE ast_value, const struct RNode_LIST *node) +dump_array(rb_ast_t *ast, const NODE *node) { VALUE ary = rb_ary_new(); - rb_ary_push(ary, NEW_CHILD(ast_value, node->nd_head)); + rb_ary_push(ary, NEW_CHILD(ast, node->nd_head)); while (node->nd_next && nd_type_p(node->nd_next, NODE_LIST)) { - node = RNODE_LIST(node->nd_next); - rb_ary_push(ary, NEW_CHILD(ast_value, node->nd_head)); - } - rb_ary_push(ary, NEW_CHILD(ast_value, node->nd_next)); - - return ary; -} - -static VALUE -dump_parser_array(VALUE ast_value, rb_parser_ary_t *p_ary) -{ - VALUE ary; - - if (p_ary->data_type != PARSER_ARY_DATA_NODE) { - rb_bug("unexpected rb_parser_ary_data_type: %d", p_ary->data_type); - } - - ary = rb_ary_new(); - - for (long i = 0; i < p_ary->len; i++) { - rb_ary_push(ary, NEW_CHILD(ast_value, p_ary->data[i])); + node = node->nd_next; + rb_ary_push(ary, NEW_CHILD(ast, node->nd_head)); } + rb_ary_push(ary, NEW_CHILD(ast, node->nd_next)); return ary; } @@ -395,341 +369,307 @@ no_name_rest(void) } static VALUE -rest_arg(VALUE ast_value, const NODE *rest_arg) +rest_arg(rb_ast_t *ast, const NODE *rest_arg) { - return NODE_NAMED_REST_P(rest_arg) ? NEW_CHILD(ast_value, rest_arg) : no_name_rest(); + return NODE_NAMED_REST_P(rest_arg) ? NEW_CHILD(ast, rest_arg) : no_name_rest(); } static VALUE -node_children(VALUE ast_value, const NODE *node) +node_children(rb_ast_t *ast, const NODE *node) { - char name[sizeof("$") + DECIMAL_SIZE_OF(long)]; + char name[DECIMAL_SIZE_OF_BITS(sizeof(long) * CHAR_BIT) + 2]; /* including '$' */ enum node_type type = nd_type(node); switch (type) { case NODE_BLOCK: - return dump_block(ast_value, RNODE_BLOCK(node)); + return dump_block(ast, node); case NODE_IF: - return rb_ary_new_from_node_args(ast_value, 3, RNODE_IF(node)->nd_cond, RNODE_IF(node)->nd_body, RNODE_IF(node)->nd_else); + return rb_ary_new_from_node_args(ast, 3, node->nd_cond, node->nd_body, node->nd_else); case NODE_UNLESS: - return rb_ary_new_from_node_args(ast_value, 3, RNODE_UNLESS(node)->nd_cond, RNODE_UNLESS(node)->nd_body, RNODE_UNLESS(node)->nd_else); + return rb_ary_new_from_node_args(ast, 3, node->nd_cond, node->nd_body, node->nd_else); case NODE_CASE: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_CASE(node)->nd_head, RNODE_CASE(node)->nd_body); + return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body); case NODE_CASE2: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_CASE2(node)->nd_head, RNODE_CASE2(node)->nd_body); + return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body); case NODE_CASE3: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_CASE3(node)->nd_head, RNODE_CASE3(node)->nd_body); + return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body); case NODE_WHEN: - return rb_ary_new_from_node_args(ast_value, 3, RNODE_WHEN(node)->nd_head, RNODE_WHEN(node)->nd_body, RNODE_WHEN(node)->nd_next); + return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_body, node->nd_next); case NODE_IN: - return rb_ary_new_from_node_args(ast_value, 3, RNODE_IN(node)->nd_head, RNODE_IN(node)->nd_body, RNODE_IN(node)->nd_next); + return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_body, node->nd_next); case NODE_WHILE: case NODE_UNTIL: - return rb_ary_push(rb_ary_new_from_node_args(ast_value, 2, RNODE_WHILE(node)->nd_cond, RNODE_WHILE(node)->nd_body), - RBOOL(RNODE_WHILE(node)->nd_state)); + return rb_ary_push(rb_ary_new_from_node_args(ast, 2, node->nd_cond, node->nd_body), + RBOOL(node->nd_state)); case NODE_ITER: case NODE_FOR: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_ITER(node)->nd_iter, RNODE_ITER(node)->nd_body); + return rb_ary_new_from_node_args(ast, 2, node->nd_iter, node->nd_body); case NODE_FOR_MASGN: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_FOR_MASGN(node)->nd_var); + return rb_ary_new_from_node_args(ast, 1, node->nd_var); case NODE_BREAK: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_BREAK(node)->nd_stts); case NODE_NEXT: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_NEXT(node)->nd_stts); case NODE_RETURN: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_RETURN(node)->nd_stts); + return rb_ary_new_from_node_args(ast, 1, node->nd_stts); case NODE_REDO: - return rb_ary_new_from_node_args(ast_value, 0); + return rb_ary_new_from_node_args(ast, 0); case NODE_RETRY: - return rb_ary_new_from_node_args(ast_value, 0); + return rb_ary_new_from_node_args(ast, 0); case NODE_BEGIN: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_BEGIN(node)->nd_body); + return rb_ary_new_from_node_args(ast, 1, node->nd_body); case NODE_RESCUE: - return rb_ary_new_from_node_args(ast_value, 3, RNODE_RESCUE(node)->nd_head, RNODE_RESCUE(node)->nd_resq, RNODE_RESCUE(node)->nd_else); + return rb_ary_new_from_node_args(ast, 3, node->nd_head, node->nd_resq, node->nd_else); case NODE_RESBODY: - return rb_ary_new_from_node_args(ast_value, 4, RNODE_RESBODY(node)->nd_args, RNODE_RESBODY(node)->nd_exc_var, RNODE_RESBODY(node)->nd_body, RNODE_RESBODY(node)->nd_next); + return rb_ary_new_from_node_args(ast, 3, node->nd_args, node->nd_body, node->nd_head); case NODE_ENSURE: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_ENSURE(node)->nd_head, RNODE_ENSURE(node)->nd_ensr); + return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_ensr); case NODE_AND: case NODE_OR: { VALUE ary = rb_ary_new(); while (1) { - rb_ary_push(ary, NEW_CHILD(ast_value, RNODE_AND(node)->nd_1st)); - if (!RNODE_AND(node)->nd_2nd || !nd_type_p(RNODE_AND(node)->nd_2nd, type)) + rb_ary_push(ary, NEW_CHILD(ast, node->nd_1st)); + if (!node->nd_2nd || !nd_type_p(node->nd_2nd, type)) break; - node = RNODE_AND(node)->nd_2nd; + node = node->nd_2nd; } - rb_ary_push(ary, NEW_CHILD(ast_value, RNODE_AND(node)->nd_2nd)); + rb_ary_push(ary, NEW_CHILD(ast, node->nd_2nd)); return ary; } case NODE_MASGN: - if (NODE_NAMED_REST_P(RNODE_MASGN(node)->nd_args)) { - return rb_ary_new_from_node_args(ast_value, 3, RNODE_MASGN(node)->nd_value, RNODE_MASGN(node)->nd_head, RNODE_MASGN(node)->nd_args); + if (NODE_NAMED_REST_P(node->nd_args)) { + return rb_ary_new_from_node_args(ast, 3, node->nd_value, node->nd_head, node->nd_args); } else { - return rb_ary_new_from_args(3, NEW_CHILD(ast_value, RNODE_MASGN(node)->nd_value), - NEW_CHILD(ast_value, RNODE_MASGN(node)->nd_head), + return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_value), + NEW_CHILD(ast, node->nd_head), no_name_rest()); } case NODE_LASGN: - if (NODE_REQUIRED_KEYWORD_P(RNODE_LASGN(node)->nd_value)) { - return rb_ary_new_from_args(2, var_name(RNODE_LASGN(node)->nd_vid), ID2SYM(rb_intern("NODE_SPECIAL_REQUIRED_KEYWORD"))); - } - return rb_ary_new_from_args(2, var_name(RNODE_LASGN(node)->nd_vid), NEW_CHILD(ast_value, RNODE_LASGN(node)->nd_value)); case NODE_DASGN: - if (NODE_REQUIRED_KEYWORD_P(RNODE_DASGN(node)->nd_value)) { - return rb_ary_new_from_args(2, var_name(RNODE_DASGN(node)->nd_vid), ID2SYM(rb_intern("NODE_SPECIAL_REQUIRED_KEYWORD"))); - } - return rb_ary_new_from_args(2, var_name(RNODE_DASGN(node)->nd_vid), NEW_CHILD(ast_value, RNODE_DASGN(node)->nd_value)); case NODE_IASGN: - return rb_ary_new_from_args(2, var_name(RNODE_IASGN(node)->nd_vid), NEW_CHILD(ast_value, RNODE_IASGN(node)->nd_value)); case NODE_CVASGN: - return rb_ary_new_from_args(2, var_name(RNODE_CVASGN(node)->nd_vid), NEW_CHILD(ast_value, RNODE_CVASGN(node)->nd_value)); case NODE_GASGN: - return rb_ary_new_from_args(2, var_name(RNODE_GASGN(node)->nd_vid), NEW_CHILD(ast_value, RNODE_GASGN(node)->nd_value)); + if (NODE_REQUIRED_KEYWORD_P(node)) { + return rb_ary_new_from_args(2, var_name(node->nd_vid), ID2SYM(rb_intern("NODE_SPECIAL_REQUIRED_KEYWORD"))); + } + return rb_ary_new_from_args(2, var_name(node->nd_vid), NEW_CHILD(ast, node->nd_value)); case NODE_CDECL: - if (RNODE_CDECL(node)->nd_vid) { - return rb_ary_new_from_args(2, ID2SYM(RNODE_CDECL(node)->nd_vid), NEW_CHILD(ast_value, RNODE_CDECL(node)->nd_value)); + if (node->nd_vid) { + return rb_ary_new_from_args(2, ID2SYM(node->nd_vid), NEW_CHILD(ast, node->nd_value)); } - return rb_ary_new_from_args(3, NEW_CHILD(ast_value, RNODE_CDECL(node)->nd_else), ID2SYM(RNODE_COLON2(RNODE_CDECL(node)->nd_else)->nd_mid), NEW_CHILD(ast_value, RNODE_CDECL(node)->nd_value)); + return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_else), ID2SYM(node->nd_else->nd_mid), NEW_CHILD(ast, node->nd_value)); case NODE_OP_ASGN1: - return rb_ary_new_from_args(4, NEW_CHILD(ast_value, RNODE_OP_ASGN1(node)->nd_recv), - ID2SYM(RNODE_OP_ASGN1(node)->nd_mid), - NEW_CHILD(ast_value, RNODE_OP_ASGN1(node)->nd_index), - NEW_CHILD(ast_value, RNODE_OP_ASGN1(node)->nd_rvalue)); + return rb_ary_new_from_args(4, NEW_CHILD(ast, node->nd_recv), + ID2SYM(node->nd_mid), + NEW_CHILD(ast, node->nd_args->nd_head), + NEW_CHILD(ast, node->nd_args->nd_body)); case NODE_OP_ASGN2: - return rb_ary_new_from_args(5, NEW_CHILD(ast_value, RNODE_OP_ASGN2(node)->nd_recv), - RBOOL(RNODE_OP_ASGN2(node)->nd_aid), - ID2SYM(RNODE_OP_ASGN2(node)->nd_vid), - ID2SYM(RNODE_OP_ASGN2(node)->nd_mid), - NEW_CHILD(ast_value, RNODE_OP_ASGN2(node)->nd_value)); + return rb_ary_new_from_args(5, NEW_CHILD(ast, node->nd_recv), + RBOOL(node->nd_next->nd_aid), + ID2SYM(node->nd_next->nd_vid), + ID2SYM(node->nd_next->nd_mid), + NEW_CHILD(ast, node->nd_value)); case NODE_OP_ASGN_AND: - return rb_ary_new_from_args(3, NEW_CHILD(ast_value, RNODE_OP_ASGN_AND(node)->nd_head), ID2SYM(idANDOP), - NEW_CHILD(ast_value, RNODE_OP_ASGN_AND(node)->nd_value)); + return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head), ID2SYM(idANDOP), + NEW_CHILD(ast, node->nd_value)); case NODE_OP_ASGN_OR: - return rb_ary_new_from_args(3, NEW_CHILD(ast_value, RNODE_OP_ASGN_OR(node)->nd_head), ID2SYM(idOROP), - NEW_CHILD(ast_value, RNODE_OP_ASGN_OR(node)->nd_value)); + return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head), ID2SYM(idOROP), + NEW_CHILD(ast, node->nd_value)); case NODE_OP_CDECL: - return rb_ary_new_from_args(3, NEW_CHILD(ast_value, RNODE_OP_CDECL(node)->nd_head), - ID2SYM(RNODE_OP_CDECL(node)->nd_aid), - NEW_CHILD(ast_value, RNODE_OP_CDECL(node)->nd_value)); + return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_head), + ID2SYM(node->nd_aid), + NEW_CHILD(ast, node->nd_value)); case NODE_CALL: - return rb_ary_new_from_args(3, NEW_CHILD(ast_value, RNODE_CALL(node)->nd_recv), - ID2SYM(RNODE_CALL(node)->nd_mid), - NEW_CHILD(ast_value, RNODE_CALL(node)->nd_args)); case NODE_OPCALL: - return rb_ary_new_from_args(3, NEW_CHILD(ast_value, RNODE_OPCALL(node)->nd_recv), - ID2SYM(RNODE_OPCALL(node)->nd_mid), - NEW_CHILD(ast_value, RNODE_OPCALL(node)->nd_args)); case NODE_QCALL: - return rb_ary_new_from_args(3, NEW_CHILD(ast_value, RNODE_QCALL(node)->nd_recv), - ID2SYM(RNODE_QCALL(node)->nd_mid), - NEW_CHILD(ast_value, RNODE_QCALL(node)->nd_args)); + return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv), + ID2SYM(node->nd_mid), + NEW_CHILD(ast, node->nd_args)); case NODE_FCALL: - return rb_ary_new_from_args(2, ID2SYM(RNODE_FCALL(node)->nd_mid), - NEW_CHILD(ast_value, RNODE_FCALL(node)->nd_args)); + return rb_ary_new_from_args(2, ID2SYM(node->nd_mid), + NEW_CHILD(ast, node->nd_args)); case NODE_VCALL: - return rb_ary_new_from_args(1, ID2SYM(RNODE_VCALL(node)->nd_mid)); + return rb_ary_new_from_args(1, ID2SYM(node->nd_mid)); case NODE_SUPER: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_SUPER(node)->nd_args); + return rb_ary_new_from_node_args(ast, 1, node->nd_args); case NODE_ZSUPER: - return rb_ary_new_from_node_args(ast_value, 0); + return rb_ary_new_from_node_args(ast, 0); case NODE_LIST: - return dump_array(ast_value, RNODE_LIST(node)); + case NODE_VALUES: + return dump_array(ast, node); case NODE_ZLIST: - return rb_ary_new_from_node_args(ast_value, 0); + return rb_ary_new_from_node_args(ast, 0); case NODE_HASH: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_HASH(node)->nd_head); + return rb_ary_new_from_node_args(ast, 1, node->nd_head); case NODE_YIELD: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_YIELD(node)->nd_head); + return rb_ary_new_from_node_args(ast, 1, node->nd_head); case NODE_LVAR: - return rb_ary_new_from_args(1, var_name(RNODE_LVAR(node)->nd_vid)); case NODE_DVAR: - return rb_ary_new_from_args(1, var_name(RNODE_DVAR(node)->nd_vid)); + return rb_ary_new_from_args(1, var_name(node->nd_vid)); case NODE_IVAR: - return rb_ary_new_from_args(1, ID2SYM(RNODE_IVAR(node)->nd_vid)); case NODE_CONST: - return rb_ary_new_from_args(1, ID2SYM(RNODE_CONST(node)->nd_vid)); case NODE_CVAR: - return rb_ary_new_from_args(1, ID2SYM(RNODE_CVAR(node)->nd_vid)); case NODE_GVAR: - return rb_ary_new_from_args(1, ID2SYM(RNODE_GVAR(node)->nd_vid)); + return rb_ary_new_from_args(1, ID2SYM(node->nd_vid)); case NODE_NTH_REF: - snprintf(name, sizeof(name), "$%ld", RNODE_NTH_REF(node)->nd_nth); + snprintf(name, sizeof(name), "$%ld", node->nd_nth); return rb_ary_new_from_args(1, ID2SYM(rb_intern(name))); case NODE_BACK_REF: name[0] = '$'; - name[1] = (char)RNODE_BACK_REF(node)->nd_nth; + name[1] = (char)node->nd_nth; name[2] = '\0'; return rb_ary_new_from_args(1, ID2SYM(rb_intern(name))); - case NODE_MATCH: - return rb_ary_new_from_args(1, rb_node_regx_string_val(node)); case NODE_MATCH2: - if (RNODE_MATCH2(node)->nd_args) { - return rb_ary_new_from_node_args(ast_value, 3, RNODE_MATCH2(node)->nd_recv, RNODE_MATCH2(node)->nd_value, RNODE_MATCH2(node)->nd_args); + if (node->nd_args) { + return rb_ary_new_from_node_args(ast, 3, node->nd_recv, node->nd_value, node->nd_args); } - return rb_ary_new_from_node_args(ast_value, 2, RNODE_MATCH2(node)->nd_recv, RNODE_MATCH2(node)->nd_value); + return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_value); case NODE_MATCH3: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_MATCH3(node)->nd_recv, RNODE_MATCH3(node)->nd_value); + return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_value); + case NODE_MATCH: + case NODE_LIT: case NODE_STR: case NODE_XSTR: - return rb_ary_new_from_args(1, rb_node_str_string_val(node)); - case NODE_INTEGER: - return rb_ary_new_from_args(1, rb_node_integer_literal_val(node)); - case NODE_FLOAT: - return rb_ary_new_from_args(1, rb_node_float_literal_val(node)); - case NODE_RATIONAL: - return rb_ary_new_from_args(1, rb_node_rational_literal_val(node)); - case NODE_IMAGINARY: - return rb_ary_new_from_args(1, rb_node_imaginary_literal_val(node)); - case NODE_REGX: - return rb_ary_new_from_args(1, rb_node_regx_string_val(node)); + return rb_ary_new_from_args(1, node->nd_lit); case NODE_ONCE: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_ONCE(node)->nd_body); + return rb_ary_new_from_node_args(ast, 1, node->nd_body); case NODE_DSTR: case NODE_DXSTR: case NODE_DREGX: case NODE_DSYM: { - struct RNode_LIST *n = RNODE_DSTR(node)->nd_next; + NODE *n = node->nd_next; VALUE head = Qnil, next = Qnil; if (n) { - head = NEW_CHILD(ast_value, n->nd_head); - next = NEW_CHILD(ast_value, n->nd_next); + head = NEW_CHILD(ast, n->nd_head); + next = NEW_CHILD(ast, n->nd_next); } - return rb_ary_new_from_args(3, rb_node_dstr_string_val(node), head, next); + return rb_ary_new_from_args(3, node->nd_lit, head, next); } - case NODE_SYM: - return rb_ary_new_from_args(1, rb_node_sym_string_val(node)); case NODE_EVSTR: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_EVSTR(node)->nd_body); + return rb_ary_new_from_node_args(ast, 1, node->nd_body); case NODE_ARGSCAT: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_ARGSCAT(node)->nd_head, RNODE_ARGSCAT(node)->nd_body); + return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body); case NODE_ARGSPUSH: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_ARGSPUSH(node)->nd_head, RNODE_ARGSPUSH(node)->nd_body); + return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body); case NODE_SPLAT: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_SPLAT(node)->nd_head); + return rb_ary_new_from_node_args(ast, 1, node->nd_head); case NODE_BLOCK_PASS: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_BLOCK_PASS(node)->nd_head, RNODE_BLOCK_PASS(node)->nd_body); + return rb_ary_new_from_node_args(ast, 2, node->nd_head, node->nd_body); case NODE_DEFN: - return rb_ary_new_from_args(2, ID2SYM(RNODE_DEFN(node)->nd_mid), NEW_CHILD(ast_value, RNODE_DEFN(node)->nd_defn)); + return rb_ary_new_from_args(2, ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_defn)); case NODE_DEFS: - return rb_ary_new_from_args(3, NEW_CHILD(ast_value, RNODE_DEFS(node)->nd_recv), ID2SYM(RNODE_DEFS(node)->nd_mid), NEW_CHILD(ast_value, RNODE_DEFS(node)->nd_defn)); + return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv), ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_defn)); case NODE_ALIAS: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_ALIAS(node)->nd_1st, RNODE_ALIAS(node)->nd_2nd); + return rb_ary_new_from_node_args(ast, 2, node->nd_1st, node->nd_2nd); case NODE_VALIAS: - return rb_ary_new_from_args(2, ID2SYM(RNODE_VALIAS(node)->nd_alias), ID2SYM(RNODE_VALIAS(node)->nd_orig)); + return rb_ary_new_from_args(2, ID2SYM(node->nd_alias), ID2SYM(node->nd_orig)); case NODE_UNDEF: - return rb_ary_new_from_args(1, dump_parser_array(ast_value, RNODE_UNDEF(node)->nd_undefs)); + return rb_ary_new_from_node_args(ast, 1, node->nd_undef); case NODE_CLASS: - return rb_ary_new_from_node_args(ast_value, 3, RNODE_CLASS(node)->nd_cpath, RNODE_CLASS(node)->nd_super, RNODE_CLASS(node)->nd_body); + return rb_ary_new_from_node_args(ast, 3, node->nd_cpath, node->nd_super, node->nd_body); case NODE_MODULE: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_MODULE(node)->nd_cpath, RNODE_MODULE(node)->nd_body); + return rb_ary_new_from_node_args(ast, 2, node->nd_cpath, node->nd_body); case NODE_SCLASS: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_SCLASS(node)->nd_recv, RNODE_SCLASS(node)->nd_body); + return rb_ary_new_from_node_args(ast, 2, node->nd_recv, node->nd_body); case NODE_COLON2: - return rb_ary_new_from_args(2, NEW_CHILD(ast_value, RNODE_COLON2(node)->nd_head), ID2SYM(RNODE_COLON2(node)->nd_mid)); + return rb_ary_new_from_args(2, NEW_CHILD(ast, node->nd_head), ID2SYM(node->nd_mid)); case NODE_COLON3: - return rb_ary_new_from_args(1, ID2SYM(RNODE_COLON3(node)->nd_mid)); + return rb_ary_new_from_args(1, ID2SYM(node->nd_mid)); case NODE_DOT2: case NODE_DOT3: case NODE_FLIP2: case NODE_FLIP3: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_DOT2(node)->nd_beg, RNODE_DOT2(node)->nd_end); + return rb_ary_new_from_node_args(ast, 2, node->nd_beg, node->nd_end); case NODE_SELF: - return rb_ary_new_from_node_args(ast_value, 0); + return rb_ary_new_from_node_args(ast, 0); case NODE_NIL: - return rb_ary_new_from_node_args(ast_value, 0); + return rb_ary_new_from_node_args(ast, 0); case NODE_TRUE: - return rb_ary_new_from_node_args(ast_value, 0); + return rb_ary_new_from_node_args(ast, 0); case NODE_FALSE: - return rb_ary_new_from_node_args(ast_value, 0); + return rb_ary_new_from_node_args(ast, 0); case NODE_ERRINFO: - return rb_ary_new_from_node_args(ast_value, 0); + return rb_ary_new_from_node_args(ast, 0); case NODE_DEFINED: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_DEFINED(node)->nd_head); + return rb_ary_new_from_node_args(ast, 1, node->nd_head); case NODE_POSTEXE: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_POSTEXE(node)->nd_body); + return rb_ary_new_from_node_args(ast, 1, node->nd_body); case NODE_ATTRASGN: - return rb_ary_new_from_args(3, NEW_CHILD(ast_value, RNODE_ATTRASGN(node)->nd_recv), ID2SYM(RNODE_ATTRASGN(node)->nd_mid), NEW_CHILD(ast_value, RNODE_ATTRASGN(node)->nd_args)); + return rb_ary_new_from_args(3, NEW_CHILD(ast, node->nd_recv), ID2SYM(node->nd_mid), NEW_CHILD(ast, node->nd_args)); case NODE_LAMBDA: - return rb_ary_new_from_node_args(ast_value, 1, RNODE_LAMBDA(node)->nd_body); + return rb_ary_new_from_node_args(ast, 1, node->nd_body); case NODE_OPT_ARG: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_OPT_ARG(node)->nd_body, RNODE_OPT_ARG(node)->nd_next); + return rb_ary_new_from_node_args(ast, 2, node->nd_body, node->nd_next); case NODE_KW_ARG: - return rb_ary_new_from_node_args(ast_value, 2, RNODE_KW_ARG(node)->nd_body, RNODE_KW_ARG(node)->nd_next); + return rb_ary_new_from_node_args(ast, 2, node->nd_body, node->nd_next); case NODE_POSTARG: - if (NODE_NAMED_REST_P(RNODE_POSTARG(node)->nd_1st)) { - return rb_ary_new_from_node_args(ast_value, 2, RNODE_POSTARG(node)->nd_1st, RNODE_POSTARG(node)->nd_2nd); + if (NODE_NAMED_REST_P(node->nd_1st)) { + return rb_ary_new_from_node_args(ast, 2, node->nd_1st, node->nd_2nd); } return rb_ary_new_from_args(2, no_name_rest(), - NEW_CHILD(ast_value, RNODE_POSTARG(node)->nd_2nd)); + NEW_CHILD(ast, node->nd_2nd)); case NODE_ARGS: { - struct rb_args_info *ainfo = &RNODE_ARGS(node)->nd_ainfo; + struct rb_args_info *ainfo = node->nd_ainfo; return rb_ary_new_from_args(10, INT2NUM(ainfo->pre_args_num), - NEW_CHILD(ast_value, ainfo->pre_init), - NEW_CHILD(ast_value, (NODE *)ainfo->opt_args), + NEW_CHILD(ast, ainfo->pre_init), + NEW_CHILD(ast, ainfo->opt_args), var_name(ainfo->first_post_arg), INT2NUM(ainfo->post_args_num), - NEW_CHILD(ast_value, ainfo->post_init), + NEW_CHILD(ast, ainfo->post_init), (ainfo->rest_arg == NODE_SPECIAL_EXCESSIVE_COMMA ? ID2SYM(rb_intern("NODE_SPECIAL_EXCESSIVE_COMMA")) : var_name(ainfo->rest_arg)), - (ainfo->no_kwarg ? Qfalse : NEW_CHILD(ast_value, (NODE *)ainfo->kw_args)), - (ainfo->no_kwarg ? Qfalse : NEW_CHILD(ast_value, ainfo->kw_rest_arg)), + (ainfo->no_kwarg ? Qfalse : NEW_CHILD(ast, ainfo->kw_args)), + (ainfo->no_kwarg ? Qfalse : NEW_CHILD(ast, ainfo->kw_rest_arg)), var_name(ainfo->block_arg)); } case NODE_SCOPE: { - rb_ast_id_table_t *tbl = RNODE_SCOPE(node)->nd_tbl; + rb_ast_id_table_t *tbl = node->nd_tbl; int i, size = tbl ? tbl->size : 0; VALUE locals = rb_ary_new_capa(size); for (i = 0; i < size; i++) { rb_ary_push(locals, var_name(tbl->ids[i])); } - return rb_ary_new_from_args(3, locals, NEW_CHILD(ast_value, (NODE *)RNODE_SCOPE(node)->nd_args), NEW_CHILD(ast_value, RNODE_SCOPE(node)->nd_body)); + return rb_ary_new_from_args(3, locals, NEW_CHILD(ast, node->nd_args), NEW_CHILD(ast, node->nd_body)); } case NODE_ARYPTN: { - VALUE rest = rest_arg(ast_value, RNODE_ARYPTN(node)->rest_arg); + struct rb_ary_pattern_info *apinfo = node->nd_apinfo; + VALUE rest = rest_arg(ast, apinfo->rest_arg); return rb_ary_new_from_args(4, - NEW_CHILD(ast_value, RNODE_ARYPTN(node)->nd_pconst), - NEW_CHILD(ast_value, RNODE_ARYPTN(node)->pre_args), + NEW_CHILD(ast, node->nd_pconst), + NEW_CHILD(ast, apinfo->pre_args), rest, - NEW_CHILD(ast_value, RNODE_ARYPTN(node)->post_args)); + NEW_CHILD(ast, apinfo->post_args)); } case NODE_FNDPTN: { - VALUE pre_rest = rest_arg(ast_value, RNODE_FNDPTN(node)->pre_rest_arg); - VALUE post_rest = rest_arg(ast_value, RNODE_FNDPTN(node)->post_rest_arg); + struct rb_fnd_pattern_info *fpinfo = node->nd_fpinfo; + VALUE pre_rest = rest_arg(ast, fpinfo->pre_rest_arg); + VALUE post_rest = rest_arg(ast, fpinfo->post_rest_arg); return rb_ary_new_from_args(4, - NEW_CHILD(ast_value, RNODE_FNDPTN(node)->nd_pconst), + NEW_CHILD(ast, node->nd_pconst), pre_rest, - NEW_CHILD(ast_value, RNODE_FNDPTN(node)->args), + NEW_CHILD(ast, fpinfo->args), post_rest); } case NODE_HSHPTN: { - VALUE kwrest = RNODE_HSHPTN(node)->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD ? ID2SYM(rb_intern("NODE_SPECIAL_NO_REST_KEYWORD")) : - NEW_CHILD(ast_value, RNODE_HSHPTN(node)->nd_pkwrestarg); + VALUE kwrest = node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD ? ID2SYM(rb_intern("NODE_SPECIAL_NO_REST_KEYWORD")) : + NEW_CHILD(ast, node->nd_pkwrestarg); return rb_ary_new_from_args(3, - NEW_CHILD(ast_value, RNODE_HSHPTN(node)->nd_pconst), - NEW_CHILD(ast_value, RNODE_HSHPTN(node)->nd_pkwargs), + NEW_CHILD(ast, node->nd_pconst), + NEW_CHILD(ast, node->nd_pkwargs), kwrest); } - case NODE_LINE: - return rb_ary_new_from_args(1, rb_node_line_lineno_val(node)); - case NODE_FILE: - return rb_ary_new_from_args(1, rb_node_file_path_val(node)); - case NODE_ENCODING: - return rb_ary_new_from_args(1, rb_node_encoding_val(node)); case NODE_ERROR: - return rb_ary_new_from_node_args(ast_value, 0); + return rb_ary_new_from_node_args(ast, 0); case NODE_ARGS_AUX: case NODE_LAST: break; @@ -744,148 +684,7 @@ ast_node_children(rb_execution_context_t *ec, VALUE self) struct ASTNodeData *data; TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data); - return node_children(data->ast_value, data->node); -} - -static int -null_loc_p(rb_code_location_t *loc) -{ - return (loc->beg_pos.lineno == 0 && loc->beg_pos.column == -1 && loc->end_pos.lineno == 0 && loc->end_pos.column == -1); -} - -static VALUE -location_new(rb_code_location_t *loc) -{ - VALUE obj; - struct ASTLocationData *data; - - if (null_loc_p(loc)) return Qnil; - - obj = TypedData_Make_Struct(rb_cLocation, struct ASTLocationData, &rb_location_type, data); - data->first_lineno = loc->beg_pos.lineno; - data->first_column = loc->beg_pos.column; - data->last_lineno = loc->end_pos.lineno; - data->last_column = loc->end_pos.column; - - return obj; -} - -static VALUE -node_locations(VALUE ast_value, const NODE *node) -{ - enum node_type type = nd_type(node); - switch (type) { - case NODE_ALIAS: - return rb_ary_new_from_args(2, - location_new(nd_code_loc(node)), - location_new(&RNODE_ALIAS(node)->keyword_loc)); - case NODE_AND: - return rb_ary_new_from_args(2, - location_new(nd_code_loc(node)), - location_new(&RNODE_AND(node)->operator_loc)); - case NODE_BLOCK_PASS: - return rb_ary_new_from_args(2, - location_new(nd_code_loc(node)), - location_new(&RNODE_BLOCK_PASS(node)->operator_loc)); - - case NODE_BREAK: - return rb_ary_new_from_args(2, - location_new(nd_code_loc(node)), - location_new(&RNODE_BREAK(node)->keyword_loc)); - case NODE_CASE: - return rb_ary_new_from_args(3, - location_new(nd_code_loc(node)), - location_new(&RNODE_CASE(node)->case_keyword_loc), - location_new(&RNODE_CASE(node)->end_keyword_loc)); - case NODE_CASE2: - return rb_ary_new_from_args(3, - location_new(nd_code_loc(node)), - location_new(&RNODE_CASE2(node)->case_keyword_loc), - location_new(&RNODE_CASE2(node)->end_keyword_loc)); - case NODE_CASE3: - return rb_ary_new_from_args(3, - location_new(nd_code_loc(node)), - location_new(&RNODE_CASE3(node)->case_keyword_loc), - location_new(&RNODE_CASE3(node)->end_keyword_loc)); - case NODE_NEXT: - return rb_ary_new_from_args(2, - location_new(nd_code_loc(node)), - location_new(&RNODE_NEXT(node)->keyword_loc)); - case NODE_OR: - return rb_ary_new_from_args(2, - location_new(nd_code_loc(node)), - location_new(&RNODE_OR(node)->operator_loc)); - case NODE_OP_ASGN1: - return rb_ary_new_from_args(5, - location_new(nd_code_loc(node)), - location_new(&RNODE_OP_ASGN1(node)->call_operator_loc), - location_new(&RNODE_OP_ASGN1(node)->opening_loc), - location_new(&RNODE_OP_ASGN1(node)->closing_loc), - location_new(&RNODE_OP_ASGN1(node)->binary_operator_loc)); - case NODE_OP_ASGN2: - return rb_ary_new_from_args(4, - location_new(nd_code_loc(node)), - location_new(&RNODE_OP_ASGN2(node)->call_operator_loc), - location_new(&RNODE_OP_ASGN2(node)->message_loc), - location_new(&RNODE_OP_ASGN2(node)->binary_operator_loc)); - case NODE_REDO: - return rb_ary_new_from_args(2, - location_new(nd_code_loc(node)), - location_new(&RNODE_REDO(node)->keyword_loc)); - case NODE_RETURN: - return rb_ary_new_from_args(2, - location_new(nd_code_loc(node)), - location_new(&RNODE_RETURN(node)->keyword_loc)); - case NODE_SPLAT: - return rb_ary_new_from_args(2, - location_new(nd_code_loc(node)), - location_new(&RNODE_SPLAT(node)->operator_loc)); - case NODE_UNDEF: - return rb_ary_new_from_args(2, - location_new(nd_code_loc(node)), - location_new(&RNODE_UNDEF(node)->keyword_loc)); - case NODE_UNLESS: - return rb_ary_new_from_args(4, - location_new(nd_code_loc(node)), - location_new(&RNODE_UNLESS(node)->keyword_loc), - location_new(&RNODE_UNLESS(node)->then_keyword_loc), - location_new(&RNODE_UNLESS(node)->end_keyword_loc)); - case NODE_VALIAS: - return rb_ary_new_from_args(2, - location_new(nd_code_loc(node)), - location_new(&RNODE_VALIAS(node)->keyword_loc)); - case NODE_WHEN: - return rb_ary_new_from_args(3, - location_new(nd_code_loc(node)), - location_new(&RNODE_WHEN(node)->keyword_loc), - location_new(&RNODE_WHEN(node)->then_keyword_loc)); - case NODE_WHILE: - return rb_ary_new_from_args(3, - location_new(nd_code_loc(node)), - location_new(&RNODE_WHILE(node)->keyword_loc), - location_new(&RNODE_WHILE(node)->closing_loc)); - case NODE_UNTIL: - return rb_ary_new_from_args(3, - location_new(nd_code_loc(node)), - location_new(&RNODE_UNTIL(node)->keyword_loc), - location_new(&RNODE_UNTIL(node)->closing_loc)); - case NODE_ARGS_AUX: - case NODE_LAST: - break; - default: - return rb_ary_new_from_args(1, location_new(nd_code_loc(node))); - } - - rb_bug("node_locations: unknown node: %s", ruby_node_name(type)); -} - -static VALUE -ast_node_locations(rb_execution_context_t *ec, VALUE self) -{ - struct ASTNodeData *data; - TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data); - - return node_locations(data->ast_value, data->node); + return node_children(data->ast, data->node); } static VALUE @@ -927,37 +726,10 @@ ast_node_last_column(rb_execution_context_t *ec, VALUE self) static VALUE ast_node_all_tokens(rb_execution_context_t *ec, VALUE self) { - long i; struct ASTNodeData *data; - rb_ast_t *ast; - rb_parser_ary_t *parser_tokens; - rb_parser_ast_token_t *parser_token; - VALUE str, loc, token, all_tokens; - TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data); - ast = rb_ruby_ast_data_get(data->ast_value); - parser_tokens = ast->node_buffer->tokens; - if (parser_tokens == NULL) { - return Qnil; - } - - all_tokens = rb_ary_new2(parser_tokens->len); - for (i = 0; i < parser_tokens->len; i++) { - parser_token = parser_tokens->data[i]; - str = rb_str_new(parser_token->str->ptr, parser_token->str->len); - loc = rb_ary_new_from_args(4, - INT2FIX(parser_token->loc.beg_pos.lineno), - INT2FIX(parser_token->loc.beg_pos.column), - INT2FIX(parser_token->loc.end_pos.lineno), - INT2FIX(parser_token->loc.end_pos.column) - ); - token = rb_ary_new_from_args(4, INT2FIX(parser_token->id), ID2SYM(rb_intern(parser_token->type_name)), str, loc); - rb_ary_push(all_tokens, token); - } - rb_ary_freeze(all_tokens); - - return all_tokens; + return rb_ast_tokens(data->ast); } static VALUE @@ -984,66 +756,10 @@ static VALUE ast_node_script_lines(rb_execution_context_t *ec, VALUE self) { struct ASTNodeData *data; - rb_ast_t *ast; TypedData_Get_Struct(self, struct ASTNodeData, &rb_node_type, data); - ast = rb_ruby_ast_data_get(data->ast_value); - rb_parser_ary_t *ret = ast->body.script_lines; - return rb_parser_build_script_lines_from(ret); -} - -static VALUE -ast_location_first_lineno(rb_execution_context_t *ec, VALUE self) -{ - struct ASTLocationData *data; - TypedData_Get_Struct(self, struct ASTLocationData, &rb_location_type, data); - - return INT2NUM(data->first_lineno); -} - -static VALUE -ast_location_first_column(rb_execution_context_t *ec, VALUE self) -{ - struct ASTLocationData *data; - TypedData_Get_Struct(self, struct ASTLocationData, &rb_location_type, data); - - return INT2NUM(data->first_column); -} - -static VALUE -ast_location_last_lineno(rb_execution_context_t *ec, VALUE self) -{ - struct ASTLocationData *data; - TypedData_Get_Struct(self, struct ASTLocationData, &rb_location_type, data); - - return INT2NUM(data->last_lineno); -} - -static VALUE -ast_location_last_column(rb_execution_context_t *ec, VALUE self) -{ - struct ASTLocationData *data; - TypedData_Get_Struct(self, struct ASTLocationData, &rb_location_type, data); - - return INT2NUM(data->last_column); -} - -static VALUE -ast_location_inspect(rb_execution_context_t *ec, VALUE self) -{ - VALUE str; - VALUE cname; - struct ASTLocationData *data; - TypedData_Get_Struct(self, struct ASTLocationData, &rb_location_type, data); - - cname = rb_class_path(rb_obj_class(self)); - str = rb_str_new2("#<"); - - rb_str_append(str, cname); - rb_str_catf(str, ":@%d:%d-%d:%d>", - data->first_lineno, data->first_column, - data->last_lineno, data->last_column); - - return str; + VALUE ret = data->ast->body.script_lines; + if (!RB_TYPE_P(ret, T_ARRAY)) return Qnil; + return ret; } #include "ast.rbinc" @@ -1053,7 +769,5 @@ Init_ast(void) { rb_mAST = rb_define_module_under(rb_cRubyVM, "AbstractSyntaxTree"); rb_cNode = rb_define_class_under(rb_mAST, "Node", rb_cObject); - rb_cLocation = rb_define_class_under(rb_mAST, "Location", rb_cObject); rb_undef_alloc_func(rb_cNode); - rb_undef_alloc_func(rb_cLocation); } @@ -13,13 +13,14 @@ # access children nodes by name, etc. # # If you are looking for a stable API or an API working under multiple Ruby -# implementations, consider using the _prism_ gem, which is the official -# Ruby API to parse Ruby code. +# implementations, consider using the _parser_ gem or Ripper. If you would +# like to make RubyVM::AbstractSyntaxTree stable, please join the discussion +# at https://bugs.ruby-lang.org/issues/14844. # module RubyVM::AbstractSyntaxTree # call-seq: - # RubyVM::AbstractSyntaxTree.parse(string, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) -> 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. @@ -52,14 +53,14 @@ module RubyVM::AbstractSyntaxTree # # (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 expression. + # Note that parsing continues even after the errored expresion. # - def self.parse string, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false + 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, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) -> 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. @@ -71,13 +72,13 @@ module RubyVM::AbstractSyntaxTree # # => #<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: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false + 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, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) -> RubyVM::AbstractSyntaxTree::Node - # RubyVM::AbstractSyntaxTree.of(method, keep_script_lines: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false) -> 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_. # @@ -92,7 +93,7 @@ module RubyVM::AbstractSyntaxTree # # => #<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: RubyVM.keep_script_lines, error_tolerant: false, keep_tokens: false + 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 @@ -264,69 +265,12 @@ module RubyVM::AbstractSyntaxTree lines = script_lines if lines lines = lines[first_lineno - 1 .. last_lineno - 1] - lines[-1] = lines[-1].byteslice(0...last_column) - lines[0] = lines[0].byteslice(first_column..-1) + lines[-1] = lines[-1][0...last_column] + lines[0] = lines[0][first_column..-1] lines.join else nil end end - - # call-seq: - # node.locations -> array - # - # Returns location objects associated with the AST node. - # The returned array contains RubyVM::AbstractSyntaxTree::Location. - def locations - Primitive.ast_node_locations - end - end - - # RubyVM::AbstractSyntaxTree::Location instances are created by - # RubyVM::AbstractSyntaxTree#locations. - # - # This class is MRI specific. - # - class Location - - # call-seq: - # location.first_lineno -> integer - # - # The line number in the source code where this AST's text began. - def first_lineno - Primitive.ast_location_first_lineno - end - - # call-seq: - # location.first_column -> integer - # - # The column number in the source code where this AST's text began. - def first_column - Primitive.ast_location_first_column - end - - # call-seq: - # location.last_lineno -> integer - # - # The line number in the source code where this AST's text ended. - def last_lineno - Primitive.ast_location_last_lineno - end - - # call-seq: - # location.last_column -> integer - # - # The column number in the source code where this AST's text ended. - def last_column - Primitive.ast_location_last_column - end - - # call-seq: - # location.inspect -> string - # - # Returns debugging information about this location as a string. - def inspect - Primitive.ast_location_inspect - end end end diff --git a/basictest/test.rb b/basictest/test.rb index 711e4f4ab3..95875b52a6 100755 --- a/basictest/test.rb +++ b/basictest/test.rb @@ -879,7 +879,7 @@ $x.sort!{|a,b| b-a} # reverse sort test_ok($x == [7,5,3,2,1]) # split test -$x = +"The Book of Mormon" +$x = "The Book of Mormon" test_ok($x.split(//).reverse!.join == $x.reverse) test_ok($x.reverse == $x.reverse!) test_ok("1 byte string".split(//).reverse.join(":") == "g:n:i:r:t:s: :e:t:y:b: :1") @@ -1643,7 +1643,7 @@ test_ok(/^(?:ab+)+/ =~ "ababb" && $& == "ababb") test_ok(/(\s+\d+){2}/ =~ " 1 2" && $& == " 1 2") test_ok(/(?:\s+\d+){2}/ =~ " 1 2" && $& == " 1 2") -$x = +<<END; +$x = <<END; ABCD ABCD END @@ -1682,12 +1682,12 @@ test_ok(?a == ?a) test_ok(?\C-a == "\1") test_ok(?\M-a == "\341") test_ok(?\M-\C-a == "\201") -test_ok("a".dup.upcase![0] == ?A) -test_ok("A".dup.downcase![0] == ?a) -test_ok("abc".dup.tr!("a-z", "A-Z") == "ABC") -test_ok("aabbcccc".dup.tr_s!("a-z", "A-Z") == "ABC") -test_ok("abcc".dup.squeeze!("a-z") == "abc") -test_ok("abcd".dup.delete!("bc") == "ad") +test_ok("a".upcase![0] == ?A) +test_ok("A".downcase![0] == ?a) +test_ok("abc".tr!("a-z", "A-Z") == "ABC") +test_ok("aabbcccc".tr_s!("a-z", "A-Z") == "ABC") +test_ok("abcc".squeeze!("a-z") == "abc") +test_ok("abcd".delete!("bc") == "ad") $x = "abcdef" $y = [ ?a, ?b, ?c, ?d, ?e, ?f ] @@ -1700,7 +1700,7 @@ $x.each_byte {|i| } test_ok(!$bad) -s = +"a string" +s = "a string" s[0..s.size]="another string" test_ok(s == "another string") diff --git a/benchmark/app_aobench.rb b/benchmark/app_aobench.rb index c1546e08ab..16296af12b 100644 --- a/benchmark/app_aobench.rb +++ b/benchmark/app_aobench.rb @@ -151,7 +151,7 @@ def clamp(f) i.to_i end -def orthoBasis(basis, n) +def otherBasis(basis, n) basis[2] = Vec.new(n.x, n.y, n.z) basis[1] = Vec.new(0.0, 0.0, 0.0) @@ -183,7 +183,7 @@ class Scene def ambient_occlusion(isect) basis = Array.new - orthoBasis(basis, isect.n) + otherBasis(basis, isect.n) ntheta = NAO_SAMPLES nphi = NAO_SAMPLES diff --git a/benchmark/array_large_literal.yml b/benchmark/array_large_literal.yml deleted file mode 100644 index 423d68391f..0000000000 --- a/benchmark/array_large_literal.yml +++ /dev/null @@ -1,19 +0,0 @@ -prelude: | - def def_array(size) - Object.class_eval(<<-END) - def array_#{size} - x = 1 - [#{(['x'] * size).join(',')}] - end - END - end - def_array(100) - def_array(1000) - def_array(10000) - def_array(100000) -benchmark: - array_100: array_100 - array_1000: array_1000 - array_10000: array_10000 - array_100000: array_100000 - diff --git a/benchmark/enum_sort_by.yml b/benchmark/enum_sort_by.yml deleted file mode 100644 index d386353888..0000000000 --- a/benchmark/enum_sort_by.yml +++ /dev/null @@ -1,53 +0,0 @@ -prelude: | - array_length = 2 - fixnum_array2 = array_length.times.to_a.map {rand(10000)} - float_array2 = array_length.times.to_a.map {rand(10000.0).to_f} - string_array2 = array_length.times.to_a.map {"r" * rand(1..10000)} - mix_array2 = array_length.times.to_a.map {if rand(1..100) <= 50 then rand(1..10000).to_f else rand(1..10000) end} - all_zero_array2 =array_length.times.to_a.map {0} - - array_length = 10 - fixnum_array10 = array_length.times.to_a.map {rand(10000)} - float_array10 = array_length.times.to_a.map {rand(10000.0).to_f} - string_array10 = array_length.times.to_a.map {"r" * rand(1..10000)} - mix_array10 = array_length.times.to_a.map {if rand(1..100) <= 50 then rand(1..10000).to_f else rand(1..10000) end} - all_zero_array10 =array_length.times.to_a.map {0} - - array_length = 1000 - fixnum_array1000 = array_length.times.to_a.map {rand(10000)} - float_array1000 = array_length.times.to_a.map {rand(10000.0).to_f} - string_array1000 = array_length.times.to_a.map {"r" * rand(1..10000)} - mix_array1000 = array_length.times.to_a.map {if rand(1..100) <= 50 then rand(1..10000).to_f else rand(1..10000) end} - all_zero_array1000 =array_length.times.to_a.map {0} - - array_length = 100000 - fixnum_array100000 = array_length.times.to_a.map {rand(10000)} - float_array100000 = array_length.times.to_a.map {rand(10000.0).to_f} - string_array100000 = array_length.times.to_a.map {"r" * rand(1..10000)} - mix_array100000 = array_length.times.to_a.map {if rand(1..100) <= 50 then rand(1..10000).to_f else rand(1..10000) end} - all_zero_array100000 =array_length.times.to_a.map {0} - -benchmark: - fixnum_array2.sort_by: fixnum_array2.sort_by {|a| a} - float_array2.sort_by: float_array2.sort_by {|a| a} - string_length2.sort_by: string_array2.sort_by {|a| a.length} - mix_array2.sort_by: mix_array2.sort_by {|a| a} - all_zero2.sort_by: all_zero_array2.sort_by{|a| a} - - fixnum_array10.sort_by: fixnum_array10.sort_by {|a| a} - float_array10.sort_by: float_array10.sort_by {|a| a} - string_length10.sort_by: string_array10.sort_by {|a| a.length} - mix_array10.sort_by: mix_array10.sort_by {|a| a} - all_zero10.sort_by: all_zero_array10.sort_by{|a| a} - - fixnum_array1000.sort_by: fixnum_array1000.sort_by {|a| a} - float_array1000.sort_by: float_array1000.sort_by {|a| a} - string_length1000.sort_by: string_array1000.sort_by {|a| a.length} - mix_array1000.sort_by: mix_array1000.sort_by {|a| a} - all_zero1000.sort_by: all_zero_array1000.sort_by{|a| a} - - fixnum_array100000.sort_by: fixnum_array100000.sort_by {|a| a} - float_array100000.sort_by: float_array100000.sort_by {|a| a} - string_length100000.sort_by: string_array100000.sort_by {|a| a.length} - mix_array100000.sort_by: mix_array100000.sort_by {|a| a} - all_zero100000.sort_by: all_zero_array100000.sort_by{|a| a} diff --git a/benchmark/hash_aref_str_lit.yml b/benchmark/hash_aref_str_lit.yml deleted file mode 100644 index ed8142bcf1..0000000000 --- a/benchmark/hash_aref_str_lit.yml +++ /dev/null @@ -1,20 +0,0 @@ -prelude: | - # frozen_string_literal: true - hash = 10.times.to_h do |i| - [i, i] - end - dyn_sym = "dynamic_symbol".to_sym - binary = RubyVM::InstructionSequence.compile("# frozen_string_literal: true\n'iseq_load'").to_binary - iseq_literal_string = RubyVM::InstructionSequence.load_from_binary(binary).eval - - hash[:some_symbol] = 1 - hash[dyn_sym] = 2 - hash["small"] = 3 - hash["frozen_string_literal"] = 4 - hash[iseq_literal_string] = 5 -benchmark: - symbol: hash[:some_symbol] - dyn_symbol: hash[dyn_sym] - small_lit: hash["small"] - frozen_lit: hash["frozen_string_literal"] - iseq_lit: hash[iseq_literal_string] diff --git a/benchmark/hash_key.yml b/benchmark/hash_key.yml deleted file mode 100644 index cab4cf9ca4..0000000000 --- a/benchmark/hash_key.yml +++ /dev/null @@ -1,5 +0,0 @@ -prelude: | - obj = Object.new - hash = { obj => true } -benchmark: hash.key?(obj) -loop_count: 30000000 diff --git a/benchmark/hash_new.yml b/benchmark/hash_new.yml deleted file mode 100644 index 9d8e34187f..0000000000 --- a/benchmark/hash_new.yml +++ /dev/null @@ -1,16 +0,0 @@ -prelude: | - has_hash_with_capa = Hash.instance_method(:initialize).parameters.include?([:key, :capacity]) - strings_1k = 1_000.times.map { |i| -i.to_s.freeze } - strings_100k = 100_000.times.map { |i| -i.to_s.freeze } -benchmark: - new: Hash.new - new_with_capa_1k: | - h = has_hash_with_capa ? Hash.new(capacity: strings_1k.size) : {} - strings_1k.each do |x| - h[x] = true - end - new_with_capa_100k: | - h = has_hash_with_capa ? Hash.new(capacity: strings_100k.size) : {} - strings_100k.each do |x| - h[x] = true - end diff --git a/benchmark/lib/benchmark_driver/runner/mjit.rb b/benchmark/lib/benchmark_driver/runner/mjit.rb new file mode 100644 index 0000000000..3a58a620de --- /dev/null +++ b/benchmark/lib/benchmark_driver/runner/mjit.rb @@ -0,0 +1,34 @@ +require 'benchmark_driver/struct' +require 'benchmark_driver/metric' +require 'erb' + +# A runner to measure after-JIT performance easily +class BenchmarkDriver::Runner::Mjit < BenchmarkDriver::Runner::Ips + # JobParser returns this, `BenchmarkDriver::Runner.runner_for` searches "*::Job" + Job = Class.new(BenchmarkDriver::DefaultJob) + + # Dynamically fetched and used by `BenchmarkDriver::JobParser.parse` + JobParser = BenchmarkDriver::DefaultJobParser.for(klass: Job, metrics: [METRIC]).extend(Module.new{ + def parse(**) + jobs = super + jobs.map do |job| + job = job.dup + job.prelude = "#{job.prelude}\n#{<<~EOS}" + if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? + __bmdv_ruby_i = 0 + while __bmdv_ruby_i < 10000 # MJIT call threshold + #{job.script} + __bmdv_ruby_i += 1 + end + RubyVM::MJIT.pause # compile + #{job.script} + RubyVM::MJIT.resume; RubyVM::MJIT.pause # recompile + #{job.script} + RubyVM::MJIT.resume; RubyVM::MJIT.pause # recompile 2 + end + EOS + job + end + end + }) +end diff --git a/benchmark/loop_each.yml b/benchmark/loop_each.yml deleted file mode 100644 index 1c757185a8..0000000000 --- a/benchmark/loop_each.yml +++ /dev/null @@ -1,4 +0,0 @@ -prelude: | - arr = [nil] * 30_000_000 -benchmark: - loop_each: arr.each{|e|} diff --git a/benchmark/loop_generator.rb b/benchmark/loop_generator.rb index 6a3194b670..d3375c744c 100644 --- a/benchmark/loop_generator.rb +++ b/benchmark/loop_generator.rb @@ -1,4 +1,4 @@ -max = 6000000 +max = 600000 if defined? Fiber gen = (1..max).each diff --git a/benchmark/loop_times_megamorphic.yml b/benchmark/loop_times_megamorphic.yml deleted file mode 100644 index f9343ba897..0000000000 --- a/benchmark/loop_times_megamorphic.yml +++ /dev/null @@ -1,7 +0,0 @@ -prelude: | - eval(<<~EOS) - def loop_times_megamorphic - #{"1.times {|i|};" * 1000} - end - EOS -benchmark: loop_times_megamorphic diff --git a/benchmark/mjit_exivar.yml b/benchmark/mjit_exivar.yml new file mode 100644 index 0000000000..2584fa6410 --- /dev/null +++ b/benchmark/mjit_exivar.yml @@ -0,0 +1,18 @@ +type: lib/benchmark_driver/runner/mjit +prelude: | + class Bench < Hash + def initialize + @exivar = nil + end + + def exivar + @exivar + end + end + + bench = Bench.new + +benchmark: + mjit_exivar: bench.exivar + +loop_count: 200000000 diff --git a/benchmark/mjit_integer.yml b/benchmark/mjit_integer.yml new file mode 100644 index 0000000000..a6b5c9ee16 --- /dev/null +++ b/benchmark/mjit_integer.yml @@ -0,0 +1,32 @@ +type: lib/benchmark_driver/runner/mjit +prelude: | + def mjit_abs(int) int.abs end + def mjit_bit_length(int) int.bit_length end + def mjit_comp(int) ~int end + def mjit_even?(int) int.even? end + def mjit_integer?(int) int.integer? end + def mjit_magnitude(int) int.magnitude end + def mjit_odd?(int) int.odd? end + def mjit_ord(int) int.ord end + def mjit_size(int) int.size end + def mjit_to_i(int) int.to_i end + def mjit_to_int(int) int.to_int end + def mjit_uminus(int) -int end + def mjit_zero?(int) int.zero? end + +benchmark: + - mjit_abs(-1) + - mjit_bit_length(100) + - mjit_comp(1) + - mjit_even?(2) + - mjit_integer?(0) + - mjit_magnitude(-1) + - mjit_odd?(1) + - mjit_ord(1) + - mjit_size(1) + - mjit_to_i(1) + - mjit_to_int(1) + - mjit_uminus(1) + - mjit_zero?(0) + +loop_count: 40000000 diff --git a/benchmark/mjit_kernel.yml b/benchmark/mjit_kernel.yml new file mode 100644 index 0000000000..7720e65c2c --- /dev/null +++ b/benchmark/mjit_kernel.yml @@ -0,0 +1,20 @@ +type: lib/benchmark_driver/runner/mjit +prelude: | + def mjit_class(obj) + obj.class + end + + def mjit_frozen?(obj) + obj.frozen? + end + + str = "" + fstr = "".freeze + +benchmark: + - mjit_class(self) + - mjit_class(1) + - mjit_frozen?(str) + - mjit_frozen?(fstr) + +loop_count: 40000000 diff --git a/benchmark/mjit_leave.yml b/benchmark/mjit_leave.yml new file mode 100644 index 0000000000..9ac68b164b --- /dev/null +++ b/benchmark/mjit_leave.yml @@ -0,0 +1,8 @@ +type: lib/benchmark_driver/runner/mjit +prelude: | + def leave + nil + end +benchmark: + mjit_leave: leave +loop_count: 200000000 diff --git a/benchmark/mjit_opt_cc_insns.yml b/benchmark/mjit_opt_cc_insns.yml new file mode 100644 index 0000000000..fed6d34bd5 --- /dev/null +++ b/benchmark/mjit_opt_cc_insns.yml @@ -0,0 +1,27 @@ +# opt_* insns using vm_method_cfunc_is with send-compatible operands: +# * opt_nil_p +# * opt_not +# * opt_eq +type: lib/benchmark_driver/runner/mjit +prelude: | + def mjit_nil?(obj) + obj.nil? + end + + def mjit_not(obj) + !obj + end + + def mjit_eq(a, b) + a == b + end + +benchmark: + - script: mjit_nil?(1) + loop_count: 40000000 + - script: mjit_not(1) + loop_count: 40000000 + - script: mjit_eq(1, nil) + loop_count: 8000000 + - script: mjit_eq(nil, 1) + loop_count: 8000000 diff --git a/benchmark/mjit_struct_aref.yml b/benchmark/mjit_struct_aref.yml new file mode 100644 index 0000000000..bfba1323f2 --- /dev/null +++ b/benchmark/mjit_struct_aref.yml @@ -0,0 +1,10 @@ +type: lib/benchmark_driver/runner/mjit +prelude: | + def mjit_struct_aref(struct) + struct.aa + end + struct = Struct.new(:a0, :a1, :a2, :a3, :a4, :a5, :a6, :a7, :a8, :a9, :aa).new + +benchmark: mjit_struct_aref(struct) + +loop_count: 40000000 diff --git a/benchmark/object_allocate.yml b/benchmark/object_allocate.yml index bdbd4536db..93ff463e41 100644 --- a/benchmark/object_allocate.yml +++ b/benchmark/object_allocate.yml @@ -11,26 +11,6 @@ prelude: | class OneTwentyEight 128.times { include(Module.new) } end - class OnePositional - def initialize a; end - end - class TwoPositional - def initialize a, b; end - end - class ThreePositional - def initialize a, b, c; end - end - class FourPositional - def initialize a, b, c, d; end - end - class KWArg - def initialize a:, b:, c:, d: - end - end - class Mixed - def initialize a, b, c:, d: - end - end # Disable GC to see raw throughput: GC.disable benchmark: @@ -38,11 +18,4 @@ benchmark: allocate_32_deep: ThirtyTwo.new allocate_64_deep: SixtyFour.new allocate_128_deep: OneTwentyEight.new - allocate_1_positional_params: OnePositional.new(1) - allocate_2_positional_params: TwoPositional.new(1, 2) - allocate_3_positional_params: ThreePositional.new(1, 2, 3) - allocate_4_positional_params: FourPositional.new(1, 2, 3, 4) - allocate_kwarg_params: "KWArg.new(a: 1, b: 2, c: 3, d: 4)" - allocate_mixed_params: "Mixed.new(1, 2, c: 3, d: 4)" - allocate_no_params: "Object.new" loop_count: 100000 diff --git a/benchmark/range_bsearch_bignum.yml b/benchmark/range_bsearch_bignum.yml deleted file mode 100644 index 5730c93fcf..0000000000 --- a/benchmark/range_bsearch_bignum.yml +++ /dev/null @@ -1,10 +0,0 @@ -prelude: | - first = 2**100 - last = 2**1000 - mid = (first + last) / 2 - r = first..last - -benchmark: - first: r.bsearch { |x| x >= first } - mid: r.bsearch { |x| x >= mid } - last: r.bsearch { |x| x >= last } diff --git a/benchmark/range_bsearch_endpointless.yml b/benchmark/range_bsearch_endpointless.yml deleted file mode 100644 index 8d7bedb662..0000000000 --- a/benchmark/range_bsearch_endpointless.yml +++ /dev/null @@ -1,21 +0,0 @@ -prelude: | - re = (1..) - rb = (..0) - -benchmark: - 'endless 10**0': re.bsearch { |x| x >= 1 } - 'endless 10**1': re.bsearch { |x| x >= 10 } - 'endless 10**2': re.bsearch { |x| x >= 100 } - 'endless 10**3': re.bsearch { |x| x >= 1000 } - 'endless 10**4': re.bsearch { |x| x >= 10000 } - 'endless 10**5': re.bsearch { |x| x >= 100000 } - 'endless 10**10': re.bsearch { |x| x >= 10000000000 } - 'endless 10**100': re.bsearch { |x| x >= 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 } - 'beginless -10**0': rb.bsearch { |x| x >= -1 } - 'beginless -10**1': rb.bsearch { |x| x >= -10 } - 'beginless -10**2': rb.bsearch { |x| x >= -100 } - 'beginless -10**3': rb.bsearch { |x| x >= -1000 } - 'beginless -10**4': rb.bsearch { |x| x >= -10000 } - 'beginless -10**5': rb.bsearch { |x| x >= -100000 } - 'beginless -10**10': rb.bsearch { |x| x >= -10000000000 } - 'beginless -10**100': rb.bsearch { |x| x >= -10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 } diff --git a/benchmark/range_bsearch_fixnum.yml b/benchmark/range_bsearch_fixnum.yml deleted file mode 100644 index 59416531b9..0000000000 --- a/benchmark/range_bsearch_fixnum.yml +++ /dev/null @@ -1,10 +0,0 @@ -prelude: | - first = 1 - last = 10000 - mid = (first + last) / 2 - r = first..last - -benchmark: - first: r.bsearch { |x| x >= first } - mid: r.bsearch { |x| x >= mid } - last: r.bsearch { |x| x >= last } diff --git a/benchmark/range_count.yml b/benchmark/range_count.yml deleted file mode 100644 index 58f53a0236..0000000000 --- a/benchmark/range_count.yml +++ /dev/null @@ -1,11 +0,0 @@ -prelude: | - r_1 = 1..1 - r_1k = 1..1000 - r_1m = 1..1000000 - r_str = 'a'..'z' - -benchmark: - 'int 1': r_1.count - 'int 1K': r_1k.count - 'int 1M': r_1m.count - string: r_str.count diff --git a/benchmark/range_overlap.yml b/benchmark/range_overlap.yml deleted file mode 100644 index 700a00053c..0000000000 --- a/benchmark/range_overlap.yml +++ /dev/null @@ -1,19 +0,0 @@ -prelude: | - class Range - unless method_defined?(:overlap?) - def overlap?(other) - other.begin == self.begin || cover?(other.begin) || other.cover?(self.begin) - end - end - end - -benchmark: - - (2..3).overlap?(1..1) - - (2..3).overlap?(2..4) - - (2..3).overlap?(4..5) - - (2..3).overlap?(2..1) - - (2..3).overlap?(0..1) - - (2..3).overlap?(...1) - - (2...3).overlap?(..2) - - (2...3).overlap?(3...) - - (2..3).overlap?('a'..'d') diff --git a/benchmark/range_reverse_each.yml b/benchmark/range_reverse_each.yml deleted file mode 100644 index a32efeccc6..0000000000 --- a/benchmark/range_reverse_each.yml +++ /dev/null @@ -1,16 +0,0 @@ -prelude: | - rf_1 = 0..1 - rf_1k = 0..1000 - rf_1m = 0..1000000 - big = 2**1000 - rb_1 = big..big+1 - rb_1k = big..big+1000 - rb_1m = big..big+1000000 - -benchmark: - "Fixnum 1": rf_1.reverse_each { _1 } - "Fixnum 1K": rf_1k.reverse_each { _1 } - "Fixnum 1M": rf_1m.reverse_each { _1 } - "Bignum 1": rb_1.reverse_each { _1 } - "Bignum 1K": rb_1k.reverse_each { _1 } - "Bignum 1M": rb_1m.reverse_each { _1 } diff --git a/benchmark/realpath.yml b/benchmark/realpath.yml index 6b6a4836b0..90a029d5b9 100644 --- a/benchmark/realpath.yml +++ b/benchmark/realpath.yml @@ -12,9 +12,6 @@ prelude: | relative_dir = 'b/c' absolute_dir = File.join(pwd, relative_dir) file_dir = 'c' -teardown: | - require 'fileutils' - FileUtils.rm_rf('b') benchmark: relative_nil: "f.realpath(relative, nil)" absolute_nil: "f.realpath(absolute, nil)" diff --git a/benchmark/regexp_dup.yml b/benchmark/regexp_dup.yml deleted file mode 100644 index 52f89991cd..0000000000 --- a/benchmark/regexp_dup.yml +++ /dev/null @@ -1,6 +0,0 @@ -prelude: | - str = "a" * 1000 - re = Regexp.new(str) - -benchmark: - dup: re.dup diff --git a/benchmark/regexp_new.yml b/benchmark/regexp_new.yml deleted file mode 100644 index bc9ab3ca21..0000000000 --- a/benchmark/regexp_new.yml +++ /dev/null @@ -1,7 +0,0 @@ -prelude: | - str = "a" * 1000 - re = Regexp.new(str) - -benchmark: - string: Regexp.new(str) - regexp: Regexp.new(re) diff --git a/benchmark/so_count_words.yml b/benchmark/so_count_words.yml index f7322a8541..99683505f9 100644 --- a/benchmark/so_count_words.yml +++ b/benchmark/so_count_words.yml @@ -15,13 +15,13 @@ prelude: | Newsgroups: rec.games.roguelike.nethack X-Mailer: Mozilla 1.1N (Macintosh; I; 68K) - Hello there, Izchak Miller was my father. When I was younger I spent - many a night, hunched over the keyboard with a cup of tea, playing - nethack with him and my brother. my dad was a philosopher with a strong - weakness for fantasy/sci fi. I remember when he started to get involved - with the Nethack team- my brother's Dungeons and Dragons monster book - found a regular place beside my dad's desk. it's nice to see him living - on in the game he loved so much :-). + Hello there, Izchak Miller was my father. When I was younger I spent + many a night, hunched over the keyboard with a cup of tea, playing + nethack with him and my brother. my dad was a philosopher with a strong + weakness for fantasy/sci fi. I remember when he started to get involved + with the Nethack team- my brother's Dungeons and Dragons monster book + found a regular place beside my dad's desk. it's nice to see him living + on in the game he loved so much :-). Tamar Miller The following is a really long word of 5000 characters: @@ -38,9 +38,8 @@ prelude: | 13.times{ data << data } - File.write(wcinput, data) + open(wcinput, 'w'){|f| f.write data} end - at_exit {File.unlink(wcinput) rescue nil} end prepare_wc_input(wc_input_base) @@ -50,16 +49,16 @@ benchmark: # $Id: wc-ruby.code,v 1.4 2004/11/13 07:43:32 bfulgham Exp $ # http://www.bagley.org/~doug/shootout/ # with help from Paul Brannan + input = open(File.join(File.dirname($0), 'wc.input'), 'rb') nl = nw = nc = 0 - File.open(File.join(File.dirname($0), 'wc.input'), 'rb') do |input| - while tmp = input.read(4096) - data = tmp << (input.gets || "") - nc += data.length - nl += data.count("\n") - ((data.strip! || data).tr!("\n", " ") || data).squeeze! - nw += data.count(" ") + 1 - end + while true + tmp = input.read(4096) or break + data = tmp << (input.gets || "") + nc += data.length + nl += data.count("\n") + ((data.strip! || data).tr!("\n", " ") || data).squeeze! + nw += data.count(" ") + 1 end # STDERR.puts "#{nl} #{nw} #{nc}" diff --git a/benchmark/so_meteor_contest.rb b/benchmark/so_meteor_contest.rb index d8c8e3ab9c..8c136baa6c 100644 --- a/benchmark/so_meteor_contest.rb +++ b/benchmark/so_meteor_contest.rb @@ -447,7 +447,7 @@ end # as an inverse. The inverse will ALWAYS be 3 one of the piece configurations that is exactly 3 rotations away # (an odd number). Checking even vs odd then produces a higher probability of finding more pieces earlier # in the cycle. We still need to keep checking all the permutations, but our probability of finding one will -# diminish over time. Since we are TOLD how many to search for this lets us exit before checking all pieces +# diminsh over time. Since we are TOLD how many to search for this lets us exit before checking all pieces # this bennifit is very great when seeking small numbers of solutions and is 0 when looking for more than the # maximum number def find_top( rotation_skip) diff --git a/benchmark/string_concat.yml b/benchmark/string_concat.yml index f11f95ee9a..e65c00cca9 100644 --- a/benchmark/string_concat.yml +++ b/benchmark/string_concat.yml @@ -1,8 +1,6 @@ prelude: | CHUNK = "a" * 64 UCHUNK = "é" * 32 - SHORT = "a" * (GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] / 2) - LONG = "a" * (GC::INTERNAL_CONSTANTS[:BASE_SLOT_SIZE] * 2) GC.disable # GC causes a lot of variance benchmark: binary_concat_7bit: | @@ -45,7 +43,3 @@ benchmark: "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \ "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" \ "#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}#{CHUNK}" - interpolation_same_heap: | - buffer = "#{SHORT}#{SHORT}" - interpolation_switching_heaps: | - buffer = "#{SHORT}#{LONG}" diff --git a/benchmark/string_dup.yml b/benchmark/string_dup.yml deleted file mode 100644 index 90793f9f2a..0000000000 --- a/benchmark/string_dup.yml +++ /dev/null @@ -1,7 +0,0 @@ -prelude: | - # frozen_string_literal: true -benchmark: - uplus: | - +"A" - dup: | - "A".dup diff --git a/benchmark/string_rpartition.yml b/benchmark/string_rpartition.yml deleted file mode 100644 index 37e9d1b071..0000000000 --- a/benchmark/string_rpartition.yml +++ /dev/null @@ -1,18 +0,0 @@ -prelude: | - str1 = [*"a".."z",*"0".."9"].join("") - str10 = str1 * 10 + ":" - str100 = str1 * 100 + ":" - str1000 = str1 * 1000 + ":" - nonascii1 = [*"\u{e0}".."\u{ff}"].join("") - nonascii10 = nonascii1 * 10 + ":" - nonascii100 = nonascii1 * 100 + ":" - nonascii1000 = nonascii1 * 1000 + ":" -benchmark: - rpartition-1: str1.rpartition(":") - rpartition-10: str10.rpartition(":") - rpartition-100: str100.rpartition(":") - rpartition-1000: str1000.rpartition(":") - rpartition-nonascii1: nonascii1.rpartition(":") - rpartition-nonascii10: nonascii10.rpartition(":") - rpartition-nonascii100: nonascii100.rpartition(":") - rpartition-nonascii1000: nonascii1000.rpartition(":") diff --git a/benchmark/struct_accessor.yml b/benchmark/struct_accessor.yml deleted file mode 100644 index 61176cfdd4..0000000000 --- a/benchmark/struct_accessor.yml +++ /dev/null @@ -1,25 +0,0 @@ -prelude: | - C = Struct.new(:x) do - class_eval <<-END - def r - #{'x;'*256} - end - def w - #{'self.x = nil;'*256} - end - def rm - m = method(:x) - #{'m.call;'*256} - end - def wm - m = method(:x=) - #{'m.call(nil);'*256} - end - END - end - obj = C.new(nil) -benchmark: - member_reader: "obj.r" - member_writer: "obj.w" - member_reader_method: "obj.rm" - member_writer_method: "obj.wm" diff --git a/benchmark/time_strftime.yml b/benchmark/time_strftime.yml deleted file mode 100644 index 28f62aec87..0000000000 --- a/benchmark/time_strftime.yml +++ /dev/null @@ -1,7 +0,0 @@ -prelude: | - # frozen_string_literal: true - time = Time.now -benchmark: - - time.strftime("%FT%T") # 19B - - time.strftime("%FT%T.%3N") # 23B - - time.strftime("%FT%T.%6N") # 26B diff --git a/benchmark/time_xmlschema.yml b/benchmark/time_xmlschema.yml deleted file mode 100644 index 654e5cfcbc..0000000000 --- a/benchmark/time_xmlschema.yml +++ /dev/null @@ -1,27 +0,0 @@ -prelude: | - # frozen_string_literal - unless Time.method_defined?(:xmlschema) - class Time - def xmlschema(fraction_digits=0) - fraction_digits = fraction_digits.to_i - s = strftime("%FT%T") - if fraction_digits > 0 - s << strftime(".%#{fraction_digits}N") - end - s << (utc? ? 'Z' : strftime("%:z")) - end - end - end - time = Time.now - utc_time = Time.now.utc - fraction_sec = Time.at(123456789.quo(9999999999)).getlocal("+09:00") - future_time = Time.utc(10000) -benchmark: - - time.xmlschema - - utc_time.xmlschema - - time.xmlschema(6) - - utc_time.xmlschema(6) - - time.xmlschema(9) - - utc_time.xmlschema(9) - - fraction_sec.xmlschema(10) - - future_time.xmlschema diff --git a/benchmark/vm_call_bmethod.yml b/benchmark/vm_call_bmethod.yml deleted file mode 100644 index 40136e5aa4..0000000000 --- a/benchmark/vm_call_bmethod.yml +++ /dev/null @@ -1,37 +0,0 @@ -prelude: | - define_method(:a0){} - define_method(:a1){|a| a} - define_method(:s){|*a| a} - define_method(:b){|kw: 1| kw} - - t0 = 0.times.to_a - t1 = 1.times.to_a - t10 = 10.times.to_a - t100 = 100.times.to_a - kw = {kw: 2} -benchmark: - bmethod_simple_0: | - a0 - bmethod_simple_1: | - a1(1) - bmethod_simple_0_splat: | - a0(*t0) - bmethod_simple_1_splat: | - a1(*t1) - bmethod_no_splat: | - s - bmethod_0_splat: | - s(*t0) - bmethod_1_splat: | - s(*t1) - bmethod_10_splat: | - s(*t10) - bmethod_100_splat: | - s(*t100) - bmethod_kw: | - b(kw: 1) - bmethod_no_kw: | - b - bmethod_kw_splat: | - b(**kw) -loop_count: 6000000 diff --git a/benchmark/vm_call_kw_and_kw_splat.yml b/benchmark/vm_call_kw_and_kw_splat.yml deleted file mode 100644 index aa6e549e0c..0000000000 --- a/benchmark/vm_call_kw_and_kw_splat.yml +++ /dev/null @@ -1,25 +0,0 @@ -prelude: | - h1, h10, h100, h1000 = [1, 10, 100, 1000].map do |n| - h = {kw: 1} - n.times{|i| h[i.to_s.to_sym] = i} - h - end - eh = {} - def kw(kw: nil, **kws) end -benchmark: - 1: | - kw(**h1) - 1_mutable: | - kw(**eh, **h1) - 10: | - kw(**h10) - 10_mutable: | - kw(**eh, **h10) - 100: | - kw(**h100) - 100_mutable: | - kw(**eh, **h100) - 1000: | - kw(**h1000) - 1000_mutable: | - kw(**eh, **h1000) diff --git a/benchmark/vm_call_method_missing.yml b/benchmark/vm_call_method_missing.yml deleted file mode 100644 index f890796f11..0000000000 --- a/benchmark/vm_call_method_missing.yml +++ /dev/null @@ -1,62 +0,0 @@ -prelude: | - class A0 - def method_missing(m); m end - end - class A1 - def method_missing(m, a) a; end - end - class S - def method_missing(m, *a) a; end - end - class B - def method_missing(m, kw: 1) kw end - end - class SB - def method_missing(m, *a, kw: 1) kw end - end - - t0 = 0.times.to_a - t1 = 1.times.to_a - t10 = 10.times.to_a - t200 = 200.times.to_a - kw = {kw: 2} - - a0 = A0.new - a1 = A1.new - s = S.new - b = B.new - sb = SB.new -benchmark: - method_missing_simple_0: | - a0.() - method_missing_simple_1: | - a1.x(1) - method_missing_simple_0_splat: | - a0.(*t0) - method_missing_simple_1_splat: | - a1.(*t1) - method_missing_no_splat: | - s.() - method_missing_0_splat: | - s.(*t0) - method_missing_1_splat: | - s.(*t1) - method_missing_10_splat: | - s.(*t10) - method_missing_200_splat: | - s.(*t200) - method_missing_kw: | - b.(kw: 1) - method_missing_no_kw: | - b.() - method_missing_kw_splat: | - b.(**kw) - method_missing_0_splat_kw: | - sb.(*t0, **kw) - method_missing_1_splat_kw: | - sb.(*t1, **kw) - method_missing_10_splat_kw: | - sb.(*t10, **kw) - method_missing_200_splat_kw: | - sb.(*t200, **kw) -loop_count: 1000000 diff --git a/benchmark/vm_call_send_iseq.yml b/benchmark/vm_call_send_iseq.yml deleted file mode 100644 index 60ff23c475..0000000000 --- a/benchmark/vm_call_send_iseq.yml +++ /dev/null @@ -1,77 +0,0 @@ -prelude: | - def a0; end - def a1(a) a; end - def s(*a) a; end - def b(kw: 1) kw end - def sb(*a, kw: 1) kw end - - t0 = 0.times.to_a - t1 = 1.times.to_a - t10 = 10.times.to_a - t200 = 200.times.to_a - - a0_t0 = [:a0, *t0] - a1_t1 = [:a1, *t1] - s_t0 = [:s, *t0] - s_t1 = [:s, *t1] - s_t10 = [:s, *t10] - s_t200 = [:s, *t200] - sb_t0 = [:sb, *t0] - sb_t1 = [:sb, *t1] - sb_t10 = [:sb, *t10] - sb_t200 = [:sb, *t200] - kw = {kw: 2} -benchmark: - send_simple_0: | - send(:a0) - send_simple_1: | - send(:a1, 1) - send_simple_0_splat: | - send(:a0, *t0) - send_simple_1_splat: | - send(:a1, *t1) - send_simple_0_splat_comb: | - send(*a0_t0) - send_simple_1_splat_comb: | - send(*a1_t1) - send_no_splat: | - send(:s) - send_0_splat: | - send(:s, *t0) - send_1_splat: | - send(:s, *t1) - send_10_splat: | - send(:s, *t10) - send_200_splat: | - send(:s, *t200) - send_0_splat_comb: | - send(*s_t0) - send_1_splat_comb: | - send(*s_t1) - send_10_splat_comb: | - send(*s_t10) - send_200_splat_comb: | - send(*s_t200) - send_kw: | - send(:b, kw: 1) - send_no_kw: | - send(:b) - send_kw_splat: | - send(:b, **kw) - send_0_splat_kw: | - send(:sb, *t0, **kw) - send_1_splat_kw: | - send(:sb, *t1, **kw) - send_10_splat_kw: | - send(:sb, *t10, **kw) - send_200_splat_kw: | - send(:sb, *t200, **kw) - send_0_splat_comb_kw: | - send(*sb_t0, **kw) - send_1_splat_comb_kw: | - send(*sb_t1, **kw) - send_10_splat_comb_kw: | - send(*sb_t10, **kw) - send_200_splat_comb_kw: | - send(*sb_t200, **kw) -loop_count: 3000000 diff --git a/benchmark/vm_call_symproc.yml b/benchmark/vm_call_symproc.yml deleted file mode 100644 index 16e0ac579e..0000000000 --- a/benchmark/vm_call_symproc.yml +++ /dev/null @@ -1,83 +0,0 @@ -prelude: | - def self.a0; end - def self.a1(a) a; end - def self.s(*a) a; end - def self.b(kw: 1) kw end - def self.sb(*a, kw: 1) kw end - - t0 = 0.times.to_a - t1 = 1.times.to_a - t10 = 10.times.to_a - t200 = 200.times.to_a - - a0_t0 = [self, *t0] - a1_t1 = [self, *t1] - s_t0 = [self, *t0] - s_t1 = [self, *t1] - s_t10 = [self, *t10] - s_t200 = [self, *t200] - sb_t0 = [self, *t0] - sb_t1 = [self, *t1] - sb_t10 = [self, *t10] - sb_t200 = [self, *t200] - kw = {kw: 2} - - a0 = :a0.to_proc - a1 = :a1.to_proc - s = :s.to_proc - b = :b.to_proc - sb = :sb.to_proc -benchmark: - symproc_simple_0: | - a0.(self) - symproc_simple_1: | - a1.(self, 1) - symproc_simple_0_splat: | - a0.(self, *t0) - symproc_simple_1_splat: | - a1.(self, *t1) - symproc_simple_0_splat_comb: | - a0.(*a0_t0) - symproc_simple_1_splat_comb: | - a1.(*a1_t1) - symproc_no_splat: | - s.(self) - symproc_0_splat: | - s.(self, *t0) - symproc_1_splat: | - s.(self, *t1) - symproc_10_splat: | - s.(self, *t10) - symproc_200_splat: | - s.(self, *t200) - symproc_0_splat_comb: | - s.(*s_t0) - symproc_1_splat_comb: | - s.(*s_t1) - symproc_10_splat_comb: | - s.(*s_t10) - symproc_200_splat_comb: | - s.(*s_t200) - symproc_kw: | - b.(self, kw: 1) - symproc_no_kw: | - b.(self) - symproc_kw_splat: | - b.(self, **kw) - symproc_0_splat_kw: | - sb.(self, *t0, **kw) - symproc_1_splat_kw: | - sb.(self, *t1, **kw) - symproc_10_splat_kw: | - sb.(self, *t10, **kw) - symproc_200_splat_kw: | - sb.(self, *t200, **kw) - symproc_0_splat_comb_kw: | - sb.(*sb_t0, **kw) - symproc_1_splat_comb_kw: | - sb.(*sb_t1, **kw) - symproc_10_splat_comb_kw: | - sb.(*sb_t10, **kw) - symproc_200_splat_comb_kw: | - sb.(*sb_t200, **kw) -loop_count: 1000000 diff --git a/benchmark/vm_ivar_ic_miss.yml b/benchmark/vm_ivar_ic_miss.yml deleted file mode 100644 index 944fb1a9e6..0000000000 --- a/benchmark/vm_ivar_ic_miss.yml +++ /dev/null @@ -1,20 +0,0 @@ -prelude: | - class Foo - def initialize diverge - if diverge - @a = 1 - end - - @a0 = @a1 = @a2 = @a3 = @a4 = @a5 = @a6 = @a7 = @a8 = @a9 = @a10 = @a11 = @a12 = @a13 = @a14 = @a15 = @a16 = @a17 = @a18 = @a19 = @a20 = @a21 = @a22 = @a23 = @a24 = @a25 = @a26 = @a27 = @a28 = @a29 = @a30 = @a31 = @a32 = @a33 = @a34 = @a35 = @a36 = @a37 = @a38 = @a39 = @a40 = @a41 = @a42 = @a43 = @a44 = @a45 = @a46 = @a47 = @a48 = @a49 = @a50 = @a51 = @a52 = @a53 = @a54 = @a55 = @a56 = @a57 = @a58 = @a59 = @a60 = @a61 = @a62 = @a63 = @a64 = @a65 = @a66 = @a67 = @a68 = @a69 = @a70 = @a71 = @a72 = @a73 = @a74 = @b = 1 - end - - def b; @b; end - end - - a = Foo.new false - b = Foo.new true -benchmark: - vm_ivar_ic_miss: | - a.b - b.b -loop_count: 30000000 diff --git a/benchmark/vm_ivar_memoize.yml b/benchmark/vm_ivar_memoize.yml deleted file mode 100644 index 90f6b07f05..0000000000 --- a/benchmark/vm_ivar_memoize.yml +++ /dev/null @@ -1,85 +0,0 @@ -prelude: | - IVARS = 60 - class Record - def initialize(offset = false) - @offset = 1 if offset - @first = 0 - IVARS.times do |i| - instance_variable_set("@ivar_#{i}", i) - end - end - - def first - @first - end - - def lazy_set - @lazy_set ||= 123 - end - - def undef - @undef - end - end - - Record.new # Need one alloc to right size - - BASE = Record.new - LAZY = Record.new - LAZY.lazy_set - - class Miss < Record - @first = 0 - IVARS.times do |i| - instance_variable_set("@i_#{i}", i) - end - end - - Miss.new # Need one alloc to right size - MISS = Miss.new - - DIVERGENT = Record.new(true) - -benchmark: - vm_ivar_stable_shape: | - BASE.first - BASE.first - BASE.first - BASE.first - BASE.first - BASE.first - vm_ivar_memoize_unstable_shape: | - BASE.first - LAZY.first - BASE.first - LAZY.first - BASE.first - LAZY.first - vm_ivar_memoize_unstable_shape_miss: | - BASE.first - MISS.first - BASE.first - MISS.first - BASE.first - MISS.first - vm_ivar_unstable_undef: | - BASE.undef - LAZY.undef - BASE.undef - LAZY.undef - BASE.undef - LAZY.undef - vm_ivar_divergent_shape: | - BASE.first - DIVERGENT.first - BASE.first - DIVERGENT.first - BASE.first - DIVERGENT.first - vm_ivar_divergent_shape_imbalanced: | - BASE.first - DIVERGENT.first - DIVERGENT.first - DIVERGENT.first - DIVERGENT.first - DIVERGENT.first diff --git a/benchmark/vm_method_splat_calls.yml b/benchmark/vm_method_splat_calls.yml deleted file mode 100644 index f2f366e99c..0000000000 --- a/benchmark/vm_method_splat_calls.yml +++ /dev/null @@ -1,13 +0,0 @@ -prelude: | - def f(x=0, y: 0) end - a = [1] - ea = [] - kw = {y: 1} - b = lambda{} -benchmark: - arg_splat: "f(1, *ea)" - arg_splat_block: "f(1, *ea, &b)" - splat_kw_splat: "f(*a, **kw)" - splat_kw_splat_block: "f(*a, **kw, &b)" - splat_kw: "f(*a, y: 1)" - splat_kw_block: "f(*a, y: 1, &b)" diff --git a/benchmark/vm_method_splat_calls2.yml b/benchmark/vm_method_splat_calls2.yml deleted file mode 100644 index d33dcd7e8b..0000000000 --- a/benchmark/vm_method_splat_calls2.yml +++ /dev/null @@ -1,27 +0,0 @@ -prelude: | - def named_arg_splat(*a) end - def named_arg_kw_splat(*a, **kw) end - def anon_arg_splat(*) end - def anon_kw_splat(**) end - def anon_arg_kw_splat(*, **) end - def anon_fw_to_named(*, **) named_arg_kw_splat(*, **) end - def fw_to_named(...) named_arg_kw_splat(...) end - def fw_to_anon_to_named(...) anon_fw_to_named(...) end - def fw_no_kw(...) named_arg_splat(...) end - a = [1] - kw = {y: 1} -benchmark: - named_multi_arg_splat: "named_arg_splat(*a, *a)" - named_post_splat: "named_arg_splat(*a, a)" - anon_arg_splat: "anon_arg_splat(*a)" - anon_arg_kw_splat: "anon_arg_kw_splat(*a, **kw)" - anon_multi_arg_splat: "anon_arg_splat(*a, *a)" - anon_post_splat: "anon_arg_splat(*a, a)" - anon_kw_splat: "anon_kw_splat(**kw)" - anon_fw_to_named_splat: "anon_fw_to_named(*a, **kw)" - anon_fw_to_named_no_splat: "anon_fw_to_named(1, y: 1)" - fw_to_named_splat: "fw_to_named(*a, **kw)" - fw_to_named_no_splat: "fw_to_named(1, y: 1)" - fw_to_anon_to_named_splat: "fw_to_anon_to_named(*a, **kw)" - fw_to_anon_to_named_no_splat: "fw_to_anon_to_named(1, y: 1)" - fw_no_kw: "fw_no_kw(1, 2)" diff --git a/benchmark/vm_send_cfunc.yml b/benchmark/vm_send_cfunc.yml index 6f12b65176..b114ac317d 100644 --- a/benchmark/vm_send_cfunc.yml +++ b/benchmark/vm_send_cfunc.yml @@ -1,14 +1,3 @@ -prelude: | - ary = [] - kw = {a: 1} - empty_kw = {} - kw_ary = [Hash.ruby2_keywords_hash(a: 1)] - empty_kw_ary = [Hash.ruby2_keywords_hash({})] benchmark: - vm_send_cfunc: itself - vm_send_cfunc_splat: itself(*ary) - vm_send_cfunc_splat_kw_hash: equal?(*kw_ary) - vm_send_cfunc_splat_empty_kw_hash: itself(*empty_kw_ary) - vm_send_cfunc_splat_kw: equal?(*ary, **kw) - vm_send_cfunc_splat_empty_kw: itself(*ary, **empty_kw) -loop_count: 20000000 + vm_send_cfunc: self.class +loop_count: 100000000 diff --git a/benchmark/vm_super_splat_calls.yml b/benchmark/vm_super_splat_calls.yml deleted file mode 100644 index 795e44e4da..0000000000 --- a/benchmark/vm_super_splat_calls.yml +++ /dev/null @@ -1,25 +0,0 @@ -prelude: | - @a = [1].freeze - @ea = [].freeze - @kw = {y: 1}.freeze - @b = lambda{} - extend(Module.new{def arg_splat(x=0, y: 0) end}) - extend(Module.new{def arg_splat_block(x=0, y: 0) end}) - extend(Module.new{def splat_kw_splat(x=0, y: 0) end}) - extend(Module.new{def splat_kw_splat_block(x=0, y: 0) end}) - extend(Module.new{def splat_kw(x=0, y: 0) end}) - extend(Module.new{def splat_kw_block(x=0, y: 0) end}) - - extend(Module.new{def arg_splat; super(1, *@ea) end}) - extend(Module.new{def arg_splat_block; super(1, *@ea, &@b) end}) - extend(Module.new{def splat_kw_splat; super(*@a, **@kw) end}) - extend(Module.new{def splat_kw_splat_block; super(*@a, **@kw, &@b) end}) - extend(Module.new{def splat_kw; super(*@a, y: 1) end}) - extend(Module.new{def splat_kw_block; super(*@a, y: 1, &@b) end}) -benchmark: - arg_splat: "arg_splat" - arg_splat_block: "arg_splat_block" - splat_kw_splat: "splat_kw_splat" - splat_kw_splat_block: "splat_kw_splat_block" - splat_kw: "splat_kw" - splat_kw_block: "splat_kw_block" diff --git a/benchmark/vm_zsuper_splat_calls.yml b/benchmark/vm_zsuper_splat_calls.yml deleted file mode 100644 index 82dc22349d..0000000000 --- a/benchmark/vm_zsuper_splat_calls.yml +++ /dev/null @@ -1,28 +0,0 @@ -prelude: | - a = [1].freeze - ea = [].freeze - kw = {y: 1}.freeze - b = lambda{} - extend(Module.new{def arg_splat(x=0, y: 0) end}) - extend(Module.new{def arg_splat_block(x=0, y: 0) end}) - extend(Module.new{def arg_splat_post(x=0, y: 0) end}) - extend(Module.new{def splat_kw_splat(x=0, y: 0) end}) - extend(Module.new{def splat_kw_splat_block(x=0, y: 0) end}) - extend(Module.new{def splat_kw(x=0, y: 0) end}) - extend(Module.new{def splat_kw_block(x=0, y: 0) end}) - - extend(Module.new{def arg_splat(x, *a) super end}) - extend(Module.new{def arg_splat_block(x, *a, &b) super end}) - extend(Module.new{def arg_splat_post(*a, x) super end}) - extend(Module.new{def splat_kw_splat(*a, **kw) super end}) - extend(Module.new{def splat_kw_splat_block(*a, **kw, &b) super end}) - extend(Module.new{def splat_kw(*a, y: 1) super end}) - extend(Module.new{def splat_kw_block(*a, y: 1, &b) super end}) -benchmark: - arg_splat: "arg_splat(1, *ea)" - arg_splat_block: "arg_splat_block(1, *ea, &b)" - arg_splat_post: "arg_splat_post(1, *ea, &b)" - splat_kw_splat: "splat_kw_splat(*a, **kw)" - splat_kw_splat_block: "splat_kw_splat_block(*a, **kw, &b)" - splat_kw: "splat_kw(*a, y: 1)" - splat_kw_block: "splat_kw_block(*a, y: 1, &b)" @@ -30,6 +30,9 @@ # define USE_GMP 0 #endif #endif +#if USE_GMP +# include <gmp.h> +#endif #include "id.h" #include "internal.h" @@ -45,23 +48,6 @@ #include "ruby/util.h" #include "ruby_assert.h" -#if USE_GMP -RBIMPL_WARNING_PUSH() -# ifdef _MSC_VER -RBIMPL_WARNING_IGNORED(4146) /* for mpn_neg() */ -# endif -# include <gmp.h> -RBIMPL_WARNING_POP() -#endif - -static const bool debug_integer_pack = ( -#ifdef DEBUG_INTEGER_PACK - DEBUG_INTEGER_PACK+0 -#else - RUBY_DEBUG -#endif - ) != 0; - const char ruby_digitmap[] = "0123456789abcdefghijklmnopqrstuvwxyz"; #ifndef SIZEOF_BDIGIT_DBL @@ -355,7 +341,7 @@ maxpow_in_bdigit_dbl(int base, int *exp_ret) BDIGIT_DBL maxpow; int exponent; - RUBY_ASSERT(2 <= base && base <= 36); + assert(2 <= base && base <= 36); { #if SIZEOF_BDIGIT_DBL == 2 @@ -387,7 +373,7 @@ maxpow_in_bdigit_dbl(int base, int *exp_ret) static inline BDIGIT_DBL bary2bdigitdbl(const BDIGIT *ds, size_t n) { - RUBY_ASSERT(n <= 2); + assert(n <= 2); if (n == 2) return ds[0] | BIGUP(ds[1]); @@ -399,7 +385,7 @@ bary2bdigitdbl(const BDIGIT *ds, size_t n) static inline void bdigitdbl2bary(BDIGIT *ds, size_t n, BDIGIT_DBL num) { - RUBY_ASSERT(n == 2); + assert(n == 2); ds[0] = BIGLO(num); ds[1] = (BDIGIT)BIGDN(num); @@ -430,7 +416,7 @@ bary_small_lshift(BDIGIT *zds, const BDIGIT *xds, size_t n, int shift) { size_t i; BDIGIT_DBL num = 0; - RUBY_ASSERT(0 <= shift && shift < BITSPERDIG); + assert(0 <= shift && shift < BITSPERDIG); for (i=0; i<n; i++) { num = num | (BDIGIT_DBL)*xds++ << shift; @@ -446,7 +432,7 @@ bary_small_rshift(BDIGIT *zds, const BDIGIT *xds, size_t n, int shift, BDIGIT hi size_t i; BDIGIT_DBL num = 0; - RUBY_ASSERT(0 <= shift && shift < BITSPERDIG); + assert(0 <= shift && shift < BITSPERDIG); num = BIGUP(higher_bdigit); for (i = 0; i < n; i++) { @@ -1063,13 +1049,15 @@ integer_unpack_num_bdigits(size_t numwords, size_t wordsize, size_t nails, int * if (numwords <= (SIZE_MAX - (BITSPERDIG-1)) / CHAR_BIT / wordsize) { num_bdigits = integer_unpack_num_bdigits_small(numwords, wordsize, nails, nlp_bits_ret); - if (debug_integer_pack) { +#ifdef DEBUG_INTEGER_PACK + { int nlp_bits1; size_t num_bdigits1 = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, &nlp_bits1); - RUBY_ASSERT(num_bdigits == num_bdigits1); - RUBY_ASSERT(*nlp_bits_ret == nlp_bits1); + assert(num_bdigits == num_bdigits1); + assert(*nlp_bits_ret == nlp_bits1); (void)num_bdigits1; } +#endif } else { num_bdigits = integer_unpack_num_bdigits_generic(numwords, wordsize, nails, nlp_bits_ret); @@ -1277,7 +1265,7 @@ bary_unpack_internal(BDIGIT *bdigits, size_t num_bdigits, const void *words, siz } if (dd) *dp++ = (BDIGIT)dd; - RUBY_ASSERT(dp <= de); + assert(dp <= de); while (dp < de) *dp++ = 0; #undef PUSH_BITS @@ -1336,7 +1324,7 @@ bary_unpack(BDIGIT *bdigits, size_t num_bdigits, const void *words, size_t numwo num_bdigits0 = integer_unpack_num_bdigits(numwords, wordsize, nails, &nlp_bits); - RUBY_ASSERT(num_bdigits0 <= num_bdigits); + assert(num_bdigits0 <= num_bdigits); sign = bary_unpack_internal(bdigits, num_bdigits0, words, numwords, wordsize, nails, flags, nlp_bits); @@ -1355,8 +1343,8 @@ bary_subb(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yd size_t i; size_t sn; - RUBY_ASSERT(xn <= zn); - RUBY_ASSERT(yn <= zn); + assert(xn <= zn); + assert(yn <= zn); sn = xn < yn ? xn : yn; @@ -1417,8 +1405,8 @@ bary_addc(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yd BDIGIT_DBL num; size_t i; - RUBY_ASSERT(xn <= zn); - RUBY_ASSERT(yn <= zn); + assert(xn <= zn); + assert(yn <= zn); if (xn > yn) { const BDIGIT *tds; @@ -1482,7 +1470,7 @@ bary_mul_single(BDIGIT *zds, size_t zn, BDIGIT x, BDIGIT y) { BDIGIT_DBL n; - RUBY_ASSERT(2 <= zn); + assert(2 <= zn); n = (BDIGIT_DBL)x * y; bdigitdbl2bary(zds, 2, n); @@ -1496,7 +1484,7 @@ bary_muladd_1xN(BDIGIT *zds, size_t zn, BDIGIT x, const BDIGIT *yds, size_t yn) BDIGIT_DBL dd; size_t j; - RUBY_ASSERT(zn > yn); + assert(zn > yn); if (x == 0) return 0; @@ -1531,7 +1519,7 @@ bigdivrem_mulsub(BDIGIT *zds, size_t zn, BDIGIT x, const BDIGIT *yds, size_t yn) BDIGIT_DBL t2; BDIGIT_DBL_SIGNED num; - RUBY_ASSERT(zn == yn + 1); + assert(zn == yn + 1); num = 0; t2 = 0; @@ -1556,7 +1544,7 @@ bary_mulsub_1xN(BDIGIT *zds, size_t zn, BDIGIT x, const BDIGIT *yds, size_t yn) { BDIGIT_DBL_SIGNED num; - RUBY_ASSERT(zn == yn + 1); + assert(zn == yn + 1); num = bigdivrem_mulsub(zds, zn, x, yds, yn); zds[yn] = BIGLO(num); @@ -1570,7 +1558,7 @@ bary_mul_normal(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIG { size_t i; - RUBY_ASSERT(xn + yn <= zn); + assert(xn + yn <= zn); BDIGITS_ZERO(zds, zn); for (i = 0; i < xn; i++) { @@ -1601,7 +1589,7 @@ bary_sq_fast(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn) BDIGIT vl; int vh; - RUBY_ASSERT(xn * 2 <= zn); + assert(xn * 2 <= zn); BDIGITS_ZERO(zds, zn); @@ -1673,9 +1661,9 @@ bary_mul_balance_with_mulfunc(BDIGIT *const zds, const size_t zn, VALUE work = 0; size_t n; - RUBY_ASSERT(xn + yn <= zn); - RUBY_ASSERT(xn <= yn); - RUBY_ASSERT(!KARATSUBA_BALANCED(xn, yn) || !TOOM3_BALANCED(xn, yn)); + assert(xn + yn <= zn); + assert(xn <= yn); + assert(!KARATSUBA_BALANCED(xn, yn) || !TOOM3_BALANCED(xn, yn)); BDIGITS_ZERO(zds, xn); @@ -1757,9 +1745,9 @@ bary_mul_karatsuba(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const B const BDIGIT *xds0, *xds1, *yds0, *yds1; BDIGIT *zds0, *zds1, *zds2, *zds3; - RUBY_ASSERT(xn + yn <= zn); - RUBY_ASSERT(xn <= yn); - RUBY_ASSERT(yn < 2 * xn); + assert(xn + yn <= zn); + assert(xn <= yn); + assert(yn < 2 * xn); sq = xds == yds && xn == yn; @@ -1774,7 +1762,7 @@ bary_mul_karatsuba(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const B n = yn / 2; - RUBY_ASSERT(n < xn); + assert(n < xn); if (wn < n) { /* This function itself needs only n BDIGITs for work area. @@ -1895,7 +1883,7 @@ bary_mul_karatsuba(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const B for (x = 0, i = xn-1; 0 <= i; i--) { x <<= SIZEOF_BDIGIT*CHAR_BIT; x |= xds[i]; } for (y = 0, i = yn-1; 0 <= i; i--) { y <<= SIZEOF_BDIGIT*CHAR_BIT; y |= yds[i]; } for (z = 0, i = zn-1; 0 <= i; i--) { z <<= SIZEOF_BDIGIT*CHAR_BIT; z |= zds[i]; } - RUBY_ASSERT(z == x * y); + assert(z == x * y); } */ @@ -1963,11 +1951,11 @@ bary_mul_toom3(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGI int sq = xds == yds && xn == yn; - RUBY_ASSERT(xn <= yn); /* assume y >= x */ - RUBY_ASSERT(xn + yn <= zn); + assert(xn <= yn); /* assume y >= x */ + assert(xn + yn <= zn); n = (yn + 2) / 3; - RUBY_ASSERT(2*n < xn); + assert(2*n < xn); wnc = 0; @@ -2154,19 +2142,19 @@ bary_mul_toom3(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGI /* z(1) : t1 <- u1 * v1 */ bary_mul_toom3_start(t1ds, t1n, u1ds, u1n, v1ds, v1n, wds, wn); t1p = u1p == v1p; - RUBY_ASSERT(t1ds[t1n-1] == 0); + assert(t1ds[t1n-1] == 0); t1n--; /* z(-1) : t2 <- u2 * v2 */ bary_mul_toom3_start(t2ds, t2n, u2ds, u2n, v2ds, v2n, wds, wn); t2p = u2p == v2p; - RUBY_ASSERT(t2ds[t2n-1] == 0); + assert(t2ds[t2n-1] == 0); t2n--; /* z(-2) : t3 <- u3 * v3 */ bary_mul_toom3_start(t3ds, t3n, u3ds, u3n, v3ds, v3n, wds, wn); t3p = u3p == v3p; - RUBY_ASSERT(t3ds[t3n-1] == 0); + assert(t3ds[t3n-1] == 0); t3n--; /* z(inf) : t4 <- x2 * y2 */ @@ -2342,7 +2330,7 @@ bary_mul_gmp(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT mpz_t x, y, z; size_t count; - RUBY_ASSERT(xn + yn <= zn); + assert(xn + yn <= zn); mpz_init(x); mpz_init(y); @@ -2377,7 +2365,7 @@ rb_big_mul_gmp(VALUE x, VALUE y) static void bary_short_mul(BDIGIT *zds, size_t zn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn) { - RUBY_ASSERT(xn + yn <= zn); + assert(xn + yn <= zn); if (xn == 1 && yn == 1) { bary_mul_single(zds, zn, xds[0], yds[0]); @@ -2413,7 +2401,7 @@ bary_mul_precheck(BDIGIT **zdsp, size_t *znp, const BDIGIT **xdsp, size_t *xnp, const BDIGIT *yds = *ydsp; size_t yn = *ynp; - RUBY_ASSERT(xn + yn <= zn); + assert(xn + yn <= zn); nlsz = 0; @@ -2462,7 +2450,7 @@ bary_mul_precheck(BDIGIT **zdsp, size_t *znp, const BDIGIT **xdsp, size_t *xnp, tds = xds; xds = yds; yds = tds; tn = xn; xn = yn; yn = tn; } - RUBY_ASSERT(xn <= yn); + assert(xn <= yn); if (xn <= 1) { if (xn == 0) { @@ -2645,8 +2633,8 @@ rb_big_stop(void *ptr) static BDIGIT bigdivrem_single1(BDIGIT *qds, const BDIGIT *xds, size_t xn, BDIGIT x_higher_bdigit, BDIGIT y) { - RUBY_ASSERT(0 < xn); - RUBY_ASSERT(x_higher_bdigit < y); + assert(0 < xn); + assert(x_higher_bdigit < y); if (POW2_P(y)) { BDIGIT r; r = xds[0] & (y-1); @@ -2678,9 +2666,9 @@ bigdivrem_restoring(BDIGIT *zds, size_t zn, BDIGIT *yds, size_t yn) struct big_div_struct bds; size_t ynzero; - RUBY_ASSERT(yn < zn); - RUBY_ASSERT(BDIGIT_MSB(yds[yn-1])); - RUBY_ASSERT(zds[zn-1] < yds[yn-1]); + assert(yn < zn); + assert(BDIGIT_MSB(yds[yn-1])); + assert(zds[zn-1] < yds[yn-1]); for (ynzero = 0; !yds[ynzero]; ynzero++); @@ -2719,9 +2707,9 @@ bary_divmod_normal(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT size_t zn; VALUE tmpyz = 0; - RUBY_ASSERT(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1])); - RUBY_ASSERT(qds ? (xn - yn + 1) <= qn : 1); - RUBY_ASSERT(rds ? yn <= rn : 1); + assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1])); + assert(qds ? (xn - yn + 1) <= qn : 1); + assert(rds ? yn <= rn : 1); zn = xn + BIGDIVREM_EXTRA_WORDS; @@ -2813,10 +2801,10 @@ bary_divmod_gmp(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xd mpz_t x, y, q, r; size_t count; - RUBY_ASSERT(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1])); - RUBY_ASSERT(qds ? (xn - yn + 1) <= qn : 1); - RUBY_ASSERT(rds ? yn <= rn : 1); - RUBY_ASSERT(qds || rds); + assert(yn < xn || (xn == yn && yds[yn - 1] <= xds[xn - 1])); + assert(qds ? (xn - yn + 1) <= qn : 1); + assert(rds ? yn <= rn : 1); + assert(qds || rds); mpz_init(x); mpz_init(y); @@ -2902,8 +2890,8 @@ bary_divmod_branch(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT static void bary_divmod(BDIGIT *qds, size_t qn, BDIGIT *rds, size_t rn, const BDIGIT *xds, size_t xn, const BDIGIT *yds, size_t yn) { - RUBY_ASSERT(xn <= qn); - RUBY_ASSERT(yn <= rn); + assert(xn <= qn); + assert(yn <= rn); BARY_TRUNC(yds, yn); if (yn == 0) @@ -3035,8 +3023,7 @@ rb_big_resize(VALUE big, size_t len) static VALUE bignew_1(VALUE klass, size_t len, int sign) { - NEWOBJ_OF(big, struct RBignum, klass, - T_BIGNUM | (RGENGC_WB_PROTECTED_BIGNUM ? FL_WB_PROTECTED : 0), sizeof(struct RBignum), 0); + NEWOBJ_OF(big, struct RBignum, klass, T_BIGNUM | (RGENGC_WB_PROTECTED_BIGNUM ? FL_WB_PROTECTED : 0)); VALUE bigv = (VALUE)big; BIGNUM_SET_SIGN(bigv, sign); if (len <= BIGNUM_EMBED_LEN_MAX) { @@ -3435,13 +3422,15 @@ rb_absint_numwords(VALUE val, size_t word_numbits, size_t *nlz_bits_ret) if (numbytes <= SIZE_MAX / CHAR_BIT) { numwords = absint_numwords_small(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits); - if (debug_integer_pack) { +#ifdef DEBUG_INTEGER_PACK + { size_t numwords0, nlz_bits0; numwords0 = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits0); - RUBY_ASSERT(numwords0 == numwords); - RUBY_ASSERT(nlz_bits0 == nlz_bits); + assert(numwords0 == numwords); + assert(nlz_bits0 == nlz_bits); (void)numwords0; } +#endif } else { numwords = absint_numwords_generic(numbytes, nlz_bits_in_msbyte, word_numbits, &nlz_bits); @@ -3854,7 +3843,7 @@ str2big_poweroftwo( if (numbits) { *dp++ = BIGLO(dd); } - RUBY_ASSERT((size_t)(dp - BDIGITS(z)) == num_bdigits); + assert((size_t)(dp - BDIGITS(z)) == num_bdigits); return z; } @@ -3897,7 +3886,7 @@ str2big_normal( } break; } - RUBY_ASSERT(blen <= num_bdigits); + assert(blen <= num_bdigits); } return z; @@ -3955,7 +3944,7 @@ str2big_karatsuba( current_base = 1; } } - RUBY_ASSERT(i == num_bdigits); + assert(i == num_bdigits); for (unit = 2; unit < num_bdigits; unit *= 2) { for (i = 0; i < num_bdigits; i += unit*2) { if (2*unit <= num_bdigits - i) { @@ -4100,8 +4089,8 @@ rb_int_parse_cstr(const char *str, ssize_t len, char **endp, size_t *ndigits, len -= (n); \ } while (0) #define ASSERT_LEN() do {\ - RUBY_ASSERT(len != 0); \ - if (len0 >= 0) RUBY_ASSERT(s + len0 == str + len); \ + assert(len != 0); \ + if (len0 >= 0) assert(s + len0 == str + len); \ } while (0) if (!str) { @@ -4552,7 +4541,7 @@ rb_uint128t2big(uint128_t n) return big; } -VALUE +MJIT_FUNC_EXPORTED VALUE rb_int128t2big(int128_t n) { int neg = 0; @@ -4646,8 +4635,8 @@ big_shift2(VALUE x, int lshift_p, VALUE y) size_t shift_numdigits; int shift_numbits; - RUBY_ASSERT(POW2_P(CHAR_BIT)); - RUBY_ASSERT(POW2_P(BITSPERDIG)); + assert(POW2_P(CHAR_BIT)); + assert(POW2_P(BITSPERDIG)); if (BIGZEROP(x)) return INT2FIX(0); @@ -4734,7 +4723,7 @@ power_cache_get_power(int base, int power_level, size_t *numdigits_ret) rb_obj_hide(power); base36_power_cache[base - 2][power_level] = power; base36_numdigits_cache[base - 2][power_level] = numdigits; - rb_vm_register_global_object(power); + rb_gc_register_mark_object(power); } if (numdigits_ret) *numdigits_ret = base36_numdigits_cache[base - 2][power_level]; @@ -4770,7 +4759,7 @@ big2str_2bdigits(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t tail int beginning = !b2s->ptr; size_t len = 0; - RUBY_ASSERT(xn <= 2); + assert(xn <= 2); num = bary2bdigitdbl(xds, xn); if (beginning) { @@ -4898,7 +4887,7 @@ big2str_karatsuba(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t wn, /* bigdivrem_restoring will modify y. * So use temporary buffer. */ tds = xds + qn; - RUBY_ASSERT(qn + bn <= xn + wn); + assert(qn + bn <= xn + wn); bary_small_lshift(tds, bds, bn, shift); xds[xn] = bary_small_lshift(xds, xds, xn, shift); } @@ -4916,7 +4905,7 @@ big2str_karatsuba(struct big2str_struct *b2s, BDIGIT *xds, size_t xn, size_t wn, } BARY_TRUNC(qds, qn); - RUBY_ASSERT(qn <= bn); + assert(qn <= bn); big2str_karatsuba(b2s, qds, qn, xn+wn - (rn+qn), lower_power_level, lower_numdigits+taillen); BARY_TRUNC(rds, rn); big2str_karatsuba(b2s, rds, rn, xn+wn - rn, lower_power_level, taillen); @@ -4981,7 +4970,7 @@ big2str_generic(VALUE x, int base) invalid_radix(base); if (xn >= LONG_MAX/BITSPERDIG) { - rb_raise(rb_eRangeError, "bignum too big to convert into 'string'"); + rb_raise(rb_eRangeError, "bignum too big to convert into `string'"); } power_level = 0; @@ -4991,7 +4980,7 @@ big2str_generic(VALUE x, int base) power_level++; power = power_cache_get_power(base, power_level, NULL); } - RUBY_ASSERT(power_level != MAX_BASE36_POWER_TABLE_ENTRIES); + assert(power_level != MAX_BASE36_POWER_TABLE_ENTRIES); if ((size_t)BIGNUM_LEN(power) <= xn) { /* @@ -5106,7 +5095,7 @@ rb_big2str1(VALUE x, int base) invalid_radix(base); if (xn >= LONG_MAX/BITSPERDIG) { - rb_raise(rb_eRangeError, "bignum too big to convert into 'string'"); + rb_raise(rb_eRangeError, "bignum too big to convert into `string'"); } if (POW2_P(base)) { @@ -5142,7 +5131,7 @@ big2ulong(VALUE x, const char *type) if (len == 0) return 0; if (BIGSIZE(x) > sizeof(long)) { - rb_raise(rb_eRangeError, "bignum too big to convert into '%s'", type); + rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type); } ds = BDIGITS(x); #if SIZEOF_LONG <= SIZEOF_BDIGIT @@ -5185,7 +5174,7 @@ rb_big2long(VALUE x) if (num <= 1+(unsigned long)(-(LONG_MIN+1))) return -(long)(num-1)-1; } - rb_raise(rb_eRangeError, "bignum too big to convert into 'long'"); + rb_raise(rb_eRangeError, "bignum too big to convert into `long'"); } #if HAVE_LONG_LONG @@ -5203,7 +5192,7 @@ big2ull(VALUE x, const char *type) if (len == 0) return 0; if (BIGSIZE(x) > SIZEOF_LONG_LONG) - rb_raise(rb_eRangeError, "bignum too big to convert into '%s'", type); + rb_raise(rb_eRangeError, "bignum too big to convert into `%s'", type); #if SIZEOF_LONG_LONG <= SIZEOF_BDIGIT num = (unsigned LONG_LONG)ds[0]; #else @@ -5244,7 +5233,7 @@ rb_big2ll(VALUE x) if (num <= 1+(unsigned LONG_LONG)(-(LLONG_MIN+1))) return -(LONG_LONG)(num-1)-1; } - rb_raise(rb_eRangeError, "bignum too big to convert into 'long long'"); + rb_raise(rb_eRangeError, "bignum too big to convert into `long long'"); } #endif /* HAVE_LONG_LONG */ @@ -5507,10 +5496,10 @@ big_op(VALUE x, VALUE y, enum big_op_t op) n = FIX2INT(rel); switch (op) { - case big_op_gt: return RBOOL(n > 0); - case big_op_ge: return RBOOL(n >= 0); - case big_op_lt: return RBOOL(n < 0); - case big_op_le: return RBOOL(n <= 0); + case big_op_gt: return RBOOL(n > 0); + case big_op_ge: return RBOOL(n >= 0); + case big_op_lt: return RBOOL(n < 0); + case big_op_le: return RBOOL(n <= 0); } return Qundef; } @@ -5666,7 +5655,7 @@ bigsub_int(VALUE x, long y0) zds = BDIGITS(z); #if SIZEOF_BDIGIT >= SIZEOF_LONG - RUBY_ASSERT(xn == zn); + assert(xn == zn); num = (BDIGIT_DBL_SIGNED)xds[0] - y; if (xn == 1 && num < 0) { BIGNUM_NEGATE(z); @@ -5729,7 +5718,7 @@ bigsub_int(VALUE x, long y0) goto finish; finish: - RUBY_ASSERT(num == 0 || num == -1); + assert(num == 0 || num == -1); if (num < 0) { get2comp(z); BIGNUM_NEGATE(z); @@ -6884,11 +6873,63 @@ BDIGIT rb_bdigit_dbl_isqrt(BDIGIT_DBL); # define BDIGIT_DBL_TO_DOUBLE(n) (double)(n) #endif +static BDIGIT * +estimate_initial_sqrt(VALUE *xp, const size_t xn, const BDIGIT *nds, size_t len) +{ + enum {dbl_per_bdig = roomof(DBL_MANT_DIG,BITSPERDIG)}; + const int zbits = nlz(nds[len-1]); + VALUE x = *xp = bignew_1(0, xn, 1); /* division may release the GVL */ + BDIGIT *xds = BDIGITS(x); + BDIGIT_DBL d = bary2bdigitdbl(nds+len-dbl_per_bdig, dbl_per_bdig); + BDIGIT lowbits = 1; + int rshift = (int)((BITSPERDIG*2-zbits+(len&BITSPERDIG&1) - DBL_MANT_DIG + 1) & ~1); + double f; + + if (rshift > 0) { + lowbits = (BDIGIT)d & ~(~(BDIGIT)1U << rshift); + d >>= rshift; + } + else if (rshift < 0) { + d <<= -rshift; + d |= nds[len-dbl_per_bdig-1] >> (BITSPERDIG+rshift); + } + f = sqrt(BDIGIT_DBL_TO_DOUBLE(d)); + d = (BDIGIT_DBL)ceil(f); + if (BDIGIT_DBL_TO_DOUBLE(d) == f) { + if (lowbits || (lowbits = !bary_zero_p(nds, len-dbl_per_bdig))) + ++d; + } + else { + lowbits = 1; + } + rshift /= 2; + rshift += (2-(len&1))*BITSPERDIG/2; + if (rshift >= 0) { + if (nlz((BDIGIT)d) + rshift >= BITSPERDIG) { + /* (d << rshift) does cause overflow. + * example: Integer.sqrt(0xffff_ffff_ffff_ffff ** 2) + */ + d = ~(BDIGIT_DBL)0; + } + else { + d <<= rshift; + } + } + BDIGITS_ZERO(xds, xn-2); + bdigitdbl2bary(&xds[xn-2], 2, d); + + if (!lowbits) return NULL; /* special case, exact result */ + return xds; +} + VALUE rb_big_isqrt(VALUE n) { BDIGIT *nds = BDIGITS(n); size_t len = BIGNUM_LEN(n); + size_t xn = (len+1) / 2; + VALUE x; + BDIGIT *xds; if (len <= 2) { BDIGIT sq = rb_bdigit_dbl_isqrt(bary2bdigitdbl(nds, len)); @@ -6898,19 +6939,25 @@ rb_big_isqrt(VALUE n) return ULONG2NUM(sq); #endif } - else { - size_t shift = FIX2LONG(rb_big_bit_length(n)) / 4; - VALUE n2 = rb_int_rshift(n, SIZET2NUM(2 * shift)); - VALUE x = FIXNUM_P(n2) ? LONG2FIX(rb_ulong_isqrt(FIX2ULONG(n2))) : rb_big_isqrt(n2); - /* x = (x+n/x)/2 */ - x = rb_int_plus(rb_int_lshift(x, SIZET2NUM(shift - 1)), rb_int_idiv(rb_int_rshift(n, SIZET2NUM(shift + 1)), x)); - VALUE xx = rb_int_mul(x, x); - while (rb_int_gt(xx, n)) { - xx = rb_int_minus(xx, rb_int_minus(rb_int_plus(x, x), INT2FIX(1))); - x = rb_int_minus(x, INT2FIX(1)); + else if ((xds = estimate_initial_sqrt(&x, xn, nds, len)) != 0) { + size_t tn = xn + BIGDIVREM_EXTRA_WORDS; + VALUE t = bignew_1(0, tn, 1); + BDIGIT *tds = BDIGITS(t); + tn = BIGNUM_LEN(t); + + /* t = n/x */ + while (bary_divmod_branch(tds, tn, NULL, 0, nds, len, xds, xn), + bary_cmp(tds, tn, xds, xn) < 0) { + int carry; + BARY_TRUNC(tds, tn); + /* x = (x+t)/2 */ + carry = bary_add(xds, xn, xds, xn, tds, tn); + bary_small_rshift(xds, xds, xn, 1, carry); + tn = BIGNUM_LEN(t); } - return x; } + RBASIC_SET_CLASS_RAW(x, rb_cInteger); + return x; } #if USE_GMP @@ -6949,7 +6996,7 @@ int_pow_tmp3(VALUE x, VALUE y, VALUE m, int nega_flg) if (FIXNUM_P(y)) { y = rb_int2big(FIX2LONG(y)); } - RUBY_ASSERT(RB_BIGNUM_TYPE_P(m)); + assert(RB_BIGNUM_TYPE_P(m)); xn = BIGNUM_LEN(x); yn = BIGNUM_LEN(y); mn = BIGNUM_LEN(m); @@ -1,6 +1,4 @@ #!/usr/bin/env ruby -# frozen_string_literal: true - #-- # Copyright 2006 by Chad Fowler, Rich Kilmer, Jim Weirich and others. # All rights reserved. diff --git a/bootstraptest/runner.rb b/bootstraptest/runner.rb index 24324fa51f..f9b3e919b8 100755 --- a/bootstraptest/runner.rb +++ b/bootstraptest/runner.rb @@ -6,6 +6,7 @@ # Never use optparse in this file. # Never use test/unit in this file. # Never use Ruby extensions in this file. +# Maintain Ruby 1.8 compatibility for now $start_time = Time.now @@ -76,9 +77,6 @@ bt = Struct.new(:ruby, :width, :indent, :platform, - :timeout, - :timeout_scale, - :launchable_test_reports ) BT = Class.new(bt) do def indent=(n) @@ -120,7 +118,7 @@ BT = Class.new(bt) do r = IO.for_fd($1.to_i(10), "rb", autoclose: false) w = IO.for_fd($2.to_i(10), "wb", autoclose: false) end - rescue + rescue => e r.close if r else r.close_on_exec = true @@ -146,10 +144,6 @@ BT = Class.new(bt) do end super wn end - - def apply_timeout_scale(timeout) - timeout&.*(timeout_scale) - end end.new BT_STATE = Struct.new(:count, :error).new @@ -162,12 +156,6 @@ def main BT.color = nil BT.tty = nil BT.quiet = false - BT.timeout = 180 - BT.timeout_scale = (defined?(RubyVM::RJIT) && RubyVM::RJIT.enabled? ? 3 : 1) # for --jit-wait - if (ts = (ENV["RUBY_TEST_TIMEOUT_SCALE"] || ENV["RUBY_TEST_SUBPROCESS_TIMEOUT_SCALE"]).to_i) > 1 - BT.timeout_scale *= ts - end - # BT.wn = 1 dir = nil quiet = false @@ -198,18 +186,14 @@ def main warn "unknown --tty argument: #$3" if $3 BT.tty = !$1 || !$2 true - when /\A(-q|--q(uiet)?)\z/ + when /\A(-q|--q(uiet))\z/ quiet = true BT.quiet = true true when /\A-j(\d+)?/ BT.wn = $1.to_i true - when /\A--timeout=(\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?)(?::(\d+(?:_\d+)*(?:\.\d+(?:_\d+)*)?))?/ - BT.timeout = $1.to_f - BT.timeout_scale = $2.to_f if defined?($2) - true - when /\A(-v|--v(erbose)?)\z/ + when /\A(-v|--v(erbose))\z/ BT.verbose = true BT.quiet = false true @@ -221,7 +205,6 @@ Usage: #{File.basename($0, '.*')} --ruby=PATH [--sets=NAME,NAME,...] default: /tmp/bootstraptestXXXXX.tmpwd --color[=WHEN] Colorize the output. WHEN defaults to 'always' or can be 'never' or 'auto'. - --timeout=TIMEOUT Default timeout in seconds. -s, --stress stress test. -v, --verbose Output test name before exec. -q, --quiet Don\'t print header message. @@ -230,19 +213,6 @@ End exit true when /\A-j/ true - when /--launchable-test-reports=(.*)/ - if File.exist?($1) - # To protect files from overwritten, do nothing when the file exists. - return true - end - - require_relative '../tool/lib/launchable' - BT.launchable_test_reports = writer = Launchable::JsonStreamWriter.new($1) - writer.write_array('testCases') - at_exit { - writer.close - } - true else false end @@ -252,7 +222,7 @@ End end tests ||= ARGV tests = Dir.glob("#{File.dirname($0)}/test_*.rb").sort if tests.empty? - paths = tests.map {|path| File.expand_path(path) } + pathes = tests.map {|path| File.expand_path(path) } BT.progress = %w[- \\ | /] BT.progress_bs = "\b" * BT.progress[0].size @@ -296,7 +266,7 @@ End end in_temporary_working_directory(dir) do - exec_test paths + exec_test pathes end end @@ -308,8 +278,8 @@ def erase(e = true) end end -def load_test paths - paths.each do |path| +def load_test pathes + pathes.each do |path| load File.expand_path(path) end end @@ -359,66 +329,13 @@ def concurrent_exec_test end end -## -# Module for writing a test file for uploading test results into Launchable. -# In bootstraptest, we aggregate the test results based on file level. -module Launchable - @@last_test_name = nil - @@failure_log = '' - @@duration = 0 - - def show_progress(message = '') - faildesc, t = super - - if writer = BT.launchable_test_reports - if faildesc - @@failure_log += faildesc - end - repo_path = File.expand_path("#{__dir__}/../") - relative_path = File.join(__dir__, self.path).delete_prefix("#{repo_path}/") - if @@last_test_name != nil && @@last_test_name != relative_path - # The test path is a URL-encoded representation. - # https://github.com/launchableinc/cli/blob/v1.81.0/launchable/testpath.py#L18 - test_path = "#{encode_test_path_component("file")}=#{encode_test_path_component(@@last_test_name)}" - if @@failure_log.size > 0 - status = 'TEST_FAILED' - else - status = 'TEST_PASSED' - end - writer.write_object( - { - testPath: test_path, - status: status, - duration: t, - createdAt: Time.now.to_s, - stderr: @@failure_log, - stdout: nil, - data: { - lineNumber: self.lineno - } - } - ) - @@duration = 0 - @@failure_log.clear - end - @@last_test_name = relative_path - @@duration += t - end - end - - private - def encode_test_path_component component - component.to_s.gsub('%', '%25').gsub('=', '%3D').gsub('#', '%23').gsub('&', '%26') - end -end - -def exec_test(paths) +def exec_test(pathes) # setup - load_test paths + load_test pathes BT_STATE.count = 0 BT_STATE.error = 0 BT.columns = 0 - BT.width = paths.map {|path| File.basename(path).size}.max + 2 + BT.width = pathes.map {|path| File.basename(path).size}.max + 2 # execute tests if BT.wn > 1 @@ -488,7 +405,6 @@ def target_platform end class Assertion < Struct.new(:src, :path, :lineno, :proc) - prepend Launchable @count = 0 @all = Hash.new{|h, k| h[k] = []} @errbuf = [] @@ -512,7 +428,7 @@ class Assertion < Struct.new(:src, :path, :lineno, :proc) def initialize(*args) super self.class.add self - @category = self.path[/\Atest_(.+)\.rb\z/, 1] + @category = self.path.match(/test_(.+)\.rb/)[1] end def call @@ -563,9 +479,9 @@ class Assertion < Struct.new(:src, :path, :lineno, :proc) $stderr.print "#{BT.progress_bs}#{BT.progress[BT_STATE.count % BT.progress.size]}" end - t = Time.now if BT.verbose || BT.launchable_test_reports + t = Time.now if BT.verbose faildesc, errout = with_stderr {yield} - t = Time.now - t if BT.verbose || BT.launchable_test_reports + t = Time.now - t if BT.verbose if !faildesc # success @@ -592,8 +508,6 @@ class Assertion < Struct.new(:src, :path, :lineno, :proc) $stderr.printf("%-*s%s", BT.width, path, BT.progress[BT_STATE.count % BT.progress.size]) end end - - [faildesc, t] rescue Interrupt $stderr.puts "\##{@id} #{path}:#{lineno}" raise @@ -612,16 +526,14 @@ class Assertion < Struct.new(:src, :path, :lineno, :proc) end end - def get_result_string(opt = '', timeout: BT.timeout, **argh) + def get_result_string(opt = '', **argh) if BT.ruby - timeout = BT.apply_timeout_scale(timeout) filename = make_srcfile(**argh) begin kw = self.err ? {err: self.err} : {} out = IO.popen("#{BT.ruby} -W0 #{opt} #{filename}", **kw) pid = out.pid - th = Thread.new {out.read.tap {Process.waitpid(pid); out.close}} - th.value if th.join(timeout) + out.read.tap{ Process.waitpid(pid); out.close } ensure raise Interrupt if $? and $?.signaled? && $?.termsig == Signal.list["INT"] @@ -639,14 +551,9 @@ class Assertion < Struct.new(:src, :path, :lineno, :proc) def make_srcfile(frozen_string_literal: nil) filename = "bootstraptest.#{self.path}_#{self.lineno}_#{self.id}.rb" File.open(filename, 'w') {|f| - f.puts "#frozen_string_literal:#{frozen_string_literal}" unless frozen_string_literal.nil? - if $stress - f.puts "GC.stress = true" if $stress - else - f.puts "" - end - f.puts "class BT_Skip < Exception; end; def skip(msg) = raise(BT_Skip, msg.to_s)" - f.puts "print(begin; #{self.src}; rescue BT_Skip; $!.message; end)" + f.puts "#frozen_string_literal:true" if frozen_string_literal + f.puts "GC.stress = true" if $stress + f.puts "print(begin; #{self.src}; end)" } filename end @@ -660,9 +567,9 @@ def add_assertion src, pr Assertion.new(src, path, lineno, pr) end -def assert_equal(expected, testsrc, message = '', opt = '', **kwargs) +def assert_equal(expected, testsrc, message = '', opt = '', **argh) add_assertion testsrc, -> as do - as.assert_check(message, opt, **kwargs) {|result| + as.assert_check(message, opt, **argh) {|result| if expected == result nil else @@ -673,9 +580,9 @@ def assert_equal(expected, testsrc, message = '', opt = '', **kwargs) end end -def assert_match(expected_pattern, testsrc, message = '', **argh) +def assert_match(expected_pattern, testsrc, message = '') add_assertion testsrc, -> as do - as.assert_check(message, **argh) {|result| + as.assert_check(message) {|result| if expected_pattern =~ result nil else @@ -707,9 +614,8 @@ def assert_valid_syntax(testsrc, message = '') end end -def assert_normal_exit(testsrc, *rest, timeout: BT.timeout, **opt) +def assert_normal_exit(testsrc, *rest, timeout: nil, **opt) add_assertion testsrc, -> as do - timeout = BT.apply_timeout_scale(timeout) message, ignore_signals = rest message ||= '' as.show_progress(message) { @@ -718,19 +624,23 @@ def assert_normal_exit(testsrc, *rest, timeout: BT.timeout, **opt) timeout_signaled = false logfile = "assert_normal_exit.#{as.path}.#{as.lineno}.log" - io = IO.popen("#{BT.ruby} -W0 #{filename}", err: logfile) - pid = io.pid - th = Thread.new { - io.read - io.close - $? - } - if !th.join(timeout) - Process.kill :KILL, pid - timeout_signaled = true + begin + err = open(logfile, "w") + io = IO.popen("#{BT.ruby} -W0 #{filename}", err: err) + pid = io.pid + th = Thread.new { + io.read + io.close + $? + } + if !th.join(timeout) + Process.kill :KILL, pid + timeout_signaled = true + end + status = th.value + ensure + err.close end - status = th.value - if status && status.signaled? signo = status.termsig signame = Signal.list.invert[signo] @@ -759,7 +669,9 @@ end def assert_finish(timeout_seconds, testsrc, message = '') add_assertion testsrc, -> as do - timeout_seconds = BT.apply_timeout_scale(timeout_seconds) + if defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # for --jit-wait + timeout_seconds *= 3 + end as.show_progress(message) { faildesc = nil @@ -815,8 +727,6 @@ end def pretty(src, desc, result) src = src.sub(/\A\s*\n/, '') - lines = src.lines - src = lines[0..20].join + "(...snip)\n" if lines.size > 20 (/\n/ =~ src ? "\n#{adjust_indent(src)}" : src) + " #=> #{desc}" end @@ -874,13 +784,4 @@ def check_coredump end end -def yjit_enabled? - ENV.key?('RUBY_YJIT_ENABLE') || ENV.fetch('RUN_OPTS', '').include?('yjit') || BT.ruby.include?('yjit') -end - -def rjit_enabled? - # Don't check `RubyVM::RJIT.enabled?`. On btest-bruby, target Ruby != runner Ruby. - ENV.fetch('RUN_OPTS', '').include?('rjit') -end - exit main diff --git a/bootstraptest/test_autoload.rb b/bootstraptest/test_autoload.rb index de66f1f3ee..9e0850bc52 100644 --- a/bootstraptest/test_autoload.rb +++ b/bootstraptest/test_autoload.rb @@ -11,7 +11,7 @@ assert_equal 'ok', %q{ }, '[ruby-dev:43816]' assert_equal 'ok', %q{ - File.write('zzz2.rb', '') + open('zzz2.rb', 'w') {|f| f.puts '' } instance_eval do autoload :ZZZ, './zzz2.rb' begin @@ -23,7 +23,7 @@ assert_equal 'ok', %q{ }, '[ruby-dev:43816]' assert_equal 'ok', %q{ - File.write('zzz3.rb', "class ZZZ; def self.ok;:ok;end;end\n") + open('zzz3.rb', 'w') {|f| f.puts 'class ZZZ; def self.ok;:ok;end;end'} instance_eval do autoload :ZZZ, './zzz3.rb' ZZZ.ok @@ -31,20 +31,20 @@ assert_equal 'ok', %q{ }, '[ruby-dev:43816]' assert_equal 'ok', %q{ - File.write("zzz4.rb", "class ZZZ; def self.ok;:ok;end;end\n") + open("zzz4.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"} autoload :ZZZ, "./zzz4.rb" ZZZ.ok } assert_equal 'ok', %q{ - File.write("zzz5.rb", "class ZZZ; def self.ok;:ok;end;end\n") + open("zzz5.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"} autoload :ZZZ, "./zzz5.rb" require "./zzz5.rb" ZZZ.ok } assert_equal 'okok', %q{ - File.write("zzz6.rb", "class ZZZ; def self.ok;:ok;end;end\n") + open("zzz6.rb", "w") {|f| f.puts "class ZZZ; def self.ok;:ok;end;end"} autoload :ZZZ, "./zzz6.rb" t1 = Thread.new {ZZZ.ok} t2 = Thread.new {ZZZ.ok} @@ -60,7 +60,7 @@ assert_finish 5, %q{ }, '[ruby-core:21696]' assert_equal 'A::C', %q{ - File.write("zzz7.rb", "") + open("zzz7.rb", "w") {} class A autoload :C, "./zzz7" class C diff --git a/bootstraptest/test_eval.rb b/bootstraptest/test_eval.rb index 20bd9615f4..a9f389c673 100644 --- a/bootstraptest/test_eval.rb +++ b/bootstraptest/test_eval.rb @@ -217,7 +217,7 @@ assert_equal %q{[10, main]}, %q{ } %w[break next redo].each do |keyword| - assert_match %r"Invalid #{keyword}\b", %{ + assert_match %r"Can't escape from eval with #{keyword}\b", %{ $stderr = STDOUT begin eval "0 rescue #{keyword}" @@ -227,16 +227,6 @@ assert_equal %q{[10, main]}, %q{ }, '[ruby-dev:31372]' end -assert_normal_exit %{ - $stderr = STDOUT - 5000.times do - begin - eval "0 rescue break" - rescue SyntaxError - end - end -} - assert_normal_exit %q{ $stderr = STDOUT class Foo @@ -364,34 +354,3 @@ assert_normal_exit %q{ end }, 'check escaping the internal value th->base_block' -assert_equal "false", <<~RUBY, "literal strings are mutable", "--disable-frozen-string-literal" - eval("'test'").frozen? -RUBY - -assert_equal "false", <<~RUBY, "literal strings are mutable", "--disable-frozen-string-literal", frozen_string_literal: true - eval("'test'").frozen? -RUBY - -assert_equal "true", <<~RUBY, "literal strings are frozen", "--enable-frozen-string-literal" - eval("'test'").frozen? -RUBY - -assert_equal "true", <<~RUBY, "literal strings are frozen", "--enable-frozen-string-literal", frozen_string_literal: false - eval("'test'").frozen? -RUBY - -assert_equal "false", <<~RUBY, "__FILE__ is mutable", "--disable-frozen-string-literal" - eval("__FILE__").frozen? -RUBY - -assert_equal "false", <<~RUBY, "__FILE__ is mutable", "--disable-frozen-string-literal", frozen_string_literal: true - eval("__FILE__").frozen? -RUBY - -assert_equal "true", <<~RUBY, "__FILE__ is frozen", "--enable-frozen-string-literal" - eval("__FILE__").frozen? -RUBY - -assert_equal "true", <<~RUBY, "__FILE__ is frozen", "--enable-frozen-string-literal", frozen_string_literal: false - eval("__FILE__").frozen? -RUBY diff --git a/bootstraptest/test_exception.rb b/bootstraptest/test_exception.rb index decfdc08a3..0fb6f552b8 100644 --- a/bootstraptest/test_exception.rb +++ b/bootstraptest/test_exception.rb @@ -370,7 +370,7 @@ assert_equal %q{}, %q{ } ## -assert_match /undefined method 'foo\'/, %q{#` +assert_match /undefined method `foo\'/, %q{#` STDERR.reopen(STDOUT) class C def inspect diff --git a/bootstraptest/test_finalizer.rb b/bootstraptest/test_finalizer.rb index ccfa0b55d6..22a16b1220 100644 --- a/bootstraptest/test_finalizer.rb +++ b/bootstraptest/test_finalizer.rb @@ -6,11 +6,3 @@ ObjectSpace.define_finalizer(b1,proc{b1.inspect}) ObjectSpace.define_finalizer(a2,proc{a1.inspect}) ObjectSpace.define_finalizer(a1,proc{}) }, '[ruby-dev:35778]' - -assert_equal 'true', %q{ - obj = Object.new - id = obj.object_id - - ObjectSpace.define_finalizer(obj, proc { |i| print(id == i) }) - nil -} diff --git a/bootstraptest/test_flow.rb b/bootstraptest/test_flow.rb index 15528a4213..35f19db588 100644 --- a/bootstraptest/test_flow.rb +++ b/bootstraptest/test_flow.rb @@ -363,7 +363,7 @@ assert_equal %q{[1, 2, 3, 5, 2, 3, 5, 7, 8]}, %q{$a = []; begin; ; $a << 1 ; $a << 8 ; rescue Exception; $a << 99; end; $a} assert_equal %q{[1, 2, 6, 3, 5, 7, 8]}, %q{$a = []; begin; ; $a << 1 - o = "test".dup; $a << 2 + o = "test"; $a << 2 def o.test(a); $a << 3 return a; $a << 4 ensure; $a << 5 diff --git a/bootstraptest/test_fork.rb b/bootstraptest/test_fork.rb index 9e64f1d026..83923dad97 100644 --- a/bootstraptest/test_fork.rb +++ b/bootstraptest/test_fork.rb @@ -75,25 +75,3 @@ assert_equal '[1, 2]', %q{ end }, '[ruby-dev:44005] [Ruby 1.9 - Bug #4950]' -assert_equal 'ok', %q{ - def now = Process.clock_gettime(Process::CLOCK_MONOTONIC) - - Thread.new do - loop { sleep 0.0001 } - end - - 10.times do - pid = fork{ exit!(0) } - deadline = now + 1 - until Process.waitpid(pid, Process::WNOHANG) - if now > deadline - Process.kill(:KILL, pid) - raise "failed" - end - sleep 0.001 - end - rescue NotImplementedError - end - :ok -}, '[Bug #20670]' - diff --git a/bootstraptest/test_gc.rb b/bootstraptest/test_gc.rb index 17bc497822..eb68c9845e 100644 --- a/bootstraptest/test_gc.rb +++ b/bootstraptest/test_gc.rb @@ -14,7 +14,7 @@ ms = "a".."k" o.send(meth) end end -}, '[ruby-dev:39453]' unless rjit_enabled? # speed up RJIT CI +}, '[ruby-dev:39453]' assert_normal_exit %q{ a = [] diff --git a/bootstraptest/test_insns.rb b/bootstraptest/test_insns.rb index 18ab1800bd..91fba9b011 100644 --- a/bootstraptest/test_insns.rb +++ b/bootstraptest/test_insns.rb @@ -92,7 +92,7 @@ tests = [ [ 'intern', %q{ :"#{true}" }, ], [ 'newarray', %q{ ["true"][0] }, ], - [ 'pushtoarraykwsplat', %q{ [**{x:'true'}][0][:x] }, ], + [ 'newarraykwsplat', %q{ [**{x:'true'}][0][:x] }, ], [ 'duparray', %q{ [ true ][0] }, ], [ 'expandarray', %q{ y = [ true, false, nil ]; x, = y; x }, ], [ 'expandarray', %q{ y = [ true, false, nil ]; x, *z = y; x }, ], @@ -214,11 +214,9 @@ tests = [ 'true'.freeze }, - [ 'opt_newarray_send', %q{ ![ ].hash.nil? }, ], - - [ 'opt_newarray_send', %q{ [ ].max.nil? }, ], - [ 'opt_newarray_send', %q{ [1, x = 2, 3].max == 3 }, ], - [ 'opt_newarray_send', <<-'},', ], # { + [ 'opt_newarray_max', %q{ [ ].max.nil? }, ], + [ 'opt_newarray_max', %q{ [1, x = 2, 3].max == 3 }, ], + [ 'opt_newarray_max', <<-'},', ], # { class Array def max true @@ -226,9 +224,9 @@ tests = [ end [1, x = 2, 3].max }, - [ 'opt_newarray_send', %q{ [ ].min.nil? }, ], - [ 'opt_newarray_send', %q{ [3, x = 2, 1].min == 1 }, ], - [ 'opt_newarray_send', <<-'},', ], # { + [ 'opt_newarray_min', %q{ [ ].min.nil? }, ], + [ 'opt_newarray_min', %q{ [3, x = 2, 1].min == 1 }, ], + [ 'opt_newarray_min', <<-'},', ], # { class Array def min true @@ -236,48 +234,6 @@ tests = [ end [3, x = 2, 1].min }, - [ 'opt_newarray_send', %q{ v = 1.23; [v, v*2].pack("E*").unpack("E*") == [v, v*2] }, ], - [ 'opt_newarray_send', %q{ v = 4.56; b = +"x"; [v, v*2].pack("E*", buffer: b); b[1..].unpack("E*") == [v, v*2] }, ], - [ 'opt_newarray_send', <<-'},', ], # { - v = 7.89; - b = +"x"; - class Array - alias _pack pack - def pack(s, buffer: nil, prefix: "y") - buffer ||= +"b" - buffer << prefix - _pack(s, buffer: buffer) - end - end - tests = [] - - ret = [v].pack("E*", prefix: "z") - tests << (ret[0..1] == "bz") - tests << (ret[2..].unpack("E*") == [v]) - - ret = [v].pack("E*") - tests << (ret[0..1] == "by") - tests << (ret[2..].unpack("E*") == [v]) - - [v, v*2, v*3].pack("E*", buffer: b) - tests << (b[0..1] == "xy") - tests << (b[2..].unpack("E*") == [v, v*2, v*3]) - - class Array - def pack(_fmt, buffer:) = buffer - end - - b = nil - tests << [v].pack("E*", buffer: b).nil? - - class Array - def pack(_fmt, **kw) = kw.empty? - end - - tests << [v].pack("E*") == true - - tests.all? or puts tests - }, [ 'throw', %q{ false.tap { break true } }, ], [ 'branchif', %q{ x = nil; x ||= true }, ], @@ -396,7 +352,7 @@ tests = [ [ 'opt_ge', %q{ +0.0.next_float >= 0.0 }, ], [ 'opt_ge', %q{ ?z >= ?a }, ], - [ 'opt_ltlt', %q{ +'' << 'true' }, ], + [ 'opt_ltlt', %q{ '' << 'true' }, ], [ 'opt_ltlt', %q{ ([] << 'true').join }, ], [ 'opt_ltlt', %q{ (1 << 31) == 2147483648 }, ], @@ -405,7 +361,7 @@ tests = [ [ 'opt_aref', %q{ 'true'[0] == ?t }, ], [ 'opt_aset', %q{ [][0] = true }, ], [ 'opt_aset', %q{ {}[0] = true }, ], - [ 'opt_aset', %q{ x = +'frue'; x[0] = 't'; x }, ], + [ 'opt_aset', %q{ x = 'frue'; x[0] = 't'; x }, ], [ 'opt_aset', <<-'},', ], # { # opt_aref / opt_aset mixup situation class X; def x; {}; end; end diff --git a/bootstraptest/test_io.rb b/bootstraptest/test_io.rb index 4e5d6d59c9..666e5a011b 100644 --- a/bootstraptest/test_io.rb +++ b/bootstraptest/test_io.rb @@ -91,7 +91,7 @@ assert_normal_exit %q{ at_exit { p :foo } megacontent = "abc" * 12345678 - #File.write("megasrc", megacontent) + #File.open("megasrc", "w") {|f| f << megacontent } t0 = Thread.main Thread.new { sleep 0.001 until t0.stop?; Process.kill(:INT, $$) } diff --git a/bootstraptest/test_jump.rb b/bootstraptest/test_jump.rb index 8751343b1f..d07c47a56d 100644 --- a/bootstraptest/test_jump.rb +++ b/bootstraptest/test_jump.rb @@ -292,7 +292,7 @@ assert_equal "true", %q{ end end end - s = +"foo" + s = "foo" s.return_eigenclass == class << s; self; end }, '[ruby-core:21379]' diff --git a/bootstraptest/test_literal.rb b/bootstraptest/test_literal.rb index 7295f7a148..a0d4ee08c6 100644 --- a/bootstraptest/test_literal.rb +++ b/bootstraptest/test_literal.rb @@ -70,7 +70,6 @@ if /wasi/ !~ target_platform assert_equal "foo\n", %q(`echo foo`) assert_equal "foo\n", %q(s = "foo"; `echo #{s}`) end -assert_equal "ECHO FOO", %q(def `(s) s.upcase; end; `echo foo`) # regexp assert_equal '', '//.source' @@ -119,14 +118,14 @@ assert_equal '5', 'a = [1,2,3]; a[1] = 5; a[1]' assert_equal 'bar', '[*:foo];:bar' assert_equal '[1, 2]', 'def nil.to_a; [2]; end; [1, *nil]' assert_equal '[1, 2]', 'def nil.to_a; [1, 2]; end; [*nil]' -assert_equal '[0, 1, {2 => 3}]', '[0, *[1], 2=>3]', "[ruby-dev:31592]" +assert_equal '[0, 1, {2=>3}]', '[0, *[1], 2=>3]', "[ruby-dev:31592]" # hash assert_equal 'Hash', '{}.class' assert_equal '{}', '{}.inspect' assert_equal 'Hash', '{1=>2}.class' -assert_equal '{1 => 2}', '{1=>2}.inspect' +assert_equal '{1=>2}', '{1=>2}.inspect' assert_equal '2', 'h = {1 => 2}; h[1]' assert_equal '0', 'h = {1 => 2}; h.delete(1); h.size' assert_equal '', 'h = {1 => 2}; h.delete(1); h[1]' diff --git a/bootstraptest/test_literal_suffix.rb b/bootstraptest/test_literal_suffix.rb index 7a4d67d0fa..c36fa7078f 100644 --- a/bootstraptest/test_literal_suffix.rb +++ b/bootstraptest/test_literal_suffix.rb @@ -46,9 +46,9 @@ assert_equal '1', '1rescue nil' assert_equal '10000000000000000001/10000000000000000000', '1.0000000000000000001r' -assert_equal 'unexpected local variable or method, expecting end-of-input', - %q{begin eval('1ir', nil, '', 0); rescue SyntaxError => e; e.message[/(?:\^~*|\A:(?:\d+:)? syntax error,) (.*)/, 1]; end} -assert_equal 'unexpected local variable or method, expecting end-of-input', - %q{begin eval('1.2ir', nil, '', 0); rescue SyntaxError => e; e.message[/(?:\^~*|\A:(?:\d+:)? syntax error,) (.*)/, 1]; end} -assert_equal 'unexpected local variable or method, expecting end-of-input', - %q{begin eval('1e1r', nil, '', 0); rescue SyntaxError => e; e.message[/(?:\^~*|\A:(?:\d+:)? syntax error,) (.*)/, 1]; end} +assert_equal 'syntax error, unexpected local variable or method, expecting end-of-input', + %q{begin eval('1ir', nil, '', 0); rescue SyntaxError => e; e.message[/\A:(?:\d+:)? (.*)/, 1] end} +assert_equal 'syntax error, unexpected local variable or method, expecting end-of-input', + %q{begin eval('1.2ir', nil, '', 0); rescue SyntaxError => e; e.message[/\A:(?:\d+:)? (.*)/, 1] end} +assert_equal 'syntax error, unexpected local variable or method, expecting end-of-input', + %q{begin eval('1e1r', nil, '', 0); rescue SyntaxError => e; e.message[/\A:(?:\d+:)? (.*)/, 1] end} diff --git a/bootstraptest/test_load.rb b/bootstraptest/test_load.rb index 5046d4fcea..e63c93a8f4 100644 --- a/bootstraptest/test_load.rb +++ b/bootstraptest/test_load.rb @@ -1,9 +1,9 @@ assert_equal 'ok', %q{ - File.write("require-lock-test.rb", <<-END) - sleep 0.1 - module M - end - END + open("require-lock-test.rb", "w") {|f| + f.puts "sleep 0.1" + f.puts "module M" + f.puts "end" + } $:.unshift Dir.pwd vs = (1..2).map {|i| Thread.start { @@ -12,11 +12,11 @@ assert_equal 'ok', %q{ } }.map {|t| t.value } vs[0] == M && vs[1] == M ? :ok : :ng -}, '[ruby-dev:32048]' unless ENV.fetch('RUN_OPTS', '').include?('rjit') # Thread seems to be switching during JIT. To be fixed later. +}, '[ruby-dev:32048]' assert_equal 'ok', %q{ %w[a a/foo b].each {|d| Dir.mkdir(d)} - File.write("b/foo", "$ok = :ok\n") + open("b/foo", "w") {|f| f.puts "$ok = :ok"} $:.replace(%w[a b]) begin load "foo" diff --git a/bootstraptest/test_method.rb b/bootstraptest/test_method.rb index af9443b8c6..04c9eb2d11 100644 --- a/bootstraptest/test_method.rb +++ b/bootstraptest/test_method.rb @@ -340,6 +340,24 @@ assert_equal '1', %q( class C; def m() 7 end; private :m end assert_equal '1', %q( class C; def m() 1 end; private :m end C.new.send(:m) ) +# with block +assert_equal '[[:ok1, :foo], [:ok2, :foo, :bar]]', +%q{ + class C + def [](a) + $ary << [yield, a] + end + def []=(a, b) + $ary << [yield, a, b] + end + end + + $ary = [] + C.new[:foo, &lambda{:ok1}] + C.new[:foo, &lambda{:ok2}] = :bar + $ary +} + # with assert_equal '[:ok1, [:ok2, 11]]', %q{ class C @@ -386,6 +404,7 @@ $result # aset and splat assert_equal '4', %q{class Foo;def []=(a,b,c,d);end;end;Foo.new[1,*a=[2,3]]=4} +assert_equal '4', %q{class Foo;def []=(a,b,c,d);end;end;def m(&blk)Foo.new[1,*a=[2,3],&blk]=4;end;m{}} # post test assert_equal %q{[1, 2, :o1, :o2, [], 3, 4, NilClass, nil, nil]}, %q{ @@ -1088,6 +1107,10 @@ assert_equal 'ok', %q{ 'ok' end } +assert_equal 'ok', %q{ + [0][0, &proc{}] += 21 + 'ok' +}, '[ruby-core:30534]' # should not cache when splat assert_equal 'ok', %q{ @@ -1167,210 +1190,3 @@ assert_equal 'DC', %q{ test2 o1, [], block $result.join } - -assert_equal 'ok', %q{ - def foo - binding - ["ok"].first - end - foo - foo -}, '[Bug #20178]' - -assert_equal 'ok', %q{ - def bar(x); x; end - def foo(...); bar(...); end - foo('ok') -} - -assert_equal 'ok', %q{ - def bar(x); x; end - def foo(z, ...); bar(...); end - foo(1, 'ok') -} - -assert_equal 'ok', %q{ - def bar(x, y); x; end - def foo(...); bar("ok", ...); end - foo(1) -} - -assert_equal 'ok', %q{ - def bar(x); x; end - def foo(...); 1.times { return bar(...) }; end - foo("ok") -} - -assert_equal 'ok', %q{ - def bar(x); x; end - def foo(...); x = nil; 1.times { x = bar(...) }; x; end - foo("ok") -} - -assert_equal 'ok', %q{ - def bar(x); yield; end - def foo(...); bar(...); end - foo(1) { "ok" } -} - -assert_equal 'ok', %q{ - def baz(x); x; end - def bar(...); baz(...); end - def foo(...); bar(...); end - foo("ok") -} - -assert_equal '[1, 2, 3, 4]', %q{ - def baz(a, b, c, d); [a, b, c, d]; end - def bar(...); baz(1, ...); end - def foo(...); bar(2, ...); end - foo(3, 4) -} - -assert_equal 'ok', %q{ - class Foo; def self.foo(x); x; end; end - class Bar < Foo; def self.foo(...); super; end; end - Bar.foo('ok') -} - -assert_equal 'ok', %q{ - class Foo; def self.foo(x); x; end; end - class Bar < Foo; def self.foo(...); super(...); end; end - Bar.foo('ok') -} - -assert_equal 'ok', %q{ - class Foo; def self.foo(x, y); x + y; end; end - class Bar < Foo; def self.foo(...); super("o", ...); end; end - Bar.foo('k') -} - -assert_equal 'ok', %q{ - def bar(a); a; end - def foo(...); lambda { bar(...) }; end - foo("ok").call -} - -assert_equal 'ok', %q{ - class Foo; def self.foo(x, y); x + y; end; end - class Bar < Foo; def self.y(&b); b; end; def self.foo(...); y { super("o", ...) }; end; end - Bar.foo('k').call -} - -assert_equal 'ok', %q{ - def baz(n); n; end - def foo(...); bar = baz(...); lambda { lambda { bar } }; end - foo("ok").call.call -} - -assert_equal 'ok', %q{ - class A; def self.foo(...); new(...); end; attr_reader :b; def initialize(a, b:"ng"); @a = a; @b = b; end end - A.foo(1).b - A.foo(1, b: "ok").b -} - -assert_equal 'ok', %q{ - class A; def initialize; @a = ["ok"]; end; def first(...); @a.first(...); end; end - def call x; x.first; end - def call1 x; x.first(1); end - call(A.new) - call1(A.new).first -} - -assert_equal 'ok', %q{ - class A; def foo; yield("o"); end; end - class B < A; def foo(...); super { |x| yield(x + "k") }; end; end - B.new.foo { |x| x } -} - -assert_equal "[1, 2, 3, 4]", %q{ - def foo(*b) = b - - def forward(...) - splat = [1,2,3] - foo(*splat, ...) - end - - forward(4) -} - -assert_equal "[1, 2, 3, 4]", %q{ -class A - def foo(*b) = b -end - -class B < A - def foo(...) - splat = [1,2,3] - super(*splat, ...) - end -end - -B.new.foo(4) -} - -assert_equal 'ok', %q{ - class A; attr_reader :iv; def initialize(...) = @iv = "ok"; end - A.new("foo", bar: []).iv -} - -assert_equal 'ok', %q{ - def foo(a, b) = a + b - def bar(...) = foo(...) - bar(1, 2) - bar(1, 2) - begin - bar(1, 2, 3) - "ng" - rescue ArgumentError - "ok" - end -} - -assert_equal 'ok', %q{ - class C - def foo(...) = :ok - def bar(...) = __send__(:foo, ...) - end - - C.new.bar -} - -assert_equal 'ok', %q{ - class C - def method_missing(...) = :ok - def foo(...) = xyzzy(...) - end - - C.new.foo -} - -assert_equal 'ok', %q{ - class C - def initialize(a) - end - end - - def foo(...) - C.new(...) - :ok - end - - foo(*["bar"]) - foo("baz") -} - -assert_equal 'ok', %q{ - class C - def foo(b:) - b - end - end - - def foo(...) - C.new.send(...) - end - - foo(:foo, b: :ok) - foo(*["foo"], b: :ok) -} diff --git a/bootstraptest/test_ractor.rb b/bootstraptest/test_ractor.rb index 5caa903b94..67e66b03ee 100644 --- a/bootstraptest/test_ractor.rb +++ b/bootstraptest/test_ractor.rb @@ -283,7 +283,9 @@ assert_equal 30.times.map { 'ok' }.to_s, %q{ 30.times.map{|i| test i } -} unless (ENV.key?('TRAVIS') && ENV['TRAVIS_CPU_ARCH'] == 'arm64') # https://bugs.ruby-lang.org/issues/17878 +} unless ENV['RUN_OPTS'] =~ /--mjit-call-threshold=5/ || # This always fails with --mjit-wait --mjit-call-threshold=5 + (ENV.key?('TRAVIS') && ENV['TRAVIS_CPU_ARCH'] == 'arm64') || # https://bugs.ruby-lang.org/issues/17878 + true # too flaky everywhere http://ci.rvm.jp/results/trunk@ruby-sp1/4321096 # Exception for empty select assert_match /specify at least one ractor/, %q{ @@ -514,9 +516,9 @@ assert_equal '[true, true, true]', %q{ end } received = [] - taken = [] + take = [] yielded = [] - until received.size == RN && taken.size == RN && yielded.size == RN + until rs.empty? r, v = Ractor.select(CR, *rs, yield_value: 'yield') case r when :receive @@ -524,17 +526,11 @@ assert_equal '[true, true, true]', %q{ when :yield yielded << v else - taken << v + take << v rs.delete r end end - r = [received == ['sendyield'] * RN, - yielded == [nil] * RN, - taken == ['take'] * RN, - ] - - STDERR.puts [received, yielded, taken].inspect - r + [received.all?('sendyield'), yielded.all?(nil), take.all?('take')] } # multiple Ractors can send to one Ractor @@ -571,7 +567,7 @@ assert_equal '[RuntimeError, "ok", true]', %q{ } # threads in a ractor will killed -assert_equal '{ok: 3}', %q{ +assert_equal '{:ok=>3}', %q{ Ractor.new Ractor.current do |main| q = Thread::Queue.new Thread.new do @@ -601,7 +597,7 @@ assert_equal '{ok: 3}', %q{ end 3.times.map{Ractor.receive}.tally -} unless yjit_enabled? # `[BUG] Bus Error at 0x000000010b7002d0` in jit_exec() +} # unshareable object are copied assert_equal 'false', %q{ @@ -628,7 +624,7 @@ assert_equal "allocator undefined for Thread", %q{ } # send shareable and unshareable objects -assert_equal "ok", <<~'RUBY', frozen_string_literal: false +assert_equal "ok", %q{ echo_ractor = Ractor.new do loop do v = Ractor.receive @@ -695,10 +691,10 @@ assert_equal "ok", <<~'RUBY', frozen_string_literal: false else results.inspect end -RUBY +} # frozen Objects are shareable -assert_equal [false, true, false].inspect, <<~'RUBY', frozen_string_literal: false +assert_equal [false, true, false].inspect, %q{ class C def initialize freeze @a = 1 @@ -721,11 +717,11 @@ assert_equal [false, true, false].inspect, <<~'RUBY', frozen_string_literal: fal results << check(C.new(true)) # false results << check(C.new(true).freeze) # true results << check(C.new(false).freeze) # false -RUBY +} # move example2: String # touching moved object causes an error -assert_equal 'hello world', <<~'RUBY', frozen_string_literal: false +assert_equal 'hello world', %q{ # move r = Ractor.new do obj = Ractor.receive @@ -743,7 +739,7 @@ assert_equal 'hello world', <<~'RUBY', frozen_string_literal: false else raise 'unreachable' end -RUBY +} # move example2: Array assert_equal '[0, 1]', %q{ @@ -946,7 +942,7 @@ assert_equal 'ArgumentError', %q{ } # ivar in shareable-objects are not allowed to access from non-main Ractor -assert_equal "can not get unshareable values from instance variables of classes/modules from non-main Ractors", <<~'RUBY', frozen_string_literal: false +assert_equal "can not get unshareable values from instance variables of classes/modules from non-main Ractors", %q{ class C @iv = 'str' end @@ -957,12 +953,13 @@ assert_equal "can not get unshareable values from instance variables of classes/ end end + begin r.take rescue Ractor::RemoteError => e e.cause.message end -RUBY +} # ivar in shareable-objects are not allowed to access from non-main Ractor assert_equal 'can not access instance variables of shareable objects from non-main Ractors', %q{ @@ -1086,41 +1083,6 @@ assert_equal '333', %q{ a + b + c + d + e + f } -assert_equal '["instance-variable", "instance-variable", nil]', %q{ - class C - @iv1 = "" - @iv2 = 42 - def self.iv1 = defined?(@iv1) # "instance-variable" - def self.iv2 = defined?(@iv2) # "instance-variable" - def self.iv3 = defined?(@iv3) # nil - end - - Ractor.new{ - [C.iv1, C.iv2, C.iv3] - }.take -} - -# moved objects have their shape properly set to original object's shape -assert_equal '1234', %q{ -class Obj - attr_accessor :a, :b, :c, :d - def initialize - @a = 1 - @b = 2 - @c = 3 - end -end -r = Ractor.new do - obj = receive - obj.d = 4 - [obj.a, obj.b, obj.c, obj.d] -end -obj = Obj.new -r.send(obj, move: true) -values = r.take -values.join -} - # cvar in shareable-objects are not allowed to access from non-main Ractor assert_equal 'can not access class variables from non-main Ractors', %q{ class C @@ -1163,7 +1125,7 @@ assert_equal 'can not access class variables from non-main Ractors', %q{ } # Getting non-shareable objects via constants by other Ractors is not allowed -assert_equal 'can not access non-shareable objects in constant C::CONST by non-main Ractor.', <<~'RUBY', frozen_string_literal: false +assert_equal 'can not access non-shareable objects in constant C::CONST by non-main Ractor.', %q{ class C CONST = 'str' end @@ -1175,10 +1137,10 @@ assert_equal 'can not access non-shareable objects in constant C::CONST by non-m rescue Ractor::RemoteError => e e.cause.message end - RUBY +} # Constant cache should care about non-sharable constants -assert_equal "can not access non-shareable objects in constant Object::STR by non-main Ractor.", <<~'RUBY', frozen_string_literal: false +assert_equal "can not access non-shareable objects in constant Object::STR by non-main Ractor.", %q{ STR = "hello" def str; STR; end s = str() # fill const cache @@ -1187,10 +1149,10 @@ assert_equal "can not access non-shareable objects in constant Object::STR by no rescue Ractor::RemoteError => e e.cause.message end -RUBY +} # Setting non-shareable objects into constants by other Ractors is not allowed -assert_equal 'can not set constants with non-shareable objects by non-main Ractors', <<~'RUBY', frozen_string_literal: false +assert_equal 'can not set constants with non-shareable objects by non-main Ractors', %q{ class C end r = Ractor.new do @@ -1201,7 +1163,7 @@ assert_equal 'can not set constants with non-shareable objects by non-main Racto rescue Ractor::RemoteError => e e.cause.message end -RUBY +} # define_method is not allowed assert_equal "defined with an un-shareable Proc in a different Ractor", %q{ @@ -1254,7 +1216,7 @@ assert_equal '0', %q{ } # ObjectSpace._id2ref can not handle unshareable objects with Ractors -assert_equal 'ok', <<~'RUBY', frozen_string_literal: false +assert_equal 'ok', %q{ s = 'hello' Ractor.new s.object_id do |id ;s| @@ -1264,10 +1226,10 @@ assert_equal 'ok', <<~'RUBY', frozen_string_literal: false :ok end end.take -RUBY +} # Ractor.make_shareable(obj) -assert_equal 'true', <<~'RUBY', frozen_string_literal: false +assert_equal 'true', %q{ class C def initialize @a = 'foo' @@ -1338,7 +1300,7 @@ assert_equal 'true', <<~'RUBY', frozen_string_literal: false } Ractor.shareable?(a) -RUBY +} # Ractor.make_shareable(obj) doesn't freeze shareable objects assert_equal 'true', %q{ @@ -1435,14 +1397,14 @@ assert_equal '[false, false, true, true]', %q{ } # TracePoint with normal Proc should be Ractor local -assert_equal '[6, 10]', %q{ +assert_equal '[4, 8]', %q{ rs = [] TracePoint.new(:line){|tp| rs << tp.lineno if tp.path == __FILE__}.enable do - Ractor.new{ # line 5 + Ractor.new{ # line 4 a = 1 b = 2 }.take - c = 3 # line 9 + c = 3 # line 8 end rs } @@ -1480,25 +1442,6 @@ assert_equal '[:ok, :ok]', %q{ end } -# Ractor.select is interruptible -assert_normal_exit %q{ - trap(:INT) do - exit - end - - r = Ractor.new do - loop do - sleep 1 - end - end - - Thread.new do - sleep 0.5 - Process.kill(:INT, Process.pid) - end - Ractor.select(r) -} - # Ractor-local storage assert_equal '[nil, "b", "a"]', %q{ ans = [] @@ -1529,13 +1472,28 @@ assert_equal "#{N}#{N}", %Q{ }.map{|r| r.take}.join } +# enc_table +assert_equal "100", %Q{ + Ractor.new do + loop do + Encoding.find("test-enc-#{rand(5_000)}").inspect + rescue ArgumentError => e + end + end + + src = Encoding.find("UTF-8") + 100.times{|i| + src.replicate("test-enc-\#{i}") + } +} + # Generic ivtbl n = N/2 assert_equal "#{n}#{n}", %Q{ 2.times.map{ Ractor.new do #{n}.times do - obj = +'' + obj = '' obj.instance_variable_set("@a", 1) obj.instance_variable_set("@b", 1) obj.instance_variable_set("@c", 1) @@ -1547,9 +1505,8 @@ assert_equal "#{n}#{n}", %Q{ # NameError assert_equal "ok", %q{ - obj = "".freeze # NameError refers the receiver indirectly begin - obj.bar + bar rescue => err end begin @@ -1585,7 +1542,7 @@ assert_equal "ok", %q{ 1_000.times { idle_worker, tmp_reporter = Ractor.select(*workers) } "ok" -} unless yjit_enabled? || rjit_enabled? # flaky +} assert_equal "ok", %q{ def foo(*); ->{ super }; end @@ -1623,7 +1580,6 @@ assert_equal "ok", %q{ end } -# check method cache invalidation assert_equal "ok", %q{ module M def foo @@ -1663,176 +1619,10 @@ assert_equal "ok", %q{ "ok" } -# check method cache invalidation -assert_equal 'true', %q{ - class C1; def self.foo = 1; end - class C2; def self.foo = 2; end - class C3; def self.foo = 3; end - class C4; def self.foo = 5; end - class C5; def self.foo = 7; end - class C6; def self.foo = 11; end - class C7; def self.foo = 13; end - class C8; def self.foo = 17; end - - LN = 10_000 - RN = 10 - CS = [C1, C2, C3, C4, C5, C6, C7, C8] - rs = RN.times.map{|i| - Ractor.new(CS.shuffle){|cs| - LN.times.sum{ - cs.inject(1){|r, c| r * c.foo} # c.foo invalidates method cache entry - } - } - } - - n = CS.inject(1){|r, c| r * c.foo} * LN - rs.map{|r| r.take} == Array.new(RN){n} -} - -# check experimental warning assert_match /\Atest_ractor\.rb:1:\s+warning:\s+Ractor is experimental/, %q{ Warning[:experimental] = $VERBOSE = true STDERR.reopen(STDOUT) eval("Ractor.new{}.take", nil, "test_ractor.rb", 1) -}, frozen_string_literal: false - -# check moved object -assert_equal 'ok', %q{ - r = Ractor.new do - Ractor.receive - GC.start - :ok - end - - obj = begin - raise - rescue => e - e = Marshal.load(Marshal.dump(e)) - end - - r.send obj, move: true - r.take -} - -## Ractor::Selector - -# Selector#empty? returns true -assert_equal 'true', %q{ - skip true unless defined? Ractor::Selector - - s = Ractor::Selector.new - s.empty? -} - -# Selector#empty? returns false if there is target ractors -assert_equal 'false', %q{ - skip false unless defined? Ractor::Selector - - s = Ractor::Selector.new - s.add Ractor.new{} - s.empty? -} - -# Selector#clear removes all ractors from the waiting list -assert_equal 'true', %q{ - skip true unless defined? Ractor::Selector - - s = Ractor::Selector.new - s.add Ractor.new{10} - s.add Ractor.new{20} - s.clear - s.empty? -} - -# Selector#wait can wait multiple ractors -assert_equal '[10, 20, true]', %q{ - skip [10, 20, true] unless defined? Ractor::Selector - - s = Ractor::Selector.new - s.add Ractor.new{10} - s.add Ractor.new{20} - r, v = s.wait - vs = [] - vs << v - r, v = s.wait - vs << v - [*vs.sort, s.empty?] -} if defined? Ractor::Selector - -# Selector#wait can wait multiple ractors with receiving. -assert_equal '30', %q{ - skip 30 unless defined? Ractor::Selector - - RN = 30 - rs = RN.times.map{ - Ractor.new{ :v } - } - s = Ractor::Selector.new(*rs) - - results = [] - until s.empty? - results << s.wait - - # Note that s.wait can raise an exception because other Ractors/Threads - # can take from the same ractors in the waiting set. - # In this case there is no other takers so `s.wait` doesn't raise an error. - end - - results.size -} if defined? Ractor::Selector - -# Selector#wait can support dynamic addition -assert_equal '600', %q{ - skip 600 unless defined? Ractor::Selector - - RN = 100 - s = Ractor::Selector.new - rs = RN.times.map{ - Ractor.new{ - Ractor.main << Ractor.new{ Ractor.yield :v3; :v4 } - Ractor.main << Ractor.new{ Ractor.yield :v5; :v6 } - Ractor.yield :v1 - :v2 - } - } - - rs.each{|r| s.add(r)} - h = {v1: 0, v2: 0, v3: 0, v4: 0, v5: 0, v6: 0} - - loop do - case s.wait receive: true - in :receive, r - s.add r - in r, v - h[v] += 1 - break if h.all?{|k, v| v == RN} - end - end - - h.sum{|k, v| v} -} unless yjit_enabled? # http://ci.rvm.jp/results/trunk-yjit@ruby-sp2-docker/4466770 - -# Selector should be GCed (free'ed) without trouble -assert_equal 'ok', %q{ - skip :ok unless defined? Ractor::Selector - - RN = 30 - rs = RN.times.map{ - Ractor.new{ :v } - } - s = Ractor::Selector.new(*rs) - :ok } end # if !ENV['GITHUB_WORKFLOW'] - -# Chilled strings are not shareable -assert_equal 'false', %q{ - Ractor.shareable?("chilled") -} - -# Chilled strings can be made shareable -assert_equal 'true', %q{ - shareable = Ractor.make_shareable("chilled") - shareable == "chilled" && Ractor.shareable?(shareable) -} diff --git a/bootstraptest/test_rjit.rb b/bootstraptest/test_rjit.rb deleted file mode 100644 index 4c8cd26dff..0000000000 --- a/bootstraptest/test_rjit.rb +++ /dev/null @@ -1,80 +0,0 @@ -# VM_CALL_OPT_SEND + VM_METHOD_TYPE_ATTRSET -assert_equal '1', %q{ - class Foo - attr_writer :foo - - def bar - send(:foo=, 1) - end - end - - Foo.new.bar -} - -# VM_CALL_OPT_SEND + OPTIMIZED_METHOD_TYPE_CALL -assert_equal 'foo', %q{ - def bar(&foo) - foo.send(:call) - end - - bar { :foo } -} - -# VM_CALL_OPT_SEND + OPTIMIZED_METHOD_TYPE_STRUCT_AREF -assert_equal 'bar', %q{ - def bar(foo) - foo.send(:bar) - end - - bar(Struct.new(:bar).new(:bar)) -} - -# AND with offset DISP32 -assert_equal '2', %q{ - def foo - a = 6; - b = {a: 1, b: 1, c: 1, d: 1, e: 1, f: 1, g: 1, h: a&3} - b[:h] - end - - foo -} - -# OR with offset DISP32 -assert_equal '6', %q{ - def foo - a = 4; - b = {a: 1, b: 1, c: 1, d: 1, e: 1, f: 1, g: 1, h: a|2} - b[:h] - end - - foo -} - -# kwargs default w/ checkkeyword + locals (which shouldn't overwrite unspecified_bits) -assert_equal '1', %q{ - def foo(bar: 1.to_s) - _ = 1 - bar - end - - def entry - foo - end - - entry -} - -# Updating local type in Context -assert_normal_exit %q{ - def foo(flag, object) - klass = if flag - object - end - klass ||= object - return klass.new - end - - foo(false, Object) - foo(true, Object) -} diff --git a/bootstraptest/test_syntax.rb b/bootstraptest/test_syntax.rb index 8301b344c6..948e2d7809 100644 --- a/bootstraptest/test_syntax.rb +++ b/bootstraptest/test_syntax.rb @@ -528,24 +528,24 @@ assert_equal %q{1}, %q{ i } def assert_syntax_error expected, code, message = '' - assert_match /^#{Regexp.escape(expected)}/, - "begin eval(%q{#{code}}, nil, '', 0)"'; rescue SyntaxError => e; e.message[/(?:\^~*|\A:(?:\d+:)?(?! syntax errors? found)(?: syntax error,)?) (.*)/, 1] end', message + assert_equal "#{expected}", + "begin eval(%q{#{code}}, nil, '', 0)"'; rescue SyntaxError => e; e.message[/\A:(?:\d+:)? (.*)/, 1] end', message end assert_syntax_error "unterminated string meets end of file", '().."', '[ruby-dev:29732]' assert_equal %q{[]}, %q{$&;[]}, '[ruby-dev:31068]' -assert_syntax_error "unexpected *, expecting '}'", %q{{*0}}, '[ruby-dev:31072]' -assert_syntax_error "'@0' is not allowed as an instance variable name", %q{@0..0}, '[ruby-dev:31095]' -assert_syntax_error "'$00' is not allowed as a global variable name", %q{$00..0}, '[ruby-dev:31100]' -assert_syntax_error "'$00' is not allowed as a global variable name", %q{0..$00=1} +assert_syntax_error "syntax error, unexpected *, expecting '}'", %q{{*0}}, '[ruby-dev:31072]' +assert_syntax_error "`@0' is not allowed as an instance variable name", %q{@0..0}, '[ruby-dev:31095]' +assert_syntax_error "identifier $00 is not valid to get", %q{$00..0}, '[ruby-dev:31100]' +assert_syntax_error "identifier $00 is not valid to set", %q{0..$00=1} assert_equal %q{0}, %q{[*0];0}, '[ruby-dev:31102]' -assert_syntax_error "unexpected ')'", %q{v0,(*,v1,) = 0}, '[ruby-dev:31104]' +assert_syntax_error "syntax error, unexpected ')'", %q{v0,(*,v1,) = 0}, '[ruby-dev:31104]' assert_equal %q{1}, %q{ class << (ary=[]); def []; 0; end; def []=(x); super(0,x);end;end; ary[]+=1 }, '[ruby-dev:31110]' assert_syntax_error "Can't set variable $1", %q{0..$1=1}, '[ruby-dev:31118]' assert_valid_syntax %q{1.times{1+(1&&next)}}, '[ruby-dev:31119]' assert_valid_syntax %q{x=-1;loop{x+=1&&redo if (x+=1).zero?}}, '[ruby-dev:31119]' -assert_syntax_error %q{unexpected end-of-input}, %q{!}, '[ruby-dev:31243]' +assert_syntax_error %q{syntax error, unexpected end-of-input}, %q{!}, '[ruby-dev:31243]' assert_equal %q{[nil]}, %q{[()]}, '[ruby-dev:31252]' assert_equal %q{true}, %q{!_=()}, '[ruby-dev:31263]' assert_equal 'ok', %q{while true; redo; end if 1 == 2; :ok}, '[ruby-dev:31360]' @@ -629,7 +629,7 @@ assert_equal '2', %q{ assert_match /invalid multibyte char/, %q{ $stderr = STDOUT - eval("\"\xf0".dup.force_encoding("utf-8")) + eval("\"\xf0".force_encoding("utf-8")) }, '[ruby-dev:32429]' # method ! and != @@ -848,7 +848,7 @@ assert_normal_exit %q{ def x(a=1, b, *rest); nil end end end -}, bug2415 unless rjit_enabled? # flaky +}, bug2415 assert_normal_exit %q{ 0.times do @@ -880,7 +880,7 @@ assert_normal_exit %q{ end end end -}, bug2415 unless rjit_enabled? # flaky +}, bug2415 assert_normal_exit %q{ a { @@ -904,35 +904,3 @@ assert_normal_exit %q{ Class end }, '[ruby-core:30293]' - -assert_equal "false", <<~RUBY, "literal strings are mutable", "--disable-frozen-string-literal" - 'test'.frozen? -RUBY - -assert_equal "true", <<~RUBY, "literal strings are frozen", "--disable-frozen-string-literal", frozen_string_literal: true - 'test'.frozen? -RUBY - -assert_equal "true", <<~RUBY, "literal strings are frozen", "--enable-frozen-string-literal" - 'test'.frozen? -RUBY - -assert_equal "false", <<~RUBY, "literal strings are mutable", "--enable-frozen-string-literal", frozen_string_literal: false - 'test'.frozen? -RUBY - -assert_equal "false", <<~RUBY, "__FILE__ is mutable", "--disable-frozen-string-literal" - __FILE__.frozen? -RUBY - -assert_equal "true", <<~RUBY, "__FILE__ is frozen", "--disable-frozen-string-literal", frozen_string_literal: true - __FILE__.frozen? -RUBY - -assert_equal "true", <<~RUBY, "__FILE__ is frozen", "--enable-frozen-string-literal" - __FILE__.frozen? -RUBY - -assert_equal "false", <<~RUBY, "__FILE__ is mutable", "--enable-frozen-string-literal", frozen_string_literal: false - __FILE__.frozen? -RUBY diff --git a/bootstraptest/test_thread.rb b/bootstraptest/test_thread.rb index 4040b68a27..5361828403 100644 --- a/bootstraptest/test_thread.rb +++ b/bootstraptest/test_thread.rb @@ -242,22 +242,9 @@ assert_equal 'true', %{ end } -assert_equal 'true', %{ - Thread.new{}.join - begin - Process.waitpid2 fork{ - Thread.new{ - sleep 0.1 - }.join - } - true - rescue NotImplementedError - true - end -} - assert_equal 'ok', %{ - File.write("zzz_t1.rb", <<-END) + open("zzz_t1.rb", "w") do |f| + f.puts <<-END begin Thread.new { fork { GC.start } }.join pid, status = Process.wait2 @@ -266,6 +253,7 @@ assert_equal 'ok', %{ $result = :ok end END + end require "./zzz_t1.rb" $result } @@ -301,7 +289,7 @@ assert_normal_exit %q{ }.each {|t| t.join } -} unless rjit_enabled? # flaky +} assert_equal 'ok', %q{ def m @@ -420,7 +408,8 @@ assert_equal 'ok', %q{ } assert_equal 'ok', %{ - File.write("zzz_t2.rb", <<-'end;') # do + open("zzz_t2.rb", "w") do |f| + f.puts <<-'end;' # do begin m = Thread::Mutex.new parent = Thread.current @@ -442,6 +431,7 @@ assert_equal 'ok', %{ $result = :ok end end; + end require "./zzz_t2.rb" $result } @@ -493,7 +483,7 @@ assert_equal 'foo', %q{ [th1, th2].each {|t| t.join } GC.start f.call.source -} unless rjit_enabled? # flaky +} assert_normal_exit %q{ class C def inspect diff --git a/bootstraptest/test_yjit.rb b/bootstraptest/test_yjit.rb index f0192c0414..5c655b8f25 100644 --- a/bootstraptest/test_yjit.rb +++ b/bootstraptest/test_yjit.rb @@ -1,271 +1,3 @@ -# To run the tests in this file only, with YJIT enabled: -# make btest BTESTS=bootstraptest/test_yjit.rb RUN_OPTS="--yjit-call-threshold=1" - -# regression test for popping before side exit -assert_equal "ok", %q{ - def foo(a, *) = a - - def call(args, &) - foo(1) # spill at where the block arg will be - foo(*args, &) - end - - call([1, 2]) - - begin - call([]) - rescue ArgumentError - :ok - end -} - -# regression test for send processing before side exit -assert_equal "ok", %q{ - def foo(a, *) = :foo - - def call(args) - send(:foo, *args) - end - - call([1, 2]) - - begin - call([]) - rescue ArgumentError - :ok - end -} - -# test discarding extra yield arguments -assert_equal "2210150001501015", %q{ - def splat_kw(ary) = yield *ary, a: 1 - - def splat(ary) = yield *ary - - def kw = yield 1, 2, a: 0 - - def simple = yield 0, 1 - - def calls - [ - splat([1, 1, 2]) { |x, y| x + y }, - splat([1, 1, 2]) { |y, opt = raise| opt + y}, - splat_kw([0, 1]) { |a:| a }, - kw { |a:| a }, - kw { |a| a }, - simple { 5.itself }, - simple { |a| a }, - simple { |opt = raise| opt }, - simple { |*rest| rest }, - simple { |opt_kw: 5| opt_kw }, - # autosplat ineractions - [0, 1, 2].yield_self { |a, b| [a, b] }, - [0, 1, 2].yield_self { |a, opt = raise| [a, opt] }, - [1].yield_self { |a, opt = 4| a + opt }, - ] - end - - calls.join -} - -# test autosplat with empty splat -assert_equal "ok", %q{ - def m(pos, splat) = yield pos, *splat - - m([:ok], []) {|v0,| v0 } -} - -# regression test for send stack shifting -assert_normal_exit %q{ - def foo(a, b) - a.singleton_methods(b) - end - - def call_foo - [1, 1, 1, 1, 1, 1, send(:foo, 1, 1)] - end - - call_foo -} - -# regression test for keyword splat with yield -assert_equal 'nil', %q{ - def splat_kw(kwargs) = yield(**kwargs) - - splat_kw({}) { _1 }.inspect -} - -# regression test for arity check with splat -assert_equal '[:ae, :ae]', %q{ - def req_one(a_, b_ = 1) = raise - - def test(args) - req_one *args - rescue ArgumentError - :ae - end - - [test(Array.new 5), test([])] -} unless rjit_enabled? # Not yet working on RJIT - -# regression test for arity check with splat and send -assert_equal '[:ae, :ae]', %q{ - def two_reqs(a, b_, _ = 1) = a.gsub(a, a) - - def test(name, args) - send(name, *args) - rescue ArgumentError - :ae - end - - [test(:two_reqs, ["g", nil, nil, nil]), test(:two_reqs, ["g"])] -} - -# regression test for GC marking stubs in invalidated code -assert_normal_exit %q{ - skip true unless defined?(GC.compact) - garbage = Array.new(10_000) { [] } # create garbage to cause iseq movement - eval(<<~RUBY) - def foo(n, garbage) - if n == 2 - # 1.times.each to create a cfunc frame to preserve the JIT frame - # which will return to a stub housed in an invalidated block - return 1.times.each do - Object.define_method(:foo) {} - garbage.clear - GC.verify_compaction_references(toward: :empty, expand_heap: true) - end - end - - foo(n + 1, garbage) - end - RUBY - - foo(1, garbage) -} - -# regression test for callee block handler overlapping with arguments -assert_equal '3', %q{ - def foo(_req, *args) = args.last - - def call_foo = foo(0, 1, 2, 3, &->{}) - - call_foo -} - -# call leaf builtin with a block argument -assert_equal '0', "0.abs(&nil)" - -# regression test for invokeblock iseq guard -assert_equal 'ok', %q{ - skip :ok unless defined?(GC.compact) - def foo = yield - 10.times do |i| - ret = eval("foo { #{i} }") - raise "failed at #{i}" unless ret == i - GC.compact - end - :ok -} unless rjit_enabled? # Not yet working on RJIT - -# regression test for overly generous guard elision -assert_equal '[0, :sum, 0, :sum]', %q{ - # In faulty versions, the following happens: - # 1. YJIT puts object on the temp stack with type knowledge - # (CArray or CString) about RBASIC_CLASS(object). - # 2. In iter=0, due to the type knowledge, YJIT generates - # a call to sum() without any guard on RBASIC_CLASS(object). - # 3. In iter=1, a singleton class is added to the object, - # changing RBASIC_CLASS(object), falsifying the type knowledge. - # 4. Because the code from (1) has no class guard, it is incorrectly - # reused and the wrong method is invoked. - # Putting a literal is important for gaining type knowledge. - def carray(iter) - array = [] - array.sum(iter.times { def array.sum(_) = :sum }) - end - - def cstring(iter) - string = "".dup - string.sum(iter.times { def string.sum(_) = :sum }) - end - - [carray(0), carray(1), cstring(0), cstring(1)] -} - -# regression test for return type of Integer#/ -# It can return a T_BIGNUM when inputs are T_FIXNUM. -assert_equal 0x3fffffffffffffff.to_s, %q{ - def call(fixnum_min) - (fixnum_min / -1) - 1 - end - - call(-(2**62)) -} - -# regression test for return type of String#<< -assert_equal 'Sub', %q{ - def call(sub) = (sub << sub).itself - - class Sub < String; end - - call(Sub.new('o')).class -} - -# test splat filling required and feeding rest -assert_equal '[0, 1, 2, [3, 4]]', %q{ - public def lead_rest(a, b, *rest) - [self, a, b, rest] - end - - def call(args) = 0.lead_rest(*args) - - call([1, 2, 3, 4]) -} - -# test missing opts are nil initialized -assert_equal '[[0, 1, nil, 3], [0, 1, nil, 3], [0, 1, nil, 3, []], [0, 1, nil, 3, []]]', %q{ - public def lead_opts(a, b=binding.local_variable_get(:c), c=3) - [self, a, b, c] - end - - public def opts_rest(a=raise, b=binding.local_variable_get(:c), c=3, *rest) - [self, a, b, c, rest] - end - - def call(args) - [ - 0.lead_opts(1), - 0.lead_opts(*args), - - 0.opts_rest(1), - 0.opts_rest(*args), - ] - end - - call([1]) -} - -# test filled optionals with unspecified keyword param -assert_equal 'ok', %q{ - def opt_rest_opt_kw(_=1, *, k: :ok) = k - - def call = opt_rest_opt_kw(0) - - call -} - -# test splat empty array with rest param -assert_equal '[0, 1, 2, []]', %q{ - public def foo(a=1, b=2, *rest) - [self, a, b, rest] - end - - def call(args) = 0.foo(*args) - - call([]) -} - # 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{ @@ -294,7 +26,7 @@ assert_equal '[:ok]', %q{ # Used to crash due to GC run in rb_ensure_iv_list_size() # not marking the newly allocated [:ok]. RegressionTest.new.extender.itself -} unless rjit_enabled? # Skip on RJIT since this uncovers a crash +} assert_equal 'true', %q{ # regression test for tracking type of locals for too long @@ -344,7 +76,7 @@ assert_normal_exit %q{ } assert_normal_exit %q{ - # Test to ensure send on overridden c functions + # Test to ensure send on overriden c functions # doesn't corrupt the stack class Bar def bar(x) @@ -377,80 +109,6 @@ assert_equal '[nil, nil, nil, nil, nil, nil]', %q{ end } -assert_equal '[nil, nil, nil, nil, nil, nil]', %q{ - # Tests defined? on non-heap objects - [NilClass, TrueClass, FalseClass, Integer, Float, Symbol].each do |klass| - klass.class_eval("def foo = defined?(@foo)") - end - - [nil, true, false, 0xFABCAFE, 0.42, :cake].map do |instance| - instance.foo - instance.foo - end -} - -assert_equal '[nil, "instance-variable", nil, "instance-variable"]', %q{ - # defined? on object that changes shape between calls - class Foo - def foo - defined?(@foo) - end - - def add - @foo = 1 - end - - def remove - self.remove_instance_variable(:@foo) - end - end - - obj = Foo.new - [obj.foo, (obj.add; obj.foo), (obj.remove; obj.foo), (obj.add; obj.foo)] -} - -assert_equal '["instance-variable", 5]', %q{ - # defined? on object too complex for shape information - class Foo - def initialize - 100.times { |i| instance_variable_set("@foo#{i}", i) } - end - - def foo - [defined?(@foo5), @foo5] - end - end - - Foo.new.foo -} - -# getinstancevariable with shape too complex -assert_normal_exit %q{ - class Foo - def initialize - @a = 1 - end - - def getter - @foobar - end - end - - # Initialize ivars in changing order, making the Foo - # class have shape too complex - 100.times do |x| - foo = Foo.new - foo.instance_variable_set(:"@a#{x}", 1) - foo.instance_variable_set(:"@foobar", 777) - - # The getter method eventually sees shape too complex - r = foo.getter - if r != 777 - raise "error" - end - end -} - assert_equal '0', %q{ # This is a regression test for incomplete invalidation from # opt_setinlinecache. This test might be brittle, so @@ -748,45 +406,6 @@ assert_equal 'false', %q{ less_than 2 } -# BOP redefinition works on Integer#<= -assert_equal 'false', %q{ - def le(x, y) = x <= y - - le(2, 2) - - class Integer - def <=(_) = false - end - - le(2, 2) -} - -# BOP redefinition works on Integer#> -assert_equal 'false', %q{ - def gt(x, y) = x > y - - gt(3, 2) - - class Integer - def >(_) = false - end - - gt(3, 2) -} - -# BOP redefinition works on Integer#>= -assert_equal 'false', %q{ - def ge(x, y) = x >= y - - ge(2, 2) - - class Integer - def >=(_) = false - end - - ge(2, 2) -} - # Putobject, less-than operator, fixnums assert_equal '2', %q{ def check_index(index) @@ -1230,7 +849,6 @@ assert_equal 'special', %q{ # Test that object references in generated code get marked and moved assert_equal "good", %q{ - skip :good unless defined?(GC.compact) def bar "good" end @@ -1254,7 +872,7 @@ assert_equal "good", %q{ # Test polymorphic getinstancevariable. T_OBJECT -> T_STRING assert_equal 'ok', %q{ @hello = @h1 = @h2 = @h3 = @h4 = 'ok' - str = +"" + str = "" str.instance_variable_set(:@hello, 'ok') public def get @@ -1398,18 +1016,6 @@ assert_equal '[42, :default]', %q{ ] } -# Test default value block for Hash with opt_aref_with -assert_equal "false", <<~RUBY, frozen_string_literal: false - def index_with_string(h) - h["foo"] - end - - h = Hash.new { |h, k| k.frozen? } - - index_with_string(h) - index_with_string(h) -RUBY - # A regression test for making sure cfp->sp is proper when # hitting stubs. See :stub-sp-flush: assert_equal 'ok', %q{ @@ -1798,7 +1404,7 @@ assert_equal '{}', %q{ } # test building hash with values -assert_equal '{foo: :bar}', %q{ +assert_equal '{:foo=>:bar}', %q{ def build_hash(val) { foo: val } end @@ -1908,7 +1514,7 @@ assert_equal 'foo', %q{ } # Test that String unary plus returns the same object ID for an unfrozen string. -assert_equal 'true', <<~RUBY, frozen_string_literal: false +assert_equal 'true', %q{ def jittable_method str = "bar" @@ -1918,7 +1524,7 @@ assert_equal 'true', <<~RUBY, frozen_string_literal: false uplus_str.object_id == old_obj_id end jittable_method -RUBY +} # Test that String unary plus returns a different unfrozen string when given a frozen string assert_equal 'false', %q{ @@ -2032,85 +1638,6 @@ assert_equal 'true', %q{ jittable_method } -# test getbyte on string class -assert_equal '[97, :nil, 97, :nil, :raised]', %q{ - def getbyte(s, i) - byte = begin - s.getbyte(i) - rescue TypeError - :raised - end - - byte || :nil - end - - getbyte("a", 0) - getbyte("a", 0) - - [getbyte("a", 0), getbyte("a", 1), getbyte("a", -1), getbyte("a", -2), getbyte("a", "a")] -} unless rjit_enabled? # Not yet working on RJIT - -# Basic test for String#setbyte -assert_equal 'AoZ', %q{ - s = +"foo" - s.setbyte(0, 65) - s.setbyte(-1, 90) - s -} - -# String#setbyte IndexError -assert_equal 'String#setbyte', %q{ - def ccall = "".setbyte(1, 0) - begin - ccall - rescue => e - e.backtrace.first.split("'").last - end -} - -# String#setbyte TypeError -assert_equal 'String#setbyte', %q{ - def ccall = "".setbyte(nil, 0) - begin - ccall - rescue => e - e.backtrace.first.split("'").last - end -} - -# String#setbyte FrozenError -assert_equal 'String#setbyte', %q{ - def ccall = "a".freeze.setbyte(0, 0) - begin - ccall - rescue => e - e.backtrace.first.split("'").last - end -} - -# non-leaf String#setbyte -assert_equal 'String#setbyte', %q{ - def to_int - @caller = caller - 0 - end - - def ccall = "a".dup.setbyte(self, 98) - ccall - - @caller.first.split("'").last -} - -# non-leaf String#byteslice -assert_equal 'TypeError', %q{ - def ccall = "".byteslice(nil, nil) - begin - ccall - rescue => e - e.class - end -} - # Test << operator on string subclass assert_equal 'abab', %q{ class MyString < String; end @@ -2256,34 +1783,6 @@ assert_equal '7', %q{ foo(5,2) } -# regression test for argument registers with invalidation -assert_equal '[0, 1, 2]', %q{ - def test(n) - ret = n - binding - ret - end - - [0, 1, 2].map do |n| - test(n) - end -} - -# regression test for argument registers -assert_equal 'true', %q{ - class Foo - def ==(other) - other == nil - end - end - - def test - [Foo.new].include?(Foo.new) - end - - test -} - # test pattern matching assert_equal '[:ok, :ok]', %q{ class C @@ -2349,20 +1848,6 @@ assert_equal '123', %q{ foo(Foo) } -# Test EP == BP invalidation with moving ISEQs -assert_equal 'ok', %q{ - skip :ok unless defined?(GC.compact) - def entry - ok = proc { :ok } # set #entry as an EP-escaping ISEQ - [nil].reverse_each do # avoid exiting the JIT frame on the constant - GC.compact # move #entry ISEQ - end - ok # should be read off of escaped EP - end - - entry.call -} - # invokesuper edge case assert_equal '[:A, [:A, :B]]', %q{ class B @@ -2519,50 +2004,6 @@ assert_equal '[:A, :Btwo]', %q{ ins.foo } -# invokesuper with a block -assert_equal 'true', %q{ - class A - def foo = block_given? - end - - class B < A - def foo = super() - end - - B.new.foo { } - B.new.foo { } -} - -# invokesuper in a block -assert_equal '[0, 2]', %q{ - class A - def foo(x) = x * 2 - end - - class B < A - def foo - 2.times.map do |x| - super(x) - end - end - end - - B.new.foo - B.new.foo -} - -# invokesuper zsuper in a bmethod -assert_equal 'ok', %q{ - class Foo - define_method(:itself) { super } - end - begin - Foo.new.itself - rescue RuntimeError - :ok - end -} - # Call to fixnum assert_equal '[true, false]', %q{ def is_odd(obj) @@ -2603,16 +2044,6 @@ assert_equal '[true, false, true, false]', %q{ [is_odd(123), is_odd(456), is_odd(bignum), is_odd(bignum+1)] } -# Flonum and Flonum -assert_equal '[2.0, 0.0, 1.0, 4.0]', %q{ - [1.0 + 1.0, 1.0 - 1.0, 1.0 * 1.0, 8.0 / 2.0] -} - -# Flonum and Fixnum -assert_equal '[2.0, 0.0, 1.0, 4.0]', %q{ - [1.0 + 1, 1.0 - 1, 1.0 * 1, 8.0 / 2] -} - # Call to static and dynamic symbol assert_equal 'bar', %q{ def to_string(obj) @@ -2653,30 +2084,6 @@ assert_equal '[1, 2, 3, 4, 5]', %q{ splatarray } -# splatkw -assert_equal '[1, 2]', %q{ - def foo(a:) = [a, yield] - - def entry(&block) - a = { a: 1 } - foo(**a, &block) - end - - entry { 2 } -} -assert_equal '[1, 2]', %q{ - def foo(a:) = [a, yield] - - def entry(obj, &block) - foo(**obj, &block) - end - - entry({ a: 3 }) { 2 } - obj = Object.new - def obj.to_hash = { a: 1 } - entry(obj) { 2 } -} - assert_equal '[1, 1, 2, 1, 2, 3]', %q{ def expandarray arr = [1, 2, 3] @@ -2731,23 +2138,6 @@ assert_equal '[:not_array, nil, nil]', %q{ expandarray_not_array(obj) } -assert_equal '[1, 2]', %q{ - class NilClass - private - def to_ary - [1, 2] - end - end - - def expandarray_redefined_nilclass - a, b = nil - [a, b] - end - - expandarray_redefined_nilclass - expandarray_redefined_nilclass -} unless rjit_enabled? - assert_equal '[1, 2, nil]', %q{ def expandarray_rhs_too_small a, b, c = [1, 2] @@ -2758,17 +2148,6 @@ assert_equal '[1, 2, nil]', %q{ expandarray_rhs_too_small } -assert_equal '[nil, 2, nil]', %q{ - def foo(arr) - a, b, c = arr - end - - a, b, c1 = foo([0, 1]) - a, b, c2 = foo([0, 1, 2]) - a, b, c3 = foo([0, 1]) - [c1, c2, c3] -} - assert_equal '[1, [2]]', %q{ def expandarray_splat a, *b = [1, 2] @@ -2858,7 +2237,7 @@ assert_equal '[[:c_return, :String, :string_alias, "events_to_str"]]', %q{ events.compiled(events) events -} unless rjit_enabled? # RJIT calls extra Ruby methods +} 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{ @@ -2940,7 +2319,7 @@ assert_equal '[[:c_call, :itself]]', %q{ tp.enable { shouldnt_compile } events -} unless rjit_enabled? # RJIT calls extra Ruby methods +} 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{ @@ -2955,7 +2334,7 @@ assert_equal '[[:c_return, :itself, main]]', %q{ tp.enable { shouldnt_compile } events -} unless rjit_enabled? # RJIT calls extra Ruby methods +} unless defined?(RubyVM::MJIT) && RubyVM::MJIT.enabled? # MJIT calls extra Ruby methods # test c_call invalidation assert_equal '[[:c_call, :itself]]', %q{ @@ -3375,7 +2754,7 @@ assert_equal '[[1, 2, 3, 4]]', %q{ } # cfunc kwargs -assert_equal '{foo: 123}', %q{ +assert_equal '{:foo=>123}', %q{ def foo(bar) bar.store(:value, foo: 123) bar[:value] @@ -3386,7 +2765,7 @@ assert_equal '{foo: 123}', %q{ } # cfunc kwargs -assert_equal '{foo: 123}', %q{ +assert_equal '{:foo=>123}', %q{ def foo(bar) bar.replace(foo: 123) end @@ -3396,7 +2775,7 @@ assert_equal '{foo: 123}', %q{ } # cfunc kwargs -assert_equal '{foo: 123, bar: 456}', %q{ +assert_equal '{:foo=>123, :bar=>456}', %q{ def foo(bar) bar.replace(foo: 123, bar: 456) end @@ -3406,7 +2785,7 @@ assert_equal '{foo: 123, bar: 456}', %q{ } # variadic cfunc kwargs -assert_equal '{foo: 123}', %q{ +assert_equal '{:foo=>123}', %q{ def foo(bar) bar.merge(foo: 123) end @@ -3530,7 +2909,7 @@ assert_equal "true", %q{ } # duphash -assert_equal '{foo: 123}', %q{ +assert_equal '{:foo=>123}', %q{ def foo {foo: 123} end @@ -3540,7 +2919,7 @@ assert_equal '{foo: 123}', %q{ } # newhash -assert_equal '{foo: 2}', %q{ +assert_equal '{:foo=>2}', %q{ def foo {foo: 1+1} end @@ -4142,1090 +3521,10 @@ assert_equal 'ok', %q{ cw(4) } -assert_equal 'threw', %q{ - def foo(args) - wrap(*args) - rescue ArgumentError - 'threw' - end - - def wrap(a) - [a] - end - - foo([Hash.ruby2_keywords_hash({})]) -} - -assert_equal 'threw', %q{ - # C call - def bar(args) - Array(*args) - rescue ArgumentError - 'threw' - end - - bar([Hash.ruby2_keywords_hash({})]) -} - -# Test instance_of? and is_a? -assert_equal 'true', %q{ - 1.instance_of?(Integer) && 1.is_a?(Integer) -} - -# Test instance_of? and is_a? for singleton classes -assert_equal 'true', %q{ - a = [] - def a.test = :test - a.instance_of?(Array) && a.is_a?(Array) -} - -# Test instance_of? for singleton_class -# Yes this does really return false -assert_equal 'false', %q{ - a = [] - def a.test = :test - a.instance_of?(a.singleton_class) -} - -# Test is_a? for singleton_class -assert_equal 'true', %q{ - a = [] - def a.test = :test - a.is_a?(a.singleton_class) -} - -# Test send with splat to a cfunc -assert_equal 'true', %q{ - 1.send(:==, 1, *[]) -} - -# Test empty splat with cfunc -assert_equal '2', %q{ - def foo - Integer.sqrt(4, *[]) - end - # call twice to deal with constant exiting - foo - foo -} - -# Test non-empty splat with cfunc -assert_equal 'Hello World', %q{ - def bar - args = ["Hello "] - greeting = +"World" - greeting.insert(0, *args) - greeting - end - bar -} - -# Regression: this creates a temp stack with > 127 elements -assert_normal_exit %q{ - def foo(a) - [ - a, a, a, a, a, a, a, a, a, a, - a, a, a, a, a, a, a, a, a, a, - a, a, a, a, a, a, a, a, a, a, - a, a, a, a, a, a, a, a, a, a, - a, a, a, a, a, a, a, a, a, a, - a, a, a, a, a, a, a, a, a, a, - a, a, a, a, a, a, a, a, a, a, - a, a, a, a, a, a, a, a, a, a, - a, a, a, a, a, a, a, a, a, a, - a, a, a, a, a, a, a, a, a, a, - a, a, a, a, a, a, a, a, a, a, - a, a, a, a, a, a, a, a, a, a, - a, a, a, a, a, a, a, a, - ] - end - - def entry - foo(1) - end - - entry -} - -# Test that splat and rest combined -# properly dupe the array -assert_equal "[]", %q{ - def foo(*rest) - rest << 1 - end - - def test(splat) - foo(*splat) - end - - EMPTY = [] - custom = Object.new - def custom.to_a - EMPTY - end - - test(custom) - test(custom) - EMPTY -} - -# Rest with send -assert_equal '[1, 2, 3]', %q{ - def bar(x, *rest) - rest.insert(0, x) - end - send(:bar, 1, 2, 3) -} - -# Fix splat block arg bad compilation -assert_equal "foo", %q{ - def literal(*args, &block) - s = ''.dup - literal_append(s, *args, &block) - s - end - - def literal_append(sql, v) - sql << v - end - - literal("foo") -} - -# regression test for accidentally having a parameter truncated -# due to Rust/C signature mismatch. Used to crash with -# > [BUG] rb_vm_insn_addr2insn: invalid insn address ... -# or -# > ... `Err` value: TryFromIntError(())' -assert_normal_exit %q{ - n = 16384 - eval( - "def foo(arg); " + "_=arg;" * n + '_=1;' + "Object; end" - ) - foo 1 -} - -# Regression test for CantCompile not using starting_ctx -assert_normal_exit %q{ - class Integer - def ===(other) - false - end - end - - def my_func(x) - case x - when 1 - 1 - when 2 - 2 - else - 3 - end - end - - my_func(1) -} - -# Regression test for CantCompile not using starting_ctx -assert_equal "ArgumentError", %q{ - def literal(*args, &block) - s = ''.dup - args = [1, 2, 3] - literal_append(s, *args, &block) - s - end - - def literal_append(sql, v) - [sql.inspect, v.inspect] - end - - begin - literal("foo") - rescue ArgumentError - "ArgumentError" - end -} - -# Rest with block -# Simplified code from railsbench -assert_equal '[{"/a" => "b", as: :c, via: :post}, [], nil]', %q{ - def match(path, *rest, &block) - [path, rest, block] - end - - def map_method(method, args, &block) - options = args.last - args.pop - options[:via] = method - match(*args, options, &block) - end - - def post(*args, &block) - map_method(:post, args, &block) - end - - post "/a" => "b", as: :c -} - -# Test rest and kw_args -assert_equal '[true, true, true, true]', %q{ - def my_func(*args, base: nil, sort: true) - [args, base, sort] - end - - def calling_my_func - results = [] - results << (my_func("test") == [["test"], nil, true]) - results << (my_func("test", base: :base) == [["test"], :base, true]) - results << (my_func("test", sort: false) == [["test"], nil, false]) - results << (my_func("test", "other", base: :base) == [["test", "other"], :base, true]) - results - end - calling_my_func -} - -# Test Integer#[] with 2 args -assert_equal '0', %q{ - 3[0, 0] -} - -# unspecified_bits + checkkeyword -assert_equal '2', %q{ - def callee = 1 - - # checkkeyword should see unspecified_bits=0 (use bar), not Integer 1 (set bar = foo). - def foo(foo, bar: foo) = bar - - def entry(&block) - # write 1 at stack[3]. Calling #callee spills stack[3]. - 1 + (1 + (1 + (1 + callee))) - # &block is written to a register instead of stack[3]. When &block is popped and - # unspecified_bits is pushed, it must be written to stack[3], not to a register. - foo(1, bar: 2, &block) - end - - entry # call branch_stub_hit (spill temps) - entry # doesn't call branch_stub_hit (not spill temps) -} - -# Test rest and optional_params -assert_equal '[true, true, true, true]', %q{ - def my_func(stuff, base=nil, sort=true, *args) - [stuff, base, sort, args] - end - - def calling_my_func - results = [] - results << (my_func("test") == ["test", nil, true, []]) - results << (my_func("test", :base) == ["test", :base, true, []]) - results << (my_func("test", :base, false) == ["test", :base, false, []]) - results << (my_func("test", :base, false, "other", "other") == ["test", :base, false, ["other", "other"]]) - results - end - calling_my_func -} - -# Test rest and optional_params and splat -assert_equal '[true, true, true, true, true]', %q{ - def my_func(stuff, base=nil, sort=true, *args) - [stuff, base, sort, args] - end - - def calling_my_func - results = [] - splat = ["test"] - results << (my_func(*splat) == ["test", nil, true, []]) - splat = [:base] - results << (my_func("test", *splat) == ["test", :base, true, []]) - splat = [:base, false] - results << (my_func("test", *splat) == ["test", :base, false, []]) - splat = [:base, false, "other", "other"] - results << (my_func("test", *splat) == ["test", :base, false, ["other", "other"]]) - splat = ["test", :base, false, "other", "other"] - results << (my_func(*splat) == ["test", :base, false, ["other", "other"]]) - results - end - calling_my_func -} - -# Regression test: rest and optional and splat -assert_equal 'true', %q{ - def my_func(base=nil, *args) - [base, args] - end - - def calling_my_func - array = [] - my_func(:base, :rest1, *array) == [:base, [:rest1]] - end - - calling_my_func -} - -# Fix failed case for large splat -assert_equal 'true', %q{ - def d(a, b=:b) - end - - def calling_func - ary = 1380888.times; - d(*ary) - end - begin - calling_func - rescue ArgumentError - true - end -} unless rjit_enabled? # Not yet working on RJIT - -# Regression test: register allocator on expandarray -assert_equal '[]', %q{ - func = proc { [] } - proc do - _x, _y = func.call - end.call -} - -# Catch TAG_BREAK in a non-FINISH frame with JIT code -assert_equal '1', %q{ - def entry - catch_break - end - - def catch_break - while_true do - break - end - 1 - end - - def while_true - while true - yield - end - end - - entry -} - -assert_equal '6', %q{ - class Base - def number = 1 + yield - end - - class Sub < Base - def number = super + 2 - end - - Sub.new.number { 3 } -} - -# Integer multiplication and overflow -assert_equal '[6, -6, 9671406556917033397649408, -9671406556917033397649408, 21267647932558653966460912964485513216]', %q{ - def foo(a, b) - a * b - end - - r1 = foo(2, 3) - r2 = foo(2, -3) - r3 = foo(2 << 40, 2 << 41) - r4 = foo(2 << 40, -2 << 41) - r5 = foo(1 << 62, 1 << 62) - - [r1, r2, r3, r4, r5] -} - -# Integer multiplication and overflow (minimized regression test from test-basic) -assert_equal '8515157028618240000', %q{2128789257154560000 * 4} - -# Inlined method calls -assert_equal 'nil', %q{ - def putnil = nil - def entry = putnil - entry.inspect -} -assert_equal '1', %q{ - def putobject_1 = 1 - def entry = putobject_1 - entry -} -assert_equal 'false', %q{ - def putobject(_unused_arg1) = false - def entry = putobject(nil) - entry -} -assert_equal 'true', %q{ - def entry = yield - entry { true } -} -assert_equal 'sym', %q{ - def entry = :sym.to_sym - entry -} - -assert_normal_exit %q{ - ivars = 1024.times.map { |i| "@iv_#{i} = #{i}\n" }.join - Foo = Class.new - Foo.class_eval "def initialize() #{ivars} end" - Foo.new -} +assert_normal_exit %{ + class Bug20997 + def foo(&) = self.class.name(&) -assert_equal '0', %q{ - def spill - 1.to_i # not inlined - end - - def inline(_stack1, _stack2, _stack3, _stack4, _stack5) - 0 # inlined - end - - def entry - # RegTemps is 00111110 prior to the #inline call. - # Its return value goes to stack_idx=0, which conflicts with stack_idx=5. - inline(spill, 2, 3, 4, 5) - end - - entry -} - -# Integer succ and overflow -assert_equal '[2, 4611686018427387904]', %q{ - [1.succ, 4611686018427387903.succ] -} - -# Integer right shift -assert_equal '[0, 1, -4]', %q{ - [0 >> 1, 2 >> 1, -7 >> 1] -} - -# Integer XOR -assert_equal '[0, 0, 4]', %q{ - [0 ^ 0, 1 ^ 1, 7 ^ 3] -} - -assert_equal '[nil, "yield"]', %q{ - def defined_yield = defined?(yield) - [defined_yield, defined_yield {}] -} - -# splat with ruby2_keywords into rest parameter -assert_equal '[[{a: 1}], {}]', %q{ - ruby2_keywords def foo(*args) = args - - def bar(*args, **kw) = [args, kw] - - def pass_bar(*args) = bar(*args) - - def body - args = foo(a: 1) - pass_bar(*args) - end - - body -} - -# concatarray -assert_equal '[1, 2]', %q{ - def foo(a, b) = [a, b] - arr = [2] - foo(*[1], *arr) -} - -# pushtoarray -assert_equal '[1, 2]', %q{ - def foo(a, b) = [a, b] - arr = [1] - foo(*arr, 2) -} - -# pop before fallback -assert_normal_exit %q{ - class Foo - attr_reader :foo - - def try = foo(0, &nil) - end - - Foo.new.try -} - -# a kwrest case -assert_equal '[1, 2, {complete: false}]', %q{ - def rest(foo: 1, bar: 2, **kwrest) - [foo, bar, kwrest] - end - - def callsite = rest(complete: false) - - callsite -} - -# splat+kw_splat+opt+rest -assert_equal '[1, []]', %q{ - def opt_rest(a = 0, *rest) = [a, rest] - - def call_site(args) = opt_rest(*args, **nil) - - call_site([1]) -} - -# splat and nil kw_splat -assert_equal 'ok', %q{ - def identity(x) = x - - def splat_nil_kw_splat(args) = identity(*args, **nil) - - splat_nil_kw_splat([:ok]) -} - -# empty splat and kwsplat into leaf builtins -assert_equal '[1, 1, 1]', %q{ - empty = [] - [1.abs(*empty), 1.abs(**nil), 1.bit_length(*empty, **nil)] -} - -# splat into C methods with -1 arity -assert_equal '[[1, 2, 3], [0, 2, 3], [1, 2, 3], [2, 2, 3], [], [], [{}]]', %q{ - class Foo < Array - def push(args) = super(1, *args) - end - - def test_cfunc_vargs_splat(sub_instance, array_class, empty_kw_hash) - splat = [2, 3] - kw_splat = [empty_kw_hash] - [ - sub_instance.push(splat), - array_class[0, *splat, **nil], - array_class[1, *splat, &nil], - array_class[2, *splat, **nil, &nil], - array_class.send(:[], *kw_splat), - # kw_splat disables keywords hash handling - array_class[*kw_splat], - array_class[*kw_splat, **nil], - ] - end - - test_cfunc_vargs_splat(Foo.new, Array, Hash.ruby2_keywords_hash({})) -} - -# Class#new (arity=-1), splat, and ruby2_keywords -assert_equal '[0, {1 => 1}]', %q{ - class KwInit - attr_reader :init_args - def initialize(x = 0, **kw) - @init_args = [x, kw] - end - end - - def test(klass, args) - klass.new(*args).init_args - end - - test(KwInit, [Hash.ruby2_keywords_hash({1 => 1})]) -} - -# Chilled string setivar trigger warning -assert_equal 'literal string will be frozen in the future', %q{ - Warning[:deprecated] = true - $VERBOSE = true - $warning = "no-warning" - module ::Warning - def self.warn(message) - $warning = message.split("warning: ").last.strip - end - end - - class String - def setivar! - @ivar = 42 - end - end - - def setivar!(str) - str.setivar! - end - - 10.times { setivar!("mutable".dup) } - 10.times do - setivar!("frozen".freeze) - rescue FrozenError - end - - setivar!("chilled") # Emit warning - $warning -} - -# arity=-2 cfuncs -assert_equal '["", "1/2", [0, [:ok, 1]]]', %q{ - def test_cases(file, chain) - new_chain = chain.allocate # to call initialize directly - new_chain.send(:initialize, [0], ok: 1) - - [ - file.join, - file.join("1", "2"), - new_chain.to_a, - ] - end - - test_cases(File, Enumerator::Chain) -} - -# singleton class should invalidate Type::CString assumption -assert_equal 'foo', %q{ - def define_singleton(str, define) - if define - # Wrap a C method frame to avoid exiting JIT code on defineclass - [nil].reverse_each do - class << str - def +(_) - "foo" - end - end - end - end - "bar" - end - - def entry(define) - str = "" - # When `define` is false, #+ compiles to rb_str_plus() without a class guard. - # When the code is reused with `define` is true, the class of `str` is changed - # to a singleton class, so the block should be invalidated. - str + define_singleton(str, define) - end - - entry(false) - entry(true) -} - -assert_equal 'ok', %q{ - def ok - :ok - end - - def delegator(...) - ok(...) - end - - def caller - send(:delegator) - end - - caller -} - -# test inlining of simple iseqs -assert_equal '[:ok, :ok, :ok]', %q{ - def identity(x) = x - def foo(x, _) = x - def bar(_, _, _, _, x) = x - - def tests - [ - identity(:ok), - foo(:ok, 2), - bar(1, 2, 3, 4, :ok), - ] - end - - tests -} - -# test inlining of simple iseqs with kwargs -assert_equal '[:ok, :ok, :ok, :ok, :ok]', %q{ - def optional_unused(x, opt: :not_ok) = x - def optional_used(x, opt: :ok) = opt - def required_unused(x, req:) = x - def required_used(x, req:) = req - def unknown(x) = x - - def tests - [ - optional_unused(:ok), - optional_used(:not_ok), - required_unused(:ok, req: :not_ok), - required_used(:not_ok, req: :ok), - begin unknown(:not_ok, unknown_kwarg: :not_ok) rescue ArgumentError; :ok end, - ] - end - - tests -} - -# test simple iseqs not eligible for inlining -assert_equal '[:ok, :ok, :ok, :ok, :ok]', %q{ - def identity(x) = x - def arg_splat(x, *args) = x - def kwarg_splat(x, **kwargs) = x - def block_arg(x, &blk) = x - def block_iseq(x) = x - def call_forwarding(...) = identity(...) - - def tests - [ - arg_splat(:ok), - kwarg_splat(:ok), - block_arg(:ok, &proc { :not_ok }), - block_iseq(:ok) { :not_ok }, - call_forwarding(:ok), - ] - end - - tests -} - -# regression test for invalidating an empty block -assert_equal '0', %q{ - def foo = (* = 1).pred - - foo # compile it - - class Integer - def to_ary = [] # invalidate - end - - foo # try again -} unless rjit_enabled? # doesn't work on RJIT - -# test integer left shift with constant rhs -assert_equal [0x80000000000, 'a+', :ok].inspect, %q{ - def shift(val) = val << 43 - - def tests - int = shift(1) - str = shift("a") - - Integer.define_method(:<<) { |_| :ok } - redef = shift(1) - - [int, str, redef] - end - - tests -} - -# test integer left shift fusion followed by opt_getconstant_path -assert_equal '33', %q{ - def test(a) - (a << 5) | (Object; a) - end - - test(1) -} - -# test String#stebyte with arguments that need conversion -assert_equal "abc", %q{ - str = +"a00" - def change_bytes(str, one, two) - str.setbyte(one, "b".ord) - str.setbyte(2, two) - end - - to_int_1 = Object.new - to_int_99 = Object.new - def to_int_1.to_int = 1 - def to_int_99.to_int = 99 - - change_bytes(str, to_int_1, to_int_99) - str -} - -# test --yjit-verify-ctx for arrays with a singleton class -assert_equal "ok", %q{ - class Array - def foo - self.singleton_class.define_method(:first) { :ok } - first - end - end - - def test = [].foo - - test -} - -assert_equal '["raised", "Module", "Object"]', %q{ - def foo(obj) - obj.superclass.name - end - - ret = [] - - begin - foo(Class.allocate) - rescue TypeError - ret << 'raised' - end - - ret += [foo(Class), foo(Class.new)] -} - -# test TrueClass#=== before and after redefining TrueClass#== -assert_equal '[[true, false, false], [true, true, false], [true, :error, :error]]', %q{ - def true_eqq(x) - true === x - rescue NoMethodError - :error - end - - def test - [ - # first one is always true because rb_equal does object comparison before calling #== - true_eqq(true), - # these will use TrueClass#== - true_eqq(false), - true_eqq(:truthy), - ] - end - - results = [test] - - class TrueClass - def ==(x) - !x - end - end - - results << test - - class TrueClass - undef_method :== - end - - results << test -} unless rjit_enabled? # Not yet working on RJIT - -# test FalseClass#=== before and after redefining FalseClass#== -assert_equal '[[true, false, false], [true, false, true], [true, :error, :error]]', %q{ - def case_equal(x, y) - x === y - rescue NoMethodError - :error - end - - def test - [ - # first one is always true because rb_equal does object comparison before calling #== - case_equal(false, false), - # these will use #== - case_equal(false, true), - case_equal(false, nil), - ] - end - - results = [test] - - class FalseClass - def ==(x) - !x - end - end - - results << test - - class FalseClass - undef_method :== - end - - results << test -} unless rjit_enabled? # Not yet working on RJIT - -# test NilClass#=== before and after redefining NilClass#== -assert_equal '[[true, false, false], [true, false, true], [true, :error, :error]]', %q{ - def case_equal(x, y) - x === y - rescue NoMethodError - :error - end - - def test - [ - # first one is always true because rb_equal does object comparison before calling #== - case_equal(nil, nil), - # these will use #== - case_equal(nil, true), - case_equal(nil, false), - ] - end - - results = [test] - - class NilClass - def ==(x) - !x - end - end - - results << test - - class NilClass - undef_method :== - end - - results << test -} unless rjit_enabled? # Not yet working on RJIT - -# test struct accessors fire c_call events -assert_equal '[[:c_call, :x=], [:c_call, :x]]', %q{ - c = Struct.new(:x) - obj = c.new - - events = [] - TracePoint.new(:c_call) do - events << [_1.event, _1.method_id] - end.enable do - obj.x = 100 - obj.x - end - - events -} - -# regression test for splatting empty array -assert_equal '1', %q{ - def callee(foo) = foo - - def test_body(args) = callee(1, *args) - - test_body([]) - array = Array.new(100) - array.clear - test_body(array) -} - -# regression test for splatting empty array to cfunc -assert_normal_exit %q{ - def test_body(args) = Array(1, *args) - - test_body([]) - 0x100.times do - array = Array.new(100) - array.clear - test_body(array) + new.foo end } - -# compiling code shouldn't emit warnings as it may call into more Ruby code -assert_equal 'ok', <<~'RUBY' - # [Bug #20522] - $VERBOSE = true - Warning[:performance] = true - - module StrictWarnings - def warn(msg, **) - raise msg - end - end - Warning.singleton_class.prepend(StrictWarnings) - - class A - def compiled_method(is_private) - @some_ivar = is_private - end - end - - shape_max_variations = 8 - if defined?(RubyVM::Shape::SHAPE_MAX_VARIATIONS) && RubyVM::Shape::SHAPE_MAX_VARIATIONS != shape_max_variations - raise "Expected SHAPE_MAX_VARIATIONS to be #{shape_max_variations}, got: #{RubyVM::Shape::SHAPE_MAX_VARIATIONS}" - end - - 100.times do |i| - klass = Class.new(A) - (shape_max_variations - 1).times do |j| - obj = klass.new - obj.instance_variable_set("@base_#{i}", 42) - obj.instance_variable_set("@ivar_#{j}", 42) - end - obj = klass.new - obj.instance_variable_set("@base_#{i}", 42) - begin - obj.compiled_method(true) - rescue - # expected - end - end - - :ok -RUBY - -assert_equal 'ok', <<~'RUBY' - class MyRelation - def callee(...) - :ok - end - - def uncached(...) - callee(...) - end - - def takes_block(&block) - # push blockhandler - uncached(&block) # CI1 - end - end - - relation = MyRelation.new - relation.takes_block { } -RUBY - -assert_equal 'ok', <<~'RUBY' - def _exec_scope(...) - instance_exec(...) - end - - def ok args, body - _exec_scope(*args, &body) - end - - ok([], -> { "ok" }) -RUBY - -assert_equal 'ok', <<~'RUBY' - def _exec_scope(...) - instance_exec(...) - end - - def ok args, body - _exec_scope(*args, &body) - end - - ok(["ok"], ->(x) { x }) -RUBY - -assert_equal 'ok', <<~'RUBY' -def baz(a, b) - a + b -end - -def bar(...) - baz(...) -end - -def foo(a, ...) - bar(a, ...) -end - -def test - foo("o", "k") -end - -test -RUBY - -assert_equal '[true, true]', <<~'RUBY' - def pack - v = 1.23 - [v, v*2, v*3].pack("E*").unpack("E*") == [v, v*2, v*3] - end - - def with_buffer - v = 4.56 - b = +"x" - [v, v*2, v*3].pack("E*", buffer: b) - b[1..].unpack("E*") == [v, v*2, v*3] - end - - [pack, with_buffer] -RUBY @@ -3,15 +3,15 @@ #include "iseq.h" #include "builtin.h" -#include "builtin_binary.inc" - -#ifndef BUILTIN_BINARY_SIZE +#ifdef CROSS_COMPILING -#define BUILTIN_LOADED(feature_name, iseq) ((void)0) +#define INCLUDED_BY_BUILTIN_C 1 #include "mini_builtin.c" #else +#include "builtin_binary.inc" + static const unsigned char * bin4feature(const struct builtin_binary *bb, const char *feature, size_t *psize) { @@ -39,15 +39,15 @@ rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin size_t size; const unsigned char *bin = builtin_lookup(feature_name, &size); if (! bin) { - rb_bug("builtin_lookup: can not find %s", feature_name); + rb_bug("builtin_lookup: can not find %s\n", feature_name); } // load binary rb_vm_t *vm = GET_VM(); if (vm->builtin_function_table != NULL) rb_bug("vm->builtin_function_table should be NULL."); vm->builtin_function_table = table; + vm->builtin_inline_index = 0; const rb_iseq_t *iseq = rb_iseq_ibf_load_bytes((const char *)bin, size); - ASSUME(iseq); // otherwise an exception should have raised vm->builtin_function_table = NULL; // exec @@ -57,12 +57,6 @@ rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin #endif void -rb_free_loaded_builtin_table(void) -{ - // do nothing -} - -void Init_builtin(void) { // nothing @@ -11,13 +11,17 @@ struct rb_builtin_function { // for load const int index; const char * const name; + + // for jit + void (*compiler)(VALUE, long, unsigned, bool); }; -#define RB_BUILTIN_FUNCTION(_i, _name, _fname, _arity) {\ +#define RB_BUILTIN_FUNCTION(_i, _name, _fname, _arity, _compiler) {\ .name = _i < 0 ? NULL : #_name, \ .func_ptr = (void *)_fname, \ .argc = _arity, \ .index = _i, \ + .compiler = _compiler, \ } void rb_load_with_builtin_functions(const char *feature_name, const struct rb_builtin_function *table); @@ -106,8 +110,6 @@ rb_vm_lvar(rb_execution_context_t *ec, int index) #endif } -#define LOCAL_PTR(local) local ## __ptr - // dump/load struct builtin_binary { diff --git a/ccan/list/list.h b/ccan/list/list.h index bf692a6937..30b2af04e9 100644 --- a/ccan/list/list.h +++ b/ccan/list/list.h @@ -635,16 +635,14 @@ static inline void ccan_list_prepend_list_(struct ccan_list_head *to, /* internal macros, do not use directly */ #define ccan_list_for_each_off_dir_(h, i, off, dir) \ - for (i = 0, \ - i = ccan_list_node_to_off_(ccan_list_debug(h, CCAN_LIST_LOC)->n.dir, \ + for (i = ccan_list_node_to_off_(ccan_list_debug(h, CCAN_LIST_LOC)->n.dir, \ (off)); \ ccan_list_node_from_off_((void *)i, (off)) != &(h)->n; \ i = ccan_list_node_to_off_(ccan_list_node_from_off_((void *)i, (off))->dir, \ (off))) #define ccan_list_for_each_safe_off_dir_(h, i, nxt, off, dir) \ - for (i = 0, \ - i = ccan_list_node_to_off_(ccan_list_debug(h, CCAN_LIST_LOC)->n.dir, \ + for (i = ccan_list_node_to_off_(ccan_list_debug(h, CCAN_LIST_LOC)->n.dir, \ (off)), \ nxt = ccan_list_node_to_off_(ccan_list_node_from_off_(i, (off))->dir, \ (off)); \ @@ -29,51 +29,8 @@ #include "internal/variable.h" #include "ruby/st.h" #include "vm_core.h" -#include "yjit.h" -/* Flags of T_CLASS - * - * 0: RCLASS_IS_ROOT - * The class has been added to the VM roots. Will always be marked and pinned. - * This is done for classes defined from C to allow storing them in global variables. - * 1: RUBY_FL_SINGLETON - * This class is a singleton class. - * 2: RCLASS_SUPERCLASSES_INCLUDE_SELF - * The RCLASS_SUPERCLASSES contains the class as the last element. - * This means that this class owns the RCLASS_SUPERCLASSES list. - * if !SHAPE_IN_BASIC_FLAGS - * 4-19: SHAPE_FLAG_MASK - * Shape ID for the class. - * endif - */ - -/* Flags of T_ICLASS - * - * 0: RICLASS_IS_ORIGIN - * 3: RICLASS_ORIGIN_SHARED_MTBL - * The T_ICLASS does not own the method table. - * if !SHAPE_IN_BASIC_FLAGS - * 4-19: SHAPE_FLAG_MASK - * Shape ID. This is set but not used. - * endif - */ - -/* Flags of T_MODULE - * - * 0: RCLASS_IS_ROOT - * The class has been added to the VM roots. Will always be marked and pinned. - * This is done for classes defined from C to allow storing them in global variables. - * 1: RMODULE_ALLOCATED_BUT_NOT_INITIALIZED - * Module has not been initialized. - * 2: RCLASS_SUPERCLASSES_INCLUDE_SELF - * See RCLASS_SUPERCLASSES_INCLUDE_SELF in T_CLASS. - * 3: RMODULE_IS_REFINEMENT - * Module is used for refinements. - * if !SHAPE_IN_BASIC_FLAGS - * 4-19: SHAPE_FLAG_MASK - * Shape ID for the module. - * endif - */ +#define id_attached id__attached__ #define METACLASS_OF(k) RBASIC(k)->klass #define SET_METACLASS_OF(k, cls) RBASIC_SET_CLASS(k, cls) @@ -226,25 +183,34 @@ rb_class_detach_module_subclasses(VALUE klass) /** * Allocates a struct RClass for a new class. * - * @param flags initial value for basic.flags of the returned class. - * @param klass the class of the returned class. - * @return an uninitialized Class object. - * @pre `klass` must refer `Class` class or an ancestor of Class. - * @pre `(flags | T_CLASS) != 0` - * @post the returned class can safely be `#initialize` 'd. + * \param flags initial value for basic.flags of the returned class. + * \param klass the class of the returned class. + * \return an uninitialized Class object. + * \pre \p klass must refer \c Class class or an ancestor of Class. + * \pre \code (flags | T_CLASS) != 0 \endcode + * \post the returned class can safely be \c #initialize 'd. * - * @note this function is not Class#allocate. + * \note this function is not Class#allocate. */ static VALUE class_alloc(VALUE flags, VALUE klass) { - size_t alloc_size = sizeof(struct RClass) + sizeof(rb_classext_t); + size_t alloc_size = sizeof(struct RClass); + +#if RCLASS_EXT_EMBEDDED + alloc_size += sizeof(rb_classext_t); +#endif flags &= T_MASK; + flags |= FL_PROMOTED1 /* start from age == 2 */; if (RGENGC_WB_PROTECTED_CLASS) flags |= FL_WB_PROTECTED; - NEWOBJ_OF(obj, struct RClass, klass, flags, alloc_size, 0); + RVARGC_NEWOBJ_OF(obj, struct RClass, klass, flags, alloc_size); +#if RCLASS_EXT_EMBEDDED memset(RCLASS_EXT(obj), 0, sizeof(rb_classext_t)); +#else + obj->ptr = ZALLOC(rb_classext_t); +#endif /* ZALLOC RCLASS_CONST_TBL(obj) = 0; @@ -257,7 +223,7 @@ class_alloc(VALUE flags, VALUE klass) */ RCLASS_SET_ORIGIN((VALUE)obj, (VALUE)obj); RB_OBJ_WRITE(obj, &RCLASS_REFINED_CLASS(obj), Qnil); - RCLASS_SET_ALLOCATOR((VALUE)obj, 0); + RCLASS_ALLOCATOR(obj) = 0; return (VALUE)obj; } @@ -268,14 +234,14 @@ RCLASS_M_TBL_INIT(VALUE c) RCLASS_M_TBL(c) = rb_id_table_create(0); } -/** +/*! * A utility function that wraps class_alloc. * * allocates a class and initializes safely. - * @param super a class from which the new class derives. - * @return a class object. - * @pre `super` must be a class. - * @post the metaclass of the new class is Class. + * \param super a class from which the new class derives. + * \return a class object. + * \pre \a super must be a class. + * \post the metaclass of the new class is Class. */ VALUE rb_class_boot(VALUE super) @@ -347,7 +313,7 @@ rb_check_inheritable(VALUE super) rb_raise(rb_eTypeError, "superclass must be an instance of Class (given an instance of %"PRIsVALUE")", rb_obj_class(super)); } - if (RCLASS_SINGLETON_P(super)) { + if (RBASIC(super)->flags & FL_SINGLETON) { rb_raise(rb_eTypeError, "can't make subclass of singleton class"); } if (super == rb_cClass) { @@ -433,7 +399,7 @@ class_init_copy_check(VALUE clone, VALUE orig) if (RCLASS_SUPER(clone) != 0 || clone == rb_cBasicObject) { rb_raise(rb_eTypeError, "already initialized class"); } - if (RCLASS_SINGLETON_P(orig)) { + if (FL_TEST(orig, FL_SINGLETON)) { rb_raise(rb_eTypeError, "can't copy singleton class"); } } @@ -444,8 +410,7 @@ struct cvc_table_copy_ctx { }; static enum rb_id_table_iterator_result -cvc_table_copy(ID id, VALUE val, void *data) -{ +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; @@ -505,7 +470,7 @@ static bool ensure_origin(VALUE klass); /** * If this flag is set, that module is allocated but not initialized yet. */ -enum {RMODULE_ALLOCATED_BUT_NOT_INITIALIZED = RUBY_FL_USER1}; +enum {RMODULE_ALLOCATED_BUT_NOT_INITIALIZED = RUBY_FL_USER5}; static inline bool RMODULE_UNINITIALIZED(VALUE module) @@ -548,14 +513,14 @@ rb_mod_init_copy(VALUE clone, VALUE orig) /* cloned flag is refer at constant inline cache * see vm_get_const_key_cref() in vm_insnhelper.c */ - RCLASS_EXT(clone)->cloned = true; - RCLASS_EXT(orig)->cloned = true; + FL_SET(clone, RCLASS_CLONED); + FL_SET(orig , RCLASS_CLONED); - if (!RCLASS_SINGLETON_P(CLASS_OF(clone))) { + if (!FL_TEST(CLASS_OF(clone), FL_SINGLETON)) { RBASIC_SET_CLASS(clone, rb_singleton_class_clone(orig)); rb_singleton_class_attached(METACLASS_OF(clone), (VALUE)clone); } - RCLASS_SET_ALLOCATOR(clone, RCLASS_ALLOCATOR(orig)); + RCLASS_ALLOCATOR(clone) = RCLASS_ALLOCATOR(orig); copy_tables(clone, orig); if (RCLASS_M_TBL(orig)) { struct clone_method_arg arg; @@ -587,14 +552,11 @@ rb_mod_init_copy(VALUE clone, VALUE orig) rb_bug("non iclass between module/class and origin"); } clone_p = class_alloc(RBASIC(p)->flags, METACLASS_OF(p)); - /* We should set the m_tbl right after allocation before anything - * that can trigger GC to avoid clone_p from becoming old and - * needing to fire write barriers. */ - RCLASS_SET_M_TBL(clone_p, RCLASS_M_TBL(p)); RCLASS_SET_SUPER(prev_clone_p, clone_p); prev_clone_p = clone_p; + RCLASS_M_TBL(clone_p) = RCLASS_M_TBL(p); RCLASS_CONST_TBL(clone_p) = RCLASS_CONST_TBL(p); - RCLASS_SET_ALLOCATOR(clone_p, RCLASS_ALLOCATOR(p)); + RCLASS_ALLOCATOR(clone_p) = RCLASS_ALLOCATOR(p); if (RB_TYPE_P(clone, T_CLASS)) { RCLASS_SET_INCLUDER(clone_p, clone); } @@ -657,7 +619,7 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach) // attached to an object other than `obj`. In which case `obj` does not have // a material singleton class attached yet and there is no singleton class // to clone. - if (!(RCLASS_SINGLETON_P(klass) && RCLASS_ATTACHED_OBJECT(klass) == obj)) { + if (!(FL_TEST(klass, FL_SINGLETON) && rb_attr_get(klass, id_attached) == obj)) { // nothing to clone return klass; } @@ -679,6 +641,7 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach) } RCLASS_SET_SUPER(clone, RCLASS_SUPER(klass)); + RCLASS_ALLOCATOR(clone) = RCLASS_ALLOCATOR(klass); rb_iv_tbl_copy(clone, klass); if (RCLASS_CONST_TBL(klass)) { struct clone_const_arg arg; @@ -708,8 +671,8 @@ rb_singleton_class_clone_and_attach(VALUE obj, VALUE attach) void rb_singleton_class_attached(VALUE klass, VALUE obj) { - if (RCLASS_SINGLETON_P(klass)) { - RCLASS_SET_ATTACHED_OBJECT(klass, obj); + if (FL_TEST(klass, FL_SINGLETON)) { + rb_class_ivar_set(klass, id_attached, obj); } } @@ -723,17 +686,17 @@ rb_singleton_class_attached(VALUE klass, VALUE obj) static int rb_singleton_class_has_metaclass_p(VALUE sklass) { - return RCLASS_ATTACHED_OBJECT(METACLASS_OF(sklass)) == sklass; + return rb_attr_get(METACLASS_OF(sklass), id_attached) == sklass; } int rb_singleton_class_internal_p(VALUE sklass) { - return (RB_TYPE_P(RCLASS_ATTACHED_OBJECT(sklass), T_CLASS) && + return (RB_TYPE_P(rb_attr_get(sklass, id_attached), T_CLASS) && !rb_singleton_class_has_metaclass_p(sklass)); } -/** +/*! * whether k has a metaclass * @retval 1 if \a k has a metaclass * @retval 0 otherwise @@ -742,25 +705,25 @@ rb_singleton_class_internal_p(VALUE sklass) (FL_TEST(METACLASS_OF(k), FL_SINGLETON) && \ rb_singleton_class_has_metaclass_p(k)) -/** - * ensures `klass` belongs to its own eigenclass. - * @return the eigenclass of `klass` - * @post `klass` belongs to the returned eigenclass. - * i.e. the attached object of the eigenclass is `klass`. +/*! + * ensures \a klass belongs to its own eigenclass. + * @return the eigenclass of \a klass + * @post \a klass belongs to the returned eigenclass. + * i.e. the attached object of the eigenclass is \a klass. * @note this macro creates a new eigenclass if necessary. */ #define ENSURE_EIGENCLASS(klass) \ (HAVE_METACLASS_P(klass) ? METACLASS_OF(klass) : make_metaclass(klass)) -/** - * Creates a metaclass of `klass` - * @param klass a class - * @return created metaclass for the class - * @pre `klass` is a Class object - * @pre `klass` has no singleton class. - * @post the class of `klass` is the returned class. - * @post the returned class is meta^(n+1)-class when `klass` is a meta^(n)-klass for n >= 0 +/*! + * Creates a metaclass of \a klass + * \param klass a class + * \return created metaclass for the class + * \pre \a klass is a Class object + * \pre \a klass has no singleton class. + * \post the class of \a klass is the returned class. + * \post the returned class is meta^(n+1)-class when \a klass is a meta^(n)-klass for n >= 0 */ static inline VALUE make_metaclass(VALUE klass) @@ -791,11 +754,11 @@ make_metaclass(VALUE klass) return metaclass; } -/** - * Creates a singleton class for `obj`. - * @pre `obj` must not be an immediate nor a special const. - * @pre `obj` must not be a Class object. - * @pre `obj` has no singleton class. +/*! + * Creates a singleton class for \a obj. + * \pre \a obj must not a immediate nor a special const. + * \pre \a obj must not a Class object. + * \pre \a obj has no singleton class. */ static inline VALUE make_singleton_class(VALUE obj) @@ -806,7 +769,6 @@ make_singleton_class(VALUE obj) FL_SET(klass, FL_SINGLETON); RBASIC_SET_CLASS(obj, klass); rb_singleton_class_attached(klass, obj); - rb_yjit_invalidate_no_singleton_class(orig_class); SET_METACLASS_OF(klass, METACLASS_OF(rb_class_real(orig_class))); return klass; @@ -820,7 +782,7 @@ boot_defclass(const char *name, VALUE super) ID id = rb_intern(name); rb_const_set((rb_cObject ? rb_cObject : obj), id, obj); - rb_vm_register_global_object(obj); + rb_vm_add_root_module(obj); return obj; } @@ -876,33 +838,12 @@ refinement_import_methods(int argc, VALUE *argv, VALUE refinement) } # endif -/*! - *-- - * \private - * Initializes the world of objects and classes. - * - * At first, the function bootstraps the class hierarchy. - * It initializes the most fundamental classes and their metaclasses. - * - \c BasicObject - * - \c Object - * - \c Module - * - \c Class - * After the bootstrap step, the class hierarchy becomes as the following - * diagram. - * - * \image html boottime-classes.png - * - * Then, the function defines classes, modules and methods as usual. - * \ingroup class - *++ - */ - void Init_class_hierarchy(void) { rb_cBasicObject = boot_defclass("BasicObject", 0); rb_cObject = boot_defclass("Object", rb_cBasicObject); - rb_vm_register_global_object(rb_cObject); + rb_gc_register_mark_object(rb_cObject); /* resolve class name ASAP for order-independence */ rb_set_class_path_string(rb_cObject, rb_cObject, rb_fstring_lit("Object")); @@ -927,15 +868,15 @@ Init_class_hierarchy(void) } -/** - * @internal +/*! + * \internal * Creates a new *singleton class* for an object. * - * @pre `obj` has no singleton class. - * @note DO NOT USE the function in an extension libraries. Use @ref rb_singleton_class. - * @param obj An object. - * @param unused ignored. - * @return The singleton class of the object. + * \pre \a obj has no singleton class. + * \note DO NOT USE the function in an extension libraries. Use \ref rb_singleton_class. + * \param obj An object. + * \param unused ignored. + * \return The singleton class of the object. */ VALUE rb_make_metaclass(VALUE obj, VALUE unused) @@ -961,15 +902,15 @@ rb_define_class_id(ID id, VALUE super) } -/** +/*! * Calls Class#inherited. - * @param super A class which will be called #inherited. + * \param super A class which will be called #inherited. * NULL means Object class. - * @param klass A Class object which derived from `super` - * @return the value `Class#inherited` returns - * @pre Each of `super` and `klass` must be a `Class` object. + * \param klass A Class object which derived from \a super + * \return the value \c Class#inherited's returns + * \pre Each of \a super and \a klass must be a \c Class object. */ -VALUE +MJIT_FUNC_EXPORTED VALUE rb_class_inherited(VALUE super, VALUE klass) { ID inherited; @@ -996,14 +937,14 @@ rb_define_class(const char *name, VALUE super) } /* Class may have been defined in Ruby and not pin-rooted */ - rb_vm_register_global_object(klass); + rb_vm_add_root_module(klass); return klass; } if (!super) { - rb_raise(rb_eArgError, "no super class for '%s'", name); + rb_raise(rb_eArgError, "no super class for `%s'", name); } klass = rb_define_class_id(id, super); - rb_vm_register_global_object(klass); + rb_vm_add_root_module(klass); rb_const_set(rb_cObject, id, klass); rb_class_inherited(super, klass); @@ -1038,7 +979,7 @@ rb_define_class_id_under_no_pin(VALUE outer, ID id, VALUE super) return klass; } if (!super) { - rb_raise(rb_eArgError, "no super class for '%"PRIsVALUE"::%"PRIsVALUE"'", + rb_raise(rb_eArgError, "no super class for `%"PRIsVALUE"::%"PRIsVALUE"'", rb_class_path(outer), rb_id2str(id)); } klass = rb_define_class_id(id, super); @@ -1053,7 +994,7 @@ 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_register_global_object(klass); + rb_vm_add_root_module(klass); return klass; } @@ -1107,11 +1048,11 @@ rb_define_module(const char *name) name, rb_obj_class(module)); } /* Module may have been defined in Ruby and not pin-rooted */ - rb_vm_register_global_object(module); + rb_vm_add_root_module(module); return module; } module = rb_module_new(); - rb_vm_register_global_object(module); + rb_vm_add_root_module(module); rb_const_set(rb_cObject, id, module); return module; @@ -1136,13 +1077,13 @@ rb_define_module_id_under(VALUE outer, ID id) outer, rb_id2str(id), rb_obj_class(module)); } /* Module may have been defined in Ruby and not pin-rooted */ - rb_vm_register_global_object(module); + rb_gc_register_mark_object(module); return module; } module = rb_module_new(); rb_const_set(outer, id, module); rb_set_class_path_string(module, outer, rb_id2str(id)); - rb_vm_register_global_object(module); + rb_gc_register_mark_object(module); return module; } @@ -1152,7 +1093,7 @@ rb_include_class_new(VALUE module, VALUE super) { VALUE klass = class_alloc(T_ICLASS, rb_cClass); - RCLASS_SET_M_TBL(klass, RCLASS_M_TBL(module)); + RCLASS_M_TBL(klass) = RCLASS_M_TBL(module); RCLASS_SET_ORIGIN(klass, klass); if (BUILTIN_TYPE(module) == T_ICLASS) { @@ -1204,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. */ @@ -1424,10 +1365,10 @@ ensure_origin(VALUE klass) VALUE origin = RCLASS_ORIGIN(klass); if (origin == klass) { origin = class_alloc(T_ICLASS, klass); - RCLASS_SET_M_TBL(origin, RCLASS_M_TBL(klass)); RCLASS_SET_SUPER(origin, RCLASS_SUPER(klass)); RCLASS_SET_SUPER(klass, origin); RCLASS_SET_ORIGIN(klass, origin); + RCLASS_M_TBL(origin) = RCLASS_M_TBL(klass); RCLASS_M_TBL_INIT(klass); rb_id_table_foreach(RCLASS_M_TBL(origin), cache_clear_refined_method, (void *)klass); rb_id_table_foreach(RCLASS_M_TBL(origin), move_refined_method, (void *)klass); @@ -1611,7 +1552,7 @@ class_descendants_recursive(VALUE klass, VALUE v) { struct subclass_traverse_data *data = (struct subclass_traverse_data *) v; - if (BUILTIN_TYPE(klass) == T_CLASS && !RCLASS_SINGLETON_P(klass)) { + if (BUILTIN_TYPE(klass) == T_CLASS && !FL_TEST(klass, FL_SINGLETON)) { if (data->buffer && data->count < data->maxcount && !rb_objspace_garbage_object_p(klass)) { // assumes that this does not cause GC as long as the length does not exceed the capacity rb_ary_push(data->buffer, klass); @@ -1716,11 +1657,11 @@ rb_class_subclasses(VALUE klass) VALUE rb_class_attached_object(VALUE klass) { - if (!RCLASS_SINGLETON_P(klass)) { - rb_raise(rb_eTypeError, "'%"PRIsVALUE"' is not a singleton class", klass); + if (!FL_TEST(klass, FL_SINGLETON)) { + rb_raise(rb_eTypeError, "`%"PRIsVALUE"' is not a singleton class", klass); } - return RCLASS_ATTACHED_OBJECT(klass); + return rb_attr_get(klass, id_attached); } static void @@ -1819,7 +1760,7 @@ static bool particular_class_p(VALUE mod) { if (!mod) return false; - if (RCLASS_SINGLETON_P(mod)) return true; + if (FL_TEST(mod, FL_SINGLETON)) return true; if (BUILTIN_TYPE(mod) == T_ICLASS) return true; return false; } @@ -2096,19 +2037,19 @@ rb_obj_singleton_methods(int argc, const VALUE *argv, VALUE obj) int recur = TRUE; if (rb_check_arity(argc, 0, 1)) recur = RTEST(argv[0]); - if (RCLASS_SINGLETON_P(obj)) { + if (RB_TYPE_P(obj, T_CLASS) && FL_TEST(obj, FL_SINGLETON)) { rb_singleton_class(obj); } klass = CLASS_OF(obj); origin = RCLASS_ORIGIN(klass); me_arg.list = st_init_numtable(); me_arg.recur = recur; - if (klass && RCLASS_SINGLETON_P(klass)) { + if (klass && FL_TEST(klass, FL_SINGLETON)) { if ((mtbl = RCLASS_M_TBL(origin)) != 0) rb_id_table_foreach(mtbl, method_entry_i, &me_arg); klass = RCLASS_SUPER(klass); } if (recur) { - while (klass && (RCLASS_SINGLETON_P(klass) || RB_TYPE_P(klass, T_ICLASS))) { + while (klass && (FL_TEST(klass, FL_SINGLETON) || RB_TYPE_P(klass, T_ICLASS))) { if (klass != origin && (mtbl = RCLASS_M_TBL(klass)) != 0) rb_id_table_foreach(mtbl, method_entry_i, &me_arg); klass = RCLASS_SUPER(klass); } @@ -2212,13 +2153,13 @@ rb_special_singleton_class(VALUE obj) return special_singleton_class_of(obj); } -/** - * @internal - * Returns the singleton class of `obj`. Creates it if necessary. +/*! + * \internal + * Returns the singleton class of \a obj. Creates it if necessary. * - * @note DO NOT expose the returned singleton class to + * \note DO NOT expose the returned singleton class to * outside of class.c. - * Use @ref rb_singleton_class instead for + * Use \ref rb_singleton_class instead for * consistency of the metaclass hierarchy. */ static VALUE @@ -2242,17 +2183,14 @@ singleton_class_of(VALUE obj) return klass; case T_STRING: - if (CHILLED_STRING_P(obj)) { - CHILLED_STRING_MUTATED(obj); - } - else if (FL_TEST_RAW(obj, RSTRING_FSTR)) { + if (FL_TEST_RAW(obj, RSTRING_FSTR)) { rb_raise(rb_eTypeError, "can't define singleton"); } } klass = METACLASS_OF(obj); - if (!(RCLASS_SINGLETON_P(klass) && - RCLASS_ATTACHED_OBJECT(klass) == obj)) { + if (!(FL_TEST(klass, FL_SINGLETON) && + rb_attr_get(klass, id_attached) == obj)) { klass = rb_make_metaclass(obj, klass); } @@ -2265,21 +2203,21 @@ void rb_freeze_singleton_class(VALUE x) { /* should not propagate to meta-meta-class, and so on */ - if (!RCLASS_SINGLETON_P(x)) { + if (!(RBASIC(x)->flags & FL_SINGLETON)) { VALUE klass = RBASIC_CLASS(x); if (klass && // no class when hidden from ObjectSpace FL_TEST(klass, (FL_SINGLETON|FL_FREEZE)) == FL_SINGLETON) { - OBJ_FREEZE(klass); + OBJ_FREEZE_RAW(klass); } } } -/** - * Returns the singleton class of `obj`, or nil if obj is not a +/*! + * Returns the singleton class of \a obj, or nil if obj is not a * singleton object. * - * @param obj an arbitrary object. - * @return the singleton class or nil. + * \param obj an arbitrary object. + * \return the singleton class or nil. */ VALUE rb_singleton_class_get(VALUE obj) @@ -2290,8 +2228,8 @@ rb_singleton_class_get(VALUE obj) return rb_special_singleton_class(obj); } klass = METACLASS_OF(obj); - if (!RCLASS_SINGLETON_P(klass)) return Qnil; - if (RCLASS_ATTACHED_OBJECT(klass) != obj) return Qnil; + if (!FL_TEST(klass, FL_SINGLETON)) return Qnil; + if (rb_attr_get(klass, id_attached) != obj) return Qnil; return klass; } @@ -2355,7 +2293,7 @@ rb_define_attr(VALUE klass, const char *name, int read, int write) rb_attr(klass, rb_intern(name), read, write, FALSE); } -VALUE +MJIT_FUNC_EXPORTED VALUE rb_keyword_error_new(const char *error, VALUE keys) { long i = 0, len = RARRAY_LEN(keys); @@ -1,12 +1,10 @@ # -*- mode: makefile-gmake; indent-tabs-mode: t -*- -# This fragment can be used with nmake.exe and with bsdmake. -# Avoid features specific to GNU Make. bin: $(PROGRAM) $(WPROGRAM) lib: $(LIBRUBY) dll: $(LIBRUBY_SO) -.SUFFIXES: .rbinc .rbbin .rb .inc .h .c .y .i .$(ASMEXT) .$(DTRACE_EXT) +.SUFFIXES: .rbinc .rb .inc .h .c .y .i .$(ASMEXT) .$(DTRACE_EXT) # V=0 quiet, V=1 verbose. other values don't work. V = 0 @@ -45,15 +43,20 @@ RUN_OPTS = --disable-gems # GITPULLOPTIONS = --no-tags -PRISM_SRCDIR = $(srcdir)/prism -INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir) -I$(PRISM_SRCDIR) -I$(UNICODE_HDR_DIR) $(incflags) +INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir) -I$(srcdir) -I$(UNICODE_HDR_DIR) $(incflags) GEM_HOME = GEM_PATH = GEM_VENDOR = BENCHMARK_DRIVER_GIT_URL = https://github.com/benchmark-driver/benchmark-driver -BENCHMARK_DRIVER_GIT_REF = v0.16.3 +BENCHMARK_DRIVER_GIT_REF = v0.16.0 +SIMPLECOV_GIT_URL = https://github.com/colszowka/simplecov.git +SIMPLECOV_GIT_REF = v0.17.0 +SIMPLECOV_HTML_GIT_URL = https://github.com/colszowka/simplecov-html.git +SIMPLECOV_HTML_GIT_REF = v0.10.2 +DOCLIE_GIT_URL = https://github.com/ms-ati/docile.git +DOCLIE_GIT_REF = v1.3.2 STATIC_RUBY = static-ruby @@ -64,53 +67,25 @@ LIBRUBY_EXTS = ./.libruby-with-ext.time REVISION_H = ./.revision.time PLATFORM_D = $(TIMESTAMPDIR)/.$(PLATFORM_DIR).time ENC_TRANS_D = $(TIMESTAMPDIR)/.enc-trans.time -RDOC = $(XRUBY) "$(tooldir)/rdoc-srcdir" +RDOC = $(XRUBY) "$(srcdir)/libexec/rdoc" --root "$(srcdir)" --encoding=UTF-8 --all RDOCOUT = $(EXTOUT)/rdoc HTMLOUT = $(EXTOUT)/html CAPIOUT = doc/capi INSTALL_DOC_OPTS = --rdoc-output="$(RDOCOUT)" --html-output="$(HTMLOUT)" -RDOC_GEN_OPTS = --no-force-update \ +RDOC_GEN_OPTS = --page-dir "$(srcdir)/doc" --no-force-update \ --title "Documentation for Ruby $(RUBY_API_VERSION)" \ - $(empty) + --main README.md INITOBJS = dmyext.$(OBJEXT) dmyenc.$(OBJEXT) NORMALMAINOBJ = main.$(OBJEXT) MAINOBJ = $(NORMALMAINOBJ) DLDOBJS = $(INITOBJS) EXTSOLIBS = -MINIOBJS = $(ARCHMINIOBJS) miniinit.$(OBJEXT) +MINIOBJS = $(ARCHMINIOBJS) miniinit.$(OBJEXT) dmyext.$(OBJEXT) ENC_MK = enc.mk MAKE_ENC = -f $(ENC_MK) V="$(V)" UNICODE_HDR_DIR="$(UNICODE_HDR_DIR)" \ RUBY="$(BOOTSTRAPRUBY)" MINIRUBY="$(BOOTSTRAPRUBY)" $(mflags) -PRISM_BUILD_DIR = prism - -PRISM_FILES = prism/api_node.$(OBJEXT) \ - prism/api_pack.$(OBJEXT) \ - prism/diagnostic.$(OBJEXT) \ - prism/encoding.$(OBJEXT) \ - prism/extension.$(OBJEXT) \ - prism/node.$(OBJEXT) \ - prism/options.$(OBJEXT) \ - prism/pack.$(OBJEXT) \ - prism/prettyprint.$(OBJEXT) \ - prism/regexp.$(OBJEXT) \ - prism/serialize.$(OBJEXT) \ - prism/static_literals.$(OBJEXT) \ - prism/token_type.$(OBJEXT) \ - prism/util/pm_buffer.$(OBJEXT) \ - prism/util/pm_char.$(OBJEXT) \ - prism/util/pm_constant_pool.$(OBJEXT) \ - prism/util/pm_integer.$(OBJEXT) \ - prism/util/pm_list.$(OBJEXT) \ - prism/util/pm_memchr.$(OBJEXT) \ - prism/util/pm_newline_list.$(OBJEXT) \ - prism/util/pm_string.$(OBJEXT) \ - prism/util/pm_strncasecmp.$(OBJEXT) \ - prism/util/pm_strpbrk.$(OBJEXT) \ - prism/prism.$(OBJEXT) \ - prism_init.$(OBJEXT) - COMMONOBJS = array.$(OBJEXT) \ ast.$(OBJEXT) \ bignum.$(OBJEXT) \ @@ -132,7 +107,6 @@ COMMONOBJS = array.$(OBJEXT) \ gc.$(OBJEXT) \ hash.$(OBJEXT) \ inits.$(OBJEXT) \ - imemo.$(OBJEXT) \ io.$(OBJEXT) \ io_buffer.$(OBJEXT) \ iseq.$(OBJEXT) \ @@ -140,15 +114,13 @@ COMMONOBJS = array.$(OBJEXT) \ marshal.$(OBJEXT) \ math.$(OBJEXT) \ memory_view.$(OBJEXT) \ - rjit.$(OBJEXT) \ - rjit_c.$(OBJEXT) \ + mjit.$(OBJEXT) \ + mjit_c.$(OBJEXT) \ node.$(OBJEXT) \ - node_dump.$(OBJEXT) \ numeric.$(OBJEXT) \ object.$(OBJEXT) \ pack.$(OBJEXT) \ parse.$(OBJEXT) \ - parser_st.$(OBJEXT) \ proc.$(OBJEXT) \ process.$(OBJEXT) \ ractor.$(OBJEXT) \ @@ -163,7 +135,6 @@ COMMONOBJS = array.$(OBJEXT) \ regparse.$(OBJEXT) \ regsyntax.$(OBJEXT) \ ruby.$(OBJEXT) \ - ruby_parser.$(OBJEXT) \ scheduler.$(OBJEXT) \ shape.$(OBJEXT) \ signal.$(OBJEXT) \ @@ -176,6 +147,7 @@ COMMONOBJS = array.$(OBJEXT) \ thread.$(OBJEXT) \ time.$(OBJEXT) \ transcode.$(OBJEXT) \ + transient_heap.$(OBJEXT) \ util.$(OBJEXT) \ variable.$(OBJEXT) \ version.$(OBJEXT) \ @@ -184,106 +156,20 @@ COMMONOBJS = array.$(OBJEXT) \ vm_dump.$(OBJEXT) \ vm_sync.$(OBJEXT) \ vm_trace.$(OBJEXT) \ - weakmap.$(OBJEXT) \ - $(PRISM_FILES) \ $(YJIT_OBJ) \ - $(YJIT_LIBOBJ) \ $(COROUTINE_OBJ) \ $(DTRACE_OBJ) \ $(BUILTIN_ENCOBJS) \ $(BUILTIN_TRANSOBJS) \ $(MISSING) -$(PRISM_FILES): $(PRISM_BUILD_DIR)/.time $(PRISM_BUILD_DIR)/util/.time - -$(PRISM_BUILD_DIR)/.time $(PRISM_BUILD_DIR)/util/.time: - $(Q) $(MAKEDIRS) $(@D) - @$(NULLCMD) > $@ - -main: $(srcdir)/lib/prism/compiler.rb -srcs: $(srcdir)/lib/prism/compiler.rb -$(srcdir)/lib/prism/compiler.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/compiler.rb.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/compiler.rb $(srcdir)/lib/prism/compiler.rb - -main: $(srcdir)/lib/prism/dispatcher.rb -srcs: $(srcdir)/lib/prism/dispatcher.rb -$(srcdir)/lib/prism/dispatcher.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/dispatcher.rb.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/dispatcher.rb $(srcdir)/lib/prism/dispatcher.rb - -main: $(srcdir)/lib/prism/dsl.rb -srcs: $(srcdir)/lib/prism/dsl.rb -$(srcdir)/lib/prism/dsl.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/dsl.rb.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/dsl.rb $(srcdir)/lib/prism/dsl.rb - -main: $(srcdir)/lib/prism/inspect_visitor.rb -srcs: $(srcdir)/lib/prism/inspect_visitor.rb -$(srcdir)/lib/prism/inspect_visitor.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/inspect_visitor.rb.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/inspect_visitor.rb $(srcdir)/lib/prism/inspect_visitor.rb - -main: $(srcdir)/lib/prism/mutation_compiler.rb -srcs: $(srcdir)/lib/prism/mutation_compiler.rb -$(srcdir)/lib/prism/mutation_compiler.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/mutation_compiler.rb.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/mutation_compiler.rb $(srcdir)/lib/prism/mutation_compiler.rb - -main: $(srcdir)/lib/prism/node.rb -srcs: $(srcdir)/lib/prism/node.rb -$(srcdir)/lib/prism/node.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/node.rb.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/node.rb $(srcdir)/lib/prism/node.rb - -main: $(srcdir)/lib/prism/reflection.rb -srcs: $(srcdir)/lib/prism/reflection.rb -$(srcdir)/lib/prism/reflection.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/reflection.rb.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/reflection.rb $(srcdir)/lib/prism/reflection.rb - -main: $(srcdir)/lib/prism/serialize.rb -srcs: $(srcdir)/lib/prism/serialize.rb -$(srcdir)/lib/prism/serialize.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/serialize.rb.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/serialize.rb $(srcdir)/lib/prism/serialize.rb - -main: $(srcdir)/lib/prism/visitor.rb -srcs: $(srcdir)/lib/prism/visitor.rb -$(srcdir)/lib/prism/visitor.rb: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/lib/prism/visitor.rb.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb lib/prism/visitor.rb $(srcdir)/lib/prism/visitor.rb - -srcs: prism/api_node.c -prism/api_node.c: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/ext/prism/api_node.c.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb ext/prism/api_node.c $@ - -srcs: prism/ast.h -prism/ast.h: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/include/prism/ast.h.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb include/prism/ast.h $@ - -srcs: prism/diagnostic.c -prism/diagnostic.c: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/src/diagnostic.c.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb src/diagnostic.c $@ - -srcs: prism/diagnostic.h -prism/diagnostic.h: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/include/prism/diagnostic.h.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb include/prism/diagnostic.h $@ - -srcs: prism/node.c -prism/node.c: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/src/node.c.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb src/node.c $@ - -srcs: prism/prettyprint.c -prism/prettyprint.c: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/src/prettyprint.c.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb src/prettyprint.c $@ - -srcs: prism/serialize.c -prism/serialize.c: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/src/serialize.c.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb src/serialize.c $@ - -srcs: prism/token_type.c -prism/token_type.c: $(PRISM_SRCDIR)/config.yml $(PRISM_SRCDIR)/templates/template.rb $(PRISM_SRCDIR)/templates/src/token_type.c.erb - $(Q) $(BASERUBY) $(PRISM_SRCDIR)/templates/template.rb src/token_type.c $@ - EXPORTOBJS = $(DLNOBJ) \ localeinit.$(OBJEXT) \ loadpath.$(OBJEXT) \ $(COMMONOBJS) OBJS = $(EXPORTOBJS) builtin.$(OBJEXT) -ALLOBJS = $(OBJS) $(MINIOBJS) $(INITOBJS) $(MAINOBJ) +ALLOBJS = $(NORMALMAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(INITOBJS) GOLFOBJS = goruby.$(OBJEXT) @@ -291,7 +177,7 @@ DEFAULT_PRELUDES = $(GEM_PRELUDE) PRELUDE_SCRIPTS = $(DEFAULT_PRELUDES) GEM_PRELUDE = PRELUDES = {$(srcdir)}miniprelude.c -GOLFPRELUDES = golf_prelude.rbbin +GOLFPRELUDES = {$(srcdir)}golf_prelude.c SCRIPT_ARGS = --dest-dir="$(DESTDIR)" \ --extout="$(EXTOUT)" \ @@ -315,7 +201,7 @@ INSTALL_DATA_MODE = 0644 BOOTSTRAPRUBY_COMMAND = $(BOOTSTRAPRUBY) $(BOOTSTRAPRUBY_OPT) TESTSDIR = $(srcdir)/test TOOL_TESTSDIR = $(tooldir)/test -TEST_EXCLUDES = --excludes-dir=$(TESTSDIR)/.excludes --name=!/memory_leak/ +TEST_EXCLUDES = --excludes-dir=$(TESTSDIR)/excludes --name=!/memory_leak/ TESTWORKDIR = testwork TESTOPTS = $(RUBY_TESTOPTS) @@ -339,26 +225,55 @@ YJIT_RUSTC_ARGS = --crate-name=yjit \ --crate-type=staticlib \ --edition=2021 \ -g \ - -C lto=thin \ -C opt-level=3 \ -C overflow-checks=on \ '--out-dir=$(CARGO_TARGET_DIR)/release/' \ $(top_srcdir)/yjit/src/lib.rs -all: $(SHOWFLAGS) main +all: $(SHOWFLAGS) main docs main: $(SHOWFLAGS) exts $(ENCSTATIC:static=lib)encs @$(NULLCMD) -main: $(srcdir)/lib/ruby_vm/rjit/instruction.rb -srcs: $(srcdir)/lib/ruby_vm/rjit/instruction.rb -$(srcdir)/lib/ruby_vm/rjit/instruction.rb: $(tooldir)/insns2vm.rb $(tooldir)/ruby_vm/views/lib/ruby_vm/rjit/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) $@ -.PHONY: rjit-bindgen -rjit-bindgen: - $(Q) $(BASERUBY) -rrubygems -C $(srcdir)/tool/rjit bindgen.rb $(CURDIR) +mjit-headers: $(MJIT_SUPPORT)-mjit-headers +no-mjit-headers: PHONY +yes-mjit-headers: mjit_config.h PHONY + +mjit.$(OBJEXT): mjit_config.h +mjit_config.h: Makefile + +.PHONY: mjit-bindgen +mjit-bindgen: + $(Q) $(BASERUBY) -rrubygems -C $(srcdir)/tool/mjit bindgen.rb $(CURDIR) + +# These rules using MJIT_HEADER_SUFFIX must be in common.mk, not +# Makefile.in, in order to override the macro in defs/universal.mk. + +# Other `-Dxxx`s preceding `-DMJIT_HEADER` will be removed in transform_mjit_header.rb. +# So `-DMJIT_HEADER` should be passed first when rb_mjit_header.h is generated. +$(TIMESTAMPDIR)/$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).time: probes.h vm.$(OBJEXT) \ + $(TIMESTAMPDIR)/$(arch)/.time $(tooldir)/mjit_tabs.rb $(PREP) $(RBCONFIG) + $(ECHO) building $(@F:.time=.h) + $(Q)$(MINIRUBY) $(tooldir)/mjit_tabs.rb "$(MJIT_TABS)" \ + $(CPP) -DMJIT_HEADER $(MJIT_HEADER_FLAGS) $(CFLAGS) $(XCFLAGS) $(CPPFLAGS) $(srcdir)/vm.c $(CPPOUTFLAG)$(@F:.time=.h).new + $(Q) $(IFCHANGE) "--timestamp=$@" $(@F:.time=.h) $(@F:.time=.h).new + +$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).h: $(TIMESTAMPDIR)/$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).time + +$(MJIT_MIN_HEADER:.h=)$(MJIT_HEADER_SUFFIX).h: \ + $(TIMESTAMPDIR)/$(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).time \ + $(tooldir)/transform_mjit_header.rb $(PREP) \ + $(MJIT_HEADER:.h=)$(MJIT_HEADER_SUFFIX).h + $(ECHO) building $@ + $(Q)$(MINIRUBY) $(tooldir)/transform_mjit_header.rb "$(CC) $(CFLAGS) -w" $(MJIT_HEADER:.h=)$(MJIT_HEADER_ARCH).h $@ + $(Q) $(MAKEDIRS) $(MJIT_HEADER_INSTALL_DIR) + $(Q) $(MAKE_LINK) $@ $(MJIT_HEADER_INSTALL_DIR)/$(@F) .PHONY: showflags exts enc trans: $(SHOWFLAGS) @@ -414,8 +329,7 @@ configure-ext: $(EXTS_MK) build-ext: $(EXTS_MK) $(Q)$(MAKE) -f $(EXTS_MK) $(mflags) libdir="$(libdir)" LIBRUBY_EXTS=$(LIBRUBY_EXTS) \ - EXTENCS="$(ENCOBJS)" BASERUBY="$(BASERUBY)" MINIRUBY="$(MINIRUBY)" \ - $(EXTSTATIC) + EXTENCS="$(ENCOBJS)" MINIRUBY="$(MINIRUBY)" UPDATE_LIBRARIES=no $(EXTSTATIC) $(Q)$(MAKE) $(EXTS_NOTE) exts-note: $(EXTS_MK) @@ -431,7 +345,7 @@ programs: $(PROGRAM) $(WPROGRAM) $(arch)-fake.rb $(PREP): $(MKFILES) -miniruby$(EXEEXT): config.status $(NORMALMAINOBJ) $(MINIOBJS) $(COMMONOBJS) $(ARCHFILE) +miniruby$(EXEEXT): config.status $(ALLOBJS) $(ARCHFILE) objs: $(ALLOBJS) @@ -458,8 +372,8 @@ Doxyfile: $(srcdir)/template/Doxyfile.tmpl $(PREP) $(tooldir)/generic_erb.rb $(R $(Q) $(MINIRUBY) $(tooldir)/generic_erb.rb -o $@ $(srcdir)/template/Doxyfile.tmpl \ --srcdir="$(srcdir)" --miniruby="$(MINIRUBY)" -program: $(SHOWFLAGS) $(DOT_WAIT) $(PROGRAM) -wprogram: $(SHOWFLAGS) $(DOT_WAIT) $(WPROGRAM) +program: $(SHOWFLAGS) $(PROGRAM) +wprogram: $(SHOWFLAGS) $(WPROGRAM) mini: PHONY miniruby$(EXEEXT) $(PROGRAM) $(WPROGRAM): $(LIBRUBY) $(MAINOBJ) $(OBJS) $(EXTOBJS) $(SETUP) $(PREP) @@ -479,17 +393,19 @@ ruby.imp: $(COMMONOBJS) $(Q){ \ $(NM) -Pgp $(COMMONOBJS) | \ awk 'BEGIN{print "#!"}; $$2~/^[A-TV-Z]$$/&&$$1!~/^$(SYMBOL_PREFIX)(Init_|InitVM_|ruby_static_id_|.*_threadptr_|rb_ec_)|^\./{print $$1}'; \ + ($(CHDIR) $(srcdir) && \ + exec sed -n '/^MJIT_FUNC_EXPORTED/!d;N;s/.*\n\(rb_[a-zA-Z_0-9]*\).*/$(SYMBOL_PREFIX)\1/p' cont.c gc.c thread*c vm*.c) \ } | \ sort -u -o $@ install: install-$(INSTALLDOC) -docs: srcs-doc $(DOCTARGETS) +docs: $(DOCTARGETS) pkgconfig-data: $(ruby_pc) $(ruby_pc): $(srcdir)/template/ruby.pc.in config.status -install-all: pre-install-all do-install-all post-install-all +install-all: docs pre-install-all do-install-all post-install-all pre-install-all:: all pre-install-local pre-install-ext pre-install-gem pre-install-doc -do-install-all: pre-install-all $(DOT_WAIT) docs +do-install-all: pre-install-all $(INSTRUBY) --make="$(MAKE)" $(INSTRUBY_ARGS) --install=all $(INSTALL_DOC_OPTS) post-install-all:: post-install-local post-install-ext post-install-gem post-install-doc @$(NULLCMD) @@ -677,24 +593,18 @@ do-install-dbg: $(PROGRAM) pre-install-dbg post-install-dbg:: @$(NULLCMD) -rdoc: PHONY main srcs-doc +rdoc: PHONY main @echo Generating RDoc documentation - $(Q) $(RDOC) --ri --op "$(RDOCOUT)" $(RDOC_GEN_OPTS) $(RDOCFLAGS) . + $(Q) $(RDOC) --ri --op "$(RDOCOUT)" $(RDOC_GEN_OPTS) $(RDOCFLAGS) "$(srcdir)" -html: PHONY main srcs-doc +html: PHONY main @echo Generating RDoc HTML files - $(Q) $(RDOC) --op "$(HTMLOUT)" $(RDOC_GEN_OPTS) $(RDOCFLAGS) . + $(Q) $(RDOC) --op "$(HTMLOUT)" $(RDOC_GEN_OPTS) $(RDOCFLAGS) "$(srcdir)" -rdoc-coverage: PHONY main srcs-doc +rdoc-coverage: PHONY main @echo Generating RDoc coverage report $(Q) $(RDOC) --quiet -C $(RDOCFLAGS) "$(srcdir)" -undocumented: PHONY main srcs-doc - $(Q) $(RDOC) --quiet -C $(RDOCFLAGS) "$(srcdir)" | \ - sed -n \ - -e '/^ *# in file /{' -e 's///;N;s/\n/: /p' -e '}' \ - -e 's/^ *\(.*[^ ]\) *# in file \(.*\)/\2: \1/p' - RDOCBENCHOUT=/tmp/rdocbench GCBENCH_ITEM=null @@ -724,25 +634,20 @@ clear-installed-list: PHONY clean: clean-ext clean-enc clean-golf clean-docs clean-extout clean-local clean-platform clean-spec clean-local:: clean-runnable - $(Q)$(RM) $(ALLOBJS) $(LIBRUBY_A) $(LIBRUBY_SO) $(LIBRUBY) $(LIBRUBY_ALIASES) + $(Q)$(RM) $(OBJS) $(MINIOBJS) $(INITOBJS) $(MAINOBJ) $(LIBRUBY_A) $(LIBRUBY_SO) $(LIBRUBY) $(LIBRUBY_ALIASES) $(Q)$(RM) $(PROGRAM) $(WPROGRAM) miniruby$(EXEEXT) dmyext.$(OBJEXT) dmyenc.$(OBJEXT) $(ARCHFILE) .*.time $(Q)$(RM) y.tab.c y.output encdb.h transdb.h config.log rbconfig.rb $(ruby_pc) $(COROUTINE_H:/Context.h=/.time) $(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)$(RM) $(PRISM_BUILD_DIR)/.time $(PRISM_BUILD_DIR)/*/.time yjit_exit_locations.dump -$(Q)$(RMALL) yjit/target - -$(Q) $(RMDIR) enc/jis enc/trans enc $(COROUTINE_H:/Context.h=) coroutine yjit \ - $(PRISM_BUILD_DIR)/*/ $(PRISM_BUILD_DIR) tmp \ - 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) lib/clean-runnable:: PHONY - $(Q)$(CHDIR) lib 2>$(NULL) && $(RM) $(LIBRUBY_A) $(LIBRUBY) $(LIBRUBY_ALIASES) $(RUBY_BASE_NAME)/$(ruby_version) $(RUBY_BASE_NAME)/vendor_ruby 2>$(NULL) || $(NULLCMD) + $(Q)$(CHDIR) lib 2>$(NULL) && $(RM) $(LIBRUBY_A) $(LIBRUBY) $(LIBRUBY_ALIASES) $(RUBY_BASE_NAME)/$(RUBY_PROGRAM_VERSION) $(RUBY_BASE_NAME)/vendor_ruby 2>$(NULL) || $(NULLCMD) clean-runnable:: bin/clean-runnable lib/clean-runnable PHONY $(Q)$(RMDIR) lib/$(RUBY_BASE_NAME) lib bin 2>$(NULL) || $(NULLCMD) - -$(Q)$(RM) $(EXTOUT)/$(arch)/rbconfig.rb $(EXTOUT)/common/$(arch) - -$(Q)$(RMALL) exe/ clean-ext:: PHONY clean-golf: PHONY $(Q)$(RM) $(GORUBY)$(EXEEXT) $(GOLFOBJS) @@ -758,7 +663,7 @@ clean-rubyspec: clean-spec distclean: distclean-ext distclean-enc distclean-golf distclean-docs distclean-extout distclean-local distclean-platform distclean-spec distclean-local:: clean-local - $(Q)$(RM) $(MKFILES) yasmdata.rb *.inc $(PRELUDES) *.rbinc *.rbbin + $(Q)$(RM) $(MKFILES) yasmdata.rb *.inc $(PRELUDES) *.rbinc $(Q)$(RM) config.cache config.status config.status.lineno $(Q)$(RM) *~ *.bak *.stackdump core *.core gmon.out $(PREP) -$(Q)$(RMALL) $(srcdir)/autom4te.cache @@ -783,6 +688,8 @@ clean-srcs-local:: $(Q)$(RM) parse.c parse.h lex.c enc/trans/newline.c revision.h $(Q)$(RM) id.c id.h probes.dmyh probes.h $(Q)$(RM) encdb.h transdb.h verconf.h ruby-runner.h + $(Q)$(RM) mjit_config.h rb_mjit_header.h + $(Q)$(RM) $(MJIT_MIN_HEADER) $(MJIT_MIN_HEADER:.h=)$(MJIT_HEADER_SUFFIX:%=*).h realclean-srcs-local:: clean-srcs-local $(Q)$(CHDIR) $(srcdir) && $(RM) \ @@ -877,7 +784,7 @@ $(HAVE_BASERUBY:no=)$(arch)-fake.rb: miniruby$(EXEEXT) # actually depending on other headers more. $(arch:noarch=ignore)-fake.rb: $(top_srcdir)/revision.h $(top_srcdir)/version.h $(srcdir)/version.c -$(arch:noarch=ignore)-fake.rb: {$(VPATH)}id.h {$(VPATH)}vm_opts.h $(REVISION_H) +$(arch:noarch=ignore)-fake.rb: {$(VPATH)}id.h {$(VPATH)}vm_opts.h $(arch:noarch=ignore)-fake.rb: $(srcdir)/template/fake.rb.in $(tooldir)/generic_erb.rb $(ECHO) generating $@ @@ -889,7 +796,6 @@ $(arch:noarch=ignore)-fake.rb: $(srcdir)/template/fake.rb.in $(tooldir)/generic_ noarch-fake.rb: # prerequisite of yes-fake $(Q) exit > $@ -# runner: BASERUBY, target: miniruby btest: $(TEST_RUNNABLE)-btest no-btest: PHONY yes-btest: yes-fake miniruby$(EXEEXT) PHONY @@ -897,7 +803,6 @@ yes-btest: yes-fake miniruby$(EXEEXT) PHONY $(Q)$(gnumake_recursive)$(exec) $(BOOTSTRAPRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(BTESTRUBY) $(RUN_OPTS)" $(OPTS) $(TESTOPTS) $(BTESTS) $(ACTIONS_ENDGROUP) -# runner: ruby, target: ruby btest-ruby: $(TEST_RUNNABLE)-btest-ruby no-btest-ruby: PHONY yes-btest-ruby: prog PHONY @@ -905,12 +810,6 @@ yes-btest-ruby: prog PHONY $(Q)$(gnumake_recursive)$(exec) $(RUNRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(PROGRAM) -I$(srcdir)/lib $(RUN_OPTS)" $(OPTS) $(TESTOPTS) $(BTESTS) $(ACTIONS_ENDGROUP) -# runner: BASERUBY, target: ruby -btest-bruby: prog PHONY - $(ACTIONS_GROUP) - $(Q)$(gnumake_recursive)$(exec) $(BOOTSTRAPRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(PROGRAM) -I$(srcdir)/lib $(RUN_OPTS)" $(OPTS) $(TESTOPTS) $(BTESTS) - $(ACTIONS_ENDGROUP) - rtest: yes-fake miniruby$(EXEEXT) PHONY $(ACTIONS_GROUP) $(Q)$(exec) $(BOOTSTRAPRUBY) "$(srcdir)/bootstraptest/runner.rb" --ruby="$(BTESTRUBY) $(RUN_OPTS)" --sets=ractor -v @@ -949,28 +848,16 @@ test-sample: test-basic # backward compatibility for mswin-build test-short: btest-ruby $(DOT_WAIT) test-knownbug $(DOT_WAIT) test-basic test: test-short -# Separate to skip updating encs and exts by `make -o test-precheck` -# for GNU make. -test-precheck: $(ENCSTATIC:static=lib)encs exts PHONY $(DOT_WAIT) -yes-test-all-precheck: programs $(DOT_WAIT) test-precheck - -PRECHECK_TEST_ALL = yes-test-all-precheck - # $ make test-all TESTOPTS="--help" displays more detail # for example, make test-all TESTOPTS="-j2 -v -n test-name -- test-file-name" test-all: $(TEST_RUNNABLE)-test-all -yes-test-all: $(PRECHECK_TEST_ALL) +yes-test-all: programs PHONY $(ACTIONS_GROUP) - $(gnumake_recursive)$(Q)$(exec) $(RUNRUBY) -r$(tooldir)/lib/_tmpdir \ - "$(TESTSDIR)/runner.rb" --ruby="$(RUNRUBY)" \ - $(TEST_EXCLUDES) $(TESTOPTS) $(TESTS) + $(gnumake_recursive)$(Q)$(exec) $(RUNRUBY) "$(TESTSDIR)/runner.rb" --ruby="$(RUNRUBY)" $(TEST_EXCLUDES) $(TESTOPTS) $(TESTS) $(ACTIONS_ENDGROUP) TESTS_BUILD = mkmf no-test-all: PHONY - $(ACTIONS_GROUP) - $(gnumake_recursive)$(MINIRUBY) -I"$(srcdir)/lib" -r$(tooldir)/lib/_tmpdir \ - "$(TESTSDIR)/runner.rb" $(TESTOPTS) $(TESTS_BUILD) - $(ACTIONS_ENDGROUP) + $(gnumake_recursive)$(MINIRUBY) -I"$(srcdir)/lib" "$(TESTSDIR)/runner.rb" $(TESTOPTS) $(TESTS_BUILD) test-almost: test-all yes-test-almost: yes-test-all @@ -1006,14 +893,13 @@ $(RBCONFIG): $(tooldir)/mkconfig.rb config.status $(srcdir)/version.h $(srcdir)/ test-rubyspec: test-spec yes-test-rubyspec: yes-test-spec -yes-test-spec-precheck: yes-test-all-precheck yes-fake +test-spec-precheck: programs yes-fake test-spec: $(TEST_RUNNABLE)-test-spec -yes-test-spec: yes-test-spec-precheck +yes-test-spec: test-spec-precheck $(ACTIONS_GROUP) $(gnumake_recursive)$(Q) \ - $(RUNRUBY) -r./$(arch)-fake -r$(tooldir)/lib/_tmpdir \ - $(srcdir)/spec/mspec/bin/mspec run -B $(srcdir)/spec/default.mspec $(MSPECOPT) $(SPECOPTS) + $(RUNRUBY) -r./$(arch)-fake $(srcdir)/spec/mspec/bin/mspec run -B $(srcdir)/spec/default.mspec $(MSPECOPT) $(SPECOPTS) $(ACTIONS_ENDGROUP) no-test-spec: @@ -1057,19 +943,23 @@ $(ENC_MK): $(srcdir)/enc/make_encmake.rb $(srcdir)/enc/Makefile.in $(srcdir)/enc PHONY: -{$(VPATH)}parse.c: {$(VPATH)}parse.y {$(VPATH)}id.h +{$(VPATH)}parse.c: {$(VPATH)}parse.y $(tooldir)/ytab.sed {$(VPATH)}id.h {$(VPATH)}parse.h: {$(VPATH)}parse.c {$(srcdir)}.y.c: $(ECHO) generating $@ - $(Q)$(BASERUBY) $(tooldir)/id2token.rb $(SRC_FILE) | \ - $(YACC) $(YFLAGS) -o$@ -H$*.h - parse.y + $(Q)$(BASERUBY) $(tooldir)/id2token.rb $(SRC_FILE) > parse.tmp.y + $(Q)$(YACC) -d $(YFLAGS) -o y.tab.c parse.tmp.y + $(Q)$(RM) parse.tmp.y + $(Q)sed -f $(tooldir)/ytab.sed -e "/^#/s|parse\.tmp\.[iy]|$(SRC_FILE)|" -e "/^#/s!y\.tab\.c!$@!" y.tab.c > $@.new + $(Q)$(MV) $@.new $@ + $(Q)sed -e "/^#line.*y\.tab\.h/d;/^#line.*parse.*\.y/d" y.tab.h > $(@:.c=.h) + $(Q)$(RM) y.tab.c y.tab.h $(PLATFORM_D): $(Q) $(MAKEDIRS) $(PLATFORM_DIR) $(@D) @$(NULLCMD) > $@ -exe/$(PROGRAM): $(TIMESTAMPDIR)/$(arch)/.time exe/$(PROGRAM): ruby-runner.c ruby-runner.h exe/.time $(PREP) {$(VPATH)}config.h $(Q) $(CC) $(CFLAGS) $(INCFLAGS) $(CPPFLAGS) -DRUBY_INSTALL_NAME=$(@F) $(COUTFLAG)ruby-runner.$(OBJEXT) -c $(CSRCFLAG)$(srcdir)/ruby-runner.c $(Q) $(PURIFY) $(CC) $(CFLAGS) $(LDFLAGS) $(OUTFLAG)$@ ruby-runner.$(OBJEXT) $(LIBS) @@ -1082,8 +972,6 @@ exe/$(PROGRAM): ruby-runner.c ruby-runner.h exe/.time $(PREP) {$(VPATH)}config.h -e ' File.symlink(prog, dest)' \ -e 'end' \ $(@F) $(@D) $(RUBY_INSTALL_NAME)$(EXEEXT) - $(Q) $(BOOTSTRAPRUBY) -r$(srcdir)/lib/fileutils \ - -e 'FileUtils::Verbose.ln_sr(*ARGV, force: true)' rbconfig.rb $(EXTOUT)/$(arch) exe/.time: $(Q) $(MAKEDIRS) $(@D) @@ -1151,7 +1039,7 @@ parse.$(OBJEXT): {$(VPATH)}parse.c miniprelude.$(OBJEXT): {$(VPATH)}miniprelude.c # dependencies for optional sources. -compile.$(OBJEXT): {$(VPATH)}optunifs.inc +compile.$(OBJEXT): {$(VPATH)}opt_sc.inc {$(VPATH)}optunifs.inc win32/win32.$(OBJEXT): {$(VPATH)}win32/win32.c {$(VPATH)}win32/file.h \ {$(VPATH)}dln.h {$(VPATH)}dln_find.c {$(VPATH)}encindex.h \ @@ -1178,6 +1066,7 @@ INSNS2VMOPT = --srcdir="$(srcdir)" srcs_vpath = {$(VPATH)} inc_common_headers = $(tooldir)/ruby_vm/views/_copyright.erb $(tooldir)/ruby_vm/views/_notice.erb +$(srcs_vpath)opt_sc.inc: $(tooldir)/ruby_vm/views/opt_sc.inc.erb $(inc_common_headers) $(srcs_vpath)optinsn.inc: $(tooldir)/ruby_vm/views/optinsn.inc.erb $(inc_common_headers) $(srcs_vpath)optunifs.inc: $(tooldir)/ruby_vm/views/optunifs.inc.erb $(inc_common_headers) $(srcs_vpath)insns.inc: $(tooldir)/ruby_vm/views/insns.inc.erb $(inc_common_headers) @@ -1189,6 +1078,7 @@ $(srcs_vpath)insns_info.inc: $(tooldir)/ruby_vm/views/insns_info.inc.erb $(inc_c $(srcs_vpath)vmtc.inc: $(tooldir)/ruby_vm/views/vmtc.inc.erb $(inc_common_headers) $(srcs_vpath)vm.inc: $(tooldir)/ruby_vm/views/vm.inc.erb $(inc_common_headers) \ $(tooldir)/ruby_vm/views/_insn_entry.erb $(tooldir)/ruby_vm/views/_trace_instruction.erb +$(srcs_vpath)mjit_sp_inc.inc: $(tooldir)/ruby_vm/views/mjit_sp_inc.inc.erb BUILTIN_RB_SRCS = \ $(srcdir)/ast.rb \ @@ -1197,13 +1087,12 @@ BUILTIN_RB_SRCS = \ $(srcdir)/numeric.rb \ $(srcdir)/io.rb \ $(srcdir)/marshal.rb \ - $(srcdir)/rjit.rb \ - $(srcdir)/rjit_c.rb \ + $(srcdir)/mjit.rb \ + $(srcdir)/mjit_c.rb \ $(srcdir)/pack.rb \ $(srcdir)/trace_point.rb \ $(srcdir)/warning.rb \ $(srcdir)/array.rb \ - $(srcdir)/hash.rb \ $(srcdir)/kernel.rb \ $(srcdir)/ractor.rb \ $(srcdir)/symbol.rb \ @@ -1222,16 +1111,9 @@ common-srcs: $(srcs_vpath)parse.c $(srcs_vpath)lex.c $(srcs_vpath)enc/trans/newl missing-srcs: $(srcdir)/missing/des_tables.c -srcs: common-srcs missing-srcs srcs-enc srcs-doc +srcs: common-srcs missing-srcs srcs-enc -RIPPER_SRCS = $(srcdir)/ext/ripper/ripper.c \ - $(srcdir)/ext/ripper/ripper_init.c \ - $(srcdir)/ext/ripper/eventids1.h \ - $(srcdir)/ext/ripper/eventids1.c \ - $(srcdir)/ext/ripper/eventids2table.c \ - # RIPPER_SRCS - -EXT_SRCS = ripper_srcs \ +EXT_SRCS = $(srcdir)/ext/ripper/ripper.c \ $(srcdir)/ext/rbconfig/sizeof/sizes.c \ $(srcdir)/ext/rbconfig/sizeof/limits.c \ $(srcdir)/ext/socket/constdefs.c \ @@ -1277,9 +1159,9 @@ id.c: $(tooldir)/generic_erb.rb $(srcdir)/template/id.c.tmpl $(srcdir)/defs/id.d $(Q) $(BASERUBY) $(tooldir)/generic_erb.rb --output=$@ \ $(srcdir)/template/id.c.tmpl -node_name.inc: $(tooldir)/node_name.rb $(srcdir)/rubyparser.h +node_name.inc: $(tooldir)/node_name.rb $(srcdir)/node.h $(ECHO) generating $@ - $(Q) $(BASERUBY) -n $(tooldir)/node_name.rb < $(srcdir)/rubyparser.h > $@ + $(Q) $(BASERUBY) -n $(tooldir)/node_name.rb < $(srcdir)/node.h > $@ encdb.h: $(RBCONFIG) $(tooldir)/generic_erb.rb $(srcdir)/template/encdb.h.tmpl $(ECHO) generating $@ @@ -1304,7 +1186,10 @@ $(MINIPRELUDE_C): $(COMPILE_PRELUDE) $(BUILTIN_RB_SRCS) $(Q) $(BASERUBY) $(tooldir)/generic_erb.rb -I$(srcdir) -o $@ \ $(srcdir)/template/prelude.c.tmpl $(BUILTIN_RB_SRCS) -golf_prelude.rbbin: {$(srcdir)}golf_prelude.rb $(tooldir)/mk_rbbin.rb $(PREP) +$(GOLF_PRELUDE_C): $(COMPILE_PRELUDE) {$(srcdir)}golf_prelude.rb + $(ECHO) generating $@ + $(Q) $(BASERUBY) $(tooldir)/generic_erb.rb -I$(srcdir) -c -o $@ \ + $(srcdir)/template/prelude.c.tmpl golf_prelude.rb MAINCPPFLAGS = $(ENABLE_DEBUG_ENV:yes=-DRUBY_DEBUG_ENV=1) @@ -1322,22 +1207,15 @@ probes.h: {$(VPATH)}probes.$(DTRACE_EXT) prereq: incs srcs preludes PHONY preludes: {$(VPATH)}miniprelude.c - -{$(srcdir)}.rb.rbbin: - $(ECHO) making $@ - $(Q) $(MINIRUBY) $(tooldir)/mk_rbbin.rb $< > $@ +preludes: {$(srcdir)}golf_prelude.c {$(srcdir)}.rb.rbinc: $(ECHO) making $@ $(Q) $(BASERUBY) $(tooldir)/mk_builtin_loader.rb $< -$(BUILTIN_BINARY:yes=built)in_binary.inc: $(PREP) $(BUILTIN_RB_SRCS) $(srcdir)/template/builtin_binary.inc.tmpl +builtin_binary.inc: $(PREP) $(BUILTIN_RB_SRCS) $(srcdir)/template/builtin_binary.inc.tmpl $(Q) $(MINIRUBY) $(tooldir)/generic_erb.rb -o $@ \ - $(srcdir)/template/builtin_binary.inc.tmpl - -$(Q) sha256sum $@ 2> $(NULL) || $(NULLCMD) - -$(BUILTIN_BINARY:no=builtin)_binary.inc: - $(Q) echo> $@ // empty $(@F) + $(srcdir)/template/builtin_binary.inc.tmpl -- --cross=$(CROSS_COMPILING) $(BUILTIN_RB_INCS): $(top_srcdir)/tool/mk_builtin_loader.rb @@ -1348,20 +1226,13 @@ $(REVISION_H)$(no_baseruby:no=~disabled~): $(REVISION_H)$(yes_baseruby:yes=~disabled~): $(Q) exit > $@ -# uncommon.mk: $(REVISION_H) -# $(MKFILES): $(REVISION_H) - -ripper_srcs: $(RIPPER_SRCS) - -$(RIPPER_SRCS): $(srcdir)/parse.y $(srcdir)/defs/id.def -$(RIPPER_SRCS): $(srcdir)/ext/ripper/tools/preproc.rb $(srcdir)/ext/ripper/tools/dsl.rb -$(RIPPER_SRCS): $(srcdir)/ext/ripper/ripper_init.c.tmpl $(srcdir)/ext/ripper/eventids2.c +$(srcdir)/ext/ripper/ripper.c: $(srcdir)/ext/ripper/tools/preproc.rb $(srcdir)/parse.y $(srcdir)/defs/id.def $(srcdir)/ext/ripper/depend $(ECHO) generating $@ $(Q) $(CHDIR) $(@D) && \ $(CAT_DEPEND) depend | \ $(exec) $(MAKE) -f - $(mflags) \ - Q=$(Q) ECHO=$(ECHO) RM="$(RM1)" top_srcdir=../.. srcdir=. VPATH=../.. \ - RUBY="$(BASERUBY)" BASERUBY="$(BASERUBY)" PATH_SEPARATOR="$(PATH_SEPARATOR)" LANG=C + Q=$(Q) ECHO=$(ECHO) RM="$(RM1)" BISON="$(YACC)" top_srcdir=../.. srcdir=. VPATH=../.. \ + RUBY="$(BASERUBY)" PATH_SEPARATOR="$(PATH_SEPARATOR)" LANG=C $(srcdir)/ext/json/parser/parser.c: $(srcdir)/ext/json/parser/parser.rl $(srcdir)/ext/json/parser/prereq.mk $(ECHO) generating $@ @@ -1389,7 +1260,7 @@ $(srcdir)/ext/rbconfig/sizeof/limits.c: $(srcdir)/ext/rbconfig/sizeof/depend \ $(exec) $(MAKE) -f - $(mflags) \ Q=$(Q) ECHO=$(ECHO) top_srcdir=../../.. srcdir=. VPATH=../../.. RUBY="$(BASERUBY)" $(@F) -$(srcdir)/ext/socket/constdefs.c: $(srcdir)/ext/socket/depend $(srcdir)/ext/socket/mkconstants.rb +$(srcdir)/ext/socket/constdefs.c: $(srcdir)/ext/socket/depend $(Q) $(CHDIR) $(@D) && \ $(CAT_DEPEND) depend | \ $(exec) $(MAKE) -f - $(mflags) \ @@ -1451,10 +1322,9 @@ run.gdb: echo ' quit' >> run.gdb echo end >> run.gdb -GDB = gdb gdb: miniruby$(EXEEXT) run.gdb PHONY - $(GDB) -x run.gdb --quiet --args $(MINIRUBY) $(RUNOPT0) $(TESTRUN_SCRIPT) $(RUNOPT) + gdb -x run.gdb --quiet --args $(MINIRUBY) $(RUNOPT0) $(TESTRUN_SCRIPT) $(RUNOPT) gdb-ruby: $(PROGRAM) run.gdb PHONY $(Q) $(RUNRUBY_COMMAND) $(RUNRUBY_DEBUGGER) -- $(RUNOPT0) $(TESTRUN_SCRIPT) $(RUNOPT) @@ -1477,7 +1347,7 @@ dist: up:: update-remote -up$(DOT_WAIT):: +up:: -$(Q)$(MAKE) $(mflags) Q=$(Q) REVISION_FORCE=PHONY ALWAYS_UPDATE_UNICODE= after-update yes:: @@ -1504,10 +1374,6 @@ update-config_files: PHONY $(Q) $(BASERUBY) -C "$(srcdir)" tool/downloader.rb -d tool --cache-dir=$(CACHE_DIR) -e gnu \ config.guess config.sub -update-coverage: main PHONY - $(XRUBY) -C "$(srcdir)" bin/gem install --no-document \ - --install-dir .bundle --conservative "simplecov" - refresh-gems: update-bundled_gems prepare-gems prepare-gems: $(HAVE_BASERUBY:yes=update-gems) $(HAVE_BASERUBY:yes=extract-gems) extract-gems: $(HAVE_BASERUBY:yes=update-gems) @@ -1534,32 +1400,16 @@ extract-gems$(gnumake:yes=-sequential): PHONY -e 'gem, ver, _, rev = *$$F' \ -e 'next if !ver or /^#/=~gem' \ -e 'g = "#{gem}-#{ver}"' \ - -e 'unless File.directory?("#{d}/#{g}")' \ - -e 'if rev and File.exist?(gs = "gems/src/#{gem}/#{gem}.gemspec")' \ - -e 'BundledGem.build(gs, ver, "gems")' \ - -e 'end' \ + -e 'if File.directory?("#{d}/#{g}")' \ + -e 'elsif rev and File.exist?(gs = "gems/src/#{gem}/#{gem}.gemspec")' \ + -e 'BundledGem.copy(gs, ".bundle")' \ + -e 'else' \ -e 'BundledGem.unpack("gems/#{g}.gem", ".bundle")' \ -e 'end' \ gems/bundled_gems -extract-gems$(gnumake:yes=-sequential): $(HAVE_GIT:yes=clone-bundled-gems-src) - -clone-bundled-gems-src: PHONY - $(Q) $(BASERUBY) -C "$(srcdir)" \ - -Itool/lib -rbundled_gem -answ \ - -e 'BEGIN {git = $$git}' \ - -e 'gem, _, repo, rev = *$$F' \ - -e 'next if !rev or /^#/=~gem' \ - -e 'gemdir = "gems/src/#{gem}"' \ - -e 'BundledGem.checkout(gemdir, repo, rev, git: git)' \ - -e 'BundledGem.dummy_gemspec("#{gemdir}/#{gem}.gemspec")' \ - -- -git="$(GIT)" \ - gems/bundled_gems - outdate-bundled-gems: PHONY - $(Q) $(BASERUBY) $(tooldir)/$@.rb --make="$(MAKE)" --mflags="$(MFLAGS)" \ - --ruby-platform=$(arch) --ruby-version=$(ruby_version) \ - "$(srcdir)" + $(Q) $(BASERUBY) $(tooldir)/$@.rb --make="$(MAKE)" --mflags="$(MFLAGS)" "$(srcdir)" update-bundled_gems: PHONY $(Q) $(RUNRUBY) -rrubygems \ @@ -1587,11 +1437,11 @@ 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 "hoe" "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 -test-bundled-gems: $(TEST_RUNNABLE)-test-bundled-gems $(DOT_WAIT) $(TEST_RUNNABLE)-test-bundled-gems-spec +test-bundled-gems: $(TEST_RUNNABLE)-test-bundled-gems yes-test-bundled-gems: test-bundled-gems-run no-test-bundled-gems: @@ -1599,31 +1449,36 @@ no-test-bundled-gems: # TEST_BUNDLED_GEMS_ALLOW_FAILURES = BUNDLED_GEMS = -test-bundled-gems-run: $(TEST_RUNNABLE)-test-bundled-gems-run -yes-test-bundled-gems-run: $(PREPARE_BUNDLED_GEMS) +test-bundled-gems-run: $(PREPARE_BUNDLED_GEMS) $(gnumake_recursive)$(Q) $(XRUBY) $(tooldir)/test-bundled-gems.rb $(BUNDLED_GEMS) -no-test-bundled-gems-run: $(PREPARE_BUNDLED_GEMS) -test-bundled-gems-spec: $(TEST_RUNNABLE)-test-bundled-gems-spec -yes-test-bundled-gems-spec: yes-test-spec-precheck $(PREPARE_BUNDLED_GEMS) +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) - $(gnumake_recursive)$(Q) \ - $(RUNRUBY) -r./$(arch)-fake -r$(tooldir)/lib/_tmpdir \ - $(srcdir)/spec/mspec/bin/mspec run -B $(srcdir)/spec/bundled_gems.mspec $(MSPECOPT) $(SPECOPTS) + $(XRUBY) -C "$(srcdir)" bin/gem install --no-document \ + --install-dir .bundle --conservative "bundler" "rake" "rspec:~> 3" #"ruby-prof" $(ACTIONS_ENDGROUP) -no-test-bundled-gems-spec: - -test-syntax-suggest: +RSPECOPTS = +SYNTAX_SUGGEST_SPECS = +PREPARE_SYNTAX_SUGGEST = test-syntax-suggest-prepare +test-syntax-suggest: $(TEST_RUNNABLE)-test-syntax-suggest +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) $(PREPARE_SYNTAX_SUGGEST) 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 -yes-test-bundler-parallel-precheck: yes-test-bundler-precheck -test-bundler-prepare: $(TEST_RUNNABLE)-test-bundler-prepare no-test-bundler-prepare: no-test-bundler-precheck yes-test-bundler-prepare: yes-test-bundler-precheck $(ACTIONS_GROUP) @@ -1632,24 +1487,23 @@ yes-test-bundler-prepare: yes-test-bundler-precheck -e 'ENV["BUNDLE_APP_CONFIG"] = File.expand_path(".bundle")' \ -e 'ENV["BUNDLE_PATH__SYSTEM"] = "true"' \ -e 'ENV["BUNDLE_WITHOUT"] = "lint doc"' \ - -e 'load "spec/bundler/support/bundle.rb"' -- install --quiet --gemfile=tool/bundler/dev_gems.rb + -e 'load "spec/bundler/support/bundle.rb"' -- install --gemfile=tool/bundler/dev_gems.rb $(ACTIONS_ENDGROUP) RSPECOPTS = BUNDLER_SPECS = -PREPARE_BUNDLER = $(TEST_RUNNABLE)-test-bundler-prepare test-bundler: $(TEST_RUNNABLE)-test-bundler -yes-test-bundler: $(PREPARE_BUNDLER) +yes-test-bundler: yes-test-bundler-prepare $(gnumake_recursive)$(XRUBY) \ -r./$(arch)-fake \ -e "exec(*ARGV)" -- \ - $(XRUBY) -C $(srcdir) -Ispec/bundler:spec/lib .bundle/bin/rspec \ - --require spec_helper --require formatter_overrides $(RSPECOPTS) spec/bundler/$(BUNDLER_SPECS) + $(XRUBY) -C $(srcdir) -Ispec/bundler .bundle/bin/rspec \ + --require spec_helper $(RSPECOPTS) spec/bundler/$(BUNDLER_SPECS) no-test-bundler: PARALLELRSPECOPTS = --runtime-log $(srcdir)/tmp/parallel_runtime_rspec.log test-bundler-parallel: $(TEST_RUNNABLE)-test-bundler-parallel -yes-test-bundler-parallel: $(PREPARE_BUNDLER) +yes-test-bundler-parallel: yes-test-bundler-prepare $(gnumake_recursive)$(XRUBY) \ -r./$(arch)-fake \ -e "ARGV[-1] = File.expand_path(ARGV[-1])" \ @@ -1657,17 +1511,17 @@ yes-test-bundler-parallel: $(PREPARE_BUNDLER) $(XRUBY) -I$(srcdir)/spec/bundler \ -e "ENV['PARALLEL_TESTS_EXECUTABLE'] = ARGV.shift" \ -e "load ARGV.shift" \ - "$(XRUBY) -C $(srcdir) -Ispec/bundler:spec/lib .bundle/bin/rspec" \ + "$(XRUBY) -C $(srcdir) -Ispec/bundler .bundle/bin/rspec" \ $(srcdir)/.bundle/bin/parallel_rspec \ - -o "--require spec_helper --require formatter_overrides" \ + -o "--require spec_helper" \ $(PARALLELRSPECOPTS) $(srcdir)/spec/bundler/$(BUNDLER_SPECS) no-test-bundler-parallel: # The annocheck supports ELF format binaries compiled for any OS and for any # architecture. It is designed to be independent of the host OS and the # architecture. The test-annocheck.sh requires docker or podman. -test-annocheck: $(PROGRAM) $(LIBRUBY_SO) - $(tooldir)/test-annocheck.sh $(PROGRAM) $(LIBRUBY_SO) +test-annocheck: $(PROGRAM) + $(tooldir)/test-annocheck.sh $(PROGRAM) GEM = up sync-default-gems: @@ -1809,16 +1663,6 @@ $(UNICODE_HDR_DIR)/name2ctype.h: $(UNICODE_SRC_DATA_DIR) $(UNICODE_SRC_EMOJI_DATA_DIR) > $@.new $(MV) $@.new $@ -srcs-doc: $(srcdir)/doc/regexp/unicode_properties.rdoc -$(srcdir)/doc/regexp/$(ALWAYS_UPDATE_UNICODE:yes=unicode_properties.rdoc): \ - $(UNICODE_HDR_DIR)/name2ctype.h $(UNICODE_PROPERTY_FILES) - -$(srcdir)/doc/regexp/unicode_properties.rdoc: - $(Q) $(BOOTSTRAPRUBY) $(tooldir)/generic_erb.rb -c -o $@ \ - $(srcdir)/template/unicode_properties.rdoc.tmpl \ - $(UNICODE_SRC_DATA_DIR) $(UNICODE_HDR_DIR)/name2ctype.h || \ - $(TOUCH) $@ - # the next non-comment line was: # $(UNICODE_HDR_DIR)/casefold.h: $(tooldir)/enc-case-folding.rb \ # but was changed to make sure CI works on systems that don't have gperf @@ -1861,8 +1705,6 @@ info-arch: PHONY @echo arch=$(arch) exam: check -exam: $(DOT_WAIT) test-bundler-parallel -exam: $(DOT_WAIT) test-bundled-gems love: sudo-precheck up all test exam install @echo love is all you need @@ -1884,39 +1726,11 @@ update-man-date: PHONY ChangeLog: $(ECHO) Generating $@ -$(Q) $(BASERUBY) -I"$(tooldir)/lib" -rvcs \ - -e 'VCS.detect(ARGV[0]).export_changelog(path: ARGV[1])' \ + -e 'VCS.detect(ARGV[0]).export_changelog("@", nil, nil, ARGV[1])' \ "$(srcdir)" $@ -# CAUTION: If using GNU make 3 which does not support `.WAIT`, this -# recipe with multiple jobs makes build and `git reset` run -# simultaneously, and will cause inconsistent results. Run with `-j1` -# or update GNU make. -nightly: yesterday $(DOT_WAIT) install - $(NULLCMD) - -# Rewind to the last commit "yesterday". "Yesterday" means here the -# period where `RUBY_RELEASE_DATE` is the day before the date to be -# generated now. In short, the yesterday in JST-9 time zone. -yesterday: rewindable - -rewindable: - $(GIT) -C $(srcdir) status --porcelain - $(GIT) -C $(srcdir) diff --quiet - HELP_EXTRA_TASKS = "" -shared-gc: probes.h - $(Q) if test -z $(shared_gc_dir); then \ - echo "You must configure with --with-shared-gc to use shared GC"; \ - exit 1; \ - elif test -z $(SHARED_GC); then \ - echo "You must specify SHARED_GC with the GC to build"; \ - exit 1; \ - fi - $(ECHO) generating $(shared_gc_dir)librubygc.$(SHARED_GC).$(SOEXT) - $(Q) $(MAKEDIRS) $(shared_gc_dir) - $(Q) $(LDSHARED) -I$(srcdir)/include -I$(srcdir) -I$(arch_hdrdir) $(XDLDFLAGS) $(cflags) -DBUILDING_SHARED_GC -fPIC -o $(shared_gc_dir)librubygc.$(SHARED_GC).$(SOEXT) $(srcdir)/gc/$(SHARED_GC).c - help: PHONY $(MESSAGE_BEGIN) \ " Makefile of Ruby" \ @@ -1933,16 +1747,13 @@ help: PHONY " runruby: runs test.rb by ruby you just built" \ " gdb: runs test.rb by miniruby under gdb" \ " gdb-ruby: runs test.rb by ruby under gdb" \ - " runirb: starts irb on built ruby (not installed ruby)" \ - " exam: equals make check test-bundler-parallel test-bundled-gems" \ - " check: equals make test test-tool test-all test-spec test-syntax-suggest" \ + " check: equals make test test-tool test-all test-spec" \ " test: ruby core tests [BTESTS=<bootstraptest files>]" \ " test-all: all ruby tests [TESTOPTS=-j4 TESTS=<test files>]" \ " test-spec: run the Ruby spec suite [SPECOPTS=<specs, opts>]" \ " test-bundler: run the Bundler spec" \ " test-bundler-parallel: run the Bundler spec with parallel" \ - " test-syntax-suggest: run the SyntaxSuggest spec" \ - " test-bundled-gems: run the test suite of bundled gems [BUNDLED_GEMS=<gems>]" \ + " test-bundled-gems: run the test suite of bundled gems" \ " test-tool: tests under the tool/test" \ " update-gems: download files of the bundled gems" \ " update-bundled_gems: update the latest version of bundled gems" \ @@ -1953,12 +1764,12 @@ help: PHONY " install: install all ruby distributions" \ " install-nodoc: install without rdoc" \ " install-cross: install cross compiling stuff" \ - " clean: clean up to the state before build" \ - " distclean: clean up to the state before configure" \ + " clean: clean for tarball" \ + " distclean: clean for repository" \ " golf: build goruby for golfers" \ $(HELP_EXTRA_TASKS) \ "see DeveloperHowto for more detail: " \ - " https://github.com/ruby/ruby/wiki/Developer-How-To" \ + " https://bugs.ruby-lang.org/projects/ruby/wiki/DeveloperHowto" \ $(MESSAGE_END) $(CROSS_COMPILING:yes=)builtin.$(OBJEXT): {$(VPATH)}mini_builtin.c @@ -1990,7 +1801,6 @@ addr2line.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h addr2line.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h addr2line.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h addr2line.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -addr2line.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h addr2line.$(OBJEXT): {$(VPATH)}internal/attr/pure.h addr2line.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h addr2line.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -2020,10 +1830,6 @@ addr2line.$(OBJEXT): {$(VPATH)}internal/stdbool.h addr2line.$(OBJEXT): {$(VPATH)}internal/warning_push.h addr2line.$(OBJEXT): {$(VPATH)}internal/xmalloc.h addr2line.$(OBJEXT): {$(VPATH)}missing.h -array.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -array.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -array.$(OBJEXT): $(CCAN_DIR)/list/list.h -array.$(OBJEXT): $(CCAN_DIR)/str/str.h array.$(OBJEXT): $(hdrdir)/ruby/ruby.h array.$(OBJEXT): $(top_srcdir)/internal/array.h array.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h @@ -2036,12 +1842,10 @@ array.$(OBJEXT): $(top_srcdir)/internal/enum.h array.$(OBJEXT): $(top_srcdir)/internal/fixnum.h array.$(OBJEXT): $(top_srcdir)/internal/gc.h array.$(OBJEXT): $(top_srcdir)/internal/hash.h -array.$(OBJEXT): $(top_srcdir)/internal/imemo.h array.$(OBJEXT): $(top_srcdir)/internal/numeric.h array.$(OBJEXT): $(top_srcdir)/internal/object.h array.$(OBJEXT): $(top_srcdir)/internal/proc.h array.$(OBJEXT): $(top_srcdir)/internal/rational.h -array.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h array.$(OBJEXT): $(top_srcdir)/internal/serial.h array.$(OBJEXT): $(top_srcdir)/internal/static_assert.h array.$(OBJEXT): $(top_srcdir)/internal/variable.h @@ -2050,7 +1854,6 @@ array.$(OBJEXT): $(top_srcdir)/internal/warnings.h array.$(OBJEXT): {$(VPATH)}array.c array.$(OBJEXT): {$(VPATH)}array.rbinc array.$(OBJEXT): {$(VPATH)}assert.h -array.$(OBJEXT): {$(VPATH)}atomic.h array.$(OBJEXT): {$(VPATH)}backward/2/assume.h array.$(OBJEXT): {$(VPATH)}backward/2/attributes.h array.$(OBJEXT): {$(VPATH)}backward/2/bool.h @@ -2108,7 +1911,6 @@ array.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h array.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h array.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h array.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -array.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h array.$(OBJEXT): {$(VPATH)}internal/attr/pure.h array.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h array.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -2177,6 +1979,7 @@ array.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h array.$(OBJEXT): {$(VPATH)}internal/intern/error.h array.$(OBJEXT): {$(VPATH)}internal/intern/eval.h array.$(OBJEXT): {$(VPATH)}internal/intern/file.h +array.$(OBJEXT): {$(VPATH)}internal/intern/gc.h array.$(OBJEXT): {$(VPATH)}internal/intern/hash.h array.$(OBJEXT): {$(VPATH)}internal/intern/io.h array.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -2207,36 +2010,29 @@ array.$(OBJEXT): {$(VPATH)}internal/memory.h array.$(OBJEXT): {$(VPATH)}internal/method.h array.$(OBJEXT): {$(VPATH)}internal/module.h array.$(OBJEXT): {$(VPATH)}internal/newobj.h +array.$(OBJEXT): {$(VPATH)}internal/rgengc.h array.$(OBJEXT): {$(VPATH)}internal/scan_args.h array.$(OBJEXT): {$(VPATH)}internal/special_consts.h array.$(OBJEXT): {$(VPATH)}internal/static_assert.h array.$(OBJEXT): {$(VPATH)}internal/stdalign.h array.$(OBJEXT): {$(VPATH)}internal/stdbool.h -array.$(OBJEXT): {$(VPATH)}internal/stdckdint.h array.$(OBJEXT): {$(VPATH)}internal/symbol.h array.$(OBJEXT): {$(VPATH)}internal/value.h array.$(OBJEXT): {$(VPATH)}internal/value_type.h array.$(OBJEXT): {$(VPATH)}internal/variable.h array.$(OBJEXT): {$(VPATH)}internal/warning_push.h array.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -array.$(OBJEXT): {$(VPATH)}method.h array.$(OBJEXT): {$(VPATH)}missing.h -array.$(OBJEXT): {$(VPATH)}node.h array.$(OBJEXT): {$(VPATH)}onigmo.h array.$(OBJEXT): {$(VPATH)}oniguruma.h array.$(OBJEXT): {$(VPATH)}probes.dmyh array.$(OBJEXT): {$(VPATH)}probes.h array.$(OBJEXT): {$(VPATH)}ruby_assert.h -array.$(OBJEXT): {$(VPATH)}ruby_atomic.h -array.$(OBJEXT): {$(VPATH)}rubyparser.h array.$(OBJEXT): {$(VPATH)}shape.h array.$(OBJEXT): {$(VPATH)}st.h array.$(OBJEXT): {$(VPATH)}subst.h -array.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -array.$(OBJEXT): {$(VPATH)}thread_native.h +array.$(OBJEXT): {$(VPATH)}transient_heap.h array.$(OBJEXT): {$(VPATH)}util.h -array.$(OBJEXT): {$(VPATH)}vm_core.h -array.$(OBJEXT): {$(VPATH)}vm_opts.h ast.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h ast.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h ast.$(OBJEXT): $(CCAN_DIR)/list/list.h @@ -2245,44 +2041,16 @@ ast.$(OBJEXT): $(hdrdir)/ruby.h ast.$(OBJEXT): $(hdrdir)/ruby/ruby.h ast.$(OBJEXT): $(top_srcdir)/internal/array.h ast.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h -ast.$(OBJEXT): $(top_srcdir)/internal/bignum.h -ast.$(OBJEXT): $(top_srcdir)/internal/bits.h ast.$(OBJEXT): $(top_srcdir)/internal/compilers.h -ast.$(OBJEXT): $(top_srcdir)/internal/complex.h -ast.$(OBJEXT): $(top_srcdir)/internal/fixnum.h ast.$(OBJEXT): $(top_srcdir)/internal/gc.h ast.$(OBJEXT): $(top_srcdir)/internal/imemo.h -ast.$(OBJEXT): $(top_srcdir)/internal/numeric.h ast.$(OBJEXT): $(top_srcdir)/internal/parse.h -ast.$(OBJEXT): $(top_srcdir)/internal/rational.h -ast.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h -ast.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h ast.$(OBJEXT): $(top_srcdir)/internal/serial.h ast.$(OBJEXT): $(top_srcdir)/internal/static_assert.h ast.$(OBJEXT): $(top_srcdir)/internal/symbol.h ast.$(OBJEXT): $(top_srcdir)/internal/variable.h ast.$(OBJEXT): $(top_srcdir)/internal/vm.h ast.$(OBJEXT): $(top_srcdir)/internal/warnings.h -ast.$(OBJEXT): $(top_srcdir)/prism/defines.h -ast.$(OBJEXT): $(top_srcdir)/prism/encoding.h -ast.$(OBJEXT): $(top_srcdir)/prism/node.h -ast.$(OBJEXT): $(top_srcdir)/prism/options.h -ast.$(OBJEXT): $(top_srcdir)/prism/pack.h -ast.$(OBJEXT): $(top_srcdir)/prism/parser.h -ast.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -ast.$(OBJEXT): $(top_srcdir)/prism/prism.h -ast.$(OBJEXT): $(top_srcdir)/prism/regexp.h -ast.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -ast.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h ast.$(OBJEXT): {$(VPATH)}assert.h ast.$(OBJEXT): {$(VPATH)}ast.c ast.$(OBJEXT): {$(VPATH)}ast.rbinc @@ -2343,7 +2111,6 @@ ast.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h ast.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h ast.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h ast.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -ast.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h ast.$(OBJEXT): {$(VPATH)}internal/attr/pure.h ast.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h ast.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -2412,6 +2179,7 @@ ast.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h ast.$(OBJEXT): {$(VPATH)}internal/intern/error.h ast.$(OBJEXT): {$(VPATH)}internal/intern/eval.h ast.$(OBJEXT): {$(VPATH)}internal/intern/file.h +ast.$(OBJEXT): {$(VPATH)}internal/intern/gc.h ast.$(OBJEXT): {$(VPATH)}internal/intern/hash.h ast.$(OBJEXT): {$(VPATH)}internal/intern/io.h ast.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -2442,12 +2210,12 @@ ast.$(OBJEXT): {$(VPATH)}internal/memory.h ast.$(OBJEXT): {$(VPATH)}internal/method.h ast.$(OBJEXT): {$(VPATH)}internal/module.h ast.$(OBJEXT): {$(VPATH)}internal/newobj.h +ast.$(OBJEXT): {$(VPATH)}internal/rgengc.h ast.$(OBJEXT): {$(VPATH)}internal/scan_args.h ast.$(OBJEXT): {$(VPATH)}internal/special_consts.h ast.$(OBJEXT): {$(VPATH)}internal/static_assert.h ast.$(OBJEXT): {$(VPATH)}internal/stdalign.h ast.$(OBJEXT): {$(VPATH)}internal/stdbool.h -ast.$(OBJEXT): {$(VPATH)}internal/stdckdint.h ast.$(OBJEXT): {$(VPATH)}internal/symbol.h ast.$(OBJEXT): {$(VPATH)}internal/value.h ast.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -2460,13 +2228,8 @@ ast.$(OBJEXT): {$(VPATH)}missing.h ast.$(OBJEXT): {$(VPATH)}node.h ast.$(OBJEXT): {$(VPATH)}onigmo.h ast.$(OBJEXT): {$(VPATH)}oniguruma.h -ast.$(OBJEXT): {$(VPATH)}prism/ast.h -ast.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -ast.$(OBJEXT): {$(VPATH)}prism/version.h -ast.$(OBJEXT): {$(VPATH)}prism_compile.h ast.$(OBJEXT): {$(VPATH)}ruby_assert.h ast.$(OBJEXT): {$(VPATH)}ruby_atomic.h -ast.$(OBJEXT): {$(VPATH)}rubyparser.h ast.$(OBJEXT): {$(VPATH)}shape.h ast.$(OBJEXT): {$(VPATH)}st.h ast.$(OBJEXT): {$(VPATH)}subst.h @@ -2475,13 +2238,7 @@ ast.$(OBJEXT): {$(VPATH)}thread_native.h ast.$(OBJEXT): {$(VPATH)}util.h ast.$(OBJEXT): {$(VPATH)}vm_core.h ast.$(OBJEXT): {$(VPATH)}vm_opts.h -bignum.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -bignum.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -bignum.$(OBJEXT): $(CCAN_DIR)/list/list.h -bignum.$(OBJEXT): $(CCAN_DIR)/str/str.h bignum.$(OBJEXT): $(hdrdir)/ruby/ruby.h -bignum.$(OBJEXT): $(top_srcdir)/internal/array.h -bignum.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h bignum.$(OBJEXT): $(top_srcdir)/internal/bignum.h bignum.$(OBJEXT): $(top_srcdir)/internal/bits.h bignum.$(OBJEXT): $(top_srcdir)/internal/class.h @@ -2489,7 +2246,6 @@ bignum.$(OBJEXT): $(top_srcdir)/internal/compilers.h bignum.$(OBJEXT): $(top_srcdir)/internal/complex.h bignum.$(OBJEXT): $(top_srcdir)/internal/fixnum.h bignum.$(OBJEXT): $(top_srcdir)/internal/gc.h -bignum.$(OBJEXT): $(top_srcdir)/internal/imemo.h bignum.$(OBJEXT): $(top_srcdir)/internal/numeric.h bignum.$(OBJEXT): $(top_srcdir)/internal/object.h bignum.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h @@ -2499,7 +2255,6 @@ bignum.$(OBJEXT): $(top_srcdir)/internal/variable.h bignum.$(OBJEXT): $(top_srcdir)/internal/vm.h bignum.$(OBJEXT): $(top_srcdir)/internal/warnings.h bignum.$(OBJEXT): {$(VPATH)}assert.h -bignum.$(OBJEXT): {$(VPATH)}atomic.h bignum.$(OBJEXT): {$(VPATH)}backward/2/assume.h bignum.$(OBJEXT): {$(VPATH)}backward/2/attributes.h bignum.$(OBJEXT): {$(VPATH)}backward/2/bool.h @@ -2513,7 +2268,6 @@ bignum.$(OBJEXT): {$(VPATH)}bignum.c bignum.$(OBJEXT): {$(VPATH)}config.h bignum.$(OBJEXT): {$(VPATH)}constant.h bignum.$(OBJEXT): {$(VPATH)}defines.h -bignum.$(OBJEXT): {$(VPATH)}encoding.h bignum.$(OBJEXT): {$(VPATH)}id.h bignum.$(OBJEXT): {$(VPATH)}id_table.h bignum.$(OBJEXT): {$(VPATH)}intern.h @@ -2556,7 +2310,6 @@ bignum.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h bignum.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h bignum.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h bignum.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -bignum.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h bignum.$(OBJEXT): {$(VPATH)}internal/attr/pure.h bignum.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h bignum.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -2589,15 +2342,6 @@ bignum.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h bignum.$(OBJEXT): {$(VPATH)}internal/ctype.h bignum.$(OBJEXT): {$(VPATH)}internal/dllexport.h bignum.$(OBJEXT): {$(VPATH)}internal/dosish.h -bignum.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -bignum.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -bignum.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -bignum.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -bignum.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -bignum.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -bignum.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -bignum.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -bignum.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h bignum.$(OBJEXT): {$(VPATH)}internal/error.h bignum.$(OBJEXT): {$(VPATH)}internal/eval.h bignum.$(OBJEXT): {$(VPATH)}internal/event.h @@ -2625,6 +2369,7 @@ bignum.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h bignum.$(OBJEXT): {$(VPATH)}internal/intern/error.h bignum.$(OBJEXT): {$(VPATH)}internal/intern/eval.h bignum.$(OBJEXT): {$(VPATH)}internal/intern/file.h +bignum.$(OBJEXT): {$(VPATH)}internal/intern/gc.h bignum.$(OBJEXT): {$(VPATH)}internal/intern/hash.h bignum.$(OBJEXT): {$(VPATH)}internal/intern/io.h bignum.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -2655,35 +2400,25 @@ bignum.$(OBJEXT): {$(VPATH)}internal/memory.h bignum.$(OBJEXT): {$(VPATH)}internal/method.h bignum.$(OBJEXT): {$(VPATH)}internal/module.h bignum.$(OBJEXT): {$(VPATH)}internal/newobj.h +bignum.$(OBJEXT): {$(VPATH)}internal/rgengc.h bignum.$(OBJEXT): {$(VPATH)}internal/scan_args.h bignum.$(OBJEXT): {$(VPATH)}internal/special_consts.h bignum.$(OBJEXT): {$(VPATH)}internal/static_assert.h bignum.$(OBJEXT): {$(VPATH)}internal/stdalign.h bignum.$(OBJEXT): {$(VPATH)}internal/stdbool.h -bignum.$(OBJEXT): {$(VPATH)}internal/stdckdint.h bignum.$(OBJEXT): {$(VPATH)}internal/symbol.h bignum.$(OBJEXT): {$(VPATH)}internal/value.h bignum.$(OBJEXT): {$(VPATH)}internal/value_type.h bignum.$(OBJEXT): {$(VPATH)}internal/variable.h bignum.$(OBJEXT): {$(VPATH)}internal/warning_push.h bignum.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -bignum.$(OBJEXT): {$(VPATH)}method.h bignum.$(OBJEXT): {$(VPATH)}missing.h -bignum.$(OBJEXT): {$(VPATH)}node.h -bignum.$(OBJEXT): {$(VPATH)}onigmo.h -bignum.$(OBJEXT): {$(VPATH)}oniguruma.h bignum.$(OBJEXT): {$(VPATH)}ruby_assert.h -bignum.$(OBJEXT): {$(VPATH)}ruby_atomic.h -bignum.$(OBJEXT): {$(VPATH)}rubyparser.h bignum.$(OBJEXT): {$(VPATH)}shape.h bignum.$(OBJEXT): {$(VPATH)}st.h bignum.$(OBJEXT): {$(VPATH)}subst.h bignum.$(OBJEXT): {$(VPATH)}thread.h -bignum.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -bignum.$(OBJEXT): {$(VPATH)}thread_native.h bignum.$(OBJEXT): {$(VPATH)}util.h -bignum.$(OBJEXT): {$(VPATH)}vm_core.h -bignum.$(OBJEXT): {$(VPATH)}vm_opts.h builtin.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h builtin.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h builtin.$(OBJEXT): $(CCAN_DIR)/list/list.h @@ -2694,32 +2429,11 @@ builtin.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h builtin.$(OBJEXT): $(top_srcdir)/internal/compilers.h builtin.$(OBJEXT): $(top_srcdir)/internal/gc.h builtin.$(OBJEXT): $(top_srcdir)/internal/imemo.h -builtin.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h builtin.$(OBJEXT): $(top_srcdir)/internal/serial.h builtin.$(OBJEXT): $(top_srcdir)/internal/static_assert.h builtin.$(OBJEXT): $(top_srcdir)/internal/variable.h builtin.$(OBJEXT): $(top_srcdir)/internal/vm.h builtin.$(OBJEXT): $(top_srcdir)/internal/warnings.h -builtin.$(OBJEXT): $(top_srcdir)/prism/defines.h -builtin.$(OBJEXT): $(top_srcdir)/prism/encoding.h -builtin.$(OBJEXT): $(top_srcdir)/prism/node.h -builtin.$(OBJEXT): $(top_srcdir)/prism/options.h -builtin.$(OBJEXT): $(top_srcdir)/prism/pack.h -builtin.$(OBJEXT): $(top_srcdir)/prism/parser.h -builtin.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -builtin.$(OBJEXT): $(top_srcdir)/prism/prism.h -builtin.$(OBJEXT): $(top_srcdir)/prism/regexp.h -builtin.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -builtin.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h builtin.$(OBJEXT): {$(VPATH)}assert.h builtin.$(OBJEXT): {$(VPATH)}atomic.h builtin.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -2737,7 +2451,6 @@ builtin.$(OBJEXT): {$(VPATH)}builtin_binary.inc builtin.$(OBJEXT): {$(VPATH)}config.h builtin.$(OBJEXT): {$(VPATH)}constant.h builtin.$(OBJEXT): {$(VPATH)}defines.h -builtin.$(OBJEXT): {$(VPATH)}encoding.h builtin.$(OBJEXT): {$(VPATH)}id.h builtin.$(OBJEXT): {$(VPATH)}id_table.h builtin.$(OBJEXT): {$(VPATH)}intern.h @@ -2780,7 +2493,6 @@ builtin.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h builtin.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h builtin.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h builtin.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -builtin.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h builtin.$(OBJEXT): {$(VPATH)}internal/attr/pure.h builtin.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h builtin.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -2813,15 +2525,6 @@ builtin.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h builtin.$(OBJEXT): {$(VPATH)}internal/ctype.h builtin.$(OBJEXT): {$(VPATH)}internal/dllexport.h builtin.$(OBJEXT): {$(VPATH)}internal/dosish.h -builtin.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -builtin.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -builtin.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -builtin.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -builtin.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -builtin.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -builtin.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -builtin.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -builtin.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h builtin.$(OBJEXT): {$(VPATH)}internal/error.h builtin.$(OBJEXT): {$(VPATH)}internal/eval.h builtin.$(OBJEXT): {$(VPATH)}internal/event.h @@ -2849,6 +2552,7 @@ builtin.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h builtin.$(OBJEXT): {$(VPATH)}internal/intern/error.h builtin.$(OBJEXT): {$(VPATH)}internal/intern/eval.h builtin.$(OBJEXT): {$(VPATH)}internal/intern/file.h +builtin.$(OBJEXT): {$(VPATH)}internal/intern/gc.h builtin.$(OBJEXT): {$(VPATH)}internal/intern/hash.h builtin.$(OBJEXT): {$(VPATH)}internal/intern/io.h builtin.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -2879,12 +2583,12 @@ builtin.$(OBJEXT): {$(VPATH)}internal/memory.h builtin.$(OBJEXT): {$(VPATH)}internal/method.h builtin.$(OBJEXT): {$(VPATH)}internal/module.h builtin.$(OBJEXT): {$(VPATH)}internal/newobj.h +builtin.$(OBJEXT): {$(VPATH)}internal/rgengc.h builtin.$(OBJEXT): {$(VPATH)}internal/scan_args.h builtin.$(OBJEXT): {$(VPATH)}internal/special_consts.h builtin.$(OBJEXT): {$(VPATH)}internal/static_assert.h builtin.$(OBJEXT): {$(VPATH)}internal/stdalign.h builtin.$(OBJEXT): {$(VPATH)}internal/stdbool.h -builtin.$(OBJEXT): {$(VPATH)}internal/stdckdint.h builtin.$(OBJEXT): {$(VPATH)}internal/symbol.h builtin.$(OBJEXT): {$(VPATH)}internal/value.h builtin.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -2895,15 +2599,8 @@ builtin.$(OBJEXT): {$(VPATH)}iseq.h builtin.$(OBJEXT): {$(VPATH)}method.h builtin.$(OBJEXT): {$(VPATH)}missing.h builtin.$(OBJEXT): {$(VPATH)}node.h -builtin.$(OBJEXT): {$(VPATH)}onigmo.h -builtin.$(OBJEXT): {$(VPATH)}oniguruma.h -builtin.$(OBJEXT): {$(VPATH)}prism/ast.h -builtin.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -builtin.$(OBJEXT): {$(VPATH)}prism/version.h -builtin.$(OBJEXT): {$(VPATH)}prism_compile.h builtin.$(OBJEXT): {$(VPATH)}ruby_assert.h builtin.$(OBJEXT): {$(VPATH)}ruby_atomic.h -builtin.$(OBJEXT): {$(VPATH)}rubyparser.h builtin.$(OBJEXT): {$(VPATH)}shape.h builtin.$(OBJEXT): {$(VPATH)}st.h builtin.$(OBJEXT): {$(VPATH)}subst.h @@ -2925,7 +2622,6 @@ class.$(OBJEXT): $(top_srcdir)/internal/gc.h class.$(OBJEXT): $(top_srcdir)/internal/hash.h class.$(OBJEXT): $(top_srcdir)/internal/imemo.h class.$(OBJEXT): $(top_srcdir)/internal/object.h -class.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h class.$(OBJEXT): $(top_srcdir)/internal/serial.h class.$(OBJEXT): $(top_srcdir)/internal/static_assert.h class.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -2991,7 +2687,6 @@ class.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h class.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h class.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h class.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -class.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h class.$(OBJEXT): {$(VPATH)}internal/attr/pure.h class.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h class.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -3060,6 +2755,7 @@ class.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h class.$(OBJEXT): {$(VPATH)}internal/intern/error.h class.$(OBJEXT): {$(VPATH)}internal/intern/eval.h class.$(OBJEXT): {$(VPATH)}internal/intern/file.h +class.$(OBJEXT): {$(VPATH)}internal/intern/gc.h class.$(OBJEXT): {$(VPATH)}internal/intern/hash.h class.$(OBJEXT): {$(VPATH)}internal/intern/io.h class.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -3090,12 +2786,12 @@ class.$(OBJEXT): {$(VPATH)}internal/memory.h class.$(OBJEXT): {$(VPATH)}internal/method.h class.$(OBJEXT): {$(VPATH)}internal/module.h class.$(OBJEXT): {$(VPATH)}internal/newobj.h +class.$(OBJEXT): {$(VPATH)}internal/rgengc.h class.$(OBJEXT): {$(VPATH)}internal/scan_args.h class.$(OBJEXT): {$(VPATH)}internal/special_consts.h class.$(OBJEXT): {$(VPATH)}internal/static_assert.h class.$(OBJEXT): {$(VPATH)}internal/stdalign.h class.$(OBJEXT): {$(VPATH)}internal/stdbool.h -class.$(OBJEXT): {$(VPATH)}internal/stdckdint.h class.$(OBJEXT): {$(VPATH)}internal/symbol.h class.$(OBJEXT): {$(VPATH)}internal/value.h class.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -3109,19 +2805,14 @@ class.$(OBJEXT): {$(VPATH)}onigmo.h class.$(OBJEXT): {$(VPATH)}oniguruma.h class.$(OBJEXT): {$(VPATH)}ruby_assert.h class.$(OBJEXT): {$(VPATH)}ruby_atomic.h -class.$(OBJEXT): {$(VPATH)}rubyparser.h class.$(OBJEXT): {$(VPATH)}shape.h class.$(OBJEXT): {$(VPATH)}st.h class.$(OBJEXT): {$(VPATH)}subst.h class.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h class.$(OBJEXT): {$(VPATH)}thread_native.h class.$(OBJEXT): {$(VPATH)}vm_core.h -class.$(OBJEXT): {$(VPATH)}vm_debug.h class.$(OBJEXT): {$(VPATH)}vm_opts.h -class.$(OBJEXT): {$(VPATH)}vm_sync.h -class.$(OBJEXT): {$(VPATH)}yjit.h compar.$(OBJEXT): $(hdrdir)/ruby/ruby.h -compar.$(OBJEXT): $(hdrdir)/ruby/version.h compar.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h compar.$(OBJEXT): $(top_srcdir)/internal/compar.h compar.$(OBJEXT): $(top_srcdir)/internal/compilers.h @@ -3185,7 +2876,6 @@ compar.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h compar.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h compar.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h compar.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -compar.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h compar.$(OBJEXT): {$(VPATH)}internal/attr/pure.h compar.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h compar.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -3254,6 +2944,7 @@ compar.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h compar.$(OBJEXT): {$(VPATH)}internal/intern/error.h compar.$(OBJEXT): {$(VPATH)}internal/intern/eval.h compar.$(OBJEXT): {$(VPATH)}internal/intern/file.h +compar.$(OBJEXT): {$(VPATH)}internal/intern/gc.h compar.$(OBJEXT): {$(VPATH)}internal/intern/hash.h compar.$(OBJEXT): {$(VPATH)}internal/intern/io.h compar.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -3284,12 +2975,12 @@ compar.$(OBJEXT): {$(VPATH)}internal/memory.h compar.$(OBJEXT): {$(VPATH)}internal/method.h compar.$(OBJEXT): {$(VPATH)}internal/module.h compar.$(OBJEXT): {$(VPATH)}internal/newobj.h +compar.$(OBJEXT): {$(VPATH)}internal/rgengc.h compar.$(OBJEXT): {$(VPATH)}internal/scan_args.h compar.$(OBJEXT): {$(VPATH)}internal/special_consts.h compar.$(OBJEXT): {$(VPATH)}internal/static_assert.h compar.$(OBJEXT): {$(VPATH)}internal/stdalign.h compar.$(OBJEXT): {$(VPATH)}internal/stdbool.h -compar.$(OBJEXT): {$(VPATH)}internal/stdckdint.h compar.$(OBJEXT): {$(VPATH)}internal/symbol.h compar.$(OBJEXT): {$(VPATH)}internal/value.h compar.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -3306,7 +2997,6 @@ compile.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h compile.$(OBJEXT): $(CCAN_DIR)/list/list.h compile.$(OBJEXT): $(CCAN_DIR)/str/str.h compile.$(OBJEXT): $(hdrdir)/ruby/ruby.h -compile.$(OBJEXT): $(hdrdir)/ruby/version.h compile.$(OBJEXT): $(top_srcdir)/internal/array.h compile.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h compile.$(OBJEXT): $(top_srcdir)/internal/bignum.h @@ -3321,14 +3011,10 @@ compile.$(OBJEXT): $(top_srcdir)/internal/fixnum.h compile.$(OBJEXT): $(top_srcdir)/internal/gc.h compile.$(OBJEXT): $(top_srcdir)/internal/hash.h compile.$(OBJEXT): $(top_srcdir)/internal/imemo.h -compile.$(OBJEXT): $(top_srcdir)/internal/io.h compile.$(OBJEXT): $(top_srcdir)/internal/numeric.h compile.$(OBJEXT): $(top_srcdir)/internal/object.h -compile.$(OBJEXT): $(top_srcdir)/internal/parse.h compile.$(OBJEXT): $(top_srcdir)/internal/rational.h compile.$(OBJEXT): $(top_srcdir)/internal/re.h -compile.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h -compile.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h compile.$(OBJEXT): $(top_srcdir)/internal/serial.h compile.$(OBJEXT): $(top_srcdir)/internal/static_assert.h compile.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -3337,27 +3023,6 @@ compile.$(OBJEXT): $(top_srcdir)/internal/thread.h compile.$(OBJEXT): $(top_srcdir)/internal/variable.h compile.$(OBJEXT): $(top_srcdir)/internal/vm.h compile.$(OBJEXT): $(top_srcdir)/internal/warnings.h -compile.$(OBJEXT): $(top_srcdir)/prism/defines.h -compile.$(OBJEXT): $(top_srcdir)/prism/encoding.h -compile.$(OBJEXT): $(top_srcdir)/prism/node.h -compile.$(OBJEXT): $(top_srcdir)/prism/options.h -compile.$(OBJEXT): $(top_srcdir)/prism/pack.h -compile.$(OBJEXT): $(top_srcdir)/prism/parser.h -compile.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -compile.$(OBJEXT): $(top_srcdir)/prism/prism.h -compile.$(OBJEXT): $(top_srcdir)/prism/regexp.h -compile.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -compile.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h -compile.$(OBJEXT): $(top_srcdir)/prism_compile.c compile.$(OBJEXT): {$(VPATH)}assert.h compile.$(OBJEXT): {$(VPATH)}atomic.h compile.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -3377,6 +3042,7 @@ compile.$(OBJEXT): {$(VPATH)}debug_counter.h compile.$(OBJEXT): {$(VPATH)}defines.h compile.$(OBJEXT): {$(VPATH)}encindex.h compile.$(OBJEXT): {$(VPATH)}encoding.h +compile.$(OBJEXT): {$(VPATH)}gc.h compile.$(OBJEXT): {$(VPATH)}id.h compile.$(OBJEXT): {$(VPATH)}id_table.h compile.$(OBJEXT): {$(VPATH)}insns.def @@ -3422,7 +3088,6 @@ compile.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h compile.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h compile.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h compile.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -compile.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h compile.$(OBJEXT): {$(VPATH)}internal/attr/pure.h compile.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h compile.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -3492,6 +3157,7 @@ compile.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h compile.$(OBJEXT): {$(VPATH)}internal/intern/error.h compile.$(OBJEXT): {$(VPATH)}internal/intern/eval.h compile.$(OBJEXT): {$(VPATH)}internal/intern/file.h +compile.$(OBJEXT): {$(VPATH)}internal/intern/gc.h compile.$(OBJEXT): {$(VPATH)}internal/intern/hash.h compile.$(OBJEXT): {$(VPATH)}internal/intern/io.h compile.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -3522,19 +3188,18 @@ compile.$(OBJEXT): {$(VPATH)}internal/memory.h compile.$(OBJEXT): {$(VPATH)}internal/method.h compile.$(OBJEXT): {$(VPATH)}internal/module.h compile.$(OBJEXT): {$(VPATH)}internal/newobj.h +compile.$(OBJEXT): {$(VPATH)}internal/rgengc.h compile.$(OBJEXT): {$(VPATH)}internal/scan_args.h compile.$(OBJEXT): {$(VPATH)}internal/special_consts.h compile.$(OBJEXT): {$(VPATH)}internal/static_assert.h compile.$(OBJEXT): {$(VPATH)}internal/stdalign.h compile.$(OBJEXT): {$(VPATH)}internal/stdbool.h -compile.$(OBJEXT): {$(VPATH)}internal/stdckdint.h compile.$(OBJEXT): {$(VPATH)}internal/symbol.h compile.$(OBJEXT): {$(VPATH)}internal/value.h compile.$(OBJEXT): {$(VPATH)}internal/value_type.h compile.$(OBJEXT): {$(VPATH)}internal/variable.h compile.$(OBJEXT): {$(VPATH)}internal/warning_push.h compile.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -compile.$(OBJEXT): {$(VPATH)}io.h compile.$(OBJEXT): {$(VPATH)}iseq.h compile.$(OBJEXT): {$(VPATH)}method.h compile.$(OBJEXT): {$(VPATH)}missing.h @@ -3542,18 +3207,10 @@ compile.$(OBJEXT): {$(VPATH)}node.h compile.$(OBJEXT): {$(VPATH)}onigmo.h compile.$(OBJEXT): {$(VPATH)}oniguruma.h compile.$(OBJEXT): {$(VPATH)}optinsn.inc -compile.$(OBJEXT): {$(VPATH)}prism/ast.h -compile.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -compile.$(OBJEXT): {$(VPATH)}prism/prism.h -compile.$(OBJEXT): {$(VPATH)}prism/version.h -compile.$(OBJEXT): {$(VPATH)}prism_compile.c -compile.$(OBJEXT): {$(VPATH)}prism_compile.h -compile.$(OBJEXT): {$(VPATH)}ractor.h compile.$(OBJEXT): {$(VPATH)}re.h compile.$(OBJEXT): {$(VPATH)}regex.h compile.$(OBJEXT): {$(VPATH)}ruby_assert.h compile.$(OBJEXT): {$(VPATH)}ruby_atomic.h -compile.$(OBJEXT): {$(VPATH)}rubyparser.h compile.$(OBJEXT): {$(VPATH)}shape.h compile.$(OBJEXT): {$(VPATH)}st.h compile.$(OBJEXT): {$(VPATH)}subst.h @@ -3564,8 +3221,6 @@ compile.$(OBJEXT): {$(VPATH)}vm_callinfo.h compile.$(OBJEXT): {$(VPATH)}vm_core.h compile.$(OBJEXT): {$(VPATH)}vm_debug.h compile.$(OBJEXT): {$(VPATH)}vm_opts.h -compile.$(OBJEXT): {$(VPATH)}vm_sync.h -compile.$(OBJEXT): {$(VPATH)}yjit.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 @@ -3585,10 +3240,8 @@ complex.$(OBJEXT): $(top_srcdir)/internal/math.h complex.$(OBJEXT): $(top_srcdir)/internal/numeric.h complex.$(OBJEXT): $(top_srcdir)/internal/object.h complex.$(OBJEXT): $(top_srcdir)/internal/rational.h -complex.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h complex.$(OBJEXT): $(top_srcdir)/internal/serial.h complex.$(OBJEXT): $(top_srcdir)/internal/static_assert.h -complex.$(OBJEXT): $(top_srcdir)/internal/string.h complex.$(OBJEXT): $(top_srcdir)/internal/variable.h complex.$(OBJEXT): $(top_srcdir)/internal/vm.h complex.$(OBJEXT): $(top_srcdir)/internal/warnings.h @@ -3606,9 +3259,7 @@ complex.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h complex.$(OBJEXT): {$(VPATH)}complex.c complex.$(OBJEXT): {$(VPATH)}config.h complex.$(OBJEXT): {$(VPATH)}constant.h -complex.$(OBJEXT): {$(VPATH)}debug_counter.h complex.$(OBJEXT): {$(VPATH)}defines.h -complex.$(OBJEXT): {$(VPATH)}encoding.h complex.$(OBJEXT): {$(VPATH)}id.h complex.$(OBJEXT): {$(VPATH)}id_table.h complex.$(OBJEXT): {$(VPATH)}intern.h @@ -3651,7 +3302,6 @@ complex.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h complex.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h complex.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h complex.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -complex.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h complex.$(OBJEXT): {$(VPATH)}internal/attr/pure.h complex.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h complex.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -3684,15 +3334,6 @@ complex.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h complex.$(OBJEXT): {$(VPATH)}internal/ctype.h complex.$(OBJEXT): {$(VPATH)}internal/dllexport.h complex.$(OBJEXT): {$(VPATH)}internal/dosish.h -complex.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -complex.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -complex.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -complex.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -complex.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -complex.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -complex.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -complex.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -complex.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h complex.$(OBJEXT): {$(VPATH)}internal/error.h complex.$(OBJEXT): {$(VPATH)}internal/eval.h complex.$(OBJEXT): {$(VPATH)}internal/event.h @@ -3720,6 +3361,7 @@ complex.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h complex.$(OBJEXT): {$(VPATH)}internal/intern/error.h complex.$(OBJEXT): {$(VPATH)}internal/intern/eval.h complex.$(OBJEXT): {$(VPATH)}internal/intern/file.h +complex.$(OBJEXT): {$(VPATH)}internal/intern/gc.h complex.$(OBJEXT): {$(VPATH)}internal/intern/hash.h complex.$(OBJEXT): {$(VPATH)}internal/intern/io.h complex.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -3750,12 +3392,12 @@ complex.$(OBJEXT): {$(VPATH)}internal/memory.h complex.$(OBJEXT): {$(VPATH)}internal/method.h complex.$(OBJEXT): {$(VPATH)}internal/module.h complex.$(OBJEXT): {$(VPATH)}internal/newobj.h +complex.$(OBJEXT): {$(VPATH)}internal/rgengc.h complex.$(OBJEXT): {$(VPATH)}internal/scan_args.h complex.$(OBJEXT): {$(VPATH)}internal/special_consts.h complex.$(OBJEXT): {$(VPATH)}internal/static_assert.h complex.$(OBJEXT): {$(VPATH)}internal/stdalign.h complex.$(OBJEXT): {$(VPATH)}internal/stdbool.h -complex.$(OBJEXT): {$(VPATH)}internal/stdckdint.h complex.$(OBJEXT): {$(VPATH)}internal/symbol.h complex.$(OBJEXT): {$(VPATH)}internal/value.h complex.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -3765,27 +3407,21 @@ complex.$(OBJEXT): {$(VPATH)}internal/xmalloc.h complex.$(OBJEXT): {$(VPATH)}method.h complex.$(OBJEXT): {$(VPATH)}missing.h complex.$(OBJEXT): {$(VPATH)}node.h -complex.$(OBJEXT): {$(VPATH)}onigmo.h -complex.$(OBJEXT): {$(VPATH)}oniguruma.h complex.$(OBJEXT): {$(VPATH)}ruby_assert.h complex.$(OBJEXT): {$(VPATH)}ruby_atomic.h -complex.$(OBJEXT): {$(VPATH)}rubyparser.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_debug.h complex.$(OBJEXT): {$(VPATH)}vm_opts.h -complex.$(OBJEXT): {$(VPATH)}vm_sync.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 cont.$(OBJEXT): $(CCAN_DIR)/str/str.h cont.$(OBJEXT): $(hdrdir)/ruby.h cont.$(OBJEXT): $(hdrdir)/ruby/ruby.h -cont.$(OBJEXT): $(hdrdir)/ruby/version.h cont.$(OBJEXT): $(top_srcdir)/internal/array.h cont.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h cont.$(OBJEXT): $(top_srcdir)/internal/compilers.h @@ -3798,30 +3434,9 @@ 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/thread.h cont.$(OBJEXT): $(top_srcdir)/internal/variable.h cont.$(OBJEXT): $(top_srcdir)/internal/vm.h cont.$(OBJEXT): $(top_srcdir)/internal/warnings.h -cont.$(OBJEXT): $(top_srcdir)/prism/defines.h -cont.$(OBJEXT): $(top_srcdir)/prism/encoding.h -cont.$(OBJEXT): $(top_srcdir)/prism/node.h -cont.$(OBJEXT): $(top_srcdir)/prism/options.h -cont.$(OBJEXT): $(top_srcdir)/prism/pack.h -cont.$(OBJEXT): $(top_srcdir)/prism/parser.h -cont.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -cont.$(OBJEXT): $(top_srcdir)/prism/prism.h -cont.$(OBJEXT): $(top_srcdir)/prism/regexp.h -cont.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -cont.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h cont.$(OBJEXT): {$(VPATH)}$(COROUTINE_H) cont.$(OBJEXT): {$(VPATH)}assert.h cont.$(OBJEXT): {$(VPATH)}atomic.h @@ -3842,6 +3457,7 @@ 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 cont.$(OBJEXT): {$(VPATH)}id.h cont.$(OBJEXT): {$(VPATH)}id_table.h cont.$(OBJEXT): {$(VPATH)}intern.h @@ -3884,7 +3500,6 @@ cont.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h cont.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h cont.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h cont.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -cont.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h cont.$(OBJEXT): {$(VPATH)}internal/attr/pure.h cont.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h cont.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -3953,6 +3568,7 @@ cont.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h cont.$(OBJEXT): {$(VPATH)}internal/intern/error.h cont.$(OBJEXT): {$(VPATH)}internal/intern/eval.h cont.$(OBJEXT): {$(VPATH)}internal/intern/file.h +cont.$(OBJEXT): {$(VPATH)}internal/intern/gc.h cont.$(OBJEXT): {$(VPATH)}internal/intern/hash.h cont.$(OBJEXT): {$(VPATH)}internal/intern/io.h cont.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -3983,12 +3599,12 @@ cont.$(OBJEXT): {$(VPATH)}internal/memory.h cont.$(OBJEXT): {$(VPATH)}internal/method.h cont.$(OBJEXT): {$(VPATH)}internal/module.h cont.$(OBJEXT): {$(VPATH)}internal/newobj.h +cont.$(OBJEXT): {$(VPATH)}internal/rgengc.h cont.$(OBJEXT): {$(VPATH)}internal/scan_args.h cont.$(OBJEXT): {$(VPATH)}internal/special_consts.h cont.$(OBJEXT): {$(VPATH)}internal/static_assert.h cont.$(OBJEXT): {$(VPATH)}internal/stdalign.h cont.$(OBJEXT): {$(VPATH)}internal/stdbool.h -cont.$(OBJEXT): {$(VPATH)}internal/stdckdint.h cont.$(OBJEXT): {$(VPATH)}internal/symbol.h cont.$(OBJEXT): {$(VPATH)}internal/value.h cont.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -3998,19 +3614,14 @@ cont.$(OBJEXT): {$(VPATH)}internal/xmalloc.h cont.$(OBJEXT): {$(VPATH)}iseq.h 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)}prism/ast.h -cont.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -cont.$(OBJEXT): {$(VPATH)}prism/version.h -cont.$(OBJEXT): {$(VPATH)}prism_compile.h cont.$(OBJEXT): {$(VPATH)}ractor.h cont.$(OBJEXT): {$(VPATH)}ractor_core.h -cont.$(OBJEXT): {$(VPATH)}rjit.h cont.$(OBJEXT): {$(VPATH)}ruby_assert.h cont.$(OBJEXT): {$(VPATH)}ruby_atomic.h -cont.$(OBJEXT): {$(VPATH)}rubyparser.h cont.$(OBJEXT): {$(VPATH)}shape.h cont.$(OBJEXT): {$(VPATH)}st.h cont.$(OBJEXT): {$(VPATH)}subst.h @@ -4032,7 +3643,6 @@ debug.$(OBJEXT): $(top_srcdir)/internal/class.h debug.$(OBJEXT): $(top_srcdir)/internal/compilers.h debug.$(OBJEXT): $(top_srcdir)/internal/gc.h debug.$(OBJEXT): $(top_srcdir)/internal/imemo.h -debug.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h debug.$(OBJEXT): $(top_srcdir)/internal/serial.h debug.$(OBJEXT): $(top_srcdir)/internal/signal.h debug.$(OBJEXT): $(top_srcdir)/internal/static_assert.h @@ -4058,6 +3668,7 @@ debug.$(OBJEXT): {$(VPATH)}defines.h debug.$(OBJEXT): {$(VPATH)}encindex.h debug.$(OBJEXT): {$(VPATH)}encoding.h debug.$(OBJEXT): {$(VPATH)}eval_intern.h +debug.$(OBJEXT): {$(VPATH)}gc.h debug.$(OBJEXT): {$(VPATH)}id.h debug.$(OBJEXT): {$(VPATH)}id_table.h debug.$(OBJEXT): {$(VPATH)}intern.h @@ -4100,7 +3711,6 @@ debug.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h debug.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h debug.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h debug.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -debug.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h debug.$(OBJEXT): {$(VPATH)}internal/attr/pure.h debug.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h debug.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -4169,6 +3779,7 @@ debug.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h debug.$(OBJEXT): {$(VPATH)}internal/intern/error.h debug.$(OBJEXT): {$(VPATH)}internal/intern/eval.h debug.$(OBJEXT): {$(VPATH)}internal/intern/file.h +debug.$(OBJEXT): {$(VPATH)}internal/intern/gc.h debug.$(OBJEXT): {$(VPATH)}internal/intern/hash.h debug.$(OBJEXT): {$(VPATH)}internal/intern/io.h debug.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -4199,12 +3810,12 @@ debug.$(OBJEXT): {$(VPATH)}internal/memory.h debug.$(OBJEXT): {$(VPATH)}internal/method.h debug.$(OBJEXT): {$(VPATH)}internal/module.h debug.$(OBJEXT): {$(VPATH)}internal/newobj.h +debug.$(OBJEXT): {$(VPATH)}internal/rgengc.h debug.$(OBJEXT): {$(VPATH)}internal/scan_args.h debug.$(OBJEXT): {$(VPATH)}internal/special_consts.h debug.$(OBJEXT): {$(VPATH)}internal/static_assert.h debug.$(OBJEXT): {$(VPATH)}internal/stdalign.h debug.$(OBJEXT): {$(VPATH)}internal/stdbool.h -debug.$(OBJEXT): {$(VPATH)}internal/stdckdint.h debug.$(OBJEXT): {$(VPATH)}internal/symbol.h debug.$(OBJEXT): {$(VPATH)}internal/value.h debug.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -4221,7 +3832,6 @@ debug.$(OBJEXT): {$(VPATH)}ractor.h debug.$(OBJEXT): {$(VPATH)}ractor_core.h debug.$(OBJEXT): {$(VPATH)}ruby_assert.h debug.$(OBJEXT): {$(VPATH)}ruby_atomic.h -debug.$(OBJEXT): {$(VPATH)}rubyparser.h debug.$(OBJEXT): {$(VPATH)}shape.h debug.$(OBJEXT): {$(VPATH)}st.h debug.$(OBJEXT): {$(VPATH)}subst.h @@ -4233,7 +3843,6 @@ debug.$(OBJEXT): {$(VPATH)}vm_callinfo.h debug.$(OBJEXT): {$(VPATH)}vm_core.h debug.$(OBJEXT): {$(VPATH)}vm_debug.h debug.$(OBJEXT): {$(VPATH)}vm_opts.h -debug.$(OBJEXT): {$(VPATH)}vm_sync.h debug_counter.$(OBJEXT): $(hdrdir)/ruby/ruby.h debug_counter.$(OBJEXT): {$(VPATH)}assert.h debug_counter.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -4288,7 +3897,6 @@ debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/pure.h debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h debug_counter.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -4348,6 +3956,7 @@ debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/error.h debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/eval.h debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/file.h +debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/gc.h debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/hash.h debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/io.h debug_counter.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -4378,12 +3987,12 @@ debug_counter.$(OBJEXT): {$(VPATH)}internal/memory.h debug_counter.$(OBJEXT): {$(VPATH)}internal/method.h debug_counter.$(OBJEXT): {$(VPATH)}internal/module.h debug_counter.$(OBJEXT): {$(VPATH)}internal/newobj.h +debug_counter.$(OBJEXT): {$(VPATH)}internal/rgengc.h debug_counter.$(OBJEXT): {$(VPATH)}internal/scan_args.h debug_counter.$(OBJEXT): {$(VPATH)}internal/special_consts.h debug_counter.$(OBJEXT): {$(VPATH)}internal/static_assert.h debug_counter.$(OBJEXT): {$(VPATH)}internal/stdalign.h debug_counter.$(OBJEXT): {$(VPATH)}internal/stdbool.h -debug_counter.$(OBJEXT): {$(VPATH)}internal/stdckdint.h debug_counter.$(OBJEXT): {$(VPATH)}internal/symbol.h debug_counter.$(OBJEXT): {$(VPATH)}internal/value.h debug_counter.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -4394,14 +4003,8 @@ debug_counter.$(OBJEXT): {$(VPATH)}missing.h debug_counter.$(OBJEXT): {$(VPATH)}st.h debug_counter.$(OBJEXT): {$(VPATH)}subst.h debug_counter.$(OBJEXT): {$(VPATH)}thread_native.h -dir.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -dir.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -dir.$(OBJEXT): $(CCAN_DIR)/list/list.h -dir.$(OBJEXT): $(CCAN_DIR)/str/str.h dir.$(OBJEXT): $(hdrdir)/ruby/ruby.h -dir.$(OBJEXT): $(hdrdir)/ruby/version.h dir.$(OBJEXT): $(top_srcdir)/internal/array.h -dir.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h dir.$(OBJEXT): $(top_srcdir)/internal/class.h dir.$(OBJEXT): $(top_srcdir)/internal/compilers.h dir.$(OBJEXT): $(top_srcdir)/internal/dir.h @@ -4409,10 +4012,8 @@ dir.$(OBJEXT): $(top_srcdir)/internal/encoding.h dir.$(OBJEXT): $(top_srcdir)/internal/error.h dir.$(OBJEXT): $(top_srcdir)/internal/file.h dir.$(OBJEXT): $(top_srcdir)/internal/gc.h -dir.$(OBJEXT): $(top_srcdir)/internal/imemo.h dir.$(OBJEXT): $(top_srcdir)/internal/io.h dir.$(OBJEXT): $(top_srcdir)/internal/object.h -dir.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h dir.$(OBJEXT): $(top_srcdir)/internal/serial.h dir.$(OBJEXT): $(top_srcdir)/internal/static_assert.h dir.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -4420,7 +4021,6 @@ dir.$(OBJEXT): $(top_srcdir)/internal/variable.h dir.$(OBJEXT): $(top_srcdir)/internal/vm.h dir.$(OBJEXT): $(top_srcdir)/internal/warnings.h dir.$(OBJEXT): {$(VPATH)}assert.h -dir.$(OBJEXT): {$(VPATH)}atomic.h dir.$(OBJEXT): {$(VPATH)}backward/2/assume.h dir.$(OBJEXT): {$(VPATH)}backward/2/attributes.h dir.$(OBJEXT): {$(VPATH)}backward/2/bool.h @@ -4480,7 +4080,6 @@ dir.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h dir.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h dir.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h dir.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -dir.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h dir.$(OBJEXT): {$(VPATH)}internal/attr/pure.h dir.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h dir.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -4549,6 +4148,7 @@ dir.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h dir.$(OBJEXT): {$(VPATH)}internal/intern/error.h dir.$(OBJEXT): {$(VPATH)}internal/intern/eval.h dir.$(OBJEXT): {$(VPATH)}internal/intern/file.h +dir.$(OBJEXT): {$(VPATH)}internal/intern/gc.h dir.$(OBJEXT): {$(VPATH)}internal/intern/hash.h dir.$(OBJEXT): {$(VPATH)}internal/intern/io.h dir.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -4579,12 +4179,12 @@ dir.$(OBJEXT): {$(VPATH)}internal/memory.h dir.$(OBJEXT): {$(VPATH)}internal/method.h dir.$(OBJEXT): {$(VPATH)}internal/module.h dir.$(OBJEXT): {$(VPATH)}internal/newobj.h +dir.$(OBJEXT): {$(VPATH)}internal/rgengc.h dir.$(OBJEXT): {$(VPATH)}internal/scan_args.h dir.$(OBJEXT): {$(VPATH)}internal/special_consts.h dir.$(OBJEXT): {$(VPATH)}internal/static_assert.h dir.$(OBJEXT): {$(VPATH)}internal/stdalign.h dir.$(OBJEXT): {$(VPATH)}internal/stdbool.h -dir.$(OBJEXT): {$(VPATH)}internal/stdckdint.h dir.$(OBJEXT): {$(VPATH)}internal/symbol.h dir.$(OBJEXT): {$(VPATH)}internal/value.h dir.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -4592,23 +4192,14 @@ dir.$(OBJEXT): {$(VPATH)}internal/variable.h dir.$(OBJEXT): {$(VPATH)}internal/warning_push.h dir.$(OBJEXT): {$(VPATH)}internal/xmalloc.h dir.$(OBJEXT): {$(VPATH)}io.h -dir.$(OBJEXT): {$(VPATH)}method.h dir.$(OBJEXT): {$(VPATH)}missing.h -dir.$(OBJEXT): {$(VPATH)}node.h dir.$(OBJEXT): {$(VPATH)}onigmo.h dir.$(OBJEXT): {$(VPATH)}oniguruma.h -dir.$(OBJEXT): {$(VPATH)}ruby_assert.h -dir.$(OBJEXT): {$(VPATH)}ruby_atomic.h -dir.$(OBJEXT): {$(VPATH)}rubyparser.h dir.$(OBJEXT): {$(VPATH)}shape.h dir.$(OBJEXT): {$(VPATH)}st.h dir.$(OBJEXT): {$(VPATH)}subst.h dir.$(OBJEXT): {$(VPATH)}thread.h -dir.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -dir.$(OBJEXT): {$(VPATH)}thread_native.h dir.$(OBJEXT): {$(VPATH)}util.h -dir.$(OBJEXT): {$(VPATH)}vm_core.h -dir.$(OBJEXT): {$(VPATH)}vm_opts.h dln.$(OBJEXT): $(hdrdir)/ruby/ruby.h dln.$(OBJEXT): $(top_srcdir)/internal/compilers.h dln.$(OBJEXT): $(top_srcdir)/internal/warnings.h @@ -4666,7 +4257,6 @@ dln.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h dln.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h dln.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h dln.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -dln.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h dln.$(OBJEXT): {$(VPATH)}internal/attr/pure.h dln.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h dln.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -4726,6 +4316,7 @@ dln.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h dln.$(OBJEXT): {$(VPATH)}internal/intern/error.h dln.$(OBJEXT): {$(VPATH)}internal/intern/eval.h dln.$(OBJEXT): {$(VPATH)}internal/intern/file.h +dln.$(OBJEXT): {$(VPATH)}internal/intern/gc.h dln.$(OBJEXT): {$(VPATH)}internal/intern/hash.h dln.$(OBJEXT): {$(VPATH)}internal/intern/io.h dln.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -4756,12 +4347,12 @@ dln.$(OBJEXT): {$(VPATH)}internal/memory.h dln.$(OBJEXT): {$(VPATH)}internal/method.h dln.$(OBJEXT): {$(VPATH)}internal/module.h dln.$(OBJEXT): {$(VPATH)}internal/newobj.h +dln.$(OBJEXT): {$(VPATH)}internal/rgengc.h dln.$(OBJEXT): {$(VPATH)}internal/scan_args.h dln.$(OBJEXT): {$(VPATH)}internal/special_consts.h dln.$(OBJEXT): {$(VPATH)}internal/static_assert.h dln.$(OBJEXT): {$(VPATH)}internal/stdalign.h dln.$(OBJEXT): {$(VPATH)}internal/stdbool.h -dln.$(OBJEXT): {$(VPATH)}internal/stdckdint.h dln.$(OBJEXT): {$(VPATH)}internal/symbol.h dln.$(OBJEXT): {$(VPATH)}internal/value.h dln.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -4824,7 +4415,6 @@ dln_find.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h dln_find.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h dln_find.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h dln_find.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -dln_find.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h dln_find.$(OBJEXT): {$(VPATH)}internal/attr/pure.h dln_find.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h dln_find.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -4884,6 +4474,7 @@ dln_find.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h dln_find.$(OBJEXT): {$(VPATH)}internal/intern/error.h dln_find.$(OBJEXT): {$(VPATH)}internal/intern/eval.h dln_find.$(OBJEXT): {$(VPATH)}internal/intern/file.h +dln_find.$(OBJEXT): {$(VPATH)}internal/intern/gc.h dln_find.$(OBJEXT): {$(VPATH)}internal/intern/hash.h dln_find.$(OBJEXT): {$(VPATH)}internal/intern/io.h dln_find.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -4914,12 +4505,12 @@ dln_find.$(OBJEXT): {$(VPATH)}internal/memory.h dln_find.$(OBJEXT): {$(VPATH)}internal/method.h dln_find.$(OBJEXT): {$(VPATH)}internal/module.h dln_find.$(OBJEXT): {$(VPATH)}internal/newobj.h +dln_find.$(OBJEXT): {$(VPATH)}internal/rgengc.h dln_find.$(OBJEXT): {$(VPATH)}internal/scan_args.h dln_find.$(OBJEXT): {$(VPATH)}internal/special_consts.h dln_find.$(OBJEXT): {$(VPATH)}internal/static_assert.h dln_find.$(OBJEXT): {$(VPATH)}internal/stdalign.h dln_find.$(OBJEXT): {$(VPATH)}internal/stdbool.h -dln_find.$(OBJEXT): {$(VPATH)}internal/stdckdint.h dln_find.$(OBJEXT): {$(VPATH)}internal/symbol.h dln_find.$(OBJEXT): {$(VPATH)}internal/value.h dln_find.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -4981,7 +4572,6 @@ dmydln.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h dmydln.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h dmydln.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h dmydln.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -dmydln.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h dmydln.$(OBJEXT): {$(VPATH)}internal/attr/pure.h dmydln.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h dmydln.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -5041,6 +4631,7 @@ dmydln.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h dmydln.$(OBJEXT): {$(VPATH)}internal/intern/error.h dmydln.$(OBJEXT): {$(VPATH)}internal/intern/eval.h dmydln.$(OBJEXT): {$(VPATH)}internal/intern/file.h +dmydln.$(OBJEXT): {$(VPATH)}internal/intern/gc.h dmydln.$(OBJEXT): {$(VPATH)}internal/intern/hash.h dmydln.$(OBJEXT): {$(VPATH)}internal/intern/io.h dmydln.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -5071,12 +4662,12 @@ dmydln.$(OBJEXT): {$(VPATH)}internal/memory.h dmydln.$(OBJEXT): {$(VPATH)}internal/method.h dmydln.$(OBJEXT): {$(VPATH)}internal/module.h dmydln.$(OBJEXT): {$(VPATH)}internal/newobj.h +dmydln.$(OBJEXT): {$(VPATH)}internal/rgengc.h dmydln.$(OBJEXT): {$(VPATH)}internal/scan_args.h dmydln.$(OBJEXT): {$(VPATH)}internal/special_consts.h dmydln.$(OBJEXT): {$(VPATH)}internal/static_assert.h dmydln.$(OBJEXT): {$(VPATH)}internal/stdalign.h dmydln.$(OBJEXT): {$(VPATH)}internal/stdbool.h -dmydln.$(OBJEXT): {$(VPATH)}internal/stdckdint.h dmydln.$(OBJEXT): {$(VPATH)}internal/symbol.h dmydln.$(OBJEXT): {$(VPATH)}internal/value.h dmydln.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -5209,6 +4800,7 @@ enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/error.h enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/eval.h enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/file.h +enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/gc.h enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/hash.h enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/io.h enc/ascii.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -5239,6 +4831,7 @@ enc/ascii.$(OBJEXT): {$(VPATH)}internal/memory.h enc/ascii.$(OBJEXT): {$(VPATH)}internal/method.h enc/ascii.$(OBJEXT): {$(VPATH)}internal/module.h enc/ascii.$(OBJEXT): {$(VPATH)}internal/newobj.h +enc/ascii.$(OBJEXT): {$(VPATH)}internal/rgengc.h enc/ascii.$(OBJEXT): {$(VPATH)}internal/scan_args.h enc/ascii.$(OBJEXT): {$(VPATH)}internal/special_consts.h enc/ascii.$(OBJEXT): {$(VPATH)}internal/static_assert.h @@ -5366,6 +4959,7 @@ enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/error.h enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/eval.h enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/file.h +enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/gc.h enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/hash.h enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/io.h enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -5396,6 +4990,7 @@ enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/memory.h enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/method.h enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/module.h enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/newobj.h +enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/rgengc.h enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/scan_args.h enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/special_consts.h enc/trans/newline.$(OBJEXT): {$(VPATH)}internal/static_assert.h @@ -5523,6 +5118,7 @@ enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/error.h enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/eval.h enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/file.h +enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/gc.h enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/hash.h enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/io.h enc/unicode.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -5553,6 +5149,7 @@ enc/unicode.$(OBJEXT): {$(VPATH)}internal/memory.h enc/unicode.$(OBJEXT): {$(VPATH)}internal/method.h enc/unicode.$(OBJEXT): {$(VPATH)}internal/module.h enc/unicode.$(OBJEXT): {$(VPATH)}internal/newobj.h +enc/unicode.$(OBJEXT): {$(VPATH)}internal/rgengc.h enc/unicode.$(OBJEXT): {$(VPATH)}internal/scan_args.h enc/unicode.$(OBJEXT): {$(VPATH)}internal/special_consts.h enc/unicode.$(OBJEXT): {$(VPATH)}internal/static_assert.h @@ -5691,6 +5288,7 @@ enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/error.h enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/eval.h enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/file.h +enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/gc.h enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/hash.h enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/io.h enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -5721,6 +5319,7 @@ enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/memory.h enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/method.h enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/module.h enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/newobj.h +enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/rgengc.h enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/scan_args.h enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/special_consts.h enc/us_ascii.$(OBJEXT): {$(VPATH)}internal/static_assert.h @@ -5859,6 +5458,7 @@ enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/error.h enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/eval.h enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/file.h +enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/gc.h enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/hash.h enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/io.h enc/utf_8.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -5889,6 +5489,7 @@ enc/utf_8.$(OBJEXT): {$(VPATH)}internal/memory.h enc/utf_8.$(OBJEXT): {$(VPATH)}internal/method.h enc/utf_8.$(OBJEXT): {$(VPATH)}internal/module.h enc/utf_8.$(OBJEXT): {$(VPATH)}internal/newobj.h +enc/utf_8.$(OBJEXT): {$(VPATH)}internal/rgengc.h enc/utf_8.$(OBJEXT): {$(VPATH)}internal/scan_args.h enc/utf_8.$(OBJEXT): {$(VPATH)}internal/special_consts.h enc/utf_8.$(OBJEXT): {$(VPATH)}internal/static_assert.h @@ -5906,22 +5507,14 @@ enc/utf_8.$(OBJEXT): {$(VPATH)}oniguruma.h enc/utf_8.$(OBJEXT): {$(VPATH)}regenc.h enc/utf_8.$(OBJEXT): {$(VPATH)}st.h enc/utf_8.$(OBJEXT): {$(VPATH)}subst.h -encoding.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -encoding.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -encoding.$(OBJEXT): $(CCAN_DIR)/list/list.h -encoding.$(OBJEXT): $(CCAN_DIR)/str/str.h encoding.$(OBJEXT): $(hdrdir)/ruby.h encoding.$(OBJEXT): $(hdrdir)/ruby/ruby.h -encoding.$(OBJEXT): $(hdrdir)/ruby/version.h -encoding.$(OBJEXT): $(top_srcdir)/internal/array.h -encoding.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h encoding.$(OBJEXT): $(top_srcdir)/internal/class.h encoding.$(OBJEXT): $(top_srcdir)/internal/compilers.h encoding.$(OBJEXT): $(top_srcdir)/internal/enc.h encoding.$(OBJEXT): $(top_srcdir)/internal/encoding.h encoding.$(OBJEXT): $(top_srcdir)/internal/error.h encoding.$(OBJEXT): $(top_srcdir)/internal/gc.h -encoding.$(OBJEXT): $(top_srcdir)/internal/imemo.h encoding.$(OBJEXT): $(top_srcdir)/internal/inits.h encoding.$(OBJEXT): $(top_srcdir)/internal/load.h encoding.$(OBJEXT): $(top_srcdir)/internal/object.h @@ -5932,7 +5525,6 @@ encoding.$(OBJEXT): $(top_srcdir)/internal/variable.h encoding.$(OBJEXT): $(top_srcdir)/internal/vm.h encoding.$(OBJEXT): $(top_srcdir)/internal/warnings.h encoding.$(OBJEXT): {$(VPATH)}assert.h -encoding.$(OBJEXT): {$(VPATH)}atomic.h encoding.$(OBJEXT): {$(VPATH)}backward/2/assume.h encoding.$(OBJEXT): {$(VPATH)}backward/2/attributes.h encoding.$(OBJEXT): {$(VPATH)}backward/2/bool.h @@ -5949,7 +5541,6 @@ encoding.$(OBJEXT): {$(VPATH)}defines.h encoding.$(OBJEXT): {$(VPATH)}encindex.h encoding.$(OBJEXT): {$(VPATH)}encoding.c encoding.$(OBJEXT): {$(VPATH)}encoding.h -encoding.$(OBJEXT): {$(VPATH)}id.h encoding.$(OBJEXT): {$(VPATH)}id_table.h encoding.$(OBJEXT): {$(VPATH)}intern.h encoding.$(OBJEXT): {$(VPATH)}internal.h @@ -5991,7 +5582,6 @@ encoding.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h encoding.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h encoding.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h encoding.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -encoding.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h encoding.$(OBJEXT): {$(VPATH)}internal/attr/pure.h encoding.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h encoding.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -6060,6 +5650,7 @@ encoding.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h encoding.$(OBJEXT): {$(VPATH)}internal/intern/error.h encoding.$(OBJEXT): {$(VPATH)}internal/intern/eval.h encoding.$(OBJEXT): {$(VPATH)}internal/intern/file.h +encoding.$(OBJEXT): {$(VPATH)}internal/intern/gc.h encoding.$(OBJEXT): {$(VPATH)}internal/intern/hash.h encoding.$(OBJEXT): {$(VPATH)}internal/intern/io.h encoding.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -6090,36 +5681,28 @@ encoding.$(OBJEXT): {$(VPATH)}internal/memory.h encoding.$(OBJEXT): {$(VPATH)}internal/method.h encoding.$(OBJEXT): {$(VPATH)}internal/module.h encoding.$(OBJEXT): {$(VPATH)}internal/newobj.h +encoding.$(OBJEXT): {$(VPATH)}internal/rgengc.h encoding.$(OBJEXT): {$(VPATH)}internal/scan_args.h encoding.$(OBJEXT): {$(VPATH)}internal/special_consts.h encoding.$(OBJEXT): {$(VPATH)}internal/static_assert.h encoding.$(OBJEXT): {$(VPATH)}internal/stdalign.h encoding.$(OBJEXT): {$(VPATH)}internal/stdbool.h -encoding.$(OBJEXT): {$(VPATH)}internal/stdckdint.h encoding.$(OBJEXT): {$(VPATH)}internal/symbol.h encoding.$(OBJEXT): {$(VPATH)}internal/value.h encoding.$(OBJEXT): {$(VPATH)}internal/value_type.h encoding.$(OBJEXT): {$(VPATH)}internal/variable.h encoding.$(OBJEXT): {$(VPATH)}internal/warning_push.h encoding.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -encoding.$(OBJEXT): {$(VPATH)}method.h encoding.$(OBJEXT): {$(VPATH)}missing.h -encoding.$(OBJEXT): {$(VPATH)}node.h encoding.$(OBJEXT): {$(VPATH)}onigmo.h encoding.$(OBJEXT): {$(VPATH)}oniguruma.h encoding.$(OBJEXT): {$(VPATH)}regenc.h encoding.$(OBJEXT): {$(VPATH)}ruby_assert.h -encoding.$(OBJEXT): {$(VPATH)}ruby_atomic.h -encoding.$(OBJEXT): {$(VPATH)}rubyparser.h encoding.$(OBJEXT): {$(VPATH)}shape.h encoding.$(OBJEXT): {$(VPATH)}st.h encoding.$(OBJEXT): {$(VPATH)}subst.h -encoding.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -encoding.$(OBJEXT): {$(VPATH)}thread_native.h encoding.$(OBJEXT): {$(VPATH)}util.h -encoding.$(OBJEXT): {$(VPATH)}vm_core.h encoding.$(OBJEXT): {$(VPATH)}vm_debug.h -encoding.$(OBJEXT): {$(VPATH)}vm_opts.h encoding.$(OBJEXT): {$(VPATH)}vm_sync.h enum.$(OBJEXT): $(hdrdir)/ruby/ruby.h enum.$(OBJEXT): $(top_srcdir)/internal/array.h @@ -6201,7 +5784,6 @@ enum.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h enum.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h enum.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h enum.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -enum.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h enum.$(OBJEXT): {$(VPATH)}internal/attr/pure.h enum.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h enum.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -6270,6 +5852,7 @@ enum.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h enum.$(OBJEXT): {$(VPATH)}internal/intern/error.h enum.$(OBJEXT): {$(VPATH)}internal/intern/eval.h enum.$(OBJEXT): {$(VPATH)}internal/intern/file.h +enum.$(OBJEXT): {$(VPATH)}internal/intern/gc.h enum.$(OBJEXT): {$(VPATH)}internal/intern/hash.h enum.$(OBJEXT): {$(VPATH)}internal/intern/io.h enum.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -6300,12 +5883,12 @@ enum.$(OBJEXT): {$(VPATH)}internal/memory.h enum.$(OBJEXT): {$(VPATH)}internal/method.h enum.$(OBJEXT): {$(VPATH)}internal/module.h enum.$(OBJEXT): {$(VPATH)}internal/newobj.h +enum.$(OBJEXT): {$(VPATH)}internal/rgengc.h enum.$(OBJEXT): {$(VPATH)}internal/scan_args.h enum.$(OBJEXT): {$(VPATH)}internal/special_consts.h enum.$(OBJEXT): {$(VPATH)}internal/static_assert.h enum.$(OBJEXT): {$(VPATH)}internal/stdalign.h enum.$(OBJEXT): {$(VPATH)}internal/stdbool.h -enum.$(OBJEXT): {$(VPATH)}internal/stdckdint.h enum.$(OBJEXT): {$(VPATH)}internal/symbol.h enum.$(OBJEXT): {$(VPATH)}internal/value.h enum.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -6326,7 +5909,6 @@ 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): $(hdrdir)/ruby/version.h enumerator.$(OBJEXT): $(top_srcdir)/internal/array.h enumerator.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h enumerator.$(OBJEXT): $(top_srcdir)/internal/bignum.h @@ -6342,12 +5924,10 @@ enumerator.$(OBJEXT): $(top_srcdir)/internal/imemo.h enumerator.$(OBJEXT): $(top_srcdir)/internal/numeric.h enumerator.$(OBJEXT): $(top_srcdir)/internal/range.h enumerator.$(OBJEXT): $(top_srcdir)/internal/rational.h -enumerator.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h enumerator.$(OBJEXT): $(top_srcdir)/internal/serial.h enumerator.$(OBJEXT): $(top_srcdir)/internal/static_assert.h enumerator.$(OBJEXT): $(top_srcdir)/internal/string.h enumerator.$(OBJEXT): $(top_srcdir)/internal/struct.h -enumerator.$(OBJEXT): $(top_srcdir)/internal/variable.h enumerator.$(OBJEXT): $(top_srcdir)/internal/vm.h enumerator.$(OBJEXT): $(top_srcdir)/internal/warnings.h enumerator.$(OBJEXT): {$(VPATH)}assert.h @@ -6362,8 +5942,6 @@ enumerator.$(OBJEXT): {$(VPATH)}backward/2/long_long.h enumerator.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h enumerator.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h enumerator.$(OBJEXT): {$(VPATH)}config.h -enumerator.$(OBJEXT): {$(VPATH)}constant.h -enumerator.$(OBJEXT): {$(VPATH)}debug_counter.h enumerator.$(OBJEXT): {$(VPATH)}defines.h enumerator.$(OBJEXT): {$(VPATH)}encoding.h enumerator.$(OBJEXT): {$(VPATH)}enumerator.c @@ -6409,7 +5987,6 @@ enumerator.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h enumerator.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h enumerator.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h enumerator.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -enumerator.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h enumerator.$(OBJEXT): {$(VPATH)}internal/attr/pure.h enumerator.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h enumerator.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -6478,6 +6055,7 @@ enumerator.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h enumerator.$(OBJEXT): {$(VPATH)}internal/intern/error.h enumerator.$(OBJEXT): {$(VPATH)}internal/intern/eval.h enumerator.$(OBJEXT): {$(VPATH)}internal/intern/file.h +enumerator.$(OBJEXT): {$(VPATH)}internal/intern/gc.h enumerator.$(OBJEXT): {$(VPATH)}internal/intern/hash.h enumerator.$(OBJEXT): {$(VPATH)}internal/intern/io.h enumerator.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -6508,12 +6086,12 @@ enumerator.$(OBJEXT): {$(VPATH)}internal/memory.h enumerator.$(OBJEXT): {$(VPATH)}internal/method.h enumerator.$(OBJEXT): {$(VPATH)}internal/module.h enumerator.$(OBJEXT): {$(VPATH)}internal/newobj.h +enumerator.$(OBJEXT): {$(VPATH)}internal/rgengc.h enumerator.$(OBJEXT): {$(VPATH)}internal/scan_args.h enumerator.$(OBJEXT): {$(VPATH)}internal/special_consts.h enumerator.$(OBJEXT): {$(VPATH)}internal/static_assert.h enumerator.$(OBJEXT): {$(VPATH)}internal/stdalign.h enumerator.$(OBJEXT): {$(VPATH)}internal/stdbool.h -enumerator.$(OBJEXT): {$(VPATH)}internal/stdckdint.h enumerator.$(OBJEXT): {$(VPATH)}internal/symbol.h enumerator.$(OBJEXT): {$(VPATH)}internal/value.h enumerator.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -6527,22 +6105,18 @@ 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)}rubyparser.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_debug.h enumerator.$(OBJEXT): {$(VPATH)}vm_opts.h -enumerator.$(OBJEXT): {$(VPATH)}vm_sync.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 error.$(OBJEXT): $(CCAN_DIR)/str/str.h error.$(OBJEXT): $(hdrdir)/ruby/ruby.h -error.$(OBJEXT): $(hdrdir)/ruby/version.h error.$(OBJEXT): $(top_srcdir)/internal/array.h error.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h error.$(OBJEXT): $(top_srcdir)/internal/class.h @@ -6555,8 +6129,6 @@ error.$(OBJEXT): $(top_srcdir)/internal/imemo.h error.$(OBJEXT): $(top_srcdir)/internal/io.h error.$(OBJEXT): $(top_srcdir)/internal/load.h error.$(OBJEXT): $(top_srcdir)/internal/object.h -error.$(OBJEXT): $(top_srcdir)/internal/process.h -error.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h error.$(OBJEXT): $(top_srcdir)/internal/serial.h error.$(OBJEXT): $(top_srcdir)/internal/static_assert.h error.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -6579,7 +6151,6 @@ error.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h error.$(OBJEXT): {$(VPATH)}builtin.h error.$(OBJEXT): {$(VPATH)}config.h error.$(OBJEXT): {$(VPATH)}constant.h -error.$(OBJEXT): {$(VPATH)}debug_counter.h error.$(OBJEXT): {$(VPATH)}defines.h error.$(OBJEXT): {$(VPATH)}encoding.h error.$(OBJEXT): {$(VPATH)}error.c @@ -6625,7 +6196,6 @@ error.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h error.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h error.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h error.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -error.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h error.$(OBJEXT): {$(VPATH)}internal/attr/pure.h error.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h error.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -6694,6 +6264,7 @@ error.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h error.$(OBJEXT): {$(VPATH)}internal/intern/error.h error.$(OBJEXT): {$(VPATH)}internal/intern/eval.h error.$(OBJEXT): {$(VPATH)}internal/intern/file.h +error.$(OBJEXT): {$(VPATH)}internal/intern/gc.h error.$(OBJEXT): {$(VPATH)}internal/intern/hash.h error.$(OBJEXT): {$(VPATH)}internal/intern/io.h error.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -6724,12 +6295,12 @@ error.$(OBJEXT): {$(VPATH)}internal/memory.h error.$(OBJEXT): {$(VPATH)}internal/method.h error.$(OBJEXT): {$(VPATH)}internal/module.h error.$(OBJEXT): {$(VPATH)}internal/newobj.h +error.$(OBJEXT): {$(VPATH)}internal/rgengc.h error.$(OBJEXT): {$(VPATH)}internal/scan_args.h error.$(OBJEXT): {$(VPATH)}internal/special_consts.h error.$(OBJEXT): {$(VPATH)}internal/static_assert.h error.$(OBJEXT): {$(VPATH)}internal/stdalign.h error.$(OBJEXT): {$(VPATH)}internal/stdbool.h -error.$(OBJEXT): {$(VPATH)}internal/stdckdint.h error.$(OBJEXT): {$(VPATH)}internal/symbol.h error.$(OBJEXT): {$(VPATH)}internal/value.h error.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -6745,26 +6316,20 @@ error.$(OBJEXT): {$(VPATH)}onigmo.h error.$(OBJEXT): {$(VPATH)}oniguruma.h error.$(OBJEXT): {$(VPATH)}ruby_assert.h error.$(OBJEXT): {$(VPATH)}ruby_atomic.h -error.$(OBJEXT): {$(VPATH)}rubyparser.h error.$(OBJEXT): {$(VPATH)}shape.h error.$(OBJEXT): {$(VPATH)}st.h error.$(OBJEXT): {$(VPATH)}subst.h error.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h error.$(OBJEXT): {$(VPATH)}thread_native.h -error.$(OBJEXT): {$(VPATH)}util.h error.$(OBJEXT): {$(VPATH)}vm_core.h -error.$(OBJEXT): {$(VPATH)}vm_debug.h error.$(OBJEXT): {$(VPATH)}vm_opts.h -error.$(OBJEXT): {$(VPATH)}vm_sync.h error.$(OBJEXT): {$(VPATH)}warning.rbinc -error.$(OBJEXT): {$(VPATH)}yjit.h eval.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h eval.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h eval.$(OBJEXT): $(CCAN_DIR)/list/list.h eval.$(OBJEXT): $(CCAN_DIR)/str/str.h eval.$(OBJEXT): $(hdrdir)/ruby.h eval.$(OBJEXT): $(hdrdir)/ruby/ruby.h -eval.$(OBJEXT): $(hdrdir)/ruby/version.h eval.$(OBJEXT): $(top_srcdir)/internal/array.h eval.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h eval.$(OBJEXT): $(top_srcdir)/internal/class.h @@ -6778,7 +6343,6 @@ eval.$(OBJEXT): $(top_srcdir)/internal/imemo.h eval.$(OBJEXT): $(top_srcdir)/internal/inits.h eval.$(OBJEXT): $(top_srcdir)/internal/io.h eval.$(OBJEXT): $(top_srcdir)/internal/object.h -eval.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h eval.$(OBJEXT): $(top_srcdir)/internal/serial.h eval.$(OBJEXT): $(top_srcdir)/internal/static_assert.h eval.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -6786,26 +6350,6 @@ eval.$(OBJEXT): $(top_srcdir)/internal/thread.h eval.$(OBJEXT): $(top_srcdir)/internal/variable.h eval.$(OBJEXT): $(top_srcdir)/internal/vm.h eval.$(OBJEXT): $(top_srcdir)/internal/warnings.h -eval.$(OBJEXT): $(top_srcdir)/prism/defines.h -eval.$(OBJEXT): $(top_srcdir)/prism/encoding.h -eval.$(OBJEXT): $(top_srcdir)/prism/node.h -eval.$(OBJEXT): $(top_srcdir)/prism/options.h -eval.$(OBJEXT): $(top_srcdir)/prism/pack.h -eval.$(OBJEXT): $(top_srcdir)/prism/parser.h -eval.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -eval.$(OBJEXT): $(top_srcdir)/prism/prism.h -eval.$(OBJEXT): $(top_srcdir)/prism/regexp.h -eval.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -eval.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h eval.$(OBJEXT): {$(VPATH)}assert.h eval.$(OBJEXT): {$(VPATH)}atomic.h eval.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -6827,6 +6371,7 @@ eval.$(OBJEXT): {$(VPATH)}eval_error.c eval.$(OBJEXT): {$(VPATH)}eval_intern.h eval.$(OBJEXT): {$(VPATH)}eval_jump.c eval.$(OBJEXT): {$(VPATH)}fiber/scheduler.h +eval.$(OBJEXT): {$(VPATH)}gc.h eval.$(OBJEXT): {$(VPATH)}id.h eval.$(OBJEXT): {$(VPATH)}id_table.h eval.$(OBJEXT): {$(VPATH)}intern.h @@ -6869,7 +6414,6 @@ eval.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h eval.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h eval.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h eval.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -eval.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h eval.$(OBJEXT): {$(VPATH)}internal/attr/pure.h eval.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h eval.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -6938,6 +6482,7 @@ eval.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h eval.$(OBJEXT): {$(VPATH)}internal/intern/error.h eval.$(OBJEXT): {$(VPATH)}internal/intern/eval.h eval.$(OBJEXT): {$(VPATH)}internal/intern/file.h +eval.$(OBJEXT): {$(VPATH)}internal/intern/gc.h eval.$(OBJEXT): {$(VPATH)}internal/intern/hash.h eval.$(OBJEXT): {$(VPATH)}internal/intern/io.h eval.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -6968,12 +6513,12 @@ eval.$(OBJEXT): {$(VPATH)}internal/memory.h eval.$(OBJEXT): {$(VPATH)}internal/method.h eval.$(OBJEXT): {$(VPATH)}internal/module.h eval.$(OBJEXT): {$(VPATH)}internal/newobj.h +eval.$(OBJEXT): {$(VPATH)}internal/rgengc.h eval.$(OBJEXT): {$(VPATH)}internal/scan_args.h eval.$(OBJEXT): {$(VPATH)}internal/special_consts.h eval.$(OBJEXT): {$(VPATH)}internal/static_assert.h eval.$(OBJEXT): {$(VPATH)}internal/stdalign.h eval.$(OBJEXT): {$(VPATH)}internal/stdbool.h -eval.$(OBJEXT): {$(VPATH)}internal/stdckdint.h eval.$(OBJEXT): {$(VPATH)}internal/symbol.h eval.$(OBJEXT): {$(VPATH)}internal/value.h eval.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -6984,22 +6529,17 @@ eval.$(OBJEXT): {$(VPATH)}io.h eval.$(OBJEXT): {$(VPATH)}iseq.h eval.$(OBJEXT): {$(VPATH)}method.h eval.$(OBJEXT): {$(VPATH)}missing.h +eval.$(OBJEXT): {$(VPATH)}mjit.h eval.$(OBJEXT): {$(VPATH)}node.h eval.$(OBJEXT): {$(VPATH)}onigmo.h eval.$(OBJEXT): {$(VPATH)}oniguruma.h -eval.$(OBJEXT): {$(VPATH)}prism/ast.h -eval.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -eval.$(OBJEXT): {$(VPATH)}prism/version.h -eval.$(OBJEXT): {$(VPATH)}prism_compile.h eval.$(OBJEXT): {$(VPATH)}probes.dmyh eval.$(OBJEXT): {$(VPATH)}probes.h eval.$(OBJEXT): {$(VPATH)}probes_helper.h eval.$(OBJEXT): {$(VPATH)}ractor.h eval.$(OBJEXT): {$(VPATH)}ractor_core.h -eval.$(OBJEXT): {$(VPATH)}rjit.h eval.$(OBJEXT): {$(VPATH)}ruby_assert.h eval.$(OBJEXT): {$(VPATH)}ruby_atomic.h -eval.$(OBJEXT): {$(VPATH)}rubyparser.h eval.$(OBJEXT): {$(VPATH)}shape.h eval.$(OBJEXT): {$(VPATH)}st.h eval.$(OBJEXT): {$(VPATH)}subst.h @@ -7009,7 +6549,6 @@ eval.$(OBJEXT): {$(VPATH)}vm.h eval.$(OBJEXT): {$(VPATH)}vm_core.h eval.$(OBJEXT): {$(VPATH)}vm_debug.h eval.$(OBJEXT): {$(VPATH)}vm_opts.h -eval.$(OBJEXT): {$(VPATH)}vm_sync.h explicit_bzero.$(OBJEXT): {$(VPATH)}config.h explicit_bzero.$(OBJEXT): {$(VPATH)}explicit_bzero.c explicit_bzero.$(OBJEXT): {$(VPATH)}internal/attr/format.h @@ -7025,12 +6564,7 @@ explicit_bzero.$(OBJEXT): {$(VPATH)}internal/config.h explicit_bzero.$(OBJEXT): {$(VPATH)}internal/dllexport.h explicit_bzero.$(OBJEXT): {$(VPATH)}internal/has/attribute.h explicit_bzero.$(OBJEXT): {$(VPATH)}missing.h -file.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -file.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -file.$(OBJEXT): $(CCAN_DIR)/list/list.h -file.$(OBJEXT): $(CCAN_DIR)/str/str.h file.$(OBJEXT): $(hdrdir)/ruby/ruby.h -file.$(OBJEXT): $(hdrdir)/ruby/version.h file.$(OBJEXT): $(top_srcdir)/internal/array.h file.$(OBJEXT): $(top_srcdir)/internal/class.h file.$(OBJEXT): $(top_srcdir)/internal/compilers.h @@ -7109,7 +6643,6 @@ file.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h file.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h file.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h file.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -file.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h file.$(OBJEXT): {$(VPATH)}internal/attr/pure.h file.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h file.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -7178,6 +6711,7 @@ file.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h file.$(OBJEXT): {$(VPATH)}internal/intern/error.h file.$(OBJEXT): {$(VPATH)}internal/intern/eval.h file.$(OBJEXT): {$(VPATH)}internal/intern/file.h +file.$(OBJEXT): {$(VPATH)}internal/intern/gc.h file.$(OBJEXT): {$(VPATH)}internal/intern/hash.h file.$(OBJEXT): {$(VPATH)}internal/intern/io.h file.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -7208,12 +6742,12 @@ file.$(OBJEXT): {$(VPATH)}internal/memory.h file.$(OBJEXT): {$(VPATH)}internal/method.h file.$(OBJEXT): {$(VPATH)}internal/module.h file.$(OBJEXT): {$(VPATH)}internal/newobj.h +file.$(OBJEXT): {$(VPATH)}internal/rgengc.h file.$(OBJEXT): {$(VPATH)}internal/scan_args.h file.$(OBJEXT): {$(VPATH)}internal/special_consts.h file.$(OBJEXT): {$(VPATH)}internal/static_assert.h file.$(OBJEXT): {$(VPATH)}internal/stdalign.h file.$(OBJEXT): {$(VPATH)}internal/stdbool.h -file.$(OBJEXT): {$(VPATH)}internal/stdckdint.h file.$(OBJEXT): {$(VPATH)}internal/symbol.h file.$(OBJEXT): {$(VPATH)}internal/value.h file.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -7228,7 +6762,6 @@ file.$(OBJEXT): {$(VPATH)}shape.h file.$(OBJEXT): {$(VPATH)}st.h file.$(OBJEXT): {$(VPATH)}subst.h file.$(OBJEXT): {$(VPATH)}thread.h -file.$(OBJEXT): {$(VPATH)}thread_native.h file.$(OBJEXT): {$(VPATH)}util.h gc.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h gc.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h @@ -7236,16 +6769,11 @@ gc.$(OBJEXT): $(CCAN_DIR)/list/list.h gc.$(OBJEXT): $(CCAN_DIR)/str/str.h gc.$(OBJEXT): $(hdrdir)/ruby.h gc.$(OBJEXT): $(hdrdir)/ruby/ruby.h -gc.$(OBJEXT): $(hdrdir)/ruby/version.h -gc.$(OBJEXT): $(top_srcdir)/gc/default.c -gc.$(OBJEXT): $(top_srcdir)/gc/gc.h -gc.$(OBJEXT): $(top_srcdir)/gc/gc_impl.h gc.$(OBJEXT): $(top_srcdir)/internal/array.h gc.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h gc.$(OBJEXT): $(top_srcdir)/internal/bignum.h gc.$(OBJEXT): $(top_srcdir)/internal/bits.h gc.$(OBJEXT): $(top_srcdir)/internal/class.h -gc.$(OBJEXT): $(top_srcdir)/internal/compile.h gc.$(OBJEXT): $(top_srcdir)/internal/compilers.h gc.$(OBJEXT): $(top_srcdir)/internal/complex.h gc.$(OBJEXT): $(top_srcdir)/internal/cont.h @@ -7270,26 +6798,6 @@ gc.$(OBJEXT): $(top_srcdir)/internal/thread.h gc.$(OBJEXT): $(top_srcdir)/internal/variable.h gc.$(OBJEXT): $(top_srcdir)/internal/vm.h gc.$(OBJEXT): $(top_srcdir)/internal/warnings.h -gc.$(OBJEXT): $(top_srcdir)/prism/defines.h -gc.$(OBJEXT): $(top_srcdir)/prism/encoding.h -gc.$(OBJEXT): $(top_srcdir)/prism/node.h -gc.$(OBJEXT): $(top_srcdir)/prism/options.h -gc.$(OBJEXT): $(top_srcdir)/prism/pack.h -gc.$(OBJEXT): $(top_srcdir)/prism/parser.h -gc.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -gc.$(OBJEXT): $(top_srcdir)/prism/prism.h -gc.$(OBJEXT): $(top_srcdir)/prism/regexp.h -gc.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -gc.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h gc.$(OBJEXT): {$(VPATH)}assert.h gc.$(OBJEXT): {$(VPATH)}atomic.h gc.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -7304,13 +6812,13 @@ gc.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h gc.$(OBJEXT): {$(VPATH)}builtin.h gc.$(OBJEXT): {$(VPATH)}config.h gc.$(OBJEXT): {$(VPATH)}constant.h -gc.$(OBJEXT): {$(VPATH)}darray.h gc.$(OBJEXT): {$(VPATH)}debug.h gc.$(OBJEXT): {$(VPATH)}debug_counter.h gc.$(OBJEXT): {$(VPATH)}defines.h gc.$(OBJEXT): {$(VPATH)}encoding.h gc.$(OBJEXT): {$(VPATH)}eval_intern.h gc.$(OBJEXT): {$(VPATH)}gc.c +gc.$(OBJEXT): {$(VPATH)}gc.h gc.$(OBJEXT): {$(VPATH)}gc.rbinc gc.$(OBJEXT): {$(VPATH)}id.h gc.$(OBJEXT): {$(VPATH)}id_table.h @@ -7354,7 +6862,6 @@ gc.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h gc.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h gc.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h gc.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -gc.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h gc.$(OBJEXT): {$(VPATH)}internal/attr/pure.h gc.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h gc.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -7424,6 +6931,7 @@ gc.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h gc.$(OBJEXT): {$(VPATH)}internal/intern/error.h gc.$(OBJEXT): {$(VPATH)}internal/intern/eval.h gc.$(OBJEXT): {$(VPATH)}internal/intern/file.h +gc.$(OBJEXT): {$(VPATH)}internal/intern/gc.h gc.$(OBJEXT): {$(VPATH)}internal/intern/hash.h gc.$(OBJEXT): {$(VPATH)}internal/intern/io.h gc.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -7454,12 +6962,12 @@ gc.$(OBJEXT): {$(VPATH)}internal/memory.h gc.$(OBJEXT): {$(VPATH)}internal/method.h gc.$(OBJEXT): {$(VPATH)}internal/module.h gc.$(OBJEXT): {$(VPATH)}internal/newobj.h +gc.$(OBJEXT): {$(VPATH)}internal/rgengc.h gc.$(OBJEXT): {$(VPATH)}internal/scan_args.h gc.$(OBJEXT): {$(VPATH)}internal/special_consts.h gc.$(OBJEXT): {$(VPATH)}internal/static_assert.h gc.$(OBJEXT): {$(VPATH)}internal/stdalign.h gc.$(OBJEXT): {$(VPATH)}internal/stdbool.h -gc.$(OBJEXT): {$(VPATH)}internal/stdckdint.h gc.$(OBJEXT): {$(VPATH)}internal/symbol.h gc.$(OBJEXT): {$(VPATH)}internal/value.h gc.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -7470,13 +6978,10 @@ gc.$(OBJEXT): {$(VPATH)}io.h gc.$(OBJEXT): {$(VPATH)}iseq.h gc.$(OBJEXT): {$(VPATH)}method.h gc.$(OBJEXT): {$(VPATH)}missing.h +gc.$(OBJEXT): {$(VPATH)}mjit.h gc.$(OBJEXT): {$(VPATH)}node.h gc.$(OBJEXT): {$(VPATH)}onigmo.h gc.$(OBJEXT): {$(VPATH)}oniguruma.h -gc.$(OBJEXT): {$(VPATH)}prism/ast.h -gc.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -gc.$(OBJEXT): {$(VPATH)}prism/version.h -gc.$(OBJEXT): {$(VPATH)}prism_compile.h gc.$(OBJEXT): {$(VPATH)}probes.dmyh gc.$(OBJEXT): {$(VPATH)}probes.h gc.$(OBJEXT): {$(VPATH)}ractor.h @@ -7485,10 +6990,8 @@ gc.$(OBJEXT): {$(VPATH)}re.h gc.$(OBJEXT): {$(VPATH)}regenc.h gc.$(OBJEXT): {$(VPATH)}regex.h gc.$(OBJEXT): {$(VPATH)}regint.h -gc.$(OBJEXT): {$(VPATH)}rjit.h gc.$(OBJEXT): {$(VPATH)}ruby_assert.h gc.$(OBJEXT): {$(VPATH)}ruby_atomic.h -gc.$(OBJEXT): {$(VPATH)}rubyparser.h gc.$(OBJEXT): {$(VPATH)}shape.h gc.$(OBJEXT): {$(VPATH)}st.h gc.$(OBJEXT): {$(VPATH)}subst.h @@ -7496,14 +6999,13 @@ gc.$(OBJEXT): {$(VPATH)}symbol.h gc.$(OBJEXT): {$(VPATH)}thread.h gc.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h gc.$(OBJEXT): {$(VPATH)}thread_native.h +gc.$(OBJEXT): {$(VPATH)}transient_heap.h gc.$(OBJEXT): {$(VPATH)}util.h -gc.$(OBJEXT): {$(VPATH)}vm.h gc.$(OBJEXT): {$(VPATH)}vm_callinfo.h gc.$(OBJEXT): {$(VPATH)}vm_core.h gc.$(OBJEXT): {$(VPATH)}vm_debug.h gc.$(OBJEXT): {$(VPATH)}vm_opts.h gc.$(OBJEXT): {$(VPATH)}vm_sync.h -gc.$(OBJEXT): {$(VPATH)}yjit.h goruby.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h goruby.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h goruby.$(OBJEXT): $(CCAN_DIR)/list/list.h @@ -7512,43 +7014,14 @@ goruby.$(OBJEXT): $(hdrdir)/ruby.h goruby.$(OBJEXT): $(hdrdir)/ruby/ruby.h goruby.$(OBJEXT): $(top_srcdir)/internal/array.h goruby.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h -goruby.$(OBJEXT): $(top_srcdir)/internal/bignum.h -goruby.$(OBJEXT): $(top_srcdir)/internal/bits.h goruby.$(OBJEXT): $(top_srcdir)/internal/compilers.h -goruby.$(OBJEXT): $(top_srcdir)/internal/complex.h -goruby.$(OBJEXT): $(top_srcdir)/internal/fixnum.h goruby.$(OBJEXT): $(top_srcdir)/internal/gc.h goruby.$(OBJEXT): $(top_srcdir)/internal/imemo.h -goruby.$(OBJEXT): $(top_srcdir)/internal/numeric.h -goruby.$(OBJEXT): $(top_srcdir)/internal/parse.h -goruby.$(OBJEXT): $(top_srcdir)/internal/rational.h -goruby.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h -goruby.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h goruby.$(OBJEXT): $(top_srcdir)/internal/serial.h goruby.$(OBJEXT): $(top_srcdir)/internal/static_assert.h goruby.$(OBJEXT): $(top_srcdir)/internal/variable.h goruby.$(OBJEXT): $(top_srcdir)/internal/vm.h goruby.$(OBJEXT): $(top_srcdir)/internal/warnings.h -goruby.$(OBJEXT): $(top_srcdir)/prism/defines.h -goruby.$(OBJEXT): $(top_srcdir)/prism/encoding.h -goruby.$(OBJEXT): $(top_srcdir)/prism/node.h -goruby.$(OBJEXT): $(top_srcdir)/prism/options.h -goruby.$(OBJEXT): $(top_srcdir)/prism/pack.h -goruby.$(OBJEXT): $(top_srcdir)/prism/parser.h -goruby.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -goruby.$(OBJEXT): $(top_srcdir)/prism/prism.h -goruby.$(OBJEXT): $(top_srcdir)/prism/regexp.h -goruby.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -goruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h goruby.$(OBJEXT): {$(VPATH)}assert.h goruby.$(OBJEXT): {$(VPATH)}atomic.h goruby.$(OBJEXT): {$(VPATH)}backward.h @@ -7564,8 +7037,7 @@ goruby.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h goruby.$(OBJEXT): {$(VPATH)}config.h goruby.$(OBJEXT): {$(VPATH)}constant.h goruby.$(OBJEXT): {$(VPATH)}defines.h -goruby.$(OBJEXT): {$(VPATH)}encoding.h -goruby.$(OBJEXT): {$(VPATH)}golf_prelude.rbbin +goruby.$(OBJEXT): {$(VPATH)}golf_prelude.c goruby.$(OBJEXT): {$(VPATH)}goruby.c goruby.$(OBJEXT): {$(VPATH)}id.h goruby.$(OBJEXT): {$(VPATH)}id_table.h @@ -7608,8 +7080,8 @@ 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/packed_struct.h goruby.$(OBJEXT): {$(VPATH)}internal/attr/pure.h goruby.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h goruby.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -7642,15 +7114,6 @@ goruby.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h goruby.$(OBJEXT): {$(VPATH)}internal/ctype.h goruby.$(OBJEXT): {$(VPATH)}internal/dllexport.h goruby.$(OBJEXT): {$(VPATH)}internal/dosish.h -goruby.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -goruby.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -goruby.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -goruby.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -goruby.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -goruby.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -goruby.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -goruby.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -goruby.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h goruby.$(OBJEXT): {$(VPATH)}internal/error.h goruby.$(OBJEXT): {$(VPATH)}internal/eval.h goruby.$(OBJEXT): {$(VPATH)}internal/event.h @@ -7678,6 +7141,7 @@ goruby.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h goruby.$(OBJEXT): {$(VPATH)}internal/intern/error.h goruby.$(OBJEXT): {$(VPATH)}internal/intern/eval.h goruby.$(OBJEXT): {$(VPATH)}internal/intern/file.h +goruby.$(OBJEXT): {$(VPATH)}internal/intern/gc.h goruby.$(OBJEXT): {$(VPATH)}internal/intern/hash.h goruby.$(OBJEXT): {$(VPATH)}internal/intern/io.h goruby.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -7708,12 +7172,12 @@ goruby.$(OBJEXT): {$(VPATH)}internal/memory.h goruby.$(OBJEXT): {$(VPATH)}internal/method.h goruby.$(OBJEXT): {$(VPATH)}internal/module.h goruby.$(OBJEXT): {$(VPATH)}internal/newobj.h +goruby.$(OBJEXT): {$(VPATH)}internal/rgengc.h goruby.$(OBJEXT): {$(VPATH)}internal/scan_args.h goruby.$(OBJEXT): {$(VPATH)}internal/special_consts.h goruby.$(OBJEXT): {$(VPATH)}internal/static_assert.h goruby.$(OBJEXT): {$(VPATH)}internal/stdalign.h goruby.$(OBJEXT): {$(VPATH)}internal/stdbool.h -goruby.$(OBJEXT): {$(VPATH)}internal/stdckdint.h goruby.$(OBJEXT): {$(VPATH)}internal/symbol.h goruby.$(OBJEXT): {$(VPATH)}internal/value.h goruby.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -7725,15 +7189,8 @@ goruby.$(OBJEXT): {$(VPATH)}main.c goruby.$(OBJEXT): {$(VPATH)}method.h goruby.$(OBJEXT): {$(VPATH)}missing.h goruby.$(OBJEXT): {$(VPATH)}node.h -goruby.$(OBJEXT): {$(VPATH)}onigmo.h -goruby.$(OBJEXT): {$(VPATH)}oniguruma.h -goruby.$(OBJEXT): {$(VPATH)}prism/ast.h -goruby.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -goruby.$(OBJEXT): {$(VPATH)}prism/version.h -goruby.$(OBJEXT): {$(VPATH)}prism_compile.h goruby.$(OBJEXT): {$(VPATH)}ruby_assert.h goruby.$(OBJEXT): {$(VPATH)}ruby_atomic.h -goruby.$(OBJEXT): {$(VPATH)}rubyparser.h goruby.$(OBJEXT): {$(VPATH)}shape.h goruby.$(OBJEXT): {$(VPATH)}st.h goruby.$(OBJEXT): {$(VPATH)}subst.h @@ -7747,7 +7204,6 @@ hash.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h hash.$(OBJEXT): $(CCAN_DIR)/list/list.h hash.$(OBJEXT): $(CCAN_DIR)/str/str.h hash.$(OBJEXT): $(hdrdir)/ruby/ruby.h -hash.$(OBJEXT): $(hdrdir)/ruby/version.h hash.$(OBJEXT): $(top_srcdir)/internal/array.h hash.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h hash.$(OBJEXT): $(top_srcdir)/internal/bignum.h @@ -7761,9 +7217,7 @@ hash.$(OBJEXT): $(top_srcdir)/internal/hash.h hash.$(OBJEXT): $(top_srcdir)/internal/imemo.h hash.$(OBJEXT): $(top_srcdir)/internal/object.h hash.$(OBJEXT): $(top_srcdir)/internal/proc.h -hash.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h hash.$(OBJEXT): $(top_srcdir)/internal/serial.h -hash.$(OBJEXT): $(top_srcdir)/internal/st.h hash.$(OBJEXT): $(top_srcdir)/internal/static_assert.h hash.$(OBJEXT): $(top_srcdir)/internal/string.h hash.$(OBJEXT): $(top_srcdir)/internal/symbol.h @@ -7772,26 +7226,6 @@ hash.$(OBJEXT): $(top_srcdir)/internal/time.h hash.$(OBJEXT): $(top_srcdir)/internal/variable.h hash.$(OBJEXT): $(top_srcdir)/internal/vm.h hash.$(OBJEXT): $(top_srcdir)/internal/warnings.h -hash.$(OBJEXT): $(top_srcdir)/prism/defines.h -hash.$(OBJEXT): $(top_srcdir)/prism/encoding.h -hash.$(OBJEXT): $(top_srcdir)/prism/node.h -hash.$(OBJEXT): $(top_srcdir)/prism/options.h -hash.$(OBJEXT): $(top_srcdir)/prism/pack.h -hash.$(OBJEXT): $(top_srcdir)/prism/parser.h -hash.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -hash.$(OBJEXT): $(top_srcdir)/prism/prism.h -hash.$(OBJEXT): $(top_srcdir)/prism/regexp.h -hash.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -hash.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h hash.$(OBJEXT): {$(VPATH)}assert.h hash.$(OBJEXT): {$(VPATH)}atomic.h hash.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -7803,14 +7237,12 @@ hash.$(OBJEXT): {$(VPATH)}backward/2/limits.h hash.$(OBJEXT): {$(VPATH)}backward/2/long_long.h hash.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h hash.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -hash.$(OBJEXT): {$(VPATH)}builtin.h hash.$(OBJEXT): {$(VPATH)}config.h hash.$(OBJEXT): {$(VPATH)}constant.h hash.$(OBJEXT): {$(VPATH)}debug_counter.h hash.$(OBJEXT): {$(VPATH)}defines.h hash.$(OBJEXT): {$(VPATH)}encoding.h hash.$(OBJEXT): {$(VPATH)}hash.c -hash.$(OBJEXT): {$(VPATH)}hash.rbinc hash.$(OBJEXT): {$(VPATH)}id.h hash.$(OBJEXT): {$(VPATH)}id_table.h hash.$(OBJEXT): {$(VPATH)}intern.h @@ -7853,7 +7285,6 @@ hash.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h hash.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h hash.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h hash.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -hash.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h hash.$(OBJEXT): {$(VPATH)}internal/attr/pure.h hash.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h hash.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -7922,6 +7353,7 @@ hash.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h hash.$(OBJEXT): {$(VPATH)}internal/intern/error.h hash.$(OBJEXT): {$(VPATH)}internal/intern/eval.h hash.$(OBJEXT): {$(VPATH)}internal/intern/file.h +hash.$(OBJEXT): {$(VPATH)}internal/intern/gc.h hash.$(OBJEXT): {$(VPATH)}internal/intern/hash.h hash.$(OBJEXT): {$(VPATH)}internal/intern/io.h hash.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -7952,13 +7384,12 @@ hash.$(OBJEXT): {$(VPATH)}internal/memory.h hash.$(OBJEXT): {$(VPATH)}internal/method.h hash.$(OBJEXT): {$(VPATH)}internal/module.h hash.$(OBJEXT): {$(VPATH)}internal/newobj.h +hash.$(OBJEXT): {$(VPATH)}internal/rgengc.h hash.$(OBJEXT): {$(VPATH)}internal/scan_args.h hash.$(OBJEXT): {$(VPATH)}internal/special_consts.h -hash.$(OBJEXT): {$(VPATH)}internal/st.h hash.$(OBJEXT): {$(VPATH)}internal/static_assert.h hash.$(OBJEXT): {$(VPATH)}internal/stdalign.h hash.$(OBJEXT): {$(VPATH)}internal/stdbool.h -hash.$(OBJEXT): {$(VPATH)}internal/stdckdint.h hash.$(OBJEXT): {$(VPATH)}internal/symbol.h hash.$(OBJEXT): {$(VPATH)}internal/value.h hash.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -7971,232 +7402,23 @@ hash.$(OBJEXT): {$(VPATH)}missing.h hash.$(OBJEXT): {$(VPATH)}node.h hash.$(OBJEXT): {$(VPATH)}onigmo.h hash.$(OBJEXT): {$(VPATH)}oniguruma.h -hash.$(OBJEXT): {$(VPATH)}prism/ast.h -hash.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -hash.$(OBJEXT): {$(VPATH)}prism/version.h -hash.$(OBJEXT): {$(VPATH)}prism_compile.h hash.$(OBJEXT): {$(VPATH)}probes.dmyh hash.$(OBJEXT): {$(VPATH)}probes.h hash.$(OBJEXT): {$(VPATH)}ractor.h hash.$(OBJEXT): {$(VPATH)}ruby_assert.h hash.$(OBJEXT): {$(VPATH)}ruby_atomic.h -hash.$(OBJEXT): {$(VPATH)}rubyparser.h hash.$(OBJEXT): {$(VPATH)}shape.h hash.$(OBJEXT): {$(VPATH)}st.h hash.$(OBJEXT): {$(VPATH)}subst.h hash.$(OBJEXT): {$(VPATH)}symbol.h hash.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h hash.$(OBJEXT): {$(VPATH)}thread_native.h +hash.$(OBJEXT): {$(VPATH)}transient_heap.h hash.$(OBJEXT): {$(VPATH)}util.h hash.$(OBJEXT): {$(VPATH)}vm_core.h hash.$(OBJEXT): {$(VPATH)}vm_debug.h hash.$(OBJEXT): {$(VPATH)}vm_opts.h hash.$(OBJEXT): {$(VPATH)}vm_sync.h -imemo.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -imemo.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -imemo.$(OBJEXT): $(CCAN_DIR)/list/list.h -imemo.$(OBJEXT): $(CCAN_DIR)/str/str.h -imemo.$(OBJEXT): $(hdrdir)/ruby/ruby.h -imemo.$(OBJEXT): $(top_srcdir)/internal/array.h -imemo.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h -imemo.$(OBJEXT): $(top_srcdir)/internal/class.h -imemo.$(OBJEXT): $(top_srcdir)/internal/compilers.h -imemo.$(OBJEXT): $(top_srcdir)/internal/gc.h -imemo.$(OBJEXT): $(top_srcdir)/internal/imemo.h -imemo.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h -imemo.$(OBJEXT): $(top_srcdir)/internal/serial.h -imemo.$(OBJEXT): $(top_srcdir)/internal/static_assert.h -imemo.$(OBJEXT): $(top_srcdir)/internal/variable.h -imemo.$(OBJEXT): $(top_srcdir)/internal/vm.h -imemo.$(OBJEXT): $(top_srcdir)/internal/warnings.h -imemo.$(OBJEXT): {$(VPATH)}assert.h -imemo.$(OBJEXT): {$(VPATH)}atomic.h -imemo.$(OBJEXT): {$(VPATH)}backward/2/assume.h -imemo.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -imemo.$(OBJEXT): {$(VPATH)}backward/2/bool.h -imemo.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h -imemo.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h -imemo.$(OBJEXT): {$(VPATH)}backward/2/limits.h -imemo.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -imemo.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -imemo.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -imemo.$(OBJEXT): {$(VPATH)}config.h -imemo.$(OBJEXT): {$(VPATH)}constant.h -imemo.$(OBJEXT): {$(VPATH)}debug_counter.h -imemo.$(OBJEXT): {$(VPATH)}defines.h -imemo.$(OBJEXT): {$(VPATH)}encoding.h -imemo.$(OBJEXT): {$(VPATH)}id.h -imemo.$(OBJEXT): {$(VPATH)}id_table.h -imemo.$(OBJEXT): {$(VPATH)}imemo.c -imemo.$(OBJEXT): {$(VPATH)}intern.h -imemo.$(OBJEXT): {$(VPATH)}internal.h -imemo.$(OBJEXT): {$(VPATH)}internal/abi.h -imemo.$(OBJEXT): {$(VPATH)}internal/anyargs.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h -imemo.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h -imemo.$(OBJEXT): {$(VPATH)}internal/assume.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/const.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/error.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/format.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -imemo.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h -imemo.$(OBJEXT): {$(VPATH)}internal/cast.h -imemo.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -imemo.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -imemo.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -imemo.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -imemo.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -imemo.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -imemo.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -imemo.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -imemo.$(OBJEXT): {$(VPATH)}internal/config.h -imemo.$(OBJEXT): {$(VPATH)}internal/constant_p.h -imemo.$(OBJEXT): {$(VPATH)}internal/core.h -imemo.$(OBJEXT): {$(VPATH)}internal/core/rarray.h -imemo.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h -imemo.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h -imemo.$(OBJEXT): {$(VPATH)}internal/core/rclass.h -imemo.$(OBJEXT): {$(VPATH)}internal/core/rdata.h -imemo.$(OBJEXT): {$(VPATH)}internal/core/rfile.h -imemo.$(OBJEXT): {$(VPATH)}internal/core/rhash.h -imemo.$(OBJEXT): {$(VPATH)}internal/core/robject.h -imemo.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h -imemo.$(OBJEXT): {$(VPATH)}internal/core/rstring.h -imemo.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h -imemo.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h -imemo.$(OBJEXT): {$(VPATH)}internal/ctype.h -imemo.$(OBJEXT): {$(VPATH)}internal/dllexport.h -imemo.$(OBJEXT): {$(VPATH)}internal/dosish.h -imemo.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -imemo.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -imemo.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -imemo.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -imemo.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -imemo.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -imemo.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -imemo.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -imemo.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h -imemo.$(OBJEXT): {$(VPATH)}internal/error.h -imemo.$(OBJEXT): {$(VPATH)}internal/eval.h -imemo.$(OBJEXT): {$(VPATH)}internal/event.h -imemo.$(OBJEXT): {$(VPATH)}internal/fl_type.h -imemo.$(OBJEXT): {$(VPATH)}internal/gc.h -imemo.$(OBJEXT): {$(VPATH)}internal/glob.h -imemo.$(OBJEXT): {$(VPATH)}internal/globals.h -imemo.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -imemo.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -imemo.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -imemo.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -imemo.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -imemo.$(OBJEXT): {$(VPATH)}internal/has/extension.h -imemo.$(OBJEXT): {$(VPATH)}internal/has/feature.h -imemo.$(OBJEXT): {$(VPATH)}internal/has/warning.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/array.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/class.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/compar.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/complex.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/cont.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/dir.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/enum.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/error.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/eval.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/file.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/hash.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/io.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/load.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/object.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/parse.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/proc.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/process.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/random.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/range.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/rational.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/re.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/select.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/signal.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/string.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/struct.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/thread.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/time.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/variable.h -imemo.$(OBJEXT): {$(VPATH)}internal/intern/vm.h -imemo.$(OBJEXT): {$(VPATH)}internal/interpreter.h -imemo.$(OBJEXT): {$(VPATH)}internal/iterator.h -imemo.$(OBJEXT): {$(VPATH)}internal/memory.h -imemo.$(OBJEXT): {$(VPATH)}internal/method.h -imemo.$(OBJEXT): {$(VPATH)}internal/module.h -imemo.$(OBJEXT): {$(VPATH)}internal/newobj.h -imemo.$(OBJEXT): {$(VPATH)}internal/scan_args.h -imemo.$(OBJEXT): {$(VPATH)}internal/special_consts.h -imemo.$(OBJEXT): {$(VPATH)}internal/static_assert.h -imemo.$(OBJEXT): {$(VPATH)}internal/stdalign.h -imemo.$(OBJEXT): {$(VPATH)}internal/stdbool.h -imemo.$(OBJEXT): {$(VPATH)}internal/stdckdint.h -imemo.$(OBJEXT): {$(VPATH)}internal/symbol.h -imemo.$(OBJEXT): {$(VPATH)}internal/value.h -imemo.$(OBJEXT): {$(VPATH)}internal/value_type.h -imemo.$(OBJEXT): {$(VPATH)}internal/variable.h -imemo.$(OBJEXT): {$(VPATH)}internal/warning_push.h -imemo.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -imemo.$(OBJEXT): {$(VPATH)}method.h -imemo.$(OBJEXT): {$(VPATH)}missing.h -imemo.$(OBJEXT): {$(VPATH)}node.h -imemo.$(OBJEXT): {$(VPATH)}onigmo.h -imemo.$(OBJEXT): {$(VPATH)}oniguruma.h -imemo.$(OBJEXT): {$(VPATH)}ruby_assert.h -imemo.$(OBJEXT): {$(VPATH)}ruby_atomic.h -imemo.$(OBJEXT): {$(VPATH)}rubyparser.h -imemo.$(OBJEXT): {$(VPATH)}shape.h -imemo.$(OBJEXT): {$(VPATH)}st.h -imemo.$(OBJEXT): {$(VPATH)}subst.h -imemo.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -imemo.$(OBJEXT): {$(VPATH)}thread_native.h -imemo.$(OBJEXT): {$(VPATH)}vm_callinfo.h -imemo.$(OBJEXT): {$(VPATH)}vm_core.h -imemo.$(OBJEXT): {$(VPATH)}vm_debug.h -imemo.$(OBJEXT): {$(VPATH)}vm_opts.h -imemo.$(OBJEXT): {$(VPATH)}vm_sync.h inits.$(OBJEXT): $(hdrdir)/ruby.h inits.$(OBJEXT): $(hdrdir)/ruby/ruby.h inits.$(OBJEXT): $(top_srcdir)/internal/compilers.h @@ -8255,7 +7477,6 @@ inits.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h inits.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h inits.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h inits.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -inits.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h inits.$(OBJEXT): {$(VPATH)}internal/attr/pure.h inits.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h inits.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -8315,6 +7536,7 @@ inits.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h inits.$(OBJEXT): {$(VPATH)}internal/intern/error.h inits.$(OBJEXT): {$(VPATH)}internal/intern/eval.h inits.$(OBJEXT): {$(VPATH)}internal/intern/file.h +inits.$(OBJEXT): {$(VPATH)}internal/intern/gc.h inits.$(OBJEXT): {$(VPATH)}internal/intern/hash.h inits.$(OBJEXT): {$(VPATH)}internal/intern/io.h inits.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -8345,12 +7567,12 @@ inits.$(OBJEXT): {$(VPATH)}internal/memory.h inits.$(OBJEXT): {$(VPATH)}internal/method.h inits.$(OBJEXT): {$(VPATH)}internal/module.h inits.$(OBJEXT): {$(VPATH)}internal/newobj.h +inits.$(OBJEXT): {$(VPATH)}internal/rgengc.h inits.$(OBJEXT): {$(VPATH)}internal/scan_args.h inits.$(OBJEXT): {$(VPATH)}internal/special_consts.h inits.$(OBJEXT): {$(VPATH)}internal/static_assert.h inits.$(OBJEXT): {$(VPATH)}internal/stdalign.h inits.$(OBJEXT): {$(VPATH)}internal/stdbool.h -inits.$(OBJEXT): {$(VPATH)}internal/stdckdint.h inits.$(OBJEXT): {$(VPATH)}internal/symbol.h inits.$(OBJEXT): {$(VPATH)}internal/value.h inits.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -8366,7 +7588,6 @@ io.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h io.$(OBJEXT): $(CCAN_DIR)/list/list.h io.$(OBJEXT): $(CCAN_DIR)/str/str.h io.$(OBJEXT): $(hdrdir)/ruby/ruby.h -io.$(OBJEXT): $(hdrdir)/ruby/version.h io.$(OBJEXT): $(top_srcdir)/internal/array.h io.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h io.$(OBJEXT): $(top_srcdir)/internal/bignum.h @@ -8383,7 +7604,6 @@ io.$(OBJEXT): $(top_srcdir)/internal/io.h io.$(OBJEXT): $(top_srcdir)/internal/numeric.h io.$(OBJEXT): $(top_srcdir)/internal/object.h io.$(OBJEXT): $(top_srcdir)/internal/process.h -io.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h io.$(OBJEXT): $(top_srcdir)/internal/serial.h io.$(OBJEXT): $(top_srcdir)/internal/static_assert.h io.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -8406,7 +7626,6 @@ io.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h io.$(OBJEXT): {$(VPATH)}builtin.h io.$(OBJEXT): {$(VPATH)}config.h io.$(OBJEXT): {$(VPATH)}constant.h -io.$(OBJEXT): {$(VPATH)}debug_counter.h io.$(OBJEXT): {$(VPATH)}defines.h io.$(OBJEXT): {$(VPATH)}dln.h io.$(OBJEXT): {$(VPATH)}encindex.h @@ -8454,7 +7673,6 @@ io.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h io.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h io.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h io.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -io.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h io.$(OBJEXT): {$(VPATH)}internal/attr/pure.h io.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h io.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -8523,6 +7741,7 @@ io.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h io.$(OBJEXT): {$(VPATH)}internal/intern/error.h io.$(OBJEXT): {$(VPATH)}internal/intern/eval.h io.$(OBJEXT): {$(VPATH)}internal/intern/file.h +io.$(OBJEXT): {$(VPATH)}internal/intern/gc.h io.$(OBJEXT): {$(VPATH)}internal/intern/hash.h io.$(OBJEXT): {$(VPATH)}internal/intern/io.h io.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -8553,12 +7772,12 @@ io.$(OBJEXT): {$(VPATH)}internal/memory.h io.$(OBJEXT): {$(VPATH)}internal/method.h io.$(OBJEXT): {$(VPATH)}internal/module.h io.$(OBJEXT): {$(VPATH)}internal/newobj.h +io.$(OBJEXT): {$(VPATH)}internal/rgengc.h io.$(OBJEXT): {$(VPATH)}internal/scan_args.h io.$(OBJEXT): {$(VPATH)}internal/special_consts.h io.$(OBJEXT): {$(VPATH)}internal/static_assert.h io.$(OBJEXT): {$(VPATH)}internal/stdalign.h io.$(OBJEXT): {$(VPATH)}internal/stdbool.h -io.$(OBJEXT): {$(VPATH)}internal/stdckdint.h io.$(OBJEXT): {$(VPATH)}internal/symbol.h io.$(OBJEXT): {$(VPATH)}internal/value.h io.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -8577,7 +7796,6 @@ io.$(OBJEXT): {$(VPATH)}oniguruma.h io.$(OBJEXT): {$(VPATH)}ractor.h io.$(OBJEXT): {$(VPATH)}ruby_assert.h io.$(OBJEXT): {$(VPATH)}ruby_atomic.h -io.$(OBJEXT): {$(VPATH)}rubyparser.h io.$(OBJEXT): {$(VPATH)}shape.h io.$(OBJEXT): {$(VPATH)}st.h io.$(OBJEXT): {$(VPATH)}subst.h @@ -8586,22 +7804,14 @@ io.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h io.$(OBJEXT): {$(VPATH)}thread_native.h io.$(OBJEXT): {$(VPATH)}util.h io.$(OBJEXT): {$(VPATH)}vm_core.h -io.$(OBJEXT): {$(VPATH)}vm_debug.h io.$(OBJEXT): {$(VPATH)}vm_opts.h -io.$(OBJEXT): {$(VPATH)}vm_sync.h -io_buffer.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -io_buffer.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -io_buffer.$(OBJEXT): $(CCAN_DIR)/list/list.h -io_buffer.$(OBJEXT): $(CCAN_DIR)/str/str.h io_buffer.$(OBJEXT): $(hdrdir)/ruby/ruby.h -io_buffer.$(OBJEXT): $(hdrdir)/ruby/version.h io_buffer.$(OBJEXT): $(top_srcdir)/internal/array.h io_buffer.$(OBJEXT): $(top_srcdir)/internal/bignum.h io_buffer.$(OBJEXT): $(top_srcdir)/internal/bits.h io_buffer.$(OBJEXT): $(top_srcdir)/internal/compilers.h io_buffer.$(OBJEXT): $(top_srcdir)/internal/error.h io_buffer.$(OBJEXT): $(top_srcdir)/internal/fixnum.h -io_buffer.$(OBJEXT): $(top_srcdir)/internal/io.h io_buffer.$(OBJEXT): $(top_srcdir)/internal/numeric.h io_buffer.$(OBJEXT): $(top_srcdir)/internal/serial.h io_buffer.$(OBJEXT): $(top_srcdir)/internal/static_assert.h @@ -8662,7 +7872,6 @@ io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/pure.h io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h io_buffer.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -8731,6 +7940,7 @@ io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/error.h io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/eval.h io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/file.h +io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/gc.h io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/hash.h io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/io.h io_buffer.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -8761,12 +7971,12 @@ io_buffer.$(OBJEXT): {$(VPATH)}internal/memory.h io_buffer.$(OBJEXT): {$(VPATH)}internal/method.h io_buffer.$(OBJEXT): {$(VPATH)}internal/module.h io_buffer.$(OBJEXT): {$(VPATH)}internal/newobj.h +io_buffer.$(OBJEXT): {$(VPATH)}internal/rgengc.h io_buffer.$(OBJEXT): {$(VPATH)}internal/scan_args.h io_buffer.$(OBJEXT): {$(VPATH)}internal/special_consts.h io_buffer.$(OBJEXT): {$(VPATH)}internal/static_assert.h io_buffer.$(OBJEXT): {$(VPATH)}internal/stdalign.h io_buffer.$(OBJEXT): {$(VPATH)}internal/stdbool.h -io_buffer.$(OBJEXT): {$(VPATH)}internal/stdckdint.h io_buffer.$(OBJEXT): {$(VPATH)}internal/symbol.h io_buffer.$(OBJEXT): {$(VPATH)}internal/value.h io_buffer.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -8781,33 +7991,24 @@ io_buffer.$(OBJEXT): {$(VPATH)}onigmo.h io_buffer.$(OBJEXT): {$(VPATH)}oniguruma.h io_buffer.$(OBJEXT): {$(VPATH)}st.h io_buffer.$(OBJEXT): {$(VPATH)}subst.h -io_buffer.$(OBJEXT): {$(VPATH)}thread_native.h iseq.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h iseq.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h iseq.$(OBJEXT): $(CCAN_DIR)/list/list.h iseq.$(OBJEXT): $(CCAN_DIR)/str/str.h iseq.$(OBJEXT): $(hdrdir)/ruby.h iseq.$(OBJEXT): $(hdrdir)/ruby/ruby.h -iseq.$(OBJEXT): $(hdrdir)/ruby/version.h iseq.$(OBJEXT): $(top_srcdir)/internal/array.h iseq.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h -iseq.$(OBJEXT): $(top_srcdir)/internal/bignum.h iseq.$(OBJEXT): $(top_srcdir)/internal/bits.h iseq.$(OBJEXT): $(top_srcdir)/internal/class.h iseq.$(OBJEXT): $(top_srcdir)/internal/compile.h iseq.$(OBJEXT): $(top_srcdir)/internal/compilers.h -iseq.$(OBJEXT): $(top_srcdir)/internal/complex.h iseq.$(OBJEXT): $(top_srcdir)/internal/error.h iseq.$(OBJEXT): $(top_srcdir)/internal/file.h -iseq.$(OBJEXT): $(top_srcdir)/internal/fixnum.h iseq.$(OBJEXT): $(top_srcdir)/internal/gc.h iseq.$(OBJEXT): $(top_srcdir)/internal/hash.h iseq.$(OBJEXT): $(top_srcdir)/internal/imemo.h -iseq.$(OBJEXT): $(top_srcdir)/internal/io.h -iseq.$(OBJEXT): $(top_srcdir)/internal/numeric.h iseq.$(OBJEXT): $(top_srcdir)/internal/parse.h -iseq.$(OBJEXT): $(top_srcdir)/internal/rational.h -iseq.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h iseq.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h iseq.$(OBJEXT): $(top_srcdir)/internal/serial.h iseq.$(OBJEXT): $(top_srcdir)/internal/static_assert.h @@ -8817,26 +8018,6 @@ iseq.$(OBJEXT): $(top_srcdir)/internal/thread.h iseq.$(OBJEXT): $(top_srcdir)/internal/variable.h iseq.$(OBJEXT): $(top_srcdir)/internal/vm.h iseq.$(OBJEXT): $(top_srcdir)/internal/warnings.h -iseq.$(OBJEXT): $(top_srcdir)/prism/defines.h -iseq.$(OBJEXT): $(top_srcdir)/prism/encoding.h -iseq.$(OBJEXT): $(top_srcdir)/prism/node.h -iseq.$(OBJEXT): $(top_srcdir)/prism/options.h -iseq.$(OBJEXT): $(top_srcdir)/prism/pack.h -iseq.$(OBJEXT): $(top_srcdir)/prism/parser.h -iseq.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -iseq.$(OBJEXT): $(top_srcdir)/prism/prism.h -iseq.$(OBJEXT): $(top_srcdir)/prism/regexp.h -iseq.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -iseq.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h iseq.$(OBJEXT): {$(VPATH)}assert.h iseq.$(OBJEXT): {$(VPATH)}atomic.h iseq.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -8855,6 +8036,7 @@ iseq.$(OBJEXT): {$(VPATH)}debug_counter.h iseq.$(OBJEXT): {$(VPATH)}defines.h iseq.$(OBJEXT): {$(VPATH)}encoding.h iseq.$(OBJEXT): {$(VPATH)}eval_intern.h +iseq.$(OBJEXT): {$(VPATH)}gc.h iseq.$(OBJEXT): {$(VPATH)}id.h iseq.$(OBJEXT): {$(VPATH)}id_table.h iseq.$(OBJEXT): {$(VPATH)}insns.def @@ -8900,7 +8082,6 @@ iseq.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h iseq.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h iseq.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h iseq.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -iseq.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h iseq.$(OBJEXT): {$(VPATH)}internal/attr/pure.h iseq.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h iseq.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -8969,6 +8150,7 @@ iseq.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h iseq.$(OBJEXT): {$(VPATH)}internal/intern/error.h iseq.$(OBJEXT): {$(VPATH)}internal/intern/eval.h iseq.$(OBJEXT): {$(VPATH)}internal/intern/file.h +iseq.$(OBJEXT): {$(VPATH)}internal/intern/gc.h iseq.$(OBJEXT): {$(VPATH)}internal/intern/hash.h iseq.$(OBJEXT): {$(VPATH)}internal/intern/io.h iseq.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -8999,36 +8181,30 @@ iseq.$(OBJEXT): {$(VPATH)}internal/memory.h iseq.$(OBJEXT): {$(VPATH)}internal/method.h iseq.$(OBJEXT): {$(VPATH)}internal/module.h iseq.$(OBJEXT): {$(VPATH)}internal/newobj.h +iseq.$(OBJEXT): {$(VPATH)}internal/rgengc.h iseq.$(OBJEXT): {$(VPATH)}internal/scan_args.h iseq.$(OBJEXT): {$(VPATH)}internal/special_consts.h iseq.$(OBJEXT): {$(VPATH)}internal/static_assert.h iseq.$(OBJEXT): {$(VPATH)}internal/stdalign.h iseq.$(OBJEXT): {$(VPATH)}internal/stdbool.h -iseq.$(OBJEXT): {$(VPATH)}internal/stdckdint.h iseq.$(OBJEXT): {$(VPATH)}internal/symbol.h iseq.$(OBJEXT): {$(VPATH)}internal/value.h iseq.$(OBJEXT): {$(VPATH)}internal/value_type.h iseq.$(OBJEXT): {$(VPATH)}internal/variable.h iseq.$(OBJEXT): {$(VPATH)}internal/warning_push.h iseq.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -iseq.$(OBJEXT): {$(VPATH)}io.h iseq.$(OBJEXT): {$(VPATH)}iseq.c iseq.$(OBJEXT): {$(VPATH)}iseq.h iseq.$(OBJEXT): {$(VPATH)}method.h iseq.$(OBJEXT): {$(VPATH)}missing.h +iseq.$(OBJEXT): {$(VPATH)}mjit.h iseq.$(OBJEXT): {$(VPATH)}node.h +iseq.$(OBJEXT): {$(VPATH)}node_name.inc iseq.$(OBJEXT): {$(VPATH)}onigmo.h iseq.$(OBJEXT): {$(VPATH)}oniguruma.h -iseq.$(OBJEXT): {$(VPATH)}prism/ast.h -iseq.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -iseq.$(OBJEXT): {$(VPATH)}prism/prism.h -iseq.$(OBJEXT): {$(VPATH)}prism/version.h -iseq.$(OBJEXT): {$(VPATH)}prism_compile.h iseq.$(OBJEXT): {$(VPATH)}ractor.h -iseq.$(OBJEXT): {$(VPATH)}rjit.h iseq.$(OBJEXT): {$(VPATH)}ruby_assert.h iseq.$(OBJEXT): {$(VPATH)}ruby_atomic.h -iseq.$(OBJEXT): {$(VPATH)}rubyparser.h iseq.$(OBJEXT): {$(VPATH)}shape.h iseq.$(OBJEXT): {$(VPATH)}st.h iseq.$(OBJEXT): {$(VPATH)}subst.h @@ -9037,35 +8213,23 @@ iseq.$(OBJEXT): {$(VPATH)}thread_native.h iseq.$(OBJEXT): {$(VPATH)}util.h iseq.$(OBJEXT): {$(VPATH)}vm_callinfo.h iseq.$(OBJEXT): {$(VPATH)}vm_core.h -iseq.$(OBJEXT): {$(VPATH)}vm_debug.h iseq.$(OBJEXT): {$(VPATH)}vm_opts.h -iseq.$(OBJEXT): {$(VPATH)}vm_sync.h iseq.$(OBJEXT): {$(VPATH)}yjit.h load.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h load.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h load.$(OBJEXT): $(CCAN_DIR)/list/list.h load.$(OBJEXT): $(CCAN_DIR)/str/str.h load.$(OBJEXT): $(hdrdir)/ruby/ruby.h -load.$(OBJEXT): $(hdrdir)/ruby/version.h load.$(OBJEXT): $(top_srcdir)/internal/array.h load.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h -load.$(OBJEXT): $(top_srcdir)/internal/bignum.h -load.$(OBJEXT): $(top_srcdir)/internal/bits.h load.$(OBJEXT): $(top_srcdir)/internal/compilers.h -load.$(OBJEXT): $(top_srcdir)/internal/complex.h load.$(OBJEXT): $(top_srcdir)/internal/dir.h load.$(OBJEXT): $(top_srcdir)/internal/error.h load.$(OBJEXT): $(top_srcdir)/internal/file.h -load.$(OBJEXT): $(top_srcdir)/internal/fixnum.h load.$(OBJEXT): $(top_srcdir)/internal/gc.h -load.$(OBJEXT): $(top_srcdir)/internal/hash.h load.$(OBJEXT): $(top_srcdir)/internal/imemo.h load.$(OBJEXT): $(top_srcdir)/internal/load.h -load.$(OBJEXT): $(top_srcdir)/internal/numeric.h load.$(OBJEXT): $(top_srcdir)/internal/parse.h -load.$(OBJEXT): $(top_srcdir)/internal/rational.h -load.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h -load.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h load.$(OBJEXT): $(top_srcdir)/internal/serial.h load.$(OBJEXT): $(top_srcdir)/internal/static_assert.h load.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -9073,26 +8237,6 @@ load.$(OBJEXT): $(top_srcdir)/internal/thread.h load.$(OBJEXT): $(top_srcdir)/internal/variable.h load.$(OBJEXT): $(top_srcdir)/internal/vm.h load.$(OBJEXT): $(top_srcdir)/internal/warnings.h -load.$(OBJEXT): $(top_srcdir)/prism/defines.h -load.$(OBJEXT): $(top_srcdir)/prism/encoding.h -load.$(OBJEXT): $(top_srcdir)/prism/node.h -load.$(OBJEXT): $(top_srcdir)/prism/options.h -load.$(OBJEXT): $(top_srcdir)/prism/pack.h -load.$(OBJEXT): $(top_srcdir)/prism/parser.h -load.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -load.$(OBJEXT): $(top_srcdir)/prism/prism.h -load.$(OBJEXT): $(top_srcdir)/prism/regexp.h -load.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -load.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -load.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -load.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -load.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -load.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -load.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -load.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -load.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -load.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -load.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h load.$(OBJEXT): {$(VPATH)}assert.h load.$(OBJEXT): {$(VPATH)}atomic.h load.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -9153,7 +8297,6 @@ load.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h load.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h load.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h load.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -load.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h load.$(OBJEXT): {$(VPATH)}internal/attr/pure.h load.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h load.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -9222,6 +8365,7 @@ load.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h load.$(OBJEXT): {$(VPATH)}internal/intern/error.h load.$(OBJEXT): {$(VPATH)}internal/intern/eval.h load.$(OBJEXT): {$(VPATH)}internal/intern/file.h +load.$(OBJEXT): {$(VPATH)}internal/intern/gc.h load.$(OBJEXT): {$(VPATH)}internal/intern/hash.h load.$(OBJEXT): {$(VPATH)}internal/intern/io.h load.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -9252,12 +8396,12 @@ load.$(OBJEXT): {$(VPATH)}internal/memory.h load.$(OBJEXT): {$(VPATH)}internal/method.h load.$(OBJEXT): {$(VPATH)}internal/module.h load.$(OBJEXT): {$(VPATH)}internal/newobj.h +load.$(OBJEXT): {$(VPATH)}internal/rgengc.h load.$(OBJEXT): {$(VPATH)}internal/scan_args.h load.$(OBJEXT): {$(VPATH)}internal/special_consts.h load.$(OBJEXT): {$(VPATH)}internal/static_assert.h load.$(OBJEXT): {$(VPATH)}internal/stdalign.h load.$(OBJEXT): {$(VPATH)}internal/stdbool.h -load.$(OBJEXT): {$(VPATH)}internal/stdckdint.h load.$(OBJEXT): {$(VPATH)}internal/symbol.h load.$(OBJEXT): {$(VPATH)}internal/value.h load.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -9271,15 +8415,10 @@ load.$(OBJEXT): {$(VPATH)}missing.h load.$(OBJEXT): {$(VPATH)}node.h load.$(OBJEXT): {$(VPATH)}onigmo.h load.$(OBJEXT): {$(VPATH)}oniguruma.h -load.$(OBJEXT): {$(VPATH)}prism/ast.h -load.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -load.$(OBJEXT): {$(VPATH)}prism/version.h -load.$(OBJEXT): {$(VPATH)}prism_compile.h load.$(OBJEXT): {$(VPATH)}probes.dmyh load.$(OBJEXT): {$(VPATH)}probes.h load.$(OBJEXT): {$(VPATH)}ruby_assert.h load.$(OBJEXT): {$(VPATH)}ruby_atomic.h -load.$(OBJEXT): {$(VPATH)}rubyparser.h load.$(OBJEXT): {$(VPATH)}shape.h load.$(OBJEXT): {$(VPATH)}st.h load.$(OBJEXT): {$(VPATH)}subst.h @@ -9341,7 +8480,6 @@ loadpath.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h loadpath.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h loadpath.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h loadpath.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -loadpath.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h loadpath.$(OBJEXT): {$(VPATH)}internal/attr/pure.h loadpath.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h loadpath.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -9401,6 +8539,7 @@ loadpath.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h loadpath.$(OBJEXT): {$(VPATH)}internal/intern/error.h loadpath.$(OBJEXT): {$(VPATH)}internal/intern/eval.h loadpath.$(OBJEXT): {$(VPATH)}internal/intern/file.h +loadpath.$(OBJEXT): {$(VPATH)}internal/intern/gc.h loadpath.$(OBJEXT): {$(VPATH)}internal/intern/hash.h loadpath.$(OBJEXT): {$(VPATH)}internal/intern/io.h loadpath.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -9431,12 +8570,12 @@ loadpath.$(OBJEXT): {$(VPATH)}internal/memory.h loadpath.$(OBJEXT): {$(VPATH)}internal/method.h loadpath.$(OBJEXT): {$(VPATH)}internal/module.h loadpath.$(OBJEXT): {$(VPATH)}internal/newobj.h +loadpath.$(OBJEXT): {$(VPATH)}internal/rgengc.h loadpath.$(OBJEXT): {$(VPATH)}internal/scan_args.h loadpath.$(OBJEXT): {$(VPATH)}internal/special_consts.h loadpath.$(OBJEXT): {$(VPATH)}internal/static_assert.h loadpath.$(OBJEXT): {$(VPATH)}internal/stdalign.h loadpath.$(OBJEXT): {$(VPATH)}internal/stdbool.h -loadpath.$(OBJEXT): {$(VPATH)}internal/stdckdint.h loadpath.$(OBJEXT): {$(VPATH)}internal/symbol.h loadpath.$(OBJEXT): {$(VPATH)}internal/value.h loadpath.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -9502,7 +8641,6 @@ localeinit.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h localeinit.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h localeinit.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h localeinit.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -localeinit.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h localeinit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h localeinit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h localeinit.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -9571,6 +8709,7 @@ localeinit.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h localeinit.$(OBJEXT): {$(VPATH)}internal/intern/error.h localeinit.$(OBJEXT): {$(VPATH)}internal/intern/eval.h localeinit.$(OBJEXT): {$(VPATH)}internal/intern/file.h +localeinit.$(OBJEXT): {$(VPATH)}internal/intern/gc.h localeinit.$(OBJEXT): {$(VPATH)}internal/intern/hash.h localeinit.$(OBJEXT): {$(VPATH)}internal/intern/io.h localeinit.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -9601,12 +8740,12 @@ localeinit.$(OBJEXT): {$(VPATH)}internal/memory.h localeinit.$(OBJEXT): {$(VPATH)}internal/method.h localeinit.$(OBJEXT): {$(VPATH)}internal/module.h localeinit.$(OBJEXT): {$(VPATH)}internal/newobj.h +localeinit.$(OBJEXT): {$(VPATH)}internal/rgengc.h localeinit.$(OBJEXT): {$(VPATH)}internal/scan_args.h localeinit.$(OBJEXT): {$(VPATH)}internal/special_consts.h localeinit.$(OBJEXT): {$(VPATH)}internal/static_assert.h localeinit.$(OBJEXT): {$(VPATH)}internal/stdalign.h localeinit.$(OBJEXT): {$(VPATH)}internal/stdbool.h -localeinit.$(OBJEXT): {$(VPATH)}internal/stdckdint.h localeinit.$(OBJEXT): {$(VPATH)}internal/symbol.h localeinit.$(OBJEXT): {$(VPATH)}internal/value.h localeinit.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -9621,15 +8760,11 @@ localeinit.$(OBJEXT): {$(VPATH)}st.h localeinit.$(OBJEXT): {$(VPATH)}subst.h main.$(OBJEXT): $(hdrdir)/ruby.h main.$(OBJEXT): $(hdrdir)/ruby/ruby.h -main.$(OBJEXT): $(top_srcdir)/internal/compilers.h -main.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h -main.$(OBJEXT): $(top_srcdir)/internal/warnings.h main.$(OBJEXT): {$(VPATH)}assert.h main.$(OBJEXT): {$(VPATH)}backward.h main.$(OBJEXT): {$(VPATH)}backward/2/assume.h main.$(OBJEXT): {$(VPATH)}backward/2/attributes.h main.$(OBJEXT): {$(VPATH)}backward/2/bool.h -main.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h main.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h main.$(OBJEXT): {$(VPATH)}backward/2/limits.h main.$(OBJEXT): {$(VPATH)}backward/2/long_long.h @@ -9676,7 +8811,6 @@ main.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h main.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h main.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h main.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -main.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h main.$(OBJEXT): {$(VPATH)}internal/attr/pure.h main.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h main.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -9736,6 +8870,7 @@ main.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h main.$(OBJEXT): {$(VPATH)}internal/intern/error.h main.$(OBJEXT): {$(VPATH)}internal/intern/eval.h main.$(OBJEXT): {$(VPATH)}internal/intern/file.h +main.$(OBJEXT): {$(VPATH)}internal/intern/gc.h main.$(OBJEXT): {$(VPATH)}internal/intern/hash.h main.$(OBJEXT): {$(VPATH)}internal/intern/io.h main.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -9766,12 +8901,12 @@ main.$(OBJEXT): {$(VPATH)}internal/memory.h main.$(OBJEXT): {$(VPATH)}internal/method.h main.$(OBJEXT): {$(VPATH)}internal/module.h main.$(OBJEXT): {$(VPATH)}internal/newobj.h +main.$(OBJEXT): {$(VPATH)}internal/rgengc.h main.$(OBJEXT): {$(VPATH)}internal/scan_args.h main.$(OBJEXT): {$(VPATH)}internal/special_consts.h main.$(OBJEXT): {$(VPATH)}internal/static_assert.h main.$(OBJEXT): {$(VPATH)}internal/stdalign.h main.$(OBJEXT): {$(VPATH)}internal/stdbool.h -main.$(OBJEXT): {$(VPATH)}internal/stdckdint.h main.$(OBJEXT): {$(VPATH)}internal/symbol.h main.$(OBJEXT): {$(VPATH)}internal/value.h main.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -9788,7 +8923,6 @@ 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): $(hdrdir)/ruby/version.h marshal.$(OBJEXT): $(top_srcdir)/internal/array.h marshal.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h marshal.$(OBJEXT): $(top_srcdir)/internal/bignum.h @@ -9803,7 +8937,6 @@ 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/sanitizers.h marshal.$(OBJEXT): $(top_srcdir)/internal/serial.h marshal.$(OBJEXT): $(top_srcdir)/internal/static_assert.h marshal.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -9827,7 +8960,6 @@ marshal.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h marshal.$(OBJEXT): {$(VPATH)}builtin.h marshal.$(OBJEXT): {$(VPATH)}config.h marshal.$(OBJEXT): {$(VPATH)}constant.h -marshal.$(OBJEXT): {$(VPATH)}debug_counter.h marshal.$(OBJEXT): {$(VPATH)}defines.h marshal.$(OBJEXT): {$(VPATH)}encindex.h marshal.$(OBJEXT): {$(VPATH)}encoding.h @@ -9872,8 +9004,8 @@ 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/packed_struct.h marshal.$(OBJEXT): {$(VPATH)}internal/attr/pure.h marshal.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h marshal.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -9942,6 +9074,7 @@ marshal.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h marshal.$(OBJEXT): {$(VPATH)}internal/intern/error.h marshal.$(OBJEXT): {$(VPATH)}internal/intern/eval.h marshal.$(OBJEXT): {$(VPATH)}internal/intern/file.h +marshal.$(OBJEXT): {$(VPATH)}internal/intern/gc.h marshal.$(OBJEXT): {$(VPATH)}internal/intern/hash.h marshal.$(OBJEXT): {$(VPATH)}internal/intern/io.h marshal.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -9972,12 +9105,12 @@ marshal.$(OBJEXT): {$(VPATH)}internal/memory.h marshal.$(OBJEXT): {$(VPATH)}internal/method.h marshal.$(OBJEXT): {$(VPATH)}internal/module.h marshal.$(OBJEXT): {$(VPATH)}internal/newobj.h +marshal.$(OBJEXT): {$(VPATH)}internal/rgengc.h marshal.$(OBJEXT): {$(VPATH)}internal/scan_args.h marshal.$(OBJEXT): {$(VPATH)}internal/special_consts.h marshal.$(OBJEXT): {$(VPATH)}internal/static_assert.h marshal.$(OBJEXT): {$(VPATH)}internal/stdalign.h marshal.$(OBJEXT): {$(VPATH)}internal/stdbool.h -marshal.$(OBJEXT): {$(VPATH)}internal/stdckdint.h marshal.$(OBJEXT): {$(VPATH)}internal/symbol.h marshal.$(OBJEXT): {$(VPATH)}internal/value.h marshal.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -9994,7 +9127,6 @@ 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)}rubyparser.h marshal.$(OBJEXT): {$(VPATH)}shape.h marshal.$(OBJEXT): {$(VPATH)}st.h marshal.$(OBJEXT): {$(VPATH)}subst.h @@ -10002,9 +9134,7 @@ 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_debug.h marshal.$(OBJEXT): {$(VPATH)}vm_opts.h -marshal.$(OBJEXT): {$(VPATH)}vm_sync.h math.$(OBJEXT): $(hdrdir)/ruby/ruby.h math.$(OBJEXT): $(top_srcdir)/internal/bignum.h math.$(OBJEXT): $(top_srcdir)/internal/class.h @@ -10072,7 +9202,6 @@ math.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h math.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h math.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h math.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -math.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h math.$(OBJEXT): {$(VPATH)}internal/attr/pure.h math.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h math.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -10132,6 +9261,7 @@ math.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h math.$(OBJEXT): {$(VPATH)}internal/intern/error.h math.$(OBJEXT): {$(VPATH)}internal/intern/eval.h math.$(OBJEXT): {$(VPATH)}internal/intern/file.h +math.$(OBJEXT): {$(VPATH)}internal/intern/gc.h math.$(OBJEXT): {$(VPATH)}internal/intern/hash.h math.$(OBJEXT): {$(VPATH)}internal/intern/io.h math.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -10162,12 +9292,12 @@ math.$(OBJEXT): {$(VPATH)}internal/memory.h math.$(OBJEXT): {$(VPATH)}internal/method.h math.$(OBJEXT): {$(VPATH)}internal/module.h math.$(OBJEXT): {$(VPATH)}internal/newobj.h +math.$(OBJEXT): {$(VPATH)}internal/rgengc.h math.$(OBJEXT): {$(VPATH)}internal/scan_args.h math.$(OBJEXT): {$(VPATH)}internal/special_consts.h math.$(OBJEXT): {$(VPATH)}internal/static_assert.h math.$(OBJEXT): {$(VPATH)}internal/stdalign.h math.$(OBJEXT): {$(VPATH)}internal/stdbool.h -math.$(OBJEXT): {$(VPATH)}internal/stdckdint.h math.$(OBJEXT): {$(VPATH)}internal/symbol.h math.$(OBJEXT): {$(VPATH)}internal/value.h math.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -10179,25 +9309,13 @@ math.$(OBJEXT): {$(VPATH)}missing.h math.$(OBJEXT): {$(VPATH)}shape.h math.$(OBJEXT): {$(VPATH)}st.h math.$(OBJEXT): {$(VPATH)}subst.h -memory_view.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -memory_view.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -memory_view.$(OBJEXT): $(CCAN_DIR)/list/list.h -memory_view.$(OBJEXT): $(CCAN_DIR)/str/str.h memory_view.$(OBJEXT): $(hdrdir)/ruby/ruby.h -memory_view.$(OBJEXT): $(top_srcdir)/internal/array.h -memory_view.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h memory_view.$(OBJEXT): $(top_srcdir)/internal/compilers.h memory_view.$(OBJEXT): $(top_srcdir)/internal/gc.h memory_view.$(OBJEXT): $(top_srcdir)/internal/hash.h -memory_view.$(OBJEXT): $(top_srcdir)/internal/imemo.h -memory_view.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h -memory_view.$(OBJEXT): $(top_srcdir)/internal/serial.h -memory_view.$(OBJEXT): $(top_srcdir)/internal/static_assert.h memory_view.$(OBJEXT): $(top_srcdir)/internal/variable.h -memory_view.$(OBJEXT): $(top_srcdir)/internal/vm.h memory_view.$(OBJEXT): $(top_srcdir)/internal/warnings.h memory_view.$(OBJEXT): {$(VPATH)}assert.h -memory_view.$(OBJEXT): {$(VPATH)}atomic.h memory_view.$(OBJEXT): {$(VPATH)}backward/2/assume.h memory_view.$(OBJEXT): {$(VPATH)}backward/2/attributes.h memory_view.$(OBJEXT): {$(VPATH)}backward/2/bool.h @@ -10211,8 +9329,6 @@ memory_view.$(OBJEXT): {$(VPATH)}config.h memory_view.$(OBJEXT): {$(VPATH)}constant.h memory_view.$(OBJEXT): {$(VPATH)}debug_counter.h memory_view.$(OBJEXT): {$(VPATH)}defines.h -memory_view.$(OBJEXT): {$(VPATH)}encoding.h -memory_view.$(OBJEXT): {$(VPATH)}id.h memory_view.$(OBJEXT): {$(VPATH)}id_table.h memory_view.$(OBJEXT): {$(VPATH)}intern.h memory_view.$(OBJEXT): {$(VPATH)}internal.h @@ -10254,7 +9370,6 @@ memory_view.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h memory_view.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h memory_view.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h memory_view.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -memory_view.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h memory_view.$(OBJEXT): {$(VPATH)}internal/attr/pure.h memory_view.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h memory_view.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -10287,15 +9402,6 @@ memory_view.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h memory_view.$(OBJEXT): {$(VPATH)}internal/ctype.h memory_view.$(OBJEXT): {$(VPATH)}internal/dllexport.h memory_view.$(OBJEXT): {$(VPATH)}internal/dosish.h -memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -memory_view.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h memory_view.$(OBJEXT): {$(VPATH)}internal/error.h memory_view.$(OBJEXT): {$(VPATH)}internal/eval.h memory_view.$(OBJEXT): {$(VPATH)}internal/event.h @@ -10323,6 +9429,7 @@ memory_view.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h memory_view.$(OBJEXT): {$(VPATH)}internal/intern/error.h memory_view.$(OBJEXT): {$(VPATH)}internal/intern/eval.h memory_view.$(OBJEXT): {$(VPATH)}internal/intern/file.h +memory_view.$(OBJEXT): {$(VPATH)}internal/intern/gc.h memory_view.$(OBJEXT): {$(VPATH)}internal/intern/hash.h memory_view.$(OBJEXT): {$(VPATH)}internal/intern/io.h memory_view.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -10353,12 +9460,12 @@ memory_view.$(OBJEXT): {$(VPATH)}internal/memory.h memory_view.$(OBJEXT): {$(VPATH)}internal/method.h memory_view.$(OBJEXT): {$(VPATH)}internal/module.h memory_view.$(OBJEXT): {$(VPATH)}internal/newobj.h +memory_view.$(OBJEXT): {$(VPATH)}internal/rgengc.h memory_view.$(OBJEXT): {$(VPATH)}internal/scan_args.h memory_view.$(OBJEXT): {$(VPATH)}internal/special_consts.h memory_view.$(OBJEXT): {$(VPATH)}internal/static_assert.h memory_view.$(OBJEXT): {$(VPATH)}internal/stdalign.h memory_view.$(OBJEXT): {$(VPATH)}internal/stdbool.h -memory_view.$(OBJEXT): {$(VPATH)}internal/stdckdint.h memory_view.$(OBJEXT): {$(VPATH)}internal/symbol.h memory_view.$(OBJEXT): {$(VPATH)}internal/value.h memory_view.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -10367,69 +9474,29 @@ memory_view.$(OBJEXT): {$(VPATH)}internal/warning_push.h memory_view.$(OBJEXT): {$(VPATH)}internal/xmalloc.h memory_view.$(OBJEXT): {$(VPATH)}memory_view.c memory_view.$(OBJEXT): {$(VPATH)}memory_view.h -memory_view.$(OBJEXT): {$(VPATH)}method.h memory_view.$(OBJEXT): {$(VPATH)}missing.h -memory_view.$(OBJEXT): {$(VPATH)}node.h -memory_view.$(OBJEXT): {$(VPATH)}onigmo.h -memory_view.$(OBJEXT): {$(VPATH)}oniguruma.h -memory_view.$(OBJEXT): {$(VPATH)}ruby_assert.h -memory_view.$(OBJEXT): {$(VPATH)}ruby_atomic.h -memory_view.$(OBJEXT): {$(VPATH)}rubyparser.h memory_view.$(OBJEXT): {$(VPATH)}shape.h memory_view.$(OBJEXT): {$(VPATH)}st.h memory_view.$(OBJEXT): {$(VPATH)}subst.h -memory_view.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -memory_view.$(OBJEXT): {$(VPATH)}thread_native.h memory_view.$(OBJEXT): {$(VPATH)}util.h -memory_view.$(OBJEXT): {$(VPATH)}vm_core.h memory_view.$(OBJEXT): {$(VPATH)}vm_debug.h -memory_view.$(OBJEXT): {$(VPATH)}vm_opts.h memory_view.$(OBJEXT): {$(VPATH)}vm_sync.h miniinit.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h miniinit.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h miniinit.$(OBJEXT): $(CCAN_DIR)/list/list.h miniinit.$(OBJEXT): $(CCAN_DIR)/str/str.h miniinit.$(OBJEXT): $(hdrdir)/ruby/ruby.h -miniinit.$(OBJEXT): $(srcdir)/rjit_c.rb +miniinit.$(OBJEXT): $(srcdir)/mjit_c.rb miniinit.$(OBJEXT): $(top_srcdir)/internal/array.h miniinit.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h -miniinit.$(OBJEXT): $(top_srcdir)/internal/bignum.h -miniinit.$(OBJEXT): $(top_srcdir)/internal/bits.h miniinit.$(OBJEXT): $(top_srcdir)/internal/compilers.h -miniinit.$(OBJEXT): $(top_srcdir)/internal/complex.h -miniinit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h miniinit.$(OBJEXT): $(top_srcdir)/internal/gc.h miniinit.$(OBJEXT): $(top_srcdir)/internal/imemo.h -miniinit.$(OBJEXT): $(top_srcdir)/internal/numeric.h -miniinit.$(OBJEXT): $(top_srcdir)/internal/parse.h -miniinit.$(OBJEXT): $(top_srcdir)/internal/rational.h -miniinit.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h -miniinit.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h miniinit.$(OBJEXT): $(top_srcdir)/internal/serial.h miniinit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h miniinit.$(OBJEXT): $(top_srcdir)/internal/variable.h miniinit.$(OBJEXT): $(top_srcdir)/internal/vm.h miniinit.$(OBJEXT): $(top_srcdir)/internal/warnings.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/defines.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/encoding.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/node.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/options.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/pack.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/parser.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/prism.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/regexp.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -miniinit.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h miniinit.$(OBJEXT): {$(VPATH)}array.rb miniinit.$(OBJEXT): {$(VPATH)}assert.h miniinit.$(OBJEXT): {$(VPATH)}ast.rb @@ -10492,8 +9559,8 @@ 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/packed_struct.h miniinit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h miniinit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h miniinit.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -10562,6 +9629,7 @@ miniinit.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h miniinit.$(OBJEXT): {$(VPATH)}internal/intern/error.h miniinit.$(OBJEXT): {$(VPATH)}internal/intern/eval.h miniinit.$(OBJEXT): {$(VPATH)}internal/intern/file.h +miniinit.$(OBJEXT): {$(VPATH)}internal/intern/gc.h miniinit.$(OBJEXT): {$(VPATH)}internal/intern/hash.h miniinit.$(OBJEXT): {$(VPATH)}internal/intern/io.h miniinit.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -10592,12 +9660,12 @@ miniinit.$(OBJEXT): {$(VPATH)}internal/memory.h miniinit.$(OBJEXT): {$(VPATH)}internal/method.h miniinit.$(OBJEXT): {$(VPATH)}internal/module.h miniinit.$(OBJEXT): {$(VPATH)}internal/newobj.h +miniinit.$(OBJEXT): {$(VPATH)}internal/rgengc.h miniinit.$(OBJEXT): {$(VPATH)}internal/scan_args.h miniinit.$(OBJEXT): {$(VPATH)}internal/special_consts.h miniinit.$(OBJEXT): {$(VPATH)}internal/static_assert.h miniinit.$(OBJEXT): {$(VPATH)}internal/stdalign.h miniinit.$(OBJEXT): {$(VPATH)}internal/stdbool.h -miniinit.$(OBJEXT): {$(VPATH)}internal/stdckdint.h miniinit.$(OBJEXT): {$(VPATH)}internal/symbol.h miniinit.$(OBJEXT): {$(VPATH)}internal/value.h miniinit.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -10613,6 +9681,8 @@ miniinit.$(OBJEXT): {$(VPATH)}mini_builtin.c miniinit.$(OBJEXT): {$(VPATH)}miniinit.c miniinit.$(OBJEXT): {$(VPATH)}miniprelude.c miniinit.$(OBJEXT): {$(VPATH)}missing.h +miniinit.$(OBJEXT): {$(VPATH)}mjit.rb +miniinit.$(OBJEXT): {$(VPATH)}mjit_c.rb miniinit.$(OBJEXT): {$(VPATH)}nilclass.rb miniinit.$(OBJEXT): {$(VPATH)}node.h miniinit.$(OBJEXT): {$(VPATH)}numeric.rb @@ -10620,16 +9690,9 @@ miniinit.$(OBJEXT): {$(VPATH)}onigmo.h miniinit.$(OBJEXT): {$(VPATH)}oniguruma.h miniinit.$(OBJEXT): {$(VPATH)}pack.rb miniinit.$(OBJEXT): {$(VPATH)}prelude.rb -miniinit.$(OBJEXT): {$(VPATH)}prism/ast.h -miniinit.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -miniinit.$(OBJEXT): {$(VPATH)}prism/version.h -miniinit.$(OBJEXT): {$(VPATH)}prism_compile.h miniinit.$(OBJEXT): {$(VPATH)}ractor.rb -miniinit.$(OBJEXT): {$(VPATH)}rjit.rb -miniinit.$(OBJEXT): {$(VPATH)}rjit_c.rb miniinit.$(OBJEXT): {$(VPATH)}ruby_assert.h miniinit.$(OBJEXT): {$(VPATH)}ruby_atomic.h -miniinit.$(OBJEXT): {$(VPATH)}rubyparser.h miniinit.$(OBJEXT): {$(VPATH)}shape.h miniinit.$(OBJEXT): {$(VPATH)}st.h miniinit.$(OBJEXT): {$(VPATH)}subst.h @@ -10643,6 +9706,441 @@ miniinit.$(OBJEXT): {$(VPATH)}vm_core.h miniinit.$(OBJEXT): {$(VPATH)}vm_opts.h miniinit.$(OBJEXT): {$(VPATH)}warning.rb miniinit.$(OBJEXT): {$(VPATH)}yjit.rb +mjit.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h +mjit.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h +mjit.$(OBJEXT): $(CCAN_DIR)/list/list.h +mjit.$(OBJEXT): $(CCAN_DIR)/str/str.h +mjit.$(OBJEXT): $(hdrdir)/ruby.h +mjit.$(OBJEXT): $(hdrdir)/ruby/ruby.h +mjit.$(OBJEXT): $(hdrdir)/ruby/version.h +mjit.$(OBJEXT): $(top_srcdir)/internal/array.h +mjit.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h +mjit.$(OBJEXT): $(top_srcdir)/internal/class.h +mjit.$(OBJEXT): $(top_srcdir)/internal/cmdlineopt.h +mjit.$(OBJEXT): $(top_srcdir)/internal/compile.h +mjit.$(OBJEXT): $(top_srcdir)/internal/compilers.h +mjit.$(OBJEXT): $(top_srcdir)/internal/cont.h +mjit.$(OBJEXT): $(top_srcdir)/internal/file.h +mjit.$(OBJEXT): $(top_srcdir)/internal/gc.h +mjit.$(OBJEXT): $(top_srcdir)/internal/hash.h +mjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h +mjit.$(OBJEXT): $(top_srcdir)/internal/process.h +mjit.$(OBJEXT): $(top_srcdir)/internal/serial.h +mjit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h +mjit.$(OBJEXT): $(top_srcdir)/internal/variable.h +mjit.$(OBJEXT): $(top_srcdir)/internal/vm.h +mjit.$(OBJEXT): $(top_srcdir)/internal/warnings.h +mjit.$(OBJEXT): {$(VPATH)}assert.h +mjit.$(OBJEXT): {$(VPATH)}atomic.h +mjit.$(OBJEXT): {$(VPATH)}backward/2/assume.h +mjit.$(OBJEXT): {$(VPATH)}backward/2/attributes.h +mjit.$(OBJEXT): {$(VPATH)}backward/2/bool.h +mjit.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h +mjit.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h +mjit.$(OBJEXT): {$(VPATH)}backward/2/limits.h +mjit.$(OBJEXT): {$(VPATH)}backward/2/long_long.h +mjit.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h +mjit.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h +mjit.$(OBJEXT): {$(VPATH)}builtin.h +mjit.$(OBJEXT): {$(VPATH)}config.h +mjit.$(OBJEXT): {$(VPATH)}constant.h +mjit.$(OBJEXT): {$(VPATH)}debug.h +mjit.$(OBJEXT): {$(VPATH)}debug_counter.h +mjit.$(OBJEXT): {$(VPATH)}defines.h +mjit.$(OBJEXT): {$(VPATH)}dln.h +mjit.$(OBJEXT): {$(VPATH)}encoding.h +mjit.$(OBJEXT): {$(VPATH)}gc.h +mjit.$(OBJEXT): {$(VPATH)}id.h +mjit.$(OBJEXT): {$(VPATH)}id_table.h +mjit.$(OBJEXT): {$(VPATH)}insns.def +mjit.$(OBJEXT): {$(VPATH)}insns.inc +mjit.$(OBJEXT): {$(VPATH)}insns_info.inc +mjit.$(OBJEXT): {$(VPATH)}intern.h +mjit.$(OBJEXT): {$(VPATH)}internal.h +mjit.$(OBJEXT): {$(VPATH)}internal/abi.h +mjit.$(OBJEXT): {$(VPATH)}internal/anyargs.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h +mjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h +mjit.$(OBJEXT): {$(VPATH)}internal/assume.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/cold.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/const.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/error.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/format.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/warning.h +mjit.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h +mjit.$(OBJEXT): {$(VPATH)}internal/cast.h +mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is.h +mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h +mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h +mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h +mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h +mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h +mjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h +mjit.$(OBJEXT): {$(VPATH)}internal/compiler_since.h +mjit.$(OBJEXT): {$(VPATH)}internal/config.h +mjit.$(OBJEXT): {$(VPATH)}internal/constant_p.h +mjit.$(OBJEXT): {$(VPATH)}internal/core.h +mjit.$(OBJEXT): {$(VPATH)}internal/core/rarray.h +mjit.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h +mjit.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h +mjit.$(OBJEXT): {$(VPATH)}internal/core/rclass.h +mjit.$(OBJEXT): {$(VPATH)}internal/core/rdata.h +mjit.$(OBJEXT): {$(VPATH)}internal/core/rfile.h +mjit.$(OBJEXT): {$(VPATH)}internal/core/rhash.h +mjit.$(OBJEXT): {$(VPATH)}internal/core/robject.h +mjit.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h +mjit.$(OBJEXT): {$(VPATH)}internal/core/rstring.h +mjit.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h +mjit.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h +mjit.$(OBJEXT): {$(VPATH)}internal/ctype.h +mjit.$(OBJEXT): {$(VPATH)}internal/dllexport.h +mjit.$(OBJEXT): {$(VPATH)}internal/dosish.h +mjit.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h +mjit.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h +mjit.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h +mjit.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h +mjit.$(OBJEXT): {$(VPATH)}internal/encoding/re.h +mjit.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h +mjit.$(OBJEXT): {$(VPATH)}internal/encoding/string.h +mjit.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h +mjit.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h +mjit.$(OBJEXT): {$(VPATH)}internal/error.h +mjit.$(OBJEXT): {$(VPATH)}internal/eval.h +mjit.$(OBJEXT): {$(VPATH)}internal/event.h +mjit.$(OBJEXT): {$(VPATH)}internal/fl_type.h +mjit.$(OBJEXT): {$(VPATH)}internal/gc.h +mjit.$(OBJEXT): {$(VPATH)}internal/glob.h +mjit.$(OBJEXT): {$(VPATH)}internal/globals.h +mjit.$(OBJEXT): {$(VPATH)}internal/has/attribute.h +mjit.$(OBJEXT): {$(VPATH)}internal/has/builtin.h +mjit.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h +mjit.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h +mjit.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h +mjit.$(OBJEXT): {$(VPATH)}internal/has/extension.h +mjit.$(OBJEXT): {$(VPATH)}internal/has/feature.h +mjit.$(OBJEXT): {$(VPATH)}internal/has/warning.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/array.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/class.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/compar.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/complex.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/cont.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/dir.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/enum.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/error.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/eval.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/file.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/gc.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/hash.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/io.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/load.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/object.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/parse.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/proc.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/process.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/random.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/range.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/rational.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/re.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/select.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/signal.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/string.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/struct.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/thread.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/time.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/variable.h +mjit.$(OBJEXT): {$(VPATH)}internal/intern/vm.h +mjit.$(OBJEXT): {$(VPATH)}internal/interpreter.h +mjit.$(OBJEXT): {$(VPATH)}internal/iterator.h +mjit.$(OBJEXT): {$(VPATH)}internal/memory.h +mjit.$(OBJEXT): {$(VPATH)}internal/method.h +mjit.$(OBJEXT): {$(VPATH)}internal/module.h +mjit.$(OBJEXT): {$(VPATH)}internal/newobj.h +mjit.$(OBJEXT): {$(VPATH)}internal/rgengc.h +mjit.$(OBJEXT): {$(VPATH)}internal/scan_args.h +mjit.$(OBJEXT): {$(VPATH)}internal/special_consts.h +mjit.$(OBJEXT): {$(VPATH)}internal/static_assert.h +mjit.$(OBJEXT): {$(VPATH)}internal/stdalign.h +mjit.$(OBJEXT): {$(VPATH)}internal/stdbool.h +mjit.$(OBJEXT): {$(VPATH)}internal/symbol.h +mjit.$(OBJEXT): {$(VPATH)}internal/value.h +mjit.$(OBJEXT): {$(VPATH)}internal/value_type.h +mjit.$(OBJEXT): {$(VPATH)}internal/variable.h +mjit.$(OBJEXT): {$(VPATH)}internal/warning_push.h +mjit.$(OBJEXT): {$(VPATH)}internal/xmalloc.h +mjit.$(OBJEXT): {$(VPATH)}iseq.h +mjit.$(OBJEXT): {$(VPATH)}method.h +mjit.$(OBJEXT): {$(VPATH)}missing.h +mjit.$(OBJEXT): {$(VPATH)}mjit.c +mjit.$(OBJEXT): {$(VPATH)}mjit.h +mjit.$(OBJEXT): {$(VPATH)}mjit.rbinc +mjit.$(OBJEXT): {$(VPATH)}mjit_c.h +mjit.$(OBJEXT): {$(VPATH)}mjit_config.h +mjit.$(OBJEXT): {$(VPATH)}node.h +mjit.$(OBJEXT): {$(VPATH)}onigmo.h +mjit.$(OBJEXT): {$(VPATH)}oniguruma.h +mjit.$(OBJEXT): {$(VPATH)}ractor.h +mjit.$(OBJEXT): {$(VPATH)}ractor_core.h +mjit.$(OBJEXT): {$(VPATH)}ruby_assert.h +mjit.$(OBJEXT): {$(VPATH)}ruby_atomic.h +mjit.$(OBJEXT): {$(VPATH)}shape.h +mjit.$(OBJEXT): {$(VPATH)}st.h +mjit.$(OBJEXT): {$(VPATH)}subst.h +mjit.$(OBJEXT): {$(VPATH)}thread.h +mjit.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h +mjit.$(OBJEXT): {$(VPATH)}thread_native.h +mjit.$(OBJEXT): {$(VPATH)}util.h +mjit.$(OBJEXT): {$(VPATH)}vm_callinfo.h +mjit.$(OBJEXT): {$(VPATH)}vm_core.h +mjit.$(OBJEXT): {$(VPATH)}vm_debug.h +mjit.$(OBJEXT): {$(VPATH)}vm_opts.h +mjit.$(OBJEXT): {$(VPATH)}vm_sync.h +mjit.$(OBJEXT): {$(VPATH)}yjit.h +mjit_c.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h +mjit_c.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h +mjit_c.$(OBJEXT): $(CCAN_DIR)/list/list.h +mjit_c.$(OBJEXT): $(CCAN_DIR)/str/str.h +mjit_c.$(OBJEXT): $(hdrdir)/ruby.h +mjit_c.$(OBJEXT): $(hdrdir)/ruby/ruby.h +mjit_c.$(OBJEXT): $(srcdir)/mjit_c.rb +mjit_c.$(OBJEXT): $(top_srcdir)/internal/array.h +mjit_c.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h +mjit_c.$(OBJEXT): $(top_srcdir)/internal/class.h +mjit_c.$(OBJEXT): $(top_srcdir)/internal/compile.h +mjit_c.$(OBJEXT): $(top_srcdir)/internal/compilers.h +mjit_c.$(OBJEXT): $(top_srcdir)/internal/gc.h +mjit_c.$(OBJEXT): $(top_srcdir)/internal/hash.h +mjit_c.$(OBJEXT): $(top_srcdir)/internal/imemo.h +mjit_c.$(OBJEXT): $(top_srcdir)/internal/object.h +mjit_c.$(OBJEXT): $(top_srcdir)/internal/serial.h +mjit_c.$(OBJEXT): $(top_srcdir)/internal/static_assert.h +mjit_c.$(OBJEXT): $(top_srcdir)/internal/variable.h +mjit_c.$(OBJEXT): $(top_srcdir)/internal/vm.h +mjit_c.$(OBJEXT): $(top_srcdir)/internal/warnings.h +mjit_c.$(OBJEXT): {$(VPATH)}assert.h +mjit_c.$(OBJEXT): {$(VPATH)}atomic.h +mjit_c.$(OBJEXT): {$(VPATH)}backward/2/assume.h +mjit_c.$(OBJEXT): {$(VPATH)}backward/2/attributes.h +mjit_c.$(OBJEXT): {$(VPATH)}backward/2/bool.h +mjit_c.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h +mjit_c.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h +mjit_c.$(OBJEXT): {$(VPATH)}backward/2/limits.h +mjit_c.$(OBJEXT): {$(VPATH)}backward/2/long_long.h +mjit_c.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h +mjit_c.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h +mjit_c.$(OBJEXT): {$(VPATH)}builtin.h +mjit_c.$(OBJEXT): {$(VPATH)}config.h +mjit_c.$(OBJEXT): {$(VPATH)}constant.h +mjit_c.$(OBJEXT): {$(VPATH)}debug_counter.h +mjit_c.$(OBJEXT): {$(VPATH)}defines.h +mjit_c.$(OBJEXT): {$(VPATH)}id.h +mjit_c.$(OBJEXT): {$(VPATH)}id_table.h +mjit_c.$(OBJEXT): {$(VPATH)}insns.def +mjit_c.$(OBJEXT): {$(VPATH)}insns.inc +mjit_c.$(OBJEXT): {$(VPATH)}insns_info.inc +mjit_c.$(OBJEXT): {$(VPATH)}intern.h +mjit_c.$(OBJEXT): {$(VPATH)}internal.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/abi.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/anyargs.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/assume.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/cold.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/const.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/error.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/format.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/pure.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/warning.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/cast.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_since.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/config.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/constant_p.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/core.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rarray.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rclass.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rdata.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rfile.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rhash.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/core/robject.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rstring.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/ctype.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/dllexport.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/dosish.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/error.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/eval.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/event.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/fl_type.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/gc.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/glob.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/globals.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/has/attribute.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/has/builtin.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/has/extension.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/has/feature.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/has/warning.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/array.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/class.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/compar.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/complex.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/cont.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/dir.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/enum.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/error.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/eval.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/file.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/gc.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/hash.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/io.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/load.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/object.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/parse.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/proc.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/process.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/random.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/range.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/rational.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/re.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/select.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/signal.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/string.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/struct.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/thread.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/time.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/variable.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/intern/vm.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/interpreter.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/iterator.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/memory.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/method.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/module.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/newobj.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/rgengc.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/scan_args.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/special_consts.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/static_assert.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/stdalign.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/stdbool.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/symbol.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/value.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/value_type.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/variable.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/warning_push.h +mjit_c.$(OBJEXT): {$(VPATH)}internal/xmalloc.h +mjit_c.$(OBJEXT): {$(VPATH)}iseq.h +mjit_c.$(OBJEXT): {$(VPATH)}method.h +mjit_c.$(OBJEXT): {$(VPATH)}missing.h +mjit_c.$(OBJEXT): {$(VPATH)}mjit.h +mjit_c.$(OBJEXT): {$(VPATH)}mjit_c.c +mjit_c.$(OBJEXT): {$(VPATH)}mjit_c.h +mjit_c.$(OBJEXT): {$(VPATH)}mjit_c.rb +mjit_c.$(OBJEXT): {$(VPATH)}mjit_c.rbinc +mjit_c.$(OBJEXT): {$(VPATH)}mjit_sp_inc.inc +mjit_c.$(OBJEXT): {$(VPATH)}node.h +mjit_c.$(OBJEXT): {$(VPATH)}ruby_assert.h +mjit_c.$(OBJEXT): {$(VPATH)}ruby_atomic.h +mjit_c.$(OBJEXT): {$(VPATH)}shape.h +mjit_c.$(OBJEXT): {$(VPATH)}st.h +mjit_c.$(OBJEXT): {$(VPATH)}subst.h +mjit_c.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h +mjit_c.$(OBJEXT): {$(VPATH)}thread_native.h +mjit_c.$(OBJEXT): {$(VPATH)}vm_callinfo.h +mjit_c.$(OBJEXT): {$(VPATH)}vm_core.h +mjit_c.$(OBJEXT): {$(VPATH)}vm_exec.h +mjit_c.$(OBJEXT): {$(VPATH)}vm_insnhelper.h +mjit_c.$(OBJEXT): {$(VPATH)}vm_opts.h +mjit_c.$(OBJEXT): {$(VPATH)}yjit.h node.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h node.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h node.$(OBJEXT): $(CCAN_DIR)/list/list.h @@ -10654,7 +10152,6 @@ node.$(OBJEXT): $(top_srcdir)/internal/compilers.h node.$(OBJEXT): $(top_srcdir)/internal/gc.h node.$(OBJEXT): $(top_srcdir)/internal/hash.h node.$(OBJEXT): $(top_srcdir)/internal/imemo.h -node.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h node.$(OBJEXT): $(top_srcdir)/internal/serial.h node.$(OBJEXT): $(top_srcdir)/internal/static_assert.h node.$(OBJEXT): $(top_srcdir)/internal/variable.h @@ -10674,7 +10171,6 @@ node.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h node.$(OBJEXT): {$(VPATH)}config.h node.$(OBJEXT): {$(VPATH)}constant.h node.$(OBJEXT): {$(VPATH)}defines.h -node.$(OBJEXT): {$(VPATH)}encoding.h node.$(OBJEXT): {$(VPATH)}id.h node.$(OBJEXT): {$(VPATH)}id_table.h node.$(OBJEXT): {$(VPATH)}intern.h @@ -10717,7 +10213,6 @@ node.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h node.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h node.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h node.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -node.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h node.$(OBJEXT): {$(VPATH)}internal/attr/pure.h node.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h node.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -10750,15 +10245,6 @@ node.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h node.$(OBJEXT): {$(VPATH)}internal/ctype.h node.$(OBJEXT): {$(VPATH)}internal/dllexport.h node.$(OBJEXT): {$(VPATH)}internal/dosish.h -node.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -node.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -node.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -node.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -node.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -node.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -node.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -node.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -node.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h node.$(OBJEXT): {$(VPATH)}internal/error.h node.$(OBJEXT): {$(VPATH)}internal/eval.h node.$(OBJEXT): {$(VPATH)}internal/event.h @@ -10786,6 +10272,7 @@ node.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h node.$(OBJEXT): {$(VPATH)}internal/intern/error.h node.$(OBJEXT): {$(VPATH)}internal/intern/eval.h node.$(OBJEXT): {$(VPATH)}internal/intern/file.h +node.$(OBJEXT): {$(VPATH)}internal/intern/gc.h node.$(OBJEXT): {$(VPATH)}internal/intern/hash.h node.$(OBJEXT): {$(VPATH)}internal/intern/io.h node.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -10816,12 +10303,12 @@ node.$(OBJEXT): {$(VPATH)}internal/memory.h node.$(OBJEXT): {$(VPATH)}internal/method.h node.$(OBJEXT): {$(VPATH)}internal/module.h node.$(OBJEXT): {$(VPATH)}internal/newobj.h +node.$(OBJEXT): {$(VPATH)}internal/rgengc.h node.$(OBJEXT): {$(VPATH)}internal/scan_args.h node.$(OBJEXT): {$(VPATH)}internal/special_consts.h node.$(OBJEXT): {$(VPATH)}internal/static_assert.h node.$(OBJEXT): {$(VPATH)}internal/stdalign.h node.$(OBJEXT): {$(VPATH)}internal/stdbool.h -node.$(OBJEXT): {$(VPATH)}internal/stdckdint.h node.$(OBJEXT): {$(VPATH)}internal/symbol.h node.$(OBJEXT): {$(VPATH)}internal/value.h node.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -10832,12 +10319,8 @@ node.$(OBJEXT): {$(VPATH)}method.h node.$(OBJEXT): {$(VPATH)}missing.h node.$(OBJEXT): {$(VPATH)}node.c node.$(OBJEXT): {$(VPATH)}node.h -node.$(OBJEXT): {$(VPATH)}node_name.inc -node.$(OBJEXT): {$(VPATH)}onigmo.h -node.$(OBJEXT): {$(VPATH)}oniguruma.h node.$(OBJEXT): {$(VPATH)}ruby_assert.h node.$(OBJEXT): {$(VPATH)}ruby_atomic.h -node.$(OBJEXT): {$(VPATH)}rubyparser.h node.$(OBJEXT): {$(VPATH)}shape.h node.$(OBJEXT): {$(VPATH)}st.h node.$(OBJEXT): {$(VPATH)}subst.h @@ -10845,226 +10328,8 @@ node.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h node.$(OBJEXT): {$(VPATH)}thread_native.h node.$(OBJEXT): {$(VPATH)}vm_core.h node.$(OBJEXT): {$(VPATH)}vm_opts.h -node_dump.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -node_dump.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -node_dump.$(OBJEXT): $(CCAN_DIR)/list/list.h -node_dump.$(OBJEXT): $(CCAN_DIR)/str/str.h -node_dump.$(OBJEXT): $(hdrdir)/ruby/ruby.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/array.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/bignum.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/bits.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/class.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/compilers.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/complex.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/fixnum.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/hash.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/numeric.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/parse.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/rational.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/serial.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/static_assert.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/variable.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/vm.h -node_dump.$(OBJEXT): $(top_srcdir)/internal/warnings.h -node_dump.$(OBJEXT): {$(VPATH)}assert.h -node_dump.$(OBJEXT): {$(VPATH)}atomic.h -node_dump.$(OBJEXT): {$(VPATH)}backward/2/assume.h -node_dump.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -node_dump.$(OBJEXT): {$(VPATH)}backward/2/bool.h -node_dump.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h -node_dump.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h -node_dump.$(OBJEXT): {$(VPATH)}backward/2/limits.h -node_dump.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -node_dump.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -node_dump.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -node_dump.$(OBJEXT): {$(VPATH)}config.h -node_dump.$(OBJEXT): {$(VPATH)}constant.h -node_dump.$(OBJEXT): {$(VPATH)}debug_counter.h -node_dump.$(OBJEXT): {$(VPATH)}defines.h -node_dump.$(OBJEXT): {$(VPATH)}encoding.h -node_dump.$(OBJEXT): {$(VPATH)}id.h -node_dump.$(OBJEXT): {$(VPATH)}id_table.h -node_dump.$(OBJEXT): {$(VPATH)}intern.h -node_dump.$(OBJEXT): {$(VPATH)}internal.h -node_dump.$(OBJEXT): {$(VPATH)}internal/abi.h -node_dump.$(OBJEXT): {$(VPATH)}internal/anyargs.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h -node_dump.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h -node_dump.$(OBJEXT): {$(VPATH)}internal/assume.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/const.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/error.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/format.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -node_dump.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h -node_dump.$(OBJEXT): {$(VPATH)}internal/cast.h -node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -node_dump.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -node_dump.$(OBJEXT): {$(VPATH)}internal/config.h -node_dump.$(OBJEXT): {$(VPATH)}internal/constant_p.h -node_dump.$(OBJEXT): {$(VPATH)}internal/core.h -node_dump.$(OBJEXT): {$(VPATH)}internal/core/rarray.h -node_dump.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h -node_dump.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h -node_dump.$(OBJEXT): {$(VPATH)}internal/core/rclass.h -node_dump.$(OBJEXT): {$(VPATH)}internal/core/rdata.h -node_dump.$(OBJEXT): {$(VPATH)}internal/core/rfile.h -node_dump.$(OBJEXT): {$(VPATH)}internal/core/rhash.h -node_dump.$(OBJEXT): {$(VPATH)}internal/core/robject.h -node_dump.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h -node_dump.$(OBJEXT): {$(VPATH)}internal/core/rstring.h -node_dump.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h -node_dump.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h -node_dump.$(OBJEXT): {$(VPATH)}internal/ctype.h -node_dump.$(OBJEXT): {$(VPATH)}internal/dllexport.h -node_dump.$(OBJEXT): {$(VPATH)}internal/dosish.h -node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -node_dump.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h -node_dump.$(OBJEXT): {$(VPATH)}internal/error.h -node_dump.$(OBJEXT): {$(VPATH)}internal/eval.h -node_dump.$(OBJEXT): {$(VPATH)}internal/event.h -node_dump.$(OBJEXT): {$(VPATH)}internal/fl_type.h -node_dump.$(OBJEXT): {$(VPATH)}internal/gc.h -node_dump.$(OBJEXT): {$(VPATH)}internal/glob.h -node_dump.$(OBJEXT): {$(VPATH)}internal/globals.h -node_dump.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -node_dump.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -node_dump.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -node_dump.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -node_dump.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -node_dump.$(OBJEXT): {$(VPATH)}internal/has/extension.h -node_dump.$(OBJEXT): {$(VPATH)}internal/has/feature.h -node_dump.$(OBJEXT): {$(VPATH)}internal/has/warning.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/array.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/class.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/compar.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/complex.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/cont.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/dir.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/enum.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/error.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/eval.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/file.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/hash.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/io.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/load.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/object.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/parse.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/proc.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/process.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/random.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/range.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/rational.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/re.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/select.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/signal.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/string.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/struct.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/thread.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/time.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/variable.h -node_dump.$(OBJEXT): {$(VPATH)}internal/intern/vm.h -node_dump.$(OBJEXT): {$(VPATH)}internal/interpreter.h -node_dump.$(OBJEXT): {$(VPATH)}internal/iterator.h -node_dump.$(OBJEXT): {$(VPATH)}internal/memory.h -node_dump.$(OBJEXT): {$(VPATH)}internal/method.h -node_dump.$(OBJEXT): {$(VPATH)}internal/module.h -node_dump.$(OBJEXT): {$(VPATH)}internal/newobj.h -node_dump.$(OBJEXT): {$(VPATH)}internal/scan_args.h -node_dump.$(OBJEXT): {$(VPATH)}internal/special_consts.h -node_dump.$(OBJEXT): {$(VPATH)}internal/static_assert.h -node_dump.$(OBJEXT): {$(VPATH)}internal/stdalign.h -node_dump.$(OBJEXT): {$(VPATH)}internal/stdbool.h -node_dump.$(OBJEXT): {$(VPATH)}internal/stdckdint.h -node_dump.$(OBJEXT): {$(VPATH)}internal/symbol.h -node_dump.$(OBJEXT): {$(VPATH)}internal/value.h -node_dump.$(OBJEXT): {$(VPATH)}internal/value_type.h -node_dump.$(OBJEXT): {$(VPATH)}internal/variable.h -node_dump.$(OBJEXT): {$(VPATH)}internal/warning_push.h -node_dump.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -node_dump.$(OBJEXT): {$(VPATH)}method.h -node_dump.$(OBJEXT): {$(VPATH)}missing.h -node_dump.$(OBJEXT): {$(VPATH)}node.h -node_dump.$(OBJEXT): {$(VPATH)}node_dump.c -node_dump.$(OBJEXT): {$(VPATH)}onigmo.h -node_dump.$(OBJEXT): {$(VPATH)}oniguruma.h -node_dump.$(OBJEXT): {$(VPATH)}ruby_assert.h -node_dump.$(OBJEXT): {$(VPATH)}ruby_atomic.h -node_dump.$(OBJEXT): {$(VPATH)}rubyparser.h -node_dump.$(OBJEXT): {$(VPATH)}shape.h -node_dump.$(OBJEXT): {$(VPATH)}st.h -node_dump.$(OBJEXT): {$(VPATH)}subst.h -node_dump.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -node_dump.$(OBJEXT): {$(VPATH)}thread_native.h -node_dump.$(OBJEXT): {$(VPATH)}vm_core.h -node_dump.$(OBJEXT): {$(VPATH)}vm_debug.h -node_dump.$(OBJEXT): {$(VPATH)}vm_opts.h -node_dump.$(OBJEXT): {$(VPATH)}vm_sync.h -numeric.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -numeric.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -numeric.$(OBJEXT): $(CCAN_DIR)/list/list.h -numeric.$(OBJEXT): $(CCAN_DIR)/str/str.h numeric.$(OBJEXT): $(hdrdir)/ruby/ruby.h numeric.$(OBJEXT): $(top_srcdir)/internal/array.h -numeric.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h numeric.$(OBJEXT): $(top_srcdir)/internal/bignum.h numeric.$(OBJEXT): $(top_srcdir)/internal/bits.h numeric.$(OBJEXT): $(top_srcdir)/internal/class.h @@ -11074,11 +10339,9 @@ numeric.$(OBJEXT): $(top_srcdir)/internal/enumerator.h numeric.$(OBJEXT): $(top_srcdir)/internal/fixnum.h numeric.$(OBJEXT): $(top_srcdir)/internal/gc.h numeric.$(OBJEXT): $(top_srcdir)/internal/hash.h -numeric.$(OBJEXT): $(top_srcdir)/internal/imemo.h numeric.$(OBJEXT): $(top_srcdir)/internal/numeric.h numeric.$(OBJEXT): $(top_srcdir)/internal/object.h numeric.$(OBJEXT): $(top_srcdir)/internal/rational.h -numeric.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h numeric.$(OBJEXT): $(top_srcdir)/internal/serial.h numeric.$(OBJEXT): $(top_srcdir)/internal/static_assert.h numeric.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -11087,7 +10350,6 @@ numeric.$(OBJEXT): $(top_srcdir)/internal/variable.h numeric.$(OBJEXT): $(top_srcdir)/internal/vm.h numeric.$(OBJEXT): $(top_srcdir)/internal/warnings.h numeric.$(OBJEXT): {$(VPATH)}assert.h -numeric.$(OBJEXT): {$(VPATH)}atomic.h numeric.$(OBJEXT): {$(VPATH)}backward/2/assume.h numeric.$(OBJEXT): {$(VPATH)}backward/2/attributes.h numeric.$(OBJEXT): {$(VPATH)}backward/2/bool.h @@ -11144,7 +10406,6 @@ numeric.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h numeric.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h numeric.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h numeric.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -numeric.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h numeric.$(OBJEXT): {$(VPATH)}internal/attr/pure.h numeric.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h numeric.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -11213,6 +10474,7 @@ numeric.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h numeric.$(OBJEXT): {$(VPATH)}internal/intern/error.h numeric.$(OBJEXT): {$(VPATH)}internal/intern/eval.h numeric.$(OBJEXT): {$(VPATH)}internal/intern/file.h +numeric.$(OBJEXT): {$(VPATH)}internal/intern/gc.h numeric.$(OBJEXT): {$(VPATH)}internal/intern/hash.h numeric.$(OBJEXT): {$(VPATH)}internal/intern/io.h numeric.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -11243,42 +10505,33 @@ numeric.$(OBJEXT): {$(VPATH)}internal/memory.h numeric.$(OBJEXT): {$(VPATH)}internal/method.h numeric.$(OBJEXT): {$(VPATH)}internal/module.h numeric.$(OBJEXT): {$(VPATH)}internal/newobj.h +numeric.$(OBJEXT): {$(VPATH)}internal/rgengc.h numeric.$(OBJEXT): {$(VPATH)}internal/scan_args.h numeric.$(OBJEXT): {$(VPATH)}internal/special_consts.h numeric.$(OBJEXT): {$(VPATH)}internal/static_assert.h numeric.$(OBJEXT): {$(VPATH)}internal/stdalign.h numeric.$(OBJEXT): {$(VPATH)}internal/stdbool.h -numeric.$(OBJEXT): {$(VPATH)}internal/stdckdint.h numeric.$(OBJEXT): {$(VPATH)}internal/symbol.h numeric.$(OBJEXT): {$(VPATH)}internal/value.h numeric.$(OBJEXT): {$(VPATH)}internal/value_type.h numeric.$(OBJEXT): {$(VPATH)}internal/variable.h numeric.$(OBJEXT): {$(VPATH)}internal/warning_push.h numeric.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -numeric.$(OBJEXT): {$(VPATH)}method.h numeric.$(OBJEXT): {$(VPATH)}missing.h -numeric.$(OBJEXT): {$(VPATH)}node.h numeric.$(OBJEXT): {$(VPATH)}numeric.c numeric.$(OBJEXT): {$(VPATH)}numeric.rbinc numeric.$(OBJEXT): {$(VPATH)}onigmo.h numeric.$(OBJEXT): {$(VPATH)}oniguruma.h numeric.$(OBJEXT): {$(VPATH)}ruby_assert.h -numeric.$(OBJEXT): {$(VPATH)}ruby_atomic.h -numeric.$(OBJEXT): {$(VPATH)}rubyparser.h numeric.$(OBJEXT): {$(VPATH)}shape.h numeric.$(OBJEXT): {$(VPATH)}st.h numeric.$(OBJEXT): {$(VPATH)}subst.h -numeric.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -numeric.$(OBJEXT): {$(VPATH)}thread_native.h numeric.$(OBJEXT): {$(VPATH)}util.h -numeric.$(OBJEXT): {$(VPATH)}vm_core.h -numeric.$(OBJEXT): {$(VPATH)}vm_opts.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): $(hdrdir)/ruby/version.h object.$(OBJEXT): $(top_srcdir)/internal/array.h object.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h object.$(OBJEXT): $(top_srcdir)/internal/bignum.h @@ -11293,9 +10546,7 @@ 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 -object.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h object.$(OBJEXT): $(top_srcdir)/internal/serial.h -object.$(OBJEXT): $(top_srcdir)/internal/st.h object.$(OBJEXT): $(top_srcdir)/internal/static_assert.h object.$(OBJEXT): $(top_srcdir)/internal/string.h object.$(OBJEXT): $(top_srcdir)/internal/struct.h @@ -11317,7 +10568,6 @@ object.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h object.$(OBJEXT): {$(VPATH)}builtin.h object.$(OBJEXT): {$(VPATH)}config.h object.$(OBJEXT): {$(VPATH)}constant.h -object.$(OBJEXT): {$(VPATH)}debug_counter.h object.$(OBJEXT): {$(VPATH)}defines.h object.$(OBJEXT): {$(VPATH)}encoding.h object.$(OBJEXT): {$(VPATH)}id.h @@ -11362,7 +10612,6 @@ object.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h object.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h object.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h object.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -object.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h object.$(OBJEXT): {$(VPATH)}internal/attr/pure.h object.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h object.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -11431,6 +10680,7 @@ object.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h object.$(OBJEXT): {$(VPATH)}internal/intern/error.h object.$(OBJEXT): {$(VPATH)}internal/intern/eval.h object.$(OBJEXT): {$(VPATH)}internal/intern/file.h +object.$(OBJEXT): {$(VPATH)}internal/intern/gc.h object.$(OBJEXT): {$(VPATH)}internal/intern/hash.h object.$(OBJEXT): {$(VPATH)}internal/intern/io.h object.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -11461,13 +10711,12 @@ object.$(OBJEXT): {$(VPATH)}internal/memory.h object.$(OBJEXT): {$(VPATH)}internal/method.h object.$(OBJEXT): {$(VPATH)}internal/module.h object.$(OBJEXT): {$(VPATH)}internal/newobj.h +object.$(OBJEXT): {$(VPATH)}internal/rgengc.h object.$(OBJEXT): {$(VPATH)}internal/scan_args.h object.$(OBJEXT): {$(VPATH)}internal/special_consts.h -object.$(OBJEXT): {$(VPATH)}internal/st.h object.$(OBJEXT): {$(VPATH)}internal/static_assert.h object.$(OBJEXT): {$(VPATH)}internal/stdalign.h object.$(OBJEXT): {$(VPATH)}internal/stdbool.h -object.$(OBJEXT): {$(VPATH)}internal/stdckdint.h object.$(OBJEXT): {$(VPATH)}internal/symbol.h object.$(OBJEXT): {$(VPATH)}internal/value.h object.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -11486,7 +10735,6 @@ 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)}rubyparser.h object.$(OBJEXT): {$(VPATH)}shape.h object.$(OBJEXT): {$(VPATH)}st.h object.$(OBJEXT): {$(VPATH)}subst.h @@ -11495,31 +10743,18 @@ 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_debug.h object.$(OBJEXT): {$(VPATH)}vm_opts.h -object.$(OBJEXT): {$(VPATH)}vm_sync.h -object.$(OBJEXT): {$(VPATH)}yjit.h -pack.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -pack.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -pack.$(OBJEXT): $(CCAN_DIR)/list/list.h -pack.$(OBJEXT): $(CCAN_DIR)/str/str.h pack.$(OBJEXT): $(hdrdir)/ruby/ruby.h pack.$(OBJEXT): $(top_srcdir)/internal/array.h -pack.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h pack.$(OBJEXT): $(top_srcdir)/internal/bits.h pack.$(OBJEXT): $(top_srcdir)/internal/compilers.h pack.$(OBJEXT): $(top_srcdir)/internal/gc.h -pack.$(OBJEXT): $(top_srcdir)/internal/imemo.h -pack.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h -pack.$(OBJEXT): $(top_srcdir)/internal/serial.h pack.$(OBJEXT): $(top_srcdir)/internal/static_assert.h pack.$(OBJEXT): $(top_srcdir)/internal/string.h pack.$(OBJEXT): $(top_srcdir)/internal/symbol.h pack.$(OBJEXT): $(top_srcdir)/internal/variable.h -pack.$(OBJEXT): $(top_srcdir)/internal/vm.h pack.$(OBJEXT): $(top_srcdir)/internal/warnings.h pack.$(OBJEXT): {$(VPATH)}assert.h -pack.$(OBJEXT): {$(VPATH)}atomic.h pack.$(OBJEXT): {$(VPATH)}backward/2/assume.h pack.$(OBJEXT): {$(VPATH)}backward/2/attributes.h pack.$(OBJEXT): {$(VPATH)}backward/2/bool.h @@ -11534,7 +10769,6 @@ pack.$(OBJEXT): {$(VPATH)}config.h pack.$(OBJEXT): {$(VPATH)}constant.h pack.$(OBJEXT): {$(VPATH)}defines.h pack.$(OBJEXT): {$(VPATH)}encoding.h -pack.$(OBJEXT): {$(VPATH)}id.h pack.$(OBJEXT): {$(VPATH)}id_table.h pack.$(OBJEXT): {$(VPATH)}intern.h pack.$(OBJEXT): {$(VPATH)}internal.h @@ -11576,7 +10810,6 @@ pack.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h pack.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h pack.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h pack.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -pack.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h pack.$(OBJEXT): {$(VPATH)}internal/attr/pure.h pack.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h pack.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -11645,6 +10878,7 @@ pack.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h pack.$(OBJEXT): {$(VPATH)}internal/intern/error.h pack.$(OBJEXT): {$(VPATH)}internal/intern/eval.h pack.$(OBJEXT): {$(VPATH)}internal/intern/file.h +pack.$(OBJEXT): {$(VPATH)}internal/intern/gc.h pack.$(OBJEXT): {$(VPATH)}internal/intern/hash.h pack.$(OBJEXT): {$(VPATH)}internal/intern/io.h pack.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -11675,45 +10909,30 @@ pack.$(OBJEXT): {$(VPATH)}internal/memory.h pack.$(OBJEXT): {$(VPATH)}internal/method.h pack.$(OBJEXT): {$(VPATH)}internal/module.h pack.$(OBJEXT): {$(VPATH)}internal/newobj.h +pack.$(OBJEXT): {$(VPATH)}internal/rgengc.h pack.$(OBJEXT): {$(VPATH)}internal/scan_args.h pack.$(OBJEXT): {$(VPATH)}internal/special_consts.h pack.$(OBJEXT): {$(VPATH)}internal/static_assert.h pack.$(OBJEXT): {$(VPATH)}internal/stdalign.h pack.$(OBJEXT): {$(VPATH)}internal/stdbool.h -pack.$(OBJEXT): {$(VPATH)}internal/stdckdint.h pack.$(OBJEXT): {$(VPATH)}internal/symbol.h pack.$(OBJEXT): {$(VPATH)}internal/value.h pack.$(OBJEXT): {$(VPATH)}internal/value_type.h pack.$(OBJEXT): {$(VPATH)}internal/variable.h pack.$(OBJEXT): {$(VPATH)}internal/warning_push.h pack.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -pack.$(OBJEXT): {$(VPATH)}method.h pack.$(OBJEXT): {$(VPATH)}missing.h -pack.$(OBJEXT): {$(VPATH)}node.h pack.$(OBJEXT): {$(VPATH)}onigmo.h pack.$(OBJEXT): {$(VPATH)}oniguruma.h pack.$(OBJEXT): {$(VPATH)}pack.c pack.$(OBJEXT): {$(VPATH)}pack.rbinc -pack.$(OBJEXT): {$(VPATH)}ruby_assert.h -pack.$(OBJEXT): {$(VPATH)}ruby_atomic.h -pack.$(OBJEXT): {$(VPATH)}rubyparser.h pack.$(OBJEXT): {$(VPATH)}shape.h pack.$(OBJEXT): {$(VPATH)}st.h pack.$(OBJEXT): {$(VPATH)}subst.h -pack.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -pack.$(OBJEXT): {$(VPATH)}thread_native.h pack.$(OBJEXT): {$(VPATH)}util.h -pack.$(OBJEXT): {$(VPATH)}vm_core.h -pack.$(OBJEXT): {$(VPATH)}vm_opts.h -parse.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -parse.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -parse.$(OBJEXT): $(CCAN_DIR)/list/list.h -parse.$(OBJEXT): $(CCAN_DIR)/str/str.h parse.$(OBJEXT): $(hdrdir)/ruby.h parse.$(OBJEXT): $(hdrdir)/ruby/ruby.h -parse.$(OBJEXT): $(hdrdir)/ruby/version.h parse.$(OBJEXT): $(top_srcdir)/internal/array.h -parse.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h parse.$(OBJEXT): $(top_srcdir)/internal/bignum.h parse.$(OBJEXT): $(top_srcdir)/internal/bits.h parse.$(OBJEXT): $(top_srcdir)/internal/compile.h @@ -11730,8 +10949,6 @@ parse.$(OBJEXT): $(top_srcdir)/internal/numeric.h parse.$(OBJEXT): $(top_srcdir)/internal/parse.h parse.$(OBJEXT): $(top_srcdir)/internal/rational.h parse.$(OBJEXT): $(top_srcdir)/internal/re.h -parse.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h -parse.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h parse.$(OBJEXT): $(top_srcdir)/internal/serial.h parse.$(OBJEXT): $(top_srcdir)/internal/static_assert.h parse.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -11741,7 +10958,6 @@ parse.$(OBJEXT): $(top_srcdir)/internal/variable.h parse.$(OBJEXT): $(top_srcdir)/internal/vm.h parse.$(OBJEXT): $(top_srcdir)/internal/warnings.h parse.$(OBJEXT): {$(VPATH)}assert.h -parse.$(OBJEXT): {$(VPATH)}atomic.h parse.$(OBJEXT): {$(VPATH)}backward/2/assume.h parse.$(OBJEXT): {$(VPATH)}backward/2/attributes.h parse.$(OBJEXT): {$(VPATH)}backward/2/bool.h @@ -11798,7 +11014,6 @@ parse.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h parse.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h parse.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h parse.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -parse.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h parse.$(OBJEXT): {$(VPATH)}internal/attr/pure.h parse.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h parse.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -11867,6 +11082,7 @@ parse.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h parse.$(OBJEXT): {$(VPATH)}internal/intern/error.h parse.$(OBJEXT): {$(VPATH)}internal/intern/eval.h parse.$(OBJEXT): {$(VPATH)}internal/intern/file.h +parse.$(OBJEXT): {$(VPATH)}internal/intern/gc.h parse.$(OBJEXT): {$(VPATH)}internal/intern/hash.h parse.$(OBJEXT): {$(VPATH)}internal/intern/io.h parse.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -11897,12 +11113,12 @@ parse.$(OBJEXT): {$(VPATH)}internal/memory.h parse.$(OBJEXT): {$(VPATH)}internal/method.h parse.$(OBJEXT): {$(VPATH)}internal/module.h parse.$(OBJEXT): {$(VPATH)}internal/newobj.h +parse.$(OBJEXT): {$(VPATH)}internal/rgengc.h parse.$(OBJEXT): {$(VPATH)}internal/scan_args.h parse.$(OBJEXT): {$(VPATH)}internal/special_consts.h parse.$(OBJEXT): {$(VPATH)}internal/static_assert.h parse.$(OBJEXT): {$(VPATH)}internal/stdalign.h parse.$(OBJEXT): {$(VPATH)}internal/stdbool.h -parse.$(OBJEXT): {$(VPATH)}internal/stdckdint.h parse.$(OBJEXT): {$(VPATH)}internal/symbol.h parse.$(OBJEXT): {$(VPATH)}internal/value.h parse.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -11911,7 +11127,6 @@ parse.$(OBJEXT): {$(VPATH)}internal/warning_push.h parse.$(OBJEXT): {$(VPATH)}internal/xmalloc.h parse.$(OBJEXT): {$(VPATH)}io.h parse.$(OBJEXT): {$(VPATH)}lex.c -parse.$(OBJEXT): {$(VPATH)}method.h parse.$(OBJEXT): {$(VPATH)}missing.h parse.$(OBJEXT): {$(VPATH)}node.h parse.$(OBJEXT): {$(VPATH)}onigmo.h @@ -11919,1081 +11134,22 @@ parse.$(OBJEXT): {$(VPATH)}oniguruma.h parse.$(OBJEXT): {$(VPATH)}parse.c parse.$(OBJEXT): {$(VPATH)}parse.h parse.$(OBJEXT): {$(VPATH)}parse.y -parse.$(OBJEXT): {$(VPATH)}parser_node.h -parse.$(OBJEXT): {$(VPATH)}parser_st.h parse.$(OBJEXT): {$(VPATH)}probes.dmyh parse.$(OBJEXT): {$(VPATH)}probes.h parse.$(OBJEXT): {$(VPATH)}ractor.h parse.$(OBJEXT): {$(VPATH)}regenc.h parse.$(OBJEXT): {$(VPATH)}regex.h parse.$(OBJEXT): {$(VPATH)}ruby_assert.h -parse.$(OBJEXT): {$(VPATH)}ruby_atomic.h -parse.$(OBJEXT): {$(VPATH)}rubyparser.h parse.$(OBJEXT): {$(VPATH)}shape.h parse.$(OBJEXT): {$(VPATH)}st.h parse.$(OBJEXT): {$(VPATH)}subst.h parse.$(OBJEXT): {$(VPATH)}symbol.h -parse.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -parse.$(OBJEXT): {$(VPATH)}thread_native.h parse.$(OBJEXT): {$(VPATH)}util.h -parse.$(OBJEXT): {$(VPATH)}vm_core.h -parse.$(OBJEXT): {$(VPATH)}vm_opts.h -parser_st.$(OBJEXT): $(top_srcdir)/internal/compilers.h -parser_st.$(OBJEXT): $(top_srcdir)/internal/static_assert.h -parser_st.$(OBJEXT): $(top_srcdir)/internal/warnings.h -parser_st.$(OBJEXT): {$(VPATH)}assert.h -parser_st.$(OBJEXT): {$(VPATH)}backward/2/assume.h -parser_st.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -parser_st.$(OBJEXT): {$(VPATH)}backward/2/bool.h -parser_st.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h -parser_st.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -parser_st.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -parser_st.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -parser_st.$(OBJEXT): {$(VPATH)}config.h -parser_st.$(OBJEXT): {$(VPATH)}defines.h -parser_st.$(OBJEXT): {$(VPATH)}internal/assume.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/const.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/error.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/format.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -parser_st.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -parser_st.$(OBJEXT): {$(VPATH)}internal/cast.h -parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -parser_st.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -parser_st.$(OBJEXT): {$(VPATH)}internal/config.h -parser_st.$(OBJEXT): {$(VPATH)}internal/dllexport.h -parser_st.$(OBJEXT): {$(VPATH)}internal/dosish.h -parser_st.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -parser_st.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -parser_st.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -parser_st.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -parser_st.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -parser_st.$(OBJEXT): {$(VPATH)}internal/has/extension.h -parser_st.$(OBJEXT): {$(VPATH)}internal/has/feature.h -parser_st.$(OBJEXT): {$(VPATH)}internal/has/warning.h -parser_st.$(OBJEXT): {$(VPATH)}internal/static_assert.h -parser_st.$(OBJEXT): {$(VPATH)}internal/stdalign.h -parser_st.$(OBJEXT): {$(VPATH)}internal/stdbool.h -parser_st.$(OBJEXT): {$(VPATH)}internal/warning_push.h -parser_st.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -parser_st.$(OBJEXT): {$(VPATH)}missing.h -parser_st.$(OBJEXT): {$(VPATH)}parser_bits.h -parser_st.$(OBJEXT): {$(VPATH)}parser_st.c -parser_st.$(OBJEXT): {$(VPATH)}parser_st.h -parser_st.$(OBJEXT): {$(VPATH)}parser_value.h -parser_st.$(OBJEXT): {$(VPATH)}st.c -prism/api_node.$(OBJEXT): $(hdrdir)/ruby.h -prism/api_node.$(OBJEXT): $(hdrdir)/ruby/ruby.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/encoding.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/extension.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/node.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/options.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/pack.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/parser.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/prism.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/regexp.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -prism/api_node.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h -prism/api_node.$(OBJEXT): {$(VPATH)}assert.h -prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/assume.h -prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/bool.h -prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h -prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/limits.h -prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -prism/api_node.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -prism/api_node.$(OBJEXT): {$(VPATH)}config.h -prism/api_node.$(OBJEXT): {$(VPATH)}defines.h -prism/api_node.$(OBJEXT): {$(VPATH)}encoding.h -prism/api_node.$(OBJEXT): {$(VPATH)}intern.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/abi.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/anyargs.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/assume.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/const.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/error.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/format.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/cast.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/config.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/constant_p.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/core.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rarray.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rclass.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rdata.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rfile.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rhash.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/robject.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rstring.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/ctype.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/dllexport.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/dosish.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/error.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/eval.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/event.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/fl_type.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/gc.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/glob.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/globals.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/extension.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/feature.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/has/warning.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/array.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/class.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/compar.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/complex.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/cont.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/dir.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/enum.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/error.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/eval.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/file.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/hash.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/io.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/load.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/object.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/parse.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/proc.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/process.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/random.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/range.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/rational.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/re.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/select.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/signal.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/string.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/struct.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/thread.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/time.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/variable.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/intern/vm.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/interpreter.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/iterator.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/memory.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/method.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/module.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/newobj.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/scan_args.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/special_consts.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/static_assert.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/stdalign.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/stdbool.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/stdckdint.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/symbol.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/value.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/value_type.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/variable.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/warning_push.h -prism/api_node.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -prism/api_node.$(OBJEXT): {$(VPATH)}missing.h -prism/api_node.$(OBJEXT): {$(VPATH)}onigmo.h -prism/api_node.$(OBJEXT): {$(VPATH)}oniguruma.h -prism/api_node.$(OBJEXT): {$(VPATH)}prism/api_node.c -prism/api_node.$(OBJEXT): {$(VPATH)}prism/ast.h -prism/api_node.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -prism/api_node.$(OBJEXT): {$(VPATH)}prism/version.h -prism/api_node.$(OBJEXT): {$(VPATH)}st.h -prism/api_node.$(OBJEXT): {$(VPATH)}subst.h -prism/api_pack.$(OBJEXT): $(hdrdir)/ruby.h -prism/api_pack.$(OBJEXT): $(hdrdir)/ruby/ruby.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/api_pack.c -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/encoding.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/extension.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/node.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/options.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/pack.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/parser.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/prism.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/regexp.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -prism/api_pack.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h -prism/api_pack.$(OBJEXT): {$(VPATH)}assert.h -prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/assume.h -prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/bool.h -prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h -prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/limits.h -prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -prism/api_pack.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -prism/api_pack.$(OBJEXT): {$(VPATH)}config.h -prism/api_pack.$(OBJEXT): {$(VPATH)}defines.h -prism/api_pack.$(OBJEXT): {$(VPATH)}encoding.h -prism/api_pack.$(OBJEXT): {$(VPATH)}intern.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/abi.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/anyargs.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/assume.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/const.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/error.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/format.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/cast.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/config.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/constant_p.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rarray.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rclass.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rdata.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rfile.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rhash.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/robject.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rstring.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/ctype.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/dllexport.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/dosish.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/error.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/eval.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/event.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/fl_type.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/gc.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/glob.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/globals.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/extension.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/feature.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/has/warning.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/array.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/class.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/compar.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/complex.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/cont.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/dir.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/enum.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/error.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/eval.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/file.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/hash.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/io.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/load.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/object.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/parse.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/proc.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/process.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/random.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/range.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/rational.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/re.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/select.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/signal.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/string.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/struct.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/thread.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/time.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/variable.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/intern/vm.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/interpreter.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/iterator.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/memory.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/method.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/module.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/newobj.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/scan_args.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/special_consts.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/static_assert.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/stdalign.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/stdbool.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/stdckdint.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/symbol.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/value.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/value_type.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/variable.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/warning_push.h -prism/api_pack.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -prism/api_pack.$(OBJEXT): {$(VPATH)}missing.h -prism/api_pack.$(OBJEXT): {$(VPATH)}onigmo.h -prism/api_pack.$(OBJEXT): {$(VPATH)}oniguruma.h -prism/api_pack.$(OBJEXT): {$(VPATH)}prism/ast.h -prism/api_pack.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -prism/api_pack.$(OBJEXT): {$(VPATH)}prism/version.h -prism/api_pack.$(OBJEXT): {$(VPATH)}st.h -prism/api_pack.$(OBJEXT): {$(VPATH)}subst.h -prism/diagnostic.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/diagnostic.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism/diagnostic.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/diagnostic.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism/diagnostic.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -prism/diagnostic.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -prism/diagnostic.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/diagnostic.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/diagnostic.$(OBJEXT): {$(VPATH)}prism/ast.h -prism/diagnostic.$(OBJEXT): {$(VPATH)}prism/diagnostic.c -prism/diagnostic.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -prism/encoding.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/encoding.$(OBJEXT): $(top_srcdir)/prism/encoding.c -prism/encoding.$(OBJEXT): $(top_srcdir)/prism/encoding.h -prism/encoding.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -prism/extension.$(OBJEXT): $(hdrdir)/ruby.h -prism/extension.$(OBJEXT): $(hdrdir)/ruby/ruby.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/encoding.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/extension.c -prism/extension.$(OBJEXT): $(top_srcdir)/prism/extension.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/node.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/options.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/pack.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/parser.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/prism.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/regexp.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -prism/extension.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h -prism/extension.$(OBJEXT): {$(VPATH)}assert.h -prism/extension.$(OBJEXT): {$(VPATH)}backward/2/assume.h -prism/extension.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -prism/extension.$(OBJEXT): {$(VPATH)}backward/2/bool.h -prism/extension.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h -prism/extension.$(OBJEXT): {$(VPATH)}backward/2/limits.h -prism/extension.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -prism/extension.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -prism/extension.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -prism/extension.$(OBJEXT): {$(VPATH)}config.h -prism/extension.$(OBJEXT): {$(VPATH)}defines.h -prism/extension.$(OBJEXT): {$(VPATH)}encoding.h -prism/extension.$(OBJEXT): {$(VPATH)}intern.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/abi.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/anyargs.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/assume.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/const.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/error.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/format.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/cast.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/config.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/constant_p.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/core.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rarray.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rclass.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rdata.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rfile.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rhash.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/core/robject.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rstring.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/ctype.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/dllexport.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/dosish.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/error.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/eval.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/event.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/fl_type.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/gc.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/glob.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/globals.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/has/extension.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/has/feature.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/has/warning.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/array.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/class.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/compar.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/complex.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/cont.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/dir.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/enum.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/error.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/eval.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/file.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/hash.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/io.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/load.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/object.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/parse.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/proc.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/process.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/random.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/range.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/rational.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/re.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/select.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/signal.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/string.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/struct.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/thread.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/time.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/variable.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/intern/vm.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/interpreter.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/iterator.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/memory.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/method.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/module.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/newobj.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/scan_args.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/special_consts.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/static_assert.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/stdalign.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/stdbool.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/stdckdint.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/symbol.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/value.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/value_type.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/variable.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/warning_push.h -prism/extension.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -prism/extension.$(OBJEXT): {$(VPATH)}missing.h -prism/extension.$(OBJEXT): {$(VPATH)}onigmo.h -prism/extension.$(OBJEXT): {$(VPATH)}oniguruma.h -prism/extension.$(OBJEXT): {$(VPATH)}prism/ast.h -prism/extension.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -prism/extension.$(OBJEXT): {$(VPATH)}prism/version.h -prism/extension.$(OBJEXT): {$(VPATH)}st.h -prism/extension.$(OBJEXT): {$(VPATH)}subst.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/encoding.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/node.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/options.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/pack.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/parser.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/prism.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/regexp.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -prism/node.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h -prism/node.$(OBJEXT): {$(VPATH)}prism/ast.h -prism/node.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -prism/node.$(OBJEXT): {$(VPATH)}prism/node.c -prism/options.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/options.$(OBJEXT): $(top_srcdir)/prism/options.c -prism/options.$(OBJEXT): $(top_srcdir)/prism/options.h -prism/options.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/options.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/options.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/pack.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/pack.$(OBJEXT): $(top_srcdir)/prism/pack.c -prism/pack.$(OBJEXT): $(top_srcdir)/prism/pack.h -prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/encoding.h -prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/options.h -prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/parser.h -prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/prettyprint.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -prism/prettyprint.$(OBJEXT): {$(VPATH)}prism/ast.h -prism/prettyprint.$(OBJEXT): {$(VPATH)}prism/prettyprint.c -prism/prism.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/encoding.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/node.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/options.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/pack.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/parser.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/prism.c -prism/prism.$(OBJEXT): $(top_srcdir)/prism/prism.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/regexp.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h -prism/prism.$(OBJEXT): $(top_srcdir)/prism/version.h -prism/prism.$(OBJEXT): {$(VPATH)}prism/ast.h -prism/prism.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -prism/prism.$(OBJEXT): {$(VPATH)}prism/version.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/encoding.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/options.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/parser.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/regexp.c -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/regexp.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/regexp.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -prism/regexp.$(OBJEXT): {$(VPATH)}prism/ast.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/encoding.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/node.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/options.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/pack.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/parser.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/prism.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/regexp.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -prism/serialize.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h -prism/serialize.$(OBJEXT): {$(VPATH)}prism/ast.h -prism/serialize.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -prism/serialize.$(OBJEXT): {$(VPATH)}prism/serialize.c -prism/serialize.$(OBJEXT): {$(VPATH)}prism/version.h -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/encoding.h -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/node.h -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/options.h -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/parser.h -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/static_literals.c -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/static_literals.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -prism/static_literals.$(OBJEXT): {$(VPATH)}prism/ast.h -prism/token_type.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/token_type.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism/token_type.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/token_type.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism/token_type.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -prism/token_type.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/token_type.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/token_type.$(OBJEXT): {$(VPATH)}prism/ast.h -prism/token_type.$(OBJEXT): {$(VPATH)}prism/token_type.c -prism/util/pm_buffer.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/util/pm_buffer.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.c -prism/util/pm_buffer.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism/util/pm_buffer.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/util/pm_buffer.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/util/pm_char.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/util/pm_char.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.c -prism/util/pm_char.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/util/pm_char.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/util/pm_constant_pool.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/util/pm_constant_pool.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.c -prism/util/pm_constant_pool.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism/util/pm_integer.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/util/pm_integer.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism/util/pm_integer.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/util/pm_integer.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.c -prism/util/pm_integer.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -prism/util/pm_integer.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/util/pm_list.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/util/pm_list.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.c -prism/util/pm_list.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/encoding.h -prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/parser.h -prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.c -prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/util/pm_memchr.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -prism/util/pm_memchr.$(OBJEXT): {$(VPATH)}prism/ast.h -prism/util/pm_newline_list.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/util/pm_newline_list.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.c -prism/util/pm_newline_list.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/util/pm_string.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/util/pm_string.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.c -prism/util/pm_string.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/util/pm_strncasecmp.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/util/pm_strncasecmp.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.c -prism/util/pm_strncasecmp.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/encoding.h -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/options.h -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/parser.h -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.c -prism/util/pm_strpbrk.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h -prism/util/pm_strpbrk.$(OBJEXT): {$(VPATH)}prism/ast.h -prism/util/pm_strpbrk.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -prism_init.$(OBJEXT): $(hdrdir)/ruby.h -prism_init.$(OBJEXT): $(hdrdir)/ruby/ruby.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/defines.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/encoding.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/extension.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/node.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/options.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/pack.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/parser.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/prism.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/regexp.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -prism_init.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h -prism_init.$(OBJEXT): $(top_srcdir)/prism_init.c -prism_init.$(OBJEXT): {$(VPATH)}assert.h -prism_init.$(OBJEXT): {$(VPATH)}backward/2/assume.h -prism_init.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -prism_init.$(OBJEXT): {$(VPATH)}backward/2/bool.h -prism_init.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h -prism_init.$(OBJEXT): {$(VPATH)}backward/2/limits.h -prism_init.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -prism_init.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -prism_init.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -prism_init.$(OBJEXT): {$(VPATH)}config.h -prism_init.$(OBJEXT): {$(VPATH)}defines.h -prism_init.$(OBJEXT): {$(VPATH)}encoding.h -prism_init.$(OBJEXT): {$(VPATH)}intern.h -prism_init.$(OBJEXT): {$(VPATH)}internal/abi.h -prism_init.$(OBJEXT): {$(VPATH)}internal/anyargs.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h -prism_init.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h -prism_init.$(OBJEXT): {$(VPATH)}internal/assume.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/const.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/error.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/format.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -prism_init.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h -prism_init.$(OBJEXT): {$(VPATH)}internal/cast.h -prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -prism_init.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -prism_init.$(OBJEXT): {$(VPATH)}internal/config.h -prism_init.$(OBJEXT): {$(VPATH)}internal/constant_p.h -prism_init.$(OBJEXT): {$(VPATH)}internal/core.h -prism_init.$(OBJEXT): {$(VPATH)}internal/core/rarray.h -prism_init.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h -prism_init.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h -prism_init.$(OBJEXT): {$(VPATH)}internal/core/rclass.h -prism_init.$(OBJEXT): {$(VPATH)}internal/core/rdata.h -prism_init.$(OBJEXT): {$(VPATH)}internal/core/rfile.h -prism_init.$(OBJEXT): {$(VPATH)}internal/core/rhash.h -prism_init.$(OBJEXT): {$(VPATH)}internal/core/robject.h -prism_init.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h -prism_init.$(OBJEXT): {$(VPATH)}internal/core/rstring.h -prism_init.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h -prism_init.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h -prism_init.$(OBJEXT): {$(VPATH)}internal/ctype.h -prism_init.$(OBJEXT): {$(VPATH)}internal/dllexport.h -prism_init.$(OBJEXT): {$(VPATH)}internal/dosish.h -prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -prism_init.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h -prism_init.$(OBJEXT): {$(VPATH)}internal/error.h -prism_init.$(OBJEXT): {$(VPATH)}internal/eval.h -prism_init.$(OBJEXT): {$(VPATH)}internal/event.h -prism_init.$(OBJEXT): {$(VPATH)}internal/fl_type.h -prism_init.$(OBJEXT): {$(VPATH)}internal/gc.h -prism_init.$(OBJEXT): {$(VPATH)}internal/glob.h -prism_init.$(OBJEXT): {$(VPATH)}internal/globals.h -prism_init.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -prism_init.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -prism_init.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -prism_init.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -prism_init.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -prism_init.$(OBJEXT): {$(VPATH)}internal/has/extension.h -prism_init.$(OBJEXT): {$(VPATH)}internal/has/feature.h -prism_init.$(OBJEXT): {$(VPATH)}internal/has/warning.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/array.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/class.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/compar.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/complex.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/cont.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/dir.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/enum.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/error.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/eval.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/file.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/hash.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/io.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/load.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/object.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/parse.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/proc.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/process.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/random.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/range.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/rational.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/re.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/select.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/signal.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/string.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/struct.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/thread.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/time.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/variable.h -prism_init.$(OBJEXT): {$(VPATH)}internal/intern/vm.h -prism_init.$(OBJEXT): {$(VPATH)}internal/interpreter.h -prism_init.$(OBJEXT): {$(VPATH)}internal/iterator.h -prism_init.$(OBJEXT): {$(VPATH)}internal/memory.h -prism_init.$(OBJEXT): {$(VPATH)}internal/method.h -prism_init.$(OBJEXT): {$(VPATH)}internal/module.h -prism_init.$(OBJEXT): {$(VPATH)}internal/newobj.h -prism_init.$(OBJEXT): {$(VPATH)}internal/scan_args.h -prism_init.$(OBJEXT): {$(VPATH)}internal/special_consts.h -prism_init.$(OBJEXT): {$(VPATH)}internal/static_assert.h -prism_init.$(OBJEXT): {$(VPATH)}internal/stdalign.h -prism_init.$(OBJEXT): {$(VPATH)}internal/stdbool.h -prism_init.$(OBJEXT): {$(VPATH)}internal/stdckdint.h -prism_init.$(OBJEXT): {$(VPATH)}internal/symbol.h -prism_init.$(OBJEXT): {$(VPATH)}internal/value.h -prism_init.$(OBJEXT): {$(VPATH)}internal/value_type.h -prism_init.$(OBJEXT): {$(VPATH)}internal/variable.h -prism_init.$(OBJEXT): {$(VPATH)}internal/warning_push.h -prism_init.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -prism_init.$(OBJEXT): {$(VPATH)}missing.h -prism_init.$(OBJEXT): {$(VPATH)}onigmo.h -prism_init.$(OBJEXT): {$(VPATH)}oniguruma.h -prism_init.$(OBJEXT): {$(VPATH)}prism/ast.h -prism_init.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -prism_init.$(OBJEXT): {$(VPATH)}prism/version.h -prism_init.$(OBJEXT): {$(VPATH)}prism_init.c -prism_init.$(OBJEXT): {$(VPATH)}st.h -prism_init.$(OBJEXT): {$(VPATH)}subst.h proc.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h proc.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h proc.$(OBJEXT): $(CCAN_DIR)/list/list.h proc.$(OBJEXT): $(CCAN_DIR)/str/str.h proc.$(OBJEXT): $(hdrdir)/ruby/ruby.h -proc.$(OBJEXT): $(hdrdir)/ruby/version.h proc.$(OBJEXT): $(top_srcdir)/internal/array.h proc.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h proc.$(OBJEXT): $(top_srcdir)/internal/class.h @@ -13001,10 +11157,10 @@ 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 -proc.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h proc.$(OBJEXT): $(top_srcdir)/internal/serial.h proc.$(OBJEXT): $(top_srcdir)/internal/static_assert.h proc.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -13012,26 +11168,6 @@ proc.$(OBJEXT): $(top_srcdir)/internal/symbol.h proc.$(OBJEXT): $(top_srcdir)/internal/variable.h proc.$(OBJEXT): $(top_srcdir)/internal/vm.h proc.$(OBJEXT): $(top_srcdir)/internal/warnings.h -proc.$(OBJEXT): $(top_srcdir)/prism/defines.h -proc.$(OBJEXT): $(top_srcdir)/prism/encoding.h -proc.$(OBJEXT): $(top_srcdir)/prism/node.h -proc.$(OBJEXT): $(top_srcdir)/prism/options.h -proc.$(OBJEXT): $(top_srcdir)/prism/pack.h -proc.$(OBJEXT): $(top_srcdir)/prism/parser.h -proc.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -proc.$(OBJEXT): $(top_srcdir)/prism/prism.h -proc.$(OBJEXT): $(top_srcdir)/prism/regexp.h -proc.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -proc.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h proc.$(OBJEXT): {$(VPATH)}assert.h proc.$(OBJEXT): {$(VPATH)}atomic.h proc.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -13045,10 +11181,10 @@ proc.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h proc.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h proc.$(OBJEXT): {$(VPATH)}config.h proc.$(OBJEXT): {$(VPATH)}constant.h -proc.$(OBJEXT): {$(VPATH)}debug_counter.h proc.$(OBJEXT): {$(VPATH)}defines.h proc.$(OBJEXT): {$(VPATH)}encoding.h proc.$(OBJEXT): {$(VPATH)}eval_intern.h +proc.$(OBJEXT): {$(VPATH)}gc.h proc.$(OBJEXT): {$(VPATH)}id.h proc.$(OBJEXT): {$(VPATH)}id_table.h proc.$(OBJEXT): {$(VPATH)}intern.h @@ -13091,7 +11227,6 @@ proc.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h proc.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h proc.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h proc.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -proc.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h proc.$(OBJEXT): {$(VPATH)}internal/attr/pure.h proc.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h proc.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -13160,6 +11295,7 @@ proc.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h proc.$(OBJEXT): {$(VPATH)}internal/intern/error.h proc.$(OBJEXT): {$(VPATH)}internal/intern/eval.h proc.$(OBJEXT): {$(VPATH)}internal/intern/file.h +proc.$(OBJEXT): {$(VPATH)}internal/intern/gc.h proc.$(OBJEXT): {$(VPATH)}internal/intern/hash.h proc.$(OBJEXT): {$(VPATH)}internal/intern/io.h proc.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -13190,12 +11326,12 @@ proc.$(OBJEXT): {$(VPATH)}internal/memory.h proc.$(OBJEXT): {$(VPATH)}internal/method.h proc.$(OBJEXT): {$(VPATH)}internal/module.h proc.$(OBJEXT): {$(VPATH)}internal/newobj.h +proc.$(OBJEXT): {$(VPATH)}internal/rgengc.h proc.$(OBJEXT): {$(VPATH)}internal/scan_args.h proc.$(OBJEXT): {$(VPATH)}internal/special_consts.h proc.$(OBJEXT): {$(VPATH)}internal/static_assert.h proc.$(OBJEXT): {$(VPATH)}internal/stdalign.h proc.$(OBJEXT): {$(VPATH)}internal/stdbool.h -proc.$(OBJEXT): {$(VPATH)}internal/stdckdint.h proc.$(OBJEXT): {$(VPATH)}internal/symbol.h proc.$(OBJEXT): {$(VPATH)}internal/value.h proc.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -13208,23 +11344,16 @@ proc.$(OBJEXT): {$(VPATH)}missing.h proc.$(OBJEXT): {$(VPATH)}node.h proc.$(OBJEXT): {$(VPATH)}onigmo.h proc.$(OBJEXT): {$(VPATH)}oniguruma.h -proc.$(OBJEXT): {$(VPATH)}prism/ast.h -proc.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -proc.$(OBJEXT): {$(VPATH)}prism/version.h -proc.$(OBJEXT): {$(VPATH)}prism_compile.h proc.$(OBJEXT): {$(VPATH)}proc.c proc.$(OBJEXT): {$(VPATH)}ruby_assert.h proc.$(OBJEXT): {$(VPATH)}ruby_atomic.h -proc.$(OBJEXT): {$(VPATH)}rubyparser.h proc.$(OBJEXT): {$(VPATH)}shape.h proc.$(OBJEXT): {$(VPATH)}st.h proc.$(OBJEXT): {$(VPATH)}subst.h proc.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h proc.$(OBJEXT): {$(VPATH)}thread_native.h proc.$(OBJEXT): {$(VPATH)}vm_core.h -proc.$(OBJEXT): {$(VPATH)}vm_debug.h proc.$(OBJEXT): {$(VPATH)}vm_opts.h -proc.$(OBJEXT): {$(VPATH)}vm_sync.h proc.$(OBJEXT): {$(VPATH)}yjit.h process.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h process.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h @@ -13232,7 +11361,6 @@ process.$(OBJEXT): $(CCAN_DIR)/list/list.h process.$(OBJEXT): $(CCAN_DIR)/str/str.h process.$(OBJEXT): $(hdrdir)/ruby.h process.$(OBJEXT): $(hdrdir)/ruby/ruby.h -process.$(OBJEXT): $(hdrdir)/ruby/version.h process.$(OBJEXT): $(top_srcdir)/internal/array.h process.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h process.$(OBJEXT): $(top_srcdir)/internal/bignum.h @@ -13246,11 +11374,9 @@ process.$(OBJEXT): $(top_srcdir)/internal/fixnum.h process.$(OBJEXT): $(top_srcdir)/internal/gc.h process.$(OBJEXT): $(top_srcdir)/internal/hash.h process.$(OBJEXT): $(top_srcdir)/internal/imemo.h -process.$(OBJEXT): $(top_srcdir)/internal/io.h process.$(OBJEXT): $(top_srcdir)/internal/numeric.h process.$(OBJEXT): $(top_srcdir)/internal/object.h process.$(OBJEXT): $(top_srcdir)/internal/process.h -process.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h process.$(OBJEXT): $(top_srcdir)/internal/serial.h process.$(OBJEXT): $(top_srcdir)/internal/static_assert.h process.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -13320,7 +11446,6 @@ process.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h process.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h process.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h process.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -process.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h process.$(OBJEXT): {$(VPATH)}internal/attr/pure.h process.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h process.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -13389,6 +11514,7 @@ process.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h process.$(OBJEXT): {$(VPATH)}internal/intern/error.h process.$(OBJEXT): {$(VPATH)}internal/intern/eval.h process.$(OBJEXT): {$(VPATH)}internal/intern/file.h +process.$(OBJEXT): {$(VPATH)}internal/intern/gc.h process.$(OBJEXT): {$(VPATH)}internal/intern/hash.h process.$(OBJEXT): {$(VPATH)}internal/intern/io.h process.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -13419,12 +11545,12 @@ process.$(OBJEXT): {$(VPATH)}internal/memory.h process.$(OBJEXT): {$(VPATH)}internal/method.h process.$(OBJEXT): {$(VPATH)}internal/module.h process.$(OBJEXT): {$(VPATH)}internal/newobj.h +process.$(OBJEXT): {$(VPATH)}internal/rgengc.h process.$(OBJEXT): {$(VPATH)}internal/scan_args.h process.$(OBJEXT): {$(VPATH)}internal/special_consts.h process.$(OBJEXT): {$(VPATH)}internal/static_assert.h process.$(OBJEXT): {$(VPATH)}internal/stdalign.h process.$(OBJEXT): {$(VPATH)}internal/stdbool.h -process.$(OBJEXT): {$(VPATH)}internal/stdckdint.h process.$(OBJEXT): {$(VPATH)}internal/symbol.h process.$(OBJEXT): {$(VPATH)}internal/value.h process.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -13434,15 +11560,14 @@ process.$(OBJEXT): {$(VPATH)}internal/xmalloc.h process.$(OBJEXT): {$(VPATH)}io.h process.$(OBJEXT): {$(VPATH)}method.h process.$(OBJEXT): {$(VPATH)}missing.h +process.$(OBJEXT): {$(VPATH)}mjit.h process.$(OBJEXT): {$(VPATH)}node.h process.$(OBJEXT): {$(VPATH)}onigmo.h process.$(OBJEXT): {$(VPATH)}oniguruma.h process.$(OBJEXT): {$(VPATH)}process.c process.$(OBJEXT): {$(VPATH)}ractor.h -process.$(OBJEXT): {$(VPATH)}rjit.h process.$(OBJEXT): {$(VPATH)}ruby_assert.h process.$(OBJEXT): {$(VPATH)}ruby_atomic.h -process.$(OBJEXT): {$(VPATH)}rubyparser.h process.$(OBJEXT): {$(VPATH)}shape.h process.$(OBJEXT): {$(VPATH)}st.h process.$(OBJEXT): {$(VPATH)}subst.h @@ -13451,16 +11576,13 @@ process.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h process.$(OBJEXT): {$(VPATH)}thread_native.h process.$(OBJEXT): {$(VPATH)}util.h process.$(OBJEXT): {$(VPATH)}vm_core.h -process.$(OBJEXT): {$(VPATH)}vm_debug.h process.$(OBJEXT): {$(VPATH)}vm_opts.h -process.$(OBJEXT): {$(VPATH)}vm_sync.h 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): $(hdrdir)/ruby/version.h ractor.$(OBJEXT): $(top_srcdir)/internal/array.h ractor.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h ractor.$(OBJEXT): $(top_srcdir)/internal/bignum.h @@ -13474,7 +11596,6 @@ ractor.$(OBJEXT): $(top_srcdir)/internal/hash.h ractor.$(OBJEXT): $(top_srcdir)/internal/imemo.h ractor.$(OBJEXT): $(top_srcdir)/internal/numeric.h ractor.$(OBJEXT): $(top_srcdir)/internal/rational.h -ractor.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h ractor.$(OBJEXT): $(top_srcdir)/internal/serial.h ractor.$(OBJEXT): $(top_srcdir)/internal/static_assert.h ractor.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -13500,7 +11621,7 @@ ractor.$(OBJEXT): {$(VPATH)}constant.h ractor.$(OBJEXT): {$(VPATH)}debug_counter.h ractor.$(OBJEXT): {$(VPATH)}defines.h ractor.$(OBJEXT): {$(VPATH)}encoding.h -ractor.$(OBJEXT): {$(VPATH)}eval_intern.h +ractor.$(OBJEXT): {$(VPATH)}gc.h ractor.$(OBJEXT): {$(VPATH)}id.h ractor.$(OBJEXT): {$(VPATH)}id_table.h ractor.$(OBJEXT): {$(VPATH)}intern.h @@ -13543,7 +11664,6 @@ ractor.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h ractor.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h ractor.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h ractor.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -ractor.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h ractor.$(OBJEXT): {$(VPATH)}internal/attr/pure.h ractor.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h ractor.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -13612,6 +11732,7 @@ ractor.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h ractor.$(OBJEXT): {$(VPATH)}internal/intern/error.h ractor.$(OBJEXT): {$(VPATH)}internal/intern/eval.h ractor.$(OBJEXT): {$(VPATH)}internal/intern/file.h +ractor.$(OBJEXT): {$(VPATH)}internal/intern/gc.h ractor.$(OBJEXT): {$(VPATH)}internal/intern/hash.h ractor.$(OBJEXT): {$(VPATH)}internal/intern/io.h ractor.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -13642,12 +11763,12 @@ ractor.$(OBJEXT): {$(VPATH)}internal/memory.h ractor.$(OBJEXT): {$(VPATH)}internal/method.h ractor.$(OBJEXT): {$(VPATH)}internal/module.h ractor.$(OBJEXT): {$(VPATH)}internal/newobj.h +ractor.$(OBJEXT): {$(VPATH)}internal/rgengc.h ractor.$(OBJEXT): {$(VPATH)}internal/scan_args.h ractor.$(OBJEXT): {$(VPATH)}internal/special_consts.h ractor.$(OBJEXT): {$(VPATH)}internal/static_assert.h ractor.$(OBJEXT): {$(VPATH)}internal/stdalign.h ractor.$(OBJEXT): {$(VPATH)}internal/stdbool.h -ractor.$(OBJEXT): {$(VPATH)}internal/stdckdint.h ractor.$(OBJEXT): {$(VPATH)}internal/symbol.h ractor.$(OBJEXT): {$(VPATH)}internal/value.h ractor.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -13656,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 @@ -13663,35 +11785,28 @@ ractor.$(OBJEXT): {$(VPATH)}ractor.c ractor.$(OBJEXT): {$(VPATH)}ractor.h ractor.$(OBJEXT): {$(VPATH)}ractor.rbinc ractor.$(OBJEXT): {$(VPATH)}ractor_core.h -ractor.$(OBJEXT): {$(VPATH)}rjit.h ractor.$(OBJEXT): {$(VPATH)}ruby_assert.h ractor.$(OBJEXT): {$(VPATH)}ruby_atomic.h -ractor.$(OBJEXT): {$(VPATH)}rubyparser.h ractor.$(OBJEXT): {$(VPATH)}shape.h ractor.$(OBJEXT): {$(VPATH)}st.h ractor.$(OBJEXT): {$(VPATH)}subst.h ractor.$(OBJEXT): {$(VPATH)}thread.h ractor.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h ractor.$(OBJEXT): {$(VPATH)}thread_native.h +ractor.$(OBJEXT): {$(VPATH)}transient_heap.h ractor.$(OBJEXT): {$(VPATH)}variable.h ractor.$(OBJEXT): {$(VPATH)}vm_core.h ractor.$(OBJEXT): {$(VPATH)}vm_debug.h ractor.$(OBJEXT): {$(VPATH)}vm_opts.h ractor.$(OBJEXT): {$(VPATH)}vm_sync.h ractor.$(OBJEXT): {$(VPATH)}yjit.h -random.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -random.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -random.$(OBJEXT): $(CCAN_DIR)/list/list.h -random.$(OBJEXT): $(CCAN_DIR)/str/str.h random.$(OBJEXT): $(hdrdir)/ruby/ruby.h random.$(OBJEXT): $(top_srcdir)/internal/array.h -random.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h random.$(OBJEXT): $(top_srcdir)/internal/bignum.h random.$(OBJEXT): $(top_srcdir)/internal/bits.h random.$(OBJEXT): $(top_srcdir)/internal/compilers.h random.$(OBJEXT): $(top_srcdir)/internal/fixnum.h random.$(OBJEXT): $(top_srcdir)/internal/gc.h -random.$(OBJEXT): $(top_srcdir)/internal/imemo.h random.$(OBJEXT): $(top_srcdir)/internal/numeric.h random.$(OBJEXT): $(top_srcdir)/internal/random.h random.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h @@ -13714,8 +11829,6 @@ random.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h random.$(OBJEXT): {$(VPATH)}config.h random.$(OBJEXT): {$(VPATH)}constant.h random.$(OBJEXT): {$(VPATH)}defines.h -random.$(OBJEXT): {$(VPATH)}encoding.h -random.$(OBJEXT): {$(VPATH)}id.h random.$(OBJEXT): {$(VPATH)}id_table.h random.$(OBJEXT): {$(VPATH)}intern.h random.$(OBJEXT): {$(VPATH)}internal.h @@ -13757,7 +11870,6 @@ random.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h random.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h random.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h random.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -random.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h random.$(OBJEXT): {$(VPATH)}internal/attr/pure.h random.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h random.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -13790,15 +11902,6 @@ random.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h random.$(OBJEXT): {$(VPATH)}internal/ctype.h random.$(OBJEXT): {$(VPATH)}internal/dllexport.h random.$(OBJEXT): {$(VPATH)}internal/dosish.h -random.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -random.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -random.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -random.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -random.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -random.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -random.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -random.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -random.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h random.$(OBJEXT): {$(VPATH)}internal/error.h random.$(OBJEXT): {$(VPATH)}internal/eval.h random.$(OBJEXT): {$(VPATH)}internal/event.h @@ -13826,6 +11929,7 @@ random.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h random.$(OBJEXT): {$(VPATH)}internal/intern/error.h random.$(OBJEXT): {$(VPATH)}internal/intern/eval.h random.$(OBJEXT): {$(VPATH)}internal/intern/file.h +random.$(OBJEXT): {$(VPATH)}internal/intern/gc.h random.$(OBJEXT): {$(VPATH)}internal/intern/hash.h random.$(OBJEXT): {$(VPATH)}internal/intern/io.h random.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -13856,41 +11960,30 @@ random.$(OBJEXT): {$(VPATH)}internal/memory.h random.$(OBJEXT): {$(VPATH)}internal/method.h random.$(OBJEXT): {$(VPATH)}internal/module.h random.$(OBJEXT): {$(VPATH)}internal/newobj.h +random.$(OBJEXT): {$(VPATH)}internal/rgengc.h random.$(OBJEXT): {$(VPATH)}internal/scan_args.h random.$(OBJEXT): {$(VPATH)}internal/special_consts.h random.$(OBJEXT): {$(VPATH)}internal/static_assert.h random.$(OBJEXT): {$(VPATH)}internal/stdalign.h random.$(OBJEXT): {$(VPATH)}internal/stdbool.h -random.$(OBJEXT): {$(VPATH)}internal/stdckdint.h random.$(OBJEXT): {$(VPATH)}internal/symbol.h random.$(OBJEXT): {$(VPATH)}internal/value.h random.$(OBJEXT): {$(VPATH)}internal/value_type.h random.$(OBJEXT): {$(VPATH)}internal/variable.h random.$(OBJEXT): {$(VPATH)}internal/warning_push.h random.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -random.$(OBJEXT): {$(VPATH)}method.h random.$(OBJEXT): {$(VPATH)}missing.h random.$(OBJEXT): {$(VPATH)}mt19937.c -random.$(OBJEXT): {$(VPATH)}node.h -random.$(OBJEXT): {$(VPATH)}onigmo.h -random.$(OBJEXT): {$(VPATH)}oniguruma.h random.$(OBJEXT): {$(VPATH)}ractor.h random.$(OBJEXT): {$(VPATH)}random.c random.$(OBJEXT): {$(VPATH)}random.h -random.$(OBJEXT): {$(VPATH)}ruby_assert.h random.$(OBJEXT): {$(VPATH)}ruby_atomic.h -random.$(OBJEXT): {$(VPATH)}rubyparser.h random.$(OBJEXT): {$(VPATH)}shape.h random.$(OBJEXT): {$(VPATH)}siphash.c random.$(OBJEXT): {$(VPATH)}siphash.h random.$(OBJEXT): {$(VPATH)}st.h random.$(OBJEXT): {$(VPATH)}subst.h -random.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -random.$(OBJEXT): {$(VPATH)}thread_native.h -random.$(OBJEXT): {$(VPATH)}vm_core.h -random.$(OBJEXT): {$(VPATH)}vm_opts.h range.$(OBJEXT): $(hdrdir)/ruby/ruby.h -range.$(OBJEXT): $(hdrdir)/ruby/version.h range.$(OBJEXT): $(top_srcdir)/internal/array.h range.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h range.$(OBJEXT): $(top_srcdir)/internal/bignum.h @@ -13964,7 +12057,6 @@ range.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h range.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h range.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h range.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -range.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h range.$(OBJEXT): {$(VPATH)}internal/attr/pure.h range.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h range.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -14033,6 +12125,7 @@ range.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h range.$(OBJEXT): {$(VPATH)}internal/intern/error.h range.$(OBJEXT): {$(VPATH)}internal/intern/eval.h range.$(OBJEXT): {$(VPATH)}internal/intern/file.h +range.$(OBJEXT): {$(VPATH)}internal/intern/gc.h range.$(OBJEXT): {$(VPATH)}internal/intern/hash.h range.$(OBJEXT): {$(VPATH)}internal/intern/io.h range.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -14063,12 +12156,12 @@ range.$(OBJEXT): {$(VPATH)}internal/memory.h range.$(OBJEXT): {$(VPATH)}internal/method.h range.$(OBJEXT): {$(VPATH)}internal/module.h range.$(OBJEXT): {$(VPATH)}internal/newobj.h +range.$(OBJEXT): {$(VPATH)}internal/rgengc.h range.$(OBJEXT): {$(VPATH)}internal/scan_args.h range.$(OBJEXT): {$(VPATH)}internal/special_consts.h range.$(OBJEXT): {$(VPATH)}internal/static_assert.h range.$(OBJEXT): {$(VPATH)}internal/stdalign.h range.$(OBJEXT): {$(VPATH)}internal/stdbool.h -range.$(OBJEXT): {$(VPATH)}internal/stdckdint.h range.$(OBJEXT): {$(VPATH)}internal/symbol.h range.$(OBJEXT): {$(VPATH)}internal/value.h range.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -14082,13 +12175,8 @@ range.$(OBJEXT): {$(VPATH)}range.c range.$(OBJEXT): {$(VPATH)}shape.h range.$(OBJEXT): {$(VPATH)}st.h range.$(OBJEXT): {$(VPATH)}subst.h -rational.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -rational.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -rational.$(OBJEXT): $(CCAN_DIR)/list/list.h -rational.$(OBJEXT): $(CCAN_DIR)/str/str.h rational.$(OBJEXT): $(hdrdir)/ruby/ruby.h rational.$(OBJEXT): $(top_srcdir)/internal/array.h -rational.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h rational.$(OBJEXT): $(top_srcdir)/internal/bignum.h rational.$(OBJEXT): $(top_srcdir)/internal/bits.h rational.$(OBJEXT): $(top_srcdir)/internal/class.h @@ -14096,18 +12184,15 @@ rational.$(OBJEXT): $(top_srcdir)/internal/compilers.h rational.$(OBJEXT): $(top_srcdir)/internal/complex.h rational.$(OBJEXT): $(top_srcdir)/internal/fixnum.h rational.$(OBJEXT): $(top_srcdir)/internal/gc.h -rational.$(OBJEXT): $(top_srcdir)/internal/imemo.h rational.$(OBJEXT): $(top_srcdir)/internal/numeric.h rational.$(OBJEXT): $(top_srcdir)/internal/object.h rational.$(OBJEXT): $(top_srcdir)/internal/rational.h -rational.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h rational.$(OBJEXT): $(top_srcdir)/internal/serial.h rational.$(OBJEXT): $(top_srcdir)/internal/static_assert.h rational.$(OBJEXT): $(top_srcdir)/internal/variable.h rational.$(OBJEXT): $(top_srcdir)/internal/vm.h rational.$(OBJEXT): $(top_srcdir)/internal/warnings.h rational.$(OBJEXT): {$(VPATH)}assert.h -rational.$(OBJEXT): {$(VPATH)}atomic.h rational.$(OBJEXT): {$(VPATH)}backward/2/assume.h rational.$(OBJEXT): {$(VPATH)}backward/2/attributes.h rational.$(OBJEXT): {$(VPATH)}backward/2/bool.h @@ -14120,7 +12205,6 @@ rational.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h rational.$(OBJEXT): {$(VPATH)}config.h rational.$(OBJEXT): {$(VPATH)}constant.h rational.$(OBJEXT): {$(VPATH)}defines.h -rational.$(OBJEXT): {$(VPATH)}encoding.h rational.$(OBJEXT): {$(VPATH)}id.h rational.$(OBJEXT): {$(VPATH)}id_table.h rational.$(OBJEXT): {$(VPATH)}intern.h @@ -14163,7 +12247,6 @@ rational.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h rational.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h rational.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h rational.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -rational.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h rational.$(OBJEXT): {$(VPATH)}internal/attr/pure.h rational.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h rational.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -14196,15 +12279,6 @@ rational.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h rational.$(OBJEXT): {$(VPATH)}internal/ctype.h rational.$(OBJEXT): {$(VPATH)}internal/dllexport.h rational.$(OBJEXT): {$(VPATH)}internal/dosish.h -rational.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -rational.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -rational.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -rational.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -rational.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -rational.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -rational.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -rational.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -rational.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h rational.$(OBJEXT): {$(VPATH)}internal/error.h rational.$(OBJEXT): {$(VPATH)}internal/eval.h rational.$(OBJEXT): {$(VPATH)}internal/event.h @@ -14232,6 +12306,7 @@ rational.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h rational.$(OBJEXT): {$(VPATH)}internal/intern/error.h rational.$(OBJEXT): {$(VPATH)}internal/intern/eval.h rational.$(OBJEXT): {$(VPATH)}internal/intern/file.h +rational.$(OBJEXT): {$(VPATH)}internal/intern/gc.h rational.$(OBJEXT): {$(VPATH)}internal/intern/hash.h rational.$(OBJEXT): {$(VPATH)}internal/intern/io.h rational.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -14262,42 +12337,27 @@ rational.$(OBJEXT): {$(VPATH)}internal/memory.h rational.$(OBJEXT): {$(VPATH)}internal/method.h rational.$(OBJEXT): {$(VPATH)}internal/module.h rational.$(OBJEXT): {$(VPATH)}internal/newobj.h +rational.$(OBJEXT): {$(VPATH)}internal/rgengc.h rational.$(OBJEXT): {$(VPATH)}internal/scan_args.h rational.$(OBJEXT): {$(VPATH)}internal/special_consts.h rational.$(OBJEXT): {$(VPATH)}internal/static_assert.h rational.$(OBJEXT): {$(VPATH)}internal/stdalign.h rational.$(OBJEXT): {$(VPATH)}internal/stdbool.h -rational.$(OBJEXT): {$(VPATH)}internal/stdckdint.h rational.$(OBJEXT): {$(VPATH)}internal/symbol.h rational.$(OBJEXT): {$(VPATH)}internal/value.h rational.$(OBJEXT): {$(VPATH)}internal/value_type.h rational.$(OBJEXT): {$(VPATH)}internal/variable.h rational.$(OBJEXT): {$(VPATH)}internal/warning_push.h rational.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -rational.$(OBJEXT): {$(VPATH)}method.h rational.$(OBJEXT): {$(VPATH)}missing.h -rational.$(OBJEXT): {$(VPATH)}node.h -rational.$(OBJEXT): {$(VPATH)}onigmo.h -rational.$(OBJEXT): {$(VPATH)}oniguruma.h rational.$(OBJEXT): {$(VPATH)}rational.c rational.$(OBJEXT): {$(VPATH)}ruby_assert.h -rational.$(OBJEXT): {$(VPATH)}ruby_atomic.h -rational.$(OBJEXT): {$(VPATH)}rubyparser.h rational.$(OBJEXT): {$(VPATH)}shape.h rational.$(OBJEXT): {$(VPATH)}st.h rational.$(OBJEXT): {$(VPATH)}subst.h -rational.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -rational.$(OBJEXT): {$(VPATH)}thread_native.h -rational.$(OBJEXT): {$(VPATH)}vm_core.h -rational.$(OBJEXT): {$(VPATH)}vm_opts.h -re.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -re.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -re.$(OBJEXT): $(CCAN_DIR)/list/list.h -re.$(OBJEXT): $(CCAN_DIR)/str/str.h re.$(OBJEXT): $(hdrdir)/ruby.h re.$(OBJEXT): $(hdrdir)/ruby/ruby.h re.$(OBJEXT): $(top_srcdir)/internal/array.h -re.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h re.$(OBJEXT): $(top_srcdir)/internal/bits.h re.$(OBJEXT): $(top_srcdir)/internal/class.h re.$(OBJEXT): $(top_srcdir)/internal/compilers.h @@ -14308,16 +12368,13 @@ re.$(OBJEXT): $(top_srcdir)/internal/imemo.h re.$(OBJEXT): $(top_srcdir)/internal/object.h re.$(OBJEXT): $(top_srcdir)/internal/ractor.h re.$(OBJEXT): $(top_srcdir)/internal/re.h -re.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h re.$(OBJEXT): $(top_srcdir)/internal/serial.h re.$(OBJEXT): $(top_srcdir)/internal/static_assert.h re.$(OBJEXT): $(top_srcdir)/internal/string.h re.$(OBJEXT): $(top_srcdir)/internal/time.h re.$(OBJEXT): $(top_srcdir)/internal/variable.h -re.$(OBJEXT): $(top_srcdir)/internal/vm.h re.$(OBJEXT): $(top_srcdir)/internal/warnings.h re.$(OBJEXT): {$(VPATH)}assert.h -re.$(OBJEXT): {$(VPATH)}atomic.h re.$(OBJEXT): {$(VPATH)}backward/2/assume.h re.$(OBJEXT): {$(VPATH)}backward/2/attributes.h re.$(OBJEXT): {$(VPATH)}backward/2/bool.h @@ -14333,7 +12390,6 @@ re.$(OBJEXT): {$(VPATH)}defines.h re.$(OBJEXT): {$(VPATH)}encindex.h re.$(OBJEXT): {$(VPATH)}encoding.h re.$(OBJEXT): {$(VPATH)}hrtime.h -re.$(OBJEXT): {$(VPATH)}id.h re.$(OBJEXT): {$(VPATH)}id_table.h re.$(OBJEXT): {$(VPATH)}intern.h re.$(OBJEXT): {$(VPATH)}internal.h @@ -14375,7 +12431,6 @@ re.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h re.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h re.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h re.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -re.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h re.$(OBJEXT): {$(VPATH)}internal/attr/pure.h re.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h re.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -14445,6 +12500,7 @@ re.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h re.$(OBJEXT): {$(VPATH)}internal/intern/error.h re.$(OBJEXT): {$(VPATH)}internal/intern/eval.h re.$(OBJEXT): {$(VPATH)}internal/intern/file.h +re.$(OBJEXT): {$(VPATH)}internal/intern/gc.h re.$(OBJEXT): {$(VPATH)}internal/intern/hash.h re.$(OBJEXT): {$(VPATH)}internal/intern/io.h re.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -14475,21 +12531,19 @@ re.$(OBJEXT): {$(VPATH)}internal/memory.h re.$(OBJEXT): {$(VPATH)}internal/method.h re.$(OBJEXT): {$(VPATH)}internal/module.h re.$(OBJEXT): {$(VPATH)}internal/newobj.h +re.$(OBJEXT): {$(VPATH)}internal/rgengc.h re.$(OBJEXT): {$(VPATH)}internal/scan_args.h re.$(OBJEXT): {$(VPATH)}internal/special_consts.h re.$(OBJEXT): {$(VPATH)}internal/static_assert.h re.$(OBJEXT): {$(VPATH)}internal/stdalign.h re.$(OBJEXT): {$(VPATH)}internal/stdbool.h -re.$(OBJEXT): {$(VPATH)}internal/stdckdint.h re.$(OBJEXT): {$(VPATH)}internal/symbol.h re.$(OBJEXT): {$(VPATH)}internal/value.h re.$(OBJEXT): {$(VPATH)}internal/value_type.h re.$(OBJEXT): {$(VPATH)}internal/variable.h re.$(OBJEXT): {$(VPATH)}internal/warning_push.h re.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -re.$(OBJEXT): {$(VPATH)}method.h re.$(OBJEXT): {$(VPATH)}missing.h -re.$(OBJEXT): {$(VPATH)}node.h re.$(OBJEXT): {$(VPATH)}onigmo.h re.$(OBJEXT): {$(VPATH)}oniguruma.h re.$(OBJEXT): {$(VPATH)}re.c @@ -14497,17 +12551,10 @@ re.$(OBJEXT): {$(VPATH)}re.h re.$(OBJEXT): {$(VPATH)}regenc.h re.$(OBJEXT): {$(VPATH)}regex.h re.$(OBJEXT): {$(VPATH)}regint.h -re.$(OBJEXT): {$(VPATH)}ruby_assert.h -re.$(OBJEXT): {$(VPATH)}ruby_atomic.h -re.$(OBJEXT): {$(VPATH)}rubyparser.h re.$(OBJEXT): {$(VPATH)}shape.h re.$(OBJEXT): {$(VPATH)}st.h re.$(OBJEXT): {$(VPATH)}subst.h -re.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -re.$(OBJEXT): {$(VPATH)}thread_native.h re.$(OBJEXT): {$(VPATH)}util.h -re.$(OBJEXT): {$(VPATH)}vm_core.h -re.$(OBJEXT): {$(VPATH)}vm_opts.h regcomp.$(OBJEXT): $(hdrdir)/ruby.h regcomp.$(OBJEXT): $(hdrdir)/ruby/ruby.h regcomp.$(OBJEXT): {$(VPATH)}assert.h @@ -14560,7 +12607,6 @@ regcomp.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h regcomp.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h regcomp.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h regcomp.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -regcomp.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h regcomp.$(OBJEXT): {$(VPATH)}internal/attr/pure.h regcomp.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h regcomp.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -14620,6 +12666,7 @@ regcomp.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h regcomp.$(OBJEXT): {$(VPATH)}internal/intern/error.h regcomp.$(OBJEXT): {$(VPATH)}internal/intern/eval.h regcomp.$(OBJEXT): {$(VPATH)}internal/intern/file.h +regcomp.$(OBJEXT): {$(VPATH)}internal/intern/gc.h regcomp.$(OBJEXT): {$(VPATH)}internal/intern/hash.h regcomp.$(OBJEXT): {$(VPATH)}internal/intern/io.h regcomp.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -14650,12 +12697,12 @@ regcomp.$(OBJEXT): {$(VPATH)}internal/memory.h regcomp.$(OBJEXT): {$(VPATH)}internal/method.h regcomp.$(OBJEXT): {$(VPATH)}internal/module.h regcomp.$(OBJEXT): {$(VPATH)}internal/newobj.h +regcomp.$(OBJEXT): {$(VPATH)}internal/rgengc.h regcomp.$(OBJEXT): {$(VPATH)}internal/scan_args.h regcomp.$(OBJEXT): {$(VPATH)}internal/special_consts.h regcomp.$(OBJEXT): {$(VPATH)}internal/static_assert.h regcomp.$(OBJEXT): {$(VPATH)}internal/stdalign.h regcomp.$(OBJEXT): {$(VPATH)}internal/stdbool.h -regcomp.$(OBJEXT): {$(VPATH)}internal/stdckdint.h regcomp.$(OBJEXT): {$(VPATH)}internal/symbol.h regcomp.$(OBJEXT): {$(VPATH)}internal/value.h regcomp.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -14722,7 +12769,6 @@ regenc.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h regenc.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h regenc.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h regenc.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -regenc.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h regenc.$(OBJEXT): {$(VPATH)}internal/attr/pure.h regenc.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h regenc.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -14782,6 +12828,7 @@ regenc.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h regenc.$(OBJEXT): {$(VPATH)}internal/intern/error.h regenc.$(OBJEXT): {$(VPATH)}internal/intern/eval.h regenc.$(OBJEXT): {$(VPATH)}internal/intern/file.h +regenc.$(OBJEXT): {$(VPATH)}internal/intern/gc.h regenc.$(OBJEXT): {$(VPATH)}internal/intern/hash.h regenc.$(OBJEXT): {$(VPATH)}internal/intern/io.h regenc.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -14812,12 +12859,12 @@ regenc.$(OBJEXT): {$(VPATH)}internal/memory.h regenc.$(OBJEXT): {$(VPATH)}internal/method.h regenc.$(OBJEXT): {$(VPATH)}internal/module.h regenc.$(OBJEXT): {$(VPATH)}internal/newobj.h +regenc.$(OBJEXT): {$(VPATH)}internal/rgengc.h regenc.$(OBJEXT): {$(VPATH)}internal/scan_args.h regenc.$(OBJEXT): {$(VPATH)}internal/special_consts.h regenc.$(OBJEXT): {$(VPATH)}internal/static_assert.h regenc.$(OBJEXT): {$(VPATH)}internal/stdalign.h regenc.$(OBJEXT): {$(VPATH)}internal/stdbool.h -regenc.$(OBJEXT): {$(VPATH)}internal/stdckdint.h regenc.$(OBJEXT): {$(VPATH)}internal/symbol.h regenc.$(OBJEXT): {$(VPATH)}internal/value.h regenc.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -14883,7 +12930,6 @@ regerror.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h regerror.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h regerror.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h regerror.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -regerror.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h regerror.$(OBJEXT): {$(VPATH)}internal/attr/pure.h regerror.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h regerror.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -14943,6 +12989,7 @@ regerror.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h regerror.$(OBJEXT): {$(VPATH)}internal/intern/error.h regerror.$(OBJEXT): {$(VPATH)}internal/intern/eval.h regerror.$(OBJEXT): {$(VPATH)}internal/intern/file.h +regerror.$(OBJEXT): {$(VPATH)}internal/intern/gc.h regerror.$(OBJEXT): {$(VPATH)}internal/intern/hash.h regerror.$(OBJEXT): {$(VPATH)}internal/intern/io.h regerror.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -14973,12 +13020,12 @@ regerror.$(OBJEXT): {$(VPATH)}internal/memory.h regerror.$(OBJEXT): {$(VPATH)}internal/method.h regerror.$(OBJEXT): {$(VPATH)}internal/module.h regerror.$(OBJEXT): {$(VPATH)}internal/newobj.h +regerror.$(OBJEXT): {$(VPATH)}internal/rgengc.h regerror.$(OBJEXT): {$(VPATH)}internal/scan_args.h regerror.$(OBJEXT): {$(VPATH)}internal/special_consts.h regerror.$(OBJEXT): {$(VPATH)}internal/static_assert.h regerror.$(OBJEXT): {$(VPATH)}internal/stdalign.h regerror.$(OBJEXT): {$(VPATH)}internal/stdbool.h -regerror.$(OBJEXT): {$(VPATH)}internal/stdckdint.h regerror.$(OBJEXT): {$(VPATH)}internal/symbol.h regerror.$(OBJEXT): {$(VPATH)}internal/value.h regerror.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -15044,7 +13091,6 @@ regexec.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h regexec.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h regexec.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h regexec.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -regexec.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h regexec.$(OBJEXT): {$(VPATH)}internal/attr/pure.h regexec.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h regexec.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -15104,6 +13150,7 @@ regexec.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h regexec.$(OBJEXT): {$(VPATH)}internal/intern/error.h regexec.$(OBJEXT): {$(VPATH)}internal/intern/eval.h regexec.$(OBJEXT): {$(VPATH)}internal/intern/file.h +regexec.$(OBJEXT): {$(VPATH)}internal/intern/gc.h regexec.$(OBJEXT): {$(VPATH)}internal/intern/hash.h regexec.$(OBJEXT): {$(VPATH)}internal/intern/io.h regexec.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -15134,12 +13181,12 @@ regexec.$(OBJEXT): {$(VPATH)}internal/memory.h regexec.$(OBJEXT): {$(VPATH)}internal/method.h regexec.$(OBJEXT): {$(VPATH)}internal/module.h regexec.$(OBJEXT): {$(VPATH)}internal/newobj.h +regexec.$(OBJEXT): {$(VPATH)}internal/rgengc.h regexec.$(OBJEXT): {$(VPATH)}internal/scan_args.h regexec.$(OBJEXT): {$(VPATH)}internal/special_consts.h regexec.$(OBJEXT): {$(VPATH)}internal/static_assert.h regexec.$(OBJEXT): {$(VPATH)}internal/stdalign.h regexec.$(OBJEXT): {$(VPATH)}internal/stdbool.h -regexec.$(OBJEXT): {$(VPATH)}internal/stdckdint.h regexec.$(OBJEXT): {$(VPATH)}internal/symbol.h regexec.$(OBJEXT): {$(VPATH)}internal/value.h regexec.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -15209,7 +13256,6 @@ regparse.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h regparse.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h regparse.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h regparse.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -regparse.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h regparse.$(OBJEXT): {$(VPATH)}internal/attr/pure.h regparse.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h regparse.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -15269,6 +13315,7 @@ regparse.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h regparse.$(OBJEXT): {$(VPATH)}internal/intern/error.h regparse.$(OBJEXT): {$(VPATH)}internal/intern/eval.h regparse.$(OBJEXT): {$(VPATH)}internal/intern/file.h +regparse.$(OBJEXT): {$(VPATH)}internal/intern/gc.h regparse.$(OBJEXT): {$(VPATH)}internal/intern/hash.h regparse.$(OBJEXT): {$(VPATH)}internal/intern/io.h regparse.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -15299,12 +13346,12 @@ regparse.$(OBJEXT): {$(VPATH)}internal/memory.h regparse.$(OBJEXT): {$(VPATH)}internal/method.h regparse.$(OBJEXT): {$(VPATH)}internal/module.h regparse.$(OBJEXT): {$(VPATH)}internal/newobj.h +regparse.$(OBJEXT): {$(VPATH)}internal/rgengc.h regparse.$(OBJEXT): {$(VPATH)}internal/scan_args.h regparse.$(OBJEXT): {$(VPATH)}internal/special_consts.h regparse.$(OBJEXT): {$(VPATH)}internal/static_assert.h regparse.$(OBJEXT): {$(VPATH)}internal/stdalign.h regparse.$(OBJEXT): {$(VPATH)}internal/stdbool.h -regparse.$(OBJEXT): {$(VPATH)}internal/stdckdint.h regparse.$(OBJEXT): {$(VPATH)}internal/symbol.h regparse.$(OBJEXT): {$(VPATH)}internal/value.h regparse.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -15371,7 +13418,6 @@ regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/pure.h regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h regsyntax.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -15431,6 +13477,7 @@ regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/error.h regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/eval.h regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/file.h +regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/gc.h regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/hash.h regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/io.h regsyntax.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -15461,12 +13508,12 @@ regsyntax.$(OBJEXT): {$(VPATH)}internal/memory.h regsyntax.$(OBJEXT): {$(VPATH)}internal/method.h regsyntax.$(OBJEXT): {$(VPATH)}internal/module.h regsyntax.$(OBJEXT): {$(VPATH)}internal/newobj.h +regsyntax.$(OBJEXT): {$(VPATH)}internal/rgengc.h regsyntax.$(OBJEXT): {$(VPATH)}internal/scan_args.h regsyntax.$(OBJEXT): {$(VPATH)}internal/special_consts.h regsyntax.$(OBJEXT): {$(VPATH)}internal/static_assert.h regsyntax.$(OBJEXT): {$(VPATH)}internal/stdalign.h regsyntax.$(OBJEXT): {$(VPATH)}internal/stdbool.h -regsyntax.$(OBJEXT): {$(VPATH)}internal/stdckdint.h regsyntax.$(OBJEXT): {$(VPATH)}internal/symbol.h regsyntax.$(OBJEXT): {$(VPATH)}internal/value.h regsyntax.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -15480,514 +13527,6 @@ regsyntax.$(OBJEXT): {$(VPATH)}regint.h regsyntax.$(OBJEXT): {$(VPATH)}regsyntax.c regsyntax.$(OBJEXT): {$(VPATH)}st.h regsyntax.$(OBJEXT): {$(VPATH)}subst.h -rjit.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -rjit.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -rjit.$(OBJEXT): $(CCAN_DIR)/list/list.h -rjit.$(OBJEXT): $(CCAN_DIR)/str/str.h -rjit.$(OBJEXT): $(hdrdir)/ruby.h -rjit.$(OBJEXT): $(hdrdir)/ruby/ruby.h -rjit.$(OBJEXT): $(hdrdir)/ruby/version.h -rjit.$(OBJEXT): $(top_srcdir)/internal/array.h -rjit.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h -rjit.$(OBJEXT): $(top_srcdir)/internal/class.h -rjit.$(OBJEXT): $(top_srcdir)/internal/cmdlineopt.h -rjit.$(OBJEXT): $(top_srcdir)/internal/compile.h -rjit.$(OBJEXT): $(top_srcdir)/internal/compilers.h -rjit.$(OBJEXT): $(top_srcdir)/internal/cont.h -rjit.$(OBJEXT): $(top_srcdir)/internal/file.h -rjit.$(OBJEXT): $(top_srcdir)/internal/gc.h -rjit.$(OBJEXT): $(top_srcdir)/internal/hash.h -rjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h -rjit.$(OBJEXT): $(top_srcdir)/internal/process.h -rjit.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h -rjit.$(OBJEXT): $(top_srcdir)/internal/serial.h -rjit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h -rjit.$(OBJEXT): $(top_srcdir)/internal/string.h -rjit.$(OBJEXT): $(top_srcdir)/internal/struct.h -rjit.$(OBJEXT): $(top_srcdir)/internal/variable.h -rjit.$(OBJEXT): $(top_srcdir)/internal/vm.h -rjit.$(OBJEXT): $(top_srcdir)/internal/warnings.h -rjit.$(OBJEXT): $(top_srcdir)/prism/defines.h -rjit.$(OBJEXT): $(top_srcdir)/prism/encoding.h -rjit.$(OBJEXT): $(top_srcdir)/prism/node.h -rjit.$(OBJEXT): $(top_srcdir)/prism/options.h -rjit.$(OBJEXT): $(top_srcdir)/prism/pack.h -rjit.$(OBJEXT): $(top_srcdir)/prism/parser.h -rjit.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -rjit.$(OBJEXT): $(top_srcdir)/prism/prism.h -rjit.$(OBJEXT): $(top_srcdir)/prism/regexp.h -rjit.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -rjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h -rjit.$(OBJEXT): {$(VPATH)}assert.h -rjit.$(OBJEXT): {$(VPATH)}atomic.h -rjit.$(OBJEXT): {$(VPATH)}backward/2/assume.h -rjit.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -rjit.$(OBJEXT): {$(VPATH)}backward/2/bool.h -rjit.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h -rjit.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h -rjit.$(OBJEXT): {$(VPATH)}backward/2/limits.h -rjit.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -rjit.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -rjit.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -rjit.$(OBJEXT): {$(VPATH)}builtin.h -rjit.$(OBJEXT): {$(VPATH)}config.h -rjit.$(OBJEXT): {$(VPATH)}constant.h -rjit.$(OBJEXT): {$(VPATH)}debug.h -rjit.$(OBJEXT): {$(VPATH)}debug_counter.h -rjit.$(OBJEXT): {$(VPATH)}defines.h -rjit.$(OBJEXT): {$(VPATH)}dln.h -rjit.$(OBJEXT): {$(VPATH)}encoding.h -rjit.$(OBJEXT): {$(VPATH)}id.h -rjit.$(OBJEXT): {$(VPATH)}id_table.h -rjit.$(OBJEXT): {$(VPATH)}insns.def -rjit.$(OBJEXT): {$(VPATH)}insns.inc -rjit.$(OBJEXT): {$(VPATH)}insns_info.inc -rjit.$(OBJEXT): {$(VPATH)}intern.h -rjit.$(OBJEXT): {$(VPATH)}internal.h -rjit.$(OBJEXT): {$(VPATH)}internal/abi.h -rjit.$(OBJEXT): {$(VPATH)}internal/anyargs.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h -rjit.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h -rjit.$(OBJEXT): {$(VPATH)}internal/assume.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/const.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/error.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/format.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -rjit.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h -rjit.$(OBJEXT): {$(VPATH)}internal/cast.h -rjit.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -rjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -rjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -rjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -rjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -rjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -rjit.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -rjit.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -rjit.$(OBJEXT): {$(VPATH)}internal/config.h -rjit.$(OBJEXT): {$(VPATH)}internal/constant_p.h -rjit.$(OBJEXT): {$(VPATH)}internal/core.h -rjit.$(OBJEXT): {$(VPATH)}internal/core/rarray.h -rjit.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h -rjit.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h -rjit.$(OBJEXT): {$(VPATH)}internal/core/rclass.h -rjit.$(OBJEXT): {$(VPATH)}internal/core/rdata.h -rjit.$(OBJEXT): {$(VPATH)}internal/core/rfile.h -rjit.$(OBJEXT): {$(VPATH)}internal/core/rhash.h -rjit.$(OBJEXT): {$(VPATH)}internal/core/robject.h -rjit.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h -rjit.$(OBJEXT): {$(VPATH)}internal/core/rstring.h -rjit.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h -rjit.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h -rjit.$(OBJEXT): {$(VPATH)}internal/ctype.h -rjit.$(OBJEXT): {$(VPATH)}internal/dllexport.h -rjit.$(OBJEXT): {$(VPATH)}internal/dosish.h -rjit.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -rjit.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -rjit.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -rjit.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -rjit.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -rjit.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -rjit.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -rjit.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -rjit.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h -rjit.$(OBJEXT): {$(VPATH)}internal/error.h -rjit.$(OBJEXT): {$(VPATH)}internal/eval.h -rjit.$(OBJEXT): {$(VPATH)}internal/event.h -rjit.$(OBJEXT): {$(VPATH)}internal/fl_type.h -rjit.$(OBJEXT): {$(VPATH)}internal/gc.h -rjit.$(OBJEXT): {$(VPATH)}internal/glob.h -rjit.$(OBJEXT): {$(VPATH)}internal/globals.h -rjit.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -rjit.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -rjit.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -rjit.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -rjit.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -rjit.$(OBJEXT): {$(VPATH)}internal/has/extension.h -rjit.$(OBJEXT): {$(VPATH)}internal/has/feature.h -rjit.$(OBJEXT): {$(VPATH)}internal/has/warning.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/array.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/class.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/compar.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/complex.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/cont.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/dir.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/enum.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/error.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/eval.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/file.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/hash.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/io.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/load.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/object.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/parse.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/proc.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/process.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/random.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/range.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/rational.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/re.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/select.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/signal.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/string.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/struct.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/thread.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/time.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/variable.h -rjit.$(OBJEXT): {$(VPATH)}internal/intern/vm.h -rjit.$(OBJEXT): {$(VPATH)}internal/interpreter.h -rjit.$(OBJEXT): {$(VPATH)}internal/iterator.h -rjit.$(OBJEXT): {$(VPATH)}internal/memory.h -rjit.$(OBJEXT): {$(VPATH)}internal/method.h -rjit.$(OBJEXT): {$(VPATH)}internal/module.h -rjit.$(OBJEXT): {$(VPATH)}internal/newobj.h -rjit.$(OBJEXT): {$(VPATH)}internal/scan_args.h -rjit.$(OBJEXT): {$(VPATH)}internal/special_consts.h -rjit.$(OBJEXT): {$(VPATH)}internal/static_assert.h -rjit.$(OBJEXT): {$(VPATH)}internal/stdalign.h -rjit.$(OBJEXT): {$(VPATH)}internal/stdbool.h -rjit.$(OBJEXT): {$(VPATH)}internal/stdckdint.h -rjit.$(OBJEXT): {$(VPATH)}internal/symbol.h -rjit.$(OBJEXT): {$(VPATH)}internal/value.h -rjit.$(OBJEXT): {$(VPATH)}internal/value_type.h -rjit.$(OBJEXT): {$(VPATH)}internal/variable.h -rjit.$(OBJEXT): {$(VPATH)}internal/warning_push.h -rjit.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -rjit.$(OBJEXT): {$(VPATH)}iseq.h -rjit.$(OBJEXT): {$(VPATH)}method.h -rjit.$(OBJEXT): {$(VPATH)}missing.h -rjit.$(OBJEXT): {$(VPATH)}node.h -rjit.$(OBJEXT): {$(VPATH)}onigmo.h -rjit.$(OBJEXT): {$(VPATH)}oniguruma.h -rjit.$(OBJEXT): {$(VPATH)}prism/ast.h -rjit.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -rjit.$(OBJEXT): {$(VPATH)}prism/version.h -rjit.$(OBJEXT): {$(VPATH)}prism_compile.h -rjit.$(OBJEXT): {$(VPATH)}ractor.h -rjit.$(OBJEXT): {$(VPATH)}ractor_core.h -rjit.$(OBJEXT): {$(VPATH)}rjit.c -rjit.$(OBJEXT): {$(VPATH)}rjit.h -rjit.$(OBJEXT): {$(VPATH)}rjit.rbinc -rjit.$(OBJEXT): {$(VPATH)}rjit_c.h -rjit.$(OBJEXT): {$(VPATH)}ruby_assert.h -rjit.$(OBJEXT): {$(VPATH)}ruby_atomic.h -rjit.$(OBJEXT): {$(VPATH)}rubyparser.h -rjit.$(OBJEXT): {$(VPATH)}shape.h -rjit.$(OBJEXT): {$(VPATH)}st.h -rjit.$(OBJEXT): {$(VPATH)}subst.h -rjit.$(OBJEXT): {$(VPATH)}thread.h -rjit.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -rjit.$(OBJEXT): {$(VPATH)}thread_native.h -rjit.$(OBJEXT): {$(VPATH)}util.h -rjit.$(OBJEXT): {$(VPATH)}vm_callinfo.h -rjit.$(OBJEXT): {$(VPATH)}vm_core.h -rjit.$(OBJEXT): {$(VPATH)}vm_debug.h -rjit.$(OBJEXT): {$(VPATH)}vm_opts.h -rjit.$(OBJEXT): {$(VPATH)}vm_sync.h -rjit.$(OBJEXT): {$(VPATH)}yjit.h -rjit_c.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -rjit_c.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -rjit_c.$(OBJEXT): $(CCAN_DIR)/list/list.h -rjit_c.$(OBJEXT): $(CCAN_DIR)/str/str.h -rjit_c.$(OBJEXT): $(hdrdir)/ruby.h -rjit_c.$(OBJEXT): $(hdrdir)/ruby/ruby.h -rjit_c.$(OBJEXT): $(srcdir)/rjit_c.rb -rjit_c.$(OBJEXT): $(top_srcdir)/internal/array.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/class.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/compile.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/compilers.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/fixnum.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/gc.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/hash.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/imemo.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/object.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/proc.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/serial.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/static_assert.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/string.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/struct.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/variable.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/vm.h -rjit_c.$(OBJEXT): $(top_srcdir)/internal/warnings.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/defines.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/encoding.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/node.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/options.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/pack.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/parser.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/prism.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/regexp.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -rjit_c.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h -rjit_c.$(OBJEXT): {$(VPATH)}assert.h -rjit_c.$(OBJEXT): {$(VPATH)}atomic.h -rjit_c.$(OBJEXT): {$(VPATH)}backward/2/assume.h -rjit_c.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -rjit_c.$(OBJEXT): {$(VPATH)}backward/2/bool.h -rjit_c.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h -rjit_c.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h -rjit_c.$(OBJEXT): {$(VPATH)}backward/2/limits.h -rjit_c.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -rjit_c.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -rjit_c.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -rjit_c.$(OBJEXT): {$(VPATH)}builtin.h -rjit_c.$(OBJEXT): {$(VPATH)}config.h -rjit_c.$(OBJEXT): {$(VPATH)}constant.h -rjit_c.$(OBJEXT): {$(VPATH)}debug.h -rjit_c.$(OBJEXT): {$(VPATH)}debug_counter.h -rjit_c.$(OBJEXT): {$(VPATH)}defines.h -rjit_c.$(OBJEXT): {$(VPATH)}encoding.h -rjit_c.$(OBJEXT): {$(VPATH)}id.h -rjit_c.$(OBJEXT): {$(VPATH)}id_table.h -rjit_c.$(OBJEXT): {$(VPATH)}insns.def -rjit_c.$(OBJEXT): {$(VPATH)}insns.inc -rjit_c.$(OBJEXT): {$(VPATH)}insns_info.inc -rjit_c.$(OBJEXT): {$(VPATH)}intern.h -rjit_c.$(OBJEXT): {$(VPATH)}internal.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/abi.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/anyargs.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/assume.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/const.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/error.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/format.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/cast.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/config.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/constant_p.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/core.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rarray.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rclass.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rdata.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rfile.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rhash.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/core/robject.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rstring.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/ctype.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/dllexport.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/dosish.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/error.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/eval.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/event.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/fl_type.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/gc.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/glob.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/globals.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/has/extension.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/has/feature.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/has/warning.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/array.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/class.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/compar.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/complex.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/cont.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/dir.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/enum.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/error.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/eval.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/file.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/hash.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/io.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/load.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/object.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/parse.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/proc.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/process.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/random.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/range.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/rational.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/re.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/select.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/signal.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/string.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/struct.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/thread.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/time.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/variable.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/intern/vm.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/interpreter.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/iterator.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/memory.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/method.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/module.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/newobj.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/scan_args.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/special_consts.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/static_assert.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/stdalign.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/stdbool.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/stdckdint.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/symbol.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/value.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/value_type.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/variable.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/warning_push.h -rjit_c.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -rjit_c.$(OBJEXT): {$(VPATH)}iseq.h -rjit_c.$(OBJEXT): {$(VPATH)}method.h -rjit_c.$(OBJEXT): {$(VPATH)}missing.h -rjit_c.$(OBJEXT): {$(VPATH)}node.h -rjit_c.$(OBJEXT): {$(VPATH)}onigmo.h -rjit_c.$(OBJEXT): {$(VPATH)}oniguruma.h -rjit_c.$(OBJEXT): {$(VPATH)}prism/ast.h -rjit_c.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -rjit_c.$(OBJEXT): {$(VPATH)}prism/version.h -rjit_c.$(OBJEXT): {$(VPATH)}prism_compile.h -rjit_c.$(OBJEXT): {$(VPATH)}probes.dmyh -rjit_c.$(OBJEXT): {$(VPATH)}probes.h -rjit_c.$(OBJEXT): {$(VPATH)}probes_helper.h -rjit_c.$(OBJEXT): {$(VPATH)}rjit.h -rjit_c.$(OBJEXT): {$(VPATH)}rjit_c.c -rjit_c.$(OBJEXT): {$(VPATH)}rjit_c.h -rjit_c.$(OBJEXT): {$(VPATH)}rjit_c.rb -rjit_c.$(OBJEXT): {$(VPATH)}rjit_c.rbinc -rjit_c.$(OBJEXT): {$(VPATH)}ruby_assert.h -rjit_c.$(OBJEXT): {$(VPATH)}ruby_atomic.h -rjit_c.$(OBJEXT): {$(VPATH)}rubyparser.h -rjit_c.$(OBJEXT): {$(VPATH)}shape.h -rjit_c.$(OBJEXT): {$(VPATH)}st.h -rjit_c.$(OBJEXT): {$(VPATH)}subst.h -rjit_c.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -rjit_c.$(OBJEXT): {$(VPATH)}thread_native.h -rjit_c.$(OBJEXT): {$(VPATH)}vm_callinfo.h -rjit_c.$(OBJEXT): {$(VPATH)}vm_core.h -rjit_c.$(OBJEXT): {$(VPATH)}vm_debug.h -rjit_c.$(OBJEXT): {$(VPATH)}vm_exec.h -rjit_c.$(OBJEXT): {$(VPATH)}vm_insnhelper.h -rjit_c.$(OBJEXT): {$(VPATH)}vm_opts.h -rjit_c.$(OBJEXT): {$(VPATH)}vm_sync.h -rjit_c.$(OBJEXT): {$(VPATH)}yjit.h ruby-runner.$(OBJEXT): {$(VPATH)}config.h ruby-runner.$(OBJEXT): {$(VPATH)}internal/compiler_is.h ruby-runner.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h @@ -16009,16 +13548,12 @@ ruby.$(OBJEXT): $(hdrdir)/ruby/ruby.h ruby.$(OBJEXT): $(hdrdir)/ruby/version.h ruby.$(OBJEXT): $(top_srcdir)/internal/array.h ruby.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h -ruby.$(OBJEXT): $(top_srcdir)/internal/bignum.h -ruby.$(OBJEXT): $(top_srcdir)/internal/bits.h ruby.$(OBJEXT): $(top_srcdir)/internal/class.h ruby.$(OBJEXT): $(top_srcdir)/internal/cmdlineopt.h ruby.$(OBJEXT): $(top_srcdir)/internal/compilers.h -ruby.$(OBJEXT): $(top_srcdir)/internal/complex.h ruby.$(OBJEXT): $(top_srcdir)/internal/cont.h ruby.$(OBJEXT): $(top_srcdir)/internal/error.h ruby.$(OBJEXT): $(top_srcdir)/internal/file.h -ruby.$(OBJEXT): $(top_srcdir)/internal/fixnum.h ruby.$(OBJEXT): $(top_srcdir)/internal/gc.h ruby.$(OBJEXT): $(top_srcdir)/internal/imemo.h ruby.$(OBJEXT): $(top_srcdir)/internal/inits.h @@ -16026,39 +13561,15 @@ ruby.$(OBJEXT): $(top_srcdir)/internal/io.h ruby.$(OBJEXT): $(top_srcdir)/internal/load.h ruby.$(OBJEXT): $(top_srcdir)/internal/loadpath.h ruby.$(OBJEXT): $(top_srcdir)/internal/missing.h -ruby.$(OBJEXT): $(top_srcdir)/internal/numeric.h ruby.$(OBJEXT): $(top_srcdir)/internal/object.h ruby.$(OBJEXT): $(top_srcdir)/internal/parse.h -ruby.$(OBJEXT): $(top_srcdir)/internal/rational.h -ruby.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h -ruby.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h +ruby.$(OBJEXT): $(top_srcdir)/internal/process.h ruby.$(OBJEXT): $(top_srcdir)/internal/serial.h ruby.$(OBJEXT): $(top_srcdir)/internal/static_assert.h ruby.$(OBJEXT): $(top_srcdir)/internal/string.h -ruby.$(OBJEXT): $(top_srcdir)/internal/thread.h ruby.$(OBJEXT): $(top_srcdir)/internal/variable.h ruby.$(OBJEXT): $(top_srcdir)/internal/vm.h ruby.$(OBJEXT): $(top_srcdir)/internal/warnings.h -ruby.$(OBJEXT): $(top_srcdir)/prism/defines.h -ruby.$(OBJEXT): $(top_srcdir)/prism/encoding.h -ruby.$(OBJEXT): $(top_srcdir)/prism/node.h -ruby.$(OBJEXT): $(top_srcdir)/prism/options.h -ruby.$(OBJEXT): $(top_srcdir)/prism/pack.h -ruby.$(OBJEXT): $(top_srcdir)/prism/parser.h -ruby.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -ruby.$(OBJEXT): $(top_srcdir)/prism/prism.h -ruby.$(OBJEXT): $(top_srcdir)/prism/regexp.h -ruby.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -ruby.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h ruby.$(OBJEXT): {$(VPATH)}assert.h ruby.$(OBJEXT): {$(VPATH)}atomic.h ruby.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -16119,7 +13630,6 @@ ruby.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h ruby.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h ruby.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h ruby.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -ruby.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h ruby.$(OBJEXT): {$(VPATH)}internal/attr/pure.h ruby.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h ruby.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -16188,6 +13698,7 @@ ruby.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h ruby.$(OBJEXT): {$(VPATH)}internal/intern/error.h ruby.$(OBJEXT): {$(VPATH)}internal/intern/eval.h ruby.$(OBJEXT): {$(VPATH)}internal/intern/file.h +ruby.$(OBJEXT): {$(VPATH)}internal/intern/gc.h ruby.$(OBJEXT): {$(VPATH)}internal/intern/hash.h ruby.$(OBJEXT): {$(VPATH)}internal/intern/io.h ruby.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -16218,12 +13729,12 @@ ruby.$(OBJEXT): {$(VPATH)}internal/memory.h ruby.$(OBJEXT): {$(VPATH)}internal/method.h ruby.$(OBJEXT): {$(VPATH)}internal/module.h ruby.$(OBJEXT): {$(VPATH)}internal/newobj.h +ruby.$(OBJEXT): {$(VPATH)}internal/rgengc.h ruby.$(OBJEXT): {$(VPATH)}internal/scan_args.h ruby.$(OBJEXT): {$(VPATH)}internal/special_consts.h ruby.$(OBJEXT): {$(VPATH)}internal/static_assert.h ruby.$(OBJEXT): {$(VPATH)}internal/stdalign.h ruby.$(OBJEXT): {$(VPATH)}internal/stdbool.h -ruby.$(OBJEXT): {$(VPATH)}internal/stdckdint.h ruby.$(OBJEXT): {$(VPATH)}internal/symbol.h ruby.$(OBJEXT): {$(VPATH)}internal/value.h ruby.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -16234,18 +13745,13 @@ ruby.$(OBJEXT): {$(VPATH)}io.h ruby.$(OBJEXT): {$(VPATH)}iseq.h ruby.$(OBJEXT): {$(VPATH)}method.h ruby.$(OBJEXT): {$(VPATH)}missing.h +ruby.$(OBJEXT): {$(VPATH)}mjit.h ruby.$(OBJEXT): {$(VPATH)}node.h ruby.$(OBJEXT): {$(VPATH)}onigmo.h ruby.$(OBJEXT): {$(VPATH)}oniguruma.h -ruby.$(OBJEXT): {$(VPATH)}prism/ast.h -ruby.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -ruby.$(OBJEXT): {$(VPATH)}prism/version.h -ruby.$(OBJEXT): {$(VPATH)}prism_compile.h -ruby.$(OBJEXT): {$(VPATH)}rjit.h ruby.$(OBJEXT): {$(VPATH)}ruby.c ruby.$(OBJEXT): {$(VPATH)}ruby_assert.h ruby.$(OBJEXT): {$(VPATH)}ruby_atomic.h -ruby.$(OBJEXT): {$(VPATH)}rubyparser.h ruby.$(OBJEXT): {$(VPATH)}shape.h ruby.$(OBJEXT): {$(VPATH)}st.h ruby.$(OBJEXT): {$(VPATH)}subst.h @@ -16256,197 +13762,6 @@ ruby.$(OBJEXT): {$(VPATH)}util.h ruby.$(OBJEXT): {$(VPATH)}vm_core.h ruby.$(OBJEXT): {$(VPATH)}vm_opts.h ruby.$(OBJEXT): {$(VPATH)}yjit.h -ruby_parser.$(OBJEXT): $(hdrdir)/ruby/ruby.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/array.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/bignum.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/bits.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/compilers.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/complex.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/error.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/fixnum.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/imemo.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/numeric.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/parse.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/rational.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/re.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/serial.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/static_assert.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/string.h -ruby_parser.$(OBJEXT): $(top_srcdir)/internal/vm.h -ruby_parser.$(OBJEXT): {$(VPATH)}assert.h -ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/assume.h -ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/bool.h -ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h -ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h -ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/limits.h -ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -ruby_parser.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -ruby_parser.$(OBJEXT): {$(VPATH)}config.h -ruby_parser.$(OBJEXT): {$(VPATH)}defines.h -ruby_parser.$(OBJEXT): {$(VPATH)}encoding.h -ruby_parser.$(OBJEXT): {$(VPATH)}intern.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/abi.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/anyargs.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/assume.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/const.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/error.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/format.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/cast.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/config.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/constant_p.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/core.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/core/rarray.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/core/rclass.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/core/rdata.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/core/rfile.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/core/rhash.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/core/robject.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/core/rstring.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/ctype.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/dllexport.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/dosish.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/error.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/eval.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/event.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/fl_type.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/gc.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/glob.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/globals.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/has/extension.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/has/feature.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/has/warning.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/array.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/class.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/compar.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/complex.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/cont.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/dir.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/enum.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/error.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/eval.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/file.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/hash.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/io.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/load.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/object.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/parse.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/proc.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/process.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/random.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/range.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/rational.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/re.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/select.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/signal.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/string.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/struct.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/thread.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/time.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/variable.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/intern/vm.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/interpreter.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/iterator.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/memory.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/method.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/module.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/newobj.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/scan_args.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/special_consts.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/static_assert.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/stdalign.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/stdbool.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/stdckdint.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/symbol.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/value.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/value_type.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/variable.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/warning_push.h -ruby_parser.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -ruby_parser.$(OBJEXT): {$(VPATH)}missing.h -ruby_parser.$(OBJEXT): {$(VPATH)}node.h -ruby_parser.$(OBJEXT): {$(VPATH)}onigmo.h -ruby_parser.$(OBJEXT): {$(VPATH)}oniguruma.h -ruby_parser.$(OBJEXT): {$(VPATH)}ruby_assert.h -ruby_parser.$(OBJEXT): {$(VPATH)}ruby_parser.c -ruby_parser.$(OBJEXT): {$(VPATH)}rubyparser.h -ruby_parser.$(OBJEXT): {$(VPATH)}st.h -ruby_parser.$(OBJEXT): {$(VPATH)}subst.h scheduler.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h scheduler.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h scheduler.$(OBJEXT): $(CCAN_DIR)/list/list.h @@ -16457,7 +13772,6 @@ scheduler.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h scheduler.$(OBJEXT): $(top_srcdir)/internal/compilers.h scheduler.$(OBJEXT): $(top_srcdir)/internal/gc.h scheduler.$(OBJEXT): $(top_srcdir)/internal/imemo.h -scheduler.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h scheduler.$(OBJEXT): $(top_srcdir)/internal/serial.h scheduler.$(OBJEXT): $(top_srcdir)/internal/static_assert.h scheduler.$(OBJEXT): $(top_srcdir)/internal/thread.h @@ -16522,7 +13836,6 @@ scheduler.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h scheduler.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h scheduler.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h scheduler.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -scheduler.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h scheduler.$(OBJEXT): {$(VPATH)}internal/attr/pure.h scheduler.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h scheduler.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -16591,6 +13904,7 @@ scheduler.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h scheduler.$(OBJEXT): {$(VPATH)}internal/intern/error.h scheduler.$(OBJEXT): {$(VPATH)}internal/intern/eval.h scheduler.$(OBJEXT): {$(VPATH)}internal/intern/file.h +scheduler.$(OBJEXT): {$(VPATH)}internal/intern/gc.h scheduler.$(OBJEXT): {$(VPATH)}internal/intern/hash.h scheduler.$(OBJEXT): {$(VPATH)}internal/intern/io.h scheduler.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -16621,12 +13935,12 @@ scheduler.$(OBJEXT): {$(VPATH)}internal/memory.h scheduler.$(OBJEXT): {$(VPATH)}internal/method.h scheduler.$(OBJEXT): {$(VPATH)}internal/module.h scheduler.$(OBJEXT): {$(VPATH)}internal/newobj.h +scheduler.$(OBJEXT): {$(VPATH)}internal/rgengc.h scheduler.$(OBJEXT): {$(VPATH)}internal/scan_args.h scheduler.$(OBJEXT): {$(VPATH)}internal/special_consts.h scheduler.$(OBJEXT): {$(VPATH)}internal/static_assert.h scheduler.$(OBJEXT): {$(VPATH)}internal/stdalign.h scheduler.$(OBJEXT): {$(VPATH)}internal/stdbool.h -scheduler.$(OBJEXT): {$(VPATH)}internal/stdckdint.h scheduler.$(OBJEXT): {$(VPATH)}internal/symbol.h scheduler.$(OBJEXT): {$(VPATH)}internal/value.h scheduler.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -16642,7 +13956,6 @@ scheduler.$(OBJEXT): {$(VPATH)}onigmo.h scheduler.$(OBJEXT): {$(VPATH)}oniguruma.h scheduler.$(OBJEXT): {$(VPATH)}ruby_assert.h scheduler.$(OBJEXT): {$(VPATH)}ruby_atomic.h -scheduler.$(OBJEXT): {$(VPATH)}rubyparser.h scheduler.$(OBJEXT): {$(VPATH)}scheduler.c scheduler.$(OBJEXT): {$(VPATH)}shape.h scheduler.$(OBJEXT): {$(VPATH)}st.h @@ -16703,7 +14016,6 @@ setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/pure.h setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h setproctitle.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -16763,6 +14075,7 @@ setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/error.h setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/eval.h setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/file.h +setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/gc.h setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/hash.h setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/io.h setproctitle.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -16793,12 +14106,12 @@ setproctitle.$(OBJEXT): {$(VPATH)}internal/memory.h setproctitle.$(OBJEXT): {$(VPATH)}internal/method.h setproctitle.$(OBJEXT): {$(VPATH)}internal/module.h setproctitle.$(OBJEXT): {$(VPATH)}internal/newobj.h +setproctitle.$(OBJEXT): {$(VPATH)}internal/rgengc.h setproctitle.$(OBJEXT): {$(VPATH)}internal/scan_args.h setproctitle.$(OBJEXT): {$(VPATH)}internal/special_consts.h setproctitle.$(OBJEXT): {$(VPATH)}internal/static_assert.h setproctitle.$(OBJEXT): {$(VPATH)}internal/stdalign.h setproctitle.$(OBJEXT): {$(VPATH)}internal/stdbool.h -setproctitle.$(OBJEXT): {$(VPATH)}internal/stdckdint.h setproctitle.$(OBJEXT): {$(VPATH)}internal/symbol.h setproctitle.$(OBJEXT): {$(VPATH)}internal/value.h setproctitle.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -16815,19 +14128,14 @@ shape.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h shape.$(OBJEXT): $(CCAN_DIR)/list/list.h shape.$(OBJEXT): $(CCAN_DIR)/str/str.h shape.$(OBJEXT): $(hdrdir)/ruby/ruby.h -shape.$(OBJEXT): $(hdrdir)/ruby/version.h shape.$(OBJEXT): $(top_srcdir)/internal/array.h shape.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h shape.$(OBJEXT): $(top_srcdir)/internal/class.h shape.$(OBJEXT): $(top_srcdir)/internal/compilers.h -shape.$(OBJEXT): $(top_srcdir)/internal/error.h shape.$(OBJEXT): $(top_srcdir)/internal/gc.h shape.$(OBJEXT): $(top_srcdir)/internal/imemo.h -shape.$(OBJEXT): $(top_srcdir)/internal/object.h -shape.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h shape.$(OBJEXT): $(top_srcdir)/internal/serial.h shape.$(OBJEXT): $(top_srcdir)/internal/static_assert.h -shape.$(OBJEXT): $(top_srcdir)/internal/string.h shape.$(OBJEXT): $(top_srcdir)/internal/symbol.h shape.$(OBJEXT): $(top_srcdir)/internal/variable.h shape.$(OBJEXT): $(top_srcdir)/internal/vm.h @@ -16848,6 +14156,7 @@ shape.$(OBJEXT): {$(VPATH)}constant.h shape.$(OBJEXT): {$(VPATH)}debug_counter.h shape.$(OBJEXT): {$(VPATH)}defines.h shape.$(OBJEXT): {$(VPATH)}encoding.h +shape.$(OBJEXT): {$(VPATH)}gc.h shape.$(OBJEXT): {$(VPATH)}id.h shape.$(OBJEXT): {$(VPATH)}id_table.h shape.$(OBJEXT): {$(VPATH)}intern.h @@ -16890,7 +14199,6 @@ shape.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h shape.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h shape.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h shape.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -shape.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h shape.$(OBJEXT): {$(VPATH)}internal/attr/pure.h shape.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h shape.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -16959,6 +14267,7 @@ shape.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h shape.$(OBJEXT): {$(VPATH)}internal/intern/error.h shape.$(OBJEXT): {$(VPATH)}internal/intern/eval.h shape.$(OBJEXT): {$(VPATH)}internal/intern/file.h +shape.$(OBJEXT): {$(VPATH)}internal/intern/gc.h shape.$(OBJEXT): {$(VPATH)}internal/intern/hash.h shape.$(OBJEXT): {$(VPATH)}internal/intern/io.h shape.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -16989,12 +14298,12 @@ shape.$(OBJEXT): {$(VPATH)}internal/memory.h shape.$(OBJEXT): {$(VPATH)}internal/method.h shape.$(OBJEXT): {$(VPATH)}internal/module.h shape.$(OBJEXT): {$(VPATH)}internal/newobj.h +shape.$(OBJEXT): {$(VPATH)}internal/rgengc.h shape.$(OBJEXT): {$(VPATH)}internal/scan_args.h shape.$(OBJEXT): {$(VPATH)}internal/special_consts.h shape.$(OBJEXT): {$(VPATH)}internal/static_assert.h shape.$(OBJEXT): {$(VPATH)}internal/stdalign.h shape.$(OBJEXT): {$(VPATH)}internal/stdbool.h -shape.$(OBJEXT): {$(VPATH)}internal/stdckdint.h shape.$(OBJEXT): {$(VPATH)}internal/symbol.h shape.$(OBJEXT): {$(VPATH)}internal/value.h shape.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -17008,7 +14317,6 @@ shape.$(OBJEXT): {$(VPATH)}onigmo.h shape.$(OBJEXT): {$(VPATH)}oniguruma.h shape.$(OBJEXT): {$(VPATH)}ruby_assert.h shape.$(OBJEXT): {$(VPATH)}ruby_atomic.h -shape.$(OBJEXT): {$(VPATH)}rubyparser.h shape.$(OBJEXT): {$(VPATH)}shape.c shape.$(OBJEXT): {$(VPATH)}shape.h shape.$(OBJEXT): {$(VPATH)}st.h @@ -17026,11 +14334,9 @@ signal.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h signal.$(OBJEXT): $(CCAN_DIR)/list/list.h signal.$(OBJEXT): $(CCAN_DIR)/str/str.h signal.$(OBJEXT): $(hdrdir)/ruby/ruby.h -signal.$(OBJEXT): $(hdrdir)/ruby/version.h signal.$(OBJEXT): $(top_srcdir)/internal/array.h signal.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h signal.$(OBJEXT): $(top_srcdir)/internal/compilers.h -signal.$(OBJEXT): $(top_srcdir)/internal/error.h signal.$(OBJEXT): $(top_srcdir)/internal/eval.h signal.$(OBJEXT): $(top_srcdir)/internal/gc.h signal.$(OBJEXT): $(top_srcdir)/internal/imemo.h @@ -17101,8 +14407,8 @@ 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/packed_struct.h signal.$(OBJEXT): {$(VPATH)}internal/attr/pure.h signal.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h signal.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -17171,6 +14477,7 @@ signal.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h signal.$(OBJEXT): {$(VPATH)}internal/intern/error.h signal.$(OBJEXT): {$(VPATH)}internal/intern/eval.h signal.$(OBJEXT): {$(VPATH)}internal/intern/file.h +signal.$(OBJEXT): {$(VPATH)}internal/intern/gc.h signal.$(OBJEXT): {$(VPATH)}internal/intern/hash.h signal.$(OBJEXT): {$(VPATH)}internal/intern/io.h signal.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -17201,12 +14508,12 @@ signal.$(OBJEXT): {$(VPATH)}internal/memory.h signal.$(OBJEXT): {$(VPATH)}internal/method.h signal.$(OBJEXT): {$(VPATH)}internal/module.h signal.$(OBJEXT): {$(VPATH)}internal/newobj.h +signal.$(OBJEXT): {$(VPATH)}internal/rgengc.h signal.$(OBJEXT): {$(VPATH)}internal/scan_args.h signal.$(OBJEXT): {$(VPATH)}internal/special_consts.h signal.$(OBJEXT): {$(VPATH)}internal/static_assert.h signal.$(OBJEXT): {$(VPATH)}internal/stdalign.h signal.$(OBJEXT): {$(VPATH)}internal/stdbool.h -signal.$(OBJEXT): {$(VPATH)}internal/stdckdint.h signal.$(OBJEXT): {$(VPATH)}internal/symbol.h signal.$(OBJEXT): {$(VPATH)}internal/value.h signal.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -17222,7 +14529,6 @@ signal.$(OBJEXT): {$(VPATH)}ractor.h signal.$(OBJEXT): {$(VPATH)}ractor_core.h signal.$(OBJEXT): {$(VPATH)}ruby_assert.h signal.$(OBJEXT): {$(VPATH)}ruby_atomic.h -signal.$(OBJEXT): {$(VPATH)}rubyparser.h signal.$(OBJEXT): {$(VPATH)}shape.h signal.$(OBJEXT): {$(VPATH)}signal.c signal.$(OBJEXT): {$(VPATH)}st.h @@ -17233,7 +14539,6 @@ signal.$(OBJEXT): {$(VPATH)}vm_core.h signal.$(OBJEXT): {$(VPATH)}vm_debug.h signal.$(OBJEXT): {$(VPATH)}vm_opts.h sprintf.$(OBJEXT): $(hdrdir)/ruby/ruby.h -sprintf.$(OBJEXT): $(hdrdir)/ruby/version.h sprintf.$(OBJEXT): $(top_srcdir)/internal/bignum.h sprintf.$(OBJEXT): $(top_srcdir)/internal/bits.h sprintf.$(OBJEXT): $(top_srcdir)/internal/class.h @@ -17308,7 +14613,6 @@ sprintf.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h sprintf.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h sprintf.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h sprintf.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -sprintf.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h sprintf.$(OBJEXT): {$(VPATH)}internal/attr/pure.h sprintf.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h sprintf.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -17378,6 +14682,7 @@ sprintf.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h sprintf.$(OBJEXT): {$(VPATH)}internal/intern/error.h sprintf.$(OBJEXT): {$(VPATH)}internal/intern/eval.h sprintf.$(OBJEXT): {$(VPATH)}internal/intern/file.h +sprintf.$(OBJEXT): {$(VPATH)}internal/intern/gc.h sprintf.$(OBJEXT): {$(VPATH)}internal/intern/hash.h sprintf.$(OBJEXT): {$(VPATH)}internal/intern/io.h sprintf.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -17408,12 +14713,12 @@ sprintf.$(OBJEXT): {$(VPATH)}internal/memory.h sprintf.$(OBJEXT): {$(VPATH)}internal/method.h sprintf.$(OBJEXT): {$(VPATH)}internal/module.h sprintf.$(OBJEXT): {$(VPATH)}internal/newobj.h +sprintf.$(OBJEXT): {$(VPATH)}internal/rgengc.h sprintf.$(OBJEXT): {$(VPATH)}internal/scan_args.h sprintf.$(OBJEXT): {$(VPATH)}internal/special_consts.h sprintf.$(OBJEXT): {$(VPATH)}internal/static_assert.h sprintf.$(OBJEXT): {$(VPATH)}internal/stdalign.h sprintf.$(OBJEXT): {$(VPATH)}internal/stdbool.h -sprintf.$(OBJEXT): {$(VPATH)}internal/stdckdint.h sprintf.$(OBJEXT): {$(VPATH)}internal/symbol.h sprintf.$(OBJEXT): {$(VPATH)}internal/value.h sprintf.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -17436,7 +14741,6 @@ st.$(OBJEXT): $(top_srcdir)/internal/bits.h st.$(OBJEXT): $(top_srcdir)/internal/compilers.h st.$(OBJEXT): $(top_srcdir)/internal/hash.h st.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h -st.$(OBJEXT): $(top_srcdir)/internal/st.h st.$(OBJEXT): $(top_srcdir)/internal/static_assert.h st.$(OBJEXT): $(top_srcdir)/internal/warnings.h st.$(OBJEXT): {$(VPATH)}assert.h @@ -17491,7 +14795,6 @@ st.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h st.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h st.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h st.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -st.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h st.$(OBJEXT): {$(VPATH)}internal/attr/pure.h st.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h st.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -17551,6 +14854,7 @@ st.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h st.$(OBJEXT): {$(VPATH)}internal/intern/error.h st.$(OBJEXT): {$(VPATH)}internal/intern/eval.h st.$(OBJEXT): {$(VPATH)}internal/intern/file.h +st.$(OBJEXT): {$(VPATH)}internal/intern/gc.h st.$(OBJEXT): {$(VPATH)}internal/intern/hash.h st.$(OBJEXT): {$(VPATH)}internal/intern/io.h st.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -17581,13 +14885,12 @@ st.$(OBJEXT): {$(VPATH)}internal/memory.h st.$(OBJEXT): {$(VPATH)}internal/method.h st.$(OBJEXT): {$(VPATH)}internal/module.h st.$(OBJEXT): {$(VPATH)}internal/newobj.h +st.$(OBJEXT): {$(VPATH)}internal/rgengc.h st.$(OBJEXT): {$(VPATH)}internal/scan_args.h st.$(OBJEXT): {$(VPATH)}internal/special_consts.h -st.$(OBJEXT): {$(VPATH)}internal/st.h st.$(OBJEXT): {$(VPATH)}internal/static_assert.h st.$(OBJEXT): {$(VPATH)}internal/stdalign.h st.$(OBJEXT): {$(VPATH)}internal/stdbool.h -st.$(OBJEXT): {$(VPATH)}internal/stdckdint.h st.$(OBJEXT): {$(VPATH)}internal/symbol.h st.$(OBJEXT): {$(VPATH)}internal/value.h st.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -17595,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 @@ -17658,7 +14962,6 @@ strftime.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h strftime.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h strftime.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h strftime.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -strftime.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h strftime.$(OBJEXT): {$(VPATH)}internal/attr/pure.h strftime.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h strftime.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -17727,6 +15030,7 @@ strftime.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h strftime.$(OBJEXT): {$(VPATH)}internal/intern/error.h strftime.$(OBJEXT): {$(VPATH)}internal/intern/eval.h strftime.$(OBJEXT): {$(VPATH)}internal/intern/file.h +strftime.$(OBJEXT): {$(VPATH)}internal/intern/gc.h strftime.$(OBJEXT): {$(VPATH)}internal/intern/hash.h strftime.$(OBJEXT): {$(VPATH)}internal/intern/io.h strftime.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -17757,12 +15061,12 @@ strftime.$(OBJEXT): {$(VPATH)}internal/memory.h strftime.$(OBJEXT): {$(VPATH)}internal/method.h strftime.$(OBJEXT): {$(VPATH)}internal/module.h strftime.$(OBJEXT): {$(VPATH)}internal/newobj.h +strftime.$(OBJEXT): {$(VPATH)}internal/rgengc.h strftime.$(OBJEXT): {$(VPATH)}internal/scan_args.h strftime.$(OBJEXT): {$(VPATH)}internal/special_consts.h strftime.$(OBJEXT): {$(VPATH)}internal/static_assert.h strftime.$(OBJEXT): {$(VPATH)}internal/stdalign.h strftime.$(OBJEXT): {$(VPATH)}internal/stdbool.h -strftime.$(OBJEXT): {$(VPATH)}internal/stdckdint.h strftime.$(OBJEXT): {$(VPATH)}internal/symbol.h strftime.$(OBJEXT): {$(VPATH)}internal/value.h strftime.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -17777,12 +15081,7 @@ strftime.$(OBJEXT): {$(VPATH)}strftime.c strftime.$(OBJEXT): {$(VPATH)}subst.h strftime.$(OBJEXT): {$(VPATH)}timev.h strftime.$(OBJEXT): {$(VPATH)}util.h -string.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -string.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -string.$(OBJEXT): $(CCAN_DIR)/list/list.h -string.$(OBJEXT): $(CCAN_DIR)/str/str.h string.$(OBJEXT): $(hdrdir)/ruby/ruby.h -string.$(OBJEXT): $(hdrdir)/ruby/version.h string.$(OBJEXT): $(top_srcdir)/internal/array.h string.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h string.$(OBJEXT): $(top_srcdir)/internal/bignum.h @@ -17794,7 +15093,6 @@ string.$(OBJEXT): $(top_srcdir)/internal/encoding.h string.$(OBJEXT): $(top_srcdir)/internal/error.h string.$(OBJEXT): $(top_srcdir)/internal/fixnum.h string.$(OBJEXT): $(top_srcdir)/internal/gc.h -string.$(OBJEXT): $(top_srcdir)/internal/imemo.h string.$(OBJEXT): $(top_srcdir)/internal/numeric.h string.$(OBJEXT): $(top_srcdir)/internal/object.h string.$(OBJEXT): $(top_srcdir)/internal/proc.h @@ -17824,6 +15122,7 @@ string.$(OBJEXT): {$(VPATH)}debug_counter.h string.$(OBJEXT): {$(VPATH)}defines.h string.$(OBJEXT): {$(VPATH)}encindex.h string.$(OBJEXT): {$(VPATH)}encoding.h +string.$(OBJEXT): {$(VPATH)}gc.h string.$(OBJEXT): {$(VPATH)}id.h string.$(OBJEXT): {$(VPATH)}id_table.h string.$(OBJEXT): {$(VPATH)}intern.h @@ -17865,8 +15164,8 @@ 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/packed_struct.h string.$(OBJEXT): {$(VPATH)}internal/attr/pure.h string.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h string.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -17936,6 +15235,7 @@ string.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h string.$(OBJEXT): {$(VPATH)}internal/intern/error.h string.$(OBJEXT): {$(VPATH)}internal/intern/eval.h string.$(OBJEXT): {$(VPATH)}internal/intern/file.h +string.$(OBJEXT): {$(VPATH)}internal/intern/gc.h string.$(OBJEXT): {$(VPATH)}internal/intern/hash.h string.$(OBJEXT): {$(VPATH)}internal/intern/io.h string.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -17966,21 +15266,19 @@ string.$(OBJEXT): {$(VPATH)}internal/memory.h string.$(OBJEXT): {$(VPATH)}internal/method.h string.$(OBJEXT): {$(VPATH)}internal/module.h string.$(OBJEXT): {$(VPATH)}internal/newobj.h +string.$(OBJEXT): {$(VPATH)}internal/rgengc.h string.$(OBJEXT): {$(VPATH)}internal/scan_args.h string.$(OBJEXT): {$(VPATH)}internal/special_consts.h string.$(OBJEXT): {$(VPATH)}internal/static_assert.h string.$(OBJEXT): {$(VPATH)}internal/stdalign.h string.$(OBJEXT): {$(VPATH)}internal/stdbool.h -string.$(OBJEXT): {$(VPATH)}internal/stdckdint.h string.$(OBJEXT): {$(VPATH)}internal/symbol.h string.$(OBJEXT): {$(VPATH)}internal/value.h string.$(OBJEXT): {$(VPATH)}internal/value_type.h string.$(OBJEXT): {$(VPATH)}internal/variable.h string.$(OBJEXT): {$(VPATH)}internal/warning_push.h string.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -string.$(OBJEXT): {$(VPATH)}method.h string.$(OBJEXT): {$(VPATH)}missing.h -string.$(OBJEXT): {$(VPATH)}node.h string.$(OBJEXT): {$(VPATH)}onigmo.h string.$(OBJEXT): {$(VPATH)}oniguruma.h string.$(OBJEXT): {$(VPATH)}probes.dmyh @@ -17988,18 +15286,13 @@ string.$(OBJEXT): {$(VPATH)}probes.h string.$(OBJEXT): {$(VPATH)}re.h string.$(OBJEXT): {$(VPATH)}regex.h string.$(OBJEXT): {$(VPATH)}ruby_assert.h -string.$(OBJEXT): {$(VPATH)}ruby_atomic.h -string.$(OBJEXT): {$(VPATH)}rubyparser.h string.$(OBJEXT): {$(VPATH)}shape.h string.$(OBJEXT): {$(VPATH)}st.h string.$(OBJEXT): {$(VPATH)}string.c string.$(OBJEXT): {$(VPATH)}subst.h -string.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h string.$(OBJEXT): {$(VPATH)}thread_native.h string.$(OBJEXT): {$(VPATH)}util.h -string.$(OBJEXT): {$(VPATH)}vm_core.h string.$(OBJEXT): {$(VPATH)}vm_debug.h -string.$(OBJEXT): {$(VPATH)}vm_opts.h string.$(OBJEXT): {$(VPATH)}vm_sync.h strlcat.$(OBJEXT): {$(VPATH)}config.h strlcat.$(OBJEXT): {$(VPATH)}internal/attr/format.h @@ -18036,7 +15329,6 @@ struct.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h struct.$(OBJEXT): $(CCAN_DIR)/list/list.h struct.$(OBJEXT): $(CCAN_DIR)/str/str.h struct.$(OBJEXT): $(hdrdir)/ruby/ruby.h -struct.$(OBJEXT): $(hdrdir)/ruby/version.h struct.$(OBJEXT): $(top_srcdir)/internal/array.h struct.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h struct.$(OBJEXT): $(top_srcdir)/internal/class.h @@ -18047,7 +15339,6 @@ struct.$(OBJEXT): $(top_srcdir)/internal/hash.h struct.$(OBJEXT): $(top_srcdir)/internal/imemo.h struct.$(OBJEXT): $(top_srcdir)/internal/object.h struct.$(OBJEXT): $(top_srcdir)/internal/proc.h -struct.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h struct.$(OBJEXT): $(top_srcdir)/internal/serial.h struct.$(OBJEXT): $(top_srcdir)/internal/static_assert.h struct.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -18070,7 +15361,6 @@ struct.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h struct.$(OBJEXT): {$(VPATH)}builtin.h struct.$(OBJEXT): {$(VPATH)}config.h struct.$(OBJEXT): {$(VPATH)}constant.h -struct.$(OBJEXT): {$(VPATH)}debug_counter.h struct.$(OBJEXT): {$(VPATH)}defines.h struct.$(OBJEXT): {$(VPATH)}encoding.h struct.$(OBJEXT): {$(VPATH)}id.h @@ -18115,7 +15405,6 @@ struct.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h struct.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h struct.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h struct.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -struct.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h struct.$(OBJEXT): {$(VPATH)}internal/attr/pure.h struct.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h struct.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -18184,6 +15473,7 @@ struct.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h struct.$(OBJEXT): {$(VPATH)}internal/intern/error.h struct.$(OBJEXT): {$(VPATH)}internal/intern/eval.h struct.$(OBJEXT): {$(VPATH)}internal/intern/file.h +struct.$(OBJEXT): {$(VPATH)}internal/intern/gc.h struct.$(OBJEXT): {$(VPATH)}internal/intern/hash.h struct.$(OBJEXT): {$(VPATH)}internal/intern/io.h struct.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -18214,12 +15504,12 @@ struct.$(OBJEXT): {$(VPATH)}internal/memory.h struct.$(OBJEXT): {$(VPATH)}internal/method.h struct.$(OBJEXT): {$(VPATH)}internal/module.h struct.$(OBJEXT): {$(VPATH)}internal/newobj.h +struct.$(OBJEXT): {$(VPATH)}internal/rgengc.h struct.$(OBJEXT): {$(VPATH)}internal/scan_args.h struct.$(OBJEXT): {$(VPATH)}internal/special_consts.h struct.$(OBJEXT): {$(VPATH)}internal/static_assert.h struct.$(OBJEXT): {$(VPATH)}internal/stdalign.h struct.$(OBJEXT): {$(VPATH)}internal/stdbool.h -struct.$(OBJEXT): {$(VPATH)}internal/stdckdint.h struct.$(OBJEXT): {$(VPATH)}internal/symbol.h struct.$(OBJEXT): {$(VPATH)}internal/value.h struct.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -18233,33 +15523,22 @@ struct.$(OBJEXT): {$(VPATH)}onigmo.h struct.$(OBJEXT): {$(VPATH)}oniguruma.h struct.$(OBJEXT): {$(VPATH)}ruby_assert.h struct.$(OBJEXT): {$(VPATH)}ruby_atomic.h -struct.$(OBJEXT): {$(VPATH)}rubyparser.h struct.$(OBJEXT): {$(VPATH)}shape.h struct.$(OBJEXT): {$(VPATH)}st.h struct.$(OBJEXT): {$(VPATH)}struct.c struct.$(OBJEXT): {$(VPATH)}subst.h struct.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h struct.$(OBJEXT): {$(VPATH)}thread_native.h +struct.$(OBJEXT): {$(VPATH)}transient_heap.h struct.$(OBJEXT): {$(VPATH)}vm_core.h -struct.$(OBJEXT): {$(VPATH)}vm_debug.h struct.$(OBJEXT): {$(VPATH)}vm_opts.h -struct.$(OBJEXT): {$(VPATH)}vm_sync.h -symbol.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -symbol.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -symbol.$(OBJEXT): $(CCAN_DIR)/list/list.h -symbol.$(OBJEXT): $(CCAN_DIR)/str/str.h symbol.$(OBJEXT): $(hdrdir)/ruby/ruby.h -symbol.$(OBJEXT): $(hdrdir)/ruby/version.h -symbol.$(OBJEXT): $(top_srcdir)/internal/array.h -symbol.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h symbol.$(OBJEXT): $(top_srcdir)/internal/class.h symbol.$(OBJEXT): $(top_srcdir)/internal/compilers.h symbol.$(OBJEXT): $(top_srcdir)/internal/error.h symbol.$(OBJEXT): $(top_srcdir)/internal/gc.h symbol.$(OBJEXT): $(top_srcdir)/internal/hash.h -symbol.$(OBJEXT): $(top_srcdir)/internal/imemo.h symbol.$(OBJEXT): $(top_srcdir)/internal/object.h -symbol.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h symbol.$(OBJEXT): $(top_srcdir)/internal/serial.h symbol.$(OBJEXT): $(top_srcdir)/internal/static_assert.h symbol.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -18268,7 +15547,6 @@ symbol.$(OBJEXT): $(top_srcdir)/internal/variable.h symbol.$(OBJEXT): $(top_srcdir)/internal/vm.h symbol.$(OBJEXT): $(top_srcdir)/internal/warnings.h symbol.$(OBJEXT): {$(VPATH)}assert.h -symbol.$(OBJEXT): {$(VPATH)}atomic.h symbol.$(OBJEXT): {$(VPATH)}backward/2/assume.h symbol.$(OBJEXT): {$(VPATH)}backward/2/attributes.h symbol.$(OBJEXT): {$(VPATH)}backward/2/bool.h @@ -18284,6 +15562,7 @@ symbol.$(OBJEXT): {$(VPATH)}constant.h symbol.$(OBJEXT): {$(VPATH)}debug_counter.h symbol.$(OBJEXT): {$(VPATH)}defines.h symbol.$(OBJEXT): {$(VPATH)}encoding.h +symbol.$(OBJEXT): {$(VPATH)}gc.h symbol.$(OBJEXT): {$(VPATH)}id.c symbol.$(OBJEXT): {$(VPATH)}id.h symbol.$(OBJEXT): {$(VPATH)}id_table.c @@ -18327,8 +15606,8 @@ 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/packed_struct.h symbol.$(OBJEXT): {$(VPATH)}internal/attr/pure.h symbol.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h symbol.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -18397,6 +15676,7 @@ symbol.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h symbol.$(OBJEXT): {$(VPATH)}internal/intern/error.h symbol.$(OBJEXT): {$(VPATH)}internal/intern/eval.h symbol.$(OBJEXT): {$(VPATH)}internal/intern/file.h +symbol.$(OBJEXT): {$(VPATH)}internal/intern/gc.h symbol.$(OBJEXT): {$(VPATH)}internal/intern/hash.h symbol.$(OBJEXT): {$(VPATH)}internal/intern/io.h symbol.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -18427,28 +15707,24 @@ symbol.$(OBJEXT): {$(VPATH)}internal/memory.h symbol.$(OBJEXT): {$(VPATH)}internal/method.h symbol.$(OBJEXT): {$(VPATH)}internal/module.h symbol.$(OBJEXT): {$(VPATH)}internal/newobj.h +symbol.$(OBJEXT): {$(VPATH)}internal/rgengc.h symbol.$(OBJEXT): {$(VPATH)}internal/scan_args.h symbol.$(OBJEXT): {$(VPATH)}internal/special_consts.h symbol.$(OBJEXT): {$(VPATH)}internal/static_assert.h symbol.$(OBJEXT): {$(VPATH)}internal/stdalign.h symbol.$(OBJEXT): {$(VPATH)}internal/stdbool.h -symbol.$(OBJEXT): {$(VPATH)}internal/stdckdint.h symbol.$(OBJEXT): {$(VPATH)}internal/symbol.h symbol.$(OBJEXT): {$(VPATH)}internal/value.h symbol.$(OBJEXT): {$(VPATH)}internal/value_type.h symbol.$(OBJEXT): {$(VPATH)}internal/variable.h symbol.$(OBJEXT): {$(VPATH)}internal/warning_push.h symbol.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -symbol.$(OBJEXT): {$(VPATH)}method.h symbol.$(OBJEXT): {$(VPATH)}missing.h -symbol.$(OBJEXT): {$(VPATH)}node.h symbol.$(OBJEXT): {$(VPATH)}onigmo.h symbol.$(OBJEXT): {$(VPATH)}oniguruma.h symbol.$(OBJEXT): {$(VPATH)}probes.dmyh symbol.$(OBJEXT): {$(VPATH)}probes.h symbol.$(OBJEXT): {$(VPATH)}ruby_assert.h -symbol.$(OBJEXT): {$(VPATH)}ruby_atomic.h -symbol.$(OBJEXT): {$(VPATH)}rubyparser.h symbol.$(OBJEXT): {$(VPATH)}shape.h symbol.$(OBJEXT): {$(VPATH)}st.h symbol.$(OBJEXT): {$(VPATH)}subst.h @@ -18456,11 +15732,7 @@ symbol.$(OBJEXT): {$(VPATH)}symbol.c symbol.$(OBJEXT): {$(VPATH)}symbol.h symbol.$(OBJEXT): {$(VPATH)}symbol.rb symbol.$(OBJEXT): {$(VPATH)}symbol.rbinc -symbol.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -symbol.$(OBJEXT): {$(VPATH)}thread_native.h -symbol.$(OBJEXT): {$(VPATH)}vm_core.h symbol.$(OBJEXT): {$(VPATH)}vm_debug.h -symbol.$(OBJEXT): {$(VPATH)}vm_opts.h symbol.$(OBJEXT): {$(VPATH)}vm_sync.h thread.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h thread.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h @@ -18468,7 +15740,6 @@ thread.$(OBJEXT): $(CCAN_DIR)/list/list.h thread.$(OBJEXT): $(CCAN_DIR)/str/str.h thread.$(OBJEXT): $(hdrdir)/ruby.h thread.$(OBJEXT): $(hdrdir)/ruby/ruby.h -thread.$(OBJEXT): $(hdrdir)/ruby/version.h thread.$(OBJEXT): $(top_srcdir)/internal/array.h thread.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h thread.$(OBJEXT): $(top_srcdir)/internal/bits.h @@ -18482,7 +15753,6 @@ thread.$(OBJEXT): $(top_srcdir)/internal/imemo.h thread.$(OBJEXT): $(top_srcdir)/internal/io.h thread.$(OBJEXT): $(top_srcdir)/internal/object.h thread.$(OBJEXT): $(top_srcdir)/internal/proc.h -thread.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h thread.$(OBJEXT): $(top_srcdir)/internal/serial.h thread.$(OBJEXT): $(top_srcdir)/internal/signal.h thread.$(OBJEXT): $(top_srcdir)/internal/static_assert.h @@ -18492,27 +15762,6 @@ thread.$(OBJEXT): $(top_srcdir)/internal/time.h thread.$(OBJEXT): $(top_srcdir)/internal/variable.h thread.$(OBJEXT): $(top_srcdir)/internal/vm.h thread.$(OBJEXT): $(top_srcdir)/internal/warnings.h -thread.$(OBJEXT): $(top_srcdir)/prism/defines.h -thread.$(OBJEXT): $(top_srcdir)/prism/encoding.h -thread.$(OBJEXT): $(top_srcdir)/prism/node.h -thread.$(OBJEXT): $(top_srcdir)/prism/options.h -thread.$(OBJEXT): $(top_srcdir)/prism/pack.h -thread.$(OBJEXT): $(top_srcdir)/prism/parser.h -thread.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -thread.$(OBJEXT): $(top_srcdir)/prism/prism.h -thread.$(OBJEXT): $(top_srcdir)/prism/regexp.h -thread.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -thread.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h -thread.$(OBJEXT): {$(VPATH)}$(COROUTINE_H) thread.$(OBJEXT): {$(VPATH)}assert.h thread.$(OBJEXT): {$(VPATH)}atomic.h thread.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -18533,6 +15782,7 @@ thread.$(OBJEXT): {$(VPATH)}defines.h thread.$(OBJEXT): {$(VPATH)}encoding.h thread.$(OBJEXT): {$(VPATH)}eval_intern.h thread.$(OBJEXT): {$(VPATH)}fiber/scheduler.h +thread.$(OBJEXT): {$(VPATH)}gc.h thread.$(OBJEXT): {$(VPATH)}hrtime.h thread.$(OBJEXT): {$(VPATH)}id.h thread.$(OBJEXT): {$(VPATH)}id_table.h @@ -18576,7 +15826,6 @@ thread.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h thread.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h thread.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h thread.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -thread.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h thread.$(OBJEXT): {$(VPATH)}internal/attr/pure.h thread.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h thread.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -18645,6 +15894,7 @@ thread.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h thread.$(OBJEXT): {$(VPATH)}internal/intern/error.h thread.$(OBJEXT): {$(VPATH)}internal/intern/eval.h thread.$(OBJEXT): {$(VPATH)}internal/intern/file.h +thread.$(OBJEXT): {$(VPATH)}internal/intern/gc.h thread.$(OBJEXT): {$(VPATH)}internal/intern/hash.h thread.$(OBJEXT): {$(VPATH)}internal/intern/io.h thread.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -18675,12 +15925,12 @@ thread.$(OBJEXT): {$(VPATH)}internal/memory.h thread.$(OBJEXT): {$(VPATH)}internal/method.h thread.$(OBJEXT): {$(VPATH)}internal/module.h thread.$(OBJEXT): {$(VPATH)}internal/newobj.h +thread.$(OBJEXT): {$(VPATH)}internal/rgengc.h thread.$(OBJEXT): {$(VPATH)}internal/scan_args.h thread.$(OBJEXT): {$(VPATH)}internal/special_consts.h thread.$(OBJEXT): {$(VPATH)}internal/static_assert.h thread.$(OBJEXT): {$(VPATH)}internal/stdalign.h thread.$(OBJEXT): {$(VPATH)}internal/stdbool.h -thread.$(OBJEXT): {$(VPATH)}internal/stdckdint.h thread.$(OBJEXT): {$(VPATH)}internal/symbol.h thread.$(OBJEXT): {$(VPATH)}internal/value.h thread.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -18691,19 +15941,14 @@ thread.$(OBJEXT): {$(VPATH)}io.h thread.$(OBJEXT): {$(VPATH)}iseq.h thread.$(OBJEXT): {$(VPATH)}method.h thread.$(OBJEXT): {$(VPATH)}missing.h +thread.$(OBJEXT): {$(VPATH)}mjit.h thread.$(OBJEXT): {$(VPATH)}node.h thread.$(OBJEXT): {$(VPATH)}onigmo.h thread.$(OBJEXT): {$(VPATH)}oniguruma.h -thread.$(OBJEXT): {$(VPATH)}prism/ast.h -thread.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -thread.$(OBJEXT): {$(VPATH)}prism/version.h -thread.$(OBJEXT): {$(VPATH)}prism_compile.h thread.$(OBJEXT): {$(VPATH)}ractor.h thread.$(OBJEXT): {$(VPATH)}ractor_core.h -thread.$(OBJEXT): {$(VPATH)}rjit.h thread.$(OBJEXT): {$(VPATH)}ruby_assert.h thread.$(OBJEXT): {$(VPATH)}ruby_atomic.h -thread.$(OBJEXT): {$(VPATH)}rubyparser.h thread.$(OBJEXT): {$(VPATH)}shape.h thread.$(OBJEXT): {$(VPATH)}st.h thread.$(OBJEXT): {$(VPATH)}subst.h @@ -18712,7 +15957,6 @@ thread.$(OBJEXT): {$(VPATH)}thread.h thread.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).c thread.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h thread.$(OBJEXT): {$(VPATH)}thread_native.h -thread.$(OBJEXT): {$(VPATH)}thread_pthread_mn.c thread.$(OBJEXT): {$(VPATH)}thread_sync.c thread.$(OBJEXT): {$(VPATH)}thread_sync.rbinc thread.$(OBJEXT): {$(VPATH)}timev.h @@ -18720,10 +15964,6 @@ thread.$(OBJEXT): {$(VPATH)}vm_core.h thread.$(OBJEXT): {$(VPATH)}vm_debug.h thread.$(OBJEXT): {$(VPATH)}vm_opts.h thread.$(OBJEXT): {$(VPATH)}vm_sync.h -time.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -time.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -time.$(OBJEXT): $(CCAN_DIR)/list/list.h -time.$(OBJEXT): $(CCAN_DIR)/str/str.h time.$(OBJEXT): $(hdrdir)/ruby/ruby.h time.$(OBJEXT): $(top_srcdir)/internal/array.h time.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h @@ -18734,10 +15974,8 @@ time.$(OBJEXT): $(top_srcdir)/internal/compilers.h time.$(OBJEXT): $(top_srcdir)/internal/fixnum.h time.$(OBJEXT): $(top_srcdir)/internal/gc.h time.$(OBJEXT): $(top_srcdir)/internal/hash.h -time.$(OBJEXT): $(top_srcdir)/internal/imemo.h time.$(OBJEXT): $(top_srcdir)/internal/numeric.h time.$(OBJEXT): $(top_srcdir)/internal/rational.h -time.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h time.$(OBJEXT): $(top_srcdir)/internal/serial.h time.$(OBJEXT): $(top_srcdir)/internal/static_assert.h time.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -18746,7 +15984,6 @@ time.$(OBJEXT): $(top_srcdir)/internal/variable.h time.$(OBJEXT): $(top_srcdir)/internal/vm.h time.$(OBJEXT): $(top_srcdir)/internal/warnings.h time.$(OBJEXT): {$(VPATH)}assert.h -time.$(OBJEXT): {$(VPATH)}atomic.h time.$(OBJEXT): {$(VPATH)}backward/2/assume.h time.$(OBJEXT): {$(VPATH)}backward/2/attributes.h time.$(OBJEXT): {$(VPATH)}backward/2/bool.h @@ -18803,7 +16040,6 @@ time.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h time.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h time.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h time.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -time.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h time.$(OBJEXT): {$(VPATH)}internal/attr/pure.h time.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h time.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -18872,6 +16108,7 @@ time.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h time.$(OBJEXT): {$(VPATH)}internal/intern/error.h time.$(OBJEXT): {$(VPATH)}internal/intern/eval.h time.$(OBJEXT): {$(VPATH)}internal/intern/file.h +time.$(OBJEXT): {$(VPATH)}internal/intern/gc.h time.$(OBJEXT): {$(VPATH)}internal/intern/hash.h time.$(OBJEXT): {$(VPATH)}internal/intern/io.h time.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -18902,37 +16139,28 @@ time.$(OBJEXT): {$(VPATH)}internal/memory.h time.$(OBJEXT): {$(VPATH)}internal/method.h time.$(OBJEXT): {$(VPATH)}internal/module.h time.$(OBJEXT): {$(VPATH)}internal/newobj.h +time.$(OBJEXT): {$(VPATH)}internal/rgengc.h time.$(OBJEXT): {$(VPATH)}internal/scan_args.h time.$(OBJEXT): {$(VPATH)}internal/special_consts.h time.$(OBJEXT): {$(VPATH)}internal/static_assert.h time.$(OBJEXT): {$(VPATH)}internal/stdalign.h time.$(OBJEXT): {$(VPATH)}internal/stdbool.h -time.$(OBJEXT): {$(VPATH)}internal/stdckdint.h time.$(OBJEXT): {$(VPATH)}internal/symbol.h time.$(OBJEXT): {$(VPATH)}internal/value.h time.$(OBJEXT): {$(VPATH)}internal/value_type.h time.$(OBJEXT): {$(VPATH)}internal/variable.h time.$(OBJEXT): {$(VPATH)}internal/warning_push.h time.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -time.$(OBJEXT): {$(VPATH)}method.h time.$(OBJEXT): {$(VPATH)}missing.h -time.$(OBJEXT): {$(VPATH)}node.h time.$(OBJEXT): {$(VPATH)}onigmo.h time.$(OBJEXT): {$(VPATH)}oniguruma.h time.$(OBJEXT): {$(VPATH)}ruby_assert.h -time.$(OBJEXT): {$(VPATH)}ruby_atomic.h -time.$(OBJEXT): {$(VPATH)}rubyparser.h time.$(OBJEXT): {$(VPATH)}shape.h time.$(OBJEXT): {$(VPATH)}st.h time.$(OBJEXT): {$(VPATH)}subst.h -time.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -time.$(OBJEXT): {$(VPATH)}thread_native.h time.$(OBJEXT): {$(VPATH)}time.c time.$(OBJEXT): {$(VPATH)}timev.h time.$(OBJEXT): {$(VPATH)}timev.rbinc -time.$(OBJEXT): {$(VPATH)}util.h -time.$(OBJEXT): {$(VPATH)}vm_core.h -time.$(OBJEXT): {$(VPATH)}vm_opts.h transcode.$(OBJEXT): $(hdrdir)/ruby/ruby.h transcode.$(OBJEXT): $(top_srcdir)/internal/array.h transcode.$(OBJEXT): $(top_srcdir)/internal/class.h @@ -19002,7 +16230,6 @@ transcode.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h transcode.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h transcode.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h transcode.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -transcode.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h transcode.$(OBJEXT): {$(VPATH)}internal/attr/pure.h transcode.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h transcode.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -19071,6 +16298,7 @@ transcode.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h transcode.$(OBJEXT): {$(VPATH)}internal/intern/error.h transcode.$(OBJEXT): {$(VPATH)}internal/intern/eval.h transcode.$(OBJEXT): {$(VPATH)}internal/intern/file.h +transcode.$(OBJEXT): {$(VPATH)}internal/intern/gc.h transcode.$(OBJEXT): {$(VPATH)}internal/intern/hash.h transcode.$(OBJEXT): {$(VPATH)}internal/intern/io.h transcode.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -19101,12 +16329,12 @@ transcode.$(OBJEXT): {$(VPATH)}internal/memory.h transcode.$(OBJEXT): {$(VPATH)}internal/method.h transcode.$(OBJEXT): {$(VPATH)}internal/module.h transcode.$(OBJEXT): {$(VPATH)}internal/newobj.h +transcode.$(OBJEXT): {$(VPATH)}internal/rgengc.h transcode.$(OBJEXT): {$(VPATH)}internal/scan_args.h transcode.$(OBJEXT): {$(VPATH)}internal/special_consts.h transcode.$(OBJEXT): {$(VPATH)}internal/static_assert.h transcode.$(OBJEXT): {$(VPATH)}internal/stdalign.h transcode.$(OBJEXT): {$(VPATH)}internal/stdbool.h -transcode.$(OBJEXT): {$(VPATH)}internal/stdckdint.h transcode.$(OBJEXT): {$(VPATH)}internal/symbol.h transcode.$(OBJEXT): {$(VPATH)}internal/value.h transcode.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -19121,12 +16349,187 @@ transcode.$(OBJEXT): {$(VPATH)}st.h transcode.$(OBJEXT): {$(VPATH)}subst.h transcode.$(OBJEXT): {$(VPATH)}transcode.c transcode.$(OBJEXT): {$(VPATH)}transcode_data.h +transient_heap.$(OBJEXT): $(hdrdir)/ruby/ruby.h +transient_heap.$(OBJEXT): $(top_srcdir)/internal/array.h +transient_heap.$(OBJEXT): $(top_srcdir)/internal/compilers.h +transient_heap.$(OBJEXT): $(top_srcdir)/internal/gc.h +transient_heap.$(OBJEXT): $(top_srcdir)/internal/hash.h +transient_heap.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h +transient_heap.$(OBJEXT): $(top_srcdir)/internal/static_assert.h +transient_heap.$(OBJEXT): $(top_srcdir)/internal/struct.h +transient_heap.$(OBJEXT): $(top_srcdir)/internal/variable.h +transient_heap.$(OBJEXT): $(top_srcdir)/internal/warnings.h +transient_heap.$(OBJEXT): {$(VPATH)}assert.h +transient_heap.$(OBJEXT): {$(VPATH)}backward/2/assume.h +transient_heap.$(OBJEXT): {$(VPATH)}backward/2/attributes.h +transient_heap.$(OBJEXT): {$(VPATH)}backward/2/bool.h +transient_heap.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h +transient_heap.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h +transient_heap.$(OBJEXT): {$(VPATH)}backward/2/limits.h +transient_heap.$(OBJEXT): {$(VPATH)}backward/2/long_long.h +transient_heap.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h +transient_heap.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h +transient_heap.$(OBJEXT): {$(VPATH)}config.h +transient_heap.$(OBJEXT): {$(VPATH)}constant.h +transient_heap.$(OBJEXT): {$(VPATH)}debug.h +transient_heap.$(OBJEXT): {$(VPATH)}debug_counter.h +transient_heap.$(OBJEXT): {$(VPATH)}defines.h +transient_heap.$(OBJEXT): {$(VPATH)}gc.h +transient_heap.$(OBJEXT): {$(VPATH)}id_table.h +transient_heap.$(OBJEXT): {$(VPATH)}intern.h +transient_heap.$(OBJEXT): {$(VPATH)}internal.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/abi.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/anyargs.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/assume.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/cold.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/const.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/error.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/format.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/pure.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/warning.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/cast.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/compiler_since.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/config.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/constant_p.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/core.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rarray.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rclass.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rdata.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rfile.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rhash.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/core/robject.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rstring.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/ctype.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/dllexport.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/dosish.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/error.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/eval.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/event.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/fl_type.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/gc.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/glob.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/globals.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/has/attribute.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/has/builtin.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/has/extension.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/has/feature.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/has/warning.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/array.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/class.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/compar.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/complex.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/cont.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/dir.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/enum.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/error.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/eval.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/file.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/gc.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/hash.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/io.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/load.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/object.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/parse.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/proc.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/process.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/random.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/range.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/rational.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/re.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/select.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/signal.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/string.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/struct.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/thread.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/time.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/variable.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/intern/vm.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/interpreter.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/iterator.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/memory.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/method.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/module.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/newobj.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/rgengc.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/scan_args.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/special_consts.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/static_assert.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/stdalign.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/stdbool.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/symbol.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/value.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/value_type.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/variable.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/warning_push.h +transient_heap.$(OBJEXT): {$(VPATH)}internal/xmalloc.h +transient_heap.$(OBJEXT): {$(VPATH)}missing.h +transient_heap.$(OBJEXT): {$(VPATH)}ruby_assert.h +transient_heap.$(OBJEXT): {$(VPATH)}shape.h +transient_heap.$(OBJEXT): {$(VPATH)}st.h +transient_heap.$(OBJEXT): {$(VPATH)}subst.h +transient_heap.$(OBJEXT): {$(VPATH)}transient_heap.c +transient_heap.$(OBJEXT): {$(VPATH)}transient_heap.h +transient_heap.$(OBJEXT): {$(VPATH)}vm_debug.h +transient_heap.$(OBJEXT): {$(VPATH)}vm_sync.h util.$(OBJEXT): $(hdrdir)/ruby/ruby.h -util.$(OBJEXT): $(top_srcdir)/internal/array.h util.$(OBJEXT): $(top_srcdir)/internal/compilers.h -util.$(OBJEXT): $(top_srcdir)/internal/imemo.h util.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h -util.$(OBJEXT): $(top_srcdir)/internal/static_assert.h util.$(OBJEXT): $(top_srcdir)/internal/util.h util.$(OBJEXT): $(top_srcdir)/internal/warnings.h util.$(OBJEXT): {$(VPATH)}assert.h @@ -19183,7 +16586,6 @@ util.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h util.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h util.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h util.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -util.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h util.$(OBJEXT): {$(VPATH)}internal/attr/pure.h util.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h util.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -19243,6 +16645,7 @@ util.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h util.$(OBJEXT): {$(VPATH)}internal/intern/error.h util.$(OBJEXT): {$(VPATH)}internal/intern/eval.h util.$(OBJEXT): {$(VPATH)}internal/intern/file.h +util.$(OBJEXT): {$(VPATH)}internal/intern/gc.h util.$(OBJEXT): {$(VPATH)}internal/intern/hash.h util.$(OBJEXT): {$(VPATH)}internal/intern/io.h util.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -19273,12 +16676,12 @@ util.$(OBJEXT): {$(VPATH)}internal/memory.h util.$(OBJEXT): {$(VPATH)}internal/method.h util.$(OBJEXT): {$(VPATH)}internal/module.h util.$(OBJEXT): {$(VPATH)}internal/newobj.h +util.$(OBJEXT): {$(VPATH)}internal/rgengc.h util.$(OBJEXT): {$(VPATH)}internal/scan_args.h util.$(OBJEXT): {$(VPATH)}internal/special_consts.h util.$(OBJEXT): {$(VPATH)}internal/static_assert.h util.$(OBJEXT): {$(VPATH)}internal/stdalign.h util.$(OBJEXT): {$(VPATH)}internal/stdbool.h -util.$(OBJEXT): {$(VPATH)}internal/stdckdint.h util.$(OBJEXT): {$(VPATH)}internal/symbol.h util.$(OBJEXT): {$(VPATH)}internal/value.h util.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -19296,7 +16699,6 @@ variable.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h variable.$(OBJEXT): $(CCAN_DIR)/list/list.h variable.$(OBJEXT): $(CCAN_DIR)/str/str.h variable.$(OBJEXT): $(hdrdir)/ruby/ruby.h -variable.$(OBJEXT): $(hdrdir)/ruby/version.h variable.$(OBJEXT): $(top_srcdir)/internal/array.h variable.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h variable.$(OBJEXT): $(top_srcdir)/internal/class.h @@ -19308,7 +16710,6 @@ variable.$(OBJEXT): $(top_srcdir)/internal/hash.h variable.$(OBJEXT): $(top_srcdir)/internal/imemo.h variable.$(OBJEXT): $(top_srcdir)/internal/object.h variable.$(OBJEXT): $(top_srcdir)/internal/re.h -variable.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h variable.$(OBJEXT): $(top_srcdir)/internal/serial.h variable.$(OBJEXT): $(top_srcdir)/internal/static_assert.h variable.$(OBJEXT): $(top_srcdir)/internal/string.h @@ -19375,7 +16776,6 @@ variable.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h variable.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h variable.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h variable.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -variable.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h variable.$(OBJEXT): {$(VPATH)}internal/attr/pure.h variable.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h variable.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -19444,6 +16844,7 @@ variable.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h variable.$(OBJEXT): {$(VPATH)}internal/intern/error.h variable.$(OBJEXT): {$(VPATH)}internal/intern/eval.h variable.$(OBJEXT): {$(VPATH)}internal/intern/file.h +variable.$(OBJEXT): {$(VPATH)}internal/intern/gc.h variable.$(OBJEXT): {$(VPATH)}internal/intern/hash.h variable.$(OBJEXT): {$(VPATH)}internal/intern/io.h variable.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -19474,12 +16875,12 @@ variable.$(OBJEXT): {$(VPATH)}internal/memory.h variable.$(OBJEXT): {$(VPATH)}internal/method.h variable.$(OBJEXT): {$(VPATH)}internal/module.h variable.$(OBJEXT): {$(VPATH)}internal/newobj.h +variable.$(OBJEXT): {$(VPATH)}internal/rgengc.h variable.$(OBJEXT): {$(VPATH)}internal/scan_args.h variable.$(OBJEXT): {$(VPATH)}internal/special_consts.h variable.$(OBJEXT): {$(VPATH)}internal/static_assert.h variable.$(OBJEXT): {$(VPATH)}internal/stdalign.h variable.$(OBJEXT): {$(VPATH)}internal/stdbool.h -variable.$(OBJEXT): {$(VPATH)}internal/stdckdint.h variable.$(OBJEXT): {$(VPATH)}internal/symbol.h variable.$(OBJEXT): {$(VPATH)}internal/value.h variable.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -19495,13 +16896,12 @@ variable.$(OBJEXT): {$(VPATH)}ractor.h variable.$(OBJEXT): {$(VPATH)}ractor_core.h variable.$(OBJEXT): {$(VPATH)}ruby_assert.h variable.$(OBJEXT): {$(VPATH)}ruby_atomic.h -variable.$(OBJEXT): {$(VPATH)}rubyparser.h variable.$(OBJEXT): {$(VPATH)}shape.h variable.$(OBJEXT): {$(VPATH)}st.h variable.$(OBJEXT): {$(VPATH)}subst.h -variable.$(OBJEXT): {$(VPATH)}symbol.h variable.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h variable.$(OBJEXT): {$(VPATH)}thread_native.h +variable.$(OBJEXT): {$(VPATH)}transient_heap.h variable.$(OBJEXT): {$(VPATH)}util.h variable.$(OBJEXT): {$(VPATH)}variable.c variable.$(OBJEXT): {$(VPATH)}variable.h @@ -19522,8 +16922,6 @@ version.$(OBJEXT): $(top_srcdir)/internal/cmdlineopt.h version.$(OBJEXT): $(top_srcdir)/internal/compilers.h version.$(OBJEXT): $(top_srcdir)/internal/gc.h version.$(OBJEXT): $(top_srcdir)/internal/imemo.h -version.$(OBJEXT): $(top_srcdir)/internal/parse.h -version.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h version.$(OBJEXT): $(top_srcdir)/internal/serial.h version.$(OBJEXT): $(top_srcdir)/internal/static_assert.h version.$(OBJEXT): $(top_srcdir)/internal/variable.h @@ -19545,7 +16943,6 @@ version.$(OBJEXT): {$(VPATH)}config.h version.$(OBJEXT): {$(VPATH)}constant.h version.$(OBJEXT): {$(VPATH)}debug_counter.h version.$(OBJEXT): {$(VPATH)}defines.h -version.$(OBJEXT): {$(VPATH)}encoding.h version.$(OBJEXT): {$(VPATH)}id.h version.$(OBJEXT): {$(VPATH)}id_table.h version.$(OBJEXT): {$(VPATH)}intern.h @@ -19588,7 +16985,6 @@ version.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h version.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h version.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h version.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -version.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h version.$(OBJEXT): {$(VPATH)}internal/attr/pure.h version.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h version.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -19621,15 +17017,6 @@ version.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h version.$(OBJEXT): {$(VPATH)}internal/ctype.h version.$(OBJEXT): {$(VPATH)}internal/dllexport.h version.$(OBJEXT): {$(VPATH)}internal/dosish.h -version.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -version.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -version.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -version.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -version.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -version.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -version.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -version.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -version.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h version.$(OBJEXT): {$(VPATH)}internal/error.h version.$(OBJEXT): {$(VPATH)}internal/eval.h version.$(OBJEXT): {$(VPATH)}internal/event.h @@ -19657,6 +17044,7 @@ version.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h version.$(OBJEXT): {$(VPATH)}internal/intern/error.h version.$(OBJEXT): {$(VPATH)}internal/intern/eval.h version.$(OBJEXT): {$(VPATH)}internal/intern/file.h +version.$(OBJEXT): {$(VPATH)}internal/intern/gc.h version.$(OBJEXT): {$(VPATH)}internal/intern/hash.h version.$(OBJEXT): {$(VPATH)}internal/intern/io.h version.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -19687,12 +17075,12 @@ version.$(OBJEXT): {$(VPATH)}internal/memory.h version.$(OBJEXT): {$(VPATH)}internal/method.h version.$(OBJEXT): {$(VPATH)}internal/module.h version.$(OBJEXT): {$(VPATH)}internal/newobj.h +version.$(OBJEXT): {$(VPATH)}internal/rgengc.h version.$(OBJEXT): {$(VPATH)}internal/scan_args.h version.$(OBJEXT): {$(VPATH)}internal/special_consts.h version.$(OBJEXT): {$(VPATH)}internal/static_assert.h version.$(OBJEXT): {$(VPATH)}internal/stdalign.h version.$(OBJEXT): {$(VPATH)}internal/stdbool.h -version.$(OBJEXT): {$(VPATH)}internal/stdckdint.h version.$(OBJEXT): {$(VPATH)}internal/symbol.h version.$(OBJEXT): {$(VPATH)}internal/value.h version.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -19701,14 +17089,11 @@ version.$(OBJEXT): {$(VPATH)}internal/warning_push.h version.$(OBJEXT): {$(VPATH)}internal/xmalloc.h version.$(OBJEXT): {$(VPATH)}method.h version.$(OBJEXT): {$(VPATH)}missing.h +version.$(OBJEXT): {$(VPATH)}mjit.h version.$(OBJEXT): {$(VPATH)}node.h -version.$(OBJEXT): {$(VPATH)}onigmo.h -version.$(OBJEXT): {$(VPATH)}oniguruma.h version.$(OBJEXT): {$(VPATH)}revision.h -version.$(OBJEXT): {$(VPATH)}rjit.h version.$(OBJEXT): {$(VPATH)}ruby_assert.h version.$(OBJEXT): {$(VPATH)}ruby_atomic.h -version.$(OBJEXT): {$(VPATH)}rubyparser.h version.$(OBJEXT): {$(VPATH)}shape.h version.$(OBJEXT): {$(VPATH)}st.h version.$(OBJEXT): {$(VPATH)}subst.h @@ -19724,7 +17109,6 @@ vm.$(OBJEXT): $(CCAN_DIR)/list/list.h vm.$(OBJEXT): $(CCAN_DIR)/str/str.h vm.$(OBJEXT): $(hdrdir)/ruby.h vm.$(OBJEXT): $(hdrdir)/ruby/ruby.h -vm.$(OBJEXT): $(hdrdir)/ruby/version.h vm.$(OBJEXT): $(top_srcdir)/internal/array.h vm.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h vm.$(OBJEXT): $(top_srcdir)/internal/bignum.h @@ -19733,9 +17117,7 @@ vm.$(OBJEXT): $(top_srcdir)/internal/class.h vm.$(OBJEXT): $(top_srcdir)/internal/compar.h vm.$(OBJEXT): $(top_srcdir)/internal/compile.h vm.$(OBJEXT): $(top_srcdir)/internal/compilers.h -vm.$(OBJEXT): $(top_srcdir)/internal/complex.h vm.$(OBJEXT): $(top_srcdir)/internal/cont.h -vm.$(OBJEXT): $(top_srcdir)/internal/encoding.h vm.$(OBJEXT): $(top_srcdir)/internal/error.h vm.$(OBJEXT): $(top_srcdir)/internal/eval.h vm.$(OBJEXT): $(top_srcdir)/internal/fixnum.h @@ -19743,15 +17125,12 @@ vm.$(OBJEXT): $(top_srcdir)/internal/gc.h vm.$(OBJEXT): $(top_srcdir)/internal/hash.h vm.$(OBJEXT): $(top_srcdir)/internal/imemo.h vm.$(OBJEXT): $(top_srcdir)/internal/inits.h -vm.$(OBJEXT): $(top_srcdir)/internal/missing.h vm.$(OBJEXT): $(top_srcdir)/internal/numeric.h vm.$(OBJEXT): $(top_srcdir)/internal/object.h vm.$(OBJEXT): $(top_srcdir)/internal/parse.h vm.$(OBJEXT): $(top_srcdir)/internal/proc.h vm.$(OBJEXT): $(top_srcdir)/internal/random.h -vm.$(OBJEXT): $(top_srcdir)/internal/rational.h vm.$(OBJEXT): $(top_srcdir)/internal/re.h -vm.$(OBJEXT): $(top_srcdir)/internal/ruby_parser.h vm.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h vm.$(OBJEXT): $(top_srcdir)/internal/serial.h vm.$(OBJEXT): $(top_srcdir)/internal/static_assert.h @@ -19759,30 +17138,9 @@ vm.$(OBJEXT): $(top_srcdir)/internal/string.h vm.$(OBJEXT): $(top_srcdir)/internal/struct.h vm.$(OBJEXT): $(top_srcdir)/internal/symbol.h vm.$(OBJEXT): $(top_srcdir)/internal/thread.h -vm.$(OBJEXT): $(top_srcdir)/internal/transcode.h vm.$(OBJEXT): $(top_srcdir)/internal/variable.h vm.$(OBJEXT): $(top_srcdir)/internal/vm.h vm.$(OBJEXT): $(top_srcdir)/internal/warnings.h -vm.$(OBJEXT): $(top_srcdir)/prism/defines.h -vm.$(OBJEXT): $(top_srcdir)/prism/encoding.h -vm.$(OBJEXT): $(top_srcdir)/prism/node.h -vm.$(OBJEXT): $(top_srcdir)/prism/options.h -vm.$(OBJEXT): $(top_srcdir)/prism/pack.h -vm.$(OBJEXT): $(top_srcdir)/prism/parser.h -vm.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -vm.$(OBJEXT): $(top_srcdir)/prism/prism.h -vm.$(OBJEXT): $(top_srcdir)/prism/regexp.h -vm.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -vm.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h vm.$(OBJEXT): {$(VPATH)}assert.h vm.$(OBJEXT): {$(VPATH)}atomic.h vm.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -19802,6 +17160,7 @@ vm.$(OBJEXT): {$(VPATH)}defines.h vm.$(OBJEXT): {$(VPATH)}defs/opt_operand.def vm.$(OBJEXT): {$(VPATH)}encoding.h vm.$(OBJEXT): {$(VPATH)}eval_intern.h +vm.$(OBJEXT): {$(VPATH)}gc.h vm.$(OBJEXT): {$(VPATH)}id.h vm.$(OBJEXT): {$(VPATH)}id_table.h vm.$(OBJEXT): {$(VPATH)}insns.def @@ -19847,7 +17206,6 @@ vm.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h vm.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h vm.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h vm.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -vm.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h vm.$(OBJEXT): {$(VPATH)}internal/attr/pure.h vm.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h vm.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -19916,6 +17274,7 @@ vm.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h vm.$(OBJEXT): {$(VPATH)}internal/intern/error.h vm.$(OBJEXT): {$(VPATH)}internal/intern/eval.h vm.$(OBJEXT): {$(VPATH)}internal/intern/file.h +vm.$(OBJEXT): {$(VPATH)}internal/intern/gc.h vm.$(OBJEXT): {$(VPATH)}internal/intern/hash.h vm.$(OBJEXT): {$(VPATH)}internal/intern/io.h vm.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -19946,12 +17305,12 @@ vm.$(OBJEXT): {$(VPATH)}internal/memory.h vm.$(OBJEXT): {$(VPATH)}internal/method.h vm.$(OBJEXT): {$(VPATH)}internal/module.h vm.$(OBJEXT): {$(VPATH)}internal/newobj.h +vm.$(OBJEXT): {$(VPATH)}internal/rgengc.h vm.$(OBJEXT): {$(VPATH)}internal/scan_args.h vm.$(OBJEXT): {$(VPATH)}internal/special_consts.h vm.$(OBJEXT): {$(VPATH)}internal/static_assert.h vm.$(OBJEXT): {$(VPATH)}internal/stdalign.h vm.$(OBJEXT): {$(VPATH)}internal/stdbool.h -vm.$(OBJEXT): {$(VPATH)}internal/stdckdint.h vm.$(OBJEXT): {$(VPATH)}internal/symbol.h vm.$(OBJEXT): {$(VPATH)}internal/value.h vm.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -19961,22 +17320,17 @@ vm.$(OBJEXT): {$(VPATH)}internal/xmalloc.h vm.$(OBJEXT): {$(VPATH)}iseq.h vm.$(OBJEXT): {$(VPATH)}method.h vm.$(OBJEXT): {$(VPATH)}missing.h +vm.$(OBJEXT): {$(VPATH)}mjit.h vm.$(OBJEXT): {$(VPATH)}node.h vm.$(OBJEXT): {$(VPATH)}onigmo.h vm.$(OBJEXT): {$(VPATH)}oniguruma.h -vm.$(OBJEXT): {$(VPATH)}prism/ast.h -vm.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -vm.$(OBJEXT): {$(VPATH)}prism/version.h -vm.$(OBJEXT): {$(VPATH)}prism_compile.h vm.$(OBJEXT): {$(VPATH)}probes.dmyh vm.$(OBJEXT): {$(VPATH)}probes.h vm.$(OBJEXT): {$(VPATH)}probes_helper.h vm.$(OBJEXT): {$(VPATH)}ractor.h vm.$(OBJEXT): {$(VPATH)}ractor_core.h -vm.$(OBJEXT): {$(VPATH)}rjit.h vm.$(OBJEXT): {$(VPATH)}ruby_assert.h vm.$(OBJEXT): {$(VPATH)}ruby_atomic.h -vm.$(OBJEXT): {$(VPATH)}rubyparser.h vm.$(OBJEXT): {$(VPATH)}shape.h vm.$(OBJEXT): {$(VPATH)}st.h vm.$(OBJEXT): {$(VPATH)}subst.h @@ -20006,41 +17360,18 @@ vm_backtrace.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h vm_backtrace.$(OBJEXT): $(CCAN_DIR)/list/list.h vm_backtrace.$(OBJEXT): $(CCAN_DIR)/str/str.h vm_backtrace.$(OBJEXT): $(hdrdir)/ruby/ruby.h -vm_backtrace.$(OBJEXT): $(hdrdir)/ruby/version.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/array.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/class.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/compilers.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/error.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/gc.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/imemo.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/serial.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/static_assert.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/string.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/variable.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/vm.h vm_backtrace.$(OBJEXT): $(top_srcdir)/internal/warnings.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/defines.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/encoding.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/node.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/options.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/pack.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/parser.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/prism.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/regexp.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -vm_backtrace.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h vm_backtrace.$(OBJEXT): {$(VPATH)}assert.h vm_backtrace.$(OBJEXT): {$(VPATH)}atomic.h vm_backtrace.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -20055,7 +17386,6 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h vm_backtrace.$(OBJEXT): {$(VPATH)}config.h vm_backtrace.$(OBJEXT): {$(VPATH)}constant.h vm_backtrace.$(OBJEXT): {$(VPATH)}debug.h -vm_backtrace.$(OBJEXT): {$(VPATH)}debug_counter.h vm_backtrace.$(OBJEXT): {$(VPATH)}defines.h vm_backtrace.$(OBJEXT): {$(VPATH)}encoding.h vm_backtrace.$(OBJEXT): {$(VPATH)}eval_intern.h @@ -20101,7 +17431,6 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/pure.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -20170,6 +17499,7 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/error.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/eval.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/file.h +vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/gc.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/hash.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/io.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -20200,12 +17530,12 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}internal/memory.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/method.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/module.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/newobj.h +vm_backtrace.$(OBJEXT): {$(VPATH)}internal/rgengc.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/scan_args.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/special_consts.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/static_assert.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/stdalign.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/stdbool.h -vm_backtrace.$(OBJEXT): {$(VPATH)}internal/stdckdint.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/symbol.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/value.h vm_backtrace.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -20218,13 +17548,8 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}missing.h vm_backtrace.$(OBJEXT): {$(VPATH)}node.h vm_backtrace.$(OBJEXT): {$(VPATH)}onigmo.h vm_backtrace.$(OBJEXT): {$(VPATH)}oniguruma.h -vm_backtrace.$(OBJEXT): {$(VPATH)}prism/ast.h -vm_backtrace.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -vm_backtrace.$(OBJEXT): {$(VPATH)}prism/version.h -vm_backtrace.$(OBJEXT): {$(VPATH)}prism_compile.h vm_backtrace.$(OBJEXT): {$(VPATH)}ruby_assert.h vm_backtrace.$(OBJEXT): {$(VPATH)}ruby_atomic.h -vm_backtrace.$(OBJEXT): {$(VPATH)}rubyparser.h vm_backtrace.$(OBJEXT): {$(VPATH)}shape.h vm_backtrace.$(OBJEXT): {$(VPATH)}st.h vm_backtrace.$(OBJEXT): {$(VPATH)}subst.h @@ -20232,9 +17557,7 @@ vm_backtrace.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h vm_backtrace.$(OBJEXT): {$(VPATH)}thread_native.h vm_backtrace.$(OBJEXT): {$(VPATH)}vm_backtrace.c vm_backtrace.$(OBJEXT): {$(VPATH)}vm_core.h -vm_backtrace.$(OBJEXT): {$(VPATH)}vm_debug.h vm_backtrace.$(OBJEXT): {$(VPATH)}vm_opts.h -vm_backtrace.$(OBJEXT): {$(VPATH)}vm_sync.h vm_dump.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h vm_dump.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h vm_dump.$(OBJEXT): $(CCAN_DIR)/list/list.h @@ -20245,32 +17568,11 @@ vm_dump.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h vm_dump.$(OBJEXT): $(top_srcdir)/internal/compilers.h vm_dump.$(OBJEXT): $(top_srcdir)/internal/gc.h vm_dump.$(OBJEXT): $(top_srcdir)/internal/imemo.h -vm_dump.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h vm_dump.$(OBJEXT): $(top_srcdir)/internal/serial.h vm_dump.$(OBJEXT): $(top_srcdir)/internal/static_assert.h vm_dump.$(OBJEXT): $(top_srcdir)/internal/variable.h vm_dump.$(OBJEXT): $(top_srcdir)/internal/vm.h vm_dump.$(OBJEXT): $(top_srcdir)/internal/warnings.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/defines.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/encoding.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/node.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/options.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/pack.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/parser.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/prism.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/regexp.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -vm_dump.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h vm_dump.$(OBJEXT): {$(VPATH)}addr2line.h vm_dump.$(OBJEXT): {$(VPATH)}assert.h vm_dump.$(OBJEXT): {$(VPATH)}atomic.h @@ -20286,7 +17588,7 @@ vm_dump.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h vm_dump.$(OBJEXT): {$(VPATH)}config.h vm_dump.$(OBJEXT): {$(VPATH)}constant.h vm_dump.$(OBJEXT): {$(VPATH)}defines.h -vm_dump.$(OBJEXT): {$(VPATH)}encoding.h +vm_dump.$(OBJEXT): {$(VPATH)}gc.h vm_dump.$(OBJEXT): {$(VPATH)}id.h vm_dump.$(OBJEXT): {$(VPATH)}id_table.h vm_dump.$(OBJEXT): {$(VPATH)}intern.h @@ -20329,7 +17631,6 @@ vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/pure.h vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h vm_dump.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -20362,15 +17663,6 @@ vm_dump.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h vm_dump.$(OBJEXT): {$(VPATH)}internal/ctype.h vm_dump.$(OBJEXT): {$(VPATH)}internal/dllexport.h vm_dump.$(OBJEXT): {$(VPATH)}internal/dosish.h -vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -vm_dump.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h vm_dump.$(OBJEXT): {$(VPATH)}internal/error.h vm_dump.$(OBJEXT): {$(VPATH)}internal/eval.h vm_dump.$(OBJEXT): {$(VPATH)}internal/event.h @@ -20398,6 +17690,7 @@ vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/error.h vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/eval.h vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/file.h +vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/gc.h vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/hash.h vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/io.h vm_dump.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -20428,12 +17721,12 @@ vm_dump.$(OBJEXT): {$(VPATH)}internal/memory.h vm_dump.$(OBJEXT): {$(VPATH)}internal/method.h vm_dump.$(OBJEXT): {$(VPATH)}internal/module.h vm_dump.$(OBJEXT): {$(VPATH)}internal/newobj.h +vm_dump.$(OBJEXT): {$(VPATH)}internal/rgengc.h vm_dump.$(OBJEXT): {$(VPATH)}internal/scan_args.h vm_dump.$(OBJEXT): {$(VPATH)}internal/special_consts.h vm_dump.$(OBJEXT): {$(VPATH)}internal/static_assert.h vm_dump.$(OBJEXT): {$(VPATH)}internal/stdalign.h vm_dump.$(OBJEXT): {$(VPATH)}internal/stdbool.h -vm_dump.$(OBJEXT): {$(VPATH)}internal/stdckdint.h vm_dump.$(OBJEXT): {$(VPATH)}internal/symbol.h vm_dump.$(OBJEXT): {$(VPATH)}internal/value.h vm_dump.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -20444,18 +17737,11 @@ vm_dump.$(OBJEXT): {$(VPATH)}iseq.h vm_dump.$(OBJEXT): {$(VPATH)}method.h vm_dump.$(OBJEXT): {$(VPATH)}missing.h vm_dump.$(OBJEXT): {$(VPATH)}node.h -vm_dump.$(OBJEXT): {$(VPATH)}onigmo.h -vm_dump.$(OBJEXT): {$(VPATH)}oniguruma.h -vm_dump.$(OBJEXT): {$(VPATH)}prism/ast.h -vm_dump.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -vm_dump.$(OBJEXT): {$(VPATH)}prism/version.h -vm_dump.$(OBJEXT): {$(VPATH)}prism_compile.h vm_dump.$(OBJEXT): {$(VPATH)}procstat_vm.c vm_dump.$(OBJEXT): {$(VPATH)}ractor.h vm_dump.$(OBJEXT): {$(VPATH)}ractor_core.h vm_dump.$(OBJEXT): {$(VPATH)}ruby_assert.h vm_dump.$(OBJEXT): {$(VPATH)}ruby_atomic.h -vm_dump.$(OBJEXT): {$(VPATH)}rubyparser.h vm_dump.$(OBJEXT): {$(VPATH)}shape.h vm_dump.$(OBJEXT): {$(VPATH)}st.h vm_dump.$(OBJEXT): {$(VPATH)}subst.h @@ -20475,10 +17761,8 @@ vm_sync.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h vm_sync.$(OBJEXT): $(top_srcdir)/internal/compilers.h vm_sync.$(OBJEXT): $(top_srcdir)/internal/gc.h vm_sync.$(OBJEXT): $(top_srcdir)/internal/imemo.h -vm_sync.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h vm_sync.$(OBJEXT): $(top_srcdir)/internal/serial.h vm_sync.$(OBJEXT): $(top_srcdir)/internal/static_assert.h -vm_sync.$(OBJEXT): $(top_srcdir)/internal/thread.h vm_sync.$(OBJEXT): $(top_srcdir)/internal/variable.h vm_sync.$(OBJEXT): $(top_srcdir)/internal/vm.h vm_sync.$(OBJEXT): $(top_srcdir)/internal/warnings.h @@ -20497,7 +17781,7 @@ vm_sync.$(OBJEXT): {$(VPATH)}config.h vm_sync.$(OBJEXT): {$(VPATH)}constant.h vm_sync.$(OBJEXT): {$(VPATH)}debug_counter.h vm_sync.$(OBJEXT): {$(VPATH)}defines.h -vm_sync.$(OBJEXT): {$(VPATH)}encoding.h +vm_sync.$(OBJEXT): {$(VPATH)}gc.h vm_sync.$(OBJEXT): {$(VPATH)}id.h vm_sync.$(OBJEXT): {$(VPATH)}id_table.h vm_sync.$(OBJEXT): {$(VPATH)}intern.h @@ -20540,7 +17824,6 @@ vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/pure.h vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h vm_sync.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -20573,15 +17856,6 @@ vm_sync.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h vm_sync.$(OBJEXT): {$(VPATH)}internal/ctype.h vm_sync.$(OBJEXT): {$(VPATH)}internal/dllexport.h vm_sync.$(OBJEXT): {$(VPATH)}internal/dosish.h -vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -vm_sync.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h vm_sync.$(OBJEXT): {$(VPATH)}internal/error.h vm_sync.$(OBJEXT): {$(VPATH)}internal/eval.h vm_sync.$(OBJEXT): {$(VPATH)}internal/event.h @@ -20609,6 +17883,7 @@ vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/error.h vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/eval.h vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/file.h +vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/gc.h vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/hash.h vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/io.h vm_sync.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -20639,12 +17914,12 @@ vm_sync.$(OBJEXT): {$(VPATH)}internal/memory.h vm_sync.$(OBJEXT): {$(VPATH)}internal/method.h vm_sync.$(OBJEXT): {$(VPATH)}internal/module.h vm_sync.$(OBJEXT): {$(VPATH)}internal/newobj.h +vm_sync.$(OBJEXT): {$(VPATH)}internal/rgengc.h vm_sync.$(OBJEXT): {$(VPATH)}internal/scan_args.h vm_sync.$(OBJEXT): {$(VPATH)}internal/special_consts.h vm_sync.$(OBJEXT): {$(VPATH)}internal/static_assert.h vm_sync.$(OBJEXT): {$(VPATH)}internal/stdalign.h vm_sync.$(OBJEXT): {$(VPATH)}internal/stdbool.h -vm_sync.$(OBJEXT): {$(VPATH)}internal/stdckdint.h vm_sync.$(OBJEXT): {$(VPATH)}internal/symbol.h vm_sync.$(OBJEXT): {$(VPATH)}internal/value.h vm_sync.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -20654,13 +17929,10 @@ vm_sync.$(OBJEXT): {$(VPATH)}internal/xmalloc.h vm_sync.$(OBJEXT): {$(VPATH)}method.h vm_sync.$(OBJEXT): {$(VPATH)}missing.h vm_sync.$(OBJEXT): {$(VPATH)}node.h -vm_sync.$(OBJEXT): {$(VPATH)}onigmo.h -vm_sync.$(OBJEXT): {$(VPATH)}oniguruma.h vm_sync.$(OBJEXT): {$(VPATH)}ractor.h vm_sync.$(OBJEXT): {$(VPATH)}ractor_core.h vm_sync.$(OBJEXT): {$(VPATH)}ruby_assert.h vm_sync.$(OBJEXT): {$(VPATH)}ruby_atomic.h -vm_sync.$(OBJEXT): {$(VPATH)}rubyparser.h vm_sync.$(OBJEXT): {$(VPATH)}shape.h vm_sync.$(OBJEXT): {$(VPATH)}st.h vm_sync.$(OBJEXT): {$(VPATH)}subst.h @@ -20679,40 +17951,16 @@ vm_trace.$(OBJEXT): $(hdrdir)/ruby.h vm_trace.$(OBJEXT): $(hdrdir)/ruby/ruby.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/array.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h -vm_trace.$(OBJEXT): $(top_srcdir)/internal/bits.h -vm_trace.$(OBJEXT): $(top_srcdir)/internal/class.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/compilers.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/gc.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/hash.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/imemo.h -vm_trace.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/serial.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/static_assert.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/symbol.h -vm_trace.$(OBJEXT): $(top_srcdir)/internal/thread.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/variable.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/vm.h vm_trace.$(OBJEXT): $(top_srcdir)/internal/warnings.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/defines.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/encoding.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/node.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/options.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/pack.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/parser.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/prism.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/regexp.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -vm_trace.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h vm_trace.$(OBJEXT): {$(VPATH)}assert.h vm_trace.$(OBJEXT): {$(VPATH)}atomic.h vm_trace.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -20774,7 +18022,6 @@ vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/pure.h vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h vm_trace.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -20843,6 +18090,7 @@ vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/error.h vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/eval.h vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/file.h +vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/gc.h vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/hash.h vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/io.h vm_trace.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -20873,12 +18121,12 @@ vm_trace.$(OBJEXT): {$(VPATH)}internal/memory.h vm_trace.$(OBJEXT): {$(VPATH)}internal/method.h vm_trace.$(OBJEXT): {$(VPATH)}internal/module.h vm_trace.$(OBJEXT): {$(VPATH)}internal/newobj.h +vm_trace.$(OBJEXT): {$(VPATH)}internal/rgengc.h vm_trace.$(OBJEXT): {$(VPATH)}internal/scan_args.h vm_trace.$(OBJEXT): {$(VPATH)}internal/special_consts.h vm_trace.$(OBJEXT): {$(VPATH)}internal/static_assert.h vm_trace.$(OBJEXT): {$(VPATH)}internal/stdalign.h vm_trace.$(OBJEXT): {$(VPATH)}internal/stdbool.h -vm_trace.$(OBJEXT): {$(VPATH)}internal/stdckdint.h vm_trace.$(OBJEXT): {$(VPATH)}internal/symbol.h vm_trace.$(OBJEXT): {$(VPATH)}internal/value.h vm_trace.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -20888,18 +18136,13 @@ vm_trace.$(OBJEXT): {$(VPATH)}internal/xmalloc.h vm_trace.$(OBJEXT): {$(VPATH)}iseq.h vm_trace.$(OBJEXT): {$(VPATH)}method.h vm_trace.$(OBJEXT): {$(VPATH)}missing.h +vm_trace.$(OBJEXT): {$(VPATH)}mjit.h vm_trace.$(OBJEXT): {$(VPATH)}node.h vm_trace.$(OBJEXT): {$(VPATH)}onigmo.h vm_trace.$(OBJEXT): {$(VPATH)}oniguruma.h -vm_trace.$(OBJEXT): {$(VPATH)}prism/ast.h -vm_trace.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -vm_trace.$(OBJEXT): {$(VPATH)}prism/version.h -vm_trace.$(OBJEXT): {$(VPATH)}prism_compile.h vm_trace.$(OBJEXT): {$(VPATH)}ractor.h -vm_trace.$(OBJEXT): {$(VPATH)}rjit.h vm_trace.$(OBJEXT): {$(VPATH)}ruby_assert.h vm_trace.$(OBJEXT): {$(VPATH)}ruby_atomic.h -vm_trace.$(OBJEXT): {$(VPATH)}rubyparser.h vm_trace.$(OBJEXT): {$(VPATH)}shape.h vm_trace.$(OBJEXT): {$(VPATH)}st.h vm_trace.$(OBJEXT): {$(VPATH)}subst.h @@ -20907,209 +18150,9 @@ vm_trace.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h vm_trace.$(OBJEXT): {$(VPATH)}thread_native.h vm_trace.$(OBJEXT): {$(VPATH)}trace_point.rbinc vm_trace.$(OBJEXT): {$(VPATH)}vm_core.h -vm_trace.$(OBJEXT): {$(VPATH)}vm_debug.h vm_trace.$(OBJEXT): {$(VPATH)}vm_opts.h -vm_trace.$(OBJEXT): {$(VPATH)}vm_sync.h vm_trace.$(OBJEXT): {$(VPATH)}vm_trace.c vm_trace.$(OBJEXT): {$(VPATH)}yjit.h -weakmap.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h -weakmap.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h -weakmap.$(OBJEXT): $(CCAN_DIR)/list/list.h -weakmap.$(OBJEXT): $(CCAN_DIR)/str/str.h -weakmap.$(OBJEXT): $(hdrdir)/ruby/ruby.h -weakmap.$(OBJEXT): $(top_srcdir)/internal/array.h -weakmap.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h -weakmap.$(OBJEXT): $(top_srcdir)/internal/compilers.h -weakmap.$(OBJEXT): $(top_srcdir)/internal/gc.h -weakmap.$(OBJEXT): $(top_srcdir)/internal/hash.h -weakmap.$(OBJEXT): $(top_srcdir)/internal/imemo.h -weakmap.$(OBJEXT): $(top_srcdir)/internal/proc.h -weakmap.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h -weakmap.$(OBJEXT): $(top_srcdir)/internal/serial.h -weakmap.$(OBJEXT): $(top_srcdir)/internal/static_assert.h -weakmap.$(OBJEXT): $(top_srcdir)/internal/vm.h -weakmap.$(OBJEXT): $(top_srcdir)/internal/warnings.h -weakmap.$(OBJEXT): {$(VPATH)}assert.h -weakmap.$(OBJEXT): {$(VPATH)}atomic.h -weakmap.$(OBJEXT): {$(VPATH)}backward/2/assume.h -weakmap.$(OBJEXT): {$(VPATH)}backward/2/attributes.h -weakmap.$(OBJEXT): {$(VPATH)}backward/2/bool.h -weakmap.$(OBJEXT): {$(VPATH)}backward/2/gcc_version_since.h -weakmap.$(OBJEXT): {$(VPATH)}backward/2/inttypes.h -weakmap.$(OBJEXT): {$(VPATH)}backward/2/limits.h -weakmap.$(OBJEXT): {$(VPATH)}backward/2/long_long.h -weakmap.$(OBJEXT): {$(VPATH)}backward/2/stdalign.h -weakmap.$(OBJEXT): {$(VPATH)}backward/2/stdarg.h -weakmap.$(OBJEXT): {$(VPATH)}config.h -weakmap.$(OBJEXT): {$(VPATH)}defines.h -weakmap.$(OBJEXT): {$(VPATH)}encoding.h -weakmap.$(OBJEXT): {$(VPATH)}id.h -weakmap.$(OBJEXT): {$(VPATH)}intern.h -weakmap.$(OBJEXT): {$(VPATH)}internal.h -weakmap.$(OBJEXT): {$(VPATH)}internal/abi.h -weakmap.$(OBJEXT): {$(VPATH)}internal/anyargs.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/char.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/double.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/fixnum.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/gid_t.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/int.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/intptr_t.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/long.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/long_long.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/mode_t.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/off_t.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/pid_t.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/short.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/size_t.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/st_data_t.h -weakmap.$(OBJEXT): {$(VPATH)}internal/arithmetic/uid_t.h -weakmap.$(OBJEXT): {$(VPATH)}internal/assume.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/alloc_size.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/artificial.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/cold.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/const.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/constexpr.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/deprecated.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/diagnose_if.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/enum_extensibility.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/error.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/flag_enum.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/forceinline.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/format.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/maybe_unused.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/noalias.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/nodiscard.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/pure.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/warning.h -weakmap.$(OBJEXT): {$(VPATH)}internal/attr/weakref.h -weakmap.$(OBJEXT): {$(VPATH)}internal/cast.h -weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_is.h -weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_is/apple.h -weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_is/clang.h -weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_is/gcc.h -weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_is/intel.h -weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_is/msvc.h -weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_is/sunpro.h -weakmap.$(OBJEXT): {$(VPATH)}internal/compiler_since.h -weakmap.$(OBJEXT): {$(VPATH)}internal/config.h -weakmap.$(OBJEXT): {$(VPATH)}internal/constant_p.h -weakmap.$(OBJEXT): {$(VPATH)}internal/core.h -weakmap.$(OBJEXT): {$(VPATH)}internal/core/rarray.h -weakmap.$(OBJEXT): {$(VPATH)}internal/core/rbasic.h -weakmap.$(OBJEXT): {$(VPATH)}internal/core/rbignum.h -weakmap.$(OBJEXT): {$(VPATH)}internal/core/rclass.h -weakmap.$(OBJEXT): {$(VPATH)}internal/core/rdata.h -weakmap.$(OBJEXT): {$(VPATH)}internal/core/rfile.h -weakmap.$(OBJEXT): {$(VPATH)}internal/core/rhash.h -weakmap.$(OBJEXT): {$(VPATH)}internal/core/robject.h -weakmap.$(OBJEXT): {$(VPATH)}internal/core/rregexp.h -weakmap.$(OBJEXT): {$(VPATH)}internal/core/rstring.h -weakmap.$(OBJEXT): {$(VPATH)}internal/core/rstruct.h -weakmap.$(OBJEXT): {$(VPATH)}internal/core/rtypeddata.h -weakmap.$(OBJEXT): {$(VPATH)}internal/ctype.h -weakmap.$(OBJEXT): {$(VPATH)}internal/dllexport.h -weakmap.$(OBJEXT): {$(VPATH)}internal/dosish.h -weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/coderange.h -weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/ctype.h -weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/encoding.h -weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/pathname.h -weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/re.h -weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/sprintf.h -weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/string.h -weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/symbol.h -weakmap.$(OBJEXT): {$(VPATH)}internal/encoding/transcode.h -weakmap.$(OBJEXT): {$(VPATH)}internal/error.h -weakmap.$(OBJEXT): {$(VPATH)}internal/eval.h -weakmap.$(OBJEXT): {$(VPATH)}internal/event.h -weakmap.$(OBJEXT): {$(VPATH)}internal/fl_type.h -weakmap.$(OBJEXT): {$(VPATH)}internal/gc.h -weakmap.$(OBJEXT): {$(VPATH)}internal/glob.h -weakmap.$(OBJEXT): {$(VPATH)}internal/globals.h -weakmap.$(OBJEXT): {$(VPATH)}internal/has/attribute.h -weakmap.$(OBJEXT): {$(VPATH)}internal/has/builtin.h -weakmap.$(OBJEXT): {$(VPATH)}internal/has/c_attribute.h -weakmap.$(OBJEXT): {$(VPATH)}internal/has/cpp_attribute.h -weakmap.$(OBJEXT): {$(VPATH)}internal/has/declspec_attribute.h -weakmap.$(OBJEXT): {$(VPATH)}internal/has/extension.h -weakmap.$(OBJEXT): {$(VPATH)}internal/has/feature.h -weakmap.$(OBJEXT): {$(VPATH)}internal/has/warning.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/array.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/bignum.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/class.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/compar.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/complex.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/cont.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/dir.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/enum.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/error.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/eval.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/file.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/hash.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/io.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/load.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/marshal.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/numeric.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/object.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/parse.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/proc.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/process.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/random.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/range.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/rational.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/re.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/ruby.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/select.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/select/largesize.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/signal.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/sprintf.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/string.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/struct.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/thread.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/time.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/variable.h -weakmap.$(OBJEXT): {$(VPATH)}internal/intern/vm.h -weakmap.$(OBJEXT): {$(VPATH)}internal/interpreter.h -weakmap.$(OBJEXT): {$(VPATH)}internal/iterator.h -weakmap.$(OBJEXT): {$(VPATH)}internal/memory.h -weakmap.$(OBJEXT): {$(VPATH)}internal/method.h -weakmap.$(OBJEXT): {$(VPATH)}internal/module.h -weakmap.$(OBJEXT): {$(VPATH)}internal/newobj.h -weakmap.$(OBJEXT): {$(VPATH)}internal/scan_args.h -weakmap.$(OBJEXT): {$(VPATH)}internal/special_consts.h -weakmap.$(OBJEXT): {$(VPATH)}internal/static_assert.h -weakmap.$(OBJEXT): {$(VPATH)}internal/stdalign.h -weakmap.$(OBJEXT): {$(VPATH)}internal/stdbool.h -weakmap.$(OBJEXT): {$(VPATH)}internal/stdckdint.h -weakmap.$(OBJEXT): {$(VPATH)}internal/symbol.h -weakmap.$(OBJEXT): {$(VPATH)}internal/value.h -weakmap.$(OBJEXT): {$(VPATH)}internal/value_type.h -weakmap.$(OBJEXT): {$(VPATH)}internal/variable.h -weakmap.$(OBJEXT): {$(VPATH)}internal/warning_push.h -weakmap.$(OBJEXT): {$(VPATH)}internal/xmalloc.h -weakmap.$(OBJEXT): {$(VPATH)}method.h -weakmap.$(OBJEXT): {$(VPATH)}missing.h -weakmap.$(OBJEXT): {$(VPATH)}node.h -weakmap.$(OBJEXT): {$(VPATH)}onigmo.h -weakmap.$(OBJEXT): {$(VPATH)}oniguruma.h -weakmap.$(OBJEXT): {$(VPATH)}ruby_assert.h -weakmap.$(OBJEXT): {$(VPATH)}ruby_atomic.h -weakmap.$(OBJEXT): {$(VPATH)}rubyparser.h -weakmap.$(OBJEXT): {$(VPATH)}st.h -weakmap.$(OBJEXT): {$(VPATH)}subst.h -weakmap.$(OBJEXT): {$(VPATH)}thread_$(THREAD_MODEL).h -weakmap.$(OBJEXT): {$(VPATH)}thread_native.h -weakmap.$(OBJEXT): {$(VPATH)}vm_core.h -weakmap.$(OBJEXT): {$(VPATH)}vm_opts.h -weakmap.$(OBJEXT): {$(VPATH)}weakmap.c yjit.$(OBJEXT): $(CCAN_DIR)/check_type/check_type.h yjit.$(OBJEXT): $(CCAN_DIR)/container_of/container_of.h yjit.$(OBJEXT): $(CCAN_DIR)/list/list.h @@ -21117,8 +18160,6 @@ yjit.$(OBJEXT): $(CCAN_DIR)/str/str.h yjit.$(OBJEXT): $(hdrdir)/ruby/ruby.h yjit.$(OBJEXT): $(top_srcdir)/internal/array.h yjit.$(OBJEXT): $(top_srcdir)/internal/basic_operators.h -yjit.$(OBJEXT): $(top_srcdir)/internal/bignum.h -yjit.$(OBJEXT): $(top_srcdir)/internal/bits.h yjit.$(OBJEXT): $(top_srcdir)/internal/class.h yjit.$(OBJEXT): $(top_srcdir)/internal/compile.h yjit.$(OBJEXT): $(top_srcdir)/internal/compilers.h @@ -21127,7 +18168,6 @@ yjit.$(OBJEXT): $(top_srcdir)/internal/fixnum.h yjit.$(OBJEXT): $(top_srcdir)/internal/gc.h yjit.$(OBJEXT): $(top_srcdir)/internal/hash.h yjit.$(OBJEXT): $(top_srcdir)/internal/imemo.h -yjit.$(OBJEXT): $(top_srcdir)/internal/numeric.h yjit.$(OBJEXT): $(top_srcdir)/internal/sanitizers.h yjit.$(OBJEXT): $(top_srcdir)/internal/serial.h yjit.$(OBJEXT): $(top_srcdir)/internal/static_assert.h @@ -21135,26 +18175,6 @@ yjit.$(OBJEXT): $(top_srcdir)/internal/string.h yjit.$(OBJEXT): $(top_srcdir)/internal/variable.h yjit.$(OBJEXT): $(top_srcdir)/internal/vm.h yjit.$(OBJEXT): $(top_srcdir)/internal/warnings.h -yjit.$(OBJEXT): $(top_srcdir)/prism/defines.h -yjit.$(OBJEXT): $(top_srcdir)/prism/encoding.h -yjit.$(OBJEXT): $(top_srcdir)/prism/node.h -yjit.$(OBJEXT): $(top_srcdir)/prism/options.h -yjit.$(OBJEXT): $(top_srcdir)/prism/pack.h -yjit.$(OBJEXT): $(top_srcdir)/prism/parser.h -yjit.$(OBJEXT): $(top_srcdir)/prism/prettyprint.h -yjit.$(OBJEXT): $(top_srcdir)/prism/prism.h -yjit.$(OBJEXT): $(top_srcdir)/prism/regexp.h -yjit.$(OBJEXT): $(top_srcdir)/prism/static_literals.h -yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_buffer.h -yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_char.h -yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_constant_pool.h -yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_integer.h -yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_list.h -yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_memchr.h -yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_newline_list.h -yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_string.h -yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_strncasecmp.h -yjit.$(OBJEXT): $(top_srcdir)/prism/util/pm_strpbrk.h yjit.$(OBJEXT): {$(VPATH)}assert.h yjit.$(OBJEXT): {$(VPATH)}atomic.h yjit.$(OBJEXT): {$(VPATH)}backward/2/assume.h @@ -21173,6 +18193,7 @@ yjit.$(OBJEXT): {$(VPATH)}debug.h yjit.$(OBJEXT): {$(VPATH)}debug_counter.h yjit.$(OBJEXT): {$(VPATH)}defines.h yjit.$(OBJEXT): {$(VPATH)}encoding.h +yjit.$(OBJEXT): {$(VPATH)}gc.h yjit.$(OBJEXT): {$(VPATH)}id.h yjit.$(OBJEXT): {$(VPATH)}id_table.h yjit.$(OBJEXT): {$(VPATH)}insns.def @@ -21218,7 +18239,6 @@ yjit.$(OBJEXT): {$(VPATH)}internal/attr/noexcept.h yjit.$(OBJEXT): {$(VPATH)}internal/attr/noinline.h yjit.$(OBJEXT): {$(VPATH)}internal/attr/nonnull.h yjit.$(OBJEXT): {$(VPATH)}internal/attr/noreturn.h -yjit.$(OBJEXT): {$(VPATH)}internal/attr/packed_struct.h yjit.$(OBJEXT): {$(VPATH)}internal/attr/pure.h yjit.$(OBJEXT): {$(VPATH)}internal/attr/restrict.h yjit.$(OBJEXT): {$(VPATH)}internal/attr/returns_nonnull.h @@ -21287,6 +18307,7 @@ yjit.$(OBJEXT): {$(VPATH)}internal/intern/enumerator.h yjit.$(OBJEXT): {$(VPATH)}internal/intern/error.h yjit.$(OBJEXT): {$(VPATH)}internal/intern/eval.h yjit.$(OBJEXT): {$(VPATH)}internal/intern/file.h +yjit.$(OBJEXT): {$(VPATH)}internal/intern/gc.h yjit.$(OBJEXT): {$(VPATH)}internal/intern/hash.h yjit.$(OBJEXT): {$(VPATH)}internal/intern/io.h yjit.$(OBJEXT): {$(VPATH)}internal/intern/load.h @@ -21317,13 +18338,12 @@ yjit.$(OBJEXT): {$(VPATH)}internal/memory.h yjit.$(OBJEXT): {$(VPATH)}internal/method.h yjit.$(OBJEXT): {$(VPATH)}internal/module.h yjit.$(OBJEXT): {$(VPATH)}internal/newobj.h -yjit.$(OBJEXT): {$(VPATH)}internal/numeric.h +yjit.$(OBJEXT): {$(VPATH)}internal/rgengc.h yjit.$(OBJEXT): {$(VPATH)}internal/scan_args.h yjit.$(OBJEXT): {$(VPATH)}internal/special_consts.h yjit.$(OBJEXT): {$(VPATH)}internal/static_assert.h yjit.$(OBJEXT): {$(VPATH)}internal/stdalign.h yjit.$(OBJEXT): {$(VPATH)}internal/stdbool.h -yjit.$(OBJEXT): {$(VPATH)}internal/stdckdint.h yjit.$(OBJEXT): {$(VPATH)}internal/symbol.h yjit.$(OBJEXT): {$(VPATH)}internal/value.h yjit.$(OBJEXT): {$(VPATH)}internal/value_type.h @@ -21336,16 +18356,11 @@ yjit.$(OBJEXT): {$(VPATH)}missing.h yjit.$(OBJEXT): {$(VPATH)}node.h yjit.$(OBJEXT): {$(VPATH)}onigmo.h yjit.$(OBJEXT): {$(VPATH)}oniguruma.h -yjit.$(OBJEXT): {$(VPATH)}prism/ast.h -yjit.$(OBJEXT): {$(VPATH)}prism/diagnostic.h -yjit.$(OBJEXT): {$(VPATH)}prism/version.h -yjit.$(OBJEXT): {$(VPATH)}prism_compile.h yjit.$(OBJEXT): {$(VPATH)}probes.dmyh yjit.$(OBJEXT): {$(VPATH)}probes.h yjit.$(OBJEXT): {$(VPATH)}probes_helper.h yjit.$(OBJEXT): {$(VPATH)}ruby_assert.h yjit.$(OBJEXT): {$(VPATH)}ruby_atomic.h -yjit.$(OBJEXT): {$(VPATH)}rubyparser.h yjit.$(OBJEXT): {$(VPATH)}shape.h yjit.$(OBJEXT): {$(VPATH)}st.h yjit.$(OBJEXT): {$(VPATH)}subst.h @@ -187,12 +187,6 @@ cmp_between(VALUE x, VALUE min, VALUE max) * 'd'.clamp('a', 'f') #=> 'd' * 'z'.clamp('a', 'f') #=> 'f' * - * If _min_ is +nil+, it is considered smaller than _obj_, - * and if _max_ is +nil+, it is considered greater than _obj_. - * - * -20.clamp(0, nil) #=> 0 - * 523.clamp(nil, 100) #=> 100 - * * In <code>(range)</code> form, returns _range.begin_ if _obj_ * <code><=></code> _range.begin_ is less than zero, _range.end_ * if _obj_ <code><=></code> _range.end_ is greater than zero, and @@ -235,7 +229,7 @@ cmp_clamp(int argc, VALUE *argv, VALUE x) } } if (!NIL_P(min) && !NIL_P(max) && cmpint(min, max) > 0) { - rb_raise(rb_eArgError, "min argument must be less than or equal to max argument"); + rb_raise(rb_eArgError, "min argument must be smaller than max argument"); } if (!NIL_P(min)) { @@ -263,28 +257,25 @@ cmp_clamp(int argc, VALUE *argv, VALUE x) * <code>==</code>, <code>>=</code>, and <code>></code>) and the * method <code>between?</code>. * - * class StringSorter + * class SizeMatters * include Comparable - * * attr :str * def <=>(other) * str.size <=> other.str.size * end - * * def initialize(str) * @str = str * end - * * def inspect * @str * end * end * - * s1 = StringSorter.new("Z") - * s2 = StringSorter.new("YY") - * s3 = StringSorter.new("XXX") - * s4 = StringSorter.new("WWWW") - * s5 = StringSorter.new("VVVVV") + * s1 = SizeMatters.new("Z") + * s2 = SizeMatters.new("YY") + * s3 = SizeMatters.new("XXX") + * s4 = SizeMatters.new("WWWW") + * s5 = SizeMatters.new("VVVVV") * * s1 < s2 #=> true * s4.between?(s1, s3) #=> false @@ -293,13 +284,13 @@ cmp_clamp(int argc, VALUE *argv, VALUE x) * * == What's Here * - * \Module \Comparable provides these methods, all of which use method <tt>#<=></tt>: + * \Module \Comparable provides these methods, all of which use method <tt><=></tt>: * * - #<: Returns whether +self+ is less than the given object. * - #<=: Returns whether +self+ is less than or equal to the given object. * - #==: Returns whether +self+ is equal to the given object. - * - #>: Returns whether +self+ is greater than the given object. - * - #>=: Returns whether +self+ is greater than or equal to the given object. + * - #>: Returns whether +self+ is greater than or equal to the given object. + * - #>=: Returns whether +self+ is greater than the given object. * - #between?: Returns +true+ if +self+ is between two given objects. * - #clamp: For given objects +min+ and +max+, or range <tt>(min..max)</tt>, returns: * @@ -17,6 +17,7 @@ #endif #include "encindex.h" +#include "gc.h" #include "id_table.h" #include "internal.h" #include "internal/array.h" @@ -24,30 +25,28 @@ #include "internal/complex.h" #include "internal/encoding.h" #include "internal/error.h" -#include "internal/gc.h" #include "internal/hash.h" -#include "internal/io.h" #include "internal/numeric.h" #include "internal/object.h" #include "internal/rational.h" #include "internal/re.h" -#include "internal/ruby_parser.h" #include "internal/symbol.h" #include "internal/thread.h" #include "internal/variable.h" #include "iseq.h" -#include "ruby/ractor.h" #include "ruby/re.h" #include "ruby/util.h" #include "vm_core.h" #include "vm_callinfo.h" #include "vm_debug.h" -#include "yjit.h" #include "builtin.h" #include "insns.inc" #include "insns_info.inc" +#undef RUBY_UNTYPED_DATA_WARNING +#define RUBY_UNTYPED_DATA_WARNING 0 + #define FIXNUM_INC(n, i) ((n)+(INT2FIX(i)&~FIXNUM_FLAG)) #define FIXNUM_OR(n, i) ((n)|INT2FIX(i)) @@ -119,7 +118,7 @@ struct ensure_range { }; struct iseq_compile_data_ensure_node_stack { - const void *ensure_node; + const NODE *ensure_node; struct iseq_compile_data_ensure_node_stack *prev; struct ensure_range *erange; }; @@ -220,34 +219,30 @@ const ID rb_iseq_shared_exc_local_tbl[] = {idERROR_INFO}; /* add an instruction */ #define ADD_INSN(seq, line_node, insn) \ - ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_body(iseq, nd_line(line_node), nd_node_id(line_node), BIN(insn), 0)) - -/* add an instruction with the given line number and node id */ -#define ADD_SYNTHETIC_INSN(seq, line_no, node_id, insn) \ - ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_body(iseq, (line_no), (node_id), BIN(insn), 0)) + ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_body(iseq, (line_node), BIN(insn), 0)) /* insert an instruction before next */ -#define INSERT_BEFORE_INSN(next, line_no, node_id, insn) \ - ELEM_INSERT_PREV(&(next)->link, (LINK_ELEMENT *) new_insn_body(iseq, line_no, node_id, BIN(insn), 0)) +#define INSERT_BEFORE_INSN(next, line_node, insn) \ + ELEM_INSERT_PREV(&(next)->link, (LINK_ELEMENT *) new_insn_body(iseq, (line_node), BIN(insn), 0)) /* insert an instruction after prev */ -#define INSERT_AFTER_INSN(prev, line_no, node_id, insn) \ - ELEM_INSERT_NEXT(&(prev)->link, (LINK_ELEMENT *) new_insn_body(iseq, line_no, node_id, BIN(insn), 0)) +#define INSERT_AFTER_INSN(prev, line_node, insn) \ + ELEM_INSERT_NEXT(&(prev)->link, (LINK_ELEMENT *) new_insn_body(iseq, (line_node), BIN(insn), 0)) /* add an instruction with some operands (1, 2, 3, 5) */ #define ADD_INSN1(seq, line_node, insn, op1) \ ADD_ELEM((seq), (LINK_ELEMENT *) \ - new_insn_body(iseq, nd_line(line_node), nd_node_id(line_node), BIN(insn), 1, (VALUE)(op1))) + new_insn_body(iseq, (line_node), BIN(insn), 1, (VALUE)(op1))) /* insert an instruction with some operands (1, 2, 3, 5) before next */ -#define INSERT_BEFORE_INSN1(next, line_no, node_id, insn, op1) \ +#define INSERT_BEFORE_INSN1(next, line_node, insn, op1) \ ELEM_INSERT_PREV(&(next)->link, (LINK_ELEMENT *) \ - new_insn_body(iseq, line_no, node_id, BIN(insn), 1, (VALUE)(op1))) + new_insn_body(iseq, (line_node), BIN(insn), 1, (VALUE)(op1))) /* insert an instruction with some operands (1, 2, 3, 5) after prev */ -#define INSERT_AFTER_INSN1(prev, line_no, node_id, insn, op1) \ +#define INSERT_AFTER_INSN1(prev, line_node, insn, op1) \ ELEM_INSERT_NEXT(&(prev)->link, (LINK_ELEMENT *) \ - new_insn_body(iseq, line_no, node_id, BIN(insn), 1, (VALUE)(op1))) + new_insn_body(iseq, (line_node), BIN(insn), 1, (VALUE)(op1))) #define LABEL_REF(label) ((label)->refcnt++) @@ -256,11 +251,11 @@ const ID rb_iseq_shared_exc_local_tbl[] = {idERROR_INFO}; #define ADD_INSN2(seq, line_node, insn, op1, op2) \ ADD_ELEM((seq), (LINK_ELEMENT *) \ - new_insn_body(iseq, nd_line(line_node), nd_node_id(line_node), BIN(insn), 2, (VALUE)(op1), (VALUE)(op2))) + new_insn_body(iseq, (line_node), BIN(insn), 2, (VALUE)(op1), (VALUE)(op2))) #define ADD_INSN3(seq, line_node, insn, op1, op2, op3) \ ADD_ELEM((seq), (LINK_ELEMENT *) \ - new_insn_body(iseq, nd_line(line_node), nd_node_id(line_node), BIN(insn), 3, (VALUE)(op1), (VALUE)(op2), (VALUE)(op3))) + new_insn_body(iseq, (line_node), BIN(insn), 3, (VALUE)(op1), (VALUE)(op2), (VALUE)(op3))) /* Specific Insn factory */ #define ADD_SEND(seq, line_node, id, argc) \ @@ -282,7 +277,7 @@ const ID rb_iseq_shared_exc_local_tbl[] = {idERROR_INFO}; ADD_SEND_R((seq), (line_node), (id), (argc), (block), (VALUE)INT2FIX(VM_CALL_FCALL), NULL) #define ADD_SEND_R(seq, line_node, id, argc, block, flag, keywords) \ - ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_send(iseq, nd_line(line_node), nd_node_id(line_node), (id), (VALUE)(argc), (block), (VALUE)(flag), (keywords))) + ADD_ELEM((seq), (LINK_ELEMENT *) new_insn_send(iseq, (line_node), (id), (VALUE)(argc), (block), (VALUE)(flag), (keywords))) #define ADD_TRACE(seq, event) \ ADD_ELEM((seq), (LINK_ELEMENT *)new_trace_body(iseq, (event), 0)) @@ -337,10 +332,10 @@ static void iseq_add_setlocal(rb_iseq_t *iseq, LINK_ANCHOR *const seq, const NOD (debug_compile("== " desc "\n", \ iseq_compile_each(iseq, (anchor), (node), (popped)))) -#define COMPILE_RECV(anchor, desc, node, recv) \ +#define COMPILE_RECV(anchor, desc, node) \ (private_recv_p(node) ? \ (ADD_INSN(anchor, node, putself), VM_CALL_FCALL) : \ - COMPILE(anchor, desc, recv) ? 0 : -1) + COMPILE(anchor, desc, node->nd_recv) ? 0 : -1) #define OPERAND_AT(insn, idx) \ (((INSN*)(insn))->operands[(idx)]) @@ -475,7 +470,7 @@ static void dump_disasm_list(const LINK_ELEMENT *elem); static int insn_data_length(INSN *iobj); static int calc_sp_depth(int depth, INSN *iobj); -static INSN *new_insn_body(rb_iseq_t *iseq, int line_no, int node_id, enum ruby_vminsn_type insn_id, int argc, ...); +static INSN *new_insn_body(rb_iseq_t *iseq, const NODE *const line_node, enum ruby_vminsn_type insn_id, int argc, ...); static LABEL *new_label_body(rb_iseq_t *iseq, long line); static ADJUST *new_adjust_body(rb_iseq_t *iseq, LABEL *label, int line); static TRACE *new_trace_body(rb_iseq_t *iseq, rb_event_flag_t event, long data); @@ -487,15 +482,16 @@ static int iseq_setup_insn(rb_iseq_t *iseq, LINK_ANCHOR *const anchor); static int iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor); static int iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *const anchor); -static int iseq_set_local_table(rb_iseq_t *iseq, const rb_ast_id_table_t *tbl, const NODE *const node_args); +static int iseq_set_local_table(rb_iseq_t *iseq, const rb_ast_id_table_t *tbl); static int iseq_set_exception_local_table(rb_iseq_t *iseq); static int iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const anchor, const NODE *const node); +static int iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *const anchor); static int iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor); static int iseq_set_exception_table(rb_iseq_t *iseq); static int iseq_set_optargs_table(rb_iseq_t *iseq); -static int compile_defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, VALUE needstr, bool ignore); +static int compile_defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, VALUE needstr); static int compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int method_call_keywords, int popped); /* @@ -609,28 +605,13 @@ branch_coverage_valid_p(rb_iseq_t *iseq, int first_line) return 1; } -#define PTR2NUM(x) (rb_int2inum((intptr_t)(void *)(x))) - static VALUE -setup_branch(const rb_code_location_t *loc, const char *type, VALUE structure, VALUE key) +decl_branch_base(rb_iseq_t *iseq, const NODE *node, const char *type) { - const int first_lineno = loc->beg_pos.lineno, first_column = loc->beg_pos.column; - const int last_lineno = loc->end_pos.lineno, last_column = loc->end_pos.column; - VALUE branch = rb_ary_hidden_new(6); - - rb_hash_aset(structure, key, branch); - rb_ary_push(branch, ID2SYM(rb_intern(type))); - rb_ary_push(branch, INT2FIX(first_lineno)); - rb_ary_push(branch, INT2FIX(first_column)); - rb_ary_push(branch, INT2FIX(last_lineno)); - rb_ary_push(branch, INT2FIX(last_column)); - return branch; -} + const int first_lineno = nd_first_lineno(node), first_column = nd_first_column(node); + const int last_lineno = nd_last_lineno(node), last_column = nd_last_column(node); -static VALUE -decl_branch_base(rb_iseq_t *iseq, VALUE key, const rb_code_location_t *loc, const char *type) -{ - if (!branch_coverage_valid_p(iseq, loc->beg_pos.lineno)) return Qundef; + if (!branch_coverage_valid_p(iseq, first_lineno)) return Qundef; /* * if !structure[node] @@ -641,11 +622,18 @@ decl_branch_base(rb_iseq_t *iseq, VALUE key, const rb_code_location_t *loc, cons */ VALUE structure = RARRAY_AREF(ISEQ_BRANCH_COVERAGE(iseq), 0); + VALUE key = (VALUE)node | 1; // FIXNUM for hash key VALUE branch_base = rb_hash_aref(structure, key); VALUE branches; if (NIL_P(branch_base)) { - branch_base = setup_branch(loc, type, structure, key); + branch_base = rb_ary_hidden_new(6); + rb_hash_aset(structure, key, branch_base); + rb_ary_push(branch_base, ID2SYM(rb_intern(type))); + rb_ary_push(branch_base, INT2FIX(first_lineno)); + rb_ary_push(branch_base, INT2FIX(first_column)); + rb_ary_push(branch_base, INT2FIX(last_lineno)); + rb_ary_push(branch_base, INT2FIX(last_column)); branches = rb_hash_new(); rb_obj_hide(branches); rb_ary_push(branch_base, branches); @@ -667,9 +655,12 @@ generate_dummy_line_node(int lineno, int node_id) } static void -add_trace_branch_coverage(rb_iseq_t *iseq, LINK_ANCHOR *const seq, const rb_code_location_t *loc, int node_id, int branch_id, const char *type, VALUE branches) +add_trace_branch_coverage(rb_iseq_t *iseq, LINK_ANCHOR *const seq, const NODE *node, int branch_id, const char *type, VALUE branches) { - if (!branch_coverage_valid_p(iseq, loc->beg_pos.lineno)) return; + const int first_lineno = nd_first_lineno(node), first_column = nd_first_column(node); + const int last_lineno = nd_last_lineno(node), last_column = nd_last_column(node); + + if (!branch_coverage_valid_p(iseq, first_lineno)) return; /* * if !branches[branch_id] @@ -684,7 +675,13 @@ add_trace_branch_coverage(rb_iseq_t *iseq, LINK_ANCHOR *const seq, const rb_code long counter_idx; if (NIL_P(branch)) { - branch = setup_branch(loc, type, branches, key); + branch = rb_ary_hidden_new(6); + rb_hash_aset(branches, key, branch); + rb_ary_push(branch, ID2SYM(rb_intern(type))); + rb_ary_push(branch, INT2FIX(first_lineno)); + rb_ary_push(branch, INT2FIX(first_column)); + rb_ary_push(branch, INT2FIX(last_lineno)); + rb_ary_push(branch, INT2FIX(last_column)); VALUE counters = RARRAY_AREF(ISEQ_BRANCH_COVERAGE(iseq), 1); counter_idx = RARRAY_LEN(counters); rb_ary_push(branch, LONG2FIX(counter_idx)); @@ -695,7 +692,9 @@ add_trace_branch_coverage(rb_iseq_t *iseq, LINK_ANCHOR *const seq, const rb_code } ADD_TRACE_WITH_DATA(seq, RUBY_EVENT_COVERAGE_BRANCH, counter_idx); - ADD_SYNTHETIC_INSN(seq, loc->end_pos.lineno, node_id, nop); + + NODE dummy_line_node = generate_dummy_line_node(last_lineno, nd_node_id(node)); + ADD_INSN(seq, &dummy_line_node, nop); } #define ISEQ_LAST_LINE(iseq) (ISEQ_COMPILE_DATA(iseq)->last_line) @@ -722,129 +721,6 @@ validate_labels(rb_iseq_t *iseq, st_table *labels_table) st_free_table(labels_table); } -static NODE * -get_nd_recv(const NODE *node) -{ - switch (nd_type(node)) { - case NODE_CALL: - return RNODE_CALL(node)->nd_recv; - case NODE_OPCALL: - return RNODE_OPCALL(node)->nd_recv; - case NODE_FCALL: - return 0; - case NODE_QCALL: - return RNODE_QCALL(node)->nd_recv; - case NODE_VCALL: - return 0; - case NODE_ATTRASGN: - return RNODE_ATTRASGN(node)->nd_recv; - case NODE_OP_ASGN1: - return RNODE_OP_ASGN1(node)->nd_recv; - case NODE_OP_ASGN2: - return RNODE_OP_ASGN2(node)->nd_recv; - default: - rb_bug("unexpected node: %s", ruby_node_name(nd_type(node))); - } -} - -static ID -get_node_call_nd_mid(const NODE *node) -{ - switch (nd_type(node)) { - case NODE_CALL: - return RNODE_CALL(node)->nd_mid; - case NODE_OPCALL: - return RNODE_OPCALL(node)->nd_mid; - case NODE_FCALL: - return RNODE_FCALL(node)->nd_mid; - case NODE_QCALL: - return RNODE_QCALL(node)->nd_mid; - case NODE_VCALL: - return RNODE_VCALL(node)->nd_mid; - case NODE_ATTRASGN: - return RNODE_ATTRASGN(node)->nd_mid; - default: - rb_bug("unexpected node: %s", ruby_node_name(nd_type(node))); - } -} - -static NODE * -get_nd_args(const NODE *node) -{ - switch (nd_type(node)) { - case NODE_CALL: - return RNODE_CALL(node)->nd_args; - case NODE_OPCALL: - return RNODE_OPCALL(node)->nd_args; - case NODE_FCALL: - return RNODE_FCALL(node)->nd_args; - case NODE_QCALL: - return RNODE_QCALL(node)->nd_args; - case NODE_VCALL: - return 0; - case NODE_ATTRASGN: - return RNODE_ATTRASGN(node)->nd_args; - default: - rb_bug("unexpected node: %s", ruby_node_name(nd_type(node))); - } -} - -static ID -get_node_colon_nd_mid(const NODE *node) -{ - switch (nd_type(node)) { - case NODE_COLON2: - return RNODE_COLON2(node)->nd_mid; - case NODE_COLON3: - return RNODE_COLON3(node)->nd_mid; - default: - rb_bug("unexpected node: %s", ruby_node_name(nd_type(node))); - } -} - -static ID -get_nd_vid(const NODE *node) -{ - switch (nd_type(node)) { - case NODE_LASGN: - return RNODE_LASGN(node)->nd_vid; - case NODE_DASGN: - return RNODE_DASGN(node)->nd_vid; - case NODE_IASGN: - return RNODE_IASGN(node)->nd_vid; - case NODE_CVASGN: - return RNODE_CVASGN(node)->nd_vid; - default: - rb_bug("unexpected node: %s", ruby_node_name(nd_type(node))); - } -} - -static NODE * -get_nd_value(const NODE *node) -{ - switch (nd_type(node)) { - case NODE_LASGN: - return RNODE_LASGN(node)->nd_value; - case NODE_DASGN: - return RNODE_DASGN(node)->nd_value; - default: - rb_bug("unexpected node: %s", ruby_node_name(nd_type(node))); - } -} - -static VALUE -get_string_value(const NODE *node) -{ - switch (nd_type(node)) { - case NODE_STR: - return rb_node_str_string_val(node); - case NODE_FILE: - return rb_node_file_path_val(node); - default: - rb_bug("unexpected node: %s", ruby_node_name(nd_type(node))); - } -} - VALUE rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback_callback_func * ifunc) { @@ -853,29 +729,32 @@ rb_iseq_compile_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_callback (*ifunc->func)(iseq, ret, ifunc->data); - ADD_SYNTHETIC_INSN(ret, ISEQ_COMPILE_DATA(iseq)->last_line, -1, leave); + NODE dummy_line_node = generate_dummy_line_node(ISEQ_COMPILE_DATA(iseq)->last_line, -1); + ADD_INSN(ret, &dummy_line_node, leave); CHECK(iseq_setup_insn(iseq, ret)); return iseq_setup(iseq, ret); } -static bool drop_unreachable_return(LINK_ANCHOR *ret); - VALUE rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node) { DECL_ANCHOR(ret); INIT_ANCHOR(ret); + if (IMEMO_TYPE_P(node, imemo_ifunc)) { + rb_raise(rb_eArgError, "unexpected imemo_ifunc"); + } + if (node == 0) { NO_CHECK(COMPILE(ret, "nil", node)); - iseq_set_local_table(iseq, 0, 0); + iseq_set_local_table(iseq, 0); } /* assume node is T_NODE */ else if (nd_type_p(node, NODE_SCOPE)) { /* iseq type of top, method, class, block */ - iseq_set_local_table(iseq, RNODE_SCOPE(node)->nd_tbl, (NODE *)RNODE_SCOPE(node)->nd_args); - iseq_set_arguments(iseq, ret, (NODE *)RNODE_SCOPE(node)->nd_args); + iseq_set_local_table(iseq, node->nd_tbl); + iseq_set_arguments(iseq, ret, node->nd_args); switch (ISEQ_BODY(iseq)->type) { case ISEQ_TYPE_BLOCK: @@ -887,9 +766,10 @@ rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node) end->rescued = LABEL_RESCUE_END; ADD_TRACE(ret, RUBY_EVENT_B_CALL); - ADD_SYNTHETIC_INSN(ret, ISEQ_BODY(iseq)->location.first_lineno, -1, nop); + NODE dummy_line_node = generate_dummy_line_node(ISEQ_BODY(iseq)->location.first_lineno, -1); + ADD_INSN (ret, &dummy_line_node, nop); ADD_LABEL(ret, start); - CHECK(COMPILE(ret, "block body", RNODE_SCOPE(node)->nd_body)); + CHECK(COMPILE(ret, "block body", node->nd_body)); ADD_LABEL(ret, end); ADD_TRACE(ret, RUBY_EVENT_B_RETURN); ISEQ_COMPILE_DATA(iseq)->last_line = ISEQ_BODY(iseq)->location.code_location.end_pos.lineno; @@ -902,23 +782,23 @@ rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node) case ISEQ_TYPE_CLASS: { ADD_TRACE(ret, RUBY_EVENT_CLASS); - CHECK(COMPILE(ret, "scoped node", RNODE_SCOPE(node)->nd_body)); + CHECK(COMPILE(ret, "scoped node", node->nd_body)); ADD_TRACE(ret, RUBY_EVENT_END); ISEQ_COMPILE_DATA(iseq)->last_line = nd_line(node); break; } case ISEQ_TYPE_METHOD: { - ISEQ_COMPILE_DATA(iseq)->root_node = RNODE_SCOPE(node)->nd_body; + ISEQ_COMPILE_DATA(iseq)->root_node = node->nd_body; ADD_TRACE(ret, RUBY_EVENT_CALL); - CHECK(COMPILE(ret, "scoped node", RNODE_SCOPE(node)->nd_body)); - ISEQ_COMPILE_DATA(iseq)->root_node = RNODE_SCOPE(node)->nd_body; + CHECK(COMPILE(ret, "scoped node", node->nd_body)); + ISEQ_COMPILE_DATA(iseq)->root_node = node->nd_body; ADD_TRACE(ret, RUBY_EVENT_RETURN); ISEQ_COMPILE_DATA(iseq)->last_line = nd_line(node); break; } default: { - CHECK(COMPILE(ret, "scoped node", RNODE_SCOPE(node)->nd_body)); + CHECK(COMPILE(ret, "scoped node", node->nd_body)); break; } } @@ -960,8 +840,9 @@ rb_iseq_compile_node(rb_iseq_t *iseq, const NODE *node) ADD_GETLOCAL(ret, &dummy_line_node, LVAR_ERRINFO, 0); ADD_INSN1(ret, &dummy_line_node, throw, INT2FIX(0) /* continue throw */ ); } - else if (!drop_unreachable_return(ret)) { - ADD_SYNTHETIC_INSN(ret, ISEQ_COMPILE_DATA(iseq)->last_line, -1, leave); + else { + NODE dummy_line_node = generate_dummy_line_node(ISEQ_COMPILE_DATA(iseq)->last_line, -1); + ADD_INSN(ret, &dummy_line_node, leave); } #if OPT_SUPPORT_JOKE @@ -991,12 +872,6 @@ rb_iseq_translate_threaded_code(rb_iseq_t *iseq) } FL_SET((VALUE)iseq, ISEQ_TRANSLATED); #endif - -#if USE_YJIT - rb_yjit_live_iseq_count++; - rb_yjit_iseq_alloc_count++; -#endif - return COMPILE_OK; } @@ -1353,7 +1228,6 @@ new_label_body(rb_iseq_t *iseq, long line) labelobj->set = 0; labelobj->rescued = LABEL_RESCUE_NONE; labelobj->unremovable = 0; - labelobj->position = -1; return labelobj; } @@ -1370,7 +1244,7 @@ new_adjust_body(rb_iseq_t *iseq, LABEL *label, int line) } static void -iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE, VALUE), VALUE data) +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++) { @@ -1381,7 +1255,7 @@ iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE, VALUE), VALUE dat case TS_VALUE: case TS_IC: // constant path array case TS_CALLDATA: // ci is stored. - func(OPERAND_AT(insn, j), data); + func(&OPERAND_AT(insn, j), data); break; default: break; @@ -1390,13 +1264,14 @@ iseq_insn_each_markable_object(INSN *insn, void (*func)(VALUE, VALUE), VALUE dat } static void -iseq_insn_each_object_write_barrier(VALUE obj, VALUE iseq) +iseq_insn_each_object_write_barrier(VALUE *obj_ptr, VALUE iseq) { - RB_OBJ_WRITTEN(iseq, Qundef, obj); + RB_OBJ_WRITTEN(iseq, Qundef, *obj_ptr); } static INSN * -new_insn_core(rb_iseq_t *iseq, int line_no, int node_id, int insn_id, int argc, VALUE *argv) +new_insn_core(rb_iseq_t *iseq, const NODE *line_node, + int insn_id, int argc, VALUE *argv) { INSN *iobj = compile_data_alloc_insn(iseq); @@ -1405,8 +1280,8 @@ new_insn_core(rb_iseq_t *iseq, int line_no, int node_id, int insn_id, int argc, iobj->link.type = ISEQ_ELEMENT_INSN; iobj->link.next = 0; iobj->insn_id = insn_id; - iobj->insn_info.line_no = line_no; - iobj->insn_info.node_id = node_id; + iobj->insn_info.line_no = nd_line(line_node); + iobj->insn_info.node_id = nd_node_id(line_node); iobj->insn_info.events = 0; iobj->operands = argv; iobj->operand_size = argc; @@ -1418,7 +1293,7 @@ new_insn_core(rb_iseq_t *iseq, int line_no, int node_id, int insn_id, int argc, } static INSN * -new_insn_body(rb_iseq_t *iseq, int line_no, int node_id, enum ruby_vminsn_type insn_id, int argc, ...) +new_insn_body(rb_iseq_t *iseq, const NODE *const line_node, enum ruby_vminsn_type insn_id, int argc, ...) { VALUE *operands = 0; va_list argv; @@ -1432,7 +1307,7 @@ new_insn_body(rb_iseq_t *iseq, int line_no, int node_id, enum ruby_vminsn_type i } va_end(argv); } - return new_insn_core(iseq, line_no, node_id, insn_id, argc, operands); + return new_insn_core(iseq, line_node, insn_id, argc, operands); } static const struct rb_callinfo * @@ -1440,16 +1315,16 @@ new_callinfo(rb_iseq_t *iseq, ID mid, int argc, unsigned int flag, struct rb_cal { VM_ASSERT(argc >= 0); + if (!(flag & (VM_CALL_ARGS_SPLAT | VM_CALL_ARGS_BLOCKARG | VM_CALL_KW_SPLAT)) && + kw_arg == NULL && !has_blockiseq) { + flag |= VM_CALL_ARGS_SIMPLE; + } + if (kw_arg) { flag |= VM_CALL_KWARG; argc += kw_arg->keyword_len; } - if (!(flag & (VM_CALL_ARGS_SPLAT | VM_CALL_ARGS_BLOCKARG | VM_CALL_KWARG | VM_CALL_KW_SPLAT | VM_CALL_FORWARDING)) - && !has_blockiseq) { - flag |= VM_CALL_ARGS_SIMPLE; - } - ISEQ_BODY(iseq)->ci_size++; const struct rb_callinfo *ci = vm_ci_new(mid, flag, argc, kw_arg); RB_OBJ_WRITTEN(iseq, Qundef, ci); @@ -1457,7 +1332,7 @@ new_callinfo(rb_iseq_t *iseq, ID mid, int argc, unsigned int flag, struct rb_cal } static INSN * -new_insn_send(rb_iseq_t *iseq, int line_no, int node_id, ID id, VALUE argc, const rb_iseq_t *blockiseq, VALUE flag, struct rb_callinfo_kwarg *keywords) +new_insn_send(rb_iseq_t *iseq, const NODE *const line_node, ID id, VALUE argc, const rb_iseq_t *blockiseq, VALUE flag, struct rb_callinfo_kwarg *keywords) { VALUE *operands = compile_data_calloc2(iseq, sizeof(VALUE), 2); VALUE ci = (VALUE)new_callinfo(iseq, id, FIX2INT(argc), FIX2INT(flag), keywords, blockiseq != NULL); @@ -1466,16 +1341,7 @@ new_insn_send(rb_iseq_t *iseq, int line_no, int node_id, ID id, VALUE argc, cons if (blockiseq) { RB_OBJ_WRITTEN(iseq, Qundef, blockiseq); } - - INSN *insn; - - if (vm_ci_flag((struct rb_callinfo *)ci) & VM_CALL_FORWARDING) { - insn = new_insn_core(iseq, line_no, node_id, BIN(sendforward), 2, operands); - } - else { - insn = new_insn_core(iseq, line_no, node_id, BIN(send), 2, operands); - } - + INSN *insn = new_insn_core(iseq, line_node, BIN(send), 2, operands); RB_OBJ_WRITTEN(iseq, Qundef, ci); RB_GC_GUARD(ci); return insn; @@ -1486,16 +1352,19 @@ new_child_iseq(rb_iseq_t *iseq, const NODE *const node, VALUE name, const rb_iseq_t *parent, enum rb_iseq_type type, int line_no) { rb_iseq_t *ret_iseq; - VALUE ast_value = rb_ruby_ast_new(node); + rb_ast_body_t ast; + + ast.root = node; + ast.compile_option = 0; + ast.script_lines = ISEQ_BODY(iseq)->variable.script_lines; debugs("[new_child_iseq]> ---------------------------------------\n"); int isolated_depth = ISEQ_COMPILE_DATA(iseq)->isolated_depth; - ret_iseq = rb_iseq_new_with_opt(ast_value, name, + ret_iseq = rb_iseq_new_with_opt(&ast, name, rb_iseq_path(iseq), rb_iseq_realpath(iseq), line_no, parent, isolated_depth ? isolated_depth + 1 : 0, - type, ISEQ_COMPILE_DATA(iseq)->option, - ISEQ_BODY(iseq)->variable.script_lines); + type, ISEQ_COMPILE_DATA(iseq)->option); debugs("[new_child_iseq]< ---------------------------------------\n"); return ret_iseq; } @@ -1515,14 +1384,11 @@ new_child_iseq_with_callback(rb_iseq_t *iseq, const struct rb_iseq_new_with_call } static void -set_catch_except_p(rb_iseq_t *iseq) +set_catch_except_p(struct rb_iseq_constant_body *body) { - RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq)); - ISEQ_COMPILE_DATA(iseq)->catch_except_p = true; - if (ISEQ_BODY(iseq)->parent_iseq != NULL) { - if (ISEQ_COMPILE_DATA(ISEQ_BODY(iseq)->parent_iseq)) { - set_catch_except_p((rb_iseq_t *) ISEQ_BODY(iseq)->parent_iseq); - } + body->catch_except_p = true; + if (body->parent_iseq != NULL) { + set_catch_except_p(ISEQ_BODY(body->parent_iseq)); } } @@ -1534,7 +1400,7 @@ set_catch_except_p(rb_iseq_t *iseq) So this function sets true for limited ISeqs with break/next/redo catch table entries whose child ISeq would really raise an exception. */ static void -update_catch_except_flags(rb_iseq_t *iseq, struct rb_iseq_constant_body *body) +update_catch_except_flags(struct rb_iseq_constant_body *body) { unsigned int pos; size_t i; @@ -1547,7 +1413,7 @@ update_catch_except_flags(rb_iseq_t *iseq, struct rb_iseq_constant_body *body) while (pos < body->iseq_size) { insn = rb_vm_insn_decode(body->iseq_encoded[pos]); if (insn == BIN(throw)) { - set_catch_except_p(iseq); + set_catch_except_p(body); break; } pos += insn_len(insn); @@ -1562,8 +1428,7 @@ update_catch_except_flags(rb_iseq_t *iseq, struct rb_iseq_constant_body *body) if (entry->type != CATCH_TYPE_BREAK && entry->type != CATCH_TYPE_NEXT && entry->type != CATCH_TYPE_REDO) { - RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq)); - ISEQ_COMPILE_DATA(iseq)->catch_except_p = true; + body->catch_except_p = true; break; } } @@ -1575,9 +1440,9 @@ iseq_insert_nop_between_end_and_cont(rb_iseq_t *iseq) VALUE catch_table_ary = ISEQ_COMPILE_DATA(iseq)->catch_table_ary; if (NIL_P(catch_table_ary)) return; unsigned int i, tlen = (unsigned int)RARRAY_LEN(catch_table_ary); - const VALUE *tptr = RARRAY_CONST_PTR(catch_table_ary); + const VALUE *tptr = RARRAY_CONST_PTR_TRANSIENT(catch_table_ary); for (i = 0; i < tlen; i++) { - const VALUE *ptr = RARRAY_CONST_PTR(tptr[i]); + const VALUE *ptr = RARRAY_CONST_PTR_TRANSIENT(tptr[i]); LINK_ELEMENT *end = (LINK_ELEMENT *)(ptr[2] & ~1); LINK_ELEMENT *cont = (LINK_ELEMENT *)(ptr[4] & ~1); LINK_ELEMENT *e; @@ -1590,15 +1455,14 @@ iseq_insert_nop_between_end_and_cont(rb_iseq_t *iseq) for (e = end; e && (IS_LABEL(e) || IS_TRACE(e)); e = e->next) { if (e == cont) { - INSN *nop = new_insn_core(iseq, 0, -1, BIN(nop), 0, 0); + NODE dummy_line_node = generate_dummy_line_node(0, -1); + INSN *nop = new_insn_core(iseq, &dummy_line_node, BIN(nop), 0, 0); ELEM_INSERT_NEXT(end, &nop->link); break; } } } } - - RB_GC_GUARD(catch_table_ary); } static int @@ -1625,6 +1489,13 @@ iseq_setup_insn(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) dump_disasm_list(FIRST_ELEMENT(anchor)); } + if (ISEQ_COMPILE_DATA(iseq)->option->stack_caching) { + debugs("[compile step 3.3 (iseq_set_sequence_stackcaching)]\n"); + iseq_set_sequence_stackcaching(iseq, anchor); + if (compile_debug > 5) + dump_disasm_list(FIRST_ELEMENT(anchor)); + } + debugs("[compile step 3.4 (iseq_insert_nop_between_end_and_cont)]\n"); iseq_insert_nop_between_end_and_cont(iseq); if (compile_debug > 5) @@ -1654,12 +1525,10 @@ iseq_setup(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) if (!rb_iseq_translate_threaded_code(iseq)) return COMPILE_NG; debugs("[compile step 6 (update_catch_except_flags)] \n"); - RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq)); - update_catch_except_flags(iseq, ISEQ_BODY(iseq)); + update_catch_except_flags(ISEQ_BODY(iseq)); debugs("[compile step 6.1 (remove unused catch tables)] \n"); - RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq)); - if (!ISEQ_COMPILE_DATA(iseq)->catch_except_p && ISEQ_BODY(iseq)->catch_table) { + if (!ISEQ_BODY(iseq)->catch_except_p && ISEQ_BODY(iseq)->catch_table) { xfree(ISEQ_BODY(iseq)->catch_table); ISEQ_BODY(iseq)->catch_table = NULL; } @@ -1795,7 +1664,7 @@ access_outer_variables(const rb_iseq_t *iseq, int level, ID id, bool write) COMPILE_ERROR(iseq, ISEQ_LAST_LINE(iseq), "can not yield from isolated Proc"); } else { - COMPILE_ERROR(iseq, ISEQ_LAST_LINE(iseq), "can not access variable '%s' from isolated Proc", rb_id2name(id)); + COMPILE_ERROR(iseq, ISEQ_LAST_LINE(iseq), "can not access variable `%s' from isolated Proc", rb_id2name(id)); } } @@ -1900,7 +1769,7 @@ static int iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const struct rb_args_info *args, int arg_size) { - const rb_node_kw_arg_t *node = args->kw_args; + const NODE *node = args->kw_args; struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq); struct rb_iseq_param_keyword *keyword; const VALUE default_values = rb_ary_hidden_new(1); @@ -1919,7 +1788,7 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, node = args->kw_args; while (node) { - const NODE *val_node = get_nd_value(node->nd_body); + const NODE *val_node = node->nd_body->nd_value; VALUE dv; if (val_node == NODE_SPECIAL_REQUIRED_KEYWORD) { @@ -1927,29 +1796,8 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, } else { switch (nd_type(val_node)) { - case NODE_SYM: - dv = rb_node_sym_string_val(val_node); - break; - case NODE_REGX: - dv = rb_node_regx_string_val(val_node); - break; - case NODE_LINE: - dv = rb_node_line_lineno_val(val_node); - break; - case NODE_INTEGER: - dv = rb_node_integer_literal_val(val_node); - break; - case NODE_FLOAT: - dv = rb_node_float_literal_val(val_node); - break; - case NODE_RATIONAL: - dv = rb_node_rational_literal_val(val_node); - break; - case NODE_IMAGINARY: - dv = rb_node_imaginary_literal_val(val_node); - break; - case NODE_ENCODING: - dv = rb_node_encoding_val(val_node); + case NODE_LIT: + dv = val_node->nd_lit; break; case NODE_NIL: dv = Qnil; @@ -1961,7 +1809,7 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, dv = Qfalse; break; default: - NO_CHECK(COMPILE_POPPED(optargs, "kwarg", RNODE(node))); /* nd_type_p(node, NODE_KW_ARG) */ + NO_CHECK(COMPILE_POPPED(optargs, "kwarg", node)); /* nd_type_p(node, NODE_KW_ARG) */ dv = complex_mark; } @@ -1974,23 +1822,23 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, keyword->num = kw; - if (RNODE_DVAR(args->kw_rest_arg)->nd_vid != 0) { - ID kw_id = iseq->body->local_table[arg_size]; + if (args->kw_rest_arg->nd_vid != 0) { keyword->rest_start = arg_size++; body->param.flags.has_kwrest = TRUE; - - if (kw_id == idPow) body->param.flags.anon_kwrest = TRUE; } keyword->required_num = rkw; keyword->table = &body->local_table[keyword->bits_start - keyword->num]; - if (RARRAY_LEN(default_values)) { + { VALUE *dvs = ALLOC_N(VALUE, RARRAY_LEN(default_values)); for (i = 0; i < RARRAY_LEN(default_values); i++) { VALUE dv = RARRAY_AREF(default_values, i); if (dv == complex_mark) dv = Qundef; - RB_OBJ_WRITE(iseq, &dvs[i], dv); + if (!SPECIAL_CONST_P(dv)) { + RB_OBJ_WRITTEN(iseq, Qundef, dv); + } + dvs[i] = dv; } keyword->default_values = dvs; @@ -1998,22 +1846,6 @@ iseq_set_arguments_keywords(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, return arg_size; } -static void -iseq_set_use_block(rb_iseq_t *iseq) -{ - struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq); - if (!body->param.flags.use_block) { - body->param.flags.use_block = 1; - - rb_vm_t *vm = GET_VM(); - - if (!vm->unused_block_warning_strict) { - st_data_t key = (st_data_t)rb_intern_str(body->location.label); // String -> ID - st_insert(vm->unused_block_warning_table, key, 1); - } - } -} - static int iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *const node_args) { @@ -2021,7 +1853,7 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons if (node_args) { struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq); - struct rb_args_info *args = &RNODE_ARGS(node_args)->nd_ainfo; + struct rb_args_info *args = node_args->nd_ainfo; ID rest_id = 0; int last_comma = 0; ID block_id = 0; @@ -2041,22 +1873,15 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons } block_id = args->block_arg; - bool optimized_forward = (args->forwarding && args->pre_args_num == 0 && !args->opt_args); - - if (optimized_forward) { - rest_id = 0; - block_id = 0; - } - if (args->opt_args) { - const rb_node_opt_arg_t *node = args->opt_args; + const NODE *node = args->opt_args; LABEL *label; VALUE labels = rb_ary_hidden_new(1); VALUE *opt_table; int i = 0, j; while (node) { - label = NEW_LABEL(nd_line(RNODE(node))); + label = NEW_LABEL(nd_line(node)); rb_ary_push(labels, (VALUE)label | 1); ADD_LABEL(optargs, label); NO_CHECK(COMPILE_POPPED(optargs, "optarg", node->nd_body)); @@ -2071,7 +1896,7 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons opt_table = ALLOC_N(VALUE, i+1); - MEMCPY(opt_table, RARRAY_CONST_PTR(labels), VALUE, i+1); + MEMCPY(opt_table, RARRAY_CONST_PTR_TRANSIENT(labels), VALUE, i+1); for (j = 0; j < i+1; j++) { opt_table[j] &= ~1; } @@ -2086,8 +1911,7 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons if (rest_id) { body->param.rest_start = arg_size++; body->param.flags.has_rest = TRUE; - if (rest_id == '*') body->param.flags.anon_rest = TRUE; - RUBY_ASSERT(body->param.rest_start != -1); + assert(body->param.rest_start != -1); } if (args->first_post_arg) { @@ -2104,16 +1928,11 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons if (args->kw_args) { arg_size = iseq_set_arguments_keywords(iseq, optargs, args, arg_size); } - else if (args->kw_rest_arg && !optimized_forward) { - ID kw_id = iseq->body->local_table[arg_size]; + else if (args->kw_rest_arg) { struct rb_iseq_param_keyword *keyword = ZALLOC_N(struct rb_iseq_param_keyword, 1); keyword->rest_start = arg_size++; body->param.keyword = keyword; body->param.flags.has_kwrest = TRUE; - - static ID anon_kwrest = 0; - if (!anon_kwrest) anon_kwrest = rb_intern("**"); - if (kw_id == anon_kwrest) body->param.flags.anon_kwrest = TRUE; } else if (args->no_kwarg) { body->param.flags.accepts_no_kwarg = TRUE; @@ -2122,14 +1941,6 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons if (block_id) { body->param.block_start = arg_size++; body->param.flags.has_block = TRUE; - iseq_set_use_block(iseq); - } - - // Only optimize specifically methods like this: `foo(...)` - if (optimized_forward) { - body->param.flags.use_block = 1; - body->param.flags.forwardable = TRUE; - arg_size = 1; } iseq_calc_param_size(iseq); @@ -2161,26 +1972,13 @@ iseq_set_arguments(rb_iseq_t *iseq, LINK_ANCHOR *const optargs, const NODE *cons } static int -iseq_set_local_table(rb_iseq_t *iseq, const rb_ast_id_table_t *tbl, const NODE *const node_args) +iseq_set_local_table(rb_iseq_t *iseq, const rb_ast_id_table_t *tbl) { unsigned int size = tbl ? tbl->size : 0; - unsigned int offset = 0; - - if (node_args) { - struct rb_args_info *args = &RNODE_ARGS(node_args)->nd_ainfo; - - // If we have a function that only has `...` as the parameter, - // then its local table should only be `...` - // FIXME: I think this should be fixed in the AST rather than special case here. - if (args->forwarding && args->pre_args_num == 0 && !args->opt_args) { - size -= 3; - offset += 3; - } - } if (size > 0) { ID *ids = (ID *)ALLOC_N(ID, size); - MEMCPY(ids, tbl->ids + offset, ID, size); + MEMCPY(ids, tbl->ids, ID, size); ISEQ_BODY(iseq)->local_table = ids; } ISEQ_BODY(iseq)->local_table_size = size; @@ -2464,7 +2262,6 @@ add_adjust_info(struct iseq_insn_info_entry *insns_info, unsigned int *positions int insns_info_index, int code_index, const ADJUST *adjust) { insns_info[insns_info_index].line_no = adjust->line_no; - insns_info[insns_info_index].node_id = -1; insns_info[insns_info_index].events = 0; positions[insns_info_index] = code_index; return TRUE; @@ -2585,12 +2382,7 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) generated_iseq = ALLOC_N(VALUE, code_index); insns_info = ALLOC_N(struct iseq_insn_info_entry, insn_num); positions = ALLOC_N(unsigned int, insn_num); - if (ISEQ_IS_SIZE(body)) { - body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, ISEQ_IS_SIZE(body)); - } - else { - body->is_entries = NULL; - } + body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, ISEQ_IS_SIZE(body)); body->call_data = ZALLOC_N(struct rb_call_data, body->ci_size); ISEQ_COMPILE_DATA(iseq)->ci_index = 0; @@ -2726,11 +2518,11 @@ iseq_set_sequence(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) break; } - case TS_CALLDATA: + case TS_CALLDATA: { const struct rb_callinfo *source_ci = (const struct rb_callinfo *)operands[j]; - RUBY_ASSERT(ISEQ_COMPILE_DATA(iseq)->ci_index <= body->ci_size); struct rb_call_data *cd = &body->call_data[ISEQ_COMPILE_DATA(iseq)->ci_index++]; + assert(ISEQ_COMPILE_DATA(iseq)->ci_index <= body->ci_size); cd->ci = source_ci; cd->cc = vm_cc_empty(); generated_iseq[code_index + 1 + j] = (VALUE)cd; @@ -2872,23 +2664,18 @@ iseq_set_exception_table(rb_iseq_t *iseq) 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(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)); table->size = tlen; for (i = 0; i < table->size; i++) { - int pos; - ptr = RARRAY_CONST_PTR(tptr[i]); + ptr = RARRAY_CONST_PTR_TRANSIENT(tptr[i]); entry = UNALIGNED_MEMBER_PTR(table, entries[i]); entry->type = (enum rb_catch_type)(ptr[0] & 0xffff); - pos = label_get_position((LABEL *)(ptr[1] & ~1)); - RUBY_ASSERT(pos >= 0); - entry->start = (unsigned int)pos; - pos = label_get_position((LABEL *)(ptr[2] & ~1)); - RUBY_ASSERT(pos >= 0); - entry->end = (unsigned int)pos; + entry->start = label_get_position((LABEL *)(ptr[1] & ~1)); + entry->end = label_get_position((LABEL *)(ptr[2] & ~1)); entry->iseq = (rb_iseq_t *)ptr[3]; RB_OBJ_WRITTEN(iseq, Qundef, entry->iseq); @@ -2902,7 +2689,6 @@ iseq_set_exception_table(rb_iseq_t *iseq) if (entry->type == CATCH_TYPE_RESCUE || entry->type == CATCH_TYPE_BREAK || entry->type == CATCH_TYPE_NEXT) { - RUBY_ASSERT(entry->sp > 0); entry->sp--; } } @@ -3012,18 +2798,16 @@ unref_destination(INSN *iobj, int pos) if (!lobj->refcnt) ELEM_REMOVE(&lobj->link); } -static bool +static void replace_destination(INSN *dobj, INSN *nobj) { VALUE n = OPERAND_AT(nobj, 0); LABEL *dl = (LABEL *)OPERAND_AT(dobj, 0); LABEL *nl = (LABEL *)n; - if (dl == nl) return false; --dl->refcnt; ++nl->refcnt; OPERAND_AT(dobj, 0) = n; if (!dl->refcnt) ELEM_REMOVE(&dl->link); - return true; } static LABEL* @@ -3117,7 +2901,7 @@ iseq_pop_newarray(rb_iseq_t *iseq, INSN *iobj) static int is_frozen_putstring(INSN *insn, VALUE *op) { - if (IS_INSN_ID(insn, putstring) || IS_INSN_ID(insn, putchilledstring)) { + if (IS_INSN_ID(insn, putstring)) { *op = OPERAND_AT(insn, 0); return 1; } @@ -3159,7 +2943,6 @@ optimize_checktype(rb_iseq_t *iseq, INSN *iobj) switch (INSN_OF(iobj)) { case BIN(putstring): - case BIN(putchilledstring): type = INT2FIX(T_STRING); break; case BIN(putnil): @@ -3200,6 +2983,7 @@ optimize_checktype(rb_iseq_t *iseq, INSN *iobj) } line = ciobj->insn_info.line_no; node_id = ciobj->insn_info.node_id; + NODE dummy_line_node = generate_dummy_line_node(line, node_id); if (!dest) { if (niobj->link.next && IS_LABEL(niobj->link.next)) { dest = (LABEL *)niobj->link.next; /* reuse label */ @@ -3209,9 +2993,9 @@ optimize_checktype(rb_iseq_t *iseq, INSN *iobj) ELEM_INSERT_NEXT(&niobj->link, &dest->link); } } - INSERT_AFTER_INSN1(iobj, line, node_id, jump, dest); + INSERT_AFTER_INSN1(iobj, &dummy_line_node, jump, dest); LABEL_REF(dest); - if (!dup) INSERT_AFTER_INSN(iobj, line, node_id, pop); + if (!dup) INSERT_AFTER_INSN(iobj, &dummy_line_node, pop); return TRUE; } @@ -3237,8 +3021,6 @@ ci_argc_set(const rb_iseq_t *iseq, const struct rb_callinfo *ci, int argc) return nci; } -#define vm_ci_simple(ci) (vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE) - static int iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcallopt) { @@ -3277,10 +3059,9 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal * => in this case, first jump instruction should jump to * LABEL2 directly */ - if (replace_destination(iobj, diobj)) { - remove_unreachable_chunk(iseq, iobj->link.next); - goto again; - } + replace_destination(iobj, diobj); + remove_unreachable_chunk(iseq, iobj->link.next); + goto again; } else if (IS_INSN_ID(diobj, leave)) { /* @@ -3325,7 +3106,8 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal */ piobj->insn_id = (IS_INSN_ID(piobj, branchif)) ? BIN(branchunless) : BIN(branchif); - if (replace_destination(piobj, iobj) && refcnt <= 1) { + replace_destination(piobj, iobj); + if (refcnt <= 1) { ELEM_REMOVE(&iobj->link); } else { @@ -3347,7 +3129,8 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal * pop * jump L1 */ - INSN *popiobj = new_insn_core(iseq, iobj->insn_info.line_no, iobj->insn_info.node_id, BIN(pop), 0, 0); + NODE dummy_line_node = generate_dummy_line_node(iobj->insn_info.line_no, iobj->insn_info.node_id); + INSN *popiobj = new_insn_core(iseq, &dummy_line_node, BIN(pop), 0, 0); ELEM_REPLACE(&piobj->link, &popiobj->link); } } @@ -3392,117 +3175,19 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal /* * ... * duparray [...] - * concatarray | concattoarray + * concatarray * => * ... * putobject [...] - * concatarray | concattoarray + * concatarray */ if (IS_INSN_ID(iobj, duparray)) { LINK_ELEMENT *next = iobj->link.next; - if (IS_INSN(next) && (IS_INSN_ID(next, concatarray) || IS_INSN_ID(next, concattoarray))) { + if (IS_INSN(next) && IS_INSN_ID(next, concatarray)) { iobj->insn_id = BIN(putobject); } } - /* - * duparray [...] - * send <calldata!mid:freeze, argc:0, ARGS_SIMPLE>, nil - * => - * opt_ary_freeze [...], <calldata!mid:freeze, argc:0, ARGS_SIMPLE> - */ - if (IS_INSN_ID(iobj, duparray)) { - LINK_ELEMENT *next = iobj->link.next; - if (IS_INSN(next) && (IS_INSN_ID(next, send))) { - const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(next, 0); - const rb_iseq_t *blockiseq = (rb_iseq_t *)OPERAND_AT(next, 1); - - if (vm_ci_simple(ci) && vm_ci_argc(ci) == 0 && blockiseq == NULL && vm_ci_mid(ci) == idFreeze) { - VALUE ary = iobj->operands[0]; - rb_obj_reveal(ary, rb_cArray); - - iobj->insn_id = BIN(opt_ary_freeze); - iobj->operand_size = 2; - iobj->operands = compile_data_calloc2(iseq, iobj->operand_size, sizeof(VALUE)); - iobj->operands[0] = ary; - iobj->operands[1] = (VALUE)ci; - ELEM_REMOVE(next); - } - } - } - - /* - * duphash {...} - * send <calldata!mid:freeze, argc:0, ARGS_SIMPLE>, nil - * => - * opt_hash_freeze {...}, <calldata!mid:freeze, argc:0, ARGS_SIMPLE> - */ - if (IS_INSN_ID(iobj, duphash)) { - LINK_ELEMENT *next = iobj->link.next; - if (IS_INSN(next) && (IS_INSN_ID(next, send))) { - const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(next, 0); - const rb_iseq_t *blockiseq = (rb_iseq_t *)OPERAND_AT(next, 1); - - if (vm_ci_simple(ci) && vm_ci_argc(ci) == 0 && blockiseq == NULL && vm_ci_mid(ci) == idFreeze) { - VALUE hash = iobj->operands[0]; - rb_obj_reveal(hash, rb_cHash); - - iobj->insn_id = BIN(opt_hash_freeze); - iobj->operand_size = 2; - iobj->operands = compile_data_calloc2(iseq, iobj->operand_size, sizeof(VALUE)); - iobj->operands[0] = hash; - iobj->operands[1] = (VALUE)ci; - ELEM_REMOVE(next); - } - } - } - - /* - * newarray 0 - * send <calldata!mid:freeze, argc:0, ARGS_SIMPLE>, nil - * => - * opt_ary_freeze [], <calldata!mid:freeze, argc:0, ARGS_SIMPLE> - */ - if (IS_INSN_ID(iobj, newarray) && iobj->operands[0] == INT2FIX(0)) { - LINK_ELEMENT *next = iobj->link.next; - if (IS_INSN(next) && (IS_INSN_ID(next, send))) { - const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(next, 0); - const rb_iseq_t *blockiseq = (rb_iseq_t *)OPERAND_AT(next, 1); - - if (vm_ci_simple(ci) && vm_ci_argc(ci) == 0 && blockiseq == NULL && vm_ci_mid(ci) == idFreeze) { - iobj->insn_id = BIN(opt_ary_freeze); - iobj->operand_size = 2; - iobj->operands = compile_data_calloc2(iseq, iobj->operand_size, sizeof(VALUE)); - iobj->operands[0] = rb_cArray_empty_frozen; - iobj->operands[1] = (VALUE)ci; - ELEM_REMOVE(next); - } - } - } - - /* - * newhash 0 - * send <calldata!mid:freeze, argc:0, ARGS_SIMPLE>, nil - * => - * opt_hash_freeze {}, <calldata!mid:freeze, argc:0, ARGS_SIMPLE> - */ - if (IS_INSN_ID(iobj, newhash) && iobj->operands[0] == INT2FIX(0)) { - LINK_ELEMENT *next = iobj->link.next; - if (IS_INSN(next) && (IS_INSN_ID(next, send))) { - const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(next, 0); - const rb_iseq_t *blockiseq = (rb_iseq_t *)OPERAND_AT(next, 1); - - if (vm_ci_simple(ci) && vm_ci_argc(ci) == 0 && blockiseq == NULL && vm_ci_mid(ci) == idFreeze) { - iobj->insn_id = BIN(opt_hash_freeze); - iobj->operand_size = 2; - iobj->operands = compile_data_calloc2(iseq, iobj->operand_size, sizeof(VALUE)); - iobj->operands[0] = rb_cHash_empty_frozen; - iobj->operands[1] = (VALUE)ci; - ELEM_REMOVE(next); - } - } - } - if (IS_INSN_ID(iobj, branchif) || IS_INSN_ID(iobj, branchnil) || IS_INSN_ID(iobj, branchunless)) { @@ -3552,7 +3237,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal for (;;) { if (IS_INSN(&nobj->link) && IS_INSN_ID(nobj, jump)) { - if (!replace_destination(iobj, nobj)) break; + replace_destination(iobj, nobj); } else if (prev_dup && IS_INSN_ID(nobj, dup) && !!(nobj = (INSN *)nobj->link.next) && @@ -3573,7 +3258,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal * dup * if L2 */ - if (!replace_destination(iobj, nobj)) break; + replace_destination(iobj, nobj); } else if (pobj) { /* @@ -3624,12 +3309,14 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal ELEM_REMOVE(iobj->link.prev); } else if (!iseq_pop_newarray(iseq, pobj)) { - pobj = new_insn_core(iseq, pobj->insn_info.line_no, pobj->insn_info.node_id, BIN(pop), 0, NULL); + NODE dummy_line_node = generate_dummy_line_node(pobj->insn_info.line_no, pobj->insn_info.node_id); + pobj = new_insn_core(iseq, &dummy_line_node, BIN(pop), 0, NULL); ELEM_INSERT_PREV(&iobj->link, &pobj->link); } if (cond) { if (prev_dup) { - pobj = new_insn_core(iseq, pobj->insn_info.line_no, pobj->insn_info.node_id, BIN(putnil), 0, NULL); + NODE dummy_line_node = generate_dummy_line_node(pobj->insn_info.line_no, pobj->insn_info.node_id); + pobj = new_insn_core(iseq, &dummy_line_node, BIN(putnil), 0, NULL); ELEM_INSERT_NEXT(&iobj->link, &pobj->link); } iobj->insn_id = BIN(jump); @@ -3659,12 +3346,11 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal enum ruby_vminsn_type previ = ((INSN *)prev)->insn_id; if (previ == BIN(putobject) || previ == BIN(putnil) || previ == BIN(putself) || previ == BIN(putstring) || - previ == BIN(putchilledstring) || previ == BIN(dup) || previ == BIN(getlocal) || previ == BIN(getblockparam) || previ == BIN(getblockparamproxy) || - previ == BIN(getinstancevariable) || + /* getinstancevariable may issue a warning */ previ == BIN(duparray)) { /* just push operand or static value and pop soon, no * side effects */ @@ -3676,7 +3362,8 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal } else if (previ == BIN(concatarray)) { INSN *piobj = (INSN *)prev; - INSERT_BEFORE_INSN1(piobj, piobj->insn_info.line_no, piobj->insn_info.node_id, splatarray, Qfalse); + NODE dummy_line_node = generate_dummy_line_node(piobj->insn_info.line_no, piobj->insn_info.node_id); + INSERT_BEFORE_INSN1(piobj, &dummy_line_node, splatarray, Qfalse); INSN_OF(piobj) = BIN(pop); } else if (previ == BIN(concatstrings)) { @@ -3693,6 +3380,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal if (IS_INSN_ID(iobj, newarray) || IS_INSN_ID(iobj, duparray) || + IS_INSN_ID(iobj, expandarray) || IS_INSN_ID(iobj, concatarray) || IS_INSN_ID(iobj, splatarray) || 0) { @@ -3741,6 +3429,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal } } else { + NODE dummy_line_node = generate_dummy_line_node(iobj->insn_info.line_no, iobj->insn_info.node_id); long diff = FIX2LONG(op1) - FIX2LONG(op2); INSN_OF(iobj) = BIN(opt_reverse); OPERAND_AT(iobj, 0) = OPERAND_AT(next, 0); @@ -3754,7 +3443,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal * opt_reverse Y */ for (; diff > 0; diff--) { - INSERT_BEFORE_INSN(iobj, iobj->insn_info.line_no, iobj->insn_info.node_id, pop); + INSERT_BEFORE_INSN(iobj, &dummy_line_node, pop); } } else { /* (op1 < op2) */ @@ -3766,7 +3455,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal * opt_reverse Y */ for (; diff < 0; diff++) { - INSERT_BEFORE_INSN(iobj, iobj->insn_info.line_no, iobj->insn_info.node_id, putnil); + INSERT_BEFORE_INSN(iobj, &dummy_line_node, putnil); } } } @@ -3801,7 +3490,7 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal } } - if (IS_INSN_ID(iobj, putstring) || IS_INSN_ID(iobj, putchilledstring) || + if (IS_INSN_ID(iobj, putstring) || (IS_INSN_ID(iobj, putobject) && RB_TYPE_P(OPERAND_AT(iobj, 0), T_STRING))) { /* * putstring "" @@ -3988,10 +3677,6 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal if (IS_TRACE(iobj->link.next)) { if (IS_NEXT_INSN_ID(iobj->link.next, leave)) { iobj->insn_id = BIN(opt_invokebuiltin_delegate_leave); - const struct rb_builtin_function *bf = (const struct rb_builtin_function *)iobj->operands[0]; - if (iobj == (INSN *)list && bf->argc == 0 && (iseq->body->builtin_attrs & BUILTIN_ATTR_LEAF)) { - iseq->body->builtin_attrs |= BUILTIN_ATTR_SINGLE_NOARG_LEAF; - } } } } @@ -4009,64 +3694,6 @@ iseq_peephole_optimize(rb_iseq_t *iseq, LINK_ELEMENT *list, const int do_tailcal } } - if (IS_INSN_ID(iobj, splatarray) && OPERAND_AT(iobj, 0) == false) { - LINK_ELEMENT *niobj = &iobj->link; - if (IS_NEXT_INSN_ID(niobj, duphash)) { - niobj = niobj->next; - LINK_ELEMENT *siobj; - unsigned int set_flags = 0, unset_flags = 0; - - /* - * Eliminate hash allocation for f(*a, kw: 1) - * - * splatarray false - * duphash - * send ARGS_SPLAT|KW_SPLAT|KW_SPLAT_MUT and not ARGS_BLOCKARG - * => - * splatarray false - * putobject - * send ARGS_SPLAT|KW_SPLAT - */ - if (IS_NEXT_INSN_ID(niobj, send)) { - siobj = niobj->next; - set_flags = VM_CALL_ARGS_SPLAT|VM_CALL_KW_SPLAT|VM_CALL_KW_SPLAT_MUT; - unset_flags = VM_CALL_ARGS_BLOCKARG; - } - /* - * Eliminate hash allocation for f(*a, kw: 1, &{arg,lvar,@iv}) - * - * splatarray false - * duphash - * getlocal / getinstancevariable / getblockparamproxy - * send ARGS_SPLAT|KW_SPLAT|KW_SPLAT_MUT|ARGS_BLOCKARG - * => - * splatarray false - * putobject - * getlocal / getinstancevariable / getblockparamproxy - * send ARGS_SPLAT|KW_SPLAT|ARGS_BLOCKARG - */ - else if ((IS_NEXT_INSN_ID(niobj, getlocal) || IS_NEXT_INSN_ID(niobj, getinstancevariable) || - IS_NEXT_INSN_ID(niobj, getblockparamproxy)) && (IS_NEXT_INSN_ID(niobj->next, send))) { - siobj = niobj->next->next; - set_flags = VM_CALL_ARGS_SPLAT|VM_CALL_KW_SPLAT|VM_CALL_KW_SPLAT_MUT|VM_CALL_ARGS_BLOCKARG; - } - - if (set_flags) { - const struct rb_callinfo *ci = (const struct rb_callinfo *)OPERAND_AT(siobj, 0); - unsigned int flags = vm_ci_flag(ci); - if ((flags & set_flags) == set_flags && !(flags & unset_flags)) { - ((INSN*)niobj)->insn_id = BIN(putobject); - OPERAND_AT(niobj, 0) = rb_hash_freeze(rb_hash_resurrect(OPERAND_AT(niobj, 0))); - - const struct rb_callinfo *nci = vm_ci_new(vm_ci_mid(ci), - flags & ~VM_CALL_KW_SPLAT_MUT, vm_ci_argc(ci), vm_ci_kwarg(ci)); - RB_OBJ_WRITTEN(iseq, ci, nci); - OPERAND_AT(siobj, 0) = (VALUE)nci; - } - } - } - } - return COMPILE_OK; } @@ -4094,82 +3721,24 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj) if (IS_INSN_ID(iobj, newarray) && iobj->link.next && IS_INSN(iobj->link.next)) { /* - * [a, b, ...].max/min -> a, b, c, opt_newarray_send max/min + * [a, b, ...].max/min -> a, b, c, opt_newarray_max/min */ INSN *niobj = (INSN *)iobj->link.next; if (IS_INSN_ID(niobj, send)) { const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT(niobj, 0); - if (vm_ci_simple(ci) && vm_ci_argc(ci) == 0) { - VALUE method = INT2FIX(0); + if ((vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE) && vm_ci_argc(ci) == 0) { switch (vm_ci_mid(ci)) { case idMax: - method = INT2FIX(VM_OPT_NEWARRAY_SEND_MAX); - break; + iobj->insn_id = BIN(opt_newarray_max); + ELEM_REMOVE(&niobj->link); + return COMPILE_OK; case idMin: - method = INT2FIX(VM_OPT_NEWARRAY_SEND_MIN); - break; - case idHash: - method = INT2FIX(VM_OPT_NEWARRAY_SEND_HASH); - break; - } - - if (method != INT2FIX(0)) { - VALUE num = iobj->operands[0]; - int operand_len = insn_len(BIN(opt_newarray_send)) - 1; - iobj->insn_id = BIN(opt_newarray_send); - iobj->operands = compile_data_calloc2(iseq, operand_len, sizeof(VALUE)); - iobj->operands[0] = num; - iobj->operands[1] = method; - iobj->operand_size = operand_len; + iobj->insn_id = BIN(opt_newarray_min); ELEM_REMOVE(&niobj->link); return COMPILE_OK; } } } - else if ((IS_INSN_ID(niobj, putstring) || IS_INSN_ID(niobj, putchilledstring) || - (IS_INSN_ID(niobj, putobject) && RB_TYPE_P(OPERAND_AT(niobj, 0), T_STRING))) && - IS_NEXT_INSN_ID(&niobj->link, send)) { - const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT((INSN *)niobj->link.next, 0); - if (vm_ci_simple(ci) && vm_ci_argc(ci) == 1 && vm_ci_mid(ci) == idPack) { - VALUE num = iobj->operands[0]; - int operand_len = insn_len(BIN(opt_newarray_send)) - 1; - iobj->insn_id = BIN(opt_newarray_send); - iobj->operands = compile_data_calloc2(iseq, operand_len, sizeof(VALUE)); - iobj->operands[0] = FIXNUM_INC(num, 1); - iobj->operands[1] = INT2FIX(VM_OPT_NEWARRAY_SEND_PACK); - iobj->operand_size = operand_len; - ELEM_REMOVE(&iobj->link); - ELEM_REMOVE(niobj->link.next); - ELEM_INSERT_NEXT(&niobj->link, &iobj->link); - return COMPILE_OK; - } - } - // newarray n, putchilledstring "E", getlocal b, send :pack with {buffer: b} - // -> putchilledstring "E", getlocal b, opt_newarray_send n+2, :pack, :buffer - else if ((IS_INSN_ID(niobj, putstring) || IS_INSN_ID(niobj, putchilledstring) || - (IS_INSN_ID(niobj, putobject) && RB_TYPE_P(OPERAND_AT(niobj, 0), T_STRING))) && - IS_NEXT_INSN_ID(&niobj->link, getlocal) && - (niobj->link.next && IS_NEXT_INSN_ID(niobj->link.next, send))) { - const struct rb_callinfo *ci = (struct rb_callinfo *)OPERAND_AT((INSN *)(niobj->link.next)->next, 0); - const struct rb_callinfo_kwarg *kwarg = vm_ci_kwarg(ci); - if (vm_ci_mid(ci) == idPack && vm_ci_argc(ci) == 2 && - (kwarg && kwarg->keyword_len == 1 && kwarg->keywords[0] == rb_id2sym(idBuffer))) { - VALUE num = iobj->operands[0]; - int operand_len = insn_len(BIN(opt_newarray_send)) - 1; - iobj->insn_id = BIN(opt_newarray_send); - iobj->operands = compile_data_calloc2(iseq, operand_len, sizeof(VALUE)); - iobj->operands[0] = FIXNUM_INC(num, 2); - iobj->operands[1] = INT2FIX(VM_OPT_NEWARRAY_SEND_PACK_BUFFER); - iobj->operand_size = operand_len; - // Remove the "send" insn. - ELEM_REMOVE((niobj->link.next)->next); - // Remove the modified insn from its original "newarray" position... - ELEM_REMOVE(&iobj->link); - // and insert it after the buffer insn. - ELEM_INSERT_NEXT(niobj->link.next, &iobj->link); - return COMPILE_OK; - } - } } if (IS_INSN_ID(iobj, send)) { @@ -4177,7 +3746,7 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj) const rb_iseq_t *blockiseq = (rb_iseq_t *)OPERAND_AT(iobj, 1); #define SP_INSN(opt) insn_set_specialized_instruction(iseq, iobj, BIN(opt_##opt)) - if (vm_ci_simple(ci)) { + if (vm_ci_flag(ci) & VM_CALL_ARGS_SIMPLE) { switch (vm_ci_argc(ci)) { case 0: switch (vm_ci_mid(ci)) { @@ -4217,7 +3786,7 @@ iseq_specialized_instruction(rb_iseq_t *iseq, INSN *iobj) } } - if ((vm_ci_flag(ci) & (VM_CALL_ARGS_BLOCKARG | VM_CALL_FORWARDING)) == 0 && blockiseq == NULL) { + if ((vm_ci_flag(ci) & VM_CALL_ARGS_BLOCKARG) == 0 && blockiseq == NULL) { iobj->insn_id = BIN(opt_send_without_block); iobj->operand_size = insn_len(iobj->insn_id) - 1; } @@ -4260,7 +3829,7 @@ iseq_optimize(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) int do_block_optimization = 0; - if (ISEQ_BODY(iseq)->type == ISEQ_TYPE_BLOCK && !ISEQ_COMPILE_DATA(iseq)->catch_except_p) { + if (ISEQ_BODY(iseq)->type == ISEQ_TYPE_BLOCK && !ISEQ_BODY(iseq)->catch_except_p) { do_block_optimization = 1; } @@ -4337,7 +3906,8 @@ new_unified_insn(rb_iseq_t *iseq, list = list->next; } - return new_insn_core(iseq, iobj->insn_info.line_no, iobj->insn_info.node_id, insn_id, argc, operands); + NODE dummy_line_node = generate_dummy_line_node(iobj->insn_info.line_no, iobj->insn_info.node_id); + return new_insn_core(iseq, &dummy_line_node, insn_id, argc, operands); } #endif @@ -4397,24 +3967,185 @@ iseq_insns_unification(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) return COMPILE_OK; } +#if OPT_STACK_CACHING + +#define SC_INSN(insn, stat) sc_insn_info[(insn)][(stat)] +#define SC_NEXT(insn) sc_insn_next[(insn)] + +#include "opt_sc.inc" + +static int +insn_set_sc_state(rb_iseq_t *iseq, const LINK_ELEMENT *anchor, INSN *iobj, int state) +{ + int nstate; + int insn_id; + + insn_id = iobj->insn_id; + iobj->insn_id = SC_INSN(insn_id, state); + nstate = SC_NEXT(iobj->insn_id); + + if (insn_id == BIN(jump) || + insn_id == BIN(branchif) || insn_id == BIN(branchunless)) { + LABEL *lobj = (LABEL *)OPERAND_AT(iobj, 0); + + if (lobj->sc_state != 0) { + if (lobj->sc_state != nstate) { + BADINSN_DUMP(anchor, iobj, lobj); + COMPILE_ERROR(iseq, iobj->insn_info.line_no, + "insn_set_sc_state error: %d at "LABEL_FORMAT + ", %d expected\n", + lobj->sc_state, lobj->label_no, nstate); + return COMPILE_NG; + } + } + else { + lobj->sc_state = nstate; + } + if (insn_id == BIN(jump)) { + nstate = SCS_XX; + } + } + else if (insn_id == BIN(leave)) { + nstate = SCS_XX; + } + + return nstate; +} + +static int +label_set_sc_state(LABEL *lobj, int state) +{ + if (lobj->sc_state != 0) { + if (lobj->sc_state != state) { + state = lobj->sc_state; + } + } + else { + lobj->sc_state = state; + } + + return state; +} + + +#endif + +static int +iseq_set_sequence_stackcaching(rb_iseq_t *iseq, LINK_ANCHOR *const anchor) +{ +#if OPT_STACK_CACHING + LINK_ELEMENT *list; + int state, insn_id; + + /* initialize */ + state = SCS_XX; + list = FIRST_ELEMENT(anchor); + /* dump_disasm_list(list); */ + + /* for each list element */ + while (list) { + redo_point: + switch (list->type) { + case ISEQ_ELEMENT_INSN: + { + INSN *iobj = (INSN *)list; + insn_id = iobj->insn_id; + + /* dump_disasm_list(list); */ + + switch (insn_id) { + case BIN(nop): + { + /* exception merge point */ + if (state != SCS_AX) { + NODE dummy_line_node = generate_dummy_line_node(0, -1); + INSN *rpobj = + new_insn_body(iseq, &dummy_line_node, BIN(reput), 0); + + /* replace this insn */ + ELEM_REPLACE(list, (LINK_ELEMENT *)rpobj); + list = (LINK_ELEMENT *)rpobj; + goto redo_point; + } + break; + } + case BIN(swap): + { + if (state == SCS_AB || state == SCS_BA) { + state = (state == SCS_AB ? SCS_BA : SCS_AB); + + ELEM_REMOVE(list); + list = list->next; + goto redo_point; + } + break; + } + case BIN(pop): + { + switch (state) { + case SCS_AX: + case SCS_BX: + state = SCS_XX; + break; + case SCS_AB: + state = SCS_AX; + break; + case SCS_BA: + state = SCS_BX; + break; + case SCS_XX: + goto normal_insn; + default: + COMPILE_ERROR(iseq, iobj->insn_info.line_no, + "unreachable"); + return COMPILE_NG; + } + /* remove useless pop */ + ELEM_REMOVE(list); + list = list->next; + goto redo_point; + } + default:; + /* none */ + } /* end of switch */ + normal_insn: + state = insn_set_sc_state(iseq, anchor, iobj, state); + break; + } + case ISEQ_ELEMENT_LABEL: + { + LABEL *lobj; + lobj = (LABEL *)list; + + state = label_set_sc_state(lobj, state); + } + default: + break; + } + list = list->next; + } +#endif + return COMPILE_OK; +} + static int all_string_result_p(const NODE *node) { if (!node) return FALSE; switch (nd_type(node)) { - case NODE_STR: case NODE_DSTR: case NODE_FILE: + case NODE_STR: case NODE_DSTR: return TRUE; case NODE_IF: case NODE_UNLESS: - if (!RNODE_IF(node)->nd_body || !RNODE_IF(node)->nd_else) return FALSE; - if (all_string_result_p(RNODE_IF(node)->nd_body)) - return all_string_result_p(RNODE_IF(node)->nd_else); + if (!node->nd_body || !node->nd_else) return FALSE; + if (all_string_result_p(node->nd_body)) + return all_string_result_p(node->nd_else); return FALSE; case NODE_AND: case NODE_OR: - if (!RNODE_AND(node)->nd_2nd) - return all_string_result_p(RNODE_AND(node)->nd_1st); - if (!all_string_result_p(RNODE_AND(node)->nd_1st)) + if (!node->nd_2nd) + return all_string_result_p(node->nd_1st); + if (!all_string_result_p(node->nd_1st)) return FALSE; - return all_string_result_p(RNODE_AND(node)->nd_2nd); + return all_string_result_p(node->nd_2nd); default: return FALSE; } @@ -4423,8 +4154,8 @@ all_string_result_p(const NODE *node) static int compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int *cntp) { - const struct RNode_LIST *list = RNODE_DSTR(node)->nd_next; - VALUE lit = rb_node_dstr_string_val(node); + const NODE *list = node->nd_next; + VALUE lit = node->nd_lit; LINK_ELEMENT *first_lit = 0; int cnt = 0; @@ -4445,7 +4176,7 @@ compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cons while (list) { const NODE *const head = list->nd_head; if (nd_type_p(head, NODE_STR)) { - lit = rb_node_str_string_val(head); + lit = rb_fstring(head->nd_lit); ADD_INSN1(ret, head, putobject, lit); RB_OBJ_WRITTEN(iseq, Qundef, lit); lit = Qnil; @@ -4454,7 +4185,7 @@ compile_dstr_fragments(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cons CHECK(COMPILE(ret, "each string", head)); } cnt++; - list = (struct RNode_LIST *)list->nd_next; + list = list->nd_next; } if (NIL_P(lit) && first_lit) { ELEM_REMOVE(first_lit); @@ -4469,12 +4200,12 @@ static int compile_block(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popped) { while (node && nd_type_p(node, NODE_BLOCK)) { - CHECK(COMPILE_(ret, "BLOCK body", RNODE_BLOCK(node)->nd_head, - (RNODE_BLOCK(node)->nd_next ? 1 : popped))); - node = RNODE_BLOCK(node)->nd_next; + CHECK(COMPILE_(ret, "BLOCK body", node->nd_head, + (node->nd_next ? 1 : popped))); + node = node->nd_next; } if (node) { - CHECK(COMPILE_(ret, "BLOCK next", RNODE_BLOCK(node)->nd_next, popped)); + CHECK(COMPILE_(ret, "BLOCK next", node->nd_next, popped)); } return COMPILE_OK; } @@ -4483,8 +4214,8 @@ static int compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node) { int cnt; - if (!RNODE_DSTR(node)->nd_next) { - VALUE lit = rb_node_dstr_string_val(node); + if (!node->nd_next) { + VALUE lit = rb_fstring(node->nd_lit); ADD_INSN1(ret, node, putstring, lit); RB_OBJ_WRITTEN(iseq, Qundef, lit); } @@ -4496,28 +4227,11 @@ compile_dstr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node) } static int -compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped) +compile_dregx(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node) { int cnt; - int cflag = (int)RNODE_DREGX(node)->as.nd_cflag; - - if (!RNODE_DREGX(node)->nd_next) { - if (!popped) { - VALUE src = rb_node_dregx_string_val(node); - VALUE match = rb_reg_compile(src, cflag, NULL, 0); - ADD_INSN1(ret, node, putobject, match); - RB_OBJ_WRITTEN(iseq, Qundef, match); - } - return COMPILE_OK; - } - CHECK(compile_dstr_fragments(iseq, ret, node, &cnt)); - ADD_INSN2(ret, node, toregexp, INT2FIX(cflag), INT2FIX(cnt)); - - if (popped) { - ADD_INSN(ret, node, pop); - } - + ADD_INSN2(ret, node, toregexp, INT2FIX(node->nd_cflag), INT2FIX(cnt)); return COMPILE_OK; } @@ -4535,7 +4249,7 @@ compile_flip_flop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const nod ADD_INSNL(ret, node, branchif, lend); /* *flip == 0 */ - CHECK(COMPILE(ret, "flip2 beg", RNODE_FLIP2(node)->nd_beg)); + CHECK(COMPILE(ret, "flip2 beg", node->nd_beg)); ADD_INSNL(ret, node, branchunless, else_label); ADD_INSN1(ret, node, putobject, Qtrue); ADD_INSN1(ret, node, setspecial, key); @@ -4545,7 +4259,7 @@ compile_flip_flop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const nod /* *flip == 1 */ ADD_LABEL(ret, lend); - CHECK(COMPILE(ret, "flip2 end", RNODE_FLIP2(node)->nd_end)); + CHECK(COMPILE(ret, "flip2 end", node->nd_end)); ADD_INSNL(ret, node, branchunless, then_label); ADD_INSN1(ret, node, putobject, Qfalse); ADD_INSN1(ret, node, setspecial, key); @@ -4555,73 +4269,40 @@ compile_flip_flop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const nod } static int -compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond, - LABEL *then_label, LABEL *else_label); - -#define COMPILE_SINGLE 2 -static int -compile_logical(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cond, - LABEL *then_label, LABEL *else_label) -{ - DECL_ANCHOR(seq); - INIT_ANCHOR(seq); - LABEL *label = NEW_LABEL(nd_line(cond)); - if (!then_label) then_label = label; - else if (!else_label) else_label = label; - - CHECK(compile_branch_condition(iseq, seq, cond, then_label, else_label)); - - if (LIST_INSN_SIZE_ONE(seq)) { - INSN *insn = (INSN *)ELEM_FIRST_INSN(FIRST_ELEMENT(seq)); - if (insn->insn_id == BIN(jump) && (LABEL *)(insn->operands[0]) == label) - return COMPILE_OK; - } - if (!label->refcnt) { - return COMPILE_SINGLE; - } - ADD_LABEL(seq, label); - ADD_SEQ(ret, seq); - return COMPILE_OK; -} - -static int -compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond, +compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *cond, LABEL *then_label, LABEL *else_label) { - int ok; - DECL_ANCHOR(ignore); - again: switch (nd_type(cond)) { case NODE_AND: - CHECK(ok = compile_logical(iseq, ret, RNODE_AND(cond)->nd_1st, NULL, else_label)); - cond = RNODE_AND(cond)->nd_2nd; - if (ok == COMPILE_SINGLE) { - INIT_ANCHOR(ignore); - ret = ignore; - then_label = NEW_LABEL(nd_line(cond)); - } - goto again; + { + LABEL *label = NEW_LABEL(nd_line(cond)); + CHECK(compile_branch_condition(iseq, ret, cond->nd_1st, label, + else_label)); + if (!label->refcnt) { + ADD_INSN(ret, cond, putnil); + break; + } + ADD_LABEL(ret, label); + cond = cond->nd_2nd; + goto again; + } case NODE_OR: - CHECK(ok = compile_logical(iseq, ret, RNODE_OR(cond)->nd_1st, then_label, NULL)); - cond = RNODE_OR(cond)->nd_2nd; - if (ok == COMPILE_SINGLE) { - INIT_ANCHOR(ignore); - ret = ignore; - else_label = NEW_LABEL(nd_line(cond)); - } - goto again; - case NODE_SYM: - case NODE_LINE: - case NODE_FILE: - case NODE_ENCODING: - case NODE_INTEGER: /* NODE_INTEGER is always true */ - case NODE_FLOAT: /* NODE_FLOAT is always true */ - case NODE_RATIONAL: /* NODE_RATIONAL is always true */ - case NODE_IMAGINARY: /* NODE_IMAGINARY is always true */ + { + LABEL *label = NEW_LABEL(nd_line(cond)); + CHECK(compile_branch_condition(iseq, ret, cond->nd_1st, then_label, + label)); + if (!label->refcnt) { + ADD_INSN(ret, cond, putnil); + break; + } + ADD_LABEL(ret, label); + cond = cond->nd_2nd; + goto again; + } + case NODE_LIT: /* NODE_LIT is always true */ case NODE_TRUE: case NODE_STR: - case NODE_REGX: case NODE_ZLIST: case NODE_LAMBDA: /* printf("useless condition eliminate (%s)\n", ruby_node_name(nd_type(cond))); */ @@ -4646,31 +4327,10 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond, CHECK(compile_flip_flop(iseq, ret, cond, FALSE, then_label, else_label)); return COMPILE_OK; case NODE_DEFINED: - CHECK(compile_defined_expr(iseq, ret, cond, Qfalse, ret == ignore)); + CHECK(compile_defined_expr(iseq, ret, cond, Qfalse)); break; default: - { - DECL_ANCHOR(cond_seq); - INIT_ANCHOR(cond_seq); - - CHECK(COMPILE(cond_seq, "branch condition", cond)); - - if (LIST_INSN_SIZE_ONE(cond_seq)) { - INSN *insn = (INSN *)ELEM_FIRST_INSN(FIRST_ELEMENT(cond_seq)); - if (insn->insn_id == BIN(putobject)) { - if (RTEST(insn->operands[0])) { - ADD_INSNL(ret, cond, jump, then_label); - // maybe unreachable - return COMPILE_OK; - } - else { - ADD_INSNL(ret, cond, jump, else_label); - return COMPILE_OK; - } - } - } - ADD_SEQ(ret, cond_seq); - } + CHECK(COMPILE(ret, "branch condition", cond)); break; } @@ -4684,68 +4344,33 @@ compile_branch_condition(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *cond, static int keyword_node_p(const NODE *const node) { - return nd_type_p(node, NODE_HASH) && (RNODE_HASH(node)->nd_brace & HASH_BRACE) != HASH_BRACE; -} - -static VALUE -get_symbol_value(rb_iseq_t *iseq, const NODE *node) -{ - switch (nd_type(node)) { - case NODE_SYM: - return rb_node_sym_string_val(node); - default: - UNKNOWN_NODE("get_symbol_value", node, Qnil); - } -} - -static VALUE -node_hash_unique_key_index(rb_iseq_t *iseq, rb_node_hash_t *node_hash, int *count_ptr) -{ - NODE *node = node_hash->nd_head; - VALUE hash = rb_hash_new(); - VALUE ary = rb_ary_new(); - - for (int i = 0; node != NULL; i++, node = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next) { - VALUE key = get_symbol_value(iseq, RNODE_LIST(node)->nd_head); - VALUE idx = rb_hash_aref(hash, key); - if (!NIL_P(idx)) { - rb_ary_store(ary, FIX2INT(idx), Qfalse); - (*count_ptr)--; - } - rb_hash_aset(hash, key, INT2FIX(i)); - rb_ary_store(ary, i, Qtrue); - (*count_ptr)++; - } - - return ary; + return nd_type_p(node, NODE_HASH) && (node->nd_brace & HASH_BRACE) != HASH_BRACE; } static int compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, - const NODE *const root_node, - struct rb_callinfo_kwarg **const kw_arg_ptr, - unsigned int *flag) + const NODE *const root_node, + struct rb_callinfo_kwarg **const kw_arg_ptr, + unsigned int *flag) { - RUBY_ASSERT(nd_type_p(root_node, NODE_HASH)); - RUBY_ASSERT(kw_arg_ptr != NULL); - RUBY_ASSERT(flag != NULL); + if (kw_arg_ptr == NULL) return FALSE; - if (RNODE_HASH(root_node)->nd_head && nd_type_p(RNODE_HASH(root_node)->nd_head, NODE_LIST)) { - const NODE *node = RNODE_HASH(root_node)->nd_head; + if (root_node->nd_head && nd_type_p(root_node->nd_head, NODE_LIST)) { + const NODE *node = root_node->nd_head; int seen_nodes = 0; while (node) { - const NODE *key_node = RNODE_LIST(node)->nd_head; + const NODE *key_node = node->nd_head; seen_nodes++; - RUBY_ASSERT(nd_type_p(node, NODE_LIST)); - if (key_node && nd_type_p(key_node, NODE_SYM)) { + assert(nd_type_p(node, NODE_LIST)); + if (key_node && nd_type_p(key_node, NODE_LIT) && SYMBOL_P(key_node->nd_lit)) { /* can be keywords */ } else { if (flag) { *flag |= VM_CALL_KW_SPLAT; - if (seen_nodes > 1 || RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next) { + if (seen_nodes > 1 || node->nd_next->nd_next) { /* A new hash will be created for the keyword arguments * in this case, so mark the method as passing mutable * keyword splat. @@ -4755,37 +4380,29 @@ compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, } return FALSE; } - node = RNODE_LIST(node)->nd_next; /* skip value node */ - node = RNODE_LIST(node)->nd_next; + node = node->nd_next; /* skip value node */ + node = node->nd_next; } /* may be keywords */ - node = RNODE_HASH(root_node)->nd_head; + node = root_node->nd_head; { - int len = 0; - VALUE key_index = node_hash_unique_key_index(iseq, RNODE_HASH(root_node), &len); + int len = (int)node->nd_alen / 2; struct rb_callinfo_kwarg *kw_arg = rb_xmalloc_mul_add(len, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg)); VALUE *keywords = kw_arg->keywords; int i = 0; - int j = 0; - kw_arg->references = 0; kw_arg->keyword_len = len; *kw_arg_ptr = kw_arg; - for (i=0; node != NULL; i++, node = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next) { - const NODE *key_node = RNODE_LIST(node)->nd_head; - const NODE *val_node = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head; - int popped = TRUE; - if (rb_ary_entry(key_index, i)) { - keywords[j] = get_symbol_value(iseq, key_node); - j++; - popped = FALSE; - } - NO_CHECK(COMPILE_(ret, "keyword values", val_node, popped)); + for (i=0; node != NULL; i++, node = node->nd_next->nd_next) { + const NODE *key_node = node->nd_head; + const NODE *val_node = node->nd_next->nd_head; + keywords[i] = key_node->nd_lit; + NO_CHECK(COMPILE(ret, "keyword values", val_node)); } - RUBY_ASSERT(j == len); + assert(i == len); return TRUE; } } @@ -4793,52 +4410,43 @@ compile_keyword_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, } static int -compile_args(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, NODE **kwnode_ptr) +compile_args(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, + struct rb_callinfo_kwarg **keywords_ptr, unsigned int *flag) { int len = 0; - for (; node; len++, node = RNODE_LIST(node)->nd_next) { + for (; node; len++, node = node->nd_next) { if (CPDEBUG > 0) { EXPECT_NODE("compile_args", node, NODE_LIST, -1); } - if (RNODE_LIST(node)->nd_next == NULL && keyword_node_p(RNODE_LIST(node)->nd_head)) { /* last node is kwnode */ - *kwnode_ptr = RNODE_LIST(node)->nd_head; + if (node->nd_next == NULL && keyword_node_p(node->nd_head)) { /* last node */ + if (compile_keyword_arg(iseq, ret, node->nd_head, keywords_ptr, flag)) { + len--; + } + else { + compile_hash(iseq, ret, node->nd_head, TRUE, FALSE); + } } else { - RUBY_ASSERT(!keyword_node_p(RNODE_LIST(node)->nd_head)); - NO_CHECK(COMPILE_(ret, "array element", RNODE_LIST(node)->nd_head, FALSE)); + NO_CHECK(COMPILE_(ret, "array element", node->nd_head, FALSE)); } } return len; } -static inline bool -frozen_string_literal_p(const rb_iseq_t *iseq) -{ - return ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal > 0; -} - -static inline bool -static_literal_node_p(const NODE *node, const rb_iseq_t *iseq, bool hash_key) +static inline int +static_literal_node_p(const NODE *node, const rb_iseq_t *iseq) { switch (nd_type(node)) { - case NODE_SYM: - case NODE_REGX: - case NODE_LINE: - case NODE_ENCODING: - case NODE_INTEGER: - case NODE_FLOAT: - case NODE_RATIONAL: - case NODE_IMAGINARY: + case NODE_LIT: case NODE_NIL: case NODE_TRUE: case NODE_FALSE: return TRUE; case NODE_STR: - case NODE_FILE: - return hash_key || frozen_string_literal_p(iseq); + return ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal; default: return FALSE; } @@ -4848,46 +4456,30 @@ static inline VALUE static_literal_value(const NODE *node, rb_iseq_t *iseq) { switch (nd_type(node)) { - case NODE_INTEGER: - return rb_node_integer_literal_val(node); - case NODE_FLOAT: - return rb_node_float_literal_val(node); - case NODE_RATIONAL: - return rb_node_rational_literal_val(node); - case NODE_IMAGINARY: - return rb_node_imaginary_literal_val(node); case NODE_NIL: return Qnil; case NODE_TRUE: return Qtrue; case NODE_FALSE: return Qfalse; - case NODE_SYM: - return rb_node_sym_string_val(node); - case NODE_REGX: - return rb_node_regx_string_val(node); - case NODE_LINE: - return rb_node_line_lineno_val(node); - case NODE_ENCODING: - return rb_node_encoding_val(node); - case NODE_FILE: case NODE_STR: if (ISEQ_COMPILE_DATA(iseq)->option->debug_frozen_string_literal || RTEST(ruby_debug)) { + VALUE lit; VALUE debug_info = rb_ary_new_from_args(2, rb_iseq_path(iseq), INT2FIX((int)nd_line(node))); - VALUE lit = rb_str_dup(get_string_value(node)); - rb_ivar_set(lit, id_debug_created_info, rb_ary_freeze(debug_info)); + lit = rb_str_dup(node->nd_lit); + rb_ivar_set(lit, id_debug_created_info, rb_obj_freeze(debug_info)); return rb_str_freeze(lit); } else { - return get_string_value(node); + return rb_fstring(node->nd_lit); } default: - rb_bug("unexpected node: %s", ruby_node_name(nd_type(node))); + return node->nd_lit; } } static int -compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popped, bool first_chunk) +compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int popped) { const NODE *line_node = node; @@ -4901,8 +4493,8 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int pop EXPECT_NODE("compile_array", node, NODE_LIST, -1); if (popped) { - for (; node; node = RNODE_LIST(node)->nd_next) { - NO_CHECK(COMPILE_(ret, "array element", RNODE_LIST(node)->nd_head, popped)); + for (; node; node = node->nd_next) { + NO_CHECK(COMPILE_(ret, "array element", node->nd_head, popped)); } return 1; } @@ -4922,8 +4514,8 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int pop * * [x1,x2,...,x10000] => * push x1 ; push x2 ; ...; push x256; newarray 256; - * push x257; push x258; ...; push x512; pushtoarray 256; - * push x513; push x514; ...; push x768; pushtoarray 256; + * push x257; push x258; ...; push x512; newarray 256; concatarray; + * push x513; push x514; ...; push x768; newarray 256; concatarray; * ... * * - Long subarray can be optimized by pre-allocating a hidden array. @@ -4933,38 +4525,38 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int pop * * [x, 1,2,3,...,100, z] => * push x; newarray 1; - * putobject [1,2,3,...,100] (<- hidden array); concattoarray; - * push z; pushtoarray 1; + * putobject [1,2,3,...,100] (<- hidden array); concatarray; + * push z; newarray 1; concatarray * - * - If the last element is a keyword, pushtoarraykwsplat should be emitted - * to only push it onto the array if it is not empty + * - If the last element is a keyword, newarraykwsplat should be emitted + * to check and remove empty keyword arguments hash from array. * (Note: a keyword is NODE_HASH which is not static_literal_node_p.) * * [1,2,3,**kw] => - * putobject 1; putobject 2; putobject 3; newarray 3; ...; pushtoarraykwsplat kw + * putobject 1; putobject 2; putobject 3; push kw; newarraykwsplat */ const int max_stack_len = 0x100; const int min_tmp_ary_len = 0x40; int stack_len = 0; + int first_chunk = 1; - /* Either create a new array, or push to the existing array */ -#define FLUSH_CHUNK \ + /* Convert pushed elements to an array, and concatarray if needed */ +#define FLUSH_CHUNK(newarrayinsn) \ if (stack_len) { \ - if (first_chunk) ADD_INSN1(ret, line_node, newarray, INT2FIX(stack_len)); \ - else ADD_INSN1(ret, line_node, pushtoarray, INT2FIX(stack_len)); \ - first_chunk = FALSE; \ - stack_len = 0; \ + ADD_INSN1(ret, line_node, newarrayinsn, INT2FIX(stack_len)); \ + if (!first_chunk) ADD_INSN(ret, line_node, concatarray); \ + first_chunk = stack_len = 0; \ } while (node) { int count = 1; /* pre-allocation check (this branch can be omittable) */ - if (static_literal_node_p(RNODE_LIST(node)->nd_head, iseq, false)) { + if (static_literal_node_p(node->nd_head, iseq)) { /* count the elements that are optimizable */ - const NODE *node_tmp = RNODE_LIST(node)->nd_next; - for (; node_tmp && static_literal_node_p(RNODE_LIST(node_tmp)->nd_head, iseq, false); node_tmp = RNODE_LIST(node_tmp)->nd_next) + const NODE *node_tmp = node->nd_next; + for (; node_tmp && static_literal_node_p(node_tmp->nd_head, iseq); node_tmp = node_tmp->nd_next) count++; if ((first_chunk && stack_len == 0 && !node_tmp) || count >= min_tmp_ary_len) { @@ -4972,61 +4564,77 @@ compile_array(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int pop VALUE ary = rb_ary_hidden_new(count); /* Create a hidden array */ - for (; count; count--, node = RNODE_LIST(node)->nd_next) - rb_ary_push(ary, static_literal_value(RNODE_LIST(node)->nd_head, iseq)); + for (; count; count--, node = node->nd_next) + rb_ary_push(ary, static_literal_value(node->nd_head, iseq)); OBJ_FREEZE(ary); /* Emit optimized code */ - FLUSH_CHUNK; + FLUSH_CHUNK(newarray); if (first_chunk) { ADD_INSN1(ret, line_node, duparray, ary); - first_chunk = FALSE; + first_chunk = 0; } else { ADD_INSN1(ret, line_node, putobject, ary); - ADD_INSN(ret, line_node, concattoarray); + ADD_INSN(ret, line_node, concatarray); } RB_OBJ_WRITTEN(iseq, Qundef, ary); } } /* Base case: Compile "count" elements */ - for (; count; count--, node = RNODE_LIST(node)->nd_next) { + for (; count; count--, node = node->nd_next) { if (CPDEBUG > 0) { EXPECT_NODE("compile_array", node, NODE_LIST, -1); } - if (!RNODE_LIST(node)->nd_next && keyword_node_p(RNODE_LIST(node)->nd_head)) { - /* Create array or push existing non-keyword elements onto array */ - if (stack_len == 0 && first_chunk) { - ADD_INSN1(ret, line_node, newarray, INT2FIX(0)); - } - else { - FLUSH_CHUNK; - } - NO_CHECK(COMPILE_(ret, "array element", RNODE_LIST(node)->nd_head, 0)); - ADD_INSN(ret, line_node, pushtoarraykwsplat); + NO_CHECK(COMPILE_(ret, "array element", node->nd_head, 0)); + stack_len++; + + if (!node->nd_next && keyword_node_p(node->nd_head)) { + /* Reached the end, and the last element is a keyword */ + FLUSH_CHUNK(newarraykwsplat); return 1; } - else { - NO_CHECK(COMPILE_(ret, "array element", RNODE_LIST(node)->nd_head, 0)); - stack_len++; - } /* If there are many pushed elements, flush them to avoid stack overflow */ - if (stack_len >= max_stack_len) FLUSH_CHUNK; + if (stack_len >= max_stack_len) FLUSH_CHUNK(newarray); } } - FLUSH_CHUNK; + FLUSH_CHUNK(newarray); #undef FLUSH_CHUNK return 1; } +/* Compile an array containing the single element represented by node */ +static int +compile_array_1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node) +{ + if (static_literal_node_p(node, iseq)) { + VALUE ary = rb_ary_hidden_new(1); + rb_ary_push(ary, static_literal_value(node, iseq)); + OBJ_FREEZE(ary); + + ADD_INSN1(ret, node, duparray, ary); + } + else { + CHECK(COMPILE_(ret, "array element", node, FALSE)); + if (keyword_node_p(node)) { + ADD_INSN1(ret, node, newarraykwsplat, INT2FIX(1)); + } + else { + ADD_INSN1(ret, node, newarray, INT2FIX(1)); + } + } + + return 1; +} + static inline int static_literal_node_pair_p(const NODE *node, const rb_iseq_t *iseq) { - return RNODE_LIST(node)->nd_head && static_literal_node_p(RNODE_LIST(node)->nd_head, iseq, true) && static_literal_node_p(RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head, iseq, false); + return node->nd_head && static_literal_node_p(node->nd_head, iseq) && static_literal_node_p(node->nd_next->nd_head, iseq); } static int @@ -5034,7 +4642,7 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth { const NODE *line_node = node; - node = RNODE_HASH(node)->nd_head; + node = node->nd_head; if (!node || nd_type_p(node, NODE_ZLIST)) { if (!popped) { @@ -5046,8 +4654,8 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth EXPECT_NODE("compile_hash", node, NODE_LIST, -1); if (popped) { - for (; node; node = RNODE_LIST(node)->nd_next) { - NO_CHECK(COMPILE_(ret, "hash element", RNODE_LIST(node)->nd_head, popped)); + for (; node; node = node->nd_next) { + NO_CHECK(COMPILE_(ret, "hash element", node->nd_head, popped)); } return 1; } @@ -5100,8 +4708,8 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth /* pre-allocation check (this branch can be omittable) */ if (static_literal_node_pair_p(node, iseq)) { /* count the elements that are optimizable */ - const NODE *node_tmp = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next; - for (; node_tmp && static_literal_node_pair_p(node_tmp, iseq); node_tmp = RNODE_LIST(RNODE_LIST(node_tmp)->nd_next)->nd_next) + const NODE *node_tmp = node->nd_next->nd_next; + for (; node_tmp && static_literal_node_pair_p(node_tmp, iseq); node_tmp = node_tmp->nd_next->nd_next) count++; if ((first_chunk && stack_len == 0 && !node_tmp) || count >= min_tmp_hash_len) { @@ -5109,14 +4717,14 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth VALUE ary = rb_ary_hidden_new(count); /* Create a hidden hash */ - for (; count; count--, node = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next) { + for (; count; count--, node = node->nd_next->nd_next) { VALUE elem[2]; - elem[0] = static_literal_value(RNODE_LIST(node)->nd_head, iseq); - elem[1] = static_literal_value(RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head, iseq); + elem[0] = static_literal_value(node->nd_head, iseq); + elem[1] = static_literal_value(node->nd_next->nd_head, iseq); rb_ary_cat(ary, elem, 2); } VALUE hash = rb_hash_new_with_size(RARRAY_LEN(ary) / 2); - rb_hash_bulk_insert(RARRAY_LEN(ary), RARRAY_CONST_PTR(ary), hash); + rb_hash_bulk_insert(RARRAY_LEN(ary), RARRAY_CONST_PTR_TRANSIENT(ary), hash); hash = rb_obj_hide(hash); OBJ_FREEZE(hash); @@ -5139,16 +4747,16 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth } /* Base case: Compile "count" elements */ - for (; count; count--, node = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next) { + for (; count; count--, node = node->nd_next->nd_next) { if (CPDEBUG > 0) { EXPECT_NODE("compile_hash", node, NODE_LIST, -1); } - if (RNODE_LIST(node)->nd_head) { + if (node->nd_head) { /* Normal key-value pair */ - NO_CHECK(COMPILE_(anchor, "hash key element", RNODE_LIST(node)->nd_head, 0)); - NO_CHECK(COMPILE_(anchor, "hash value element", RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head, 0)); + NO_CHECK(COMPILE_(anchor, "hash key element", node->nd_head, 0)); + NO_CHECK(COMPILE_(anchor, "hash value element", node->nd_next->nd_head, 0)); stack_len += 2; /* If there are many pushed elements, flush them to avoid stack overflow */ @@ -5158,13 +4766,12 @@ compile_hash(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, int meth /* kwsplat case: foo(..., **kw, ...) */ FLUSH_CHUNK(); - const NODE *kw = RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_head; - int empty_kw = nd_type_p(kw, NODE_HASH) && (!RNODE_HASH(kw)->nd_head); /* foo( ..., **{}, ...) */ + const NODE *kw = node->nd_next->nd_head; + int empty_kw = nd_type_p(kw, NODE_LIT) && RB_TYPE_P(kw->nd_lit, T_HASH); /* foo( ..., **{}, ...) */ int first_kw = first_chunk && stack_len == 0; /* foo(1,2,3, **kw, ...) */ - int last_kw = !RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next; /* foo( ..., **kw) */ + int last_kw = !node->nd_next->nd_next; /* foo( ..., **kw) */ int only_kw = last_kw && first_kw; /* foo(1,2,3, **kw) */ - empty_kw = empty_kw || nd_type_p(kw, NODE_NIL); /* foo( ..., **nil, ...) */ if (empty_kw) { if (only_kw && method_call_keywords) { /* **{} appears at the only keyword argument in method call, @@ -5224,34 +4831,29 @@ VALUE rb_node_case_when_optimizable_literal(const NODE *const node) { switch (nd_type(node)) { - case NODE_INTEGER: - return rb_node_integer_literal_val(node); - case NODE_FLOAT: { - VALUE v = rb_node_float_literal_val(node); + case NODE_LIT: { + VALUE v = node->nd_lit; double ival; - - if (modf(RFLOAT_VALUE(v), &ival) == 0.0) { + if (RB_FLOAT_TYPE_P(v) && + modf(RFLOAT_VALUE(v), &ival) == 0.0) { return FIXABLE(ival) ? LONG2FIX((long)ival) : rb_dbl2big(ival); } - return v; + if (RB_TYPE_P(v, T_RATIONAL) || RB_TYPE_P(v, T_COMPLEX)) { + return Qundef; + } + if (SYMBOL_P(v) || rb_obj_is_kind_of(v, rb_cNumeric)) { + return v; + } + break; } - case NODE_RATIONAL: - case NODE_IMAGINARY: - return Qundef; case NODE_NIL: return Qnil; case NODE_TRUE: return Qtrue; case NODE_FALSE: return Qfalse; - case NODE_SYM: - return rb_node_sym_string_val(node); - case NODE_LINE: - return rb_node_line_lineno_val(node); case NODE_STR: - return rb_node_str_string_val(node); - case NODE_FILE: - return rb_node_file_path_val(node); + return rb_fstring(node->nd_lit); } return Qundef; } @@ -5261,7 +4863,7 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals, LABEL *l1, int only_special_literals, VALUE literals) { while (vals) { - const NODE *val = RNODE_LIST(vals)->nd_head; + const NODE *val = vals->nd_head; VALUE lit = rb_node_case_when_optimizable_literal(val); if (UNDEF_P(lit)) { @@ -5271,9 +4873,9 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals, rb_hash_aset(literals, lit, (VALUE)(l1) | 1); } - if (nd_type_p(val, NODE_STR) || nd_type_p(val, NODE_FILE)) { - debugp_param("nd_lit", get_string_value(val)); - lit = get_string_value(val); + if (nd_type_p(val, NODE_STR)) { + debugp_param("nd_lit", val->nd_lit); + lit = rb_fstring(val->nd_lit); ADD_INSN1(cond_seq, val, putobject, lit); RB_OBJ_WRITTEN(iseq, Qundef, lit); } @@ -5281,11 +4883,11 @@ when_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals, if (!COMPILE(cond_seq, "when cond", val)) return -1; } - // Emit pattern === target + // Emit patern === target ADD_INSN1(cond_seq, vals, topn, INT2FIX(1)); ADD_CALL(cond_seq, vals, idEqq, INT2FIX(1)); ADD_INSNL(cond_seq, val, branchif, l1); - vals = RNODE_LIST(vals)->nd_next; + vals = vals->nd_next; } return only_special_literals; } @@ -5303,19 +4905,19 @@ when_splat_vals(rb_iseq_t *iseq, LINK_ANCHOR *const cond_seq, const NODE *vals, break; case NODE_SPLAT: ADD_INSN (cond_seq, line_node, dup); - CHECK(COMPILE(cond_seq, "when splat", RNODE_SPLAT(vals)->nd_head)); + CHECK(COMPILE(cond_seq, "when splat", vals->nd_head)); ADD_INSN1(cond_seq, line_node, splatarray, Qfalse); ADD_INSN1(cond_seq, line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE | VM_CHECKMATCH_ARRAY)); ADD_INSNL(cond_seq, line_node, branchif, l1); break; case NODE_ARGSCAT: - CHECK(when_splat_vals(iseq, cond_seq, RNODE_ARGSCAT(vals)->nd_head, l1, only_special_literals, literals)); - CHECK(when_splat_vals(iseq, cond_seq, RNODE_ARGSCAT(vals)->nd_body, l1, only_special_literals, literals)); + CHECK(when_splat_vals(iseq, cond_seq, vals->nd_head, l1, only_special_literals, literals)); + CHECK(when_splat_vals(iseq, cond_seq, vals->nd_body, l1, only_special_literals, literals)); break; case NODE_ARGSPUSH: - CHECK(when_splat_vals(iseq, cond_seq, RNODE_ARGSPUSH(vals)->nd_head, l1, only_special_literals, literals)); + CHECK(when_splat_vals(iseq, cond_seq, vals->nd_head, l1, only_special_literals, literals)); ADD_INSN (cond_seq, line_node, dup); - CHECK(COMPILE(cond_seq, "when argspush body", RNODE_ARGSPUSH(vals)->nd_body)); + CHECK(COMPILE(cond_seq, "when argspush body", vals->nd_body)); ADD_INSN1(cond_seq, line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_CASE)); ADD_INSNL(cond_seq, line_node, branchif, l1); break; @@ -5508,35 +5110,11 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const 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); - bool dupsplat = false; ci = ci_argc_set(iseq, ci, argc - 1); - if (!(vm_ci_flag(ci) & VM_CALL_ARGS_SPLAT_MUT)) { - /* Given h[*a], _ = ary - * setup_args sets VM_CALL_ARGS_SPLAT and not VM_CALL_ARGS_SPLAT_MUT - * `a` must be dupped, because it will be appended with ary[0] - * Since you are dupping `a`, you can set VM_CALL_ARGS_SPLAT_MUT - */ - dupsplat = true; - ci = ci_flag_set(iseq, ci, VM_CALL_ARGS_SPLAT_MUT); - } OPERAND_AT(iobj, 0) = (VALUE)ci; RB_OBJ_WRITTEN(iseq, Qundef, iobj); - - /* Given: h[*a], h[*b, 1] = ary - * h[*a] uses splatarray false and does not set VM_CALL_ARGS_SPLAT_MUT, - * so this uses splatarray true on a to dup it before using pushtoarray - * h[*b, 1] uses splatarray true and sets VM_CALL_ARGS_SPLAT_MUT, - * so you can use pushtoarray directly - */ - int line_no = nd_line(line_node); - int node_id = nd_node_id(line_node); - - if (dupsplat) { - INSERT_BEFORE_INSN(iobj, line_no, node_id, swap); - INSERT_BEFORE_INSN1(iobj, line_no, node_id, splatarray, Qtrue); - INSERT_BEFORE_INSN(iobj, line_no, node_id, swap); - } - INSERT_BEFORE_INSN1(iobj, line_no, node_id, pushtoarray, INT2FIX(1)); + INSERT_BEFORE_INSN1(iobj, line_node, newarray, INT2FIX(1)); + INSERT_BEFORE_INSN(iobj, line_node, concatarray); } if (!safenav_call) { ADD_INSN(lhs, line_node, pop); @@ -5568,7 +5146,7 @@ compile_massign_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const break; } case NODE_CDECL: - if (!RNODE_CDECL(node)->nd_vid) { + if (!node->nd_vid) { /* Special handling only needed for expr::C, not for C */ INSN *iobj; @@ -5606,8 +5184,8 @@ static int compile_massign_opt_lhs(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *lhsn) { if (lhsn) { - CHECK(compile_massign_opt_lhs(iseq, ret, RNODE_LIST(lhsn)->nd_next)); - CHECK(compile_massign_lhs(iseq, ret, ret, ret, ret, RNODE_LIST(lhsn)->nd_head, NULL, 0)); + CHECK(compile_massign_opt_lhs(iseq, ret, lhsn->nd_next)); + CHECK(compile_massign_lhs(iseq, ret, ret, ret, ret, lhsn->nd_head, NULL, 0)); } return COMPILE_OK; } @@ -5637,29 +5215,31 @@ compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *const ret, } while (lhsn) { - const NODE *ln = RNODE_LIST(lhsn)->nd_head; + const NODE *ln = lhsn->nd_head; switch (nd_type(ln)) { case NODE_LASGN: + MEMORY(ln->nd_vid); + break; case NODE_DASGN: case NODE_IASGN: case NODE_CVASGN: - MEMORY(get_nd_vid(ln)); + MEMORY(ln->nd_vid); break; default: return 0; } - lhsn = RNODE_LIST(lhsn)->nd_next; + lhsn = lhsn->nd_next; llen++; } while (rhsn) { if (llen <= rlen) { - NO_CHECK(COMPILE_POPPED(ret, "masgn val (popped)", RNODE_LIST(rhsn)->nd_head)); + NO_CHECK(COMPILE_POPPED(ret, "masgn val (popped)", rhsn->nd_head)); } else { - NO_CHECK(COMPILE(ret, "masgn val", RNODE_LIST(rhsn)->nd_head)); + NO_CHECK(COMPILE(ret, "masgn val", rhsn->nd_head)); } - rhsn = RNODE_LIST(rhsn)->nd_next; + rhsn = rhsn->nd_next; rlen++; } @@ -5676,31 +5256,32 @@ compile_massign_opt(rb_iseq_t *iseq, LINK_ANCHOR *const ret, static int compile_massign0(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const rhs, LINK_ANCHOR *const lhs, LINK_ANCHOR *const post, const NODE *const node, struct masgn_state *state, int popped) { - const NODE *rhsn = RNODE_MASGN(node)->nd_value; - const NODE *splatn = RNODE_MASGN(node)->nd_args; - const NODE *lhsn = RNODE_MASGN(node)->nd_head; + const NODE *rhsn = node->nd_value; + const NODE *splatn = node->nd_args; + const NODE *lhsn = node->nd_head; const NODE *lhsn_count = lhsn; int lhs_splat = (splatn && NODE_NAMED_REST_P(splatn)) ? 1 : 0; int llen = 0; int lpos = 0; + int expand = 1; while (lhsn_count) { llen++; - lhsn_count = RNODE_LIST(lhsn_count)->nd_next; + lhsn_count = lhsn_count->nd_next; } while (lhsn) { - CHECK(compile_massign_lhs(iseq, pre, rhs, lhs, post, RNODE_LIST(lhsn)->nd_head, state, (llen - lpos) + lhs_splat + state->lhs_level)); + CHECK(compile_massign_lhs(iseq, pre, rhs, lhs, post, lhsn->nd_head, state, (llen - lpos) + lhs_splat + state->lhs_level)); lpos++; - lhsn = RNODE_LIST(lhsn)->nd_next; + lhsn = lhsn->nd_next; } if (lhs_splat) { if (nd_type_p(splatn, NODE_POSTARG)) { /*a, b, *r, p1, p2 */ - const NODE *postn = RNODE_POSTARG(splatn)->nd_2nd; - const NODE *restn = RNODE_POSTARG(splatn)->nd_1st; - int plen = (int)RNODE_LIST(postn)->as.nd_alen; + const NODE *postn = splatn->nd_2nd; + const NODE *restn = splatn->nd_1st; + int plen = (int)postn->nd_alen; int ppos = 0; int flag = 0x02 | (NODE_NAMED_REST_P(restn) ? 0x01 : 0x00); @@ -5710,9 +5291,9 @@ compile_massign0(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const rhs CHECK(compile_massign_lhs(iseq, pre, rhs, lhs, post, restn, state, 1 + plen + state->lhs_level)); } while (postn) { - CHECK(compile_massign_lhs(iseq, pre, rhs, lhs, post, RNODE_LIST(postn)->nd_head, state, (plen - ppos) + state->lhs_level)); + CHECK(compile_massign_lhs(iseq, pre, rhs, lhs, post, postn->nd_head, state, (plen - ppos) + state->lhs_level)); ppos++; - postn = RNODE_LIST(postn)->nd_next; + postn = postn->nd_next; } } else { @@ -5721,6 +5302,7 @@ compile_massign0(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const rhs } } + if (!state->nested) { NO_CHECK(COMPILE(rhs, "normal masgn rhs", rhsn)); } @@ -5728,14 +5310,16 @@ compile_massign0(rb_iseq_t *iseq, LINK_ANCHOR *const pre, LINK_ANCHOR *const rhs if (!popped) { ADD_INSN(rhs, node, dup); } - ADD_INSN2(rhs, node, expandarray, INT2FIX(llen), INT2FIX(lhs_splat)); + if (expand) { + ADD_INSN2(rhs, node, expandarray, INT2FIX(llen), INT2FIX(lhs_splat)); + } return COMPILE_OK; } static int compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped) { - if (!popped || RNODE_MASGN(node)->nd_args || !compile_massign_opt(iseq, ret, RNODE_MASGN(node)->nd_value, RNODE_MASGN(node)->nd_head)) { + if (!popped || node->nd_args || !compile_massign_opt(iseq, ret, node->nd_value, node->nd_head)) { struct masgn_state state; state.lhs_level = popped ? 0 : 1; state.nested = 0; @@ -5757,7 +5341,7 @@ compile_massign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, while (memo) { VALUE topn_arg = INT2FIX((state.num_args - memo->argn) + memo->lhs_pos); for (int i = 0; i < memo->num_args; i++) { - INSERT_BEFORE_INSN1(memo->before_insn, nd_line(memo->line_node), nd_node_id(memo->line_node), topn, topn_arg); + INSERT_BEFORE_INSN1(memo->before_insn, memo->line_node, topn, topn_arg); } tmp_memo = memo->next; free(memo); @@ -5784,15 +5368,15 @@ collect_const_segments(rb_iseq_t *iseq, const NODE *node) for (;;) { switch (nd_type(node)) { case NODE_CONST: - rb_ary_unshift(arr, ID2SYM(RNODE_CONST(node)->nd_vid)); + rb_ary_unshift(arr, ID2SYM(node->nd_vid)); return arr; case NODE_COLON3: - rb_ary_unshift(arr, ID2SYM(RNODE_COLON3(node)->nd_mid)); + rb_ary_unshift(arr, ID2SYM(node->nd_mid)); rb_ary_unshift(arr, ID2SYM(idNULL)); return arr; case NODE_COLON2: - rb_ary_unshift(arr, ID2SYM(RNODE_COLON2(node)->nd_mid)); - node = RNODE_COLON2(node)->nd_head; + rb_ary_unshift(arr, ID2SYM(node->nd_mid)); + node = node->nd_head; break; default: return Qfalse; @@ -5806,22 +5390,22 @@ compile_const_prefix(rb_iseq_t *iseq, const NODE *const node, { switch (nd_type(node)) { case NODE_CONST: - debugi("compile_const_prefix - colon", RNODE_CONST(node)->nd_vid); + debugi("compile_const_prefix - colon", node->nd_vid); ADD_INSN1(body, node, putobject, Qtrue); - ADD_INSN1(body, node, getconstant, ID2SYM(RNODE_CONST(node)->nd_vid)); + ADD_INSN1(body, node, getconstant, ID2SYM(node->nd_vid)); break; case NODE_COLON3: - debugi("compile_const_prefix - colon3", RNODE_COLON3(node)->nd_mid); + debugi("compile_const_prefix - colon3", node->nd_mid); ADD_INSN(body, node, pop); ADD_INSN1(body, node, putobject, rb_cObject); ADD_INSN1(body, node, putobject, Qtrue); - ADD_INSN1(body, node, getconstant, ID2SYM(RNODE_COLON3(node)->nd_mid)); + ADD_INSN1(body, node, getconstant, ID2SYM(node->nd_mid)); break; case NODE_COLON2: - CHECK(compile_const_prefix(iseq, RNODE_COLON2(node)->nd_head, pref, body)); - debugi("compile_const_prefix - colon2", RNODE_COLON2(node)->nd_mid); + CHECK(compile_const_prefix(iseq, node->nd_head, pref, body)); + debugi("compile_const_prefix - colon2", node->nd_mid); ADD_INSN1(body, node, putobject, Qfalse); - ADD_INSN1(body, node, getconstant, ID2SYM(RNODE_COLON2(node)->nd_mid)); + ADD_INSN1(body, node, getconstant, ID2SYM(node->nd_mid)); break; default: CHECK(COMPILE(pref, "const colon2 prefix", node)); @@ -5838,9 +5422,9 @@ compile_cpath(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const NODE *cpath) ADD_INSN1(ret, cpath, putobject, rb_cObject); return VM_DEFINECLASS_FLAG_SCOPED; } - else if (nd_type_p(cpath, NODE_COLON2) && RNODE_COLON2(cpath)->nd_head) { + else if (cpath->nd_head) { /* Bar::Foo */ - NO_CHECK(COMPILE(ret, "nd_else->nd_head", RNODE_COLON2(cpath)->nd_head)); + NO_CHECK(COMPILE(ret, "nd_else->nd_head", cpath->nd_head)); return VM_DEFINECLASS_FLAG_SCOPED; } else { @@ -5854,16 +5438,16 @@ compile_cpath(LINK_ANCHOR *const ret, rb_iseq_t *iseq, const NODE *cpath) static inline int private_recv_p(const NODE *node) { - NODE *recv = get_nd_recv(node); - if (recv && nd_type_p(recv, NODE_SELF)) { - return RNODE_SELF(recv)->nd_state != 0; + if (nd_type_p(node->nd_recv, NODE_SELF)) { + NODE *self = node->nd_recv; + return self->nd_state != 0; } return 0; } static void defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, - const NODE *const node, LABEL **lfinish, VALUE needstr, bool ignore); + const NODE *const node, LABEL **lfinish, VALUE needstr); static int compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, const enum node_type type, const NODE *const line_node, int popped, bool assume_receiver); @@ -5894,34 +5478,21 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, expr_type = DEFINED_FALSE; break; - case NODE_HASH: case NODE_LIST:{ - const NODE *vals = (nd_type(node) == NODE_HASH) ? RNODE_HASH(node)->nd_head : node; + const NODE *vals = node; - if (vals) { - do { - if (RNODE_LIST(vals)->nd_head) { - defined_expr0(iseq, ret, RNODE_LIST(vals)->nd_head, lfinish, Qfalse, false); + do { + defined_expr0(iseq, ret, vals->nd_head, lfinish, Qfalse, false); - if (!lfinish[1]) { - lfinish[1] = NEW_LABEL(line); - } - ADD_INSNL(ret, line_node, branchunless, lfinish[1]); - } - } while ((vals = RNODE_LIST(vals)->nd_next) != NULL); - } + if (!lfinish[1]) { + lfinish[1] = NEW_LABEL(line); + } + ADD_INSNL(ret, line_node, branchunless, lfinish[1]); + } while ((vals = vals->nd_next) != NULL); } /* fall through */ case NODE_STR: - case NODE_SYM: - case NODE_REGX: - case NODE_LINE: - case NODE_FILE: - case NODE_ENCODING: - case NODE_INTEGER: - case NODE_FLOAT: - case NODE_RATIONAL: - case NODE_IMAGINARY: + case NODE_LIT: case NODE_ZLIST: case NODE_AND: case NODE_OR: @@ -5929,15 +5500,6 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, expr_type = DEFINED_EXPR; break; - case NODE_SPLAT: - defined_expr0(iseq, ret, RNODE_LIST(node)->nd_head, lfinish, Qfalse, false); - if (!lfinish[1]) { - lfinish[1] = NEW_LABEL(line); - } - ADD_INSNL(ret, line_node, branchunless, lfinish[1]); - expr_type = DEFINED_EXPR; - break; - /* variables */ case NODE_LVAR: case NODE_DVAR: @@ -5946,48 +5508,49 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, #define PUSH_VAL(type) (needstr == Qfalse ? Qtrue : rb_iseq_defined_string(type)) case NODE_IVAR: - ADD_INSN3(ret, line_node, definedivar, - ID2SYM(RNODE_IVAR(node)->nd_vid), get_ivar_ic_value(iseq,RNODE_IVAR(node)->nd_vid), PUSH_VAL(DEFINED_IVAR)); + ADD_INSN(ret, line_node, putnil); + ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_IVAR), + ID2SYM(node->nd_vid), PUSH_VAL(DEFINED_IVAR)); return; case NODE_GVAR: ADD_INSN(ret, line_node, putnil); ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_GVAR), - ID2SYM(RNODE_GVAR(node)->nd_vid), PUSH_VAL(DEFINED_GVAR)); + ID2SYM(node->nd_entry), PUSH_VAL(DEFINED_GVAR)); return; case NODE_CVAR: ADD_INSN(ret, line_node, putnil); ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_CVAR), - ID2SYM(RNODE_CVAR(node)->nd_vid), PUSH_VAL(DEFINED_CVAR)); + ID2SYM(node->nd_vid), PUSH_VAL(DEFINED_CVAR)); return; case NODE_CONST: ADD_INSN(ret, line_node, putnil); ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_CONST), - ID2SYM(RNODE_CONST(node)->nd_vid), PUSH_VAL(DEFINED_CONST)); + ID2SYM(node->nd_vid), PUSH_VAL(DEFINED_CONST)); return; case NODE_COLON2: if (!lfinish[1]) { lfinish[1] = NEW_LABEL(line); } - defined_expr0(iseq, ret, RNODE_COLON2(node)->nd_head, lfinish, Qfalse, false); + defined_expr0(iseq, ret, node->nd_head, lfinish, Qfalse, false); ADD_INSNL(ret, line_node, branchunless, lfinish[1]); - NO_CHECK(COMPILE(ret, "defined/colon2#nd_head", RNODE_COLON2(node)->nd_head)); + NO_CHECK(COMPILE(ret, "defined/colon2#nd_head", node->nd_head)); - if (rb_is_const_id(RNODE_COLON2(node)->nd_mid)) { + if (rb_is_const_id(node->nd_mid)) { ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_CONST_FROM), - ID2SYM(RNODE_COLON2(node)->nd_mid), PUSH_VAL(DEFINED_CONST)); + ID2SYM(node->nd_mid), PUSH_VAL(DEFINED_CONST)); } else { ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_METHOD), - ID2SYM(RNODE_COLON2(node)->nd_mid), PUSH_VAL(DEFINED_METHOD)); + ID2SYM(node->nd_mid), PUSH_VAL(DEFINED_METHOD)); } return; case NODE_COLON3: ADD_INSN1(ret, line_node, putobject, rb_cObject); ADD_INSN3(ret, line_node, defined, - INT2FIX(DEFINED_CONST_FROM), ID2SYM(RNODE_COLON3(node)->nd_mid), PUSH_VAL(DEFINED_CONST)); + INT2FIX(DEFINED_CONST_FROM), ID2SYM(node->nd_mid), PUSH_VAL(DEFINED_CONST)); return; /* method dispatch */ @@ -6000,7 +5563,7 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, (type == NODE_CALL || type == NODE_OPCALL || (type == NODE_ATTRASGN && !private_recv_p(node))); - if (get_nd_args(node) || explicit_receiver) { + if (node->nd_args || explicit_receiver) { if (!lfinish[1]) { lfinish[1] = NEW_LABEL(line); } @@ -6008,31 +5571,31 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, lfinish[2] = NEW_LABEL(line); } } - if (get_nd_args(node)) { - defined_expr0(iseq, ret, get_nd_args(node), lfinish, Qfalse, false); + if (node->nd_args) { + defined_expr0(iseq, ret, node->nd_args, lfinish, Qfalse, false); ADD_INSNL(ret, line_node, branchunless, lfinish[1]); } if (explicit_receiver) { - defined_expr0(iseq, ret, get_nd_recv(node), lfinish, Qfalse, true); - switch (nd_type(get_nd_recv(node))) { + defined_expr0(iseq, ret, node->nd_recv, lfinish, Qfalse, true); + switch (nd_type(node->nd_recv)) { case NODE_CALL: case NODE_OPCALL: case NODE_VCALL: case NODE_FCALL: case NODE_ATTRASGN: ADD_INSNL(ret, line_node, branchunless, lfinish[2]); - compile_call(iseq, ret, get_nd_recv(node), nd_type(get_nd_recv(node)), line_node, 0, true); + compile_call(iseq, ret, node->nd_recv, nd_type(node->nd_recv), line_node, 0, true); break; default: ADD_INSNL(ret, line_node, branchunless, lfinish[1]); - NO_CHECK(COMPILE(ret, "defined/recv", get_nd_recv(node))); + NO_CHECK(COMPILE(ret, "defined/recv", node->nd_recv)); break; } if (keep_result) { ADD_INSN(ret, line_node, dup); } ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_METHOD), - ID2SYM(get_node_call_nd_mid(node)), PUSH_VAL(DEFINED_METHOD)); + ID2SYM(node->nd_mid), PUSH_VAL(DEFINED_METHOD)); } else { ADD_INSN(ret, line_node, putself); @@ -6040,7 +5603,7 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, ADD_INSN(ret, line_node, dup); } ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_FUNC), - ID2SYM(get_node_call_nd_mid(node)), PUSH_VAL(DEFINED_METHOD)); + ID2SYM(node->nd_mid), PUSH_VAL(DEFINED_METHOD)); } return; } @@ -6049,14 +5612,13 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, ADD_INSN(ret, line_node, putnil); ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_YIELD), 0, PUSH_VAL(DEFINED_YIELD)); - iseq_set_use_block(ISEQ_BODY(iseq)->local_iseq); return; case NODE_BACK_REF: case NODE_NTH_REF: ADD_INSN(ret, line_node, putnil); ADD_INSN3(ret, line_node, defined, INT2FIX(DEFINED_REF), - INT2FIX((RNODE_BACK_REF(node)->nd_nth << 1) | (type == NODE_BACK_REF)), + INT2FIX((node->nd_nth << 1) | (type == NODE_BACK_REF)), PUSH_VAL(DEFINED_GVAR)); return; @@ -6079,12 +5641,11 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, case NODE_IASGN: case NODE_CDECL: case NODE_CVASGN: - case NODE_OP_CDECL: expr_type = DEFINED_ASGN; break; } - RUBY_ASSERT(expr_type != DEFINED_NOT_DEFINED); + assert(expr_type != DEFINED_NOT_DEFINED); if (needstr != Qfalse) { VALUE str = rb_iseq_defined_string(expr_type); @@ -6098,13 +5659,14 @@ defined_expr0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, static void build_defined_rescue_iseq(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const void *unused) { - ADD_SYNTHETIC_INSN(ret, 0, -1, putnil); + NODE dummy_line_node = generate_dummy_line_node(0, -1); + ADD_INSN(ret, &dummy_line_node, putnil); iseq_set_exception_local_table(iseq); } static void defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, - const NODE *const node, LABEL **lfinish, VALUE needstr, bool ignore) + const NODE *const node, LABEL **lfinish, VALUE needstr) { LINK_ELEMENT *lcur = ret->last; defined_expr0(iseq, ret, node, lfinish, needstr, false); @@ -6123,18 +5685,16 @@ defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, lend->rescued = LABEL_RESCUE_END; APPEND_LABEL(ret, lcur, lstart); ADD_LABEL(ret, lend); - if (!ignore) { - ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue, lfinish[1]); - } + ADD_CATCH_ENTRY(CATCH_TYPE_RESCUE, lstart, lend, rescue, lfinish[1]); } } static int -compile_defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, VALUE needstr, bool ignore) +compile_defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, VALUE needstr) { const int line = nd_line(node); const NODE *line_node = node; - if (!RNODE_DEFINED(node)->nd_head) { + if (!node->nd_head) { VALUE str = rb_iseq_defined_string(DEFINED_NIL); ADD_INSN1(ret, line_node, putobject, str); } @@ -6144,9 +5704,9 @@ compile_defined_expr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const lfinish[0] = NEW_LABEL(line); lfinish[1] = 0; lfinish[2] = 0; - defined_expr(iseq, ret, RNODE_DEFINED(node)->nd_head, lfinish, needstr, ignore); + defined_expr(iseq, ret, node->nd_head, lfinish, needstr); if (lfinish[1]) { - ELEM_INSERT_NEXT(last, &new_insn_body(iseq, nd_line(line_node), nd_node_id(line_node), BIN(putnil), 0)->link); + ELEM_INSERT_NEXT(last, &new_insn_body(iseq, line_node, BIN(putnil), 0)->link); ADD_INSN(ret, line_node, swap); if (lfinish[2]) { ADD_LABEL(ret, lfinish[2]); @@ -6185,7 +5745,7 @@ make_name_for_block(const rb_iseq_t *orig_iseq) static void push_ensure_entry(rb_iseq_t *iseq, struct iseq_compile_data_ensure_node_stack *enl, - struct ensure_range *er, const void *const node) + struct ensure_range *er, const NODE *const node) { enl->ensure_node = node; enl->prev = ISEQ_COMPILE_DATA(iseq)->ensure_node_stack; /* prev */ @@ -6227,7 +5787,7 @@ can_add_ensure_iseq(const rb_iseq_t *iseq) static void add_ensure_iseq(LINK_ANCHOR *const ret, rb_iseq_t *iseq, int is_return) { - RUBY_ASSERT(can_add_ensure_iseq(iseq)); + assert(can_add_ensure_iseq(iseq)); struct iseq_compile_data_ensure_node_stack *enlp = ISEQ_COMPILE_DATA(iseq)->ensure_node_stack; @@ -6261,205 +5821,79 @@ add_ensure_iseq(LINK_ANCHOR *const ret, rb_iseq_t *iseq, int is_return) ADD_SEQ(ret, ensure); } -#if RUBY_DEBUG static int check_keyword(const NODE *node) { /* This check is essentially a code clone of compile_keyword_arg. */ if (nd_type_p(node, NODE_LIST)) { - while (RNODE_LIST(node)->nd_next) { - node = RNODE_LIST(node)->nd_next; + while (node->nd_next) { + node = node->nd_next; } - node = RNODE_LIST(node)->nd_head; + node = node->nd_head; } return keyword_node_p(node); } -#endif -static bool -keyword_node_single_splat_p(NODE *kwnode) -{ - RUBY_ASSERT(keyword_node_p(kwnode)); - - NODE *node = RNODE_HASH(kwnode)->nd_head; - return RNODE_LIST(node)->nd_head == NULL && - RNODE_LIST(RNODE_LIST(node)->nd_next)->nd_next == NULL; -} - -static void -compile_single_keyword_splat_mutable(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn, - NODE *kwnode, unsigned int *flag_ptr) -{ - *flag_ptr |= VM_CALL_KW_SPLAT_MUT; - ADD_INSN1(args, argn, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); - ADD_INSN1(args, argn, newhash, INT2FIX(0)); - compile_hash(iseq, args, kwnode, TRUE, FALSE); - ADD_SEND(args, argn, id_core_hash_merge_kwd, INT2FIX(2)); -} - -#define SPLATARRAY_FALSE 0 -#define SPLATARRAY_TRUE 1 -#define DUP_SINGLE_KW_SPLAT 2 - -static int +static VALUE setup_args_core(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn, - unsigned int *dup_rest, unsigned int *flag_ptr, struct rb_callinfo_kwarg **kwarg_ptr) + int dup_rest, unsigned int *flag, struct rb_callinfo_kwarg **keywords) { - if (!argn) return 0; - - NODE *kwnode = NULL; - - switch (nd_type(argn)) { - case NODE_LIST: { - // f(x, y, z) - int len = compile_args(iseq, args, argn, &kwnode); - RUBY_ASSERT(flag_ptr == NULL || (*flag_ptr & VM_CALL_ARGS_SPLAT) == 0); - - if (kwnode) { - if (compile_keyword_arg(iseq, args, kwnode, kwarg_ptr, flag_ptr)) { - len -= 1; + if (argn) { + switch (nd_type(argn)) { + case NODE_SPLAT: { + NO_CHECK(COMPILE(args, "args (splat)", argn->nd_head)); + ADD_INSN1(args, argn, splatarray, RBOOL(dup_rest)); + if (flag) *flag |= VM_CALL_ARGS_SPLAT; + return INT2FIX(1); + } + case NODE_ARGSCAT: + case NODE_ARGSPUSH: { + int next_is_list = (nd_type_p(argn->nd_head, NODE_LIST)); + VALUE argc = setup_args_core(iseq, args, argn->nd_head, 1, NULL, NULL); + if (nd_type_p(argn->nd_body, NODE_LIST)) { + /* This branch is needed to avoid "newarraykwsplat" [Bug #16442] */ + int rest_len = compile_args(iseq, args, argn->nd_body, NULL, NULL); + ADD_INSN1(args, argn, newarray, INT2FIX(rest_len)); } else { - if (keyword_node_single_splat_p(kwnode) && (*dup_rest & DUP_SINGLE_KW_SPLAT)) { - compile_single_keyword_splat_mutable(iseq, args, argn, kwnode, flag_ptr); + NO_CHECK(COMPILE(args, "args (cat: splat)", argn->nd_body)); + } + if (flag) { + *flag |= VM_CALL_ARGS_SPLAT; + /* This is a dirty hack. It traverses the AST twice. + * In a long term, it should be fixed by a redesign of keyword arguments */ + if (check_keyword(argn->nd_body)) + *flag |= VM_CALL_KW_SPLAT; + } + if (nd_type_p(argn, NODE_ARGSCAT)) { + if (next_is_list) { + ADD_INSN1(args, argn, splatarray, Qtrue); + return INT2FIX(FIX2INT(argc) + 1); } else { - compile_hash(iseq, args, kwnode, TRUE, FALSE); + ADD_INSN1(args, argn, splatarray, Qfalse); + ADD_INSN(args, argn, concatarray); + return argc; } } - } - - return len; - } - case NODE_SPLAT: { - // f(*a) - NO_CHECK(COMPILE(args, "args (splat)", RNODE_SPLAT(argn)->nd_head)); - ADD_INSN1(args, argn, splatarray, RBOOL(*dup_rest & SPLATARRAY_TRUE)); - if (*dup_rest & SPLATARRAY_TRUE) *dup_rest &= ~SPLATARRAY_TRUE; - if (flag_ptr) *flag_ptr |= VM_CALL_ARGS_SPLAT; - RUBY_ASSERT(flag_ptr == NULL || (*flag_ptr & VM_CALL_KW_SPLAT) == 0); - return 1; - } - case NODE_ARGSCAT: { - if (flag_ptr) *flag_ptr |= VM_CALL_ARGS_SPLAT; - int argc = setup_args_core(iseq, args, RNODE_ARGSCAT(argn)->nd_head, dup_rest, NULL, NULL); - bool args_pushed = false; - - if (nd_type_p(RNODE_ARGSCAT(argn)->nd_body, NODE_LIST)) { - int rest_len = compile_args(iseq, args, RNODE_ARGSCAT(argn)->nd_body, &kwnode); - if (kwnode) rest_len--; - ADD_INSN1(args, argn, pushtoarray, INT2FIX(rest_len)); - args_pushed = true; - } - else { - RUBY_ASSERT(!check_keyword(RNODE_ARGSCAT(argn)->nd_body)); - NO_CHECK(COMPILE(args, "args (cat: splat)", RNODE_ARGSCAT(argn)->nd_body)); - } - - if (nd_type_p(RNODE_ARGSCAT(argn)->nd_head, NODE_LIST)) { - ADD_INSN1(args, argn, splatarray, RBOOL(*dup_rest & SPLATARRAY_TRUE)); - if (*dup_rest & SPLATARRAY_TRUE) *dup_rest &= ~SPLATARRAY_TRUE; - argc += 1; - } - else if (!args_pushed) { - ADD_INSN(args, argn, concattoarray); - } - - // f(..., *a, ..., k1:1, ...) #=> f(..., *[*a, ...], **{k1:1, ...}) - if (kwnode) { - // kwsplat - *flag_ptr |= VM_CALL_KW_SPLAT; - compile_hash(iseq, args, kwnode, TRUE, FALSE); - argc += 1; - } - - return argc; - } - case NODE_ARGSPUSH: { - if (flag_ptr) *flag_ptr |= VM_CALL_ARGS_SPLAT; - int argc = setup_args_core(iseq, args, RNODE_ARGSPUSH(argn)->nd_head, dup_rest, NULL, NULL); - - if (nd_type_p(RNODE_ARGSPUSH(argn)->nd_body, NODE_LIST)) { - int rest_len = compile_args(iseq, args, RNODE_ARGSPUSH(argn)->nd_body, &kwnode); - if (kwnode) rest_len--; - ADD_INSN1(args, argn, newarray, INT2FIX(rest_len)); - ADD_INSN1(args, argn, pushtoarray, INT2FIX(1)); - } - else { - if (keyword_node_p(RNODE_ARGSPUSH(argn)->nd_body)) { - kwnode = RNODE_ARGSPUSH(argn)->nd_body; - } else { - NO_CHECK(COMPILE(args, "args (cat: splat)", RNODE_ARGSPUSH(argn)->nd_body)); - ADD_INSN1(args, argn, pushtoarray, INT2FIX(1)); - } - } - - if (kwnode) { - // f(*a, k:1) - *flag_ptr |= VM_CALL_KW_SPLAT; - if (!keyword_node_single_splat_p(kwnode)) { - *flag_ptr |= VM_CALL_KW_SPLAT_MUT; - compile_hash(iseq, args, kwnode, TRUE, FALSE); - } - else if (*dup_rest & DUP_SINGLE_KW_SPLAT) { - compile_single_keyword_splat_mutable(iseq, args, argn, kwnode, flag_ptr); + ADD_INSN1(args, argn, newarray, INT2FIX(1)); + ADD_INSN(args, argn, concatarray); + return argc; } - else { - compile_hash(iseq, args, kwnode, TRUE, FALSE); - } - argc += 1; + } + case NODE_LIST: { + int len = compile_args(iseq, args, argn, keywords, flag); + return INT2FIX(len); + } + default: { + UNKNOWN_NODE("setup_arg", argn, Qnil); + } } - - return argc; - } - default: { - UNKNOWN_NODE("setup_arg", argn, Qnil); - } - } -} - -static void -setup_args_splat_mut(unsigned int *flag, int dup_rest, int initial_dup_rest) -{ - if ((*flag & VM_CALL_ARGS_SPLAT) && dup_rest != initial_dup_rest) { - *flag |= VM_CALL_ARGS_SPLAT_MUT; - } -} - -static bool -setup_args_dup_rest_p(const NODE *argn) -{ - switch(nd_type(argn)) { - case NODE_LVAR: - case NODE_DVAR: - case NODE_GVAR: - case NODE_IVAR: - case NODE_CVAR: - case NODE_CONST: - case NODE_COLON3: - case NODE_INTEGER: - case NODE_FLOAT: - case NODE_RATIONAL: - case NODE_IMAGINARY: - case NODE_STR: - case NODE_SYM: - case NODE_REGX: - case NODE_SELF: - case NODE_NIL: - case NODE_TRUE: - case NODE_FALSE: - case NODE_LAMBDA: - case NODE_NTH_REF: - case NODE_BACK_REF: - return false; - case NODE_COLON2: - return setup_args_dup_rest_p(RNODE_COLON2(argn)->nd_head); - default: - return true; } + return INT2FIX(0); } static VALUE @@ -6467,94 +5901,13 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn, unsigned int *flag, struct rb_callinfo_kwarg **keywords) { VALUE ret; - unsigned int dup_rest = SPLATARRAY_TRUE, initial_dup_rest; - - if (argn) { - const NODE *check_arg = nd_type_p(argn, NODE_BLOCK_PASS) ? - RNODE_BLOCK_PASS(argn)->nd_head : argn; - - if (check_arg) { - switch(nd_type(check_arg)) { - case(NODE_SPLAT): - // avoid caller side array allocation for f(*arg) - dup_rest = SPLATARRAY_FALSE; - break; - case(NODE_ARGSCAT): - // avoid caller side array allocation for f(1, *arg) - dup_rest = !nd_type_p(RNODE_ARGSCAT(check_arg)->nd_head, NODE_LIST); - break; - case(NODE_ARGSPUSH): - // avoid caller side array allocation for f(*arg, **hash) and f(1, *arg, **hash) - dup_rest = !((nd_type_p(RNODE_ARGSPUSH(check_arg)->nd_head, NODE_SPLAT) || - (nd_type_p(RNODE_ARGSPUSH(check_arg)->nd_head, NODE_ARGSCAT) && - nd_type_p(RNODE_ARGSCAT(RNODE_ARGSPUSH(check_arg)->nd_head)->nd_head, NODE_LIST))) && - nd_type_p(RNODE_ARGSPUSH(check_arg)->nd_body, NODE_HASH) && - !RNODE_HASH(RNODE_ARGSPUSH(check_arg)->nd_body)->nd_brace); - - if (dup_rest == SPLATARRAY_FALSE) { - // require allocation for keyword key/value/splat that may modify splatted argument - NODE *node = RNODE_HASH(RNODE_ARGSPUSH(check_arg)->nd_body)->nd_head; - while (node) { - NODE *key_node = RNODE_LIST(node)->nd_head; - if (key_node && setup_args_dup_rest_p(key_node)) { - dup_rest = SPLATARRAY_TRUE; - break; - } - - node = RNODE_LIST(node)->nd_next; - NODE *value_node = RNODE_LIST(node)->nd_head; - if (setup_args_dup_rest_p(value_node)) { - dup_rest = SPLATARRAY_TRUE; - break; - } - - node = RNODE_LIST(node)->nd_next; - } - } - break; - default: - break; - } - } - - if (check_arg != argn && setup_args_dup_rest_p(RNODE_BLOCK_PASS(argn)->nd_body)) { - // for block pass that may modify splatted argument, dup rest and kwrest if given - dup_rest = SPLATARRAY_TRUE | DUP_SINGLE_KW_SPLAT; - } - } - initial_dup_rest = dup_rest; - if (argn && nd_type_p(argn, NODE_BLOCK_PASS)) { + unsigned int dup_rest = 1; DECL_ANCHOR(arg_block); INIT_ANCHOR(arg_block); + NO_CHECK(COMPILE(arg_block, "block", argn->nd_body)); - if (RNODE_BLOCK_PASS(argn)->forwarding && ISEQ_BODY(ISEQ_BODY(iseq)->local_iseq)->param.flags.forwardable) { - int idx = ISEQ_BODY(ISEQ_BODY(iseq)->local_iseq)->local_table_size;// - get_local_var_idx(iseq, idDot3); - - RUBY_ASSERT(nd_type_p(RNODE_BLOCK_PASS(argn)->nd_head, NODE_ARGSPUSH)); - const NODE * arg_node = - RNODE_ARGSPUSH(RNODE_BLOCK_PASS(argn)->nd_head)->nd_head; - - int argc = 0; - - // Only compile leading args: - // foo(x, y, ...) - // ^^^^ - if (nd_type_p(arg_node, NODE_ARGSCAT)) { - argc += setup_args_core(iseq, args, RNODE_ARGSCAT(arg_node)->nd_head, &dup_rest, flag, keywords); - } - - *flag |= VM_CALL_FORWARDING; - - ADD_GETLOCAL(args, argn, idx, get_lvar_level(iseq)); - setup_args_splat_mut(flag, dup_rest, initial_dup_rest); - return INT2FIX(argc); - } - else { - *flag |= VM_CALL_ARGS_BLOCKARG; - - NO_CHECK(COMPILE(arg_block, "block", RNODE_BLOCK_PASS(argn)->nd_body)); - } + *flag |= VM_CALL_ARGS_BLOCKARG; if (LIST_INSN_SIZE_ONE(arg_block)) { LINK_ELEMENT *elem = FIRST_ELEMENT(arg_block); @@ -6563,15 +5916,15 @@ setup_args(rb_iseq_t *iseq, LINK_ANCHOR *const args, const NODE *argn, if (iobj->insn_id == BIN(getblockparam)) { iobj->insn_id = BIN(getblockparamproxy); } + dup_rest = 0; } } - ret = INT2FIX(setup_args_core(iseq, args, RNODE_BLOCK_PASS(argn)->nd_head, &dup_rest, flag, keywords)); + ret = setup_args_core(iseq, args, argn->nd_head, dup_rest, flag, keywords); ADD_SEQ(args, arg_block); } else { - ret = INT2FIX(setup_args_core(iseq, args, argn, &dup_rest, flag, keywords)); + ret = setup_args_core(iseq, args, argn, 0, flag, keywords); } - setup_args_splat_mut(flag, dup_rest, initial_dup_rest); return ret; } @@ -6586,7 +5939,7 @@ build_postexe_iseq(rb_iseq_t *iseq, LINK_ANCHOR *ret, const void *ptr) ADD_INSN1(ret, body, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); ADD_CALL_WITH_BLOCK(ret, body, id_core_set_postexe, argc, block); RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)block); - iseq_set_local_table(iseq, 0, 0); + iseq_set_local_table(iseq, 0); } static void @@ -6606,19 +5959,19 @@ compile_named_capture_assign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE ADD_INSN(ret, line_node, dup); ADD_INSNL(ret, line_node, branchunless, fail_label); - for (vars = node; vars; vars = RNODE_BLOCK(vars)->nd_next) { + for (vars = node; vars; vars = vars->nd_next) { INSN *cap; - if (RNODE_BLOCK(vars)->nd_next) { + if (vars->nd_next) { ADD_INSN(ret, line_node, dup); } last = ret->last; - NO_CHECK(COMPILE_POPPED(ret, "capture", RNODE_BLOCK(vars)->nd_head)); + NO_CHECK(COMPILE_POPPED(ret, "capture", vars->nd_head)); last = last->next; /* putobject :var */ - cap = new_insn_send(iseq, nd_line(line_node), nd_node_id(line_node), idAREF, INT2FIX(1), + cap = new_insn_send(iseq, line_node, idAREF, INT2FIX(1), NULL, INT2FIX(0), NULL); ELEM_INSERT_PREV(last->next, (LINK_ELEMENT *)cap); #if !defined(NAMED_CAPTURE_SINGLE_OPT) || NAMED_CAPTURE_SINGLE_OPT-0 - if (!RNODE_BLOCK(vars)->nd_next && vars == node) { + if (!vars->nd_next && vars == node) { /* only one name */ DECL_ANCHOR(nom); @@ -6639,9 +5992,9 @@ compile_named_capture_assign(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE ADD_INSNL(ret, line_node, jump, end_label); ADD_LABEL(ret, fail_label); ADD_INSN(ret, line_node, pop); - for (vars = node; vars; vars = RNODE_BLOCK(vars)->nd_next) { + for (vars = node; vars; vars = vars->nd_next) { last = ret->last; - NO_CHECK(COMPILE_POPPED(ret, "capture", RNODE_BLOCK(vars)->nd_head)); + NO_CHECK(COMPILE_POPPED(ret, "capture", vars->nd_head)); last = last->next; /* putobject :var */ ((INSN*)last)->insn_id = BIN(putnil); ((INSN*)last)->operand_size = 0; @@ -6654,10 +6007,8 @@ optimizable_range_item_p(const NODE *n) { if (!n) return FALSE; switch (nd_type(n)) { - case NODE_LINE: - return TRUE; - case NODE_INTEGER: - return TRUE; + case NODE_LIT: + return RB_INTEGER_TYPE_P(n->nd_lit); case NODE_NIL: return TRUE; default: @@ -6665,70 +6016,69 @@ optimizable_range_item_p(const NODE *n) } } -static VALUE -optimized_range_item(const NODE *n) -{ - switch (nd_type(n)) { - case NODE_LINE: - return rb_node_line_lineno_val(n); - case NODE_INTEGER: - return rb_node_integer_literal_val(n); - case NODE_FLOAT: - return rb_node_float_literal_val(n); - case NODE_RATIONAL: - return rb_node_rational_literal_val(n); - case NODE_IMAGINARY: - return rb_node_imaginary_literal_val(n); - case NODE_NIL: - return Qnil; - default: - rb_bug("unexpected node: %s", ruby_node_name(nd_type(n))); - } -} - static int compile_if(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped, const enum node_type type) { - const NODE *const node_body = type == NODE_IF ? RNODE_IF(node)->nd_body : RNODE_UNLESS(node)->nd_else; - const NODE *const node_else = type == NODE_IF ? RNODE_IF(node)->nd_else : RNODE_UNLESS(node)->nd_body; + struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq); + const NODE *const node_body = type == NODE_IF ? node->nd_body : node->nd_else; + const NODE *const node_else = type == NODE_IF ? node->nd_else : node->nd_body; const int line = nd_line(node); const NODE *line_node = node; DECL_ANCHOR(cond_seq); + DECL_ANCHOR(then_seq); + DECL_ANCHOR(else_seq); LABEL *then_label, *else_label, *end_label; VALUE branches = Qfalse; + int ci_size; + VALUE catch_table = ISEQ_COMPILE_DATA(iseq)->catch_table_ary; + long catch_table_size = NIL_P(catch_table) ? 0 : RARRAY_LEN(catch_table); INIT_ANCHOR(cond_seq); + INIT_ANCHOR(then_seq); + INIT_ANCHOR(else_seq); then_label = NEW_LABEL(line); else_label = NEW_LABEL(line); end_label = 0; - NODE *cond = RNODE_IF(node)->nd_cond; - if (nd_type(cond) == NODE_BLOCK) { - cond = RNODE_BLOCK(cond)->nd_head; + compile_branch_condition(iseq, cond_seq, node->nd_cond, + then_label, else_label); + + ci_size = body->ci_size; + CHECK(COMPILE_(then_seq, "then", node_body, popped)); + catch_table = ISEQ_COMPILE_DATA(iseq)->catch_table_ary; + if (!then_label->refcnt) { + body->ci_size = ci_size; + if (!NIL_P(catch_table)) rb_ary_set_len(catch_table, catch_table_size); + } + else { + if (!NIL_P(catch_table)) catch_table_size = RARRAY_LEN(catch_table); + } + + ci_size = body->ci_size; + CHECK(COMPILE_(else_seq, "else", node_else, popped)); + catch_table = ISEQ_COMPILE_DATA(iseq)->catch_table_ary; + if (!else_label->refcnt) { + body->ci_size = ci_size; + if (!NIL_P(catch_table)) rb_ary_set_len(catch_table, catch_table_size); + } + else { + if (!NIL_P(catch_table)) catch_table_size = RARRAY_LEN(catch_table); } - CHECK(compile_branch_condition(iseq, cond_seq, cond, then_label, else_label)); ADD_SEQ(ret, cond_seq); if (then_label->refcnt && else_label->refcnt) { - branches = decl_branch_base(iseq, PTR2NUM(node), nd_code_loc(node), type == NODE_IF ? "if" : "unless"); + branches = decl_branch_base(iseq, node, type == NODE_IF ? "if" : "unless"); } if (then_label->refcnt) { ADD_LABEL(ret, then_label); - - DECL_ANCHOR(then_seq); - INIT_ANCHOR(then_seq); - CHECK(COMPILE_(then_seq, "then", node_body, popped)); - if (else_label->refcnt) { - const NODE *const coverage_node = node_body ? node_body : node; add_trace_branch_coverage( iseq, ret, - nd_code_loc(coverage_node), - nd_node_id(coverage_node), + node_body ? node_body : node, 0, type == NODE_IF ? "then" : "else", branches); @@ -6743,18 +6093,11 @@ compile_if(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int if (else_label->refcnt) { ADD_LABEL(ret, else_label); - - DECL_ANCHOR(else_seq); - INIT_ANCHOR(else_seq); - CHECK(COMPILE_(else_seq, "else", node_else, popped)); - if (then_label->refcnt) { - const NODE *const coverage_node = node_else ? node_else : node; add_trace_branch_coverage( iseq, ret, - nd_code_loc(coverage_node), - nd_node_id(coverage_node), + node_else ? node_else : node, 1, type == NODE_IF ? "else" : "then", branches); @@ -6792,11 +6135,11 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_nod RHASH_TBL_RAW(literals)->type = &cdhash_type; - CHECK(COMPILE(head, "case base", RNODE_CASE(node)->nd_head)); + CHECK(COMPILE(head, "case base", node->nd_head)); - branches = decl_branch_base(iseq, PTR2NUM(node), nd_code_loc(node), "case"); + branches = decl_branch_base(iseq, node, "case"); - node = RNODE_CASE(node)->nd_body; + node = node->nd_body; EXPECT_NODE("NODE_CASE", node, NODE_WHEN, COMPILE_NG); type = nd_type(node); line = nd_line(node); @@ -6813,21 +6156,17 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_nod l1 = NEW_LABEL(line); ADD_LABEL(body_seq, l1); ADD_INSN(body_seq, line_node, pop); - - const NODE *const coverage_node = RNODE_WHEN(node)->nd_body ? RNODE_WHEN(node)->nd_body : node; add_trace_branch_coverage( iseq, body_seq, - nd_code_loc(coverage_node), - nd_node_id(coverage_node), + node->nd_body ? node->nd_body : node, branch_id++, "when", branches); - - CHECK(COMPILE_(body_seq, "when body", RNODE_WHEN(node)->nd_body, popped)); + CHECK(COMPILE_(body_seq, "when body", node->nd_body, popped)); ADD_INSNL(body_seq, line_node, jump, endlabel); - vals = RNODE_WHEN(node)->nd_head; + vals = node->nd_head; if (vals) { switch (nd_type(vals)) { case NODE_LIST: @@ -6848,7 +6187,7 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_nod EXPECT_NODE_NONULL("NODE_CASE", node, NODE_LIST, COMPILE_NG); } - node = RNODE_WHEN(node)->nd_next; + node = node->nd_next; if (!node) { break; } @@ -6860,7 +6199,7 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_nod if (node) { ADD_LABEL(cond_seq, elselabel); ADD_INSN(cond_seq, line_node, pop); - add_trace_branch_coverage(iseq, cond_seq, nd_code_loc(node), nd_node_id(node), branch_id, "else", branches); + add_trace_branch_coverage(iseq, cond_seq, node, branch_id, "else", branches); CHECK(COMPILE_(cond_seq, "else", node, popped)); ADD_INSNL(cond_seq, line_node, jump, endlabel); } @@ -6868,7 +6207,7 @@ compile_case(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_nod debugs("== else (implicit)\n"); ADD_LABEL(cond_seq, elselabel); ADD_INSN(cond_seq, orig_node, pop); - add_trace_branch_coverage(iseq, cond_seq, nd_code_loc(orig_node), nd_node_id(orig_node), branch_id, "else", branches); + add_trace_branch_coverage(iseq, cond_seq, orig_node, branch_id, "else", branches); if (!popped) { ADD_INSN(cond_seq, orig_node, putnil); } @@ -6893,13 +6232,13 @@ compile_case2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no { const NODE *vals; const NODE *val; - const NODE *node = RNODE_CASE2(orig_node)->nd_body; + const NODE *node = orig_node->nd_body; LABEL *endlabel; DECL_ANCHOR(body_seq); VALUE branches = Qfalse; int branch_id = 0; - branches = decl_branch_base(iseq, PTR2NUM(orig_node), nd_code_loc(orig_node), "case"); + branches = decl_branch_base(iseq, orig_node, "case"); INIT_ANCHOR(body_seq); endlabel = NEW_LABEL(nd_line(node)); @@ -6908,21 +6247,17 @@ compile_case2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no const int line = nd_line(node); LABEL *l1 = NEW_LABEL(line); ADD_LABEL(body_seq, l1); - - const NODE *const coverage_node = RNODE_WHEN(node)->nd_body ? RNODE_WHEN(node)->nd_body : node; add_trace_branch_coverage( iseq, body_seq, - nd_code_loc(coverage_node), - nd_node_id(coverage_node), + node->nd_body ? node->nd_body : node, branch_id++, "when", branches); - - CHECK(COMPILE_(body_seq, "when", RNODE_WHEN(node)->nd_body, popped)); + CHECK(COMPILE_(body_seq, "when", node->nd_body, popped)); ADD_INSNL(body_seq, node, jump, endlabel); - vals = RNODE_WHEN(node)->nd_head; + vals = node->nd_head; if (!vals) { EXPECT_NODE_NONULL("NODE_WHEN", node, NODE_LIST, COMPILE_NG); } @@ -6930,12 +6265,12 @@ compile_case2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no case NODE_LIST: while (vals) { LABEL *lnext; - val = RNODE_LIST(vals)->nd_head; + val = vals->nd_head; lnext = NEW_LABEL(nd_line(val)); debug_compile("== when2\n", (void)0); CHECK(compile_branch_condition(iseq, ret, val, l1, lnext)); ADD_LABEL(ret, lnext); - vals = RNODE_LIST(vals)->nd_next; + vals = vals->nd_next; } break; case NODE_SPLAT: @@ -6949,15 +6284,13 @@ compile_case2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no default: UNKNOWN_NODE("NODE_WHEN", vals, COMPILE_NG); } - node = RNODE_WHEN(node)->nd_next; + node = node->nd_next; } /* else */ - const NODE *const coverage_node = node ? node : orig_node; add_trace_branch_coverage( iseq, ret, - nd_code_loc(coverage_node), - nd_node_id(coverage_node), + node ? node : orig_node, branch_id, "else", branches); @@ -7043,13 +6376,14 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c * match_failed: * goto unmatched */ - const NODE *args = RNODE_ARYPTN(node)->pre_args; - const int pre_args_num = RNODE_ARYPTN(node)->pre_args ? rb_long2int(RNODE_LIST(RNODE_ARYPTN(node)->pre_args)->as.nd_alen) : 0; - const int post_args_num = RNODE_ARYPTN(node)->post_args ? rb_long2int(RNODE_LIST(RNODE_ARYPTN(node)->post_args)->as.nd_alen) : 0; + struct rb_ary_pattern_info *apinfo = node->nd_apinfo; + const NODE *args = apinfo->pre_args; + const int pre_args_num = apinfo->pre_args ? rb_long2int(apinfo->pre_args->nd_alen) : 0; + const int post_args_num = apinfo->post_args ? rb_long2int(apinfo->post_args->nd_alen) : 0; const int min_argc = pre_args_num + post_args_num; - const int use_rest_num = RNODE_ARYPTN(node)->rest_arg && (NODE_NAMED_REST_P(RNODE_ARYPTN(node)->rest_arg) || - (!NODE_NAMED_REST_P(RNODE_ARYPTN(node)->rest_arg) && post_args_num > 0)); + const int use_rest_num = apinfo->rest_arg && (NODE_NAMED_REST_P(apinfo->rest_arg) || + (!NODE_NAMED_REST_P(apinfo->rest_arg) && post_args_num > 0)); LABEL *match_failed, *type_error, *deconstruct, *deconstructed; int i; @@ -7073,10 +6407,10 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c ADD_INSN(ret, line_node, dup); ADD_SEND(ret, line_node, idLength, INT2FIX(0)); ADD_INSN1(ret, line_node, putobject, INT2FIX(min_argc)); - ADD_SEND(ret, line_node, RNODE_ARYPTN(node)->rest_arg ? idGE : idEq, INT2FIX(1)); // (1) + ADD_SEND(ret, line_node, apinfo->rest_arg ? idGE : idEq, INT2FIX(1)); // (1) if (in_single_pattern) { CHECK(iseq_compile_pattern_set_length_errmsg(iseq, ret, node, - RNODE_ARYPTN(node)->rest_arg ? rb_fstring_lit("%p length mismatch (given %p, expected %p+)") : + apinfo->rest_arg ? rb_fstring_lit("%p length mismatch (given %p, expected %p+)") : rb_fstring_lit("%p length mismatch (given %p, expected %p)"), INT2FIX(min_argc), base_index + 1 /* (1) */)); } @@ -7086,12 +6420,12 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c ADD_INSN(ret, line_node, dup); ADD_INSN1(ret, line_node, putobject, INT2FIX(i)); ADD_SEND(ret, line_node, idAREF, INT2FIX(1)); // (2) - CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_LIST(args)->nd_head, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (2) */, false)); - args = RNODE_LIST(args)->nd_next; + CHECK(iseq_compile_pattern_match(iseq, ret, args->nd_head, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (2) */, false)); + args = args->nd_next; } - if (RNODE_ARYPTN(node)->rest_arg) { - if (NODE_NAMED_REST_P(RNODE_ARYPTN(node)->rest_arg)) { + if (apinfo->rest_arg) { + if (NODE_NAMED_REST_P(apinfo->rest_arg)) { ADD_INSN(ret, line_node, dup); ADD_INSN1(ret, line_node, putobject, INT2FIX(pre_args_num)); ADD_INSN1(ret, line_node, topn, INT2FIX(1)); @@ -7101,7 +6435,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c ADD_INSN1(ret, line_node, setn, INT2FIX(4)); ADD_SEND(ret, line_node, idAREF, INT2FIX(2)); // (3) - CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_ARYPTN(node)->rest_arg, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (3) */, false)); + CHECK(iseq_compile_pattern_match(iseq, ret, apinfo->rest_arg, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (3) */, false)); } else { if (post_args_num > 0) { @@ -7115,7 +6449,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c } } - args = RNODE_ARYPTN(node)->post_args; + args = apinfo->post_args; for (i = 0; i < post_args_num; i++) { ADD_INSN(ret, line_node, dup); @@ -7124,8 +6458,8 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c ADD_SEND(ret, line_node, idPLUS, INT2FIX(1)); ADD_SEND(ret, line_node, idAREF, INT2FIX(1)); // (4) - CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_LIST(args)->nd_head, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (4) */, false)); - args = RNODE_LIST(args)->nd_next; + CHECK(iseq_compile_pattern_match(iseq, ret, args->nd_head, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (4) */, false)); + args = args->nd_next; } ADD_INSN(ret, line_node, pop); @@ -7203,8 +6537,9 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c * match_failed: * goto unmatched */ - const NODE *args = RNODE_FNDPTN(node)->args; - const int args_num = RNODE_FNDPTN(node)->args ? rb_long2int(RNODE_LIST(RNODE_FNDPTN(node)->args)->as.nd_alen) : 0; + struct rb_fnd_pattern_info *fpinfo = node->nd_fpinfo; + const NODE *args = fpinfo->args; + const int args_num = fpinfo->args ? rb_long2int(fpinfo->args->nd_alen) : 0; LABEL *match_failed, *type_error, *deconstruct, *deconstructed; match_failed = NEW_LABEL(line); @@ -7257,25 +6592,25 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c } ADD_SEND(ret, line_node, idAREF, INT2FIX(1)); // (5) - CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_LIST(args)->nd_head, next_loop, in_single_pattern, in_alt_pattern, base_index + 4 /* (2), (3), (4), (5) */, false)); - args = RNODE_LIST(args)->nd_next; + CHECK(iseq_compile_pattern_match(iseq, ret, args->nd_head, next_loop, in_single_pattern, in_alt_pattern, base_index + 4 /* (2), (3), (4), (5) */, false)); + args = args->nd_next; } - if (NODE_NAMED_REST_P(RNODE_FNDPTN(node)->pre_rest_arg)) { + if (NODE_NAMED_REST_P(fpinfo->pre_rest_arg)) { ADD_INSN1(ret, line_node, topn, INT2FIX(3)); ADD_INSN1(ret, line_node, putobject, INT2FIX(0)); ADD_INSN1(ret, line_node, topn, INT2FIX(2)); ADD_SEND(ret, line_node, idAREF, INT2FIX(2)); // (6) - CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_FNDPTN(node)->pre_rest_arg, find_failed, in_single_pattern, in_alt_pattern, base_index + 4 /* (2), (3), (4), (6) */, false)); + CHECK(iseq_compile_pattern_match(iseq, ret, fpinfo->pre_rest_arg, find_failed, in_single_pattern, in_alt_pattern, base_index + 4 /* (2), (3), (4), (6) */, false)); } - if (NODE_NAMED_REST_P(RNODE_FNDPTN(node)->post_rest_arg)) { + if (NODE_NAMED_REST_P(fpinfo->post_rest_arg)) { ADD_INSN1(ret, line_node, topn, INT2FIX(3)); ADD_INSN1(ret, line_node, topn, INT2FIX(1)); ADD_INSN1(ret, line_node, putobject, INT2FIX(args_num)); ADD_SEND(ret, line_node, idPLUS, INT2FIX(1)); ADD_INSN1(ret, line_node, topn, INT2FIX(3)); ADD_SEND(ret, line_node, idAREF, INT2FIX(2)); // (7) - CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_FNDPTN(node)->post_rest_arg, find_failed, in_single_pattern, in_alt_pattern, base_index + 4 /* (2), (3),(4), (7) */, false)); + CHECK(iseq_compile_pattern_match(iseq, ret, fpinfo->post_rest_arg, find_failed, in_single_pattern, in_alt_pattern, base_index + 4 /* (2), (3),(4), (7) */, false)); } ADD_INSNL(ret, line_node, jump, find_succeeded); @@ -7389,12 +6724,12 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c match_failed = NEW_LABEL(line); type_error = NEW_LABEL(line); - if (RNODE_HSHPTN(node)->nd_pkwargs && !RNODE_HSHPTN(node)->nd_pkwrestarg) { - const NODE *kw_args = RNODE_HASH(RNODE_HSHPTN(node)->nd_pkwargs)->nd_head; - keys = rb_ary_new_capa(kw_args ? RNODE_LIST(kw_args)->as.nd_alen/2 : 0); + if (node->nd_pkwargs && !node->nd_pkwrestarg) { + const NODE *kw_args = node->nd_pkwargs->nd_head; + keys = rb_ary_new_capa(kw_args ? kw_args->nd_alen/2 : 0); while (kw_args) { - rb_ary_push(keys, get_symbol_value(iseq, RNODE_LIST(kw_args)->nd_head)); - kw_args = RNODE_LIST(RNODE_LIST(kw_args)->nd_next)->nd_next; + rb_ary_push(keys, kw_args->nd_head->nd_lit); + kw_args = kw_args->nd_next->nd_next; } } @@ -7421,23 +6756,28 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c ADD_INSN1(ret, line_node, checktype, INT2FIX(T_HASH)); ADD_INSNL(ret, line_node, branchunless, type_error); - if (RNODE_HSHPTN(node)->nd_pkwrestarg) { + if (node->nd_pkwrestarg) { ADD_SEND(ret, line_node, rb_intern("dup"), INT2FIX(0)); } - if (RNODE_HSHPTN(node)->nd_pkwargs) { + if (node->nd_pkwargs) { int i; int keys_num; const NODE *args; - args = RNODE_HASH(RNODE_HSHPTN(node)->nd_pkwargs)->nd_head; + args = node->nd_pkwargs->nd_head; if (args) { DECL_ANCHOR(match_values); INIT_ANCHOR(match_values); - keys_num = rb_long2int(RNODE_LIST(args)->as.nd_alen) / 2; + keys_num = rb_long2int(args->nd_alen) / 2; for (i = 0; i < keys_num; i++) { - NODE *key_node = RNODE_LIST(args)->nd_head; - NODE *value_node = RNODE_LIST(RNODE_LIST(args)->nd_next)->nd_head; - VALUE key = get_symbol_value(iseq, key_node); + NODE *key_node = args->nd_head; + NODE *value_node = args->nd_next->nd_head; + VALUE key; + + if (!nd_type_p(key_node, NODE_LIT)) { + UNKNOWN_NODE("NODE_IN", key_node, COMPILE_NG); + } + key = key_node->nd_lit; ADD_INSN(ret, line_node, dup); ADD_INSN1(ret, line_node, putobject, key); @@ -7466,9 +6806,9 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c ADD_INSN(match_values, line_node, dup); ADD_INSN1(match_values, line_node, putobject, key); - ADD_SEND(match_values, line_node, RNODE_HSHPTN(node)->nd_pkwrestarg ? rb_intern("delete") : idAREF, INT2FIX(1)); // (8) + ADD_SEND(match_values, line_node, node->nd_pkwrestarg ? rb_intern("delete") : idAREF, INT2FIX(1)); // (8) CHECK(iseq_compile_pattern_match(iseq, match_values, value_node, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (8) */, false)); - args = RNODE_LIST(RNODE_LIST(args)->nd_next)->nd_next; + args = args->nd_next->nd_next; } ADD_SEQ(ret, match_values); } @@ -7482,8 +6822,8 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c ADD_INSNL(ret, line_node, branchunless, match_failed); } - if (RNODE_HSHPTN(node)->nd_pkwrestarg) { - if (RNODE_HSHPTN(node)->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD) { + if (node->nd_pkwrestarg) { + if (node->nd_pkwrestarg == NODE_SPECIAL_NO_REST_KEYWORD) { ADD_INSN(ret, line_node, dup); ADD_SEND(ret, line_node, idEmptyP, INT2FIX(0)); // (10) if (in_single_pattern) { @@ -7493,7 +6833,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c } else { ADD_INSN(ret, line_node, dup); // (11) - CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_HSHPTN(node)->nd_pkwrestarg, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (11) */, false)); + CHECK(iseq_compile_pattern_match(iseq, ret, node->nd_pkwrestarg, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (11) */, false)); } } @@ -7513,15 +6853,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c ADD_INSNL(ret, line_node, jump, unmatched); break; } - case NODE_SYM: - case NODE_REGX: - case NODE_LINE: - case NODE_INTEGER: - case NODE_FLOAT: - case NODE_RATIONAL: - case NODE_IMAGINARY: - case NODE_FILE: - case NODE_ENCODING: + case NODE_LIT: case NODE_STR: case NODE_XSTR: case NODE_DSTR: @@ -7545,8 +6877,6 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c case NODE_COLON2: case NODE_COLON3: case NODE_BEGIN: - case NODE_BLOCK: - case NODE_ONCE: CHECK(COMPILE(ret, "case in literal", node)); // (1) if (in_single_pattern) { ADD_INSN1(ret, line_node, dupn, INT2FIX(2)); @@ -7560,7 +6890,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c break; case NODE_LASGN: { struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq); - ID id = RNODE_LASGN(node)->nd_vid; + ID id = node->nd_vid; int idx = ISEQ_BODY(body->local_iseq)->local_table_size - get_local_var_idx(iseq, id); if (in_alt_pattern) { @@ -7578,7 +6908,7 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c } case NODE_DASGN: { int idx, lv, ls; - ID id = RNODE_DASGN(node)->nd_vid; + ID id = node->nd_vid; idx = get_dyna_var_idx(iseq, id, &lv, &ls); @@ -7604,8 +6934,8 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c case NODE_UNLESS: { LABEL *match_failed; match_failed = unmatched; - CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_IF(node)->nd_body, unmatched, in_single_pattern, in_alt_pattern, base_index, use_deconstructed_cache)); - CHECK(COMPILE(ret, "case in if", RNODE_IF(node)->nd_cond)); + CHECK(iseq_compile_pattern_match(iseq, ret, node->nd_body, unmatched, in_single_pattern, in_alt_pattern, base_index, use_deconstructed_cache)); + CHECK(COMPILE(ret, "case in if", node->nd_cond)); if (in_single_pattern) { LABEL *match_succeeded; match_succeeded = NEW_LABEL(line); @@ -7642,15 +6972,15 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c LABEL *match_failed; match_failed = NEW_LABEL(line); - n = RNODE_HASH(node)->nd_head; - if (! (nd_type_p(n, NODE_LIST) && RNODE_LIST(n)->as.nd_alen == 2)) { + n = node->nd_head; + if (! (nd_type_p(n, NODE_LIST) && n->nd_alen == 2)) { COMPILE_ERROR(ERROR_ARGS "unexpected node"); return COMPILE_NG; } ADD_INSN(ret, line_node, dup); // (1) - CHECK(iseq_compile_pattern_match(iseq, ret, RNODE_LIST(n)->nd_head, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (1) */, use_deconstructed_cache)); - CHECK(iseq_compile_pattern_each(iseq, ret, RNODE_LIST(RNODE_LIST(n)->nd_next)->nd_head, matched, match_failed, in_single_pattern, in_alt_pattern, base_index, false)); + CHECK(iseq_compile_pattern_match(iseq, ret, n->nd_head, match_failed, in_single_pattern, in_alt_pattern, base_index + 1 /* (1) */, use_deconstructed_cache)); + CHECK(iseq_compile_pattern_each(iseq, ret, n->nd_next->nd_head, matched, match_failed, in_single_pattern, in_alt_pattern, base_index, false)); ADD_INSN(ret, line_node, putnil); ADD_LABEL(ret, match_failed); @@ -7664,13 +6994,13 @@ iseq_compile_pattern_each(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *c fin = NEW_LABEL(line); ADD_INSN(ret, line_node, dup); // (1) - CHECK(iseq_compile_pattern_each(iseq, ret, RNODE_OR(node)->nd_1st, match_succeeded, fin, in_single_pattern, true, base_index + 1 /* (1) */, use_deconstructed_cache)); + CHECK(iseq_compile_pattern_each(iseq, ret, node->nd_1st, match_succeeded, fin, in_single_pattern, true, base_index + 1 /* (1) */, use_deconstructed_cache)); ADD_LABEL(ret, match_succeeded); ADD_INSN(ret, line_node, pop); ADD_INSNL(ret, line_node, jump, matched); ADD_INSN(ret, line_node, putnil); ADD_LABEL(ret, fin); - CHECK(iseq_compile_pattern_each(iseq, ret, RNODE_OR(node)->nd_2nd, matched, unmatched, in_single_pattern, true, base_index, use_deconstructed_cache)); + CHECK(iseq_compile_pattern_each(iseq, ret, node->nd_2nd, matched, unmatched, in_single_pattern, true, base_index, use_deconstructed_cache)); break; } default: @@ -7693,9 +7023,9 @@ iseq_compile_pattern_constant(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NOD { const NODE *line_node = node; - if (RNODE_ARYPTN(node)->nd_pconst) { + if (node->nd_pconst) { ADD_INSN(ret, line_node, dup); // (1) - CHECK(COMPILE(ret, "constant", RNODE_ARYPTN(node)->nd_pconst)); // (2) + CHECK(COMPILE(ret, "constant", node->nd_pconst)); // (2) if (in_single_pattern) { ADD_INSN1(ret, line_node, dupn, INT2FIX(2)); } @@ -7896,14 +7226,14 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no INIT_ANCHOR(body_seq); INIT_ANCHOR(cond_seq); - branches = decl_branch_base(iseq, PTR2NUM(node), nd_code_loc(node), "case"); + branches = decl_branch_base(iseq, node, "case"); - node = RNODE_CASE3(node)->nd_body; + node = node->nd_body; EXPECT_NODE("NODE_CASE3", node, NODE_IN, COMPILE_NG); type = nd_type(node); line = nd_line(node); line_node = node; - single_pattern = !RNODE_IN(node)->nd_next; + single_pattern = !node->nd_next; endlabel = NEW_LABEL(line); elselabel = NEW_LABEL(line); @@ -7917,7 +7247,7 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no } ADD_INSN(head, line_node, putnil); /* allocate stack for cached #deconstruct value */ - CHECK(COMPILE(head, "case base", RNODE_CASE3(orig_node)->nd_head)); + CHECK(COMPILE(head, "case base", orig_node->nd_head)); ADD_SEQ(ret, head); /* case VAL */ @@ -7930,21 +7260,17 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no l1 = NEW_LABEL(line); ADD_LABEL(body_seq, l1); ADD_INSN1(body_seq, line_node, adjuststack, INT2FIX(single_pattern ? 6 : 2)); - - const NODE *const coverage_node = RNODE_IN(node)->nd_body ? RNODE_IN(node)->nd_body : node; add_trace_branch_coverage( iseq, body_seq, - nd_code_loc(coverage_node), - nd_node_id(coverage_node), + node->nd_body ? node->nd_body : node, branch_id++, "in", branches); - - CHECK(COMPILE_(body_seq, "in body", RNODE_IN(node)->nd_body, popped)); + CHECK(COMPILE_(body_seq, "in body", node->nd_body, popped)); ADD_INSNL(body_seq, line_node, jump, endlabel); - pattern = RNODE_IN(node)->nd_head; + pattern = node->nd_head; if (pattern) { int pat_line = nd_line(pattern); LABEL *next_pat = NEW_LABEL(pat_line); @@ -7959,7 +7285,7 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no return COMPILE_NG; } - node = RNODE_IN(node)->nd_next; + node = node->nd_next; if (!node) { break; } @@ -7972,7 +7298,7 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no ADD_LABEL(cond_seq, elselabel); ADD_INSN(cond_seq, line_node, pop); ADD_INSN(cond_seq, line_node, pop); /* discard cached #deconstruct value */ - add_trace_branch_coverage(iseq, cond_seq, nd_code_loc(node), nd_node_id(node), branch_id, "else", branches); + add_trace_branch_coverage(iseq, cond_seq, node, branch_id, "else", branches); CHECK(COMPILE_(cond_seq, "else", node, popped)); ADD_INSNL(cond_seq, line_node, jump, endlabel); ADD_INSN(cond_seq, line_node, putnil); @@ -7983,7 +7309,7 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no else { debugs("== else (implicit)\n"); ADD_LABEL(cond_seq, elselabel); - add_trace_branch_coverage(iseq, cond_seq, nd_code_loc(orig_node), nd_node_id(orig_node), branch_id, "else", branches); + add_trace_branch_coverage(iseq, cond_seq, orig_node, branch_id, "else", branches); ADD_INSN1(cond_seq, orig_node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); if (single_pattern) { @@ -8001,7 +7327,6 @@ compile_case3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const orig_no fin = NEW_LABEL(line); kw_arg = rb_xmalloc_mul_add(2, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg)); - kw_arg->references = 0; kw_arg->keyword_len = 2; kw_arg->keywords[0] = ID2SYM(rb_intern("matchee")); kw_arg->keywords[1] = ID2SYM(rb_intern("key")); @@ -8085,7 +7410,7 @@ compile_loop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in ISEQ_COMPILE_DATA(iseq)->loopval_popped = 0; push_ensure_entry(iseq, &enl, NULL, NULL); - if (RNODE_WHILE(node)->nd_state == 1) { + if (node->nd_state == 1) { ADD_INSNL(ret, line_node, jump, next_label); } else { @@ -8100,35 +7425,31 @@ compile_loop(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in if (tmp_label) ADD_LABEL(ret, tmp_label); ADD_LABEL(ret, redo_label); - branches = decl_branch_base(iseq, PTR2NUM(node), nd_code_loc(node), type == NODE_WHILE ? "while" : "until"); - - const NODE *const coverage_node = RNODE_WHILE(node)->nd_body ? RNODE_WHILE(node)->nd_body : node; + branches = decl_branch_base(iseq, node, type == NODE_WHILE ? "while" : "until"); add_trace_branch_coverage( iseq, ret, - nd_code_loc(coverage_node), - nd_node_id(coverage_node), + node->nd_body ? node->nd_body : node, 0, "body", branches); - - CHECK(COMPILE_POPPED(ret, "while body", RNODE_WHILE(node)->nd_body)); + CHECK(COMPILE_POPPED(ret, "while body", node->nd_body)); ADD_LABEL(ret, next_label); /* next */ if (type == NODE_WHILE) { - CHECK(compile_branch_condition(iseq, ret, RNODE_WHILE(node)->nd_cond, - redo_label, end_label)); + compile_branch_condition(iseq, ret, node->nd_cond, + redo_label, end_label); } else { /* until */ - CHECK(compile_branch_condition(iseq, ret, RNODE_WHILE(node)->nd_cond, - end_label, redo_label)); + compile_branch_condition(iseq, ret, node->nd_cond, + end_label, redo_label); } ADD_LABEL(ret, end_label); ADD_ADJUST_RESTORE(ret, adjust_label); - if (UNDEF_P(RNODE_WHILE(node)->nd_state)) { + if (UNDEF_P(node->nd_state)) { /* ADD_INSN(ret, line_node, putundef); */ COMPILE_ERROR(ERROR_ARGS "unsupported: putundef"); return COMPILE_NG; @@ -8170,18 +7491,18 @@ compile_iter(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in ADD_LABEL(ret, retry_label); if (nd_type_p(node, NODE_FOR)) { - CHECK(COMPILE(ret, "iter caller (for)", RNODE_FOR(node)->nd_iter)); + CHECK(COMPILE(ret, "iter caller (for)", node->nd_iter)); ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq = - NEW_CHILD_ISEQ(RNODE_FOR(node)->nd_body, make_name_for_block(iseq), + NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line); ADD_SEND_WITH_BLOCK(ret, line_node, idEach, INT2FIX(0), child_iseq); } else { ISEQ_COMPILE_DATA(iseq)->current_block = child_iseq = - NEW_CHILD_ISEQ(RNODE_ITER(node)->nd_body, make_name_for_block(iseq), + NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line); - CHECK(COMPILE(ret, "iter caller", RNODE_ITER(node)->nd_iter)); + CHECK(COMPILE(ret, "iter caller", node->nd_iter)); } { @@ -8192,11 +7513,11 @@ compile_iter(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in // Normally, "send" instruction is at the last. // However, qcall under branch coverage measurement adds some instructions after the "send". // - // Note that "invokesuper", "invokesuperforward" appears instead of "send". + // Note that "invokesuper" appears instead of "send". INSN *iobj; LINK_ELEMENT *last_elem = LAST_ELEMENT(ret); iobj = IS_INSN(last_elem) ? (INSN*) last_elem : (INSN*) get_prev_insn((INSN*) last_elem); - while (!IS_INSN_ID(iobj, send) && !IS_INSN_ID(iobj, invokesuper) && !IS_INSN_ID(iobj, sendforward) && !IS_INSN_ID(iobj, invokesuperforward)) { + while (INSN_OF(iobj) != BIN(send) && INSN_OF(iobj) != BIN(invokesuper)) { iobj = (INSN*) get_prev_insn(iobj); } ELEM_INSERT_NEXT(&iobj->link, (LINK_ELEMENT*) retry_end_l); @@ -8225,7 +7546,7 @@ compile_for_masgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const nod * (args.length == 1 && Array.try_convert(args[0])) || args */ const NODE *line_node = node; - const NODE *var = RNODE_FOR_MASGN(node)->nd_var; + const NODE *var = node->nd_var; LABEL *not_single = NEW_LABEL(nd_line(var)); LABEL *not_ary = NEW_LABEL(nd_line(var)); CHECK(COMPILE(ret, "for var", var)); @@ -8260,7 +7581,7 @@ compile_break(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i LABEL *splabel = NEW_LABEL(0); ADD_LABEL(ret, splabel); ADD_ADJUST(ret, line_node, ISEQ_COMPILE_DATA(iseq)->redo_label); - CHECK(COMPILE_(ret, "break val (while/until)", RNODE_BREAK(node)->nd_stts, + CHECK(COMPILE_(ret, "break val (while/until)", node->nd_stts, ISEQ_COMPILE_DATA(iseq)->loopval_popped)); add_ensure_iseq(ret, iseq, 0); ADD_INSNL(ret, line_node, jump, ISEQ_COMPILE_DATA(iseq)->end_label); @@ -8295,7 +7616,7 @@ compile_break(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i } /* escape from block */ - CHECK(COMPILE(ret, "break val (block)", RNODE_BREAK(node)->nd_stts)); + CHECK(COMPILE(ret, "break val (block)", node->nd_stts)); ADD_INSN1(ret, line_node, throw, INT2FIX(throw_flag | TAG_BREAK)); if (popped) { ADD_INSN(ret, line_node, pop); @@ -8318,7 +7639,7 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in LABEL *splabel = NEW_LABEL(0); debugs("next in while loop\n"); ADD_LABEL(ret, splabel); - CHECK(COMPILE(ret, "next val/valid syntax?", RNODE_NEXT(node)->nd_stts)); + CHECK(COMPILE(ret, "next val/valid syntax?", node->nd_stts)); add_ensure_iseq(ret, iseq, 0); ADD_ADJUST(ret, line_node, ISEQ_COMPILE_DATA(iseq)->redo_label); ADD_INSNL(ret, line_node, jump, ISEQ_COMPILE_DATA(iseq)->start_label); @@ -8332,7 +7653,7 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in debugs("next in block\n"); ADD_LABEL(ret, splabel); ADD_ADJUST(ret, line_node, ISEQ_COMPILE_DATA(iseq)->start_label); - CHECK(COMPILE(ret, "next val", RNODE_NEXT(node)->nd_stts)); + CHECK(COMPILE(ret, "next val", node->nd_stts)); add_ensure_iseq(ret, iseq, 0); ADD_INSNL(ret, line_node, jump, ISEQ_COMPILE_DATA(iseq)->end_label); ADD_ADJUST_RESTORE(ret, splabel); @@ -8366,7 +7687,7 @@ compile_next(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, in ip = ISEQ_BODY(ip)->parent_iseq; } if (ip != 0) { - CHECK(COMPILE(ret, "next val", RNODE_NEXT(node)->nd_stts)); + CHECK(COMPILE(ret, "next val", node->nd_stts)); ADD_INSN1(ret, line_node, throw, INT2FIX(throw_flag | TAG_NEXT)); if (popped) { @@ -8478,7 +7799,7 @@ compile_rescue(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, LABEL *lstart = NEW_LABEL(line); LABEL *lend = NEW_LABEL(line); LABEL *lcont = NEW_LABEL(line); - const rb_iseq_t *rescue = NEW_CHILD_ISEQ(RNODE_RESCUE(node)->nd_resq, + const rb_iseq_t *rescue = NEW_CHILD_ISEQ(node->nd_resq, rb_str_concat(rb_str_new2("rescue in "), ISEQ_BODY(iseq)->location.label), ISEQ_TYPE_RESCUE, line); @@ -8490,14 +7811,14 @@ compile_rescue(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, bool prev_in_rescue = ISEQ_COMPILE_DATA(iseq)->in_rescue; ISEQ_COMPILE_DATA(iseq)->in_rescue = true; { - CHECK(COMPILE(ret, "rescue head", RNODE_RESCUE(node)->nd_head)); + CHECK(COMPILE(ret, "rescue head", node->nd_head)); } ISEQ_COMPILE_DATA(iseq)->in_rescue = prev_in_rescue; ADD_LABEL(ret, lend); - if (RNODE_RESCUE(node)->nd_else) { + if (node->nd_else) { ADD_INSN(ret, line_node, pop); - CHECK(COMPILE(ret, "rescue else", RNODE_RESCUE(node)->nd_else)); + CHECK(COMPILE(ret, "rescue else", node->nd_else)); } ADD_INSN(ret, line_node, nop); ADD_LABEL(ret, lcont); @@ -8525,16 +7846,16 @@ compile_resbody(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, label_miss = NEW_LABEL(line); label_hit = NEW_LABEL(line); - narg = RNODE_RESBODY(resq)->nd_args; + narg = resq->nd_args; if (narg) { switch (nd_type(narg)) { case NODE_LIST: while (narg) { ADD_GETLOCAL(ret, line_node, LVAR_ERRINFO, 0); - CHECK(COMPILE(ret, "rescue arg", RNODE_LIST(narg)->nd_head)); + CHECK(COMPILE(ret, "rescue arg", narg->nd_head)); ADD_INSN1(ret, line_node, checkmatch, INT2FIX(VM_CHECKMATCH_TYPE_RESCUE)); ADD_INSNL(ret, line_node, branchif, label_hit); - narg = RNODE_LIST(narg)->nd_next; + narg = narg->nd_next; } break; case NODE_SPLAT: @@ -8557,26 +7878,13 @@ compile_resbody(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, } ADD_INSNL(ret, line_node, jump, label_miss); ADD_LABEL(ret, label_hit); - ADD_TRACE(ret, RUBY_EVENT_RESCUE); - - if (RNODE_RESBODY(resq)->nd_exc_var) { - CHECK(COMPILE_POPPED(ret, "resbody exc_var", RNODE_RESBODY(resq)->nd_exc_var)); - } - - if (nd_type(RNODE_RESBODY(resq)->nd_body) == NODE_BEGIN && RNODE_BEGIN(RNODE_RESBODY(resq)->nd_body)->nd_body == NULL && !RNODE_RESBODY(resq)->nd_exc_var) { - // empty body - ADD_SYNTHETIC_INSN(ret, nd_line(RNODE_RESBODY(resq)->nd_body), -1, putnil); - } - else { - CHECK(COMPILE(ret, "resbody body", RNODE_RESBODY(resq)->nd_body)); - } - + CHECK(COMPILE(ret, "resbody body", resq->nd_body)); if (ISEQ_COMPILE_DATA(iseq)->option->tailcall_optimization) { ADD_INSN(ret, line_node, nop); } ADD_INSN(ret, line_node, leave); ADD_LABEL(ret, label_miss); - resq = RNODE_RESBODY(resq)->nd_next; + resq = resq->nd_head; } return COMPILE_OK; } @@ -8584,10 +7892,10 @@ compile_resbody(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, static int compile_ensure(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped) { - const int line = nd_line(RNODE_ENSURE(node)->nd_ensr); + const int line = nd_line(node); const NODE *line_node = node; DECL_ANCHOR(ensr); - const rb_iseq_t *ensure = NEW_CHILD_ISEQ(RNODE_ENSURE(node)->nd_ensr, + const rb_iseq_t *ensure = NEW_CHILD_ISEQ(node->nd_ensr, rb_str_concat(rb_str_new2 ("ensure in "), ISEQ_BODY(iseq)->location.label), ISEQ_TYPE_ENSURE, line); LABEL *lstart = NEW_LABEL(line); @@ -8600,17 +7908,17 @@ compile_ensure(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, struct ensure_range *erange; INIT_ANCHOR(ensr); - CHECK(COMPILE_POPPED(ensr, "ensure ensr", RNODE_ENSURE(node)->nd_ensr)); + CHECK(COMPILE_POPPED(ensr, "ensure ensr", node->nd_ensr)); last = ensr->last; last_leave = last && IS_INSN(last) && IS_INSN_ID(last, leave); er.begin = lstart; er.end = lend; er.next = 0; - push_ensure_entry(iseq, &enl, &er, RNODE_ENSURE(node)->nd_ensr); + push_ensure_entry(iseq, &enl, &er, node->nd_ensr); ADD_LABEL(ret, lstart); - CHECK(COMPILE_(ret, "ensure head", RNODE_ENSURE(node)->nd_head, (popped | last_leave))); + CHECK(COMPILE_(ret, "ensure head", node->nd_head, (popped | last_leave))); ADD_LABEL(ret, lend); ADD_SEQ(ret, ensr); if (!popped && last_leave) ADD_INSN(ret, line_node, putnil); @@ -8639,7 +7947,7 @@ compile_return(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, enum rb_iseq_type type = ISEQ_BODY(iseq)->type; const rb_iseq_t *is = iseq; enum rb_iseq_type t = type; - const NODE *retval = RNODE_RETURN(node)->nd_stts; + const NODE *retval = node->nd_stts; LABEL *splabel = 0; while (t == ISEQ_TYPE_RESCUE || t == ISEQ_TYPE_ENSURE) { @@ -8689,27 +7997,6 @@ compile_return(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, return COMPILE_OK; } -static bool -drop_unreachable_return(LINK_ANCHOR *ret) -{ - LINK_ELEMENT *i = ret->last, *last; - if (!i) return false; - if (IS_TRACE(i)) i = i->prev; - if (!IS_INSN(i) || !IS_INSN_ID(i, putnil)) return false; - last = i = i->prev; - if (IS_ADJUST(i)) i = i->prev; - if (!IS_INSN(i)) return false; - switch (INSN_OF(i)) { - case BIN(leave): - case BIN(jump): - break; - default: - return false; - } - (ret->last = last->prev)->next = NULL; - return true; -} - static int compile_evstr(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped) { @@ -8743,11 +8030,11 @@ qcall_branch_start(rb_iseq_t *iseq, LINK_ANCHOR *const recv, VALUE *branches, co LABEL *else_label = NEW_LABEL(nd_line(line_node)); VALUE br = 0; - br = decl_branch_base(iseq, PTR2NUM(node), nd_code_loc(node), "&."); + br = decl_branch_base(iseq, node, "&."); *branches = br; ADD_INSN(recv, line_node, dup); ADD_INSNL(recv, line_node, branchnil, else_label); - add_trace_branch_coverage(iseq, recv, nd_code_loc(node), nd_node_id(node), 0, "then", br); + add_trace_branch_coverage(iseq, recv, node, 0, "then", br); return else_label; } @@ -8759,7 +8046,7 @@ qcall_branch_end(rb_iseq_t *iseq, LINK_ANCHOR *const ret, LABEL *else_label, VAL end_label = NEW_LABEL(nd_line(line_node)); ADD_INSNL(ret, line_node, jump, end_label); ADD_LABEL(ret, else_label); - add_trace_branch_coverage(iseq, ret, nd_code_loc(node), nd_node_id(node), 1, "else", branches); + add_trace_branch_coverage(iseq, ret, node, 1, "else", branches); ADD_LABEL(ret, end_label); } @@ -8769,14 +8056,13 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE /* optimization shortcut * "literal".freeze -> opt_str_freeze("literal") */ - if (get_nd_recv(node) && - (nd_type_p(get_nd_recv(node), NODE_STR) || nd_type_p(get_nd_recv(node), NODE_FILE)) && - (get_node_call_nd_mid(node) == idFreeze || get_node_call_nd_mid(node) == idUMinus) && - get_nd_args(node) == NULL && + if (node->nd_recv && nd_type_p(node->nd_recv, NODE_STR) && + (node->nd_mid == idFreeze || node->nd_mid == idUMinus) && + node->nd_args == NULL && ISEQ_COMPILE_DATA(iseq)->current_block == NULL && ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) { - VALUE str = get_string_value(get_nd_recv(node)); - if (get_node_call_nd_mid(node) == idUMinus) { + VALUE str = rb_fstring(node->nd_recv->nd_lit); + if (node->nd_mid == idUMinus) { ADD_INSN2(ret, line_node, opt_str_uminus, str, new_callinfo(iseq, idUMinus, 0, 0, NULL, FALSE)); } @@ -8793,14 +8079,14 @@ compile_call_precheck_freeze(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE /* optimization shortcut * obj["literal"] -> opt_aref_with(obj, "literal") */ - if (get_node_call_nd_mid(node) == idAREF && !private_recv_p(node) && get_nd_args(node) && - nd_type_p(get_nd_args(node), NODE_LIST) && RNODE_LIST(get_nd_args(node))->as.nd_alen == 1 && - (nd_type_p(RNODE_LIST(get_nd_args(node))->nd_head, NODE_STR) || nd_type_p(RNODE_LIST(get_nd_args(node))->nd_head, NODE_FILE)) && + if (node->nd_mid == idAREF && !private_recv_p(node) && node->nd_args && + nd_type_p(node->nd_args, NODE_LIST) && node->nd_args->nd_alen == 1 && + nd_type_p(node->nd_args->nd_head, NODE_STR) && ISEQ_COMPILE_DATA(iseq)->current_block == NULL && - !frozen_string_literal_p(iseq) && + !ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal && ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) { - VALUE str = get_string_value(RNODE_LIST(get_nd_args(node))->nd_head); - CHECK(COMPILE(ret, "recv", get_nd_recv(node))); + VALUE str = rb_fstring(node->nd_args->nd_head->nd_lit); + CHECK(COMPILE(ret, "recv", node->nd_recv)); ADD_INSN2(ret, line_node, opt_aref_with, str, new_callinfo(iseq, idAREF, 1, 0, NULL, FALSE)); RB_OBJ_WRITTEN(iseq, Qundef, str); @@ -8843,12 +8129,12 @@ iseq_builtin_function_name(const enum node_type type, const NODE *recv, ID mid) if (recv) { switch (nd_type(recv)) { case NODE_VCALL: - if (RNODE_VCALL(recv)->nd_mid == rb_intern("__builtin")) { + if (recv->nd_mid == rb_intern("__builtin")) { return name; } break; case NODE_CONST: - if (RNODE_CONST(recv)->nd_vid == rb_intern("Primitive")) { + if (recv->nd_vid == rb_intern("Primitive")) { return name; } break; @@ -8929,75 +8215,16 @@ delegate_call_p(const rb_iseq_t *iseq, unsigned int argc, const LINK_ANCHOR *arg } } -// Compile Primitive.attr! :leaf, ... -static int -compile_builtin_attr(rb_iseq_t *iseq, const NODE *node) -{ - VALUE symbol; - VALUE string; - if (!node) goto no_arg; - while (node) { - if (!nd_type_p(node, NODE_LIST)) goto bad_arg; - const NODE *next = RNODE_LIST(node)->nd_next; - - node = RNODE_LIST(node)->nd_head; - if (!node) goto no_arg; - switch (nd_type(node)) { - case NODE_SYM: - symbol = rb_node_sym_string_val(node); - break; - default: - goto bad_arg; - } - - if (!SYMBOL_P(symbol)) goto non_symbol_arg; - - string = rb_sym_to_s(symbol); - if (strcmp(RSTRING_PTR(string), "leaf") == 0) { - ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_LEAF; - } - else if (strcmp(RSTRING_PTR(string), "inline_block") == 0) { - ISEQ_BODY(iseq)->builtin_attrs |= BUILTIN_ATTR_INLINE_BLOCK; - } - else if (strcmp(RSTRING_PTR(string), "use_block") == 0) { - iseq_set_use_block(iseq); - } - else { - goto unknown_arg; - } - node = next; - } - return COMPILE_OK; - no_arg: - COMPILE_ERROR(ERROR_ARGS "attr!: no argument"); - return COMPILE_NG; - non_symbol_arg: - COMPILE_ERROR(ERROR_ARGS "non symbol argument to attr!: %s", rb_builtin_class_name(symbol)); - return COMPILE_NG; - unknown_arg: - COMPILE_ERROR(ERROR_ARGS "unknown argument to attr!: %s", RSTRING_PTR(string)); - return COMPILE_NG; - bad_arg: - UNKNOWN_NODE("attr!", node, COMPILE_NG); -} - static int compile_builtin_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *node, const NODE *line_node, int popped) { - VALUE name; - if (!node) goto no_arg; if (!nd_type_p(node, NODE_LIST)) goto bad_arg; - if (RNODE_LIST(node)->nd_next) goto too_many_arg; - node = RNODE_LIST(node)->nd_head; + if (node->nd_next) goto too_many_arg; + node = node->nd_head; if (!node) goto no_arg; - switch (nd_type(node)) { - case NODE_SYM: - name = rb_node_sym_string_val(node); - break; - default: - goto bad_arg; - } + if (!nd_type_p(node, NODE_LIT)) goto bad_arg; + VALUE name = node->nd_lit; if (!SYMBOL_P(name)) goto non_symbol_arg; if (!popped) { compile_lvar(iseq, ret, line_node, SYM2ID(name)); @@ -9021,8 +8248,8 @@ static NODE * mandatory_node(const rb_iseq_t *iseq, const NODE *cond_node) { const NODE *node = ISEQ_COMPILE_DATA(iseq)->root_node; - if (nd_type(node) == NODE_IF && RNODE_IF(node)->nd_cond == cond_node) { - return RNODE_IF(node)->nd_body; + if (nd_type(node) == NODE_IF && node->nd_cond == cond_node) { + return node->nd_body; } else { rb_bug("mandatory_node: can't find mandatory node"); @@ -9036,9 +8263,8 @@ compile_builtin_mandatory_only_method(rb_iseq_t *iseq, const NODE *node, const N struct rb_args_info args = { .pre_args_num = ISEQ_BODY(iseq)->param.lead_num, }; - rb_node_args_t args_node; - rb_node_init(RNODE(&args_node), NODE_ARGS); - args_node.nd_ainfo = args; + NODE args_node; + rb_node_init(&args_node, NODE_ARGS, 0, 0, (VALUE)&args); // local table without non-mandatory parameters const int skip_local_size = ISEQ_BODY(iseq)->param.size - ISEQ_BODY(iseq)->param.lead_num; @@ -9059,21 +8285,24 @@ compile_builtin_mandatory_only_method(rb_iseq_t *iseq, const NODE *node, const N tbl->ids[i] = ISEQ_BODY(iseq)->local_table[i + skip_local_size]; } - rb_node_scope_t scope_node; - rb_node_init(RNODE(&scope_node), NODE_SCOPE); - scope_node.nd_tbl = tbl; - scope_node.nd_body = mandatory_node(iseq, node); - scope_node.nd_args = &args_node; + NODE scope_node; + rb_node_init(&scope_node, NODE_SCOPE, (VALUE)tbl, (VALUE)mandatory_node(iseq, node), (VALUE)&args_node); - VALUE ast_value = rb_ruby_ast_new(RNODE(&scope_node)); + rb_ast_body_t ast = { + .root = &scope_node, + .compile_option = 0, + .script_lines = ISEQ_BODY(iseq)->variable.script_lines, + }; + + int prev_inline_index = GET_VM()->builtin_inline_index; ISEQ_BODY(iseq)->mandatory_only_iseq = - rb_iseq_new_with_opt(ast_value, rb_iseq_base_label(iseq), + rb_iseq_new_with_opt(&ast, rb_iseq_base_label(iseq), rb_iseq_path(iseq), rb_iseq_realpath(iseq), nd_line(line_node), NULL, 0, - ISEQ_TYPE_METHOD, ISEQ_COMPILE_DATA(iseq)->option, - ISEQ_BODY(iseq)->variable.script_lines); + ISEQ_TYPE_METHOD, ISEQ_COMPILE_DATA(iseq)->option); + GET_VM()->builtin_inline_index = prev_inline_index; ALLOCV_END(idtmp); return COMPILE_OK; } @@ -9082,15 +8311,15 @@ static int compile_builtin_function_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, const NODE *line_node, int popped, const rb_iseq_t *parent_block, LINK_ANCHOR *args, const char *builtin_func) { - NODE *args_node = get_nd_args(node); + NODE *args_node = node->nd_args; if (parent_block != NULL) { - COMPILE_ERROR(ERROR_ARGS_AT(line_node) "should not call builtins here."); + COMPILE_ERROR(iseq, nd_line(line_node), "should not call builtins here."); return COMPILE_NG; } else { # define BUILTIN_INLINE_PREFIX "_bi" - char inline_func[sizeof(BUILTIN_INLINE_PREFIX) + DECIMAL_SIZE_OF(int)]; + char inline_func[DECIMAL_SIZE_OF_BITS(sizeof(int) * CHAR_BIT) + sizeof(BUILTIN_INLINE_PREFIX)]; bool cconst = false; retry:; const struct rb_builtin_function *bf = iseq_builtin_function_lookup(iseq, builtin_func); @@ -9105,10 +8334,13 @@ compile_builtin_function_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NOD } else if (strcmp("cinit!", builtin_func) == 0) { // ignore + GET_VM()->builtin_inline_index++; return COMPILE_OK; } else if (strcmp("attr!", builtin_func) == 0) { - return compile_builtin_attr(iseq, args_node); + // There's only "inline" attribute for now + ISEQ_BODY(iseq)->builtin_inline_p = true; + return COMPILE_OK; } else if (strcmp("arg!", builtin_func) == 0) { return compile_builtin_arg(iseq, ret, args_node, line_node, popped); @@ -9132,7 +8364,10 @@ compile_builtin_function_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NOD return COMPILE_NG; } - int inline_index = nd_line(node); + if (GET_VM()->builtin_inline_index == INT_MAX) { + rb_bug("builtin inline function index overflow:%s", builtin_func); + } + int inline_index = GET_VM()->builtin_inline_index++; snprintf(inline_func, sizeof(inline_func), BUILTIN_INLINE_PREFIX "%d", inline_index); builtin_func = inline_func; args_node = NULL; @@ -9181,7 +8416,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co */ DECL_ANCHOR(recv); DECL_ANCHOR(args); - ID mid = get_node_call_nd_mid(node); + ID mid = node->nd_mid; VALUE argc; unsigned int flag = 0; struct rb_callinfo_kwarg *keywords = NULL; @@ -9229,7 +8464,20 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co labels_table = st_init_numtable(); ISEQ_COMPILE_DATA(iseq)->labels_table = labels_table; } - { + if (nd_type_p(node->nd_args->nd_head, NODE_LIT) && + SYMBOL_P(node->nd_args->nd_head->nd_lit)) { + + label_name = node->nd_args->nd_head->nd_lit; + if (!st_lookup(labels_table, (st_data_t)label_name, &data)) { + label = NEW_LABEL(nd_line(line_node)); + label->position = nd_line(line_node); + st_insert(labels_table, (st_data_t)label_name, (st_data_t)label); + } + else { + label = (LABEL *)data; + } + } + else { COMPILE_ERROR(ERROR_ARGS "invalid goto/label format"); return COMPILE_NG; } @@ -9247,7 +8495,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co const char *builtin_func; if (UNLIKELY(iseq_has_builtin_function_table(iseq)) && - (builtin_func = iseq_builtin_function_name(type, get_nd_recv(node), mid)) != NULL) { + (builtin_func = iseq_builtin_function_name(type, node->nd_recv, mid)) != NULL) { return compile_builtin_function_call(iseq, ret, node, line_node, popped, parent_block, args, builtin_func); } @@ -9257,16 +8505,16 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co int idx, level; if (mid == idCall && - nd_type_p(get_nd_recv(node), NODE_LVAR) && - iseq_block_param_id_p(iseq, RNODE_LVAR(get_nd_recv(node))->nd_vid, &idx, &level)) { - ADD_INSN2(recv, get_nd_recv(node), getblockparamproxy, INT2FIX(idx + VM_ENV_DATA_SIZE - 1), INT2FIX(level)); + nd_type_p(node->nd_recv, NODE_LVAR) && + iseq_block_param_id_p(iseq, node->nd_recv->nd_vid, &idx, &level)) { + ADD_INSN2(recv, node->nd_recv, getblockparamproxy, INT2FIX(idx + VM_ENV_DATA_SIZE - 1), INT2FIX(level)); } else if (private_recv_p(node)) { ADD_INSN(recv, node, putself); flag |= VM_CALL_FCALL; } else { - CHECK(COMPILE(recv, "recv", get_nd_recv(node))); + CHECK(COMPILE(recv, "recv", node->nd_recv)); } if (type == NODE_QCALL) { @@ -9280,7 +8528,7 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co /* args */ if (type != NODE_VCALL) { - argc = setup_args(iseq, args, get_nd_args(node), &flag, &keywords); + argc = setup_args(iseq, args, node->nd_args, &flag, &keywords); CHECK(!NIL_P(argc)); } else { @@ -9301,9 +8549,6 @@ compile_call(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, co flag |= VM_CALL_FCALL; } - if ((flag & VM_CALL_ARGS_BLOCKARG) && (flag & VM_CALL_KW_SPLAT) && !(flag & VM_CALL_KW_SPLAT_MUT)) { - ADD_INSN(ret, line_node, splatkw); - } ADD_SEND_R(ret, line_node, mid, argc, parent_block, INT2FIX(flag), keywords); qcall_branch_end(iseq, ret, else_label, branches, node, line_node); @@ -9320,7 +8565,8 @@ compile_op_asgn1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node VALUE argc; unsigned int flag = 0; int asgnflag = 0; - ID id = RNODE_OP_ASGN1(node)->nd_mid; + ID id = node->nd_mid; + int boff = 0; /* * a[x] (op)= y @@ -9348,20 +8594,22 @@ compile_op_asgn1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node if (!popped) { ADD_INSN(ret, node, putnil); } - asgnflag = COMPILE_RECV(ret, "NODE_OP_ASGN1 recv", node, RNODE_OP_ASGN1(node)->nd_recv); + asgnflag = COMPILE_RECV(ret, "NODE_OP_ASGN1 recv", node); CHECK(asgnflag != -1); - switch (nd_type(RNODE_OP_ASGN1(node)->nd_index)) { + switch (nd_type(node->nd_args->nd_head)) { case NODE_ZLIST: argc = INT2FIX(0); break; + case NODE_BLOCK_PASS: + boff = 1; + /* fall through */ default: - argc = setup_args(iseq, ret, RNODE_OP_ASGN1(node)->nd_index, &flag, NULL); + argc = setup_args(iseq, ret, node->nd_args->nd_head, &flag, NULL); CHECK(!NIL_P(argc)); } - int dup_argn = FIX2INT(argc) + 1; - ADD_INSN1(ret, node, dupn, INT2FIX(dup_argn)); + ADD_INSN1(ret, node, dupn, FIXNUM_INC(argc, 1 + boff)); flag |= asgnflag; - ADD_SEND_R(ret, node, idAREF, argc, NULL, INT2FIX(flag & ~VM_CALL_ARGS_SPLAT_MUT), NULL); + ADD_SEND_WITH_FLAG(ret, node, idAREF, argc, INT2FIX(flag)); if (id == idOROP || id == idANDOP) { /* a[x] ||= y or a[x] &&= y @@ -9384,63 +8632,64 @@ compile_op_asgn1(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node } ADD_INSN(ret, node, pop); - CHECK(COMPILE(ret, "NODE_OP_ASGN1 nd_rvalue: ", RNODE_OP_ASGN1(node)->nd_rvalue)); + CHECK(COMPILE(ret, "NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body)); if (!popped) { - ADD_INSN1(ret, node, setn, INT2FIX(dup_argn+1)); + ADD_INSN1(ret, node, setn, FIXNUM_INC(argc, 2+boff)); } if (flag & VM_CALL_ARGS_SPLAT) { - if (!(flag & VM_CALL_ARGS_SPLAT_MUT)) { + ADD_INSN1(ret, node, newarray, INT2FIX(1)); + if (boff > 0) { + ADD_INSN1(ret, node, dupn, INT2FIX(3)); ADD_INSN(ret, node, swap); - ADD_INSN1(ret, node, splatarray, Qtrue); - ADD_INSN(ret, node, swap); - flag |= VM_CALL_ARGS_SPLAT_MUT; + ADD_INSN(ret, node, pop); } - ADD_INSN1(ret, node, pushtoarray, INT2FIX(1)); - ADD_SEND_R(ret, node, idASET, argc, NULL, INT2FIX(flag), NULL); + ADD_INSN(ret, node, concatarray); + if (boff > 0) { + ADD_INSN1(ret, node, setn, INT2FIX(3)); + ADD_INSN(ret, node, pop); + ADD_INSN(ret, node, pop); + } + ADD_SEND_WITH_FLAG(ret, node, idASET, argc, INT2FIX(flag)); } else { - ADD_SEND_R(ret, node, idASET, FIXNUM_INC(argc, 1), NULL, INT2FIX(flag), NULL); + if (boff > 0) + ADD_INSN(ret, node, swap); + ADD_SEND_WITH_FLAG(ret, node, idASET, FIXNUM_INC(argc, 1), INT2FIX(flag)); } ADD_INSN(ret, node, pop); ADD_INSNL(ret, node, jump, lfin); ADD_LABEL(ret, label); if (!popped) { - ADD_INSN1(ret, node, setn, INT2FIX(dup_argn+1)); + ADD_INSN1(ret, node, setn, FIXNUM_INC(argc, 2+boff)); } - ADD_INSN1(ret, node, adjuststack, INT2FIX(dup_argn+1)); + ADD_INSN1(ret, node, adjuststack, FIXNUM_INC(argc, 2+boff)); ADD_LABEL(ret, lfin); } else { - CHECK(COMPILE(ret, "NODE_OP_ASGN1 nd_rvalue: ", RNODE_OP_ASGN1(node)->nd_rvalue)); + CHECK(COMPILE(ret, "NODE_OP_ASGN1 args->body: ", node->nd_args->nd_body)); ADD_SEND(ret, node, id, INT2FIX(1)); if (!popped) { - ADD_INSN1(ret, node, setn, INT2FIX(dup_argn+1)); + ADD_INSN1(ret, node, setn, FIXNUM_INC(argc, 2+boff)); } if (flag & VM_CALL_ARGS_SPLAT) { - if (flag & VM_CALL_KW_SPLAT) { - ADD_INSN1(ret, node, topn, INT2FIX(2)); - if (!(flag & VM_CALL_ARGS_SPLAT_MUT)) { - ADD_INSN1(ret, node, splatarray, Qtrue); - flag |= VM_CALL_ARGS_SPLAT_MUT; - } + ADD_INSN1(ret, node, newarray, INT2FIX(1)); + if (boff > 0) { + ADD_INSN1(ret, node, dupn, INT2FIX(3)); ADD_INSN(ret, node, swap); - ADD_INSN1(ret, node, pushtoarray, INT2FIX(1)); - ADD_INSN1(ret, node, setn, INT2FIX(2)); ADD_INSN(ret, node, pop); } - else { - if (!(flag & VM_CALL_ARGS_SPLAT_MUT)) { - ADD_INSN(ret, node, swap); - ADD_INSN1(ret, node, splatarray, Qtrue); - ADD_INSN(ret, node, swap); - flag |= VM_CALL_ARGS_SPLAT_MUT; - } - ADD_INSN1(ret, node, pushtoarray, INT2FIX(1)); + ADD_INSN(ret, node, concatarray); + if (boff > 0) { + ADD_INSN1(ret, node, setn, INT2FIX(3)); + ADD_INSN(ret, node, pop); + ADD_INSN(ret, node, pop); } - ADD_SEND_R(ret, node, idASET, argc, NULL, INT2FIX(flag), NULL); + ADD_SEND_WITH_FLAG(ret, node, idASET, argc, INT2FIX(flag)); } else { - ADD_SEND_R(ret, node, idASET, FIXNUM_INC(argc, 1), NULL, INT2FIX(flag), NULL); + if (boff > 0) + ADD_INSN(ret, node, swap); + ADD_SEND_WITH_FLAG(ret, node, idASET, FIXNUM_INC(argc, 1), INT2FIX(flag)); } ADD_INSN(ret, node, pop); } @@ -9451,8 +8700,8 @@ static int compile_op_asgn2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped) { const int line = nd_line(node); - ID atype = RNODE_OP_ASGN2(node)->nd_mid; - ID vid = RNODE_OP_ASGN2(node)->nd_vid, aid = rb_id_attrset(vid); + ID atype = node->nd_next->nd_mid; + ID vid = node->nd_next->nd_vid, aid = rb_id_attrset(vid); int asgnflag; LABEL *lfin = NEW_LABEL(line); LABEL *lcfin = NEW_LABEL(line); @@ -9510,9 +8759,9 @@ compile_op_asgn2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node */ - asgnflag = COMPILE_RECV(ret, "NODE_OP_ASGN2#recv", node, RNODE_OP_ASGN2(node)->nd_recv); + asgnflag = COMPILE_RECV(ret, "NODE_OP_ASGN2#recv", node); CHECK(asgnflag != -1); - if (RNODE_OP_ASGN2(node)->nd_aid) { + if (node->nd_next->nd_aid) { lskip = NEW_LABEL(line); ADD_INSN(ret, node, dup); ADD_INSNL(ret, node, branchnil, lskip); @@ -9533,7 +8782,7 @@ compile_op_asgn2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node if (!popped) { ADD_INSN(ret, node, pop); } - CHECK(COMPILE(ret, "NODE_OP_ASGN2 val", RNODE_OP_ASGN2(node)->nd_value)); + CHECK(COMPILE(ret, "NODE_OP_ASGN2 val", node->nd_value)); if (!popped) { ADD_INSN(ret, node, swap); ADD_INSN1(ret, node, topn, INT2FIX(1)); @@ -9549,7 +8798,7 @@ compile_op_asgn2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node ADD_LABEL(ret, lfin); } else { - CHECK(COMPILE(ret, "NODE_OP_ASGN2 val", RNODE_OP_ASGN2(node)->nd_value)); + CHECK(COMPILE(ret, "NODE_OP_ASGN2 val", node->nd_value)); ADD_SEND(ret, node, atype, INT2FIX(1)); if (!popped) { ADD_INSN(ret, node, swap); @@ -9567,8 +8816,6 @@ compile_op_asgn2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node return COMPILE_OK; } -static int compile_shareable_constant_value(rb_iseq_t *iseq, LINK_ANCHOR *ret, enum rb_parser_shareability shareable, const NODE *lhs, const NODE *value); - static int compile_op_cdecl(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped) { @@ -9577,21 +8824,21 @@ compile_op_cdecl(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node LABEL *lassign = 0; ID mid; - switch (nd_type(RNODE_OP_CDECL(node)->nd_head)) { + switch (nd_type(node->nd_head)) { case NODE_COLON3: ADD_INSN1(ret, node, putobject, rb_cObject); break; case NODE_COLON2: - CHECK(COMPILE(ret, "NODE_OP_CDECL/colon2#nd_head", RNODE_COLON2(RNODE_OP_CDECL(node)->nd_head)->nd_head)); + CHECK(COMPILE(ret, "NODE_OP_CDECL/colon2#nd_head", node->nd_head->nd_head)); break; default: COMPILE_ERROR(ERROR_ARGS "%s: invalid node in NODE_OP_CDECL", - ruby_node_name(nd_type(RNODE_OP_CDECL(node)->nd_head))); + ruby_node_name(nd_type(node->nd_head))); return COMPILE_NG; } - mid = get_node_colon_nd_mid(RNODE_OP_CDECL(node)->nd_head); + mid = node->nd_head->nd_mid; /* cref */ - if (RNODE_OP_CDECL(node)->nd_aid == idOROP) { + if (node->nd_aid == idOROP) { lassign = NEW_LABEL(line); ADD_INSN(ret, node, dup); /* cref cref */ ADD_INSN3(ret, node, defined, INT2FIX(DEFINED_CONST_FROM), @@ -9602,17 +8849,17 @@ compile_op_cdecl(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node ADD_INSN1(ret, node, putobject, Qtrue); ADD_INSN1(ret, node, getconstant, ID2SYM(mid)); /* cref obj */ - if (RNODE_OP_CDECL(node)->nd_aid == idOROP || RNODE_OP_CDECL(node)->nd_aid == idANDOP) { + if (node->nd_aid == idOROP || node->nd_aid == idANDOP) { lfin = NEW_LABEL(line); if (!popped) ADD_INSN(ret, node, dup); /* cref [obj] obj */ - if (RNODE_OP_CDECL(node)->nd_aid == idOROP) + if (node->nd_aid == idOROP) ADD_INSNL(ret, node, branchif, lfin); else /* idANDOP */ ADD_INSNL(ret, node, branchunless, lfin); /* cref [obj] */ if (!popped) ADD_INSN(ret, node, pop); /* cref */ if (lassign) ADD_LABEL(ret, lassign); - CHECK(compile_shareable_constant_value(iseq, ret, RNODE_OP_CDECL(node)->shareability, RNODE_OP_CDECL(node)->nd_head, RNODE_OP_CDECL(node)->nd_value)); + CHECK(COMPILE(ret, "NODE_OP_CDECL#nd_value", node->nd_value)); /* cref value */ if (popped) ADD_INSN1(ret, node, topn, INT2FIX(1)); /* cref value cref */ @@ -9626,9 +8873,9 @@ compile_op_cdecl(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node ADD_INSN(ret, node, pop); /* [value] */ } else { - CHECK(compile_shareable_constant_value(iseq, ret, RNODE_OP_CDECL(node)->shareability, RNODE_OP_CDECL(node)->nd_head, RNODE_OP_CDECL(node)->nd_value)); + CHECK(COMPILE(ret, "NODE_OP_CDECL#nd_value", node->nd_value)); /* cref obj value */ - ADD_CALL(ret, node, RNODE_OP_CDECL(node)->nd_aid, INT2FIX(1)); + ADD_CALL(ret, node, node->nd_aid, INT2FIX(1)); /* cref value */ ADD_INSN(ret, node, swap); /* value cref */ if (!popped) { @@ -9647,11 +8894,11 @@ compile_op_log(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, LABEL *lfin = NEW_LABEL(line); LABEL *lassign; - if (type == NODE_OP_ASGN_OR && !nd_type_p(RNODE_OP_ASGN_OR(node)->nd_head, NODE_IVAR)) { + if (type == NODE_OP_ASGN_OR && !nd_type_p(node->nd_head, NODE_IVAR)) { LABEL *lfinish[2]; lfinish[0] = lfin; lfinish[1] = 0; - defined_expr(iseq, ret, RNODE_OP_ASGN_OR(node)->nd_head, lfinish, Qfalse, false); + defined_expr(iseq, ret, node->nd_head, lfinish, Qfalse); lassign = lfinish[1]; if (!lassign) { lassign = NEW_LABEL(line); @@ -9662,7 +8909,7 @@ compile_op_log(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, lassign = NEW_LABEL(line); } - CHECK(COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_head", RNODE_OP_ASGN_OR(node)->nd_head)); + CHECK(COMPILE(ret, "NODE_OP_ASGN_AND/OR#nd_head", node->nd_head)); if (!popped) { ADD_INSN(ret, node, dup); @@ -9680,7 +8927,7 @@ compile_op_log(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, } ADD_LABEL(ret, lassign); - CHECK(COMPILE_(ret, "NODE_OP_ASGN_AND/OR#nd_value", RNODE_OP_ASGN_OR(node)->nd_value, popped)); + CHECK(COMPILE_(ret, "NODE_OP_ASGN_AND/OR#nd_value", node->nd_value, popped)); ADD_LABEL(ret, lfin); return COMPILE_OK; } @@ -9694,22 +8941,13 @@ compile_super(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i unsigned int flag = 0; struct rb_callinfo_kwarg *keywords = NULL; const rb_iseq_t *parent_block = ISEQ_COMPILE_DATA(iseq)->current_block; - int use_block = 1; INIT_ANCHOR(args); ISEQ_COMPILE_DATA(iseq)->current_block = NULL; - if (type == NODE_SUPER) { - VALUE vargc = setup_args(iseq, args, RNODE_SUPER(node)->nd_args, &flag, &keywords); + VALUE vargc = setup_args(iseq, args, node->nd_args, &flag, &keywords); CHECK(!NIL_P(vargc)); argc = FIX2INT(vargc); - if ((flag & VM_CALL_ARGS_BLOCKARG) && (flag & VM_CALL_KW_SPLAT) && !(flag & VM_CALL_KW_SPLAT_MUT)) { - ADD_INSN(args, node, splatkw); - } - - if (flag & VM_CALL_ARGS_BLOCKARG) { - use_block = 0; - } } else { /* NODE_ZSUPER */ @@ -9727,13 +8965,6 @@ compile_super(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i ADD_GETLOCAL(args, node, idx, lvar_level); } - /* forward ... */ - if (local_body->param.flags.forwardable) { - flag |= VM_CALL_FORWARDING; - int idx = local_body->local_table_size - get_local_var_idx(liseq, idDot3); - ADD_GETLOCAL(args, node, idx, lvar_level); - } - if (local_body->param.flags.has_opt) { /* optional arguments */ int j; @@ -9748,7 +8979,7 @@ compile_super(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i /* rest argument */ int idx = local_body->local_table_size - local_body->param.rest_start; ADD_GETLOCAL(args, node, idx, lvar_level); - ADD_INSN1(args, node, splatarray, RBOOL(local_body->param.flags.has_post)); + ADD_INSN1(args, node, splatarray, Qfalse); argc = local_body->param.rest_start + 1; flag |= VM_CALL_ARGS_SPLAT; @@ -9764,8 +8995,8 @@ compile_super(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i int idx = local_body->local_table_size - (post_start + j); ADD_GETLOCAL(args, node, idx, lvar_level); } - ADD_INSN1(args, node, pushtoarray, INT2FIX(j)); - flag |= VM_CALL_ARGS_SPLAT_MUT; + ADD_INSN1(args, node, newarray, INT2FIX(j)); + ADD_INSN (args, node, concatarray); /* argc is settled at above */ } else { @@ -9787,11 +9018,14 @@ compile_super(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i if (local_body->param.flags.has_kwrest) { int idx = local_body->local_table_size - local_kwd->rest_start; ADD_GETLOCAL(args, node, idx, lvar_level); - RUBY_ASSERT(local_kwd->num > 0); - ADD_SEND (args, node, rb_intern("dup"), INT2FIX(0)); + if (local_kwd->num > 0) { + ADD_SEND (args, node, rb_intern("dup"), INT2FIX(0)); + flag |= VM_CALL_KW_SPLAT_MUT; + } } else { ADD_INSN1(args, node, newhash, INT2FIX(0)); + flag |= VM_CALL_KW_SPLAT_MUT; } for (i = 0; i < local_kwd->num; ++i) { ID id = local_kwd->table[i]; @@ -9800,33 +9034,35 @@ compile_super(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i ADD_GETLOCAL(args, node, idx, lvar_level); } ADD_SEND(args, node, id_core_hash_merge_ptr, INT2FIX(i * 2 + 1)); - flag |= VM_CALL_KW_SPLAT| VM_CALL_KW_SPLAT_MUT; + if (local_body->param.flags.has_rest) { + ADD_INSN1(args, node, newarray, INT2FIX(1)); + ADD_INSN (args, node, concatarray); + --argc; + } + flag |= VM_CALL_KW_SPLAT; } else if (local_body->param.flags.has_kwrest) { int idx = local_body->local_table_size - local_kwd->rest_start; ADD_GETLOCAL(args, node, idx, lvar_level); - argc++; + + if (local_body->param.flags.has_rest) { + ADD_INSN1(args, node, newarray, INT2FIX(1)); + ADD_INSN (args, node, concatarray); + } + else { + argc++; + } flag |= VM_CALL_KW_SPLAT; } } - if (use_block && parent_block == NULL) { - iseq_set_use_block(ISEQ_BODY(iseq)->local_iseq); - } - flag |= VM_CALL_SUPER | VM_CALL_FCALL; if (type == NODE_ZSUPER) flag |= VM_CALL_ZSUPER; ADD_INSN(ret, node, putself); ADD_SEQ(ret, args); - - const struct rb_callinfo * ci = new_callinfo(iseq, 0, argc, flag, keywords, parent_block != NULL); - - if (vm_ci_flag(ci) & VM_CALL_FORWARDING) { - ADD_INSN2(ret, node, invokesuperforward, ci, parent_block); - } - else { - ADD_INSN2(ret, node, invokesuper, ci, parent_block); - } + ADD_INSN2(ret, node, invokesuper, + new_callinfo(iseq, 0, argc, flag, keywords, parent_block != NULL), + parent_block); if (popped) { ADD_INSN(ret, node, pop); @@ -9853,8 +9089,8 @@ compile_yield(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i default: /* valid */; } - if (RNODE_YIELD(node)->nd_head) { - argc = setup_args(iseq, args, RNODE_YIELD(node)->nd_head, &flag, &keywords); + if (node->nd_head) { + argc = setup_args(iseq, args, node->nd_head, &flag, &keywords); CHECK(!NIL_P(argc)); } else { @@ -9863,7 +9099,6 @@ compile_yield(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i ADD_SEQ(ret, args); ADD_INSN1(ret, node, invokeblock, new_callinfo(iseq, 0, FIX2INT(argc), flag, keywords, FALSE)); - iseq_set_use_block(ISEQ_BODY(iseq)->local_iseq); if (popped) { ADD_INSN(ret, node, pop); @@ -9889,17 +9124,17 @@ compile_match(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i INIT_ANCHOR(val); switch ((int)type) { case NODE_MATCH: - ADD_INSN1(recv, node, putobject, rb_node_regx_string_val(node)); + ADD_INSN1(recv, node, putobject, node->nd_lit); ADD_INSN2(val, node, getspecial, INT2FIX(0), INT2FIX(0)); break; case NODE_MATCH2: - CHECK(COMPILE(recv, "receiver", RNODE_MATCH2(node)->nd_recv)); - CHECK(COMPILE(val, "value", RNODE_MATCH2(node)->nd_value)); + CHECK(COMPILE(recv, "receiver", node->nd_recv)); + CHECK(COMPILE(val, "value", node->nd_value)); break; case NODE_MATCH3: - CHECK(COMPILE(recv, "receiver", RNODE_MATCH3(node)->nd_value)); - CHECK(COMPILE(val, "value", RNODE_MATCH3(node)->nd_recv)); + CHECK(COMPILE(recv, "receiver", node->nd_value)); + CHECK(COMPILE(val, "value", node->nd_recv)); break; } @@ -9907,8 +9142,8 @@ compile_match(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i ADD_SEQ(ret, val); ADD_SEND(ret, node, idEqTilde, INT2FIX(1)); - if (nd_type_p(node, NODE_MATCH2) && RNODE_MATCH2(node)->nd_args) { - compile_named_capture_assign(iseq, ret, RNODE_MATCH2(node)->nd_args); + if (node->nd_args) { + compile_named_capture_assign(iseq, ret, node->nd_args); } if (popped) { @@ -9920,7 +9155,7 @@ compile_match(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, i static int compile_colon2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped) { - if (rb_is_const_id(RNODE_COLON2(node)->nd_mid)) { + if (rb_is_const_id(node->nd_mid)) { /* constant */ VALUE segments; if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache && @@ -9950,8 +9185,8 @@ compile_colon2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, else { /* function call */ ADD_CALL_RECEIVER(ret, node); - CHECK(COMPILE(ret, "colon2#nd_head", RNODE_COLON2(node)->nd_head)); - ADD_CALL(ret, node, RNODE_COLON2(node)->nd_mid, INT2FIX(1)); + CHECK(COMPILE(ret, "colon2#nd_head", node->nd_head)); + ADD_CALL(ret, node, node->nd_mid, INT2FIX(1)); } if (popped) { ADD_INSN(ret, node, pop); @@ -9962,19 +9197,19 @@ compile_colon2(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, static int compile_colon3(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped) { - debugi("colon3#nd_mid", RNODE_COLON3(node)->nd_mid); + debugi("colon3#nd_mid", node->nd_mid); /* add cache insn */ if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) { ISEQ_BODY(iseq)->ic_size++; - VALUE segments = rb_ary_new_from_args(2, ID2SYM(idNULL), ID2SYM(RNODE_COLON3(node)->nd_mid)); + VALUE segments = rb_ary_new_from_args(2, ID2SYM(idNULL), ID2SYM(node->nd_mid)); ADD_INSN1(ret, node, opt_getconstant_path, segments); RB_OBJ_WRITTEN(iseq, Qundef, segments); } else { ADD_INSN1(ret, node, putobject, rb_cObject); ADD_INSN1(ret, node, putobject, Qtrue); - ADD_INSN1(ret, node, getconstant, ID2SYM(RNODE_COLON3(node)->nd_mid)); + ADD_INSN1(ret, node, getconstant, ID2SYM(node->nd_mid)); } if (popped) { @@ -9987,13 +9222,13 @@ static int compile_dots(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped, const int excl) { VALUE flag = INT2FIX(excl); - const NODE *b = RNODE_DOT2(node)->nd_beg; - const NODE *e = RNODE_DOT2(node)->nd_end; + const NODE *b = node->nd_beg; + const NODE *e = node->nd_end; if (optimizable_range_item_p(b) && optimizable_range_item_p(e)) { if (!popped) { - VALUE bv = optimized_range_item(b); - VALUE ev = optimized_range_item(e); + VALUE bv = nd_type_p(b, NODE_LIT) ? b->nd_lit : Qnil; + VALUE ev = nd_type_p(e, NODE_LIT) ? e->nd_lit : Qnil; VALUE val = rb_range_new(bv, ev, excl); ADD_INSN1(ret, node, putobject, val); RB_OBJ_WRITTEN(iseq, Qundef, val); @@ -10042,20 +9277,14 @@ compile_kw_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, { struct rb_iseq_constant_body *const body = ISEQ_BODY(iseq); LABEL *end_label = NEW_LABEL(nd_line(node)); - const NODE *default_value = get_nd_value(RNODE_KW_ARG(node)->nd_body); + const NODE *default_value = node->nd_body->nd_value; if (default_value == NODE_SPECIAL_REQUIRED_KEYWORD) { /* required argument. do nothing */ COMPILE_ERROR(ERROR_ARGS "unreachable"); return COMPILE_NG; } - else if (nd_type_p(default_value, NODE_SYM) || - nd_type_p(default_value, NODE_REGX) || - nd_type_p(default_value, NODE_LINE) || - nd_type_p(default_value, NODE_INTEGER) || - nd_type_p(default_value, NODE_FLOAT) || - nd_type_p(default_value, NODE_RATIONAL) || - nd_type_p(default_value, NODE_IMAGINARY) || + else if (nd_type_p(default_value, NODE_LIT) || nd_type_p(default_value, NODE_NIL) || nd_type_p(default_value, NODE_TRUE) || nd_type_p(default_value, NODE_FALSE)) { @@ -10072,7 +9301,7 @@ compile_kw_arg(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, ADD_INSN2(ret, node, checkkeyword, INT2FIX(kw_bits_idx + VM_ENV_DATA_SIZE - 1), INT2FIX(keyword_idx)); ADD_INSNL(ret, node, branchif, end_label); - CHECK(COMPILE_POPPED(ret, "keyword default argument", RNODE_KW_ARG(node)->nd_body)); + CHECK(COMPILE_POPPED(ret, "keyword default argument", node->nd_body)); ADD_LABEL(ret, end_label); } return COMPILE_OK; @@ -10084,7 +9313,7 @@ compile_attrasgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node DECL_ANCHOR(recv); DECL_ANCHOR(args); unsigned int flag = 0; - ID mid = RNODE_ATTRASGN(node)->nd_mid; + ID mid = node->nd_mid; VALUE argc; LABEL *else_label = NULL; VALUE branches = Qfalse; @@ -10092,16 +9321,17 @@ 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) && RNODE_ATTRASGN(node)->nd_args && - nd_type_p(RNODE_ATTRASGN(node)->nd_args, NODE_LIST) && RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->as.nd_alen == 2 && - (nd_type_p(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head, NODE_STR) || nd_type_p(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head, NODE_FILE)) && + 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 && - !frozen_string_literal_p(iseq) && + !ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal && ISEQ_COMPILE_DATA(iseq)->option->specialized_instruction) { - VALUE str = get_string_value(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_head); - CHECK(COMPILE(ret, "recv", RNODE_ATTRASGN(node)->nd_recv)); - CHECK(COMPILE(ret, "value", RNODE_LIST(RNODE_LIST(RNODE_ATTRASGN(node)->nd_args)->nd_next)->nd_head)); + VALUE str = rb_fstring(node->nd_args->nd_head->nd_lit); + CHECK(COMPILE(ret, "recv", node->nd_recv)); + CHECK(COMPILE(ret, "value", node->nd_args->nd_next->nd_head)); if (!popped) { ADD_INSN(ret, node, swap); ADD_INSN1(ret, node, topn, INT2FIX(1)); @@ -10115,10 +9345,10 @@ compile_attrasgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node INIT_ANCHOR(recv); INIT_ANCHOR(args); - argc = setup_args(iseq, args, RNODE_ATTRASGN(node)->nd_args, &flag, NULL); + argc = setup_args(iseq, args, node->nd_args, &flag, NULL); CHECK(!NIL_P(argc)); - int asgnflag = COMPILE_RECV(recv, "recv", node, RNODE_ATTRASGN(node)->nd_recv); + int asgnflag = COMPILE_RECV(recv, "recv", node); CHECK(asgnflag != -1); flag |= (unsigned int)asgnflag; @@ -10135,7 +9365,16 @@ compile_attrasgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node ADD_SEQ(ret, recv); ADD_SEQ(ret, args); - if (flag & VM_CALL_ARGS_SPLAT) { + if (flag & VM_CALL_ARGS_BLOCKARG) { + ADD_INSN1(ret, node, topn, INT2FIX(1)); + if (flag & VM_CALL_ARGS_SPLAT) { + ADD_INSN1(ret, node, putobject, INT2FIX(-1)); + ADD_SEND_WITH_FLAG(ret, node, idAREF, INT2FIX(1), INT2FIX(asgnflag)); + } + ADD_INSN1(ret, node, setn, FIXNUM_INC(argc, 3)); + ADD_INSN (ret, node, pop); + } + else if (flag & VM_CALL_ARGS_SPLAT) { ADD_INSN(ret, node, dup); ADD_INSN1(ret, node, putobject, INT2FIX(-1)); ADD_SEND_WITH_FLAG(ret, node, idAREF, INT2FIX(1), INT2FIX(asgnflag)); @@ -10156,367 +9395,6 @@ compile_attrasgn(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node return COMPILE_OK; } -static int -compile_make_shareable_node(rb_iseq_t *iseq, LINK_ANCHOR *ret, LINK_ANCHOR *sub, const NODE *value, bool copy) -{ - ADD_INSN1(ret, value, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); - ADD_SEQ(ret, sub); - - if (copy) { - /* - * NEW_CALL(fcore, rb_intern("make_shareable_copy"), - * NEW_LIST(value, loc), loc); - */ - ADD_SEND_WITH_FLAG(ret, value, rb_intern("make_shareable_copy"), INT2FIX(1), INT2FIX(VM_CALL_ARGS_SIMPLE)); - } - else { - /* - * NEW_CALL(fcore, rb_intern("make_shareable"), - * NEW_LIST(value, loc), loc); - */ - ADD_SEND_WITH_FLAG(ret, value, rb_intern("make_shareable"), INT2FIX(1), INT2FIX(VM_CALL_ARGS_SIMPLE)); - } - - return COMPILE_OK; -} - -static VALUE -node_const_decl_val(const NODE *node) -{ - VALUE path; - switch (nd_type(node)) { - case NODE_CDECL: - if (RNODE_CDECL(node)->nd_vid) { - path = rb_id2str(RNODE_CDECL(node)->nd_vid); - goto end; - } - else { - node = RNODE_CDECL(node)->nd_else; - } - break; - case NODE_COLON2: - break; - case NODE_COLON3: - // ::Const - path = rb_str_new_cstr("::"); - rb_str_append(path, rb_id2str(RNODE_COLON3(node)->nd_mid)); - goto end; - default: - rb_bug("unexpected node: %s", ruby_node_name(nd_type(node))); - UNREACHABLE_RETURN(0); - } - - path = rb_ary_new(); - if (node) { - for (; node && nd_type_p(node, NODE_COLON2); node = RNODE_COLON2(node)->nd_head) { - rb_ary_push(path, rb_id2str(RNODE_COLON2(node)->nd_mid)); - } - if (node && nd_type_p(node, NODE_CONST)) { - // Const::Name - rb_ary_push(path, rb_id2str(RNODE_CONST(node)->nd_vid)); - } - else if (node && nd_type_p(node, NODE_COLON3)) { - // ::Const::Name - rb_ary_push(path, rb_id2str(RNODE_COLON3(node)->nd_mid)); - rb_ary_push(path, rb_str_new(0, 0)); - } - else { - // expression::Name - rb_ary_push(path, rb_str_new_cstr("...")); - } - path = rb_ary_join(rb_ary_reverse(path), rb_str_new_cstr("::")); - } - end: - path = rb_fstring(path); - return path; -} - -static VALUE -const_decl_path(NODE *dest) -{ - VALUE path = Qnil; - if (!nd_type_p(dest, NODE_CALL)) { - path = node_const_decl_val(dest); - } - return path; -} - -static int -compile_ensure_shareable_node(rb_iseq_t *iseq, LINK_ANCHOR *ret, NODE *dest, const NODE *value) -{ - /* - *. RubyVM::FrozenCore.ensure_shareable(value, const_decl_path(dest)) - */ - VALUE path = const_decl_path(dest); - ADD_INSN1(ret, value, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); - CHECK(COMPILE(ret, "compile_ensure_shareable_node", value)); - ADD_INSN1(ret, value, putobject, path); - RB_OBJ_WRITTEN(iseq, Qundef, path); - ADD_SEND_WITH_FLAG(ret, value, rb_intern("ensure_shareable"), INT2FIX(2), INT2FIX(VM_CALL_ARGS_SIMPLE)); - - return COMPILE_OK; -} - -#ifndef SHAREABLE_BARE_EXPRESSION -#define SHAREABLE_BARE_EXPRESSION 1 -#endif - -static int -compile_shareable_literal_constant(rb_iseq_t *iseq, LINK_ANCHOR *ret, enum rb_parser_shareability shareable, NODE *dest, const NODE *node, size_t level, VALUE *value_p, int *shareable_literal_p) -{ -# define compile_shareable_literal_constant_next(node, anchor, value_p, shareable_literal_p) \ - compile_shareable_literal_constant(iseq, anchor, shareable, dest, node, level+1, value_p, shareable_literal_p) - VALUE lit = Qnil; - DECL_ANCHOR(anchor); - - enum node_type type = nd_type(node); - switch (type) { - case NODE_TRUE: - *value_p = Qtrue; - goto compile; - case NODE_FALSE: - *value_p = Qfalse; - goto compile; - case NODE_NIL: - *value_p = Qnil; - goto compile; - case NODE_SYM: - *value_p = rb_node_sym_string_val(node); - goto compile; - case NODE_REGX: - *value_p = rb_node_regx_string_val(node); - goto compile; - case NODE_LINE: - *value_p = rb_node_line_lineno_val(node); - goto compile; - case NODE_INTEGER: - *value_p = rb_node_integer_literal_val(node); - goto compile; - case NODE_FLOAT: - *value_p = rb_node_float_literal_val(node); - goto compile; - case NODE_RATIONAL: - *value_p = rb_node_rational_literal_val(node); - goto compile; - case NODE_IMAGINARY: - *value_p = rb_node_imaginary_literal_val(node); - goto compile; - case NODE_ENCODING: - *value_p = rb_node_encoding_val(node); - - compile: - CHECK(COMPILE(ret, "shareable_literal_constant", node)); - *shareable_literal_p = 1; - return COMPILE_OK; - - case NODE_DSTR: - CHECK(COMPILE(ret, "shareable_literal_constant", node)); - if (shareable == rb_parser_shareable_literal) { - /* - * NEW_CALL(node, idUMinus, 0, loc); - * - * -"#{var}" - */ - ADD_SEND_WITH_FLAG(ret, node, idUMinus, INT2FIX(0), INT2FIX(VM_CALL_ARGS_SIMPLE)); - } - *value_p = Qundef; - *shareable_literal_p = 1; - return COMPILE_OK; - - case NODE_STR:{ - VALUE lit = rb_node_str_string_val(node); - ADD_INSN1(ret, node, putobject, lit); - RB_OBJ_WRITTEN(iseq, Qundef, lit); - *value_p = lit; - *shareable_literal_p = 1; - - return COMPILE_OK; - } - - case NODE_FILE:{ - VALUE lit = rb_node_file_path_val(node); - ADD_INSN1(ret, node, putobject, lit); - RB_OBJ_WRITTEN(iseq, Qundef, lit); - *value_p = lit; - *shareable_literal_p = 1; - - return COMPILE_OK; - } - - case NODE_ZLIST:{ - VALUE lit = rb_ary_new(); - OBJ_FREEZE(lit); - ADD_INSN1(ret, node, putobject, lit); - RB_OBJ_WRITTEN(iseq, Qundef, lit); - *value_p = lit; - *shareable_literal_p = 1; - - return COMPILE_OK; - } - - case NODE_LIST:{ - INIT_ANCHOR(anchor); - lit = rb_ary_new(); - for (NODE *n = (NODE *)node; n; n = RNODE_LIST(n)->nd_next) { - VALUE val; - int shareable_literal_p2; - NODE *elt = RNODE_LIST(n)->nd_head; - if (elt) { - CHECK(compile_shareable_literal_constant_next(elt, anchor, &val, &shareable_literal_p2)); - if (shareable_literal_p2) { - /* noop */ - } - else if (RTEST(lit)) { - rb_ary_clear(lit); - lit = Qfalse; - } - } - if (RTEST(lit)) { - if (!UNDEF_P(val)) { - rb_ary_push(lit, val); - } - else { - rb_ary_clear(lit); - lit = Qnil; /* make shareable at runtime */ - } - } - } - break; - } - case NODE_HASH:{ - if (!RNODE_HASH(node)->nd_brace) { - *value_p = Qundef; - *shareable_literal_p = 0; - return COMPILE_OK; - } - - INIT_ANCHOR(anchor); - lit = rb_hash_new(); - for (NODE *n = RNODE_HASH(node)->nd_head; n; n = RNODE_LIST(RNODE_LIST(n)->nd_next)->nd_next) { - VALUE key_val; - VALUE value_val; - int shareable_literal_p2; - NODE *key = RNODE_LIST(n)->nd_head; - NODE *val = RNODE_LIST(RNODE_LIST(n)->nd_next)->nd_head; - if (key) { - CHECK(compile_shareable_literal_constant_next(key, anchor, &key_val, &shareable_literal_p2)); - if (shareable_literal_p2) { - /* noop */ - } - else if (RTEST(lit)) { - rb_hash_clear(lit); - lit = Qfalse; - } - } - if (val) { - CHECK(compile_shareable_literal_constant_next(val, anchor, &value_val, &shareable_literal_p2)); - if (shareable_literal_p2) { - /* noop */ - } - else if (RTEST(lit)) { - rb_hash_clear(lit); - lit = Qfalse; - } - } - if (RTEST(lit)) { - if (!UNDEF_P(key_val) && !UNDEF_P(value_val)) { - rb_hash_aset(lit, key_val, value_val); - } - else { - rb_hash_clear(lit); - lit = Qnil; /* make shareable at runtime */ - } - } - } - break; - } - - default: - if (shareable == rb_parser_shareable_literal && - (SHAREABLE_BARE_EXPRESSION || level > 0)) { - CHECK(compile_ensure_shareable_node(iseq, ret, dest, node)); - *value_p = Qundef; - *shareable_literal_p = 1; - return COMPILE_OK; - } - CHECK(COMPILE(ret, "shareable_literal_constant", node)); - *value_p = Qundef; - *shareable_literal_p = 0; - return COMPILE_OK; - } - - /* Array or Hash */ - if (!lit) { - if (nd_type(node) == NODE_LIST) { - ADD_INSN1(anchor, node, newarray, INT2FIX(RNODE_LIST(node)->as.nd_alen)); - } - else if (nd_type(node) == NODE_HASH) { - int len = (int)RNODE_LIST(RNODE_HASH(node)->nd_head)->as.nd_alen; - ADD_INSN1(anchor, node, newhash, INT2FIX(len)); - } - *value_p = Qundef; - *shareable_literal_p = 0; - ADD_SEQ(ret, anchor); - return COMPILE_OK; - } - if (NIL_P(lit)) { - // if shareable_literal, all elements should have been ensured - // as shareable - if (nd_type(node) == NODE_LIST) { - ADD_INSN1(anchor, node, newarray, INT2FIX(RNODE_LIST(node)->as.nd_alen)); - } - else if (nd_type(node) == NODE_HASH) { - int len = (int)RNODE_LIST(RNODE_HASH(node)->nd_head)->as.nd_alen; - ADD_INSN1(anchor, node, newhash, INT2FIX(len)); - } - CHECK(compile_make_shareable_node(iseq, ret, anchor, node, false)); - *value_p = Qundef; - *shareable_literal_p = 1; - } - else { - VALUE val = rb_ractor_make_shareable(lit); - ADD_INSN1(ret, node, putobject, val); - RB_OBJ_WRITTEN(iseq, Qundef, val); - *value_p = val; - *shareable_literal_p = 1; - } - - return COMPILE_OK; -} - -static int -compile_shareable_constant_value(rb_iseq_t *iseq, LINK_ANCHOR *ret, enum rb_parser_shareability shareable, const NODE *lhs, const NODE *value) -{ - int literal_p = 0; - VALUE val; - DECL_ANCHOR(anchor); - INIT_ANCHOR(anchor); - - switch (shareable) { - case rb_parser_shareable_none: - CHECK(COMPILE(ret, "compile_shareable_constant_value", value)); - return COMPILE_OK; - - case rb_parser_shareable_literal: - CHECK(compile_shareable_literal_constant(iseq, anchor, shareable, (NODE *)lhs, value, 0, &val, &literal_p)); - ADD_SEQ(ret, anchor); - return COMPILE_OK; - - case rb_parser_shareable_copy: - case rb_parser_shareable_everything: - CHECK(compile_shareable_literal_constant(iseq, anchor, shareable, (NODE *)lhs, value, 0, &val, &literal_p)); - if (!literal_p) { - CHECK(compile_make_shareable_node(iseq, ret, anchor, value, shareable == rb_parser_shareable_copy)); - } - else { - ADD_SEQ(ret, anchor); - } - return COMPILE_OK; - default: - rb_bug("unexpected rb_parser_shareability: %d", shareable); - } -} - static int iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const node, int popped); /** compile each node @@ -10533,7 +9411,8 @@ iseq_compile_each(rb_iseq_t *iseq, LINK_ANCHOR *ret, const NODE *node, int poppe int lineno = ISEQ_COMPILE_DATA(iseq)->last_line; if (lineno == 0) lineno = FIX2INT(rb_iseq_first_lineno(iseq)); debugs("node: NODE_NIL(implicit)\n"); - ADD_SYNTHETIC_INSN(ret, lineno, -1, putnil); + NODE dummy_line_node = generate_dummy_line_node(lineno, -1); + ADD_INSN(ret, &dummy_line_node, putnil); } return COMPILE_OK; } @@ -10551,7 +9430,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no /* ignore */ } else { - if (nd_fl_newline(node)) { + if (node->flags & NODE_FL_NEWLINE) { int event = RUBY_EVENT_LINE; ISEQ_COMPILE_DATA(iseq)->last_line = line; if (ISEQ_COVERAGE(iseq) && ISEQ_LINE_COVERAGE(iseq)) { @@ -10606,7 +9485,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no CHECK(compile_retry(iseq, ret, node, popped)); break; case NODE_BEGIN:{ - CHECK(COMPILE_(ret, "NODE_BEGIN", RNODE_BEGIN(node)->nd_body, popped)); + CHECK(COMPILE_(ret, "NODE_BEGIN", node->nd_body, popped)); break; } case NODE_RESCUE: @@ -10622,7 +9501,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no case NODE_AND: case NODE_OR:{ LABEL *end_label = NEW_LABEL(line); - CHECK(COMPILE(ret, "nd_1st", RNODE_OR(node)->nd_1st)); + CHECK(COMPILE(ret, "nd_1st", node->nd_1st)); if (!popped) { ADD_INSN(ret, node, dup); } @@ -10635,22 +9514,25 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no if (!popped) { ADD_INSN(ret, node, pop); } - CHECK(COMPILE_(ret, "nd_2nd", RNODE_OR(node)->nd_2nd, popped)); + CHECK(COMPILE_(ret, "nd_2nd", node->nd_2nd, popped)); ADD_LABEL(ret, end_label); break; } 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; } case NODE_LASGN:{ - ID id = RNODE_LASGN(node)->nd_vid; + ID id = node->nd_vid; int idx = ISEQ_BODY(body->local_iseq)->local_table_size - get_local_var_idx(iseq, id); debugs("lvar: %s idx: %d\n", rb_id2name(id), idx); - CHECK(COMPILE(ret, "rvalue", RNODE_LASGN(node)->nd_value)); + CHECK(COMPILE(ret, "rvalue", node->nd_value)); if (!popped) { ADD_INSN(ret, node, dup); @@ -10660,8 +9542,8 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no } case NODE_DASGN: { int idx, lv, ls; - ID id = RNODE_DASGN(node)->nd_vid; - CHECK(COMPILE(ret, "dvalue", RNODE_DASGN(node)->nd_value)); + ID id = node->nd_vid; + CHECK(COMPILE(ret, "dvalue", node->nd_value)); debugi("dassn id", rb_id2str(id) ? id : '*'); if (!popped) { @@ -10679,27 +9561,27 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; } case NODE_GASGN:{ - CHECK(COMPILE(ret, "lvalue", RNODE_GASGN(node)->nd_value)); + CHECK(COMPILE(ret, "lvalue", node->nd_value)); if (!popped) { ADD_INSN(ret, node, dup); } - ADD_INSN1(ret, node, setglobal, ID2SYM(RNODE_GASGN(node)->nd_vid)); + ADD_INSN1(ret, node, setglobal, ID2SYM(node->nd_entry)); break; } case NODE_IASGN:{ - CHECK(COMPILE(ret, "lvalue", RNODE_IASGN(node)->nd_value)); + CHECK(COMPILE(ret, "lvalue", node->nd_value)); if (!popped) { ADD_INSN(ret, node, dup); } ADD_INSN2(ret, node, setinstancevariable, - ID2SYM(RNODE_IASGN(node)->nd_vid), - get_ivar_ic_value(iseq,RNODE_IASGN(node)->nd_vid)); + ID2SYM(node->nd_vid), + get_ivar_ic_value(iseq,node->nd_vid)); break; } case NODE_CDECL:{ - if (RNODE_CDECL(node)->nd_vid) { - CHECK(compile_shareable_constant_value(iseq, ret, RNODE_CDECL(node)->shareability, node, RNODE_CDECL(node)->nd_value)); + if (node->nd_vid) { + CHECK(COMPILE(ret, "lvalue", node->nd_value)); if (!popped) { ADD_INSN(ret, node, dup); @@ -10707,11 +9589,11 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CONST_BASE)); - ADD_INSN1(ret, node, setconstant, ID2SYM(RNODE_CDECL(node)->nd_vid)); + ADD_INSN1(ret, node, setconstant, ID2SYM(node->nd_vid)); } else { - compile_cpath(ret, iseq, RNODE_CDECL(node)->nd_else); - CHECK(compile_shareable_constant_value(iseq, ret, RNODE_CDECL(node)->shareability, node, RNODE_CDECL(node)->nd_value)); + compile_cpath(ret, iseq, node->nd_else); + CHECK(COMPILE(ret, "lvalue", node->nd_value)); ADD_INSN(ret, node, swap); if (!popped) { @@ -10719,18 +9601,18 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no ADD_INSN(ret, node, swap); } - ADD_INSN1(ret, node, setconstant, ID2SYM(get_node_colon_nd_mid(RNODE_CDECL(node)->nd_else))); + ADD_INSN1(ret, node, setconstant, ID2SYM(node->nd_else->nd_mid)); } break; } case NODE_CVASGN:{ - CHECK(COMPILE(ret, "cvasgn val", RNODE_CVASGN(node)->nd_value)); + CHECK(COMPILE(ret, "cvasgn val", node->nd_value)); if (!popped) { ADD_INSN(ret, node, dup); } ADD_INSN2(ret, node, setclassvariable, - ID2SYM(RNODE_CVASGN(node)->nd_vid), - get_cvar_ic_value(iseq, RNODE_CVASGN(node)->nd_vid)); + ID2SYM(node->nd_vid), + get_cvar_ic_value(iseq,node->nd_vid)); break; } case NODE_OP_ASGN1: @@ -10763,7 +9645,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no CHECK(compile_super(iseq, ret, node, popped, type)); break; case NODE_LIST:{ - CHECK(compile_array(iseq, ret, node, popped, TRUE) >= 0); + CHECK(compile_array(iseq, ret, node, popped) >= 0); break; } case NODE_ZLIST:{ @@ -10772,6 +9654,18 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no } break; } + case NODE_VALUES:{ + const NODE *n = node; + if (popped) { + COMPILE_ERROR(ERROR_ARGS "NODE_VALUES: must not be popped"); + } + while (n) { + CHECK(COMPILE(ret, "values item", n->nd_head)); + n = n->nd_next; + } + ADD_INSN1(ret, node, newarray, INT2FIX(node->nd_alen)); + break; + } case NODE_HASH: CHECK(compile_hash(iseq, ret, node, FALSE, popped) >= 0); break; @@ -10783,18 +9677,18 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; case NODE_LVAR:{ if (!popped) { - compile_lvar(iseq, ret, node, RNODE_LVAR(node)->nd_vid); + compile_lvar(iseq, ret, node, node->nd_vid); } break; } case NODE_DVAR:{ int lv, idx, ls; - debugi("nd_vid", RNODE_DVAR(node)->nd_vid); + debugi("nd_vid", node->nd_vid); if (!popped) { - idx = get_dyna_var_idx(iseq, RNODE_DVAR(node)->nd_vid, &lv, &ls); + idx = get_dyna_var_idx(iseq, node->nd_vid, &lv, &ls); if (idx < 0) { COMPILE_ERROR(ERROR_ARGS "unknown dvar (%"PRIsVALUE")", - rb_id2str(RNODE_DVAR(node)->nd_vid)); + rb_id2str(node->nd_vid)); goto ng; } ADD_GETLOCAL(ret, node, ls - idx, lv); @@ -10802,34 +9696,34 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; } case NODE_GVAR:{ - ADD_INSN1(ret, node, getglobal, ID2SYM(RNODE_GVAR(node)->nd_vid)); + ADD_INSN1(ret, node, getglobal, ID2SYM(node->nd_entry)); if (popped) { ADD_INSN(ret, node, pop); } break; } case NODE_IVAR:{ - debugi("nd_vid", RNODE_IVAR(node)->nd_vid); + debugi("nd_vid", node->nd_vid); if (!popped) { ADD_INSN2(ret, node, getinstancevariable, - ID2SYM(RNODE_IVAR(node)->nd_vid), - get_ivar_ic_value(iseq, RNODE_IVAR(node)->nd_vid)); + ID2SYM(node->nd_vid), + get_ivar_ic_value(iseq,node->nd_vid)); } break; } case NODE_CONST:{ - debugi("nd_vid", RNODE_CONST(node)->nd_vid); + debugi("nd_vid", node->nd_vid); if (ISEQ_COMPILE_DATA(iseq)->option->inline_const_cache) { body->ic_size++; - VALUE segments = rb_ary_new_from_args(1, ID2SYM(RNODE_CONST(node)->nd_vid)); + VALUE segments = rb_ary_new_from_args(1, ID2SYM(node->nd_vid)); ADD_INSN1(ret, node, opt_getconstant_path, segments); RB_OBJ_WRITTEN(iseq, Qundef, segments); } else { ADD_INSN(ret, node, putnil); ADD_INSN1(ret, node, putobject, Qtrue); - ADD_INSN1(ret, node, getconstant, ID2SYM(RNODE_CONST(node)->nd_vid)); + ADD_INSN1(ret, node, getconstant, ID2SYM(node->nd_vid)); } if (popped) { @@ -10840,26 +9734,26 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no case NODE_CVAR:{ if (!popped) { ADD_INSN2(ret, node, getclassvariable, - ID2SYM(RNODE_CVAR(node)->nd_vid), - get_cvar_ic_value(iseq, RNODE_CVAR(node)->nd_vid)); + ID2SYM(node->nd_vid), + get_cvar_ic_value(iseq,node->nd_vid)); } break; } case NODE_NTH_REF:{ if (!popped) { - if (!RNODE_NTH_REF(node)->nd_nth) { + if (!node->nd_nth) { ADD_INSN(ret, node, putnil); break; } ADD_INSN2(ret, node, getspecial, INT2FIX(1) /* '~' */, - INT2FIX(RNODE_NTH_REF(node)->nd_nth << 1)); + INT2FIX(node->nd_nth << 1)); } break; } case NODE_BACK_REF:{ if (!popped) { ADD_INSN2(ret, node, getspecial, INT2FIX(1) /* '~' */, - INT2FIX(0x01 | (RNODE_BACK_REF(node)->nd_nth << 1))); + INT2FIX(0x01 | (node->nd_nth << 1))); } break; } @@ -10868,86 +9762,40 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no case NODE_MATCH3: CHECK(compile_match(iseq, ret, node, popped, type)); break; - case NODE_SYM:{ - if (!popped) { - ADD_INSN1(ret, node, putobject, rb_node_sym_string_val(node)); - } - break; - } - case NODE_LINE:{ - if (!popped) { - ADD_INSN1(ret, node, putobject, rb_node_line_lineno_val(node)); - } - break; - } - case NODE_ENCODING:{ - if (!popped) { - ADD_INSN1(ret, node, putobject, rb_node_encoding_val(node)); - } - break; - } - case NODE_INTEGER:{ - VALUE lit = rb_node_integer_literal_val(node); - debugp_param("integer", lit); - if (!popped) { - ADD_INSN1(ret, node, putobject, lit); - RB_OBJ_WRITTEN(iseq, Qundef, lit); - } - break; - } - case NODE_FLOAT:{ - VALUE lit = rb_node_float_literal_val(node); - debugp_param("float", lit); + case NODE_LIT:{ + debugp_param("lit", node->nd_lit); if (!popped) { - ADD_INSN1(ret, node, putobject, lit); - RB_OBJ_WRITTEN(iseq, Qundef, lit); - } - break; - } - case NODE_RATIONAL:{ - VALUE lit = rb_node_rational_literal_val(node); - debugp_param("rational", lit); - if (!popped) { - ADD_INSN1(ret, node, putobject, lit); - RB_OBJ_WRITTEN(iseq, Qundef, lit); - } - break; - } - case NODE_IMAGINARY:{ - VALUE lit = rb_node_imaginary_literal_val(node); - debugp_param("imaginary", lit); - if (!popped) { - ADD_INSN1(ret, node, putobject, lit); - RB_OBJ_WRITTEN(iseq, Qundef, 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; } - case NODE_FILE: case NODE_STR:{ - debugp_param("nd_lit", get_string_value(node)); + debugp_param("nd_lit", node->nd_lit); if (!popped) { - VALUE lit = get_string_value(node); - switch (ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal) { - case ISEQ_FROZEN_STRING_LITERAL_UNSET: - ADD_INSN1(ret, node, putchilledstring, lit); - RB_OBJ_WRITTEN(iseq, Qundef, lit); - break; - case ISEQ_FROZEN_STRING_LITERAL_DISABLED: + VALUE lit = node->nd_lit; + if (!ISEQ_COMPILE_DATA(iseq)->option->frozen_string_literal) { + lit = rb_fstring(lit); ADD_INSN1(ret, node, putstring, lit); RB_OBJ_WRITTEN(iseq, Qundef, lit); - break; - case ISEQ_FROZEN_STRING_LITERAL_ENABLED: + } + else { if (ISEQ_COMPILE_DATA(iseq)->option->debug_frozen_string_literal || RTEST(ruby_debug)) { VALUE debug_info = rb_ary_new_from_args(2, rb_iseq_path(iseq), INT2FIX(line)); lit = rb_str_dup(lit); - rb_ivar_set(lit, id_debug_created_info, rb_ary_freeze(debug_info)); + rb_ivar_set(lit, id_debug_created_info, rb_obj_freeze(debug_info)); lit = rb_str_freeze(lit); } + else { + lit = rb_fstring(lit); + } ADD_INSN1(ret, node, putobject, lit); RB_OBJ_WRITTEN(iseq, Qundef, lit); - break; - default: - rb_bug("invalid frozen_string_literal"); } } break; @@ -10962,7 +9810,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no } case NODE_XSTR:{ ADD_CALL_RECEIVER(ret, node); - VALUE str = rb_node_str_string_val(node); + VALUE str = rb_fstring(node->nd_lit); ADD_INSN1(ret, node, putobject, str); RB_OBJ_WRITTEN(iseq, Qundef, str); ADD_CALL(ret, node, idBackquote, INT2FIX(1)); @@ -10983,23 +9831,20 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; } case NODE_EVSTR: - CHECK(compile_evstr(iseq, ret, RNODE_EVSTR(node)->nd_body, popped)); + CHECK(compile_evstr(iseq, ret, node->nd_body, popped)); break; - case NODE_REGX:{ - if (!popped) { - VALUE lit = rb_node_regx_string_val(node); - ADD_INSN1(ret, node, putobject, lit); - RB_OBJ_WRITTEN(iseq, Qundef, lit); + case NODE_DREGX:{ + compile_dregx(iseq, ret, node); + + if (popped) { + ADD_INSN(ret, node, pop); } break; } - case NODE_DREGX: - compile_dregx(iseq, ret, node, popped); - break; case NODE_ONCE:{ int ic_index = body->ise_size++; const rb_iseq_t *block_iseq; - block_iseq = NEW_CHILD_ISEQ(RNODE_ONCE(node)->nd_body, make_name_for_block(iseq), ISEQ_TYPE_PLAIN, line); + block_iseq = NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_PLAIN, line); ADD_INSN2(ret, node, once, block_iseq, INT2FIX(ic_index)); RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)block_iseq); @@ -11011,53 +9856,36 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no } case NODE_ARGSCAT:{ if (popped) { - CHECK(COMPILE(ret, "argscat head", RNODE_ARGSCAT(node)->nd_head)); + CHECK(COMPILE(ret, "argscat head", node->nd_head)); ADD_INSN1(ret, node, splatarray, Qfalse); ADD_INSN(ret, node, pop); - CHECK(COMPILE(ret, "argscat body", RNODE_ARGSCAT(node)->nd_body)); + CHECK(COMPILE(ret, "argscat body", node->nd_body)); ADD_INSN1(ret, node, splatarray, Qfalse); ADD_INSN(ret, node, pop); } else { - CHECK(COMPILE(ret, "argscat head", RNODE_ARGSCAT(node)->nd_head)); - const NODE *body_node = RNODE_ARGSCAT(node)->nd_body; - if (nd_type_p(body_node, NODE_LIST)) { - CHECK(compile_array(iseq, ret, body_node, popped, FALSE) >= 0); - } - else { - CHECK(COMPILE(ret, "argscat body", body_node)); - ADD_INSN(ret, node, concattoarray); - } + CHECK(COMPILE(ret, "argscat head", node->nd_head)); + CHECK(COMPILE(ret, "argscat body", node->nd_body)); + ADD_INSN(ret, node, concatarray); } break; } case NODE_ARGSPUSH:{ if (popped) { - CHECK(COMPILE(ret, "argspush head", RNODE_ARGSPUSH(node)->nd_head)); + CHECK(COMPILE(ret, "argspush head", node->nd_head)); ADD_INSN1(ret, node, splatarray, Qfalse); ADD_INSN(ret, node, pop); - CHECK(COMPILE_(ret, "argspush body", RNODE_ARGSPUSH(node)->nd_body, popped)); + CHECK(COMPILE_(ret, "argspush body", node->nd_body, popped)); } else { - CHECK(COMPILE(ret, "argspush head", RNODE_ARGSPUSH(node)->nd_head)); - const NODE *body_node = RNODE_ARGSPUSH(node)->nd_body; - if (keyword_node_p(body_node)) { - CHECK(COMPILE_(ret, "array element", body_node, FALSE)); - ADD_INSN(ret, node, pushtoarraykwsplat); - } - else if (static_literal_node_p(body_node, iseq, false)) { - ADD_INSN1(ret, body_node, putobject, static_literal_value(body_node, iseq)); - ADD_INSN1(ret, node, pushtoarray, INT2FIX(1)); - } - else { - CHECK(COMPILE_(ret, "array element", body_node, FALSE)); - ADD_INSN1(ret, node, pushtoarray, INT2FIX(1)); - } + CHECK(COMPILE(ret, "argspush head", node->nd_head)); + CHECK(compile_array_1(iseq, ret, node->nd_body)); + ADD_INSN(ret, node, concatarray); } break; } case NODE_SPLAT:{ - CHECK(COMPILE(ret, "splat", RNODE_SPLAT(node)->nd_head)); + CHECK(COMPILE(ret, "splat", node->nd_head)); ADD_INSN1(ret, node, splatarray, Qtrue); if (popped) { @@ -11066,8 +9894,8 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; } case NODE_DEFN:{ - ID mid = RNODE_DEFN(node)->nd_mid; - const rb_iseq_t *method_iseq = NEW_ISEQ(RNODE_DEFN(node)->nd_defn, + ID mid = node->nd_mid; + const rb_iseq_t *method_iseq = NEW_ISEQ(node->nd_defn, rb_id2str(mid), ISEQ_TYPE_METHOD, line); @@ -11082,13 +9910,13 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; } case NODE_DEFS:{ - ID mid = RNODE_DEFS(node)->nd_mid; - const rb_iseq_t * singleton_method_iseq = NEW_ISEQ(RNODE_DEFS(node)->nd_defn, + ID mid = node->nd_mid; + const rb_iseq_t * singleton_method_iseq = NEW_ISEQ(node->nd_defn, rb_id2str(mid), ISEQ_TYPE_METHOD, line); debugp_param("defs/iseq", rb_iseqw_new(singleton_method_iseq)); - CHECK(COMPILE(ret, "defs: recv", RNODE_DEFS(node)->nd_recv)); + CHECK(COMPILE(ret, "defs: recv", node->nd_recv)); ADD_INSN2(ret, node, definesmethod, ID2SYM(mid), singleton_method_iseq); RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)singleton_method_iseq); @@ -11100,8 +9928,8 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no case NODE_ALIAS:{ ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE)); - CHECK(COMPILE(ret, "alias arg1", RNODE_ALIAS(node)->nd_1st)); - CHECK(COMPILE(ret, "alias arg2", RNODE_ALIAS(node)->nd_2nd)); + CHECK(COMPILE(ret, "alias arg1", node->nd_1st)); + CHECK(COMPILE(ret, "alias arg2", node->nd_2nd)); ADD_SEND(ret, node, id_core_set_method_alias, INT2FIX(3)); if (popped) { @@ -11111,8 +9939,8 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no } case NODE_VALIAS:{ ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); - ADD_INSN1(ret, node, putobject, ID2SYM(RNODE_VALIAS(node)->nd_alias)); - ADD_INSN1(ret, node, putobject, ID2SYM(RNODE_VALIAS(node)->nd_orig)); + ADD_INSN1(ret, node, putobject, ID2SYM(node->nd_alias)); + ADD_INSN1(ret, node, putobject, ID2SYM(node->nd_orig)); ADD_SEND(ret, node, id_core_set_variable_alias, INT2FIX(2)); if (popped) { @@ -11121,18 +9949,10 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; } case NODE_UNDEF:{ - const rb_parser_ary_t *ary = RNODE_UNDEF(node)->nd_undefs; - - for (long i = 0; i < ary->len; i++) { - ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); - ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE)); - CHECK(COMPILE(ret, "undef arg", ary->data[i])); - ADD_SEND(ret, node, id_core_undef_method, INT2FIX(2)); - - if (i < ary->len - 1) { - ADD_INSN(ret, node, pop); - } - } + ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); + ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_CBASE)); + CHECK(COMPILE(ret, "undef arg", node->nd_undef)); + ADD_SEND(ret, node, id_core_undef_method, INT2FIX(2)); if (popped) { ADD_INSN(ret, node, pop); @@ -11140,15 +9960,15 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; } case NODE_CLASS:{ - const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(RNODE_CLASS(node)->nd_body, - rb_str_freeze(rb_sprintf("<class:%"PRIsVALUE">", rb_id2str(get_node_colon_nd_mid(RNODE_CLASS(node)->nd_cpath)))), + const rb_iseq_t *class_iseq = NEW_CHILD_ISEQ(node->nd_body, + rb_str_freeze(rb_sprintf("<class:%"PRIsVALUE">", rb_id2str(node->nd_cpath->nd_mid))), ISEQ_TYPE_CLASS, line); const int flags = VM_DEFINECLASS_TYPE_CLASS | - (RNODE_CLASS(node)->nd_super ? VM_DEFINECLASS_FLAG_HAS_SUPERCLASS : 0) | - compile_cpath(ret, iseq, RNODE_CLASS(node)->nd_cpath); + (node->nd_super ? VM_DEFINECLASS_FLAG_HAS_SUPERCLASS : 0) | + compile_cpath(ret, iseq, node->nd_cpath); - CHECK(COMPILE(ret, "super", RNODE_CLASS(node)->nd_super)); - ADD_INSN3(ret, node, defineclass, ID2SYM(get_node_colon_nd_mid(RNODE_CLASS(node)->nd_cpath)), class_iseq, INT2FIX(flags)); + CHECK(COMPILE(ret, "super", node->nd_super)); + ADD_INSN3(ret, node, defineclass, ID2SYM(node->nd_cpath->nd_mid), class_iseq, INT2FIX(flags)); RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)class_iseq); if (popped) { @@ -11157,14 +9977,14 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; } case NODE_MODULE:{ - const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(RNODE_MODULE(node)->nd_body, - rb_str_freeze(rb_sprintf("<module:%"PRIsVALUE">", rb_id2str(get_node_colon_nd_mid(RNODE_MODULE(node)->nd_cpath)))), + const rb_iseq_t *module_iseq = NEW_CHILD_ISEQ(node->nd_body, + rb_str_freeze(rb_sprintf("<module:%"PRIsVALUE">", rb_id2str(node->nd_cpath->nd_mid))), ISEQ_TYPE_CLASS, line); const int flags = VM_DEFINECLASS_TYPE_MODULE | - compile_cpath(ret, iseq, RNODE_MODULE(node)->nd_cpath); + compile_cpath(ret, iseq, node->nd_cpath); ADD_INSN (ret, node, putnil); /* dummy */ - ADD_INSN3(ret, node, defineclass, ID2SYM(get_node_colon_nd_mid(RNODE_MODULE(node)->nd_cpath)), module_iseq, INT2FIX(flags)); + ADD_INSN3(ret, node, defineclass, ID2SYM(node->nd_cpath->nd_mid), module_iseq, INT2FIX(flags)); RB_OBJ_WRITTEN(iseq, Qundef, (VALUE)module_iseq); if (popped) { @@ -11174,10 +9994,10 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no } case NODE_SCLASS:{ ID singletonclass; - const rb_iseq_t *singleton_class = NEW_ISEQ(RNODE_SCLASS(node)->nd_body, rb_fstring_lit("singleton class"), + const rb_iseq_t *singleton_class = NEW_ISEQ(node->nd_body, rb_fstring_lit("singleton class"), ISEQ_TYPE_CLASS, line); - CHECK(COMPILE(ret, "sclass#recv", RNODE_SCLASS(node)->nd_recv)); + CHECK(COMPILE(ret, "sclass#recv", node->nd_recv)); ADD_INSN (ret, node, putnil); CONST_ID(singletonclass, "singletonclass"); ADD_INSN3(ret, node, defineclass, @@ -11246,7 +10066,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; case NODE_DEFINED: if (!popped) { - CHECK(compile_defined_expr(iseq, ret, node, Qtrue, false)); + CHECK(compile_defined_expr(iseq, ret, node, Qtrue)); } break; case NODE_POSTEXE:{ @@ -11255,7 +10075,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no */ int is_index = body->ise_size++; struct rb_iseq_new_with_callback_callback_func *ifunc = - rb_iseq_new_with_callback_new_callback(build_postexe_iseq, RNODE_POSTEXE(node)->nd_body); + rb_iseq_new_with_callback_new_callback(build_postexe_iseq, node->nd_body); const rb_iseq_t *once_iseq = new_child_iseq_with_callback(iseq, ifunc, rb_fstring(make_name_for_block(iseq)), iseq, ISEQ_TYPE_BLOCK, line); @@ -11286,7 +10106,7 @@ iseq_compile_each0(rb_iseq_t *iseq, LINK_ANCHOR *const ret, const NODE *const no break; case NODE_LAMBDA:{ /* compile same as lambda{...} */ - const rb_iseq_t *block = NEW_CHILD_ISEQ(RNODE_LAMBDA(node)->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line); + const rb_iseq_t *block = NEW_CHILD_ISEQ(node->nd_body, make_name_for_block(iseq), ISEQ_TYPE_BLOCK, line); VALUE argc = INT2FIX(0); ADD_INSN1(ret, node, putspecialobject, INT2FIX(VM_SPECIAL_OBJECT_VMCORE)); @@ -11471,7 +10291,7 @@ dump_disasm_list_with_cursor(const LINK_ELEMENT *link, const LINK_ELEMENT *curr, case ISEQ_ELEMENT_LABEL: { lobj = (LABEL *)link; - printf(LABEL_FORMAT" [sp: %d, unremovable: %d, refcnt: %d]%s\n", lobj->label_no, lobj->sp, lobj->unremovable, lobj->refcnt, + printf(LABEL_FORMAT" [sp: %d]%s\n", lobj->label_no, lobj->sp, dest == lobj ? " <---" : ""); break; } @@ -11489,7 +10309,7 @@ dump_disasm_list_with_cursor(const LINK_ELEMENT *link, const LINK_ELEMENT *curr, } default: /* ignore */ - rb_raise(rb_eSyntaxError, "dump_disasm_list error: %d\n", (int)link->type); + rb_raise(rb_eSyntaxError, "dump_disasm_list error: %ld\n", FIX2LONG(link->type)); } link = link->next; } @@ -11497,12 +10317,6 @@ dump_disasm_list_with_cursor(const LINK_ELEMENT *link, const LINK_ELEMENT *curr, fflush(stdout); } -int -rb_insn_len(VALUE insn) -{ - return insn_len(insn); -} - const char * rb_insns_name(int i) { @@ -11517,7 +10331,7 @@ rb_insns_name_array(void) for (i = 0; i < VM_INSTRUCTION_SIZE; i++) { rb_ary_push(ary, rb_fstring_cstr(insn_name(i))); } - return rb_ary_freeze(ary); + return rb_obj_freeze(ary); } static LABEL * @@ -11666,7 +10480,6 @@ iseq_build_callinfo_from_hash(rb_iseq_t *iseq, VALUE op) size_t n = rb_callinfo_kwarg_bytes(len); kw_arg = xmalloc(n); - kw_arg->references = 0; kw_arg->keyword_len = len; for (i = 0; i < len; i++) { VALUE kw = RARRAY_AREF(vkw_arg, i); @@ -11692,7 +10505,6 @@ event_name_to_flag(VALUE sym) CHECK_EVENT(RUBY_EVENT_RETURN); CHECK_EVENT(RUBY_EVENT_B_CALL); CHECK_EVENT(RUBY_EVENT_B_RETURN); - CHECK_EVENT(RUBY_EVENT_RESCUE); #undef CHECK_EVENT return RUBY_EVENT_NONE; } @@ -11703,7 +10515,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor, { /* TODO: body should be frozen */ long i, len = RARRAY_LEN(body); - struct st_table *labels_table = RTYPEDDATA_DATA(labels_wrapper); + struct st_table *labels_table = DATA_PTR(labels_wrapper); int j; int line_no = 0, node_id = -1, insn_idx = 0; int ret = COMPILE_OK; @@ -11763,8 +10575,9 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor, argv = compile_data_calloc2(iseq, sizeof(VALUE), argc); // add element before operand setup to make GC root + NODE dummy_line_node = generate_dummy_line_node(line_no, node_id); ADD_ELEM(anchor, - (LINK_ELEMENT*)new_insn_core(iseq, line_no, node_id, + (LINK_ELEMENT*)new_insn_core(iseq, &dummy_line_node, (enum ruby_vminsn_type)insn_id, argc, argv)); for (j=0; j<argc; j++) { @@ -11872,8 +10685,9 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor, } } else { + NODE dummy_line_node = generate_dummy_line_node(line_no, node_id); ADD_ELEM(anchor, - (LINK_ELEMENT*)new_insn_core(iseq, line_no, node_id, + (LINK_ELEMENT*)new_insn_core(iseq, &dummy_line_node, (enum ruby_vminsn_type)insn_id, argc, NULL)); } } @@ -11881,8 +10695,7 @@ iseq_build_from_ary_body(rb_iseq_t *iseq, LINK_ANCHOR *const anchor, rb_raise(rb_eTypeError, "unexpected object for instruction"); } } - RTYPEDDATA_DATA(labels_wrapper) = 0; - RB_GC_GUARD(labels_wrapper); + DATA_PTR(labels_wrapper) = 0; validate_labels(iseq, labels_table); if (!ret) return ret; return iseq_setup(iseq, anchor); @@ -11966,7 +10779,7 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords) rb_raise(rb_eTypeError, "keyword default has unsupported len %+"PRIsVALUE, key); } ids[i] = SYM2ID(sym); - RB_OBJ_WRITE(iseq, &dvs[j], default_val); + dvs[j] = default_val; } keyword->table = ids; @@ -11976,13 +10789,13 @@ iseq_build_kw(rb_iseq_t *iseq, VALUE params, VALUE keywords) } static void -iseq_insn_each_object_mark_and_pin(VALUE obj, VALUE _) +iseq_insn_each_object_mark(VALUE *obj_ptr, VALUE _) { - rb_gc_mark(obj); + rb_gc_mark(*obj_ptr); } void -rb_iseq_mark_and_pin_insn_storage(struct iseq_compile_data_storage *storage) +rb_iseq_mark_insn_storage(struct iseq_compile_data_storage *storage) { INSN *iobj = 0; size_t size = sizeof(INSN); @@ -12007,22 +10820,13 @@ rb_iseq_mark_and_pin_insn_storage(struct iseq_compile_data_storage *storage) iobj = (INSN *)&storage->buff[pos]; if (iobj->operands) { - iseq_insn_each_markable_object(iobj, iseq_insn_each_object_mark_and_pin, (VALUE)0); + iseq_insn_each_markable_object(iobj, iseq_insn_each_object_mark, (VALUE)0); } pos += (int)size; } } } -static const rb_data_type_t labels_wrapper_type = { - .wrap_struct_name = "compiler/labels_wrapper", - .function = { - .dmark = (RUBY_DATA_FUNC)rb_mark_set, - .dfree = (RUBY_DATA_FUNC)st_free_table, - }, - .flags = RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_WB_PROTECTED, -}; - void rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params, VALUE exception, VALUE body) @@ -12032,7 +10836,7 @@ rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params, unsigned int arg_size, local_size, stack_max; ID *tbl; struct st_table *labels_table = st_init_numtable(); - VALUE labels_wrapper = TypedData_Wrap_Struct(0, &labels_wrapper_type, labels_table); + VALUE labels_wrapper = Data_Wrap_Struct(0, rb_mark_set, st_free_table, labels_table); VALUE arg_opt_labels = rb_hash_aref(params, SYM(opt)); VALUE keywords = rb_hash_aref(params, SYM(keyword)); VALUE sym_arg_rest = ID2SYM(rb_intern_const("#arg_rest")); @@ -12114,10 +10918,6 @@ rb_iseq_build_from_ary(rb_iseq_t *iseq, VALUE misc, VALUE locals, VALUE params, ISEQ_BODY(iseq)->param.flags.ambiguous_param0 = TRUE; } - if (Qtrue == rb_hash_aref(params, SYM(use_block))) { - ISEQ_BODY(iseq)->param.flags.use_block = TRUE; - } - if (int_param(&i, params, SYM(kwrest))) { struct rb_iseq_param_keyword *keyword = (struct rb_iseq_param_keyword *)ISEQ_BODY(iseq)->param.keyword; if (keyword == NULL) { @@ -12193,7 +10993,7 @@ rb_local_defined(ID id, const rb_iseq_t *iseq) #define IBF_ISEQ_ENABLE_LOCAL_BUFFER 0 #endif -typedef uint32_t ibf_offset_t; +typedef unsigned int ibf_offset_t; #define IBF_OFFSET(ptr) ((ibf_offset_t)(VALUE)(ptr)) #define IBF_MAJOR_VERSION ISEQ_MAJOR_VERSION @@ -12204,27 +11004,17 @@ typedef uint32_t ibf_offset_t; #define IBF_MINOR_VERSION ISEQ_MINOR_VERSION #endif -static const char IBF_ENDIAN_MARK = -#ifdef WORDS_BIGENDIAN - 'b' -#else - 'l' -#endif - ; - struct ibf_header { char magic[4]; /* YARB */ - uint32_t major_version; - uint32_t minor_version; - uint32_t size; - uint32_t extra_size; + unsigned int major_version; + unsigned int minor_version; + unsigned int size; + unsigned int extra_size; - uint32_t iseq_list_size; - uint32_t global_object_list_size; + unsigned int iseq_list_size; + unsigned int global_object_list_size; ibf_offset_t iseq_list_offset; ibf_offset_t global_object_list_offset; - uint8_t endian; - uint8_t wordsize; /* assume no 2048-bit CPU */ }; struct ibf_dump_buffer { @@ -12259,7 +11049,7 @@ struct ibf_load { struct pinned_list { long size; - VALUE buffer[1]; + VALUE * buffer; }; static void @@ -12274,14 +11064,25 @@ pinned_list_mark(void *ptr) } } +static void +pinned_list_free(void *ptr) +{ + struct pinned_list *list = (struct pinned_list *)ptr; + xfree(list->buffer); + xfree(ptr); +} + +static size_t +pinned_list_memsize(const void *ptr) +{ + struct pinned_list *list = (struct pinned_list *)ptr; + return sizeof(struct pinned_list) + (list->size * sizeof(VALUE *)); +} + static const rb_data_type_t pinned_list_type = { "pinned_list", - { - pinned_list_mark, - RUBY_DEFAULT_FREE, - NULL, // No external memory to report, - }, - 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE + {pinned_list_mark, pinned_list_free, pinned_list_memsize,}, + 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY }; static VALUE @@ -12315,10 +11116,13 @@ pinned_list_store(VALUE list, long offset, VALUE object) static VALUE pinned_list_new(long size) { - size_t memsize = offsetof(struct pinned_list, buffer) + size * sizeof(VALUE); - VALUE obj_list = rb_data_typed_object_zalloc(0, memsize, &pinned_list_type); - struct pinned_list * ptr = RTYPEDDATA_GET_DATA(obj_list); + struct pinned_list * ptr; + VALUE obj_list = + TypedData_Make_Struct(0, struct pinned_list, &pinned_list_type, ptr); + + ptr->buffer = xcalloc(size, sizeof(VALUE)); ptr->size = size; + return obj_list; } @@ -12467,10 +11271,6 @@ ibf_load_id(const struct ibf_load *load, const ID id_index) return 0; } VALUE sym = ibf_load_object(load, id_index); - if (rb_integer_type_p(sym)) { - /* Load hidden local variables as indexes */ - return NUM2ULONG(sym); - } return rb_sym2id(sym); } @@ -12670,7 +11470,7 @@ ibf_dump_code(struct ibf_dump *dump, const rb_iseq_t *iseq) ibf_dump_write_small_value(dump, wv); skip_wv:; } - RUBY_ASSERT(insn_len(insn) == op_index+1); + assert(insn_len(insn) == op_index+1); } return offset; @@ -12835,8 +11635,8 @@ ibf_load_code(const struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t bytecod } } - RUBY_ASSERT(code_index == iseq_size); - RUBY_ASSERT(reading_pos == bytecode_offset + bytecode_size); + assert(code_index == iseq_size); + assert(reading_pos == bytecode_offset + bytecode_size); return code; } @@ -12899,7 +11699,7 @@ ibf_load_param_keyword(const struct ibf_load *load, ibf_offset_t param_keyword_o struct rb_iseq_param_keyword *kw = IBF_R(param_keyword_offset, struct rb_iseq_param_keyword, 1); ID *ids = IBF_R(kw->table, ID, kw->num); int dv_num = kw->num - kw->required_num; - VALUE *dvs = dv_num ? IBF_R(kw->default_values, VALUE, dv_num) : NULL; + VALUE *dvs = IBF_R(kw->default_values, VALUE, dv_num); int i; for (i=0; i<kw->num; i++) { @@ -12994,12 +11794,7 @@ ibf_dump_local_table(struct ibf_dump *dump, const rb_iseq_t *iseq) int i; for (i=0; i<size; i++) { - VALUE v = ibf_dump_id(dump, body->local_table[i]); - if (v == 0) { - /* Dump hidden local variables as indexes, so load_from_binary will work with them */ - v = ibf_dump_object(dump, ULONG2NUM(body->local_table[i])); - } - table[i] = v; + table[i] = ibf_dump_id(dump, body->local_table[i]); } IBF_W_ALIGN(ID); @@ -13120,34 +11915,13 @@ ibf_dump_ci_entries(struct ibf_dump *dump, const rb_iseq_t *iseq) return offset; } -struct outer_variable_pair { - ID id; - VALUE name; - VALUE val; -}; - -struct outer_variable_list { - size_t num; - struct outer_variable_pair pairs[1]; -}; - static enum rb_id_table_iterator_result -store_outer_variable(ID id, VALUE val, void *dump) +dump_outer_variable(ID id, VALUE val, void *dump) { - struct outer_variable_list *ovlist = dump; - struct outer_variable_pair *pair = &ovlist->pairs[ovlist->num++]; - pair->id = id; - pair->name = rb_id2str(id); - pair->val = val; - return ID_TABLE_CONTINUE; -} + ibf_dump_write_small_value(dump, ibf_dump_id(dump, id)); + ibf_dump_write_small_value(dump, val); -static int -outer_variable_cmp(const void *a, const void *b, void *arg) -{ - const struct outer_variable_pair *ap = (const struct outer_variable_pair *)a; - const struct outer_variable_pair *bp = (const struct outer_variable_pair *)b; - return rb_str_cmp(ap->name, bp->name); + return ID_TABLE_CONTINUE; } static ibf_offset_t @@ -13157,24 +11931,12 @@ ibf_dump_outer_variables(struct ibf_dump *dump, const rb_iseq_t *iseq) ibf_offset_t offset = ibf_dump_pos(dump); - size_t size = ovs ? rb_id_table_size(ovs) : 0; - ibf_dump_write_small_value(dump, (VALUE)size); - if (size > 0) { - VALUE buff; - size_t buffsize = - rb_size_mul_add_or_raise(sizeof(struct outer_variable_pair), size, - offsetof(struct outer_variable_list, pairs), - rb_eArgError); - struct outer_variable_list *ovlist = RB_ALLOCV(buff, buffsize); - ovlist->num = 0; - rb_id_table_foreach(ovs, store_outer_variable, ovlist); - ruby_qsort(ovlist->pairs, size, sizeof(struct outer_variable_pair), outer_variable_cmp, NULL); - for (size_t i = 0; i < size; ++i) { - ID id = ovlist->pairs[i].id; - ID val = ovlist->pairs[i].val; - ibf_dump_write_small_value(dump, ibf_dump_id(dump, id)); - ibf_dump_write_small_value(dump, val); - } + if (ovs) { + ibf_dump_write_small_value(dump, (VALUE)rb_id_table_size(ovs)); + rb_id_table_foreach(ovs, dump_outer_variable, (void *)dump); + } + else { + ibf_dump_write_small_value(dump, (VALUE)0); } return offset; @@ -13205,7 +11967,6 @@ ibf_load_ci_entries(const struct ibf_load *load, int kwlen = (int)ibf_load_small_value(load, &reading_pos); if (kwlen > 0) { kwarg = rb_xmalloc_mul_add(kwlen, sizeof(VALUE), sizeof(struct rb_callinfo_kwarg)); - kwarg->references = 0; kwarg->keyword_len = kwlen; for (int j=0; j<kwlen; j++) { VALUE keyword = ibf_load_small_value(load, &reading_pos); @@ -13251,7 +12012,7 @@ ibf_load_outer_variables(const struct ibf_load * load, ibf_offset_t outer_variab static ibf_offset_t ibf_dump_iseq_each(struct ibf_dump *dump, const rb_iseq_t *iseq) { - RUBY_ASSERT(dump->current_buffer == &dump->global_buffer); + assert(dump->current_buffer == &dump->global_buffer); unsigned int *positions; @@ -13310,11 +12071,7 @@ ibf_dump_iseq_each(struct ibf_dump *dump, const rb_iseq_t *iseq) (body->param.flags.has_block << 6) | (body->param.flags.ambiguous_param0 << 7) | (body->param.flags.accepts_no_kwarg << 8) | - (body->param.flags.ruby2_keywords << 9) | - (body->param.flags.anon_rest << 10) | - (body->param.flags.anon_kwrest << 11) | - (body->param.flags.use_block << 12) | - (body->param.flags.forwardable << 13) ; + (body->param.flags.ruby2_keywords << 9); #if IBF_ISEQ_ENABLE_LOCAL_BUFFER # define IBF_BODY_OFFSET(x) (x) @@ -13364,8 +12121,8 @@ ibf_dump_iseq_each(struct ibf_dump *dump, const rb_iseq_t *iseq) ibf_dump_write_small_value(dump, body->ic_size); ibf_dump_write_small_value(dump, body->ci_size); ibf_dump_write_small_value(dump, body->stack_max); - ibf_dump_write_small_value(dump, body->builtin_attrs); - ibf_dump_write_small_value(dump, body->prism ? 1 : 0); + ibf_dump_write_small_value(dump, body->catch_except_p); + ibf_dump_write_small_value(dump, body->builtin_inline_p); #undef IBF_BODY_OFFSET @@ -13477,8 +12234,8 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset) const unsigned int ci_size = (unsigned int)ibf_load_small_value(load, &reading_pos); const unsigned int stack_max = (unsigned int)ibf_load_small_value(load, &reading_pos); - const unsigned int builtin_attrs = (unsigned int)ibf_load_small_value(load, &reading_pos); - const bool prism = (bool)ibf_load_small_value(load, &reading_pos); + const char catch_except_p = (char)ibf_load_small_value(load, &reading_pos); + const bool builtin_inline_p = (bool)ibf_load_small_value(load, &reading_pos); // setup fname and dummy frame VALUE path = ibf_load_object(load, location_pathobj_index); @@ -13528,10 +12285,6 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset) load_body->param.flags.ambiguous_param0 = (param_flags >> 7) & 1; load_body->param.flags.accepts_no_kwarg = (param_flags >> 8) & 1; load_body->param.flags.ruby2_keywords = (param_flags >> 9) & 1; - load_body->param.flags.anon_rest = (param_flags >> 10) & 1; - load_body->param.flags.anon_kwrest = (param_flags >> 11) & 1; - load_body->param.flags.use_block = (param_flags >> 12) & 1; - load_body->param.flags.forwardable = (param_flags >> 13) & 1; load_body->param.size = param_size; load_body->param.lead_num = param_lead_num; load_body->param.opt_num = param_opt_num; @@ -13554,20 +12307,14 @@ ibf_load_iseq_each(struct ibf_load *load, rb_iseq_t *iseq, ibf_offset_t offset) load_body->location.code_location.beg_pos.column = location_code_location_beg_pos_column; load_body->location.code_location.end_pos.lineno = location_code_location_end_pos_lineno; load_body->location.code_location.end_pos.column = location_code_location_end_pos_column; - load_body->builtin_attrs = builtin_attrs; - load_body->prism = prism; + load_body->catch_except_p = catch_except_p; + load_body->builtin_inline_p = builtin_inline_p; load_body->ivc_size = ivc_size; load_body->icvarc_size = icvarc_size; load_body->ise_size = ise_size; load_body->ic_size = ic_size; - - if (ISEQ_IS_SIZE(load_body)) { - load_body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, ISEQ_IS_SIZE(load_body)); - } - else { - load_body->is_entries = NULL; - } + load_body->is_entries = ZALLOC_N(union iseq_inline_storage_entry, ISEQ_IS_SIZE(load_body)); ibf_load_ci_entries(load, ci_entries_offset, ci_size, &load_body->call_data); load_body->outer_variables = ibf_load_outer_variables(load, outer_variables_offset); load_body->param.opt_table = ibf_load_param_opt_table(load, param_opt_table_offset, param_opt_num); @@ -13840,7 +12587,7 @@ ibf_load_object_string(const struct ibf_load *load, const struct ibf_object_head VALUE str; if (header->frozen && !header->internal) { - str = rb_enc_literal_str(ptr, len, rb_enc_from_index(encindex)); + str = rb_enc_interned_str(ptr, len, rb_enc_from_index(encindex)); } else { str = rb_enc_str_new(ptr, len, rb_enc_from_index(encindex)); @@ -13905,7 +12652,7 @@ ibf_load_object_array(const struct ibf_load *load, const struct ibf_object_heade rb_ary_push(ary, ibf_load_object(load, index)); } - if (header->frozen) rb_ary_freeze(ary); + if (header->frozen) rb_obj_freeze(ary); return ary; } @@ -14007,12 +12754,8 @@ ibf_load_object_bignum(const struct ibf_load *load, const struct ibf_object_head const struct ibf_object_bignum *bignum = IBF_OBJBODY(struct ibf_object_bignum, offset); int sign = bignum->slen > 0; ssize_t len = sign > 0 ? bignum->slen : -1 * bignum->slen; - const int big_unpack_flags = /* c.f. rb_big_unpack() */ - INTEGER_PACK_LSWORD_FIRST | - INTEGER_PACK_NATIVE_BYTE_ORDER; - VALUE obj = rb_integer_unpack(bignum->digits, len, sizeof(BDIGIT), 0, - big_unpack_flags | - (sign == 0 ? INTEGER_PACK_NEGATIVE : 0)); + VALUE obj = rb_integer_unpack(bignum->digits, len * 2, 2, 0, + INTEGER_PACK_LITTLE_ENDIAN | (sign == 0 ? INTEGER_PACK_NEGATIVE : 0)); if (header->internal) rb_obj_hide(obj); if (header->frozen) rb_obj_freeze(obj); return obj; @@ -14104,7 +12847,7 @@ ibf_load_object_symbol(const struct ibf_load *load, const struct ibf_object_head } typedef void (*ibf_dump_object_function)(struct ibf_dump *dump, VALUE obj); -static const ibf_dump_object_function dump_object_functions[RUBY_T_MASK+1] = { +static ibf_dump_object_function dump_object_functions[RUBY_T_MASK+1] = { ibf_dump_object_unsupported, /* T_NONE */ ibf_dump_object_unsupported, /* T_OBJECT */ ibf_dump_object_class, /* T_CLASS */ @@ -14197,7 +12940,7 @@ ibf_dump_object_object(struct ibf_dump *dump, VALUE obj) } typedef VALUE (*ibf_load_object_function)(const struct ibf_load *load, const struct ibf_object_header *header, ibf_offset_t offset); -static const ibf_load_object_function load_object_functions[RUBY_T_MASK+1] = { +static ibf_load_object_function load_object_functions[RUBY_T_MASK+1] = { ibf_load_object_unsupported, /* T_NONE */ ibf_load_object_unsupported, /* T_OBJECT */ ibf_load_object_class, /* T_CLASS */ @@ -14340,13 +13083,14 @@ ibf_dump_free(void *ptr) st_free_table(dump->iseq_table); dump->iseq_table = 0; } + ruby_xfree(dump); } static size_t ibf_dump_memsize(const void *ptr) { struct ibf_dump *dump = (struct ibf_dump *)ptr; - size_t size = 0; + size_t size = sizeof(*dump); if (dump->iseq_table) size += st_memsize(dump->iseq_table); if (dump->global_buffer.obj_table) size += st_memsize(dump->global_buffer.obj_table); return size; @@ -14355,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_FREE_IMMEDIATELY | RUBY_TYPED_EMBEDDABLE + 0, 0, RUBY_TYPED_FREE_IMMEDIATELY }; static void @@ -14391,6 +13135,7 @@ rb_iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt) ibf_dump_setup(dump, dump_obj); ibf_dump_write(dump, &header, sizeof(header)); + ibf_dump_write(dump, RUBY_PLATFORM, strlen(RUBY_PLATFORM) + 1); ibf_dump_iseq(dump, iseq); header.magic[0] = 'Y'; /* YARB */ @@ -14399,8 +13144,6 @@ rb_iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt) header.magic[3] = 'B'; header.major_version = IBF_MAJOR_VERSION; header.minor_version = IBF_MINOR_VERSION; - header.endian = IBF_ENDIAN_MARK; - header.wordsize = (uint8_t)SIZEOF_VALUE; ibf_dump_iseq_list(dump, &header); ibf_dump_object_list(dump, &header.global_object_list_offset, &header.global_object_list_size); header.size = ibf_dump_pos(dump); @@ -14418,6 +13161,8 @@ rb_iseq_ibf_dump(const rb_iseq_t *iseq, VALUE opt) ibf_dump_overwrite(dump, &header, sizeof(header), 0); str = dump->global_buffer.str; + ibf_dump_free(dump); + DATA_PTR(dump_obj) = NULL; RB_GC_GUARD(dump_obj); return str; } @@ -14448,7 +13193,7 @@ rb_ibf_load_iseq_complete(rb_iseq_t *iseq) } #if USE_LAZY_LOAD -const rb_iseq_t * +MJIT_FUNC_EXPORTED const rb_iseq_t * rb_iseq_complete(const rb_iseq_t *iseq) { rb_ibf_load_iseq_complete((rb_iseq_t *)iseq); @@ -14491,12 +13236,16 @@ ibf_load_iseq(const struct ibf_load *load, const rb_iseq_t *index_iseq) #endif pinned_list_store(load->iseq_list, iseq_index, (VALUE)iseq); - if (!USE_LAZY_LOAD || GET_VM()->builtin_function_table) { +#if !USE_LAZY_LOAD #if IBF_ISEQ_DEBUG - fprintf(stderr, "ibf_load_iseq: loading iseq=%p\n", (void *)iseq); + fprintf(stderr, "ibf_load_iseq: loading iseq=%p\n", (void *)iseq); #endif + rb_ibf_load_iseq_complete(iseq); +#else + if (GET_VM()->builtin_function_table) { rb_ibf_load_iseq_complete(iseq); } +#endif /* !USE_LAZY_LOAD */ #if IBF_ISEQ_DEBUG fprintf(stderr, "ibf_load_iseq: iseq=%p loaded %p\n", @@ -14510,39 +13259,35 @@ ibf_load_iseq(const struct ibf_load *load, const rb_iseq_t *index_iseq) static void ibf_load_setup_bytes(struct ibf_load *load, VALUE loader_obj, const char *bytes, size_t size) { - struct ibf_header *header = (struct ibf_header *)bytes; load->loader_obj = loader_obj; load->global_buffer.buff = bytes; - load->header = header; - load->global_buffer.size = header->size; - load->global_buffer.obj_list_offset = header->global_object_list_offset; - load->global_buffer.obj_list_size = header->global_object_list_size; - RB_OBJ_WRITE(loader_obj, &load->iseq_list, pinned_list_new(header->iseq_list_size)); + load->header = (struct ibf_header *)load->global_buffer.buff; + load->global_buffer.size = load->header->size; + load->global_buffer.obj_list_offset = load->header->global_object_list_offset; + load->global_buffer.obj_list_size = load->header->global_object_list_size; + RB_OBJ_WRITE(loader_obj, &load->iseq_list, pinned_list_new(load->header->iseq_list_size)); RB_OBJ_WRITE(loader_obj, &load->global_buffer.obj_list, pinned_list_new(load->global_buffer.obj_list_size)); load->iseq = NULL; load->current_buffer = &load->global_buffer; - if (size < header->size) { + if (size < load->header->size) { rb_raise(rb_eRuntimeError, "broken binary format"); } - if (strncmp(header->magic, "YARB", 4) != 0) { + if (strncmp(load->header->magic, "YARB", 4) != 0) { rb_raise(rb_eRuntimeError, "unknown binary format"); } - if (header->major_version != IBF_MAJOR_VERSION || - header->minor_version != IBF_MINOR_VERSION) { + if (load->header->major_version != IBF_MAJOR_VERSION || + load->header->minor_version != IBF_MINOR_VERSION) { rb_raise(rb_eRuntimeError, "unmatched version file (%u.%u for %u.%u)", - header->major_version, header->minor_version, IBF_MAJOR_VERSION, IBF_MINOR_VERSION); - } - if (header->endian != IBF_ENDIAN_MARK) { - rb_raise(rb_eRuntimeError, "unmatched endian: %c", header->endian); + load->header->major_version, load->header->minor_version, IBF_MAJOR_VERSION, IBF_MINOR_VERSION); } - if (header->wordsize != SIZEOF_VALUE) { - rb_raise(rb_eRuntimeError, "unmatched word size: %d", header->wordsize); + if (strcmp(load->global_buffer.buff + sizeof(struct ibf_header), RUBY_PLATFORM) != 0) { + rb_raise(rb_eRuntimeError, "unmatched platform"); } - if (header->iseq_list_offset % RUBY_ALIGNOF(ibf_offset_t)) { + if (load->header->iseq_list_offset % RUBY_ALIGNOF(ibf_offset_t)) { rb_raise(rb_eArgError, "unaligned iseq list offset: %u", - header->iseq_list_offset); + load->header->iseq_list_offset); } if (load->global_buffer.obj_list_offset % RUBY_ALIGNOF(ibf_offset_t)) { rb_raise(rb_eArgError, "unaligned object list offset: %u", @@ -14553,15 +13298,13 @@ ibf_load_setup_bytes(struct ibf_load *load, VALUE loader_obj, const char *bytes, static void ibf_load_setup(struct ibf_load *load, VALUE loader_obj, VALUE str) { - StringValue(str); - if (RSTRING_LENINT(str) < (int)sizeof(struct ibf_header)) { rb_raise(rb_eRuntimeError, "broken binary format"); } - if (USE_LAZY_LOAD) { - str = rb_str_new(RSTRING_PTR(str), RSTRING_LEN(str)); - } +#if USE_LAZY_LOAD + str = rb_str_new(RSTRING_PTR(str), RSTRING_LEN(str)); +#endif ibf_load_setup_bytes(load, loader_obj, StringValuePtr(str), RSTRING_LEN(str)); RB_OBJ_WRITE(loader_obj, &load->str, str); @@ -14635,5 +13378,3 @@ rb_iseq_ibf_load_extra_data(VALUE str) RB_GC_GUARD(loader_obj); return extra_str; } - -#include "prism_compile.c" @@ -24,7 +24,6 @@ #include "internal/numeric.h" #include "internal/object.h" #include "internal/rational.h" -#include "internal/string.h" #include "ruby_assert.h" #define ZERO INT2FIX(0) @@ -392,12 +391,11 @@ k_numeric_p(VALUE x) inline static VALUE nucomp_s_new_internal(VALUE klass, VALUE real, VALUE imag) { - NEWOBJ_OF(obj, struct RComplex, klass, - T_COMPLEX | (RGENGC_WB_PROTECTED_COMPLEX ? FL_WB_PROTECTED : 0), sizeof(struct RComplex), 0); + NEWOBJ_OF(obj, struct RComplex, klass, T_COMPLEX | (RGENGC_WB_PROTECTED_COMPLEX ? FL_WB_PROTECTED : 0)); RCOMPLEX_SET_REAL(obj, real); RCOMPLEX_SET_IMAG(obj, imag); - OBJ_FREEZE((VALUE)obj); + OBJ_FREEZE_RAW((VALUE)obj); return (VALUE)obj; } @@ -411,15 +409,15 @@ nucomp_s_alloc(VALUE klass) inline static VALUE f_complex_new_bang1(VALUE klass, VALUE x) { - RUBY_ASSERT(!RB_TYPE_P(x, T_COMPLEX)); + assert(!RB_TYPE_P(x, T_COMPLEX)); return nucomp_s_new_internal(klass, x, ZERO); } inline static VALUE f_complex_new_bang2(VALUE klass, VALUE x, VALUE y) { - RUBY_ASSERT(!RB_TYPE_P(x, T_COMPLEX)); - RUBY_ASSERT(!RB_TYPE_P(y, T_COMPLEX)); + assert(!RB_TYPE_P(x, T_COMPLEX)); + assert(!RB_TYPE_P(y, T_COMPLEX)); return nucomp_s_new_internal(klass, x, y); } @@ -432,7 +430,7 @@ nucomp_real_check(VALUE num) !RB_TYPE_P(num, T_RATIONAL)) { if (RB_TYPE_P(num, T_COMPLEX) && nucomp_real_p(num)) { VALUE real = RCOMPLEX(num)->real; - RUBY_ASSERT(!RB_TYPE_P(real, T_COMPLEX)); + assert(!RB_TYPE_P(real, T_COMPLEX)); return real; } if (!k_numeric_p(num) || !f_real_p(num)) @@ -475,19 +473,12 @@ nucomp_s_canonicalize_internal(VALUE klass, VALUE real, VALUE imag) /* * call-seq: - * Complex.rect(real, imag = 0) -> complex + * Complex.rect(real[, imag]) -> complex + * Complex.rectangular(real[, imag]) -> complex * - * Returns a new \Complex object formed from the arguments, - * each of which must be an instance of Numeric, - * or an instance of one of its subclasses: - * \Complex, Float, Integer, Rational; - * see {Rectangular Coordinates}[rdoc-ref:Complex@Rectangular+Coordinates]: + * Returns a complex object which denotes the given rectangular form. * - * Complex.rect(3) # => (3+0i) - * Complex.rect(3, Math::PI) # => (3+3.141592653589793i) - * Complex.rect(-3, -Math::PI) # => (-3-3.141592653589793i) - * - * \Complex.rectangular is an alias for \Complex.rect. + * Complex.rectangular(1, 2) #=> (1+2i) */ static VALUE nucomp_s_new(int argc, VALUE *argv, VALUE klass) @@ -524,54 +515,39 @@ static VALUE nucomp_s_convert(int argc, VALUE *argv, VALUE klass); /* * call-seq: - * Complex(real, imag = 0, exception: true) -> complex or nil - * Complex(s, exception: true) -> complex or nil - * - * Returns a new \Complex object if the arguments are valid; - * otherwise raises an exception if +exception+ is +true+; - * otherwise returns +nil+. - * - * With Numeric arguments +real+ and +imag+, - * returns <tt>Complex.rect(real, imag)</tt> if the arguments are valid. - * - * With string argument +s+, returns a new \Complex object if the argument is valid; - * the string may have: - * - * - One or two numeric substrings, - * each of which specifies a Complex, Float, Integer, Numeric, or Rational value, - * specifying {rectangular coordinates}[rdoc-ref:Complex@Rectangular+Coordinates]: - * - * - Sign-separated real and imaginary numeric substrings - * (with trailing character <tt>'i'</tt>): - * - * Complex('1+2i') # => (1+2i) - * Complex('+1+2i') # => (1+2i) - * Complex('+1-2i') # => (1-2i) - * Complex('-1+2i') # => (-1+2i) - * Complex('-1-2i') # => (-1-2i) - * - * - Real-only numeric string (without trailing character <tt>'i'</tt>): - * - * Complex('1') # => (1+0i) - * Complex('+1') # => (1+0i) - * Complex('-1') # => (-1+0i) - * - * - Imaginary-only numeric string (with trailing character <tt>'i'</tt>): - * - * Complex('1i') # => (0+1i) - * Complex('+1i') # => (0+1i) - * Complex('-1i') # => (0-1i) - * - * - At-sign separated real and imaginary rational substrings, - * each of which specifies a Rational value, - * specifying {polar coordinates}[rdoc-ref:Complex@Polar+Coordinates]: - * - * Complex('1/2@3/4') # => (0.36584443443691045+0.34081938001166706i) - * Complex('+1/2@+3/4') # => (0.36584443443691045+0.34081938001166706i) - * Complex('+1/2@-3/4') # => (0.36584443443691045-0.34081938001166706i) - * Complex('-1/2@+3/4') # => (-0.36584443443691045-0.34081938001166706i) - * Complex('-1/2@-3/4') # => (-0.36584443443691045+0.34081938001166706i) - * + * Complex(x[, y], exception: true) -> numeric or nil + * + * Returns x+i*y; + * + * Complex(1, 2) #=> (1+2i) + * Complex('1+2i') #=> (1+2i) + * Complex(nil) #=> TypeError + * Complex(1, nil) #=> TypeError + * + * Complex(1, nil, exception: false) #=> nil + * Complex('1+2', exception: false) #=> nil + * + * Syntax of string form: + * + * string form = extra spaces , complex , extra spaces ; + * complex = real part | [ sign ] , imaginary part + * | real part , sign , imaginary part + * | rational , "@" , rational ; + * real part = rational ; + * imaginary part = imaginary unit | unsigned rational , imaginary unit ; + * rational = [ sign ] , unsigned rational ; + * unsigned rational = numerator | numerator , "/" , denominator ; + * numerator = integer part | fractional part | integer part , fractional part ; + * denominator = digits ; + * integer part = digits ; + * fractional part = "." , digits , [ ( "e" | "E" ) , [ sign ] , digits ] ; + * imaginary unit = "i" | "I" | "j" | "J" ; + * sign = "-" | "+" ; + * digits = digit , { digit | "_" , digit }; + * digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9" ; + * extra spaces = ? \s* ? ; + * + * See String#to_c. */ static VALUE nucomp_f_complex(int argc, VALUE *argv, VALUE klass) @@ -721,19 +697,14 @@ rb_dbl_complex_new_polar_pi(double abs, double ang) /* * call-seq: - * Complex.polar(abs, arg = 0) -> complex + * Complex.polar(abs[, arg]) -> complex * - * Returns a new \Complex object formed from the arguments, - * each of which must be an instance of Numeric, - * or an instance of one of its subclasses: - * \Complex, Float, Integer, Rational. - * Argument +arg+ is given in radians; - * see {Polar Coordinates}[rdoc-ref:Complex@Polar+Coordinates]: - * - * Complex.polar(3) # => (3+0i) - * Complex.polar(3, 2.0) # => (-1.2484405096414273+2.727892280477045i) - * Complex.polar(-3, -2.0) # => (1.2484405096414273+2.727892280477045i) + * Returns a complex object which denotes the given polar form. * + * Complex.polar(3, 0) #=> (3.0+0.0i) + * Complex.polar(3, Math::PI/2) #=> (1.836909530733566e-16+3.0i) + * Complex.polar(3, Math::PI) #=> (-3.0+3.673819061467132e-16i) + * Complex.polar(3, -Math::PI/2) #=> (1.836909530733566e-16-3.0i) */ static VALUE nucomp_s_polar(int argc, VALUE *argv, VALUE klass) @@ -753,19 +724,12 @@ nucomp_s_polar(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * real -> numeric - * - * Returns the real value for +self+: - * - * Complex.rect(7).real # => 7 - * Complex.rect(9, -4).real # => 9 + * cmp.real -> real * - * If +self+ was created with - * {polar coordinates}[rdoc-ref:Complex@Polar+Coordinates], the returned value - * is computed, and may be inexact: - * - * Complex.polar(1, Math::PI/4).real # => 0.7071067811865476 # Square root of 2. + * Returns the real part. * + * Complex(7).real #=> 7 + * Complex(9, -4).real #=> 9 */ VALUE rb_complex_real(VALUE self) @@ -776,19 +740,13 @@ rb_complex_real(VALUE self) /* * call-seq: - * imag -> numeric - * - * Returns the imaginary value for +self+: + * cmp.imag -> real + * cmp.imaginary -> real * - * Complex.rect(7).imag # => 0 - * Complex.rect(9, -4).imag # => -4 - * - * If +self+ was created with - * {polar coordinates}[rdoc-ref:Complex@Polar+Coordinates], the returned value - * is computed, and may be inexact: - * - * Complex.polar(1, Math::PI/4).imag # => 0.7071067811865476 # Square root of 2. + * Returns the imaginary part. * + * Complex(7).imaginary #=> 0 + * Complex(9, -4).imaginary #=> -4 */ VALUE rb_complex_imag(VALUE self) @@ -799,13 +757,11 @@ rb_complex_imag(VALUE self) /* * call-seq: - * -complex -> new_complex - * - * Returns the negation of +self+, which is the negation of each of its parts: + * -cmp -> complex * - * -Complex.rect(1, 2) # => (-1-2i) - * -Complex.rect(-1, -2) # => (1+2i) + * Returns negation of the value. * + * -Complex(1, 2) #=> (-1-2i) */ VALUE rb_complex_uminus(VALUE self) @@ -817,16 +773,15 @@ rb_complex_uminus(VALUE self) /* * call-seq: - * complex + numeric -> new_complex + * cmp + numeric -> complex * - * Returns the sum of +self+ and +numeric+: - * - * Complex.rect(2, 3) + Complex.rect(2, 3) # => (4+6i) - * Complex.rect(900) + Complex.rect(1) # => (901+0i) - * Complex.rect(-2, 9) + Complex.rect(-9, 2) # => (-11+11i) - * Complex.rect(9, 8) + 4 # => (13+8i) - * Complex.rect(20, 9) + 9.8 # => (29.8+9i) + * Performs addition. * + * Complex(2, 3) + Complex(2, 3) #=> (4+6i) + * Complex(900) + Complex(1) #=> (901+0i) + * Complex(-2, 9) + Complex(-9, 2) #=> (-11+11i) + * Complex(9, 8) + 4 #=> (13+8i) + * Complex(20, 9) + 9.8 #=> (29.8+9i) */ VALUE rb_complex_plus(VALUE self, VALUE other) @@ -852,16 +807,15 @@ rb_complex_plus(VALUE self, VALUE other) /* * call-seq: - * complex - numeric -> new_complex - * - * Returns the difference of +self+ and +numeric+: + * cmp - numeric -> complex * - * Complex.rect(2, 3) - Complex.rect(2, 3) # => (0+0i) - * Complex.rect(900) - Complex.rect(1) # => (899+0i) - * Complex.rect(-2, 9) - Complex.rect(-9, 2) # => (7+7i) - * Complex.rect(9, 8) - 4 # => (5+8i) - * Complex.rect(20, 9) - 9.8 # => (10.2+9i) + * Performs subtraction. * + * Complex(2, 3) - Complex(2, 3) #=> (0+0i) + * Complex(900) - Complex(1) #=> (899+0i) + * Complex(-2, 9) - Complex(-9, 2) #=> (7+7i) + * Complex(9, 8) - 4 #=> (5+8i) + * Complex(20, 9) - 9.8 #=> (10.2+9i) */ VALUE rb_complex_minus(VALUE self, VALUE other) @@ -913,16 +867,15 @@ comp_mul(VALUE areal, VALUE aimag, VALUE breal, VALUE bimag, VALUE *real, VALUE /* * call-seq: - * complex * numeric -> new_complex + * cmp * numeric -> complex * - * Returns the product of +self+ and +numeric+: - * - * Complex.rect(2, 3) * Complex.rect(2, 3) # => (-5+12i) - * Complex.rect(900) * Complex.rect(1) # => (900+0i) - * Complex.rect(-2, 9) * Complex.rect(-9, 2) # => (0-85i) - * Complex.rect(9, 8) * 4 # => (36+32i) - * Complex.rect(20, 9) * 9.8 # => (196.0+88.2i) + * Performs multiplication. * + * Complex(2, 3) * Complex(2, 3) #=> (-5+12i) + * Complex(900) * Complex(1) #=> (900+0i) + * Complex(-2, 9) * Complex(-9, 2) #=> (0-85i) + * Complex(9, 8) * 4 #=> (36+32i) + * Complex(20, 9) * 9.8 #=> (196.0+88.2i) */ VALUE rb_complex_mul(VALUE self, VALUE other) @@ -989,16 +942,16 @@ f_divide(VALUE self, VALUE other, /* * call-seq: - * complex / numeric -> new_complex - * - * Returns the quotient of +self+ and +numeric+: + * cmp / numeric -> complex + * cmp.quo(numeric) -> complex * - * Complex.rect(2, 3) / Complex.rect(2, 3) # => (1+0i) - * Complex.rect(900) / Complex.rect(1) # => (900+0i) - * Complex.rect(-2, 9) / Complex.rect(-9, 2) # => ((36/85)-(77/85)*i) - * Complex.rect(9, 8) / 4 # => ((9/4)+2i) - * Complex.rect(20, 9) / 9.8 # => (2.0408163265306123+0.9183673469387754i) + * Performs division. * + * Complex(2, 3) / Complex(2, 3) #=> ((1/1)+(0/1)*i) + * Complex(900) / Complex(1) #=> ((900/1)+(0/1)*i) + * Complex(-2, 9) / Complex(-9, 2) #=> ((36/85)-(77/85)*i) + * Complex(9, 8) / 4 #=> ((9/4)+(2/1)*i) + * Complex(20, 9) / 9.8 #=> (2.0408163265306123+0.9183673469387754i) */ VALUE rb_complex_div(VALUE self, VALUE other) @@ -1010,12 +963,11 @@ rb_complex_div(VALUE self, VALUE other) /* * call-seq: - * fdiv(numeric) -> new_complex - * - * Returns <tt>Complex.rect(self.real/numeric, self.imag/numeric)</tt>: + * cmp.fdiv(numeric) -> complex * - * Complex.rect(11, 22).fdiv(3) # => (3.6666666666666665+7.333333333333333i) + * Performs division as each part is a float, never returns a float. * + * Complex(11, 22).fdiv(3) #=> (3.6666666666666665+7.333333333333333i) */ static VALUE nucomp_fdiv(VALUE self, VALUE other) @@ -1029,95 +981,14 @@ f_reciprocal(VALUE x) return f_quo(ONE, x); } -static VALUE -zero_for(VALUE x) -{ - if (RB_FLOAT_TYPE_P(x)) - return DBL2NUM(0); - if (RB_TYPE_P(x, T_RATIONAL)) - return rb_rational_new(INT2FIX(0), INT2FIX(1)); - - return INT2FIX(0); -} - -static VALUE -complex_pow_for_special_angle(VALUE self, VALUE other) -{ - if (!rb_integer_type_p(other)) { - return Qundef; - } - - get_dat1(self); - VALUE x = Qundef; - int dir; - if (f_zero_p(dat->imag)) { - x = dat->real; - dir = 0; - } - else if (f_zero_p(dat->real)) { - x = dat->imag; - dir = 2; - } - else if (f_eqeq_p(dat->real, dat->imag)) { - x = dat->real; - dir = 1; - } - else if (f_eqeq_p(dat->real, f_negate(dat->imag))) { - x = dat->imag; - dir = 3; - } else { - dir = 0; - } - - if (UNDEF_P(x)) return x; - - if (f_negative_p(x)) { - x = f_negate(x); - dir += 4; - } - - VALUE zx; - if (dir % 2 == 0) { - zx = rb_num_pow(x, other); - } - else { - zx = rb_num_pow( - rb_funcall(rb_int_mul(TWO, x), '*', 1, x), - rb_int_div(other, TWO) - ); - if (rb_int_odd_p(other)) { - zx = rb_funcall(zx, '*', 1, x); - } - } - static const int dirs[][2] = { - {1, 0}, {1, 1}, {0, 1}, {-1, 1}, {-1, 0}, {-1, -1}, {0, -1}, {1, -1} - }; - int z_dir = FIX2INT(rb_int_modulo(rb_int_mul(INT2FIX(dir), other), INT2FIX(8))); - - VALUE zr = Qfalse, zi = Qfalse; - switch (dirs[z_dir][0]) { - case 0: zr = zero_for(zx); break; - case 1: zr = zx; break; - case -1: zr = f_negate(zx); break; - } - switch (dirs[z_dir][1]) { - case 0: zi = zero_for(zx); break; - case 1: zi = zx; break; - case -1: zi = f_negate(zx); break; - } - return nucomp_s_new_internal(CLASS_OF(self), zr, zi); -} - - /* * call-seq: - * complex ** numeric -> new_complex + * cmp ** numeric -> complex * - * Returns +self+ raised to power +numeric+: - * - * Complex.rect(0, 1) ** 2 # => (-1+0i) - * Complex.rect(-8) ** Rational(1, 3) # => (1.0000000000000002+1.7320508075688772i) + * Performs exponentiation. * + * Complex('i') ** 2 #=> (-1+0i) + * Complex(-8) ** Rational(1, 3) #=> (1.0000000000000002+1.7320508075688772i) */ VALUE rb_complex_pow(VALUE self, VALUE other) @@ -1135,14 +1006,6 @@ rb_complex_pow(VALUE self, VALUE other) other = dat->real; /* c14n */ } - if (other == ONE) { - get_dat1(self); - return nucomp_s_new_internal(CLASS_OF(self), dat->real, dat->imag); - } - - VALUE result = complex_pow_for_special_angle(self, other); - if (!UNDEF_P(result)) return result; - if (RB_TYPE_P(other, T_COMPLEX)) { VALUE r, theta, nr, ntheta; @@ -1215,13 +1078,15 @@ rb_complex_pow(VALUE self, VALUE other) /* * call-seq: - * complex == object -> true or false + * cmp == object -> true or false * - * Returns +true+ if <tt>self.real == object.real</tt> - * and <tt>self.imag == object.imag</tt>: - * - * Complex.rect(2, 3) == Complex.rect(2.0, 3.0) # => true + * Returns true if cmp equals object numerically. * + * Complex(2, 3) == Complex(2, 3) #=> true + * Complex(5) == 5 #=> true + * Complex(0) == 0.0 #=> true + * Complex('1/3') == 0.33 #=> false + * Complex('1/2') == '1/2' #=> false */ static VALUE nucomp_eqeq_p(VALUE self, VALUE other) @@ -1249,26 +1114,17 @@ nucomp_real_p(VALUE self) /* * call-seq: - * complex <=> object -> -1, 0, 1, or nil - * - * Returns: + * cmp <=> object -> 0, 1, -1, or nil * - * - <tt>self.real <=> object.real</tt> if both of the following are true: - * - * - <tt>self.imag == 0</tt>. - * - <tt>object.imag == 0</tt>. # Always true if object is numeric but not complex. - * - * - +nil+ otherwise. - * - * Examples: - * - * Complex.rect(2) <=> 3 # => -1 - * Complex.rect(2) <=> 2 # => 0 - * Complex.rect(2) <=> 1 # => 1 - * Complex.rect(2, 1) <=> 1 # => nil # self.imag not zero. - * Complex.rect(1) <=> Complex.rect(1, 1) # => nil # object.imag not zero. - * Complex.rect(1) <=> 'Foo' # => nil # object.imag not defined. + * If +cmp+'s imaginary part is zero, and +object+ is also a + * real number (or a Complex number where the imaginary part is zero), + * compare the real part of +cmp+ to object. Otherwise, return nil. * + * Complex(2, 3) <=> Complex(2, 3) #=> nil + * Complex(2, 3) <=> 1 #=> nil + * Complex(2) <=> 1 #=> 1 + * Complex(2) <=> 2 #=> 0 + * Complex(2) <=> 3 #=> -1 */ static VALUE nucomp_cmp(VALUE self, VALUE other) @@ -1313,19 +1169,13 @@ nucomp_coerce(VALUE self, VALUE other) /* * call-seq: - * abs -> float - * - * Returns the absolute value (magnitude) for +self+; - * see {polar coordinates}[rdoc-ref:Complex@Polar+Coordinates]: + * cmp.abs -> real + * cmp.magnitude -> real * - * Complex.polar(-1, 0).abs # => 1.0 - * - * If +self+ was created with - * {rectangular coordinates}[rdoc-ref:Complex@Rectangular+Coordinates], the returned value - * is computed, and may be inexact: - * - * Complex.rectangular(1, 1).abs # => 1.4142135623730951 # The square root of 2. + * Returns the absolute part of its polar form. * + * Complex(-1).abs #=> 1 + * Complex(3.0, -4.0).abs #=> 5.0 */ VALUE rb_complex_abs(VALUE self) @@ -1349,19 +1199,12 @@ rb_complex_abs(VALUE self) /* * call-seq: - * abs2 -> float - * - * Returns square of the absolute value (magnitude) for +self+; - * see {polar coordinates}[rdoc-ref:Complex@Polar+Coordinates]: - * - * Complex.polar(2, 2).abs2 # => 4.0 + * cmp.abs2 -> real * - * If +self+ was created with - * {rectangular coordinates}[rdoc-ref:Complex@Rectangular+Coordinates], the returned value - * is computed, and may be inexact: - * - * Complex.rectangular(1.0/3, 1.0/3).abs2 # => 0.2222222222222222 + * Returns square of the absolute value. * + * Complex(-1).abs2 #=> 1 + * Complex(3.0, -4.0).abs2 #=> 25.0 */ static VALUE nucomp_abs2(VALUE self) @@ -1373,19 +1216,13 @@ nucomp_abs2(VALUE self) /* * call-seq: - * arg -> float - * - * Returns the argument (angle) for +self+ in radians; - * see {polar coordinates}[rdoc-ref:Complex@Polar+Coordinates]: - * - * Complex.polar(3, Math::PI/2).arg # => 1.57079632679489660 + * cmp.arg -> float + * cmp.angle -> float + * cmp.phase -> float * - * If +self+ was created with - * {rectangular coordinates}[rdoc-ref:Complex@Rectangular+Coordinates], the returned value - * is computed, and may be inexact: - * - * Complex.polar(1, 1.0/3).arg # => 0.33333333333333326 + * Returns the angle part of its polar form. * + * Complex.polar(3, Math::PI/2).arg #=> 1.5707963267948966 */ VALUE rb_complex_arg(VALUE self) @@ -1396,22 +1233,12 @@ rb_complex_arg(VALUE self) /* * call-seq: - * rect -> array - * - * Returns the array <tt>[self.real, self.imag]</tt>: + * cmp.rect -> array + * cmp.rectangular -> array * - * Complex.rect(1, 2).rect # => [1, 2] + * Returns an array; [cmp.real, cmp.imag]. * - * See {Rectangular Coordinates}[rdoc-ref:Complex@Rectangular+Coordinates]. - * - * If +self+ was created with - * {polar coordinates}[rdoc-ref:Complex@Polar+Coordinates], the returned value - * is computed, and may be inexact: - * - * Complex.polar(1.0, 1.0).rect # => [0.5403023058681398, 0.8414709848078965] - * - * - * Complex#rectangular is an alias for Complex#rect. + * Complex(1, 2).rectangular #=> [1, 2] */ static VALUE nucomp_rect(VALUE self) @@ -1422,20 +1249,11 @@ nucomp_rect(VALUE self) /* * call-seq: - * polar -> array - * - * Returns the array <tt>[self.abs, self.arg]</tt>: + * cmp.polar -> array * - * Complex.polar(1, 2).polar # => [1.0, 2.0] - * - * See {Polar Coordinates}[rdoc-ref:Complex@Polar+Coordinates]. - * - * If +self+ was created with - * {rectangular coordinates}[rdoc-ref:Complex@Rectangular+Coordinates], the returned value - * is computed, and may be inexact: - * - * Complex.rect(1, 1).polar # => [1.4142135623730951, 0.7853981633974483] + * Returns an array; [cmp.abs, cmp.arg]. * + * Complex(1, 2).polar #=> [2.23606797749979, 1.1071487177940904] */ static VALUE nucomp_polar(VALUE self) @@ -1445,12 +1263,12 @@ nucomp_polar(VALUE self) /* * call-seq: - * conj -> complex + * cmp.conj -> complex + * cmp.conjugate -> complex * - * Returns the conjugate of +self+, <tt>Complex.rect(self.imag, self.real)</tt>: - * - * Complex.rect(1, 2).conj # => (1-2i) + * Returns the complex conjugate. * + * Complex(1, 2).conjugate #=> (1-2i) */ VALUE rb_complex_conjugate(VALUE self) @@ -1461,9 +1279,10 @@ rb_complex_conjugate(VALUE self) /* * call-seq: - * real? -> false + * Complex(1).real? -> false + * Complex(1, 2).real? -> false * - * Returns +false+; for compatibility with Numeric#real?. + * Returns false, even if the complex number has no imaginary part. */ static VALUE nucomp_real_p_m(VALUE self) @@ -1473,17 +1292,11 @@ nucomp_real_p_m(VALUE self) /* * call-seq: - * denominator -> integer - * - * Returns the denominator of +self+, which is - * the {least common multiple}[https://en.wikipedia.org/wiki/Least_common_multiple] - * of <tt>self.real.denominator</tt> and <tt>self.imag.denominator</tt>: + * cmp.denominator -> integer * - * Complex.rect(Rational(1, 2), Rational(2, 3)).denominator # => 6 + * Returns the denominator (lcm of both denominator - real and imag). * - * Note that <tt>n.denominator</tt> of a non-rational numeric is +1+. - * - * Related: Complex#numerator. + * See numerator. */ static VALUE nucomp_denominator(VALUE self) @@ -1494,23 +1307,21 @@ nucomp_denominator(VALUE self) /* * call-seq: - * numerator -> new_complex - * - * Returns the \Complex object created from the numerators - * of the real and imaginary parts of +self+, - * after converting each part to the - * {lowest common denominator}[https://en.wikipedia.org/wiki/Lowest_common_denominator] - * of the two: + * cmp.numerator -> numeric * - * c = Complex.rect(Rational(2, 3), Rational(3, 4)) # => ((2/3)+(3/4)*i) - * c.numerator # => (8+9i) + * Returns the numerator. * - * In this example, the lowest common denominator of the two parts is 12; - * the two converted parts may be thought of as \Rational(8, 12) and \Rational(9, 12), - * whose numerators, respectively, are 8 and 9; - * so the returned value of <tt>c.numerator</tt> is <tt>Complex.rect(8, 9)</tt>. + * 1 2 3+4i <- numerator + * - + -i -> ---- + * 2 3 6 <- denominator * - * Related: Complex#denominator. + * c = Complex('1/2+2/3i') #=> ((1/2)+(2/3)*i) + * n = c.numerator #=> (3+4i) + * d = c.denominator #=> 6 + * n / d #=> ((1/2)+(2/3)*i) + * Complex(Rational(n.real, d), Rational(n.imag, d)) + * #=> ((1/2)+(2/3)*i) + * See denominator. */ static VALUE nucomp_numerator(VALUE self) @@ -1543,18 +1354,6 @@ rb_complex_hash(VALUE self) return v; } -/* - * :call-seq: - * hash -> integer - * - * Returns the integer hash value for +self+. - * - * Two \Complex objects created from the same values will have the same hash value - * (and will compare using #eql?): - * - * Complex.rect(1, 2).hash == Complex.rect(1, 2).hash # => true - * - */ static VALUE nucomp_hash(VALUE self) { @@ -1593,15 +1392,16 @@ f_tpositive_p(VALUE x) } static VALUE -f_format(VALUE self, VALUE s, VALUE (*func)(VALUE)) +f_format(VALUE self, VALUE (*func)(VALUE)) { + VALUE s; int impos; get_dat1(self); impos = f_tpositive_p(dat->imag); - rb_str_concat(s, (*func)(dat->real)); + s = (*func)(dat->real); rb_str_cat2(s, !impos ? "-" : "+"); rb_str_concat(s, (*func)(f_abs(dat->imag))); @@ -1614,35 +1414,33 @@ f_format(VALUE self, VALUE s, VALUE (*func)(VALUE)) /* * call-seq: - * to_s -> string - * - * Returns a string representation of +self+: + * cmp.to_s -> string * - * Complex.rect(2).to_s # => "2+0i" - * Complex.rect(-8, 6).to_s # => "-8+6i" - * Complex.rect(0, Rational(1, 2)).to_s # => "0+1/2i" - * Complex.rect(0, Float::INFINITY).to_s # => "0+Infinity*i" - * Complex.rect(Float::NAN, Float::NAN).to_s # => "NaN+NaN*i" + * Returns the value as a string. * + * Complex(2).to_s #=> "2+0i" + * Complex('-8/6').to_s #=> "-4/3+0i" + * Complex('1/2i').to_s #=> "0+1/2i" + * Complex(0, Float::INFINITY).to_s #=> "0+Infinity*i" + * Complex(Float::NAN, Float::NAN).to_s #=> "NaN+NaN*i" */ static VALUE nucomp_to_s(VALUE self) { - return f_format(self, rb_usascii_str_new2(""), rb_String); + return f_format(self, rb_String); } /* * call-seq: - * inspect -> string + * cmp.inspect -> string * - * Returns a string representation of +self+: - * - * Complex.rect(2).inspect # => "(2+0i)" - * Complex.rect(-8, 6).inspect # => "(-8+6i)" - * Complex.rect(0, Rational(1, 2)).inspect # => "(0+(1/2)*i)" - * Complex.rect(0, Float::INFINITY).inspect # => "(0+Infinity*i)" - * Complex.rect(Float::NAN, Float::NAN).inspect # => "(NaN+NaN*i)" + * Returns the value as a string for inspection. * + * Complex(2).inspect #=> "(2+0i)" + * Complex('-8/6').inspect #=> "((-4/3)+0i)" + * Complex('1/2i').inspect #=> "(0+(1/2)*i)" + * Complex(0, Float::INFINITY).inspect #=> "(0+Infinity*i)" + * Complex(Float::NAN, Float::NAN).inspect #=> "(NaN+NaN*i)" */ static VALUE nucomp_inspect(VALUE self) @@ -1650,7 +1448,7 @@ nucomp_inspect(VALUE self) VALUE s; s = rb_usascii_str_new2("("); - f_format(self, s, rb_inspect); + rb_str_concat(s, f_format(self, rb_inspect)); rb_str_cat2(s, ")"); return s; @@ -1660,15 +1458,10 @@ nucomp_inspect(VALUE self) /* * call-seq: - * finite? -> true or false - * - * Returns +true+ if both <tt>self.real.finite?</tt> and <tt>self.imag.finite?</tt> - * are true, +false+ otherwise: - * - * Complex.rect(1, 1).finite? # => true - * Complex.rect(Float::INFINITY, 0).finite? # => false + * cmp.finite? -> true or false * - * Related: Numeric#finite?, Float#finite?. + * Returns +true+ if +cmp+'s real and imaginary parts are both finite numbers, + * otherwise returns +false+. */ static VALUE rb_complex_finite_p(VALUE self) @@ -1680,15 +1473,15 @@ rb_complex_finite_p(VALUE self) /* * call-seq: - * infinite? -> 1 or nil + * cmp.infinite? -> nil or 1 * - * Returns +1+ if either <tt>self.real.infinite?</tt> or <tt>self.imag.infinite?</tt> - * is true, +nil+ otherwise: + * Returns +1+ if +cmp+'s real or imaginary part is an infinite number, + * otherwise returns +nil+. * - * Complex.rect(Float::INFINITY, 0).infinite? # => 1 - * Complex.rect(1, 1).infinite? # => nil + * For example: * - * Related: Numeric#infinite?, Float#infinite?. + * (1+1i).infinite? #=> nil + * (Float::INFINITY + 1i).infinite? #=> 1 */ static VALUE rb_complex_infinite_p(VALUE self) @@ -1716,7 +1509,7 @@ nucomp_loader(VALUE self, VALUE a) RCOMPLEX_SET_REAL(dat, rb_ivar_get(a, id_i_real)); RCOMPLEX_SET_IMAG(dat, rb_ivar_get(a, id_i_imag)); - OBJ_FREEZE(self); + OBJ_FREEZE_RAW(self); return self; } @@ -1786,15 +1579,14 @@ rb_dbl_complex_new(double real, double imag) /* * call-seq: - * to_i -> integer - * - * Returns the value of <tt>self.real</tt> as an Integer, if possible: + * cmp.to_i -> integer * - * Complex.rect(1, 0).to_i # => 1 - * Complex.rect(1, Rational(0, 1)).to_i # => 1 + * Returns the value as an integer if possible (the imaginary part + * should be exactly zero). * - * Raises RangeError if <tt>self.imag</tt> is not exactly zero - * (either <tt>Integer(0)</tt> or <tt>Rational(0, _n_)</tt>). + * Complex(1, 0).to_i #=> 1 + * Complex(1, 0.0).to_i # RangeError + * Complex(1, 2).to_i # RangeError */ static VALUE nucomp_to_i(VALUE self) @@ -1810,15 +1602,14 @@ nucomp_to_i(VALUE self) /* * call-seq: - * to_f -> float + * cmp.to_f -> float * - * Returns the value of <tt>self.real</tt> as a Float, if possible: + * Returns the value as a float if possible (the imaginary part should + * be exactly zero). * - * Complex.rect(1, 0).to_f # => 1.0 - * Complex.rect(1, Rational(0, 1)).to_f # => 1.0 - * - * Raises RangeError if <tt>self.imag</tt> is not exactly zero - * (either <tt>Integer(0)</tt> or <tt>Rational(0, _n_)</tt>). + * Complex(1, 0).to_f #=> 1.0 + * Complex(1, 0.0).to_f # RangeError + * Complex(1, 2).to_f # RangeError */ static VALUE nucomp_to_f(VALUE self) @@ -1834,69 +1625,41 @@ nucomp_to_f(VALUE self) /* * call-seq: - * to_r -> rational - * - * Returns the value of <tt>self.real</tt> as a Rational, if possible: + * cmp.to_r -> rational * - * Complex.rect(1, 0).to_r # => (1/1) - * Complex.rect(1, Rational(0, 1)).to_r # => (1/1) - * Complex.rect(1, 0.0).to_r # => (1/1) + * Returns the value as a rational if possible (the imaginary part + * should be exactly zero). * - * Raises RangeError if <tt>self.imag</tt> is not exactly zero - * (either <tt>Integer(0)</tt> or <tt>Rational(0, _n_)</tt>) - * and <tt>self.imag.to_r</tt> is not exactly zero. + * Complex(1, 0).to_r #=> (1/1) + * Complex(1, 0.0).to_r # RangeError + * Complex(1, 2).to_r # RangeError * - * Related: Complex#rationalize. + * See rationalize. */ static VALUE nucomp_to_r(VALUE self) { get_dat1(self); - if (RB_FLOAT_TYPE_P(dat->imag) && FLOAT_ZERO_P(dat->imag)) { - /* Do nothing here */ - } - else if (!k_exact_zero_p(dat->imag)) { - VALUE imag = rb_check_convert_type_with_id(dat->imag, T_RATIONAL, "Rational", idTo_r); - if (NIL_P(imag) || !k_exact_zero_p(imag)) { - rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Rational", - self); - } + if (!k_exact_zero_p(dat->imag)) { + rb_raise(rb_eRangeError, "can't convert %"PRIsVALUE" into Rational", + self); } return f_to_r(dat->real); } /* * call-seq: - * rationalize(epsilon = nil) -> rational - * - * Returns a Rational object whose value is exactly or approximately - * equivalent to that of <tt>self.real</tt>. - * - * With no argument +epsilon+ given, returns a \Rational object - * whose value is exactly equal to that of <tt>self.real.rationalize</tt>: - * - * Complex.rect(1, 0).rationalize # => (1/1) - * Complex.rect(1, Rational(0, 1)).rationalize # => (1/1) - * Complex.rect(3.14159, 0).rationalize # => (314159/100000) - * - * With argument +epsilon+ given, returns a \Rational object - * whose value is exactly or approximately equal to that of <tt>self.real</tt> - * to the given precision: - * - * Complex.rect(3.14159, 0).rationalize(0.1) # => (16/5) - * Complex.rect(3.14159, 0).rationalize(0.01) # => (22/7) - * Complex.rect(3.14159, 0).rationalize(0.001) # => (201/64) - * Complex.rect(3.14159, 0).rationalize(0.0001) # => (333/106) - * Complex.rect(3.14159, 0).rationalize(0.00001) # => (355/113) - * Complex.rect(3.14159, 0).rationalize(0.000001) # => (7433/2366) - * Complex.rect(3.14159, 0).rationalize(0.0000001) # => (9208/2931) - * Complex.rect(3.14159, 0).rationalize(0.00000001) # => (47460/15107) - * Complex.rect(3.14159, 0).rationalize(0.000000001) # => (76149/24239) - * Complex.rect(3.14159, 0).rationalize(0.0000000001) # => (314159/100000) - * Complex.rect(3.14159, 0).rationalize(0.0) # => (3537115888337719/1125899906842624) - * - * Related: Complex#to_r. + * cmp.rationalize([eps]) -> rational + * + * Returns the value as a rational if possible (the imaginary part + * should be exactly zero). + * + * Complex(1.0/3, 0).rationalize #=> (1/3) + * Complex(1, 0.0).rationalize # RangeError + * Complex(1, 2).rationalize # RangeError + * + * See to_r. */ static VALUE nucomp_rationalize(int argc, VALUE *argv, VALUE self) @@ -1914,9 +1677,12 @@ nucomp_rationalize(int argc, VALUE *argv, VALUE self) /* * call-seq: - * to_c -> self + * complex.to_c -> self * - * Returns +self+. + * Returns self. + * + * Complex(2).to_c #=> (2+0i) + * Complex(-8, 6).to_c #=> (-8+6i) */ static VALUE nucomp_to_c(VALUE self) @@ -1926,12 +1692,9 @@ nucomp_to_c(VALUE self) /* * call-seq: - * to_c -> (0+0i) - * - * Returns zero as a Complex: - * - * nil.to_c # => (0+0i) + * nil.to_c -> (0+0i) * + * Returns zero as a complex. */ static VALUE nilclass_to_c(VALUE self) @@ -1941,9 +1704,9 @@ nilclass_to_c(VALUE self) /* * call-seq: - * to_c -> complex + * num.to_c -> complex * - * Returns +self+ as a Complex object. + * Returns the value as a complex. */ static VALUE numeric_to_c(VALUE self) @@ -2223,14 +1986,23 @@ string_to_c_strict(VALUE self, int raise) rb_must_asciicompat(self); - if (raise) { - s = StringValueCStr(self); + s = RSTRING_PTR(self); + + if (!s || memchr(s, '\0', RSTRING_LEN(self))) { + if (!raise) return Qnil; + rb_raise(rb_eArgError, "string contains null byte"); } - else if (!(s = rb_str_to_cstr(self))) { - return Qnil; + + if (s && s[RSTRING_LEN(self)]) { + rb_str_modify(self); + s = RSTRING_PTR(self); + s[RSTRING_LEN(self)] = '\0'; } - if (!parse_comp(s, TRUE, &num)) { + if (!s) + s = (char *)""; + + if (!parse_comp(s, 1, &num)) { if (!raise) return Qnil; rb_raise(rb_eArgError, "invalid value for convert(): %+"PRIsVALUE, self); @@ -2241,39 +2013,53 @@ string_to_c_strict(VALUE self, int raise) /* * call-seq: - * to_c -> complex - * - * Returns +self+ interpreted as a Complex object; - * leading whitespace and trailing garbage are ignored: - * - * '9'.to_c # => (9+0i) - * '2.5'.to_c # => (2.5+0i) - * '2.5/1'.to_c # => ((5/2)+0i) - * '-3/2'.to_c # => ((-3/2)+0i) - * '-i'.to_c # => (0-1i) - * '45i'.to_c # => (0+45i) - * '3-4i'.to_c # => (3-4i) - * '-4e2-4e-2i'.to_c # => (-400.0-0.04i) - * '-0.0-0.0i'.to_c # => (-0.0-0.0i) - * '1/2+3/4i'.to_c # => ((1/2)+(3/4)*i) - * '1.0@0'.to_c # => (1+0.0i) - * "1.0@#{Math::PI/2}".to_c # => (0.0+1i) - * "1.0@#{Math::PI}".to_c # => (-1+0.0i) - * - * Returns \Complex zero if the string cannot be converted: - * - * 'ruby'.to_c # => (0+0i) - * - * See Kernel#Complex. + * str.to_c -> complex + * + * Returns a complex which denotes the string form. The parser + * ignores leading whitespaces and trailing garbage. Any digit + * sequences can be separated by an underscore. Returns zero for null + * or garbage string. + * + * '9'.to_c #=> (9+0i) + * '2.5'.to_c #=> (2.5+0i) + * '2.5/1'.to_c #=> ((5/2)+0i) + * '-3/2'.to_c #=> ((-3/2)+0i) + * '-i'.to_c #=> (0-1i) + * '45i'.to_c #=> (0+45i) + * '3-4i'.to_c #=> (3-4i) + * '-4e2-4e-2i'.to_c #=> (-400.0-0.04i) + * '-0.0-0.0i'.to_c #=> (-0.0-0.0i) + * '1/2+3/4i'.to_c #=> ((1/2)+(3/4)*i) + * 'ruby'.to_c #=> (0+0i) + * + * Polar form: + * include Math + * "1.0@0".to_c #=> (1+0.0i) + * "1.0@#{PI/2}".to_c #=> (0.0+1i) + * "1.0@#{PI}".to_c #=> (-1+0.0i) + * + * See Kernel.Complex. */ static VALUE string_to_c(VALUE self) { + char *s; VALUE num; rb_must_asciicompat(self); - (void)parse_comp(rb_str_fill_terminator(self, 1), FALSE, &num); + s = RSTRING_PTR(self); + + if (s && s[RSTRING_LEN(self)]) { + rb_str_modify(self); + s = RSTRING_PTR(self); + s[RSTRING_LEN(self)] = '\0'; + } + + if (!s) + s = (char *)""; + + (void)parse_comp(s, 0, &num); return num; } @@ -2378,9 +2164,9 @@ nucomp_s_convert(int argc, VALUE *argv, VALUE klass) /* * call-seq: - * abs2 -> real + * num.abs2 -> real * - * Returns the square of +self+. + * Returns square of self. */ static VALUE numeric_abs2(VALUE self) @@ -2390,9 +2176,11 @@ numeric_abs2(VALUE self) /* * call-seq: - * arg -> 0 or Math::PI + * num.arg -> 0 or float + * num.angle -> 0 or float + * num.phase -> 0 or float * - * Returns zero if +self+ is positive, Math::PI otherwise. + * Returns 0 if the value is positive, pi otherwise. */ static VALUE numeric_arg(VALUE self) @@ -2404,9 +2192,10 @@ numeric_arg(VALUE self) /* * call-seq: - * rect -> array + * num.rect -> array + * num.rectangular -> array * - * Returns array <tt>[self, 0]</tt>. + * Returns an array; [num, 0]. */ static VALUE numeric_rect(VALUE self) @@ -2416,9 +2205,9 @@ numeric_rect(VALUE self) /* * call-seq: - * polar -> array + * num.polar -> array * - * Returns array <tt>[self.abs, self.arg]</tt>. + * Returns an array; [num.abs, num.arg]. */ static VALUE numeric_polar(VALUE self) @@ -2446,9 +2235,11 @@ numeric_polar(VALUE self) /* * call-seq: - * arg -> 0 or Math::PI + * flo.arg -> 0 or float + * flo.angle -> 0 or float + * flo.phase -> 0 or float * - * Returns 0 if +self+ is positive, Math::PI otherwise. + * Returns 0 if the value is positive, pi otherwise. */ static VALUE float_arg(VALUE self) @@ -2461,137 +2252,45 @@ float_arg(VALUE self) } /* - * A \Complex object houses a pair of values, - * given when the object is created as either <i>rectangular coordinates</i> - * or <i>polar coordinates</i>. - * - * == Rectangular Coordinates - * - * The rectangular coordinates of a complex number - * are called the _real_ and _imaginary_ parts; - * see {Complex number definition}[https://en.wikipedia.org/wiki/Complex_number#Definition_and_basic_operations]. - * - * You can create a \Complex object from rectangular coordinates with: - * - * - A {complex literal}[rdoc-ref:doc/syntax/literals.rdoc@Complex+Literals]. - * - \Method Complex.rect. - * - \Method Kernel#Complex, either with numeric arguments or with certain string arguments. - * - \Method String#to_c, for certain strings. - * - * Note that each of the stored parts may be a an instance one of the classes - * Complex, Float, Integer, or Rational; - * they may be retrieved: - * - * - Separately, with methods Complex#real and Complex#imaginary. - * - Together, with method Complex#rect. - * - * The corresponding (computed) polar values may be retrieved: - * - * - Separately, with methods Complex#abs and Complex#arg. - * - Together, with method Complex#polar. - * - * == Polar Coordinates - * - * The polar coordinates of a complex number - * are called the _absolute_ and _argument_ parts; - * see {Complex polar plane}[https://en.wikipedia.org/wiki/Complex_number#Polar_form]. - * - * In this class, the argument part - * in expressed {radians}[https://en.wikipedia.org/wiki/Radian] - * (not {degrees}[https://en.wikipedia.org/wiki/Degree_(angle)]). - * - * You can create a \Complex object from polar coordinates with: - * - * - \Method Complex.polar. - * - \Method Kernel#Complex, with certain string arguments. - * - \Method String#to_c, for certain strings. - * - * Note that each of the stored parts may be a an instance one of the classes - * Complex, Float, Integer, or Rational; - * they may be retrieved: - * - * - Separately, with methods Complex#abs and Complex#arg. - * - Together, with method Complex#polar. - * - * The corresponding (computed) rectangular values may be retrieved: - * - * - Separately, with methods Complex#real and Complex#imag. - * - Together, with method Complex#rect. - * - * == What's Here - * - * First, what's elsewhere: - * - * - \Class \Complex inherits (directly or indirectly) - * from classes {Numeric}[rdoc-ref:Numeric@What-27s+Here] - * and {Object}[rdoc-ref:Object@What-27s+Here]. - * - Includes (indirectly) module {Comparable}[rdoc-ref:Comparable@What-27s+Here]. - * - * Here, class \Complex has methods for: - * - * === Creating \Complex Objects - * - * - ::polar: Returns a new \Complex object based on given polar coordinates. - * - ::rect (and its alias ::rectangular): - * Returns a new \Complex object based on given rectangular coordinates. - * - * === Querying - * - * - #abs (and its alias #magnitude): Returns the absolute value for +self+. - * - #arg (and its aliases #angle and #phase): - * Returns the argument (angle) for +self+ in radians. - * - #denominator: Returns the denominator of +self+. - * - #finite?: Returns whether both +self.real+ and +self.image+ are finite. - * - #hash: Returns the integer hash value for +self+. - * - #imag (and its alias #imaginary): Returns the imaginary value for +self+. - * - #infinite?: Returns whether +self.real+ or +self.image+ is infinite. - * - #numerator: Returns the numerator of +self+. - * - #polar: Returns the array <tt>[self.abs, self.arg]</tt>. - * - #inspect: Returns a string representation of +self+. - * - #real: Returns the real value for +self+. - * - #real?: Returns +false+; for compatibility with Numeric#real?. - * - #rect (and its alias #rectangular): - * Returns the array <tt>[self.real, self.imag]</tt>. + * A complex number can be represented as a paired real number with + * imaginary unit; a+bi. Where a is real part, b is imaginary part + * and i is imaginary unit. Real a equals complex a+0i + * mathematically. * - * === Comparing + * You can create a \Complex object explicitly with: * - * - #<=>: Returns whether +self+ is less than, equal to, or greater than the given argument. - * - #==: Returns whether +self+ is equal to the given argument. + * - A {complex literal}[rdoc-ref:syntax/literals.rdoc@Complex+Literals]. * - * === Converting + * You can convert certain objects to \Complex objects with: * - * - #rationalize: Returns a Rational object whose value is exactly - * or approximately equivalent to that of <tt>self.real</tt>. - * - #to_c: Returns +self+. - * - #to_d: Returns the value as a BigDecimal object. - * - #to_f: Returns the value of <tt>self.real</tt> as a Float, if possible. - * - #to_i: Returns the value of <tt>self.real</tt> as an Integer, if possible. - * - #to_r: Returns the value of <tt>self.real</tt> as a Rational, if possible. - * - #to_s: Returns a string representation of +self+. + * - \Method #Complex. * - * === Performing Complex Arithmetic + * Complex object can be created as literal, and also by using + * Kernel#Complex, Complex::rect, Complex::polar or to_c method. * - * - #*: Returns the product of +self+ and the given numeric. - * - #**: Returns +self+ raised to power of the given numeric. - * - #+: Returns the sum of +self+ and the given numeric. - * - #-: Returns the difference of +self+ and the given numeric. - * - #-@: Returns the negation of +self+. - * - #/: Returns the quotient of +self+ and the given numeric. - * - #abs2: Returns square of the absolute value (magnitude) for +self+. - * - #conj (and its alias #conjugate): Returns the conjugate of +self+. - * - #fdiv: Returns <tt>Complex.rect(self.real/numeric, self.imag/numeric)</tt>. + * 2+1i #=> (2+1i) + * Complex(1) #=> (1+0i) + * Complex(2, 3) #=> (2+3i) + * Complex.polar(2, 3) #=> (-1.9799849932008908+0.2822400161197344i) + * 3.to_c #=> (3+0i) * - * === Working with JSON + * You can also create complex object from floating-point numbers or + * strings. * - * - ::json_create: Returns a new \Complex object, - * deserialized from the given serialized hash. - * - #as_json: Returns a serialized hash constructed from +self+. - * - #to_json: Returns a JSON string representing +self+. + * Complex(0.3) #=> (0.3+0i) + * Complex('0.3-0.5i') #=> (0.3-0.5i) + * Complex('2/3+3/4i') #=> ((2/3)+(3/4)*i) + * Complex('1@2') #=> (-0.4161468365471424+0.9092974268256817i) * - * These methods are provided by the {JSON gem}[https://github.com/flori/json]. To make these methods available: + * 0.3.to_c #=> (0.3+0i) + * '0.3-0.5i'.to_c #=> (0.3-0.5i) + * '2/3+3/4i'.to_c #=> ((2/3)+(3/4)*i) + * '1@2'.to_c #=> (-0.4161468365471424+0.9092974268256817i) * - * require 'json/add/complex' + * A complex object is either an exact or an inexact number. * + * Complex(1, 1) / 2 #=> ((1/2)+(1/2)*i) + * Complex(1, 1) / 2.0 #=> (0.5+0.5i) */ void Init_Complex(void) @@ -2712,17 +2411,13 @@ Init_Complex(void) rb_define_method(rb_cFloat, "phase", float_arg, 0); /* - * Equivalent - * to <tt>Complex.rect(0, 1)</tt>: - * - * Complex::I # => (0+1i) - * + * The imaginary unit. */ rb_define_const(rb_cComplex, "I", f_complex_new_bang2(rb_cComplex, ZERO, ONE)); #if !USE_FLONUM - rb_vm_register_global_object(RFLOAT_0 = DBL2NUM(0.0)); + rb_gc_register_mark_object(RFLOAT_0 = DBL2NUM(0.0)); #endif rb_provide("complex.so"); /* for backward compatibility */ diff --git a/configure.ac b/configure.ac index d099b62679..220392d120 100644 --- a/configure.ac +++ b/configure.ac @@ -9,67 +9,49 @@ tooldir="$srcdir/tool" AC_DISABLE_OPTION_CHECKING -m4_define([RUBY_M4_INCLUDED], [])dnl -AC_DEFUN([RUBY_M4_INCLUDE], [m4_include([tool/m4/$1])dnl - m4_append([RUBY_M4_INCLUDED], [ \ - $(tooldir)/m4/$1])dnl -]) -RUBY_M4_INCLUDE([_colorize_result_prepare.m4])dnl -RUBY_M4_INCLUDE([ac_msg_result.m4])dnl -RUBY_M4_INCLUDE([colorize_result.m4])dnl -RUBY_M4_INCLUDE([ruby_append_option.m4])dnl -RUBY_M4_INCLUDE([ruby_append_options.m4])dnl -RUBY_M4_INCLUDE([ruby_check_builtin_func.m4])dnl -RUBY_M4_INCLUDE([ruby_check_builtin_setjmp.m4])dnl -RUBY_M4_INCLUDE([ruby_check_header.m4])dnl -RUBY_M4_INCLUDE([ruby_check_printf_prefix.m4])dnl -RUBY_M4_INCLUDE([ruby_check_setjmp.m4])dnl -RUBY_M4_INCLUDE([ruby_check_signedness.m4])dnl -RUBY_M4_INCLUDE([ruby_check_sizeof.m4])dnl -RUBY_M4_INCLUDE([ruby_check_sysconf.m4])dnl -RUBY_M4_INCLUDE([ruby_cppoutfile.m4])dnl -RUBY_M4_INCLUDE([ruby_decl_attribute.m4])dnl -RUBY_M4_INCLUDE([ruby_default_arch.m4])dnl -RUBY_M4_INCLUDE([ruby_define_if.m4])dnl -RUBY_M4_INCLUDE([ruby_defint.m4])dnl -RUBY_M4_INCLUDE([ruby_dtrace_available.m4])dnl -RUBY_M4_INCLUDE([ruby_dtrace_postprocess.m4])dnl -RUBY_M4_INCLUDE([ruby_func_attribute.m4])dnl -RUBY_M4_INCLUDE([ruby_mingw32.m4])dnl -RUBY_M4_INCLUDE([ruby_prepend_option.m4])dnl -RUBY_M4_INCLUDE([ruby_prog_gnu_ld.m4])dnl -RUBY_M4_INCLUDE([ruby_prog_makedirs.m4])dnl -RUBY_M4_INCLUDE([ruby_replace_funcs.m4])dnl -RUBY_M4_INCLUDE([ruby_replace_type.m4])dnl -RUBY_M4_INCLUDE([ruby_require_funcs.m4])dnl -RUBY_M4_INCLUDE([ruby_rm_recursive.m4])dnl -RUBY_M4_INCLUDE([ruby_setjmp_type.m4])dnl -RUBY_M4_INCLUDE([ruby_shared_gc.m4])dnl -RUBY_M4_INCLUDE([ruby_stack_grow_direction.m4])dnl -RUBY_M4_INCLUDE([ruby_thread.m4])dnl -RUBY_M4_INCLUDE([ruby_try_cflags.m4])dnl -RUBY_M4_INCLUDE([ruby_try_cxxflags.m4])dnl -RUBY_M4_INCLUDE([ruby_try_ldflags.m4])dnl -RUBY_M4_INCLUDE([ruby_universal_arch.m4])dnl -RUBY_M4_INCLUDE([ruby_wasm_tools.m4])dnl -RUBY_M4_INCLUDE([ruby_werror_flag.m4])dnl - -AS_IF([test "x${GITHUB_ACTIONS}" = xtrue], -[AC_REQUIRE([_COLORIZE_RESULT_PREPARE])dnl -dnl 93(bright yellow) is copied from .github/workflows/mingw.yml - begin_group() { AS_ECHO(["::group::@<:@93m$[]1@<:@m"]);} - end_group() { AS_ECHO(["::endgroup::"]);} -], -[dnl - begin_group() { :;} - end_group() { :;} -]) +m4_include([tool/m4/_colorize_result_prepare.m4])dnl +m4_include([tool/m4/ac_msg_result.m4])dnl +m4_include([tool/m4/colorize_result.m4])dnl +m4_include([tool/m4/ruby_append_option.m4])dnl +m4_include([tool/m4/ruby_append_options.m4])dnl +m4_include([tool/m4/ruby_check_builtin_func.m4])dnl +m4_include([tool/m4/ruby_check_builtin_setjmp.m4])dnl +m4_include([tool/m4/ruby_check_printf_prefix.m4])dnl +m4_include([tool/m4/ruby_check_setjmp.m4])dnl +m4_include([tool/m4/ruby_check_signedness.m4])dnl +m4_include([tool/m4/ruby_check_sizeof.m4])dnl +m4_include([tool/m4/ruby_check_sysconf.m4])dnl +m4_include([tool/m4/ruby_cppoutfile.m4])dnl +m4_include([tool/m4/ruby_decl_attribute.m4])dnl +m4_include([tool/m4/ruby_default_arch.m4])dnl +m4_include([tool/m4/ruby_define_if.m4])dnl +m4_include([tool/m4/ruby_defint.m4])dnl +m4_include([tool/m4/ruby_dtrace_available.m4])dnl +m4_include([tool/m4/ruby_dtrace_postprocess.m4])dnl +m4_include([tool/m4/ruby_func_attribute.m4])dnl +m4_include([tool/m4/ruby_mingw32.m4])dnl +m4_include([tool/m4/ruby_prepend_option.m4])dnl +m4_include([tool/m4/ruby_prog_gnu_ld.m4])dnl +m4_include([tool/m4/ruby_prog_makedirs.m4])dnl +m4_include([tool/m4/ruby_replace_funcs.m4])dnl +m4_include([tool/m4/ruby_replace_type.m4])dnl +m4_include([tool/m4/ruby_require_funcs.m4])dnl +m4_include([tool/m4/ruby_rm_recursive.m4])dnl +m4_include([tool/m4/ruby_setjmp_type.m4])dnl +m4_include([tool/m4/ruby_stack_grow_direction.m4])dnl +m4_include([tool/m4/ruby_thread.m4])dnl +m4_include([tool/m4/ruby_try_cflags.m4])dnl +m4_include([tool/m4/ruby_try_cxxflags.m4])dnl +m4_include([tool/m4/ruby_try_ldflags.m4])dnl +m4_include([tool/m4/ruby_universal_arch.m4])dnl +m4_include([tool/m4/ruby_wasm_tools.m4])dnl +m4_include([tool/m4/ruby_werror_flag.m4])dnl AC_ARG_VAR([cflags], [additional CFLAGS (ignored when CFLAGS is given)])dnl AC_ARG_VAR([cppflags], [additional CPPFLAGS (ignored when CPPFLAGS is given)])dnl AC_ARG_VAR([cxxflags], [additional CXXFLAGS (ignored when CXXFLAGS is given)])dnl -[begin]_group "environment section" && { +: "environment section" && { HAVE_BASERUBY=yes BASERUBY_VERSION= AC_ARG_WITH(baseruby, @@ -82,21 +64,21 @@ AC_ARG_WITH(baseruby, [ AC_PATH_PROG([BASERUBY], [ruby], [false]) ]) -AS_IF([test "$HAVE_BASERUBY" != no], [ - RUBYOPT=- $BASERUBY --disable=gems -rerb -rfileutils -rtempfile "${tooldir}/missing-baseruby.bat" || HAVE_BASERUBY=no -]) -AS_IF([test "${HAVE_BASERUBY:=no}" != no], [ +# BASERUBY must be >= 2.2.0. Note that `"2.2.0" > "2.2"` is true. +AS_IF([test "$HAVE_BASERUBY" != no -a "`RUBYOPT=- $BASERUBY --disable=gems -e 'print 42 if RUBY_VERSION > "2.2"' 2>/dev/null`" = 42], [ AS_CASE(["$build_os"], [mingw*], [ # Can MSys shell run a command with a drive letter? RUBYOPT=- `cygpath -ma "$BASERUBY"` --disable=gems -e exit 2>/dev/null || HAVE_BASERUBY=no ]) - RUBY_APPEND_OPTION(BASERUBY, "--disable=gems") + BASERUBY="$BASERUBY --disable=gems" BASERUBY_VERSION=`$BASERUBY -v` $BASERUBY -C "$srcdir" tool/downloader.rb -d tool -e gnu config.guess config.sub >&AS_MESSAGE_FD +], [ + HAVE_BASERUBY=no ]) AS_IF([test "$HAVE_BASERUBY" = no], [ AS_IF([test "$cross_compiling" = yes], [AC_MSG_ERROR([executable host ruby is required for cross-compiling])]) - BASERUBY=${tooldir}/missing-baseruby.bat + BASERUBY="echo executable host ruby is required. use --with-baseruby option.; false" ]) AC_SUBST(BASERUBY) AC_SUBST(HAVE_BASERUBY) @@ -261,7 +243,7 @@ AS_CASE(["${build_os}"], AC_PATH_TOOL([NM], [nm], [/usr/ccs/bin/nm], [/usr/ccs/bin:$PATH]) ]) AS_CASE(["${target_os}"], -[cygwin*|msys*|mingw*|darwin*], [ +[cygwin*|msys*|mingw*], [ ac_cv_prog_ac_ct_OBJCOPY=":" ]) @@ -280,14 +262,10 @@ AC_CHECK_TOOLS([AR], [gar ar]) AC_CHECK_TOOLS([AS], [gas as]) AC_CHECK_TOOLS([LD], [gld ld]) # ... try gold ? AC_CHECK_TOOLS([NM], [gnm nm]) -AC_CHECK_TOOLS([OBJCOPY], [gobjcopy objcopy], [:]) +AC_CHECK_TOOLS([OBJCOPY], [gobjcopy objcopy]) AC_CHECK_TOOLS([OBJDUMP], [gobjdump objdump]) AC_CHECK_TOOLS([STRIP], [gstrip strip], [:]) -# nm errors with Rust's LLVM bitcode when Rust uses a newer LLVM version than nm. -# In case we're working with llvm-nm, tell it to not worry about the bitcode. -AS_IF([${NM} --help 2>&1 | grep -q 'llvm-bc'], [NM="$NM --no-llvm-bc"]) - AS_IF([test ! $rb_test_CFLAGS], [AS_UNSET(CFLAGS)]); AS_UNSET(rb_test_CFLAGS) AS_IF([test ! $rb_test_CXXFLAGS], [AS_UNSET(CXXFLAGS)]); AS_UNSET(rb_save_CXXFLAGS) @@ -360,7 +338,7 @@ test -z "$warnflags" || AS_IF([test -z "${CFLAGS+set}"], [ cflags=`echo " $cflags " | sed "$cflagspat;s/^ *//;s/ *$//"` orig_cflags="$cflags" - cflags='${hardenflags} '"$cflags "'${optflags} ${debugflags} ${warnflags}' + cflags="$cflags "'${optflags} ${debugflags} ${warnflags}' ]) dnl AS_IF([test -z "${CXXFLAGS+set}"], [ dnl cxxflags=`echo " $cxxflags " | sed "$cflagspat;s/^ *//;s/ *$//"` @@ -415,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= ]) @@ -429,26 +414,33 @@ AC_SUBST(OUTFLAG) AC_SUBST(COUTFLAG) AC_SUBST(CSRCFLAG) +: ${MJIT_CC=$CC} +AS_IF([test "x$cross_compiling" = xno], [ + AC_PATH_PROG([MJIT_CC], ${MJIT_CC}) + + # if $CC is in /usr/lib/ccache/$CC, search original $CC (disable ccache) + AS_IF([echo $RUBY_DEBUG | grep ci > /dev/null && + echo $MJIT_CC | grep ^/usr/lib/ccache > /dev/null], [ + PATH=`echo $PATH | sed "s/\/usr\/lib\/ccache://"` MJIT_CC=`which $CC`]) + + AS_CASE([$target_os], + [*mingw*], [command -v cygpath > /dev/null && MJIT_CC=`cygpath -ma $MJIT_CC`]) + shift 2 + MJIT_CC="$MJIT_CC${1+ }$*" +]) + AS_CASE(["$build_os"], - [darwin*], [ - # gcc 13 warns duplicate -l options, which are added by the - # default spec. + [darwin1*.*], [ # Xcode linker warns for deprecated architecture and wrongly # installed TBD files. - AC_MSG_CHECKING(for $CC linker warning) - suppress_ld_waring=no + CC_WRAPPER="" echo 'int main(void) {return 0;}' > conftest.c AS_IF([$CC -framework Foundation -o conftest conftest.c 2>&1 | - grep \ - -e '^ld: warning: ignoring duplicate libraries:' \ - -e '^ld: warning: text-based stub file' \ - -e '^ld: warning: -multiply_defined is obsolete' \ - >/dev/null], [ - suppress_ld_waring=yes + grep '^ld: warning: text-based stub file' >/dev/null], [ + CC_WRAPPER=`cd -P "${tooldir}" && pwd`/darwin-cc + CC="$CC_WRAPPER $CC" ]) rm -fr conftest* - test $suppress_ld_waring = yes && warnflags="${warnflags:+${warnflags} }-Wl,-w" - AC_MSG_RESULT($suppress_ld_waring) ]) AS_CASE(["$target_os"], [wasi*], [ @@ -475,8 +467,8 @@ AC_SUBST(CC_VERSION_MESSAGE, $cc_version_message) : ${DLDFLAGS="$LDFLAGS"} RUBY_UNIVERSAL_ARCH -AS_IF([test "$target_cpu" != "$host_cpu" -a "$GCC" = yes -a "${universal_binary:-no}" = no], [ - RUBY_DEFAULT_ARCH($target_cpu) +AS_IF([test "$target_cpu" != "$host_cpu" -a "$GCC" = yes -a "$cross_compiling" = no -a "${universal_binary:-no}" = no], [ + RUBY_DEFAULT_ARCH("$target_cpu") ]) host_os=$target_os host_vendor=$target_vendor @@ -489,6 +481,7 @@ AC_CACHE_CHECK([for $AR flags], [rb_cv_arflags], [ [rb_cv_arflags=rcD], [rb_cv_arflags=rcu]) ]) AC_SUBST(ARFLAGS, ["$rb_cv_arflags "]) +AC_SUBST(ASFLAGS) AS_CASE(["$target_os"], [cygwin*|msys*|mingw*], [ @@ -519,7 +512,6 @@ AS_CASE(["$target_os"], ]) rb_cv_binary_elf=no : ${enable_shared=yes} - AS_IF([$WINDRES --version | grep LLVM > /dev/null], [USE_LLVM_WINDRES=yes], [USE_LLVM_WINDRES=no]) ], [hiuxmpp*], [AC_DEFINE(__HIUX_MPP__)]) # by TOYODA Eizi <toyoda@npd.kishou.go.jp> @@ -603,7 +595,7 @@ AC_MSG_RESULT([$CHDIR]) AC_SUBST(CHDIR) } -[begin]_group "compiler section" && { +: "compiler section" && { RUBY_WERROR_FLAG([ AC_MSG_CHECKING([whether CFLAGS is valid]) AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[]])], @@ -662,9 +654,9 @@ RUBY_WERROR_FLAG([ [enable_rpath=$enableval], [enable_rpath="$rb_cv_binary_elf"]) AS_IF([test "$enable_rpath:${RPATHFLAG}" = yes:], [ - RPATHFLAG="${rpathflag:+${rpathflag}%1\$-s}" + RPATHFLAG="${rpathflag:+ ${rpathflag}%1\$-s}" ]) - AS_CASE([${RPATHFLAG}],[*'%1$'*],[: ${LIBPATHFLAG='-L%1$-s'}],[: ${LIBPATHFLAG='-L%s'}]) + AS_CASE([${RPATHFLAG}],[*'%1$'*],[: ${LIBPATHFLAG=' -L%1$-s'}],[: ${LIBPATHFLAG=' -L%s'}]) } RUBY_TRY_LDFLAGS(-fdeclspec, [fdeclspec=yes], [fdeclspec=no]) @@ -698,10 +690,6 @@ AS_CASE(["$GCC:${warnflags+set}:${extra_warnflags:+set}:"], AS_IF([test $gcc_major -le 6], [ extra_warnflags="$extra_warnflags -Wno-maybe-uninitialized" ]) - AS_CASE([ $CFLAGS ], [*" -save-temps="*|*" -save-temps "*], [], [ - extra_warnflags="$extra_warnflags -Werror=misleading-indentation" - ]) - # ICC doesn't support -Werror= AS_IF([test $icc_version -gt 0], [ particular_werror_flags=no @@ -713,6 +701,7 @@ AS_CASE(["$GCC:${warnflags+set}:${extra_warnflags:+set}:"], -Werror=duplicated-cond \ -Werror=implicit-function-declaration \ -Werror=implicit-int \ + -Werror=misleading-indentation \ -Werror=pointer-arith \ -Werror=shorten-64-to-32 \ -Werror=write-strings \ @@ -812,10 +801,12 @@ AS_IF([test "$GCC" = yes], [ [fortify_source=$enableval]) AS_IF([test "x$fortify_source" != xno], [ RUBY_TRY_CFLAGS([$optflags -D_FORTIFY_SOURCE=2], - [RUBY_PREPEND_OPTION(hardenflags, -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2)], [], + [RUBY_APPEND_OPTION(XCFLAGS, -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2)], [], [@%:@include <stdio.h>]) ]) + : ${MJIT_HEADER_FLAGS='-P -dD'} + # -fstack-protector AS_CASE(["$target_os"], [emscripten*|wasi*], [ @@ -833,45 +824,18 @@ AS_IF([test "$GCC" = yes], [ AC_MSG_CHECKING([for -fstack-protector]) AC_MSG_RESULT(["$stack_protector"]) AS_CASE(["$stack_protector"], [-*], [ - RUBY_PREPEND_OPTION(hardenflags, $stack_protector) - RUBY_APPEND_OPTION(XLDFLAGS, $stack_protector) - RUBY_APPEND_OPTION(LDFLAGS, $stack_protector) + RUBY_APPEND_OPTION(XCFLAGS, $stack_protector) + RUBY_APPEND_OPTION(XLDFLAGS, $stack_protector) + RUBY_APPEND_OPTION(LDFLAGS, $stack_protector) ]) # aarch64 branch protection - AS_CASE(["$target_cpu"], [aarch64|arm64], [ - # LLVM libunwind is not actually capable of unwinding code compiled with pointer - # authentication unless it's built without LIBUNWIND_ENABLE_CROSS_UNWINDING (see - # https://github.com/llvm/llvm-project/blob/8e35c86977ce5529a9387657321ac9fefcdae5b5/libunwind/src/DwarfInstructions.hpp#L294) - # It seems that macOS ships LLVM compiled this way. - # Detect this and disable automatic insertion of pac-ret flags in that case, since we assume - # that reliable backtraces are more important than hardening flags. - AC_MSG_CHECKING([for a broken LLVM libunwind that cannot unwind code with RA signing]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ - @%:@include <libunwind.h> - int foo = UNW_ECROSSRASIGNING; - ]])], - # If compilation succeeds, that means we a) had libunwind, and b) it was NOT native only - [rb_cv_libunwind_broken_ra_signing=yes], - # if compilation fails, that means we either a) do not have libunwind, or b) have it in - # native only mode (which is good!) - [rb_cv_libunwind_broken_ra_signing=no] - ) - AC_MSG_RESULT(["$rb_cv_libunwind_broken_ra_signing"]) - AS_IF([test "x$rb_cv_libunwind_broken_ra_signing" = "xno"], [ - AS_FOR(option, opt, [-mbranch-protection=pac-ret -msign-return-address=all], [ - # Try these flags in the _prepended_ position - i.e. we want to try building a program - # with CFLAGS="-mbranch-protection=pac-ret $CFLAGS". If the builder has provided different - # branch protection flags in CFLAGS, we don't want to overwrite those. We just want to - # find some branch protection flags which work if none were provided. - RUBY_TRY_CFLAGS_PREPEND(option, [branch_protection=yes], [branch_protection=no]) - AS_IF([test "x$branch_protection" = xyes], [ - # _prepend_ the options to CFLAGS, so that user-provided flags will overwrite them. - # These CFLAGS are used during the configure script to compile further test programs; - # however, $harden_flags is prepended separately to CFLAGS at the end of the script. - RUBY_PREPEND_OPTION(hardenflags, $opt) - break - ]) + AS_CASE(["$target_cpu"], [aarch64], [ + AS_FOR(option, opt, [-mbranch-protection=pac-ret -msign-return-address=all], [ + RUBY_TRY_CFLAGS(option, [branch_protection=yes], [branch_protection=no]) + AS_IF([test "x$branch_protection" = xyes], [ + RUBY_APPEND_OPTION(XCFLAGS, option) + break ]) ]) ]) @@ -927,9 +891,9 @@ AS_IF([test "$GCC" = yes], [ # suppress annoying -Wstrict-overflow warnings RUBY_TRY_CFLAGS(-fno-strict-overflow, [RUBY_APPEND_OPTION(XCFLAGS, -fno-strict-overflow)]) - test "${debugflags+set}" || {RUBY_TRY_LDFLAGS(-ggdb3, [debugflags=-ggdb3])} - test "${debugflags+set}" || {RUBY_TRY_LDFLAGS(-ggdb, [debugflags=-ggdb])} - test "${debugflags+set}" || {RUBY_TRY_LDFLAGS(-g3, [debugflags=-g3])} + test "${debugflags+set}" || {RUBY_TRY_CFLAGS(-ggdb3, [debugflags=-ggdb3])} + test "${debugflags+set}" || {RUBY_TRY_CFLAGS(-ggdb, [debugflags=-ggdb])} + test "${debugflags+set}" || {RUBY_TRY_CFLAGS(-g3, [debugflags=-g3])} ]) test $ac_cv_prog_cc_g = yes && : ${debugflags=-g} @@ -946,6 +910,7 @@ AS_IF([test "$GCC" = yes], [ ], [ RUBY_TRY_LDFLAGS([-Wl,-unexported_symbol,_Init_*], [visibility_option=ld], [visibility_option=no]) ]) + test "$visibility_option" = no || OBJCOPY=: ]) AS_IF([test "$GCC" = yes], [ @@ -1001,17 +966,9 @@ AC_ARG_WITH(opt-dir, [OPT_DIR="${OPT_DIR:+$OPT_DIR$PATH_SEPARATOR}$withval"], []) AS_IF([test "x$OPT_DIR" != x], [ - save_IFS="$IFS" IFS="$PATH_SEPARATOR" val= PWD= - for dir in $OPT_DIR; do - test -z "$dir" && continue - dir=`eval $CHDIR '"$dir"' && pwd` || continue - val="${val:+$val$PATH_SEPARATOR}$dir" - done - IFS="$save_IFS" OPT_DIR="$val" - unset PWD - unset save_IFS val=`IFS="$PATH_SEPARATOR" for dir in $OPT_DIR; do + test -z "$dir" && continue echo x ${LIBPATHFLAG} ${RPATHFLAG} | sed "s/^x *//;s${IFS}"'%1\\$-s'"${IFS}${dir}/lib${IFS}g;s${IFS}%s${IFS}${dir}/lib${IFS}g" done | tr '\012' ' ' | sed 's/ *$//'` @@ -1025,7 +982,7 @@ 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\"" - +} AC_CACHE_CHECK([whether compiler has statement and declarations in expressions], rb_cv_have_stmt_and_decl_in_expr, @@ -1035,9 +992,8 @@ AC_CACHE_CHECK([whether compiler has statement and declarations in expressions], AS_IF([test "$rb_cv_have_stmt_and_decl_in_expr" = yes], [ AC_DEFINE(HAVE_STMT_AND_DECL_IN_EXPR) ]) -} -[begin]_group "header and library section" && { +: "header and library section" && { AC_ARG_WITH(winnt-ver, AS_HELP_STRING([--with-winnt-ver=0xXXXX], [target Windows NT version (default to 0x0600)]), [with_winnt_ver="$withval"], [with_winnt_ver="0x0600"]) @@ -1092,6 +1048,7 @@ AS_CASE(["$target_os"], AS_IF([test $gcc_major -eq 4 -a $gcc_minor -lt 3], [ ac_cv_func___builtin_setjmp=no ]) + with_setjmp_type=sigsetjmp # to hijack SIGCHLD handler AC_CACHE_CHECK(for broken crypt with 8bit chars, rb_cv_broken_crypt, [AC_RUN_IFELSE([AC_LANG_SOURCE([[ #include <stdio.h> @@ -1139,23 +1096,21 @@ main() ]) POSTLINK="" AC_CHECK_PROGS(codesign, codesign) - dsymutils= - AS_CASE("$CC_NO_WRAPPER", [gcc*-1[[3-9]]], [ - dsymutils=${CC_NO_WRAPPER@%:@gcc} - dsymutils=dsymutil${dsymutils%-1*} - dsymutils="$dsymutils-19 $dsymutils-18 $dsymutils-17" - ]) - AC_CHECK_PROGS(dsymutil, $dsymutils dsymutil) + AC_CHECK_PROGS(dsymutil, dsymutil) AS_IF([test -n "$codesign"], [ - POSTLINK="{ test -z '\$(RUBY_CODESIGN)' || $codesign -s '\$(RUBY_CODESIGN)' \$@; }${POSTLINK:+; $POSTLINK}" + POSTLINK="{ test -z '\$(RUBY_CODESIGN)' || $codesign -s '\$(RUBY_CODESIGN)' -f \$@; }${POSTLINK:+; $POSTLINK}" ]) AS_IF([test -n "$dsymutil"], [ - POSTLINK="$dsymutil \$@ 2>/dev/null${POSTLINK:+; $POSTLINK}" + POSTLINK="$dsymutil \$@${POSTLINK:+; $POSTLINK}" + ]) + AS_IF([test -n "${POSTLINK}"], [ + LINK_SO="$LINK_SO +\$(POSTLINK)" ]) AC_CHECK_HEADERS(crt_externs.h, [], [], [ #include <crt_externs.h> ]) - cleanlibs='$(TARGET_SO:=.dSYM)' + cleanlibs='$(TARGET_SO).dSYM' ], [solaris*], [ LIBS="-lm $LIBS" ac_cv_func_vfork=no @@ -1248,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 @@ -1290,11 +1243,10 @@ main() # __builtin_longjmp in ppc64* Linux does not restore # the TOC register (r2), which is problematic # when a global exit happens from JITted .so code. - # __builtin_setjmp can have issues on arm64 linux (see [Bug #14480]). - AS_CASE(["$target_cpu"], [powerpc64*|arm64|aarch64], [ + AS_CASE(["$target_cpu"], [powerpc64*], [ ac_cv_func___builtin_setjmp=no ]) - # With gcc-8's -fcf-protection, RJIT's __builtin_longjmp fails. + # With gcc-8's -fcf-protection, MJIT's __builtin_longjmp fails. AS_CASE(["$CC $CFLAGS "], [*" -fcf-protection "*], [cf_protection=yes], [cf_protection=no]) AS_IF([test "$cf_protection" = yes], [ ac_cv_func___builtin_setjmp=no @@ -1309,7 +1261,7 @@ main() [wasi*],[ LIBS="-lm -lwasi-emulated-mman -lwasi-emulated-signal -lwasi-emulated-getpid -lwasi-emulated-process-clocks $LIBS" RUBY_APPEND_OPTIONS(CFLAGS, -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_MMAN -D_WASI_EMULATED_GETPID -D_WASI_EMULATED_PROCESS_CLOCKS) RUBY_APPEND_OPTIONS(CPPFLAGS, -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_MMAN -D_WASI_EMULATED_GETPID -D_WASI_EMULATED_PROCESS_CLOCKS) - POSTLINK="\$(WASMOPT) --asyncify \$(wasmoptflags) -o \$@ \$@${POSTLINK:+; $POSTLINK}" + POSTLINK="\$(WASMOPT) --asyncify \$(wasmoptflags) --pass-arg=asyncify-ignore-imports -o \$@ \$@${POSTLINK:+; $POSTLINK}" # wasi-libc's sys/socket.h is not compatible with -std=gnu99, # so re-declare shutdown in include/ruby/missing.h ac_cv_func_shutdown=no @@ -1317,13 +1269,6 @@ main() [ LIBS="-lm $LIBS"]) : ${ORIG_LIBS=$LIBS} -AS_IF([test -n "${POSTLINK}"], [ - # NOTE: A (part of) link commands used link shared extension libraries. If - # the first line of the value is empty, mkmf prepends default link steps. - LINK_SO="$LINK_SO -\$(POSTLINK)" -]) - AS_IF([test -n "${rb_there_is_in_fact_no_gplusplus_but_autoconf_is_cheating_us}"], [ AC_MSG_NOTICE([Test skipped due to lack of a C++ compiler.]) ], @@ -1403,18 +1348,15 @@ AC_CHECK_HEADERS(syscall.h) AC_CHECK_HEADERS(time.h) AC_CHECK_HEADERS(ucontext.h) AC_CHECK_HEADERS(utime.h) -AC_CHECK_HEADERS(sys/epoll.h) -AC_CHECK_HEADERS(sys/event.h) -AC_CHECK_HEADERS(stdckdint.h) AC_CHECK_HEADERS(stdatomic.h) -AS_CASE("$target_cpu", [x64|x86_64|[i[3-6]86*]], [ +AS_CASE("$target_cpu", [x64|x86_64|i[3-6]86*], [ AC_CHECK_HEADERS(x86intrin.h) ]) RUBY_UNIVERSAL_CHECK_HEADER([x86_64, i386], x86intrin.h) AS_IF([test "x$with_gmp" != xno], - [RUBY_CHECK_HEADER(gmp.h) + [AC_CHECK_HEADERS(gmp.h) AS_IF([test "x$ac_cv_header_gmp_h" != xno], AC_SEARCH_LIBS([__gmpz_init], [gmp], [AC_DEFINE(HAVE_LIBGMP, 1)]))]) @@ -1484,7 +1426,7 @@ AC_SYS_LARGEFILE # which is not added by AC_SYS_LARGEFILE. AS_IF([test x"$enable_largefile" != xno], [ AS_CASE(["$target_os"], [solaris*], [ - AC_MSG_CHECKING([whether _LARGEFILE_SOURCE should be defined]) + AC_MSG_CHECKING([wheather _LARGEFILE_SOURCE should be defined]) AS_CASE(["${ac_cv_sys_file_offset_bits}:${ac_cv_sys_large_files}"], ["64:"|"64:no"|"64:unknown"], [ # insert _LARGEFILE_SOURCE before _FILE_OFFSET_BITS line @@ -1545,25 +1487,6 @@ RUBY_CHECK_SIZEOF(float) RUBY_CHECK_SIZEOF(double) RUBY_CHECK_SIZEOF(time_t, [long "long long"], [], [@%:@include <time.h>]) RUBY_CHECK_SIZEOF(clock_t, [], [], [@%:@include <time.h>]) -AC_SUBST(X_BUILTIN_BINARY, yes) -AS_IF([test "$cross_compiling" = yes], -[dnl miniruby cannot run if cross compiling - X_BUILTIN_BINARY=no -], -[ - AS_CASE([ac_cv_sizeof_voidp], - [[1-9]*], [dnl fixed value - ], - [ - AC_CACHE_CHECK([word size], [rb_cv_word_size], - [for w in 4 8; do - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@if SIZEOF_VOIDP != ${w} - @%:@error SIZEOF_VOIDP - @%:@endif]])], [rb_cv_word_size=${w}; break]) - done]) - AS_IF([test -z $rb_cv_word_size], [X_BUILTIN_BINARY=no]) - ]) -]) AC_CACHE_CHECK(packed struct attribute, rb_cv_packed_struct, [rb_cv_packed_struct=no @@ -1576,9 +1499,10 @@ AC_CACHE_CHECK(packed struct attribute, rb_cv_packed_struct, [rb_cv_packed_struct=$mac; break]) done]) AS_IF([test "$rb_cv_packed_struct" != no], [ - AC_DEFINE_UNQUOTED([RBIMPL_ATTR_PACKED_STRUCT_BEGIN()], [`echo " $rb_cv_packed_struct " | sed 's/ x .*//;s/^ *//'`]) - AC_DEFINE_UNQUOTED([RBIMPL_ATTR_PACKED_STRUCT_END()], [`echo " $rb_cv_packed_struct " | sed 's/.* x //;s/ *$//'`]) + AC_DEFINE_UNQUOTED([PACKED_STRUCT(x)], [$rb_cv_packed_struct]) RUBY_TRY_CFLAGS(-Wno-address-of-packed-member, [AC_DEFINE(USE_UNALIGNED_MEMBER_ACCESS)]) +], [ + AC_DEFINE_UNQUOTED([PACKED_STRUCT(x)], x) ]) AS_IF([test "x$ac_cv_type_long_long" = xyes], [ @@ -1683,7 +1607,7 @@ AS_IF([test "$rb_cv_func_weak" != x], [ AC_DEFINE(HAVE_FUNC_WEAK) ]) -AC_CACHE_CHECK([for __attribute__((__deprecated__(msg))) in C++], +AC_CACHE_CHECK([for __attribute__((__depreacted__(msg))) in C++], rb_cv_CentOS6_CXX_workaround, RUBY_WERROR_FLAG([ AC_LANG_PUSH([C++]) @@ -1793,7 +1717,7 @@ AS_IF([test "$GCC" = yes], [ AC_CACHE_CHECK(for exported function attribute, rb_cv_func_exported, [ rb_cv_func_exported=no RUBY_WERROR_FLAG([ -for mac in '__declspec(dllexport)' '__attribute__ ((__visibility__("default")))'; do +for mac in '__attribute__ ((__visibility__("default")))' '__declspec(dllexport)'; do AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[@%:@define RUBY_FUNC_EXPORTED $mac extern RUBY_FUNC_EXPORTED void conftest_attribute_check(void);]], [[]])], [rb_cv_func_exported="$mac"; break]) @@ -1819,7 +1743,7 @@ AC_CACHE_CHECK(for function name string predefined identifier, [AS_CASE(["$target_os"],[openbsd*],[ rb_cv_function_name_string=__func__ ],[ - rb_cv_function_name_string=no + rb_cv_function_name_string=no RUBY_WERROR_FLAG([ for func in __func__ __FUNCTION__; do AC_LINK_IFELSE([AC_LANG_PROGRAM([[@%:@include <stdio.h>]], @@ -1827,8 +1751,7 @@ AC_CACHE_CHECK(for function name string predefined identifier, [rb_cv_function_name_string=$func break]) done - ]) - ])] + ])])] ) AS_IF([test "$rb_cv_function_name_string" != no], [ AC_DEFINE_UNQUOTED(RUBY_FUNCTION_NAME_STRING, [$rb_cv_function_name_string]) @@ -2088,7 +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_DECLS(atomic_signal_fence, [], [], [#include <stdatomic.h>]) AC_CHECK_FUNCS(chmod) AC_CHECK_FUNCS(chown) AC_CHECK_FUNCS(chroot) @@ -2112,7 +2035,6 @@ AC_CHECK_FUNCS(execv) AC_CHECK_FUNCS(execve) AC_CHECK_FUNCS(explicit_memset) AC_CHECK_FUNCS(fcopyfile) -AC_CHECK_FUNCS(fchdir) AC_CHECK_FUNCS(fchmod) AC_CHECK_FUNCS(fchown) AC_CHECK_FUNCS(fcntl) @@ -2153,6 +2075,7 @@ AC_CHECK_FUNCS(gettimeofday) # for making ac_cv_func_gettimeofday AC_CHECK_FUNCS(getuid) AC_CHECK_FUNCS(getuidx) AC_CHECK_FUNCS(gmtime_r) +AC_CHECK_FUNCS(grantpt) AC_CHECK_FUNCS(initgroups) AC_CHECK_FUNCS(ioctl) AC_CHECK_FUNCS(isfinite) @@ -2169,7 +2092,6 @@ AC_CHECK_FUNCS(lstat) AC_CHECK_FUNCS(lutimes) AC_CHECK_FUNCS(malloc_usable_size) AC_CHECK_FUNCS(malloc_size) -AC_CHECK_FUNCS(malloc_trim) AC_CHECK_FUNCS(mblen) AC_CHECK_FUNCS(memalign) AC_CHECK_FUNCS(memset_s) @@ -2223,7 +2145,6 @@ AC_CHECK_FUNCS(sigaction) AC_CHECK_FUNCS(sigaltstack) AC_CHECK_FUNCS(sigprocmask) AC_CHECK_FUNCS(sinh) -AC_CHECK_FUNCS(snprintf) AC_CHECK_FUNCS(spawnv) AC_CHECK_FUNCS(symlink) AC_CHECK_FUNCS(syscall) @@ -2248,6 +2169,9 @@ AC_CHECK_FUNCS(__sinpi) AS_IF([test "x$ac_cv_member_struct_statx_stx_btime" = xyes], [AC_CHECK_FUNCS(statx)]) +AS_CASE(["$ac_cv_func_memset_s:$ac_cv_func_qsort_s"], [*yes*], + [RUBY_DEFINE_IF([!defined __STDC_WANT_LIB_EXT1__], [__STDC_WANT_LIB_EXT1__], 1)]) + AS_IF([test "$ac_cv_func_getcwd" = yes], [ AC_CACHE_CHECK(if getcwd allocates buffer if NULL is given, [rb_cv_getcwd_malloc], [AC_RUN_IFELSE([AC_LANG_SOURCE([[ @@ -2316,27 +2240,6 @@ RUBY_CHECK_BUILTIN_FUNC(__builtin_types_compatible_p, [__builtin_types_compatibl RUBY_CHECK_BUILTIN_FUNC(__builtin_trap, [__builtin_trap()]) RUBY_CHECK_BUILTIN_FUNC(__builtin_expect, [__builtin_expect(0, 0)]) -AS_IF([test "$rb_cv_builtin___builtin_mul_overflow" != no], [ - AC_CACHE_CHECK(for __builtin_mul_overflow with long long arguments, rb_cv_use___builtin_mul_overflow_long_long, [ - AC_LINK_IFELSE([AC_LANG_SOURCE([[ -#pragma clang optimize off - -int -main(void) -{ - long long x = 0, y; - __builtin_mul_overflow(x, x, &y); - - return 0; -} -]])], - rb_cv_use___builtin_mul_overflow_long_long=yes, - rb_cv_use___builtin_mul_overflow_long_long=no)]) -]) -AS_IF([test "$rb_cv_use___builtin_mul_overflow_long_long" = yes], [ - AC_DEFINE(USE___BUILTIN_MUL_OVERFLOW_LONG_LONG, 1) -]) - AS_IF([test "$ac_cv_func_qsort_r" != no], [ AC_CACHE_CHECK(whether qsort_r is GNU version, rb_cv_gnu_qsort_r, [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ @@ -2724,9 +2627,6 @@ AS_CASE([$coroutine_type], [yes|''], [ [*86-mingw*], [ coroutine_type=win32 ], - [aarch64-mingw*], [ - coroutine_type=arm64 - ], [arm*-linux*], [ coroutine_type=arm32 ], @@ -2739,9 +2639,6 @@ AS_CASE([$coroutine_type], [yes|''], [ [riscv64-linux*], [ coroutine_type=riscv64 ], - [loongarch64-linux*], [ - coroutine_type=loongarch64 - ], [x86_64-freebsd*], [ coroutine_type=amd64 ], @@ -2751,12 +2648,6 @@ AS_CASE([$coroutine_type], [yes|''], [ [aarch64-freebsd*], [ coroutine_type=arm64 ], - [powerpc64-freebsd*], [ - coroutine_type=ppc64le - ], - [powerpc64le-freebsd*], [ - coroutine_type=ppc64le - ], [x86_64-netbsd*], [ coroutine_type=amd64 ], @@ -2772,9 +2663,6 @@ AS_CASE([$coroutine_type], [yes|''], [ [i386-openbsd*], [ coroutine_type=x86 ], - [aarch64-openbsd*], [ - coroutine_type=arm64 - ], [*-openbsd*], [ coroutine_type=pthread ], @@ -2872,22 +2760,6 @@ AS_IF([test "$THREAD_MODEL" = pthread], [ AC_DEFINE_UNQUOTED(SET_ANOTHER_THREAD_NAME(thid,name), $set_another_thread_name) ]) ]) - - AC_CACHE_CHECK([for thread-local storage specifier], [rb_cv_tls_specifier], - rb_cv_tls_specifier=none - RUBY_WERROR_FLAG([ - for attr in \ - _Thread_local \ - __thread \ - ; do - AC_LINK_IFELSE([AC_LANG_PROGRAM([[$attr int conftest;]])], - [rb_cv_tls_specifier=$attr; break]) - done - ]) - ) - AS_IF([test x"${rb_cv_tls_specifier}" != xnone], - [AC_DEFINE_UNQUOTED(RB_THREAD_LOCAL_SPECIFIER, ${rb_cv_tls_specifier})] - ) ]) AS_IF([test x"$ac_cv_header_ucontext_h" = xno], [ @@ -3031,8 +2903,8 @@ AS_IF([test "x$ac_cv_func_ioctl" = xyes], [ } -[begin]_group "runtime section" && { -dnl whether use dln_a_out or not +: "runtime section" && { +dnl wheather use dln_a_out or not AC_ARG_WITH(dln-a-out, AS_HELP_STRING([--with-dln-a-out], [dln_a_out is deprecated]), [ @@ -3065,8 +2937,22 @@ AS_CASE(["$target_os"], ])]) LIBEXT=a +AC_ARG_WITH(mjit-tabs, + AS_HELP_STRING([--without-mjit-tabs], [expand tabs in mjit header]), + [AS_IF([test $withval = no], [MJIT_TABS=false])]) +AC_SUBST(MJIT_TABS)dnl AC_SUBST(DLDFLAGS)dnl AC_SUBST(ARCH_FLAG)dnl +AC_SUBST(MJIT_HEADER_FLAGS)dnl +AC_SUBST(MJIT_HEADER_INSTALL_DIR)dnl +AC_SUBST(MJIT_CC)dnl +AS_CASE(["$GCC:$target_os"], + [yes:aix*], [mjit_std_cflag="-std=gnu99"], + [mjit_std_cflag=]) +AC_SUBST(MJIT_CFLAGS, [${MJIT_CFLAGS-"-w ${mjit_std_cflag} ${orig_cflags}"}])dnl +AC_SUBST(MJIT_OPTFLAGS, [${MJIT_OPTFLAGS-'$(optflags)'}])dnl +AC_SUBST(MJIT_DEBUGFLAGS, [${MJIT_DEBUGFLAGS-'$(debugflags)'}])dnl +AC_SUBST(MJIT_LDSHARED)dnl AC_SUBST(STATIC)dnl AC_SUBST(CCDLFLAGS)dnl @@ -3183,7 +3069,8 @@ AC_SUBST(EXTOBJS) : ${LIBPATHENV=DYLD_LIBRARY_PATH} : ${PRELOADENV=DYLD_INSERT_LIBRARIES} AS_IF([test x"$enable_shared" = xyes], [ - # Resolve symbols from libruby.dylib in $(LIBS) when --enable-shared + # Resolve symbols from libruby.dylib when --enable-shared + EXTDLDFLAGS='$(LIBRUBYARG_SHARED)' ], [test "x$EXTSTATIC" = x], [ # When building exts as bundles, a mach-o bundle needs to know its loader # program to bind symbols from the ruby executable @@ -3219,7 +3106,6 @@ AC_SUBST(EXTOBJS) [hiuxmpp], [ : ${LDSHARED='$(LD) -r'}], [atheos*], [ : ${LDSHARED='$(CC) -shared'} rb_cv_dlopen=yes], - [wasi*], [ : ${LDSHARED='$(LD) -shared -Xlinker --export-dynamic'}], [ : ${LDSHARED='$(LD)'}]) AC_MSG_RESULT($rb_cv_dlopen) } @@ -3475,7 +3361,7 @@ done BTESTRUBY='$(MINIRUBY)' AS_IF([test x"$cross_compiling" = xyes], [ - test x"$MINIRUBY" = x && MINIRUBY="${RUBY-$BASERUBY} -I${ac_abs_builddir-.} "-r'$(arch)-fake' + test x"$MINIRUBY" = x && MINIRUBY="${RUBY-$BASERUBY} -I`$CHDIR .; pwd` "-r'$(arch)-fake' XRUBY_LIBDIR=`${RUBY-$BASERUBY} -rrbconfig -e ['puts RbConfig::CONFIG["libdir"]']` XRUBY_RUBYLIBDIR=`${RUBY-$BASERUBY} -rrbconfig -e ['puts RbConfig::CONFIG["rubylibdir"]']` XRUBY_RUBYHDRDIR=`${RUBY-$BASERUBY} -rrbconfig -e ['puts RbConfig::CONFIG["rubyhdrdir"]']` @@ -3533,6 +3419,9 @@ AC_ARG_ENABLE(multiarch, [multiarch=], [unset multiarch]) AS_IF([test ${multiarch+set}], [ AC_DEFINE(ENABLE_MULTIARCH) + MJIT_HEADER_INSTALL_DIR=include/'${arch}/${RUBY_VERSION_NAME}' +], [ + MJIT_HEADER_INSTALL_DIR=include/'${RUBY_VERSION_NAME}/${arch}' ]) archlibdir='${libdir}/${arch}' @@ -3553,7 +3442,7 @@ AC_ARG_WITH(soname, ], [mingw*], [ RUBY_SO_NAME="${rb_cv_msvcrt}"'-$(RUBY_BASE_NAME)$(MAJOR)$(MINOR)0' - AS_IF([test x"${target_cpu}" != xi386 || test x"${rb_cv_msvcrt}" != xmsvcrt], [ + AS_IF([test x"${target_cpu}" != xi386], [ RUBY_SO_NAME="${target_cpu}-${RUBY_SO_NAME}" ]) ], @@ -3618,7 +3507,7 @@ AS_CASE("$enable_shared", [yes], [ RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ['-Wl,-soname,$(LIBRUBY_SONAME)' "$LDFLAGS_OPTDIR"]) LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_SO_NAME).$(SOEXT)' AS_IF([test "$load_relative" = yes], [ - libprefix="'\$\${ORIGIN}/../${multiarch+../../}${libdir_basename}'" + libprefix="'\$\${ORIGIN}/../${libdir_basename}'" LIBRUBY_RPATHFLAGS="-Wl,-rpath,${libprefix}" LIBRUBY_RELATIVE=yes ]) @@ -3630,7 +3519,7 @@ AS_CASE("$enable_shared", [yes], [ LIBRUBY_SO="$LIBRUBY_SO.\$(TEENY)" LIBRUBY_ALIASES='' ], [test "$load_relative" = yes], [ - libprefix="'\$\$ORIGIN/../${multiarch+../../}${libdir_basename}'" + libprefix="'\$\$ORIGIN/../${libdir_basename}'" LIBRUBY_RPATHFLAGS="-Wl,-rpath,${libprefix}" LIBRUBY_RELATIVE=yes ]) @@ -3654,7 +3543,7 @@ AS_CASE("$enable_shared", [yes], [ LIBRUBY_ALIASES='$(LIBRUBY_SONAME) lib$(RUBY_SO_NAME).$(SOEXT)' RUBY_APPEND_OPTIONS(LIBRUBY_DLDFLAGS, ["${linker_flag}-h${linker_flag:+,}"'$(@F)']) AS_IF([test "$load_relative" = yes], [ - libprefix="'\$\$ORIGIN/../${multiarch+../../}${libdir_basename}'" + libprefix="'\$\$ORIGIN/../${libdir_basename}'" LIBRUBY_RPATHFLAGS="-R${libprefix}" LIBRUBY_RELATIVE=yes ], [ @@ -3671,7 +3560,7 @@ AS_CASE("$enable_shared", [yes], [ LIBRUBY_SONAME='$(LIBRUBY_SO)' LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).$(SOEXT)' AS_IF([test "$load_relative" = yes], [ - libprefix="@executable_path/../${multiarch+../../}${libdir_basename}" + libprefix="@executable_path/../${libdir_basename}" LIBRUBY_RELATIVE=yes ]) LIBRUBY_DLDFLAGS="$LIBRUBY_DLDFLAGS -install_name ${libprefix}"'/$(LIBRUBY_SONAME)' @@ -3719,16 +3608,16 @@ AS_CASE("$enable_shared", [yes], [ ]) ]) AS_IF([test "$enable_rpath" = yes], [ - AS_CASE(["${cross_compiling}${load_relative}"], - [*yes*], [rpathflag="${RPATHFLAG}"], - [rpathflag="$RPATHFLAG${LIBPATHFLAG:+${RPATHFLAG:+ }$LIBPATHFLAG}"]) + test -z "$LIBRUBY_RPATHFLAGS" || LIBRUBY_RPATHFLAGS="$LIBRUBY_RPATHFLAGS " + rpathflag="${RPATHFLAG}" + AS_CASE(["${cross_compiling}${load_relative}"], [*yes*], [], [rpathflag="$RPATHFLAG$LIBPATHFLAG"]) rpathflag=`IFS="$PATH_SEPARATOR" echo x "$rpathflag" | sed "s/^x *//;s${IFS}"'%1\\$-s'"${IFS}${libprefix}${IFS}g;s${IFS}%s${IFS}${libprefix}${IFS}g" ` - LIBRUBY_RPATHFLAGS="${LIBRUBY_RPATHFLAGS:+$LIBRUBY_RPATHFLAGS }${rpathflag}" - LIBRUBYARG_SHARED="${LIBRUBY_RPATHFLAGS:+$LIBRUBY_RPATHFLAGS }$LIBRUBYARG_SHARED" - LIBRUBYARG_STATIC="${LIBRUBY_RPATHFLAGS:+$LIBRUBY_RPATHFLAGS }$LIBRUBYARG_STATIC" + LIBRUBY_RPATHFLAGS="$LIBRUBY_RPATHFLAGS${rpathflag}" + LIBRUBYARG_SHARED="$LIBRUBY_RPATHFLAGS $LIBRUBYARG_SHARED" + LIBRUBYARG_STATIC="$LIBRUBY_RPATHFLAGS $LIBRUBYARG_STATIC" ]) AC_SUBST(LIBRUBY_RELATIVE) @@ -3805,15 +3694,14 @@ AC_ARG_ENABLE(gcov, AS_HELP_STRING([--enable-gcov], [enable coverage measurement by gcov]), [gcov=yes]) AS_IF([test x"$gcov" = xyes], [ - CFLAGS="$CFLAGS -coverage -fprofile-update=atomic" + CFLAGS="$CFLAGS -coverage" LDFLAGS="$LDFLAGS -coverage" ]) RUBY_SETJMP_TYPE -RUBY_SHARED_GC } -[begin]_group "installation section" && { +: "build section" && { dnl build rdoc index if requested RDOCTARGET="" CAPITARGET="" @@ -3861,19 +3749,20 @@ AC_SUBST(CAPITARGET) AS_CASE(["$RDOCTARGET:$CAPITARGET"],[nodoc:nodoc],[INSTALLDOC=nodoc],[INSTALLDOC=all]) AC_SUBST(INSTALLDOC) -AC_ARG_ENABLE(install-static-library, - AS_HELP_STRING([--disable-install-static-library], [do not install static ruby library]), - [INSTALL_STATIC_LIBRARY=$enableval - AS_IF([test x"$enable_shared" = xno -a x"$INSTALL_STATIC_LIBRARY" = xno], - [AC_MSG_ERROR([must install either static or shared library])], - [])], - AS_IF([test x"$enable_shared" = xyes], - [INSTALL_STATIC_LIBRARY=no], - [INSTALL_STATIC_LIBRARY=yes])) -AC_SUBST(INSTALL_STATIC_LIBRARY) -} +AC_ARG_ENABLE(jit-support, + AS_HELP_STRING([--disable-jit-support], [disable JIT features]), + [MJIT_SUPPORT=$enableval], + [AS_CASE(["$target_os"], + [wasi | mingw* | solaris*], [MJIT_SUPPORT=no], + [MJIT_SUPPORT=yes] + )]) + +AS_IF([test x"$MJIT_SUPPORT" = "xyes"], + [AC_DEFINE(USE_MJIT, 1)], + [AC_DEFINE(USE_MJIT, 0)]) + +AC_SUBST(MJIT_SUPPORT) -[begin]_group "JIT section" && { AC_CHECK_PROG(RUSTC, [rustc], [rustc], [no]) dnl no ac_tool_prefix dnl check if rustc is recent enough to build YJIT (rustc >= 1.58.0) @@ -3919,8 +3808,8 @@ AC_ARG_ENABLE(yjit, AS_HELP_STRING([--enable-yjit], [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(["$YJIT_TARGET_OK:$YJIT_RUSTC_OK"], - [yes:yes], [ + [AS_CASE(["$enable_jit_support:$YJIT_TARGET_OK:$YJIT_RUSTC_OK"], + [yes:yes:yes|:yes:yes], [ YJIT_SUPPORT=yes ], [YJIT_SUPPORT=no] @@ -3932,6 +3821,9 @@ CARGO_BUILD_ARGS= YJIT_LIBS= AS_CASE(["${YJIT_SUPPORT}"], [yes|dev|stats|dev_nodebug], [ + AS_IF([test x"$enable_jit_support" = "xno"], + AC_MSG_ERROR([--disable-jit-support but --enable-yjit. YJIT requires JIT support]) + ) AS_IF([test x"$RUSTC" = "xno"], AC_MSG_ERROR([rustc is required. Installation instructions available at https://www.rust-lang.org/tools/install]) ) @@ -3942,17 +3834,16 @@ AS_CASE(["${YJIT_SUPPORT}"], ], [dev], [ rb_rust_target_subdir=debug - CARGO_BUILD_ARGS='--features disasm,runtime_checks' + CARGO_BUILD_ARGS='--features stats,disasm' AC_DEFINE(RUBY_DEBUG, 1) ], [dev_nodebug], [ rb_rust_target_subdir=dev_nodebug - CARGO_BUILD_ARGS='--profile dev_nodebug --features disasm' - AC_DEFINE(YJIT_STATS, 1) + CARGO_BUILD_ARGS='--profile dev_nodebug --features stats,disasm' ], [stats], [ rb_rust_target_subdir=stats - CARGO_BUILD_ARGS='--profile stats' + CARGO_BUILD_ARGS='--profile stats --features stats' AC_DEFINE(YJIT_STATS, 1) ]) @@ -3972,9 +3863,7 @@ AS_CASE(["${YJIT_SUPPORT}"], AC_DEFINE_UNQUOTED(YJIT_SUPPORT, [$YJIT_SUPPORT]) ]) AC_DEFINE(USE_YJIT, 1) -], [ - AC_DEFINE(USE_YJIT, 0) -]) +], [AC_DEFINE(USE_YJIT, 0)]) dnl These variables end up in ::RbConfig::CONFIG AC_SUBST(YJIT_SUPPORT)dnl what flavor of YJIT the Ruby build includes @@ -3984,53 +3873,17 @@ AC_SUBST(CARGO_BUILD_ARGS)dnl for selecting Rust build profiles AC_SUBST(YJIT_LIBS)dnl for optionally building the Rust parts of YJIT AC_SUBST(YJIT_OBJ)dnl for optionally building the C parts of YJIT -dnl RJIT supports only x86_64 platforms, but allows arm64/aarch64 for custom JITs. -RJIT_TARGET_OK=no -AS_IF([test "$cross_compiling" = no], - AS_CASE(["$target_cpu-$target_os"], - [*android*], [ - RJIT_TARGET_OK=no - ], - [arm64-darwin*|aarch64-darwin*|x86_64-darwin*], [ - RJIT_TARGET_OK=yes - ], - [arm64-*linux*|aarch64-*linux*|x86_64-*linux*], [ - RJIT_TARGET_OK=yes - ], - [arm64-*bsd*|aarch64-*bsd*|x86_64-*bsd*], [ - RJIT_TARGET_OK=yes - ] - ) -) - -dnl Build RJIT on supported platforms or if --enable-rjit is specified. -AC_ARG_ENABLE(rjit, - AS_HELP_STRING([--enable-rjit], - [enable pure-Ruby JIT compiler. enabled by default on Unix x86_64 platforms]), - [RJIT_SUPPORT=$enableval], - [AS_CASE(["$RJIT_TARGET_OK"], - [yes], [RJIT_SUPPORT=yes], - [RJIT_SUPPORT=no] - )] -) - -AS_CASE(["$RJIT_SUPPORT"], -[yes|dev], [ - AS_CASE(["$RJIT_SUPPORT"], - [dev], [ - # Link libcapstone for --rjit-dump-disasm - AC_CHECK_LIB([capstone], [cs_disasm]) - ]) - - AC_DEFINE(USE_RJIT, 1) -], [ - AC_DEFINE(USE_RJIT, 0) -]) - -AC_SUBST(RJIT_SUPPORT) -} +AC_ARG_ENABLE(install-static-library, + AS_HELP_STRING([--disable-install-static-library], [do not install static ruby library]), + [INSTALL_STATIC_LIBRARY=$enableval + AS_IF([test x"$enable_shared" = xno -a x"$INSTALL_STATIC_LIBRARY" = xno], + [AC_MSG_ERROR([must install either static or shared library])], + [])], + AS_IF([test x"$enable_shared" = xyes], + [INSTALL_STATIC_LIBRARY=no], + [INSTALL_STATIC_LIBRARY=yes])) +AC_SUBST(INSTALL_STATIC_LIBRARY) -[begin]_group "build section" && { AC_CACHE_CHECK([for prefix of external symbols], rb_cv_symbol_prefix, [ AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[extern void conftest_external(void) {}]], [[]])],[ rb_cv_symbol_prefix=`$NM conftest.$ac_objext | @@ -4041,25 +3894,6 @@ AC_CACHE_CHECK([for prefix of external symbols], rb_cv_symbol_prefix, [ ]) SYMBOL_PREFIX="$rb_cv_symbol_prefix" test "x$SYMBOL_PREFIX" = xNONE && SYMBOL_PREFIX='' - -AS_IF([test x"$SOEXT" = xdll], [ - # DLL on Windows is managed by win32/mkexports.rb -], [test x"$enable_shared" = xyes], [ - AC_CACHE_CHECK([for default symbols in empty shared library], rb_cv_symbols_in_emptylib, [ - save_CC="$CC" - eval CC=\"`printf "%s" "${DLDSHARED}" | sed ['s/\$(CC)/${CC}/']`\" - AC_LINK_IFELSE([AC_LANG_PROGRAM()],[ - rb_cv_symbols_in_emptylib=`$NM -Pgp conftest$ac_exeext | - sed ["/ [A-TV-Z] .*/!d;s///;s/^${SYMBOL_PREFIX}//;/^main$/d"]` - ]) - set dummy ${rb_cv_symbols_in_emptylib} - shift - rb_cv_symbols_in_emptylib="$*" - CC="$save_CC" - ]) -]) -AC_SUBST(XSYMBOLS_IN_EMPTYLIB, "${rb_cv_symbols_in_emptylib}") - DLNOBJ=dln.o AC_ARG_ENABLE(dln, AS_HELP_STRING([--disable-dln], [disable dynamic link feature]), @@ -4127,7 +3961,6 @@ enum { [mingw*], [ AS_IF([test x"$enable_shared" = xyes], [ LIBRUBY_SO='$(RUBY_SO_NAME)'.dll - LIBRUBY_SONAME='' LIBRUBY_DLDFLAGS="${LIBRUBY_DLDFLAGS}"' $(RUBYDEF)' ]) EXPORT_PREFIX=' ' @@ -4238,9 +4071,8 @@ AS_IF([test "${universal_binary-no}" = yes ], [ const char arch[[]] = __ARCHITECTURE__;]], [[puts(arch);]])], [rb_cv_architecture_available=yes], [rb_cv_architecture_available=no])) ]) -} -[end]_group +: ${MJIT_LDSHARED=`echo "$LDSHARED" | sed ['s|\$(LD)|'"${LD}"'|g;s|\$(CC)|$(MJIT_CC)|g']`} MAINLIBS="$LIBS" LIBS=$ORIG_LIBS @@ -4268,13 +4100,12 @@ AS_IF([test "${ARCH_FLAG}"], [ rb_cv_warnflags=`echo "$rb_cv_warnflags" | sed 's/^ *//;s/ *$//'` warnflags="$rb_cv_warnflags" AC_SUBST(cppflags)dnl -AC_SUBST(cflags, ['${hardenflags} '"${orig_cflags:+$orig_cflags }"' ${optflags} ${debugflags} ${warnflags}'])dnl +AC_SUBST(cflags, ["${orig_cflags:+$orig_cflags }"'${optflags} ${debugflags} ${warnflags}'])dnl AC_SUBST(cxxflags)dnl AC_SUBST(optflags)dnl AC_SUBST(debugflags)dnl AC_SUBST(warnflags)dnl AC_SUBST(strict_warnflags)dnl -AC_SUBST(hardenflags)dnl AC_SUBST(XCFLAGS)dnl AC_SUBST(XLDFLAGS)dnl AC_SUBST(EXTLDFLAGS)dnl @@ -4307,7 +4138,6 @@ AC_SUBST(MINIOBJS) AC_SUBST(THREAD_MODEL) AC_SUBST(COROUTINE_TYPE, ${coroutine_type}) AC_SUBST(PLATFORM_DIR) -AC_SUBST(USE_LLVM_WINDRES) firstmf=`echo $FIRSTMAKEFILE | sed 's/:.*//'` firsttmpl=`echo $FIRSTMAKEFILE | sed 's/.*://'` @@ -4459,10 +4289,6 @@ AS_IF([test "${universal_binary-no}" = yes ], [ arch="${target_cpu}-${target_os}" ]) AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "$arch") - - AS_IF([test "$arch" = "s390x-linux"], [ - AC_DEFINE_UNQUOTED(USE_MN_THREADS, 0) - ]) ]) unset sitearch @@ -4567,7 +4393,7 @@ guard=INCLUDE_RUBY_CONFIG_H { echo "#ifndef $guard" echo "#define $guard 1" - sed "/^@%:@define PACKAGE_/d;s/ *$//" confdefs.h + grep -v "^#define PACKAGE_" confdefs.h echo "#endif /* $guard */" } | tr -d '\015' | ( @@ -4655,9 +4481,6 @@ AC_CONFIG_FILES(Makefile:template/Makefile.in, [ ], [ echo 'distclean-local::; @$(RM) GNUmakefile uncommon.mk' ]) - - echo; echo '$(srcdir)/$(CONFIGURE):RUBY_M4_INCLUDED \ - $(empty)' } > $tmpmk && AS_IF([! grep '^ruby:' $tmpmk > /dev/null], [ AS_IF([test "${gnumake}" = yes], [ tmpgmk=confgmk$$.tmp @@ -4688,6 +4511,7 @@ AC_SUBST(DESTDIR) AC_OUTPUT } +} AS_IF([test "$silent" = yes], [], [ AS_IF([${FOLD+:} false], [], [ @@ -4724,7 +4548,6 @@ config_summary "target OS" "$target_os" config_summary "compiler" "$CC" config_summary "with thread" "$THREAD_MODEL" config_summary "with coroutine" "$coroutine_type" -config_summary "with shared GC" "$shared_gc_summary" config_summary "enable shared libs" "$ENABLE_SHARED" config_summary "dynamic library ext" "$DLEXT" config_summary "CFLAGS" "$cflags" @@ -4734,11 +4557,10 @@ config_summary "DLDFLAGS" "$DLDFLAGS" config_summary "optflags" "$optflags" config_summary "debugflags" "$debugflags" config_summary "warnflags" "$warnflags" -config_summary "hardenflags" "$hardenflags" config_summary "strip command" "$STRIP" config_summary "install doc" "$DOCTARGETS" +config_summary "MJIT support" "$MJIT_SUPPORT" config_summary "YJIT support" "$YJIT_SUPPORT" -config_summary "RJIT support" "$RJIT_SUPPORT" config_summary "man page type" "$MANTYPE" config_summary "search path" "$search_path" config_summary "static-linked-ext" ${EXTSTATIC:+"yes"} diff --git a/constant.h b/constant.h index 90a68d447a..e0d36909e1 100644 --- a/constant.h +++ b/constant.h @@ -43,11 +43,13 @@ VALUE rb_mod_deprecate_constant(int argc, const VALUE *argv, VALUE obj); void rb_free_const_table(struct rb_id_table *tbl); VALUE rb_const_source_location(VALUE, ID); +MJIT_SYMBOL_EXPORT_BEGIN int rb_autoloading_value(VALUE mod, ID id, VALUE *value, rb_const_flag_t *flag); rb_const_entry_t *rb_const_lookup(VALUE klass, ID id); VALUE rb_public_const_get_at(VALUE klass, ID id); VALUE rb_public_const_get_from(VALUE klass, ID id); int rb_public_const_defined_from(VALUE klass, ID id); VALUE rb_const_source_location_at(VALUE, ID); +MJIT_SYMBOL_EXPORT_END #endif /* CONSTANT_H */ @@ -26,16 +26,15 @@ extern int madvise(caddr_t, size_t, int); #include COROUTINE_H #include "eval_intern.h" +#include "gc.h" #include "internal.h" #include "internal/cont.h" -#include "internal/thread.h" #include "internal/error.h" -#include "internal/gc.h" #include "internal/proc.h" #include "internal/sanitizers.h" #include "internal/warnings.h" #include "ruby/fiber/scheduler.h" -#include "rjit.h" +#include "mjit.h" #include "yjit.h" #include "vm_core.h" #include "vm_sync.h" @@ -71,6 +70,8 @@ static VALUE rb_cFiberPool; #define FIBER_POOL_ALLOCATION_FREE #endif +#define jit_cont_enabled (mjit_enabled || rb_yjit_enabled_p()) + enum context_type { CONTINUATION_CONTEXT = 0, FIBER_CONTEXT = 1 @@ -177,7 +178,7 @@ struct fiber_pool { // A singly-linked list of allocations which contain 1 or more stacks each. struct fiber_pool_allocation * allocations; - // Free list that provides O(1) stack "allocation". + // Provides O(1) stack "allocation": struct fiber_pool_vacancy * vacancies; // The size of the stack allocations (excluding any guard page). @@ -189,15 +190,13 @@ struct fiber_pool { // The initial number of stacks to allocate. size_t initial_count; - // Whether to madvise(free) the stack or not. - // If this value is set to 1, the stack will be madvise(free)ed - // (or equivalent), where possible, when it is returned to the pool. + // Whether to madvise(free) the stack or not: int free_stacks; // The number of stacks that have been used in this pool. size_t used; - // The amount to allocate for the vm_stack. + // The amount to allocate for the vm_stack: size_t vm_stack_size; }; @@ -226,21 +225,22 @@ typedef struct rb_context_struct { } machine; rb_execution_context_t saved_ec; rb_jmpbuf_t jmpbuf; + rb_ensure_entry_t *ensure_array; struct rb_jit_cont *jit_cont; // Continuation contexts for JITs } rb_context_t; + /* * Fiber status: - * [Fiber.new] ------> FIBER_CREATED ----> [Fiber#kill] --> | - * | [Fiber#resume] | - * v | - * +--> FIBER_RESUMED ----> [return] ------> | - * [Fiber#resume] | | [Fiber.yield/transfer] | - * [Fiber#transfer] | v | - * +--- FIBER_SUSPENDED --> [Fiber#kill] --> | - * | - * | - * FIBER_TERMINATED <-------------------+ + * [Fiber.new] ------> FIBER_CREATED + * | [Fiber#resume] + * v + * +--> FIBER_RESUMED ----+ + * [Fiber#resume] | | [Fiber.yield] | + * | v | + * +-- FIBER_SUSPENDED | [Terminate] + * | + * FIBER_TERMINATED <-+ */ enum fiber_status { FIBER_CREATED, @@ -266,20 +266,12 @@ struct rb_fiber_struct { unsigned int yielding : 1; unsigned int blocking : 1; - unsigned int killed : 1; - struct coroutine_context context; struct fiber_pool_stack stack; }; static struct fiber_pool shared_fiber_pool = {NULL, NULL, 0, 0, 0, 0}; -void -rb_free_shared_fiber_pool(void) -{ - xfree(shared_fiber_pool.allocations); -} - static ID fiber_initialize_keywords[3] = {0}; /* @@ -700,9 +692,7 @@ fiber_pool_stack_free(struct fiber_pool_stack * stack) // If this is not true, the vacancy information will almost certainly be destroyed: VM_ASSERT(size <= (stack->size - RB_PAGE_SIZE)); - int advice = stack->pool->free_stacks >> 1; - - if (DEBUG) fprintf(stderr, "fiber_pool_stack_free: %p+%"PRIuSIZE" [base=%p, size=%"PRIuSIZE"] advice=%d\n", base, size, stack->base, stack->size, advice); + if (DEBUG) fprintf(stderr, "fiber_pool_stack_free: %p+%"PRIuSIZE" [base=%p, size=%"PRIuSIZE"]\n", base, size, stack->base, stack->size); // The pages being used by the stack can be returned back to the system. // That doesn't change the page mapping, but it does allow the system to @@ -716,29 +706,24 @@ fiber_pool_stack_free(struct fiber_pool_stack * stack) #ifdef __wasi__ // WebAssembly doesn't support madvise, so we just don't do anything. #elif VM_CHECK_MODE > 0 && defined(MADV_DONTNEED) - if (!advice) advice = MADV_DONTNEED; // This immediately discards the pages and the memory is reset to zero. - madvise(base, size, advice); + madvise(base, size, MADV_DONTNEED); #elif defined(MADV_FREE_REUSABLE) - if (!advice) advice = MADV_FREE_REUSABLE; // Darwin / macOS / iOS. // Acknowledge the kernel down to the task info api we make this // page reusable for future use. - // As for MADV_FREE_REUSABLE below we ensure in the rare occasions the task was not + // As for MADV_FREE_REUSE below we ensure in the rare occasions the task was not // completed at the time of the call to re-iterate. - while (madvise(base, size, advice) == -1 && errno == EAGAIN); + while (madvise(base, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN); #elif defined(MADV_FREE) - if (!advice) advice = MADV_FREE; // Recent Linux. - madvise(base, size, advice); + madvise(base, size, MADV_FREE); #elif defined(MADV_DONTNEED) - if (!advice) advice = MADV_DONTNEED; // Old Linux. - madvise(base, size, advice); + madvise(base, size, MADV_DONTNEED); #elif defined(POSIX_MADV_DONTNEED) - if (!advice) advice = POSIX_MADV_DONTNEED; // Solaris? - posix_madvise(base, size, advice); + posix_madvise(base, size, POSIX_MADV_DONTNEED); #elif defined(_WIN32) VirtualAlloc(base, size, MEM_RESET, PAGE_READWRITE); // Not available in all versions of Windows. @@ -795,9 +780,6 @@ static inline void ec_switch(rb_thread_t *th, rb_fiber_t *fiber) { rb_execution_context_t *ec = &fiber->cont.saved_ec; -#ifdef RUBY_ASAN_ENABLED - ec->machine.asan_fake_stack_handle = asan_get_thread_fake_stack_handle(); -#endif rb_ractor_set_current_ec(th->ractor, th->ec = ec); // ruby_current_execution_context_ptr = th->ec = ec; @@ -1025,8 +1007,13 @@ cont_mark(void *ptr) cont->machine.stack + cont->machine.stack_size); } else { - /* fiber machine context is marked as part of rb_execution_context_mark, no need to - * do anything here. */ + /* fiber */ + const rb_fiber_t *fiber = (rb_fiber_t*)cont; + + if (!FIBER_TERMINATED_P(fiber)) { + rb_gc_mark_locations(cont->machine.stack, + cont->machine.stack + cont->machine.stack_size); + } } } @@ -1052,6 +1039,7 @@ cont_free(void *ptr) if (cont->type == CONTINUATION_CONTEXT) { ruby_xfree(cont->saved_ec.vm_stack); + ruby_xfree(cont->ensure_array); RUBY_FREE_UNLESS_NULL(cont->machine.stack); } else { @@ -1062,8 +1050,10 @@ cont_free(void *ptr) RUBY_FREE_UNLESS_NULL(cont->saved_vm_stack.ptr); - VM_ASSERT(cont->jit_cont != NULL); - jit_cont_free(cont->jit_cont); + if (jit_cont_enabled) { + VM_ASSERT(cont->jit_cont != NULL); + jit_cont_free(cont->jit_cont); + } /* free rb_cont_t or rb_fiber_t */ ruby_xfree(ptr); RUBY_FREE_LEAVE("cont"); @@ -1292,42 +1282,26 @@ rb_jit_cont_each_iseq(rb_iseq_callback callback, void *data) if (cont->ec->vm_stack == NULL) continue; - const rb_control_frame_t *cfp = cont->ec->cfp; - while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(cont->ec, cfp)) { - if (cfp->pc && cfp->iseq && imemo_type((VALUE)cfp->iseq) == imemo_iseq) { - callback(cfp->iseq, data); + const rb_control_frame_t *cfp; + for (cfp = RUBY_VM_END_CONTROL_FRAME(cont->ec) - 1; ; cfp = RUBY_VM_NEXT_CONTROL_FRAME(cfp)) { + const rb_iseq_t *iseq; + if (cfp->pc && (iseq = cfp->iseq) != NULL && imemo_type((VALUE)iseq) == imemo_iseq) { + callback(iseq, data); } - cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); - } - } -} - -#if USE_YJIT -// Update the jit_return of all CFPs to leave_exit unless it's leave_exception or not set. -// This prevents jit_exec_exception from jumping to the caller after invalidation. -void -rb_yjit_cancel_jit_return(void *leave_exit, void *leave_exception) -{ - struct rb_jit_cont *cont; - for (cont = first_jit_cont; cont != NULL; cont = cont->next) { - if (cont->ec->vm_stack == NULL) - continue; - const rb_control_frame_t *cfp = cont->ec->cfp; - while (!RUBY_VM_CONTROL_FRAME_STACK_OVERFLOW_P(cont->ec, cfp)) { - if (cfp->jit_return && cfp->jit_return != leave_exception) { - ((rb_control_frame_t *)cfp)->jit_return = leave_exit; - } - cfp = RUBY_VM_PREVIOUS_CONTROL_FRAME(cfp); + if (cfp == cont->ec->cfp) + break; // reached the most recent cfp } } } -#endif // Finish working with jit_cont. void rb_jit_cont_finish(void) { + if (!jit_cont_enabled) + return; + struct rb_jit_cont *cont, *next; for (cont = first_jit_cont; cont != NULL; cont = next) { next = cont->next; @@ -1340,8 +1314,9 @@ static void cont_init_jit_cont(rb_context_t *cont) { VM_ASSERT(cont->jit_cont == NULL); - // We always allocate this since YJIT may be enabled later - cont->jit_cont = jit_cont_new(&(cont->saved_ec)); + if (jit_cont_enabled) { + cont->jit_cont = jit_cont_new(&(cont->saved_ec)); + } } struct rb_execution_context_struct * @@ -1388,11 +1363,15 @@ rb_fiberptr_blocking(struct rb_fiber_struct *fiber) return fiber->blocking; } -// Initialize the jit_cont_lock +// Start working with jit_cont. void rb_jit_cont_init(void) { + if (!jit_cont_enabled) + return; + rb_native_mutex_initialize(&jit_cont_lock); + cont_init_jit_cont(&GET_EC()->fiber_ptr->cont); } #if 0 @@ -1456,6 +1435,22 @@ cont_capture(volatile int *volatile stat) VM_ASSERT(cont->saved_ec.cfp != NULL); cont_save_machine_stack(th, cont); + /* backup ensure_list to array for search in another context */ + { + rb_ensure_list_t *p; + int size = 0; + rb_ensure_entry_t *entry; + for (p=th->ec->ensure_list; p; p=p->next) + size++; + entry = cont->ensure_array = ALLOC_N(rb_ensure_entry_t,size+1); + for (p=th->ec->ensure_list; p; p=p->next) { + if (!p->entry.marker) + p->entry.marker = rb_ary_hidden_new(0); /* dummy object */ + *entry++ = p->entry; + } + entry->marker = 0; + } + if (ruby_setjmp(cont->jmpbuf)) { VALUE value; @@ -1516,6 +1511,7 @@ cont_restore_thread(rb_context_t *cont) th->ec->tag = sec->tag; th->ec->root_lep = sec->root_lep; th->ec->root_svar = sec->root_svar; + th->ec->ensure_list = sec->ensure_list; th->ec->errinfo = sec->errinfo; VM_ASSERT(th->ec->vm_stack != NULL); @@ -1547,10 +1543,11 @@ fiber_setcontext(rb_fiber_t *new_fiber, rb_fiber_t *old_fiber) } } - /* these values are used in rb_gc_mark_machine_context to mark the fiber's stack. */ + /* exchange machine_stack_start between old_fiber and new_fiber */ old_fiber->cont.saved_ec.machine.stack_start = th->ec->machine.stack_start; - old_fiber->cont.saved_ec.machine.stack_end = FIBER_TERMINATED_P(old_fiber) ? NULL : th->ec->machine.stack_end; + /* old_fiber->machine.stack_end should be NULL */ + old_fiber->cont.saved_ec.machine.stack_end = NULL; // if (DEBUG) fprintf(stderr, "fiber_setcontext: %p[%p] -> %p[%p]\n", (void*)old_fiber, old_fiber->stack.base, (void*)new_fiber, new_fiber->stack.base); @@ -1753,13 +1750,6 @@ rb_callcc(VALUE self) return rb_yield(val); } } -#ifdef RUBY_ASAN_ENABLED -/* callcc can't possibly work with ASAN; see bug #20273. Also this function - * definition below avoids a "defined and not used" warning. */ -MAYBE_UNUSED(static void notusing_callcc(void)) { rb_callcc(Qnil); } -# define rb_callcc rb_f_notimplement -#endif - static VALUE make_passing_arg(int argc, const VALUE *argv) @@ -1778,6 +1768,80 @@ make_passing_arg(int argc, const VALUE *argv) typedef VALUE e_proc(VALUE); +/* CAUTION!! : Currently, error in rollback_func is not supported */ +/* same as rb_protect if set rollback_func to NULL */ +void +ruby_register_rollback_func_for_ensure(e_proc *ensure_func, e_proc *rollback_func) +{ + st_table **table_p = &GET_VM()->ensure_rollback_table; + if (UNLIKELY(*table_p == NULL)) { + *table_p = st_init_numtable(); + } + st_insert(*table_p, (st_data_t)ensure_func, (st_data_t)rollback_func); +} + +static inline e_proc * +lookup_rollback_func(e_proc *ensure_func) +{ + st_table *table = GET_VM()->ensure_rollback_table; + st_data_t val; + if (table && st_lookup(table, (st_data_t)ensure_func, &val)) + return (e_proc *) val; + return (e_proc *) Qundef; +} + + +static inline void +rollback_ensure_stack(VALUE self,rb_ensure_list_t *current,rb_ensure_entry_t *target) +{ + rb_ensure_list_t *p; + rb_ensure_entry_t *entry; + size_t i, j; + size_t cur_size; + size_t target_size; + size_t base_point; + e_proc *func; + + cur_size = 0; + for (p=current; p; p=p->next) + cur_size++; + target_size = 0; + for (entry=target; entry->marker; entry++) + target_size++; + + /* search common stack point */ + p = current; + base_point = cur_size; + while (base_point) { + if (target_size >= base_point && + p->entry.marker == target[target_size - base_point].marker) + break; + base_point --; + p = p->next; + } + + /* rollback function check */ + for (i=0; i < target_size - base_point; i++) { + if (!lookup_rollback_func(target[i].e_proc)) { + rb_raise(rb_eRuntimeError, "continuation called from out of critical rb_ensure scope"); + } + } + /* pop ensure stack */ + while (cur_size > base_point) { + /* escape from ensure block */ + (*current->entry.e_proc)(current->entry.data2); + current = current->next; + cur_size--; + } + /* push ensure stack */ + for (j = 0; j < i; j++) { + func = lookup_rollback_func(target[i - j - 1].e_proc); + if (!UNDEF_P((VALUE)func)) { + (*func)(target[i - j - 1].data2); + } + } +} + NORETURN(static VALUE rb_cont_call(int argc, VALUE *argv, VALUE contval)); /* @@ -1809,6 +1873,7 @@ rb_cont_call(int argc, VALUE *argv, VALUE contval) rb_raise(rb_eRuntimeError, "continuation called across fiber"); } } + rollback_ensure_stack(contval, th->ec->ensure_list, cont->ensure_array); cont->argc = argc; cont->value = make_passing_arg(argc, argv); @@ -1931,7 +1996,6 @@ fiber_t_alloc(VALUE fiber_value, unsigned int blocking) fiber->cont.self = fiber_value; fiber->cont.type = FIBER_CONTEXT; fiber->blocking = blocking; - fiber->killed = 0; cont_init(&fiber->cont, th); fiber->cont.saved_ec.fiber_ptr = fiber; @@ -1997,10 +2061,10 @@ fiber_storage_set(struct rb_fiber_struct *fiber, VALUE storage) } static inline VALUE -fiber_storage_get(rb_fiber_t *fiber, int allocate) +fiber_storage_get(rb_fiber_t *fiber) { VALUE storage = fiber->cont.saved_ec.storage; - if (storage == Qnil && allocate) { + if (storage == Qnil) { storage = rb_hash_new(); fiber_storage_set(fiber, storage); } @@ -2027,15 +2091,7 @@ static VALUE rb_fiber_storage_get(VALUE self) { storage_access_must_be_from_same_fiber(self); - - VALUE storage = fiber_storage_get(fiber_ptr(self), FALSE); - - if (storage == Qnil) { - return Qnil; - } - else { - return rb_obj_dup(storage); - } + return rb_obj_dup(fiber_storage_get(fiber_ptr(self))); } static int @@ -2115,7 +2171,8 @@ rb_fiber_storage_aref(VALUE class, VALUE key) { Check_Type(key, T_SYMBOL); - VALUE storage = fiber_storage_get(fiber_current(), FALSE); + VALUE storage = fiber_storage_get(fiber_current()); + if (storage == Qnil) return Qnil; return rb_hash_aref(storage, key); @@ -2136,15 +2193,9 @@ rb_fiber_storage_aset(VALUE class, VALUE key, VALUE value) { Check_Type(key, T_SYMBOL); - VALUE storage = fiber_storage_get(fiber_current(), value != Qnil); - if (storage == Qnil) return Qnil; + VALUE storage = fiber_storage_get(fiber_current()); - if (value == Qnil) { - return rb_hash_delete(storage, key); - } - else { - return rb_hash_aset(storage, key, value); - } + return rb_hash_aset(storage, key, value); } static VALUE @@ -2422,6 +2473,7 @@ rb_fiber_start(rb_fiber_t *fiber) rb_proc_t *proc; enum ruby_tag_type state; + int need_interrupt = TRUE; VM_ASSERT(th->ec == GET_EC()); VM_ASSERT(FIBER_RESUMED_P(fiber)); @@ -2447,7 +2499,6 @@ rb_fiber_start(rb_fiber_t *fiber) } EC_POP_TAG(); - int need_interrupt = TRUE; VALUE err = Qfalse; if (state) { err = th->ec->errinfo; @@ -2456,16 +2507,13 @@ rb_fiber_start(rb_fiber_t *fiber) if (state == TAG_RAISE) { // noop... } - else if (state == TAG_FATAL && err == RUBY_FATAL_FIBER_KILLED) { - need_interrupt = FALSE; - err = Qfalse; - } else if (state == TAG_FATAL) { rb_threadptr_pending_interrupt_enque(th, err); } else { err = rb_vm_make_jump_tag_but_local_jump(state, err); } + need_interrupt = TRUE; } rb_fiber_terminate(fiber, need_interrupt, err); @@ -2475,17 +2523,21 @@ rb_fiber_start(rb_fiber_t *fiber) void rb_threadptr_root_fiber_setup(rb_thread_t *th) { - rb_fiber_t *fiber = ruby_mimcalloc(1, sizeof(rb_fiber_t)); + rb_fiber_t *fiber = ruby_mimmalloc(sizeof(rb_fiber_t)); if (!fiber) { rb_bug("%s", strerror(errno)); /* ... is it possible to call rb_bug here? */ } + MEMZERO(fiber, rb_fiber_t, 1); fiber->cont.type = FIBER_CONTEXT; fiber->cont.saved_ec.fiber_ptr = fiber; fiber->cont.saved_ec.thread_ptr = th; fiber->blocking = 1; - fiber->killed = 0; fiber_status_set(fiber, FIBER_RESUMED); /* skip CREATED */ th->ec = &fiber->cont.saved_ec; + // When rb_threadptr_root_fiber_setup is called for the first time, mjit_enabled and + // rb_yjit_enabled_p() are still false. So this does nothing and rb_jit_cont_init() that is + // called later will take care of it. However, you still have to call cont_init_jit_cont() + // here for other Ractors, which are not initialized by rb_jit_cont_init(). cont_init_jit_cont(&fiber->cont); } @@ -2496,12 +2548,12 @@ rb_threadptr_root_fiber_release(rb_thread_t *th) /* ignore. A root fiber object will free th->ec */ } else { - rb_execution_context_t *ec = rb_current_execution_context(false); + rb_execution_context_t *ec = GET_EC(); VM_ASSERT(th->ec->fiber_ptr->cont.type == FIBER_CONTEXT); VM_ASSERT(th->ec->fiber_ptr->cont.self == 0); - if (ec && th->ec == ec) { + if (th->ec == ec) { rb_ractor_set_current_ec(th->ractor, NULL); } fiber_free(th->ec->fiber_ptr); @@ -2582,19 +2634,6 @@ fiber_store(rb_fiber_t *next_fiber, rb_thread_t *th) fiber_setcontext(next_fiber, fiber); } -static void -fiber_check_killed(rb_fiber_t *fiber) -{ - VM_ASSERT(fiber == fiber_current()); - - if (fiber->killed) { - rb_thread_t *thread = fiber->cont.saved_ec.thread_ptr; - - thread->ec->errinfo = RUBY_FATAL_FIBER_KILLED; - EC_JUMP_TAG(thread->ec, RUBY_TAG_FATAL); - } -} - static inline VALUE fiber_switch(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat, rb_fiber_t *resuming_fiber, bool yielding) { @@ -2683,14 +2722,7 @@ fiber_switch(rb_fiber_t *fiber, int argc, const VALUE *argv, int kw_splat, rb_fi current_fiber = th->ec->fiber_ptr; value = current_fiber->cont.value; - - fiber_check_killed(current_fiber); - - if (current_fiber->cont.argc == -1) { - // Fiber#raise will trigger this path. - rb_exc_raise(value); - } - + if (current_fiber->cont.argc == -1) rb_exc_raise(value); return value; } @@ -2726,8 +2758,6 @@ fiber_blocking_yield(VALUE fiber_value) rb_fiber_t *fiber = fiber_ptr(fiber_value); rb_thread_t * volatile th = fiber->cont.saved_ec.thread_ptr; - VM_ASSERT(fiber->blocking == 0); - // fiber->blocking is `unsigned int : 1`, so we use it as a boolean: fiber->blocking = 1; @@ -3130,13 +3160,12 @@ rb_fiber_s_yield(int argc, VALUE *argv, VALUE klass) } static VALUE -fiber_raise(rb_fiber_t *fiber, VALUE exception) +fiber_raise(rb_fiber_t *fiber, int argc, const VALUE *argv) { - if (fiber == fiber_current()) { - rb_exc_raise(exception); - } - else if (fiber->resuming_fiber) { - return fiber_raise(fiber->resuming_fiber, exception); + VALUE exception = rb_make_exception(argc, argv); + + if (fiber->resuming_fiber) { + rb_raise(rb_eFiberError, "attempt to raise a resuming fiber"); } else if (FIBER_SUSPENDED_P(fiber) && !fiber->yielding) { return fiber_transfer_kw(fiber, -1, &exception, RB_NO_KEYWORDS); @@ -3149,9 +3178,7 @@ fiber_raise(rb_fiber_t *fiber, VALUE exception) VALUE rb_fiber_raise(VALUE fiber, int argc, const VALUE *argv) { - VALUE exception = rb_make_exception(argc, argv); - - return fiber_raise(fiber_ptr(fiber), exception); + return fiber_raise(fiber_ptr(fiber), argc, argv); } /* @@ -3174,10 +3201,6 @@ rb_fiber_raise(VALUE fiber, int argc, const VALUE *argv) * the exception, and the third parameter is an array of callback information. * Exceptions are caught by the +rescue+ clause of <code>begin...end</code> * blocks. - * - * Raises +FiberError+ if called on a Fiber belonging to another +Thread+. - * - * See Kernel#raise for more information. */ static VALUE rb_fiber_m_raise(int argc, VALUE *argv, VALUE self) @@ -3187,46 +3210,6 @@ rb_fiber_m_raise(int argc, VALUE *argv, VALUE self) /* * call-seq: - * fiber.kill -> nil - * - * Terminates the fiber by raising an uncatchable exception. - * It only terminates the given fiber and no other fiber, returning +nil+ to - * another fiber if that fiber was calling #resume or #transfer. - * - * <tt>Fiber#kill</tt> only interrupts another fiber when it is in Fiber.yield. - * If called on the current fiber then it raises that exception at the <tt>Fiber#kill</tt> call site. - * - * If the fiber has not been started, transition directly to the terminated state. - * - * If the fiber is already terminated, does nothing. - * - * Raises FiberError if called on a fiber belonging to another thread. - */ -static VALUE -rb_fiber_m_kill(VALUE self) -{ - rb_fiber_t *fiber = fiber_ptr(self); - - if (fiber->killed) return Qfalse; - fiber->killed = 1; - - if (fiber->status == FIBER_CREATED) { - fiber->status = FIBER_TERMINATED; - } - else if (fiber->status != FIBER_TERMINATED) { - if (fiber_current() == fiber) { - fiber_check_killed(fiber); - } - else { - fiber_raise(fiber_ptr(self), Qnil); - } - } - - return self; -} - -/* - * call-seq: * Fiber.current -> fiber * * Returns the current fiber. If you are not running in the context of @@ -3383,15 +3366,6 @@ Init_Cont(void) const char *fiber_shared_fiber_pool_free_stacks = getenv("RUBY_SHARED_FIBER_POOL_FREE_STACKS"); if (fiber_shared_fiber_pool_free_stacks) { shared_fiber_pool.free_stacks = atoi(fiber_shared_fiber_pool_free_stacks); - - if (shared_fiber_pool.free_stacks < 0) { - rb_warn("Setting RUBY_SHARED_FIBER_POOL_FREE_STACKS to a negative value is not allowed."); - shared_fiber_pool.free_stacks = 0; - } - - if (shared_fiber_pool.free_stacks > 1) { - rb_warn("Setting RUBY_SHARED_FIBER_POOL_FREE_STACKS to a value greater than 1 is operating system specific, and may cause crashes."); - } } rb_cFiber = rb_define_class("Fiber", rb_cObject); @@ -3409,7 +3383,6 @@ Init_Cont(void) rb_define_method(rb_cFiber, "storage=", rb_fiber_storage_set, 1); rb_define_method(rb_cFiber, "resume", rb_fiber_m_resume, -1); rb_define_method(rb_cFiber, "raise", rb_fiber_m_raise, -1); - rb_define_method(rb_cFiber, "kill", rb_fiber_m_kill, 0); rb_define_method(rb_cFiber, "backtrace", rb_fiber_backtrace, -1); rb_define_method(rb_cFiber, "backtrace_locations", rb_fiber_backtrace_locations, -1); rb_define_method(rb_cFiber, "to_s", fiber_to_s, 0); diff --git a/coroutine/amd64/Context.S b/coroutine/amd64/Context.S index eebf9bf18e..d50732adbc 100644 --- a/coroutine/amd64/Context.S +++ b/coroutine/amd64/Context.S @@ -5,10 +5,6 @@ ## Copyright, 2018, by Samuel Williams. ## -/* Important - do _not_ include <cet.h> in this file; doing so will - * cause an incorrect .note.gnu.property section to be emitted. We have - * one at the bottom of this file */ - #define TOKEN_PASTE(x,y) x##y #define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name) @@ -17,40 +13,29 @@ .globl PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer) PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer): -#if defined(__CET__) && (__CET__ & 0x01) != 0 - /* IBT landing pad */ - endbr64 -#endif - - # Make space on the stack for 6 registers: - subq $48, %rsp + # Save caller state + pushq %rbp + pushq %rbx + pushq %r12 + pushq %r13 + pushq %r14 + pushq %r15 - # Save caller state: - movq %rbp, 40(%rsp) - movq %rbx, 32(%rsp) - movq %r12, 24(%rsp) - movq %r13, 16(%rsp) - movq %r14, 8(%rsp) - movq %r15, (%rsp) - - # Save caller stack pointer: + # Save caller stack pointer movq %rsp, (%rdi) - # Restore callee stack pointer: + # Restore callee stack pointer movq (%rsi), %rsp # Restore callee state - movq 40(%rsp), %rbp - movq 32(%rsp), %rbx - movq 24(%rsp), %r12 - movq 16(%rsp), %r13 - movq 8(%rsp), %r14 - movq (%rsp), %r15 - - # Adjust stack pointer back: - addq $48, %rsp - - # Put the first argument into the return value: + popq %r15 + popq %r14 + popq %r13 + popq %r12 + popq %rbx + popq %rbp + + # Put the first argument into the return value movq %rdi, %rax # We pop the return address and jump to it @@ -59,31 +44,3 @@ PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer): #if (defined(__linux__) || defined(__FreeBSD__)) && defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif - -#if defined(__ELF__) - -#if defined(__CET__) && (__CET__ & 0x01) != 0 -# define IBT_FLAG 0x01 -#else -# define IBT_FLAG 0x00 -#endif - -/* We do _NOT_ support CET shadow-stack. Do _not_ add the property for - * this to the Context.o object. If you require CET shadow-stack support, - * for now, consider building with --with-coroutine=ucontext */ -#define SHSTK_FLAG 0x00 - -.pushsection .note.gnu.property, "a" -.p2align 3 -.long 0x4 /* Name size ("GNU\0") */ -.long 0x10 /* Descriptor size */ -.long 0x5 /* Type: NT_GNU_PROPERTY_TYPE_0 */ -.asciz "GNU" /* Name */ -# Begin descriptor -.long 0xc0000002 /* Property type: GNU_PROPERTY_X86_FEATURE_1_AND */ -.long 0x4 /* Property size */ -.long (IBT_FLAG | SHSTK_FLAG) -.long 0x0 /* 8-byte alignment padding */ -/* End descriptor */ -.popsection -#endif diff --git a/coroutine/arm64/Context.S b/coroutine/arm64/Context.S index 2391333cae..07d50d30df 100644 --- a/coroutine/arm64/Context.S +++ b/coroutine/arm64/Context.S @@ -18,29 +18,11 @@ .align 2 #endif -#if defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT & 0x02) != 0 -# error "-mbranch-protection flag specified b-key but Context.S does not support this" -#endif - -## NOTE(PAC): Use we HINT mnemonics instead of PAC mnemonics to -## keep compatibility with those assemblers that don't support PAC. -## -## See "Providing protection for complex software" for more details about PAC/BTI -## https://developer.arm.com/architectures/learn-the-architecture/providing-protection-for-complex-software - .global PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer) PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer): -#if defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT != 0) - # paciasp (it also acts as BTI landing pad, so no need to insert BTI also) - hint #25 -#elif defined(__ARM_FEATURE_BTI_DEFAULT) && (__ARM_FEATURE_BTI_DEFAULT != 0) - # For the case PAC is not enabled but BTI is. - # bti c - hint #34 -#endif # Make space on the stack for caller registers - sub sp, sp, 0xa0 + sub sp, sp, 0xb0 # Save caller registers stp d8, d9, [sp, 0x00] @@ -54,6 +36,9 @@ PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer): stp x27, x28, [sp, 0x80] stp x29, x30, [sp, 0x90] + # Save return address + str x30, [sp, 0xa0] + # Save stack pointer to x0 (first argument) mov x2, sp str x2, [x0, 0] @@ -74,53 +59,15 @@ PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer): ldp x27, x28, [sp, 0x80] ldp x29, x30, [sp, 0x90] - # Pop stack frame - add sp, sp, 0xa0 + # Load return address into x4 + ldr x4, [sp, 0xa0] -#if defined(__ARM_FEATURE_PAC_DEFAULT) && (__ARM_FEATURE_PAC_DEFAULT != 0) - # autiasp: Authenticate x30 (LR) with SP and key A - hint #29 -#endif + # Pop stack frame + add sp, sp, 0xb0 - # Jump to return address (in x30) - ret + # Jump to return address (in x4) + ret x4 #if defined(__linux__) && defined(__ELF__) .section .note.GNU-stack,"",%progbits #endif - -#if (defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT != 0) || (defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT != 0) -#if defined(__ELF__) -/* See "ELF for the Arm 64-bit Architecture (AArch64)" - https://github.com/ARM-software/abi-aa/blob/2023Q3/aaelf64/aaelf64.rst#program-property */ -# define GNU_PROPERTY_AARCH64_FEATURE_1_BTI (1<<0) -# define GNU_PROPERTY_AARCH64_FEATURE_1_PAC (1<<1) - -# if defined(__ARM_FEATURE_BTI_DEFAULT) && __ARM_FEATURE_BTI_DEFAULT != 0 -# define BTI_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_BTI -# else -# define BTI_FLAG 0 -# endif -# if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT != 0 -# define PAC_FLAG GNU_PROPERTY_AARCH64_FEATURE_1_PAC -# else -# define PAC_FLAG 0 -# endif - - # The note section format is described by Note Section in Chapter 5 - # of "System V Application Binary Interface, Edition 4.1". - .pushsection .note.gnu.property, "a" - .p2align 3 - .long 0x4 /* Name size ("GNU\0") */ - .long 0x10 /* Descriptor size */ - .long 0x5 /* Type: NT_GNU_PROPERTY_TYPE_0 */ - .asciz "GNU" /* Name */ - # Begin descriptor - .long 0xc0000000 /* Property type: GNU_PROPERTY_AARCH64_FEATURE_1_AND */ - .long 0x4 /* Property size */ - .long (BTI_FLAG|PAC_FLAG) - .long 0x0 /* 8-byte alignment padding */ - # End descriptor - .popsection -#endif -#endif diff --git a/coroutine/arm64/Context.h b/coroutine/arm64/Context.h index eb66fbea0f..1472621f48 100644 --- a/coroutine/arm64/Context.h +++ b/coroutine/arm64/Context.h @@ -17,7 +17,7 @@ #define COROUTINE __attribute__((noreturn)) void -enum {COROUTINE_REGISTERS = 0xa0 / 8}; +enum {COROUTINE_REGISTERS = 0xb0 / 8}; #if defined(__SANITIZE_ADDRESS__) #define COROUTINE_SANITIZE_ADDRESS @@ -50,20 +50,6 @@ static inline void coroutine_initialize_main(struct coroutine_context * context) context->stack_pointer = NULL; } -static inline void *ptrauth_sign_instruction_addr(void *addr, void *modifier) { -#if defined(__ARM_FEATURE_PAC_DEFAULT) && __ARM_FEATURE_PAC_DEFAULT != 0 - // Sign the given instruction address with the given modifier and key A - register void *r17 __asm("r17") = addr; - register void *r16 __asm("r16") = modifier; - // Use HINT mnemonic instead of PACIA1716 for compatibility with older assemblers. - __asm ("hint #8;" : "+r"(r17) : "r"(r16)); - addr = r17; -#else - // No-op if PAC is not enabled -#endif - return addr; -} - static inline void coroutine_initialize( struct coroutine_context *context, coroutine_start start, @@ -80,13 +66,12 @@ static inline void coroutine_initialize( // Stack grows down. Force 16-byte alignment. char * top = (char*)stack + size; - top = (char *)((uintptr_t)top & ~0xF); - context->stack_pointer = (void**)top; + context->stack_pointer = (void**)((uintptr_t)top & ~0xF); context->stack_pointer -= COROUTINE_REGISTERS; memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS); - context->stack_pointer[0x98 / 8] = ptrauth_sign_instruction_addr((void*)start, (void*)top); + context->stack_pointer[0xa0 / 8] = (void*)start; } struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target); diff --git a/coroutine/loongarch64/Context.S b/coroutine/loongarch64/Context.S deleted file mode 100644 index 662f5dfb6c..0000000000 --- a/coroutine/loongarch64/Context.S +++ /dev/null @@ -1,73 +0,0 @@ -#define TOKEN_PASTE(x,y) x##y -#define PREFIXED_SYMBOL(prefix,name) TOKEN_PASTE(prefix,name) - -.text -.align 2 - -.global PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer) -PREFIXED_SYMBOL(SYMBOL_PREFIX,coroutine_transfer): - - # Make space on the stack for caller registers - addi.d $sp, $sp, -0xa0 - - # Save caller registers - st.d $s0, $sp, 0x00 - st.d $s1, $sp, 0x08 - st.d $s2, $sp, 0x10 - st.d $s3, $sp, 0x18 - st.d $s4, $sp, 0x20 - st.d $s5, $sp, 0x28 - st.d $s6, $sp, 0x30 - st.d $s7, $sp, 0x38 - st.d $s8, $sp, 0x40 - st.d $fp, $sp, 0x48 - fst.d $fs0, $sp, 0x50 - fst.d $fs1, $sp, 0x58 - fst.d $fs2, $sp, 0x60 - fst.d $fs3, $sp, 0x68 - fst.d $fs4, $sp, 0x70 - fst.d $fs5, $sp, 0x78 - fst.d $fs6, $sp, 0x80 - fst.d $fs7, $sp, 0x88 - - # Save return address - st.d $ra, $sp, 0x90 - - # Save stack pointer to a0 (first argument) - st.d $sp, $a0, 0x00 - - # Load stack pointer from a1 (second argument) - ld.d $sp, $a1, 0x00 - - # Restore caller registers - ld.d $s0, $sp, 0x00 - ld.d $s1, $sp, 0x08 - ld.d $s2, $sp, 0x10 - ld.d $s3, $sp, 0x18 - ld.d $s4, $sp, 0x20 - ld.d $s5, $sp, 0x28 - ld.d $s6, $sp, 0x30 - ld.d $s7, $sp, 0x38 - ld.d $s8, $sp, 0x40 - ld.d $fp, $sp, 0x48 - fld.d $fs0, $sp, 0x50 - fld.d $fs1, $sp, 0x58 - fld.d $fs2, $sp, 0x60 - fld.d $fs3, $sp, 0x68 - fld.d $fs4, $sp, 0x70 - fld.d $fs5, $sp, 0x78 - fld.d $fs6, $sp, 0x80 - fld.d $fs7, $sp, 0x88 - - # Load return address - ld.d $ra, $sp, 0x90 - - # Pop stack frame - addi.d $sp, $sp, 0xa0 - - # Jump to return address - jr $ra - -#if defined(__linux__) && defined(__ELF__) -.section .note.GNU-stack,"",%progbits -#endif diff --git a/coroutine/loongarch64/Context.h b/coroutine/loongarch64/Context.h deleted file mode 100644 index 668c9a965e..0000000000 --- a/coroutine/loongarch64/Context.h +++ /dev/null @@ -1,46 +0,0 @@ -#pragma once - -#include <assert.h> -#include <stddef.h> -#include <stdint.h> -#include <string.h> - -#define COROUTINE __attribute__((noreturn)) void - -enum {COROUTINE_REGISTERS = 0xa0 / 8}; - -struct coroutine_context -{ - void **stack_pointer; - void *argument; -}; - -typedef COROUTINE(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self); - -static inline void coroutine_initialize_main(struct coroutine_context * context) { - context->stack_pointer = NULL; -} - -static inline void coroutine_initialize( - struct coroutine_context *context, - coroutine_start start, - void *stack, - size_t size -) { - assert(start && stack && size >= 1024); - - // Stack grows down. Force 16-byte alignment. - char * top = (char*)stack + size; - context->stack_pointer = (void**)((uintptr_t)top & ~0xF); - - context->stack_pointer -= COROUTINE_REGISTERS; - memset(context->stack_pointer, 0, sizeof(void*) * COROUTINE_REGISTERS); - - context->stack_pointer[0x90 / 8] = (void*)start; -} - -struct coroutine_context * coroutine_transfer(struct coroutine_context * current, struct coroutine_context * target); - -static inline void coroutine_destroy(struct coroutine_context * context) -{ -} diff --git a/coroutine/ppc/Context.S b/coroutine/ppc/Context.S index e2431a9250..cdda93e179 100644 --- a/coroutine/ppc/Context.S +++ b/coroutine/ppc/Context.S @@ -3,7 +3,7 @@ ; Some relevant examples: https://github.com/gcc-mirror/gcc/blob/master/libphobos/libdruntime/config/powerpc/switchcontext.S ; https://github.com/gcc-mirror/gcc/blob/master/libgcc/config/rs6000/darwin-gpsave.S ; https://www.ibm.com/docs/en/aix/7.2?topic=epilogs-saving-gprs-only -; ppc32 version may be re-written compactly with stmw/lwm, but the code won't be faster, see: https://github.com/ruby/ruby/pull/5927#issuecomment-1139730541 +; ppc32 version may be re-written compactly with stmw/lwm, but the code wonʼt be faster, see: https://github.com/ruby/ruby/pull/5927#issuecomment-1139730541 ; Notice that this code is only for Darwin (macOS). Darwin ABI differs from AIX and ELF. ; To add support for AIX, *BSD or *Linux, please make separate implementations. diff --git a/coroutine/ppc/Context.h b/coroutine/ppc/Context.h index 8035d08556..1fce112579 100644 --- a/coroutine/ppc/Context.h +++ b/coroutine/ppc/Context.h @@ -13,7 +13,7 @@ enum { COROUTINE_REGISTERS = - 20 /* 19 general purpose registers (r13-r31) and 1 return address */ + 20 /* 19 general purpose registers (r13–r31) and 1 return address */ + 4 /* space for fiber_entry() to store the link register */ }; diff --git a/coroutine/ppc64/Context.h b/coroutine/ppc64/Context.h index 085b475ed5..3e6f77f55a 100644 --- a/coroutine/ppc64/Context.h +++ b/coroutine/ppc64/Context.h @@ -12,7 +12,7 @@ enum { COROUTINE_REGISTERS = - 20 /* 19 general purpose registers (r13-r31) and 1 return address */ + 20 /* 19 general purpose registers (r13–r31) and 1 return address */ + 4 /* space for fiber_entry() to store the link register */ }; diff --git a/coroutine/win64/Context.h b/coroutine/win64/Context.h index d85ebf8e0e..aaa4caeaf9 100644 --- a/coroutine/win64/Context.h +++ b/coroutine/win64/Context.h @@ -30,7 +30,7 @@ struct coroutine_context typedef void(* coroutine_start)(struct coroutine_context *from, struct coroutine_context *self); -void coroutine_trampoline(void); +void coroutine_trampoline(); static inline void coroutine_initialize_main(struct coroutine_context * context) { context->stack_pointer = NULL; diff --git a/cygwin/GNUmakefile.in b/cygwin/GNUmakefile.in index 192a8cc711..f342d2fcf7 100644 --- a/cygwin/GNUmakefile.in +++ b/cygwin/GNUmakefile.in @@ -2,15 +2,13 @@ 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)" -ifeq (@USE_LLVM_WINDRES@,yes) # USE_LLVM_WINDRES - # llvm-windres fails when preprocessor options are added - windres-cpp := -else - windres-cpp := $(CPP) -xc - windres-cpp := --preprocessor=$(firstword $(windres-cpp)) \ - $(addprefix --preprocessor-arg=,$(wordlist 2,$(words $(windres-cpp)),$(windres-cpp))) -endif +windres-cpp := $(CPP) -xc +windres-cpp := --preprocessor=$(firstword $(windres-cpp)) \ + $(addprefix --preprocessor-arg=,$(wordlist 2,$(words $(windres-cpp)),$(windres-cpp))) WINDRES = @WINDRES@ $(windres-cpp) -DRC_INVOKED STRIP = @STRIP@ @@ -46,7 +44,6 @@ SOLIBS := $(DLL_BASE_NAME).res.$(OBJEXT) $(SOLIBS) override EXTOBJS += $(if $(filter-out $(RUBYW_INSTALL_NAME),$(@:$(EXEEXT)=)),$(RUBY_INSTALL_NAME),$(@:$(EXEEXT)=)).res.$(OBJEXT) RCFILES = $(RUBY_INSTALL_NAME).rc $(RUBYW_INSTALL_NAME).rc $(DLL_BASE_NAME).rc RUBYDEF = $(DLL_BASE_NAME).def -override LIBRUBY_FOR_LEAKED_GLOBALS := # DLL shows symbols from import library ruby: $(PROGRAM) rubyw: $(WPROGRAM) @@ -69,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) @@ -5,8 +5,6 @@ #include <stddef.h> #include <stdlib.h> -#include "internal/bits.h" - // Type for a dynamic array. Use to declare a dynamic array. // It is a pointer so it fits in st_table nicely. Designed // to be fairly type-safe. @@ -39,13 +37,12 @@ // #define rb_darray_ref(ary, idx) (&((ary)->data[(idx)])) -/* Copy a new element into the array. ptr_to_ary is evaluated multiple times. - * - * void rb_darray_append(rb_darray(T) *ptr_to_ary, T element); - */ +// Copy a new element into the array. ptr_to_ary is evaluated multiple times. +// +// void rb_darray_append(rb_darray(T) *ptr_to_ary, T element); +// #define rb_darray_append(ptr_to_ary, element) do { \ - rb_darray_ensure_space((ptr_to_ary), \ - sizeof(**(ptr_to_ary)), \ + rb_darray_ensure_space((ptr_to_ary), sizeof(**(ptr_to_ary)), \ sizeof((*(ptr_to_ary))->data[0])); \ rb_darray_set(*(ptr_to_ary), \ (*(ptr_to_ary))->meta.size, \ @@ -53,65 +50,53 @@ (*(ptr_to_ary))->meta.size++; \ } while (0) -#define rb_darray_insert(ptr_to_ary, idx, element) do { \ - rb_darray_ensure_space((ptr_to_ary), \ - sizeof(**(ptr_to_ary)), \ - sizeof((*(ptr_to_ary))->data[0])); \ - MEMMOVE( \ - rb_darray_ref(*(ptr_to_ary), idx + 1), \ - rb_darray_ref(*(ptr_to_ary), idx), \ - sizeof((*(ptr_to_ary))->data[0]), \ - rb_darray_size(*(ptr_to_ary)) - idx); \ - rb_darray_set(*(ptr_to_ary), idx, element); \ - (*(ptr_to_ary))->meta.size++; \ -} while (0) + +// Last element of the array +// +#define rb_darray_back(ary) ((ary)->data[(ary)->meta.size - 1]) + +// Remove the last element of the array. +// +#define rb_darray_pop_back(ary) ((ary)->meta.size--) + +// Remove element at idx and replace it by the last element +#define rb_darray_remove_unordered(ary, idx) do { \ + rb_darray_set(ary, idx, rb_darray_back(ary)); \ + rb_darray_pop_back(ary); \ +} while (0); // Iterate over items of the array in a for loop // #define rb_darray_foreach(ary, idx_name, elem_ptr_var) \ for (size_t idx_name = 0; idx_name < rb_darray_size(ary) && ((elem_ptr_var) = rb_darray_ref(ary, idx_name)); ++idx_name) -// Iterate over valid indices in the array in a for loop +// Iterate over valid indicies in the array in a for loop // #define rb_darray_for(ary, idx_name) \ for (size_t idx_name = 0; idx_name < rb_darray_size(ary); ++idx_name) -/* Make a dynamic array of a certain size. All bytes backing the elements are set to zero. - * Return 1 on success and 0 on failure. - * - * Note that NULL is a valid empty dynamic array. - * - * void rb_darray_make(rb_darray(T) *ptr_to_ary, size_t size); - */ +// Make a dynamic array of a certain size. All bytes backing the elements are set to zero. +// +// Note that NULL is a valid empty dynamic array. +// +// void rb_darray_make(rb_darray(T) *ptr_to_ary, size_t size); +// #define rb_darray_make(ptr_to_ary, size) \ - rb_darray_make_impl((ptr_to_ary), size, sizeof(**(ptr_to_ary)), sizeof((*(ptr_to_ary))->data[0])) - -/* Resize the darray to a new capacity. The new capacity must be greater than - * or equal to the size of the darray. - * - * void rb_darray_resize_capa(rb_darray(T) *ptr_to_ary, size_t capa); - */ -#define rb_darray_resize_capa(ptr_to_ary, capa) \ - rb_darray_resize_capa_impl((ptr_to_ary), capa, sizeof(**(ptr_to_ary)), sizeof((*(ptr_to_ary))->data[0])) + rb_darray_make_impl((ptr_to_ary), size, sizeof(**(ptr_to_ary)), \ + sizeof((*(ptr_to_ary))->data[0])) #define rb_darray_data_ptr(ary) ((ary)->data) +// Set the size of the array to zero without freeing the backing memory. +// Allows reusing the same array. +// +#define rb_darray_clear(ary) (ary->meta.size = 0) + typedef struct rb_darray_meta { size_t size; size_t capa; } rb_darray_meta_t; -/* Set the size of the array to zero without freeing the backing memory. - * Allows reusing the same array. */ -static inline void -rb_darray_clear(void *ary) -{ - rb_darray_meta_t *meta = ary; - if (meta) { - meta->size = 0; - } -} - // Get the size of the dynamic array. // static inline size_t @@ -121,14 +106,6 @@ rb_darray_size(const void *ary) return meta ? meta->size : 0; } - -static inline void -rb_darray_pop(void *ary, size_t count) -{ - rb_darray_meta_t *meta = ary; - meta->size -= count; -} - // Get the capacity of the dynamic array. // static inline size_t @@ -138,36 +115,13 @@ rb_darray_capa(const void *ary) return meta ? meta->capa : 0; } -/* Free the dynamic array. */ +// Free the dynamic array. +// static inline void rb_darray_free(void *ary) { - xfree(ary); -} - -/* Internal function. Resizes the capacity of a darray. The new capacity must - * be greater than or equal to the size of the darray. */ -static inline void -rb_darray_resize_capa_impl(void *ptr_to_ary, size_t new_capa, size_t header_size, size_t element_size) -{ - rb_darray_meta_t **ptr_to_ptr_to_meta = ptr_to_ary; - rb_darray_meta_t *meta = *ptr_to_ptr_to_meta; - - rb_darray_meta_t *new_ary = xrealloc(meta, new_capa * element_size + header_size); - - if (meta == NULL) { - /* First allocation. Initialize size. On subsequence allocations - * realloc takes care of carrying over the size. */ - new_ary->size = 0; - } - - RUBY_ASSERT(new_ary->size <= new_capa); - - new_ary->capa = new_capa; - - // We don't have access to the type of the dynamic array in function context. - // Write out result with memcpy to avoid strict aliasing issue. - memcpy(ptr_to_ary, &new_ary, sizeof(new_ary)); + rb_darray_meta_t *meta = ary; + ruby_sized_xfree(ary, meta->capa); } // Internal function @@ -184,7 +138,21 @@ rb_darray_ensure_space(void *ptr_to_ary, size_t header_size, size_t element_size // Double the capacity size_t new_capa = current_capa == 0 ? 1 : current_capa * 2; - rb_darray_resize_capa_impl(ptr_to_ary, new_capa, header_size, element_size); + rb_darray_meta_t *doubled_ary = rb_xrealloc_mul_add(meta, new_capa, element_size, header_size); + // rb_xrealloc functions guarantee that NULL is not returned + assert(doubled_ary != NULL); + + if (meta == NULL) { + // First allocation. Initialize size. On subsequence allocations + // realloc takes care of carrying over the size. + doubled_ary->size = 0; + } + + doubled_ary->capa = new_capa; + + // We don't have access to the type of the dynamic array in function context. + // Write out result with memcpy to avoid strict aliasing issue. + memcpy(ptr_to_ary, &doubled_ary, sizeof(doubled_ary)); } static inline void @@ -196,7 +164,9 @@ rb_darray_make_impl(void *ptr_to_ary, size_t array_size, size_t header_size, siz return; } - rb_darray_meta_t *meta = xcalloc(array_size * element_size + header_size, 1); + rb_darray_meta_t *meta = rb_xcalloc_mul_add(array_size, element_size, header_size); + // rb_xcalloc functions guarantee that NULL is not returned + assert(meta != NULL); meta->size = array_size; meta->capa = array_size; @@ -53,8 +53,14 @@ const union { rb_econv_result_t econv_result; enum ruby_preserved_encindex encoding_index; enum ruby_robject_flags robject_flags; +#if !USE_RVARGC + enum ruby_robject_consts robject_consts; +#endif enum ruby_rmodule_flags rmodule_flags; enum ruby_rstring_flags rstring_flags; +#if !USE_RVARGC + enum ruby_rstring_consts rstring_consts; +#endif enum ruby_rarray_flags rarray_flags; enum ruby_rarray_consts rarray_consts; enum { @@ -70,7 +76,7 @@ const union { RUBY_FMODE_NOREVLOOKUP = 0x00000100, RUBY_FMODE_TRUNC = FMODE_TRUNC, RUBY_FMODE_TEXTMODE = FMODE_TEXTMODE, - RUBY_FMODE_EXTERNAL = 0x00010000, + RUBY_FMODE_PREP = 0x00010000, RUBY_FMODE_SETENC_BY_BOM = FMODE_SETENC_BY_BOM, RUBY_FMODE_UNIX = 0x00200000, RUBY_FMODE_INET = 0x00400000, @@ -112,7 +118,7 @@ ruby_debug_printf(const char *format, ...) va_end(ap); } -#include "internal/gc.h" +#include "gc.h" VALUE ruby_debug_print_value(int level, int debug_level, const char *header, VALUE obj) @@ -147,21 +153,13 @@ NODE * ruby_debug_print_node(int level, int debug_level, const char *header, const NODE *node) { if (level < debug_level) { - fprintf(stderr, "DBG> %s: %s (id: %d, line: %d, location: (%d,%d)-(%d,%d))\n", - header, ruby_node_name(nd_type(node)), nd_node_id(node), nd_line(node), - nd_first_lineno(node), nd_first_column(node), - nd_last_lineno(node), nd_last_column(node)); + fprintf(stderr, "DBG> %s: %s (%u)\n", header, + ruby_node_name(nd_type(node)), nd_line(node)); } return (NODE *)node; } void -ruby_debug_print_n(const NODE *node) -{ - ruby_debug_print_node(0, 1, "", node); -} - -void ruby_debug_breakpoint(void) { /* */ @@ -185,9 +183,9 @@ ruby_env_debug_option(const char *str, int len, void *arg) int ov; size_t retlen; unsigned long n; -#define NAME_MATCH(name) (len == sizeof(name) - 1 && strncmp(str, (name), len) == 0) #define SET_WHEN(name, var, val) do { \ - if (NAME_MATCH(name)) { \ + if (len == sizeof(name) - 1 && \ + strncmp(str, (name), len) == 0) { \ (var) = (val); \ return 1; \ } \ @@ -215,31 +213,31 @@ ruby_env_debug_option(const char *str, int len, void *arg) --len; \ } \ if (len > 0) { \ - fprintf(stderr, "ignored "name" option: '%.*s'\n", len, str); \ + fprintf(stderr, "ignored "name" option: `%.*s'\n", len, str); \ } \ } while (0) #define SET_WHEN_UINT(name, vals, num, req) \ - if (NAME_MATCH_VALUE(name)) { \ - if (!len) req; \ - else SET_UINT_LIST(name, vals, num); \ - return 1; \ - } + if (NAME_MATCH_VALUE(name)) SET_UINT_LIST(name, vals, num); - if (NAME_MATCH("gc_stress")) { - rb_gc_initial_stress_set(Qtrue); - return 1; - } + SET_WHEN("gc_stress", *ruby_initial_gc_stress_ptr, Qtrue); SET_WHEN("core", ruby_enable_coredump, 1); SET_WHEN("ci", ruby_on_ci, 1); - SET_WHEN_UINT("rgengc", &ruby_rgengc_debug, 1, ruby_rgengc_debug = 1); + if (NAME_MATCH_VALUE("rgengc")) { + if (!len) ruby_rgengc_debug = 1; + else SET_UINT_LIST("rgengc", &ruby_rgengc_debug, 1); + return 1; + } #if defined _WIN32 # if RUBY_MSVCRT_VERSION >= 80 SET_WHEN("rtc_error", ruby_w32_rtc_error, 1); # endif #endif #if defined _WIN32 || defined __CYGWIN__ - SET_WHEN_UINT("codepage", ruby_w32_codepage, numberof(ruby_w32_codepage), - fprintf(stderr, "missing codepage argument")); + if (NAME_MATCH_VALUE("codepage")) { + if (!len) fprintf(stderr, "missing codepage argument"); + else SET_UINT_LIST("codepage", ruby_w32_codepage, numberof(ruby_w32_codepage)); + return 1; + } #endif return 0; } @@ -293,20 +291,12 @@ static const char *dlf_type_names[] = { "func", }; -#ifdef MAX_PATH -#define DEBUG_LOG_MAX_PATH (MAX_PATH-1) -#else -#define DEBUG_LOG_MAX_PATH 255 -#endif - static struct { char *mem; unsigned int cnt; struct debug_log_filter filters[MAX_DEBUG_LOG_FILTER_NUM]; unsigned int filters_num; - bool show_pid; rb_nativethread_lock_t lock; - char output_file[DEBUG_LOG_MAX_PATH+1]; FILE *output; } debug_log; @@ -408,39 +398,7 @@ setup_debug_log(void) } else { ruby_debug_log_mode |= ruby_debug_log_file; - - // pid extension with %p - unsigned long len = strlen(log_config); - - for (unsigned long i=0, j=0; i<len; i++) { - const char c = log_config[i]; - - if (c == '%') { - i++; - switch (log_config[i]) { - case '%': - debug_log.output_file[j++] = '%'; - break; - case 'p': - snprintf(debug_log.output_file + j, DEBUG_LOG_MAX_PATH - j, "%d", getpid()); - j = strlen(debug_log.output_file); - break; - default: - fprintf(stderr, "can not parse RUBY_DEBUG_LOG filename: %s\n", log_config); - exit(1); - } - } - else { - debug_log.output_file[j++] = c; - } - - if (j >= DEBUG_LOG_MAX_PATH) { - fprintf(stderr, "RUBY_DEBUG_LOG=%s is too long\n", log_config); - exit(1); - } - } - - if ((debug_log.output = fopen(debug_log.output_file, "w")) == NULL) { + if ((debug_log.output = fopen(log_config, "w")) == NULL) { fprintf(stderr, "can not open %s for RUBY_DEBUG_LOG\n", log_config); exit(1); } @@ -451,17 +409,9 @@ setup_debug_log(void) (ruby_debug_log_mode & ruby_debug_log_memory) ? "[mem]" : "", (ruby_debug_log_mode & ruby_debug_log_stderr) ? "[stderr]" : "", (ruby_debug_log_mode & ruby_debug_log_file) ? "[file]" : ""); - if (debug_log.output_file[0]) { - fprintf(stderr, "RUBY_DEBUG_LOG filename=%s\n", debug_log.output_file); - } - rb_nativethread_lock_initialize(&debug_log.lock); setup_debug_log_filter(); - - if (getenv("RUBY_DEBUG_LOG_PID")) { - debug_log.show_pid = true; - } } } @@ -500,7 +450,7 @@ check_filter(const char *str, const struct debug_log_filter *filter, bool *state // (func_name or file_name) contains baz or boo // // RUBY_DEBUG_LOG_FILTER=foo,bar,-baz,-boo -// returns true if +// retunrs true if // (func_name or file_name) contains foo or bar // or // (func_name or file_name) doesn't contain baz and @@ -557,16 +507,10 @@ ruby_debug_log(const char *file, int line, const char *func_name, const char *fm int len = 0; int r = 0; - if (debug_log.show_pid) { - r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN, "pid:%d\t", getpid()); - if (r < 0) rb_bug("ruby_debug_log returns %d", r); - len += r; - } - // message title if (func_name && len < MAX_DEBUG_LOG_MESSAGE_LEN) { r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN, "%s\t", func_name); - if (r < 0) rb_bug("ruby_debug_log returns %d", r); + if (r < 0) rb_bug("ruby_debug_log returns %d\n", r); len += r; } @@ -585,67 +529,41 @@ ruby_debug_log(const char *file, int line, const char *func_name, const char *fm // C location if (file && len < MAX_DEBUG_LOG_MESSAGE_LEN) { r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN, "\t%s:%d", pretty_filename(file), line); - if (r < 0) rb_bug("ruby_debug_log returns %d", r); + if (r < 0) rb_bug("ruby_debug_log returns %d\n", r); len += r; } - rb_execution_context_t *ec = rb_current_execution_context(false); - - // Ruby location - int ruby_line; - const char *ruby_file = ec ? rb_source_location_cstr(&ruby_line) : NULL; - - if (len < MAX_DEBUG_LOG_MESSAGE_LEN) { - if (ruby_file) { - r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\t%s:%d", pretty_filename(ruby_file), ruby_line); - } - else { - r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\t"); + if (rb_current_execution_context(false)) { + // Ruby location + int ruby_line; + const char *ruby_file = rb_source_location_cstr(&ruby_line); + if (len < MAX_DEBUG_LOG_MESSAGE_LEN) { + if (ruby_file) { + r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\t%s:%d", pretty_filename(ruby_file), ruby_line); + } + else { + r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\t"); + } + if (r < 0) rb_bug("ruby_debug_log returns %d\n", r); + len += r; } - if (r < 0) rb_bug("ruby_debug_log returns %d", r); - len += r; - } - -#ifdef RUBY_NT_SERIAL - // native thread information - if (len < MAX_DEBUG_LOG_MESSAGE_LEN) { - r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\tnt:%d", ruby_nt_serial); - if (r < 0) rb_bug("ruby_debug_log returns %d", r); - len += r; - } -#endif - - if (ec) { - rb_thread_t *th = ec ? rb_ec_thread_ptr(ec) : NULL; // ractor information if (ruby_single_main_ractor == NULL) { - rb_ractor_t *cr = th ? th->ractor : NULL; - rb_vm_t *vm = GET_VM(); - + rb_ractor_t *cr = GET_RACTOR(); if (r && len < MAX_DEBUG_LOG_MESSAGE_LEN) { - r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\tr:#%d/%u (%u)", - cr ? (int)rb_ractor_id(cr) : -1, vm->ractor.cnt, vm->ractor.sched.running_cnt); - - if (r < 0) rb_bug("ruby_debug_log returns %d", r); + r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\tr:#%u/%u", + (unsigned int)rb_ractor_id(cr), GET_VM()->ractor.cnt); + if (r < 0) rb_bug("ruby_debug_log returns %d\n", r); len += r; } } // thread information - if (th && r && len < MAX_DEBUG_LOG_MESSAGE_LEN) { - rb_execution_context_t *rec = th->ractor ? th->ractor->threads.running_ec : NULL; - const rb_thread_t *rth = rec ? rec->thread_ptr : NULL; - const rb_thread_t *sth = th->ractor ? th->ractor->threads.sched.running : NULL; - - if (rth != th || sth != th) { - r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\tth:%u (rth:%d,sth:%d)", - rb_th_serial(th), rth ? (int)rb_th_serial(rth) : -1, sth ? (int)rb_th_serial(sth) : -1); - } - else { - r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\tth:%u", rb_th_serial(th)); - } - if (r < 0) rb_bug("ruby_debug_log returns %d", r); + const rb_thread_t *th = GET_THREAD(); + if (r && len < MAX_DEBUG_LOG_MESSAGE_LEN) { + r = snprintf(buff + len, MAX_DEBUG_LOG_MESSAGE_LEN - len, "\tth:%u", rb_th_serial(th)); + if (r < 0) rb_bug("ruby_debug_log returns %d\n", r); len += r; } } @@ -683,7 +601,7 @@ debug_log_dump(FILE *out, unsigned int n) int index = current_index - size + i; if (index < 0) index += MAX_DEBUG_LOG; VM_ASSERT(index <= MAX_DEBUG_LOG); - const char *mesg = RUBY_DEBUG_LOG_MEM_ENTRY(index); + const char *mesg = RUBY_DEBUG_LOG_MEM_ENTRY(index);; fprintf(out, "%4u: %s\n", debug_log.cnt - size + i, mesg); } } diff --git a/debug_counter.c b/debug_counter.c index 3dcc4c6a3a..463bebf849 100644 --- a/debug_counter.c +++ b/debug_counter.c @@ -25,8 +25,10 @@ const char *const rb_debug_counter_names[] = { #undef RB_DEBUG_COUNTER }; +MJIT_SYMBOL_EXPORT_BEGIN size_t rb_debug_counter[numberof(rb_debug_counter_names)]; void rb_debug_counter_add_atomic(enum rb_debug_counter_type type, int add); +MJIT_SYMBOL_EXPORT_END static rb_nativethread_lock_t debug_counter_lock; diff --git a/debug_counter.h b/debug_counter.h index 481a0727e6..6e0b8dee60 100644 --- a/debug_counter.h +++ b/debug_counter.h @@ -100,13 +100,6 @@ RB_DEBUG_COUNTER(ccf_opt_block_call) RB_DEBUG_COUNTER(ccf_opt_struct_aref) RB_DEBUG_COUNTER(ccf_opt_struct_aset) RB_DEBUG_COUNTER(ccf_super_method) -RB_DEBUG_COUNTER(ccf_cfunc_other) -RB_DEBUG_COUNTER(ccf_cfunc_only_splat) -RB_DEBUG_COUNTER(ccf_cfunc_only_splat_kw) -RB_DEBUG_COUNTER(ccf_iseq_bmethod) -RB_DEBUG_COUNTER(ccf_noniseq_bmethod) -RB_DEBUG_COUNTER(ccf_opt_send_complex) -RB_DEBUG_COUNTER(ccf_opt_send_simple) /* * control frame push counts. @@ -134,22 +127,29 @@ RB_DEBUG_COUNTER(frame_R2C) RB_DEBUG_COUNTER(frame_C2C) RB_DEBUG_COUNTER(frame_C2R) -/* instance variable counts */ -RB_DEBUG_COUNTER(ivar_get_obj_hit) // Only T_OBJECT hits -RB_DEBUG_COUNTER(ivar_get_obj_miss) // Only T_OBJECT misses -RB_DEBUG_COUNTER(ivar_get_ic_hit) // All hits -RB_DEBUG_COUNTER(ivar_get_ic_miss) // All misses -RB_DEBUG_COUNTER(ivar_set_ic_hit) // All hits -RB_DEBUG_COUNTER(ivar_set_obj_hit) // Only T_OBJECT hits -RB_DEBUG_COUNTER(ivar_set_obj_miss) // Only T_OBJECT misses -RB_DEBUG_COUNTER(ivar_set_ic_miss) // All misses -RB_DEBUG_COUNTER(ivar_set_ic_miss_noobject) // Miss because non T_OBJECT -RB_DEBUG_COUNTER(ivar_get_base) // Calls to `rb_ivar_get` (very slow path) -RB_DEBUG_COUNTER(ivar_set_base) // Calls to `ivar_set` (very slow path) -RB_DEBUG_COUNTER(ivar_get_ic_miss_set) // Misses on IV reads where the cache was wrong -RB_DEBUG_COUNTER(ivar_get_cc_miss_set) // Misses on attr_reader where the cache was wrong -RB_DEBUG_COUNTER(ivar_get_ic_miss_unset) // Misses on IV read where the cache wasn't set -RB_DEBUG_COUNTER(ivar_get_cc_miss_unset) // Misses on attr_reader where the cache wasn't set +/* instance variable counts + * + * * ivar_get_ic_hit/miss: ivar_get inline cache (ic) hit/miss counts (VM insn) + * * ivar_get_ic_miss_unset: ... by unset (VM insn) + * * ivar_get_ic_miss_noobject: ... by "not T_OBJECT" (VM insn) + * * ivar_set_...: same counts with ivar_set (VM insn) + * * ivar_get/set_base: call counts of "rb_ivar_get/set()". + * because of (1) ic miss. + * (2) direct call by C extensions. + */ +RB_DEBUG_COUNTER(ivar_get_ic_hit) +RB_DEBUG_COUNTER(ivar_get_ic_miss) +RB_DEBUG_COUNTER(ivar_get_ic_miss_noobject) +RB_DEBUG_COUNTER(ivar_set_ic_hit) +RB_DEBUG_COUNTER(ivar_set_ic_miss) +RB_DEBUG_COUNTER(ivar_set_ic_miss_iv_hit) +RB_DEBUG_COUNTER(ivar_set_ic_miss_noobject) +RB_DEBUG_COUNTER(ivar_get_base) +RB_DEBUG_COUNTER(ivar_set_base) +RB_DEBUG_COUNTER(ivar_get_ic_miss_set) +RB_DEBUG_COUNTER(ivar_get_cc_miss_set) +RB_DEBUG_COUNTER(ivar_get_ic_miss_unset) +RB_DEBUG_COUNTER(ivar_get_cc_miss_unset) /* local variable counts * @@ -185,7 +185,8 @@ RB_DEBUG_COUNTER(gc_major_force) RB_DEBUG_COUNTER(gc_major_oldmalloc) RB_DEBUG_COUNTER(gc_enter_start) -RB_DEBUG_COUNTER(gc_enter_continue) +RB_DEBUG_COUNTER(gc_enter_mark_continue) +RB_DEBUG_COUNTER(gc_enter_sweep_continue) RB_DEBUG_COUNTER(gc_enter_rest) RB_DEBUG_COUNTER(gc_enter_finalizer) @@ -214,6 +215,7 @@ RB_DEBUG_COUNTER(gc_isptr_maybe) * * [attr] * * _ptr: R?? is not embed. * * _embed: R?? is embed. + * * _transient: R?? uses transient heap. * * type specific attr. * * str_shared: str is shared. * * str_nofree: nofree @@ -239,6 +241,7 @@ RB_DEBUG_COUNTER(obj_promote) RB_DEBUG_COUNTER(obj_wb_unprotect) RB_DEBUG_COUNTER(obj_obj_embed) +RB_DEBUG_COUNTER(obj_obj_transient) RB_DEBUG_COUNTER(obj_obj_ptr) RB_DEBUG_COUNTER(obj_obj_too_complex) @@ -249,6 +252,7 @@ RB_DEBUG_COUNTER(obj_str_nofree) RB_DEBUG_COUNTER(obj_str_fstr) RB_DEBUG_COUNTER(obj_ary_embed) +RB_DEBUG_COUNTER(obj_ary_transient) RB_DEBUG_COUNTER(obj_ary_ptr) RB_DEBUG_COUNTER(obj_ary_extracapa) /* @@ -272,9 +276,11 @@ RB_DEBUG_COUNTER(obj_hash_g8) RB_DEBUG_COUNTER(obj_hash_null) RB_DEBUG_COUNTER(obj_hash_ar) RB_DEBUG_COUNTER(obj_hash_st) +RB_DEBUG_COUNTER(obj_hash_transient) RB_DEBUG_COUNTER(obj_hash_force_convert) RB_DEBUG_COUNTER(obj_struct_embed) +RB_DEBUG_COUNTER(obj_struct_transient) RB_DEBUG_COUNTER(obj_struct_ptr) RB_DEBUG_COUNTER(obj_data_empty) @@ -329,6 +335,11 @@ RB_DEBUG_COUNTER(heap_xmalloc) RB_DEBUG_COUNTER(heap_xrealloc) RB_DEBUG_COUNTER(heap_xfree) +/* transient_heap */ +RB_DEBUG_COUNTER(theap_alloc) +RB_DEBUG_COUNTER(theap_alloc_fail) +RB_DEBUG_COUNTER(theap_evacuate) + // VM sync RB_DEBUG_COUNTER(vm_sync_lock) RB_DEBUG_COUNTER(vm_sync_lock_enter) @@ -356,7 +367,7 @@ RB_DEBUG_COUNTER(load_path_is_not_realpath) enum rb_debug_counter_type { #define RB_DEBUG_COUNTER(name) RB_DEBUG_COUNTER_##name, -#include "debug_counter.h" +#include __FILE__ RB_DEBUG_COUNTER_MAX #undef RB_DEBUG_COUNTER }; diff --git a/defs/gmake.mk b/defs/gmake.mk index b34e8420ba..54fef6685f 100644 --- a/defs/gmake.mk +++ b/defs/gmake.mk @@ -1,19 +1,20 @@ # -*- mode: makefile-gmake; indent-tabs-mode: t -*- reconfig config.status: export MAKE:=$(MAKE) -export BASERUBY:=$(BASERUBY) override gnumake_recursive := $(if $(findstring n,$(firstword $(MFLAGS))),,+) override mflags := $(filter-out -j%,$(MFLAGS)) MSPECOPT += $(if $(filter -j%,$(MFLAGS)),-j) nproc = $(subst -j,,$(filter -j%,$(MFLAGS))) ifeq ($(GITHUB_ACTIONS),true) -# 93(bright yellow) is copied from .github/workflows/mingw.yml -override ACTIONS_GROUP = @echo "::group::[93m$(@:yes-%=%)[m" -override ACTIONS_ENDGROUP = @echo "::endgroup::" +override ACTIONS_GROUP = @echo "\#\#[group]$(patsubst yes-%,%,$@)" +override ACTIONS_ENDGROUP = @echo "\#\#[endgroup]" endif ifneq ($(filter darwin%,$(target_os)),) +# Remove debug option not to generate thousands of .dSYM +MJIT_DEBUGFLAGS := $(filter-out -g%,$(MJIT_DEBUGFLAGS)) + INSTRUBY_ENV += SDKROOT= endif INSTRUBY_ARGS += --gnumake @@ -25,7 +26,7 @@ TEST_TARGETS := $(filter $(CHECK_TARGETS),$(MAKECMDGOALS)) 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,test-bundled-gems test-bundler-parallel check,$(TEST_TARGETS)) +TEST_TARGETS := $(patsubst exam,check,$(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)) @@ -36,15 +37,12 @@ TEST_DEPENDS := $(filter-out test-all $(TEST_TARGETS),$(TEST_DEPENDS)) TEST_TARGETS := $(patsubst test,test-short,$(TEST_TARGETS)) TEST_DEPENDS := $(filter-out test $(TEST_TARGETS),$(TEST_DEPENDS)) TEST_TARGETS := $(patsubst test-short,btest-ruby test-knownbug test-basic,$(TEST_TARGETS)) -TEST_TARGETS := $(patsubst test-basic,test-basic test-leaked-globals,$(TEST_TARGETS)) -TEST_TARGETS := $(patsubst test-bundled-gems,test-bundled-gems-spec test-bundled-gems-run,$(TEST_TARGETS)) +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-bundler-parallel,test-bundler-parallel $(PREPARE_BUNDLER),$(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) -TEST_TARGETS := $(patsubst yes-%,%,$(filter-out no-%,$(TEST_TARGETS))) endif in-srcdir := $(if $(filter-out .,$(srcdir)),$(CHDIR) $(srcdir) &&) @@ -57,13 +55,6 @@ ifeq ($(if $(filter all main exts enc trans libencs libenc libtrans \ -include $(SHOWFLAGS) endif -ifeq ($(HAVE_BASERUBY):$(HAVE_GIT),yes:yes) -override modified := $(shell $(BASERUBY) -C $(srcdir) tool/file2lastrev.rb --modified='%Y %m %d') -override RUBY_RELEASE_YEAR := $(word 1,$(modified)) -override RUBY_RELEASE_MONTH := $(word 2,$(modified)) -override RUBY_RELEASE_DAY := $(word 3,$(modified)) -endif - ifneq ($(filter universal-%,$(arch)),) define archcmd %.$(1).S: %.c @@ -79,7 +70,7 @@ define archcmd %.i: %.$(1).i endef -$(foreach arch,$(filter -arch=%,$(subst -arch ,-arch=,$(ARCH_FLAG))),\ +$(foreach arch,$(arch_flags),\ $(eval $(call archcmd,$(patsubst -arch=%,%,$(value arch)),$(patsubst -arch=%,-arch %,$(value arch))))) endif @@ -91,32 +82,16 @@ $(addprefix yes-,$(TEST_TARGETS)): $(TEST_DEPENDS) endif ORDERED_TEST_TARGETS := $(filter $(TEST_TARGETS), \ - btest-ruby test-knownbug test-leaked-globals test-basic \ + btest-ruby test-knownbug test-basic \ test-testframework test-tool test-ruby test-all \ 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 \ - test-bundled-gems-spec \ ) - -# grep ^yes-test-.*-precheck: template/Makefile.in defs/gmake.mk common.mk -test_prechecks := $(filter $(ORDERED_TEST_TARGETS),\ - test-leaked-globals \ - test-all \ - test-spec \ - test-syntax-suggest \ - test-bundler \ - test-bundler-parallel \ - test-bundled-gems\ - ) -prev_test := $(subst test-bundler-parallel,test-bundler,$(test_prechecks)) -prev_test := $(addsuffix -precheck,$(prev_test)) -first_test_prechecks := $(prev_test) - +prev_test := $(if $(filter test-spec,$(ORDERED_TEST_TARGETS)),test-spec-precheck) $(foreach test,$(ORDERED_TEST_TARGETS), \ - $(eval yes-$(value test): $(addprefix yes-,$(value prev_test))); \ - $(eval no-$(value test): $(addprefix no-,$(value prev_test))); \ + $(eval yes-$(value test) no-$(value test): $(value prev_test)); \ $(eval prev_test := $(value test))) endif @@ -194,22 +169,15 @@ $(SCRIPTBINDIR): $(Q) mkdir $@ .PHONY: commit -COMMIT_PREPARE := $(subst :,\:,$(filter-out commit do-commit,$(MAKECMDGOALS))) up - -commit: pre-commit $(DOT_WAIT) do-commit $(DOT_WAIT) post_commit -pre-commit: $(COMMIT_PREPARE) -do-commit: $(if $(DOT_WAIT),,pre-commit) +commit: $(if $(filter commit,$(MAKECMDGOALS)),$(filter-out commit,$(MAKECMDGOALS))) up @$(BASERUBY) -C "$(srcdir)" -I./tool/lib -rvcs -e 'VCS.detect(".").commit' -post-commit: $(if $(DOT_WAIT),,do-commit) +$(Q) \ { \ $(in-srcdir) \ exec sed -f tool/prereq.status defs/gmake.mk template/Makefile.in common.mk; \ } | \ - $(MAKE) $(mflags) Q=$(Q) ECHO=$(ECHO) \ - top_srcdir="$(top_srcdir)" srcdir="$(srcdir)" srcs_vpath="" CHDIR="$(CHDIR)" \ - BOOTSTRAPRUBY="$(BOOTSTRAPRUBY)" BOOTSTRAPRUBY_OPT="$(BOOTSTRAPRUBY_OPT)" \ - MINIRUBY="$(BASERUBY)" BASERUBY="$(BASERUBY)" HAVE_BASERUBY="$(HAVE_BASERUBY)" \ + $(MAKE) $(mflags) Q=$(Q) ECHO=$(ECHO) srcdir="$(srcdir)" srcs_vpath="" CHDIR="$(CHDIR)" \ + BOOTSTRAPRUBY="$(BOOTSTRAPRUBY)" MINIRUBY="$(BASERUBY)" BASERUBY="$(BASERUBY)" \ VCSUP="" ENC_MK=.top-enc.mk REVISION_FORCE=PHONY CONFIGURE="$(CONFIGURE)" -f - \ update-src srcs all-incs @@ -300,7 +268,6 @@ HELP_EXTRA_TASKS = \ " checkout-github: checkout GitHub Pull Request [PR=1234]" \ " pull-github: rebase GitHub Pull Request to new worktree [PR=1234]" \ " update-github: merge master branch and push it to Pull Request [PR=1234]" \ - " tags: generate TAGS file" \ "" # 1. squeeze spaces @@ -325,13 +292,12 @@ foreach-bundled-gems-rev = \ foreach-bundled-gems-rev-0 = \ $(call $(1),$(word 1,$(2)),$(word 2,$(2)),$(word 3,$(2)),$(word 4,$(2))) bundled-gem-gemfile = $(srcdir)/gems/$(1)-$(2).gem -bundled-gem-gemspec = $(srcdir)/gems/src/$(1)/$(1).gemspec +bundled-gem-srcdir = $(srcdir)/gems/src/$(1) bundled-gem-extracted = $(srcdir)/.bundle/gems/$(1)-$(2) -bundled-gem-revision = $(srcdir)/.bundle/.timestamp/$(1).revision update-gems: | $(patsubst %,$(srcdir)/gems/%.gem,$(bundled-gems)) update-gems: | $(call foreach-bundled-gems-rev,bundled-gem-gemfile) -update-gems: | $(call foreach-bundled-gems-rev,bundled-gem-gemspec) +update-gems: | $(call foreach-bundled-gems-rev,bundled-gem-srcdir) test-bundler-precheck: | $(srcdir)/.bundle/cache @@ -359,44 +325,27 @@ $(srcdir)/.bundle/gems/%: $(srcdir)/gems/%.gem | .bundle/gems -Itool/lib -rbundled_gem \ -e 'BundledGem.unpack("gems/$(@F).gem", ".bundle")' -$(srcdir)/.bundle/.timestamp: - $(MAKEDIRS) $@ - -define build-gem -$(srcdir)/gems/src/$(1)/.git: | $(srcdir)/gems/src +define copy-gem +$(srcdir)/gems/src/$(1): | $(srcdir)/gems/src $(ECHO) Cloning $(4) - $(Q) $(GIT) clone $(4) $$(@D) + $(Q) $(GIT) clone $(4) $$(@) -$(bundled-gem-revision): \ - $(if $(if $(wildcard $$(@)),$(filter $(3),$(shell cat $$(@)))),,PHONY) \ - | $(srcdir)/.bundle/.timestamp $(srcdir)/gems/src/$(1)/.git - $(ECHO) Update $(1) to $(3) +$(srcdir)/.bundle/gems/$(1)-$(2): | $(srcdir)/gems/src/$(1) .bundle/gems + $(ECHO) Copying $(1)@$(3) to $$(@F) $(Q) $(CHDIR) "$(srcdir)/gems/src/$(1)" && \ - if [ `$(GIT) rev-parse HEAD` != $(3) ]; then \ - $(GIT) fetch origin $(3) && \ - $(GIT) checkout --detach $(3) && \ - :; \ - fi - echo $(3) | $(IFCHANGE) $$(@) - - -# The repository of minitest does not include minitest.gemspec because it uses hoe. -# This creates a dummy gemspec. -$(bundled-gem-gemspec): $(bundled-gem-revision) \ - | $(srcdir)/gems/src/$(1)/.git - $(Q) $(BASERUBY) -I$(tooldir)/lib -rbundled_gem -e 'BundledGem.dummy_gemspec(*ARGV)' $$(@) - -$(bundled-gem-gemfile): $(bundled-gem-gemspec) $(bundled-gem-revision) - $(ECHO) Building $(1)@$(3) to $$(@) + $(GIT) fetch origin $(3) && \ + $(GIT) checkout --detach $(3) && \ + : $(Q) $(BASERUBY) -C "$(srcdir)" \ -Itool/lib -rbundled_gem \ - -e 'BundledGem.build("gems/src/$(1)/$(1).gemspec", "$(2)", "gems", validation: false)' + -e 'BundledGem.copy("gems/src/$(1)/$(1).gemspec", ".bundle")' endef -define build-gem-0 -$(eval $(call build-gem,$(1),$(2),$(3),$(4))) +define copy-gem-0 +$(eval $(call copy-gem,$(1),$(2),$(3),$(4))) endef -$(call foreach-bundled-gems-rev,build-gem-0) +$(call foreach-bundled-gems-rev,copy-gem-0) $(srcdir)/gems/src: $(MAKEDIRS) $@ @@ -404,36 +353,49 @@ $(srcdir)/gems/src: $(srcdir)/.bundle/gems: $(MAKEDIRS) $@ -ifneq ($(DOT_WAIT),) -up:: $(DOT_WAIT) after-update -endif - ifneq ($(filter update-bundled_gems refresh-gems,$(MAKECMDGOALS)),) update-gems: update-bundled_gems endif +ifeq ($(filter 0 1,$(words $(arch_flags))),) +$(foreach x,$(patsubst -arch=%,%,$(arch_flags)), \ + $(eval $$(MJIT_HEADER:.h=)-$(value x).h \ + $$(MJIT_MIN_HEADER:.h=)-$(value x).h \ + $$(TIMESTAMPDIR)/$$(MJIT_HEADER:.h=)-$(value x).time \ + : ARCH_FLAG := -arch $(value x))) + +$(foreach x,$(patsubst -arch=%,%,$(arch_flags)), \ + $(eval $$(MJIT_HEADER:.h=)-$(value x).h: \ + $$(TIMESTAMPDIR)/$$(MJIT_HEADER:.h=)-$(value x).time)) + +mjit_min_headers := $(patsubst -arch=%,$(MJIT_MIN_HEADER:.h=-%.h),$(arch_flags)) +$(MJIT_MIN_HEADER): $(mjit_min_headers) $(PREP) + @ set -e; set $(patsubst -arch=%,%,$(arch_flags)); \ + cd $(@D); h=$(@F:.h=); \ + exec > $(@F).new; \ + echo '#if 0'; \ + for arch; do\ + echo "#elif defined __$${arch}__"; \ + echo "# include \"$$h-$$arch.h\""; \ + done; \ + echo "#else"; echo "# error unsupported platform"; echo "#endif" + $(IFCHANGE) $@ $@.new + $(Q) $(MAKEDIRS) $(MJIT_HEADER_INSTALL_DIR) + $(Q) $(MAKE_LINK) $@ $(MJIT_HEADER_INSTALL_DIR)/$(@F) + +endif + .SECONDARY: update-unicode-files .SECONDARY: update-unicode-auxiliary-files .SECONDARY: update-unicode-ucd-emoji-files .SECONDARY: update-unicode-emoji-files -ifneq ($(DOT_WAIT),) -.NOTPARALLEL: update-unicode -.NOTPARALLEL: update-unicode-files -.NOTPARALLEL: update-unicode-auxiliary-files -.NOTPARALLEL: update-unicode-ucd-emoji-files -.NOTPARALLEL: update-unicode-emoji-files -.NOTPARALLEL: $(UNICODE_FILES) $(UNICODE_PROPERTY_FILES) -.NOTPARALLEL: $(UNICODE_AUXILIARY_FILES) -.NOTPARALLEL: $(UNICODE_UCD_EMOJI_FILES) $(UNICODE_EMOJI_FILES) -endif - ifeq ($(HAVE_GIT),yes) REVISION_LATEST := $(shell $(CHDIR) $(srcdir) && $(GIT) log -1 --format=%H 2>/dev/null) else REVISION_LATEST := update endif -REVISION_IN_HEADER := $(shell sed '/^\#define RUBY_FULL_REVISION "\(.*\)"/!d;s//\1/;q' $(wildcard $(srcdir)/revision.h revision.h) /dev/null 2>/dev/null) +REVISION_IN_HEADER := $(shell sed -n 's/^\#define RUBY_FULL_REVISION "\(.*\)"/\1/p' $(wildcard $(srcdir)/revision.h revision.h) /dev/null 2>/dev/null) ifeq ($(REVISION_IN_HEADER),) REVISION_IN_HEADER := none endif @@ -470,10 +432,6 @@ benchmark/%: miniruby$(EXEEXT) update-benchmark-driver PHONY --executables="built-ruby::$(BENCH_RUBY) --disable-gem" \ $(srcdir)/$@ $(BENCH_OPTS) $(OPTS) -clean-local:: TARGET_SO = $(PROGRAM) $(WPROGRAM) $(LIBRUBY_SO) $(STATIC_RUBY) miniruby goruby -clean-local:: - -$(Q)$(RMALL) $(cleanlibs) - clean-srcs-ext:: $(Q)$(RM) $(patsubst $(srcdir)/%,%,$(EXT_SRCS)) @@ -508,18 +466,13 @@ update-deps: $(RUBYSPEC_CAPIEXT)/%.$(DLEXT): $(srcdir)/$(RUBYSPEC_CAPIEXT)/%.c $(srcdir)/$(RUBYSPEC_CAPIEXT)/rubyspec.h $(RUBY_H_INCLUDES) $(LIBRUBY) $(ECHO) building $@ $(Q) $(MAKEDIRS) $(@D) - $(Q) $(DLDSHARED) -L. $(XDLDFLAGS) $(XLDFLAGS) $(LDFLAGS) $(INCFLAGS) $(CPPFLAGS) $(OUTFLAG)$@ $< $(LIBRUBYARG) -ifneq ($(POSTLINK),) - $(Q) $(POSTLINK) -endif + $(Q) $(DLDSHARED) $(XDLDFLAGS) $(XLDFLAGS) $(LDFLAGS) $(INCFLAGS) $(CPPFLAGS) $(OUTFLAG)$@ $< $(LIBRUBYARG) $(Q) $(RMALL) $@.* -RUBYSPEC_CAPIEXT_SO := $(patsubst %.c,$(RUBYSPEC_CAPIEXT)/%.$(DLEXT),$(notdir $(wildcard $(srcdir)/$(RUBYSPEC_CAPIEXT)/*.c))) -rubyspec-capiext: $(RUBYSPEC_CAPIEXT_SO) +rubyspec-capiext: $(patsubst %.c,$(RUBYSPEC_CAPIEXT)/%.$(DLEXT),$(notdir $(wildcard $(srcdir)/$(RUBYSPEC_CAPIEXT)/*.c))) @ $(NULLCMD) ifeq ($(ENABLE_SHARED),yes) -ruby: $(if $(LIBRUBY_SO_UPDATE),$(RUBYSPEC_CAPIEXT_SO)) exts: rubyspec-capiext endif @@ -527,44 +480,3 @@ spec/%/ spec/%_spec.rb: programs exts PHONY +$(RUNRUBY) -r./$(arch)-fake $(srcdir)/spec/mspec/bin/mspec-run -B $(srcdir)/spec/default.mspec $(SPECOPTS) $(patsubst %,$(srcdir)/%,$@) ruby.pc: $(filter-out ruby.pc,$(ruby_pc)) - -matz: up - $(eval OLD := $(MAJOR).$(MINOR).0) - $(eval MINOR := $(shell expr $(MINOR) + 1)) - $(eval NEW := $(MAJOR).$(MINOR).0) - $(eval message := Development of $(NEW) started.) - $(eval files := include/ruby/version.h include/ruby/internal/abi.h) - $(GIT) -C $(srcdir) mv -f NEWS.md doc/NEWS/NEWS-$(OLD).md - $(GIT) -C $(srcdir) commit -m "[DOC] Flush NEWS.md" - sed -i~ \ - -e "s/^\(#define RUBY_API_VERSION_MINOR\) .*/\1 $(MINOR)/" \ - -e "s/^\(#define RUBY_ABI_VERSION\) .*/\1 0/" \ - $(files:%=$(srcdir)/%) - $(GIT) -C $(srcdir) add $(files) - $(BASERUBY) -C $(srcdir) -p -00 \ - -e 'BEGIN {old, new = ARGV.shift(2); STDOUT.reopen("NEWS.md")}' \ - -e 'case $$.' \ - -e 'when 1; $$_.sub!(/Ruby \K[0-9.]+/, new)' \ - -e 'when 2; $$_.sub!(/\*\*\K[0-9.]+(?=\*\*)/, old)' \ - -e 'end' \ - -e 'next if /^[\[ *]/ =~ $$_' \ - -e '$$_.sub!(/\n{2,}\z/, "\n\n")' \ - $(OLD) $(NEW) doc/NEWS/NEWS-$(OLD).md - $(GIT) -C $(srcdir) add NEWS.md - $(GIT) -C $(srcdir) commit -m "$(message)" - -tags: - $(MAKE) GIT="$(GIT)" -C "$(srcdir)" -f defs/tags.mk - - -# ripper_srcs makes all sources at once. invoking this target multiple -# times in parallel means all sources will be built for the number of -# sources times respectively. -ifneq ($(DOT_WAIT),) -.NOTPARALLEL: ripper_srcs -else -ripper_src = -$(foreach r,$(RIPPER_SRCS),$(eval $(value r): | $(value ripper_src))\ - $(eval ripper_src := $(value r))) -ripper_srcs: $(ripper_src) -endif diff --git a/defs/id.def b/defs/id.def index 73dd7840e4..ebf00506ea 100644 --- a/defs/id.def +++ b/defs/id.def @@ -2,7 +2,6 @@ firstline, predefined = __LINE__+1, %[\ max min - hash freeze nil? inspect @@ -26,6 +25,7 @@ firstline, predefined = __LINE__+1, %[\ lambda send __send__ + __attached__ __recursive_key__ initialize initialize_copy @@ -59,8 +59,6 @@ firstline, predefined = __LINE__+1, %[\ name nil path - pack - buffer _ UScore diff --git a/defs/known_errors.def b/defs/known_errors.def index 23e9e53507..e9694cfbda 100644 --- a/defs/known_errors.def +++ b/defs/known_errors.def @@ -1,157 +1,157 @@ -E2BIG Argument list too long -EACCES Permission denied -EADDRINUSE Address already in use -EADDRNOTAVAIL Address not available -EADV Advertise error -EAFNOSUPPORT Address family not supported -EAGAIN Resource temporarily unavailable, try again (may be the same value as EWOULDBLOCK) -EALREADY Connection already in progress -EAUTH Authentication error -EBADARCH Bad CPU type in executable -EBADE Bad exchange -EBADEXEC Bad executable -EBADF Bad file descriptor -EBADFD File descriptor in bad state -EBADMACHO Malformed Macho file -EBADMSG Bad message -EBADR Invalid request descriptor -EBADRPC RPC struct is bad -EBADRQC Invalid request code -EBADSLT Invalid slot -EBFONT Bad font file format -EBUSY Device or resource busy -ECANCELED Operation canceled -ECAPMODE Not permitted in capability mode -ECHILD No child processes -ECHRNG Channel number out of range -ECOMM Communication error on send -ECONNABORTED Connection aborted -ECONNREFUSED Connection refused -ECONNRESET Connection reset -EDEADLK Resource deadlock avoided -EDEADLOCK File locking deadlock error -EDESTADDRREQ Destination address required -EDEVERR Device error; e.g., printer paper out -EDOM Mathematics argument out of domain of function -EDOOFUS Improper function use -EDOTDOT RFS specific error -EDQUOT Disk quota exceeded -EEXIST File exists -EFAULT Bad address -EFBIG File too large -EFTYPE Invalid file type or format -EHOSTDOWN Host is down -EHOSTUNREACH Host is unreachable -EHWPOISON Memory page has hardware error -EIDRM Identifier removed -EILSEQ Invalid or incomplete multibyte or wide character -EINPROGRESS Operation in progress -EINTR Interrupted function call -EINVAL Invalid argument -EIO Input/output error -EIPSEC IPsec processing failure -EISCONN Socket is connected -EISDIR Is a directory -EISNAM Is a named file type -EKEYEXPIRED Key has expired -EKEYREJECTED Key was rejected by service -EKEYREVOKED Key has been revoked -EL2HLT Level 2 halted -EL2NSYNC Level 2 not synchronized -EL3HLT Level 3 halted -EL3RST Level 3 reset -ELIBACC Cannot access a needed shared library -ELIBBAD Accessing a corrupted shared library -ELIBEXEC Cannot exec a shared library directly -ELIBMAX Attempting to link in too many shared libraries -ELIBSCN .lib section in a.out corrupted -ELNRNG Link number out of range -ELOOP Too many levels of symbolic links -EMEDIUMTYPE Wrong medium type -EMFILE Too many open files -EMLINK Too many links -EMSGSIZE Message too long -EMULTIHOP Multihop attempted -ENAMETOOLONG Filename too long -ENAVAIL No XENIX semaphores available -ENEEDAUTH Need authenticator -ENETDOWN Network is down -ENETRESET Connection aborted by network -ENETUNREACH Network unreachable -ENFILE Too many open files in system -ENOANO No anode -ENOATTR Attribute not found -ENOBUFS No buffer space available -ENOCSI No CSI structure available -ENODATA No data available -ENODEV No such device -ENOENT No such file or directory -ENOEXEC Exec format error -ENOKEY Required key not available -ENOLCK No locks available -ENOLINK Link has been severed -ENOMEDIUM No medium found -ENOMEM Not enough space/cannot allocate memory -ENOMSG No message of the desired type -ENONET Machine is not on the network -ENOPKG Package not installed -ENOPOLICY No such policy -ENOPROTOOPT Protocol not available -ENOSPC No space left on device -ENOSR No STREAM resources -ENOSTR Not a STREAM -ENOSYS Functionality not implemented -ENOTBLK Block device required -ENOTCAPABLE Capabilities insufficient -ENOTCONN The socket is not connected -ENOTDIR Not a directory -ENOTEMPTY Directory not empty -ENOTNAM Not a XENIX named type file -ENOTRECOVERABLE State not recoverable -ENOTSOCK Not a socket -ENOTSUP Operation not supported -ENOTTY Inappropriate I/O control operation -ENOTUNIQ Name not unique on network -ENXIO No such device or address -EOPNOTSUPP Operation not supported on socket -EOVERFLOW Value too large to be stored in data type -EOWNERDEAD Owner died -EPERM Operation not permitted -EPFNOSUPPORT Protocol family not supported -EPIPE Broken pipe -EPROCLIM Too many processes -EPROCUNAVAIL Bad procedure for program -EPROGMISMATCH Program version wrong -EPROGUNAVAIL RPC program isn't available -EPROTO Protocol error -EPROTONOSUPPORT Protocol not supported -EPROTOTYPE Protocol wrong type for socket -EPWROFF Device power is off -EQFULL Interface output queue is full -ERANGE Result too large -EREMCHG Remote address changed -EREMOTE Object is remote -EREMOTEIO Remote I/O error -ERESTART Interrupted system call should be restarted -ERFKILL Operation not possible due to RF-kill -EROFS Read-only file system -ERPCMISMATCH RPC version wrong -ESHLIBVERS Shared library version mismatch -ESHUTDOWN Cannot send after transport endpoint shutdown -ESOCKTNOSUPPORT Socket type not supported -ESPIPE Illegal seek -ESRCH No such process -ESRMNT Server mount error -ESTALE Stale file handle -ESTRPIPE Streams pipe error -ETIME Timer expired -ETIMEDOUT Connection timed out -ETOOMANYREFS Too many references: cannot splice -ETXTBSY Text file busy -EUCLEAN Structure needs cleaning -EUNATCH Protocol driver not attached -EUSERS Too many users -EWOULDBLOCK Operation would block -EXDEV Invalid cross-device link -EXFULL Exchange full -ELAST Largest errno value +E2BIG +EACCES +EADDRINUSE +EADDRNOTAVAIL +EADV +EAFNOSUPPORT +EAGAIN +EALREADY +EAUTH +EBADARCH +EBADE +EBADEXEC +EBADF +EBADFD +EBADMACHO +EBADMSG +EBADR +EBADRPC +EBADRQC +EBADSLT +EBFONT +EBUSY +ECANCELED +ECAPMODE +ECHILD +ECHRNG +ECOMM +ECONNABORTED +ECONNREFUSED +ECONNRESET +EDEADLK +EDEADLOCK +EDESTADDRREQ +EDEVERR +EDOM +EDOOFUS +EDOTDOT +EDQUOT +EEXIST +EFAULT +EFBIG +EFTYPE +EHOSTDOWN +EHOSTUNREACH +EHWPOISON +EIDRM +EILSEQ +EINPROGRESS +EINTR +EINVAL +EIO +EIPSEC +EISCONN +EISDIR +EISNAM +EKEYEXPIRED +EKEYREJECTED +EKEYREVOKED +EL2HLT +EL2NSYNC +EL3HLT +EL3RST +ELAST +ELIBACC +ELIBBAD +ELIBEXEC +ELIBMAX +ELIBSCN +ELNRNG +ELOOP +EMEDIUMTYPE +EMFILE +EMLINK +EMSGSIZE +EMULTIHOP +ENAMETOOLONG +ENAVAIL +ENEEDAUTH +ENETDOWN +ENETRESET +ENETUNREACH +ENFILE +ENOANO +ENOATTR +ENOBUFS +ENOCSI +ENODATA +ENODEV +ENOENT +ENOEXEC +ENOKEY +ENOLCK +ENOLINK +ENOMEDIUM +ENOMEM +ENOMSG +ENONET +ENOPKG +ENOPOLICY +ENOPROTOOPT +ENOSPC +ENOSR +ENOSTR +ENOSYS +ENOTBLK +ENOTCAPABLE +ENOTCONN +ENOTDIR +ENOTEMPTY +ENOTNAM +ENOTRECOVERABLE +ENOTSOCK +ENOTSUP +ENOTTY +ENOTUNIQ +ENXIO +EOPNOTSUPP +EOVERFLOW +EOWNERDEAD +EPERM +EPFNOSUPPORT +EPIPE +EPROCLIM +EPROCUNAVAIL +EPROGMISMATCH +EPROGUNAVAIL +EPROTO +EPROTONOSUPPORT +EPROTOTYPE +EPWROFF +EQFULL +ERANGE +EREMCHG +EREMOTE +EREMOTEIO +ERESTART +ERFKILL +EROFS +ERPCMISMATCH +ESHLIBVERS +ESHUTDOWN +ESOCKTNOSUPPORT +ESPIPE +ESRCH +ESRMNT +ESTALE +ESTRPIPE +ETIME +ETIMEDOUT +ETOOMANYREFS +ETXTBSY +EUCLEAN +EUNATCH +EUSERS +EWOULDBLOCK +EXDEV +EXFULL diff --git a/defs/tags.mk b/defs/tags.mk deleted file mode 100644 index d29260c294..0000000000 --- a/defs/tags.mk +++ /dev/null @@ -1,18 +0,0 @@ -# -*- mode: makefile-gmake; indent-tabs-mode: t -*- - -SRCS := $(shell $(GIT) ls-files \ - *.[chy] *.def *.inc *.rb \ - ccan/ coroutine/ include/ internal/ missing/ \ - 'enc/**/*.[ch]' 'win32/**/*.[ch]' \ - ) - -TAGS: $(SRCS) - @echo updating $@ - @tmp=$$(mktemp); \ - trap 'rm -f "$$tmp"' 0; \ - { \ - $(GIT) grep -h --no-line-number -o '^ *# *define *RBIMPL_ATTR_[A-Z_]*(*' -- include | \ - sed 's/^ *# *define *//;/_H$$/d;y/(/+/' | sort -u && \ - echo 'NORETURN+'; \ - } > "$$tmp" && \ - ctags -e -I@"$$tmp" -h .def.inc --langmap=c:+.y.def.inc $(^) diff --git a/defs/universal.mk b/defs/universal.mk new file mode 100644 index 0000000000..c34a31b356 --- /dev/null +++ b/defs/universal.mk @@ -0,0 +1,5 @@ +arch_flags := $(filter -arch=%,$(subst -arch ,-arch=,$(ARCH_FLAG))) +ifeq ($(filter 0 1,$(words $(arch_flags))),) +override MJIT_HEADER_SUFFIX = -% +override MJIT_HEADER_ARCH = -$(word 2,$(ARCH_FLAG)) +endif @@ -113,7 +113,6 @@ char *strchr(char*,char); #include "internal/gc.h" #include "internal/io.h" #include "internal/object.h" -#include "internal/imemo.h" #include "internal/vm.h" #include "ruby/encoding.h" #include "ruby/ruby.h" @@ -143,50 +142,6 @@ char *strchr(char*,char); # define IS_WIN32 0 #endif -#ifdef HAVE_GETATTRLIST -struct getattrlist_args { - const char *path; - int fd; - struct attrlist *list; - void *buf; - size_t size; - unsigned int options; -}; - -# define GETATTRLIST_ARGS(list_, buf_, options_) (struct getattrlist_args) \ - {.list = list_, .buf = buf_, .size = sizeof(buf_), .options = options_} - -static void * -nogvl_getattrlist(void *args) -{ - struct getattrlist_args *arg = args; - return (void *)(VALUE)getattrlist(arg->path, arg->list, arg->buf, arg->size, arg->options); -} - -static int -gvl_getattrlist(struct getattrlist_args *args, const char *path) -{ - args->path = path; - return IO_WITHOUT_GVL_INT(nogvl_getattrlist, args); -} - -# ifdef HAVE_FGETATTRLIST -static void * -nogvl_fgetattrlist(void *args) -{ - struct getattrlist_args *arg = args; - return (void *)(VALUE)fgetattrlist(arg->fd, arg->list, arg->buf, arg->size, arg->options); -} - -static int -gvl_fgetattrlist(struct getattrlist_args *args, int fd) -{ - args->fd = fd; - return IO_WITHOUT_GVL_INT(nogvl_fgetattrlist, args); -} -# endif -#endif - #if NORMALIZE_UTF8PATH # if defined HAVE_FGETATTRLIST || !defined HAVE_GETATTRLIST # define need_normalization(dirp, path) need_normalization(dirp) @@ -199,11 +154,10 @@ need_normalization(DIR *dirp, const char *path) # if defined HAVE_FGETATTRLIST || defined HAVE_GETATTRLIST u_int32_t attrbuf[SIZEUP32(fsobj_tag_t)]; struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_OBJTAG,}; - struct getattrlist_args args = GETATTRLIST_ARGS(&al, attrbuf, 0); # if defined HAVE_FGETATTRLIST - int ret = gvl_fgetattrlist(&args, dirfd(dirp)); + int ret = fgetattrlist(dirfd(dirp), &al, attrbuf, sizeof(attrbuf), 0); # else - int ret = gvl_getattrlist(&args, path); + int ret = getattrlist(path, &al, attrbuf, sizeof(attrbuf), 0); # endif if (!ret) { const fsobj_tag_t *tag = (void *)(attrbuf+1); @@ -512,26 +466,31 @@ struct dir_data { }; static void +dir_mark(void *ptr) +{ + struct dir_data *dir = ptr; + rb_gc_mark(dir->path); +} + +static void dir_free(void *ptr) { struct dir_data *dir = ptr; if (dir->dir) closedir(dir->dir); + xfree(dir); } -RUBY_REFERENCES(dir_refs) = { - RUBY_REF_EDGE(struct dir_data, path), - RUBY_REF_END -}; +static size_t +dir_memsize(const void *ptr) +{ + return sizeof(struct dir_data); +} static const rb_data_type_t dir_data_type = { "dir", - { - RUBY_REFS_LIST_PTR(dir_refs), - dir_free, - NULL, // Nothing allocated externally, so don't need a memsize function - }, - 0, NULL, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY | RUBY_TYPED_DECL_MARKING | RUBY_TYPED_EMBEDDABLE + {dir_mark, dir_free, dir_memsize,}, + 0, 0, RUBY_TYPED_WB_PROTECTED | RUBY_TYPED_FREE_IMMEDIATELY }; static VALUE dir_close(VALUE); @@ -554,7 +513,7 @@ nogvl_opendir(void *ptr) { const char *path = ptr; - return opendir(path); + return (void *)opendir(path); } static DIR * @@ -565,31 +524,12 @@ opendir_without_gvl(const char *path) u.in = path; - return IO_WITHOUT_GVL(nogvl_opendir, u.out); + return rb_thread_call_without_gvl(nogvl_opendir, u.out, RUBY_UBF_IO, 0); } else return opendir(path); } -static void -close_dir_data(struct dir_data *dp) -{ - if (dp->dir) { - if (closedir(dp->dir) < 0) { - dp->dir = NULL; - rb_sys_fail("closedir"); - } - dp->dir = NULL; - } -} - -static void -check_closedir(DIR *dirp) -{ - if (closedir(dirp) < 0) - rb_sys_fail("closedir"); -} - static VALUE dir_initialize(rb_execution_context_t *ec, VALUE dir, VALUE dirname, VALUE enc) { @@ -604,7 +544,8 @@ dir_initialize(rb_execution_context_t *ec, VALUE dir, VALUE dirname, VALUE enc) dirname = rb_str_dup_frozen(dirname); TypedData_Get_Struct(dir, struct dir_data, &dir_data_type, dp); - close_dir_data(dp); + if (dp->dir) closedir(dp->dir); + dp->dir = NULL; RB_OBJ_WRITE(dir, &dp->path, Qnil); dp->enc = fsenc; path = RSTRING_PTR(dirname); @@ -618,8 +559,7 @@ dir_initialize(rb_execution_context_t *ec, VALUE dir, VALUE dirname, VALUE enc) else if (e == EIO) { u_int32_t attrbuf[1]; struct attrlist al = {ATTR_BIT_MAP_COUNT, 0}; - struct getattrlist_args args = GETATTRLIST_ARGS(&al, attrbuf, FSOPT_NOFOLLOW); - if (gvl_getattrlist(&args, path) == 0) { + if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW) == 0) { dp->dir = opendir_without_gvl(path); } } @@ -651,51 +591,6 @@ dir_s_close(rb_execution_context_t *ec, VALUE klass, VALUE dir) return dir_close(dir); } -# if defined(HAVE_FDOPENDIR) && defined(HAVE_DIRFD) -static void * -nogvl_fdopendir(void *fd) -{ - return fdopendir((int)(VALUE)fd); -} - -/* - * call-seq: - * Dir.for_fd(fd) -> dir - * - * Returns a new \Dir object representing the directory specified by the given - * integer directory file descriptor +fd+: - * - * d0 = Dir.new('..') - * d1 = Dir.for_fd(d0.fileno) - * - * Note that the returned +d1+ does not have an associated path: - * - * d0.path # => '..' - * d1.path # => nil - * - * This method uses the - * {fdopendir()}[https://www.man7.org/linux/man-pages/man3/fdopendir.3p.html] - * function defined by POSIX 2008; - * the method is not implemented on non-POSIX platforms (raises NotImplementedError). - */ -static VALUE -dir_s_for_fd(VALUE klass, VALUE fd) -{ - struct dir_data *dp; - VALUE dir = TypedData_Make_Struct(klass, struct dir_data, &dir_data_type, dp); - - if (!(dp->dir = IO_WITHOUT_GVL(nogvl_fdopendir, (void *)(VALUE)NUM2INT(fd)))) { - rb_sys_fail("fdopendir"); - UNREACHABLE_RETURN(Qnil); - } - - RB_OBJ_WRITE(dir, &dp->path, Qnil); - return dir; -} -#else -#define dir_s_for_fd rb_f_notimplement -#endif - NORETURN(static void dir_closed(void)); static void @@ -723,13 +618,10 @@ dir_check(VALUE dir) /* - * call-seq: - * inspect -> string - * - * Returns a string description of +self+: - * - * Dir.new('example').inspect # => "#<Dir:example>" + * call-seq: + * dir.inspect -> string * + * Return a string describing this Dir object. */ static VALUE dir_inspect(VALUE dir) @@ -763,18 +655,18 @@ dir_inspect(VALUE dir) #ifdef HAVE_DIRFD /* - * call-seq: - * fileno -> integer + * call-seq: + * dir.fileno -> integer * - * Returns the file descriptor used in <em>dir</em>. + * Returns the file descriptor used in <em>dir</em>. * - * d = Dir.new('..') - * d.fileno # => 8 + * d = Dir.new("..") + * d.fileno #=> 8 + * + * This method uses dirfd() function defined by POSIX 2008. + * NotImplementedError is raised on other platforms, such as Windows, + * which doesn't provide the function. * - * This method uses the - * {dirfd()}[https://www.man7.org/linux/man-pages/man3/dirfd.3.html] - * function defined by POSIX 2008; - * the method is not implemented on non-POSIX platforms (raises NotImplementedError). */ static VALUE dir_fileno(VALUE dir) @@ -793,14 +685,14 @@ dir_fileno(VALUE dir) #endif /* - * call-seq: - * path -> string or nil - * - * Returns the +dirpath+ string that was used to create +self+ - * (or +nil+ if created by method Dir.for_fd): + * call-seq: + * dir.path -> string or nil + * dir.to_path -> string or nil * - * Dir.new('example').path # => "example" + * Returns the path parameter passed to <em>dir</em>'s constructor. * + * d = Dir.new("..") + * d.path #=> ".." */ static VALUE dir_path(VALUE dir) @@ -826,28 +718,8 @@ fundamental_encoding_p(rb_encoding *enc) } } # define READDIR(dir, enc) rb_w32_readdir((dir), (enc)) -# define READDIR_NOGVL READDIR #else -NORETURN(static void *sys_failure(void *function)); -static void * -sys_failure(void *function) -{ - rb_sys_fail(function); -} - -static void * -nogvl_readdir(void *dir) -{ - rb_errno_set(0); - if ((dir = readdir(dir)) == NULL) { - if (rb_errno()) - rb_thread_call_with_gvl(sys_failure, (void *)"readdir"); - } - return dir; -} - -# define READDIR(dir, enc) IO_WITHOUT_GVL(nogvl_readdir, (void *)(dir)) -# define READDIR_NOGVL(dir, enc) nogvl_readdir((dir)) +# define READDIR(dir, enc) readdir((dir)) #endif /* safe to use without GVL */ @@ -874,18 +746,16 @@ to_be_skipped(const struct dirent *dp) } /* - * call-seq: - * read -> string or nil - * - * Reads and returns the next entry name from +self+; - * returns +nil+ if at end-of-stream; - * see {Dir As Stream-Like}[rdoc-ref:Dir@Dir+As+Stream-Like]: + * call-seq: + * dir.read -> string or nil * - * dir = Dir.new('example') - * dir.read # => "." - * dir.read # => ".." - * dir.read # => "config.h" + * Reads the next entry from <em>dir</em> and returns it as a string. + * Returns <code>nil</code> at the end of the stream. * + * d = Dir.new("testdir") + * d.read #=> "." + * d.read #=> ".." + * d.read #=> "config.h" */ static VALUE dir_read(VALUE dir) @@ -894,7 +764,7 @@ dir_read(VALUE dir) struct dirent *dp; GetDIR(dir, dirp); - rb_errno_set(0); + errno = 0; if ((dp = READDIR(dirp->dir, dirp->enc)) != NULL) { return rb_external_str_new_with_enc(dp->d_name, NAMLEN(dp), dirp->enc); } @@ -914,23 +784,24 @@ dir_yield(VALUE arg, VALUE path) } /* - * call-seq: - * each {|entry_name| ... } -> self + * call-seq: + * dir.each { |filename| block } -> dir + * dir.each -> an_enumerator * - * Calls the block with each entry name in +self+: + * Calls the block once for each entry in this directory, passing the + * filename of each entry as a parameter to the block. * - * Dir.new('example').each {|entry_name| p entry_name } + * If no block is given, an enumerator is returned instead. * - * Output: - - * "." - * ".." - * "config.h" - * "lib" - * "main.rb" + * d = Dir.new("testdir") + * d.each {|x| puts "Got #{x}" } * - * With no block given, returns an Enumerator. + * <em>produces:</em> * + * Got . + * Got .. + * Got config.h + * Got main.rb */ static VALUE dir_each(VALUE dir) @@ -973,17 +844,16 @@ dir_each_entry(VALUE dir, VALUE (*each)(VALUE, VALUE), VALUE arg, int children_o #ifdef HAVE_TELLDIR /* - * call-seq: - * tell -> integer - * - * Returns the current position of +self+; - * see {Dir As Stream-Like}[rdoc-ref:Dir@Dir+As+Stream-Like]: + * call-seq: + * dir.pos -> integer + * dir.tell -> integer * - * dir = Dir.new('example') - * dir.tell # => 0 - * dir.read # => "." - * dir.tell # => 1 + * Returns the current position in <em>dir</em>. See also Dir#seek. * + * d = Dir.new("testdir") + * d.tell #=> 0 + * d.read #=> "." + * d.tell #=> 12 */ static VALUE dir_tell(VALUE dir) @@ -992,8 +862,7 @@ dir_tell(VALUE dir) long pos; GetDIR(dir, dirp); - if((pos = telldir(dirp->dir)) < 0) - rb_sys_fail("telldir"); + pos = telldir(dirp->dir); return rb_int2inum(pos); } #else @@ -1002,24 +871,18 @@ dir_tell(VALUE dir) #ifdef HAVE_SEEKDIR /* - * call-seq: - * seek(position) -> self - * - * Sets the position in +self+ and returns +self+. - * The value of +position+ should have been returned from an earlier call to #tell; - * if not, the return values from subsequent calls to #read are unspecified. - * - * See {Dir As Stream-Like}[rdoc-ref:Dir@Dir+As+Stream-Like]. - * - * Examples: - * - * dir = Dir.new('example') - * dir.pos # => 0 - * dir.seek(3) # => #<Dir:example> - * dir.pos # => 3 - * dir.seek(30) # => #<Dir:example> - * dir.pos # => 5 - * + * call-seq: + * dir.seek( integer ) -> dir + * + * Seeks to a particular location in <em>dir</em>. <i>integer</i> + * must be a value returned by Dir#tell. + * + * d = Dir.new("testdir") #=> #<Dir:0x401b3c40> + * d.read #=> "." + * i = d.tell #=> 12 + * d.read #=> ".." + * d.seek(i) #=> #<Dir:0x401b3c40> + * d.read #=> ".." */ static VALUE dir_seek(VALUE dir, VALUE pos) @@ -1037,24 +900,17 @@ dir_seek(VALUE dir, VALUE pos) #ifdef HAVE_SEEKDIR /* - * call-seq: - * pos = position -> integer - * - * Sets the position in +self+ and returns +position+. - * The value of +position+ should have been returned from an earlier call to #tell; - * if not, the return values from subsequent calls to #read are unspecified. - * - * See {Dir As Stream-Like}[rdoc-ref:Dir@Dir+As+Stream-Like]. + * call-seq: + * dir.pos = integer -> integer * - * Examples: - * - * dir = Dir.new('example') - * dir.pos # => 0 - * dir.pos = 3 # => 3 - * dir.pos # => 3 - * dir.pos = 30 # => 30 - * dir.pos # => 5 + * Synonym for Dir#seek, but returns the position parameter. * + * d = Dir.new("testdir") #=> #<Dir:0x401b3c40> + * d.read #=> "." + * i = d.pos #=> 12 + * d.read #=> ".." + * d.pos = i #=> 12 + * d.read #=> ".." */ static VALUE dir_set_pos(VALUE dir, VALUE pos) @@ -1067,19 +923,15 @@ dir_set_pos(VALUE dir, VALUE pos) #endif /* - * call-seq: - * rewind -> self - * - * Sets the position in +self+ to zero; - * see {Dir As Stream-Like}[rdoc-ref:Dir@Dir+As+Stream-Like]: + * call-seq: + * dir.rewind -> dir * - * dir = Dir.new('example') - * dir.read # => "." - * dir.read # => ".." - * dir.pos # => 2 - * dir.rewind # => #<Dir:example> - * dir.pos # => 0 + * Repositions <em>dir</em> to the first entry. * + * d = Dir.new("testdir") + * d.read #=> "." + * d.rewind #=> #<Dir:0x401b3fb0> + * d.read #=> "." */ static VALUE dir_rewind(VALUE dir) @@ -1092,18 +944,14 @@ dir_rewind(VALUE dir) } /* - * call-seq: - * close -> nil - * - * Closes the stream in +self+, if it is open, and returns +nil+; - * ignored if +self+ is already closed: + * call-seq: + * dir.close -> nil * - * dir = Dir.new('example') - * dir.read # => "." - * dir.close # => nil - * dir.close # => nil - * dir.read # Raises IOError. + * Closes the directory stream. + * Calling this method on closed Dir object is ignored since Ruby 2.3. * + * d = Dir.new("testdir") + * d.close #=> nil */ static VALUE dir_close(VALUE dir) @@ -1112,7 +960,8 @@ dir_close(VALUE dir) dirp = dir_get(dir); if (!dirp->dir) return Qnil; - close_dir_data(dirp); + closedir(dirp->dir); + dirp->dir = NULL; return Qnil; } @@ -1126,80 +975,30 @@ nogvl_chdir(void *ptr) } static void -dir_chdir0(VALUE path) +dir_chdir(VALUE path) { - if (IO_WITHOUT_GVL_INT(nogvl_chdir, (void*)RSTRING_PTR(path)) < 0) + if (chdir(RSTRING_PTR(path)) < 0) rb_sys_fail_path(path); } -static struct { - VALUE thread; - VALUE path; - int line; - int blocking; -} chdir_lock = { - .blocking = 0, .thread = Qnil, - .path = Qnil, .line = 0, -}; - -static void -chdir_enter(void) -{ - if (chdir_lock.blocking == 0) { - chdir_lock.path = rb_source_location(&chdir_lock.line); - } - chdir_lock.blocking++; - if (NIL_P(chdir_lock.thread)) { - chdir_lock.thread = rb_thread_current(); - } -} - -static void -chdir_leave(void) -{ - chdir_lock.blocking--; - if (chdir_lock.blocking == 0) { - chdir_lock.thread = Qnil; - chdir_lock.path = Qnil; - chdir_lock.line = 0; - } -} - -static int -chdir_alone_block_p(void) -{ - int block_given = rb_block_given_p(); - if (chdir_lock.blocking > 0) { - if (rb_thread_current() != chdir_lock.thread) - rb_raise(rb_eRuntimeError, "conflicting chdir during another chdir block"); - if (!block_given) { - if (!NIL_P(chdir_lock.path)) { - rb_warn("conflicting chdir during another chdir block\n" - "%" PRIsVALUE ":%d: note: previous chdir was here", - chdir_lock.path, chdir_lock.line); - } - else { - rb_warn("conflicting chdir during another chdir block"); - } - } - } - return block_given; -} +static int chdir_blocking = 0; +static VALUE chdir_thread = Qnil; struct chdir_data { VALUE old_path, new_path; int done; - bool yield_path; }; static VALUE chdir_yield(VALUE v) { struct chdir_data *args = (void *)v; - dir_chdir0(args->new_path); + dir_chdir(args->new_path); args->done = TRUE; - chdir_enter(); - return args->yield_path ? rb_yield(args->new_path) : rb_yield_values2(0, NULL); + chdir_blocking++; + if (NIL_P(chdir_thread)) + chdir_thread = rb_thread_current(); + return rb_yield(args->new_path); } static VALUE @@ -1207,96 +1006,53 @@ chdir_restore(VALUE v) { struct chdir_data *args = (void *)v; if (args->done) { - chdir_leave(); - dir_chdir0(args->old_path); + chdir_blocking--; + if (chdir_blocking == 0) + chdir_thread = Qnil; + dir_chdir(args->old_path); } return Qnil; } -static VALUE -chdir_path(VALUE path, bool yield_path) -{ - if (chdir_alone_block_p()) { - struct chdir_data args; - - args.old_path = rb_str_encode_ospath(rb_dir_getwd()); - args.new_path = path; - args.done = FALSE; - args.yield_path = yield_path; - return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args); - } - else { - char *p = RSTRING_PTR(path); - int r = IO_WITHOUT_GVL_INT(nogvl_chdir, p); - if (r < 0) - rb_sys_fail_path(path); - } - - return INT2FIX(0); -} - /* - * call-seq: - * Dir.chdir(new_dirpath) -> 0 - * Dir.chdir -> 0 - * Dir.chdir(new_dirpath) {|new_dirpath| ... } -> object - * Dir.chdir {|cur_dirpath| ... } -> object - * - * Changes the current working directory. - * - * With argument +new_dirpath+ and no block, - * changes to the given +dirpath+: - * - * Dir.pwd # => "/example" - * Dir.chdir('..') # => 0 - * Dir.pwd # => "/" - * - * With no argument and no block: - * - * - Changes to the value of environment variable +HOME+ if defined. - * - Otherwise changes to the value of environment variable +LOGDIR+ if defined. - * - Otherwise makes no change. - * - * With argument +new_dirpath+ and a block, temporarily changes the working directory: - * - * - Calls the block with the argument. - * - Changes to the given directory. - * - Executes the block (yielding the new path). - * - Restores the previous working directory. - * - Returns the block's return value. - * - * Example: - * - * Dir.chdir('/var/spool/mail') - * Dir.pwd # => "/var/spool/mail" - * Dir.chdir('/tmp') do - * Dir.pwd # => "/tmp" - * end - * Dir.pwd # => "/var/spool/mail" - * - * With no argument and a block, - * calls the block with the current working directory (string) - * and returns the block's return value. - * - * Calls to \Dir.chdir with blocks may be nested: - * - * Dir.chdir('/var/spool/mail') - * Dir.pwd # => "/var/spool/mail" - * Dir.chdir('/tmp') do - * Dir.pwd # => "/tmp" - * Dir.chdir('/usr') do - * Dir.pwd # => "/usr" + * call-seq: + * Dir.chdir( [ string] ) -> 0 + * Dir.chdir( [ string] ) {| path | block } -> anObject + * + * Changes the current working directory of the process to the given + * string. When called without an argument, changes the directory to + * the value of the environment variable <code>HOME</code>, or + * <code>LOGDIR</code>. SystemCallError (probably Errno::ENOENT) if + * the target directory does not exist. + * + * If a block is given, it is passed the name of the new current + * directory, and the block is executed with that as the current + * directory. The original working directory is restored when the block + * exits. The return value of <code>chdir</code> is the value of the + * block. <code>chdir</code> blocks can be nested, but in a + * multi-threaded program an error will be raised if a thread attempts + * to open a <code>chdir</code> block while another thread has one + * open or a call to <code>chdir</code> without a block occurs inside + * a block passed to <code>chdir</code> (even in the same thread). + * + * Dir.chdir("/var/spool/mail") + * puts Dir.pwd + * Dir.chdir("/tmp") do + * puts Dir.pwd + * Dir.chdir("/usr") do + * puts Dir.pwd + * end + * puts Dir.pwd * end - * Dir.pwd # => "/tmp" - * end - * Dir.pwd # => "/var/spool/mail" + * puts Dir.pwd * - * In a multi-threaded program an error is raised if a thread attempts - * to open a +chdir+ block while another thread has one open, - * or a call to +chdir+ without a block occurs inside - * a block passed to +chdir+ (even in the same thread). + * <em>produces:</em> * - * Raises an exception if the target directory does not exist. + * /var/spool/mail + * /tmp + * /usr + * /tmp + * /var/spool/mail */ static VALUE dir_s_chdir(int argc, VALUE *argv, VALUE obj) @@ -1315,162 +1071,31 @@ dir_s_chdir(int argc, VALUE *argv, VALUE obj) path = rb_str_new2(dist); } - return chdir_path(path, true); -} - -#if defined(HAVE_FCHDIR) && defined(HAVE_DIRFD) && HAVE_FCHDIR && HAVE_DIRFD -static void * -nogvl_fchdir(void *ptr) -{ - const int *fd = ptr; - - return (void *)(VALUE)fchdir(*fd); -} - -static void -dir_fchdir(int fd) -{ - if (IO_WITHOUT_GVL_INT(nogvl_fchdir, (void *)&fd) < 0) - rb_sys_fail("fchdir"); -} - -struct fchdir_data { - VALUE old_dir; - int fd; - int done; -}; - -static VALUE -fchdir_yield(VALUE v) -{ - struct fchdir_data *args = (void *)v; - dir_fchdir(args->fd); - args->done = TRUE; - chdir_enter(); - return rb_yield_values(0); -} - -static VALUE -fchdir_restore(VALUE v) -{ - struct fchdir_data *args = (void *)v; - if (args->done) { - chdir_leave(); - dir_fchdir(RB_NUM2INT(dir_fileno(args->old_dir))); + if (chdir_blocking > 0) { + if (rb_thread_current() != chdir_thread) + rb_raise(rb_eRuntimeError, "conflicting chdir during another chdir block"); + if (!rb_block_given_p()) + rb_warn("conflicting chdir during another chdir block"); } - dir_close(args->old_dir); - return Qnil; -} -/* - * call-seq: - * Dir.fchdir(fd) -> 0 - * Dir.fchdir(fd) { ... } -> object - * - * Changes the current working directory to the directory - * specified by the integer file descriptor +fd+. - * - * When passing a file descriptor over a UNIX socket or to a child process, - * using +fchdir+ instead of +chdir+ avoids the - * {time-of-check to time-of-use vulnerability}[https://en.wikipedia.org/wiki/Time-of-check_to_time-of-use] - * - * With no block, changes to the directory given by +fd+: - * - * Dir.chdir('/var/spool/mail') - * Dir.pwd # => "/var/spool/mail" - * dir = Dir.new('/usr') - * fd = dir.fileno - * Dir.fchdir(fd) - * Dir.pwd # => "/usr" - * - * With a block, temporarily changes the working directory: - * - * - Calls the block with the argument. - * - Changes to the given directory. - * - Executes the block (yields no args). - * - Restores the previous working directory. - * - Returns the block's return value. - * - * Example: - * - * Dir.chdir('/var/spool/mail') - * Dir.pwd # => "/var/spool/mail" - * dir = Dir.new('/tmp') - * fd = dir.fileno - * Dir.fchdir(fd) do - * Dir.pwd # => "/tmp" - * end - * Dir.pwd # => "/var/spool/mail" - * - * This method uses the - * {fchdir()}[https://www.man7.org/linux/man-pages/man3/fchdir.3p.html] - * function defined by POSIX 2008; - * the method is not implemented on non-POSIX platforms (raises NotImplementedError). - * - * Raises an exception if the file descriptor is not valid. - * - * In a multi-threaded program an error is raised if a thread attempts - * to open a +chdir+ block while another thread has one open, - * or a call to +chdir+ without a block occurs inside - * a block passed to +chdir+ (even in the same thread). - */ -static VALUE -dir_s_fchdir(VALUE klass, VALUE fd_value) -{ - int fd = RB_NUM2INT(fd_value); + if (rb_block_given_p()) { + struct chdir_data args; - if (chdir_alone_block_p()) { - struct fchdir_data args; - args.old_dir = dir_s_alloc(klass); - dir_initialize(NULL, args.old_dir, rb_fstring_cstr("."), Qnil); - args.fd = fd; + args.old_path = rb_str_encode_ospath(rb_dir_getwd()); + args.new_path = path; args.done = FALSE; - return rb_ensure(fchdir_yield, (VALUE)&args, fchdir_restore, (VALUE)&args); + return rb_ensure(chdir_yield, (VALUE)&args, chdir_restore, (VALUE)&args); } else { - int r = IO_WITHOUT_GVL_INT(nogvl_fchdir, &fd); + char *p = RSTRING_PTR(path); + int r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_chdir, p, + RUBY_UBF_IO, 0); if (r < 0) - rb_sys_fail("fchdir"); + rb_sys_fail_path(path); } return INT2FIX(0); } -#else -#define dir_s_fchdir rb_f_notimplement -#endif - -/* - * call-seq: - * chdir -> 0 - * chdir { ... } -> object - * - * Changes the current working directory to +self+: - * - * Dir.pwd # => "/" - * dir = Dir.new('example') - * dir.chdir - * Dir.pwd # => "/example" - * - * With a block, temporarily changes the working directory: - * - * - Calls the block. - * - Changes to the given directory. - * - Executes the block (yields no args). - * - Restores the previous working directory. - * - Returns the block's return value. - * - * Uses Dir.fchdir if available, and Dir.chdir if not, see those - * methods for caveats. - */ -static VALUE -dir_chdir(VALUE dir) -{ -#if defined(HAVE_FCHDIR) && defined(HAVE_DIRFD) && HAVE_FCHDIR && HAVE_DIRFD - return dir_s_fchdir(rb_cDir, dir_fileno(dir)); -#else - return chdir_path(dir_get(dir)->path, false); -#endif -} #ifndef _WIN32 VALUE @@ -1480,15 +1105,19 @@ rb_dir_getwd_ospath(void) VALUE cwd; VALUE path_guard; - path_guard = rb_imemo_tmpbuf_auto_free_pointer(); +#undef RUBY_UNTYPED_DATA_WARNING +#define RUBY_UNTYPED_DATA_WARNING 0 + path_guard = Data_Wrap_Struct((VALUE)0, NULL, RUBY_DEFAULT_FREE, NULL); path = ruby_getcwd(); - rb_imemo_tmpbuf_set_ptr(path_guard, path); + DATA_PTR(path_guard) = path; #ifdef __APPLE__ cwd = rb_str_normalize_ospath(path, strlen(path)); #else cwd = rb_str_new2(path); #endif - rb_free_tmp_buffer(&path_guard); + DATA_PTR(path_guard) = 0; + + xfree(path); return cwd; } #endif @@ -1514,14 +1143,16 @@ rb_dir_getwd(void) } /* - * call-seq: - * Dir.pwd -> string + * call-seq: + * Dir.getwd -> string + * Dir.pwd -> string * - * Returns the path to the current working directory: - * - * Dir.chdir("/tmp") # => 0 - * Dir.pwd # => "/tmp" + * Returns the path to the current working directory of this process as + * a string. * + * Dir.chdir("/tmp") #=> 0 + * Dir.getwd #=> "/tmp" + * Dir.pwd #=> "/tmp" */ static VALUE dir_s_getwd(VALUE dir) @@ -1550,29 +1181,20 @@ check_dirname(VALUE dir) } #if defined(HAVE_CHROOT) -static void * -nogvl_chroot(void *dirname) -{ - return (void *)(VALUE)chroot((const char *)dirname); -} - /* - * call-seq: - * Dir.chroot(dirpath) -> 0 - * - * Changes the root directory of the calling process to that specified in +dirpath+. - * The new root directory is used for pathnames beginning with <tt>'/'</tt>. - * The root directory is inherited by all children of the calling process. + * call-seq: + * Dir.chroot( string ) -> 0 * - * Only a privileged process may call +chroot+. - * - * See {Linux chroot}[https://man7.org/linux/man-pages/man2/chroot.2.html]. + * Changes this process's idea of the file system root. Only a + * privileged process may make this call. Not available on all + * platforms. On Unix systems, see <code>chroot(2)</code> for more + * information. */ static VALUE dir_s_chroot(VALUE dir, VALUE path) { path = check_dirname(path); - if (IO_WITHOUT_GVL_INT(nogvl_chroot, (void *)RSTRING_PTR(path)) == -1) + if (chroot(RSTRING_PTR(path)) == -1) rb_sys_fail_path(path); return INT2FIX(0); @@ -1595,20 +1217,18 @@ nogvl_mkdir(void *ptr) } /* - * call-seq: - * Dir.mkdir(dirpath, permissions = 0775) -> 0 + * call-seq: + * Dir.mkdir( string [, integer] ) -> 0 * - * Creates a directory in the underlying file system - * at +dirpath+ with the given +permissions+; - * returns zero: + * Makes a new directory named by <i>string</i>, with permissions + * specified by the optional parameter <i>anInteger</i>. The + * permissions may be modified by the value of File::umask, and are + * ignored on NT. Raises a SystemCallError if the directory cannot be + * created. See also the discussion of permissions in the class + * documentation for File. * - * Dir.mkdir('foo') - * File.stat(Dir.new('foo')).mode.to_s(8)[1..4] # => "0755" - * Dir.mkdir('bar', 0644) - * File.stat(Dir.new('bar')).mode.to_s(8)[1..4] # => "0644" + * Dir.mkdir(File.join(Dir.home, ".foo"), 0700) #=> 0 * - * See {File Permissions}[rdoc-ref:File@File+Permissions]. - * Note that argument +permissions+ is ignored on Windows. */ static VALUE dir_s_mkdir(int argc, VALUE *argv, VALUE obj) @@ -1626,7 +1246,7 @@ dir_s_mkdir(int argc, VALUE *argv, VALUE obj) path = check_dirname(path); m.path = RSTRING_PTR(path); - r = IO_WITHOUT_GVL_INT(nogvl_mkdir, &m); + r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_mkdir, &m, RUBY_UBF_IO, 0); if (r < 0) rb_sys_fail_path(path); @@ -1642,14 +1262,13 @@ nogvl_rmdir(void *ptr) } /* - * call-seq: - * Dir.rmdir(dirpath) -> 0 - * - * Removes the directory at +dirpath+ from the underlying file system: + * call-seq: + * Dir.delete( string ) -> 0 + * Dir.rmdir( string ) -> 0 + * Dir.unlink( string ) -> 0 * - * Dir.rmdir('foo') # => 0 - * - * Raises an exception if the directory is not empty. + * Deletes the named directory. Raises a subclass of SystemCallError + * if the directory isn't empty. */ static VALUE dir_s_rmdir(VALUE obj, VALUE dir) @@ -1659,7 +1278,7 @@ dir_s_rmdir(VALUE obj, VALUE dir) dir = check_dirname(dir); p = RSTRING_PTR(dir); - r = IO_WITHOUT_GVL_INT(nogvl_rmdir, (void *)p); + r = (int)(VALUE)rb_thread_call_without_gvl(nogvl_rmdir, (void *)p, RUBY_UBF_IO, 0); if (r < 0) rb_sys_fail_path(dir); @@ -1749,11 +1368,11 @@ to_be_ignored(int e) } #ifdef _WIN32 -#define STAT(args) (int)(VALUE)nogvl_stat(&(args)) -#define LSTAT(args) (int)(VALUE)nogvl_lstat(&(args)) +#define STAT(p, s) rb_w32_ustati128((p), (s)) +#undef lstat +#define lstat(p, s) rb_w32_ulstati128((p), (s)) #else -#define STAT(args) IO_WITHOUT_GVL_INT(nogvl_stat, (void *)&(args)) -#define LSTAT(args) IO_WITHOUT_GVL_INT(nogvl_lstat, (void *)&(args)) +#define STAT(p, s) stat((p), (s)) #endif typedef int ruby_glob_errfunc(const char*, VALUE, const void*, int); @@ -1774,50 +1393,14 @@ at_subpath(int fd, size_t baselen, const char *path) return *path ? path : "."; } -#if USE_OPENDIR_AT -struct fstatat_args { - int fd; - int flag; - const char *path; - struct stat *pst; -}; - -static void * -nogvl_fstatat(void *args) -{ - struct fstatat_args *arg = (struct fstatat_args *)args; - return (void *)(VALUE)fstatat(arg->fd, arg->path, arg->pst, arg->flag); -} -#else -struct stat_args { - const char *path; - struct stat *pst; -}; - -static void * -nogvl_stat(void *args) -{ - struct stat_args *arg = (struct stat_args *)args; - return (void *)(VALUE)stat(arg->path, arg->pst); -} -#endif - /* System call with warning */ static int do_stat(int fd, size_t baselen, const char *path, struct stat *pst, int flags, rb_encoding *enc) { #if USE_OPENDIR_AT - struct fstatat_args args; - args.fd = fd; - args.path = path; - args.pst = pst; - args.flag = 0; - int ret = IO_WITHOUT_GVL_INT(nogvl_fstatat, (void *)&args); + int ret = fstatat(fd, at_subpath(fd, baselen, path), pst, 0); #else - struct stat_args args; - args.path = path; - args.pst = pst; - int ret = STAT(args); + int ret = STAT(path, pst); #endif if (ret < 0 && !to_be_ignored(errno)) sys_warning(path, enc); @@ -1826,30 +1409,13 @@ do_stat(int fd, size_t baselen, const char *path, struct stat *pst, int flags, r } #if defined HAVE_LSTAT || defined lstat || USE_OPENDIR_AT -#if !USE_OPENDIR_AT -static void * -nogvl_lstat(void *args) -{ - struct stat_args *arg = (struct stat_args *)args; - return (void *)(VALUE)lstat(arg->path, arg->pst); -} -#endif - static int do_lstat(int fd, size_t baselen, const char *path, struct stat *pst, int flags, rb_encoding *enc) { #if USE_OPENDIR_AT - struct fstatat_args args; - args.fd = fd; - args.path = path; - args.pst = pst; - args.flag = AT_SYMLINK_NOFOLLOW; - int ret = IO_WITHOUT_GVL_INT(nogvl_fstatat, (void *)&args); + int ret = fstatat(fd, at_subpath(fd, baselen, path), pst, AT_SYMLINK_NOFOLLOW); #else - struct stat_args args; - args.path = path; - args.pst = pst; - int ret = LSTAT(args); + int ret = lstat(path, pst); #endif if (ret < 0 && !to_be_ignored(errno)) sys_warning(path, enc); @@ -1910,7 +1476,7 @@ nogvl_opendir_at(void *ptr) /* fallthrough*/ case 0: if (fd >= 0) close(fd); - rb_errno_set(e); + errno = e; } } #else /* !USE_OPENDIR_AT */ @@ -1931,7 +1497,7 @@ opendir_at(int basefd, const char *path) oaa.path = path; if (vm_initialized) - return IO_WITHOUT_GVL(nogvl_opendir_at, &oaa); + return rb_thread_call_without_gvl(nogvl_opendir_at, &oaa, RUBY_UBF_IO, 0); else return nogvl_opendir_at(&oaa); } @@ -2210,15 +1776,14 @@ is_case_sensitive(DIR *dirp, const char *path) const vol_capabilities_attr_t *const cap = attrbuf[0].cap; const int idx = VOL_CAPABILITIES_FORMAT; const uint32_t mask = VOL_CAP_FMT_CASE_SENSITIVE; - struct getattrlist_args args = GETATTRLIST_ARGS(&al, attrbuf, FSOPT_NOFOLLOW); + # if defined HAVE_FGETATTRLIST - int ret = gvl_fgetattrlist(&args, dirfd(dirp)); + if (fgetattrlist(dirfd(dirp), &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW)) + return -1; # else - int ret = gvl_getattrlist(&args, path); -# endif - if (ret) + if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW)) return -1; - +# endif if (!(cap->valid[idx] & mask)) return -1; return (cap->capabilities[idx] & mask) != 0; @@ -2241,8 +1806,7 @@ replace_real_basename(char *path, long base, rb_encoding *enc, int norm_p, int f IF_NORMALIZE_UTF8PATH(VALUE utf8str = Qnil); *type = path_noent; - struct getattrlist_args args = GETATTRLIST_ARGS(&al, attrbuf, FSOPT_NOFOLLOW); - if (gvl_getattrlist(&args, path)) { + if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), FSOPT_NOFOLLOW)) { if (!to_be_ignored(errno)) sys_warning(path, enc); return path; @@ -2615,7 +2179,7 @@ static void glob_dir_finish(ruby_glob_entries_t *ent, int flags) { if (flags & FNM_GLOB_NOSORT) { - check_closedir(ent->nosort.dirp); + closedir(ent->nosort.dirp); ent->nosort.dirp = NULL; } else if (ent->sort.entries) { @@ -2646,7 +2210,7 @@ glob_opendir(ruby_glob_entries_t *ent, DIR *dirp, int flags, rb_encoding *enc) #ifdef _WIN32 if ((capacity = dirp->nfiles) > 0) { if (!(newp = GLOB_ALLOC_N(rb_dirent_t, capacity))) { - check_closedir(dirp); + closedir(dirp); return NULL; } ent->sort.entries = newp; @@ -2666,7 +2230,7 @@ glob_opendir(ruby_glob_entries_t *ent, DIR *dirp, int flags, rb_encoding *enc) ent->sort.entries[count++] = rdp; ent->sort.count = count; } - check_closedir(dirp); + closedir(dirp); if (count < capacity) { if (!(newp = GLOB_REALLOC_N(ent->sort.entries, count))) { glob_dir_finish(ent, 0); @@ -2681,7 +2245,7 @@ glob_opendir(ruby_glob_entries_t *ent, DIR *dirp, int flags, rb_encoding *enc) nomem: glob_dir_finish(ent, 0); - check_closedir(dirp); + closedir(dirp); return NULL; } @@ -2844,7 +2408,7 @@ glob_helper( # if NORMALIZE_UTF8PATH if (!(norm_p || magical || recursive)) { - check_closedir(dirp); + closedir(dirp); goto literally; } # endif @@ -3305,7 +2869,7 @@ push_glob(VALUE ary, VALUE str, VALUE base, int flags) fd = AT_FDCWD; if (!NIL_P(base)) { if (!RB_TYPE_P(base, T_STRING) || !rb_enc_check(str, base)) { - struct dir_data *dirp = RTYPEDDATA_GET_DATA(base); + struct dir_data *dirp = DATA_PTR(base); if (!dirp->dir) dir_closed(); #ifdef HAVE_DIRFD if ((fd = dirfd(dirp->dir)) == -1) @@ -3429,35 +2993,26 @@ dir_open_dir(int argc, VALUE *argv) /* - * call-seq: - * Dir.foreach(dirpath, encoding: 'UTF-8') {|entry_name| ... } -> nil - * - * Calls the block with each entry name in the directory at +dirpath+; - * sets the given encoding onto each passed +entry_name+: - * - * Dir.foreach('/example') {|entry_name| p entry_name } + * call-seq: + * Dir.foreach( dirname ) {| filename | block } -> nil + * Dir.foreach( dirname, encoding: enc ) {| filename | block } -> nil + * Dir.foreach( dirname ) -> an_enumerator + * Dir.foreach( dirname, encoding: enc ) -> an_enumerator * - * Output: + * Calls the block once for each entry in the named directory, passing + * the filename of each entry as a parameter to the block. * - * "config.h" - * "lib" - * "main.rb" - * ".." - * "." + * If no block is given, an enumerator is returned instead. * - * Encoding: + * Dir.foreach("testdir") {|x| puts "Got #{x}" } * - * Dir.foreach('/example') {|entry_name| p entry_name.encoding; break } - * Dir.foreach('/example', encoding: 'US-ASCII') {|entry_name| p entry_name.encoding; break } + * <em>produces:</em> * - * Output: + * Got . + * Got .. + * Got config.h + * Got main.rb * - * #<Encoding:UTF-8> - * #<Encoding:US-ASCII> - * - * See {String Encoding}[rdoc-ref:encodings.rdoc@String+Encoding]. - * - * Returns an enumerator if no block is given. */ static VALUE dir_foreach(int argc, VALUE *argv, VALUE io) @@ -3479,21 +3034,19 @@ dir_collect(VALUE dir) } /* - * call-seq: - * Dir.entries(dirname, encoding: 'UTF-8') -> array + * call-seq: + * Dir.entries( dirname ) -> array + * Dir.entries( dirname, encoding: enc ) -> array * - * Returns an array of the entry names in the directory at +dirpath+; - * sets the given encoding onto each returned entry name: + * Returns an array containing all of the filenames in the given + * directory. Will raise a SystemCallError if the named directory + * doesn't exist. * - * Dir.entries('/example') # => ["config.h", "lib", "main.rb", "..", "."] - * Dir.entries('/example').first.encoding - * # => #<Encoding:UTF-8> - * Dir.entries('/example', encoding: 'US-ASCII').first.encoding - * # => #<Encoding:US-ASCII> + * The optional <i>encoding</i> keyword argument specifies the encoding of the + * directory. If not specified, the filesystem encoding is used. * - * See {String Encoding}[rdoc-ref:encodings.rdoc@String+Encoding]. + * Dir.entries("testdir") #=> [".", "..", "config.h", "main.rb"] * - * Raises an exception if the directory does not exist. */ static VALUE dir_entries(int argc, VALUE *argv, VALUE io) @@ -3511,12 +3064,25 @@ dir_each_child(VALUE dir) } /* - * call-seq: - * Dir.each_child(dirpath) {|entry_name| ... } -> nil - * Dir.each_child(dirpath, encoding: 'UTF-8') {|entry_name| ... } -> nil + * call-seq: + * Dir.each_child( dirname ) {| filename | block } -> nil + * Dir.each_child( dirname, encoding: enc ) {| filename | block } -> nil + * Dir.each_child( dirname ) -> an_enumerator + * Dir.each_child( dirname, encoding: enc ) -> an_enumerator + * + * Calls the block once for each entry except for "." and ".." in the + * named directory, passing the filename of each entry as a parameter + * to the block. + * + * If no block is given, an enumerator is returned instead. + * + * Dir.each_child("testdir") {|x| puts "Got #{x}" } + * + * <em>produces:</em> + * + * Got config.h + * Got main.rb * - * Like Dir.foreach, except that entries <tt>'.'</tt> and <tt>'..'</tt> - * are not included. */ static VALUE dir_s_each_child(int argc, VALUE *argv, VALUE io) @@ -3530,22 +3096,24 @@ dir_s_each_child(int argc, VALUE *argv, VALUE io) } /* - * call-seq: - * each_child {|entry_name| ... } -> self + * call-seq: + * dir.each_child {| filename | block } -> dir + * dir.each_child -> an_enumerator + * + * Calls the block once for each entry except for "." and ".." in + * this directory, passing the filename of each entry as a parameter + * to the block. * - * Calls the block with each entry name in +self+ - * except <tt>'.'</tt> and <tt>'..'</tt>: + * If no block is given, an enumerator is returned instead. * - * dir = Dir.new('/example') - * dir.each_child {|entry_name| p entry_name } + * d = Dir.new("testdir") + * d.each_child {|x| puts "Got #{x}" } * - * Output: + * <em>produces:</em> * - * "config.h" - * "lib" - * "main.rb" + * Got config.h + * Got main.rb * - * If no block is given, returns an enumerator. */ static VALUE dir_each_child_m(VALUE dir) @@ -3555,14 +3123,14 @@ dir_each_child_m(VALUE dir) } /* - * call-seq: - * children -> array + * call-seq: + * dir.children -> array * - * Returns an array of the entry names in +self+ - * except for <tt>'.'</tt> and <tt>'..'</tt>: + * Returns an array containing all of the filenames except for "." + * and ".." in this directory. * - * dir = Dir.new('/example') - * dir.children # => ["config.h", "lib", "main.rb"] + * d = Dir.new("testdir") + * d.children #=> ["config.h", "main.rb"] * */ static VALUE @@ -3574,23 +3142,19 @@ dir_collect_children(VALUE dir) } /* - * call-seq: - * Dir.children(dirpath) -> array - * Dir.children(dirpath, encoding: 'UTF-8') -> array + * call-seq: + * Dir.children( dirname ) -> array + * Dir.children( dirname, encoding: enc ) -> array * - * Returns an array of the entry names in the directory at +dirpath+ - * except for <tt>'.'</tt> and <tt>'..'</tt>; - * sets the given encoding onto each returned entry name: + * Returns an array containing all of the filenames except for "." + * and ".." in the given directory. Will raise a SystemCallError if + * the named directory doesn't exist. * - * Dir.children('/example') # => ["config.h", "lib", "main.rb"] - * Dir.children('/example').first.encoding - * # => #<Encoding:UTF-8> - * Dir.children('/example', encoding: 'US-ASCII').first.encoding - * # => #<Encoding:US-ASCII> + * The optional <i>encoding</i> keyword argument specifies the encoding of the + * directory. If not specified, the filesystem encoding is used. * - * See {String Encoding}[rdoc-ref:encodings.rdoc@String+Encoding]. + * Dir.children("testdir") #=> ["config.h", "main.rb"] * - * Raises an exception if the directory does not exist. */ static VALUE dir_s_children(int argc, VALUE *argv, VALUE io) @@ -3664,16 +3228,12 @@ file_s_fnmatch(int argc, VALUE *argv, VALUE obj) } /* - * call-seq: - * Dir.home(user_name = nil) -> dirpath + * call-seq: + * Dir.home() -> "/home/me" + * Dir.home("root") -> "/root" * - * Returns the home directory path of the user specified with +user_name+ - * if it is not +nil+, or the current login user: - * - * Dir.home # => "/home/me" - * Dir.home('root') # => "/root" - * - * Raises ArgumentError if +user_name+ is not a user name. + * Returns the home directory of the current user or the named user + * if given. */ static VALUE dir_s_home(int argc, VALUE *argv, VALUE obj) @@ -3684,7 +3244,7 @@ dir_s_home(int argc, VALUE *argv, VALUE obj) rb_check_arity(argc, 0, 1); user = (argc > 0) ? argv[0] : Qnil; if (!NIL_P(user)) { - StringValue(user); + SafeStringValue(user); rb_must_asciicompat(user); u = StringValueCStr(user); if (*u) { @@ -3698,15 +3258,10 @@ dir_s_home(int argc, VALUE *argv, VALUE obj) #if 0 /* * call-seq: - * Dir.exist?(dirpath) -> true or false - * - * Returns whether +dirpath+ is a directory in the underlying file system: - * - * Dir.exist?('/example') # => true - * Dir.exist?('/nosuch') # => false - * Dir.exist?('/example/main.rb') # => false + * Dir.exist?(file_name) -> true or false * - * Same as File.directory?. + * Returns <code>true</code> if the named file is a directory, + * <code>false</code> otherwise. * */ VALUE @@ -3733,33 +3288,26 @@ nogvl_dir_empty_p(void *ptr) /* fall through */ case 0: if (e == ENOTDIR) return (void *)Qfalse; - return (void *)INT2FIX(e); + errno = e; /* for rb_sys_fail_path */ + return (void *)Qundef; } } - while ((dp = READDIR_NOGVL(dir, NULL)) != NULL) { + while ((dp = READDIR(dir, NULL)) != NULL) { if (!to_be_skipped(dp)) { result = Qfalse; break; } } - check_closedir(dir); + closedir(dir); return (void *)result; } /* * call-seq: - * Dir.empty?(dirpath) -> true or false + * Dir.empty?(path_name) -> true or false * - * Returns whether +dirpath+ specifies an empty directory: - * - * dirpath = '/tmp/foo' - * Dir.mkdir(dirpath) - * Dir.empty?(dirpath) # => true - * Dir.empty?('/example') # => false - * Dir.empty?('/example/main.rb') # => false - * - * Raises an exception if +dirpath+ does not specify a directory or file - * in the underlying file system. + * Returns <code>true</code> if the named file is an empty directory, + * <code>false</code> if it is not a directory or non-empty. */ static VALUE rb_dir_s_empty_p(VALUE obj, VALUE dirname) @@ -3778,13 +3326,12 @@ rb_dir_s_empty_p(VALUE obj, VALUE dirname) { u_int32_t attrbuf[SIZEUP32(fsobj_tag_t)]; struct attrlist al = {ATTR_BIT_MAP_COUNT, 0, ATTR_CMN_OBJTAG,}; - struct getattrlist_args args = GETATTRLIST_ARGS(&al, attrbuf, 0); - if (gvl_getattrlist(&args, path) != 0) + if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), 0) != 0) rb_sys_fail_path(orig); if (*(const fsobj_tag_t *)(attrbuf+1) == VT_HFS) { al.commonattr = 0; al.dirattr = ATTR_DIR_ENTRYCOUNT; - if (gvl_getattrlist(&args, path) == 0) { + if (getattrlist(path, &al, attrbuf, sizeof(attrbuf), 0) == 0) { if (attrbuf[0] >= 2 * sizeof(u_int32_t)) return RBOOL(attrbuf[1] == 0); if (false_on_notdir) return Qfalse; @@ -3794,9 +3341,10 @@ rb_dir_s_empty_p(VALUE obj, VALUE dirname) } #endif - result = (VALUE)IO_WITHOUT_GVL(nogvl_dir_empty_p, (void *)path); - if (FIXNUM_P(result)) { - rb_syserr_fail_path((int)FIX2LONG(result), orig); + result = (VALUE)rb_thread_call_without_gvl(nogvl_dir_empty_p, (void *)path, + RUBY_UBF_IO, 0); + if (UNDEF_P(result)) { + rb_sys_fail_path(orig); } return result; } @@ -3804,15 +3352,11 @@ rb_dir_s_empty_p(VALUE obj, VALUE dirname) void Init_Dir(void) { - rb_gc_register_address(&chdir_lock.path); - rb_gc_register_address(&chdir_lock.thread); - rb_cDir = rb_define_class("Dir", rb_cObject); rb_include_module(rb_cDir, rb_mEnumerable); rb_define_alloc_func(rb_cDir, dir_s_alloc); - rb_define_singleton_method(rb_cDir,"for_fd", dir_s_for_fd, 1); rb_define_singleton_method(rb_cDir, "foreach", dir_foreach, -1); rb_define_singleton_method(rb_cDir, "entries", dir_entries, -1); rb_define_singleton_method(rb_cDir, "each_child", dir_s_each_child, -1); @@ -3832,9 +3376,7 @@ Init_Dir(void) rb_define_method(rb_cDir,"pos", dir_tell, 0); rb_define_method(rb_cDir,"pos=", dir_set_pos, 1); rb_define_method(rb_cDir,"close", dir_close, 0); - rb_define_method(rb_cDir,"chdir", dir_chdir, 0); - rb_define_singleton_method(rb_cDir,"fchdir", dir_s_fchdir, 1); rb_define_singleton_method(rb_cDir,"chdir", dir_s_chdir, -1); rb_define_singleton_method(rb_cDir,"getwd", dir_s_getwd, 0); rb_define_singleton_method(rb_cDir,"pwd", dir_s_getwd, 0); @@ -3851,26 +3393,51 @@ Init_Dir(void) rb_define_singleton_method(rb_cFile,"fnmatch", file_s_fnmatch, -1); rb_define_singleton_method(rb_cFile,"fnmatch?", file_s_fnmatch, -1); - /* Document-const: FNM_NOESCAPE - * {File::FNM_NOESCAPE}[rdoc-ref:File::Constants@File-3A-3AFNM_NOESCAPE] */ + /* Document-const: File::Constants::FNM_NOESCAPE + * + * Disables escapes in File.fnmatch and Dir.glob patterns + */ rb_file_const("FNM_NOESCAPE", INT2FIX(FNM_NOESCAPE)); - /* Document-const: FNM_PATHNAME - * {File::FNM_PATHNAME}[rdoc-ref:File::Constants@File-3A-3AFNM_PATHNAME] */ + + /* Document-const: File::Constants::FNM_PATHNAME + * + * Wildcards in File.fnmatch and Dir.glob patterns do not match directory + * separators + */ rb_file_const("FNM_PATHNAME", INT2FIX(FNM_PATHNAME)); - /* Document-const: FNM_DOTMATCH - * {File::FNM_DOTMATCH}[rdoc-ref:File::Constants@File-3A-3AFNM_DOTMATCH] */ + + /* Document-const: File::Constants::FNM_DOTMATCH + * + * The '*' wildcard matches filenames starting with "." in File.fnmatch + * and Dir.glob patterns + */ rb_file_const("FNM_DOTMATCH", INT2FIX(FNM_DOTMATCH)); - /* Document-const: FNM_CASEFOLD - * {File::FNM_CASEFOLD}[rdoc-ref:File::Constants@File-3A-3AFNM_CASEFOLD] */ + + /* Document-const: File::Constants::FNM_CASEFOLD + * + * Makes File.fnmatch patterns case insensitive (but not Dir.glob + * patterns). + */ rb_file_const("FNM_CASEFOLD", INT2FIX(FNM_CASEFOLD)); - /* Document-const: FNM_EXTGLOB - * {File::FNM_EXTGLOB}[rdoc-ref:File::Constants@File-3A-3AFNM_EXTGLOB] */ + + /* Document-const: File::Constants::FNM_EXTGLOB + * + * Allows file globbing through "{a,b}" in File.fnmatch patterns. + */ rb_file_const("FNM_EXTGLOB", INT2FIX(FNM_EXTGLOB)); - /* Document-const: FNM_SYSCASE - * {File::FNM_SYSCASE}[rdoc-ref:File::Constants@File-3A-3AFNM_SYSCASE] */ + + /* Document-const: File::Constants::FNM_SYSCASE + * + * System default case insensitiveness, equals to FNM_CASEFOLD or + * 0. + */ rb_file_const("FNM_SYSCASE", INT2FIX(FNM_SYSCASE)); - /* Document-const: FNM_SHORTNAME - * {File::FNM_SHORTNAME}[rdoc-ref:File::Constants@File-3A-3AFNM_SHORTNAME] */ + + /* Document-const: File::Constants::FNM_SHORTNAME + * + * Makes patterns to match short names if existing. Valid only + * on Microsoft Windows. + */ rb_file_const("FNM_SHORTNAME", INT2FIX(FNM_SHORTNAME)); } @@ -1,85 +1,11 @@ -# An object of class \Dir represents a directory in the underlying file system. +# Objects of class Dir are directory streams representing +# directories in the underlying file system. They provide a variety +# of ways to list directories and their contents. See also File. # -# It consists mainly of: -# -# - A string _path_, given when the object is created, -# that specifies a directory in the underlying file system; -# method #path returns the path. -# - A collection of string <i>entry names</i>, -# each of which is the name of a directory or file in the underlying file system; -# the entry names may be retrieved -# in an {array-like fashion}[rdoc-ref:Dir@Dir+As+Array-Like] -# or in a {stream-like fashion}[rdoc-ref:Dir@Dir+As+Stream-Like]. -# -# == About the Examples -# -# Some examples on this page use this simple file tree: -# -# example/ -# ├── config.h -# ├── lib/ -# │ ├── song/ -# │ │ └── karaoke.rb -# │ └── song.rb -# └── main.rb -# -# Others use the file tree for the -# {Ruby project itself}[https://github.com/ruby/ruby]. -# -# == \Dir As \Array-Like -# -# A \Dir object is in some ways array-like: -# -# - It has instance methods #children, #each, and #each_child. -# - It includes {module Enumerable}[rdoc-ref:Enumerable@What-27s+Here]. -# -# == \Dir As Stream-Like -# -# A \Dir object is in some ways stream-like. -# -# The stream is initially open for reading, -# but may be closed manually (using method #close), -# and will be closed on block exit if created by Dir.open called with a block. -# The closed stream may not be further manipulated, -# and may not be reopened. -# -# The stream has a _position_, which is the index of an entry in the directory: -# -# - The initial position is zero (before the first entry). -# - \Method #tell (aliased as #pos) returns the position. -# - \Method #pos= sets the position (but ignores a value outside the stream), -# and returns the position. -# - \Method #seek is like #pos=, but returns +self+ (convenient for chaining). -# - \Method #read, if not at end-of-stream, reads the next entry and increments -# the position; -# if at end-of-stream, does not increment the position. -# - \Method #rewind sets the position to zero. -# -# Examples (using the {simple file tree}[rdoc-ref:Dir@About+the+Examples]): -# -# dir = Dir.new('example') # => #<Dir:example> -# dir.pos # => 0 -# -# dir.read # => "." -# dir.read # => ".." -# dir.read # => "config.h" -# dir.read # => "lib" -# dir.read # => "main.rb" -# dir.pos # => 5 -# dir.read # => nil -# dir.pos # => 5 -# -# dir.rewind # => #<Dir:example> -# dir.pos # => 0 -# -# dir.pos = 3 # => 3 -# dir.pos # => 3 -# -# dir.seek(4) # => #<Dir:example> -# dir.pos # => 4 -# -# dir.close # => nil -# dir.read # Raises IOError. +# The directory used in these examples contains the two regular files +# (<code>config.h</code> and <code>main.rb</code>), the parent +# directory (<code>..</code>), and the directory itself +# (<code>.</code>). # # == What's Here # @@ -154,32 +80,20 @@ # closing it upon block exit. # - ::unlink (aliased as ::delete and ::rmdir): Removes the given directory. # - #inspect: Returns a string description of +self+. -# class Dir # call-seq: - # Dir.open(dirpath) -> dir - # Dir.open(dirpath, encoding: nil) -> dir - # Dir.open(dirpath) {|dir| ... } -> object - # Dir.open(dirpath, encoding: nil) {|dir| ... } -> object - # - # Creates a new \Dir object _dir_ for the directory at +dirpath+. - # - # With no block, the method equivalent to Dir.new(dirpath, encoding): - # - # Dir.open('.') # => #<Dir:.> - # - # With a block given, the block is called with the created _dir_; - # on block exit _dir_ is closed and the block's value is returned: - # - # Dir.open('.') {|dir| dir.inspect } # => "#<Dir:.>" - # - # The value given with optional keyword argument +encoding+ - # specifies the encoding for the directory entry names; - # if +nil+ (the default), the file system's encoding is used: - # - # Dir.open('.').read.encoding # => #<Encoding:UTF-8> - # Dir.open('.', encoding: 'US-ASCII').read.encoding # => #<Encoding:US-ASCII> - # + # Dir.open( string ) -> aDir + # Dir.open( string, encoding: enc ) -> aDir + # Dir.open( string ) {| aDir | block } -> anObject + # Dir.open( string, encoding: enc ) {| aDir | block } -> anObject + # + # The optional <i>encoding</i> keyword argument specifies the encoding of the directory. + # If not specified, the filesystem encoding is used. + # + # With no block, <code>open</code> is a synonym for Dir::new. If a + # block is present, it is passed <i>aDir</i> as a parameter. The + # directory is closed at the end of the block, and Dir::open returns + # the value of the block. def self.open(name, encoding: nil, &block) dir = Primitive.dir_s_open(name, encoding) if block @@ -194,221 +108,115 @@ class Dir end # call-seq: - # Dir.new(dirpath) -> dir - # Dir.new(dirpath, encoding: nil) -> dir - # - # Returns a new \Dir object for the directory at +dirpath+: - # - # Dir.new('.') # => #<Dir:.> + # Dir.new( string ) -> aDir + # Dir.new( string, encoding: enc ) -> aDir # - # The value given with optional keyword argument +encoding+ - # specifies the encoding for the directory entry names; - # if +nil+ (the default), the file system's encoding is used: - # - # Dir.new('.').read.encoding # => #<Encoding:UTF-8> - # Dir.new('.', encoding: 'US-ASCII').read.encoding # => #<Encoding:US-ASCII> + # Returns a new directory object for the named directory. # + # The optional <i>encoding</i> keyword argument specifies the encoding of the directory. + # If not specified, the filesystem encoding is used. def initialize(name, encoding: nil) Primitive.dir_initialize(name, encoding) end # call-seq: - # Dir[*patterns, base: nil, sort: true] -> array - # - # Calls Dir.glob with argument +patterns+ - # and the values of keyword arguments +base+ and +sort+; - # returns the array of selected entry names. + # Dir[ string [, string ...] [, base: path] [, sort: true] ] -> array # + # Equivalent to calling + # <code>Dir.glob([</code><i>string,...</i><code>], 0)</code>. def self.[](*args, base: nil, sort: true) Primitive.dir_s_aref(args, base, sort) end # call-seq: - # Dir.glob(*patterns, flags: 0, base: nil, sort: true) -> array - # Dir.glob(*patterns, flags: 0, base: nil, sort: true) {|entry_name| ... } -> nil - # - # Forms an array _entry_names_ of the entry names selected by the arguments. - # - # Argument +patterns+ is a string pattern or an array of string patterns; - # note that these are not regexps; see below. - # - # Notes for the following examples: - # - # - <tt>'*'</tt> is the pattern that matches any entry name - # except those that begin with <tt>'.'</tt>. - # - We use method Array#take to shorten returned arrays - # that otherwise would be very large. - # - # With no block, returns array _entry_names_; - # example (using the {simple file tree}[rdoc-ref:Dir@About+the+Examples]): - # - # Dir.glob('*') # => ["config.h", "lib", "main.rb"] - # - # With a block, calls the block with each of the _entry_names_ - # and returns +nil+: - # - # Dir.glob('*') {|entry_name| puts entry_name } # => nil + # Dir.glob( pattern, [flags], [base: path] [, sort: true] ) -> array + # Dir.glob( pattern, [flags], [base: path] [, sort: true] ) { |filename| block } -> nil # - # Output: + # Expands +pattern+, which is a pattern string or an Array of pattern + # strings, and returns an array containing the matching filenames. + # If a block is given, calls the block once for each matching filename, + # passing the filename as a parameter to the block. # - # config.h - # lib - # main.rb + # The optional +base+ keyword argument specifies the base directory for + # interpreting relative pathnames instead of the current working directory. + # As the results are not prefixed with the base directory name in this + # case, you will need to prepend the base directory name if you want real + # paths. # - # If optional keyword argument +flags+ is given, - # the value modifies the matching; see below. + # The results which matched single wildcard or character set are sorted in + # binary ascending order, unless +false+ is given as the optional +sort+ + # keyword argument. The order of an Array of pattern strings and braces + # are preserved. # - # If optional keyword argument +base+ is given, - # its value specifies the base directory. - # Each pattern string specifies entries relative to the base directory; - # the default is <tt>'.'</tt>. - # The base directory is not prepended to the entry names in the result: + # Note that the pattern is not a regexp, it's closer to a shell glob. + # See File::fnmatch for the meaning of the +flags+ parameter. + # Case sensitivity depends on your system (+File::FNM_CASEFOLD+ is ignored). # - # Dir.glob(pattern, base: 'lib').take(5) - # # => ["abbrev.gemspec", "abbrev.rb", "base64.gemspec", "base64.rb", "benchmark.gemspec"] - # Dir.glob(pattern, base: 'lib/irb').take(5) - # # => ["cmd", "color.rb", "color_printer.rb", "completion.rb", "context.rb"] - # - # If optional keyword +sort+ is given, its value specifies whether - # the array is to be sorted; the default is +true+. - # Passing value +false+ with that keyword disables sorting - # (though the underlying file system may already have sorted the array). - # - # <b>Patterns</b> - # - # Each pattern string is expanded - # according to certain metacharacters; - # examples below use the {Ruby file tree}[rdoc-ref:Dir@About+the+Examples]: - # - # - <tt>'*'</tt>: Matches any substring in an entry name, - # similar in meaning to regexp <tt>/.*/mx</tt>; - # may be restricted by other values in the pattern strings: - # - # - <tt>'*'</tt> matches all entry names: - # - # Dir.glob('*').take(3) # => ["BSDL", "CONTRIBUTING.md", "COPYING"] - # - # - <tt>'c*'</tt> matches entry names beginning with <tt>'c'</tt>: - # - # Dir.glob('c*').take(3) # => ["CONTRIBUTING.md", "COPYING", "COPYING.ja"] - # - # - <tt>'*c'</tt> matches entry names ending with <tt>'c'</tt>: - # - # Dir.glob('*c').take(3) # => ["addr2line.c", "array.c", "ast.c"] - # - # - <tt>'\*c\*'</tt> matches entry names that contain <tt>'c'</tt>, - # even at the beginning or end: - # - # Dir.glob('*c*').take(3) # => ["CONTRIBUTING.md", "COPYING", "COPYING.ja"] - # - # Does not match Unix-like hidden entry names ("dot files"). - # To include those in the matched entry names, - # use flag IO::FNM_DOTMATCH or something like <tt>'{*,.*}'</tt>. - # - # - <tt>'**'</tt>: Matches entry names recursively - # if followed by the slash character <tt>'/'</tt>: - # - # Dir.glob('**/').take(3) # => ["basictest/", "benchmark/", "benchmark/gc/"] - # - # If the string pattern contains other characters - # or is not followed by a slash character, - # it is equivalent to <tt>'*'</tt>. - # - # - <tt>'?'</tt> Matches any single character; - # similar in meaning to regexp <tt>/./</tt>: - # - # Dir.glob('io.?') # => ["io.c"] - # - # - <tt>'[_set_]'</tt>: Matches any one character in the string _set_; - # behaves like a {Regexp character class}[rdoc-ref:Regexp@Character+Classes], - # including set negation (<tt>'[^a-z]'</tt>): - # - # Dir.glob('*.[a-z][a-z]').take(3) - # # => ["CONTRIBUTING.md", "COPYING.ja", "KNOWNBUGS.rb"] - # - # - <tt>'{_abc_,_xyz_}'</tt>: - # Matches either string _abc_ or string _xyz_; - # behaves like {Regexp alternation}[rdoc-ref:Regexp@Alternation]: - # - # Dir.glob('{LEGAL,BSDL}') # => ["LEGAL", "BSDL"] - # - # More than two alternatives may be given. - # - # - <tt>\\</tt>: Escapes the following metacharacter. - # - # Note that on Windows, the backslash character may not be used - # in a string pattern: - # <tt>Dir['c:\\foo*']</tt> will not work, use <tt>Dir['c:/foo*']</tt> instead. - # - # More examples (using the {simple file tree}[rdoc-ref:Dir@About+the+Examples]): - # - # # We're in the example directory. - # File.basename(Dir.pwd) # => "example" - # Dir.glob('config.?') # => ["config.h"] - # Dir.glob('*.[a-z][a-z]') # => ["main.rb"] - # Dir.glob('*.[^r]*') # => ["config.h"] - # Dir.glob('*.{rb,h}') # => ["main.rb", "config.h"] - # Dir.glob('*') # => ["config.h", "lib", "main.rb"] - # Dir.glob('*', File::FNM_DOTMATCH) # => [".", "config.h", "lib", "main.rb"] - # Dir.glob(["*.rb", "*.h"]) # => ["main.rb", "config.h"] - # - # Dir.glob('**/*.rb') - # => ["lib/song/karaoke.rb", "lib/song.rb", "main.rb"] - # - # Dir.glob('**/*.rb', base: 'lib') # => ["song/karaoke.rb", "song.rb"] - # - # Dir.glob('**/lib') # => ["lib"] + # <code>*</code>:: + # Matches any file. Can be restricted by other values in the glob. + # Equivalent to <code>/.*/mx</code> in regexp. # - # Dir.glob('**/lib/**/*.rb') # => ["lib/song/karaoke.rb", "lib/song.rb"] + # <code>*</code>:: Matches all files + # <code>c*</code>:: Matches all files beginning with <code>c</code> + # <code>*c</code>:: Matches all files ending with <code>c</code> + # <code>\*c\*</code>:: Match all files that have <code>c</code> in them + # (including at the beginning or end). # - # Dir.glob('**/lib/*.rb') # => ["lib/song.rb"] + # Note, this will not match Unix-like hidden files (dotfiles). In order + # to include those in the match results, you must use the + # File::FNM_DOTMATCH flag or something like <code>"{*,.*}"</code>. # - # <b>Flags</b> + # <code>**</code>:: + # Matches directories recursively if followed by <code>/</code>. If + # this path segment contains any other characters, it is the same as the + # usual <code>*</code>. # - # If optional keyword argument +flags+ is given (the default is zero -- no flags), - # its value should be the bitwise OR of one or more of the constants - # defined in module File::Constants. + # <code>?</code>:: + # Matches any one character. Equivalent to <code>/.{1}/</code> in regexp. # - # Example: + # <code>[set]</code>:: + # Matches any one character in +set+. Behaves exactly like character sets + # in Regexp, including set negation (<code>[^a-z]</code>). # - # flags = File::FNM_EXTGLOB | File::FNM_DOTMATCH + # <code>{p,q}</code>:: + # Matches either literal <code>p</code> or literal <code>q</code>. + # Equivalent to pattern alternation in regexp. # - # Specifying flags can extend, restrict, or otherwise modify the matching. + # Matching literals may be more than one character in length. More than + # two literals may be specified. # - # The flags for this method (other constants in File::Constants do not apply): + # <code>\\</code>:: + # Escapes the next metacharacter. # - # - File::FNM_DOTMATCH: - # specifies that entry names beginning with <tt>'.'</tt> - # should be considered for matching: + # Note that this means you cannot use backslash on windows as part of a + # glob, i.e. <code>Dir["c:\\foo*"]</code> will not work, use + # <code>Dir["c:/foo*"]</code> instead. # - # Dir.glob('*').take(5) - # # => ["BSDL", "CONTRIBUTING.md", "COPYING", "COPYING.ja", "GPL"] - # Dir.glob('*', flags: File::FNM_DOTMATCH).take(5) - # # => [".", ".appveyor.yml", ".cirrus.yml", ".dir-locals.el", ".document"] + # Examples: # - # - File::FNM_EXTGLOB: - # enables the pattern extension - # <tt>'{_a_,_b_}'</tt>, which matches pattern _a_ and pattern _b_; - # behaves like a - # {regexp union}[rdoc-ref:Regexp.union] - # (e.g., <tt>'(?:_a_|_b_)'</tt>): + # Dir["config.?"] #=> ["config.h"] + # Dir.glob("config.?") #=> ["config.h"] + # Dir.glob("*.[a-z][a-z]") #=> ["main.rb"] + # Dir.glob("*.[^r]*") #=> ["config.h"] + # Dir.glob("*.{rb,h}") #=> ["main.rb", "config.h"] + # Dir.glob("*") #=> ["config.h", "main.rb"] + # Dir.glob("*", File::FNM_DOTMATCH) #=> [".", "config.h", "main.rb"] + # Dir.glob(["*.rb", "*.h"]) #=> ["main.rb", "config.h"] # - # pattern = '{LEGAL,BSDL}' - # Dir.glob(pattern) # => ["LEGAL", "BSDL"] + # Dir.glob("**/*.rb") #=> ["main.rb", + # # "lib/song.rb", + # # "lib/song/karaoke.rb"] # - # - File::FNM_NOESCAPE: - # specifies that escaping with the backslash character <tt>'\'</tt> - # is disabled; the character is not an escape character. + # Dir.glob("**/*.rb", base: "lib") #=> ["song.rb", + # # "song/karaoke.rb"] # - # - File::FNM_PATHNAME: - # specifies that metacharacters <tt>'*'</tt> and <tt>'?'</tt> - # do not match directory separators. + # Dir.glob("**/lib") #=> ["lib"] # - # - File::FNM_SHORTNAME: - # specifies that patterns may match short names if they exist; Windows only. + # Dir.glob("**/lib/**/*.rb") #=> ["lib/song.rb", + # # "lib/song/karaoke.rb"] # + # Dir.glob("**/lib/*.rb") #=> ["lib/song.rb"] def self.glob(pattern, _flags = 0, flags: _flags, base: nil, sort: true) - Primitive.attr! :use_block Primitive.dir_s_glob(pattern, flags, base, sort) end end @@ -107,45 +107,36 @@ dln_loaderror(const char *format, ...) #endif #if defined(_WIN32) || defined(USE_DLN_DLOPEN) -struct string_part { - const char *ptr; - size_t len; -}; - -static struct string_part -init_funcname_len(const char *file) +static size_t +init_funcname_len(const char **file) { - const char *p = file, *base, *dot = NULL; + const char *p = *file, *base, *dot = NULL; /* Load the file as an object one */ for (base = p; *p; p++) { /* Find position of last '/' */ if (*p == '.' && !dot) dot = p; if (isdirsep(*p)) base = p+1, dot = NULL; } + *file = base; /* Delete suffix if it exists */ - const size_t len = (dot ? dot : p) - base; - return (struct string_part){base, len}; -} - -static inline char * -concat_funcname(char *buf, const char *prefix, size_t plen, const struct string_part base) -{ - if (!buf) { - dln_memerror(); - } - memcpy(buf, prefix, plen); - memcpy(buf + plen, base.ptr, base.len); - buf[plen + base.len] = '\0'; - return buf; + return (dot ? dot : p) - base; } -#define build_funcname(prefix, buf, file) do {\ - const struct string_part f = init_funcname_len(file);\ - const size_t plen = sizeof(prefix "") - 1;\ - *(buf) = concat_funcname(ALLOCA_N(char, plen+f.len+1), prefix, plen, f);\ +static const char funcname_prefix[sizeof(FUNCNAME_PREFIX) - 1] = FUNCNAME_PREFIX; + +#define init_funcname(buf, file) do {\ + const char *base = (file);\ + const size_t flen = init_funcname_len(&base);\ + const size_t plen = sizeof(funcname_prefix);\ + char *const tmp = ALLOCA_N(char, plen+flen+1);\ + if (!tmp) {\ + dln_memerror();\ + }\ + memcpy(tmp, funcname_prefix, plen);\ + memcpy(tmp+plen, base, flen);\ + tmp[plen+flen] = '\0';\ + *(buf) = tmp;\ } while (0) - -#define init_funcname(buf, file) build_funcname(FUNCNAME_PREFIX, buf, file) #endif #ifdef USE_DLN_DLOPEN @@ -281,15 +272,13 @@ rb_w32_check_imported(HMODULE ext, HMODULE mine) static bool dln_incompatible_func(void *handle, const char *funcname, void *const fp, const char **libname) { + Dl_info dli; void *ex = dlsym(handle, funcname); if (!ex) return false; if (ex == fp) return false; -# if defined(HAVE_DLADDR) - Dl_info dli; if (dladdr(ex, &dli)) { *libname = dli.dli_fname; } -# endif return true; } @@ -403,12 +392,6 @@ dln_open(const char *file) dln_fatalerror("%s - %s", incompatible, file); } else { - if (libruby_name) { - const size_t len = strlen(libruby_name); - char *const tmp = ALLOCA_N(char, len + 1); - if (tmp) memcpy(tmp, libruby_name, len + 1); - libruby_name = tmp; - } dlclose(handle); if (libruby_name) { dln_loaderror("linked to incompatible %s - %s", libruby_name, file); @@ -430,63 +413,33 @@ dln_open(const char *file) static void * dln_sym(void *handle, const char *symbol) { -#if defined(_WIN32) - return GetProcAddress(handle, symbol); -#elif defined(USE_DLN_DLOPEN) - return dlsym(handle, symbol); -#endif -} + void *func; + const char *error; -static void * -dln_sym_func(void *handle, const char *symbol) -{ - void *func = dln_sym(handle, symbol); +#if defined(_WIN32) + char message[1024]; + func = GetProcAddress(handle, symbol); if (func == NULL) { - const char *error; -#if defined(_WIN32) - char message[1024]; error = dln_strerror(); + goto failed; + } + #elif defined(USE_DLN_DLOPEN) + func = dlsym(handle, symbol); + if (func == NULL) { const size_t errlen = strlen(error = dln_strerror()) + 1; error = memcpy(ALLOCA_N(char, errlen), error, errlen); -#endif - dln_loaderror("%s - %s", error, symbol); + goto failed; } - return func; -} - -#define dln_sym_callable(rettype, argtype, handle, symbol) \ - (*(rettype (*)argtype)dln_sym_func(handle, symbol)) #endif -void * -dln_symbol(void *handle, const char *symbol) -{ -#if defined(_WIN32) || defined(USE_DLN_DLOPEN) - if (EXTERNAL_PREFIX[0]) { - const size_t symlen = strlen(symbol); - char *const tmp = ALLOCA_N(char, symlen + sizeof(EXTERNAL_PREFIX)); - if (!tmp) dln_memerror(); - memcpy(tmp, EXTERNAL_PREFIX, sizeof(EXTERNAL_PREFIX) - 1); - memcpy(tmp + sizeof(EXTERNAL_PREFIX) - 1, symbol, symlen + 1); - symbol = tmp; - } - if (handle == NULL) { -# if defined(USE_DLN_DLOPEN) - handle = dlopen(NULL, RTLD_LAZY | RTLD_GLOBAL); -# elif defined(_WIN32) - handle = rb_libruby_handle(); -# else - return NULL; -# endif - } - return dln_sym(handle, symbol); -#else - return NULL; -#endif -} + return func; + failed: + dln_loaderror("%s - %s", error, symbol); +} +#endif #if defined(RUBY_DLN_CHECK_ABI) && defined(USE_DLN_DLOPEN) static bool @@ -504,19 +457,19 @@ dln_load(const char *file) void *handle = dln_open(file); #ifdef RUBY_DLN_CHECK_ABI - typedef unsigned long long abi_version_number; - abi_version_number binary_abi_version = - dln_sym_callable(abi_version_number, (void), handle, EXTERNAL_PREFIX "ruby_abi_version")(); - if (binary_abi_version != RUBY_ABI_VERSION && abi_check_enabled_p()) { + unsigned long long (*abi_version_fct)(void) = (unsigned long long(*)(void))dln_sym(handle, "ruby_abi_version"); + unsigned long long binary_abi_version = (*abi_version_fct)(); + if (binary_abi_version != ruby_abi_version() && abi_check_enabled_p()) { dln_loaderror("incompatible ABI version of binary - %s", file); } #endif char *init_fct_name; init_funcname(&init_fct_name, file); + void (*init_fct)(void) = (void(*)(void))dln_sym(handle, init_fct_name); /* Call the init code */ - dln_sym_callable(void, (void), handle, init_fct_name)(); + (*init_fct)(); return handle; @@ -25,7 +25,6 @@ RUBY_SYMBOL_EXPORT_BEGIN char *dln_find_exe_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL); char *dln_find_file_r(const char*,const char*,char*,size_t DLN_FIND_EXTRA_ARG_DECL); void *dln_load(const char*); -void *dln_symbol(void*,const char*); RUBY_SYMBOL_EXPORT_END diff --git a/dln_find.c b/dln_find.c index ae37b9dde4..5d380f5d39 100644 --- a/dln_find.c +++ b/dln_find.c @@ -11,9 +11,11 @@ #ifdef RUBY_EXPORT #include "ruby/ruby.h" -#define dln_warning(...) rb_warning(__VA_ARGS__) +#define dln_warning rb_warning +#define dln_warning_arg #else -#define dln_warning(...) fprintf(stderr, __VA_ARGS__) +#define dln_warning fprintf +#define dln_warning_arg stderr, #endif #include "dln.h" @@ -73,7 +75,7 @@ dln_find_exe_r(const char *fname, const char *path, char *buf, size_t size "."; } buf = dln_find_1(fname, path, buf, size, 1 DLN_FIND_EXTRA_ARG); - free(envpath); + if (envpath) free(envpath); return buf; } @@ -107,7 +109,7 @@ dln_find_1(const char *fname, const char *path, char *fbuf, size_t size, static const char pathname_too_long[] = "openpath: pathname too long (ignored)\n\ \tDirectory \"%.*s\"%s\n\tFile \"%.*s\"%s\n"; -#define PATHNAME_TOO_LONG() dln_warning(pathname_too_long, \ +#define PATHNAME_TOO_LONG() dln_warning(dln_warning_arg pathname_too_long, \ ((bp - fbuf) > 100 ? 100 : (int)(bp - fbuf)), fbuf, \ ((bp - fbuf) > 100 ? "..." : ""), \ (fnlen > 100 ? 100 : (int)fnlen), fname, \ @@ -118,7 +120,8 @@ dln_find_1(const char *fname, const char *path, char *fbuf, size_t size, RETURN_IF(!fname); fnlen = strlen(fname); if (fnlen >= size) { - dln_warning("openpath: pathname too long (ignored)\n\tFile \"%.*s\"%s\n", + dln_warning(dln_warning_arg + "openpath: pathname too long (ignored)\n\tFile \"%.*s\"%s\n", (fnlen > 100 ? 100 : (int)fnlen), fname, (fnlen > 100 ? "..." : "")); return NULL; @@ -1,6 +1,3 @@ -// This file is used by miniruby, not ruby. -// ruby uses dln.c. - #include "ruby/ruby.h" NORETURN(void *dln_load(const char *)); @@ -11,12 +8,3 @@ dln_load(const char *file) UNREACHABLE_RETURN(NULL); } - -NORETURN(void *dln_symbol(void*,const char*)); -void* -dln_symbol(void *handle, const char *symbol) -{ - rb_loaderror("this executable file can't load extension libraries"); - - UNREACHABLE_RETURN(NULL); -} @@ -1,17 +1,3 @@ -// This file is used by dynamically-linked ruby, which has no -// statically-linked encodings other than the builtin encodings. -// -// - miniruby does not use this Init_enc. Instead, "miniinit.c" -// provides Init_enc, which defines only the builtin encodings. -// -// - Dynamically-linked ruby uses this Init_enc, which requires -// "enc/encdb.so" to load the builtin encodings and set up the -// optional encodings. -// -// - Statically-linked ruby does not use this Init_enc. Instead, -// "enc/encinit.c" (which is a generated file) defines Init_enc, -// which activates the encodings. - #define require(name) ruby_require_internal(name, (unsigned int)sizeof(name)-1) int ruby_require_internal(const char *, int); @@ -1,17 +1,3 @@ -// This file is used by dynamically-linked ruby, which has no -// statically-linked extension libraries. -// -// - miniruby does not use this Init_ext. Instead, "miniinit.c" -// provides Init_enc, which does nothing too. It does not support -// require'ing extension libraries. -// -// - Dynamically-linked ruby uses this Init_ext, which does -// nothing. It loads extension libraries by dlopen, etc. -// -// - Statically-linked ruby does not use this Init_ext. Instead, -// "ext/extinit.c" (which is a generated file) defines Init_ext, -// which activates the (statically-linked) extension libraries. - void Init_ext(void) { diff --git a/doc/.document b/doc/.document index 8174394f48..f589dda07c 100644 --- a/doc/.document +++ b/doc/.document @@ -1,12 +1,9 @@ *.md *.rb -[^_]*.rdoc +*.rdoc contributing NEWS syntax optparse rdoc -regexp -rjit yjit -ruby diff --git a/doc/ChangeLog/ChangeLog-0.06_to_0.52 b/doc/ChangeLog-0.06_to_0.52 index 63826081b3..63826081b3 100644 --- a/doc/ChangeLog/ChangeLog-0.06_to_0.52 +++ b/doc/ChangeLog-0.06_to_0.52 diff --git a/doc/ChangeLog/ChangeLog-0.50_to_0.60 b/doc/ChangeLog-0.50_to_0.60 index 5f5b03ff40..5f5b03ff40 100644 --- a/doc/ChangeLog/ChangeLog-0.50_to_0.60 +++ b/doc/ChangeLog-0.50_to_0.60 diff --git a/doc/ChangeLog/ChangeLog-0.60_to_1.1 b/doc/ChangeLog-0.60_to_1.1 index 59d195e780..59d195e780 100644 --- a/doc/ChangeLog/ChangeLog-0.60_to_1.1 +++ b/doc/ChangeLog-0.60_to_1.1 diff --git a/doc/ChangeLog/ChangeLog-1.8.0 b/doc/ChangeLog-1.8.0 index 6d9453d011..6d9453d011 100644 --- a/doc/ChangeLog/ChangeLog-1.8.0 +++ b/doc/ChangeLog-1.8.0 diff --git a/doc/ChangeLog/ChangeLog-1.9.3 b/doc/ChangeLog-1.9.3 index 0f80eed2d5..0f80eed2d5 100644 --- a/doc/ChangeLog/ChangeLog-1.9.3 +++ b/doc/ChangeLog-1.9.3 |