Compare commits

..

1 commit

Author SHA1 Message Date
Saúl Ibarra Corretgé
4e186c538b
TEST 2023-12-07 10:54:48 +01:00
48 changed files with 5373 additions and 16042 deletions

View file

@ -15,15 +15,6 @@ on:
- master
jobs:
codegen:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: build
run: |
make codegen
- name: Check if the git repository is clean
run: $(exit $(git status --porcelain --untracked-files=no | head -255 | wc -l)) || (echo "Dirty git tree"; git diff; exit 1)
linux:
runs-on: ubuntu-latest
strategy:
@ -31,7 +22,7 @@ jobs:
matrix:
buildType: [Debug, Release]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
with:
submodules: true
- name: build
@ -47,17 +38,13 @@ jobs:
if: ${{ matrix.buildType == 'Release' }}
run: |
time make test262
- name: test v8 mjsunit
if: ${{ matrix.buildType == 'Release' }}
run: |
./v8.sh
linux-32bits:
runs-on: ubuntu-latest
defaults:
run:
shell: alpine.sh {0}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: jirutka/setup-alpine@v1
with:
arch: x86
@ -71,77 +58,40 @@ jobs:
- name: test
run: |
make test
linux-riscv64:
runs-on: ubuntu-latest
defaults:
run:
shell: alpine.sh {0}
steps:
- uses: actions/checkout@v3
- uses: jirutka/setup-alpine@v1
with:
arch: riscv64
packages: "build-base make cmake"
- name: build
run: |
make
- name: stats
run: |
make stats
- name: test
run: |
make test
linux-s390x:
runs-on: ubuntu-latest
defaults:
run:
shell: alpine.sh {0}
steps:
- uses: actions/checkout@v3
- uses: jirutka/setup-alpine@v1
with:
arch: s390x
packages: "build-base make cmake"
- name: build
run: |
make
- name: stats
run: |
make stats
- name: test
run: |
make test
linux-gcc48:
runs-on: ubuntu-latest
container:
image: ubuntu:18.04
image: ubuntu:14.04
steps:
- name: install dependencies
run: |
apt update && apt -y install make gcc-4.8 cmake software-properties-common
apt update && apt -y install make gcc-4.8 wget time software-properties-common
# git in default ppa repository is too old to run submodule checkout
add-apt-repository -y ppa:git-core/ppa
apt update && apt install -y git
apt update
apt install -y git
wget https://github.com/Kitware/CMake/releases/download/v3.28.0-rc5/cmake-3.28.0-rc5-linux-x86_64.sh
sh cmake-3.28.0-rc5-linux-x86_64.sh --skip-license --prefix=/usr
- name: checkout
uses: actions/checkout@v3
with:
submodules: true
- name: build
env:
CC: gcc-4.8
run: |
mkdir build
cd build
cmake ..
cd ..
make -C build -j$(getconf _NPROCESSORS_ONLN)
CC=gcc-4.8 make
- name: stats
run: |
./build/qjs -qd
make stats
- name: test
run: |
make test
- name: test 262
run: |
time make test262
linux-examples:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: build
run: |
make BUILD_EXAMPLES=ON
@ -159,11 +109,10 @@ jobs:
./build/qjs examples/test_fib.js
./build/qjs examples/test_point.js
./build/qjs tests/test_bjson.js
./build/function_source
linux-shared:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: build
run: |
make BUILD_SHARED_LIBS=ON
@ -174,13 +123,9 @@ jobs:
linux-asan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
with:
submodules: true
# ASLR with big PIE slides does not work well with [AM]San
- name: disable ASLR
run: |
sudo sysctl -w kernel.randomize_va_space=0
- name: build
run: |
make CONFIG_ASAN=ON
@ -197,13 +142,9 @@ jobs:
linux-msan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
with:
submodules: true
# ASLR with big PIE slides does not work well with [AM]San
- name: disable ASLR
run: |
sudo sysctl -w kernel.randomize_va_space=0
- name: build
env:
CC: clang
@ -217,7 +158,7 @@ jobs:
linux-ubsan:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
with:
submodules: true
- name: build
@ -233,41 +174,15 @@ jobs:
UBSAN_OPTIONS: halt_on_error=1
run: |
time make test262
linux-tcc:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: install TCC
run: |
pushd /tmp
git clone https://repo.or.cz/tinycc.git
cd tinycc
git checkout 9d2068c6309dc50dfdbbc30a5d6757683d3f884c
./configure
make
sudo make install
tcc -v
popd
- name: build
env:
CC: tcc
run: |
make
- name: stats
run: |
make stats
macos:
runs-on: ${{ matrix.os }}
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
buildType: [Debug, Release]
os: [macos-12, macos-14]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: build
run: |
make BUILD_TYPE=${{matrix.buildType}}
@ -278,13 +193,9 @@ jobs:
run: |
make test
macos-examples:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-12, macos-14]
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: build
run: |
make BUILD_EXAMPLES=ON
@ -302,15 +213,10 @@ jobs:
./build/qjs examples/test_fib.js
./build/qjs examples/test_point.js
./build/qjs tests/test_bjson.js
./build/function_source
macos-shared:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-12, macos-14]
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: build
run: |
make BUILD_SHARED_LIBS=ON
@ -319,13 +225,9 @@ jobs:
run: |
make stats
macos-asan:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-12, macos-14]
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: build
run: |
make CONFIG_ASAN=ON
@ -335,13 +237,9 @@ jobs:
run: |
make test
macos-ubsan:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-12, macos-14]
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: build
run: |
make CONFIG_UBSAN=ON
@ -351,35 +249,6 @@ jobs:
run: |
make test
windows-msvc:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
arch: [x64, Win32]
buildType: [Debug, Release]
steps:
- uses: actions/checkout@v4
- name: build
run: |
cmake -B build -G "Visual Studio 17 2022" -A ${{matrix.arch}}
cmake --build build --config ${{matrix.buildType}} --target qjs_exe
cmake --build build --config ${{matrix.buildType}} --target function_source
- name: stats
run: |
build\${{matrix.buildType}}\qjs.exe -qd
- name: test
run: |
build\${{matrix.buildType}}\qjs.exe tests\test_bigint.js
build\${{matrix.buildType}}\qjs.exe tests\test_closure.js
build\${{matrix.buildType}}\qjs.exe tests\test_language.js
build\${{matrix.buildType}}\qjs.exe tests\test_builtin.js
build\${{matrix.buildType}}\qjs.exe tests\test_loop.js
build\${{matrix.buildType}}\qjs.exe tests\test_std.js
build\${{matrix.buildType}}\qjs.exe tests\test_worker.js
build\${{matrix.buildType}}\qjs.exe tests\test_queue_microtask.js
build\${{matrix.buildType}}\function_source.exe
windows-clang:
runs-on: windows-latest
strategy:
@ -387,58 +256,24 @@ jobs:
matrix:
buildType: [Debug, Release]
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: build
run: |
cmake -B build -G "Visual Studio 17 2022" -T ClangCL
cmake --build build --config ${{matrix.buildType}} --target qjs_exe
cmake --build build --config ${{matrix.buildType}} --target function_source
- name: stats
run: |
build\${{matrix.buildType}}\qjs.exe -qd
- name: test
run: |
build\${{matrix.buildType}}\qjs.exe tests\test_bigint.js
build\${{matrix.buildType}}\qjs.exe tests\test_closure.js
build\${{matrix.buildType}}\qjs.exe tests\test_language.js
build\${{matrix.buildType}}\qjs.exe tests\test_builtin.js
build\${{matrix.buildType}}\qjs.exe tests\test_loop.js
build\${{matrix.buildType}}\qjs.exe tests\test_std.js
build\${{matrix.buildType}}\qjs.exe tests\test_worker.js
build\${{matrix.buildType}}\qjs.exe tests\test_queue_microtask.js
build\${{matrix.buildType}}\function_source.exe
windows-ninja:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
buildType: [Debug, Release]
steps:
- uses: actions/checkout@v4
- name: install ninja
run: |
choco install ninja
ninja.exe --version
- name: build
run: |
cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -G "Ninja"
cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -G "Visual Studio 17 2022" -T ClangCL
cmake --build build --target qjs_exe
cmake --build build --target function_source
- name: stats
run: |
build\qjs.exe -qd
cmd /r build\Debug\qjs.exe -qd
- name: test
run: |
build\qjs.exe tests\test_bigint.js
build\qjs.exe tests\test_closure.js
build\qjs.exe tests\test_language.js
build\qjs.exe tests\test_builtin.js
build\qjs.exe tests\test_loop.js
build\qjs.exe tests\test_std.js
build\qjs.exe tests\test_worker.js
build\qjs.exe tests\test_queue_microtask.js
build\function_source.exe
cmd /r build\Debug\qjs.exe tests\test_bigint.js
cmd /r build\Debug\qjs.exe tests\test_closure.js
cmd /r build\Debug\qjs.exe tests\test_language.js
cmd /r build\Debug\qjs.exe tests\test_builtin.js
cmd /r build\Debug\qjs.exe tests\test_loop.js
cmd /r build\Debug\qjs.exe tests\test_std.js
cmd /r build\Debug\qjs.exe tests\test_worker.js
cmd /r build\Debug\qjs.exe tests\test_queue_microtask.js
windows-mingw:
runs-on: windows-latest
@ -455,7 +290,7 @@ jobs:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
@ -483,7 +318,7 @@ jobs:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
@ -505,7 +340,7 @@ jobs:
emscripten:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: mymindstorm/setup-emsdk@v13
- name: check emsdk
run: emcc -v
@ -515,22 +350,6 @@ jobs:
emmake make -C build qjs_wasm -j$(getconf _NPROCESSORS_ONLN)
- name: result
run: ls -lh build
wasi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: jcbhmr/setup-wasmtime@v2
- name: setup wasi-sdk
run: |
wget -nv https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-21/wasi-sdk_21.0_amd64.deb -P /tmp
sudo apt install /tmp/wasi-sdk*.deb
- name: test
run: |
cmake -B build -DCMAKE_TOOLCHAIN_FILE=/opt/wasi-sdk/share/cmake/wasi-sdk.cmake
make -C build qjs_exe
wasmtime run build/qjs -qd
echo "console.log('hello wasi!');" > t.js
wasmtime run --dir . build/qjs t.js
cygwin:
runs-on: windows-latest
@ -546,7 +365,7 @@ jobs:
with:
packages: make cmake gcc-g++ bash
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: build
run: make
@ -560,70 +379,29 @@ jobs:
openbsd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: build + test
uses: vmactions/openbsd-vm@v1
with:
usesh: true
prepare: |
pkg_add cmake gmake
pkg_add cmake
run: |
gmake
gmake stats
cmake -B build
cmake --build build -j $(sysctl -n hw.ncpu)
./build/qjs -qd
freebsd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: build + test
uses: vmactions/freebsd-vm@v1
with:
usesh: true
prepare: |
pkg install -y cmake gmake
pkg install -y cmake
run: |
gmake
gmake stats
netbsd:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: build + test
uses: vmactions/netbsd-vm@v1
with:
usesh: true
prepare: |
/usr/sbin/pkg_add cmake gmake
run: |
gmake
gmake stats
gmake test
android:
runs-on: ubuntu-latest
container: reactnativecommunity/react-native-android:v13.0
steps:
- uses: actions/checkout@v4
- name: Configure android arm64
# see build options you can use in https://developer.android.com/ndk/guides/cmake
run: |
mkdir build
cd build
$ANDROID_HOME/cmake/3.22.1/bin/cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk/26.0.10792818/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_PLATFORM=android-24 -DBUILD_QJS_LIBC=ON ..
- name: Build android arm64
run: |
$ANDROID_HOME/cmake/3.22.1/bin/cmake --build build --target qjs
ls -lh build
ios:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: configure
run: |
cmake -B build -GXcode -DCMAKE_SYSTEM_NAME:STRING=iOS -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED:BOOL=NO -DBUILD_QJS_LIBC=ON
- name: build
run: |
cmake --build build --config Release --target qjs
ls -lh build
cmake -B build
cmake --build build -j $(sysctl -n hw.ncpu)
./build/qjs -qd

View file

@ -6,66 +6,10 @@ on:
- "v*.*.*"
jobs:
linux-aarch64:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- uses: jirutka/setup-alpine@v1
with:
arch: aarch64
packages: "build-base make cmake"
- name: build
shell: alpine.sh {0}
run: |
mkdir build
cd build
cmake -DBUILD_STATIC_QJS_EXE=ON ..
cd ..
cmake --build build --target qjs_exe -j$(getconf _NPROCESSORS_ONLN)
cmake --build build --target qjsc -j$(getconf _NPROCESSORS_ONLN)
mv build/qjs build/qjs-linux-aarch64
mv build/qjsc build/qjsc-linux-aarch64
- name: check
shell: alpine.sh {0}
run: |
file build/*-linux-aarch64
- name: upload
uses: actions/upload-artifact@v3
with:
name: qjs
path: build/*-linux-aarch64
linux-riscv64:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- uses: jirutka/setup-alpine@v1
with:
arch: riscv64
packages: "build-base make cmake"
- name: build
shell: alpine.sh {0}
run: |
mkdir build
cd build
cmake -DBUILD_STATIC_QJS_EXE=ON ..
cd ..
cmake --build build --target qjs_exe -j$(getconf _NPROCESSORS_ONLN)
cmake --build build --target qjsc -j$(getconf _NPROCESSORS_ONLN)
mv build/qjs build/qjs-linux-riscv64
mv build/qjsc build/qjsc-linux-riscv64
- name: check
shell: alpine.sh {0}
run: |
file build/*-linux-riscv64
- name: upload
uses: actions/upload-artifact@v3
with:
name: qjs
path: build/*-linux-riscv64
linux-x86:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: jirutka/setup-alpine@v1
with:
arch: x86
@ -78,23 +22,21 @@ jobs:
cmake -DBUILD_STATIC_QJS_EXE=ON ..
cd ..
cmake --build build --target qjs_exe -j$(getconf _NPROCESSORS_ONLN)
cmake --build build --target qjsc -j$(getconf _NPROCESSORS_ONLN)
mv build/qjs build/qjs-linux-x86
mv build/qjsc build/qjsc-linux-x86
- name: check
shell: alpine.sh {0}
run: |
file build/*-linux-x86
file build/qjs-linux-x86
- name: upload
uses: actions/upload-artifact@v3
with:
name: qjs
path: build/*-linux-x86
path: build/qjs-linux-x86
linux-x86_64:
runs-on: ubuntu-20.04
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- uses: jirutka/setup-alpine@v1
with:
arch: x86_64
@ -107,23 +49,21 @@ jobs:
cmake -DBUILD_STATIC_QJS_EXE=ON ..
cd ..
cmake --build build --target qjs_exe -j$(getconf _NPROCESSORS_ONLN)
cmake --build build --target qjsc -j$(getconf _NPROCESSORS_ONLN)
mv build/qjs build/qjs-linux-x86_64
mv build/qjsc build/qjsc-linux-x86_64
- name: check
shell: alpine.sh {0}
run: |
file build/*-linux-x86_64
file build/qjs-linux-x86_64
- name: upload
uses: actions/upload-artifact@v3
with:
name: qjs
path: build/*-linux-x86_64
path: build/qjs-linux-x86_64
macos:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: build
run: |
mkdir build
@ -131,15 +71,14 @@ jobs:
cmake -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" ..
make -j$(getconf _NPROCESSORS_ONLN)
mv qjs qjs-darwin
mv qjsc qjsc-darwin
- name: check
run: |
lipo -info build/qjs-darwin build/qjsc-darwin
lipo -info build/qjs-darwin
- name: upload
uses: actions/upload-artifact@v3
with:
name: qjs
path: build/*-darwin
path: build/qjs-darwin
windows-x86:
runs-on: windows-latest
@ -147,7 +86,7 @@ jobs:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
@ -163,15 +102,14 @@ jobs:
run: |
make
mv build/qjs.exe build/qjs-windows-x86.exe
mv build/qjsc.exe build/qjsc-windows-x86.exe
- name: check
run: |
ldd build/qjs-windows-x86.exe build/qjsc-windows-x86.exe
ldd build/qjs-windows-x86.exe
- name: upload
uses: actions/upload-artifact@v3
with:
name: qjs
path: build/*-windows-x86.exe
path: build/qjs-windows-x86.exe
windows-x86_64:
runs-on: windows-latest
@ -179,7 +117,7 @@ jobs:
run:
shell: msys2 {0}
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v3
- name: Setup MSYS2
uses: msys2/setup-msys2@v2
with:
@ -195,38 +133,18 @@ jobs:
run: |
make
mv build/qjs.exe build/qjs-windows-x86_64.exe
mv build/qjsc.exe build/qjsc-windows-x86_64.exe
- name: check
run: |
ldd build/qjs-windows-x86_64.exe build/qjsc-windows-x86_64.exe
ldd build/qjs-windows-x86_64.exe
- name: upload
uses: actions/upload-artifact@v3
with:
name: qjs
path: build/*-windows-x86_64.exe
wasi:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- name: setup wasi-sdk
run: |
wget -nv https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-21/wasi-sdk_21.0_amd64.deb -P /tmp
sudo apt install /tmp/wasi-sdk*.deb
- name: build
run: |
cmake -B build -DCMAKE_TOOLCHAIN_FILE=/opt/wasi-sdk/share/cmake/wasi-sdk.cmake
make -C build qjs_exe
mv build/qjs build/qjs-wasi.wasm
- name: upload
uses: actions/upload-artifact@v3
with:
name: qjs
path: build/qjs-wasi.wasm
path: build/qjs-windows-x86_64.exe
upload-to-release:
needs: [linux-aarch64, linux-riscv64, linux-x86, linux-x86_64, macos, windows-x86, windows-x86_64, wasi]
runs-on: ubuntu-20.04
needs: [linux-x86, linux-x86_64, macos, windows-x86, windows-x86_64]
runs-on: ubuntu-latest
steps:
- name: get assets
uses: actions/download-artifact@v3
@ -236,5 +154,8 @@ jobs:
uses: softprops/action-gh-release@v1
with:
files: |
build/qjs/qjs-*
build/qjs/qjsc-*
build/qjs/qjs-linux-x86_64
build/qjs/qjs-linux-x86
build/qjs/qjs-windows-x86.exe
build/qjs/qjs-windows-x86_64.exe
build/qjs/qjs-darwin

View file

@ -1,23 +0,0 @@
name: valgrind
on:
push:
branches:
- master
workflow_dispatch:
jobs:
linux:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: install valgrind
run: sudo apt-get update && sudo apt-get install valgrind
- name: build
run: |
make BUILD_TYPE=RelWithDebInfo
- name: test
run: |
valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes --error-exitcode=1 ./build/run-test262 -m -c test262.conf -c test262-fast.conf -a

2
.gitignore vendored
View file

@ -5,5 +5,3 @@
build/
unicode/
test262_*.txt
.idea
cmake-*

View file

@ -5,6 +5,9 @@ project(quickjs LANGUAGES C)
include(CheckCCompilerFlag)
include(GNUInstallDirs)
# TODO:
# - Support cross-compilation
set(CMAKE_C_VISIBILITY_PRESET hidden)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS ON)
@ -27,7 +30,7 @@ macro(xcheck_add_c_compiler_flag FLAG)
endmacro()
xcheck_add_c_compiler_flag(-Wall)
if(NOT MSVC AND NOT IOS)
if(NOT MSVC)
xcheck_add_c_compiler_flag(-Werror)
xcheck_add_c_compiler_flag(-Wextra)
endif()
@ -35,6 +38,7 @@ xcheck_add_c_compiler_flag(-Wno-implicit-fallthrough)
xcheck_add_c_compiler_flag(-Wno-sign-compare)
xcheck_add_c_compiler_flag(-Wno-missing-field-initializers)
xcheck_add_c_compiler_flag(-Wno-unused-parameter)
xcheck_add_c_compiler_flag(-Wno-unused-variable)
xcheck_add_c_compiler_flag(-Wno-unused-but-set-variable)
xcheck_add_c_compiler_flag(-Wno-array-bounds)
xcheck_add_c_compiler_flag(-Wno-format-truncation)
@ -50,18 +54,7 @@ if(MSVC)
xcheck_add_c_compiler_flag(-Wno-reserved-macro-identifier)
xcheck_add_c_compiler_flag(-Wno-reserved-identifier)
xcheck_add_c_compiler_flag(-Wdeprecated-declarations)
xcheck_add_c_compiler_flag(/experimental:c11atomics)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "WASI")
add_compile_definitions(
_WASI_EMULATED_PROCESS_CLOCKS
_WASI_EMULATED_SIGNAL
)
add_link_options(
-lwasi-emulated-process-clocks
-lwasi-emulated-signal
)
add_compile_definitions(WIN32_LEAN_AND_MEAN)
endif()
if(CMAKE_BUILD_TYPE MATCHES "Debug")
@ -152,21 +145,14 @@ if(BUILD_QJS_LIBC)
list(APPEND qjs_sources quickjs-libc.c)
endif()
list(APPEND qjs_defines _GNU_SOURCE)
if(WIN32)
list(APPEND qjs_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0602)
endif()
list(APPEND qjs_libs qjs ${CMAKE_DL_LIBS})
find_package(Threads)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "WASI")
list(APPEND qjs_libs ${CMAKE_THREAD_LIBS_INIT})
endif()
if(NOT MSVC)
list(APPEND qjs_libs m)
list(APPEND qjs_libs m pthread)
endif()
add_library(qjs ${qjs_sources})
target_compile_definitions(qjs PRIVATE ${qjs_defines})
if(CMAKE_BUILD_TYPE MATCHES Debug OR DUMP_LEAKS)
if (CMAKE_BUILD_TYPE MATCHES Debug)
target_compile_definitions(qjs PRIVATE
DUMP_LEAKS
)
@ -178,18 +164,6 @@ target_include_directories(qjs PUBLIC
if(EMSCRIPTEN)
add_executable(qjs_wasm ${qjs_sources})
target_link_options(qjs_wasm PRIVATE
# in emscripten 3.x, this will be set to 16k which is too small for quickjs. #write sth. to force github rebuild
-sSTACK_SIZE=2097152 # let it be 2m = 2 * 1024 * 1024 = 2097152, otherwise, stack overflow may be occured at bootstrap
-sNO_INVOKE_RUN
-sNO_EXIT_RUNTIME
-sMODULARIZE # do not mess the global
-sEXPORT_ES6 # export js file to morden es module
-sEXPORT_NAME=getQuickJs # give a name
-sTEXTDECODER=1 # it will be 2 if we use -Oz, and that will cause js -> c string convertion fail
-sNO_DEFAULT_TO_CXX # this project is pure c project, no need for c plus plus handle
-sEXPORTED_RUNTIME_METHODS=ccall,cwrap
)
target_compile_definitions(qjs_wasm PRIVATE ${qjs_defines})
target_link_libraries(qjs_wasm m)
endif()
@ -209,10 +183,19 @@ target_link_libraries(qjsc ${qjs_libs})
# QuickJS CLI
#
add_custom_command(
OUTPUT repl.c
COMMAND qjsc -o ./repl.c -m ${CMAKE_CURRENT_SOURCE_DIR}/repl.js
DEPENDS qjsc
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Compile repl.js to bytecode"
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/repl.js
)
add_executable(qjs_exe
gen/repl.c
qjs.c
quickjs-libc.c
${CMAKE_CURRENT_BINARY_DIR}/repl.c
)
set_target_properties(qjs_exe PROPERTIES
OUTPUT_NAME "qjs"
@ -234,7 +217,7 @@ endif()
#
# run-test262 uses pthreads.
if(NOT WIN32 AND NOT EMSCRIPTEN)
if(NOT WIN32)
add_executable(run-test262
quickjs-libc.c
run-test262.c
@ -253,28 +236,37 @@ add_executable(unicode_gen EXCLUDE_FROM_ALL
)
target_compile_definitions(unicode_gen PRIVATE ${qjs_defines})
add_executable(function_source
gen/function_source.c
quickjs-libc.c
)
target_include_directories(function_source PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_definitions(function_source PRIVATE ${qjs_defines})
target_link_libraries(function_source ${qjs_libs})
# Examples
#
if(BUILD_EXAMPLES AND NOT WIN32)
add_custom_command(
OUTPUT hello.c
COMMAND qjsc -e -o hello.c ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello.js
DEPENDS qjsc
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Compile hello.js to a C file with bytecode embeddee"
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello.js
)
add_executable(hello
gen/hello.c
${CMAKE_CURRENT_BINARY_DIR}/hello.c
quickjs-libc.c
)
target_include_directories(hello PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
target_compile_definitions(hello PRIVATE ${qjs_defines})
target_link_libraries(hello ${qjs_libs})
add_custom_command(
OUTPUT hello_module.c
COMMAND qjsc -e -o hello_module.c -m ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello_module.js
DEPENDS qjsc
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Compile hello_module.js to a C file with bytecode embeddee"
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/examples/hello_module.js
)
add_executable(hello_module
gen/hello_module.c
${CMAKE_CURRENT_BINARY_DIR}/hello_module.c
quickjs-libc.c
)
target_include_directories(hello_module PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
@ -313,9 +305,17 @@ if(BUILD_EXAMPLES AND NOT WIN32)
endif()
endif()
add_custom_command(
OUTPUT test_fib.c
COMMAND qjsc -e -o test_fib.c -M ${CMAKE_CURRENT_SOURCE_DIR}/examples/fib.so,fib -m ${CMAKE_CURRENT_SOURCE_DIR}/examples/test_fib.js
DEPENDS qjsc
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
COMMENT "Compile test_fib.js to a C file with bytecode embedded"
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/examples/test_fib.js
)
add_executable(test_fib
${CMAKE_CURRENT_BINARY_DIR}/test_fib.c
examples/fib.c
gen/test_fib.c
quickjs-libc.c
)
target_include_directories(test_fib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
@ -323,14 +323,10 @@ if(BUILD_EXAMPLES AND NOT WIN32)
target_link_libraries(test_fib ${qjs_libs})
endif()
add_executable(test_conv
tests/test_conv.c
)
# Install target
#
if(NOT IOS)
file(STRINGS quickjs.h quickjs_h REGEX QJS_VERSION)
string(REGEX MATCHALL "([0-9])" QJS_VERSION "${quickjs_h}")
list(GET QJS_VERSION 0 QJS_VERSION_MAJOR)
@ -352,4 +348,3 @@ if(NOT IOS)
install(EXPORT qjsConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/quickjs)
install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(DIRECTORY examples DESTINATION ${CMAKE_INSTALL_DOCDIR})
endif()

View file

@ -26,21 +26,11 @@
BUILD_DIR=build
BUILD_TYPE?=Release
JOBS?=$(shell getconf _NPROCESSORS_ONLN)
QJS=$(BUILD_DIR)/qjs
QJSC=$(BUILD_DIR)/qjsc
RUN262=$(BUILD_DIR)/run-test262
JOBS?=$(shell getconf _NPROCESSORS_ONLN)
ifeq ($(JOBS),)
JOBS := $(shell sysctl -n hw.ncpu)
endif
ifeq ($(JOBS),)
JOBS := $(shell nproc)
endif
ifeq ($(JOBS),)
JOBS := 4
endif
all: $(QJS)
@ -50,26 +40,12 @@ $(BUILD_DIR):
$(QJS): $(BUILD_DIR)
cmake --build $(BUILD_DIR) -j $(JOBS)
$(QJSC): $(BUILD_DIR)
cmake --build $(BUILD_DIR) --target qjsc -j $(JOBS)
$(BUILD_DIR)/test_conv: $(BUILD_DIR) tests/test_conv.c
cmake --build $(BUILD_DIR) --target test_conv
install: $(QJS) $(QJSC)
install: $(QJS)
cmake --build $(BUILD_DIR) --target install
clean:
@rm -f v8.txt[1-9]*
cmake --build $(BUILD_DIR) --target clean
codegen: $(QJSC)
$(QJSC) -ss -o gen/repl.c -m repl.js
$(QJSC) -e -o gen/function_source.c tests/function_source.js
$(QJSC) -e -o gen/hello.c examples/hello.js
$(QJSC) -e -o gen/hello_module.c -m examples/hello_module.js
$(QJSC) -e -o gen/test_fib.c -M examples/fib.so,fib -m examples/test_fib.js
debug:
BUILD_TYPE=Debug $(MAKE)
@ -89,15 +65,9 @@ test: $(QJS)
$(QJS) tests/test_worker.js
$(QJS) tests/test_queue_microtask.js
testconv: $(BUILD_DIR)/test_conv
$(BUILD_DIR)/test_conv
test262: $(QJS)
$(RUN262) -m -c test262.conf -a
test262-fast: $(QJS)
$(RUN262) -m -c test262.conf -c test262-fast.conf -a
test262-update: $(QJS)
$(RUN262) -u -c test262.conf -a
@ -113,4 +83,4 @@ unicode_gen: $(BUILD_DIR)
libunicode-table.h: unicode_gen
$(BUILD_DIR)/unicode_gen unicode $@
.PHONY: all debug install clean codegen distclean stats test test262 test262-update test262-check microbench unicode_gen $(QJS) $(QJSC)
.PHONY: all build debug install clean distclean stats test test262 test262-update test262-check microbench unicode_gen

View file

@ -1,22 +1,7 @@
# ⚡️ QuickJS - A mighty JavaScript engine
Friendly [QuickJS]() fork focused on reigniting the project.
Friendly [QuickJS](https://bellard.org/quickjs) fork focused on reigniting the project.
## Overview
🚧 Work in progress.
In October 2023 [@bnoordhuis] and [@saghul] decided to fork the [QuickJS] project with
the aim of reigniting it. They reached out to the original authors ([@bellard] and [@chqrlie])
about their intentions.
As of December 2023 the initial goal was somewhat accomplished. [@bellard] resumed working on
the project and both parties have been pulling patches from each other since.
As of early 2024 both projects agree the proper path forward involves merging both projects
and combining the efforts. While that may take a while, since both projects diverged in certain
areas, there is willingness to go in this direction from both sides.
[QuickJS]: https://bellard.org/quickjs
[@bellard]: https://github.com/bellard
[@bnoordhuis]: https://github.com/bnoordhuis
[@chqrlie]: https://github.com/chqrlie
[@saghul]: https://github.com/saghul
test.

892
cutils.c
View file

@ -34,9 +34,6 @@
#include "cutils.h"
#undef NANOSEC
#define NANOSEC ((uint64_t) 1e9)
#pragma GCC visibility push(default)
void pstrcpy(char *buf, int buf_size, const char *str)
@ -132,7 +129,7 @@ int dbuf_realloc(DynBuf *s, size_t new_size)
return 0;
}
int dbuf_write(DynBuf *s, size_t offset, const void *data, size_t len)
int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len)
{
size_t end;
end = offset + len;
@ -144,7 +141,7 @@ int dbuf_write(DynBuf *s, size_t offset, const void *data, size_t len)
return 0;
}
int dbuf_put(DynBuf *s, const void *data, size_t len)
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len)
{
if (unlikely((s->size + len) > s->allocated_size)) {
if (dbuf_realloc(s, s->size + len))
@ -213,85 +210,56 @@ void dbuf_free(DynBuf *s)
memset(s, 0, sizeof(*s));
}
/*--- UTF-8 utility functions --*/
/* Note: only encode valid codepoints (0x0000..0x10FFFF).
At most UTF8_CHAR_LEN_MAX bytes are output. */
/* Compute the number of bytes of the UTF-8 encoding for a codepoint
`c` is a code-point.
Returns the number of bytes. If a codepoint is beyond 0x10FFFF the
return value is 3 as the codepoint would be encoded as 0xFFFD.
*/
size_t utf8_encode_len(uint32_t c)
/* Note: at most 31 bits are encoded. At most UTF8_CHAR_LEN_MAX bytes
are output. */
int unicode_to_utf8(uint8_t *buf, unsigned int c)
{
if (c < 0x80)
return 1;
if (c < 0x800)
return 2;
if (c < 0x10000)
return 3;
if (c < 0x110000)
return 4;
return 3;
}
uint8_t *q = buf;
/* Encode a codepoint in UTF-8
`buf` points to an array of at least `UTF8_CHAR_LEN_MAX` bytes
`c` is a code-point.
Returns the number of bytes. If a codepoint is beyond 0x10FFFF the
return value is 3 and the codepoint is encoded as 0xFFFD.
No null byte is stored after the encoded bytes.
Return value is in range 1..4
*/
size_t utf8_encode(uint8_t *buf, uint32_t c)
{
if (c < 0x80) {
buf[0] = c;
return 1;
}
*q++ = c;
} else {
if (c < 0x800) {
buf[0] = (c >> 6) | 0xC0;
buf[1] = (c & 0x3F) | 0x80;
return 2;
}
*q++ = (c >> 6) | 0xc0;
} else {
if (c < 0x10000) {
buf[0] = (c >> 12) | 0xE0;
buf[1] = ((c >> 6) & 0x3F) | 0x80;
buf[2] = (c & 0x3F) | 0x80;
return 3;
*q++ = (c >> 12) | 0xe0;
} else {
if (c < 0x00200000) {
*q++ = (c >> 18) | 0xf0;
} else {
if (c < 0x04000000) {
*q++ = (c >> 24) | 0xf8;
} else if (c < 0x80000000) {
*q++ = (c >> 30) | 0xfc;
*q++ = ((c >> 24) & 0x3f) | 0x80;
} else {
return 0;
}
if (c < 0x110000) {
buf[0] = (c >> 18) | 0xF0;
buf[1] = ((c >> 12) & 0x3F) | 0x80;
buf[2] = ((c >> 6) & 0x3F) | 0x80;
buf[3] = (c & 0x3F) | 0x80;
return 4;
*q++ = ((c >> 18) & 0x3f) | 0x80;
}
buf[0] = (0xFFFD >> 12) | 0xE0;
buf[1] = ((0xFFFD >> 6) & 0x3F) | 0x80;
buf[2] = (0xFFFD & 0x3F) | 0x80;
return 3;
*q++ = ((c >> 12) & 0x3f) | 0x80;
}
*q++ = ((c >> 6) & 0x3f) | 0x80;
}
*q++ = (c & 0x3f) | 0x80;
}
return q - buf;
}
/* Decode a single code point from a UTF-8 encoded array of bytes
`p` is a valid pointer to an array of bytes
`pp` is a valid pointer to a `const uint8_t *` to store a pointer
to the byte following the current sequence.
Return the code point at `p`, in the range `0..0x10FFFF`
Return 0xFFFD on error. Only a single byte is consumed in this case
The maximum length for a UTF-8 byte sequence is 4 bytes.
This implements the algorithm specified in whatwg.org, except it accepts
UTF-8 encoded surrogates as JavaScript allows them in strings.
The source string is assumed to have at least UTF8_CHAR_LEN_MAX bytes
or be null terminated.
If `p[0]` is '\0', the return value is `0` and the byte is consumed.
cf: https://encoding.spec.whatwg.org/#utf-8-encoder
*/
uint32_t utf8_decode(const uint8_t *p, const uint8_t **pp)
static const unsigned int utf8_min_code[5] = {
0x80, 0x800, 0x10000, 0x00200000, 0x04000000,
};
static const unsigned char utf8_first_code_mask[5] = {
0x1f, 0xf, 0x7, 0x3, 0x1,
};
/* return -1 if error. *pp is not updated in this case. max_len must
be >= 1. The maximum length for a UTF8 byte sequence is 6 bytes. */
int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp)
{
uint32_t c;
uint8_t lower, upper;
int l, c, b, i;
c = *p++;
if (c < 0x80) {
@ -299,533 +267,51 @@ uint32_t utf8_decode(const uint8_t *p, const uint8_t **pp)
return c;
}
switch(c) {
case 0xC2: case 0xC3:
case 0xC4: case 0xC5: case 0xC6: case 0xC7:
case 0xC8: case 0xC9: case 0xCA: case 0xCB:
case 0xCC: case 0xCD: case 0xCE: case 0xCF:
case 0xD0: case 0xD1: case 0xD2: case 0xD3:
case 0xD4: case 0xD5: case 0xD6: case 0xD7:
case 0xD8: case 0xD9: case 0xDA: case 0xDB:
case 0xDC: case 0xDD: case 0xDE: case 0xDF:
if (*p >= 0x80 && *p <= 0xBF) {
*pp = p + 1;
return ((c - 0xC0) << 6) + (*p - 0x80);
}
// otherwise encoding error
case 0xc0: case 0xc1: case 0xc2: case 0xc3:
case 0xc4: case 0xc5: case 0xc6: case 0xc7:
case 0xc8: case 0xc9: case 0xca: case 0xcb:
case 0xcc: case 0xcd: case 0xce: case 0xcf:
case 0xd0: case 0xd1: case 0xd2: case 0xd3:
case 0xd4: case 0xd5: case 0xd6: case 0xd7:
case 0xd8: case 0xd9: case 0xda: case 0xdb:
case 0xdc: case 0xdd: case 0xde: case 0xdf:
l = 1;
break;
case 0xE0:
lower = 0xA0; /* reject invalid encoding */
goto need2;
case 0xE1: case 0xE2: case 0xE3:
case 0xE4: case 0xE5: case 0xE6: case 0xE7:
case 0xE8: case 0xE9: case 0xEA: case 0xEB:
case 0xEC: case 0xED: case 0xEE: case 0xEF:
lower = 0x80;
need2:
if (*p >= lower && *p <= 0xBF && p[1] >= 0x80 && p[1] <= 0xBF) {
*pp = p + 2;
return ((c - 0xE0) << 12) + ((*p - 0x80) << 6) + (p[1] - 0x80);
}
// otherwise encoding error
case 0xe0: case 0xe1: case 0xe2: case 0xe3:
case 0xe4: case 0xe5: case 0xe6: case 0xe7:
case 0xe8: case 0xe9: case 0xea: case 0xeb:
case 0xec: case 0xed: case 0xee: case 0xef:
l = 2;
break;
case 0xF0:
lower = 0x90; /* reject invalid encoding */
upper = 0xBF;
goto need3;
case 0xF4:
lower = 0x80;
upper = 0x8F; /* reject values above 0x10FFFF */
goto need3;
case 0xF1: case 0xF2: case 0xF3:
lower = 0x80;
upper = 0xBF;
need3:
if (*p >= lower && *p <= upper && p[1] >= 0x80 && p[1] <= 0xBF
&& p[2] >= 0x80 && p[2] <= 0xBF) {
*pp = p + 3;
return ((c - 0xF0) << 18) + ((*p - 0x80) << 12) +
((p[1] - 0x80) << 6) + (p[2] - 0x80);
}
// otherwise encoding error
case 0xf0: case 0xf1: case 0xf2: case 0xf3:
case 0xf4: case 0xf5: case 0xf6: case 0xf7:
l = 3;
break;
case 0xf8: case 0xf9: case 0xfa: case 0xfb:
l = 4;
break;
case 0xfc: case 0xfd:
l = 5;
break;
default:
// invalid lead byte
break;
return -1;
}
/* check that we have enough characters */
if (l > (max_len - 1))
return -1;
c &= utf8_first_code_mask[l - 1];
for(i = 0; i < l; i++) {
b = *p++;
if (b < 0x80 || b >= 0xc0)
return -1;
c = (c << 6) | (b & 0x3f);
}
if (c < utf8_min_code[l - 1])
return -1;
*pp = p;
return 0xFFFD;
return c;
}
uint32_t utf8_decode_len(const uint8_t *p, size_t max_len, const uint8_t **pp) {
switch (max_len) {
case 0:
*pp = p;
return 0xFFFD;
case 1:
if (*p < 0x80)
goto good;
break;
case 2:
if (*p < 0xE0)
goto good;
break;
case 3:
if (*p < 0xF0)
goto good;
break;
default:
good:
return utf8_decode(p, pp);
}
*pp = p + 1;
return 0xFFFD;
}
/* Scan a UTF-8 encoded buffer for content type
`buf` is a valid pointer to a UTF-8 encoded string
`len` is the number of bytes to scan
`plen` points to a `size_t` variable to receive the number of units
Return value is a mask of bits.
- `UTF8_PLAIN_ASCII`: return value for 7-bit ASCII plain text
- `UTF8_NON_ASCII`: bit for non ASCII code points (8-bit or more)
- `UTF8_HAS_16BIT`: bit for 16-bit code points
- `UTF8_HAS_NON_BMP1`: bit for non-BMP1 code points, needs UTF-16 surrogate pairs
- `UTF8_HAS_ERRORS`: bit for encoding errors
*/
int utf8_scan(const char *buf, size_t buf_len, size_t *plen)
{
const uint8_t *p, *p_end, *p_next;
size_t i, len;
int kind;
uint8_t cbits;
kind = UTF8_PLAIN_ASCII;
cbits = 0;
len = buf_len;
// TODO: handle more than 1 byte at a time
for (i = 0; i < buf_len; i++)
cbits |= buf[i];
if (cbits >= 0x80) {
p = (const uint8_t *)buf;
p_end = p + buf_len;
kind = UTF8_NON_ASCII;
len = 0;
while (p < p_end) {
len++;
if (*p++ >= 0x80) {
/* parse UTF-8 sequence, check for encoding error */
uint32_t c = utf8_decode_len(p - 1, p_end - (p - 1), &p_next);
if (p_next == p)
kind |= UTF8_HAS_ERRORS;
p = p_next;
if (c > 0xFF) {
kind |= UTF8_HAS_16BIT;
if (c > 0xFFFF) {
len++;
kind |= UTF8_HAS_NON_BMP1;
}
}
}
}
}
*plen = len;
return kind;
}
/* Decode a string encoded in UTF-8 into an array of bytes
`src` points to the source string. It is assumed to be correctly encoded
and only contains code points below 0x800
`src_len` is the length of the source string
`dest` points to the destination array, it can be null if `dest_len` is `0`
`dest_len` is the length of the destination array. A null
terminator is stored at the end of the array unless `dest_len` is `0`.
*/
size_t utf8_decode_buf8(uint8_t *dest, size_t dest_len, const char *src, size_t src_len)
{
const uint8_t *p, *p_end;
size_t i;
p = (const uint8_t *)src;
p_end = p + src_len;
for (i = 0; p < p_end; i++) {
uint32_t c = *p++;
if (c >= 0xC0)
c = (c << 6) + *p++ - ((0xC0 << 6) + 0x80);
if (i < dest_len)
dest[i] = c;
}
if (i < dest_len)
dest[i] = '\0';
else if (dest_len > 0)
dest[dest_len - 1] = '\0';
return i;
}
/* Decode a string encoded in UTF-8 into an array of 16-bit words
`src` points to the source string. It is assumed to be correctly encoded.
`src_len` is the length of the source string
`dest` points to the destination array, it can be null if `dest_len` is `0`
`dest_len` is the length of the destination array. No null terminator is
stored at the end of the array.
*/
size_t utf8_decode_buf16(uint16_t *dest, size_t dest_len, const char *src, size_t src_len)
{
const uint8_t *p, *p_end;
size_t i;
p = (const uint8_t *)src;
p_end = p + src_len;
for (i = 0; p < p_end; i++) {
uint32_t c = *p++;
if (c >= 0x80) {
/* parse utf-8 sequence */
c = utf8_decode_len(p - 1, p_end - (p - 1), &p);
/* encoding errors are converted as 0xFFFD and use a single byte */
if (c > 0xFFFF) {
if (i < dest_len)
dest[i] = get_hi_surrogate(c);
i++;
c = get_lo_surrogate(c);
}
}
if (i < dest_len)
dest[i] = c;
}
return i;
}
/* Encode a buffer of 8-bit bytes as a UTF-8 encoded string
`src` points to the source buffer.
`src_len` is the length of the source buffer
`dest` points to the destination array, it can be null if `dest_len` is `0`
`dest_len` is the length in bytes of the destination array. A null
terminator is stored at the end of the array unless `dest_len` is `0`.
*/
size_t utf8_encode_buf8(char *dest, size_t dest_len, const uint8_t *src, size_t src_len)
{
size_t i, j;
uint32_t c;
for (i = j = 0; i < src_len; i++) {
c = src[i];
if (c < 0x80) {
if (j + 1 >= dest_len)
goto overflow;
dest[j++] = c;
} else {
if (j + 2 >= dest_len)
goto overflow;
dest[j++] = (c >> 6) | 0xC0;
dest[j++] = (c & 0x3F) | 0x80;
}
}
if (j < dest_len)
dest[j] = '\0';
return j;
overflow:
if (j < dest_len)
dest[j] = '\0';
while (i < src_len)
j += 1 + (src[i++] >= 0x80);
return j;
}
/* Encode a buffer of 16-bit code points as a UTF-8 encoded string
`src` points to the source buffer.
`src_len` is the length of the source buffer
`dest` points to the destination array, it can be null if `dest_len` is `0`
`dest_len` is the length in bytes of the destination array. A null
terminator is stored at the end of the array unless `dest_len` is `0`.
*/
size_t utf8_encode_buf16(char *dest, size_t dest_len, const uint16_t *src, size_t src_len)
{
size_t i, j;
uint32_t c;
for (i = j = 0; i < src_len;) {
c = src[i++];
if (c < 0x80) {
if (j + 1 >= dest_len)
goto overflow;
dest[j++] = c;
} else {
if (is_hi_surrogate(c) && i < src_len && is_lo_surrogate(src[i]))
c = from_surrogate(c, src[i++]);
if (j + utf8_encode_len(c) >= dest_len)
goto overflow;
j += utf8_encode((uint8_t *)dest + j, c);
}
}
if (j < dest_len)
dest[j] = '\0';
return j;
overflow:
i -= 1 + (c > 0xFFFF);
if (j < dest_len)
dest[j] = '\0';
while (i < src_len) {
c = src[i++];
if (c < 0x80) {
j++;
} else {
if (is_hi_surrogate(c) && i < src_len && is_lo_surrogate(src[i]))
c = from_surrogate(c, src[i++]);
j += utf8_encode_len(c);
}
}
return j;
}
/*--- integer to string conversions --*/
/* All conversion functions:
- require a destination array `buf` of sufficient length
- write the string representation at the beginning of `buf`
- null terminate the string
- return the string length
*/
/* 2 <= base <= 36 */
char const digits36[36] = "0123456789abcdefghijklmnopqrstuvwxyz";
#define USE_SPECIAL_RADIX_10 1 // special case base 10 radix conversions
#define USE_SINGLE_CASE_FAST 1 // special case single digit numbers
/* using u32toa_shift variant */
#define gen_digit(buf, c) if (is_be()) \
buf = (buf >> 8) | ((uint64_t)(c) << ((sizeof(buf) - 1) * 8)); \
else \
buf = (buf << 8) | (c)
size_t u7toa_shift(char dest[minimum_length(8)], uint32_t n)
{
size_t len = 1;
uint64_t buf = 0;
while (n >= 10) {
uint32_t quo = n % 10;
n /= 10;
gen_digit(buf, '0' + quo);
len++;
}
gen_digit(buf, '0' + n);
memcpy(dest, &buf, sizeof buf);
return len;
}
size_t u07toa_shift(char dest[minimum_length(8)], uint32_t n, size_t len)
{
size_t i;
dest += len;
dest[7] = '\0';
for (i = 7; i-- > 1;) {
uint32_t quo = n % 10;
n /= 10;
dest[i] = (char)('0' + quo);
}
dest[i] = (char)('0' + n);
return len + 7;
}
size_t u32toa(char buf[minimum_length(11)], uint32_t n)
{
#ifdef USE_SINGLE_CASE_FAST /* 10% */
if (n < 10) {
buf[0] = (char)('0' + n);
buf[1] = '\0';
return 1;
}
#endif
#define TEN_POW_7 10000000
if (n >= TEN_POW_7) {
uint32_t quo = n / TEN_POW_7;
n %= TEN_POW_7;
size_t len = u7toa_shift(buf, quo);
return u07toa_shift(buf, n, len);
}
return u7toa_shift(buf, n);
}
size_t u64toa(char buf[minimum_length(21)], uint64_t n)
{
if (likely(n < 0x100000000))
return u32toa(buf, n);
size_t len;
if (n >= TEN_POW_7) {
uint64_t n1 = n / TEN_POW_7;
n %= TEN_POW_7;
if (n1 >= TEN_POW_7) {
uint32_t quo = n1 / TEN_POW_7;
n1 %= TEN_POW_7;
len = u7toa_shift(buf, quo);
len = u07toa_shift(buf, n1, len);
} else {
len = u7toa_shift(buf, n1);
}
return u07toa_shift(buf, n, len);
}
return u7toa_shift(buf, n);
}
size_t i32toa(char buf[minimum_length(12)], int32_t n)
{
if (likely(n >= 0))
return u32toa(buf, n);
buf[0] = '-';
return 1 + u32toa(buf + 1, -(uint32_t)n);
}
size_t i64toa(char buf[minimum_length(22)], int64_t n)
{
if (likely(n >= 0))
return u64toa(buf, n);
buf[0] = '-';
return 1 + u64toa(buf + 1, -(uint64_t)n);
}
/* using u32toa_radix_length variant */
static uint8_t const radix_shift[64] = {
0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0,
4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
};
size_t u32toa_radix(char buf[minimum_length(33)], uint32_t n, unsigned base)
{
int shift;
#ifdef USE_SPECIAL_RADIX_10
if (likely(base == 10))
return u32toa(buf, n);
#endif
if (n < base) {
buf[0] = digits36[n];
buf[1] = '\0';
return 1;
}
shift = radix_shift[base & 63];
if (shift) {
uint32_t mask = (1 << shift) - 1;
size_t len = (32 - clz32(n) + shift - 1) / shift;
size_t last = n & mask;
char *end = buf + len;
n >>= shift;
*end-- = '\0';
*end-- = digits36[last];
while (n >= base) {
size_t quo = n & mask;
n >>= shift;
*end-- = digits36[quo];
}
*end = digits36[n];
return len;
} else {
size_t len = 2;
size_t last = n % base;
n /= base;
uint32_t nbase = base;
while (n >= nbase) {
nbase *= base;
len++;
}
char *end = buf + len;
*end-- = '\0';
*end-- = digits36[last];
while (n >= base) {
size_t quo = n % base;
n /= base;
*end-- = digits36[quo];
}
*end = digits36[n];
return len;
}
}
size_t u64toa_radix(char buf[minimum_length(65)], uint64_t n, unsigned base)
{
int shift;
#ifdef USE_SPECIAL_RADIX_10
if (likely(base == 10))
return u64toa(buf, n);
#endif
shift = radix_shift[base & 63];
if (shift) {
if (n < base) {
buf[0] = digits36[n];
buf[1] = '\0';
return 1;
}
uint64_t mask = (1 << shift) - 1;
size_t len = (64 - clz64(n) + shift - 1) / shift;
size_t last = n & mask;
char *end = buf + len;
n >>= shift;
*end-- = '\0';
*end-- = digits36[last];
while (n >= base) {
size_t quo = n & mask;
n >>= shift;
*end-- = digits36[quo];
}
*end = digits36[n];
return len;
} else {
if (likely(n < 0x100000000))
return u32toa_radix(buf, n, base);
size_t last = n % base;
n /= base;
uint64_t nbase = base;
size_t len = 2;
while (n >= nbase) {
nbase *= base;
len++;
}
char *end = buf + len;
*end-- = '\0';
*end-- = digits36[last];
while (n >= base) {
size_t quo = n % base;
n /= base;
*end-- = digits36[quo];
}
*end = digits36[n];
return len;
}
}
size_t i32toa_radix(char buf[minimum_length(34)], int32_t n, unsigned int base)
{
if (likely(n >= 0))
return u32toa_radix(buf, n, base);
buf[0] = '-';
return 1 + u32toa_radix(buf + 1, -(uint32_t)n, base);
}
size_t i64toa_radix(char buf[minimum_length(66)], int64_t n, unsigned int base)
{
if (likely(n >= 0))
return u64toa_radix(buf, n, base);
buf[0] = '-';
return 1 + u64toa_radix(buf + 1, -(uint64_t)n, base);
}
#undef gen_digit
#undef TEN_POW_7
#undef USE_SPECIAL_RADIX_10
#undef USE_SINGLE_CASE_FAST
/*---- sorting with opaque argument ----*/
typedef void (*exchange_f)(void *a, void *b, size_t size);
typedef int (*cmp_f)(const void *, const void *, void *opaque);
@ -1125,8 +611,6 @@ void rqsort(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque)
}
}
/*---- Portable time functions ----*/
#if defined(_MSC_VER)
// From: https://stackoverflow.com/a/26085827
static int gettimeofday_msvc(struct timeval *tp, struct timezone *tzp)
@ -1165,7 +649,7 @@ uint64_t js__hrtime_ns(void) {
* performance counter interval, integer math could cause this computation
* to overflow. Therefore we resort to floating point math.
*/
scaled_freq = (double) frequency.QuadPart / NANOSEC;
scaled_freq = (double) frequency.QuadPart / 1e9;
result = (double) counter.QuadPart / scaled_freq;
return (uint64_t) result;
}
@ -1176,7 +660,7 @@ uint64_t js__hrtime_ns(void) {
if (clock_gettime(CLOCK_MONOTONIC, &t))
abort();
return t.tv_sec * NANOSEC + t.tv_nsec;
return t.tv_sec * (uint64_t) 1e9 + t.tv_nsec;
}
#endif
@ -1190,218 +674,4 @@ int64_t js__gettimeofday_us(void) {
return ((int64_t)tv.tv_sec * 1000000) + tv.tv_usec;
}
/*--- Cross-platform threading APIs. ----*/
#if !defined(EMSCRIPTEN) && !defined(__wasi__)
#if defined(_WIN32)
typedef void (*js__once_cb)(void);
typedef struct {
js__once_cb callback;
} js__once_data_t;
static BOOL WINAPI js__once_inner(INIT_ONCE *once, void *param, void **context) {
js__once_data_t *data = param;
data->callback();
return TRUE;
}
void js_once(js_once_t *guard, js__once_cb callback) {
js__once_data_t data = { .callback = callback };
InitOnceExecuteOnce(guard, js__once_inner, (void*) &data, NULL);
}
void js_mutex_init(js_mutex_t *mutex) {
InitializeCriticalSection(mutex);
}
void js_mutex_destroy(js_mutex_t *mutex) {
DeleteCriticalSection(mutex);
}
void js_mutex_lock(js_mutex_t *mutex) {
EnterCriticalSection(mutex);
}
void js_mutex_unlock(js_mutex_t *mutex) {
LeaveCriticalSection(mutex);
}
void js_cond_init(js_cond_t *cond) {
InitializeConditionVariable(cond);
}
void js_cond_destroy(js_cond_t *cond) {
/* nothing to do */
(void) cond;
}
void js_cond_signal(js_cond_t *cond) {
WakeConditionVariable(cond);
}
void js_cond_broadcast(js_cond_t *cond) {
WakeAllConditionVariable(cond);
}
void js_cond_wait(js_cond_t *cond, js_mutex_t *mutex) {
if (!SleepConditionVariableCS(cond, mutex, INFINITE))
abort();
}
int js_cond_timedwait(js_cond_t *cond, js_mutex_t *mutex, uint64_t timeout) {
if (SleepConditionVariableCS(cond, mutex, (DWORD)(timeout / 1e6)))
return 0;
if (GetLastError() != ERROR_TIMEOUT)
abort();
return -1;
}
#else /* !defined(_WIN32) */
void js_once(js_once_t *guard, void (*callback)(void)) {
if (pthread_once(guard, callback))
abort();
}
void js_mutex_init(js_mutex_t *mutex) {
if (pthread_mutex_init(mutex, NULL))
abort();
}
void js_mutex_destroy(js_mutex_t *mutex) {
if (pthread_mutex_destroy(mutex))
abort();
}
void js_mutex_lock(js_mutex_t *mutex) {
if (pthread_mutex_lock(mutex))
abort();
}
void js_mutex_unlock(js_mutex_t *mutex) {
if (pthread_mutex_unlock(mutex))
abort();
}
void js_cond_init(js_cond_t *cond) {
#if defined(__APPLE__) && defined(__MACH__)
if (pthread_cond_init(cond, NULL))
abort();
#else
pthread_condattr_t attr;
if (pthread_condattr_init(&attr))
abort();
if (pthread_condattr_setclock(&attr, CLOCK_MONOTONIC))
abort();
if (pthread_cond_init(cond, &attr))
abort();
if (pthread_condattr_destroy(&attr))
abort();
#endif
}
void js_cond_destroy(js_cond_t *cond) {
#if defined(__APPLE__) && defined(__MACH__)
/* It has been reported that destroying condition variables that have been
* signalled but not waited on can sometimes result in application crashes.
* See https://codereview.chromium.org/1323293005.
*/
pthread_mutex_t mutex;
struct timespec ts;
int err;
if (pthread_mutex_init(&mutex, NULL))
abort();
if (pthread_mutex_lock(&mutex))
abort();
ts.tv_sec = 0;
ts.tv_nsec = 1;
err = pthread_cond_timedwait_relative_np(cond, &mutex, &ts);
if (err != 0 && err != ETIMEDOUT)
abort();
if (pthread_mutex_unlock(&mutex))
abort();
if (pthread_mutex_destroy(&mutex))
abort();
#endif /* defined(__APPLE__) && defined(__MACH__) */
if (pthread_cond_destroy(cond))
abort();
}
void js_cond_signal(js_cond_t *cond) {
if (pthread_cond_signal(cond))
abort();
}
void js_cond_broadcast(js_cond_t *cond) {
if (pthread_cond_broadcast(cond))
abort();
}
void js_cond_wait(js_cond_t *cond, js_mutex_t *mutex) {
#if defined(__APPLE__) && defined(__MACH__)
int r;
errno = 0;
r = pthread_cond_wait(cond, mutex);
/* Workaround for a bug in OS X at least up to 13.6
* See https://github.com/libuv/libuv/issues/4165
*/
if (r == EINVAL && errno == EBUSY)
return;
if (r)
abort();
#else
if (pthread_cond_wait(cond, mutex))
abort();
#endif
}
int js_cond_timedwait(js_cond_t *cond, js_mutex_t *mutex, uint64_t timeout) {
int r;
struct timespec ts;
#if !defined(__APPLE__)
timeout += js__hrtime_ns();
#endif
ts.tv_sec = timeout / NANOSEC;
ts.tv_nsec = timeout % NANOSEC;
#if defined(__APPLE__) && defined(__MACH__)
r = pthread_cond_timedwait_relative_np(cond, mutex, &ts);
#else
r = pthread_cond_timedwait(cond, mutex, &ts);
#endif
if (r == 0)
return 0;
if (r == ETIMEDOUT)
return -1;
abort();
/* Pacify some compilers. */
return -1;
}
#endif
#endif /* !defined(EMSCRIPTEN) && !defined(__wasi__) */
#pragma GCC visibility pop

246
cutils.h
View file

@ -26,13 +26,13 @@
#define CUTILS_H
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#if defined(_WIN32)
#include <windows.h>
#endif
/* set if CPU is big endian */
#undef WORDS_BIGENDIAN
#if defined(_MSC_VER)
#include <windows.h>
#include <winsock2.h>
#include <malloc.h>
#define alloca _alloca
@ -40,57 +40,17 @@
#endif
#if defined(__APPLE__)
#include <malloc/malloc.h>
#elif defined(__linux__) || defined(__ANDROID__) || defined(__CYGWIN__)
#elif defined(__linux__) || defined(__CYGWIN__)
#include <malloc.h>
#elif defined(__FreeBSD__)
#include <malloc_np.h>
#endif
#if !defined(_WIN32)
#include <errno.h>
#include <pthread.h>
#endif
#if defined(_MSC_VER) && !defined(__clang__)
# define likely(x) (x)
# define unlikely(x) (x)
# define force_inline __forceinline
# define no_inline __declspec(noinline)
# define __maybe_unused
# define __attribute__(x)
# define __attribute(x)
# include <intrin.h>
static void *__builtin_frame_address(unsigned int level) {
return (void *)((char*)_AddressOfReturnAddress() - sizeof(int *) - level * sizeof(int *));
}
#else
#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)
#define force_inline inline __attribute__((always_inline))
#define no_inline __attribute__((noinline))
#define __maybe_unused __attribute__((unused))
#endif
// https://stackoverflow.com/a/6849629
#undef FORMAT_STRING
#if _MSC_VER >= 1400
# include <sal.h>
# if _MSC_VER > 1400
# define FORMAT_STRING(p) _Printf_format_string_ p
# else
# define FORMAT_STRING(p) __format_string p
# endif /* FORMAT_STRING */
#else
# define FORMAT_STRING(p) p
#endif /* _MSC_VER */
#if defined(_MSC_VER) && !defined(__clang__)
#include <math.h>
#define INF INFINITY
#define NEG_INF -INFINITY
#else
#define INF (1.0/0.0)
#define NEG_INF (-1.0/0.0)
#endif
#define xglue(x, y) x ## y
#define glue(x, y) xglue(x, y)
@ -106,16 +66,6 @@ static void *__builtin_frame_address(unsigned int level) {
#define endof(x) ((x) + countof(x))
#endif
#endif
#ifndef container_of
/* return the pointer of type 'type *' containing 'ptr' as field 'member' */
#define container_of(ptr, type, member) ((type *)((uint8_t *)(ptr) - offsetof(type, member)))
#endif
#if !defined(_MSC_VER) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define minimum_length(n) static n
#else
#define minimum_length(n) n
#endif
typedef int BOOL;
@ -131,14 +81,6 @@ char *pstrcat(char *buf, int buf_size, const char *s);
int strstart(const char *str, const char *val, const char **ptr);
int has_suffix(const char *str, const char *suffix);
static inline uint8_t is_be(void) {
union {
uint16_t a;
uint8_t b;
} u = { 0x100 };
return u.b;
}
static inline int max_int(int a, int b)
{
if (a > b)
@ -190,113 +132,82 @@ static inline int64_t min_int64(int64_t a, int64_t b)
/* WARNING: undefined if a = 0 */
static inline int clz32(unsigned int a)
{
#if defined(_MSC_VER) && !defined(__clang__)
unsigned long index;
_BitScanReverse(&index, a);
return 31 - index;
#else
return __builtin_clz(a);
#endif
}
/* WARNING: undefined if a = 0 */
static inline int clz64(uint64_t a)
{
#if defined(_MSC_VER) && !defined(__clang__)
#if INTPTR_MAX == INT64_MAX
unsigned long index;
_BitScanReverse64(&index, a);
return 63 - index;
#else
if (a >> 32)
return clz32((unsigned)(a >> 32));
else
return clz32((unsigned)a) + 32;
#endif
#else
return __builtin_clzll(a);
#endif
}
/* WARNING: undefined if a = 0 */
static inline int ctz32(unsigned int a)
{
#if defined(_MSC_VER) && !defined(__clang__)
unsigned long index;
_BitScanForward(&index, a);
return index;
#else
return __builtin_ctz(a);
#endif
}
/* WARNING: undefined if a = 0 */
static inline int ctz64(uint64_t a)
{
#if defined(_MSC_VER) && !defined(__clang__)
unsigned long index;
_BitScanForward64(&index, a);
return index;
#else
return __builtin_ctzll(a);
#endif
}
struct __attribute__((packed)) packed_u64 {
uint64_t v;
};
struct __attribute__((packed)) packed_u32 {
uint32_t v;
};
struct __attribute__((packed)) packed_u16 {
uint16_t v;
};
static inline uint64_t get_u64(const uint8_t *tab)
{
uint64_t v;
memcpy(&v, tab, sizeof(v));
return v;
return ((const struct packed_u64 *)tab)->v;
}
static inline int64_t get_i64(const uint8_t *tab)
{
int64_t v;
memcpy(&v, tab, sizeof(v));
return v;
return (int64_t)((const struct packed_u64 *)tab)->v;
}
static inline void put_u64(uint8_t *tab, uint64_t val)
{
memcpy(tab, &val, sizeof(val));
((struct packed_u64 *)tab)->v = val;
}
static inline uint32_t get_u32(const uint8_t *tab)
{
uint32_t v;
memcpy(&v, tab, sizeof(v));
return v;
return ((const struct packed_u32 *)tab)->v;
}
static inline int32_t get_i32(const uint8_t *tab)
{
int32_t v;
memcpy(&v, tab, sizeof(v));
return v;
return (int32_t)((const struct packed_u32 *)tab)->v;
}
static inline void put_u32(uint8_t *tab, uint32_t val)
{
memcpy(tab, &val, sizeof(val));
((struct packed_u32 *)tab)->v = val;
}
static inline uint32_t get_u16(const uint8_t *tab)
{
uint16_t v;
memcpy(&v, tab, sizeof(v));
return v;
return ((const struct packed_u16 *)tab)->v;
}
static inline int32_t get_i16(const uint8_t *tab)
{
int16_t v;
memcpy(&v, tab, sizeof(v));
return v;
return (int16_t)((const struct packed_u16 *)tab)->v;
}
static inline void put_u16(uint8_t *tab, uint16_t val)
{
memcpy(tab, &val, sizeof(val));
((struct packed_u16 *)tab)->v = val;
}
static inline uint32_t get_u8(const uint8_t *tab)
@ -314,22 +225,17 @@ static inline void put_u8(uint8_t *tab, uint8_t val)
*tab = val;
}
#ifndef bswap16
static inline uint16_t bswap16(uint16_t x)
{
return (x >> 8) | (x << 8);
}
#endif
#ifndef bswap32
static inline uint32_t bswap32(uint32_t v)
{
return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) |
((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24);
}
#endif
#ifndef bswap64
static inline uint64_t bswap64(uint64_t v)
{
return ((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) |
@ -341,7 +247,6 @@ static inline uint64_t bswap64(uint64_t v)
((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) |
((v & ((uint64_t)0xff << (0 * 8))) << (7 * 8));
}
#endif
static inline void inplace_bswap16(uint8_t *tab) {
put_u16(tab, bswap16(get_u16(tab)));
@ -366,8 +271,8 @@ typedef struct DynBuf {
void dbuf_init(DynBuf *s);
void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func);
int dbuf_realloc(DynBuf *s, size_t new_size);
int dbuf_write(DynBuf *s, size_t offset, const void *data, size_t len);
int dbuf_put(DynBuf *s, const void *data, size_t len);
int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len);
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len);
int dbuf_put_self(DynBuf *s, size_t offset, size_t len);
int dbuf_putc(DynBuf *s, uint8_t c);
int dbuf_putstr(DynBuf *s, const char *str);
@ -384,7 +289,7 @@ static inline int dbuf_put_u64(DynBuf *s, uint64_t val)
return dbuf_put(s, (uint8_t *)&val, 8);
}
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
FORMAT_STRING(const char *fmt), ...);
const char *fmt, ...);
void dbuf_free(DynBuf *s);
static inline BOOL dbuf_error(DynBuf *s) {
return s->error;
@ -394,50 +299,19 @@ static inline void dbuf_set_error(DynBuf *s)
s->error = TRUE;
}
/*---- UTF-8 and UTF-16 handling ----*/
#define UTF8_CHAR_LEN_MAX 6
#define UTF8_CHAR_LEN_MAX 4
enum {
UTF8_PLAIN_ASCII = 0, // 7-bit ASCII plain text
UTF8_NON_ASCII = 1, // has non ASCII code points (8-bit or more)
UTF8_HAS_16BIT = 2, // has 16-bit code points
UTF8_HAS_NON_BMP1 = 4, // has non-BMP1 code points, needs UTF-16 surrogate pairs
UTF8_HAS_ERRORS = 8, // has encoding errors
};
int utf8_scan(const char *buf, size_t len, size_t *plen);
size_t utf8_encode_len(uint32_t c);
size_t utf8_encode(uint8_t *buf, uint32_t c);
uint32_t utf8_decode_len(const uint8_t *p, size_t max_len, const uint8_t **pp);
uint32_t utf8_decode(const uint8_t *p, const uint8_t **pp);
size_t utf8_decode_buf8(uint8_t *dest, size_t dest_len, const char *src, size_t src_len);
size_t utf8_decode_buf16(uint16_t *dest, size_t dest_len, const char *src, size_t src_len);
size_t utf8_encode_buf8(char *dest, size_t dest_len, const uint8_t *src, size_t src_len);
size_t utf8_encode_buf16(char *dest, size_t dest_len, const uint16_t *src, size_t src_len);
static inline BOOL is_surrogate(uint32_t c)
{
return (c >> 11) == (0xD800 >> 11); // 0xD800-0xDFFF
}
int unicode_to_utf8(uint8_t *buf, unsigned int c);
int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp);
static inline BOOL is_hi_surrogate(uint32_t c)
{
return (c >> 10) == (0xD800 >> 10); // 0xD800-0xDBFF
return 54 == (c >> 10); // 0xD800-0xDBFF
}
static inline BOOL is_lo_surrogate(uint32_t c)
{
return (c >> 10) == (0xDC00 >> 10); // 0xDC00-0xDFFF
}
static inline uint32_t get_hi_surrogate(uint32_t c)
{
return (c >> 10) - (0x10000 >> 10) + 0xD800;
}
static inline uint32_t get_lo_surrogate(uint32_t c)
{
return (c & 0x3FF) | 0xDC00;
return 55 == (c >> 10); // 0xDC00-0xDFFF
}
static inline uint32_t from_surrogate(uint32_t hi, uint32_t lo)
@ -457,24 +331,6 @@ static inline int from_hex(int c)
return -1;
}
static inline uint8_t is_upper_ascii(uint8_t c) {
return c >= 'A' && c <= 'Z';
}
static inline uint8_t to_upper_ascii(uint8_t c) {
return c >= 'a' && c <= 'z' ? c - 'a' + 'A' : c;
}
extern char const digits36[36];
size_t u32toa(char buf[minimum_length(11)], uint32_t n);
size_t i32toa(char buf[minimum_length(12)], int32_t n);
size_t u64toa(char buf[minimum_length(21)], uint64_t n);
size_t i64toa(char buf[minimum_length(22)], int64_t n);
size_t u32toa_radix(char buf[minimum_length(33)], uint32_t n, unsigned int base);
size_t i32toa_radix(char buf[minimum_length(34)], int32_t n, unsigned base);
size_t u64toa_radix(char buf[minimum_length(65)], uint64_t n, unsigned int base);
size_t i64toa_radix(char buf[minimum_length(66)], int64_t n, unsigned int base);
void rqsort(void *base, size_t nmemb, size_t size,
int (*cmp)(const void *, const void *, void *),
void *arg);
@ -488,43 +344,11 @@ static inline size_t js__malloc_usable_size(const void *ptr)
return malloc_size(ptr);
#elif defined(_WIN32)
return _msize((void *)ptr);
#elif defined(__linux__) || defined(__ANDROID__) || defined(__CYGWIN__) || defined(__FreeBSD__)
#elif defined(__linux__) || defined(__FreeBSD__)
return malloc_usable_size((void *)ptr);
#else
return 0;
#endif
}
/* Cross-platform threading APIs. */
#if !defined(EMSCRIPTEN) && !defined(__wasi__)
#if defined(_WIN32)
#define JS_ONCE_INIT INIT_ONCE_STATIC_INIT
typedef INIT_ONCE js_once_t;
typedef CRITICAL_SECTION js_mutex_t;
typedef CONDITION_VARIABLE js_cond_t;
#else
#define JS_ONCE_INIT PTHREAD_ONCE_INIT
typedef pthread_once_t js_once_t;
typedef pthread_mutex_t js_mutex_t;
typedef pthread_cond_t js_cond_t;
#endif
void js_once(js_once_t *guard, void (*callback)(void));
void js_mutex_init(js_mutex_t *mutex);
void js_mutex_destroy(js_mutex_t *mutex);
void js_mutex_lock(js_mutex_t *mutex);
void js_mutex_unlock(js_mutex_t *mutex);
void js_cond_init(js_cond_t *cond);
void js_cond_destroy(js_cond_t *cond);
void js_cond_signal(js_cond_t *cond);
void js_cond_broadcast(js_cond_t *cond);
void js_cond_wait(js_cond_t *cond, js_mutex_t *mutex);
int js_cond_timedwait(js_cond_t *cond, js_mutex_t *mutex, uint64_t timeout);
#endif /* !defined(EMSCRIPTEN) && !defined(__wasi__) */
#endif /* CUTILS_H */

View file

@ -330,11 +330,6 @@ optional properties:
@item backtrace_barrier
Boolean (default = false). If true, error backtraces do not list the
stack frames below the evalScript.
@item async
Boolean (default = false). If true, @code{await} is accepted in the
script and a promise is returned. The promise is resolved with an
object whose @code{value} property holds the value returned by the
script.
@end table
@item loadScript(filename)
@ -722,12 +717,6 @@ write_fd]} or null in case of error.
@item sleep(delay_ms)
Sleep during @code{delay_ms} milliseconds.
@item sleepAsync(delay_ms)
Asynchronouse sleep during @code{delay_ms} milliseconds. Returns a promise. Example:
@example
await os.sleepAsync(500);
@end example
@item setTimeout(func, delay)
Call the function @code{func} after @code{delay} ms. Return a handle
to the timer.

View file

@ -35,8 +35,8 @@ static int fib(int n)
return fib(n - 1) + fib(n - 2);
}
static JSValue js_fib(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
static JSValue js_fib(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
int n, res;
if (JS_ToInt32(ctx, &n, argv[0]))

View file

@ -43,8 +43,8 @@ static void js_point_finalizer(JSRuntime *rt, JSValue val)
}
static JSValue js_point_ctor(JSContext *ctx,
JSValue new_target,
int argc, JSValue *argv)
JSValueConst new_target,
int argc, JSValueConst *argv)
{
JSPointData *s;
JSValue obj = JS_UNDEFINED;
@ -74,7 +74,7 @@ static JSValue js_point_ctor(JSContext *ctx,
return JS_EXCEPTION;
}
static JSValue js_point_get_xy(JSContext *ctx, JSValue this_val, int magic)
static JSValue js_point_get_xy(JSContext *ctx, JSValueConst this_val, int magic)
{
JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id);
if (!s)
@ -85,7 +85,7 @@ static JSValue js_point_get_xy(JSContext *ctx, JSValue this_val, int magic)
return JS_NewInt32(ctx, s->y);
}
static JSValue js_point_set_xy(JSContext *ctx, JSValue this_val, JSValue val, int magic)
static JSValue js_point_set_xy(JSContext *ctx, JSValueConst this_val, JSValue val, int magic)
{
JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id);
int v;
@ -100,8 +100,8 @@ static JSValue js_point_set_xy(JSContext *ctx, JSValue this_val, JSValue val, in
return JS_UNDEFINED;
}
static JSValue js_point_norm(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
static JSValue js_point_norm(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id);
if (!s)

View file

@ -1,82 +0,0 @@
/* File generated automatically by the QuickJS-ng compiler. */
#include "quickjs-libc.h"
const uint32_t qjsc_function_source_size = 384;
const uint8_t qjsc_function_source[384] = {
0x0c, 0x06, 0x0c, 0x61, 0x63, 0x74, 0x75, 0x61,
0x6c, 0x02, 0x66, 0x30, 0x74, 0x65, 0x73, 0x74,
0x73, 0x2f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x2e, 0x6a, 0x73, 0x0c, 0x65, 0x78, 0x70,
0x65, 0x63, 0x74, 0x14, 0x75, 0x73, 0x65, 0x20,
0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x34, 0x66,
0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
0x66, 0x28, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65,
0x74, 0x75, 0x72, 0x6e, 0x20, 0x34, 0x32, 0x20,
0x7d, 0x0c, 0x00, 0xfa, 0x01, 0x9e, 0x01, 0x00,
0x06, 0x00, 0x03, 0x00, 0x01, 0xa0, 0x01, 0x06,
0xa0, 0x01, 0x00, 0x00, 0x00, 0xb2, 0x03, 0x02,
0x00, 0x30, 0xb4, 0x03, 0x04, 0x00, 0x70, 0xb2,
0x03, 0x04, 0x03, 0x70, 0x10, 0x00, 0x01, 0x00,
0xe0, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x43, 0xfa,
0x01, 0xb4, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x03, 0x00, 0xbb, 0x2a, 0x28, 0xb6, 0x03,
0x03, 0x01, 0x04, 0x02, 0x1e, 0x0c, 0x0e, 0x1a,
0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x20, 0x66, 0x28, 0x29, 0x20, 0x7b, 0x20, 0x72,
0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x34, 0x32,
0x20, 0x7d, 0x0c, 0x03, 0xc1, 0x05, 0x08, 0xc1,
0x04, 0x3f, 0xdc, 0x00, 0x00, 0x00, 0x80, 0x3f,
0xda, 0x00, 0x00, 0x00, 0x40, 0x3e, 0xdc, 0x00,
0x00, 0x00, 0x80, 0xbe, 0x00, 0x40, 0xda, 0x00,
0x00, 0x00, 0x00, 0x04, 0xdd, 0x00, 0x00, 0x00,
0xc8, 0x04, 0xde, 0x00, 0x00, 0x00, 0x3a, 0xdc,
0x00, 0x00, 0x00, 0x61, 0x01, 0x00, 0x38, 0xda,
0x00, 0x00, 0x00, 0x42, 0x36, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0xc9, 0x06, 0xc8, 0x62, 0x01,
0x00, 0x38, 0xdc, 0x00, 0x00, 0x00, 0xaf, 0xe9,
0x0b, 0x38, 0x92, 0x00, 0x00, 0x00, 0x62, 0x01,
0x00, 0xee, 0x2f, 0x61, 0x03, 0x00, 0x61, 0x02,
0x00, 0x38, 0x39, 0x00, 0x00, 0x00, 0x38, 0xdc,
0x00, 0x00, 0x00, 0x04, 0xda, 0x00, 0x00, 0x00,
0x9d, 0x31, 0x01, 0x00, 0x04, 0x00, 0xca, 0x62,
0x02, 0x00, 0x42, 0x36, 0x00, 0x00, 0x00, 0x24,
0x00, 0x00, 0xcb, 0x06, 0xc8, 0x62, 0x03, 0x00,
0x38, 0xdc, 0x00, 0x00, 0x00, 0xaf, 0xe9, 0x0b,
0x38, 0x92, 0x00, 0x00, 0x00, 0x62, 0x03, 0x00,
0xee, 0x2f, 0x68, 0x03, 0x00, 0x68, 0x02, 0x00,
0xc4, 0x28, 0xb6, 0x03, 0x01, 0x01, 0x28, 0x60,
0x01, 0x49, 0x02, 0x21, 0x1a, 0x1b, 0x04, 0x1e,
0x1d, 0x12, 0x26, 0x49, 0x1d, 0x0c, 0x06, 0x11,
0x18, 0x2a, 0x1c, 0x37, 0x41, 0x21, 0x1c, 0x34,
0x18, 0x1b, 0x04, 0x26, 0x11, 0x3f, 0x1d, 0x0c,
0x06, 0x11, 0x18, 0x2a, 0x1c, 0x53, 0x41, 0x00,
};
static JSContext *JS_NewCustomContext(JSRuntime *rt)
{
JSContext *ctx = JS_NewContext(rt);
if (!ctx)
return NULL;
return ctx;
}
int main(int argc, char **argv)
{
JSRuntime *rt;
JSContext *ctx;
rt = JS_NewRuntime();
js_std_set_worker_new_context_func(JS_NewCustomContext);
js_std_init_handlers(rt);
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
ctx = JS_NewCustomContext(rt);
js_std_add_helpers(ctx, argc, argv);
js_std_eval_binary(ctx, qjsc_function_source, qjsc_function_source_size, 0);
js_std_loop(ctx);
JS_FreeContext(ctx);
js_std_free_handlers(rt);
JS_FreeRuntime(rt);
return 0;
}

View file

@ -1,46 +0,0 @@
/* File generated automatically by the QuickJS-ng compiler. */
#include "quickjs-libc.h"
const uint32_t qjsc_hello_size = 89;
const uint8_t qjsc_hello[89] = {
0x0c, 0x04, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x6f,
0x6c, 0x65, 0x06, 0x6c, 0x6f, 0x67, 0x16, 0x48,
0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72,
0x6c, 0x64, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70,
0x6c, 0x65, 0x73, 0x2f, 0x68, 0x65, 0x6c, 0x6c,
0x6f, 0x2e, 0x6a, 0x73, 0x0c, 0x00, 0xfa, 0x00,
0x9e, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00,
0x14, 0x01, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x38,
0xd9, 0x00, 0x00, 0x00, 0x42, 0xda, 0x00, 0x00,
0x00, 0x04, 0xdb, 0x00, 0x00, 0x00, 0x24, 0x01,
0x00, 0xcc, 0x28, 0xb8, 0x03, 0x01, 0x01, 0x00,
0x00,
};
static JSContext *JS_NewCustomContext(JSRuntime *rt)
{
JSContext *ctx = JS_NewContext(rt);
if (!ctx)
return NULL;
return ctx;
}
int main(int argc, char **argv)
{
JSRuntime *rt;
JSContext *ctx;
rt = JS_NewRuntime();
js_std_set_worker_new_context_func(JS_NewCustomContext);
js_std_init_handlers(rt);
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
ctx = JS_NewCustomContext(rt);
js_std_add_helpers(ctx, argc, argv);
js_std_eval_binary(ctx, qjsc_hello, qjsc_hello_size, 0);
js_std_loop(ctx);
JS_FreeContext(ctx);
js_std_free_handlers(rt);
JS_FreeRuntime(rt);
return 0;
}

View file

@ -1,102 +0,0 @@
/* File generated automatically by the QuickJS-ng compiler. */
#include "quickjs-libc.h"
const uint32_t qjsc_fib_module_size = 311;
const uint8_t qjsc_fib_module[311] = {
0x0c, 0x03, 0x2c, 0x65, 0x78, 0x61, 0x6d, 0x70,
0x6c, 0x65, 0x73, 0x2f, 0x66, 0x69, 0x62, 0x5f,
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x6a,
0x73, 0x06, 0x66, 0x69, 0x62, 0x02, 0x6e, 0x0d,
0xb2, 0x03, 0x00, 0x01, 0x00, 0x00, 0xb4, 0x03,
0x00, 0x00, 0x00, 0x0c, 0x20, 0xfa, 0x01, 0x9e,
0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x09,
0x00, 0xb4, 0x03, 0x00, 0x01, 0x0c, 0x43, 0xfa,
0x01, 0xb4, 0x03, 0x01, 0x00, 0x01, 0x04, 0x01,
0x00, 0x1a, 0x01, 0xb6, 0x03, 0x00, 0x01, 0x00,
0xb4, 0x03, 0x00, 0x00, 0xd0, 0xb3, 0xa7, 0xe9,
0x03, 0xb3, 0x28, 0xd0, 0xb4, 0xac, 0xe9, 0x03,
0xb4, 0x28, 0xdc, 0xd0, 0xb4, 0x9e, 0xee, 0xdc,
0xd0, 0xb5, 0x9e, 0xee, 0x9d, 0x28, 0xb2, 0x03,
0x02, 0x08, 0x20, 0x04, 0x00, 0x07, 0x06, 0x07,
0x06, 0x12, 0x09, 0x08, 0x07, 0x07, 0x10, 0x07,
0x06, 0x07, 0x06, 0x12, 0x13, 0x08, 0x07, 0x08,
0x16, 0x0c, 0x0c, 0x07, 0x04, 0x0c, 0x0a, 0x0c,
0x0c, 0x07, 0x04, 0x8d, 0x01, 0x66, 0x75, 0x6e,
0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 0x69,
0x62, 0x28, 0x6e, 0x29, 0x0a, 0x7b, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6e,
0x20, 0x3c, 0x3d, 0x20, 0x30, 0x29, 0x0a, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72,
0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 0x3b,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73,
0x65, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6e, 0x20,
0x3d, 0x3d, 0x20, 0x31, 0x29, 0x0a, 0x20, 0x20,
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 0x65,
0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x3b, 0x0a,
0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 0x65,
0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20,
0x66, 0x69, 0x62, 0x28, 0x6e, 0x20, 0x2d, 0x20,
0x31, 0x29, 0x20, 0x2b, 0x20, 0x66, 0x69, 0x62,
0x28, 0x6e, 0x20, 0x2d, 0x20, 0x32, 0x29, 0x3b,
0x0a, 0x7d, 0x08, 0xe9, 0x05, 0xbe, 0x00, 0xe0,
0x29, 0x06, 0x2e, 0xb2, 0x03, 0x01, 0x01, 0x06,
0x01, 0x01, 0x00, 0x07, 0x14, 0x02, 0x00,
};
const uint32_t qjsc_hello_module_size = 178;
const uint8_t qjsc_hello_module[178] = {
0x0c, 0x07, 0x30, 0x65, 0x78, 0x61, 0x6d, 0x70,
0x6c, 0x65, 0x73, 0x2f, 0x68, 0x65, 0x6c, 0x6c,
0x6f, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
0x2e, 0x6a, 0x73, 0x1e, 0x2e, 0x2f, 0x66, 0x69,
0x62, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
0x2e, 0x6a, 0x73, 0x06, 0x66, 0x69, 0x62, 0x0e,
0x63, 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x06,
0x6c, 0x6f, 0x67, 0x16, 0x48, 0x65, 0x6c, 0x6c,
0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x10,
0x66, 0x69, 0x62, 0x28, 0x31, 0x30, 0x29, 0x3d,
0x0d, 0xb2, 0x03, 0x01, 0xb4, 0x03, 0x00, 0x00,
0x01, 0x00, 0xb6, 0x03, 0x00, 0x00, 0x0c, 0x20,
0xfa, 0x01, 0x9e, 0x01, 0x00, 0x00, 0x00, 0x05,
0x01, 0x00, 0x32, 0x00, 0xb6, 0x03, 0x00, 0x0c,
0x08, 0xe9, 0x02, 0x29, 0x38, 0xdc, 0x00, 0x00,
0x00, 0x42, 0xdd, 0x00, 0x00, 0x00, 0x04, 0xde,
0x00, 0x00, 0x00, 0x24, 0x01, 0x00, 0x0e, 0x38,
0xdc, 0x00, 0x00, 0x00, 0x42, 0xdd, 0x00, 0x00,
0x00, 0x04, 0xdf, 0x00, 0x00, 0x00, 0x65, 0x00,
0x00, 0xbb, 0x0a, 0xee, 0x24, 0x02, 0x00, 0x0e,
0x06, 0x2e, 0xb2, 0x03, 0x01, 0x01, 0x0a, 0x01,
0x01, 0x00, 0x04, 0x0a, 0x02, 0x62, 0x00, 0x4d,
0x30, 0x00,
};
static JSContext *JS_NewCustomContext(JSRuntime *rt)
{
JSContext *ctx = JS_NewContext(rt);
if (!ctx)
return NULL;
js_std_eval_binary(ctx, qjsc_fib_module, qjsc_fib_module_size, 1);
return ctx;
}
int main(int argc, char **argv)
{
JSRuntime *rt;
JSContext *ctx;
rt = JS_NewRuntime();
js_std_set_worker_new_context_func(JS_NewCustomContext);
js_std_init_handlers(rt);
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
ctx = JS_NewCustomContext(rt);
js_std_add_helpers(ctx, argc, argv);
js_std_eval_binary(ctx, qjsc_hello_module, qjsc_hello_module_size, 0);
js_std_loop(ctx);
JS_FreeContext(ctx);
js_std_free_handlers(rt);
JS_FreeRuntime(rt);
return 0;
}

2847
gen/repl.c

File diff suppressed because it is too large Load diff

View file

@ -1,59 +0,0 @@
/* File generated automatically by the QuickJS-ng compiler. */
#include "quickjs-libc.h"
const uint32_t qjsc_test_fib_size = 167;
const uint8_t qjsc_test_fib[167] = {
0x0c, 0x07, 0x28, 0x65, 0x78, 0x61, 0x6d, 0x70,
0x6c, 0x65, 0x73, 0x2f, 0x74, 0x65, 0x73, 0x74,
0x5f, 0x66, 0x69, 0x62, 0x2e, 0x6a, 0x73, 0x10,
0x2e, 0x2f, 0x66, 0x69, 0x62, 0x2e, 0x73, 0x6f,
0x06, 0x66, 0x69, 0x62, 0x0e, 0x63, 0x6f, 0x6e,
0x73, 0x6f, 0x6c, 0x65, 0x06, 0x6c, 0x6f, 0x67,
0x16, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57,
0x6f, 0x72, 0x6c, 0x64, 0x10, 0x66, 0x69, 0x62,
0x28, 0x31, 0x30, 0x29, 0x3d, 0x0d, 0xb2, 0x03,
0x01, 0xb4, 0x03, 0x00, 0x00, 0x01, 0x00, 0xb6,
0x03, 0x00, 0x00, 0x0c, 0x20, 0xfa, 0x01, 0x9e,
0x01, 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x32,
0x00, 0xb6, 0x03, 0x00, 0x0c, 0x08, 0xe9, 0x02,
0x29, 0x38, 0xdc, 0x00, 0x00, 0x00, 0x42, 0xdd,
0x00, 0x00, 0x00, 0x04, 0xde, 0x00, 0x00, 0x00,
0x24, 0x01, 0x00, 0x0e, 0x38, 0xdc, 0x00, 0x00,
0x00, 0x42, 0xdd, 0x00, 0x00, 0x00, 0x04, 0xdf,
0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0xbb, 0x0a,
0xee, 0x24, 0x02, 0x00, 0x0e, 0x06, 0x2e, 0xb2,
0x03, 0x01, 0x01, 0x0a, 0x01, 0x01, 0x00, 0x04,
0x0a, 0x02, 0x62, 0x00, 0x4d, 0x30, 0x00,
};
static JSContext *JS_NewCustomContext(JSRuntime *rt)
{
JSContext *ctx = JS_NewContext(rt);
if (!ctx)
return NULL;
{
extern JSModuleDef *js_init_module_fib(JSContext *ctx, const char *name);
js_init_module_fib(ctx, "examples/fib.so");
}
return ctx;
}
int main(int argc, char **argv)
{
JSRuntime *rt;
JSContext *ctx;
rt = JS_NewRuntime();
js_std_set_worker_new_context_func(JS_NewCustomContext);
js_std_init_handlers(rt);
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
ctx = JS_NewCustomContext(rt);
js_std_add_helpers(ctx, argc, argv);
js_std_eval_binary(ctx, qjsc_test_fib, qjsc_test_fib_size, 0);
js_std_loop(ctx);
JS_FreeContext(ctx);
js_std_free_handlers(rt);
JS_FreeRuntime(rt);
return 0;
}

View file

@ -63,15 +63,13 @@ typedef enum {
#define TMP_BUF_SIZE 128
// invariant: is_unicode ^ unicode_sets (or neither, but not both)
typedef struct {
DynBuf byte_code;
const uint8_t *buf_ptr;
const uint8_t *buf_end;
const uint8_t *buf_start;
int re_flags;
BOOL is_unicode;
BOOL unicode_sets;
BOOL is_utf16;
BOOL ignore_case;
BOOL dotall;
int capture_count;
@ -103,11 +101,10 @@ static const REOpCode reopcode_info[REOP_COUNT] = {
};
#define RE_HEADER_FLAGS 0
#define RE_HEADER_CAPTURE_COUNT 2
#define RE_HEADER_STACK_SIZE 3
#define RE_HEADER_BYTECODE_LEN 4
#define RE_HEADER_CAPTURE_COUNT 1
#define RE_HEADER_STACK_SIZE 2
#define RE_HEADER_LEN 8
#define RE_HEADER_LEN 7
static inline int is_digit(int c) {
return c >= '0' && c <= '9';
@ -124,11 +121,11 @@ static int dbuf_insert(DynBuf *s, int pos, int len)
}
/* canonicalize with the specific JS regexp rules */
static uint32_t lre_canonicalize(uint32_t c, BOOL is_unicode)
static uint32_t lre_canonicalize(uint32_t c, BOOL is_utf16)
{
uint32_t res[LRE_CC_RES_LEN_MAX];
int len;
if (is_unicode) {
if (is_utf16) {
if (likely(c < 128)) {
if (c >= 'A' && c <= 'Z')
c = c - 'A' + 'a';
@ -282,16 +279,16 @@ static __maybe_unused void lre_dump_bytecode(const uint8_t *buf,
assert(buf_len >= RE_HEADER_LEN);
re_flags = lre_get_flags(buf);
bc_len = get_u32(buf + RE_HEADER_BYTECODE_LEN);
re_flags= buf[0];
bc_len = get_u32(buf + 3);
assert(bc_len + RE_HEADER_LEN <= buf_len);
printf("flags: 0x%x capture_count=%d stack_size=%d\n",
re_flags, buf[RE_HEADER_CAPTURE_COUNT], buf[RE_HEADER_STACK_SIZE]);
re_flags, buf[1], buf[2]);
if (re_flags & LRE_FLAG_NAMED_GROUPS) {
const char *p;
p = (char *)buf + RE_HEADER_LEN + bc_len;
printf("named groups: ");
for(i = 1; i < buf[RE_HEADER_CAPTURE_COUNT]; i++) {
for(i = 1; i < buf[1]; i++) {
if (i != 1)
printf(",");
printf("<%s>", p);
@ -712,7 +709,7 @@ static int parse_unicode_property(REParseState *s, CharRange *cr,
static int get_class_atom(REParseState *s, CharRange *cr,
const uint8_t **pp, BOOL inclass)
{
const uint8_t *p, *p_next;
const uint8_t *p;
uint32_t c;
int ret;
@ -753,10 +750,10 @@ static int get_class_atom(REParseState *s, CharRange *cr,
if ((c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(((c >= '0' && c <= '9') || c == '_') &&
inclass && !s->is_unicode)) { /* Annex B.1.4 */
inclass && !s->is_utf16)) { /* Annex B.1.4 */
c &= 0x1f;
p++;
} else if (s->is_unicode) {
} else if (s->is_utf16) {
goto invalid_escape;
} else {
/* otherwise return '\' and 'c' */
@ -766,7 +763,7 @@ static int get_class_atom(REParseState *s, CharRange *cr,
break;
case 'p':
case 'P':
if (s->is_unicode) {
if (s->is_utf16) {
if (parse_unicode_property(s, cr, &p, (c == 'P')))
return -1;
c = CLASS_RANGE_BASE;
@ -775,17 +772,14 @@ static int get_class_atom(REParseState *s, CharRange *cr,
/* fall thru */
default:
p--;
ret = lre_parse_escape(&p, s->is_unicode * 2);
ret = lre_parse_escape(&p, s->is_utf16 * 2);
if (ret >= 0) {
c = ret;
} else {
if (ret == -2 && *p != '\0' && strchr("^$\\.*+?()[]{}|/", *p)) {
/* always valid to escape these characters */
goto normal_char;
} else if (s->is_unicode) {
// special case: allowed inside [] but not outside
if (ret == -2 && *p == '-' && inclass)
goto normal_char;
} else if (s->is_utf16) {
invalid_escape:
return re_parse_error(s, "invalid escape sequence in regular expression");
} else {
@ -804,18 +798,15 @@ static int get_class_atom(REParseState *s, CharRange *cr,
/* fall thru */
default:
normal_char:
p++;
if (c >= 0x80) {
c = utf8_decode(p - 1, &p_next);
if (p_next == p)
return re_parse_error(s, "invalid UTF-8 sequence");
p = p_next;
if (c > 0xFFFF && !s->is_unicode) {
// TODO(chqrlie): should handle non BMP-1 code points in
// the calling function and no require the source string
// to be CESU-8 encoded if not s->is_unicode
/* normal char */
if (c >= 128) {
c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p);
if ((unsigned)c > 0xffff && !s->is_utf16) {
/* XXX: should handle non BMP-1 code points */
return re_parse_error(s, "malformed unicode char");
}
} else {
p++;
}
break;
}
@ -861,8 +852,6 @@ static int re_emit_range(REParseState *s, const CharRange *cr)
return 0;
}
// s->unicode turns patterns like []] into syntax errors
// s->unicode_sets turns more patterns into errors, like [a-] or [[]
static int re_parse_char_class(REParseState *s, const uint8_t **pp)
{
const uint8_t *p;
@ -874,47 +863,21 @@ static int re_parse_char_class(REParseState *s, const uint8_t **pp)
cr_init(cr, s->opaque, lre_realloc);
p = *pp;
p++; /* skip '[' */
if (s->unicode_sets) {
static const char verboten[] =
"()[{}/-|" "\0"
"&&!!##$$%%**++,,..::;;<<==>>??@@``~~" "\0"
"^^^_^^";
const char *s = verboten;
int n = 1;
do {
if (!memcmp(s, p, n))
if (p[n] == ']')
goto invalid_class_range;
s += n;
if (!*s) {
s++;
n++;
}
} while (n < 4);
}
invert = FALSE;
if (*p == '^') {
p++;
invert = TRUE;
}
for(;;) {
if (*p == ']')
break;
c1 = get_class_atom(s, cr1, &p, TRUE);
if ((int)c1 < 0)
goto fail;
if (*p == '-' && p[1] == ']' && s->unicode_sets) {
if (c1 >= CLASS_RANGE_BASE)
cr_free(cr1);
goto invalid_class_range;
}
if (*p == '-' && p[1] != ']') {
const uint8_t *p0 = p + 1;
if (c1 >= CLASS_RANGE_BASE) {
if (s->is_unicode) {
if (s->is_utf16) {
cr_free(cr1);
goto invalid_class_range;
}
@ -926,7 +889,7 @@ static int re_parse_char_class(REParseState *s, const uint8_t **pp)
goto fail;
if (c2 >= CLASS_RANGE_BASE) {
cr_free(cr1);
if (s->is_unicode) {
if (s->is_utf16) {
goto invalid_class_range;
}
/* Annex B: match '-' character */
@ -1108,35 +1071,35 @@ static int re_is_simple_quantifier(const uint8_t *bc_buf, int bc_buf_len)
/* '*pp' is the first char after '<' */
static int re_parse_group_name(char *buf, int buf_size, const uint8_t **pp)
{
const uint8_t *p, *p_next;
const uint8_t *p, *p1;
uint32_t c, d;
char *q;
p = *pp;
q = buf;
for(;;) {
c = *p++;
c = *p;
if (c == '\\') {
p++;
if (*p != 'u')
return -1;
c = lre_parse_escape(&p, 2); // accept surrogate pairs
if ((int)c < 0)
return -1;
} else if (c == '>') {
break;
} else if (c >= 0x80) {
c = utf8_decode(p - 1, &p_next);
if (p_next == p)
return -1;
p = p_next;
} else if (c >= 128) {
c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p);
if (is_hi_surrogate(c)) {
d = utf8_decode(p, &p_next);
d = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p1);
if (is_lo_surrogate(d)) {
c = from_surrogate(c, d);
p = p_next;
p = p1;
}
}
} else {
p++;
}
if (c > 0x10FFFF)
return -1;
if (q == buf) {
if (!lre_js_is_ident_first(c))
return -1;
@ -1146,15 +1109,16 @@ static int re_parse_group_name(char *buf, int buf_size, const uint8_t **pp)
}
if ((q - buf + UTF8_CHAR_LEN_MAX + 1) > buf_size)
return -1;
if (c < 0x80) {
if (c < 128) {
*q++ = c;
} else {
q += utf8_encode((uint8_t*)q, c);
q += unicode_to_utf8((uint8_t*)q, c);
}
}
if (q == buf)
return -1;
*q = '\0';
p++;
*pp = p;
return 0;
}
@ -1283,7 +1247,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
re_emit_op(s, REOP_prev);
break;
case '{':
if (s->is_unicode) {
if (s->is_utf16) {
return re_parse_error(s, "syntax error");
} else if (!is_digit(p[1])) {
/* Annex B: we accept '{' not followed by digits as a
@ -1335,7 +1299,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
lookahead:
/* Annex B allows lookahead to be used as an atom for
the quantifiers */
if (!s->is_unicode && !is_backward_lookahead) {
if (!s->is_utf16 && !is_backward_lookahead) {
last_atom_start = s->byte_code.size;
last_capture_count = s->capture_count;
}
@ -1411,7 +1375,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
/* annex B: we tolerate invalid group names in non
unicode mode if there is no named capture
definition */
if (s->is_unicode || re_has_named_captures(s))
if (s->is_utf16 || re_has_named_captures(s))
return re_parse_error(s, "expecting group name");
else
goto parse_class_atom;
@ -1419,7 +1383,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
p1 += 3;
if (re_parse_group_name(s->u.tmp_buf, sizeof(s->u.tmp_buf),
&p1)) {
if (s->is_unicode || re_has_named_captures(s))
if (s->is_utf16 || re_has_named_captures(s))
return re_parse_error(s, "invalid group name");
else
goto parse_class_atom;
@ -1430,7 +1394,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
after (inefficient, but hopefully not common */
c = re_parse_captures(s, &dummy_res, s->u.tmp_buf);
if (c < 0) {
if (s->is_unicode || re_has_named_captures(s))
if (s->is_utf16 || re_has_named_captures(s))
return re_parse_error(s, "group name not defined");
else
goto parse_class_atom;
@ -1442,7 +1406,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
case '0':
p += 2;
c = 0;
if (s->is_unicode) {
if (s->is_utf16) {
if (is_digit(*p)) {
return re_parse_error(s, "invalid decimal escape in regular expression");
}
@ -1464,7 +1428,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
c = parse_digits(&p, FALSE);
if (c < 0 || (c >= s->capture_count && c >= re_count_captures(s))) {
if (!s->is_unicode) {
if (!s->is_utf16) {
/* Annex B.1.4: accept legacy octal */
p = q;
if (*p <= '7') {
@ -1506,7 +1470,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
break;
case ']':
case '}':
if (s->is_unicode)
if (s->is_utf16)
return re_parse_error(s, "syntax error");
goto parse_class_atom;
default:
@ -1528,7 +1492,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
return -1;
} else {
if (s->ignore_case)
c = lre_canonicalize(c, s->is_unicode);
c = lre_canonicalize(c, s->is_utf16);
if (c <= 0x7f)
re_emit_op_u8(s, REOP_char8, c);
else if (c <= 0xffff)
@ -1566,7 +1530,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
/* As an extension (see ES6 annex B), we accept '{' not
followed by digits as a normal atom */
if (!is_digit(p[1])) {
if (s->is_unicode)
if (s->is_utf16)
goto invalid_quant_count;
break;
}
@ -1585,7 +1549,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
quant_max = INT32_MAX; /* infinity */
}
}
if (*p != '}' && !s->is_unicode) {
if (*p != '}' && !s->is_utf16) {
/* Annex B: normal atom if invalid '{' syntax */
p = p1;
break;
@ -1874,11 +1838,10 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
s->buf_end = s->buf_ptr + buf_len;
s->buf_start = s->buf_ptr;
s->re_flags = re_flags;
s->is_unicode = ((re_flags & LRE_FLAG_UNICODE) != 0);
s->is_utf16 = ((re_flags & LRE_FLAG_UTF16) != 0);
is_sticky = ((re_flags & LRE_FLAG_STICKY) != 0);
s->ignore_case = ((re_flags & LRE_FLAG_IGNORECASE) != 0);
s->dotall = ((re_flags & LRE_FLAG_DOTALL) != 0);
s->unicode_sets = ((re_flags & LRE_FLAG_UNICODE_SETS) != 0);
s->capture_count = 1;
s->total_capture_count = -1;
s->has_named_captures = -1;
@ -1886,7 +1849,7 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
dbuf_init2(&s->byte_code, opaque, lre_realloc);
dbuf_init2(&s->group_names, opaque, lre_realloc);
dbuf_put_u16(&s->byte_code, re_flags); /* first element is the flags */
dbuf_putc(&s->byte_code, re_flags); /* first element is the flags */
dbuf_putc(&s->byte_code, 0); /* second element is the number of captures */
dbuf_putc(&s->byte_code, 0); /* stack size */
dbuf_put_u32(&s->byte_code, 0); /* bytecode length */
@ -1933,14 +1896,12 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
s->byte_code.buf[RE_HEADER_CAPTURE_COUNT] = s->capture_count;
s->byte_code.buf[RE_HEADER_STACK_SIZE] = stack_size;
put_u32(s->byte_code.buf + RE_HEADER_BYTECODE_LEN,
s->byte_code.size - RE_HEADER_LEN);
put_u32(s->byte_code.buf + 3, s->byte_code.size - RE_HEADER_LEN);
/* add the named groups if needed */
if (s->group_names.size > (s->capture_count - 1)) {
dbuf_put(&s->byte_code, s->group_names.buf, s->group_names.size);
put_u16(s->byte_code.buf + RE_HEADER_FLAGS,
LRE_FLAG_NAMED_GROUPS | lre_get_flags(s->byte_code.buf));
s->byte_code.buf[RE_HEADER_FLAGS] |= LRE_FLAG_NAMED_GROUPS;
}
dbuf_free(&s->group_names);
@ -1966,86 +1927,86 @@ static BOOL is_word_char(uint32_t c)
(c == '_'));
}
#define GET_CHAR(c, cptr, cbuf_end, cbuf_type) \
#define GET_CHAR(c, cptr, cbuf_end) \
do { \
if (cbuf_type == 0) { \
c = *cptr++; \
} else { \
const uint16_t *_p = (const uint16_t *)cptr; \
const uint16_t *_end = (const uint16_t *)cbuf_end; \
const uint16_t *_p = (uint16_t *)cptr; \
const uint16_t *_end = (uint16_t *)cbuf_end; \
c = *_p++; \
if (is_hi_surrogate(c)) \
if (cbuf_type == 2) \
if (_p < _end) \
if (is_lo_surrogate(*_p)) \
c = from_surrogate(c, *_p++); \
cptr = (const void *)_p; \
cptr = (void *) _p; \
} \
} while (0)
#define PEEK_CHAR(c, cptr, cbuf_end, cbuf_type) \
#define PEEK_CHAR(c, cptr, cbuf_end) \
do { \
if (cbuf_type == 0) { \
c = cptr[0]; \
} else { \
const uint16_t *_p = (const uint16_t *)cptr; \
const uint16_t *_end = (const uint16_t *)cbuf_end; \
const uint16_t *_p = (uint16_t *)cptr; \
const uint16_t *_end = (uint16_t *)cbuf_end; \
c = *_p++; \
if (is_hi_surrogate(c)) \
if (cbuf_type == 2) \
if (_p < _end) \
if (is_lo_surrogate(*_p)) \
c = from_surrogate(c, *_p); \
c = from_surrogate(c, *_p++); \
} \
} while (0)
#define PEEK_PREV_CHAR(c, cptr, cbuf_start, cbuf_type) \
#define PEEK_PREV_CHAR(c, cptr, cbuf_start) \
do { \
if (cbuf_type == 0) { \
c = cptr[-1]; \
} else { \
const uint16_t *_p = (const uint16_t *)cptr - 1; \
const uint16_t *_start = (const uint16_t *)cbuf_start; \
const uint16_t *_p = (uint16_t *)cptr - 1; \
const uint16_t *_start = (uint16_t *)cbuf_start; \
c = *_p; \
if (is_lo_surrogate(c)) \
if (cbuf_type == 2) \
if (_p > _start) \
if (is_hi_surrogate(_p[-1])) \
c = from_surrogate(*--_p, c); \
if (is_hi_surrogate(*--_p)) \
c = from_surrogate(*_p, c); \
} \
} while (0)
#define GET_PREV_CHAR(c, cptr, cbuf_start, cbuf_type) \
#define GET_PREV_CHAR(c, cptr, cbuf_start) \
do { \
if (cbuf_type == 0) { \
cptr--; \
c = cptr[0]; \
} else { \
const uint16_t *_p = (const uint16_t *)cptr - 1; \
const uint16_t *_start = (const uint16_t *)cbuf_start; \
const uint16_t *_p = (uint16_t *)cptr - 1; \
const uint16_t *_start = (uint16_t *)cbuf_start; \
c = *_p; \
if (is_lo_surrogate(c)) \
if (cbuf_type == 2) \
if (_p > _start) \
if (is_hi_surrogate(_p[-1])) \
c = from_surrogate(*--_p, c); \
cptr = (const void *)_p; \
if (is_hi_surrogate(*--_p)) \
c = from_surrogate(*_p, c); \
cptr = (void *) _p; \
} \
} while (0)
#define PREV_CHAR(cptr, cbuf_start, cbuf_type) \
#define PREV_CHAR(cptr, cbuf_start) \
do { \
if (cbuf_type == 0) { \
cptr--; \
} else { \
const uint16_t *_p = (const uint16_t *)cptr - 1; \
const uint16_t *_start = (const uint16_t *)cbuf_start; \
const uint16_t *_p = (uint16_t *)cptr - 1; \
const uint16_t *_start = (uint16_t *)cbuf_start; \
if (is_lo_surrogate(*_p)) \
if (cbuf_type == 2) \
if (_p > _start) \
if (is_hi_surrogate(_p[-1])) \
_p--; \
cptr = (const void *)_p; \
cptr = (void *) _p; \
} \
} while (0)
@ -2076,7 +2037,7 @@ typedef struct {
int stack_size_max;
BOOL multi_line;
BOOL ignore_case;
BOOL is_unicode;
BOOL is_utf16;
void *opaque; /* used for stack overflow check */
size_t state_size;
@ -2185,7 +2146,7 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
/* go backward */
char_count = get_u32(pc + 12);
for(i = 0; i < char_count; i++) {
PREV_CHAR(cptr, s->cbuf, cbuf_type);
PREV_CHAR(cptr, s->cbuf);
}
pc = (pc + 16) + (int)get_u32(pc);
rs->cptr = cptr;
@ -2224,9 +2185,9 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
test_char:
if (cptr >= cbuf_end)
goto no_match;
GET_CHAR(c, cptr, cbuf_end, cbuf_type);
GET_CHAR(c, cptr, cbuf_end);
if (s->ignore_case) {
c = lre_canonicalize(c, s->is_unicode);
c = lre_canonicalize(c, s->is_utf16);
}
if (val != c)
goto no_match;
@ -2271,7 +2232,7 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
break;
if (!s->multi_line)
goto no_match;
PEEK_PREV_CHAR(c, cptr, s->cbuf, cbuf_type);
PEEK_PREV_CHAR(c, cptr, s->cbuf);
if (!is_line_terminator(c))
goto no_match;
break;
@ -2280,21 +2241,21 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
break;
if (!s->multi_line)
goto no_match;
PEEK_CHAR(c, cptr, cbuf_end, cbuf_type);
PEEK_CHAR(c, cptr, cbuf_end);
if (!is_line_terminator(c))
goto no_match;
break;
case REOP_dot:
if (cptr == cbuf_end)
goto no_match;
GET_CHAR(c, cptr, cbuf_end, cbuf_type);
GET_CHAR(c, cptr, cbuf_end);
if (is_line_terminator(c))
goto no_match;
break;
case REOP_any:
if (cptr == cbuf_end)
goto no_match;
GET_CHAR(c, cptr, cbuf_end, cbuf_type);
GET_CHAR(c, cptr, cbuf_end);
break;
case REOP_save_start:
case REOP_save_end:
@ -2348,14 +2309,14 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
if (cptr == s->cbuf) {
v1 = FALSE;
} else {
PEEK_PREV_CHAR(c, cptr, s->cbuf, cbuf_type);
PEEK_PREV_CHAR(c, cptr, s->cbuf);
v1 = is_word_char(c);
}
/* current char */
if (cptr >= cbuf_end) {
v2 = FALSE;
} else {
PEEK_CHAR(c, cptr, cbuf_end, cbuf_type);
PEEK_CHAR(c, cptr, cbuf_end);
v2 = is_word_char(c);
}
if (v1 ^ v2 ^ (REOP_not_word_boundary - opcode))
@ -2380,11 +2341,11 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
while (cptr1 < cptr1_end) {
if (cptr >= cbuf_end)
goto no_match;
GET_CHAR(c1, cptr1, cptr1_end, cbuf_type);
GET_CHAR(c2, cptr, cbuf_end, cbuf_type);
GET_CHAR(c1, cptr1, cptr1_end);
GET_CHAR(c2, cptr, cbuf_end);
if (s->ignore_case) {
c1 = lre_canonicalize(c1, s->is_unicode);
c2 = lre_canonicalize(c2, s->is_unicode);
c1 = lre_canonicalize(c1, s->is_utf16);
c2 = lre_canonicalize(c2, s->is_utf16);
}
if (c1 != c2)
goto no_match;
@ -2394,11 +2355,11 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
while (cptr1 > cptr1_start) {
if (cptr == s->cbuf)
goto no_match;
GET_PREV_CHAR(c1, cptr1, cptr1_start, cbuf_type);
GET_PREV_CHAR(c2, cptr, s->cbuf, cbuf_type);
GET_PREV_CHAR(c1, cptr1, cptr1_start);
GET_PREV_CHAR(c2, cptr, s->cbuf);
if (s->ignore_case) {
c1 = lre_canonicalize(c1, s->is_unicode);
c2 = lre_canonicalize(c2, s->is_unicode);
c1 = lre_canonicalize(c1, s->is_utf16);
c2 = lre_canonicalize(c2, s->is_utf16);
}
if (c1 != c2)
goto no_match;
@ -2415,9 +2376,9 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
pc += 2;
if (cptr >= cbuf_end)
goto no_match;
GET_CHAR(c, cptr, cbuf_end, cbuf_type);
GET_CHAR(c, cptr, cbuf_end);
if (s->ignore_case) {
c = lre_canonicalize(c, s->is_unicode);
c = lre_canonicalize(c, s->is_utf16);
}
idx_min = 0;
low = get_u16(pc + 0 * 4);
@ -2455,9 +2416,9 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
pc += 2;
if (cptr >= cbuf_end)
goto no_match;
GET_CHAR(c, cptr, cbuf_end, cbuf_type);
GET_CHAR(c, cptr, cbuf_end);
if (s->ignore_case) {
c = lre_canonicalize(c, s->is_unicode);
c = lre_canonicalize(c, s->is_utf16);
}
idx_min = 0;
low = get_u32(pc + 0 * 8);
@ -2487,7 +2448,7 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
/* go to the previous char */
if (cptr == s->cbuf)
goto no_match;
PREV_CHAR(cptr, s->cbuf, cbuf_type);
PREV_CHAR(cptr, s->cbuf);
break;
case REOP_simple_greedy_quant:
{
@ -2546,16 +2507,16 @@ int lre_exec(uint8_t **capture,
int re_flags, i, alloca_size, ret;
StackInt *stack_buf;
re_flags = lre_get_flags(bc_buf);
re_flags = bc_buf[RE_HEADER_FLAGS];
s->multi_line = (re_flags & LRE_FLAG_MULTILINE) != 0;
s->ignore_case = (re_flags & LRE_FLAG_IGNORECASE) != 0;
s->is_unicode = (re_flags & LRE_FLAG_UNICODE) != 0;
s->is_utf16 = (re_flags & LRE_FLAG_UTF16) != 0;
s->capture_count = bc_buf[RE_HEADER_CAPTURE_COUNT];
s->stack_size_max = bc_buf[RE_HEADER_STACK_SIZE];
s->cbuf = cbuf;
s->cbuf_end = cbuf + (clen << cbuf_type);
s->cbuf_type = cbuf_type;
if (s->cbuf_type == 1 && s->is_unicode)
if (s->cbuf_type == 1 && s->is_utf16)
s->cbuf_type = 2;
s->opaque = opaque;
@ -2583,7 +2544,7 @@ int lre_get_capture_count(const uint8_t *bc_buf)
int lre_get_flags(const uint8_t *bc_buf)
{
return get_u16(bc_buf + RE_HEADER_FLAGS);
return bc_buf[RE_HEADER_FLAGS];
}
/* Return NULL if no group names. Otherwise, return a pointer to
@ -2593,14 +2554,14 @@ const char *lre_get_groupnames(const uint8_t *bc_buf)
uint32_t re_bytecode_len;
if ((lre_get_flags(bc_buf) & LRE_FLAG_NAMED_GROUPS) == 0)
return NULL;
re_bytecode_len = get_u32(bc_buf + RE_HEADER_BYTECODE_LEN);
return (const char *)(bc_buf + RE_HEADER_LEN + re_bytecode_len);
re_bytecode_len = get_u32(bc_buf + 3);
return (const char *)(bc_buf + 7 + re_bytecode_len);
}
void lre_byte_swap(uint8_t *buf, size_t len, BOOL is_byte_swapped)
{
uint8_t *p, *pe;
uint32_t n, r, nw;
uint32_t n, r;
p = buf;
if (len < RE_HEADER_LEN)
@ -2612,10 +2573,8 @@ void lre_byte_swap(uint8_t *buf, size_t len, BOOL is_byte_swapped)
// <capture group name 1>
// <capture group name 2>
// etc.
inplace_bswap16(&p[RE_HEADER_FLAGS]);
n = get_u32(&p[RE_HEADER_BYTECODE_LEN]);
inplace_bswap32(&p[RE_HEADER_BYTECODE_LEN]);
n = get_u32(&p[3]); // bytecode size
inplace_bswap32(&p[3]);
if (is_byte_swapped)
n = bswap32(n);
if (n > len - RE_HEADER_LEN)
@ -2635,23 +2594,16 @@ void lre_byte_swap(uint8_t *buf, size_t len, BOOL is_byte_swapped)
case REOP_save_reset: // has two 8 bit arguments
break;
case REOP_range32: // variable length
nw = get_u16(&p[1]); // number of pairs of uint32_t
if (is_byte_swapped)
n = bswap16(n);
for (r = 3 + 8 * nw; n < r; n += 4)
for (r = 3 + 4 * get_u16(&p[1]); n < r; n += 4)
inplace_bswap32(&p[n]);
goto doswap16;
case REOP_range: // variable length
nw = get_u16(&p[1]); // number of pairs of uint16_t
if (is_byte_swapped)
n = bswap16(n);
for (r = 3 + 4 * nw; n < r; n += 2)
for (r = 3 + 2 * get_u16(&p[1]); n < r; n += 2)
inplace_bswap16(&p[n]);
goto doswap16;
default:
doswap16:
inplace_bswap16(&p[1]);
break;
}
break;
case 5:

View file

@ -34,11 +34,11 @@
#define LRE_FLAG_IGNORECASE (1 << 1)
#define LRE_FLAG_MULTILINE (1 << 2)
#define LRE_FLAG_DOTALL (1 << 3)
#define LRE_FLAG_UNICODE (1 << 4)
#define LRE_FLAG_UTF16 (1 << 4)
#define LRE_FLAG_STICKY (1 << 5)
#define LRE_FLAG_INDICES (1 << 6) /* Unused by libregexp, just recorded. */
#define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */
#define LRE_FLAG_UNICODE_SETS (1 << 8)
uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
const char *buf, size_t buf_len, int re_flags,
@ -53,7 +53,7 @@ int lre_exec(uint8_t **capture,
int lre_parse_escape(const uint8_t **pp, int allow_utf16);
LRE_BOOL lre_is_space(int c);
void lre_byte_swap(uint8_t *buf, size_t len, LRE_BOOL is_byte_swapped);
void lre_byte_swap(uint8_t *buf, size_t len, BOOL is_byte_swapped);
/* must be provided by the user */
LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size);

View file

@ -947,8 +947,8 @@ int unicode_script(CharRange *cr,
int script_idx;
const uint8_t *p, *p_end;
uint32_t c, c1, b, n, v, v_len, i, type;
CharRange cr1_s = { 0 }, *cr1 = NULL;
CharRange cr2_s = { 0 }, *cr2 = &cr2_s;
CharRange cr1_s, *cr1;
CharRange cr2_s, *cr2 = &cr2_s;
BOOL is_common;
script_idx = unicode_find_name(unicode_script_name_table, script_name);

View file

@ -24,7 +24,6 @@
#ifndef LIBUNICODE_H
#define LIBUNICODE_H
#include <stddef.h>
#include <inttypes.h>
#define LRE_BOOL int /* for documentation purposes */

3
list.h
View file

@ -36,7 +36,8 @@ struct list_head {
#define LIST_HEAD_INIT(el) { &(el), &(el) }
/* return the pointer of type 'type *' containing 'el' as field 'member' */
#define list_entry(el, type, member) container_of(el, type, member)
#define list_entry(el, type, member) \
((type *)((uint8_t *)(el) - offsetof(type, member)))
static inline void init_list_head(struct list_head *head)
{

124
qjs.c
View file

@ -41,8 +41,6 @@
extern const uint8_t qjsc_repl[];
extern const uint32_t qjsc_repl_size;
static JSCFunctionListEntry argv0;
static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
const char *filename, int eval_flags)
{
@ -58,7 +56,6 @@ static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
js_module_set_import_meta(ctx, val, TRUE, TRUE);
val = JS_EvalFunction(ctx, val);
}
val = js_std_await(ctx, val);
} else {
val = JS_Eval(ctx, buf, buf_len, filename, eval_flags);
}
@ -97,51 +94,6 @@ static int eval_file(JSContext *ctx, const char *filename, int module)
return ret;
}
static int64_t parse_limit(const char *arg) {
char *p;
unsigned long unit = 1024; /* default to traditional KB */
double d = strtod(arg, &p);
if (p == arg) {
fprintf(stderr, "Invalid limit: %s\n", arg);
return -1;
}
if (*p) {
switch (*p++) {
case 'b': case 'B': unit = 1UL << 0; break;
case 'k': case 'K': unit = 1UL << 10; break; /* IEC kibibytes */
case 'm': case 'M': unit = 1UL << 20; break; /* IEC mebibytes */
case 'g': case 'G': unit = 1UL << 30; break; /* IEC gigibytes */
default:
fprintf(stderr, "Invalid limit: %s, unrecognized suffix, only k,m,g are allowed\n", arg);
return -1;
}
if (*p) {
fprintf(stderr, "Invalid limit: %s, only one suffix allowed\n", arg);
return -1;
}
}
return (int64_t)(d * unit);
}
static JSValue js_gc(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
{
JS_RunGC(JS_GetRuntime(ctx));
return JS_UNDEFINED;
}
static const JSCFunctionListEntry navigator_obj[] = {
JS_PROP_STRING_DEF("userAgent", "quickjs-ng", JS_PROP_ENUMERABLE),
};
static const JSCFunctionListEntry global_obj[] = {
JS_CFUNC_DEF("gc", 0, js_gc),
JS_OBJECT_DEF("navigator", navigator_obj, countof(navigator_obj), JS_PROP_C_W_E),
};
/* also used to initialize the worker context */
static JSContext *JS_NewCustomContext(JSRuntime *rt)
{
@ -152,12 +104,6 @@ static JSContext *JS_NewCustomContext(JSRuntime *rt)
/* system modules */
js_init_module_std(ctx, "std");
js_init_module_os(ctx, "os");
JSValue global = JS_GetGlobalObject(ctx);
JS_SetPropertyFunctionList(ctx, global, global_obj, countof(global_obj));
JS_SetPropertyFunctionList(ctx, global, &argv0, 1);
JS_FreeValue(ctx, global);
return ctx;
}
@ -229,8 +175,7 @@ static void *js_trace_malloc(JSMallocState *s, size_t size)
/* Do not allocate zero bytes: behavior is platform dependent */
assert(size != 0);
/* When malloc_limit is 0 (unlimited), malloc_limit - 1 will be SIZE_MAX. */
if (unlikely(s->malloc_size + size > s->malloc_limit - 1))
if (unlikely(s->malloc_size + size > s->malloc_limit))
return NULL;
ptr = malloc(size);
js_trace_malloc_printf(s, "A %zd -> %p\n", size, ptr);
@ -269,8 +214,7 @@ static void *js_trace_realloc(JSMallocState *s, void *ptr, size_t size)
free(ptr);
return NULL;
}
/* When malloc_limit is 0 (unlimited), malloc_limit - 1 will be SIZE_MAX. */
if (s->malloc_size + size - old_size > s->malloc_limit - 1)
if (s->malloc_size + size - old_size > s->malloc_limit)
return NULL;
js_trace_malloc_printf(s, "R %zd %p", size, ptr);
@ -305,8 +249,8 @@ void help(void)
" --std make 'std' and 'os' available to the loaded script\n"
"-T --trace trace memory allocation\n"
"-d --dump dump the memory usage stats\n"
" --memory-limit n limit the memory usage to 'n' Kbytes\n"
" --stack-size n limit the stack size to 'n' Kbytes\n"
" --memory-limit n limit the memory usage to 'n' bytes\n"
" --stack-size n limit the stack size to 'n' bytes\n"
" --unhandled-rejection dump unhandled promise rejections\n"
"-q --quit just instantiate the interpreter and quit\n", JS_GetVersion());
exit(1);
@ -321,19 +265,15 @@ int main(int argc, char **argv)
char *expr = NULL;
int interactive = 0;
int dump_memory = 0;
int dump_flags = 0;
int trace_memory = 0;
int empty_run = 0;
int module = -1;
int load_std = 0;
int dump_unhandled_promise_rejection = 0;
size_t memory_limit = 0;
char *include_list[32];
int i, include_count = 0;
int64_t memory_limit = -1;
int64_t stack_size = -1;
argv0 = (JSCFunctionListEntry)JS_PROP_STRING_DEF("argv0", argv[0],
JS_PROP_C_W_E);
size_t stack_size = 0;
/* cannot use getopt because we want to pass the command line to
the script */
@ -341,16 +281,12 @@ int main(int argc, char **argv)
while (optind < argc && *argv[optind] == '-') {
char *arg = argv[optind] + 1;
const char *longopt = "";
char *opt_arg = NULL;
/* a single - is not an option, it also stops argument scanning */
if (!*arg)
break;
optind++;
if (*arg == '-') {
longopt = arg + 1;
opt_arg = strchr(longopt, '=');
if (opt_arg)
*opt_arg++ = '\0';
arg += strlen(arg);
/* -- stops argument scanning */
if (!*longopt)
@ -358,26 +294,24 @@ int main(int argc, char **argv)
}
for (; *arg || *longopt; longopt = "") {
char opt = *arg;
if (opt) {
if (opt)
arg++;
if (!opt_arg && *arg)
opt_arg = arg;
}
if (opt == 'h' || opt == '?' || !strcmp(longopt, "help")) {
help();
continue;
}
if (opt == 'e' || !strcmp(longopt, "eval")) {
if (!opt_arg) {
if (optind >= argc) {
if (*arg) {
expr = arg;
break;
}
if (optind < argc) {
expr = argv[optind++];
break;
}
fprintf(stderr, "qjs: missing expression for -e\n");
exit(2);
}
opt_arg = argv[optind++];
}
expr = opt_arg;
break;
}
if (opt == 'I' || !strcmp(longopt, "include")) {
if (optind >= argc) {
fprintf(stderr, "expecting filename");
@ -406,10 +340,6 @@ int main(int argc, char **argv)
dump_memory++;
continue;
}
if (opt == 'D' || !strcmp(longopt, "dump-flags")) {
dump_flags = opt_arg ? strtol(opt_arg, NULL, 16) : 0;
break;
}
if (opt == 'T' || !strcmp(longopt, "trace")) {
trace_memory++;
continue;
@ -427,26 +357,20 @@ int main(int argc, char **argv)
continue;
}
if (!strcmp(longopt, "memory-limit")) {
if (!opt_arg) {
if (optind >= argc) {
fprintf(stderr, "expecting memory limit");
exit(1);
}
opt_arg = argv[optind++];
}
memory_limit = parse_limit(opt_arg);
break;
memory_limit = (size_t)strtod(argv[optind++], NULL);
continue;
}
if (!strcmp(longopt, "stack-size")) {
if (!opt_arg) {
if (optind >= argc) {
fprintf(stderr, "expecting stack size");
exit(1);
}
opt_arg = argv[optind++];
}
stack_size = parse_limit(opt_arg);
break;
stack_size = (size_t)strtod(argv[optind++], NULL);
continue;
}
if (opt) {
fprintf(stderr, "qjs: unknown option '-%c'\n", opt);
@ -467,12 +391,10 @@ int main(int argc, char **argv)
fprintf(stderr, "qjs: cannot allocate JS runtime\n");
exit(2);
}
if (memory_limit >= 0)
JS_SetMemoryLimit(rt, (size_t)memory_limit);
if (stack_size >= 0)
JS_SetMaxStackSize(rt, (size_t)stack_size);
if (dump_flags != 0)
JS_SetDumpFlags(rt, dump_flags);
if (memory_limit != 0)
JS_SetMemoryLimit(rt, memory_limit);
if (stack_size != 0)
JS_SetMaxStackSize(rt, stack_size);
js_std_set_worker_new_context_func(JS_NewCustomContext);
js_std_init_handlers(rt);
ctx = JS_NewCustomContext(rt);

20
qjsc.c
View file

@ -56,7 +56,7 @@ static namelist_t cmodule_list;
static namelist_t init_module_list;
static FILE *outfile;
static const char *c_ident_prefix = "qjsc_";
static int strip;
void namelist_add(namelist_t *lp, const char *name, const char *short_name,
int flags)
@ -150,20 +150,13 @@ static void dump_hex(FILE *f, const uint8_t *buf, size_t len)
}
static void output_object_code(JSContext *ctx,
FILE *fo, JSValue obj, const char *c_name,
FILE *fo, JSValueConst obj, const char *c_name,
BOOL load_only)
{
uint8_t *out_buf;
size_t out_buf_len;
int flags = JS_WRITE_OBJ_BYTECODE;
if (strip) {
flags |= JS_WRITE_OBJ_STRIP_SOURCE;
if (strip > 1)
flags |= JS_WRITE_OBJ_STRIP_DEBUG;
}
out_buf = JS_WriteObject(ctx, &out_buf_len, obj, flags);
out_buf = JS_WriteObject(ctx, &out_buf_len, obj, JS_WRITE_OBJ_BYTECODE);
if (!out_buf) {
js_std_dump_error(ctx);
exit(1);
@ -312,7 +305,6 @@ static const char main_c_template1[] =
static const char main_c_template2[] =
" js_std_loop(ctx);\n"
" JS_FreeContext(ctx);\n"
" js_std_free_handlers(rt);\n"
" JS_FreeRuntime(rt);\n"
" return 0;\n"
"}\n";
@ -361,7 +353,6 @@ int main(int argc, char **argv)
cname = NULL;
module = -1;
verbose = 0;
strip = 0;
stack_size = 0;
memset(&dynamic_module_list, 0, sizeof(dynamic_module_list));
@ -370,7 +361,7 @@ int main(int argc, char **argv)
namelist_add(&cmodule_list, "os", "os", 0);
for(;;) {
c = getopt(argc, argv, "ho:N:mxesvM:p:S:D:");
c = getopt(argc, argv, "ho:N:mxevM:p:S:D:");
if (c == -1)
break;
switch(c) {
@ -407,9 +398,6 @@ int main(int argc, char **argv)
case 'D':
namelist_add(&dynamic_module_list, optarg, NULL, 0);
break;
case 's':
strip++;
break;
case 'v':
verbose++;
break;

View file

@ -79,6 +79,8 @@ DEF(await, "await")
DEF(empty_string, "")
/* identifiers */
DEF(length, "length")
DEF(fileName, "fileName")
DEF(lineNumber, "lineNumber")
DEF(message, "message")
DEF(cause, "cause")
DEF(errors, "errors")
@ -170,9 +172,11 @@ DEF(status, "status")
DEF(reason, "reason")
DEF(globalThis, "globalThis")
DEF(bigint, "bigint")
#ifdef CONFIG_ATOMICS
DEF(not_equal, "not-equal")
DEF(timed_out, "timed-out")
DEF(ok, "ok")
#endif
DEF(toJSON, "toJSON")
/* class names */
DEF(Object, "Object")
@ -234,7 +238,6 @@ DEF(SyntaxError, "SyntaxError")
DEF(TypeError, "TypeError")
DEF(URIError, "URIError")
DEF(InternalError, "InternalError")
DEF(CallSite, "CallSite")
/* private symbols */
DEF(Private_brand, "<brand>")
/* symbols */

File diff suppressed because it is too large Load diff

View file

@ -37,19 +37,18 @@ JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name);
JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name);
void js_std_add_helpers(JSContext *ctx, int argc, char **argv);
void js_std_loop(JSContext *ctx);
JSValue js_std_await(JSContext *ctx, JSValue obj);
void js_std_init_handlers(JSRuntime *rt);
void js_std_free_handlers(JSRuntime *rt);
void js_std_dump_error(JSContext *ctx);
uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename);
int js_module_set_import_meta(JSContext *ctx, JSValue func_val,
int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val,
JS_BOOL use_realpath, JS_BOOL is_main);
JSModuleDef *js_module_loader(JSContext *ctx,
const char *module_name, void *opaque);
void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
int flags);
void js_std_promise_rejection_tracker(JSContext *ctx, JSValue promise,
JSValue reason,
void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
JSValueConst reason,
JS_BOOL is_handled, void *opaque);
void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt));

View file

@ -44,7 +44,6 @@ FMT(loc)
FMT(arg)
FMT(var_ref)
FMT(u32)
FMT(u32x2)
FMT(i32)
FMT(const)
FMT(label)
@ -136,12 +135,9 @@ DEF( put_ref_value, 1, 3, 0, none)
DEF( define_var, 6, 0, 0, atom_u8)
DEF(check_define_var, 6, 0, 0, atom_u8)
DEF( define_func, 6, 1, 0, atom_u8)
// order matters, see IC counterparts
DEF( get_field, 5, 1, 1, atom)
DEF( get_field2, 5, 1, 2, atom)
DEF( put_field, 5, 2, 0, atom)
DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */
DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */
DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */
@ -186,7 +182,6 @@ DEF( goto, 5, 0, 0, label) /* must come after if_true */
DEF( catch, 5, 0, 1, label)
DEF( gosub, 5, 0, 0, label) /* used to execute the finally block */
DEF( ret, 1, 1, 0, none) /* used to return from the finally block */
DEF( nip_catch, 1, 2, 1, none) /* catch ... a -> a */
DEF( to_object, 1, 1, 1, none)
//DEF( to_string, 1, 1, 1, none)
@ -213,6 +208,7 @@ DEF( for_of_next, 2, 3, 5, u8)
DEF(iterator_check_object, 1, 1, 1, none)
DEF(iterator_get_value_done, 1, 1, 2, none)
DEF( iterator_close, 1, 3, 0, none)
DEF(iterator_close_return, 1, 4, 4, none)
DEF( iterator_next, 1, 4, 4, none)
DEF( iterator_call, 2, 4, 5, u8)
DEF( initial_yield, 1, 0, 0, none)
@ -281,11 +277,11 @@ def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase
def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */
def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */
def(scope_put_private_field, 7, 2, 0, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */
def(scope_put_private_field, 7, 1, 1, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */
def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
def( source_loc, 9, 0, 0, u32x2) /* emitted in phase 1, removed in phase 3 */
def( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
DEF( push_minus1, 1, 0, 1, none_int)
DEF( push_0, 1, 0, 1, none_int)
@ -361,7 +357,6 @@ DEF( is_null, 1, 1, 1, none)
DEF(typeof_is_undefined, 1, 1, 1, none)
DEF( typeof_is_function, 1, 1, 1, none)
// order matters, see non-IC counterparts
DEF( get_field_ic, 5, 1, 1, none)
DEF( get_field2_ic, 5, 1, 2, none)
DEF( put_field_ic, 5, 2, 0, none)

9472
quickjs.c

File diff suppressed because it is too large Load diff

436
quickjs.h
View file

@ -29,18 +29,18 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__GNUC__) || defined(__clang__)
#define js_unlikely(x) __builtin_expect(!!(x), 0)
#define js_force_inline inline __attribute__((always_inline))
#define __js_printf_like(f, a) __attribute__((format(printf, f, a)))
#define JS_EXTERN __attribute__((visibility("default")))
#else
#define js_unlikely(x) (x)
#define js_force_inline inline
#define __js_printf_like(a, b)
#define JS_EXTERN /* nothing */
@ -55,12 +55,6 @@ typedef struct JSClass JSClass;
typedef uint32_t JSClassID;
typedef uint32_t JSAtom;
/* Unless documented otherwise, C string pointers (`char *` or `const char *`)
are assumed to verify these constraints:
- unless a length is passed separately, the string has a null terminator
- string contents is either pure ASCII or is UTF-8 encoded.
*/
#if INTPTR_MAX < INT64_MAX
/* Use NAN boxing for 32bit builds. */
#define JS_NAN_BOXING
@ -92,12 +86,47 @@ typedef struct JSRefCountHeader {
} JSRefCountHeader;
#define JS_FLOAT64_NAN NAN
#define JSValueConst JSValue /* For backwards compatibility. */
#if defined(JS_NAN_BOXING)
#ifdef CONFIG_CHECK_JSVALUE
/* JSValue consistency : it is not possible to run the code in this
mode, but it is useful to detect simple reference counting
errors. It would be interesting to modify a static C analyzer to
handle specific annotations (clang has such annotations but only
for objective C) */
typedef struct __JSValue *JSValue;
typedef const struct __JSValue *JSValueConst;
#define JS_VALUE_GET_TAG(v) (int)((uintptr_t)(v) & 0xf)
/* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */
#define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG(v)
#define JS_VALUE_GET_INT(v) (int)((intptr_t)(v) >> 4)
#define JS_VALUE_GET_BOOL(v) JS_VALUE_GET_INT(v)
#define JS_VALUE_GET_FLOAT64(v) (double)JS_VALUE_GET_INT(v)
#define JS_VALUE_GET_PTR(v) (void *)((intptr_t)(v) & ~0xf)
#define JS_MKVAL(tag, val) (JSValue)(intptr_t)(((val) << 4) | (tag))
#define JS_MKPTR(tag, p) (JSValue)((intptr_t)(p) | (tag))
#define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64)
#define JS_NAN JS_MKVAL(JS_TAG_FLOAT64, 1)
static inline JSValue __JS_NewFloat64(double d)
{
return JS_MKVAL(JS_TAG_FLOAT64, (int)d);
}
static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
{
return 0;
}
#elif defined(JS_NAN_BOXING)
typedef uint64_t JSValue;
#define JSValueConst JSValue
#define JS_VALUE_GET_TAG(v) (int)((v) >> 32)
#define JS_VALUE_GET_INT(v) (int)(v)
#define JS_VALUE_GET_BOOL(v) (int)(v)
@ -130,7 +159,7 @@ static inline JSValue __JS_NewFloat64(double d)
JSValue v;
u.d = d;
/* normalize NaN */
if ((u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000)
if (js_unlikely((u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000))
v = JS_NAN;
else
v = u.u64 - ((uint64_t)JS_FLOAT64_TAG_ADDEND << 32);
@ -170,6 +199,8 @@ typedef struct JSValue {
int64_t tag;
} JSValue;
#define JSValueConst JSValue
#define JS_VALUE_GET_TAG(v) ((int32_t)(v).tag)
/* same as JS_VALUE_GET_TAG, but return JS_TAG_FLOAT64 with NaN boxing */
#define JS_VALUE_GET_NORM_TAG(v) JS_VALUE_GET_TAG(v)
@ -183,7 +214,7 @@ typedef struct JSValue {
#define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64)
#define JS_NAN (JSValue){ (JSValueUnion){ .float64 = JS_FLOAT64_NAN }, JS_TAG_FLOAT64 }
#define JS_NAN (JSValue){ .u.float64 = JS_FLOAT64_NAN, JS_TAG_FLOAT64 }
static inline JSValue __JS_NewFloat64(double d)
{
@ -211,6 +242,7 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
#define JS_VALUE_IS_BOTH_FLOAT(v1, v2) (JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(v1)) && JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(v2)))
#define JS_VALUE_GET_OBJ(v) ((JSObject *)JS_VALUE_GET_PTR(v))
#define JS_VALUE_GET_STRING(v) ((JSString *)JS_VALUE_GET_PTR(v))
#define JS_VALUE_HAS_REF_COUNT(v) ((unsigned)JS_VALUE_GET_TAG(v) >= (unsigned)JS_TAG_FIRST)
/* special values */
@ -251,14 +283,8 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
#define JS_PROP_NO_ADD (1 << 16) /* internal use */
#define JS_PROP_NO_EXOTIC (1 << 17) /* internal use */
#define JS_PROP_DEFINE_PROPERTY (1 << 18) /* internal use */
#define JS_PROP_REFLECT_DEFINE_PROPERTY (1 << 19) /* internal use */
#if defined(__wasi__)
#define JS_DEFAULT_STACK_SIZE 0
#else
#define JS_DEFAULT_STACK_SIZE (256 * 1024)
#endif
/* JS_Eval() flags */
#define JS_EVAL_TYPE_GLOBAL (0 << 0) /* global code (default) */
@ -275,13 +301,10 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
#define JS_EVAL_FLAG_COMPILE_ONLY (1 << 5)
/* don't include the stack frames before this eval in the Error() backtraces */
#define JS_EVAL_FLAG_BACKTRACE_BARRIER (1 << 6)
/* allow top-level await in normal script. JS_Eval() returns a
promise. Only allowed with JS_EVAL_TYPE_GLOBAL */
#define JS_EVAL_FLAG_ASYNC (1 << 7)
typedef JSValue JSCFunction(JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
typedef JSValue JSCFunctionMagic(JSContext *ctx, JSValue this_val, int argc, JSValue *argv, int magic);
typedef JSValue JSCFunctionData(JSContext *ctx, JSValue this_val, int argc, JSValue *argv, int magic, JSValue *func_data);
typedef JSValue JSCFunction(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv);
typedef JSValue JSCFunctionMagic(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic);
typedef JSValue JSCFunctionData(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic, JSValue *func_data);
typedef struct JSMallocState {
size_t malloc_count;
@ -302,10 +325,7 @@ typedef struct JSGCObjectHeader JSGCObjectHeader;
JS_EXTERN JSRuntime *JS_NewRuntime(void);
/* info lifetime must exceed that of rt */
JS_EXTERN void JS_SetRuntimeInfo(JSRuntime *rt, const char *info);
/* use 0 to disable memory limit */
JS_EXTERN void JS_SetMemoryLimit(JSRuntime *rt, size_t limit);
JS_EXTERN void JS_SetDumpFlags(JSRuntime *rt, uint64_t flags);
JS_EXTERN size_t JS_GetGCThreshold(JSRuntime *rt);
JS_EXTERN void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold);
/* use 0 to disable maximum stack size check */
JS_EXTERN void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size);
@ -317,9 +337,9 @@ JS_EXTERN void JS_FreeRuntime(JSRuntime *rt);
JS_EXTERN void *JS_GetRuntimeOpaque(JSRuntime *rt);
JS_EXTERN void JS_SetRuntimeOpaque(JSRuntime *rt, void *opaque);
typedef void JS_MarkFunc(JSRuntime *rt, JSGCObjectHeader *gp);
JS_EXTERN void JS_MarkValue(JSRuntime *rt, JSValue val, JS_MarkFunc *mark_func);
JS_EXTERN void JS_MarkValue(JSRuntime *rt, JSValueConst val, JS_MarkFunc *mark_func);
JS_EXTERN void JS_RunGC(JSRuntime *rt);
JS_EXTERN JS_BOOL JS_IsLiveObject(JSRuntime *rt, JSValue obj);
JS_EXTERN JS_BOOL JS_IsLiveObject(JSRuntime *rt, JSValueConst obj);
JS_EXTERN JSContext *JS_NewContext(JSRuntime *rt);
JS_EXTERN void JS_FreeContext(JSContext *s);
@ -347,16 +367,9 @@ JS_EXTERN void JS_AddIntrinsicBigInt(JSContext *ctx);
JS_EXTERN void JS_AddIntrinsicWeakRef(JSContext *ctx);
JS_EXTERN void JS_AddPerformance(JSContext *ctx);
/* for equality comparisons and sameness */
JS_EXTERN int JS_IsEqual(JSContext *ctx, JSValue op1, JSValue op2);
JS_EXTERN JS_BOOL JS_IsStrictEqual(JSContext *ctx, JSValue op1, JSValue op2);
JS_EXTERN JS_BOOL JS_IsSameValue(JSContext *ctx, JSValue op1, JSValue op2);
/* Similar to same-value equality, but +0 and -0 are considered equal. */
JS_EXTERN JS_BOOL JS_IsSameValueZero(JSContext *ctx, JSValue op1, JSValue op2);
/* Only used for running 262 tests. TODO(saghul) add build time flag. */
JS_EXTERN JSValue js_string_codePointRange(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv);
JS_EXTERN JSValue js_string_codePointRange(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv);
JS_EXTERN void *js_malloc_rt(JSRuntime *rt, size_t size);
JS_EXTERN void js_free_rt(JSRuntime *rt, void *ptr);
@ -404,7 +417,7 @@ JS_EXTERN void JS_FreeAtomRT(JSRuntime *rt, JSAtom v);
JS_EXTERN JSValue JS_AtomToValue(JSContext *ctx, JSAtom atom);
JS_EXTERN JSValue JS_AtomToString(JSContext *ctx, JSAtom atom);
JS_EXTERN const char *JS_AtomToCString(JSContext *ctx, JSAtom atom);
JS_EXTERN JSAtom JS_ValueToAtom(JSContext *ctx, JSValue val);
JS_EXTERN JSAtom JS_ValueToAtom(JSContext *ctx, JSValueConst val);
/* object class support */
@ -425,41 +438,41 @@ typedef struct JSClassExoticMethods {
FALSE if the property does not exists, TRUE if it exists. If 1 is
returned, the property descriptor 'desc' is filled if != NULL. */
int (*get_own_property)(JSContext *ctx, JSPropertyDescriptor *desc,
JSValue obj, JSAtom prop);
JSValueConst obj, JSAtom prop);
/* '*ptab' should hold the '*plen' property keys. Return 0 if OK,
-1 if exception. The 'is_enumerable' field is ignored.
*/
int (*get_own_property_names)(JSContext *ctx, JSPropertyEnum **ptab,
uint32_t *plen,
JSValue obj);
JSValueConst obj);
/* return < 0 if exception, or TRUE/FALSE */
int (*delete_property)(JSContext *ctx, JSValue obj, JSAtom prop);
int (*delete_property)(JSContext *ctx, JSValueConst obj, JSAtom prop);
/* return < 0 if exception or TRUE/FALSE */
int (*define_own_property)(JSContext *ctx, JSValue this_obj,
JSAtom prop, JSValue val,
JSValue getter, JSValue setter,
int (*define_own_property)(JSContext *ctx, JSValueConst this_obj,
JSAtom prop, JSValueConst val,
JSValueConst getter, JSValueConst setter,
int flags);
/* The following methods can be emulated with the previous ones,
so they are usually not needed */
/* return < 0 if exception or TRUE/FALSE */
int (*has_property)(JSContext *ctx, JSValue obj, JSAtom atom);
JSValue (*get_property)(JSContext *ctx, JSValue obj, JSAtom atom,
JSValue receiver);
int (*has_property)(JSContext *ctx, JSValueConst obj, JSAtom atom);
JSValue (*get_property)(JSContext *ctx, JSValueConst obj, JSAtom atom,
JSValueConst receiver);
/* return < 0 if exception or TRUE/FALSE */
int (*set_property)(JSContext *ctx, JSValue obj, JSAtom atom,
JSValue value, JSValue receiver, int flags);
int (*set_property)(JSContext *ctx, JSValueConst obj, JSAtom atom,
JSValueConst value, JSValueConst receiver, int flags);
} JSClassExoticMethods;
typedef void JSClassFinalizer(JSRuntime *rt, JSValue val);
typedef void JSClassGCMark(JSRuntime *rt, JSValue val,
typedef void JSClassGCMark(JSRuntime *rt, JSValueConst val,
JS_MarkFunc *mark_func);
#define JS_CALL_FLAG_CONSTRUCTOR (1 << 0)
typedef JSValue JSClassCall(JSContext *ctx, JSValue func_obj,
JSValue this_val, int argc, JSValue *argv,
typedef JSValue JSClassCall(JSContext *ctx, JSValueConst func_obj,
JSValueConst this_val, int argc, JSValueConst *argv,
int flags);
typedef struct JSClassDef {
const char *class_name; /* pure ASCII only! */
const char *class_name;
JSClassFinalizer *finalizer;
JSClassGCMark *gc_mark;
/* if call != NULL, the object is a function. If (flags &
@ -473,10 +486,7 @@ typedef struct JSClassDef {
JSClassExoticMethods *exotic;
} JSClassDef;
#define JS_INVALID_CLASS_ID 0
JS_EXTERN JSClassID JS_NewClassID(JSRuntime *rt, JSClassID *pclass_id);
/* Returns the class ID if `v` is an object, otherwise returns JS_INVALID_CLASS_ID. */
JS_EXTERN JSClassID JS_GetClassID(JSValue v);
JS_EXTERN int JS_NewClass(JSRuntime *rt, JSClassID class_id, const JSClassDef *class_def);
JS_EXTERN int JS_IsRegisteredClass(JSRuntime *rt, JSClassID class_id);
@ -492,11 +502,6 @@ static js_force_inline JSValue JS_NewInt32(JSContext *ctx, int32_t val)
return JS_MKVAL(JS_TAG_INT, val);
}
static js_force_inline JSValue JS_NewFloat64(JSContext *ctx, double val)
{
return __JS_NewFloat64(val);
}
static js_force_inline JSValue JS_NewCatchOffset(JSContext *ctx, int32_t val)
{
return JS_MKVAL(JS_TAG_CATCH_OFFSET, val);
@ -505,10 +510,10 @@ static js_force_inline JSValue JS_NewCatchOffset(JSContext *ctx, int32_t val)
static js_force_inline JSValue JS_NewInt64(JSContext *ctx, int64_t val)
{
JSValue v;
if (val >= INT32_MIN && val <= INT32_MAX) {
v = JS_NewInt32(ctx, (int32_t)val);
if (val == (int32_t)val) {
v = JS_NewInt32(ctx, val);
} else {
v = JS_NewFloat64(ctx, (double)val);
v = __JS_NewFloat64(val);
}
return v;
}
@ -517,75 +522,74 @@ static js_force_inline JSValue JS_NewUint32(JSContext *ctx, uint32_t val)
{
JSValue v;
if (val <= 0x7fffffff) {
v = JS_NewInt32(ctx, (int32_t)val);
v = JS_NewInt32(ctx, val);
} else {
v = JS_NewFloat64(ctx, (double)val);
v = __JS_NewFloat64(val);
}
return v;
}
JS_EXTERN JSValue JS_NewNumber(JSContext *ctx, double d);
JS_EXTERN JSValue JS_NewFloat64(JSContext *ctx, double d);
JS_EXTERN JSValue JS_NewBigInt64(JSContext *ctx, int64_t v);
JS_EXTERN JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v);
static inline JS_BOOL JS_IsNumber(JSValue v)
static inline JS_BOOL JS_IsNumber(JSValueConst v)
{
int tag = JS_VALUE_GET_TAG(v);
return tag == JS_TAG_INT || JS_TAG_IS_FLOAT64(tag);
}
static inline JS_BOOL JS_IsBigInt(JSContext *ctx, JSValue v)
static inline JS_BOOL JS_IsBigInt(JSContext *ctx, JSValueConst v)
{
int tag = JS_VALUE_GET_TAG(v);
return tag == JS_TAG_BIG_INT;
}
static inline JS_BOOL JS_IsBool(JSValue v)
static inline JS_BOOL JS_IsBool(JSValueConst v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_BOOL;
}
static inline JS_BOOL JS_IsNull(JSValue v)
static inline JS_BOOL JS_IsNull(JSValueConst v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_NULL;
}
static inline JS_BOOL JS_IsUndefined(JSValue v)
static inline JS_BOOL JS_IsUndefined(JSValueConst v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_UNDEFINED;
}
static inline JS_BOOL JS_IsException(JSValue v)
static inline JS_BOOL JS_IsException(JSValueConst v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_EXCEPTION;
return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_EXCEPTION);
}
static inline JS_BOOL JS_IsUninitialized(JSValue v)
static inline JS_BOOL JS_IsUninitialized(JSValueConst v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_UNINITIALIZED;
return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_UNINITIALIZED);
}
static inline JS_BOOL JS_IsString(JSValue v)
static inline JS_BOOL JS_IsString(JSValueConst v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_STRING;
}
static inline JS_BOOL JS_IsSymbol(JSValue v)
static inline JS_BOOL JS_IsSymbol(JSValueConst v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_SYMBOL;
}
static inline JS_BOOL JS_IsObject(JSValue v)
static inline JS_BOOL JS_IsObject(JSValueConst v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_OBJECT;
}
JS_EXTERN JSValue JS_Throw(JSContext *ctx, JSValue obj);
JS_EXTERN JSValue JS_GetException(JSContext *ctx);
JS_EXTERN JS_BOOL JS_IsError(JSContext *ctx, JSValue val);
JS_EXTERN JS_BOOL JS_IsError(JSContext *ctx, JSValueConst val);
JS_EXTERN void JS_ResetUncatchableError(JSContext *ctx);
JS_EXTERN JSValue JS_NewError(JSContext *ctx);
JS_EXTERN JSValue __js_printf_like(2, 3) JS_ThrowPlainError(JSContext *ctx, const char *fmt, ...);
JS_EXTERN JSValue __js_printf_like(2, 3) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...);
JS_EXTERN JSValue __js_printf_like(2, 3) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...);
JS_EXTERN JSValue __js_printf_like(2, 3) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...);
@ -614,94 +618,101 @@ static inline void JS_FreeValueRT(JSRuntime *rt, JSValue v)
}
}
static inline JSValue JS_DupValue(JSContext *ctx, JSValue v)
static inline JSValue JS_DupValue(JSContext *ctx, JSValueConst v)
{
if (JS_VALUE_HAS_REF_COUNT(v)) {
JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
p->ref_count++;
}
return v;
return (JSValue)v;
}
static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValue v)
static inline JSValue JS_DupValueRT(JSRuntime *rt, JSValueConst v)
{
if (JS_VALUE_HAS_REF_COUNT(v)) {
JSRefCountHeader *p = (JSRefCountHeader *)JS_VALUE_GET_PTR(v);
p->ref_count++;
}
return v;
return (JSValue)v;
}
JS_EXTERN int JS_ToBool(JSContext *ctx, JSValue val); /* return -1 for JS_EXCEPTION */
JS_EXTERN int JS_ToInt32(JSContext *ctx, int32_t *pres, JSValue val);
static inline int JS_ToUint32(JSContext *ctx, uint32_t *pres, JSValue val)
JS_EXTERN int JS_ToBool(JSContext *ctx, JSValueConst val); /* return -1 for JS_EXCEPTION */
JS_EXTERN int JS_ToInt32(JSContext *ctx, int32_t *pres, JSValueConst val);
static inline int JS_ToUint32(JSContext *ctx, uint32_t *pres, JSValueConst val)
{
return JS_ToInt32(ctx, (int32_t*)pres, val);
}
JS_EXTERN int JS_ToInt64(JSContext *ctx, int64_t *pres, JSValue val);
JS_EXTERN int JS_ToIndex(JSContext *ctx, uint64_t *plen, JSValue val);
JS_EXTERN int JS_ToFloat64(JSContext *ctx, double *pres, JSValue val);
JS_EXTERN int JS_ToInt64(JSContext *ctx, int64_t *pres, JSValueConst val);
JS_EXTERN int JS_ToIndex(JSContext *ctx, uint64_t *plen, JSValueConst val);
JS_EXTERN int JS_ToFloat64(JSContext *ctx, double *pres, JSValueConst val);
/* return an exception if 'val' is a Number */
JS_EXTERN int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValue val);
JS_EXTERN int JS_ToBigUint64(JSContext *ctx, uint64_t *pres, JSValue val);
JS_EXTERN int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValueConst val);
/* same as JS_ToInt64() but allow BigInt */
JS_EXTERN int JS_ToInt64Ext(JSContext *ctx, int64_t *pres, JSValue val);
JS_EXTERN int JS_ToInt64Ext(JSContext *ctx, int64_t *pres, JSValueConst val);
JS_EXTERN JSValue JS_NewStringLen(JSContext *ctx, const char *str1, size_t len1);
static inline JSValue JS_NewString(JSContext *ctx, const char *str) {
return JS_NewStringLen(ctx, str, strlen(str));
}
JS_EXTERN JSValue JS_NewString(JSContext *ctx, const char *str);
JS_EXTERN JSValue JS_NewAtomString(JSContext *ctx, const char *str);
JS_EXTERN JSValue JS_ToString(JSContext *ctx, JSValue val);
JS_EXTERN JSValue JS_ToPropertyKey(JSContext *ctx, JSValue val);
JS_EXTERN const char *JS_ToCStringLen2(JSContext *ctx, size_t *plen, JSValue val1, JS_BOOL cesu8);
static inline const char *JS_ToCStringLen(JSContext *ctx, size_t *plen, JSValue val1)
JS_EXTERN JSValue JS_ToString(JSContext *ctx, JSValueConst val);
JS_EXTERN JSValue JS_ToPropertyKey(JSContext *ctx, JSValueConst val);
JS_EXTERN const char *JS_ToCStringLen2(JSContext *ctx, size_t *plen, JSValueConst val1, JS_BOOL cesu8);
static inline const char *JS_ToCStringLen(JSContext *ctx, size_t *plen, JSValueConst val1)
{
return JS_ToCStringLen2(ctx, plen, val1, 0);
}
static inline const char *JS_ToCString(JSContext *ctx, JSValue val1)
static inline const char *JS_ToCString(JSContext *ctx, JSValueConst val1)
{
return JS_ToCStringLen2(ctx, NULL, val1, 0);
}
JS_EXTERN void JS_FreeCString(JSContext *ctx, const char *ptr);
JS_EXTERN JSValue JS_NewObjectProtoClass(JSContext *ctx, JSValue proto, JSClassID class_id);
JS_EXTERN JSValue JS_NewObjectProtoClass(JSContext *ctx, JSValueConst proto, JSClassID class_id);
JS_EXTERN JSValue JS_NewObjectClass(JSContext *ctx, int class_id);
JS_EXTERN JSValue JS_NewObjectProto(JSContext *ctx, JSValue proto);
JS_EXTERN JSValue JS_NewObjectProto(JSContext *ctx, JSValueConst proto);
JS_EXTERN JSValue JS_NewObject(JSContext *ctx);
JS_EXTERN JS_BOOL JS_IsFunction(JSContext* ctx, JSValue val);
JS_EXTERN JS_BOOL JS_IsConstructor(JSContext* ctx, JSValue val);
JS_EXTERN JS_BOOL JS_SetConstructorBit(JSContext *ctx, JSValue func_obj, JS_BOOL val);
JS_EXTERN JS_BOOL JS_IsFunction(JSContext* ctx, JSValueConst val);
JS_EXTERN JS_BOOL JS_IsConstructor(JSContext* ctx, JSValueConst val);
JS_EXTERN JS_BOOL JS_SetConstructorBit(JSContext *ctx, JSValueConst func_obj, JS_BOOL val);
JS_EXTERN JSValue JS_NewArray(JSContext *ctx);
JS_EXTERN int JS_IsArray(JSContext *ctx, JSValue val);
JS_EXTERN int JS_IsArray(JSContext *ctx, JSValueConst val);
JS_EXTERN JSValue JS_NewDate(JSContext *ctx, double epoch_ms);
JS_EXTERN JSValue JS_GetProperty(JSContext *ctx, JSValue this_obj, JSAtom prop);
JS_EXTERN JSValue JS_GetPropertyUint32(JSContext *ctx, JSValue this_obj,
uint32_t idx);
JS_EXTERN JSValue JS_GetPropertyInt64(JSContext *ctx, JSValue this_obj,
int64_t idx);
JS_EXTERN JSValue JS_GetPropertyStr(JSContext *ctx, JSValue this_obj,
JS_EXTERN JSValue JS_GetPropertyInternal(JSContext *ctx, JSValueConst obj,
JSAtom prop, JSValueConst receiver,
JS_BOOL throw_ref_error);
static js_force_inline JSValue JS_GetProperty(JSContext *ctx, JSValueConst this_obj,
JSAtom prop)
{
return JS_GetPropertyInternal(ctx, this_obj, prop, this_obj, 0);
}
JS_EXTERN JSValue JS_GetPropertyStr(JSContext *ctx, JSValueConst this_obj,
const char *prop);
JS_EXTERN JSValue JS_GetPropertyUint32(JSContext *ctx, JSValueConst this_obj,
uint32_t idx);
JS_EXTERN int JS_SetProperty(JSContext *ctx, JSValue this_obj,
JSAtom prop, JSValue val);
JS_EXTERN int JS_SetPropertyUint32(JSContext *ctx, JSValue this_obj,
int JS_SetPropertyInternal(JSContext *ctx, JSValueConst this_obj,
JSAtom prop, JSValue val,
int flags);
static inline int JS_SetProperty(JSContext *ctx, JSValueConst this_obj,
JSAtom prop, JSValue val)
{
return JS_SetPropertyInternal(ctx, this_obj, prop, val, JS_PROP_THROW);
}
JS_EXTERN int JS_SetPropertyUint32(JSContext *ctx, JSValueConst this_obj,
uint32_t idx, JSValue val);
JS_EXTERN int JS_SetPropertyInt64(JSContext *ctx, JSValue this_obj,
JS_EXTERN int JS_SetPropertyInt64(JSContext *ctx, JSValueConst this_obj,
int64_t idx, JSValue val);
JS_EXTERN int JS_SetPropertyStr(JSContext *ctx, JSValue this_obj,
JS_EXTERN int JS_SetPropertyStr(JSContext *ctx, JSValueConst this_obj,
const char *prop, JSValue val);
JS_EXTERN int JS_HasProperty(JSContext *ctx, JSValue this_obj, JSAtom prop);
JS_EXTERN int JS_IsExtensible(JSContext *ctx, JSValue obj);
JS_EXTERN int JS_PreventExtensions(JSContext *ctx, JSValue obj);
JS_EXTERN int JS_DeleteProperty(JSContext *ctx, JSValue obj, JSAtom prop, int flags);
JS_EXTERN int JS_SetPrototype(JSContext *ctx, JSValue obj, JSValue proto_val);
JS_EXTERN JSValue JS_GetPrototype(JSContext *ctx, JSValue val);
JS_EXTERN int JS_GetLength(JSContext *ctx, JSValue obj, int64_t *pres);
JS_EXTERN int JS_HasProperty(JSContext *ctx, JSValueConst this_obj, JSAtom prop);
JS_EXTERN int JS_IsExtensible(JSContext *ctx, JSValueConst obj);
JS_EXTERN int JS_PreventExtensions(JSContext *ctx, JSValueConst obj);
JS_EXTERN int JS_DeleteProperty(JSContext *ctx, JSValueConst obj, JSAtom prop, int flags);
JS_EXTERN int JS_SetPrototype(JSContext *ctx, JSValueConst obj, JSValueConst proto_val);
JS_EXTERN JSValue JS_GetPrototype(JSContext *ctx, JSValueConst val);
#define JS_GPN_STRING_MASK (1 << 0)
#define JS_GPN_SYMBOL_MASK (1 << 1)
@ -712,71 +723,67 @@ JS_EXTERN int JS_GetLength(JSContext *ctx, JSValue obj, int64_t *pres);
#define JS_GPN_SET_ENUM (1 << 5)
JS_EXTERN int JS_GetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab,
uint32_t *plen, JSValue obj, int flags);
uint32_t *plen, JSValueConst obj, int flags);
JS_EXTERN int JS_GetOwnProperty(JSContext *ctx, JSPropertyDescriptor *desc,
JSValue obj, JSAtom prop);
JS_EXTERN void JS_FreePropertyEnum(JSContext *ctx, JSPropertyEnum *tab,
uint32_t len);
JSValueConst obj, JSAtom prop);
JS_EXTERN JSValue JS_Call(JSContext *ctx, JSValue func_obj, JSValue this_obj,
int argc, JSValue *argv);
JS_EXTERN JSValue JS_Invoke(JSContext *ctx, JSValue this_val, JSAtom atom,
int argc, JSValue *argv);
JS_EXTERN JSValue JS_CallConstructor(JSContext *ctx, JSValue func_obj,
int argc, JSValue *argv);
JS_EXTERN JSValue JS_CallConstructor2(JSContext *ctx, JSValue func_obj,
JSValue new_target,
int argc, JSValue *argv);
JS_EXTERN JSValue JS_Call(JSContext *ctx, JSValueConst func_obj, JSValueConst this_obj,
int argc, JSValueConst *argv);
JS_EXTERN JSValue JS_Invoke(JSContext *ctx, JSValueConst this_val, JSAtom atom,
int argc, JSValueConst *argv);
JS_EXTERN JSValue JS_CallConstructor(JSContext *ctx, JSValueConst func_obj,
int argc, JSValueConst *argv);
JS_EXTERN JSValue JS_CallConstructor2(JSContext *ctx, JSValueConst func_obj,
JSValueConst new_target,
int argc, JSValueConst *argv);
JS_EXTERN JS_BOOL JS_DetectModule(const char *input, size_t input_len);
/* 'input' must be zero terminated i.e. input[input_len] = '\0'. */
JS_EXTERN JSValue JS_Eval(JSContext *ctx, const char *input, size_t input_len,
const char *filename, int eval_flags);
/* same as JS_Eval() but with an explicit 'this_obj' parameter */
JS_EXTERN JSValue JS_EvalThis(JSContext *ctx, JSValue this_obj,
JS_EXTERN JSValue JS_EvalThis(JSContext *ctx, JSValueConst this_obj,
const char *input, size_t input_len,
const char *filename, int eval_flags);
JS_EXTERN JSValue JS_GetGlobalObject(JSContext *ctx);
JS_EXTERN int JS_IsInstanceOf(JSContext *ctx, JSValue val, JSValue obj);
JS_EXTERN int JS_DefineProperty(JSContext *ctx, JSValue this_obj,
JSAtom prop, JSValue val,
JSValue getter, JSValue setter, int flags);
JS_EXTERN int JS_DefinePropertyValue(JSContext *ctx, JSValue this_obj,
JS_EXTERN int JS_IsInstanceOf(JSContext *ctx, JSValueConst val, JSValueConst obj);
JS_EXTERN int JS_DefineProperty(JSContext *ctx, JSValueConst this_obj,
JSAtom prop, JSValueConst val,
JSValueConst getter, JSValueConst setter, int flags);
JS_EXTERN int JS_DefinePropertyValue(JSContext *ctx, JSValueConst this_obj,
JSAtom prop, JSValue val, int flags);
JS_EXTERN int JS_DefinePropertyValueUint32(JSContext *ctx, JSValue this_obj,
JS_EXTERN int JS_DefinePropertyValueUint32(JSContext *ctx, JSValueConst this_obj,
uint32_t idx, JSValue val, int flags);
JS_EXTERN int JS_DefinePropertyValueStr(JSContext *ctx, JSValue this_obj,
JS_EXTERN int JS_DefinePropertyValueStr(JSContext *ctx, JSValueConst this_obj,
const char *prop, JSValue val, int flags);
JS_EXTERN int JS_DefinePropertyGetSet(JSContext *ctx, JSValue this_obj,
JS_EXTERN int JS_DefinePropertyGetSet(JSContext *ctx, JSValueConst this_obj,
JSAtom prop, JSValue getter, JSValue setter,
int flags);
JS_EXTERN void JS_SetOpaque(JSValue obj, void *opaque);
JS_EXTERN void *JS_GetOpaque(JSValue obj, JSClassID class_id);
JS_EXTERN void *JS_GetOpaque2(JSContext *ctx, JSValue obj, JSClassID class_id);
JS_EXTERN void *JS_GetAnyOpaque(JSValue obj, JSClassID *class_id);
JS_EXTERN void *JS_GetOpaque(JSValueConst obj, JSClassID class_id);
JS_EXTERN void *JS_GetOpaque2(JSContext *ctx, JSValueConst obj, JSClassID class_id);
JS_EXTERN void *JS_GetAnyOpaque(JSValueConst obj, JSClassID *class_id);
/* 'buf' must be zero terminated i.e. buf[buf_len] = '\0'. */
JS_EXTERN JSValue JS_ParseJSON(JSContext *ctx, const char *buf, size_t buf_len,
const char *filename);
JS_EXTERN JSValue JS_JSONStringify(JSContext *ctx, JSValue obj,
JSValue replacer, JSValue space0);
JS_EXTERN JSValue JS_JSONStringify(JSContext *ctx, JSValueConst obj,
JSValueConst replacer, JSValueConst space0);
typedef void JSFreeArrayBufferDataFunc(JSRuntime *rt, void *opaque, void *ptr);
JS_EXTERN JSValue JS_NewArrayBuffer(JSContext *ctx, uint8_t *buf, size_t len,
JSFreeArrayBufferDataFunc *free_func, void *opaque,
JS_BOOL is_shared);
JS_EXTERN JSValue JS_NewArrayBufferCopy(JSContext *ctx, const uint8_t *buf, size_t len);
JS_EXTERN void JS_DetachArrayBuffer(JSContext *ctx, JSValue obj);
JS_EXTERN uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValue obj);
JS_EXTERN JS_BOOL JS_IsArrayBuffer(JSValue obj);
JS_EXTERN uint8_t *JS_GetUint8Array(JSContext *ctx, size_t *psize, JSValue obj);
JS_EXTERN JSValue JS_GetTypedArrayBuffer(JSContext *ctx, JSValue obj,
JS_EXTERN void JS_DetachArrayBuffer(JSContext *ctx, JSValueConst obj);
JS_EXTERN uint8_t *JS_GetArrayBuffer(JSContext *ctx, size_t *psize, JSValueConst obj);
JS_EXTERN uint8_t *JS_GetUint8Array(JSContext *ctx, size_t *psize, JSValueConst obj);
JS_EXTERN JSValue JS_GetTypedArrayBuffer(JSContext *ctx, JSValueConst obj,
size_t *pbyte_offset,
size_t *pbyte_length,
size_t *pbytes_per_element);
JS_EXTERN JSValue JS_NewUint8Array(JSContext *ctx, uint8_t *buf, size_t len,
JSFreeArrayBufferDataFunc *free_func, void *opaque,
JS_BOOL is_shared);
JS_EXTERN JS_BOOL JS_IsUint8Array(JSValue obj);
JS_EXTERN JSValue JS_NewUint8ArrayCopy(JSContext *ctx, const uint8_t *buf, size_t len);
typedef struct {
void *(*sab_alloc)(void *opaque, size_t size);
@ -786,21 +793,11 @@ typedef struct {
} JSSharedArrayBufferFunctions;
JS_EXTERN void JS_SetSharedArrayBufferFunctions(JSRuntime *rt, const JSSharedArrayBufferFunctions *sf);
typedef enum JSPromiseStateEnum {
JS_PROMISE_PENDING,
JS_PROMISE_FULFILLED,
JS_PROMISE_REJECTED,
} JSPromiseStateEnum;
JS_EXTERN JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs);
JS_EXTERN JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise);
JS_EXTERN JSValue JS_PromiseResult(JSContext *ctx, JSValue promise);
JS_EXTERN JSValue JS_NewSymbol(JSContext *ctx, const char *description, JS_BOOL is_global);
/* is_handled = TRUE means that the rejection is handled */
typedef void JSHostPromiseRejectionTracker(JSContext *ctx, JSValue promise,
JSValue reason,
typedef void JSHostPromiseRejectionTracker(JSContext *ctx, JSValueConst promise,
JSValueConst reason,
JS_BOOL is_handled, void *opaque);
JS_EXTERN void JS_SetHostPromiseRejectionTracker(JSRuntime *rt, JSHostPromiseRejectionTracker *cb, void *opaque);
@ -810,7 +807,7 @@ JS_EXTERN void JS_SetInterruptHandler(JSRuntime *rt, JSInterruptHandler *cb, voi
/* if can_block is TRUE, Atomics.wait() can be used */
JS_EXTERN void JS_SetCanBlock(JSRuntime *rt, JS_BOOL can_block);
/* set the [IsHTMLDDA] internal slot */
JS_EXTERN void JS_SetIsHTMLDDA(JSContext *ctx, JSValue obj);
JS_EXTERN void JS_SetIsHTMLDDA(JSContext *ctx, JSValueConst obj);
typedef struct JSModuleDef JSModuleDef;
@ -830,12 +827,11 @@ JS_EXTERN void JS_SetModuleLoaderFunc(JSRuntime *rt,
/* return the import.meta object of a module */
JS_EXTERN JSValue JS_GetImportMeta(JSContext *ctx, JSModuleDef *m);
JS_EXTERN JSAtom JS_GetModuleName(JSContext *ctx, JSModuleDef *m);
JSValue JS_GetModuleNamespace(JSContext *ctx, JSModuleDef *m);
/* JS Job support */
typedef JSValue JSJobFunc(JSContext *ctx, int argc, JSValue *argv);
JS_EXTERN int JS_EnqueueJob(JSContext *ctx, JSJobFunc *job_func, int argc, JSValue *argv);
typedef JSValue JSJobFunc(JSContext *ctx, int argc, JSValueConst *argv);
JS_EXTERN int JS_EnqueueJob(JSContext *ctx, JSJobFunc *job_func, int argc, JSValueConst *argv);
JS_EXTERN JS_BOOL JS_IsJobPending(JSRuntime *rt);
JS_EXTERN int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx);
@ -844,15 +840,15 @@ JS_EXTERN int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx);
#define JS_WRITE_OBJ_BYTECODE (1 << 0) /* allow function/module */
#define JS_WRITE_OBJ_BSWAP (0) /* byte swapped output (obsolete, handled transparently) */
#define JS_WRITE_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */
#define JS_WRITE_OBJ_REFERENCE (1 << 3) /* allow object references to encode arbitrary object graph */
#define JS_WRITE_OBJ_STRIP_SOURCE (1 << 4) /* do not write source code information */
#define JS_WRITE_OBJ_STRIP_DEBUG (1 << 5) /* do not write debug information */
JS_EXTERN uint8_t *JS_WriteObject(JSContext *ctx, size_t *psize, JSValue obj, int flags);
JS_EXTERN uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValue obj,
#define JS_WRITE_OBJ_REFERENCE (1 << 3) /* allow object references to
encode arbitrary object
graph */
JS_EXTERN uint8_t *JS_WriteObject(JSContext *ctx, size_t *psize, JSValueConst obj, int flags);
JS_EXTERN uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValueConst obj,
int flags, uint8_t ***psab_tab, size_t *psab_tab_len);
#define JS_READ_OBJ_BYTECODE (1 << 0) /* allow function/module */
#define JS_READ_OBJ_ROM_DATA (0) /* avoid duplicating 'buf' data (obsolete, broken by ICs) */
#define JS_READ_OBJ_ROM_DATA (1 << 1) /* avoid duplicating 'buf' data */
#define JS_READ_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */
#define JS_READ_OBJ_REFERENCE (1 << 3) /* allow object references */
JS_EXTERN JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_len, int flags);
@ -861,12 +857,12 @@ JS_EXTERN JSValue JS_ReadObject(JSContext *ctx, const uint8_t *buf, size_t buf_l
JS_EXTERN JSValue JS_EvalFunction(JSContext *ctx, JSValue fun_obj);
/* load the dependencies of the module 'obj'. Useful when JS_ReadObject()
returns a module. */
JS_EXTERN int JS_ResolveModule(JSContext *ctx, JSValue obj);
JS_EXTERN int JS_ResolveModule(JSContext *ctx, JSValueConst obj);
/* only exported for os.Worker() */
JS_EXTERN JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels);
/* only exported for os.Worker() */
JS_EXTERN JSValue JS_LoadModule(JSContext *ctx, const char *basename,
JS_EXTERN JSModuleDef *JS_RunModule(JSContext *ctx, const char *basename,
const char *filename);
/* C function definition */
@ -888,18 +884,18 @@ typedef enum JSCFunctionEnum { /* XXX: should rename for namespace isolation */
typedef union JSCFunctionType {
JSCFunction *generic;
JSValue (*generic_magic)(JSContext *ctx, JSValue this_val, int argc, JSValue *argv, int magic);
JSValue (*generic_magic)(JSContext *ctx, JSValueConst this_val, int argc, JSValueConst *argv, int magic);
JSCFunction *constructor;
JSValue (*constructor_magic)(JSContext *ctx, JSValue new_target, int argc, JSValue *argv, int magic);
JSValue (*constructor_magic)(JSContext *ctx, JSValueConst new_target, int argc, JSValueConst *argv, int magic);
JSCFunction *constructor_or_func;
double (*f_f)(double);
double (*f_f_f)(double, double);
JSValue (*getter)(JSContext *ctx, JSValue this_val);
JSValue (*setter)(JSContext *ctx, JSValue this_val, JSValue val);
JSValue (*getter_magic)(JSContext *ctx, JSValue this_val, int magic);
JSValue (*setter_magic)(JSContext *ctx, JSValue this_val, JSValue val, int magic);
JSValue (*iterator_next)(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv, int *pdone, int magic);
JSValue (*getter)(JSContext *ctx, JSValueConst this_val);
JSValue (*setter)(JSContext *ctx, JSValueConst this_val, JSValueConst val);
JSValue (*getter_magic)(JSContext *ctx, JSValueConst this_val, int magic);
JSValue (*setter_magic)(JSContext *ctx, JSValueConst this_val, JSValueConst val, int magic);
JSValue (*iterator_next)(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv, int *pdone, int magic);
} JSCFunctionType;
JS_EXTERN JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func,
@ -907,7 +903,7 @@ JS_EXTERN JSValue JS_NewCFunction2(JSContext *ctx, JSCFunction *func,
int length, JSCFunctionEnum cproto, int magic);
JS_EXTERN JSValue JS_NewCFunctionData(JSContext *ctx, JSCFunctionData *func,
int length, int magic, int data_len,
JSValue *data);
JSValueConst *data);
static inline JSValue JS_NewCFunction(JSContext *ctx, JSCFunction *func, const char *name,
int length)
@ -923,13 +919,13 @@ static inline JSValue JS_NewCFunctionMagic(JSContext *ctx, JSCFunctionMagic *fun
JSCFunctionType ft = { .generic_magic = func };
return JS_NewCFunction2(ctx, ft.generic, name, length, cproto, magic);
}
JS_EXTERN void JS_SetConstructor(JSContext *ctx, JSValue func_obj,
JSValue proto);
JS_EXTERN void JS_SetConstructor(JSContext *ctx, JSValueConst func_obj,
JSValueConst proto);
/* C property definition */
typedef struct JSCFunctionListEntry {
const char *name; /* pure ASCII or UTF-8 encoded */
const char *name;
uint8_t prop_flags;
uint8_t def_type;
int16_t magic;
@ -951,7 +947,7 @@ typedef struct JSCFunctionListEntry {
const struct JSCFunctionListEntry *tab;
int len;
} prop_list;
const char *str; /* pure ASCII or UTF-8 encoded */
const char *str;
int32_t i32;
int64_t i64;
double f64;
@ -970,23 +966,23 @@ typedef struct JSCFunctionListEntry {
#define JS_DEF_ALIAS 9
/* Note: c++ does not like nested designators */
#define JS_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
#define JS_CFUNC_DEF2(name, length, func1, prop_flags) { name, prop_flags, JS_DEF_CFUNC, 0, { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
#define JS_CFUNC_MAGIC_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, { .func = { length, JS_CFUNC_generic_magic, { .generic_magic = func1 } } } }
#define JS_CFUNC_SPECIAL_DEF(name, length, cproto, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, { .func = { length, JS_CFUNC_ ## cproto, { .cproto = func1 } } } }
#define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, { .func = { length, JS_CFUNC_iterator_next, { .iterator_next = func1 } } } }
#define JS_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET, 0, { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
#define JS_CGETSET_MAGIC_DEF(name, fgetter, fsetter, magic) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET_MAGIC, magic, { .getset = { .get = { .getter_magic = fgetter }, .set = { .setter_magic = fsetter } } } }
#define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, { .str = cstr } }
#define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, { .i32 = val } }
#define JS_PROP_INT64_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT64, 0, { .i64 = val } }
#define JS_PROP_DOUBLE_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_DOUBLE, 0, { .f64 = val } }
#define JS_PROP_UNDEFINED_DEF(name, prop_flags) { name, prop_flags, JS_DEF_PROP_UNDEFINED, 0, { .i32 = 0 } }
#define JS_OBJECT_DEF(name, tab, len, prop_flags) { name, prop_flags, JS_DEF_OBJECT, 0, { .prop_list = { tab, len } } }
#define JS_ALIAS_DEF(name, from) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, { .alias = { from, -1 } } }
#define JS_ALIAS_BASE_DEF(name, from, base) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, { .alias = { from, base } } }
#define JS_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
#define JS_CFUNC_DEF2(name, length, func1, prop_flags) { name, prop_flags, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
#define JS_CFUNC_MAGIC_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_generic_magic, { .generic_magic = func1 } } } }
#define JS_CFUNC_SPECIAL_DEF(name, length, cproto, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_ ## cproto, { .cproto = func1 } } } }
#define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_iterator_next, { .iterator_next = func1 } } } }
#define JS_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
#define JS_CGETSET_MAGIC_DEF(name, fgetter, fsetter, magic) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET_MAGIC, magic, .u = { .getset = { .get = { .getter_magic = fgetter }, .set = { .setter_magic = fsetter } } } }
#define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, .u = { .str = cstr } }
#define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, .u = { .i32 = val } }
#define JS_PROP_INT64_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT64, 0, .u = { .i64 = val } }
#define JS_PROP_DOUBLE_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_DOUBLE, 0, .u = { .f64 = val } }
#define JS_PROP_UNDEFINED_DEF(name, prop_flags) { name, prop_flags, JS_DEF_PROP_UNDEFINED, 0, .u = { .i32 = 0 } }
#define JS_OBJECT_DEF(name, tab, len, prop_flags) { name, prop_flags, JS_DEF_OBJECT, 0, .u = { .prop_list = { tab, len } } }
#define JS_ALIAS_DEF(name, from) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, -1 } } }
#define JS_ALIAS_BASE_DEF(name, from, base) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, base } } }
JS_EXTERN void JS_SetPropertyFunctionList(JSContext *ctx, JSValue obj,
JS_EXTERN void JS_SetPropertyFunctionList(JSContext *ctx, JSValueConst obj,
const JSCFunctionListEntry *tab,
int len);
@ -1006,16 +1002,28 @@ JS_EXTERN int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *exp
JS_EXTERN int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
const JSCFunctionListEntry *tab, int len);
/* Promise */
typedef enum JSPromiseStateEnum {
JS_PROMISE_PENDING,
JS_PROMISE_FULFILLED,
JS_PROMISE_REJECTED,
} JSPromiseStateEnum;
JS_EXTERN JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise);
JS_EXTERN JSValue JS_PromiseResult(JSContext *ctx, JSValue promise);
/* Version */
#define QJS_VERSION_MAJOR 0
#define QJS_VERSION_MINOR 6
#define QJS_VERSION_MINOR 3
#define QJS_VERSION_PATCH 0
#define QJS_VERSION_SUFFIX "dev"
JS_EXTERN const char* JS_GetVersion(void);
#undef JS_EXTERN
#undef js_unlikely
#undef js_force_inline
#undef __js_printf_like

929
repl.js

File diff suppressed because it is too large Load diff

View file

@ -371,8 +371,8 @@ static void enumerate_tests(const char *path)
namelist_cmp_indirect);
}
static JSValue js_print(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
static JSValue js_print(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
int i;
const char *str;
@ -508,7 +508,7 @@ static void *agent_start(void *arg)
NULL, NULL, TRUE);
args[1] = JS_NewInt32(ctx, agent->broadcast_val);
ret_val = JS_Call(ctx, agent->broadcast_func, JS_UNDEFINED,
2, args);
2, (JSValueConst *)args);
JS_FreeValue(ctx, args[0]);
JS_FreeValue(ctx, args[1]);
if (JS_IsException(ret_val))
@ -594,7 +594,7 @@ static BOOL is_broadcast_pending(void)
static JSValue js_agent_broadcast(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
{
JSValue sab = argv[0];
JSValueConst sab = argv[0];
struct list_head *el;
Test262Agent *agent;
uint8_t *buf;
@ -820,19 +820,6 @@ static JSModuleDef *js_module_loader_test(JSContext *ctx,
uint8_t *buf;
JSModuleDef *m;
JSValue func_val;
char *filename, *slash, path[1024];
// interpret import("bar.js") from path/to/foo.js as
// import("path/to/bar.js") but leave import("./bar.js") untouched
filename = opaque;
if (!strchr(module_name, '/')) {
slash = strrchr(filename, '/');
if (slash) {
snprintf(path, sizeof(path), "%.*s/%s",
(int) (slash - filename), filename, module_name);
module_name = path;
}
}
buf = js_load_file(ctx, &buf_len, module_name);
if (!buf) {
@ -1198,7 +1185,7 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
{
JSValue res_val, exception_val;
int ret, error_line, pos, pos_line;
BOOL is_error, has_error_line, ret_promise;
BOOL is_error, has_error_line;
const char *error_name;
pos = skip_comments(buf, 1, &pos_line);
@ -1207,19 +1194,12 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
exception_val = JS_UNDEFINED;
error_name = NULL;
/* a module evaluation returns a promise */
ret_promise = ((eval_flags & JS_EVAL_TYPE_MODULE) != 0);
async_done = 0; /* counter of "Test262:AsyncTestComplete" messages */
res_val = JS_Eval(ctx, buf, buf_len, filename, eval_flags);
if ((is_async || ret_promise) && !JS_IsException(res_val)) {
JSValue promise = JS_UNDEFINED;
if (ret_promise) {
promise = res_val;
} else {
if (is_async && !JS_IsException(res_val)) {
JS_FreeValue(ctx, res_val);
}
for(;;) {
JSContext *ctx1;
ret = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1);
@ -1227,23 +1207,34 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
res_val = JS_EXCEPTION;
break;
} else if (ret == 0) {
if (is_async) {
/* test if the test called $DONE() once */
if (async_done != 1) {
res_val = JS_ThrowTypeError(ctx, "$DONE() not called");
} else {
res_val = JS_UNDEFINED;
}
} else {
/* check that the returned promise is fulfilled */
JSPromiseStateEnum state = JS_PromiseState(ctx, promise);
if (state == JS_PROMISE_FULFILLED)
break;
}
}
} else if ((eval_flags & JS_EVAL_TYPE_MODULE) &&
!JS_IsUndefined(res_val) &&
!JS_IsException(res_val)) {
JSValue promise = res_val;
for(;;) {
JSContext *ctx1;
ret = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1);
if (ret < 0) {
res_val = JS_EXCEPTION;
break;
}
if (ret == 0) {
JSPromiseStateEnum s = JS_PromiseState(ctx, promise);
if (s == JS_PROMISE_FULFILLED)
res_val = JS_UNDEFINED;
else if (state == JS_PROMISE_REJECTED)
else if (s == JS_PROMISE_REJECTED)
res_val = JS_Throw(ctx, JS_PromiseResult(ctx, promise));
else
res_val = JS_ThrowTypeError(ctx, "promise is pending");
}
res_val = JS_EXCEPTION;
break;
}
}
@ -1295,16 +1286,12 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
const char *msg;
msg = JS_ToCString(ctx, exception_val);
if (msg == NULL) {
ret = -1;
} else {
error_class = strdup_len(msg, strcspn(msg, ":"));
if (!str_equal(error_class, error_type))
ret = -1;
free(error_class);
JS_FreeCString(ctx, msg);
}
}
} else {
ret = -1;
}
@ -1503,9 +1490,7 @@ void update_stats(JSRuntime *rt, const char *filename) {
JS_ComputeMemoryUsage(rt, &stats);
if (stats_count++ == 0) {
stats_avg = stats_all = stats_min = stats_max = stats;
free(stats_min_filename);
stats_min_filename = strdup(filename);
free(stats_max_filename);
stats_max_filename = strdup(filename);
} else {
if (stats_max.malloc_size < stats.malloc_size) {
@ -1570,7 +1555,7 @@ int run_test_buf(const char *filename, char *harness, namelist_t *ip,
JS_SetCanBlock(rt, can_block);
/* loader for ES6 modules */
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader_test, (void *) filename);
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader_test, NULL);
add_helpers(ctx);
@ -1866,7 +1851,7 @@ int run_test262_harness_test(const char *filename, BOOL is_module)
JS_SetCanBlock(rt, can_block);
/* loader for ES6 modules */
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader_test, (void *) filename);
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader_test, NULL);
add_helpers(ctx);
@ -1882,13 +1867,8 @@ int run_test262_harness_test(const char *filename, BOOL is_module)
if (JS_IsException(res_val)) {
js_std_dump_error(ctx);
ret_code = 1;
} else {
JSValue promise = JS_UNDEFINED;
if (is_module) {
promise = res_val;
} else {
JS_FreeValue(ctx, res_val);
}
for(;;) {
JSContext *ctx1;
ret = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1);
@ -1899,16 +1879,6 @@ int run_test262_harness_test(const char *filename, BOOL is_module)
break;
}
}
/* dump the error if the module returned an error. */
if (is_module) {
JSPromiseStateEnum state = JS_PromiseState(ctx, promise);
if (state == JS_PROMISE_REJECTED) {
JS_Throw(ctx, JS_PromiseResult(ctx, promise));
js_std_dump_error(ctx);
ret_code = 1;
}
}
JS_FreeValue(ctx, promise);
}
free(buf);
#ifdef CONFIG_AGENT
@ -2195,12 +2165,7 @@ int main(int argc, char **argv)
free(harness_dir);
free(harness_features);
free(harness_exclude);
free(harness_skip_features);
free(error_file);
free(error_filename);
free(report_filename);
free(stats_min_filename);
free(stats_max_filename);
/* Signal that the error file is out of date. */
return new_errors || changed_errors || fixed_errors;

View file

@ -1,132 +0,0 @@
[exclude]
# list excluded tests and directories here for faster operation
# lengthy constructed regexp (>500 ms)
test262/test/annexB/built-ins/RegExp/RegExp-leading-escape-BMP.js
test262/test/annexB/built-ins/RegExp/RegExp-trailing-escape-BMP.js
# slow notifications (> 600 ms)
test262/test/built-ins/Atomics/notify/notify-in-order-one-time.js
test262/test/built-ins/Atomics/notify/notify-in-order.js
test262/test/built-ins/Atomics/wait/bigint/waiterlist-order-of-operations-is-fifo.js
test262/test/built-ins/Atomics/wait/waiterlist-order-of-operations-is-fifo.js
# lengthy constructed regexp (>200 ms)
test262/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-flags-u.js
test262/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier-flags-u.js
test262/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-flags-u.js
test262/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier-flags-u.js
test262/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-flags-u.js
test262/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier-flags-u.js
test262/test/built-ins/RegExp/character-class-escape-non-whitespace.js
# 417 lengty tests with huge constructed regexp (>200 ms)
test262/test/built-ins/RegExp/property-escapes/generated/
# lengthy constructed URLS (>200 ms)
test262/test/built-ins/decodeURI/S15.1.3.1_A1.2_T1.js
test262/test/built-ins/decodeURI/S15.1.3.1_A1.2_T2.js
test262/test/built-ins/decodeURI/S15.1.3.1_A1.10_T1.js
test262/test/built-ins/decodeURI/S15.1.3.1_A1.11_T1.js
test262/test/built-ins/decodeURI/S15.1.3.1_A1.11_T2.js
test262/test/built-ins/decodeURI/S15.1.3.1_A1.12_T1.js
test262/test/built-ins/decodeURI/S15.1.3.1_A1.12_T2.js
test262/test/built-ins/decodeURI/S15.1.3.1_A1.12_T3.js
test262/test/built-ins/decodeURI/S15.1.3.1_A2.5_T1.js
test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.2_T1.js
test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.2_T2.js
test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.10_T1.js
test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.11_T1.js
test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.11_T2.js
test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.12_T1.js
test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.12_T2.js
test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.12_T3.js
test262/test/built-ins/decodeURIComponent/S15.1.3.2_A2.5_T1.js
# lengthy comment tests
test262/test/language/comments/S7.4_A5.js
test262/test/language/comments/S7.4_A6.js
# lengthy unicode level tests
test262/test/language/identifiers/start-unicode-5.2.0-class-escaped.js
test262/test/language/identifiers/start-unicode-5.2.0-class.js
test262/test/language/identifiers/start-unicode-8.0.0-class-escaped.js
test262/test/language/identifiers/start-unicode-8.0.0-class.js
test262/test/language/identifiers/start-unicode-9.0.0-class-escaped.js
test262/test/language/identifiers/start-unicode-9.0.0-class.js
test262/test/language/identifiers/start-unicode-10.0.0-class-escaped.js
test262/test/language/identifiers/start-unicode-10.0.0-class.js
test262/test/language/identifiers/start-unicode-13.0.0-class-escaped.js
test262/test/language/identifiers/start-unicode-13.0.0-class.js
test262/test/language/identifiers/start-unicode-15.0.0-class-escaped.js
test262/test/language/identifiers/start-unicode-15.0.0-class.js
# Atomics tests with 2 second delays
test262/test/built-ins/Atomics/notify/bigint/notify-all-on-loc.js
test262/test/built-ins/Atomics/notify/negative-count.js
test262/test/built-ins/Atomics/notify/notify-all-on-loc.js
test262/test/built-ins/Atomics/notify/notify-all.js
test262/test/built-ins/Atomics/notify/notify-nan.js
test262/test/built-ins/Atomics/notify/notify-one.js
test262/test/built-ins/Atomics/notify/notify-two.js
test262/test/built-ins/Atomics/notify/notify-zero.js
# Atomics tests with 400 millisecond delays
test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-no-operation.js
test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-add.js
test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-and.js
test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-compareExchange.js
test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-exchange.js
test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-or.js
test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-store.js
test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-sub.js
test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-xor.js
test262/test/built-ins/Atomics/wait/no-spurious-wakeup-no-operation.js
test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-add.js
test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-and.js
test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-compareExchange.js
test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-exchange.js
test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-or.js
test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-store.js
test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-sub.js
test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-xor.js
# Atomics tests with 200 millisecond delays
test262/test/built-ins/Atomics/notify/count-defaults-to-infinity-missing.js
test262/test/built-ins/Atomics/notify/count-defaults-to-infinity-undefined.js
test262/test/built-ins/Atomics/notify/notify-renotify-noop.js
test262/test/built-ins/Atomics/notify/undefined-index-defaults-to-zero.js
test262/test/built-ins/Atomics/wait/bigint/false-for-timeout-agent.js
test262/test/built-ins/Atomics/wait/bigint/nan-for-timeout.js
test262/test/built-ins/Atomics/wait/bigint/negative-timeout-agent.js
test262/test/built-ins/Atomics/wait/bigint/value-not-equal.js
test262/test/built-ins/Atomics/wait/bigint/was-woken-before-timeout.js
test262/test/built-ins/Atomics/wait/false-for-timeout-agent.js
test262/test/built-ins/Atomics/wait/nan-for-timeout.js
test262/test/built-ins/Atomics/wait/negative-timeout-agent.js
test262/test/built-ins/Atomics/wait/null-for-timeout-agent.js
test262/test/built-ins/Atomics/wait/object-for-timeout-agent.js
test262/test/built-ins/Atomics/wait/poisoned-object-for-timeout-throws-agent.js
test262/test/built-ins/Atomics/wait/symbol-for-index-throws-agent.js
test262/test/built-ins/Atomics/wait/symbol-for-timeout-throws-agent.js
test262/test/built-ins/Atomics/wait/symbol-for-value-throws-agent.js
test262/test/built-ins/Atomics/wait/true-for-timeout-agent.js
test262/test/built-ins/Atomics/wait/undefined-for-timeout.js
test262/test/built-ins/Atomics/wait/undefined-index-defaults-to-zero.js
test262/test/built-ins/Atomics/wait/value-not-equal.js
test262/test/built-ins/Atomics/wait/wait-index-value-not-equal.js
test262/test/built-ins/Atomics/wait/was-woken-before-timeout.js
# lengthy regexp literal construction (>500 ms)
test262/test/language/literals/regexp/S7.8.5_A1.1_T2.js
test262/test/language/literals/regexp/S7.8.5_A1.4_T2.js
test262/test/language/literals/regexp/S7.8.5_A2.1_T2.js
test262/test/language/literals/regexp/S7.8.5_A2.4_T2.js
# lengthy built-ins tests (100-200 ms)
test262/test/built-ins/Function/prototype/toString/built-in-function-object.js
test262/test/built-ins/decodeURI/S15.1.3.1_A2.4_T1.js
test262/test/built-ins/decodeURIComponent/S15.1.3.2_A2.4_T1.js
test262/test/built-ins/encodeURI/S15.1.3.3_A2.3_T1.js
test262/test/built-ins/encodeURIComponent/S15.1.3.4_A2.3_T1.js
test262/test/language/expressions/dynamic-import/await-import-evaluation.js

View file

@ -69,7 +69,7 @@ arraybuffer-transfer
arrow-function
async-functions
async-iteration
Atomics
Atomics=skip # disabled because of Windows <-> pthreads
Atomics.waitAsync=skip
BigInt
caller
@ -157,7 +157,7 @@ regexp-lookbehind
regexp-match-indices
regexp-named-groups
regexp-unicode-property-escapes
regexp-v-flag
regexp-v-flag=skip
resizable-arraybuffer=skip
rest-parameters
Set
@ -223,147 +223,5 @@ test262/test/built-ins/ThrowTypeError/unique-per-realm-function-proto.js
#test262/test/built-ins/RegExp/CharacterClassEscapes/
#test262/test/built-ins/RegExp/property-escapes/
# in progress regexp-v-flag support, see https://github.com/quickjs-ng/quickjs/issues/228
test262/test/built-ins/RegExp/property-escapes/generated/strings/Basic_Emoji-negative-CharacterClass.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/Basic_Emoji-negative-P.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/Basic_Emoji-negative-u.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/Basic_Emoji.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/Emoji_Keycap_Sequence-negative-CharacterClass.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/Emoji_Keycap_Sequence-negative-P.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/Emoji_Keycap_Sequence-negative-u.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/Emoji_Keycap_Sequence.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji-negative-CharacterClass.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji-negative-P.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji-negative-u.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Flag_Sequence-negative-CharacterClass.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Flag_Sequence-negative-P.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Flag_Sequence-negative-u.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Flag_Sequence.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Modifier_Sequence-negative-CharacterClass.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Modifier_Sequence-negative-P.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Modifier_Sequence-negative-u.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Modifier_Sequence.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Tag_Sequence-negative-CharacterClass.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Tag_Sequence-negative-P.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Tag_Sequence-negative-u.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Tag_Sequence.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_ZWJ_Sequence-negative-CharacterClass.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_ZWJ_Sequence-negative-P.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_ZWJ_Sequence-negative-u.js
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_ZWJ_Sequence.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-difference-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-difference-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-difference-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-difference-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-difference-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-difference-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-difference-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-difference-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-difference-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-difference-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-difference-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-difference-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-intersection-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-intersection-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-intersection-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-intersection-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-intersection-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-intersection-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-union-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-union-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-union-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-union-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-union-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-union-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-intersection-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-intersection-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-intersection-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-intersection-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-intersection-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-intersection-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-union-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-union-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-union-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-union-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-union-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-union-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-difference-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-difference-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-difference-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-difference-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-difference-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-difference-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-intersection-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-intersection-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-intersection-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-intersection-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-intersection-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-intersection-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-difference-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-difference-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-difference-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-difference-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-difference-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-difference-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-intersection-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-intersection-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-intersection-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-intersection-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-intersection-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-intersection-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-union-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-union-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-union-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-union-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-union-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-union-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-union-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-union-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-union-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-union-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-union-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/character-union-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-difference-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-difference-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-difference-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-difference-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-difference-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-difference-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-intersection-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-intersection-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-intersection-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-intersection-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-intersection-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-intersection-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-union-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-union-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-union-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-union-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-union-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-union-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/rgi-emoji-13.1.js
test262/test/built-ins/RegExp/unicodeSets/generated/rgi-emoji-14.0.js
test262/test/built-ins/RegExp/unicodeSets/generated/rgi-emoji-15.0.js
test262/test/built-ins/RegExp/unicodeSets/generated/rgi-emoji-15.1.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-difference-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-difference-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-difference-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-difference-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-difference-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-difference-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-intersection-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-intersection-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-intersection-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-intersection-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-intersection-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-intersection-string-literal.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-union-character-class-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-union-character-class.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-union-character-property-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-union-character.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-union-property-of-strings-escape.js
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-union-string-literal.js
[tests]
# list test files or use config.testdir

View file

@ -1,12 +1,163 @@
test262/test/annexB/language/eval-code/direct/script-decl-lex-collision-in-sloppy-mode.js:13: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
test262/test/built-ins/AsyncGeneratorPrototype/return/return-suspendedYield-broken-promise-try-catch.js:39: TypeError: $DONE() not called
test262/test/built-ins/AsyncGeneratorPrototype/return/return-suspendedYield-broken-promise-try-catch.js:39: strict mode: TypeError: $DONE() not called
test262/test/built-ins/RegExp/lookahead-quantifier-match-groups.js:27: Test262Error: Expected [a, abc] and [a, undefined] to have the same contents. ? quantifier
test262/test/built-ins/RegExp/lookahead-quantifier-match-groups.js:27: strict mode: Test262Error: Expected [a, abc] and [a, undefined] to have the same contents. ? quantifier
test262/test/built-ins/TypedArray/prototype/set/array-arg-targetbuffer-detached-on-get-src-value-no-throw.js:30: TypeError: out-of-bound numeric index (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/set/array-arg-targetbuffer-detached-on-get-src-value-no-throw.js:30: strict mode: TypeError: out-of-bound numeric index (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/sort/sort-tonumber.js:30: TypeError: ArrayBuffer is detached (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/sort/sort-tonumber.js:30: strict mode: TypeError: ArrayBuffer is detached (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/toReversed/ignores-species.js:26: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/toReversed/ignores-species.js:26: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/toReversed/immutable.js:14: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/toReversed/immutable.js:14: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/toReversed/length-property-ignored.js:21: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/toReversed/length-property-ignored.js:21: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/toReversed/metadata/length.js:30: TypeError: cannot convert to object
test262/test/built-ins/TypedArray/prototype/toReversed/metadata/length.js:30: strict mode: TypeError: cannot convert to object
test262/test/built-ins/TypedArray/prototype/toReversed/metadata/name.js:28: TypeError: cannot convert to object
test262/test/built-ins/TypedArray/prototype/toReversed/metadata/name.js:28: strict mode: TypeError: cannot convert to object
test262/test/built-ins/TypedArray/prototype/toReversed/metadata/property-descriptor.js:18: Test262Error: typeof Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/TypedArray/prototype/toReversed/metadata/property-descriptor.js:18: strict mode: Test262Error: typeof Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/TypedArray/prototype/toReversed/not-a-constructor.js:25: Test262Error: isConstructor invoked with a non-function value
test262/test/built-ins/TypedArray/prototype/toReversed/not-a-constructor.js:25: strict mode: Test262Error: isConstructor invoked with a non-function value
test262/test/built-ins/TypedArray/prototype/toSorted/ignores-species.js:26: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/toSorted/ignores-species.js:26: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/toSorted/immutable.js:14: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/toSorted/immutable.js:14: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/toSorted/length-property-ignored.js:21: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/toSorted/length-property-ignored.js:21: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/toSorted/metadata/length.js:30: TypeError: cannot convert to object
test262/test/built-ins/TypedArray/prototype/toSorted/metadata/length.js:30: strict mode: TypeError: cannot convert to object
test262/test/built-ins/TypedArray/prototype/toSorted/metadata/name.js:28: TypeError: cannot convert to object
test262/test/built-ins/TypedArray/prototype/toSorted/metadata/name.js:28: strict mode: TypeError: cannot convert to object
test262/test/built-ins/TypedArray/prototype/toSorted/metadata/property-descriptor.js:18: Test262Error: typeof Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/TypedArray/prototype/toSorted/metadata/property-descriptor.js:18: strict mode: Test262Error: typeof Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/TypedArray/prototype/toSorted/not-a-constructor.js:25: Test262Error: isConstructor invoked with a non-function value
test262/test/built-ins/TypedArray/prototype/toSorted/not-a-constructor.js:25: strict mode: Test262Error: isConstructor invoked with a non-function value
test262/test/built-ins/TypedArray/prototype/with/BigInt/early-type-coercion-bigint.js:29: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/with/BigInt/early-type-coercion-bigint.js:29: strict mode: TypeError: not a function (Testing with BigInt64Array.)
test262/test/built-ins/TypedArray/prototype/with/early-type-coercion.js:29: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/early-type-coercion.js:29: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/ignores-species.js:26: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/ignores-species.js:26: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/immutable.js:14: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/immutable.js:14: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/index-bigger-or-eq-than-length.js:22: Test262Error: Expected a RangeError but got a TypeError (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/index-bigger-or-eq-than-length.js:22: strict mode: Test262Error: Expected a RangeError but got a TypeError (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/index-casted-to-number.js:24: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/index-casted-to-number.js:24: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/index-negative.js:24: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/index-negative.js:24: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/index-smaller-than-minus-length.js:22: Test262Error: Expected a RangeError but got a TypeError (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/index-smaller-than-minus-length.js:22: strict mode: Test262Error: Expected a RangeError but got a TypeError (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/length-property-ignored.js:21: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/length-property-ignored.js:21: strict mode: TypeError: not a function (Testing with Float64Array.)
test262/test/built-ins/TypedArray/prototype/with/metadata/length.js:30: TypeError: cannot convert to object
test262/test/built-ins/TypedArray/prototype/with/metadata/length.js:30: strict mode: TypeError: cannot convert to object
test262/test/built-ins/TypedArray/prototype/with/metadata/name.js:28: TypeError: cannot convert to object
test262/test/built-ins/TypedArray/prototype/with/metadata/name.js:28: strict mode: TypeError: cannot convert to object
test262/test/built-ins/TypedArray/prototype/with/metadata/property-descriptor.js:18: Test262Error: typeof Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/TypedArray/prototype/with/metadata/property-descriptor.js:18: strict mode: Test262Error: typeof Expected SameValue(«undefined», «function») to be true
test262/test/built-ins/TypedArray/prototype/with/not-a-constructor.js:25: Test262Error: isConstructor invoked with a non-function value
test262/test/built-ins/TypedArray/prototype/with/not-a-constructor.js:25: strict mode: Test262Error: isConstructor invoked with a non-function value
test262/test/built-ins/TypedArrayConstructors/ctors/no-species.js:16: Test262Error: unreachable
test262/test/built-ins/TypedArrayConstructors/ctors/no-species.js:16: strict mode: Test262Error: unreachable
test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/BigInt/detached-buffer.js:46: Test262Error: (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/BigInt/detached-buffer.js:46: strict mode: Test262Error: (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/BigInt/tonumber-value-detached-buffer.js:40: Test262Error: Reflect.defineProperty(ta, 0, {value: {valueOf() {$DETACHBUFFER(ta.buffer); return 42n;}}}) must return true Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/BigInt/tonumber-value-detached-buffer.js:40: strict mode: Test262Error: Reflect.defineProperty(ta, 0, {value: {valueOf() {$DETACHBUFFER(ta.buffer); return 42n;}}}) must return true Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/detached-buffer.js:47: Test262Error: (Testing with Float64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/detached-buffer.js:47: strict mode: Test262Error: (Testing with Float64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/tonumber-value-detached-buffer.js:42: Test262Error: Reflect.defineProperty(ta, 0, {value: {valueOf() {$DETACHBUFFER(ta.buffer); return 42;}}} ) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/tonumber-value-detached-buffer.js:42: strict mode: Test262Error: Reflect.defineProperty(ta, 0, {value: {valueOf() {$DETACHBUFFER(ta.buffer); return 42;}}} ) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/detached-buffer-realm.js:37: strict mode: TypeError: out-of-bound numeric index (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/detached-buffer.js:34: TypeError: cannot convert bigint to number (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/detached-buffer.js:32: strict mode: TypeError: out-of-bound numeric index (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-minus-zero.js:20: Test262Error: Reflect.set("new TA([42n])", "-0", 1n) must return true Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-minus-zero.js:20: strict mode: Test262Error: Reflect.set("new TA([42n])", "-0", 1n) must return true Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-not-integer.js:21: Test262Error: Reflect.set("new TA([42n])", "1.1", 1n) must return true Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-not-integer.js:21: strict mode: Test262Error: Reflect.set("new TA([42n])", "1.1", 1n) must return true Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-out-of-bounds.js:27: Test262Error: Reflect.set("new TA([42n])", "-1", 1n) must return false Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-out-of-bounds.js:27: strict mode: Test262Error: Reflect.set("new TA([42n])", "-1", 1n) must return false Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/tonumber-value-detached-buffer.js:24: Test262Error: Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/tonumber-value-detached-buffer.js:24: strict mode: Test262Error: Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/detached-buffer-realm.js:37: strict mode: TypeError: out-of-bound numeric index (Testing with Float64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/detached-buffer.js:32: strict mode: TypeError: out-of-bound numeric index (Testing with Float64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-minus-zero.js:22: Test262Error: Reflect.set(sample, "-0", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-minus-zero.js:22: strict mode: Test262Error: Reflect.set(sample, "-0", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-not-integer.js:22: Test262Error: Reflect.set(sample, "1.1", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-not-integer.js:22: strict mode: Test262Error: Reflect.set(sample, "1.1", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds.js:22: Test262Error: Reflect.set(sample, "-1", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds.js:22: strict mode: Test262Error: Reflect.set(sample, "-1", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/tonumber-value-detached-buffer.js:39: Test262Error: Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
test262/test/built-ins/TypedArrayConstructors/internals/Set/tonumber-value-detached-buffer.js:39: strict mode: Test262Error: Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
test262/test/language/expressions/arrow-function/static-init-await-reference.js:12: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/expressions/arrow-function/static-init-await-reference.js:12: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/expressions/assignment/target-member-computed-reference-null.js:32: Test262Error: Expected a DummyError but got a TypeError
test262/test/language/expressions/assignment/target-member-computed-reference-null.js:32: strict mode: Test262Error: Expected a DummyError but got a TypeError
test262/test/language/expressions/assignment/target-member-computed-reference-undefined.js:32: Test262Error: Expected a DummyError but got a TypeError
test262/test/language/expressions/assignment/target-member-computed-reference-undefined.js:32: strict mode: Test262Error: Expected a DummyError but got a TypeError
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-add.js:59: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «3») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-add.js:59: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «3») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-bitand.js:59: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «0») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-bitand.js:59: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «0») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-bitor.js:59: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «15») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-bitor.js:59: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «15») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-bitxor.js:59: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «257») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-bitxor.js:59: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «257») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-div.js:59: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «0.5») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-div.js:59: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «0.5») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-exp.js:59: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «1000») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-exp.js:59: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «1000») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-lshift.js:59: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «96») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-lshift.js:59: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «96») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-mod.js:59: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «1») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-mod.js:59: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «1») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-mult.js:59: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «6») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-mult.js:59: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «6») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-rshift.js:59: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «3») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-rshift.js:59: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «3») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-srshift.js:59: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «3») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-srshift.js:59: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «3») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-sub.js:59: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «1») to be true
test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-sub.js:59: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «1») to be true
test262/test/language/expressions/delete/super-property-null-base.js:26: Test262Error: Expected a ReferenceError but got a TypeError
test262/test/language/expressions/delete/super-property-null-base.js:26: strict mode: Test262Error: Expected a ReferenceError but got a TypeError
test262/test/language/expressions/dynamic-import/usage-from-eval.js:26: TypeError: $DONE() not called
test262/test/language/expressions/dynamic-import/usage-from-eval.js:26: strict mode: TypeError: $DONE() not called
test262/test/language/expressions/function/static-init-await-binding.js:16: SyntaxError: 'await' is a reserved identifier
test262/test/language/expressions/function/static-init-await-binding.js:16: strict mode: SyntaxError: 'await' is a reserved identifier
test262/test/language/expressions/generators/static-init-await-binding.js:16: SyntaxError: 'await' is a reserved identifier
test262/test/language/expressions/generators/static-init-await-binding.js:16: strict mode: SyntaxError: 'await' is a reserved identifier
test262/test/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-and.js:60: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «false») to be true
test262/test/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-and.js:60: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «false») to be true
test262/test/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-nullish.js:59: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «1») to be true
test262/test/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-nullish.js:59: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «1») to be true
test262/test/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-or.js:60: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «true») to be true
test262/test/language/expressions/logical-assignment/left-hand-side-private-reference-accessor-property-or.js:60: strict mode: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «true») to be true
test262/test/language/expressions/optional-chaining/optional-call-preserves-this.js:21: TypeError: cannot read property 'c' of undefined
test262/test/language/expressions/optional-chaining/optional-call-preserves-this.js:16: strict mode: TypeError: cannot read property '_b' of undefined
test262/test/language/expressions/optional-chaining/optional-call-preserves-this.js:15: strict mode: TypeError: cannot read property '_b' of undefined
test262/test/language/global-code/script-decl-lex-var-declared-via-eval-sloppy.js:13: Test262Error: variable Expected a SyntaxError to be thrown but no exception was thrown at all
test262/test/language/statements/async-generator/yield-star-promise-not-unwrapped.js:25: TypeError: $DONE() not called
test262/test/language/statements/async-generator/yield-star-promise-not-unwrapped.js:25: strict mode: TypeError: $DONE() not called
test262/test/language/statements/async-generator/yield-star-return-then-getter-ticks.js:131: TypeError: $DONE() not called
test262/test/language/statements/async-generator/yield-star-return-then-getter-ticks.js:131: strict mode: TypeError: $DONE() not called
test262/test/language/statements/class/elements/private-method-double-initialisation-get-and-set.js:33: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
test262/test/language/statements/class/elements/private-method-double-initialisation-get-and-set.js:33: strict mode: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
test262/test/language/statements/class/elements/private-method-double-initialisation-get.js:32: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
test262/test/language/statements/class/elements/private-method-double-initialisation-get.js:32: strict mode: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
test262/test/language/statements/class/elements/private-method-double-initialisation-set.js:32: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
test262/test/language/statements/class/elements/private-method-double-initialisation-set.js:32: strict mode: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
test262/test/language/statements/class/elements/private-method-double-initialisation.js:32: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
test262/test/language/statements/class/elements/private-method-double-initialisation.js:32: strict mode: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
test262/test/language/statements/class/private-non-static-getter-static-setter-early-error.js:13: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/statements/class/private-non-static-getter-static-setter-early-error.js:13: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/statements/class/private-non-static-setter-static-getter-early-error.js:13: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/statements/class/private-non-static-setter-static-getter-early-error.js:13: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/statements/class/private-static-getter-non-static-setter-early-error.js:13: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/statements/class/private-static-getter-non-static-setter-early-error.js:13: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/statements/class/private-static-setter-non-static-getter-early-error.js:13: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/statements/class/private-static-setter-non-static-getter-early-error.js:13: strict mode: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/statements/for-of/head-lhs-async-invalid.js:14: unexpected error type: Test262: This statement should not be evaluated.
test262/test/language/statements/for-of/head-lhs-async-invalid.js:14: strict mode: unexpected error type: Test262: This statement should not be evaluated.

View file

@ -24,8 +24,8 @@
#include "../quickjs-libc.h"
#include "../cutils.h"
static JSValue js_bjson_read(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
static JSValue js_bjson_read(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
uint8_t *buf;
uint64_t pos, len;
@ -49,8 +49,8 @@ static JSValue js_bjson_read(JSContext *ctx, JSValue this_val,
return obj;
}
static JSValue js_bjson_write(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
static JSValue js_bjson_write(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
size_t len;
uint8_t *buf;

View file

@ -1,14 +0,0 @@
"use strict"
const expect = "function f() { return 42 }"
function f() { return 42 }
{
const actual = f.toString()
if (actual !== expect) throw Error(actual)
}
{
const f = eval(expect + "f")
const actual = f.toString()
if (actual !== expect) throw Error(actual)
}

View file

@ -876,23 +876,9 @@ function int_to_string(n)
var s, r, j;
r = 0;
for(j = 0; j < n; j++) {
s = (j % 10) + '';
s = (j % 100) + '';
s = (j) + '';
s = (j + 1).toString();
}
return n * 3;
}
function int_toString(n)
{
var s, r, j;
r = 0;
for(j = 0; j < n; j++) {
s = (j % 10).toString();
s = (j % 100).toString();
s = (j).toString();
}
return n * 3;
return n;
}
function float_to_string(n)
@ -900,59 +886,9 @@ function float_to_string(n)
var s, r, j;
r = 0;
for(j = 0; j < n; j++) {
s = (j % 10 + 0.1) + '';
s = (j + 0.1) + '';
s = (j * 12345678 + 0.1) + '';
}
return n * 3;
}
function float_toString(n)
{
var s, r, j;
r = 0;
for(j = 0; j < n; j++) {
s = (j % 10 + 0.1).toString();
s = (j + 0.1).toString();
s = (j * 12345678 + 0.1).toString();
}
return n * 3;
}
function float_toFixed(n)
{
var s, r, j;
r = 0;
for(j = 0; j < n; j++) {
s = (j % 10 + 0.1).toFixed(j % 16);
s = (j + 0.1).toFixed(j % 16);
s = (j * 12345678 + 0.1).toFixed(j % 16);
}
return n * 3;
}
function float_toPrecision(n)
{
var s, r, j;
r = 0;
for(j = 0; j < n; j++) {
s = (j % 10 + 0.1).toPrecision(j % 16 + 1);
s = (j + 0.1).toPrecision(j % 16 + 1);
s = (j * 12345678 + 0.1).toPrecision(j % 16 + 1);
}
return n * 3;
}
function float_toExponential(n)
{
var s, r, j;
r = 0;
for(j = 0; j < n; j++) {
s = (j % 10 + 0.1).toExponential(j % 16);
s = (j + 0.1).toExponential(j % 16);
s = (j * 12345678 + 0.1).toExponential(j % 16);
}
return n * 3;
return n;
}
function string_to_int(n)
@ -1047,17 +983,12 @@ function main(argc, argv, g)
//string_build4,
sort_bench,
int_to_string,
int_toString,
float_to_string,
float_toString,
float_toFixed,
float_toPrecision,
float_toExponential,
string_to_int,
string_to_float,
];
var tests = [];
var i, j, n, f, name, found;
var i, j, n, f, name;
if (typeof BigInt == "function") {
/* BigInt test */
@ -1084,14 +1015,14 @@ function main(argc, argv, g)
sort_bench.array_size = +argv[i++];
continue;
}
for (j = 0, found = false; j < test_list.length; j++) {
for (j = 0; j < test_list.length; j++) {
f = test_list[j];
if (f.name.startsWith(name)) {
if (name === f.name) {
tests.push(f);
found = true;
break;
}
}
if (!found) {
if (j == test_list.length) {
console.log("unknown benchmark: " + name);
return 1;
}
@ -1119,9 +1050,6 @@ function main(argc, argv, g)
save_result("microbench-new.txt", log_data);
}
if (typeof scriptArgs === "undefined") {
if (!scriptArgs)
scriptArgs = [];
if (typeof process.argv === "object")
scriptArgs = process.argv.slice(1);
}
main(scriptArgs.length, scriptArgs, this);

View file

@ -85,7 +85,7 @@ function toStr(a)
case "undefined":
return "undefined";
case "string":
return JSON.stringify(a);
return a.__quote();
case "number":
if (a == 0 && 1 / a < 0)
return "-0";

View file

@ -1,105 +1,18 @@
import * as os from "os";
// Keep this at the top; it tests source positions.
function test_exception_source_pos()
{
var e;
try {
throw new Error(""); // line 9, column 19
} catch(_e) {
e = _e;
}
assert(e.stack.includes("test_builtin.js:9:19"));
}
// Keep this at the top; it tests source positions.
function test_function_source_pos() // line 18, column 1
{
function inner() {} // line 20, column 5
var f = eval("function f() {} f");
assert(`${test_function_source_pos.lineNumber}:${test_function_source_pos.columnNumber}`, "18:1");
assert(`${inner.lineNumber}:${inner.columnNumber}`, "20:5");
assert(`${f.lineNumber}:${f.columnNumber}`, "1:1");
}
// Keep this at the top; it tests source positions.
function test_exception_prepare_stack()
{
var e;
Error.prepareStackTrace = (_, frames) => {
// Just return the array to check.
return frames;
};
try {
throw new Error(""); // line 38, column 19
} catch(_e) {
e = _e;
}
assert(e.stack.length === 2);
const f = e.stack[0];
assert(f.getFunctionName() === 'test_exception_prepare_stack');
assert(f.getFileName() === 'tests/test_builtin.js');
assert(f.getLineNumber() === 38);
assert(f.getColumnNumber() === 19);
assert(!f.isNative());
Error.prepareStackTrace = undefined;
}
// Keep this at the top; it tests source positions.
function test_exception_stack_size_limit()
{
var e;
Error.stackTraceLimit = 1;
Error.prepareStackTrace = (_, frames) => {
// Just return the array to check.
return frames;
};
try {
throw new Error(""); // line 66, column 19
} catch(_e) {
e = _e;
}
assert(e.stack.length === 1);
const f = e.stack[0];
assert(f.getFunctionName() === 'test_exception_stack_size_limit');
assert(f.getFileName() === 'tests/test_builtin.js');
assert(f.getLineNumber() === 66);
assert(f.getColumnNumber() === 19);
assert(!f.isNative());
Error.stackTraceLimit = 10;
Error.prepareStackTrace = undefined;
}
function assert(actual, expected, message) {
if (arguments.length == 1)
expected = true;
if (typeof actual === typeof expected) {
if (actual === expected) {
if (actual !== 0 || (1 / actual) === (1 / expected))
if (actual === expected)
return;
}
if (typeof actual === 'number') {
if (isNaN(actual) && isNaN(expected))
return true;
}
if (typeof actual === 'object') {
if (actual !== null && expected !== null
&& actual.constructor === expected.constructor
&& typeof actual == 'object' && typeof expected == 'object'
&& actual.toString() === expected.toString())
return;
}
}
throw Error("assertion failed: got |" + actual + "|" +
", expected |" + expected + "|" +
(message ? " (" + message + ")" : ""));
@ -220,8 +133,6 @@ function test()
assert(Object.isExtensible(a), false, "extensible");
assert(typeof a.y, "undefined", "extensible");
assert(err, true, "extensible");
assert_throws(TypeError, () => Object.setPrototypeOf(Object.prototype, {}));
}
function test_enum()
@ -434,17 +345,17 @@ function test_number()
assert(Number.isNaN(Number("-")));
assert(Number.isNaN(Number("\x00a")));
assert((1-2**-53).toString(12), "0.bbbbbbbbbbbbbba");
assert((1000000000000000128).toString(), "1000000000000000100");
assert((1000000000000000128).toFixed(0), "1000000000000000128");
// TODO: Fix rounding errors on Windows/Cygwin.
if (['win32', 'cygwin'].includes(os.platform)) {
return;
}
assert((25).toExponential(0), "3e+1");
assert((-25).toExponential(0), "-3e+1");
assert((2.5).toPrecision(1), "3");
assert((-2.5).toPrecision(1), "-3");
assert((1.125).toFixed(2), "1.13");
assert((-1.125).toFixed(2), "-1.13");
assert((0.5).toFixed(0), "1");
assert((-0.5).toFixed(0), "-1");
}
function test_eval2()
@ -461,20 +372,6 @@ function test_eval2()
f1(g);
f2(g);
assert(g_call_count, 2);
var e;
try {
new class extends Object {
constructor() {
(() => {
for (const _ in this);
eval("");
})();
}
};
} catch (_e) {
e = _e;
}
assert(e?.message, "this is not initialized");
}
function test_eval()
@ -516,7 +413,7 @@ function test_eval()
function test_typed_array()
{
var buffer, a, i, str, b;
var buffer, a, i, str;
a = new Uint8Array(4);
assert(a.length, 4);
@ -569,17 +466,6 @@ function test_typed_array()
assert(a.toString(), "1,2,3,4");
a.set([10, 11], 2);
assert(a.toString(), "1,2,10,11");
a = new Uint8Array(buffer, 0, 4);
a.constructor = {
[Symbol.species]: function (len) {
return new Uint8Array(buffer, 1, len);
},
};
b = a.slice();
assert(a.buffer, b.buffer);
assert(a.toString(), "0,0,0,255");
assert(b.toString(), "0,0,255,255");
}
function test_json()
@ -609,113 +495,26 @@ function test_json()
function test_date()
{
// Date Time String format is YYYY-MM-DDTHH:mm:ss.sssZ
// accepted date formats are: YYYY, YYYY-MM and YYYY-MM-DD
// accepted time formats are: THH:mm, THH:mm:ss, THH:mm:ss.sss
// expanded years are represented with 6 digits prefixed by + or -
// -000000 is invalid.
// A string containing out-of-bounds or nonconforming elements
// is not a valid instance of this format.
// Hence the fractional part after . should have 3 digits and how
// a different number of digits is handled is implementation defined.
assert(Date.parse(""), NaN);
assert(Date.parse("2000"), 946684800000);
assert(Date.parse("2000-01"), 946684800000);
assert(Date.parse("2000-01-01"), 946684800000);
//assert(Date.parse("2000-01-01T"), NaN);
//assert(Date.parse("2000-01-01T00Z"), NaN);
assert(Date.parse("2000-01-01T00:00Z"), 946684800000);
assert(Date.parse("2000-01-01T00:00:00Z"), 946684800000);
assert(Date.parse("2000-01-01T00:00:00.1Z"), 946684800100);
assert(Date.parse("2000-01-01T00:00:00.10Z"), 946684800100);
assert(Date.parse("2000-01-01T00:00:00.100Z"), 946684800100);
assert(Date.parse("2000-01-01T00:00:00.1000Z"), 946684800100);
assert(Date.parse("2000-01-01T00:00:00+00:00"), 946684800000);
//assert(Date.parse("2000-01-01T00:00:00+00:30"), 946686600000);
var d = new Date("2000T00:00"); // Jan 1st 2000, 0:00:00 local time
assert(typeof d === 'object' && d.toString() != 'Invalid Date');
assert((new Date('Jan 1 2000')).toISOString(),
d.toISOString());
assert((new Date('Jan 1 2000 00:00')).toISOString(),
d.toISOString());
assert((new Date('Jan 1 2000 00:00:00')).toISOString(),
d.toISOString());
assert((new Date('Jan 1 2000 00:00:00 GMT+0100')).toISOString(),
'1999-12-31T23:00:00.000Z');
assert((new Date('Jan 1 2000 00:00:00 GMT+0200')).toISOString(),
'1999-12-31T22:00:00.000Z');
assert((new Date('Sat Jan 1 2000')).toISOString(),
d.toISOString());
assert((new Date('Sat Jan 1 2000 00:00')).toISOString(),
d.toISOString());
assert((new Date('Sat Jan 1 2000 00:00:00')).toISOString(),
d.toISOString());
assert((new Date('Sat Jan 1 2000 00:00:00 GMT+0100')).toISOString(),
'1999-12-31T23:00:00.000Z');
assert((new Date('Sat Jan 1 2000 00:00:00 GMT+0200')).toISOString(),
'1999-12-31T22:00:00.000Z');
var d = new Date(1506098258091);
var d = new Date(1506098258091), a, s;
assert(d.toISOString(), "2017-09-22T16:37:38.091Z");
d.setUTCHours(18, 10, 11);
assert(d.toISOString(), "2017-09-22T18:10:11.091Z");
var a = Date.parse(d.toISOString());
a = Date.parse(d.toISOString());
assert((new Date(a)).toISOString(), d.toISOString());
assert((new Date("2020-01-01T01:01:01.123Z")).toISOString(),
"2020-01-01T01:01:01.123Z");
/* implementation defined behavior */
assert((new Date("2020-01-01T01:01:01.1Z")).toISOString(),
"2020-01-01T01:01:01.100Z");
assert((new Date("2020-01-01T01:01:01.12Z")).toISOString(),
"2020-01-01T01:01:01.120Z");
assert((new Date("2020-01-01T01:01:01.1234Z")).toISOString(),
"2020-01-01T01:01:01.123Z");
assert((new Date("2020-01-01T01:01:01.12345Z")).toISOString(),
"2020-01-01T01:01:01.123Z");
assert((new Date("2020-01-01T01:01:01.1235Z")).toISOString(),
"2020-01-01T01:01:01.123Z");
assert((new Date("2020-01-01T01:01:01.9999Z")).toISOString(),
"2020-01-01T01:01:01.999Z");
assert(Date.UTC(2017), 1483228800000);
assert(Date.UTC(2017, 9), 1506816000000);
assert(Date.UTC(2017, 9, 22), 1508630400000);
assert(Date.UTC(2017, 9, 22, 18), 1508695200000);
assert(Date.UTC(2017, 9, 22, 18, 10), 1508695800000);
assert(Date.UTC(2017, 9, 22, 18, 10, 11), 1508695811000);
assert(Date.UTC(2017, 9, 22, 18, 10, 11, 91), 1508695811091);
assert(Date.UTC(NaN), NaN);
assert(Date.UTC(2017, NaN), NaN);
assert(Date.UTC(2017, 9, NaN), NaN);
assert(Date.UTC(2017, 9, 22, NaN), NaN);
assert(Date.UTC(2017, 9, 22, 18, NaN), NaN);
assert(Date.UTC(2017, 9, 22, 18, 10, NaN), NaN);
assert(Date.UTC(2017, 9, 22, 18, 10, 11, NaN), NaN);
assert(Date.UTC(2017, 9, 22, 18, 10, 11, 91, NaN), 1508695811091);
// TODO: Fix rounding errors on Windows/Cygwin.
if (!['win32', 'cygwin'].includes(os.platform)) {
// from test262/test/built-ins/Date/UTC/fp-evaluation-order.js
assert(Date.UTC(1970, 0, 1, 80063993375, 29, 1, -288230376151711740), 29312,
'order of operations / precision in MakeTime');
assert(Date.UTC(1970, 0, 213503982336, 0, 0, 0, -18446744073709552000), 34447360,
'precision in MakeDate');
}
//assert(Date.UTC(2017 - 1e9, 9 + 12e9), 1506816000000); // node fails this
assert(Date.UTC(2017, 9, 22 - 1e10, 18 + 24e10), 1508695200000);
assert(Date.UTC(2017, 9, 22, 18 - 1e10, 10 + 60e10), 1508695800000);
assert(Date.UTC(2017, 9, 22, 18, 10 - 1e10, 11 + 60e10), 1508695811000);
assert(Date.UTC(2017, 9, 22, 18, 10, 11 - 1e12, 91 + 1000e12), 1508695811091);
assert(new Date("2024 Apr 7 1:00 AM").toLocaleString(), "04/07/2024, 01:00:00 AM");
assert(new Date("2024 Apr 7 2:00 AM").toLocaleString(), "04/07/2024, 02:00:00 AM");
assert(new Date("2024 Apr 7 11:00 AM").toLocaleString(), "04/07/2024, 11:00:00 AM");
assert(new Date("2024 Apr 7 12:00 AM").toLocaleString(), "04/07/2024, 12:00:00 AM");
assert(new Date("2024 Apr 7 1:00 PM").toLocaleString(), "04/07/2024, 01:00:00 PM");
assert(new Date("2024 Apr 7 2:00 PM").toLocaleString(), "04/07/2024, 02:00:00 PM");
assert(new Date("2024 Apr 7 11:00 PM").toLocaleString(), "04/07/2024, 11:00:00 PM");
assert(new Date("2024 Apr 7 12:00 PM").toLocaleString(), "04/07/2024, 12:00:00 PM");
s = new Date("2020-01-01T01:01:01.1Z").toISOString();
assert(s == "2020-01-01T01:01:01.100Z");
s = new Date("2020-01-01T01:01:01.12Z").toISOString();
assert(s == "2020-01-01T01:01:01.120Z");
s = new Date("2020-01-01T01:01:01.123Z").toISOString();
assert(s == "2020-01-01T01:01:01.123Z");
s = new Date("2020-01-01T01:01:01.1234Z").toISOString();
assert(s == "2020-01-01T01:01:01.123Z");
s = new Date("2020-01-01T01:01:01.12345Z").toISOString();
assert(s == "2020-01-01T01:01:01.123Z");
s = new Date("2020-01-01T01:01:01.1235Z").toISOString();
assert(s == "2020-01-01T01:01:01.124Z");
s = new Date("2020-01-01T01:01:01.9999Z").toISOString();
assert(s == "2020-01-01T01:01:02.000Z");
}
function test_regexp()
@ -754,20 +553,6 @@ function test_regexp()
assert(/{1a}/.toString(), "/{1a}/");
a = /a{1+/.exec("a{11");
assert(a, ["a{11"] );
eval("/[a-]/"); // accepted with no flag
eval("/[a-]/u"); // accepted with 'u' flag
let ex;
try {
eval("/[a-]/v"); // rejected with 'v' flag
} catch (_ex) {
ex = _ex;
}
assert(ex?.message, "invalid class range");
eval("/[\\-]/");
eval("/[\\-]/u");
}
function test_symbol()
@ -806,16 +591,6 @@ function test_map()
{
var a, i, n, tab, o, v;
n = 1000;
a = new Map();
for (var i = 0; i < n; i++) {
a.set(i, i);
}
a.set(-2147483648, 1);
assert(a.get(-2147483648), 1);
assert(a.get(-2147483647 - 1), 1);
assert(a.get(-2147483647.5 - 0.5), 1);
a = new Map();
tab = [];
for(i = 0; i < n; i++) {
@ -910,18 +685,6 @@ function test_generator()
assert(ret, "ret_val");
return 3;
}
function *f3() {
var ret;
/* test stack consistency with nip_n to handle yield return +
* finally clause */
try {
ret = 2 + (yield 1);
} catch(e) {
} finally {
ret++;
}
return ret;
}
var g, v;
g = f();
v = g.next();
@ -942,28 +705,6 @@ function test_generator()
assert(v.value === 3 && v.done === true);
v = g.next();
assert(v.value === undefined && v.done === true);
g = f3();
v = g.next();
assert(v.value === 1 && v.done === false);
v = g.next(3);
assert(v.value === 6 && v.done === true);
}
function test_proxy_iter()
{
const p = new Proxy({}, {
getOwnPropertyDescriptor() {
return {configurable: true, enumerable: true, value: 42};
},
ownKeys() {
return ["x", "y"];
},
});
const a = [];
for (const x in p) a.push(x);
assert(a[0], "x");
assert(a[1], "y");
}
/* CVE-2023-31922 */
@ -976,63 +717,15 @@ function test_proxy_is_array()
/* Without ASAN */
assert(Array.isArray(r));
} catch(e) {
/* With ASAN expect RangeError "Maximum call stack size exceeded" to be raised */
if (e instanceof RangeError) {
assert(e.message, "Maximum call stack size exceeded", "Stack overflow error was not raised")
/* With ASAN expect InternalError "stack overflow" to be raised */
if (e instanceof InternalError) {
assert(e.message, "stack overflow", "Stack overflow error was not raised")
} else {
throw e;
}
}
}
function test_cur_pc()
{
var a = [];
Object.defineProperty(a, '1', {
get: function() { throw Error("a[1]_get"); },
set: function(x) { throw Error("a[1]_set"); }
});
assert_throws(Error, function() { return a[1]; });
assert_throws(Error, function() { a[1] = 1; });
assert_throws(Error, function() { return [...a]; });
assert_throws(Error, function() { return ({...b} = a); });
var o = {};
Object.defineProperty(o, 'x', {
get: function() { throw Error("o.x_get"); },
set: function(x) { throw Error("o.x_set"); }
});
o.valueOf = function() { throw Error("o.valueOf"); };
assert_throws(Error, function() { return +o; });
assert_throws(Error, function() { return -o; });
assert_throws(Error, function() { return o+1; });
assert_throws(Error, function() { return o-1; });
assert_throws(Error, function() { return o*1; });
assert_throws(Error, function() { return o/1; });
assert_throws(Error, function() { return o%1; });
assert_throws(Error, function() { return o**1; });
assert_throws(Error, function() { return o<<1; });
assert_throws(Error, function() { return o>>1; });
assert_throws(Error, function() { return o>>>1; });
assert_throws(Error, function() { return o&1; });
assert_throws(Error, function() { return o|1; });
assert_throws(Error, function() { return o^1; });
assert_throws(Error, function() { return o<1; });
assert_throws(Error, function() { return o==1; });
assert_throws(Error, function() { return o++; });
assert_throws(Error, function() { return o--; });
assert_throws(Error, function() { return ++o; });
assert_throws(Error, function() { return --o; });
assert_throws(Error, function() { return ~o; });
Object.defineProperty(globalThis, 'xxx', {
get: function() { throw Error("xxx_get"); },
set: function(x) { throw Error("xxx_set"); }
});
assert_throws(Error, function() { return xxx; });
assert_throws(Error, function() { xxx = 1; });
}
test();
test_function();
test_enum();
@ -1050,10 +743,4 @@ test_map();
test_weak_map();
test_weak_set();
test_generator();
test_proxy_iter();
test_proxy_is_array();
test_exception_source_pos();
test_function_source_pos();
test_exception_prepare_stack();
test_exception_stack_size_limit();
test_cur_pc();

File diff suppressed because it is too large Load diff

View file

@ -5,41 +5,29 @@ function assert(actual, expected, message) {
if (actual === expected)
return;
if (typeof actual == 'number' && isNaN(actual)
&& typeof expected == 'number' && isNaN(expected))
return;
if (actual !== null && expected !== null
&& typeof actual == 'object' && typeof expected == 'object'
&& actual.toString() === expected.toString())
return;
var msg = message ? " (" + message + ")" : "";
throw Error("assertion failed: got |" + actual + "|" +
", expected |" + expected + "|" + msg);
", expected |" + expected + "|" +
(message ? " (" + message + ")" : ""));
}
function assert_throws(expected_error, func, message)
function assert_throws(expected_error, func)
{
var err = false;
var msg = message ? " (" + message + ")" : "";
try {
switch (typeof func) {
case 'string':
eval(func);
break;
case 'function':
func();
break;
}
} catch(e) {
err = true;
if (!(e instanceof expected_error)) {
throw Error(`expected ${expected_error.name}, got ${e.name}${msg}`);
throw Error("unexpected exception type");
}
}
if (!err) {
throw Error(`expected ${expected_error.name}${msg}`);
throw Error("expected exception");
}
}
@ -132,7 +120,6 @@ function test_cvt()
assert((Infinity >>> 0) === 0);
assert(((-Infinity) >>> 0) === 0);
assert(((4294967296 * 3 - 4) >>> 0) === (4294967296 - 4));
assert((19686109595169230000).toString() === "19686109595169230000");
}
function test_eq()
@ -347,13 +334,6 @@ function test_class()
assert(S.x === 42);
assert(S.y === 42);
assert(S.z === 42);
class P {
get = () => "123";
static() { return 42; }
}
assert(new P().get() === "123");
assert(new P().static() === 42);
};
function test_template()
@ -381,9 +361,8 @@ function test_template_skip()
function test_object_literal()
{
var x = 0, get = 1, set = 2; async = 3;
a = { get: 2, set: 3, async: 4, get a(){ return this.get} };
assert(JSON.stringify(a), '{"get":2,"set":3,"async":4,"a":2}');
assert(a.a === 2);
a = { get: 2, set: 3, async: 4 };
assert(JSON.stringify(a), '{"get":2,"set":3,"async":4}');
a = { x, get, set, async };
assert(JSON.stringify(a), '{"x":0,"get":1,"set":2,"async":3}');
@ -441,8 +420,6 @@ function test_argument_scope()
var c = "global";
f = function(a = eval("var arguments")) {};
// for some reason v8 does not throw an exception here
if (typeof require === 'undefined')
assert_throws(SyntaxError, f);
f = function(a = eval("1"), b = arguments[0]) { return b; };
@ -558,107 +535,6 @@ function test_function_expr_name()
assert_throws(TypeError, f);
}
function test_expr(expr, err) {
if (err)
assert_throws(err, expr, `for ${expr}`);
else
assert(1, eval(expr), `for ${expr}`);
}
function test_name(name, err)
{
test_expr(`(function() { return typeof ${name} ? 1 : 1; })()`);
test_expr(`(function() { var ${name}; ${name} = 1; return ${name}; })()`);
test_expr(`(function() { let ${name}; ${name} = 1; return ${name}; })()`, name == 'let' ? SyntaxError : undefined);
test_expr(`(function() { const ${name} = 1; return ${name}; })()`, name == 'let' ? SyntaxError : undefined);
test_expr(`(function(${name}) { ${name} = 1; return ${name}; })()`);
test_expr(`(function({${name}}) { ${name} = 1; return ${name}; })({})`);
test_expr(`(function ${name}() { return ${name} ? 1 : 0; })()`);
test_expr(`"use strict"; (function() { return typeof ${name} ? 1 : 1; })()`, err);
test_expr(`"use strict"; (function() { if (0) ${name} = 1; return 1; })()`, err);
test_expr(`"use strict"; (function() { var x; if (0) x = ${name}; return 1; })()`, err);
test_expr(`"use strict"; (function() { var ${name}; return 1; })()`, err);
test_expr(`"use strict"; (function() { let ${name}; return 1; })()`, err);
test_expr(`"use strict"; (function() { const ${name} = 1; return 1; })()`, err);
test_expr(`"use strict"; (function() { var ${name}; ${name} = 1; return 1; })()`, err);
test_expr(`"use strict"; (function() { var ${name}; ${name} = 1; return ${name}; })()`, err);
test_expr(`"use strict"; (function(${name}) { return 1; })()`, err);
test_expr(`"use strict"; (function({${name}}) { return 1; })({})`, err);
test_expr(`"use strict"; (function ${name}() { return 1; })()`, err);
test_expr(`(function() { "use strict"; return typeof ${name} ? 1 : 1; })()`, err);
test_expr(`(function() { "use strict"; if (0) ${name} = 1; return 1; })()`, err);
test_expr(`(function() { "use strict"; var x; if (0) x = ${name}; return 1; })()`, err);
test_expr(`(function() { "use strict"; var ${name}; return 1; })()`, err);
test_expr(`(function() { "use strict"; let ${name}; return 1; })()`, err);
test_expr(`(function() { "use strict"; const ${name} = 1; return 1; })()`, err);
test_expr(`(function() { "use strict"; var ${name}; ${name} = 1; return 1; })()`, err);
test_expr(`(function() { "use strict"; var ${name}; ${name} = 1; return ${name}; })()`, err);
test_expr(`(function(${name}) { "use strict"; return 1; })()`, err);
test_expr(`(function({${name}}) { "use strict"; return 1; })({})`, SyntaxError);
test_expr(`(function ${name}() { "use strict"; return 1; })()`, err);
}
function test_reserved_names()
{
test_name('await');
test_name('yield', SyntaxError);
test_name('implements', SyntaxError);
test_name('interface', SyntaxError);
test_name('let', SyntaxError);
test_name('package', SyntaxError);
test_name('private', SyntaxError);
test_name('protected', SyntaxError);
test_name('public', SyntaxError);
test_name('static', SyntaxError);
}
function test_number_literals()
{
assert(0.1.a, undefined);
assert(0x1.a, undefined);
assert(0b1.a, undefined);
assert(01.a, undefined);
assert(0o1.a, undefined);
test_expr('0.a', SyntaxError);
assert(parseInt("0_1"), 0);
assert(parseInt("1_0"), 1);
assert(parseInt("0_1", 8), 0);
assert(parseInt("1_0", 8), 1);
assert(parseFloat("0_1"), 0);
assert(parseFloat("1_0"), 1);
assert(1_0, 10);
assert(parseInt("Infinity"), NaN);
assert(parseFloat("Infinity"), Infinity);
assert(parseFloat("Infinity1"), Infinity);
assert(parseFloat("Infinity_"), Infinity);
assert(parseFloat("Infinity."), Infinity);
test_expr('0_0', SyntaxError);
test_expr('00_0', SyntaxError);
test_expr('01_0', SyntaxError);
test_expr('08_0', SyntaxError);
test_expr('09_0', SyntaxError);
}
function test_syntax()
{
assert_throws(SyntaxError, "do");
assert_throws(SyntaxError, "do;");
assert_throws(SyntaxError, "do{}");
assert_throws(SyntaxError, "if");
assert_throws(SyntaxError, "if\n");
assert_throws(SyntaxError, "if 1");
assert_throws(SyntaxError, "if \0");
assert_throws(SyntaxError, "if ;");
assert_throws(SyntaxError, "if 'abc'");
assert_throws(SyntaxError, "if `abc`");
assert_throws(SyntaxError, "if /abc/");
assert_throws(SyntaxError, "if abc");
assert_throws(SyntaxError, "if abc\u0064");
assert_throws(SyntaxError, "if abc\\u0064");
assert_throws(SyntaxError, "if \u0123");
assert_throws(SyntaxError, "if \\u0123");
}
test_op1();
test_cvt();
test_eq();
@ -678,6 +554,3 @@ test_spread();
test_function_length();
test_argument_scope();
test_function_expr_name();
test_reserved_names();
test_number_literals();
test_syntax();

View file

@ -2,7 +2,6 @@ import * as std from "std";
import * as os from "os";
const isWin = os.platform === 'win32';
const isCygwin = os.platform === 'cygwin';
function assert(actual, expected, message) {
if (arguments.length == 1)
@ -244,26 +243,13 @@ function test_os_exec()
pid = os.exec(["cat"], { block: false } );
assert(pid >= 0);
os.kill(pid, os.SIGTERM);
os.kill(pid, os.SIGQUIT);
[ret, status] = os.waitpid(pid, 0);
assert(ret, pid);
// Flaky on cygwin for unclear reasons, see
// https://github.com/quickjs-ng/quickjs/issues/184
if (!isCygwin) {
assert(status & 0x7f, os.SIGTERM);
}
assert(status & 0x7f, os.SIGQUIT);
}
function test_interval()
{
var t = os.setInterval(f, 1);
function f() {
if (++f.count === 3) os.clearInterval(t);
}
f.count = 0;
}
function test_timeout()
function test_timer()
{
var th, i;
@ -275,18 +261,6 @@ function test_timeout()
os.clearTimeout(th[i]);
}
function test_timeout_order()
{
var s = "";
os.setTimeout(a, 1);
os.setTimeout(b, 2);
os.setTimeout(d, 5);
function a() { s += "a"; os.setTimeout(c, 0); }
function b() { s += "b"; }
function c() { s += "c"; }
function d() { assert(s === "abc"); } // not "acb"
}
test_printf();
test_file1();
test_file2();
@ -294,6 +268,4 @@ test_getline();
test_popen();
test_os();
!isWin && test_os_exec();
test_interval();
test_timeout();
test_timeout_order();
test_timer();

View file

@ -217,7 +217,7 @@ static const char *unicode_prop_short_name[] = {
#undef DEF
};
#undef UNICODE_PROP_LIST
#undef UNICODE_SPROP_LIST
typedef struct {
/* case conv */

View file

@ -1,25 +0,0 @@
;(function() {
"use strict"
const print = globalThis.print
globalThis.print = function() {} // print nothing, v8 tests are chatty
let count = 0 // rate limit to avoid excessive logs
globalThis.failWithMessage = function(message) {
if (count > 99) return
if (++count > 99) return print("<output elided>")
print(String(message).slice(0, 300))
}
globalThis.formatFailureText = function(expectedText, found, name_opt) {
var message = "Fail" + "ure"
if (name_opt) {
// Fix this when we ditch the old test runner.
message += " (" + name_opt + ")"
}
var foundText = prettyPrinted(found)
if (expectedText.length <= 60 && foundText.length <= 60) {
message += ": expected <" + expectedText + "> found <" + foundText + ">"
} else {
message += ":\nexpected:\n" + expectedText + "\nfound:\n" + foundText
}
return message
}
})()

109
v8.js
View file

@ -1,109 +0,0 @@
import * as std from "std"
import * as os from "os"
argv0 = realpath(argv0)
const tweak = realpath("v8-tweak.js")
const dir = "test262/implementation-contributed/v8/mjsunit"
const exclude = [
"arguments-indirect.js", // implementation-defined
"array-concat.js", // slow
"array-isarray.js", // unstable output due to stack overflow
"array-join.js", // unstable output due to stack overflow
"ascii-regexp-subject.js", // slow
"asm-directive.js", // v8 specific
"disallow-codegen-from-strings.js", // --disallow-code-generation-from-strings
"cyclic-array-to-string.js", // unstable output due to stack overflow
"error-tostring.js", // unstable output due to stack overflow
"invalid-lhs.js", // v8 expects ReferenceError but ECMA says SyntaxError
"regexp.js", // invalid, legitimate early SyntaxError
"regexp-capture-3.js", // slow
"regexp-cache-replace.js", // deprecated RegExp.$1 etc.
"regexp-indexof.js", // deprecated RegExp.lastMatch etc.
"regexp-static.js", // deprecated RegExp static properties.
"regexp-modifiers-autogenerated-i18n.js", // invalid group
"regexp-modifiers-autogenerated.js", // invalid group
"regexp-modifiers-dotall.js", // invalid group
"regexp-modifiers-i18n.js", // invalid group
"regexp-modifiers.js", // invalid group
"regexp-override-symbol-match-all.js", // missing g flag
"serialize-embedded-error.js", // parseInt() = 0;
"string-replace.js", // unstable output
"string-match.js", // deprecated RegExp.$1 etc.
"string-slices-regexp.js", // deprecated RegExp.$1 etc.
"omit-default-ctors-array-iterator.js",
"mjsunit.js",
"mjsunit-assertion-error.js",
"mjsunit-assert-equals.js",
"mjsunit_suppressions.js",
"verify-assert-false.js", // self check
"verify-check-false.js", // self check
"clone-ic-regression-crbug-1466315.js", // spurious output
]
let files = scriptArgs.slice(1) // run only these tests
if (files.length === 0) files = os.readdir(dir)[0].sort()
for (const file of files) {
if (!file.endsWith(".js")) continue
if (exclude.includes(file)) continue
const source = std.loadFile(dir + "/" + file)
if (/^(im|ex)port/m.test(source)) continue // TODO support modules
if (source.includes('Realm.create')) continue // TODO support Realm object
if (source.includes('// MODULE')) continue // TODO support modules
if (source.includes('// Files:')) continue // TODO support includes
// the default --stack-size is necessary to keep output of stack overflowing
// tests stable; it will be overridden by a Flags comment
let flags = { '--stack-size': 2048 }, flagstr = ""
// parse command line flags
for (let s of source.matchAll(/\/\/ Flags:(.+)/g)) {
for (let m of s[1].matchAll(/\s*([\S]+)/g)) {
const v = m[1].match(/([\S]+)=([\S]+)/)
if (v) {
flags[v[1]] = v[2]
flagstr += ` ${v[1]}=${v[2]}`
} else {
flags[m[1]] = true
flagstr += ` ${m[1]}`
}
}
}
// exclude tests that use V8 intrinsics like %OptimizeFunctionOnNextCall
if (flags["--allow-natives-syntax"]) continue
if (flags["--allow-natives-for-differential-fuzzing"]) continue
if (flags["--dump-counters"]) continue
if (flags["--expose-cputracemark"]) continue
if (flags["--harmony-rab-gsab"]) continue
if (flags["--harmony-class-fields"]) continue
if (flags["--enable-experimental-regexp-engine"]) continue
if (flags["--experimental-stack-trace-frames"]) continue
if (flags["--js-float16array"]) continue
if (flags["--expose-cputracemark-as"]) continue
// exclude tests that use V8 extensions
if (flags["--expose-externalize-string"]) continue
// parse environment variables
let env = {}, envstr = ""
for (let s of source.matchAll(/environment variables:(.+)/ig)) {
for (let m of s[1].matchAll(/\s*([\S]+)=([\S]+)/g)) {
env[m[1]] = m[2]
envstr += ` ${m[1]}=${m[2]}`
}
}
//print(`=== ${file}${envstr}${flagstr}`)
print(`=== ${file}${envstr}`)
const args = [argv0,
"--stack-size", `${flags["--stack-size"]}`,
"-I", "mjsunit.js",
"-I", tweak,
file]
const opts = {block:true, cwd:dir, env:env, usePath:false}
os.exec(args, opts)
}
function realpath(path) {
return os.realpath(path)[0]
}

10
v8.sh
View file

@ -1,10 +0,0 @@
#!/bin/sh
set -e
: ${QJS:=build/qjs}
if [ "x" = "x$1" ] ; then
"$QJS" v8.js $* 2>&1 | tee v8.txt$$
diff -uw v8.txt v8.txt$$ || exit 1
rm v8.txt$$
else
"$QJS" v8.js $* 2>&1
fi

971
v8.txt
View file

@ -1,971 +0,0 @@
=== accessors-no-prototype.js
=== accessors-on-global-object.js
=== api-call-after-bypassed-exception.js
=== apply-arguments-gc-safepoint.js
=== argument-assigned.js
=== argument-named-arguments.js
=== arguments-apply.js
=== arguments-call-apply.js
=== arguments-enum.js
=== arguments-escape.js
=== arguments-lazy.js
=== arguments-load-across-eval.js
=== arguments-read-and-assignment.js
=== array-elements-from-array-prototype-chain.js
=== array-elements-from-array-prototype.js
=== array-elements-from-object-prototype.js
=== array-foreach.js
=== array-from-large-set.js
=== array-functions-prototype-misc.js
=== array-functions-prototype.js
=== array-indexing.js
=== array-iteration.js
=== array-join-element-tostring-prototype-side-effects.js
=== array-join-nesting.js
=== array-join-nonarray-length-getter-side-effects.js
=== array-lastindexof.js
=== array-length-number-conversion.js
=== array-length.js
=== array-prototype-every.js
=== array-prototype-filter.js
=== array-prototype-find.js
=== array-prototype-findindex.js
=== array-prototype-foreach.js
=== array-prototype-includes.js
=== array-prototype-indexof.js
=== array-prototype-lastindexof.js
=== array-prototype-map.js
=== array-prototype-pop.js
=== array-prototype-reduce.js
=== array-prototype-slice.js
=== array-prototype-some.js
=== array-push-non-smi-value.js
=== array-push10.js
=== array-push11.js
=== array-push13.js
=== array-push14.js
=== array-push2.js
=== array-reverse.js
=== array-shift.js
=== array-splice.js
=== array-tolocalestring.js
Failure: expected <"1,"> found <"1,[object Object]">
Failure: expected <"1,"> found <"1,[object Object]">
Failure (Error message): expected <"7 is not a function"> found <"not a function">
=== array-tostring.js
=== array-unshift.js
=== arrow-with.js
=== async-stack-traces-prepare-stacktrace-1.js
=== async-stack-traces-prepare-stacktrace-2.js
Failure:
expected:
undefined
found:
async function two(x) {
"use strict";
try {
x = await x;
throw new Error();
} catch (e) {
return e.stack;
}
}
=== async-stack-traces-prepare-stacktrace-3.js
=== async-stack-traces-prepare-stacktrace-4.js
=== big-array-literal.js
=== big-object-literal.js
=== binary-op-newspace.js
=== binary-operation-overwrite.js
=== bit-not.js
=== bitops-info.js
=== bitwise-operations-bools.js
=== bitwise-operations-undefined.js
=== body-not-visible.js
=== bool-concat.js
=== boolean.js
=== break.js
=== call-non-function-call.js
=== call-non-function.js
=== call-stub.js
=== call.js
=== char-escape.js
=== class-of-builtins.js
=== closure.js
=== code-comments.js
=== codegen-coverage.js
=== compare-character.js
=== compare-nan.js
=== compare-table-eq.js
=== compare-table-gt.js
=== compare-table-gteq.js
=== compare-table-lt.js
=== compare-table-lteq.js
=== compare-table-ne.js
=== compare-table-seq.js
=== compare-table-sne.js
=== console.js
TypeError: not a function
at <eval> (console.js:5:1)
=== constant-folding.js
=== context-variable-assignments.js
=== copy-on-write-assert.js
=== cyrillic.js
Failure (7): expected <true> found <false>
Failure (8): expected <true> found <false>
Failure (9): expected <true> found <false>
Failure (10): expected <true> found <false>
Failure (11): expected <true> found <false>
Failure (12): expected <true> found <false>
Failure (7): expected <true> found <false>
Failure (8): expected <true> found <false>
Failure (9): expected <true> found <false>
Failure (10): expected <true> found <false>
Failure (11): expected <true> found <false>
Failure (12): expected <true> found <false>
Failure (16): expected <true> found <false>
Failure (19): expected <true> found <false>
Failure (20): expected <true> found <false>
Failure (21): expected <true> found <false>
Failure (25): expected <true> found <false>
Failure (26): expected <true> found <false>
Failure (27): expected <true> found <false>
Failure (44[]): expected <true> found <false>
Failure (45[]): expected <true> found <false>
Failure (46[]): expected <true> found <false>
Failure (54[]): expected <true> found <false>
Failure (55[]): expected <true> found <false>
Failure (56[]): expected <true> found <false>
=== date-parse.js
=== declare-locally.js
=== deep-recursion.js
=== define-property-gc.js
=== delay-syntax-error.js
=== delete-global-properties.js
=== delete-in-eval.js
=== delete-in-with.js
=== delete-non-configurable.js
=== delete-vars-from-eval.js
=== delete.js
=== deserialize-reference.js
=== do-not-strip-fc.js
=== dont-enum-array-holes.js
=== dont-reinit-global-var.js
=== double-equals.js
=== dtoa.js
=== duplicate-parameters.js
=== eagerly-parsed-lazily-compiled-functions.js
=== elements-transition-and-store.js
=== empirical_max_arraybuffer.js
=== enumeration-order.js
=== error-accessors.js
=== error-constructors.js
=== error-tostring-omit.js
Failure: expected <true> found <false>
=== escape.js
=== eval-enclosing-function-name.js
Failure: expected <"number"> found <"undefined">
Failure: expected <"number"> found <"function">
=== eval-origin.js
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
=== eval-stack-trace.js
Failure: expected <"eval"> found <"<eval>">
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
TypeError: not a function
[object CallSite],[object CallSite],[object CallSite],[object CallSite]
=== eval-typeof-non-existing.js
=== eval.js
=== external-backing-store-gc.js
=== extra-arguments.js
TypeError: cannot read property 'length' of undefined
at g (extra-arguments.js:35:23)
at f (extra-arguments.js:29:10)
at apply (native)
at <eval> (extra-arguments.js:51:40)
=== extra-commas.js
=== for-in-delete.js
=== for-in-null-or-undefined.js
=== for-in-special-cases.js
=== for-in.js
=== for-of-in-catch-duplicate-decl.js
=== for.js
=== fun-as-prototype.js
=== fun-name.js
=== function-arguments-null.js
Failure: expected <true> found <false>
=== function-bind-name.js
=== function-call.js
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <true> found <false>
<output elided>
=== function-caller.js
Failure: expected <function f(match) {
g(match);
}> found <undefined>
Failure: expected <function h() {
f(h);
}> found <undefined>
Failure: expected <function f(match) {
g(match);
}> found <undefined>
Failure: expected <null> found <undefined>
Failure: expected <function f(match) {
g(match);
}> found <undefined>
Failure: expected <null> found <undefined>
Failure: expected <function f(match) {
g(match);
}> found <undefined>
Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
=== function-length-accessor.js
=== function-name-eval-shadowed.js
Failure: expected <200> found <function f() { eval("var f = 100"); f = 200; return f }>
=== function-names.js
=== function-property.js
=== function-prototype.js
=== function-var.js
=== function-without-prototype.js
=== function.js
Failure: expected <"undefined"> found <"function">
Failure: expected <42> found <function anonymous(
) {
return anonymous;
}>
=== fuzz-accessors.js
=== get-own-property-descriptor-non-objects.js
=== get-own-property-descriptor.js
=== get-prototype-of.js
=== getter-in-prototype.js
=== getter-in-value-prototype.js
=== global-accessors.js
=== global-arrow-delete-this.js
=== global-deleted-property-ic.js
=== global-hash.js
=== global-ic.js
=== global-load-from-eval-in-with.js
=== global-load-from-eval.js
=== global-load-from-nested-eval.js
=== global-properties.js
=== global-vars-eval.js
=== global-vars-with.js
=== handle-count-ast.js
=== handle-count-runtime-literals.js
=== has-own-property-evaluation-order.js
=== has-own-property.js
=== hex-parsing.js
=== holy-double-no-arg-array.js
=== html-comments.js
=== html-string-funcs.js
=== icu-date-lord-howe.js TZ=Australia/Lord_Howe LC_ALL=en
Failure:
expected:
"Mon Jan 01 1990 11:00:00 GMT+1100 (Lord Howe Daylight Time)"
found:
"Mon Jan 01 1990 11:00:00 GMT+1100"
Failure:
expected:
"Fri Jun 01 1990 10:30:00 GMT+1030 (Lord Howe Standard Time)"
found:
"Fri Jun 01 1990 10:30:00 GMT+1030"
=== icu-date-to-string.js TZ=Europe/Madrid LC_ALL=de
Failure:
expected:
"Sun Dec 31 1989 00:00:00 GMT+0100 (Mitteleuropäische Normalzeit)"
found:
"Sun Dec 31 1989 00:00:00 GMT+0100"
Failure:
expected:
"Sat Jun 30 1990 00:00:00 GMT+0200 (Mitteleuropäische Sommerzeit)"
found:
"Sat Jun 30 1990 00:00:00 GMT+0200"
=== if-in-undefined.js
=== in.js
=== indexed-accessors.js
=== indexed-value-properties.js
=== instanceof-2.js
=== instanceof.js
=== int32-ops.js
=== integer-to-string.js
=== intl-numberformat-formattoparts.js
=== intl-pluralrules-select.js
=== invalid-source-element.js
=== json-errors.js
Failure:
expected:
"Unexpected token \n in JSON at position 3"
found:
"Bad control character in string literal in JSON at position 3 (line 1 column 4)"
Failure:
expected:
"Unexpected token \n in JSON at position 3"
found:
"Bad control character in string literal in JSON at position 3 (line 1 column 4)"
=== json-parser-recursive.js
=== json-replacer-number-wrapper-tostring.js
=== json-replacer-order.js
=== json-stringify-holder.js
=== json-stringify-recursive.js
Did not throw exception
Did not throw exception
=== json-stringify-stack.js
=== json.js
=== keyed-array-call.js
=== keyed-call-generic.js
=== keyed-call-ic.js
=== keyed-ic.js
=== keyed-storage-extend.js
=== keywords-and-reserved_words.js
=== large-object-allocation.js
=== lazy-inner-functions.js
=== lazy-load.js
=== leakcheck.js
=== length.js
=== linecontinuation.js
=== load-callback-from-value-classic.js
=== local-load-from-eval.js
=== logical.js
=== math-exp-precision.js
=== math-sqrt.js
=== md5.js
=== megamorphic-callbacks.js
=== mod.js
=== mul-exhaustive-part1.js
=== mul-exhaustive-part10.js
=== mul-exhaustive-part2.js
=== mul-exhaustive-part3.js
=== mul-exhaustive-part4.js
=== mul-exhaustive-part5.js
=== mul-exhaustive-part6.js
=== mul-exhaustive-part7.js
=== mul-exhaustive-part8.js
=== mul-exhaustive-part9.js
=== multiline.js
=== multiple-return.js
=== negate-zero.js
=== negate.js
=== new-function.js
Failure: expected <true> found <false>
=== new.js
=== newline-in-string.js
=== no-branch-elimination.js
=== no-octal-constants-above-256.js
=== no-semicolon.js
=== non-ascii-replace.js
=== not.js
=== nul-characters.js
=== number-is.js
=== number-limits.js
=== number-literal.js
=== number-string-index-call.js
=== number-tostring-add.js
=== number-tostring-big-integer.js
=== number-tostring-func.js
=== number-tostring-small.js
=== number-tostring.js
=== numops-fuzz-part1.js
=== numops-fuzz-part2.js
=== numops-fuzz-part3.js
=== numops-fuzz-part4.js
=== obj-construct.js
=== object-create.js
=== object-define-properties.js
Failure: expected <undefined> found <1>
=== object-freeze-global.js
=== object-get-own-property-names.js
=== object-is.js
=== object-literal-conversions.js
=== object-literal-gc.js
=== object-literal-modified-object-prototype.js
=== object-literal-multiple-fields.js
=== object-literal-multiple-proto-fields.js
=== object-seal-global.js
=== object-toprimitive.js
=== override-read-only-property.js
=== parallel-compile-tasks.js
=== parse-int-float.js
=== parse-surrogates.js
=== preparse-toplevel-strict-eval.js
=== primitive-keyed-access.js
Failure: expected <100> found <200>
Did not throw exception
=== print.js
Failure (printErr should be defined): expected <"function"> found <"undefined">
=== property-load-across-eval.js
=== property-name-eval-arguments.js
=== property-object-key.js
=== proto-accessor.js
=== proto-elements-add-during-foreach.js
=== proto.js
=== prototype.js
=== random-bit-correlations.js
=== readonly-accessor.js
=== receiver-in-with-calls.js
=== regexp-UC16.js
=== regexp-call-as-function.js
=== regexp-capture.js
Failure: expected <["",undefined,""]> found <["","undefined",""]>
Failure: expected <["",undefined,""]> found <["","undefined",""]>
Failure: expected <["bbaa","a","","a"]> found <["abba","bba","b","a"]>
=== regexp-captures.js
=== regexp-compile.js
=== regexp-global.js
SyntaxError: too many captures
at RegExp (native)
at <eval> (regexp-global.js:169:36)
=== regexp-lastIndex.js
=== regexp-lookahead.js
=== regexp-loop-capture.js
Failure: expected <["abc",undefined,undefined,"c"]> found <["abc","a","b","c"]>
Failure: expected <["ab",undefined]> found <["ab","a"]>
=== regexp-multiline.js
Failure: expected <true> found <false>
Failure: expected <true> found <false>
=== regexp-override-exec.js
=== regexp-override-symbol-match.js
=== regexp-override-symbol-replace.js
=== regexp-override-symbol-search.js
=== regexp-override-symbol-split.js
=== regexp-regexpexec.js
=== regexp-results-cache.js
=== regexp-sort.js
=== regexp-stack-overflow.js
=== regexp-standalones.js
=== regexp-string-methods.js
=== regress-regexp-functional-replace-slow.js
=== result-table-max.js
=== result-table-min.js
=== scanner.js
=== scope-calls-eval.js
=== search-string-multiple.js
=== serialize-after-execute.js
=== serialize-ic.js
=== shifts.js
=== short-circuit-boolean.js
=== simple-constructor.js
=== skipping-inner-functions-bailout.js
=== skipping-inner-functions.js
=== smi-negative-zero.js
=== smi-ops-inlined.js
=== smi-ops.js
=== sparse-array.js
=== splice-proxy.js
=== spread-large-array.js
=== spread-large-map.js
=== spread-large-set.js
=== spread-large-string.js
=== stack-traces-2.js
=== stack-traces-custom-lazy.js
Failure:
expected:
"bar"
found:
" at <anonymous> (stack-traces-custom-lazy.js:47:46)\n at testPrepareStackTrace (stack-traces-custom-lazy.js:31:5)\n at <eval> (stack-traces-custom-lazy.js:47:60)\n"
Failure:
expected:
"bar"
found:
" at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js
=== stack-traces-custom.js
TypeError: not a function
at <eval> (stack-traces-custom.js:20:21)
=== stack-traces-overflow.js
Failure: expected <true> found <false>
Failure: expected <true> found <false>
Failure: expected <undefined> found <"">
=== stack-traces.js
Failure (testArrayNative doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:48:31)
at map (native)
at testArrayNative (stack-traces.js:48:37)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:267:47)
): expected <true> found <false>
Failure (testMethodNameInference doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:30:37)
at testMethodNameInference (stack-traces.js:31:8)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:269:63)
): expected <true> found <false>
Failure (testImplicitConversion doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:53:42)
at testImplicitConversion (stack-traces.js:54:19)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:270:61)
): expected <true> found <false>
Failure (testEval doesn't contain expected[0] stack = at Doo (<input>:1:17)
at <eval> (<input>:1:26)
at testEval (stack-traces.js:58:3)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:271:33)
): expected <true> found <false>
Failure (testNestedEval doesn't contain expected[0] stack = at <eval> (<input>:1:1)
at Inner (<input>:1:19)
at Outer (<input>:1:58)
at <eval> (<input>:1:70)
at testNestedEval (stack-traces.js:63:3)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:272:45)
):
Failure (testEvalWithSourceURL doesn't contain expected[0] stack = at Doo (<input>:1:17)
at <eval> (<input>:1:26)
at testEvalWithSourceURL (stack-traces.js:67:3)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:274:34)
): expected <true> found <false>
Failure (testNestedEvalWithSourceURL doesn't contain expected[0] stack = at <eval> (<input>:1:1)
at Inner (<input>:1:19)
at Outer (<input>:1:36)
at <eval> (<input>:1:48)
at testNestedEvalWithSourceURL (stack-traces.js:73:3)
at testTrace (stack-traces.js:162:5)
at <eval> (
Failure (testNestedEvalWithSourceURL doesn't contain expected[1] stack = at <eval> (<input>:1:1)
at Inner (<input>:1:19)
at Outer (<input>:1:36)
at <eval> (<input>:1:48)
at testNestedEvalWithSourceURL (stack-traces.js:73:3)
at testTrace (stack-traces.js:162:5)
at <eval> (
Failure (testValue doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:77:47)
at testValue (stack-traces.js:78:3)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:278:35)
): expected <true> found <false>
Failure (testConstructor doesn't contain expected[0] stack = at Plonk (stack-traces.js:82:22)
at testConstructor (stack-traces.js:83:7)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:279:47)
): expected <true> found <false>
Failure (testRenamedMethod doesn't contain expected[0] stack = at a$b$c$d (stack-traces.js:87:31)
at testRenamedMethod (stack-traces.js:90:8)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:280:51)
): expected <true> found <false>
Failure (testAnonymousMethod doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:94:18)
at call (native)
at testAnonymousMethod (stack-traces.js:94:38)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:281:55)
): expected <true> found <false>
Failure (testFunctionName doesn't contain expected[2] stack = at foo_0 (stack-traces.js:101:9)
at foo_1 (stack-traces.js:103:27)
at <anonymous> (stack-traces.js:103:27)
at boo_3 (stack-traces.js:103:27)
at <anonymous> (stack-traces.js:103:27)
at testFunctionName (stack-traces
Failure (testFunctionName doesn't contain expected[4] stack = at foo_0 (stack-traces.js:101:9)
at foo_1 (stack-traces.js:103:27)
at <anonymous> (stack-traces.js:103:27)
at boo_3 (stack-traces.js:103:27)
at <anonymous> (stack-traces.js:103:27)
at testFunctionName (stack-traces
Failure (testDefaultCustomError doesn't contain expected[0] stack = at CustomError (stack-traces.js:130:33)
at testDefaultCustomError (stack-traces.js:138:36)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:287:5)
): expected <true> found <false>
Failure (testDefaultCustomError doesn't contain expected[1] stack = at CustomError (stack-traces.js:130:33)
at testDefaultCustomError (stack-traces.js:138:36)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:287:5)
): expected <true> found <false>
Failure (testStrippedCustomError doesn't contain expected[0] stack = at CustomError (stack-traces.js:130:33)
at testStrippedCustomError (stack-traces.js:142:36)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:289:25)
): expected <true> found <false>
Failure (testClassNames doesn't contain expected[0] stack = at MyObj (stack-traces.js:145:22)
at <anonymous> (stack-traces.js:150:14)
at testClassNames (stack-traces.js:154:8)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:291:49)
): expected <true> found <false>
Failure (testClassNames doesn't contain expected[1] stack = at MyObj (stack-traces.js:145:22)
at <anonymous> (stack-traces.js:150:14)
at testClassNames (stack-traces.js:154:8)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:291:49)
): expected <true> found <false>
Failure (UnintendedCallerCensorship didn't contain new ReferenceError): expected <true> found <false>
Failure: expected <"abc"> found <undefined>
Failure: expected <"abc"> found <" at <eval> (stack-traces.js:371:13)\n">
Failure: expected <undefined> found <" at <eval> (stack-traces.js:375:13)\n">
TypeError: not a function
at <eval> (stack-traces.js:381:1)
=== str-to-num.js
Failure: expected <7.922816251426436e+28> found <7.922816251426434e+28>
=== stress-array-push.js
=== strict-equals.js
=== strict-mode-eval.js
=== strict-mode.js
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Failure: expected <null> found <undefined>
Failure: expected <undefined> found <function non_strict() {
return return_my_caller();
}>
Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
TypeError: cannot read property 'value' of undefined
at <anonymous> (strict-mode.js:1213:58)
at recurse (strict-mode.js:1207:14)
at non_strict (strict-mode.js:1214:5)
at strict (strict-mode.js:1199:15)
at <anonymous> (strict-mode.js:1218:43)
at recurse (strict-mode.js:1207:14)
at test (strict-mode.js:1218:54)
at TestNonStrictFunctionCallerDescriptorPill (strict-mode.js:1222:22)
at <eval> (strict-mode.js:1224:1)
=== string-add.js
=== string-charat.js
=== string-compare-alignment.js
=== string-concat.js
=== string-equal.js
=== string-flatten.js
=== string-indexof-2.js
=== string-lastindexof.js
=== string-localecompare.js
=== string-normalize.js
=== string-oom-concat.js
=== string-pad.js
=== string-replace-gc.js
=== string-replace-one-char.js
=== string-search.js
=== string-split-cache.js
=== string-trim.js
=== string-wrapper.js
=== substr.js
=== test-builtins-setup.js
=== this-dynamic-lookup.js
=== this-in-callbacks.js
=== this-property-assignment.js
=== this.js
=== throw-and-catch-function.js
=== throw-exception-for-null-access.js
=== to-precision.js
=== to_number_order.js
=== tobool.js
=== toint32.js
=== top-level-assignments.js
=== touint32.js
=== transcendentals.js
=== try-catch-default-destructuring.js
=== try-catch-extension-object.js
=== try-catch-scopes.js
=== try-finally-continue.js
=== try-finally-nested.js
=== try.js
=== typeof.js
=== tzoffset-seoul-noi18n.js TZ=Asia/Seoul
=== tzoffset-seoul.js TZ=Asia/Seoul
=== tzoffset-transition-apia.js TZ=Pacific/Apia
Failure: expected <Date(1316872800000)> found <Date(1316876400000)>
Failure: expected <Date(1316874600000)> found <Date(1316878200000)>
Failure: expected <Date(1325275200000)> found <Date(1325188800000)>
Failure: expected <Date(1325277000000)> found <Date(1325190600000)>
Failure: expected <Date(1325278800000)> found <Date(1325192400000)>
Failure: expected <Date(1325280600000)> found <Date(1325194200000)>
Failure: expected <Date(1325282400000)> found <Date(1325196000000)>
Failure: expected <Date(1325284200000)> found <Date(1325197800000)>
Failure: expected <Date(1325286000000)> found <Date(1325199600000)>
Failure: expected <Date(1325287800000)> found <Date(1325201400000)>
Failure: expected <Date(1325289600000)> found <Date(1325203200000)>
Failure: expected <Date(1325291400000)> found <Date(1325205000000)>
Failure: expected <Date(1325293200000)> found <Date(1325206800000)>
Failure: expected <Date(1325295000000)> found <Date(1325208600000)>
Failure: expected <Date(1325296800000)> found <Date(1325210400000)>
Failure: expected <Date(1325298600000)> found <Date(1325212200000)>
Failure: expected <Date(1325300400000)> found <Date(1325214000000)>
Failure: expected <Date(1325302200000)> found <Date(1325215800000)>
Failure: expected <Date(1325304000000)> found <Date(1325217600000)>
Failure: expected <Date(1325305800000)> found <Date(1325219400000)>
Failure: expected <Date(1325307600000)> found <Date(1325221200000)>
Failure: expected <Date(1325309400000)> found <Date(1325223000000)>
Failure: expected <Date(1325311200000)> found <Date(1325224800000)>
Failure: expected <Date(1325313000000)> found <Date(1325226600000)>
Failure: expected <Date(1325314800000)> found <Date(1325228400000)>
Failure: expected <Date(1325316600000)> found <Date(1325230200000)>
Failure: expected <Date(1325318400000)> found <Date(1325232000000)>
Failure: expected <Date(1325320200000)> found <Date(1325233800000)>
Failure: expected <Date(1325322000000)> found <Date(1325235600000)>
Failure: expected <Date(1325323800000)> found <Date(1325237400000)>
Failure: expected <Date(1333198800000)> found <Date(1333202400000)>
Failure: expected <Date(1333200600000)> found <Date(1333204200000)>
Failure: expected <Date(1333202340000)> found <Date(1333205940000)>
=== tzoffset-transition-lord-howe.js TZ=Australia/Lord_Howe
Failure: expected <Date(1491056940000)> found <Date(1491058740000)>
Failure: expected <Date(1491057000000)> found <Date(1491058800000)>
Failure: expected <Date(1491057900000)> found <Date(1491059700000)>
Failure: expected <Date(1491058740000)> found <Date(1491060540000)>
Failure: expected <Date(1506785340000)> found <Date(1506783540000)>
Failure: expected <Date(1506785400000)> found <Date(1506783600000)>
Failure: expected <Date(1506786300000)> found <Date(1506784500000)>
Failure: expected <-660> found <-630>
=== tzoffset-transition-moscow.js TZ=Europe/Moscow
Failure: expected <Date(1269730740000)> found <Date(1269727140000)>
Failure: expected <Date(1269730800000)> found <Date(1269727200000)>
Failure: expected <Date(1269732600000)> found <Date(1269729000000)>
Failure: expected <-240> found <-180>
Failure: expected <Date(1288475940000)> found <Date(1288479540000)>
Failure: expected <Date(1288476000000)> found <Date(1288479600000)>
Failure: expected <Date(1288477800000)> found <Date(1288481400000)>
Failure: expected <Date(1288479540000)> found <Date(1288483140000)>
Failure: expected <Date(1301180340000)> found <Date(1301176740000)>
Failure: expected <Date(1301180400000)> found <Date(1301176800000)>
Failure: expected <Date(1301182200000)> found <Date(1301178600000)>
Failure: expected <-240> found <-180>
Failure: expected <Date(1414270740000)> found <Date(1414274340000)>
Failure: expected <Date(1414270800000)> found <Date(1414274400000)>
Failure: expected <Date(1414272600000)> found <Date(1414276200000)>
Failure: expected <Date(1414274340000)> found <Date(1414277940000)>
=== tzoffset-transition-new-york-noi18n.js TZ=America/New_York
Failure: expected <Date(1489302000000)> found <Date(1489305600000)>
Failure: expected <Date(1489303800000)> found <Date(1489307400000)>
Failure: expected <Date(1509865200000)> found <Date(1509861600000)>
Failure: expected <Date(1509868800000)> found <Date(1509865200000)>
=== tzoffset-transition-new-york.js TZ=America/New_York
Failure: expected <Date(1489302000000)> found <Date(1489305600000)>
Failure: expected <Date(1489303800000)> found <Date(1489307400000)>
Failure: expected <Date(1509865200000)> found <Date(1509861600000)>
Failure: expected <Date(1509868800000)> found <Date(1509865200000)>
=== ubsan-fuzzerbugs.js
=== undeletable-functions.js
=== unicode-case-overoptimization.js
Failure (181): expected <true> found <false>
Failure (224): expected <true> found <false>
Failure (225): expected <true> found <false>
Failure (226): expected <true> found <false>
Failure (227): expected <true> found <false>
Failure (228): expected <true> found <false>
Failure (229): expected <true> found <false>
Failure (230): expected <true> found <false>
Failure (231): expected <true> found <false>
Failure (232): expected <true> found <false>
Failure (233): expected <true> found <false>
Failure (234): expected <true> found <false>
Failure (235): expected <true> found <false>
Failure (236): expected <true> found <false>
Failure (237): expected <true> found <false>
Failure (238): expected <true> found <false>
Failure (239): expected <true> found <false>
Failure (240): expected <true> found <false>
Failure (241): expected <true> found <false>
Failure (242): expected <true> found <false>
Failure (243): expected <true> found <false>
Failure (244): expected <true> found <false>
Failure (245): expected <true> found <false>
Failure (246): expected <true> found <false>
Failure (248): expected <true> found <false>
Failure (249): expected <true> found <false>
Failure (250): expected <true> found <false>
Failure (251): expected <true> found <false>
Failure (252): expected <true> found <false>
Failure (253): expected <true> found <false>
Failure (254): expected <true> found <false>
Failure (255): expected <true> found <false>
Failure (257): expected <true> found <false>
Failure (259): expected <true> found <false>
Failure (261): expected <true> found <false>
Failure (263): expected <true> found <false>
Failure (265): expected <true> found <false>
Failure (267): expected <true> found <false>
Failure (269): expected <true> found <false>
Failure (271): expected <true> found <false>
Failure (273): expected <true> found <false>
Failure (275): expected <true> found <false>
Failure (277): expected <true> found <false>
Failure (279): expected <true> found <false>
Failure (281): expected <true> found <false>
Failure (283): expected <true> found <false>
Failure (285): expected <true> found <false>
Failure (287): expected <true> found <false>
Failure (289): expected <true> found <false>
Failure (291): expected <true> found <false>
Failure (293): expected <true> found <false>
Failure (295): expected <true> found <false>
Failure (297): expected <true> found <false>
Failure (299): expected <true> found <false>
Failure (301): expected <true> found <false>
Failure (303): expected <true> found <false>
Failure (307): expected <true> found <false>
Failure (309): expected <true> found <false>
Failure (311): expected <true> found <false>
Failure (314): expected <true> found <false>
Failure (316): expected <true> found <false>
Failure (318): expected <true> found <false>
Failure (320): expected <true> found <false>
Failure (322): expected <true> found <false>
Failure (324): expected <true> found <false>
Failure (326): expected <true> found <false>
Failure (328): expected <true> found <false>
Failure (331): expected <true> found <false>
Failure (333): expected <true> found <false>
Failure (335): expected <true> found <false>
Failure (337): expected <true> found <false>
Failure (339): expected <true> found <false>
Failure (341): expected <true> found <false>
Failure (343): expected <true> found <false>
Failure (345): expected <true> found <false>
Failure (347): expected <true> found <false>
Failure (349): expected <true> found <false>
Failure (351): expected <true> found <false>
Failure (353): expected <true> found <false>
Failure (355): expected <true> found <false>
Failure (357): expected <true> found <false>
Failure (359): expected <true> found <false>
Failure (361): expected <true> found <false>
Failure (363): expected <true> found <false>
Failure (365): expected <true> found <false>
Failure (367): expected <true> found <false>
Failure (369): expected <true> found <false>
Failure (371): expected <true> found <false>
Failure (373): expected <true> found <false>
Failure (375): expected <true> found <false>
Failure (378): expected <true> found <false>
Failure (380): expected <true> found <false>
Failure (382): expected <true> found <false>
Failure (384): expected <true> found <false>
Failure (387): expected <true> found <false>
Failure (389): expected <true> found <false>
Failure (392): expected <true> found <false>
Failure (396): expected <true> found <false>
Failure (402): expected <true> found <false>
<output elided>
=== unicode-string-to-number.js
=== unicode-test.js
=== unicodelctest-no-optimization.js
=== unicodelctest.js
=== unused-context-in-with.js
=== unusual-constructor.js
=== uri.js
=== value-callic-prototype-change.js
=== value-of.js
=== value-wrapper.js
=== var.js
=== whitespaces.js
=== with-function-expression.js
=== with-leave.js
=== with-parameter-access.js
=== with-prototype.js
=== with-readonly.js
=== with-value.js