Compare commits

..

1 commit

Author SHA1 Message Date
Saúl Ibarra Corretgé
6d3bd6056e Add new documentation 2024-03-19 12:12:40 +01:00
60 changed files with 30821 additions and 11235 deletions

View file

@ -71,26 +71,6 @@ jobs:
- name: test
run: |
make test
linux-riscv64:
runs-on: ubuntu-latest
defaults:
run:
shell: alpine.sh {0}
steps:
- uses: actions/checkout@v3
- uses: jirutka/setup-alpine@v1
with:
arch: riscv64
packages: "build-base make cmake"
- name: build
run: |
make
- name: stats
run: |
make stats
- name: test
run: |
make test
linux-s390x:
runs-on: ubuntu-latest
defaults:
@ -114,30 +94,33 @@ jobs:
linux-gcc48:
runs-on: ubuntu-latest
container:
image: ubuntu:18.04
image: ubuntu:14.04
steps:
- name: install dependencies
run: |
apt update && apt -y install make gcc-4.8 cmake software-properties-common
apt update && apt -y install make gcc-4.8 wget time software-properties-common
# git in default ppa repository is too old to run submodule checkout
add-apt-repository -y ppa:git-core/ppa
apt update && apt install -y git
apt update
apt install -y git
wget -nv https://github.com/Kitware/CMake/releases/download/v3.28.0-rc5/cmake-3.28.0-rc5-linux-x86_64.sh
sh cmake-3.28.0-rc5-linux-x86_64.sh --skip-license --prefix=/usr
- name: checkout
uses: actions/checkout@v3
with:
submodules: true
- name: build
env:
CC: gcc-4.8
run: |
mkdir build
cd build
cmake ..
cd ..
make -C build -j$(getconf _NPROCESSORS_ONLN)
CC=gcc-4.8 make
- name: stats
run: |
./build/qjs -qd
make stats
- name: test
run: |
make test
- name: test 262
run: |
time make test262
linux-examples:
runs-on: ubuntu-latest
steps:
@ -260,12 +243,11 @@ jobs:
make stats
macos:
runs-on: ${{ matrix.os }}
runs-on: macos-latest
strategy:
fail-fast: false
matrix:
buildType: [Debug, Release]
os: [macos-12, macos-14]
steps:
- uses: actions/checkout@v4
- name: build
@ -278,11 +260,7 @@ jobs:
run: |
make test
macos-examples:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-12, macos-14]
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: build
@ -304,11 +282,7 @@ jobs:
./build/qjs tests/test_bjson.js
./build/function_source
macos-shared:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-12, macos-14]
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: build
@ -319,11 +293,7 @@ jobs:
run: |
make stats
macos-asan:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-12, macos-14]
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: build
@ -335,11 +305,7 @@ jobs:
run: |
make test
macos-ubsan:
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [macos-12, macos-14]
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: build
@ -356,29 +322,28 @@ jobs:
strategy:
fail-fast: false
matrix:
arch: [x64, Win32]
buildType: [Debug, Release]
steps:
- uses: actions/checkout@v4
- name: build
run: |
cmake -B build -G "Visual Studio 17 2022" -A ${{matrix.arch}}
cmake --build build --config ${{matrix.buildType}} --target qjs_exe
cmake --build build --config ${{matrix.buildType}} --target function_source
cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -G "Visual Studio 17 2022"
cmake --build build --target qjs_exe
cmake --build build --target function_source
- name: stats
run: |
build\${{matrix.buildType}}\qjs.exe -qd
build\Debug\qjs.exe -qd
- name: test
run: |
build\${{matrix.buildType}}\qjs.exe tests\test_bigint.js
build\${{matrix.buildType}}\qjs.exe tests\test_closure.js
build\${{matrix.buildType}}\qjs.exe tests\test_language.js
build\${{matrix.buildType}}\qjs.exe tests\test_builtin.js
build\${{matrix.buildType}}\qjs.exe tests\test_loop.js
build\${{matrix.buildType}}\qjs.exe tests\test_std.js
build\${{matrix.buildType}}\qjs.exe tests\test_worker.js
build\${{matrix.buildType}}\qjs.exe tests\test_queue_microtask.js
build\${{matrix.buildType}}\function_source.exe
build\Debug\qjs.exe tests\test_bigint.js
build\Debug\qjs.exe tests\test_closure.js
build\Debug\qjs.exe tests\test_language.js
build\Debug\qjs.exe tests\test_builtin.js
build\Debug\qjs.exe tests\test_loop.js
build\Debug\qjs.exe tests\test_std.js
build\Debug\qjs.exe tests\test_worker.js
build\Debug\qjs.exe tests\test_queue_microtask.js
build\Debug\function_source.exe
windows-clang:
runs-on: windows-latest
@ -390,55 +355,23 @@ jobs:
- uses: actions/checkout@v4
- name: build
run: |
cmake -B build -G "Visual Studio 17 2022" -T ClangCL
cmake --build build --config ${{matrix.buildType}} --target qjs_exe
cmake --build build --config ${{matrix.buildType}} --target function_source
- name: stats
run: |
build\${{matrix.buildType}}\qjs.exe -qd
- name: test
run: |
build\${{matrix.buildType}}\qjs.exe tests\test_bigint.js
build\${{matrix.buildType}}\qjs.exe tests\test_closure.js
build\${{matrix.buildType}}\qjs.exe tests\test_language.js
build\${{matrix.buildType}}\qjs.exe tests\test_builtin.js
build\${{matrix.buildType}}\qjs.exe tests\test_loop.js
build\${{matrix.buildType}}\qjs.exe tests\test_std.js
build\${{matrix.buildType}}\qjs.exe tests\test_worker.js
build\${{matrix.buildType}}\qjs.exe tests\test_queue_microtask.js
build\${{matrix.buildType}}\function_source.exe
windows-ninja:
runs-on: windows-latest
strategy:
fail-fast: false
matrix:
buildType: [Debug, Release]
steps:
- uses: actions/checkout@v4
- name: install ninja
run: |
choco install ninja
ninja.exe --version
- name: build
run: |
cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -G "Ninja"
cmake -B build -DCMAKE_BUILD_TYPE=${{matrix.buildType}} -G "Visual Studio 17 2022" -T ClangCL
cmake --build build --target qjs_exe
cmake --build build --target function_source
- name: stats
run: |
build\qjs.exe -qd
cmd /r build\Debug\qjs.exe -qd
- name: test
run: |
build\qjs.exe tests\test_bigint.js
build\qjs.exe tests\test_closure.js
build\qjs.exe tests\test_language.js
build\qjs.exe tests\test_builtin.js
build\qjs.exe tests\test_loop.js
build\qjs.exe tests\test_std.js
build\qjs.exe tests\test_worker.js
build\qjs.exe tests\test_queue_microtask.js
build\function_source.exe
cmd /r build\Debug\qjs.exe tests\test_bigint.js
cmd /r build\Debug\qjs.exe tests\test_closure.js
cmd /r build\Debug\qjs.exe tests\test_language.js
cmd /r build\Debug\qjs.exe tests\test_builtin.js
cmd /r build\Debug\qjs.exe tests\test_loop.js
cmd /r build\Debug\qjs.exe tests\test_std.js
cmd /r build\Debug\qjs.exe tests\test_worker.js
cmd /r build\Debug\qjs.exe tests\test_queue_microtask.js
cmd /r build\Debug\function_source.exe
windows-mingw:
runs-on: windows-latest
@ -610,20 +543,8 @@ jobs:
run: |
mkdir build
cd build
$ANDROID_HOME/cmake/3.22.1/bin/cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk/26.0.10792818/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_PLATFORM=android-24 -DBUILD_QJS_LIBC=ON ..
$ANDROID_HOME/cmake/3.22.1/bin/cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_HOME/ndk/26.0.10792818/build/cmake/android.toolchain.cmake -DCMAKE_BUILD_TYPE=Release -DANDROID_ABI="arm64-v8a" -DANDROID_PLATFORM=android-24 ..
- name: Build android arm64
run: |
$ANDROID_HOME/cmake/3.22.1/bin/cmake --build build --target qjs
ls -lh build
ios:
runs-on: macos-latest
steps:
- uses: actions/checkout@v4
- name: configure
run: |
cmake -B build -GXcode -DCMAKE_SYSTEM_NAME:STRING=iOS -DCMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED:BOOL=NO -DBUILD_QJS_LIBC=ON
- name: build
run: |
cmake --build build --config Release --target qjs
ls -lh build

View file

@ -6,62 +6,6 @@ on:
- "v*.*.*"
jobs:
linux-aarch64:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- uses: jirutka/setup-alpine@v1
with:
arch: aarch64
packages: "build-base make cmake"
- name: build
shell: alpine.sh {0}
run: |
mkdir build
cd build
cmake -DBUILD_STATIC_QJS_EXE=ON ..
cd ..
cmake --build build --target qjs_exe -j$(getconf _NPROCESSORS_ONLN)
cmake --build build --target qjsc -j$(getconf _NPROCESSORS_ONLN)
mv build/qjs build/qjs-linux-aarch64
mv build/qjsc build/qjsc-linux-aarch64
- name: check
shell: alpine.sh {0}
run: |
file build/*-linux-aarch64
- name: upload
uses: actions/upload-artifact@v3
with:
name: qjs
path: build/*-linux-aarch64
linux-riscv64:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v4
- uses: jirutka/setup-alpine@v1
with:
arch: riscv64
packages: "build-base make cmake"
- name: build
shell: alpine.sh {0}
run: |
mkdir build
cd build
cmake -DBUILD_STATIC_QJS_EXE=ON ..
cd ..
cmake --build build --target qjs_exe -j$(getconf _NPROCESSORS_ONLN)
cmake --build build --target qjsc -j$(getconf _NPROCESSORS_ONLN)
mv build/qjs build/qjs-linux-riscv64
mv build/qjsc build/qjsc-linux-riscv64
- name: check
shell: alpine.sh {0}
run: |
file build/*-linux-riscv64
- name: upload
uses: actions/upload-artifact@v3
with:
name: qjs
path: build/*-linux-riscv64
linux-x86:
runs-on: ubuntu-20.04
steps:
@ -84,7 +28,7 @@ jobs:
- name: check
shell: alpine.sh {0}
run: |
file build/*-linux-x86
file build/qjs-linux-x86 build/qjsc-linux-x86
- name: upload
uses: actions/upload-artifact@v3
with:
@ -113,7 +57,7 @@ jobs:
- name: check
shell: alpine.sh {0}
run: |
file build/*-linux-x86_64
file build/qjs-linux-x86_64 build/qjsc-linux-x86_64
- name: upload
uses: actions/upload-artifact@v3
with:
@ -225,7 +169,7 @@ jobs:
path: build/qjs-wasi.wasm
upload-to-release:
needs: [linux-aarch64, linux-riscv64, linux-x86, linux-x86_64, macos, windows-x86, windows-x86_64, wasi]
needs: [linux-x86, linux-x86_64, macos, windows-x86, windows-x86_64, wasi]
runs-on: ubuntu-20.04
steps:
- name: get assets

View file

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

View file

@ -27,7 +27,7 @@ macro(xcheck_add_c_compiler_flag FLAG)
endmacro()
xcheck_add_c_compiler_flag(-Wall)
if(NOT MSVC AND NOT IOS)
if(NOT MSVC)
xcheck_add_c_compiler_flag(-Werror)
xcheck_add_c_compiler_flag(-Wextra)
endif()
@ -35,6 +35,7 @@ xcheck_add_c_compiler_flag(-Wno-implicit-fallthrough)
xcheck_add_c_compiler_flag(-Wno-sign-compare)
xcheck_add_c_compiler_flag(-Wno-missing-field-initializers)
xcheck_add_c_compiler_flag(-Wno-unused-parameter)
xcheck_add_c_compiler_flag(-Wno-unused-variable)
xcheck_add_c_compiler_flag(-Wno-unused-but-set-variable)
xcheck_add_c_compiler_flag(-Wno-array-bounds)
xcheck_add_c_compiler_flag(-Wno-format-truncation)
@ -50,7 +51,7 @@ if(MSVC)
xcheck_add_c_compiler_flag(-Wno-reserved-macro-identifier)
xcheck_add_c_compiler_flag(-Wno-reserved-identifier)
xcheck_add_c_compiler_flag(-Wdeprecated-declarations)
xcheck_add_c_compiler_flag(/experimental:c11atomics)
add_compile_definitions(WIN32_LEAN_AND_MEAN)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "WASI")
@ -152,27 +153,20 @@ if(BUILD_QJS_LIBC)
list(APPEND qjs_sources quickjs-libc.c)
endif()
list(APPEND qjs_defines _GNU_SOURCE)
if(WIN32)
list(APPEND qjs_defines WIN32_LEAN_AND_MEAN _WIN32_WINNT=0x0602)
endif()
list(APPEND qjs_libs qjs ${CMAKE_DL_LIBS})
find_package(Threads)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "WASI")
list(APPEND qjs_libs ${CMAKE_THREAD_LIBS_INIT})
endif()
if(NOT MSVC)
list(APPEND qjs_libs m)
list(APPEND qjs_libs m pthread)
endif()
add_library(qjs ${qjs_sources})
target_compile_definitions(qjs PRIVATE ${qjs_defines})
if(CMAKE_BUILD_TYPE MATCHES Debug OR DUMP_LEAKS)
if (CMAKE_BUILD_TYPE MATCHES Debug OR DUMP_LEAKS)
target_compile_definitions(qjs PRIVATE
DUMP_LEAKS
)
endif()
target_include_directories(qjs PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
)
@ -234,7 +228,7 @@ endif()
#
# run-test262 uses pthreads.
if(NOT WIN32 AND NOT EMSCRIPTEN)
if(NOT WIN32)
add_executable(run-test262
quickjs-libc.c
run-test262.c
@ -323,33 +317,28 @@ if(BUILD_EXAMPLES AND NOT WIN32)
target_link_libraries(test_fib ${qjs_libs})
endif()
add_executable(test_conv
tests/test_conv.c
)
# Install target
#
if(NOT IOS)
file(STRINGS quickjs.h quickjs_h REGEX QJS_VERSION)
string(REGEX MATCHALL "([0-9])" QJS_VERSION "${quickjs_h}")
list(GET QJS_VERSION 0 QJS_VERSION_MAJOR)
list(GET QJS_VERSION 1 QJS_VERSION_MINOR)
list(GET QJS_VERSION 2 QJS_VERSION_PATCH)
set_target_properties(qjs PROPERTIES
VERSION ${QJS_VERSION_MAJOR}.${QJS_VERSION_MINOR}.${QJS_VERSION_PATCH}
SOVERSION ${QJS_VERSION_MAJOR}
)
install(FILES quickjs.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
if(BUILD_QJS_LIBC)
install(FILES quickjs-libc.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
endif()
install(TARGETS qjs_exe RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(TARGETS qjs EXPORT qjsConfig
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(EXPORT qjsConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/quickjs)
install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(DIRECTORY examples DESTINATION ${CMAKE_INSTALL_DOCDIR})
file(STRINGS quickjs.h quickjs_h REGEX QJS_VERSION)
string(REGEX MATCHALL "([0-9])" QJS_VERSION "${quickjs_h}")
list(GET QJS_VERSION 0 QJS_VERSION_MAJOR)
list(GET QJS_VERSION 1 QJS_VERSION_MINOR)
list(GET QJS_VERSION 2 QJS_VERSION_PATCH)
set_target_properties(qjs PROPERTIES
VERSION ${QJS_VERSION_MAJOR}.${QJS_VERSION_MINOR}.${QJS_VERSION_PATCH}
SOVERSION ${QJS_VERSION_MAJOR}
)
install(FILES quickjs.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
if(BUILD_QJS_LIBC)
install(FILES quickjs-libc.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR})
endif()
install(TARGETS qjs_exe RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR})
install(TARGETS qjs EXPORT qjsConfig
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR})
install(EXPORT qjsConfig DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/quickjs)
install(FILES LICENSE DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(DIRECTORY examples DESTINATION ${CMAKE_INSTALL_DOCDIR})

View file

@ -53,18 +53,14 @@ $(QJS): $(BUILD_DIR)
$(QJSC): $(BUILD_DIR)
cmake --build $(BUILD_DIR) --target qjsc -j $(JOBS)
$(BUILD_DIR)/test_conv: $(BUILD_DIR) tests/test_conv.c
cmake --build $(BUILD_DIR) --target test_conv
install: $(QJS) $(QJSC)
cmake --build $(BUILD_DIR) --target install
clean:
@rm -f v8.txt[1-9]*
cmake --build $(BUILD_DIR) --target clean
codegen: $(QJSC)
$(QJSC) -ss -o gen/repl.c -m repl.js
$(QJSC) -o gen/repl.c -m repl.js
$(QJSC) -e -o gen/function_source.c tests/function_source.js
$(QJSC) -e -o gen/hello.c examples/hello.js
$(QJSC) -e -o gen/hello_module.c -m examples/hello_module.js
@ -89,15 +85,9 @@ test: $(QJS)
$(QJS) tests/test_worker.js
$(QJS) tests/test_queue_microtask.js
testconv: $(BUILD_DIR)/test_conv
$(BUILD_DIR)/test_conv
test262: $(QJS)
$(RUN262) -m -c test262.conf -a
test262-fast: $(QJS)
$(RUN262) -m -c test262.conf -c test262-fast.conf -a
test262-update: $(QJS)
$(RUN262) -u -c test262.conf -a

894
cutils.c
View file

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

115
cutils.h
View file

@ -29,10 +29,8 @@
#include <string.h>
#include <inttypes.h>
#if defined(_WIN32)
#include <windows.h>
#endif
#if defined(_MSC_VER)
#include <windows.h>
#include <winsock2.h>
#include <malloc.h>
#define alloca _alloca
@ -45,10 +43,7 @@
#elif defined(__FreeBSD__)
#include <malloc_np.h>
#endif
#if !defined(_WIN32)
#include <errno.h>
#include <pthread.h>
#endif
#if defined(_MSC_VER) && !defined(__clang__)
# define likely(x) (x)
@ -131,14 +126,6 @@ char *pstrcat(char *buf, int buf_size, const char *s);
int strstart(const char *str, const char *val, const char **ptr);
int has_suffix(const char *str, const char *suffix);
static inline uint8_t is_be(void) {
union {
uint16_t a;
uint8_t b;
} u = { 0x100 };
return u.b;
}
static inline int max_int(int a, int b)
{
if (a > b)
@ -203,16 +190,9 @@ static inline int clz32(unsigned int a)
static inline int clz64(uint64_t a)
{
#if defined(_MSC_VER) && !defined(__clang__)
#if INTPTR_MAX == INT64_MAX
unsigned long index;
_BitScanReverse64(&index, a);
return 63 - index;
#else
if (a >> 32)
return clz32((unsigned)(a >> 32));
else
return clz32((unsigned)a) + 32;
#endif
#else
return __builtin_clzll(a);
#endif
@ -394,50 +374,19 @@ static inline void dbuf_set_error(DynBuf *s)
s->error = TRUE;
}
/*---- UTF-8 and UTF-16 handling ----*/
#define UTF8_CHAR_LEN_MAX 6
#define UTF8_CHAR_LEN_MAX 4
enum {
UTF8_PLAIN_ASCII = 0, // 7-bit ASCII plain text
UTF8_NON_ASCII = 1, // has non ASCII code points (8-bit or more)
UTF8_HAS_16BIT = 2, // has 16-bit code points
UTF8_HAS_NON_BMP1 = 4, // has non-BMP1 code points, needs UTF-16 surrogate pairs
UTF8_HAS_ERRORS = 8, // has encoding errors
};
int utf8_scan(const char *buf, size_t len, size_t *plen);
size_t utf8_encode_len(uint32_t c);
size_t utf8_encode(uint8_t *buf, uint32_t c);
uint32_t utf8_decode_len(const uint8_t *p, size_t max_len, const uint8_t **pp);
uint32_t utf8_decode(const uint8_t *p, const uint8_t **pp);
size_t utf8_decode_buf8(uint8_t *dest, size_t dest_len, const char *src, size_t src_len);
size_t utf8_decode_buf16(uint16_t *dest, size_t dest_len, const char *src, size_t src_len);
size_t utf8_encode_buf8(char *dest, size_t dest_len, const uint8_t *src, size_t src_len);
size_t utf8_encode_buf16(char *dest, size_t dest_len, const uint16_t *src, size_t src_len);
static inline BOOL is_surrogate(uint32_t c)
{
return (c >> 11) == (0xD800 >> 11); // 0xD800-0xDFFF
}
int unicode_to_utf8(uint8_t *buf, unsigned int c);
int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp);
static inline BOOL is_hi_surrogate(uint32_t c)
{
return (c >> 10) == (0xD800 >> 10); // 0xD800-0xDBFF
return 54 == (c >> 10); // 0xD800-0xDBFF
}
static inline BOOL is_lo_surrogate(uint32_t c)
{
return (c >> 10) == (0xDC00 >> 10); // 0xDC00-0xDFFF
}
static inline uint32_t get_hi_surrogate(uint32_t c)
{
return (c >> 10) - (0x10000 >> 10) + 0xD800;
}
static inline uint32_t get_lo_surrogate(uint32_t c)
{
return (c & 0x3FF) | 0xDC00;
return 55 == (c >> 10); // 0xDC00-0xDFFF
}
static inline uint32_t from_surrogate(uint32_t hi, uint32_t lo)
@ -457,24 +406,6 @@ static inline int from_hex(int c)
return -1;
}
static inline uint8_t is_upper_ascii(uint8_t c) {
return c >= 'A' && c <= 'Z';
}
static inline uint8_t to_upper_ascii(uint8_t c) {
return c >= 'a' && c <= 'z' ? c - 'a' + 'A' : c;
}
extern char const digits36[36];
size_t u32toa(char buf[minimum_length(11)], uint32_t n);
size_t i32toa(char buf[minimum_length(12)], int32_t n);
size_t u64toa(char buf[minimum_length(21)], uint64_t n);
size_t i64toa(char buf[minimum_length(22)], int64_t n);
size_t u32toa_radix(char buf[minimum_length(33)], uint32_t n, unsigned int base);
size_t i32toa_radix(char buf[minimum_length(34)], int32_t n, unsigned base);
size_t u64toa_radix(char buf[minimum_length(65)], uint64_t n, unsigned int base);
size_t i64toa_radix(char buf[minimum_length(66)], int64_t n, unsigned int base);
void rqsort(void *base, size_t nmemb, size_t size,
int (*cmp)(const void *, const void *, void *),
void *arg);
@ -495,36 +426,4 @@ static inline size_t js__malloc_usable_size(const void *ptr)
#endif
}
/* Cross-platform threading APIs. */
#if !defined(EMSCRIPTEN) && !defined(__wasi__)
#if defined(_WIN32)
#define JS_ONCE_INIT INIT_ONCE_STATIC_INIT
typedef INIT_ONCE js_once_t;
typedef CRITICAL_SECTION js_mutex_t;
typedef CONDITION_VARIABLE js_cond_t;
#else
#define JS_ONCE_INIT PTHREAD_ONCE_INIT
typedef pthread_once_t js_once_t;
typedef pthread_mutex_t js_mutex_t;
typedef pthread_cond_t js_cond_t;
#endif
void js_once(js_once_t *guard, void (*callback)(void));
void js_mutex_init(js_mutex_t *mutex);
void js_mutex_destroy(js_mutex_t *mutex);
void js_mutex_lock(js_mutex_t *mutex);
void js_mutex_unlock(js_mutex_t *mutex);
void js_cond_init(js_cond_t *cond);
void js_cond_destroy(js_cond_t *cond);
void js_cond_signal(js_cond_t *cond);
void js_cond_broadcast(js_cond_t *cond);
void js_cond_wait(js_cond_t *cond, js_mutex_t *mutex);
int js_cond_timedwait(js_cond_t *cond, js_mutex_t *mutex, uint64_t timeout);
#endif /* !defined(EMSCRIPTEN) && !defined(__wasi__) */
#endif /* CUTILS_H */

File diff suppressed because it is too large Load diff

20
docs/.gitignore vendored Normal file
View file

@ -0,0 +1,20 @@
# Dependencies
/node_modules
# Production
/build
# Generated files
.docusaurus
.cache-loader
# Misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

1
docs/.nvmrc Normal file
View file

@ -0,0 +1 @@
18

41
docs/README.md Normal file
View file

@ -0,0 +1,41 @@
# Website
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
### Installation
```
$ yarn
```
### Local Development
```
$ yarn start
```
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
### Build
```
$ yarn build
```
This command generates static content into the `build` directory and can be served using any static contents hosting service.
### Deployment
Using SSH:
```
$ USE_SSH=true yarn deploy
```
Not using SSH:
```
$ GIT_USER=<Your GitHub username> yarn deploy
```
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

3
docs/babel.config.js Normal file
View file

@ -0,0 +1,3 @@
module.exports = {
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
};

12
docs/docs/building.md Normal file
View file

@ -0,0 +1,12 @@
---
sidebar_position: 2
---
# Building
QuickJS uses [CMake] as its main build system, with an additional helper [Makefile].
WIP.
[CMake]: https://cmake.org
[Makefile]: https://www.gnu.org/software/make/

7
docs/docs/cli.md Normal file
View file

@ -0,0 +1,7 @@
---
sidebar_position: 4
---
# The qjs and qjsc CLI tools
WIP.

View file

@ -0,0 +1,7 @@
{
"label": "Developer Guide",
"position": 5,
"link": {
"type": "generated-index"
}
}

View file

@ -0,0 +1,7 @@
---
sidebar_position: 5
---
# Custom modules
WIP.

View file

@ -0,0 +1,7 @@
---
sidebar_position: 3
---
# Evaluating code
WIP.

View file

@ -0,0 +1,7 @@
---
sidebar_position: 1
---
# Introduction
WIP.

View file

@ -0,0 +1,7 @@
---
sidebar_position: 2
---
# JSRuntime and JSContext
WIP.

View file

@ -0,0 +1,7 @@
---
sidebar_position: 4
---
# Working with values
WIP.

3
docs/docs/es_features.md Normal file
View file

@ -0,0 +1,3 @@
# ECMAScript Features
WIP.

34
docs/docs/installation.md Normal file
View file

@ -0,0 +1,34 @@
---
sidebar_position: 3
---
# Installation
Installing QuickJS is simple, and we provide several ways to do so.
## Build from source
If you built it from source as outlined in [building](./building) you can just run:
```bash
make install
```
and it will be installed in your system. The default installation path is `/usr/local`.
## Using a prebuilt binary
Each [release on GitHub] includes binaries for several systems.
## Using jsvu
As of version 2.2.0 of `jsvu`, QuickJS-ng will be installed when the `quickjs` engine is requested.
```bash
npm install jsvu -g
```
[release on GitHub]: https://github.com/quickjs-ng/quickjs/releases

25
docs/docs/intro.md Normal file
View file

@ -0,0 +1,25 @@
---
slug: /
sidebar_position: 1
sidebar_label: Welcome
---
# Welcome to QuickJS
QuickJS is a small and embeddable Javascript engine. It supports the [ES2023] specification
including modules, asynchronous generators, proxies, BigInt and more.
This project is a _fork_ of the [original QuickJS project] by Fabrice Bellard, after it went
dormant for several years.
:::note
This site is under construction, the entire API is not yet documented.
:::
## Getting Started
WIP.
[ES2023]: https://tc39.es/ecma262/
[original QuickJS project]: https://bellard.org/quickjs

View file

@ -0,0 +1,3 @@
# Supported Platforms
WIP.

122
docs/docusaurus.config.js Normal file
View file

@ -0,0 +1,122 @@
// @ts-check
// `@type` JSDoc annotations allow editor autocompletion and type checking
// (when paired with `@ts-check`).
// There are various equivalent ways to declare your Docusaurus config.
// See: https://docusaurus.io/docs/api/docusaurus-config
import {themes as prismThemes} from 'prism-react-renderer';
/** @type {import('@docusaurus/types').Config} */
const config = {
title: 'QuickJS-NG',
tagline: 'QuickJS, the Next Generation: a mighty JavaScript engine',
favicon: 'img/favicon.ico',
// Set the production url of your site here
url: 'https://quickjs-ng.github.io',
// Set the /<baseUrl>/ pathname under which your site is served
// For GitHub pages deployment, it is often '/<projectName>/'
baseUrl: '/quickjs/',
// GitHub pages deployment config.
// If you aren't using GitHub pages, you don't need these.
organizationName: 'quickjs-ng', // Usually your GitHub org/user name.
projectName: 'quickjs', // Usually your repo name.
onBrokenLinks: 'throw',
onBrokenMarkdownLinks: 'warn',
// Even if you don't use internationalization, you can use this field to set
// useful metadata like html lang. For example, if your site is Chinese, you
// may want to replace "en" with "zh-Hans".
i18n: {
defaultLocale: 'en',
locales: ['en'],
},
presets: [
[
'classic',
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
routeBasePath: '/',
sidebarPath: './sidebars.js',
// Please change this to your repo.
// Remove this to remove the "edit this page" links.
editUrl: 'https://github.com/quickjs-ng/quickjs/tree/master/docs/',
},
blog: false,
theme: {
customCss: './src/css/custom.css',
},
}),
],
],
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
// Replace with your project's social card
image: 'img/docusaurus-social-card.jpg',
navbar: {
title: 'QuickJS',
items: [
{
type: 'docSidebar',
sidebarId: 'docsSidebar',
position: 'left',
label: 'Documentation',
},
{
href: 'https://github.com/quickjs-ng/quickjs',
label: 'GitHub',
position: 'right',
},
],
},
footer: {
style: 'dark',
links: [
{
title: 'Docs',
items: [
{
label: 'Tutorial',
to: '/docs/intro',
},
],
},
{
title: 'Community',
items: [
{
label: 'GitHub Discussions',
href: 'https://github.com/quickjs-ng/quickjs/discussions',
},
{
label: 'Matrix',
href: 'https://matrix.to/#/%23quickjs-ng%3Amatrix.org?via=matrix.org',
},
],
},
{
title: 'More',
items: [
{
label: 'GitHub',
href: 'https://github.com/quickjs-ng/quickjs',
},
],
},
],
copyright: `Copyright © ${new Date().getFullYear()} QuickJS-NG project contributors.`,
},
prism: {
theme: prismThemes.github,
darkTheme: prismThemes.dracula,
},
}),
};
export default config;

14664
docs/package-lock.json generated Normal file

File diff suppressed because it is too large Load diff

44
docs/package.json Normal file
View file

@ -0,0 +1,44 @@
{
"name": "docs-ng",
"version": "0.0.0",
"private": true,
"scripts": {
"docusaurus": "docusaurus",
"start": "docusaurus start",
"build": "docusaurus build",
"swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy",
"clear": "docusaurus clear",
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids"
},
"dependencies": {
"@docusaurus/core": "^3.1.1",
"@docusaurus/preset-classic": "^3.1.1",
"@mdx-js/react": "^3.0.0",
"clsx": "^1.2.1",
"prism-react-renderer": "^2.1.0",
"react": "^18.0.0",
"react-dom": "^18.0.0"
},
"devDependencies": {
"@docusaurus/module-type-aliases": "^3.1.1",
"@docusaurus/types": "^3.1.1"
},
"browserslist": {
"production": [
">0.5%",
"not dead",
"not op_mini all"
],
"development": [
"last 3 chrome version",
"last 3 firefox version",
"last 5 safari version"
]
},
"engines": {
"node": ">=18.0"
}
}

20
docs/sidebars.js Normal file
View file

@ -0,0 +1,20 @@
/**
* Creating a sidebar enables you to:
- create an ordered group of docs
- render a sidebar for each doc of that group
- provide next/previous navigation
The sidebars can be generated from the filesystem, or explicitly defined here.
Create as many sidebars as you want.
*/
// @ts-check
/** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */
const sidebars = {
// By default, Docusaurus generates a sidebar from the docs folder structure
docsSidebar: [{type: 'autogenerated', dirName: '.'}],
};
export default sidebars;

30
docs/src/css/custom.css Normal file
View file

@ -0,0 +1,30 @@
/**
* Any CSS included here will be global. The classic template
* bundles Infima by default. Infima is a CSS framework designed to
* work well for content-centric websites.
*/
/* You can override the default Infima variables here. */
:root {
--ifm-color-primary: #2e8555;
--ifm-color-primary-dark: #29784c;
--ifm-color-primary-darker: #277148;
--ifm-color-primary-darkest: #205d3b;
--ifm-color-primary-light: #33925d;
--ifm-color-primary-lighter: #359962;
--ifm-color-primary-lightest: #3cad6e;
--ifm-code-font-size: 95%;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.1);
}
/* For readability concerns, you should choose a lighter palette in dark mode. */
[data-theme='dark'] {
--ifm-color-primary: #25c2a0;
--ifm-color-primary-dark: #21af90;
--ifm-color-primary-darker: #1fa588;
--ifm-color-primary-darkest: #1a8870;
--ifm-color-primary-light: #29d5b0;
--ifm-color-primary-lighter: #32d8b4;
--ifm-color-primary-lightest: #4fddbf;
--docusaurus-highlighted-code-line-bg: rgba(0, 0, 0, 0.3);
}

0
docs/static/.nojekyll vendored Normal file
View file

BIN
docs/static/img/favicon.ico vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

View file

@ -2,57 +2,59 @@
#include "quickjs-libc.h"
const uint32_t qjsc_function_source_size = 384;
const uint32_t qjsc_function_source_size = 393;
const uint8_t qjsc_function_source[384] = {
0x0c, 0x06, 0x0c, 0x61, 0x63, 0x74, 0x75, 0x61,
0x6c, 0x02, 0x66, 0x30, 0x74, 0x65, 0x73, 0x74,
0x73, 0x2f, 0x66, 0x75, 0x6e, 0x63, 0x74, 0x69,
0x6f, 0x6e, 0x5f, 0x73, 0x6f, 0x75, 0x72, 0x63,
0x65, 0x2e, 0x6a, 0x73, 0x0c, 0x65, 0x78, 0x70,
0x65, 0x63, 0x74, 0x14, 0x75, 0x73, 0x65, 0x20,
0x73, 0x74, 0x72, 0x69, 0x63, 0x74, 0x34, 0x66,
0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20,
0x66, 0x28, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65,
0x74, 0x75, 0x72, 0x6e, 0x20, 0x34, 0x32, 0x20,
0x7d, 0x0c, 0x00, 0xfa, 0x01, 0x9e, 0x01, 0x00,
const uint8_t qjsc_function_source[393] = {
0x08, 0x06, 0x0c, 0x61, 0x63, 0x74, 0x75, 0x61,
0x6c, 0x02, 0x66, 0x0c, 0x65, 0x78, 0x70, 0x65,
0x63, 0x74, 0x14, 0x75, 0x73, 0x65, 0x20, 0x73,
0x74, 0x72, 0x69, 0x63, 0x74, 0x34, 0x66, 0x75,
0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66,
0x28, 0x29, 0x20, 0x7b, 0x20, 0x72, 0x65, 0x74,
0x75, 0x72, 0x6e, 0x20, 0x34, 0x32, 0x20, 0x7d,
0x30, 0x74, 0x65, 0x73, 0x74, 0x73, 0x2f, 0x66,
0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x5f,
0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x2e, 0x6a,
0x73, 0x0c, 0x00, 0x02, 0x01, 0x9e, 0x01, 0x00,
0x06, 0x00, 0x03, 0x00, 0x01, 0xa0, 0x01, 0x06,
0xa0, 0x01, 0x00, 0x00, 0x00, 0xb2, 0x03, 0x02,
0x00, 0x30, 0xb4, 0x03, 0x04, 0x00, 0x70, 0xb2,
0xa0, 0x01, 0x00, 0x00, 0x00, 0xac, 0x03, 0x02,
0x00, 0x30, 0xae, 0x03, 0x04, 0x00, 0x70, 0xac,
0x03, 0x04, 0x03, 0x70, 0x10, 0x00, 0x01, 0x00,
0xe0, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x43, 0xfa,
0x01, 0xb4, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00,
0x00, 0x03, 0x00, 0xbb, 0x2a, 0x28, 0xb6, 0x03,
0x03, 0x01, 0x04, 0x02, 0x1e, 0x0c, 0x0e, 0x1a,
0x66, 0x75, 0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e,
0x20, 0x66, 0x28, 0x29, 0x20, 0x7b, 0x20, 0x72,
0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x34, 0x32,
0x20, 0x7d, 0x0c, 0x03, 0xc1, 0x05, 0x08, 0xc1,
0x04, 0x3f, 0xdc, 0x00, 0x00, 0x00, 0x80, 0x3f,
0xda, 0x00, 0x00, 0x00, 0x40, 0x3e, 0xdc, 0x00,
0x00, 0x00, 0x80, 0xbe, 0x00, 0x40, 0xda, 0x00,
0x00, 0x00, 0x00, 0x04, 0xdd, 0x00, 0x00, 0x00,
0xc8, 0x04, 0xde, 0x00, 0x00, 0x00, 0x3a, 0xdc,
0x00, 0x00, 0x00, 0x61, 0x01, 0x00, 0x38, 0xda,
0x00, 0x00, 0x00, 0x42, 0x36, 0x00, 0x00, 0x00,
0x24, 0x00, 0x00, 0xc9, 0x06, 0xc8, 0x62, 0x01,
0x00, 0x38, 0xdc, 0x00, 0x00, 0x00, 0xaf, 0xe9,
0x0b, 0x38, 0x92, 0x00, 0x00, 0x00, 0x62, 0x01,
0x00, 0xee, 0x2f, 0x61, 0x03, 0x00, 0x61, 0x02,
0x00, 0x38, 0x39, 0x00, 0x00, 0x00, 0x38, 0xdc,
0x00, 0x00, 0x00, 0x04, 0xda, 0x00, 0x00, 0x00,
0x9d, 0x31, 0x01, 0x00, 0x04, 0x00, 0xca, 0x62,
0x02, 0x00, 0x42, 0x36, 0x00, 0x00, 0x00, 0x24,
0x00, 0x00, 0xcb, 0x06, 0xc8, 0x62, 0x03, 0x00,
0x38, 0xdc, 0x00, 0x00, 0x00, 0xaf, 0xe9, 0x0b,
0x38, 0x92, 0x00, 0x00, 0x00, 0x62, 0x03, 0x00,
0xee, 0x2f, 0x68, 0x03, 0x00, 0x68, 0x02, 0x00,
0xc4, 0x28, 0xb6, 0x03, 0x01, 0x01, 0x28, 0x60,
0x01, 0x49, 0x02, 0x21, 0x1a, 0x1b, 0x04, 0x1e,
0x1d, 0x12, 0x26, 0x49, 0x1d, 0x0c, 0x06, 0x11,
0x18, 0x2a, 0x1c, 0x37, 0x41, 0x21, 0x1c, 0x34,
0x18, 0x1b, 0x04, 0x26, 0x11, 0x3f, 0x1d, 0x0c,
0x06, 0x11, 0x18, 0x2a, 0x1c, 0x53, 0x41, 0x00,
0xe0, 0x01, 0x00, 0x01, 0x00, 0x0c, 0x03, 0xc1,
0x05, 0x08, 0xc1, 0x04, 0x3f, 0xd8, 0x00, 0x00,
0x00, 0x80, 0x3f, 0xd7, 0x00, 0x00, 0x00, 0x40,
0x3e, 0xd8, 0x00, 0x00, 0x00, 0x80, 0xbe, 0x00,
0x40, 0xd7, 0x00, 0x00, 0x00, 0x00, 0x04, 0xd9,
0x00, 0x00, 0x00, 0xc8, 0x04, 0xda, 0x00, 0x00,
0x00, 0x3a, 0xd8, 0x00, 0x00, 0x00, 0x61, 0x01,
0x00, 0x38, 0xd7, 0x00, 0x00, 0x00, 0x42, 0x36,
0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0xc9, 0x06,
0xc8, 0x62, 0x01, 0x00, 0x38, 0xd8, 0x00, 0x00,
0x00, 0xaf, 0xe9, 0x0b, 0x38, 0x8f, 0x00, 0x00,
0x00, 0x62, 0x01, 0x00, 0xee, 0x2f, 0x61, 0x03,
0x00, 0x61, 0x02, 0x00, 0x38, 0x39, 0x00, 0x00,
0x00, 0x38, 0xd8, 0x00, 0x00, 0x00, 0x04, 0xd7,
0x00, 0x00, 0x00, 0x9d, 0x31, 0x01, 0x00, 0x04,
0x00, 0xca, 0x62, 0x02, 0x00, 0x42, 0x36, 0x00,
0x00, 0x00, 0x24, 0x00, 0x00, 0xcb, 0x06, 0xc8,
0x62, 0x03, 0x00, 0x38, 0xd8, 0x00, 0x00, 0x00,
0xaf, 0xe9, 0x0b, 0x38, 0x8f, 0x00, 0x00, 0x00,
0x62, 0x03, 0x00, 0xee, 0x2f, 0x68, 0x03, 0x00,
0x68, 0x02, 0x00, 0xc4, 0x28, 0xb6, 0x03, 0x01,
0x01, 0x28, 0x60, 0x01, 0x49, 0x02, 0x21, 0x1a,
0x1b, 0x04, 0x1e, 0x1d, 0x12, 0x26, 0x49, 0x1d,
0x0c, 0x06, 0x11, 0x18, 0x2a, 0x1c, 0x37, 0x41,
0x21, 0x1c, 0x34, 0x18, 0x1b, 0x04, 0x26, 0x11,
0x3f, 0x1d, 0x0c, 0x06, 0x11, 0x18, 0x2a, 0x1c,
0x53, 0x41, 0x00, 0xff, 0x49, 0x43, 0x01, 0x6c,
0x0c, 0x43, 0x02, 0x01, 0xae, 0x03, 0x00, 0x00,
0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0xbb, 0x2a,
0x28, 0xb6, 0x03, 0x03, 0x01, 0x04, 0x02, 0x1e,
0x0c, 0x0e, 0x1a, 0x66, 0x75, 0x6e, 0x63, 0x74,
0x69, 0x6f, 0x6e, 0x20, 0x66, 0x28, 0x29, 0x20,
0x7b, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
0x20, 0x34, 0x32, 0x20, 0x7d, 0xff, 0x49, 0x43,
0x00,
};
static JSContext *JS_NewCustomContext(JSRuntime *rt)

View file

@ -2,21 +2,21 @@
#include "quickjs-libc.h"
const uint32_t qjsc_hello_size = 89;
const uint32_t qjsc_hello_size = 95;
const uint8_t qjsc_hello[89] = {
0x0c, 0x04, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x6f,
const uint8_t qjsc_hello[95] = {
0x08, 0x04, 0x0e, 0x63, 0x6f, 0x6e, 0x73, 0x6f,
0x6c, 0x65, 0x06, 0x6c, 0x6f, 0x67, 0x16, 0x48,
0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57, 0x6f, 0x72,
0x6c, 0x64, 0x22, 0x65, 0x78, 0x61, 0x6d, 0x70,
0x6c, 0x65, 0x73, 0x2f, 0x68, 0x65, 0x6c, 0x6c,
0x6f, 0x2e, 0x6a, 0x73, 0x0c, 0x00, 0xfa, 0x00,
0x6f, 0x2e, 0x6a, 0x73, 0x0c, 0x00, 0x02, 0x00,
0x9e, 0x01, 0x00, 0x01, 0x00, 0x03, 0x00, 0x00,
0x14, 0x01, 0xa0, 0x01, 0x00, 0x00, 0x00, 0x38,
0xd9, 0x00, 0x00, 0x00, 0x42, 0xda, 0x00, 0x00,
0x00, 0x04, 0xdb, 0x00, 0x00, 0x00, 0x24, 0x01,
0x00, 0xcc, 0x28, 0xb8, 0x03, 0x01, 0x01, 0x00,
0x00,
0xd6, 0x00, 0x00, 0x00, 0x42, 0xd7, 0x00, 0x00,
0x00, 0x04, 0xd8, 0x00, 0x00, 0x00, 0x24, 0x01,
0x00, 0xcc, 0x28, 0xb2, 0x03, 0x01, 0x01, 0x00,
0x00, 0xff, 0x49, 0x43, 0x01, 0xae, 0x03,
};
static JSContext *JS_NewCustomContext(JSRuntime *rt)

View file

@ -2,23 +2,26 @@
#include "quickjs-libc.h"
const uint32_t qjsc_fib_module_size = 311;
const uint32_t qjsc_fib_module_size = 318;
const uint8_t qjsc_fib_module[311] = {
0x0c, 0x03, 0x2c, 0x65, 0x78, 0x61, 0x6d, 0x70,
const uint8_t qjsc_fib_module[318] = {
0x08, 0x03, 0x2c, 0x65, 0x78, 0x61, 0x6d, 0x70,
0x6c, 0x65, 0x73, 0x2f, 0x66, 0x69, 0x62, 0x5f,
0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e, 0x6a,
0x73, 0x06, 0x66, 0x69, 0x62, 0x02, 0x6e, 0x0d,
0xb2, 0x03, 0x00, 0x01, 0x00, 0x00, 0xb4, 0x03,
0x00, 0x00, 0x00, 0x0c, 0x20, 0xfa, 0x01, 0x9e,
0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x09,
0x00, 0xb4, 0x03, 0x00, 0x01, 0x0c, 0x43, 0xfa,
0x01, 0xb4, 0x03, 0x01, 0x00, 0x01, 0x04, 0x01,
0x00, 0x1a, 0x01, 0xb6, 0x03, 0x00, 0x01, 0x00,
0xb4, 0x03, 0x00, 0x00, 0xd0, 0xb3, 0xa7, 0xe9,
0xac, 0x03, 0x00, 0x01, 0x00, 0x00, 0xae, 0x03,
0x00, 0x00, 0x0c, 0x20, 0x02, 0x01, 0x9e, 0x01,
0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x09, 0x00,
0xae, 0x03, 0x00, 0x01, 0x08, 0xe9, 0x05, 0xbe,
0x00, 0xe0, 0x29, 0x06, 0x2e, 0xac, 0x03, 0x01,
0x01, 0x06, 0x01, 0x01, 0x00, 0x07, 0x14, 0x02,
0x00, 0xff, 0x49, 0x43, 0x00, 0x0c, 0x43, 0x02,
0x01, 0xae, 0x03, 0x01, 0x00, 0x01, 0x04, 0x01,
0x00, 0x1a, 0x01, 0xb0, 0x03, 0x00, 0x01, 0x00,
0xae, 0x03, 0x00, 0x00, 0xd0, 0xb3, 0xa7, 0xe9,
0x03, 0xb3, 0x28, 0xd0, 0xb4, 0xac, 0xe9, 0x03,
0xb4, 0x28, 0xdc, 0xd0, 0xb4, 0x9e, 0xee, 0xdc,
0xd0, 0xb5, 0x9e, 0xee, 0x9d, 0x28, 0xb2, 0x03,
0xd0, 0xb5, 0x9e, 0xee, 0x9d, 0x28, 0xac, 0x03,
0x02, 0x08, 0x20, 0x04, 0x00, 0x07, 0x06, 0x07,
0x06, 0x12, 0x09, 0x08, 0x07, 0x07, 0x10, 0x07,
0x06, 0x07, 0x06, 0x12, 0x13, 0x08, 0x07, 0x08,
@ -41,15 +44,13 @@ const uint8_t qjsc_fib_module[311] = {
0x66, 0x69, 0x62, 0x28, 0x6e, 0x20, 0x2d, 0x20,
0x31, 0x29, 0x20, 0x2b, 0x20, 0x66, 0x69, 0x62,
0x28, 0x6e, 0x20, 0x2d, 0x20, 0x32, 0x29, 0x3b,
0x0a, 0x7d, 0x08, 0xe9, 0x05, 0xbe, 0x00, 0xe0,
0x29, 0x06, 0x2e, 0xb2, 0x03, 0x01, 0x01, 0x06,
0x01, 0x01, 0x00, 0x07, 0x14, 0x02, 0x00,
0x0a, 0x7d, 0xff, 0x49, 0x43, 0x00,
};
const uint32_t qjsc_hello_module_size = 178;
const uint32_t qjsc_hello_module_size = 183;
const uint8_t qjsc_hello_module[178] = {
0x0c, 0x07, 0x30, 0x65, 0x78, 0x61, 0x6d, 0x70,
const uint8_t qjsc_hello_module[183] = {
0x08, 0x07, 0x30, 0x65, 0x78, 0x61, 0x6d, 0x70,
0x6c, 0x65, 0x73, 0x2f, 0x68, 0x65, 0x6c, 0x6c,
0x6f, 0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65,
0x2e, 0x6a, 0x73, 0x1e, 0x2e, 0x2f, 0x66, 0x69,
@ -59,19 +60,19 @@ const uint8_t qjsc_hello_module[178] = {
0x6c, 0x6f, 0x67, 0x16, 0x48, 0x65, 0x6c, 0x6c,
0x6f, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64, 0x10,
0x66, 0x69, 0x62, 0x28, 0x31, 0x30, 0x29, 0x3d,
0x0d, 0xb2, 0x03, 0x01, 0xb4, 0x03, 0x00, 0x00,
0x01, 0x00, 0xb6, 0x03, 0x00, 0x00, 0x0c, 0x20,
0xfa, 0x01, 0x9e, 0x01, 0x00, 0x00, 0x00, 0x05,
0x01, 0x00, 0x32, 0x00, 0xb6, 0x03, 0x00, 0x0c,
0x08, 0xe9, 0x02, 0x29, 0x38, 0xdc, 0x00, 0x00,
0x00, 0x42, 0xdd, 0x00, 0x00, 0x00, 0x04, 0xde,
0x00, 0x00, 0x00, 0x24, 0x01, 0x00, 0x0e, 0x38,
0xdc, 0x00, 0x00, 0x00, 0x42, 0xdd, 0x00, 0x00,
0x00, 0x04, 0xdf, 0x00, 0x00, 0x00, 0x65, 0x00,
0x00, 0xbb, 0x0a, 0xee, 0x24, 0x02, 0x00, 0x0e,
0x06, 0x2e, 0xb2, 0x03, 0x01, 0x01, 0x0a, 0x01,
0x01, 0x00, 0x04, 0x0a, 0x02, 0x62, 0x00, 0x4d,
0x30, 0x00,
0x0d, 0xac, 0x03, 0x01, 0xae, 0x03, 0x00, 0x00,
0x01, 0x00, 0xb0, 0x03, 0x00, 0x0c, 0x20, 0x02,
0x01, 0x9e, 0x01, 0x00, 0x00, 0x00, 0x05, 0x01,
0x00, 0x32, 0x00, 0xb0, 0x03, 0x00, 0x0c, 0x08,
0xe9, 0x02, 0x29, 0x38, 0xd9, 0x00, 0x00, 0x00,
0x42, 0xda, 0x00, 0x00, 0x00, 0x04, 0xdb, 0x00,
0x00, 0x00, 0x24, 0x01, 0x00, 0x0e, 0x38, 0xd9,
0x00, 0x00, 0x00, 0x42, 0xda, 0x00, 0x00, 0x00,
0x04, 0xdc, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00,
0xbb, 0x0a, 0xee, 0x24, 0x02, 0x00, 0x0e, 0x06,
0x2e, 0xac, 0x03, 0x01, 0x01, 0x0a, 0x01, 0x01,
0x00, 0x04, 0x0a, 0x02, 0x62, 0x00, 0x4d, 0x30,
0x00, 0xff, 0x49, 0x43, 0x01, 0xb4, 0x03,
};
static JSContext *JS_NewCustomContext(JSRuntime *rt)

15612
gen/repl.c

File diff suppressed because it is too large Load diff

View file

@ -2,10 +2,10 @@
#include "quickjs-libc.h"
const uint32_t qjsc_test_fib_size = 167;
const uint32_t qjsc_test_fib_size = 172;
const uint8_t qjsc_test_fib[167] = {
0x0c, 0x07, 0x28, 0x65, 0x78, 0x61, 0x6d, 0x70,
const uint8_t qjsc_test_fib[172] = {
0x08, 0x07, 0x28, 0x65, 0x78, 0x61, 0x6d, 0x70,
0x6c, 0x65, 0x73, 0x2f, 0x74, 0x65, 0x73, 0x74,
0x5f, 0x66, 0x69, 0x62, 0x2e, 0x6a, 0x73, 0x10,
0x2e, 0x2f, 0x66, 0x69, 0x62, 0x2e, 0x73, 0x6f,
@ -13,19 +13,20 @@ const uint8_t qjsc_test_fib[167] = {
0x73, 0x6f, 0x6c, 0x65, 0x06, 0x6c, 0x6f, 0x67,
0x16, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20, 0x57,
0x6f, 0x72, 0x6c, 0x64, 0x10, 0x66, 0x69, 0x62,
0x28, 0x31, 0x30, 0x29, 0x3d, 0x0d, 0xb2, 0x03,
0x01, 0xb4, 0x03, 0x00, 0x00, 0x01, 0x00, 0xb6,
0x03, 0x00, 0x00, 0x0c, 0x20, 0xfa, 0x01, 0x9e,
0x01, 0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x32,
0x00, 0xb6, 0x03, 0x00, 0x0c, 0x08, 0xe9, 0x02,
0x29, 0x38, 0xdc, 0x00, 0x00, 0x00, 0x42, 0xdd,
0x00, 0x00, 0x00, 0x04, 0xde, 0x00, 0x00, 0x00,
0x24, 0x01, 0x00, 0x0e, 0x38, 0xdc, 0x00, 0x00,
0x00, 0x42, 0xdd, 0x00, 0x00, 0x00, 0x04, 0xdf,
0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0xbb, 0x0a,
0xee, 0x24, 0x02, 0x00, 0x0e, 0x06, 0x2e, 0xb2,
0x03, 0x01, 0x01, 0x0a, 0x01, 0x01, 0x00, 0x04,
0x0a, 0x02, 0x62, 0x00, 0x4d, 0x30, 0x00,
0x28, 0x31, 0x30, 0x29, 0x3d, 0x0d, 0xac, 0x03,
0x01, 0xae, 0x03, 0x00, 0x00, 0x01, 0x00, 0xb0,
0x03, 0x00, 0x0c, 0x20, 0x02, 0x01, 0x9e, 0x01,
0x00, 0x00, 0x00, 0x05, 0x01, 0x00, 0x32, 0x00,
0xb0, 0x03, 0x00, 0x0c, 0x08, 0xe9, 0x02, 0x29,
0x38, 0xd9, 0x00, 0x00, 0x00, 0x42, 0xda, 0x00,
0x00, 0x00, 0x04, 0xdb, 0x00, 0x00, 0x00, 0x24,
0x01, 0x00, 0x0e, 0x38, 0xd9, 0x00, 0x00, 0x00,
0x42, 0xda, 0x00, 0x00, 0x00, 0x04, 0xdc, 0x00,
0x00, 0x00, 0x65, 0x00, 0x00, 0xbb, 0x0a, 0xee,
0x24, 0x02, 0x00, 0x0e, 0x06, 0x2e, 0xac, 0x03,
0x01, 0x01, 0x0a, 0x01, 0x01, 0x00, 0x04, 0x0a,
0x02, 0x62, 0x00, 0x4d, 0x30, 0x00, 0xff, 0x49,
0x43, 0x01, 0xb4, 0x03,
};
static JSContext *JS_NewCustomContext(JSRuntime *rt)

View file

@ -712,7 +712,7 @@ static int parse_unicode_property(REParseState *s, CharRange *cr,
static int get_class_atom(REParseState *s, CharRange *cr,
const uint8_t **pp, BOOL inclass)
{
const uint8_t *p, *p_next;
const uint8_t *p;
uint32_t c;
int ret;
@ -804,18 +804,15 @@ static int get_class_atom(REParseState *s, CharRange *cr,
/* fall thru */
default:
normal_char:
p++;
if (c >= 0x80) {
c = utf8_decode(p - 1, &p_next);
if (p_next == p)
return re_parse_error(s, "invalid UTF-8 sequence");
p = p_next;
if (c > 0xFFFF && !s->is_unicode) {
// TODO(chqrlie): should handle non BMP-1 code points in
// the calling function and no require the source string
// to be CESU-8 encoded if not s->is_unicode
/* normal char */
if (c >= 128) {
c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p);
if ((unsigned)c > 0xffff && !s->is_unicode) {
/* XXX: should handle non BMP-1 code points */
return re_parse_error(s, "malformed unicode char");
}
} else {
p++;
}
break;
}
@ -1108,35 +1105,35 @@ static int re_is_simple_quantifier(const uint8_t *bc_buf, int bc_buf_len)
/* '*pp' is the first char after '<' */
static int re_parse_group_name(char *buf, int buf_size, const uint8_t **pp)
{
const uint8_t *p, *p_next;
const uint8_t *p, *p1;
uint32_t c, d;
char *q;
p = *pp;
q = buf;
for(;;) {
c = *p++;
c = *p;
if (c == '\\') {
p++;
if (*p != 'u')
return -1;
c = lre_parse_escape(&p, 2); // accept surrogate pairs
if ((int)c < 0)
return -1;
} else if (c == '>') {
break;
} else if (c >= 0x80) {
c = utf8_decode(p - 1, &p_next);
if (p_next == p)
return -1;
p = p_next;
} else if (c >= 128) {
c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p);
if (is_hi_surrogate(c)) {
d = utf8_decode(p, &p_next);
d = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p1);
if (is_lo_surrogate(d)) {
c = from_surrogate(c, d);
p = p_next;
p = p1;
}
}
} else {
p++;
}
if (c > 0x10FFFF)
return -1;
if (q == buf) {
if (!lre_js_is_ident_first(c))
return -1;
@ -1146,15 +1143,16 @@ static int re_parse_group_name(char *buf, int buf_size, const uint8_t **pp)
}
if ((q - buf + UTF8_CHAR_LEN_MAX + 1) > buf_size)
return -1;
if (c < 0x80) {
if (c < 128) {
*q++ = c;
} else {
q += utf8_encode((uint8_t*)q, c);
q += unicode_to_utf8((uint8_t*)q, c);
}
}
if (q == buf)
return -1;
*q = '\0';
p++;
*pp = p;
return 0;
}

View file

@ -53,7 +53,7 @@ int lre_exec(uint8_t **capture,
int lre_parse_escape(const uint8_t **pp, int allow_utf16);
LRE_BOOL lre_is_space(int c);
void lre_byte_swap(uint8_t *buf, size_t len, LRE_BOOL is_byte_swapped);
void lre_byte_swap(uint8_t *buf, size_t len, BOOL is_byte_swapped);
/* must be provided by the user */
LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size);

View file

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

111
qjs.c
View file

@ -58,7 +58,6 @@ static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
js_module_set_import_meta(ctx, val, TRUE, TRUE);
val = JS_EvalFunction(ctx, val);
}
val = js_std_await(ctx, val);
} else {
val = JS_Eval(ctx, buf, buf_len, filename, eval_flags);
}
@ -97,35 +96,6 @@ static int eval_file(JSContext *ctx, const char *filename, int module)
return ret;
}
static int64_t parse_limit(const char *arg) {
char *p;
unsigned long unit = 1024; /* default to traditional KB */
double d = strtod(arg, &p);
if (p == arg) {
fprintf(stderr, "Invalid limit: %s\n", arg);
return -1;
}
if (*p) {
switch (*p++) {
case 'b': case 'B': unit = 1UL << 0; break;
case 'k': case 'K': unit = 1UL << 10; break; /* IEC kibibytes */
case 'm': case 'M': unit = 1UL << 20; break; /* IEC mebibytes */
case 'g': case 'G': unit = 1UL << 30; break; /* IEC gigibytes */
default:
fprintf(stderr, "Invalid limit: %s, unrecognized suffix, only k,m,g are allowed\n", arg);
return -1;
}
if (*p) {
fprintf(stderr, "Invalid limit: %s, only one suffix allowed\n", arg);
return -1;
}
}
return (int64_t)(d * unit);
}
static JSValue js_gc(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
{
@ -229,8 +199,7 @@ static void *js_trace_malloc(JSMallocState *s, size_t size)
/* Do not allocate zero bytes: behavior is platform dependent */
assert(size != 0);
/* When malloc_limit is 0 (unlimited), malloc_limit - 1 will be SIZE_MAX. */
if (unlikely(s->malloc_size + size > s->malloc_limit - 1))
if (unlikely(s->malloc_size + size > s->malloc_limit))
return NULL;
ptr = malloc(size);
js_trace_malloc_printf(s, "A %zd -> %p\n", size, ptr);
@ -269,8 +238,7 @@ static void *js_trace_realloc(JSMallocState *s, void *ptr, size_t size)
free(ptr);
return NULL;
}
/* When malloc_limit is 0 (unlimited), malloc_limit - 1 will be SIZE_MAX. */
if (s->malloc_size + size - old_size > s->malloc_limit - 1)
if (s->malloc_size + size - old_size > s->malloc_limit)
return NULL;
js_trace_malloc_printf(s, "R %zd %p", size, ptr);
@ -305,8 +273,8 @@ void help(void)
" --std make 'std' and 'os' available to the loaded script\n"
"-T --trace trace memory allocation\n"
"-d --dump dump the memory usage stats\n"
" --memory-limit n limit the memory usage to 'n' Kbytes\n"
" --stack-size n limit the stack size to 'n' Kbytes\n"
" --memory-limit n limit the memory usage to 'n' bytes\n"
" --stack-size n limit the stack size to 'n' bytes\n"
" --unhandled-rejection dump unhandled promise rejections\n"
"-q --quit just instantiate the interpreter and quit\n", JS_GetVersion());
exit(1);
@ -321,16 +289,15 @@ int main(int argc, char **argv)
char *expr = NULL;
int interactive = 0;
int dump_memory = 0;
int dump_flags = 0;
int trace_memory = 0;
int empty_run = 0;
int module = -1;
int load_std = 0;
int dump_unhandled_promise_rejection = 0;
size_t memory_limit = 0;
char *include_list[32];
int i, include_count = 0;
int64_t memory_limit = -1;
int64_t stack_size = -1;
size_t stack_size = 0;
argv0 = (JSCFunctionListEntry)JS_PROP_STRING_DEF("argv0", argv[0],
JS_PROP_C_W_E);
@ -341,16 +308,12 @@ int main(int argc, char **argv)
while (optind < argc && *argv[optind] == '-') {
char *arg = argv[optind] + 1;
const char *longopt = "";
char *opt_arg = NULL;
/* a single - is not an option, it also stops argument scanning */
if (!*arg)
break;
optind++;
if (*arg == '-') {
longopt = arg + 1;
opt_arg = strchr(longopt, '=');
if (opt_arg)
*opt_arg++ = '\0';
arg += strlen(arg);
/* -- stops argument scanning */
if (!*longopt)
@ -358,25 +321,23 @@ int main(int argc, char **argv)
}
for (; *arg || *longopt; longopt = "") {
char opt = *arg;
if (opt) {
if (opt)
arg++;
if (!opt_arg && *arg)
opt_arg = arg;
}
if (opt == 'h' || opt == '?' || !strcmp(longopt, "help")) {
help();
continue;
}
if (opt == 'e' || !strcmp(longopt, "eval")) {
if (!opt_arg) {
if (optind >= argc) {
fprintf(stderr, "qjs: missing expression for -e\n");
exit(2);
}
opt_arg = argv[optind++];
if (*arg) {
expr = arg;
break;
}
expr = opt_arg;
break;
if (optind < argc) {
expr = argv[optind++];
break;
}
fprintf(stderr, "qjs: missing expression for -e\n");
exit(2);
}
if (opt == 'I' || !strcmp(longopt, "include")) {
if (optind >= argc) {
@ -406,10 +367,6 @@ int main(int argc, char **argv)
dump_memory++;
continue;
}
if (opt == 'D' || !strcmp(longopt, "dump-flags")) {
dump_flags = opt_arg ? strtol(opt_arg, NULL, 16) : 0;
break;
}
if (opt == 'T' || !strcmp(longopt, "trace")) {
trace_memory++;
continue;
@ -427,26 +384,20 @@ int main(int argc, char **argv)
continue;
}
if (!strcmp(longopt, "memory-limit")) {
if (!opt_arg) {
if (optind >= argc) {
fprintf(stderr, "expecting memory limit");
exit(1);
}
opt_arg = argv[optind++];
if (optind >= argc) {
fprintf(stderr, "expecting memory limit");
exit(1);
}
memory_limit = parse_limit(opt_arg);
break;
memory_limit = (size_t)strtod(argv[optind++], NULL);
continue;
}
if (!strcmp(longopt, "stack-size")) {
if (!opt_arg) {
if (optind >= argc) {
fprintf(stderr, "expecting stack size");
exit(1);
}
opt_arg = argv[optind++];
if (optind >= argc) {
fprintf(stderr, "expecting stack size");
exit(1);
}
stack_size = parse_limit(opt_arg);
break;
stack_size = (size_t)strtod(argv[optind++], NULL);
continue;
}
if (opt) {
fprintf(stderr, "qjs: unknown option '-%c'\n", opt);
@ -467,12 +418,10 @@ int main(int argc, char **argv)
fprintf(stderr, "qjs: cannot allocate JS runtime\n");
exit(2);
}
if (memory_limit >= 0)
JS_SetMemoryLimit(rt, (size_t)memory_limit);
if (stack_size >= 0)
JS_SetMaxStackSize(rt, (size_t)stack_size);
if (dump_flags != 0)
JS_SetDumpFlags(rt, dump_flags);
if (memory_limit != 0)
JS_SetMemoryLimit(rt, memory_limit);
if (stack_size != 0)
JS_SetMaxStackSize(rt, stack_size);
js_std_set_worker_new_context_func(JS_NewCustomContext);
js_std_init_handlers(rt);
ctx = JS_NewCustomContext(rt);

17
qjsc.c
View file

@ -56,7 +56,7 @@ static namelist_t cmodule_list;
static namelist_t init_module_list;
static FILE *outfile;
static const char *c_ident_prefix = "qjsc_";
static int strip;
void namelist_add(namelist_t *lp, const char *name, const char *short_name,
int flags)
@ -155,15 +155,8 @@ static void output_object_code(JSContext *ctx,
{
uint8_t *out_buf;
size_t out_buf_len;
int flags = JS_WRITE_OBJ_BYTECODE;
if (strip) {
flags |= JS_WRITE_OBJ_STRIP_SOURCE;
if (strip > 1)
flags |= JS_WRITE_OBJ_STRIP_DEBUG;
}
out_buf = JS_WriteObject(ctx, &out_buf_len, obj, flags);
out_buf = JS_WriteObject(ctx, &out_buf_len, obj, JS_WRITE_OBJ_BYTECODE);
if (!out_buf) {
js_std_dump_error(ctx);
exit(1);
@ -361,7 +354,6 @@ int main(int argc, char **argv)
cname = NULL;
module = -1;
verbose = 0;
strip = 0;
stack_size = 0;
memset(&dynamic_module_list, 0, sizeof(dynamic_module_list));
@ -370,7 +362,7 @@ int main(int argc, char **argv)
namelist_add(&cmodule_list, "os", "os", 0);
for(;;) {
c = getopt(argc, argv, "ho:N:mxesvM:p:S:D:");
c = getopt(argc, argv, "ho:N:mxevM:p:S:D:");
if (c == -1)
break;
switch(c) {
@ -407,9 +399,6 @@ int main(int argc, char **argv)
case 'D':
namelist_add(&dynamic_module_list, optarg, NULL, 0);
break;
case 's':
strip++;
break;
case 'v':
verbose++;
break;

View file

@ -170,9 +170,11 @@ DEF(status, "status")
DEF(reason, "reason")
DEF(globalThis, "globalThis")
DEF(bigint, "bigint")
#ifdef CONFIG_ATOMICS
DEF(not_equal, "not-equal")
DEF(timed_out, "timed-out")
DEF(ok, "ok")
#endif
DEF(toJSON, "toJSON")
/* class names */
DEF(Object, "Object")

View file

@ -112,10 +112,8 @@ typedef struct {
typedef struct {
struct list_head link;
uint8_t has_object:1;
uint8_t repeats:1;
BOOL has_object;
int64_t timeout;
int64_t delay;
JSValue func;
} JSOSTimer;
@ -272,21 +270,20 @@ static JSValue js_printf_internal(JSContext *ctx,
if (i >= argc)
goto missing;
if (JS_IsString(argv[i])) {
// TODO(chqrlie) need an API to wrap charCodeAt and codePointAt */
string_arg = JS_ToCString(ctx, argv[i++]);
if (!string_arg)
goto fail;
int32_arg = utf8_decode((const uint8_t *)string_arg, &p);
int32_arg = unicode_from_utf8((const uint8_t *)string_arg, UTF8_CHAR_LEN_MAX, &p);
JS_FreeCString(ctx, string_arg);
} else {
if (JS_ToInt32(ctx, &int32_arg, argv[i++]))
goto fail;
}
// XXX: throw an exception?
/* handle utf-8 encoding explicitly */
if ((unsigned)int32_arg > 0x10FFFF)
int32_arg = 0xFFFD;
/* ignore conversion flags, width and precision */
len = utf8_encode(cbuf, int32_arg);
len = unicode_to_utf8(cbuf, int32_arg);
dbuf_put(&dbuf, cbuf, len);
break;
@ -778,7 +775,6 @@ static JSValue js_evalScript(JSContext *ctx, JSValue this_val,
JSValue ret;
JSValue options_obj;
BOOL backtrace_barrier = FALSE;
BOOL is_async = FALSE;
int flags;
if (argc >= 2) {
@ -786,9 +782,6 @@ static JSValue js_evalScript(JSContext *ctx, JSValue this_val,
if (get_bool_option(ctx, &backtrace_barrier, options_obj,
"backtrace_barrier"))
return JS_EXCEPTION;
if (get_bool_option(ctx, &is_async, options_obj,
"async"))
return JS_EXCEPTION;
}
str = JS_ToCStringLen(ctx, &len, argv[0]);
@ -801,8 +794,6 @@ static JSValue js_evalScript(JSContext *ctx, JSValue this_val,
flags = JS_EVAL_TYPE_GLOBAL;
if (backtrace_barrier)
flags |= JS_EVAL_FLAG_BACKTRACE_BARRIER;
if (is_async)
flags |= JS_EVAL_FLAG_ASYNC;
ret = JS_Eval(ctx, str, len, "<evalScript>", flags);
JS_FreeCString(ctx, str);
if (!ts->recv_pipe && --ts->eval_script_recurse == 0) {
@ -2025,11 +2016,6 @@ static JSValue js_os_now(JSContext *ctx, JSValue this_val,
return JS_NewInt64(ctx, js__hrtime_ns() / 1000);
}
static uint64_t js__hrtime_ms(void)
{
return js__hrtime_ns() / (1000 * 1000);
}
static void unlink_timer(JSRuntime *rt, JSOSTimer *th)
{
if (th->link.prev) {
@ -2065,10 +2051,8 @@ static void js_os_timer_mark(JSRuntime *rt, JSValue val,
}
}
// TODO(bnoordhuis) accept string as first arg and eval at timer expiry
// TODO(bnoordhuis) retain argv[2..] as args for callback if argc > 2
static JSValue js_os_setTimeout(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv, int magic)
int argc, JSValue *argv)
{
JSRuntime *rt = JS_GetRuntime(ctx);
JSThreadState *ts = JS_GetRuntimeOpaque(rt);
@ -2082,8 +2066,6 @@ static JSValue js_os_setTimeout(JSContext *ctx, JSValue this_val,
return JS_ThrowTypeError(ctx, "not a function");
if (JS_ToInt64(ctx, &delay, argv[1]))
return JS_EXCEPTION;
if (delay < 1)
delay = 1;
obj = JS_NewObjectClass(ctx, js_os_timer_class_id);
if (JS_IsException(obj))
return obj;
@ -2093,9 +2075,7 @@ static JSValue js_os_setTimeout(JSContext *ctx, JSValue this_val,
return JS_EXCEPTION;
}
th->has_object = TRUE;
th->repeats = (magic > 0);
th->timeout = js__hrtime_ms() + delay;
th->delay = delay;
th->timeout = js__hrtime_ns() / 1e6 + delay;
th->func = JS_DupValue(ctx, func);
list_add_tail(&th->link, &ts->os_timers);
JS_SetOpaque(obj, th);
@ -2109,8 +2089,6 @@ static JSValue js_os_clearTimeout(JSContext *ctx, JSValue this_val,
if (!th)
return JS_EXCEPTION;
unlink_timer(JS_GetRuntime(ctx), th);
JS_FreeValue(ctx, th->func);
th->func = JS_UNDEFINED;
return JS_UNDEFINED;
}
@ -2120,38 +2098,6 @@ static JSClassDef js_os_timer_class = {
.gc_mark = js_os_timer_mark,
};
/* return a promise */
static JSValue js_os_sleepAsync(JSContext *ctx, JSValueConst this_val,
int argc, JSValueConst *argv)
{
JSRuntime *rt = JS_GetRuntime(ctx);
JSThreadState *ts = JS_GetRuntimeOpaque(rt);
int64_t delay;
JSOSTimer *th;
JSValue promise, resolving_funcs[2];
if (JS_ToInt64(ctx, &delay, argv[0]))
return JS_EXCEPTION;
promise = JS_NewPromiseCapability(ctx, resolving_funcs);
if (JS_IsException(promise))
return JS_EXCEPTION;
th = js_mallocz(ctx, sizeof(*th));
if (!th) {
JS_FreeValue(ctx, promise);
JS_FreeValue(ctx, resolving_funcs[0]);
JS_FreeValue(ctx, resolving_funcs[1]);
return JS_EXCEPTION;
}
th->has_object = FALSE;
th->timeout = js__hrtime_ms() + delay;
th->func = JS_DupValue(ctx, resolving_funcs[0]);
list_add_tail(&th->link, &ts->os_timers);
JS_FreeValue(ctx, resolving_funcs[0]);
JS_FreeValue(ctx, resolving_funcs[1]);
return promise;
}
static void call_handler(JSContext *ctx, JSValue func)
{
JSValue ret, func1;
@ -2165,43 +2111,6 @@ static void call_handler(JSContext *ctx, JSValue func)
JS_FreeValue(ctx, ret);
}
static int js_os_run_timers(JSRuntime *rt, JSContext *ctx, JSThreadState *ts)
{
JSValue func;
JSOSTimer *th;
int min_delay;
int64_t cur_time, delay;
struct list_head *el;
if (list_empty(&ts->os_timers))
return -1;
cur_time = js__hrtime_ms();
min_delay = 10000;
list_for_each(el, &ts->os_timers) {
th = list_entry(el, JSOSTimer, link);
delay = th->timeout - cur_time;
if (delay > 0) {
min_delay = min_int(min_delay, delay);
} else {
func = JS_DupValueRT(rt, th->func);
unlink_timer(rt, th);
if (th->repeats) {
th->timeout = cur_time + th->delay;
list_add_tail(&th->link, &ts->os_timers);
} else if (!th->has_object) {
free_timer(rt, th);
}
call_handler(ctx, func);
JS_FreeValueRT(rt, func);
return 0;
}
}
return min_delay;
}
#if defined(_WIN32)
static int js_os_poll(JSContext *ctx)
@ -2209,17 +2118,40 @@ static int js_os_poll(JSContext *ctx)
JSRuntime *rt = JS_GetRuntime(ctx);
JSThreadState *ts = JS_GetRuntimeOpaque(rt);
int min_delay, console_fd;
int64_t cur_time, delay;
JSOSRWHandler *rh;
struct list_head *el;
/* XXX: handle signals if useful */
min_delay = js_os_run_timers(rt, ctx, ts);
if (min_delay == 0)
return 0; // expired timer
if (min_delay < 0)
if (list_empty(&ts->os_rw_handlers))
return -1; /* no more events */
if (list_empty(&ts->os_rw_handlers) && list_empty(&ts->os_timers))
return -1; /* no more events */
/* XXX: only timers and basic console input are supported */
if (!list_empty(&ts->os_timers)) {
cur_time = js__hrtime_ns() / 1e6;
min_delay = 10000;
list_for_each(el, &ts->os_timers) {
JSOSTimer *th = list_entry(el, JSOSTimer, link);
delay = th->timeout - cur_time;
if (delay <= 0) {
JSValue func;
/* the timer expired */
func = th->func;
th->func = JS_UNDEFINED;
unlink_timer(rt, th);
if (!th->has_object)
free_timer(rt, th);
call_handler(ctx, func);
JS_FreeValue(ctx, func);
return 0;
} else if (delay < min_delay) {
min_delay = delay;
}
}
} else {
min_delay = -1;
}
console_fd = -1;
list_for_each(el, &ts->os_rw_handlers) {
@ -2338,6 +2270,7 @@ static int js_os_poll(JSContext *ctx)
JSRuntime *rt = JS_GetRuntime(ctx);
JSThreadState *ts = JS_GetRuntimeOpaque(rt);
int ret, fd_max, min_delay;
int64_t cur_time, delay;
fd_set rfds, wfds;
JSOSRWHandler *rh;
struct list_head *el;
@ -2360,18 +2293,36 @@ static int js_os_poll(JSContext *ctx)
}
}
min_delay = js_os_run_timers(rt, ctx, ts);
if (min_delay == 0)
return 0; // expired timer
if (min_delay < 0)
if (list_empty(&ts->os_rw_handlers) && list_empty(&ts->port_list))
return -1; /* no more events */
if (list_empty(&ts->os_rw_handlers) && list_empty(&ts->os_timers) &&
list_empty(&ts->port_list))
return -1; /* no more events */
tvp = NULL;
if (min_delay >= 0) {
if (!list_empty(&ts->os_timers)) {
cur_time = js__hrtime_ns() / 1e6;
min_delay = 10000;
list_for_each(el, &ts->os_timers) {
JSOSTimer *th = list_entry(el, JSOSTimer, link);
delay = th->timeout - cur_time;
if (delay <= 0) {
JSValue func;
/* the timer expired */
func = th->func;
th->func = JS_UNDEFINED;
unlink_timer(rt, th);
if (!th->has_object)
free_timer(rt, th);
call_handler(ctx, func);
JS_FreeValue(ctx, func);
return 0;
} else if (delay < min_delay) {
min_delay = delay;
}
}
tv.tv_sec = min_delay / 1000;
tv.tv_usec = (min_delay % 1000) * 1000;
tvp = &tv;
} else {
tvp = NULL;
}
FD_ZERO(&rfds);
@ -3367,7 +3318,6 @@ static void *worker_func(void *opaque)
JSRuntime *rt;
JSThreadState *ts;
JSContext *ctx;
JSValue val;
rt = JS_NewRuntime();
if (rt == NULL) {
@ -3394,14 +3344,11 @@ static void *worker_func(void *opaque)
js_std_add_helpers(ctx, -1, NULL);
val = JS_LoadModule(ctx, args->basename, args->filename);
if (!JS_RunModule(ctx, args->basename, args->filename))
js_std_dump_error(ctx);
free(args->filename);
free(args->basename);
free(args);
val = js_std_await(ctx, val);
if (JS_IsException(val))
js_std_dump_error(ctx);
JS_FreeValue(ctx, val);
js_std_loop(ctx);
@ -3739,12 +3686,8 @@ static const JSCFunctionListEntry js_os_funcs[] = {
JS_CFUNC_DEF("cputime", 0, js_os_cputime ),
#endif
JS_CFUNC_DEF("now", 0, js_os_now ),
JS_CFUNC_MAGIC_DEF("setTimeout", 2, js_os_setTimeout, 0 ),
JS_CFUNC_MAGIC_DEF("setInterval", 2, js_os_setTimeout, 1 ),
// per spec: both functions can cancel timeouts and intervals
JS_CFUNC_DEF("setTimeout", 2, js_os_setTimeout ),
JS_CFUNC_DEF("clearTimeout", 1, js_os_clearTimeout ),
JS_CFUNC_DEF("clearInterval", 1, js_os_clearTimeout ),
JS_CFUNC_DEF("sleepAsync", 1, js_os_sleepAsync ),
JS_PROP_STRING_DEF("platform", OS_PLATFORM, 0 ),
JS_CFUNC_DEF("getcwd", 0, js_os_getcwd ),
JS_CFUNC_DEF("chdir", 0, js_os_chdir ),
@ -4023,42 +3966,6 @@ void js_std_loop(JSContext *ctx)
}
}
/* Wait for a promise and execute pending jobs while waiting for
it. Return the promise result or JS_EXCEPTION in case of promise
rejection. */
JSValue js_std_await(JSContext *ctx, JSValue obj)
{
JSValue ret;
int state;
for(;;) {
state = JS_PromiseState(ctx, obj);
if (state == JS_PROMISE_FULFILLED) {
ret = JS_PromiseResult(ctx, obj);
JS_FreeValue(ctx, obj);
break;
} else if (state == JS_PROMISE_REJECTED) {
ret = JS_Throw(ctx, JS_PromiseResult(ctx, obj));
JS_FreeValue(ctx, obj);
break;
} else if (state == JS_PROMISE_PENDING) {
JSContext *ctx1;
int err;
err = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1);
if (err < 0) {
js_std_dump_error(ctx1);
}
if (os_poll_func)
os_poll_func(ctx);
} else {
/* not a promise */
ret = obj;
break;
}
}
return ret;
}
void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
int load_only)
{
@ -4077,11 +3984,8 @@ void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
goto exception;
}
js_module_set_import_meta(ctx, obj, FALSE, TRUE);
val = JS_EvalFunction(ctx, obj);
val = js_std_await(ctx, val);
} else {
val = JS_EvalFunction(ctx, obj);
}
val = JS_EvalFunction(ctx, obj);
if (JS_IsException(val)) {
exception:
js_std_dump_error(ctx);

View file

@ -37,7 +37,6 @@ JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name);
JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name);
void js_std_add_helpers(JSContext *ctx, int argc, char **argv);
void js_std_loop(JSContext *ctx);
JSValue js_std_await(JSContext *ctx, JSValue obj);
void js_std_init_handlers(JSRuntime *rt);
void js_std_free_handlers(JSRuntime *rt);
void js_std_dump_error(JSContext *ctx);

View file

@ -136,12 +136,9 @@ DEF( put_ref_value, 1, 3, 0, none)
DEF( define_var, 6, 0, 0, atom_u8)
DEF(check_define_var, 6, 0, 0, atom_u8)
DEF( define_func, 6, 1, 0, atom_u8)
// order matters, see IC counterparts
DEF( get_field, 5, 1, 1, atom)
DEF( get_field2, 5, 1, 2, atom)
DEF( put_field, 5, 2, 0, atom)
DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */
DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */
DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */
@ -361,7 +358,6 @@ DEF( is_null, 1, 1, 1, none)
DEF(typeof_is_undefined, 1, 1, 1, none)
DEF( typeof_is_function, 1, 1, 1, none)
// order matters, see non-IC counterparts
DEF( get_field_ic, 5, 1, 1, none)
DEF( get_field2_ic, 5, 1, 2, none)
DEF( put_field_ic, 5, 2, 0, none)

4379
quickjs.c

File diff suppressed because it is too large Load diff

157
quickjs.h
View file

@ -29,18 +29,18 @@
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <math.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(__GNUC__) || defined(__clang__)
#define js_unlikely(x) __builtin_expect(!!(x), 0)
#define js_force_inline inline __attribute__((always_inline))
#define __js_printf_like(f, a) __attribute__((format(printf, f, a)))
#define JS_EXTERN __attribute__((visibility("default")))
#else
#define js_unlikely(x) (x)
#define js_force_inline inline
#define __js_printf_like(a, b)
#define JS_EXTERN /* nothing */
@ -55,12 +55,6 @@ typedef struct JSClass JSClass;
typedef uint32_t JSClassID;
typedef uint32_t JSAtom;
/* Unless documented otherwise, C string pointers (`char *` or `const char *`)
are assumed to verify these constraints:
- unless a length is passed separately, the string has a null terminator
- string contents is either pure ASCII or is UTF-8 encoded.
*/
#if INTPTR_MAX < INT64_MAX
/* Use NAN boxing for 32bit builds. */
#define JS_NAN_BOXING
@ -130,7 +124,7 @@ static inline JSValue __JS_NewFloat64(double d)
JSValue v;
u.d = d;
/* normalize NaN */
if ((u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000)
if (js_unlikely((u.u64 & 0x7fffffffffffffff) > 0x7ff0000000000000))
v = JS_NAN;
else
v = u.u64 - ((uint64_t)JS_FLOAT64_TAG_ADDEND << 32);
@ -183,7 +177,7 @@ typedef struct JSValue {
#define JS_TAG_IS_FLOAT64(tag) ((unsigned)(tag) == JS_TAG_FLOAT64)
#define JS_NAN (JSValue){ (JSValueUnion){ .float64 = JS_FLOAT64_NAN }, JS_TAG_FLOAT64 }
#define JS_NAN (JSValue){ .u.float64 = JS_FLOAT64_NAN, JS_TAG_FLOAT64 }
static inline JSValue __JS_NewFloat64(double d)
{
@ -211,6 +205,7 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
#define JS_VALUE_IS_BOTH_FLOAT(v1, v2) (JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(v1)) && JS_TAG_IS_FLOAT64(JS_VALUE_GET_TAG(v2)))
#define JS_VALUE_GET_OBJ(v) ((JSObject *)JS_VALUE_GET_PTR(v))
#define JS_VALUE_GET_STRING(v) ((JSString *)JS_VALUE_GET_PTR(v))
#define JS_VALUE_HAS_REF_COUNT(v) ((unsigned)JS_VALUE_GET_TAG(v) >= (unsigned)JS_TAG_FIRST)
/* special values */
@ -275,9 +270,6 @@ static inline JS_BOOL JS_VALUE_IS_NAN(JSValue v)
#define JS_EVAL_FLAG_COMPILE_ONLY (1 << 5)
/* don't include the stack frames before this eval in the Error() backtraces */
#define JS_EVAL_FLAG_BACKTRACE_BARRIER (1 << 6)
/* allow top-level await in normal script. JS_Eval() returns a
promise. Only allowed with JS_EVAL_TYPE_GLOBAL */
#define JS_EVAL_FLAG_ASYNC (1 << 7)
typedef JSValue JSCFunction(JSContext *ctx, JSValue this_val, int argc, JSValue *argv);
typedef JSValue JSCFunctionMagic(JSContext *ctx, JSValue this_val, int argc, JSValue *argv, int magic);
@ -302,10 +294,7 @@ typedef struct JSGCObjectHeader JSGCObjectHeader;
JS_EXTERN JSRuntime *JS_NewRuntime(void);
/* info lifetime must exceed that of rt */
JS_EXTERN void JS_SetRuntimeInfo(JSRuntime *rt, const char *info);
/* use 0 to disable memory limit */
JS_EXTERN void JS_SetMemoryLimit(JSRuntime *rt, size_t limit);
JS_EXTERN void JS_SetDumpFlags(JSRuntime *rt, uint64_t flags);
JS_EXTERN size_t JS_GetGCThreshold(JSRuntime *rt);
JS_EXTERN void JS_SetGCThreshold(JSRuntime *rt, size_t gc_threshold);
/* use 0 to disable maximum stack size check */
JS_EXTERN void JS_SetMaxStackSize(JSRuntime *rt, size_t stack_size);
@ -347,13 +336,6 @@ JS_EXTERN void JS_AddIntrinsicBigInt(JSContext *ctx);
JS_EXTERN void JS_AddIntrinsicWeakRef(JSContext *ctx);
JS_EXTERN void JS_AddPerformance(JSContext *ctx);
/* for equality comparisons and sameness */
JS_EXTERN int JS_IsEqual(JSContext *ctx, JSValue op1, JSValue op2);
JS_EXTERN JS_BOOL JS_IsStrictEqual(JSContext *ctx, JSValue op1, JSValue op2);
JS_EXTERN JS_BOOL JS_IsSameValue(JSContext *ctx, JSValue op1, JSValue op2);
/* Similar to same-value equality, but +0 and -0 are considered equal. */
JS_EXTERN JS_BOOL JS_IsSameValueZero(JSContext *ctx, JSValue op1, JSValue op2);
/* Only used for running 262 tests. TODO(saghul) add build time flag. */
JS_EXTERN JSValue js_string_codePointRange(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv);
@ -459,7 +441,7 @@ typedef JSValue JSClassCall(JSContext *ctx, JSValue func_obj,
int flags);
typedef struct JSClassDef {
const char *class_name; /* pure ASCII only! */
const char *class_name;
JSClassFinalizer *finalizer;
JSClassGCMark *gc_mark;
/* if call != NULL, the object is a function. If (flags &
@ -492,11 +474,6 @@ static js_force_inline JSValue JS_NewInt32(JSContext *ctx, int32_t val)
return JS_MKVAL(JS_TAG_INT, val);
}
static js_force_inline JSValue JS_NewFloat64(JSContext *ctx, double val)
{
return __JS_NewFloat64(val);
}
static js_force_inline JSValue JS_NewCatchOffset(JSContext *ctx, int32_t val)
{
return JS_MKVAL(JS_TAG_CATCH_OFFSET, val);
@ -505,10 +482,10 @@ static js_force_inline JSValue JS_NewCatchOffset(JSContext *ctx, int32_t val)
static js_force_inline JSValue JS_NewInt64(JSContext *ctx, int64_t val)
{
JSValue v;
if (val >= INT32_MIN && val <= INT32_MAX) {
v = JS_NewInt32(ctx, (int32_t)val);
if (val == (int32_t)val) {
v = JS_NewInt32(ctx, val);
} else {
v = JS_NewFloat64(ctx, (double)val);
v = __JS_NewFloat64(val);
}
return v;
}
@ -517,14 +494,14 @@ static js_force_inline JSValue JS_NewUint32(JSContext *ctx, uint32_t val)
{
JSValue v;
if (val <= 0x7fffffff) {
v = JS_NewInt32(ctx, (int32_t)val);
v = JS_NewInt32(ctx, val);
} else {
v = JS_NewFloat64(ctx, (double)val);
v = __JS_NewFloat64(val);
}
return v;
}
JS_EXTERN JSValue JS_NewNumber(JSContext *ctx, double d);
JS_EXTERN JSValue JS_NewFloat64(JSContext *ctx, double d);
JS_EXTERN JSValue JS_NewBigInt64(JSContext *ctx, int64_t v);
JS_EXTERN JSValue JS_NewBigUint64(JSContext *ctx, uint64_t v);
@ -557,12 +534,12 @@ static inline JS_BOOL JS_IsUndefined(JSValue v)
static inline JS_BOOL JS_IsException(JSValue v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_EXCEPTION;
return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_EXCEPTION);
}
static inline JS_BOOL JS_IsUninitialized(JSValue v)
{
return JS_VALUE_GET_TAG(v) == JS_TAG_UNINITIALIZED;
return js_unlikely(JS_VALUE_GET_TAG(v) == JS_TAG_UNINITIALIZED);
}
static inline JS_BOOL JS_IsString(JSValue v)
@ -585,7 +562,6 @@ JS_EXTERN JSValue JS_GetException(JSContext *ctx);
JS_EXTERN JS_BOOL JS_IsError(JSContext *ctx, JSValue val);
JS_EXTERN void JS_ResetUncatchableError(JSContext *ctx);
JS_EXTERN JSValue JS_NewError(JSContext *ctx);
JS_EXTERN JSValue __js_printf_like(2, 3) JS_ThrowPlainError(JSContext *ctx, const char *fmt, ...);
JS_EXTERN JSValue __js_printf_like(2, 3) JS_ThrowSyntaxError(JSContext *ctx, const char *fmt, ...);
JS_EXTERN JSValue __js_printf_like(2, 3) JS_ThrowTypeError(JSContext *ctx, const char *fmt, ...);
JS_EXTERN JSValue __js_printf_like(2, 3) JS_ThrowReferenceError(JSContext *ctx, const char *fmt, ...);
@ -643,14 +619,11 @@ JS_EXTERN int JS_ToIndex(JSContext *ctx, uint64_t *plen, JSValue val);
JS_EXTERN int JS_ToFloat64(JSContext *ctx, double *pres, JSValue val);
/* return an exception if 'val' is a Number */
JS_EXTERN int JS_ToBigInt64(JSContext *ctx, int64_t *pres, JSValue val);
JS_EXTERN int JS_ToBigUint64(JSContext *ctx, uint64_t *pres, JSValue val);
/* same as JS_ToInt64() but allow BigInt */
JS_EXTERN int JS_ToInt64Ext(JSContext *ctx, int64_t *pres, JSValue val);
JS_EXTERN JSValue JS_NewStringLen(JSContext *ctx, const char *str1, size_t len1);
static inline JSValue JS_NewString(JSContext *ctx, const char *str) {
return JS_NewStringLen(ctx, str, strlen(str));
}
JS_EXTERN JSValue JS_NewString(JSContext *ctx, const char *str);
JS_EXTERN JSValue JS_NewAtomString(JSContext *ctx, const char *str);
JS_EXTERN JSValue JS_ToString(JSContext *ctx, JSValue val);
JS_EXTERN JSValue JS_ToPropertyKey(JSContext *ctx, JSValue val);
@ -679,16 +652,27 @@ JS_EXTERN int JS_IsArray(JSContext *ctx, JSValue val);
JS_EXTERN JSValue JS_NewDate(JSContext *ctx, double epoch_ms);
JS_EXTERN JSValue JS_GetProperty(JSContext *ctx, JSValue this_obj, JSAtom prop);
JS_EXTERN JSValue JS_GetPropertyUint32(JSContext *ctx, JSValue this_obj,
uint32_t idx);
JS_EXTERN JSValue JS_GetPropertyInt64(JSContext *ctx, JSValue this_obj,
int64_t idx);
JS_EXTERN JSValue JS_GetPropertyInternal(JSContext *ctx, JSValue obj,
JSAtom prop, JSValue receiver,
JS_BOOL throw_ref_error);
static js_force_inline JSValue JS_GetProperty(JSContext *ctx, JSValue this_obj,
JSAtom prop)
{
return JS_GetPropertyInternal(ctx, this_obj, prop, this_obj, 0);
}
JS_EXTERN JSValue JS_GetPropertyStr(JSContext *ctx, JSValue this_obj,
const char *prop);
JS_EXTERN JSValue JS_GetPropertyUint32(JSContext *ctx, JSValue this_obj,
uint32_t idx);
JS_EXTERN int JS_SetProperty(JSContext *ctx, JSValue this_obj,
JSAtom prop, JSValue val);
int JS_SetPropertyInternal(JSContext *ctx, JSValue this_obj,
JSAtom prop, JSValue val,
int flags);
static inline int JS_SetProperty(JSContext *ctx, JSValue this_obj,
JSAtom prop, JSValue val)
{
return JS_SetPropertyInternal(ctx, this_obj, prop, val, JS_PROP_THROW);
}
JS_EXTERN int JS_SetPropertyUint32(JSContext *ctx, JSValue this_obj,
uint32_t idx, JSValue val);
JS_EXTERN int JS_SetPropertyInt64(JSContext *ctx, JSValue this_obj,
@ -701,7 +685,6 @@ JS_EXTERN int JS_PreventExtensions(JSContext *ctx, JSValue obj);
JS_EXTERN int JS_DeleteProperty(JSContext *ctx, JSValue obj, JSAtom prop, int flags);
JS_EXTERN int JS_SetPrototype(JSContext *ctx, JSValue obj, JSValue proto_val);
JS_EXTERN JSValue JS_GetPrototype(JSContext *ctx, JSValue val);
JS_EXTERN int JS_GetLength(JSContext *ctx, JSValue obj, int64_t *pres);
#define JS_GPN_STRING_MASK (1 << 0)
#define JS_GPN_SYMBOL_MASK (1 << 1)
@ -715,8 +698,6 @@ JS_EXTERN int JS_GetOwnPropertyNames(JSContext *ctx, JSPropertyEnum **ptab,
uint32_t *plen, JSValue obj, int flags);
JS_EXTERN int JS_GetOwnProperty(JSContext *ctx, JSPropertyDescriptor *desc,
JSValue obj, JSAtom prop);
JS_EXTERN void JS_FreePropertyEnum(JSContext *ctx, JSPropertyEnum *tab,
uint32_t len);
JS_EXTERN JSValue JS_Call(JSContext *ctx, JSValue func_obj, JSValue this_obj,
int argc, JSValue *argv);
@ -786,17 +767,7 @@ typedef struct {
} JSSharedArrayBufferFunctions;
JS_EXTERN void JS_SetSharedArrayBufferFunctions(JSRuntime *rt, const JSSharedArrayBufferFunctions *sf);
typedef enum JSPromiseStateEnum {
JS_PROMISE_PENDING,
JS_PROMISE_FULFILLED,
JS_PROMISE_REJECTED,
} JSPromiseStateEnum;
JS_EXTERN JSValue JS_NewPromiseCapability(JSContext *ctx, JSValue *resolving_funcs);
JS_EXTERN JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise);
JS_EXTERN JSValue JS_PromiseResult(JSContext *ctx, JSValue promise);
JS_EXTERN JSValue JS_NewSymbol(JSContext *ctx, const char *description, JS_BOOL is_global);
/* is_handled = TRUE means that the rejection is handled */
typedef void JSHostPromiseRejectionTracker(JSContext *ctx, JSValue promise,
@ -844,9 +815,9 @@ JS_EXTERN int JS_ExecutePendingJob(JSRuntime *rt, JSContext **pctx);
#define JS_WRITE_OBJ_BYTECODE (1 << 0) /* allow function/module */
#define JS_WRITE_OBJ_BSWAP (0) /* byte swapped output (obsolete, handled transparently) */
#define JS_WRITE_OBJ_SAB (1 << 2) /* allow SharedArrayBuffer */
#define JS_WRITE_OBJ_REFERENCE (1 << 3) /* allow object references to encode arbitrary object graph */
#define JS_WRITE_OBJ_STRIP_SOURCE (1 << 4) /* do not write source code information */
#define JS_WRITE_OBJ_STRIP_DEBUG (1 << 5) /* do not write debug information */
#define JS_WRITE_OBJ_REFERENCE (1 << 3) /* allow object references to
encode arbitrary object
graph */
JS_EXTERN uint8_t *JS_WriteObject(JSContext *ctx, size_t *psize, JSValue obj, int flags);
JS_EXTERN uint8_t *JS_WriteObject2(JSContext *ctx, size_t *psize, JSValue obj,
int flags, uint8_t ***psab_tab, size_t *psab_tab_len);
@ -866,8 +837,8 @@ JS_EXTERN int JS_ResolveModule(JSContext *ctx, JSValue obj);
/* only exported for os.Worker() */
JS_EXTERN JSAtom JS_GetScriptOrModuleName(JSContext *ctx, int n_stack_levels);
/* only exported for os.Worker() */
JS_EXTERN JSValue JS_LoadModule(JSContext *ctx, const char *basename,
const char *filename);
JS_EXTERN JSModuleDef *JS_RunModule(JSContext *ctx, const char *basename,
const char *filename);
/* C function definition */
typedef enum JSCFunctionEnum { /* XXX: should rename for namespace isolation */
@ -929,7 +900,7 @@ JS_EXTERN void JS_SetConstructor(JSContext *ctx, JSValue func_obj,
/* C property definition */
typedef struct JSCFunctionListEntry {
const char *name; /* pure ASCII or UTF-8 encoded */
const char *name;
uint8_t prop_flags;
uint8_t def_type;
int16_t magic;
@ -951,7 +922,7 @@ typedef struct JSCFunctionListEntry {
const struct JSCFunctionListEntry *tab;
int len;
} prop_list;
const char *str; /* pure ASCII or UTF-8 encoded */
const char *str;
int32_t i32;
int64_t i64;
double f64;
@ -970,21 +941,21 @@ typedef struct JSCFunctionListEntry {
#define JS_DEF_ALIAS 9
/* Note: c++ does not like nested designators */
#define JS_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
#define JS_CFUNC_DEF2(name, length, func1, prop_flags) { name, prop_flags, JS_DEF_CFUNC, 0, { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
#define JS_CFUNC_MAGIC_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, { .func = { length, JS_CFUNC_generic_magic, { .generic_magic = func1 } } } }
#define JS_CFUNC_SPECIAL_DEF(name, length, cproto, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, { .func = { length, JS_CFUNC_ ## cproto, { .cproto = func1 } } } }
#define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, { .func = { length, JS_CFUNC_iterator_next, { .iterator_next = func1 } } } }
#define JS_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET, 0, { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
#define JS_CGETSET_MAGIC_DEF(name, fgetter, fsetter, magic) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET_MAGIC, magic, { .getset = { .get = { .getter_magic = fgetter }, .set = { .setter_magic = fsetter } } } }
#define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, { .str = cstr } }
#define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, { .i32 = val } }
#define JS_PROP_INT64_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT64, 0, { .i64 = val } }
#define JS_PROP_DOUBLE_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_DOUBLE, 0, { .f64 = val } }
#define JS_PROP_UNDEFINED_DEF(name, prop_flags) { name, prop_flags, JS_DEF_PROP_UNDEFINED, 0, { .i32 = 0 } }
#define JS_OBJECT_DEF(name, tab, len, prop_flags) { name, prop_flags, JS_DEF_OBJECT, 0, { .prop_list = { tab, len } } }
#define JS_ALIAS_DEF(name, from) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, { .alias = { from, -1 } } }
#define JS_ALIAS_BASE_DEF(name, from, base) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, { .alias = { from, base } } }
#define JS_CFUNC_DEF(name, length, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
#define JS_CFUNC_DEF2(name, length, func1, prop_flags) { name, prop_flags, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_generic, { .generic = func1 } } } }
#define JS_CFUNC_MAGIC_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_generic_magic, { .generic_magic = func1 } } } }
#define JS_CFUNC_SPECIAL_DEF(name, length, cproto, func1) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, 0, .u = { .func = { length, JS_CFUNC_ ## cproto, { .cproto = func1 } } } }
#define JS_ITERATOR_NEXT_DEF(name, length, func1, magic) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_CFUNC, magic, .u = { .func = { length, JS_CFUNC_iterator_next, { .iterator_next = func1 } } } }
#define JS_CGETSET_DEF(name, fgetter, fsetter) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET, 0, .u = { .getset = { .get = { .getter = fgetter }, .set = { .setter = fsetter } } } }
#define JS_CGETSET_MAGIC_DEF(name, fgetter, fsetter, magic) { name, JS_PROP_CONFIGURABLE, JS_DEF_CGETSET_MAGIC, magic, .u = { .getset = { .get = { .getter_magic = fgetter }, .set = { .setter_magic = fsetter } } } }
#define JS_PROP_STRING_DEF(name, cstr, prop_flags) { name, prop_flags, JS_DEF_PROP_STRING, 0, .u = { .str = cstr } }
#define JS_PROP_INT32_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT32, 0, .u = { .i32 = val } }
#define JS_PROP_INT64_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_INT64, 0, .u = { .i64 = val } }
#define JS_PROP_DOUBLE_DEF(name, val, prop_flags) { name, prop_flags, JS_DEF_PROP_DOUBLE, 0, .u = { .f64 = val } }
#define JS_PROP_UNDEFINED_DEF(name, prop_flags) { name, prop_flags, JS_DEF_PROP_UNDEFINED, 0, .u = { .i32 = 0 } }
#define JS_OBJECT_DEF(name, tab, len, prop_flags) { name, prop_flags, JS_DEF_OBJECT, 0, .u = { .prop_list = { tab, len } } }
#define JS_ALIAS_DEF(name, from) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, -1 } } }
#define JS_ALIAS_BASE_DEF(name, from, base) { name, JS_PROP_WRITABLE | JS_PROP_CONFIGURABLE, JS_DEF_ALIAS, 0, .u = { .alias = { from, base } } }
JS_EXTERN void JS_SetPropertyFunctionList(JSContext *ctx, JSValue obj,
const JSCFunctionListEntry *tab,
@ -1006,16 +977,32 @@ JS_EXTERN int JS_SetModuleExport(JSContext *ctx, JSModuleDef *m, const char *exp
JS_EXTERN int JS_SetModuleExportList(JSContext *ctx, JSModuleDef *m,
const JSCFunctionListEntry *tab, int len);
/* Promise */
#define JS_INVALID_PROMISE_STATE (-1)
typedef enum JSPromiseStateEnum {
JS_PROMISE_PENDING,
JS_PROMISE_FULFILLED,
JS_PROMISE_REJECTED,
} JSPromiseStateEnum;
/* Returns JSPromiseReactionEnum for the promise or JS_INVALID_PROMISE_STATE if the value is not a promise. */
JS_EXTERN JSPromiseStateEnum JS_PromiseState(JSContext *ctx, JSValue promise);
/* Return the result of the promise if the promise's state is in the FULFILLED or REJECTED state. Otherwise returns JS_UNDEFINED. */
JS_EXTERN JSValue JS_PromiseResult(JSContext *ctx, JSValue promise);
/* Version */
#define QJS_VERSION_MAJOR 0
#define QJS_VERSION_MINOR 6
#define QJS_VERSION_MINOR 5
#define QJS_VERSION_PATCH 0
#define QJS_VERSION_SUFFIX "dev"
JS_EXTERN const char* JS_GetVersion(void);
#undef JS_EXTERN
#undef js_unlikely
#undef js_force_inline
#undef __js_printf_like

947
repl.js

File diff suppressed because it is too large Load diff

View file

@ -1198,7 +1198,7 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
{
JSValue res_val, exception_val;
int ret, error_line, pos, pos_line;
BOOL is_error, has_error_line, ret_promise;
BOOL is_error, has_error_line;
const char *error_name;
pos = skip_comments(buf, 1, &pos_line);
@ -1207,19 +1207,12 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
exception_val = JS_UNDEFINED;
error_name = NULL;
/* a module evaluation returns a promise */
ret_promise = ((eval_flags & JS_EVAL_TYPE_MODULE) != 0);
async_done = 0; /* counter of "Test262:AsyncTestComplete" messages */
res_val = JS_Eval(ctx, buf, buf_len, filename, eval_flags);
if ((is_async || ret_promise) && !JS_IsException(res_val)) {
JSValue promise = JS_UNDEFINED;
if (ret_promise) {
promise = res_val;
} else {
JS_FreeValue(ctx, res_val);
}
if (is_async && !JS_IsException(res_val)) {
JS_FreeValue(ctx, res_val);
for(;;) {
JSContext *ctx1;
ret = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1);
@ -1227,26 +1220,37 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
res_val = JS_EXCEPTION;
break;
} else if (ret == 0) {
if (is_async) {
/* test if the test called $DONE() once */
if (async_done != 1) {
res_val = JS_ThrowTypeError(ctx, "$DONE() not called");
} else {
res_val = JS_UNDEFINED;
}
/* test if the test called $DONE() once */
if (async_done != 1) {
res_val = JS_ThrowTypeError(ctx, "$DONE() not called");
} else {
/* check that the returned promise is fulfilled */
JSPromiseStateEnum state = JS_PromiseState(ctx, promise);
if (state == JS_PROMISE_FULFILLED)
res_val = JS_UNDEFINED;
else if (state == JS_PROMISE_REJECTED)
res_val = JS_Throw(ctx, JS_PromiseResult(ctx, promise));
else
res_val = JS_ThrowTypeError(ctx, "promise is pending");
res_val = JS_UNDEFINED;
}
break;
}
}
} else if ((eval_flags & JS_EVAL_TYPE_MODULE) &&
!JS_IsUndefined(res_val) &&
!JS_IsException(res_val)) {
JSValue promise = res_val;
for(;;) {
JSContext *ctx1;
ret = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1);
if (ret < 0) {
res_val = JS_EXCEPTION;
break;
}
if (ret == 0) {
JSPromiseStateEnum s = JS_PromiseState(ctx, promise);
if (s == JS_PROMISE_FULFILLED)
res_val = JS_UNDEFINED;
else if (s == JS_PROMISE_REJECTED)
res_val = JS_Throw(ctx, JS_PromiseResult(ctx, promise));
else
res_val = JS_EXCEPTION;
break;
}
}
JS_FreeValue(ctx, promise);
}
@ -1295,15 +1299,11 @@ static int eval_buf(JSContext *ctx, const char *buf, size_t buf_len,
const char *msg;
msg = JS_ToCString(ctx, exception_val);
if (msg == NULL) {
error_class = strdup_len(msg, strcspn(msg, ":"));
if (!str_equal(error_class, error_type))
ret = -1;
} else {
error_class = strdup_len(msg, strcspn(msg, ":"));
if (!str_equal(error_class, error_type))
ret = -1;
free(error_class);
JS_FreeCString(ctx, msg);
}
free(error_class);
JS_FreeCString(ctx, msg);
}
} else {
ret = -1;
@ -1503,9 +1503,7 @@ void update_stats(JSRuntime *rt, const char *filename) {
JS_ComputeMemoryUsage(rt, &stats);
if (stats_count++ == 0) {
stats_avg = stats_all = stats_min = stats_max = stats;
free(stats_min_filename);
stats_min_filename = strdup(filename);
free(stats_max_filename);
stats_max_filename = strdup(filename);
} else {
if (stats_max.malloc_size < stats.malloc_size) {
@ -1883,32 +1881,17 @@ int run_test262_harness_test(const char *filename, BOOL is_module)
js_std_dump_error(ctx);
ret_code = 1;
} else {
JSValue promise = JS_UNDEFINED;
if (is_module) {
promise = res_val;
} else {
JS_FreeValue(ctx, res_val);
}
JS_FreeValue(ctx, res_val);
for(;;) {
JSContext *ctx1;
ret = JS_ExecutePendingJob(JS_GetRuntime(ctx), &ctx1);
if (ret < 0) {
js_std_dump_error(ctx1);
ret_code = 1;
js_std_dump_error(ctx1);
ret_code = 1;
} else if (ret == 0) {
break;
break;
}
}
/* dump the error if the module returned an error. */
if (is_module) {
JSPromiseStateEnum state = JS_PromiseState(ctx, promise);
if (state == JS_PROMISE_REJECTED) {
JS_Throw(ctx, JS_PromiseResult(ctx, promise));
js_std_dump_error(ctx);
ret_code = 1;
}
}
JS_FreeValue(ctx, promise);
}
}
free(buf);
#ifdef CONFIG_AGENT
@ -2195,12 +2178,7 @@ int main(int argc, char **argv)
free(harness_dir);
free(harness_features);
free(harness_exclude);
free(harness_skip_features);
free(error_file);
free(error_filename);
free(report_filename);
free(stats_min_filename);
free(stats_max_filename);
/* Signal that the error file is out of date. */
return new_errors || changed_errors || fixed_errors;

View file

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

View file

@ -69,7 +69,7 @@ arraybuffer-transfer
arrow-function
async-functions
async-iteration
Atomics
Atomics=skip # disabled because of Windows <-> pthreads
Atomics.waitAsync=skip
BigInt
caller

View file

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

View file

@ -434,17 +434,17 @@ function test_number()
assert(Number.isNaN(Number("-")));
assert(Number.isNaN(Number("\x00a")));
assert((1-2**-53).toString(12), "0.bbbbbbbbbbbbbba");
assert((1000000000000000128).toString(), "1000000000000000100");
assert((1000000000000000128).toFixed(0), "1000000000000000128");
// TODO: Fix rounding errors on Windows/Cygwin.
if (['win32', 'cygwin'].includes(os.platform)) {
return;
}
assert((25).toExponential(0), "3e+1");
assert((-25).toExponential(0), "-3e+1");
assert((2.5).toPrecision(1), "3");
assert((-2.5).toPrecision(1), "-3");
assert((1.125).toFixed(2), "1.13");
assert((-1.125).toFixed(2), "-1.13");
assert((0.5).toFixed(0), "1");
assert((-0.5).toFixed(0), "-1");
}
function test_eval2()
@ -516,7 +516,7 @@ function test_eval()
function test_typed_array()
{
var buffer, a, i, str, b;
var buffer, a, i, str;
a = new Uint8Array(4);
assert(a.length, 4);
@ -569,17 +569,6 @@ function test_typed_array()
assert(a.toString(), "1,2,3,4");
a.set([10, 11], 2);
assert(a.toString(), "1,2,10,11");
a = new Uint8Array(buffer, 0, 4);
a.constructor = {
[Symbol.species]: function (len) {
return new Uint8Array(buffer, 1, len);
},
};
b = a.slice();
assert(a.buffer, b.buffer);
assert(a.toString(), "0,0,0,255");
assert(b.toString(), "0,0,255,255");
}
function test_json()
@ -708,14 +697,6 @@ function test_date()
assert(Date.UTC(2017, 9, 22, 18 - 1e10, 10 + 60e10), 1508695800000);
assert(Date.UTC(2017, 9, 22, 18, 10 - 1e10, 11 + 60e10), 1508695811000);
assert(Date.UTC(2017, 9, 22, 18, 10, 11 - 1e12, 91 + 1000e12), 1508695811091);
assert(new Date("2024 Apr 7 1:00 AM").toLocaleString(), "04/07/2024, 01:00:00 AM");
assert(new Date("2024 Apr 7 2:00 AM").toLocaleString(), "04/07/2024, 02:00:00 AM");
assert(new Date("2024 Apr 7 11:00 AM").toLocaleString(), "04/07/2024, 11:00:00 AM");
assert(new Date("2024 Apr 7 12:00 AM").toLocaleString(), "04/07/2024, 12:00:00 AM");
assert(new Date("2024 Apr 7 1:00 PM").toLocaleString(), "04/07/2024, 01:00:00 PM");
assert(new Date("2024 Apr 7 2:00 PM").toLocaleString(), "04/07/2024, 02:00:00 PM");
assert(new Date("2024 Apr 7 11:00 PM").toLocaleString(), "04/07/2024, 11:00:00 PM");
assert(new Date("2024 Apr 7 12:00 PM").toLocaleString(), "04/07/2024, 12:00:00 PM");
}
function test_regexp()
@ -985,54 +966,6 @@ function test_proxy_is_array()
}
}
function test_cur_pc()
{
var a = [];
Object.defineProperty(a, '1', {
get: function() { throw Error("a[1]_get"); },
set: function(x) { throw Error("a[1]_set"); }
});
assert_throws(Error, function() { return a[1]; });
assert_throws(Error, function() { a[1] = 1; });
assert_throws(Error, function() { return [...a]; });
assert_throws(Error, function() { return ({...b} = a); });
var o = {};
Object.defineProperty(o, 'x', {
get: function() { throw Error("o.x_get"); },
set: function(x) { throw Error("o.x_set"); }
});
o.valueOf = function() { throw Error("o.valueOf"); };
assert_throws(Error, function() { return +o; });
assert_throws(Error, function() { return -o; });
assert_throws(Error, function() { return o+1; });
assert_throws(Error, function() { return o-1; });
assert_throws(Error, function() { return o*1; });
assert_throws(Error, function() { return o/1; });
assert_throws(Error, function() { return o%1; });
assert_throws(Error, function() { return o**1; });
assert_throws(Error, function() { return o<<1; });
assert_throws(Error, function() { return o>>1; });
assert_throws(Error, function() { return o>>>1; });
assert_throws(Error, function() { return o&1; });
assert_throws(Error, function() { return o|1; });
assert_throws(Error, function() { return o^1; });
assert_throws(Error, function() { return o<1; });
assert_throws(Error, function() { return o==1; });
assert_throws(Error, function() { return o++; });
assert_throws(Error, function() { return o--; });
assert_throws(Error, function() { return ++o; });
assert_throws(Error, function() { return --o; });
assert_throws(Error, function() { return ~o; });
Object.defineProperty(globalThis, 'xxx', {
get: function() { throw Error("xxx_get"); },
set: function(x) { throw Error("xxx_set"); }
});
assert_throws(Error, function() { return xxx; });
assert_throws(Error, function() { xxx = 1; });
}
test();
test_function();
test_enum();
@ -1056,4 +989,3 @@ test_exception_source_pos();
test_function_source_pos();
test_exception_prepare_stack();
test_exception_stack_size_limit();
test_cur_pc();

File diff suppressed because it is too large Load diff

View file

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

View file

@ -254,16 +254,7 @@ function test_os_exec()
}
}
function test_interval()
{
var t = os.setInterval(f, 1);
function f() {
if (++f.count === 3) os.clearInterval(t);
}
f.count = 0;
}
function test_timeout()
function test_timer()
{
var th, i;
@ -275,18 +266,6 @@ function test_timeout()
os.clearTimeout(th[i]);
}
function test_timeout_order()
{
var s = "";
os.setTimeout(a, 1);
os.setTimeout(b, 2);
os.setTimeout(d, 5);
function a() { s += "a"; os.setTimeout(c, 0); }
function b() { s += "b"; }
function c() { s += "c"; }
function d() { assert(s === "abc"); } // not "acb"
}
test_printf();
test_file1();
test_file2();
@ -294,6 +273,4 @@ test_getline();
test_popen();
test_os();
!isWin && test_os_exec();
test_interval();
test_timeout();
test_timeout_order();
test_timer();

View file

@ -6,20 +6,6 @@
globalThis.failWithMessage = function(message) {
if (count > 99) return
if (++count > 99) return print("<output elided>")
print(String(message).slice(0, 300))
}
globalThis.formatFailureText = function(expectedText, found, name_opt) {
var message = "Fail" + "ure"
if (name_opt) {
// Fix this when we ditch the old test runner.
message += " (" + name_opt + ")"
}
var foundText = prettyPrinted(found)
if (expectedText.length <= 60 && foundText.length <= 60) {
message += ": expected <" + expectedText + "> found <" + foundText + ">"
} else {
message += ":\nexpected:\n" + expectedText + "\nfound:\n" + foundText
}
return message
print(String(message).slice(0, 128))
}
})()

30
v8.js
View file

@ -15,33 +15,18 @@ const exclude = [
"disallow-codegen-from-strings.js", // --disallow-code-generation-from-strings
"cyclic-array-to-string.js", // unstable output due to stack overflow
"error-tostring.js", // unstable output due to stack overflow
"invalid-lhs.js", // v8 expects ReferenceError but ECMA says SyntaxError
"regexp.js", // invalid, legitimate early SyntaxError
"regexp-capture-3.js", // slow
"regexp-cache-replace.js", // deprecated RegExp.$1 etc.
"regexp-indexof.js", // deprecated RegExp.lastMatch etc.
"regexp-static.js", // deprecated RegExp static properties.
"regexp-modifiers-autogenerated-i18n.js", // invalid group
"regexp-modifiers-autogenerated.js", // invalid group
"regexp-modifiers-dotall.js", // invalid group
"regexp-modifiers-i18n.js", // invalid group
"regexp-modifiers.js", // invalid group
"regexp-override-symbol-match-all.js", // missing g flag
"serialize-embedded-error.js", // parseInt() = 0;
"string-replace.js", // unstable output
"string-match.js", // deprecated RegExp.$1 etc.
"string-slices-regexp.js", // deprecated RegExp.$1 etc.
"omit-default-ctors-array-iterator.js",
"mjsunit.js",
"mjsunit-assertion-error.js",
"mjsunit-assert-equals.js",
"mjsunit.js",
"mjsunit_suppressions.js",
"verify-assert-false.js", // self check
"verify-check-false.js", // self check
"clone-ic-regression-crbug-1466315.js", // spurious output
]
let files = scriptArgs.slice(1) // run only these tests
@ -52,7 +37,7 @@ for (const file of files) {
if (exclude.includes(file)) continue
const source = std.loadFile(dir + "/" + file)
if (/^(im|ex)port/m.test(source)) continue // TODO support modules
if (source.includes('Realm.create')) continue // TODO support Realm object
if (source.includes('Realm.create()')) continue // TODO support Realm object
if (source.includes('// MODULE')) continue // TODO support modules
if (source.includes('// Files:')) continue // TODO support includes
@ -74,15 +59,6 @@ for (const file of files) {
}
// exclude tests that use V8 intrinsics like %OptimizeFunctionOnNextCall
if (flags["--allow-natives-syntax"]) continue
if (flags["--allow-natives-for-differential-fuzzing"]) continue
if (flags["--dump-counters"]) continue
if (flags["--expose-cputracemark"]) continue
if (flags["--harmony-rab-gsab"]) continue
if (flags["--harmony-class-fields"]) continue
if (flags["--enable-experimental-regexp-engine"]) continue
if (flags["--experimental-stack-trace-frames"]) continue
if (flags["--js-float16array"]) continue
if (flags["--expose-cputracemark-as"]) continue
// exclude tests that use V8 extensions
if (flags["--expose-externalize-string"]) continue
// parse environment variables
@ -96,7 +72,7 @@ for (const file of files) {
//print(`=== ${file}${envstr}${flagstr}`)
print(`=== ${file}${envstr}`)
const args = [argv0,
"--stack-size", `${flags["--stack-size"]}`,
"--stack-size", `${flags["--stack-size"]*1024}`,
"-I", "mjsunit.js",
"-I", tweak,
file]

10
v8.sh
View file

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

501
v8.txt
View file

@ -66,10 +66,7 @@ async function two(x) {
try {
x = await x;
throw new Error();
} catch (e) {
return e.stack;
}
}
}
=== async-stack-traces-prepare-stacktrace-3.js
=== async-stack-traces-prepare-stacktrace-4.js
=== big-array-literal.js
@ -137,6 +134,7 @@ Failure (54[]): expected <true> found <false>
Failure (55[]): expected <true> found <false>
Failure (56[]): expected <true> found <false>
=== date-parse.js
Failure (May 25 2008 1:30( )AM (PM) is not NaN.): expected <true> found <false>
=== declare-locally.js
=== deep-recursion.js
=== define-property-gc.js
@ -326,7 +324,11 @@ Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
=== function-length-accessor.js
=== function-name-eval-shadowed.js
Failure: expected <200> found <function f() { eval("var f = 100"); f = 200; return f }>
Failure:
expected:
200
found:
function f() { eval("var f = 100"); f = 200; return f }
=== function-names.js
=== function-property.js
=== function-prototype.js
@ -334,10 +336,14 @@ Failure: expected <200> found <function f() { eval("var f = 100"); f = 200; retu
=== function-without-prototype.js
=== function.js
Failure: expected <"undefined"> found <"function">
Failure: expected <42> found <function anonymous(
Failure:
expected:
42
found:
function anonymous(
) {
return anonymous;
}>
}
=== fuzz-accessors.js
=== get-own-property-descriptor-non-objects.js
=== get-own-property-descriptor.js
@ -362,6 +368,9 @@ return anonymous;
=== hex-parsing.js
=== holy-double-no-arg-array.js
=== html-comments.js
SyntaxError: unexpected token in expression: '>'
at html-comments.js:1:1
=== html-string-funcs.js
=== icu-date-lord-howe.js TZ=Australia/Lord_Howe LC_ALL=en
Failure:
@ -395,18 +404,51 @@ found:
=== integer-to-string.js
=== intl-numberformat-formattoparts.js
=== intl-pluralrules-select.js
=== invalid-lhs.js
Object <Error(SyntaxError: invalid assignment left-hand side)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid assignment left-hand side)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid assignment left-hand side)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid assignment left-hand side)> is not an instance of <ReferenceError> but of <SyntaxError>
threw an exception: invalid assignment left-hand side
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
threw an exception: invalid increment/decrement operand
threw an exception: invalid increment/decrement operand
Object <Error(SyntaxError: invalid for in/of left hand-side)> is not an instance of <ReferenceError> but of <SyntaxError>
threw an exception: invalid for in/of left hand-side
Object <Error(SyntaxError: invalid assignment left-hand side)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid assignment left-hand side)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid assignment left-hand side)> is not an instance of <ReferenceError> but of <SyntaxError>
threw an exception: invalid assignment left-hand side
Object <Error(SyntaxError: invalid assignment left-hand side)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid assignment left-hand side)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid assignment left-hand side)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid assignment left-hand side)> is not an instance of <ReferenceError> but of <SyntaxError>
Object <Error(SyntaxError: invalid increment/decrement operand)> is not an instance of <ReferenceError> but of <SyntaxError>
=== invalid-source-element.js
=== json-errors.js
Failure:
expected:
"Unexpected token \n in JSON at position 3"
found:
"Bad control character in string literal in JSON at position 3 (line 1 column 4)"
"Bad control character in string literal in JSON"
Failure:
expected:
"Unexpected token \n in JSON at position 3"
found:
"Bad control character in string literal in JSON at position 3 (line 1 column 4)"
"Bad control character in string literal in JSON"
=== json-parser-recursive.js
=== json-replacer-number-wrapper-tostring.js
=== json-replacer-order.js
@ -475,6 +517,8 @@ Failure: expected <true> found <false>
=== numops-fuzz-part4.js
=== obj-construct.js
=== object-create.js
Failure: expected <true> found <false>
Failure: expected <true> found <false>
=== object-define-properties.js
Failure: expected <undefined> found <1>
=== object-freeze-global.js
@ -508,6 +552,10 @@ Failure (printErr should be defined): expected <"function"> found <"undefined">
=== readonly-accessor.js
=== receiver-in-with-calls.js
=== regexp-UC16.js
=== regexp-cache-replace.js
Failure: expected <"o"> found <undefined>
Failure: expected <"x"> found <undefined>
Failure: expected <"o"> found <undefined>
=== regexp-call-as-function.js
=== regexp-capture.js
Failure: expected <["",undefined,""]> found <["","undefined",""]>
@ -525,10 +573,35 @@ SyntaxError: too many captures
=== regexp-loop-capture.js
Failure: expected <["abc",undefined,undefined,"c"]> found <["abc","a","b","c"]>
Failure: expected <["ab",undefined]> found <["ab","a"]>
=== regexp-modifiers-autogenerated-i18n.js
SyntaxError: invalid group
at regexp-modifiers-autogenerated-i18n.js:12:1
=== regexp-modifiers-autogenerated.js
SyntaxError: invalid group
at regexp-modifiers-autogenerated.js:10:1
=== regexp-modifiers-dotall.js
SyntaxError: invalid group
at regexp-modifiers-dotall.js:9:1
=== regexp-modifiers-i18n.js
SyntaxError: invalid group
at regexp-modifiers-i18n.js:9:1
=== regexp-modifiers.js
SyntaxError: invalid group
at regexp-modifiers.js:7:1
=== regexp-multiline.js
Failure: expected <true> found <false>
Failure: expected <true> found <false>
=== regexp-override-exec.js
=== regexp-override-symbol-match-all.js
TypeError: regexp must have the 'g' flag
at matchAll (native)
at <eval> (regexp-override-symbol-match-all.js:9:23)
=== regexp-override-symbol-match.js
=== regexp-override-symbol-replace.js
=== regexp-override-symbol-search.js
@ -546,6 +619,10 @@ Failure: expected <true> found <false>
=== scope-calls-eval.js
=== search-string-multiple.js
=== serialize-after-execute.js
=== serialize-embedded-error.js
SyntaxError: invalid assignment left-hand side
at serialize-embedded-error.js:9:1
=== serialize-ic.js
=== shifts.js
=== short-circuit-boolean.js
@ -562,17 +639,43 @@ Failure: expected <true> found <false>
=== spread-large-set.js
=== spread-large-string.js
=== stack-traces-2.js
=== stack-traces-class-fields.js
Failure (during class construction doesn't contain expected[1] stack = at thrower (stack-traces-class-fields.js:35:3)
at
Failure (during class construction contains unexpected[0]): expected <59> found <-1>
Failure (during class instantiation doesn't contain expected[1] stack = at thrower (stack-traces-class-fields.js:35:3)
a
Failure (during class instantiation doesn't contain expected[2] stack = at thrower (stack-traces-class-fields.js:35:3)
a
Failure (during class instantiation contains unexpected[0]): expected <59> found <-1>
Failure (during class instantiation with super doesn't contain expected[1] stack = at thrower (stack-traces-class-fields.js:
Failure (during class instantiation with super doesn't contain expected[2] stack = at thrower (stack-traces-class-fields.js:
Failure (during class instantiation with super contains unexpected[1]): expected <59> found <-1>
Failure (during class instantiation with super2 doesn't contain expected[1] stack = at thrower (stack-traces-class-fields.js
Failure (during class instantiation with super2 doesn't contain expected[2] stack = at thrower (stack-traces-class-fields.js
Failure (during class instantiation with super2 contains unexpected[1]): expected <59> found <-1>
Failure (during class instantiation with super3 doesn't contain expected[1] stack = at thrower (stack-traces-class-fields.js
Failure (during class instantiation with super3 doesn't contain expected[2] stack = at thrower (stack-traces-class-fields.js
Failure (during class instantiation with super3 doesn't contain expected[3] stack = at thrower (stack-traces-class-fields.js
Failure (during class instantiation with super3 contains unexpected[0]): expected <59> found <-1>
Failure (during class field call doesn't contain expected[0] stack = at thrower (stack-traces-class-fields.js:35:3)
at t
Failure (during static class field call doesn't contain expected[0] stack = at thrower (stack-traces-class-fields.js:35:3)
Failure (during class field call with FNI doesn't contain expected[0] stack = at x (stack-traces-class-fields.js:208:7)
Failure (during static class field call with FNI doesn't contain expected[0] stack = at x (stack-traces-class-fields.js:230:
=== stack-traces-custom-lazy.js
Failure:
expected:
"bar"
found:
" at <anonymous> (stack-traces-custom-lazy.js:47:46)\n at testPrepareStackTrace (stack-traces-custom-lazy.js:31:5)\n at <eval> (stack-traces-custom-lazy.js:47:60)\n"
" at <anonymous> (stack-traces-custom-lazy.js:47:46)\n at testPrepareStackTrace (stack-tra
Failure:
expected:
"bar"
found:
" at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js
" at f (stack-traces-custom-lazy.js:48:38)\n at f (stack-traces-custom-lazy.js:48:38)\n
=== stack-traces-custom.js
TypeError: not a function
at <eval> (stack-traces-custom.js:20:21)
@ -584,118 +687,58 @@ Failure: expected <undefined> found <"">
=== stack-traces.js
Failure (testArrayNative doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:48:31)
at map (native)
at testArrayNative (stack-traces.js:48:37)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:267:47)
): expected <true> found <false>
Failure (testMethodNameInference doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:30:37)
at testMethodNameInference (stack-traces.js:31:8)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:269:63)
): expected <true> found <false>
at testMetho
Failure (testImplicitConversion doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:53:42)
at testImplicitConversion (stack-traces.js:54:19)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:270:61)
): expected <true> found <false>
at testImplic
Failure (testEval doesn't contain expected[0] stack = at Doo (<input>:1:17)
at <eval> (<input>:1:26)
at testEval (stack-traces.js:58:3)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:271:33)
): expected <true> found <false>
at testEval (st
Failure (testNestedEval doesn't contain expected[0] stack = at <eval> (<input>:1:1)
at Inner (<input>:1:19)
at Outer (<input>:1:58)
at <eval> (<input>:1:70)
at testNestedEval (stack-traces.js:63:3)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:272:45)
):
at Outer
Failure (testEvalWithSourceURL doesn't contain expected[0] stack = at Doo (<input>:1:17)
at <eval> (<input>:1:26)
at testEvalWithSourceURL (stack-traces.js:67:3)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:274:34)
): expected <true> found <false>
at
Failure (testNestedEvalWithSourceURL doesn't contain expected[0] stack = at <eval> (<input>:1:1)
at Inner (<input>:1:19)
at Outer (<input>:1:36)
at <eval> (<input>:1:48)
at testNestedEvalWithSourceURL (stack-traces.js:73:3)
at testTrace (stack-traces.js:162:5)
at <eval> (
Failure (testNestedEvalWithSourceURL doesn't contain expected[1] stack = at <eval> (<input>:1:1)
at Inner (<input>:1:19)
at Outer (<input>:1:36)
at <eval> (<input>:1:48)
at testNestedEvalWithSourceURL (stack-traces.js:73:3)
at testTrace (stack-traces.js:162:5)
at <eval> (
Failure (testValue doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:77:47)
at testValue (stack-traces.js:78:3)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:278:35)
): expected <true> found <false>
at testValue (stack-traces
Failure (testConstructor doesn't contain expected[0] stack = at Plonk (stack-traces.js:82:22)
at testConstructor (stack-traces.js:83:7)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:279:47)
): expected <true> found <false>
at testConstructor (stack-
Failure (testRenamedMethod doesn't contain expected[0] stack = at a$b$c$d (stack-traces.js:87:31)
at testRenamedMethod (stack-traces.js:90:8)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:280:51)
): expected <true> found <false>
at testRenamedMethod (
Failure (testAnonymousMethod doesn't contain expected[0] stack = at <anonymous> (stack-traces.js:94:18)
at call (native)
at testAnonymousMethod (stack-traces.js:94:38)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:281:55)
): expected <true> found <false>
Failure (testFunctionName doesn't contain expected[2] stack = at foo_0 (stack-traces.js:101:9)
at foo_1 (stack-traces.js:103:27)
at <anonymous> (stack-traces.js:103:27)
at boo_3 (stack-traces.js:103:27)
at <anonymous> (stack-traces.js:103:27)
at testFunctionName (stack-traces
at foo_1 (stack-traces.js
Failure (testFunctionName doesn't contain expected[4] stack = at foo_0 (stack-traces.js:101:9)
at foo_1 (stack-traces.js:103:27)
at <anonymous> (stack-traces.js:103:27)
at boo_3 (stack-traces.js:103:27)
at <anonymous> (stack-traces.js:103:27)
at testFunctionName (stack-traces
at foo_1 (stack-traces.js
Failure (testDefaultCustomError doesn't contain expected[0] stack = at CustomError (stack-traces.js:130:33)
at testDefaultCustomError (stack-traces.js:138:36)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:287:5)
): expected <true> found <false>
at testDefau
Failure (testDefaultCustomError doesn't contain expected[1] stack = at CustomError (stack-traces.js:130:33)
at testDefaultCustomError (stack-traces.js:138:36)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:287:5)
): expected <true> found <false>
at testDefau
Failure (testStrippedCustomError doesn't contain expected[0] stack = at CustomError (stack-traces.js:130:33)
at testStrippedCustomError (stack-traces.js:142:36)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:289:25)
): expected <true> found <false>
at testStri
Failure (testClassNames doesn't contain expected[0] stack = at MyObj (stack-traces.js:145:22)
at <anonymous> (stack-traces.js:150:14)
at testClassNames (stack-traces.js:154:8)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:291:49)
): expected <true> found <false>
at <anonymous> (stack-trac
Failure (testClassNames doesn't contain expected[1] stack = at MyObj (stack-traces.js:145:22)
at <anonymous> (stack-traces.js:150:14)
at testClassNames (stack-traces.js:154:8)
at testTrace (stack-traces.js:162:5)
at <eval> (stack-traces.js:291:49)
): expected <true> found <false>
at <anonymous> (stack-trac
Failure (UnintendedCallerCensorship didn't contain new ReferenceError): expected <true> found <false>
Failure: expected <"abc"> found <undefined>
Failure: expected <"abc"> found <" at <eval> (stack-traces.js:371:13)\n">
Failure: expected <undefined> found <" at <eval> (stack-traces.js:375:13)\n">
Failure:
expected:
"abc"
found:
" at <eval> (stack-traces.js:371:13)\n"
Failure:
expected:
undefined
found:
" at <eval> (stack-traces.js:375:13)\n"
TypeError: not a function
at <eval> (stack-traces.js:381:1)
@ -711,10 +754,68 @@ Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Did not throw exception
Failure: expected <null> found <undefined>
Failure: expected <undefined> found <function non_strict() {
Failure:
expected:
undefined
found:
function non_strict() {
return return_my_caller();
}>
}
Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
Failure: expected <null> found <undefined>
@ -745,12 +846,214 @@ TypeError: cannot read property 'value' of undefined
=== string-indexof-2.js
=== string-lastindexof.js
=== string-localecompare.js
=== string-match.js
Failure (Nonglobal-$&): expected <"A"> found <undefined>
Failure (Nonglobal-lastMatch): expected <"A"> found <undefined>
Failure (Nonglobal-nocapture-1): expected <""> found <undefined>
Failure (Nonglobal-nocapture-2): expected <""> found <undefined>
Failure (Nonglobal-nocapture-3): expected <""> found <undefined>
Failure (Nonglobal-nocapture-4): expected <""> found <undefined>
Failure (Nonglobal-nocapture-5): expected <""> found <undefined>
Failure (Nonglobal-nocapture-6): expected <""> found <undefined>
Failure (Nonglobal-nocapture-7): expected <""> found <undefined>
Failure (Nonglobal-nocapture-8): expected <""> found <undefined>
Failure (Nonglobal-nocapture-9): expected <""> found <undefined>
Failure (Nonglobal-input): expected <"A man, a plan, a canal: Panama"> found <undefined>
Failure (Nonglobal-$_): expected <"A man, a plan, a canal: Panama"> found <undefined>
Failure (Nonglobal-$`): expected <""> found <undefined>
Failure (Nonglobal-leftContex): expected <""> found <undefined>
Failure (Nonglobal-$'): expected <" man, a plan, a canal: Panama"> found <undefined>
Failure (Nonglobal-rightContex): expected <" man, a plan, a canal: Panama"> found <undefined>
Failure (Nonglobal-$+): expected <""> found <undefined>
Failure (Nonglobal-lastParen): expected <""> found <undefined>
Failure (Nonglobal-ignore-lastIndex-$&): expected <"A"> found <undefined>
Failure (Nonglobal-ignore-lastIndex-lastMatch): expected <"A"> found <undefined>
Failure (Nonglobal-ignore-lastIndex-nocapture-1): expected <""> found <undefined>
Failure (Nonglobal-ignore-lastIndex-nocapture-2): expected <""> found <undefined>
Failure (Nonglobal-ignore-lastIndex-nocapture-3): expected <""> found <undefined>
Failure (Nonglobal-ignore-lastIndex-nocapture-4): expected <""> found <undefined>
Failure (Nonglobal-ignore-lastIndex-nocapture-5): expected <""> found <undefined>
Failure (Nonglobal-ignore-lastIndex-nocapture-6): expected <""> found <undefined>
Failure (Nonglobal-ignore-lastIndex-nocapture-7): expected <""> found <undefined>
Failure (Nonglobal-ignore-lastIndex-nocapture-8): expected <""> found <undefined>
Failure (Nonglobal-ignore-lastIndex-nocapture-9): expected <""> found <undefined>
Failure (Nonglobal-ignore-lastIndex-input): expected <"A man, a plan, a canal: Panama"> found <undefined>
Failure (Nonglobal-ignore-lastIndex-$_): expected <"A man, a plan, a canal: Panama"> found <undefined>
Failure (Nonglobal-ignore-lastIndex-$`): expected <""> found <undefined>
Failure (Nonglobal-ignore-lastIndex-leftContex): expected <""> found <undefined>
Failure (Nonglobal-ignore-lastIndex-$'): expected <" man, a plan, a canal: Panama"> found <undefined>
Failure (Nonglobal-ignore-lastIndex-rightContex): expected <" man, a plan, a canal: Panama"> found <undefined>
Failure (Nonglobal-ignore-lastIndex-$+): expected <""> found <undefined>
Failure (Nonglobal-ignore-lastIndex-lastParen): expected <""> found <undefined>
Failure (Capture-Nonglobal-$&): expected <"abcdefghij"> found <undefined>
Failure (Capture-Nonglobal-lastMatch): expected <"abcdefghij"> found <undefined>
Failure (Capture-Nonglobal-capture-1): expected <"a"> found <undefined>
Failure (Capture-Nonglobal-capture-2): expected <"b"> found <undefined>
Failure (Capture-Nonglobal-capture-3): expected <"c"> found <undefined>
Failure (Capture-Nonglobal-capture-4): expected <"d"> found <undefined>
Failure (Capture-Nonglobal-capture-5): expected <"e"> found <undefined>
Failure (Capture-Nonglobal-capture-6): expected <"f"> found <undefined>
Failure (Capture-Nonglobal-capture-7): expected <"g"> found <undefined>
Failure (Capture-Nonglobal-capture-8): expected <"h"> found <undefined>
Failure (Capture-Nonglobal-capture-9): expected <"i"> found <undefined>
Failure (Capture-Nonglobal-input): expected <"abcdefghijxxxxxxxxxx"> found <undefined>
Failure (Capture-Nonglobal-$_): expected <"abcdefghijxxxxxxxxxx"> found <undefined>
Failure (Capture-Nonglobal-$`): expected <""> found <undefined>
Failure (Capture-Nonglobal-leftContex): expected <""> found <undefined>
Failure (Capture-Nonglobal-$'): expected <"xxxxxxxxxx"> found <undefined>
Failure (Capture-Nonglobal-rightContex): expected <"xxxxxxxxxx"> found <undefined>
Failure (Capture-Nonglobal-$+): expected <"j"> found <undefined>
Failure (Capture-Nonglobal-lastParen): expected <"j"> found <undefined>
Failure (Global-$&): expected <"glyf"> found <undefined>
Failure (Global-lastMatch): expected <"glyf"> found <undefined>
Failure (Global-nocapture-1): expected <""> found <undefined>
Failure (Global-nocapture-2): expected <""> found <undefined>
Failure (Global-nocapture-3): expected <""> found <undefined>
Failure (Global-nocapture-4): expected <""> found <undefined>
Failure (Global-nocapture-5): expected <""> found <undefined>
Failure (Global-nocapture-6): expected <""> found <undefined>
Failure (Global-nocapture-7): expected <""> found <undefined>
Failure (Global-nocapture-8): expected <""> found <undefined>
Failure (Global-nocapture-9): expected <""> found <undefined>
Failure (Global-input): expected <"Argle bargle glop glyf!"> found <undefined>
Failure (Global-$_): expected <"Argle bargle glop glyf!"> found <undefined>
Failure (Global-$`): expected <"Argle bargle glop "> found <undefined>
Failure (Global-leftContex): expected <"Argle bargle glop "> found <undefined>
Failure (Global-$'): expected <"!"> found <undefined>
Failure (Global-rightContex): expected <"!"> found <undefined>
Failure (Global-$+): expected <""> found <undefined>
Failure (Global-lastParen): expected <""> found <undefined>
Failure (Global-ignore-lastIndex-$&): expected <"glyf"> found <undefined>
Failure (Global-ignore-lastIndex-lastMatch): expected <"glyf"> found <undefined>
Failure (Global-ignore-lastIndex-nocapture-1): expected <""> found <undefined>
Failure (Global-ignore-lastIndex-nocapture-2): expected <""> found <undefined>
Failure (Global-ignore-lastIndex-nocapture-3): expected <""> found <undefined>
Failure (Global-ignore-lastIndex-nocapture-4): expected <""> found <undefined>
Failure (Global-ignore-lastIndex-nocapture-5): expected <""> found <undefined>
Failure (Global-ignore-lastIndex-nocapture-6): expected <""> found <undefined>
Failure (Global-ignore-lastIndex-nocapture-7): expected <""> found <undefined>
Failure (Global-ignore-lastIndex-nocapture-8): expected <""> found <undefined>
Failure (Global-ignore-lastIndex-nocapture-9): expected <""> found <undefined>
Failure (Global-ignore-lastIndex-input): expected <"Argle bargle glop glyf!"> found <undefined>
Failure (Global-ignore-lastIndex-$_): expected <"Argle bargle glop glyf!"> found <undefined>
Failure (Global-ignore-lastIndex-$`): expected <"Argle bargle glop "> found <undefined>
Failure (Global-ignore-lastIndex-leftContex): expected <"Argle bargle glop "> found <undefined>
Failure (Global-ignore-lastIndex-$'): expected <"!"> found <undefined>
Failure (Global-ignore-lastIndex-rightContex): expected <"!"> found <undefined>
Failure (Global-ignore-lastIndex-$+): expected <""> found <undefined>
Failure (Global-ignore-lastIndex-lastParen): expected <""> found <undefined>
Failure (Capture-Global-$&): expected <"Panama"> found <undefined>
Failure (Capture-Global-lastMatch): expected <"Panama"> found <undefined>
Failure (Capture-Global-capture-1): expected <"anama"> found <undefined>
Failure (Capture-Global-nocapture-2): expected <""> found <undefined>
<output elided>
=== string-normalize.js
=== string-oom-concat.js
=== string-pad.js
=== string-replace-gc.js
=== string-replace-one-char.js
=== string-search.js
=== string-slices-regexp.js
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
Failure (RegExp.$1): expected <"regexp"> found <undefined>
<output elided>
=== string-split-cache.js
=== string-trim.js
=== string-wrapper.js