diff --git a/.github/workflows/build-and-test-macos.yaml b/.github/workflows/build-and-test-macos.yaml index ebf3f16cd..fcf1e309b 100644 --- a/.github/workflows/build-and-test-macos.yaml +++ b/.github/workflows/build-and-test-macos.yaml @@ -39,7 +39,7 @@ jobs: fail-fast: false matrix: os: ["macos-14", "macos-15", "macos-15-intel", "macos-26"] - otp: ["24", "25", "26", "27", "28"] + otp: ["26", "27", "28"] mbedtls: ["mbedtls@3"] cmake_opts_other: [""] @@ -67,22 +67,8 @@ jobs: submodules: 'recursive' - name: "Install deps" - if: matrix.otp != '24' && matrix.otp != '25' run: brew update && HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install gperf doxygen erlang@${{ matrix.otp }} gleam ${{ matrix.mbedtls }} rebar3 - - name: "Install deps" - if: matrix.otp == '24' || matrix.otp == '25' - run: | - brew update - HOMEBREW_NO_INSTALLED_DEPENDENTS_CHECK=1 brew install gperf doxygen erlang@${{ matrix.otp }} gleam ${{ matrix.mbedtls }} - wget https://github.com/erlang/rebar3/releases/download/3.23.0/rebar3 - chmod +x rebar3 - for bin_dir in {/usr/local,/opt/homebrew}/opt/erlang@{24,25}/bin/ ; do - if [ -e ${bin_dir} ]; then - sudo cp rebar3 ${bin_dir} - fi - done - - name: "Workaround for nxdomain random issues" run: | # https://github.com/actions/runner-images/issues/8649#issuecomment-2231240347 diff --git a/.github/workflows/build-and-test.yaml b/.github/workflows/build-and-test.yaml index 60361ccb4..e31e5ca43 100644 --- a/.github/workflows/build-and-test.yaml +++ b/.github/workflows/build-and-test.yaml @@ -32,6 +32,14 @@ concurrency: group: ${{ github.workflow }}-${{ github.ref != 'refs/heads/main' && github.ref || github.run_id }} cancel-in-progress: true +env: + DEFAULT_OTP_VERSION: "28" + DEFAULT_ELIXIR_VERSION: "1.19" + DEFAULT_REBAR3_VERSION: "3.25.1" + DEFAULT_GLEAM_VERSION: "1.11.1" + DEFAULT_CFLAGS: "-O3" + DEFAULT_CMAKE_OPTS_OTHER: "-DAVM_WARNINGS_ARE_ERRORS=ON" + jobs: build-and-test: runs-on: ${{ matrix.os || 'ubuntu-24.04' }} @@ -48,312 +56,173 @@ jobs: # Ubuntu 22.04 has clang from 12 to 15 ("clang" is 14) # Ubuntu 24.04 has clang from 14 to 18 ("clang" is 18) # We want to test every compiler but don't need to test every OS - # We only test several OTP versions with default compilers (gcc-9, 11, 13, clang-10, 14, 18) - cc: ["gcc-9", "gcc-11", "gcc-13", "clang-10", "clang-14", "clang-18"] - cflags: ["-O3"] - otp: ["25", "26", "27"] - gleam_version: ["1.11.1"] + # We only test several OTP versions with default compilers for supported OSes (gcc 11, gcc 13, clang 14, clang 18) + cc: ["gcc-11", "gcc-13", "clang-14", "clang-18"] + otp: ["26", "27", "28"] include: + ### gcc + # erlef/setup-beam officially supports ubuntu 22 and 24, we are getting + # warnings for gcc 7 and 8 that require ubuntu 20. - cc: "gcc-7" cxx: "g++-7" compiler_pkgs: "gcc-7 g++-7" container: "ubuntu:20.04" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" + cmake_opts_other: " " - cc: "gcc-8" cxx: "g++-8" compiler_pkgs: "gcc-8 g++-8" container: "ubuntu:20.04" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" + # from gcc 9 we can use ubuntu 24. - cc: "gcc-9" cxx: "g++-9" compiler_pkgs: "gcc-9 g++-9" - container: "ubuntu:20.04" - # otp: all - cc: "gcc-10" cxx: "g++-10" compiler_pkgs: "gcc-10 g++-10" - # Use Werror for recent GCC versions that have better diagnostics - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON" - os: "ubuntu-22.04" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" - cc: "gcc-11" cxx: "g++-11" compiler_pkgs: "gcc-11 g++-11" - # Use Werror for recent GCC versions that have better diagnostics - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON" - os: "ubuntu-22.04" # otp: all - cc: "gcc-12" cxx: "g++-12" compiler_pkgs: "gcc-12 g++-12" - # Use Werror for recent GCC versions that have better diagnostics - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON" - os: "ubuntu-24.04" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" - cc: "gcc-13" cxx: "g++-13" compiler_pkgs: "gcc-13 g++-13" - # Use Werror for recent GCC versions that have better diagnostics - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON" - os: "ubuntu-24.04" # otp: all - cc: "gcc-14" cxx: "g++-14" compiler_pkgs: "gcc-14 g++-14" - # Use Werror for recent GCC versions that have better diagnostics - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON" - os: "ubuntu-24.04" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" + ### clang - cc: "clang-10" cxx: "clang++-10" compiler_pkgs: "clang-10" - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON" container: "ubuntu:20.04" - # otp: all - cc: "clang-11" cxx: "clang++-11" compiler_pkgs: "clang-11" - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON" container: "ubuntu:20.04" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" + + # from clang 12 we can use ubuntu 22 - cc: "clang-12" cxx: "clang++-12" compiler_pkgs: "clang-12" - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON" os: "ubuntu-22.04" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" - cc: "clang-13" cxx: "clang++-13" compiler_pkgs: "clang-13" - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON" os: "ubuntu-22.04" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" - cc: "clang-14" cxx: "clang++-14" compiler_pkgs: "clang-14" - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON" - os: "ubuntu-22.04" # otp: all - cc: "clang-15" cxx: "clang++-15" compiler_pkgs: "clang-15" - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON" - os: "ubuntu-24.04" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" - cc: "clang-16" cxx: "clang++-16" compiler_pkgs: "clang-16" - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON" - os: "ubuntu-24.04" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" - cc: "clang-17" cxx: "clang++-17" compiler_pkgs: "clang-17" - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON" - os: "ubuntu-24.04" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" - cc: "clang-18" cxx: "clang++-18" compiler_pkgs: "clang-18" - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON" - os: "ubuntu-24.04" # otp: all - - otp: "25" - elixir_version: "1.14" - rebar3_version: "3.24.0" - - - otp: "26" - elixir_version: "1.17" - rebar3_version: "3.24.0" - - - otp: "27" - elixir_version: "1.18" - rebar3_version: "3.24.0" - - # Old versions of OTP/Elixir - - container: "ubuntu:20.04" - cc: "cc" + # Additional runs with older elixir + - cc: "cc" cxx: "c++" - cflags: "" - otp: "21" - elixir_version: "1.7" - rebar3_version: "3.15.2" - compiler_pkgs: "g++" + otp: "27" + elixir_version: "1.18" - - container: "ubuntu:20.04" - cc: "cc" + - cc: "cc" cxx: "c++" - cflags: "" - otp: "22" - elixir_version: "1.8" - rebar3_version: "3.18.0" - compiler_pkgs: "g++" + otp: "27" + elixir_version: "1.17" - - container: "ubuntu:20.04" - cc: "cc" + - cc: "cc" cxx: "c++" - cflags: "" - otp: "23" - elixir_version: "1.11" - rebar3_version: "3.20.0" - compiler_pkgs: "g++" + otp: "26" + elixir_version: "1.18" - - container: "ubuntu:20.04" - cc: "cc" + - cc: "cc" cxx: "c++" - cflags: "" - otp: "24" - elixir_version: "1.14" - rebar3_version: "3.23.0" - compiler_pkgs: "g++" + otp: "26" + elixir_version: "1.17" - - os: "ubuntu-24.04" - cc: "cc" + # Additional run with OTP master and default compiler + - cc: "cc" cxx: "c++" otp: "master" elixir_version: "main" - rebar3_version: "3.24.0" - - # Additional default compiler builds - - container: "ubuntu:20.04" - cc: "cc" - cxx: "c++" - cflags: "" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" - compiler_pkgs: "g++" - - - os: "ubuntu-22.04" - cc: "cc" - cxx: "c++" - cflags: "" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" # Additional latest & -Os compiler builds - - os: "ubuntu-24.04" - cc: "gcc-14" + - cc: "gcc-14" cxx: "g++-14" cflags: "-Os" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" compiler_pkgs: "gcc-14 g++-14" - - os: "ubuntu-24.04" - cc: "clang-18" + - cc: "clang-18" cxx: "clang++-18" cflags: "-Os" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" compiler_pkgs: "clang-18" # Additional build with 32 bits floats - - os: "ubuntu-24.04" - cc: "cc" + - cc: "cc" cxx: "c++" - otp: "27" - elixir_version: "1.17" - rebar3_version: "3.24.0" - cmake_opts_other: "-DAVM_USE_32BIT_FLOAT=ON" + cmake_opts_other: "-DAVM_USE_32BIT_FLOAT=ON -DAVM_WARNINGS_ARE_ERRORS=ON" + + # Additional run with -DAVM_CREATE_STACKTRACES=off + - cc: "cc" + cxx: "c++" + cmake_opts_other: "-DAVM_CREATE_STACKTRACES=off -DAVM_WARNINGS_ARE_ERRORS=ON" + + # JIT build + - cc: "cc" + cxx: "c++" + cmake_opts_other: "-DAVM_DISABLE_JIT=OFF" + jit_target_arch: "x86_64" # Additional 32 bits build - container: "ubuntu:20.04" cc: "gcc-10" cxx: "g++-10" cflags: "-m32 -O3" - otp: "23" - elixir_version: "1.11" - rebar3_version: "3.20.0" - # Use Werror so we get an error with 32 bit specific warnings cmake_opts_other: "-DAVM_CREATE_STACKTRACES=off -DAVM_WARNINGS_ARE_ERRORS=ON" arch: "i386" compiler_pkgs: "gcc-10 g++-10 gcc-10-multilib g++-10-multilib libc6-dev-i386 libc6-dbg:i386 zlib1g-dev:i386 libmbedtls-dev:i386" - # JIT build - - os: "ubuntu-24.04" - cc: "cc" - cxx: "c++" - cflags: "" - otp: "28" - elixir_version: "1.17" - rebar3_version: "3.24.0" - cmake_opts_other: "-DAVM_DISABLE_JIT=OFF" - jit_target_arch: "x86_64" - # arm64 builds - os: "ubuntu-24.04-arm" cc: "cc" cxx: "c++" - cflags: "-O2" - otp: "28" - elixir_version: "1.17" - rebar3_version: "3.24.0" - cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=OFF" - os: "ubuntu-24.04-arm" cc: "cc" cxx: "c++" - cflags: "" - otp: "28" - elixir_version: "1.17" - rebar3_version: "3.24.0" cmake_opts_other: "-DAVM_DISABLE_JIT=OFF" jit_target_arch: "aarch64" # armhf builds - - os: "ubuntu-24.04" - cc: "arm-linux-gnueabihf-gcc" + - cc: "arm-linux-gnueabihf-gcc" cxx: "arm-linux-gnueabihf-g++" # -D_FILE_OFFSET_BITS=64 is required for making atomvm:posix_readdir/1 test work # otherwise readdir will fail due to 64 bits inode numbers with 32 bit ino_t - cflags: "-mcpu=cortex-a7 -mfloat-abi=hard -O2 -mthumb -mthumb-interwork -D_FILE_OFFSET_BITS=64" - otp: "28" - elixir_version: "1.17" - rebar3_version: "3.24.0" + cflags: "-mcpu=cortex-a7 -mfloat-abi=hard -O3 -mthumb -mthumb-interwork -D_FILE_OFFSET_BITS=64" cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON -DCMAKE_TOOLCHAIN_FILE=${RUNNER_TEMP}/armhf_toolchain.cmake" compiler_pkgs: "crossbuild-essential-armhf libc6-dbg:armhf zlib1g-dev:armhf libmbedtls-dev:armhf qemu-user qemu-user-binfmt binfmt-support" arch: "armhf" library-arch: arm-linux-gnueabihf - - os: "ubuntu-24.04" - cc: "arm-linux-gnueabihf-gcc" + - cc: "arm-linux-gnueabihf-gcc" cxx: "arm-linux-gnueabihf-g++" # -D_FILE_OFFSET_BITS=64 is required for making atomvm:posix_readdir/1 test work # otherwise readdir will fail due to 64 bits inode numbers with 32 bit ino_t - cflags: "-mcpu=cortex-a7 -mfloat-abi=hard -O2 -mthumb -mthumb-interwork -D_FILE_OFFSET_BITS=64" - otp: "28" - elixir_version: "1.17" - rebar3_version: "3.24.0" + cflags: "-mcpu=cortex-a7 -mfloat-abi=hard -O3 -mthumb -mthumb-interwork -D_FILE_OFFSET_BITS=64" cmake_opts_other: "-DAVM_DISABLE_JIT=OFF -DAVM_JIT_TARGET_ARCH=armv6m -DCMAKE_TOOLCHAIN_FILE=${RUNNER_TEMP}/armhf_toolchain.cmake" compiler_pkgs: "crossbuild-essential-armhf libc6-dbg:armhf zlib1g-dev:armhf libmbedtls-dev:armhf qemu-user qemu-user-binfmt binfmt-support" arch: "armhf" @@ -361,15 +230,8 @@ jobs: jit_target_arch: "armv6m" # s390x build - - os: "ubuntu-24.04" - cc: "s390x-linux-gnu-gcc" + - cc: "s390x-linux-gnu-gcc" cxx: "s390x-linux-gnu-g++" - # -D_FILE_OFFSET_BITS=64 is required for making atomvm:posix_readdir/1 test work - # otherwise readdir will fail due to 64 bits inode numbers with 32 bit ino_t - cflags: "-O2" - otp: "28" - elixir_version: "1.17" - rebar3_version: "3.24.0" cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON -DCMAKE_TOOLCHAIN_FILE=${RUNNER_TEMP}/s390x_toolchain.cmake" compiler_pkgs: "crossbuild-essential-s390x libc6-dbg:s390x zlib1g-dev:s390x libmbedtls-dev:s390x qemu-user qemu-user-binfmt binfmt-support" arch: "s390x" @@ -379,10 +241,6 @@ jobs: - os: "ubuntu-24.04" cc: "riscv32-unknown-linux-gnu-gcc" cxx: "riscv32-unknown-linux-gnu-g++" - cflags: "-O2" - otp: "28" - elixir_version: "1.17" - rebar3_version: "3.24.0" cmake_opts_other: "-DAVM_WARNINGS_ARE_ERRORS=ON -DCMAKE_TOOLCHAIN_FILE=${RUNNER_TEMP}/riscv32_ilp32_toolchain.cmake" compiler_pkgs: "qemu-user qemu-user-binfmt binfmt-support" arch: "riscv32" @@ -392,10 +250,6 @@ jobs: - os: "ubuntu-24.04" cc: "riscv32-unknown-linux-gnu-gcc" cxx: "riscv32-unknown-linux-gnu-g++" - cflags: "-O2" - otp: "28" - elixir_version: "1.17" - rebar3_version: "3.24.0" cmake_opts_other: "-DAVM_DISABLE_JIT=OFF -DAVM_JIT_TARGET_ARCH=riscv32 -DCMAKE_TOOLCHAIN_FILE=${RUNNER_TEMP}/riscv32_ilp32_toolchain.cmake" compiler_pkgs: "qemu-user qemu-user-binfmt binfmt-support" arch: "riscv32" @@ -413,6 +267,13 @@ jobs: steps: # Setup + - name: "Set CFLAGS" + run: | + if [ $"CFLAGS" = "" ]; then + echo "CFLAGS=$DEFAULT_CFLAGS" >> $GITHUB_ENV + echo "CXXFLAGS=$DEFAULT_CFLAGS" >> $GITHUB_ENV + fi + - name: "Install deps for containers" if: matrix.container != '' run: apt-get update && apt-get install -y --no-install-recommends sudo unzip git tzdata @@ -566,12 +427,26 @@ jobs: with: submodules: 'recursive' + # There is no working arm64 binary for gleam + # https://github.com/erlef/setup-beam/issues/398 + - uses: erlef/setup-beam@v1 + if: matrix.os != 'ubuntu-24.04-arm' + with: + otp-version: ${{ matrix.otp || env.DEFAULT_OTP_VERSION }} + elixir-version: ${{ matrix.elixir_version || env.DEFAULT_ELIXIR_VERSION }} + rebar3-version: ${{ matrix.rebar3_version || env.DEFAULT_REBAR3_VERSION }} + gleam-version: ${{ matrix.gleam_version || env.DEFAULT_GLEAM_VERSION }} + hexpm-mirrors: | + https://builds.hex.pm + https://repo.hex.pm + https://cdn.jsdelivr.net/hex + - uses: erlef/setup-beam@v1 + if: matrix.os == 'ubuntu-24.04-arm' with: - otp-version: ${{ matrix.otp }} - elixir-version: ${{ matrix.elixir_version }} - rebar3-version: ${{ matrix.rebar3_version }} - gleam-version: ${{ matrix.gleam_version }} + otp-version: ${{ matrix.otp || env.DEFAULT_OTP_VERSION }} + elixir-version: ${{ matrix.elixir_version || env.DEFAULT_ELIXIR_VERSION }} + rebar3-version: ${{ matrix.rebar3_version || env.DEFAULT_REBAR3_VERSION }} hexpm-mirrors: | https://builds.hex.pm https://repo.hex.pm @@ -587,6 +462,8 @@ jobs: echo "**C Compiler version:**" $CC --version $CXX --version + echo "**CFLAGS:**" + echo $CFLAGS echo "**Linker version:**" ld --version echo "**CMake version:**" @@ -602,12 +479,12 @@ jobs: id: cache with: path: 'build/tests/**/*.beam' - key: ${{ matrix.otp }}-${{ hashFiles('**/build-and-test.yaml', 'tests/**/*.erl', 'tests/**/*.hrl', 'tests/**/*.ex') }}-${{ matrix.jit_target_arch }} + key: ${{ matrix.otp || env.DEFAULT_OTP_VERSION }}-${{ hashFiles('**/build-and-test.yaml', 'tests/**/*.erl', 'tests/**/*.hrl', 'tests/**/*.ex') }}-${{ matrix.jit_target_arch }} - name: "Build: run cmake" working-directory: build run: | - cmake ${{ matrix.cmake_opts_fp }} ${{ matrix.cmake_opts_smp }} ${{ matrix.cmake_opts_other }} .. + cmake ${{ matrix.cmake_opts_fp }} ${{ matrix.cmake_opts_smp }} ${{ matrix.cmake_opts_other || env.DEFAULT_CMAKE_OPTS_OTHER }} .. # git clone will use more recent timestamps than cached beam files # touch them so we can benefit from the cache and avoid costly beam file rebuild. find . -name '*.beam' -exec touch {} \; @@ -749,7 +626,7 @@ jobs: ./src/AtomVM ./tests/libs/eavmlib/test_eavmlib.avm - name: "Test: test_jit.avm with valgrind" - if: matrix.library-arch == '' && matrix.otp != '21' && matrix.otp != '22' + if: matrix.library-arch == '' timeout-minutes: 60 working-directory: build run: | @@ -758,7 +635,6 @@ jobs: - name: "Test: test_jit.avm" timeout-minutes: 60 - if: matrix.otp != '21' && matrix.otp != '22' working-directory: build run: | ulimit -c unlimited @@ -840,7 +716,7 @@ jobs: uses: actions/upload-artifact@v4 if: ${{ failure() }} with: - name: core-${{ matrix.os }}-${{ matrix.cc }}-${{ matrix.otp }}-${{ github.run_id }}-${{ github.run_attempt }} + name: core-${{ matrix.os }}-${{ matrix.cc }}-${{ matrix.otp || env.DEFAULT_OTP_VERSION }}-${{ github.run_id }}-${{ github.run_attempt }} path: | core/* retention-days: 5 diff --git a/.github/workflows/run-tests-with-beam.yaml b/.github/workflows/run-tests-with-beam.yaml index 41e73a7e6..6e574c101 100644 --- a/.github/workflows/run-tests-with-beam.yaml +++ b/.github/workflows/run-tests-with-beam.yaml @@ -40,34 +40,6 @@ jobs: fail-fast: false matrix: include: - - os: "ubuntu-24.04" - test_erlang_opts: "-s prime_smp" - container: erlang:21 - otp: "21" - archive: "true" - - - os: "ubuntu-24.04" - test_erlang_opts: "-s prime_smp" - container: erlang:22 - otp: "22" - archive: "true" - - - os: "ubuntu-24.04" - test_erlang_opts: "-s prime_smp" - container: erlang:23 - otp: "23" - archive: "true" - - - os: "ubuntu-24.04" - test_erlang_opts: "-s prime_smp" - otp: "24" - container: erlang:24 - - - os: "ubuntu-24.04" - test_erlang_opts: "-s prime_smp" - otp: "25" - container: erlang:25 - - os: "ubuntu-24.04" test_erlang_opts: "-s prime_smp" otp: "26" @@ -102,11 +74,6 @@ jobs: with: submodules: 'recursive' - - name: "Switch to archive.debian.org" - if: matrix.archive == 'true' - run: | - sed -i 's|deb\.debian\.org|archive.debian.org/debian-archive|g' /etc/apt/sources.list - - name: "Install deps (container)" if: runner.os == 'Linux' run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index c61a19b98..3f6c71e11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -83,6 +83,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `binary_to_integer` and `list_to_integer` do not raise anymore `overflow` error, they raise instead `badarg`. - Resources are now references instead of empty binaries. +- Removed support for OTP versions < 26 ### Fixed diff --git a/doc/release-notes.md.in b/doc/release-notes.md.in index 28336ebea..2aae39042 100644 --- a/doc/release-notes.md.in +++ b/doc/release-notes.md.in @@ -27,14 +27,13 @@ AtomVM will run BEAM files that have been compiled using the following Erlang an | Erlang Version | Elixir Version | |----------------|----------------| -| ✅ OTP 21 | ✅ 1.7 | -| ✅ OTP 22 | ✅ 1.8 | -| ✅ OTP 23 | ✅ 1.11 | -| ✅ OTP 24 | ✅ 1.14 | -| ✅ OTP 25 | ✅ 1.14 | -| ✅ OTP 26 | ✅ 1.15 | +| ✅ OTP 26 | ✅ 1.17 | +| ✅ OTP 26 | ✅ 1.18 | +| ✅ OTP 26 | ✅ 1.19 | | ✅ OTP 27 | ✅ 1.17 | -| ✅ OTP 28 | ✅ 1.17 | +| ✅ OTP 27 | ✅ 1.18 | +| ✅ OTP 27 | ✅ 1.19 | +| ✅ OTP 28 | ✅ 1.19 | ```{note} Versions of Elixir that are compatible with a particular OTP version may work. This table reflects the versions that are tested. diff --git a/doc/src/differences-with-beam.md b/doc/src/differences-with-beam.md index 952bb837c..687af7ee0 100644 --- a/doc/src/differences-with-beam.md +++ b/doc/src/differences-with-beam.md @@ -219,8 +219,8 @@ Ports are also executed by the schedulers and should return quickly. ### BEAM file compatibility -AtomVM can run BEAM files generated by `erlc` compiler from OTP21 to the latest master version, -while BEAM cannot and often requires to recompile. +AtomVM can run BEAM files generated by `erlc` compiler from the latest three releases, even in +cases where latest BEAM would require a recompile. ### Stacktraces and exceptions diff --git a/libs/CMakeLists.txt b/libs/CMakeLists.txt index 2f168baed..1ccaad0b2 100644 --- a/libs/CMakeLists.txt +++ b/libs/CMakeLists.txt @@ -27,10 +27,7 @@ add_subdirectory(alisp/src) add_subdirectory(etest/src) add_subdirectory(esp32boot) add_subdirectory(esp32devmode/src) -# JIT compiler doesn't compile with OTP < 23 -if(Erlang_VERSION VERSION_GREATER_EQUAL "23") - add_subdirectory(jit/src) -endif() +add_subdirectory(jit/src) set(ATOMVM_LIBS eavmlib estdlib alisp) @@ -84,9 +81,7 @@ if (Dialyzer_FOUND) ${CMAKE_CURRENT_BINARY_DIR}/eavmlib_beams.txt ${CMAKE_CURRENT_BINARY_DIR}/alisp_beams.txt ) - if(Erlang_VERSION VERSION_GREATER_EQUAL "23") - set(dialyzer_lists ${dialyzer_lists} ${CMAKE_CURRENT_BINARY_DIR}/jit_beams.txt) - endif() + set(dialyzer_lists ${dialyzer_lists} ${CMAKE_CURRENT_BINARY_DIR}/jit_beams.txt) add_custom_command( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/atomvmlib.plt DEPENDS ${dialyzer_lists} diff --git a/src/libAtomVM/opcodesswitch.h b/src/libAtomVM/opcodesswitch.h index 9cfc423c6..2a5010a31 100644 --- a/src/libAtomVM/opcodesswitch.h +++ b/src/libAtomVM/opcodesswitch.h @@ -49,8 +49,8 @@ // These constants can be used to reduce the size of the VM for a specific // range of compiler versions -#define MINIMUM_OTP_COMPILER_VERSION 21 -#define MAXIMUM_OTP_COMPILER_VERSION 26 +#define MINIMUM_OTP_COMPILER_VERSION 26 +#define MAXIMUM_OTP_COMPILER_VERSION 28 #ifdef __cplusplus extern "C" { @@ -2638,36 +2638,6 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) break; } -#if MINIMUM_OTP_COMPILER_VERSION <= 23 - case OP_ALLOCATE_HEAP_ZERO: { - uint32_t stack_need; - DECODE_LITERAL(stack_need, pc); - uint32_t heap_need; - DECODE_ALLOCATOR_LIST(heap_need, pc); - uint32_t live; - DECODE_LITERAL(live, pc); - TRACE("allocate_heap_zero/3 stack_need=%i, heap_need=%i, live=%i\n", stack_need, heap_need, live); - USED_BY_TRACE(stack_need); - USED_BY_TRACE(heap_need); - USED_BY_TRACE(live); - - #ifdef IMPL_EXECUTE_LOOP - if (ctx->heap.root->next || ((ctx->heap.heap_ptr + heap_need) > ctx->e - (stack_need + 1))) { - TRIM_LIVE_REGS(live); - if (UNLIKELY(memory_ensure_free_with_roots(ctx, heap_need + stack_need + 1, live, x_regs, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) { - RAISE_ERROR(OUT_OF_MEMORY_ATOM); - } - } - ctx->e -= stack_need + 1; - for (uint32_t s = 0; s < stack_need; s++) { - ctx->e[s] = term_nil(); - } - ctx->e[stack_need] = ctx->cp; - #endif - break; - } -#endif - case OP_TEST_HEAP: { uint32_t heap_need; DECODE_ALLOCATOR_LIST(heap_need, pc); @@ -3654,45 +3624,6 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) break; } -#if MINIMUM_OTP_COMPILER_VERSION <= 21 - case OP_PUT_TUPLE: { - uint32_t size; - DECODE_LITERAL(size, pc); - - #ifdef IMPL_EXECUTE_LOOP - term t = term_alloc_tuple(size, &ctx->heap); - #endif - - DEST_REGISTER(dreg); - DECODE_DEST_REGISTER(dreg, pc); - - TRACE("put_tuple/2 size=%u, dest=%c%i\n", (unsigned) size, T_DEST_REG(dreg)); - - #ifdef IMPL_EXECUTE_LOOP - WRITE_REGISTER(dreg, t); - #endif - - for (uint32_t j = 0; j < size; j++) { - if (*pc++ != OP_PUT) { - fprintf(stderr, "Expected put, got opcode: %i\n", pc[-1]); - AVM_ABORT(); - } - term put_value; - DECODE_COMPACT_TERM(put_value, pc); - #ifdef IMPL_CODE_LOADER - TRACE("put/2\n"); - UNUSED(put_value); - #endif - - #ifdef IMPL_EXECUTE_LOOP - TRACE("put/2 elem=%i, value=0x%" TERM_X_FMT "\n", j, put_value); - term_put_tuple_element(t, j, put_value); - #endif - } - break; - } -#endif - case OP_BADMATCH: { term arg1; DECODE_COMPACT_TERM(arg1, pc) @@ -4120,163 +4051,6 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) break; } -#if MINIMUM_OTP_COMPILER_VERSION <= 24 - case OP_BS_INIT2: { - uint32_t fail; - DECODE_LABEL(fail, pc) - term size; - DECODE_COMPACT_TERM(size, pc) - uint32_t words; - DECODE_LITERAL(words, pc) - uint32_t live; - DECODE_LITERAL(live, pc) - term flags; - UNUSED(flags); - DECODE_COMPACT_TERM(flags, pc) - - #ifdef IMPL_CODE_LOADER - TRACE("bs_init2/6\n"); - #endif - - #ifdef IMPL_EXECUTE_LOOP - VERIFY_IS_INTEGER(size, "bs_init2", 0); - avm_int_t size_val = term_to_int(size); - - TRIM_LIVE_REGS(live); - if (UNLIKELY(memory_ensure_free_with_roots(ctx, words + term_binary_heap_size(size_val), live, x_regs, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) { - RAISE_ERROR(OUT_OF_MEMORY_ATOM); - } - term t = term_create_empty_binary(size_val, &ctx->heap, ctx->global); - if (UNLIKELY(term_is_invalid_term(t))) { - RAISE_ERROR(OUT_OF_MEMORY_ATOM); - } - - ctx->bs = t; - ctx->bs_offset = 0; - #endif - - DEST_REGISTER(dreg); - DECODE_DEST_REGISTER(dreg, pc); - - #ifdef IMPL_EXECUTE_LOOP - TRACE("bs_init2/6, fail=%u size=" AVM_INT_FMT " words=%u live=%u dreg=%c%i\n", (unsigned) fail, size_val, (unsigned) words, (unsigned) live, T_DEST_REG(dreg)); - WRITE_REGISTER(dreg, t); - #endif - break; - } - - case OP_BS_INIT_BITS: { - uint32_t fail; - DECODE_LABEL(fail, pc) - term size; - DECODE_COMPACT_TERM(size, pc) - uint32_t words; - DECODE_LITERAL(words, pc) - uint32_t live; - DECODE_LITERAL(live, pc) - uint32_t flags_value; - DECODE_LITERAL(flags_value, pc) - - #ifdef IMPL_CODE_LOADER - TRACE("bs_init_bits/6\n"); - #endif - - #ifdef IMPL_EXECUTE_LOOP - VERIFY_IS_INTEGER(size, "bs_init_bits", 0); - avm_int_t size_val = term_to_int(size); - if (size_val % 8 != 0) { - TRACE("bs_init_bits: size_val (" AVM_INT_FMT ") is not evenly divisible by 8\n", size_val); - RAISE_ERROR(UNSUPPORTED_ATOM); - } - if (flags_value != 0) { - TRACE("bs_init_bits: neither signed nor native or little endian encoding supported.\n"); - RAISE_ERROR(UNSUPPORTED_ATOM); - } - - TRIM_LIVE_REGS(live); - if (UNLIKELY(memory_ensure_free_with_roots(ctx, words + term_binary_heap_size(size_val / 8), live, x_regs, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) { - RAISE_ERROR(OUT_OF_MEMORY_ATOM); - } - term t = term_create_empty_binary(size_val / 8, &ctx->heap, ctx->global); - if (UNLIKELY(term_is_invalid_term(t))) { - RAISE_ERROR(OUT_OF_MEMORY_ATOM); - } - - ctx->bs = t; - ctx->bs_offset = 0; - #endif - - DEST_REGISTER(dreg); - DECODE_DEST_REGISTER(dreg, pc); - - #ifdef IMPL_EXECUTE_LOOP - TRACE("bs_init_bits/6, fail=%i size=" AVM_INT_FMT " words=%i live=%u dreg=%c%i\n", fail, size_val, words, (unsigned) live, T_DEST_REG(dreg)); - WRITE_REGISTER(dreg, t); - #endif - break; - } - - case OP_BS_UTF8_SIZE: { - uint32_t fail; - DECODE_LABEL(fail, pc) - term src; - DECODE_COMPACT_TERM(src, pc) - DEST_REGISTER(dreg); - DECODE_DEST_REGISTER(dreg, pc); - #ifdef IMPL_CODE_LOADER - TRACE("bs_utf8_size/3\n"); - #endif - #ifdef IMPL_EXECUTE_LOOP - VERIFY_IS_INTEGER(src, "bs_utf8_size/3", 0); - avm_int_t src_value = term_to_int(src); - TRACE("bs_utf8_size/3 fail=%i src=0x%lx dreg=%c%i\n", fail, (long) src_value, T_DEST_REG(dreg)); - size_t utf8_size; - if (UNLIKELY(!bitstring_utf8_size(src_value, &utf8_size))) { - RAISE_ERROR(BADARG_ATOM); - } - WRITE_REGISTER(dreg, term_from_int(utf8_size)); - #endif - break; - } - - case OP_BS_PUT_UTF8: { - uint32_t fail; - DECODE_LABEL(fail, pc) - uint32_t flags; - DECODE_LITERAL(flags, pc) - term src; - DECODE_COMPACT_TERM(src, pc) - #ifdef IMPL_CODE_LOADER - TRACE("bs_put_utf8/3 flags=%x\n", (int) flags); - if (flags != 0) { - fprintf(stderr, "bs_put_utf8/3 : unsupported flags %x\n", (int) flags); - AVM_ABORT(); - } - #endif - #ifdef IMPL_EXECUTE_LOOP - VERIFY_IS_INTEGER(src, "bs_put_utf8/3", 0); - avm_int_t src_value = term_to_int(src); - TRACE("bs_put_utf8/3 flags=%x, src=0x%lx\n", (int) flags, (long) src_value); - if (UNLIKELY(!term_is_binary(ctx->bs))) { - TRACE("bs_put_utf8/3: Bad state. ctx->bs is not a binary.\n"); - RAISE_ERROR(BADARG_ATOM); - } - if (ctx->bs_offset % 8 != 0) { - TRACE("bs_put_utf8/3: Unsupported bit syntax operation. Writing strings must be byte-aligend.\n"); - RAISE_ERROR(UNSUPPORTED_ATOM); - } - size_t byte_size; - bool result = bitstring_insert_utf8(ctx->bs, ctx->bs_offset, src_value, &byte_size); - if (UNLIKELY(!result)) { - TRACE("bs_put_utf8/3: Failed to insert character as utf8 into binary: %i\n", result); - RAISE_ERROR(BADARG_ATOM); - } - ctx->bs_offset += byte_size * 8; - #endif - break; - } -#endif - case OP_BS_GET_UTF8: { uint32_t fail; DECODE_LABEL(fail, pc) @@ -4343,643 +4117,183 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) bool is_valid = bitstring_match_utf8(src_bin, (size_t) offset_bits, &c, &out_size); if (!is_valid) { - pc = mod->labels[fail]; - } else { - term_set_match_state_offset(src, offset_bits + (out_size * 8)); - } - #endif - - break; - } - -#if MINIMUM_OTP_COMPILER_VERSION <= 24 - case OP_BS_UTF16_SIZE: { - uint32_t fail; - DECODE_LABEL(fail, pc) - term src; - DECODE_COMPACT_TERM(src, pc) - DEST_REGISTER(dreg); - DECODE_DEST_REGISTER(dreg, pc); - #ifdef IMPL_CODE_LOADER - TRACE("bs_utf16_size/3\n"); - #endif - #ifdef IMPL_EXECUTE_LOOP - VERIFY_IS_INTEGER(src, "bs_utf16_size/3", 0); - avm_int_t src_value = term_to_int(src); - TRACE("bs_utf16_size/3 fail=%i src=0x%lx dreg=%c%i\n", fail, (long) src_value, T_DEST_REG(dreg)); - size_t utf16_size; - if (UNLIKELY(!bitstring_utf16_size(src_value, &utf16_size))) { - RAISE_ERROR(BADARG_ATOM); - } - WRITE_REGISTER(dreg, term_from_int(utf16_size)); - #endif - break; - } - - case OP_BS_PUT_UTF16: { - uint32_t fail; - DECODE_LABEL(fail, pc) - uint32_t flags; - DECODE_LITERAL(flags, pc) - term src; - DECODE_COMPACT_TERM(src, pc) - #ifdef IMPL_CODE_LOADER - TRACE("bs_put_utf16/3 flags=%x\n", (int) flags); - if (flags != 0 && flags != LittleEndianInteger && flags != NativeEndianInteger) { - fprintf(stderr, "bs_put_utf16/3 : unsupported flags %x\n", (int) flags); - AVM_ABORT(); - } - #endif - #ifdef IMPL_EXECUTE_LOOP - VERIFY_IS_INTEGER(src, "bs_put_utf16/3", 0); - avm_int_t src_value = term_to_int(src); - TRACE("bs_put_utf16/3 flags=%x, src=" AVM_INT_FMT "\n", (int) flags, src_value); - if (UNLIKELY(!term_is_binary(ctx->bs))) { - TRACE("bs_put_utf16: Bad state. ctx->bs is not a binary.\n"); - RAISE_ERROR(BADARG_ATOM); - } - if (ctx->bs_offset % 8 != 0) { - TRACE("bs_put_utf16: Unsupported bit syntax operation. Writing strings must be byte-aligend.\n"); - RAISE_ERROR(UNSUPPORTED_ATOM); - } - size_t byte_size; - bool result = bitstring_insert_utf16(ctx->bs, ctx->bs_offset, src_value, flags, &byte_size); - if (UNLIKELY(!result)) { - TRACE("bs_put_utf8/3: Failed to insert character as utf8 into binary: %i\n", result); - RAISE_ERROR(BADARG_ATOM); - } - ctx->bs_offset += byte_size * 8; - #endif - break; - } -#endif - - case OP_BS_GET_UTF16: { - uint32_t fail; - DECODE_LABEL(fail, pc) - term src; - DECODE_COMPACT_TERM(src, pc); - term arg2; - DECODE_COMPACT_TERM(arg2, pc); - uint32_t flags_value; - DECODE_LITERAL(flags_value, pc); - DEST_REGISTER(dreg); - DECODE_DEST_REGISTER(dreg, pc); - - #ifdef IMPL_CODE_LOADER - TRACE("bs_get_utf16/5\n"); - #endif - - #ifdef IMPL_EXECUTE_LOOP - TRACE("bs_get_utf16/5, fail=%i src=0x%" TERM_X_FMT " arg2=0x%" TERM_X_FMT " flags=0x%"PRIu32" dreg=%c%i\n", fail, src, arg2, flags_value, T_DEST_REG(dreg)); - - assert(term_is_match_state(src)); - - term src_bin = term_get_match_state_binary(src); - avm_int_t offset_bits = term_get_match_state_offset(src); - - int32_t val = 0; - size_t out_size = 0; - bool is_valid = bitstring_match_utf16(src_bin, (size_t) offset_bits, &val, &out_size, flags_value); - - if (!is_valid) { - pc = mod->labels[fail]; - } else { - term_set_match_state_offset(src, offset_bits + (out_size * 8)); - WRITE_REGISTER(dreg, term_from_int(val)); - } - #endif - - break; - } - - case OP_BS_SKIP_UTF16: { - uint32_t fail; - DECODE_LABEL(fail, pc) - term src; - DECODE_COMPACT_TERM(src, pc); - term arg2; - DECODE_COMPACT_TERM(arg2, pc); - term flags; - DECODE_LITERAL(flags, pc); - - #ifdef IMPL_CODE_LOADER - TRACE("bs_skip_utf16/5\n"); - #endif - - #ifdef IMPL_EXECUTE_LOOP - TRACE("bs_skip_utf16/5, fail=%i src=0x%" TERM_X_FMT " arg2=0x%" TERM_X_FMT " flags=0x%" TERM_X_FMT "\n", fail, src, arg2, flags); - - assert(term_is_match_state(src)); - - term src_bin = term_get_match_state_binary(src); - avm_int_t offset_bits = term_get_match_state_offset(src); - - int32_t val = 0; - size_t out_size = 0; - bool is_valid = bitstring_match_utf16(src_bin, (size_t) offset_bits, &val, &out_size, flags); - - if (!is_valid) { - pc = mod->labels[fail]; - } else { - term_set_match_state_offset(src, offset_bits + (out_size * 8)); - } - #endif - - break; - } - -#if MINIMUM_OTP_COMPILER_VERSION <= 24 - case OP_BS_PUT_UTF32: { - uint32_t fail; - DECODE_LABEL(fail, pc) - uint32_t flags; - DECODE_LITERAL(flags, pc) - term src; - DECODE_COMPACT_TERM(src, pc) - #ifdef IMPL_CODE_LOADER - TRACE("bs_put_utf32/3 flags=%x\n", (int) flags); - if (flags != 0 && flags != LittleEndianInteger && flags != NativeEndianInteger) { - fprintf(stderr, "bs_put_utf32/3 : unsupported flags %x\n", (int) flags); - AVM_ABORT(); - } - #endif - #ifdef IMPL_EXECUTE_LOOP - VERIFY_IS_INTEGER(src, "bs_put_utf32/3", 0); - avm_int_t src_value = term_to_int(src); - TRACE("bs_put_utf32/3 flags=%x, src=" AVM_INT_FMT "\n", (int) flags, src_value); - if (UNLIKELY(!term_is_binary(ctx->bs))) { - TRACE("bs_put_utf32/3: Bad state. ctx->bs is not a binary.\n"); - RAISE_ERROR(BADARG_ATOM); - } - if (ctx->bs_offset % 8 != 0) { - TRACE("bs_put_utf32/3: Unsupported bit syntax operation. Writing strings must be byte-aligend.\n"); - RAISE_ERROR(UNSUPPORTED_ATOM); - } - bool result = bitstring_insert_utf32(ctx->bs, ctx->bs_offset, src_value, flags); - if (UNLIKELY(!result)) { - TRACE("bs_put_utf32/3: Failed to insert integer into binary: %i\n", result); - RAISE_ERROR(BADARG_ATOM); - } - ctx->bs_offset += 4 * 8; - #endif - break; - } -#endif - - case OP_BS_GET_UTF32: { - uint32_t fail; - DECODE_LABEL(fail, pc) - term src; - DECODE_COMPACT_TERM(src, pc); - term arg2; - DECODE_COMPACT_TERM(arg2, pc); - uint32_t flags_value; - DECODE_LITERAL(flags_value, pc); - DEST_REGISTER(dreg); - DECODE_DEST_REGISTER(dreg, pc); - - #ifdef IMPL_CODE_LOADER - TRACE("bs_get_utf32/5\n"); - #endif - - #ifdef IMPL_EXECUTE_LOOP - TRACE("bs_get_utf32/5, fail=%i src=0x%" TERM_X_FMT " arg2=0x%" TERM_X_FMT " flags=0x%"PRIu32" dreg=%c%i\n", fail, src, arg2, flags_value, T_DEST_REG(dreg)); - - assert(term_is_match_state(src)); - - term src_bin = term_get_match_state_binary(src); - avm_int_t offset_bits = term_get_match_state_offset(src); - - int32_t val = 0; - bool is_valid = bitstring_match_utf32(src_bin, (size_t) offset_bits, &val, flags_value); - - if (!is_valid) { - pc = mod->labels[fail]; - } else { - term_set_match_state_offset(src, offset_bits + 32); - WRITE_REGISTER(dreg, term_from_int(val)); - } - #endif - - break; - } - - case OP_BS_SKIP_UTF32: { - uint32_t fail; - DECODE_LABEL(fail, pc) - term src; - DECODE_COMPACT_TERM(src, pc); - term arg2; - DECODE_COMPACT_TERM(arg2, pc); - term flags; - DECODE_LITERAL(flags, pc); - - #ifdef IMPL_CODE_LOADER - TRACE("bs_skip_utf32/5\n"); - #endif - - #ifdef IMPL_EXECUTE_LOOP - TRACE("bs_skip_utf32/5, fail=%i src=0x%" TERM_X_FMT " arg2=0x%" TERM_X_FMT " flags=0x%" TERM_X_FMT "\n", fail, src, arg2, flags); - - assert(term_is_match_state(src)); - - term src_bin = term_get_match_state_binary(src); - avm_int_t offset_bits = term_get_match_state_offset(src); - - int32_t val = 0; - bool is_valid = bitstring_match_utf32(src_bin, (size_t) offset_bits, &val, flags); - - if (!is_valid) { - pc = mod->labels[fail]; - } else { - term_set_match_state_offset(src, offset_bits + 32); - } - #endif - - break; - } - - case OP_BS_INIT_WRITABLE: { - - TRACE("bs_init_writable/0\n"); - - #ifdef IMPL_EXECUTE_LOOP - if (UNLIKELY(memory_ensure_free_opt(ctx, term_binary_heap_size(0), MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) { - RAISE_ERROR(OUT_OF_MEMORY_ATOM); - } - term t = term_create_empty_binary(0, &ctx->heap, ctx->global); - if (UNLIKELY(term_is_invalid_term(t))) { - RAISE_ERROR(OUT_OF_MEMORY_ATOM); - } - - ctx->bs = t; - ctx->bs_offset = 0; - x_regs[0] = t; - #endif - break; - } - -#if MINIMUM_OTP_COMPILER_VERSION <= 24 - case OP_BS_APPEND: { - uint32_t fail; - DECODE_LABEL(fail, pc) - term size; - DECODE_COMPACT_TERM(size, pc) - term extra; - UNUSED(extra); - DECODE_COMPACT_TERM(extra, pc) - uint32_t live; - UNUSED(live); - DECODE_LITERAL(live, pc); - uint32_t unit; - DECODE_LITERAL(unit, pc); - term src; - DECODE_COMPACT_TERM(src, pc) - term flags; - UNUSED(flags); - DECODE_COMPACT_TERM(flags, pc) - - #ifdef IMPL_CODE_LOADER - TRACE("bs_append/8\n"); - #endif - - #ifdef IMPL_EXECUTE_LOOP - VERIFY_IS_BINARY(src, "bs_append", 0); - VERIFY_IS_INTEGER(size, "bs_append", 0); - VERIFY_IS_INTEGER(extra, "bs_append", 0); - avm_int_t size_val = term_to_int(size); - avm_int_t extra_val = term_to_int(extra); - - if (size_val % 8 != 0) { - TRACE("bs_append: size_val (" AVM_INT_FMT ") is not evenly divisible by 8\n", size_val); - RAISE_ERROR(UNSUPPORTED_ATOM); - } - if (unit != 8) { - TRACE("bs_append: unit is not equal to 8; unit=%u\n", (unsigned) unit); - RAISE_ERROR(UNSUPPORTED_ATOM); - } - - size_t src_size = term_binary_size(src); - TRIM_LIVE_REGS(live); - // there is always room for a MAX_REG + 1 register, used as working register - x_regs[live] = src; - // TODO: further investigate extra_val - if (UNLIKELY(memory_ensure_free_with_roots(ctx, src_size + term_binary_heap_size(size_val / 8) + extra_val, live + 1, x_regs, MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) { - RAISE_ERROR(OUT_OF_MEMORY_ATOM); - } - #endif - - DEST_REGISTER(dreg); - DECODE_DEST_REGISTER(dreg, pc); - - #ifdef IMPL_EXECUTE_LOOP - TRACE("bs_append/8, fail=%u size=" AVM_INT_FMT " unit=%u src=0x%" TERM_X_FMT " dreg=%c%i\n", (unsigned) fail, size_val, (unsigned) unit, src, T_DEST_REG(dreg)); - src = x_regs[live]; - term t = term_create_empty_binary(src_size + size_val / 8, &ctx->heap, ctx->global); - if (UNLIKELY(term_is_invalid_term(t))) { - RAISE_ERROR(OUT_OF_MEMORY_ATOM); - } - memcpy((void *) term_binary_data(t), (void *) term_binary_data(src), src_size); - - ctx->bs = t; - ctx->bs_offset = src_size * 8; - - WRITE_REGISTER(dreg, t); - #endif - break; - } - - case OP_BS_PRIVATE_APPEND: { - uint32_t fail; - DECODE_LABEL(fail, pc) - term size; - DECODE_COMPACT_TERM(size, pc) - uint32_t unit; - DECODE_LITERAL(unit, pc); - term src; - #ifdef IMPL_EXECUTE_LOOP - const uint8_t *src_pc = pc; - #endif - DECODE_COMPACT_TERM(src, pc) - term flags; - UNUSED(flags); - DECODE_COMPACT_TERM(flags, pc) - - #ifdef IMPL_CODE_LOADER - TRACE("bs_private_append/6\n"); - #endif - - #ifdef IMPL_EXECUTE_LOOP - VERIFY_IS_BINARY(src, "bs_private_append", 0); - VERIFY_IS_INTEGER(size, "bs_private_append", 0); - avm_int_t size_val = term_to_int(size); - - if (size_val % 8 != 0) { - TRACE("bs_private_append: size_val (%li) is not evenly divisible by 8\n", (long int) size_val); - RAISE_ERROR(UNSUPPORTED_ATOM); - } - // TODO: further investigate unit. - // We currently do not support unaligned binaries, unit seems to be equal to 1 binary comprehensions - size_t src_size = term_binary_size(src); - if (UNLIKELY(memory_ensure_free_opt(ctx, src_size + term_binary_heap_size(size_val / 8), MEMORY_NO_GC) != MEMORY_GC_OK)) { - RAISE_ERROR(OUT_OF_MEMORY_ATOM); - } - DECODE_COMPACT_TERM(src, src_pc) - term t = term_reuse_binary(src, src_size + size_val / 8, &ctx->heap, ctx->global); - if (UNLIKELY(term_is_invalid_term(t))) { - RAISE_ERROR(OUT_OF_MEMORY_ATOM); - } - - ctx->bs = t; - ctx->bs_offset = src_size * 8; - #endif - - DEST_REGISTER(dreg); - DECODE_DEST_REGISTER(dreg, pc); - - #ifdef IMPL_EXECUTE_LOOP - TRACE("bs_private_append/6, fail=%u size=" AVM_INT_FMT " unit=%u src=0x%" TERM_X_FMT " dreg=%c%i\n", (unsigned) fail, size_val, (unsigned) unit, src, T_DEST_REG(dreg)); - WRITE_REGISTER(dreg, t); - #endif - break; - } - - case OP_BS_PUT_INTEGER: { - uint32_t fail; - DECODE_LABEL(fail, pc) - term size; - DECODE_COMPACT_TERM(size, pc) - uint32_t unit; - DECODE_LITERAL(unit, pc); - uint32_t flags_value; - DECODE_LITERAL(flags_value, pc) - term src; - DECODE_COMPACT_TERM(src, pc); - - #ifdef IMPL_CODE_LOADER - TRACE("bs_put_integer/5\n"); - #endif - - #ifdef IMPL_EXECUTE_LOOP - VERIFY_IS_ANY_INTEGER(src, "bs_put_integer", 0); - VERIFY_IS_INTEGER(size, "bs_put_integer", 0); - - avm_int64_t src_value = term_maybe_unbox_int64(src); - avm_int_t size_value = term_to_int(size); - - TRACE("bs_put_integer/5, fail=%u size=" AVM_INT_FMT " unit=%u flags=%x src=%i\n", (unsigned) fail, size_value, (unsigned) unit, (int) flags_value, (unsigned int) src_value); - - bool result = bitstring_insert_integer(ctx->bs, ctx->bs_offset, src_value, size_value * unit, flags_value); - if (UNLIKELY(!result)) { - TRACE("bs_put_integer: Failed to insert integer into binary\n"); - RAISE_ERROR(BADARG_ATOM); + pc = mod->labels[fail]; + } else { + term_set_match_state_offset(src, offset_bits + (out_size * 8)); } - - ctx->bs_offset += size_value * unit; #endif + break; } - case OP_BS_PUT_BINARY: { + case OP_BS_GET_UTF16: { uint32_t fail; DECODE_LABEL(fail, pc) - term size; - DECODE_COMPACT_TERM(size, pc) - uint32_t unit; - DECODE_LITERAL(unit, pc); - uint32_t flags_value; - DECODE_LITERAL(flags_value, pc) term src; DECODE_COMPACT_TERM(src, pc); + term arg2; + DECODE_COMPACT_TERM(arg2, pc); + uint32_t flags_value; + DECODE_LITERAL(flags_value, pc); + DEST_REGISTER(dreg); + DECODE_DEST_REGISTER(dreg, pc); #ifdef IMPL_CODE_LOADER - TRACE("bs_put_binary/5\n"); + TRACE("bs_get_utf16/5\n"); #endif #ifdef IMPL_EXECUTE_LOOP - VERIFY_IS_BINARY(src, "bs_put_binary", 0); - unsigned long size_val = 0; - if (term_is_integer(size)) { - avm_int_t bit_size = term_to_int(size) * unit; - if (bit_size % 8 != 0) { - TRACE("bs_put_binary: Bit size must be evenly divisible by 8.\n"); - RAISE_ERROR(UNSUPPORTED_ATOM); - } - size_val = bit_size / 8; - } else if (size == ALL_ATOM) { - size_val = term_binary_size(src); - } else { - TRACE("bs_put_binary: Unsupported size term type in put binary: %p\n", (void *) size); - RAISE_ERROR(BADARG_ATOM); - } - if (size_val > term_binary_size(src)) { - TRACE("bs_put_binary: binary data size (%li) larger than source binary size (%li)\n", size_val, term_binary_size(src)); - RAISE_ERROR(BADARG_ATOM); - } - if (flags_value != 0) { - TRACE("bs_put_binary: neither signed nor native or little endian encoding supported.\n"); - RAISE_ERROR(UNSUPPORTED_ATOM); - } + TRACE("bs_get_utf16/5, fail=%i src=0x%" TERM_X_FMT " arg2=0x%" TERM_X_FMT " flags=0x%"PRIu32" dreg=%c%i\n", fail, src, arg2, flags_value, T_DEST_REG(dreg)); - if (ctx->bs_offset % 8 != 0) { - TRACE("bs_put_binary: Unsupported bit syntax operation. Writing binaries must be byte-aligend.\n"); - RAISE_ERROR(UNSUPPORTED_ATOM); - } + assert(term_is_match_state(src)); - TRACE("bs_put_binary/5, fail=%u size=%li unit=%u flags=%x src=0x%x\n", (unsigned) fail, size_val, (unsigned) unit, (int) flags_value, (unsigned int) src); + term src_bin = term_get_match_state_binary(src); + avm_int_t offset_bits = term_get_match_state_offset(src); - int result = term_bs_insert_binary(ctx->bs, ctx->bs_offset, src, size_val); - if (UNLIKELY(result)) { - TRACE("bs_put_binary: Failed to insert binary into binary: %i\n", result); - RAISE_ERROR(BADARG_ATOM); + int32_t val = 0; + size_t out_size = 0; + bool is_valid = bitstring_match_utf16(src_bin, (size_t) offset_bits, &val, &out_size, flags_value); + + if (!is_valid) { + pc = mod->labels[fail]; + } else { + term_set_match_state_offset(src, offset_bits + (out_size * 8)); + WRITE_REGISTER(dreg, term_from_int(val)); } - ctx->bs_offset += 8 * size_val; #endif + break; } -#if MINIMUM_OTP_COMPILER_VERSION <= 24 - case OP_BS_PUT_FLOAT: { + case OP_BS_SKIP_UTF16: { uint32_t fail; DECODE_LABEL(fail, pc) - term size; - DECODE_COMPACT_TERM(size, pc) - uint32_t unit; - DECODE_LITERAL(unit, pc); - uint32_t flags_value; - DECODE_LITERAL(flags_value, pc) term src; DECODE_COMPACT_TERM(src, pc); + term arg2; + DECODE_COMPACT_TERM(arg2, pc); + term flags; + DECODE_LITERAL(flags, pc); #ifdef IMPL_CODE_LOADER - TRACE("bs_put_float/5\n"); + TRACE("bs_skip_utf16/5\n"); #endif #ifdef IMPL_EXECUTE_LOOP - avm_float_t float_value; - if (term_is_float(src)) { - float_value = term_to_float(src); - } else if (term_is_any_integer(src)) { - float_value = (avm_float_t) term_maybe_unbox_int64(src); - } else { - if (fail == 0) { - RAISE_ERROR(BADARG_ATOM); - } else { - JUMP_TO_LABEL(mod, fail); - } - } + TRACE("bs_skip_utf16/5, fail=%i src=0x%" TERM_X_FMT " arg2=0x%" TERM_X_FMT " flags=0x%" TERM_X_FMT "\n", fail, src, arg2, flags); - avm_int_t signed_size_value = 64; - if (size != term_nil()) { - VERIFY_IS_INTEGER(size, "bs_create_bin/6", fail); - signed_size_value = term_to_int(size); - if (UNLIKELY(signed_size_value != 16 && signed_size_value != 32 && signed_size_value != 64)) { - if (fail == 0) { - RAISE_ERROR(BADARG_ATOM); - } else { - JUMP_TO_LABEL(mod, fail); - } - } - } + assert(term_is_match_state(src)); - bool result; - if (signed_size_value == 16) { - result = bitstring_insert_f16(ctx->bs, ctx->bs_offset, float_value, flags_value); - } else if (signed_size_value == 32) { - result = bitstring_insert_f32(ctx->bs, ctx->bs_offset, float_value, flags_value); - } else { - result = bitstring_insert_f64(ctx->bs, ctx->bs_offset, float_value, flags_value); - } + term src_bin = term_get_match_state_binary(src); + avm_int_t offset_bits = term_get_match_state_offset(src); - if (UNLIKELY(!result)) { - TRACE("bs_put_float: Failed to insert float into binary\n"); - RAISE_ERROR(BADARG_ATOM); - } + int32_t val = 0; + size_t out_size = 0; + bool is_valid = bitstring_match_utf16(src_bin, (size_t) offset_bits, &val, &out_size, flags); - ctx->bs_offset += signed_size_value * unit; + if (!is_valid) { + pc = mod->labels[fail]; + } else { + term_set_match_state_offset(src, offset_bits + (out_size * 8)); + } #endif + break; } -#endif - case OP_BS_PUT_STRING: { - uint32_t size; - DECODE_LITERAL(size, pc); - uint32_t offset; - DECODE_LITERAL(offset, pc); + case OP_BS_GET_UTF32: { + uint32_t fail; + DECODE_LABEL(fail, pc) + term src; + DECODE_COMPACT_TERM(src, pc); + term arg2; + DECODE_COMPACT_TERM(arg2, pc); + uint32_t flags_value; + DECODE_LITERAL(flags_value, pc); + DEST_REGISTER(dreg); + DECODE_DEST_REGISTER(dreg, pc); #ifdef IMPL_CODE_LOADER - TRACE("bs_put_string/2\n"); + TRACE("bs_get_utf32/5\n"); #endif #ifdef IMPL_EXECUTE_LOOP - if (UNLIKELY(!term_is_binary(ctx->bs))) { - TRACE("bs_put_string: Bad state. ctx->bs is not a binary.\n"); - RAISE_ERROR(BADARG_ATOM); - } + TRACE("bs_get_utf32/5, fail=%i src=0x%" TERM_X_FMT " arg2=0x%" TERM_X_FMT " flags=0x%"PRIu32" dreg=%c%i\n", fail, src, arg2, flags_value, T_DEST_REG(dreg)); - TRACE("bs_put_string/2, size=%u offset=%u\n", size, offset); + assert(term_is_match_state(src)); - size_t remaining = 0; - const uint8_t *str = module_get_str(mod, offset, &remaining); - if (IS_NULL_PTR(str)) { - TRACE("bs_put_string: Bad offset in strings table.\n"); - RAISE_ERROR(BADARG_ATOM); - } + term src_bin = term_get_match_state_binary(src); + avm_int_t offset_bits = term_get_match_state_offset(src); + + int32_t val = 0; + bool is_valid = bitstring_match_utf32(src_bin, (size_t) offset_bits, &val, flags_value); - size_t size_in_bits = size * 8; - uint8_t *dst = (uint8_t *) term_binary_data(ctx->bs); - bitstring_copy_bits(dst, ctx->bs_offset, str, size_in_bits); - ctx->bs_offset += size_in_bits; + if (!is_valid) { + pc = mod->labels[fail]; + } else { + term_set_match_state_offset(src, offset_bits + 32); + WRITE_REGISTER(dreg, term_from_int(val)); + } #endif + break; } -#endif -#if MINIMUM_OTP_COMPILER_VERSION <= 21 - case OP_BS_START_MATCH2: { + case OP_BS_SKIP_UTF32: { uint32_t fail; DECODE_LABEL(fail, pc) term src; DECODE_COMPACT_TERM(src, pc); - uint32_t live; - DECODE_LITERAL(live, pc); - term slots_term; - DECODE_COMPACT_TERM(slots_term, pc); - GC_SAFE_DEST_REGISTER(dreg); - DECODE_DEST_REGISTER_GC_SAFE(dreg, pc); + term arg2; + DECODE_COMPACT_TERM(arg2, pc); + term flags; + DECODE_LITERAL(flags, pc); #ifdef IMPL_CODE_LOADER - TRACE("bs_start_match2/5\n"); + TRACE("bs_skip_utf32/5\n"); #endif #ifdef IMPL_EXECUTE_LOOP - TRACE("bs_start_match2/5, fail=%i src=0x%" TERM_X_FMT " live=%u arg3=0x%" TERM_X_FMT " dreg=%c%i\n", fail, src, (unsigned) live, slots_term, T_DEST_REG_GC_SAFE(dreg)); - if (!(term_is_binary(src) || term_is_match_state(src))) { - WRITE_REGISTER_GC_SAFE(dreg, src); + TRACE("bs_skip_utf32/5, fail=%i src=0x%" TERM_X_FMT " arg2=0x%" TERM_X_FMT " flags=0x%" TERM_X_FMT "\n", fail, src, arg2, flags); + + assert(term_is_match_state(src)); + + term src_bin = term_get_match_state_binary(src); + avm_int_t offset_bits = term_get_match_state_offset(src); + + int32_t val = 0; + bool is_valid = bitstring_match_utf32(src_bin, (size_t) offset_bits, &val, flags); + + if (!is_valid) { pc = mod->labels[fail]; } else { - int slots = term_to_int(slots_term); + term_set_match_state_offset(src, offset_bits + 32); + } + #endif - TRIM_LIVE_REGS(live); - // MEMORY_CAN_SHRINK because bs_start_match is classified as gc in beam_ssa_codegen.erl - x_regs[live] = src; - if (memory_ensure_free_with_roots(ctx, TERM_BOXED_BIN_MATCH_STATE_SIZE + slots, live + 1, x_regs, MEMORY_CAN_SHRINK) != MEMORY_GC_OK) { - RAISE_ERROR(OUT_OF_MEMORY_ATOM); - } - src = x_regs[live]; + break; + } - term match_state = term_alloc_bin_match_state(src, slots, &ctx->heap); + case OP_BS_INIT_WRITABLE: { - WRITE_REGISTER_GC_SAFE(dreg, match_state); + TRACE("bs_init_writable/0\n"); + + #ifdef IMPL_EXECUTE_LOOP + if (UNLIKELY(memory_ensure_free_opt(ctx, term_binary_heap_size(0), MEMORY_CAN_SHRINK) != MEMORY_GC_OK)) { + RAISE_ERROR(OUT_OF_MEMORY_ATOM); + } + term t = term_create_empty_binary(0, &ctx->heap, ctx->global); + if (UNLIKELY(term_is_invalid_term(t))) { + RAISE_ERROR(OUT_OF_MEMORY_ATOM); } + + ctx->bs = t; + ctx->bs_offset = 0; + x_regs[0] = t; #endif break; } -#endif -#if MAXIMUM_OTP_COMPILER_VERSION >= 22 case OP_BS_START_MATCH3: { uint32_t fail; DECODE_LABEL(fail, pc) @@ -5110,8 +4424,8 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) #endif break; } -#endif +#if MINIMUM_OTP_COMPILER_VERSION <= 27 case OP_BS_MATCH_STRING: { uint32_t fail; DECODE_LABEL(fail, pc) @@ -5193,64 +4507,6 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) #endif break; } - -#if MINIMUM_OTP_COMPILER_VERSION <= 21 - case OP_BS_SAVE2: { - term src; - DECODE_COMPACT_TERM(src, pc); - term index = 0; - DECODE_COMPACT_TERM(index, pc); - - #ifdef IMPL_CODE_LOADER - TRACE("bs_save2/2\n"); - #endif - - #ifdef IMPL_EXECUTE_LOOP - VERIFY_IS_MATCH_STATE(src, "bs_save2", 0); - - avm_int_t index_val; - if (index == START_ATOM) { - // TODO: not sure if 'start' is used anytime in generated code - term_match_state_save_start_offset(src); - } else if (term_is_integer(index)) { - index_val = term_to_int(index); - term_match_state_save_offset(src, index_val); - } else { - AVM_ABORT(); - } - - TRACE("bs_save2/2, src=0x%" TERM_X_FMT " pos=" AVM_INT_FMT "\n", src, index == START_ATOM ? -1 : index_val); - #endif - break; - } - - case OP_BS_RESTORE2: { - term src; - DECODE_COMPACT_TERM(src, pc); - term index = 0; - DECODE_COMPACT_TERM(index, pc); - - #ifdef IMPL_CODE_LOADER - TRACE("bs_restore2/5\n"); - #endif - - #ifdef IMPL_EXECUTE_LOOP - VERIFY_IS_MATCH_STATE(src, "bs_restore2", 0); - - avm_int_t index_val; - if (index == START_ATOM) { - term_match_state_restore_start_offset(src); - } else if (term_is_integer(index)) { - index_val = term_to_int(index); - term_match_state_restore_offset(src, index_val); - } else { - AVM_ABORT(); - } - - TRACE("bs_restore2/2, src=0x%" TERM_X_FMT " pos=" AVM_INT_FMT "\n", src, index == START_ATOM ? -1 : index_val); - #endif - break; - } #endif case OP_BS_SKIP_BITS2: { @@ -5291,33 +4547,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) break; } -#if MINIMUM_OTP_COMPILER_VERSION <= 24 - case OP_BS_TEST_UNIT: { - uint32_t fail; - DECODE_LABEL(fail, pc) - term src; - DECODE_COMPACT_TERM(src, pc); - uint32_t unit; - DECODE_LITERAL(unit, pc); - - #ifdef IMPL_CODE_LOADER - TRACE("bs_test_unit/3\n"); - #endif - - #ifdef IMPL_EXECUTE_LOOP - VERIFY_IS_MATCH_STATE(src, "bs_test_unit", 0); - - TRACE("bs_test_unit/3, fail=%u src=%p unit=%u\n", (unsigned) fail, (void *) src, (unsigned) unit); - - avm_int_t bs_offset = term_get_match_state_offset(src); - if ((term_binary_size(src) * 8 - bs_offset) % unit != 0) { - TRACE("bs_test_unit: Available bits in source not evenly divisible by unit\n"); - JUMP_TO_ADDRESS(mod->labels[fail]); - } - #endif - break; - } - +#if MINIMUM_OTP_COMPILER_VERSION <= 26 case OP_BS_TEST_TAIL2: { uint32_t fail; DECODE_LABEL(fail, pc) @@ -5980,28 +5210,6 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) break; } -#if MINIMUM_OTP_COMPILER_VERSION <= 23 - //it looks like it can be safely left unimplemented - case OP_RECV_MARK: { - uint32_t label; - DECODE_LABEL(label, pc); - - TRACE("recv_mark/1 label=%i\n", label); - USED_BY_TRACE(label); - break; - } - - //it looks like it can be safely left unimplemented - case OP_RECV_SET: { - uint32_t label; - DECODE_LABEL(label, pc); - - TRACE("recv_set/1 label=%i\n", label); - USED_BY_TRACE(label); - break; - } -#endif - case OP_LINE: { #ifdef IMPL_CODE_LOADER unsigned int offset = pc - code; @@ -6350,21 +5558,6 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) break; } -#if MINIMUM_OTP_COMPILER_VERSION <= 23 - case OP_FCLEARERROR: { - // This can be a noop as we raise from bifs - TRACE("fclearerror/0\n"); - break; - } - - case OP_FCHECKERROR: { - // This can be a noop as we raise from bifs - int fail_label; - DECODE_LABEL(fail_label, pc); - break; - } -#endif - case OP_FMOVE: { if (IS_EXTENDED_FP_REGISTER(pc)) { int freg; @@ -6705,7 +5898,6 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) break; } -#if MAXIMUM_OTP_COMPILER_VERSION >= 22 case OP_PUT_TUPLE2: { DEST_REGISTER(dreg); DECODE_DEST_REGISTER(dreg, pc); @@ -6738,9 +5930,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) #endif break; } -#endif -#if MAXIMUM_OTP_COMPILER_VERSION >= 23 case OP_SWAP: { DEST_REGISTER(reg_a); DECODE_DEST_REGISTER(reg_a, pc); @@ -6798,9 +5988,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) #endif break; } -#endif -#if MAXIMUM_OTP_COMPILER_VERSION >= 24 case OP_MAKE_FUN3: { uint32_t fun_index; DECODE_LITERAL(fun_index, pc); @@ -6882,9 +6070,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) TRACE("recv_marker_use/1: reg1=%c%i\n", T_DEST_REG(reg_a)); break; } -#endif -#if MAXIMUM_OTP_COMPILER_VERSION >= 25 case OP_BS_CREATE_BIN: { uint32_t fail; DECODE_LABEL(fail, pc); @@ -7329,9 +6515,7 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) break; } -#endif -#if MAXIMUM_OTP_COMPILER_VERSION >= 26 case OP_UPDATE_RECORD: { #ifdef IMPL_CODE_LOADER TRACE("update_record/5\n"); @@ -7659,7 +6843,6 @@ HOT_FUNC int scheduler_entry_point(GlobalContext *glb) JUMP_TO_ADDRESS(mod->labels[fail]); #endif } -#endif default: printf("Undecoded opcode: %i\n", pc[-1]); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index c7652f4b6..e274e4926 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -114,10 +114,7 @@ if (NOT "${CMAKE_GENERATOR}" MATCHES "Xcode") add_subdirectory(libs/estdlib) add_subdirectory(libs/eavmlib) add_subdirectory(libs/alisp) - # JIT compiler doesn't compile with OTP < 23 - if(Erlang_VERSION VERSION_GREATER_EQUAL "23") - add_subdirectory(libs/jit) - endif() + add_subdirectory(libs/jit) if (Elixir_FOUND) add_subdirectory(libs/exavmlib) else() diff --git a/tests/erlang_tests/CMakeLists.txt b/tests/erlang_tests/CMakeLists.txt index ed8f4ac8f..699a0ce64 100644 --- a/tests/erlang_tests/CMakeLists.txt +++ b/tests/erlang_tests/CMakeLists.txt @@ -620,22 +620,6 @@ compile_erlang(test_lists_member) compile_erlang(test_lists_keymember) compile_erlang(test_lists_keyfind) -if(Erlang_VERSION VERSION_GREATER_EQUAL "23") - set(OTP23_OR_GREATER_TESTS - test_op_bs_start_match_asm.beam - ) -else() - set(OTP23_OR_GREATER_TESTS) -endif() - -if(Erlang_VERSION VERSION_GREATER_EQUAL "25") - set(OTP25_OR_GREATER_TESTS - test_op_bs_create_bin_asm.beam - ) -else() - set(OTP25_OR_GREATER_TESTS) -endif() - set(erlang_test_beams add.beam fact.beam @@ -1150,8 +1134,8 @@ set(erlang_test_beams bigint.beam bigint_stress.beam - ${OTP23_OR_GREATER_TESTS} - ${OTP25_OR_GREATER_TESTS} + test_op_bs_start_match_asm.beam + test_op_bs_create_bin_asm.beam ) if(NOT AVM_DISABLE_JIT) diff --git a/tests/erlang_tests/maps_nifs.erl b/tests/erlang_tests/maps_nifs.erl index ca8104ea6..9d6d8052c 100644 --- a/tests/erlang_tests/maps_nifs.erl +++ b/tests/erlang_tests/maps_nifs.erl @@ -23,17 +23,10 @@ -export([start/0, fact/1, make_value/1, get_expected/1, get_list/1]). start() -> - test_maps_from_keys(get_otp_version()). - -get_otp_version() -> - case erlang:system_info(machine) of - "BEAM" -> list_to_integer(erlang:system_info(otp_release)); - _ -> atomvm - end. + ok = test_maps_from_keys(), + 0. -test_maps_from_keys(OTPVersion) when - (is_integer(OTPVersion) andalso OTPVersion >= 24) orelse OTPVersion == atomvm --> +test_maps_from_keys() -> M1 = #{1 => [], 5 => [], 6 => [], 8 => [], 9 => [], 24 => [], 43 => [], 100 => []}, M1 = maps:from_keys(?MODULE:get_list(1), []), @@ -52,10 +45,7 @@ test_maps_from_keys(OTPVersion) when 0 = map_size(M5), M5 = ?MODULE:get_expected(5), - 0; -test_maps_from_keys(OTPVersion) -> - % test skipped: maps:from_keys not supported on OTP < 24 - 0. + ok. fact(0) -> 1; diff --git a/tests/erlang_tests/test_binary_to_term.erl b/tests/erlang_tests/test_binary_to_term.erl index eb6129dc7..ee167a9eb 100644 --- a/tests/erlang_tests/test_binary_to_term.erl +++ b/tests/erlang_tests/test_binary_to_term.erl @@ -34,9 +34,8 @@ ]). start() -> - % Starting from OTP-26, atoms are encoded as UTF-8 by default. - test_reverse(foo, {<<131, 119, 3, 102, 111, 111>>, <<131, 100, 0, 3, 102, 111, 111>>}), - test_reverse(bar, {<<131, 119, 3, 98, 97, 114>>, <<131, 100, 0, 3, 98, 97, 114>>}), + test_reverse(foo, <<131, 119, 3, 102, 111, 111>>), + test_reverse(bar, <<131, 119, 3, 98, 97, 114>>), test_reverse( '∀x∃y.f(x,y)', <<131, 119, 15, 226, 136, 128, 120, 226, 136, 131, 121, 46, 102, 40, 120, 44, 121, 41>>, @@ -55,57 +54,32 @@ start() -> test_reverse(32768, <<131, 98, 0, 0, 128, 0>>), test_reverse(-32768, <<131, 98, 255, 255, 128, 0>>), test_reverse( - {foo, bar}, { - <<131, 104, 2, 119, 3, 102, 111, 111, 119, 3, 98, 97, 114>>, - <<131, 104, 2, 100, 0, 3, 102, 111, 111, 100, 0, 3, 98, 97, 114>> - } + {foo, bar}, <<131, 104, 2, 119, 3, 102, 111, 111, 119, 3, 98, 97, 114>> ), - test_reverse({foo, 0}, { - <<131, 104, 2, 119, 3, 102, 111, 111, 97, 0>>, - <<131, 104, 2, 100, 0, 3, 102, 111, 111, 97, 0>> - }), + test_reverse({foo, 0}, <<131, 104, 2, 119, 3, 102, 111, 111, 97, 0>>), test_reverse([], <<131, 106>>), test_reverse( - [{foo, 0}, {bar, 1}], { - <<131, 108, 0, 0, 0, 2, 104, 2, 119, 3, 102, 111, 111, 97, 0, 104, 2, 119, 3, 98, 97, - 114, 97, 1, 106>>, - <<131, 108, 0, 0, 0, 2, 104, 2, 100, 0, 3, 102, 111, 111, 97, 0, 104, 2, 100, 0, 3, 98, - 97, 114, 97, 1, 106>> - } + [{foo, 0}, {bar, 1}], + <<131, 108, 0, 0, 0, 2, 104, 2, 119, 3, 102, 111, 111, 97, 0, 104, 2, 119, 3, 98, 97, 114, + 97, 1, 106>> ), test_reverse( [improper | list], - { - <<131, 108, 0, 0, 0, 1, 119, 8, 105, 109, 112, 114, 111, 112, 101, 114, 119, 4, 108, - 105, 115, 116>>, - <<131, 108, 0, 0, 0, 1, 100, 0, 8, 105, 109, 112, 114, 111, 112, 101, 114, 100, 0, 4, - 108, 105, 115, 116>> - } + <<131, 108, 0, 0, 0, 1, 119, 8, 105, 109, 112, 114, 111, 112, 101, 114, 119, 4, 108, 105, + 115, 116>> ), - test_reverse({foo, bar}, { - <<131, 104, 2, 119, 3, 102, 111, 111, 119, 3, 98, 97, 114>>, - <<131, 104, 2, 100, 0, 3, 102, 111, 111, 100, 0, 3, 98, 97, 114>> - }), - test_reverse({foo, 0}, { - <<131, 104, 2, 119, 3, 102, 111, 111, 97, 0>>, - <<131, 104, 2, 100, 0, 3, 102, 111, 111, 97, 0>> - }), + test_reverse({foo, bar}, <<131, 104, 2, 119, 3, 102, 111, 111, 119, 3, 98, 97, 114>>), + test_reverse({foo, 0}, <<131, 104, 2, 119, 3, 102, 111, 111, 97, 0>>), test_reverse([], <<131, 106>>), test_reverse( - [{foo, 0}, {bar, 1}], { - <<131, 108, 0, 0, 0, 2, 104, 2, 119, 3, 102, 111, 111, 97, 0, 104, 2, 119, 3, 98, 97, - 114, 97, 1, 106>>, - <<131, 108, 0, 0, 0, 2, 104, 2, 100, 0, 3, 102, 111, 111, 97, 0, 104, 2, 100, 0, 3, 98, - 97, 114, 97, 1, 106>> - } + [{foo, 0}, {bar, 1}], + <<131, 108, 0, 0, 0, 2, 104, 2, 119, 3, 102, 111, 111, 97, 0, 104, 2, 119, 3, 98, 97, 114, + 97, 1, 106>> ), test_reverse( - [improper | list], { - <<131, 108, 0, 0, 0, 1, 119, 8, 105, 109, 112, 114, 111, 112, 101, 114, 119, 4, 108, - 105, 115, 116>>, - <<131, 108, 0, 0, 0, 1, 100, 0, 8, 105, 109, 112, 114, 111, 112, 101, 114, 100, 0, 4, - 108, 105, 115, 116>> - } + [improper | list], + <<131, 108, 0, 0, 0, 1, 119, 8, 105, 109, 112, 114, 111, 112, 101, 114, 119, 4, 108, 105, + 115, 116>> ), test_reverse(<<"foobar">>, <<131, 109, 0, 0, 0, 6, 102, 111, 111, 98, 97, 114>>), test_reverse(<<":アトムVM">>, <<131, 109, 0, 0, 0, 6, 58, 162, 200, 224, 54, 45>>), @@ -185,15 +159,6 @@ start() -> test_reverse(T, Interop) -> test_reverse(T, Interop, []). -test_reverse(T, {Utf8Interop, Latin1Interop}, Options) -> - case get_otp_version() of - X when is_integer(X) andalso X >= 26 -> - test_reverse(T, Utf8Interop, Options); - atomvm -> - test_reverse(T, Utf8Interop, Options); - _ -> - test_reverse(T, Latin1Interop, Options) - end; test_reverse(T, Interop, Options) when is_binary(Interop) andalso is_list(Options) -> Bin = case Options of @@ -272,7 +237,8 @@ test_external_function() -> T = T = [?MODULE:id(fun ?MODULE:apply/2), ?MODULE:id(fun ?MODULE:apply/3)], Bin = case get_otp_version() of - X when is_integer(X) andalso X >= 26 orelse X == atomvm -> + % OTP26+ and atomvm + X when X >= 26 -> %% expect SMALL_ATOM_UTF8_EXT encoding <<131, 108, 0, 0, 0, 2, 113, 119, 19, 116, 101, 115, 116, 95, 98, 105, 110, 97, 114, 121, 95, 116, 111, 95, 116, 101, 114, 109, 119, 5, 97, 112, 112, 108, 121, 97, @@ -489,21 +455,7 @@ test_encode_pid() -> hello -> ok after 500 -> error end, - {ExpectedSize, CreationOrder} = - case erlang:system_info(machine) of - "ATOM" -> - {29, true}; - "BEAM" -> - OTPRelease = erlang:system_info(otp_release), - if - OTPRelease =:= "21" -> {27, true}; - OTPRelease =:= "22" -> {27, false}; - OTPRelease < "26" -> {30, true}; - % small utf8 atom - true -> {29, true} - end - end, - ExpectedSize = byte_size(Bin), + 29 = byte_size(Bin), % Creation is not displayed in list representation FalsePid1 = binary_to_term_idempotent( @@ -516,7 +468,7 @@ test_encode_pid() -> ), "<0.1.0>" = pid_to_list(FalsePid1Cr), false = FalsePid1 =:= FalsePid1Cr, - CreationOrder = FalsePid1 < FalsePid1Cr, + true = FalsePid1 < FalsePid1Cr, % Order is done by pid on a given node FalsePid2 = binary_to_term_idempotent( @@ -601,47 +553,32 @@ test_encode_pid() -> error:badarg -> ok end, - case has_setnode_creation() of - true -> - % Test distributed pid - Ref42 = do_setnode(test@test_node, 42), - DistributedPid1 = binary_to_term( - <<131, 88, 119, 14, "test@test_node", 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 42>> - ), - true = is_pid(DistributedPid1), - true = is_process_alive(DistributedPid1), - - DistributedBin42 = term_to_binary(self()), - true = DistributedBin42 =/= Bin, - DistributedPid42 = binary_to_term(DistributedBin42), - true = DistributedPid42 =:= Pid, - ExpectedSize = byte_size(DistributedBin42) - 1, - - ok = do_unsetnode(Ref42), - Bin = term_to_binary(self()), - - Ref43 = do_setnode(test@test_node, 43), - DistributedBin43 = term_to_binary(self()), - true = DistributedBin43 =/= DistributedBin42, - DistributedPid43 = binary_to_term(DistributedBin43), - true = DistributedPid43 =:= Pid, - - ok = do_unsetnode(Ref43), - Bin = term_to_binary(self()), - ok; - false -> - ok - end, - ok. + % Test distributed pid + Ref42 = do_setnode(test@test_node, 42), + DistributedPid1 = binary_to_term( + <<131, 88, 119, 14, "test@test_node", 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 42>> + ), + true = is_pid(DistributedPid1), + true = is_process_alive(DistributedPid1), -has_setnode_creation() -> - case erlang:system_info(machine) of - "ATOM" -> - true; - "BEAM" -> - OTPRelease = erlang:system_info(otp_release), - OTPRelease >= "23" - end. + DistributedBin42 = term_to_binary(self()), + true = DistributedBin42 =/= Bin, + DistributedPid42 = binary_to_term(DistributedBin42), + true = DistributedPid42 =:= Pid, + 30 = byte_size(DistributedBin42), + + ok = do_unsetnode(Ref42), + Bin = term_to_binary(self()), + + Ref43 = do_setnode(test@test_node, 43), + DistributedBin43 = term_to_binary(self()), + true = DistributedBin43 =/= DistributedBin42, + DistributedPid43 = binary_to_term(DistributedBin43), + true = DistributedPid43 =:= Pid, + + ok = do_unsetnode(Ref43), + Bin = term_to_binary(self()), + ok. do_setnode(Node, Creation) -> {NetKernelPid, MonitorRef} = spawn_opt( @@ -680,102 +617,73 @@ test_encode_port() -> Bin = term_to_binary(TestPort), TestPort = binary_to_term(Bin), true = is_port(TestPort), - {ExpectedSize, SupportsV4PortEncoding} = - case erlang:system_info(machine) of - "ATOM" -> - % small utf8 atom - {29, true}; - "BEAM" -> - OTPRelease = erlang:system_info(otp_release), - if - OTPRelease < "23" -> {23, false}; - OTPRelease < "24" -> {26, false}; - % v4 is supported but not the default - OTPRelease < "26" -> {26, true}; - % small utf8 atom - true -> {29, true} - end - end, - ExpectedSize = byte_size(Bin), - case SupportsV4PortEncoding of - true -> - LocalPort1 = binary_to_term( - <<131, 120, 119, 13, "nonode@nohost", 1:64, 0:32>> - ), - true = is_port(LocalPort1), - "#Port<0.1>" = port_to_list(LocalPort1), - Port1 = binary_to_term(<<131, 120, 119, 4, "true", 43:64, 0:32>>), - Port2 = binary_to_term(<<131, 120, 119, 4, "true", 43:64, 1:32>>), - false = Port1 =:= Port2, - true = Port1 < Port2, - "#Port<1.43>" = port_to_list(Port1), - "#Port<1.43>" = port_to_list(Port2), - - % Order - FalsePort_42_43 = binary_to_term_idempotent( - <<131, 120, 119, 5, "false", 42:64, 43:32>>, "26" - ), - FalsePort_43_42 = binary_to_term_idempotent( - <<131, 120, 119, 5, "false", 43:64, 42:32>>, "26" - ), - FalsePort_43_43 = binary_to_term_idempotent( - <<131, 120, 119, 5, "false", 43:64, 43:32>>, "26" - ), - FalsfPort_42_41 = binary_to_term_idempotent( - <<131, 120, 119, 5, "falsf", 42:64, 41:32>>, "26" - ), - - % Node first, creation second, number third - true = FalsePort_42_43 > FalsePort_43_42, - true = FalsfPort_42_41 > FalsePort_42_43, - true = FalsfPort_42_41 > FalsePort_43_42, - true = FalsePort_43_42 < FalsePort_43_43, - - % Order is done by node atom, with local pid as nonode@nohost - true = - TestPort > - binary_to_term_idempotent(<<131, 120, 119, 5, "false", 1:64, 0:32>>, "26"), - true = - TestPort > - binary_to_term_idempotent(<<131, 120, 119, 6, "nonode", 1:64, 0:32>>, "26"), - true = - TestPort < - binary_to_term_idempotent(<<131, 120, 119, 6, "nonodf", 1:64, 0:32>>, "26"), + 29 = byte_size(Bin), + LocalPort1 = binary_to_term( + <<131, 120, 119, 13, "nonode@nohost", 1:64, 0:32>> + ), + true = is_port(LocalPort1), + "#Port<0.1>" = port_to_list(LocalPort1), + Port1 = binary_to_term(<<131, 120, 119, 4, "true", 43:64, 0:32>>), + Port2 = binary_to_term(<<131, 120, 119, 4, "true", 43:64, 1:32>>), + false = Port1 =:= Port2, + true = Port1 < Port2, + "#Port<1.43>" = port_to_list(Port1), + "#Port<1.43>" = port_to_list(Port2), - ok; - false -> - ok - end, - case has_setnode_creation() of - true -> - % Test distributed ports - % Test doesn't pass on BEAM if we use 42 and 43 like for refs, - % as there probably is a side-effect we don't have - Ref42 = do_setnode(test@test_node, 1042), - DistributedBin42 = term_to_binary(TestPort), - true = DistributedBin42 =/= Bin, - TestRef42 = binary_to_term(DistributedBin42), - true = TestRef42 =:= TestPort, - ExpectedSize = byte_size(DistributedBin42) - 1, - - ok = do_unsetnode(Ref42), - - Ref43 = do_setnode(test@test_node, 1043), - DistributedBin43 = term_to_binary(TestPort), - true = DistributedBin43 =/= DistributedBin42, - TestRef43 = binary_to_term(DistributedBin43), - true = TestRef43 =:= TestPort, - ExpectedSize = byte_size(DistributedBin43) - 1, - - % If our creation is 1043, encoded binary with creation 1042 is a different port - TestRef42_43 = binary_to_term(DistributedBin42), - false = TestRef42_43 =:= TestPort, - - ok = do_unsetnode(Ref43), - ok; - false -> - ok - end, + % Order + FalsePort_42_43 = binary_to_term_idempotent( + <<131, 120, 119, 5, "false", 42:64, 43:32>>, "26" + ), + FalsePort_43_42 = binary_to_term_idempotent( + <<131, 120, 119, 5, "false", 43:64, 42:32>>, "26" + ), + FalsePort_43_43 = binary_to_term_idempotent( + <<131, 120, 119, 5, "false", 43:64, 43:32>>, "26" + ), + FalsfPort_42_41 = binary_to_term_idempotent( + <<131, 120, 119, 5, "falsf", 42:64, 41:32>>, "26" + ), + + % Node first, creation second, number third + true = FalsePort_42_43 > FalsePort_43_42, + true = FalsfPort_42_41 > FalsePort_42_43, + true = FalsfPort_42_41 > FalsePort_43_42, + true = FalsePort_43_42 < FalsePort_43_43, + + % Order is done by node atom, with local pid as nonode@nohost + true = + TestPort > + binary_to_term_idempotent(<<131, 120, 119, 5, "false", 1:64, 0:32>>, "26"), + true = + TestPort > + binary_to_term_idempotent(<<131, 120, 119, 6, "nonode", 1:64, 0:32>>, "26"), + true = + TestPort < + binary_to_term_idempotent(<<131, 120, 119, 6, "nonodf", 1:64, 0:32>>, "26"), + % Test distributed ports + % Test doesn't pass on BEAM if we use 42 and 43 like for refs, + % as there probably is a side-effect we don't have + Ref42 = do_setnode(test@test_node, 1042), + DistributedBin42 = term_to_binary(TestPort), + true = DistributedBin42 =/= Bin, + TestRef42 = binary_to_term(DistributedBin42), + true = TestRef42 =:= TestPort, + ExpectedSize = byte_size(DistributedBin42) - 1, + + ok = do_unsetnode(Ref42), + + Ref43 = do_setnode(test@test_node, 1043), + DistributedBin43 = term_to_binary(TestPort), + true = DistributedBin43 =/= DistributedBin42, + TestRef43 = binary_to_term(DistributedBin43), + true = TestRef43 =:= TestPort, + ExpectedSize = byte_size(DistributedBin43) - 1, + + % If our creation is 1043, encoded binary with creation 1042 is a different port + TestRef42_43 = binary_to_term(DistributedBin42), + false = TestRef42_43 =:= TestPort, + + ok = do_unsetnode(Ref43), ok. test_encode_reference() -> @@ -787,20 +695,14 @@ test_encode_reference() -> <<131, 90, 0, 2, 119, 13, "nonode@nohost", 0:32, 1:32, 2:32>> ), true = is_reference(Ref123), - {ExpectedSize, HasV4NC} = + ExpectedSize = case erlang:system_info(machine) of "ATOM" -> % small utf8 atom & reference with 2 words - {31, true}; + 31; "BEAM" -> - OTPRelease = erlang:system_info(otp_release), - if - OTPRelease < "23" -> {33, false}; - OTPRelease < "24" -> {36, false}; - OTPRelease < "26" -> {36, true}; - % small utf8 atom - true -> {35, true} - end + % small utf8 atom + 35 end, ExpectedSize = byte_size(Bin), @@ -832,32 +734,27 @@ test_encode_reference() -> true = Ref6 > Ref3, % Starting from OTP-24 that introduced DFLAG_V4_NC, references can have 4 or 5 words - if - HasV4NC -> - Ref7 = binary_to_term_idempotent( - <<131, 90, 0, 4, 119, 4, "true", 1:32, 41:32, 42:32, 43:32, 44:32>>, "26" - ), - Ref8 = binary_to_term_idempotent( - <<131, 90, 0, 4, 119, 4, "true", 1:32, 44:32, 43:32, 42:32, 41:32>>, "26" - ), - "#Ref<1.44.43.42.41>" = ref_to_list(Ref7), - "#Ref<1.41.42.43.44>" = ref_to_list(Ref8), - true = Ref7 > Ref8, - true = Ref8 > Ref5, - - Ref9 = binary_to_term_idempotent( - <<131, 90, 0, 5, 119, 4, "true", 1:32, 40:32, 41:32, 42:32, 43:32, 44:32>>, "26" - ), - RefA = binary_to_term_idempotent( - <<131, 90, 0, 5, 119, 4, "true", 1:32, 44:32, 43:32, 42:32, 41:32, 40:32>>, "26" - ), - "#Ref<1.44.43.42.41.40>" = ref_to_list(Ref9), - "#Ref<1.40.41.42.43.44>" = ref_to_list(RefA), - true = Ref9 > RefA, - true = RefA > Ref7; - true -> - ok - end, + Ref7 = binary_to_term_idempotent( + <<131, 90, 0, 4, 119, 4, "true", 1:32, 41:32, 42:32, 43:32, 44:32>>, "26" + ), + Ref8 = binary_to_term_idempotent( + <<131, 90, 0, 4, 119, 4, "true", 1:32, 44:32, 43:32, 42:32, 41:32>>, "26" + ), + "#Ref<1.44.43.42.41>" = ref_to_list(Ref7), + "#Ref<1.41.42.43.44>" = ref_to_list(Ref8), + true = Ref7 > Ref8, + true = Ref8 > Ref5, + + Ref9 = binary_to_term_idempotent( + <<131, 90, 0, 5, 119, 4, "true", 1:32, 40:32, 41:32, 42:32, 43:32, 44:32>>, "26" + ), + RefA = binary_to_term_idempotent( + <<131, 90, 0, 5, 119, 4, "true", 1:32, 44:32, 43:32, 42:32, 41:32, 40:32>>, "26" + ), + "#Ref<1.44.43.42.41.40>" = ref_to_list(Ref9), + "#Ref<1.40.41.42.43.44>" = ref_to_list(RefA), + true = Ref9 > RefA, + true = RefA > Ref7, % Zero-length is tolerated RefB = binary_to_term_idempotent(<<131, 90, 0, 0, 119, 4, "true", 1:32>>, "26"), @@ -1020,47 +917,41 @@ test_encode_reference() -> error:badarg -> ok end, - case has_setnode_creation() of - true -> - % Test distributed pid - Ref42 = do_setnode(test@test_node, 42), - DistributedRef123_42 = binary_to_term( - <<131, 90, 0, 2, 119, 14, "test@test_node", 42:32, 1:32, 2:32>> - ), - true = is_reference(DistributedRef123_42), - true = DistributedRef123_42 =:= Ref123, - - DistributedBin42 = term_to_binary(TestRef), - true = DistributedBin42 =/= Bin, - TestRef42 = binary_to_term(DistributedBin42), - true = TestRef42 =:= TestRef, - ExpectedSize = byte_size(DistributedBin42) - 1, - - ok = do_unsetnode(Ref42), - - Ref43 = do_setnode(test@test_node, 43), - DistributedRef123_43 = binary_to_term( - <<131, 90, 0, 2, 119, 14, "test@test_node", 43:32, 1:32, 2:32>> - ), - true = is_reference(DistributedRef123_43), - true = DistributedRef123_43 =:= Ref123, - - DistributedRef123_42_43 = binary_to_term( - <<131, 90, 0, 2, 119, 14, "test@test_node", 42:32, 1:32, 2:32>> - ), - true = is_reference(DistributedRef123_42_43), - false = DistributedRef123_42_43 =:= Ref123, - - DistributedBin43 = term_to_binary(TestRef), - true = DistributedBin43 =/= Bin, - TestRef43 = binary_to_term(DistributedBin43), - true = TestRef43 =:= TestRef, - - ok = do_unsetnode(Ref43), - ok; - false -> - ok - end, + % Test distributed pid + Ref42 = do_setnode(test@test_node, 42), + DistributedRef123_42 = binary_to_term( + <<131, 90, 0, 2, 119, 14, "test@test_node", 42:32, 1:32, 2:32>> + ), + true = is_reference(DistributedRef123_42), + true = DistributedRef123_42 =:= Ref123, + + DistributedBin42 = term_to_binary(TestRef), + true = DistributedBin42 =/= Bin, + TestRef42 = binary_to_term(DistributedBin42), + true = TestRef42 =:= TestRef, + ExpectedSize = byte_size(DistributedBin42) - 1, + + ok = do_unsetnode(Ref42), + + Ref43 = do_setnode(test@test_node, 43), + DistributedRef123_43 = binary_to_term( + <<131, 90, 0, 2, 119, 14, "test@test_node", 43:32, 1:32, 2:32>> + ), + true = is_reference(DistributedRef123_43), + true = DistributedRef123_43 =:= Ref123, + + DistributedRef123_42_43 = binary_to_term( + <<131, 90, 0, 2, 119, 14, "test@test_node", 42:32, 1:32, 2:32>> + ), + true = is_reference(DistributedRef123_42_43), + false = DistributedRef123_42_43 =:= Ref123, + + DistributedBin43 = term_to_binary(TestRef), + true = DistributedBin43 =/= Bin, + TestRef43 = binary_to_term(DistributedBin43), + true = TestRef43 =:= TestRef, + + ok = do_unsetnode(Ref43), ok. test_encode_resource() -> @@ -1177,7 +1068,8 @@ compare_pair_encoding(Id) -> A = erlang:binary_to_term(erlang:term_to_binary(A)), OTPVersion = get_otp_version(), if - OTPVersion =:= atomvm orelse OTPVersion >= 26 -> + % OTP 26+ and atomvm + OTPVersion >= 26 -> B == erlang:term_to_binary(A); true -> true diff --git a/tests/erlang_tests/test_ets.erl b/tests/erlang_tests/test_ets.erl index 7909506dd..6eb962e29 100644 --- a/tests/erlang_tests/test_ets.erl +++ b/tests/erlang_tests/test_ets.erl @@ -58,10 +58,7 @@ test_ets_new() -> ets:new(heir_test, [{heir, none}]), ets:new(write_conc_test, [{write_concurrency, true}]), ets:new(read_conc_test, [{read_concurrency, true}]), - case otp_version() of - OTP when OTP >= 23 -> ets:new(decent_counters_test, [{decentralized_counters, true}]); - _ -> ok - end, + ets:new(decent_counters_test, [{decentralized_counters, true}]), ets:new(compressed_test, [compressed]), ok. @@ -131,10 +128,7 @@ test_keys() -> #{another => "map"} => erlang:make_ref(), <<1, 2, 3, 4>> => <<-4, -3, -2, -1>> }), - case supports_v4_port_encoding() of - true -> ok = assert_stored_key(T, binary_to_term(DistributedPortBin)); - false -> ok - end, + ok = assert_stored_key(T, binary_to_term(DistributedPortBin)), ok. test_keypos() -> @@ -299,23 +293,3 @@ assert_badarg(Fun) -> OtherClass:OtherError -> erlang:error({OtherClass, OtherError}) end. - -supports_v4_port_encoding() -> - case erlang:system_info(machine) of - "ATOM" -> - % small utf8 atom - true; - "BEAM" -> - OTP = otp_version(), - if - OTP < 24 -> false; - % v4 is supported but not the default - OTP < 26 -> true; - % small utf8 atom - true -> true - end - end. - -otp_version() -> - OTPRelease = erlang:system_info(otp_release), - list_to_integer(OTPRelease). diff --git a/tests/libs/eavmlib/test_ahttp_client.erl b/tests/libs/eavmlib/test_ahttp_client.erl index 7f8fb45dd..6ef1adb67 100644 --- a/tests/libs/eavmlib/test_ahttp_client.erl +++ b/tests/libs/eavmlib/test_ahttp_client.erl @@ -24,13 +24,9 @@ test() -> ok = test_passive(), ok = test_active(), - case get_otp_version() of - Version when Version =:= atomvm orelse (is_integer(Version) andalso Version >= 24) -> - ok = test_passive_socket(), - ok = test_active_socket(); - _ -> - ok - end. + ok = test_passive_socket(), + ok = test_active_socket(), + ok. test_passive() -> ok = ssl:start(), @@ -162,11 +158,3 @@ parse_responses( _Expected ) -> Resp#{done => true}. - -get_otp_version() -> - case erlang:system_info(machine) of - "BEAM" -> - list_to_integer(erlang:system_info(otp_release)); - _ -> - atomvm - end. diff --git a/tests/libs/estdlib/test_epmd.erl b/tests/libs/estdlib/test_epmd.erl index 4c99d7ef4..9b3fc59b7 100644 --- a/tests/libs/estdlib/test_epmd.erl +++ b/tests/libs/estdlib/test_epmd.erl @@ -25,35 +25,21 @@ -define(EPMD_PORT, 4369). test() -> - % AtomVM's epmd only runs on AtomVM and OTP 24+ - CanRunEpmd = - case erlang:system_info(machine) of - "ATOM" -> - true; - "BEAM" -> - OTPRelease = erlang:system_info(otp_release), - OTPRelease >= "24" - end, - if - CanRunEpmd -> - case stop_epmd() of - ok -> - {ok, Pid} = epmd:start_link([]), - ok = test_client(), - ok = test_two_clients(), - MonitorRef = monitor(process, Pid), - unlink(Pid), - exit(Pid, shutdown), - ok = - receive - {'DOWN', MonitorRef, process, Pid, shutdown} -> ok - after 5000 -> timeout - end, - ok; - {error, not_found} -> - ok - end; - true -> + case stop_epmd() of + ok -> + {ok, Pid} = epmd:start_link([]), + ok = test_client(), + ok = test_two_clients(), + MonitorRef = monitor(process, Pid), + unlink(Pid), + exit(Pid, shutdown), + ok = + receive + {'DOWN', MonitorRef, process, Pid, shutdown} -> ok + after 5000 -> timeout + end, + ok; + {error, not_found} -> ok end, case start_epmd() of @@ -177,28 +163,10 @@ stop_epmd() -> test_client() -> {ok, Pid1} = erl_epmd:start_link(), - ok = - case erl_epmd:port_please("test_epmd", "host.invalid") of - noport -> - ok; - {error, nxdomain} -> - "BEAM" = erlang:system_info(machine), - true = erlang:system_info(otp_release) =< "22", - ok - end, + noport = erl_epmd:port_please("test_epmd", "host.invalid"), noport = erl_epmd:port_please("test_epmd", "localhost"), {ok, Creation1} = erl_epmd:register_node("test_epmd", 12345), - {port, 12345, Version} = erl_epmd:port_please("test_epmd", "localhost"), - case erlang:system_info(machine) of - "BEAM" -> - case erlang:system_info(otp_release) of - "21" -> 5 = Version; - "22" -> 5 = Version; - _ -> 6 = Version - end; - "ATOM" -> - 6 = Version - end, + {port, 12345, 6} = erl_epmd:port_please("test_epmd", "localhost"), {error, already_registered} = erl_epmd:register_node("test_epmd", 12345), {error, already_registered} = erl_epmd:register_node("test_epmd_new", 12346), {ok, Names} = erl_epmd:names("localhost"), diff --git a/tests/libs/estdlib/test_gen_server.erl b/tests/libs/estdlib/test_gen_server.erl index 596525a37..df059b62f 100644 --- a/tests/libs/estdlib/test_gen_server.erl +++ b/tests/libs/estdlib/test_gen_server.erl @@ -94,23 +94,17 @@ test_start_link() -> ok. test_start_monitor() -> - case get_otp_version() of - %% Test on AtomVM and OTP 23 and later - Version when Version >= 23 -> - {ok, {Pid, Ref}} = gen_server:start_monitor(?MODULE, [], []), + {ok, {Pid, Ref}} = gen_server:start_monitor(?MODULE, [], []), - pong = gen_server:call(Pid, ping), - pong = gen_server:call(Pid, reply_ping), - ok = gen_server:cast(Pid, crash), - ok = - receive - {'DOWN', Ref, process, Pid, _Reason} -> ok - after 30000 -> timeout - end, - ok; - _ -> - ok - end. + pong = gen_server:call(Pid, ping), + pong = gen_server:call(Pid, reply_ping), + ok = gen_server:cast(Pid, crash), + ok = + receive + {'DOWN', Ref, process, Pid, _Reason} -> ok + after 30000 -> timeout + end, + ok. test_start_name() -> undefined = whereis(?MODULE), @@ -131,18 +125,12 @@ test_start_name() -> undefined = whereis(?MODULE), true = erlang:process_flag(trap_exit, PreviousTrapExit), - case get_otp_version() of - %% Test on AtomVM and OTP 23 and later - Version when Version >= 23 -> - {ok, {Pid3, MonitorRef}} = gen_server:start_monitor({local, ?MODULE}, ?MODULE, [], []), - Pid3 = whereis(?MODULE), - % Demonitor to avoid any DOWN message - true = demonitor(MonitorRef), - ok = gen_server:stop(Pid3), - undefined = whereis(?MODULE); - _ -> - ok - end, + {ok, {Pid3, MonitorRef}} = gen_server:start_monitor({local, ?MODULE}, ?MODULE, [], []), + Pid3 = whereis(?MODULE), + % Demonitor to avoid any DOWN message + true = demonitor(MonitorRef), + ok = gen_server:stop(Pid3), + undefined = whereis(?MODULE), ok. test_continue() -> diff --git a/tests/libs/estdlib/test_gen_tcp.erl b/tests/libs/estdlib/test_gen_tcp.erl index 767fcecdb..7a3ba5a00 100644 --- a/tests/libs/estdlib/test_gen_tcp.erl +++ b/tests/libs/estdlib/test_gen_tcp.erl @@ -125,13 +125,8 @@ loop(Socket, I) -> end. test_listen_connect_parameters() -> - case get_otp_version() of - Version when Version =:= atomvm orelse (is_integer(Version) andalso Version >= 24) -> - ok = test_listen_connect_parameters(socket, socket), - ok = test_listen_connect_parameters(inet, inet); - _ -> - ok = test_listen_connect_parameters(inet, inet) - end, + ok = test_listen_connect_parameters(socket, socket), + ok = test_listen_connect_parameters(inet, inet), ok. test_listen_connect_parameters(InetClientBackend, InetServerBackend) -> @@ -156,15 +151,8 @@ test_listen_connect_parameters( InetClientBackend, InetServerBackend, ListenMode, ConnectMode, ListenActive, ConnectActive ) -> etest:flush_msg_queue(), - - case get_otp_version() of - Version when Version =:= atomvm orelse (is_integer(Version) andalso Version >= 24) -> - ServerBackendOption = [{inet_backend, InetServerBackend}], - ClientBackendOption = [{inet_backend, InetClientBackend}]; - _ -> - ServerBackendOption = [], - ClientBackendOption = [] - end, + ServerBackendOption = [{inet_backend, InetServerBackend}], + ClientBackendOption = [{inet_backend, InetClientBackend}], io:format( "GEN_TCP-TEST> ServerBackendOption=~p ClientBackendOption=~p ListenMode=~p ConnectMode=~p ListenActive=~p ConnectActive=~p~n", @@ -364,21 +352,12 @@ test_connect_parameters() -> end, Hostname = "www.atomvm.org", Port = 80, - OptTests = - case get_otp_version() of - Version when Version =:= atomvm orelse (is_integer(Version) andalso Version >= 24) -> - [ - [{active, true}], - [{active, false}], - [{inet_backend, socket}, {active, true}], - [{inet_backend, socket}, {active, false}] - ]; - _ -> - [ - [{active, true}], - [{active, false}] - ] - end, + OptTests = [ + [{active, true}], + [{active, false}], + [{inet_backend, socket}, {active, true}], + [{inet_backend, socket}, {active, false}] + ], test_connect_parameters(OptTests, IP, Hostname, Port, []). test_connect_parameters([], _IP, _Host, _Port, Results) -> @@ -413,13 +392,7 @@ test_connect_parameters([Test | TestOpts], IP, Host, Port, Results) -> test_connect_bad_address() -> InetTest = test_connect_bad_address(inet_backend, []), - SocketTest = - case get_otp_version() of - Version when Version =:= atomvm orelse (is_integer(Version) andalso Version >= 24) -> - test_connect_bad_address(socket_backend, [{inet_backend, socket}]); - _ -> - ok - end, + SocketTest = test_connect_bad_address(socket_backend, [{inet_backend, socket}]), Result = [InetTest, SocketTest], case Result of [ok, ok] -> @@ -518,11 +491,3 @@ test_tcp_double_close() -> ok = gen_tcp:close(Socket), {error, closed} = gen_tcp:recv(Socket, 512, 5000), ok. - -get_otp_version() -> - case erlang:system_info(machine) of - "BEAM" -> - list_to_integer(erlang:system_info(otp_release)); - _ -> - atomvm - end. diff --git a/tests/libs/estdlib/test_gen_udp.erl b/tests/libs/estdlib/test_gen_udp.erl index e6e1bc515..83c237901 100644 --- a/tests/libs/estdlib/test_gen_udp.erl +++ b/tests/libs/estdlib/test_gen_udp.erl @@ -25,19 +25,12 @@ -include("etest.hrl"). test() -> - BackendOptions = - case get_otp_version() of - Version when Version =:= atomvm orelse (is_integer(Version) andalso Version >= 24) -> - [[{inet_backend, inet}], [{inet_backend, socket}]]; - _ -> - [[]] - end, [ ok = test_send_receive(SpawnControllingProcess, IsActive, Mode, BackendOption) || SpawnControllingProcess <- [false, true], IsActive <- [false, true], Mode <- [binary, list], - BackendOption <- BackendOptions + BackendOption <- [[{inet_backend, inet}], [{inet_backend, socket}]] ], ok. @@ -163,11 +156,3 @@ count_passive_received(Socket, Mode, I) -> erlang:display({count_passive_received, unexpected, Other}), count_passive_received(Socket, Mode, I) end. - -get_otp_version() -> - case erlang:system_info(machine) of - "BEAM" -> - list_to_integer(erlang:system_info(otp_release)); - _ -> - atomvm - end. diff --git a/tests/libs/estdlib/test_net_kernel.erl b/tests/libs/estdlib/test_net_kernel.erl index 2b96f2e78..4c95fb523 100644 --- a/tests/libs/estdlib/test_net_kernel.erl +++ b/tests/libs/estdlib/test_net_kernel.erl @@ -27,44 +27,27 @@ start() -> test() -> Platform = erlang:system_info(machine), - case has_compatible_erl(Platform) andalso has_epmd(Platform) of + case has_command(Platform, "erl") andalso has_epmd(Platform) of true -> ok = ensure_epmd(Platform), ok = test_ping_from_beam(Platform), ok = test_fail_with_wrong_cookie(Platform), ok = test_rpc_from_beam(Platform), ok = test_rpc_loop_from_beam(Platform), - ok = test_autoconnect_fail(Platform), + ok = test_autoconnect_fail(), ok = test_autoconnect_to_beam(Platform), ok = test_groupleader(Platform), ok = test_link_remote_exit_remote(Platform), ok = test_link_remote_exit_local(Platform), ok = test_link_local_unlink_remote(Platform), ok = test_link_local_unlink_local(Platform), - ok = test_is_alive(Platform), + ok = test_is_alive(), ok; false -> io:format("~s: skipped\n", [?MODULE]), ok end. -%% Determine if we can connect with BEAM. -%% This test currently supports AtomVM connecting with OTP 24+ -%% as well as any version of OTP connecting with OTP -has_compatible_erl("BEAM" = Platform) -> - has_command(Platform, "erl"); -has_compatible_erl("ATOM") -> - case has_command("ATOM", "erl") of - true -> - Result = execute_command( - "ATOM", - "erl -eval \"io:put_chars(erlang:system_info(otp_release) ++ [13,10]).\" -s init stop -noshell" - ), - Result >= "24"; - false -> - false - end. - has_epmd(Platform) -> has_command(Platform, "epmd"). @@ -92,10 +75,9 @@ ensure_epmd("ATOM") -> ok. test_ping_from_beam(Platform) -> - {ok, _NetKernelPid} = net_kernel_start(Platform, atomvm), + {ok, _NetKernelPid} = net_kernel:start(atomvm, #{name_domain => shortnames}), Node = node(), - % erlang:set_cookie/1 is from OTP 24.1 - erlang:set_cookie(Node, 'AtomVM'), + erlang:set_cookie('AtomVM'), Result = execute_command( Platform, "erl -sname otp -setcookie AtomVM -eval \"R = net_adm:ping('" ++ @@ -107,9 +89,9 @@ test_ping_from_beam(Platform) -> ok. test_fail_with_wrong_cookie(Platform) -> - {ok, _NetKernelPid} = net_kernel_start(Platform, atomvm), + {ok, _NetKernelPid} = net_kernel:start(atomvm, #{name_domain => shortnames}), Node = node(), - erlang:set_cookie(Node, 'AtomVM'), + erlang:set_cookie('AtomVM'), Result = execute_command( Platform, "erl -sname otp -setcookie Wrong -eval \"R = net_adm:ping('" ++ @@ -121,9 +103,9 @@ test_fail_with_wrong_cookie(Platform) -> ok. test_rpc_from_beam(Platform) -> - {ok, _NetKernelPid} = net_kernel_start(Platform, atomvm), + {ok, _NetKernelPid} = net_kernel:start(atomvm, #{name_domain => shortnames}), Node = node(), - erlang:set_cookie(Node, 'AtomVM'), + erlang:set_cookie('AtomVM'), Result = execute_command( Platform, "erl -sname otp -setcookie AtomVM -eval \"R = rpc:call('" ++ atom_to_list(Node) ++ @@ -134,9 +116,9 @@ test_rpc_from_beam(Platform) -> ok. test_rpc_loop_from_beam(Platform) -> - {ok, _NetKernelPid} = net_kernel_start(Platform, atomvm), + {ok, _NetKernelPid} = net_kernel:start(atomvm, #{name_domain => shortnames}), Node = node(), - erlang:set_cookie(Node, 'AtomVM'), + erlang:set_cookie('AtomVM'), Result = execute_command( Platform, "erl -sname otp -setcookie AtomVM -eval \"R = lists:foldl(fun(X, Acc) -> R = rpc:call('" ++ @@ -147,10 +129,10 @@ test_rpc_loop_from_beam(Platform) -> net_kernel:stop(), ok. -test_autoconnect_fail(Platform) -> - {ok, _NetKernelPid} = net_kernel_start(Platform, atomvm), +test_autoconnect_fail() -> + {ok, _NetKernelPid} = net_kernel:start(atomvm, #{name_domain => shortnames}), Node = node(), - erlang:set_cookie(Node, 'AtomVM'), + erlang:set_cookie('AtomVM'), [_, Host] = string:split(atom_to_list(Node), "@"), OTPNode = list_to_atom("otp@" ++ Host), {beam, OTPNode} ! {self(), ping}, @@ -158,10 +140,10 @@ test_autoconnect_fail(Platform) -> ok. test_autoconnect_to_beam(Platform) -> - {ok, _NetKernelPid} = net_kernel_start(Platform, atomvm), + {ok, _NetKernelPid} = net_kernel:start(atomvm, #{name_domain => shortnames}), Node = node(), Parent = self(), - erlang:set_cookie(Node, 'AtomVM'), + erlang:set_cookie('AtomVM'), {Pid, MonitorRef} = spawn_opt( fun() -> Command = @@ -234,9 +216,9 @@ test_autoconnect_to_beam(Platform) -> ok. start_apply_loop(Platform) -> - {ok, _NetKernelPid} = net_kernel_start(Platform, atomvm), + {ok, _NetKernelPid} = net_kernel:start(atomvm, #{name_domain => shortnames}), Node = node(), - erlang:set_cookie(Node, 'AtomVM'), + erlang:set_cookie('AtomVM'), register(atomvm, self()), Parent = self(), {Pid, MonitorRef} = spawn_opt( @@ -467,9 +449,9 @@ test_link_local_unlink_local(Platform) -> ok = stop_apply_loop(BeamMainPid, Pid, MonitorRef), ok. -test_is_alive(Platform) -> +test_is_alive() -> false = is_alive(), - {ok, _NetKernelPid} = net_kernel_start(Platform, atomvm), + {ok, _NetKernelPid} = net_kernel:start(atomvm, #{name_domain => shortnames}), true = is_alive(), net_kernel:stop(), false = is_alive(), @@ -523,14 +505,3 @@ beam_loop_read(Port, Acc) -> after 5000 -> exit(timeout) end. - -net_kernel_start("ATOM", Nodename) -> - net_kernel:start(Nodename, #{name_domain => shortnames}); -net_kernel_start("BEAM", Nodename) -> - OTPRelease = erlang:system_info(otp_release), - if - OTPRelease >= "24" -> - net_kernel:start(Nodename, #{name_domain => shortnames}); - true -> - net_kernel:start([Nodename, shortnames]) - end. diff --git a/tests/libs/estdlib/test_proc_lib.erl b/tests/libs/estdlib/test_proc_lib.erl index 2c783d196..c905c0c7c 100644 --- a/tests/libs/estdlib/test_proc_lib.erl +++ b/tests/libs/estdlib/test_proc_lib.erl @@ -28,12 +28,7 @@ test() -> ok = test_start_monitor_badarg(), ok = test_start_link_sync(), ok = test_start_link_opt_sync(), - case get_otp_version() of - Version when Version >= 23 -> - ok = test_start_monitor_sync(); - _ -> - ok - end, + ok = test_start_monitor_sync(), ok = test_start_timeout(), ok = test_start_crash(), ok = test_initial_call_and_ancestors(), @@ -268,11 +263,3 @@ init_crash({Class, Reason, Stacktrace}) -> init_initial_call_ancestors(Parent) -> proc_lib:init_ack(Parent, {ok, get('$initial_call'), get('$ancestors')}). - -get_otp_version() -> - case erlang:system_info(machine) of - "BEAM" -> - list_to_integer(erlang:system_info(otp_release)); - _ -> - atomvm - end. diff --git a/tests/libs/estdlib/test_queue.erl b/tests/libs/estdlib/test_queue.erl index 569aa9320..0b5de7068 100644 --- a/tests/libs/estdlib/test_queue.erl +++ b/tests/libs/estdlib/test_queue.erl @@ -48,23 +48,17 @@ test() -> ok = test_split(), ok = test_filter(), ok = test_filter_replace(), - ok = test_filtermap(get_otp_version()), - ok = test_filtermap_replace(get_otp_version()), - ok = test_fold(get_otp_version()), - ok = test_any(get_otp_version()), - ok = test_all(get_otp_version()), - ok = test_delete(get_otp_version()), - ok = test_delete_with(get_otp_version()), - ok = test_delete_with_r(get_otp_version()), + ok = test_filtermap(), + ok = test_filtermap_replace(), + ok = test_fold(), + ok = test_any(), + ok = test_all(), + ok = test_delete(), + ok = test_delete_with(), + ok = test_delete_with_r(), ok = test_complete_flow(), ok. -get_otp_version() -> - case erlang:system_info(machine) of - "BEAM" -> list_to_integer(erlang:system_info(otp_release)); - _ -> atomvm - end. - test_from_to_list() -> L = [1, -1, 2, -3], Q = queue:from_list(L), @@ -234,83 +228,51 @@ test_filter_replace() -> ?ASSERT_MATCH(queue:to_list(Q1), [1, 2, 2, 3, 3, 4, 4, 5, 5, 6]), ok. -test_filtermap(OTPVersion) when - (is_integer(OTPVersion) andalso OTPVersion >= 24) orelse OTPVersion == atomvm --> +test_filtermap() -> Q = queue:from_list([1, 2, 3, 4, 5]), Q1 = queue:filtermap(fun(E) -> E > 2 end, Q), ?ASSERT_MATCH(queue:to_list(Q1), [3, 4, 5]), - ok; -test_filtermap(_) -> ok. -test_filtermap_replace(OTPVersion) when - (is_integer(OTPVersion) andalso OTPVersion >= 24) orelse OTPVersion == atomvm --> +test_filtermap_replace() -> Q = queue:from_list([1, 2, 3, 4, 5]), Q1 = queue:filtermap(fun(E) -> {true, E + 100} end, Q), ?ASSERT_MATCH(queue:to_list(Q1), [101, 102, 103, 104, 105]), - ok; -test_filtermap_replace(_) -> ok. -test_fold(OTPVersion) when - (is_integer(OTPVersion) andalso OTPVersion >= 24) orelse OTPVersion == atomvm --> +test_fold() -> Q = queue:from_list([1, 2, 3, 4, 5]), ?ASSERT_MATCH(queue:fold(fun(X, Sum) -> X + Sum end, 0, Q), 15), - ok; -test_fold(_) -> ok. -test_any(OTPVersion) when - (is_integer(OTPVersion) andalso OTPVersion >= 24) orelse OTPVersion == atomvm --> +test_any() -> Q = queue:from_list([1, 2, 3, 4, 5]), ?ASSERT_MATCH(queue:any(fun(E) -> E > 10 end, Q), false), ?ASSERT_MATCH(queue:any(fun(E) -> E > 3 end, Q), true), - ok; -test_any(_) -> ok. -test_all(OTPVersion) when - (is_integer(OTPVersion) andalso OTPVersion >= 24) orelse OTPVersion == atomvm --> +test_all() -> Q = queue:from_list([1, 2, 3, 4, 5]), ?ASSERT_MATCH(queue:all(fun(E) -> E > 3 end, Q), false), ?ASSERT_MATCH(queue:all(fun(E) -> E > 0 end, Q), true), - ok; -test_all(_) -> ok. -test_delete(OTPVersion) when - (is_integer(OTPVersion) andalso OTPVersion >= 24) orelse OTPVersion == atomvm --> +test_delete() -> Q = queue:from_list([1, 2, 3, 4, 5]), Q1 = queue:delete(3, Q), ?ASSERT_MATCH(queue:member(3, Q1), false), - ok; -test_delete(_) -> ok. -test_delete_with(OTPVersion) when - (is_integer(OTPVersion) andalso OTPVersion >= 24) orelse OTPVersion == atomvm --> +test_delete_with() -> Q = queue:from_list([100, 1, 2, 3, 4, 5]), Q1 = queue:delete_with(fun(E) -> E > 0 end, Q), ?ASSERT_MATCH(queue:to_list(Q1), [1, 2, 3, 4, 5]), - ok; -test_delete_with(_) -> ok. -test_delete_with_r(OTPVersion) when - (is_integer(OTPVersion) andalso OTPVersion >= 24) orelse OTPVersion == atomvm --> +test_delete_with_r() -> Q = queue:from_list([1, 2, 3, 4, 5, 100]), Q1 = queue:delete_with_r(fun(E) -> E > 10 end, Q), ?ASSERT_MATCH(queue:to_list(Q1), [1, 2, 3, 4, 5]), - ok; -test_delete_with_r(_) -> ok. test_complete_flow() -> diff --git a/tests/libs/estdlib/test_tcp_socket.erl b/tests/libs/estdlib/test_tcp_socket.erl index f38758c91..f6f888e70 100644 --- a/tests/libs/estdlib/test_tcp_socket.erl +++ b/tests/libs/estdlib/test_tcp_socket.erl @@ -31,10 +31,10 @@ test() -> ok = test_recv_nowait(), ok = test_accept_nowait(), ok = test_setopt_getopt(), - case get_otp_version() of - atomvm -> + case erlang:system_info(machine) of + "ATOM" -> ok = test_abandon_select(); - _ -> + "BEAM" -> ok end, ok. @@ -232,7 +232,7 @@ echo(Pid, Socket) -> {error, closed} -> Pid ! recv_terminated, ok; - %% OTP-24 + %% OTP returns this in some (random) cases {error, econnreset} -> Pid ! recv_terminated, ok; @@ -464,18 +464,11 @@ test_recv_nowait(ReceiveFun) -> ok = close_listen_socket(ListenSocket). test_accept_nowait() -> - OTPVersion = get_otp_version(), - ok = test_accept_nowait(nowait, OTPVersion), - ok = test_accept_nowait(make_ref(), OTPVersion), + ok = test_accept_nowait(nowait), + ok = test_accept_nowait(make_ref()), ok. -% actually since 22.1, but let's simplify here. -test_accept_nowait(_NoWaitRef, Version) when Version =/= atomvm andalso Version < 23 -> ok; -test_accept_nowait(Ref, Version) when - is_reference(Ref) andalso Version =/= atomvm andalso Version < 24 --> - ok; -test_accept_nowait(NoWaitRef, _Version) -> +test_accept_nowait(NoWaitRef) -> etest:flush_msg_queue(), {ok, Socket} = socket:open(inet, stream, tcp), @@ -573,13 +566,5 @@ test_abandon_select() -> erlang:garbage_collect(), ok. -get_otp_version() -> - case erlang:system_info(machine) of - "BEAM" -> - list_to_integer(erlang:system_info(otp_release)); - _ -> - atomvm - end. - id(X) -> X. diff --git a/tests/libs/estdlib/tests.erl b/tests/libs/estdlib/tests.erl index 566b9843d..53b73b663 100644 --- a/tests/libs/estdlib/tests.erl +++ b/tests/libs/estdlib/tests.erl @@ -41,7 +41,7 @@ start() -> end, NetworkingTests = if - Networking -> get_networking_tests(OTPVersion); + Networking -> get_networking_tests(); true -> [] end, ok = etest:test(NonNetworkingTests ++ NetworkingTests). @@ -55,18 +55,12 @@ get_otp_version() -> end. % test_sets heavily relies on is_equal that is from OTP-27 -get_non_networking_tests(OTPVersion) when - (is_integer(OTPVersion) andalso OTPVersion >= 27) orelse OTPVersion =:= atomvm --> - [test_sets | get_non_networking_tests(undefined)]; -% test_binary uses encode_hex/1 (OTP-24), encode_hex/2 (OTP-26) -get_non_networking_tests(OTPVersion) when - (is_integer(OTPVersion) andalso OTPVersion >= 26) orelse OTPVersion =:= atomvm --> - [test_binary | get_non_networking_tests(undefined)]; +get_non_networking_tests(OTPVersion) when OTPVersion >= 27 -> + [test_sets | get_non_networking_tests(26)]; get_non_networking_tests(_OTPVersion) -> [ test_apply, + test_binary, test_lists, test_calendar, test_gen_event, @@ -86,16 +80,15 @@ get_non_networking_tests(_OTPVersion) -> test_file ]. -get_networking_tests(OTPVersion) when - (is_integer(OTPVersion) andalso OTPVersion >= 24) orelse OTPVersion =:= atomvm --> +get_networking_tests() -> [ test_tcp_socket, test_udp_socket, test_epmd, test_net, - test_ssl - | get_networking_tests(undefined) - ]; -get_networking_tests(_OTPVersion) -> - [test_gen_udp, test_gen_tcp, test_inet, test_net_kernel]. + test_ssl, + test_gen_udp, + test_gen_tcp, + test_inet, + test_net_kernel + ].