remove versioned quickjs
This commit is contained in:
parent
b8af92a138
commit
89fe5e4f34
|
@ -1,148 +0,0 @@
|
||||||
2021-03-27:
|
|
||||||
|
|
||||||
- faster Array.prototype.push and Array.prototype.unshift
|
|
||||||
- added JS_UpdateStackTop()
|
|
||||||
- fixed Windows console
|
|
||||||
- misc bug fixes
|
|
||||||
|
|
||||||
2020-11-08:
|
|
||||||
|
|
||||||
- improved function parameter initializers
|
|
||||||
- added std.setenv(), std.unsetenv() and std.getenviron()
|
|
||||||
- added JS_EvalThis()
|
|
||||||
- misc bug fixes
|
|
||||||
|
|
||||||
2020-09-06:
|
|
||||||
|
|
||||||
- added logical assignment operators
|
|
||||||
- added IsHTMLDDA support
|
|
||||||
- faster for-of loops
|
|
||||||
- os.Worker now takes a module filename as parameter
|
|
||||||
- qjsc: added -D option to compile dynamically loaded modules or workers
|
|
||||||
- misc bug fixes
|
|
||||||
|
|
||||||
2020-07-05:
|
|
||||||
|
|
||||||
- modified JS_GetPrototype() to return a live value
|
|
||||||
- REPL: support unicode characters larger than 16 bits
|
|
||||||
- added os.Worker
|
|
||||||
- improved object serialization
|
|
||||||
- added std.parseExtJSON
|
|
||||||
- misc bug fixes
|
|
||||||
|
|
||||||
2020-04-12:
|
|
||||||
|
|
||||||
- added cross realm support
|
|
||||||
- added AggregateError and Promise.any
|
|
||||||
- added env, uid and gid options in os.exec()
|
|
||||||
- misc bug fixes
|
|
||||||
|
|
||||||
2020-03-16:
|
|
||||||
|
|
||||||
- reworked error handling in std and os libraries: suppressed I/O
|
|
||||||
exceptions in std FILE functions and return a positive errno value
|
|
||||||
when it is explicit
|
|
||||||
- output exception messages to stderr
|
|
||||||
- added std.loadFile(), std.strerror(), std.FILE.prototype.tello()
|
|
||||||
- added JS_GetRuntimeOpaque(), JS_SetRuntimeOpaque(), JS_NewUint32()
|
|
||||||
- updated to Unicode 13.0.0
|
|
||||||
- misc bug fixes
|
|
||||||
|
|
||||||
2020-01-19:
|
|
||||||
|
|
||||||
- keep CONFIG_BIGNUM in the makefile
|
|
||||||
- added os.chdir()
|
|
||||||
- qjs: added -I option
|
|
||||||
- more memory checks in the bignum operations
|
|
||||||
- modified operator overloading semantics to be closer to the TC39
|
|
||||||
proposal
|
|
||||||
- suppressed "use bigint" mode. Simplified "use math" mode
|
|
||||||
- BigDecimal: changed suffix from 'd' to 'm'
|
|
||||||
- misc bug fixes
|
|
||||||
|
|
||||||
2020-01-05:
|
|
||||||
|
|
||||||
- always compile the bignum code. Added '--bignum' option to qjs.
|
|
||||||
- added BigDecimal
|
|
||||||
- added String.prototype.replaceAll
|
|
||||||
- misc bug fixes
|
|
||||||
|
|
||||||
2019-12-21:
|
|
||||||
|
|
||||||
- added nullish coalescing operator (ES2020)
|
|
||||||
- added optional chaining (ES2020)
|
|
||||||
- removed recursions in garbage collector
|
|
||||||
- test stack overflow in the parser
|
|
||||||
- improved backtrace logic
|
|
||||||
- added JS_SetHostPromiseRejectionTracker()
|
|
||||||
- allow exotic constructors
|
|
||||||
- improved c++ compatibility
|
|
||||||
- misc bug fixes
|
|
||||||
|
|
||||||
2019-10-27:
|
|
||||||
|
|
||||||
- added example of C class in a module (examples/test_point.js)
|
|
||||||
- added JS_GetTypedArrayBuffer()
|
|
||||||
- misc bug fixes
|
|
||||||
|
|
||||||
2019-09-18:
|
|
||||||
|
|
||||||
- added os.exec and other system calls
|
|
||||||
- exported JS_ValueToAtom()
|
|
||||||
- qjsc: added 'qjsc_' prefix to the generated C identifiers
|
|
||||||
- added cross-compilation support
|
|
||||||
- misc bug fixes
|
|
||||||
|
|
||||||
2019-09-01:
|
|
||||||
|
|
||||||
- added globalThis
|
|
||||||
- documented JS_EVAL_FLAG_COMPILE_ONLY
|
|
||||||
- added import.meta.url and import.meta.main
|
|
||||||
- added 'debugger' statement
|
|
||||||
- misc bug fixes
|
|
||||||
|
|
||||||
2019-08-18:
|
|
||||||
|
|
||||||
- added os.realpath, os.getcwd, os.mkdir, os.stat, os.lstat,
|
|
||||||
os.readlink, os.readdir, os.utimes, std.popen
|
|
||||||
- module autodetection
|
|
||||||
- added import.meta
|
|
||||||
- misc bug fixes
|
|
||||||
|
|
||||||
2019-08-10:
|
|
||||||
|
|
||||||
- added public class fields and private class fields, methods and
|
|
||||||
accessors (TC39 proposal)
|
|
||||||
- changed JS_ToCStringLen() prototype
|
|
||||||
- qjsc: handle '-' in module names and modules with the same filename
|
|
||||||
- added std.urlGet
|
|
||||||
- exported JS_GetOwnPropertyNames() and JS_GetOwnProperty()
|
|
||||||
- exported some bigint C functions
|
|
||||||
- added support for eshost in run-test262
|
|
||||||
- misc bug fixes
|
|
||||||
|
|
||||||
2019-07-28:
|
|
||||||
|
|
||||||
- added dynamic import
|
|
||||||
- added Promise.allSettled
|
|
||||||
- added String.prototype.matchAll
|
|
||||||
- added Object.fromEntries
|
|
||||||
- reduced number of ticks in await
|
|
||||||
- added BigInt support in Atomics
|
|
||||||
- exported JS_NewPromiseCapability()
|
|
||||||
- misc async function and async generator fixes
|
|
||||||
- enabled hashbang support by default
|
|
||||||
|
|
||||||
2019-07-21:
|
|
||||||
|
|
||||||
- updated test262 tests
|
|
||||||
- updated to Unicode version 12.1.0
|
|
||||||
- fixed missing Date object in qjsc
|
|
||||||
- fixed multi-context creation
|
|
||||||
- misc ES2020 related fixes
|
|
||||||
- simplified power and division operators in bignum extension
|
|
||||||
- fixed several crash conditions
|
|
||||||
|
|
||||||
2019-07-09:
|
|
||||||
|
|
||||||
- first public release
|
|
|
@ -1,22 +0,0 @@
|
||||||
QuickJS Javascript Engine
|
|
||||||
|
|
||||||
Copyright (c) 2017-2021 Fabrice Bellard
|
|
||||||
Copyright (c) 2017-2021 Charlie Gordon
|
|
||||||
|
|
||||||
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.
|
|
486
quickjs/Makefile
486
quickjs/Makefile
|
@ -1,486 +0,0 @@
|
||||||
#
|
|
||||||
# QuickJS Javascript Engine
|
|
||||||
#
|
|
||||||
# Copyright (c) 2017-2021 Fabrice Bellard
|
|
||||||
# Copyright (c) 2017-2021 Charlie Gordon
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
ifeq ($(shell uname -s),Darwin)
|
|
||||||
ifeq ($(HOST_CC),clang)
|
|
||||||
CFLAGS += -arch $(ARCH)
|
|
||||||
endif
|
|
||||||
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
|
|
||||||
|
|
||||||
# use clang instead of gcc
|
|
||||||
ifeq ($(HOST_CC),clang)
|
|
||||||
CONFIG_CLANG=y
|
|
||||||
CONFIG_DEFAULT_AR=y
|
|
||||||
endif
|
|
||||||
|
|
||||||
|
|
||||||
# installation directory
|
|
||||||
prefix=/usr/local
|
|
||||||
|
|
||||||
# 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
|
|
||||||
|
|
||||||
OBJDIR=.obj
|
|
||||||
|
|
||||||
ifdef CONFIG_WIN32
|
|
||||||
ifdef CONFIG_M32
|
|
||||||
CROSS_PREFIX=i686-w64-mingw32-
|
|
||||||
else
|
|
||||||
CROSS_PREFIX=x86_64-w64-mingw32-
|
|
||||||
endif
|
|
||||||
EXE=.exe
|
|
||||||
else
|
|
||||||
CROSS_PREFIX=
|
|
||||||
EXE=
|
|
||||||
endif
|
|
||||||
ifeq ($(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 += -Wno-unused-function -Wno-unused-const-variable
|
|
||||||
CFLAGS += -Wundef -Wuninitialized
|
|
||||||
CFLAGS += -Wunused -Wno-unused-parameter
|
|
||||||
CFLAGS += -Wwrite-strings
|
|
||||||
CFLAGS += -Wchar-subscripts -funsigned-char
|
|
||||||
CFLAGS += -MMD -MF $(OBJDIR)/$(@F).d
|
|
||||||
ifneq ($(TTARGET),)
|
|
||||||
CFLAGS += --target=$(TTARGET)
|
|
||||||
CFLAGS += -isysroot $(SYSRT)
|
|
||||||
endif
|
|
||||||
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
|
|
||||||
CC=$(CROSS_PREFIX)gcc
|
|
||||||
CFLAGS += -g -Wall -MMD -MF $(OBJDIR)/$(@F).d
|
|
||||||
CFLAGS += -Wno-array-bounds -Wno-format-truncation
|
|
||||||
CFLAGS += -Wno-unused-function -Wno-unused-const-variable
|
|
||||||
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)\"
|
|
||||||
ifdef CONFIG_BIGNUM
|
|
||||||
DEFINES+=-DCONFIG_BIGNUM
|
|
||||||
endif
|
|
||||||
ifdef CONFIG_WIN32
|
|
||||||
DEFINES+=-D__USE_MINGW_ANSI_STDIO # for standard snprintf behavior
|
|
||||||
endif
|
|
||||||
|
|
||||||
CFLAGS+=$(DEFINES)
|
|
||||||
CFLAGS_DEBUG=$(CFLAGS) -O0
|
|
||||||
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
|
|
||||||
|
|
||||||
ifeq ($(OPT), small)
|
|
||||||
USEFLAGS = $(CFLAGS_SMALL)
|
|
||||||
else ifeq ($(OPT), 1)
|
|
||||||
USEFLAGS = $(CFLAGS_OPT)
|
|
||||||
else
|
|
||||||
USEFLAGS = $(CFLAGS_DEBUG)
|
|
||||||
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
|
|
||||||
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:
|
|
||||||
rm -f repl.c qjscalc.c out.c
|
|
||||||
rm -f *.a *.o *.d *~ unicode_gen regexp_test $(PROGS)
|
|
||||||
rm -f hello.c test_fib.c
|
|
||||||
rm -f examples/*.so tests/*.so
|
|
||||||
rm -rf $(OBJDIR)/ *.dSYM/ qjs-debug
|
|
||||||
rm -rf run-test262-debug run-test262-32
|
|
||||||
|
|
||||||
install: all
|
|
||||||
mkdir -p "$(DESTDIR)$(prefix)/bin"
|
|
||||||
$(STRIP) qjs qjsc
|
|
||||||
install -m755 qjs qjsc "$(DESTDIR)$(prefix)/bin"
|
|
||||||
ln -sf qjs "$(DESTDIR)$(prefix)/bin/qjscalc"
|
|
||||||
mkdir -p "$(DESTDIR)$(prefix)/lib/quickjs"
|
|
||||||
install -m644 libquickjs.a "$(DESTDIR)$(prefix)/lib/quickjs"
|
|
||||||
ifdef CONFIG_LTO
|
|
||||||
install -m644 libquickjs.lto.a "$(DESTDIR)$(prefix)/lib/quickjs"
|
|
||||||
endif
|
|
||||||
mkdir -p "$(DESTDIR)$(prefix)/include/quickjs"
|
|
||||||
install -m644 quickjs.h quickjs-libc.h "$(DESTDIR)$(prefix)/include/quickjs"
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# examples
|
|
||||||
|
|
||||||
# example of static JS compilation
|
|
||||||
HELLO_SRCS=examples/hello.js
|
|
||||||
HELLO_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \
|
|
||||||
-fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \
|
|
||||||
-fno-date -fno-module-loader
|
|
||||||
ifdef CONFIG_BIGNUM
|
|
||||||
HELLO_OPTS+=-fno-bigint
|
|
||||||
endif
|
|
||||||
|
|
||||||
hello.c: $(QJSC) $(HELLO_SRCS)
|
|
||||||
$(QJSC) -e $(HELLO_OPTS) -o $@ $(HELLO_SRCS)
|
|
||||||
|
|
||||||
ifdef CONFIG_M32
|
|
||||||
examples/hello: $(OBJDIR)/hello.m32s.o $(patsubst %.o, %.m32s.o, $(QJS_LIB_OBJS))
|
|
||||||
$(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS)
|
|
||||||
else
|
|
||||||
examples/hello: $(OBJDIR)/hello.o $(QJS_LIB_OBJS)
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
|
||||||
endif
|
|
||||||
|
|
||||||
# example of static JS compilation with modules
|
|
||||||
HELLO_MODULE_SRCS=examples/hello_module.js
|
|
||||||
HELLO_MODULE_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \
|
|
||||||
-fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \
|
|
||||||
-fno-date -m
|
|
||||||
examples/hello_module: $(QJSC) libquickjs$(LTOEXT).a $(HELLO_MODULE_SRCS)
|
|
||||||
$(QJSC) $(HELLO_MODULE_OPTS) -o $@ $(HELLO_MODULE_SRCS)
|
|
||||||
|
|
||||||
# use of an external C module (static compilation)
|
|
||||||
|
|
||||||
test_fib.c: $(QJSC) examples/test_fib.js
|
|
||||||
$(QJSC) -e -M examples/fib.so,fib -m -o $@ examples/test_fib.js
|
|
||||||
|
|
||||||
examples/test_fib: $(OBJDIR)/test_fib.o $(OBJDIR)/examples/fib.o libquickjs$(LTOEXT).a
|
|
||||||
$(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
|
|
||||||
|
|
||||||
examples/fib.so: $(OBJDIR)/examples/fib.pic.o
|
|
||||||
$(CC) $(LDFLAGS) -shared -o $@ $^
|
|
||||||
|
|
||||||
examples/point.so: $(OBJDIR)/examples/point.pic.o
|
|
||||||
$(CC) $(LDFLAGS) -shared -o $@ $^
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# documentation
|
|
||||||
|
|
||||||
DOCS=doc/quickjs.pdf doc/quickjs.html doc/jsbignum.pdf doc/jsbignum.html
|
|
||||||
|
|
||||||
build_doc: $(DOCS)
|
|
||||||
|
|
||||||
clean_doc:
|
|
||||||
rm -f $(DOCS)
|
|
||||||
|
|
||||||
doc/%.pdf: doc/%.texi
|
|
||||||
texi2pdf --clean -o $@ -q $<
|
|
||||||
|
|
||||||
doc/%.html.pre: doc/%.texi
|
|
||||||
makeinfo --html --no-headers --no-split --number-sections -o $@ $<
|
|
||||||
|
|
||||||
doc/%.html: doc/%.html.pre
|
|
||||||
sed -e 's|</style>|</style>\n<meta name="viewport" content="width=device-width, initial-scale=1.0">|' < $< > $@
|
|
||||||
|
|
||||||
###############################################################################
|
|
||||||
# tests
|
|
||||||
|
|
||||||
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)
|
|
70
quickjs/TODO
70
quickjs/TODO
|
@ -1,70 +0,0 @@
|
||||||
Bugs:
|
|
||||||
- modules: better error handling with cyclic module references
|
|
||||||
|
|
||||||
Misc ideas:
|
|
||||||
- use custom printf to avoid compatibility issues with floating point numbers
|
|
||||||
- consistent naming for preprocessor defines
|
|
||||||
- unify coding style and naming conventions
|
|
||||||
- use names from the ECMA spec in library implementation
|
|
||||||
- use byte code emitters with typed arguments (for clarity)
|
|
||||||
- use 2 bytecode DynBufs in JSFunctionDef, one for reading, one for writing
|
|
||||||
and use the same wrappers in all phases
|
|
||||||
- use more generic method for line numbers in resolve_variables and resolve_labels
|
|
||||||
- use custom timezone support to avoid C library compatibility issues
|
|
||||||
|
|
||||||
Memory:
|
|
||||||
- use memory pools for objects, etc?
|
|
||||||
- test border cases for max number of atoms, object properties, string length
|
|
||||||
- add emergency malloc mode for out of memory exceptions.
|
|
||||||
- test all DynBuf memory errors
|
|
||||||
- test all js_realloc memory errors
|
|
||||||
- improve JS_ComputeMemoryUsage() with more info
|
|
||||||
|
|
||||||
Built-in standard library:
|
|
||||||
- BSD sockets
|
|
||||||
- modules: use realpath in module name normalizer and put it in quickjs-libc
|
|
||||||
- modules: if no ".", use a well known module loading path ?
|
|
||||||
- get rid of __loadScript, use more common name
|
|
||||||
|
|
||||||
REPL:
|
|
||||||
- debugger
|
|
||||||
- readline: support MS Windows terminal
|
|
||||||
- readline: handle dynamic terminal resizing
|
|
||||||
- readline: handle double width unicode characters
|
|
||||||
- multiline editing
|
|
||||||
- runtime object and function inspectors
|
|
||||||
- interactive object browser
|
|
||||||
- use more generic approach to display evaluation results
|
|
||||||
- improve directive handling: dispatch, colorize, completion...
|
|
||||||
- save history
|
|
||||||
- close all predefined methods in repl.js and jscalc.js
|
|
||||||
|
|
||||||
Optimization ideas:
|
|
||||||
- 64-bit atoms in 64-bit mode ?
|
|
||||||
- 64-bit small bigint in 64-bit mode ?
|
|
||||||
- reuse stack slots for disjoint scopes, if strip
|
|
||||||
- add heuristic to avoid some cycles in closures
|
|
||||||
- small String (0-2 charcodes) with immediate storage
|
|
||||||
- perform static string concatenation at compile time
|
|
||||||
- optimize string concatenation with ropes or miniropes?
|
|
||||||
- add implicit numeric strings for Uint32 numbers?
|
|
||||||
- optimize `s += a + b`, `s += a.b` and similar simple expressions
|
|
||||||
- ensure string canonical representation and optimise comparisons and hashes?
|
|
||||||
- remove JSObject.first_weak_ref, use bit+context based hashed array for weak references
|
|
||||||
- property access optimization on the global object, functions,
|
|
||||||
prototypes and special non extensible objects.
|
|
||||||
- create object literals with the correct length by backpatching length argument
|
|
||||||
- remove redundant set_loc_uninitialized/check_uninitialized opcodes
|
|
||||||
- peephole optim: push_atom_value, to_propkey -> push_atom_value
|
|
||||||
- peephole optim: put_loc x, get_loc_check x -> set_loc x
|
|
||||||
- convert slow array to fast array when all properties != length are numeric
|
|
||||||
- optimize destructuring assignments for global and local variables
|
|
||||||
- implement some form of tail-call-optimization
|
|
||||||
- optimize OP_apply
|
|
||||||
- optimize f(...b)
|
|
||||||
|
|
||||||
Test262o: 0/11262 errors, 463 excluded
|
|
||||||
Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
|
|
||||||
|
|
||||||
Result: 35/75280 errors, 909 excluded, 585 skipped
|
|
||||||
Test262 commit: 31126581e7290f9233c29cefd93f66c6ac78f1c9
|
|
|
@ -1 +0,0 @@
|
||||||
2021-03-27
|
|
631
quickjs/cutils.c
631
quickjs/cutils.c
|
@ -1,631 +0,0 @@
|
||||||
/*
|
|
||||||
* C utilities
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017 Fabrice Bellard
|
|
||||||
* Copyright (c) 2018 Charlie Gordon
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string.h>
|
|
||||||
|
|
||||||
#include "cutils.h"
|
|
||||||
|
|
||||||
void pstrcpy(char *buf, int buf_size, const char *str)
|
|
||||||
{
|
|
||||||
int c;
|
|
||||||
char *q = buf;
|
|
||||||
|
|
||||||
if (buf_size <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
for(;;) {
|
|
||||||
c = *str++;
|
|
||||||
if (c == 0 || q >= buf + buf_size - 1)
|
|
||||||
break;
|
|
||||||
*q++ = c;
|
|
||||||
}
|
|
||||||
*q = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* strcat and truncate. */
|
|
||||||
char *pstrcat(char *buf, int buf_size, const char *s)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
len = strlen(buf);
|
|
||||||
if (len < buf_size)
|
|
||||||
pstrcpy(buf + len, buf_size - len, s);
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
int strstart(const char *str, const char *val, const char **ptr)
|
|
||||||
{
|
|
||||||
const char *p, *q;
|
|
||||||
p = str;
|
|
||||||
q = val;
|
|
||||||
while (*q != '\0') {
|
|
||||||
if (*p != *q)
|
|
||||||
return 0;
|
|
||||||
p++;
|
|
||||||
q++;
|
|
||||||
}
|
|
||||||
if (ptr)
|
|
||||||
*ptr = p;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int has_suffix(const char *str, const char *suffix)
|
|
||||||
{
|
|
||||||
size_t len = strlen(str);
|
|
||||||
size_t slen = strlen(suffix);
|
|
||||||
return (len >= slen && !memcmp(str + len - slen, suffix, slen));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Dynamic buffer package */
|
|
||||||
|
|
||||||
static void *dbuf_default_realloc(void *opaque, void *ptr, size_t size)
|
|
||||||
{
|
|
||||||
return realloc(ptr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func)
|
|
||||||
{
|
|
||||||
memset(s, 0, sizeof(*s));
|
|
||||||
if (!realloc_func)
|
|
||||||
realloc_func = dbuf_default_realloc;
|
|
||||||
s->opaque = opaque;
|
|
||||||
s->realloc_func = realloc_func;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dbuf_init(DynBuf *s)
|
|
||||||
{
|
|
||||||
dbuf_init2(s, NULL, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return < 0 if error */
|
|
||||||
int dbuf_realloc(DynBuf *s, size_t new_size)
|
|
||||||
{
|
|
||||||
size_t size;
|
|
||||||
uint8_t *new_buf;
|
|
||||||
if (new_size > s->allocated_size) {
|
|
||||||
if (s->error)
|
|
||||||
return -1;
|
|
||||||
size = s->allocated_size * 3 / 2;
|
|
||||||
if (size > new_size)
|
|
||||||
new_size = size;
|
|
||||||
new_buf = s->realloc_func(s->opaque, s->buf, new_size);
|
|
||||||
if (!new_buf) {
|
|
||||||
s->error = TRUE;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
s->buf = new_buf;
|
|
||||||
s->allocated_size = new_size;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len)
|
|
||||||
{
|
|
||||||
size_t end;
|
|
||||||
end = offset + len;
|
|
||||||
if (dbuf_realloc(s, end))
|
|
||||||
return -1;
|
|
||||||
memcpy(s->buf + offset, data, len);
|
|
||||||
if (end > s->size)
|
|
||||||
s->size = end;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len)
|
|
||||||
{
|
|
||||||
if (unlikely((s->size + len) > s->allocated_size)) {
|
|
||||||
if (dbuf_realloc(s, s->size + len))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy(s->buf + s->size, data, len);
|
|
||||||
s->size += len;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dbuf_put_self(DynBuf *s, size_t offset, size_t len)
|
|
||||||
{
|
|
||||||
if (unlikely((s->size + len) > s->allocated_size)) {
|
|
||||||
if (dbuf_realloc(s, s->size + len))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
memcpy(s->buf + s->size, s->buf + offset, len);
|
|
||||||
s->size += len;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int dbuf_putc(DynBuf *s, uint8_t c)
|
|
||||||
{
|
|
||||||
return dbuf_put(s, &c, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
int dbuf_putstr(DynBuf *s, const char *str)
|
|
||||||
{
|
|
||||||
return dbuf_put(s, (const uint8_t *)str, strlen(str));
|
|
||||||
}
|
|
||||||
|
|
||||||
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
|
|
||||||
const char *fmt, ...)
|
|
||||||
{
|
|
||||||
va_list ap;
|
|
||||||
char buf[128];
|
|
||||||
int len;
|
|
||||||
|
|
||||||
va_start(ap, fmt);
|
|
||||||
len = vsnprintf(buf, sizeof(buf), fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
if (len < sizeof(buf)) {
|
|
||||||
/* fast case */
|
|
||||||
return dbuf_put(s, (uint8_t *)buf, len);
|
|
||||||
} else {
|
|
||||||
if (dbuf_realloc(s, s->size + len + 1))
|
|
||||||
return -1;
|
|
||||||
va_start(ap, fmt);
|
|
||||||
vsnprintf((char *)(s->buf + s->size), s->allocated_size - s->size,
|
|
||||||
fmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
s->size += len;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dbuf_free(DynBuf *s)
|
|
||||||
{
|
|
||||||
/* we test s->buf as a fail safe to avoid crashing if dbuf_free()
|
|
||||||
is called twice */
|
|
||||||
if (s->buf) {
|
|
||||||
s->realloc_func(s->opaque, s->buf, 0);
|
|
||||||
}
|
|
||||||
memset(s, 0, sizeof(*s));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Note: at most 31 bits are encoded. At most UTF8_CHAR_LEN_MAX bytes
|
|
||||||
are output. */
|
|
||||||
int unicode_to_utf8(uint8_t *buf, unsigned int c)
|
|
||||||
{
|
|
||||||
uint8_t *q = buf;
|
|
||||||
|
|
||||||
if (c < 0x80) {
|
|
||||||
*q++ = c;
|
|
||||||
} else {
|
|
||||||
if (c < 0x800) {
|
|
||||||
*q++ = (c >> 6) | 0xc0;
|
|
||||||
} else {
|
|
||||||
if (c < 0x10000) {
|
|
||||||
*q++ = (c >> 12) | 0xe0;
|
|
||||||
} else {
|
|
||||||
if (c < 0x00200000) {
|
|
||||||
*q++ = (c >> 18) | 0xf0;
|
|
||||||
} else {
|
|
||||||
if (c < 0x04000000) {
|
|
||||||
*q++ = (c >> 24) | 0xf8;
|
|
||||||
} else if (c < 0x80000000) {
|
|
||||||
*q++ = (c >> 30) | 0xfc;
|
|
||||||
*q++ = ((c >> 24) & 0x3f) | 0x80;
|
|
||||||
} else {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
*q++ = ((c >> 18) & 0x3f) | 0x80;
|
|
||||||
}
|
|
||||||
*q++ = ((c >> 12) & 0x3f) | 0x80;
|
|
||||||
}
|
|
||||||
*q++ = ((c >> 6) & 0x3f) | 0x80;
|
|
||||||
}
|
|
||||||
*q++ = (c & 0x3f) | 0x80;
|
|
||||||
}
|
|
||||||
return q - buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const unsigned int utf8_min_code[5] = {
|
|
||||||
0x80, 0x800, 0x10000, 0x00200000, 0x04000000,
|
|
||||||
};
|
|
||||||
|
|
||||||
static const unsigned char utf8_first_code_mask[5] = {
|
|
||||||
0x1f, 0xf, 0x7, 0x3, 0x1,
|
|
||||||
};
|
|
||||||
|
|
||||||
/* return -1 if error. *pp is not updated in this case. max_len must
|
|
||||||
be >= 1. The maximum length for a UTF8 byte sequence is 6 bytes. */
|
|
||||||
int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp)
|
|
||||||
{
|
|
||||||
int l, c, b, i;
|
|
||||||
|
|
||||||
c = *p++;
|
|
||||||
if (c < 0x80) {
|
|
||||||
*pp = p;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
switch(c) {
|
|
||||||
case 0xc0: case 0xc1: case 0xc2: case 0xc3:
|
|
||||||
case 0xc4: case 0xc5: case 0xc6: case 0xc7:
|
|
||||||
case 0xc8: case 0xc9: case 0xca: case 0xcb:
|
|
||||||
case 0xcc: case 0xcd: case 0xce: case 0xcf:
|
|
||||||
case 0xd0: case 0xd1: case 0xd2: case 0xd3:
|
|
||||||
case 0xd4: case 0xd5: case 0xd6: case 0xd7:
|
|
||||||
case 0xd8: case 0xd9: case 0xda: case 0xdb:
|
|
||||||
case 0xdc: case 0xdd: case 0xde: case 0xdf:
|
|
||||||
l = 1;
|
|
||||||
break;
|
|
||||||
case 0xe0: case 0xe1: case 0xe2: case 0xe3:
|
|
||||||
case 0xe4: case 0xe5: case 0xe6: case 0xe7:
|
|
||||||
case 0xe8: case 0xe9: case 0xea: case 0xeb:
|
|
||||||
case 0xec: case 0xed: case 0xee: case 0xef:
|
|
||||||
l = 2;
|
|
||||||
break;
|
|
||||||
case 0xf0: case 0xf1: case 0xf2: case 0xf3:
|
|
||||||
case 0xf4: case 0xf5: case 0xf6: case 0xf7:
|
|
||||||
l = 3;
|
|
||||||
break;
|
|
||||||
case 0xf8: case 0xf9: case 0xfa: case 0xfb:
|
|
||||||
l = 4;
|
|
||||||
break;
|
|
||||||
case 0xfc: case 0xfd:
|
|
||||||
l = 5;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
/* check that we have enough characters */
|
|
||||||
if (l > (max_len - 1))
|
|
||||||
return -1;
|
|
||||||
c &= utf8_first_code_mask[l - 1];
|
|
||||||
for(i = 0; i < l; i++) {
|
|
||||||
b = *p++;
|
|
||||||
if (b < 0x80 || b >= 0xc0)
|
|
||||||
return -1;
|
|
||||||
c = (c << 6) | (b & 0x3f);
|
|
||||||
}
|
|
||||||
if (c < utf8_min_code[l - 1])
|
|
||||||
return -1;
|
|
||||||
*pp = p;
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
#if defined(EMSCRIPTEN) || defined(__ANDROID__)
|
|
||||||
|
|
||||||
static void *rqsort_arg;
|
|
||||||
static int (*rqsort_cmp)(const void *, const void *, void *);
|
|
||||||
|
|
||||||
static int rqsort_cmp2(const void *p1, const void *p2)
|
|
||||||
{
|
|
||||||
return rqsort_cmp(p1, p2, rqsort_arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* not reentrant, but not needed with emscripten */
|
|
||||||
void rqsort(void *base, size_t nmemb, size_t size,
|
|
||||||
int (*cmp)(const void *, const void *, void *),
|
|
||||||
void *arg)
|
|
||||||
{
|
|
||||||
rqsort_arg = arg;
|
|
||||||
rqsort_cmp = cmp;
|
|
||||||
qsort(base, nmemb, size, rqsort_cmp2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
typedef void (*exchange_f)(void *a, void *b, size_t size);
|
|
||||||
typedef int (*cmp_f)(const void *, const void *, void *opaque);
|
|
||||||
|
|
||||||
static void exchange_bytes(void *a, void *b, size_t size) {
|
|
||||||
uint8_t *ap = (uint8_t *)a;
|
|
||||||
uint8_t *bp = (uint8_t *)b;
|
|
||||||
|
|
||||||
while (size-- != 0) {
|
|
||||||
uint8_t t = *ap;
|
|
||||||
*ap++ = *bp;
|
|
||||||
*bp++ = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exchange_one_byte(void *a, void *b, size_t size) {
|
|
||||||
uint8_t *ap = (uint8_t *)a;
|
|
||||||
uint8_t *bp = (uint8_t *)b;
|
|
||||||
uint8_t t = *ap;
|
|
||||||
*ap = *bp;
|
|
||||||
*bp = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exchange_int16s(void *a, void *b, size_t size) {
|
|
||||||
uint16_t *ap = (uint16_t *)a;
|
|
||||||
uint16_t *bp = (uint16_t *)b;
|
|
||||||
|
|
||||||
for (size /= sizeof(uint16_t); size-- != 0;) {
|
|
||||||
uint16_t t = *ap;
|
|
||||||
*ap++ = *bp;
|
|
||||||
*bp++ = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exchange_one_int16(void *a, void *b, size_t size) {
|
|
||||||
uint16_t *ap = (uint16_t *)a;
|
|
||||||
uint16_t *bp = (uint16_t *)b;
|
|
||||||
uint16_t t = *ap;
|
|
||||||
*ap = *bp;
|
|
||||||
*bp = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exchange_int32s(void *a, void *b, size_t size) {
|
|
||||||
uint32_t *ap = (uint32_t *)a;
|
|
||||||
uint32_t *bp = (uint32_t *)b;
|
|
||||||
|
|
||||||
for (size /= sizeof(uint32_t); size-- != 0;) {
|
|
||||||
uint32_t t = *ap;
|
|
||||||
*ap++ = *bp;
|
|
||||||
*bp++ = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exchange_one_int32(void *a, void *b, size_t size) {
|
|
||||||
uint32_t *ap = (uint32_t *)a;
|
|
||||||
uint32_t *bp = (uint32_t *)b;
|
|
||||||
uint32_t t = *ap;
|
|
||||||
*ap = *bp;
|
|
||||||
*bp = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exchange_int64s(void *a, void *b, size_t size) {
|
|
||||||
uint64_t *ap = (uint64_t *)a;
|
|
||||||
uint64_t *bp = (uint64_t *)b;
|
|
||||||
|
|
||||||
for (size /= sizeof(uint64_t); size-- != 0;) {
|
|
||||||
uint64_t t = *ap;
|
|
||||||
*ap++ = *bp;
|
|
||||||
*bp++ = t;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exchange_one_int64(void *a, void *b, size_t size) {
|
|
||||||
uint64_t *ap = (uint64_t *)a;
|
|
||||||
uint64_t *bp = (uint64_t *)b;
|
|
||||||
uint64_t t = *ap;
|
|
||||||
*ap = *bp;
|
|
||||||
*bp = t;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exchange_int128s(void *a, void *b, size_t size) {
|
|
||||||
uint64_t *ap = (uint64_t *)a;
|
|
||||||
uint64_t *bp = (uint64_t *)b;
|
|
||||||
|
|
||||||
for (size /= sizeof(uint64_t) * 2; size-- != 0; ap += 2, bp += 2) {
|
|
||||||
uint64_t t = ap[0];
|
|
||||||
uint64_t u = ap[1];
|
|
||||||
ap[0] = bp[0];
|
|
||||||
ap[1] = bp[1];
|
|
||||||
bp[0] = t;
|
|
||||||
bp[1] = u;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void exchange_one_int128(void *a, void *b, size_t size) {
|
|
||||||
uint64_t *ap = (uint64_t *)a;
|
|
||||||
uint64_t *bp = (uint64_t *)b;
|
|
||||||
uint64_t t = ap[0];
|
|
||||||
uint64_t u = ap[1];
|
|
||||||
ap[0] = bp[0];
|
|
||||||
ap[1] = bp[1];
|
|
||||||
bp[0] = t;
|
|
||||||
bp[1] = u;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline exchange_f exchange_func(const void *base, size_t size) {
|
|
||||||
switch (((uintptr_t)base | (uintptr_t)size) & 15) {
|
|
||||||
case 0:
|
|
||||||
if (size == sizeof(uint64_t) * 2)
|
|
||||||
return exchange_one_int128;
|
|
||||||
else
|
|
||||||
return exchange_int128s;
|
|
||||||
case 8:
|
|
||||||
if (size == sizeof(uint64_t))
|
|
||||||
return exchange_one_int64;
|
|
||||||
else
|
|
||||||
return exchange_int64s;
|
|
||||||
case 4:
|
|
||||||
case 12:
|
|
||||||
if (size == sizeof(uint32_t))
|
|
||||||
return exchange_one_int32;
|
|
||||||
else
|
|
||||||
return exchange_int32s;
|
|
||||||
case 2:
|
|
||||||
case 6:
|
|
||||||
case 10:
|
|
||||||
case 14:
|
|
||||||
if (size == sizeof(uint16_t))
|
|
||||||
return exchange_one_int16;
|
|
||||||
else
|
|
||||||
return exchange_int16s;
|
|
||||||
default:
|
|
||||||
if (size == 1)
|
|
||||||
return exchange_one_byte;
|
|
||||||
else
|
|
||||||
return exchange_bytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void heapsortx(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque)
|
|
||||||
{
|
|
||||||
uint8_t *basep = (uint8_t *)base;
|
|
||||||
size_t i, n, c, r;
|
|
||||||
exchange_f swap = exchange_func(base, size);
|
|
||||||
|
|
||||||
if (nmemb > 1) {
|
|
||||||
i = (nmemb / 2) * size;
|
|
||||||
n = nmemb * size;
|
|
||||||
|
|
||||||
while (i > 0) {
|
|
||||||
i -= size;
|
|
||||||
for (r = i; (c = r * 2 + size) < n; r = c) {
|
|
||||||
if (c < n - size && cmp(basep + c, basep + c + size, opaque) <= 0)
|
|
||||||
c += size;
|
|
||||||
if (cmp(basep + r, basep + c, opaque) > 0)
|
|
||||||
break;
|
|
||||||
swap(basep + r, basep + c, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (i = n - size; i > 0; i -= size) {
|
|
||||||
swap(basep, basep + i, size);
|
|
||||||
|
|
||||||
for (r = 0; (c = r * 2 + size) < i; r = c) {
|
|
||||||
if (c < i - size && cmp(basep + c, basep + c + size, opaque) <= 0)
|
|
||||||
c += size;
|
|
||||||
if (cmp(basep + r, basep + c, opaque) > 0)
|
|
||||||
break;
|
|
||||||
swap(basep + r, basep + c, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void *med3(void *a, void *b, void *c, cmp_f cmp, void *opaque)
|
|
||||||
{
|
|
||||||
return cmp(a, b, opaque) < 0 ?
|
|
||||||
(cmp(b, c, opaque) < 0 ? b : (cmp(a, c, opaque) < 0 ? c : a )) :
|
|
||||||
(cmp(b, c, opaque) > 0 ? b : (cmp(a, c, opaque) < 0 ? a : c ));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* pointer based version with local stack and insertion sort threshhold */
|
|
||||||
void rqsort(void *base, size_t nmemb, size_t size, cmp_f cmp, void *opaque)
|
|
||||||
{
|
|
||||||
struct { uint8_t *base; size_t count; int depth; } stack[50], *sp = stack;
|
|
||||||
uint8_t *ptr, *pi, *pj, *plt, *pgt, *top, *m;
|
|
||||||
size_t m4, i, lt, gt, span, span2;
|
|
||||||
int c, depth;
|
|
||||||
exchange_f swap = exchange_func(base, size);
|
|
||||||
exchange_f swap_block = exchange_func(base, size | 128);
|
|
||||||
|
|
||||||
if (nmemb < 2 || size <= 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
sp->base = (uint8_t *)base;
|
|
||||||
sp->count = nmemb;
|
|
||||||
sp->depth = 0;
|
|
||||||
sp++;
|
|
||||||
|
|
||||||
while (sp > stack) {
|
|
||||||
sp--;
|
|
||||||
ptr = sp->base;
|
|
||||||
nmemb = sp->count;
|
|
||||||
depth = sp->depth;
|
|
||||||
|
|
||||||
while (nmemb > 6) {
|
|
||||||
if (++depth > 50) {
|
|
||||||
/* depth check to ensure worst case logarithmic time */
|
|
||||||
heapsortx(ptr, nmemb, size, cmp, opaque);
|
|
||||||
nmemb = 0;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* select median of 3 from 1/4, 1/2, 3/4 positions */
|
|
||||||
/* should use median of 5 or 9? */
|
|
||||||
m4 = (nmemb >> 2) * size;
|
|
||||||
m = med3(ptr + m4, ptr + 2 * m4, ptr + 3 * m4, cmp, opaque);
|
|
||||||
swap(ptr, m, size); /* move the pivot to the start or the array */
|
|
||||||
i = lt = 1;
|
|
||||||
pi = plt = ptr + size;
|
|
||||||
gt = nmemb;
|
|
||||||
pj = pgt = top = ptr + nmemb * size;
|
|
||||||
for (;;) {
|
|
||||||
while (pi < pj && (c = cmp(ptr, pi, opaque)) >= 0) {
|
|
||||||
if (c == 0) {
|
|
||||||
swap(plt, pi, size);
|
|
||||||
lt++;
|
|
||||||
plt += size;
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
pi += size;
|
|
||||||
}
|
|
||||||
while (pi < (pj -= size) && (c = cmp(ptr, pj, opaque)) <= 0) {
|
|
||||||
if (c == 0) {
|
|
||||||
gt--;
|
|
||||||
pgt -= size;
|
|
||||||
swap(pgt, pj, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pi >= pj)
|
|
||||||
break;
|
|
||||||
swap(pi, pj, size);
|
|
||||||
i++;
|
|
||||||
pi += size;
|
|
||||||
}
|
|
||||||
/* array has 4 parts:
|
|
||||||
* from 0 to lt excluded: elements identical to pivot
|
|
||||||
* from lt to pi excluded: elements smaller than pivot
|
|
||||||
* from pi to gt excluded: elements greater than pivot
|
|
||||||
* from gt to n excluded: elements identical to pivot
|
|
||||||
*/
|
|
||||||
/* move elements identical to pivot in the middle of the array: */
|
|
||||||
/* swap values in ranges [0..lt[ and [i-lt..i[
|
|
||||||
swapping the smallest span between lt and i-lt is sufficient
|
|
||||||
*/
|
|
||||||
span = plt - ptr;
|
|
||||||
span2 = pi - plt;
|
|
||||||
lt = i - lt;
|
|
||||||
if (span > span2)
|
|
||||||
span = span2;
|
|
||||||
swap_block(ptr, pi - span, span);
|
|
||||||
/* swap values in ranges [gt..top[ and [i..top-(top-gt)[
|
|
||||||
swapping the smallest span between top-gt and gt-i is sufficient
|
|
||||||
*/
|
|
||||||
span = top - pgt;
|
|
||||||
span2 = pgt - pi;
|
|
||||||
pgt = top - span2;
|
|
||||||
gt = nmemb - (gt - i);
|
|
||||||
if (span > span2)
|
|
||||||
span = span2;
|
|
||||||
swap_block(pi, top - span, span);
|
|
||||||
|
|
||||||
/* now array has 3 parts:
|
|
||||||
* from 0 to lt excluded: elements smaller than pivot
|
|
||||||
* from lt to gt excluded: elements identical to pivot
|
|
||||||
* from gt to n excluded: elements greater than pivot
|
|
||||||
*/
|
|
||||||
/* stack the larger segment and keep processing the smaller one
|
|
||||||
to minimize stack use for pathological distributions */
|
|
||||||
if (lt > nmemb - gt) {
|
|
||||||
sp->base = ptr;
|
|
||||||
sp->count = lt;
|
|
||||||
sp->depth = depth;
|
|
||||||
sp++;
|
|
||||||
ptr = pgt;
|
|
||||||
nmemb -= gt;
|
|
||||||
} else {
|
|
||||||
sp->base = pgt;
|
|
||||||
sp->count = nmemb - gt;
|
|
||||||
sp->depth = depth;
|
|
||||||
sp++;
|
|
||||||
nmemb = lt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Use insertion sort for small fragments */
|
|
||||||
for (pi = ptr + size, top = ptr + nmemb * size; pi < top; pi += size) {
|
|
||||||
for (pj = pi; pj > ptr && cmp(pj - size, pj, opaque) > 0; pj -= size)
|
|
||||||
swap(pj, pj - size, size);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
300
quickjs/cutils.h
300
quickjs/cutils.h
|
@ -1,300 +0,0 @@
|
||||||
/*
|
|
||||||
* C utilities
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017 Fabrice Bellard
|
|
||||||
* Copyright (c) 2018 Charlie Gordon
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
#ifndef CUTILS_H
|
|
||||||
#define CUTILS_H
|
|
||||||
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
/* set if CPU is big endian */
|
|
||||||
#undef WORDS_BIGENDIAN
|
|
||||||
|
|
||||||
#define likely(x) __builtin_expect(!!(x), 1)
|
|
||||||
#define unlikely(x) __builtin_expect(!!(x), 0)
|
|
||||||
#define force_inline inline __attribute__((always_inline))
|
|
||||||
#define no_inline __attribute__((noinline))
|
|
||||||
#define __maybe_unused __attribute__((unused))
|
|
||||||
|
|
||||||
#define xglue(x, y) x ## y
|
|
||||||
#define glue(x, y) xglue(x, y)
|
|
||||||
#define stringify(s) tostring(s)
|
|
||||||
#define tostring(s) #s
|
|
||||||
|
|
||||||
#ifndef offsetof
|
|
||||||
#define offsetof(type, field) ((size_t) &((type *)0)->field)
|
|
||||||
#endif
|
|
||||||
#ifndef countof
|
|
||||||
#define countof(x) (sizeof(x) / sizeof((x)[0]))
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* return the pointer of type 'type *' containing 'ptr' as field 'member' */
|
|
||||||
#define container_of(ptr, type, member) ((type *)((uint8_t *)(ptr) - offsetof(type, member)))
|
|
||||||
|
|
||||||
typedef int BOOL;
|
|
||||||
|
|
||||||
#ifndef FALSE
|
|
||||||
enum {
|
|
||||||
FALSE = 0,
|
|
||||||
TRUE = 1,
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void pstrcpy(char *buf, int buf_size, const char *str);
|
|
||||||
char *pstrcat(char *buf, int buf_size, const char *s);
|
|
||||||
int strstart(const char *str, const char *val, const char **ptr);
|
|
||||||
int has_suffix(const char *str, const char *suffix);
|
|
||||||
|
|
||||||
static inline int max_int(int a, int b)
|
|
||||||
{
|
|
||||||
if (a > b)
|
|
||||||
return a;
|
|
||||||
else
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int min_int(int a, int b)
|
|
||||||
{
|
|
||||||
if (a < b)
|
|
||||||
return a;
|
|
||||||
else
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t max_uint32(uint32_t a, uint32_t b)
|
|
||||||
{
|
|
||||||
if (a > b)
|
|
||||||
return a;
|
|
||||||
else
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t min_uint32(uint32_t a, uint32_t b)
|
|
||||||
{
|
|
||||||
if (a < b)
|
|
||||||
return a;
|
|
||||||
else
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int64_t max_int64(int64_t a, int64_t b)
|
|
||||||
{
|
|
||||||
if (a > b)
|
|
||||||
return a;
|
|
||||||
else
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int64_t min_int64(int64_t a, int64_t b)
|
|
||||||
{
|
|
||||||
if (a < b)
|
|
||||||
return a;
|
|
||||||
else
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WARNING: undefined if a = 0 */
|
|
||||||
static inline int clz32(unsigned int a)
|
|
||||||
{
|
|
||||||
return __builtin_clz(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WARNING: undefined if a = 0 */
|
|
||||||
static inline int clz64(uint64_t a)
|
|
||||||
{
|
|
||||||
return __builtin_clzll(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WARNING: undefined if a = 0 */
|
|
||||||
static inline int ctz32(unsigned int a)
|
|
||||||
{
|
|
||||||
return __builtin_ctz(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* WARNING: undefined if a = 0 */
|
|
||||||
static inline int ctz64(uint64_t a)
|
|
||||||
{
|
|
||||||
return __builtin_ctzll(a);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct __attribute__((packed)) packed_u64 {
|
|
||||||
uint64_t v;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct __attribute__((packed)) packed_u32 {
|
|
||||||
uint32_t v;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct __attribute__((packed)) packed_u16 {
|
|
||||||
uint16_t v;
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline uint64_t get_u64(const uint8_t *tab)
|
|
||||||
{
|
|
||||||
return ((const struct packed_u64 *)tab)->v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int64_t get_i64(const uint8_t *tab)
|
|
||||||
{
|
|
||||||
return (int64_t)((const struct packed_u64 *)tab)->v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void put_u64(uint8_t *tab, uint64_t val)
|
|
||||||
{
|
|
||||||
((struct packed_u64 *)tab)->v = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t get_u32(const uint8_t *tab)
|
|
||||||
{
|
|
||||||
return ((const struct packed_u32 *)tab)->v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int32_t get_i32(const uint8_t *tab)
|
|
||||||
{
|
|
||||||
return (int32_t)((const struct packed_u32 *)tab)->v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void put_u32(uint8_t *tab, uint32_t val)
|
|
||||||
{
|
|
||||||
((struct packed_u32 *)tab)->v = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t get_u16(const uint8_t *tab)
|
|
||||||
{
|
|
||||||
return ((const struct packed_u16 *)tab)->v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int32_t get_i16(const uint8_t *tab)
|
|
||||||
{
|
|
||||||
return (int16_t)((const struct packed_u16 *)tab)->v;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void put_u16(uint8_t *tab, uint16_t val)
|
|
||||||
{
|
|
||||||
((struct packed_u16 *)tab)->v = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t get_u8(const uint8_t *tab)
|
|
||||||
{
|
|
||||||
return *tab;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int32_t get_i8(const uint8_t *tab)
|
|
||||||
{
|
|
||||||
return (int8_t)*tab;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void put_u8(uint8_t *tab, uint8_t val)
|
|
||||||
{
|
|
||||||
*tab = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint16_t bswap16(uint16_t x)
|
|
||||||
{
|
|
||||||
return (x >> 8) | (x << 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint32_t bswap32(uint32_t v)
|
|
||||||
{
|
|
||||||
return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) |
|
|
||||||
((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline uint64_t bswap64(uint64_t v)
|
|
||||||
{
|
|
||||||
return ((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) |
|
|
||||||
((v & ((uint64_t)0xff << (6 * 8))) >> (5 * 8)) |
|
|
||||||
((v & ((uint64_t)0xff << (5 * 8))) >> (3 * 8)) |
|
|
||||||
((v & ((uint64_t)0xff << (4 * 8))) >> (1 * 8)) |
|
|
||||||
((v & ((uint64_t)0xff << (3 * 8))) << (1 * 8)) |
|
|
||||||
((v & ((uint64_t)0xff << (2 * 8))) << (3 * 8)) |
|
|
||||||
((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) |
|
|
||||||
((v & ((uint64_t)0xff << (0 * 8))) << (7 * 8));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* XXX: should take an extra argument to pass slack information to the caller */
|
|
||||||
typedef void *DynBufReallocFunc(void *opaque, void *ptr, size_t size);
|
|
||||||
|
|
||||||
typedef struct DynBuf {
|
|
||||||
uint8_t *buf;
|
|
||||||
size_t size;
|
|
||||||
size_t allocated_size;
|
|
||||||
BOOL error; /* true if a memory allocation error occurred */
|
|
||||||
DynBufReallocFunc *realloc_func;
|
|
||||||
void *opaque; /* for realloc_func */
|
|
||||||
} DynBuf;
|
|
||||||
|
|
||||||
void dbuf_init(DynBuf *s);
|
|
||||||
void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func);
|
|
||||||
int dbuf_realloc(DynBuf *s, size_t new_size);
|
|
||||||
int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len);
|
|
||||||
int dbuf_put(DynBuf *s, const uint8_t *data, size_t len);
|
|
||||||
int dbuf_put_self(DynBuf *s, size_t offset, size_t len);
|
|
||||||
int dbuf_putc(DynBuf *s, uint8_t c);
|
|
||||||
int dbuf_putstr(DynBuf *s, const char *str);
|
|
||||||
static inline int dbuf_put_u16(DynBuf *s, uint16_t val)
|
|
||||||
{
|
|
||||||
return dbuf_put(s, (uint8_t *)&val, 2);
|
|
||||||
}
|
|
||||||
static inline int dbuf_put_u32(DynBuf *s, uint32_t val)
|
|
||||||
{
|
|
||||||
return dbuf_put(s, (uint8_t *)&val, 4);
|
|
||||||
}
|
|
||||||
static inline int dbuf_put_u64(DynBuf *s, uint64_t val)
|
|
||||||
{
|
|
||||||
return dbuf_put(s, (uint8_t *)&val, 8);
|
|
||||||
}
|
|
||||||
int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
|
|
||||||
const char *fmt, ...);
|
|
||||||
void dbuf_free(DynBuf *s);
|
|
||||||
static inline BOOL dbuf_error(DynBuf *s) {
|
|
||||||
return s->error;
|
|
||||||
}
|
|
||||||
static inline void dbuf_set_error(DynBuf *s)
|
|
||||||
{
|
|
||||||
s->error = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
#define UTF8_CHAR_LEN_MAX 6
|
|
||||||
|
|
||||||
int unicode_to_utf8(uint8_t *buf, unsigned int c);
|
|
||||||
int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp);
|
|
||||||
|
|
||||||
static inline int from_hex(int c)
|
|
||||||
{
|
|
||||||
if (c >= '0' && c <= '9')
|
|
||||||
return c - '0';
|
|
||||||
else if (c >= 'A' && c <= 'F')
|
|
||||||
return c - 'A' + 10;
|
|
||||||
else if (c >= 'a' && c <= 'f')
|
|
||||||
return c - 'a' + 10;
|
|
||||||
else
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void rqsort(void *base, size_t nmemb, size_t size,
|
|
||||||
int (*cmp)(const void *, const void *, void *),
|
|
||||||
void *arg);
|
|
||||||
|
|
||||||
#endif /* CUTILS_H */
|
|
|
@ -1,589 +0,0 @@
|
||||||
\input texinfo
|
|
||||||
|
|
||||||
@iftex
|
|
||||||
@afourpaper
|
|
||||||
@headings double
|
|
||||||
@end iftex
|
|
||||||
|
|
||||||
@titlepage
|
|
||||||
@afourpaper
|
|
||||||
@sp 7
|
|
||||||
@center @titlefont{Javascript Bignum Extensions}
|
|
||||||
@sp 3
|
|
||||||
@center Version 2020-01-11
|
|
||||||
@sp 3
|
|
||||||
@center Author: Fabrice Bellard
|
|
||||||
@end titlepage
|
|
||||||
|
|
||||||
@setfilename jsbignum.info
|
|
||||||
@settitle Javascript Bignum Extensions
|
|
||||||
|
|
||||||
@contents
|
|
||||||
|
|
||||||
@chapter Introduction
|
|
||||||
|
|
||||||
The Bignum extensions add the following features to the Javascript
|
|
||||||
language while being 100% backward compatible:
|
|
||||||
|
|
||||||
@itemize
|
|
||||||
|
|
||||||
@item Operator overloading with a dispatch logic inspired from the proposal available at @url{https://github.com/tc39/proposal-operator-overloading/}.
|
|
||||||
|
|
||||||
@item Arbitrarily large floating point numbers (@code{BigFloat}) in base 2 using the IEEE 754 semantics.
|
|
||||||
|
|
||||||
@item Arbitrarily large floating point numbers (@code{BigDecimal}) in base 10 based on the proposal available at
|
|
||||||
@url{https://github.com/littledan/proposal-bigdecimal}.
|
|
||||||
|
|
||||||
@item @code{math} mode: arbitrarily large integers and floating point numbers are available by default. The integer division and power can be overloaded for example to return a fraction. The modulo operator (@code{%}) is defined as the Euclidian
|
|
||||||
remainder. @code{^} is an alias to the power operator
|
|
||||||
(@code{**}). @code{^^} is used as the exclusive or operator.
|
|
||||||
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
The extensions are independent from each other except the @code{math}
|
|
||||||
mode which relies on BigFloat and operator overloading.
|
|
||||||
|
|
||||||
@chapter Operator overloading
|
|
||||||
|
|
||||||
Operator overloading is inspired from the proposal available at
|
|
||||||
@url{https://github.com/tc39/proposal-operator-overloading/}. It
|
|
||||||
implements the same dispatch logic but finds the operator sets by
|
|
||||||
looking at the @code{Symbol.operatorSet} property in the objects. The
|
|
||||||
changes were done in order to simplify the implementation.
|
|
||||||
|
|
||||||
More precisely, the following modifications were made:
|
|
||||||
|
|
||||||
@itemize
|
|
||||||
|
|
||||||
@item @code{with operators from} is not supported. Operator overloading is always enabled.
|
|
||||||
|
|
||||||
@item The dispatch is not based on a static @code{[[OperatorSet]]} field in all instances. Instead, a dynamic lookup of the @code{Symbol.operatorSet} property is done. This property is typically added in the prototype of each object.
|
|
||||||
|
|
||||||
@item @code{Operators.create(...dictionaries)} is used to create a new OperatorSet object. The @code{Operators} function is supported as an helper to be closer to the TC39 proposal.
|
|
||||||
|
|
||||||
@item @code{[]} cannot be overloaded.
|
|
||||||
|
|
||||||
@item In math mode, the BigInt division and power operators can be overloaded with @code{Operators.updateBigIntOperators(dictionary)}.
|
|
||||||
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
@chapter BigInt extensions
|
|
||||||
|
|
||||||
A few properties are added to the BigInt object:
|
|
||||||
|
|
||||||
@table @code
|
|
||||||
|
|
||||||
@item tdiv(a, b)
|
|
||||||
Return @math{trunc(a/b)}. @code{b = 0} raises a RangeError
|
|
||||||
exception.
|
|
||||||
|
|
||||||
@item fdiv(a, b)
|
|
||||||
Return @math{\lfloor a/b \rfloor}. @code{b = 0} raises a RangeError
|
|
||||||
exception.
|
|
||||||
|
|
||||||
@item cdiv(a, b)
|
|
||||||
Return @math{\lceil a/b \rceil}. @code{b = 0} raises a RangeError
|
|
||||||
exception.
|
|
||||||
|
|
||||||
@item ediv(a, b)
|
|
||||||
Return @math{sgn(b) \lfloor a/{|b|} \rfloor} (Euclidian
|
|
||||||
division). @code{b = 0} raises a RangeError exception.
|
|
||||||
|
|
||||||
@item tdivrem(a, b)
|
|
||||||
@item fdivrem(a, b)
|
|
||||||
@item cdivrem(a, b)
|
|
||||||
@item edivrem(a, b)
|
|
||||||
Return an array of two elements. The first element is the quotient,
|
|
||||||
the second is the remainder. The same rounding is done as the
|
|
||||||
corresponding division operation.
|
|
||||||
|
|
||||||
@item sqrt(a)
|
|
||||||
Return @math{\lfloor \sqrt(a) \rfloor}. A RangeError exception is
|
|
||||||
raised if @math{a < 0}.
|
|
||||||
|
|
||||||
@item sqrtrem(a)
|
|
||||||
Return an array of two elements. The first element is @math{\lfloor
|
|
||||||
\sqrt{a} \rfloor}. The second element is @math{a-\lfloor \sqrt{a}
|
|
||||||
\rfloor^2}. A RangeError exception is raised if @math{a < 0}.
|
|
||||||
|
|
||||||
@item floorLog2(a)
|
|
||||||
Return -1 if @math{a \leq 0} otherwise return @math{\lfloor \log2(a) \rfloor}.
|
|
||||||
|
|
||||||
@item ctz(a)
|
|
||||||
Return the number of trailing zeros in the two's complement binary representation of a. Return -1 if @math{a=0}.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@chapter BigFloat
|
|
||||||
|
|
||||||
@section Introduction
|
|
||||||
|
|
||||||
This extension adds the @code{BigFloat} primitive type. The
|
|
||||||
@code{BigFloat} type represents floating point numbers in base 2
|
|
||||||
with the IEEE 754 semantics. A floating
|
|
||||||
point number is represented as a sign, mantissa and exponent. The
|
|
||||||
special values @code{NaN}, @code{+/-Infinity}, @code{+0} and @code{-0}
|
|
||||||
are supported. The mantissa and exponent can have any bit length with
|
|
||||||
an implementation specific minimum and maximum.
|
|
||||||
|
|
||||||
@section Floating point rounding
|
|
||||||
|
|
||||||
Each floating point operation operates with infinite precision and
|
|
||||||
then rounds the result according to the specified floating point
|
|
||||||
environment (@code{BigFloatEnv} object). The status flags of the
|
|
||||||
environment are also set according to the result of the operation.
|
|
||||||
|
|
||||||
If no floating point environment is provided, the global floating
|
|
||||||
point environment is used.
|
|
||||||
|
|
||||||
The rounding mode of the global floating point environment is always
|
|
||||||
@code{RNDN} (``round to nearest with ties to even'')@footnote{The
|
|
||||||
rationale is that the rounding mode changes must always be
|
|
||||||
explicit.}. The status flags of the global environment cannot be
|
|
||||||
read@footnote{The rationale is to avoid side effects for the built-in
|
|
||||||
operators.}. The precision of the global environment is
|
|
||||||
@code{BigFloatEnv.prec}. The number of exponent bits of the global
|
|
||||||
environment is @code{BigFloatEnv.expBits}. The global environment
|
|
||||||
subnormal flag is set to @code{true}.
|
|
||||||
|
|
||||||
For example, @code{prec = 53} and @code{ expBits = 11} exactly give
|
|
||||||
the same precision as the IEEE 754 64 bit floating point format. The
|
|
||||||
default precision is @code{prec = 113} and @code{ expBits = 15} (IEEE
|
|
||||||
754 128 bit floating point format).
|
|
||||||
|
|
||||||
The global floating point environment can only be modified temporarily
|
|
||||||
when calling a function (see @code{BigFloatEnv.setPrec}). Hence a
|
|
||||||
function can change the global floating point environment for its
|
|
||||||
callees but not for its caller.
|
|
||||||
|
|
||||||
@section Operators
|
|
||||||
|
|
||||||
The builtin operators are extended so that a BigFloat is returned if
|
|
||||||
at least one operand is a BigFloat. The computations are always done
|
|
||||||
with infinite precision and rounded according to the global floating
|
|
||||||
point environment.
|
|
||||||
|
|
||||||
@code{typeof} applied on a @code{BigFloat} returns @code{bigfloat}.
|
|
||||||
|
|
||||||
BigFloat can be compared with all the other numeric types and the
|
|
||||||
result follows the expected mathematical relations.
|
|
||||||
|
|
||||||
However, since BigFloat and Number are different types they are never
|
|
||||||
equal when using the strict comparison operators (e.g. @code{0.0 ===
|
|
||||||
0.0l} is false).
|
|
||||||
|
|
||||||
@section BigFloat literals
|
|
||||||
|
|
||||||
BigFloat literals are floating point numbers with a trailing @code{l}
|
|
||||||
suffix. BigFloat literals have an infinite precision. They are rounded
|
|
||||||
according to the global floating point environment when they are
|
|
||||||
evaluated.@footnote{Base 10 floating point literals cannot usually be
|
|
||||||
exactly represented as base 2 floating point number. In order to
|
|
||||||
ensure that the literal is represented accurately with the current
|
|
||||||
precision, it must be evaluated at runtime.}
|
|
||||||
|
|
||||||
@section Builtin Object changes
|
|
||||||
|
|
||||||
@subsection @code{BigFloat} function
|
|
||||||
|
|
||||||
The @code{BigFloat} function cannot be invoked as a constructor. When
|
|
||||||
invoked as a function: the parameter is converted to a primitive
|
|
||||||
type. If the result is a numeric type, it is converted to BigFloat
|
|
||||||
without rounding. If the result is a string, it is converted to
|
|
||||||
BigFloat using the precision of the global floating point environment.
|
|
||||||
|
|
||||||
@code{BigFloat} properties:
|
|
||||||
|
|
||||||
@table @code
|
|
||||||
|
|
||||||
@item LN2
|
|
||||||
@item PI
|
|
||||||
Getter. Return the value of the corresponding mathematical constant
|
|
||||||
rounded to nearest, ties to even with the current global
|
|
||||||
precision. The constant values are cached for small precisions.
|
|
||||||
|
|
||||||
@item MIN_VALUE
|
|
||||||
@item MAX_VALUE
|
|
||||||
@item EPSILON
|
|
||||||
Getter. Return the minimum, maximum and epsilon @code{BigFloat} values
|
|
||||||
(same definition as the corresponding @code{Number} constants).
|
|
||||||
|
|
||||||
@item fpRound(a[, e])
|
|
||||||
Round the floating point number @code{a} according to the floating
|
|
||||||
point environment @code{e} or the global environment if @code{e} is
|
|
||||||
undefined.
|
|
||||||
|
|
||||||
@item parseFloat(a[, radix[, e]])
|
|
||||||
Parse the string @code{a} as a floating point number in radix
|
|
||||||
@code{radix}. The radix is 0 (default) or from 2 to 36. The radix 0
|
|
||||||
means radix 10 unless there is a hexadecimal or binary prefix. The
|
|
||||||
result is rounded according to the floating point environment @code{e}
|
|
||||||
or the global environment if @code{e} is undefined.
|
|
||||||
|
|
||||||
@item isFinite(a)
|
|
||||||
Return true if @code{a} is a finite bigfloat.
|
|
||||||
|
|
||||||
@item isNaN(a)
|
|
||||||
Return true if @code{a} is a NaN bigfloat.
|
|
||||||
|
|
||||||
@item add(a, b[, e])
|
|
||||||
@item sub(a, b[, e])
|
|
||||||
@item mul(a, b[, e])
|
|
||||||
@item div(a, b[, e])
|
|
||||||
Perform the specified floating point operation and round the floating
|
|
||||||
point number @code{a} according to the floating point environment
|
|
||||||
@code{e} or the global environment if @code{e} is undefined. If
|
|
||||||
@code{e} is specified, the floating point status flags are updated.
|
|
||||||
|
|
||||||
@item floor(x)
|
|
||||||
@item ceil(x)
|
|
||||||
@item round(x)
|
|
||||||
@item trunc(x)
|
|
||||||
Round to an integer. No additional rounding is performed.
|
|
||||||
|
|
||||||
@item abs(x)
|
|
||||||
Return the absolute value of x. No additional rounding is performed.
|
|
||||||
|
|
||||||
@item fmod(x, y[, e])
|
|
||||||
@item remainder(x, y[, e])
|
|
||||||
Floating point remainder. The quotient is truncated to zero (fmod) or
|
|
||||||
to the nearest integer with ties to even (remainder). @code{e} is an
|
|
||||||
optional floating point environment.
|
|
||||||
|
|
||||||
@item sqrt(x[, e])
|
|
||||||
Square root. Return a rounded floating point number. @code{e} is an
|
|
||||||
optional floating point environment.
|
|
||||||
|
|
||||||
@item sin(x[, e])
|
|
||||||
@item cos(x[, e])
|
|
||||||
@item tan(x[, e])
|
|
||||||
@item asin(x[, e])
|
|
||||||
@item acos(x[, e])
|
|
||||||
@item atan(x[, e])
|
|
||||||
@item atan2(x, y[, e])
|
|
||||||
@item exp(x[, e])
|
|
||||||
@item log(x[, e])
|
|
||||||
@item pow(x, y[, e])
|
|
||||||
Transcendental operations. Return a rounded floating point
|
|
||||||
number. @code{e} is an optional floating point environment.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@subsection @code{BigFloat.prototype}
|
|
||||||
|
|
||||||
The following properties are modified:
|
|
||||||
|
|
||||||
@table @code
|
|
||||||
@item valueOf()
|
|
||||||
Return the bigfloat primitive value corresponding to @code{this}.
|
|
||||||
|
|
||||||
@item toString(radix)
|
|
||||||
|
|
||||||
For floating point numbers:
|
|
||||||
|
|
||||||
@itemize
|
|
||||||
@item
|
|
||||||
If the radix is a power of two, the conversion is done with infinite
|
|
||||||
precision.
|
|
||||||
@item
|
|
||||||
Otherwise, the number is rounded to nearest with ties to even using
|
|
||||||
the global precision. It is then converted to string using the minimum
|
|
||||||
number of digits so that its conversion back to a floating point using
|
|
||||||
the global precision and round to nearest gives the same number.
|
|
||||||
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
The exponent letter is @code{e} for base 10, @code{p} for bases 2, 8,
|
|
||||||
16 with a binary exponent and @code{@@} for the other bases.
|
|
||||||
|
|
||||||
@item toPrecision(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10)
|
|
||||||
@item toFixed(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10)
|
|
||||||
@item toExponential(p, rnd_mode = BigFloatEnv.RNDNA, radix = 10)
|
|
||||||
Same semantics as the corresponding @code{Number} functions with
|
|
||||||
BigFloats. There is no limit on the accepted precision @code{p}. The
|
|
||||||
rounding mode and radix can be optionally specified. The radix must be
|
|
||||||
between 2 and 36.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@subsection @code{BigFloatEnv} constructor
|
|
||||||
|
|
||||||
The @code{BigFloatEnv([p, [,rndMode]]} constructor cannot be invoked as a
|
|
||||||
function. The floating point environment contains:
|
|
||||||
|
|
||||||
@itemize
|
|
||||||
@item the mantissa precision in bits
|
|
||||||
|
|
||||||
@item the exponent size in bits assuming an IEEE 754 representation;
|
|
||||||
|
|
||||||
@item the subnormal flag (if true, subnormal floating point numbers can
|
|
||||||
be generated by the floating point operations).
|
|
||||||
|
|
||||||
@item the rounding mode
|
|
||||||
|
|
||||||
@item the floating point status. The status flags can only be set by the floating point operations. They can be reset with @code{BigFloatEnv.prototype.clearStatus()} or with the various status flag setters.
|
|
||||||
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
@code{new BigFloatEnv([p, [,rndMode]]} creates a new floating point
|
|
||||||
environment. The status flags are reset. If no parameter is given the
|
|
||||||
precision, exponent bits and subnormal flags are copied from the
|
|
||||||
global floating point environment. Otherwise, the precision is set to
|
|
||||||
@code{p}, the number of exponent bits is set to @code{expBitsMax} and the
|
|
||||||
subnormal flags is set to @code{false}. If @code{rndMode} is
|
|
||||||
@code{undefined}, the rounding mode is set to @code{RNDN}.
|
|
||||||
|
|
||||||
@code{BigFloatEnv} properties:
|
|
||||||
|
|
||||||
@table @code
|
|
||||||
|
|
||||||
@item prec
|
|
||||||
Getter. Return the precision in bits of the global floating point
|
|
||||||
environment. The initial value is @code{113}.
|
|
||||||
|
|
||||||
@item expBits
|
|
||||||
Getter. Return the exponent size in bits of the global floating point
|
|
||||||
environment assuming an IEEE 754 representation. The initial value is
|
|
||||||
@code{15}.
|
|
||||||
|
|
||||||
@item setPrec(f, p[, e])
|
|
||||||
Set the precision of the global floating point environment to @code{p}
|
|
||||||
and the exponent size to @code{e} then call the function
|
|
||||||
@code{f}. Then the Float precision and exponent size are reset to
|
|
||||||
their precious value and the return value of @code{f} is returned (or
|
|
||||||
an exception is raised if @code{f} raised an exception). If @code{e}
|
|
||||||
is @code{undefined} it is set to @code{BigFloatEnv.expBitsMax}.
|
|
||||||
|
|
||||||
@item precMin
|
|
||||||
Read-only integer. Return the minimum allowed precision. Must be at least 2.
|
|
||||||
|
|
||||||
@item precMax
|
|
||||||
Read-only integer. Return the maximum allowed precision. Must be at least 113.
|
|
||||||
|
|
||||||
@item expBitsMin
|
|
||||||
Read-only integer. Return the minimum allowed exponent size in
|
|
||||||
bits. Must be at least 3.
|
|
||||||
|
|
||||||
@item expBitsMax
|
|
||||||
Read-only integer. Return the maximum allowed exponent size in
|
|
||||||
bits. Must be at least 15.
|
|
||||||
|
|
||||||
@item RNDN
|
|
||||||
Read-only integer. Round to nearest, with ties to even rounding mode.
|
|
||||||
|
|
||||||
@item RNDZ
|
|
||||||
Read-only integer. Round to zero rounding mode.
|
|
||||||
|
|
||||||
@item RNDD
|
|
||||||
Read-only integer. Round to -Infinity rounding mode.
|
|
||||||
|
|
||||||
@item RNDU
|
|
||||||
Read-only integer. Round to +Infinity rounding mode.
|
|
||||||
|
|
||||||
@item RNDNA
|
|
||||||
Read-only integer. Round to nearest, with ties away from zero rounding mode.
|
|
||||||
|
|
||||||
@item RNDA
|
|
||||||
Read-only integer. Round away from zero rounding mode.
|
|
||||||
|
|
||||||
@item RNDF@footnote{Could be removed in case a deterministic behavior for floating point operations is required.}
|
|
||||||
Read-only integer. Faithful rounding mode. The result is
|
|
||||||
non-deterministically rounded to -Infinity or +Infinity. This rounding
|
|
||||||
mode usually gives a faster and deterministic running time for the
|
|
||||||
floating point operations.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@code{BigFloatEnv.prototype} properties:
|
|
||||||
|
|
||||||
@table @code
|
|
||||||
|
|
||||||
@item prec
|
|
||||||
Getter and setter (Integer). Return or set the precision in bits.
|
|
||||||
|
|
||||||
@item expBits
|
|
||||||
Getter and setter (Integer). Return or set the exponent size in bits
|
|
||||||
assuming an IEEE 754 representation.
|
|
||||||
|
|
||||||
@item rndMode
|
|
||||||
Getter and setter (Integer). Return or set the rounding mode.
|
|
||||||
|
|
||||||
@item subnormal
|
|
||||||
Getter and setter (Boolean). subnormal flag. It is false when
|
|
||||||
@code{expBits = expBitsMax}.
|
|
||||||
|
|
||||||
@item clearStatus()
|
|
||||||
Clear the status flags.
|
|
||||||
|
|
||||||
@item invalidOperation
|
|
||||||
@item divideByZero
|
|
||||||
@item overflow
|
|
||||||
@item underflow
|
|
||||||
@item inexact
|
|
||||||
Getter and setter (Boolean). Status flags.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@chapter BigDecimal
|
|
||||||
|
|
||||||
This extension adds the @code{BigDecimal} primitive type. The
|
|
||||||
@code{BigDecimal} type represents floating point numbers in base
|
|
||||||
10. It is inspired from the proposal available at
|
|
||||||
@url{https://github.com/littledan/proposal-bigdecimal}.
|
|
||||||
|
|
||||||
The @code{BigDecimal} floating point numbers are always normalized and
|
|
||||||
finite. There is no concept of @code{-0}, @code{Infinity} or
|
|
||||||
@code{NaN}. By default, all the computations are done with infinite
|
|
||||||
precision.
|
|
||||||
|
|
||||||
@section Operators
|
|
||||||
|
|
||||||
The following builtin operators support BigDecimal:
|
|
||||||
|
|
||||||
@table @code
|
|
||||||
|
|
||||||
@item +
|
|
||||||
@item -
|
|
||||||
@item *
|
|
||||||
Both operands must be BigDecimal. The result is computed with infinite
|
|
||||||
precision.
|
|
||||||
@item %
|
|
||||||
Both operands must be BigDecimal. The result is computed with infinite
|
|
||||||
precision. A range error is throws in case of division by zero.
|
|
||||||
|
|
||||||
@item /
|
|
||||||
Both operands must be BigDecimal. A range error is throws in case of
|
|
||||||
division by zero or if the result cannot be represented with infinite
|
|
||||||
precision (use @code{BigDecimal.div} to specify the rounding).
|
|
||||||
|
|
||||||
@item **
|
|
||||||
Both operands must be BigDecimal. The exponent must be a positive
|
|
||||||
integer. The result is computed with infinite precision.
|
|
||||||
|
|
||||||
@item ===
|
|
||||||
When one of the operand is a BigDecimal, return true if both operands
|
|
||||||
are a BigDecimal and if they are equal.
|
|
||||||
|
|
||||||
@item ==
|
|
||||||
@item !=
|
|
||||||
@item <=
|
|
||||||
@item >=
|
|
||||||
@item <
|
|
||||||
@item >
|
|
||||||
|
|
||||||
Numerical comparison. When one of the operand is not a BigDecimal, it is
|
|
||||||
converted to BigDecimal by using ToString(). Hence comparisons between
|
|
||||||
Number and BigDecimal do not use the exact mathematical value of the
|
|
||||||
Number value.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@section BigDecimal literals
|
|
||||||
|
|
||||||
BigDecimal literals are decimal floating point numbers with a trailing
|
|
||||||
@code{m} suffix.
|
|
||||||
|
|
||||||
@section Builtin Object changes
|
|
||||||
|
|
||||||
@subsection The @code{BigDecimal} function.
|
|
||||||
|
|
||||||
It returns @code{0m} if no parameter is provided. Otherwise the first
|
|
||||||
parameter is converted to a bigdecimal by using ToString(). Hence
|
|
||||||
Number values are not converted to their exact numerical value as
|
|
||||||
BigDecimal.
|
|
||||||
|
|
||||||
@subsection Properties of the @code{BigDecimal} object
|
|
||||||
|
|
||||||
@table @code
|
|
||||||
|
|
||||||
@item add(a, b[, e])
|
|
||||||
@item sub(a, b[, e])
|
|
||||||
@item mul(a, b[, e])
|
|
||||||
@item div(a, b[, e])
|
|
||||||
@item mod(a, b[, e])
|
|
||||||
@item sqrt(a, e)
|
|
||||||
@item round(a, e)
|
|
||||||
Perform the specified floating point operation and round the floating
|
|
||||||
point result according to the rounding object @code{e}. If the
|
|
||||||
rounding object is not present, the operation is executed with
|
|
||||||
infinite precision.
|
|
||||||
|
|
||||||
For @code{div}, a @code{RangeError} exception is thrown in case of
|
|
||||||
division by zero or if the result cannot be represented with infinite
|
|
||||||
precision if no rounding object is present.
|
|
||||||
|
|
||||||
For @code{sqrt}, a range error is thrown if @code{a} is less than
|
|
||||||
zero.
|
|
||||||
|
|
||||||
The rounding object must contain the following properties:
|
|
||||||
@code{roundingMode} is a string specifying the rounding mode
|
|
||||||
(@code{"floor"}, @code{"ceiling"}, @code{"down"}, @code{"up"},
|
|
||||||
@code{"half-even"}, @code{"half-up"}). Either
|
|
||||||
@code{maximumSignificantDigits} or @code{maximumFractionDigits} must
|
|
||||||
be present to specify respectively the number of significant digits
|
|
||||||
(must be >= 1) or the number of digits after the decimal point (must
|
|
||||||
be >= 0).
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@subsection Properties of the @code{BigDecimal.prototype} object
|
|
||||||
|
|
||||||
@table @code
|
|
||||||
@item valueOf()
|
|
||||||
Return the bigdecimal primitive value corresponding to @code{this}.
|
|
||||||
|
|
||||||
@item toString()
|
|
||||||
Convert @code{this} to a string with infinite precision in base 10.
|
|
||||||
|
|
||||||
@item toPrecision(p, rnd_mode = "half-up")
|
|
||||||
@item toFixed(p, rnd_mode = "half-up")
|
|
||||||
@item toExponential(p, rnd_mode = "half-up")
|
|
||||||
Convert the BigDecimal @code{this} to string with the specified
|
|
||||||
precision @code{p}. There is no limit on the accepted precision
|
|
||||||
@code{p}. The rounding mode can be optionally
|
|
||||||
specified. @code{toPrecision} outputs either in decimal fixed notation
|
|
||||||
or in decimal exponential notation with a @code{p} digits of
|
|
||||||
precision. @code{toExponential} outputs in decimal exponential
|
|
||||||
notation with @code{p} digits after the decimal point. @code{toFixed}
|
|
||||||
outputs in decimal notation with @code{p} digits after the decimal
|
|
||||||
point.
|
|
||||||
|
|
||||||
@end table
|
|
||||||
|
|
||||||
@chapter Math mode
|
|
||||||
|
|
||||||
A new @emph{math mode} is enabled with the @code{"use math"}
|
|
||||||
directive. It propagates the same way as the @emph{strict mode}. It is
|
|
||||||
designed so that arbitrarily large integers and floating point numbers
|
|
||||||
are available by default. In order to minimize the number of changes
|
|
||||||
in the Javascript semantics, integers are represented either as Number
|
|
||||||
or BigInt depending on their magnitude. Floating point numbers are
|
|
||||||
always represented as BigFloat.
|
|
||||||
|
|
||||||
The following changes are made to the Javascript semantics:
|
|
||||||
|
|
||||||
@itemize
|
|
||||||
|
|
||||||
@item Floating point literals (i.e. number with a decimal point or an exponent) are @code{BigFloat} by default (i.e. a @code{l} suffix is implied). Hence @code{typeof 1.0 === "bigfloat"}.
|
|
||||||
|
|
||||||
@item Integer literals (i.e. numbers without a decimal point or an exponent) with or without the @code{n} suffix are @code{BigInt} if their value cannot be represented as a safe integer. A safe integer is defined as a integer whose absolute value is smaller or equal to @code{2**53-1}. Hence @code{typeof 1 === "number "}, @code{typeof 1n === "number"} but @code{typeof 9007199254740992 === "bigint" }.
|
|
||||||
|
|
||||||
@item All the bigint builtin operators and functions are modified so that their result is returned as a Number if it is a safe integer. Otherwise the result stays a BigInt.
|
|
||||||
|
|
||||||
@item The builtin operators are modified so that they return an exact result (which can be a BigInt) if their operands are safe integers. Operands between Number and BigInt are accepted provided the Number operand is a safe integer. The integer power with a negative exponent returns a BigFloat as result. The integer division returns a BigFloat as result.
|
|
||||||
|
|
||||||
@item The @code{^} operator is an alias to the power operator (@code{**}).
|
|
||||||
|
|
||||||
@item The power operator (both @code{^} and @code{**}) grammar is modified so that @code{-2^2} is allowed and yields @code{-4}.
|
|
||||||
|
|
||||||
@item The logical xor operator is still available with the @code{^^} operator.
|
|
||||||
|
|
||||||
@item The modulo operator (@code{%}) returns the Euclidian remainder (always positive) instead of the truncated remainder.
|
|
||||||
|
|
||||||
@item The integer division operator can be overloaded with @code{Operators.updateBigIntOperators(dictionary)}.
|
|
||||||
|
|
||||||
@item The integer power operator with a non zero negative exponent can be overloaded with @code{Operators.updateBigIntOperators(dictionary)}.
|
|
||||||
|
|
||||||
@end itemize
|
|
||||||
|
|
||||||
@bye
|
|
File diff suppressed because it is too large
Load diff
8473
quickjs/libbf.c
8473
quickjs/libbf.c
File diff suppressed because it is too large
Load diff
535
quickjs/libbf.h
535
quickjs/libbf.h
|
@ -1,535 +0,0 @@
|
||||||
/*
|
|
||||||
* Tiny arbitrary precision floating point library
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017-2021 Fabrice Bellard
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#ifndef LIBBF_H
|
|
||||||
#define LIBBF_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#if defined(__SIZEOF_INT128__) && (INTPTR_MAX >= INT64_MAX)
|
|
||||||
#define LIMB_LOG2_BITS 6
|
|
||||||
#else
|
|
||||||
#define LIMB_LOG2_BITS 5
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define LIMB_BITS (1 << LIMB_LOG2_BITS)
|
|
||||||
|
|
||||||
#if LIMB_BITS == 64
|
|
||||||
typedef __int128 int128_t;
|
|
||||||
typedef unsigned __int128 uint128_t;
|
|
||||||
typedef int64_t slimb_t;
|
|
||||||
typedef uint64_t limb_t;
|
|
||||||
typedef uint128_t dlimb_t;
|
|
||||||
#define BF_RAW_EXP_MIN INT64_MIN
|
|
||||||
#define BF_RAW_EXP_MAX INT64_MAX
|
|
||||||
|
|
||||||
#define LIMB_DIGITS 19
|
|
||||||
#define BF_DEC_BASE UINT64_C(10000000000000000000)
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
typedef int32_t slimb_t;
|
|
||||||
typedef uint32_t limb_t;
|
|
||||||
typedef uint64_t dlimb_t;
|
|
||||||
#define BF_RAW_EXP_MIN INT32_MIN
|
|
||||||
#define BF_RAW_EXP_MAX INT32_MAX
|
|
||||||
|
|
||||||
#define LIMB_DIGITS 9
|
|
||||||
#define BF_DEC_BASE 1000000000U
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* in bits */
|
|
||||||
/* minimum number of bits for the exponent */
|
|
||||||
#define BF_EXP_BITS_MIN 3
|
|
||||||
/* maximum number of bits for the exponent */
|
|
||||||
#define BF_EXP_BITS_MAX (LIMB_BITS - 3)
|
|
||||||
/* extended range for exponent, used internally */
|
|
||||||
#define BF_EXT_EXP_BITS_MAX (BF_EXP_BITS_MAX + 1)
|
|
||||||
/* minimum possible precision */
|
|
||||||
#define BF_PREC_MIN 2
|
|
||||||
/* minimum possible precision */
|
|
||||||
#define BF_PREC_MAX (((limb_t)1 << (LIMB_BITS - 2)) - 2)
|
|
||||||
/* some operations support infinite precision */
|
|
||||||
#define BF_PREC_INF (BF_PREC_MAX + 1) /* infinite precision */
|
|
||||||
|
|
||||||
#if LIMB_BITS == 64
|
|
||||||
#define BF_CHKSUM_MOD (UINT64_C(975620677) * UINT64_C(9795002197))
|
|
||||||
#else
|
|
||||||
#define BF_CHKSUM_MOD 975620677U
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define BF_EXP_ZERO BF_RAW_EXP_MIN
|
|
||||||
#define BF_EXP_INF (BF_RAW_EXP_MAX - 1)
|
|
||||||
#define BF_EXP_NAN BF_RAW_EXP_MAX
|
|
||||||
|
|
||||||
/* +/-zero is represented with expn = BF_EXP_ZERO and len = 0,
|
|
||||||
+/-infinity is represented with expn = BF_EXP_INF and len = 0,
|
|
||||||
NaN is represented with expn = BF_EXP_NAN and len = 0 (sign is ignored)
|
|
||||||
*/
|
|
||||||
typedef struct {
|
|
||||||
struct bf_context_t *ctx;
|
|
||||||
int sign;
|
|
||||||
slimb_t expn;
|
|
||||||
limb_t len;
|
|
||||||
limb_t *tab;
|
|
||||||
} bf_t;
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
/* must be kept identical to bf_t */
|
|
||||||
struct bf_context_t *ctx;
|
|
||||||
int sign;
|
|
||||||
slimb_t expn;
|
|
||||||
limb_t len;
|
|
||||||
limb_t *tab;
|
|
||||||
} bfdec_t;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
BF_RNDN, /* round to nearest, ties to even */
|
|
||||||
BF_RNDZ, /* round to zero */
|
|
||||||
BF_RNDD, /* round to -inf (the code relies on (BF_RNDD xor BF_RNDU) = 1) */
|
|
||||||
BF_RNDU, /* round to +inf */
|
|
||||||
BF_RNDNA, /* round to nearest, ties away from zero */
|
|
||||||
BF_RNDA, /* round away from zero */
|
|
||||||
BF_RNDF, /* faithful rounding (nondeterministic, either RNDD or RNDU,
|
|
||||||
inexact flag is always set) */
|
|
||||||
} bf_rnd_t;
|
|
||||||
|
|
||||||
/* allow subnormal numbers. Only available if the number of exponent
|
|
||||||
bits is <= BF_EXP_BITS_USER_MAX and prec != BF_PREC_INF. */
|
|
||||||
#define BF_FLAG_SUBNORMAL (1 << 3)
|
|
||||||
/* 'prec' is the precision after the radix point instead of the whole
|
|
||||||
mantissa. Can only be used with bf_round() and
|
|
||||||
bfdec_[add|sub|mul|div|sqrt|round](). */
|
|
||||||
#define BF_FLAG_RADPNT_PREC (1 << 4)
|
|
||||||
|
|
||||||
#define BF_RND_MASK 0x7
|
|
||||||
#define BF_EXP_BITS_SHIFT 5
|
|
||||||
#define BF_EXP_BITS_MASK 0x3f
|
|
||||||
|
|
||||||
/* shortcut for bf_set_exp_bits(BF_EXT_EXP_BITS_MAX) */
|
|
||||||
#define BF_FLAG_EXT_EXP (BF_EXP_BITS_MASK << BF_EXP_BITS_SHIFT)
|
|
||||||
|
|
||||||
/* contains the rounding mode and number of exponents bits */
|
|
||||||
typedef uint32_t bf_flags_t;
|
|
||||||
|
|
||||||
typedef void *bf_realloc_func_t(void *opaque, void *ptr, size_t size);
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
bf_t val;
|
|
||||||
limb_t prec;
|
|
||||||
} BFConstCache;
|
|
||||||
|
|
||||||
typedef struct bf_context_t {
|
|
||||||
void *realloc_opaque;
|
|
||||||
bf_realloc_func_t *realloc_func;
|
|
||||||
BFConstCache log2_cache;
|
|
||||||
BFConstCache pi_cache;
|
|
||||||
struct BFNTTState *ntt_state;
|
|
||||||
} bf_context_t;
|
|
||||||
|
|
||||||
static inline int bf_get_exp_bits(bf_flags_t flags)
|
|
||||||
{
|
|
||||||
int e;
|
|
||||||
e = (flags >> BF_EXP_BITS_SHIFT) & BF_EXP_BITS_MASK;
|
|
||||||
if (e == BF_EXP_BITS_MASK)
|
|
||||||
return BF_EXP_BITS_MAX + 1;
|
|
||||||
else
|
|
||||||
return BF_EXP_BITS_MAX - e;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline bf_flags_t bf_set_exp_bits(int n)
|
|
||||||
{
|
|
||||||
return ((BF_EXP_BITS_MAX - n) & BF_EXP_BITS_MASK) << BF_EXP_BITS_SHIFT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* returned status */
|
|
||||||
#define BF_ST_INVALID_OP (1 << 0)
|
|
||||||
#define BF_ST_DIVIDE_ZERO (1 << 1)
|
|
||||||
#define BF_ST_OVERFLOW (1 << 2)
|
|
||||||
#define BF_ST_UNDERFLOW (1 << 3)
|
|
||||||
#define BF_ST_INEXACT (1 << 4)
|
|
||||||
/* indicate that a memory allocation error occured. NaN is returned */
|
|
||||||
#define BF_ST_MEM_ERROR (1 << 5)
|
|
||||||
|
|
||||||
#define BF_RADIX_MAX 36 /* maximum radix for bf_atof() and bf_ftoa() */
|
|
||||||
|
|
||||||
static inline slimb_t bf_max(slimb_t a, slimb_t b)
|
|
||||||
{
|
|
||||||
if (a > b)
|
|
||||||
return a;
|
|
||||||
else
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline slimb_t bf_min(slimb_t a, slimb_t b)
|
|
||||||
{
|
|
||||||
if (a < b)
|
|
||||||
return a;
|
|
||||||
else
|
|
||||||
return b;
|
|
||||||
}
|
|
||||||
|
|
||||||
void bf_context_init(bf_context_t *s, bf_realloc_func_t *realloc_func,
|
|
||||||
void *realloc_opaque);
|
|
||||||
void bf_context_end(bf_context_t *s);
|
|
||||||
/* free memory allocated for the bf cache data */
|
|
||||||
void bf_clear_cache(bf_context_t *s);
|
|
||||||
|
|
||||||
static inline void *bf_realloc(bf_context_t *s, void *ptr, size_t size)
|
|
||||||
{
|
|
||||||
return s->realloc_func(s->realloc_opaque, ptr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 'size' must be != 0 */
|
|
||||||
static inline void *bf_malloc(bf_context_t *s, size_t size)
|
|
||||||
{
|
|
||||||
return bf_realloc(s, NULL, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void bf_free(bf_context_t *s, void *ptr)
|
|
||||||
{
|
|
||||||
/* must test ptr otherwise equivalent to malloc(0) */
|
|
||||||
if (ptr)
|
|
||||||
bf_realloc(s, ptr, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void bf_init(bf_context_t *s, bf_t *r);
|
|
||||||
|
|
||||||
static inline void bf_delete(bf_t *r)
|
|
||||||
{
|
|
||||||
bf_context_t *s = r->ctx;
|
|
||||||
/* we accept to delete a zeroed bf_t structure */
|
|
||||||
if (s && r->tab) {
|
|
||||||
bf_realloc(s, r->tab, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void bf_neg(bf_t *r)
|
|
||||||
{
|
|
||||||
r->sign ^= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int bf_is_finite(const bf_t *a)
|
|
||||||
{
|
|
||||||
return (a->expn < BF_EXP_INF);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int bf_is_nan(const bf_t *a)
|
|
||||||
{
|
|
||||||
return (a->expn == BF_EXP_NAN);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int bf_is_zero(const bf_t *a)
|
|
||||||
{
|
|
||||||
return (a->expn == BF_EXP_ZERO);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void bf_memcpy(bf_t *r, const bf_t *a)
|
|
||||||
{
|
|
||||||
*r = *a;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bf_set_ui(bf_t *r, uint64_t a);
|
|
||||||
int bf_set_si(bf_t *r, int64_t a);
|
|
||||||
void bf_set_nan(bf_t *r);
|
|
||||||
void bf_set_zero(bf_t *r, int is_neg);
|
|
||||||
void bf_set_inf(bf_t *r, int is_neg);
|
|
||||||
int bf_set(bf_t *r, const bf_t *a);
|
|
||||||
void bf_move(bf_t *r, bf_t *a);
|
|
||||||
int bf_get_float64(const bf_t *a, double *pres, bf_rnd_t rnd_mode);
|
|
||||||
int bf_set_float64(bf_t *a, double d);
|
|
||||||
|
|
||||||
int bf_cmpu(const bf_t *a, const bf_t *b);
|
|
||||||
int bf_cmp_full(const bf_t *a, const bf_t *b);
|
|
||||||
int bf_cmp(const bf_t *a, const bf_t *b);
|
|
||||||
static inline int bf_cmp_eq(const bf_t *a, const bf_t *b)
|
|
||||||
{
|
|
||||||
return bf_cmp(a, b) == 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int bf_cmp_le(const bf_t *a, const bf_t *b)
|
|
||||||
{
|
|
||||||
return bf_cmp(a, b) <= 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int bf_cmp_lt(const bf_t *a, const bf_t *b)
|
|
||||||
{
|
|
||||||
return bf_cmp(a, b) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bf_add(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec, bf_flags_t flags);
|
|
||||||
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_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_si(bf_t *r, const bf_t *a, int64_t b1, 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);
|
|
||||||
#define BF_DIVREM_EUCLIDIAN BF_RNDF
|
|
||||||
int bf_divrem(bf_t *q, bf_t *r, const bf_t *a, const bf_t *b,
|
|
||||||
limb_t prec, bf_flags_t flags, int rnd_mode);
|
|
||||||
int bf_rem(bf_t *r, const bf_t *a, const bf_t *b, limb_t prec,
|
|
||||||
bf_flags_t flags, int rnd_mode);
|
|
||||||
int bf_remquo(slimb_t *pq, bf_t *r, const bf_t *a, const bf_t *b, limb_t prec,
|
|
||||||
bf_flags_t flags, int rnd_mode);
|
|
||||||
/* round to integer with infinite precision */
|
|
||||||
int bf_rint(bf_t *r, int rnd_mode);
|
|
||||||
int bf_round(bf_t *r, limb_t prec, bf_flags_t flags);
|
|
||||||
int bf_sqrtrem(bf_t *r, bf_t *rem1, const bf_t *a);
|
|
||||||
int bf_sqrt(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
|
|
||||||
slimb_t bf_get_exp_min(const bf_t *a);
|
|
||||||
int bf_logic_or(bf_t *r, const bf_t *a, const bf_t *b);
|
|
||||||
int bf_logic_xor(bf_t *r, const bf_t *a, const bf_t *b);
|
|
||||||
int bf_logic_and(bf_t *r, const bf_t *a, const bf_t *b);
|
|
||||||
|
|
||||||
/* additional flags for bf_atof */
|
|
||||||
/* do not accept hex radix prefix (0x or 0X) if radix = 0 or radix = 16 */
|
|
||||||
#define BF_ATOF_NO_HEX (1 << 16)
|
|
||||||
/* accept binary (0b or 0B) or octal (0o or 0O) radix prefix if radix = 0 */
|
|
||||||
#define BF_ATOF_BIN_OCT (1 << 17)
|
|
||||||
/* Do not parse NaN or Inf */
|
|
||||||
#define BF_ATOF_NO_NAN_INF (1 << 18)
|
|
||||||
/* return the exponent separately */
|
|
||||||
#define BF_ATOF_EXPONENT (1 << 19)
|
|
||||||
|
|
||||||
int bf_atof(bf_t *a, const char *str, const char **pnext, int radix,
|
|
||||||
limb_t prec, bf_flags_t flags);
|
|
||||||
/* this version accepts prec = BF_PREC_INF and returns the radix
|
|
||||||
exponent */
|
|
||||||
int bf_atof2(bf_t *r, slimb_t *pexponent,
|
|
||||||
const char *str, const char **pnext, int radix,
|
|
||||||
limb_t prec, bf_flags_t flags);
|
|
||||||
int bf_mul_pow_radix(bf_t *r, const bf_t *T, limb_t radix,
|
|
||||||
slimb_t expn, limb_t prec, bf_flags_t flags);
|
|
||||||
|
|
||||||
|
|
||||||
/* Conversion of floating point number to string. Return a null
|
|
||||||
terminated string or NULL if memory error. *plen contains its
|
|
||||||
length if plen != NULL. The exponent letter is "e" for base 10,
|
|
||||||
"p" for bases 2, 8, 16 with a binary exponent and "@" for the other
|
|
||||||
bases. */
|
|
||||||
|
|
||||||
#define BF_FTOA_FORMAT_MASK (3 << 16)
|
|
||||||
|
|
||||||
/* fixed format: prec significant digits rounded with (flags &
|
|
||||||
BF_RND_MASK). Exponential notation is used if too many zeros are
|
|
||||||
needed.*/
|
|
||||||
#define BF_FTOA_FORMAT_FIXED (0 << 16)
|
|
||||||
/* fractional format: prec digits after the decimal point rounded with
|
|
||||||
(flags & BF_RND_MASK) */
|
|
||||||
#define BF_FTOA_FORMAT_FRAC (1 << 16)
|
|
||||||
/* free format:
|
|
||||||
|
|
||||||
For binary radices with bf_ftoa() and for bfdec_ftoa(): use the minimum
|
|
||||||
number of digits to represent 'a'. The precision and the rounding
|
|
||||||
mode are ignored.
|
|
||||||
|
|
||||||
For the non binary radices with bf_ftoa(): use as many digits as
|
|
||||||
necessary so that bf_atof() return the same number when using
|
|
||||||
precision 'prec', rounding to nearest and the subnormal
|
|
||||||
configuration of 'flags'. The result is meaningful only if 'a' is
|
|
||||||
already rounded to 'prec' bits. If the subnormal flag is set, the
|
|
||||||
exponent in 'flags' must also be set to the desired exponent range.
|
|
||||||
*/
|
|
||||||
#define BF_FTOA_FORMAT_FREE (2 << 16)
|
|
||||||
/* same as BF_FTOA_FORMAT_FREE but uses the minimum number of digits
|
|
||||||
(takes more computation time). Identical to BF_FTOA_FORMAT_FREE for
|
|
||||||
binary radices with bf_ftoa() and for bfdec_ftoa(). */
|
|
||||||
#define BF_FTOA_FORMAT_FREE_MIN (3 << 16)
|
|
||||||
|
|
||||||
/* force exponential notation for fixed or free format */
|
|
||||||
#define BF_FTOA_FORCE_EXP (1 << 20)
|
|
||||||
/* add 0x prefix for base 16, 0o prefix for base 8 or 0b prefix for
|
|
||||||
base 2 if non zero value */
|
|
||||||
#define BF_FTOA_ADD_PREFIX (1 << 21)
|
|
||||||
/* return "Infinity" instead of "Inf" and add a "+" for positive
|
|
||||||
exponents */
|
|
||||||
#define BF_FTOA_JS_QUIRKS (1 << 22)
|
|
||||||
|
|
||||||
char *bf_ftoa(size_t *plen, const bf_t *a, int radix, limb_t prec,
|
|
||||||
bf_flags_t flags);
|
|
||||||
|
|
||||||
/* modulo 2^n instead of saturation. NaN and infinity return 0 */
|
|
||||||
#define BF_GET_INT_MOD (1 << 0)
|
|
||||||
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_uint64(uint64_t *pres, const bf_t *a);
|
|
||||||
|
|
||||||
/* the following functions are exported for testing only. */
|
|
||||||
void mp_print_str(const char *str, const limb_t *tab, limb_t n);
|
|
||||||
void bf_print_str(const char *str, const bf_t *a);
|
|
||||||
int bf_resize(bf_t *r, limb_t len);
|
|
||||||
int bf_get_fft_size(int *pdpl, int *pnb_mods, limb_t len);
|
|
||||||
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);
|
|
||||||
slimb_t bf_mul_log2_radix(slimb_t a1, unsigned int radix, int is_inv,
|
|
||||||
int is_ceil1);
|
|
||||||
int mp_mul(bf_context_t *s, limb_t *result,
|
|
||||||
const limb_t *op1, limb_t op1_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 n, limb_t carry);
|
|
||||||
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_recip(bf_context_t *s, limb_t *tabr, const limb_t *taba, limb_t n);
|
|
||||||
limb_t bf_isqrt(limb_t a);
|
|
||||||
|
|
||||||
/* transcendental functions */
|
|
||||||
int bf_const_log2(bf_t *T, limb_t prec, bf_flags_t flags);
|
|
||||||
int bf_const_pi(bf_t *T, limb_t prec, bf_flags_t flags);
|
|
||||||
int bf_exp(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
|
|
||||||
int bf_log(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
|
|
||||||
#define BF_POW_JS_QUIRKS (1 << 16) /* (+/-1)^(+/-Inf) = NaN, 1^NaN = NaN */
|
|
||||||
int bf_pow(bf_t *r, const bf_t *x, const bf_t *y, limb_t prec, bf_flags_t flags);
|
|
||||||
int bf_cos(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
|
|
||||||
int bf_sin(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
|
|
||||||
int bf_tan(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
|
|
||||||
int bf_atan(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
|
|
||||||
int bf_atan2(bf_t *r, const bf_t *y, const bf_t *x,
|
|
||||||
limb_t prec, bf_flags_t flags);
|
|
||||||
int bf_asin(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
|
|
||||||
int bf_acos(bf_t *r, const bf_t *a, limb_t prec, bf_flags_t flags);
|
|
||||||
|
|
||||||
/* decimal floating point */
|
|
||||||
|
|
||||||
static inline void bfdec_init(bf_context_t *s, bfdec_t *r)
|
|
||||||
{
|
|
||||||
bf_init(s, (bf_t *)r);
|
|
||||||
}
|
|
||||||
static inline void bfdec_delete(bfdec_t *r)
|
|
||||||
{
|
|
||||||
bf_delete((bf_t *)r);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void bfdec_neg(bfdec_t *r)
|
|
||||||
{
|
|
||||||
r->sign ^= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int bfdec_is_finite(const bfdec_t *a)
|
|
||||||
{
|
|
||||||
return (a->expn < BF_EXP_INF);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int bfdec_is_nan(const bfdec_t *a)
|
|
||||||
{
|
|
||||||
return (a->expn == BF_EXP_NAN);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int bfdec_is_zero(const bfdec_t *a)
|
|
||||||
{
|
|
||||||
return (a->expn == BF_EXP_ZERO);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void bfdec_memcpy(bfdec_t *r, const bfdec_t *a)
|
|
||||||
{
|
|
||||||
bf_memcpy((bf_t *)r, (const bf_t *)a);
|
|
||||||
}
|
|
||||||
|
|
||||||
int bfdec_set_ui(bfdec_t *r, uint64_t a);
|
|
||||||
int bfdec_set_si(bfdec_t *r, int64_t a);
|
|
||||||
|
|
||||||
static inline void bfdec_set_nan(bfdec_t *r)
|
|
||||||
{
|
|
||||||
bf_set_nan((bf_t *)r);
|
|
||||||
}
|
|
||||||
static inline void bfdec_set_zero(bfdec_t *r, int is_neg)
|
|
||||||
{
|
|
||||||
bf_set_zero((bf_t *)r, is_neg);
|
|
||||||
}
|
|
||||||
static inline void bfdec_set_inf(bfdec_t *r, int is_neg)
|
|
||||||
{
|
|
||||||
bf_set_inf((bf_t *)r, is_neg);
|
|
||||||
}
|
|
||||||
static inline int bfdec_set(bfdec_t *r, const bfdec_t *a)
|
|
||||||
{
|
|
||||||
return bf_set((bf_t *)r, (bf_t *)a);
|
|
||||||
}
|
|
||||||
static inline void bfdec_move(bfdec_t *r, bfdec_t *a)
|
|
||||||
{
|
|
||||||
bf_move((bf_t *)r, (bf_t *)a);
|
|
||||||
}
|
|
||||||
static inline int bfdec_cmpu(const bfdec_t *a, const bfdec_t *b)
|
|
||||||
{
|
|
||||||
return bf_cmpu((const bf_t *)a, (const bf_t *)b);
|
|
||||||
}
|
|
||||||
static inline int bfdec_cmp_full(const bfdec_t *a, const bfdec_t *b)
|
|
||||||
{
|
|
||||||
return bf_cmp_full((const bf_t *)a, (const bf_t *)b);
|
|
||||||
}
|
|
||||||
static inline int bfdec_cmp(const bfdec_t *a, const bfdec_t *b)
|
|
||||||
{
|
|
||||||
return bf_cmp((const bf_t *)a, (const bf_t *)b);
|
|
||||||
}
|
|
||||||
static inline int bfdec_cmp_eq(const bfdec_t *a, const bfdec_t *b)
|
|
||||||
{
|
|
||||||
return bfdec_cmp(a, b) == 0;
|
|
||||||
}
|
|
||||||
static inline int bfdec_cmp_le(const bfdec_t *a, const bfdec_t *b)
|
|
||||||
{
|
|
||||||
return bfdec_cmp(a, b) <= 0;
|
|
||||||
}
|
|
||||||
static inline int bfdec_cmp_lt(const bfdec_t *a, const bfdec_t *b)
|
|
||||||
{
|
|
||||||
return bfdec_cmp(a, b) < 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int bfdec_add(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
|
|
||||||
bf_flags_t flags);
|
|
||||||
int bfdec_sub(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
|
|
||||||
bf_flags_t flags);
|
|
||||||
int bfdec_add_si(bfdec_t *r, const bfdec_t *a, int64_t b1, limb_t prec,
|
|
||||||
bf_flags_t flags);
|
|
||||||
int bfdec_mul(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
|
|
||||||
bf_flags_t flags);
|
|
||||||
int bfdec_mul_si(bfdec_t *r, const bfdec_t *a, int64_t b1, limb_t prec,
|
|
||||||
bf_flags_t flags);
|
|
||||||
int bfdec_div(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
|
|
||||||
bf_flags_t flags);
|
|
||||||
int bfdec_divrem(bfdec_t *q, bfdec_t *r, const bfdec_t *a, const bfdec_t *b,
|
|
||||||
limb_t prec, bf_flags_t flags, int rnd_mode);
|
|
||||||
int bfdec_rem(bfdec_t *r, const bfdec_t *a, const bfdec_t *b, limb_t prec,
|
|
||||||
bf_flags_t flags, int rnd_mode);
|
|
||||||
int bfdec_rint(bfdec_t *r, int rnd_mode);
|
|
||||||
int bfdec_sqrt(bfdec_t *r, const bfdec_t *a, limb_t prec, bf_flags_t flags);
|
|
||||||
int bfdec_round(bfdec_t *r, limb_t prec, bf_flags_t flags);
|
|
||||||
int bfdec_get_int32(int *pres, const bfdec_t *a);
|
|
||||||
int bfdec_pow_ui(bfdec_t *r, const bfdec_t *a, limb_t b);
|
|
||||||
|
|
||||||
char *bfdec_ftoa(size_t *plen, const bfdec_t *a, limb_t prec, bf_flags_t flags);
|
|
||||||
int bfdec_atof(bfdec_t *r, const char *str, const char **pnext,
|
|
||||||
limb_t prec, bf_flags_t flags);
|
|
||||||
|
|
||||||
/* the following functions are exported for testing only. */
|
|
||||||
extern const limb_t mp_pow_dec[LIMB_DIGITS + 1];
|
|
||||||
void bfdec_print_str(const char *str, const bfdec_t *a);
|
|
||||||
static inline int bfdec_resize(bfdec_t *r, limb_t len)
|
|
||||||
{
|
|
||||||
return bf_resize((bf_t *)r, len);
|
|
||||||
}
|
|
||||||
int bfdec_normalize_and_round(bfdec_t *r, limb_t prec1, bf_flags_t flags);
|
|
||||||
|
|
||||||
#endif /* LIBBF_H */
|
|
|
@ -1,57 +0,0 @@
|
||||||
/*
|
|
||||||
* Regular Expression Engine
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017-2018 Fabrice Bellard
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef DEF
|
|
||||||
|
|
||||||
DEF(invalid, 1) /* never used */
|
|
||||||
DEF(char, 3)
|
|
||||||
DEF(char32, 5)
|
|
||||||
DEF(dot, 1)
|
|
||||||
DEF(any, 1) /* same as dot but match any character including line terminator */
|
|
||||||
DEF(line_start, 1)
|
|
||||||
DEF(line_end, 1)
|
|
||||||
DEF(goto, 5)
|
|
||||||
DEF(split_goto_first, 5)
|
|
||||||
DEF(split_next_first, 5)
|
|
||||||
DEF(match, 1)
|
|
||||||
DEF(save_start, 2) /* save start position */
|
|
||||||
DEF(save_end, 2) /* save end position, must come after saved_start */
|
|
||||||
DEF(save_reset, 3) /* reset save positions */
|
|
||||||
DEF(loop, 5) /* decrement the top the stack and goto if != 0 */
|
|
||||||
DEF(push_i32, 5) /* push integer on the stack */
|
|
||||||
DEF(drop, 1)
|
|
||||||
DEF(word_boundary, 1)
|
|
||||||
DEF(not_word_boundary, 1)
|
|
||||||
DEF(back_reference, 2)
|
|
||||||
DEF(backward_back_reference, 2) /* must come after back_reference */
|
|
||||||
DEF(range, 3) /* variable length */
|
|
||||||
DEF(range32, 3) /* variable length */
|
|
||||||
DEF(lookahead, 5)
|
|
||||||
DEF(negative_lookahead, 5)
|
|
||||||
DEF(push_char_pos, 1) /* push the character position on the stack */
|
|
||||||
DEF(check_advance, 1) /* pop one stack element and check that it is different from the character position */
|
|
||||||
DEF(prev, 1) /* go to the previous char */
|
|
||||||
DEF(simple_greedy_quant, 17)
|
|
||||||
|
|
||||||
#endif /* DEF */
|
|
2529
quickjs/libregexp.c
2529
quickjs/libregexp.c
File diff suppressed because it is too large
Load diff
|
@ -1,93 +0,0 @@
|
||||||
/*
|
|
||||||
* Regular Expression Engine
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017-2018 Fabrice Bellard
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#ifndef LIBREGEXP_H
|
|
||||||
#define LIBREGEXP_H
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
|
|
||||||
#include "libunicode.h"
|
|
||||||
|
|
||||||
#define LRE_BOOL int /* for documentation purposes */
|
|
||||||
|
|
||||||
#define LRE_FLAG_GLOBAL (1 << 0)
|
|
||||||
#define LRE_FLAG_IGNORECASE (1 << 1)
|
|
||||||
#define LRE_FLAG_MULTILINE (1 << 2)
|
|
||||||
#define LRE_FLAG_DOTALL (1 << 3)
|
|
||||||
#define LRE_FLAG_UTF16 (1 << 4)
|
|
||||||
#define LRE_FLAG_STICKY (1 << 5)
|
|
||||||
#define LRE_FLAG_INDICES (1 << 6) /* Unused by libregexp, just recorded. */
|
|
||||||
|
|
||||||
#define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */
|
|
||||||
|
|
||||||
uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
|
|
||||||
const char *buf, size_t buf_len, int re_flags,
|
|
||||||
void *opaque);
|
|
||||||
int lre_get_capture_count(const uint8_t *bc_buf);
|
|
||||||
int lre_get_flags(const uint8_t *bc_buf);
|
|
||||||
const char *lre_get_groupnames(const uint8_t *bc_buf);
|
|
||||||
int lre_exec(uint8_t **capture,
|
|
||||||
const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen,
|
|
||||||
int cbuf_type, void *opaque);
|
|
||||||
|
|
||||||
int lre_parse_escape(const uint8_t **pp, int allow_utf16);
|
|
||||||
LRE_BOOL lre_is_space(int c);
|
|
||||||
|
|
||||||
/* must be provided by the user */
|
|
||||||
LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size);
|
|
||||||
void *lre_realloc(void *opaque, void *ptr, size_t size);
|
|
||||||
|
|
||||||
/* JS identifier test */
|
|
||||||
extern uint32_t const lre_id_start_table_ascii[4];
|
|
||||||
extern uint32_t const lre_id_continue_table_ascii[4];
|
|
||||||
|
|
||||||
static inline int lre_js_is_ident_first(int c)
|
|
||||||
{
|
|
||||||
if ((uint32_t)c < 128) {
|
|
||||||
return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1;
|
|
||||||
} else {
|
|
||||||
#ifdef CONFIG_ALL_UNICODE
|
|
||||||
return lre_is_id_start(c);
|
|
||||||
#else
|
|
||||||
return !lre_is_space(c);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int lre_js_is_ident_next(int c)
|
|
||||||
{
|
|
||||||
if ((uint32_t)c < 128) {
|
|
||||||
return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1;
|
|
||||||
} else {
|
|
||||||
/* ZWNJ and ZWJ are accepted in identifiers */
|
|
||||||
#ifdef CONFIG_ALL_UNICODE
|
|
||||||
return lre_is_id_continue(c) || c == 0x200C || c == 0x200D;
|
|
||||||
#else
|
|
||||||
return !lre_is_space(c) || c == 0x200C || c == 0x200D;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#undef LRE_BOOL
|
|
||||||
|
|
||||||
#endif /* LIBREGEXP_H */
|
|
File diff suppressed because it is too large
Load diff
1788
quickjs/libunicode.c
1788
quickjs/libunicode.c
File diff suppressed because it is too large
Load diff
|
@ -1,127 +0,0 @@
|
||||||
/*
|
|
||||||
* Unicode utilities
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017-2018 Fabrice Bellard
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#ifndef LIBUNICODE_H
|
|
||||||
#define LIBUNICODE_H
|
|
||||||
|
|
||||||
#include <inttypes.h>
|
|
||||||
|
|
||||||
#define LRE_BOOL int /* for documentation purposes */
|
|
||||||
|
|
||||||
/* define it to include all the unicode tables (40KB larger) */
|
|
||||||
#define CONFIG_ALL_UNICODE
|
|
||||||
|
|
||||||
#define LRE_CC_RES_LEN_MAX 3
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
UNICODE_NFC,
|
|
||||||
UNICODE_NFD,
|
|
||||||
UNICODE_NFKC,
|
|
||||||
UNICODE_NFKD,
|
|
||||||
} UnicodeNormalizationEnum;
|
|
||||||
|
|
||||||
int lre_case_conv(uint32_t *res, uint32_t c, int conv_type);
|
|
||||||
int lre_canonicalize(uint32_t c, BOOL is_unicode);
|
|
||||||
LRE_BOOL lre_is_cased(uint32_t c);
|
|
||||||
LRE_BOOL lre_is_case_ignorable(uint32_t c);
|
|
||||||
|
|
||||||
/* char ranges */
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
int len; /* in points, always even */
|
|
||||||
int size;
|
|
||||||
uint32_t *points; /* points sorted by increasing value */
|
|
||||||
void *mem_opaque;
|
|
||||||
void *(*realloc_func)(void *opaque, void *ptr, size_t size);
|
|
||||||
} CharRange;
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
CR_OP_UNION,
|
|
||||||
CR_OP_INTER,
|
|
||||||
CR_OP_XOR,
|
|
||||||
} CharRangeOpEnum;
|
|
||||||
|
|
||||||
void cr_init(CharRange *cr, void *mem_opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size));
|
|
||||||
void cr_free(CharRange *cr);
|
|
||||||
int cr_realloc(CharRange *cr, int size);
|
|
||||||
int cr_copy(CharRange *cr, const CharRange *cr1);
|
|
||||||
|
|
||||||
static inline int cr_add_point(CharRange *cr, uint32_t v)
|
|
||||||
{
|
|
||||||
if (cr->len >= cr->size) {
|
|
||||||
if (cr_realloc(cr, cr->len + 1))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
cr->points[cr->len++] = v;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int cr_add_interval(CharRange *cr, uint32_t c1, uint32_t c2)
|
|
||||||
{
|
|
||||||
if ((cr->len + 2) > cr->size) {
|
|
||||||
if (cr_realloc(cr, cr->len + 2))
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
cr->points[cr->len++] = c1;
|
|
||||||
cr->points[cr->len++] = c2;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int cr_union1(CharRange *cr, const uint32_t *b_pt, int b_len);
|
|
||||||
|
|
||||||
static inline int cr_union_interval(CharRange *cr, uint32_t c1, uint32_t c2)
|
|
||||||
{
|
|
||||||
uint32_t b_pt[2];
|
|
||||||
b_pt[0] = c1;
|
|
||||||
b_pt[1] = c2 + 1;
|
|
||||||
return cr_union1(cr, b_pt, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len,
|
|
||||||
const uint32_t *b_pt, int b_len, int op);
|
|
||||||
|
|
||||||
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_continue(uint32_t c);
|
|
||||||
|
|
||||||
int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
|
|
||||||
UnicodeNormalizationEnum n_type,
|
|
||||||
void *opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size));
|
|
||||||
|
|
||||||
/* Unicode character range functions */
|
|
||||||
|
|
||||||
int unicode_script(CharRange *cr,
|
|
||||||
const char *script_name, LRE_BOOL is_ext);
|
|
||||||
int unicode_general_category(CharRange *cr, const char *gc_name);
|
|
||||||
int unicode_prop(CharRange *cr, const char *prop_name);
|
|
||||||
|
|
||||||
#endif /* CONFIG_ALL_UNICODE */
|
|
||||||
|
|
||||||
#undef LRE_BOOL
|
|
||||||
|
|
||||||
#endif /* LIBUNICODE_H */
|
|
|
@ -1,99 +0,0 @@
|
||||||
/*
|
|
||||||
* Linux klist like system
|
|
||||||
*
|
|
||||||
* Copyright (c) 2016-2017 Fabrice Bellard
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#ifndef LIST_H
|
|
||||||
#define LIST_H
|
|
||||||
|
|
||||||
#ifndef NULL
|
|
||||||
#include <stddef.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct list_head {
|
|
||||||
struct list_head *prev;
|
|
||||||
struct list_head *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
#define LIST_HEAD_INIT(el) { &(el), &(el) }
|
|
||||||
|
|
||||||
/* return the pointer of type 'type *' containing 'el' as field 'member' */
|
|
||||||
#define list_entry(el, type, member) container_of(el, type, member)
|
|
||||||
|
|
||||||
static inline void init_list_head(struct list_head *head)
|
|
||||||
{
|
|
||||||
head->prev = head;
|
|
||||||
head->next = head;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* insert 'el' between 'prev' and 'next' */
|
|
||||||
static inline void __list_add(struct list_head *el,
|
|
||||||
struct list_head *prev, struct list_head *next)
|
|
||||||
{
|
|
||||||
prev->next = el;
|
|
||||||
el->prev = prev;
|
|
||||||
el->next = next;
|
|
||||||
next->prev = el;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add 'el' at the head of the list 'head' (= after element head) */
|
|
||||||
static inline void list_add(struct list_head *el, struct list_head *head)
|
|
||||||
{
|
|
||||||
__list_add(el, head, head->next);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* add 'el' at the end of the list 'head' (= before element head) */
|
|
||||||
static inline void list_add_tail(struct list_head *el, struct list_head *head)
|
|
||||||
{
|
|
||||||
__list_add(el, head->prev, head);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline void list_del(struct list_head *el)
|
|
||||||
{
|
|
||||||
struct list_head *prev, *next;
|
|
||||||
prev = el->prev;
|
|
||||||
next = el->next;
|
|
||||||
prev->next = next;
|
|
||||||
next->prev = prev;
|
|
||||||
el->prev = 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) \
|
|
||||||
for(el = (head)->next; el != (head); el = el->next)
|
|
||||||
|
|
||||||
#define list_for_each_safe(el, el1, head) \
|
|
||||||
for(el = (head)->next, el1 = el->next; el != (head); \
|
|
||||||
el = el1, el1 = el->next)
|
|
||||||
|
|
||||||
#define list_for_each_prev(el, head) \
|
|
||||||
for(el = (head)->prev; el != (head); el = el->prev)
|
|
||||||
|
|
||||||
#define list_for_each_prev_safe(el, el1, head) \
|
|
||||||
for(el = (head)->prev, el1 = el->prev; el != (head); \
|
|
||||||
el = el1, el1 = el->prev)
|
|
||||||
|
|
||||||
#endif /* LIST_H */
|
|
|
@ -1,273 +0,0 @@
|
||||||
/*
|
|
||||||
* QuickJS atom definitions
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017-2018 Fabrice Bellard
|
|
||||||
* Copyright (c) 2017-2018 Charlie Gordon
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef DEF
|
|
||||||
|
|
||||||
/* Note: first atoms are considered as keywords in the parser */
|
|
||||||
DEF(null, "null") /* must be first */
|
|
||||||
DEF(false, "false")
|
|
||||||
DEF(true, "true")
|
|
||||||
DEF(if, "if")
|
|
||||||
DEF(else, "else")
|
|
||||||
DEF(return, "return")
|
|
||||||
DEF(var, "var")
|
|
||||||
DEF(this, "this")
|
|
||||||
DEF(delete, "delete")
|
|
||||||
DEF(void, "void")
|
|
||||||
DEF(typeof, "typeof")
|
|
||||||
DEF(new, "new")
|
|
||||||
DEF(in, "in")
|
|
||||||
DEF(instanceof, "instanceof")
|
|
||||||
DEF(do, "do")
|
|
||||||
DEF(while, "while")
|
|
||||||
DEF(for, "for")
|
|
||||||
DEF(break, "break")
|
|
||||||
DEF(continue, "continue")
|
|
||||||
DEF(switch, "switch")
|
|
||||||
DEF(case, "case")
|
|
||||||
DEF(default, "default")
|
|
||||||
DEF(throw, "throw")
|
|
||||||
DEF(try, "try")
|
|
||||||
DEF(catch, "catch")
|
|
||||||
DEF(finally, "finally")
|
|
||||||
DEF(function, "function")
|
|
||||||
DEF(debugger, "debugger")
|
|
||||||
DEF(with, "with")
|
|
||||||
/* FutureReservedWord */
|
|
||||||
DEF(class, "class")
|
|
||||||
DEF(const, "const")
|
|
||||||
DEF(enum, "enum")
|
|
||||||
DEF(export, "export")
|
|
||||||
DEF(extends, "extends")
|
|
||||||
DEF(import, "import")
|
|
||||||
DEF(super, "super")
|
|
||||||
/* FutureReservedWords when parsing strict mode code */
|
|
||||||
DEF(implements, "implements")
|
|
||||||
DEF(interface, "interface")
|
|
||||||
DEF(let, "let")
|
|
||||||
DEF(package, "package")
|
|
||||||
DEF(private, "private")
|
|
||||||
DEF(protected, "protected")
|
|
||||||
DEF(public, "public")
|
|
||||||
DEF(static, "static")
|
|
||||||
DEF(yield, "yield")
|
|
||||||
DEF(await, "await")
|
|
||||||
|
|
||||||
/* empty string */
|
|
||||||
DEF(empty_string, "")
|
|
||||||
/* identifiers */
|
|
||||||
DEF(length, "length")
|
|
||||||
DEF(fileName, "fileName")
|
|
||||||
DEF(lineNumber, "lineNumber")
|
|
||||||
DEF(message, "message")
|
|
||||||
DEF(cause, "cause")
|
|
||||||
DEF(errors, "errors")
|
|
||||||
DEF(stack, "stack")
|
|
||||||
DEF(name, "name")
|
|
||||||
DEF(toString, "toString")
|
|
||||||
DEF(toLocaleString, "toLocaleString")
|
|
||||||
DEF(valueOf, "valueOf")
|
|
||||||
DEF(eval, "eval")
|
|
||||||
DEF(prototype, "prototype")
|
|
||||||
DEF(constructor, "constructor")
|
|
||||||
DEF(configurable, "configurable")
|
|
||||||
DEF(writable, "writable")
|
|
||||||
DEF(enumerable, "enumerable")
|
|
||||||
DEF(value, "value")
|
|
||||||
DEF(get, "get")
|
|
||||||
DEF(set, "set")
|
|
||||||
DEF(of, "of")
|
|
||||||
DEF(__proto__, "__proto__")
|
|
||||||
DEF(undefined, "undefined")
|
|
||||||
DEF(number, "number")
|
|
||||||
DEF(boolean, "boolean")
|
|
||||||
DEF(string, "string")
|
|
||||||
DEF(object, "object")
|
|
||||||
DEF(symbol, "symbol")
|
|
||||||
DEF(integer, "integer")
|
|
||||||
DEF(unknown, "unknown")
|
|
||||||
DEF(arguments, "arguments")
|
|
||||||
DEF(callee, "callee")
|
|
||||||
DEF(caller, "caller")
|
|
||||||
DEF(_eval_, "<eval>")
|
|
||||||
DEF(_ret_, "<ret>")
|
|
||||||
DEF(_var_, "<var>")
|
|
||||||
DEF(_arg_var_, "<arg_var>")
|
|
||||||
DEF(_with_, "<with>")
|
|
||||||
DEF(lastIndex, "lastIndex")
|
|
||||||
DEF(target, "target")
|
|
||||||
DEF(index, "index")
|
|
||||||
DEF(input, "input")
|
|
||||||
DEF(defineProperties, "defineProperties")
|
|
||||||
DEF(apply, "apply")
|
|
||||||
DEF(join, "join")
|
|
||||||
DEF(concat, "concat")
|
|
||||||
DEF(split, "split")
|
|
||||||
DEF(construct, "construct")
|
|
||||||
DEF(getPrototypeOf, "getPrototypeOf")
|
|
||||||
DEF(setPrototypeOf, "setPrototypeOf")
|
|
||||||
DEF(isExtensible, "isExtensible")
|
|
||||||
DEF(preventExtensions, "preventExtensions")
|
|
||||||
DEF(has, "has")
|
|
||||||
DEF(deleteProperty, "deleteProperty")
|
|
||||||
DEF(defineProperty, "defineProperty")
|
|
||||||
DEF(getOwnPropertyDescriptor, "getOwnPropertyDescriptor")
|
|
||||||
DEF(ownKeys, "ownKeys")
|
|
||||||
DEF(add, "add")
|
|
||||||
DEF(done, "done")
|
|
||||||
DEF(next, "next")
|
|
||||||
DEF(values, "values")
|
|
||||||
DEF(source, "source")
|
|
||||||
DEF(flags, "flags")
|
|
||||||
DEF(global, "global")
|
|
||||||
DEF(unicode, "unicode")
|
|
||||||
DEF(raw, "raw")
|
|
||||||
DEF(new_target, "new.target")
|
|
||||||
DEF(this_active_func, "this.active_func")
|
|
||||||
DEF(home_object, "<home_object>")
|
|
||||||
DEF(computed_field, "<computed_field>")
|
|
||||||
DEF(static_computed_field, "<static_computed_field>") /* must come after computed_fields */
|
|
||||||
DEF(class_fields_init, "<class_fields_init>")
|
|
||||||
DEF(brand, "<brand>")
|
|
||||||
DEF(hash_constructor, "#constructor")
|
|
||||||
DEF(as, "as")
|
|
||||||
DEF(from, "from")
|
|
||||||
DEF(meta, "meta")
|
|
||||||
DEF(_default_, "*default*")
|
|
||||||
DEF(_star_, "*")
|
|
||||||
DEF(Module, "Module")
|
|
||||||
DEF(then, "then")
|
|
||||||
DEF(resolve, "resolve")
|
|
||||||
DEF(reject, "reject")
|
|
||||||
DEF(promise, "promise")
|
|
||||||
DEF(proxy, "proxy")
|
|
||||||
DEF(revoke, "revoke")
|
|
||||||
DEF(async, "async")
|
|
||||||
DEF(exec, "exec")
|
|
||||||
DEF(groups, "groups")
|
|
||||||
DEF(indices, "indices")
|
|
||||||
DEF(status, "status")
|
|
||||||
DEF(reason, "reason")
|
|
||||||
DEF(globalThis, "globalThis")
|
|
||||||
DEF(bigint, "bigint")
|
|
||||||
#ifdef CONFIG_BIGNUM
|
|
||||||
DEF(bigfloat, "bigfloat")
|
|
||||||
DEF(bigdecimal, "bigdecimal")
|
|
||||||
DEF(roundingMode, "roundingMode")
|
|
||||||
DEF(maximumSignificantDigits, "maximumSignificantDigits")
|
|
||||||
DEF(maximumFractionDigits, "maximumFractionDigits")
|
|
||||||
#endif
|
|
||||||
/* the following 3 atoms are only used with CONFIG_ATOMICS */
|
|
||||||
DEF(not_equal, "not-equal")
|
|
||||||
DEF(timed_out, "timed-out")
|
|
||||||
DEF(ok, "ok")
|
|
||||||
/* */
|
|
||||||
DEF(toJSON, "toJSON")
|
|
||||||
/* class names */
|
|
||||||
DEF(Object, "Object")
|
|
||||||
DEF(Array, "Array")
|
|
||||||
DEF(Error, "Error")
|
|
||||||
DEF(Number, "Number")
|
|
||||||
DEF(String, "String")
|
|
||||||
DEF(Boolean, "Boolean")
|
|
||||||
DEF(Symbol, "Symbol")
|
|
||||||
DEF(Arguments, "Arguments")
|
|
||||||
DEF(Math, "Math")
|
|
||||||
DEF(JSON, "JSON")
|
|
||||||
DEF(Date, "Date")
|
|
||||||
DEF(Function, "Function")
|
|
||||||
DEF(GeneratorFunction, "GeneratorFunction")
|
|
||||||
DEF(ForInIterator, "ForInIterator")
|
|
||||||
DEF(RegExp, "RegExp")
|
|
||||||
DEF(ArrayBuffer, "ArrayBuffer")
|
|
||||||
DEF(SharedArrayBuffer, "SharedArrayBuffer")
|
|
||||||
/* must keep same order as class IDs for typed arrays */
|
|
||||||
DEF(Uint8ClampedArray, "Uint8ClampedArray")
|
|
||||||
DEF(Int8Array, "Int8Array")
|
|
||||||
DEF(Uint8Array, "Uint8Array")
|
|
||||||
DEF(Int16Array, "Int16Array")
|
|
||||||
DEF(Uint16Array, "Uint16Array")
|
|
||||||
DEF(Int32Array, "Int32Array")
|
|
||||||
DEF(Uint32Array, "Uint32Array")
|
|
||||||
DEF(BigInt64Array, "BigInt64Array")
|
|
||||||
DEF(BigUint64Array, "BigUint64Array")
|
|
||||||
DEF(Float32Array, "Float32Array")
|
|
||||||
DEF(Float64Array, "Float64Array")
|
|
||||||
DEF(DataView, "DataView")
|
|
||||||
DEF(BigInt, "BigInt")
|
|
||||||
#ifdef CONFIG_BIGNUM
|
|
||||||
DEF(BigFloat, "BigFloat")
|
|
||||||
DEF(BigFloatEnv, "BigFloatEnv")
|
|
||||||
DEF(BigDecimal, "BigDecimal")
|
|
||||||
DEF(OperatorSet, "OperatorSet")
|
|
||||||
DEF(Operators, "Operators")
|
|
||||||
#endif
|
|
||||||
DEF(Map, "Map")
|
|
||||||
DEF(Set, "Set") /* Map + 1 */
|
|
||||||
DEF(WeakMap, "WeakMap") /* Map + 2 */
|
|
||||||
DEF(WeakSet, "WeakSet") /* Map + 3 */
|
|
||||||
DEF(Map_Iterator, "Map Iterator")
|
|
||||||
DEF(Set_Iterator, "Set Iterator")
|
|
||||||
DEF(Array_Iterator, "Array Iterator")
|
|
||||||
DEF(String_Iterator, "String Iterator")
|
|
||||||
DEF(RegExp_String_Iterator, "RegExp String Iterator")
|
|
||||||
DEF(Generator, "Generator")
|
|
||||||
DEF(Proxy, "Proxy")
|
|
||||||
DEF(Promise, "Promise")
|
|
||||||
DEF(PromiseResolveFunction, "PromiseResolveFunction")
|
|
||||||
DEF(PromiseRejectFunction, "PromiseRejectFunction")
|
|
||||||
DEF(AsyncFunction, "AsyncFunction")
|
|
||||||
DEF(AsyncFunctionResolve, "AsyncFunctionResolve")
|
|
||||||
DEF(AsyncFunctionReject, "AsyncFunctionReject")
|
|
||||||
DEF(AsyncGeneratorFunction, "AsyncGeneratorFunction")
|
|
||||||
DEF(AsyncGenerator, "AsyncGenerator")
|
|
||||||
DEF(EvalError, "EvalError")
|
|
||||||
DEF(RangeError, "RangeError")
|
|
||||||
DEF(ReferenceError, "ReferenceError")
|
|
||||||
DEF(SyntaxError, "SyntaxError")
|
|
||||||
DEF(TypeError, "TypeError")
|
|
||||||
DEF(URIError, "URIError")
|
|
||||||
DEF(InternalError, "InternalError")
|
|
||||||
/* private symbols */
|
|
||||||
DEF(Private_brand, "<brand>")
|
|
||||||
/* symbols */
|
|
||||||
DEF(Symbol_toPrimitive, "Symbol.toPrimitive")
|
|
||||||
DEF(Symbol_iterator, "Symbol.iterator")
|
|
||||||
DEF(Symbol_match, "Symbol.match")
|
|
||||||
DEF(Symbol_matchAll, "Symbol.matchAll")
|
|
||||||
DEF(Symbol_replace, "Symbol.replace")
|
|
||||||
DEF(Symbol_search, "Symbol.search")
|
|
||||||
DEF(Symbol_split, "Symbol.split")
|
|
||||||
DEF(Symbol_toStringTag, "Symbol.toStringTag")
|
|
||||||
DEF(Symbol_isConcatSpreadable, "Symbol.isConcatSpreadable")
|
|
||||||
DEF(Symbol_hasInstance, "Symbol.hasInstance")
|
|
||||||
DEF(Symbol_species, "Symbol.species")
|
|
||||||
DEF(Symbol_unscopables, "Symbol.unscopables")
|
|
||||||
DEF(Symbol_asyncIterator, "Symbol.asyncIterator")
|
|
||||||
#ifdef CONFIG_BIGNUM
|
|
||||||
DEF(Symbol_operatorSet, "Symbol.operatorSet")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* DEF */
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,59 +0,0 @@
|
||||||
/*
|
|
||||||
* QuickJS C library
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017-2018 Fabrice Bellard
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
||||||
* of this software and associated documentation files (the "Software"), to deal
|
|
||||||
* in the Software without restriction, including without limitation the rights
|
|
||||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
||||||
* copies of the Software, and to permit persons to whom the Software is
|
|
||||||
* furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
||||||
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
||||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
||||||
* THE SOFTWARE.
|
|
||||||
*/
|
|
||||||
#ifndef QUICKJS_LIBC_H
|
|
||||||
#define QUICKJS_LIBC_H
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "quickjs.h"
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name);
|
|
||||||
JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name);
|
|
||||||
void js_std_add_helpers(JSContext *ctx, int argc, char **argv);
|
|
||||||
void js_std_loop(JSContext *ctx);
|
|
||||||
void js_std_init_handlers(JSRuntime *rt);
|
|
||||||
void js_std_free_handlers(JSRuntime *rt);
|
|
||||||
void js_std_dump_error(JSContext *ctx);
|
|
||||||
uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename);
|
|
||||||
int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val,
|
|
||||||
JS_BOOL use_realpath, JS_BOOL is_main);
|
|
||||||
JSModuleDef *js_module_loader(JSContext *ctx,
|
|
||||||
const char *module_name, void *opaque);
|
|
||||||
void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
|
|
||||||
int flags);
|
|
||||||
void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
|
|
||||||
JSValueConst reason,
|
|
||||||
JS_BOOL is_handled, void *opaque);
|
|
||||||
void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt));
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
} /* extern "C" { */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* QUICKJS_LIBC_H */
|
|
|
@ -1,372 +0,0 @@
|
||||||
/*
|
|
||||||
* QuickJS opcode definitions
|
|
||||||
*
|
|
||||||
* Copyright (c) 2017-2018 Fabrice Bellard
|
|
||||||
* Copyright (c) 2017-2018 Charlie Gordon
|
|
||||||
*
|
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifdef FMT
|
|
||||||
FMT(none)
|
|
||||||
FMT(none_int)
|
|
||||||
FMT(none_loc)
|
|
||||||
FMT(none_arg)
|
|
||||||
FMT(none_var_ref)
|
|
||||||
FMT(u8)
|
|
||||||
FMT(i8)
|
|
||||||
FMT(loc8)
|
|
||||||
FMT(const8)
|
|
||||||
FMT(label8)
|
|
||||||
FMT(u16)
|
|
||||||
FMT(i16)
|
|
||||||
FMT(label16)
|
|
||||||
FMT(npop)
|
|
||||||
FMT(npopx)
|
|
||||||
FMT(npop_u16)
|
|
||||||
FMT(loc)
|
|
||||||
FMT(arg)
|
|
||||||
FMT(var_ref)
|
|
||||||
FMT(u32)
|
|
||||||
FMT(i32)
|
|
||||||
FMT(const)
|
|
||||||
FMT(label)
|
|
||||||
FMT(atom)
|
|
||||||
FMT(atom_u8)
|
|
||||||
FMT(atom_u16)
|
|
||||||
FMT(atom_label_u8)
|
|
||||||
FMT(atom_label_u16)
|
|
||||||
FMT(label_u16)
|
|
||||||
#undef FMT
|
|
||||||
#endif /* FMT */
|
|
||||||
|
|
||||||
#ifdef DEF
|
|
||||||
|
|
||||||
#ifndef def
|
|
||||||
#define def(id, size, n_pop, n_push, f) DEF(id, size, n_pop, n_push, f)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
DEF(invalid, 1, 0, 0, none) /* never emitted */
|
|
||||||
|
|
||||||
/* push values */
|
|
||||||
DEF( push_i32, 5, 0, 1, i32)
|
|
||||||
DEF( push_const, 5, 0, 1, const)
|
|
||||||
DEF( fclosure, 5, 0, 1, const) /* must follow push_const */
|
|
||||||
DEF(push_atom_value, 5, 0, 1, atom)
|
|
||||||
DEF( private_symbol, 5, 0, 1, atom)
|
|
||||||
DEF( undefined, 1, 0, 1, none)
|
|
||||||
DEF( null, 1, 0, 1, none)
|
|
||||||
DEF( push_this, 1, 0, 1, none) /* only used at the start of a function */
|
|
||||||
DEF( push_false, 1, 0, 1, none)
|
|
||||||
DEF( push_true, 1, 0, 1, none)
|
|
||||||
DEF( object, 1, 0, 1, none)
|
|
||||||
DEF( special_object, 2, 0, 1, u8) /* only used at the start of a function */
|
|
||||||
DEF( rest, 3, 0, 1, u16) /* only used at the start of a function */
|
|
||||||
|
|
||||||
DEF( drop, 1, 1, 0, none) /* a -> */
|
|
||||||
DEF( nip, 1, 2, 1, none) /* a b -> b */
|
|
||||||
DEF( nip1, 1, 3, 2, none) /* a b c -> b c */
|
|
||||||
DEF( dup, 1, 1, 2, none) /* a -> a a */
|
|
||||||
DEF( dup1, 1, 2, 3, none) /* a b -> a a b */
|
|
||||||
DEF( dup2, 1, 2, 4, none) /* a b -> a b a b */
|
|
||||||
DEF( dup3, 1, 3, 6, none) /* a b c -> a b c a b c */
|
|
||||||
DEF( insert2, 1, 2, 3, none) /* obj a -> a obj a (dup_x1) */
|
|
||||||
DEF( insert3, 1, 3, 4, none) /* obj prop a -> a obj prop a (dup_x2) */
|
|
||||||
DEF( insert4, 1, 4, 5, none) /* this obj prop a -> a this obj prop a */
|
|
||||||
DEF( perm3, 1, 3, 3, none) /* obj a b -> a obj b */
|
|
||||||
DEF( perm4, 1, 4, 4, none) /* obj prop a b -> a obj prop b */
|
|
||||||
DEF( perm5, 1, 5, 5, none) /* this obj prop a b -> a this obj prop b */
|
|
||||||
DEF( swap, 1, 2, 2, none) /* a b -> b a */
|
|
||||||
DEF( swap2, 1, 4, 4, none) /* a b c d -> c d a b */
|
|
||||||
DEF( rot3l, 1, 3, 3, none) /* x a b -> a b x */
|
|
||||||
DEF( rot3r, 1, 3, 3, none) /* a b x -> x a b */
|
|
||||||
DEF( rot4l, 1, 4, 4, none) /* x a b c -> a b c x */
|
|
||||||
DEF( rot5l, 1, 5, 5, none) /* x a b c d -> a b c d x */
|
|
||||||
|
|
||||||
DEF(call_constructor, 3, 2, 1, npop) /* func new.target args -> ret. arguments are not counted in n_pop */
|
|
||||||
DEF( call, 3, 1, 1, npop) /* arguments are not counted in n_pop */
|
|
||||||
DEF( tail_call, 3, 1, 0, npop) /* arguments are not counted in n_pop */
|
|
||||||
DEF( call_method, 3, 2, 1, npop) /* arguments are not counted in n_pop */
|
|
||||||
DEF(tail_call_method, 3, 2, 0, npop) /* arguments are not counted in n_pop */
|
|
||||||
DEF( array_from, 3, 0, 1, npop) /* arguments are not counted in n_pop */
|
|
||||||
DEF( apply, 3, 3, 1, u16)
|
|
||||||
DEF( return, 1, 1, 0, none)
|
|
||||||
DEF( return_undef, 1, 0, 0, none)
|
|
||||||
DEF(check_ctor_return, 1, 1, 2, none)
|
|
||||||
DEF( check_ctor, 1, 0, 0, none)
|
|
||||||
DEF( check_brand, 1, 2, 2, none) /* this_obj func -> this_obj func */
|
|
||||||
DEF( add_brand, 1, 2, 0, none) /* this_obj home_obj -> */
|
|
||||||
DEF( return_async, 1, 1, 0, none)
|
|
||||||
DEF( throw, 1, 1, 0, none)
|
|
||||||
DEF( throw_error, 6, 0, 0, atom_u8)
|
|
||||||
DEF( eval, 5, 1, 1, npop_u16) /* func args... -> ret_val */
|
|
||||||
DEF( apply_eval, 3, 2, 1, u16) /* func array -> ret_eval */
|
|
||||||
DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a
|
|
||||||
bytecode string */
|
|
||||||
DEF( get_super, 1, 1, 1, none)
|
|
||||||
DEF( import, 1, 1, 1, none) /* dynamic module import */
|
|
||||||
|
|
||||||
DEF( check_var, 5, 0, 1, atom) /* check if a variable exists */
|
|
||||||
DEF( get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */
|
|
||||||
DEF( get_var, 5, 0, 1, atom) /* throw an exception if the variable does not exist */
|
|
||||||
DEF( put_var, 5, 1, 0, atom) /* must come after get_var */
|
|
||||||
DEF( put_var_init, 5, 1, 0, atom) /* must come after put_var. Used to initialize a global lexical variable */
|
|
||||||
DEF( put_var_strict, 5, 2, 0, atom) /* for strict mode variable write */
|
|
||||||
|
|
||||||
DEF( get_ref_value, 1, 2, 3, none)
|
|
||||||
DEF( put_ref_value, 1, 3, 0, none)
|
|
||||||
|
|
||||||
DEF( define_var, 6, 0, 0, atom_u8)
|
|
||||||
DEF(check_define_var, 6, 0, 0, atom_u8)
|
|
||||||
DEF( define_func, 6, 1, 0, atom_u8)
|
|
||||||
DEF( get_field, 5, 1, 1, atom)
|
|
||||||
DEF( get_field2, 5, 1, 2, atom)
|
|
||||||
DEF( put_field, 5, 2, 0, atom)
|
|
||||||
DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */
|
|
||||||
DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */
|
|
||||||
DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */
|
|
||||||
DEF( get_array_el, 1, 2, 1, none)
|
|
||||||
DEF( get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */
|
|
||||||
DEF( put_array_el, 1, 3, 0, none)
|
|
||||||
DEF(get_super_value, 1, 3, 1, none) /* this obj prop -> value */
|
|
||||||
DEF(put_super_value, 1, 4, 0, none) /* this obj prop value -> */
|
|
||||||
DEF( define_field, 5, 2, 1, atom)
|
|
||||||
DEF( set_name, 5, 1, 1, atom)
|
|
||||||
DEF(set_name_computed, 1, 2, 2, none)
|
|
||||||
DEF( set_proto, 1, 2, 1, none)
|
|
||||||
DEF(set_home_object, 1, 2, 2, none)
|
|
||||||
DEF(define_array_el, 1, 3, 2, none)
|
|
||||||
DEF( append, 1, 3, 2, none) /* append enumerated object, update length */
|
|
||||||
DEF(copy_data_properties, 2, 3, 3, u8)
|
|
||||||
DEF( define_method, 6, 2, 1, atom_u8)
|
|
||||||
DEF(define_method_computed, 2, 3, 1, u8) /* must come after define_method */
|
|
||||||
DEF( define_class, 6, 2, 2, atom_u8) /* parent ctor -> ctor proto */
|
|
||||||
DEF( define_class_computed, 6, 3, 3, atom_u8) /* field_name parent ctor -> field_name ctor proto (class with computed name) */
|
|
||||||
|
|
||||||
DEF( get_loc, 3, 0, 1, loc)
|
|
||||||
DEF( put_loc, 3, 1, 0, loc) /* must come after get_loc */
|
|
||||||
DEF( set_loc, 3, 1, 1, loc) /* must come after put_loc */
|
|
||||||
DEF( get_arg, 3, 0, 1, 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( get_var_ref, 3, 0, 1, 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_loc_uninitialized, 3, 0, 0, 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_init, 3, 1, 0, loc)
|
|
||||||
DEF(get_loc_checkthis, 3, 0, 1, loc)
|
|
||||||
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_init, 3, 1, 0, var_ref)
|
|
||||||
DEF( close_loc, 3, 0, 0, loc)
|
|
||||||
DEF( if_false, 5, 1, 0, label)
|
|
||||||
DEF( if_true, 5, 1, 0, label) /* must come after if_false */
|
|
||||||
DEF( goto, 5, 0, 0, label) /* must come after if_true */
|
|
||||||
DEF( catch, 5, 0, 1, label)
|
|
||||||
DEF( gosub, 5, 0, 0, label) /* used to execute the finally block */
|
|
||||||
DEF( ret, 1, 1, 0, none) /* used to return from the finally block */
|
|
||||||
DEF( nip_catch, 1, 2, 1, none) /* catch ... a -> a */
|
|
||||||
|
|
||||||
DEF( to_object, 1, 1, 1, none)
|
|
||||||
//DEF( to_string, 1, 1, 1, none)
|
|
||||||
DEF( to_propkey, 1, 1, 1, none)
|
|
||||||
DEF( to_propkey2, 1, 2, 2, none)
|
|
||||||
|
|
||||||
DEF( with_get_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */
|
|
||||||
DEF( with_put_var, 10, 2, 1, atom_label_u8) /* must be in the same order as scope_xxx */
|
|
||||||
DEF(with_delete_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */
|
|
||||||
DEF( with_make_ref, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */
|
|
||||||
DEF( with_get_ref, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */
|
|
||||||
DEF(with_get_ref_undef, 10, 1, 0, atom_label_u8)
|
|
||||||
|
|
||||||
DEF( make_loc_ref, 7, 0, 2, atom_u16)
|
|
||||||
DEF( make_arg_ref, 7, 0, 2, atom_u16)
|
|
||||||
DEF(make_var_ref_ref, 7, 0, 2, atom_u16)
|
|
||||||
DEF( make_var_ref, 5, 0, 2, atom)
|
|
||||||
|
|
||||||
DEF( for_in_start, 1, 1, 1, none)
|
|
||||||
DEF( for_of_start, 1, 1, 3, none)
|
|
||||||
DEF(for_await_of_start, 1, 1, 3, none)
|
|
||||||
DEF( for_in_next, 1, 1, 3, none)
|
|
||||||
DEF( for_of_next, 2, 3, 5, u8)
|
|
||||||
DEF(iterator_check_object, 1, 1, 1, none)
|
|
||||||
DEF(iterator_get_value_done, 1, 1, 2, none)
|
|
||||||
DEF( iterator_close, 1, 3, 0, none)
|
|
||||||
DEF( iterator_next, 1, 4, 4, none)
|
|
||||||
DEF( iterator_call, 2, 4, 5, u8)
|
|
||||||
DEF( initial_yield, 1, 0, 0, none)
|
|
||||||
DEF( yield, 1, 1, 2, none)
|
|
||||||
DEF( yield_star, 1, 1, 2, none)
|
|
||||||
DEF(async_yield_star, 1, 1, 2, none)
|
|
||||||
DEF( await, 1, 1, 1, none)
|
|
||||||
|
|
||||||
/* arithmetic/logic operations */
|
|
||||||
DEF( neg, 1, 1, 1, none)
|
|
||||||
DEF( plus, 1, 1, 1, none)
|
|
||||||
DEF( dec, 1, 1, 1, none)
|
|
||||||
DEF( inc, 1, 1, 1, none)
|
|
||||||
DEF( post_dec, 1, 1, 2, none)
|
|
||||||
DEF( post_inc, 1, 1, 2, none)
|
|
||||||
DEF( dec_loc, 2, 0, 0, loc8)
|
|
||||||
DEF( inc_loc, 2, 0, 0, loc8)
|
|
||||||
DEF( add_loc, 2, 1, 0, loc8)
|
|
||||||
DEF( not, 1, 1, 1, none)
|
|
||||||
DEF( lnot, 1, 1, 1, none)
|
|
||||||
DEF( typeof, 1, 1, 1, none)
|
|
||||||
DEF( delete, 1, 2, 1, none)
|
|
||||||
DEF( delete_var, 5, 0, 1, atom)
|
|
||||||
|
|
||||||
DEF( mul, 1, 2, 1, none)
|
|
||||||
DEF( div, 1, 2, 1, none)
|
|
||||||
DEF( mod, 1, 2, 1, none)
|
|
||||||
DEF( add, 1, 2, 1, none)
|
|
||||||
DEF( sub, 1, 2, 1, none)
|
|
||||||
DEF( pow, 1, 2, 1, none)
|
|
||||||
DEF( shl, 1, 2, 1, none)
|
|
||||||
DEF( sar, 1, 2, 1, none)
|
|
||||||
DEF( shr, 1, 2, 1, none)
|
|
||||||
DEF( lt, 1, 2, 1, none)
|
|
||||||
DEF( lte, 1, 2, 1, none)
|
|
||||||
DEF( gt, 1, 2, 1, none)
|
|
||||||
DEF( gte, 1, 2, 1, none)
|
|
||||||
DEF( instanceof, 1, 2, 1, none)
|
|
||||||
DEF( in, 1, 2, 1, none)
|
|
||||||
DEF( eq, 1, 2, 1, none)
|
|
||||||
DEF( neq, 1, 2, 1, none)
|
|
||||||
DEF( strict_eq, 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( private_in, 1, 2, 1, none)
|
|
||||||
#ifdef CONFIG_BIGNUM
|
|
||||||
DEF( mul_pow10, 1, 2, 1, none)
|
|
||||||
DEF( math_mod, 1, 2, 1, none)
|
|
||||||
#endif
|
|
||||||
/* must be the last non short and non temporary opcode */
|
|
||||||
DEF( nop, 1, 0, 0, none)
|
|
||||||
|
|
||||||
/* temporary opcodes: never emitted in the final bytecode */
|
|
||||||
|
|
||||||
def( enter_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */
|
|
||||||
def( leave_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */
|
|
||||||
|
|
||||||
def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */
|
|
||||||
|
|
||||||
/* the following opcodes must be in the same order as the 'with_x' and
|
|
||||||
get_var_undef, get_var and put_var opcodes */
|
|
||||||
def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
|
||||||
def( scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
|
||||||
def( scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
|
||||||
def(scope_delete_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
|
||||||
def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */
|
|
||||||
def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
|
||||||
def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */
|
|
||||||
def(scope_get_var_checkthis, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2, only used to return 'this' in derived class constructors */
|
|
||||||
def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */
|
|
||||||
def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */
|
|
||||||
def(scope_put_private_field, 7, 2, 0, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */
|
|
||||||
def(scope_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( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
|
|
||||||
|
|
||||||
#if SHORT_OPCODES
|
|
||||||
DEF( push_minus1, 1, 0, 1, none_int)
|
|
||||||
DEF( push_0, 1, 0, 1, none_int)
|
|
||||||
DEF( push_1, 1, 0, 1, none_int)
|
|
||||||
DEF( push_2, 1, 0, 1, none_int)
|
|
||||||
DEF( push_3, 1, 0, 1, none_int)
|
|
||||||
DEF( push_4, 1, 0, 1, none_int)
|
|
||||||
DEF( push_5, 1, 0, 1, none_int)
|
|
||||||
DEF( push_6, 1, 0, 1, none_int)
|
|
||||||
DEF( push_7, 1, 0, 1, none_int)
|
|
||||||
DEF( push_i8, 2, 0, 1, i8)
|
|
||||||
DEF( push_i16, 3, 0, 1, i16)
|
|
||||||
DEF( push_const8, 2, 0, 1, const8)
|
|
||||||
DEF( fclosure8, 2, 0, 1, const8) /* must follow push_const8 */
|
|
||||||
DEF(push_empty_string, 1, 0, 1, none)
|
|
||||||
|
|
||||||
DEF( get_loc8, 2, 0, 1, loc8)
|
|
||||||
DEF( put_loc8, 2, 1, 0, loc8)
|
|
||||||
DEF( set_loc8, 2, 1, 1, loc8)
|
|
||||||
|
|
||||||
DEF( get_loc0, 1, 0, 1, none_loc)
|
|
||||||
DEF( get_loc1, 1, 0, 1, none_loc)
|
|
||||||
DEF( get_loc2, 1, 0, 1, none_loc)
|
|
||||||
DEF( get_loc3, 1, 0, 1, none_loc)
|
|
||||||
DEF( put_loc0, 1, 1, 0, none_loc)
|
|
||||||
DEF( put_loc1, 1, 1, 0, none_loc)
|
|
||||||
DEF( put_loc2, 1, 1, 0, none_loc)
|
|
||||||
DEF( put_loc3, 1, 1, 0, none_loc)
|
|
||||||
DEF( set_loc0, 1, 1, 1, none_loc)
|
|
||||||
DEF( set_loc1, 1, 1, 1, none_loc)
|
|
||||||
DEF( set_loc2, 1, 1, 1, none_loc)
|
|
||||||
DEF( set_loc3, 1, 1, 1, none_loc)
|
|
||||||
DEF( get_arg0, 1, 0, 1, none_arg)
|
|
||||||
DEF( get_arg1, 1, 0, 1, none_arg)
|
|
||||||
DEF( get_arg2, 1, 0, 1, none_arg)
|
|
||||||
DEF( get_arg3, 1, 0, 1, none_arg)
|
|
||||||
DEF( put_arg0, 1, 1, 0, none_arg)
|
|
||||||
DEF( put_arg1, 1, 1, 0, none_arg)
|
|
||||||
DEF( put_arg2, 1, 1, 0, none_arg)
|
|
||||||
DEF( put_arg3, 1, 1, 0, none_arg)
|
|
||||||
DEF( set_arg0, 1, 1, 1, none_arg)
|
|
||||||
DEF( set_arg1, 1, 1, 1, none_arg)
|
|
||||||
DEF( set_arg2, 1, 1, 1, none_arg)
|
|
||||||
DEF( set_arg3, 1, 1, 1, none_arg)
|
|
||||||
DEF( get_var_ref0, 1, 0, 1, none_var_ref)
|
|
||||||
DEF( get_var_ref1, 1, 0, 1, none_var_ref)
|
|
||||||
DEF( get_var_ref2, 1, 0, 1, none_var_ref)
|
|
||||||
DEF( get_var_ref3, 1, 0, 1, none_var_ref)
|
|
||||||
DEF( put_var_ref0, 1, 1, 0, none_var_ref)
|
|
||||||
DEF( put_var_ref1, 1, 1, 0, none_var_ref)
|
|
||||||
DEF( put_var_ref2, 1, 1, 0, none_var_ref)
|
|
||||||
DEF( put_var_ref3, 1, 1, 0, none_var_ref)
|
|
||||||
DEF( set_var_ref0, 1, 1, 1, none_var_ref)
|
|
||||||
DEF( set_var_ref1, 1, 1, 1, none_var_ref)
|
|
||||||
DEF( set_var_ref2, 1, 1, 1, none_var_ref)
|
|
||||||
DEF( set_var_ref3, 1, 1, 1, none_var_ref)
|
|
||||||
|
|
||||||
DEF( get_length, 1, 1, 1, none)
|
|
||||||
|
|
||||||
DEF( if_false8, 2, 1, 0, label8)
|
|
||||||
DEF( if_true8, 2, 1, 0, label8) /* must come after if_false8 */
|
|
||||||
DEF( goto8, 2, 0, 0, label8) /* must come after if_true8 */
|
|
||||||
DEF( goto16, 3, 0, 0, label16)
|
|
||||||
|
|
||||||
DEF( call0, 1, 1, 1, npopx)
|
|
||||||
DEF( call1, 1, 1, 1, npopx)
|
|
||||||
DEF( call2, 1, 1, 1, npopx)
|
|
||||||
DEF( call3, 1, 1, 1, npopx)
|
|
||||||
|
|
||||||
DEF( is_undefined, 1, 1, 1, none)
|
|
||||||
DEF( is_null, 1, 1, 1, none)
|
|
||||||
DEF(typeof_is_undefined, 1, 1, 1, none)
|
|
||||||
DEF( typeof_is_function, 1, 1, 1, none)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#undef DEF
|
|
||||||
#undef def
|
|
||||||
#endif /* DEF */
|
|
55548
quickjs/quickjs.c
55548
quickjs/quickjs.c
File diff suppressed because it is too large
Load diff
1060
quickjs/quickjs.h
1060
quickjs/quickjs.h
File diff suppressed because it is too large
Load diff
|
@ -1 +0,0 @@
|
||||||
The main documentation is in doc/quickjs.pdf or doc/quickjs.html.
|
|
|
@ -1,158 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
# Release the QuickJS source code
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
version=`cat VERSION`
|
|
||||||
|
|
||||||
if [ "$1" = "-h" ] ; then
|
|
||||||
echo "release.sh [release_list]"
|
|
||||||
echo ""
|
|
||||||
echo "release_list: extras binary win_binary quickjs"
|
|
||||||
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
release_list="extras binary win_binary quickjs"
|
|
||||||
|
|
||||||
if [ "$1" != "" ] ; then
|
|
||||||
release_list="$1"
|
|
||||||
fi
|
|
||||||
|
|
||||||
#################################################"
|
|
||||||
# extras
|
|
||||||
|
|
||||||
if echo $release_list | grep -w -q extras ; then
|
|
||||||
|
|
||||||
d="quickjs-${version}"
|
|
||||||
name="quickjs-extras-${version}"
|
|
||||||
outdir="/tmp/${d}"
|
|
||||||
|
|
||||||
rm -rf $outdir
|
|
||||||
mkdir -p $outdir $outdir/unicode $outdir/tests
|
|
||||||
|
|
||||||
cp unicode/* $outdir/unicode
|
|
||||||
cp -a tests/bench-v8 $outdir/tests
|
|
||||||
|
|
||||||
( cd /tmp && tar Jcvf /tmp/${name}.tar.xz ${d} )
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
#################################################"
|
|
||||||
# Windows binary release
|
|
||||||
|
|
||||||
if echo $release_list | grep -w -q win_binary ; then
|
|
||||||
|
|
||||||
# win64
|
|
||||||
|
|
||||||
dlldir=/usr/x86_64-w64-mingw32/sys-root/mingw/bin
|
|
||||||
cross_prefix="x86_64-w64-mingw32-"
|
|
||||||
d="quickjs-win-x86_64-${version}"
|
|
||||||
outdir="/tmp/${d}"
|
|
||||||
|
|
||||||
rm -rf $outdir
|
|
||||||
mkdir -p $outdir
|
|
||||||
|
|
||||||
make CONFIG_WIN32=y qjs.exe
|
|
||||||
cp qjs.exe $outdir
|
|
||||||
${cross_prefix}strip $outdir/qjs.exe
|
|
||||||
cp $dlldir/libwinpthread-1.dll $outdir
|
|
||||||
|
|
||||||
( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . )
|
|
||||||
|
|
||||||
make CONFIG_WIN32=y clean
|
|
||||||
|
|
||||||
# win32
|
|
||||||
|
|
||||||
dlldir=/usr/i686-w64-mingw32/sys-root/mingw/bin
|
|
||||||
cross_prefix="i686-w64-mingw32-"
|
|
||||||
d="quickjs-win-i686-${version}"
|
|
||||||
outdir="/tmp/${d}"
|
|
||||||
|
|
||||||
rm -rf $outdir
|
|
||||||
mkdir -p $outdir
|
|
||||||
|
|
||||||
make clean
|
|
||||||
make CONFIG_WIN32=y clean
|
|
||||||
|
|
||||||
make CONFIG_WIN32=y CONFIG_M32=y qjs.exe
|
|
||||||
cp qjs.exe $outdir
|
|
||||||
${cross_prefix}strip $outdir/qjs.exe
|
|
||||||
cp $dlldir/libwinpthread-1.dll $outdir
|
|
||||||
|
|
||||||
( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . )
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
#################################################"
|
|
||||||
# Linux binary release
|
|
||||||
|
|
||||||
if echo $release_list | grep -w -q binary ; then
|
|
||||||
|
|
||||||
make clean
|
|
||||||
make CONFIG_WIN32=y clean
|
|
||||||
make -j4 qjs run-test262
|
|
||||||
make -j4 CONFIG_M32=y qjs32 run-test262-32
|
|
||||||
strip qjs run-test262 qjs32 run-test262-32
|
|
||||||
|
|
||||||
d="quickjs-linux-x86_64-${version}"
|
|
||||||
outdir="/tmp/${d}"
|
|
||||||
|
|
||||||
rm -rf $outdir
|
|
||||||
mkdir -p $outdir
|
|
||||||
|
|
||||||
cp qjs run-test262 $outdir
|
|
||||||
|
|
||||||
( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . )
|
|
||||||
|
|
||||||
d="quickjs-linux-i686-${version}"
|
|
||||||
outdir="/tmp/${d}"
|
|
||||||
|
|
||||||
rm -rf $outdir
|
|
||||||
mkdir -p $outdir
|
|
||||||
|
|
||||||
cp qjs32 $outdir/qjs
|
|
||||||
cp run-test262-32 $outdir/run-test262
|
|
||||||
|
|
||||||
( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . )
|
|
||||||
|
|
||||||
fi
|
|
||||||
|
|
||||||
#################################################"
|
|
||||||
# quickjs
|
|
||||||
|
|
||||||
if echo $release_list | grep -w -q quickjs ; then
|
|
||||||
|
|
||||||
make build_doc
|
|
||||||
|
|
||||||
d="quickjs-${version}"
|
|
||||||
outdir="/tmp/${d}"
|
|
||||||
|
|
||||||
rm -rf $outdir
|
|
||||||
mkdir -p $outdir $outdir/doc $outdir/tests $outdir/examples
|
|
||||||
|
|
||||||
cp Makefile VERSION TODO Changelog readme.txt LICENSE \
|
|
||||||
release.sh unicode_download.sh \
|
|
||||||
qjs.c qjsc.c qjscalc.js repl.js \
|
|
||||||
quickjs.c quickjs.h quickjs-atom.h \
|
|
||||||
quickjs-libc.c quickjs-libc.h quickjs-opcode.h \
|
|
||||||
cutils.c cutils.h list.h \
|
|
||||||
libregexp.c libregexp.h libregexp-opcode.h \
|
|
||||||
libunicode.c libunicode.h libunicode-table.h \
|
|
||||||
libbf.c libbf.h \
|
|
||||||
unicode_gen.c unicode_gen_def.h \
|
|
||||||
run-test262.c test262o.conf test262.conf \
|
|
||||||
test262o_errors.txt test262_errors.txt \
|
|
||||||
$outdir
|
|
||||||
|
|
||||||
cp tests/*.js tests/*.patch tests/bjson.c $outdir/tests
|
|
||||||
|
|
||||||
cp examples/*.js examples/*.c $outdir/examples
|
|
||||||
|
|
||||||
cp doc/quickjs.texi doc/quickjs.pdf doc/quickjs.html \
|
|
||||||
doc/jsbignum.texi doc/jsbignum.html doc/jsbignum.pdf \
|
|
||||||
$outdir/doc
|
|
||||||
|
|
||||||
( cd /tmp && tar Jcvf /tmp/${d}.tar.xz ${d} )
|
|
||||||
|
|
||||||
fi
|
|
|
@ -1,19 +0,0 @@
|
||||||
#!/bin/sh
|
|
||||||
set -e
|
|
||||||
|
|
||||||
url="ftp://ftp.unicode.org/Public/14.0.0/ucd"
|
|
||||||
emoji_url="${url}/emoji/emoji-data.txt"
|
|
||||||
|
|
||||||
files="CaseFolding.txt DerivedNormalizationProps.txt PropList.txt \
|
|
||||||
SpecialCasing.txt CompositionExclusions.txt ScriptExtensions.txt \
|
|
||||||
UnicodeData.txt DerivedCoreProperties.txt NormalizationTest.txt Scripts.txt \
|
|
||||||
PropertyValueAliases.txt"
|
|
||||||
|
|
||||||
mkdir -p unicode
|
|
||||||
|
|
||||||
for f in $files; do
|
|
||||||
g="${url}/${f}"
|
|
||||||
wget $g -O unicode/$f
|
|
||||||
done
|
|
||||||
|
|
||||||
wget $emoji_url -O unicode/emoji-data.txt
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,291 +0,0 @@
|
||||||
#ifdef UNICODE_GENERAL_CATEGORY
|
|
||||||
DEF(Cn, "Unassigned") /* must be zero */
|
|
||||||
DEF(Lu, "Uppercase_Letter")
|
|
||||||
DEF(Ll, "Lowercase_Letter")
|
|
||||||
DEF(Lt, "Titlecase_Letter")
|
|
||||||
DEF(Lm, "Modifier_Letter")
|
|
||||||
DEF(Lo, "Other_Letter")
|
|
||||||
DEF(Mn, "Nonspacing_Mark")
|
|
||||||
DEF(Mc, "Spacing_Mark")
|
|
||||||
DEF(Me, "Enclosing_Mark")
|
|
||||||
DEF(Nd, "Decimal_Number,digit")
|
|
||||||
DEF(Nl, "Letter_Number")
|
|
||||||
DEF(No, "Other_Number")
|
|
||||||
DEF(Sm, "Math_Symbol")
|
|
||||||
DEF(Sc, "Currency_Symbol")
|
|
||||||
DEF(Sk, "Modifier_Symbol")
|
|
||||||
DEF(So, "Other_Symbol")
|
|
||||||
DEF(Pc, "Connector_Punctuation")
|
|
||||||
DEF(Pd, "Dash_Punctuation")
|
|
||||||
DEF(Ps, "Open_Punctuation")
|
|
||||||
DEF(Pe, "Close_Punctuation")
|
|
||||||
DEF(Pi, "Initial_Punctuation")
|
|
||||||
DEF(Pf, "Final_Punctuation")
|
|
||||||
DEF(Po, "Other_Punctuation")
|
|
||||||
DEF(Zs, "Space_Separator")
|
|
||||||
DEF(Zl, "Line_Separator")
|
|
||||||
DEF(Zp, "Paragraph_Separator")
|
|
||||||
DEF(Cc, "Control,cntrl")
|
|
||||||
DEF(Cf, "Format")
|
|
||||||
DEF(Cs, "Surrogate")
|
|
||||||
DEF(Co, "Private_Use")
|
|
||||||
/* synthetic properties */
|
|
||||||
DEF(LC, "Cased_Letter")
|
|
||||||
DEF(L, "Letter")
|
|
||||||
DEF(M, "Mark,Combining_Mark")
|
|
||||||
DEF(N, "Number")
|
|
||||||
DEF(S, "Symbol")
|
|
||||||
DEF(P, "Punctuation,punct")
|
|
||||||
DEF(Z, "Separator")
|
|
||||||
DEF(C, "Other")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNICODE_SCRIPT
|
|
||||||
/* scripts aliases names in PropertyValueAliases.txt */
|
|
||||||
DEF(Unknown, "Zzzz")
|
|
||||||
DEF(Adlam, "Adlm")
|
|
||||||
DEF(Ahom, "Ahom")
|
|
||||||
DEF(Anatolian_Hieroglyphs, "Hluw")
|
|
||||||
DEF(Arabic, "Arab")
|
|
||||||
DEF(Armenian, "Armn")
|
|
||||||
DEF(Avestan, "Avst")
|
|
||||||
DEF(Balinese, "Bali")
|
|
||||||
DEF(Bamum, "Bamu")
|
|
||||||
DEF(Bassa_Vah, "Bass")
|
|
||||||
DEF(Batak, "Batk")
|
|
||||||
DEF(Bengali, "Beng")
|
|
||||||
DEF(Bhaiksuki, "Bhks")
|
|
||||||
DEF(Bopomofo, "Bopo")
|
|
||||||
DEF(Brahmi, "Brah")
|
|
||||||
DEF(Braille, "Brai")
|
|
||||||
DEF(Buginese, "Bugi")
|
|
||||||
DEF(Buhid, "Buhd")
|
|
||||||
DEF(Canadian_Aboriginal, "Cans")
|
|
||||||
DEF(Carian, "Cari")
|
|
||||||
DEF(Caucasian_Albanian, "Aghb")
|
|
||||||
DEF(Chakma, "Cakm")
|
|
||||||
DEF(Cham, "Cham")
|
|
||||||
DEF(Cherokee, "Cher")
|
|
||||||
DEF(Chorasmian, "Chrs")
|
|
||||||
DEF(Common, "Zyyy")
|
|
||||||
DEF(Coptic, "Copt,Qaac")
|
|
||||||
DEF(Cuneiform, "Xsux")
|
|
||||||
DEF(Cypriot, "Cprt")
|
|
||||||
DEF(Cyrillic, "Cyrl")
|
|
||||||
DEF(Cypro_Minoan, "Cpmn")
|
|
||||||
DEF(Deseret, "Dsrt")
|
|
||||||
DEF(Devanagari, "Deva")
|
|
||||||
DEF(Dives_Akuru, "Diak")
|
|
||||||
DEF(Dogra, "Dogr")
|
|
||||||
DEF(Duployan, "Dupl")
|
|
||||||
DEF(Egyptian_Hieroglyphs, "Egyp")
|
|
||||||
DEF(Elbasan, "Elba")
|
|
||||||
DEF(Elymaic, "Elym")
|
|
||||||
DEF(Ethiopic, "Ethi")
|
|
||||||
DEF(Georgian, "Geor")
|
|
||||||
DEF(Glagolitic, "Glag")
|
|
||||||
DEF(Gothic, "Goth")
|
|
||||||
DEF(Grantha, "Gran")
|
|
||||||
DEF(Greek, "Grek")
|
|
||||||
DEF(Gujarati, "Gujr")
|
|
||||||
DEF(Gunjala_Gondi, "Gong")
|
|
||||||
DEF(Gurmukhi, "Guru")
|
|
||||||
DEF(Han, "Hani")
|
|
||||||
DEF(Hangul, "Hang")
|
|
||||||
DEF(Hanifi_Rohingya, "Rohg")
|
|
||||||
DEF(Hanunoo, "Hano")
|
|
||||||
DEF(Hatran, "Hatr")
|
|
||||||
DEF(Hebrew, "Hebr")
|
|
||||||
DEF(Hiragana, "Hira")
|
|
||||||
DEF(Imperial_Aramaic, "Armi")
|
|
||||||
DEF(Inherited, "Zinh,Qaai")
|
|
||||||
DEF(Inscriptional_Pahlavi, "Phli")
|
|
||||||
DEF(Inscriptional_Parthian, "Prti")
|
|
||||||
DEF(Javanese, "Java")
|
|
||||||
DEF(Kaithi, "Kthi")
|
|
||||||
DEF(Kannada, "Knda")
|
|
||||||
DEF(Katakana, "Kana")
|
|
||||||
DEF(Kawi, "Kawi")
|
|
||||||
DEF(Kayah_Li, "Kali")
|
|
||||||
DEF(Kharoshthi, "Khar")
|
|
||||||
DEF(Khmer, "Khmr")
|
|
||||||
DEF(Khojki, "Khoj")
|
|
||||||
DEF(Khitan_Small_Script, "Kits")
|
|
||||||
DEF(Khudawadi, "Sind")
|
|
||||||
DEF(Lao, "Laoo")
|
|
||||||
DEF(Latin, "Latn")
|
|
||||||
DEF(Lepcha, "Lepc")
|
|
||||||
DEF(Limbu, "Limb")
|
|
||||||
DEF(Linear_A, "Lina")
|
|
||||||
DEF(Linear_B, "Linb")
|
|
||||||
DEF(Lisu, "Lisu")
|
|
||||||
DEF(Lycian, "Lyci")
|
|
||||||
DEF(Lydian, "Lydi")
|
|
||||||
DEF(Makasar, "Maka")
|
|
||||||
DEF(Mahajani, "Mahj")
|
|
||||||
DEF(Malayalam, "Mlym")
|
|
||||||
DEF(Mandaic, "Mand")
|
|
||||||
DEF(Manichaean, "Mani")
|
|
||||||
DEF(Marchen, "Marc")
|
|
||||||
DEF(Masaram_Gondi, "Gonm")
|
|
||||||
DEF(Medefaidrin, "Medf")
|
|
||||||
DEF(Meetei_Mayek, "Mtei")
|
|
||||||
DEF(Mende_Kikakui, "Mend")
|
|
||||||
DEF(Meroitic_Cursive, "Merc")
|
|
||||||
DEF(Meroitic_Hieroglyphs, "Mero")
|
|
||||||
DEF(Miao, "Plrd")
|
|
||||||
DEF(Modi, "Modi")
|
|
||||||
DEF(Mongolian, "Mong")
|
|
||||||
DEF(Mro, "Mroo")
|
|
||||||
DEF(Multani, "Mult")
|
|
||||||
DEF(Myanmar, "Mymr")
|
|
||||||
DEF(Nabataean, "Nbat")
|
|
||||||
DEF(Nag_Mundari, "Nagm")
|
|
||||||
DEF(Nandinagari, "Nand")
|
|
||||||
DEF(New_Tai_Lue, "Talu")
|
|
||||||
DEF(Newa, "Newa")
|
|
||||||
DEF(Nko, "Nkoo")
|
|
||||||
DEF(Nushu, "Nshu")
|
|
||||||
DEF(Nyiakeng_Puachue_Hmong, "Hmnp")
|
|
||||||
DEF(Ogham, "Ogam")
|
|
||||||
DEF(Ol_Chiki, "Olck")
|
|
||||||
DEF(Old_Hungarian, "Hung")
|
|
||||||
DEF(Old_Italic, "Ital")
|
|
||||||
DEF(Old_North_Arabian, "Narb")
|
|
||||||
DEF(Old_Permic, "Perm")
|
|
||||||
DEF(Old_Persian, "Xpeo")
|
|
||||||
DEF(Old_Sogdian, "Sogo")
|
|
||||||
DEF(Old_South_Arabian, "Sarb")
|
|
||||||
DEF(Old_Turkic, "Orkh")
|
|
||||||
DEF(Old_Uyghur, "Ougr")
|
|
||||||
DEF(Oriya, "Orya")
|
|
||||||
DEF(Osage, "Osge")
|
|
||||||
DEF(Osmanya, "Osma")
|
|
||||||
DEF(Pahawh_Hmong, "Hmng")
|
|
||||||
DEF(Palmyrene, "Palm")
|
|
||||||
DEF(Pau_Cin_Hau, "Pauc")
|
|
||||||
DEF(Phags_Pa, "Phag")
|
|
||||||
DEF(Phoenician, "Phnx")
|
|
||||||
DEF(Psalter_Pahlavi, "Phlp")
|
|
||||||
DEF(Rejang, "Rjng")
|
|
||||||
DEF(Runic, "Runr")
|
|
||||||
DEF(Samaritan, "Samr")
|
|
||||||
DEF(Saurashtra, "Saur")
|
|
||||||
DEF(Sharada, "Shrd")
|
|
||||||
DEF(Shavian, "Shaw")
|
|
||||||
DEF(Siddham, "Sidd")
|
|
||||||
DEF(SignWriting, "Sgnw")
|
|
||||||
DEF(Sinhala, "Sinh")
|
|
||||||
DEF(Sogdian, "Sogd")
|
|
||||||
DEF(Sora_Sompeng, "Sora")
|
|
||||||
DEF(Soyombo, "Soyo")
|
|
||||||
DEF(Sundanese, "Sund")
|
|
||||||
DEF(Syloti_Nagri, "Sylo")
|
|
||||||
DEF(Syriac, "Syrc")
|
|
||||||
DEF(Tagalog, "Tglg")
|
|
||||||
DEF(Tagbanwa, "Tagb")
|
|
||||||
DEF(Tai_Le, "Tale")
|
|
||||||
DEF(Tai_Tham, "Lana")
|
|
||||||
DEF(Tai_Viet, "Tavt")
|
|
||||||
DEF(Takri, "Takr")
|
|
||||||
DEF(Tamil, "Taml")
|
|
||||||
DEF(Tangut, "Tang")
|
|
||||||
DEF(Telugu, "Telu")
|
|
||||||
DEF(Thaana, "Thaa")
|
|
||||||
DEF(Thai, "Thai")
|
|
||||||
DEF(Tibetan, "Tibt")
|
|
||||||
DEF(Tifinagh, "Tfng")
|
|
||||||
DEF(Tirhuta, "Tirh")
|
|
||||||
DEF(Tangsa, "Tnsa")
|
|
||||||
DEF(Toto, "Toto")
|
|
||||||
DEF(Ugaritic, "Ugar")
|
|
||||||
DEF(Vai, "Vaii")
|
|
||||||
DEF(Vithkuqi, "Vith")
|
|
||||||
DEF(Wancho, "Wcho")
|
|
||||||
DEF(Warang_Citi, "Wara")
|
|
||||||
DEF(Yezidi, "Yezi")
|
|
||||||
DEF(Yi, "Yiii")
|
|
||||||
DEF(Zanabazar_Square, "Zanb")
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef UNICODE_PROP_LIST
|
|
||||||
/* Prop list not exported to regexp */
|
|
||||||
DEF(Hyphen, "")
|
|
||||||
DEF(Other_Math, "")
|
|
||||||
DEF(Other_Alphabetic, "")
|
|
||||||
DEF(Other_Lowercase, "")
|
|
||||||
DEF(Other_Uppercase, "")
|
|
||||||
DEF(Other_Grapheme_Extend, "")
|
|
||||||
DEF(Other_Default_Ignorable_Code_Point, "")
|
|
||||||
DEF(Other_ID_Start, "")
|
|
||||||
DEF(Other_ID_Continue, "")
|
|
||||||
DEF(Prepended_Concatenation_Mark, "")
|
|
||||||
/* additional computed properties for smaller tables */
|
|
||||||
DEF(ID_Continue1, "")
|
|
||||||
DEF(XID_Start1, "")
|
|
||||||
DEF(XID_Continue1, "")
|
|
||||||
DEF(Changes_When_Titlecased1, "")
|
|
||||||
DEF(Changes_When_Casefolded1, "")
|
|
||||||
DEF(Changes_When_NFKC_Casefolded1, "")
|
|
||||||
|
|
||||||
/* Prop list exported to JS */
|
|
||||||
DEF(ASCII_Hex_Digit, "AHex")
|
|
||||||
DEF(Bidi_Control, "Bidi_C")
|
|
||||||
DEF(Dash, "")
|
|
||||||
DEF(Deprecated, "Dep")
|
|
||||||
DEF(Diacritic, "Dia")
|
|
||||||
DEF(Extender, "Ext")
|
|
||||||
DEF(Hex_Digit, "Hex")
|
|
||||||
DEF(IDS_Binary_Operator, "IDSB")
|
|
||||||
DEF(IDS_Trinary_Operator, "IDST")
|
|
||||||
DEF(Ideographic, "Ideo")
|
|
||||||
DEF(Join_Control, "Join_C")
|
|
||||||
DEF(Logical_Order_Exception, "LOE")
|
|
||||||
DEF(Noncharacter_Code_Point, "NChar")
|
|
||||||
DEF(Pattern_Syntax, "Pat_Syn")
|
|
||||||
DEF(Pattern_White_Space, "Pat_WS")
|
|
||||||
DEF(Quotation_Mark, "QMark")
|
|
||||||
DEF(Radical, "")
|
|
||||||
DEF(Regional_Indicator, "RI")
|
|
||||||
DEF(Sentence_Terminal, "STerm")
|
|
||||||
DEF(Soft_Dotted, "SD")
|
|
||||||
DEF(Terminal_Punctuation, "Term")
|
|
||||||
DEF(Unified_Ideograph, "UIdeo")
|
|
||||||
DEF(Variation_Selector, "VS")
|
|
||||||
DEF(White_Space, "space")
|
|
||||||
DEF(Bidi_Mirrored, "Bidi_M")
|
|
||||||
DEF(Emoji, "")
|
|
||||||
DEF(Emoji_Component, "EComp")
|
|
||||||
DEF(Emoji_Modifier, "EMod")
|
|
||||||
DEF(Emoji_Modifier_Base, "EBase")
|
|
||||||
DEF(Emoji_Presentation, "EPres")
|
|
||||||
DEF(Extended_Pictographic, "ExtPict")
|
|
||||||
DEF(Default_Ignorable_Code_Point, "DI")
|
|
||||||
DEF(ID_Start, "IDS")
|
|
||||||
DEF(Case_Ignorable, "CI")
|
|
||||||
|
|
||||||
/* other binary properties */
|
|
||||||
DEF(ASCII,"")
|
|
||||||
DEF(Alphabetic, "Alpha")
|
|
||||||
DEF(Any, "")
|
|
||||||
DEF(Assigned,"")
|
|
||||||
DEF(Cased, "")
|
|
||||||
DEF(Changes_When_Casefolded, "CWCF")
|
|
||||||
DEF(Changes_When_Casemapped, "CWCM")
|
|
||||||
DEF(Changes_When_Lowercased, "CWL")
|
|
||||||
DEF(Changes_When_NFKC_Casefolded, "CWKCF")
|
|
||||||
DEF(Changes_When_Titlecased, "CWT")
|
|
||||||
DEF(Changes_When_Uppercased, "CWU")
|
|
||||||
DEF(Grapheme_Base, "Gr_Base")
|
|
||||||
DEF(Grapheme_Extend, "Gr_Ext")
|
|
||||||
DEF(ID_Continue, "IDC")
|
|
||||||
DEF(Lowercase, "Lower")
|
|
||||||
DEF(Math, "")
|
|
||||||
DEF(Uppercase, "Upper")
|
|
||||||
DEF(XID_Continue, "XIDC")
|
|
||||||
DEF(XID_Start, "XIDS")
|
|
||||||
|
|
||||||
/* internal tables with index */
|
|
||||||
DEF(Cased1, "")
|
|
||||||
|
|
||||||
#endif
|
|
Loading…
Reference in a new issue