Compare commits
1 commit
master
...
revert-265
Author | SHA1 | Date | |
---|---|---|---|
|
e02472dabc |
130 changed files with 23519 additions and 39809 deletions
BIN
.DS_Store
vendored
BIN
.DS_Store
vendored
Binary file not shown.
10
.gitignore
vendored
10
.gitignore
vendored
|
@ -1,15 +1,17 @@
|
||||||
*.a
|
*.a
|
||||||
.obj/
|
.obj/
|
||||||
tests/bjson.so
|
tests/bjson.so
|
||||||
|
examples/test_fib
|
||||||
|
test_fib.c
|
||||||
examples/*.so
|
examples/*.so
|
||||||
|
examples/hello
|
||||||
|
examples/hello_module
|
||||||
|
hello.c
|
||||||
microbench*.txt
|
microbench*.txt
|
||||||
qjs
|
qjs
|
||||||
qjsc
|
qjsc
|
||||||
qjscalc
|
qjscalc
|
||||||
qjscalc.c
|
qjscalc.c
|
||||||
hello.c
|
|
||||||
hello
|
|
||||||
hello_module
|
|
||||||
repl.c
|
repl.c
|
||||||
run-test262
|
run-test262
|
||||||
test262
|
test262
|
||||||
|
@ -20,5 +22,3 @@ unicode
|
||||||
unicode_gen
|
unicode_gen
|
||||||
run_octane
|
run_octane
|
||||||
run_sunspider_like
|
run_sunspider_like
|
||||||
build/
|
|
||||||
.vscode/
|
|
399
CMakeLists.txt
399
CMakeLists.txt
|
@ -1,399 +0,0 @@
|
||||||
cmake_minimum_required(VERSION 3.10)
|
|
||||||
|
|
||||||
project(quickjs LANGUAGES C)
|
|
||||||
|
|
||||||
include(CheckCCompilerFlag)
|
|
||||||
include(GNUInstallDirs)
|
|
||||||
|
|
||||||
set(CMAKE_C_VISIBILITY_PRESET hidden)
|
|
||||||
set(CMAKE_C_STANDARD_REQUIRED ON)
|
|
||||||
set(CMAKE_C_EXTENSIONS ON)
|
|
||||||
set(CMAKE_C_STANDARD 11)
|
|
||||||
|
|
||||||
if(NOT CMAKE_BUILD_TYPE)
|
|
||||||
message(STATUS "No build type selected, default to Release")
|
|
||||||
set(CMAKE_BUILD_TYPE "Release")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
message(STATUS "Building in ${CMAKE_BUILD_TYPE} mode")
|
|
||||||
message(STATUS "Building with ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION} on ${CMAKE_SYSTEM}")
|
|
||||||
|
|
||||||
macro(xcheck_add_c_compiler_flag FLAG)
|
|
||||||
string(REPLACE "-" "" FLAG_NO_HYPHEN ${FLAG})
|
|
||||||
check_c_compiler_flag(${FLAG} COMPILER_SUPPORTS_${FLAG_NO_HYPHEN})
|
|
||||||
if(COMPILER_SUPPORTS_${FLAG_NO_HYPHEN})
|
|
||||||
add_compile_options(${FLAG})
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
xcheck_add_c_compiler_flag(-Wall)
|
|
||||||
if(NOT MSVC AND NOT IOS)
|
|
||||||
xcheck_add_c_compiler_flag(-Werror)
|
|
||||||
xcheck_add_c_compiler_flag(-Wextra)
|
|
||||||
endif()
|
|
||||||
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-but-set-variable)
|
|
||||||
xcheck_add_c_compiler_flag(-Wno-array-bounds)
|
|
||||||
xcheck_add_c_compiler_flag(-Wno-format-truncation)
|
|
||||||
xcheck_add_c_compiler_flag(-funsigned-char)
|
|
||||||
|
|
||||||
# ClangCL is command line compatible with MSVC, so 'MSVC' is set.
|
|
||||||
if(MSVC)
|
|
||||||
xcheck_add_c_compiler_flag(-Wno-unsafe-buffer-usage)
|
|
||||||
xcheck_add_c_compiler_flag(-Wno-sign-conversion)
|
|
||||||
xcheck_add_c_compiler_flag(-Wno-nonportable-system-include-path)
|
|
||||||
xcheck_add_c_compiler_flag(-Wno-implicit-int-conversion)
|
|
||||||
xcheck_add_c_compiler_flag(-Wno-shorten-64-to-32)
|
|
||||||
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)
|
|
||||||
xcheck_add_c_compiler_flag(/wd4018) # -Wno-sign-conversion
|
|
||||||
xcheck_add_c_compiler_flag(/wd4061) # -Wno-implicit-fallthrough
|
|
||||||
xcheck_add_c_compiler_flag(/wd4100) # -Wno-unused-parameter
|
|
||||||
xcheck_add_c_compiler_flag(/wd4200) # -Wno-zero-length-array
|
|
||||||
xcheck_add_c_compiler_flag(/wd4242) # -Wno-shorten-64-to-32
|
|
||||||
xcheck_add_c_compiler_flag(/wd4244) # -Wno-shorten-64-to-32
|
|
||||||
xcheck_add_c_compiler_flag(/wd4245) # -Wno-sign-compare
|
|
||||||
xcheck_add_c_compiler_flag(/wd4267) # -Wno-shorten-64-to-32
|
|
||||||
xcheck_add_c_compiler_flag(/wd4388) # -Wno-sign-compare
|
|
||||||
xcheck_add_c_compiler_flag(/wd4389) # -Wno-sign-compare
|
|
||||||
xcheck_add_c_compiler_flag(/wd4710) # Function not inlined
|
|
||||||
xcheck_add_c_compiler_flag(/wd4711) # Function was inlined
|
|
||||||
xcheck_add_c_compiler_flag(/wd4820) # Padding added after construct
|
|
||||||
xcheck_add_c_compiler_flag(/wd4996) # -Wdeprecated-declarations
|
|
||||||
xcheck_add_c_compiler_flag(/wd5045) # Compiler will insert Spectre mitigation for memory load if /Qspectre switch specified
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# MacOS and GCC 11 or later need -Wno-maybe-uninitialized
|
|
||||||
# https://github.com/quickjs-ng/quickjs/issues/453
|
|
||||||
if(APPLE AND CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_GREATER_EQUAL 11)
|
|
||||||
xcheck_add_c_compiler_flag(-Wno-maybe-uninitialized)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME STREQUAL "WASI")
|
|
||||||
add_compile_definitions(
|
|
||||||
_WASI_EMULATED_PROCESS_CLOCKS
|
|
||||||
_WASI_EMULATED_SIGNAL
|
|
||||||
)
|
|
||||||
add_link_options(
|
|
||||||
-lwasi-emulated-process-clocks
|
|
||||||
-lwasi-emulated-signal
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CMAKE_BUILD_TYPE MATCHES "Debug")
|
|
||||||
add_compile_options(-O0)
|
|
||||||
xcheck_add_c_compiler_flag(-ggdb)
|
|
||||||
xcheck_add_c_compiler_flag(-fno-omit-frame-pointer)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
macro(xoption OPTION_NAME OPTION_TEXT OPTION_DEFAULT)
|
|
||||||
option(${OPTION_NAME} ${OPTION_TEXT} ${OPTION_DEFAULT})
|
|
||||||
if(DEFINED ENV{${OPTION_NAME}})
|
|
||||||
# Allow setting the option through an environment variable.
|
|
||||||
set(${OPTION_NAME} $ENV{${OPTION_NAME}})
|
|
||||||
endif()
|
|
||||||
if(${OPTION_NAME})
|
|
||||||
add_definitions(-D${OPTION_NAME})
|
|
||||||
endif()
|
|
||||||
message(STATUS " ${OPTION_NAME}: ${${OPTION_NAME}}")
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
xoption(BUILD_SHARED_LIBS "Build a shared library" OFF)
|
|
||||||
if(BUILD_SHARED_LIBS)
|
|
||||||
message(STATUS "Building a shared library")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# note: CONFIG_TSAN is currently incompatible with the other sanitizers but we
|
|
||||||
# don't explicitly check for that because who knows what the future will bring?
|
|
||||||
# CONFIG_MSAN only works with clang at the time of writing; also not checked
|
|
||||||
# for the same reason
|
|
||||||
xoption(BUILD_EXAMPLES "Build examples" OFF)
|
|
||||||
xoption(BUILD_STATIC_QJS_EXE "Build a static qjs executable" OFF)
|
|
||||||
xoption(BUILD_CLI_WITH_MIMALLOC "Build the qjs executable with mimalloc" OFF)
|
|
||||||
xoption(BUILD_CLI_WITH_STATIC_MIMALLOC "Build the qjs executable with mimalloc (statically linked)" OFF)
|
|
||||||
xoption(CONFIG_ASAN "Enable AddressSanitizer (ASan)" OFF)
|
|
||||||
xoption(CONFIG_MSAN "Enable MemorySanitizer (MSan)" OFF)
|
|
||||||
xoption(CONFIG_TSAN "Enable ThreadSanitizer (TSan)" OFF)
|
|
||||||
xoption(CONFIG_UBSAN "Enable UndefinedBehaviorSanitizer (UBSan)" OFF)
|
|
||||||
|
|
||||||
if(CONFIG_ASAN)
|
|
||||||
message(STATUS "Building with ASan")
|
|
||||||
add_compile_options(
|
|
||||||
-fsanitize=address
|
|
||||||
-fno-sanitize-recover=all
|
|
||||||
-fno-omit-frame-pointer
|
|
||||||
)
|
|
||||||
add_link_options(
|
|
||||||
-fsanitize=address
|
|
||||||
-fno-sanitize-recover=all
|
|
||||||
-fno-omit-frame-pointer
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CONFIG_MSAN)
|
|
||||||
message(STATUS "Building with MSan")
|
|
||||||
add_compile_options(
|
|
||||||
-fsanitize=memory
|
|
||||||
-fno-sanitize-recover=all
|
|
||||||
-fno-omit-frame-pointer
|
|
||||||
)
|
|
||||||
add_link_options(
|
|
||||||
-fsanitize=memory
|
|
||||||
-fno-sanitize-recover=all
|
|
||||||
-fno-omit-frame-pointer
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CONFIG_TSAN)
|
|
||||||
message(STATUS "Building with TSan")
|
|
||||||
add_compile_options(
|
|
||||||
-fsanitize=thread
|
|
||||||
-fno-sanitize-recover=all
|
|
||||||
-fno-omit-frame-pointer
|
|
||||||
)
|
|
||||||
add_link_options(
|
|
||||||
-fsanitize=thread
|
|
||||||
-fno-sanitize-recover=all
|
|
||||||
-fno-omit-frame-pointer
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(CONFIG_UBSAN)
|
|
||||||
message(STATUS "Building with UBSan")
|
|
||||||
add_compile_options(
|
|
||||||
-fsanitize=undefined
|
|
||||||
-fno-sanitize-recover=all
|
|
||||||
-fno-omit-frame-pointer
|
|
||||||
)
|
|
||||||
add_link_options(
|
|
||||||
-fsanitize=undefined
|
|
||||||
-fno-sanitize-recover=all
|
|
||||||
-fno-omit-frame-pointer
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# QuickJS library
|
|
||||||
#
|
|
||||||
|
|
||||||
xoption(BUILD_QJS_LIBC "Build standard library modules as part of the library" OFF)
|
|
||||||
macro(add_qjs_libc_if_needed target)
|
|
||||||
if(NOT BUILD_QJS_LIBC)
|
|
||||||
target_sources(${target} PRIVATE quickjs-libc.c)
|
|
||||||
endif()
|
|
||||||
endmacro()
|
|
||||||
|
|
||||||
set(qjs_sources
|
|
||||||
cutils.c
|
|
||||||
libbf.c
|
|
||||||
libregexp.c
|
|
||||||
libunicode.c
|
|
||||||
quickjs.c
|
|
||||||
)
|
|
||||||
|
|
||||||
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 ${CMAKE_DL_LIBS})
|
|
||||||
find_package(Threads)
|
|
||||||
if(NOT CMAKE_SYSTEM_NAME STREQUAL "WASI")
|
|
||||||
list(APPEND qjs_libs ${CMAKE_THREAD_LIBS_INIT})
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# try to find libm
|
|
||||||
find_library(M_LIBRARIES m)
|
|
||||||
if(M_LIBRARIES OR CMAKE_C_COMPILER_ID STREQUAL "TinyCC")
|
|
||||||
list(APPEND qjs_libs m)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(qjs ${qjs_sources})
|
|
||||||
target_compile_definitions(qjs PRIVATE ${qjs_defines})
|
|
||||||
target_include_directories(qjs PUBLIC
|
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
|
|
||||||
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
|
|
||||||
)
|
|
||||||
target_link_libraries(qjs PUBLIC ${qjs_libs})
|
|
||||||
|
|
||||||
if(EMSCRIPTEN)
|
|
||||||
add_executable(qjs_wasm ${qjs_sources})
|
|
||||||
target_link_options(qjs_wasm PRIVATE
|
|
||||||
# in emscripten 3.x, this will be set to 16k which is too small for quickjs. #write sth. to force github rebuild
|
|
||||||
-sSTACK_SIZE=2097152 # let it be 2m = 2 * 1024 * 1024 = 2097152, otherwise, stack overflow may be occured at bootstrap
|
|
||||||
-sNO_INVOKE_RUN
|
|
||||||
-sNO_EXIT_RUNTIME
|
|
||||||
-sMODULARIZE # do not mess the global
|
|
||||||
-sEXPORT_ES6 # export js file to morden es module
|
|
||||||
-sEXPORT_NAME=getQuickJs # give a name
|
|
||||||
-sTEXTDECODER=1 # it will be 2 if we use -Oz, and that will cause js -> c string convertion fail
|
|
||||||
-sNO_DEFAULT_TO_CXX # this project is pure c project, no need for c plus plus handle
|
|
||||||
-sEXPORTED_RUNTIME_METHODS=ccall,cwrap
|
|
||||||
)
|
|
||||||
target_compile_definitions(qjs_wasm PRIVATE ${qjs_defines})
|
|
||||||
target_link_libraries(qjs_wasm m)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
# QuickJS bytecode compiler
|
|
||||||
#
|
|
||||||
|
|
||||||
add_executable(qjsc
|
|
||||||
qjsc.c
|
|
||||||
)
|
|
||||||
add_qjs_libc_if_needed(qjsc)
|
|
||||||
target_compile_definitions(qjsc PRIVATE ${qjs_defines})
|
|
||||||
target_link_libraries(qjsc qjs)
|
|
||||||
|
|
||||||
|
|
||||||
# QuickJS CLI
|
|
||||||
#
|
|
||||||
|
|
||||||
add_executable(qjs_exe
|
|
||||||
gen/repl.c
|
|
||||||
gen/standalone.c
|
|
||||||
qjs.c
|
|
||||||
)
|
|
||||||
add_qjs_libc_if_needed(qjs_exe)
|
|
||||||
set_target_properties(qjs_exe PROPERTIES
|
|
||||||
OUTPUT_NAME "qjs"
|
|
||||||
)
|
|
||||||
target_compile_definitions(qjs_exe PRIVATE ${qjs_defines})
|
|
||||||
target_link_libraries(qjs_exe qjs)
|
|
||||||
if(BUILD_STATIC_QJS_EXE OR MINGW)
|
|
||||||
target_link_options(qjs_exe PRIVATE -static)
|
|
||||||
if(MINGW)
|
|
||||||
target_link_options(qjs_exe PRIVATE -static-libgcc)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
if(NOT WIN32)
|
|
||||||
set_target_properties(qjs_exe PROPERTIES ENABLE_EXPORTS TRUE)
|
|
||||||
endif()
|
|
||||||
if(BUILD_CLI_WITH_MIMALLOC OR BUILD_CLI_WITH_STATIC_MIMALLOC)
|
|
||||||
find_package(mimalloc REQUIRED)
|
|
||||||
# Upstream mimalloc doesn't provide a way to know if both libraries are supported.
|
|
||||||
if(BUILD_CLI_WITH_STATIC_MIMALLOC)
|
|
||||||
target_link_libraries(qjs_exe mimalloc-static)
|
|
||||||
else()
|
|
||||||
target_link_libraries(qjs_exe mimalloc)
|
|
||||||
endif()
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Test262 runner
|
|
||||||
#
|
|
||||||
|
|
||||||
if(NOT EMSCRIPTEN)
|
|
||||||
add_executable(run-test262
|
|
||||||
run-test262.c
|
|
||||||
)
|
|
||||||
add_qjs_libc_if_needed(run-test262)
|
|
||||||
target_compile_definitions(run-test262 PRIVATE ${qjs_defines})
|
|
||||||
target_link_libraries(run-test262 qjs)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# Unicode generator
|
|
||||||
#
|
|
||||||
|
|
||||||
add_executable(unicode_gen EXCLUDE_FROM_ALL
|
|
||||||
cutils.c
|
|
||||||
libunicode.c
|
|
||||||
unicode_gen.c
|
|
||||||
)
|
|
||||||
target_compile_definitions(unicode_gen PRIVATE ${qjs_defines})
|
|
||||||
|
|
||||||
add_executable(function_source
|
|
||||||
gen/function_source.c
|
|
||||||
)
|
|
||||||
add_qjs_libc_if_needed(function_source)
|
|
||||||
target_include_directories(function_source PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
target_compile_definitions(function_source PRIVATE ${qjs_defines})
|
|
||||||
target_link_libraries(function_source qjs)
|
|
||||||
|
|
||||||
# Examples
|
|
||||||
#
|
|
||||||
|
|
||||||
if(BUILD_EXAMPLES)
|
|
||||||
add_executable(hello
|
|
||||||
gen/hello.c
|
|
||||||
)
|
|
||||||
add_qjs_libc_if_needed(hello)
|
|
||||||
target_include_directories(hello PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
target_compile_definitions(hello PRIVATE ${qjs_defines})
|
|
||||||
target_link_libraries(hello qjs)
|
|
||||||
|
|
||||||
add_executable(hello_module
|
|
||||||
gen/hello_module.c
|
|
||||||
)
|
|
||||||
add_qjs_libc_if_needed(hello_module)
|
|
||||||
target_include_directories(hello_module PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
target_compile_definitions(hello_module PRIVATE ${qjs_defines})
|
|
||||||
target_link_libraries(hello_module qjs)
|
|
||||||
|
|
||||||
add_library(fib MODULE examples/fib.c)
|
|
||||||
set_target_properties(fib PROPERTIES
|
|
||||||
PREFIX ""
|
|
||||||
C_VISIBILITY_PRESET default
|
|
||||||
)
|
|
||||||
target_compile_definitions(fib PRIVATE JS_SHARED_LIBRARY)
|
|
||||||
if(WIN32)
|
|
||||||
target_link_libraries(fib qjs)
|
|
||||||
elseif(APPLE)
|
|
||||||
target_link_options(fib PRIVATE -undefined dynamic_lookup)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_library(point MODULE examples/point.c)
|
|
||||||
set_target_properties(point PROPERTIES
|
|
||||||
PREFIX ""
|
|
||||||
C_VISIBILITY_PRESET default
|
|
||||||
)
|
|
||||||
target_compile_definitions(point PRIVATE JS_SHARED_LIBRARY)
|
|
||||||
if(WIN32)
|
|
||||||
target_link_libraries(point qjs)
|
|
||||||
elseif(APPLE)
|
|
||||||
target_link_options(point PRIVATE -undefined dynamic_lookup)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_executable(test_fib
|
|
||||||
examples/fib.c
|
|
||||||
gen/test_fib.c
|
|
||||||
)
|
|
||||||
add_qjs_libc_if_needed(test_fib)
|
|
||||||
target_include_directories(test_fib PRIVATE ${CMAKE_CURRENT_SOURCE_DIR})
|
|
||||||
target_compile_definitions(test_fib PRIVATE ${qjs_defines})
|
|
||||||
target_link_libraries(test_fib qjs)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# 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 qjsc 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})
|
|
||||||
endif()
|
|
175
Changelog
Normal file
175
Changelog
Normal file
|
@ -0,0 +1,175 @@
|
||||||
|
2024-01-13:
|
||||||
|
|
||||||
|
- top-level-await support in modules
|
||||||
|
- allow 'await' in the REPL
|
||||||
|
- added Array.prototype.{with,toReversed,toSpliced,toSorted} and
|
||||||
|
TypedArray.prototype.{with,toReversed,toSorted}
|
||||||
|
- added String.prototype.isWellFormed and String.prototype.toWellFormed
|
||||||
|
- added Object.groupBy and Map.groupBy
|
||||||
|
- added Promise.withResolvers
|
||||||
|
- class static block
|
||||||
|
- 'in' operator support for private fields
|
||||||
|
- optional chaining fixes
|
||||||
|
- added RegExp 'd' flag
|
||||||
|
- fixed RegExp zero length match logic
|
||||||
|
- fixed RegExp case insensitive flag
|
||||||
|
- added os.sleepAsync(), os.getpid() and os.now()
|
||||||
|
- added cosmopolitan build
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2023-12-09:
|
||||||
|
|
||||||
|
- added Object.hasOwn, {String|Array|TypedArray}.prototype.at,
|
||||||
|
{Array|TypedArray}.prototype.findLast{Index}
|
||||||
|
- BigInt support is enabled even if CONFIG_BIGNUM disabled
|
||||||
|
- updated to Unicode 15.0.0
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2021-03-27:
|
||||||
|
|
||||||
|
- faster Array.prototype.push and Array.prototype.unshift
|
||||||
|
- added JS_UpdateStackTop()
|
||||||
|
- fixed Windows console
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2020-11-08:
|
||||||
|
|
||||||
|
- improved function parameter initializers
|
||||||
|
- added std.setenv(), std.unsetenv() and std.getenviron()
|
||||||
|
- added JS_EvalThis()
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2020-09-06:
|
||||||
|
|
||||||
|
- added logical assignment operators
|
||||||
|
- added IsHTMLDDA support
|
||||||
|
- faster for-of loops
|
||||||
|
- os.Worker now takes a module filename as parameter
|
||||||
|
- qjsc: added -D option to compile dynamically loaded modules or workers
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2020-07-05:
|
||||||
|
|
||||||
|
- modified JS_GetPrototype() to return a live value
|
||||||
|
- REPL: support unicode characters larger than 16 bits
|
||||||
|
- added os.Worker
|
||||||
|
- improved object serialization
|
||||||
|
- added std.parseExtJSON
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2020-04-12:
|
||||||
|
|
||||||
|
- added cross realm support
|
||||||
|
- added AggregateError and Promise.any
|
||||||
|
- added env, uid and gid options in os.exec()
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2020-03-16:
|
||||||
|
|
||||||
|
- reworked error handling in std and os libraries: suppressed I/O
|
||||||
|
exceptions in std FILE functions and return a positive errno value
|
||||||
|
when it is explicit
|
||||||
|
- output exception messages to stderr
|
||||||
|
- added std.loadFile(), std.strerror(), std.FILE.prototype.tello()
|
||||||
|
- added JS_GetRuntimeOpaque(), JS_SetRuntimeOpaque(), JS_NewUint32()
|
||||||
|
- updated to Unicode 13.0.0
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2020-01-19:
|
||||||
|
|
||||||
|
- keep CONFIG_BIGNUM in the makefile
|
||||||
|
- added os.chdir()
|
||||||
|
- qjs: added -I option
|
||||||
|
- more memory checks in the bignum operations
|
||||||
|
- modified operator overloading semantics to be closer to the TC39
|
||||||
|
proposal
|
||||||
|
- suppressed "use bigint" mode. Simplified "use math" mode
|
||||||
|
- BigDecimal: changed suffix from 'd' to 'm'
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2020-01-05:
|
||||||
|
|
||||||
|
- always compile the bignum code. Added '--bignum' option to qjs.
|
||||||
|
- added BigDecimal
|
||||||
|
- added String.prototype.replaceAll
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2019-12-21:
|
||||||
|
|
||||||
|
- added nullish coalescing operator (ES2020)
|
||||||
|
- added optional chaining (ES2020)
|
||||||
|
- removed recursions in garbage collector
|
||||||
|
- test stack overflow in the parser
|
||||||
|
- improved backtrace logic
|
||||||
|
- added JS_SetHostPromiseRejectionTracker()
|
||||||
|
- allow exotic constructors
|
||||||
|
- improved c++ compatibility
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2019-10-27:
|
||||||
|
|
||||||
|
- added example of C class in a module (examples/test_point.js)
|
||||||
|
- added JS_GetTypedArrayBuffer()
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2019-09-18:
|
||||||
|
|
||||||
|
- added os.exec and other system calls
|
||||||
|
- exported JS_ValueToAtom()
|
||||||
|
- qjsc: added 'qjsc_' prefix to the generated C identifiers
|
||||||
|
- added cross-compilation support
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2019-09-01:
|
||||||
|
|
||||||
|
- added globalThis
|
||||||
|
- documented JS_EVAL_FLAG_COMPILE_ONLY
|
||||||
|
- added import.meta.url and import.meta.main
|
||||||
|
- added 'debugger' statement
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2019-08-18:
|
||||||
|
|
||||||
|
- added os.realpath, os.getcwd, os.mkdir, os.stat, os.lstat,
|
||||||
|
os.readlink, os.readdir, os.utimes, std.popen
|
||||||
|
- module autodetection
|
||||||
|
- added import.meta
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2019-08-10:
|
||||||
|
|
||||||
|
- added public class fields and private class fields, methods and
|
||||||
|
accessors (TC39 proposal)
|
||||||
|
- changed JS_ToCStringLen() prototype
|
||||||
|
- qjsc: handle '-' in module names and modules with the same filename
|
||||||
|
- added std.urlGet
|
||||||
|
- exported JS_GetOwnPropertyNames() and JS_GetOwnProperty()
|
||||||
|
- exported some bigint C functions
|
||||||
|
- added support for eshost in run-test262
|
||||||
|
- misc bug fixes
|
||||||
|
|
||||||
|
2019-07-28:
|
||||||
|
|
||||||
|
- added dynamic import
|
||||||
|
- added Promise.allSettled
|
||||||
|
- added String.prototype.matchAll
|
||||||
|
- added Object.fromEntries
|
||||||
|
- reduced number of ticks in await
|
||||||
|
- added BigInt support in Atomics
|
||||||
|
- exported JS_NewPromiseCapability()
|
||||||
|
- misc async function and async generator fixes
|
||||||
|
- enabled hashbang support by default
|
||||||
|
|
||||||
|
2019-07-21:
|
||||||
|
|
||||||
|
- updated test262 tests
|
||||||
|
- updated to Unicode version 12.1.0
|
||||||
|
- fixed missing Date object in qjsc
|
||||||
|
- fixed multi-context creation
|
||||||
|
- misc ES2020 related fixes
|
||||||
|
- simplified power and division operators in bignum extension
|
||||||
|
- fixed several crash conditions
|
||||||
|
|
||||||
|
2019-07-09:
|
||||||
|
|
||||||
|
- first public release
|
5
LICENSE
5
LICENSE
|
@ -1,8 +1,5 @@
|
||||||
QuickJS Javascript Engine (DoneJS Edition)
|
QuickJS Javascript Engine
|
||||||
|
|
||||||
Copyright (c) 2025 Sneed Group
|
|
||||||
Copyright (c) 2023 Ben Noordhuis
|
|
||||||
Copyright (c) 2023 Saúl Ibarra Corretgé
|
|
||||||
Copyright (c) 2017-2021 Fabrice Bellard
|
Copyright (c) 2017-2021 Fabrice Bellard
|
||||||
Copyright (c) 2017-2021 Charlie Gordon
|
Copyright (c) 2017-2021 Charlie Gordon
|
||||||
|
|
||||||
|
|
610
Makefile
610
Makefile
|
@ -3,8 +3,6 @@
|
||||||
#
|
#
|
||||||
# Copyright (c) 2017-2021 Fabrice Bellard
|
# Copyright (c) 2017-2021 Fabrice Bellard
|
||||||
# Copyright (c) 2017-2021 Charlie Gordon
|
# Copyright (c) 2017-2021 Charlie Gordon
|
||||||
# Copyright (c) 2023 Ben Noordhuis
|
|
||||||
# Copyright (c) 2023 Saúl Ibarra Corretgé
|
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
# of this software and associated documentation files (the "Software"), to deal
|
# of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -24,97 +22,569 @@
|
||||||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
# THE SOFTWARE.
|
# THE SOFTWARE.
|
||||||
|
|
||||||
BUILD_DIR=build
|
ifeq ($(shell uname -s),Darwin)
|
||||||
BUILD_TYPE?=Release
|
CONFIG_DARWIN=y
|
||||||
INSTALL_PREFIX?=/usr/local
|
|
||||||
|
|
||||||
QJS=$(BUILD_DIR)/qjs
|
|
||||||
QJSC=$(BUILD_DIR)/qjsc
|
|
||||||
RUN262=$(BUILD_DIR)/run-test262
|
|
||||||
|
|
||||||
JOBS?=$(shell getconf _NPROCESSORS_ONLN)
|
|
||||||
ifeq ($(JOBS),)
|
|
||||||
JOBS := $(shell sysctl -n hw.ncpu)
|
|
||||||
endif
|
endif
|
||||||
ifeq ($(JOBS),)
|
ifeq ($(shell uname -s),FreeBSD)
|
||||||
JOBS := $(shell nproc)
|
CONFIG_FREEBSD=y
|
||||||
endif
|
endif
|
||||||
ifeq ($(JOBS),)
|
# Windows cross compilation from Linux
|
||||||
JOBS := 4
|
#CONFIG_WIN32=y
|
||||||
|
# use link time optimization (smaller and faster executables but slower build)
|
||||||
|
#CONFIG_LTO=y
|
||||||
|
# consider warnings as errors (for development)
|
||||||
|
#CONFIG_WERROR=y
|
||||||
|
# force 32 bit build for some utilities
|
||||||
|
#CONFIG_M32=y
|
||||||
|
# cosmopolitan build (see https://github.com/jart/cosmopolitan)
|
||||||
|
#CONFIG_COSMO=y
|
||||||
|
|
||||||
|
# installation directory
|
||||||
|
PREFIX?=/usr/local
|
||||||
|
|
||||||
|
# use the gprof profiler
|
||||||
|
#CONFIG_PROFILE=y
|
||||||
|
# use address sanitizer
|
||||||
|
#CONFIG_ASAN=y
|
||||||
|
# use memory sanitizer
|
||||||
|
#CONFIG_MSAN=y
|
||||||
|
# use UB sanitizer
|
||||||
|
#CONFIG_UBSAN=y
|
||||||
|
|
||||||
|
# include the code for BigFloat/BigDecimal and math mode
|
||||||
|
CONFIG_BIGNUM=y
|
||||||
|
|
||||||
|
OBJDIR=.obj
|
||||||
|
|
||||||
|
ifdef CONFIG_ASAN
|
||||||
|
OBJDIR:=$(OBJDIR)/asan
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_MSAN
|
||||||
|
OBJDIR:=$(OBJDIR)/msan
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_UBSAN
|
||||||
|
OBJDIR:=$(OBJDIR)/ubsan
|
||||||
endif
|
endif
|
||||||
|
|
||||||
all: $(QJS)
|
ifdef CONFIG_DARWIN
|
||||||
|
# use clang instead of gcc
|
||||||
|
CONFIG_CLANG=y
|
||||||
|
CONFIG_DEFAULT_AR=y
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_FREEBSD
|
||||||
|
# use clang instead of gcc
|
||||||
|
CONFIG_CLANG=y
|
||||||
|
CONFIG_DEFAULT_AR=y
|
||||||
|
CONFIG_LTO=
|
||||||
|
endif
|
||||||
|
|
||||||
fuzz:
|
ifdef CONFIG_WIN32
|
||||||
clang -g -O1 -fsanitize=address,undefined,fuzzer -o fuzz fuzz.c
|
ifdef CONFIG_M32
|
||||||
./fuzz
|
CROSS_PREFIX?=i686-w64-mingw32-
|
||||||
|
else
|
||||||
|
CROSS_PREFIX?=x86_64-w64-mingw32-
|
||||||
|
endif
|
||||||
|
EXE=.exe
|
||||||
|
else
|
||||||
|
CROSS_PREFIX?=
|
||||||
|
EXE=
|
||||||
|
endif
|
||||||
|
|
||||||
$(BUILD_DIR):
|
ifdef CONFIG_CLANG
|
||||||
cmake -B $(BUILD_DIR) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE) -DCMAKE_INSTALL_PREFIX=$(INSTALL_PREFIX)
|
HOST_CC=clang
|
||||||
|
CC=$(CROSS_PREFIX)clang
|
||||||
|
CFLAGS+=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d
|
||||||
|
CFLAGS += -Wextra
|
||||||
|
CFLAGS += -Wno-sign-compare
|
||||||
|
CFLAGS += -Wno-missing-field-initializers
|
||||||
|
CFLAGS += -Wundef -Wuninitialized
|
||||||
|
CFLAGS += -Wunused -Wno-unused-parameter
|
||||||
|
CFLAGS += -Wwrite-strings
|
||||||
|
CFLAGS += -Wchar-subscripts -funsigned-char
|
||||||
|
CFLAGS += -MMD -MF $(OBJDIR)/$(@F).d
|
||||||
|
ifdef CONFIG_DEFAULT_AR
|
||||||
|
AR=$(CROSS_PREFIX)ar
|
||||||
|
else
|
||||||
|
ifdef CONFIG_LTO
|
||||||
|
AR=$(CROSS_PREFIX)llvm-ar
|
||||||
|
else
|
||||||
|
AR=$(CROSS_PREFIX)ar
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
LIB_FUZZING_ENGINE ?= "-fsanitize=fuzzer"
|
||||||
|
else ifdef CONFIG_COSMO
|
||||||
|
CONFIG_LTO=
|
||||||
|
HOST_CC=gcc
|
||||||
|
CC=cosmocc
|
||||||
|
# cosmocc does not correct support -MF
|
||||||
|
CFLAGS=-g -Wall #-MMD -MF $(OBJDIR)/$(@F).d
|
||||||
|
CFLAGS += -Wno-array-bounds -Wno-format-truncation
|
||||||
|
AR=cosmoar
|
||||||
|
else
|
||||||
|
HOST_CC=gcc
|
||||||
|
CC=$(CROSS_PREFIX)gcc
|
||||||
|
CFLAGS+=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d
|
||||||
|
CFLAGS += -Wno-array-bounds -Wno-format-truncation
|
||||||
|
ifdef CONFIG_LTO
|
||||||
|
AR=$(CROSS_PREFIX)gcc-ar
|
||||||
|
else
|
||||||
|
AR=$(CROSS_PREFIX)ar
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
STRIP?=$(CROSS_PREFIX)strip
|
||||||
|
CFLAGS+=-fwrapv # ensure that signed overflows behave as expected
|
||||||
|
ifdef CONFIG_WERROR
|
||||||
|
CFLAGS+=-Werror
|
||||||
|
endif
|
||||||
|
DEFINES:=-D_GNU_SOURCE -DCONFIG_VERSION=\"$(shell cat VERSION)\"
|
||||||
|
ifdef CONFIG_BIGNUM
|
||||||
|
DEFINES+=-DCONFIG_BIGNUM
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_WIN32
|
||||||
|
DEFINES+=-D__USE_MINGW_ANSI_STDIO # for standard snprintf behavior
|
||||||
|
endif
|
||||||
|
ifndef CONFIG_WIN32
|
||||||
|
ifeq ($(shell $(CC) -o /dev/null compat/test-closefrom.c 2>/dev/null && echo 1),1)
|
||||||
|
DEFINES+=-DHAVE_CLOSEFROM
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
$(QJS): $(BUILD_DIR)
|
CFLAGS+=$(DEFINES)
|
||||||
cmake --build $(BUILD_DIR) -j $(JOBS)
|
CFLAGS_DEBUG=$(CFLAGS) -O0
|
||||||
|
CFLAGS_SMALL=$(CFLAGS) -Os
|
||||||
|
CFLAGS_OPT=$(CFLAGS) -O2
|
||||||
|
CFLAGS_NOLTO:=$(CFLAGS_OPT)
|
||||||
|
ifdef CONFIG_COSMO
|
||||||
|
LDFLAGS+=-s # better to strip by default
|
||||||
|
else
|
||||||
|
LDFLAGS+=-g
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_LTO
|
||||||
|
CFLAGS_SMALL+=-flto
|
||||||
|
CFLAGS_OPT+=-flto
|
||||||
|
LDFLAGS+=-flto
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_PROFILE
|
||||||
|
CFLAGS+=-p
|
||||||
|
LDFLAGS+=-p
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_ASAN
|
||||||
|
CFLAGS+=-fsanitize=address -fno-omit-frame-pointer
|
||||||
|
LDFLAGS+=-fsanitize=address -fno-omit-frame-pointer
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_MSAN
|
||||||
|
CFLAGS+=-fsanitize=memory -fno-omit-frame-pointer
|
||||||
|
LDFLAGS+=-fsanitize=memory -fno-omit-frame-pointer
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_UBSAN
|
||||||
|
CFLAGS+=-fsanitize=undefined -fno-omit-frame-pointer
|
||||||
|
LDFLAGS+=-fsanitize=undefined -fno-omit-frame-pointer
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_WIN32
|
||||||
|
LDEXPORT=
|
||||||
|
else
|
||||||
|
LDEXPORT=-rdynamic
|
||||||
|
endif
|
||||||
|
|
||||||
$(QJSC): $(BUILD_DIR)
|
ifndef CONFIG_COSMO
|
||||||
cmake --build $(BUILD_DIR) --target qjsc -j $(JOBS)
|
ifndef CONFIG_DARWIN
|
||||||
|
CONFIG_SHARED_LIBS=y # building shared libraries is supported
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
install: $(QJS) $(QJSC)
|
PROGS=qjs$(EXE) qjsc$(EXE) run-test262
|
||||||
cmake --build $(BUILD_DIR) --target install
|
ifneq ($(CROSS_PREFIX),)
|
||||||
|
QJSC_CC=gcc
|
||||||
|
QJSC=./host-qjsc
|
||||||
|
PROGS+=$(QJSC)
|
||||||
|
else
|
||||||
|
QJSC_CC=$(CC)
|
||||||
|
QJSC=./qjsc$(EXE)
|
||||||
|
endif
|
||||||
|
ifndef CONFIG_WIN32
|
||||||
|
PROGS+=qjscalc
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_M32
|
||||||
|
PROGS+=qjs32 qjs32_s
|
||||||
|
endif
|
||||||
|
PROGS+=libquickjs.a
|
||||||
|
ifdef CONFIG_LTO
|
||||||
|
PROGS+=libquickjs.lto.a
|
||||||
|
endif
|
||||||
|
|
||||||
clean:
|
# examples
|
||||||
cmake --build $(BUILD_DIR) --target clean
|
ifeq ($(CROSS_PREFIX),)
|
||||||
|
ifndef CONFIG_ASAN
|
||||||
|
ifndef CONFIG_MSAN
|
||||||
|
ifndef CONFIG_UBSAN
|
||||||
|
PROGS+=examples/hello examples/hello_module examples/test_fib
|
||||||
|
ifdef CONFIG_SHARED_LIBS
|
||||||
|
PROGS+=examples/fib.so examples/point.so
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
codegen: $(QJSC)
|
all: $(OBJDIR) $(OBJDIR)/quickjs.check.o $(OBJDIR)/qjs.check.o $(PROGS)
|
||||||
$(QJSC) -ss -o gen/repl.c -m repl.js
|
|
||||||
$(QJSC) -ss -o gen/standalone.c -m standalone.js
|
|
||||||
$(QJSC) -e -o gen/function_source.c tests/function_source.js
|
|
||||||
$(QJSC) -e -o gen/hello.c examples/hello.js
|
|
||||||
$(QJSC) -e -o gen/hello_module.c -m examples/hello_module.js
|
|
||||||
$(QJSC) -e -o gen/test_fib.c -M examples/fib.so,fib -m examples/test_fib.js
|
|
||||||
|
|
||||||
debug:
|
QJS_LIB_OBJS=$(OBJDIR)/quickjs.o $(OBJDIR)/libregexp.o $(OBJDIR)/libunicode.o $(OBJDIR)/cutils.o $(OBJDIR)/quickjs-libc.o $(OBJDIR)/libbf.o
|
||||||
BUILD_TYPE=Debug $(MAKE)
|
|
||||||
|
|
||||||
distclean:
|
QJS_OBJS=$(OBJDIR)/qjs.o $(OBJDIR)/repl.o $(QJS_LIB_OBJS)
|
||||||
@rm -rf $(BUILD_DIR)
|
ifdef CONFIG_BIGNUM
|
||||||
|
QJS_OBJS+=$(OBJDIR)/qjscalc.o
|
||||||
|
endif
|
||||||
|
|
||||||
stats: $(QJS)
|
HOST_LIBS=-lm -ldl -lpthread
|
||||||
$(QJS) -qd
|
LIBS=-lm
|
||||||
|
ifndef CONFIG_WIN32
|
||||||
|
LIBS+=-ldl -lpthread
|
||||||
|
endif
|
||||||
|
LIBS+=$(EXTRA_LIBS)
|
||||||
|
|
||||||
# effectively .PHONY because it doesn't generate output
|
$(OBJDIR):
|
||||||
ctest: CFLAGS=-std=c11 -fsyntax-only -Wall -Wextra -Werror -pedantic
|
mkdir -p $(OBJDIR) $(OBJDIR)/examples $(OBJDIR)/tests
|
||||||
ctest: ctest.c quickjs.h
|
|
||||||
$(CC) $(CFLAGS) -DJS_NAN_BOXING=0 $<
|
|
||||||
$(CC) $(CFLAGS) -DJS_NAN_BOXING=1 $<
|
|
||||||
|
|
||||||
# effectively .PHONY because it doesn't generate output
|
qjs$(EXE): $(QJS_OBJS)
|
||||||
cxxtest: CXXFLAGS=-std=c++11 -fsyntax-only -Wall -Wextra -Werror -pedantic
|
$(CC) $(LDFLAGS) $(LDEXPORT) -o $@ $^ $(LIBS)
|
||||||
cxxtest: cxxtest.cc quickjs.h
|
|
||||||
$(CXX) $(CXXFLAGS) -DJS_NAN_BOXING=0 $<
|
|
||||||
$(CXX) $(CXXFLAGS) -DJS_NAN_BOXING=1 $<
|
|
||||||
|
|
||||||
test: $(QJS)
|
qjs-debug$(EXE): $(patsubst %.o, %.debug.o, $(QJS_OBJS))
|
||||||
$(RUN262) -c tests.conf
|
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
test262: $(QJS)
|
qjsc$(EXE): $(OBJDIR)/qjsc.o $(QJS_LIB_OBJS)
|
||||||
$(RUN262) -m -c test262.conf -a
|
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
test262-fast: $(QJS)
|
fuzz_eval: $(OBJDIR)/fuzz_eval.o $(OBJDIR)/fuzz_common.o libquickjs.fuzz.a
|
||||||
$(RUN262) -m -c test262.conf -c test262-fast.conf -a
|
$(CC) $(CFLAGS_OPT) $^ -o fuzz_eval $(LIB_FUZZING_ENGINE)
|
||||||
|
|
||||||
test262-update: $(QJS)
|
fuzz_compile: $(OBJDIR)/fuzz_compile.o $(OBJDIR)/fuzz_common.o libquickjs.fuzz.a
|
||||||
$(RUN262) -u -c test262.conf -a -t 1
|
$(CC) $(CFLAGS_OPT) $^ -o fuzz_compile $(LIB_FUZZING_ENGINE)
|
||||||
|
|
||||||
test262-check: $(QJS)
|
fuzz_regexp: $(OBJDIR)/fuzz_regexp.o $(OBJDIR)/libregexp.fuzz.o $(OBJDIR)/cutils.fuzz.o $(OBJDIR)/libunicode.fuzz.o
|
||||||
$(RUN262) -m -c test262.conf -E -a
|
$(CC) $(CFLAGS_OPT) $^ -o fuzz_regexp $(LIB_FUZZING_ENGINE)
|
||||||
|
|
||||||
microbench: $(QJS)
|
libfuzzer: fuzz_eval fuzz_compile fuzz_regexp
|
||||||
$(QJS) tests/microbench.js
|
|
||||||
|
|
||||||
unicode_gen: $(BUILD_DIR)
|
ifneq ($(CROSS_PREFIX),)
|
||||||
cmake --build $(BUILD_DIR) --target unicode_gen
|
|
||||||
|
$(QJSC): $(OBJDIR)/qjsc.host.o \
|
||||||
|
$(patsubst %.o, %.host.o, $(QJS_LIB_OBJS))
|
||||||
|
$(HOST_CC) $(LDFLAGS) -o $@ $^ $(HOST_LIBS)
|
||||||
|
|
||||||
|
endif #CROSS_PREFIX
|
||||||
|
|
||||||
|
QJSC_DEFINES:=-DCONFIG_CC=\"$(QJSC_CC)\" -DCONFIG_PREFIX=\"$(PREFIX)\"
|
||||||
|
ifdef CONFIG_LTO
|
||||||
|
QJSC_DEFINES+=-DCONFIG_LTO
|
||||||
|
endif
|
||||||
|
QJSC_HOST_DEFINES:=-DCONFIG_CC=\"$(HOST_CC)\" -DCONFIG_PREFIX=\"$(PREFIX)\"
|
||||||
|
|
||||||
|
$(OBJDIR)/qjsc.o: CFLAGS+=$(QJSC_DEFINES)
|
||||||
|
$(OBJDIR)/qjsc.host.o: CFLAGS+=$(QJSC_HOST_DEFINES)
|
||||||
|
|
||||||
|
qjs32: $(patsubst %.o, %.m32.o, $(QJS_OBJS))
|
||||||
|
$(CC) -m32 $(LDFLAGS) $(LDEXPORT) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
|
qjs32_s: $(patsubst %.o, %.m32s.o, $(QJS_OBJS))
|
||||||
|
$(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
@size $@
|
||||||
|
|
||||||
|
qjscalc: qjs
|
||||||
|
ln -sf $< $@
|
||||||
|
|
||||||
|
ifdef CONFIG_LTO
|
||||||
|
LTOEXT=.lto
|
||||||
|
else
|
||||||
|
LTOEXT=
|
||||||
|
endif
|
||||||
|
|
||||||
|
libquickjs$(LTOEXT).a: $(QJS_LIB_OBJS)
|
||||||
|
$(AR) rcs $@ $^
|
||||||
|
|
||||||
|
ifdef CONFIG_LTO
|
||||||
|
libquickjs.a: $(patsubst %.o, %.nolto.o, $(QJS_LIB_OBJS))
|
||||||
|
$(AR) rcs $@ $^
|
||||||
|
endif # CONFIG_LTO
|
||||||
|
|
||||||
|
libquickjs.fuzz.a: $(patsubst %.o, %.fuzz.o, $(QJS_LIB_OBJS))
|
||||||
|
$(AR) rcs $@ $^
|
||||||
|
|
||||||
|
repl.c: $(QJSC) repl.js
|
||||||
|
$(QJSC) -c -o $@ -m repl.js
|
||||||
|
|
||||||
|
qjscalc.c: $(QJSC) qjscalc.js
|
||||||
|
$(QJSC) -fbignum -c -o $@ qjscalc.js
|
||||||
|
|
||||||
|
ifneq ($(wildcard unicode/UnicodeData.txt),)
|
||||||
|
$(OBJDIR)/libunicode.o $(OBJDIR)/libunicode.m32.o $(OBJDIR)/libunicode.m32s.o \
|
||||||
|
$(OBJDIR)/libunicode.nolto.o: libunicode-table.h
|
||||||
|
|
||||||
libunicode-table.h: unicode_gen
|
libunicode-table.h: unicode_gen
|
||||||
$(BUILD_DIR)/unicode_gen unicode $@
|
./unicode_gen unicode $@
|
||||||
|
endif
|
||||||
|
|
||||||
.PHONY: all ctest cxxtest debug fuzz install clean codegen distclean stats test test262 test262-update test262-check microbench unicode_gen $(QJS) $(QJSC)
|
run-test262: $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS)
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
|
run-test262-debug: $(patsubst %.o, %.debug.o, $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS))
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
|
run-test262-32: $(patsubst %.o, %.m32.o, $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS))
|
||||||
|
$(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
|
# object suffix order: nolto, [m32|m32s]
|
||||||
|
|
||||||
|
$(OBJDIR)/%.o: %.c | $(OBJDIR)
|
||||||
|
$(CC) $(CFLAGS_OPT) -c -o $@ $<
|
||||||
|
|
||||||
|
$(OBJDIR)/fuzz_%.o: fuzz/fuzz_%.c | $(OBJDIR)
|
||||||
|
$(CC) $(CFLAGS_OPT) -c -I. -o $@ $<
|
||||||
|
|
||||||
|
$(OBJDIR)/%.host.o: %.c | $(OBJDIR)
|
||||||
|
$(HOST_CC) $(CFLAGS_OPT) -c -o $@ $<
|
||||||
|
|
||||||
|
$(OBJDIR)/%.pic.o: %.c | $(OBJDIR)
|
||||||
|
$(CC) $(CFLAGS_OPT) -fPIC -DJS_SHARED_LIBRARY -c -o $@ $<
|
||||||
|
|
||||||
|
$(OBJDIR)/%.nolto.o: %.c | $(OBJDIR)
|
||||||
|
$(CC) $(CFLAGS_NOLTO) -c -o $@ $<
|
||||||
|
|
||||||
|
$(OBJDIR)/%.m32.o: %.c | $(OBJDIR)
|
||||||
|
$(CC) -m32 $(CFLAGS_OPT) -c -o $@ $<
|
||||||
|
|
||||||
|
$(OBJDIR)/%.m32s.o: %.c | $(OBJDIR)
|
||||||
|
$(CC) -m32 $(CFLAGS_SMALL) -c -o $@ $<
|
||||||
|
|
||||||
|
$(OBJDIR)/%.debug.o: %.c | $(OBJDIR)
|
||||||
|
$(CC) $(CFLAGS_DEBUG) -c -o $@ $<
|
||||||
|
|
||||||
|
$(OBJDIR)/%.fuzz.o: %.c | $(OBJDIR)
|
||||||
|
$(CC) $(CFLAGS_OPT) -fsanitize=fuzzer-no-link -c -o $@ $<
|
||||||
|
|
||||||
|
$(OBJDIR)/%.check.o: %.c | $(OBJDIR)
|
||||||
|
$(CC) $(CFLAGS) -DCONFIG_CHECK_JSVALUE -c -o $@ $<
|
||||||
|
|
||||||
|
regexp_test: libregexp.c libunicode.c cutils.c
|
||||||
|
$(CC) $(LDFLAGS) $(CFLAGS) -DTEST -o $@ libregexp.c libunicode.c cutils.c $(LIBS)
|
||||||
|
|
||||||
|
unicode_gen: $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o libunicode.c unicode_gen_def.h
|
||||||
|
$(HOST_CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -f repl.c qjscalc.c out.c
|
||||||
|
rm -f *.a *.o *.d *~ unicode_gen regexp_test fuzz_eval fuzz_compile fuzz_regexp $(PROGS)
|
||||||
|
rm -f hello.c test_fib.c
|
||||||
|
rm -f examples/*.so tests/*.so
|
||||||
|
rm -rf $(OBJDIR)/ *.dSYM/ qjs-debug
|
||||||
|
rm -rf run-test262-debug run-test262-32
|
||||||
|
rm -f run_octane run_sunspider_like
|
||||||
|
|
||||||
|
install: all
|
||||||
|
mkdir -p "$(DESTDIR)$(PREFIX)/bin"
|
||||||
|
$(STRIP) qjs$(EXE) qjsc$(EXE)
|
||||||
|
install -m755 qjs$(EXE) qjsc$(EXE) "$(DESTDIR)$(PREFIX)/bin"
|
||||||
|
ln -sf qjs$(EXE) "$(DESTDIR)$(PREFIX)/bin/qjscalc$(EXE)"
|
||||||
|
mkdir -p "$(DESTDIR)$(PREFIX)/lib/quickjs"
|
||||||
|
install -m644 libquickjs.a "$(DESTDIR)$(PREFIX)/lib/quickjs"
|
||||||
|
ifdef CONFIG_LTO
|
||||||
|
install -m644 libquickjs.lto.a "$(DESTDIR)$(PREFIX)/lib/quickjs"
|
||||||
|
endif
|
||||||
|
mkdir -p "$(DESTDIR)$(PREFIX)/include/quickjs"
|
||||||
|
install -m644 quickjs.h quickjs-libc.h "$(DESTDIR)$(PREFIX)/include/quickjs"
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# examples
|
||||||
|
|
||||||
|
# example of static JS compilation
|
||||||
|
HELLO_SRCS=examples/hello.js
|
||||||
|
HELLO_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \
|
||||||
|
-fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \
|
||||||
|
-fno-date -fno-module-loader -fno-bigint
|
||||||
|
|
||||||
|
hello.c: $(QJSC) $(HELLO_SRCS)
|
||||||
|
$(QJSC) -e $(HELLO_OPTS) -o $@ $(HELLO_SRCS)
|
||||||
|
|
||||||
|
ifdef CONFIG_M32
|
||||||
|
examples/hello: $(OBJDIR)/hello.m32s.o $(patsubst %.o, %.m32s.o, $(QJS_LIB_OBJS))
|
||||||
|
$(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
else
|
||||||
|
examples/hello: $(OBJDIR)/hello.o $(QJS_LIB_OBJS)
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
# example of static JS compilation with modules
|
||||||
|
HELLO_MODULE_SRCS=examples/hello_module.js
|
||||||
|
HELLO_MODULE_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \
|
||||||
|
-fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \
|
||||||
|
-fno-date -m
|
||||||
|
examples/hello_module: $(QJSC) libquickjs$(LTOEXT).a $(HELLO_MODULE_SRCS)
|
||||||
|
$(QJSC) $(HELLO_MODULE_OPTS) -o $@ $(HELLO_MODULE_SRCS)
|
||||||
|
|
||||||
|
# use of an external C module (static compilation)
|
||||||
|
|
||||||
|
test_fib.c: $(QJSC) examples/test_fib.js
|
||||||
|
$(QJSC) -e -M examples/fib.so,fib -m -o $@ examples/test_fib.js
|
||||||
|
|
||||||
|
examples/test_fib: $(OBJDIR)/test_fib.o $(OBJDIR)/examples/fib.o libquickjs$(LTOEXT).a
|
||||||
|
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
|
examples/fib.so: $(OBJDIR)/examples/fib.pic.o
|
||||||
|
$(CC) $(LDFLAGS) -shared -o $@ $^
|
||||||
|
|
||||||
|
examples/point.so: $(OBJDIR)/examples/point.pic.o
|
||||||
|
$(CC) $(LDFLAGS) -shared -o $@ $^
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# documentation
|
||||||
|
|
||||||
|
DOCS=doc/quickjs.pdf doc/quickjs.html doc/jsbignum.pdf doc/jsbignum.html
|
||||||
|
|
||||||
|
build_doc: $(DOCS)
|
||||||
|
|
||||||
|
clean_doc:
|
||||||
|
rm -f $(DOCS)
|
||||||
|
|
||||||
|
doc/%.pdf: doc/%.texi
|
||||||
|
texi2pdf --clean -o $@ -q $<
|
||||||
|
|
||||||
|
doc/%.html.pre: doc/%.texi
|
||||||
|
makeinfo --html --no-headers --no-split --number-sections -o $@ $<
|
||||||
|
|
||||||
|
doc/%.html: doc/%.html.pre
|
||||||
|
sed -e 's|</style>|</style>\n<meta name="viewport" content="width=device-width, initial-scale=1.0">|' < $< > $@
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# tests
|
||||||
|
|
||||||
|
ifdef CONFIG_SHARED_LIBS
|
||||||
|
test: tests/bjson.so examples/point.so
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_M32
|
||||||
|
test: qjs32
|
||||||
|
endif
|
||||||
|
|
||||||
|
test: qjs
|
||||||
|
./qjs tests/test_closure.js
|
||||||
|
./qjs tests/test_language.js
|
||||||
|
./qjs --std tests/test_builtin.js
|
||||||
|
./qjs tests/test_loop.js
|
||||||
|
./qjs tests/test_bignum.js
|
||||||
|
./qjs tests/test_std.js
|
||||||
|
./qjs tests/test_worker.js
|
||||||
|
ifdef CONFIG_SHARED_LIBS
|
||||||
|
ifdef CONFIG_BIGNUM
|
||||||
|
./qjs --bignum tests/test_bjson.js
|
||||||
|
else
|
||||||
|
./qjs tests/test_bjson.js
|
||||||
|
endif
|
||||||
|
./qjs examples/test_point.js
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_BIGNUM
|
||||||
|
./qjs --bignum tests/test_op_overloading.js
|
||||||
|
./qjs --bignum tests/test_bigfloat.js
|
||||||
|
./qjs --qjscalc tests/test_qjscalc.js
|
||||||
|
endif
|
||||||
|
ifdef CONFIG_M32
|
||||||
|
./qjs32 tests/test_closure.js
|
||||||
|
./qjs32 tests/test_language.js
|
||||||
|
./qjs32 --std tests/test_builtin.js
|
||||||
|
./qjs32 tests/test_loop.js
|
||||||
|
./qjs32 tests/test_bignum.js
|
||||||
|
./qjs32 tests/test_std.js
|
||||||
|
./qjs32 tests/test_worker.js
|
||||||
|
ifdef CONFIG_BIGNUM
|
||||||
|
./qjs32 --bignum tests/test_op_overloading.js
|
||||||
|
./qjs32 --bignum tests/test_bigfloat.js
|
||||||
|
./qjs32 --qjscalc tests/test_qjscalc.js
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
stats: qjs qjs32
|
||||||
|
./qjs -qd
|
||||||
|
./qjs32 -qd
|
||||||
|
|
||||||
|
microbench: qjs
|
||||||
|
./qjs --std tests/microbench.js
|
||||||
|
|
||||||
|
microbench-32: qjs32
|
||||||
|
./qjs32 --std tests/microbench.js
|
||||||
|
|
||||||
|
ifeq ($(wildcard test262o/tests.txt),)
|
||||||
|
test2o test2o-32 test2o-update:
|
||||||
|
@echo test262o tests not installed
|
||||||
|
else
|
||||||
|
# ES5 tests (obsolete)
|
||||||
|
test2o: run-test262
|
||||||
|
time ./run-test262 -t -m -c test262o.conf
|
||||||
|
|
||||||
|
test2o-32: run-test262-32
|
||||||
|
time ./run-test262-32 -t -m -c test262o.conf
|
||||||
|
|
||||||
|
test2o-update: run-test262
|
||||||
|
./run-test262 -t -u -c test262o.conf
|
||||||
|
endif
|
||||||
|
|
||||||
|
ifeq ($(wildcard test262o/tests.txt),)
|
||||||
|
test2 test2-32 test2-update test2-default test2-check:
|
||||||
|
@echo test262 tests not installed
|
||||||
|
else
|
||||||
|
# Test262 tests
|
||||||
|
test2-default: run-test262
|
||||||
|
time ./run-test262 -t -m -c test262.conf
|
||||||
|
|
||||||
|
test2: run-test262
|
||||||
|
time ./run-test262 -t -m -c test262.conf -a
|
||||||
|
|
||||||
|
test2-32: run-test262-32
|
||||||
|
time ./run-test262-32 -t -m -c test262.conf -a
|
||||||
|
|
||||||
|
test2-update: run-test262
|
||||||
|
./run-test262 -t -u -c test262.conf -a
|
||||||
|
|
||||||
|
test2-check: run-test262
|
||||||
|
time ./run-test262 -t -m -c test262.conf -E -a
|
||||||
|
endif
|
||||||
|
|
||||||
|
testall: all test microbench test2o test2
|
||||||
|
|
||||||
|
testall-32: all test-32 microbench-32 test2o-32 test2-32
|
||||||
|
|
||||||
|
testall-complete: testall testall-32
|
||||||
|
|
||||||
|
node-test:
|
||||||
|
node tests/test_closure.js
|
||||||
|
node tests/test_language.js
|
||||||
|
node tests/test_builtin.js
|
||||||
|
node tests/test_loop.js
|
||||||
|
node tests/test_bignum.js
|
||||||
|
|
||||||
|
node-microbench:
|
||||||
|
node tests/microbench.js -s microbench-node.txt
|
||||||
|
node --jitless tests/microbench.js -s microbench-node-jitless.txt
|
||||||
|
|
||||||
|
bench-v8: qjs
|
||||||
|
make -C tests/bench-v8
|
||||||
|
./qjs -d tests/bench-v8/combined.js
|
||||||
|
|
||||||
|
node-bench-v8:
|
||||||
|
make -C tests/bench-v8
|
||||||
|
node --jitless tests/bench-v8/combined.js
|
||||||
|
|
||||||
|
tests/bjson.so: $(OBJDIR)/tests/bjson.pic.o
|
||||||
|
$(CC) $(LDFLAGS) -shared -o $@ $^ $(LIBS)
|
||||||
|
|
||||||
|
BENCHMARKDIR=../quickjs-benchmarks
|
||||||
|
|
||||||
|
run_sunspider_like: $(BENCHMARKDIR)/run_sunspider_like.c
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -DNO_INCLUDE_DIR -I. -o $@ $< libquickjs$(LTOEXT).a $(LIBS)
|
||||||
|
|
||||||
|
run_octane: $(BENCHMARKDIR)/run_octane.c
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -DNO_INCLUDE_DIR -I. -o $@ $< libquickjs$(LTOEXT).a $(LIBS)
|
||||||
|
|
||||||
|
benchmarks: run_sunspider_like run_octane
|
||||||
|
./run_sunspider_like $(BENCHMARKDIR)/kraken-1.0/
|
||||||
|
./run_sunspider_like $(BENCHMARKDIR)/kraken-1.1/
|
||||||
|
./run_sunspider_like $(BENCHMARKDIR)/sunspider-1.0/
|
||||||
|
./run_octane $(BENCHMARKDIR)/
|
||||||
|
|
||||||
|
-include $(wildcard $(OBJDIR)/*.d)
|
||||||
|
|
25
README.md
25
README.md
|
@ -1,25 +0,0 @@
|
||||||
# ⚡️ QuickJS/DoneJS - A VERY mighty JavaScript engine
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
QuickJS/DoneJS (QuickJS NG DoneJS Edition) is a small and embeddable JavaScript engine. It aims to support the latest
|
|
||||||
[ECMAScript] specification.
|
|
||||||
|
|
||||||
This project is a _fork_ of the [QuickJS NG project] which is a _fork_ of the [original QuickJS project] by Fabrice Bellard and Charlie Gordon, after it went dormant, with the intent of reigniting its development.
|
|
||||||
|
|
||||||
## Getting started
|
|
||||||
|
|
||||||
Head over to the [project website] for instructions on how to get started and more
|
|
||||||
documentation.
|
|
||||||
|
|
||||||
## Authors
|
|
||||||
|
|
||||||
[@bnoordhuis], [@saghul], [@sneedgroup-holder], and many more [contributors].
|
|
||||||
|
|
||||||
[ECMAScript]: https://tc39.es/ecma262/
|
|
||||||
[original QuickJS project]: https://bellard.org/quickjs
|
|
||||||
[@bnoordhuis]: https://github.com/bnoordhuis
|
|
||||||
[@saghul]: https://github.com/saghul
|
|
||||||
[QuickJS NG contributors]: https://github.com/quickjs-ng/quickjs/graphs/contributors
|
|
||||||
[QuickJS NG project]: https://quickjs-ng.github.io/quickjs/
|
|
||||||
[Project Website]: https://donejs-runtime.github.io
|
|
67
TODO
Normal file
67
TODO
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
Misc ideas:
|
||||||
|
- use custom printf to avoid compatibility issues with floating point numbers
|
||||||
|
- consistent naming for preprocessor defines
|
||||||
|
- unify coding style and naming conventions
|
||||||
|
- use names from the ECMA spec in library implementation
|
||||||
|
- use byte code emitters with typed arguments (for clarity)
|
||||||
|
- use 2 bytecode DynBufs in JSFunctionDef, one for reading, one for writing
|
||||||
|
and use the same wrappers in all phases
|
||||||
|
- use more generic method for line numbers in resolve_variables and resolve_labels
|
||||||
|
- use custom timezone support to avoid C library compatibility issues
|
||||||
|
|
||||||
|
Memory:
|
||||||
|
- use memory pools for objects, etc?
|
||||||
|
- test border cases for max number of atoms, object properties, string length
|
||||||
|
- add emergency malloc mode for out of memory exceptions.
|
||||||
|
- test all DynBuf memory errors
|
||||||
|
- test all js_realloc memory errors
|
||||||
|
- improve JS_ComputeMemoryUsage() with more info
|
||||||
|
|
||||||
|
Built-in standard library:
|
||||||
|
- BSD sockets
|
||||||
|
- modules: use realpath in module name normalizer and put it in quickjs-libc
|
||||||
|
- modules: if no ".", use a well known module loading path ?
|
||||||
|
- get rid of __loadScript, use more common name
|
||||||
|
|
||||||
|
REPL:
|
||||||
|
- debugger
|
||||||
|
- readline: support MS Windows terminal
|
||||||
|
- readline: handle dynamic terminal resizing
|
||||||
|
- readline: handle double width unicode characters
|
||||||
|
- multiline editing
|
||||||
|
- runtime object and function inspectors
|
||||||
|
- interactive object browser
|
||||||
|
- use more generic approach to display evaluation results
|
||||||
|
- improve directive handling: dispatch, colorize, completion...
|
||||||
|
- save history
|
||||||
|
- close all predefined methods in repl.js and jscalc.js
|
||||||
|
|
||||||
|
Optimization ideas:
|
||||||
|
- 64-bit atoms in 64-bit mode ?
|
||||||
|
- 64-bit small bigint in 64-bit mode ?
|
||||||
|
- reuse stack slots for disjoint scopes, if strip
|
||||||
|
- add heuristic to avoid some cycles in closures
|
||||||
|
- small String (0-2 charcodes) with immediate storage
|
||||||
|
- perform static string concatenation at compile time
|
||||||
|
- optimize string concatenation with ropes or miniropes?
|
||||||
|
- add implicit numeric strings for Uint32 numbers?
|
||||||
|
- optimize `s += a + b`, `s += a.b` and similar simple expressions
|
||||||
|
- ensure string canonical representation and optimise comparisons and hashes?
|
||||||
|
- remove JSObject.first_weak_ref, use bit+context based hashed array for weak references
|
||||||
|
- property access optimization on the global object, functions,
|
||||||
|
prototypes and special non extensible objects.
|
||||||
|
- create object literals with the correct length by backpatching length argument
|
||||||
|
- remove redundant set_loc_uninitialized/check_uninitialized opcodes
|
||||||
|
- peephole optim: push_atom_value, to_propkey -> push_atom_value
|
||||||
|
- peephole optim: put_loc x, get_loc_check x -> set_loc x
|
||||||
|
- convert slow array to fast array when all properties != length are numeric
|
||||||
|
- optimize destructuring assignments for global and local variables
|
||||||
|
- implement some form of tail-call-optimization
|
||||||
|
- optimize OP_apply
|
||||||
|
- optimize f(...b)
|
||||||
|
|
||||||
|
Test262o: 0/11262 errors, 463 excluded
|
||||||
|
Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
|
||||||
|
|
||||||
|
Result: 8/76947 errors, 1497 excluded, 8117 skipped
|
||||||
|
Test262 commit: 6cbb6da9473c56d95358d8e679c5a6d2b4574efb
|
1
VERSION
Normal file
1
VERSION
Normal file
|
@ -0,0 +1 @@
|
||||||
|
2024-02-14
|
6
compat/test-closefrom.c
Normal file
6
compat/test-closefrom.c
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
closefrom(3);
|
||||||
|
return 0;
|
||||||
|
}
|
17
ctest.c
17
ctest.c
|
@ -1,17 +0,0 @@
|
||||||
// note: file is not actually compiled, only checked for C syntax errors
|
|
||||||
#include "quickjs.h"
|
|
||||||
|
|
||||||
int main(void)
|
|
||||||
{
|
|
||||||
JSRuntime *rt = JS_NewRuntime();
|
|
||||||
JSContext *ctx = JS_NewContext(rt);
|
|
||||||
JS_FreeValue(ctx, JS_NAN);
|
|
||||||
JS_FreeValue(ctx, JS_UNDEFINED);
|
|
||||||
JS_FreeValue(ctx, JS_NewFloat64(ctx, 42));
|
|
||||||
// not a legal way of using JS_MKPTR but this is here
|
|
||||||
// to have the compiler syntax-check its definition
|
|
||||||
JS_FreeValue(ctx, JS_MKPTR(JS_TAG_UNINITIALIZED, 0));
|
|
||||||
JS_FreeContext(ctx);
|
|
||||||
JS_FreeRuntime(rt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
353
cutils.h
353
cutils.h
|
@ -28,88 +28,33 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <math.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#define likely(x) __builtin_expect(!!(x), 1)
|
||||||
extern "C" {
|
#define unlikely(x) __builtin_expect(!!(x), 0)
|
||||||
#endif
|
#define force_inline inline __attribute__((always_inline))
|
||||||
|
#define no_inline __attribute__((noinline))
|
||||||
|
#define __maybe_unused __attribute__((unused))
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#define xglue(x, y) x ## y
|
||||||
#include <winsock2.h>
|
#define glue(x, y) xglue(x, y)
|
||||||
#include <malloc.h>
|
#define stringify(s) tostring(s)
|
||||||
#define alloca _alloca
|
#define tostring(s) #s
|
||||||
#define ssize_t ptrdiff_t
|
|
||||||
#endif
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
#include <malloc/malloc.h>
|
|
||||||
#elif defined(__linux__) || defined(__ANDROID__) || defined(__CYGWIN__)
|
|
||||||
#include <malloc.h>
|
|
||||||
#elif defined(__FreeBSD__)
|
|
||||||
#include <malloc_np.h>
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
#include <windows.h>
|
|
||||||
#endif
|
|
||||||
#if !defined(_WIN32) && !defined(EMSCRIPTEN) && !defined(__wasi__)
|
|
||||||
#include <errno.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
|
||||||
# define likely(x) (x)
|
|
||||||
# define unlikely(x) (x)
|
|
||||||
# define force_inline __forceinline
|
|
||||||
# define no_inline __declspec(noinline)
|
|
||||||
# define __maybe_unused
|
|
||||||
# define __attribute__(x)
|
|
||||||
# define __attribute(x)
|
|
||||||
#else
|
|
||||||
# define likely(x) __builtin_expect(!!(x), 1)
|
|
||||||
# define unlikely(x) __builtin_expect(!!(x), 0)
|
|
||||||
# define force_inline inline __attribute__((always_inline))
|
|
||||||
# define no_inline __attribute__((noinline))
|
|
||||||
# define __maybe_unused __attribute__((unused))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// https://stackoverflow.com/a/6849629
|
|
||||||
#undef FORMAT_STRING
|
|
||||||
#if _MSC_VER >= 1400
|
|
||||||
# include <sal.h>
|
|
||||||
# if _MSC_VER > 1400
|
|
||||||
# define FORMAT_STRING(p) _Printf_format_string_ p
|
|
||||||
# else
|
|
||||||
# define FORMAT_STRING(p) __format_string p
|
|
||||||
# endif /* FORMAT_STRING */
|
|
||||||
#else
|
|
||||||
# define FORMAT_STRING(p) p
|
|
||||||
#endif /* _MSC_VER */
|
|
||||||
|
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
|
||||||
#include <math.h>
|
|
||||||
#define INF INFINITY
|
|
||||||
#define NEG_INF -INFINITY
|
|
||||||
#else
|
|
||||||
#define INF (1.0/0.0)
|
|
||||||
#define NEG_INF (-1.0/0.0)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef offsetof
|
#ifndef offsetof
|
||||||
#define offsetof(type, field) ((size_t) &((type *)0)->field)
|
#define offsetof(type, field) ((size_t) &((type *)0)->field)
|
||||||
#endif
|
#endif
|
||||||
#ifndef countof
|
#ifndef countof
|
||||||
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
#ifndef endof
|
|
||||||
#define endof(x) ((x) + countof(x))
|
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
#ifndef container_of
|
#ifndef container_of
|
||||||
/* return the pointer of type 'type *' containing 'ptr' as field 'member' */
|
/* return the pointer of type 'type *' containing 'ptr' as field 'member' */
|
||||||
#define container_of(ptr, type, member) ((type *)((uint8_t *)(ptr) - offsetof(type, member)))
|
#define container_of(ptr, type, member) ((type *)((uint8_t *)(ptr) - offsetof(type, member)))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if !defined(_MSC_VER) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
|
||||||
#define minimum_length(n) n
|
#define minimum_length(n) static n
|
||||||
#else
|
#else
|
||||||
#define minimum_length(n) static n
|
#define minimum_length(n) n
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef int BOOL;
|
typedef int BOOL;
|
||||||
|
@ -121,17 +66,15 @@ enum {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void js__pstrcpy(char *buf, int buf_size, const char *str);
|
void pstrcpy(char *buf, int buf_size, const char *str);
|
||||||
char *js__pstrcat(char *buf, int buf_size, const char *s);
|
char *pstrcat(char *buf, int buf_size, const char *s);
|
||||||
int js__strstart(const char *str, const char *val, const char **ptr);
|
int strstart(const char *str, const char *val, const char **ptr);
|
||||||
int js__has_suffix(const char *str, const char *suffix);
|
int has_suffix(const char *str, const char *suffix);
|
||||||
|
|
||||||
static inline uint8_t is_be(void) {
|
/* Prevent UB when n == 0 and (src == NULL or dest == NULL) */
|
||||||
union {
|
static inline void memcpy_no_ub(void *dest, const void *src, size_t n) {
|
||||||
uint16_t a;
|
if (n)
|
||||||
uint8_t b;
|
memcpy(dest, src, n);
|
||||||
} u = { 0x100 };
|
|
||||||
return u.b;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int max_int(int a, int b)
|
static inline int max_int(int a, int b)
|
||||||
|
@ -185,113 +128,82 @@ static inline int64_t min_int64(int64_t a, int64_t b)
|
||||||
/* WARNING: undefined if a = 0 */
|
/* WARNING: undefined if a = 0 */
|
||||||
static inline int clz32(unsigned int a)
|
static inline int clz32(unsigned int a)
|
||||||
{
|
{
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
|
||||||
unsigned long index;
|
|
||||||
_BitScanReverse(&index, a);
|
|
||||||
return 31 - index;
|
|
||||||
#else
|
|
||||||
return __builtin_clz(a);
|
return __builtin_clz(a);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WARNING: undefined if a = 0 */
|
/* WARNING: undefined if a = 0 */
|
||||||
static inline int clz64(uint64_t 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);
|
return __builtin_clzll(a);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WARNING: undefined if a = 0 */
|
/* WARNING: undefined if a = 0 */
|
||||||
static inline int ctz32(unsigned int a)
|
static inline int ctz32(unsigned int a)
|
||||||
{
|
{
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
|
||||||
unsigned long index;
|
|
||||||
_BitScanForward(&index, a);
|
|
||||||
return index;
|
|
||||||
#else
|
|
||||||
return __builtin_ctz(a);
|
return __builtin_ctz(a);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* WARNING: undefined if a = 0 */
|
/* WARNING: undefined if a = 0 */
|
||||||
static inline int ctz64(uint64_t a)
|
static inline int ctz64(uint64_t a)
|
||||||
{
|
{
|
||||||
#if defined(_MSC_VER) && !defined(__clang__)
|
|
||||||
unsigned long index;
|
|
||||||
_BitScanForward64(&index, a);
|
|
||||||
return index;
|
|
||||||
#else
|
|
||||||
return __builtin_ctzll(a);
|
return __builtin_ctzll(a);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct __attribute__((packed)) packed_u64 {
|
||||||
|
uint64_t v;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed)) packed_u32 {
|
||||||
|
uint32_t v;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct __attribute__((packed)) packed_u16 {
|
||||||
|
uint16_t v;
|
||||||
|
};
|
||||||
|
|
||||||
static inline uint64_t get_u64(const uint8_t *tab)
|
static inline uint64_t get_u64(const uint8_t *tab)
|
||||||
{
|
{
|
||||||
uint64_t v;
|
return ((const struct packed_u64 *)tab)->v;
|
||||||
memcpy(&v, tab, sizeof(v));
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int64_t get_i64(const uint8_t *tab)
|
static inline int64_t get_i64(const uint8_t *tab)
|
||||||
{
|
{
|
||||||
int64_t v;
|
return (int64_t)((const struct packed_u64 *)tab)->v;
|
||||||
memcpy(&v, tab, sizeof(v));
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void put_u64(uint8_t *tab, uint64_t val)
|
static inline void put_u64(uint8_t *tab, uint64_t val)
|
||||||
{
|
{
|
||||||
memcpy(tab, &val, sizeof(val));
|
((struct packed_u64 *)tab)->v = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t get_u32(const uint8_t *tab)
|
static inline uint32_t get_u32(const uint8_t *tab)
|
||||||
{
|
{
|
||||||
uint32_t v;
|
return ((const struct packed_u32 *)tab)->v;
|
||||||
memcpy(&v, tab, sizeof(v));
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int32_t get_i32(const uint8_t *tab)
|
static inline int32_t get_i32(const uint8_t *tab)
|
||||||
{
|
{
|
||||||
int32_t v;
|
return (int32_t)((const struct packed_u32 *)tab)->v;
|
||||||
memcpy(&v, tab, sizeof(v));
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void put_u32(uint8_t *tab, uint32_t val)
|
static inline void put_u32(uint8_t *tab, uint32_t val)
|
||||||
{
|
{
|
||||||
memcpy(tab, &val, sizeof(val));
|
((struct packed_u32 *)tab)->v = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t get_u16(const uint8_t *tab)
|
static inline uint32_t get_u16(const uint8_t *tab)
|
||||||
{
|
{
|
||||||
uint16_t v;
|
return ((const struct packed_u16 *)tab)->v;
|
||||||
memcpy(&v, tab, sizeof(v));
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int32_t get_i16(const uint8_t *tab)
|
static inline int32_t get_i16(const uint8_t *tab)
|
||||||
{
|
{
|
||||||
int16_t v;
|
return (int16_t)((const struct packed_u16 *)tab)->v;
|
||||||
memcpy(&v, tab, sizeof(v));
|
|
||||||
return v;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void put_u16(uint8_t *tab, uint16_t val)
|
static inline void put_u16(uint8_t *tab, uint16_t val)
|
||||||
{
|
{
|
||||||
memcpy(tab, &val, sizeof(val));
|
((struct packed_u16 *)tab)->v = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t get_u8(const uint8_t *tab)
|
static inline uint32_t get_u8(const uint8_t *tab)
|
||||||
|
@ -338,89 +250,6 @@ static inline uint64_t bswap64(uint64_t v)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static inline void inplace_bswap16(uint8_t *tab) {
|
|
||||||
put_u16(tab, bswap16(get_u16(tab)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void inplace_bswap32(uint8_t *tab) {
|
|
||||||
put_u32(tab, bswap32(get_u32(tab)));
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline double fromfp16(uint16_t v) {
|
|
||||||
double d, s;
|
|
||||||
int e;
|
|
||||||
if ((v & 0x7C00) == 0x7C00) {
|
|
||||||
d = (v & 0x3FF) ? NAN : INFINITY;
|
|
||||||
} else {
|
|
||||||
d = (v & 0x3FF) / 1024.;
|
|
||||||
e = (v & 0x7C00) >> 10;
|
|
||||||
if (e == 0) {
|
|
||||||
e = -14;
|
|
||||||
} else {
|
|
||||||
d += 1;
|
|
||||||
e -= 15;
|
|
||||||
}
|
|
||||||
d = scalbn(d, e);
|
|
||||||
}
|
|
||||||
s = (v & 0x8000) ? -1.0 : 1.0;
|
|
||||||
return d * s;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t tofp16(double d) {
|
|
||||||
uint16_t f, s;
|
|
||||||
double t;
|
|
||||||
int e;
|
|
||||||
s = 0;
|
|
||||||
if (copysign(1, d) < 0) { // preserve sign when |d| is negative zero
|
|
||||||
d = -d;
|
|
||||||
s = 0x8000;
|
|
||||||
}
|
|
||||||
if (isinf(d))
|
|
||||||
return s | 0x7C00;
|
|
||||||
if (isnan(d))
|
|
||||||
return s | 0x7C01;
|
|
||||||
if (d == 0)
|
|
||||||
return s | 0;
|
|
||||||
d = 2 * frexp(d, &e);
|
|
||||||
e--;
|
|
||||||
if (e > 15)
|
|
||||||
return s | 0x7C00; // out of range, return +/-infinity
|
|
||||||
if (e < -25) {
|
|
||||||
d = 0;
|
|
||||||
e = 0;
|
|
||||||
} else if (e < -14) {
|
|
||||||
d = scalbn(d, e + 14);
|
|
||||||
e = 0;
|
|
||||||
} else {
|
|
||||||
d -= 1;
|
|
||||||
e += 15;
|
|
||||||
}
|
|
||||||
d *= 1024.;
|
|
||||||
f = (uint16_t)d;
|
|
||||||
t = d - f;
|
|
||||||
if (t < 0.5)
|
|
||||||
goto done;
|
|
||||||
if (t == 0.5)
|
|
||||||
if ((f & 1) == 0)
|
|
||||||
goto done;
|
|
||||||
// adjust for rounding
|
|
||||||
if (++f == 1024) {
|
|
||||||
f = 0;
|
|
||||||
if (++e == 31)
|
|
||||||
return s | 0x7C00; // out of range, return +/-infinity
|
|
||||||
}
|
|
||||||
done:
|
|
||||||
return s | (e << 10) | f;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int isfp16nan(uint16_t v) {
|
|
||||||
return (v & 0x7FFF) > 0x7C00;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int isfp16zero(uint16_t v) {
|
|
||||||
return (v & 0x7FFF) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XXX: should take an extra argument to pass slack information to the caller */
|
/* XXX: should take an extra argument to pass slack information to the caller */
|
||||||
typedef void *DynBufReallocFunc(void *opaque, void *ptr, size_t size);
|
typedef void *DynBufReallocFunc(void *opaque, void *ptr, size_t size);
|
||||||
|
|
||||||
|
@ -436,8 +265,8 @@ typedef struct DynBuf {
|
||||||
void dbuf_init(DynBuf *s);
|
void dbuf_init(DynBuf *s);
|
||||||
void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func);
|
void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func);
|
||||||
int dbuf_realloc(DynBuf *s, size_t new_size);
|
int dbuf_realloc(DynBuf *s, size_t new_size);
|
||||||
int dbuf_write(DynBuf *s, size_t offset, const void *data, size_t len);
|
int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len);
|
||||||
int dbuf_put(DynBuf *s, const void *data, size_t len);
|
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len);
|
||||||
int dbuf_put_self(DynBuf *s, size_t offset, size_t len);
|
int dbuf_put_self(DynBuf *s, size_t offset, size_t len);
|
||||||
int dbuf_putc(DynBuf *s, uint8_t c);
|
int dbuf_putc(DynBuf *s, uint8_t c);
|
||||||
int dbuf_putstr(DynBuf *s, const char *str);
|
int dbuf_putstr(DynBuf *s, const char *str);
|
||||||
|
@ -454,7 +283,7 @@ static inline int dbuf_put_u64(DynBuf *s, uint64_t val)
|
||||||
return dbuf_put(s, (uint8_t *)&val, 8);
|
return dbuf_put(s, (uint8_t *)&val, 8);
|
||||||
}
|
}
|
||||||
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
|
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
|
||||||
FORMAT_STRING(const char *fmt), ...);
|
const char *fmt, ...);
|
||||||
void dbuf_free(DynBuf *s);
|
void dbuf_free(DynBuf *s);
|
||||||
static inline BOOL dbuf_error(DynBuf *s) {
|
static inline BOOL dbuf_error(DynBuf *s) {
|
||||||
return s->error;
|
return s->error;
|
||||||
|
@ -464,26 +293,10 @@ static inline void dbuf_set_error(DynBuf *s)
|
||||||
s->error = TRUE;
|
s->error = TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---- UTF-8 and UTF-16 handling ----*/
|
#define UTF8_CHAR_LEN_MAX 6
|
||||||
|
|
||||||
#define UTF8_CHAR_LEN_MAX 4
|
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);
|
||||||
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[minimum_length(UTF8_CHAR_LEN_MAX)], 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)
|
static inline BOOL is_surrogate(uint32_t c)
|
||||||
{
|
{
|
||||||
|
@ -512,7 +325,7 @@ static inline uint32_t get_lo_surrogate(uint32_t c)
|
||||||
|
|
||||||
static inline uint32_t from_surrogate(uint32_t hi, uint32_t lo)
|
static inline uint32_t from_surrogate(uint32_t hi, uint32_t lo)
|
||||||
{
|
{
|
||||||
return 65536 + 1024 * (hi & 1023) + (lo & 1023);
|
return 0x10000 + 0x400 * (hi - 0xD800) + (lo - 0xDC00);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int from_hex(int c)
|
static inline int from_hex(int c)
|
||||||
|
@ -527,78 +340,8 @@ static inline int from_hex(int c)
|
||||||
return -1;
|
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,
|
void rqsort(void *base, size_t nmemb, size_t size,
|
||||||
int (*cmp)(const void *, const void *, void *),
|
int (*cmp)(const void *, const void *, void *),
|
||||||
void *arg);
|
void *arg);
|
||||||
|
|
||||||
int64_t js__gettimeofday_us(void);
|
|
||||||
uint64_t js__hrtime_ns(void);
|
|
||||||
|
|
||||||
static inline size_t js__malloc_usable_size(const void *ptr)
|
|
||||||
{
|
|
||||||
#if defined(__APPLE__)
|
|
||||||
return malloc_size(ptr);
|
|
||||||
#elif defined(_WIN32)
|
|
||||||
return _msize((void *)ptr);
|
|
||||||
#elif defined(__linux__) || defined(__ANDROID__) || defined(__CYGWIN__) || defined(__FreeBSD__)
|
|
||||||
return malloc_usable_size((void *)ptr);
|
|
||||||
#else
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Cross-platform threading APIs. */
|
|
||||||
|
|
||||||
#if !defined(EMSCRIPTEN) && !defined(__wasi__)
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
#define JS_ONCE_INIT INIT_ONCE_STATIC_INIT
|
|
||||||
typedef INIT_ONCE js_once_t;
|
|
||||||
typedef CRITICAL_SECTION js_mutex_t;
|
|
||||||
typedef CONDITION_VARIABLE js_cond_t;
|
|
||||||
#else
|
|
||||||
#define JS_ONCE_INIT PTHREAD_ONCE_INIT
|
|
||||||
typedef pthread_once_t js_once_t;
|
|
||||||
typedef pthread_mutex_t js_mutex_t;
|
|
||||||
typedef pthread_cond_t js_cond_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void js_once(js_once_t *guard, void (*callback)(void));
|
|
||||||
|
|
||||||
void js_mutex_init(js_mutex_t *mutex);
|
|
||||||
void js_mutex_destroy(js_mutex_t *mutex);
|
|
||||||
void js_mutex_lock(js_mutex_t *mutex);
|
|
||||||
void js_mutex_unlock(js_mutex_t *mutex);
|
|
||||||
|
|
||||||
void js_cond_init(js_cond_t *cond);
|
|
||||||
void js_cond_destroy(js_cond_t *cond);
|
|
||||||
void js_cond_signal(js_cond_t *cond);
|
|
||||||
void js_cond_broadcast(js_cond_t *cond);
|
|
||||||
void js_cond_wait(js_cond_t *cond, js_mutex_t *mutex);
|
|
||||||
int js_cond_timedwait(js_cond_t *cond, js_mutex_t *mutex, uint64_t timeout);
|
|
||||||
|
|
||||||
#endif /* !defined(EMSCRIPTEN) && !defined(__wasi__) */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" { */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* CUTILS_H */
|
#endif /* CUTILS_H */
|
||||||
|
|
|
@ -1,2 +0,0 @@
|
||||||
// note: file is not actually compiled, only checked for C++ syntax errors
|
|
||||||
#include "ctest.c"
|
|
1166
dirent_compat.h
1166
dirent_compat.h
File diff suppressed because it is too large
Load diff
589
doc/jsbignum.texi
Normal file
589
doc/jsbignum.texi
Normal file
|
@ -0,0 +1,589 @@
|
||||||
|
\input texinfo
|
||||||
|
|
||||||
|
@iftex
|
||||||
|
@afourpaper
|
||||||
|
@headings double
|
||||||
|
@end iftex
|
||||||
|
|
||||||
|
@titlepage
|
||||||
|
@afourpaper
|
||||||
|
@sp 7
|
||||||
|
@center @titlefont{Javascript Bignum Extensions}
|
||||||
|
@sp 3
|
||||||
|
@center Version 2020-01-11
|
||||||
|
@sp 3
|
||||||
|
@center Author: Fabrice Bellard
|
||||||
|
@end titlepage
|
||||||
|
|
||||||
|
@setfilename jsbignum.info
|
||||||
|
@settitle Javascript Bignum Extensions
|
||||||
|
|
||||||
|
@contents
|
||||||
|
|
||||||
|
@chapter Introduction
|
||||||
|
|
||||||
|
The Bignum extensions add the following features to the Javascript
|
||||||
|
language while being 100% backward compatible:
|
||||||
|
|
||||||
|
@itemize
|
||||||
|
|
||||||
|
@item Operator overloading with a dispatch logic inspired from the proposal available at @url{https://github.com/tc39/proposal-operator-overloading/}.
|
||||||
|
|
||||||
|
@item Arbitrarily large floating point numbers (@code{BigFloat}) in base 2 using the IEEE 754 semantics.
|
||||||
|
|
||||||
|
@item Arbitrarily large floating point numbers (@code{BigDecimal}) in base 10 based on the proposal available at
|
||||||
|
@url{https://github.com/littledan/proposal-bigdecimal}.
|
||||||
|
|
||||||
|
@item @code{math} mode: arbitrarily large integers and floating point numbers are available by default. The integer division and power can be overloaded for example to return a fraction. The modulo operator (@code{%}) is defined as the Euclidian
|
||||||
|
remainder. @code{^} is an alias to the power operator
|
||||||
|
(@code{**}). @code{^^} is used as the exclusive or operator.
|
||||||
|
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
The extensions are independent from each other except the @code{math}
|
||||||
|
mode which relies on BigFloat and operator overloading.
|
||||||
|
|
||||||
|
@chapter Operator overloading
|
||||||
|
|
||||||
|
Operator overloading is inspired from the proposal available at
|
||||||
|
@url{https://github.com/tc39/proposal-operator-overloading/}. It
|
||||||
|
implements the same dispatch logic but finds the operator sets by
|
||||||
|
looking at the @code{Symbol.operatorSet} property in the objects. The
|
||||||
|
changes were done in order to simplify the implementation.
|
||||||
|
|
||||||
|
More precisely, the following modifications were made:
|
||||||
|
|
||||||
|
@itemize
|
||||||
|
|
||||||
|
@item @code{with operators from} is not supported. Operator overloading is always enabled.
|
||||||
|
|
||||||
|
@item The dispatch is not based on a static @code{[[OperatorSet]]} field in all instances. Instead, a dynamic lookup of the @code{Symbol.operatorSet} property is done. This property is typically added in the prototype of each object.
|
||||||
|
|
||||||
|
@item @code{Operators.create(...dictionaries)} is used to create a new OperatorSet object. The @code{Operators} function is supported as an helper to be closer to the TC39 proposal.
|
||||||
|
|
||||||
|
@item @code{[]} cannot be overloaded.
|
||||||
|
|
||||||
|
@item In math mode, the BigInt division and power operators can be overloaded with @code{Operators.updateBigIntOperators(dictionary)}.
|
||||||
|
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@chapter BigInt extensions
|
||||||
|
|
||||||
|
A few properties are added to the BigInt object:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item tdiv(a, b)
|
||||||
|
Return @math{trunc(a/b)}. @code{b = 0} raises a RangeError
|
||||||
|
exception.
|
||||||
|
|
||||||
|
@item fdiv(a, b)
|
||||||
|
Return @math{\lfloor a/b \rfloor}. @code{b = 0} raises a RangeError
|
||||||
|
exception.
|
||||||
|
|
||||||
|
@item cdiv(a, b)
|
||||||
|
Return @math{\lceil a/b \rceil}. @code{b = 0} raises a RangeError
|
||||||
|
exception.
|
||||||
|
|
||||||
|
@item ediv(a, b)
|
||||||
|
Return @math{sgn(b) \lfloor a/{|b|} \rfloor} (Euclidian
|
||||||
|
division). @code{b = 0} raises a RangeError exception.
|
||||||
|
|
||||||
|
@item tdivrem(a, b)
|
||||||
|
@item fdivrem(a, b)
|
||||||
|
@item cdivrem(a, b)
|
||||||
|
@item edivrem(a, b)
|
||||||
|
Return an array of two elements. The first element is the quotient,
|
||||||
|
the second is the remainder. The same rounding is done as the
|
||||||
|
corresponding division operation.
|
||||||
|
|
||||||
|
@item sqrt(a)
|
||||||
|
Return @math{\lfloor \sqrt(a) \rfloor}. A RangeError exception is
|
||||||
|
raised if @math{a < 0}.
|
||||||
|
|
||||||
|
@item sqrtrem(a)
|
||||||
|
Return an array of two elements. The first element is @math{\lfloor
|
||||||
|
\sqrt{a} \rfloor}. The second element is @math{a-\lfloor \sqrt{a}
|
||||||
|
\rfloor^2}. A RangeError exception is raised if @math{a < 0}.
|
||||||
|
|
||||||
|
@item floorLog2(a)
|
||||||
|
Return -1 if @math{a \leq 0} otherwise return @math{\lfloor \log2(a) \rfloor}.
|
||||||
|
|
||||||
|
@item ctz(a)
|
||||||
|
Return the number of trailing zeros in the two's complement binary representation of a. Return -1 if @math{a=0}.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@chapter BigFloat
|
||||||
|
|
||||||
|
@section Introduction
|
||||||
|
|
||||||
|
This extension adds the @code{BigFloat} primitive type. The
|
||||||
|
@code{BigFloat} type represents floating point numbers in base 2
|
||||||
|
with the IEEE 754 semantics. A floating
|
||||||
|
point number is represented as a sign, mantissa and exponent. The
|
||||||
|
special values @code{NaN}, @code{+/-Infinity}, @code{+0} and @code{-0}
|
||||||
|
are supported. The mantissa and exponent can have any bit length with
|
||||||
|
an implementation specific minimum and maximum.
|
||||||
|
|
||||||
|
@section Floating point rounding
|
||||||
|
|
||||||
|
Each floating point operation operates with infinite precision and
|
||||||
|
then rounds the result according to the specified floating point
|
||||||
|
environment (@code{BigFloatEnv} object). The status flags of the
|
||||||
|
environment are also set according to the result of the operation.
|
||||||
|
|
||||||
|
If no floating point environment is provided, the global floating
|
||||||
|
point environment is used.
|
||||||
|
|
||||||
|
The rounding mode of the global floating point environment is always
|
||||||
|
@code{RNDN} (``round to nearest with ties to even'')@footnote{The
|
||||||
|
rationale is that the rounding mode changes must always be
|
||||||
|
explicit.}. The status flags of the global environment cannot be
|
||||||
|
read@footnote{The rationale is to avoid side effects for the built-in
|
||||||
|
operators.}. The precision of the global environment is
|
||||||
|
@code{BigFloatEnv.prec}. The number of exponent bits of the global
|
||||||
|
environment is @code{BigFloatEnv.expBits}. The global environment
|
||||||
|
subnormal flag is set to @code{true}.
|
||||||
|
|
||||||
|
For example, @code{prec = 53} and @code{ expBits = 11} exactly give
|
||||||
|
the same precision as the IEEE 754 64 bit floating point format. The
|
||||||
|
default precision is @code{prec = 113} and @code{ expBits = 15} (IEEE
|
||||||
|
754 128 bit floating point format).
|
||||||
|
|
||||||
|
The global floating point environment can only be modified temporarily
|
||||||
|
when calling a function (see @code{BigFloatEnv.setPrec}). Hence a
|
||||||
|
function can change the global floating point environment for its
|
||||||
|
callees but not for its caller.
|
||||||
|
|
||||||
|
@section Operators
|
||||||
|
|
||||||
|
The builtin operators are extended so that a BigFloat is returned if
|
||||||
|
at least one operand is a BigFloat. The computations are always done
|
||||||
|
with infinite precision and rounded according to the global floating
|
||||||
|
point environment.
|
||||||
|
|
||||||
|
@code{typeof} applied on a @code{BigFloat} returns @code{bigfloat}.
|
||||||
|
|
||||||
|
BigFloat can be compared with all the other numeric types and the
|
||||||
|
result follows the expected mathematical relations.
|
||||||
|
|
||||||
|
However, since BigFloat and Number are different types they are never
|
||||||
|
equal when using the strict comparison operators (e.g. @code{0.0 ===
|
||||||
|
0.0l} is false).
|
||||||
|
|
||||||
|
@section BigFloat literals
|
||||||
|
|
||||||
|
BigFloat literals are floating point numbers with a trailing @code{l}
|
||||||
|
suffix. BigFloat literals have an infinite precision. They are rounded
|
||||||
|
according to the global floating point environment when they are
|
||||||
|
evaluated.@footnote{Base 10 floating point literals cannot usually be
|
||||||
|
exactly represented as base 2 floating point number. In order to
|
||||||
|
ensure that the literal is represented accurately with the current
|
||||||
|
precision, it must be evaluated at runtime.}
|
||||||
|
|
||||||
|
@section Builtin Object changes
|
||||||
|
|
||||||
|
@subsection @code{BigFloat} function
|
||||||
|
|
||||||
|
The @code{BigFloat} function cannot be invoked as a constructor. When
|
||||||
|
invoked as a function: the parameter is converted to a primitive
|
||||||
|
type. If the result is a numeric type, it is converted to BigFloat
|
||||||
|
without rounding. If the result is a string, it is converted to
|
||||||
|
BigFloat using the precision of the global floating point environment.
|
||||||
|
|
||||||
|
@code{BigFloat} properties:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item LN2
|
||||||
|
@item PI
|
||||||
|
Getter. Return the value of the corresponding mathematical constant
|
||||||
|
rounded to nearest, ties to even with the current global
|
||||||
|
precision. The constant values are cached for small precisions.
|
||||||
|
|
||||||
|
@item MIN_VALUE
|
||||||
|
@item MAX_VALUE
|
||||||
|
@item EPSILON
|
||||||
|
Getter. Return the minimum, maximum and epsilon @code{BigFloat} values
|
||||||
|
(same definition as the corresponding @code{Number} constants).
|
||||||
|
|
||||||
|
@item fpRound(a[, e])
|
||||||
|
Round the floating point number @code{a} according to the floating
|
||||||
|
point environment @code{e} or the global environment if @code{e} is
|
||||||
|
undefined.
|
||||||
|
|
||||||
|
@item parseFloat(a[, radix[, e]])
|
||||||
|
Parse the string @code{a} as a floating point number in radix
|
||||||
|
@code{radix}. The radix is 0 (default) or from 2 to 36. The radix 0
|
||||||
|
means radix 10 unless there is a hexadecimal or binary prefix. The
|
||||||
|
result is rounded according to the floating point environment @code{e}
|
||||||
|
or the global environment if @code{e} is undefined.
|
||||||
|
|
||||||
|
@item isFinite(a)
|
||||||
|
Return true if @code{a} is a finite bigfloat.
|
||||||
|
|
||||||
|
@item isNaN(a)
|
||||||
|
Return true if @code{a} is a NaN bigfloat.
|
||||||
|
|
||||||
|
@item add(a, b[, e])
|
||||||
|
@item sub(a, b[, e])
|
||||||
|
@item mul(a, b[, e])
|
||||||
|
@item div(a, b[, e])
|
||||||
|
Perform the specified floating point operation and round the floating
|
||||||
|
point number @code{a} according to the floating point environment
|
||||||
|
@code{e} or the global environment if @code{e} is undefined. If
|
||||||
|
@code{e} is specified, the floating point status flags are updated.
|
||||||
|
|
||||||
|
@item floor(x)
|
||||||
|
@item ceil(x)
|
||||||
|
@item round(x)
|
||||||
|
@item trunc(x)
|
||||||
|
Round to an integer. No additional rounding is performed.
|
||||||
|
|
||||||
|
@item abs(x)
|
||||||
|
Return the absolute value of x. No additional rounding is performed.
|
||||||
|
|
||||||
|
@item fmod(x, y[, e])
|
||||||
|
@item remainder(x, y[, e])
|
||||||
|
Floating point remainder. The quotient is truncated to zero (fmod) or
|
||||||
|
to the nearest integer with ties to even (remainder). @code{e} is an
|
||||||
|
optional floating point environment.
|
||||||
|
|
||||||
|
@item sqrt(x[, e])
|
||||||
|
Square root. Return a rounded floating point number. @code{e} is an
|
||||||
|
optional floating point environment.
|
||||||
|
|
||||||
|
@item sin(x[, e])
|
||||||
|
@item cos(x[, e])
|
||||||
|
@item tan(x[, e])
|
||||||
|
@item asin(x[, e])
|
||||||
|
@item acos(x[, e])
|
||||||
|
@item atan(x[, e])
|
||||||
|
@item atan2(x, y[, e])
|
||||||
|
@item exp(x[, e])
|
||||||
|
@item log(x[, e])
|
||||||
|
@item pow(x, y[, e])
|
||||||
|
Transcendental operations. Return a rounded floating point
|
||||||
|
number. @code{e} is an optional floating point environment.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@subsection @code{BigFloat.prototype}
|
||||||
|
|
||||||
|
The following properties are modified:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item valueOf()
|
||||||
|
Return the bigfloat primitive value corresponding to @code{this}.
|
||||||
|
|
||||||
|
@item toString(radix)
|
||||||
|
|
||||||
|
For floating point numbers:
|
||||||
|
|
||||||
|
@itemize
|
||||||
|
@item
|
||||||
|
If the radix is a power of two, the conversion is done with infinite
|
||||||
|
precision.
|
||||||
|
@item
|
||||||
|
Otherwise, the number is rounded to nearest with ties to even using
|
||||||
|
the global precision. It is then converted to string using the minimum
|
||||||
|
number of digits so that its conversion back to a floating point using
|
||||||
|
the global precision and round to nearest gives the same number.
|
||||||
|
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
The exponent letter is @code{e} for base 10, @code{p} for bases 2, 8,
|
||||||
|
16 with a binary exponent and @code{@@} for the other bases.
|
||||||
|
|
||||||
|
@item toPrecision(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10)
|
||||||
|
@item toFixed(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10)
|
||||||
|
@item toExponential(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10)
|
||||||
|
Same semantics as the corresponding @code{Number} functions with
|
||||||
|
BigFloats. There is no limit on the accepted precision @code{p}. The
|
||||||
|
rounding mode and radix can be optionally specified. The radix must be
|
||||||
|
between 2 and 36.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@subsection @code{BigFloatEnv} constructor
|
||||||
|
|
||||||
|
The @code{BigFloatEnv([p, [,rndMode]]} constructor cannot be invoked as a
|
||||||
|
function. The floating point environment contains:
|
||||||
|
|
||||||
|
@itemize
|
||||||
|
@item the mantissa precision in bits
|
||||||
|
|
||||||
|
@item the exponent size in bits assuming an IEEE 754 representation;
|
||||||
|
|
||||||
|
@item the subnormal flag (if true, subnormal floating point numbers can
|
||||||
|
be generated by the floating point operations).
|
||||||
|
|
||||||
|
@item the rounding mode
|
||||||
|
|
||||||
|
@item the floating point status. The status flags can only be set by the floating point operations. They can be reset with @code{BigFloatEnv.prototype.clearStatus()} or with the various status flag setters.
|
||||||
|
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@code{new BigFloatEnv([p, [,rndMode]]} creates a new floating point
|
||||||
|
environment. The status flags are reset. If no parameter is given the
|
||||||
|
precision, exponent bits and subnormal flags are copied from the
|
||||||
|
global floating point environment. Otherwise, the precision is set to
|
||||||
|
@code{p}, the number of exponent bits is set to @code{expBitsMax} and the
|
||||||
|
subnormal flags is set to @code{false}. If @code{rndMode} is
|
||||||
|
@code{undefined}, the rounding mode is set to @code{RNDN}.
|
||||||
|
|
||||||
|
@code{BigFloatEnv} properties:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item prec
|
||||||
|
Getter. Return the precision in bits of the global floating point
|
||||||
|
environment. The initial value is @code{113}.
|
||||||
|
|
||||||
|
@item expBits
|
||||||
|
Getter. Return the exponent size in bits of the global floating point
|
||||||
|
environment assuming an IEEE 754 representation. The initial value is
|
||||||
|
@code{15}.
|
||||||
|
|
||||||
|
@item setPrec(f, p[, e])
|
||||||
|
Set the precision of the global floating point environment to @code{p}
|
||||||
|
and the exponent size to @code{e} then call the function
|
||||||
|
@code{f}. Then the Float precision and exponent size are reset to
|
||||||
|
their precious value and the return value of @code{f} is returned (or
|
||||||
|
an exception is raised if @code{f} raised an exception). If @code{e}
|
||||||
|
is @code{undefined} it is set to @code{BigFloatEnv.expBitsMax}.
|
||||||
|
|
||||||
|
@item precMin
|
||||||
|
Read-only integer. Return the minimum allowed precision. Must be at least 2.
|
||||||
|
|
||||||
|
@item precMax
|
||||||
|
Read-only integer. Return the maximum allowed precision. Must be at least 113.
|
||||||
|
|
||||||
|
@item expBitsMin
|
||||||
|
Read-only integer. Return the minimum allowed exponent size in
|
||||||
|
bits. Must be at least 3.
|
||||||
|
|
||||||
|
@item expBitsMax
|
||||||
|
Read-only integer. Return the maximum allowed exponent size in
|
||||||
|
bits. Must be at least 15.
|
||||||
|
|
||||||
|
@item RNDN
|
||||||
|
Read-only integer. Round to nearest, with ties to even rounding mode.
|
||||||
|
|
||||||
|
@item RNDZ
|
||||||
|
Read-only integer. Round to zero rounding mode.
|
||||||
|
|
||||||
|
@item RNDD
|
||||||
|
Read-only integer. Round to -Infinity rounding mode.
|
||||||
|
|
||||||
|
@item RNDU
|
||||||
|
Read-only integer. Round to +Infinity rounding mode.
|
||||||
|
|
||||||
|
@item RNDNA
|
||||||
|
Read-only integer. Round to nearest, with ties away from zero rounding mode.
|
||||||
|
|
||||||
|
@item RNDA
|
||||||
|
Read-only integer. Round away from zero rounding mode.
|
||||||
|
|
||||||
|
@item RNDF@footnote{Could be removed in case a deterministic behavior for floating point operations is required.}
|
||||||
|
Read-only integer. Faithful rounding mode. The result is
|
||||||
|
non-deterministically rounded to -Infinity or +Infinity. This rounding
|
||||||
|
mode usually gives a faster and deterministic running time for the
|
||||||
|
floating point operations.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@code{BigFloatEnv.prototype} properties:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item prec
|
||||||
|
Getter and setter (Integer). Return or set the precision in bits.
|
||||||
|
|
||||||
|
@item expBits
|
||||||
|
Getter and setter (Integer). Return or set the exponent size in bits
|
||||||
|
assuming an IEEE 754 representation.
|
||||||
|
|
||||||
|
@item rndMode
|
||||||
|
Getter and setter (Integer). Return or set the rounding mode.
|
||||||
|
|
||||||
|
@item subnormal
|
||||||
|
Getter and setter (Boolean). subnormal flag. It is false when
|
||||||
|
@code{expBits = expBitsMax}.
|
||||||
|
|
||||||
|
@item clearStatus()
|
||||||
|
Clear the status flags.
|
||||||
|
|
||||||
|
@item invalidOperation
|
||||||
|
@item divideByZero
|
||||||
|
@item overflow
|
||||||
|
@item underflow
|
||||||
|
@item inexact
|
||||||
|
Getter and setter (Boolean). Status flags.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@chapter BigDecimal
|
||||||
|
|
||||||
|
This extension adds the @code{BigDecimal} primitive type. The
|
||||||
|
@code{BigDecimal} type represents floating point numbers in base
|
||||||
|
10. It is inspired from the proposal available at
|
||||||
|
@url{https://github.com/littledan/proposal-bigdecimal}.
|
||||||
|
|
||||||
|
The @code{BigDecimal} floating point numbers are always normalized and
|
||||||
|
finite. There is no concept of @code{-0}, @code{Infinity} or
|
||||||
|
@code{NaN}. By default, all the computations are done with infinite
|
||||||
|
precision.
|
||||||
|
|
||||||
|
@section Operators
|
||||||
|
|
||||||
|
The following builtin operators support BigDecimal:
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item +
|
||||||
|
@item -
|
||||||
|
@item *
|
||||||
|
Both operands must be BigDecimal. The result is computed with infinite
|
||||||
|
precision.
|
||||||
|
@item %
|
||||||
|
Both operands must be BigDecimal. The result is computed with infinite
|
||||||
|
precision. A range error is throws in case of division by zero.
|
||||||
|
|
||||||
|
@item /
|
||||||
|
Both operands must be BigDecimal. A range error is throws in case of
|
||||||
|
division by zero or if the result cannot be represented with infinite
|
||||||
|
precision (use @code{BigDecimal.div} to specify the rounding).
|
||||||
|
|
||||||
|
@item **
|
||||||
|
Both operands must be BigDecimal. The exponent must be a positive
|
||||||
|
integer. The result is computed with infinite precision.
|
||||||
|
|
||||||
|
@item ===
|
||||||
|
When one of the operand is a BigDecimal, return true if both operands
|
||||||
|
are a BigDecimal and if they are equal.
|
||||||
|
|
||||||
|
@item ==
|
||||||
|
@item !=
|
||||||
|
@item <=
|
||||||
|
@item >=
|
||||||
|
@item <
|
||||||
|
@item >
|
||||||
|
|
||||||
|
Numerical comparison. When one of the operand is not a BigDecimal, it is
|
||||||
|
converted to BigDecimal by using ToString(). Hence comparisons between
|
||||||
|
Number and BigDecimal do not use the exact mathematical value of the
|
||||||
|
Number value.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@section BigDecimal literals
|
||||||
|
|
||||||
|
BigDecimal literals are decimal floating point numbers with a trailing
|
||||||
|
@code{m} suffix.
|
||||||
|
|
||||||
|
@section Builtin Object changes
|
||||||
|
|
||||||
|
@subsection The @code{BigDecimal} function.
|
||||||
|
|
||||||
|
It returns @code{0m} if no parameter is provided. Otherwise the first
|
||||||
|
parameter is converted to a bigdecimal by using ToString(). Hence
|
||||||
|
Number values are not converted to their exact numerical value as
|
||||||
|
BigDecimal.
|
||||||
|
|
||||||
|
@subsection Properties of the @code{BigDecimal} object
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
|
||||||
|
@item add(a, b[, e])
|
||||||
|
@item sub(a, b[, e])
|
||||||
|
@item mul(a, b[, e])
|
||||||
|
@item div(a, b[, e])
|
||||||
|
@item mod(a, b[, e])
|
||||||
|
@item sqrt(a, e)
|
||||||
|
@item round(a, e)
|
||||||
|
Perform the specified floating point operation and round the floating
|
||||||
|
point result according to the rounding object @code{e}. If the
|
||||||
|
rounding object is not present, the operation is executed with
|
||||||
|
infinite precision.
|
||||||
|
|
||||||
|
For @code{div}, a @code{RangeError} exception is thrown in case of
|
||||||
|
division by zero or if the result cannot be represented with infinite
|
||||||
|
precision if no rounding object is present.
|
||||||
|
|
||||||
|
For @code{sqrt}, a range error is thrown if @code{a} is less than
|
||||||
|
zero.
|
||||||
|
|
||||||
|
The rounding object must contain the following properties:
|
||||||
|
@code{roundingMode} is a string specifying the rounding mode
|
||||||
|
(@code{"floor"}, @code{"ceiling"}, @code{"down"}, @code{"up"},
|
||||||
|
@code{"half-even"}, @code{"half-up"}). Either
|
||||||
|
@code{maximumSignificantDigits} or @code{maximumFractionDigits} must
|
||||||
|
be present to specify respectively the number of significant digits
|
||||||
|
(must be >= 1) or the number of digits after the decimal point (must
|
||||||
|
be >= 0).
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@subsection Properties of the @code{BigDecimal.prototype} object
|
||||||
|
|
||||||
|
@table @code
|
||||||
|
@item valueOf()
|
||||||
|
Return the bigdecimal primitive value corresponding to @code{this}.
|
||||||
|
|
||||||
|
@item toString()
|
||||||
|
Convert @code{this} to a string with infinite precision in base 10.
|
||||||
|
|
||||||
|
@item toPrecision(p, rnd_mode = "half-up")
|
||||||
|
@item toFixed(p, rnd_mode = "half-up")
|
||||||
|
@item toExponential(p, rnd_mode = "half-up")
|
||||||
|
Convert the BigDecimal @code{this} to string with the specified
|
||||||
|
precision @code{p}. There is no limit on the accepted precision
|
||||||
|
@code{p}. The rounding mode can be optionally
|
||||||
|
specified. @code{toPrecision} outputs either in decimal fixed notation
|
||||||
|
or in decimal exponential notation with a @code{p} digits of
|
||||||
|
precision. @code{toExponential} outputs in decimal exponential
|
||||||
|
notation with @code{p} digits after the decimal point. @code{toFixed}
|
||||||
|
outputs in decimal notation with @code{p} digits after the decimal
|
||||||
|
point.
|
||||||
|
|
||||||
|
@end table
|
||||||
|
|
||||||
|
@chapter Math mode
|
||||||
|
|
||||||
|
A new @emph{math mode} is enabled with the @code{"use math"}
|
||||||
|
directive. It propagates the same way as the @emph{strict mode}. It is
|
||||||
|
designed so that arbitrarily large integers and floating point numbers
|
||||||
|
are available by default. In order to minimize the number of changes
|
||||||
|
in the Javascript semantics, integers are represented either as Number
|
||||||
|
or BigInt depending on their magnitude. Floating point numbers are
|
||||||
|
always represented as BigFloat.
|
||||||
|
|
||||||
|
The following changes are made to the Javascript semantics:
|
||||||
|
|
||||||
|
@itemize
|
||||||
|
|
||||||
|
@item Floating point literals (i.e. number with a decimal point or an exponent) are @code{BigFloat} by default (i.e. a @code{l} suffix is implied). Hence @code{typeof 1.0 === "bigfloat"}.
|
||||||
|
|
||||||
|
@item Integer literals (i.e. numbers without a decimal point or an exponent) with or without the @code{n} suffix are @code{BigInt} if their value cannot be represented as a safe integer. A safe integer is defined as a integer whose absolute value is smaller or equal to @code{2**53-1}. Hence @code{typeof 1 === "number "}, @code{typeof 1n === "number"} but @code{typeof 9007199254740992 === "bigint" }.
|
||||||
|
|
||||||
|
@item All the bigint builtin operators and functions are modified so that their result is returned as a Number if it is a safe integer. Otherwise the result stays a BigInt.
|
||||||
|
|
||||||
|
@item The builtin operators are modified so that they return an exact result (which can be a BigInt) if their operands are safe integers. Operands between Number and BigInt are accepted provided the Number operand is a safe integer. The integer power with a negative exponent returns a BigFloat as result. The integer division returns a BigFloat as result.
|
||||||
|
|
||||||
|
@item The @code{^} operator is an alias to the power operator (@code{**}).
|
||||||
|
|
||||||
|
@item The power operator (both @code{^} and @code{**}) grammar is modified so that @code{-2^2} is allowed and yields @code{-4}.
|
||||||
|
|
||||||
|
@item The logical xor operator is still available with the @code{^^} operator.
|
||||||
|
|
||||||
|
@item The modulo operator (@code{%}) returns the Euclidian remainder (always positive) instead of the truncated remainder.
|
||||||
|
|
||||||
|
@item The integer division operator can be overloaded with @code{Operators.updateBigIntOperators(dictionary)}.
|
||||||
|
|
||||||
|
@item The integer power operator with a non zero negative exponent can be overloaded with @code{Operators.updateBigIntOperators(dictionary)}.
|
||||||
|
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@bye
|
1122
doc/quickjs.texi
Normal file
1122
doc/quickjs.texi
Normal file
File diff suppressed because it is too large
Load diff
20
docs/.gitignore
vendored
20
docs/.gitignore
vendored
|
@ -1,20 +0,0 @@
|
||||||
# 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 +0,0 @@
|
||||||
18
|
|
|
@ -1,3 +0,0 @@
|
||||||
module.exports = {
|
|
||||||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
|
|
||||||
};
|
|
|
@ -1,53 +0,0 @@
|
||||||
---
|
|
||||||
sidebar_position: 2
|
|
||||||
---
|
|
||||||
|
|
||||||
# Building
|
|
||||||
|
|
||||||
QuickJS uses [CMake] as its main build system, with an additional helper [Makefile].
|
|
||||||
|
|
||||||
:::note
|
|
||||||
Windows users will need to run the CMake commands manually.
|
|
||||||
:::
|
|
||||||
|
|
||||||
## Getting the source
|
|
||||||
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/quickjs-ng/quickjs.git
|
|
||||||
cd quickjs
|
|
||||||
```
|
|
||||||
|
|
||||||
## Compiling everything
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make
|
|
||||||
```
|
|
||||||
|
|
||||||
This will build the `qjs` and `qjsc` executables and other test tools. Head over [here](./cli) for
|
|
||||||
instructions on how to use them.
|
|
||||||
|
|
||||||
## Debug builds
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make debug
|
|
||||||
```
|
|
||||||
|
|
||||||
This will produce a debug build without optimizations, suitable for developers.
|
|
||||||
|
|
||||||
## Running test262
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make test262
|
|
||||||
```
|
|
||||||
|
|
||||||
This will run the test262 suite.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
make test262-update
|
|
||||||
```
|
|
||||||
|
|
||||||
This will run the test262 suite and update the error / pass report, useful after
|
|
||||||
implementing a new feature that would alter the result of the test suite.
|
|
||||||
|
|
||||||
[CMake]: https://cmake.org
|
|
||||||
[Makefile]: https://www.gnu.org/software/make/
|
|
130
docs/docs/cli.md
130
docs/docs/cli.md
|
@ -1,130 +0,0 @@
|
||||||
---
|
|
||||||
sidebar_position: 4
|
|
||||||
---
|
|
||||||
|
|
||||||
# The qjs and qjsc CLI tools
|
|
||||||
|
|
||||||
## `qjs` - The QuickJS JavaScript interpreter
|
|
||||||
|
|
||||||
The `qjs` executable runs the JavaScript interpreter. It includes a simple standard
|
|
||||||
library and REPL.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ qjs
|
|
||||||
usage: qjs [options] [file [args]]
|
|
||||||
-h --help list options
|
|
||||||
-e --eval EXPR evaluate EXPR
|
|
||||||
-i --interactive go to interactive mode
|
|
||||||
-m --module load as ES6 module (default=autodetect)
|
|
||||||
--script load as ES6 script (default=autodetect)
|
|
||||||
-I --include file include an additional file
|
|
||||||
--std make 'std', 'os' and 'bjson' available to script
|
|
||||||
-T --trace trace memory allocation
|
|
||||||
-d --dump dump the memory usage stats
|
|
||||||
-D --dump-flags flags for dumping debug data (see DUMP_* defines)
|
|
||||||
-c --compile FILE compile the given JS file as a standalone executable
|
|
||||||
-o --out FILE output file for standalone executables
|
|
||||||
--exe select the executable to use as the base, defaults to the current one
|
|
||||||
--memory-limit n limit the memory usage to 'n' Kbytes
|
|
||||||
--stack-size n limit the stack size to 'n' Kbytes
|
|
||||||
--unhandled-rejection dump unhandled promise rejections
|
|
||||||
-q --quit just instantiate the interpreter and quit
|
|
||||||
```
|
|
||||||
|
|
||||||
The following dump flags are supported:
|
|
||||||
|
|
||||||
```
|
|
||||||
DUMP_BYTECODE_FINAL 0x01 /* dump pass 3 final byte code */
|
|
||||||
DUMP_BYTECODE_PASS2 0x02 /* dump pass 2 code */
|
|
||||||
DUMP_BYTECODE_PASS1 0x04 /* dump pass 1 code */
|
|
||||||
DUMP_BYTECODE_HEX 0x10 /* dump bytecode in hex */
|
|
||||||
DUMP_BYTECODE_PC2LINE 0x20 /* dump line number table */
|
|
||||||
DUMP_BYTECODE_STACK 0x40 /* dump compute_stack_size */
|
|
||||||
DUMP_BYTECODE_STEP 0x80 /* dump executed bytecode */
|
|
||||||
DUMP_READ_OBJECT 0x100 /* dump the marshalled objects at load time */
|
|
||||||
DUMP_FREE 0x200 /* dump every object free */
|
|
||||||
DUMP_GC 0x400 /* dump the occurrence of the automatic GC */
|
|
||||||
DUMP_GC_FREE 0x800 /* dump objects freed by the GC */
|
|
||||||
DUMP_MODULE_RESOLVE 0x1000 /* dump module resolution steps */
|
|
||||||
DUMP_PROMISE 0x2000 /* dump promise steps */
|
|
||||||
DUMP_LEAKS 0x4000 /* dump leaked objects and strings in JS_FreeRuntime */
|
|
||||||
DUMP_ATOM_LEAKS 0x8000 /* dump leaked atoms in JS_FreeRuntime */
|
|
||||||
DUMP_MEM 0x10000 /* dump memory usage in JS_FreeRuntime */
|
|
||||||
DUMP_OBJECTS 0x20000 /* dump objects in JS_FreeRuntime */
|
|
||||||
DUMP_ATOMS 0x40000 /* dump atoms in JS_FreeRuntime */
|
|
||||||
DUMP_SHAPES 0x80000 /* dump shapes in JS_FreeRuntime */
|
|
||||||
```
|
|
||||||
|
|
||||||
### Creating standalone executables
|
|
||||||
|
|
||||||
With the `qjs` CLI it's possible to create standalone executables that will bundle the given JavaScript file
|
|
||||||
alongside the binary.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ qjs -c app.js -o app --exe qjs
|
|
||||||
```
|
|
||||||
|
|
||||||
The resulting `app` binary will have the same runtime dependencies as the `qjs` binary. This is acomplished
|
|
||||||
by compiling the target JavaScript file to bytecode and adding it a copy of the executable, with a little
|
|
||||||
trailer to help locate it. `--exe` expects the absolute path to `qjs`, e.g., `~/bin/qjs` or `$HOME/bin/qjs`.
|
|
||||||
|
|
||||||
Rather than using the current executable, it's possible to use the `--exe` switch to create standalone
|
|
||||||
executables for other platforms.
|
|
||||||
|
|
||||||
No JavaScript bundling is performed, the specified JS file cannot depend on other files. A bundler such
|
|
||||||
as `esbuild` can be used to generate an app bundle which can then be turned into the executable.
|
|
||||||
|
|
||||||
```
|
|
||||||
npx esbuild my-app/index.js \
|
|
||||||
--bundle \
|
|
||||||
--outfile=app.js \
|
|
||||||
--external:qjs:* \
|
|
||||||
--minify \
|
|
||||||
--target=es2023 \
|
|
||||||
--platform=neutral \
|
|
||||||
--format=esm \
|
|
||||||
--main-fields=main,module
|
|
||||||
```
|
|
||||||
|
|
||||||
## `qjsc` - The QuickJS JavaScript compiler
|
|
||||||
|
|
||||||
The `qjsc` executable runs the JavaScript compiler, it can generate bytecode from
|
|
||||||
source files which can then be embedded in an executable, or it can generate the necessary
|
|
||||||
scaffolding to build a C application which embeds QuickJS.
|
|
||||||
|
|
||||||
```
|
|
||||||
$ qjsc
|
|
||||||
usage: qjsc [options] [files]
|
|
||||||
|
|
||||||
options are:
|
|
||||||
-b output raw bytecode instead of C code
|
|
||||||
-e output main() and bytecode in a C file
|
|
||||||
-o output set the output filename
|
|
||||||
-n script_name set the script name (as used in stack traces)
|
|
||||||
-N cname set the C name of the generated data
|
|
||||||
-m compile as JavaScript module (default=autodetect)
|
|
||||||
-D module_name compile a dynamically loaded module or worker
|
|
||||||
-M module_name[,cname] add initialization code for an external C module
|
|
||||||
-p prefix set the prefix of the generated C names
|
|
||||||
-s strip the source code, specify twice to also strip debug info
|
|
||||||
-S n set the maximum stack size to 'n' bytes (default=262144)
|
|
||||||
```
|
|
||||||
|
|
||||||
Here is an example on how to create a standalone executable that embeds QuickJS
|
|
||||||
and the `examples/hello.js` JavaScript file:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Make sure you are in the QuickJS source directory.
|
|
||||||
$ cc hello.c cutils.c libbf.c libregexp.c libunicode.c quickjs.c quickjs-libc.c -I. -o hello
|
|
||||||
```
|
|
||||||
|
|
||||||
The resulting binary `hello` will be in the current directory.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ ./hello
|
|
||||||
Hello World
|
|
||||||
```
|
|
||||||
|
|
||||||
:::note
|
|
||||||
See the ["Creating standalone executables"](#creating-standalone-executables) section for a simpler way.
|
|
||||||
:::
|
|
|
@ -1,7 +0,0 @@
|
||||||
{
|
|
||||||
"label": "Developer Guide",
|
|
||||||
"position": 6,
|
|
||||||
"link": {
|
|
||||||
"type": "generated-index"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
# API Reference
|
|
||||||
|
|
||||||
WIP.
|
|
|
@ -1,117 +0,0 @@
|
||||||
# Internals
|
|
||||||
|
|
||||||
## Bytecode
|
|
||||||
|
|
||||||
The compiler generates bytecode directly with no intermediate
|
|
||||||
representation such as a parse tree, hence it is very fast. Several
|
|
||||||
optimizations passes are done over the generated bytecode.
|
|
||||||
|
|
||||||
A stack-based bytecode was chosen because it is simple and generates
|
|
||||||
compact code.
|
|
||||||
|
|
||||||
For each function, the maximum stack size is computed at compile time so that
|
|
||||||
no runtime stack overflow tests are needed.
|
|
||||||
|
|
||||||
A separate compressed line number table is maintained for the debug
|
|
||||||
information.
|
|
||||||
|
|
||||||
Access to closure variables is optimized and is almost as fast as local
|
|
||||||
variables.
|
|
||||||
|
|
||||||
Direct `eval` in strict mode is optimized.
|
|
||||||
|
|
||||||
## Runtime
|
|
||||||
|
|
||||||
### Strings
|
|
||||||
|
|
||||||
Strings are stored either as an 8 bit or a 16 bit array of
|
|
||||||
characters. Hence random access to characters is always fast.
|
|
||||||
|
|
||||||
The C API provides functions to convert JavaScript Strings to C UTF-8 encoded
|
|
||||||
strings. The most common case where the JavaScript string contains
|
|
||||||
only ASCII characters involves no copying.
|
|
||||||
|
|
||||||
### Objects
|
|
||||||
|
|
||||||
The object shapes (object prototype, property names and flags) are shared
|
|
||||||
between objects to save memory.
|
|
||||||
|
|
||||||
Arrays with no holes (except at the end of the array) are optimized.
|
|
||||||
|
|
||||||
TypedArray accesses are optimized.
|
|
||||||
|
|
||||||
### Atoms
|
|
||||||
|
|
||||||
Object property names and some strings are stored as Atoms (unique
|
|
||||||
strings) to save memory and allow fast comparison. Atoms are
|
|
||||||
represented as a 32 bit integer. Half of the atom range is reserved for
|
|
||||||
immediate integer literals from 0 to 2^31-1.
|
|
||||||
|
|
||||||
### Numbers
|
|
||||||
|
|
||||||
Numbers are represented either as 32-bit signed integers or 64-bit IEEE-754
|
|
||||||
floating point values. Most operations have fast paths for the 32-bit
|
|
||||||
integer case.
|
|
||||||
|
|
||||||
### Garbage collection
|
|
||||||
|
|
||||||
Reference counting is used to free objects automatically and
|
|
||||||
deterministically. A separate cycle removal pass is done when the allocated
|
|
||||||
memory becomes too large. The cycle removal algorithm only uses the
|
|
||||||
reference counts and the object content, so no explicit garbage
|
|
||||||
collection roots need to be manipulated in the C code.
|
|
||||||
|
|
||||||
### JSValue
|
|
||||||
|
|
||||||
It is a JavaScript value which can be a primitive type (such as
|
|
||||||
Number, String, ...) or an Object. NaN boxing is used in the 32-bit version
|
|
||||||
to store 64-bit floating point numbers. The representation is
|
|
||||||
optimized so that 32-bit integers and reference counted values can be
|
|
||||||
efficiently tested.
|
|
||||||
|
|
||||||
In 64-bit code, JSValue are 128-bit large and no NaN boxing is used. The
|
|
||||||
rationale is that in 64-bit code memory usage is less critical.
|
|
||||||
|
|
||||||
In both cases (32 or 64 bits), JSValue exactly fits two CPU registers,
|
|
||||||
so it can be efficiently returned by C functions.
|
|
||||||
|
|
||||||
### Function call
|
|
||||||
|
|
||||||
The engine is optimized so that function calls are fast. The system
|
|
||||||
stack holds the JavaScript parameters and local variables.
|
|
||||||
|
|
||||||
### RegExp
|
|
||||||
|
|
||||||
A specific regular expression engine was developed. It is both small
|
|
||||||
and efficient and supports all the ES2020+ features including the
|
|
||||||
Unicode properties. As the JavaScript compiler, it directly generates
|
|
||||||
bytecode without a parse tree.
|
|
||||||
|
|
||||||
Backtracking with an explicit stack is used so that there is no
|
|
||||||
recursion on the system stack. Simple quantifiers are specifically
|
|
||||||
optimized to avoid recursions.
|
|
||||||
|
|
||||||
Infinite recursions coming from quantifiers with empty terms are
|
|
||||||
avoided.
|
|
||||||
|
|
||||||
The full regexp library weighs about 15 KiB (x86 code), excluding the
|
|
||||||
Unicode library.
|
|
||||||
|
|
||||||
### Unicode
|
|
||||||
|
|
||||||
A specific Unicode library was developed so that there is no
|
|
||||||
dependency on an external large Unicode library such as ICU. All the
|
|
||||||
Unicode tables are compressed while keeping a reasonable access
|
|
||||||
speed.
|
|
||||||
|
|
||||||
The library supports case conversion, Unicode normalization, Unicode
|
|
||||||
script queries, Unicode general category queries and all Unicode
|
|
||||||
binary properties.
|
|
||||||
|
|
||||||
The full Unicode library weighs about 45 KiB (x86 code).
|
|
||||||
|
|
||||||
### BigInt
|
|
||||||
|
|
||||||
BigInt is implemented with the [libbf](https://bellard.org/libbf) library.
|
|
||||||
It weights about 90 KiB (x86 code) and provides arbitrary precision IEEE 754 floating
|
|
||||||
point operations and transcendental functions with exact rounding.
|
|
|
@ -1,113 +0,0 @@
|
||||||
---
|
|
||||||
sidebar_position: 1
|
|
||||||
---
|
|
||||||
|
|
||||||
# The QuickJS C API
|
|
||||||
|
|
||||||
The C API was designed to be simple and efficient. The C API is
|
|
||||||
defined in the header `quickjs.h`.
|
|
||||||
|
|
||||||
## Runtime and contexts
|
|
||||||
|
|
||||||
`JSRuntime` represents a JavaScript runtime corresponding to an
|
|
||||||
object heap. Several runtimes can exist at the same time but they
|
|
||||||
cannot exchange objects. Inside a given runtime, no multi-threading is
|
|
||||||
supported.
|
|
||||||
|
|
||||||
`JSContext` represents a JavaScript context (or Realm). Each
|
|
||||||
JSContext has its own global objects and system objects. There can be
|
|
||||||
several JSContexts per JSRuntime and they can share objects, similar
|
|
||||||
to frames of the same origin sharing JavaScript objects in a
|
|
||||||
web browser.
|
|
||||||
|
|
||||||
## JSValue
|
|
||||||
|
|
||||||
`JSValue` represents a JavaScript value which can be a primitive
|
|
||||||
type or an object. Reference counting is used, so it is important to
|
|
||||||
explicitly duplicate (`JS_DupValue()`, increment the reference
|
|
||||||
count) or free (`JS_FreeValue()`, decrement the reference count)
|
|
||||||
JSValues.
|
|
||||||
|
|
||||||
## C functions
|
|
||||||
|
|
||||||
C functions can be created with
|
|
||||||
`JS_NewCFunction()`. `JS_SetPropertyFunctionList()` is a
|
|
||||||
shortcut to easily add functions, setters and getters properties to a
|
|
||||||
given object.
|
|
||||||
|
|
||||||
Unlike other embedded JavaScript engines, there is no implicit stack,
|
|
||||||
so C functions get their parameters as normal C parameters. As a
|
|
||||||
general rule, C functions take constant `JSValue`s as parameters
|
|
||||||
(so they don't need to free them) and return a newly allocated (=live)
|
|
||||||
`JSValue`.
|
|
||||||
|
|
||||||
## Exceptions
|
|
||||||
|
|
||||||
Most C functions can return a JavaScript exception. It
|
|
||||||
must be explicitly tested and handled by the C code. The specific
|
|
||||||
`JSValue` `JS_EXCEPTION` indicates that an exception
|
|
||||||
occurred. The actual exception object is stored in the
|
|
||||||
`JSContext` and can be retrieved with `JS_GetException()`.
|
|
||||||
|
|
||||||
## Script evaluation
|
|
||||||
|
|
||||||
Use `JS_Eval()` to evaluate a script or module source.
|
|
||||||
|
|
||||||
If the script or module was compiled to bytecode with `qjsc`, it
|
|
||||||
can be evaluated by calling `js_std_eval_binary()`. The advantage
|
|
||||||
is that no compilation is needed so it is faster and smaller because
|
|
||||||
the compiler can be removed from the executable if no `eval` is
|
|
||||||
required.
|
|
||||||
|
|
||||||
Note: the bytecode format is linked to a given QuickJS
|
|
||||||
version. Moreover, no security check is done before its
|
|
||||||
execution. Hence the bytecode should not be loaded from untrusted
|
|
||||||
sources.
|
|
||||||
|
|
||||||
## JS Classes
|
|
||||||
|
|
||||||
C opaque data can be attached to a JavaScript object. The type of the
|
|
||||||
C opaque data is determined with the class ID (`JSClassID`) of
|
|
||||||
the object. Hence the first step is to register a new class ID and JS
|
|
||||||
class (`JS_NewClassID()`, `JS_NewClass()`). Then you can
|
|
||||||
create objects of this class with `JS_NewObjectClass()` and get or
|
|
||||||
set the C opaque point with `JS_GetOpaque()` / `JS_SetOpaque()`.
|
|
||||||
|
|
||||||
When defining a new JS class, it is possible to declare a finalizer
|
|
||||||
which is called when the object is destroyed. The finalizer should be
|
|
||||||
used to release C resources. It is invalid to execute JS code from
|
|
||||||
it. A `gc_mark` method can be provided so that the cycle removal
|
|
||||||
algorithm can find the other objects referenced by this object. Other
|
|
||||||
methods are available to define exotic object behaviors.
|
|
||||||
|
|
||||||
The Class ID are allocated per-runtime. The
|
|
||||||
`JSClass` are allocated per `JSRuntime`. `JS_SetClassProto()`
|
|
||||||
is used to define a prototype for a given class in a given
|
|
||||||
`JSContext`. `JS_NewObjectClass()` sets this prototype in the
|
|
||||||
created object.
|
|
||||||
|
|
||||||
Examples are available in `quickjs-libc.c`.
|
|
||||||
|
|
||||||
## C Modules
|
|
||||||
|
|
||||||
Native ES6 modules are supported and can be dynamically or statically
|
|
||||||
linked. The standard library `quickjs-libc.c` is a good example
|
|
||||||
of a native module.
|
|
||||||
|
|
||||||
## Memory handling
|
|
||||||
|
|
||||||
Use `JS_SetMemoryLimit()` to set a global memory allocation limit
|
|
||||||
to a given `JSRuntime`.
|
|
||||||
|
|
||||||
Custom memory allocation functions can be provided with `JS_NewRuntime2()`.
|
|
||||||
|
|
||||||
The maximum system stack size can be set with `JS_SetMaxStackSize()`.
|
|
||||||
|
|
||||||
## Execution timeout and interrupts
|
|
||||||
|
|
||||||
Use `JS_SetInterruptHandler()` to set a callback which is
|
|
||||||
regularly called by the engine when it is executing code. This
|
|
||||||
callback can be used to implement an execution timeout.
|
|
||||||
|
|
||||||
It is used by the command line interpreter to implement a
|
|
||||||
`Ctrl-C` handler.
|
|
|
@ -1,68 +0,0 @@
|
||||||
# Differences with bellard/quickjs
|
|
||||||
|
|
||||||
This project aims to be a drop-in replacement for those already using QuickJS.
|
|
||||||
Minimal API changes might be necessary.
|
|
||||||
|
|
||||||
## Community development
|
|
||||||
|
|
||||||
NG is developed in the open, interacting with the wider community and through
|
|
||||||
these interactions many improvements have already been made, including the incorporation
|
|
||||||
of patches previously maintained in other forks.
|
|
||||||
|
|
||||||
Each PR is reviewed, iterated on, and merged in GitHub.
|
|
||||||
|
|
||||||
To date, NG has had over 40 distinct contributors and over 400 PRs.
|
|
||||||
|
|
||||||
## Consistent release cadence
|
|
||||||
|
|
||||||
As the project moves forward, a steady cadence of releases has been maintained, with an
|
|
||||||
average of a new release every 2 months.
|
|
||||||
|
|
||||||
## Testing
|
|
||||||
|
|
||||||
Since its inception testing has been a focus. Each PR is tested in over 50 configurations,
|
|
||||||
involving different operating systems, build types and sanitizers.
|
|
||||||
|
|
||||||
The `test262` suite is also ran for every change.
|
|
||||||
|
|
||||||
## Cross-platform support
|
|
||||||
|
|
||||||
In order to better support other platforms such as Windows the build system was
|
|
||||||
changed to use [CMake].
|
|
||||||
|
|
||||||
In addition, Windows is treated as a first class citizen, with the addition of support
|
|
||||||
for the MSVC compiler.
|
|
||||||
|
|
||||||
[CMake]: https://cmake.org/
|
|
||||||
|
|
||||||
## Performance
|
|
||||||
|
|
||||||
While being an interpreter limits the performance in comparison with other engines which
|
|
||||||
use a JIT, several significant performance improvements have been made:
|
|
||||||
|
|
||||||
- Opcode fusion
|
|
||||||
- Polymorphic inline caching
|
|
||||||
- Memory allocation improvements
|
|
||||||
- Improved parse speeds
|
|
||||||
|
|
||||||
## New ECMAScript APIs
|
|
||||||
|
|
||||||
The main focus of NG is to deliver state-of-the-art JavaScript features. Typically once they
|
|
||||||
are stable (stage 4) but sometimes even at earlier stages. Here is a non-exhaustive list
|
|
||||||
of ES features present in NG:
|
|
||||||
|
|
||||||
- Resizable ArrayBuffer
|
|
||||||
- Float16Array
|
|
||||||
- WeakRef
|
|
||||||
- FinalizationRegistry
|
|
||||||
- Iterator Helpers
|
|
||||||
- Promise.try
|
|
||||||
- Error.isError
|
|
||||||
- Set operations
|
|
||||||
|
|
||||||
Some non-standard but widely used APIs have also been added:
|
|
||||||
|
|
||||||
- V8's [stack trace API](https://v8.dev/docs/stack-trace-api)
|
|
||||||
- `Error.captureStackTrace`
|
|
||||||
- `Error.prepareStackTrace`
|
|
||||||
- `Error.stackTraceLimit`
|
|
|
@ -1,11 +0,0 @@
|
||||||
---
|
|
||||||
sidebar_position: 7
|
|
||||||
---
|
|
||||||
|
|
||||||
# ECMAScript Features
|
|
||||||
|
|
||||||
QuickJS aims to support the latest available ECMAScript features once they hit the spec.
|
|
||||||
|
|
||||||
Progress on _test262_ compliance can be checked [here](https://test262.fyi/#|qjs_ng).
|
|
||||||
|
|
||||||
Due to size constraints it is unlikely QuickJS will ever support the [Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl) APIs.
|
|
|
@ -1,34 +0,0 @@
|
||||||
---
|
|
||||||
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 and architectures.
|
|
||||||
|
|
||||||
|
|
||||||
## 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
|
|
|
@ -1,33 +0,0 @@
|
||||||
---
|
|
||||||
slug: /
|
|
||||||
sidebar_position: 1
|
|
||||||
sidebar_label: Welcome
|
|
||||||
---
|
|
||||||
|
|
||||||
# Welcome to QuickJS-NG
|
|
||||||
|
|
||||||
QuickJS is a small and embeddable JavaScript engine. It aims to support the latest
|
|
||||||
[ECMAScript] specification.
|
|
||||||
|
|
||||||
This project is a _fork_ of the [original QuickJS project] by Fabrice Bellard and Charlie Gordon, after it went dormant, with the intent of reigniting its development.
|
|
||||||
|
|
||||||
This project is focused on (but not limited to):
|
|
||||||
|
|
||||||
- Community development
|
|
||||||
- Testing
|
|
||||||
- Cross-platform support
|
|
||||||
- ES features
|
|
||||||
|
|
||||||
You can check the differences with the original project [here.](./diff)
|
|
||||||
|
|
||||||
:::note
|
|
||||||
This site is under construction, the entire API is not yet documented.
|
|
||||||
:::
|
|
||||||
|
|
||||||
## Getting Started
|
|
||||||
|
|
||||||
Head over to [building](./building) if you want to build QuickJS from source or [installation](./installation)
|
|
||||||
for installing it from prebuilt binaries.
|
|
||||||
|
|
||||||
[ECMAScript]: https://tc39.es/ecma262/
|
|
||||||
[original QuickJS project]: https://bellard.org/quickjs
|
|
|
@ -1,32 +0,0 @@
|
||||||
# Projects using NG
|
|
||||||
|
|
||||||
Here is a list of projects currently using, supporting or migrating to QuickJS-NG.
|
|
||||||
If you want yours to be listed here, please open a PR!
|
|
||||||
|
|
||||||
## [txiki.js](https://github.com/saghul/txiki.js)
|
|
||||||
|
|
||||||
A tiny JavaScript runtime.
|
|
||||||
|
|
||||||
## [radare2](https://github.com/radareorg/radare2)
|
|
||||||
|
|
||||||
Reverse engineering framework.
|
|
||||||
|
|
||||||
## [rquickjs](https://github.com/DelSkayn/rquickjs)
|
|
||||||
|
|
||||||
High level Rust bindings.
|
|
||||||
|
|
||||||
## [llrt](https://github.com/awslabs/llrt)
|
|
||||||
|
|
||||||
Lightweight JS runtime for serverless applications.
|
|
||||||
|
|
||||||
## [nx.js](https://github.com/TooTallNate/nx.js)
|
|
||||||
|
|
||||||
JavaScript runtime for Nintendo Switch homebrew applications.
|
|
||||||
|
|
||||||
## [quickjs-rusty](https://github.com/Icemic/quickjs-rusty)
|
|
||||||
|
|
||||||
Rust wrapper focus on embedding-ready and no-pain type conversion and interoperability.
|
|
||||||
|
|
||||||
## [GodotJS](https://github.com/godotjs/GodotJS)
|
|
||||||
|
|
||||||
This project adds TypeScript/JavaScript support for Godot 4.x. It supports multiple javascript runtimes, including QuicJS-NG.
|
|
|
@ -1,553 +0,0 @@
|
||||||
---
|
|
||||||
sidebar_position: 5
|
|
||||||
---
|
|
||||||
|
|
||||||
# Standard library
|
|
||||||
|
|
||||||
The standard libary is provided as part of the `qjs` executable and the `quickjs-libc.c` source file
|
|
||||||
and it's not part of the core engine.
|
|
||||||
|
|
||||||
## Globals
|
|
||||||
|
|
||||||
### `argv0`
|
|
||||||
|
|
||||||
Provides the executable path.
|
|
||||||
|
|
||||||
### `scriptArgs`
|
|
||||||
|
|
||||||
Provides the command line arguments. The first argument is the script name.
|
|
||||||
|
|
||||||
### `print(...args)`
|
|
||||||
|
|
||||||
Print the arguments separated by spaces and a trailing newline.
|
|
||||||
|
|
||||||
### `console.log(...args)`
|
|
||||||
|
|
||||||
Same as `print()`.
|
|
||||||
|
|
||||||
### `navigator.userAgent`
|
|
||||||
|
|
||||||
Returns `quickjs-ng/<version>`.
|
|
||||||
|
|
||||||
### `gc()`
|
|
||||||
|
|
||||||
Shorthand for `std.gc()`.
|
|
||||||
|
|
||||||
## `qjs:bjson` module
|
|
||||||
|
|
||||||
### `bjson.write(obj, [flags])`
|
|
||||||
|
|
||||||
Serializes the given object into the QuickJS internal serialization format.
|
|
||||||
Returns an ArrayBuffer with the serialized data.
|
|
||||||
|
|
||||||
Supported flags:
|
|
||||||
|
|
||||||
- `WRITE_OBJ_BYTECODE`: allow serializing functions and modules
|
|
||||||
- `WRITE_OBJ_REFERENCE`: allow serializing object references
|
|
||||||
- `WRITE_OBJ_SAB`: allow serializing SharedArrayBuffer instances
|
|
||||||
- `WRITE_OBJ_STRIP_DEBUG`: strip debugging information when serializing
|
|
||||||
- `WRITE_OBJ_STRIP_SOURCE`: strip the source information when serializing
|
|
||||||
|
|
||||||
### `bjson.read(buf, [pos], [len], [flags])`
|
|
||||||
|
|
||||||
De-serialize the given ArrayBuffer (in QuickJS internal serialization format) back into a JavaScript value.
|
|
||||||
|
|
||||||
Supported flags:
|
|
||||||
|
|
||||||
- `READ_OBJ_BYTECODE`: allow de-serializing functions and modules
|
|
||||||
- `READ_OBJ_REFERENCE`: allow de-serializing object references
|
|
||||||
- `READ_OBJ_SAB`: allow de-serializing SharedArrayBuffer instances
|
|
||||||
|
|
||||||
## `qjs:os` module
|
|
||||||
|
|
||||||
The `os` module provides Operating System specific functions:
|
|
||||||
|
|
||||||
- low level file access
|
|
||||||
- signals
|
|
||||||
- timers
|
|
||||||
- basic asynchronous I/O
|
|
||||||
- workers (threads)
|
|
||||||
|
|
||||||
The OS functions usually return 0 if OK or an OS specific negative
|
|
||||||
error code.
|
|
||||||
|
|
||||||
### `open(filename, flags, mode = 0o666)`
|
|
||||||
|
|
||||||
Open a file. Return a handle or < 0 if error.
|
|
||||||
|
|
||||||
Supported flags:
|
|
||||||
|
|
||||||
- `O_RDONLY`
|
|
||||||
- `O_WRONLY`
|
|
||||||
- `O_RDWR`
|
|
||||||
- `O_APPEND`
|
|
||||||
- `O_CREAT`
|
|
||||||
- `O_EXCL`
|
|
||||||
- `O_TRUNC`
|
|
||||||
|
|
||||||
POSIX open flags.
|
|
||||||
|
|
||||||
- `O_TEXT`
|
|
||||||
|
|
||||||
(Windows specific). Open the file in text mode. The default is binary mode.
|
|
||||||
|
|
||||||
### `close(fd)`
|
|
||||||
|
|
||||||
Close the file handle `fd`.
|
|
||||||
|
|
||||||
### `seek(fd, offset, whence)`
|
|
||||||
|
|
||||||
Seek in the file. Use `std.SEEK_*` for
|
|
||||||
`whence`. `offset` is either a number or a BigInt. If
|
|
||||||
`offset` is a BigInt, a BigInt is returned too.
|
|
||||||
|
|
||||||
### `read(fd, buffer, offset, length)`
|
|
||||||
|
|
||||||
Read `length` bytes from the file handle `fd` to the
|
|
||||||
ArrayBuffer `buffer` at byte position `offset`.
|
|
||||||
Return the number of read bytes or < 0 if error.
|
|
||||||
|
|
||||||
### `write(fd, buffer, offset, length)`
|
|
||||||
|
|
||||||
Write `length` bytes to the file handle `fd` from the
|
|
||||||
ArrayBuffer `buffer` at byte position `offset`.
|
|
||||||
Return the number of written bytes or < 0 if error.
|
|
||||||
|
|
||||||
### `isatty(fd)`
|
|
||||||
|
|
||||||
Return `true` is `fd` is a TTY (terminal) handle.
|
|
||||||
|
|
||||||
### `ttyGetWinSize(fd)`
|
|
||||||
|
|
||||||
Return the TTY size as `[width, height]` or `null` if not available.
|
|
||||||
|
|
||||||
### `ttySetRaw(fd)`
|
|
||||||
|
|
||||||
Set the TTY in raw mode.
|
|
||||||
|
|
||||||
### `remove(filename)`
|
|
||||||
|
|
||||||
Remove a file. Return 0 if OK or `-errno`.
|
|
||||||
|
|
||||||
### `rename(oldname, newname)`
|
|
||||||
|
|
||||||
Rename a file. Return 0 if OK or `-errno`.
|
|
||||||
|
|
||||||
### `realpath(path)`
|
|
||||||
|
|
||||||
Return `[str, err]` where `str` is the canonicalized absolute
|
|
||||||
pathname of `path` and `err` the error code.
|
|
||||||
|
|
||||||
### `getcwd()`
|
|
||||||
|
|
||||||
Return `[str, err]` where `str` is the current working directory
|
|
||||||
and `err` the error code.
|
|
||||||
|
|
||||||
### `chdir(path)`
|
|
||||||
|
|
||||||
Change the current directory. Return 0 if OK or `-errno`.
|
|
||||||
|
|
||||||
### `mkdir(path, mode = 0o777)`
|
|
||||||
|
|
||||||
Create a directory at `path`. Return 0 if OK or `-errno`.
|
|
||||||
|
|
||||||
### `stat(path)` / `lstat(path)`
|
|
||||||
|
|
||||||
Return `[obj, err]` where `obj` is an object containing the
|
|
||||||
file status of `path`. `err` is the error code. The
|
|
||||||
following fields are defined in `obj`: `dev`, `ino`, `mode`, `nlink`,
|
|
||||||
`uid`, `gid`, `rdev`, `size`, `blocks`, `atime`, `mtime`, `ctime`. The times are
|
|
||||||
specified in milliseconds since 1970. `lstat()` is the same as
|
|
||||||
`stat()` excepts that it returns information about the link
|
|
||||||
itself.
|
|
||||||
|
|
||||||
- `S_IFMT`
|
|
||||||
- `S_IFIFO`
|
|
||||||
- `S_IFCHR`
|
|
||||||
- `S_IFDIR`
|
|
||||||
- `S_IFBLK`
|
|
||||||
- `S_IFREG`
|
|
||||||
- `S_IFSOCK`
|
|
||||||
- `S_IFLNK`
|
|
||||||
- `S_ISGID`
|
|
||||||
- `S_ISUID`
|
|
||||||
|
|
||||||
Constants to interpret the `mode` property returned by
|
|
||||||
`stat()`. They have the same value as in the C system header
|
|
||||||
`sys/stat.h`.
|
|
||||||
|
|
||||||
### `utimes(path, atime, mtime)`
|
|
||||||
|
|
||||||
Change the access and modification times of the file `path`. The
|
|
||||||
times are specified in milliseconds since 1970. Return 0 if OK or `-errno`.
|
|
||||||
|
|
||||||
### `symlink(target, linkpath)`
|
|
||||||
|
|
||||||
Create a link at `linkpath` containing the string `target`. Return 0 if OK or `-errno`.
|
|
||||||
|
|
||||||
### `readlink(path)`
|
|
||||||
|
|
||||||
Return `[str, err]` where `str` is the link target and `err`
|
|
||||||
the error code.
|
|
||||||
|
|
||||||
### `readdir(path)`
|
|
||||||
|
|
||||||
Return `[array, err]` where `array` is an array of strings
|
|
||||||
containing the filenames of the directory `path`. `err` is
|
|
||||||
the error code.
|
|
||||||
|
|
||||||
### `setReadHandler(fd, func)`
|
|
||||||
|
|
||||||
Add a read handler to the file handle `fd`. `func` is called
|
|
||||||
each time there is data pending for `fd`. A single read handler
|
|
||||||
per file handle is supported. Use `func = null` to remove the
|
|
||||||
handler.
|
|
||||||
|
|
||||||
### `setWriteHandler(fd, func)`
|
|
||||||
|
|
||||||
Add a write handler to the file handle `fd`. `func` is
|
|
||||||
called each time data can be written to `fd`. A single write
|
|
||||||
handler per file handle is supported. Use `func = null` to remove
|
|
||||||
the handler.
|
|
||||||
|
|
||||||
### `signal(signal, func)`
|
|
||||||
|
|
||||||
Call the function `func` when the signal `signal`
|
|
||||||
happens. Only a single handler per signal number is supported. Use
|
|
||||||
`null` to set the default handler or `undefined` to ignore
|
|
||||||
the signal. Signal handlers can only be defined in the main thread.
|
|
||||||
|
|
||||||
- `SIGINT`
|
|
||||||
- `SIGABRT`
|
|
||||||
- `SIGFPE`
|
|
||||||
- `SIGILL`
|
|
||||||
- `SIGSEGV`
|
|
||||||
- `SIGTERM`
|
|
||||||
|
|
||||||
POSIX signal numbers.
|
|
||||||
|
|
||||||
### `kill(pid, sig)`
|
|
||||||
|
|
||||||
Send the signal `sig` to the process `pid`.
|
|
||||||
|
|
||||||
### `exec(args[, options])`
|
|
||||||
|
|
||||||
Execute a process with the arguments `args`. `options` is an
|
|
||||||
object containing optional parameters:
|
|
||||||
|
|
||||||
- `block` - Boolean (default = true). If true, wait until the process is
|
|
||||||
terminated. In this case, `exec` return the exit code if positive
|
|
||||||
or the negated signal number if the process was interrupted by a
|
|
||||||
signal. If false, do not block and return the process id of the child.
|
|
||||||
- `usePath` - Boolean (default = true). If true, the file is searched in the
|
|
||||||
`PATH` environment variable.
|
|
||||||
- `file` - String (default = `args[0]`). Set the file to be executed.
|
|
||||||
- `cwd` - String. If present, set the working directory of the new process.
|
|
||||||
- `stdin`, `stdout`, `stderr` - If present, set the handle in the child for stdin, stdout or stderr.
|
|
||||||
- `env` - Object. If present, set the process environment from the object
|
|
||||||
key-value pairs. Otherwise use the same environment as the current
|
|
||||||
process.
|
|
||||||
- `uid` - Integer. If present, the process uid with `setuid`.
|
|
||||||
- `gid` - Integer. If present, the process gid with `setgid`.
|
|
||||||
|
|
||||||
### `waitpid(pid, options)`
|
|
||||||
|
|
||||||
`waitpid` Unix system call. Return the array `[ret, status]`.
|
|
||||||
`ret` contains `-errno` in case of error.
|
|
||||||
|
|
||||||
- `WNOHANG`
|
|
||||||
|
|
||||||
Constant for the `options` argument of `waitpid`.
|
|
||||||
|
|
||||||
### `dup(fd)`
|
|
||||||
|
|
||||||
`dup` Unix system call.
|
|
||||||
|
|
||||||
### `dup2(oldfd, newfd)`
|
|
||||||
|
|
||||||
`dup2` Unix system call.
|
|
||||||
|
|
||||||
### `pipe()`
|
|
||||||
|
|
||||||
`pipe` Unix system call. Return two handles as `[read_fd, write_fd]` or null in case of error.
|
|
||||||
|
|
||||||
### `sleep(delay_ms)`
|
|
||||||
|
|
||||||
Sleep during `delay_ms` milliseconds.
|
|
||||||
|
|
||||||
### `sleepAsync(delay_ms)`
|
|
||||||
|
|
||||||
Asynchronouse sleep during `delay_ms` milliseconds. Returns a promise. Example:
|
|
||||||
|
|
||||||
```js
|
|
||||||
await os.sleepAsync(500);
|
|
||||||
```
|
|
||||||
|
|
||||||
### `setTimeout(func, delay)`
|
|
||||||
|
|
||||||
Call the function `func` after `delay` ms. Return a timer ID.
|
|
||||||
|
|
||||||
### `clearTimeout(id)`
|
|
||||||
|
|
||||||
Cancel a timer.
|
|
||||||
|
|
||||||
### `platform`
|
|
||||||
|
|
||||||
Return a string representing the platform: `"linux"`, `"darwin"`, `"win32"` or `"js"`.
|
|
||||||
|
|
||||||
### `Worker(module_filename)`
|
|
||||||
|
|
||||||
Constructor to create a new thread (worker) with an API close to that of
|
|
||||||
`WebWorkers`. `module_filename` is a string specifying the
|
|
||||||
module filename which is executed in the newly created thread. As for
|
|
||||||
dynamically imported module, it is relative to the current script or
|
|
||||||
module path. Threads normally don't share any data and communicate
|
|
||||||
between each other with messages. Nested workers are not supported. An
|
|
||||||
example is available in `tests/test_worker.js`.
|
|
||||||
|
|
||||||
The worker class has the following static properties:
|
|
||||||
|
|
||||||
- `parent` - In the created worker, `Worker.parent` represents the parent
|
|
||||||
worker and is used to send or receive messages.
|
|
||||||
|
|
||||||
The worker instances have the following properties:
|
|
||||||
|
|
||||||
- `postMessage(msg)` - Send a message to the corresponding worker. `msg` is cloned in
|
|
||||||
the destination worker using an algorithm similar to the `HTML`
|
|
||||||
structured clone algorithm. `SharedArrayBuffer` are shared
|
|
||||||
between workers.
|
|
||||||
|
|
||||||
- `onmessage` - Getter and setter. Set a function which is called each time a
|
|
||||||
message is received. The function is called with a single
|
|
||||||
argument. It is an object with a `data` property containing the
|
|
||||||
received message. The thread is not terminated if there is at least
|
|
||||||
one non `null` `onmessage` handler.
|
|
||||||
|
|
||||||
## `qjs:std` module
|
|
||||||
|
|
||||||
The `std` module provides wrappers to libc (`stdlib.h` and `stdio.h`) and a few other utilities.
|
|
||||||
|
|
||||||
### `exit(n)`
|
|
||||||
|
|
||||||
Exit the process.
|
|
||||||
|
|
||||||
### `evalScript(str, options = undefined)`
|
|
||||||
|
|
||||||
Evaluate the string `str` as a script (global
|
|
||||||
eval). `options` is an optional object containing the following
|
|
||||||
optional properties:
|
|
||||||
|
|
||||||
- `backtrace_barrier` - Boolean (default = false). If true, error backtraces do not list the
|
|
||||||
stack frames below the evalScript.
|
|
||||||
- `async` - Boolean (default = false). If true, `await` is accepted in the
|
|
||||||
script and a promise is returned. The promise is resolved with an
|
|
||||||
object whose `value` property holds the value returned by the
|
|
||||||
script.
|
|
||||||
|
|
||||||
### `loadScript(filename)`
|
|
||||||
|
|
||||||
Evaluate the file `filename` as a script (global eval).
|
|
||||||
|
|
||||||
### `loadFile(filename, [options])`
|
|
||||||
|
|
||||||
Load the file `filename` and return it as a string assuming UTF-8
|
|
||||||
encoding. Return `null` in case of I/O error.
|
|
||||||
|
|
||||||
If `options.binary` is set to `true` a `Uint8Array` is returned instead.
|
|
||||||
|
|
||||||
### `open(filename, flags, errorObj = undefined)`
|
|
||||||
|
|
||||||
Open a file (wrapper to the libc `fopen()`). Return the FILE
|
|
||||||
object or `null` in case of I/O error. If `errorObj` is not
|
|
||||||
undefined, set its `errno` property to the error code or to 0 if
|
|
||||||
no error occurred.
|
|
||||||
|
|
||||||
### `popen(command, flags, errorObj = undefined)`
|
|
||||||
|
|
||||||
Open a process by creating a pipe (wrapper to the libc
|
|
||||||
`popen()`). Return the FILE
|
|
||||||
object or `null` in case of I/O error. If `errorObj` is not
|
|
||||||
undefined, set its `errno` property to the error code or to 0 if
|
|
||||||
no error occurred.
|
|
||||||
|
|
||||||
### `fdopen(fd, flags, errorObj = undefined)`
|
|
||||||
|
|
||||||
Open a file from a file handle (wrapper to the libc
|
|
||||||
`fdopen()`). Return the FILE
|
|
||||||
object or null` in case of I/O error. If `errorObj` is not
|
|
||||||
undefined, set its `errno` property to the error code or to 0 if
|
|
||||||
no error occurred.
|
|
||||||
|
|
||||||
### `tmpfile(errorObj = undefined)`
|
|
||||||
|
|
||||||
Open a temporary file. Return the FILE
|
|
||||||
object or `null` in case of I/O error. If `errorObj` is not
|
|
||||||
undefined, set its `errno` property to the error code or to 0 if
|
|
||||||
no error occurred.
|
|
||||||
|
|
||||||
### `puts(str)`
|
|
||||||
|
|
||||||
Equivalent to `std.out.puts(str)`.
|
|
||||||
|
|
||||||
### `printf(fmt, ...args)`
|
|
||||||
|
|
||||||
Equivalent to `std.out.printf(fmt, ...args)`.
|
|
||||||
|
|
||||||
### `sprintf(fmt, ...args)`
|
|
||||||
|
|
||||||
Equivalent to the libc sprintf().
|
|
||||||
|
|
||||||
### `in`, `out`, `err`
|
|
||||||
|
|
||||||
Wrappers to the libc file `stdin`, `stdout`, `stderr`.
|
|
||||||
|
|
||||||
### `Error`
|
|
||||||
|
|
||||||
Enumeration object containing the integer value of common errors
|
|
||||||
(additional error codes may be defined):
|
|
||||||
|
|
||||||
- `EINVAL`
|
|
||||||
- `EIO`
|
|
||||||
- `EACCES`
|
|
||||||
- `EEXIST`
|
|
||||||
- `ENOSPC`
|
|
||||||
- `ENOSYS`
|
|
||||||
- `EBUSY`
|
|
||||||
- `ENOENT`
|
|
||||||
- `EPERM`
|
|
||||||
- `EPIPE`
|
|
||||||
|
|
||||||
### `strerror(errno)`
|
|
||||||
|
|
||||||
Return a string that describes the error `errno`.
|
|
||||||
|
|
||||||
### `gc()`
|
|
||||||
|
|
||||||
Manually invoke the cycle removal algorithm. The cycle removal
|
|
||||||
algorithm is automatically started when needed, so this function is
|
|
||||||
useful in case of specific memory constraints or for testing.
|
|
||||||
|
|
||||||
### `getenv(name)`
|
|
||||||
|
|
||||||
Return the value of the environment variable `name` or
|
|
||||||
`undefined` if it is not defined.
|
|
||||||
|
|
||||||
### `setenv(name, value)`
|
|
||||||
|
|
||||||
Set the value of the environment variable `name` to the string
|
|
||||||
`value`.
|
|
||||||
|
|
||||||
### `unsetenv(name)`
|
|
||||||
|
|
||||||
Delete the environment variable `name`.
|
|
||||||
|
|
||||||
### `getenviron()`
|
|
||||||
|
|
||||||
Return an object containing the environment variables as key-value pairs.
|
|
||||||
|
|
||||||
### `urlGet(url, options = undefined)`
|
|
||||||
|
|
||||||
Download `url` using the `curl` command line
|
|
||||||
utility. `options` is an optional object containing the following
|
|
||||||
optional properties:
|
|
||||||
|
|
||||||
- `binary` - Boolean (default = false). If true, the response is an ArrayBuffer
|
|
||||||
instead of a string. When a string is returned, the data is assumed
|
|
||||||
to be UTF-8 encoded.
|
|
||||||
- `full` - Boolean (default = false). If true, return the an object contains
|
|
||||||
the properties `response` (response content),
|
|
||||||
`responseHeaders` (headers separated by CRLF), `status`
|
|
||||||
(status code). `response` is `null` is case of protocol or
|
|
||||||
network error. If `full` is false, only the response is
|
|
||||||
returned if the status is between 200 and 299. Otherwise `null`
|
|
||||||
is returned.
|
|
||||||
|
|
||||||
### `FILE`
|
|
||||||
|
|
||||||
File object.
|
|
||||||
|
|
||||||
#### `close()`
|
|
||||||
|
|
||||||
Close the file. Return 0 if OK or `-errno` in case of I/O error.
|
|
||||||
|
|
||||||
#### `puts(str)`
|
|
||||||
|
|
||||||
Outputs the string with the UTF-8 encoding.
|
|
||||||
|
|
||||||
#### `printf(fmt, ...args)`
|
|
||||||
|
|
||||||
Formatted printf.
|
|
||||||
|
|
||||||
The same formats as the standard C library `printf` are
|
|
||||||
supported. Integer format types (e.g. `%d`) truncate the Numbers
|
|
||||||
or BigInts to 32 bits. Use the `l` modifier (e.g. `%ld`) to
|
|
||||||
truncate to 64 bits.
|
|
||||||
|
|
||||||
#### `flush()`
|
|
||||||
|
|
||||||
Flush the buffered file.
|
|
||||||
|
|
||||||
#### `seek(offset, whence)`
|
|
||||||
|
|
||||||
Seek to a give file position (whence is
|
|
||||||
`std.SEEK_*`). `offset` can be a number or a BigInt. Return
|
|
||||||
0 if OK or `-errno` in case of I/O error.
|
|
||||||
|
|
||||||
- `SEEK_SET`
|
|
||||||
- `SEEK_CUR`
|
|
||||||
- `SEEK_END`
|
|
||||||
|
|
||||||
Constants for seek().
|
|
||||||
|
|
||||||
#### `tell()`
|
|
||||||
|
|
||||||
Return the current file position.
|
|
||||||
|
|
||||||
#### `tello()`
|
|
||||||
|
|
||||||
Return the current file position as a BigInt.
|
|
||||||
|
|
||||||
#### `eof()`
|
|
||||||
|
|
||||||
Return true if end of file.
|
|
||||||
|
|
||||||
#### `fileno()`
|
|
||||||
|
|
||||||
Return the associated OS handle.
|
|
||||||
|
|
||||||
#### `error()`
|
|
||||||
|
|
||||||
Return true if there was an error.
|
|
||||||
|
|
||||||
#### `clearerr()`
|
|
||||||
|
|
||||||
Clear the error indication.
|
|
||||||
|
|
||||||
#### `read(buffer, position, length)`
|
|
||||||
|
|
||||||
Read `length` bytes from the file to the ArrayBuffer `buffer` at byte
|
|
||||||
position `position` (wrapper to the libc `fread`).
|
|
||||||
|
|
||||||
#### `write(buffer, position, length)`
|
|
||||||
|
|
||||||
Write `length` bytes to the file from the ArrayBuffer `buffer` at byte
|
|
||||||
position `position` (wrapper to the libc `fwrite`).
|
|
||||||
|
|
||||||
#### `getline()`
|
|
||||||
|
|
||||||
Return the next line from the file, assuming UTF-8 encoding, excluding
|
|
||||||
the trailing line feed.
|
|
||||||
|
|
||||||
#### `readAsString(max_size = undefined)`
|
|
||||||
|
|
||||||
Read `max_size` bytes from the file and return them as a string
|
|
||||||
assuming UTF-8 encoding. If `max_size` is not present, the file
|
|
||||||
is read up its end.
|
|
||||||
|
|
||||||
#### `getByte()`
|
|
||||||
|
|
||||||
Return the next byte from the file. Return -1 if the end of file is reached.
|
|
||||||
|
|
||||||
#### `putByte(c)`
|
|
||||||
|
|
||||||
Write one byte to the file.
|
|
|
@ -1,18 +0,0 @@
|
||||||
---
|
|
||||||
sidebar_position: 8
|
|
||||||
---
|
|
||||||
|
|
||||||
# Supported Platforms
|
|
||||||
|
|
||||||
| System | Supported versions | Notes |
|
|
||||||
|---|---|---|
|
|
||||||
| GNU/Linux | * | glibc and musl are supported |
|
|
||||||
| macOS | macOS >= 11 | Currently supported macOS releases |
|
|
||||||
| Windows | >= Windows 8 | VS >= 2022 and Clang are supported |
|
|
||||||
| FreeBSD | * | Limited testing |
|
|
||||||
| OpenBSD | * | Limited testing |
|
|
||||||
| NetBSD | * | Limited testing |
|
|
||||||
| Android | NDK >= 26.0.10792818 | Limited testing |
|
|
||||||
| iOS | * | Limited testing |
|
|
||||||
| MinGW | MinGW-w64 | |
|
|
||||||
| Other | N/A | Missing? Open a PR! |
|
|
|
@ -1,114 +0,0 @@
|
||||||
// @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
|
|
||||||
|
|
||||||
/** @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: 'throw',
|
|
||||||
|
|
||||||
// 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-NG',
|
|
||||||
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: [
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
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: {
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
};
|
|
||||||
|
|
||||||
export default config;
|
|
14656
docs/package-lock.json
generated
14656
docs/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -1,42 +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.5.2",
|
|
||||||
"@docusaurus/preset-classic": "3.5.2",
|
|
||||||
"@mdx-js/react": "3.0.1",
|
|
||||||
"clsx": "2.1.1",
|
|
||||||
"prism-react-renderer": "2.4.0",
|
|
||||||
"react": "18.3.1",
|
|
||||||
"react-dom": "18.3.1"
|
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"@docusaurus/module-type-aliases": "3.5.2",
|
|
||||||
"@docusaurus/types": "3.5.2"
|
|
||||||
},
|
|
||||||
"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"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
/**
|
|
||||||
* 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;
|
|
|
@ -1,30 +0,0 @@
|
||||||
/**
|
|
||||||
* 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);
|
|
||||||
}
|
|
BIN
docs/static/img/favicon.ico
vendored
BIN
docs/static/img/favicon.ico
vendored
Binary file not shown.
Before Width: | Height: | Size: 3.5 KiB |
|
@ -35,8 +35,8 @@ static int fib(int n)
|
||||||
return fib(n - 1) + fib(n - 2);
|
return fib(n - 1) + fib(n - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_fib(JSContext *ctx, JSValue this_val,
|
static JSValue js_fib(JSContext *ctx, JSValueConst this_val,
|
||||||
int argc, JSValue *argv)
|
int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
int n, res;
|
int n, res;
|
||||||
if (JS_ToInt32(ctx, &n, argv[0]))
|
if (JS_ToInt32(ctx, &n, argv[0]))
|
||||||
|
@ -61,15 +61,7 @@ static int js_fib_init(JSContext *ctx, JSModuleDef *m)
|
||||||
#define JS_INIT_MODULE js_init_module_fib
|
#define JS_INIT_MODULE js_init_module_fib
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef JS_EXTERN
|
JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name)
|
||||||
#ifdef _WIN32
|
|
||||||
#define JS_EXTERN __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define JS_EXTERN
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
JS_EXTERN JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name)
|
|
||||||
{
|
{
|
||||||
JSModuleDef *m;
|
JSModuleDef *m;
|
||||||
m = JS_NewCModule(ctx, module_name, js_fib_init);
|
m = JS_NewCModule(ctx, module_name, js_fib_init);
|
||||||
|
|
68
examples/pi_bigdecimal.js
Normal file
68
examples/pi_bigdecimal.js
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* PI computation in Javascript using the QuickJS bigdecimal type
|
||||||
|
* (decimal floating point)
|
||||||
|
*/
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/* compute PI with a precision of 'prec' digits */
|
||||||
|
function calc_pi(prec) {
|
||||||
|
const CHUD_A = 13591409m;
|
||||||
|
const CHUD_B = 545140134m;
|
||||||
|
const CHUD_C = 640320m;
|
||||||
|
const CHUD_C3 = 10939058860032000m; /* C^3/24 */
|
||||||
|
const CHUD_DIGITS_PER_TERM = 14.18164746272548; /* log10(C/12)*3 */
|
||||||
|
|
||||||
|
/* return [P, Q, G] */
|
||||||
|
function chud_bs(a, b, need_G) {
|
||||||
|
var c, P, Q, G, P1, Q1, G1, P2, Q2, G2, b1;
|
||||||
|
if (a == (b - 1n)) {
|
||||||
|
b1 = BigDecimal(b);
|
||||||
|
G = (2m * b1 - 1m) * (6m * b1 - 1m) * (6m * b1 - 5m);
|
||||||
|
P = G * (CHUD_B * b1 + CHUD_A);
|
||||||
|
if (b & 1n)
|
||||||
|
P = -P;
|
||||||
|
G = G;
|
||||||
|
Q = b1 * b1 * b1 * CHUD_C3;
|
||||||
|
} else {
|
||||||
|
c = (a + b) >> 1n;
|
||||||
|
[P1, Q1, G1] = chud_bs(a, c, true);
|
||||||
|
[P2, Q2, G2] = chud_bs(c, b, need_G);
|
||||||
|
P = P1 * Q2 + P2 * G1;
|
||||||
|
Q = Q1 * Q2;
|
||||||
|
if (need_G)
|
||||||
|
G = G1 * G2;
|
||||||
|
else
|
||||||
|
G = 0m;
|
||||||
|
}
|
||||||
|
return [P, Q, G];
|
||||||
|
}
|
||||||
|
|
||||||
|
var n, P, Q, G;
|
||||||
|
/* number of serie terms */
|
||||||
|
n = BigInt(Math.ceil(prec / CHUD_DIGITS_PER_TERM)) + 10n;
|
||||||
|
[P, Q, G] = chud_bs(0n, n, false);
|
||||||
|
Q = BigDecimal.div(Q, (P + Q * CHUD_A),
|
||||||
|
{ roundingMode: "half-even",
|
||||||
|
maximumSignificantDigits: prec });
|
||||||
|
G = (CHUD_C / 12m) * BigDecimal.sqrt(CHUD_C,
|
||||||
|
{ roundingMode: "half-even",
|
||||||
|
maximumSignificantDigits: prec });
|
||||||
|
return Q * G;
|
||||||
|
}
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var r, n_digits, n_bits;
|
||||||
|
if (typeof scriptArgs != "undefined") {
|
||||||
|
if (scriptArgs.length < 2) {
|
||||||
|
print("usage: pi n_digits");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
n_digits = scriptArgs[1] | 0;
|
||||||
|
} else {
|
||||||
|
n_digits = 1000;
|
||||||
|
}
|
||||||
|
/* we add more digits to reduce the probability of bad rounding for
|
||||||
|
the last digits */
|
||||||
|
r = calc_pi(n_digits + 20);
|
||||||
|
print(r.toFixed(n_digits, "down"));
|
||||||
|
})();
|
66
examples/pi_bigfloat.js
Normal file
66
examples/pi_bigfloat.js
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
/*
|
||||||
|
* PI computation in Javascript using the QuickJS bigfloat type
|
||||||
|
* (binary floating point)
|
||||||
|
*/
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
/* compute PI with a precision of 'prec' bits */
|
||||||
|
function calc_pi() {
|
||||||
|
const CHUD_A = 13591409n;
|
||||||
|
const CHUD_B = 545140134n;
|
||||||
|
const CHUD_C = 640320n;
|
||||||
|
const CHUD_C3 = 10939058860032000n; /* C^3/24 */
|
||||||
|
const CHUD_BITS_PER_TERM = 47.11041313821584202247; /* log2(C/12)*3 */
|
||||||
|
|
||||||
|
/* return [P, Q, G] */
|
||||||
|
function chud_bs(a, b, need_G) {
|
||||||
|
var c, P, Q, G, P1, Q1, G1, P2, Q2, G2;
|
||||||
|
if (a == (b - 1n)) {
|
||||||
|
G = (2n * b - 1n) * (6n * b - 1n) * (6n * b - 5n);
|
||||||
|
P = BigFloat(G * (CHUD_B * b + CHUD_A));
|
||||||
|
if (b & 1n)
|
||||||
|
P = -P;
|
||||||
|
G = BigFloat(G);
|
||||||
|
Q = BigFloat(b * b * b * CHUD_C3);
|
||||||
|
} else {
|
||||||
|
c = (a + b) >> 1n;
|
||||||
|
[P1, Q1, G1] = chud_bs(a, c, true);
|
||||||
|
[P2, Q2, G2] = chud_bs(c, b, need_G);
|
||||||
|
P = P1 * Q2 + P2 * G1;
|
||||||
|
Q = Q1 * Q2;
|
||||||
|
if (need_G)
|
||||||
|
G = G1 * G2;
|
||||||
|
else
|
||||||
|
G = 0l;
|
||||||
|
}
|
||||||
|
return [P, Q, G];
|
||||||
|
}
|
||||||
|
|
||||||
|
var n, P, Q, G;
|
||||||
|
/* number of serie terms */
|
||||||
|
n = BigInt(Math.ceil(BigFloatEnv.prec / CHUD_BITS_PER_TERM)) + 10n;
|
||||||
|
[P, Q, G] = chud_bs(0n, n, false);
|
||||||
|
Q = Q / (P + Q * BigFloat(CHUD_A));
|
||||||
|
G = BigFloat((CHUD_C / 12n)) * BigFloat.sqrt(BigFloat(CHUD_C));
|
||||||
|
return Q * G;
|
||||||
|
}
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
var r, n_digits, n_bits;
|
||||||
|
if (typeof scriptArgs != "undefined") {
|
||||||
|
if (scriptArgs.length < 2) {
|
||||||
|
print("usage: pi n_digits");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
n_digits = scriptArgs[1];
|
||||||
|
} else {
|
||||||
|
n_digits = 1000;
|
||||||
|
}
|
||||||
|
n_bits = Math.ceil(n_digits * Math.log2(10));
|
||||||
|
/* we add more bits to reduce the probability of bad rounding for
|
||||||
|
the last digits */
|
||||||
|
BigFloatEnv.setPrec( () => {
|
||||||
|
r = calc_pi();
|
||||||
|
print(r.toFixed(n_digits, BigFloatEnv.RNDZ));
|
||||||
|
}, n_bits + 32);
|
||||||
|
})();
|
|
@ -43,8 +43,8 @@ static void js_point_finalizer(JSRuntime *rt, JSValue val)
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_point_ctor(JSContext *ctx,
|
static JSValue js_point_ctor(JSContext *ctx,
|
||||||
JSValue new_target,
|
JSValueConst new_target,
|
||||||
int argc, JSValue *argv)
|
int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
JSPointData *s;
|
JSPointData *s;
|
||||||
JSValue obj = JS_UNDEFINED;
|
JSValue obj = JS_UNDEFINED;
|
||||||
|
@ -74,7 +74,7 @@ static JSValue js_point_ctor(JSContext *ctx,
|
||||||
return JS_EXCEPTION;
|
return JS_EXCEPTION;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_point_get_xy(JSContext *ctx, JSValue this_val, int magic)
|
static JSValue js_point_get_xy(JSContext *ctx, JSValueConst this_val, int magic)
|
||||||
{
|
{
|
||||||
JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id);
|
JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id);
|
||||||
if (!s)
|
if (!s)
|
||||||
|
@ -85,7 +85,7 @@ static JSValue js_point_get_xy(JSContext *ctx, JSValue this_val, int magic)
|
||||||
return JS_NewInt32(ctx, s->y);
|
return JS_NewInt32(ctx, s->y);
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_point_set_xy(JSContext *ctx, JSValue this_val, JSValue val, int magic)
|
static JSValue js_point_set_xy(JSContext *ctx, JSValueConst this_val, JSValue val, int magic)
|
||||||
{
|
{
|
||||||
JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id);
|
JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id);
|
||||||
int v;
|
int v;
|
||||||
|
@ -100,8 +100,8 @@ static JSValue js_point_set_xy(JSContext *ctx, JSValue this_val, JSValue val, in
|
||||||
return JS_UNDEFINED;
|
return JS_UNDEFINED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static JSValue js_point_norm(JSContext *ctx, JSValue this_val,
|
static JSValue js_point_norm(JSContext *ctx, JSValueConst this_val,
|
||||||
int argc, JSValue *argv)
|
int argc, JSValueConst *argv)
|
||||||
{
|
{
|
||||||
JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id);
|
JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id);
|
||||||
if (!s)
|
if (!s)
|
||||||
|
@ -123,11 +123,10 @@ static const JSCFunctionListEntry js_point_proto_funcs[] = {
|
||||||
static int js_point_init(JSContext *ctx, JSModuleDef *m)
|
static int js_point_init(JSContext *ctx, JSModuleDef *m)
|
||||||
{
|
{
|
||||||
JSValue point_proto, point_class;
|
JSValue point_proto, point_class;
|
||||||
JSRuntime *rt = JS_GetRuntime(ctx);
|
|
||||||
|
|
||||||
/* create the Point class */
|
/* create the Point class */
|
||||||
JS_NewClassID(rt, &js_point_class_id);
|
JS_NewClassID(&js_point_class_id);
|
||||||
JS_NewClass(rt, js_point_class_id, &js_point_class);
|
JS_NewClass(JS_GetRuntime(ctx), js_point_class_id, &js_point_class);
|
||||||
|
|
||||||
point_proto = JS_NewObject(ctx);
|
point_proto = JS_NewObject(ctx);
|
||||||
JS_SetPropertyFunctionList(ctx, point_proto, js_point_proto_funcs, countof(js_point_proto_funcs));
|
JS_SetPropertyFunctionList(ctx, point_proto, js_point_proto_funcs, countof(js_point_proto_funcs));
|
||||||
|
@ -141,15 +140,7 @@ static int js_point_init(JSContext *ctx, JSModuleDef *m)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef JS_EXTERN
|
JSModuleDef *js_init_module(JSContext *ctx, const char *module_name)
|
||||||
#ifdef _WIN32
|
|
||||||
#define JS_EXTERN __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define JS_EXTERN
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
JS_EXTERN JSModuleDef *js_init_module(JSContext *ctx, const char *module_name)
|
|
||||||
{
|
{
|
||||||
JSModuleDef *m;
|
JSModuleDef *m;
|
||||||
m = JS_NewCModule(ctx, module_name, js_point_init);
|
m = JS_NewCModule(ctx, module_name, js_point_init);
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
/* example of JS module importing a C module */
|
/* example of JS module importing a C module */
|
||||||
import * as os from "qjs:os";
|
|
||||||
|
|
||||||
const isWin = os.platform === 'win32';
|
import { fib } from "./fib.so";
|
||||||
const { fib } = await import(`./fib.${isWin ? 'dll' : 'so'}`);
|
|
||||||
|
|
||||||
console.log("Hello World");
|
console.log("Hello World");
|
||||||
console.log("fib(10)=", fib(10));
|
console.log("fib(10)=", fib(10));
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
/* example of JS module importing a C module */
|
/* example of JS module importing a C module */
|
||||||
import * as os from "qjs:os";
|
import { Point } from "./point.so";
|
||||||
|
|
||||||
const isWin = os.platform === 'win32';
|
|
||||||
const { Point } = await import(`./point.${isWin ? 'dll' : 'so'}`);
|
|
||||||
|
|
||||||
function assert(b, str)
|
function assert(b, str)
|
||||||
{
|
{
|
||||||
|
|
23
fuzz.c
23
fuzz.c
|
@ -1,23 +0,0 @@
|
||||||
// clang -g -O1 -fsanitize=fuzzer -o fuzz fuzz.c
|
|
||||||
#include "quickjs.h"
|
|
||||||
#include "quickjs.c"
|
|
||||||
#include "cutils.c"
|
|
||||||
#include "libbf.c"
|
|
||||||
#include "libregexp.c"
|
|
||||||
#include "libunicode.c"
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
|
|
||||||
{
|
|
||||||
JSRuntime *rt = JS_NewRuntime();
|
|
||||||
if (!rt)
|
|
||||||
exit(1);
|
|
||||||
JSContext *ctx = JS_NewContext(rt);
|
|
||||||
if (!ctx)
|
|
||||||
exit(1);
|
|
||||||
JSValueConst val = JS_ReadObject(ctx, buf, len, /*flags*/0);
|
|
||||||
JS_FreeValue(ctx, val);
|
|
||||||
JS_FreeContext(ctx);
|
|
||||||
JS_FreeRuntime(rt);
|
|
||||||
return 0;
|
|
||||||
}
|
|
27
fuzz/README
Normal file
27
fuzz/README
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
libFuzzer support for QuickJS
|
||||||
|
=============================
|
||||||
|
|
||||||
|
Build QuickJS with libFuzzer support as follows:
|
||||||
|
|
||||||
|
CONFIG_CLANG=y make libfuzzer
|
||||||
|
|
||||||
|
This can be extended with sanitizer support to improve efficacy:
|
||||||
|
|
||||||
|
CONFIG_CLANG=y CONFIG_ASAN=y make libfuzzer
|
||||||
|
|
||||||
|
|
||||||
|
Currently, there are three fuzzing targets defined: fuzz_eval, fuzz_compile and fuzz_regexp.
|
||||||
|
The above build command will produce an executable binary for each of them, which can be
|
||||||
|
simply executed as:
|
||||||
|
|
||||||
|
./fuzz_eval
|
||||||
|
|
||||||
|
or with an initial corpus:
|
||||||
|
|
||||||
|
./fuzz_compile corpus_dir/
|
||||||
|
|
||||||
|
or with a predefined dictionary to improve its efficacy:
|
||||||
|
|
||||||
|
./fuzz_eval -dict fuzz/fuzz.dict
|
||||||
|
|
||||||
|
or with arbitrary CLI arguments provided by libFuzzer (https://llvm.org/docs/LibFuzzer.html).
|
257
fuzz/fuzz.dict
Normal file
257
fuzz/fuzz.dict
Normal file
|
@ -0,0 +1,257 @@
|
||||||
|
"__loadScript"
|
||||||
|
"abs"
|
||||||
|
"acos"
|
||||||
|
"acosh"
|
||||||
|
"add"
|
||||||
|
"AggregateError"
|
||||||
|
"and"
|
||||||
|
"apply"
|
||||||
|
"Array"
|
||||||
|
"ArrayBuffer"
|
||||||
|
"asin"
|
||||||
|
"asinh"
|
||||||
|
"atan"
|
||||||
|
"atan2"
|
||||||
|
"atanh"
|
||||||
|
"Atomics"
|
||||||
|
"BigDecimal"
|
||||||
|
"BigFloat"
|
||||||
|
"BigFloatEnv"
|
||||||
|
"BigInt"
|
||||||
|
"BigInt64Array"
|
||||||
|
"BigUint64Array"
|
||||||
|
"Boolean"
|
||||||
|
"cbrt"
|
||||||
|
"ceil"
|
||||||
|
"chdir"
|
||||||
|
"clearTimeout"
|
||||||
|
"close"
|
||||||
|
"clz32"
|
||||||
|
"compareExchange"
|
||||||
|
"console"
|
||||||
|
"construct"
|
||||||
|
"cos"
|
||||||
|
"cosh"
|
||||||
|
"DataView"
|
||||||
|
"Date"
|
||||||
|
"decodeURI"
|
||||||
|
"decodeURIComponent"
|
||||||
|
"defineProperty"
|
||||||
|
"deleteProperty"
|
||||||
|
"dup"
|
||||||
|
"dup2"
|
||||||
|
"E"
|
||||||
|
"encodeURI"
|
||||||
|
"encodeURIComponent"
|
||||||
|
"err"
|
||||||
|
"Error"
|
||||||
|
"escape"
|
||||||
|
"eval"
|
||||||
|
"EvalError"
|
||||||
|
"evalScript"
|
||||||
|
"exchange"
|
||||||
|
"exec"
|
||||||
|
"exit"
|
||||||
|
"exp"
|
||||||
|
"expm1"
|
||||||
|
"fdopen"
|
||||||
|
"Float32Array"
|
||||||
|
"Float64Array"
|
||||||
|
"floor"
|
||||||
|
"fround"
|
||||||
|
"Function"
|
||||||
|
"gc"
|
||||||
|
"get"
|
||||||
|
"getcwd"
|
||||||
|
"getenv"
|
||||||
|
"getenviron"
|
||||||
|
"getOwnPropertyDescriptor"
|
||||||
|
"getpid"
|
||||||
|
"getPrototypeOf"
|
||||||
|
"globalThis"
|
||||||
|
"has"
|
||||||
|
"hypot"
|
||||||
|
"imul"
|
||||||
|
"in"
|
||||||
|
"Infinity"
|
||||||
|
"Int16Array"
|
||||||
|
"Int32Array"
|
||||||
|
"Int8Array"
|
||||||
|
"InternalError"
|
||||||
|
"isatty"
|
||||||
|
"isExtensible"
|
||||||
|
"isFinite"
|
||||||
|
"isLockFree"
|
||||||
|
"isNaN"
|
||||||
|
"iterateBuiltIns"
|
||||||
|
"JSON"
|
||||||
|
"kill"
|
||||||
|
"length"
|
||||||
|
"LN10"
|
||||||
|
"LN2"
|
||||||
|
"load"
|
||||||
|
"loadFile"
|
||||||
|
"loadScript"
|
||||||
|
"log"
|
||||||
|
"log10"
|
||||||
|
"LOG10E"
|
||||||
|
"log1p"
|
||||||
|
"log2"
|
||||||
|
"LOG2E"
|
||||||
|
"lstat"
|
||||||
|
"Map"
|
||||||
|
"Math"
|
||||||
|
"max"
|
||||||
|
"min"
|
||||||
|
"mkdir"
|
||||||
|
"NaN"
|
||||||
|
"notify"
|
||||||
|
"now"
|
||||||
|
"Number"
|
||||||
|
"O_APPEND"
|
||||||
|
"O_CREAT"
|
||||||
|
"O_EXCL"
|
||||||
|
"O_RDONLY"
|
||||||
|
"O_RDWR"
|
||||||
|
"O_TRUNC"
|
||||||
|
"O_WRONLY"
|
||||||
|
"Object"
|
||||||
|
"open"
|
||||||
|
"Operators"
|
||||||
|
"or"
|
||||||
|
"os"
|
||||||
|
"out"
|
||||||
|
"ownKeys"
|
||||||
|
"parse"
|
||||||
|
"parseExtJSON"
|
||||||
|
"parseFloat"
|
||||||
|
"parseInt"
|
||||||
|
"PI"
|
||||||
|
"pipe"
|
||||||
|
"platform"
|
||||||
|
"popen"
|
||||||
|
"pow"
|
||||||
|
"preventExtensions"
|
||||||
|
"print"
|
||||||
|
"printf"
|
||||||
|
"Promise"
|
||||||
|
"Proxy"
|
||||||
|
"puts"
|
||||||
|
"random"
|
||||||
|
"RangeError"
|
||||||
|
"read"
|
||||||
|
"readdir"
|
||||||
|
"readlink"
|
||||||
|
"realpath"
|
||||||
|
"ReferenceError"
|
||||||
|
"Reflect"
|
||||||
|
"RegExp"
|
||||||
|
"remove"
|
||||||
|
"rename"
|
||||||
|
"round"
|
||||||
|
"S_IFBLK"
|
||||||
|
"S_IFCHR"
|
||||||
|
"S_IFDIR"
|
||||||
|
"S_IFIFO"
|
||||||
|
"S_IFLNK"
|
||||||
|
"S_IFMT"
|
||||||
|
"S_IFREG"
|
||||||
|
"S_IFSOCK"
|
||||||
|
"S_ISGID"
|
||||||
|
"S_ISUID"
|
||||||
|
"scriptArgs"
|
||||||
|
"seek"
|
||||||
|
"SEEK_CUR"
|
||||||
|
"SEEK_END"
|
||||||
|
"SEEK_SET"
|
||||||
|
"set"
|
||||||
|
"Set"
|
||||||
|
"setenv"
|
||||||
|
"setPrototypeOf"
|
||||||
|
"setReadHandler"
|
||||||
|
"setTimeout"
|
||||||
|
"setWriteHandler"
|
||||||
|
"SharedArrayBuffer"
|
||||||
|
"SIGABRT"
|
||||||
|
"SIGALRM"
|
||||||
|
"SIGCHLD"
|
||||||
|
"SIGCONT"
|
||||||
|
"SIGFPE"
|
||||||
|
"SIGILL"
|
||||||
|
"SIGINT"
|
||||||
|
"sign"
|
||||||
|
"signal"
|
||||||
|
"SIGPIPE"
|
||||||
|
"SIGQUIT"
|
||||||
|
"SIGSEGV"
|
||||||
|
"SIGSTOP"
|
||||||
|
"SIGTERM"
|
||||||
|
"SIGTSTP"
|
||||||
|
"SIGTTIN"
|
||||||
|
"SIGTTOU"
|
||||||
|
"SIGUSR1"
|
||||||
|
"SIGUSR2"
|
||||||
|
"sin"
|
||||||
|
"sinh"
|
||||||
|
"sleep"
|
||||||
|
"sleepAsync"
|
||||||
|
"sprintf"
|
||||||
|
"sqrt"
|
||||||
|
"SQRT1_2"
|
||||||
|
"SQRT2"
|
||||||
|
"stat"
|
||||||
|
"std"
|
||||||
|
"store"
|
||||||
|
"strerror"
|
||||||
|
"String"
|
||||||
|
"stringify"
|
||||||
|
"sub"
|
||||||
|
"Symbol"
|
||||||
|
"symlink"
|
||||||
|
"SyntaxError"
|
||||||
|
"tan"
|
||||||
|
"tanh"
|
||||||
|
"tmpfile"
|
||||||
|
"trunc"
|
||||||
|
"ttyGetWinSize"
|
||||||
|
"ttySetRaw"
|
||||||
|
"TypeError"
|
||||||
|
"Uint16Array"
|
||||||
|
"Uint32Array"
|
||||||
|
"Uint8Array"
|
||||||
|
"Uint8ClampedArray"
|
||||||
|
"undefined"
|
||||||
|
"unescape"
|
||||||
|
"unsetenv"
|
||||||
|
"URIError"
|
||||||
|
"urlGet"
|
||||||
|
"utimes"
|
||||||
|
"wait"
|
||||||
|
"waitpid"
|
||||||
|
"WeakMap"
|
||||||
|
"WeakSet"
|
||||||
|
"WNOHANG"
|
||||||
|
"Worker"
|
||||||
|
"write"
|
||||||
|
"xor"
|
||||||
|
"v0"
|
||||||
|
"v1"
|
||||||
|
"v2"
|
||||||
|
"v3"
|
||||||
|
"v4"
|
||||||
|
"v5"
|
||||||
|
"v6"
|
||||||
|
"v7"
|
||||||
|
"v8"
|
||||||
|
"v9"
|
||||||
|
"v10"
|
||||||
|
"v11"
|
||||||
|
"v12"
|
||||||
|
"v13"
|
||||||
|
"v14"
|
||||||
|
"v15"
|
||||||
|
"v16"
|
||||||
|
"v17"
|
||||||
|
"v18"
|
||||||
|
"v19"
|
||||||
|
"v20"
|
62
fuzz/fuzz_common.c
Normal file
62
fuzz/fuzz_common.c
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/* Copyright 2020 Google Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "fuzz/fuzz_common.h"
|
||||||
|
|
||||||
|
// handle timeouts from infinite loops
|
||||||
|
static int interrupt_handler(JSRuntime *rt, void *opaque)
|
||||||
|
{
|
||||||
|
nbinterrupts++;
|
||||||
|
return (nbinterrupts > 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset_nbinterrupts() {
|
||||||
|
nbinterrupts = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void test_one_input_init(JSRuntime *rt, JSContext *ctx) {
|
||||||
|
// 64 Mo
|
||||||
|
JS_SetMemoryLimit(rt, 0x4000000);
|
||||||
|
// 64 Kb
|
||||||
|
JS_SetMaxStackSize(rt, 0x10000);
|
||||||
|
|
||||||
|
JS_AddIntrinsicBigFloat(ctx);
|
||||||
|
JS_AddIntrinsicBigDecimal(ctx);
|
||||||
|
JS_AddIntrinsicOperators(ctx);
|
||||||
|
JS_EnableBignumExt(ctx, 1);
|
||||||
|
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
|
||||||
|
JS_SetInterruptHandler(JS_GetRuntime(ctx), interrupt_handler, NULL);
|
||||||
|
js_std_add_helpers(ctx, 0, NULL);
|
||||||
|
|
||||||
|
// Load os and std
|
||||||
|
js_std_init_handlers(rt);
|
||||||
|
js_init_module_std(ctx, "std");
|
||||||
|
js_init_module_os(ctx, "os");
|
||||||
|
const char *str = "import * as std from 'std';\n"
|
||||||
|
"import * as os from 'os';\n"
|
||||||
|
"globalThis.std = std;\n"
|
||||||
|
"globalThis.os = os;\n";
|
||||||
|
JSValue std_val = JS_Eval(ctx, str, strlen(str), "<input>", JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
|
||||||
|
if (!JS_IsException(std_val)) {
|
||||||
|
js_module_set_import_meta(ctx, std_val, 1, 1);
|
||||||
|
std_val = JS_EvalFunction(ctx, std_val);
|
||||||
|
} else {
|
||||||
|
js_std_dump_error(ctx);
|
||||||
|
}
|
||||||
|
std_val = js_std_await(ctx, std_val);
|
||||||
|
JS_FreeValue(ctx, std_val);
|
||||||
|
}
|
22
fuzz/fuzz_common.h
Normal file
22
fuzz/fuzz_common.h
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
/* Copyright 2020 Google Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "quickjs.h"
|
||||||
|
#include "quickjs-libc.h"
|
||||||
|
|
||||||
|
static int nbinterrupts = 0;
|
||||||
|
|
||||||
|
void reset_nbinterrupts();
|
||||||
|
void test_one_input_init(JSRuntime *rt, JSContext *ctx);
|
93
fuzz/fuzz_compile.c
Normal file
93
fuzz/fuzz_compile.c
Normal file
|
@ -0,0 +1,93 @@
|
||||||
|
/* Copyright 2020 Google Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "quickjs.h"
|
||||||
|
#include "quickjs-libc.h"
|
||||||
|
#include "cutils.h"
|
||||||
|
#include "fuzz/fuzz_common.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
JSRuntime *rt = JS_NewRuntime();
|
||||||
|
JSContext *ctx = JS_NewContext(rt);
|
||||||
|
test_one_input_init(rt, ctx);
|
||||||
|
|
||||||
|
uint8_t *null_terminated_data = malloc(size + 1);
|
||||||
|
memcpy(null_terminated_data, data, size);
|
||||||
|
null_terminated_data[size] = 0;
|
||||||
|
|
||||||
|
JSValue obj = JS_Eval(ctx, (const char *)null_terminated_data, size, "<none>", JS_EVAL_FLAG_COMPILE_ONLY | JS_EVAL_TYPE_MODULE);
|
||||||
|
free(null_terminated_data);
|
||||||
|
//TODO target with JS_ParseJSON
|
||||||
|
if (JS_IsException(obj)) {
|
||||||
|
js_std_free_handlers(rt);
|
||||||
|
JS_FreeValue(ctx, obj);
|
||||||
|
JS_FreeContext(ctx);
|
||||||
|
JS_FreeRuntime(rt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
obj = js_std_await(ctx, obj);
|
||||||
|
size_t bytecode_size;
|
||||||
|
uint8_t* bytecode = JS_WriteObject(ctx, &bytecode_size, obj, JS_WRITE_OBJ_BYTECODE);
|
||||||
|
JS_FreeValue(ctx, obj);
|
||||||
|
if (!bytecode) {
|
||||||
|
js_std_free_handlers(rt);
|
||||||
|
JS_FreeContext(ctx);
|
||||||
|
JS_FreeRuntime(rt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
obj = JS_ReadObject(ctx, bytecode, bytecode_size, JS_READ_OBJ_BYTECODE);
|
||||||
|
js_free(ctx, bytecode);
|
||||||
|
if (JS_IsException(obj)) {
|
||||||
|
js_std_free_handlers(rt);
|
||||||
|
JS_FreeContext(ctx);
|
||||||
|
JS_FreeRuntime(rt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
reset_nbinterrupts();
|
||||||
|
/* this is based on
|
||||||
|
* js_std_eval_binary(ctx, bytecode, bytecode_size, 0);
|
||||||
|
* modified so as not to exit on JS exception
|
||||||
|
*/
|
||||||
|
JSValue val;
|
||||||
|
if (JS_VALUE_GET_TAG(obj) == JS_TAG_MODULE) {
|
||||||
|
if (JS_ResolveModule(ctx, obj) < 0) {
|
||||||
|
JS_FreeValue(ctx, obj);
|
||||||
|
js_std_free_handlers(rt);
|
||||||
|
JS_FreeContext(ctx);
|
||||||
|
JS_FreeRuntime(rt);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
js_module_set_import_meta(ctx, obj, FALSE, TRUE);
|
||||||
|
}
|
||||||
|
val = JS_EvalFunction(ctx, obj);
|
||||||
|
if (JS_IsException(val)) {
|
||||||
|
js_std_dump_error(ctx);
|
||||||
|
} else {
|
||||||
|
js_std_loop(ctx);
|
||||||
|
}
|
||||||
|
JS_FreeValue(ctx, val);
|
||||||
|
js_std_free_handlers(rt);
|
||||||
|
JS_FreeContext(ctx);
|
||||||
|
JS_FreeRuntime(rt);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
49
fuzz/fuzz_eval.c
Normal file
49
fuzz/fuzz_eval.c
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
/* Copyright 2020 Google Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "quickjs.h"
|
||||||
|
#include "quickjs-libc.h"
|
||||||
|
#include "fuzz/fuzz_common.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
if (size == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
JSRuntime *rt = JS_NewRuntime();
|
||||||
|
JSContext *ctx = JS_NewContext(rt);
|
||||||
|
test_one_input_init(rt, ctx);
|
||||||
|
|
||||||
|
uint8_t *null_terminated_data = malloc(size + 1);
|
||||||
|
memcpy(null_terminated_data, data, size);
|
||||||
|
null_terminated_data[size] = 0;
|
||||||
|
|
||||||
|
reset_nbinterrupts();
|
||||||
|
//the final 0 does not count (as in strlen)
|
||||||
|
JSValue val = JS_Eval(ctx, (const char *)null_terminated_data, size, "<none>", JS_EVAL_TYPE_GLOBAL);
|
||||||
|
free(null_terminated_data);
|
||||||
|
//TODO targets with JS_ParseJSON, JS_ReadObject
|
||||||
|
if (!JS_IsException(val)) {
|
||||||
|
js_std_loop(ctx);
|
||||||
|
JS_FreeValue(ctx, val);
|
||||||
|
}
|
||||||
|
js_std_free_handlers(rt);
|
||||||
|
JS_FreeContext(ctx);
|
||||||
|
JS_FreeRuntime(rt);
|
||||||
|
return 0;
|
||||||
|
}
|
59
fuzz/fuzz_regexp.c
Normal file
59
fuzz/fuzz_regexp.c
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
/* Copyright 2020 Google Inc.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libregexp.h"
|
||||||
|
#include "quickjs-libc.h"
|
||||||
|
|
||||||
|
|
||||||
|
int lre_check_stack_overflow(void *opaque, size_t alloca_size) { return 0; }
|
||||||
|
|
||||||
|
void *lre_realloc(void *opaque, void *ptr, size_t size)
|
||||||
|
{
|
||||||
|
return realloc(ptr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
|
||||||
|
int len, ret, i;
|
||||||
|
uint8_t *bc;
|
||||||
|
char error_msg[64];
|
||||||
|
const uint8_t *input;
|
||||||
|
uint8_t *capture[255 * 2];
|
||||||
|
size_t size1 = size;
|
||||||
|
|
||||||
|
//Splits buffer into 2 sub buffers delimited by null character
|
||||||
|
for (i = 0; i < size; i++) {
|
||||||
|
if (data[i] == 0) {
|
||||||
|
size1 = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (size1 == size) {
|
||||||
|
//missing delimiter
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
bc = lre_compile(&len, error_msg, sizeof(error_msg), (const char *) data,
|
||||||
|
size1, 0, NULL);
|
||||||
|
if (!bc) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
input = data + size1 + 1;
|
||||||
|
ret = lre_exec(capture, bc, input, 0, size - (size1 + 1), 0, NULL);
|
||||||
|
if (ret == 1) {
|
||||||
|
lre_get_capture_count(bc);
|
||||||
|
}
|
||||||
|
free(bc);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
24
fuzz/generate_dict.js
Normal file
24
fuzz/generate_dict.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
// Function to recursively iterate through built-in names.
|
||||||
|
function collectBuiltinNames(obj, visited = new Set(), result = new Set()) {
|
||||||
|
// Check if the object has already been visited to avoid infinite recursion.
|
||||||
|
if (visited.has(obj))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Add the current object to the set of visited objects
|
||||||
|
visited.add(obj);
|
||||||
|
// Get the property names of the current object
|
||||||
|
const properties = Object.getOwnPropertyNames(obj);
|
||||||
|
// Iterate through each property
|
||||||
|
for (var i=0; i < properties.length; i++) {
|
||||||
|
var property = properties[i];
|
||||||
|
if (property != "collectBuiltinNames" && typeof property != "number")
|
||||||
|
result.add(property);
|
||||||
|
// Check if the property is an object and if so, recursively iterate through its properties.
|
||||||
|
if (typeof obj[property] === 'object' && obj[property] !== null)
|
||||||
|
collectBuiltinNames(obj[property], visited, result);
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Start the recursive iteration with the global object.
|
||||||
|
console.log(Array.from(collectBuiltinNames(this)).join('\n'));
|
|
@ -1,79 +0,0 @@
|
||||||
/* File generated automatically by the QuickJS-ng compiler. */
|
|
||||||
|
|
||||||
#include "quickjs-libc.h"
|
|
||||||
|
|
||||||
const uint32_t qjsc_function_source_size = 320;
|
|
||||||
|
|
||||||
const uint8_t qjsc_function_source[320] = {
|
|
||||||
0x13, 0x05, 0x01, 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, 0x01, 0x0c, 0x61, 0x63,
|
|
||||||
0x74, 0x75, 0x61, 0x6c, 0x01, 0x02, 0x66, 0x01,
|
|
||||||
0x0c, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x01,
|
|
||||||
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, 0x0d, 0xc0, 0x03, 0x00, 0x00,
|
|
||||||
0x00, 0x00, 0x00, 0x0c, 0x20, 0xfa, 0x01, 0xa2,
|
|
||||||
0x01, 0x00, 0x05, 0x00, 0x03, 0x02, 0x01, 0x74,
|
|
||||||
0x05, 0xc2, 0x03, 0x02, 0x00, 0x30, 0xc4, 0x03,
|
|
||||||
0x04, 0x00, 0x70, 0xc2, 0x03, 0x04, 0x02, 0x70,
|
|
||||||
0x10, 0x00, 0x01, 0x00, 0xe4, 0x01, 0x00, 0x01,
|
|
||||||
0x00, 0xc6, 0x03, 0x00, 0x0d, 0xc4, 0x03, 0x01,
|
|
||||||
0x01, 0x0c, 0x43, 0xfa, 0x01, 0xc4, 0x03, 0x00,
|
|
||||||
0x00, 0x00, 0x01, 0x00, 0x00, 0x03, 0x00, 0xbd,
|
|
||||||
0x2a, 0x28, 0xc0, 0x03, 0x03, 0x01, 0x00, 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, 0xc3, 0x04, 0x08, 0xcd,
|
|
||||||
0x08, 0xeb, 0x05, 0xc0, 0x00, 0xe3, 0x29, 0x04,
|
|
||||||
0xe4, 0x00, 0x00, 0x00, 0xe2, 0x62, 0x00, 0x00,
|
|
||||||
0xdf, 0x43, 0x38, 0x00, 0x00, 0x00, 0x24, 0x00,
|
|
||||||
0x00, 0xca, 0x63, 0x00, 0x00, 0x66, 0x00, 0x00,
|
|
||||||
0xb0, 0xeb, 0x0b, 0x39, 0x95, 0x00, 0x00, 0x00,
|
|
||||||
0x63, 0x00, 0x00, 0xf0, 0x30, 0x62, 0x02, 0x00,
|
|
||||||
0x62, 0x01, 0x00, 0x39, 0x3b, 0x00, 0x00, 0x00,
|
|
||||||
0x66, 0x00, 0x00, 0x04, 0xe2, 0x00, 0x00, 0x00,
|
|
||||||
0x9e, 0x32, 0x01, 0x00, 0x03, 0x00, 0xcb, 0x63,
|
|
||||||
0x01, 0x00, 0x43, 0x38, 0x00, 0x00, 0x00, 0x24,
|
|
||||||
0x00, 0x00, 0xcc, 0x63, 0x02, 0x00, 0x66, 0x00,
|
|
||||||
0x00, 0xb0, 0xeb, 0x0b, 0x39, 0x95, 0x00, 0x00,
|
|
||||||
0x00, 0x63, 0x02, 0x00, 0xf0, 0x30, 0x69, 0x02,
|
|
||||||
0x00, 0x69, 0x01, 0x00, 0x06, 0x2f, 0xc0, 0x03,
|
|
||||||
0x01, 0x01, 0x14, 0x00, 0x1c, 0x0a, 0x2a, 0x26,
|
|
||||||
0x03, 0x39, 0x28, 0x00, 0x10, 0x08, 0x27, 0x11,
|
|
||||||
0x12, 0x67, 0x0d, 0x26, 0x03, 0x39, 0x28, 0x00,
|
|
||||||
};
|
|
||||||
|
|
||||||
static JSContext *JS_NewCustomContext(JSRuntime *rt)
|
|
||||||
{
|
|
||||||
JSContext *ctx = JS_NewContext(rt);
|
|
||||||
if (!ctx)
|
|
||||||
return NULL;
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
JSRuntime *rt;
|
|
||||||
JSContext *ctx;
|
|
||||||
r = 0;
|
|
||||||
rt = JS_NewRuntime();
|
|
||||||
js_std_set_worker_new_context_func(JS_NewCustomContext);
|
|
||||||
js_std_init_handlers(rt);
|
|
||||||
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
|
|
||||||
ctx = JS_NewCustomContext(rt);
|
|
||||||
js_std_add_helpers(ctx, argc, argv);
|
|
||||||
js_std_eval_binary(ctx, qjsc_function_source, qjsc_function_source_size, 0);
|
|
||||||
r = js_std_loop(ctx);
|
|
||||||
if (r) {
|
|
||||||
js_std_dump_error(ctx);
|
|
||||||
}
|
|
||||||
js_std_free_handlers(rt);
|
|
||||||
JS_FreeContext(ctx);
|
|
||||||
JS_FreeRuntime(rt);
|
|
||||||
return r;
|
|
||||||
}
|
|
|
@ -1,106 +0,0 @@
|
||||||
/* File generated automatically by the QuickJS-ng compiler. */
|
|
||||||
|
|
||||||
#include "quickjs-libc.h"
|
|
||||||
|
|
||||||
const uint32_t qjsc_fib_module_size = 290;
|
|
||||||
|
|
||||||
const uint8_t qjsc_fib_module[290] = {
|
|
||||||
0x13, 0x03, 0x01, 0x2c, 0x65, 0x78, 0x61, 0x6d,
|
|
||||||
0x70, 0x6c, 0x65, 0x73, 0x2f, 0x66, 0x69, 0x62,
|
|
||||||
0x5f, 0x6d, 0x6f, 0x64, 0x75, 0x6c, 0x65, 0x2e,
|
|
||||||
0x6a, 0x73, 0x01, 0x06, 0x66, 0x69, 0x62, 0x01,
|
|
||||||
0x02, 0x6e, 0x0d, 0xc0, 0x03, 0x00, 0x01, 0x00,
|
|
||||||
0x00, 0xc2, 0x03, 0x00, 0x00, 0x00, 0x0c, 0x20,
|
|
||||||
0xfa, 0x01, 0xa2, 0x01, 0x00, 0x00, 0x00, 0x01,
|
|
||||||
0x01, 0x01, 0x09, 0x00, 0xc2, 0x03, 0x00, 0x01,
|
|
||||||
0x0c, 0x43, 0xfa, 0x01, 0xc2, 0x03, 0x01, 0x00,
|
|
||||||
0x01, 0x04, 0x01, 0x00, 0x1a, 0x01, 0xc4, 0x03,
|
|
||||||
0x00, 0x01, 0x00, 0xc2, 0x03, 0x00, 0x00, 0xd2,
|
|
||||||
0xb5, 0xa8, 0xeb, 0x03, 0xb5, 0x28, 0xd2, 0xb6,
|
|
||||||
0xad, 0xeb, 0x03, 0xb6, 0x28, 0xde, 0xd2, 0xb6,
|
|
||||||
0x9f, 0xf0, 0xde, 0xd2, 0xb7, 0x9f, 0xf0, 0x9e,
|
|
||||||
0x28, 0xc0, 0x03, 0x02, 0x08, 0x0e, 0x09, 0x0c,
|
|
||||||
0x27, 0x0a, 0x28, 0x02, 0x07, 0x08, 0x11, 0x0a,
|
|
||||||
0x07, 0x08, 0x07, 0x08, 0x8d, 0x01, 0x66, 0x75,
|
|
||||||
0x6e, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x66,
|
|
||||||
0x69, 0x62, 0x28, 0x6e, 0x29, 0x0a, 0x7b, 0x0a,
|
|
||||||
0x20, 0x20, 0x20, 0x20, 0x69, 0x66, 0x20, 0x28,
|
|
||||||
0x6e, 0x20, 0x3c, 0x3d, 0x20, 0x30, 0x29, 0x0a,
|
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
||||||
0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x30,
|
|
||||||
0x3b, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c,
|
|
||||||
0x73, 0x65, 0x20, 0x69, 0x66, 0x20, 0x28, 0x6e,
|
|
||||||
0x20, 0x3d, 0x3d, 0x20, 0x31, 0x29, 0x0a, 0x20,
|
|
||||||
0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x72,
|
|
||||||
0x65, 0x74, 0x75, 0x72, 0x6e, 0x20, 0x31, 0x3b,
|
|
||||||
0x0a, 0x20, 0x20, 0x20, 0x20, 0x65, 0x6c, 0x73,
|
|
||||||
0x65, 0x0a, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
|
|
||||||
0x20, 0x20, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e,
|
|
||||||
0x20, 0x66, 0x69, 0x62, 0x28, 0x6e, 0x20, 0x2d,
|
|
||||||
0x20, 0x31, 0x29, 0x20, 0x2b, 0x20, 0x66, 0x69,
|
|
||||||
0x62, 0x28, 0x6e, 0x20, 0x2d, 0x20, 0x32, 0x29,
|
|
||||||
0x3b, 0x0a, 0x7d, 0x08, 0xeb, 0x05, 0xc0, 0x00,
|
|
||||||
0xe2, 0x29, 0x06, 0x2f, 0xc0, 0x03, 0x01, 0x01,
|
|
||||||
0x00, 0x00,
|
|
||||||
};
|
|
||||||
|
|
||||||
const uint32_t qjsc_hello_module_size = 187;
|
|
||||||
|
|
||||||
const uint8_t qjsc_hello_module[187] = {
|
|
||||||
0x13, 0x07, 0x01, 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, 0x01, 0x1e, 0x2e, 0x2f,
|
|
||||||
0x66, 0x69, 0x62, 0x5f, 0x6d, 0x6f, 0x64, 0x75,
|
|
||||||
0x6c, 0x65, 0x2e, 0x6a, 0x73, 0x01, 0x06, 0x66,
|
|
||||||
0x69, 0x62, 0x01, 0x0e, 0x63, 0x6f, 0x6e, 0x73,
|
|
||||||
0x6f, 0x6c, 0x65, 0x01, 0x06, 0x6c, 0x6f, 0x67,
|
|
||||||
0x01, 0x16, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20,
|
|
||||||
0x57, 0x6f, 0x72, 0x6c, 0x64, 0x01, 0x10, 0x66,
|
|
||||||
0x69, 0x62, 0x28, 0x31, 0x30, 0x29, 0x3d, 0x0d,
|
|
||||||
0xc0, 0x03, 0x01, 0xc2, 0x03, 0x00, 0x00, 0x01,
|
|
||||||
0x00, 0xc4, 0x03, 0x00, 0x00, 0x0c, 0x20, 0xfa,
|
|
||||||
0x01, 0xa2, 0x01, 0x00, 0x00, 0x00, 0x05, 0x01,
|
|
||||||
0x00, 0x32, 0x00, 0xc4, 0x03, 0x00, 0x0c, 0x08,
|
|
||||||
0xeb, 0x02, 0x29, 0x39, 0xe3, 0x00, 0x00, 0x00,
|
|
||||||
0x43, 0xe4, 0x00, 0x00, 0x00, 0x04, 0xe5, 0x00,
|
|
||||||
0x00, 0x00, 0x24, 0x01, 0x00, 0x0e, 0x39, 0xe3,
|
|
||||||
0x00, 0x00, 0x00, 0x43, 0xe4, 0x00, 0x00, 0x00,
|
|
||||||
0x04, 0xe6, 0x00, 0x00, 0x00, 0x66, 0x00, 0x00,
|
|
||||||
0xbd, 0x0a, 0xf0, 0x24, 0x02, 0x00, 0x0e, 0x06,
|
|
||||||
0x2f, 0xc0, 0x03, 0x01, 0x01, 0x0c, 0x00, 0x04,
|
|
||||||
0x08, 0x00, 0x34, 0x10, 0x30, 0x0f, 0x34, 0x10,
|
|
||||||
0x2a, 0x20, 0x00,
|
|
||||||
};
|
|
||||||
|
|
||||||
static JSContext *JS_NewCustomContext(JSRuntime *rt)
|
|
||||||
{
|
|
||||||
JSContext *ctx = JS_NewContext(rt);
|
|
||||||
if (!ctx)
|
|
||||||
return NULL;
|
|
||||||
js_std_eval_binary(ctx, qjsc_fib_module, qjsc_fib_module_size, 1);
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
JSRuntime *rt;
|
|
||||||
JSContext *ctx;
|
|
||||||
r = 0;
|
|
||||||
rt = JS_NewRuntime();
|
|
||||||
js_std_set_worker_new_context_func(JS_NewCustomContext);
|
|
||||||
js_std_init_handlers(rt);
|
|
||||||
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
|
|
||||||
ctx = JS_NewCustomContext(rt);
|
|
||||||
js_std_add_helpers(ctx, argc, argv);
|
|
||||||
js_std_eval_binary(ctx, qjsc_hello_module, qjsc_hello_module_size, 0);
|
|
||||||
r = js_std_loop(ctx);
|
|
||||||
if (r) {
|
|
||||||
js_std_dump_error(ctx);
|
|
||||||
}
|
|
||||||
js_std_free_handlers(rt);
|
|
||||||
JS_FreeContext(ctx);
|
|
||||||
JS_FreeRuntime(rt);
|
|
||||||
return r;
|
|
||||||
}
|
|
318
gen/standalone.c
318
gen/standalone.c
|
@ -1,318 +0,0 @@
|
||||||
/* File generated automatically by the QuickJS-ng compiler. */
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
const uint32_t qjsc_standalone_size = 2466;
|
|
||||||
|
|
||||||
const uint8_t qjsc_standalone[2466] = {
|
|
||||||
0x13, 0x4d, 0x01, 0x1a, 0x73, 0x74, 0x61, 0x6e,
|
|
||||||
0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x2e, 0x6a,
|
|
||||||
0x73, 0x01, 0x0e, 0x71, 0x6a, 0x73, 0x3a, 0x73,
|
|
||||||
0x74, 0x64, 0x01, 0x0c, 0x71, 0x6a, 0x73, 0x3a,
|
|
||||||
0x6f, 0x73, 0x01, 0x12, 0x71, 0x6a, 0x73, 0x3a,
|
|
||||||
0x62, 0x6a, 0x73, 0x6f, 0x6e, 0x01, 0x22, 0x63,
|
|
||||||
0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x53, 0x74,
|
|
||||||
0x61, 0x6e, 0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65,
|
|
||||||
0x01, 0x1a, 0x72, 0x75, 0x6e, 0x53, 0x74, 0x61,
|
|
||||||
0x6e, 0x64, 0x61, 0x6c, 0x6f, 0x6e, 0x65, 0x01,
|
|
||||||
0x06, 0x73, 0x74, 0x64, 0x01, 0x04, 0x6f, 0x73,
|
|
||||||
0x01, 0x0a, 0x62, 0x6a, 0x73, 0x6f, 0x6e, 0x01,
|
|
||||||
0x28, 0x4a, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44,
|
|
||||||
0x5f, 0x4f, 0x42, 0x4a, 0x5f, 0x42, 0x59, 0x54,
|
|
||||||
0x45, 0x43, 0x4f, 0x44, 0x45, 0x01, 0x2a, 0x4a,
|
|
||||||
0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f,
|
|
||||||
0x42, 0x4a, 0x5f, 0x52, 0x45, 0x46, 0x45, 0x52,
|
|
||||||
0x45, 0x4e, 0x43, 0x45, 0x01, 0x2a, 0x4a, 0x53,
|
|
||||||
0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4f,
|
|
||||||
0x42, 0x4a, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x43,
|
|
||||||
0x4f, 0x44, 0x45, 0x01, 0x2c, 0x4a, 0x53, 0x5f,
|
|
||||||
0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4f, 0x42,
|
|
||||||
0x4a, 0x5f, 0x52, 0x45, 0x46, 0x45, 0x52, 0x45,
|
|
||||||
0x4e, 0x43, 0x45, 0x01, 0x32, 0x4a, 0x53, 0x5f,
|
|
||||||
0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4f, 0x42,
|
|
||||||
0x4a, 0x5f, 0x53, 0x54, 0x52, 0x49, 0x50, 0x5f,
|
|
||||||
0x53, 0x4f, 0x55, 0x52, 0x43, 0x45, 0x01, 0x0e,
|
|
||||||
0x54, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x01,
|
|
||||||
0x16, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x41,
|
|
||||||
0x73, 0x63, 0x69, 0x69, 0x01, 0x16, 0x64, 0x65,
|
|
||||||
0x63, 0x6f, 0x64, 0x65, 0x41, 0x73, 0x63, 0x69,
|
|
||||||
0x69, 0x01, 0x06, 0x74, 0x78, 0x74, 0x01, 0x02,
|
|
||||||
0x63, 0x01, 0x14, 0x63, 0x68, 0x61, 0x72, 0x43,
|
|
||||||
0x6f, 0x64, 0x65, 0x41, 0x74, 0x01, 0x06, 0x6d,
|
|
||||||
0x61, 0x70, 0x01, 0x06, 0x62, 0x75, 0x66, 0x01,
|
|
||||||
0x18, 0x66, 0x72, 0x6f, 0x6d, 0x43, 0x68, 0x61,
|
|
||||||
0x72, 0x43, 0x6f, 0x64, 0x65, 0x01, 0x0c, 0x69,
|
|
||||||
0x6e, 0x46, 0x69, 0x6c, 0x65, 0x01, 0x0e, 0x6f,
|
|
||||||
0x75, 0x74, 0x46, 0x69, 0x6c, 0x65, 0x01, 0x12,
|
|
||||||
0x74, 0x61, 0x72, 0x67, 0x65, 0x74, 0x45, 0x78,
|
|
||||||
0x65, 0x01, 0x04, 0x6a, 0x73, 0x01, 0x08, 0x63,
|
|
||||||
0x6f, 0x64, 0x65, 0x01, 0x10, 0x62, 0x79, 0x74,
|
|
||||||
0x65, 0x63, 0x6f, 0x64, 0x65, 0x01, 0x16, 0x65,
|
|
||||||
0x78, 0x65, 0x46, 0x69, 0x6c, 0x65, 0x4e, 0x61,
|
|
||||||
0x6d, 0x65, 0x01, 0x06, 0x65, 0x78, 0x65, 0x01,
|
|
||||||
0x0e, 0x65, 0x78, 0x65, 0x53, 0x69, 0x7a, 0x65,
|
|
||||||
0x01, 0x12, 0x6e, 0x65, 0x77, 0x42, 0x75, 0x66,
|
|
||||||
0x66, 0x65, 0x72, 0x01, 0x0c, 0x6e, 0x65, 0x77,
|
|
||||||
0x45, 0x78, 0x65, 0x01, 0x04, 0x64, 0x77, 0x01,
|
|
||||||
0x0a, 0x6e, 0x65, 0x77, 0x46, 0x64, 0x01, 0x10,
|
|
||||||
0x6c, 0x6f, 0x61, 0x64, 0x46, 0x69, 0x6c, 0x65,
|
|
||||||
0x01, 0x1e, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64,
|
|
||||||
0x20, 0x74, 0x6f, 0x20, 0x6f, 0x70, 0x65, 0x6e,
|
|
||||||
0x20, 0x01, 0x14, 0x65, 0x76, 0x61, 0x6c, 0x53,
|
|
||||||
0x63, 0x72, 0x69, 0x70, 0x74, 0x01, 0x18, 0x63,
|
|
||||||
0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x5f, 0x6f,
|
|
||||||
0x6e, 0x6c, 0x79, 0x01, 0x1c, 0x63, 0x6f, 0x6d,
|
|
||||||
0x70, 0x69, 0x6c, 0x65, 0x5f, 0x6d, 0x6f, 0x64,
|
|
||||||
0x75, 0x6c, 0x65, 0x01, 0x0a, 0x77, 0x72, 0x69,
|
|
||||||
0x74, 0x65, 0x01, 0x0a, 0x61, 0x72, 0x67, 0x76,
|
|
||||||
0x30, 0x01, 0x0c, 0x62, 0x69, 0x6e, 0x61, 0x72,
|
|
||||||
0x79, 0x01, 0x36, 0x66, 0x61, 0x69, 0x6c, 0x65,
|
|
||||||
0x64, 0x20, 0x74, 0x6f, 0x20, 0x6f, 0x70, 0x65,
|
|
||||||
0x6e, 0x20, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74,
|
|
||||||
0x61, 0x62, 0x6c, 0x65, 0x3a, 0x20, 0x01, 0x0c,
|
|
||||||
0x62, 0x75, 0x66, 0x66, 0x65, 0x72, 0x01, 0x10,
|
|
||||||
0x74, 0x72, 0x61, 0x6e, 0x73, 0x66, 0x65, 0x72,
|
|
||||||
0x01, 0x08, 0x53, 0x69, 0x7a, 0x65, 0x01, 0x0a,
|
|
||||||
0x4d, 0x61, 0x67, 0x69, 0x63, 0x01, 0x12, 0x4d,
|
|
||||||
0x61, 0x67, 0x69, 0x63, 0x53, 0x69, 0x7a, 0x65,
|
|
||||||
0x01, 0x10, 0x44, 0x61, 0x74, 0x61, 0x53, 0x69,
|
|
||||||
0x7a, 0x65, 0x01, 0x12, 0x73, 0x65, 0x74, 0x55,
|
|
||||||
0x69, 0x6e, 0x74, 0x33, 0x32, 0x01, 0x08, 0x6f,
|
|
||||||
0x70, 0x65, 0x6e, 0x01, 0x10, 0x4f, 0x5f, 0x57,
|
|
||||||
0x52, 0x4f, 0x4e, 0x4c, 0x59, 0x01, 0x0e, 0x4f,
|
|
||||||
0x5f, 0x43, 0x52, 0x45, 0x41, 0x54, 0x01, 0x0e,
|
|
||||||
0x4f, 0x5f, 0x54, 0x52, 0x55, 0x4e, 0x43, 0x01,
|
|
||||||
0x22, 0x66, 0x61, 0x69, 0x6c, 0x65, 0x64, 0x20,
|
|
||||||
0x74, 0x6f, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74,
|
|
||||||
0x65, 0x20, 0x01, 0x14, 0x62, 0x79, 0x74, 0x65,
|
|
||||||
0x4c, 0x65, 0x6e, 0x67, 0x74, 0x68, 0x01, 0x0a,
|
|
||||||
0x63, 0x6c, 0x6f, 0x73, 0x65, 0x01, 0x3c, 0x66,
|
|
||||||
0x61, 0x69, 0x6c, 0x65, 0x64, 0x20, 0x74, 0x6f,
|
|
||||||
0x20, 0x77, 0x72, 0x69, 0x74, 0x65, 0x20, 0x74,
|
|
||||||
0x6f, 0x20, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74,
|
|
||||||
0x20, 0x66, 0x69, 0x6c, 0x65, 0x01, 0x08, 0x66,
|
|
||||||
0x69, 0x6c, 0x65, 0x01, 0x02, 0x72, 0x01, 0x0e,
|
|
||||||
0x74, 0x72, 0x61, 0x69, 0x6c, 0x65, 0x72, 0x01,
|
|
||||||
0x0a, 0x6d, 0x61, 0x67, 0x69, 0x63, 0x01, 0x0c,
|
|
||||||
0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x01, 0x04,
|
|
||||||
0x72, 0x62, 0x01, 0x08, 0x73, 0x65, 0x65, 0x6b,
|
|
||||||
0x01, 0x10, 0x53, 0x45, 0x45, 0x4b, 0x5f, 0x45,
|
|
||||||
0x4e, 0x44, 0x01, 0x18, 0x73, 0x65, 0x65, 0x6b,
|
|
||||||
0x20, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x3a, 0x20,
|
|
||||||
0x01, 0x08, 0x72, 0x65, 0x61, 0x64, 0x01, 0x40,
|
|
||||||
0x63, 0x6f, 0x72, 0x72, 0x75, 0x70, 0x74, 0x65,
|
|
||||||
0x64, 0x20, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x79,
|
|
||||||
0x2c, 0x20, 0x6d, 0x61, 0x67, 0x69, 0x63, 0x20,
|
|
||||||
0x6d, 0x69, 0x73, 0x6d, 0x61, 0x74, 0x63, 0x68,
|
|
||||||
0x01, 0x12, 0x67, 0x65, 0x74, 0x55, 0x69, 0x6e,
|
|
||||||
0x74, 0x33, 0x32, 0x01, 0x10, 0x53, 0x45, 0x45,
|
|
||||||
0x4b, 0x5f, 0x53, 0x45, 0x54, 0x01, 0x0a, 0x65,
|
|
||||||
0x72, 0x72, 0x6f, 0x72, 0x01, 0x14, 0x72, 0x65,
|
|
||||||
0x61, 0x64, 0x20, 0x65, 0x72, 0x72, 0x6f, 0x72,
|
|
||||||
0x01, 0x16, 0x65, 0x76, 0x61, 0x6c, 0x5f, 0x6d,
|
|
||||||
0x6f, 0x64, 0x75, 0x6c, 0x65, 0x01, 0x10, 0x71,
|
|
||||||
0x75, 0x69, 0x63, 0x6b, 0x6a, 0x73, 0x32, 0x0d,
|
|
||||||
0xc0, 0x03, 0x03, 0xc2, 0x03, 0xc4, 0x03, 0xc6,
|
|
||||||
0x03, 0x02, 0x00, 0x0b, 0xc8, 0x03, 0x00, 0x0c,
|
|
||||||
0xca, 0x03, 0x00, 0x03, 0x00, 0xfc, 0x01, 0x00,
|
|
||||||
0x01, 0xfc, 0x01, 0x01, 0x02, 0xfc, 0x01, 0x02,
|
|
||||||
0x00, 0x0c, 0x20, 0x02, 0x01, 0xa2, 0x01, 0x00,
|
|
||||||
0x00, 0x00, 0x02, 0x0d, 0x04, 0x58, 0x00, 0xcc,
|
|
||||||
0x03, 0x00, 0x0d, 0xce, 0x03, 0x01, 0x0d, 0xd0,
|
|
||||||
0x03, 0x02, 0x0d, 0xd2, 0x03, 0x00, 0x0d, 0xd4,
|
|
||||||
0x03, 0x01, 0x0d, 0xd6, 0x03, 0x02, 0x0d, 0xd8,
|
|
||||||
0x03, 0x03, 0x0d, 0xda, 0x03, 0x04, 0x0d, 0xdc,
|
|
||||||
0x03, 0x05, 0x0d, 0xde, 0x03, 0x06, 0x01, 0xe0,
|
|
||||||
0x03, 0x07, 0x01, 0xc8, 0x03, 0x08, 0x01, 0xca,
|
|
||||||
0x03, 0x09, 0x01, 0x0c, 0x43, 0x02, 0x01, 0xde,
|
|
||||||
0x03, 0x01, 0x00, 0x01, 0x05, 0x00, 0x01, 0x1e,
|
|
||||||
0x01, 0xe2, 0x03, 0x00, 0x01, 0x00, 0x0c, 0x42,
|
|
||||||
0x02, 0x01, 0x00, 0x01, 0x00, 0x01, 0x03, 0x00,
|
|
||||||
0x00, 0x0a, 0x01, 0xe4, 0x03, 0x00, 0x01, 0x00,
|
|
||||||
0xd2, 0x43, 0xf3, 0x00, 0x00, 0x00, 0xb5, 0x25,
|
|
||||||
0x01, 0x00, 0x39, 0xa6, 0x00, 0x00, 0x00, 0x11,
|
|
||||||
0xd2, 0x43, 0x5e, 0x00, 0x00, 0x00, 0xc1, 0x24,
|
|
||||||
0x01, 0x00, 0x43, 0xf4, 0x00, 0x00, 0x00, 0xc0,
|
|
||||||
0x00, 0x24, 0x01, 0x00, 0x21, 0x01, 0x00, 0x28,
|
|
||||||
0x0c, 0x43, 0x02, 0x01, 0xe0, 0x03, 0x01, 0x00,
|
|
||||||
0x01, 0x03, 0x00, 0x01, 0x21, 0x01, 0xea, 0x03,
|
|
||||||
0x00, 0x01, 0x00, 0x0c, 0x42, 0x02, 0x01, 0x00,
|
|
||||||
0x01, 0x00, 0x01, 0x03, 0x00, 0x00, 0x0e, 0x01,
|
|
||||||
0xe4, 0x03, 0x00, 0x01, 0x00, 0x39, 0x97, 0x00,
|
|
||||||
0x00, 0x00, 0x43, 0xf6, 0x00, 0x00, 0x00, 0xd2,
|
|
||||||
0x25, 0x01, 0x00, 0x39, 0x94, 0x00, 0x00, 0x00,
|
|
||||||
0x43, 0x7b, 0x00, 0x00, 0x00, 0xd2, 0x24, 0x01,
|
|
||||||
0x00, 0x43, 0xf4, 0x00, 0x00, 0x00, 0xc0, 0x00,
|
|
||||||
0x24, 0x01, 0x00, 0x43, 0x5c, 0x00, 0x00, 0x00,
|
|
||||||
0xc1, 0x25, 0x01, 0x00, 0x0c, 0x43, 0x02, 0x01,
|
|
||||||
0xc8, 0x03, 0x03, 0x0a, 0x03, 0x07, 0x08, 0x00,
|
|
||||||
0x86, 0x04, 0x0d, 0xee, 0x03, 0x00, 0x01, 0x00,
|
|
||||||
0xf0, 0x03, 0x00, 0x01, 0x00, 0xf2, 0x03, 0x00,
|
|
||||||
0x01, 0x00, 0xf4, 0x03, 0x01, 0x00, 0x30, 0xf6,
|
|
||||||
0x03, 0x01, 0x01, 0x30, 0xf8, 0x03, 0x01, 0x02,
|
|
||||||
0x30, 0xfa, 0x03, 0x01, 0x03, 0x30, 0xfc, 0x03,
|
|
||||||
0x01, 0x04, 0x30, 0xfe, 0x03, 0x01, 0x05, 0x30,
|
|
||||||
0x80, 0x04, 0x01, 0x06, 0x30, 0x82, 0x04, 0x01,
|
|
||||||
0x07, 0x30, 0x84, 0x04, 0x01, 0x08, 0x30, 0x86,
|
|
||||||
0x04, 0x01, 0x09, 0x30, 0xcc, 0x03, 0x00, 0x0c,
|
|
||||||
0xd0, 0x03, 0x02, 0x0c, 0xd6, 0x03, 0x05, 0x0c,
|
|
||||||
0xd8, 0x03, 0x06, 0x0c, 0xda, 0x03, 0x07, 0x0c,
|
|
||||||
0xdc, 0x03, 0x08, 0x0c, 0xde, 0x03, 0x09, 0x00,
|
|
||||||
0xce, 0x03, 0x01, 0x0c, 0x62, 0x09, 0x00, 0x62,
|
|
||||||
0x08, 0x00, 0x62, 0x07, 0x00, 0x62, 0x06, 0x00,
|
|
||||||
0x62, 0x05, 0x00, 0x62, 0x04, 0x00, 0x62, 0x03,
|
|
||||||
0x00, 0x62, 0x02, 0x00, 0x62, 0x01, 0x00, 0x62,
|
|
||||||
0x00, 0x00, 0x66, 0x00, 0x00, 0x43, 0x04, 0x01,
|
|
||||||
0x00, 0x00, 0xd2, 0x24, 0x01, 0x00, 0xca, 0x63,
|
|
||||||
0x00, 0x00, 0x97, 0xeb, 0x19, 0x39, 0x95, 0x00,
|
|
||||||
0x00, 0x00, 0x11, 0x04, 0x05, 0x01, 0x00, 0x00,
|
|
||||||
0x43, 0x5d, 0x00, 0x00, 0x00, 0xd2, 0x24, 0x01,
|
|
||||||
0x00, 0x21, 0x01, 0x00, 0x30, 0x66, 0x00, 0x00,
|
|
||||||
0x43, 0x06, 0x01, 0x00, 0x00, 0x63, 0x00, 0x00,
|
|
||||||
0x0b, 0x0a, 0x4d, 0x07, 0x01, 0x00, 0x00, 0x0a,
|
|
||||||
0x4d, 0x08, 0x01, 0x00, 0x00, 0x24, 0x02, 0x00,
|
|
||||||
0xcb, 0x39, 0xa6, 0x00, 0x00, 0x00, 0x11, 0x66,
|
|
||||||
0x01, 0x00, 0x43, 0x09, 0x01, 0x00, 0x00, 0x63,
|
|
||||||
0x01, 0x00, 0x66, 0x02, 0x00, 0x66, 0x03, 0x00,
|
|
||||||
0xa5, 0x66, 0x04, 0x00, 0xa5, 0x24, 0x02, 0x00,
|
|
||||||
0x21, 0x01, 0x00, 0xcc, 0xd4, 0x11, 0xb1, 0xeb,
|
|
||||||
0x0c, 0x0e, 0x39, 0x8c, 0x00, 0x00, 0x00, 0x42,
|
|
||||||
0x0a, 0x01, 0x00, 0x00, 0xcd, 0x66, 0x00, 0x00,
|
|
||||||
0x43, 0x04, 0x01, 0x00, 0x00, 0x63, 0x03, 0x00,
|
|
||||||
0x0b, 0x0a, 0x4d, 0x0b, 0x01, 0x00, 0x00, 0x24,
|
|
||||||
0x02, 0x00, 0xc3, 0x04, 0x63, 0x04, 0x00, 0x97,
|
|
||||||
0xeb, 0x1b, 0x39, 0x95, 0x00, 0x00, 0x00, 0x11,
|
|
||||||
0x04, 0x0c, 0x01, 0x00, 0x00, 0x43, 0x5d, 0x00,
|
|
||||||
0x00, 0x00, 0x63, 0x03, 0x00, 0x24, 0x01, 0x00,
|
|
||||||
0x21, 0x01, 0x00, 0x30, 0x63, 0x04, 0x00, 0xea,
|
|
||||||
0xc3, 0x05, 0x63, 0x04, 0x00, 0x42, 0x0d, 0x01,
|
|
||||||
0x00, 0x00, 0x43, 0x0e, 0x01, 0x00, 0x00, 0x63,
|
|
||||||
0x05, 0x00, 0x63, 0x02, 0x00, 0xea, 0x9e, 0x66,
|
|
||||||
0x05, 0x00, 0x42, 0x0f, 0x01, 0x00, 0x00, 0x9e,
|
|
||||||
0x24, 0x01, 0x00, 0xc3, 0x06, 0x39, 0xa6, 0x00,
|
|
||||||
0x00, 0x00, 0x11, 0x63, 0x06, 0x00, 0x21, 0x01,
|
|
||||||
0x00, 0xc3, 0x07, 0x63, 0x07, 0x00, 0x43, 0x43,
|
|
||||||
0x00, 0x00, 0x00, 0x63, 0x02, 0x00, 0x63, 0x05,
|
|
||||||
0x00, 0x24, 0x02, 0x00, 0x0e, 0x63, 0x07, 0x00,
|
|
||||||
0x43, 0x43, 0x00, 0x00, 0x00, 0x5f, 0x06, 0x00,
|
|
||||||
0x66, 0x05, 0x00, 0x42, 0x10, 0x01, 0x00, 0x00,
|
|
||||||
0xf0, 0x63, 0x05, 0x00, 0x63, 0x02, 0x00, 0xea,
|
|
||||||
0x9e, 0x24, 0x02, 0x00, 0x0e, 0x39, 0xb0, 0x00,
|
|
||||||
0x00, 0x00, 0x11, 0x63, 0x06, 0x00, 0x63, 0x05,
|
|
||||||
0x00, 0x63, 0x02, 0x00, 0xea, 0x9e, 0x66, 0x05,
|
|
||||||
0x00, 0x42, 0x11, 0x01, 0x00, 0x00, 0x9e, 0x66,
|
|
||||||
0x05, 0x00, 0x42, 0x12, 0x01, 0x00, 0x00, 0x21,
|
|
||||||
0x03, 0x00, 0xc3, 0x08, 0x63, 0x08, 0x00, 0x43,
|
|
||||||
0x13, 0x01, 0x00, 0x00, 0xb5, 0x63, 0x05, 0x00,
|
|
||||||
0x0a, 0x24, 0x03, 0x00, 0x0e, 0x66, 0x07, 0x00,
|
|
||||||
0x43, 0x14, 0x01, 0x00, 0x00, 0xd3, 0x66, 0x07,
|
|
||||||
0x00, 0x42, 0x15, 0x01, 0x00, 0x00, 0x66, 0x07,
|
|
||||||
0x00, 0x42, 0x16, 0x01, 0x00, 0x00, 0xa5, 0x66,
|
|
||||||
0x07, 0x00, 0x42, 0x17, 0x01, 0x00, 0x00, 0xa5,
|
|
||||||
0xbe, 0xed, 0x01, 0x24, 0x03, 0x00, 0xc3, 0x09,
|
|
||||||
0x63, 0x09, 0x00, 0xb5, 0xa7, 0xeb, 0x19, 0x39,
|
|
||||||
0x95, 0x00, 0x00, 0x00, 0x11, 0x04, 0x18, 0x01,
|
|
||||||
0x00, 0x00, 0x43, 0x5d, 0x00, 0x00, 0x00, 0xd3,
|
|
||||||
0x24, 0x01, 0x00, 0x21, 0x01, 0x00, 0x30, 0x66,
|
|
||||||
0x07, 0x00, 0x43, 0x09, 0x01, 0x00, 0x00, 0x63,
|
|
||||||
0x09, 0x00, 0x63, 0x06, 0x00, 0xb5, 0x63, 0x06,
|
|
||||||
0x00, 0x42, 0x19, 0x01, 0x00, 0x00, 0x24, 0x04,
|
|
||||||
0x00, 0xb5, 0xa7, 0xeb, 0x1f, 0x66, 0x07, 0x00,
|
|
||||||
0x43, 0x1a, 0x01, 0x00, 0x00, 0x63, 0x09, 0x00,
|
|
||||||
0x24, 0x01, 0x00, 0x0e, 0x39, 0x95, 0x00, 0x00,
|
|
||||||
0x00, 0x11, 0x04, 0x1b, 0x01, 0x00, 0x00, 0x21,
|
|
||||||
0x01, 0x00, 0x30, 0x66, 0x07, 0x00, 0x43, 0x1a,
|
|
||||||
0x01, 0x00, 0x00, 0x63, 0x09, 0x00, 0x24, 0x01,
|
|
||||||
0x00, 0x29, 0x0c, 0x43, 0x02, 0x01, 0xca, 0x03,
|
|
||||||
0x00, 0x09, 0x00, 0x07, 0x06, 0x00, 0xa4, 0x04,
|
|
||||||
0x09, 0xb8, 0x04, 0x01, 0x00, 0x30, 0xfc, 0x03,
|
|
||||||
0x01, 0x01, 0x30, 0xba, 0x04, 0x01, 0x02, 0x20,
|
|
||||||
0xbc, 0x04, 0x01, 0x03, 0x30, 0xbe, 0x04, 0x01,
|
|
||||||
0x04, 0x30, 0x84, 0x04, 0x01, 0x05, 0x30, 0xc0,
|
|
||||||
0x04, 0x01, 0x06, 0x30, 0xf8, 0x03, 0x01, 0x07,
|
|
||||||
0x30, 0xf6, 0x03, 0x01, 0x08, 0x30, 0xcc, 0x03,
|
|
||||||
0x00, 0x0c, 0xdc, 0x03, 0x08, 0x0c, 0xe0, 0x03,
|
|
||||||
0x0a, 0x00, 0xd0, 0x03, 0x02, 0x0c, 0xd2, 0x03,
|
|
||||||
0x03, 0x0c, 0xd4, 0x03, 0x04, 0x0c, 0x62, 0x08,
|
|
||||||
0x00, 0x62, 0x07, 0x00, 0x62, 0x06, 0x00, 0x62,
|
|
||||||
0x05, 0x00, 0x62, 0x04, 0x00, 0x62, 0x03, 0x00,
|
|
||||||
0x62, 0x02, 0x00, 0x62, 0x01, 0x00, 0x62, 0x00,
|
|
||||||
0x00, 0x39, 0x8c, 0x00, 0x00, 0x00, 0x42, 0x0a,
|
|
||||||
0x01, 0x00, 0x00, 0xca, 0x66, 0x00, 0x00, 0x43,
|
|
||||||
0x14, 0x01, 0x00, 0x00, 0x63, 0x00, 0x00, 0x04,
|
|
||||||
0x21, 0x01, 0x00, 0x00, 0x24, 0x02, 0x00, 0xcb,
|
|
||||||
0x63, 0x01, 0x00, 0x97, 0xeb, 0x1b, 0x39, 0x95,
|
|
||||||
0x00, 0x00, 0x00, 0x11, 0x04, 0x0c, 0x01, 0x00,
|
|
||||||
0x00, 0x43, 0x5d, 0x00, 0x00, 0x00, 0x63, 0x00,
|
|
||||||
0x00, 0x24, 0x01, 0x00, 0x21, 0x01, 0x00, 0x30,
|
|
||||||
0x63, 0x01, 0x00, 0x43, 0x22, 0x01, 0x00, 0x00,
|
|
||||||
0x66, 0x01, 0x00, 0x42, 0x0f, 0x01, 0x00, 0x00,
|
|
||||||
0x8d, 0x66, 0x00, 0x00, 0x42, 0x23, 0x01, 0x00,
|
|
||||||
0x00, 0x24, 0x02, 0x00, 0xcc, 0x63, 0x02, 0x00,
|
|
||||||
0xb5, 0xa7, 0xeb, 0x1c, 0x39, 0x95, 0x00, 0x00,
|
|
||||||
0x00, 0x11, 0x04, 0x24, 0x01, 0x00, 0x00, 0x43,
|
|
||||||
0x5d, 0x00, 0x00, 0x00, 0x63, 0x02, 0x00, 0x8d,
|
|
||||||
0x24, 0x01, 0x00, 0x21, 0x01, 0x00, 0x30, 0x39,
|
|
||||||
0xa6, 0x00, 0x00, 0x00, 0x11, 0x66, 0x01, 0x00,
|
|
||||||
0x42, 0x0f, 0x01, 0x00, 0x00, 0x21, 0x01, 0x00,
|
|
||||||
0xcd, 0x63, 0x01, 0x00, 0x43, 0x25, 0x01, 0x00,
|
|
||||||
0x00, 0x63, 0x03, 0x00, 0x42, 0x0d, 0x01, 0x00,
|
|
||||||
0x00, 0xb5, 0x66, 0x01, 0x00, 0x42, 0x0f, 0x01,
|
|
||||||
0x00, 0x00, 0x24, 0x03, 0x00, 0x0e, 0x39, 0xa6,
|
|
||||||
0x00, 0x00, 0x00, 0x11, 0x63, 0x03, 0x00, 0x42,
|
|
||||||
0x0d, 0x01, 0x00, 0x00, 0xb5, 0x66, 0x01, 0x00,
|
|
||||||
0x42, 0x11, 0x01, 0x00, 0x00, 0x21, 0x03, 0x00,
|
|
||||||
0xc3, 0x04, 0xe0, 0x63, 0x04, 0x00, 0xf0, 0x66,
|
|
||||||
0x01, 0x00, 0x42, 0x10, 0x01, 0x00, 0x00, 0xb0,
|
|
||||||
0xeb, 0x1c, 0x63, 0x01, 0x00, 0x43, 0x1a, 0x01,
|
|
||||||
0x00, 0x00, 0x24, 0x00, 0x00, 0x0e, 0x39, 0x95,
|
|
||||||
0x00, 0x00, 0x00, 0x11, 0x04, 0x26, 0x01, 0x00,
|
|
||||||
0x00, 0x21, 0x01, 0x00, 0x30, 0x39, 0xb0, 0x00,
|
|
||||||
0x00, 0x00, 0x11, 0x63, 0x03, 0x00, 0x42, 0x0d,
|
|
||||||
0x01, 0x00, 0x00, 0x66, 0x01, 0x00, 0x42, 0x11,
|
|
||||||
0x01, 0x00, 0x00, 0x66, 0x01, 0x00, 0x42, 0x12,
|
|
||||||
0x01, 0x00, 0x00, 0x21, 0x03, 0x00, 0xc3, 0x05,
|
|
||||||
0x63, 0x05, 0x00, 0x43, 0x27, 0x01, 0x00, 0x00,
|
|
||||||
0xb5, 0x0a, 0x24, 0x02, 0x00, 0xc3, 0x06, 0x39,
|
|
||||||
0xa6, 0x00, 0x00, 0x00, 0x11, 0x63, 0x06, 0x00,
|
|
||||||
0x66, 0x01, 0x00, 0x42, 0x0f, 0x01, 0x00, 0x00,
|
|
||||||
0x9f, 0x21, 0x01, 0x00, 0xc3, 0x07, 0x63, 0x01,
|
|
||||||
0x00, 0x43, 0x22, 0x01, 0x00, 0x00, 0x63, 0x06,
|
|
||||||
0x00, 0x66, 0x00, 0x00, 0x42, 0x28, 0x01, 0x00,
|
|
||||||
0x00, 0x24, 0x02, 0x00, 0x11, 0x64, 0x02, 0x00,
|
|
||||||
0x0e, 0x63, 0x02, 0x00, 0xb5, 0xa7, 0xeb, 0x28,
|
|
||||||
0x63, 0x01, 0x00, 0x43, 0x1a, 0x01, 0x00, 0x00,
|
|
||||||
0x24, 0x00, 0x00, 0x0e, 0x39, 0x95, 0x00, 0x00,
|
|
||||||
0x00, 0x11, 0x04, 0x24, 0x01, 0x00, 0x00, 0x43,
|
|
||||||
0x5d, 0x00, 0x00, 0x00, 0x63, 0x02, 0x00, 0x8d,
|
|
||||||
0x24, 0x01, 0x00, 0x21, 0x01, 0x00, 0x30, 0x63,
|
|
||||||
0x01, 0x00, 0x43, 0x25, 0x01, 0x00, 0x00, 0x63,
|
|
||||||
0x07, 0x00, 0x42, 0x0d, 0x01, 0x00, 0x00, 0xb5,
|
|
||||||
0x63, 0x07, 0x00, 0xea, 0x24, 0x03, 0x00, 0x0e,
|
|
||||||
0x63, 0x01, 0x00, 0x43, 0x29, 0x01, 0x00, 0x00,
|
|
||||||
0x24, 0x00, 0x00, 0xeb, 0x1c, 0x63, 0x01, 0x00,
|
|
||||||
0x43, 0x1a, 0x01, 0x00, 0x00, 0x24, 0x00, 0x00,
|
|
||||||
0x0e, 0x39, 0x95, 0x00, 0x00, 0x00, 0x11, 0x04,
|
|
||||||
0x2a, 0x01, 0x00, 0x00, 0x21, 0x01, 0x00, 0x30,
|
|
||||||
0x63, 0x01, 0x00, 0x43, 0x1a, 0x01, 0x00, 0x00,
|
|
||||||
0x24, 0x00, 0x00, 0x0e, 0x66, 0x03, 0x00, 0x43,
|
|
||||||
0x25, 0x01, 0x00, 0x00, 0x63, 0x07, 0x00, 0x42,
|
|
||||||
0x0d, 0x01, 0x00, 0x00, 0xb5, 0x63, 0x07, 0x00,
|
|
||||||
0xea, 0x66, 0x04, 0x00, 0x66, 0x05, 0x00, 0xa5,
|
|
||||||
0x24, 0x04, 0x00, 0xc3, 0x08, 0x66, 0x00, 0x00,
|
|
||||||
0x43, 0x06, 0x01, 0x00, 0x00, 0x63, 0x08, 0x00,
|
|
||||||
0x0b, 0x0a, 0x4d, 0x2b, 0x01, 0x00, 0x00, 0x25,
|
|
||||||
0x02, 0x00, 0x08, 0xeb, 0x16, 0xc0, 0x00, 0x60,
|
|
||||||
0x09, 0x00, 0xc0, 0x01, 0x60, 0x0a, 0x00, 0xc0,
|
|
||||||
0x02, 0x60, 0x0b, 0x00, 0xc0, 0x03, 0x60, 0x0c,
|
|
||||||
0x00, 0x29, 0xb6, 0xb5, 0xa0, 0xe5, 0xb6, 0xb8,
|
|
||||||
0xa0, 0x60, 0x04, 0x00, 0xb6, 0xb5, 0xa0, 0x60,
|
|
||||||
0x05, 0x00, 0xb6, 0xb8, 0xa0, 0x60, 0x06, 0x00,
|
|
||||||
0xb6, 0xb9, 0xa0, 0x60, 0x07, 0x00, 0x0b, 0x04,
|
|
||||||
0x2c, 0x01, 0x00, 0x00, 0x4d, 0x10, 0x01, 0x00,
|
|
||||||
0x00, 0xbd, 0x08, 0x4d, 0x11, 0x01, 0x00, 0x00,
|
|
||||||
0xb9, 0x4d, 0x12, 0x01, 0x00, 0x00, 0xbd, 0x0c,
|
|
||||||
0x4d, 0x0f, 0x01, 0x00, 0x00, 0x60, 0x08, 0x00,
|
|
||||||
0x06, 0x2f,
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,80 +0,0 @@
|
||||||
/* File generated automatically by the QuickJS-ng compiler. */
|
|
||||||
|
|
||||||
#include "quickjs-libc.h"
|
|
||||||
|
|
||||||
const uint32_t qjsc_test_fib_size = 294;
|
|
||||||
|
|
||||||
const uint8_t qjsc_test_fib[294] = {
|
|
||||||
0x13, 0x0e, 0x01, 0x28, 0x65, 0x78, 0x61, 0x6d,
|
|
||||||
0x70, 0x6c, 0x65, 0x73, 0x2f, 0x74, 0x65, 0x73,
|
|
||||||
0x74, 0x5f, 0x66, 0x69, 0x62, 0x2e, 0x6a, 0x73,
|
|
||||||
0x01, 0x0c, 0x71, 0x6a, 0x73, 0x3a, 0x6f, 0x73,
|
|
||||||
0x01, 0x04, 0x6f, 0x73, 0x01, 0x0a, 0x69, 0x73,
|
|
||||||
0x57, 0x69, 0x6e, 0x01, 0x06, 0x66, 0x69, 0x62,
|
|
||||||
0x01, 0x10, 0x70, 0x6c, 0x61, 0x74, 0x66, 0x6f,
|
|
||||||
0x72, 0x6d, 0x01, 0x0a, 0x77, 0x69, 0x6e, 0x33,
|
|
||||||
0x32, 0x01, 0x0c, 0x2e, 0x2f, 0x66, 0x69, 0x62,
|
|
||||||
0x2e, 0x01, 0x06, 0x64, 0x6c, 0x6c, 0x01, 0x04,
|
|
||||||
0x73, 0x6f, 0x01, 0x0e, 0x63, 0x6f, 0x6e, 0x73,
|
|
||||||
0x6f, 0x6c, 0x65, 0x01, 0x06, 0x6c, 0x6f, 0x67,
|
|
||||||
0x01, 0x16, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x20,
|
|
||||||
0x57, 0x6f, 0x72, 0x6c, 0x64, 0x01, 0x10, 0x66,
|
|
||||||
0x69, 0x62, 0x28, 0x31, 0x30, 0x29, 0x3d, 0x0d,
|
|
||||||
0xc0, 0x03, 0x01, 0xc2, 0x03, 0x00, 0x00, 0x01,
|
|
||||||
0x00, 0xfc, 0x01, 0x00, 0x01, 0x0c, 0x20, 0xfa,
|
|
||||||
0x01, 0xa2, 0x01, 0x00, 0x00, 0x00, 0x05, 0x03,
|
|
||||||
0x00, 0x73, 0x00, 0xc4, 0x03, 0x00, 0x0d, 0xc6,
|
|
||||||
0x03, 0x00, 0x0d, 0xc8, 0x03, 0x01, 0x0d, 0x08,
|
|
||||||
0xeb, 0x02, 0x29, 0x66, 0x00, 0x00, 0x42, 0xe5,
|
|
||||||
0x00, 0x00, 0x00, 0x04, 0xe6, 0x00, 0x00, 0x00,
|
|
||||||
0xaf, 0xe3, 0x06, 0x11, 0xf3, 0xec, 0x0b, 0x71,
|
|
||||||
0x43, 0xe4, 0x00, 0x00, 0x00, 0xe4, 0x0e, 0xed,
|
|
||||||
0x24, 0x0e, 0x04, 0xe7, 0x00, 0x00, 0x00, 0x43,
|
|
||||||
0x5d, 0x00, 0x00, 0x00, 0x66, 0x01, 0x00, 0xeb,
|
|
||||||
0x08, 0x04, 0xe8, 0x00, 0x00, 0x00, 0xed, 0x06,
|
|
||||||
0x04, 0xe9, 0x00, 0x00, 0x00, 0x24, 0x01, 0x00,
|
|
||||||
0x36, 0x8c, 0xed, 0xd4, 0x39, 0xea, 0x00, 0x00,
|
|
||||||
0x00, 0x43, 0xeb, 0x00, 0x00, 0x00, 0x04, 0xec,
|
|
||||||
0x00, 0x00, 0x00, 0x24, 0x01, 0x00, 0x0e, 0x39,
|
|
||||||
0xea, 0x00, 0x00, 0x00, 0x43, 0xeb, 0x00, 0x00,
|
|
||||||
0x00, 0x04, 0xed, 0x00, 0x00, 0x00, 0x66, 0x02,
|
|
||||||
0x00, 0xbd, 0x0a, 0xf0, 0x24, 0x02, 0x00, 0x0e,
|
|
||||||
0x06, 0x2f, 0xc0, 0x03, 0x01, 0x01, 0x0e, 0x41,
|
|
||||||
0x3c, 0x00, 0x39, 0x06, 0x3b, 0x34, 0x10, 0x30,
|
|
||||||
0x0f, 0x34, 0x10, 0x2a, 0x20, 0x00,
|
|
||||||
};
|
|
||||||
|
|
||||||
static JSContext *JS_NewCustomContext(JSRuntime *rt)
|
|
||||||
{
|
|
||||||
JSContext *ctx = JS_NewContext(rt);
|
|
||||||
if (!ctx)
|
|
||||||
return NULL;
|
|
||||||
{
|
|
||||||
extern JSModuleDef *js_init_module_os(JSContext *ctx, const char *name);
|
|
||||||
js_init_module_os(ctx, "qjs:os");
|
|
||||||
}
|
|
||||||
return ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
|
||||||
{
|
|
||||||
int r;
|
|
||||||
JSRuntime *rt;
|
|
||||||
JSContext *ctx;
|
|
||||||
r = 0;
|
|
||||||
rt = JS_NewRuntime();
|
|
||||||
js_std_set_worker_new_context_func(JS_NewCustomContext);
|
|
||||||
js_std_init_handlers(rt);
|
|
||||||
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
|
|
||||||
ctx = JS_NewCustomContext(rt);
|
|
||||||
js_std_add_helpers(ctx, argc, argv);
|
|
||||||
js_std_eval_binary(ctx, qjsc_test_fib, qjsc_test_fib_size, 0);
|
|
||||||
r = js_std_loop(ctx);
|
|
||||||
if (r) {
|
|
||||||
js_std_dump_error(ctx);
|
|
||||||
}
|
|
||||||
js_std_free_handlers(rt);
|
|
||||||
JS_FreeContext(ctx);
|
|
||||||
JS_FreeRuntime(rt);
|
|
||||||
return r;
|
|
||||||
}
|
|
653
getopt_compat.h
653
getopt_compat.h
|
@ -1,653 +0,0 @@
|
||||||
#ifndef __GETOPT_H__
|
|
||||||
/**
|
|
||||||
* DISCLAIMER
|
|
||||||
* This file is part of the mingw-w64 runtime package.
|
|
||||||
*
|
|
||||||
* The mingw-w64 runtime package and its code is distributed in the hope that it
|
|
||||||
* will be useful but WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESSED OR
|
|
||||||
* IMPLIED ARE HEREBY DISCLAIMED. This includes but is not limited to
|
|
||||||
* warranties of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
||||||
*/
|
|
||||||
/*
|
|
||||||
* Copyright (c) 2002 Todd C. Miller <Todd.Miller@courtesan.com>
|
|
||||||
*
|
|
||||||
* Permission to use, copy, modify, and distribute this software for any
|
|
||||||
* purpose with or without fee is hereby granted, provided that the above
|
|
||||||
* copyright notice and this permission notice appear in all copies.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
||||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
||||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
||||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
||||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
|
||||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
|
||||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
||||||
*
|
|
||||||
* Sponsored in part by the Defense Advanced Research Projects
|
|
||||||
* Agency (DARPA) and Air Force Research Laboratory, Air Force
|
|
||||||
* Materiel Command, USAF, under agreement number F39502-99-1-0512.
|
|
||||||
*/
|
|
||||||
/*-
|
|
||||||
* Copyright (c) 2000 The NetBSD Foundation, Inc.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This code is derived from software contributed to The NetBSD Foundation
|
|
||||||
* by Dieter Baron and Thomas Klausner.
|
|
||||||
*
|
|
||||||
* Redistribution and use in source and binary forms, with or without
|
|
||||||
* modification, are permitted provided that the following conditions
|
|
||||||
* are met:
|
|
||||||
* 1. Redistributions of source code must retain the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer.
|
|
||||||
* 2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
* notice, this list of conditions and the following disclaimer in the
|
|
||||||
* documentation and/or other materials provided with the distribution.
|
|
||||||
*
|
|
||||||
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
||||||
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
||||||
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
||||||
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
||||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
||||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
||||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
||||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
||||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
* POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma warning(disable:4996)
|
|
||||||
|
|
||||||
#define __GETOPT_H__
|
|
||||||
|
|
||||||
/* All the headers include this file. */
|
|
||||||
#include <crtdefs.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <windows.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define REPLACE_GETOPT /* use this getopt as the system getopt(3) */
|
|
||||||
|
|
||||||
#ifdef REPLACE_GETOPT
|
|
||||||
int opterr = 1; /* if error message should be printed */
|
|
||||||
int optind = 1; /* index into parent argv vector */
|
|
||||||
int optopt = '?'; /* character checked for validity */
|
|
||||||
#undef optreset /* see getopt.h */
|
|
||||||
#define optreset __mingw_optreset
|
|
||||||
int optreset; /* reset getopt */
|
|
||||||
char *optarg; /* argument associated with option */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//extern int optind; /* index of first non-option in argv */
|
|
||||||
//extern int optopt; /* single option character, as parsed */
|
|
||||||
//extern int opterr; /* flag to enable built-in diagnostics... */
|
|
||||||
// /* (user may set to zero, to suppress) */
|
|
||||||
//
|
|
||||||
//extern char *optarg; /* pointer to argument of current option */
|
|
||||||
|
|
||||||
#define PRINT_ERROR ((opterr) && (*options != ':'))
|
|
||||||
|
|
||||||
#define FLAG_PERMUTE 0x01 /* permute non-options to the end of argv */
|
|
||||||
#define FLAG_ALLARGS 0x02 /* treat non-options as args to option "-1" */
|
|
||||||
#define FLAG_LONGONLY 0x04 /* operate as getopt_long_only */
|
|
||||||
|
|
||||||
/* return values */
|
|
||||||
#define BADCH (int)'?'
|
|
||||||
#define BADARG ((*options == ':') ? (int)':' : (int)'?')
|
|
||||||
#define INORDER (int)1
|
|
||||||
|
|
||||||
#ifndef __CYGWIN__
|
|
||||||
#define __progname __argv[0]
|
|
||||||
#else
|
|
||||||
extern char __declspec(dllimport) *__progname;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __CYGWIN__
|
|
||||||
static char EMSG[] = "";
|
|
||||||
#else
|
|
||||||
#define EMSG ""
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct option /* specification for a long form option... */
|
|
||||||
{
|
|
||||||
const char *name; /* option name, without leading hyphens */
|
|
||||||
int has_arg; /* does it take an argument? */
|
|
||||||
int *flag; /* where to save its status, or NULL */
|
|
||||||
int val; /* its associated status value */
|
|
||||||
};
|
|
||||||
|
|
||||||
static int getopt_internal(int, char * const *, const char *,
|
|
||||||
const struct option *, int *, int);
|
|
||||||
static int parse_long_options(char * const *, const char *,
|
|
||||||
const struct option *, int *, int);
|
|
||||||
static int gcd(int, int);
|
|
||||||
static void permute_args(int, int, int, char * const *);
|
|
||||||
|
|
||||||
static char *place = EMSG; /* option letter processing */
|
|
||||||
|
|
||||||
/* XXX: set optreset to 1 rather than these two */
|
|
||||||
static int nonopt_start = -1; /* first non option argument (for permute) */
|
|
||||||
static int nonopt_end = -1; /* first option after non options (for permute) */
|
|
||||||
|
|
||||||
/* Error messages */
|
|
||||||
static const char recargchar[] = "option requires an argument -- %c";
|
|
||||||
static const char recargstring[] = "option requires an argument -- %s";
|
|
||||||
static const char ambig[] = "ambiguous option -- %.*s";
|
|
||||||
static const char noarg[] = "option doesn't take an argument -- %.*s";
|
|
||||||
static const char illoptchar[] = "unknown option -- %c";
|
|
||||||
static const char illoptstring[] = "unknown option -- %s";
|
|
||||||
|
|
||||||
static void
|
|
||||||
_vwarnx(const char *fmt,va_list ap)
|
|
||||||
{
|
|
||||||
(void)fprintf(stderr,"%s: ",__progname);
|
|
||||||
if (fmt != NULL)
|
|
||||||
(void)vfprintf(stderr,fmt,ap);
|
|
||||||
(void)fprintf(stderr,"\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
warnx(const char *fmt,...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
va_start(ap,fmt);
|
|
||||||
_vwarnx(fmt,ap);
|
|
||||||
va_end(ap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compute the greatest common divisor of a and b.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
gcd(int a, int b)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
|
|
||||||
c = a % b;
|
|
||||||
while (c != 0) {
|
|
||||||
a = b;
|
|
||||||
b = c;
|
|
||||||
c = a % b;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (b);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Exchange the block from nonopt_start to nonopt_end with the block
|
|
||||||
* from nonopt_end to opt_end (keeping the same order of arguments
|
|
||||||
* in each block).
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
permute_args(int panonopt_start, int panonopt_end, int opt_end,
|
|
||||||
char * const *nargv)
|
|
||||||
{
|
|
||||||
int cstart, cyclelen, i, j, ncycle, nnonopts, nopts, pos;
|
|
||||||
char *swap;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* compute lengths of blocks and number and size of cycles
|
|
||||||
*/
|
|
||||||
nnonopts = panonopt_end - panonopt_start;
|
|
||||||
nopts = opt_end - panonopt_end;
|
|
||||||
ncycle = gcd(nnonopts, nopts);
|
|
||||||
cyclelen = (opt_end - panonopt_start) / ncycle;
|
|
||||||
|
|
||||||
for (i = 0; i < ncycle; i++) {
|
|
||||||
cstart = panonopt_end+i;
|
|
||||||
pos = cstart;
|
|
||||||
for (j = 0; j < cyclelen; j++) {
|
|
||||||
if (pos >= panonopt_end)
|
|
||||||
pos -= nnonopts;
|
|
||||||
else
|
|
||||||
pos += nopts;
|
|
||||||
swap = nargv[pos];
|
|
||||||
/* LINTED const cast */
|
|
||||||
((char **) nargv)[pos] = nargv[cstart];
|
|
||||||
/* LINTED const cast */
|
|
||||||
((char **)nargv)[cstart] = swap;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef REPLACE_GETOPT
|
|
||||||
/*
|
|
||||||
* getopt --
|
|
||||||
* Parse argc/argv argument vector.
|
|
||||||
*
|
|
||||||
* [eventually this will replace the BSD getopt]
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
getopt(int nargc, char * const *nargv, const char *options)
|
|
||||||
{
|
|
||||||
|
|
||||||
/*
|
|
||||||
* We don't pass FLAG_PERMUTE to getopt_internal() since
|
|
||||||
* the BSD getopt(3) (unlike GNU) has never done this.
|
|
||||||
*
|
|
||||||
* Furthermore, since many privileged programs call getopt()
|
|
||||||
* before dropping privileges it makes sense to keep things
|
|
||||||
* as simple (and bug-free) as possible.
|
|
||||||
*/
|
|
||||||
return (getopt_internal(nargc, nargv, options, NULL, NULL, 0));
|
|
||||||
}
|
|
||||||
#endif /* REPLACE_GETOPT */
|
|
||||||
|
|
||||||
//extern int getopt(int nargc, char * const *nargv, const char *options);
|
|
||||||
|
|
||||||
#ifdef _BSD_SOURCE
|
|
||||||
/*
|
|
||||||
* BSD adds the non-standard `optreset' feature, for reinitialisation
|
|
||||||
* of `getopt' parsing. We support this feature, for applications which
|
|
||||||
* proclaim their BSD heritage, before including this header; however,
|
|
||||||
* to maintain portability, developers are advised to avoid it.
|
|
||||||
*/
|
|
||||||
# define optreset __mingw_optreset
|
|
||||||
extern int optreset;
|
|
||||||
#endif
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
/*
|
|
||||||
* POSIX requires the `getopt' API to be specified in `unistd.h';
|
|
||||||
* thus, `unistd.h' includes this header. However, we do not want
|
|
||||||
* to expose the `getopt_long' or `getopt_long_only' APIs, when
|
|
||||||
* included in this manner. Thus, close the standard __GETOPT_H__
|
|
||||||
* declarations block, and open an additional __GETOPT_LONG_H__
|
|
||||||
* specific block, only when *not* __UNISTD_H_SOURCED__, in which
|
|
||||||
* to declare the extended API.
|
|
||||||
*/
|
|
||||||
#endif /* !defined(__GETOPT_H__) */
|
|
||||||
|
|
||||||
#if !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__)
|
|
||||||
#define __GETOPT_LONG_H__
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum /* permitted values for its `has_arg' field... */
|
|
||||||
{
|
|
||||||
no_argument = 0, /* option never takes an argument */
|
|
||||||
required_argument, /* option always requires an argument */
|
|
||||||
optional_argument /* option may take an argument */
|
|
||||||
};
|
|
||||||
|
|
||||||
/*
|
|
||||||
* parse_long_options --
|
|
||||||
* Parse long options in argc/argv argument vector.
|
|
||||||
* Returns -1 if short_too is set and the option does not match long_options.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
parse_long_options(char * const *nargv, const char *options,
|
|
||||||
const struct option *long_options, int *idx, int short_too)
|
|
||||||
{
|
|
||||||
char *current_argv, *has_equal;
|
|
||||||
size_t current_argv_len;
|
|
||||||
int i, ambiguous, match;
|
|
||||||
|
|
||||||
#define IDENTICAL_INTERPRETATION(_x, _y) \
|
|
||||||
(long_options[(_x)].has_arg == long_options[(_y)].has_arg && \
|
|
||||||
long_options[(_x)].flag == long_options[(_y)].flag && \
|
|
||||||
long_options[(_x)].val == long_options[(_y)].val)
|
|
||||||
|
|
||||||
current_argv = place;
|
|
||||||
match = -1;
|
|
||||||
ambiguous = 0;
|
|
||||||
|
|
||||||
optind++;
|
|
||||||
|
|
||||||
if ((has_equal = strchr(current_argv, '=')) != NULL) {
|
|
||||||
/* argument found (--option=arg) */
|
|
||||||
current_argv_len = has_equal - current_argv;
|
|
||||||
has_equal++;
|
|
||||||
} else
|
|
||||||
current_argv_len = strlen(current_argv);
|
|
||||||
|
|
||||||
for (i = 0; long_options[i].name; i++) {
|
|
||||||
/* find matching long option */
|
|
||||||
if (strncmp(current_argv, long_options[i].name,
|
|
||||||
current_argv_len))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (strlen(long_options[i].name) == current_argv_len) {
|
|
||||||
/* exact match */
|
|
||||||
match = i;
|
|
||||||
ambiguous = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
* If this is a known short option, don't allow
|
|
||||||
* a partial match of a single character.
|
|
||||||
*/
|
|
||||||
if (short_too && current_argv_len == 1)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (match == -1) /* partial match */
|
|
||||||
match = i;
|
|
||||||
else if (!IDENTICAL_INTERPRETATION(i, match))
|
|
||||||
ambiguous = 1;
|
|
||||||
}
|
|
||||||
if (ambiguous) {
|
|
||||||
/* ambiguous abbreviation */
|
|
||||||
if (PRINT_ERROR)
|
|
||||||
warnx(ambig, (int)current_argv_len,
|
|
||||||
current_argv);
|
|
||||||
optopt = 0;
|
|
||||||
return (BADCH);
|
|
||||||
}
|
|
||||||
if (match != -1) { /* option found */
|
|
||||||
if (long_options[match].has_arg == no_argument
|
|
||||||
&& has_equal) {
|
|
||||||
if (PRINT_ERROR)
|
|
||||||
warnx(noarg, (int)current_argv_len,
|
|
||||||
current_argv);
|
|
||||||
/*
|
|
||||||
* XXX: GNU sets optopt to val regardless of flag
|
|
||||||
*/
|
|
||||||
if (long_options[match].flag == NULL)
|
|
||||||
optopt = long_options[match].val;
|
|
||||||
else
|
|
||||||
optopt = 0;
|
|
||||||
return (BADARG);
|
|
||||||
}
|
|
||||||
if (long_options[match].has_arg == required_argument ||
|
|
||||||
long_options[match].has_arg == optional_argument) {
|
|
||||||
if (has_equal)
|
|
||||||
optarg = has_equal;
|
|
||||||
else if (long_options[match].has_arg ==
|
|
||||||
required_argument) {
|
|
||||||
/*
|
|
||||||
* optional argument doesn't use next nargv
|
|
||||||
*/
|
|
||||||
optarg = nargv[optind++];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((long_options[match].has_arg == required_argument)
|
|
||||||
&& (optarg == NULL)) {
|
|
||||||
/*
|
|
||||||
* Missing argument; leading ':' indicates no error
|
|
||||||
* should be generated.
|
|
||||||
*/
|
|
||||||
if (PRINT_ERROR)
|
|
||||||
warnx(recargstring,
|
|
||||||
current_argv);
|
|
||||||
/*
|
|
||||||
* XXX: GNU sets optopt to val regardless of flag
|
|
||||||
*/
|
|
||||||
if (long_options[match].flag == NULL)
|
|
||||||
optopt = long_options[match].val;
|
|
||||||
else
|
|
||||||
optopt = 0;
|
|
||||||
--optind;
|
|
||||||
return (BADARG);
|
|
||||||
}
|
|
||||||
} else { /* unknown option */
|
|
||||||
if (short_too) {
|
|
||||||
--optind;
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
if (PRINT_ERROR)
|
|
||||||
warnx(illoptstring, current_argv);
|
|
||||||
optopt = 0;
|
|
||||||
return (BADCH);
|
|
||||||
}
|
|
||||||
if (idx)
|
|
||||||
*idx = match;
|
|
||||||
if (long_options[match].flag) {
|
|
||||||
*long_options[match].flag = long_options[match].val;
|
|
||||||
return (0);
|
|
||||||
} else
|
|
||||||
return (long_options[match].val);
|
|
||||||
#undef IDENTICAL_INTERPRETATION
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* getopt_internal --
|
|
||||||
* Parse argc/argv argument vector. Called by user level routines.
|
|
||||||
*/
|
|
||||||
static int
|
|
||||||
getopt_internal(int nargc, char * const *nargv, const char *options,
|
|
||||||
const struct option *long_options, int *idx, int flags)
|
|
||||||
{
|
|
||||||
char *oli; /* option letter list index */
|
|
||||||
int optchar, short_too;
|
|
||||||
static int posixly_correct = -1;
|
|
||||||
|
|
||||||
if (options == NULL)
|
|
||||||
return (-1);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* XXX Some GNU programs (like cvs) set optind to 0 instead of
|
|
||||||
* XXX using optreset. Work around this braindamage.
|
|
||||||
*/
|
|
||||||
if (optind == 0)
|
|
||||||
optind = optreset = 1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Disable GNU extensions if POSIXLY_CORRECT is set or options
|
|
||||||
* string begins with a '+'.
|
|
||||||
*
|
|
||||||
* CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or
|
|
||||||
* optreset != 0 for GNU compatibility.
|
|
||||||
*/
|
|
||||||
if (posixly_correct == -1 || optreset != 0)
|
|
||||||
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
|
|
||||||
if (*options == '-')
|
|
||||||
flags |= FLAG_ALLARGS;
|
|
||||||
else if (posixly_correct || *options == '+')
|
|
||||||
flags &= ~FLAG_PERMUTE;
|
|
||||||
if (*options == '+' || *options == '-')
|
|
||||||
options++;
|
|
||||||
|
|
||||||
optarg = NULL;
|
|
||||||
if (optreset)
|
|
||||||
nonopt_start = nonopt_end = -1;
|
|
||||||
start:
|
|
||||||
if (optreset || !*place) { /* update scanning pointer */
|
|
||||||
optreset = 0;
|
|
||||||
if (optind >= nargc) { /* end of argument vector */
|
|
||||||
place = EMSG;
|
|
||||||
if (nonopt_end != -1) {
|
|
||||||
/* do permutation, if we have to */
|
|
||||||
permute_args(nonopt_start, nonopt_end,
|
|
||||||
optind, nargv);
|
|
||||||
optind -= nonopt_end - nonopt_start;
|
|
||||||
}
|
|
||||||
else if (nonopt_start != -1) {
|
|
||||||
/*
|
|
||||||
* If we skipped non-options, set optind
|
|
||||||
* to the first of them.
|
|
||||||
*/
|
|
||||||
optind = nonopt_start;
|
|
||||||
}
|
|
||||||
nonopt_start = nonopt_end = -1;
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
if (*(place = nargv[optind]) != '-' ||
|
|
||||||
(place[1] == '\0' && strchr(options, '-') == NULL)) {
|
|
||||||
place = EMSG; /* found non-option */
|
|
||||||
if (flags & FLAG_ALLARGS) {
|
|
||||||
/*
|
|
||||||
* GNU extension:
|
|
||||||
* return non-option as argument to option 1
|
|
||||||
*/
|
|
||||||
optarg = nargv[optind++];
|
|
||||||
return (INORDER);
|
|
||||||
}
|
|
||||||
if (!(flags & FLAG_PERMUTE)) {
|
|
||||||
/*
|
|
||||||
* If no permutation wanted, stop parsing
|
|
||||||
* at first non-option.
|
|
||||||
*/
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
/* do permutation */
|
|
||||||
if (nonopt_start == -1)
|
|
||||||
nonopt_start = optind;
|
|
||||||
else if (nonopt_end != -1) {
|
|
||||||
permute_args(nonopt_start, nonopt_end,
|
|
||||||
optind, nargv);
|
|
||||||
nonopt_start = optind -
|
|
||||||
(nonopt_end - nonopt_start);
|
|
||||||
nonopt_end = -1;
|
|
||||||
}
|
|
||||||
optind++;
|
|
||||||
/* process next argument */
|
|
||||||
goto start;
|
|
||||||
}
|
|
||||||
if (nonopt_start != -1 && nonopt_end == -1)
|
|
||||||
nonopt_end = optind;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* If we have "-" do nothing, if "--" we are done.
|
|
||||||
*/
|
|
||||||
if (place[1] != '\0' && *++place == '-' && place[1] == '\0') {
|
|
||||||
optind++;
|
|
||||||
place = EMSG;
|
|
||||||
/*
|
|
||||||
* We found an option (--), so if we skipped
|
|
||||||
* non-options, we have to permute.
|
|
||||||
*/
|
|
||||||
if (nonopt_end != -1) {
|
|
||||||
permute_args(nonopt_start, nonopt_end,
|
|
||||||
optind, nargv);
|
|
||||||
optind -= nonopt_end - nonopt_start;
|
|
||||||
}
|
|
||||||
nonopt_start = nonopt_end = -1;
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Check long options if:
|
|
||||||
* 1) we were passed some
|
|
||||||
* 2) the arg is not just "-"
|
|
||||||
* 3) either the arg starts with -- we are getopt_long_only()
|
|
||||||
*/
|
|
||||||
if (long_options != NULL && place != nargv[optind] &&
|
|
||||||
(*place == '-' || (flags & FLAG_LONGONLY))) {
|
|
||||||
short_too = 0;
|
|
||||||
if (*place == '-')
|
|
||||||
place++; /* --foo long option */
|
|
||||||
else if (*place != ':' && strchr(options, *place) != NULL)
|
|
||||||
short_too = 1; /* could be short option too */
|
|
||||||
|
|
||||||
optchar = parse_long_options(nargv, options, long_options,
|
|
||||||
idx, short_too);
|
|
||||||
if (optchar != -1) {
|
|
||||||
place = EMSG;
|
|
||||||
return (optchar);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((optchar = (int)*place++) == (int)':' ||
|
|
||||||
(optchar == (int)'-' && *place != '\0') ||
|
|
||||||
(oli = (char*)strchr(options, optchar)) == NULL) {
|
|
||||||
/*
|
|
||||||
* If the user specified "-" and '-' isn't listed in
|
|
||||||
* options, return -1 (non-option) as per POSIX.
|
|
||||||
* Otherwise, it is an unknown option character (or ':').
|
|
||||||
*/
|
|
||||||
if (optchar == (int)'-' && *place == '\0')
|
|
||||||
return (-1);
|
|
||||||
if (!*place)
|
|
||||||
++optind;
|
|
||||||
if (PRINT_ERROR)
|
|
||||||
warnx(illoptchar, optchar);
|
|
||||||
optopt = optchar;
|
|
||||||
return (BADCH);
|
|
||||||
}
|
|
||||||
if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
|
|
||||||
/* -W long-option */
|
|
||||||
if (*place) /* no space */
|
|
||||||
/* NOTHING */;
|
|
||||||
else if (++optind >= nargc) { /* no arg */
|
|
||||||
place = EMSG;
|
|
||||||
if (PRINT_ERROR)
|
|
||||||
warnx(recargchar, optchar);
|
|
||||||
optopt = optchar;
|
|
||||||
return (BADARG);
|
|
||||||
} else /* white space */
|
|
||||||
place = nargv[optind];
|
|
||||||
optchar = parse_long_options(nargv, options, long_options,
|
|
||||||
idx, 0);
|
|
||||||
place = EMSG;
|
|
||||||
return (optchar);
|
|
||||||
}
|
|
||||||
if (*++oli != ':') { /* doesn't take argument */
|
|
||||||
if (!*place)
|
|
||||||
++optind;
|
|
||||||
} else { /* takes (optional) argument */
|
|
||||||
optarg = NULL;
|
|
||||||
if (*place) /* no white space */
|
|
||||||
optarg = place;
|
|
||||||
else if (oli[1] != ':') { /* arg not optional */
|
|
||||||
if (++optind >= nargc) { /* no arg */
|
|
||||||
place = EMSG;
|
|
||||||
if (PRINT_ERROR)
|
|
||||||
warnx(recargchar, optchar);
|
|
||||||
optopt = optchar;
|
|
||||||
return (BADARG);
|
|
||||||
} else
|
|
||||||
optarg = nargv[optind];
|
|
||||||
}
|
|
||||||
place = EMSG;
|
|
||||||
++optind;
|
|
||||||
}
|
|
||||||
/* dump back option letter */
|
|
||||||
return (optchar);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* getopt_long --
|
|
||||||
* Parse argc/argv argument vector.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
getopt_long(int nargc, char * const *nargv, const char *options,
|
|
||||||
const struct option *long_options, int *idx)
|
|
||||||
{
|
|
||||||
|
|
||||||
return (getopt_internal(nargc, nargv, options, long_options, idx,
|
|
||||||
FLAG_PERMUTE));
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* getopt_long_only --
|
|
||||||
* Parse argc/argv argument vector.
|
|
||||||
*/
|
|
||||||
int
|
|
||||||
getopt_long_only(int nargc, char * const *nargv, const char *options,
|
|
||||||
const struct option *long_options, int *idx)
|
|
||||||
{
|
|
||||||
|
|
||||||
return (getopt_internal(nargc, nargv, options, long_options, idx,
|
|
||||||
FLAG_PERMUTE|FLAG_LONGONLY));
|
|
||||||
}
|
|
||||||
|
|
||||||
//extern int getopt_long(int nargc, char * const *nargv, const char *options,
|
|
||||||
// const struct option *long_options, int *idx);
|
|
||||||
//extern int getopt_long_only(int nargc, char * const *nargv, const char *options,
|
|
||||||
// const struct option *long_options, int *idx);
|
|
||||||
/*
|
|
||||||
* Previous MinGW implementation had...
|
|
||||||
*/
|
|
||||||
#ifndef HAVE_DECL_GETOPT
|
|
||||||
/*
|
|
||||||
* ...for the long form API only; keep this for compatibility.
|
|
||||||
*/
|
|
||||||
# define HAVE_DECL_GETOPT 1
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* !defined(__UNISTD_H_SOURCED__) && !defined(__GETOPT_LONG_H__) */
|
|
99
libbf.c
99
libbf.c
|
@ -37,10 +37,12 @@
|
||||||
|
|
||||||
/* enable it to check the multiplication result */
|
/* enable it to check the multiplication result */
|
||||||
//#define USE_MUL_CHECK
|
//#define USE_MUL_CHECK
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
/* enable it to use FFT/NTT multiplication */
|
/* enable it to use FFT/NTT multiplication */
|
||||||
#define USE_FFT_MUL
|
#define USE_FFT_MUL
|
||||||
/* enable decimal floating point support */
|
/* enable decimal floating point support */
|
||||||
#define USE_BF_DEC
|
#define USE_BF_DEC
|
||||||
|
#endif
|
||||||
|
|
||||||
//#define inline __attribute__((always_inline))
|
//#define inline __attribute__((always_inline))
|
||||||
|
|
||||||
|
@ -134,6 +136,7 @@ static inline slimb_t ceil_div(slimb_t a, slimb_t b)
|
||||||
return a / b;
|
return a / b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_BF_DEC
|
||||||
/* b must be >= 1 */
|
/* b must be >= 1 */
|
||||||
static inline slimb_t floor_div(slimb_t a, slimb_t b)
|
static inline slimb_t floor_div(slimb_t a, slimb_t b)
|
||||||
{
|
{
|
||||||
|
@ -143,6 +146,7 @@ static inline slimb_t floor_div(slimb_t a, slimb_t b)
|
||||||
return (a - b + 1) / b;
|
return (a - b + 1) / b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* return r = a modulo b (0 <= r <= b - 1. b must be >= 1 */
|
/* return r = a modulo b (0 <= r <= b - 1. b must be >= 1 */
|
||||||
static inline limb_t smod(slimb_t a, slimb_t b)
|
static inline limb_t smod(slimb_t a, slimb_t b)
|
||||||
|
@ -307,8 +311,7 @@ int bf_set(bf_t *r, const bf_t *a)
|
||||||
}
|
}
|
||||||
r->sign = a->sign;
|
r->sign = a->sign;
|
||||||
r->expn = a->expn;
|
r->expn = a->expn;
|
||||||
if (a->len > 0)
|
memcpy_no_ub(r->tab, a->tab, a->len * sizeof(limb_t));
|
||||||
memcpy(r->tab, a->tab, a->len * sizeof(limb_t));
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1601,7 +1604,9 @@ int bf_mul(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec,
|
||||||
r = &tmp;
|
r = &tmp;
|
||||||
}
|
}
|
||||||
if (bf_resize(r, a_len + b_len)) {
|
if (bf_resize(r, a_len + b_len)) {
|
||||||
|
#ifdef USE_FFT_MUL
|
||||||
fail:
|
fail:
|
||||||
|
#endif
|
||||||
bf_set_nan(r);
|
bf_set_nan(r);
|
||||||
ret = BF_ST_MEM_ERROR;
|
ret = BF_ST_MEM_ERROR;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -1710,13 +1715,6 @@ static int __bf_div(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec,
|
||||||
slimb_t d;
|
slimb_t d;
|
||||||
|
|
||||||
na = n + nb;
|
na = n + nb;
|
||||||
|
|
||||||
#if LIMB_LOG2_BITS == 6
|
|
||||||
if (na >= (SIZE_MAX / sizeof(limb_t)) - 1) {
|
|
||||||
return BF_ST_MEM_ERROR; /* Return memory error status */
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
taba = bf_malloc(s, (na + 1) * sizeof(limb_t));
|
taba = bf_malloc(s, (na + 1) * sizeof(limb_t));
|
||||||
if (!taba)
|
if (!taba)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -2305,11 +2303,14 @@ static int bf_pow_ui_ui(bf_t *r, limb_t a1, limb_t b,
|
||||||
bf_t a;
|
bf_t a;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
#ifdef USE_BF_DEC
|
||||||
if (a1 == 10 && b <= LIMB_DIGITS) {
|
if (a1 == 10 && b <= LIMB_DIGITS) {
|
||||||
/* use precomputed powers. We do not round at this point
|
/* use precomputed powers. We do not round at this point
|
||||||
because we expect the caller to do it */
|
because we expect the caller to do it */
|
||||||
ret = bf_set_ui(r, mp_pow_dec[b]);
|
ret = bf_set_ui(r, mp_pow_dec[b]);
|
||||||
} else {
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
bf_init(r->ctx, &a);
|
bf_init(r->ctx, &a);
|
||||||
ret = bf_set_ui(&a, a1);
|
ret = bf_set_ui(&a, a1);
|
||||||
ret |= bf_pow_ui(r, &a, b, prec, flags);
|
ret |= bf_pow_ui(r, &a, b, prec, flags);
|
||||||
|
@ -2840,7 +2841,7 @@ int bf_mul_pow_radix(bf_t *r, const bf_t *T, limb_t radix,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int bf_to_digit(int c)
|
static inline int to_digit(int c)
|
||||||
{
|
{
|
||||||
if (c >= '0' && c <= '9')
|
if (c >= '0' && c <= '9')
|
||||||
return c - '0';
|
return c - '0';
|
||||||
|
@ -2947,7 +2948,7 @@ static int bf_atof_internal(bf_t *r, slimb_t *pexponent,
|
||||||
goto no_prefix;
|
goto no_prefix;
|
||||||
}
|
}
|
||||||
/* there must be a digit after the prefix */
|
/* there must be a digit after the prefix */
|
||||||
if (bf_to_digit((uint8_t)*p) >= radix) {
|
if (to_digit((uint8_t)*p) >= radix) {
|
||||||
bf_set_nan(r);
|
bf_set_nan(r);
|
||||||
ret = 0;
|
ret = 0;
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -2995,14 +2996,14 @@ static int bf_atof_internal(bf_t *r, slimb_t *pexponent,
|
||||||
int_len = digit_count = 0;
|
int_len = digit_count = 0;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
limb_t c;
|
limb_t c;
|
||||||
if (*p == '.' && (p > p_start || bf_to_digit(p[1]) < radix)) {
|
if (*p == '.' && (p > p_start || to_digit(p[1]) < radix)) {
|
||||||
if (has_decpt)
|
if (has_decpt)
|
||||||
break;
|
break;
|
||||||
has_decpt = TRUE;
|
has_decpt = TRUE;
|
||||||
int_len = digit_count;
|
int_len = digit_count;
|
||||||
p++;
|
p++;
|
||||||
}
|
}
|
||||||
c = bf_to_digit(*p);
|
c = to_digit(*p);
|
||||||
if (c >= radix)
|
if (c >= radix)
|
||||||
break;
|
break;
|
||||||
digit_count++;
|
digit_count++;
|
||||||
|
@ -3083,7 +3084,7 @@ static int bf_atof_internal(bf_t *r, slimb_t *pexponent,
|
||||||
}
|
}
|
||||||
for(;;) {
|
for(;;) {
|
||||||
int c;
|
int c;
|
||||||
c = bf_to_digit(*p);
|
c = to_digit(*p);
|
||||||
if (c >= 10)
|
if (c >= 10)
|
||||||
break;
|
break;
|
||||||
if (unlikely(expn > ((BF_RAW_EXP_MAX - 2 - 9) / 10))) {
|
if (unlikely(expn > ((BF_RAW_EXP_MAX - 2 - 9) / 10))) {
|
||||||
|
@ -4821,6 +4822,11 @@ int bf_pow(bf_t *r, const bf_t *x, const bf_t *y, limb_t prec, bf_flags_t flags)
|
||||||
bf_t *y1;
|
bf_t *y1;
|
||||||
if (y_emin < 0 && check_exact_power2n(r, T, -y_emin)) {
|
if (y_emin < 0 && check_exact_power2n(r, T, -y_emin)) {
|
||||||
/* the problem is reduced to a power to an integer */
|
/* the problem is reduced to a power to an integer */
|
||||||
|
#if 0
|
||||||
|
printf("\nn=%" PRId64 "\n", -(int64_t)y_emin);
|
||||||
|
bf_print_str("T", T);
|
||||||
|
bf_print_str("r", r);
|
||||||
|
#endif
|
||||||
bf_set(T, r);
|
bf_set(T, r);
|
||||||
y1 = &ytmp_s;
|
y1 = &ytmp_s;
|
||||||
y1->tab = y->tab;
|
y1->tab = y->tab;
|
||||||
|
@ -5372,20 +5378,19 @@ int bf_acos(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags)
|
||||||
#if LIMB_BITS == 64
|
#if LIMB_BITS == 64
|
||||||
|
|
||||||
/* Note: we assume __int128 is available */
|
/* Note: we assume __int128 is available */
|
||||||
/* uint128_t defined in libbf.h */
|
|
||||||
#define muldq(r1, r0, a, b) \
|
#define muldq(r1, r0, a, b) \
|
||||||
do { \
|
do { \
|
||||||
uint128_t __t; \
|
unsigned __int128 __t; \
|
||||||
__t = (uint128_t)(a) * (uint128_t)(b); \
|
__t = (unsigned __int128)(a) * (unsigned __int128)(b); \
|
||||||
r0 = __t; \
|
r0 = __t; \
|
||||||
r1 = __t >> 64; \
|
r1 = __t >> 64; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define divdq(q, r, a1, a0, b) \
|
#define divdq(q, r, a1, a0, b) \
|
||||||
do { \
|
do { \
|
||||||
uint128_t __t; \
|
unsigned __int128 __t; \
|
||||||
limb_t __b = (b); \
|
limb_t __b = (b); \
|
||||||
__t = ((uint128_t)(a1) << 64) | (a0); \
|
__t = ((unsigned __int128)(a1) << 64) | (a0); \
|
||||||
q = __t / __b; \
|
q = __t / __b; \
|
||||||
r = __t % __b; \
|
r = __t % __b; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -6330,6 +6335,34 @@ static limb_t get_digit(const limb_t *tab, limb_t len, slimb_t pos)
|
||||||
return fast_shr_dec(tab[i], shift) % 10;
|
return fast_shr_dec(tab[i], shift) % 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
static limb_t get_digits(const limb_t *tab, limb_t len, slimb_t pos)
|
||||||
|
{
|
||||||
|
limb_t a0, a1;
|
||||||
|
int shift;
|
||||||
|
slimb_t i;
|
||||||
|
|
||||||
|
i = floor_div(pos, LIMB_DIGITS);
|
||||||
|
shift = pos - i * LIMB_DIGITS;
|
||||||
|
if (i >= 0 && i < len)
|
||||||
|
a0 = tab[i];
|
||||||
|
else
|
||||||
|
a0 = 0;
|
||||||
|
if (shift == 0) {
|
||||||
|
return a0;
|
||||||
|
} else {
|
||||||
|
i++;
|
||||||
|
if (i >= 0 && i < len)
|
||||||
|
a1 = tab[i];
|
||||||
|
else
|
||||||
|
a1 = 0;
|
||||||
|
return fast_shr_dec(a0, shift) +
|
||||||
|
fast_urem(a1, &mp_pow_div[LIMB_DIGITS - shift]) *
|
||||||
|
mp_pow_dec[shift];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* return the addend for rounding. Note that prec can be <= 0 for bf_rint() */
|
/* return the addend for rounding. Note that prec can be <= 0 for bf_rint() */
|
||||||
static int bfdec_get_rnd_add(int *pret, const bfdec_t *r, limb_t l,
|
static int bfdec_get_rnd_add(int *pret, const bfdec_t *r, limb_t l,
|
||||||
slimb_t prec, int rnd_mode)
|
slimb_t prec, int rnd_mode)
|
||||||
|
@ -7956,6 +7989,12 @@ static no_inline void limb_to_ntt(BFNTTState *s,
|
||||||
int j, shift;
|
int j, shift;
|
||||||
limb_t base_mask1, a0, a1, a2, r, m, m_inv;
|
limb_t base_mask1, a0, a1, a2, r, m, m_inv;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
for(i = 0; i < a_len; i++) {
|
||||||
|
printf("%" PRId64 ": " FMT_LIMB "\n",
|
||||||
|
(int64_t)i, taba[i]);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
memset(tabr, 0, sizeof(NTTLimb) * fft_len * nb_mods);
|
memset(tabr, 0, sizeof(NTTLimb) * fft_len * nb_mods);
|
||||||
shift = dpl & (LIMB_BITS - 1);
|
shift = dpl & (LIMB_BITS - 1);
|
||||||
if (shift == 0)
|
if (shift == 0)
|
||||||
|
@ -8082,6 +8121,14 @@ static no_inline void ntt_to_limb(BFNTTState *s, limb_t *tabr, limb_t r_len,
|
||||||
}
|
}
|
||||||
u[l] = r + carry[l];
|
u[l] = r + carry[l];
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("%" PRId64 ": ", i);
|
||||||
|
for(j = nb_mods - 1; j >= 0; j--) {
|
||||||
|
printf(" %019" PRIu64, u[j]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
/* write the digits */
|
/* write the digits */
|
||||||
pos = i * dpl;
|
pos = i * dpl;
|
||||||
for(j = 0; j < n_limb1; j++) {
|
for(j = 0; j < n_limb1; j++) {
|
||||||
|
@ -8175,6 +8222,14 @@ static no_inline void ntt_to_limb(BFNTTState *s, limb_t *tabr, limb_t r_len,
|
||||||
}
|
}
|
||||||
u[l] = r + carry[l];
|
u[l] = r + carry[l];
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
printf("%" PRId64 ": ", (int64_t)i);
|
||||||
|
for(j = nb_mods - 1; j >= 0; j--) {
|
||||||
|
printf(" " FMT_LIMB, u[j]);
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
|
|
||||||
/* write the digits */
|
/* write the digits */
|
||||||
pos = i * dpl;
|
pos = i * dpl;
|
||||||
for(j = 0; j < n_limb1; j++) {
|
for(j = 0; j < n_limb1; j++) {
|
||||||
|
@ -8418,7 +8473,3 @@ int bf_get_fft_size(int *pdpl, int *pnb_mods, limb_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* !USE_FFT_MUL */
|
#endif /* !USE_FFT_MUL */
|
||||||
|
|
||||||
#undef malloc
|
|
||||||
#undef free
|
|
||||||
#undef realloc
|
|
||||||
|
|
16
libbf.h
16
libbf.h
|
@ -27,11 +27,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#if defined(__SIZEOF_INT128__) && (INTPTR_MAX >= INT64_MAX)
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if INTPTR_MAX >= INT64_MAX && !defined(_WIN32) && !defined(__TINYC__)
|
|
||||||
#define LIMB_LOG2_BITS 6
|
#define LIMB_LOG2_BITS 6
|
||||||
#else
|
#else
|
||||||
#define LIMB_LOG2_BITS 5
|
#define LIMB_LOG2_BITS 5
|
||||||
|
@ -40,10 +36,8 @@ extern "C" {
|
||||||
#define LIMB_BITS (1 << LIMB_LOG2_BITS)
|
#define LIMB_BITS (1 << LIMB_LOG2_BITS)
|
||||||
|
|
||||||
#if LIMB_BITS == 64
|
#if LIMB_BITS == 64
|
||||||
#ifndef INT128_MAX
|
typedef __int128 int128_t;
|
||||||
__extension__ typedef __int128 int128_t;
|
typedef unsigned __int128 uint128_t;
|
||||||
__extension__ typedef unsigned __int128 uint128_t;
|
|
||||||
#endif
|
|
||||||
typedef int64_t slimb_t;
|
typedef int64_t slimb_t;
|
||||||
typedef uint64_t limb_t;
|
typedef uint64_t limb_t;
|
||||||
typedef uint128_t dlimb_t;
|
typedef uint128_t dlimb_t;
|
||||||
|
@ -538,8 +532,4 @@ static inline int bfdec_resize(bfdec_t *r, limb_t len)
|
||||||
}
|
}
|
||||||
int bfdec_normalize_and_round(bfdec_t *r, limb_t prec1, bf_flags_t flags);
|
int bfdec_normalize_and_round(bfdec_t *r, limb_t prec1, bf_flags_t flags);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" { */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* LIBBF_H */
|
#endif /* LIBBF_H */
|
||||||
|
|
|
@ -25,8 +25,7 @@
|
||||||
#ifdef DEF
|
#ifdef DEF
|
||||||
|
|
||||||
DEF(invalid, 1) /* never used */
|
DEF(invalid, 1) /* never used */
|
||||||
DEF(char8, 2) /* 7 bits in fact */
|
DEF(char, 3)
|
||||||
DEF(char16, 3)
|
|
||||||
DEF(char32, 5)
|
DEF(char32, 5)
|
||||||
DEF(dot, 1)
|
DEF(dot, 1)
|
||||||
DEF(any, 1) /* same as dot but match any character including line terminator */
|
DEF(any, 1) /* same as dot but match any character including line terminator */
|
||||||
|
|
321
libregexp.c
321
libregexp.c
|
@ -30,6 +30,7 @@
|
||||||
|
|
||||||
#include "cutils.h"
|
#include "cutils.h"
|
||||||
#include "libregexp.h"
|
#include "libregexp.h"
|
||||||
|
#include "libunicode.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
TODO:
|
TODO:
|
||||||
|
@ -60,7 +61,6 @@ typedef enum {
|
||||||
|
|
||||||
#define TMP_BUF_SIZE 128
|
#define TMP_BUF_SIZE 128
|
||||||
|
|
||||||
// invariant: is_unicode ^ unicode_sets (or neither, but not both)
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
DynBuf byte_code;
|
DynBuf byte_code;
|
||||||
const uint8_t *buf_ptr;
|
const uint8_t *buf_ptr;
|
||||||
|
@ -68,7 +68,6 @@ typedef struct {
|
||||||
const uint8_t *buf_start;
|
const uint8_t *buf_start;
|
||||||
int re_flags;
|
int re_flags;
|
||||||
BOOL is_unicode;
|
BOOL is_unicode;
|
||||||
BOOL unicode_sets;
|
|
||||||
BOOL ignore_case;
|
BOOL ignore_case;
|
||||||
BOOL dotall;
|
BOOL dotall;
|
||||||
int capture_count;
|
int capture_count;
|
||||||
|
@ -100,13 +99,13 @@ static const REOpCode reopcode_info[REOP_COUNT] = {
|
||||||
};
|
};
|
||||||
|
|
||||||
#define RE_HEADER_FLAGS 0
|
#define RE_HEADER_FLAGS 0
|
||||||
#define RE_HEADER_CAPTURE_COUNT 2
|
#define RE_HEADER_CAPTURE_COUNT 1
|
||||||
#define RE_HEADER_STACK_SIZE 3
|
#define RE_HEADER_STACK_SIZE 2
|
||||||
#define RE_HEADER_BYTECODE_LEN 4
|
#define RE_HEADER_BYTECODE_LEN 3
|
||||||
|
|
||||||
#define RE_HEADER_LEN 8
|
#define RE_HEADER_LEN 7
|
||||||
|
|
||||||
static inline int lre_is_digit(int c) {
|
static inline int is_digit(int c) {
|
||||||
return c >= '0' && c <= '9';
|
return c >= '0' && c <= '9';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,32 +142,6 @@ static const uint16_t char_range_s[] = {
|
||||||
0xFEFF, 0xFEFF + 1,
|
0xFEFF, 0xFEFF + 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
BOOL lre_is_space(int c)
|
|
||||||
{
|
|
||||||
int i, n, low, high;
|
|
||||||
n = (countof(char_range_s) - 1) / 2;
|
|
||||||
for(i = 0; i < n; i++) {
|
|
||||||
low = char_range_s[2 * i + 1];
|
|
||||||
if (c < low)
|
|
||||||
return FALSE;
|
|
||||||
high = char_range_s[2 * i + 2];
|
|
||||||
if (c < high)
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t const lre_id_start_table_ascii[4] = {
|
|
||||||
/* $ A-Z _ a-z */
|
|
||||||
0x00000000, 0x00000010, 0x87FFFFFE, 0x07FFFFFE
|
|
||||||
};
|
|
||||||
|
|
||||||
uint32_t const lre_id_continue_table_ascii[4] = {
|
|
||||||
/* $ 0-9 A-Z _ a-z */
|
|
||||||
0x00000000, 0x03FF0010, 0x87FFFFFE, 0x07FFFFFE
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
static const uint16_t char_range_w[] = {
|
static const uint16_t char_range_w[] = {
|
||||||
4,
|
4,
|
||||||
0x0030, 0x0039 + 1,
|
0x0030, 0x0039 + 1,
|
||||||
|
@ -188,7 +161,7 @@ typedef enum {
|
||||||
CHAR_RANGE_W,
|
CHAR_RANGE_W,
|
||||||
} CharRangeEnum;
|
} CharRangeEnum;
|
||||||
|
|
||||||
static const uint16_t *char_range_table[] = {
|
static const uint16_t * const char_range_table[] = {
|
||||||
char_range_d,
|
char_range_d,
|
||||||
char_range_s,
|
char_range_s,
|
||||||
char_range_w,
|
char_range_w,
|
||||||
|
@ -263,15 +236,15 @@ static __maybe_unused void lre_dump_bytecode(const uint8_t *buf,
|
||||||
}
|
}
|
||||||
printf("%s", reopcode_info[opcode].name);
|
printf("%s", reopcode_info[opcode].name);
|
||||||
switch(opcode) {
|
switch(opcode) {
|
||||||
case REOP_char8:
|
case REOP_char:
|
||||||
val = get_u8(buf + pos + 1);
|
|
||||||
goto printchar;
|
|
||||||
case REOP_char16:
|
|
||||||
val = get_u16(buf + pos + 1);
|
val = get_u16(buf + pos + 1);
|
||||||
goto printchar;
|
if (val >= ' ' && val <= 126)
|
||||||
|
printf(" '%c'", val);
|
||||||
|
else
|
||||||
|
printf(" 0x%04x", val);
|
||||||
|
break;
|
||||||
case REOP_char32:
|
case REOP_char32:
|
||||||
val = get_u32(buf + pos + 1);
|
val = get_u32(buf + pos + 1);
|
||||||
printchar:
|
|
||||||
if (val >= ' ' && val <= 126)
|
if (val >= ' ' && val <= 126)
|
||||||
printf(" '%c'", val);
|
printf(" '%c'", val);
|
||||||
else
|
else
|
||||||
|
@ -521,7 +494,7 @@ int lre_parse_escape(const uint8_t **pp, int allow_utf16)
|
||||||
c -= '0';
|
c -= '0';
|
||||||
if (allow_utf16 == 2) {
|
if (allow_utf16 == 2) {
|
||||||
/* only accept \0 not followed by digit */
|
/* only accept \0 not followed by digit */
|
||||||
if (c != 0 || lre_is_digit(*p))
|
if (c != 0 || is_digit(*p))
|
||||||
return -1;
|
return -1;
|
||||||
} else {
|
} else {
|
||||||
/* parse a legacy octal sequence */
|
/* parse a legacy octal sequence */
|
||||||
|
@ -547,6 +520,7 @@ int lre_parse_escape(const uint8_t **pp, int allow_utf16)
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ALL_UNICODE
|
||||||
/* XXX: we use the same chars for name and value */
|
/* XXX: we use the same chars for name and value */
|
||||||
static BOOL is_unicode_char(int c)
|
static BOOL is_unicode_char(int c)
|
||||||
{
|
{
|
||||||
|
@ -649,6 +623,7 @@ static int parse_unicode_property(REParseState *s, CharRange *cr,
|
||||||
out_of_memory:
|
out_of_memory:
|
||||||
return re_parse_out_of_memory(s);
|
return re_parse_out_of_memory(s);
|
||||||
}
|
}
|
||||||
|
#endif /* CONFIG_ALL_UNICODE */
|
||||||
|
|
||||||
/* return -1 if error otherwise the character or a class range
|
/* return -1 if error otherwise the character or a class range
|
||||||
(CLASS_RANGE_BASE). In case of class range, 'cr' is
|
(CLASS_RANGE_BASE). In case of class range, 'cr' is
|
||||||
|
@ -656,7 +631,7 @@ static int parse_unicode_property(REParseState *s, CharRange *cr,
|
||||||
static int get_class_atom(REParseState *s, CharRange *cr,
|
static int get_class_atom(REParseState *s, CharRange *cr,
|
||||||
const uint8_t **pp, BOOL inclass)
|
const uint8_t **pp, BOOL inclass)
|
||||||
{
|
{
|
||||||
const uint8_t *p, *p_next;
|
const uint8_t *p;
|
||||||
uint32_t c;
|
uint32_t c;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -708,6 +683,7 @@ static int get_class_atom(REParseState *s, CharRange *cr,
|
||||||
c = '\\';
|
c = '\\';
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#ifdef CONFIG_ALL_UNICODE
|
||||||
case 'p':
|
case 'p':
|
||||||
case 'P':
|
case 'P':
|
||||||
if (s->is_unicode) {
|
if (s->is_unicode) {
|
||||||
|
@ -717,6 +693,7 @@ static int get_class_atom(REParseState *s, CharRange *cr,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* fall thru */
|
/* fall thru */
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
p--;
|
p--;
|
||||||
ret = lre_parse_escape(&p, s->is_unicode * 2);
|
ret = lre_parse_escape(&p, s->is_unicode * 2);
|
||||||
|
@ -727,9 +704,6 @@ static int get_class_atom(REParseState *s, CharRange *cr,
|
||||||
/* always valid to escape these characters */
|
/* always valid to escape these characters */
|
||||||
goto normal_char;
|
goto normal_char;
|
||||||
} else if (s->is_unicode) {
|
} else if (s->is_unicode) {
|
||||||
// special case: allowed inside [] but not outside
|
|
||||||
if (ret == -2 && *p == '-' && inclass)
|
|
||||||
goto normal_char;
|
|
||||||
invalid_escape:
|
invalid_escape:
|
||||||
return re_parse_error(s, "invalid escape sequence in regular expression");
|
return re_parse_error(s, "invalid escape sequence in regular expression");
|
||||||
} else {
|
} else {
|
||||||
|
@ -748,18 +722,15 @@ static int get_class_atom(REParseState *s, CharRange *cr,
|
||||||
/* fall thru */
|
/* fall thru */
|
||||||
default:
|
default:
|
||||||
normal_char:
|
normal_char:
|
||||||
p++;
|
/* normal char */
|
||||||
if (c >= 0x80) {
|
if (c >= 128) {
|
||||||
c = utf8_decode(p - 1, &p_next);
|
c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p);
|
||||||
if (p_next == p)
|
if ((unsigned)c > 0xffff && !s->is_unicode) {
|
||||||
return re_parse_error(s, "invalid UTF-8 sequence");
|
/* XXX: should handle non BMP-1 code points */
|
||||||
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
|
|
||||||
return re_parse_error(s, "malformed unicode char");
|
return re_parse_error(s, "malformed unicode char");
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
p++;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -805,8 +776,6 @@ static int re_emit_range(REParseState *s, const CharRange *cr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// s->unicode turns patterns like []] into syntax errors
|
|
||||||
// s->unicode_sets turns more patterns into errors, like [a-] or [[]
|
|
||||||
static int re_parse_char_class(REParseState *s, const uint8_t **pp)
|
static int re_parse_char_class(REParseState *s, const uint8_t **pp)
|
||||||
{
|
{
|
||||||
const uint8_t *p;
|
const uint8_t *p;
|
||||||
|
@ -819,25 +788,6 @@ static int re_parse_char_class(REParseState *s, const uint8_t **pp)
|
||||||
p = *pp;
|
p = *pp;
|
||||||
p++; /* skip '[' */
|
p++; /* skip '[' */
|
||||||
|
|
||||||
if (s->unicode_sets) {
|
|
||||||
static const char verboten[] =
|
|
||||||
"()[{}/-|" "\0"
|
|
||||||
"&&!!##$$%%**++,,..::;;<<==>>??@@``~~" "\0"
|
|
||||||
"^^^_^^";
|
|
||||||
const char *s = verboten;
|
|
||||||
int n = 1;
|
|
||||||
do {
|
|
||||||
if (!memcmp(s, p, n))
|
|
||||||
if (p[n] == ']')
|
|
||||||
goto invalid_class_range;
|
|
||||||
s += n;
|
|
||||||
if (!*s) {
|
|
||||||
s++;
|
|
||||||
n++;
|
|
||||||
}
|
|
||||||
} while (n < 4);
|
|
||||||
}
|
|
||||||
|
|
||||||
invert = FALSE;
|
invert = FALSE;
|
||||||
if (*p == '^') {
|
if (*p == '^') {
|
||||||
p++;
|
p++;
|
||||||
|
@ -850,11 +800,6 @@ static int re_parse_char_class(REParseState *s, const uint8_t **pp)
|
||||||
c1 = get_class_atom(s, cr1, &p, TRUE);
|
c1 = get_class_atom(s, cr1, &p, TRUE);
|
||||||
if ((int)c1 < 0)
|
if ((int)c1 < 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
if (*p == '-' && p[1] == ']' && s->unicode_sets) {
|
|
||||||
if (c1 >= CLASS_RANGE_BASE)
|
|
||||||
cr_free(cr1);
|
|
||||||
goto invalid_class_range;
|
|
||||||
}
|
|
||||||
if (*p == '-' && p[1] != ']') {
|
if (*p == '-' && p[1] != ']') {
|
||||||
const uint8_t *p0 = p + 1;
|
const uint8_t *p0 = p + 1;
|
||||||
if (c1 >= CLASS_RANGE_BASE) {
|
if (c1 >= CLASS_RANGE_BASE) {
|
||||||
|
@ -931,7 +876,6 @@ static BOOL re_need_check_advance(const uint8_t *bc_buf, int bc_buf_len)
|
||||||
|
|
||||||
ret = TRUE;
|
ret = TRUE;
|
||||||
pos = 0;
|
pos = 0;
|
||||||
|
|
||||||
while (pos < bc_buf_len) {
|
while (pos < bc_buf_len) {
|
||||||
opcode = bc_buf[pos];
|
opcode = bc_buf[pos];
|
||||||
len = reopcode_info[opcode].size;
|
len = reopcode_info[opcode].size;
|
||||||
|
@ -944,9 +888,8 @@ static BOOL re_need_check_advance(const uint8_t *bc_buf, int bc_buf_len)
|
||||||
val = get_u16(bc_buf + pos + 1);
|
val = get_u16(bc_buf + pos + 1);
|
||||||
len += val * 8;
|
len += val * 8;
|
||||||
goto simple_char;
|
goto simple_char;
|
||||||
|
case REOP_char:
|
||||||
case REOP_char32:
|
case REOP_char32:
|
||||||
case REOP_char16:
|
|
||||||
case REOP_char8:
|
|
||||||
case REOP_dot:
|
case REOP_dot:
|
||||||
case REOP_any:
|
case REOP_any:
|
||||||
simple_char:
|
simple_char:
|
||||||
|
@ -969,7 +912,7 @@ static BOOL re_need_check_advance(const uint8_t *bc_buf, int bc_buf_len)
|
||||||
case REOP_backward_back_reference:
|
case REOP_backward_back_reference:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
/* safe behvior: we cannot predict the outcome */
|
/* safe behavior: we cannot predict the outcome */
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
pos += len;
|
pos += len;
|
||||||
|
@ -998,9 +941,8 @@ static int re_is_simple_quantifier(const uint8_t *bc_buf, int bc_buf_len)
|
||||||
val = get_u16(bc_buf + pos + 1);
|
val = get_u16(bc_buf + pos + 1);
|
||||||
len += val * 8;
|
len += val * 8;
|
||||||
goto simple_char;
|
goto simple_char;
|
||||||
|
case REOP_char:
|
||||||
case REOP_char32:
|
case REOP_char32:
|
||||||
case REOP_char16:
|
|
||||||
case REOP_char8:
|
|
||||||
case REOP_dot:
|
case REOP_dot:
|
||||||
case REOP_any:
|
case REOP_any:
|
||||||
simple_char:
|
simple_char:
|
||||||
|
@ -1022,35 +964,35 @@ static int re_is_simple_quantifier(const uint8_t *bc_buf, int bc_buf_len)
|
||||||
/* '*pp' is the first char after '<' */
|
/* '*pp' is the first char after '<' */
|
||||||
static int re_parse_group_name(char *buf, int buf_size, const uint8_t **pp)
|
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;
|
uint32_t c, d;
|
||||||
char *q;
|
char *q;
|
||||||
|
|
||||||
p = *pp;
|
p = *pp;
|
||||||
q = buf;
|
q = buf;
|
||||||
for(;;) {
|
for(;;) {
|
||||||
c = *p++;
|
c = *p;
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
|
p++;
|
||||||
if (*p != 'u')
|
if (*p != 'u')
|
||||||
return -1;
|
return -1;
|
||||||
c = lre_parse_escape(&p, 2); // accept surrogate pairs
|
c = lre_parse_escape(&p, 2); // accept surrogate pairs
|
||||||
if ((int)c < 0)
|
|
||||||
return -1;
|
|
||||||
} else if (c == '>') {
|
} else if (c == '>') {
|
||||||
break;
|
break;
|
||||||
} else if (c >= 0x80) {
|
} else if (c >= 128) {
|
||||||
c = utf8_decode(p - 1, &p_next);
|
c = unicode_from_utf8(p, UTF8_CHAR_LEN_MAX, &p);
|
||||||
if (p_next == p)
|
|
||||||
return -1;
|
|
||||||
p = p_next;
|
|
||||||
if (is_hi_surrogate(c)) {
|
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)) {
|
if (is_lo_surrogate(d)) {
|
||||||
c = from_surrogate(c, d);
|
c = from_surrogate(c, d);
|
||||||
p = p_next;
|
p = p1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
p++;
|
||||||
}
|
}
|
||||||
|
if (c > 0x10FFFF)
|
||||||
|
return -1;
|
||||||
if (q == buf) {
|
if (q == buf) {
|
||||||
if (!lre_js_is_ident_first(c))
|
if (!lre_js_is_ident_first(c))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1060,15 +1002,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)
|
if ((q - buf + UTF8_CHAR_LEN_MAX + 1) > buf_size)
|
||||||
return -1;
|
return -1;
|
||||||
if (c < 0x80) {
|
if (c < 128) {
|
||||||
*q++ = c;
|
*q++ = c;
|
||||||
} else {
|
} else {
|
||||||
q += utf8_encode((uint8_t*)q, c);
|
q += unicode_to_utf8((uint8_t*)q, c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (q == buf)
|
if (q == buf)
|
||||||
return -1;
|
return -1;
|
||||||
*q = '\0';
|
*q = '\0';
|
||||||
|
p++;
|
||||||
*pp = p;
|
*pp = p;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1199,7 +1142,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
|
||||||
case '{':
|
case '{':
|
||||||
if (s->is_unicode) {
|
if (s->is_unicode) {
|
||||||
return re_parse_error(s, "syntax error");
|
return re_parse_error(s, "syntax error");
|
||||||
} else if (!lre_is_digit(p[1])) {
|
} else if (!is_digit(p[1])) {
|
||||||
/* Annex B: we accept '{' not followed by digits as a
|
/* Annex B: we accept '{' not followed by digits as a
|
||||||
normal atom */
|
normal atom */
|
||||||
goto parse_class_atom;
|
goto parse_class_atom;
|
||||||
|
@ -1209,7 +1152,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
|
||||||
parse_digits(&p1, TRUE);
|
parse_digits(&p1, TRUE);
|
||||||
if (*p1 == ',') {
|
if (*p1 == ',') {
|
||||||
p1++;
|
p1++;
|
||||||
if (lre_is_digit(*p1)) {
|
if (is_digit(*p1)) {
|
||||||
parse_digits(&p1, TRUE);
|
parse_digits(&p1, TRUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1357,7 +1300,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
|
||||||
p += 2;
|
p += 2;
|
||||||
c = 0;
|
c = 0;
|
||||||
if (s->is_unicode) {
|
if (s->is_unicode) {
|
||||||
if (lre_is_digit(*p)) {
|
if (is_digit(*p)) {
|
||||||
return re_parse_error(s, "invalid decimal escape in regular expression");
|
return re_parse_error(s, "invalid decimal escape in regular expression");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -1443,10 +1386,8 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
|
||||||
} else {
|
} else {
|
||||||
if (s->ignore_case)
|
if (s->ignore_case)
|
||||||
c = lre_canonicalize(c, s->is_unicode);
|
c = lre_canonicalize(c, s->is_unicode);
|
||||||
if (c <= 0x7f)
|
if (c <= 0xffff)
|
||||||
re_emit_op_u8(s, REOP_char8, c);
|
re_emit_op_u16(s, REOP_char, c);
|
||||||
else if (c <= 0xffff)
|
|
||||||
re_emit_op_u16(s, REOP_char16, c);
|
|
||||||
else
|
else
|
||||||
re_emit_op_u32(s, REOP_char32, c);
|
re_emit_op_u32(s, REOP_char32, c);
|
||||||
}
|
}
|
||||||
|
@ -1479,7 +1420,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
|
||||||
const uint8_t *p1 = p;
|
const uint8_t *p1 = p;
|
||||||
/* As an extension (see ES6 annex B), we accept '{' not
|
/* As an extension (see ES6 annex B), we accept '{' not
|
||||||
followed by digits as a normal atom */
|
followed by digits as a normal atom */
|
||||||
if (!lre_is_digit(p[1])) {
|
if (!is_digit(p[1])) {
|
||||||
if (s->is_unicode)
|
if (s->is_unicode)
|
||||||
goto invalid_quant_count;
|
goto invalid_quant_count;
|
||||||
break;
|
break;
|
||||||
|
@ -1489,7 +1430,7 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
|
||||||
quant_max = quant_min;
|
quant_max = quant_min;
|
||||||
if (*p == ',') {
|
if (*p == ',') {
|
||||||
p++;
|
p++;
|
||||||
if (lre_is_digit(*p)) {
|
if (is_digit(*p)) {
|
||||||
quant_max = parse_digits(&p, TRUE);
|
quant_max = parse_digits(&p, TRUE);
|
||||||
if (quant_max < quant_min) {
|
if (quant_max < quant_min) {
|
||||||
invalid_quant_count:
|
invalid_quant_count:
|
||||||
|
@ -1547,13 +1488,15 @@ static int re_parse_term(REParseState *s, BOOL is_backward_dir)
|
||||||
|
|
||||||
if (dbuf_error(&s->byte_code))
|
if (dbuf_error(&s->byte_code))
|
||||||
goto out_of_memory;
|
goto out_of_memory;
|
||||||
|
/* the spec tells that if there is no advance when
|
||||||
|
running the atom after the first quant_min times,
|
||||||
|
then there is no match. We remove this test when we
|
||||||
|
are sure the atom always advances the position. */
|
||||||
|
add_zero_advance_check = re_need_check_advance(s->byte_code.buf + last_atom_start,
|
||||||
|
s->byte_code.size - last_atom_start);
|
||||||
|
} else {
|
||||||
|
add_zero_advance_check = FALSE;
|
||||||
}
|
}
|
||||||
/* the spec tells that if there is no advance when
|
|
||||||
running the atom after the first quant_min times,
|
|
||||||
then there is no match. We remove this test when we
|
|
||||||
are sure the atom always advances the position. */
|
|
||||||
add_zero_advance_check = re_need_check_advance(s->byte_code.buf + last_atom_start,
|
|
||||||
s->byte_code.size - last_atom_start);
|
|
||||||
|
|
||||||
{
|
{
|
||||||
int len, pos;
|
int len, pos;
|
||||||
|
@ -1727,7 +1670,7 @@ static int re_parse_disjunction(REParseState *s, BOOL is_backward_dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* the control flow is recursive so the analysis can be linear */
|
/* the control flow is recursive so the analysis can be linear */
|
||||||
static int lre_compute_stack_size(const uint8_t *bc_buf, int bc_buf_len)
|
static int compute_stack_size(const uint8_t *bc_buf, int bc_buf_len)
|
||||||
{
|
{
|
||||||
int stack_size, stack_size_max, pos, opcode, len;
|
int stack_size, stack_size_max, pos, opcode, len;
|
||||||
uint32_t val;
|
uint32_t val;
|
||||||
|
@ -1793,7 +1736,6 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
|
||||||
is_sticky = ((re_flags & LRE_FLAG_STICKY) != 0);
|
is_sticky = ((re_flags & LRE_FLAG_STICKY) != 0);
|
||||||
s->ignore_case = ((re_flags & LRE_FLAG_IGNORECASE) != 0);
|
s->ignore_case = ((re_flags & LRE_FLAG_IGNORECASE) != 0);
|
||||||
s->dotall = ((re_flags & LRE_FLAG_DOTALL) != 0);
|
s->dotall = ((re_flags & LRE_FLAG_DOTALL) != 0);
|
||||||
s->unicode_sets = ((re_flags & LRE_FLAG_UNICODE_SETS) != 0);
|
|
||||||
s->capture_count = 1;
|
s->capture_count = 1;
|
||||||
s->total_capture_count = -1;
|
s->total_capture_count = -1;
|
||||||
s->has_named_captures = -1;
|
s->has_named_captures = -1;
|
||||||
|
@ -1801,7 +1743,7 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
|
||||||
dbuf_init2(&s->byte_code, opaque, lre_realloc);
|
dbuf_init2(&s->byte_code, opaque, lre_realloc);
|
||||||
dbuf_init2(&s->group_names, opaque, lre_realloc);
|
dbuf_init2(&s->group_names, opaque, lre_realloc);
|
||||||
|
|
||||||
dbuf_put_u16(&s->byte_code, re_flags); /* first element is the flags */
|
dbuf_putc(&s->byte_code, re_flags); /* first element is the flags */
|
||||||
dbuf_putc(&s->byte_code, 0); /* second element is the number of captures */
|
dbuf_putc(&s->byte_code, 0); /* second element is the number of captures */
|
||||||
dbuf_putc(&s->byte_code, 0); /* stack size */
|
dbuf_putc(&s->byte_code, 0); /* stack size */
|
||||||
dbuf_put_u32(&s->byte_code, 0); /* bytecode length */
|
dbuf_put_u32(&s->byte_code, 0); /* bytecode length */
|
||||||
|
@ -1821,7 +1763,7 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
|
||||||
error:
|
error:
|
||||||
dbuf_free(&s->byte_code);
|
dbuf_free(&s->byte_code);
|
||||||
dbuf_free(&s->group_names);
|
dbuf_free(&s->group_names);
|
||||||
js__pstrcpy(error_msg, error_msg_size, s->u.error_msg);
|
pstrcpy(error_msg, error_msg_size, s->u.error_msg);
|
||||||
*plen = 0;
|
*plen = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1840,7 +1782,7 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
stack_size = lre_compute_stack_size(s->byte_code.buf, s->byte_code.size);
|
stack_size = compute_stack_size(s->byte_code.buf, s->byte_code.size);
|
||||||
if (stack_size < 0) {
|
if (stack_size < 0) {
|
||||||
re_parse_error(s, "too many imbricated quantifiers");
|
re_parse_error(s, "too many imbricated quantifiers");
|
||||||
goto error;
|
goto error;
|
||||||
|
@ -1854,8 +1796,7 @@ uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
|
||||||
/* add the named groups if needed */
|
/* add the named groups if needed */
|
||||||
if (s->group_names.size > (s->capture_count - 1)) {
|
if (s->group_names.size > (s->capture_count - 1)) {
|
||||||
dbuf_put(&s->byte_code, s->group_names.buf, s->group_names.size);
|
dbuf_put(&s->byte_code, s->group_names.buf, s->group_names.size);
|
||||||
put_u16(s->byte_code.buf + RE_HEADER_FLAGS,
|
s->byte_code.buf[RE_HEADER_FLAGS] |= LRE_FLAG_NAMED_GROUPS;
|
||||||
LRE_FLAG_NAMED_GROUPS | lre_get_flags(s->byte_code.buf));
|
|
||||||
}
|
}
|
||||||
dbuf_free(&s->group_names);
|
dbuf_free(&s->group_names);
|
||||||
|
|
||||||
|
@ -1889,11 +1830,11 @@ static BOOL is_word_char(uint32_t c)
|
||||||
const uint16_t *_p = (const uint16_t *)cptr; \
|
const uint16_t *_p = (const uint16_t *)cptr; \
|
||||||
const uint16_t *_end = (const uint16_t *)cbuf_end; \
|
const uint16_t *_end = (const uint16_t *)cbuf_end; \
|
||||||
c = *_p++; \
|
c = *_p++; \
|
||||||
if (is_hi_surrogate(c)) \
|
if (is_hi_surrogate(c) && cbuf_type == 2) { \
|
||||||
if (cbuf_type == 2) \
|
if (_p < _end && is_lo_surrogate(*_p)) { \
|
||||||
if (_p < _end) \
|
c = from_surrogate(c, *_p++); \
|
||||||
if (is_lo_surrogate(*_p)) \
|
} \
|
||||||
c = from_surrogate(c, *_p++); \
|
} \
|
||||||
cptr = (const void *)_p; \
|
cptr = (const void *)_p; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -1906,11 +1847,11 @@ static BOOL is_word_char(uint32_t c)
|
||||||
const uint16_t *_p = (const uint16_t *)cptr; \
|
const uint16_t *_p = (const uint16_t *)cptr; \
|
||||||
const uint16_t *_end = (const uint16_t *)cbuf_end; \
|
const uint16_t *_end = (const uint16_t *)cbuf_end; \
|
||||||
c = *_p++; \
|
c = *_p++; \
|
||||||
if (is_hi_surrogate(c)) \
|
if (is_hi_surrogate(c) && cbuf_type == 2) { \
|
||||||
if (cbuf_type == 2) \
|
if (_p < _end && is_lo_surrogate(*_p)) { \
|
||||||
if (_p < _end) \
|
c = from_surrogate(c, *_p); \
|
||||||
if (is_lo_surrogate(*_p)) \
|
} \
|
||||||
c = from_surrogate(c, *_p); \
|
} \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -1922,11 +1863,11 @@ static BOOL is_word_char(uint32_t c)
|
||||||
const uint16_t *_p = (const uint16_t *)cptr - 1; \
|
const uint16_t *_p = (const uint16_t *)cptr - 1; \
|
||||||
const uint16_t *_start = (const uint16_t *)cbuf_start; \
|
const uint16_t *_start = (const uint16_t *)cbuf_start; \
|
||||||
c = *_p; \
|
c = *_p; \
|
||||||
if (is_lo_surrogate(c)) \
|
if (is_lo_surrogate(c) && cbuf_type == 2) { \
|
||||||
if (cbuf_type == 2) \
|
if (_p > _start && is_hi_surrogate(_p[-1])) { \
|
||||||
if (_p > _start) \
|
c = from_surrogate(*--_p, c); \
|
||||||
if (is_hi_surrogate(_p[-1])) \
|
} \
|
||||||
c = from_surrogate(*--_p, c); \
|
} \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
|
@ -1939,11 +1880,11 @@ static BOOL is_word_char(uint32_t c)
|
||||||
const uint16_t *_p = (const uint16_t *)cptr - 1; \
|
const uint16_t *_p = (const uint16_t *)cptr - 1; \
|
||||||
const uint16_t *_start = (const uint16_t *)cbuf_start; \
|
const uint16_t *_start = (const uint16_t *)cbuf_start; \
|
||||||
c = *_p; \
|
c = *_p; \
|
||||||
if (is_lo_surrogate(c)) \
|
if (is_lo_surrogate(c) && cbuf_type == 2) { \
|
||||||
if (cbuf_type == 2) \
|
if (_p > _start && is_hi_surrogate(_p[-1])) { \
|
||||||
if (_p > _start) \
|
c = from_surrogate(*--_p, c); \
|
||||||
if (is_hi_surrogate(_p[-1])) \
|
} \
|
||||||
c = from_surrogate(*--_p, c); \
|
} \
|
||||||
cptr = (const void *)_p; \
|
cptr = (const void *)_p; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -1955,11 +1896,11 @@ static BOOL is_word_char(uint32_t c)
|
||||||
} else { \
|
} else { \
|
||||||
const uint16_t *_p = (const uint16_t *)cptr - 1; \
|
const uint16_t *_p = (const uint16_t *)cptr - 1; \
|
||||||
const uint16_t *_start = (const uint16_t *)cbuf_start; \
|
const uint16_t *_start = (const uint16_t *)cbuf_start; \
|
||||||
if (is_lo_surrogate(*_p)) \
|
if (is_lo_surrogate(*_p) && cbuf_type == 2) { \
|
||||||
if (cbuf_type == 2) \
|
if (_p > _start && is_hi_surrogate(_p[-1])) { \
|
||||||
if (_p > _start) \
|
--_p; \
|
||||||
if (is_hi_surrogate(_p[-1])) \
|
} \
|
||||||
_p--; \
|
} \
|
||||||
cptr = (const void *)_p; \
|
cptr = (const void *)_p; \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
@ -1979,7 +1920,7 @@ typedef struct REExecState {
|
||||||
size_t count; /* only used for RE_EXEC_STATE_GREEDY_QUANT */
|
size_t count; /* only used for RE_EXEC_STATE_GREEDY_QUANT */
|
||||||
const uint8_t *cptr;
|
const uint8_t *cptr;
|
||||||
const uint8_t *pc;
|
const uint8_t *pc;
|
||||||
void *buf[];
|
void *buf[0];
|
||||||
} REExecState;
|
} REExecState;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -2129,13 +2070,9 @@ static intptr_t lre_exec_backtrack(REExecContext *s, uint8_t **capture,
|
||||||
val = get_u32(pc);
|
val = get_u32(pc);
|
||||||
pc += 4;
|
pc += 4;
|
||||||
goto test_char;
|
goto test_char;
|
||||||
case REOP_char16:
|
case REOP_char:
|
||||||
val = get_u16(pc);
|
val = get_u16(pc);
|
||||||
pc += 2;
|
pc += 2;
|
||||||
goto test_char;
|
|
||||||
case REOP_char8:
|
|
||||||
val = get_u8(pc);
|
|
||||||
pc += 1;
|
|
||||||
test_char:
|
test_char:
|
||||||
if (cptr >= cbuf_end)
|
if (cptr >= cbuf_end)
|
||||||
goto no_match;
|
goto no_match;
|
||||||
|
@ -2496,7 +2433,7 @@ int lre_get_capture_count(const uint8_t *bc_buf)
|
||||||
|
|
||||||
int lre_get_flags(const uint8_t *bc_buf)
|
int lre_get_flags(const uint8_t *bc_buf)
|
||||||
{
|
{
|
||||||
return get_u16(bc_buf + RE_HEADER_FLAGS);
|
return bc_buf[RE_HEADER_FLAGS];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return NULL if no group names. Otherwise, return a pointer to
|
/* Return NULL if no group names. Otherwise, return a pointer to
|
||||||
|
@ -2510,80 +2447,6 @@ const char *lre_get_groupnames(const uint8_t *bc_buf)
|
||||||
return (const char *)(bc_buf + RE_HEADER_LEN + re_bytecode_len);
|
return (const char *)(bc_buf + RE_HEADER_LEN + re_bytecode_len);
|
||||||
}
|
}
|
||||||
|
|
||||||
void lre_byte_swap(uint8_t *buf, size_t len, BOOL is_byte_swapped)
|
|
||||||
{
|
|
||||||
uint8_t *p, *pe;
|
|
||||||
uint32_t n, r, nw;
|
|
||||||
|
|
||||||
p = buf;
|
|
||||||
if (len < RE_HEADER_LEN)
|
|
||||||
abort();
|
|
||||||
|
|
||||||
// format is:
|
|
||||||
// <header>
|
|
||||||
// <bytecode>
|
|
||||||
// <capture group name 1>
|
|
||||||
// <capture group name 2>
|
|
||||||
// etc.
|
|
||||||
inplace_bswap16(&p[RE_HEADER_FLAGS]);
|
|
||||||
|
|
||||||
n = get_u32(&p[RE_HEADER_BYTECODE_LEN]);
|
|
||||||
inplace_bswap32(&p[RE_HEADER_BYTECODE_LEN]);
|
|
||||||
if (is_byte_swapped)
|
|
||||||
n = bswap32(n);
|
|
||||||
if (n > len - RE_HEADER_LEN)
|
|
||||||
abort();
|
|
||||||
|
|
||||||
p = &buf[RE_HEADER_LEN];
|
|
||||||
pe = &p[n];
|
|
||||||
|
|
||||||
while (p < pe) {
|
|
||||||
n = reopcode_info[*p].size;
|
|
||||||
switch (n) {
|
|
||||||
case 1:
|
|
||||||
case 2:
|
|
||||||
break;
|
|
||||||
case 3:
|
|
||||||
switch (*p) {
|
|
||||||
case REOP_save_reset: // has two 8 bit arguments
|
|
||||||
break;
|
|
||||||
case REOP_range32: // variable length
|
|
||||||
nw = get_u16(&p[1]); // number of pairs of uint32_t
|
|
||||||
if (is_byte_swapped)
|
|
||||||
n = bswap16(n);
|
|
||||||
for (r = 3 + 8 * nw; n < r; n += 4)
|
|
||||||
inplace_bswap32(&p[n]);
|
|
||||||
goto doswap16;
|
|
||||||
case REOP_range: // variable length
|
|
||||||
nw = get_u16(&p[1]); // number of pairs of uint16_t
|
|
||||||
if (is_byte_swapped)
|
|
||||||
n = bswap16(n);
|
|
||||||
for (r = 3 + 4 * nw; n < r; n += 2)
|
|
||||||
inplace_bswap16(&p[n]);
|
|
||||||
goto doswap16;
|
|
||||||
default:
|
|
||||||
doswap16:
|
|
||||||
inplace_bswap16(&p[1]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
inplace_bswap32(&p[1]);
|
|
||||||
break;
|
|
||||||
case 17:
|
|
||||||
assert(*p == REOP_simple_greedy_quant);
|
|
||||||
inplace_bswap32(&p[1]);
|
|
||||||
inplace_bswap32(&p[5]);
|
|
||||||
inplace_bswap32(&p[9]);
|
|
||||||
inplace_bswap32(&p[13]);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
abort();
|
|
||||||
}
|
|
||||||
p = &p[n];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef TEST
|
#ifdef TEST
|
||||||
|
|
||||||
BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size)
|
BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size)
|
||||||
|
@ -2607,7 +2470,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
if (argc < 4) {
|
if (argc < 4) {
|
||||||
printf("usage: %s regexp flags input\n", argv[0]);
|
printf("usage: %s regexp flags input\n", argv[0]);
|
||||||
exit(1);
|
return 1;
|
||||||
}
|
}
|
||||||
flags = atoi(argv[2]);
|
flags = atoi(argv[2]);
|
||||||
bc = lre_compile(&len, error_msg, sizeof(error_msg), argv[1],
|
bc = lre_compile(&len, error_msg, sizeof(error_msg), argv[1],
|
||||||
|
|
46
libregexp.h
46
libregexp.h
|
@ -25,14 +25,7 @@
|
||||||
#define LIBREGEXP_H
|
#define LIBREGEXP_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
#include "libunicode.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LRE_BOOL int /* for documentation purposes */
|
|
||||||
|
|
||||||
#define LRE_FLAG_GLOBAL (1 << 0)
|
#define LRE_FLAG_GLOBAL (1 << 0)
|
||||||
#define LRE_FLAG_IGNORECASE (1 << 1)
|
#define LRE_FLAG_IGNORECASE (1 << 1)
|
||||||
|
@ -42,7 +35,6 @@ extern "C" {
|
||||||
#define LRE_FLAG_STICKY (1 << 5)
|
#define LRE_FLAG_STICKY (1 << 5)
|
||||||
#define LRE_FLAG_INDICES (1 << 6) /* Unused by libregexp, just recorded. */
|
#define LRE_FLAG_INDICES (1 << 6) /* Unused by libregexp, just recorded. */
|
||||||
#define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */
|
#define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */
|
||||||
#define LRE_FLAG_UNICODE_SETS (1 << 8)
|
|
||||||
|
|
||||||
uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
|
uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
|
||||||
const char *buf, size_t buf_len, int re_flags,
|
const char *buf, size_t buf_len, int re_flags,
|
||||||
|
@ -55,41 +47,9 @@ int lre_exec(uint8_t **capture,
|
||||||
int cbuf_type, void *opaque);
|
int cbuf_type, void *opaque);
|
||||||
|
|
||||||
int lre_parse_escape(const uint8_t **pp, int allow_utf16);
|
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);
|
/* must be provided by the user, return non zero if overflow */
|
||||||
|
int lre_check_stack_overflow(void *opaque, size_t alloca_size);
|
||||||
/* must be provided by the user */
|
|
||||||
LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size);
|
|
||||||
void *lre_realloc(void *opaque, void *ptr, size_t size);
|
void *lre_realloc(void *opaque, void *ptr, size_t size);
|
||||||
|
|
||||||
/* JS identifier test */
|
|
||||||
extern uint32_t const lre_id_start_table_ascii[4];
|
|
||||||
extern uint32_t const lre_id_continue_table_ascii[4];
|
|
||||||
|
|
||||||
static inline int lre_js_is_ident_first(int c)
|
|
||||||
{
|
|
||||||
if ((uint32_t)c < 128) {
|
|
||||||
return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1;
|
|
||||||
} else {
|
|
||||||
return lre_is_id_start(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lre_js_is_ident_next(int c)
|
|
||||||
{
|
|
||||||
if ((uint32_t)c < 128) {
|
|
||||||
return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1;
|
|
||||||
} else {
|
|
||||||
/* ZWNJ and ZWJ are accepted in identifiers */
|
|
||||||
return lre_is_id_continue(c) || c == 0x200C || c == 0x200D;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef LRE_BOOL
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" { */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* LIBREGEXP_H */
|
#endif /* LIBREGEXP_H */
|
||||||
|
|
3479
libunicode-table.h
3479
libunicode-table.h
File diff suppressed because it is too large
Load diff
188
libunicode.c
188
libunicode.c
|
@ -31,7 +31,6 @@
|
||||||
#include "libunicode.h"
|
#include "libunicode.h"
|
||||||
#include "libunicode-table.h"
|
#include "libunicode-table.h"
|
||||||
|
|
||||||
// note: stored as 4 bit tag, not much room left
|
|
||||||
enum {
|
enum {
|
||||||
RUN_TYPE_U,
|
RUN_TYPE_U,
|
||||||
RUN_TYPE_L,
|
RUN_TYPE_L,
|
||||||
|
@ -314,6 +313,14 @@ static BOOL lre_is_in_table(uint32_t c, const uint8_t *table,
|
||||||
return FALSE; /* outside the table */
|
return FALSE; /* outside the table */
|
||||||
p = table + pos;
|
p = table + pos;
|
||||||
bit = 0;
|
bit = 0;
|
||||||
|
/* Compressed run length encoding:
|
||||||
|
00..3F: 2 packed lengths: 3-bit + 3-bit
|
||||||
|
40..5F: 5-bits plus extra byte for length
|
||||||
|
60..7F: 5-bits plus 2 extra bytes for length
|
||||||
|
80..FF: 7-bit length
|
||||||
|
lengths must be incremented to get character count
|
||||||
|
Ranges alternate between false and true return value.
|
||||||
|
*/
|
||||||
for(;;) {
|
for(;;) {
|
||||||
b = *p++;
|
b = *p++;
|
||||||
if (b < 64) {
|
if (b < 64) {
|
||||||
|
@ -530,6 +537,8 @@ int cr_invert(CharRange *cr)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_ALL_UNICODE
|
||||||
|
|
||||||
BOOL lre_is_id_start(uint32_t c)
|
BOOL lre_is_id_start(uint32_t c)
|
||||||
{
|
{
|
||||||
return lre_is_in_table(c, unicode_prop_ID_Start_table,
|
return lre_is_in_table(c, unicode_prop_ID_Start_table,
|
||||||
|
@ -545,13 +554,6 @@ BOOL lre_is_id_continue(uint32_t c)
|
||||||
sizeof(unicode_prop_ID_Continue1_index) / 3);
|
sizeof(unicode_prop_ID_Continue1_index) / 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
BOOL lre_is_white_space(uint32_t c)
|
|
||||||
{
|
|
||||||
return lre_is_in_table(c, unicode_prop_White_Space_table,
|
|
||||||
unicode_prop_White_Space_index,
|
|
||||||
sizeof(unicode_prop_White_Space_index) / 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UNICODE_DECOMP_LEN_MAX 18
|
#define UNICODE_DECOMP_LEN_MAX 18
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
|
@ -835,6 +837,13 @@ static int unicode_get_cc(uint32_t c)
|
||||||
if (pos < 0)
|
if (pos < 0)
|
||||||
return 0;
|
return 0;
|
||||||
p = unicode_cc_table + pos;
|
p = unicode_cc_table + pos;
|
||||||
|
/* Compressed run length encoding:
|
||||||
|
- 2 high order bits are combining class type
|
||||||
|
- 0:0, 1:230, 2:extra byte linear progression, 3:extra byte
|
||||||
|
- 00..2F: range length (add 1)
|
||||||
|
- 30..37: 3-bit range-length + 1 extra byte
|
||||||
|
- 38..3F: 3-bit range-length + 2 extra byte
|
||||||
|
*/
|
||||||
for(;;) {
|
for(;;) {
|
||||||
b = *p++;
|
b = *p++;
|
||||||
type = b >> 6;
|
type = b >> 6;
|
||||||
|
@ -899,6 +908,13 @@ static void sort_cc(int *buf, int len)
|
||||||
buf[k + 1] = ch1;
|
buf[k + 1] = ch1;
|
||||||
j++;
|
j++;
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
printf("cc:");
|
||||||
|
for(k = start; k < j; k++) {
|
||||||
|
printf(" %3d", unicode_get_cc(buf[k]));
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
#endif
|
||||||
i = j;
|
i = j;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1058,8 +1074,8 @@ int unicode_script(CharRange *cr,
|
||||||
int script_idx;
|
int script_idx;
|
||||||
const uint8_t *p, *p_end;
|
const uint8_t *p, *p_end;
|
||||||
uint32_t c, c1, b, n, v, v_len, i, type;
|
uint32_t c, c1, b, n, v, v_len, i, type;
|
||||||
CharRange cr1_s = { 0 }, *cr1 = NULL;
|
CharRange cr1_s, *cr1;
|
||||||
CharRange cr2_s = { 0 }, *cr2 = &cr2_s;
|
CharRange cr2_s, *cr2 = &cr2_s;
|
||||||
BOOL is_common;
|
BOOL is_common;
|
||||||
|
|
||||||
script_idx = unicode_find_name(unicode_script_name_table, script_name);
|
script_idx = unicode_find_name(unicode_script_name_table, script_name);
|
||||||
|
@ -1180,6 +1196,15 @@ static int unicode_general_category1(CharRange *cr, uint32_t gc_mask)
|
||||||
p = unicode_gc_table;
|
p = unicode_gc_table;
|
||||||
p_end = unicode_gc_table + countof(unicode_gc_table);
|
p_end = unicode_gc_table + countof(unicode_gc_table);
|
||||||
c = 0;
|
c = 0;
|
||||||
|
/* Compressed range encoding:
|
||||||
|
initial byte:
|
||||||
|
bits 0..4: category number (special case 31)
|
||||||
|
bits 5..7: range length (add 1)
|
||||||
|
special case bits 5..7 == 7: read an extra byte
|
||||||
|
- 00..7F: range length (add 7 + 1)
|
||||||
|
- 80..BF: 6-bits plus extra byte for range length (add 7 + 128)
|
||||||
|
- C0..FF: 6-bits plus 2 extra bytes for range length (add 7 + 128 + 16384)
|
||||||
|
*/
|
||||||
while (p < p_end) {
|
while (p < p_end) {
|
||||||
b = *p++;
|
b = *p++;
|
||||||
n = b >> 5;
|
n = b >> 5;
|
||||||
|
@ -1233,6 +1258,14 @@ static int unicode_prop1(CharRange *cr, int prop_idx)
|
||||||
p_end = p + unicode_prop_len_table[prop_idx];
|
p_end = p + unicode_prop_len_table[prop_idx];
|
||||||
c = 0;
|
c = 0;
|
||||||
bit = 0;
|
bit = 0;
|
||||||
|
/* Compressed range encoding:
|
||||||
|
00..3F: 2 packed lengths: 3-bit + 3-bit
|
||||||
|
40..5F: 5-bits plus extra byte for length
|
||||||
|
60..7F: 5-bits plus 2 extra bytes for length
|
||||||
|
80..FF: 7-bit length
|
||||||
|
lengths must be incremented to get character count
|
||||||
|
Ranges alternate between false and true return value.
|
||||||
|
*/
|
||||||
while (p < p_end) {
|
while (p < p_end) {
|
||||||
c0 = c;
|
c0 = c;
|
||||||
b = *p++;
|
b = *p++;
|
||||||
|
@ -1542,13 +1575,11 @@ static int unicode_prop_ops(CharRange *cr, ...)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
va_end(ap);
|
|
||||||
assert(stack_len == 1);
|
assert(stack_len == 1);
|
||||||
ret = cr_copy(cr, &stack[0]);
|
ret = cr_copy(cr, &stack[0]);
|
||||||
cr_free(&stack[0]);
|
cr_free(&stack[0]);
|
||||||
return ret;
|
return ret;
|
||||||
fail:
|
fail:
|
||||||
va_end(ap);
|
|
||||||
for(i = 0; i < stack_len; i++)
|
for(i = 0; i < stack_len; i++)
|
||||||
cr_free(&stack[i]);
|
cr_free(&stack[i]);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -1728,6 +1759,42 @@ int unicode_prop(CharRange *cr, const char *prop_name)
|
||||||
POP_XOR,
|
POP_XOR,
|
||||||
POP_END);
|
POP_END);
|
||||||
break;
|
break;
|
||||||
|
#if 0
|
||||||
|
case UNICODE_PROP_ID_Start:
|
||||||
|
ret = unicode_prop_ops(cr,
|
||||||
|
POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl),
|
||||||
|
POP_PROP, UNICODE_PROP_Other_ID_Start,
|
||||||
|
POP_UNION,
|
||||||
|
POP_PROP, UNICODE_PROP_Pattern_Syntax,
|
||||||
|
POP_PROP, UNICODE_PROP_Pattern_White_Space,
|
||||||
|
POP_UNION,
|
||||||
|
POP_INVERT,
|
||||||
|
POP_INTER,
|
||||||
|
POP_END);
|
||||||
|
break;
|
||||||
|
case UNICODE_PROP_ID_Continue:
|
||||||
|
ret = unicode_prop_ops(cr,
|
||||||
|
POP_GC, M(Lu) | M(Ll) | M(Lt) | M(Lm) | M(Lo) | M(Nl) |
|
||||||
|
M(Mn) | M(Mc) | M(Nd) | M(Pc),
|
||||||
|
POP_PROP, UNICODE_PROP_Other_ID_Start,
|
||||||
|
POP_UNION,
|
||||||
|
POP_PROP, UNICODE_PROP_Other_ID_Continue,
|
||||||
|
POP_UNION,
|
||||||
|
POP_PROP, UNICODE_PROP_Pattern_Syntax,
|
||||||
|
POP_PROP, UNICODE_PROP_Pattern_White_Space,
|
||||||
|
POP_UNION,
|
||||||
|
POP_INVERT,
|
||||||
|
POP_INTER,
|
||||||
|
POP_END);
|
||||||
|
break;
|
||||||
|
case UNICODE_PROP_Case_Ignorable:
|
||||||
|
ret = unicode_prop_ops(cr,
|
||||||
|
POP_GC, M(Mn) | M(Cf) | M(Lm) | M(Sk),
|
||||||
|
POP_PROP, UNICODE_PROP_Case_Ignorable1,
|
||||||
|
POP_XOR,
|
||||||
|
POP_END);
|
||||||
|
break;
|
||||||
|
#else
|
||||||
/* we use the existing tables */
|
/* we use the existing tables */
|
||||||
case UNICODE_PROP_ID_Continue:
|
case UNICODE_PROP_ID_Continue:
|
||||||
ret = unicode_prop_ops(cr,
|
ret = unicode_prop_ops(cr,
|
||||||
|
@ -1736,6 +1803,7 @@ int unicode_prop(CharRange *cr, const char *prop_name)
|
||||||
POP_XOR,
|
POP_XOR,
|
||||||
POP_END);
|
POP_END);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
default:
|
default:
|
||||||
if (prop_idx >= countof(unicode_prop_table))
|
if (prop_idx >= countof(unicode_prop_table))
|
||||||
return -2;
|
return -2;
|
||||||
|
@ -1744,3 +1812,99 @@ int unicode_prop(CharRange *cr, const char *prop_name)
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif /* CONFIG_ALL_UNICODE */
|
||||||
|
|
||||||
|
/*---- lre codepoint categorizing functions ----*/
|
||||||
|
|
||||||
|
#define S UNICODE_C_SPACE
|
||||||
|
#define D UNICODE_C_DIGIT
|
||||||
|
#define X UNICODE_C_XDIGIT
|
||||||
|
#define U UNICODE_C_UPPER
|
||||||
|
#define L UNICODE_C_LOWER
|
||||||
|
#define _ UNICODE_C_UNDER
|
||||||
|
#define d UNICODE_C_DOLLAR
|
||||||
|
|
||||||
|
uint8_t const lre_ctype_bits[256] = {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, S, S, S, S, S, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
|
S, 0, 0, 0, d, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
X|D, X|D, X|D, X|D, X|D, X|D, X|D, X|D,
|
||||||
|
X|D, X|D, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
|
0, X|U, X|U, X|U, X|U, X|U, X|U, U,
|
||||||
|
U, U, U, U, U, U, U, U,
|
||||||
|
U, U, U, U, U, U, U, U,
|
||||||
|
U, U, U, 0, 0, 0, 0, _,
|
||||||
|
|
||||||
|
0, X|L, X|L, X|L, X|L, X|L, X|L, L,
|
||||||
|
L, L, L, L, L, L, L, L,
|
||||||
|
L, L, L, L, L, L, L, L,
|
||||||
|
L, L, L, 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, 0, 0, 0, 0, 0, 0,
|
||||||
|
|
||||||
|
S, 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,
|
||||||
|
|
||||||
|
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, 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, 0, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
#undef S
|
||||||
|
#undef D
|
||||||
|
#undef X
|
||||||
|
#undef U
|
||||||
|
#undef L
|
||||||
|
#undef _
|
||||||
|
#undef d
|
||||||
|
|
||||||
|
/* code point ranges for Zs,Zl or Zp property */
|
||||||
|
static const uint16_t char_range_s[] = {
|
||||||
|
10,
|
||||||
|
0x0009, 0x000D + 1,
|
||||||
|
0x0020, 0x0020 + 1,
|
||||||
|
0x00A0, 0x00A0 + 1,
|
||||||
|
0x1680, 0x1680 + 1,
|
||||||
|
0x2000, 0x200A + 1,
|
||||||
|
/* 2028;LINE SEPARATOR;Zl;0;WS;;;;;N;;;;; */
|
||||||
|
/* 2029;PARAGRAPH SEPARATOR;Zp;0;B;;;;;N;;;;; */
|
||||||
|
0x2028, 0x2029 + 1,
|
||||||
|
0x202F, 0x202F + 1,
|
||||||
|
0x205F, 0x205F + 1,
|
||||||
|
0x3000, 0x3000 + 1,
|
||||||
|
/* FEFF;ZERO WIDTH NO-BREAK SPACE;Cf;0;BN;;;;;N;BYTE ORDER MARK;;;; */
|
||||||
|
0xFEFF, 0xFEFF + 1,
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOL lre_is_space_non_ascii(uint32_t c)
|
||||||
|
{
|
||||||
|
size_t i, n;
|
||||||
|
|
||||||
|
n = countof(char_range_s);
|
||||||
|
for(i = 5; i < n; i += 2) {
|
||||||
|
uint32_t low = char_range_s[i];
|
||||||
|
uint32_t high = char_range_s[i + 1];
|
||||||
|
if (c < low)
|
||||||
|
return FALSE;
|
||||||
|
if (c < high)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
109
libunicode.h
109
libunicode.h
|
@ -24,29 +24,13 @@
|
||||||
#ifndef LIBUNICODE_H
|
#ifndef LIBUNICODE_H
|
||||||
#define LIBUNICODE_H
|
#define LIBUNICODE_H
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stdint.h>
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/* define it to include all the unicode tables (40KB larger) */
|
||||||
extern "C" {
|
#define CONFIG_ALL_UNICODE
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LRE_BOOL int /* for documentation purposes */
|
|
||||||
|
|
||||||
#define LRE_CC_RES_LEN_MAX 3
|
#define LRE_CC_RES_LEN_MAX 3
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
UNICODE_NFC,
|
|
||||||
UNICODE_NFD,
|
|
||||||
UNICODE_NFKC,
|
|
||||||
UNICODE_NFKD,
|
|
||||||
} UnicodeNormalizationEnum;
|
|
||||||
|
|
||||||
int lre_case_conv(uint32_t *res, uint32_t c, int conv_type);
|
|
||||||
int lre_canonicalize(uint32_t c, BOOL is_unicode);
|
|
||||||
LRE_BOOL lre_is_cased(uint32_t c);
|
|
||||||
LRE_BOOL lre_is_case_ignorable(uint32_t c);
|
|
||||||
|
|
||||||
/* char ranges */
|
/* char ranges */
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -103,11 +87,15 @@ int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len,
|
||||||
const uint32_t *b_pt, int b_len, int op);
|
const uint32_t *b_pt, int b_len, int op);
|
||||||
|
|
||||||
int cr_invert(CharRange *cr);
|
int cr_invert(CharRange *cr);
|
||||||
int cr_regexp_canonicalize(CharRange *cr, BOOL is_unicode);
|
|
||||||
|
|
||||||
LRE_BOOL lre_is_id_start(uint32_t c);
|
int cr_regexp_canonicalize(CharRange *cr, int is_unicode);
|
||||||
LRE_BOOL lre_is_id_continue(uint32_t c);
|
|
||||||
LRE_BOOL lre_is_white_space(uint32_t c);
|
typedef enum {
|
||||||
|
UNICODE_NFC,
|
||||||
|
UNICODE_NFD,
|
||||||
|
UNICODE_NFKC,
|
||||||
|
UNICODE_NFKD,
|
||||||
|
} UnicodeNormalizationEnum;
|
||||||
|
|
||||||
int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
|
int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
|
||||||
UnicodeNormalizationEnum n_type,
|
UnicodeNormalizationEnum n_type,
|
||||||
|
@ -115,15 +103,80 @@ int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
|
||||||
|
|
||||||
/* Unicode character range functions */
|
/* Unicode character range functions */
|
||||||
|
|
||||||
int unicode_script(CharRange *cr,
|
int unicode_script(CharRange *cr, const char *script_name, int is_ext);
|
||||||
const char *script_name, LRE_BOOL is_ext);
|
|
||||||
int unicode_general_category(CharRange *cr, const char *gc_name);
|
int unicode_general_category(CharRange *cr, const char *gc_name);
|
||||||
int unicode_prop(CharRange *cr, const char *prop_name);
|
int unicode_prop(CharRange *cr, const char *prop_name);
|
||||||
|
|
||||||
#undef LRE_BOOL
|
int lre_case_conv(uint32_t *res, uint32_t c, int conv_type);
|
||||||
|
int lre_canonicalize(uint32_t c, int is_unicode);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
/* Code point type categories */
|
||||||
} /* extern "C" { */
|
enum {
|
||||||
|
UNICODE_C_SPACE = (1 << 0),
|
||||||
|
UNICODE_C_DIGIT = (1 << 1),
|
||||||
|
UNICODE_C_UPPER = (1 << 2),
|
||||||
|
UNICODE_C_LOWER = (1 << 3),
|
||||||
|
UNICODE_C_UNDER = (1 << 4),
|
||||||
|
UNICODE_C_DOLLAR = (1 << 5),
|
||||||
|
UNICODE_C_XDIGIT = (1 << 6),
|
||||||
|
};
|
||||||
|
extern uint8_t const lre_ctype_bits[256];
|
||||||
|
|
||||||
|
/* zero or non-zero return value */
|
||||||
|
int lre_is_cased(uint32_t c);
|
||||||
|
int lre_is_case_ignorable(uint32_t c);
|
||||||
|
int lre_is_id_start(uint32_t c);
|
||||||
|
int lre_is_id_continue(uint32_t c);
|
||||||
|
|
||||||
|
static inline int lre_is_space_byte(uint8_t c) {
|
||||||
|
return lre_ctype_bits[c] & UNICODE_C_SPACE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int lre_is_id_start_byte(uint8_t c) {
|
||||||
|
return lre_ctype_bits[c] & (UNICODE_C_UPPER | UNICODE_C_LOWER |
|
||||||
|
UNICODE_C_UNDER | UNICODE_C_DOLLAR);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int lre_is_id_continue_byte(uint8_t c) {
|
||||||
|
return lre_ctype_bits[c] & (UNICODE_C_UPPER | UNICODE_C_LOWER |
|
||||||
|
UNICODE_C_UNDER | UNICODE_C_DOLLAR |
|
||||||
|
UNICODE_C_DIGIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
int lre_is_space_non_ascii(uint32_t c);
|
||||||
|
|
||||||
|
static inline int lre_is_space(uint32_t c) {
|
||||||
|
if (c < 256)
|
||||||
|
return lre_is_space_byte(c);
|
||||||
|
else
|
||||||
|
return lre_is_space_non_ascii(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int lre_js_is_ident_first(uint32_t c) {
|
||||||
|
if (c < 128) {
|
||||||
|
return lre_is_id_start_byte(c);
|
||||||
|
} else {
|
||||||
|
#ifdef CONFIG_ALL_UNICODE
|
||||||
|
return lre_is_id_start(c);
|
||||||
|
#else
|
||||||
|
return !lre_is_space_non_ascii(c);
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int lre_js_is_ident_next(uint32_t c) {
|
||||||
|
if (c < 128) {
|
||||||
|
return lre_is_id_continue_byte(c);
|
||||||
|
} else {
|
||||||
|
/* ZWNJ and ZWJ are accepted in identifiers */
|
||||||
|
if (c >= 0x200C && c <= 0x200D)
|
||||||
|
return TRUE;
|
||||||
|
#ifdef CONFIG_ALL_UNICODE
|
||||||
|
return lre_is_id_continue(c);
|
||||||
|
#else
|
||||||
|
return !lre_is_space_non_ascii(c);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* LIBUNICODE_H */
|
#endif /* LIBUNICODE_H */
|
||||||
|
|
8
list.h
8
list.h
|
@ -28,10 +28,6 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct list_head {
|
struct list_head {
|
||||||
struct list_head *prev;
|
struct list_head *prev;
|
||||||
struct list_head *next;
|
struct list_head *next;
|
||||||
|
@ -100,8 +96,4 @@ static inline int list_empty(struct list_head *el)
|
||||||
for(el = (head)->prev, el1 = el->prev; el != (head); \
|
for(el = (head)->prev, el1 = el->prev; el != (head); \
|
||||||
el = el1, el1 = el->prev)
|
el = el1, el1 = el->prev)
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" { */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* LIST_H */
|
#endif /* LIST_H */
|
||||||
|
|
573
qjs.c
573
qjs.c
|
@ -28,81 +28,28 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#if !defined(_MSC_VER)
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#include <malloc/malloc.h>
|
||||||
|
#elif defined(__linux__)
|
||||||
|
#include <malloc.h>
|
||||||
|
#elif defined(__FreeBSD__)
|
||||||
|
#include <malloc_np.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "cutils.h"
|
#include "cutils.h"
|
||||||
#include "quickjs.h"
|
|
||||||
#include "quickjs-libc.h"
|
#include "quickjs-libc.h"
|
||||||
|
|
||||||
#ifdef QJS_USE_MIMALLOC
|
|
||||||
#include <mimalloc.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern const uint8_t qjsc_repl[];
|
extern const uint8_t qjsc_repl[];
|
||||||
extern const uint32_t qjsc_repl_size;
|
extern const uint32_t qjsc_repl_size;
|
||||||
extern const uint8_t qjsc_standalone[];
|
#ifdef CONFIG_BIGNUM
|
||||||
extern const uint32_t qjsc_standalone_size;
|
extern const uint8_t qjsc_qjscalc[];
|
||||||
|
extern const uint32_t qjsc_qjscalc_size;
|
||||||
// Must match standalone.js
|
static int bignum_ext;
|
||||||
#define TRAILER_SIZE 12
|
#endif
|
||||||
static const char trailer_magic[] = "quickjs2";
|
|
||||||
static const int trailer_magic_size = sizeof(trailer_magic) - 1;
|
|
||||||
static const int trailer_size = TRAILER_SIZE;
|
|
||||||
|
|
||||||
static int qjs__argc;
|
|
||||||
static char **qjs__argv;
|
|
||||||
|
|
||||||
|
|
||||||
static BOOL is_standalone(const char *exe)
|
|
||||||
{
|
|
||||||
FILE *exe_f = fopen(exe, "rb");
|
|
||||||
if (!exe_f)
|
|
||||||
return FALSE;
|
|
||||||
if (fseek(exe_f, -trailer_size, SEEK_END) < 0)
|
|
||||||
goto fail;
|
|
||||||
uint8_t buf[TRAILER_SIZE];
|
|
||||||
if (fread(buf, 1, trailer_size, exe_f) != trailer_size)
|
|
||||||
goto fail;
|
|
||||||
fclose(exe_f);
|
|
||||||
return !memcmp(buf, trailer_magic, trailer_magic_size);
|
|
||||||
fail:
|
|
||||||
fclose(exe_f);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue load_standalone_module(JSContext *ctx)
|
|
||||||
{
|
|
||||||
JSModuleDef *m;
|
|
||||||
JSValue obj, val;
|
|
||||||
obj = JS_ReadObject(ctx, qjsc_standalone, qjsc_standalone_size, JS_READ_OBJ_BYTECODE);
|
|
||||||
if (JS_IsException(obj))
|
|
||||||
goto exception;
|
|
||||||
assert(JS_VALUE_GET_TAG(obj) == JS_TAG_MODULE);
|
|
||||||
if (JS_ResolveModule(ctx, obj) < 0) {
|
|
||||||
JS_FreeValue(ctx, obj);
|
|
||||||
goto exception;
|
|
||||||
}
|
|
||||||
js_module_set_import_meta(ctx, obj, FALSE, TRUE);
|
|
||||||
val = JS_EvalFunction(ctx, JS_DupValue(ctx, obj));
|
|
||||||
val = js_std_await(ctx, val);
|
|
||||||
|
|
||||||
if (JS_IsException(val)) {
|
|
||||||
JS_FreeValue(ctx, obj);
|
|
||||||
exception:
|
|
||||||
js_std_dump_error(ctx);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
JS_FreeValue(ctx, val);
|
|
||||||
|
|
||||||
m = JS_VALUE_GET_PTR(obj);
|
|
||||||
JS_FreeValue(ctx, obj);
|
|
||||||
return JS_GetModuleNamespace(ctx, m);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
|
static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
|
||||||
const char *filename, int eval_flags)
|
const char *filename, int eval_flags)
|
||||||
|
@ -146,71 +93,18 @@ static int eval_file(JSContext *ctx, const char *filename, int module)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (module < 0) {
|
if (module < 0) {
|
||||||
module = (js__has_suffix(filename, ".mjs") ||
|
module = (has_suffix(filename, ".mjs") ||
|
||||||
JS_DetectModule((const char *)buf, buf_len));
|
JS_DetectModule((const char *)buf, buf_len));
|
||||||
}
|
}
|
||||||
if (module)
|
if (module)
|
||||||
eval_flags = JS_EVAL_TYPE_MODULE;
|
eval_flags = JS_EVAL_TYPE_MODULE;
|
||||||
else
|
else
|
||||||
eval_flags = JS_EVAL_TYPE_GLOBAL;
|
eval_flags = JS_EVAL_TYPE_GLOBAL;
|
||||||
|
|
||||||
ret = eval_buf(ctx, buf, buf_len, filename, eval_flags);
|
ret = eval_buf(ctx, buf, buf_len, filename, eval_flags);
|
||||||
js_free(ctx, buf);
|
js_free(ctx, buf);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int64_t parse_limit(const char *arg) {
|
|
||||||
char *p;
|
|
||||||
unsigned long unit = 1024; /* default to traditional KB */
|
|
||||||
double d = strtod(arg, &p);
|
|
||||||
|
|
||||||
if (p == arg) {
|
|
||||||
fprintf(stderr, "Invalid limit: %s\n", arg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*p) {
|
|
||||||
switch (*p++) {
|
|
||||||
case 'b': case 'B': unit = 1UL << 0; break;
|
|
||||||
case 'k': case 'K': unit = 1UL << 10; break; /* IEC kibibytes */
|
|
||||||
case 'm': case 'M': unit = 1UL << 20; break; /* IEC mebibytes */
|
|
||||||
case 'g': case 'G': unit = 1UL << 30; break; /* IEC gigibytes */
|
|
||||||
default:
|
|
||||||
fprintf(stderr, "Invalid limit: %s, unrecognized suffix, only k,m,g are allowed\n", arg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (*p) {
|
|
||||||
fprintf(stderr, "Invalid limit: %s, only one suffix allowed\n", arg);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (int64_t)(d * unit);
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_gc(JSContext *ctx, JSValue this_val,
|
|
||||||
int argc, JSValue *argv)
|
|
||||||
{
|
|
||||||
JS_RunGC(JS_GetRuntime(ctx));
|
|
||||||
return JS_UNDEFINED;
|
|
||||||
}
|
|
||||||
|
|
||||||
static JSValue js_navigator_get_userAgent(JSContext *ctx, JSValue this_val)
|
|
||||||
{
|
|
||||||
char version[32];
|
|
||||||
snprintf(version, sizeof(version), "quickjs-ng/%s", JS_GetVersion());
|
|
||||||
return JS_NewString(ctx, version);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry navigator_proto_funcs[] = {
|
|
||||||
JS_CGETSET_DEF2("userAgent", js_navigator_get_userAgent, NULL, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE),
|
|
||||||
JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Navigator", JS_PROP_CONFIGURABLE),
|
|
||||||
};
|
|
||||||
|
|
||||||
static const JSCFunctionListEntry global_obj[] = {
|
|
||||||
JS_CFUNC_DEF("gc", 0, js_gc),
|
|
||||||
};
|
|
||||||
|
|
||||||
/* also used to initialize the worker context */
|
/* also used to initialize the worker context */
|
||||||
static JSContext *JS_NewCustomContext(JSRuntime *rt)
|
static JSContext *JS_NewCustomContext(JSRuntime *rt)
|
||||||
{
|
{
|
||||||
|
@ -218,30 +112,26 @@ static JSContext *JS_NewCustomContext(JSRuntime *rt)
|
||||||
ctx = JS_NewContext(rt);
|
ctx = JS_NewContext(rt);
|
||||||
if (!ctx)
|
if (!ctx)
|
||||||
return NULL;
|
return NULL;
|
||||||
/* system modules */
|
#ifdef CONFIG_BIGNUM
|
||||||
js_init_module_std(ctx, "qjs:std");
|
if (bignum_ext) {
|
||||||
js_init_module_os(ctx, "qjs:os");
|
JS_AddIntrinsicBigFloat(ctx);
|
||||||
js_init_module_bjson(ctx, "qjs:bjson");
|
JS_AddIntrinsicBigDecimal(ctx);
|
||||||
|
JS_AddIntrinsicOperators(ctx);
|
||||||
JSValue global = JS_GetGlobalObject(ctx);
|
JS_EnableBignumExt(ctx, TRUE);
|
||||||
JS_SetPropertyFunctionList(ctx, global, global_obj, countof(global_obj));
|
|
||||||
JSValue args = JS_NewArray(ctx);
|
|
||||||
int i;
|
|
||||||
for(i = 0; i < qjs__argc; i++) {
|
|
||||||
JS_SetPropertyUint32(ctx, args, i, JS_NewString(ctx, qjs__argv[i]));
|
|
||||||
}
|
}
|
||||||
JS_SetPropertyStr(ctx, global, "execArgv", args);
|
#endif
|
||||||
JS_SetPropertyStr(ctx, global, "argv0", JS_NewString(ctx, qjs__argv[0]));
|
/* system modules */
|
||||||
JSValue navigator_proto = JS_NewObject(ctx);
|
js_init_module_std(ctx, "std");
|
||||||
JS_SetPropertyFunctionList(ctx, navigator_proto, navigator_proto_funcs, countof(navigator_proto_funcs));
|
js_init_module_os(ctx, "os");
|
||||||
JSValue navigator = JS_NewObjectProto(ctx, navigator_proto);
|
|
||||||
JS_DefinePropertyValueStr(ctx, global, "navigator", navigator, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE);
|
|
||||||
JS_FreeValue(ctx, global);
|
|
||||||
JS_FreeValue(ctx, navigator_proto);
|
|
||||||
|
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
#define MALLOC_OVERHEAD 0
|
||||||
|
#else
|
||||||
|
#define MALLOC_OVERHEAD 8
|
||||||
|
#endif
|
||||||
|
|
||||||
struct trace_malloc_data {
|
struct trace_malloc_data {
|
||||||
uint8_t *base;
|
uint8_t *base;
|
||||||
};
|
};
|
||||||
|
@ -252,14 +142,31 @@ static inline unsigned long long js_trace_malloc_ptr_offset(uint8_t *ptr,
|
||||||
return ptr - dp->base;
|
return ptr - dp->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* default memory allocation functions with memory limitation */
|
||||||
|
static size_t js_trace_malloc_usable_size(const void *ptr)
|
||||||
|
{
|
||||||
|
#if defined(__APPLE__)
|
||||||
|
return malloc_size(ptr);
|
||||||
|
#elif defined(_WIN32)
|
||||||
|
return _msize((void *)ptr);
|
||||||
|
#elif defined(EMSCRIPTEN)
|
||||||
|
return 0;
|
||||||
|
#elif defined(__linux__)
|
||||||
|
return malloc_usable_size((void *)ptr);
|
||||||
|
#else
|
||||||
|
/* change this to `return 0;` if compilation fails */
|
||||||
|
return malloc_usable_size((void *)ptr);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
#if defined(_WIN32) && !defined(__clang__)
|
#ifdef _WIN32
|
||||||
/* mingw printf is used */
|
/* mingw printf is used */
|
||||||
__attribute__((format(gnu_printf, 2, 3)))
|
__attribute__((format(gnu_printf, 2, 3)))
|
||||||
#else
|
#else
|
||||||
__attribute__((format(printf, 2, 3)))
|
__attribute__((format(printf, 2, 3)))
|
||||||
#endif
|
#endif
|
||||||
js_trace_malloc_printf(void *opaque, const char *fmt, ...)
|
js_trace_malloc_printf(JSMallocState *s, const char *fmt, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
int c;
|
int c;
|
||||||
|
@ -274,8 +181,8 @@ __attribute__((format(printf, 2, 3)))
|
||||||
printf("NULL");
|
printf("NULL");
|
||||||
} else {
|
} else {
|
||||||
printf("H%+06lld.%zd",
|
printf("H%+06lld.%zd",
|
||||||
js_trace_malloc_ptr_offset(ptr, opaque),
|
js_trace_malloc_ptr_offset(ptr, s->opaque),
|
||||||
js__malloc_usable_size(ptr));
|
js_trace_malloc_usable_size(ptr));
|
||||||
}
|
}
|
||||||
fmt++;
|
fmt++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -297,83 +204,77 @@ static void js_trace_malloc_init(struct trace_malloc_data *s)
|
||||||
free(s->base = malloc(8));
|
free(s->base = malloc(8));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *js_trace_calloc(void *opaque, size_t count, size_t size)
|
static void *js_trace_malloc(JSMallocState *s, size_t size)
|
||||||
{
|
{
|
||||||
void *ptr;
|
void *ptr;
|
||||||
ptr = calloc(count, size);
|
|
||||||
js_trace_malloc_printf(opaque, "C %zd %zd -> %p\n", count, size, ptr);
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *js_trace_malloc(void *opaque, size_t size)
|
/* Do not allocate zero bytes: behavior is platform dependent */
|
||||||
{
|
assert(size != 0);
|
||||||
void *ptr;
|
|
||||||
|
if (unlikely(s->malloc_size + size > s->malloc_limit))
|
||||||
|
return NULL;
|
||||||
ptr = malloc(size);
|
ptr = malloc(size);
|
||||||
js_trace_malloc_printf(opaque, "A %zd -> %p\n", size, ptr);
|
js_trace_malloc_printf(s, "A %zd -> %p\n", size, ptr);
|
||||||
|
if (ptr) {
|
||||||
|
s->malloc_count++;
|
||||||
|
s->malloc_size += js_trace_malloc_usable_size(ptr) + MALLOC_OVERHEAD;
|
||||||
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void js_trace_free(void *opaque, void *ptr)
|
static void js_trace_free(JSMallocState *s, void *ptr)
|
||||||
{
|
{
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return;
|
return;
|
||||||
js_trace_malloc_printf(opaque, "F %p\n", ptr);
|
|
||||||
|
js_trace_malloc_printf(s, "F %p\n", ptr);
|
||||||
|
s->malloc_count--;
|
||||||
|
s->malloc_size -= js_trace_malloc_usable_size(ptr) + MALLOC_OVERHEAD;
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *js_trace_realloc(void *opaque, void *ptr, size_t size)
|
static void *js_trace_realloc(JSMallocState *s, void *ptr, size_t size)
|
||||||
{
|
{
|
||||||
js_trace_malloc_printf(opaque, "R %zd %p", size, ptr);
|
size_t old_size;
|
||||||
|
|
||||||
|
if (!ptr) {
|
||||||
|
if (size == 0)
|
||||||
|
return NULL;
|
||||||
|
return js_trace_malloc(s, size);
|
||||||
|
}
|
||||||
|
old_size = js_trace_malloc_usable_size(ptr);
|
||||||
|
if (size == 0) {
|
||||||
|
js_trace_malloc_printf(s, "R %zd %p\n", size, ptr);
|
||||||
|
s->malloc_count--;
|
||||||
|
s->malloc_size -= old_size + MALLOC_OVERHEAD;
|
||||||
|
free(ptr);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (s->malloc_size + size - old_size > s->malloc_limit)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
js_trace_malloc_printf(s, "R %zd %p", size, ptr);
|
||||||
|
|
||||||
ptr = realloc(ptr, size);
|
ptr = realloc(ptr, size);
|
||||||
js_trace_malloc_printf(opaque, " -> %p\n", ptr);
|
js_trace_malloc_printf(s, " -> %p\n", ptr);
|
||||||
|
if (ptr) {
|
||||||
|
s->malloc_size += js_trace_malloc_usable_size(ptr) - old_size;
|
||||||
|
}
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const JSMallocFunctions trace_mf = {
|
static const JSMallocFunctions trace_mf = {
|
||||||
js_trace_calloc,
|
|
||||||
js_trace_malloc,
|
js_trace_malloc,
|
||||||
js_trace_free,
|
js_trace_free,
|
||||||
js_trace_realloc,
|
js_trace_realloc,
|
||||||
js__malloc_usable_size
|
js_trace_malloc_usable_size,
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef QJS_USE_MIMALLOC
|
|
||||||
static void *js_mi_calloc(void *opaque, size_t count, size_t size)
|
|
||||||
{
|
|
||||||
return mi_calloc(count, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *js_mi_malloc(void *opaque, size_t size)
|
|
||||||
{
|
|
||||||
return mi_malloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void js_mi_free(void *opaque, void *ptr)
|
|
||||||
{
|
|
||||||
if (!ptr)
|
|
||||||
return;
|
|
||||||
mi_free(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void *js_mi_realloc(void *opaque, void *ptr, size_t size)
|
|
||||||
{
|
|
||||||
return mi_realloc(ptr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const JSMallocFunctions mi_mf = {
|
|
||||||
js_mi_calloc,
|
|
||||||
js_mi_malloc,
|
|
||||||
js_mi_free,
|
|
||||||
js_mi_realloc,
|
|
||||||
mi_malloc_usable_size
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define PROG_NAME "qjs"
|
#define PROG_NAME "qjs"
|
||||||
|
|
||||||
void help(void)
|
void help(void)
|
||||||
{
|
{
|
||||||
printf("QuickJS-ng DoneJS Edition version %s\n"
|
printf("QuickJS version " CONFIG_VERSION "\n"
|
||||||
"usage: " PROG_NAME " [options] [file [args]]\n"
|
"usage: " PROG_NAME " [options] [file [args]]\n"
|
||||||
"-h --help list options\n"
|
"-h --help list options\n"
|
||||||
"-e --eval EXPR evaluate EXPR\n"
|
"-e --eval EXPR evaluate EXPR\n"
|
||||||
|
@ -381,16 +282,17 @@ void help(void)
|
||||||
"-m --module load as ES6 module (default=autodetect)\n"
|
"-m --module load as ES6 module (default=autodetect)\n"
|
||||||
" --script load as ES6 script (default=autodetect)\n"
|
" --script load as ES6 script (default=autodetect)\n"
|
||||||
"-I --include file include an additional file\n"
|
"-I --include file include an additional file\n"
|
||||||
" --std make 'std', 'os' and 'bjson' available to script\n"
|
" --std make 'std' and 'os' available to the loaded script\n"
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
|
" --bignum enable the bignum extensions (BigFloat, BigDecimal)\n"
|
||||||
|
" --qjscalc load the QJSCalc runtime (default if invoked as qjscalc)\n"
|
||||||
|
#endif
|
||||||
"-T --trace trace memory allocation\n"
|
"-T --trace trace memory allocation\n"
|
||||||
"-d --dump dump the memory usage stats\n"
|
"-d --dump dump the memory usage stats\n"
|
||||||
"-D --dump-flags flags for dumping debug data (see DUMP_* defines)\n"
|
" --memory-limit n limit the memory usage to 'n' bytes\n"
|
||||||
"-c --compile FILE compile the given JS file as a standalone executable\n"
|
" --stack-size n limit the stack size to 'n' bytes\n"
|
||||||
"-o --out FILE output file for standalone executables\n"
|
" --unhandled-rejection dump unhandled promise rejections\n"
|
||||||
" --exe select the executable to use as the base, defaults to the current one\n"
|
"-q --quit just instantiate the interpreter and quit\n");
|
||||||
" --memory-limit n limit the memory usage to 'n' Kbytes\n"
|
|
||||||
" --stack-size n limit the stack size to 'n' Kbytes\n"
|
|
||||||
"-q --quit just instantiate the interpreter and quit\n", JS_GetVersion());
|
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -398,55 +300,48 @@ int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
JSRuntime *rt;
|
JSRuntime *rt;
|
||||||
JSContext *ctx;
|
JSContext *ctx;
|
||||||
JSValue ret = JS_UNDEFINED;
|
|
||||||
struct trace_malloc_data trace_data = { NULL };
|
struct trace_malloc_data trace_data = { NULL };
|
||||||
int r = 0;
|
int optind;
|
||||||
int optind = 1;
|
|
||||||
char *compile_file = NULL;
|
|
||||||
char *exe = NULL;
|
|
||||||
char *expr = NULL;
|
char *expr = NULL;
|
||||||
char *dump_flags_str = NULL;
|
|
||||||
char *out = NULL;
|
|
||||||
int standalone = 0;
|
|
||||||
int interactive = 0;
|
int interactive = 0;
|
||||||
int dump_memory = 0;
|
int dump_memory = 0;
|
||||||
int dump_flags = 0;
|
|
||||||
int trace_memory = 0;
|
int trace_memory = 0;
|
||||||
int empty_run = 0;
|
int empty_run = 0;
|
||||||
int module = -1;
|
int module = -1;
|
||||||
int load_std = 0;
|
int load_std = 0;
|
||||||
|
int dump_unhandled_promise_rejection = 0;
|
||||||
|
size_t memory_limit = 0;
|
||||||
char *include_list[32];
|
char *include_list[32];
|
||||||
int i, include_count = 0;
|
int i, include_count = 0;
|
||||||
int64_t memory_limit = -1;
|
#ifdef CONFIG_BIGNUM
|
||||||
int64_t stack_size = -1;
|
int load_jscalc;
|
||||||
|
#endif
|
||||||
|
size_t stack_size = 0;
|
||||||
|
|
||||||
/* save for later */
|
#ifdef CONFIG_BIGNUM
|
||||||
qjs__argc = argc;
|
/* load jscalc runtime if invoked as 'qjscalc' */
|
||||||
qjs__argv = argv;
|
{
|
||||||
|
const char *p, *exename;
|
||||||
if (is_standalone(argv[0])) {
|
exename = argv[0];
|
||||||
standalone = 1;
|
p = strrchr(exename, '/');
|
||||||
goto start;
|
if (p)
|
||||||
|
exename = p + 1;
|
||||||
|
load_jscalc = !strcmp(exename, "qjscalc");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
dump_flags_str = getenv("QJS_DUMP_FLAGS");
|
|
||||||
dump_flags = dump_flags_str ? strtol(dump_flags_str, NULL, 16) : 0;
|
|
||||||
|
|
||||||
/* cannot use getopt because we want to pass the command line to
|
/* cannot use getopt because we want to pass the command line to
|
||||||
the script */
|
the script */
|
||||||
|
optind = 1;
|
||||||
while (optind < argc && *argv[optind] == '-') {
|
while (optind < argc && *argv[optind] == '-') {
|
||||||
char *arg = argv[optind] + 1;
|
char *arg = argv[optind] + 1;
|
||||||
const char *longopt = "";
|
const char *longopt = "";
|
||||||
char *opt_arg = NULL;
|
|
||||||
/* a single - is not an option, it also stops argument scanning */
|
/* a single - is not an option, it also stops argument scanning */
|
||||||
if (!*arg)
|
if (!*arg)
|
||||||
break;
|
break;
|
||||||
optind++;
|
optind++;
|
||||||
if (*arg == '-') {
|
if (*arg == '-') {
|
||||||
longopt = arg + 1;
|
longopt = arg + 1;
|
||||||
opt_arg = strchr(longopt, '=');
|
|
||||||
if (opt_arg)
|
|
||||||
*opt_arg++ = '\0';
|
|
||||||
arg += strlen(arg);
|
arg += strlen(arg);
|
||||||
/* -- stops argument scanning */
|
/* -- stops argument scanning */
|
||||||
if (!*longopt)
|
if (!*longopt)
|
||||||
|
@ -454,25 +349,23 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
for (; *arg || *longopt; longopt = "") {
|
for (; *arg || *longopt; longopt = "") {
|
||||||
char opt = *arg;
|
char opt = *arg;
|
||||||
if (opt) {
|
if (opt)
|
||||||
arg++;
|
arg++;
|
||||||
if (!opt_arg && *arg)
|
|
||||||
opt_arg = arg;
|
|
||||||
}
|
|
||||||
if (opt == 'h' || opt == '?' || !strcmp(longopt, "help")) {
|
if (opt == 'h' || opt == '?' || !strcmp(longopt, "help")) {
|
||||||
help();
|
help();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (opt == 'e' || !strcmp(longopt, "eval")) {
|
if (opt == 'e' || !strcmp(longopt, "eval")) {
|
||||||
if (!opt_arg) {
|
if (*arg) {
|
||||||
if (optind >= argc) {
|
expr = arg;
|
||||||
fprintf(stderr, "qjs: missing expression for -e\n");
|
break;
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
opt_arg = argv[optind++];
|
|
||||||
}
|
}
|
||||||
expr = opt_arg;
|
if (optind < argc) {
|
||||||
break;
|
expr = argv[optind++];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fprintf(stderr, "qjs: missing expression for -e\n");
|
||||||
|
exit(2);
|
||||||
}
|
}
|
||||||
if (opt == 'I' || !strcmp(longopt, "include")) {
|
if (opt == 'I' || !strcmp(longopt, "include")) {
|
||||||
if (optind >= argc) {
|
if (optind >= argc) {
|
||||||
|
@ -502,10 +395,6 @@ int main(int argc, char **argv)
|
||||||
dump_memory++;
|
dump_memory++;
|
||||||
continue;
|
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")) {
|
if (opt == 'T' || !strcmp(longopt, "trace")) {
|
||||||
trace_memory++;
|
trace_memory++;
|
||||||
continue;
|
continue;
|
||||||
|
@ -514,64 +403,39 @@ int main(int argc, char **argv)
|
||||||
load_std = 1;
|
load_std = 1;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (!strcmp(longopt, "unhandled-rejection")) {
|
||||||
|
dump_unhandled_promise_rejection = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
|
if (!strcmp(longopt, "bignum")) {
|
||||||
|
bignum_ext = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!strcmp(longopt, "qjscalc")) {
|
||||||
|
load_jscalc = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (opt == 'q' || !strcmp(longopt, "quit")) {
|
if (opt == 'q' || !strcmp(longopt, "quit")) {
|
||||||
empty_run++;
|
empty_run++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(longopt, "memory-limit")) {
|
if (!strcmp(longopt, "memory-limit")) {
|
||||||
if (!opt_arg) {
|
if (optind >= argc) {
|
||||||
if (optind >= argc) {
|
fprintf(stderr, "expecting memory limit");
|
||||||
fprintf(stderr, "expecting memory limit");
|
exit(1);
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
opt_arg = argv[optind++];
|
|
||||||
}
|
}
|
||||||
memory_limit = parse_limit(opt_arg);
|
memory_limit = (size_t)strtod(argv[optind++], NULL);
|
||||||
break;
|
continue;
|
||||||
}
|
}
|
||||||
if (!strcmp(longopt, "stack-size")) {
|
if (!strcmp(longopt, "stack-size")) {
|
||||||
if (!opt_arg) {
|
if (optind >= argc) {
|
||||||
if (optind >= argc) {
|
fprintf(stderr, "expecting stack size");
|
||||||
fprintf(stderr, "expecting stack size");
|
exit(1);
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
opt_arg = argv[optind++];
|
|
||||||
}
|
}
|
||||||
stack_size = parse_limit(opt_arg);
|
stack_size = (size_t)strtod(argv[optind++], NULL);
|
||||||
break;
|
continue;
|
||||||
}
|
|
||||||
if (opt == 'c' || !strcmp(longopt, "compile")) {
|
|
||||||
if (!opt_arg) {
|
|
||||||
if (optind >= argc) {
|
|
||||||
fprintf(stderr, "qjs: missing file for -c\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
opt_arg = argv[optind++];
|
|
||||||
}
|
|
||||||
compile_file = opt_arg;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (opt == 'o' || !strcmp(longopt, "out")) {
|
|
||||||
if (!opt_arg) {
|
|
||||||
if (optind >= argc) {
|
|
||||||
fprintf(stderr, "qjs: missing file for -o\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
opt_arg = argv[optind++];
|
|
||||||
}
|
|
||||||
out = opt_arg;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (!strcmp(longopt, "exe")) {
|
|
||||||
if (!opt_arg) {
|
|
||||||
if (optind >= argc) {
|
|
||||||
fprintf(stderr, "qjs: missing file for --exe\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
opt_arg = argv[optind++];
|
|
||||||
}
|
|
||||||
exe = opt_arg;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
if (opt) {
|
if (opt) {
|
||||||
fprintf(stderr, "qjs: unknown option '-%c'\n", opt);
|
fprintf(stderr, "qjs: unknown option '-%c'\n", opt);
|
||||||
|
@ -582,31 +446,25 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (compile_file && !out)
|
#ifdef CONFIG_BIGNUM
|
||||||
help();
|
if (load_jscalc)
|
||||||
|
bignum_ext = 1;
|
||||||
start:
|
#endif
|
||||||
|
|
||||||
if (trace_memory) {
|
if (trace_memory) {
|
||||||
js_trace_malloc_init(&trace_data);
|
js_trace_malloc_init(&trace_data);
|
||||||
rt = JS_NewRuntime2(&trace_mf, &trace_data);
|
rt = JS_NewRuntime2(&trace_mf, &trace_data);
|
||||||
} else {
|
} else {
|
||||||
#ifdef QJS_USE_MIMALLOC
|
|
||||||
rt = JS_NewRuntime2(&mi_mf, NULL);
|
|
||||||
#else
|
|
||||||
rt = JS_NewRuntime();
|
rt = JS_NewRuntime();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
if (!rt) {
|
if (!rt) {
|
||||||
fprintf(stderr, "qjs: cannot allocate JS runtime\n");
|
fprintf(stderr, "qjs: cannot allocate JS runtime\n");
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
if (memory_limit >= 0)
|
if (memory_limit != 0)
|
||||||
JS_SetMemoryLimit(rt, (size_t)memory_limit);
|
JS_SetMemoryLimit(rt, memory_limit);
|
||||||
if (stack_size >= 0)
|
if (stack_size != 0)
|
||||||
JS_SetMaxStackSize(rt, (size_t)stack_size);
|
JS_SetMaxStackSize(rt, stack_size);
|
||||||
if (dump_flags != 0)
|
|
||||||
JS_SetDumpFlags(rt, dump_flags);
|
|
||||||
js_std_set_worker_new_context_func(JS_NewCustomContext);
|
js_std_set_worker_new_context_func(JS_NewCustomContext);
|
||||||
js_std_init_handlers(rt);
|
js_std_init_handlers(rt);
|
||||||
ctx = JS_NewCustomContext(rt);
|
ctx = JS_NewCustomContext(rt);
|
||||||
|
@ -618,89 +476,38 @@ start:
|
||||||
/* loader for ES6 modules */
|
/* loader for ES6 modules */
|
||||||
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
|
JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
|
||||||
|
|
||||||
/* exit on unhandled promise rejections */
|
if (dump_unhandled_promise_rejection) {
|
||||||
JS_SetHostPromiseRejectionTracker(rt, js_std_promise_rejection_tracker, NULL);
|
JS_SetHostPromiseRejectionTracker(rt, js_std_promise_rejection_tracker,
|
||||||
|
NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (!empty_run) {
|
if (!empty_run) {
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
|
if (load_jscalc) {
|
||||||
|
js_std_eval_binary(ctx, qjsc_qjscalc, qjsc_qjscalc_size, 0);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
js_std_add_helpers(ctx, argc - optind, argv + optind);
|
js_std_add_helpers(ctx, argc - optind, argv + optind);
|
||||||
|
|
||||||
//POLYFILLS
|
/* make 'std' and 'os' visible to non module code */
|
||||||
const char *pf = "globalThis.global = globalThis;\n"
|
if (load_std) {
|
||||||
"global.console.error = console.log\n"
|
const char *str = "import * as std from 'std';\n"
|
||||||
"global.console.warn = console.log\n"
|
"import * as os from 'os';\n"
|
||||||
"globalThis.breakFunction = () => { throw new Error('Function Break'); };\n"
|
|
||||||
"\n"
|
|
||||||
"if (typeof os !== 'undefined') {\n"
|
|
||||||
" globalThis.sleep = os.sleep;\n"
|
|
||||||
" async function setTimeout2(func, ms) {globalThis.clearTimeout = false; await sleep(ms); if (!clearTimeout) { func(); } }\n"
|
|
||||||
" globalThis.setTimeout = setTimeout2\n"
|
|
||||||
"} else {\n"
|
|
||||||
" console.error('os is not defined.');\n"
|
|
||||||
"}\n"
|
|
||||||
"\n"
|
|
||||||
"if (typeof std !== 'undefined') {\n"
|
|
||||||
" globalThis.urlGet = std.urlGet;\n"
|
|
||||||
" globalThis.loadFile = std.loadFile;\n"
|
|
||||||
" globalThis.doneRequire = std.loadScript;\n"
|
|
||||||
" globalThis.printf = console.log;\n"
|
|
||||||
" globalThis.evalFile = std.loadScript;\n"
|
|
||||||
" globalThis.require = (moduleSpecifier) => import(moduleSpecifier).then(mod => mod.default || mod);\n"
|
|
||||||
" globalThis.stdRequire = globalThis.require;\n"
|
|
||||||
" globalThis.safeGlobals = {} \n"
|
|
||||||
" globalThis.getURL = std.urlGet;\n"
|
|
||||||
"} else {\n"
|
|
||||||
" console.error('std is not defined.');\n"
|
|
||||||
"}\n";
|
|
||||||
|
|
||||||
const char *stdAndOS =
|
|
||||||
"import * as bjson from 'qjs:bjson';\n"
|
|
||||||
"import * as std from 'qjs:std';\n"
|
|
||||||
"import * as os from 'qjs:os';\n"
|
|
||||||
"globalThis.bjson = bjson;\n"
|
|
||||||
"globalThis.std = std;\n"
|
"globalThis.std = std;\n"
|
||||||
"globalThis.os = os;\n";
|
"globalThis.os = os;\n";
|
||||||
|
eval_buf(ctx, str, strlen(str), "<input>", JS_EVAL_TYPE_MODULE);
|
||||||
|
}
|
||||||
/* make 'std' 'os' and polyfills visible to non module code */
|
|
||||||
eval_buf(ctx, stdAndOS, strlen(stdAndOS), "<input>", JS_EVAL_TYPE_MODULE);
|
|
||||||
eval_buf(ctx, pf, strlen(pf), "<input>", JS_EVAL_TYPE_MODULE);
|
|
||||||
|
|
||||||
for(i = 0; i < include_count; i++) {
|
for(i = 0; i < include_count; i++) {
|
||||||
if (eval_file(ctx, include_list[i], 0))
|
if (eval_file(ctx, include_list[i], module))
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (standalone) {
|
if (expr) {
|
||||||
JSValue ns = load_standalone_module(ctx);
|
|
||||||
if (JS_IsException(ns))
|
|
||||||
goto fail;
|
|
||||||
JSValue func = JS_GetPropertyStr(ctx, ns, "runStandalone");
|
|
||||||
JS_FreeValue(ctx, ns);
|
|
||||||
if (JS_IsException(func))
|
|
||||||
goto fail;
|
|
||||||
ret = JS_Call(ctx, func, JS_UNDEFINED, 0, NULL);
|
|
||||||
JS_FreeValue(ctx, func);
|
|
||||||
} else if (compile_file) {
|
|
||||||
JSValue ns = load_standalone_module(ctx);
|
|
||||||
if (JS_IsException(ns))
|
|
||||||
goto fail;
|
|
||||||
JSValue func = JS_GetPropertyStr(ctx, ns, "compileStandalone");
|
|
||||||
JS_FreeValue(ctx, ns);
|
|
||||||
if (JS_IsException(func))
|
|
||||||
goto fail;
|
|
||||||
JSValue args[3];
|
|
||||||
args[0] = JS_NewString(ctx, compile_file);
|
|
||||||
args[1] = JS_NewString(ctx, out);
|
|
||||||
args[2] = JS_NewString(ctx, exe != NULL ? exe : argv[0]);
|
|
||||||
ret = JS_Call(ctx, func, JS_UNDEFINED, countof(args), args);
|
|
||||||
JS_FreeValue(ctx, func);
|
|
||||||
JS_FreeValue(ctx, args[0]);
|
|
||||||
JS_FreeValue(ctx, args[1]);
|
|
||||||
JS_FreeValue(ctx, args[2]);
|
|
||||||
} else if (expr) {
|
|
||||||
if (eval_buf(ctx, expr, strlen(expr), "<cmdline>", 0))
|
if (eval_buf(ctx, expr, strlen(expr), "<cmdline>", 0))
|
||||||
goto fail;
|
goto fail;
|
||||||
} else if (optind >= argc) {
|
} else
|
||||||
|
if (optind >= argc) {
|
||||||
/* interactive mode */
|
/* interactive mode */
|
||||||
interactive = 1;
|
interactive = 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -712,21 +519,7 @@ start:
|
||||||
if (interactive) {
|
if (interactive) {
|
||||||
js_std_eval_binary(ctx, qjsc_repl, qjsc_repl_size, 0);
|
js_std_eval_binary(ctx, qjsc_repl, qjsc_repl_size, 0);
|
||||||
}
|
}
|
||||||
|
js_std_loop(ctx);
|
||||||
if (standalone || compile_file) {
|
|
||||||
if (JS_IsException(ret)) {
|
|
||||||
r = 1;
|
|
||||||
} else {
|
|
||||||
JS_FreeValue(ctx, ret);
|
|
||||||
r = js_std_loop(ctx);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
r = js_std_loop(ctx);
|
|
||||||
}
|
|
||||||
if (r) {
|
|
||||||
js_std_dump_error(ctx);
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dump_memory) {
|
if (dump_memory) {
|
||||||
|
@ -740,7 +533,7 @@ start:
|
||||||
|
|
||||||
if (empty_run && dump_memory) {
|
if (empty_run && dump_memory) {
|
||||||
clock_t t[5];
|
clock_t t[5];
|
||||||
double best[5] = {0};
|
double best[5];
|
||||||
int i, j;
|
int i, j;
|
||||||
for (i = 0; i < 100; i++) {
|
for (i = 0; i < 100; i++) {
|
||||||
t[0] = clock();
|
t[0] = clock();
|
||||||
|
|
383
qjsc.c
383
qjsc.c
|
@ -2,8 +2,6 @@
|
||||||
* QuickJS command line compiler
|
* QuickJS command line compiler
|
||||||
*
|
*
|
||||||
* Copyright (c) 2018-2021 Fabrice Bellard
|
* Copyright (c) 2018-2021 Fabrice Bellard
|
||||||
* Copyright (c) 2023 Ben Noordhuis
|
|
||||||
* Copyright (c) 2023 Saúl Ibarra Corretgé
|
|
||||||
*
|
*
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
@ -29,22 +27,15 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#if defined(_MSC_VER)
|
|
||||||
#include "getopt_compat.h"
|
|
||||||
#else
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#if !defined(_WIN32)
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "cutils.h"
|
#include "cutils.h"
|
||||||
#include "quickjs-libc.h"
|
#include "quickjs-libc.h"
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
OUTPUT_C,
|
|
||||||
OUTPUT_C_MAIN,
|
|
||||||
OUTPUT_RAW,
|
|
||||||
} OutputTypeEnum;
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *name;
|
char *name;
|
||||||
char *short_name;
|
char *short_name;
|
||||||
|
@ -57,13 +48,36 @@ typedef struct namelist_t {
|
||||||
int size;
|
int size;
|
||||||
} namelist_t;
|
} namelist_t;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char *option_name;
|
||||||
|
const char *init_name;
|
||||||
|
} FeatureEntry;
|
||||||
|
|
||||||
static namelist_t cname_list;
|
static namelist_t cname_list;
|
||||||
static namelist_t cmodule_list;
|
static namelist_t cmodule_list;
|
||||||
static namelist_t init_module_list;
|
static namelist_t init_module_list;
|
||||||
static OutputTypeEnum output_type;
|
static uint64_t feature_bitmap;
|
||||||
static FILE *outfile;
|
static FILE *outfile;
|
||||||
|
static BOOL byte_swap;
|
||||||
|
static BOOL dynamic_export;
|
||||||
static const char *c_ident_prefix = "qjsc_";
|
static const char *c_ident_prefix = "qjsc_";
|
||||||
static int strip;
|
|
||||||
|
#define FE_ALL (-1)
|
||||||
|
|
||||||
|
static const FeatureEntry feature_list[] = {
|
||||||
|
{ "date", "Date" },
|
||||||
|
{ "eval", "Eval" },
|
||||||
|
{ "string-normalize", "StringNormalize" },
|
||||||
|
{ "regexp", "RegExp" },
|
||||||
|
{ "json", "JSON" },
|
||||||
|
{ "proxy", "Proxy" },
|
||||||
|
{ "map", "MapSet" },
|
||||||
|
{ "typedarray", "TypedArrays" },
|
||||||
|
{ "promise", "Promise" },
|
||||||
|
#define FE_MODULE_LOADER 9
|
||||||
|
{ "module-loader", NULL },
|
||||||
|
{ "bigint", "BigInt" },
|
||||||
|
};
|
||||||
|
|
||||||
void namelist_add(namelist_t *lp, const char *name, const char *short_name,
|
void namelist_add(namelist_t *lp, const char *name, const char *short_name,
|
||||||
int flags)
|
int flags)
|
||||||
|
@ -126,7 +140,7 @@ static void get_c_name(char *buf, size_t buf_size, const char *file)
|
||||||
len = strlen(p);
|
len = strlen(p);
|
||||||
else
|
else
|
||||||
len = r - p;
|
len = r - p;
|
||||||
js__pstrcpy(buf, buf_size, c_ident_prefix);
|
pstrcpy(buf, buf_size, c_ident_prefix);
|
||||||
q = buf + strlen(buf);
|
q = buf + strlen(buf);
|
||||||
for(i = 0; i < len; i++) {
|
for(i = 0; i < len; i++) {
|
||||||
c = p[i];
|
c = p[i];
|
||||||
|
@ -157,19 +171,15 @@ static void dump_hex(FILE *f, const uint8_t *buf, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void output_object_code(JSContext *ctx,
|
static void output_object_code(JSContext *ctx,
|
||||||
FILE *fo, JSValue obj, const char *c_name,
|
FILE *fo, JSValueConst obj, const char *c_name,
|
||||||
BOOL load_only)
|
BOOL load_only)
|
||||||
{
|
{
|
||||||
uint8_t *out_buf;
|
uint8_t *out_buf;
|
||||||
size_t out_buf_len;
|
size_t out_buf_len;
|
||||||
int flags = JS_WRITE_OBJ_BYTECODE;
|
int flags;
|
||||||
|
flags = JS_WRITE_OBJ_BYTECODE;
|
||||||
if (strip) {
|
if (byte_swap)
|
||||||
flags |= JS_WRITE_OBJ_STRIP_SOURCE;
|
flags |= JS_WRITE_OBJ_BSWAP;
|
||||||
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, flags);
|
||||||
if (!out_buf) {
|
if (!out_buf) {
|
||||||
js_std_dump_error(ctx);
|
js_std_dump_error(ctx);
|
||||||
|
@ -178,16 +188,12 @@ static void output_object_code(JSContext *ctx,
|
||||||
|
|
||||||
namelist_add(&cname_list, c_name, NULL, load_only);
|
namelist_add(&cname_list, c_name, NULL, load_only);
|
||||||
|
|
||||||
if (output_type == OUTPUT_RAW) {
|
fprintf(fo, "const uint32_t %s_size = %u;\n\n",
|
||||||
fwrite(out_buf, 1, out_buf_len, fo);
|
c_name, (unsigned int)out_buf_len);
|
||||||
} else {
|
fprintf(fo, "const uint8_t %s[%u] = {\n",
|
||||||
fprintf(fo, "const uint32_t %s_size = %u;\n\n",
|
c_name, (unsigned int)out_buf_len);
|
||||||
c_name, (unsigned int)out_buf_len);
|
dump_hex(fo, out_buf, out_buf_len);
|
||||||
fprintf(fo, "const uint8_t %s[%u] = {\n",
|
fprintf(fo, "};\n\n");
|
||||||
c_name, (unsigned int)out_buf_len);
|
|
||||||
dump_hex(fo, out_buf, out_buf_len);
|
|
||||||
fprintf(fo, "};\n\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
js_free(ctx, out_buf);
|
js_free(ctx, out_buf);
|
||||||
}
|
}
|
||||||
|
@ -196,7 +202,6 @@ static int js_module_dummy_init(JSContext *ctx, JSModuleDef *m)
|
||||||
{
|
{
|
||||||
/* should never be called when compiling JS code */
|
/* should never be called when compiling JS code */
|
||||||
abort();
|
abort();
|
||||||
return -1; // pacify compiler
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void find_unique_cname(char *cname, size_t cname_size)
|
static void find_unique_cname(char *cname, size_t cname_size)
|
||||||
|
@ -218,7 +223,7 @@ static void find_unique_cname(char *cname, size_t cname_size)
|
||||||
break;
|
break;
|
||||||
suffix_num++;
|
suffix_num++;
|
||||||
}
|
}
|
||||||
js__pstrcpy(cname, cname_size, cname1);
|
pstrcpy(cname, cname_size, cname1);
|
||||||
}
|
}
|
||||||
|
|
||||||
JSModuleDef *jsc_module_loader(JSContext *ctx,
|
JSModuleDef *jsc_module_loader(JSContext *ctx,
|
||||||
|
@ -234,10 +239,13 @@ JSModuleDef *jsc_module_loader(JSContext *ctx,
|
||||||
namelist_add(&init_module_list, e->name, e->short_name, 0);
|
namelist_add(&init_module_list, e->name, e->short_name, 0);
|
||||||
/* create a dummy module */
|
/* create a dummy module */
|
||||||
m = JS_NewCModule(ctx, module_name, js_module_dummy_init);
|
m = JS_NewCModule(ctx, module_name, js_module_dummy_init);
|
||||||
} else if (js__has_suffix(module_name, ".so")) {
|
} else if (has_suffix(module_name, ".so")) {
|
||||||
JS_ThrowReferenceError(ctx, "%s: dynamically linking to shared libraries not supported",
|
fprintf(stderr, "Warning: binary module '%s' will be dynamically loaded\n", module_name);
|
||||||
module_name);
|
/* create a dummy module */
|
||||||
return NULL;
|
m = JS_NewCModule(ctx, module_name, js_module_dummy_init);
|
||||||
|
/* the resulting executable will export its symbols for the
|
||||||
|
dynamic library */
|
||||||
|
dynamic_export = TRUE;
|
||||||
} else {
|
} else {
|
||||||
size_t buf_len;
|
size_t buf_len;
|
||||||
uint8_t *buf;
|
uint8_t *buf;
|
||||||
|
@ -272,7 +280,6 @@ JSModuleDef *jsc_module_loader(JSContext *ctx,
|
||||||
|
|
||||||
static void compile_file(JSContext *ctx, FILE *fo,
|
static void compile_file(JSContext *ctx, FILE *fo,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
const char *script_name,
|
|
||||||
const char *c_name1,
|
const char *c_name1,
|
||||||
int module)
|
int module)
|
||||||
{
|
{
|
||||||
|
@ -289,21 +296,21 @@ static void compile_file(JSContext *ctx, FILE *fo,
|
||||||
}
|
}
|
||||||
eval_flags = JS_EVAL_FLAG_COMPILE_ONLY;
|
eval_flags = JS_EVAL_FLAG_COMPILE_ONLY;
|
||||||
if (module < 0) {
|
if (module < 0) {
|
||||||
module = (js__has_suffix(filename, ".mjs") ||
|
module = (has_suffix(filename, ".mjs") ||
|
||||||
JS_DetectModule((const char *)buf, buf_len));
|
JS_DetectModule((const char *)buf, buf_len));
|
||||||
}
|
}
|
||||||
if (module)
|
if (module)
|
||||||
eval_flags |= JS_EVAL_TYPE_MODULE;
|
eval_flags |= JS_EVAL_TYPE_MODULE;
|
||||||
else
|
else
|
||||||
eval_flags |= JS_EVAL_TYPE_GLOBAL;
|
eval_flags |= JS_EVAL_TYPE_GLOBAL;
|
||||||
obj = JS_Eval(ctx, (const char *)buf, buf_len, script_name ? script_name : filename, eval_flags);
|
obj = JS_Eval(ctx, (const char *)buf, buf_len, filename, eval_flags);
|
||||||
if (JS_IsException(obj)) {
|
if (JS_IsException(obj)) {
|
||||||
js_std_dump_error(ctx);
|
js_std_dump_error(ctx);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
js_free(ctx, buf);
|
js_free(ctx, buf);
|
||||||
if (c_name1) {
|
if (c_name1) {
|
||||||
js__pstrcpy(c_name, sizeof(c_name), c_name1);
|
pstrcpy(c_name, sizeof(c_name), c_name1);
|
||||||
} else {
|
} else {
|
||||||
get_c_name(c_name, sizeof(c_name), filename);
|
get_c_name(c_name, sizeof(c_name), filename);
|
||||||
}
|
}
|
||||||
|
@ -314,103 +321,245 @@ static void compile_file(JSContext *ctx, FILE *fo,
|
||||||
static const char main_c_template1[] =
|
static const char main_c_template1[] =
|
||||||
"int main(int argc, char **argv)\n"
|
"int main(int argc, char **argv)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" int r;\n"
|
|
||||||
" JSRuntime *rt;\n"
|
" JSRuntime *rt;\n"
|
||||||
" JSContext *ctx;\n"
|
" JSContext *ctx;\n"
|
||||||
" r = 0;\n"
|
|
||||||
" rt = JS_NewRuntime();\n"
|
" rt = JS_NewRuntime();\n"
|
||||||
" js_std_set_worker_new_context_func(JS_NewCustomContext);\n"
|
" js_std_set_worker_new_context_func(JS_NewCustomContext);\n"
|
||||||
" js_std_init_handlers(rt);\n"
|
" js_std_init_handlers(rt);\n"
|
||||||
;
|
;
|
||||||
|
|
||||||
static const char main_c_template2[] =
|
static const char main_c_template2[] =
|
||||||
" r = js_std_loop(ctx);\n"
|
" js_std_loop(ctx);\n"
|
||||||
" if (r) {\n"
|
|
||||||
" js_std_dump_error(ctx);\n"
|
|
||||||
" }\n"
|
|
||||||
" js_std_free_handlers(rt);\n"
|
" js_std_free_handlers(rt);\n"
|
||||||
" JS_FreeContext(ctx);\n"
|
" JS_FreeContext(ctx);\n"
|
||||||
" JS_FreeRuntime(rt);\n"
|
" JS_FreeRuntime(rt);\n"
|
||||||
" return r;\n"
|
" return 0;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
#define PROG_NAME "qjsc"
|
#define PROG_NAME "qjsc"
|
||||||
|
|
||||||
void help(void)
|
void help(void)
|
||||||
{
|
{
|
||||||
printf("QuickJS-ng Compiler DoneJS Edition version %s\n"
|
printf("QuickJS Compiler version " CONFIG_VERSION "\n"
|
||||||
"usage: " PROG_NAME " [options] [files]\n"
|
"usage: " PROG_NAME " [options] [files]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"options are:\n"
|
"options are:\n"
|
||||||
"-b output raw bytecode instead of C code\n"
|
"-c only output bytecode to a C file\n"
|
||||||
"-e output main() and bytecode in a C file\n"
|
"-e output main() and bytecode to a C file (default = executable output)\n"
|
||||||
"-o output set the output filename\n"
|
"-o output set the output filename\n"
|
||||||
"-n script_name set the script name (as used in stack traces)\n"
|
|
||||||
"-N cname set the C name of the generated data\n"
|
"-N cname set the C name of the generated data\n"
|
||||||
"-m compile as Javascript module (default=autodetect)\n"
|
"-m compile as Javascript module (default=autodetect)\n"
|
||||||
"-D module_name compile a dynamically loaded module or worker\n"
|
"-D module_name compile a dynamically loaded module or worker\n"
|
||||||
"-M module_name[,cname] add initialization code for an external C module\n"
|
"-M module_name[,cname] add initialization code for an external C module\n"
|
||||||
|
"-x byte swapped output\n"
|
||||||
"-p prefix set the prefix of the generated C names\n"
|
"-p prefix set the prefix of the generated C names\n"
|
||||||
"-s strip the source code, specify twice to also strip debug info\n"
|
|
||||||
"-S n set the maximum stack size to 'n' bytes (default=%d)\n",
|
"-S n set the maximum stack size to 'n' bytes (default=%d)\n",
|
||||||
JS_GetVersion(),
|
|
||||||
JS_DEFAULT_STACK_SIZE);
|
JS_DEFAULT_STACK_SIZE);
|
||||||
|
#ifdef CONFIG_LTO
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
printf("-flto use link time optimization\n");
|
||||||
|
printf("-fbignum enable bignum extensions\n");
|
||||||
|
printf("-fno-[");
|
||||||
|
for(i = 0; i < countof(feature_list); i++) {
|
||||||
|
if (i != 0)
|
||||||
|
printf("|");
|
||||||
|
printf("%s", feature_list[i].option_name);
|
||||||
|
}
|
||||||
|
printf("]\n"
|
||||||
|
" disable selected language features (smaller code size)\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(CONFIG_CC) && !defined(_WIN32)
|
||||||
|
|
||||||
|
int exec_cmd(char **argv)
|
||||||
|
{
|
||||||
|
int pid, status, ret;
|
||||||
|
|
||||||
|
pid = fork();
|
||||||
|
if (pid == 0) {
|
||||||
|
execvp(argv[0], argv);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
for(;;) {
|
||||||
|
ret = waitpid(pid, &status, 0);
|
||||||
|
if (ret == pid && WIFEXITED(status))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return WEXITSTATUS(status);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int output_executable(const char *out_filename, const char *cfilename,
|
||||||
|
BOOL use_lto, BOOL verbose, const char *exename)
|
||||||
|
{
|
||||||
|
const char *argv[64];
|
||||||
|
const char **arg, *bn_suffix, *lto_suffix;
|
||||||
|
char libjsname[1024];
|
||||||
|
char exe_dir[1024], inc_dir[1024], lib_dir[1024], buf[1024], *p;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* get the directory of the executable */
|
||||||
|
pstrcpy(exe_dir, sizeof(exe_dir), exename);
|
||||||
|
p = strrchr(exe_dir, '/');
|
||||||
|
if (p) {
|
||||||
|
*p = '\0';
|
||||||
|
} else {
|
||||||
|
pstrcpy(exe_dir, sizeof(exe_dir), ".");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* if 'quickjs.h' is present at the same path as the executable, we
|
||||||
|
use it as include and lib directory */
|
||||||
|
snprintf(buf, sizeof(buf), "%s/quickjs.h", exe_dir);
|
||||||
|
if (access(buf, R_OK) == 0) {
|
||||||
|
pstrcpy(inc_dir, sizeof(inc_dir), exe_dir);
|
||||||
|
pstrcpy(lib_dir, sizeof(lib_dir), exe_dir);
|
||||||
|
} else {
|
||||||
|
snprintf(inc_dir, sizeof(inc_dir), "%s/include/quickjs", CONFIG_PREFIX);
|
||||||
|
snprintf(lib_dir, sizeof(lib_dir), "%s/lib/quickjs", CONFIG_PREFIX);
|
||||||
|
}
|
||||||
|
|
||||||
|
lto_suffix = "";
|
||||||
|
bn_suffix = "";
|
||||||
|
|
||||||
|
arg = argv;
|
||||||
|
*arg++ = CONFIG_CC;
|
||||||
|
*arg++ = "-O2";
|
||||||
|
#ifdef CONFIG_LTO
|
||||||
|
if (use_lto) {
|
||||||
|
*arg++ = "-flto";
|
||||||
|
lto_suffix = ".lto";
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/* XXX: use the executable path to find the includes files and
|
||||||
|
libraries */
|
||||||
|
*arg++ = "-D";
|
||||||
|
*arg++ = "_GNU_SOURCE";
|
||||||
|
*arg++ = "-I";
|
||||||
|
*arg++ = inc_dir;
|
||||||
|
*arg++ = "-o";
|
||||||
|
*arg++ = out_filename;
|
||||||
|
if (dynamic_export)
|
||||||
|
*arg++ = "-rdynamic";
|
||||||
|
*arg++ = cfilename;
|
||||||
|
snprintf(libjsname, sizeof(libjsname), "%s/libquickjs%s%s.a",
|
||||||
|
lib_dir, bn_suffix, lto_suffix);
|
||||||
|
*arg++ = libjsname;
|
||||||
|
*arg++ = "-lm";
|
||||||
|
*arg++ = "-ldl";
|
||||||
|
*arg++ = "-lpthread";
|
||||||
|
*arg = NULL;
|
||||||
|
|
||||||
|
if (verbose) {
|
||||||
|
for(arg = argv; *arg != NULL; arg++)
|
||||||
|
printf("%s ", *arg);
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = exec_cmd((char **)argv);
|
||||||
|
unlink(cfilename);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
static int output_executable(const char *out_filename, const char *cfilename,
|
||||||
|
BOOL use_lto, BOOL verbose, const char *exename)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Executable output is not supported for this target\n");
|
||||||
|
exit(1);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
OUTPUT_C,
|
||||||
|
OUTPUT_C_MAIN,
|
||||||
|
OUTPUT_EXECUTABLE,
|
||||||
|
} OutputTypeEnum;
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
int c, i, verbose;
|
int c, i, verbose;
|
||||||
const char *out_filename, *cname, *script_name;
|
const char *out_filename, *cname;
|
||||||
char cfilename[1024];
|
char cfilename[1024];
|
||||||
FILE *fo;
|
FILE *fo;
|
||||||
JSRuntime *rt;
|
JSRuntime *rt;
|
||||||
JSContext *ctx;
|
JSContext *ctx;
|
||||||
|
BOOL use_lto;
|
||||||
int module;
|
int module;
|
||||||
|
OutputTypeEnum output_type;
|
||||||
size_t stack_size;
|
size_t stack_size;
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
|
BOOL bignum_ext = FALSE;
|
||||||
|
#endif
|
||||||
namelist_t dynamic_module_list;
|
namelist_t dynamic_module_list;
|
||||||
|
|
||||||
out_filename = NULL;
|
out_filename = NULL;
|
||||||
script_name = NULL;
|
output_type = OUTPUT_EXECUTABLE;
|
||||||
output_type = OUTPUT_C;
|
|
||||||
cname = NULL;
|
cname = NULL;
|
||||||
|
feature_bitmap = FE_ALL;
|
||||||
module = -1;
|
module = -1;
|
||||||
|
byte_swap = FALSE;
|
||||||
verbose = 0;
|
verbose = 0;
|
||||||
strip = 0;
|
use_lto = FALSE;
|
||||||
stack_size = 0;
|
stack_size = 0;
|
||||||
memset(&dynamic_module_list, 0, sizeof(dynamic_module_list));
|
memset(&dynamic_module_list, 0, sizeof(dynamic_module_list));
|
||||||
|
|
||||||
|
|
||||||
/* add system modules */
|
/* add system modules */
|
||||||
namelist_add(&cmodule_list, "qjs:std", "std", 0);
|
|
||||||
namelist_add(&cmodule_list, "qjs:os", "os", 0);
|
|
||||||
namelist_add(&cmodule_list, "qjs:bjson", "bjson", 0);
|
|
||||||
namelist_add(&cmodule_list, "std", "std", 0);
|
namelist_add(&cmodule_list, "std", "std", 0);
|
||||||
namelist_add(&cmodule_list, "os", "os", 0);
|
namelist_add(&cmodule_list, "os", "os", 0);
|
||||||
namelist_add(&cmodule_list, "bjson", "bjson", 0);
|
|
||||||
|
|
||||||
for(;;) {
|
for(;;) {
|
||||||
c = getopt(argc, argv, "ho:N:mn:bxesvM:p:S:D:");
|
c = getopt(argc, argv, "ho:cN:f:mxevM:p:S:D:");
|
||||||
if (c == -1)
|
if (c == -1)
|
||||||
break;
|
break;
|
||||||
switch(c) {
|
switch(c) {
|
||||||
case 'h':
|
case 'h':
|
||||||
help();
|
help();
|
||||||
case 'b':
|
|
||||||
output_type = OUTPUT_RAW;
|
|
||||||
break;
|
|
||||||
case 'o':
|
case 'o':
|
||||||
out_filename = optarg;
|
out_filename = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
output_type = OUTPUT_C;
|
||||||
|
break;
|
||||||
case 'e':
|
case 'e':
|
||||||
output_type = OUTPUT_C_MAIN;
|
output_type = OUTPUT_C_MAIN;
|
||||||
break;
|
break;
|
||||||
case 'n':
|
|
||||||
script_name = optarg;
|
|
||||||
break;
|
|
||||||
case 'N':
|
case 'N':
|
||||||
cname = optarg;
|
cname = optarg;
|
||||||
break;
|
break;
|
||||||
|
case 'f':
|
||||||
|
{
|
||||||
|
const char *p;
|
||||||
|
p = optarg;
|
||||||
|
if (!strcmp(optarg, "lto")) {
|
||||||
|
use_lto = TRUE;
|
||||||
|
} else if (strstart(p, "no-", &p)) {
|
||||||
|
use_lto = TRUE;
|
||||||
|
for(i = 0; i < countof(feature_list); i++) {
|
||||||
|
if (!strcmp(p, feature_list[i].option_name)) {
|
||||||
|
feature_bitmap &= ~((uint64_t)1 << i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i == countof(feature_list))
|
||||||
|
goto bad_feature;
|
||||||
|
} else
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
|
if (!strcmp(optarg, "bignum")) {
|
||||||
|
bignum_ext = TRUE;
|
||||||
|
} else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
bad_feature:
|
||||||
|
fprintf(stderr, "unsupported feature: %s\n", optarg);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'm':
|
case 'm':
|
||||||
module = 1;
|
module = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -419,11 +568,11 @@ int main(int argc, char **argv)
|
||||||
char *p;
|
char *p;
|
||||||
char path[1024];
|
char path[1024];
|
||||||
char cname[1024];
|
char cname[1024];
|
||||||
js__pstrcpy(path, sizeof(path), optarg);
|
pstrcpy(path, sizeof(path), optarg);
|
||||||
p = strchr(path, ',');
|
p = strchr(path, ',');
|
||||||
if (p) {
|
if (p) {
|
||||||
*p = '\0';
|
*p = '\0';
|
||||||
js__pstrcpy(cname, sizeof(cname), p + 1);
|
pstrcpy(cname, sizeof(cname), p + 1);
|
||||||
} else {
|
} else {
|
||||||
get_c_name(cname, sizeof(cname), path);
|
get_c_name(cname, sizeof(cname), path);
|
||||||
}
|
}
|
||||||
|
@ -433,8 +582,8 @@ int main(int argc, char **argv)
|
||||||
case 'D':
|
case 'D':
|
||||||
namelist_add(&dynamic_module_list, optarg, NULL, 0);
|
namelist_add(&dynamic_module_list, optarg, NULL, 0);
|
||||||
break;
|
break;
|
||||||
case 's':
|
case 'x':
|
||||||
strip++;
|
byte_swap = TRUE;
|
||||||
break;
|
break;
|
||||||
case 'v':
|
case 'v':
|
||||||
verbose++;
|
verbose++;
|
||||||
|
@ -453,16 +602,26 @@ int main(int argc, char **argv)
|
||||||
if (optind >= argc)
|
if (optind >= argc)
|
||||||
help();
|
help();
|
||||||
|
|
||||||
if (!out_filename)
|
if (!out_filename) {
|
||||||
out_filename = "out.c";
|
if (output_type == OUTPUT_EXECUTABLE) {
|
||||||
|
out_filename = "a.out";
|
||||||
|
} else {
|
||||||
|
out_filename = "out.c";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
js__pstrcpy(cfilename, sizeof(cfilename), out_filename);
|
if (output_type == OUTPUT_EXECUTABLE) {
|
||||||
|
#if defined(_WIN32) || defined(__ANDROID__)
|
||||||
if (output_type == OUTPUT_RAW)
|
/* XXX: find a /tmp directory ? */
|
||||||
fo = fopen(cfilename, "wb");
|
snprintf(cfilename, sizeof(cfilename), "out%d.c", getpid());
|
||||||
else
|
#else
|
||||||
fo = fopen(cfilename, "w");
|
snprintf(cfilename, sizeof(cfilename), "/tmp/out%d.c", getpid());
|
||||||
|
#endif
|
||||||
|
} else {
|
||||||
|
pstrcpy(cfilename, sizeof(cfilename), out_filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
fo = fopen(cfilename, "w");
|
||||||
if (!fo) {
|
if (!fo) {
|
||||||
perror(cfilename);
|
perror(cfilename);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -471,21 +630,27 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
rt = JS_NewRuntime();
|
rt = JS_NewRuntime();
|
||||||
ctx = JS_NewContext(rt);
|
ctx = JS_NewContext(rt);
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
|
if (bignum_ext) {
|
||||||
|
JS_AddIntrinsicBigFloat(ctx);
|
||||||
|
JS_AddIntrinsicBigDecimal(ctx);
|
||||||
|
JS_AddIntrinsicOperators(ctx);
|
||||||
|
JS_EnableBignumExt(ctx, TRUE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* loader for ES6 modules */
|
/* loader for ES6 modules */
|
||||||
JS_SetModuleLoaderFunc(rt, NULL, jsc_module_loader, NULL);
|
JS_SetModuleLoaderFunc(rt, NULL, jsc_module_loader, NULL);
|
||||||
|
|
||||||
if (output_type != OUTPUT_RAW) {
|
fprintf(fo, "/* File generated automatically by the QuickJS compiler. */\n"
|
||||||
fprintf(fo, "/* File generated automatically by the QuickJS-ng compiler. */\n"
|
"\n"
|
||||||
"\n"
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (output_type == OUTPUT_C_MAIN) {
|
if (output_type != OUTPUT_C) {
|
||||||
fprintf(fo, "#include \"quickjs-libc.h\"\n"
|
fprintf(fo, "#include \"quickjs-libc.h\"\n"
|
||||||
"\n"
|
"\n"
|
||||||
);
|
);
|
||||||
} else if (output_type == OUTPUT_C) {
|
} else {
|
||||||
fprintf(fo, "#include <inttypes.h>\n"
|
fprintf(fo, "#include <inttypes.h>\n"
|
||||||
"\n"
|
"\n"
|
||||||
);
|
);
|
||||||
|
@ -493,7 +658,7 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
for(i = optind; i < argc; i++) {
|
for(i = optind; i < argc; i++) {
|
||||||
const char *filename = argv[i];
|
const char *filename = argv[i];
|
||||||
compile_file(ctx, fo, filename, script_name, cname, module);
|
compile_file(ctx, fo, filename, cname, module);
|
||||||
cname = NULL;
|
cname = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -505,13 +670,31 @@ int main(int argc, char **argv)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (output_type == OUTPUT_C_MAIN) {
|
if (output_type != OUTPUT_C) {
|
||||||
fprintf(fo,
|
fprintf(fo,
|
||||||
"static JSContext *JS_NewCustomContext(JSRuntime *rt)\n"
|
"static JSContext *JS_NewCustomContext(JSRuntime *rt)\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" JSContext *ctx = JS_NewContext(rt);\n"
|
" JSContext *ctx = JS_NewContextRaw(rt);\n"
|
||||||
" if (!ctx)\n"
|
" if (!ctx)\n"
|
||||||
" return NULL;\n");
|
" return NULL;\n");
|
||||||
|
/* add the basic objects */
|
||||||
|
fprintf(fo, " JS_AddIntrinsicBaseObjects(ctx);\n");
|
||||||
|
for(i = 0; i < countof(feature_list); i++) {
|
||||||
|
if ((feature_bitmap & ((uint64_t)1 << i)) &&
|
||||||
|
feature_list[i].init_name) {
|
||||||
|
fprintf(fo, " JS_AddIntrinsic%s(ctx);\n",
|
||||||
|
feature_list[i].init_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
|
if (bignum_ext) {
|
||||||
|
fprintf(fo,
|
||||||
|
" JS_AddIntrinsicBigFloat(ctx);\n"
|
||||||
|
" JS_AddIntrinsicBigDecimal(ctx);\n"
|
||||||
|
" JS_AddIntrinsicOperators(ctx);\n"
|
||||||
|
" JS_EnableBignumExt(ctx, 1);\n");
|
||||||
|
}
|
||||||
|
#endif
|
||||||
/* add the precompiled modules (XXX: could modify the module
|
/* add the precompiled modules (XXX: could modify the module
|
||||||
loader instead) */
|
loader instead) */
|
||||||
for(i = 0; i < init_module_list.count; i++) {
|
for(i = 0; i < init_module_list.count; i++) {
|
||||||
|
@ -543,8 +726,10 @@ int main(int argc, char **argv)
|
||||||
(unsigned int)stack_size);
|
(unsigned int)stack_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* add the module loader */
|
/* add the module loader if necessary */
|
||||||
fprintf(fo, " JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);\n");
|
if (feature_bitmap & (1 << FE_MODULE_LOADER)) {
|
||||||
|
fprintf(fo, " JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);\n");
|
||||||
|
}
|
||||||
|
|
||||||
fprintf(fo,
|
fprintf(fo,
|
||||||
" ctx = JS_NewCustomContext(rt);\n"
|
" ctx = JS_NewCustomContext(rt);\n"
|
||||||
|
@ -565,6 +750,10 @@ int main(int argc, char **argv)
|
||||||
|
|
||||||
fclose(fo);
|
fclose(fo);
|
||||||
|
|
||||||
|
if (output_type == OUTPUT_EXECUTABLE) {
|
||||||
|
return output_executable(out_filename, cfilename, use_lto, verbose,
|
||||||
|
argv[0]);
|
||||||
|
}
|
||||||
namelist_free(&cname_list);
|
namelist_free(&cname_list);
|
||||||
namelist_free(&cmodule_list);
|
namelist_free(&cmodule_list);
|
||||||
namelist_free(&init_module_list);
|
namelist_free(&init_module_list);
|
||||||
|
|
2657
qjscalc.js
Normal file
2657
qjscalc.js
Normal file
File diff suppressed because it is too large
Load diff
|
@ -78,9 +78,9 @@ DEF(await, "await")
|
||||||
/* empty string */
|
/* empty string */
|
||||||
DEF(empty_string, "")
|
DEF(empty_string, "")
|
||||||
/* identifiers */
|
/* identifiers */
|
||||||
DEF(keys, "keys")
|
|
||||||
DEF(size, "size")
|
|
||||||
DEF(length, "length")
|
DEF(length, "length")
|
||||||
|
DEF(fileName, "fileName")
|
||||||
|
DEF(lineNumber, "lineNumber")
|
||||||
DEF(message, "message")
|
DEF(message, "message")
|
||||||
DEF(cause, "cause")
|
DEF(cause, "cause")
|
||||||
DEF(errors, "errors")
|
DEF(errors, "errors")
|
||||||
|
@ -172,11 +172,19 @@ DEF(status, "status")
|
||||||
DEF(reason, "reason")
|
DEF(reason, "reason")
|
||||||
DEF(globalThis, "globalThis")
|
DEF(globalThis, "globalThis")
|
||||||
DEF(bigint, "bigint")
|
DEF(bigint, "bigint")
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
|
DEF(bigfloat, "bigfloat")
|
||||||
|
DEF(bigdecimal, "bigdecimal")
|
||||||
|
DEF(roundingMode, "roundingMode")
|
||||||
|
DEF(maximumSignificantDigits, "maximumSignificantDigits")
|
||||||
|
DEF(maximumFractionDigits, "maximumFractionDigits")
|
||||||
|
#endif
|
||||||
|
/* the following 3 atoms are only used with CONFIG_ATOMICS */
|
||||||
DEF(not_equal, "not-equal")
|
DEF(not_equal, "not-equal")
|
||||||
DEF(timed_out, "timed-out")
|
DEF(timed_out, "timed-out")
|
||||||
DEF(ok, "ok")
|
DEF(ok, "ok")
|
||||||
|
/* */
|
||||||
DEF(toJSON, "toJSON")
|
DEF(toJSON, "toJSON")
|
||||||
DEF(maxByteLength, "maxByteLength")
|
|
||||||
/* class names */
|
/* class names */
|
||||||
DEF(Object, "Object")
|
DEF(Object, "Object")
|
||||||
DEF(Array, "Array")
|
DEF(Array, "Array")
|
||||||
|
@ -205,20 +213,21 @@ DEF(Int32Array, "Int32Array")
|
||||||
DEF(Uint32Array, "Uint32Array")
|
DEF(Uint32Array, "Uint32Array")
|
||||||
DEF(BigInt64Array, "BigInt64Array")
|
DEF(BigInt64Array, "BigInt64Array")
|
||||||
DEF(BigUint64Array, "BigUint64Array")
|
DEF(BigUint64Array, "BigUint64Array")
|
||||||
DEF(Float16Array, "Float16Array")
|
|
||||||
DEF(Float32Array, "Float32Array")
|
DEF(Float32Array, "Float32Array")
|
||||||
DEF(Float64Array, "Float64Array")
|
DEF(Float64Array, "Float64Array")
|
||||||
DEF(DataView, "DataView")
|
DEF(DataView, "DataView")
|
||||||
DEF(BigInt, "BigInt")
|
DEF(BigInt, "BigInt")
|
||||||
DEF(WeakRef, "WeakRef")
|
#ifdef CONFIG_BIGNUM
|
||||||
DEF(FinalizationRegistry, "FinalizationRegistry")
|
DEF(BigFloat, "BigFloat")
|
||||||
|
DEF(BigFloatEnv, "BigFloatEnv")
|
||||||
|
DEF(BigDecimal, "BigDecimal")
|
||||||
|
DEF(OperatorSet, "OperatorSet")
|
||||||
|
DEF(Operators, "Operators")
|
||||||
|
#endif
|
||||||
DEF(Map, "Map")
|
DEF(Map, "Map")
|
||||||
DEF(Set, "Set") /* Map + 1 */
|
DEF(Set, "Set") /* Map + 1 */
|
||||||
DEF(WeakMap, "WeakMap") /* Map + 2 */
|
DEF(WeakMap, "WeakMap") /* Map + 2 */
|
||||||
DEF(WeakSet, "WeakSet") /* Map + 3 */
|
DEF(WeakSet, "WeakSet") /* Map + 3 */
|
||||||
DEF(Iterator, "Iterator")
|
|
||||||
DEF(IteratorHelper, "Iterator Helper")
|
|
||||||
DEF(IteratorWrap, "Iterator Wrap")
|
|
||||||
DEF(Map_Iterator, "Map Iterator")
|
DEF(Map_Iterator, "Map Iterator")
|
||||||
DEF(Set_Iterator, "Set Iterator")
|
DEF(Set_Iterator, "Set Iterator")
|
||||||
DEF(Array_Iterator, "Array Iterator")
|
DEF(Array_Iterator, "Array Iterator")
|
||||||
|
@ -241,7 +250,6 @@ DEF(SyntaxError, "SyntaxError")
|
||||||
DEF(TypeError, "TypeError")
|
DEF(TypeError, "TypeError")
|
||||||
DEF(URIError, "URIError")
|
DEF(URIError, "URIError")
|
||||||
DEF(InternalError, "InternalError")
|
DEF(InternalError, "InternalError")
|
||||||
DEF(CallSite, "CallSite")
|
|
||||||
/* private symbols */
|
/* private symbols */
|
||||||
DEF(Private_brand, "<brand>")
|
DEF(Private_brand, "<brand>")
|
||||||
/* symbols */
|
/* symbols */
|
||||||
|
@ -258,5 +266,8 @@ DEF(Symbol_hasInstance, "Symbol.hasInstance")
|
||||||
DEF(Symbol_species, "Symbol.species")
|
DEF(Symbol_species, "Symbol.species")
|
||||||
DEF(Symbol_unscopables, "Symbol.unscopables")
|
DEF(Symbol_unscopables, "Symbol.unscopables")
|
||||||
DEF(Symbol_asyncIterator, "Symbol.asyncIterator")
|
DEF(Symbol_asyncIterator, "Symbol.asyncIterator")
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
|
DEF(Symbol_operatorSet, "Symbol.operatorSet")
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* DEF */
|
#endif /* DEF */
|
||||||
|
|
|
@ -1,54 +0,0 @@
|
||||||
/*
|
|
||||||
* QuickJS C atomics definitions
|
|
||||||
*
|
|
||||||
* Copyright (c) 2023 Marcin Kolny
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if (defined(__GNUC__) || defined(__GNUG__)) && !defined(__clang__)
|
|
||||||
// Use GCC builtins for version < 4.9
|
|
||||||
# if((__GNUC__ << 16) + __GNUC_MINOR__ < ((4) << 16) + 9)
|
|
||||||
# define GCC_BUILTIN_ATOMICS
|
|
||||||
# endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef GCC_BUILTIN_ATOMICS
|
|
||||||
#define atomic_fetch_add(obj, arg) \
|
|
||||||
__atomic_fetch_add(obj, arg, __ATOMIC_SEQ_CST)
|
|
||||||
#define atomic_compare_exchange_strong(obj, expected, desired) \
|
|
||||||
__atomic_compare_exchange_n(obj, expected, desired, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)
|
|
||||||
#define atomic_exchange(obj, desired) \
|
|
||||||
__atomic_exchange_n (obj, desired, __ATOMIC_SEQ_CST)
|
|
||||||
#define atomic_load(obj) \
|
|
||||||
__atomic_load_n(obj, __ATOMIC_SEQ_CST)
|
|
||||||
#define atomic_store(obj, desired) \
|
|
||||||
__atomic_store_n(obj, desired, __ATOMIC_SEQ_CST)
|
|
||||||
#define atomic_fetch_or(obj, arg) \
|
|
||||||
__atomic_fetch_or(obj, arg, __ATOMIC_SEQ_CST)
|
|
||||||
#define atomic_fetch_xor(obj, arg) \
|
|
||||||
__atomic_fetch_xor(obj, arg, __ATOMIC_SEQ_CST)
|
|
||||||
#define atomic_fetch_and(obj, arg) \
|
|
||||||
__atomic_fetch_and(obj, arg, __ATOMIC_SEQ_CST)
|
|
||||||
#define atomic_fetch_sub(obj, arg) \
|
|
||||||
__atomic_fetch_sub(obj, arg, __ATOMIC_SEQ_CST)
|
|
||||||
#define _Atomic
|
|
||||||
#else
|
|
||||||
#include <stdatomic.h>
|
|
||||||
#endif
|
|
1184
quickjs-libc.c
1184
quickjs-libc.c
File diff suppressed because it is too large
Load diff
|
@ -35,22 +35,21 @@ extern "C" {
|
||||||
|
|
||||||
JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name);
|
JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name);
|
||||||
JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name);
|
JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name);
|
||||||
JSModuleDef *js_init_module_bjson(JSContext *ctx, const char *module_name);
|
|
||||||
void js_std_add_helpers(JSContext *ctx, int argc, char **argv);
|
void js_std_add_helpers(JSContext *ctx, int argc, char **argv);
|
||||||
int js_std_loop(JSContext *ctx);
|
void js_std_loop(JSContext *ctx);
|
||||||
JSValue js_std_await(JSContext *ctx, JSValue obj);
|
JSValue js_std_await(JSContext *ctx, JSValue obj);
|
||||||
void js_std_init_handlers(JSRuntime *rt);
|
void js_std_init_handlers(JSRuntime *rt);
|
||||||
void js_std_free_handlers(JSRuntime *rt);
|
void js_std_free_handlers(JSRuntime *rt);
|
||||||
void js_std_dump_error(JSContext *ctx);
|
void js_std_dump_error(JSContext *ctx);
|
||||||
uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename);
|
uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename);
|
||||||
int js_module_set_import_meta(JSContext *ctx, JSValue func_val,
|
int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val,
|
||||||
JS_BOOL use_realpath, JS_BOOL is_main);
|
JS_BOOL use_realpath, JS_BOOL is_main);
|
||||||
JSModuleDef *js_module_loader(JSContext *ctx,
|
JSModuleDef *js_module_loader(JSContext *ctx,
|
||||||
const char *module_name, void *opaque);
|
const char *module_name, void *opaque);
|
||||||
void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
|
void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
|
||||||
int flags);
|
int flags);
|
||||||
void js_std_promise_rejection_tracker(JSContext *ctx, JSValue promise,
|
void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
|
||||||
JSValue reason,
|
JSValueConst reason,
|
||||||
JS_BOOL is_handled, void *opaque);
|
JS_BOOL is_handled, void *opaque);
|
||||||
void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt));
|
void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt));
|
||||||
|
|
||||||
|
|
|
@ -44,7 +44,6 @@ FMT(loc)
|
||||||
FMT(arg)
|
FMT(arg)
|
||||||
FMT(var_ref)
|
FMT(var_ref)
|
||||||
FMT(u32)
|
FMT(u32)
|
||||||
FMT(u32x2)
|
|
||||||
FMT(i32)
|
FMT(i32)
|
||||||
FMT(const)
|
FMT(const)
|
||||||
FMT(label)
|
FMT(label)
|
||||||
|
@ -111,7 +110,6 @@ DEF( return, 1, 1, 0, none)
|
||||||
DEF( return_undef, 1, 0, 0, none)
|
DEF( return_undef, 1, 0, 0, none)
|
||||||
DEF(check_ctor_return, 1, 1, 2, none)
|
DEF(check_ctor_return, 1, 1, 2, none)
|
||||||
DEF( check_ctor, 1, 0, 0, none)
|
DEF( check_ctor, 1, 0, 0, none)
|
||||||
DEF( init_ctor, 1, 0, 1, none)
|
|
||||||
DEF( check_brand, 1, 2, 2, none) /* this_obj func -> this_obj func */
|
DEF( check_brand, 1, 2, 2, none) /* this_obj func -> this_obj func */
|
||||||
DEF( add_brand, 1, 2, 0, none) /* this_obj home_obj -> */
|
DEF( add_brand, 1, 2, 0, none) /* this_obj home_obj -> */
|
||||||
DEF( return_async, 1, 1, 0, none)
|
DEF( return_async, 1, 1, 0, none)
|
||||||
|
@ -137,12 +135,9 @@ DEF( put_ref_value, 1, 3, 0, none)
|
||||||
DEF( define_var, 6, 0, 0, atom_u8)
|
DEF( define_var, 6, 0, 0, atom_u8)
|
||||||
DEF(check_define_var, 6, 0, 0, atom_u8)
|
DEF(check_define_var, 6, 0, 0, atom_u8)
|
||||||
DEF( define_func, 6, 1, 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_field, 5, 1, 1, atom)
|
||||||
DEF( get_field2, 5, 1, 2, atom)
|
DEF( get_field2, 5, 1, 2, atom)
|
||||||
DEF( put_field, 5, 2, 0, atom)
|
DEF( put_field, 5, 2, 0, atom)
|
||||||
|
|
||||||
DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */
|
DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */
|
||||||
DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */
|
DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */
|
||||||
DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */
|
DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */
|
||||||
|
@ -177,6 +172,7 @@ DEF(set_loc_uninitialized, 3, 0, 0, loc)
|
||||||
DEF( get_loc_check, 3, 0, 1, loc)
|
DEF( get_loc_check, 3, 0, 1, loc)
|
||||||
DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */
|
DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */
|
||||||
DEF( put_loc_check_init, 3, 1, 0, loc)
|
DEF( put_loc_check_init, 3, 1, 0, loc)
|
||||||
|
DEF(get_loc_checkthis, 3, 0, 1, loc)
|
||||||
DEF(get_var_ref_check, 3, 0, 1, var_ref)
|
DEF(get_var_ref_check, 3, 0, 1, var_ref)
|
||||||
DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */
|
DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */
|
||||||
DEF(put_var_ref_check_init, 3, 1, 0, var_ref)
|
DEF(put_var_ref_check_init, 3, 1, 0, var_ref)
|
||||||
|
@ -238,20 +234,15 @@ DEF( typeof, 1, 1, 1, none)
|
||||||
DEF( delete, 1, 2, 1, none)
|
DEF( delete, 1, 2, 1, none)
|
||||||
DEF( delete_var, 5, 0, 1, atom)
|
DEF( delete_var, 5, 0, 1, atom)
|
||||||
|
|
||||||
/* warning: order matters (see js_parse_assign_expr) */
|
|
||||||
DEF( mul, 1, 2, 1, none)
|
DEF( mul, 1, 2, 1, none)
|
||||||
DEF( div, 1, 2, 1, none)
|
DEF( div, 1, 2, 1, none)
|
||||||
DEF( mod, 1, 2, 1, none)
|
DEF( mod, 1, 2, 1, none)
|
||||||
DEF( add, 1, 2, 1, none)
|
DEF( add, 1, 2, 1, none)
|
||||||
DEF( sub, 1, 2, 1, none)
|
DEF( sub, 1, 2, 1, none)
|
||||||
|
DEF( pow, 1, 2, 1, none)
|
||||||
DEF( shl, 1, 2, 1, none)
|
DEF( shl, 1, 2, 1, none)
|
||||||
DEF( sar, 1, 2, 1, none)
|
DEF( sar, 1, 2, 1, none)
|
||||||
DEF( shr, 1, 2, 1, none)
|
DEF( shr, 1, 2, 1, none)
|
||||||
DEF( and, 1, 2, 1, none)
|
|
||||||
DEF( xor, 1, 2, 1, none)
|
|
||||||
DEF( or, 1, 2, 1, none)
|
|
||||||
DEF( pow, 1, 2, 1, none)
|
|
||||||
|
|
||||||
DEF( lt, 1, 2, 1, none)
|
DEF( lt, 1, 2, 1, none)
|
||||||
DEF( lte, 1, 2, 1, none)
|
DEF( lte, 1, 2, 1, none)
|
||||||
DEF( gt, 1, 2, 1, none)
|
DEF( gt, 1, 2, 1, none)
|
||||||
|
@ -262,8 +253,15 @@ DEF( eq, 1, 2, 1, none)
|
||||||
DEF( neq, 1, 2, 1, none)
|
DEF( neq, 1, 2, 1, none)
|
||||||
DEF( strict_eq, 1, 2, 1, none)
|
DEF( strict_eq, 1, 2, 1, none)
|
||||||
DEF( strict_neq, 1, 2, 1, none)
|
DEF( strict_neq, 1, 2, 1, none)
|
||||||
|
DEF( and, 1, 2, 1, none)
|
||||||
|
DEF( xor, 1, 2, 1, none)
|
||||||
|
DEF( or, 1, 2, 1, none)
|
||||||
DEF(is_undefined_or_null, 1, 1, 1, none)
|
DEF(is_undefined_or_null, 1, 1, 1, none)
|
||||||
DEF( private_in, 1, 2, 1, none)
|
DEF( private_in, 1, 2, 1, none)
|
||||||
|
#ifdef CONFIG_BIGNUM
|
||||||
|
DEF( mul_pow10, 1, 2, 1, none)
|
||||||
|
DEF( math_mod, 1, 2, 1, none)
|
||||||
|
#endif
|
||||||
/* must be the last non short and non temporary opcode */
|
/* must be the last non short and non temporary opcode */
|
||||||
DEF( nop, 1, 0, 0, none)
|
DEF( nop, 1, 0, 0, none)
|
||||||
|
|
||||||
|
@ -274,6 +272,8 @@ def( leave_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */
|
||||||
|
|
||||||
def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */
|
def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */
|
||||||
|
|
||||||
|
/* the following opcodes must be in the same order as the 'with_x' and
|
||||||
|
get_var_undef, get_var and put_var opcodes */
|
||||||
def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
||||||
def( scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
def( scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
||||||
def( scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
def( scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
||||||
|
@ -281,6 +281,7 @@ def(scope_delete_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase
|
||||||
def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */
|
def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */
|
||||||
def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
||||||
def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
||||||
|
def(scope_get_var_checkthis, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2, only used to return 'this' in derived class constructors */
|
||||||
def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */
|
def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */
|
||||||
def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */
|
def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */
|
||||||
def(scope_put_private_field, 7, 2, 0, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */
|
def(scope_put_private_field, 7, 2, 0, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */
|
||||||
|
@ -289,8 +290,9 @@ def(get_field_opt_chain, 5, 1, 1, atom) /* emitted in phase 1, removed in phase
|
||||||
def(get_array_el_opt_chain, 1, 2, 1, none) /* emitted in phase 1, removed in phase 2 */
|
def(get_array_el_opt_chain, 1, 2, 1, none) /* emitted in phase 1, removed in phase 2 */
|
||||||
def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
|
def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
|
||||||
|
|
||||||
def( source_loc, 9, 0, 0, u32x2) /* emitted in phase 1, removed in phase 3 */
|
def( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
|
||||||
|
|
||||||
|
#if SHORT_OPCODES
|
||||||
DEF( push_minus1, 1, 0, 1, none_int)
|
DEF( push_minus1, 1, 0, 1, none_int)
|
||||||
DEF( push_0, 1, 0, 1, none_int)
|
DEF( push_0, 1, 0, 1, none_int)
|
||||||
DEF( push_1, 1, 0, 1, none_int)
|
DEF( push_1, 1, 0, 1, none_int)
|
||||||
|
@ -310,7 +312,6 @@ DEF( get_loc8, 2, 0, 1, loc8)
|
||||||
DEF( put_loc8, 2, 1, 0, loc8)
|
DEF( put_loc8, 2, 1, 0, loc8)
|
||||||
DEF( set_loc8, 2, 1, 1, loc8)
|
DEF( set_loc8, 2, 1, 1, loc8)
|
||||||
|
|
||||||
DEF( get_loc0_loc1, 1, 0, 2, none_loc)
|
|
||||||
DEF( get_loc0, 1, 0, 1, none_loc)
|
DEF( get_loc0, 1, 0, 1, none_loc)
|
||||||
DEF( get_loc1, 1, 0, 1, none_loc)
|
DEF( get_loc1, 1, 0, 1, none_loc)
|
||||||
DEF( get_loc2, 1, 0, 1, none_loc)
|
DEF( get_loc2, 1, 0, 1, none_loc)
|
||||||
|
@ -364,11 +365,7 @@ DEF( is_undefined, 1, 1, 1, none)
|
||||||
DEF( is_null, 1, 1, 1, none)
|
DEF( is_null, 1, 1, 1, none)
|
||||||
DEF(typeof_is_undefined, 1, 1, 1, none)
|
DEF(typeof_is_undefined, 1, 1, 1, none)
|
||||||
DEF( typeof_is_function, 1, 1, 1, none)
|
DEF( typeof_is_function, 1, 1, 1, none)
|
||||||
|
#endif
|
||||||
// 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)
|
|
||||||
|
|
||||||
#undef DEF
|
#undef DEF
|
||||||
#undef def
|
#undef def
|
||||||
|
|
1
readme.txt
Normal file
1
readme.txt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
The main documentation is in doc/quickjs.pdf or doc/quickjs.html.
|
158
release.sh
Executable file
158
release.sh
Executable file
|
@ -0,0 +1,158 @@
|
||||||
|
#!/bin/sh
|
||||||
|
# Release the QuickJS source code
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
version=`cat VERSION`
|
||||||
|
|
||||||
|
if [ "$1" = "-h" ] ; then
|
||||||
|
echo "release.sh [release_list]"
|
||||||
|
echo ""
|
||||||
|
echo "release_list: extras binary win_binary quickjs"
|
||||||
|
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
release_list="extras binary win_binary quickjs"
|
||||||
|
|
||||||
|
if [ "$1" != "" ] ; then
|
||||||
|
release_list="$1"
|
||||||
|
fi
|
||||||
|
|
||||||
|
#################################################"
|
||||||
|
# extras
|
||||||
|
|
||||||
|
if echo $release_list | grep -w -q extras ; then
|
||||||
|
|
||||||
|
d="quickjs-${version}"
|
||||||
|
name="quickjs-extras-${version}"
|
||||||
|
outdir="/tmp/${d}"
|
||||||
|
|
||||||
|
rm -rf $outdir
|
||||||
|
mkdir -p $outdir $outdir/unicode $outdir/tests
|
||||||
|
|
||||||
|
cp unicode/* $outdir/unicode
|
||||||
|
cp -a tests/bench-v8 $outdir/tests
|
||||||
|
|
||||||
|
( cd /tmp && tar Jcvf /tmp/${name}.tar.xz ${d} )
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
#################################################"
|
||||||
|
# Windows binary release
|
||||||
|
|
||||||
|
if echo $release_list | grep -w -q win_binary ; then
|
||||||
|
|
||||||
|
# win64
|
||||||
|
|
||||||
|
dlldir=/usr/x86_64-w64-mingw32/sys-root/mingw/bin
|
||||||
|
cross_prefix="x86_64-w64-mingw32-"
|
||||||
|
d="quickjs-win-x86_64-${version}"
|
||||||
|
outdir="/tmp/${d}"
|
||||||
|
|
||||||
|
rm -rf $outdir
|
||||||
|
mkdir -p $outdir
|
||||||
|
|
||||||
|
make CONFIG_WIN32=y qjs.exe
|
||||||
|
cp qjs.exe $outdir
|
||||||
|
${cross_prefix}strip $outdir/qjs.exe
|
||||||
|
cp $dlldir/libwinpthread-1.dll $outdir
|
||||||
|
|
||||||
|
( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . )
|
||||||
|
|
||||||
|
make CONFIG_WIN32=y clean
|
||||||
|
|
||||||
|
# win32
|
||||||
|
|
||||||
|
dlldir=/usr/i686-w64-mingw32/sys-root/mingw/bin
|
||||||
|
cross_prefix="i686-w64-mingw32-"
|
||||||
|
d="quickjs-win-i686-${version}"
|
||||||
|
outdir="/tmp/${d}"
|
||||||
|
|
||||||
|
rm -rf $outdir
|
||||||
|
mkdir -p $outdir
|
||||||
|
|
||||||
|
make clean
|
||||||
|
make CONFIG_WIN32=y clean
|
||||||
|
|
||||||
|
make CONFIG_WIN32=y CONFIG_M32=y qjs.exe
|
||||||
|
cp qjs.exe $outdir
|
||||||
|
${cross_prefix}strip $outdir/qjs.exe
|
||||||
|
cp $dlldir/libwinpthread-1.dll $outdir
|
||||||
|
|
||||||
|
( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . )
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
#################################################"
|
||||||
|
# Linux binary release
|
||||||
|
|
||||||
|
if echo $release_list | grep -w -q binary ; then
|
||||||
|
|
||||||
|
make clean
|
||||||
|
make CONFIG_WIN32=y clean
|
||||||
|
make -j4 qjs run-test262
|
||||||
|
make -j4 CONFIG_M32=y qjs32 run-test262-32
|
||||||
|
strip qjs run-test262 qjs32 run-test262-32
|
||||||
|
|
||||||
|
d="quickjs-linux-x86_64-${version}"
|
||||||
|
outdir="/tmp/${d}"
|
||||||
|
|
||||||
|
rm -rf $outdir
|
||||||
|
mkdir -p $outdir
|
||||||
|
|
||||||
|
cp qjs run-test262 $outdir
|
||||||
|
|
||||||
|
( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . )
|
||||||
|
|
||||||
|
d="quickjs-linux-i686-${version}"
|
||||||
|
outdir="/tmp/${d}"
|
||||||
|
|
||||||
|
rm -rf $outdir
|
||||||
|
mkdir -p $outdir
|
||||||
|
|
||||||
|
cp qjs32 $outdir/qjs
|
||||||
|
cp run-test262-32 $outdir/run-test262
|
||||||
|
|
||||||
|
( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . )
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
#################################################"
|
||||||
|
# quickjs
|
||||||
|
|
||||||
|
if echo $release_list | grep -w -q quickjs ; then
|
||||||
|
|
||||||
|
make build_doc
|
||||||
|
|
||||||
|
d="quickjs-${version}"
|
||||||
|
outdir="/tmp/${d}"
|
||||||
|
|
||||||
|
rm -rf $outdir
|
||||||
|
mkdir -p $outdir $outdir/doc $outdir/tests $outdir/examples
|
||||||
|
|
||||||
|
cp Makefile VERSION TODO Changelog readme.txt LICENSE \
|
||||||
|
release.sh unicode_download.sh \
|
||||||
|
qjs.c qjsc.c qjscalc.js repl.js \
|
||||||
|
quickjs.c quickjs.h quickjs-atom.h \
|
||||||
|
quickjs-libc.c quickjs-libc.h quickjs-opcode.h \
|
||||||
|
cutils.c cutils.h list.h \
|
||||||
|
libregexp.c libregexp.h libregexp-opcode.h \
|
||||||
|
libunicode.c libunicode.h libunicode-table.h \
|
||||||
|
libbf.c libbf.h \
|
||||||
|
unicode_gen.c unicode_gen_def.h \
|
||||||
|
run-test262.c test262o.conf test262.conf \
|
||||||
|
test262o_errors.txt test262_errors.txt \
|
||||||
|
$outdir
|
||||||
|
|
||||||
|
cp tests/*.js tests/*.patch tests/bjson.c $outdir/tests
|
||||||
|
|
||||||
|
cp examples/*.js examples/*.c $outdir/examples
|
||||||
|
|
||||||
|
cp doc/quickjs.texi doc/quickjs.pdf doc/quickjs.html \
|
||||||
|
doc/jsbignum.texi doc/jsbignum.html doc/jsbignum.pdf \
|
||||||
|
$outdir/doc
|
||||||
|
|
||||||
|
( cd /tmp && tar Jcvf /tmp/${d}.tar.xz ${d} )
|
||||||
|
|
||||||
|
fi
|
964
run-test262.c
964
run-test262.c
File diff suppressed because it is too large
Load diff
129
standalone.js
129
standalone.js
|
@ -1,129 +0,0 @@
|
||||||
import * as std from "qjs:std";
|
|
||||||
import * as os from "qjs:os";
|
|
||||||
import * as bjson from "qjs:bjson";
|
|
||||||
|
|
||||||
// See quickjs.h
|
|
||||||
const JS_READ_OBJ_BYTECODE = 1 << 0;
|
|
||||||
const JS_READ_OBJ_REFERENCE = 1 << 3;
|
|
||||||
const JS_WRITE_OBJ_BYTECODE = 1 << 0;
|
|
||||||
const JS_WRITE_OBJ_REFERENCE = 1 << 3;
|
|
||||||
const JS_WRITE_OBJ_STRIP_SOURCE = 1 << 4;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Trailer for standalone binaries. When some code gets bundled with the qjs
|
|
||||||
* executable we add a 12 byte trailer. The first 8 bytes are the magic
|
|
||||||
* string that helps us understand this is a standalone binary, and the
|
|
||||||
* remaining 4 are the offset (from the beginning of the binary) where the
|
|
||||||
* bundled data is located.
|
|
||||||
*
|
|
||||||
* The offset is stored as a 32bit little-endian number.
|
|
||||||
*/
|
|
||||||
const Trailer = {
|
|
||||||
Magic: 'quickjs2',
|
|
||||||
MagicSize: 8,
|
|
||||||
DataSize: 4,
|
|
||||||
Size: 12
|
|
||||||
};
|
|
||||||
|
|
||||||
function encodeAscii(txt) {
|
|
||||||
return new Uint8Array(txt.split('').map(c => c.charCodeAt(0)));
|
|
||||||
}
|
|
||||||
|
|
||||||
function decodeAscii(buf) {
|
|
||||||
return Array.from(buf).map(c => String.fromCharCode(c)).join('')
|
|
||||||
}
|
|
||||||
|
|
||||||
export function compileStandalone(inFile, outFile, targetExe) {
|
|
||||||
// Step 1: compile the source file to bytecode
|
|
||||||
const js = std.loadFile(inFile);
|
|
||||||
|
|
||||||
if (!js) {
|
|
||||||
throw new Error(`failed to open ${inFile}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const code = std.evalScript(js, {
|
|
||||||
compile_only: true,
|
|
||||||
compile_module: true
|
|
||||||
});
|
|
||||||
const bytecode = new Uint8Array(bjson.write(code, JS_WRITE_OBJ_BYTECODE | JS_WRITE_OBJ_REFERENCE | JS_WRITE_OBJ_STRIP_SOURCE));
|
|
||||||
|
|
||||||
// Step 2: copy the bytecode to the end of the executable and add a marker.
|
|
||||||
const exeFileName = targetExe ?? globalThis.argv0;
|
|
||||||
const exe = std.loadFile(exeFileName, { binary: true });
|
|
||||||
|
|
||||||
if (!exe) {
|
|
||||||
throw new Error(`failed to open executable: ${exeFileName}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const exeSize = exe.length;
|
|
||||||
const newBuffer = exe.buffer.transfer(exeSize + bytecode.length + Trailer.Size);
|
|
||||||
const newExe = new Uint8Array(newBuffer);
|
|
||||||
|
|
||||||
newExe.set(bytecode, exeSize);
|
|
||||||
newExe.set(encodeAscii(Trailer.Magic), exeSize + bytecode.length);
|
|
||||||
|
|
||||||
const dw = new DataView(newBuffer, exeSize + bytecode.length + Trailer.MagicSize, Trailer.DataSize);
|
|
||||||
|
|
||||||
dw.setUint32(0, exeSize, true /* little-endian */);
|
|
||||||
|
|
||||||
// We use os.open() so we can set the permissions mask.
|
|
||||||
const newFd = os.open(outFile, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o755);
|
|
||||||
|
|
||||||
if (newFd < 0) {
|
|
||||||
throw new Error(`failed to create ${outFile}`);
|
|
||||||
}
|
|
||||||
if (os.write(newFd, newBuffer, 0, newBuffer.byteLength) < 0) {
|
|
||||||
os.close(newFd);
|
|
||||||
throw new Error(`failed to write to output file`);
|
|
||||||
}
|
|
||||||
os.close(newFd);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function runStandalone() {
|
|
||||||
const file = globalThis.argv0;
|
|
||||||
const exe = std.open(file, 'rb');
|
|
||||||
|
|
||||||
if (!exe) {
|
|
||||||
throw new Error(`failed to open executable: ${file}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
let r = exe.seek(-Trailer.Size, std.SEEK_END);
|
|
||||||
if (r < 0) {
|
|
||||||
throw new Error(`seek error: ${-r}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const trailer = new Uint8Array(Trailer.Size);
|
|
||||||
|
|
||||||
exe.read(trailer.buffer, 0, Trailer.Size);
|
|
||||||
|
|
||||||
const magic = new Uint8Array(trailer.buffer, 0, Trailer.MagicSize);
|
|
||||||
|
|
||||||
// Shouldn't happen since qjs.c checks for it.
|
|
||||||
if (decodeAscii(magic) !== Trailer.Magic) {
|
|
||||||
exe.close();
|
|
||||||
throw new Error('corrupted binary, magic mismatch');
|
|
||||||
}
|
|
||||||
|
|
||||||
const dw = new DataView(trailer.buffer, Trailer.MagicSize, Trailer.DataSize);
|
|
||||||
const offset = dw.getUint32(0, true /* little-endian */);
|
|
||||||
const bytecode = new Uint8Array(offset - Trailer.Size);
|
|
||||||
|
|
||||||
r = exe.seek(offset, std.SEEK_SET);
|
|
||||||
if (r < 0) {
|
|
||||||
exe.close();
|
|
||||||
throw new Error(`seek error: ${-r}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
exe.read(bytecode.buffer, 0, bytecode.length);
|
|
||||||
if (exe.error()) {
|
|
||||||
exe.close();
|
|
||||||
throw new Error('read error');
|
|
||||||
}
|
|
||||||
exe.close();
|
|
||||||
|
|
||||||
const code = bjson.read(bytecode.buffer, 0, bytecode.length, JS_READ_OBJ_BYTECODE | JS_READ_OBJ_REFERENCE);
|
|
||||||
|
|
||||||
return std.evalScript(code, {
|
|
||||||
eval_module: true
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -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
|
|
198
test262.conf
198
test262.conf
|
@ -1,6 +1,9 @@
|
||||||
[config]
|
[config]
|
||||||
# general settings for test262 ES6 version
|
# general settings for test262 ES6 version
|
||||||
|
|
||||||
|
# framework style: old, new
|
||||||
|
style=new
|
||||||
|
|
||||||
# handle tests tagged as [noStrict]: yes, no, skip
|
# handle tests tagged as [noStrict]: yes, no, skip
|
||||||
nostrict=yes
|
nostrict=yes
|
||||||
|
|
||||||
|
@ -34,6 +37,9 @@ errorfile=test262_errors.txt
|
||||||
# exclude tests enumerated in this file (see also [exclude] section)
|
# exclude tests enumerated in this file (see also [exclude] section)
|
||||||
#excludefile=test262_exclude.txt
|
#excludefile=test262_exclude.txt
|
||||||
|
|
||||||
|
# report test results to this file
|
||||||
|
reportfile=test262_report.txt
|
||||||
|
|
||||||
# enumerate tests from this directory
|
# enumerate tests from this directory
|
||||||
testdir=test262/test
|
testdir=test262/test
|
||||||
|
|
||||||
|
@ -55,16 +61,15 @@ Array.fromAsync=skip
|
||||||
Array.prototype.at
|
Array.prototype.at
|
||||||
Array.prototype.flat
|
Array.prototype.flat
|
||||||
Array.prototype.flatMap
|
Array.prototype.flatMap
|
||||||
|
Array.prototype.flatten
|
||||||
Array.prototype.includes
|
Array.prototype.includes
|
||||||
Array.prototype.values
|
Array.prototype.values
|
||||||
ArrayBuffer
|
ArrayBuffer
|
||||||
arraybuffer-transfer
|
arraybuffer-transfer=skip
|
||||||
arrow-function
|
arrow-function
|
||||||
async-functions
|
async-functions
|
||||||
async-iteration
|
async-iteration
|
||||||
# atomics are broken in recent versions of tcc
|
Atomics
|
||||||
Atomics=!tcc
|
|
||||||
Atomics.pause=!tcc
|
|
||||||
Atomics.waitAsync=skip
|
Atomics.waitAsync=skip
|
||||||
BigInt
|
BigInt
|
||||||
caller
|
caller
|
||||||
|
@ -78,6 +83,7 @@ class-static-block
|
||||||
class-static-fields-private
|
class-static-fields-private
|
||||||
class-static-fields-public
|
class-static-fields-public
|
||||||
class-static-methods-private
|
class-static-methods-private
|
||||||
|
cleanupSome=skip
|
||||||
coalesce-expression
|
coalesce-expression
|
||||||
computed-property-names
|
computed-property-names
|
||||||
const
|
const
|
||||||
|
@ -97,13 +103,11 @@ destructuring-assignment
|
||||||
destructuring-binding
|
destructuring-binding
|
||||||
dynamic-import
|
dynamic-import
|
||||||
error-cause
|
error-cause
|
||||||
Error.isError
|
|
||||||
explicit-resource-management=skip
|
|
||||||
exponentiation
|
exponentiation
|
||||||
export-star-as-namespace-from-module
|
export-star-as-namespace-from-module
|
||||||
FinalizationRegistry
|
FinalizationGroup=skip
|
||||||
FinalizationRegistry.prototype.cleanupSome=skip
|
FinalizationRegistry.prototype.cleanupSome=skip
|
||||||
Float16Array
|
FinalizationRegistry=skip
|
||||||
Float32Array
|
Float32Array
|
||||||
Float64Array
|
Float64Array
|
||||||
for-in-order
|
for-in-order
|
||||||
|
@ -118,25 +122,8 @@ import.meta
|
||||||
Int16Array
|
Int16Array
|
||||||
Int32Array
|
Int32Array
|
||||||
Int8Array
|
Int8Array
|
||||||
Intl-enumeration=skip
|
|
||||||
intl-normative-optional=skip
|
|
||||||
Intl.DateTimeFormat-datetimestyle=skip
|
|
||||||
Intl.DateTimeFormat-dayPeriod=skip
|
|
||||||
Intl.DateTimeFormat-extend-timezonename=skip
|
|
||||||
Intl.DateTimeFormat-formatRange=skip
|
|
||||||
Intl.DateTimeFormat-fractionalSecondDigits=skip
|
|
||||||
Intl.DisplayNames-v2=skip
|
|
||||||
Intl.DisplayNames=skip
|
|
||||||
Intl.DurationFormat=skip
|
|
||||||
Intl.ListFormat=skip
|
|
||||||
Intl.Locale-info=skip
|
|
||||||
Intl.Locale=skip
|
|
||||||
Intl.NumberFormat-unified=skip
|
|
||||||
Intl.NumberFormat-v3=skip
|
|
||||||
Intl.RelativeTimeFormat=skip
|
|
||||||
Intl.Segmenter=skip
|
|
||||||
IsHTMLDDA
|
IsHTMLDDA
|
||||||
iterator-helpers
|
iterator-helpers=skip
|
||||||
json-modules=skip
|
json-modules=skip
|
||||||
json-parse-with-source=skip
|
json-parse-with-source=skip
|
||||||
json-superset
|
json-superset
|
||||||
|
@ -144,7 +131,6 @@ legacy-regexp=skip
|
||||||
let
|
let
|
||||||
logical-assignment-operators
|
logical-assignment-operators
|
||||||
Map
|
Map
|
||||||
Math.sumPrecise
|
|
||||||
new.target
|
new.target
|
||||||
numeric-separator-literal
|
numeric-separator-literal
|
||||||
object-rest
|
object-rest
|
||||||
|
@ -155,7 +141,6 @@ Object.is
|
||||||
optional-catch-binding
|
optional-catch-binding
|
||||||
optional-chaining
|
optional-chaining
|
||||||
Promise
|
Promise
|
||||||
promise-try
|
|
||||||
promise-with-resolvers
|
promise-with-resolvers
|
||||||
Promise.allSettled
|
Promise.allSettled
|
||||||
Promise.any
|
Promise.any
|
||||||
|
@ -170,19 +155,15 @@ regexp-dotall
|
||||||
regexp-duplicate-named-groups=skip
|
regexp-duplicate-named-groups=skip
|
||||||
regexp-lookbehind
|
regexp-lookbehind
|
||||||
regexp-match-indices
|
regexp-match-indices
|
||||||
regexp-modifiers=skip
|
|
||||||
regexp-named-groups
|
regexp-named-groups
|
||||||
regexp-unicode-property-escapes
|
regexp-unicode-property-escapes
|
||||||
regexp-v-flag
|
regexp-v-flag=skip
|
||||||
RegExp.escape
|
resizable-arraybuffer=skip
|
||||||
resizable-arraybuffer
|
|
||||||
rest-parameters
|
rest-parameters
|
||||||
Set
|
Set
|
||||||
set-methods
|
set-methods=skip
|
||||||
ShadowRealm=skip
|
ShadowRealm=skip
|
||||||
SharedArrayBuffer
|
SharedArrayBuffer
|
||||||
source-phase-imports-module-source=skip
|
|
||||||
source-phase-imports=skip
|
|
||||||
string-trimming
|
string-trimming
|
||||||
String.fromCodePoint
|
String.fromCodePoint
|
||||||
String.prototype.at
|
String.prototype.at
|
||||||
|
@ -210,7 +191,7 @@ Symbol.split
|
||||||
Symbol.toPrimitive
|
Symbol.toPrimitive
|
||||||
Symbol.toStringTag
|
Symbol.toStringTag
|
||||||
Symbol.unscopables
|
Symbol.unscopables
|
||||||
symbols-as-weakmap-keys
|
symbols-as-weakmap-keys=skip
|
||||||
tail-call-optimization=skip
|
tail-call-optimization=skip
|
||||||
template
|
template
|
||||||
Temporal=skip
|
Temporal=skip
|
||||||
|
@ -221,10 +202,9 @@ u180e
|
||||||
Uint16Array
|
Uint16Array
|
||||||
Uint32Array
|
Uint32Array
|
||||||
Uint8Array
|
Uint8Array
|
||||||
uint8array-base64=skip
|
|
||||||
Uint8ClampedArray
|
Uint8ClampedArray
|
||||||
WeakMap
|
WeakMap
|
||||||
WeakRef
|
WeakRef=skip
|
||||||
WeakSet
|
WeakSet
|
||||||
well-formed-json-stringify
|
well-formed-json-stringify
|
||||||
|
|
||||||
|
@ -243,147 +223,5 @@ test262/test/built-ins/ThrowTypeError/unique-per-realm-function-proto.js
|
||||||
#test262/test/built-ins/RegExp/CharacterClassEscapes/
|
#test262/test/built-ins/RegExp/CharacterClassEscapes/
|
||||||
#test262/test/built-ins/RegExp/property-escapes/
|
#test262/test/built-ins/RegExp/property-escapes/
|
||||||
|
|
||||||
# in progress regexp-v-flag support, see https://github.com/quickjs-ng/quickjs/issues/228
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/Basic_Emoji-negative-CharacterClass.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/Basic_Emoji-negative-P.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/Basic_Emoji-negative-u.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/Basic_Emoji.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/Emoji_Keycap_Sequence-negative-CharacterClass.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/Emoji_Keycap_Sequence-negative-P.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/Emoji_Keycap_Sequence-negative-u.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/Emoji_Keycap_Sequence.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji-negative-CharacterClass.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji-negative-P.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji-negative-u.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Flag_Sequence-negative-CharacterClass.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Flag_Sequence-negative-P.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Flag_Sequence-negative-u.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Flag_Sequence.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Modifier_Sequence-negative-CharacterClass.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Modifier_Sequence-negative-P.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Modifier_Sequence-negative-u.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Modifier_Sequence.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Tag_Sequence-negative-CharacterClass.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Tag_Sequence-negative-P.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Tag_Sequence-negative-u.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_Tag_Sequence.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_ZWJ_Sequence-negative-CharacterClass.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_ZWJ_Sequence-negative-P.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_ZWJ_Sequence-negative-u.js
|
|
||||||
test262/test/built-ins/RegExp/property-escapes/generated/strings/RGI_Emoji_ZWJ_Sequence.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-difference-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-difference-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-difference-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-difference-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-difference-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-difference-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-difference-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-difference-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-difference-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-difference-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-difference-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-difference-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-intersection-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-intersection-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-intersection-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-intersection-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-intersection-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-intersection-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-union-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-union-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-union-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-union-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-union-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-escape-union-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-intersection-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-intersection-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-intersection-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-intersection-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-intersection-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-intersection-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-union-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-union-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-union-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-union-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-union-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-class-union-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-difference-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-difference-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-difference-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-difference-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-difference-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-difference-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-intersection-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-intersection-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-intersection-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-intersection-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-intersection-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-intersection-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-difference-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-difference-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-difference-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-difference-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-difference-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-difference-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-intersection-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-intersection-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-intersection-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-intersection-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-intersection-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-intersection-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-union-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-union-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-union-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-union-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-union-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-property-escape-union-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-union-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-union-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-union-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-union-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-union-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/character-union-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-difference-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-difference-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-difference-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-difference-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-difference-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-difference-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-intersection-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-intersection-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-intersection-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-intersection-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-intersection-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-intersection-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-union-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-union-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-union-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-union-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-union-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/property-of-strings-escape-union-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/rgi-emoji-13.1.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/rgi-emoji-14.0.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/rgi-emoji-15.0.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/rgi-emoji-15.1.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-difference-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-difference-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-difference-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-difference-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-difference-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-difference-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-intersection-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-intersection-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-intersection-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-intersection-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-intersection-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-intersection-string-literal.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-union-character-class-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-union-character-class.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-union-character-property-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-union-character.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-union-property-of-strings-escape.js
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/string-literal-union-string-literal.js
|
|
||||||
|
|
||||||
[tests]
|
[tests]
|
||||||
# list test files or use config.testdir
|
# list test files or use config.testdir
|
||||||
|
|
|
@ -1,84 +1,8 @@
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/iterator-result-poisoned-wrapper.js:64: TypeError: $DONE() not called
|
test262/test/annexB/language/eval-code/direct/script-decl-lex-collision-in-sloppy-mode.js:13: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/iterator-result-poisoned-wrapper.js:64: strict mode: TypeError: $DONE() not called
|
test262/test/language/expressions/assignment/target-member-computed-reference-null.js:32: Test262Error: Expected a DummyError but got a TypeError
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/next-result-poisoned-wrapper.js:69: TypeError: $DONE() not called
|
test262/test/language/expressions/assignment/target-member-computed-reference-null.js:32: strict mode: Test262Error: Expected a DummyError but got a TypeError
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/next-result-poisoned-wrapper.js:69: strict mode: TypeError: $DONE() not called
|
test262/test/language/expressions/assignment/target-member-computed-reference-undefined.js:32: Test262Error: Expected a DummyError but got a TypeError
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/yield-iterator-next-rejected-promise-close.js:59: TypeError: $DONE() not called
|
test262/test/language/expressions/assignment/target-member-computed-reference-undefined.js:32: strict mode: Test262Error: Expected a DummyError but got a TypeError
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/yield-iterator-next-rejected-promise-close.js:59: strict mode: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/yield-next-rejected-promise-close.js:64: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/next/yield-next-rejected-promise-close.js:64: strict mode: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/iterator-result-rejected-promise-close.js:74: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/iterator-result-rejected-promise-close.js:74: strict mode: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-result-poisoned-wrapper.js:81: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-result-poisoned-wrapper.js:81: strict mode: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-get-return-undefined.js:64: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-get-return-undefined.js:64: strict mode: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-poisoned-return.js:68: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-poisoned-return.js:68: strict mode: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-not-object.js:72: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-not-object.js:72: strict mode: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-object.js:66: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/AsyncFromSyncIteratorPrototype/throw/throw-undefined-return-object.js:66: strict mode: TypeError: $DONE() not called
|
|
||||||
test262/test/built-ins/Iterator/prototype/constructor/prop-desc.js:10: Test262Error: Expected SameValue(«"undefined"», «"function"») to be true
|
|
||||||
test262/test/built-ins/Iterator/prototype/constructor/prop-desc.js:10: strict mode: Test262Error: Expected SameValue(«"undefined"», «"function"») to be true
|
|
||||||
test262/test/built-ins/Iterator/prototype/constructor/weird-setter.js:23: TypeError: cannot read property 'call' of undefined
|
|
||||||
test262/test/built-ins/Iterator/prototype/constructor/weird-setter.js:23: strict mode: TypeError: cannot read property 'call' of undefined
|
|
||||||
test262/test/built-ins/Object/defineProperties/typedarray-backed-by-resizable-buffer.js:20: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
|
|
||||||
test262/test/built-ins/Object/defineProperties/typedarray-backed-by-resizable-buffer.js:20: strict mode: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
|
|
||||||
test262/test/built-ins/Object/defineProperty/coerced-P-grow.js:45: TypeError: out-of-bound index in typed array
|
|
||||||
test262/test/built-ins/Object/defineProperty/coerced-P-grow.js:45: strict mode: TypeError: out-of-bound index in typed array
|
|
||||||
test262/test/built-ins/Object/defineProperty/coerced-P-shrink.js:16: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
|
|
||||||
test262/test/built-ins/Object/defineProperty/coerced-P-shrink.js:16: strict mode: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
|
|
||||||
test262/test/built-ins/Object/defineProperty/typedarray-backed-by-resizable-buffer.js:18: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
|
|
||||||
test262/test/built-ins/Object/defineProperty/typedarray-backed-by-resizable-buffer.js:18: strict mode: Test262Error: Expected a TypeError to be thrown but no exception was thrown at all
|
|
||||||
test262/test/built-ins/RegExp/prototype/exec/regexp-builtin-exec-v-u-flag.js:45: Test262Error: Actual argument shouldn't be nullish. Unicode property escapes with v flag
|
|
||||||
test262/test/built-ins/RegExp/prototype/exec/regexp-builtin-exec-v-u-flag.js:45: strict mode: Test262Error: Actual argument shouldn't be nullish. Unicode property escapes with v flag
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/rgi-emoji-16.0.js:16: Test262Error: `\p{RGI_Emoji}` should match 🇨🇶 (U+01F1E8 U+01F1F6)
|
|
||||||
test262/test/built-ins/RegExp/unicodeSets/generated/rgi-emoji-16.0.js:16: strict mode: Test262Error: `\p{RGI_Emoji}` should match 🇨🇶 (U+01F1E8 U+01F1F6)
|
|
||||||
test262/test/built-ins/String/prototype/match/regexp-prototype-match-v-u-flag.js:10: Test262Error: Actual argument shouldn't be nullish. Unicode property escapes with v flag
|
|
||||||
test262/test/built-ins/String/prototype/match/regexp-prototype-match-v-u-flag.js:10: strict mode: Test262Error: Actual argument shouldn't be nullish. Unicode property escapes with v flag
|
|
||||||
test262/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-v-u-flag.js:73: Test262Error: Actual [] and expected [𠮷, 𠮷, 𠮷, 0, 3, 6] should have the same contents.
|
|
||||||
test262/test/built-ins/String/prototype/matchAll/regexp-prototype-matchAll-v-u-flag.js:73: strict mode: Test262Error: Actual [] and expected [𠮷, 𠮷, 𠮷, 0, 3, 6] should have the same contents.
|
|
||||||
test262/test/built-ins/String/prototype/replace/regexp-prototype-replace-v-u-flag.js:9: Test262Error: Unicode property escapes with v flag Expected SameValue(«"𠮷a𠮷b𠮷"», «"XaXbX"») to be true
|
|
||||||
test262/test/built-ins/String/prototype/replace/regexp-prototype-replace-v-u-flag.js:9: strict mode: Test262Error: Unicode property escapes with v flag Expected SameValue(«"𠮷a𠮷b𠮷"», «"XaXbX"») to be true
|
|
||||||
test262/test/built-ins/String/prototype/search/regexp-prototype-search-v-flag.js:9: Test262Error: Unicode property escapes with v flag Expected SameValue(«-1», «0») to be true
|
|
||||||
test262/test/built-ins/String/prototype/search/regexp-prototype-search-v-flag.js:9: strict mode: Test262Error: Unicode property escapes with v flag Expected SameValue(«-1», «0») to be true
|
|
||||||
test262/test/built-ins/String/prototype/search/regexp-prototype-search-v-u-flag.js:9: Test262Error: Unicode property escapes with v flag Expected SameValue(«-1», «0») to be true
|
|
||||||
test262/test/built-ins/String/prototype/search/regexp-prototype-search-v-u-flag.js:9: strict mode: Test262Error: Unicode property escapes with v flag Expected SameValue(«-1», «0») to be true
|
|
||||||
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-prototype-chain-set.js:35: Test262Error: value should not be coerced Expected SameValue(«22», «0») to be true
|
|
||||||
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-prototype-chain-set.js:35: strict mode: Test262Error: value should not be coerced Expected SameValue(«22», «0») to be true
|
|
||||||
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-reflect-set.js:35: Test262Error: value should not be coerced Expected SameValue(«32», «0») to be true
|
|
||||||
test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-canonical-invalid-index-reflect-set.js:35: strict mode: Test262Error: value should not be coerced Expected SameValue(«32», «0») to be true
|
|
||||||
test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-prototype-chain-set.js:35: Test262Error: value should not be coerced Expected SameValue(«110», «0») to be true
|
|
||||||
test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-prototype-chain-set.js:35: strict mode: Test262Error: value should not be coerced Expected SameValue(«110», «0») to be true
|
|
||||||
test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-reflect-set.js:35: Test262Error: value should not be coerced Expected SameValue(«160», «0») to be true
|
|
||||||
test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-canonical-invalid-index-reflect-set.js:35: strict mode: Test262Error: value should not be coerced Expected SameValue(«160», «0») to be true
|
|
||||||
test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-object.js:19: Test262Error: valueOf is not called Expected SameValue(«1», «0») to be true
|
|
||||||
test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-object.js:19: strict mode: Test262Error: valueOf is not called Expected SameValue(«1», «0») to be true
|
|
||||||
test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-typed-array.js:19: Test262Error: valueOf is not called Expected SameValue(«1», «0») to be true
|
|
||||||
test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds-receiver-is-not-typed-array.js:19: strict mode: Test262Error: valueOf is not called Expected SameValue(«1», «0») to be true
|
|
||||||
test262/test/language/destructuring/binding/keyed-destructuring-property-reference-target-evaluation-order-with-bindings.js:73: Test262Error: Actual [binding::source, binding::sourceKey, sourceKey, get source, binding::defaultValue, binding::varTarget] and expected [binding::source, binding::sourceKey, sourceKey, binding::varTarget, get source, binding::defaultValue] should have the same contents.
|
|
||||||
test262/test/language/expressions/assignment/destructuring/iterator-destructuring-property-reference-target-evaluation-order.js:42: Test262Error: Actual [source, iterator, target, target-key, target-key-tostring, iterator-step, iterator-done, set] and expected [source, iterator, target, target-key, iterator-step, iterator-done, target-key-tostring, set] should have the same contents.
|
|
||||||
test262/test/language/expressions/assignment/destructuring/iterator-destructuring-property-reference-target-evaluation-order.js:42: strict mode: Test262Error: Actual [source, iterator, target, target-key, target-key-tostring, iterator-step, iterator-done, set] and expected [source, iterator, target, target-key, iterator-step, iterator-done, target-key-tostring, set] should have the same contents.
|
|
||||||
test262/test/language/expressions/assignment/destructuring/keyed-destructuring-property-reference-target-evaluation-order-with-bindings.js:37: Test262Error: Actual [binding::source, binding::sourceKey, sourceKey, binding::target, binding::targetKey, targetKey, get source, binding::defaultValue, set target] and expected [binding::source, binding::sourceKey, sourceKey, binding::target, binding::targetKey, get source, binding::defaultValue, targetKey, set target] should have the same contents.
|
|
||||||
test262/test/language/expressions/assignment/destructuring/keyed-destructuring-property-reference-target-evaluation-order.js:32: Test262Error: Actual [source, source-key, source-key-tostring, target, target-key, target-key-tostring, get, set] and expected [source, source-key, source-key-tostring, target, target-key, get, target-key-tostring, set] should have the same contents.
|
|
||||||
test262/test/language/expressions/assignment/destructuring/keyed-destructuring-property-reference-target-evaluation-order.js:32: strict mode: Test262Error: Actual [source, source-key, source-key-tostring, target, target-key, target-key-tostring, get, set] and expected [source, source-key, source-key-tostring, target, target-key, get, target-key-tostring, set] should have the same contents.
|
|
||||||
test262/test/language/expressions/assignment/target-member-computed-reference.js:22: Test262Error: Expected a DummyError but got a Test262Error
|
|
||||||
test262/test/language/expressions/assignment/target-member-computed-reference.js:22: strict mode: Test262Error: Expected a DummyError but got a Test262Error
|
|
||||||
test262/test/language/expressions/assignment/target-super-computed-reference.js:20: Test262Error: Expected a DummyError but got a Test262Error
|
|
||||||
test262/test/language/expressions/assignment/target-super-computed-reference.js:20: strict mode: Test262Error: Expected a DummyError but got a Test262Error
|
|
||||||
test262/test/language/expressions/in/private-field-invalid-assignment-target.js:23: unexpected error type: Test262: This statement should not be evaluated.
|
test262/test/language/expressions/in/private-field-invalid-assignment-target.js:23: unexpected error type: Test262: This statement should not be evaluated.
|
||||||
test262/test/language/expressions/in/private-field-invalid-assignment-target.js:23: strict mode: unexpected error type: Test262: This statement should not be evaluated.
|
test262/test/language/expressions/in/private-field-invalid-assignment-target.js:23: strict mode: unexpected error type: Test262: This statement should not be evaluated.
|
||||||
test262/test/language/expressions/object/computed-property-name-topropertykey-before-value-evaluation.js:31: Test262Error: Expected SameValue(«"bad"», «"ok"») to be true
|
test262/test/language/global-code/script-decl-lex-var-declared-via-eval-sloppy.js:13: Test262Error: variable Expected a SyntaxError to be thrown but no exception was thrown at all
|
||||||
test262/test/language/expressions/object/computed-property-name-topropertykey-before-value-evaluation.js:31: strict mode: Test262Error: Expected SameValue(«"bad"», «"ok"») to be true
|
|
||||||
test262/test/language/module-code/top-level-await/async-module-does-not-block-sibling-modules.js:13: SyntaxError: Could not find export 'check' in module 'test262/test/language/module-code/top-level-await/async-module-sync_FIXTURE.js'
|
|
||||||
test262/test/language/module-code/top-level-await/module-graphs-does-not-hang.js:10: TypeError: $DONE() not called
|
|
||||||
test262/test/language/statements/class/elements/syntax/valid/grammar-field-named-get-followed-by-generator-asi.js:40: SyntaxError: invalid property name
|
|
||||||
test262/test/language/statements/class/elements/syntax/valid/grammar-field-named-get-followed-by-generator-asi.js:40: strict mode: SyntaxError: invalid property name
|
|
||||||
test262/test/language/statements/class/elements/syntax/valid/grammar-field-named-set-followed-by-generator-asi.js:40: SyntaxError: invalid property name
|
|
||||||
test262/test/language/statements/class/elements/syntax/valid/grammar-field-named-set-followed-by-generator-asi.js:40: strict mode: SyntaxError: invalid property name
|
|
||||||
test262/test/language/statements/with/get-binding-value-call-with-proxy-env.js:39: Test262Error: Actual [has:Object, get:Symbol(Symbol.unscopables), get:Object] and expected [has:Object, get:Symbol(Symbol.unscopables), has:Object, get:Object] should have the same contents.
|
|
||||||
test262/test/language/statements/with/get-binding-value-idref-with-proxy-env.js:39: Test262Error: Actual [has:Object, get:Symbol(Symbol.unscopables), get:Object] and expected [has:Object, get:Symbol(Symbol.unscopables), has:Object, get:Object] should have the same contents.
|
|
||||||
test262/test/language/statements/with/get-mutable-binding-binding-deleted-in-get-unscopables-strict-mode.js:21: Test262Error: Expected a ReferenceError to be thrown but no exception was thrown at all
|
|
||||||
test262/test/language/statements/with/set-mutable-binding-binding-deleted-with-typed-array-in-proto-chain.js:20: Test262Error: Expected SameValue(«[object Object]», «undefined») to be true
|
|
||||||
test262/test/language/statements/with/set-mutable-binding-idref-compound-assign-with-proxy-env.js:58: Test262Error: Actual [has:p, get:Symbol(Symbol.unscopables), get:p, set:p, getOwnPropertyDescriptor:p, defineProperty:p] and expected [has:p, get:Symbol(Symbol.unscopables), has:p, get:p, has:p, set:p, getOwnPropertyDescriptor:p, defineProperty:p] should have the same contents.
|
|
||||||
test262/test/language/statements/with/set-mutable-binding-idref-with-proxy-env.js:50: Test262Error: Actual [has:p, get:Symbol(Symbol.unscopables), set:p, getOwnPropertyDescriptor:p, defineProperty:p] and expected [has:p, get:Symbol(Symbol.unscopables), has:p, set:p, getOwnPropertyDescriptor:p, defineProperty:p] should have the same contents.
|
|
||||||
|
|
413
test262o.conf
Normal file
413
test262o.conf
Normal file
|
@ -0,0 +1,413 @@
|
||||||
|
[config]
|
||||||
|
# general settings for test262 ES5 version
|
||||||
|
|
||||||
|
# framework style: old, new
|
||||||
|
style=old
|
||||||
|
|
||||||
|
# handle tests tagged as @noStrict: yes, no, skip
|
||||||
|
nostrict=yes
|
||||||
|
|
||||||
|
# handle tests tagged as @strictOnly: yes, no, skip
|
||||||
|
strict=yes
|
||||||
|
|
||||||
|
# test mode: default, default-nostrict, default-strict, strict, nostrict, both, all
|
||||||
|
mode=default
|
||||||
|
|
||||||
|
# output error messages: yes, no
|
||||||
|
verbose=yes
|
||||||
|
|
||||||
|
# load harness files this directory
|
||||||
|
harnessdir=test262o/test/harness
|
||||||
|
|
||||||
|
# name of the error file for known errors
|
||||||
|
errorfile=test262o_errors.txt
|
||||||
|
|
||||||
|
# exclude tests enumerated in this file
|
||||||
|
#excludefile=test262o_excluded.txt
|
||||||
|
|
||||||
|
# report test results to this file
|
||||||
|
reportfile=test262o_report.txt
|
||||||
|
|
||||||
|
# enumerate tests from this directory
|
||||||
|
testdir=test262o/test/suite
|
||||||
|
|
||||||
|
[exclude]
|
||||||
|
# list excluded tests and directories here
|
||||||
|
|
||||||
|
# intl not supported
|
||||||
|
test262o/test/suite/intl402/
|
||||||
|
|
||||||
|
# ES6 != ES5: block scoped function definitions allowed in strict mode
|
||||||
|
test262o/test/suite/bestPractice/Sbp_A1_T1.js
|
||||||
|
test262o/test/suite/bestPractice/Sbp_A2_T1.js
|
||||||
|
test262o/test/suite/bestPractice/Sbp_A2_T2.js
|
||||||
|
test262o/test/suite/bestPractice/Sbp_A3_T1.js
|
||||||
|
test262o/test/suite/bestPractice/Sbp_A3_T2.js
|
||||||
|
test262o/test/suite/bestPractice/Sbp_A4_T1.js
|
||||||
|
test262o/test/suite/bestPractice/Sbp_A4_T2.js
|
||||||
|
test262o/test/suite/bestPractice/Sbp_A5_T2.js
|
||||||
|
|
||||||
|
# ES6 != ES5: `y={x};` is shorthand for `y={x:x}`
|
||||||
|
test262o/test/suite/ch12/12.1/S12.1_A4_T2.js
|
||||||
|
test262o/test/suite/ch12/12.6/12.6.4/S12.6.4_A15.js
|
||||||
|
|
||||||
|
# ES6 != ES5: function length property is configurable
|
||||||
|
test262o/test/suite/ch11/11.4/11.4.1/11.4.1-5-a-28-s.js
|
||||||
|
test262o/test/suite/ch13/13.2/13.2-15-1.js
|
||||||
|
test262o/test/suite/ch15/15.1/15.1.2/15.1.2.1/S15.1.2.1_A4.2.js
|
||||||
|
test262o/test/suite/ch15/15.1/15.1.2/15.1.2.2/S15.1.2.2_A9.2.js
|
||||||
|
test262o/test/suite/ch15/15.1/15.1.2/15.1.2.3/S15.1.2.3_A7.2.js
|
||||||
|
test262o/test/suite/ch15/15.1/15.1.2/15.1.2.4/S15.1.2.4_A2.2.js
|
||||||
|
test262o/test/suite/ch15/15.1/15.1.2/15.1.2.5/S15.1.2.5_A2.2.js
|
||||||
|
test262o/test/suite/ch15/15.1/15.1.3/15.1.3.1/S15.1.3.1_A5.2.js
|
||||||
|
test262o/test/suite/ch15/15.1/15.1.3/15.1.3.2/S15.1.3.2_A5.2.js
|
||||||
|
test262o/test/suite/ch15/15.1/15.1.3/15.1.3.3/S15.1.3.3_A5.2.js
|
||||||
|
test262o/test/suite/ch15/15.1/15.1.3/15.1.3.4/S15.1.3.4_A5.2.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-186.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-187.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-191.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-194.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-201.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.4/15.2.4.2/S15.2.4.2_A9.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.4/15.2.4.3/S15.2.4.3_A9.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.4/15.2.4.4/S15.2.4.4_A9.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.4/15.2.4.5/S15.2.4.5_A9.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.4/15.2.4.6/S15.2.4.6_A9.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.4/15.2.4.7/S15.2.4.7_A9.js
|
||||||
|
test262o/test/suite/ch15/15.3/15.3.3/15.3.3.2/15.3.3.2-1.js
|
||||||
|
test262o/test/suite/ch15/15.3/15.3.4/15.3.4.2/S15.3.4.2_A9.js
|
||||||
|
test262o/test/suite/ch15/15.3/15.3.4/15.3.4.3/S15.3.4.3_A9.js
|
||||||
|
test262o/test/suite/ch15/15.3/15.3.4/15.3.4.4/S15.3.4.4_A9.js
|
||||||
|
test262o/test/suite/ch15/15.3/15.3.4/15.3.4.5/15.3.4.5-15-2.js
|
||||||
|
test262o/test/suite/ch15/15.3/15.3.5/S15.3.5.1_A2_T1.js
|
||||||
|
test262o/test/suite/ch15/15.3/15.3.5/S15.3.5.1_A2_T2.js
|
||||||
|
test262o/test/suite/ch15/15.3/15.3.5/S15.3.5.1_A2_T3.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.3/S15.4.3_A2.2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.2/S15.4.4.2_A4.2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.3/S15.4.4.3_A4.2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.4/S15.4.4.4_A4.2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.5/S15.4.4.5_A6.2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.6/S15.4.4.6_A5.2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.7/S15.4.4.7_A6.2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.8/S15.4.4.8_A5.2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.9/S15.4.4.9_A5.2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.10/S15.4.4.10_A5.2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.11/S15.4.4.11_A7.2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.12/S15.4.4.12_A5.2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.13/S15.4.4.13_A5.2.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.4/S15.5.4.4_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.5/S15.5.4.5_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.6/S15.5.4.6_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.7/S15.5.4.7_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.8/S15.5.4.8_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.9/S15.5.4.9_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.10/S15.5.4.10_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.11/S15.5.4.11_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.12/S15.5.4.12_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.13/S15.5.4.13_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.14/S15.5.4.14_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.15/S15.5.4.15_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.16/S15.5.4.16_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.17/S15.5.4.17_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.18/S15.5.4.18_A9.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.19/S15.5.4.19_A9.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.4/15.9.4.2/S15.9.4.2_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.4/15.9.4.3/S15.9.4.3_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.1/S15.9.5.1_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.2/S15.9.5.2_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.3/S15.9.5.3_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.4/S15.9.5.4_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.5/S15.9.5.5_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.6/S15.9.5.6_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.7/S15.9.5.7_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.8/S15.9.5.8_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.9/S15.9.5.9_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.10/S15.9.5.10_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.11/S15.9.5.11_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.12/S15.9.5.12_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.13/S15.9.5.13_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.14/S15.9.5.14_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.15/S15.9.5.15_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.16/S15.9.5.16_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.17/S15.9.5.17_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.18/S15.9.5.18_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.19/S15.9.5.19_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.20/S15.9.5.20_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.21/S15.9.5.21_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.22/S15.9.5.22_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.23/S15.9.5.23_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.24/S15.9.5.24_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.25/S15.9.5.25_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.26/S15.9.5.26_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.27/S15.9.5.27_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.28/S15.9.5.28_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.29/S15.9.5.29_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.30/S15.9.5.30_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.31/S15.9.5.31_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.32/S15.9.5.32_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.33/S15.9.5.33_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.34/S15.9.5.34_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.35/S15.9.5.35_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.36/S15.9.5.36_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.37/S15.9.5.37_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.38/S15.9.5.38_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.39/S15.9.5.39_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.40/S15.9.5.40_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.41/S15.9.5.41_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.42/S15.9.5.42_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.6/15.10.6.2/S15.10.6.2_A9.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.6/15.10.6.3/S15.10.6.3_A9.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.6/15.10.6.4/S15.10.6.4_A9.js
|
||||||
|
|
||||||
|
# ES6 != ES5: object literals may have duplicates
|
||||||
|
test262o/test/suite/ch11/11.1/11.1.5/11.1.5-4-4-a-1-s.js
|
||||||
|
test262o/test/suite/ch11/11.1/11.1.5/11.1.5_4-4-b-1.js
|
||||||
|
test262o/test/suite/ch11/11.1/11.1.5/11.1.5_4-4-b-2.js
|
||||||
|
test262o/test/suite/ch11/11.1/11.1.5/11.1.5_4-4-c-1.js
|
||||||
|
test262o/test/suite/ch11/11.1/11.1.5/11.1.5_4-4-c-2.js
|
||||||
|
test262o/test/suite/ch11/11.1/11.1.5/11.1.5_4-4-d-1.js
|
||||||
|
test262o/test/suite/ch11/11.1/11.1.5/11.1.5_4-4-d-2.js
|
||||||
|
test262o/test/suite/ch11/11.1/11.1.5/11.1.5_4-4-d-3.js
|
||||||
|
test262o/test/suite/ch11/11.1/11.1.5/11.1.5_4-4-d-4.js
|
||||||
|
|
||||||
|
# ES6 != ES5: Date.prototype is no longer an instance of Date
|
||||||
|
test262o/test/suite/ch15/15.9/15.9.5/15.9.5.40/15.9.5.40_1.js
|
||||||
|
|
||||||
|
# ES6 != ES5: Object.getPrototypeOf converts argument to object
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.2/15.2.3.2-1-3.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.2/15.2.3.2-1-4.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.2/15.2.3.2-1.js
|
||||||
|
|
||||||
|
# ES6 != ES5: Object.getPrototypeOf(NativeError)
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.2/15.2.3.2-2-12.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.2/15.2.3.2-2-13.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.2/15.2.3.2-2-14.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.2/15.2.3.2-2-15.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.2/15.2.3.2-2-16.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.2/15.2.3.2-2-17.js
|
||||||
|
|
||||||
|
# ES6 != ES5: Object.getOwnPropertyDescriptor converts argument to object
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.3/15.2.3.3-1-3.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.3/15.2.3.3-1-4.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.3/15.2.3.3-1.js
|
||||||
|
|
||||||
|
# ES6 != ES5: Object.getOwnPropertyNames converts argument to object
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.4/15.2.3.4-1-4.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.4/15.2.3.4-1-5.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.4/15.2.3.4-1.js
|
||||||
|
|
||||||
|
# ES6 != ES5: Object.seal accepts all types
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.8/15.2.3.8-1-1.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.8/15.2.3.8-1-2.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.8/15.2.3.8-1-3.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.8/15.2.3.8-1-4.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.8/15.2.3.8-1.js
|
||||||
|
|
||||||
|
# ES6 != ES5: Object.freeze accepts all types
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.9/15.2.3.9-1-1.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.9/15.2.3.9-1-2.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.9/15.2.3.9-1-3.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.9/15.2.3.9-1-4.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.9/15.2.3.9-1.js
|
||||||
|
|
||||||
|
# ES6 != ES5: Object.preventExtensions accepts all types
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.10/15.2.3.10-1-1.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.10/15.2.3.10-1-2.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.10/15.2.3.10-1-3.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.10/15.2.3.10-1-4.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.10/15.2.3.10-1.js
|
||||||
|
|
||||||
|
# ES6 != ES5: Object.isSealed accepts all types
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.11/15.2.3.11-1.js
|
||||||
|
|
||||||
|
# ES6 != ES5: Object.isFrozen accepts all types
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.12/15.2.3.12-1-1.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.12/15.2.3.12-1-2.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.12/15.2.3.12-1-3.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.12/15.2.3.12-1-4.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.12/15.2.3.12-1.js
|
||||||
|
|
||||||
|
# ES6 != ES5: Object.isExtensible accepts all types
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.13/15.2.3.13-1-1.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.13/15.2.3.13-1-2.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.13/15.2.3.13-1-3.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.13/15.2.3.13-1-4.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.13/15.2.3.13-1.js
|
||||||
|
|
||||||
|
# ES6 != ES5: Object.keys converts argument to object
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.14/15.2.3.14-1-1.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.14/15.2.3.14-1-2.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.14/15.2.3.14-1-3.js
|
||||||
|
|
||||||
|
# ES6 != ES5: source and other properties of RegExp.prototype are not own properties
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-212.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-213.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-214.js
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.3/15.2.3.3-4-215.js
|
||||||
|
|
||||||
|
# ES6 != ES5: String numeric object properties are enumerated first
|
||||||
|
test262o/test/suite/ch15/15.2/15.2.3/15.2.3.4/15.2.3.4-4-44.js
|
||||||
|
|
||||||
|
# ES6: new RegExp(regex, flags) is valid
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.3/S15.10.3.1_A2_T1.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.3/S15.10.3.1_A2_T2.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.4/15.10.4.1/15.10.4.1-1.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.4/S15.10.4.1_A2_T1.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.4/S15.10.4.1_A2_T2.js
|
||||||
|
|
||||||
|
# ES6 != ES5: RegExp.prototype.test behavior
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.6/15.10.6.2/S15.10.6.2_A5_T3.js
|
||||||
|
|
||||||
|
# ES6 != ES5: source, global, ignoreCase, multiline, lastIndex are not data properties
|
||||||
|
# of RegExp objects and RegExp.prototype is not a RegExp object
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.6/15.10.6.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.1/15.10.7.1-1.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.1/15.10.7.1-2.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.1/S15.10.7.1_A8.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.1/S15.10.7.1_A9.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.1/S15.10.7.1_A10.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.2/15.10.7.2-1.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.2/15.10.7.2-2.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.2/S15.10.7.2_A8.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.2/S15.10.7.2_A9.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.2/S15.10.7.2_A10.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.3/15.10.7.3-1.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.3/15.10.7.3-2.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.3/S15.10.7.3_A8.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.3/S15.10.7.3_A9.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.3/S15.10.7.3_A10.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.4/15.10.7.4-1.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.4/15.10.7.4-2.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.4/S15.10.7.4_A8.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.4/S15.10.7.4_A9.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.4/S15.10.7.4_A10.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.5/15.10.7.5-1.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.7/15.10.7.5/15.10.7.5-2.js
|
||||||
|
|
||||||
|
# ES6 != ES5: Error.prototype is a normal object
|
||||||
|
test262o/test/suite/ch15/15.11/15.11.4/S15.11.4_A2.js
|
||||||
|
|
||||||
|
# ES6 different ToLength() semantics
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.5/S15.4.4.5_A4_T3.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.6/S15.4.4.6_A2_T2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.6/S15.4.4.6_A3_T1.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.6/S15.4.4.6_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.6/S15.4.4.6_A3_T3.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.7/S15.4.4.7_A2_T2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.7/S15.4.4.7_A4_T1.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.7/S15.4.4.7_A4_T3.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.8/S15.4.4.8_A3_T3.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.9/S15.4.4.9_A3_T3.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.10/S15.4.4.10_A3_T1.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.10/S15.4.4.10_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.10/S15.4.4.10_A3_T3.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.11/S15.4.4.11_A4_T3.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.12/S15.4.4.12_A3_T1.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.12/S15.4.4.12_A3_T3.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.13/S15.4.4.13_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.14/15.4.4.14-3-7.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.14/15.4.4.14-3-8.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.14/15.4.4.14-3-12.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.14/15.4.4.14-3-14.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.14/15.4.4.14-3-25.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.14/15.4.4.14-3-28.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.14/15.4.4.14-3-29.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.15/15.4.4.15-3-7.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.15/15.4.4.15-3-12.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.15/15.4.4.15-3-25.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.15/15.4.4.15-3-28.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.16/15.4.4.16-3-7.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.16/15.4.4.16-3-8.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.16/15.4.4.16-3-12.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.16/15.4.4.16-3-14.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.16/15.4.4.16-3-25.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.16/15.4.4.16-3-29.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.17/15.4.4.17-3-7.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.17/15.4.4.17-3-8.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.17/15.4.4.17-3-12.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.17/15.4.4.17-3-14.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.17/15.4.4.17-3-25.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.17/15.4.4.17-3-28.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.17/15.4.4.17-3-29.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.18/15.4.4.18-3-7.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.18/15.4.4.18-3-12.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.18/15.4.4.18-3-25.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.19/15.4.4.19-3-7.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.19/15.4.4.19-3-8.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.19/15.4.4.19-3-12.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.19/15.4.4.19-3-14.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.19/15.4.4.19-3-25.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.19/15.4.4.19-3-28.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.19/15.4.4.19-3-29.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.20/15.4.4.20-3-7.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.20/15.4.4.20-3-12.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.20/15.4.4.20-3-25.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.21/15.4.4.21-3-7.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.21/15.4.4.21-3-12.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.21/15.4.4.21-3-25.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.22/15.4.4.22-3-7.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.22/15.4.4.22-3-12.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.22/15.4.4.22-3-25.js
|
||||||
|
|
||||||
|
# ES6 different ToLength() semantics causes near infinite runtime
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.15/15.4.4.15-3-14.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.18/15.4.4.18-3-14.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.20/15.4.4.20-3-14.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.21/15.4.4.21-3-14.js
|
||||||
|
test262o/test/suite/ch15/15.4/15.4.4/15.4.4.22/15.4.4.22-3-14.js
|
||||||
|
|
||||||
|
# ES6 arguments/caller changes
|
||||||
|
test262o/test/suite/ch10/10.6/10.6-13-b-1-s.js
|
||||||
|
test262o/test/suite/ch10/10.6/10.6-13-b-2-s.js
|
||||||
|
test262o/test/suite/ch10/10.6/10.6-13-b-3-s.js
|
||||||
|
test262o/test/suite/ch10/10.6/10.6-14-1-s.js
|
||||||
|
test262o/test/suite/ch10/10.6/10.6-14-b-1-s.js
|
||||||
|
test262o/test/suite/ch10/10.6/10.6-14-b-4-s.js
|
||||||
|
test262o/test/suite/ch13/13.2/13.2-29-s.js
|
||||||
|
test262o/test/suite/ch13/13.2/13.2-30-s.js
|
||||||
|
test262o/test/suite/ch13/13.2/13.2-31-s.js
|
||||||
|
test262o/test/suite/ch13/13.2/13.2-32-s.js
|
||||||
|
test262o/test/suite/ch13/13.2/13.2-33-s.js
|
||||||
|
test262o/test/suite/ch13/13.2/13.2-34-s.js
|
||||||
|
test262o/test/suite/ch13/13.2/13.2-35-s.js
|
||||||
|
test262o/test/suite/ch13/13.2/13.2-36-s.js
|
||||||
|
test262o/test/suite/ch13/13.2/S13.2.3_A1.js
|
||||||
|
test262o/test/suite/ch15/15.3/15.3.4/15.3.4.5/15.3.4.5-20-1.js
|
||||||
|
test262o/test/suite/ch15/15.3/15.3.4/15.3.4.5/15.3.4.5-20-4.js
|
||||||
|
test262o/test/suite/ch15/15.3/15.3.4/15.3.4.5/15.3.4.5-20-5.js
|
||||||
|
test262o/test/suite/ch15/15.3/15.3.4/15.3.4.5/15.3.4.5-21-1.js
|
||||||
|
test262o/test/suite/ch15/15.3/15.3.4/15.3.4.5/15.3.4.5-21-4.js
|
||||||
|
test262o/test/suite/ch15/15.3/15.3.4/15.3.4.5/15.3.4.5-21-5.js
|
||||||
|
|
||||||
|
# u180e is no longer considered as a space
|
||||||
|
test262o/test/suite/ch09/9.3/9.3.1/S9.3.1_A2.js
|
||||||
|
test262o/test/suite/ch09/9.3/9.3.1/S9.3.1_A3_T1.js
|
||||||
|
test262o/test/suite/ch09/9.3/9.3.1/S9.3.1_A3_T2.js
|
||||||
|
test262o/test/suite/ch15/15.1/15.1.2/15.1.2.2/S15.1.2.2_A2_T10.js
|
||||||
|
test262o/test/suite/ch15/15.1/15.1.2/15.1.2.3/S15.1.2.3_A2_T10.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.20/15.5.4.20-3-2.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.20/15.5.4.20-3-3.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.20/15.5.4.20-3-4.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.20/15.5.4.20-3-5.js
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.20/15.5.4.20-3-6.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.2/15.10.2.12/S15.10.2.12_A1_T1.js
|
||||||
|
test262o/test/suite/ch15/15.10/15.10.2/15.10.2.12/S15.10.2.12_A2_T1.js
|
||||||
|
|
||||||
|
# E6 eval return value is different
|
||||||
|
test262o/test/suite/ch12/12.6/12.6.3/S12.6.3_A9.js
|
||||||
|
test262o/test/suite/ch12/12.6/12.6.3/S12.6.3_A9.1.js
|
||||||
|
|
||||||
|
# ECMA 2019 optional-catch-binding feature allows try{}catch{}
|
||||||
|
test262o/test/suite/ch12/12.14/S12.14_A16_T4.js
|
||||||
|
|
||||||
|
# Syntax error instead of ReferenceError in ES2020
|
||||||
|
test262o/test/suite/ch11/11.13/11.13.1/11.13.1-1-1.js
|
||||||
|
test262o/test/suite/ch11/11.13/11.13.1/11.13.1-1-2.js
|
||||||
|
test262o/test/suite/ch11/11.13/11.13.1/11.13.1-1-3.js
|
||||||
|
test262o/test/suite/ch11/11.13/11.13.1/11.13.1-1-4.js
|
||||||
|
|
||||||
|
# String.prototype.localeCompare special cases
|
||||||
|
test262o/test/suite/ch15/15.5/15.5.4/15.5.4.9/15.5.4.9_CE.js
|
||||||
|
|
||||||
|
[tests]
|
||||||
|
# list test files or use config.testdir
|
|
@ -1,9 +0,0 @@
|
||||||
[config]
|
|
||||||
local=yes
|
|
||||||
verbose=yes
|
|
||||||
testdir=tests
|
|
||||||
|
|
||||||
[exclude]
|
|
||||||
tests/fixture_cyclic_import.js
|
|
||||||
tests/microbench.js
|
|
||||||
tests/test_worker_module.js
|
|
|
@ -1,49 +0,0 @@
|
||||||
export function assert(actual, expected, message) {
|
|
||||||
if (arguments.length === 1)
|
|
||||||
expected = true;
|
|
||||||
|
|
||||||
if (typeof actual === typeof expected) {
|
|
||||||
if (actual === expected) {
|
|
||||||
if (actual !== 0 || (1 / actual) === (1 / expected))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeof actual === 'number') {
|
|
||||||
if (isNaN(actual) && isNaN(expected))
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeof actual === 'object') {
|
|
||||||
if (actual !== null && expected !== null
|
|
||||||
&& actual.constructor === expected.constructor
|
|
||||||
&& actual.toString() === expected.toString())
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw Error("assertion failed: got |" + actual + "|" +
|
|
||||||
", expected |" + expected + "|" +
|
|
||||||
(message ? " (" + message + ")" : ""));
|
|
||||||
}
|
|
||||||
|
|
||||||
export function assertThrows(err, func)
|
|
||||||
{
|
|
||||||
var ex;
|
|
||||||
ex = false;
|
|
||||||
try {
|
|
||||||
func();
|
|
||||||
} catch(e) {
|
|
||||||
ex = true;
|
|
||||||
assert(e instanceof err);
|
|
||||||
}
|
|
||||||
assert(ex, true, "exception expected");
|
|
||||||
}
|
|
||||||
|
|
||||||
export function assertArrayEquals(a, b)
|
|
||||||
{
|
|
||||||
if (!Array.isArray(a) || !Array.isArray(b))
|
|
||||||
return assert(false);
|
|
||||||
|
|
||||||
assert(a.length, b.length);
|
|
||||||
|
|
||||||
a.forEach((value, idx) => {
|
|
||||||
assert(b[idx], value);
|
|
||||||
});
|
|
||||||
}
|
|
96
tests/bjson.c
Normal file
96
tests/bjson.c
Normal file
|
@ -0,0 +1,96 @@
|
||||||
|
/*
|
||||||
|
* QuickJS: binary JSON module (test only)
|
||||||
|
*
|
||||||
|
* Copyright (c) 2017-2019 Fabrice Bellard
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to deal
|
||||||
|
* in the Software without restriction, including without limitation the rights
|
||||||
|
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
* copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
* THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
#include "../quickjs-libc.h"
|
||||||
|
#include "../cutils.h"
|
||||||
|
|
||||||
|
static JSValue js_bjson_read(JSContext *ctx, JSValueConst this_val,
|
||||||
|
int argc, JSValueConst *argv)
|
||||||
|
{
|
||||||
|
uint8_t *buf;
|
||||||
|
uint64_t pos, len;
|
||||||
|
JSValue obj;
|
||||||
|
size_t size;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
if (JS_ToIndex(ctx, &pos, argv[1]))
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
if (JS_ToIndex(ctx, &len, argv[2]))
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
buf = JS_GetArrayBuffer(ctx, &size, argv[0]);
|
||||||
|
if (!buf)
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
if (pos + len > size)
|
||||||
|
return JS_ThrowRangeError(ctx, "array buffer overflow");
|
||||||
|
flags = 0;
|
||||||
|
if (JS_ToBool(ctx, argv[3]))
|
||||||
|
flags |= JS_READ_OBJ_REFERENCE;
|
||||||
|
obj = JS_ReadObject(ctx, buf + pos, len, flags);
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
static JSValue js_bjson_write(JSContext *ctx, JSValueConst this_val,
|
||||||
|
int argc, JSValueConst *argv)
|
||||||
|
{
|
||||||
|
size_t len;
|
||||||
|
uint8_t *buf;
|
||||||
|
JSValue array;
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
flags = 0;
|
||||||
|
if (JS_ToBool(ctx, argv[1]))
|
||||||
|
flags |= JS_WRITE_OBJ_REFERENCE;
|
||||||
|
buf = JS_WriteObject(ctx, &len, argv[0], flags);
|
||||||
|
if (!buf)
|
||||||
|
return JS_EXCEPTION;
|
||||||
|
array = JS_NewArrayBufferCopy(ctx, buf, len);
|
||||||
|
js_free(ctx, buf);
|
||||||
|
return array;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const JSCFunctionListEntry js_bjson_funcs[] = {
|
||||||
|
JS_CFUNC_DEF("read", 4, js_bjson_read ),
|
||||||
|
JS_CFUNC_DEF("write", 2, js_bjson_write ),
|
||||||
|
};
|
||||||
|
|
||||||
|
static int js_bjson_init(JSContext *ctx, JSModuleDef *m)
|
||||||
|
{
|
||||||
|
return JS_SetModuleExportList(ctx, m, js_bjson_funcs,
|
||||||
|
countof(js_bjson_funcs));
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef JS_SHARED_LIBRARY
|
||||||
|
#define JS_INIT_MODULE js_init_module
|
||||||
|
#else
|
||||||
|
#define JS_INIT_MODULE js_init_module_bjson
|
||||||
|
#endif
|
||||||
|
|
||||||
|
JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name)
|
||||||
|
{
|
||||||
|
JSModuleDef *m;
|
||||||
|
m = JS_NewCModule(ctx, module_name, js_bjson_init);
|
||||||
|
if (!m)
|
||||||
|
return NULL;
|
||||||
|
JS_AddModuleExportList(ctx, m, js_bjson_funcs, countof(js_bjson_funcs));
|
||||||
|
return m;
|
||||||
|
}
|
|
@ -1,7 +0,0 @@
|
||||||
/*---
|
|
||||||
flags: [qjs:no-detect-module]
|
|
||||||
negative:
|
|
||||||
phase: parse
|
|
||||||
type: SyntaxError
|
|
||||||
---*/
|
|
||||||
const undefined = 42 // SyntaxError at global scope
|
|
|
@ -1,4 +0,0 @@
|
||||||
/*---
|
|
||||||
flags: [qjs:no-detect-module, module]
|
|
||||||
---*/
|
|
||||||
const undefined = 42 // not a SyntaxError at toplevel module scope
|
|
|
@ -1,4 +0,0 @@
|
||||||
/*---
|
|
||||||
flags: [qjs:no-detect-module]
|
|
||||||
---*/
|
|
||||||
{ const undefined = 42 } // not a SyntaxError, not at global scope
|
|
|
@ -1,4 +0,0 @@
|
||||||
/*---
|
|
||||||
flags: [qjs:no-detect-module]
|
|
||||||
---*/
|
|
||||||
;(function() { const undefined = 42 })() // not a SyntaxError, not at global scope
|
|
|
@ -1,4 +0,0 @@
|
||||||
"use strict";
|
|
||||||
|
|
||||||
const u8 = new Uint8Array(1);
|
|
||||||
u8[100] = 123; // Should not throw.
|
|
|
@ -1,9 +0,0 @@
|
||||||
import { assert, assertThrows } from "../assert.js";
|
|
||||||
const ab = new ArrayBuffer(1);
|
|
||||||
const u8 = new Uint8Array(ab);
|
|
||||||
assert(!ab.detached);
|
|
||||||
// Detach the ArrayBuffer.
|
|
||||||
ab.transfer();
|
|
||||||
assert(ab.detached);
|
|
||||||
u8[100] = 123; // Doesn't throw.
|
|
||||||
assertThrows(TypeError, () => Object.defineProperty(u8, "100", { value: 123 }));
|
|
|
@ -1,7 +0,0 @@
|
||||||
import { assert, assertThrows } from "../assert.js";
|
|
||||||
const ab = new ArrayBuffer(16, { maxByteLength: 32 });
|
|
||||||
const u8 = new Uint8Array(ab, 16);
|
|
||||||
ab.resize(8);
|
|
||||||
assert(ab.byteLength, 8);
|
|
||||||
u8[1] = 123; // Doesn't throw.
|
|
||||||
assertThrows(TypeError, () => Object.defineProperty(u8, "1", { value: 123 }));
|
|
|
@ -1,13 +0,0 @@
|
||||||
/*---
|
|
||||||
negative:
|
|
||||||
phase: runtime
|
|
||||||
type: Error
|
|
||||||
---*/
|
|
||||||
let finrec = new FinalizationRegistry(v => {})
|
|
||||||
let object = {object:"object"}
|
|
||||||
finrec.register(object, {held:"held"}, {token:"token"})
|
|
||||||
object = undefined
|
|
||||||
// abrupt termination should not leak |held|
|
|
||||||
// unfortunately only shows up in qjs, not run-test262,
|
|
||||||
// but still good to have a regression test
|
|
||||||
throw Error("ok")
|
|
|
@ -1,4 +0,0 @@
|
||||||
import { assert } from "./assert.js"
|
|
||||||
const ref = new WeakRef({})
|
|
||||||
const val = ref.deref() // should not throw
|
|
||||||
assert(val, undefined)
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue