Update lang.qjs and use quickjs-ng instead ##lang

* Fix all the portability issues for w32, w64, wasi
This commit is contained in:
Adam Satko 2024-09-27 09:27:50 +00:00 committed by GitHub
parent 24f43bcac8
commit c2e7795bfb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
28 changed files with 17009 additions and 14690 deletions

View File

@ -6,6 +6,7 @@ spp_inc = [platform_inc, include_directories('../../shlr/spp')]
# qjs_inc = [ include_directories('../../shlr/qjs/src') ] # qjs_inc = [ include_directories('../../shlr/qjs/src') ]
qjs_inc = '../../shlr/qjs/src' qjs_inc = '../../shlr/qjs/src'
r_lang_sources += '../../shlr/qjs/src/quickjs.c' r_lang_sources += '../../shlr/qjs/src/quickjs.c'
r_lang_sources += '../../shlr/qjs/src/libbf.c'
r_lang_sources += '../../shlr/qjs/src/cutils.c' r_lang_sources += '../../shlr/qjs/src/cutils.c'
r_lang_sources += '../../shlr/qjs/src/libregexp.c' r_lang_sources += '../../shlr/qjs/src/libregexp.c'
r_lang_sources += '../../shlr/qjs/src/libunicode.c' r_lang_sources += '../../shlr/qjs/src/libunicode.c'

View File

@ -785,12 +785,6 @@ static JSContext *JS_NewCustomContext(JSRuntime *rt) {
if (!ctx) { if (!ctx) {
return NULL; return NULL;
} }
#if CONFIG_BIGNUM
JS_AddIntrinsicBigFloat (ctx);
JS_AddIntrinsicBigDecimal (ctx);
JS_AddIntrinsicOperators (ctx);
JS_EnableBignumExt (ctx, true);
#endif
return ctx; return ctx;
} }

View File

@ -8,6 +8,11 @@ ifeq ($(QJS_BRANCH),frida)
QJS_GITURL=https://github.com/frida/quickjs QJS_GITURL=https://github.com/frida/quickjs
QJS_CFLAGS+=-DQJS_NAME="\\"$(QJS_NAME)\\"" QJS_CFLAGS+=-DQJS_NAME="\\"$(QJS_NAME)\\""
QJS_CFLAGS+=-DQJS_FRIDA=1 QJS_CFLAGS+=-DQJS_FRIDA=1
else ifeq ($(QJS_BRANCH),quickjs-ng)
QJS_NAME=quickjs-ng
QJS_GITURL=https://github.com/quickjs-ng/quickjs
QJS_CFLAGS+=-DQJS_NAME="\\"$(QJS_NAME)\\""
QJS_CFLAGS+=-DQJS_FRIDA=0
else else
QJS_NAME=quickjs-bellard QJS_NAME=quickjs-bellard
QJS_GITURL=https://github.com/bellard/quickjs QJS_GITURL=https://github.com/bellard/quickjs
@ -18,15 +23,15 @@ endif
.PHONY: $(QJS_NAME) .PHONY: $(QJS_NAME)
QJS_CFLAGS+=-D QJS_LIBC=$(QJS_LIBC) QJS_CFLAGS+=-D QJS_LIBC=$(QJS_LIBC)
QJS_CFLAGS+=-D CONFIG_STACK_CHECK=y
QJS_CFLAGS+=-D QJS_NOABORT=1 QJS_CFLAGS+=-D QJS_NOABORT=1
QJS_CFLAGS+=-U CONFIG_BIGNUM
QJS_CFLAGS+=-U DUMP_LEAKS QJS_CFLAGS+=-U DUMP_LEAKS
QJS_CFLAGS+=-U NDEBUG QJS_CFLAGS+=-U NDEBUG
QJS_LIBS+=-lr_core -lr_config -lr_cons QJS_LIBS+=-lr_core -lr_config -lr_cons
QJS_VERSION=$(shell cat src/VERSION.txt) #QJS_VERSION=$(shell cat src/VERSION)
# XXX: Is version needed when there is QJS_VERSION_STRING?
QJS_VERSION=0.6.1
JS_CFILES:=js_repl.c js_r2papi.c js_require.c JS_CFILES:=js_repl.c js_r2papi.c js_require.c
@ -45,7 +50,8 @@ sync-qjs qjs-sync sync:
rm -rf src/.git rm -rf src/.git
mkdir -p src2 mkdir -p src2
ls src ls src
cp $(QJS_FILES) src/*.h src/Makefile src/VERSION.txt src2/ # cp $(QJS_FILES) src/*.h src/Makefile src/VERSION src2/
cp $(QJS_FILES) src/*.h src/Makefile src2/
rm -rf src rm -rf src
mv src2 src mv src2 src
sed -i -e 's/CONFIG_VERSION/"$(QJS_VERSION)"/' src/quickjs.c sed -i -e 's/CONFIG_VERSION/"$(QJS_VERSION)"/' src/quickjs.c

View File

@ -1,8 +1,6 @@
include ../../libr/config.mk include ../../libr/config.mk
# include $(SHLR)/qjs/config.mk # include $(SHLR)/qjs/config.mk
LINK_QJS_ARCHIVE=0 LINK_QJS_ARCHIVE=0
QJS_STACK_CHECK=1
QJS_BIGNUM=1
QJS_LIBC=0 QJS_LIBC=0
ifeq ($(LINK_QJS_ARCHIVE),1) ifeq ($(LINK_QJS_ARCHIVE),1)
@ -12,21 +10,14 @@ QJSFILES+=quickjs.c
QJSFILES+=cutils.c QJSFILES+=cutils.c
QJSFILES+=libregexp.c QJSFILES+=libregexp.c
QJSFILES+=libunicode.c QJSFILES+=libunicode.c
# https://github.com/quickjs-ng/quickjs/issues/17
QJSFILES+=libbf.c
ifeq ($(QJS_LIBC),1) ifeq ($(QJS_LIBC),1)
QJSFILES+=quickjs-libc.c QJSFILES+=quickjs-libc.c
endif endif
ifeq ($(QJS_BIGNUM),1)
QJSFILES+=libbf.c
endif
endif endif
QJSOBJS=$(subst .c,.o,$(QJSFILES)) QJSOBJS=$(subst .c,.o,$(QJSFILES))
QJS_FILES=$(addprefix $(SHLR)/qjs/src/,$(QJSFILES)) QJS_FILES=$(addprefix $(SHLR)/qjs/src/,$(QJSFILES))
QJS_OBJS=$(addprefix $(SHLR)/qjs/src/,$(QJSOBJS)) QJS_OBJS=$(addprefix $(SHLR)/qjs/src/,$(QJSOBJS))
CFLAGS+=-I$(SHLR)/qjs/src CFLAGS+=-I$(SHLR)/qjs/src
ifeq ($(QJS_BIGNUM),1)
CFLAGS+=-DCONFIG_BIGNUM=$(QJS_BIGNUM)
endif
ifeq ($(QJS_STACK_CHECK),1)
CFLAGS+=-DCONFIG_STACK_CHECK=y
endif

View File

@ -3,6 +3,8 @@
# #
# 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
@ -22,456 +24,94 @@
# 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.
ifeq ($(shell uname -s),Darwin) BUILD_DIR=build
CONFIG_DARWIN=y BUILD_TYPE?=Release
endif
# Windows cross compilation from Linux
#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
ifdef CONFIG_DARWIN QJS=$(BUILD_DIR)/qjs
# use clang instead of gcc QJSC=$(BUILD_DIR)/qjsc
CONFIG_CLANG=y RUN262=$(BUILD_DIR)/run-test262
CONFIG_DEFAULT_AR=y
JOBS?=$(shell getconf _NPROCESSORS_ONLN)
ifeq ($(JOBS),)
JOBS := $(shell sysctl -n hw.ncpu)
endif
ifeq ($(JOBS),)
JOBS := $(shell nproc)
endif
ifeq ($(JOBS),)
JOBS := 4
endif endif
# installation directory all: $(QJS)
prefix=/usr/local
# avoid stack overflow on recursive calls $(BUILD_DIR):
CONFIG_STACK_CHECK=y cmake -B $(BUILD_DIR) -DCMAKE_BUILD_TYPE=$(BUILD_TYPE)
# use the gprof profiler
#CONFIG_PROFILE=y
# use address sanitizer
#CONFIG_ASAN=y
# include the code for BigInt/BigFloat/BigDecimal and math mode
CONFIG_BIGNUM=y
CONFIG_NOABORT=y $(QJS): $(BUILD_DIR)
cmake --build $(BUILD_DIR) -j $(JOBS)
OBJDIR=.obj $(QJSC): $(BUILD_DIR)
cmake --build $(BUILD_DIR) --target qjsc -j $(JOBS)
ifdef CONFIG_WIN32 $(BUILD_DIR)/test_conv: $(BUILD_DIR) tests/test_conv.c
ifdef CONFIG_M32 cmake --build $(BUILD_DIR) --target test_conv
CROSS_PREFIX=i686-w64-mingw32-
else
CROSS_PREFIX=x86_64-w64-mingw32-
endif
EXE=.exe
else
CROSS_PREFIX=
EXE=
endif
ifdef CONFIG_CLANG
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
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
ifdef CONFIG_WERROR
CFLAGS+=-Werror
endif
DEFINES:=-D_GNU_SOURCE -DCONFIG_VERSION=\"$(shell cat VERSION.txt)\"
ifdef CONFIG_BIGNUM
DEFINES+=-DCONFIG_BIGNUM
endif
ifdef CONFIG_WIN32
DEFINES+=-D__USE_MINGW_ANSI_STDIO # for standard snprintf behavior
endif
CFLAGS+=$(DEFINES) install: $(QJS) $(QJSC)
CFLAGS_DEBUG=$(CFLAGS) -O0 cmake --build $(BUILD_DIR) --target install
CFLAGS_SMALL=$(CFLAGS) -Os
CFLAGS_OPT=$(CFLAGS) -O2
CFLAGS_NOLTO:=$(CFLAGS_OPT)
LDFLAGS=-g
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_WIN32
LDEXPORT=
else
LDEXPORT=-rdynamic
endif
PROGS=qjs$(EXE) qjsc$(EXE) run-test262
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
# examples
ifeq ($(CROSS_PREFIX),)
ifdef CONFIG_ASAN
PROGS+=
else
PROGS+=examples/hello examples/hello_module examples/test_fib
ifndef CONFIG_DARWIN
PROGS+=examples/fib.so examples/point.so
endif
endif
endif
all: $(OBJDIR) $(OBJDIR)/quickjs.check.o $(OBJDIR)/qjs.check.o $(PROGS)
QJS_LIB_OBJS=$(OBJDIR)/quickjs.o $(OBJDIR)/libregexp.o $(OBJDIR)/libunicode.o $(OBJDIR)/cutils.o $(OBJDIR)/quickjs-libc.o
QJS_OBJS=$(OBJDIR)/qjs.o $(OBJDIR)/repl.o $(QJS_LIB_OBJS)
ifdef CONFIG_BIGNUM
QJS_LIB_OBJS+=$(OBJDIR)/libbf.o
QJS_OBJS+=$(OBJDIR)/qjscalc.o
endif
HOST_LIBS=-lm -ldl -lpthread
LIBS=-lm
ifndef CONFIG_WIN32
LIBS+=-ldl -lpthread
endif
LIBS+=$(EXTRA_LIBS)
$(OBJDIR):
mkdir -p $(OBJDIR) $(OBJDIR)/examples $(OBJDIR)/tests
qjs$(EXE): $(QJS_OBJS)
$(CC) $(LDFLAGS) $(LDEXPORT) -o $@ $^ $(LIBS)
qjs-debug$(EXE): $(patsubst %.o, %.debug.o, $(QJS_OBJS))
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
qjsc$(EXE): $(OBJDIR)/qjsc.o $(QJS_LIB_OBJS)
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
ifneq ($(CROSS_PREFIX),)
$(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
ifdef CONFIG_NOABORT
QJSC_DEFINES+=-DCONFIG_NOABORT
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
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
./unicode_gen unicode $@
endif
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)/%.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)/%.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: clean:
rm -f repl.c qjscalc.c out.c @rm -f v8.txt[1-9]*
rm -f *.a *.o *.d *~ unicode_gen regexp_test $(PROGS) cmake --build $(BUILD_DIR) --target clean
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
install: all codegen: $(QJSC)
mkdir -p "$(DESTDIR)$(prefix)/bin" $(QJSC) -ss -o gen/repl.c -m repl.js
$(STRIP) qjs qjsc $(QJSC) -e -o gen/function_source.c tests/function_source.js
install -m755 qjs qjsc "$(DESTDIR)$(prefix)/bin" $(QJSC) -e -o gen/hello.c examples/hello.js
ln -sf qjs "$(DESTDIR)$(prefix)/bin/qjscalc" $(QJSC) -e -o gen/hello_module.c -m examples/hello_module.js
mkdir -p "$(DESTDIR)$(prefix)/lib/quickjs" $(QJSC) -e -o gen/test_fib.c -M examples/fib.so,fib -m examples/test_fib.js
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"
############################################################################### debug:
# examples BUILD_TYPE=Debug $(MAKE)
# example of static JS compilation distclean:
HELLO_SRCS=examples/hello.js @rm -rf $(BUILD_DIR)
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
ifdef CONFIG_BIGNUM
HELLO_OPTS+=-fno-bigint
endif
hello.c: $(QJSC) $(HELLO_SRCS) stats: $(QJS)
$(QJSC) -e $(HELLO_OPTS) -o $@ $(HELLO_SRCS) $(QJS) -qd
ifdef CONFIG_M32 test: $(QJS)
examples/hello: $(OBJDIR)/hello.m32s.o $(patsubst %.o, %.m32s.o, $(QJS_LIB_OBJS)) $(QJS) tests/test_bigint.js
$(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS) $(QJS) tests/test_closure.js
else $(QJS) tests/test_language.js
examples/hello: $(OBJDIR)/hello.o $(QJS_LIB_OBJS) $(QJS) tests/test_builtin.js
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(QJS) tests/test_loop.js
endif $(QJS) tests/test_std.js
$(QJS) tests/test_worker.js
$(QJS) tests/test_queue_microtask.js
$(QJS) tests/test_module_detect.js
# example of static JS compilation with modules testconv: $(BUILD_DIR)/test_conv
HELLO_MODULE_SRCS=examples/hello_module.js $(BUILD_DIR)/test_conv
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) test262: $(QJS)
$(RUN262) -m -c test262.conf -a
test_fib.c: $(QJSC) examples/test_fib.js test262-fast: $(QJS)
$(QJSC) -e -M examples/fib.so,fib -m -o $@ examples/test_fib.js $(RUN262) -m -c test262.conf -c test262-fast.conf -a
examples/test_fib: $(OBJDIR)/test_fib.o $(OBJDIR)/examples/fib.o libquickjs$(LTOEXT).a test262-update: $(QJS)
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS) $(RUN262) -u -c test262.conf -a
examples/fib.so: $(OBJDIR)/examples/fib.pic.o test262-check: $(QJS)
$(CC) $(LDFLAGS) -shared -o $@ $^ $(RUN262) -m -c test262.conf -E -a
examples/point.so: $(OBJDIR)/examples/point.pic.o microbench: $(QJS)
$(CC) $(LDFLAGS) -shared -o $@ $^ $(QJS) tests/microbench.js
############################################################################### unicode_gen: $(BUILD_DIR)
# documentation cmake --build $(BUILD_DIR) --target unicode_gen
DOCS=doc/quickjs.pdf doc/quickjs.html doc/jsbignum.pdf doc/jsbignum.html libunicode-table.h: unicode_gen
$(BUILD_DIR)/unicode_gen unicode $@
build_doc: $(DOCS) .PHONY: all debug install clean codegen distclean stats test test262 test262-update test262-check microbench unicode_gen $(QJS) $(QJSC)
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
ifndef CONFIG_DARWIN
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 tests/test_builtin.js
./qjs tests/test_loop.js
./qjs tests/test_std.js
./qjs tests/test_worker.js
ifndef CONFIG_DARWIN
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_bignum.js
./qjs --qjscalc tests/test_qjscalc.js
endif
ifdef CONFIG_M32
./qjs32 tests/test_closure.js
./qjs32 tests/test_language.js
./qjs32 tests/test_builtin.js
./qjs32 tests/test_loop.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_bignum.js
./qjs32 --qjscalc tests/test_qjscalc.js
endif
endif
stats: qjs qjs32
./qjs -qd
./qjs32 -qd
microbench: qjs
./qjs tests/microbench.js
microbench-32: qjs32
./qjs32 tests/microbench.js
# ES5 tests (obsolete)
test2o: run-test262
time ./run-test262 -m -c test262o.conf
test2o-32: run-test262-32
time ./run-test262-32 -m -c test262o.conf
test2o-update: run-test262
./run-test262 -u -c test262o.conf
# Test262 tests
test2-default: run-test262
time ./run-test262 -m -c test262.conf
test2: run-test262
time ./run-test262 -m -c test262.conf -a
test2-32: run-test262-32
time ./run-test262-32 -m -c test262.conf -a
test2-update: run-test262
./run-test262 -u -c test262.conf -a
test2-check: run-test262
time ./run-test262 -m -c test262.conf -E -a
testall: all test microbench test2o test2
testall-32: all test-32 microbench-32 test2o-32 test2-32
testall-complete: testall testall-32
bench-v8: qjs
make -C tests/bench-v8
./qjs -d tests/bench-v8/combined.js
tests/bjson.so: $(OBJDIR)/tests/bjson.pic.o
$(CC) $(LDFLAGS) -shared -o $@ $^ $(LIBS)
-include $(wildcard $(OBJDIR)/*.d)

View File

@ -1 +0,0 @@
2021-03-27

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* /*
* C utilities * C utilities
* *
* Copyright (c) 2017 Fabrice Bellard * Copyright (c) 2017 Fabrice Bellard
* Copyright (c) 2018 Charlie Gordon * Copyright (c) 2018 Charlie Gordon
* *
@ -26,30 +26,74 @@
#define CUTILS_H #define CUTILS_H
#include <stdlib.h> #include <stdlib.h>
#include <string.h>
#include <inttypes.h> #include <inttypes.h>
#include <math.h>
#ifdef _MSC_VER #ifdef __cplusplus
#include <windows.h> extern "C" {
#include <intrin.h>
#else
#include <sys/time.h>
#endif #endif
#ifdef _MSC_VER #if defined(_MSC_VER)
#define likely(x) (x) #include <winsock2.h>
#define unlikely(x) (x) #include <malloc.h>
#define force_inline __forceinline #define alloca _alloca
#define no_inline __declspec(noinline) #define ssize_t ptrdiff_t
#define __maybe_unused #endif
#define __attribute__(x) #if defined(__APPLE__)
#define __attribute(x) #include <malloc/malloc.h>
typedef size_t ssize_t; #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)
# include <intrin.h>
static void *__builtin_frame_address(unsigned int level) {
return (void *)((char*)_AddressOfReturnAddress() - sizeof(int *) - level * sizeof(int *));
}
#else #else
#define likely(x) __builtin_expect(!!(x), 1) # define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0) # define unlikely(x) __builtin_expect(!!(x), 0)
#define force_inline inline __attribute__((always_inline)) # define force_inline inline __attribute__((always_inline))
#define no_inline __attribute__((noinline)) # define no_inline __attribute__((noinline))
#define __maybe_unused __attribute__((unused)) # 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 #endif
#define xglue(x, y) x ## y #define xglue(x, y) x ## y
@ -62,6 +106,19 @@ typedef size_t ssize_t;
#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
#ifndef container_of
/* return the pointer of type 'type *' containing 'ptr' as field 'member' */
#define container_of(ptr, type, member) ((type *)((uint8_t *)(ptr) - offsetof(type, member)))
#endif
#if !defined(_MSC_VER) && defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
#define minimum_length(n) static n
#else
#define minimum_length(n) n
#endif #endif
typedef int BOOL; typedef int BOOL;
@ -78,6 +135,14 @@ char *pstrcat(char *buf, int buf_size, const char *s);
int strstart(const char *str, const char *val, const char **ptr); int strstart(const char *str, const char *val, const char **ptr);
int has_suffix(const char *str, const char *suffix); int has_suffix(const char *str, const char *suffix);
static inline uint8_t is_be(void) {
union {
uint16_t a;
uint8_t b;
} u = { 0x100 };
return u.b;
}
static inline int max_int(int a, int b) static inline int max_int(int a, int b)
{ {
if (a > b) if (a > b)
@ -126,19 +191,13 @@ static inline int64_t min_int64(int64_t a, int64_t b)
return b; return b;
} }
extern size_t r_num_bit_count(unsigned int val);
/* 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) #if defined(_MSC_VER) && !defined(__clang__)
unsigned long idx; unsigned long index;
_BitScanReverse(&idx, a); _BitScanReverse(&index, a);
return 31 ^ idx; return 31 - index;
#elif defined(__TINYC__)
a = a - ((a >> 1) & 0x55555555);
a = (a & 0x33333333) + ((a >> 2) & 0x33333333);
return (((a + (a >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
#else #else
return __builtin_clz(a); return __builtin_clz(a);
#endif #endif
@ -147,22 +206,17 @@ static inline int clz32(unsigned int a)
/* 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) #if defined(_MSC_VER) && !defined(__clang__)
unsigned long where; #if INTPTR_MAX == INT64_MAX
#if INTPTR_MAX >= INT64_MAX unsigned long index;
if (_BitScanReverse64(&where, a)) _BitScanReverse64(&index, a);
return (int)(63 - where); return 63 - index;
#else #else
if (_BitScanReverse(&where, (uint32_t)(a >> 32))) if (a >> 32)
return (int)(63 - (where + 32)); return clz32((unsigned)(a >> 32));
if (_BitScanReverse(&where, (uint32_t)(a))) else
return (int)(63 - where); return clz32((unsigned)a) + 32;
#endif #endif
return 64; /* undefined behavior */
#elif defined(__TINYC__)
a = a - ((a >> 1) & 0x5555555555555555);
a = (a & 0x3333333333333333) + ((a >> 2) & 0x3333333333333333);
return (((a + (a >> 4)) & 0x0F0F0F0F0F0F0F0F) * 0x0101010101010101) >> 24;
#else #else
return __builtin_clzll(a); return __builtin_clzll(a);
#endif #endif
@ -171,13 +225,10 @@ static inline int clz64(uint64_t a)
/* 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) #if defined(_MSC_VER) && !defined(__clang__)
unsigned long idx; unsigned long index;
_BitScanForward(&idx, a); _BitScanForward(&index, a);
return 31 ^ idx; return index;
#elif defined(__TINYC__)
const unsigned int m = 0x01010101;
return (unsigned)((((a - 1) ^ a) & (m - 1)) * m) >> 24;
#else #else
return __builtin_ctz(a); return __builtin_ctz(a);
#endif #endif
@ -186,98 +237,70 @@ static inline int ctz32(unsigned int a)
/* 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) #if defined(_MSC_VER) && !defined(__clang__)
unsigned long where; unsigned long index;
#if INTPTR_MAX >= INT64_MAX /* 64-bit */ _BitScanForward64(&index, a);
if (_BitScanForward64(&where, a)) return index;
return (int)(where);
#else
if (_BitScanForward(&where, (uint32_t)a))
return (int)(where);
if (_BitScanForward(&where, (uint32_t)(a >> 32)))
return (int)(where + 32);
#endif
return 64;
#elif defined(__TINYC__)
const unsigned long long m = 0x0101010101010101ULL;
a ^= a - 1;
return (unsigned)(((unsigned long long)((a & (m - 1)) * m)) >> 56);
#else #else
return __builtin_ctzll(a); return __builtin_ctzll(a);
#endif #endif
} }
#ifdef _MSC_VER
#pragma pack(push, 1)
struct packed_u64 {
uint64_t v;
};
struct packed_u32 {
uint32_t v;
};
struct packed_u16 {
uint16_t v;
};
#pragma pack(pop)
#else
struct __attribute__((packed)) packed_u64 {
uint64_t v;
};
struct __attribute__((packed)) packed_u32 {
uint32_t v;
};
struct __attribute__((packed)) packed_u16 {
uint16_t v;
};
#endif
static inline uint64_t get_u64(const uint8_t *tab) static inline uint64_t get_u64(const uint8_t *tab)
{ {
return ((const struct packed_u64 *)tab)->v; uint64_t 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)
{ {
return (int64_t)((const struct packed_u64 *)tab)->v; int64_t 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)
{ {
((struct packed_u64 *)tab)->v = val; memcpy(tab, &val, sizeof(val));
} }
static inline uint32_t get_u32(const uint8_t *tab) static inline uint32_t get_u32(const uint8_t *tab)
{ {
return ((const struct packed_u32 *)tab)->v; uint32_t 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)
{ {
return (int32_t)((const struct packed_u32 *)tab)->v; int32_t 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)
{ {
((struct packed_u32 *)tab)->v = val; memcpy(tab, &val, sizeof(val));
} }
static inline uint32_t get_u16(const uint8_t *tab) static inline uint32_t get_u16(const uint8_t *tab)
{ {
return ((const struct packed_u16 *)tab)->v; uint16_t 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)
{ {
return (int16_t)((const struct packed_u16 *)tab)->v; int16_t 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)
{ {
((struct packed_u16 *)tab)->v = val; memcpy(tab, &val, sizeof(val));
} }
static inline uint32_t get_u8(const uint8_t *tab) static inline uint32_t get_u8(const uint8_t *tab)
@ -295,28 +318,117 @@ static inline void put_u8(uint8_t *tab, uint8_t val)
*tab = val; *tab = val;
} }
#ifndef bswap16
static inline uint16_t bswap16(uint16_t x) static inline uint16_t bswap16(uint16_t x)
{ {
return (x >> 8) | (x << 8); return (x >> 8) | (x << 8);
} }
#endif
#ifndef bswap32
static inline uint32_t bswap32(uint32_t v) static inline uint32_t bswap32(uint32_t v)
{ {
return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) | return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) |
((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24); ((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24);
} }
#endif
#ifndef bswap64
static inline uint64_t bswap64(uint64_t v) static inline uint64_t bswap64(uint64_t v)
{ {
return ((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) | return ((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) |
((v & ((uint64_t)0xff << (6 * 8))) >> (5 * 8)) | ((v & ((uint64_t)0xff << (6 * 8))) >> (5 * 8)) |
((v & ((uint64_t)0xff << (5 * 8))) >> (3 * 8)) | ((v & ((uint64_t)0xff << (5 * 8))) >> (3 * 8)) |
((v & ((uint64_t)0xff << (4 * 8))) >> (1 * 8)) | ((v & ((uint64_t)0xff << (4 * 8))) >> (1 * 8)) |
((v & ((uint64_t)0xff << (3 * 8))) << (1 * 8)) | ((v & ((uint64_t)0xff << (3 * 8))) << (1 * 8)) |
((v & ((uint64_t)0xff << (2 * 8))) << (3 * 8)) | ((v & ((uint64_t)0xff << (2 * 8))) << (3 * 8)) |
((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) | ((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) |
((v & ((uint64_t)0xff << (0 * 8))) << (7 * 8)); ((v & ((uint64_t)0xff << (0 * 8))) << (7 * 8));
} }
#endif
static inline void inplace_bswap16(uint8_t *tab) {
put_u16(tab, bswap16(get_u16(tab)));
}
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);
@ -333,8 +445,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 uint8_t *data, size_t len); int dbuf_write(DynBuf *s, size_t offset, const void *data, size_t len);
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len); int dbuf_put(DynBuf *s, const void *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);
@ -351,7 +463,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,
const char *fmt, ...); FORMAT_STRING(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;
@ -361,10 +473,56 @@ static inline void dbuf_set_error(DynBuf *s)
s->error = TRUE; s->error = TRUE;
} }
#define UTF8_CHAR_LEN_MAX 6 /*---- UTF-8 and UTF-16 handling ----*/
int unicode_to_utf8(uint8_t *buf, unsigned int c); #define UTF8_CHAR_LEN_MAX 4
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, uint32_t c);
uint32_t utf8_decode_len(const uint8_t *p, size_t max_len, const uint8_t **pp);
uint32_t utf8_decode(const uint8_t *p, const uint8_t **pp);
size_t utf8_decode_buf8(uint8_t *dest, size_t dest_len, const char *src, size_t src_len);
size_t utf8_decode_buf16(uint16_t *dest, size_t dest_len, const char *src, size_t src_len);
size_t utf8_encode_buf8(char *dest, size_t dest_len, const uint8_t *src, size_t src_len);
size_t utf8_encode_buf16(char *dest, size_t dest_len, const uint16_t *src, size_t src_len);
static inline BOOL is_surrogate(uint32_t c)
{
return (c >> 11) == (0xD800 >> 11); // 0xD800-0xDFFF
}
static inline BOOL is_hi_surrogate(uint32_t c)
{
return (c >> 10) == (0xD800 >> 10); // 0xD800-0xDBFF
}
static inline BOOL is_lo_surrogate(uint32_t c)
{
return (c >> 10) == (0xDC00 >> 10); // 0xDC00-0xDFFF
}
static inline uint32_t get_hi_surrogate(uint32_t c)
{
return (c >> 10) - (0x10000 >> 10) + 0xD800;
}
static inline uint32_t get_lo_surrogate(uint32_t c)
{
return (c & 0x3FF) | 0xDC00;
}
static inline uint32_t from_surrogate(uint32_t hi, uint32_t lo)
{
return 65536 + 1024 * (hi & 1023) + (lo & 1023);
}
static inline int from_hex(int c) static inline int from_hex(int c)
{ {
@ -378,8 +536,78 @@ 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 */

1166
shlr/qjs/src/dirent_compat.h Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,653 @@
#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__) */

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* /*
* Tiny arbitrary precision floating point library * Tiny arbitrary precision floating point library
* *
* Copyright (c) 2017-2021 Fabrice Bellard * Copyright (c) 2017-2021 Fabrice Bellard
* *
* 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
@ -27,7 +27,11 @@
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#if !defined(_MSC_VER) && !defined(__TINYC__) && INTPTR_MAX >= INT64_MAX #ifdef __cplusplus
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
@ -36,8 +40,10 @@
#define LIMB_BITS (1 << LIMB_LOG2_BITS) #define LIMB_BITS (1 << LIMB_LOG2_BITS)
#if LIMB_BITS == 64 #if LIMB_BITS == 64
typedef __int128 int128_t; #ifndef INT128_MAX
typedef unsigned __int128 uint128_t; __extension__ typedef __int128 int128_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;
@ -171,7 +177,7 @@ static inline bf_flags_t bf_set_exp_bits(int n)
#define BF_ST_UNDERFLOW (1 << 3) #define BF_ST_UNDERFLOW (1 << 3)
#define BF_ST_INEXACT (1 << 4) #define BF_ST_INEXACT (1 << 4)
/* indicate that a memory allocation error occured. NaN is returned */ /* indicate that a memory allocation error occured. NaN is returned */
#define BF_ST_MEM_ERROR (1 << 5) #define BF_ST_MEM_ERROR (1 << 5)
#define BF_RADIX_MAX 36 /* maximum radix for bf_atof() and bf_ftoa() */ #define BF_RADIX_MAX 36 /* maximum radix for bf_atof() and bf_ftoa() */
@ -284,7 +290,7 @@ int bf_sub(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags)
int bf_add_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec, bf_flags_t flags); int bf_add_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec, bf_flags_t flags);
int bf_mul(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags); int bf_mul(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags);
int bf_mul_ui(bf_t *r, const bf_t *a, uint64_t b1, limb_t prec, bf_flags_t flags); int bf_mul_ui(bf_t *r, const bf_t *a, uint64_t b1, limb_t prec, bf_flags_t flags);
int bf_mul_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec, int bf_mul_si(bf_t *r, const bf_t *a, int64_t b1, limb_t prec,
bf_flags_t flags); bf_flags_t flags);
int bf_mul_2exp(bf_t *r, slimb_t e, limb_t prec, bf_flags_t flags); int bf_mul_2exp(bf_t *r, slimb_t e, limb_t prec, bf_flags_t flags);
int bf_div(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags); int bf_div(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags);
@ -341,12 +347,12 @@ int bf_mul_pow_radix(bf_t *r, const bf_t *T, limb_t radix,
/* fractional format: prec digits after the decimal point rounded with /* fractional format: prec digits after the decimal point rounded with
(flags & BF_RND_MASK) */ (flags & BF_RND_MASK) */
#define BF_FTOA_FORMAT_FRAC (1 << 16) #define BF_FTOA_FORMAT_FRAC (1 << 16)
/* free format: /* free format:
For binary radices with bf_ftoa() and for bfdec_ftoa(): use the minimum For binary radices with bf_ftoa() and for bfdec_ftoa(): use the minimum
number of digits to represent 'a'. The precision and the rounding number of digits to represent 'a'. The precision and the rounding
mode are ignored. mode are ignored.
For the non binary radices with bf_ftoa(): use as many digits as For the non binary radices with bf_ftoa(): use as many digits as
necessary so that bf_atof() return the same number when using necessary so that bf_atof() return the same number when using
precision 'prec', rounding to nearest and the subnormal precision 'prec', rounding to nearest and the subnormal
@ -373,7 +379,7 @@ char *bf_ftoa(size_t *plen, const bf_t *a, int radix, limb_t prec,
bf_flags_t flags); bf_flags_t flags);
/* modulo 2^n instead of saturation. NaN and infinity return 0 */ /* modulo 2^n instead of saturation. NaN and infinity return 0 */
#define BF_GET_INT_MOD (1 << 0) #define BF_GET_INT_MOD (1 << 0)
int bf_get_int32(int *pres, const bf_t *a, int flags); int bf_get_int32(int *pres, const bf_t *a, int flags);
int bf_get_int64(int64_t *pres, const bf_t *a, int flags); int bf_get_int64(int64_t *pres, const bf_t *a, int flags);
int bf_get_uint64(uint64_t *pres, const bf_t *a); int bf_get_uint64(uint64_t *pres, const bf_t *a);
@ -387,10 +393,10 @@ int bf_normalize_and_round(bf_t *r, limb_t prec1, bf_flags_t flags);
int bf_can_round(const bf_t *a, slimb_t prec, bf_rnd_t rnd_mode, slimb_t k); int bf_can_round(const bf_t *a, slimb_t prec, bf_rnd_t rnd_mode, slimb_t k);
slimb_t bf_mul_log2_radix(slimb_t a1, unsigned int radix, int is_inv, slimb_t bf_mul_log2_radix(slimb_t a1, unsigned int radix, int is_inv,
int is_ceil1); int is_ceil1);
int mp_mul(bf_context_t *s, limb_t *result, int mp_mul(bf_context_t *s, limb_t *result,
const limb_t *op1, limb_t op1_size, const limb_t *op1, limb_t op1_size,
const limb_t *op2, limb_t op2_size); const limb_t *op2, limb_t op2_size);
limb_t mp_add(limb_t *res, const limb_t *op1, const limb_t *op2, limb_t mp_add(limb_t *res, const limb_t *op1, const limb_t *op2,
limb_t n, limb_t carry); limb_t n, limb_t carry);
limb_t mp_add_ui(limb_t *tab, limb_t b, size_t n); limb_t mp_add_ui(limb_t *tab, limb_t b, size_t n);
int mp_sqrtrem(bf_context_t *s, limb_t *tabs, limb_t *taba, limb_t n); int mp_sqrtrem(bf_context_t *s, limb_t *tabs, limb_t *taba, limb_t n);
@ -532,4 +538,8 @@ 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 */

View File

@ -1,6 +1,6 @@
/* /*
* Regular Expression Engine * Regular Expression Engine
* *
* Copyright (c) 2017-2018 Fabrice Bellard * Copyright (c) 2017-2018 Fabrice Bellard
* *
* 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
@ -25,7 +25,8 @@
#ifdef DEF #ifdef DEF
DEF(invalid, 1) /* never used */ DEF(invalid, 1) /* never used */
DEF(char, 3) DEF(char8, 2) /* 7 bits in fact */
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 */
@ -50,8 +51,7 @@ DEF(range32, 3) /* variable length */
DEF(lookahead, 5) DEF(lookahead, 5)
DEF(negative_lookahead, 5) DEF(negative_lookahead, 5)
DEF(push_char_pos, 1) /* push the character position on the stack */ DEF(push_char_pos, 1) /* push the character position on the stack */
DEF(bne_char_pos, 5) /* pop one stack element and jump if equal to the character DEF(check_advance, 1) /* pop one stack element and check that it is different from the character position */
position */
DEF(prev, 1) /* go to the previous char */ DEF(prev, 1) /* go to the previous char */
DEF(simple_greedy_quant, 17) DEF(simple_greedy_quant, 17)

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* /*
* Regular Expression Engine * Regular Expression Engine
* *
* Copyright (c) 2017-2018 Fabrice Bellard * Copyright (c) 2017-2018 Fabrice Bellard
* *
* 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
@ -28,16 +28,21 @@
#include "libunicode.h" #include "libunicode.h"
#ifdef __cplusplus
extern "C" {
#endif
#define LRE_BOOL int /* for documentation purposes */ #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)
#define LRE_FLAG_MULTILINE (1 << 2) #define LRE_FLAG_MULTILINE (1 << 2)
#define LRE_FLAG_DOTALL (1 << 3) #define LRE_FLAG_DOTALL (1 << 3)
#define LRE_FLAG_UTF16 (1 << 4) #define LRE_FLAG_UNICODE (1 << 4)
#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_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,
@ -48,13 +53,14 @@ const char *lre_get_groupnames(const uint8_t *bc_buf);
int lre_exec(uint8_t **capture, int lre_exec(uint8_t **capture,
const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen, const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen,
int cbuf_type, void *opaque); int cbuf_type, void *opaque);
void lre_byte_swap(uint8_t *bc_buf, int bc_buf_len);
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); 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 */ /* must be provided by the user */
LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size); 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 */ /* JS identifier test */
@ -66,11 +72,7 @@ static inline int lre_js_is_ident_first(int c)
if ((uint32_t)c < 128) { if ((uint32_t)c < 128) {
return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1; return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1;
} else { } else {
#ifdef CONFIG_ALL_UNICODE
return lre_is_id_start(c); return lre_is_id_start(c);
#else
return !lre_is_space(c);
#endif
} }
} }
@ -80,14 +82,14 @@ static inline int lre_js_is_ident_next(int c)
return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1; return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1;
} else { } else {
/* ZWNJ and ZWJ are accepted in identifiers */ /* ZWNJ and ZWJ are accepted in identifiers */
#ifdef CONFIG_ALL_UNICODE
return lre_is_id_continue(c) || c == 0x200C || c == 0x200D; return lre_is_id_continue(c) || c == 0x200C || c == 0x200D;
#else
return !lre_is_space(c) || c == 0x200C || c == 0x200D;
#endif
} }
} }
#undef LRE_BOOL #undef LRE_BOOL
#ifdef __cplusplus
} /* extern "C" { */
#endif
#endif /* LIBREGEXP_H */ #endif /* LIBREGEXP_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
/* /*
* Unicode utilities * Unicode utilities
* *
* Copyright (c) 2017-2018 Fabrice Bellard * Copyright (c) 2017-2018 Fabrice Bellard
* *
* 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
@ -43,15 +43,115 @@ enum {
RUN_TYPE_UF_D1_EXT, RUN_TYPE_UF_D1_EXT,
RUN_TYPE_U_EXT, RUN_TYPE_U_EXT,
RUN_TYPE_LF_EXT, RUN_TYPE_LF_EXT,
RUN_TYPE_U_EXT2, RUN_TYPE_UF_EXT2,
RUN_TYPE_L_EXT2, RUN_TYPE_LF_EXT2,
RUN_TYPE_U_EXT3, RUN_TYPE_UF_EXT3,
}; };
static int lre_case_conv1(uint32_t c, int conv_type)
{
uint32_t res[LRE_CC_RES_LEN_MAX];
lre_case_conv(res, c, conv_type);
return res[0];
}
/* case conversion using the table entry 'idx' with value 'v' */
static int lre_case_conv_entry(uint32_t *res, uint32_t c, int conv_type, uint32_t idx, uint32_t v)
{
uint32_t code, data, type, a, is_lower;
is_lower = (conv_type != 0);
type = (v >> (32 - 17 - 7 - 4)) & 0xf;
data = ((v & 0xf) << 8) | case_conv_table2[idx];
code = v >> (32 - 17);
switch(type) {
case RUN_TYPE_U:
case RUN_TYPE_L:
case RUN_TYPE_UF:
case RUN_TYPE_LF:
if (conv_type == (type & 1) ||
(type >= RUN_TYPE_UF && conv_type == 2)) {
c = c - code + (case_conv_table1[data] >> (32 - 17));
}
break;
case RUN_TYPE_UL:
a = c - code;
if ((a & 1) != (1 - is_lower))
break;
c = (a ^ 1) + code;
break;
case RUN_TYPE_LSU:
a = c - code;
if (a == 1) {
c += 2 * is_lower - 1;
} else if (a == (1 - is_lower) * 2) {
c += (2 * is_lower - 1) * 2;
}
break;
case RUN_TYPE_U2L_399_EXT2:
if (!is_lower) {
res[0] = c - code + case_conv_ext[data >> 6];
res[1] = 0x399;
return 2;
} else {
c = c - code + case_conv_ext[data & 0x3f];
}
break;
case RUN_TYPE_UF_D20:
if (conv_type == 1)
break;
c = data + (conv_type == 2) * 0x20;
break;
case RUN_TYPE_UF_D1_EXT:
if (conv_type == 1)
break;
c = case_conv_ext[data] + (conv_type == 2);
break;
case RUN_TYPE_U_EXT:
case RUN_TYPE_LF_EXT:
if (is_lower != (type - RUN_TYPE_U_EXT))
break;
c = case_conv_ext[data];
break;
case RUN_TYPE_LF_EXT2:
if (!is_lower)
break;
res[0] = c - code + case_conv_ext[data >> 6];
res[1] = case_conv_ext[data & 0x3f];
return 2;
case RUN_TYPE_UF_EXT2:
if (conv_type == 1)
break;
res[0] = c - code + case_conv_ext[data >> 6];
res[1] = case_conv_ext[data & 0x3f];
if (conv_type == 2) {
/* convert to lower */
res[0] = lre_case_conv1(res[0], 1);
res[1] = lre_case_conv1(res[1], 1);
}
return 2;
default:
case RUN_TYPE_UF_EXT3:
if (conv_type == 1)
break;
res[0] = case_conv_ext[data >> 8];
res[1] = case_conv_ext[(data >> 4) & 0xf];
res[2] = case_conv_ext[data & 0xf];
if (conv_type == 2) {
/* convert to lower */
res[0] = lre_case_conv1(res[0], 1);
res[1] = lre_case_conv1(res[1], 1);
res[2] = lre_case_conv1(res[2], 1);
}
return 3;
}
res[0] = c;
return 1;
}
/* conv_type: /* conv_type:
0 = to upper 0 = to upper
1 = to lower 1 = to lower
2 = case folding (= to lower with modifications) 2 = case folding (= to lower with modifications)
*/ */
int lre_case_conv(uint32_t *res, uint32_t c, int conv_type) int lre_case_conv(uint32_t *res, uint32_t c, int conv_type)
{ {
@ -66,10 +166,9 @@ int lre_case_conv(uint32_t *res, uint32_t c, int conv_type)
} }
} }
} else { } else {
uint32_t v, code, data, type, len, a, is_lower; uint32_t v, code, len;
int idx, idx_min, idx_max; int idx, idx_min, idx_max;
is_lower = (conv_type != 0);
idx_min = 0; idx_min = 0;
idx_max = countof(case_conv_table1) - 1; idx_max = countof(case_conv_table1) - 1;
while (idx_min <= idx_max) { while (idx_min <= idx_max) {
@ -82,74 +181,7 @@ int lre_case_conv(uint32_t *res, uint32_t c, int conv_type)
} else if (c >= code + len) { } else if (c >= code + len) {
idx_min = idx + 1; idx_min = idx + 1;
} else { } else {
type = (v >> (32 - 17 - 7 - 4)) & 0xf; return lre_case_conv_entry(res, c, conv_type, idx, v);
data = ((v & 0xf) << 8) | case_conv_table2[idx];
switch(type) {
case RUN_TYPE_U:
case RUN_TYPE_L:
case RUN_TYPE_UF:
case RUN_TYPE_LF:
if (conv_type == (type & 1) ||
(type >= RUN_TYPE_UF && conv_type == 2)) {
c = c - code + (case_conv_table1[data] >> (32 - 17));
}
break;
case RUN_TYPE_UL:
a = c - code;
if ((a & 1) != (1 - is_lower))
break;
c = (a ^ 1) + code;
break;
case RUN_TYPE_LSU:
a = c - code;
if (a == 1) {
c += 2 * is_lower - 1;
} else if (a == (1 - is_lower) * 2) {
c += (2 * is_lower - 1) * 2;
}
break;
case RUN_TYPE_U2L_399_EXT2:
if (!is_lower) {
res[0] = c - code + case_conv_ext[data >> 6];
res[1] = 0x399;
return 2;
} else {
c = c - code + case_conv_ext[data & 0x3f];
}
break;
case RUN_TYPE_UF_D20:
if (conv_type == 1)
break;
c = data + (conv_type == 2) * 0x20;
break;
case RUN_TYPE_UF_D1_EXT:
if (conv_type == 1)
break;
c = case_conv_ext[data] + (conv_type == 2);
break;
case RUN_TYPE_U_EXT:
case RUN_TYPE_LF_EXT:
if (is_lower != (type - RUN_TYPE_U_EXT))
break;
c = case_conv_ext[data];
break;
case RUN_TYPE_U_EXT2:
case RUN_TYPE_L_EXT2:
if (conv_type != (type - RUN_TYPE_U_EXT2))
break;
res[0] = c - code + case_conv_ext[data >> 6];
res[1] = case_conv_ext[data & 0x3f];
return 2;
default:
case RUN_TYPE_U_EXT3:
if (conv_type != 0)
break;
res[0] = case_conv_ext[data >> 8];
res[1] = case_conv_ext[(data >> 4) & 0xf];
res[2] = case_conv_ext[data & 0xf];
return 3;
}
break;
} }
} }
} }
@ -157,13 +189,80 @@ int lre_case_conv(uint32_t *res, uint32_t c, int conv_type)
return 1; return 1;
} }
static int lre_case_folding_entry(uint32_t c, uint32_t idx, uint32_t v, BOOL is_unicode)
{
uint32_t res[LRE_CC_RES_LEN_MAX];
int len;
if (is_unicode) {
len = lre_case_conv_entry(res, c, 2, idx, v);
if (len == 1) {
c = res[0];
} else {
/* handle the few specific multi-character cases (see
unicode_gen.c:dump_case_folding_special_cases()) */
if (c == 0xfb06) {
c = 0xfb05;
} else if (c == 0x01fd3) {
c = 0x390;
} else if (c == 0x01fe3) {
c = 0x3b0;
}
}
} else {
if (likely(c < 128)) {
if (c >= 'a' && c <= 'z')
c = c - 'a' + 'A';
} else {
/* legacy regexp: to upper case if single char >= 128 */
len = lre_case_conv_entry(res, c, FALSE, idx, v);
if (len == 1 && res[0] >= 128)
c = res[0];
}
}
return c;
}
/* JS regexp specific rules for case folding */
int lre_canonicalize(uint32_t c, BOOL is_unicode)
{
if (c < 128) {
/* fast case */
if (is_unicode) {
if (c >= 'A' && c <= 'Z') {
c = c - 'A' + 'a';
}
} else {
if (c >= 'a' && c <= 'z') {
c = c - 'a' + 'A';
}
}
} else {
uint32_t v, code, len;
int idx, idx_min, idx_max;
idx_min = 0;
idx_max = countof(case_conv_table1) - 1;
while (idx_min <= idx_max) {
idx = (unsigned)(idx_max + idx_min) / 2;
v = case_conv_table1[idx];
code = v >> (32 - 17);
len = (v >> (32 - 17 - 7)) & 0x7f;
if (c < code) {
idx_max = idx - 1;
} else if (c >= code + len) {
idx_min = idx + 1;
} else {
return lre_case_folding_entry(c, idx, v, is_unicode);
}
}
}
return c;
}
static uint32_t get_le24(const uint8_t *ptr) static uint32_t get_le24(const uint8_t *ptr)
{ {
#if defined(__x86__) || defined(__x86_64__)
return *(uint16_t *)ptr | (ptr[2] << 16);
#else
return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16); return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16);
#endif
} }
#define UNICODE_INDEX_BLOCK_LEN 32 #define UNICODE_INDEX_BLOCK_LEN 32
@ -208,7 +307,7 @@ static BOOL lre_is_in_table(uint32_t c, const uint8_t *table,
uint32_t code, b, bit; uint32_t code, b, bit;
int pos; int pos;
const uint8_t *p; const uint8_t *p;
pos = get_index_pos(&code, c, index_table, index_table_len); pos = get_index_pos(&code, c, index_table, index_table_len);
if (pos < 0) if (pos < 0)
return FALSE; /* outside the table */ return FALSE; /* outside the table */
@ -241,7 +340,7 @@ BOOL lre_is_cased(uint32_t c)
{ {
uint32_t v, code, len; uint32_t v, code, len;
int idx, idx_min, idx_max; int idx, idx_min, idx_max;
idx_min = 0; idx_min = 0;
idx_max = countof(case_conv_table1) - 1; idx_max = countof(case_conv_table1) - 1;
while (idx_min <= idx_max) { while (idx_min <= idx_max) {
@ -300,7 +399,7 @@ int cr_realloc(CharRange *cr, int size)
{ {
int new_size; int new_size;
uint32_t *new_buf; uint32_t *new_buf;
if (size > cr->size) { if (size > cr->size) {
new_size = max_int(size, cr->size * 3 / 2); new_size = max_int(size, cr->size * 3 / 2);
new_buf = cr->realloc_func(cr->mem_opaque, cr->points, new_buf = cr->realloc_func(cr->mem_opaque, cr->points,
@ -327,7 +426,7 @@ static void cr_compress(CharRange *cr)
{ {
int i, j, k, len; int i, j, k, len;
uint32_t *pt; uint32_t *pt;
pt = cr->points; pt = cr->points;
len = cr->len; len = cr->len;
i = 0; i = 0;
@ -357,7 +456,7 @@ int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len,
{ {
int a_idx, b_idx, is_in; int a_idx, b_idx, is_in;
uint32_t v; uint32_t v;
a_idx = 0; a_idx = 0;
b_idx = 0; b_idx = 0;
for(;;) { for(;;) {
@ -430,8 +529,6 @@ 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,
@ -658,7 +755,7 @@ static int unicode_decomp_char(uint32_t *res, uint32_t c, BOOL is_compat1)
{ {
uint32_t v, type, is_compat, code, len; uint32_t v, type, is_compat, code, len;
int idx_min, idx_max, idx; int idx_min, idx_max, idx;
idx_min = 0; idx_min = 0;
idx_max = countof(unicode_decomp_table1) - 1; idx_max = countof(unicode_decomp_table1) - 1;
while (idx_min <= idx_max) { while (idx_min <= idx_max) {
@ -688,7 +785,7 @@ static int unicode_compose_pair(uint32_t c0, uint32_t c1)
uint32_t code, len, type, v, idx1, d_idx, d_offset, ch; uint32_t code, len, type, v, idx1, d_idx, d_offset, ch;
int idx_min, idx_max, idx, d; int idx_min, idx_max, idx, d;
uint32_t pair[2]; uint32_t pair[2];
idx_min = 0; idx_min = 0;
idx_max = countof(unicode_comp_table) - 1; idx_max = countof(unicode_comp_table) - 1;
while (idx_min <= idx_max) { while (idx_min <= idx_max) {
@ -724,7 +821,7 @@ static int unicode_get_cc(uint32_t c)
uint32_t code, n, type, cc, c1, b; uint32_t code, n, type, cc, c1, b;
int pos; int pos;
const uint8_t *p; const uint8_t *p;
pos = get_index_pos(&code, c, pos = get_index_pos(&code, c,
unicode_cc_index, sizeof(unicode_cc_index) / 3); unicode_cc_index, sizeof(unicode_cc_index) / 3);
if (pos < 0) if (pos < 0)
@ -773,7 +870,7 @@ static int unicode_get_cc(uint32_t c)
static void sort_cc(int *buf, int len) static void sort_cc(int *buf, int len)
{ {
int i, j, k, cc, cc1, start, ch1; int i, j, k, cc, cc1, start, ch1;
for(i = 0; i < len; i++) { for(i = 0; i < len; i++) {
cc = unicode_get_cc(buf[i]); cc = unicode_get_cc(buf[i]);
if (cc != 0) { if (cc != 0) {
@ -794,13 +891,6 @@ 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;
} }
} }
@ -812,7 +902,7 @@ static void to_nfd_rec(DynBuf *dbuf,
uint32_t c, v; uint32_t c, v;
int i, l; int i, l;
uint32_t res[UNICODE_DECOMP_LEN_MAX]; uint32_t res[UNICODE_DECOMP_LEN_MAX];
for(i = 0; i < src_len; i++) { for(i = 0; i < src_len; i++) {
c = src[i]; c = src[i];
if (c >= 0xac00 && c < 0xd7a4) { if (c >= 0xac00 && c < 0xd7a4) {
@ -857,7 +947,7 @@ int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
int *buf, buf_len, i, p, starter_pos, cc, last_cc, out_len; int *buf, buf_len, i, p, starter_pos, cc, last_cc, out_len;
BOOL is_compat; BOOL is_compat;
DynBuf dbuf_s, *dbuf = &dbuf_s; DynBuf dbuf_s, *dbuf = &dbuf_s;
is_compat = n_type >> 1; is_compat = n_type >> 1;
dbuf_init2(dbuf, opaque, realloc_func); dbuf_init2(dbuf, opaque, realloc_func);
@ -885,15 +975,15 @@ int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
} }
buf = (int *)dbuf->buf; buf = (int *)dbuf->buf;
buf_len = dbuf->size / sizeof(int); buf_len = dbuf->size / sizeof(int);
sort_cc(buf, buf_len); sort_cc(buf, buf_len);
if (buf_len <= 1 || (n_type & 1) != 0) { if (buf_len <= 1 || (n_type & 1) != 0) {
/* NFD / NFKD */ /* NFD / NFKD */
*pdst = (uint32_t *)buf; *pdst = (uint32_t *)buf;
return buf_len; return buf_len;
} }
i = 1; i = 1;
out_len = 1; out_len = 1;
while (i < buf_len) { while (i < buf_len) {
@ -930,7 +1020,7 @@ static int unicode_find_name(const char *name_table, const char *name)
const char *p, *r; const char *p, *r;
int pos; int pos;
size_t name_len, len; size_t name_len, len;
p = name_table; p = name_table;
pos = 0; pos = 0;
name_len = strlen(name); name_len = strlen(name);
@ -960,16 +1050,16 @@ 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, *cr1; CharRange cr1_s = { 0 }, *cr1 = NULL;
CharRange cr2_s, *cr2 = &cr2_s; CharRange cr2_s = { 0 }, *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);
if (script_idx < 0) if (script_idx < 0)
return -2; return -2;
/* Note: we remove the "Unknown" Script */ /* Note: we remove the "Unknown" Script */
script_idx += UNICODE_SCRIPT_Unknown + 1; script_idx += UNICODE_SCRIPT_Unknown + 1;
is_common = (script_idx == UNICODE_SCRIPT_Common || is_common = (script_idx == UNICODE_SCRIPT_Common ||
script_idx == UNICODE_SCRIPT_Inherited); script_idx == UNICODE_SCRIPT_Inherited);
if (is_ext) { if (is_ext) {
@ -1179,11 +1269,11 @@ static int unicode_case1(CharRange *cr, int case_mask)
#define MR(x) (1 << RUN_TYPE_ ## x) #define MR(x) (1 << RUN_TYPE_ ## x)
const uint32_t tab_run_mask[3] = { const uint32_t tab_run_mask[3] = {
MR(U) | MR(UF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(UF_D20) | MR(U) | MR(UF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(UF_D20) |
MR(UF_D1_EXT) | MR(U_EXT) | MR(U_EXT2) | MR(U_EXT3), MR(UF_D1_EXT) | MR(U_EXT) | MR(UF_EXT2) | MR(UF_EXT3),
MR(L) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(L_EXT2), MR(L) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(LF_EXT2),
MR(UF) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(UF_D20) | MR(UF_D1_EXT) | MR(LF_EXT), MR(UF) | MR(LF) | MR(UL) | MR(LSU) | MR(U2L_399_EXT2) | MR(LF_EXT) | MR(LF_EXT2) | MR(UF_D20) | MR(UF_D1_EXT) | MR(LF_EXT) | MR(UF_EXT2) | MR(UF_EXT3),
}; };
#undef MR #undef MR
uint32_t mask, v, code, type, len, i, idx; uint32_t mask, v, code, type, len, i, idx;
@ -1236,7 +1326,136 @@ static int unicode_case1(CharRange *cr, int case_mask)
} }
return 0; return 0;
} }
static int point_cmp(const void *p1, const void *p2, void *arg)
{
uint32_t v1 = *(uint32_t *)p1;
uint32_t v2 = *(uint32_t *)p2;
return (v1 > v2) - (v1 < v2);
}
static void cr_sort_and_remove_overlap(CharRange *cr)
{
uint32_t start, end, start1, end1, i, j;
/* the resulting ranges are not necessarily sorted and may overlap */
rqsort(cr->points, cr->len / 2, sizeof(cr->points[0]) * 2, point_cmp, NULL);
j = 0;
for(i = 0; i < cr->len; ) {
start = cr->points[i];
end = cr->points[i + 1];
i += 2;
while (i < cr->len) {
start1 = cr->points[i];
end1 = cr->points[i + 1];
if (start1 > end) {
/* |------|
* |-------| */
break;
} else if (end1 <= end) {
/* |------|
* |--| */
i += 2;
} else {
/* |------|
* |-------| */
end = end1;
i += 2;
}
}
cr->points[j] = start;
cr->points[j + 1] = end;
j += 2;
}
cr->len = j;
}
/* canonicalize a character set using the JS regex case folding rules
(see lre_canonicalize()) */
int cr_regexp_canonicalize(CharRange *cr, BOOL is_unicode)
{
CharRange cr_inter, cr_mask, cr_result, cr_sub;
uint32_t v, code, len, i, idx, start, end, c, d_start, d_end, d;
cr_init(&cr_mask, cr->mem_opaque, cr->realloc_func);
cr_init(&cr_inter, cr->mem_opaque, cr->realloc_func);
cr_init(&cr_result, cr->mem_opaque, cr->realloc_func);
cr_init(&cr_sub, cr->mem_opaque, cr->realloc_func);
if (unicode_case1(&cr_mask, is_unicode ? CASE_F : CASE_U))
goto fail;
if (cr_op(&cr_inter, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER))
goto fail;
if (cr_invert(&cr_mask))
goto fail;
if (cr_op(&cr_sub, cr_mask.points, cr_mask.len, cr->points, cr->len, CR_OP_INTER))
goto fail;
/* cr_inter = cr & cr_mask */
/* cr_sub = cr & ~cr_mask */
/* use the case conversion table to compute the result */
d_start = -1;
d_end = -1;
idx = 0;
v = case_conv_table1[idx];
code = v >> (32 - 17);
len = (v >> (32 - 17 - 7)) & 0x7f;
for(i = 0; i < cr_inter.len; i += 2) {
start = cr_inter.points[i];
end = cr_inter.points[i + 1];
for(c = start; c < end; c++) {
for(;;) {
if (c >= code && c < code + len)
break;
idx++;
assert(idx < countof(case_conv_table1));
v = case_conv_table1[idx];
code = v >> (32 - 17);
len = (v >> (32 - 17 - 7)) & 0x7f;
}
d = lre_case_folding_entry(c, idx, v, is_unicode);
/* try to merge with the current interval */
if (d_start == -1) {
d_start = d;
d_end = d + 1;
} else if (d_end == d) {
d_end++;
} else {
cr_add_interval(&cr_result, d_start, d_end);
d_start = d;
d_end = d + 1;
}
}
}
if (d_start != -1) {
if (cr_add_interval(&cr_result, d_start, d_end))
goto fail;
}
/* the resulting ranges are not necessarily sorted and may overlap */
cr_sort_and_remove_overlap(&cr_result);
/* or with the character not affected by the case folding */
cr->len = 0;
if (cr_op(cr, cr_result.points, cr_result.len, cr_sub.points, cr_sub.len, CR_OP_UNION))
goto fail;
cr_free(&cr_inter);
cr_free(&cr_mask);
cr_free(&cr_result);
cr_free(&cr_sub);
return 0;
fail:
cr_free(&cr_inter);
cr_free(&cr_mask);
cr_free(&cr_result);
cr_free(&cr_sub);
return -1;
}
typedef enum { typedef enum {
POP_GC, POP_GC,
POP_PROP, POP_PROP,
@ -1256,7 +1475,7 @@ static int unicode_prop_ops(CharRange *cr, ...)
CharRange stack[POP_STACK_LEN_MAX]; CharRange stack[POP_STACK_LEN_MAX];
int stack_len, op, ret, i; int stack_len, op, ret, i;
uint32_t a; uint32_t a;
va_start(ap, cr); va_start(ap, cr);
stack_len = 0; stack_len = 0;
for(;;) { for(;;) {
@ -1342,7 +1561,7 @@ int unicode_general_category(CharRange *cr, const char *gc_name)
{ {
int gc_idx; int gc_idx;
uint32_t gc_mask; uint32_t gc_mask;
gc_idx = unicode_find_name(unicode_gc_name_table, gc_name); gc_idx = unicode_find_name(unicode_gc_name_table, gc_name);
if (gc_idx < 0) if (gc_idx < 0)
return -2; return -2;
@ -1360,7 +1579,7 @@ 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)
{ {
int prop_idx, ret; int prop_idx, ret;
prop_idx = unicode_find_name(unicode_prop_name_table, prop_name); prop_idx = unicode_find_name(unicode_prop_name_table, prop_name);
if (prop_idx < 0) if (prop_idx < 0)
return -2; return -2;
@ -1499,42 +1718,6 @@ 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,
@ -1543,7 +1726,6 @@ 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;
@ -1552,5 +1734,3 @@ int unicode_prop(CharRange *cr, const char *prop_name)
} }
return ret; return ret;
} }
#endif /* CONFIG_ALL_UNICODE */

View File

@ -1,6 +1,6 @@
/* /*
* Unicode utilities * Unicode utilities
* *
* Copyright (c) 2017-2018 Fabrice Bellard * Copyright (c) 2017-2018 Fabrice Bellard
* *
* 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
@ -24,12 +24,14 @@
#ifndef LIBUNICODE_H #ifndef LIBUNICODE_H
#define LIBUNICODE_H #define LIBUNICODE_H
#include <stddef.h>
#include <inttypes.h> #include <inttypes.h>
#define LRE_BOOL int /* for documentation purposes */ #ifdef __cplusplus
extern "C" {
#endif
/* define it to include all the unicode tables (40KB larger) */ #define LRE_BOOL int /* for documentation purposes */
#define CONFIG_ALL_UNICODE
#define LRE_CC_RES_LEN_MAX 3 #define LRE_CC_RES_LEN_MAX 3
@ -41,6 +43,7 @@ typedef enum {
} UnicodeNormalizationEnum; } UnicodeNormalizationEnum;
int lre_case_conv(uint32_t *res, uint32_t c, int conv_type); 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_cased(uint32_t c);
LRE_BOOL lre_is_case_ignorable(uint32_t c); LRE_BOOL lre_is_case_ignorable(uint32_t c);
@ -100,8 +103,7 @@ 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);
#ifdef CONFIG_ALL_UNICODE
LRE_BOOL lre_is_id_start(uint32_t c); LRE_BOOL lre_is_id_start(uint32_t c);
LRE_BOOL lre_is_id_continue(uint32_t c); LRE_BOOL lre_is_id_continue(uint32_t c);
@ -117,8 +119,10 @@ int unicode_script(CharRange *cr,
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);
#endif /* CONFIG_ALL_UNICODE */
#undef LRE_BOOL #undef LRE_BOOL
#ifdef __cplusplus
} /* extern "C" { */
#endif
#endif /* LIBUNICODE_H */ #endif /* LIBUNICODE_H */

View File

@ -1,6 +1,6 @@
/* /*
* Linux klist like system * Linux klist like system
* *
* Copyright (c) 2016-2017 Fabrice Bellard * Copyright (c) 2016-2017 Fabrice Bellard
* *
* 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
@ -28,6 +28,10 @@
#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;
@ -36,8 +40,7 @@ struct list_head {
#define LIST_HEAD_INIT(el) { &(el), &(el) } #define LIST_HEAD_INIT(el) { &(el), &(el) }
/* return the pointer of type 'type *' containing 'el' as field 'member' */ /* return the pointer of type 'type *' containing 'el' as field 'member' */
#define list_entry(el, type, member) \ #define list_entry(el, type, member) container_of(el, type, member)
((type *)((uint8_t *)(el) - offsetof(type, member)))
static inline void init_list_head(struct list_head *head) static inline void init_list_head(struct list_head *head)
{ {
@ -45,13 +48,8 @@ static inline void init_list_head(struct list_head *head)
head->next = head; head->next = head;
} }
static inline int list_empty(const struct list_head *el)
{
return el->next == el;
}
/* insert 'el' between 'prev' and 'next' */ /* insert 'el' between 'prev' and 'next' */
static inline void __list_add(struct list_head *el, static inline void __list_add(struct list_head *el,
struct list_head *prev, struct list_head *next) struct list_head *prev, struct list_head *next)
{ {
prev->next = el; prev->next = el;
@ -72,20 +70,6 @@ static inline void list_add_tail(struct list_head *el, struct list_head *head)
__list_add(el, head->prev, head); __list_add(el, head->prev, head);
} }
static inline void list_splice(const struct list_head *list,
struct list_head *head)
{
if (!list_empty(list)) {
struct list_head *a = list->next;
struct list_head *b = list->prev;
struct list_head *c = head->next;
head->next = a;
a->prev = head;
b->next = c;
c->prev = b;
}
}
static inline void list_del(struct list_head *el) static inline void list_del(struct list_head *el)
{ {
struct list_head *prev, *next; struct list_head *prev, *next;
@ -97,6 +81,11 @@ static inline void list_del(struct list_head *el)
el->next = NULL; /* fail safe */ el->next = NULL; /* fail safe */
} }
static inline int list_empty(struct list_head *el)
{
return el->next == el;
}
#define list_for_each(el, head) \ #define list_for_each(el, head) \
for(el = (head)->next; el != (head); el = el->next) for(el = (head)->next; el != (head); el = el->next)
@ -111,4 +100,8 @@ static inline void list_del(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 */

View File

@ -1,6 +1,6 @@
/* /*
* QuickJS atom definitions * QuickJS atom definitions
* *
* Copyright (c) 2017-2018 Fabrice Bellard * Copyright (c) 2017-2018 Fabrice Bellard
* Copyright (c) 2017-2018 Charlie Gordon * Copyright (c) 2017-2018 Charlie Gordon
* *
@ -78,13 +78,13 @@ 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(errors, "errors") DEF(errors, "errors")
DEF(stack, "stack") DEF(stack, "stack")
DEF(prepareStackTrace, "prepareStackTrace")
DEF(name, "name") DEF(name, "name")
DEF(toString, "toString") DEF(toString, "toString")
DEF(toLocaleString, "toLocaleString") DEF(toLocaleString, "toLocaleString")
@ -167,22 +167,14 @@ DEF(revoke, "revoke")
DEF(async, "async") DEF(async, "async")
DEF(exec, "exec") DEF(exec, "exec")
DEF(groups, "groups") DEF(groups, "groups")
DEF(indices, "indices")
DEF(status, "status") DEF(status, "status")
DEF(reason, "reason") DEF(reason, "reason")
DEF(globalThis, "globalThis") DEF(globalThis, "globalThis")
#ifdef CONFIG_BIGNUM
DEF(bigint, "bigint") DEF(bigint, "bigint")
DEF(bigfloat, "bigfloat")
DEF(bigdecimal, "bigdecimal")
DEF(roundingMode, "roundingMode")
DEF(maximumSignificantDigits, "maximumSignificantDigits")
DEF(maximumFractionDigits, "maximumFractionDigits")
#endif
#ifdef 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")
#endif
DEF(toJSON, "toJSON") DEF(toJSON, "toJSON")
/* class names */ /* class names */
DEF(Object, "Object") DEF(Object, "Object")
@ -203,32 +195,27 @@ DEF(RegExp, "RegExp")
DEF(ArrayBuffer, "ArrayBuffer") DEF(ArrayBuffer, "ArrayBuffer")
DEF(SharedArrayBuffer, "SharedArrayBuffer") DEF(SharedArrayBuffer, "SharedArrayBuffer")
/* must keep same order as class IDs for typed arrays */ /* must keep same order as class IDs for typed arrays */
DEF(Uint8ClampedArray, "Uint8ClampedArray") DEF(Uint8ClampedArray, "Uint8ClampedArray")
DEF(Int8Array, "Int8Array") DEF(Int8Array, "Int8Array")
DEF(Uint8Array, "Uint8Array") DEF(Uint8Array, "Uint8Array")
DEF(Int16Array, "Int16Array") DEF(Int16Array, "Int16Array")
DEF(Uint16Array, "Uint16Array") DEF(Uint16Array, "Uint16Array")
DEF(Int32Array, "Int32Array") DEF(Int32Array, "Int32Array")
DEF(Uint32Array, "Uint32Array") DEF(Uint32Array, "Uint32Array")
#ifdef CONFIG_BIGNUM
DEF(BigInt64Array, "BigInt64Array") DEF(BigInt64Array, "BigInt64Array")
DEF(BigUint64Array, "BigUint64Array") DEF(BigUint64Array, "BigUint64Array")
#endif DEF(Float16Array, "Float16Array")
DEF(Float32Array, "Float32Array") DEF(Float32Array, "Float32Array")
DEF(Float64Array, "Float64Array") DEF(Float64Array, "Float64Array")
DEF(DataView, "DataView") DEF(DataView, "DataView")
#ifdef CONFIG_BIGNUM
DEF(BigInt, "BigInt") DEF(BigInt, "BigInt")
DEF(BigFloat, "BigFloat") DEF(WeakRef, "WeakRef")
DEF(BigFloatEnv, "BigFloatEnv") DEF(FinalizationRegistry, "FinalizationRegistry")
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(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")
@ -251,6 +238,7 @@ 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 */
@ -267,8 +255,5 @@ 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 */

View File

@ -0,0 +1,54 @@
/*
* 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

View File

@ -1,6 +1,6 @@
/* /*
* QuickJS C library * QuickJS C library
* *
* Copyright (c) 2017-2018 Fabrice Bellard * Copyright (c) 2017-2018 Fabrice Bellard
* *
* 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
@ -35,23 +35,26 @@ 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);
void js_std_loop(JSContext *ctx); JSValue js_std_loop(JSContext *ctx);
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);
void js_std_dump_error1(JSContext *ctx, JSValue exception_val);
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, JSValueConst func_val, int js_module_set_import_meta(JSContext *ctx, JSValue 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, JSValueConst promise, void js_std_promise_rejection_tracker(JSContext *ctx, JSValue promise,
JSValueConst reason, JSValue 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));
#ifdef __cplusplus #ifdef __cplusplus
} /* extern "C" { */ } /* extern "C" { */
#endif #endif

View File

@ -1,6 +1,6 @@
/* /*
* QuickJS opcode definitions * QuickJS opcode definitions
* *
* Copyright (c) 2017-2018 Fabrice Bellard * Copyright (c) 2017-2018 Fabrice Bellard
* Copyright (c) 2017-2018 Charlie Gordon * Copyright (c) 2017-2018 Charlie Gordon
* *
@ -44,6 +44,7 @@ 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)
@ -135,9 +136,12 @@ 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 */
@ -165,14 +169,14 @@ DEF( set_loc, 3, 1, 1, loc) /* must come after put_loc */
DEF( get_arg, 3, 0, 1, arg) DEF( get_arg, 3, 0, 1, arg)
DEF( put_arg, 3, 1, 0, arg) /* must come after get_arg */ DEF( put_arg, 3, 1, 0, arg) /* must come after get_arg */
DEF( set_arg, 3, 1, 1, arg) /* must come after put_arg */ DEF( set_arg, 3, 1, 1, arg) /* must come after put_arg */
DEF( get_var_ref, 3, 0, 1, var_ref) DEF( get_var_ref, 3, 0, 1, var_ref)
DEF( put_var_ref, 3, 1, 0, var_ref) /* must come after get_var_ref */ DEF( put_var_ref, 3, 1, 0, var_ref) /* must come after get_var_ref */
DEF( set_var_ref, 3, 1, 1, var_ref) /* must come after put_var_ref */ DEF( set_var_ref, 3, 1, 1, var_ref) /* must come after put_var_ref */
DEF(set_loc_uninitialized, 3, 0, 0, loc) 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_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)
DEF( close_loc, 3, 0, 0, loc) DEF( close_loc, 3, 0, 0, loc)
@ -182,6 +186,7 @@ DEF( goto, 5, 0, 0, label) /* must come after if_true */
DEF( catch, 5, 0, 1, label) DEF( catch, 5, 0, 1, label)
DEF( gosub, 5, 0, 0, label) /* used to execute the finally block */ DEF( gosub, 5, 0, 0, label) /* used to execute the finally block */
DEF( ret, 1, 1, 0, none) /* used to return from the finally block */ DEF( ret, 1, 1, 0, none) /* used to return from the finally block */
DEF( nip_catch, 1, 2, 1, none) /* catch ... a -> a */
DEF( to_object, 1, 1, 1, none) DEF( to_object, 1, 1, 1, none)
//DEF( to_string, 1, 1, 1, none) //DEF( to_string, 1, 1, 1, none)
@ -208,7 +213,6 @@ DEF( for_of_next, 2, 3, 5, u8)
DEF(iterator_check_object, 1, 1, 1, none) DEF(iterator_check_object, 1, 1, 1, none)
DEF(iterator_get_value_done, 1, 1, 2, none) DEF(iterator_get_value_done, 1, 1, 2, none)
DEF( iterator_close, 1, 3, 0, none) DEF( iterator_close, 1, 3, 0, none)
DEF(iterator_close_return, 1, 4, 4, none)
DEF( iterator_next, 1, 4, 4, none) DEF( iterator_next, 1, 4, 4, none)
DEF( iterator_call, 2, 4, 5, u8) DEF( iterator_call, 2, 4, 5, u8)
DEF( initial_yield, 1, 0, 0, none) DEF( initial_yield, 1, 0, 0, none)
@ -233,15 +237,20 @@ 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)
@ -252,16 +261,10 @@ 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)
#ifdef CONFIG_BIGNUM DEF( private_in, 1, 2, 1, none)
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)
/* temporary opcodes: never emitted in the final bytecode */ /* temporary opcodes: never emitted in the final bytecode */
@ -279,13 +282,14 @@ def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase
def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */ def(scope_get_private_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, 1, 1, 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 */
def(scope_in_private_field, 7, 1, 1, atom_u16) /* obj -> res emitted in phase 1, removed in phase 2 */
def(get_field_opt_chain, 5, 1, 1, atom) /* 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( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
#if SHORT_OPCODES def( source_loc, 9, 0, 0, u32x2) /* emitted in phase 1, removed in phase 3 */
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)
@ -305,6 +309,7 @@ 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)
@ -358,7 +363,11 @@ 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -105,6 +105,7 @@ DEF(Javanese, "Java")
DEF(Kaithi, "Kthi") DEF(Kaithi, "Kthi")
DEF(Kannada, "Knda") DEF(Kannada, "Knda")
DEF(Katakana, "Kana") DEF(Katakana, "Kana")
DEF(Kawi, "Kawi")
DEF(Kayah_Li, "Kali") DEF(Kayah_Li, "Kali")
DEF(Kharoshthi, "Khar") DEF(Kharoshthi, "Khar")
DEF(Khmer, "Khmr") DEF(Khmer, "Khmr")
@ -139,6 +140,7 @@ DEF(Mro, "Mroo")
DEF(Multani, "Mult") DEF(Multani, "Mult")
DEF(Myanmar, "Mymr") DEF(Myanmar, "Mymr")
DEF(Nabataean, "Nbat") DEF(Nabataean, "Nbat")
DEF(Nag_Mundari, "Nagm")
DEF(Nandinagari, "Nand") DEF(Nandinagari, "Nand")
DEF(New_Tai_Lue, "Talu") DEF(New_Tai_Lue, "Talu")
DEF(Newa, "Newa") DEF(Newa, "Newa")

View File

@ -1,6 +1,8 @@
#!/bin/sh #!/bin/sh
cp -f dist/plugins-cfg/plugins.mingw.cfg plugins.cfg cp -f dist/plugins-cfg/plugins.mingw.cfg plugins.cfg
export CC=x86_64-w64-mingw32-gcc export CC=x86_64-w64-mingw32-gcc
export CFLAGS="-pthread"
./configure --with-ostype=windows --with-compiler=x86_64-w64-mingw32-gcc --prefix=/ || exit 1 ./configure --with-ostype=windows --with-compiler=x86_64-w64-mingw32-gcc --prefix=/ || exit 1
make -j4 || exit 1 make -j4 || exit 1
# install # install

View File

@ -10,10 +10,10 @@ EXPECT=<<EOF
123 123
EOF EOF
EXPECT_ERR=<<EOF EXPECT_ERR=<<EOF
ERROR: ReferenceError: 'a' is not defined ERROR: ReferenceError: a is not defined
ERROR: at <eval> (-) ERROR: at <eval> (-:1:1)
ERROR: null ERROR: [uninitialized]
EOF EOF
RUN RUN