├── .gitattributes ├── .github └── workflows │ ├── ci.yml │ ├── docs.yml │ ├── release.yml │ ├── test-docs.yml │ ├── tsan.yml │ └── valgrind.yml ├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── Makefile ├── README.md ├── ctest.c ├── cutils.c ├── cutils.h ├── cxxtest.cc ├── dirent_compat.h ├── docs ├── .gitignore ├── .nvmrc ├── babel.config.js ├── docs │ ├── building.md │ ├── cli.md │ ├── developer-guide │ │ ├── _category_.json │ │ ├── api.md │ │ ├── internals.md │ │ └── intro.md │ ├── diff.md │ ├── es_features.md │ ├── installation.md │ ├── intro.md │ ├── projects.md │ ├── stdlib.md │ └── supported_platforms.md ├── docusaurus.config.js ├── package-lock.json ├── package.json ├── sidebars.js ├── src │ └── css │ │ └── custom.css └── static │ ├── .nojekyll │ └── img │ └── favicon.ico ├── examples ├── fib.c ├── fib_module.js ├── hello.js ├── hello_module.js ├── pi_bigint.js ├── point.c ├── test_fib.js └── test_point.js ├── fuzz.c ├── gen ├── function_source.c ├── hello.c ├── hello_module.c ├── repl.c ├── standalone.c └── test_fib.c ├── getopt_compat.h ├── libbf.c ├── libbf.h ├── libregexp-opcode.h ├── libregexp.c ├── libregexp.h ├── libunicode-table.h ├── libunicode.c ├── libunicode.h ├── list.h ├── qjs.c ├── qjsc.c ├── quickjs-atom.h ├── quickjs-c-atomics.h ├── quickjs-libc.c ├── quickjs-libc.h ├── quickjs-opcode.h ├── quickjs.c ├── quickjs.h ├── repl.js ├── run-test262.c ├── standalone.js ├── test262-fast.conf ├── test262.conf ├── test262_errors.txt ├── tests.conf ├── tests ├── assert.js ├── bug633 │ ├── 0.js │ ├── 1.js │ ├── 2.js │ └── 3.js ├── bug645 │ ├── 0.js │ ├── 1.js │ └── 2.js ├── bug648.js ├── bug652.js ├── bug741.js ├── bug775.js ├── bug776.js ├── detect_module │ ├── 0.js │ ├── 1.js │ ├── 2.js │ ├── 3.js │ └── 4.js ├── fixture_cyclic_import.js ├── function_source.js ├── microbench.js ├── test_bigint.js ├── test_bjson.js ├── test_builtin.js ├── test_closure.js ├── test_conv.c ├── test_cyclic_import.js ├── test_language.js ├── test_loop.js ├── test_queue_microtask.js ├── test_std.js ├── test_worker.js └── test_worker_module.js ├── unicode_download.sh ├── unicode_gen.c └── unicode_gen_def.h /.gitattributes: -------------------------------------------------------------------------------- 1 | # Don't show changes in generated files when doing git diff 2 | 3 | gen/** -diff 4 | 5 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | name: Docs 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | paths: 8 | - 'docs/**' 9 | - '.github/workflows/*docs.yml' 10 | 11 | jobs: 12 | build: 13 | name: Build Docusaurus 14 | runs-on: ubuntu-latest 15 | steps: 16 | - uses: actions/checkout@v4 17 | - uses: actions/setup-node@v4 18 | with: 19 | node-version-file: 'docs/.nvmrc' 20 | - name: Install dependencies 21 | working-directory: ./docs 22 | run: npm install 23 | - name: Build 24 | working-directory: ./docs 25 | run: npm run build 26 | - name: Upload Build Artifact 27 | uses: actions/upload-pages-artifact@v3 28 | with: 29 | path: docs/build 30 | 31 | deploy: 32 | name: Deploy to GitHub Pages 33 | needs: build 34 | 35 | # Grant GITHUB_TOKEN the permissions required to make a Pages deployment 36 | permissions: 37 | pages: write # to deploy to Pages 38 | id-token: write # to verify the deployment originates from an appropriate source 39 | 40 | # Deploy to the github-pages environment 41 | environment: 42 | name: github-pages 43 | url: ${{ steps.deployment.outputs.page_url }} 44 | 45 | runs-on: ubuntu-latest 46 | steps: 47 | - name: Deploy to GitHub Pages 48 | id: deployment 49 | uses: actions/deploy-pages@v4 50 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | 3 | on: 4 | pull_request: 5 | push: 6 | tags: 7 | - "v*.*.*" 8 | 9 | jobs: 10 | linux: 11 | runs-on: ubuntu-20.04 12 | strategy: 13 | fail-fast: false 14 | matrix: 15 | arch: [aarch64, riscv64, x86, x86_64] 16 | steps: 17 | - uses: actions/checkout@v4 18 | - uses: jirutka/setup-alpine@v1 19 | with: 20 | arch: ${{matrix.arch}} 21 | packages: "build-base make cmake" 22 | - name: build 23 | shell: alpine.sh {0} 24 | run: | 25 | mkdir build 26 | cd build 27 | cmake -DBUILD_STATIC_QJS_EXE=ON .. 28 | cd .. 29 | cmake --build build --target qjs_exe -j$(getconf _NPROCESSORS_ONLN) 30 | cmake --build build --target qjsc -j$(getconf _NPROCESSORS_ONLN) 31 | mv build/qjs build/qjs-linux-${{matrix.arch}} 32 | mv build/qjsc build/qjsc-linux-${{matrix.arch}} 33 | - name: check 34 | shell: alpine.sh {0} 35 | run: | 36 | file build/*-linux-${{matrix.arch}} 37 | - name: upload 38 | uses: actions/upload-artifact@v4 39 | with: 40 | name: qjs-linux-${{matrix.arch}} 41 | path: build/*-linux-${{matrix.arch}} 42 | 43 | macos: 44 | runs-on: macos-latest 45 | steps: 46 | - uses: actions/checkout@v4 47 | - name: build 48 | run: | 49 | mkdir build 50 | cd build 51 | cmake -DCMAKE_OSX_ARCHITECTURES="x86_64;arm64" .. 52 | make -j$(getconf _NPROCESSORS_ONLN) 53 | mv qjs qjs-darwin 54 | mv qjsc qjsc-darwin 55 | - name: check 56 | run: | 57 | lipo -info build/qjs-darwin build/qjsc-darwin 58 | - name: upload 59 | uses: actions/upload-artifact@v4 60 | with: 61 | name: qjs-darwin 62 | path: build/*-darwin 63 | 64 | windows: 65 | runs-on: windows-latest 66 | strategy: 67 | fail-fast: false 68 | matrix: 69 | arch: [x86, x86_64] 70 | defaults: 71 | run: 72 | shell: msys2 {0} 73 | steps: 74 | - uses: actions/checkout@v4 75 | - name: Setup MSYS2 76 | uses: msys2/setup-msys2@v2 77 | with: 78 | msystem: ${{ matrix.arch == 'x86' && 'mingw32' || 'ucrt64' }} 79 | install: >- 80 | git 81 | make 82 | pacboy: >- 83 | cmake:p 84 | ninja:p 85 | toolchain:p 86 | - name: build 87 | run: | 88 | make 89 | mv build/qjs.exe build/qjs-windows-${{matrix.arch}}.exe 90 | mv build/qjsc.exe build/qjsc-windows-${{matrix.arch}}.exe 91 | - name: check 92 | run: | 93 | file build/qjs-windows-${{matrix.arch}}.exe 94 | ldd build/qjs-windows-${{matrix.arch}}.exe build/qjsc-windows-${{matrix.arch}}.exe 95 | - name: upload 96 | uses: actions/upload-artifact@v4 97 | with: 98 | name: qjs-windows-${{matrix.arch}} 99 | path: build/*-windows-${{matrix.arch}}.exe 100 | 101 | wasi: 102 | runs-on: ubuntu-20.04 103 | steps: 104 | - uses: actions/checkout@v4 105 | - name: setup wasi-sdk 106 | run: | 107 | wget -nv https://github.com/WebAssembly/wasi-sdk/releases/download/wasi-sdk-21/wasi-sdk_21.0_amd64.deb -P /tmp 108 | sudo apt install /tmp/wasi-sdk*.deb 109 | - name: build 110 | run: | 111 | cmake -B build -DCMAKE_TOOLCHAIN_FILE=/opt/wasi-sdk/share/cmake/wasi-sdk.cmake 112 | make -C build qjs_exe 113 | mv build/qjs build/qjs-wasi.wasm 114 | - name: upload 115 | uses: actions/upload-artifact@v4 116 | with: 117 | name: qjs-wasi 118 | path: build/qjs-wasi.wasm 119 | 120 | upload-to-release: 121 | needs: [linux, macos, windows, wasi] 122 | runs-on: ubuntu-20.04 123 | steps: 124 | - name: get assets 125 | uses: actions/download-artifact@v4 126 | with: 127 | pattern: qjs-* 128 | path: build 129 | merge-multiple: true 130 | - run: ls -R build 131 | - name: release 132 | if: ${{ startsWith(github.ref, 'refs/tags/v') }} 133 | uses: softprops/action-gh-release@v1 134 | with: 135 | files: | 136 | build/* 137 | -------------------------------------------------------------------------------- /.github/workflows/test-docs.yml: -------------------------------------------------------------------------------- 1 | name: Test Docs 2 | 3 | on: 4 | pull_request: 5 | paths: 6 | - 'docs/**' 7 | - '.github/workflows/*docs.yml' 8 | 9 | jobs: 10 | test-docs: 11 | name: Test Docusaurus build 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: actions/setup-node@v4 16 | with: 17 | node-version-file: 'docs/.nvmrc' 18 | - name: Install dependencies 19 | working-directory: ./docs 20 | run: npm install 21 | - name: Build 22 | working-directory: ./docs 23 | run: npm run build 24 | -------------------------------------------------------------------------------- /.github/workflows/tsan.yml: -------------------------------------------------------------------------------- 1 | name: tsan 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | paths: 8 | - '**' 9 | - '!.gitignore' 10 | - '!LICENSE' 11 | - '!README.md' 12 | - '!docs/**' 13 | - '!examples/**' 14 | - '.github/workflows/tsan.yml' 15 | - '.github/workflows/valgrind.yml' 16 | workflow_dispatch: 17 | 18 | jobs: 19 | linux: 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/checkout@v4 23 | with: 24 | submodules: true 25 | - name: build 26 | run: | 27 | cmake -B build -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCONFIG_TSAN=ON 28 | cmake --build build -j`nproc` 29 | - name: test 30 | run: | 31 | git submodule update --init --checkout --depth 1 32 | ./build/run-test262 -m -c test262.conf -c test262-fast.conf -a 33 | -------------------------------------------------------------------------------- /.github/workflows/valgrind.yml: -------------------------------------------------------------------------------- 1 | name: valgrind 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | paths: 8 | - '**' 9 | - '!.gitignore' 10 | - '!LICENSE' 11 | - '!README.md' 12 | - '!docs/**' 13 | - '!examples/**' 14 | - '.github/workflows/tsan.yml' 15 | - '.github/workflows/valgrind.yml' 16 | workflow_dispatch: 17 | 18 | jobs: 19 | linux: 20 | runs-on: ubuntu-latest 21 | steps: 22 | - uses: actions/checkout@v4 23 | with: 24 | submodules: true 25 | - name: install valgrind 26 | run: sudo apt-get update && sudo apt-get install valgrind 27 | - name: build 28 | run: | 29 | make BUILD_TYPE=RelWithDebInfo 30 | - name: test 31 | run: | 32 | git submodule update --init --checkout --depth 1 33 | 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 34 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.a 2 | *.orig 3 | *.so 4 | .obj/ 5 | build/ 6 | unicode/ 7 | .idea 8 | cmake-* 9 | .vs 10 | out/ 11 | CMakeUserPresets.json 12 | fuzz 13 | .vscode/ -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "test262"] 2 | path = test262 3 | url = https://github.com/tc39/test262 4 | shallow = true 5 | update = none 6 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.10) 2 | 3 | project(quickjs LANGUAGES C) 4 | 5 | include(CheckCCompilerFlag) 6 | include(GNUInstallDirs) 7 | 8 | set(CMAKE_C_VISIBILITY_PRESET hidden) 9 | set(CMAKE_C_STANDARD_REQUIRED ON) 10 | set(CMAKE_C_EXTENSIONS ON) 11 | set(CMAKE_C_STANDARD 11) 12 | 13 | if(NOT CMAKE_BUILD_TYPE) 14 | message(STATUS "No build type selected, default to Release") 15 | set(CMAKE_BUILD_TYPE "Release") 16 | endif() 17 | 18 | message(STATUS "Building in ${CMAKE_BUILD_TYPE} mode") 19 | message(STATUS "Building with ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION} on ${CMAKE_SYSTEM}") 20 | 21 | macro(xcheck_add_c_compiler_flag FLAG) 22 | string(REPLACE "-" "" FLAG_NO_HYPHEN ${FLAG}) 23 | check_c_compiler_flag(${FLAG} COMPILER_SUPPORTS_${FLAG_NO_HYPHEN}) 24 | if(COMPILER_SUPPORTS_${FLAG_NO_HYPHEN}) 25 | add_compile_options(${FLAG}) 26 | endif() 27 | endmacro() 28 | 29 | xcheck_add_c_compiler_flag(-Wall) 30 | if(NOT MSVC AND NOT IOS) 31 | xcheck_add_c_compiler_flag(-Werror) 32 | xcheck_add_c_compiler_flag(-Wextra) 33 | endif() 34 | xcheck_add_c_compiler_flag(-Wno-implicit-fallthrough) 35 | xcheck_add_c_compiler_flag(-Wno-sign-compare) 36 | xcheck_add_c_compiler_flag(-Wno-missing-field-initializers) 37 | xcheck_add_c_compiler_flag(-Wno-unused-parameter) 38 | xcheck_add_c_compiler_flag(-Wno-unused-but-set-variable) 39 | xcheck_add_c_compiler_flag(-Wno-array-bounds) 40 | xcheck_add_c_compiler_flag(-Wno-format-truncation) 41 | xcheck_add_c_compiler_flag(-funsigned-char) 42 | 43 | # ClangCL is command line compatible with MSVC, so 'MSVC' is set. 44 | if(MSVC) 45 | xcheck_add_c_compiler_flag(-Wno-unsafe-buffer-usage) 46 | xcheck_add_c_compiler_flag(-Wno-sign-conversion) 47 | xcheck_add_c_compiler_flag(-Wno-nonportable-system-include-path) 48 | xcheck_add_c_compiler_flag(-Wno-implicit-int-conversion) 49 | xcheck_add_c_compiler_flag(-Wno-shorten-64-to-32) 50 | xcheck_add_c_compiler_flag(-Wno-reserved-macro-identifier) 51 | xcheck_add_c_compiler_flag(-Wno-reserved-identifier) 52 | xcheck_add_c_compiler_flag(-Wdeprecated-declarations) 53 | xcheck_add_c_compiler_flag(/experimental:c11atomics) 54 | xcheck_add_c_compiler_flag(/wd4018) # -Wno-sign-conversion 55 | xcheck_add_c_compiler_flag(/wd4061) # -Wno-implicit-fallthrough 56 | xcheck_add_c_compiler_flag(/wd4100) # -Wno-unused-parameter 57 | xcheck_add_c_compiler_flag(/wd4200) # -Wno-zero-length-array 58 | xcheck_add_c_compiler_flag(/wd4242) # -Wno-shorten-64-to-32 59 | xcheck_add_c_compiler_flag(/wd4244) # -Wno-shorten-64-to-32 60 | xcheck_add_c_compiler_flag(/wd4245) # -Wno-sign-compare 61 | xcheck_add_c_compiler_flag(/wd4267) # -Wno-shorten-64-to-32 62 | xcheck_add_c_compiler_flag(/wd4388) # -Wno-sign-compare 63 | xcheck_add_c_compiler_flag(/wd4389) # -Wno-sign-compare 64 | xcheck_add_c_compiler_flag(/wd4710) # Function not inlined 65 | xcheck_add_c_compiler_flag(/wd4711) # Function was inlined 66 | xcheck_add_c_compiler_flag(/wd4820) # Padding added after construct 67 | xcheck_add_c_compiler_flag(/wd4996) # -Wdeprecated-declarations 68 | xcheck_add_c_compiler_flag(/wd5045) # Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified 69 | endif() 70 | 71 | # MacOS and GCC 11 or later need -Wno-maybe-uninitialized 72 | # https://github.com/quickjs-ng/quickjs/issues/453 73 | if(APPLE AND CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 11) 74 | xcheck_add_c_compiler_flag(-Wno-maybe-uninitialized) 75 | endif() 76 | 77 | if(CMAKE_SYSTEM_NAME STREQUAL "WASI") 78 | add_compile_definitions( 79 | _WASI_EMULATED_PROCESS_CLOCKS 80 | _WASI_EMULATED_SIGNAL 81 | ) 82 | add_link_options( 83 | -lwasi-emulated-process-clocks 84 | -lwasi-emulated-signal 85 | ) 86 | endif() 87 | 88 | if(CMAKE_BUILD_TYPE MATCHES "Debug") 89 | add_compile_options(-O0) 90 | xcheck_add_c_compiler_flag(-ggdb) 91 | xcheck_add_c_compiler_flag(-fno-omit-frame-pointer) 92 | endif() 93 | 94 | macro(xoption OPTION_NAME OPTION_TEXT OPTION_DEFAULT) 95 | option(${OPTION_NAME} ${OPTION_TEXT} ${OPTION_DEFAULT}) 96 | if(DEFINED ENV{${OPTION_NAME}}) 97 | # Allow setting the option through an environment variable. 98 | set(${OPTION_NAME} $ENV{${OPTION_NAME}}) 99 | endif() 100 | if(${OPTION_NAME}) 101 | add_definitions(-D${OPTION_NAME}) 102 | endif() 103 | message(STATUS " ${OPTION_NAME}: ${${OPTION_NAME}}") 104 | endmacro() 105 | 106 | xoption(BUILD_SHARED_LIBS "Build a shared library" OFF) 107 | if(BUILD_SHARED_LIBS) 108 | message(STATUS "Building a shared library") 109 | endif() 110 | 111 | # note: CONFIG_TSAN is currently incompatible with the other sanitizers but we 112 | # don't explicitly check for that because who knows what the future will bring? 113 | # CONFIG_MSAN only works with clang at the time of writing; also not checked 114 | # for the same reason 115 | xoption(BUILD_EXAMPLES "Build examples" OFF) 116 | xoption(BUILD_STATIC_QJS_EXE "Build a static qjs executable" OFF) 117 | xoption(BUILD_CLI_WITH_MIMALLOC "Build the qjs executable with mimalloc" OFF) 118 | xoption(BUILD_CLI_WITH_STATIC_MIMALLOC "Build the qjs executable with mimalloc (statically linked)" OFF) 119 | xoption(CONFIG_ASAN "Enable AddressSanitizer (ASan)" OFF) 120 | xoption(CONFIG_MSAN "Enable MemorySanitizer (MSan)" OFF) 121 | xoption(CONFIG_TSAN "Enable ThreadSanitizer (TSan)" OFF) 122 | xoption(CONFIG_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan)" OFF) 123 | 124 | if(CONFIG_ASAN) 125 | message(STATUS "Building with ASan") 126 | add_compile_options( 127 | -fsanitize=address 128 | -fno-sanitize-recover=all 129 | -fno-omit-frame-pointer 130 | ) 131 | add_link_options( 132 | -fsanitize=address 133 | -fno-sanitize-recover=all 134 | -fno-omit-frame-pointer 135 | ) 136 | endif() 137 | 138 | if(CONFIG_MSAN) 139 | message(STATUS "Building with MSan") 140 | add_compile_options( 141 | -fsanitize=memory 142 | -fno-sanitize-recover=all 143 | -fno-omit-frame-pointer 144 | ) 145 | add_link_options( 146 | -fsanitize=memory 147 | -fno-sanitize-recover=all 148 | -fno-omit-frame-pointer 149 | ) 150 | endif() 151 | 152 | if(CONFIG_TSAN) 153 | message(STATUS "Building with TSan") 154 | add_compile_options( 155 | -fsanitize=thread 156 | -fno-sanitize-recover=all 157 | -fno-omit-frame-pointer 158 | ) 159 | add_link_options( 160 | -fsanitize=thread 161 | -fno-sanitize-recover=all 162 | -fno-omit-frame-pointer 163 | ) 164 | endif() 165 | 166 | if(CONFIG_UBSAN) 167 | message(STATUS "Building with UBSan") 168 | add_compile_options( 169 | -fsanitize=undefined 170 | -fno-sanitize-recover=all 171 | -fno-omit-frame-pointer 172 | ) 173 | add_link_options( 174 | -fsanitize=undefined 175 | -fno-sanitize-recover=all 176 | -fno-omit-frame-pointer 177 | ) 178 | endif() 179 | 180 | 181 | # QuickJS library 182 | # 183 | 184 | xoption(BUILD_QJS_LIBC "Build standard library modules as part of the library" OFF) 185 | macro(add_qjs_libc_if_needed target) 186 | if(NOT BUILD_QJS_LIBC) 187 | target_sources(${target} PRIVATE quickjs-libc.c) 188 | endif() 189 | endmacro() 190 | 191 | set(qjs_sources 192 | cutils.c 193 | libbf.c 194 | libregexp.c 195 | libunicode.c 196 | quickjs.c 197 | ) 198 | 199 | if(BUILD_QJS_LIBC) 200 | list(APPEND qjs_sources quickjs-libc.c) 201 | endif() 202 | list(APPEND qjs_defines _GNU_SOURCE) 203 | if(WIN32) 204 | list(APPEND qjs_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0602) 205 | endif() 206 | list(APPEND qjs_libs ${CMAKE_DL_LIBS}) 207 | find_package(Threads) 208 | if(NOT CMAKE_SYSTEM_NAME STREQUAL "WASI") 209 | list(APPEND qjs_libs ${CMAKE_THREAD_LIBS_INIT}) 210 | endif() 211 | 212 | # try to find libm 213 | find_library(M_LIBRARIES m) 214 | if(M_LIBRARIES OR CMAKE_C_COMPILER_ID STREQUAL "TinyCC") 215 | list(APPEND qjs_libs m) 216 | endif() 217 | 218 | add_library(qjs ${qjs_sources}) 219 | target_compile_definitions(qjs PRIVATE ${qjs_defines}) 220 | target_include_directories(qjs PUBLIC 221 | $ 222 | $ 223 | ) 224 | target_link_libraries(qjs PUBLIC ${qjs_libs}) 225 | 226 | if(EMSCRIPTEN) 227 | add_executable(qjs_wasm ${qjs_sources}) 228 | target_link_options(qjs_wasm PRIVATE 229 | # in emscripten 3.x, this will be set to 16k which is too small for quickjs. #write sth. to force github rebuild 230 | -sSTACK_SIZE=2097152 # let it be 2m = 2 * 1024 * 1024 = 2097152, otherwise, stack overflow may be occured at bootstrap 231 | -sNO_INVOKE_RUN 232 | -sNO_EXIT_RUNTIME 233 | -sMODULARIZE # do not mess the global 234 | -sEXPORT_ES6 # export js file to morden es module 235 | -sEXPORT_NAME=getQuickJs # give a name 236 | -sTEXTDECODER=1 # it will be 2 if we use -Oz, and that will cause js -> c string convertion fail 237 | -sNO_DEFAULT_TO_CXX # this project is pure c project, no need for c plus plus handle 238 | -sEXPORTED_RUNTIME_METHODS=ccall,cwrap 239 | ) 240 | target_compile_definitions(qjs_wasm PRIVATE ${qjs_defines}) 241 | target_link_libraries(qjs_wasm m) 242 | endif() 243 | 244 | 245 | # QuickJS bytecode compiler 246 | # 247 | 248 | add_executable(qjsc 249 | qjsc.c 250 | ) 251 | add_qjs_libc_if_needed(qjsc) 252 | target_compile_definitions(qjsc PRIVATE ${qjs_defines}) 253 | target_link_libraries(qjsc qjs) 254 | 255 | 256 | # QuickJS CLI 257 | # 258 | 259 | add_executable(qjs_exe 260 | gen/repl.c 261 | gen/standalone.c 262 | qjs.c 263 | ) 264 | add_qjs_libc_if_needed(qjs_exe) 265 | set_target_properties(qjs_exe PROPERTIES 266 | OUTPUT_NAME "qjs" 267 | ) 268 | target_compile_definitions(qjs_exe PRIVATE ${qjs_defines}) 269 | target_link_libraries(qjs_exe qjs) 270 | if(BUILD_STATIC_QJS_EXE OR MINGW) 271 | target_link_options(qjs_exe PRIVATE -static) 272 | if(MINGW) 273 | target_link_options(qjs_exe PRIVATE -static-libgcc) 274 | endif() 275 | endif() 276 | if(NOT WIN32) 277 | set_target_properties(qjs_exe PROPERTIES ENABLE_EXPORTS TRUE) 278 | endif() 279 | if(BUILD_CLI_WITH_MIMALLOC OR BUILD_CLI_WITH_STATIC_MIMALLOC) 280 | find_package(mimalloc REQUIRED) 281 | # Upstream mimalloc doesn't provide a way to know if both libraries are supported. 282 | if(BUILD_CLI_WITH_STATIC_MIMALLOC) 283 | target_link_libraries(qjs_exe mimalloc-static) 284 | else() 285 | target_link_libraries(qjs_exe mimalloc) 286 | endif() 287 | endif() 288 | 289 | # Test262 runner 290 | # 291 | 292 | if(NOT EMSCRIPTEN) 293 | add_executable(run-test262 294 | run-test262.c 295 | ) 296 | add_qjs_libc_if_needed(run-test262) 297 | target_compile_definitions(run-test262 PRIVATE ${qjs_defines}) 298 | target_link_libraries(run-test262 qjs) 299 | endif() 300 | 301 | # Unicode generator 302 | # 303 | 304 | add_executable(unicode_gen EXCLUDE_FROM_ALL 305 | cutils.c 306 | libunicode.c 307 | unicode_gen.c 308 | ) 309 | target_compile_definitions(unicode_gen PRIVATE ${qjs_defines}) 310 | 311 | add_executable(function_source 312 | gen/function_source.c 313 | ) 314 | add_qjs_libc_if_needed(function_source) 315 | target_include_directories(function_source PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) 316 | target_compile_definitions(function_source PRIVATE ${qjs_defines}) 317 | target_link_libraries(function_source qjs) 318 | 319 | # Examples 320 | # 321 | 322 | if(BUILD_EXAMPLES) 323 | add_executable(hello 324 | gen/hello.c 325 | ) 326 | add_qjs_libc_if_needed(hello) 327 | target_include_directories(hello PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) 328 | target_compile_definitions(hello PRIVATE ${qjs_defines}) 329 | target_link_libraries(hello qjs) 330 | 331 | add_executable(hello_module 332 | gen/hello_module.c 333 | ) 334 | add_qjs_libc_if_needed(hello_module) 335 | target_include_directories(hello_module PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) 336 | target_compile_definitions(hello_module PRIVATE ${qjs_defines}) 337 | target_link_libraries(hello_module qjs) 338 | 339 | add_library(fib MODULE examples/fib.c) 340 | set_target_properties(fib PROPERTIES 341 | PREFIX "" 342 | C_VISIBILITY_PRESET default 343 | ) 344 | target_compile_definitions(fib PRIVATE JS_SHARED_LIBRARY) 345 | if(WIN32) 346 | target_link_libraries(fib qjs) 347 | elseif(APPLE) 348 | target_link_options(fib PRIVATE -undefined dynamic_lookup) 349 | endif() 350 | 351 | add_library(point MODULE examples/point.c) 352 | set_target_properties(point PROPERTIES 353 | PREFIX "" 354 | C_VISIBILITY_PRESET default 355 | ) 356 | target_compile_definitions(point PRIVATE JS_SHARED_LIBRARY) 357 | if(WIN32) 358 | target_link_libraries(point qjs) 359 | elseif(APPLE) 360 | target_link_options(point PRIVATE -undefined dynamic_lookup) 361 | endif() 362 | 363 | add_executable(test_fib 364 | examples/fib.c 365 | gen/test_fib.c 366 | ) 367 | add_qjs_libc_if_needed(test_fib) 368 | target_include_directories(test_fib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) 369 | target_compile_definitions(test_fib PRIVATE ${qjs_defines}) 370 | target_link_libraries(test_fib qjs) 371 | endif() 372 | 373 | add_executable(test_conv 374 | tests/test_conv.c 375 | ) 376 | 377 | # Install target 378 | # 379 | 380 | if(NOT IOS) 381 | file(STRINGS quickjs.h quickjs_h REGEX QJS_VERSION) 382 | string(REGEX MATCHALL "([0-9])" QJS_VERSION "${quickjs_h}") 383 | list(GET QJS_VERSION 0 QJS_VERSION_MAJOR) 384 | list(GET QJS_VERSION 1 QJS_VERSION_MINOR) 385 | list(GET QJS_VERSION 2 QJS_VERSION_PATCH) 386 | set_target_properties(qjs PROPERTIES 387 | VERSION ${QJS_VERSION_MAJOR}.${QJS_VERSION_MINOR}.${QJS_VERSION_PATCH} 388 | SOVERSION ${QJS_VERSION_MAJOR} 389 | ) 390 | install(FILES quickjs.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) 391 | if(BUILD_QJS_LIBC) 392 | install(FILES quickjs-libc.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) 393 | endif() 394 | install(TARGETS qjs_exe RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) 395 | install(TARGETS qjsc RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}) 396 | install(TARGETS qjs EXPORT qjsConfig 397 | RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} 398 | LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} 399 | ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}) 400 | install(EXPORT qjsConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/quickjs) 401 | install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR}) 402 | install(DIRECTORY examples DESTINATION ${CMAKE_INSTALL_DOCDIR}) 403 | endif() 404 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2017-2021 Fabrice Bellard 4 | Copyright (c) 2017-2021 Charlie Gordon 5 | Copyright (c) 2023 Ben Noordhuis 6 | Copyright (c) 2023 Saúl Ibarra Corretgé 7 | 8 | Permission is hereby granted, free of charge, to any person obtaining a copy 9 | of this software and associated documentation files (the "Software"), to deal 10 | in the Software without restriction, including without limitation the rights 11 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | copies of the Software, and to permit persons to whom the Software is 13 | furnished to do so, subject to the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be included in 16 | all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 21 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | THE SOFTWARE. 25 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # QuickJS Javascript Engine 3 | # 4 | # Copyright (c) 2017-2021 Fabrice Bellard 5 | # Copyright (c) 2017-2021 Charlie Gordon 6 | # Copyright (c) 2023 Ben Noordhuis 7 | # Copyright (c) 2023 Saúl Ibarra Corretgé 8 | # 9 | # Permission is hereby granted, free of charge, to any person obtaining a copy 10 | # of this software and associated documentation files (the "Software"), to deal 11 | # in the Software without restriction, including without limitation the rights 12 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | # copies of the Software, and to permit persons to whom the Software is 14 | # furnished to do so, subject to the following conditions: 15 | # 16 | # The above copyright notice and this permission notice shall be included in 17 | # all copies or substantial portions of the Software. 18 | # 19 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 22 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | # THE SOFTWARE. 26 | 27 | BUILD_DIR=build 28 | BUILD_TYPE?=Release 29 | INSTALL_PREFIX?=/usr/local 30 | 31 | QJS=$(BUILD_DIR)/qjs 32 | QJSC=$(BUILD_DIR)/qjsc 33 | RUN262=$(BUILD_DIR)/run-test262 34 | 35 | JOBS?=$(shell getconf _NPROCESSORS_ONLN) 36 | ifeq ($(JOBS),) 37 | JOBS := $(shell sysctl -n hw.ncpu) 38 | endif 39 | ifeq ($(JOBS),) 40 | JOBS := $(shell nproc) 41 | endif 42 | ifeq ($(JOBS),) 43 | JOBS := 4 44 | endif 45 | 46 | all: $(QJS) 47 | 48 | fuzz: 49 | clang -g -O1 -fsanitize=address,undefined,fuzzer -o fuzz fuzz.c 50 | ./fuzz 51 | 52 | $(BUILD_DIR): 53 | cmake -B $(BUILD_DIR) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DCMAKE_INSTALL_PREFIX=$(INSTALL_PREFIX) 54 | 55 | $(QJS): $(BUILD_DIR) 56 | cmake --build $(BUILD_DIR) -j $(JOBS) 57 | 58 | $(QJSC): $(BUILD_DIR) 59 | cmake --build $(BUILD_DIR) --target qjsc -j $(JOBS) 60 | 61 | $(BUILD_DIR)/test_conv: $(BUILD_DIR) tests/test_conv.c 62 | cmake --build $(BUILD_DIR) --target test_conv 63 | 64 | install: $(QJS) $(QJSC) 65 | cmake --build $(BUILD_DIR) --target install 66 | 67 | clean: 68 | cmake --build $(BUILD_DIR) --target clean 69 | 70 | codegen: $(QJSC) 71 | $(QJSC) -ss -o gen/repl.c -m repl.js 72 | $(QJSC) -ss -o gen/standalone.c -m standalone.js 73 | $(QJSC) -e -o gen/function_source.c tests/function_source.js 74 | $(QJSC) -e -o gen/hello.c examples/hello.js 75 | $(QJSC) -e -o gen/hello_module.c -m examples/hello_module.js 76 | $(QJSC) -e -o gen/test_fib.c -M examples/fib.so,fib -m examples/test_fib.js 77 | 78 | debug: 79 | BUILD_TYPE=Debug $(MAKE) 80 | 81 | distclean: 82 | @rm -rf $(BUILD_DIR) 83 | 84 | stats: $(QJS) 85 | $(QJS) -qd 86 | 87 | # effectively .PHONY because it doesn't generate output 88 | ctest: CFLAGS=-std=c11 -fsyntax-only -Wall -Wextra -Werror -pedantic 89 | ctest: ctest.c quickjs.h 90 | $(CC) $(CFLAGS) -DJS_NAN_BOXING=0 $< 91 | $(CC) $(CFLAGS) -DJS_NAN_BOXING=1 $< 92 | 93 | # effectively .PHONY because it doesn't generate output 94 | cxxtest: CXXFLAGS=-std=c++11 -fsyntax-only -Wall -Wextra -Werror -pedantic 95 | cxxtest: cxxtest.cc quickjs.h 96 | $(CXX) $(CXXFLAGS) -DJS_NAN_BOXING=0 $< 97 | $(CXX) $(CXXFLAGS) -DJS_NAN_BOXING=1 $< 98 | 99 | test: $(QJS) 100 | $(RUN262) -c tests.conf 101 | 102 | testconv: $(BUILD_DIR)/test_conv 103 | $(BUILD_DIR)/test_conv 104 | 105 | test262: $(QJS) 106 | $(RUN262) -m -c test262.conf -a 107 | 108 | test262-fast: $(QJS) 109 | $(RUN262) -m -c test262.conf -c test262-fast.conf -a 110 | 111 | test262-update: $(QJS) 112 | $(RUN262) -u -c test262.conf -a -t 1 113 | 114 | test262-check: $(QJS) 115 | $(RUN262) -m -c test262.conf -E -a 116 | 117 | microbench: $(QJS) 118 | $(QJS) tests/microbench.js 119 | 120 | unicode_gen: $(BUILD_DIR) 121 | cmake --build $(BUILD_DIR) --target unicode_gen 122 | 123 | libunicode-table.h: unicode_gen 124 | $(BUILD_DIR)/unicode_gen unicode $@ 125 | 126 | .PHONY: all ctest cxxtest debug fuzz install clean codegen distclean stats test test262 test262-update test262-check microbench unicode_gen $(QJS) $(QJSC) 127 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ⚡️ QuickJS - A mighty JavaScript engine 2 | 3 | ## Overview 4 | 5 | QuickJS is a small and embeddable JavaScript engine. It aims to support the latest 6 | [ECMAScript] specification. 7 | 8 | This project is a _fork_ of the [original QuickJS project] by Fabrice Bellard and Charlie Gordon, after it went dormant, with the intent of reigniting its development. 9 | 10 | ## Getting started 11 | 12 | Head over to the [project website] for instructions on how to get started and more 13 | documentation. 14 | 15 | ## Authors 16 | 17 | [@bnoordhuis], [@saghul], and many more [contributors]. 18 | 19 | [ECMAScript]: https://tc39.es/ecma262/ 20 | [original QuickJS project]: https://bellard.org/quickjs 21 | [@bnoordhuis]: https://github.com/bnoordhuis 22 | [@saghul]: https://github.com/saghul 23 | [contributors]: https://github.com/quickjs-ng/quickjs/graphs/contributors 24 | [project website]: https://quickjs-ng.github.io/quickjs/ 25 | -------------------------------------------------------------------------------- /ctest.c: -------------------------------------------------------------------------------- 1 | // note: file is not actually compiled, only checked for C syntax errors 2 | #include "quickjs.h" 3 | 4 | int main(void) 5 | { 6 | JSRuntime *rt = JS_NewRuntime(); 7 | JSContext *ctx = JS_NewContext(rt); 8 | JS_FreeValue(ctx, JS_NAN); 9 | JS_FreeValue(ctx, JS_UNDEFINED); 10 | JS_FreeValue(ctx, JS_NewFloat64(ctx, 42)); 11 | // not a legal way of using JS_MKPTR but this is here 12 | // to have the compiler syntax-check its definition 13 | JS_FreeValue(ctx, JS_MKPTR(JS_TAG_UNINITIALIZED, 0)); 14 | JS_FreeContext(ctx); 15 | JS_FreeRuntime(rt); 16 | return 0; 17 | } 18 | -------------------------------------------------------------------------------- /cxxtest.cc: -------------------------------------------------------------------------------- 1 | // note: file is not actually compiled, only checked for C++ syntax errors 2 | #include "ctest.c" 3 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | # Dependencies 2 | /node_modules 3 | 4 | # Production 5 | /build 6 | 7 | # Generated files 8 | .docusaurus 9 | .cache-loader 10 | 11 | # Misc 12 | .DS_Store 13 | .env.local 14 | .env.development.local 15 | .env.test.local 16 | .env.production.local 17 | 18 | npm-debug.log* 19 | yarn-debug.log* 20 | yarn-error.log* 21 | -------------------------------------------------------------------------------- /docs/.nvmrc: -------------------------------------------------------------------------------- 1 | 18 2 | -------------------------------------------------------------------------------- /docs/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [require.resolve('@docusaurus/core/lib/babel/preset')], 3 | }; 4 | -------------------------------------------------------------------------------- /docs/docs/building.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 2 3 | --- 4 | 5 | # Building 6 | 7 | QuickJS uses [CMake] as its main build system, with an additional helper [Makefile]. 8 | 9 | :::note 10 | Windows users will need to run the CMake commands manually. 11 | ::: 12 | 13 | ## Getting the source 14 | 15 | ```bash 16 | git clone https://github.com/quickjs-ng/quickjs.git 17 | cd quickjs 18 | ``` 19 | 20 | ## Compiling everything 21 | 22 | ```bash 23 | make 24 | ``` 25 | 26 | This will build the `qjs` and `qjsc` executables and other test tools. Head over [here](./cli) for 27 | instructions on how to use them. 28 | 29 | ## Debug builds 30 | 31 | ```bash 32 | make debug 33 | ``` 34 | 35 | This will produce a debug build without optimizations, suitable for developers. 36 | 37 | ## Running test262 38 | 39 | ```bash 40 | make test262 41 | ``` 42 | 43 | This will run the test262 suite. 44 | 45 | ```bash 46 | make test262-update 47 | ``` 48 | 49 | This will run the test262 suite and update the error / pass report, useful after 50 | implementing a new feature that would alter the result of the test suite. 51 | 52 | [CMake]: https://cmake.org 53 | [Makefile]: https://www.gnu.org/software/make/ 54 | -------------------------------------------------------------------------------- /docs/docs/cli.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 4 3 | --- 4 | 5 | # The qjs and qjsc CLI tools 6 | 7 | ## `qjs` - The QuickJS JavaScript interpreter 8 | 9 | The `qjs` executable runs the JavaScript interpreter. It includes a simple standard 10 | library and REPL. 11 | 12 | ``` 13 | $ qjs 14 | usage: qjs [options] [file [args]] 15 | -h --help list options 16 | -e --eval EXPR evaluate EXPR 17 | -i --interactive go to interactive mode 18 | -m --module load as ES6 module (default=autodetect) 19 | --script load as ES6 script (default=autodetect) 20 | -I --include file include an additional file 21 | --std make 'std', 'os' and 'bjson' available to script 22 | -T --trace trace memory allocation 23 | -d --dump dump the memory usage stats 24 | -D --dump-flags flags for dumping debug data (see DUMP_* defines) 25 | -c --compile FILE compile the given JS file as a standalone executable 26 | -o --out FILE output file for standalone executables 27 | --exe select the executable to use as the base, defaults to the current one 28 | --memory-limit n limit the memory usage to 'n' Kbytes 29 | --stack-size n limit the stack size to 'n' Kbytes 30 | --unhandled-rejection dump unhandled promise rejections 31 | -q --quit just instantiate the interpreter and quit 32 | ``` 33 | 34 | The following dump flags are supported: 35 | 36 | ``` 37 | DUMP_BYTECODE_FINAL 0x01 /* dump pass 3 final byte code */ 38 | DUMP_BYTECODE_PASS2 0x02 /* dump pass 2 code */ 39 | DUMP_BYTECODE_PASS1 0x04 /* dump pass 1 code */ 40 | DUMP_BYTECODE_HEX 0x10 /* dump bytecode in hex */ 41 | DUMP_BYTECODE_PC2LINE 0x20 /* dump line number table */ 42 | DUMP_BYTECODE_STACK 0x40 /* dump compute_stack_size */ 43 | DUMP_BYTECODE_STEP 0x80 /* dump executed bytecode */ 44 | DUMP_READ_OBJECT 0x100 /* dump the marshalled objects at load time */ 45 | DUMP_FREE 0x200 /* dump every object free */ 46 | DUMP_GC 0x400 /* dump the occurrence of the automatic GC */ 47 | DUMP_GC_FREE 0x800 /* dump objects freed by the GC */ 48 | DUMP_MODULE_RESOLVE 0x1000 /* dump module resolution steps */ 49 | DUMP_PROMISE 0x2000 /* dump promise steps */ 50 | DUMP_LEAKS 0x4000 /* dump leaked objects and strings in JS_FreeRuntime */ 51 | DUMP_ATOM_LEAKS 0x8000 /* dump leaked atoms in JS_FreeRuntime */ 52 | DUMP_MEM 0x10000 /* dump memory usage in JS_FreeRuntime */ 53 | DUMP_OBJECTS 0x20000 /* dump objects in JS_FreeRuntime */ 54 | DUMP_ATOMS 0x40000 /* dump atoms in JS_FreeRuntime */ 55 | DUMP_SHAPES 0x80000 /* dump shapes in JS_FreeRuntime */ 56 | ``` 57 | 58 | ### Creating standalone executables 59 | 60 | With the `qjs` CLI it's possible to create standalone executables that will bundle the given JavaScript file 61 | alongside the binary. 62 | 63 | ``` 64 | $ qjs -c app.js -o app --exe qjs 65 | ``` 66 | 67 | The resulting `app` binary will have the same runtime dependencies as the `qjs` binary. This is acomplished 68 | by compiling the target JavaScript file to bytecode and adding it a copy of the executable, with a little 69 | trailer to help locate it. 70 | 71 | Rather than using the current executable, it's possible to use the `--exe` switch to create standalone 72 | executables for other platforms. 73 | 74 | No JavaScript bundling is performed, the specified JS file cannot depend on other files. A bundler such 75 | as `esbuild` can be used to generate an app bundle which can then be turned into the executable. 76 | 77 | ``` 78 | npx esbuild my-app/index.js \ 79 | --bundle \ 80 | --outfile=app.js \ 81 | --external:qjs:* \ 82 | --minify \ 83 | --target=es2023 \ 84 | --platform=neutral \ 85 | --format=esm \ 86 | --main-fields=main,module 87 | ``` 88 | 89 | ## `qjsc` - The QuickJS JavaScript compiler 90 | 91 | The `qjsc` executable runs the JavaScript compiler, it can generate bytecode from 92 | source files which can then be embedded in an executable, or it can generate the necessary 93 | scaffolding to build a C application which embeds QuickJS. 94 | 95 | ``` 96 | $ qjsc 97 | usage: qjsc [options] [files] 98 | 99 | options are: 100 | -b output raw bytecode instead of C code 101 | -e output main() and bytecode in a C file 102 | -o output set the output filename 103 | -n script_name set the script name (as used in stack traces) 104 | -N cname set the C name of the generated data 105 | -m compile as JavaScript module (default=autodetect) 106 | -D module_name compile a dynamically loaded module or worker 107 | -M module_name[,cname] add initialization code for an external C module 108 | -p prefix set the prefix of the generated C names 109 | -s strip the source code, specify twice to also strip debug info 110 | -S n set the maximum stack size to 'n' bytes (default=262144) 111 | ``` 112 | 113 | Here is an example on how to create a standalone executable that embeds QuickJS 114 | and the `examples/hello.js` JavaScript file: 115 | 116 | ```bash 117 | # Make sure you are in the QuickJS source directory. 118 | $ cc hello.c cutils.c libbf.c libregexp.c libunicode.c quickjs.c quickjs-libc.c -I. -o hello 119 | ``` 120 | 121 | The resulting binary `hello` will be in the current directory. 122 | 123 | ```bash 124 | $ ./hello 125 | Hello World 126 | ``` 127 | 128 | :::note 129 | See the ["Creating standalone executables"](#creating-standalone-executables) section for a simpler way. 130 | ::: 131 | -------------------------------------------------------------------------------- /docs/docs/developer-guide/_category_.json: -------------------------------------------------------------------------------- 1 | { 2 | "label": "Developer Guide", 3 | "position": 6, 4 | "link": { 5 | "type": "generated-index" 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /docs/docs/developer-guide/api.md: -------------------------------------------------------------------------------- 1 | # API Reference 2 | 3 | WIP. 4 | -------------------------------------------------------------------------------- /docs/docs/developer-guide/internals.md: -------------------------------------------------------------------------------- 1 | # Internals 2 | 3 | ## Bytecode 4 | 5 | The compiler generates bytecode directly with no intermediate 6 | representation such as a parse tree, hence it is very fast. Several 7 | optimizations passes are done over the generated bytecode. 8 | 9 | A stack-based bytecode was chosen because it is simple and generates 10 | compact code. 11 | 12 | For each function, the maximum stack size is computed at compile time so that 13 | no runtime stack overflow tests are needed. 14 | 15 | A separate compressed line number table is maintained for the debug 16 | information. 17 | 18 | Access to closure variables is optimized and is almost as fast as local 19 | variables. 20 | 21 | Direct `eval` in strict mode is optimized. 22 | 23 | ## Runtime 24 | 25 | ### Strings 26 | 27 | Strings are stored either as an 8 bit or a 16 bit array of 28 | characters. Hence random access to characters is always fast. 29 | 30 | The C API provides functions to convert JavaScript Strings to C UTF-8 encoded 31 | strings. The most common case where the JavaScript string contains 32 | only ASCII characters involves no copying. 33 | 34 | ### Objects 35 | 36 | The object shapes (object prototype, property names and flags) are shared 37 | between objects to save memory. 38 | 39 | Arrays with no holes (except at the end of the array) are optimized. 40 | 41 | TypedArray accesses are optimized. 42 | 43 | ### Atoms 44 | 45 | Object property names and some strings are stored as Atoms (unique 46 | strings) to save memory and allow fast comparison. Atoms are 47 | represented as a 32 bit integer. Half of the atom range is reserved for 48 | immediate integer literals from 0 to 2^31-1. 49 | 50 | ### Numbers 51 | 52 | Numbers are represented either as 32-bit signed integers or 64-bit IEEE-754 53 | floating point values. Most operations have fast paths for the 32-bit 54 | integer case. 55 | 56 | ### Garbage collection 57 | 58 | Reference counting is used to free objects automatically and 59 | deterministically. A separate cycle removal pass is done when the allocated 60 | memory becomes too large. The cycle removal algorithm only uses the 61 | reference counts and the object content, so no explicit garbage 62 | collection roots need to be manipulated in the C code. 63 | 64 | ### JSValue 65 | 66 | It is a JavaScript value which can be a primitive type (such as 67 | Number, String, ...) or an Object. NaN boxing is used in the 32-bit version 68 | to store 64-bit floating point numbers. The representation is 69 | optimized so that 32-bit integers and reference counted values can be 70 | efficiently tested. 71 | 72 | In 64-bit code, JSValue are 128-bit large and no NaN boxing is used. The 73 | rationale is that in 64-bit code memory usage is less critical. 74 | 75 | In both cases (32 or 64 bits), JSValue exactly fits two CPU registers, 76 | so it can be efficiently returned by C functions. 77 | 78 | ### Function call 79 | 80 | The engine is optimized so that function calls are fast. The system 81 | stack holds the JavaScript parameters and local variables. 82 | 83 | ### RegExp 84 | 85 | A specific regular expression engine was developed. It is both small 86 | and efficient and supports all the ES2020+ features including the 87 | Unicode properties. As the JavaScript compiler, it directly generates 88 | bytecode without a parse tree. 89 | 90 | Backtracking with an explicit stack is used so that there is no 91 | recursion on the system stack. Simple quantifiers are specifically 92 | optimized to avoid recursions. 93 | 94 | Infinite recursions coming from quantifiers with empty terms are 95 | avoided. 96 | 97 | The full regexp library weighs about 15 KiB (x86 code), excluding the 98 | Unicode library. 99 | 100 | ### Unicode 101 | 102 | A specific Unicode library was developed so that there is no 103 | dependency on an external large Unicode library such as ICU. All the 104 | Unicode tables are compressed while keeping a reasonable access 105 | speed. 106 | 107 | The library supports case conversion, Unicode normalization, Unicode 108 | script queries, Unicode general category queries and all Unicode 109 | binary properties. 110 | 111 | The full Unicode library weighs about 45 KiB (x86 code). 112 | 113 | ### BigInt 114 | 115 | BigInt is implemented with the [libbf](https://bellard.org/libbf) library. 116 | It weights about 90 KiB (x86 code) and provides arbitrary precision IEEE 754 floating 117 | point operations and transcendental functions with exact rounding. 118 | -------------------------------------------------------------------------------- /docs/docs/developer-guide/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 1 3 | --- 4 | 5 | # The QuickJS C API 6 | 7 | The C API was designed to be simple and efficient. The C API is 8 | defined in the header `quickjs.h`. 9 | 10 | ## Runtime and contexts 11 | 12 | `JSRuntime` represents a JavaScript runtime corresponding to an 13 | object heap. Several runtimes can exist at the same time but they 14 | cannot exchange objects. Inside a given runtime, no multi-threading is 15 | supported. 16 | 17 | `JSContext` represents a JavaScript context (or Realm). Each 18 | JSContext has its own global objects and system objects. There can be 19 | several JSContexts per JSRuntime and they can share objects, similar 20 | to frames of the same origin sharing JavaScript objects in a 21 | web browser. 22 | 23 | ## JSValue 24 | 25 | `JSValue` represents a JavaScript value which can be a primitive 26 | type or an object. Reference counting is used, so it is important to 27 | explicitly duplicate (`JS_DupValue()`, increment the reference 28 | count) or free (`JS_FreeValue()`, decrement the reference count) 29 | JSValues. 30 | 31 | ## C functions 32 | 33 | C functions can be created with 34 | `JS_NewCFunction()`. `JS_SetPropertyFunctionList()` is a 35 | shortcut to easily add functions, setters and getters properties to a 36 | given object. 37 | 38 | Unlike other embedded JavaScript engines, there is no implicit stack, 39 | so C functions get their parameters as normal C parameters. As a 40 | general rule, C functions take constant `JSValue`s as parameters 41 | (so they don't need to free them) and return a newly allocated (=live) 42 | `JSValue`. 43 | 44 | ## Exceptions 45 | 46 | Most C functions can return a JavaScript exception. It 47 | must be explicitly tested and handled by the C code. The specific 48 | `JSValue` `JS_EXCEPTION` indicates that an exception 49 | occurred. The actual exception object is stored in the 50 | `JSContext` and can be retrieved with `JS_GetException()`. 51 | 52 | ## Script evaluation 53 | 54 | Use `JS_Eval()` to evaluate a script or module source. 55 | 56 | If the script or module was compiled to bytecode with `qjsc`, it 57 | can be evaluated by calling `js_std_eval_binary()`. The advantage 58 | is that no compilation is needed so it is faster and smaller because 59 | the compiler can be removed from the executable if no `eval` is 60 | required. 61 | 62 | Note: the bytecode format is linked to a given QuickJS 63 | version. Moreover, no security check is done before its 64 | execution. Hence the bytecode should not be loaded from untrusted 65 | sources. 66 | 67 | ## JS Classes 68 | 69 | C opaque data can be attached to a JavaScript object. The type of the 70 | C opaque data is determined with the class ID (`JSClassID`) of 71 | the object. Hence the first step is to register a new class ID and JS 72 | class (`JS_NewClassID()`, `JS_NewClass()`). Then you can 73 | create objects of this class with `JS_NewObjectClass()` and get or 74 | set the C opaque point with `JS_GetOpaque()` / `JS_SetOpaque()`. 75 | 76 | When defining a new JS class, it is possible to declare a finalizer 77 | which is called when the object is destroyed. The finalizer should be 78 | used to release C resources. It is invalid to execute JS code from 79 | it. A `gc_mark` method can be provided so that the cycle removal 80 | algorithm can find the other objects referenced by this object. Other 81 | methods are available to define exotic object behaviors. 82 | 83 | The Class ID are allocated per-runtime. The 84 | `JSClass` are allocated per `JSRuntime`. `JS_SetClassProto()` 85 | is used to define a prototype for a given class in a given 86 | `JSContext`. `JS_NewObjectClass()` sets this prototype in the 87 | created object. 88 | 89 | Examples are available in `quickjs-libc.c`. 90 | 91 | ## C Modules 92 | 93 | Native ES6 modules are supported and can be dynamically or statically 94 | linked. The standard library `quickjs-libc.c` is a good example 95 | of a native module. 96 | 97 | ## Memory handling 98 | 99 | Use `JS_SetMemoryLimit()` to set a global memory allocation limit 100 | to a given `JSRuntime`. 101 | 102 | Custom memory allocation functions can be provided with `JS_NewRuntime2()`. 103 | 104 | The maximum system stack size can be set with `JS_SetMaxStackSize()`. 105 | 106 | ## Execution timeout and interrupts 107 | 108 | Use `JS_SetInterruptHandler()` to set a callback which is 109 | regularly called by the engine when it is executing code. This 110 | callback can be used to implement an execution timeout. 111 | 112 | It is used by the command line interpreter to implement a 113 | `Ctrl-C` handler. 114 | -------------------------------------------------------------------------------- /docs/docs/diff.md: -------------------------------------------------------------------------------- 1 | # Differences with bellard/quickjs 2 | 3 | This project aims to be a drop-in replacement for those already using QuickJS. 4 | Minimal API changes might be necessary. 5 | 6 | ## Community development 7 | 8 | NG is developed in the open, interacting with the wider community and through 9 | these interactions many improvements have already been made, including the incorporation 10 | of patches previously maintained in other forks. 11 | 12 | Each PR is reviewed, iterated on, and merged in GitHub. 13 | 14 | To date, NG has had over 40 distinct contributors and over 400 PRs. 15 | 16 | ## Consistent release cadence 17 | 18 | As the project moves forward, a steady cadence of releases has been maintained, with an 19 | average of a new release every 2 months. 20 | 21 | ## Testing 22 | 23 | Since its inception testing has been a focus. Each PR is tested in over 50 configurations, 24 | involving different operating systems, build types and sanitizers. 25 | 26 | The `test262` suite is also ran for every change. 27 | 28 | ## Cross-platform support 29 | 30 | In order to better support other platforms such as Windows the build system was 31 | changed to use [CMake]. 32 | 33 | In addition, Windows is treated as a first class citizen, with the addition of support 34 | for the MSVC compiler. 35 | 36 | [CMake]: https://cmake.org/ 37 | 38 | ## Performance 39 | 40 | While being an interpreter limits the performance in comparison with other engines which 41 | use a JIT, several significant performance improvements have been made: 42 | 43 | - Opcode fusion 44 | - Polymorphic inline caching 45 | - Memory allocation improvements 46 | - Improved parse speeds 47 | 48 | ## New ECMAScript APIs 49 | 50 | The main focus of NG is to deliver state-of-the-art JavaScript features. Typically once they 51 | are stable (stage 4) but sometimes even at earlier stages. Here is a non-exhaustive list 52 | of ES features present in NG: 53 | 54 | - Resizable ArrayBuffer 55 | - Float16Array 56 | - WeakRef 57 | - FinalizationRegistry 58 | - Iterator Helpers 59 | - Promise.try 60 | - Error.isError 61 | - Set operations 62 | 63 | Some non-standard but widely used APIs have also been added: 64 | 65 | - V8's [stack trace API](https://v8.dev/docs/stack-trace-api) 66 | - `Error.captureStackTrace` 67 | - `Error.prepareStackTrace` 68 | - `Error.stackTraceLimit` 69 | -------------------------------------------------------------------------------- /docs/docs/es_features.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 7 3 | --- 4 | 5 | # ECMAScript Features 6 | 7 | QuickJS aims to support the latest available ECMAScript features once they hit the spec. 8 | 9 | Progress on _test262_ compliance can be checked [here](https://test262.fyi/#|qjs_ng). 10 | 11 | Due to size constraints it is unlikely QuickJS will ever support the [Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl) APIs. 12 | -------------------------------------------------------------------------------- /docs/docs/installation.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 3 3 | --- 4 | 5 | # Installation 6 | 7 | Installing QuickJS is simple, and we provide several ways to do so. 8 | 9 | 10 | ## Build from source 11 | 12 | If you built it from source as outlined in [building](./building) you can just run: 13 | 14 | ```bash 15 | make install 16 | ``` 17 | 18 | and it will be installed in your system. The default installation path is `/usr/local`. 19 | 20 | 21 | ## Using a prebuilt binary 22 | 23 | Each [release on GitHub] includes binaries for several systems and architectures. 24 | 25 | 26 | ## Using jsvu 27 | 28 | As of version 2.2.0 of `jsvu`, QuickJS-ng will be installed when the `quickjs` engine is requested. 29 | 30 | ```bash 31 | npm install jsvu -g 32 | ``` 33 | 34 | [release on GitHub]: https://github.com/quickjs-ng/quickjs/releases 35 | -------------------------------------------------------------------------------- /docs/docs/intro.md: -------------------------------------------------------------------------------- 1 | --- 2 | slug: / 3 | sidebar_position: 1 4 | sidebar_label: Welcome 5 | --- 6 | 7 | # Welcome to QuickJS-NG 8 | 9 | QuickJS is a small and embeddable JavaScript engine. It aims to support the latest 10 | [ECMAScript] specification. 11 | 12 | This project is a _fork_ of the [original QuickJS project] by Fabrice Bellard and Charlie Gordon, after it went dormant, with the intent of reigniting its development. 13 | 14 | This project is focused on (but not limited to): 15 | 16 | - Community development 17 | - Testing 18 | - Cross-platform support 19 | - ES features 20 | 21 | You can check the differences with the original project [here.](./diff) 22 | 23 | :::note 24 | This site is under construction, the entire API is not yet documented. 25 | ::: 26 | 27 | ## Getting Started 28 | 29 | Head over to [building](./building) if you want to build QuickJS from source or [installation](./installation) 30 | for installing it from prebuilt binaries. 31 | 32 | [ECMAScript]: https://tc39.es/ecma262/ 33 | [original QuickJS project]: https://bellard.org/quickjs 34 | -------------------------------------------------------------------------------- /docs/docs/projects.md: -------------------------------------------------------------------------------- 1 | # Projects using NG 2 | 3 | Here is a list of projects currently using, supporting or migrating to QuickJS-NG. 4 | If you want yours to be listed here, please open a PR! 5 | 6 | ## [txiki.js](https://github.com/saghul/txiki.js) 7 | 8 | A tiny JavaScript runtime. 9 | 10 | ## [radare2](https://github.com/radareorg/radare2) 11 | 12 | Reverse engineering framework. 13 | 14 | ## [rquickjs](https://github.com/DelSkayn/rquickjs) 15 | 16 | High level Rust bindings. 17 | 18 | ## [llrt](https://github.com/awslabs/llrt) 19 | 20 | Lightweight JS runtime for serverless applications. 21 | 22 | ## [nx.js](https://github.com/TooTallNate/nx.js) 23 | 24 | JavaScript runtime for Nintendo Switch homebrew applications. 25 | 26 | ## [quickjs-rusty](https://github.com/Icemic/quickjs-rusty) 27 | 28 | Rust wrapper focus on embedding-ready and no-pain type conversion and interoperability. 29 | -------------------------------------------------------------------------------- /docs/docs/supported_platforms.md: -------------------------------------------------------------------------------- 1 | --- 2 | sidebar_position: 8 3 | --- 4 | 5 | # Supported Platforms 6 | 7 | | System | Supported versions | Notes | 8 | |---|---|---| 9 | | GNU/Linux | * | glibc and musl are supported | 10 | | macOS | macOS >= 11 | Currently supported macOS releases | 11 | | Windows | >= Windows 8 | VS >= 2022 and Clang are supported | 12 | | FreeBSD | * | Limited testing | 13 | | OpenBSD | * | Limited testing | 14 | | NetBSD | * | Limited testing | 15 | | Android | NDK >= 26.0.10792818 | Limited testing | 16 | | iOS | * | Limited testing | 17 | | MinGW | MinGW-w64 | | 18 | | Other | N/A | Missing? Open a PR! | 19 | -------------------------------------------------------------------------------- /docs/docusaurus.config.js: -------------------------------------------------------------------------------- 1 | // @ts-check 2 | // `@type` JSDoc annotations allow editor autocompletion and type checking 3 | // (when paired with `@ts-check`). 4 | // There are various equivalent ways to declare your Docusaurus config. 5 | // See: https://docusaurus.io/docs/api/docusaurus-config 6 | 7 | /** @type {import('@docusaurus/types').Config} */ 8 | const config = { 9 | title: 'QuickJS-NG', 10 | tagline: 'QuickJS, the Next Generation: a mighty JavaScript engine', 11 | favicon: 'img/favicon.ico', 12 | 13 | // Set the production url of your site here 14 | url: 'https://quickjs-ng.github.io', 15 | // Set the // pathname under which your site is served 16 | // For GitHub pages deployment, it is often '//' 17 | baseUrl: '/quickjs/', 18 | 19 | // GitHub pages deployment config. 20 | // If you aren't using GitHub pages, you don't need these. 21 | organizationName: 'quickjs-ng', // Usually your GitHub org/user name. 22 | projectName: 'quickjs', // Usually your repo name. 23 | 24 | onBrokenLinks: 'throw', 25 | onBrokenMarkdownLinks: 'throw', 26 | 27 | // Even if you don't use internationalization, you can use this field to set 28 | // useful metadata like html lang. For example, if your site is Chinese, you 29 | // may want to replace "en" with "zh-Hans". 30 | i18n: { 31 | defaultLocale: 'en', 32 | locales: ['en'], 33 | }, 34 | 35 | presets: [ 36 | [ 37 | 'classic', 38 | /** @type {import('@docusaurus/preset-classic').Options} */ 39 | ({ 40 | docs: { 41 | routeBasePath: '/', 42 | sidebarPath: './sidebars.js', 43 | // Please change this to your repo. 44 | // Remove this to remove the "edit this page" links. 45 | editUrl: 'https://github.com/quickjs-ng/quickjs/tree/master/docs/', 46 | }, 47 | blog: false, 48 | theme: { 49 | customCss: './src/css/custom.css', 50 | }, 51 | }), 52 | ], 53 | ], 54 | 55 | themeConfig: 56 | /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ 57 | ({ 58 | // Replace with your project's social card 59 | image: 'img/docusaurus-social-card.jpg', 60 | navbar: { 61 | title: 'QuickJS-NG', 62 | items: [ 63 | { 64 | type: 'docSidebar', 65 | sidebarId: 'docsSidebar', 66 | position: 'left', 67 | label: 'Documentation', 68 | }, 69 | { 70 | href: 'https://github.com/quickjs-ng/quickjs', 71 | label: 'GitHub', 72 | position: 'right', 73 | }, 74 | ], 75 | }, 76 | footer: { 77 | style: 'dark', 78 | links: [ 79 | { 80 | title: 'Docs', 81 | items: [ 82 | ], 83 | }, 84 | { 85 | title: 'Community', 86 | items: [ 87 | { 88 | label: 'GitHub Discussions', 89 | href: 'https://github.com/quickjs-ng/quickjs/discussions', 90 | }, 91 | { 92 | label: 'Matrix', 93 | href: 'https://matrix.to/#/%23quickjs-ng%3Amatrix.org?via=matrix.org', 94 | }, 95 | ], 96 | }, 97 | { 98 | title: 'More', 99 | items: [ 100 | { 101 | label: 'GitHub', 102 | href: 'https://github.com/quickjs-ng/quickjs', 103 | }, 104 | ], 105 | }, 106 | ], 107 | copyright: `Copyright © ${new Date().getFullYear()} QuickJS-NG project contributors.`, 108 | }, 109 | prism: { 110 | }, 111 | }), 112 | }; 113 | 114 | export default config; 115 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "private": true, 3 | "scripts": { 4 | "docusaurus": "docusaurus", 5 | "start": "docusaurus start", 6 | "build": "docusaurus build", 7 | "swizzle": "docusaurus swizzle", 8 | "deploy": "docusaurus deploy", 9 | "clear": "docusaurus clear", 10 | "serve": "docusaurus serve", 11 | "write-translations": "docusaurus write-translations", 12 | "write-heading-ids": "docusaurus write-heading-ids" 13 | }, 14 | "dependencies": { 15 | "@docusaurus/core": "3.5.2", 16 | "@docusaurus/preset-classic": "3.5.2", 17 | "@mdx-js/react": "3.0.1", 18 | "clsx": "2.1.1", 19 | "prism-react-renderer": "2.4.0", 20 | "react": "18.3.1", 21 | "react-dom": "18.3.1" 22 | }, 23 | "devDependencies": { 24 | "@docusaurus/module-type-aliases": "3.5.2", 25 | "@docusaurus/types": "3.5.2" 26 | }, 27 | "browserslist": { 28 | "production": [ 29 | ">0.5%", 30 | "not dead", 31 | "not op_mini all" 32 | ], 33 | "development": [ 34 | "last 3 chrome version", 35 | "last 3 firefox version", 36 | "last 5 safari version" 37 | ] 38 | }, 39 | "engines": { 40 | "node": ">=18.0" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /docs/sidebars.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Creating a sidebar enables you to: 3 | - create an ordered group of docs 4 | - render a sidebar for each doc of that group 5 | - provide next/previous navigation 6 | 7 | The sidebars can be generated from the filesystem, or explicitly defined here. 8 | 9 | Create as many sidebars as you want. 10 | */ 11 | 12 | // @ts-check 13 | 14 | /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ 15 | const sidebars = { 16 | // By default, Docusaurus generates a sidebar from the docs folder structure 17 | docsSidebar: [{type: 'autogenerated', dirName: '.'}], 18 | }; 19 | 20 | export default sidebars; 21 | -------------------------------------------------------------------------------- /docs/src/css/custom.css: -------------------------------------------------------------------------------- 1 | /** 2 | * Any CSS included here will be global. The classic template 3 | * bundles Infima by default. Infima is a CSS framework designed to 4 | * work well for content-centric websites. 5 | */ 6 | 7 | /* You can override the default Infima variables here. */ 8 | :root { 9 | --ifm-color-primary: #2e8555; 10 | --ifm-color-primary-dark: #29784c; 11 | --ifm-color-primary-darker: #277148; 12 | --ifm-color-primary-darkest: #205d3b; 13 | --ifm-color-primary-light: #33925d; 14 | --ifm-color-primary-lighter: #359962; 15 | --ifm-color-primary-lightest: #3cad6e; 16 | --ifm-code-font-size: 95%; 17 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1); 18 | } 19 | 20 | /* For readability concerns, you should choose a lighter palette in dark mode. */ 21 | [data-theme='dark'] { 22 | --ifm-color-primary: #25c2a0; 23 | --ifm-color-primary-dark: #21af90; 24 | --ifm-color-primary-darker: #1fa588; 25 | --ifm-color-primary-darkest: #1a8870; 26 | --ifm-color-primary-light: #29d5b0; 27 | --ifm-color-primary-lighter: #32d8b4; 28 | --ifm-color-primary-lightest: #4fddbf; 29 | --docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3); 30 | } 31 | -------------------------------------------------------------------------------- /docs/static/.nojekyll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluesky950520/quickjs/d78294aa928eabbc17a7d98eaca87cec3dd4eaa6/docs/static/.nojekyll -------------------------------------------------------------------------------- /docs/static/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bluesky950520/quickjs/d78294aa928eabbc17a7d98eaca87cec3dd4eaa6/docs/static/img/favicon.ico -------------------------------------------------------------------------------- /examples/fib.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS: Example of C module 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include "../quickjs.h" 25 | 26 | #define countof(x) (sizeof(x) / sizeof((x)[0])) 27 | 28 | static int fib(int n) 29 | { 30 | if (n <= 0) 31 | return 0; 32 | else if (n == 1) 33 | return 1; 34 | else 35 | return fib(n - 1) + fib(n - 2); 36 | } 37 | 38 | static JSValue js_fib(JSContext *ctx, JSValue this_val, 39 | int argc, JSValue *argv) 40 | { 41 | int n, res; 42 | if (JS_ToInt32(ctx, &n, argv[0])) 43 | return JS_EXCEPTION; 44 | res = fib(n); 45 | return JS_NewInt32(ctx, res); 46 | } 47 | 48 | static const JSCFunctionListEntry js_fib_funcs[] = { 49 | JS_CFUNC_DEF("fib", 1, js_fib ), 50 | }; 51 | 52 | static int js_fib_init(JSContext *ctx, JSModuleDef *m) 53 | { 54 | return JS_SetModuleExportList(ctx, m, js_fib_funcs, 55 | countof(js_fib_funcs)); 56 | } 57 | 58 | #ifdef JS_SHARED_LIBRARY 59 | #define JS_INIT_MODULE js_init_module 60 | #else 61 | #define JS_INIT_MODULE js_init_module_fib 62 | #endif 63 | 64 | #ifndef JS_EXTERN 65 | #ifdef _WIN32 66 | #define JS_EXTERN __declspec(dllexport) 67 | #else 68 | #define JS_EXTERN 69 | #endif 70 | #endif 71 | 72 | JS_EXTERN JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name) 73 | { 74 | JSModuleDef *m; 75 | m = JS_NewCModule(ctx, module_name, js_fib_init); 76 | if (!m) 77 | return NULL; 78 | JS_AddModuleExportList(ctx, m, js_fib_funcs, countof(js_fib_funcs)); 79 | return m; 80 | } 81 | -------------------------------------------------------------------------------- /examples/fib_module.js: -------------------------------------------------------------------------------- 1 | /* fib module */ 2 | export function fib(n) 3 | { 4 | if (n <= 0) 5 | return 0; 6 | else if (n == 1) 7 | return 1; 8 | else 9 | return fib(n - 1) + fib(n - 2); 10 | } 11 | -------------------------------------------------------------------------------- /examples/hello.js: -------------------------------------------------------------------------------- 1 | console.log("Hello World"); 2 | -------------------------------------------------------------------------------- /examples/hello_module.js: -------------------------------------------------------------------------------- 1 | /* example of JS module */ 2 | 3 | import { fib } from "./fib_module.js"; 4 | 5 | console.log("Hello World"); 6 | console.log("fib(10)=", fib(10)); 7 | -------------------------------------------------------------------------------- /examples/pi_bigint.js: -------------------------------------------------------------------------------- 1 | /* 2 | * PI computation in Javascript using the BigInt type 3 | */ 4 | "use strict"; 5 | 6 | /* return floor(log2(a)) for a > 0 and 0 for a = 0 */ 7 | function floor_log2(a) 8 | { 9 | var k_max, a1, k, i; 10 | k_max = 0n; 11 | while ((a >> (2n ** k_max)) != 0n) { 12 | k_max++; 13 | } 14 | k = 0n; 15 | a1 = a; 16 | for(i = k_max - 1n; i >= 0n; i--) { 17 | a1 = a >> (2n ** i); 18 | if (a1 != 0n) { 19 | a = a1; 20 | k |= (1n << i); 21 | } 22 | } 23 | return k; 24 | } 25 | 26 | /* return ceil(log2(a)) for a > 0 */ 27 | function ceil_log2(a) 28 | { 29 | return floor_log2(a - 1n) + 1n; 30 | } 31 | 32 | /* return floor(sqrt(a)) (not efficient but simple) */ 33 | function int_sqrt(a) 34 | { 35 | var l, u, s; 36 | if (a == 0n) 37 | return a; 38 | l = ceil_log2(a); 39 | u = 1n << ((l + 1n) / 2n); 40 | /* u >= floor(sqrt(a)) */ 41 | for(;;) { 42 | s = u; 43 | u = ((a / s) + s) / 2n; 44 | if (u >= s) 45 | break; 46 | } 47 | return s; 48 | } 49 | 50 | /* return pi * 2**prec */ 51 | function calc_pi(prec) { 52 | const CHUD_A = 13591409n; 53 | const CHUD_B = 545140134n; 54 | const CHUD_C = 640320n; 55 | const CHUD_C3 = 10939058860032000n; /* C^3/24 */ 56 | const CHUD_BITS_PER_TERM = 47.11041313821584202247; /* log2(C/12)*3 */ 57 | 58 | /* return [P, Q, G] */ 59 | function chud_bs(a, b, need_G) { 60 | var c, P, Q, G, P1, Q1, G1, P2, Q2, G2; 61 | if (a == (b - 1n)) { 62 | G = (2n * b - 1n) * (6n * b - 1n) * (6n * b - 5n); 63 | P = G * (CHUD_B * b + CHUD_A); 64 | if (b & 1n) 65 | P = -P; 66 | Q = b * b * b * CHUD_C3; 67 | } else { 68 | c = (a + b) >> 1n; 69 | [P1, Q1, G1] = chud_bs(a, c, true); 70 | [P2, Q2, G2] = chud_bs(c, b, need_G); 71 | P = P1 * Q2 + P2 * G1; 72 | Q = Q1 * Q2; 73 | if (need_G) 74 | G = G1 * G2; 75 | else 76 | G = 0n; 77 | } 78 | return [P, Q, G]; 79 | } 80 | 81 | var n, P, Q, G; 82 | /* number of serie terms */ 83 | n = BigInt(Math.ceil(Number(prec) / CHUD_BITS_PER_TERM)) + 10n; 84 | [P, Q, G] = chud_bs(0n, n, false); 85 | Q = (CHUD_C / 12n) * (Q << prec) / (P + Q * CHUD_A); 86 | G = int_sqrt(CHUD_C << (2n * prec)); 87 | return (Q * G) >> prec; 88 | } 89 | 90 | function main(args) { 91 | var r, n_digits, n_bits, out; 92 | if (args.length < 1) { 93 | print("usage: pi n_digits"); 94 | return; 95 | } 96 | n_digits = args[0] | 0; 97 | 98 | /* we add more bits to reduce the probability of bad rounding for 99 | the last digits */ 100 | n_bits = BigInt(Math.ceil(n_digits * Math.log2(10))) + 32n; 101 | r = calc_pi(n_bits); 102 | r = ((10n ** BigInt(n_digits)) * r) >> n_bits; 103 | out = r.toString(); 104 | print(out[0] + "." + out.slice(1)); 105 | } 106 | 107 | var args; 108 | if (typeof scriptArgs != "undefined") { 109 | args = scriptArgs; 110 | args.shift(); 111 | } else if (typeof arguments != "undefined") { 112 | args = arguments; 113 | } else { 114 | /* default: 1000 digits */ 115 | args=[1000]; 116 | } 117 | 118 | main(args); 119 | -------------------------------------------------------------------------------- /examples/point.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS: Example of C module with a class 3 | * 4 | * Copyright (c) 2019 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include "../quickjs.h" 25 | #include 26 | 27 | #define countof(x) (sizeof(x) / sizeof((x)[0])) 28 | 29 | /* Point Class */ 30 | 31 | typedef struct { 32 | int x; 33 | int y; 34 | } JSPointData; 35 | 36 | static JSClassID js_point_class_id; 37 | 38 | static void js_point_finalizer(JSRuntime *rt, JSValue val) 39 | { 40 | JSPointData *s = JS_GetOpaque(val, js_point_class_id); 41 | /* Note: 's' can be NULL in case JS_SetOpaque() was not called */ 42 | js_free_rt(rt, s); 43 | } 44 | 45 | static JSValue js_point_ctor(JSContext *ctx, 46 | JSValue new_target, 47 | int argc, JSValue *argv) 48 | { 49 | JSPointData *s; 50 | JSValue obj = JS_UNDEFINED; 51 | JSValue proto; 52 | 53 | s = js_mallocz(ctx, sizeof(*s)); 54 | if (!s) 55 | return JS_EXCEPTION; 56 | if (JS_ToInt32(ctx, &s->x, argv[0])) 57 | goto fail; 58 | if (JS_ToInt32(ctx, &s->y, argv[1])) 59 | goto fail; 60 | /* using new_target to get the prototype is necessary when the 61 | class is extended. */ 62 | proto = JS_GetPropertyStr(ctx, new_target, "prototype"); 63 | if (JS_IsException(proto)) 64 | goto fail; 65 | obj = JS_NewObjectProtoClass(ctx, proto, js_point_class_id); 66 | JS_FreeValue(ctx, proto); 67 | if (JS_IsException(obj)) 68 | goto fail; 69 | JS_SetOpaque(obj, s); 70 | return obj; 71 | fail: 72 | js_free(ctx, s); 73 | JS_FreeValue(ctx, obj); 74 | return JS_EXCEPTION; 75 | } 76 | 77 | static JSValue js_point_get_xy(JSContext *ctx, JSValue this_val, int magic) 78 | { 79 | JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id); 80 | if (!s) 81 | return JS_EXCEPTION; 82 | if (magic == 0) 83 | return JS_NewInt32(ctx, s->x); 84 | else 85 | return JS_NewInt32(ctx, s->y); 86 | } 87 | 88 | static JSValue js_point_set_xy(JSContext *ctx, JSValue this_val, JSValue val, int magic) 89 | { 90 | JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id); 91 | int v; 92 | if (!s) 93 | return JS_EXCEPTION; 94 | if (JS_ToInt32(ctx, &v, val)) 95 | return JS_EXCEPTION; 96 | if (magic == 0) 97 | s->x = v; 98 | else 99 | s->y = v; 100 | return JS_UNDEFINED; 101 | } 102 | 103 | static JSValue js_point_norm(JSContext *ctx, JSValue this_val, 104 | int argc, JSValue *argv) 105 | { 106 | JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id); 107 | if (!s) 108 | return JS_EXCEPTION; 109 | return JS_NewFloat64(ctx, sqrt((double)s->x * s->x + (double)s->y * s->y)); 110 | } 111 | 112 | static JSClassDef js_point_class = { 113 | "Point", 114 | .finalizer = js_point_finalizer, 115 | }; 116 | 117 | static const JSCFunctionListEntry js_point_proto_funcs[] = { 118 | JS_CGETSET_MAGIC_DEF("x", js_point_get_xy, js_point_set_xy, 0), 119 | JS_CGETSET_MAGIC_DEF("y", js_point_get_xy, js_point_set_xy, 1), 120 | JS_CFUNC_DEF("norm", 0, js_point_norm), 121 | }; 122 | 123 | static int js_point_init(JSContext *ctx, JSModuleDef *m) 124 | { 125 | JSValue point_proto, point_class; 126 | JSRuntime *rt = JS_GetRuntime(ctx); 127 | 128 | /* create the Point class */ 129 | JS_NewClassID(rt, &js_point_class_id); 130 | JS_NewClass(rt, js_point_class_id, &js_point_class); 131 | 132 | point_proto = JS_NewObject(ctx); 133 | JS_SetPropertyFunctionList(ctx, point_proto, js_point_proto_funcs, countof(js_point_proto_funcs)); 134 | 135 | point_class = JS_NewCFunction2(ctx, js_point_ctor, "Point", 2, JS_CFUNC_constructor, 0); 136 | /* set proto.constructor and ctor.prototype */ 137 | JS_SetConstructor(ctx, point_class, point_proto); 138 | JS_SetClassProto(ctx, js_point_class_id, point_proto); 139 | 140 | JS_SetModuleExport(ctx, m, "Point", point_class); 141 | return 0; 142 | } 143 | 144 | #ifndef JS_EXTERN 145 | #ifdef _WIN32 146 | #define JS_EXTERN __declspec(dllexport) 147 | #else 148 | #define JS_EXTERN 149 | #endif 150 | #endif 151 | 152 | JS_EXTERN JSModuleDef *js_init_module(JSContext *ctx, const char *module_name) 153 | { 154 | JSModuleDef *m; 155 | m = JS_NewCModule(ctx, module_name, js_point_init); 156 | if (!m) 157 | return NULL; 158 | JS_AddModuleExport(ctx, m, "Point"); 159 | return m; 160 | } 161 | -------------------------------------------------------------------------------- /examples/test_fib.js: -------------------------------------------------------------------------------- 1 | /* example of JS module importing a C module */ 2 | import * as os from "qjs:os"; 3 | 4 | const isWin = os.platform === 'win32'; 5 | const { fib } = await import(`./fib.${isWin ? 'dll' : 'so'}`); 6 | 7 | console.log("Hello World"); 8 | console.log("fib(10)=", fib(10)); 9 | -------------------------------------------------------------------------------- /examples/test_point.js: -------------------------------------------------------------------------------- 1 | /* example of JS module importing a C module */ 2 | import * as os from "qjs:os"; 3 | 4 | const isWin = os.platform === 'win32'; 5 | const { Point } = await import(`./point.${isWin ? 'dll' : 'so'}`); 6 | 7 | function assert(b, str) 8 | { 9 | if (b) { 10 | return; 11 | } else { 12 | throw Error("assertion failed: " + str); 13 | } 14 | } 15 | 16 | class ColorPoint extends Point { 17 | constructor(x, y, color) { 18 | super(x, y); 19 | this.color = color; 20 | } 21 | get_color() { 22 | return this.color; 23 | } 24 | }; 25 | 26 | function main() 27 | { 28 | var pt, pt2; 29 | 30 | pt = new Point(2, 3); 31 | assert(pt.x === 2); 32 | assert(pt.y === 3); 33 | pt.x = 4; 34 | assert(pt.x === 4); 35 | assert(pt.norm() == 5); 36 | 37 | pt2 = new ColorPoint(2, 3, 0xffffff); 38 | assert(pt2.x === 2); 39 | assert(pt2.color === 0xffffff); 40 | assert(pt2.get_color() === 0xffffff); 41 | } 42 | 43 | main(); 44 | -------------------------------------------------------------------------------- /fuzz.c: -------------------------------------------------------------------------------- 1 | // clang -g -O1 -fsanitize=fuzzer -o fuzz fuzz.c 2 | #include "quickjs.h" 3 | #include "quickjs.c" 4 | #include "cutils.c" 5 | #include "libbf.c" 6 | #include "libregexp.c" 7 | #include "libunicode.c" 8 | #include 9 | 10 | int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len) 11 | { 12 | JSRuntime *rt = JS_NewRuntime(); 13 | if (!rt) 14 | exit(1); 15 | JSContext *ctx = JS_NewContext(rt); 16 | if (!ctx) 17 | exit(1); 18 | JSValueConst val = JS_ReadObject(ctx, buf, len, /*flags*/0); 19 | JS_FreeValue(ctx, val); 20 | JS_FreeContext(ctx); 21 | JS_FreeRuntime(rt); 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /gen/function_source.c: -------------------------------------------------------------------------------- 1 | /* File generated automatically by the QuickJS-ng compiler. */ 2 | 3 | #include "quickjs-libc.h" 4 | 5 | const uint32_t qjsc_function_source_size = 314; 6 | 7 | const uint8_t qjsc_function_source[314] = { 8 | 0x13, 0x05, 0x01, 0x30, 0x74, 0x65, 0x73, 0x74, 9 | 0x73, 0x2f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 10 | 0x6f, 0x6e, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63, 11 | 0x65, 0x2e, 0x6a, 0x73, 0x01, 0x0c, 0x61, 0x63, 12 | 0x74, 0x75, 0x61, 0x6c, 0x01, 0x02, 0x66, 0x01, 13 | 0x0c, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x01, 14 | 0x34, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 15 | 0x6e, 0x20, 0x66, 0x28, 0x29, 0x20, 0x7b, 0x20, 16 | 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x34, 17 | 0x32, 0x20, 0x7d, 0x0d, 0xc0, 0x03, 0x00, 0x00, 18 | 0x00, 0x00, 0x00, 0x0c, 0x20, 0xfa, 0x01, 0xa2, 19 | 0x01, 0x00, 0x05, 0x00, 0x03, 0x02, 0x01, 0x74, 20 | 0x05, 0xc2, 0x03, 0x02, 0x00, 0x30, 0xc4, 0x03, 21 | 0x04, 0x00, 0x70, 0xc2, 0x03, 0x04, 0x02, 0x70, 22 | 0x10, 0x00, 0x01, 0x00, 0xe4, 0x01, 0x00, 0x01, 23 | 0x00, 0xc6, 0x03, 0x00, 0x0d, 0xc4, 0x03, 0x01, 24 | 0x01, 0x0c, 0x43, 0xfa, 0x01, 0xc4, 0x03, 0x00, 25 | 0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0xbc, 26 | 0x2a, 0x28, 0xc0, 0x03, 0x03, 0x01, 0x00, 0x1a, 27 | 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 28 | 0x20, 0x66, 0x28, 0x29, 0x20, 0x7b, 0x20, 0x72, 29 | 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x34, 0x32, 30 | 0x20, 0x7d, 0x0c, 0x03, 0xc2, 0x04, 0x08, 0xcc, 31 | 0x08, 0xea, 0x05, 0xbf, 0x00, 0xe2, 0x29, 0x04, 32 | 0xe4, 0x00, 0x00, 0x00, 0xe1, 0x61, 0x00, 0x00, 33 | 0xde, 0x42, 0x38, 0x00, 0x00, 0x00, 0x24, 0x00, 34 | 0x00, 0xc9, 0x62, 0x00, 0x00, 0x65, 0x00, 0x00, 35 | 0xaf, 0xea, 0x0b, 0x38, 0x95, 0x00, 0x00, 0x00, 36 | 0x62, 0x00, 0x00, 0xef, 0x2f, 0x61, 0x02, 0x00, 37 | 0x61, 0x01, 0x00, 0x38, 0x3b, 0x00, 0x00, 0x00, 38 | 0x65, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00, 39 | 0x9d, 0x31, 0x01, 0x00, 0x03, 0x00, 0xca, 0x62, 40 | 0x01, 0x00, 0x42, 0x38, 0x00, 0x00, 0x00, 0x24, 41 | 0x00, 0x00, 0xcb, 0x62, 0x02, 0x00, 0x65, 0x00, 42 | 0x00, 0xaf, 0xea, 0x0b, 0x38, 0x95, 0x00, 0x00, 43 | 0x00, 0x62, 0x02, 0x00, 0xef, 0x2f, 0x68, 0x02, 44 | 0x00, 0x68, 0x01, 0x00, 0x06, 0x2e, 0xc0, 0x03, 45 | 0x01, 0x01, 0x0e, 0x00, 0x1c, 0x0a, 0x2a, 0x5d, 46 | 0x18, 0x00, 0x10, 0x08, 0x25, 0x76, 0x0e, 0x5d, 47 | 0x18, 0x00, 48 | }; 49 | 50 | static JSContext *JS_NewCustomContext(JSRuntime *rt) 51 | { 52 | JSContext *ctx = JS_NewContext(rt); 53 | if (!ctx) 54 | return NULL; 55 | return ctx; 56 | } 57 | 58 | int main(int argc, char **argv) 59 | { 60 | int r; 61 | JSValue ret; 62 | JSRuntime *rt; 63 | JSContext *ctx; 64 | r = 0; 65 | rt = JS_NewRuntime(); 66 | js_std_set_worker_new_context_func(JS_NewCustomContext); 67 | js_std_init_handlers(rt); 68 | JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL); 69 | ctx = JS_NewCustomContext(rt); 70 | js_std_add_helpers(ctx, argc, argv); 71 | js_std_eval_binary(ctx, qjsc_function_source, qjsc_function_source_size, 0); 72 | ret = js_std_loop(ctx); 73 | if (JS_IsException(ret)) { 74 | js_std_dump_error1(ctx, ret); 75 | r = 1; 76 | } 77 | JS_FreeValue(ctx, ret); 78 | JS_FreeContext(ctx); 79 | js_std_free_handlers(rt); 80 | JS_FreeRuntime(rt); 81 | return r; 82 | } 83 | -------------------------------------------------------------------------------- /gen/hello.c: -------------------------------------------------------------------------------- 1 | /* File generated automatically by the QuickJS-ng compiler. */ 2 | 3 | #include "quickjs-libc.h" 4 | 5 | const uint32_t qjsc_hello_size = 103; 6 | 7 | const uint8_t qjsc_hello[103] = { 8 | 0x13, 0x04, 0x01, 0x22, 0x65, 0x78, 0x61, 0x6d, 9 | 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x68, 0x65, 0x6c, 10 | 0x6c, 0x6f, 0x2e, 0x6a, 0x73, 0x01, 0x0e, 0x63, 11 | 0x6f, 0x6e, 0x73, 0x6f, 0x6c, 0x65, 0x01, 0x06, 12 | 0x6c, 0x6f, 0x67, 0x01, 0x16, 0x48, 0x65, 0x6c, 13 | 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 14 | 0x0d, 0xc0, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 15 | 0x0c, 0x20, 0xfa, 0x01, 0xa2, 0x01, 0x00, 0x00, 16 | 0x00, 0x03, 0x00, 0x00, 0x19, 0x00, 0x08, 0xea, 17 | 0x02, 0x29, 0x38, 0xe1, 0x00, 0x00, 0x00, 0x42, 18 | 0xe2, 0x00, 0x00, 0x00, 0x04, 0xe3, 0x00, 0x00, 19 | 0x00, 0x24, 0x01, 0x00, 0x0e, 0x06, 0x2e, 0xc0, 20 | 0x03, 0x01, 0x01, 0x02, 0x48, 0x0e, 0x00, 21 | }; 22 | 23 | static JSContext *JS_NewCustomContext(JSRuntime *rt) 24 | { 25 | JSContext *ctx = JS_NewContext(rt); 26 | if (!ctx) 27 | return NULL; 28 | return ctx; 29 | } 30 | 31 | int main(int argc, char **argv) 32 | { 33 | int r; 34 | JSValue ret; 35 | JSRuntime *rt; 36 | JSContext *ctx; 37 | r = 0; 38 | rt = JS_NewRuntime(); 39 | js_std_set_worker_new_context_func(JS_NewCustomContext); 40 | js_std_init_handlers(rt); 41 | JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL); 42 | ctx = JS_NewCustomContext(rt); 43 | js_std_add_helpers(ctx, argc, argv); 44 | js_std_eval_binary(ctx, qjsc_hello, qjsc_hello_size, 0); 45 | ret = js_std_loop(ctx); 46 | if (JS_IsException(ret)) { 47 | js_std_dump_error1(ctx, ret); 48 | r = 1; 49 | } 50 | JS_FreeValue(ctx, ret); 51 | JS_FreeContext(ctx); 52 | js_std_free_handlers(rt); 53 | JS_FreeRuntime(rt); 54 | return r; 55 | } 56 | -------------------------------------------------------------------------------- /gen/hello_module.c: -------------------------------------------------------------------------------- 1 | /* File generated automatically by the QuickJS-ng compiler. */ 2 | 3 | #include "quickjs-libc.h" 4 | 5 | const uint32_t qjsc_fib_module_size = 282; 6 | 7 | const uint8_t qjsc_fib_module[282] = { 8 | 0x13, 0x03, 0x01, 0x2c, 0x65, 0x78, 0x61, 0x6d, 9 | 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x66, 0x69, 0x62, 10 | 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 11 | 0x6a, 0x73, 0x01, 0x06, 0x66, 0x69, 0x62, 0x01, 12 | 0x02, 0x6e, 0x0d, 0xc0, 0x03, 0x00, 0x01, 0x00, 13 | 0x00, 0xc2, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x20, 14 | 0xfa, 0x01, 0xa2, 0x01, 0x00, 0x00, 0x00, 0x01, 15 | 0x01, 0x01, 0x09, 0x00, 0xc2, 0x03, 0x00, 0x01, 16 | 0x0c, 0x43, 0xfa, 0x01, 0xc2, 0x03, 0x01, 0x00, 17 | 0x01, 0x04, 0x01, 0x00, 0x1a, 0x01, 0xc4, 0x03, 18 | 0x00, 0x01, 0x00, 0xc2, 0x03, 0x00, 0x00, 0xd1, 19 | 0xb4, 0xa7, 0xea, 0x03, 0xb4, 0x28, 0xd1, 0xb5, 20 | 0xac, 0xea, 0x03, 0xb5, 0x28, 0xdd, 0xd1, 0xb5, 21 | 0x9e, 0xef, 0xdd, 0xd1, 0xb6, 0x9e, 0xef, 0x9d, 22 | 0x28, 0xc0, 0x03, 0x02, 0x08, 0x06, 0x00, 0x0f, 23 | 0x0e, 0x10, 0x1b, 0x1a, 0x8d, 0x01, 0x66, 0x75, 24 | 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66, 25 | 0x69, 0x62, 0x28, 0x6e, 0x29, 0x0a, 0x7b, 0x0a, 26 | 0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28, 27 | 0x6e, 0x20, 0x3c, 0x3d, 0x20, 0x30, 0x29, 0x0a, 28 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 29 | 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30, 30 | 0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 31 | 0x73, 0x65, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6e, 32 | 0x20, 0x3d, 0x3d, 0x20, 0x31, 0x29, 0x0a, 0x20, 33 | 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72, 34 | 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x3b, 35 | 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73, 36 | 0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 37 | 0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 38 | 0x20, 0x66, 0x69, 0x62, 0x28, 0x6e, 0x20, 0x2d, 39 | 0x20, 0x31, 0x29, 0x20, 0x2b, 0x20, 0x66, 0x69, 40 | 0x62, 0x28, 0x6e, 0x20, 0x2d, 0x20, 0x32, 0x29, 41 | 0x3b, 0x0a, 0x7d, 0x08, 0xea, 0x05, 0xbf, 0x00, 42 | 0xe1, 0x29, 0x06, 0x2e, 0xc0, 0x03, 0x01, 0x01, 43 | 0x00, 0x00, 44 | }; 45 | 46 | const uint32_t qjsc_hello_module_size = 183; 47 | 48 | const uint8_t qjsc_hello_module[183] = { 49 | 0x13, 0x07, 0x01, 0x30, 0x65, 0x78, 0x61, 0x6d, 50 | 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x68, 0x65, 0x6c, 51 | 0x6c, 0x6f, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 52 | 0x65, 0x2e, 0x6a, 0x73, 0x01, 0x1e, 0x2e, 0x2f, 53 | 0x66, 0x69, 0x62, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 54 | 0x6c, 0x65, 0x2e, 0x6a, 0x73, 0x01, 0x06, 0x66, 55 | 0x69, 0x62, 0x01, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 56 | 0x6f, 0x6c, 0x65, 0x01, 0x06, 0x6c, 0x6f, 0x67, 57 | 0x01, 0x16, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 58 | 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x01, 0x10, 0x66, 59 | 0x69, 0x62, 0x28, 0x31, 0x30, 0x29, 0x3d, 0x0d, 60 | 0xc0, 0x03, 0x01, 0xc2, 0x03, 0x00, 0x00, 0x01, 61 | 0x00, 0xc4, 0x03, 0x00, 0x00, 0x0c, 0x20, 0xfa, 62 | 0x01, 0xa2, 0x01, 0x00, 0x00, 0x00, 0x05, 0x01, 63 | 0x00, 0x32, 0x00, 0xc4, 0x03, 0x00, 0x0c, 0x08, 64 | 0xea, 0x02, 0x29, 0x38, 0xe3, 0x00, 0x00, 0x00, 65 | 0x42, 0xe4, 0x00, 0x00, 0x00, 0x04, 0xe5, 0x00, 66 | 0x00, 0x00, 0x24, 0x01, 0x00, 0x0e, 0x38, 0xe3, 67 | 0x00, 0x00, 0x00, 0x42, 0xe4, 0x00, 0x00, 0x00, 68 | 0x04, 0xe6, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 69 | 0xbc, 0x0a, 0xef, 0x24, 0x02, 0x00, 0x0e, 0x06, 70 | 0x2e, 0xc0, 0x03, 0x01, 0x01, 0x08, 0x18, 0x28, 71 | 0x36, 0x17, 0x62, 0x00, 0x2a, 0x20, 0x00, 72 | }; 73 | 74 | static JSContext *JS_NewCustomContext(JSRuntime *rt) 75 | { 76 | JSContext *ctx = JS_NewContext(rt); 77 | if (!ctx) 78 | return NULL; 79 | js_std_eval_binary(ctx, qjsc_fib_module, qjsc_fib_module_size, 1); 80 | return ctx; 81 | } 82 | 83 | int main(int argc, char **argv) 84 | { 85 | int r; 86 | JSValue ret; 87 | JSRuntime *rt; 88 | JSContext *ctx; 89 | r = 0; 90 | rt = JS_NewRuntime(); 91 | js_std_set_worker_new_context_func(JS_NewCustomContext); 92 | js_std_init_handlers(rt); 93 | JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL); 94 | ctx = JS_NewCustomContext(rt); 95 | js_std_add_helpers(ctx, argc, argv); 96 | js_std_eval_binary(ctx, qjsc_hello_module, qjsc_hello_module_size, 0); 97 | ret = js_std_loop(ctx); 98 | if (JS_IsException(ret)) { 99 | js_std_dump_error1(ctx, ret); 100 | r = 1; 101 | } 102 | JS_FreeValue(ctx, ret); 103 | JS_FreeContext(ctx); 104 | js_std_free_handlers(rt); 105 | JS_FreeRuntime(rt); 106 | return r; 107 | } 108 | -------------------------------------------------------------------------------- /gen/standalone.c: -------------------------------------------------------------------------------- 1 | /* File generated automatically by the QuickJS-ng compiler. */ 2 | 3 | #include 4 | 5 | const uint32_t qjsc_standalone_size = 2466; 6 | 7 | const uint8_t qjsc_standalone[2466] = { 8 | 0x13, 0x4d, 0x01, 0x1a, 0x73, 0x74, 0x61, 0x6e, 9 | 0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x2e, 0x6a, 10 | 0x73, 0x01, 0x0e, 0x71, 0x6a, 0x73, 0x3a, 0x73, 11 | 0x74, 0x64, 0x01, 0x0c, 0x71, 0x6a, 0x73, 0x3a, 12 | 0x6f, 0x73, 0x01, 0x12, 0x71, 0x6a, 0x73, 0x3a, 13 | 0x62, 0x6a, 0x73, 0x6f, 0x6e, 0x01, 0x22, 0x63, 14 | 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x53, 0x74, 15 | 0x61, 0x6e, 0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 16 | 0x01, 0x1a, 0x72, 0x75, 0x6e, 0x53, 0x74, 0x61, 17 | 0x6e, 0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x01, 18 | 0x06, 0x73, 0x74, 0x64, 0x01, 0x04, 0x6f, 0x73, 19 | 0x01, 0x0a, 0x62, 0x6a, 0x73, 0x6f, 0x6e, 0x01, 20 | 0x28, 0x4a, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 21 | 0x5f, 0x4f, 0x42, 0x4a, 0x5f, 0x42, 0x59, 0x54, 22 | 0x45, 0x43, 0x4f, 0x44, 0x45, 0x01, 0x2a, 0x4a, 23 | 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 24 | 0x42, 0x4a, 0x5f, 0x52, 0x45, 0x46, 0x45, 0x52, 25 | 0x45, 0x4e, 0x43, 0x45, 0x01, 0x2a, 0x4a, 0x53, 26 | 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4f, 27 | 0x42, 0x4a, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x43, 28 | 0x4f, 0x44, 0x45, 0x01, 0x2c, 0x4a, 0x53, 0x5f, 29 | 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4f, 0x42, 30 | 0x4a, 0x5f, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45, 31 | 0x4e, 0x43, 0x45, 0x01, 0x32, 0x4a, 0x53, 0x5f, 32 | 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4f, 0x42, 33 | 0x4a, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x50, 0x5f, 34 | 0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x01, 0x0e, 35 | 0x54, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x01, 36 | 0x16, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x41, 37 | 0x73, 0x63, 0x69, 0x69, 0x01, 0x16, 0x64, 0x65, 38 | 0x63, 0x6f, 0x64, 0x65, 0x41, 0x73, 0x63, 0x69, 39 | 0x69, 0x01, 0x06, 0x74, 0x78, 0x74, 0x01, 0x02, 40 | 0x63, 0x01, 0x14, 0x63, 0x68, 0x61, 0x72, 0x43, 41 | 0x6f, 0x64, 0x65, 0x41, 0x74, 0x01, 0x06, 0x6d, 42 | 0x61, 0x70, 0x01, 0x06, 0x62, 0x75, 0x66, 0x01, 43 | 0x18, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61, 44 | 0x72, 0x43, 0x6f, 0x64, 0x65, 0x01, 0x0c, 0x69, 45 | 0x6e, 0x46, 0x69, 0x6c, 0x65, 0x01, 0x0e, 0x6f, 46 | 0x75, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x01, 0x12, 47 | 0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x45, 0x78, 48 | 0x65, 0x01, 0x04, 0x6a, 0x73, 0x01, 0x08, 0x63, 49 | 0x6f, 0x64, 0x65, 0x01, 0x10, 0x62, 0x79, 0x74, 50 | 0x65, 0x63, 0x6f, 0x64, 0x65, 0x01, 0x16, 0x65, 51 | 0x78, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x61, 52 | 0x6d, 0x65, 0x01, 0x06, 0x65, 0x78, 0x65, 0x01, 53 | 0x0e, 0x65, 0x78, 0x65, 0x53, 0x69, 0x7a, 0x65, 54 | 0x01, 0x12, 0x6e, 0x65, 0x77, 0x42, 0x75, 0x66, 55 | 0x66, 0x65, 0x72, 0x01, 0x0c, 0x6e, 0x65, 0x77, 56 | 0x45, 0x78, 0x65, 0x01, 0x04, 0x64, 0x77, 0x01, 57 | 0x0a, 0x6e, 0x65, 0x77, 0x46, 0x64, 0x01, 0x10, 58 | 0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65, 59 | 0x01, 0x1e, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 60 | 0x20, 0x74, 0x6f, 0x20, 0x6f, 0x70, 0x65, 0x6e, 61 | 0x20, 0x01, 0x14, 0x65, 0x76, 0x61, 0x6c, 0x53, 62 | 0x63, 0x72, 0x69, 0x70, 0x74, 0x01, 0x18, 0x63, 63 | 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x5f, 0x6f, 64 | 0x6e, 0x6c, 0x79, 0x01, 0x1c, 0x63, 0x6f, 0x6d, 65 | 0x70, 0x69, 0x6c, 0x65, 0x5f, 0x6d, 0x6f, 0x64, 66 | 0x75, 0x6c, 0x65, 0x01, 0x0a, 0x77, 0x72, 0x69, 67 | 0x74, 0x65, 0x01, 0x0a, 0x61, 0x72, 0x67, 0x76, 68 | 0x30, 0x01, 0x0c, 0x62, 0x69, 0x6e, 0x61, 0x72, 69 | 0x79, 0x01, 0x36, 0x66, 0x61, 0x69, 0x6c, 0x65, 70 | 0x64, 0x20, 0x74, 0x6f, 0x20, 0x6f, 0x70, 0x65, 71 | 0x6e, 0x20, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 72 | 0x61, 0x62, 0x6c, 0x65, 0x3a, 0x20, 0x01, 0x0c, 73 | 0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x01, 0x10, 74 | 0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72, 75 | 0x01, 0x08, 0x53, 0x69, 0x7a, 0x65, 0x01, 0x0a, 76 | 0x4d, 0x61, 0x67, 0x69, 0x63, 0x01, 0x12, 0x4d, 77 | 0x61, 0x67, 0x69, 0x63, 0x53, 0x69, 0x7a, 0x65, 78 | 0x01, 0x10, 0x44, 0x61, 0x74, 0x61, 0x53, 0x69, 79 | 0x7a, 0x65, 0x01, 0x12, 0x73, 0x65, 0x74, 0x55, 80 | 0x69, 0x6e, 0x74, 0x33, 0x32, 0x01, 0x08, 0x6f, 81 | 0x70, 0x65, 0x6e, 0x01, 0x10, 0x4f, 0x5f, 0x57, 82 | 0x52, 0x4f, 0x4e, 0x4c, 0x59, 0x01, 0x0e, 0x4f, 83 | 0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x01, 0x0e, 84 | 0x4f, 0x5f, 0x54, 0x52, 0x55, 0x4e, 0x43, 0x01, 85 | 0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 86 | 0x74, 0x6f, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 87 | 0x65, 0x20, 0x01, 0x14, 0x62, 0x79, 0x74, 0x65, 88 | 0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x01, 0x0a, 89 | 0x63, 0x6c, 0x6f, 0x73, 0x65, 0x01, 0x3c, 0x66, 90 | 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f, 91 | 0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x74, 92 | 0x6f, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 93 | 0x20, 0x66, 0x69, 0x6c, 0x65, 0x01, 0x08, 0x66, 94 | 0x69, 0x6c, 0x65, 0x01, 0x02, 0x72, 0x01, 0x0e, 95 | 0x74, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x01, 96 | 0x0a, 0x6d, 0x61, 0x67, 0x69, 0x63, 0x01, 0x0c, 97 | 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x01, 0x04, 98 | 0x72, 0x62, 0x01, 0x08, 0x73, 0x65, 0x65, 0x6b, 99 | 0x01, 0x10, 0x53, 0x45, 0x45, 0x4b, 0x5f, 0x45, 100 | 0x4e, 0x44, 0x01, 0x18, 0x73, 0x65, 0x65, 0x6b, 101 | 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x20, 102 | 0x01, 0x08, 0x72, 0x65, 0x61, 0x64, 0x01, 0x40, 103 | 0x63, 0x6f, 0x72, 0x72, 0x75, 0x70, 0x74, 0x65, 104 | 0x64, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79, 105 | 0x2c, 0x20, 0x6d, 0x61, 0x67, 0x69, 0x63, 0x20, 106 | 0x6d, 0x69, 0x73, 0x6d, 0x61, 0x74, 0x63, 0x68, 107 | 0x01, 0x12, 0x67, 0x65, 0x74, 0x55, 0x69, 0x6e, 108 | 0x74, 0x33, 0x32, 0x01, 0x10, 0x53, 0x45, 0x45, 109 | 0x4b, 0x5f, 0x53, 0x45, 0x54, 0x01, 0x0a, 0x65, 110 | 0x72, 0x72, 0x6f, 0x72, 0x01, 0x14, 0x72, 0x65, 111 | 0x61, 0x64, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 112 | 0x01, 0x16, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x6d, 113 | 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x01, 0x10, 0x71, 114 | 0x75, 0x69, 0x63, 0x6b, 0x6a, 0x73, 0x32, 0x0d, 115 | 0xc0, 0x03, 0x03, 0xc2, 0x03, 0xc4, 0x03, 0xc6, 116 | 0x03, 0x02, 0x00, 0x0b, 0xc8, 0x03, 0x00, 0x0c, 117 | 0xca, 0x03, 0x00, 0x03, 0x00, 0xfc, 0x01, 0x00, 118 | 0x01, 0xfc, 0x01, 0x01, 0x02, 0xfc, 0x01, 0x02, 119 | 0x00, 0x0c, 0x20, 0x02, 0x01, 0xa2, 0x01, 0x00, 120 | 0x00, 0x00, 0x02, 0x0d, 0x04, 0x58, 0x00, 0xcc, 121 | 0x03, 0x00, 0x0d, 0xce, 0x03, 0x01, 0x0d, 0xd0, 122 | 0x03, 0x02, 0x0d, 0xd2, 0x03, 0x00, 0x0d, 0xd4, 123 | 0x03, 0x01, 0x0d, 0xd6, 0x03, 0x02, 0x0d, 0xd8, 124 | 0x03, 0x03, 0x0d, 0xda, 0x03, 0x04, 0x0d, 0xdc, 125 | 0x03, 0x05, 0x0d, 0xde, 0x03, 0x06, 0x01, 0xe0, 126 | 0x03, 0x07, 0x01, 0xc8, 0x03, 0x08, 0x01, 0xca, 127 | 0x03, 0x09, 0x01, 0x0c, 0x43, 0x02, 0x01, 0xde, 128 | 0x03, 0x01, 0x00, 0x01, 0x05, 0x00, 0x01, 0x1e, 129 | 0x01, 0xe2, 0x03, 0x00, 0x01, 0x00, 0x0c, 0x42, 130 | 0x02, 0x01, 0x00, 0x01, 0x00, 0x01, 0x03, 0x00, 131 | 0x00, 0x0a, 0x01, 0xe4, 0x03, 0x00, 0x01, 0x00, 132 | 0xd1, 0x42, 0xf3, 0x00, 0x00, 0x00, 0xb4, 0x25, 133 | 0x01, 0x00, 0x38, 0xa6, 0x00, 0x00, 0x00, 0x11, 134 | 0xd1, 0x42, 0x5e, 0x00, 0x00, 0x00, 0xc0, 0x24, 135 | 0x01, 0x00, 0x42, 0xf4, 0x00, 0x00, 0x00, 0xbf, 136 | 0x00, 0x24, 0x01, 0x00, 0x21, 0x01, 0x00, 0x28, 137 | 0x0c, 0x43, 0x02, 0x01, 0xe0, 0x03, 0x01, 0x00, 138 | 0x01, 0x03, 0x00, 0x01, 0x21, 0x01, 0xea, 0x03, 139 | 0x00, 0x01, 0x00, 0x0c, 0x42, 0x02, 0x01, 0x00, 140 | 0x01, 0x00, 0x01, 0x03, 0x00, 0x00, 0x0e, 0x01, 141 | 0xe4, 0x03, 0x00, 0x01, 0x00, 0x38, 0x97, 0x00, 142 | 0x00, 0x00, 0x42, 0xf6, 0x00, 0x00, 0x00, 0xd1, 143 | 0x25, 0x01, 0x00, 0x38, 0x94, 0x00, 0x00, 0x00, 144 | 0x42, 0x7b, 0x00, 0x00, 0x00, 0xd1, 0x24, 0x01, 145 | 0x00, 0x42, 0xf4, 0x00, 0x00, 0x00, 0xbf, 0x00, 146 | 0x24, 0x01, 0x00, 0x42, 0x5c, 0x00, 0x00, 0x00, 147 | 0xc0, 0x25, 0x01, 0x00, 0x0c, 0x43, 0x02, 0x01, 148 | 0xc8, 0x03, 0x03, 0x0a, 0x03, 0x07, 0x08, 0x00, 149 | 0x86, 0x04, 0x0d, 0xee, 0x03, 0x00, 0x01, 0x00, 150 | 0xf0, 0x03, 0x00, 0x01, 0x00, 0xf2, 0x03, 0x00, 151 | 0x01, 0x00, 0xf4, 0x03, 0x01, 0x00, 0x30, 0xf6, 152 | 0x03, 0x01, 0x01, 0x30, 0xf8, 0x03, 0x01, 0x02, 153 | 0x30, 0xfa, 0x03, 0x01, 0x03, 0x30, 0xfc, 0x03, 154 | 0x01, 0x04, 0x30, 0xfe, 0x03, 0x01, 0x05, 0x30, 155 | 0x80, 0x04, 0x01, 0x06, 0x30, 0x82, 0x04, 0x01, 156 | 0x07, 0x30, 0x84, 0x04, 0x01, 0x08, 0x30, 0x86, 157 | 0x04, 0x01, 0x09, 0x30, 0xcc, 0x03, 0x00, 0x0c, 158 | 0xd0, 0x03, 0x02, 0x0c, 0xd6, 0x03, 0x05, 0x0c, 159 | 0xd8, 0x03, 0x06, 0x0c, 0xda, 0x03, 0x07, 0x0c, 160 | 0xdc, 0x03, 0x08, 0x0c, 0xde, 0x03, 0x09, 0x00, 161 | 0xce, 0x03, 0x01, 0x0c, 0x61, 0x09, 0x00, 0x61, 162 | 0x08, 0x00, 0x61, 0x07, 0x00, 0x61, 0x06, 0x00, 163 | 0x61, 0x05, 0x00, 0x61, 0x04, 0x00, 0x61, 0x03, 164 | 0x00, 0x61, 0x02, 0x00, 0x61, 0x01, 0x00, 0x61, 165 | 0x00, 0x00, 0x65, 0x00, 0x00, 0x42, 0x04, 0x01, 166 | 0x00, 0x00, 0xd1, 0x24, 0x01, 0x00, 0xc9, 0x62, 167 | 0x00, 0x00, 0x96, 0xea, 0x19, 0x38, 0x95, 0x00, 168 | 0x00, 0x00, 0x11, 0x04, 0x05, 0x01, 0x00, 0x00, 169 | 0x42, 0x5d, 0x00, 0x00, 0x00, 0xd1, 0x24, 0x01, 170 | 0x00, 0x21, 0x01, 0x00, 0x2f, 0x65, 0x00, 0x00, 171 | 0x42, 0x06, 0x01, 0x00, 0x00, 0x62, 0x00, 0x00, 172 | 0x0b, 0x0a, 0x4c, 0x07, 0x01, 0x00, 0x00, 0x0a, 173 | 0x4c, 0x08, 0x01, 0x00, 0x00, 0x24, 0x02, 0x00, 174 | 0xca, 0x38, 0xa6, 0x00, 0x00, 0x00, 0x11, 0x65, 175 | 0x01, 0x00, 0x42, 0x09, 0x01, 0x00, 0x00, 0x62, 176 | 0x01, 0x00, 0x65, 0x02, 0x00, 0x65, 0x03, 0x00, 177 | 0xa4, 0x65, 0x04, 0x00, 0xa4, 0x24, 0x02, 0x00, 178 | 0x21, 0x01, 0x00, 0xcb, 0xd3, 0x11, 0xb0, 0xea, 179 | 0x0c, 0x0e, 0x38, 0x8c, 0x00, 0x00, 0x00, 0x41, 180 | 0x0a, 0x01, 0x00, 0x00, 0xcc, 0x65, 0x00, 0x00, 181 | 0x42, 0x04, 0x01, 0x00, 0x00, 0x62, 0x03, 0x00, 182 | 0x0b, 0x0a, 0x4c, 0x0b, 0x01, 0x00, 0x00, 0x24, 183 | 0x02, 0x00, 0xc2, 0x04, 0x62, 0x04, 0x00, 0x96, 184 | 0xea, 0x1b, 0x38, 0x95, 0x00, 0x00, 0x00, 0x11, 185 | 0x04, 0x0c, 0x01, 0x00, 0x00, 0x42, 0x5d, 0x00, 186 | 0x00, 0x00, 0x62, 0x03, 0x00, 0x24, 0x01, 0x00, 187 | 0x21, 0x01, 0x00, 0x2f, 0x62, 0x04, 0x00, 0xe9, 188 | 0xc2, 0x05, 0x62, 0x04, 0x00, 0x41, 0x0d, 0x01, 189 | 0x00, 0x00, 0x42, 0x0e, 0x01, 0x00, 0x00, 0x62, 190 | 0x05, 0x00, 0x62, 0x02, 0x00, 0xe9, 0x9d, 0x65, 191 | 0x05, 0x00, 0x41, 0x0f, 0x01, 0x00, 0x00, 0x9d, 192 | 0x24, 0x01, 0x00, 0xc2, 0x06, 0x38, 0xa6, 0x00, 193 | 0x00, 0x00, 0x11, 0x62, 0x06, 0x00, 0x21, 0x01, 194 | 0x00, 0xc2, 0x07, 0x62, 0x07, 0x00, 0x42, 0x43, 195 | 0x00, 0x00, 0x00, 0x62, 0x02, 0x00, 0x62, 0x05, 196 | 0x00, 0x24, 0x02, 0x00, 0x0e, 0x62, 0x07, 0x00, 197 | 0x42, 0x43, 0x00, 0x00, 0x00, 0x5e, 0x06, 0x00, 198 | 0x65, 0x05, 0x00, 0x41, 0x10, 0x01, 0x00, 0x00, 199 | 0xef, 0x62, 0x05, 0x00, 0x62, 0x02, 0x00, 0xe9, 200 | 0x9d, 0x24, 0x02, 0x00, 0x0e, 0x38, 0xb0, 0x00, 201 | 0x00, 0x00, 0x11, 0x62, 0x06, 0x00, 0x62, 0x05, 202 | 0x00, 0x62, 0x02, 0x00, 0xe9, 0x9d, 0x65, 0x05, 203 | 0x00, 0x41, 0x11, 0x01, 0x00, 0x00, 0x9d, 0x65, 204 | 0x05, 0x00, 0x41, 0x12, 0x01, 0x00, 0x00, 0x21, 205 | 0x03, 0x00, 0xc2, 0x08, 0x62, 0x08, 0x00, 0x42, 206 | 0x13, 0x01, 0x00, 0x00, 0xb4, 0x62, 0x05, 0x00, 207 | 0x0a, 0x24, 0x03, 0x00, 0x0e, 0x65, 0x07, 0x00, 208 | 0x42, 0x14, 0x01, 0x00, 0x00, 0xd2, 0x65, 0x07, 209 | 0x00, 0x41, 0x15, 0x01, 0x00, 0x00, 0x65, 0x07, 210 | 0x00, 0x41, 0x16, 0x01, 0x00, 0x00, 0xa4, 0x65, 211 | 0x07, 0x00, 0x41, 0x17, 0x01, 0x00, 0x00, 0xa4, 212 | 0xbd, 0xed, 0x01, 0x24, 0x03, 0x00, 0xc2, 0x09, 213 | 0x62, 0x09, 0x00, 0xb4, 0xa6, 0xea, 0x19, 0x38, 214 | 0x95, 0x00, 0x00, 0x00, 0x11, 0x04, 0x18, 0x01, 215 | 0x00, 0x00, 0x42, 0x5d, 0x00, 0x00, 0x00, 0xd2, 216 | 0x24, 0x01, 0x00, 0x21, 0x01, 0x00, 0x2f, 0x65, 217 | 0x07, 0x00, 0x42, 0x09, 0x01, 0x00, 0x00, 0x62, 218 | 0x09, 0x00, 0x62, 0x06, 0x00, 0xb4, 0x62, 0x06, 219 | 0x00, 0x41, 0x19, 0x01, 0x00, 0x00, 0x24, 0x04, 220 | 0x00, 0xb4, 0xa6, 0xea, 0x1f, 0x65, 0x07, 0x00, 221 | 0x42, 0x1a, 0x01, 0x00, 0x00, 0x62, 0x09, 0x00, 222 | 0x24, 0x01, 0x00, 0x0e, 0x38, 0x95, 0x00, 0x00, 223 | 0x00, 0x11, 0x04, 0x1b, 0x01, 0x00, 0x00, 0x21, 224 | 0x01, 0x00, 0x2f, 0x65, 0x07, 0x00, 0x42, 0x1a, 225 | 0x01, 0x00, 0x00, 0x62, 0x09, 0x00, 0x24, 0x01, 226 | 0x00, 0x29, 0x0c, 0x43, 0x02, 0x01, 0xca, 0x03, 227 | 0x00, 0x09, 0x00, 0x07, 0x06, 0x00, 0xa4, 0x04, 228 | 0x09, 0xb8, 0x04, 0x01, 0x00, 0x30, 0xfc, 0x03, 229 | 0x01, 0x01, 0x30, 0xba, 0x04, 0x01, 0x02, 0x20, 230 | 0xbc, 0x04, 0x01, 0x03, 0x30, 0xbe, 0x04, 0x01, 231 | 0x04, 0x30, 0x84, 0x04, 0x01, 0x05, 0x30, 0xc0, 232 | 0x04, 0x01, 0x06, 0x30, 0xf8, 0x03, 0x01, 0x07, 233 | 0x30, 0xf6, 0x03, 0x01, 0x08, 0x30, 0xcc, 0x03, 234 | 0x00, 0x0c, 0xdc, 0x03, 0x08, 0x0c, 0xe0, 0x03, 235 | 0x0a, 0x00, 0xd0, 0x03, 0x02, 0x0c, 0xd2, 0x03, 236 | 0x03, 0x0c, 0xd4, 0x03, 0x04, 0x0c, 0x61, 0x08, 237 | 0x00, 0x61, 0x07, 0x00, 0x61, 0x06, 0x00, 0x61, 238 | 0x05, 0x00, 0x61, 0x04, 0x00, 0x61, 0x03, 0x00, 239 | 0x61, 0x02, 0x00, 0x61, 0x01, 0x00, 0x61, 0x00, 240 | 0x00, 0x38, 0x8c, 0x00, 0x00, 0x00, 0x41, 0x0a, 241 | 0x01, 0x00, 0x00, 0xc9, 0x65, 0x00, 0x00, 0x42, 242 | 0x14, 0x01, 0x00, 0x00, 0x62, 0x00, 0x00, 0x04, 243 | 0x21, 0x01, 0x00, 0x00, 0x24, 0x02, 0x00, 0xca, 244 | 0x62, 0x01, 0x00, 0x96, 0xea, 0x1b, 0x38, 0x95, 245 | 0x00, 0x00, 0x00, 0x11, 0x04, 0x0c, 0x01, 0x00, 246 | 0x00, 0x42, 0x5d, 0x00, 0x00, 0x00, 0x62, 0x00, 247 | 0x00, 0x24, 0x01, 0x00, 0x21, 0x01, 0x00, 0x2f, 248 | 0x62, 0x01, 0x00, 0x42, 0x22, 0x01, 0x00, 0x00, 249 | 0x65, 0x01, 0x00, 0x41, 0x0f, 0x01, 0x00, 0x00, 250 | 0x8c, 0x65, 0x00, 0x00, 0x41, 0x23, 0x01, 0x00, 251 | 0x00, 0x24, 0x02, 0x00, 0xcb, 0x62, 0x02, 0x00, 252 | 0xb4, 0xa6, 0xea, 0x1c, 0x38, 0x95, 0x00, 0x00, 253 | 0x00, 0x11, 0x04, 0x24, 0x01, 0x00, 0x00, 0x42, 254 | 0x5d, 0x00, 0x00, 0x00, 0x62, 0x02, 0x00, 0x8c, 255 | 0x24, 0x01, 0x00, 0x21, 0x01, 0x00, 0x2f, 0x38, 256 | 0xa6, 0x00, 0x00, 0x00, 0x11, 0x65, 0x01, 0x00, 257 | 0x41, 0x0f, 0x01, 0x00, 0x00, 0x21, 0x01, 0x00, 258 | 0xcc, 0x62, 0x01, 0x00, 0x42, 0x25, 0x01, 0x00, 259 | 0x00, 0x62, 0x03, 0x00, 0x41, 0x0d, 0x01, 0x00, 260 | 0x00, 0xb4, 0x65, 0x01, 0x00, 0x41, 0x0f, 0x01, 261 | 0x00, 0x00, 0x24, 0x03, 0x00, 0x0e, 0x38, 0xa6, 262 | 0x00, 0x00, 0x00, 0x11, 0x62, 0x03, 0x00, 0x41, 263 | 0x0d, 0x01, 0x00, 0x00, 0xb4, 0x65, 0x01, 0x00, 264 | 0x41, 0x11, 0x01, 0x00, 0x00, 0x21, 0x03, 0x00, 265 | 0xc2, 0x04, 0xdf, 0x62, 0x04, 0x00, 0xef, 0x65, 266 | 0x01, 0x00, 0x41, 0x10, 0x01, 0x00, 0x00, 0xaf, 267 | 0xea, 0x1c, 0x62, 0x01, 0x00, 0x42, 0x1a, 0x01, 268 | 0x00, 0x00, 0x24, 0x00, 0x00, 0x0e, 0x38, 0x95, 269 | 0x00, 0x00, 0x00, 0x11, 0x04, 0x26, 0x01, 0x00, 270 | 0x00, 0x21, 0x01, 0x00, 0x2f, 0x38, 0xb0, 0x00, 271 | 0x00, 0x00, 0x11, 0x62, 0x03, 0x00, 0x41, 0x0d, 272 | 0x01, 0x00, 0x00, 0x65, 0x01, 0x00, 0x41, 0x11, 273 | 0x01, 0x00, 0x00, 0x65, 0x01, 0x00, 0x41, 0x12, 274 | 0x01, 0x00, 0x00, 0x21, 0x03, 0x00, 0xc2, 0x05, 275 | 0x62, 0x05, 0x00, 0x42, 0x27, 0x01, 0x00, 0x00, 276 | 0xb4, 0x0a, 0x24, 0x02, 0x00, 0xc2, 0x06, 0x38, 277 | 0xa6, 0x00, 0x00, 0x00, 0x11, 0x62, 0x06, 0x00, 278 | 0x65, 0x01, 0x00, 0x41, 0x0f, 0x01, 0x00, 0x00, 279 | 0x9e, 0x21, 0x01, 0x00, 0xc2, 0x07, 0x62, 0x01, 280 | 0x00, 0x42, 0x22, 0x01, 0x00, 0x00, 0x62, 0x06, 281 | 0x00, 0x65, 0x00, 0x00, 0x41, 0x28, 0x01, 0x00, 282 | 0x00, 0x24, 0x02, 0x00, 0x11, 0x63, 0x02, 0x00, 283 | 0x0e, 0x62, 0x02, 0x00, 0xb4, 0xa6, 0xea, 0x28, 284 | 0x62, 0x01, 0x00, 0x42, 0x1a, 0x01, 0x00, 0x00, 285 | 0x24, 0x00, 0x00, 0x0e, 0x38, 0x95, 0x00, 0x00, 286 | 0x00, 0x11, 0x04, 0x24, 0x01, 0x00, 0x00, 0x42, 287 | 0x5d, 0x00, 0x00, 0x00, 0x62, 0x02, 0x00, 0x8c, 288 | 0x24, 0x01, 0x00, 0x21, 0x01, 0x00, 0x2f, 0x62, 289 | 0x01, 0x00, 0x42, 0x25, 0x01, 0x00, 0x00, 0x62, 290 | 0x07, 0x00, 0x41, 0x0d, 0x01, 0x00, 0x00, 0xb4, 291 | 0x62, 0x07, 0x00, 0xe9, 0x24, 0x03, 0x00, 0x0e, 292 | 0x62, 0x01, 0x00, 0x42, 0x29, 0x01, 0x00, 0x00, 293 | 0x24, 0x00, 0x00, 0xea, 0x1c, 0x62, 0x01, 0x00, 294 | 0x42, 0x1a, 0x01, 0x00, 0x00, 0x24, 0x00, 0x00, 295 | 0x0e, 0x38, 0x95, 0x00, 0x00, 0x00, 0x11, 0x04, 296 | 0x2a, 0x01, 0x00, 0x00, 0x21, 0x01, 0x00, 0x2f, 297 | 0x62, 0x01, 0x00, 0x42, 0x1a, 0x01, 0x00, 0x00, 298 | 0x24, 0x00, 0x00, 0x0e, 0x65, 0x03, 0x00, 0x42, 299 | 0x25, 0x01, 0x00, 0x00, 0x62, 0x07, 0x00, 0x41, 300 | 0x0d, 0x01, 0x00, 0x00, 0xb4, 0x62, 0x07, 0x00, 301 | 0xe9, 0x65, 0x04, 0x00, 0x65, 0x05, 0x00, 0xa4, 302 | 0x24, 0x04, 0x00, 0xc2, 0x08, 0x65, 0x00, 0x00, 303 | 0x42, 0x06, 0x01, 0x00, 0x00, 0x62, 0x08, 0x00, 304 | 0x0b, 0x0a, 0x4c, 0x2b, 0x01, 0x00, 0x00, 0x25, 305 | 0x02, 0x00, 0x08, 0xea, 0x16, 0xbf, 0x00, 0x5f, 306 | 0x09, 0x00, 0xbf, 0x01, 0x5f, 0x0a, 0x00, 0xbf, 307 | 0x02, 0x5f, 0x0b, 0x00, 0xbf, 0x03, 0x5f, 0x0c, 308 | 0x00, 0x29, 0xb5, 0xb4, 0x9f, 0xe4, 0xb5, 0xb7, 309 | 0x9f, 0x5f, 0x04, 0x00, 0xb5, 0xb4, 0x9f, 0x5f, 310 | 0x05, 0x00, 0xb5, 0xb7, 0x9f, 0x5f, 0x06, 0x00, 311 | 0xb5, 0xb8, 0x9f, 0x5f, 0x07, 0x00, 0x0b, 0x04, 312 | 0x2c, 0x01, 0x00, 0x00, 0x4c, 0x10, 0x01, 0x00, 313 | 0x00, 0xbc, 0x08, 0x4c, 0x11, 0x01, 0x00, 0x00, 314 | 0xb8, 0x4c, 0x12, 0x01, 0x00, 0x00, 0xbc, 0x0c, 315 | 0x4c, 0x0f, 0x01, 0x00, 0x00, 0x5f, 0x08, 0x00, 316 | 0x06, 0x2e, 317 | }; 318 | 319 | -------------------------------------------------------------------------------- /gen/test_fib.c: -------------------------------------------------------------------------------- 1 | /* File generated automatically by the QuickJS-ng compiler. */ 2 | 3 | #include "quickjs-libc.h" 4 | 5 | const uint32_t qjsc_test_fib_size = 290; 6 | 7 | const uint8_t qjsc_test_fib[290] = { 8 | 0x13, 0x0e, 0x01, 0x28, 0x65, 0x78, 0x61, 0x6d, 9 | 0x70, 0x6c, 0x65, 0x73, 0x2f, 0x74, 0x65, 0x73, 10 | 0x74, 0x5f, 0x66, 0x69, 0x62, 0x2e, 0x6a, 0x73, 11 | 0x01, 0x0c, 0x71, 0x6a, 0x73, 0x3a, 0x6f, 0x73, 12 | 0x01, 0x04, 0x6f, 0x73, 0x01, 0x0a, 0x69, 0x73, 13 | 0x57, 0x69, 0x6e, 0x01, 0x06, 0x66, 0x69, 0x62, 14 | 0x01, 0x10, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f, 15 | 0x72, 0x6d, 0x01, 0x0a, 0x77, 0x69, 0x6e, 0x33, 16 | 0x32, 0x01, 0x0c, 0x2e, 0x2f, 0x66, 0x69, 0x62, 17 | 0x2e, 0x01, 0x06, 0x64, 0x6c, 0x6c, 0x01, 0x04, 18 | 0x73, 0x6f, 0x01, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 19 | 0x6f, 0x6c, 0x65, 0x01, 0x06, 0x6c, 0x6f, 0x67, 20 | 0x01, 0x16, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 21 | 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x01, 0x10, 0x66, 22 | 0x69, 0x62, 0x28, 0x31, 0x30, 0x29, 0x3d, 0x0d, 23 | 0xc0, 0x03, 0x01, 0xc2, 0x03, 0x00, 0x00, 0x01, 24 | 0x00, 0xfc, 0x01, 0x00, 0x01, 0x0c, 0x20, 0xfa, 25 | 0x01, 0xa2, 0x01, 0x00, 0x00, 0x00, 0x05, 0x03, 26 | 0x00, 0x73, 0x00, 0xc4, 0x03, 0x00, 0x0d, 0xc6, 27 | 0x03, 0x00, 0x0d, 0xc8, 0x03, 0x01, 0x0d, 0x08, 28 | 0xea, 0x02, 0x29, 0x65, 0x00, 0x00, 0x41, 0xe5, 29 | 0x00, 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00, 30 | 0xae, 0xe2, 0x06, 0x11, 0xf2, 0xeb, 0x0b, 0x70, 31 | 0x42, 0xe4, 0x00, 0x00, 0x00, 0xe3, 0x0e, 0xec, 32 | 0x24, 0x0e, 0x04, 0xe7, 0x00, 0x00, 0x00, 0x42, 33 | 0x5d, 0x00, 0x00, 0x00, 0x65, 0x01, 0x00, 0xea, 34 | 0x08, 0x04, 0xe8, 0x00, 0x00, 0x00, 0xec, 0x06, 35 | 0x04, 0xe9, 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, 36 | 0x35, 0x8b, 0xec, 0xd4, 0x38, 0xea, 0x00, 0x00, 37 | 0x00, 0x42, 0xeb, 0x00, 0x00, 0x00, 0x04, 0xec, 38 | 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, 0x0e, 0x38, 39 | 0xea, 0x00, 0x00, 0x00, 0x42, 0xeb, 0x00, 0x00, 40 | 0x00, 0x04, 0xed, 0x00, 0x00, 0x00, 0x65, 0x02, 41 | 0x00, 0xbc, 0x0a, 0xef, 0x24, 0x02, 0x00, 0x0e, 42 | 0x06, 0x2e, 0xc0, 0x03, 0x01, 0x01, 0x0a, 0x00, 43 | 0x45, 0x08, 0x6c, 0x36, 0x5b, 0x62, 0x00, 0x2a, 44 | 0x20, 0x00, 45 | }; 46 | 47 | static JSContext *JS_NewCustomContext(JSRuntime *rt) 48 | { 49 | JSContext *ctx = JS_NewContext(rt); 50 | if (!ctx) 51 | return NULL; 52 | { 53 | extern JSModuleDef *js_init_module_os(JSContext *ctx, const char *name); 54 | js_init_module_os(ctx, "qjs:os"); 55 | } 56 | return ctx; 57 | } 58 | 59 | int main(int argc, char **argv) 60 | { 61 | int r; 62 | JSValue ret; 63 | JSRuntime *rt; 64 | JSContext *ctx; 65 | r = 0; 66 | rt = JS_NewRuntime(); 67 | js_std_set_worker_new_context_func(JS_NewCustomContext); 68 | js_std_init_handlers(rt); 69 | JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL); 70 | ctx = JS_NewCustomContext(rt); 71 | js_std_add_helpers(ctx, argc, argv); 72 | js_std_eval_binary(ctx, qjsc_test_fib, qjsc_test_fib_size, 0); 73 | ret = js_std_loop(ctx); 74 | if (JS_IsException(ret)) { 75 | js_std_dump_error1(ctx, ret); 76 | r = 1; 77 | } 78 | JS_FreeValue(ctx, ret); 79 | JS_FreeContext(ctx); 80 | js_std_free_handlers(rt); 81 | JS_FreeRuntime(rt); 82 | return r; 83 | } 84 | -------------------------------------------------------------------------------- /libregexp-opcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Regular Expression Engine 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #ifdef DEF 26 | 27 | DEF(invalid, 1) /* never used */ 28 | DEF(char8, 2) /* 7 bits in fact */ 29 | DEF(char16, 3) 30 | DEF(char32, 5) 31 | DEF(dot, 1) 32 | DEF(any, 1) /* same as dot but match any character including line terminator */ 33 | DEF(line_start, 1) 34 | DEF(line_end, 1) 35 | DEF(goto, 5) 36 | DEF(split_goto_first, 5) 37 | DEF(split_next_first, 5) 38 | DEF(match, 1) 39 | DEF(save_start, 2) /* save start position */ 40 | DEF(save_end, 2) /* save end position, must come after saved_start */ 41 | DEF(save_reset, 3) /* reset save positions */ 42 | DEF(loop, 5) /* decrement the top the stack and goto if != 0 */ 43 | DEF(push_i32, 5) /* push integer on the stack */ 44 | DEF(drop, 1) 45 | DEF(word_boundary, 1) 46 | DEF(not_word_boundary, 1) 47 | DEF(back_reference, 2) 48 | DEF(backward_back_reference, 2) /* must come after back_reference */ 49 | DEF(range, 3) /* variable length */ 50 | DEF(range32, 3) /* variable length */ 51 | DEF(lookahead, 5) 52 | DEF(negative_lookahead, 5) 53 | DEF(push_char_pos, 1) /* push the character position on the stack */ 54 | DEF(check_advance, 1) /* pop one stack element and check that it is different from the character position */ 55 | DEF(prev, 1) /* go to the previous char */ 56 | DEF(simple_greedy_quant, 17) 57 | 58 | #endif /* DEF */ 59 | -------------------------------------------------------------------------------- /libregexp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Regular Expression Engine 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIBREGEXP_H 25 | #define LIBREGEXP_H 26 | 27 | #include 28 | 29 | #include "libunicode.h" 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | #define LRE_BOOL int /* for documentation purposes */ 36 | 37 | #define LRE_FLAG_GLOBAL (1 << 0) 38 | #define LRE_FLAG_IGNORECASE (1 << 1) 39 | #define LRE_FLAG_MULTILINE (1 << 2) 40 | #define LRE_FLAG_DOTALL (1 << 3) 41 | #define LRE_FLAG_UNICODE (1 << 4) 42 | #define LRE_FLAG_STICKY (1 << 5) 43 | #define LRE_FLAG_INDICES (1 << 6) /* Unused by libregexp, just recorded. */ 44 | #define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */ 45 | #define LRE_FLAG_UNICODE_SETS (1 << 8) 46 | 47 | uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size, 48 | const char *buf, size_t buf_len, int re_flags, 49 | void *opaque); 50 | int lre_get_capture_count(const uint8_t *bc_buf); 51 | int lre_get_flags(const uint8_t *bc_buf); 52 | const char *lre_get_groupnames(const uint8_t *bc_buf); 53 | int lre_exec(uint8_t **capture, 54 | const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen, 55 | int cbuf_type, void *opaque); 56 | 57 | int lre_parse_escape(const uint8_t **pp, int allow_utf16); 58 | LRE_BOOL lre_is_space(int c); 59 | 60 | void lre_byte_swap(uint8_t *buf, size_t len, LRE_BOOL is_byte_swapped); 61 | 62 | /* must be provided by the user */ 63 | LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size); 64 | void *lre_realloc(void *opaque, void *ptr, size_t size); 65 | 66 | /* JS identifier test */ 67 | extern uint32_t const lre_id_start_table_ascii[4]; 68 | extern uint32_t const lre_id_continue_table_ascii[4]; 69 | 70 | static inline int lre_js_is_ident_first(int c) 71 | { 72 | if ((uint32_t)c < 128) { 73 | return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1; 74 | } else { 75 | return lre_is_id_start(c); 76 | } 77 | } 78 | 79 | static inline int lre_js_is_ident_next(int c) 80 | { 81 | if ((uint32_t)c < 128) { 82 | return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1; 83 | } else { 84 | /* ZWNJ and ZWJ are accepted in identifiers */ 85 | return lre_is_id_continue(c) || c == 0x200C || c == 0x200D; 86 | } 87 | } 88 | 89 | #undef LRE_BOOL 90 | 91 | #ifdef __cplusplus 92 | } /* extern "C" { */ 93 | #endif 94 | 95 | #endif /* LIBREGEXP_H */ 96 | -------------------------------------------------------------------------------- /libunicode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Unicode utilities 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIBUNICODE_H 25 | #define LIBUNICODE_H 26 | 27 | #include 28 | #include 29 | 30 | #ifdef __cplusplus 31 | extern "C" { 32 | #endif 33 | 34 | #define LRE_BOOL int /* for documentation purposes */ 35 | 36 | #define LRE_CC_RES_LEN_MAX 3 37 | 38 | typedef enum { 39 | UNICODE_NFC, 40 | UNICODE_NFD, 41 | UNICODE_NFKC, 42 | UNICODE_NFKD, 43 | } UnicodeNormalizationEnum; 44 | 45 | int lre_case_conv(uint32_t *res, uint32_t c, int conv_type); 46 | int lre_canonicalize(uint32_t c, BOOL is_unicode); 47 | LRE_BOOL lre_is_cased(uint32_t c); 48 | LRE_BOOL lre_is_case_ignorable(uint32_t c); 49 | 50 | /* char ranges */ 51 | 52 | typedef struct { 53 | int len; /* in points, always even */ 54 | int size; 55 | uint32_t *points; /* points sorted by increasing value */ 56 | void *mem_opaque; 57 | void *(*realloc_func)(void *opaque, void *ptr, size_t size); 58 | } CharRange; 59 | 60 | typedef enum { 61 | CR_OP_UNION, 62 | CR_OP_INTER, 63 | CR_OP_XOR, 64 | } CharRangeOpEnum; 65 | 66 | void cr_init(CharRange *cr, void *mem_opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); 67 | void cr_free(CharRange *cr); 68 | int cr_realloc(CharRange *cr, int size); 69 | int cr_copy(CharRange *cr, const CharRange *cr1); 70 | 71 | static inline int cr_add_point(CharRange *cr, uint32_t v) 72 | { 73 | if (cr->len >= cr->size) { 74 | if (cr_realloc(cr, cr->len + 1)) 75 | return -1; 76 | } 77 | cr->points[cr->len++] = v; 78 | return 0; 79 | } 80 | 81 | static inline int cr_add_interval(CharRange *cr, uint32_t c1, uint32_t c2) 82 | { 83 | if ((cr->len + 2) > cr->size) { 84 | if (cr_realloc(cr, cr->len + 2)) 85 | return -1; 86 | } 87 | cr->points[cr->len++] = c1; 88 | cr->points[cr->len++] = c2; 89 | return 0; 90 | } 91 | 92 | int cr_union1(CharRange *cr, const uint32_t *b_pt, int b_len); 93 | 94 | static inline int cr_union_interval(CharRange *cr, uint32_t c1, uint32_t c2) 95 | { 96 | uint32_t b_pt[2]; 97 | b_pt[0] = c1; 98 | b_pt[1] = c2 + 1; 99 | return cr_union1(cr, b_pt, 2); 100 | } 101 | 102 | int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len, 103 | const uint32_t *b_pt, int b_len, int op); 104 | 105 | int cr_invert(CharRange *cr); 106 | int cr_regexp_canonicalize(CharRange *cr, BOOL is_unicode); 107 | 108 | LRE_BOOL lre_is_id_start(uint32_t c); 109 | LRE_BOOL lre_is_id_continue(uint32_t c); 110 | LRE_BOOL lre_is_white_space(uint32_t c); 111 | 112 | int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, 113 | UnicodeNormalizationEnum n_type, 114 | void *opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); 115 | 116 | /* Unicode character range functions */ 117 | 118 | int unicode_script(CharRange *cr, 119 | const char *script_name, LRE_BOOL is_ext); 120 | int unicode_general_category(CharRange *cr, const char *gc_name); 121 | int unicode_prop(CharRange *cr, const char *prop_name); 122 | 123 | #undef LRE_BOOL 124 | 125 | #ifdef __cplusplus 126 | } /* extern "C" { */ 127 | #endif 128 | 129 | #endif /* LIBUNICODE_H */ 130 | -------------------------------------------------------------------------------- /list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Linux klist like system 3 | * 4 | * Copyright (c) 2016-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIST_H 25 | #define LIST_H 26 | 27 | #ifndef NULL 28 | #include 29 | #endif 30 | 31 | #ifdef __cplusplus 32 | extern "C" { 33 | #endif 34 | 35 | struct list_head { 36 | struct list_head *prev; 37 | struct list_head *next; 38 | }; 39 | 40 | #define LIST_HEAD_INIT(el) { &(el), &(el) } 41 | 42 | /* return the pointer of type 'type *' containing 'el' as field 'member' */ 43 | #define list_entry(el, type, member) container_of(el, type, member) 44 | 45 | static inline void init_list_head(struct list_head *head) 46 | { 47 | head->prev = head; 48 | head->next = head; 49 | } 50 | 51 | /* insert 'el' between 'prev' and 'next' */ 52 | static inline void __list_add(struct list_head *el, 53 | struct list_head *prev, struct list_head *next) 54 | { 55 | prev->next = el; 56 | el->prev = prev; 57 | el->next = next; 58 | next->prev = el; 59 | } 60 | 61 | /* add 'el' at the head of the list 'head' (= after element head) */ 62 | static inline void list_add(struct list_head *el, struct list_head *head) 63 | { 64 | __list_add(el, head, head->next); 65 | } 66 | 67 | /* add 'el' at the end of the list 'head' (= before element head) */ 68 | static inline void list_add_tail(struct list_head *el, struct list_head *head) 69 | { 70 | __list_add(el, head->prev, head); 71 | } 72 | 73 | static inline void list_del(struct list_head *el) 74 | { 75 | struct list_head *prev, *next; 76 | prev = el->prev; 77 | next = el->next; 78 | prev->next = next; 79 | next->prev = prev; 80 | el->prev = NULL; /* fail safe */ 81 | el->next = NULL; /* fail safe */ 82 | } 83 | 84 | static inline int list_empty(struct list_head *el) 85 | { 86 | return el->next == el; 87 | } 88 | 89 | #define list_for_each(el, head) \ 90 | for(el = (head)->next; el != (head); el = el->next) 91 | 92 | #define list_for_each_safe(el, el1, head) \ 93 | for(el = (head)->next, el1 = el->next; el != (head); \ 94 | el = el1, el1 = el->next) 95 | 96 | #define list_for_each_prev(el, head) \ 97 | for(el = (head)->prev; el != (head); el = el->prev) 98 | 99 | #define list_for_each_prev_safe(el, el1, head) \ 100 | for(el = (head)->prev, el1 = el->prev; el != (head); \ 101 | el = el1, el1 = el->prev) 102 | 103 | #ifdef __cplusplus 104 | } /* extern "C" { */ 105 | #endif 106 | 107 | #endif /* LIST_H */ 108 | -------------------------------------------------------------------------------- /quickjs-atom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS atom definitions 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * Copyright (c) 2017-2018 Charlie Gordon 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | #ifdef DEF 27 | 28 | /* Note: first atoms are considered as keywords in the parser */ 29 | DEF(null, "null") /* must be first */ 30 | DEF(false, "false") 31 | DEF(true, "true") 32 | DEF(if, "if") 33 | DEF(else, "else") 34 | DEF(return, "return") 35 | DEF(var, "var") 36 | DEF(this, "this") 37 | DEF(delete, "delete") 38 | DEF(void, "void") 39 | DEF(typeof, "typeof") 40 | DEF(new, "new") 41 | DEF(in, "in") 42 | DEF(instanceof, "instanceof") 43 | DEF(do, "do") 44 | DEF(while, "while") 45 | DEF(for, "for") 46 | DEF(break, "break") 47 | DEF(continue, "continue") 48 | DEF(switch, "switch") 49 | DEF(case, "case") 50 | DEF(default, "default") 51 | DEF(throw, "throw") 52 | DEF(try, "try") 53 | DEF(catch, "catch") 54 | DEF(finally, "finally") 55 | DEF(function, "function") 56 | DEF(debugger, "debugger") 57 | DEF(with, "with") 58 | /* FutureReservedWord */ 59 | DEF(class, "class") 60 | DEF(const, "const") 61 | DEF(enum, "enum") 62 | DEF(export, "export") 63 | DEF(extends, "extends") 64 | DEF(import, "import") 65 | DEF(super, "super") 66 | /* FutureReservedWords when parsing strict mode code */ 67 | DEF(implements, "implements") 68 | DEF(interface, "interface") 69 | DEF(let, "let") 70 | DEF(package, "package") 71 | DEF(private, "private") 72 | DEF(protected, "protected") 73 | DEF(public, "public") 74 | DEF(static, "static") 75 | DEF(yield, "yield") 76 | DEF(await, "await") 77 | 78 | /* empty string */ 79 | DEF(empty_string, "") 80 | /* identifiers */ 81 | DEF(keys, "keys") 82 | DEF(size, "size") 83 | DEF(length, "length") 84 | DEF(message, "message") 85 | DEF(cause, "cause") 86 | DEF(errors, "errors") 87 | DEF(stack, "stack") 88 | DEF(name, "name") 89 | DEF(toString, "toString") 90 | DEF(toLocaleString, "toLocaleString") 91 | DEF(valueOf, "valueOf") 92 | DEF(eval, "eval") 93 | DEF(prototype, "prototype") 94 | DEF(constructor, "constructor") 95 | DEF(configurable, "configurable") 96 | DEF(writable, "writable") 97 | DEF(enumerable, "enumerable") 98 | DEF(value, "value") 99 | DEF(get, "get") 100 | DEF(set, "set") 101 | DEF(of, "of") 102 | DEF(__proto__, "__proto__") 103 | DEF(undefined, "undefined") 104 | DEF(number, "number") 105 | DEF(boolean, "boolean") 106 | DEF(string, "string") 107 | DEF(object, "object") 108 | DEF(symbol, "symbol") 109 | DEF(integer, "integer") 110 | DEF(unknown, "unknown") 111 | DEF(arguments, "arguments") 112 | DEF(callee, "callee") 113 | DEF(caller, "caller") 114 | DEF(_eval_, "") 115 | DEF(_ret_, "") 116 | DEF(_var_, "") 117 | DEF(_arg_var_, "") 118 | DEF(_with_, "") 119 | DEF(lastIndex, "lastIndex") 120 | DEF(target, "target") 121 | DEF(index, "index") 122 | DEF(input, "input") 123 | DEF(defineProperties, "defineProperties") 124 | DEF(apply, "apply") 125 | DEF(join, "join") 126 | DEF(concat, "concat") 127 | DEF(split, "split") 128 | DEF(construct, "construct") 129 | DEF(getPrototypeOf, "getPrototypeOf") 130 | DEF(setPrototypeOf, "setPrototypeOf") 131 | DEF(isExtensible, "isExtensible") 132 | DEF(preventExtensions, "preventExtensions") 133 | DEF(has, "has") 134 | DEF(deleteProperty, "deleteProperty") 135 | DEF(defineProperty, "defineProperty") 136 | DEF(getOwnPropertyDescriptor, "getOwnPropertyDescriptor") 137 | DEF(ownKeys, "ownKeys") 138 | DEF(add, "add") 139 | DEF(done, "done") 140 | DEF(next, "next") 141 | DEF(values, "values") 142 | DEF(source, "source") 143 | DEF(flags, "flags") 144 | DEF(global, "global") 145 | DEF(unicode, "unicode") 146 | DEF(raw, "raw") 147 | DEF(new_target, "new.target") 148 | DEF(this_active_func, "this.active_func") 149 | DEF(home_object, "") 150 | DEF(computed_field, "") 151 | DEF(static_computed_field, "") /* must come after computed_fields */ 152 | DEF(class_fields_init, "") 153 | DEF(brand, "") 154 | DEF(hash_constructor, "#constructor") 155 | DEF(as, "as") 156 | DEF(from, "from") 157 | DEF(meta, "meta") 158 | DEF(_default_, "*default*") 159 | DEF(_star_, "*") 160 | DEF(Module, "Module") 161 | DEF(then, "then") 162 | DEF(resolve, "resolve") 163 | DEF(reject, "reject") 164 | DEF(promise, "promise") 165 | DEF(proxy, "proxy") 166 | DEF(revoke, "revoke") 167 | DEF(async, "async") 168 | DEF(exec, "exec") 169 | DEF(groups, "groups") 170 | DEF(indices, "indices") 171 | DEF(status, "status") 172 | DEF(reason, "reason") 173 | DEF(globalThis, "globalThis") 174 | DEF(bigint, "bigint") 175 | DEF(not_equal, "not-equal") 176 | DEF(timed_out, "timed-out") 177 | DEF(ok, "ok") 178 | DEF(toJSON, "toJSON") 179 | DEF(maxByteLength, "maxByteLength") 180 | /* class names */ 181 | DEF(Object, "Object") 182 | DEF(Array, "Array") 183 | DEF(Error, "Error") 184 | DEF(Number, "Number") 185 | DEF(String, "String") 186 | DEF(Boolean, "Boolean") 187 | DEF(Symbol, "Symbol") 188 | DEF(Arguments, "Arguments") 189 | DEF(Math, "Math") 190 | DEF(JSON, "JSON") 191 | DEF(Date, "Date") 192 | DEF(Function, "Function") 193 | DEF(GeneratorFunction, "GeneratorFunction") 194 | DEF(ForInIterator, "ForInIterator") 195 | DEF(RegExp, "RegExp") 196 | DEF(ArrayBuffer, "ArrayBuffer") 197 | DEF(SharedArrayBuffer, "SharedArrayBuffer") 198 | /* must keep same order as class IDs for typed arrays */ 199 | DEF(Uint8ClampedArray, "Uint8ClampedArray") 200 | DEF(Int8Array, "Int8Array") 201 | DEF(Uint8Array, "Uint8Array") 202 | DEF(Int16Array, "Int16Array") 203 | DEF(Uint16Array, "Uint16Array") 204 | DEF(Int32Array, "Int32Array") 205 | DEF(Uint32Array, "Uint32Array") 206 | DEF(BigInt64Array, "BigInt64Array") 207 | DEF(BigUint64Array, "BigUint64Array") 208 | DEF(Float16Array, "Float16Array") 209 | DEF(Float32Array, "Float32Array") 210 | DEF(Float64Array, "Float64Array") 211 | DEF(DataView, "DataView") 212 | DEF(BigInt, "BigInt") 213 | DEF(WeakRef, "WeakRef") 214 | DEF(FinalizationRegistry, "FinalizationRegistry") 215 | DEF(Map, "Map") 216 | DEF(Set, "Set") /* Map + 1 */ 217 | DEF(WeakMap, "WeakMap") /* Map + 2 */ 218 | DEF(WeakSet, "WeakSet") /* Map + 3 */ 219 | DEF(Iterator, "Iterator") 220 | DEF(IteratorHelper, "Iterator Helper") 221 | DEF(IteratorWrap, "Iterator Wrap") 222 | DEF(Map_Iterator, "Map Iterator") 223 | DEF(Set_Iterator, "Set Iterator") 224 | DEF(Array_Iterator, "Array Iterator") 225 | DEF(String_Iterator, "String Iterator") 226 | DEF(RegExp_String_Iterator, "RegExp String Iterator") 227 | DEF(Generator, "Generator") 228 | DEF(Proxy, "Proxy") 229 | DEF(Promise, "Promise") 230 | DEF(PromiseResolveFunction, "PromiseResolveFunction") 231 | DEF(PromiseRejectFunction, "PromiseRejectFunction") 232 | DEF(AsyncFunction, "AsyncFunction") 233 | DEF(AsyncFunctionResolve, "AsyncFunctionResolve") 234 | DEF(AsyncFunctionReject, "AsyncFunctionReject") 235 | DEF(AsyncGeneratorFunction, "AsyncGeneratorFunction") 236 | DEF(AsyncGenerator, "AsyncGenerator") 237 | DEF(EvalError, "EvalError") 238 | DEF(RangeError, "RangeError") 239 | DEF(ReferenceError, "ReferenceError") 240 | DEF(SyntaxError, "SyntaxError") 241 | DEF(TypeError, "TypeError") 242 | DEF(URIError, "URIError") 243 | DEF(InternalError, "InternalError") 244 | DEF(CallSite, "CallSite") 245 | /* private symbols */ 246 | DEF(Private_brand, "") 247 | /* symbols */ 248 | DEF(Symbol_toPrimitive, "Symbol.toPrimitive") 249 | DEF(Symbol_iterator, "Symbol.iterator") 250 | DEF(Symbol_match, "Symbol.match") 251 | DEF(Symbol_matchAll, "Symbol.matchAll") 252 | DEF(Symbol_replace, "Symbol.replace") 253 | DEF(Symbol_search, "Symbol.search") 254 | DEF(Symbol_split, "Symbol.split") 255 | DEF(Symbol_toStringTag, "Symbol.toStringTag") 256 | DEF(Symbol_isConcatSpreadable, "Symbol.isConcatSpreadable") 257 | DEF(Symbol_hasInstance, "Symbol.hasInstance") 258 | DEF(Symbol_species, "Symbol.species") 259 | DEF(Symbol_unscopables, "Symbol.unscopables") 260 | DEF(Symbol_asyncIterator, "Symbol.asyncIterator") 261 | 262 | #endif /* DEF */ 263 | -------------------------------------------------------------------------------- /quickjs-c-atomics.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS C atomics definitions 3 | * 4 | * Copyright (c) 2023 Marcin Kolny 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #if (defined(__GNUC__) || defined(__GNUG__)) && !defined(__clang__) 26 | // Use GCC builtins for version < 4.9 27 | # if((__GNUC__ << 16) + __GNUC_MINOR__ < ((4) << 16) + 9) 28 | # define GCC_BUILTIN_ATOMICS 29 | # endif 30 | #endif 31 | 32 | #ifdef GCC_BUILTIN_ATOMICS 33 | #define atomic_fetch_add(obj, arg) \ 34 | __atomic_fetch_add(obj, arg, __ATOMIC_SEQ_CST) 35 | #define atomic_compare_exchange_strong(obj, expected, desired) \ 36 | __atomic_compare_exchange_n(obj, expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) 37 | #define atomic_exchange(obj, desired) \ 38 | __atomic_exchange_n (obj, desired, __ATOMIC_SEQ_CST) 39 | #define atomic_load(obj) \ 40 | __atomic_load_n(obj, __ATOMIC_SEQ_CST) 41 | #define atomic_store(obj, desired) \ 42 | __atomic_store_n(obj, desired, __ATOMIC_SEQ_CST) 43 | #define atomic_fetch_or(obj, arg) \ 44 | __atomic_fetch_or(obj, arg, __ATOMIC_SEQ_CST) 45 | #define atomic_fetch_xor(obj, arg) \ 46 | __atomic_fetch_xor(obj, arg, __ATOMIC_SEQ_CST) 47 | #define atomic_fetch_and(obj, arg) \ 48 | __atomic_fetch_and(obj, arg, __ATOMIC_SEQ_CST) 49 | #define atomic_fetch_sub(obj, arg) \ 50 | __atomic_fetch_sub(obj, arg, __ATOMIC_SEQ_CST) 51 | #define _Atomic 52 | #else 53 | #include 54 | #endif 55 | -------------------------------------------------------------------------------- /quickjs-libc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS C library 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef QUICKJS_LIBC_H 25 | #define QUICKJS_LIBC_H 26 | 27 | #include 28 | #include 29 | 30 | #include "quickjs.h" 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name); 37 | JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name); 38 | JSModuleDef *js_init_module_bjson(JSContext *ctx, const char *module_name); 39 | void js_std_add_helpers(JSContext *ctx, int argc, char **argv); 40 | JSValue js_std_loop(JSContext *ctx); 41 | JSValue js_std_await(JSContext *ctx, JSValue obj); 42 | void js_std_init_handlers(JSRuntime *rt); 43 | void js_std_free_handlers(JSRuntime *rt); 44 | void js_std_dump_error(JSContext *ctx); 45 | void js_std_dump_error1(JSContext *ctx, JSValue exception_val); 46 | uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename); 47 | int js_module_set_import_meta(JSContext *ctx, JSValue func_val, 48 | JS_BOOL use_realpath, JS_BOOL is_main); 49 | JSModuleDef *js_module_loader(JSContext *ctx, 50 | const char *module_name, void *opaque); 51 | void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len, 52 | int flags); 53 | void js_std_promise_rejection_tracker(JSContext *ctx, JSValue promise, 54 | JSValue reason, 55 | JS_BOOL is_handled, void *opaque); 56 | void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt)); 57 | 58 | #ifdef __cplusplus 59 | } /* extern "C" { */ 60 | #endif 61 | 62 | #endif /* QUICKJS_LIBC_H */ 63 | -------------------------------------------------------------------------------- /standalone.js: -------------------------------------------------------------------------------- 1 | import * as std from "qjs:std"; 2 | import * as os from "qjs:os"; 3 | import * as bjson from "qjs:bjson"; 4 | 5 | // See quickjs.h 6 | const JS_READ_OBJ_BYTECODE = 1 << 0; 7 | const JS_READ_OBJ_REFERENCE = 1 << 3; 8 | const JS_WRITE_OBJ_BYTECODE = 1 << 0; 9 | const JS_WRITE_OBJ_REFERENCE = 1 << 3; 10 | const JS_WRITE_OBJ_STRIP_SOURCE = 1 << 4; 11 | 12 | /** 13 | * Trailer for standalone binaries. When some code gets bundled with the qjs 14 | * executable we add a 12 byte trailer. The first 8 bytes are the magic 15 | * string that helps us understand this is a standalone binary, and the 16 | * remaining 4 are the offset (from the beginning of the binary) where the 17 | * bundled data is located. 18 | * 19 | * The offset is stored as a 32bit little-endian number. 20 | */ 21 | const Trailer = { 22 | Magic: 'quickjs2', 23 | MagicSize: 8, 24 | DataSize: 4, 25 | Size: 12 26 | }; 27 | 28 | function encodeAscii(txt) { 29 | return new Uint8Array(txt.split('').map(c => c.charCodeAt(0))); 30 | } 31 | 32 | function decodeAscii(buf) { 33 | return Array.from(buf).map(c => String.fromCharCode(c)).join('') 34 | } 35 | 36 | export function compileStandalone(inFile, outFile, targetExe) { 37 | // Step 1: compile the source file to bytecode 38 | const js = std.loadFile(inFile); 39 | 40 | if (!js) { 41 | throw new Error(`failed to open ${inFile}`); 42 | } 43 | 44 | const code = std.evalScript(js, { 45 | compile_only: true, 46 | compile_module: true 47 | }); 48 | const bytecode = new Uint8Array(bjson.write(code, JS_WRITE_OBJ_BYTECODE | JS_WRITE_OBJ_REFERENCE | JS_WRITE_OBJ_STRIP_SOURCE)); 49 | 50 | // Step 2: copy the bytecode to the end of the executable and add a marker. 51 | const exeFileName = targetExe ?? globalThis.argv0; 52 | const exe = std.loadFile(exeFileName, { binary: true }); 53 | 54 | if (!exe) { 55 | throw new Error(`failed to open executable: ${exeFileName}`); 56 | } 57 | 58 | const exeSize = exe.length; 59 | const newBuffer = exe.buffer.transfer(exeSize + bytecode.length + Trailer.Size); 60 | const newExe = new Uint8Array(newBuffer); 61 | 62 | newExe.set(bytecode, exeSize); 63 | newExe.set(encodeAscii(Trailer.Magic), exeSize + bytecode.length); 64 | 65 | const dw = new DataView(newBuffer, exeSize + bytecode.length + Trailer.MagicSize, Trailer.DataSize); 66 | 67 | dw.setUint32(0, exeSize, true /* little-endian */); 68 | 69 | // We use os.open() so we can set the permissions mask. 70 | const newFd = os.open(outFile, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o755); 71 | 72 | if (newFd < 0) { 73 | throw new Error(`failed to create ${outFile}`); 74 | } 75 | if (os.write(newFd, newBuffer, 0, newBuffer.byteLength) < 0) { 76 | os.close(newFd); 77 | throw new Error(`failed to write to output file`); 78 | } 79 | os.close(newFd); 80 | } 81 | 82 | export function runStandalone() { 83 | const file = globalThis.argv0; 84 | const exe = std.open(file, 'rb'); 85 | 86 | if (!exe) { 87 | throw new Error(`failed to open executable: ${file}`); 88 | } 89 | 90 | let r = exe.seek(-Trailer.Size, std.SEEK_END); 91 | if (r < 0) { 92 | throw new Error(`seek error: ${-r}`); 93 | } 94 | 95 | const trailer = new Uint8Array(Trailer.Size); 96 | 97 | exe.read(trailer.buffer, 0, Trailer.Size); 98 | 99 | const magic = new Uint8Array(trailer.buffer, 0, Trailer.MagicSize); 100 | 101 | // Shouldn't happen since qjs.c checks for it. 102 | if (decodeAscii(magic) !== Trailer.Magic) { 103 | exe.close(); 104 | throw new Error('corrupted binary, magic mismatch'); 105 | } 106 | 107 | const dw = new DataView(trailer.buffer, Trailer.MagicSize, Trailer.DataSize); 108 | const offset = dw.getUint32(0, true /* little-endian */); 109 | const bytecode = new Uint8Array(offset - Trailer.Size); 110 | 111 | r = exe.seek(offset, std.SEEK_SET); 112 | if (r < 0) { 113 | exe.close(); 114 | throw new Error(`seek error: ${-r}`); 115 | } 116 | 117 | exe.read(bytecode.buffer, 0, bytecode.length); 118 | if (exe.error()) { 119 | exe.close(); 120 | throw new Error('read error'); 121 | } 122 | exe.close(); 123 | 124 | const code = bjson.read(bytecode.buffer, 0, bytecode.length, JS_READ_OBJ_BYTECODE | JS_READ_OBJ_REFERENCE); 125 | 126 | return std.evalScript(code, { 127 | eval_module: true 128 | }); 129 | } 130 | -------------------------------------------------------------------------------- /test262-fast.conf: -------------------------------------------------------------------------------- 1 | [exclude] 2 | # list excluded tests and directories here for faster operation 3 | 4 | # lengthy constructed regexp (>500 ms) 5 | test262/test/annexB/built-ins/RegExp/RegExp-leading-escape-BMP.js 6 | test262/test/annexB/built-ins/RegExp/RegExp-trailing-escape-BMP.js 7 | 8 | # slow notifications (> 600 ms) 9 | test262/test/built-ins/Atomics/notify/notify-in-order-one-time.js 10 | test262/test/built-ins/Atomics/notify/notify-in-order.js 11 | test262/test/built-ins/Atomics/wait/bigint/waiterlist-order-of-operations-is-fifo.js 12 | test262/test/built-ins/Atomics/wait/waiterlist-order-of-operations-is-fifo.js 13 | 14 | # lengthy constructed regexp (>200 ms) 15 | test262/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-flags-u.js 16 | test262/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-digit-class-escape-plus-quantifier-flags-u.js 17 | test262/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-flags-u.js 18 | test262/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-whitespace-class-escape-plus-quantifier-flags-u.js 19 | test262/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-flags-u.js 20 | test262/test/built-ins/RegExp/CharacterClassEscapes/character-class-non-word-class-escape-plus-quantifier-flags-u.js 21 | test262/test/built-ins/RegExp/character-class-escape-non-whitespace.js 22 | 23 | # 417 lengty tests with huge constructed regexp (>200 ms) 24 | test262/test/built-ins/RegExp/property-escapes/generated/ 25 | 26 | # lengthy constructed URLS (>200 ms) 27 | test262/test/built-ins/decodeURI/S15.1.3.1_A1.2_T1.js 28 | test262/test/built-ins/decodeURI/S15.1.3.1_A1.2_T2.js 29 | test262/test/built-ins/decodeURI/S15.1.3.1_A1.10_T1.js 30 | test262/test/built-ins/decodeURI/S15.1.3.1_A1.11_T1.js 31 | test262/test/built-ins/decodeURI/S15.1.3.1_A1.11_T2.js 32 | test262/test/built-ins/decodeURI/S15.1.3.1_A1.12_T1.js 33 | test262/test/built-ins/decodeURI/S15.1.3.1_A1.12_T2.js 34 | test262/test/built-ins/decodeURI/S15.1.3.1_A1.12_T3.js 35 | test262/test/built-ins/decodeURI/S15.1.3.1_A2.5_T1.js 36 | test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.2_T1.js 37 | test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.2_T2.js 38 | test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.10_T1.js 39 | test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.11_T1.js 40 | test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.11_T2.js 41 | test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.12_T1.js 42 | test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.12_T2.js 43 | test262/test/built-ins/decodeURIComponent/S15.1.3.2_A1.12_T3.js 44 | test262/test/built-ins/decodeURIComponent/S15.1.3.2_A2.5_T1.js 45 | 46 | # lengthy comment tests 47 | test262/test/language/comments/S7.4_A5.js 48 | test262/test/language/comments/S7.4_A6.js 49 | 50 | # lengthy unicode level tests 51 | test262/test/language/identifiers/start-unicode-5.2.0-class-escaped.js 52 | test262/test/language/identifiers/start-unicode-5.2.0-class.js 53 | test262/test/language/identifiers/start-unicode-8.0.0-class-escaped.js 54 | test262/test/language/identifiers/start-unicode-8.0.0-class.js 55 | test262/test/language/identifiers/start-unicode-9.0.0-class-escaped.js 56 | test262/test/language/identifiers/start-unicode-9.0.0-class.js 57 | test262/test/language/identifiers/start-unicode-10.0.0-class-escaped.js 58 | test262/test/language/identifiers/start-unicode-10.0.0-class.js 59 | test262/test/language/identifiers/start-unicode-13.0.0-class-escaped.js 60 | test262/test/language/identifiers/start-unicode-13.0.0-class.js 61 | test262/test/language/identifiers/start-unicode-15.0.0-class-escaped.js 62 | test262/test/language/identifiers/start-unicode-15.0.0-class.js 63 | 64 | # Atomics tests with 2 second delays 65 | test262/test/built-ins/Atomics/notify/bigint/notify-all-on-loc.js 66 | test262/test/built-ins/Atomics/notify/negative-count.js 67 | test262/test/built-ins/Atomics/notify/notify-all-on-loc.js 68 | test262/test/built-ins/Atomics/notify/notify-all.js 69 | test262/test/built-ins/Atomics/notify/notify-nan.js 70 | test262/test/built-ins/Atomics/notify/notify-one.js 71 | test262/test/built-ins/Atomics/notify/notify-two.js 72 | test262/test/built-ins/Atomics/notify/notify-zero.js 73 | 74 | # Atomics tests with 400 millisecond delays 75 | test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-no-operation.js 76 | test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-add.js 77 | test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-and.js 78 | test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-compareExchange.js 79 | test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-exchange.js 80 | test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-or.js 81 | test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-store.js 82 | test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-sub.js 83 | test262/test/built-ins/Atomics/wait/bigint/no-spurious-wakeup-on-xor.js 84 | test262/test/built-ins/Atomics/wait/no-spurious-wakeup-no-operation.js 85 | test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-add.js 86 | test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-and.js 87 | test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-compareExchange.js 88 | test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-exchange.js 89 | test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-or.js 90 | test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-store.js 91 | test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-sub.js 92 | test262/test/built-ins/Atomics/wait/no-spurious-wakeup-on-xor.js 93 | 94 | # Atomics tests with 200 millisecond delays 95 | test262/test/built-ins/Atomics/notify/count-defaults-to-infinity-missing.js 96 | test262/test/built-ins/Atomics/notify/count-defaults-to-infinity-undefined.js 97 | test262/test/built-ins/Atomics/notify/notify-renotify-noop.js 98 | test262/test/built-ins/Atomics/notify/undefined-index-defaults-to-zero.js 99 | test262/test/built-ins/Atomics/wait/bigint/false-for-timeout-agent.js 100 | test262/test/built-ins/Atomics/wait/bigint/nan-for-timeout.js 101 | test262/test/built-ins/Atomics/wait/bigint/negative-timeout-agent.js 102 | test262/test/built-ins/Atomics/wait/bigint/value-not-equal.js 103 | test262/test/built-ins/Atomics/wait/bigint/was-woken-before-timeout.js 104 | test262/test/built-ins/Atomics/wait/false-for-timeout-agent.js 105 | test262/test/built-ins/Atomics/wait/nan-for-timeout.js 106 | test262/test/built-ins/Atomics/wait/negative-timeout-agent.js 107 | test262/test/built-ins/Atomics/wait/null-for-timeout-agent.js 108 | test262/test/built-ins/Atomics/wait/object-for-timeout-agent.js 109 | test262/test/built-ins/Atomics/wait/poisoned-object-for-timeout-throws-agent.js 110 | test262/test/built-ins/Atomics/wait/symbol-for-index-throws-agent.js 111 | test262/test/built-ins/Atomics/wait/symbol-for-timeout-throws-agent.js 112 | test262/test/built-ins/Atomics/wait/symbol-for-value-throws-agent.js 113 | test262/test/built-ins/Atomics/wait/true-for-timeout-agent.js 114 | test262/test/built-ins/Atomics/wait/undefined-for-timeout.js 115 | test262/test/built-ins/Atomics/wait/undefined-index-defaults-to-zero.js 116 | test262/test/built-ins/Atomics/wait/value-not-equal.js 117 | test262/test/built-ins/Atomics/wait/wait-index-value-not-equal.js 118 | test262/test/built-ins/Atomics/wait/was-woken-before-timeout.js 119 | 120 | # lengthy regexp literal construction (>500 ms) 121 | test262/test/language/literals/regexp/S7.8.5_A1.1_T2.js 122 | test262/test/language/literals/regexp/S7.8.5_A1.4_T2.js 123 | test262/test/language/literals/regexp/S7.8.5_A2.1_T2.js 124 | test262/test/language/literals/regexp/S7.8.5_A2.4_T2.js 125 | 126 | # lengthy built-ins tests (100-200 ms) 127 | test262/test/built-ins/Function/prototype/toString/built-in-function-object.js 128 | test262/test/built-ins/decodeURI/S15.1.3.1_A2.4_T1.js 129 | test262/test/built-ins/decodeURIComponent/S15.1.3.2_A2.4_T1.js 130 | test262/test/built-ins/encodeURI/S15.1.3.3_A2.3_T1.js 131 | test262/test/built-ins/encodeURIComponent/S15.1.3.4_A2.3_T1.js 132 | test262/test/language/expressions/dynamic-import/await-import-evaluation.js 133 | -------------------------------------------------------------------------------- /test262_errors.txt: -------------------------------------------------------------------------------- 1 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/iterator-result-poisoned-wrapper.js:64: TypeError: $DONE() not called 2 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/iterator-result-poisoned-wrapper.js:64: strict mode: TypeError: $DONE() not called 3 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/next-result-poisoned-wrapper.js:69: TypeError: $DONE() not called 4 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/next-result-poisoned-wrapper.js:69: strict mode: TypeError: $DONE() not called 5 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/yield-iterator-next-rejected-promise-close.js:59: TypeError: $DONE() not called 6 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/yield-iterator-next-rejected-promise-close.js:59: strict mode: TypeError: $DONE() not called 7 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/yield-next-rejected-promise-close.js:64: TypeError: $DONE() not called 8 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/yield-next-rejected-promise-close.js:64: strict mode: TypeError: $DONE() not called 9 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/iterator-result-rejected-promise-close.js:74: TypeError: $DONE() not called 10 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/iterator-result-rejected-promise-close.js:74: strict mode: TypeError: $DONE() not called 11 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-result-poisoned-wrapper.js:81: TypeError: $DONE() not called 12 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-result-poisoned-wrapper.js:81: strict mode: TypeError: $DONE() not called 13 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-get-return-undefined.js:64: TypeError: $DONE() not called 14 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-get-return-undefined.js:64: strict mode: TypeError: $DONE() not called 15 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-poisoned-return.js:68: TypeError: $DONE() not called 16 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-poisoned-return.js:68: strict mode: TypeError: $DONE() not called 17 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-not-object.js:72: TypeError: $DONE() not called 18 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-not-object.js:72: strict mode: TypeError: $DONE() not called 19 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-object.js:66: TypeError: $DONE() not called 20 | test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-object.js:66: strict mode: TypeError: $DONE() not called 21 | test262/test/built-ins/Iterator/prototype/constructor/prop-desc.js:10: Test262Error: Expected SameValue(«"undefined"», «"function"») to be true 22 | test262/test/built-ins/Iterator/prototype/constructor/prop-desc.js:10: strict mode: Test262Error: Expected SameValue(«"undefined"», «"function"») to be true 23 | test262/test/built-ins/Iterator/prototype/constructor/weird-setter.js:23: TypeError: cannot read property 'call' of undefined 24 | test262/test/built-ins/Iterator/prototype/constructor/weird-setter.js:23: strict mode: TypeError: cannot read property 'call' of undefined 25 | test262/test/built-ins/Object/defineProperties/typedarray-backed-by-resizable-buffer.js:20: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all 26 | test262/test/built-ins/Object/defineProperties/typedarray-backed-by-resizable-buffer.js:20: strict mode: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all 27 | test262/test/built-ins/Object/defineProperty/coerced-P-grow.js:45: TypeError: out-of-bound index in typed array 28 | test262/test/built-ins/Object/defineProperty/coerced-P-grow.js:45: strict mode: TypeError: out-of-bound index in typed array 29 | test262/test/built-ins/Object/defineProperty/coerced-P-shrink.js:16: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all 30 | test262/test/built-ins/Object/defineProperty/coerced-P-shrink.js:16: strict mode: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all 31 | test262/test/built-ins/Object/defineProperty/typedarray-backed-by-resizable-buffer.js:18: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all 32 | test262/test/built-ins/Object/defineProperty/typedarray-backed-by-resizable-buffer.js:18: strict mode: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all 33 | test262/test/built-ins/RegExp/prototype/exec/regexp-builtin-exec-v-u-flag.js:45: Test262Error: Actual argument shouldn't be nullish. Unicode property escapes with v flag 34 | test262/test/built-ins/RegExp/prototype/exec/regexp-builtin-exec-v-u-flag.js:45: strict mode: Test262Error: Actual argument shouldn't be nullish. Unicode property escapes with v flag 35 | test262/test/built-ins/RegExp/unicodeSets/generated/rgi-emoji-16.0.js:16: Test262Error: `\p{RGI_Emoji}` should match 🇨🇶 (U+01F1E8 U+01F1F6) 36 | test262/test/built-ins/RegExp/unicodeSets/generated/rgi-emoji-16.0.js:16: strict mode: Test262Error: `\p{RGI_Emoji}` should match 🇨🇶 (U+01F1E8 U+01F1F6) 37 | test262/test/built-ins/String/prototype/match/regexp-prototype-match-v-u-flag.js:10: Test262Error: Actual argument shouldn't be nullish. Unicode property escapes with v flag 38 | test262/test/built-ins/String/prototype/match/regexp-prototype-match-v-u-flag.js:10: strict mode: Test262Error: Actual argument shouldn't be nullish. Unicode property escapes with v flag 39 | test262/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-v-u-flag.js:73: Test262Error: Actual [] and expected [𠮷, 𠮷, 𠮷, 0, 3, 6] should have the same contents. 40 | test262/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-v-u-flag.js:73: strict mode: Test262Error: Actual [] and expected [𠮷, 𠮷, 𠮷, 0, 3, 6] should have the same contents. 41 | test262/test/built-ins/String/prototype/replace/regexp-prototype-replace-v-u-flag.js:9: Test262Error: Unicode property escapes with v flag Expected SameValue(«"𠮷a𠮷b𠮷"», «"XaXbX"») to be true 42 | test262/test/built-ins/String/prototype/replace/regexp-prototype-replace-v-u-flag.js:9: strict mode: Test262Error: Unicode property escapes with v flag Expected SameValue(«"𠮷a𠮷b𠮷"», «"XaXbX"») to be true 43 | test262/test/built-ins/String/prototype/search/regexp-prototype-search-v-flag.js:9: Test262Error: Unicode property escapes with v flag Expected SameValue(«-1», «0») to be true 44 | test262/test/built-ins/String/prototype/search/regexp-prototype-search-v-flag.js:9: strict mode: Test262Error: Unicode property escapes with v flag Expected SameValue(«-1», «0») to be true 45 | test262/test/built-ins/String/prototype/search/regexp-prototype-search-v-u-flag.js:9: Test262Error: Unicode property escapes with v flag Expected SameValue(«-1», «0») to be true 46 | test262/test/built-ins/String/prototype/search/regexp-prototype-search-v-u-flag.js:9: strict mode: Test262Error: Unicode property escapes with v flag Expected SameValue(«-1», «0») to be true 47 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-prototype-chain-set.js:35: Test262Error: value should not be coerced Expected SameValue(«22», «0») to be true 48 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-prototype-chain-set.js:35: strict mode: Test262Error: value should not be coerced Expected SameValue(«22», «0») to be true 49 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-reflect-set.js:35: Test262Error: value should not be coerced Expected SameValue(«32», «0») to be true 50 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-reflect-set.js:35: strict mode: Test262Error: value should not be coerced Expected SameValue(«32», «0») to be true 51 | test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-prototype-chain-set.js:35: Test262Error: value should not be coerced Expected SameValue(«110», «0») to be true 52 | test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-prototype-chain-set.js:35: strict mode: Test262Error: value should not be coerced Expected SameValue(«110», «0») to be true 53 | test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-reflect-set.js:35: Test262Error: value should not be coerced Expected SameValue(«160», «0») to be true 54 | test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-reflect-set.js:35: strict mode: Test262Error: value should not be coerced Expected SameValue(«160», «0») to be true 55 | test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-object.js:19: Test262Error: valueOf is not called Expected SameValue(«1», «0») to be true 56 | test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-object.js:19: strict mode: Test262Error: valueOf is not called Expected SameValue(«1», «0») to be true 57 | test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-typed-array.js:19: Test262Error: valueOf is not called Expected SameValue(«1», «0») to be true 58 | test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-typed-array.js:19: strict mode: Test262Error: valueOf is not called Expected SameValue(«1», «0») to be true 59 | test262/test/language/destructuring/binding/keyed-destructuring-property-reference-target-evaluation-order-with-bindings.js:73: Test262Error: Actual [binding::source, binding::sourceKey, sourceKey, get source, binding::defaultValue, binding::varTarget] and expected [binding::source, binding::sourceKey, sourceKey, binding::varTarget, get source, binding::defaultValue] should have the same contents. 60 | test262/test/language/expressions/assignment/destructuring/iterator-destructuring-property-reference-target-evaluation-order.js:42: Test262Error: Actual [source, iterator, target, target-key, target-key-tostring, iterator-step, iterator-done, set] and expected [source, iterator, target, target-key, iterator-step, iterator-done, target-key-tostring, set] should have the same contents. 61 | test262/test/language/expressions/assignment/destructuring/iterator-destructuring-property-reference-target-evaluation-order.js:42: strict mode: Test262Error: Actual [source, iterator, target, target-key, target-key-tostring, iterator-step, iterator-done, set] and expected [source, iterator, target, target-key, iterator-step, iterator-done, target-key-tostring, set] should have the same contents. 62 | test262/test/language/expressions/assignment/destructuring/keyed-destructuring-property-reference-target-evaluation-order-with-bindings.js:37: Test262Error: Actual [binding::source, binding::sourceKey, sourceKey, binding::target, binding::targetKey, targetKey, get source, binding::defaultValue, set target] and expected [binding::source, binding::sourceKey, sourceKey, binding::target, binding::targetKey, get source, binding::defaultValue, targetKey, set target] should have the same contents. 63 | test262/test/language/expressions/assignment/destructuring/keyed-destructuring-property-reference-target-evaluation-order.js:32: Test262Error: Actual [source, source-key, source-key-tostring, target, target-key, target-key-tostring, get, set] and expected [source, source-key, source-key-tostring, target, target-key, get, target-key-tostring, set] should have the same contents. 64 | test262/test/language/expressions/assignment/destructuring/keyed-destructuring-property-reference-target-evaluation-order.js:32: strict mode: Test262Error: Actual [source, source-key, source-key-tostring, target, target-key, target-key-tostring, get, set] and expected [source, source-key, source-key-tostring, target, target-key, get, target-key-tostring, set] should have the same contents. 65 | test262/test/language/expressions/assignment/target-member-computed-reference.js:22: Test262Error: Expected a DummyError but got a Test262Error 66 | test262/test/language/expressions/assignment/target-member-computed-reference.js:22: strict mode: Test262Error: Expected a DummyError but got a Test262Error 67 | test262/test/language/expressions/assignment/target-super-computed-reference.js:20: Test262Error: Expected a DummyError but got a Test262Error 68 | test262/test/language/expressions/assignment/target-super-computed-reference.js:20: strict mode: Test262Error: Expected a DummyError but got a Test262Error 69 | test262/test/language/expressions/in/private-field-invalid-assignment-target.js:23: unexpected error type: Test262: This statement should not be evaluated. 70 | test262/test/language/expressions/in/private-field-invalid-assignment-target.js:23: strict mode: unexpected error type: Test262: This statement should not be evaluated. 71 | test262/test/language/expressions/object/computed-property-name-topropertykey-before-value-evaluation.js:31: Test262Error: Expected SameValue(«"bad"», «"ok"») to be true 72 | test262/test/language/expressions/object/computed-property-name-topropertykey-before-value-evaluation.js:31: strict mode: Test262Error: Expected SameValue(«"bad"», «"ok"») to be true 73 | test262/test/language/module-code/top-level-await/async-module-does-not-block-sibling-modules.js:13: SyntaxError: Could not find export 'check' in module 'test262/test/language/module-code/top-level-await/async-module-sync_FIXTURE.js' 74 | test262/test/language/module-code/top-level-await/module-graphs-does-not-hang.js:10: TypeError: $DONE() not called 75 | test262/test/language/statements/class/elements/syntax/valid/grammar-field-named-get-followed-by-generator-asi.js:40: SyntaxError: invalid property name 76 | test262/test/language/statements/class/elements/syntax/valid/grammar-field-named-get-followed-by-generator-asi.js:40: strict mode: SyntaxError: invalid property name 77 | test262/test/language/statements/class/elements/syntax/valid/grammar-field-named-set-followed-by-generator-asi.js:40: SyntaxError: invalid property name 78 | test262/test/language/statements/class/elements/syntax/valid/grammar-field-named-set-followed-by-generator-asi.js:40: strict mode: SyntaxError: invalid property name 79 | test262/test/language/statements/with/get-binding-value-call-with-proxy-env.js:39: Test262Error: Actual [has:Object, get:Symbol(Symbol.unscopables), get:Object] and expected [has:Object, get:Symbol(Symbol.unscopables), has:Object, get:Object] should have the same contents. 80 | test262/test/language/statements/with/get-binding-value-idref-with-proxy-env.js:39: Test262Error: Actual [has:Object, get:Symbol(Symbol.unscopables), get:Object] and expected [has:Object, get:Symbol(Symbol.unscopables), has:Object, get:Object] should have the same contents. 81 | test262/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js:21: Test262Error: Expected a ReferenceError to be thrown but no exception was thrown at all 82 | test262/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain.js:20: Test262Error: Expected SameValue(«[object Object]», «undefined») to be true 83 | test262/test/language/statements/with/set-mutable-binding-idref-compound-assign-with-proxy-env.js:58: Test262Error: Actual [has:p, get:Symbol(Symbol.unscopables), get:p, set:p, getOwnPropertyDescriptor:p, defineProperty:p] and expected [has:p, get:Symbol(Symbol.unscopables), has:p, get:p, has:p, set:p, getOwnPropertyDescriptor:p, defineProperty:p] should have the same contents. 84 | test262/test/language/statements/with/set-mutable-binding-idref-with-proxy-env.js:50: Test262Error: Actual [has:p, get:Symbol(Symbol.unscopables), set:p, getOwnPropertyDescriptor:p, defineProperty:p] and expected [has:p, get:Symbol(Symbol.unscopables), has:p, set:p, getOwnPropertyDescriptor:p, defineProperty:p] should have the same contents. 85 | -------------------------------------------------------------------------------- /tests.conf: -------------------------------------------------------------------------------- 1 | [config] 2 | local=yes 3 | verbose=yes 4 | testdir=tests 5 | 6 | [exclude] 7 | tests/fixture_cyclic_import.js 8 | tests/microbench.js 9 | tests/test_worker_module.js 10 | -------------------------------------------------------------------------------- /tests/assert.js: -------------------------------------------------------------------------------- 1 | export function assert(actual, expected, message) { 2 | if (arguments.length === 1) 3 | expected = true; 4 | 5 | if (typeof actual === typeof expected) { 6 | if (actual === expected) { 7 | if (actual !== 0 || (1 / actual) === (1 / expected)) 8 | return; 9 | } 10 | if (typeof actual === 'number') { 11 | if (isNaN(actual) && isNaN(expected)) 12 | return; 13 | } 14 | if (typeof actual === 'object') { 15 | if (actual !== null && expected !== null 16 | && actual.constructor === expected.constructor 17 | && actual.toString() === expected.toString()) 18 | return; 19 | } 20 | } 21 | throw Error("assertion failed: got |" + actual + "|" + 22 | ", expected |" + expected + "|" + 23 | (message ? " (" + message + ")" : "")); 24 | } 25 | 26 | export function assertThrows(err, func) 27 | { 28 | var ex; 29 | ex = false; 30 | try { 31 | func(); 32 | } catch(e) { 33 | ex = true; 34 | assert(e instanceof err); 35 | } 36 | assert(ex, true, "exception expected"); 37 | } 38 | 39 | export function assertArrayEquals(a, b) 40 | { 41 | if (!Array.isArray(a) || !Array.isArray(b)) 42 | return assert(false); 43 | 44 | assert(a.length, b.length); 45 | 46 | a.forEach((value, idx) => { 47 | assert(b[idx], value); 48 | }); 49 | } 50 | -------------------------------------------------------------------------------- /tests/bug633/0.js: -------------------------------------------------------------------------------- 1 | /*--- 2 | flags: [qjs:no-detect-module] 3 | negative: 4 | phase: parse 5 | type: SyntaxError 6 | ---*/ 7 | const undefined = 42 // SyntaxError at global scope 8 | -------------------------------------------------------------------------------- /tests/bug633/1.js: -------------------------------------------------------------------------------- 1 | /*--- 2 | flags: [qjs:no-detect-module, module] 3 | ---*/ 4 | const undefined = 42 // not a SyntaxError at toplevel module scope 5 | -------------------------------------------------------------------------------- /tests/bug633/2.js: -------------------------------------------------------------------------------- 1 | /*--- 2 | flags: [qjs:no-detect-module] 3 | ---*/ 4 | { const undefined = 42 } // not a SyntaxError, not at global scope 5 | -------------------------------------------------------------------------------- /tests/bug633/3.js: -------------------------------------------------------------------------------- 1 | /*--- 2 | flags: [qjs:no-detect-module] 3 | ---*/ 4 | ;(function() { const undefined = 42 })() // not a SyntaxError, not at global scope 5 | -------------------------------------------------------------------------------- /tests/bug645/0.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | const u8 = new Uint8Array(1); 4 | u8[100] = 123; // Should not throw. 5 | -------------------------------------------------------------------------------- /tests/bug645/1.js: -------------------------------------------------------------------------------- 1 | import { assert, assertThrows } from "../assert.js"; 2 | const ab = new ArrayBuffer(1); 3 | const u8 = new Uint8Array(ab); 4 | assert(!ab.detached); 5 | // Detach the ArrayBuffer. 6 | ab.transfer(); 7 | assert(ab.detached); 8 | u8[100] = 123; // Doesn't throw. 9 | assertThrows(TypeError, () => Object.defineProperty(u8, "100", { value: 123 })); 10 | -------------------------------------------------------------------------------- /tests/bug645/2.js: -------------------------------------------------------------------------------- 1 | import { assert, assertThrows } from "../assert.js"; 2 | const ab = new ArrayBuffer(16, { maxByteLength: 32 }); 3 | const u8 = new Uint8Array(ab, 16); 4 | ab.resize(8); 5 | assert(ab.byteLength, 8); 6 | u8[1] = 123; // Doesn't throw. 7 | assertThrows(TypeError, () => Object.defineProperty(u8, "1", { value: 123 })); 8 | -------------------------------------------------------------------------------- /tests/bug648.js: -------------------------------------------------------------------------------- 1 | /*--- 2 | negative: 3 | phase: runtime 4 | type: Error 5 | ---*/ 6 | let finrec = new FinalizationRegistry(v => {}) 7 | let object = {object:"object"} 8 | finrec.register(object, {held:"held"}, {token:"token"}) 9 | object = undefined 10 | // abrupt termination should not leak |held| 11 | // unfortunately only shows up in qjs, not run-test262, 12 | // but still good to have a regression test 13 | throw Error("ok") 14 | -------------------------------------------------------------------------------- /tests/bug652.js: -------------------------------------------------------------------------------- 1 | import { assert } from "./assert.js" 2 | const ref = new WeakRef({}) 3 | const val = ref.deref() // should not throw 4 | assert(val, undefined) 5 | -------------------------------------------------------------------------------- /tests/bug741.js: -------------------------------------------------------------------------------- 1 | import {assert} from "./assert.js" 2 | 3 | while (1) label: break 4 | 5 | var i = 0 6 | while (i < 3) label: { 7 | if (i > 0) 8 | break 9 | i++ 10 | } 11 | assert(i, 1) 12 | 13 | for (;;) label: break 14 | 15 | for (i = 0; i < 3; i++) label: { 16 | if (i > 0) 17 | break 18 | } 19 | assert(i, 1) 20 | -------------------------------------------------------------------------------- /tests/bug775.js: -------------------------------------------------------------------------------- 1 | /*--- 2 | negative: 3 | phase: runtime 4 | type: RangeError 5 | ---*/ 6 | function f() { f() } // was problematic under ASan 7 | f() 8 | -------------------------------------------------------------------------------- /tests/bug776.js: -------------------------------------------------------------------------------- 1 | /*--- 2 | negative: 3 | phase: runtime 4 | type: RangeError 5 | ---*/ 6 | function f() { f.apply(null) } // was problematic under ASan 7 | f() 8 | -------------------------------------------------------------------------------- /tests/detect_module/0.js: -------------------------------------------------------------------------------- 1 | await undefined 2 | -------------------------------------------------------------------------------- /tests/detect_module/1.js: -------------------------------------------------------------------------------- 1 | const p = Promise.resolve(42) 2 | await p 3 | -------------------------------------------------------------------------------- /tests/detect_module/2.js: -------------------------------------------------------------------------------- 1 | await = 42 // parsed as classic script 2 | -------------------------------------------------------------------------------- /tests/detect_module/3.js: -------------------------------------------------------------------------------- 1 | /*--- 2 | negative: 3 | phase: parse 4 | type: SyntaxError 5 | ---*/ 6 | // the import statement makes it a module but `await = 42` is a SyntaxError 7 | import * as _ from "dummy" 8 | await = 42 9 | -------------------------------------------------------------------------------- /tests/detect_module/4.js: -------------------------------------------------------------------------------- 1 | // imports should classify it as a module, even when not at the top 2 | os.now() 3 | import * as os from "qjs:os" 4 | -------------------------------------------------------------------------------- /tests/fixture_cyclic_import.js: -------------------------------------------------------------------------------- 1 | import * as a from "./test_cyclic_import.js" 2 | export function f(x) { return 2 * a.g(x) } 3 | -------------------------------------------------------------------------------- /tests/function_source.js: -------------------------------------------------------------------------------- 1 | "use strict" 2 | const expect = "function f() { return 42 }" 3 | function f() { return 42 } 4 | 5 | { 6 | const actual = f.toString() 7 | if (actual !== expect) throw Error(actual) 8 | } 9 | 10 | { 11 | const f = eval(expect + "f") 12 | const actual = f.toString() 13 | if (actual !== expect) throw Error(actual) 14 | } 15 | -------------------------------------------------------------------------------- /tests/test_bigint.js: -------------------------------------------------------------------------------- 1 | import { assert, assertThrows } from "./assert.js"; 2 | 3 | 4 | function bigint_pow(a, n) 5 | { 6 | var r, i; 7 | r = 1n; 8 | for(i = 0n; i < n; i++) 9 | r *= a; 10 | return r; 11 | } 12 | 13 | /* a must be < b */ 14 | function test_less(a, b) 15 | { 16 | assert(a < b); 17 | assert(!(b < a)); 18 | assert(a <= b); 19 | assert(!(b <= a)); 20 | assert(b > a); 21 | assert(!(a > b)); 22 | assert(b >= a); 23 | assert(!(a >= b)); 24 | assert(a != b); 25 | assert(!(a == b)); 26 | } 27 | 28 | /* a must be numerically equal to b */ 29 | function test_eq(a, b) 30 | { 31 | assert(a == b); 32 | assert(b == a); 33 | assert(!(a != b)); 34 | assert(!(b != a)); 35 | assert(a <= b); 36 | assert(b <= a); 37 | assert(!(a < b)); 38 | assert(a >= b); 39 | assert(b >= a); 40 | assert(!(a > b)); 41 | } 42 | 43 | function test_bigint1() 44 | { 45 | var a, r; 46 | 47 | test_less(2n, 3n); 48 | test_eq(3n, 3n); 49 | 50 | test_less(2, 3n); 51 | test_eq(3, 3n); 52 | 53 | test_less(2.1, 3n); 54 | test_eq(Math.sqrt(4), 2n); 55 | 56 | a = bigint_pow(3n, 100n); 57 | assert((a - 1n) != a); 58 | assert(a, 515377520732011331036461129765621272702107522001n); 59 | assert(a, 0x5a4653ca673768565b41f775d6947d55cf3813d1n); 60 | 61 | r = 1n << 31n; 62 | assert(r, 2147483648n, "1 << 31n === 2147483648n"); 63 | 64 | r = 1n << 32n; 65 | assert(r, 4294967296n, "1 << 32n === 4294967296n"); 66 | } 67 | 68 | function test_bigint2() 69 | { 70 | assert(BigInt(""), 0n); 71 | assert(BigInt(" 123"), 123n); 72 | assert(BigInt(" 123 "), 123n); 73 | assertThrows(SyntaxError, () => { BigInt("+") } ); 74 | assertThrows(SyntaxError, () => { BigInt("-") } ); 75 | assertThrows(SyntaxError, () => { BigInt("\x00a") } ); 76 | assertThrows(SyntaxError, () => { BigInt(" 123 r") } ); 77 | } 78 | 79 | function test_bigint_map() 80 | { 81 | var m = new Map(); 82 | assert(m.size, 0); 83 | 84 | for (let i = 0n; i < 1337n; i++) { 85 | const r = m.set(i, i.toString()); 86 | assert(r, m); 87 | } 88 | assert(m.size, 1337); 89 | 90 | for (let i = 0n; i < 1337n; i++) { 91 | const r = m.get(i); 92 | assert(r, i.toString()); 93 | } 94 | assert(m.get(1337n), undefined); 95 | assert(m.size, 1337); 96 | 97 | for (let i = 0n; i < 1337n; i++) 98 | assert(m.delete(i)); 99 | assert(!m.delete(1337n)); 100 | assert(m.size, 0); 101 | } 102 | 103 | test_bigint1(); 104 | test_bigint2(); 105 | test_bigint_map(); 106 | -------------------------------------------------------------------------------- /tests/test_bjson.js: -------------------------------------------------------------------------------- 1 | import * as std from "qjs:std"; 2 | import * as bjson from "qjs:bjson"; 3 | import { assert } from "./assert.js"; 4 | 5 | function base64decode(s) { 6 | var A = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 7 | var n = s.indexOf("="); 8 | if (n < 0) n = s.length; 9 | if (n & 3 === 1) throw Error("bad base64"); // too much padding 10 | var r = new Uint8Array(3 * (n>>2) + (n>>1 & 1) + (n & 1)); 11 | var a, b, c, d, i, j; 12 | a = b = c = d = i = j = 0; 13 | while (i+3 < n) { 14 | a = A.indexOf(s[i++]); 15 | b = A.indexOf(s[i++]); 16 | c = A.indexOf(s[i++]); 17 | d = A.indexOf(s[i++]); 18 | if (~63 & (a|b|c|d)) throw Error("bad base64"); 19 | r[j++] = a<<2 | b>>4; 20 | r[j++] = 255 & b<<4 | c>>2; 21 | r[j++] = 255 & c<<6 | d; 22 | } 23 | switch (n & 3) { 24 | case 2: 25 | a = A.indexOf(s[i++]); 26 | b = A.indexOf(s[i++]); 27 | if (~63 & (a|b)) throw Error("bad base64"); 28 | if (b & 15) throw Error("bad base64"); 29 | r[j++] = a<<2 | b>>4; 30 | break; 31 | case 3: 32 | a = A.indexOf(s[i++]); 33 | b = A.indexOf(s[i++]); 34 | c = A.indexOf(s[i++]); 35 | if (~63 & (a|b|c)) throw Error("bad base64"); 36 | if (c & 3) throw Error("bad base64"); 37 | r[j++] = a<<2 | b>>4; 38 | r[j++] = 255 & b<<4 | c>>2; 39 | break; 40 | } 41 | return r.buffer; 42 | } 43 | 44 | function toHex(a) 45 | { 46 | var i, s = "", tab, v; 47 | tab = new Uint8Array(a); 48 | for(i = 0; i < tab.length; i++) { 49 | v = tab[i].toString(16); 50 | if (v.length < 2) 51 | v = "0" + v; 52 | if (i !== 0) 53 | s += " "; 54 | s += v; 55 | } 56 | return s; 57 | } 58 | 59 | function isArrayLike(a) 60 | { 61 | return Array.isArray(a) || 62 | (a instanceof Uint8ClampedArray) || 63 | (a instanceof Uint8Array) || 64 | (a instanceof Uint16Array) || 65 | (a instanceof Uint32Array) || 66 | (a instanceof Int8Array) || 67 | (a instanceof Int16Array) || 68 | (a instanceof Int32Array) || 69 | (a instanceof Float16Array) || 70 | (a instanceof Float32Array) || 71 | (a instanceof Float64Array); 72 | } 73 | 74 | function toStr(a) 75 | { 76 | var s, i, props, prop; 77 | 78 | switch(typeof(a)) { 79 | case "object": 80 | if (a === null) 81 | return "null"; 82 | if (a instanceof Date) { 83 | s = "Date(" + toStr(a.valueOf()) + ")"; 84 | } else if (a instanceof Number) { 85 | s = "Number(" + toStr(a.valueOf()) + ")"; 86 | } else if (a instanceof String) { 87 | s = "String(" + toStr(a.valueOf()) + ")"; 88 | } else if (a instanceof Boolean) { 89 | s = "Boolean(" + toStr(a.valueOf()) + ")"; 90 | } else if (isArrayLike(a)) { 91 | s = "["; 92 | for(i = 0; i < a.length; i++) { 93 | if (i != 0) 94 | s += ","; 95 | s += toStr(a[i]); 96 | } 97 | s += "]"; 98 | } else { 99 | props = Object.keys(a); 100 | s = "{"; 101 | for(i = 0; i < props.length; i++) { 102 | if (i != 0) 103 | s += ","; 104 | prop = props[i]; 105 | s += prop + ":" + toStr(a[prop]); 106 | } 107 | s += "}"; 108 | } 109 | return s; 110 | case "undefined": 111 | return "undefined"; 112 | case "string": 113 | return JSON.stringify(a); 114 | case "number": 115 | if (a == 0 && 1 / a < 0) 116 | return "-0"; 117 | else 118 | return a.toString(); 119 | break; 120 | default: 121 | return a.toString(); 122 | } 123 | } 124 | 125 | function bjson_test(a) 126 | { 127 | var buf, r, a_str, r_str; 128 | a_str = toStr(a); 129 | buf = bjson.write(a); 130 | if (0) { 131 | print(a_str, "->", toHex(buf)); 132 | } 133 | r = bjson.read(buf, 0, buf.byteLength); 134 | r_str = toStr(r); 135 | if (a_str != r_str) { 136 | print(a_str); 137 | print(r_str); 138 | assert(false); 139 | } 140 | } 141 | 142 | function bjson_test_arraybuffer() 143 | { 144 | var buf, array_buffer; 145 | 146 | array_buffer = new ArrayBuffer(4); 147 | assert(array_buffer.byteLength, 4); 148 | assert(array_buffer.maxByteLength, 4); 149 | assert(array_buffer.resizable, false); 150 | buf = bjson.write(array_buffer); 151 | array_buffer = bjson.read(buf, 0, buf.byteLength); 152 | assert(array_buffer.byteLength, 4); 153 | assert(array_buffer.maxByteLength, 4); 154 | assert(array_buffer.resizable, false); 155 | 156 | array_buffer = new ArrayBuffer(4, {maxByteLength: 4}); 157 | assert(array_buffer.byteLength, 4); 158 | assert(array_buffer.maxByteLength, 4); 159 | assert(array_buffer.resizable, true); 160 | buf = bjson.write(array_buffer); 161 | array_buffer = bjson.read(buf, 0, buf.byteLength); 162 | assert(array_buffer.byteLength, 4); 163 | assert(array_buffer.maxByteLength, 4); 164 | assert(array_buffer.resizable, true); 165 | 166 | array_buffer = new ArrayBuffer(4, {maxByteLength: 8}); 167 | assert(array_buffer.byteLength, 4); 168 | assert(array_buffer.maxByteLength, 8); 169 | assert(array_buffer.resizable, true); 170 | buf = bjson.write(array_buffer); 171 | array_buffer = bjson.read(buf, 0, buf.byteLength); 172 | assert(array_buffer.byteLength, 4); 173 | assert(array_buffer.maxByteLength, 8); 174 | assert(array_buffer.resizable, true); 175 | } 176 | 177 | /* test multiple references to an object including circular 178 | references */ 179 | function bjson_test_reference() 180 | { 181 | var array, buf, i, n, array_buffer; 182 | n = 16; 183 | array = []; 184 | for(i = 0; i < n; i++) 185 | array[i] = {}; 186 | array_buffer = new ArrayBuffer(n); 187 | for(i = 0; i < n; i++) { 188 | array[i].next = array[(i + 1) % n]; 189 | array[i].idx = i; 190 | array[i].typed_array = new Uint8Array(array_buffer, i, 1); 191 | } 192 | buf = bjson.write(array, bjson.WRITE_OBJ_REFERENCE); 193 | 194 | array = bjson.read(buf, 0, buf.byteLength, bjson.READ_OBJ_REFERENCE); 195 | 196 | /* check the result */ 197 | for(i = 0; i < n; i++) { 198 | assert(array[i].next, array[(i + 1) % n]); 199 | assert(array[i].idx, i); 200 | assert(array[i].typed_array.buffer, array_buffer); 201 | assert(array[i].typed_array.length, 1); 202 | assert(array[i].typed_array.byteOffset, i); 203 | } 204 | } 205 | 206 | function bjson_test_regexp() 207 | { 208 | var buf, r; 209 | 210 | bjson_test(/xyzzy/); 211 | bjson_test(/xyzzy/digu); 212 | 213 | buf = bjson.write(/(?<𝓓𝓸𝓰>dog)/); 214 | r = bjson.read(buf, 0, buf.byteLength); 215 | assert("sup dog".match(r).groups["𝓓𝓸𝓰"], "dog"); 216 | } 217 | 218 | function bjson_test_map() 219 | { 220 | var buf, r, xs; 221 | 222 | xs = [["key", "value"]]; 223 | buf = bjson.write(new Map(xs)); 224 | r = bjson.read(buf, 0, buf.byteLength); 225 | assert(r instanceof Map); 226 | assert([...r].toString(), xs.toString()); 227 | } 228 | 229 | function bjson_test_set() 230 | { 231 | var buf, r, xs; 232 | 233 | xs = ["one", "two", "three"]; 234 | buf = bjson.write(new Set(xs)); 235 | r = bjson.read(buf, 0, buf.byteLength); 236 | assert(r instanceof Set); 237 | assert([...r].toString(), xs.toString()); 238 | } 239 | 240 | function bjson_test_symbol() 241 | { 242 | var buf, r, o; 243 | 244 | o = {[Symbol.toStringTag]: "42"}; 245 | buf = bjson.write(o); 246 | r = bjson.read(buf, 0, buf.byteLength); 247 | assert(o.toString(), r.toString()); 248 | 249 | o = Symbol('foo'); 250 | buf = bjson.write(o); 251 | r = bjson.read(buf, 0, buf.byteLength); 252 | assert(o.toString(), r.toString()); 253 | assert(o !== r); 254 | 255 | o = Symbol.for('foo'); 256 | buf = bjson.write(o); 257 | r = bjson.read(buf, 0, buf.byteLength); 258 | assert(o, r); 259 | 260 | o = Symbol.toStringTag; 261 | buf = bjson.write(o); 262 | r = bjson.read(buf, 0, buf.byteLength); 263 | assert(o, r); 264 | } 265 | 266 | function bjson_test_bytecode() 267 | { 268 | var buf, o, r, e, i; 269 | 270 | o = std.evalScript(";(function f(o){ return o.i })", {compile_only: true}); 271 | buf = bjson.write(o, /*JS_WRITE_OBJ_BYTECODE*/(1 << 0)); 272 | try { 273 | bjson.read(buf, 0, buf.byteLength); 274 | } catch (_e) { 275 | e = _e; 276 | } 277 | assert(String(e), "SyntaxError: no bytecode allowed"); 278 | 279 | o = bjson.read(buf, 0, buf.byteLength, /*JS_READ_OBJ_BYTECODE*/(1 << 0)); 280 | assert(String(o), "[function bytecode]"); 281 | o = std.evalScript(o, {eval_function: true}); 282 | for (i = 0; i < 42; i++) o({i}); // exercise o.i IC 283 | } 284 | 285 | function bjson_test_fuzz() 286 | { 287 | var corpus = [ 288 | "EBAAAAAABGA=", 289 | "EObm5oIt", 290 | "EAARABMGBgYGBgYGBgYGBv////8QABEALxH/vy8R/78=", 291 | ]; 292 | for (var input of corpus) { 293 | var buf = base64decode(input); 294 | try { 295 | bjson.read(buf, 0, buf.byteLength); 296 | } catch (e) { 297 | // okay, ignore 298 | } 299 | } 300 | } 301 | 302 | function bjson_test_all() 303 | { 304 | var obj; 305 | 306 | bjson_test({x:1, y:2, if:3}); 307 | bjson_test([1, 2, 3]); 308 | bjson_test([1.0, "aa", true, false, undefined, null, NaN, -Infinity, -0.0]); 309 | if (typeof BigInt !== "undefined") { 310 | bjson_test([BigInt("1"), -BigInt("0x123456789"), 311 | BigInt("0x123456789abcdef123456789abcdef")]); 312 | } 313 | 314 | bjson_test([new Date(1234), new String("abc"), new Number(-12.1), new Boolean(true)]); 315 | 316 | bjson_test(new Int32Array([123123, 222111, -32222])); 317 | bjson_test(new Float16Array([1024, 1024.5])); 318 | bjson_test(new Float64Array([123123, 222111.5])); 319 | 320 | /* tested with a circular reference */ 321 | obj = {}; 322 | obj.x = obj; 323 | try { 324 | bjson.write(obj); 325 | assert(false); 326 | } catch(e) { 327 | assert(e instanceof TypeError); 328 | } 329 | 330 | bjson_test_arraybuffer(); 331 | bjson_test_reference(); 332 | bjson_test_regexp(); 333 | bjson_test_map(); 334 | bjson_test_set(); 335 | bjson_test_symbol(); 336 | bjson_test_bytecode(); 337 | bjson_test_fuzz(); 338 | } 339 | 340 | bjson_test_all(); 341 | -------------------------------------------------------------------------------- /tests/test_closure.js: -------------------------------------------------------------------------------- 1 | // This test cannot use imports because it needs to run in non-strict mode. 2 | 3 | function assert(actual, expected, message) { 4 | if (arguments.length == 1) 5 | expected = true; 6 | 7 | if (actual === expected) 8 | return; 9 | 10 | if (actual !== null && expected !== null 11 | && typeof actual == 'object' && typeof expected == 'object' 12 | && actual.toString() === expected.toString()) 13 | return; 14 | 15 | throw Error("assertion failed: got |" + actual + "|" + 16 | ", expected |" + expected + "|" + 17 | (message ? " (" + message + ")" : "")); 18 | } 19 | 20 | /*----------------*/ 21 | 22 | var log_str = ""; 23 | 24 | function log(str) 25 | { 26 | log_str += str + ","; 27 | } 28 | 29 | function f(a, b, c) 30 | { 31 | var x = 10; 32 | log("a="+a); 33 | function g(d) { 34 | function h() { 35 | log("d=" + d); 36 | log("x=" + x); 37 | } 38 | log("b=" + b); 39 | log("c=" + c); 40 | h(); 41 | } 42 | g(4); 43 | return g; 44 | } 45 | 46 | var g1 = f(1, 2, 3); 47 | g1(5); 48 | 49 | assert(log_str, "a=1,b=2,c=3,d=4,x=10,b=2,c=3,d=5,x=10,", "closure1"); 50 | 51 | function test_closure1() 52 | { 53 | function f2() 54 | { 55 | var val = 1; 56 | 57 | function set(a) { 58 | val = a; 59 | } 60 | function get(a) { 61 | return val; 62 | } 63 | return { "set": set, "get": get }; 64 | } 65 | 66 | var obj = f2(); 67 | obj.set(10); 68 | var r; 69 | r = obj.get(); 70 | assert(r, 10, "closure2"); 71 | } 72 | 73 | function test_closure2() 74 | { 75 | var expr_func = function myfunc1(n) { 76 | function myfunc2(n) { 77 | return myfunc1(n - 1); 78 | } 79 | if (n == 0) 80 | return 0; 81 | else 82 | return myfunc2(n); 83 | }; 84 | var r; 85 | r = expr_func(1); 86 | assert(r, 0, "expr_func"); 87 | } 88 | 89 | function test_closure3() 90 | { 91 | function fib(n) 92 | { 93 | if (n <= 0) 94 | return 0; 95 | else if (n == 1) 96 | return 1; 97 | else 98 | return fib(n - 1) + fib(n - 2); 99 | } 100 | 101 | var fib_func = function fib1(n) 102 | { 103 | if (n <= 0) 104 | return 0; 105 | else if (n == 1) 106 | return 1; 107 | else 108 | return fib1(n - 1) + fib1(n - 2); 109 | }; 110 | 111 | assert(fib(6), 8, "fib"); 112 | assert(fib_func(6), 8, "fib_func"); 113 | } 114 | 115 | function test_arrow_function() 116 | { 117 | "use strict"; 118 | 119 | function f1() { 120 | return (() => arguments)(); 121 | } 122 | function f2() { 123 | return (() => this)(); 124 | } 125 | function f3() { 126 | return (() => eval("this"))(); 127 | } 128 | function f4() { 129 | return (() => eval("new.target"))(); 130 | } 131 | var a; 132 | 133 | a = f1(1, 2); 134 | assert(a.length, 2); 135 | assert(a[0] === 1 && a[1] === 2); 136 | 137 | assert(f2.call("this_val"), "this_val"); 138 | assert(f3.call("this_val"), "this_val"); 139 | assert(new f4(), f4); 140 | 141 | var o1 = { f() { return this; } }; 142 | var o2 = { f() { 143 | return (() => eval("super.f()"))(); 144 | } }; 145 | o2.__proto__ = o1; 146 | 147 | assert(o2.f(), o2); 148 | } 149 | 150 | function test_with() 151 | { 152 | var o1 = { x: "o1", y: "o1" }; 153 | var x = "local"; 154 | eval('var z="var_obj";'); 155 | assert(z, "var_obj"); 156 | with (o1) { 157 | assert(x, "o1"); 158 | assert(eval("x"), "o1"); 159 | var f = function () { 160 | o2 = { x: "o2" }; 161 | with (o2) { 162 | assert(x, "o2"); 163 | assert(y, "o1"); 164 | assert(z, "var_obj"); 165 | assert(eval("x"), "o2"); 166 | assert(eval("y"), "o1"); 167 | assert(eval("z"), "var_obj"); 168 | assert(eval('eval("x")'), "o2"); 169 | } 170 | }; 171 | f(); 172 | } 173 | } 174 | 175 | function test_eval_closure() 176 | { 177 | var tab; 178 | 179 | tab = []; 180 | for(let i = 0; i < 3; i++) { 181 | eval("tab.push(function g1() { return i; })"); 182 | } 183 | for(let i = 0; i < 3; i++) { 184 | assert(tab[i](), i); 185 | } 186 | 187 | tab = []; 188 | for(let i = 0; i < 3; i++) { 189 | let f = function f() { 190 | eval("tab.push(function g2() { return i; })"); 191 | }; 192 | f(); 193 | } 194 | for(let i = 0; i < 3; i++) { 195 | assert(tab[i](), i); 196 | } 197 | } 198 | 199 | function test_eval_const() 200 | { 201 | const a = 1; 202 | var success = false; 203 | var f = function () { 204 | eval("a = 1"); 205 | }; 206 | try { 207 | f(); 208 | } catch(e) { 209 | success = (e instanceof TypeError); 210 | } 211 | assert(success); 212 | } 213 | 214 | test_closure1(); 215 | test_closure2(); 216 | test_closure3(); 217 | test_arrow_function(); 218 | test_with(); 219 | test_eval_closure(); 220 | test_eval_const(); 221 | -------------------------------------------------------------------------------- /tests/test_cyclic_import.js: -------------------------------------------------------------------------------- 1 | /*--- 2 | negative: 3 | phase: resolution 4 | type: SyntaxError 5 | ---*/ 6 | // FIXME(bnoordhuis) shouldn't throw SyntaxError but that's still better 7 | // than segfaulting, see https://github.com/quickjs-ng/quickjs/issues/567 8 | import {assert} from "./assert.js" 9 | import {f} from "./fixture_cyclic_import.js" 10 | export {f} 11 | export function g(x) { return x + 1 } 12 | assert(f(1), 4) 13 | -------------------------------------------------------------------------------- /tests/test_loop.js: -------------------------------------------------------------------------------- 1 | // This test cannot use imports because it needs to run in non-strict mode. 2 | 3 | function assert(actual, expected, message) { 4 | if (arguments.length == 1) 5 | expected = true; 6 | 7 | if (actual === expected) 8 | return; 9 | 10 | if (actual !== null && expected !== null 11 | && typeof actual == 'object' && typeof expected == 'object' 12 | && actual.toString() === expected.toString()) 13 | return; 14 | 15 | throw Error("assertion failed: got |" + actual + "|" + 16 | ", expected |" + expected + "|" + 17 | (message ? " (" + message + ")" : "")); 18 | } 19 | 20 | /*----------------*/ 21 | 22 | function test_while() 23 | { 24 | var i, c; 25 | i = 0; 26 | c = 0; 27 | while (i < 3) { 28 | c++; 29 | i++; 30 | } 31 | assert(c, 3); 32 | } 33 | 34 | function test_while_break() 35 | { 36 | var i, c; 37 | i = 0; 38 | c = 0; 39 | while (i < 3) { 40 | c++; 41 | if (i == 1) 42 | break; 43 | i++; 44 | } 45 | assert(c === 2 && i === 1); 46 | } 47 | 48 | function test_do_while() 49 | { 50 | var i, c; 51 | i = 0; 52 | c = 0; 53 | do { 54 | c++; 55 | i++; 56 | } while (i < 3); 57 | assert(c === 3 && i === 3); 58 | } 59 | 60 | function test_for() 61 | { 62 | var i, c; 63 | c = 0; 64 | for(i = 0; i < 3; i++) { 65 | c++; 66 | } 67 | assert(c === 3 && i === 3); 68 | 69 | c = 0; 70 | for(var j = 0; j < 3; j++) { 71 | c++; 72 | } 73 | assert(c === 3 && j === 3); 74 | } 75 | 76 | function test_for_in() 77 | { 78 | var i, tab, a, b; 79 | 80 | tab = []; 81 | for(i in {x:1, y: 2}) { 82 | tab.push(i); 83 | } 84 | assert(tab.toString(), "x,y", "for_in"); 85 | 86 | /* prototype chain test */ 87 | a = {x:2, y: 2, "1": 3}; 88 | b = {"4" : 3 }; 89 | Object.setPrototypeOf(a, b); 90 | tab = []; 91 | for(i in a) { 92 | tab.push(i); 93 | } 94 | assert(tab.toString(), "1,x,y,4", "for_in"); 95 | 96 | /* non enumerable properties hide enumerables ones in the 97 | prototype chain */ 98 | a = {y: 2, "1": 3}; 99 | Object.defineProperty(a, "x", { value: 1 }); 100 | b = {"x" : 3 }; 101 | Object.setPrototypeOf(a, b); 102 | tab = []; 103 | for(i in a) { 104 | tab.push(i); 105 | } 106 | assert(tab.toString(), "1,y", "for_in"); 107 | 108 | /* array optimization */ 109 | a = []; 110 | for(i = 0; i < 10; i++) 111 | a.push(i); 112 | tab = []; 113 | for(i in a) { 114 | tab.push(i); 115 | } 116 | assert(tab.toString(), "0,1,2,3,4,5,6,7,8,9", "for_in"); 117 | 118 | /* iterate with a field */ 119 | a={x:0}; 120 | tab = []; 121 | for(a.x in {x:1, y: 2}) { 122 | tab.push(a.x); 123 | } 124 | assert(tab.toString(), "x,y", "for_in"); 125 | 126 | /* iterate with a variable field */ 127 | a=[0]; 128 | tab = []; 129 | for(a[0] in {x:1, y: 2}) { 130 | tab.push(a[0]); 131 | } 132 | assert(tab.toString(), "x,y", "for_in"); 133 | 134 | /* variable definition in the for in */ 135 | tab = []; 136 | for(var j in {x:1, y: 2}) { 137 | tab.push(j); 138 | } 139 | assert(tab.toString(), "x,y", "for_in"); 140 | 141 | /* variable assigment in the for in */ 142 | tab = []; 143 | for(var k = 2 in {x:1, y: 2}) { 144 | tab.push(k); 145 | } 146 | assert(tab.toString(), "x,y", "for_in"); 147 | } 148 | 149 | function test_for_in2() 150 | { 151 | var i; 152 | tab = []; 153 | for(i in {x:1, y: 2, z:3}) { 154 | if (i === "y") 155 | continue; 156 | tab.push(i); 157 | } 158 | assert(tab.toString() == "x,z"); 159 | 160 | tab = []; 161 | for(i in {x:1, y: 2, z:3}) { 162 | if (i === "z") 163 | break; 164 | tab.push(i); 165 | } 166 | assert(tab.toString() == "x,y"); 167 | } 168 | 169 | function test_for_break() 170 | { 171 | var i, c; 172 | c = 0; 173 | L1: for(i = 0; i < 3; i++) { 174 | c++; 175 | if (i == 0) 176 | continue; 177 | while (1) { 178 | break L1; 179 | } 180 | } 181 | assert(c === 2 && i === 1); 182 | } 183 | 184 | function test_switch1() 185 | { 186 | var i, a, s; 187 | s = ""; 188 | for(i = 0; i < 3; i++) { 189 | a = "?"; 190 | switch(i) { 191 | case 0: 192 | a = "a"; 193 | break; 194 | case 1: 195 | a = "b"; 196 | break; 197 | default: 198 | a = "c"; 199 | break; 200 | } 201 | s += a; 202 | } 203 | assert(s === "abc" && i === 3); 204 | } 205 | 206 | function test_switch2() 207 | { 208 | var i, a, s; 209 | s = ""; 210 | for(i = 0; i < 4; i++) { 211 | a = "?"; 212 | switch(i) { 213 | case 0: 214 | a = "a"; 215 | break; 216 | case 1: 217 | a = "b"; 218 | break; 219 | case 2: 220 | continue; 221 | default: 222 | a = "" + i; 223 | break; 224 | } 225 | s += a; 226 | } 227 | assert(s === "ab3" && i === 4); 228 | } 229 | 230 | function test_try_catch1() 231 | { 232 | try { 233 | throw "hello"; 234 | } catch (e) { 235 | assert(e, "hello", "catch"); 236 | return; 237 | } 238 | assert(false, "catch"); 239 | } 240 | 241 | function test_try_catch2() 242 | { 243 | var a; 244 | try { 245 | a = 1; 246 | } catch (e) { 247 | a = 2; 248 | } 249 | assert(a, 1, "catch"); 250 | } 251 | 252 | function test_try_catch3() 253 | { 254 | var s; 255 | s = ""; 256 | try { 257 | s += "t"; 258 | } catch (e) { 259 | s += "c"; 260 | } finally { 261 | s += "f"; 262 | } 263 | assert(s, "tf", "catch"); 264 | } 265 | 266 | function test_try_catch4() 267 | { 268 | var s; 269 | s = ""; 270 | try { 271 | s += "t"; 272 | throw "c"; 273 | } catch (e) { 274 | s += e; 275 | } finally { 276 | s += "f"; 277 | } 278 | assert(s, "tcf", "catch"); 279 | } 280 | 281 | function test_try_catch5() 282 | { 283 | var s; 284 | s = ""; 285 | for(;;) { 286 | try { 287 | s += "t"; 288 | break; 289 | s += "b"; 290 | } finally { 291 | s += "f"; 292 | } 293 | } 294 | assert(s, "tf", "catch"); 295 | } 296 | 297 | function test_try_catch6() 298 | { 299 | function f() { 300 | try { 301 | s += 't'; 302 | return 1; 303 | } finally { 304 | s += "f"; 305 | } 306 | } 307 | var s = ""; 308 | assert(f() === 1); 309 | assert(s, "tf", "catch6"); 310 | } 311 | 312 | function test_try_catch7() 313 | { 314 | var s; 315 | s = ""; 316 | 317 | try { 318 | try { 319 | s += "t"; 320 | throw "a"; 321 | } finally { 322 | s += "f"; 323 | } 324 | } catch(e) { 325 | s += e; 326 | } finally { 327 | s += "g"; 328 | } 329 | assert(s, "tfag", "catch"); 330 | } 331 | 332 | function test_try_catch8() 333 | { 334 | var i, s; 335 | 336 | s = ""; 337 | for(var i in {x:1, y:2}) { 338 | try { 339 | s += i; 340 | throw "a"; 341 | } catch (e) { 342 | s += e; 343 | } finally { 344 | s += "f"; 345 | } 346 | } 347 | assert(s === "xafyaf"); 348 | } 349 | 350 | test_while(); 351 | test_while_break(); 352 | test_do_while(); 353 | test_for(); 354 | test_for_break(); 355 | test_switch1(); 356 | test_switch2(); 357 | test_for_in(); 358 | test_for_in2(); 359 | 360 | test_try_catch1(); 361 | test_try_catch2(); 362 | test_try_catch3(); 363 | test_try_catch4(); 364 | test_try_catch5(); 365 | test_try_catch6(); 366 | test_try_catch7(); 367 | test_try_catch8(); 368 | -------------------------------------------------------------------------------- /tests/test_queue_microtask.js: -------------------------------------------------------------------------------- 1 | import { assert, assertArrayEquals, assertThrows } from "./assert.js"; 2 | 3 | function test_types() { 4 | assertThrows(TypeError, () => queueMicrotask(), "no argument"); 5 | assertThrows(TypeError, () => queueMicrotask(undefined), "undefined"); 6 | assertThrows(TypeError, () => queueMicrotask(null), "null"); 7 | assertThrows(TypeError, () => queueMicrotask(0), "0"); 8 | assertThrows(TypeError, () => queueMicrotask({ handleEvent() { } }), "an event handler object"); 9 | assertThrows(TypeError, () => queueMicrotask("window.x = 5;"), "a string"); 10 | } 11 | 12 | function test_async() { 13 | let called = false; 14 | queueMicrotask(() => { 15 | called = true; 16 | }); 17 | assert(!called); 18 | } 19 | 20 | function test_arguments() { 21 | queueMicrotask(function () { // note: intentionally not an arrow function 22 | assert(arguments.length === 0); 23 | }, "x", "y"); 24 | }; 25 | 26 | function test_async_order() { 27 | const happenings = []; 28 | Promise.resolve().then(() => happenings.push("a")); 29 | queueMicrotask(() => happenings.push("b")); 30 | Promise.reject().catch(() => happenings.push("c")); 31 | queueMicrotask(() => { 32 | assertArrayEquals(happenings, ["a", "b", "c"]); 33 | }); 34 | } 35 | 36 | test_types(); 37 | test_async(); 38 | test_arguments(); 39 | test_async_order(); 40 | -------------------------------------------------------------------------------- /tests/test_std.js: -------------------------------------------------------------------------------- 1 | import * as std from "qjs:std"; 2 | import * as os from "qjs:os"; 3 | import { assert } from "./assert.js"; 4 | 5 | const isWin = os.platform === 'win32'; 6 | const isCygwin = os.platform === 'cygwin'; 7 | 8 | 9 | function test_printf() 10 | { 11 | assert(std.sprintf("a=%d s=%s", 123, "abc"), "a=123 s=abc"); 12 | assert(std.sprintf("%010d", 123), "0000000123"); 13 | assert(std.sprintf("%x", -2), "fffffffe"); 14 | assert(std.sprintf("%lx", -2), "fffffffffffffffe"); 15 | assert(std.sprintf("%10.1f", 2.1), " 2.1"); 16 | assert(std.sprintf("%*.*f", 10, 2, -2.13), " -2.13"); 17 | assert(std.sprintf("%#lx", 0x7fffffffffffffffn), "0x7fffffffffffffff"); 18 | } 19 | 20 | function test_file1() 21 | { 22 | var f, len, str, size, buf, ret, i, str1; 23 | 24 | f = std.tmpfile(); 25 | str = "hello world\n"; 26 | f.puts(str); 27 | 28 | f.seek(0, std.SEEK_SET); 29 | str1 = f.readAsString(); 30 | assert(str1, str); 31 | 32 | f.seek(0, std.SEEK_END); 33 | size = f.tell(); 34 | assert(size, str.length); 35 | 36 | f.seek(0, std.SEEK_SET); 37 | 38 | buf = new Uint8Array(size); 39 | ret = f.read(buf.buffer, 0, size); 40 | assert(ret, size); 41 | for(i = 0; i < size; i++) 42 | assert(buf[i], str.charCodeAt(i)); 43 | 44 | f.close(); 45 | } 46 | 47 | function test_file2() 48 | { 49 | var f, str, i, size; 50 | f = std.tmpfile(); 51 | str = "hello world\n"; 52 | size = str.length; 53 | for(i = 0; i < size; i++) 54 | f.putByte(str.charCodeAt(i)); 55 | f.seek(0, std.SEEK_SET); 56 | for(i = 0; i < size; i++) { 57 | assert(str.charCodeAt(i), f.getByte()); 58 | } 59 | assert(f.getByte(), -1); 60 | f.close(); 61 | } 62 | 63 | function test_getline() 64 | { 65 | var f, line, line_count, lines, i; 66 | 67 | lines = ["hello world", "line 1", "line 2" ]; 68 | f = std.tmpfile(); 69 | for(i = 0; i < lines.length; i++) { 70 | f.puts(lines[i], "\n"); 71 | } 72 | 73 | f.seek(0, std.SEEK_SET); 74 | assert(!f.eof()); 75 | line_count = 0; 76 | for(;;) { 77 | line = f.getline(); 78 | if (line === null) 79 | break; 80 | assert(line, lines[line_count]); 81 | line_count++; 82 | } 83 | assert(f.eof()); 84 | assert(line_count, lines.length); 85 | 86 | f.close(); 87 | } 88 | 89 | function test_popen() 90 | { 91 | var str, f, fname = "tmp_file.txt"; 92 | var content = "hello world"; 93 | var cmd = isWin ? "type" : "cat"; 94 | 95 | f = std.open(fname, "w"); 96 | f.puts(content); 97 | f.close(); 98 | 99 | /* test loadFile */ 100 | assert(std.loadFile(fname), content); 101 | 102 | /* execute shell command */ 103 | f = std.popen(cmd + " " + fname, "r"); 104 | str = f.readAsString(); 105 | f.close(); 106 | 107 | assert(str, content); 108 | 109 | os.remove(fname); 110 | } 111 | 112 | function test_os() 113 | { 114 | var fd, fpath, fname, fdir, buf, buf2, i, files, err, fdate, st, link_path; 115 | 116 | // XXX(bnoordhuis) disabled because stdio is not a tty on CI 117 | //assert(os.isatty(0)); 118 | 119 | fdir = "test_tmp_dir"; 120 | fname = "tmp_file.txt"; 121 | fpath = fdir + "/" + fname; 122 | link_path = fdir + "/test_link"; 123 | 124 | os.remove(link_path); 125 | os.remove(fpath); 126 | os.remove(fdir); 127 | 128 | err = os.mkdir(fdir, 0o755); 129 | assert(err, 0); 130 | 131 | fd = os.open(fpath, os.O_RDWR | os.O_CREAT | os.O_TRUNC); 132 | assert(fd >= 0); 133 | 134 | buf = new Uint8Array(10); 135 | for(i = 0; i < buf.length; i++) 136 | buf[i] = i; 137 | assert(os.write(fd, buf.buffer, 0, buf.length), buf.length); 138 | 139 | assert(os.seek(fd, 0, std.SEEK_SET), 0); 140 | buf2 = new Uint8Array(buf.length); 141 | assert(os.read(fd, buf2.buffer, 0, buf2.length), buf2.length); 142 | 143 | for(i = 0; i < buf.length; i++) 144 | assert(buf[i] == buf2[i]); 145 | 146 | if (typeof BigInt !== "undefined") { 147 | assert(os.seek(fd, BigInt(6), std.SEEK_SET), BigInt(6)); 148 | assert(os.read(fd, buf2.buffer, 0, 1), 1); 149 | assert(buf[6] == buf2[0]); 150 | } 151 | 152 | assert(os.close(fd), 0); 153 | 154 | [files, err] = os.readdir(fdir); 155 | assert(err, 0); 156 | assert(files.indexOf(fname) >= 0); 157 | 158 | fdate = 10000; 159 | 160 | err = os.utimes(fpath, fdate, fdate); 161 | assert(err, 0); 162 | 163 | [st, err] = os.stat(fpath); 164 | assert(err, 0); 165 | assert(st.mode & os.S_IFMT, os.S_IFREG); 166 | assert(st.mtime, fdate); 167 | 168 | if (!isWin) { 169 | err = os.symlink(fname, link_path); 170 | assert(err, 0); 171 | 172 | [st, err] = os.lstat(link_path); 173 | assert(err, 0); 174 | assert(st.mode & os.S_IFMT, os.S_IFLNK); 175 | 176 | [buf, err] = os.readlink(link_path); 177 | assert(err, 0); 178 | assert(buf, fname); 179 | 180 | assert(os.remove(link_path) === 0); 181 | } 182 | 183 | [buf, err] = os.getcwd(); 184 | assert(err, 0); 185 | 186 | [buf2, err] = os.realpath("."); 187 | assert(err, 0); 188 | 189 | assert(buf, buf2); 190 | 191 | assert(os.remove(fpath) === 0); 192 | 193 | fd = os.open(fpath, os.O_RDONLY); 194 | assert(fd < 0); 195 | 196 | assert(os.remove(fdir) === 0); 197 | } 198 | 199 | function test_os_exec() 200 | { 201 | var ret, fds, pid, f, status; 202 | 203 | ret = os.exec(["true"]); 204 | assert(ret, 0); 205 | 206 | ret = os.exec(["/bin/sh", "-c", "exit 1"], { usePath: false }); 207 | assert(ret, 1); 208 | 209 | fds = os.pipe(); 210 | pid = os.exec(["sh", "-c", "echo $FOO"], { 211 | stdout: fds[1], 212 | block: false, 213 | env: { FOO: "hello" }, 214 | } ); 215 | assert(pid >= 0); 216 | os.close(fds[1]); /* close the write end (as it is only in the child) */ 217 | f = std.fdopen(fds[0], "r"); 218 | assert(f.getline(), "hello"); 219 | assert(f.getline(), null); 220 | f.close(); 221 | [ret, status] = os.waitpid(pid, 0); 222 | assert(ret, pid); 223 | assert(status & 0x7f, 0); /* exited */ 224 | assert(status >> 8, 0); /* exit code */ 225 | 226 | pid = os.exec(["cat"], { block: false } ); 227 | assert(pid >= 0); 228 | os.kill(pid, os.SIGTERM); 229 | [ret, status] = os.waitpid(pid, 0); 230 | assert(ret, pid); 231 | // Flaky on cygwin for unclear reasons, see 232 | // https://github.com/quickjs-ng/quickjs/issues/184 233 | if (!isCygwin) { 234 | assert(status & 0x7f, os.SIGTERM); 235 | } 236 | } 237 | 238 | function test_interval() 239 | { 240 | var t = os.setInterval(f, 1); 241 | function f() { 242 | if (++f.count === 3) os.clearInterval(t); 243 | } 244 | f.count = 0; 245 | } 246 | 247 | function test_timeout() 248 | { 249 | var th, i; 250 | 251 | /* just test that a timer can be inserted and removed */ 252 | th = []; 253 | for(i = 0; i < 3; i++) 254 | th[i] = os.setTimeout(function () { }, 1000); 255 | for(i = 0; i < 3; i++) 256 | os.clearTimeout(th[i]); 257 | } 258 | 259 | function test_timeout_order() 260 | { 261 | var s = ""; 262 | os.setTimeout(a, 0); 263 | os.setTimeout(b, 100); 264 | os.setTimeout(d, 700); 265 | function a() { s += "a"; os.setTimeout(c, 300); } 266 | function b() { s += "b"; } 267 | function c() { s += "c"; } 268 | function d() { assert(s, "abc"); } // not "acb" 269 | } 270 | 271 | function test_stdio_close() 272 | { 273 | for (const f of [std.in, std.out, std.err]) { 274 | let caught = false; 275 | try { 276 | f.close(); 277 | } catch (e) { 278 | assert(/cannot close stdio/.test(e.message)); 279 | caught = true; 280 | } 281 | assert(caught); 282 | } 283 | } 284 | 285 | test_printf(); 286 | test_file1(); 287 | test_file2(); 288 | test_getline(); 289 | test_popen(); 290 | test_os(); 291 | !isWin && test_os_exec(); 292 | test_interval(); 293 | test_timeout(); 294 | test_timeout_order(); 295 | test_stdio_close(); 296 | -------------------------------------------------------------------------------- /tests/test_worker.js: -------------------------------------------------------------------------------- 1 | import * as os from "qjs:os"; 2 | import { assert } from "./assert.js"; 3 | 4 | var worker; 5 | 6 | function test_worker() 7 | { 8 | var counter; 9 | 10 | worker = new os.Worker("./test_worker_module.js"); 11 | 12 | counter = 0; 13 | worker.onmessage = function (e) { 14 | var ev = e.data; 15 | // print("recv", JSON.stringify(ev)); 16 | switch(ev.type) { 17 | case "num": 18 | assert(ev.num, counter); 19 | counter++; 20 | if (counter == 10) { 21 | /* test SharedArrayBuffer modification */ 22 | let sab = new SharedArrayBuffer(10); 23 | let buf = new Uint8Array(sab); 24 | worker.postMessage({ type: "sab", buf: buf }); 25 | } 26 | break; 27 | case "sab_done": 28 | { 29 | let buf = ev.buf; 30 | /* check that the SharedArrayBuffer was modified */ 31 | assert(buf[2], 10); 32 | worker.postMessage({ type: "abort" }); 33 | } 34 | break; 35 | case "done": 36 | /* terminate */ 37 | worker.onmessage = null; 38 | break; 39 | } 40 | }; 41 | } 42 | 43 | if (os.platform !== 'win32') { 44 | test_worker(); 45 | } 46 | -------------------------------------------------------------------------------- /tests/test_worker_module.js: -------------------------------------------------------------------------------- 1 | /* Worker code for test_worker.js */ 2 | import * as os from "qjs:os"; 3 | 4 | var parent = os.Worker.parent; 5 | 6 | function handle_msg(e) { 7 | var ev = e.data; 8 | // print("child_recv", JSON.stringify(ev)); 9 | switch(ev.type) { 10 | case "abort": 11 | parent.postMessage({ type: "done" }); 12 | break; 13 | case "sab": 14 | /* modify the SharedArrayBuffer */ 15 | ev.buf[2] = 10; 16 | parent.postMessage({ type: "sab_done", buf: ev.buf }); 17 | break; 18 | } 19 | } 20 | 21 | function worker_main() { 22 | var i; 23 | 24 | parent.onmessage = handle_msg; 25 | for(i = 0; i < 10; i++) { 26 | parent.postMessage({ type: "num", num: i }); 27 | } 28 | } 29 | 30 | worker_main(); 31 | -------------------------------------------------------------------------------- /unicode_download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | url="ftp://ftp.unicode.org/Public/16.0.0/ucd" 5 | emoji_url="${url}/emoji/emoji-data.txt" 6 | 7 | files="CaseFolding.txt DerivedNormalizationProps.txt PropList.txt \ 8 | SpecialCasing.txt CompositionExclusions.txt ScriptExtensions.txt \ 9 | UnicodeData.txt DerivedCoreProperties.txt NormalizationTest.txt Scripts.txt \ 10 | PropertyValueAliases.txt" 11 | 12 | mkdir -p unicode 13 | 14 | for f in $files; do 15 | g="${url}/${f}" 16 | wget $g -O unicode/$f 17 | done 18 | 19 | wget $emoji_url -O unicode/emoji-data.txt 20 | -------------------------------------------------------------------------------- /unicode_gen_def.h: -------------------------------------------------------------------------------- 1 | #ifdef UNICODE_GENERAL_CATEGORY 2 | DEF(Cn, "Unassigned") /* must be zero */ 3 | DEF(Lu, "Uppercase_Letter") 4 | DEF(Ll, "Lowercase_Letter") 5 | DEF(Lt, "Titlecase_Letter") 6 | DEF(Lm, "Modifier_Letter") 7 | DEF(Lo, "Other_Letter") 8 | DEF(Mn, "Nonspacing_Mark") 9 | DEF(Mc, "Spacing_Mark") 10 | DEF(Me, "Enclosing_Mark") 11 | DEF(Nd, "Decimal_Number,digit") 12 | DEF(Nl, "Letter_Number") 13 | DEF(No, "Other_Number") 14 | DEF(Sm, "Math_Symbol") 15 | DEF(Sc, "Currency_Symbol") 16 | DEF(Sk, "Modifier_Symbol") 17 | DEF(So, "Other_Symbol") 18 | DEF(Pc, "Connector_Punctuation") 19 | DEF(Pd, "Dash_Punctuation") 20 | DEF(Ps, "Open_Punctuation") 21 | DEF(Pe, "Close_Punctuation") 22 | DEF(Pi, "Initial_Punctuation") 23 | DEF(Pf, "Final_Punctuation") 24 | DEF(Po, "Other_Punctuation") 25 | DEF(Zs, "Space_Separator") 26 | DEF(Zl, "Line_Separator") 27 | DEF(Zp, "Paragraph_Separator") 28 | DEF(Cc, "Control,cntrl") 29 | DEF(Cf, "Format") 30 | DEF(Cs, "Surrogate") 31 | DEF(Co, "Private_Use") 32 | /* synthetic properties */ 33 | DEF(LC, "Cased_Letter") 34 | DEF(L, "Letter") 35 | DEF(M, "Mark,Combining_Mark") 36 | DEF(N, "Number") 37 | DEF(S, "Symbol") 38 | DEF(P, "Punctuation,punct") 39 | DEF(Z, "Separator") 40 | DEF(C, "Other") 41 | #endif 42 | 43 | #ifdef UNICODE_SCRIPT 44 | /* scripts aliases names in PropertyValueAliases.txt */ 45 | DEF(Unknown, "Zzzz") 46 | DEF(Adlam, "Adlm") 47 | DEF(Ahom, "Ahom") 48 | DEF(Anatolian_Hieroglyphs, "Hluw") 49 | DEF(Arabic, "Arab") 50 | DEF(Armenian, "Armn") 51 | DEF(Avestan, "Avst") 52 | DEF(Balinese, "Bali") 53 | DEF(Bamum, "Bamu") 54 | DEF(Bassa_Vah, "Bass") 55 | DEF(Batak, "Batk") 56 | DEF(Bengali, "Beng") 57 | DEF(Bhaiksuki, "Bhks") 58 | DEF(Bopomofo, "Bopo") 59 | DEF(Brahmi, "Brah") 60 | DEF(Braille, "Brai") 61 | DEF(Buginese, "Bugi") 62 | DEF(Buhid, "Buhd") 63 | DEF(Canadian_Aboriginal, "Cans") 64 | DEF(Carian, "Cari") 65 | DEF(Caucasian_Albanian, "Aghb") 66 | DEF(Chakma, "Cakm") 67 | DEF(Cham, "Cham") 68 | DEF(Cherokee, "Cher") 69 | DEF(Chorasmian, "Chrs") 70 | DEF(Common, "Zyyy") 71 | DEF(Coptic, "Copt,Qaac") 72 | DEF(Cuneiform, "Xsux") 73 | DEF(Cypriot, "Cprt") 74 | DEF(Cyrillic, "Cyrl") 75 | DEF(Cypro_Minoan, "Cpmn") 76 | DEF(Deseret, "Dsrt") 77 | DEF(Devanagari, "Deva") 78 | DEF(Dives_Akuru, "Diak") 79 | DEF(Dogra, "Dogr") 80 | DEF(Duployan, "Dupl") 81 | DEF(Egyptian_Hieroglyphs, "Egyp") 82 | DEF(Elbasan, "Elba") 83 | DEF(Elymaic, "Elym") 84 | DEF(Ethiopic, "Ethi") 85 | DEF(Georgian, "Geor") 86 | DEF(Glagolitic, "Glag") 87 | DEF(Gothic, "Goth") 88 | DEF(Garay, "Gara") 89 | DEF(Grantha, "Gran") 90 | DEF(Greek, "Grek") 91 | DEF(Gujarati, "Gujr") 92 | DEF(Gunjala_Gondi, "Gong") 93 | DEF(Gurmukhi, "Guru") 94 | DEF(Gurung_Khema, "Gukh") 95 | DEF(Han, "Hani") 96 | DEF(Hangul, "Hang") 97 | DEF(Hanifi_Rohingya, "Rohg") 98 | DEF(Hanunoo, "Hano") 99 | DEF(Hatran, "Hatr") 100 | DEF(Hebrew, "Hebr") 101 | DEF(Hiragana, "Hira") 102 | DEF(Imperial_Aramaic, "Armi") 103 | DEF(Inherited, "Zinh,Qaai") 104 | DEF(Inscriptional_Pahlavi, "Phli") 105 | DEF(Inscriptional_Parthian, "Prti") 106 | DEF(Javanese, "Java") 107 | DEF(Kaithi, "Kthi") 108 | DEF(Kannada, "Knda") 109 | DEF(Katakana, "Kana") 110 | DEF(Kawi, "Kawi") 111 | DEF(Kayah_Li, "Kali") 112 | DEF(Kharoshthi, "Khar") 113 | DEF(Khmer, "Khmr") 114 | DEF(Khojki, "Khoj") 115 | DEF(Khitan_Small_Script, "Kits") 116 | DEF(Khudawadi, "Sind") 117 | DEF(Kirat_Rai, "Krai") 118 | DEF(Lao, "Laoo") 119 | DEF(Latin, "Latn") 120 | DEF(Lepcha, "Lepc") 121 | DEF(Limbu, "Limb") 122 | DEF(Linear_A, "Lina") 123 | DEF(Linear_B, "Linb") 124 | DEF(Lisu, "Lisu") 125 | DEF(Lycian, "Lyci") 126 | DEF(Lydian, "Lydi") 127 | DEF(Makasar, "Maka") 128 | DEF(Mahajani, "Mahj") 129 | DEF(Malayalam, "Mlym") 130 | DEF(Mandaic, "Mand") 131 | DEF(Manichaean, "Mani") 132 | DEF(Marchen, "Marc") 133 | DEF(Masaram_Gondi, "Gonm") 134 | DEF(Medefaidrin, "Medf") 135 | DEF(Meetei_Mayek, "Mtei") 136 | DEF(Mende_Kikakui, "Mend") 137 | DEF(Meroitic_Cursive, "Merc") 138 | DEF(Meroitic_Hieroglyphs, "Mero") 139 | DEF(Miao, "Plrd") 140 | DEF(Modi, "Modi") 141 | DEF(Mongolian, "Mong") 142 | DEF(Mro, "Mroo") 143 | DEF(Multani, "Mult") 144 | DEF(Myanmar, "Mymr") 145 | DEF(Nabataean, "Nbat") 146 | DEF(Nag_Mundari, "Nagm") 147 | DEF(Nandinagari, "Nand") 148 | DEF(New_Tai_Lue, "Talu") 149 | DEF(Newa, "Newa") 150 | DEF(Nko, "Nkoo") 151 | DEF(Nushu, "Nshu") 152 | DEF(Nyiakeng_Puachue_Hmong, "Hmnp") 153 | DEF(Ogham, "Ogam") 154 | DEF(Ol_Chiki, "Olck") 155 | DEF(Ol_Onal, "Onao") 156 | DEF(Old_Hungarian, "Hung") 157 | DEF(Old_Italic, "Ital") 158 | DEF(Old_North_Arabian, "Narb") 159 | DEF(Old_Permic, "Perm") 160 | DEF(Old_Persian, "Xpeo") 161 | DEF(Old_Sogdian, "Sogo") 162 | DEF(Old_South_Arabian, "Sarb") 163 | DEF(Old_Turkic, "Orkh") 164 | DEF(Old_Uyghur, "Ougr") 165 | DEF(Oriya, "Orya") 166 | DEF(Osage, "Osge") 167 | DEF(Osmanya, "Osma") 168 | DEF(Pahawh_Hmong, "Hmng") 169 | DEF(Palmyrene, "Palm") 170 | DEF(Pau_Cin_Hau, "Pauc") 171 | DEF(Phags_Pa, "Phag") 172 | DEF(Phoenician, "Phnx") 173 | DEF(Psalter_Pahlavi, "Phlp") 174 | DEF(Rejang, "Rjng") 175 | DEF(Runic, "Runr") 176 | DEF(Samaritan, "Samr") 177 | DEF(Saurashtra, "Saur") 178 | DEF(Sharada, "Shrd") 179 | DEF(Shavian, "Shaw") 180 | DEF(Siddham, "Sidd") 181 | DEF(SignWriting, "Sgnw") 182 | DEF(Sinhala, "Sinh") 183 | DEF(Sogdian, "Sogd") 184 | DEF(Sora_Sompeng, "Sora") 185 | DEF(Soyombo, "Soyo") 186 | DEF(Sundanese, "Sund") 187 | DEF(Sunuwar, "Sunu") 188 | DEF(Syloti_Nagri, "Sylo") 189 | DEF(Syriac, "Syrc") 190 | DEF(Tagalog, "Tglg") 191 | DEF(Tagbanwa, "Tagb") 192 | DEF(Tai_Le, "Tale") 193 | DEF(Tai_Tham, "Lana") 194 | DEF(Tai_Viet, "Tavt") 195 | DEF(Takri, "Takr") 196 | DEF(Tamil, "Taml") 197 | DEF(Tangut, "Tang") 198 | DEF(Telugu, "Telu") 199 | DEF(Thaana, "Thaa") 200 | DEF(Thai, "Thai") 201 | DEF(Tibetan, "Tibt") 202 | DEF(Tifinagh, "Tfng") 203 | DEF(Tirhuta, "Tirh") 204 | DEF(Tangsa, "Tnsa") 205 | DEF(Todhri, "Todr") 206 | DEF(Toto, "Toto") 207 | DEF(Tulu_Tigalari, "Tutg") 208 | DEF(Ugaritic, "Ugar") 209 | DEF(Vai, "Vaii") 210 | DEF(Vithkuqi, "Vith") 211 | DEF(Wancho, "Wcho") 212 | DEF(Warang_Citi, "Wara") 213 | DEF(Yezidi, "Yezi") 214 | DEF(Yi, "Yiii") 215 | DEF(Zanabazar_Square, "Zanb") 216 | #endif 217 | 218 | #ifdef UNICODE_PROP_LIST 219 | /* Prop list not exported to regexp */ 220 | DEF(Hyphen, "") 221 | DEF(Other_Math, "") 222 | DEF(Other_Alphabetic, "") 223 | DEF(Other_Lowercase, "") 224 | DEF(Other_Uppercase, "") 225 | DEF(Other_Grapheme_Extend, "") 226 | DEF(Other_Default_Ignorable_Code_Point, "") 227 | DEF(Other_ID_Start, "") 228 | DEF(Other_ID_Continue, "") 229 | DEF(Prepended_Concatenation_Mark, "") 230 | /* additional computed properties for smaller tables */ 231 | DEF(ID_Continue1, "") 232 | DEF(XID_Start1, "") 233 | DEF(XID_Continue1, "") 234 | DEF(Changes_When_Titlecased1, "") 235 | DEF(Changes_When_Casefolded1, "") 236 | DEF(Changes_When_NFKC_Casefolded1, "") 237 | 238 | /* Prop list exported to JS */ 239 | DEF(ASCII_Hex_Digit, "AHex") 240 | DEF(Bidi_Control, "Bidi_C") 241 | DEF(Dash, "") 242 | DEF(Deprecated, "Dep") 243 | DEF(Diacritic, "Dia") 244 | DEF(Extender, "Ext") 245 | DEF(Hex_Digit, "Hex") 246 | DEF(IDS_Unary_Operator, "IDSU") 247 | DEF(IDS_Binary_Operator, "IDSB") 248 | DEF(IDS_Trinary_Operator, "IDST") 249 | DEF(Ideographic, "Ideo") 250 | DEF(Join_Control, "Join_C") 251 | DEF(Logical_Order_Exception, "LOE") 252 | DEF(Modifier_Combining_Mark, "MCM") 253 | DEF(Noncharacter_Code_Point, "NChar") 254 | DEF(Pattern_Syntax, "Pat_Syn") 255 | DEF(Pattern_White_Space, "Pat_WS") 256 | DEF(Quotation_Mark, "QMark") 257 | DEF(Radical, "") 258 | DEF(Regional_Indicator, "RI") 259 | DEF(Sentence_Terminal, "STerm") 260 | DEF(Soft_Dotted, "SD") 261 | DEF(Terminal_Punctuation, "Term") 262 | DEF(Unified_Ideograph, "UIdeo") 263 | DEF(Variation_Selector, "VS") 264 | DEF(White_Space, "space") 265 | DEF(Bidi_Mirrored, "Bidi_M") 266 | DEF(Emoji, "") 267 | DEF(Emoji_Component, "EComp") 268 | DEF(Emoji_Modifier, "EMod") 269 | DEF(Emoji_Modifier_Base, "EBase") 270 | DEF(Emoji_Presentation, "EPres") 271 | DEF(Extended_Pictographic, "ExtPict") 272 | DEF(Default_Ignorable_Code_Point, "DI") 273 | DEF(ID_Start, "IDS") 274 | DEF(Case_Ignorable, "CI") 275 | 276 | /* other binary properties */ 277 | DEF(ASCII,"") 278 | DEF(Alphabetic, "Alpha") 279 | DEF(Any, "") 280 | DEF(Assigned,"") 281 | DEF(Cased, "") 282 | DEF(Changes_When_Casefolded, "CWCF") 283 | DEF(Changes_When_Casemapped, "CWCM") 284 | DEF(Changes_When_Lowercased, "CWL") 285 | DEF(Changes_When_NFKC_Casefolded, "CWKCF") 286 | DEF(Changes_When_Titlecased, "CWT") 287 | DEF(Changes_When_Uppercased, "CWU") 288 | DEF(Grapheme_Base, "Gr_Base") 289 | DEF(Grapheme_Extend, "Gr_Ext") 290 | DEF(ID_Continue, "IDC") 291 | DEF(ID_Compat_Math_Start, "") 292 | DEF(ID_Compat_Math_Continue, "") 293 | DEF(Lowercase, "Lower") 294 | DEF(Math, "") 295 | DEF(Uppercase, "Upper") 296 | DEF(XID_Continue, "XIDC") 297 | DEF(XID_Start, "XIDS") 298 | 299 | /* internal tables with index */ 300 | DEF(Cased1, "") 301 | 302 | /* unused by us */ 303 | DEF(InCB, "") 304 | 305 | #endif 306 | --------------------------------------------------------------------------------