├── Changelog ├── LICENSE ├── Makefile ├── README.md ├── TODO ├── VERSION ├── bench ├── test.c ├── test.js └── test.wasm ├── build_wasi.sh ├── cutils.c ├── cutils.h ├── doc ├── jsbignum.texi └── quickjs.texi ├── examples ├── fib.c ├── fib_module.js ├── hello.js ├── hello_module.js ├── pi_bigdecimal.js ├── pi_bigfloat.js ├── pi_bigint.js ├── point.c ├── test_fib.js └── test_point.js ├── lib ├── binding.rs ├── build_lib.sh ├── libquickjs.a ├── wapper.c └── wapper.h ├── libbf.c ├── libbf.h ├── libregexp-opcode.h ├── libregexp.c ├── libregexp.h ├── libunicode-table.h ├── libunicode.c ├── libunicode.h ├── list.h ├── qjs.c ├── qjs.wasm ├── qjsc.c ├── qjscalc.c ├── qjscalc.js ├── quickjs-atom.h ├── quickjs-libc.c ├── quickjs-libc.h ├── quickjs-opcode.h ├── quickjs.c ├── quickjs.h ├── readme.txt ├── release.sh ├── repl.c ├── repl.js ├── run-test262.c ├── test262.conf ├── test262_errors.txt ├── test262o.conf ├── test262o_errors.txt ├── tests ├── bjson.c ├── microbench.js ├── test262.patch ├── test_bignum.js ├── test_bjson.js ├── test_builtin.js ├── test_closure.js ├── test_language.js ├── test_loop.js ├── test_op_overloading.js ├── test_qjscalc.js ├── test_std.js ├── test_worker.js └── test_worker_module.js ├── unicode_download.sh ├── unicode_gen.c └── unicode_gen_def.h /Changelog: -------------------------------------------------------------------------------- 1 | 2024-01-13: 2 | 3 | - top-level-await support in modules 4 | - allow 'await' in the REPL 5 | - added Array.prototype.{with,toReversed,toSpliced,toSorted} and 6 | TypedArray.prototype.{with,toReversed,toSorted} 7 | - added String.prototype.isWellFormed and String.prototype.toWellFormed 8 | - added Object.groupBy and Map.groupBy 9 | - added Promise.withResolvers 10 | - class static block 11 | - 'in' operator support for private fields 12 | - optional chaining fixes 13 | - added RegExp 'd' flag 14 | - fixed RegExp zero length match logic 15 | - fixed RegExp case insensitive flag 16 | - added os.sleepAsync(), os.getpid() and os.now() 17 | - added cosmopolitan build 18 | - misc bug fixes 19 | 20 | 2023-12-09: 21 | 22 | - added Object.hasOwn, {String|Array|TypedArray}.prototype.at, 23 | {Array|TypedArray}.prototype.findLast{Index} 24 | - BigInt support is enabled even if CONFIG_BIGNUM disabled 25 | - updated to Unicode 15.0.0 26 | - misc bug fixes 27 | 28 | 2021-03-27: 29 | 30 | - faster Array.prototype.push and Array.prototype.unshift 31 | - added JS_UpdateStackTop() 32 | - fixed Windows console 33 | - misc bug fixes 34 | 35 | 2020-11-08: 36 | 37 | - improved function parameter initializers 38 | - added std.setenv(), std.unsetenv() and std.getenviron() 39 | - added JS_EvalThis() 40 | - misc bug fixes 41 | 42 | 2020-09-06: 43 | 44 | - added logical assignment operators 45 | - added IsHTMLDDA support 46 | - faster for-of loops 47 | - os.Worker now takes a module filename as parameter 48 | - qjsc: added -D option to compile dynamically loaded modules or workers 49 | - misc bug fixes 50 | 51 | 2020-07-05: 52 | 53 | - modified JS_GetPrototype() to return a live value 54 | - REPL: support unicode characters larger than 16 bits 55 | - added os.Worker 56 | - improved object serialization 57 | - added std.parseExtJSON 58 | - misc bug fixes 59 | 60 | 2020-04-12: 61 | 62 | - added cross realm support 63 | - added AggregateError and Promise.any 64 | - added env, uid and gid options in os.exec() 65 | - misc bug fixes 66 | 67 | 2020-03-16: 68 | 69 | - reworked error handling in std and os libraries: suppressed I/O 70 | exceptions in std FILE functions and return a positive errno value 71 | when it is explicit 72 | - output exception messages to stderr 73 | - added std.loadFile(), std.strerror(), std.FILE.prototype.tello() 74 | - added JS_GetRuntimeOpaque(), JS_SetRuntimeOpaque(), JS_NewUint32() 75 | - updated to Unicode 13.0.0 76 | - misc bug fixes 77 | 78 | 2020-01-19: 79 | 80 | - keep CONFIG_BIGNUM in the makefile 81 | - added os.chdir() 82 | - qjs: added -I option 83 | - more memory checks in the bignum operations 84 | - modified operator overloading semantics to be closer to the TC39 85 | proposal 86 | - suppressed "use bigint" mode. Simplified "use math" mode 87 | - BigDecimal: changed suffix from 'd' to 'm' 88 | - misc bug fixes 89 | 90 | 2020-01-05: 91 | 92 | - always compile the bignum code. Added '--bignum' option to qjs. 93 | - added BigDecimal 94 | - added String.prototype.replaceAll 95 | - misc bug fixes 96 | 97 | 2019-12-21: 98 | 99 | - added nullish coalescing operator (ES2020) 100 | - added optional chaining (ES2020) 101 | - removed recursions in garbage collector 102 | - test stack overflow in the parser 103 | - improved backtrace logic 104 | - added JS_SetHostPromiseRejectionTracker() 105 | - allow exotic constructors 106 | - improved c++ compatibility 107 | - misc bug fixes 108 | 109 | 2019-10-27: 110 | 111 | - added example of C class in a module (examples/test_point.js) 112 | - added JS_GetTypedArrayBuffer() 113 | - misc bug fixes 114 | 115 | 2019-09-18: 116 | 117 | - added os.exec and other system calls 118 | - exported JS_ValueToAtom() 119 | - qjsc: added 'qjsc_' prefix to the generated C identifiers 120 | - added cross-compilation support 121 | - misc bug fixes 122 | 123 | 2019-09-01: 124 | 125 | - added globalThis 126 | - documented JS_EVAL_FLAG_COMPILE_ONLY 127 | - added import.meta.url and import.meta.main 128 | - added 'debugger' statement 129 | - misc bug fixes 130 | 131 | 2019-08-18: 132 | 133 | - added os.realpath, os.getcwd, os.mkdir, os.stat, os.lstat, 134 | os.readlink, os.readdir, os.utimes, std.popen 135 | - module autodetection 136 | - added import.meta 137 | - misc bug fixes 138 | 139 | 2019-08-10: 140 | 141 | - added public class fields and private class fields, methods and 142 | accessors (TC39 proposal) 143 | - changed JS_ToCStringLen() prototype 144 | - qjsc: handle '-' in module names and modules with the same filename 145 | - added std.urlGet 146 | - exported JS_GetOwnPropertyNames() and JS_GetOwnProperty() 147 | - exported some bigint C functions 148 | - added support for eshost in run-test262 149 | - misc bug fixes 150 | 151 | 2019-07-28: 152 | 153 | - added dynamic import 154 | - added Promise.allSettled 155 | - added String.prototype.matchAll 156 | - added Object.fromEntries 157 | - reduced number of ticks in await 158 | - added BigInt support in Atomics 159 | - exported JS_NewPromiseCapability() 160 | - misc async function and async generator fixes 161 | - enabled hashbang support by default 162 | 163 | 2019-07-21: 164 | 165 | - updated test262 tests 166 | - updated to Unicode version 12.1.0 167 | - fixed missing Date object in qjsc 168 | - fixed multi-context creation 169 | - misc ES2020 related fixes 170 | - simplified power and division operators in bignum extension 171 | - fixed several crash conditions 172 | 173 | 2019-07-09: 174 | 175 | - first public release 176 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | QuickJS Javascript Engine 2 | 3 | Copyright (c) 2017-2021 Fabrice Bellard 4 | Copyright (c) 2017-2021 Charlie Gordon 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in 14 | all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # QuickJS Javascript Engine 3 | # 4 | # Copyright (c) 2017-2021 Fabrice Bellard 5 | # Copyright (c) 2017-2021 Charlie Gordon 6 | # 7 | # Permission is hereby granted, free of charge, to any person obtaining a copy 8 | # of this software and associated documentation files (the "Software"), to deal 9 | # in the Software without restriction, including without limitation the rights 10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | # copies of the Software, and to permit persons to whom the Software is 12 | # furnished to do so, subject to the following conditions: 13 | # 14 | # The above copyright notice and this permission notice shall be included in 15 | # all copies or substantial portions of the Software. 16 | # 17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | # THE SOFTWARE. 24 | 25 | ifeq ($(shell uname -s),Darwin) 26 | CONFIG_DARWIN=y 27 | endif 28 | # Windows cross compilation from Linux 29 | #CONFIG_WIN32=y 30 | # use link time optimization (smaller and faster executables but slower build) 31 | # CONFIG_LTO=y 32 | # consider warnings as errors (for development) 33 | #CONFIG_WERROR=y 34 | # force 32 bit build for some utilities 35 | #CONFIG_M32=y 36 | # cosmopolitan build (see https://github.com/jart/cosmopolitan) 37 | #CONFIG_COSMO=y 38 | 39 | # installation directory 40 | PREFIX?=/usr/local 41 | 42 | # use the gprof profiler 43 | #CONFIG_PROFILE=y 44 | # use address sanitizer 45 | #CONFIG_ASAN=y 46 | # include the code for BigFloat/BigDecimal, math mode and faster large integers 47 | CONFIG_BIGNUM=y 48 | 49 | OBJDIR=.obj 50 | 51 | ifdef CONFIG_DARWIN 52 | # use clang instead of gcc 53 | CONFIG_CLANG=y 54 | CONFIG_DEFAULT_AR=y 55 | endif 56 | 57 | ifdef CONFIG_WIN32 58 | ifdef CONFIG_M32 59 | CROSS_PREFIX?=i686-w64-mingw32- 60 | else 61 | CROSS_PREFIX?=x86_64-w64-mingw32- 62 | endif 63 | EXE=.exe 64 | else 65 | CROSS_PREFIX?= 66 | EXE= 67 | endif 68 | 69 | ifdef CONFIG_CLANG 70 | HOST_CC=clang 71 | CC=$(CROSS_PREFIX)clang 72 | CFLAGS+=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d 73 | CFLAGS += -Wextra 74 | CFLAGS += -Wno-sign-compare 75 | CFLAGS += -Wno-missing-field-initializers 76 | CFLAGS += -Wundef -Wuninitialized 77 | CFLAGS += -Wunused -Wno-unused-parameter 78 | CFLAGS += -Wwrite-strings 79 | CFLAGS += -Wchar-subscripts -funsigned-char 80 | CFLAGS += -MMD -MF $(OBJDIR)/$(@F).d 81 | ifdef CONFIG_DEFAULT_AR 82 | AR=$(CROSS_PREFIX)ar 83 | else 84 | ifdef CONFIG_LTO 85 | AR=$(CROSS_PREFIX)llvm-ar 86 | else 87 | AR=$(CROSS_PREFIX)ar 88 | endif 89 | endif 90 | else ifdef CONFIG_COSMO 91 | CONFIG_LTO= 92 | HOST_CC=gcc 93 | CC=cosmocc 94 | # cosmocc does not correct support -MF 95 | CFLAGS=-g -Wall #-MMD -MF $(OBJDIR)/$(@F).d 96 | CFLAGS += -Wno-array-bounds -Wno-format-truncation 97 | AR=cosmoar 98 | else 99 | HOST_CC=gcc 100 | CC=$(CROSS_PREFIX)gcc 101 | CFLAGS+=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d 102 | CFLAGS += -Wno-array-bounds -Wno-format-truncation 103 | ifdef CONFIG_LTO 104 | AR=$(CROSS_PREFIX)gcc-ar 105 | else 106 | AR=$(CROSS_PREFIX)ar 107 | endif 108 | endif 109 | STRIP=$(CROSS_PREFIX)strip 110 | CFLAGS+=-fwrapv # ensure that signed overflows behave as expected 111 | ifdef CONFIG_WERROR 112 | CFLAGS+=-Werror 113 | endif 114 | DEFINES:=-D_GNU_SOURCE -DCONFIG_VERSION=\"$(shell cat VERSION)\" 115 | ifdef CONFIG_BIGNUM 116 | DEFINES+=-DCONFIG_BIGNUM 117 | endif 118 | ifdef CONFIG_WIN32 119 | DEFINES+=-D__USE_MINGW_ANSI_STDIO # for standard snprintf behavior 120 | endif 121 | 122 | DEFINES+=-D__wasi__ 123 | DEFINES+=-D__native__ 124 | 125 | CFLAGS+=$(DEFINES) 126 | CFLAGS_DEBUG=$(CFLAGS) -O0 127 | CFLAGS_SMALL=$(CFLAGS) -Os 128 | CFLAGS_OPT=$(CFLAGS) -O2 129 | CFLAGS_NOLTO:=$(CFLAGS_OPT) 130 | ifdef CONFIG_COSMO 131 | LDFLAGS+=-s # better to strip by default 132 | else 133 | LDFLAGS+=-g 134 | endif 135 | ifdef CONFIG_LTO 136 | CFLAGS_SMALL+=-flto 137 | CFLAGS_OPT+=-flto 138 | LDFLAGS+=-flto 139 | endif 140 | ifdef CONFIG_PROFILE 141 | CFLAGS+=-p 142 | LDFLAGS+=-p 143 | endif 144 | ifdef CONFIG_ASAN 145 | CFLAGS+=-fsanitize=address -fno-omit-frame-pointer 146 | LDFLAGS+=-fsanitize=address -fno-omit-frame-pointer 147 | endif 148 | ifdef CONFIG_WIN32 149 | LDEXPORT= 150 | else 151 | LDEXPORT=-rdynamic 152 | endif 153 | 154 | ifndef CONFIG_COSMO 155 | ifndef CONFIG_DARWIN 156 | CONFIG_SHARED_LIBS=y # building shared libraries is supported 157 | endif 158 | endif 159 | 160 | PROGS=qjs$(EXE) qjsc$(EXE) run-test262 161 | ifneq ($(CROSS_PREFIX),) 162 | QJSC_CC=gcc 163 | QJSC=./host-qjsc 164 | PROGS+=$(QJSC) 165 | else 166 | QJSC_CC=$(CC) 167 | QJSC=./qjsc$(EXE) 168 | endif 169 | ifndef CONFIG_WIN32 170 | PROGS+=qjscalc 171 | endif 172 | ifdef CONFIG_M32 173 | PROGS+=qjs32 qjs32_s 174 | endif 175 | PROGS+=libquickjs.a 176 | ifdef CONFIG_LTO 177 | PROGS+=libquickjs.lto.a 178 | endif 179 | 180 | # examples 181 | ifeq ($(CROSS_PREFIX),) 182 | PROGS+=examples/hello 183 | ifndef CONFIG_ASAN 184 | PROGS+=examples/hello_module 185 | endif 186 | ifdef CONFIG_SHARED_LIBS 187 | PROGS+=examples/test_fib examples/fib.so examples/point.so 188 | endif 189 | endif 190 | 191 | all: $(OBJDIR) $(OBJDIR)/quickjs.check.o $(OBJDIR)/qjs.check.o $(PROGS) 192 | 193 | QJS_LIB_OBJS=$(OBJDIR)/quickjs.o $(OBJDIR)/libregexp.o $(OBJDIR)/libunicode.o $(OBJDIR)/cutils.o $(OBJDIR)/quickjs-libc.o $(OBJDIR)/libbf.o 194 | 195 | QJS_OBJS=$(OBJDIR)/qjs.o $(OBJDIR)/repl.o $(QJS_LIB_OBJS) 196 | ifdef CONFIG_BIGNUM 197 | QJS_OBJS+=$(OBJDIR)/qjscalc.o 198 | endif 199 | 200 | HOST_LIBS=-lm -ldl -lpthread 201 | LIBS=-lm 202 | ifndef CONFIG_WIN32 203 | LIBS+=-ldl -lpthread 204 | endif 205 | LIBS+=$(EXTRA_LIBS) 206 | 207 | $(OBJDIR): 208 | mkdir -p $(OBJDIR) $(OBJDIR)/examples $(OBJDIR)/tests 209 | 210 | qjs$(EXE): $(QJS_OBJS) 211 | $(CC) $(LDFLAGS) $(LDEXPORT) -o $@ $^ $(LIBS) 212 | 213 | qjs-debug$(EXE): $(patsubst %.o, %.debug.o, $(QJS_OBJS)) 214 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 215 | 216 | qjsc$(EXE): $(OBJDIR)/qjsc.o $(QJS_LIB_OBJS) 217 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 218 | 219 | ifneq ($(CROSS_PREFIX),) 220 | 221 | $(QJSC): $(OBJDIR)/qjsc.host.o \ 222 | $(patsubst %.o, %.host.o, $(QJS_LIB_OBJS)) 223 | $(HOST_CC) $(LDFLAGS) -o $@ $^ $(HOST_LIBS) 224 | 225 | endif #CROSS_PREFIX 226 | 227 | QJSC_DEFINES:=-DCONFIG_CC=\"$(QJSC_CC)\" -DCONFIG_PREFIX=\"$(PREFIX)\" 228 | ifdef CONFIG_LTO 229 | QJSC_DEFINES+=-DCONFIG_LTO 230 | endif 231 | QJSC_HOST_DEFINES:=-DCONFIG_CC=\"$(HOST_CC)\" -DCONFIG_PREFIX=\"$(PREFIX)\" 232 | 233 | $(OBJDIR)/qjsc.o: CFLAGS+=$(QJSC_DEFINES) 234 | $(OBJDIR)/qjsc.host.o: CFLAGS+=$(QJSC_HOST_DEFINES) 235 | 236 | qjs32: $(patsubst %.o, %.m32.o, $(QJS_OBJS)) 237 | $(CC) -m32 $(LDFLAGS) $(LDEXPORT) -o $@ $^ $(LIBS) 238 | 239 | qjs32_s: $(patsubst %.o, %.m32s.o, $(QJS_OBJS)) 240 | $(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS) 241 | @size $@ 242 | 243 | qjscalc: qjs 244 | ln -sf $< $@ 245 | 246 | ifdef CONFIG_LTO 247 | LTOEXT=.lto 248 | else 249 | LTOEXT= 250 | endif 251 | 252 | libquickjs$(LTOEXT).a: $(QJS_LIB_OBJS) 253 | $(AR) rcs $@ $^ 254 | 255 | ifdef CONFIG_LTO 256 | libquickjs.a: $(patsubst %.o, %.nolto.o, $(QJS_LIB_OBJS)) 257 | $(AR) rcs $@ $^ 258 | endif # CONFIG_LTO 259 | 260 | repl.c: $(QJSC) repl.js 261 | $(QJSC) -c -o $@ -m repl.js 262 | 263 | qjscalc.c: $(QJSC) qjscalc.js 264 | $(QJSC) -fbignum -c -o $@ qjscalc.js 265 | 266 | ifneq ($(wildcard unicode/UnicodeData.txt),) 267 | $(OBJDIR)/libunicode.o $(OBJDIR)/libunicode.m32.o $(OBJDIR)/libunicode.m32s.o \ 268 | $(OBJDIR)/libunicode.nolto.o: libunicode-table.h 269 | 270 | libunicode-table.h: unicode_gen 271 | ./unicode_gen unicode $@ 272 | endif 273 | 274 | run-test262: $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS) 275 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 276 | 277 | run-test262-debug: $(patsubst %.o, %.debug.o, $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS)) 278 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 279 | 280 | run-test262-32: $(patsubst %.o, %.m32.o, $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS)) 281 | $(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS) 282 | 283 | # object suffix order: nolto, [m32|m32s] 284 | 285 | $(OBJDIR)/%.o: %.c | $(OBJDIR) 286 | $(CC) $(CFLAGS_OPT) -c -o $@ $< 287 | 288 | $(OBJDIR)/%.host.o: %.c | $(OBJDIR) 289 | $(HOST_CC) $(CFLAGS_OPT) -c -o $@ $< 290 | 291 | $(OBJDIR)/%.pic.o: %.c | $(OBJDIR) 292 | $(CC) $(CFLAGS_OPT) -fPIC -DJS_SHARED_LIBRARY -c -o $@ $< 293 | 294 | $(OBJDIR)/%.nolto.o: %.c | $(OBJDIR) 295 | $(CC) $(CFLAGS_NOLTO) -c -o $@ $< 296 | 297 | $(OBJDIR)/%.m32.o: %.c | $(OBJDIR) 298 | $(CC) -m32 $(CFLAGS_OPT) -c -o $@ $< 299 | 300 | $(OBJDIR)/%.m32s.o: %.c | $(OBJDIR) 301 | $(CC) -m32 $(CFLAGS_SMALL) -c -o $@ $< 302 | 303 | $(OBJDIR)/%.debug.o: %.c | $(OBJDIR) 304 | $(CC) $(CFLAGS_DEBUG) -c -o $@ $< 305 | 306 | $(OBJDIR)/%.check.o: %.c | $(OBJDIR) 307 | $(CC) $(CFLAGS) -DCONFIG_CHECK_JSVALUE -c -o $@ $< 308 | 309 | regexp_test: libregexp.c libunicode.c cutils.c 310 | $(CC) $(LDFLAGS) $(CFLAGS) -DTEST -o $@ libregexp.c libunicode.c cutils.c $(LIBS) 311 | 312 | unicode_gen: $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o libunicode.c unicode_gen_def.h 313 | $(HOST_CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o 314 | 315 | clean: 316 | rm -f repl.c qjscalc.c out.c 317 | rm -f *.a *.o *.d *~ unicode_gen regexp_test $(PROGS) 318 | rm -f hello.c test_fib.c 319 | rm -f examples/*.so tests/*.so 320 | rm -rf $(OBJDIR)/ *.dSYM/ qjs-debug 321 | rm -rf run-test262-debug run-test262-32 322 | 323 | install: all 324 | mkdir -p "$(DESTDIR)$(PREFIX)/bin" 325 | $(STRIP) qjs qjsc 326 | install -m755 qjs qjsc "$(DESTDIR)$(PREFIX)/bin" 327 | ln -sf qjs "$(DESTDIR)$(PREFIX)/bin/qjscalc" 328 | mkdir -p "$(DESTDIR)$(PREFIX)/lib/quickjs" 329 | install -m644 libquickjs.a "$(DESTDIR)$(PREFIX)/lib/quickjs" 330 | ifdef CONFIG_LTO 331 | install -m644 libquickjs.lto.a "$(DESTDIR)$(PREFIX)/lib/quickjs" 332 | endif 333 | mkdir -p "$(DESTDIR)$(PREFIX)/include/quickjs" 334 | install -m644 quickjs.h quickjs-libc.h "$(DESTDIR)$(PREFIX)/include/quickjs" 335 | 336 | ############################################################################### 337 | # examples 338 | 339 | # example of static JS compilation 340 | HELLO_SRCS=examples/hello.js 341 | HELLO_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \ 342 | -fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \ 343 | -fno-date -fno-module-loader -fno-bigint 344 | 345 | hello.c: $(QJSC) $(HELLO_SRCS) 346 | $(QJSC) -e $(HELLO_OPTS) -o $@ $(HELLO_SRCS) 347 | 348 | ifdef CONFIG_M32 349 | examples/hello: $(OBJDIR)/hello.m32s.o $(patsubst %.o, %.m32s.o, $(QJS_LIB_OBJS)) 350 | $(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS) 351 | else 352 | examples/hello: $(OBJDIR)/hello.o $(QJS_LIB_OBJS) 353 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 354 | endif 355 | 356 | # example of static JS compilation with modules 357 | HELLO_MODULE_SRCS=examples/hello_module.js 358 | HELLO_MODULE_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \ 359 | -fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \ 360 | -fno-date -m 361 | examples/hello_module: $(QJSC) libquickjs$(LTOEXT).a $(HELLO_MODULE_SRCS) 362 | $(QJSC) $(HELLO_MODULE_OPTS) -o $@ $(HELLO_MODULE_SRCS) 363 | 364 | # use of an external C module (static compilation) 365 | 366 | test_fib.c: $(QJSC) examples/test_fib.js 367 | $(QJSC) -e -M examples/fib.so,fib -m -o $@ examples/test_fib.js 368 | 369 | examples/test_fib: $(OBJDIR)/test_fib.o $(OBJDIR)/examples/fib.o libquickjs$(LTOEXT).a 370 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS) 371 | 372 | examples/fib.so: $(OBJDIR)/examples/fib.pic.o 373 | $(CC) $(LDFLAGS) -shared -o $@ $^ 374 | 375 | examples/point.so: $(OBJDIR)/examples/point.pic.o 376 | $(CC) $(LDFLAGS) -shared -o $@ $^ 377 | 378 | ############################################################################### 379 | # documentation 380 | 381 | DOCS=doc/quickjs.pdf doc/quickjs.html doc/jsbignum.pdf doc/jsbignum.html 382 | 383 | build_doc: $(DOCS) 384 | 385 | clean_doc: 386 | rm -f $(DOCS) 387 | 388 | doc/%.pdf: doc/%.texi 389 | texi2pdf --clean -o $@ -q $< 390 | 391 | doc/%.html.pre: doc/%.texi 392 | makeinfo --html --no-headers --no-split --number-sections -o $@ $< 393 | 394 | doc/%.html: doc/%.html.pre 395 | sed -e 's||\n|' < $< > $@ 396 | 397 | ############################################################################### 398 | # tests 399 | 400 | ifdef CONFIG_SHARED_LIBS 401 | test: tests/bjson.so examples/point.so 402 | endif 403 | ifdef CONFIG_M32 404 | test: qjs32 405 | endif 406 | 407 | test: qjs 408 | ./qjs tests/test_closure.js 409 | ./qjs tests/test_language.js 410 | ./qjs tests/test_builtin.js 411 | ./qjs tests/test_loop.js 412 | ./qjs tests/test_std.js 413 | ./qjs tests/test_worker.js 414 | ifdef CONFIG_SHARED_LIBS 415 | ifdef CONFIG_BIGNUM 416 | ./qjs --bignum tests/test_bjson.js 417 | else 418 | ./qjs tests/test_bjson.js 419 | endif 420 | ./qjs examples/test_point.js 421 | endif 422 | ifdef CONFIG_BIGNUM 423 | ./qjs --bignum tests/test_op_overloading.js 424 | ./qjs --bignum tests/test_bignum.js 425 | ./qjs --qjscalc tests/test_qjscalc.js 426 | endif 427 | ifdef CONFIG_M32 428 | ./qjs32 tests/test_closure.js 429 | ./qjs32 tests/test_language.js 430 | ./qjs32 tests/test_builtin.js 431 | ./qjs32 tests/test_loop.js 432 | ./qjs32 tests/test_std.js 433 | ./qjs32 tests/test_worker.js 434 | ifdef CONFIG_BIGNUM 435 | ./qjs32 --bignum tests/test_op_overloading.js 436 | ./qjs32 --bignum tests/test_bignum.js 437 | ./qjs32 --qjscalc tests/test_qjscalc.js 438 | endif 439 | endif 440 | 441 | stats: qjs qjs32 442 | ./qjs -qd 443 | ./qjs32 -qd 444 | 445 | microbench: qjs 446 | ./qjs tests/microbench.js 447 | 448 | microbench-32: qjs32 449 | ./qjs32 tests/microbench.js 450 | 451 | # ES5 tests (obsolete) 452 | test2o: run-test262 453 | time ./run-test262 -m -c test262o.conf 454 | 455 | test2o-32: run-test262-32 456 | time ./run-test262-32 -m -c test262o.conf 457 | 458 | test2o-update: run-test262 459 | ./run-test262 -u -c test262o.conf 460 | 461 | # Test262 tests 462 | test2-default: run-test262 463 | time ./run-test262 -m -c test262.conf 464 | 465 | test2: run-test262 466 | time ./run-test262 -m -c test262.conf -a 467 | 468 | test2-32: run-test262-32 469 | time ./run-test262-32 -m -c test262.conf -a 470 | 471 | test2-update: run-test262 472 | ./run-test262 -u -c test262.conf -a 473 | 474 | test2-check: run-test262 475 | time ./run-test262 -m -c test262.conf -E -a 476 | 477 | testall: all test microbench test2o test2 478 | 479 | testall-32: all test-32 microbench-32 test2o-32 test2-32 480 | 481 | testall-complete: testall testall-32 482 | 483 | bench-v8: qjs 484 | make -C tests/bench-v8 485 | ./qjs -d tests/bench-v8/combined.js 486 | 487 | tests/bjson.so: $(OBJDIR)/tests/bjson.pic.o 488 | $(CC) $(LDFLAGS) -shared -o $@ $^ $(LIBS) 489 | 490 | -include $(wildcard $(OBJDIR)/*.d) 491 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Build dependencies: 2 | - [`wasi-sdk(12)`](https://github.com/WebAssembly/wasi-sdk/releases). 3 | 4 | ## Compilation 5 | 6 | ```sh 7 | # build qjs.wasm 8 | ./build_wasi.sh 9 | ``` 10 | 11 | ## Run with WasmEdge(0.8.2-rc4+) 12 | 13 | ```sh 14 | #eval 15 | wasmedge --dir=.:. qjs.wasm -e "print('hello')" 16 | 17 | #repl 18 | wasmedge --dir=.:. qjs.wasm 19 | ``` 20 | 21 | ## Acknowledgment 22 | This project is form from [bellard/quickjs](https://github.com/bellard/quickjs) 23 | 24 | ### reference project 25 | [dip-proto/quickjs-wasi](https://github.com/dip-proto/quickjs-wasi) -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Misc ideas: 2 | - use custom printf to avoid compatibility issues with floating point numbers 3 | - consistent naming for preprocessor defines 4 | - unify coding style and naming conventions 5 | - use names from the ECMA spec in library implementation 6 | - use byte code emitters with typed arguments (for clarity) 7 | - use 2 bytecode DynBufs in JSFunctionDef, one for reading, one for writing 8 | and use the same wrappers in all phases 9 | - use more generic method for line numbers in resolve_variables and resolve_labels 10 | - use custom timezone support to avoid C library compatibility issues 11 | 12 | Memory: 13 | - use memory pools for objects, etc? 14 | - test border cases for max number of atoms, object properties, string length 15 | - add emergency malloc mode for out of memory exceptions. 16 | - test all DynBuf memory errors 17 | - test all js_realloc memory errors 18 | - improve JS_ComputeMemoryUsage() with more info 19 | 20 | Built-in standard library: 21 | - BSD sockets 22 | - modules: use realpath in module name normalizer and put it in quickjs-libc 23 | - modules: if no ".", use a well known module loading path ? 24 | - get rid of __loadScript, use more common name 25 | 26 | REPL: 27 | - debugger 28 | - readline: support MS Windows terminal 29 | - readline: handle dynamic terminal resizing 30 | - readline: handle double width unicode characters 31 | - multiline editing 32 | - runtime object and function inspectors 33 | - interactive object browser 34 | - use more generic approach to display evaluation results 35 | - improve directive handling: dispatch, colorize, completion... 36 | - save history 37 | - close all predefined methods in repl.js and jscalc.js 38 | 39 | Optimization ideas: 40 | - 64-bit atoms in 64-bit mode ? 41 | - 64-bit small bigint in 64-bit mode ? 42 | - reuse stack slots for disjoint scopes, if strip 43 | - add heuristic to avoid some cycles in closures 44 | - small String (0-2 charcodes) with immediate storage 45 | - perform static string concatenation at compile time 46 | - optimize string concatenation with ropes or miniropes? 47 | - add implicit numeric strings for Uint32 numbers? 48 | - optimize `s += a + b`, `s += a.b` and similar simple expressions 49 | - ensure string canonical representation and optimise comparisons and hashes? 50 | - remove JSObject.first_weak_ref, use bit+context based hashed array for weak references 51 | - property access optimization on the global object, functions, 52 | prototypes and special non extensible objects. 53 | - create object literals with the correct length by backpatching length argument 54 | - remove redundant set_loc_uninitialized/check_uninitialized opcodes 55 | - peephole optim: push_atom_value, to_propkey -> push_atom_value 56 | - peephole optim: put_loc x, get_loc_check x -> set_loc x 57 | - convert slow array to fast array when all properties != length are numeric 58 | - optimize destructuring assignments for global and local variables 59 | - implement some form of tail-call-optimization 60 | - optimize OP_apply 61 | - optimize f(...b) 62 | 63 | Test262o: 0/11262 errors, 463 excluded 64 | Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch) 65 | 66 | Result: 8/76947 errors, 1497 excluded, 8117 skipped 67 | Test262 commit: 6cbb6da9473c56d95358d8e679c5a6d2b4574efb 68 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 2024-01-13 2 | -------------------------------------------------------------------------------- /bench/test.c: -------------------------------------------------------------------------------- 1 | /* File generated automatically by the QuickJS compiler. */ 2 | 3 | #include "quickjs-libc.h" 4 | 5 | const uint32_t qjsc_test_size = 2646; 6 | 7 | const uint8_t qjsc_test[2646] = { 8 | 0x02, 0x39, 0x02, 0x69, 0x0e, 0x53, 0x69, 0x70, 9 | 0x48, 0x61, 0x73, 0x68, 0x0c, 0x6d, 0x6f, 0x64, 10 | 0x75, 0x6c, 0x65, 0x0e, 0x65, 0x78, 0x70, 0x6f, 11 | 0x72, 0x74, 0x73, 0x06, 0x6b, 0x65, 0x79, 0x02, 12 | 0x68, 0x1e, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 13 | 0x31, 0x36, 0x5f, 0x74, 0x6f, 0x5f, 0x6b, 0x65, 14 | 0x79, 0x20, 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 15 | 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63, 0x64, 16 | 0x65, 0x66, 0x02, 0x6c, 0x0e, 0x63, 0x6f, 0x6e, 17 | 0x73, 0x6f, 0x6c, 0x65, 0x06, 0x6c, 0x6f, 0x67, 18 | 0x18, 0x43, 0x6f, 0x6d, 0x70, 0x75, 0x74, 0x69, 19 | 0x6e, 0x67, 0x2e, 0x2e, 0x2e, 0x08, 0x68, 0x61, 20 | 0x73, 0x68, 0x0e, 0x74, 0x65, 0x73, 0x74, 0x2e, 21 | 0x6a, 0x73, 0x08, 0x5f, 0x61, 0x64, 0x64, 0x08, 22 | 0x5f, 0x78, 0x6f, 0x72, 0x0a, 0x5f, 0x72, 0x6f, 23 | 0x74, 0x6c, 0x0e, 0x5f, 0x72, 0x6f, 0x74, 0x6c, 24 | 0x33, 0x32, 0x12, 0x5f, 0x63, 0x6f, 0x6d, 0x70, 25 | 0x72, 0x65, 0x73, 0x73, 0x10, 0x5f, 0x67, 0x65, 26 | 0x74, 0x5f, 0x69, 0x6e, 0x74, 0x10, 0x68, 0x61, 27 | 0x73, 0x68, 0x5f, 0x68, 0x65, 0x78, 0x12, 0x68, 28 | 0x61, 0x73, 0x68, 0x5f, 0x75, 0x69, 0x6e, 0x74, 29 | 0x18, 0x73, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x5f, 30 | 0x74, 0x6f, 0x5f, 0x75, 0x38, 0x02, 0x61, 0x02, 31 | 0x62, 0x04, 0x72, 0x6c, 0x04, 0x61, 0x32, 0x02, 32 | 0x6e, 0x04, 0x61, 0x6c, 0x04, 0x76, 0x30, 0x04, 33 | 0x76, 0x31, 0x04, 0x76, 0x32, 0x04, 0x76, 0x33, 34 | 0x0c, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x02, 35 | 0x6d, 0x04, 0x6b, 0x30, 0x04, 0x6b, 0x31, 0x04, 36 | 0x6d, 0x6c, 0x06, 0x6d, 0x6c, 0x37, 0x06, 0x62, 37 | 0x75, 0x66, 0x04, 0x6d, 0x70, 0x04, 0x6d, 0x69, 38 | 0x04, 0x69, 0x63, 0x06, 0x6d, 0x69, 0x6c, 0x02, 39 | 0x72, 0x0e, 0x30, 0x30, 0x30, 0x30, 0x30, 0x30, 40 | 0x30, 0x0c, 0x73, 0x75, 0x62, 0x73, 0x74, 0x72, 41 | 0x06, 0x73, 0x74, 0x72, 0x0a, 0x62, 0x79, 0x74, 42 | 0x65, 0x73, 0x02, 0x6a, 0x16, 0x54, 0x65, 0x78, 43 | 0x74, 0x45, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x72, 44 | 0x0c, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x10, 45 | 0x75, 0x6e, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 46 | 0x24, 0x65, 0x6e, 0x63, 0x6f, 0x64, 0x65, 0x55, 47 | 0x52, 0x49, 0x43, 0x6f, 0x6d, 0x70, 0x6f, 0x6e, 48 | 0x65, 0x6e, 0x74, 0x14, 0x63, 0x68, 0x61, 0x72, 49 | 0x43, 0x6f, 0x64, 0x65, 0x41, 0x74, 0x04, 0x75, 50 | 0x38, 0x36, 0x4b, 0x65, 0x79, 0x20, 0x6c, 0x65, 51 | 0x6e, 0x67, 0x74, 0x68, 0x20, 0x6d, 0x75, 0x73, 52 | 0x74, 0x20, 0x62, 0x65, 0x20, 0x31, 0x36, 0x20, 53 | 0x62, 0x79, 0x74, 0x65, 0x73, 0x0e, 0x00, 0x06, 54 | 0x00, 0x9e, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 55 | 0x01, 0x9f, 0x02, 0x02, 0xa0, 0x01, 0x00, 0x00, 56 | 0x00, 0xb8, 0x03, 0x02, 0x00, 0x40, 0x40, 0xdd, 57 | 0x00, 0x00, 0x00, 0x00, 0x40, 0xde, 0x00, 0x00, 58 | 0x00, 0x00, 0x40, 0xdf, 0x00, 0x00, 0x00, 0x00, 59 | 0x40, 0xe0, 0x00, 0x00, 0x00, 0x80, 0x40, 0xe1, 60 | 0x00, 0x00, 0x00, 0x80, 0x3f, 0xdd, 0x00, 0x00, 61 | 0x00, 0x00, 0x3f, 0xde, 0x00, 0x00, 0x00, 0x00, 62 | 0x3f, 0xdf, 0x00, 0x00, 0x00, 0x00, 0x3f, 0xe0, 63 | 0x00, 0x00, 0x00, 0x82, 0x3f, 0xe1, 0x00, 0x00, 64 | 0x00, 0x82, 0xc2, 0x00, 0xf0, 0x11, 0x3a, 0xdd, 65 | 0x00, 0x00, 0x00, 0x0e, 0x39, 0xde, 0x00, 0x00, 66 | 0x00, 0x11, 0xed, 0x03, 0x0e, 0x0b, 0x11, 0x3a, 67 | 0xde, 0x00, 0x00, 0x00, 0x0e, 0x39, 0xde, 0x00, 68 | 0x00, 0x00, 0x39, 0xdd, 0x00, 0x00, 0x00, 0x15, 69 | 0x44, 0xdf, 0x00, 0x00, 0x00, 0x11, 0x3a, 0xdf, 70 | 0x00, 0x00, 0x00, 0x0e, 0x39, 0xdd, 0x00, 0x00, 71 | 0x00, 0x43, 0xe2, 0x00, 0x00, 0x00, 0x04, 0xe3, 72 | 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, 0x3b, 0xe0, 73 | 0x00, 0x00, 0x00, 0x0b, 0xb7, 0x4d, 0xe1, 0x00, 74 | 0x00, 0x00, 0xb7, 0x4d, 0xe4, 0x00, 0x00, 0x00, 75 | 0x3b, 0xe1, 0x00, 0x00, 0x00, 0x39, 0xe5, 0x00, 76 | 0x00, 0x00, 0x43, 0xe6, 0x00, 0x00, 0x00, 0x04, 77 | 0xe7, 0x00, 0x00, 0x00, 0x24, 0x01, 0x00, 0xcb, 78 | 0x06, 0xcb, 0x62, 0x01, 0x00, 0xb7, 0xcc, 0x63, 79 | 0x01, 0x00, 0x01, 0xe0, 0x93, 0x04, 0x00, 0xa5, 80 | 0xec, 0x4b, 0x39, 0xdd, 0x00, 0x00, 0x00, 0x43, 81 | 0xe8, 0x00, 0x00, 0x00, 0x39, 0xe0, 0x00, 0x00, 82 | 0x00, 0x04, 0x56, 0x00, 0x00, 0x00, 0x24, 0x02, 83 | 0x00, 0x11, 0x3a, 0xe1, 0x00, 0x00, 0x00, 0xcb, 84 | 0x39, 0xe0, 0x00, 0x00, 0x00, 0xb7, 0x72, 0x39, 85 | 0xe1, 0x00, 0x00, 0x00, 0xb7, 0x48, 0x16, 0x4a, 86 | 0xcb, 0x39, 0xe0, 0x00, 0x00, 0x00, 0xb8, 0x72, 87 | 0x39, 0xe1, 0x00, 0x00, 0x00, 0xb8, 0x48, 0x16, 88 | 0x4a, 0xcb, 0x63, 0x01, 0x00, 0x93, 0x64, 0x01, 89 | 0x00, 0x0e, 0xee, 0xac, 0x39, 0xe5, 0x00, 0x00, 90 | 0x00, 0x43, 0xe6, 0x00, 0x00, 0x00, 0x39, 0xe1, 91 | 0x00, 0x00, 0x00, 0x42, 0xe4, 0x00, 0x00, 0x00, 92 | 0x24, 0x01, 0x00, 0xcf, 0x28, 0xd2, 0x03, 0x01, 93 | 0x10, 0x97, 0x00, 0x1e, 0xe6, 0x02, 0x35, 0x58, 94 | 0x77, 0x76, 0x5d, 0x62, 0x5d, 0x99, 0x58, 0x58, 95 | 0x35, 0x0e, 0x43, 0x06, 0x01, 0x00, 0x00, 0x0b, 96 | 0x00, 0x02, 0x00, 0x0b, 0x4d, 0x0b, 0xd4, 0x03, 97 | 0x00, 0x00, 0x80, 0xd6, 0x03, 0x00, 0x01, 0x80, 98 | 0xd8, 0x03, 0x00, 0x02, 0x80, 0xda, 0x03, 0x00, 99 | 0x03, 0x80, 0xdc, 0x03, 0x00, 0x04, 0x80, 0xde, 100 | 0x03, 0x00, 0x05, 0x80, 0xd0, 0x03, 0x00, 0x06, 101 | 0x80, 0xe0, 0x03, 0x00, 0x07, 0x00, 0xe2, 0x03, 102 | 0x00, 0x08, 0x00, 0xe4, 0x03, 0x00, 0x09, 0x80, 103 | 0xc4, 0x03, 0x00, 0x0a, 0x00, 0xc2, 0x00, 0xcb, 104 | 0xc2, 0x01, 0xcc, 0xc2, 0x02, 0xcd, 0xc2, 0x03, 105 | 0xce, 0xc2, 0x04, 0xc5, 0x04, 0xc2, 0x05, 0xc5, 106 | 0x05, 0xc2, 0x06, 0xc5, 0x06, 0xc2, 0x07, 0xc5, 107 | 0x07, 0xc2, 0x08, 0xc5, 0x08, 0xc2, 0x09, 0xc5, 108 | 0x09, 0xc2, 0x0a, 0xc5, 0x0a, 0x0b, 0xc4, 0x06, 109 | 0x4d, 0xe8, 0x00, 0x00, 0x00, 0xc4, 0x07, 0x4d, 110 | 0xf0, 0x00, 0x00, 0x00, 0xc4, 0x08, 0x4d, 0xf1, 111 | 0x00, 0x00, 0x00, 0xc4, 0x0a, 0x4d, 0xe2, 0x00, 112 | 0x00, 0x00, 0xc4, 0x09, 0x4d, 0xf2, 0x00, 0x00, 113 | 0x00, 0x28, 0xd2, 0x03, 0x01, 0x0a, 0x00, 0x28, 114 | 0xd6, 0x02, 0x08, 0x26, 0x26, 0x26, 0x26, 0x26, 115 | 0x0e, 0x43, 0x06, 0x01, 0xd4, 0x03, 0x02, 0x02, 116 | 0x02, 0x04, 0x00, 0x00, 0x4c, 0x04, 0xe6, 0x03, 117 | 0x00, 0x01, 0x00, 0xe8, 0x03, 0x00, 0x01, 0x00, 118 | 0xea, 0x03, 0x00, 0x00, 0x00, 0xec, 0x03, 0x00, 119 | 0x01, 0x00, 0xd3, 0x42, 0xe4, 0x00, 0x00, 0x00, 120 | 0xd4, 0x42, 0xe4, 0x00, 0x00, 0x00, 0x9f, 0xcb, 121 | 0x0b, 0xd3, 0x42, 0xe1, 0x00, 0x00, 0x00, 0xd4, 122 | 0x42, 0xe1, 0x00, 0x00, 0x00, 0x9f, 0xc7, 0xb9, 123 | 0x9d, 0xbf, 0x1f, 0xa4, 0x9f, 0xb7, 0xa4, 0x4d, 124 | 0xe1, 0x00, 0x00, 0x00, 0xc7, 0xb7, 0xa4, 0x4d, 125 | 0xe4, 0x00, 0x00, 0x00, 0xcc, 0xd3, 0xc8, 0x42, 126 | 0xe1, 0x00, 0x00, 0x00, 0x44, 0xe1, 0x00, 0x00, 127 | 0x00, 0xd3, 0xc8, 0x42, 0xe4, 0x00, 0x00, 0x00, 128 | 0x44, 0xe4, 0x00, 0x00, 0x00, 0x29, 0xd2, 0x03, 129 | 0x03, 0x08, 0x03, 0x49, 0x08, 0x8a, 0x2b, 0x08, 130 | 0x3f, 0x3f, 0x0e, 0x43, 0x06, 0x01, 0xd6, 0x03, 131 | 0x02, 0x00, 0x02, 0x03, 0x00, 0x00, 0x3f, 0x02, 132 | 0xe6, 0x03, 0x00, 0x01, 0x00, 0xe8, 0x03, 0x00, 133 | 0x01, 0x00, 0xd3, 0x43, 0xe1, 0x00, 0x00, 0x00, 134 | 0xd4, 0x42, 0xe1, 0x00, 0x00, 0x00, 0xb0, 0x44, 135 | 0xe1, 0x00, 0x00, 0x00, 0xd3, 0x43, 0xe1, 0x00, 136 | 0x00, 0x00, 0xb7, 0xa4, 0x44, 0xe1, 0x00, 0x00, 137 | 0x00, 0xd3, 0x43, 0xe4, 0x00, 0x00, 0x00, 0xd4, 138 | 0x42, 0xe4, 0x00, 0x00, 0x00, 0xb0, 0x44, 0xe4, 139 | 0x00, 0x00, 0x00, 0xd3, 0x43, 0xe4, 0x00, 0x00, 140 | 0x00, 0xb7, 0xa4, 0x44, 0xe4, 0x00, 0x00, 0x00, 141 | 0x29, 0xd2, 0x03, 0x0c, 0x05, 0x03, 0x5d, 0x44, 142 | 0x5d, 0x44, 0x0e, 0x43, 0x06, 0x01, 0xd8, 0x03, 143 | 0x02, 0x01, 0x02, 0x05, 0x00, 0x00, 0x4d, 0x03, 144 | 0xe6, 0x03, 0x00, 0x01, 0x00, 0xee, 0x03, 0x00, 145 | 0x01, 0x00, 0xec, 0x03, 0x00, 0x00, 0x00, 0x0b, 146 | 0xd3, 0x42, 0xe1, 0x00, 0x00, 0x00, 0xd4, 0xa2, 147 | 0xd3, 0x42, 0xe4, 0x00, 0x00, 0x00, 0xbf, 0x20, 148 | 0xd4, 0xa0, 0xa4, 0xb1, 0x4d, 0xe1, 0x00, 0x00, 149 | 0x00, 0xd3, 0x42, 0xe4, 0x00, 0x00, 0x00, 0xd4, 150 | 0xa2, 0xd3, 0x42, 0xe1, 0x00, 0x00, 0x00, 0xbf, 151 | 0x20, 0xd4, 0xa0, 0xa4, 0xb1, 0x4d, 0xe4, 0x00, 152 | 0x00, 0x00, 0xcb, 0xd3, 0xc7, 0x42, 0xe1, 0x00, 153 | 0x00, 0x00, 0x44, 0xe1, 0x00, 0x00, 0x00, 0xd3, 154 | 0xc7, 0x42, 0xe4, 0x00, 0x00, 0x00, 0x44, 0xe4, 155 | 0x00, 0x00, 0x00, 0x29, 0xd2, 0x03, 0x12, 0x07, 156 | 0x03, 0x08, 0x80, 0x80, 0x08, 0x3f, 0x3f, 0x0e, 157 | 0x43, 0x06, 0x01, 0xda, 0x03, 0x01, 0x01, 0x01, 158 | 0x02, 0x00, 0x00, 0x1b, 0x02, 0xe6, 0x03, 0x00, 159 | 0x01, 0x00, 0xf0, 0x03, 0x00, 0x00, 0x00, 0xd3, 160 | 0x42, 0xe4, 0x00, 0x00, 0x00, 0xcb, 0xd3, 0xd3, 161 | 0x42, 0xe1, 0x00, 0x00, 0x00, 0x44, 0xe4, 0x00, 162 | 0x00, 0x00, 0xd3, 0xc7, 0x44, 0xe1, 0x00, 0x00, 163 | 0x00, 0x29, 0xd2, 0x03, 0x1a, 0x04, 0x03, 0x26, 164 | 0x3f, 0x26, 0x0e, 0x43, 0x06, 0x01, 0xdc, 0x03, 165 | 0x04, 0x00, 0x04, 0x03, 0x04, 0x00, 0x48, 0x04, 166 | 0xf2, 0x03, 0x00, 0x01, 0x00, 0xf4, 0x03, 0x00, 167 | 0x01, 0x00, 0xf6, 0x03, 0x00, 0x01, 0x00, 0xf8, 168 | 0x03, 0x00, 0x01, 0x00, 0xd4, 0x03, 0x00, 0x01, 169 | 0xd8, 0x03, 0x02, 0x01, 0xd6, 0x03, 0x01, 0x01, 170 | 0xda, 0x03, 0x03, 0x01, 0xdf, 0xd3, 0xd4, 0xf2, 171 | 0x0e, 0xdf, 0xd5, 0xd6, 0xf2, 0x0e, 0xe0, 0xd4, 172 | 0xbf, 0x0d, 0xf2, 0x0e, 0xe0, 0xd6, 0xbf, 0x10, 173 | 0xf2, 0x0e, 0xe1, 0xd4, 0xd3, 0xf2, 0x0e, 0xe1, 174 | 0xd6, 0xd5, 0xf2, 0x0e, 0xe2, 0xd3, 0xf1, 0x0e, 175 | 0xdf, 0xd5, 0xd4, 0xf2, 0x0e, 0xdf, 0xd3, 0xd6, 176 | 0xf2, 0x0e, 0xe0, 0xd4, 0xbf, 0x11, 0xf2, 0x0e, 177 | 0xe0, 0xd6, 0xbf, 0x15, 0xf2, 0x0e, 0xe1, 0xd4, 178 | 0xd5, 0xf2, 0x0e, 0xe1, 0xd6, 0xd3, 0xf2, 0x0e, 179 | 0xe2, 0xd5, 0xf1, 0x29, 0xd2, 0x03, 0x1f, 0x0f, 180 | 0x03, 0x1c, 0x1c, 0x21, 0x21, 0x1c, 0x1c, 0x17, 181 | 0x1c, 0x1c, 0x21, 0x21, 0x1c, 0x1c, 0x12, 0x0e, 182 | 0x43, 0x06, 0x01, 0xde, 0x03, 0x02, 0x00, 0x02, 183 | 0x04, 0x00, 0x00, 0x1f, 0x02, 0xe6, 0x03, 0x00, 184 | 0x01, 0x00, 0xfa, 0x03, 0x00, 0x01, 0x00, 0xd3, 185 | 0xd4, 0xba, 0x9f, 0x48, 0xbf, 0x18, 0xa2, 0xd3, 186 | 0xd4, 0xb9, 0x9f, 0x48, 0xbf, 0x10, 0xa2, 0xb1, 187 | 0xd3, 0xd4, 0xb8, 0x9f, 0x48, 0xbf, 0x08, 0xa2, 188 | 0xb1, 0xd3, 0xd4, 0x48, 0xb1, 0x28, 0xd2, 0x03, 189 | 0x2f, 0x05, 0x04, 0x2b, 0x30, 0x30, 0x17, 0x0e, 190 | 0x43, 0x06, 0x01, 0xd0, 0x03, 0x02, 0x0e, 0x02, 191 | 0x05, 0x04, 0x00, 0xb4, 0x04, 0x10, 0xc0, 0x03, 192 | 0x00, 0x01, 0x00, 0xfc, 0x03, 0x00, 0x01, 0x00, 193 | 0xfe, 0x03, 0x00, 0x00, 0x00, 0x80, 0x04, 0x00, 194 | 0x01, 0x00, 0xf2, 0x03, 0x00, 0x02, 0x00, 0xf6, 195 | 0x03, 0x00, 0x03, 0x00, 0xf4, 0x03, 0x00, 0x04, 196 | 0x00, 0xf8, 0x03, 0x00, 0x05, 0x00, 0x82, 0x04, 197 | 0x00, 0x06, 0x00, 0x84, 0x04, 0x00, 0x07, 0x00, 198 | 0x86, 0x04, 0x00, 0x08, 0x00, 0x88, 0x04, 0x00, 199 | 0x09, 0x00, 0x8a, 0x04, 0x00, 0x0a, 0x00, 0x8c, 200 | 0x04, 0x00, 0x0b, 0x00, 0x8e, 0x04, 0x00, 0x0c, 201 | 0x00, 0xc2, 0x03, 0x00, 0x0d, 0x00, 0xe4, 0x03, 202 | 0x09, 0x01, 0xd6, 0x03, 0x01, 0x01, 0xde, 0x03, 203 | 0x05, 0x01, 0xdc, 0x03, 0x04, 0x01, 0xd4, 0x99, 204 | 0x04, 0x47, 0x00, 0x00, 0x00, 0xad, 0xec, 0x05, 205 | 0xdf, 0xd4, 0xf1, 0xd8, 0x0b, 0xd3, 0xb8, 0x48, 206 | 0xb7, 0xa4, 0x4d, 0xe1, 0x00, 0x00, 0x00, 0xd3, 207 | 0xb7, 0x48, 0xb7, 0xa4, 0x4d, 0xe4, 0x00, 0x00, 208 | 0x00, 0xcb, 0x0b, 0xd3, 0xba, 0x48, 0xb7, 0xa4, 209 | 0x4d, 0xe1, 0x00, 0x00, 0x00, 0xd3, 0xb9, 0x48, 210 | 0xb7, 0xa4, 0x4d, 0xe4, 0x00, 0x00, 0x00, 0xcc, 211 | 0x0b, 0xc7, 0x42, 0xe1, 0x00, 0x00, 0x00, 0x4d, 212 | 0xe1, 0x00, 0x00, 0x00, 0xc7, 0x42, 0xe4, 0x00, 213 | 0x00, 0x00, 0x4d, 0xe4, 0x00, 0x00, 0x00, 0xcd, 214 | 0xc7, 0xce, 0x0b, 0xc8, 0x42, 0xe1, 0x00, 0x00, 215 | 0x00, 0x4d, 0xe1, 0x00, 0x00, 0x00, 0xc8, 0x42, 216 | 0xe4, 0x00, 0x00, 0x00, 0x4d, 0xe4, 0x00, 0x00, 217 | 0x00, 0xc5, 0x04, 0xc8, 0xc5, 0x05, 0xd4, 0xeb, 218 | 0xc6, 0x06, 0xbe, 0xa0, 0xc5, 0x07, 0x39, 0xa3, 219 | 0x00, 0x00, 0x00, 0x11, 0x39, 0x9f, 0x00, 0x00, 220 | 0x00, 0x11, 0xbf, 0x08, 0x21, 0x01, 0x00, 0x21, 221 | 0x01, 0x00, 0xc5, 0x08, 0xe0, 0xc9, 0x0b, 0x01, 222 | 0x65, 0x6d, 0x6f, 0x73, 0x4d, 0xe1, 0x00, 0x00, 223 | 0x00, 0x01, 0x75, 0x65, 0x73, 0x70, 0x4d, 0xe4, 224 | 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xe0, 0xc4, 0x04, 225 | 0x0b, 0x01, 0x61, 0x72, 0x6f, 0x64, 0x4d, 0xe1, 226 | 0x00, 0x00, 0x00, 0x01, 0x6d, 0x6f, 0x64, 0x6e, 227 | 0x4d, 0xe4, 0x00, 0x00, 0x00, 0xf2, 0x0e, 0xe0, 228 | 0xca, 0x0b, 0x01, 0x65, 0x67, 0x79, 0x6c, 0x4d, 229 | 0xe1, 0x00, 0x00, 0x00, 0x01, 0x61, 0x72, 0x65, 230 | 0x6e, 0x4d, 0xe4, 0x00, 0x00, 0x00, 0xf2, 0x0e, 231 | 0xe0, 0xc4, 0x05, 0x0b, 0x01, 0x62, 0x64, 0x65, 232 | 0x74, 0x4d, 0xe1, 0x00, 0x00, 0x00, 0x01, 0x73, 233 | 0x65, 0x74, 0x79, 0x4d, 0xe4, 0x00, 0x00, 0x00, 234 | 0xf2, 0x0e, 0xb7, 0xc5, 0x09, 0xc4, 0x09, 0xc4, 235 | 0x07, 0xa5, 0xec, 0x43, 0x0b, 0xe1, 0xd4, 0xc4, 236 | 0x09, 0xbb, 0x9f, 0xf2, 0x4d, 0xe1, 0x00, 0x00, 237 | 0x00, 0xe1, 0xd4, 0xc4, 0x09, 0xf2, 0x4d, 0xe4, 238 | 0x00, 0x00, 0x00, 0xc5, 0x0a, 0xe0, 0xc4, 0x05, 239 | 0xc4, 0x0a, 0xf2, 0x0e, 0xe2, 0xc9, 0xc4, 0x04, 240 | 0xca, 0xc4, 0x05, 0x22, 0x04, 0x00, 0x0e, 0xe2, 241 | 0xc9, 0xc4, 0x04, 0xca, 0xc4, 0x05, 0x22, 0x04, 242 | 0x00, 0x0e, 0xe0, 0xc9, 0xc4, 0x0a, 0xf2, 0x0e, 243 | 0xbf, 0x08, 0x96, 0x09, 0xee, 0xb8, 0xc4, 0x08, 244 | 0xbe, 0xc4, 0x06, 0x4a, 0xb7, 0xc5, 0x0b, 0xc4, 245 | 0x09, 0xc4, 0x06, 0xa5, 0xec, 0x13, 0xc4, 0x08, 246 | 0xc4, 0x0b, 0x93, 0xc5, 0x0b, 0x72, 0xd4, 0xc4, 247 | 0x09, 0x93, 0xc5, 0x09, 0x48, 0x4a, 0xee, 0xe8, 248 | 0xc4, 0x0b, 0xbe, 0xa5, 0xec, 0x0c, 0xc4, 0x08, 249 | 0xc4, 0x0b, 0x93, 0xc5, 0x0b, 0xb7, 0x4a, 0xee, 250 | 0xf0, 0x0b, 0xc4, 0x08, 0xbe, 0x48, 0xbf, 0x18, 251 | 0xa2, 0xc4, 0x08, 0xbd, 0x48, 0xbf, 0x10, 0xa2, 252 | 0xb1, 0xc4, 0x08, 0xbc, 0x48, 0xbf, 0x08, 0xa2, 253 | 0xb1, 0xc4, 0x08, 0xbb, 0x48, 0xb1, 0x4d, 0xe1, 254 | 0x00, 0x00, 0x00, 0xc4, 0x08, 0xba, 0x48, 0xbf, 255 | 0x18, 0xa2, 0xc4, 0x08, 0xb9, 0x48, 0xbf, 0x10, 256 | 0xa2, 0xb1, 0xc4, 0x08, 0xb8, 0x48, 0xbf, 0x08, 257 | 0xa2, 0xb1, 0xc4, 0x08, 0xb7, 0x48, 0xb1, 0x4d, 258 | 0xe4, 0x00, 0x00, 0x00, 0xc5, 0x0c, 0xe0, 0xc4, 259 | 0x05, 0xc4, 0x0c, 0xf2, 0x0e, 0xe2, 0xc9, 0xc4, 260 | 0x04, 0xca, 0xc4, 0x05, 0x22, 0x04, 0x00, 0x0e, 261 | 0xe2, 0xc9, 0xc4, 0x04, 0xca, 0xc4, 0x05, 0x22, 262 | 0x04, 0x00, 0x0e, 0xe0, 0xc9, 0xc4, 0x0c, 0xf2, 263 | 0x0e, 0xe0, 0xca, 0x0b, 0xb7, 0x4d, 0xe1, 0x00, 264 | 0x00, 0x00, 0xc0, 0xff, 0x00, 0x4d, 0xe4, 0x00, 265 | 0x00, 0x00, 0xf2, 0x0e, 0xe2, 0xc9, 0xc4, 0x04, 266 | 0xca, 0xc4, 0x05, 0x22, 0x04, 0x00, 0x0e, 0xe2, 267 | 0xc9, 0xc4, 0x04, 0xca, 0xc4, 0x05, 0x22, 0x04, 268 | 0x00, 0x0e, 0xe2, 0xc9, 0xc4, 0x04, 0xca, 0xc4, 269 | 0x05, 0x22, 0x04, 0x00, 0x0e, 0xe2, 0xc9, 0xc4, 270 | 0x04, 0xca, 0xc4, 0x05, 0x22, 0x04, 0x00, 0x0e, 271 | 0xc9, 0xc5, 0x0d, 0xe0, 0xc4, 0x0d, 0xc4, 0x04, 272 | 0xf2, 0x0e, 0xe0, 0xc4, 0x0d, 0xca, 0xf2, 0x0e, 273 | 0xe0, 0xc4, 0x0d, 0xc4, 0x05, 0xf2, 0x0e, 0xc4, 274 | 0x0d, 0x28, 0xd2, 0x03, 0x37, 0x50, 0x03, 0x35, 275 | 0x18, 0x08, 0x35, 0x35, 0x08, 0x08, 0x35, 0x35, 276 | 0x08, 0x08, 0x3a, 0x3a, 0x08, 0x0d, 0x08, 0x3a, 277 | 0x3a, 0x0d, 0x12, 0x17, 0x17, 0x71, 0x12, 0x35, 278 | 0x35, 0x0d, 0x17, 0x35, 0x35, 0x0d, 0x12, 0x35, 279 | 0x35, 0x0d, 0x17, 0x35, 0x35, 0x0d, 0x12, 0x26, 280 | 0x08, 0x3f, 0x35, 0x0d, 0x26, 0x3a, 0x3a, 0x21, 281 | 0x17, 0x0d, 0x21, 0x12, 0x26, 0x53, 0x0d, 0x21, 282 | 0x30, 0x0d, 0x08, 0xa8, 0xa8, 0x0d, 0x26, 0x3a, 283 | 0x3a, 0x21, 0x12, 0x21, 0x2b, 0x0d, 0x3a, 0x3a, 284 | 0x3a, 0x3a, 0x12, 0x26, 0x21, 0x26, 0x0e, 0x43, 285 | 0x06, 0x01, 0xe0, 0x03, 0x02, 0x01, 0x02, 0x05, 286 | 0x01, 0x00, 0x47, 0x03, 0xc0, 0x03, 0x00, 0x01, 287 | 0x00, 0xfc, 0x03, 0x00, 0x01, 0x00, 0x90, 0x04, 288 | 0x00, 0x00, 0x00, 0xd0, 0x03, 0x06, 0x01, 0xdf, 289 | 0xd3, 0xd4, 0xf2, 0xcb, 0x04, 0x09, 0x01, 0x00, 290 | 0x00, 0xc7, 0x42, 0xe1, 0x00, 0x00, 0x00, 0x43, 291 | 0x36, 0x00, 0x00, 0x00, 0xbf, 0x10, 0x24, 0x01, 292 | 0x00, 0x9f, 0x43, 0x0a, 0x01, 0x00, 0x00, 0xbf, 293 | 0xf8, 0x24, 0x01, 0x00, 0x04, 0x09, 0x01, 0x00, 294 | 0x00, 0xc7, 0x42, 0xe4, 0x00, 0x00, 0x00, 0x43, 295 | 0x36, 0x00, 0x00, 0x00, 0xbf, 0x10, 0x24, 0x01, 296 | 0x00, 0x9f, 0x43, 0x0a, 0x01, 0x00, 0x00, 0xbf, 297 | 0xf8, 0x24, 0x01, 0x00, 0x9f, 0x28, 0xd2, 0x03, 298 | 0x8a, 0x01, 0x04, 0x03, 0x1d, 0xa3, 0xa8, 0x0e, 299 | 0x43, 0x06, 0x01, 0xe2, 0x03, 0x02, 0x01, 0x02, 300 | 0x03, 0x01, 0x00, 0x1e, 0x03, 0xc0, 0x03, 0x00, 301 | 0x01, 0x00, 0xfc, 0x03, 0x00, 0x01, 0x00, 0x90, 302 | 0x04, 0x00, 0x00, 0x00, 0xd0, 0x03, 0x06, 0x01, 303 | 0xdf, 0xd3, 0xd4, 0xf2, 0xcf, 0x42, 0xe1, 0x00, 304 | 0x00, 0x00, 0x01, 0xff, 0xff, 0x1f, 0x00, 0xaf, 305 | 0x01, 0x00, 0x00, 0x00, 0x80, 0x9c, 0xc7, 0x42, 306 | 0xe4, 0x00, 0x00, 0x00, 0x9f, 0x28, 0xd2, 0x03, 307 | 0x91, 0x01, 0x02, 0x03, 0x1c, 0x0e, 0x43, 0x06, 308 | 0x01, 0xe4, 0x03, 0x01, 0x03, 0x01, 0x05, 0x00, 309 | 0x00, 0x52, 0x04, 0x96, 0x04, 0x00, 0x01, 0x00, 310 | 0x98, 0x04, 0x00, 0x00, 0x00, 0xb8, 0x03, 0x00, 311 | 0x01, 0x00, 0x9a, 0x04, 0x00, 0x02, 0x00, 0x38, 312 | 0x0e, 0x01, 0x00, 0x00, 0xf6, 0xec, 0x13, 0x39, 313 | 0x0e, 0x01, 0x00, 0x00, 0x11, 0x21, 0x00, 0x00, 314 | 0x43, 0x0f, 0x01, 0x00, 0x00, 0xd3, 0x25, 0x01, 315 | 0x00, 0x39, 0x10, 0x01, 0x00, 0x00, 0x39, 0x11, 316 | 0x01, 0x00, 0x00, 0xd3, 0xf1, 0xf1, 0xd7, 0x39, 317 | 0xa3, 0x00, 0x00, 0x00, 0x11, 0xd3, 0xeb, 0x21, 318 | 0x01, 0x00, 0xcb, 0xb7, 0xcc, 0xd3, 0xeb, 0xcd, 319 | 0xc8, 0xc9, 0xa5, 0xec, 0x13, 0xc7, 0xc8, 0x72, 320 | 0xd3, 0x43, 0x12, 0x01, 0x00, 0x00, 0xc8, 0x24, 321 | 0x01, 0x00, 0x4a, 0x95, 0x01, 0xee, 0xea, 0xc7, 322 | 0x28, 0xd2, 0x03, 0x95, 0x01, 0x08, 0x03, 0x2b, 323 | 0x5e, 0x49, 0x3f, 0x35, 0x49, 0x17, 0x0e, 0x43, 324 | 0x06, 0x01, 0xc4, 0x03, 0x01, 0x02, 0x01, 0x05, 325 | 0x02, 0x00, 0x44, 0x03, 0x96, 0x04, 0x00, 0x01, 326 | 0x00, 0xa6, 0x04, 0x00, 0x00, 0x00, 0xc0, 0x03, 327 | 0x00, 0x01, 0x00, 0xe4, 0x03, 0x09, 0x01, 0xde, 328 | 0x03, 0x05, 0x01, 0xdf, 0xd3, 0xf1, 0xcf, 0xeb, 329 | 0xbf, 0x10, 0xae, 0xec, 0x0d, 0x39, 0x92, 0x00, 330 | 0x00, 0x00, 0x04, 0x14, 0x01, 0x00, 0x00, 0xf1, 331 | 0x2f, 0x39, 0xa7, 0x00, 0x00, 0x00, 0x11, 0xbb, 332 | 0x21, 0x01, 0x00, 0xd0, 0xb7, 0x72, 0xe0, 0xc7, 333 | 0xb7, 0xf2, 0x4a, 0xc8, 0xb8, 0x72, 0xe0, 0xc7, 334 | 0xbb, 0xf2, 0x4a, 0xc8, 0xb9, 0x72, 0xe0, 0xc7, 335 | 0xbf, 0x08, 0xf2, 0x4a, 0xc8, 0xba, 0x72, 0xe0, 336 | 0xc7, 0xbf, 0x0c, 0xf2, 0x4a, 0xc8, 0x28, 0xd2, 337 | 0x03, 0xa0, 0x01, 0x0a, 0x03, 0x17, 0x21, 0x3a, 338 | 0x08, 0x3a, 0x26, 0x2b, 0x30, 0x30, 339 | }; 340 | 341 | int main(int argc, char **argv) 342 | { 343 | JSRuntime *rt; 344 | JSContext *ctx; 345 | rt = JS_NewRuntime(); 346 | ctx = JS_NewContextRaw(rt); 347 | JS_AddIntrinsicBaseObjects(ctx); 348 | JS_AddIntrinsicDate(ctx); 349 | JS_AddIntrinsicStringNormalize(ctx); 350 | JS_AddIntrinsicRegExp(ctx); 351 | JS_AddIntrinsicJSON(ctx); 352 | JS_AddIntrinsicMapSet(ctx); 353 | JS_AddIntrinsicTypedArrays(ctx); 354 | JS_AddIntrinsicPromise(ctx); 355 | js_std_add_helpers(ctx, argc, argv); 356 | js_std_eval_binary(ctx, qjsc_test, qjsc_test_size, 0); 357 | js_std_loop(ctx); 358 | JS_FreeContext(ctx); 359 | JS_FreeRuntime(rt); 360 | return 0; 361 | } 362 | -------------------------------------------------------------------------------- /bench/test.js: -------------------------------------------------------------------------------- 1 | var SipHash = (function() { 2 | "use strict"; 3 | function _add(a, b) { 4 | var rl = a.l + b.l, 5 | a2 = { 6 | h: (a.h + b.h + ((rl / 2) >>> 31)) >>> 0, 7 | l: rl >>> 0 8 | }; 9 | a.h = a2.h; 10 | a.l = a2.l; 11 | } 12 | function _xor(a, b) { 13 | a.h ^= b.h; 14 | a.h >>>= 0; 15 | a.l ^= b.l; 16 | a.l >>>= 0; 17 | } 18 | function _rotl(a, n) { 19 | var a2 = { 20 | h: (a.h << n) | (a.l >>> (32 - n)), 21 | l: (a.l << n) | (a.h >>> (32 - n)) 22 | }; 23 | a.h = a2.h; 24 | a.l = a2.l; 25 | } 26 | function _rotl32(a) { 27 | var al = a.l; 28 | a.l = a.h; 29 | a.h = al; 30 | } 31 | function _compress(v0, v1, v2, v3) { 32 | _add(v0, v1); 33 | _add(v2, v3); 34 | _rotl(v1, 13); 35 | _rotl(v3, 16); 36 | _xor(v1, v0); 37 | _xor(v3, v2); 38 | _rotl32(v0); 39 | _add(v2, v1); 40 | _add(v0, v3); 41 | _rotl(v1, 17); 42 | _rotl(v3, 21); 43 | _xor(v1, v2); 44 | _xor(v3, v0); 45 | _rotl32(v2); 46 | } 47 | function _get_int(a, offset) { 48 | return ( 49 | (a[offset + 3] << 24) | 50 | (a[offset + 2] << 16) | 51 | (a[offset + 1] << 8) | 52 | a[offset] 53 | ); 54 | } 55 | function hash(key, m) { 56 | if (typeof m === "string") { 57 | m = string_to_u8(m); 58 | } 59 | var k0 = { 60 | h: key[1] >>> 0, 61 | l: key[0] >>> 0 62 | }, 63 | k1 = { 64 | h: key[3] >>> 0, 65 | l: key[2] >>> 0 66 | }, 67 | v0 = { 68 | h: k0.h, 69 | l: k0.l 70 | }, 71 | v2 = k0, 72 | v1 = { 73 | h: k1.h, 74 | l: k1.l 75 | }, 76 | v3 = k1, 77 | ml = m.length, 78 | ml7 = ml - 7, 79 | buf = new Uint8Array(new ArrayBuffer(8)); 80 | _xor(v0, { 81 | h: 0x736f6d65, 82 | l: 0x70736575 83 | }); 84 | _xor(v1, { 85 | h: 0x646f7261, 86 | l: 0x6e646f6d 87 | }); 88 | _xor(v2, { 89 | h: 0x6c796765, 90 | l: 0x6e657261 91 | }); 92 | _xor(v3, { 93 | h: 0x74656462, 94 | l: 0x79746573 95 | }); 96 | var mp = 0; 97 | while (mp < ml7) { 98 | var mi = { 99 | h: _get_int(m, mp + 4), 100 | l: _get_int(m, mp) 101 | }; 102 | _xor(v3, mi); 103 | _compress(v0, v1, v2, v3); 104 | _compress(v0, v1, v2, v3); 105 | _xor(v0, mi); 106 | mp += 8; 107 | } 108 | buf[7] = ml; 109 | var ic = 0; 110 | while (mp < ml) { 111 | buf[ic++] = m[mp++]; 112 | } 113 | while (ic < 7) { 114 | buf[ic++] = 0; 115 | } 116 | var mil = { 117 | h: (buf[7] << 24) | (buf[6] << 16) | (buf[5] << 8) | buf[4], 118 | l: (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0] 119 | }; 120 | _xor(v3, mil); 121 | _compress(v0, v1, v2, v3); 122 | _compress(v0, v1, v2, v3); 123 | _xor(v0, mil); 124 | _xor(v2, { 125 | h: 0, 126 | l: 0xff 127 | }); 128 | _compress(v0, v1, v2, v3); 129 | _compress(v0, v1, v2, v3); 130 | _compress(v0, v1, v2, v3); 131 | _compress(v0, v1, v2, v3); 132 | var h = v0; 133 | _xor(h, v1); 134 | _xor(h, v2); 135 | _xor(h, v3); 136 | return h; 137 | } 138 | function hash_hex(key, m) { 139 | var r = hash(key, m); 140 | return ( 141 | ("0000000" + r.h.toString(16)).substr(-8) + 142 | ("0000000" + r.l.toString(16)).substr(-8) 143 | ); 144 | } 145 | function hash_uint(key, m) { 146 | var r = hash(key, m); 147 | return (r.h & 0x1fffff) * 0x100000000 + r.l; 148 | } 149 | function string_to_u8(str) { 150 | if (typeof TextEncoder === "function") { 151 | return new TextEncoder().encode(str); 152 | } 153 | str = unescape(encodeURIComponent(str)); 154 | var bytes = new Uint8Array(str.length); 155 | for (var i = 0, j = str.length; i < j; i++) { 156 | bytes[i] = str.charCodeAt(i); 157 | } 158 | return bytes; 159 | } 160 | function string16_to_key(str) { 161 | var u8 = string_to_u8(str); 162 | if (u8.length !== 16) { 163 | throw Error("Key length must be 16 bytes"); 164 | } 165 | var key = new Uint32Array(4); 166 | key[0] = _get_int(u8, 0); 167 | key[1] = _get_int(u8, 4); 168 | key[2] = _get_int(u8, 8); 169 | key[3] = _get_int(u8, 12); 170 | return key; 171 | } 172 | return { 173 | hash: hash, 174 | hash_hex: hash_hex, 175 | hash_uint: hash_uint, 176 | string16_to_key: string16_to_key, 177 | string_to_u8: string_to_u8 178 | }; 179 | })(); 180 | var module = module || {}, 181 | exports = (module.exports = SipHash); 182 | 183 | let key = SipHash.string16_to_key("0123456789abcdef"); 184 | let h = { h: 0, l: 0 }; 185 | console.log("Computing..."); 186 | for (let i = 0; i < 300000; i++) { 187 | h = SipHash.hash(key, "input"); 188 | key[0] = h[0]; 189 | key[1] = h[1]; 190 | } 191 | console.log(h.l); 192 | -------------------------------------------------------------------------------- /bench/test.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/quickjs-wasi/84589b6f6d1ff9752286cbab24bac24245b31d97/bench/test.wasm -------------------------------------------------------------------------------- /build_wasi.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | wasicc libunicode.c cutils.c libbf.c libregexp.c quickjs.c quickjs-libc.c qjs.c repl.c qjscalc.c -DCONFIG_VERSION='"wasi"' -D_WASI_EMULATED_SIGNAL -DCONFIG_BIGNUM=y -lwasi-emulated-signal -O3 -o qjs.wasm -------------------------------------------------------------------------------- /cutils.h: -------------------------------------------------------------------------------- 1 | /* 2 | * C utilities 3 | * 4 | * Copyright (c) 2017 Fabrice Bellard 5 | * Copyright (c) 2018 Charlie Gordon 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | #ifndef CUTILS_H 26 | #define CUTILS_H 27 | 28 | #include 29 | #include 30 | 31 | /* set if CPU is big endian */ 32 | #undef WORDS_BIGENDIAN 33 | 34 | #define likely(x) __builtin_expect(!!(x), 1) 35 | #define unlikely(x) __builtin_expect(!!(x), 0) 36 | #define force_inline inline __attribute__((always_inline)) 37 | #define no_inline __attribute__((noinline)) 38 | #define __maybe_unused __attribute__((unused)) 39 | 40 | #define xglue(x, y) x ## y 41 | #define glue(x, y) xglue(x, y) 42 | #define stringify(s) tostring(s) 43 | #define tostring(s) #s 44 | 45 | #ifndef offsetof 46 | #define offsetof(type, field) ((size_t) &((type *)0)->field) 47 | #endif 48 | #ifndef countof 49 | #define countof(x) (sizeof(x) / sizeof((x)[0])) 50 | #endif 51 | 52 | /* return the pointer of type 'type *' containing 'ptr' as field 'member' */ 53 | #define container_of(ptr, type, member) ((type *)((uint8_t *)(ptr) - offsetof(type, member))) 54 | 55 | typedef int BOOL; 56 | 57 | #ifndef FALSE 58 | enum { 59 | FALSE = 0, 60 | TRUE = 1, 61 | }; 62 | #endif 63 | 64 | void pstrcpy(char *buf, int buf_size, const char *str); 65 | char *pstrcat(char *buf, int buf_size, const char *s); 66 | int strstart(const char *str, const char *val, const char **ptr); 67 | int has_suffix(const char *str, const char *suffix); 68 | 69 | static inline int max_int(int a, int b) 70 | { 71 | if (a > b) 72 | return a; 73 | else 74 | return b; 75 | } 76 | 77 | static inline int min_int(int a, int b) 78 | { 79 | if (a < b) 80 | return a; 81 | else 82 | return b; 83 | } 84 | 85 | static inline uint32_t max_uint32(uint32_t a, uint32_t b) 86 | { 87 | if (a > b) 88 | return a; 89 | else 90 | return b; 91 | } 92 | 93 | static inline uint32_t min_uint32(uint32_t a, uint32_t b) 94 | { 95 | if (a < b) 96 | return a; 97 | else 98 | return b; 99 | } 100 | 101 | static inline int64_t max_int64(int64_t a, int64_t b) 102 | { 103 | if (a > b) 104 | return a; 105 | else 106 | return b; 107 | } 108 | 109 | static inline int64_t min_int64(int64_t a, int64_t b) 110 | { 111 | if (a < b) 112 | return a; 113 | else 114 | return b; 115 | } 116 | 117 | /* WARNING: undefined if a = 0 */ 118 | static inline int clz32(unsigned int a) 119 | { 120 | return __builtin_clz(a); 121 | } 122 | 123 | /* WARNING: undefined if a = 0 */ 124 | static inline int clz64(uint64_t a) 125 | { 126 | return __builtin_clzll(a); 127 | } 128 | 129 | /* WARNING: undefined if a = 0 */ 130 | static inline int ctz32(unsigned int a) 131 | { 132 | return __builtin_ctz(a); 133 | } 134 | 135 | /* WARNING: undefined if a = 0 */ 136 | static inline int ctz64(uint64_t a) 137 | { 138 | return __builtin_ctzll(a); 139 | } 140 | 141 | struct __attribute__((packed)) packed_u64 { 142 | uint64_t v; 143 | }; 144 | 145 | struct __attribute__((packed)) packed_u32 { 146 | uint32_t v; 147 | }; 148 | 149 | struct __attribute__((packed)) packed_u16 { 150 | uint16_t v; 151 | }; 152 | 153 | static inline uint64_t get_u64(const uint8_t *tab) 154 | { 155 | return ((const struct packed_u64 *)tab)->v; 156 | } 157 | 158 | static inline int64_t get_i64(const uint8_t *tab) 159 | { 160 | return (int64_t)((const struct packed_u64 *)tab)->v; 161 | } 162 | 163 | static inline void put_u64(uint8_t *tab, uint64_t val) 164 | { 165 | ((struct packed_u64 *)tab)->v = val; 166 | } 167 | 168 | static inline uint32_t get_u32(const uint8_t *tab) 169 | { 170 | return ((const struct packed_u32 *)tab)->v; 171 | } 172 | 173 | static inline int32_t get_i32(const uint8_t *tab) 174 | { 175 | return (int32_t)((const struct packed_u32 *)tab)->v; 176 | } 177 | 178 | static inline void put_u32(uint8_t *tab, uint32_t val) 179 | { 180 | ((struct packed_u32 *)tab)->v = val; 181 | } 182 | 183 | static inline uint32_t get_u16(const uint8_t *tab) 184 | { 185 | return ((const struct packed_u16 *)tab)->v; 186 | } 187 | 188 | static inline int32_t get_i16(const uint8_t *tab) 189 | { 190 | return (int16_t)((const struct packed_u16 *)tab)->v; 191 | } 192 | 193 | static inline void put_u16(uint8_t *tab, uint16_t val) 194 | { 195 | ((struct packed_u16 *)tab)->v = val; 196 | } 197 | 198 | static inline uint32_t get_u8(const uint8_t *tab) 199 | { 200 | return *tab; 201 | } 202 | 203 | static inline int32_t get_i8(const uint8_t *tab) 204 | { 205 | return (int8_t)*tab; 206 | } 207 | 208 | static inline void put_u8(uint8_t *tab, uint8_t val) 209 | { 210 | *tab = val; 211 | } 212 | 213 | static inline uint16_t bswap16(uint16_t x) 214 | { 215 | return (x >> 8) | (x << 8); 216 | } 217 | 218 | static inline uint32_t bswap32(uint32_t v) 219 | { 220 | return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) | 221 | ((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24); 222 | } 223 | 224 | static inline uint64_t bswap64(uint64_t v) 225 | { 226 | return ((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) | 227 | ((v & ((uint64_t)0xff << (6 * 8))) >> (5 * 8)) | 228 | ((v & ((uint64_t)0xff << (5 * 8))) >> (3 * 8)) | 229 | ((v & ((uint64_t)0xff << (4 * 8))) >> (1 * 8)) | 230 | ((v & ((uint64_t)0xff << (3 * 8))) << (1 * 8)) | 231 | ((v & ((uint64_t)0xff << (2 * 8))) << (3 * 8)) | 232 | ((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) | 233 | ((v & ((uint64_t)0xff << (0 * 8))) << (7 * 8)); 234 | } 235 | 236 | /* XXX: should take an extra argument to pass slack information to the caller */ 237 | typedef void *DynBufReallocFunc(void *opaque, void *ptr, size_t size); 238 | 239 | typedef struct DynBuf { 240 | uint8_t *buf; 241 | size_t size; 242 | size_t allocated_size; 243 | BOOL error; /* true if a memory allocation error occurred */ 244 | DynBufReallocFunc *realloc_func; 245 | void *opaque; /* for realloc_func */ 246 | } DynBuf; 247 | 248 | void dbuf_init(DynBuf *s); 249 | void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func); 250 | int dbuf_realloc(DynBuf *s, size_t new_size); 251 | int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len); 252 | int dbuf_put(DynBuf *s, const uint8_t *data, size_t len); 253 | int dbuf_put_self(DynBuf *s, size_t offset, size_t len); 254 | int dbuf_putc(DynBuf *s, uint8_t c); 255 | int dbuf_putstr(DynBuf *s, const char *str); 256 | static inline int dbuf_put_u16(DynBuf *s, uint16_t val) 257 | { 258 | return dbuf_put(s, (uint8_t *)&val, 2); 259 | } 260 | static inline int dbuf_put_u32(DynBuf *s, uint32_t val) 261 | { 262 | return dbuf_put(s, (uint8_t *)&val, 4); 263 | } 264 | static inline int dbuf_put_u64(DynBuf *s, uint64_t val) 265 | { 266 | return dbuf_put(s, (uint8_t *)&val, 8); 267 | } 268 | int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s, 269 | const char *fmt, ...); 270 | void dbuf_free(DynBuf *s); 271 | static inline BOOL dbuf_error(DynBuf *s) { 272 | return s->error; 273 | } 274 | static inline void dbuf_set_error(DynBuf *s) 275 | { 276 | s->error = TRUE; 277 | } 278 | 279 | #define UTF8_CHAR_LEN_MAX 6 280 | 281 | int unicode_to_utf8(uint8_t *buf, unsigned int c); 282 | int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp); 283 | 284 | static inline int from_hex(int c) 285 | { 286 | if (c >= '0' && c <= '9') 287 | return c - '0'; 288 | else if (c >= 'A' && c <= 'F') 289 | return c - 'A' + 10; 290 | else if (c >= 'a' && c <= 'f') 291 | return c - 'a' + 10; 292 | else 293 | return -1; 294 | } 295 | 296 | void rqsort(void *base, size_t nmemb, size_t size, 297 | int (*cmp)(const void *, const void *, void *), 298 | void *arg); 299 | 300 | #endif /* CUTILS_H */ 301 | -------------------------------------------------------------------------------- /examples/fib.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS: Example of C module 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include "../quickjs.h" 25 | 26 | #define countof(x) (sizeof(x) / sizeof((x)[0])) 27 | 28 | static int fib(int n) 29 | { 30 | if (n <= 0) 31 | return 0; 32 | else if (n == 1) 33 | return 1; 34 | else 35 | return fib(n - 1) + fib(n - 2); 36 | } 37 | 38 | static JSValue js_fib(JSContext *ctx, JSValueConst this_val, 39 | int argc, JSValueConst *argv) 40 | { 41 | int n, res; 42 | if (JS_ToInt32(ctx, &n, argv[0])) 43 | return JS_EXCEPTION; 44 | res = fib(n); 45 | return JS_NewInt32(ctx, res); 46 | } 47 | 48 | static const JSCFunctionListEntry js_fib_funcs[] = { 49 | JS_CFUNC_DEF("fib", 1, js_fib ), 50 | }; 51 | 52 | static int js_fib_init(JSContext *ctx, JSModuleDef *m) 53 | { 54 | return JS_SetModuleExportList(ctx, m, js_fib_funcs, 55 | countof(js_fib_funcs)); 56 | } 57 | 58 | #ifdef JS_SHARED_LIBRARY 59 | #define JS_INIT_MODULE js_init_module 60 | #else 61 | #define JS_INIT_MODULE js_init_module_fib 62 | #endif 63 | 64 | JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name) 65 | { 66 | JSModuleDef *m; 67 | m = JS_NewCModule(ctx, module_name, js_fib_init); 68 | if (!m) 69 | return NULL; 70 | JS_AddModuleExportList(ctx, m, js_fib_funcs, countof(js_fib_funcs)); 71 | return m; 72 | } 73 | -------------------------------------------------------------------------------- /examples/fib_module.js: -------------------------------------------------------------------------------- 1 | /* fib module */ 2 | export function fib(n) 3 | { 4 | if (n <= 0) 5 | return 0; 6 | else if (n == 1) 7 | return 1; 8 | else 9 | return fib(n - 1) + fib(n - 2); 10 | } 11 | -------------------------------------------------------------------------------- /examples/hello.js: -------------------------------------------------------------------------------- 1 | console.log("Hello World"); 2 | -------------------------------------------------------------------------------- /examples/hello_module.js: -------------------------------------------------------------------------------- 1 | /* example of JS module */ 2 | 3 | import { fib } from "./fib_module.js"; 4 | 5 | console.log("Hello World"); 6 | console.log("fib(10)=", fib(10)); 7 | -------------------------------------------------------------------------------- /examples/pi_bigdecimal.js: -------------------------------------------------------------------------------- 1 | /* 2 | * PI computation in Javascript using the QuickJS bigdecimal type 3 | * (decimal floating point) 4 | */ 5 | "use strict"; 6 | 7 | /* compute PI with a precision of 'prec' digits */ 8 | function calc_pi(prec) { 9 | const CHUD_A = 13591409m; 10 | const CHUD_B = 545140134m; 11 | const CHUD_C = 640320m; 12 | const CHUD_C3 = 10939058860032000m; /* C^3/24 */ 13 | const CHUD_DIGITS_PER_TERM = 14.18164746272548; /* log10(C/12)*3 */ 14 | 15 | /* return [P, Q, G] */ 16 | function chud_bs(a, b, need_G) { 17 | var c, P, Q, G, P1, Q1, G1, P2, Q2, G2, b1; 18 | if (a == (b - 1n)) { 19 | b1 = BigDecimal(b); 20 | G = (2m * b1 - 1m) * (6m * b1 - 1m) * (6m * b1 - 5m); 21 | P = G * (CHUD_B * b1 + CHUD_A); 22 | if (b & 1n) 23 | P = -P; 24 | G = G; 25 | Q = b1 * b1 * b1 * CHUD_C3; 26 | } else { 27 | c = (a + b) >> 1n; 28 | [P1, Q1, G1] = chud_bs(a, c, true); 29 | [P2, Q2, G2] = chud_bs(c, b, need_G); 30 | P = P1 * Q2 + P2 * G1; 31 | Q = Q1 * Q2; 32 | if (need_G) 33 | G = G1 * G2; 34 | else 35 | G = 0m; 36 | } 37 | return [P, Q, G]; 38 | } 39 | 40 | var n, P, Q, G; 41 | /* number of serie terms */ 42 | n = BigInt(Math.ceil(prec / CHUD_DIGITS_PER_TERM)) + 10n; 43 | [P, Q, G] = chud_bs(0n, n, false); 44 | Q = BigDecimal.div(Q, (P + Q * CHUD_A), 45 | { roundingMode: "half-even", 46 | maximumSignificantDigits: prec }); 47 | G = (CHUD_C / 12m) * BigDecimal.sqrt(CHUD_C, 48 | { roundingMode: "half-even", 49 | maximumSignificantDigits: prec }); 50 | return Q * G; 51 | } 52 | 53 | (function() { 54 | var r, n_digits, n_bits; 55 | if (typeof scriptArgs != "undefined") { 56 | if (scriptArgs.length < 2) { 57 | print("usage: pi n_digits"); 58 | return; 59 | } 60 | n_digits = scriptArgs[1] | 0; 61 | } else { 62 | n_digits = 1000; 63 | } 64 | /* we add more digits to reduce the probability of bad rounding for 65 | the last digits */ 66 | r = calc_pi(n_digits + 20); 67 | print(r.toFixed(n_digits, "down")); 68 | })(); 69 | -------------------------------------------------------------------------------- /examples/pi_bigfloat.js: -------------------------------------------------------------------------------- 1 | /* 2 | * PI computation in Javascript using the QuickJS bigfloat type 3 | * (binary floating point) 4 | */ 5 | "use strict"; 6 | 7 | /* compute PI with a precision of 'prec' bits */ 8 | function calc_pi() { 9 | const CHUD_A = 13591409n; 10 | const CHUD_B = 545140134n; 11 | const CHUD_C = 640320n; 12 | const CHUD_C3 = 10939058860032000n; /* C^3/24 */ 13 | const CHUD_BITS_PER_TERM = 47.11041313821584202247; /* log2(C/12)*3 */ 14 | 15 | /* return [P, Q, G] */ 16 | function chud_bs(a, b, need_G) { 17 | var c, P, Q, G, P1, Q1, G1, P2, Q2, G2; 18 | if (a == (b - 1n)) { 19 | G = (2n * b - 1n) * (6n * b - 1n) * (6n * b - 5n); 20 | P = BigFloat(G * (CHUD_B * b + CHUD_A)); 21 | if (b & 1n) 22 | P = -P; 23 | G = BigFloat(G); 24 | Q = BigFloat(b * b * b * CHUD_C3); 25 | } else { 26 | c = (a + b) >> 1n; 27 | [P1, Q1, G1] = chud_bs(a, c, true); 28 | [P2, Q2, G2] = chud_bs(c, b, need_G); 29 | P = P1 * Q2 + P2 * G1; 30 | Q = Q1 * Q2; 31 | if (need_G) 32 | G = G1 * G2; 33 | else 34 | G = 0l; 35 | } 36 | return [P, Q, G]; 37 | } 38 | 39 | var n, P, Q, G; 40 | /* number of serie terms */ 41 | n = BigInt(Math.ceil(BigFloatEnv.prec / CHUD_BITS_PER_TERM)) + 10n; 42 | [P, Q, G] = chud_bs(0n, n, false); 43 | Q = Q / (P + Q * BigFloat(CHUD_A)); 44 | G = BigFloat((CHUD_C / 12n)) * BigFloat.sqrt(BigFloat(CHUD_C)); 45 | return Q * G; 46 | } 47 | 48 | (function() { 49 | var r, n_digits, n_bits; 50 | if (typeof scriptArgs != "undefined") { 51 | if (scriptArgs.length < 2) { 52 | print("usage: pi n_digits"); 53 | return; 54 | } 55 | n_digits = scriptArgs[1]; 56 | } else { 57 | n_digits = 1000; 58 | } 59 | n_bits = Math.ceil(n_digits * Math.log2(10)); 60 | /* we add more bits to reduce the probability of bad rounding for 61 | the last digits */ 62 | BigFloatEnv.setPrec( () => { 63 | r = calc_pi(); 64 | print(r.toFixed(n_digits, BigFloatEnv.RNDZ)); 65 | }, n_bits + 32); 66 | })(); 67 | -------------------------------------------------------------------------------- /examples/pi_bigint.js: -------------------------------------------------------------------------------- 1 | /* 2 | * PI computation in Javascript using the BigInt type 3 | */ 4 | "use strict"; 5 | 6 | /* return floor(log2(a)) for a > 0 and 0 for a = 0 */ 7 | function floor_log2(a) 8 | { 9 | var k_max, a1, k, i; 10 | k_max = 0n; 11 | while ((a >> (2n ** k_max)) != 0n) { 12 | k_max++; 13 | } 14 | k = 0n; 15 | a1 = a; 16 | for(i = k_max - 1n; i >= 0n; i--) { 17 | a1 = a >> (2n ** i); 18 | if (a1 != 0n) { 19 | a = a1; 20 | k |= (1n << i); 21 | } 22 | } 23 | return k; 24 | } 25 | 26 | /* return ceil(log2(a)) for a > 0 */ 27 | function ceil_log2(a) 28 | { 29 | return floor_log2(a - 1n) + 1n; 30 | } 31 | 32 | /* return floor(sqrt(a)) (not efficient but simple) */ 33 | function int_sqrt(a) 34 | { 35 | var l, u, s; 36 | if (a == 0n) 37 | return a; 38 | l = ceil_log2(a); 39 | u = 1n << ((l + 1n) / 2n); 40 | /* u >= floor(sqrt(a)) */ 41 | for(;;) { 42 | s = u; 43 | u = ((a / s) + s) / 2n; 44 | if (u >= s) 45 | break; 46 | } 47 | return s; 48 | } 49 | 50 | /* return pi * 2**prec */ 51 | function calc_pi(prec) { 52 | const CHUD_A = 13591409n; 53 | const CHUD_B = 545140134n; 54 | const CHUD_C = 640320n; 55 | const CHUD_C3 = 10939058860032000n; /* C^3/24 */ 56 | const CHUD_BITS_PER_TERM = 47.11041313821584202247; /* log2(C/12)*3 */ 57 | 58 | /* return [P, Q, G] */ 59 | function chud_bs(a, b, need_G) { 60 | var c, P, Q, G, P1, Q1, G1, P2, Q2, G2; 61 | if (a == (b - 1n)) { 62 | G = (2n * b - 1n) * (6n * b - 1n) * (6n * b - 5n); 63 | P = G * (CHUD_B * b + CHUD_A); 64 | if (b & 1n) 65 | P = -P; 66 | Q = b * b * b * CHUD_C3; 67 | } else { 68 | c = (a + b) >> 1n; 69 | [P1, Q1, G1] = chud_bs(a, c, true); 70 | [P2, Q2, G2] = chud_bs(c, b, need_G); 71 | P = P1 * Q2 + P2 * G1; 72 | Q = Q1 * Q2; 73 | if (need_G) 74 | G = G1 * G2; 75 | else 76 | G = 0n; 77 | } 78 | return [P, Q, G]; 79 | } 80 | 81 | var n, P, Q, G; 82 | /* number of serie terms */ 83 | n = BigInt(Math.ceil(Number(prec) / CHUD_BITS_PER_TERM)) + 10n; 84 | [P, Q, G] = chud_bs(0n, n, false); 85 | Q = (CHUD_C / 12n) * (Q << prec) / (P + Q * CHUD_A); 86 | G = int_sqrt(CHUD_C << (2n * prec)); 87 | return (Q * G) >> prec; 88 | } 89 | 90 | function main(args) { 91 | var r, n_digits, n_bits, out; 92 | if (args.length < 1) { 93 | print("usage: pi n_digits"); 94 | return; 95 | } 96 | n_digits = args[0] | 0; 97 | 98 | /* we add more bits to reduce the probability of bad rounding for 99 | the last digits */ 100 | n_bits = BigInt(Math.ceil(n_digits * Math.log2(10))) + 32n; 101 | r = calc_pi(n_bits); 102 | r = ((10n ** BigInt(n_digits)) * r) >> n_bits; 103 | out = r.toString(); 104 | print(out[0] + "." + out.slice(1)); 105 | } 106 | 107 | var args; 108 | if (typeof scriptArgs != "undefined") { 109 | args = scriptArgs; 110 | args.shift(); 111 | } else if (typeof arguments != "undefined") { 112 | args = arguments; 113 | } else { 114 | /* default: 1000 digits */ 115 | args=[1000]; 116 | } 117 | 118 | main(args); 119 | -------------------------------------------------------------------------------- /examples/point.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS: Example of C module with a class 3 | * 4 | * Copyright (c) 2019 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include "../quickjs.h" 25 | #include 26 | 27 | #define countof(x) (sizeof(x) / sizeof((x)[0])) 28 | 29 | /* Point Class */ 30 | 31 | typedef struct { 32 | int x; 33 | int y; 34 | } JSPointData; 35 | 36 | static JSClassID js_point_class_id; 37 | 38 | static void js_point_finalizer(JSRuntime *rt, JSValue val) 39 | { 40 | JSPointData *s = JS_GetOpaque(val, js_point_class_id); 41 | /* Note: 's' can be NULL in case JS_SetOpaque() was not called */ 42 | js_free_rt(rt, s); 43 | } 44 | 45 | static JSValue js_point_ctor(JSContext *ctx, 46 | JSValueConst new_target, 47 | int argc, JSValueConst *argv) 48 | { 49 | JSPointData *s; 50 | JSValue obj = JS_UNDEFINED; 51 | JSValue proto; 52 | 53 | s = js_mallocz(ctx, sizeof(*s)); 54 | if (!s) 55 | return JS_EXCEPTION; 56 | if (JS_ToInt32(ctx, &s->x, argv[0])) 57 | goto fail; 58 | if (JS_ToInt32(ctx, &s->y, argv[1])) 59 | goto fail; 60 | /* using new_target to get the prototype is necessary when the 61 | class is extended. */ 62 | proto = JS_GetPropertyStr(ctx, new_target, "prototype"); 63 | if (JS_IsException(proto)) 64 | goto fail; 65 | obj = JS_NewObjectProtoClass(ctx, proto, js_point_class_id); 66 | JS_FreeValue(ctx, proto); 67 | if (JS_IsException(obj)) 68 | goto fail; 69 | JS_SetOpaque(obj, s); 70 | return obj; 71 | fail: 72 | js_free(ctx, s); 73 | JS_FreeValue(ctx, obj); 74 | return JS_EXCEPTION; 75 | } 76 | 77 | static JSValue js_point_get_xy(JSContext *ctx, JSValueConst this_val, int magic) 78 | { 79 | JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id); 80 | if (!s) 81 | return JS_EXCEPTION; 82 | if (magic == 0) 83 | return JS_NewInt32(ctx, s->x); 84 | else 85 | return JS_NewInt32(ctx, s->y); 86 | } 87 | 88 | static JSValue js_point_set_xy(JSContext *ctx, JSValueConst this_val, JSValue val, int magic) 89 | { 90 | JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id); 91 | int v; 92 | if (!s) 93 | return JS_EXCEPTION; 94 | if (JS_ToInt32(ctx, &v, val)) 95 | return JS_EXCEPTION; 96 | if (magic == 0) 97 | s->x = v; 98 | else 99 | s->y = v; 100 | return JS_UNDEFINED; 101 | } 102 | 103 | static JSValue js_point_norm(JSContext *ctx, JSValueConst this_val, 104 | int argc, JSValueConst *argv) 105 | { 106 | JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id); 107 | if (!s) 108 | return JS_EXCEPTION; 109 | return JS_NewFloat64(ctx, sqrt((double)s->x * s->x + (double)s->y * s->y)); 110 | } 111 | 112 | static JSClassDef js_point_class = { 113 | "Point", 114 | .finalizer = js_point_finalizer, 115 | }; 116 | 117 | static const JSCFunctionListEntry js_point_proto_funcs[] = { 118 | JS_CGETSET_MAGIC_DEF("x", js_point_get_xy, js_point_set_xy, 0), 119 | JS_CGETSET_MAGIC_DEF("y", js_point_get_xy, js_point_set_xy, 1), 120 | JS_CFUNC_DEF("norm", 0, js_point_norm), 121 | }; 122 | 123 | static int js_point_init(JSContext *ctx, JSModuleDef *m) 124 | { 125 | JSValue point_proto, point_class; 126 | 127 | /* create the Point class */ 128 | JS_NewClassID(&js_point_class_id); 129 | JS_NewClass(JS_GetRuntime(ctx), js_point_class_id, &js_point_class); 130 | 131 | point_proto = JS_NewObject(ctx); 132 | JS_SetPropertyFunctionList(ctx, point_proto, js_point_proto_funcs, countof(js_point_proto_funcs)); 133 | 134 | point_class = JS_NewCFunction2(ctx, js_point_ctor, "Point", 2, JS_CFUNC_constructor, 0); 135 | /* set proto.constructor and ctor.prototype */ 136 | JS_SetConstructor(ctx, point_class, point_proto); 137 | JS_SetClassProto(ctx, js_point_class_id, point_proto); 138 | 139 | JS_SetModuleExport(ctx, m, "Point", point_class); 140 | return 0; 141 | } 142 | 143 | JSModuleDef *js_init_module(JSContext *ctx, const char *module_name) 144 | { 145 | JSModuleDef *m; 146 | m = JS_NewCModule(ctx, module_name, js_point_init); 147 | if (!m) 148 | return NULL; 149 | JS_AddModuleExport(ctx, m, "Point"); 150 | return m; 151 | } 152 | -------------------------------------------------------------------------------- /examples/test_fib.js: -------------------------------------------------------------------------------- 1 | /* example of JS module importing a C module */ 2 | 3 | import { fib } from "./fib.so"; 4 | 5 | console.log("Hello World"); 6 | console.log("fib(10)=", fib(10)); 7 | -------------------------------------------------------------------------------- /examples/test_point.js: -------------------------------------------------------------------------------- 1 | /* example of JS module importing a C module */ 2 | import { Point } from "./point.so"; 3 | 4 | function assert(b, str) 5 | { 6 | if (b) { 7 | return; 8 | } else { 9 | throw Error("assertion failed: " + str); 10 | } 11 | } 12 | 13 | class ColorPoint extends Point { 14 | constructor(x, y, color) { 15 | super(x, y); 16 | this.color = color; 17 | } 18 | get_color() { 19 | return this.color; 20 | } 21 | }; 22 | 23 | function main() 24 | { 25 | var pt, pt2; 26 | 27 | pt = new Point(2, 3); 28 | assert(pt.x === 2); 29 | assert(pt.y === 3); 30 | pt.x = 4; 31 | assert(pt.x === 4); 32 | assert(pt.norm() == 5); 33 | 34 | pt2 = new ColorPoint(2, 3, 0xffffff); 35 | assert(pt2.x === 2); 36 | assert(pt2.color === 0xffffff); 37 | assert(pt2.get_color() === 0xffffff); 38 | } 39 | 40 | main(); 41 | -------------------------------------------------------------------------------- /lib/build_lib.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | ~/wasi-sdk-21.0/bin/clang --sysroot=${WASI_ROOT_PATH} -msimd128 -mbulk-memory -c ../libbf.c ../cutils.c ../libunicode.c wapper.c ../libregexp.c ../quickjs-libc.c -DNO_OS_POLL=1 -DCONFIG_BIGNUM=1 -DCONFIG_VERSION='"wasi"' -D_WASI_EMULATED_SIGNAL -O3 -fPIC 3 | ~/wasi-sdk-21.0/bin/ar -r libquickjs.a *.o 4 | bindgen wapper.h --no-layout-tests --allowlist-item '(JS|js|Js).*' -o binding.rs -- -D__wasi__ 5 | # cp static-lib and binding.rs to quickjs-rs-wasi 6 | # change cp path 7 | # cp libquickjs.a ../../quickjs-rs-wasi/lib/ 8 | # cp binding.rs ../../quickjs-rs-wasi/lib/ 9 | rm *.o -------------------------------------------------------------------------------- /lib/libquickjs.a: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/quickjs-wasi/84589b6f6d1ff9752286cbab24bac24245b31d97/lib/libquickjs.a -------------------------------------------------------------------------------- /lib/wapper.c: -------------------------------------------------------------------------------- 1 | #include "wapper.h" 2 | #include "../quickjs.c" 3 | 4 | int JS_ValueGetTag_real(JSValue v) { 5 | return JS_VALUE_GET_TAG(v); 6 | } 7 | 8 | void JS_FreeValue_real(JSContext *ctx, JSValue v) { 9 | JS_FreeValue(ctx, v); 10 | } 11 | 12 | void JS_FreeValueRT_real(JSRuntime *rt, JSValue v) { 13 | return JS_FreeValueRT(rt, v); 14 | } 15 | 16 | JSValue JS_DupValue_real(JSContext *ctx, JSValue v) { 17 | return JS_DupValue(ctx, v); 18 | } 19 | 20 | JSValue JS_DupValueRT_real(JSRuntime *rt, JSValueConst v) { 21 | return JS_DupValueRT(rt, v); 22 | } 23 | 24 | JSValue JS_NewFloat64_real(JSContext *ctx, double d) { 25 | return JS_NewFloat64(ctx, d); 26 | } 27 | 28 | JSValue JS_NewInt32_real(JSContext *ctx, int32_t val) { 29 | return JS_NewInt32(ctx, val); 30 | } 31 | 32 | JSValue JS_NewInt64_real(JSContext *ctx, int64_t val) { 33 | return JS_NewInt64(ctx, val); 34 | } 35 | 36 | JSValue JS_NewBool_real(JSContext *ctx, JS_BOOL val) { 37 | return JS_NewBool(ctx, val) ; 38 | } 39 | 40 | JS_BOOL JS_VALUE_IS_NAN_real(JSValue v) { 41 | return JS_VALUE_IS_NAN(v); 42 | } 43 | 44 | double JS_VALUE_GET_FLOAT64_real(JSValue v) { 45 | return JS_VALUE_GET_FLOAT64(v); 46 | } 47 | 48 | enum JS_TAG JS_VALUE_GET_NORM_TAG_real(JSValue v) { 49 | return JS_VALUE_GET_NORM_TAG(v); 50 | } 51 | 52 | void *JS_VALUE_GET_PTR_real(JSValue v) { 53 | return JS_VALUE_GET_PTR(v); 54 | } 55 | 56 | JS_BOOL JS_IsNumber_real(JSValueConst v) { 57 | return JS_IsNumber(v); 58 | } 59 | 60 | JS_BOOL JS_IsBigInt_real(JSContext *ctx, JSValueConst v) { 61 | return JS_IsBigInt(ctx, v); 62 | } 63 | 64 | JS_BOOL JS_IsBigFloat_real(JSValueConst v) { 65 | return JS_IsBigFloat(v); 66 | } 67 | 68 | JS_BOOL JS_IsBigDecimal_real(JSValueConst v) { 69 | return JS_IsBigDecimal(v); 70 | } 71 | 72 | JS_BOOL JS_IsBool_real(JSValueConst v) { 73 | return JS_IsBool(v); 74 | } 75 | 76 | JS_BOOL JS_IsNull_real(JSValueConst v) { 77 | return JS_IsNull(v); 78 | } 79 | 80 | JS_BOOL JS_IsUndefined_real(JSValueConst v) { 81 | return JS_IsUndefined(v); 82 | } 83 | 84 | JS_BOOL JS_IsException_real(JSValueConst v) { 85 | return JS_IsException(v); 86 | } 87 | 88 | JS_BOOL JS_IsUninitialized_real(JSValueConst v) { 89 | return JS_IsUninitialized(v); 90 | } 91 | 92 | JS_BOOL JS_IsString_real(JSValueConst v) { 93 | return JS_IsString(v); 94 | } 95 | 96 | JS_BOOL JS_IsSymbol_real(JSValueConst v) { 97 | return JS_IsSymbol(v); 98 | } 99 | 100 | JS_BOOL JS_IsObject_real(JSValueConst v) { 101 | return JS_IsObject(v); 102 | } 103 | 104 | int JS_ToUint32_real(JSContext *ctx, uint32_t *pres, JSValueConst val) { 105 | return JS_ToUint32(ctx, pres, val); 106 | } 107 | 108 | int JS_SetProperty_real(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValue val) { 109 | return JS_SetProperty(ctx, this_obj, prop, val); 110 | } 111 | 112 | JSValue JS_NewCFunction_real(JSContext *ctx, JSCFunction *func, const char *name,int length) { 113 | return JS_NewCFunction(ctx, func, name, length); 114 | } 115 | 116 | JSValue JS_NewCFunctionMagic_real(JSContext *ctx, JSCFunctionMagic *func, const char *name, int length, JSCFunctionEnum cproto, int magic) { 117 | return JS_NewCFunctionMagic(ctx, func, name, length, cproto, magic); 118 | } 119 | 120 | JSValue JS_GetPromiseResult_real(JSContext *ctx, JSValueConst this_val) { 121 | return JS_GetPromiseResult(ctx, this_val); 122 | } 123 | 124 | int JS_IsPromise(JSContext *ctx, JSValueConst val) { 125 | JSObject *p; 126 | if (JS_VALUE_GET_TAG(val) == JS_TAG_OBJECT) { 127 | p = JS_VALUE_GET_OBJ(val); 128 | return p->class_id == JS_CLASS_PROMISE; 129 | } else { 130 | return FALSE; 131 | } 132 | } 133 | 134 | int js_eval_buf(JSContext *ctx, const void *buf, int buf_len, const char *filename, int eval_flags) 135 | { 136 | JSValue val; 137 | int ret; 138 | 139 | if ((eval_flags & JS_EVAL_TYPE_MASK) == JS_EVAL_TYPE_MODULE) { 140 | /* for the modules, we compile then run to be able to set 141 | import.meta */ 142 | val = JS_Eval(ctx, buf, buf_len, filename, 143 | eval_flags | JS_EVAL_FLAG_COMPILE_ONLY); 144 | if (!JS_IsException(val)) { 145 | js_module_set_import_meta(ctx, val, TRUE, TRUE); 146 | val = JS_EvalFunction(ctx, val); 147 | } 148 | } else { 149 | val = JS_Eval(ctx, buf, buf_len, filename, eval_flags); 150 | } 151 | if (JS_IsException(val)) { 152 | js_std_dump_error(ctx); 153 | ret = -1; 154 | } else { 155 | ret = 0; 156 | } 157 | JS_FreeValue(ctx, val); 158 | return ret; 159 | } 160 | 161 | JSValue js_undefined(){ 162 | return JS_UNDEFINED; 163 | } 164 | 165 | JSValue js_exception(){ 166 | return JS_EXCEPTION; 167 | } 168 | 169 | JSValue js_null(){ 170 | return JS_NULL; 171 | } -------------------------------------------------------------------------------- /lib/wapper.h: -------------------------------------------------------------------------------- 1 | #include "../quickjs.h" 2 | 3 | // quickjs-libc.h 4 | JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name); 5 | JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name); 6 | void js_std_add_console(JSContext *ctx); 7 | void js_std_loop(JSContext *ctx); 8 | void js_std_init_handlers(JSRuntime *rt); 9 | void js_std_free_handlers(JSRuntime *rt); 10 | void js_std_dump_error(JSContext *ctx); 11 | uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename); 12 | int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val, 13 | JS_BOOL use_realpath, JS_BOOL is_main); 14 | JSModuleDef *js_module_loader(JSContext *ctx, 15 | const char *module_name, void *opaque); 16 | void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len, 17 | int flags); 18 | void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise, 19 | JSValueConst reason, 20 | JS_BOOL is_handled, void *opaque); 21 | 22 | //ex 23 | int JS_ValueGetTag_real(JSValue v); 24 | 25 | void JS_FreeValue_real(JSContext *ctx, JSValue v); 26 | 27 | void JS_FreeValueRT_real(JSRuntime *rt, JSValue v); 28 | 29 | JSValue JS_DupValue_real(JSContext *ctx, JSValue v); 30 | 31 | JSValue JS_DupValueRT_real(JSRuntime *rt, JSValueConst v); 32 | 33 | JSValue JS_NewFloat64_real(JSContext *ctx, double d); 34 | 35 | JSValue JS_NewInt32_real(JSContext *ctx, int32_t val); 36 | JSValue JS_NewInt64_real(JSContext *ctx, int64_t val); 37 | 38 | JSValue JS_NewBool_real(JSContext *ctx, JS_BOOL val); 39 | 40 | JS_BOOL JS_VALUE_IS_NAN_real(JSValue v); 41 | 42 | double JS_VALUE_GET_FLOAT64_real(JSValue v); 43 | 44 | int JS_VALUE_GET_NORM_TAG_real(JSValue v); 45 | 46 | void *JS_VALUE_GET_PTR_real(JSValue v); 47 | 48 | JS_BOOL JS_IsNumber_real(JSValueConst v); 49 | 50 | JS_BOOL JS_IsBigInt_real(JSContext *ctx, JSValueConst v); 51 | 52 | JS_BOOL JS_IsBigFloat_real(JSValueConst v); 53 | 54 | JS_BOOL JS_IsBigDecimal_real(JSValueConst v); 55 | 56 | JS_BOOL JS_IsBool_real(JSValueConst v); 57 | 58 | JS_BOOL JS_IsNull_real(JSValueConst v); 59 | 60 | JS_BOOL JS_IsUndefined_real(JSValueConst v); 61 | 62 | JS_BOOL JS_IsException_real(JSValueConst v); 63 | 64 | JS_BOOL JS_IsUninitialized_real(JSValueConst v); 65 | 66 | JS_BOOL JS_IsString_real(JSValueConst v); 67 | 68 | JS_BOOL JS_IsSymbol_real(JSValueConst v); 69 | 70 | JS_BOOL JS_IsObject_real(JSValueConst v); 71 | 72 | int JS_IsPromise(JSContext *ctx, JSValueConst val); 73 | 74 | JSValue JS_GetPromiseResult_real(JSContext *ctx, JSValueConst this_val); 75 | 76 | int JS_ToUint32_real(JSContext *ctx, uint32_t *pres, JSValueConst val); 77 | 78 | int JS_SetProperty_real(JSContext *ctx, JSValueConst this_obj, JSAtom prop, JSValue val); 79 | 80 | JSValue JS_NewCFunction_real(JSContext *ctx, JSCFunction *func, const char *name,int length); 81 | 82 | JSValue JS_NewCFunctionMagic_real(JSContext *ctx, JSCFunctionMagic *func, const char *name, int length, JSCFunctionEnum cproto, int magic); 83 | 84 | int js_eval_buf(JSContext *ctx, const void *buf, int buf_len, const char *filename, int eval_flags); 85 | 86 | void *memcpy(void *str1, const void *str2, size_t n); 87 | 88 | JSValue js_undefined(); 89 | 90 | JSValue js_exception(); 91 | 92 | JSValue js_null(); -------------------------------------------------------------------------------- /libregexp-opcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Regular Expression Engine 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | 25 | #ifdef DEF 26 | 27 | DEF(invalid, 1) /* never used */ 28 | DEF(char, 3) 29 | DEF(char32, 5) 30 | DEF(dot, 1) 31 | DEF(any, 1) /* same as dot but match any character including line terminator */ 32 | DEF(line_start, 1) 33 | DEF(line_end, 1) 34 | DEF(goto, 5) 35 | DEF(split_goto_first, 5) 36 | DEF(split_next_first, 5) 37 | DEF(match, 1) 38 | DEF(save_start, 2) /* save start position */ 39 | DEF(save_end, 2) /* save end position, must come after saved_start */ 40 | DEF(save_reset, 3) /* reset save positions */ 41 | DEF(loop, 5) /* decrement the top the stack and goto if != 0 */ 42 | DEF(push_i32, 5) /* push integer on the stack */ 43 | DEF(drop, 1) 44 | DEF(word_boundary, 1) 45 | DEF(not_word_boundary, 1) 46 | DEF(back_reference, 2) 47 | DEF(backward_back_reference, 2) /* must come after back_reference */ 48 | DEF(range, 3) /* variable length */ 49 | DEF(range32, 3) /* variable length */ 50 | DEF(lookahead, 5) 51 | DEF(negative_lookahead, 5) 52 | DEF(push_char_pos, 1) /* push the character position on the stack */ 53 | DEF(check_advance, 1) /* pop one stack element and check that it is different from the character position */ 54 | DEF(prev, 1) /* go to the previous char */ 55 | DEF(simple_greedy_quant, 17) 56 | 57 | #endif /* DEF */ 58 | -------------------------------------------------------------------------------- /libregexp.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Regular Expression Engine 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIBREGEXP_H 25 | #define LIBREGEXP_H 26 | 27 | #include 28 | 29 | #include "libunicode.h" 30 | 31 | #define LRE_BOOL int /* for documentation purposes */ 32 | 33 | #define LRE_FLAG_GLOBAL (1 << 0) 34 | #define LRE_FLAG_IGNORECASE (1 << 1) 35 | #define LRE_FLAG_MULTILINE (1 << 2) 36 | #define LRE_FLAG_DOTALL (1 << 3) 37 | #define LRE_FLAG_UTF16 (1 << 4) 38 | #define LRE_FLAG_STICKY (1 << 5) 39 | #define LRE_FLAG_INDICES (1 << 6) /* Unused by libregexp, just recorded. */ 40 | 41 | #define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */ 42 | 43 | uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size, 44 | const char *buf, size_t buf_len, int re_flags, 45 | void *opaque); 46 | int lre_get_capture_count(const uint8_t *bc_buf); 47 | int lre_get_flags(const uint8_t *bc_buf); 48 | const char *lre_get_groupnames(const uint8_t *bc_buf); 49 | int lre_exec(uint8_t **capture, 50 | const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen, 51 | int cbuf_type, void *opaque); 52 | 53 | int lre_parse_escape(const uint8_t **pp, int allow_utf16); 54 | LRE_BOOL lre_is_space(int c); 55 | 56 | /* must be provided by the user */ 57 | LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size); 58 | void *lre_realloc(void *opaque, void *ptr, size_t size); 59 | 60 | /* JS identifier test */ 61 | extern uint32_t const lre_id_start_table_ascii[4]; 62 | extern uint32_t const lre_id_continue_table_ascii[4]; 63 | 64 | static inline int lre_js_is_ident_first(int c) 65 | { 66 | if ((uint32_t)c < 128) { 67 | return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1; 68 | } else { 69 | #ifdef CONFIG_ALL_UNICODE 70 | return lre_is_id_start(c); 71 | #else 72 | return !lre_is_space(c); 73 | #endif 74 | } 75 | } 76 | 77 | static inline int lre_js_is_ident_next(int c) 78 | { 79 | if ((uint32_t)c < 128) { 80 | return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1; 81 | } else { 82 | /* ZWNJ and ZWJ are accepted in identifiers */ 83 | #ifdef CONFIG_ALL_UNICODE 84 | return lre_is_id_continue(c) || c == 0x200C || c == 0x200D; 85 | #else 86 | return !lre_is_space(c) || c == 0x200C || c == 0x200D; 87 | #endif 88 | } 89 | } 90 | 91 | #undef LRE_BOOL 92 | 93 | #endif /* LIBREGEXP_H */ 94 | -------------------------------------------------------------------------------- /libunicode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Unicode utilities 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIBUNICODE_H 25 | #define LIBUNICODE_H 26 | 27 | #include 28 | 29 | #define LRE_BOOL int /* for documentation purposes */ 30 | 31 | /* define it to include all the unicode tables (40KB larger) */ 32 | #define CONFIG_ALL_UNICODE 33 | 34 | #define LRE_CC_RES_LEN_MAX 3 35 | 36 | typedef enum { 37 | UNICODE_NFC, 38 | UNICODE_NFD, 39 | UNICODE_NFKC, 40 | UNICODE_NFKD, 41 | } UnicodeNormalizationEnum; 42 | 43 | int lre_case_conv(uint32_t *res, uint32_t c, int conv_type); 44 | int lre_canonicalize(uint32_t c, BOOL is_unicode); 45 | LRE_BOOL lre_is_cased(uint32_t c); 46 | LRE_BOOL lre_is_case_ignorable(uint32_t c); 47 | 48 | /* char ranges */ 49 | 50 | typedef struct { 51 | int len; /* in points, always even */ 52 | int size; 53 | uint32_t *points; /* points sorted by increasing value */ 54 | void *mem_opaque; 55 | void *(*realloc_func)(void *opaque, void *ptr, size_t size); 56 | } CharRange; 57 | 58 | typedef enum { 59 | CR_OP_UNION, 60 | CR_OP_INTER, 61 | CR_OP_XOR, 62 | } CharRangeOpEnum; 63 | 64 | void cr_init(CharRange *cr, void *mem_opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); 65 | void cr_free(CharRange *cr); 66 | int cr_realloc(CharRange *cr, int size); 67 | int cr_copy(CharRange *cr, const CharRange *cr1); 68 | 69 | static inline int cr_add_point(CharRange *cr, uint32_t v) 70 | { 71 | if (cr->len >= cr->size) { 72 | if (cr_realloc(cr, cr->len + 1)) 73 | return -1; 74 | } 75 | cr->points[cr->len++] = v; 76 | return 0; 77 | } 78 | 79 | static inline int cr_add_interval(CharRange *cr, uint32_t c1, uint32_t c2) 80 | { 81 | if ((cr->len + 2) > cr->size) { 82 | if (cr_realloc(cr, cr->len + 2)) 83 | return -1; 84 | } 85 | cr->points[cr->len++] = c1; 86 | cr->points[cr->len++] = c2; 87 | return 0; 88 | } 89 | 90 | int cr_union1(CharRange *cr, const uint32_t *b_pt, int b_len); 91 | 92 | static inline int cr_union_interval(CharRange *cr, uint32_t c1, uint32_t c2) 93 | { 94 | uint32_t b_pt[2]; 95 | b_pt[0] = c1; 96 | b_pt[1] = c2 + 1; 97 | return cr_union1(cr, b_pt, 2); 98 | } 99 | 100 | int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len, 101 | const uint32_t *b_pt, int b_len, int op); 102 | 103 | int cr_invert(CharRange *cr); 104 | 105 | int cr_regexp_canonicalize(CharRange *cr, BOOL is_unicode); 106 | 107 | #ifdef CONFIG_ALL_UNICODE 108 | 109 | LRE_BOOL lre_is_id_start(uint32_t c); 110 | LRE_BOOL lre_is_id_continue(uint32_t c); 111 | 112 | int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len, 113 | UnicodeNormalizationEnum n_type, 114 | void *opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size)); 115 | 116 | /* Unicode character range functions */ 117 | 118 | int unicode_script(CharRange *cr, 119 | const char *script_name, LRE_BOOL is_ext); 120 | int unicode_general_category(CharRange *cr, const char *gc_name); 121 | int unicode_prop(CharRange *cr, const char *prop_name); 122 | 123 | #endif /* CONFIG_ALL_UNICODE */ 124 | 125 | #undef LRE_BOOL 126 | 127 | #endif /* LIBUNICODE_H */ 128 | -------------------------------------------------------------------------------- /list.h: -------------------------------------------------------------------------------- 1 | /* 2 | * Linux klist like system 3 | * 4 | * Copyright (c) 2016-2017 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef LIST_H 25 | #define LIST_H 26 | 27 | #ifndef NULL 28 | #include 29 | #endif 30 | 31 | struct list_head { 32 | struct list_head *prev; 33 | struct list_head *next; 34 | }; 35 | 36 | #define LIST_HEAD_INIT(el) { &(el), &(el) } 37 | 38 | /* return the pointer of type 'type *' containing 'el' as field 'member' */ 39 | #define list_entry(el, type, member) container_of(el, type, member) 40 | 41 | static inline void init_list_head(struct list_head *head) 42 | { 43 | head->prev = head; 44 | head->next = head; 45 | } 46 | 47 | /* insert 'el' between 'prev' and 'next' */ 48 | static inline void __list_add(struct list_head *el, 49 | struct list_head *prev, struct list_head *next) 50 | { 51 | prev->next = el; 52 | el->prev = prev; 53 | el->next = next; 54 | next->prev = el; 55 | } 56 | 57 | /* add 'el' at the head of the list 'head' (= after element head) */ 58 | static inline void list_add(struct list_head *el, struct list_head *head) 59 | { 60 | __list_add(el, head, head->next); 61 | } 62 | 63 | /* add 'el' at the end of the list 'head' (= before element head) */ 64 | static inline void list_add_tail(struct list_head *el, struct list_head *head) 65 | { 66 | __list_add(el, head->prev, head); 67 | } 68 | 69 | static inline void list_del(struct list_head *el) 70 | { 71 | struct list_head *prev, *next; 72 | prev = el->prev; 73 | next = el->next; 74 | prev->next = next; 75 | next->prev = prev; 76 | el->prev = NULL; /* fail safe */ 77 | el->next = NULL; /* fail safe */ 78 | } 79 | 80 | static inline int list_empty(struct list_head *el) 81 | { 82 | return el->next == el; 83 | } 84 | 85 | #define list_for_each(el, head) \ 86 | for(el = (head)->next; el != (head); el = el->next) 87 | 88 | #define list_for_each_safe(el, el1, head) \ 89 | for(el = (head)->next, el1 = el->next; el != (head); \ 90 | el = el1, el1 = el->next) 91 | 92 | #define list_for_each_prev(el, head) \ 93 | for(el = (head)->prev; el != (head); el = el->prev) 94 | 95 | #define list_for_each_prev_safe(el, el1, head) \ 96 | for(el = (head)->prev, el1 = el->prev; el != (head); \ 97 | el = el1, el1 = el->prev) 98 | 99 | #endif /* LIST_H */ 100 | -------------------------------------------------------------------------------- /qjs.wasm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/quickjs-wasi/84589b6f6d1ff9752286cbab24bac24245b31d97/qjs.wasm -------------------------------------------------------------------------------- /quickjs-atom.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS atom definitions 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * Copyright (c) 2017-2018 Charlie Gordon 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | #ifdef DEF 27 | 28 | /* Note: first atoms are considered as keywords in the parser */ 29 | DEF(null, "null") /* must be first */ 30 | DEF(false, "false") 31 | DEF(true, "true") 32 | DEF(if, "if") 33 | DEF(else, "else") 34 | DEF(return, "return") 35 | DEF(var, "var") 36 | DEF(this, "this") 37 | DEF(delete, "delete") 38 | DEF(void, "void") 39 | DEF(typeof, "typeof") 40 | DEF(new, "new") 41 | DEF(in, "in") 42 | DEF(instanceof, "instanceof") 43 | DEF(do, "do") 44 | DEF(while, "while") 45 | DEF(for, "for") 46 | DEF(break, "break") 47 | DEF(continue, "continue") 48 | DEF(switch, "switch") 49 | DEF(case, "case") 50 | DEF(default, "default") 51 | DEF(throw, "throw") 52 | DEF(try, "try") 53 | DEF(catch, "catch") 54 | DEF(finally, "finally") 55 | DEF(function, "function") 56 | DEF(debugger, "debugger") 57 | DEF(with, "with") 58 | /* FutureReservedWord */ 59 | DEF(class, "class") 60 | DEF(const, "const") 61 | DEF(enum, "enum") 62 | DEF(export, "export") 63 | DEF(extends, "extends") 64 | DEF(import, "import") 65 | DEF(super, "super") 66 | /* FutureReservedWords when parsing strict mode code */ 67 | DEF(implements, "implements") 68 | DEF(interface, "interface") 69 | DEF(let, "let") 70 | DEF(package, "package") 71 | DEF(private, "private") 72 | DEF(protected, "protected") 73 | DEF(public, "public") 74 | DEF(static, "static") 75 | DEF(yield, "yield") 76 | DEF(await, "await") 77 | 78 | /* empty string */ 79 | DEF(empty_string, "") 80 | /* identifiers */ 81 | DEF(length, "length") 82 | DEF(fileName, "fileName") 83 | DEF(lineNumber, "lineNumber") 84 | DEF(message, "message") 85 | DEF(cause, "cause") 86 | DEF(errors, "errors") 87 | DEF(stack, "stack") 88 | DEF(name, "name") 89 | DEF(toString, "toString") 90 | DEF(toLocaleString, "toLocaleString") 91 | DEF(valueOf, "valueOf") 92 | DEF(eval, "eval") 93 | DEF(prototype, "prototype") 94 | DEF(constructor, "constructor") 95 | DEF(configurable, "configurable") 96 | DEF(writable, "writable") 97 | DEF(enumerable, "enumerable") 98 | DEF(value, "value") 99 | DEF(get, "get") 100 | DEF(set, "set") 101 | DEF(of, "of") 102 | DEF(__proto__, "__proto__") 103 | DEF(undefined, "undefined") 104 | DEF(number, "number") 105 | DEF(boolean, "boolean") 106 | DEF(string, "string") 107 | DEF(object, "object") 108 | DEF(symbol, "symbol") 109 | DEF(integer, "integer") 110 | DEF(unknown, "unknown") 111 | DEF(arguments, "arguments") 112 | DEF(callee, "callee") 113 | DEF(caller, "caller") 114 | DEF(_eval_, "") 115 | DEF(_ret_, "") 116 | DEF(_var_, "") 117 | DEF(_arg_var_, "") 118 | DEF(_with_, "") 119 | DEF(lastIndex, "lastIndex") 120 | DEF(target, "target") 121 | DEF(index, "index") 122 | DEF(input, "input") 123 | DEF(defineProperties, "defineProperties") 124 | DEF(apply, "apply") 125 | DEF(join, "join") 126 | DEF(concat, "concat") 127 | DEF(split, "split") 128 | DEF(construct, "construct") 129 | DEF(getPrototypeOf, "getPrototypeOf") 130 | DEF(setPrototypeOf, "setPrototypeOf") 131 | DEF(isExtensible, "isExtensible") 132 | DEF(preventExtensions, "preventExtensions") 133 | DEF(has, "has") 134 | DEF(deleteProperty, "deleteProperty") 135 | DEF(defineProperty, "defineProperty") 136 | DEF(getOwnPropertyDescriptor, "getOwnPropertyDescriptor") 137 | DEF(ownKeys, "ownKeys") 138 | DEF(add, "add") 139 | DEF(done, "done") 140 | DEF(next, "next") 141 | DEF(values, "values") 142 | DEF(source, "source") 143 | DEF(flags, "flags") 144 | DEF(global, "global") 145 | DEF(unicode, "unicode") 146 | DEF(raw, "raw") 147 | DEF(new_target, "new.target") 148 | DEF(this_active_func, "this.active_func") 149 | DEF(home_object, "") 150 | DEF(computed_field, "") 151 | DEF(static_computed_field, "") /* must come after computed_fields */ 152 | DEF(class_fields_init, "") 153 | DEF(brand, "") 154 | DEF(hash_constructor, "#constructor") 155 | DEF(as, "as") 156 | DEF(from, "from") 157 | DEF(meta, "meta") 158 | DEF(_default_, "*default*") 159 | DEF(_star_, "*") 160 | DEF(Module, "Module") 161 | DEF(then, "then") 162 | DEF(resolve, "resolve") 163 | DEF(reject, "reject") 164 | DEF(promise, "promise") 165 | DEF(proxy, "proxy") 166 | DEF(revoke, "revoke") 167 | DEF(async, "async") 168 | DEF(exec, "exec") 169 | DEF(groups, "groups") 170 | DEF(indices, "indices") 171 | DEF(status, "status") 172 | DEF(reason, "reason") 173 | DEF(globalThis, "globalThis") 174 | DEF(bigint, "bigint") 175 | #ifdef CONFIG_BIGNUM 176 | DEF(bigfloat, "bigfloat") 177 | DEF(bigdecimal, "bigdecimal") 178 | DEF(roundingMode, "roundingMode") 179 | DEF(maximumSignificantDigits, "maximumSignificantDigits") 180 | DEF(maximumFractionDigits, "maximumFractionDigits") 181 | #endif 182 | /* the following 3 atoms are only used with CONFIG_ATOMICS */ 183 | DEF(not_equal, "not-equal") 184 | DEF(timed_out, "timed-out") 185 | DEF(ok, "ok") 186 | /* */ 187 | DEF(toJSON, "toJSON") 188 | /* class names */ 189 | DEF(Object, "Object") 190 | DEF(Array, "Array") 191 | DEF(Error, "Error") 192 | DEF(Number, "Number") 193 | DEF(String, "String") 194 | DEF(Boolean, "Boolean") 195 | DEF(Symbol, "Symbol") 196 | DEF(Arguments, "Arguments") 197 | DEF(Math, "Math") 198 | DEF(JSON, "JSON") 199 | DEF(Date, "Date") 200 | DEF(Function, "Function") 201 | DEF(GeneratorFunction, "GeneratorFunction") 202 | DEF(ForInIterator, "ForInIterator") 203 | DEF(RegExp, "RegExp") 204 | DEF(ArrayBuffer, "ArrayBuffer") 205 | DEF(SharedArrayBuffer, "SharedArrayBuffer") 206 | /* must keep same order as class IDs for typed arrays */ 207 | DEF(Uint8ClampedArray, "Uint8ClampedArray") 208 | DEF(Int8Array, "Int8Array") 209 | DEF(Uint8Array, "Uint8Array") 210 | DEF(Int16Array, "Int16Array") 211 | DEF(Uint16Array, "Uint16Array") 212 | DEF(Int32Array, "Int32Array") 213 | DEF(Uint32Array, "Uint32Array") 214 | DEF(BigInt64Array, "BigInt64Array") 215 | DEF(BigUint64Array, "BigUint64Array") 216 | DEF(Float32Array, "Float32Array") 217 | DEF(Float64Array, "Float64Array") 218 | DEF(DataView, "DataView") 219 | DEF(BigInt, "BigInt") 220 | #ifdef CONFIG_BIGNUM 221 | DEF(BigFloat, "BigFloat") 222 | DEF(BigFloatEnv, "BigFloatEnv") 223 | DEF(BigDecimal, "BigDecimal") 224 | DEF(OperatorSet, "OperatorSet") 225 | DEF(Operators, "Operators") 226 | #endif 227 | DEF(Map, "Map") 228 | DEF(Set, "Set") /* Map + 1 */ 229 | DEF(WeakMap, "WeakMap") /* Map + 2 */ 230 | DEF(WeakSet, "WeakSet") /* Map + 3 */ 231 | DEF(Map_Iterator, "Map Iterator") 232 | DEF(Set_Iterator, "Set Iterator") 233 | DEF(Array_Iterator, "Array Iterator") 234 | DEF(String_Iterator, "String Iterator") 235 | DEF(RegExp_String_Iterator, "RegExp String Iterator") 236 | DEF(Generator, "Generator") 237 | DEF(Proxy, "Proxy") 238 | DEF(Promise, "Promise") 239 | DEF(PromiseResolveFunction, "PromiseResolveFunction") 240 | DEF(PromiseRejectFunction, "PromiseRejectFunction") 241 | DEF(AsyncFunction, "AsyncFunction") 242 | DEF(AsyncFunctionResolve, "AsyncFunctionResolve") 243 | DEF(AsyncFunctionReject, "AsyncFunctionReject") 244 | DEF(AsyncGeneratorFunction, "AsyncGeneratorFunction") 245 | DEF(AsyncGenerator, "AsyncGenerator") 246 | DEF(EvalError, "EvalError") 247 | DEF(RangeError, "RangeError") 248 | DEF(ReferenceError, "ReferenceError") 249 | DEF(SyntaxError, "SyntaxError") 250 | DEF(TypeError, "TypeError") 251 | DEF(URIError, "URIError") 252 | DEF(InternalError, "InternalError") 253 | /* private symbols */ 254 | DEF(Private_brand, "") 255 | /* symbols */ 256 | DEF(Symbol_toPrimitive, "Symbol.toPrimitive") 257 | DEF(Symbol_iterator, "Symbol.iterator") 258 | DEF(Symbol_match, "Symbol.match") 259 | DEF(Symbol_matchAll, "Symbol.matchAll") 260 | DEF(Symbol_replace, "Symbol.replace") 261 | DEF(Symbol_search, "Symbol.search") 262 | DEF(Symbol_split, "Symbol.split") 263 | DEF(Symbol_toStringTag, "Symbol.toStringTag") 264 | DEF(Symbol_isConcatSpreadable, "Symbol.isConcatSpreadable") 265 | DEF(Symbol_hasInstance, "Symbol.hasInstance") 266 | DEF(Symbol_species, "Symbol.species") 267 | DEF(Symbol_unscopables, "Symbol.unscopables") 268 | DEF(Symbol_asyncIterator, "Symbol.asyncIterator") 269 | #ifdef CONFIG_BIGNUM 270 | DEF(Symbol_operatorSet, "Symbol.operatorSet") 271 | #endif 272 | 273 | #endif /* DEF */ 274 | -------------------------------------------------------------------------------- /quickjs-libc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS C library 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #ifndef QUICKJS_LIBC_H 25 | #define QUICKJS_LIBC_H 26 | 27 | #include 28 | #include 29 | 30 | #include "quickjs.h" 31 | 32 | #ifdef __cplusplus 33 | extern "C" { 34 | #endif 35 | 36 | JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name); 37 | JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name); 38 | void js_std_add_helpers(JSContext *ctx, int argc, char **argv); 39 | void js_std_loop(JSContext *ctx); 40 | JSValue js_std_await(JSContext *ctx, JSValue obj); 41 | void js_std_init_handlers(JSRuntime *rt); 42 | void js_std_free_handlers(JSRuntime *rt); 43 | void js_std_dump_error(JSContext *ctx); 44 | uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename); 45 | int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val, 46 | JS_BOOL use_realpath, JS_BOOL is_main); 47 | JSModuleDef *js_module_loader(JSContext *ctx, 48 | const char *module_name, void *opaque); 49 | void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len, 50 | int flags); 51 | void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise, 52 | JSValueConst reason, 53 | JS_BOOL is_handled, void *opaque); 54 | void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt)); 55 | 56 | #ifdef __cplusplus 57 | } /* extern "C" { */ 58 | #endif 59 | 60 | #endif /* QUICKJS_LIBC_H */ 61 | -------------------------------------------------------------------------------- /quickjs-opcode.h: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS opcode definitions 3 | * 4 | * Copyright (c) 2017-2018 Fabrice Bellard 5 | * Copyright (c) 2017-2018 Charlie Gordon 6 | * 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in 15 | * all copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 20 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 23 | * THE SOFTWARE. 24 | */ 25 | 26 | #ifdef FMT 27 | FMT(none) 28 | FMT(none_int) 29 | FMT(none_loc) 30 | FMT(none_arg) 31 | FMT(none_var_ref) 32 | FMT(u8) 33 | FMT(i8) 34 | FMT(loc8) 35 | FMT(const8) 36 | FMT(label8) 37 | FMT(u16) 38 | FMT(i16) 39 | FMT(label16) 40 | FMT(npop) 41 | FMT(npopx) 42 | FMT(npop_u16) 43 | FMT(loc) 44 | FMT(arg) 45 | FMT(var_ref) 46 | FMT(u32) 47 | FMT(i32) 48 | FMT(const) 49 | FMT(label) 50 | FMT(atom) 51 | FMT(atom_u8) 52 | FMT(atom_u16) 53 | FMT(atom_label_u8) 54 | FMT(atom_label_u16) 55 | FMT(label_u16) 56 | #undef FMT 57 | #endif /* FMT */ 58 | 59 | #ifdef DEF 60 | 61 | #ifndef def 62 | #define def(id, size, n_pop, n_push, f) DEF(id, size, n_pop, n_push, f) 63 | #endif 64 | 65 | DEF(invalid, 1, 0, 0, none) /* never emitted */ 66 | 67 | /* push values */ 68 | DEF( push_i32, 5, 0, 1, i32) 69 | DEF( push_const, 5, 0, 1, const) 70 | DEF( fclosure, 5, 0, 1, const) /* must follow push_const */ 71 | DEF(push_atom_value, 5, 0, 1, atom) 72 | DEF( private_symbol, 5, 0, 1, atom) 73 | DEF( undefined, 1, 0, 1, none) 74 | DEF( null, 1, 0, 1, none) 75 | DEF( push_this, 1, 0, 1, none) /* only used at the start of a function */ 76 | DEF( push_false, 1, 0, 1, none) 77 | DEF( push_true, 1, 0, 1, none) 78 | DEF( object, 1, 0, 1, none) 79 | DEF( special_object, 2, 0, 1, u8) /* only used at the start of a function */ 80 | DEF( rest, 3, 0, 1, u16) /* only used at the start of a function */ 81 | 82 | DEF( drop, 1, 1, 0, none) /* a -> */ 83 | DEF( nip, 1, 2, 1, none) /* a b -> b */ 84 | DEF( nip1, 1, 3, 2, none) /* a b c -> b c */ 85 | DEF( dup, 1, 1, 2, none) /* a -> a a */ 86 | DEF( dup1, 1, 2, 3, none) /* a b -> a a b */ 87 | DEF( dup2, 1, 2, 4, none) /* a b -> a b a b */ 88 | DEF( dup3, 1, 3, 6, none) /* a b c -> a b c a b c */ 89 | DEF( insert2, 1, 2, 3, none) /* obj a -> a obj a (dup_x1) */ 90 | DEF( insert3, 1, 3, 4, none) /* obj prop a -> a obj prop a (dup_x2) */ 91 | DEF( insert4, 1, 4, 5, none) /* this obj prop a -> a this obj prop a */ 92 | DEF( perm3, 1, 3, 3, none) /* obj a b -> a obj b */ 93 | DEF( perm4, 1, 4, 4, none) /* obj prop a b -> a obj prop b */ 94 | DEF( perm5, 1, 5, 5, none) /* this obj prop a b -> a this obj prop b */ 95 | DEF( swap, 1, 2, 2, none) /* a b -> b a */ 96 | DEF( swap2, 1, 4, 4, none) /* a b c d -> c d a b */ 97 | DEF( rot3l, 1, 3, 3, none) /* x a b -> a b x */ 98 | DEF( rot3r, 1, 3, 3, none) /* a b x -> x a b */ 99 | DEF( rot4l, 1, 4, 4, none) /* x a b c -> a b c x */ 100 | DEF( rot5l, 1, 5, 5, none) /* x a b c d -> a b c d x */ 101 | 102 | DEF(call_constructor, 3, 2, 1, npop) /* func new.target args -> ret. arguments are not counted in n_pop */ 103 | DEF( call, 3, 1, 1, npop) /* arguments are not counted in n_pop */ 104 | DEF( tail_call, 3, 1, 0, npop) /* arguments are not counted in n_pop */ 105 | DEF( call_method, 3, 2, 1, npop) /* arguments are not counted in n_pop */ 106 | DEF(tail_call_method, 3, 2, 0, npop) /* arguments are not counted in n_pop */ 107 | DEF( array_from, 3, 0, 1, npop) /* arguments are not counted in n_pop */ 108 | DEF( apply, 3, 3, 1, u16) 109 | DEF( return, 1, 1, 0, none) 110 | DEF( return_undef, 1, 0, 0, none) 111 | DEF(check_ctor_return, 1, 1, 2, none) 112 | DEF( check_ctor, 1, 0, 0, none) 113 | DEF( check_brand, 1, 2, 2, none) /* this_obj func -> this_obj func */ 114 | DEF( add_brand, 1, 2, 0, none) /* this_obj home_obj -> */ 115 | DEF( return_async, 1, 1, 0, none) 116 | DEF( throw, 1, 1, 0, none) 117 | DEF( throw_error, 6, 0, 0, atom_u8) 118 | DEF( eval, 5, 1, 1, npop_u16) /* func args... -> ret_val */ 119 | DEF( apply_eval, 3, 2, 1, u16) /* func array -> ret_eval */ 120 | DEF( regexp, 1, 2, 1, none) /* create a RegExp object from the pattern and a 121 | bytecode string */ 122 | DEF( get_super, 1, 1, 1, none) 123 | DEF( import, 1, 1, 1, none) /* dynamic module import */ 124 | 125 | DEF( check_var, 5, 0, 1, atom) /* check if a variable exists */ 126 | DEF( get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */ 127 | DEF( get_var, 5, 0, 1, atom) /* throw an exception if the variable does not exist */ 128 | DEF( put_var, 5, 1, 0, atom) /* must come after get_var */ 129 | DEF( put_var_init, 5, 1, 0, atom) /* must come after put_var. Used to initialize a global lexical variable */ 130 | DEF( put_var_strict, 5, 2, 0, atom) /* for strict mode variable write */ 131 | 132 | DEF( get_ref_value, 1, 2, 3, none) 133 | DEF( put_ref_value, 1, 3, 0, none) 134 | 135 | DEF( define_var, 6, 0, 0, atom_u8) 136 | DEF(check_define_var, 6, 0, 0, atom_u8) 137 | DEF( define_func, 6, 1, 0, atom_u8) 138 | DEF( get_field, 5, 1, 1, atom) 139 | DEF( get_field2, 5, 1, 2, atom) 140 | DEF( put_field, 5, 2, 0, atom) 141 | DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */ 142 | DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */ 143 | DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */ 144 | DEF( get_array_el, 1, 2, 1, none) 145 | DEF( get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */ 146 | DEF( put_array_el, 1, 3, 0, none) 147 | DEF(get_super_value, 1, 3, 1, none) /* this obj prop -> value */ 148 | DEF(put_super_value, 1, 4, 0, none) /* this obj prop value -> */ 149 | DEF( define_field, 5, 2, 1, atom) 150 | DEF( set_name, 5, 1, 1, atom) 151 | DEF(set_name_computed, 1, 2, 2, none) 152 | DEF( set_proto, 1, 2, 1, none) 153 | DEF(set_home_object, 1, 2, 2, none) 154 | DEF(define_array_el, 1, 3, 2, none) 155 | DEF( append, 1, 3, 2, none) /* append enumerated object, update length */ 156 | DEF(copy_data_properties, 2, 3, 3, u8) 157 | DEF( define_method, 6, 2, 1, atom_u8) 158 | DEF(define_method_computed, 2, 3, 1, u8) /* must come after define_method */ 159 | DEF( define_class, 6, 2, 2, atom_u8) /* parent ctor -> ctor proto */ 160 | DEF( define_class_computed, 6, 3, 3, atom_u8) /* field_name parent ctor -> field_name ctor proto (class with computed name) */ 161 | 162 | DEF( get_loc, 3, 0, 1, loc) 163 | DEF( put_loc, 3, 1, 0, loc) /* must come after get_loc */ 164 | DEF( set_loc, 3, 1, 1, loc) /* must come after put_loc */ 165 | DEF( get_arg, 3, 0, 1, arg) 166 | DEF( put_arg, 3, 1, 0, arg) /* must come after get_arg */ 167 | DEF( set_arg, 3, 1, 1, arg) /* must come after put_arg */ 168 | DEF( get_var_ref, 3, 0, 1, var_ref) 169 | DEF( put_var_ref, 3, 1, 0, var_ref) /* must come after get_var_ref */ 170 | DEF( set_var_ref, 3, 1, 1, var_ref) /* must come after put_var_ref */ 171 | DEF(set_loc_uninitialized, 3, 0, 0, loc) 172 | DEF( get_loc_check, 3, 0, 1, loc) 173 | DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */ 174 | DEF( put_loc_check_init, 3, 1, 0, loc) 175 | DEF(get_loc_checkthis, 3, 0, 1, loc) 176 | DEF(get_var_ref_check, 3, 0, 1, var_ref) 177 | DEF(put_var_ref_check, 3, 1, 0, var_ref) /* must come after get_var_ref_check */ 178 | DEF(put_var_ref_check_init, 3, 1, 0, var_ref) 179 | DEF( close_loc, 3, 0, 0, loc) 180 | DEF( if_false, 5, 1, 0, label) 181 | DEF( if_true, 5, 1, 0, label) /* must come after if_false */ 182 | DEF( goto, 5, 0, 0, label) /* must come after if_true */ 183 | DEF( catch, 5, 0, 1, label) 184 | DEF( gosub, 5, 0, 0, label) /* used to execute the finally block */ 185 | DEF( ret, 1, 1, 0, none) /* used to return from the finally block */ 186 | DEF( nip_catch, 1, 2, 1, none) /* catch ... a -> a */ 187 | 188 | DEF( to_object, 1, 1, 1, none) 189 | //DEF( to_string, 1, 1, 1, none) 190 | DEF( to_propkey, 1, 1, 1, none) 191 | DEF( to_propkey2, 1, 2, 2, none) 192 | 193 | DEF( with_get_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ 194 | DEF( with_put_var, 10, 2, 1, atom_label_u8) /* must be in the same order as scope_xxx */ 195 | DEF(with_delete_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ 196 | DEF( with_make_ref, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ 197 | DEF( with_get_ref, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */ 198 | DEF(with_get_ref_undef, 10, 1, 0, atom_label_u8) 199 | 200 | DEF( make_loc_ref, 7, 0, 2, atom_u16) 201 | DEF( make_arg_ref, 7, 0, 2, atom_u16) 202 | DEF(make_var_ref_ref, 7, 0, 2, atom_u16) 203 | DEF( make_var_ref, 5, 0, 2, atom) 204 | 205 | DEF( for_in_start, 1, 1, 1, none) 206 | DEF( for_of_start, 1, 1, 3, none) 207 | DEF(for_await_of_start, 1, 1, 3, none) 208 | DEF( for_in_next, 1, 1, 3, none) 209 | DEF( for_of_next, 2, 3, 5, u8) 210 | DEF(iterator_check_object, 1, 1, 1, none) 211 | DEF(iterator_get_value_done, 1, 1, 2, none) 212 | DEF( iterator_close, 1, 3, 0, none) 213 | DEF( iterator_next, 1, 4, 4, none) 214 | DEF( iterator_call, 2, 4, 5, u8) 215 | DEF( initial_yield, 1, 0, 0, none) 216 | DEF( yield, 1, 1, 2, none) 217 | DEF( yield_star, 1, 1, 2, none) 218 | DEF(async_yield_star, 1, 1, 2, none) 219 | DEF( await, 1, 1, 1, none) 220 | 221 | /* arithmetic/logic operations */ 222 | DEF( neg, 1, 1, 1, none) 223 | DEF( plus, 1, 1, 1, none) 224 | DEF( dec, 1, 1, 1, none) 225 | DEF( inc, 1, 1, 1, none) 226 | DEF( post_dec, 1, 1, 2, none) 227 | DEF( post_inc, 1, 1, 2, none) 228 | DEF( dec_loc, 2, 0, 0, loc8) 229 | DEF( inc_loc, 2, 0, 0, loc8) 230 | DEF( add_loc, 2, 1, 0, loc8) 231 | DEF( not, 1, 1, 1, none) 232 | DEF( lnot, 1, 1, 1, none) 233 | DEF( typeof, 1, 1, 1, none) 234 | DEF( delete, 1, 2, 1, none) 235 | DEF( delete_var, 5, 0, 1, atom) 236 | 237 | DEF( mul, 1, 2, 1, none) 238 | DEF( div, 1, 2, 1, none) 239 | DEF( mod, 1, 2, 1, none) 240 | DEF( add, 1, 2, 1, none) 241 | DEF( sub, 1, 2, 1, none) 242 | DEF( pow, 1, 2, 1, none) 243 | DEF( shl, 1, 2, 1, none) 244 | DEF( sar, 1, 2, 1, none) 245 | DEF( shr, 1, 2, 1, none) 246 | DEF( lt, 1, 2, 1, none) 247 | DEF( lte, 1, 2, 1, none) 248 | DEF( gt, 1, 2, 1, none) 249 | DEF( gte, 1, 2, 1, none) 250 | DEF( instanceof, 1, 2, 1, none) 251 | DEF( in, 1, 2, 1, none) 252 | DEF( eq, 1, 2, 1, none) 253 | DEF( neq, 1, 2, 1, none) 254 | DEF( strict_eq, 1, 2, 1, none) 255 | DEF( strict_neq, 1, 2, 1, none) 256 | DEF( and, 1, 2, 1, none) 257 | DEF( xor, 1, 2, 1, none) 258 | DEF( or, 1, 2, 1, none) 259 | DEF(is_undefined_or_null, 1, 1, 1, none) 260 | DEF( private_in, 1, 2, 1, none) 261 | #ifdef CONFIG_BIGNUM 262 | DEF( mul_pow10, 1, 2, 1, none) 263 | DEF( math_mod, 1, 2, 1, none) 264 | #endif 265 | /* must be the last non short and non temporary opcode */ 266 | DEF( nop, 1, 0, 0, none) 267 | 268 | /* temporary opcodes: never emitted in the final bytecode */ 269 | 270 | def( enter_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */ 271 | def( leave_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */ 272 | 273 | def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */ 274 | 275 | /* the following opcodes must be in the same order as the 'with_x' and 276 | get_var_undef, get_var and put_var opcodes */ 277 | def(scope_get_var_undef, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ 278 | def( scope_get_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ 279 | def( scope_put_var, 7, 1, 0, atom_u16) /* emitted in phase 1, removed in phase 2 */ 280 | def(scope_delete_var, 7, 0, 1, atom_u16) /* emitted in phase 1, removed in phase 2 */ 281 | def( scope_make_ref, 11, 0, 2, atom_label_u16) /* emitted in phase 1, removed in phase 2 */ 282 | def( scope_get_ref, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ 283 | def(scope_put_var_init, 7, 0, 2, atom_u16) /* emitted in phase 1, removed in phase 2 */ 284 | 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 */ 285 | def(scope_get_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */ 286 | def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */ 287 | def(scope_put_private_field, 7, 2, 0, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */ 288 | def(scope_in_private_field, 7, 1, 1, atom_u16) /* obj -> res emitted in phase 1, removed in phase 2 */ 289 | def(get_field_opt_chain, 5, 1, 1, atom) /* emitted in phase 1, removed in phase 2 */ 290 | def(get_array_el_opt_chain, 1, 2, 1, none) /* emitted in phase 1, removed in phase 2 */ 291 | def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */ 292 | 293 | def( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */ 294 | 295 | #if SHORT_OPCODES 296 | DEF( push_minus1, 1, 0, 1, none_int) 297 | DEF( push_0, 1, 0, 1, none_int) 298 | DEF( push_1, 1, 0, 1, none_int) 299 | DEF( push_2, 1, 0, 1, none_int) 300 | DEF( push_3, 1, 0, 1, none_int) 301 | DEF( push_4, 1, 0, 1, none_int) 302 | DEF( push_5, 1, 0, 1, none_int) 303 | DEF( push_6, 1, 0, 1, none_int) 304 | DEF( push_7, 1, 0, 1, none_int) 305 | DEF( push_i8, 2, 0, 1, i8) 306 | DEF( push_i16, 3, 0, 1, i16) 307 | DEF( push_const8, 2, 0, 1, const8) 308 | DEF( fclosure8, 2, 0, 1, const8) /* must follow push_const8 */ 309 | DEF(push_empty_string, 1, 0, 1, none) 310 | 311 | DEF( get_loc8, 2, 0, 1, loc8) 312 | DEF( put_loc8, 2, 1, 0, loc8) 313 | DEF( set_loc8, 2, 1, 1, loc8) 314 | 315 | DEF( get_loc0, 1, 0, 1, none_loc) 316 | DEF( get_loc1, 1, 0, 1, none_loc) 317 | DEF( get_loc2, 1, 0, 1, none_loc) 318 | DEF( get_loc3, 1, 0, 1, none_loc) 319 | DEF( put_loc0, 1, 1, 0, none_loc) 320 | DEF( put_loc1, 1, 1, 0, none_loc) 321 | DEF( put_loc2, 1, 1, 0, none_loc) 322 | DEF( put_loc3, 1, 1, 0, none_loc) 323 | DEF( set_loc0, 1, 1, 1, none_loc) 324 | DEF( set_loc1, 1, 1, 1, none_loc) 325 | DEF( set_loc2, 1, 1, 1, none_loc) 326 | DEF( set_loc3, 1, 1, 1, none_loc) 327 | DEF( get_arg0, 1, 0, 1, none_arg) 328 | DEF( get_arg1, 1, 0, 1, none_arg) 329 | DEF( get_arg2, 1, 0, 1, none_arg) 330 | DEF( get_arg3, 1, 0, 1, none_arg) 331 | DEF( put_arg0, 1, 1, 0, none_arg) 332 | DEF( put_arg1, 1, 1, 0, none_arg) 333 | DEF( put_arg2, 1, 1, 0, none_arg) 334 | DEF( put_arg3, 1, 1, 0, none_arg) 335 | DEF( set_arg0, 1, 1, 1, none_arg) 336 | DEF( set_arg1, 1, 1, 1, none_arg) 337 | DEF( set_arg2, 1, 1, 1, none_arg) 338 | DEF( set_arg3, 1, 1, 1, none_arg) 339 | DEF( get_var_ref0, 1, 0, 1, none_var_ref) 340 | DEF( get_var_ref1, 1, 0, 1, none_var_ref) 341 | DEF( get_var_ref2, 1, 0, 1, none_var_ref) 342 | DEF( get_var_ref3, 1, 0, 1, none_var_ref) 343 | DEF( put_var_ref0, 1, 1, 0, none_var_ref) 344 | DEF( put_var_ref1, 1, 1, 0, none_var_ref) 345 | DEF( put_var_ref2, 1, 1, 0, none_var_ref) 346 | DEF( put_var_ref3, 1, 1, 0, none_var_ref) 347 | DEF( set_var_ref0, 1, 1, 1, none_var_ref) 348 | DEF( set_var_ref1, 1, 1, 1, none_var_ref) 349 | DEF( set_var_ref2, 1, 1, 1, none_var_ref) 350 | DEF( set_var_ref3, 1, 1, 1, none_var_ref) 351 | 352 | DEF( get_length, 1, 1, 1, none) 353 | 354 | DEF( if_false8, 2, 1, 0, label8) 355 | DEF( if_true8, 2, 1, 0, label8) /* must come after if_false8 */ 356 | DEF( goto8, 2, 0, 0, label8) /* must come after if_true8 */ 357 | DEF( goto16, 3, 0, 0, label16) 358 | 359 | DEF( call0, 1, 1, 1, npopx) 360 | DEF( call1, 1, 1, 1, npopx) 361 | DEF( call2, 1, 1, 1, npopx) 362 | DEF( call3, 1, 1, 1, npopx) 363 | 364 | DEF( is_undefined, 1, 1, 1, none) 365 | DEF( is_null, 1, 1, 1, none) 366 | DEF(typeof_is_undefined, 1, 1, 1, none) 367 | DEF( typeof_is_function, 1, 1, 1, none) 368 | #endif 369 | 370 | #undef DEF 371 | #undef def 372 | #endif /* DEF */ 373 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | The main documentation is in doc/quickjs.pdf or doc/quickjs.html. 2 | -------------------------------------------------------------------------------- /release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # Release the QuickJS source code 3 | 4 | set -e 5 | 6 | version=`cat VERSION` 7 | 8 | if [ "$1" = "-h" ] ; then 9 | echo "release.sh [release_list]" 10 | echo "" 11 | echo "release_list: extras binary win_binary quickjs" 12 | 13 | exit 1 14 | fi 15 | 16 | release_list="extras binary win_binary quickjs" 17 | 18 | if [ "$1" != "" ] ; then 19 | release_list="$1" 20 | fi 21 | 22 | #################################################" 23 | # extras 24 | 25 | if echo $release_list | grep -w -q extras ; then 26 | 27 | d="quickjs-${version}" 28 | name="quickjs-extras-${version}" 29 | outdir="/tmp/${d}" 30 | 31 | rm -rf $outdir 32 | mkdir -p $outdir $outdir/unicode $outdir/tests 33 | 34 | cp unicode/* $outdir/unicode 35 | cp -a tests/bench-v8 $outdir/tests 36 | 37 | ( cd /tmp && tar Jcvf /tmp/${name}.tar.xz ${d} ) 38 | 39 | fi 40 | 41 | #################################################" 42 | # Windows binary release 43 | 44 | if echo $release_list | grep -w -q win_binary ; then 45 | 46 | # win64 47 | 48 | dlldir=/usr/x86_64-w64-mingw32/sys-root/mingw/bin 49 | cross_prefix="x86_64-w64-mingw32-" 50 | d="quickjs-win-x86_64-${version}" 51 | outdir="/tmp/${d}" 52 | 53 | rm -rf $outdir 54 | mkdir -p $outdir 55 | 56 | make CONFIG_WIN32=y qjs.exe 57 | cp qjs.exe $outdir 58 | ${cross_prefix}strip $outdir/qjs.exe 59 | cp $dlldir/libwinpthread-1.dll $outdir 60 | 61 | ( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . ) 62 | 63 | make CONFIG_WIN32=y clean 64 | 65 | # win32 66 | 67 | dlldir=/usr/i686-w64-mingw32/sys-root/mingw/bin 68 | cross_prefix="i686-w64-mingw32-" 69 | d="quickjs-win-i686-${version}" 70 | outdir="/tmp/${d}" 71 | 72 | rm -rf $outdir 73 | mkdir -p $outdir 74 | 75 | make clean 76 | make CONFIG_WIN32=y clean 77 | 78 | make CONFIG_WIN32=y CONFIG_M32=y qjs.exe 79 | cp qjs.exe $outdir 80 | ${cross_prefix}strip $outdir/qjs.exe 81 | cp $dlldir/libwinpthread-1.dll $outdir 82 | 83 | ( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . ) 84 | 85 | fi 86 | 87 | #################################################" 88 | # Linux binary release 89 | 90 | if echo $release_list | grep -w -q binary ; then 91 | 92 | make clean 93 | make CONFIG_WIN32=y clean 94 | make -j4 qjs run-test262 95 | make -j4 CONFIG_M32=y qjs32 run-test262-32 96 | strip qjs run-test262 qjs32 run-test262-32 97 | 98 | d="quickjs-linux-x86_64-${version}" 99 | outdir="/tmp/${d}" 100 | 101 | rm -rf $outdir 102 | mkdir -p $outdir 103 | 104 | cp qjs run-test262 $outdir 105 | 106 | ( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . ) 107 | 108 | d="quickjs-linux-i686-${version}" 109 | outdir="/tmp/${d}" 110 | 111 | rm -rf $outdir 112 | mkdir -p $outdir 113 | 114 | cp qjs32 $outdir/qjs 115 | cp run-test262-32 $outdir/run-test262 116 | 117 | ( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . ) 118 | 119 | fi 120 | 121 | #################################################" 122 | # quickjs 123 | 124 | if echo $release_list | grep -w -q quickjs ; then 125 | 126 | make build_doc 127 | 128 | d="quickjs-${version}" 129 | outdir="/tmp/${d}" 130 | 131 | rm -rf $outdir 132 | mkdir -p $outdir $outdir/doc $outdir/tests $outdir/examples 133 | 134 | cp Makefile VERSION TODO Changelog readme.txt LICENSE \ 135 | release.sh unicode_download.sh \ 136 | qjs.c qjsc.c qjscalc.js repl.js \ 137 | quickjs.c quickjs.h quickjs-atom.h \ 138 | quickjs-libc.c quickjs-libc.h quickjs-opcode.h \ 139 | cutils.c cutils.h list.h \ 140 | libregexp.c libregexp.h libregexp-opcode.h \ 141 | libunicode.c libunicode.h libunicode-table.h \ 142 | libbf.c libbf.h \ 143 | unicode_gen.c unicode_gen_def.h \ 144 | run-test262.c test262o.conf test262.conf \ 145 | test262o_errors.txt test262_errors.txt \ 146 | $outdir 147 | 148 | cp tests/*.js tests/*.patch tests/bjson.c $outdir/tests 149 | 150 | cp examples/*.js examples/*.c $outdir/examples 151 | 152 | cp doc/quickjs.texi doc/quickjs.pdf doc/quickjs.html \ 153 | doc/jsbignum.texi doc/jsbignum.html doc/jsbignum.pdf \ 154 | $outdir/doc 155 | 156 | ( cd /tmp && tar Jcvf /tmp/${d}.tar.xz ${d} ) 157 | 158 | fi 159 | -------------------------------------------------------------------------------- /test262.conf: -------------------------------------------------------------------------------- 1 | [config] 2 | # general settings for test262 ES6 version 3 | 4 | # framework style: old, new 5 | style=new 6 | 7 | # handle tests tagged as [noStrict]: yes, no, skip 8 | nostrict=yes 9 | 10 | # handle tests tagged as [strictOnly]: yes, no, skip 11 | strict=yes 12 | 13 | # test mode: default, default-nostrict, default-strict, strict, nostrict, both, all 14 | mode=default 15 | 16 | # handle tests flagged as [async]: yes, no, skip 17 | # for these, load 'harness/doneprintHandle.js' prior to test 18 | # and expect `print('Test262:AsyncTestComplete')` to be called for 19 | # successful termination 20 | async=yes 21 | 22 | # handle tests flagged as [module]: yes, no, skip 23 | module=yes 24 | 25 | # output error messages: yes, no 26 | verbose=yes 27 | 28 | # load harness files from this directory 29 | harnessdir=test262/harness 30 | 31 | # names of harness include files to skip 32 | #harnessexclude= 33 | 34 | # name of the error file for known errors 35 | errorfile=test262_errors.txt 36 | 37 | # exclude tests enumerated in this file (see also [exclude] section) 38 | #excludefile=test262_exclude.txt 39 | 40 | # report test results to this file 41 | reportfile=test262_report.txt 42 | 43 | # enumerate tests from this directory 44 | testdir=test262/test 45 | 46 | [features] 47 | # Standard language features and proposed extensions 48 | # list the features that are included 49 | # skipped features are tagged as such to avoid warnings 50 | # Keep this list alpha-sorted (:sort i in vim) 51 | 52 | __getter__ 53 | __proto__ 54 | __setter__ 55 | AggregateError 56 | align-detached-buffer-semantics-with-web-reality 57 | arbitrary-module-namespace-names=skip 58 | array-find-from-last 59 | array-grouping 60 | Array.fromAsync=skip 61 | Array.prototype.at 62 | Array.prototype.flat 63 | Array.prototype.flatMap 64 | Array.prototype.flatten 65 | Array.prototype.includes 66 | Array.prototype.values 67 | ArrayBuffer 68 | arraybuffer-transfer=skip 69 | arrow-function 70 | async-functions 71 | async-iteration 72 | Atomics 73 | Atomics.waitAsync=skip 74 | BigInt 75 | caller 76 | change-array-by-copy 77 | class 78 | class-fields-private 79 | class-fields-private-in 80 | class-fields-public 81 | class-methods-private 82 | class-static-block 83 | class-static-fields-private 84 | class-static-fields-public 85 | class-static-methods-private 86 | cleanupSome=skip 87 | coalesce-expression 88 | computed-property-names 89 | const 90 | cross-realm 91 | DataView 92 | DataView.prototype.getFloat32 93 | DataView.prototype.getFloat64 94 | DataView.prototype.getInt16 95 | DataView.prototype.getInt32 96 | DataView.prototype.getInt8 97 | DataView.prototype.getUint16 98 | DataView.prototype.getUint32 99 | DataView.prototype.setUint8 100 | decorators=skip 101 | default-parameters 102 | destructuring-assignment 103 | destructuring-binding 104 | dynamic-import 105 | error-cause 106 | exponentiation 107 | export-star-as-namespace-from-module 108 | FinalizationGroup=skip 109 | FinalizationRegistry.prototype.cleanupSome=skip 110 | FinalizationRegistry=skip 111 | Float32Array 112 | Float64Array 113 | for-in-order 114 | for-of 115 | generators 116 | globalThis 117 | hashbang 118 | host-gc-required=skip 119 | import-assertions=skip 120 | import-attributes=skip 121 | import.meta 122 | Int16Array 123 | Int32Array 124 | Int8Array 125 | IsHTMLDDA 126 | iterator-helpers=skip 127 | json-modules=skip 128 | json-parse-with-source=skip 129 | json-superset 130 | legacy-regexp=skip 131 | let 132 | logical-assignment-operators 133 | Map 134 | new.target 135 | numeric-separator-literal 136 | object-rest 137 | object-spread 138 | Object.fromEntries 139 | Object.hasOwn 140 | Object.is 141 | optional-catch-binding 142 | optional-chaining 143 | Promise 144 | promise-with-resolvers 145 | Promise.allSettled 146 | Promise.any 147 | Promise.prototype.finally 148 | Proxy 149 | proxy-missing-checks 150 | Reflect 151 | Reflect.construct 152 | Reflect.set 153 | Reflect.setPrototypeOf 154 | regexp-dotall 155 | regexp-duplicate-named-groups=skip 156 | regexp-lookbehind 157 | regexp-match-indices 158 | regexp-named-groups 159 | regexp-unicode-property-escapes 160 | regexp-v-flag=skip 161 | resizable-arraybuffer=skip 162 | rest-parameters 163 | Set 164 | set-methods=skip 165 | ShadowRealm=skip 166 | SharedArrayBuffer 167 | string-trimming 168 | String.fromCodePoint 169 | String.prototype.at 170 | String.prototype.endsWith 171 | String.prototype.includes 172 | String.prototype.isWellFormed 173 | String.prototype.matchAll 174 | String.prototype.replaceAll 175 | String.prototype.toWellFormed 176 | String.prototype.trimEnd 177 | String.prototype.trimStart 178 | super 179 | Symbol 180 | Symbol.asyncIterator 181 | Symbol.hasInstance 182 | Symbol.isConcatSpreadable 183 | Symbol.iterator 184 | Symbol.match 185 | Symbol.matchAll 186 | Symbol.prototype.description 187 | Symbol.replace 188 | Symbol.search 189 | Symbol.species 190 | Symbol.split 191 | Symbol.toPrimitive 192 | Symbol.toStringTag 193 | Symbol.unscopables 194 | symbols-as-weakmap-keys=skip 195 | tail-call-optimization=skip 196 | template 197 | Temporal=skip 198 | top-level-await 199 | TypedArray 200 | TypedArray.prototype.at 201 | u180e 202 | Uint16Array 203 | Uint32Array 204 | Uint8Array 205 | Uint8ClampedArray 206 | WeakMap 207 | WeakRef=skip 208 | WeakSet 209 | well-formed-json-stringify 210 | 211 | [exclude] 212 | # list excluded tests and directories here 213 | 214 | # intl not supported 215 | test262/test/intl402/ 216 | 217 | # incompatible with the "caller" feature 218 | test262/test/built-ins/Function/prototype/restricted-property-caller.js 219 | test262/test/built-ins/Function/prototype/restricted-property-arguments.js 220 | test262/test/built-ins/ThrowTypeError/unique-per-realm-function-proto.js 221 | 222 | # slow tests 223 | #test262/test/built-ins/RegExp/CharacterClassEscapes/ 224 | #test262/test/built-ins/RegExp/property-escapes/ 225 | 226 | [tests] 227 | # list test files or use config.testdir 228 | -------------------------------------------------------------------------------- /test262_errors.txt: -------------------------------------------------------------------------------- 1 | test262/test/annexB/language/eval-code/direct/script-decl-lex-collision-in-sloppy-mode.js:13: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all 2 | test262/test/language/expressions/assignment/target-member-computed-reference-null.js:32: Test262Error: Expected a DummyError but got a TypeError 3 | test262/test/language/expressions/assignment/target-member-computed-reference-null.js:32: strict mode: Test262Error: Expected a DummyError but got a TypeError 4 | test262/test/language/expressions/assignment/target-member-computed-reference-undefined.js:32: Test262Error: Expected a DummyError but got a TypeError 5 | test262/test/language/expressions/assignment/target-member-computed-reference-undefined.js:32: strict mode: Test262Error: Expected a DummyError but got a TypeError 6 | test262/test/language/expressions/in/private-field-invalid-assignment-target.js:23: unexpected error type: Test262: This statement should not be evaluated. 7 | test262/test/language/expressions/in/private-field-invalid-assignment-target.js:23: strict mode: unexpected error type: Test262: This statement should not be evaluated. 8 | test262/test/language/global-code/script-decl-lex-var-declared-via-eval-sloppy.js:13: Test262Error: variable Expected a SyntaxError to be thrown but no exception was thrown at all 9 | -------------------------------------------------------------------------------- /test262o_errors.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/second-state/quickjs-wasi/84589b6f6d1ff9752286cbab24bac24245b31d97/test262o_errors.txt -------------------------------------------------------------------------------- /tests/bjson.c: -------------------------------------------------------------------------------- 1 | /* 2 | * QuickJS: binary JSON module (test only) 3 | * 4 | * Copyright (c) 2017-2019 Fabrice Bellard 5 | * 6 | * Permission is hereby granted, free of charge, to any person obtaining a copy 7 | * of this software and associated documentation files (the "Software"), to deal 8 | * in the Software without restriction, including without limitation the rights 9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | * copies of the Software, and to permit persons to whom the Software is 11 | * furnished to do so, subject to the following conditions: 12 | * 13 | * The above copyright notice and this permission notice shall be included in 14 | * all copies or substantial portions of the Software. 15 | * 16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 | * THE SOFTWARE. 23 | */ 24 | #include "../quickjs-libc.h" 25 | #include "../cutils.h" 26 | 27 | static JSValue js_bjson_read(JSContext *ctx, JSValueConst this_val, 28 | int argc, JSValueConst *argv) 29 | { 30 | uint8_t *buf; 31 | uint64_t pos, len; 32 | JSValue obj; 33 | size_t size; 34 | int flags; 35 | 36 | if (JS_ToIndex(ctx, &pos, argv[1])) 37 | return JS_EXCEPTION; 38 | if (JS_ToIndex(ctx, &len, argv[2])) 39 | return JS_EXCEPTION; 40 | buf = JS_GetArrayBuffer(ctx, &size, argv[0]); 41 | if (!buf) 42 | return JS_EXCEPTION; 43 | if (pos + len > size) 44 | return JS_ThrowRangeError(ctx, "array buffer overflow"); 45 | flags = 0; 46 | if (JS_ToBool(ctx, argv[3])) 47 | flags |= JS_READ_OBJ_REFERENCE; 48 | obj = JS_ReadObject(ctx, buf + pos, len, flags); 49 | return obj; 50 | } 51 | 52 | static JSValue js_bjson_write(JSContext *ctx, JSValueConst this_val, 53 | int argc, JSValueConst *argv) 54 | { 55 | size_t len; 56 | uint8_t *buf; 57 | JSValue array; 58 | int flags; 59 | 60 | flags = 0; 61 | if (JS_ToBool(ctx, argv[1])) 62 | flags |= JS_WRITE_OBJ_REFERENCE; 63 | buf = JS_WriteObject(ctx, &len, argv[0], flags); 64 | if (!buf) 65 | return JS_EXCEPTION; 66 | array = JS_NewArrayBufferCopy(ctx, buf, len); 67 | js_free(ctx, buf); 68 | return array; 69 | } 70 | 71 | static const JSCFunctionListEntry js_bjson_funcs[] = { 72 | JS_CFUNC_DEF("read", 4, js_bjson_read ), 73 | JS_CFUNC_DEF("write", 2, js_bjson_write ), 74 | }; 75 | 76 | static int js_bjson_init(JSContext *ctx, JSModuleDef *m) 77 | { 78 | return JS_SetModuleExportList(ctx, m, js_bjson_funcs, 79 | countof(js_bjson_funcs)); 80 | } 81 | 82 | #ifdef JS_SHARED_LIBRARY 83 | #define JS_INIT_MODULE js_init_module 84 | #else 85 | #define JS_INIT_MODULE js_init_module_bjson 86 | #endif 87 | 88 | JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name) 89 | { 90 | JSModuleDef *m; 91 | m = JS_NewCModule(ctx, module_name, js_bjson_init); 92 | if (!m) 93 | return NULL; 94 | JS_AddModuleExportList(ctx, m, js_bjson_funcs, countof(js_bjson_funcs)); 95 | return m; 96 | } 97 | -------------------------------------------------------------------------------- /tests/test262.patch: -------------------------------------------------------------------------------- 1 | diff --git a/harness/atomicsHelper.js b/harness/atomicsHelper.js 2 | index 9c1217351e..3c24755558 100644 3 | --- a/harness/atomicsHelper.js 4 | +++ b/harness/atomicsHelper.js 5 | @@ -227,10 +227,14 @@ $262.agent.waitUntil = function(typedArray, index, expected) { 6 | * } 7 | */ 8 | $262.agent.timeouts = { 9 | - yield: 100, 10 | - small: 200, 11 | - long: 1000, 12 | - huge: 10000, 13 | +// yield: 100, 14 | +// small: 200, 15 | +// long: 1000, 16 | +// huge: 10000, 17 | + yield: 20, 18 | + small: 20, 19 | + long: 100, 20 | + huge: 1000, 21 | }; 22 | 23 | /** 24 | diff --git a/harness/regExpUtils.js b/harness/regExpUtils.js 25 | index be7039fda0..7b38abf8df 100644 26 | --- a/harness/regExpUtils.js 27 | +++ b/harness/regExpUtils.js 28 | @@ -6,24 +6,27 @@ description: | 29 | defines: [buildString, testPropertyEscapes, matchValidator] 30 | ---*/ 31 | 32 | +if ($262 && typeof $262.codePointRange === "function") { 33 | + /* use C function to build the codePointRange (much faster with 34 | + slow JS engines) */ 35 | + codePointRange = $262.codePointRange; 36 | +} else { 37 | + codePointRange = function codePointRange(start, end) { 38 | + const codePoints = []; 39 | + let length = 0; 40 | + for (codePoint = start; codePoint < end; codePoint++) { 41 | + codePoints[length++] = codePoint; 42 | + } 43 | + return String.fromCodePoint.apply(null, codePoints); 44 | + } 45 | +} 46 | + 47 | function buildString({ loneCodePoints, ranges }) { 48 | - const CHUNK_SIZE = 10000; 49 | - let result = Reflect.apply(String.fromCodePoint, null, loneCodePoints); 50 | - for (let i = 0; i < ranges.length; i++) { 51 | - const range = ranges[i]; 52 | - const start = range[0]; 53 | - const end = range[1]; 54 | - const codePoints = []; 55 | - for (let length = 0, codePoint = start; codePoint <= end; codePoint++) { 56 | - codePoints[length++] = codePoint; 57 | - if (length === CHUNK_SIZE) { 58 | - result += Reflect.apply(String.fromCodePoint, null, codePoints); 59 | - codePoints.length = length = 0; 60 | - } 61 | + let result = String.fromCodePoint.apply(null, loneCodePoints); 62 | + for (const [start, end] of ranges) { 63 | + result += codePointRange(start, end + 1); 64 | } 65 | - result += Reflect.apply(String.fromCodePoint, null, codePoints); 66 | - } 67 | - return result; 68 | + return result; 69 | } 70 | 71 | function testPropertyEscapes(regex, string, expression) { 72 | -------------------------------------------------------------------------------- /tests/test_bignum.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | function assert(actual, expected, message) { 4 | if (arguments.length == 1) 5 | expected = true; 6 | 7 | if (actual === expected) 8 | return; 9 | 10 | if (actual !== null && expected !== null 11 | && typeof actual == 'object' && typeof expected == 'object' 12 | && actual.toString() === expected.toString()) 13 | return; 14 | 15 | throw Error("assertion failed: got |" + actual + "|" + 16 | ", expected |" + expected + "|" + 17 | (message ? " (" + message + ")" : "")); 18 | } 19 | 20 | function assertThrows(err, func) 21 | { 22 | var ex; 23 | ex = false; 24 | try { 25 | func(); 26 | } catch(e) { 27 | ex = true; 28 | assert(e instanceof err); 29 | } 30 | assert(ex, true, "exception expected"); 31 | } 32 | 33 | // load more elaborate version of assert if available 34 | try { __loadScript("test_assert.js"); } catch(e) {} 35 | 36 | /*----------------*/ 37 | 38 | function bigint_pow(a, n) 39 | { 40 | var r, i; 41 | r = 1n; 42 | for(i = 0n; i < n; i++) 43 | r *= a; 44 | return r; 45 | } 46 | 47 | /* a must be < b */ 48 | function test_less(a, b) 49 | { 50 | assert(a < b); 51 | assert(!(b < a)); 52 | assert(a <= b); 53 | assert(!(b <= a)); 54 | assert(b > a); 55 | assert(!(a > b)); 56 | assert(b >= a); 57 | assert(!(a >= b)); 58 | assert(a != b); 59 | assert(!(a == b)); 60 | } 61 | 62 | /* a must be numerically equal to b */ 63 | function test_eq(a, b) 64 | { 65 | assert(a == b); 66 | assert(b == a); 67 | assert(!(a != b)); 68 | assert(!(b != a)); 69 | assert(a <= b); 70 | assert(b <= a); 71 | assert(!(a < b)); 72 | assert(a >= b); 73 | assert(b >= a); 74 | assert(!(a > b)); 75 | } 76 | 77 | function test_bigint1() 78 | { 79 | var a, r; 80 | 81 | test_less(2n, 3n); 82 | test_eq(3n, 3n); 83 | 84 | test_less(2, 3n); 85 | test_eq(3, 3n); 86 | 87 | test_less(2.1, 3n); 88 | test_eq(Math.sqrt(4), 2n); 89 | 90 | a = bigint_pow(3n, 100n); 91 | assert((a - 1n) != a); 92 | assert(a == 515377520732011331036461129765621272702107522001n); 93 | assert(a == 0x5a4653ca673768565b41f775d6947d55cf3813d1n); 94 | 95 | r = 1n << 31n; 96 | assert(r, 2147483648n, "1 << 31n === 2147483648n"); 97 | 98 | r = 1n << 32n; 99 | assert(r, 4294967296n, "1 << 32n === 4294967296n"); 100 | } 101 | 102 | function test_bigint2() 103 | { 104 | assert(BigInt(""), 0n); 105 | assert(BigInt(" 123"), 123n); 106 | assert(BigInt(" 123 "), 123n); 107 | assertThrows(SyntaxError, () => { BigInt("+") } ); 108 | assertThrows(SyntaxError, () => { BigInt("-") } ); 109 | assertThrows(SyntaxError, () => { BigInt("\x00a") } ); 110 | assertThrows(SyntaxError, () => { BigInt(" 123 r") } ); 111 | } 112 | 113 | function test_divrem(div1, a, b, q) 114 | { 115 | var div, divrem, t; 116 | div = BigInt[div1]; 117 | divrem = BigInt[div1 + "rem"]; 118 | assert(div(a, b) == q); 119 | t = divrem(a, b); 120 | assert(t[0] == q); 121 | assert(a == b * q + t[1]); 122 | } 123 | 124 | function test_idiv1(div, a, b, r) 125 | { 126 | test_divrem(div, a, b, r[0]); 127 | test_divrem(div, -a, b, r[1]); 128 | test_divrem(div, a, -b, r[2]); 129 | test_divrem(div, -a, -b, r[3]); 130 | } 131 | 132 | /* QuickJS BigInt extensions */ 133 | function test_bigint_ext() 134 | { 135 | var r; 136 | assert(BigInt.floorLog2(0n) === -1n); 137 | assert(BigInt.floorLog2(7n) === 2n); 138 | 139 | assert(BigInt.sqrt(0xffffffc000000000000000n) === 17592185913343n); 140 | r = BigInt.sqrtrem(0xffffffc000000000000000n); 141 | assert(r[0] === 17592185913343n); 142 | assert(r[1] === 35167191957503n); 143 | 144 | test_idiv1("tdiv", 3n, 2n, [1n, -1n, -1n, 1n]); 145 | test_idiv1("fdiv", 3n, 2n, [1n, -2n, -2n, 1n]); 146 | test_idiv1("cdiv", 3n, 2n, [2n, -1n, -1n, 2n]); 147 | test_idiv1("ediv", 3n, 2n, [1n, -2n, -1n, 2n]); 148 | } 149 | 150 | function test_bigfloat() 151 | { 152 | var e, a, b, sqrt2; 153 | 154 | assert(typeof 1n === "bigint"); 155 | assert(typeof 1l === "bigfloat"); 156 | assert(1 == 1.0l); 157 | assert(1 !== 1.0l); 158 | 159 | test_less(2l, 3l); 160 | test_eq(3l, 3l); 161 | 162 | test_less(2, 3l); 163 | test_eq(3, 3l); 164 | 165 | test_less(2.1, 3l); 166 | test_eq(Math.sqrt(9), 3l); 167 | 168 | test_less(2n, 3l); 169 | test_eq(3n, 3l); 170 | 171 | e = new BigFloatEnv(128); 172 | assert(e.prec == 128); 173 | a = BigFloat.sqrt(2l, e); 174 | assert(a === BigFloat.parseFloat("0x1.6a09e667f3bcc908b2fb1366ea957d3e", 0, e)); 175 | assert(e.inexact === true); 176 | assert(BigFloat.fpRound(a) == 0x1.6a09e667f3bcc908b2fb1366ea95l); 177 | 178 | b = BigFloatEnv.setPrec(BigFloat.sqrt.bind(null, 2), 128); 179 | assert(a === b); 180 | 181 | assert(BigFloat.isNaN(BigFloat(NaN))); 182 | assert(BigFloat.isFinite(1l)); 183 | assert(!BigFloat.isFinite(1l/0l)); 184 | 185 | assert(BigFloat.abs(-3l) === 3l); 186 | assert(BigFloat.sign(-3l) === -1l); 187 | 188 | assert(BigFloat.exp(0.2l) === 1.2214027581601698339210719946396742l); 189 | assert(BigFloat.log(3l) === 1.0986122886681096913952452369225256l); 190 | assert(BigFloat.pow(2.1l, 1.6l) === 3.277561666451861947162828744873745l); 191 | 192 | assert(BigFloat.sin(-1l) === -0.841470984807896506652502321630299l); 193 | assert(BigFloat.cos(1l) === 0.5403023058681397174009366074429766l); 194 | assert(BigFloat.tan(0.1l) === 0.10033467208545054505808004578111154l); 195 | 196 | assert(BigFloat.asin(0.3l) === 0.30469265401539750797200296122752915l); 197 | assert(BigFloat.acos(0.4l) === 1.1592794807274085998465837940224159l); 198 | assert(BigFloat.atan(0.7l) === 0.610725964389208616543758876490236l); 199 | assert(BigFloat.atan2(7.1l, -5.1l) === 2.1937053809751415549388104628759813l); 200 | 201 | assert(BigFloat.floor(2.5l) === 2l); 202 | assert(BigFloat.ceil(2.5l) === 3l); 203 | assert(BigFloat.trunc(-2.5l) === -2l); 204 | assert(BigFloat.round(2.5l) === 3l); 205 | 206 | assert(BigFloat.fmod(3l,2l) === 1l); 207 | assert(BigFloat.remainder(3l,2l) === -1l); 208 | 209 | /* string conversion */ 210 | assert((1234.125l).toString(), "1234.125"); 211 | assert((1234.125l).toFixed(2), "1234.13"); 212 | assert((1234.125l).toFixed(2, "down"), "1234.12"); 213 | assert((1234.125l).toExponential(), "1.234125e+3"); 214 | assert((1234.125l).toExponential(5), "1.23413e+3"); 215 | assert((1234.125l).toExponential(5, BigFloatEnv.RNDZ), "1.23412e+3"); 216 | assert((1234.125l).toPrecision(6), "1234.13"); 217 | assert((1234.125l).toPrecision(6, BigFloatEnv.RNDZ), "1234.12"); 218 | 219 | /* string conversion with binary base */ 220 | assert((0x123.438l).toString(16), "123.438"); 221 | assert((0x323.438l).toString(16), "323.438"); 222 | assert((0x723.438l).toString(16), "723.438"); 223 | assert((0xf23.438l).toString(16), "f23.438"); 224 | assert((0x123.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "123.44"); 225 | assert((0x323.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "323.44"); 226 | assert((0x723.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "723.44"); 227 | assert((0xf23.438l).toFixed(2, BigFloatEnv.RNDNA, 16), "f23.44"); 228 | assert((0x0.0000438l).toFixed(6, BigFloatEnv.RNDNA, 16), "0.000044"); 229 | assert((0x1230000000l).toFixed(1, BigFloatEnv.RNDNA, 16), "1230000000.0"); 230 | assert((0x123.438l).toPrecision(5, BigFloatEnv.RNDNA, 16), "123.44"); 231 | assert((0x123.438l).toPrecision(5, BigFloatEnv.RNDZ, 16), "123.43"); 232 | assert((0x323.438l).toPrecision(5, BigFloatEnv.RNDNA, 16), "323.44"); 233 | assert((0x723.438l).toPrecision(5, BigFloatEnv.RNDNA, 16), "723.44"); 234 | assert((-0xf23.438l).toPrecision(5, BigFloatEnv.RNDD, 16), "-f23.44"); 235 | assert((0x123.438l).toExponential(4, BigFloatEnv.RNDNA, 16), "1.2344p+8"); 236 | } 237 | 238 | function test_bigdecimal() 239 | { 240 | assert(1m === 1m); 241 | assert(1m !== 2m); 242 | test_less(1m, 2m); 243 | test_eq(2m, 2m); 244 | 245 | test_less(1, 2m); 246 | test_eq(2, 2m); 247 | 248 | test_less(1.1, 2m); 249 | test_eq(Math.sqrt(4), 2m); 250 | 251 | test_less(2n, 3m); 252 | test_eq(3n, 3m); 253 | 254 | assert(BigDecimal("1234.1") === 1234.1m); 255 | assert(BigDecimal(" 1234.1") === 1234.1m); 256 | assert(BigDecimal(" 1234.1 ") === 1234.1m); 257 | 258 | assert(BigDecimal(0.1) === 0.1m); 259 | assert(BigDecimal(123) === 123m); 260 | assert(BigDecimal(true) === 1m); 261 | 262 | assert(123m + 1m === 124m); 263 | assert(123m - 1m === 122m); 264 | 265 | assert(3.2m * 3m === 9.6m); 266 | assert(10m / 2m === 5m); 267 | assertThrows(RangeError, () => { 10m / 3m } ); 268 | 269 | assert(10m % 3m === 1m); 270 | assert(-10m % 3m === -1m); 271 | 272 | assert(1234.5m ** 3m === 1881365963.625m); 273 | assertThrows(RangeError, () => { 2m ** 3.1m } ); 274 | assertThrows(RangeError, () => { 2m ** -3m } ); 275 | 276 | assert(BigDecimal.sqrt(2m, 277 | { roundingMode: "half-even", 278 | maximumSignificantDigits: 4 }) === 1.414m); 279 | assert(BigDecimal.sqrt(101m, 280 | { roundingMode: "half-even", 281 | maximumFractionDigits: 3 }) === 10.050m); 282 | assert(BigDecimal.sqrt(0.002m, 283 | { roundingMode: "half-even", 284 | maximumFractionDigits: 3 }) === 0.045m); 285 | 286 | assert(BigDecimal.round(3.14159m, 287 | { roundingMode: "half-even", 288 | maximumFractionDigits: 3 }) === 3.142m); 289 | 290 | assert(BigDecimal.add(3.14159m, 0.31212m, 291 | { roundingMode: "half-even", 292 | maximumFractionDigits: 2 }) === 3.45m); 293 | assert(BigDecimal.sub(3.14159m, 0.31212m, 294 | { roundingMode: "down", 295 | maximumFractionDigits: 2 }) === 2.82m); 296 | assert(BigDecimal.mul(3.14159m, 0.31212m, 297 | { roundingMode: "half-even", 298 | maximumFractionDigits: 3 }) === 0.981m); 299 | assert(BigDecimal.mod(3.14159m, 0.31211m, 300 | { roundingMode: "half-even", 301 | maximumFractionDigits: 4 }) === 0.0205m); 302 | assert(BigDecimal.div(20m, 3m, 303 | { roundingMode: "half-even", 304 | maximumSignificantDigits: 3 }) === 6.67m); 305 | assert(BigDecimal.div(20m, 3m, 306 | { roundingMode: "half-even", 307 | maximumFractionDigits: 50 }) === 308 | 6.66666666666666666666666666666666666666666666666667m); 309 | 310 | /* string conversion */ 311 | assert((1234.125m).toString(), "1234.125"); 312 | assert((1234.125m).toFixed(2), "1234.13"); 313 | assert((1234.125m).toFixed(2, "down"), "1234.12"); 314 | assert((1234.125m).toExponential(), "1.234125e+3"); 315 | assert((1234.125m).toExponential(5), "1.23413e+3"); 316 | assert((1234.125m).toExponential(5, "down"), "1.23412e+3"); 317 | assert((1234.125m).toPrecision(6), "1234.13"); 318 | assert((1234.125m).toPrecision(6, "down"), "1234.12"); 319 | assert((-1234.125m).toPrecision(6, "floor"), "-1234.13"); 320 | } 321 | 322 | test_bigint1(); 323 | test_bigint2(); 324 | test_bigint_ext(); 325 | test_bigfloat(); 326 | test_bigdecimal(); 327 | -------------------------------------------------------------------------------- /tests/test_bjson.js: -------------------------------------------------------------------------------- 1 | import * as bjson from "./bjson.so"; 2 | 3 | function assert(actual, expected, message) { 4 | if (arguments.length == 1) 5 | expected = true; 6 | 7 | if (actual === expected) 8 | return; 9 | 10 | if (actual !== null && expected !== null 11 | && typeof actual == 'object' && typeof expected == 'object' 12 | && actual.toString() === expected.toString()) 13 | return; 14 | 15 | throw Error("assertion failed: got |" + actual + "|" + 16 | ", expected |" + expected + "|" + 17 | (message ? " (" + message + ")" : "")); 18 | } 19 | 20 | function toHex(a) 21 | { 22 | var i, s = "", tab, v; 23 | tab = new Uint8Array(a); 24 | for(i = 0; i < tab.length; i++) { 25 | v = tab[i].toString(16); 26 | if (v.length < 2) 27 | v = "0" + v; 28 | if (i !== 0) 29 | s += " "; 30 | s += v; 31 | } 32 | return s; 33 | } 34 | 35 | function isArrayLike(a) 36 | { 37 | return Array.isArray(a) || 38 | (a instanceof Uint8ClampedArray) || 39 | (a instanceof Uint8Array) || 40 | (a instanceof Uint16Array) || 41 | (a instanceof Uint32Array) || 42 | (a instanceof Int8Array) || 43 | (a instanceof Int16Array) || 44 | (a instanceof Int32Array) || 45 | (a instanceof Float32Array) || 46 | (a instanceof Float64Array); 47 | } 48 | 49 | function toStr(a) 50 | { 51 | var s, i, props, prop; 52 | 53 | switch(typeof(a)) { 54 | case "object": 55 | if (a === null) 56 | return "null"; 57 | if (a instanceof Date) { 58 | s = "Date(" + toStr(a.valueOf()) + ")"; 59 | } else if (a instanceof Number) { 60 | s = "Number(" + toStr(a.valueOf()) + ")"; 61 | } else if (a instanceof String) { 62 | s = "String(" + toStr(a.valueOf()) + ")"; 63 | } else if (a instanceof Boolean) { 64 | s = "Boolean(" + toStr(a.valueOf()) + ")"; 65 | } else if (isArrayLike(a)) { 66 | s = "["; 67 | for(i = 0; i < a.length; i++) { 68 | if (i != 0) 69 | s += ","; 70 | s += toStr(a[i]); 71 | } 72 | s += "]"; 73 | } else { 74 | props = Object.keys(a); 75 | s = "{"; 76 | for(i = 0; i < props.length; i++) { 77 | if (i != 0) 78 | s += ","; 79 | prop = props[i]; 80 | s += prop + ":" + toStr(a[prop]); 81 | } 82 | s += "}"; 83 | } 84 | return s; 85 | case "undefined": 86 | return "undefined"; 87 | case "string": 88 | return a.__quote(); 89 | case "number": 90 | case "bigfloat": 91 | if (a == 0 && 1 / a < 0) 92 | return "-0"; 93 | else 94 | return a.toString(); 95 | break; 96 | default: 97 | return a.toString(); 98 | } 99 | } 100 | 101 | function bjson_test(a) 102 | { 103 | var buf, r, a_str, r_str; 104 | a_str = toStr(a); 105 | buf = bjson.write(a); 106 | if (0) { 107 | print(a_str, "->", toHex(buf)); 108 | } 109 | r = bjson.read(buf, 0, buf.byteLength); 110 | r_str = toStr(r); 111 | if (a_str != r_str) { 112 | print(a_str); 113 | print(r_str); 114 | assert(false); 115 | } 116 | } 117 | 118 | /* test multiple references to an object including circular 119 | references */ 120 | function bjson_test_reference() 121 | { 122 | var array, buf, i, n, array_buffer; 123 | n = 16; 124 | array = []; 125 | for(i = 0; i < n; i++) 126 | array[i] = {}; 127 | array_buffer = new ArrayBuffer(n); 128 | for(i = 0; i < n; i++) { 129 | array[i].next = array[(i + 1) % n]; 130 | array[i].idx = i; 131 | array[i].typed_array = new Uint8Array(array_buffer, i, 1); 132 | } 133 | buf = bjson.write(array, true); 134 | 135 | array = bjson.read(buf, 0, buf.byteLength, true); 136 | 137 | /* check the result */ 138 | for(i = 0; i < n; i++) { 139 | assert(array[i].next, array[(i + 1) % n]); 140 | assert(array[i].idx, i); 141 | assert(array[i].typed_array.buffer, array_buffer); 142 | assert(array[i].typed_array.length, 1); 143 | assert(array[i].typed_array.byteOffset, i); 144 | } 145 | } 146 | 147 | function bjson_test_all() 148 | { 149 | var obj; 150 | 151 | bjson_test({x:1, y:2, if:3}); 152 | bjson_test([1, 2, 3]); 153 | bjson_test([1.0, "aa", true, false, undefined, null, NaN, -Infinity, -0.0]); 154 | if (typeof BigInt !== "undefined") { 155 | bjson_test([BigInt("1"), -BigInt("0x123456789"), 156 | BigInt("0x123456789abcdef123456789abcdef")]); 157 | } 158 | if (typeof BigFloat !== "undefined") { 159 | BigFloatEnv.setPrec(function () { 160 | bjson_test([BigFloat("0.1"), BigFloat("-1e30"), BigFloat("0"), 161 | BigFloat("-0"), BigFloat("Infinity"), BigFloat("-Infinity"), 162 | 0.0 / BigFloat("0"), BigFloat.MAX_VALUE, 163 | BigFloat.MIN_VALUE]); 164 | }, 113, 15); 165 | } 166 | if (typeof BigDecimal !== "undefined") { 167 | bjson_test([BigDecimal("0"), 168 | BigDecimal("0.8"), BigDecimal("123321312321321e100"), 169 | BigDecimal("-1233213123213214332333223332e100"), 170 | BigDecimal("1.233e-1000")]); 171 | } 172 | 173 | bjson_test([new Date(1234), new String("abc"), new Number(-12.1), new Boolean(true)]); 174 | 175 | bjson_test(new Int32Array([123123, 222111, -32222])); 176 | bjson_test(new Float64Array([123123, 222111.5])); 177 | 178 | /* tested with a circular reference */ 179 | obj = {}; 180 | obj.x = obj; 181 | try { 182 | bjson.write(obj); 183 | assert(false); 184 | } catch(e) { 185 | assert(e instanceof TypeError); 186 | } 187 | 188 | bjson_test_reference(); 189 | } 190 | 191 | bjson_test_all(); 192 | -------------------------------------------------------------------------------- /tests/test_closure.js: -------------------------------------------------------------------------------- 1 | function assert(actual, expected, message) { 2 | if (arguments.length == 1) 3 | expected = true; 4 | 5 | if (actual === expected) 6 | return; 7 | 8 | if (actual !== null && expected !== null 9 | && typeof actual == 'object' && typeof expected == 'object' 10 | && actual.toString() === expected.toString()) 11 | return; 12 | 13 | throw Error("assertion failed: got |" + actual + "|" + 14 | ", expected |" + expected + "|" + 15 | (message ? " (" + message + ")" : "")); 16 | } 17 | 18 | // load more elaborate version of assert if available 19 | try { __loadScript("test_assert.js"); } catch(e) {} 20 | 21 | /*----------------*/ 22 | 23 | var log_str = ""; 24 | 25 | function log(str) 26 | { 27 | log_str += str + ","; 28 | } 29 | 30 | function f(a, b, c) 31 | { 32 | var x = 10; 33 | log("a="+a); 34 | function g(d) { 35 | function h() { 36 | log("d=" + d); 37 | log("x=" + x); 38 | } 39 | log("b=" + b); 40 | log("c=" + c); 41 | h(); 42 | } 43 | g(4); 44 | return g; 45 | } 46 | 47 | var g1 = f(1, 2, 3); 48 | g1(5); 49 | 50 | assert(log_str, "a=1,b=2,c=3,d=4,x=10,b=2,c=3,d=5,x=10,", "closure1"); 51 | 52 | function test_closure1() 53 | { 54 | function f2() 55 | { 56 | var val = 1; 57 | 58 | function set(a) { 59 | val = a; 60 | } 61 | function get(a) { 62 | return val; 63 | } 64 | return { "set": set, "get": get }; 65 | } 66 | 67 | var obj = f2(); 68 | obj.set(10); 69 | var r; 70 | r = obj.get(); 71 | assert(r, 10, "closure2"); 72 | } 73 | 74 | function test_closure2() 75 | { 76 | var expr_func = function myfunc1(n) { 77 | function myfunc2(n) { 78 | return myfunc1(n - 1); 79 | } 80 | if (n == 0) 81 | return 0; 82 | else 83 | return myfunc2(n); 84 | }; 85 | var r; 86 | r = expr_func(1); 87 | assert(r, 0, "expr_func"); 88 | } 89 | 90 | function test_closure3() 91 | { 92 | function fib(n) 93 | { 94 | if (n <= 0) 95 | return 0; 96 | else if (n == 1) 97 | return 1; 98 | else 99 | return fib(n - 1) + fib(n - 2); 100 | } 101 | 102 | var fib_func = function fib1(n) 103 | { 104 | if (n <= 0) 105 | return 0; 106 | else if (n == 1) 107 | return 1; 108 | else 109 | return fib1(n - 1) + fib1(n - 2); 110 | }; 111 | 112 | assert(fib(6), 8, "fib"); 113 | assert(fib_func(6), 8, "fib_func"); 114 | } 115 | 116 | function test_arrow_function() 117 | { 118 | "use strict"; 119 | 120 | function f1() { 121 | return (() => arguments)(); 122 | } 123 | function f2() { 124 | return (() => this)(); 125 | } 126 | function f3() { 127 | return (() => eval("this"))(); 128 | } 129 | function f4() { 130 | return (() => eval("new.target"))(); 131 | } 132 | var a; 133 | 134 | a = f1(1, 2); 135 | assert(a.length, 2); 136 | assert(a[0] === 1 && a[1] === 2); 137 | 138 | assert(f2.call("this_val") === "this_val"); 139 | assert(f3.call("this_val") === "this_val"); 140 | assert(new f4() === f4); 141 | 142 | var o1 = { f() { return this; } }; 143 | var o2 = { f() { 144 | return (() => eval("super.f()"))(); 145 | } }; 146 | o2.__proto__ = o1; 147 | 148 | assert(o2.f() === o2); 149 | } 150 | 151 | function test_with() 152 | { 153 | var o1 = { x: "o1", y: "o1" }; 154 | var x = "local"; 155 | eval('var z="var_obj";'); 156 | assert(z === "var_obj"); 157 | with (o1) { 158 | assert(x === "o1"); 159 | assert(eval("x") === "o1"); 160 | var f = function () { 161 | o2 = { x: "o2" }; 162 | with (o2) { 163 | assert(x === "o2"); 164 | assert(y === "o1"); 165 | assert(z === "var_obj"); 166 | assert(eval("x") === "o2"); 167 | assert(eval("y") === "o1"); 168 | assert(eval("z") === "var_obj"); 169 | assert(eval('eval("x")') === "o2"); 170 | } 171 | }; 172 | f(); 173 | } 174 | } 175 | 176 | function test_eval_closure() 177 | { 178 | var tab; 179 | 180 | tab = []; 181 | for(let i = 0; i < 3; i++) { 182 | eval("tab.push(function g1() { return i; })"); 183 | } 184 | for(let i = 0; i < 3; i++) { 185 | assert(tab[i]() === i); 186 | } 187 | 188 | tab = []; 189 | for(let i = 0; i < 3; i++) { 190 | let f = function f() { 191 | eval("tab.push(function g2() { return i; })"); 192 | }; 193 | f(); 194 | } 195 | for(let i = 0; i < 3; i++) { 196 | assert(tab[i]() === i); 197 | } 198 | } 199 | 200 | function test_eval_const() 201 | { 202 | const a = 1; 203 | var success = false; 204 | var f = function () { 205 | eval("a = 1"); 206 | }; 207 | try { 208 | f(); 209 | } catch(e) { 210 | success = (e instanceof TypeError); 211 | } 212 | assert(success); 213 | } 214 | 215 | test_closure1(); 216 | test_closure2(); 217 | test_closure3(); 218 | test_arrow_function(); 219 | test_with(); 220 | test_eval_closure(); 221 | test_eval_const(); 222 | -------------------------------------------------------------------------------- /tests/test_language.js: -------------------------------------------------------------------------------- 1 | function assert(actual, expected, message) { 2 | if (arguments.length == 1) 3 | expected = true; 4 | 5 | if (actual === expected) 6 | return; 7 | 8 | if (actual !== null && expected !== null 9 | && typeof actual == 'object' && typeof expected == 'object' 10 | && actual.toString() === expected.toString()) 11 | return; 12 | 13 | throw Error("assertion failed: got |" + actual + "|" + 14 | ", expected |" + expected + "|" + 15 | (message ? " (" + message + ")" : "")); 16 | } 17 | 18 | function assert_throws(expected_error, func) 19 | { 20 | var err = false; 21 | try { 22 | func(); 23 | } catch(e) { 24 | err = true; 25 | if (!(e instanceof expected_error)) { 26 | throw Error("unexpected exception type"); 27 | } 28 | } 29 | if (!err) { 30 | throw Error("expected exception"); 31 | } 32 | } 33 | 34 | // load more elaborate version of assert if available 35 | try { __loadScript("test_assert.js"); } catch(e) {} 36 | 37 | /*----------------*/ 38 | 39 | function test_op1() 40 | { 41 | var r, a; 42 | r = 1 + 2; 43 | assert(r, 3, "1 + 2 === 3"); 44 | 45 | r = 1 - 2; 46 | assert(r, -1, "1 - 2 === -1"); 47 | 48 | r = -1; 49 | assert(r, -1, "-1 === -1"); 50 | 51 | r = +2; 52 | assert(r, 2, "+2 === 2"); 53 | 54 | r = 2 * 3; 55 | assert(r, 6, "2 * 3 === 6"); 56 | 57 | r = 4 / 2; 58 | assert(r, 2, "4 / 2 === 2"); 59 | 60 | r = 4 % 3; 61 | assert(r, 1, "4 % 3 === 3"); 62 | 63 | r = 4 << 2; 64 | assert(r, 16, "4 << 2 === 16"); 65 | 66 | r = 1 << 0; 67 | assert(r, 1, "1 << 0 === 1"); 68 | 69 | r = 1 << 31; 70 | assert(r, -2147483648, "1 << 31 === -2147483648"); 71 | 72 | r = 1 << 32; 73 | assert(r, 1, "1 << 32 === 1"); 74 | 75 | r = (1 << 31) < 0; 76 | assert(r, true, "(1 << 31) < 0 === true"); 77 | 78 | r = -4 >> 1; 79 | assert(r, -2, "-4 >> 1 === -2"); 80 | 81 | r = -4 >>> 1; 82 | assert(r, 0x7ffffffe, "-4 >>> 1 === 0x7ffffffe"); 83 | 84 | r = 1 & 1; 85 | assert(r, 1, "1 & 1 === 1"); 86 | 87 | r = 0 | 1; 88 | assert(r, 1, "0 | 1 === 1"); 89 | 90 | r = 1 ^ 1; 91 | assert(r, 0, "1 ^ 1 === 0"); 92 | 93 | r = ~1; 94 | assert(r, -2, "~1 === -2"); 95 | 96 | r = !1; 97 | assert(r, false, "!1 === false"); 98 | 99 | assert((1 < 2), true, "(1 < 2) === true"); 100 | 101 | assert((2 > 1), true, "(2 > 1) === true"); 102 | 103 | assert(('b' > 'a'), true, "('b' > 'a') === true"); 104 | 105 | assert(2 ** 8, 256, "2 ** 8 === 256"); 106 | } 107 | 108 | function test_cvt() 109 | { 110 | assert((NaN | 0) === 0); 111 | assert((Infinity | 0) === 0); 112 | assert(((-Infinity) | 0) === 0); 113 | assert(("12345" | 0) === 12345); 114 | assert(("0x12345" | 0) === 0x12345); 115 | assert(((4294967296 * 3 - 4) | 0) === -4); 116 | 117 | assert(("12345" >>> 0) === 12345); 118 | assert(("0x12345" >>> 0) === 0x12345); 119 | assert((NaN >>> 0) === 0); 120 | assert((Infinity >>> 0) === 0); 121 | assert(((-Infinity) >>> 0) === 0); 122 | assert(((4294967296 * 3 - 4) >>> 0) === (4294967296 - 4)); 123 | assert((19686109595169230000).toString() === "19686109595169230000"); 124 | } 125 | 126 | function test_eq() 127 | { 128 | assert(null == undefined); 129 | assert(undefined == null); 130 | assert(true == 1); 131 | assert(0 == false); 132 | assert("" == 0); 133 | assert("123" == 123); 134 | assert("122" != 123); 135 | assert((new Number(1)) == 1); 136 | assert(2 == (new Number(2))); 137 | assert((new String("abc")) == "abc"); 138 | assert({} != "abc"); 139 | } 140 | 141 | function test_inc_dec() 142 | { 143 | var a, r; 144 | 145 | a = 1; 146 | r = a++; 147 | assert(r === 1 && a === 2, true, "++"); 148 | 149 | a = 1; 150 | r = ++a; 151 | assert(r === 2 && a === 2, true, "++"); 152 | 153 | a = 1; 154 | r = a--; 155 | assert(r === 1 && a === 0, true, "--"); 156 | 157 | a = 1; 158 | r = --a; 159 | assert(r === 0 && a === 0, true, "--"); 160 | 161 | a = {x:true}; 162 | a.x++; 163 | assert(a.x, 2, "++"); 164 | 165 | a = {x:true}; 166 | a.x--; 167 | assert(a.x, 0, "--"); 168 | 169 | a = [true]; 170 | a[0]++; 171 | assert(a[0], 2, "++"); 172 | 173 | a = {x:true}; 174 | r = a.x++; 175 | assert(r === 1 && a.x === 2, true, "++"); 176 | 177 | a = {x:true}; 178 | r = a.x--; 179 | assert(r === 1 && a.x === 0, true, "--"); 180 | 181 | a = [true]; 182 | r = a[0]++; 183 | assert(r === 1 && a[0] === 2, true, "++"); 184 | 185 | a = [true]; 186 | r = a[0]--; 187 | assert(r === 1 && a[0] === 0, true, "--"); 188 | } 189 | 190 | function F(x) 191 | { 192 | this.x = x; 193 | } 194 | 195 | function test_op2() 196 | { 197 | var a, b; 198 | a = new Object; 199 | a.x = 1; 200 | assert(a.x, 1, "new"); 201 | b = new F(2); 202 | assert(b.x, 2, "new"); 203 | 204 | a = {x : 2}; 205 | assert(("x" in a), true, "in"); 206 | assert(("y" in a), false, "in"); 207 | 208 | a = {}; 209 | assert((a instanceof Object), true, "instanceof"); 210 | assert((a instanceof String), false, "instanceof"); 211 | 212 | assert((typeof 1), "number", "typeof"); 213 | assert((typeof Object), "function", "typeof"); 214 | assert((typeof null), "object", "typeof"); 215 | assert((typeof unknown_var), "undefined", "typeof"); 216 | 217 | a = {x: 1, if: 2, async: 3}; 218 | assert(a.if === 2); 219 | assert(a.async === 3); 220 | } 221 | 222 | function test_delete() 223 | { 224 | var a, err; 225 | 226 | a = {x: 1, y: 1}; 227 | assert((delete a.x), true, "delete"); 228 | assert(("x" in a), false, "delete"); 229 | 230 | /* the following are not tested by test262 */ 231 | assert(delete "abc"[100], true); 232 | 233 | err = false; 234 | try { 235 | delete null.a; 236 | } catch(e) { 237 | err = (e instanceof TypeError); 238 | } 239 | assert(err, true, "delete"); 240 | 241 | err = false; 242 | try { 243 | a = { f() { delete super.a; } }; 244 | a.f(); 245 | } catch(e) { 246 | err = (e instanceof ReferenceError); 247 | } 248 | assert(err, true, "delete"); 249 | } 250 | 251 | function test_prototype() 252 | { 253 | var f = function f() { }; 254 | assert(f.prototype.constructor, f, "prototype"); 255 | 256 | var g = function g() { }; 257 | /* QuickJS bug */ 258 | Object.defineProperty(g, "prototype", { writable: false }); 259 | assert(g.prototype.constructor, g, "prototype"); 260 | } 261 | 262 | function test_arguments() 263 | { 264 | function f2() { 265 | assert(arguments.length, 2, "arguments"); 266 | assert(arguments[0], 1, "arguments"); 267 | assert(arguments[1], 3, "arguments"); 268 | } 269 | f2(1, 3); 270 | } 271 | 272 | function test_class() 273 | { 274 | var o; 275 | class C { 276 | constructor() { 277 | this.x = 10; 278 | } 279 | f() { 280 | return 1; 281 | } 282 | static F() { 283 | return -1; 284 | } 285 | get y() { 286 | return 12; 287 | } 288 | }; 289 | class D extends C { 290 | constructor() { 291 | super(); 292 | this.z = 20; 293 | } 294 | g() { 295 | return 2; 296 | } 297 | static G() { 298 | return -2; 299 | } 300 | h() { 301 | return super.f(); 302 | } 303 | static H() { 304 | return super["F"](); 305 | } 306 | } 307 | 308 | assert(C.F() === -1); 309 | assert(Object.getOwnPropertyDescriptor(C.prototype, "y").get.name === "get y"); 310 | 311 | o = new C(); 312 | assert(o.f() === 1); 313 | assert(o.x === 10); 314 | 315 | assert(D.F() === -1); 316 | assert(D.G() === -2); 317 | assert(D.H() === -1); 318 | 319 | o = new D(); 320 | assert(o.f() === 1); 321 | assert(o.g() === 2); 322 | assert(o.x === 10); 323 | assert(o.z === 20); 324 | assert(o.h() === 1); 325 | 326 | /* test class name scope */ 327 | var E1 = class E { static F() { return E; } }; 328 | assert(E1 === E1.F()); 329 | 330 | class S { 331 | static x = 42; 332 | static y = S.x; 333 | static z = this.x; 334 | } 335 | assert(S.x === 42); 336 | assert(S.y === 42); 337 | assert(S.z === 42); 338 | }; 339 | 340 | function test_template() 341 | { 342 | var a, b; 343 | b = 123; 344 | a = `abc${b}d`; 345 | assert(a, "abc123d"); 346 | 347 | a = String.raw `abc${b}d`; 348 | assert(a, "abc123d"); 349 | 350 | a = "aaa"; 351 | b = "bbb"; 352 | assert(`aaa${a, b}ccc`, "aaabbbccc"); 353 | } 354 | 355 | function test_template_skip() 356 | { 357 | var a = "Bar"; 358 | var { b = `${a + `a${a}` }baz` } = {}; 359 | assert(b, "BaraBarbaz"); 360 | } 361 | 362 | function test_object_literal() 363 | { 364 | var x = 0, get = 1, set = 2; async = 3; 365 | a = { get: 2, set: 3, async: 4 }; 366 | assert(JSON.stringify(a), '{"get":2,"set":3,"async":4}'); 367 | 368 | a = { x, get, set, async }; 369 | assert(JSON.stringify(a), '{"x":0,"get":1,"set":2,"async":3}'); 370 | } 371 | 372 | function test_regexp_skip() 373 | { 374 | var a, b; 375 | [a, b = /abc\(/] = [1]; 376 | assert(a === 1); 377 | 378 | [a, b =/abc\(/] = [2]; 379 | assert(a === 2); 380 | } 381 | 382 | function test_labels() 383 | { 384 | do x: { break x; } while(0); 385 | if (1) 386 | x: { break x; } 387 | else 388 | x: { break x; } 389 | with ({}) x: { break x; }; 390 | while (0) x: { break x; }; 391 | } 392 | 393 | function test_destructuring() 394 | { 395 | function * g () { return 0; }; 396 | var [x] = g(); 397 | assert(x, void 0); 398 | } 399 | 400 | function test_spread() 401 | { 402 | var x; 403 | x = [1, 2, ...[3, 4]]; 404 | assert(x.toString(), "1,2,3,4"); 405 | 406 | x = [ ...[ , ] ]; 407 | assert(Object.getOwnPropertyNames(x).toString(), "0,length"); 408 | } 409 | 410 | function test_function_length() 411 | { 412 | assert( ((a, b = 1, c) => {}).length, 1); 413 | assert( (([a,b]) => {}).length, 1); 414 | assert( (({a,b}) => {}).length, 1); 415 | assert( ((c, [a,b] = 1, d) => {}).length, 1); 416 | } 417 | 418 | function test_argument_scope() 419 | { 420 | var f; 421 | var c = "global"; 422 | 423 | f = function(a = eval("var arguments")) {}; 424 | assert_throws(SyntaxError, f); 425 | 426 | f = function(a = eval("1"), b = arguments[0]) { return b; }; 427 | assert(f(12), 12); 428 | 429 | f = function(a, b = arguments[0]) { return b; }; 430 | assert(f(12), 12); 431 | 432 | f = function(a, b = () => arguments) { return b; }; 433 | assert(f(12)()[0], 12); 434 | 435 | f = function(a = eval("1"), b = () => arguments) { return b; }; 436 | assert(f(12)()[0], 12); 437 | 438 | (function() { 439 | "use strict"; 440 | f = function(a = this) { return a; }; 441 | assert(f.call(123), 123); 442 | 443 | f = function f(a = f) { return a; }; 444 | assert(f(), f); 445 | 446 | f = function f(a = eval("f")) { return a; }; 447 | assert(f(), f); 448 | })(); 449 | 450 | f = (a = eval("var c = 1"), probe = () => c) => { 451 | var c = 2; 452 | assert(c, 2); 453 | assert(probe(), 1); 454 | } 455 | f(); 456 | 457 | f = (a = eval("var arguments = 1"), probe = () => arguments) => { 458 | var arguments = 2; 459 | assert(arguments, 2); 460 | assert(probe(), 1); 461 | } 462 | f(); 463 | 464 | f = function f(a = eval("var c = 1"), b = c, probe = () => c) { 465 | assert(b, 1); 466 | assert(c, 1); 467 | assert(probe(), 1) 468 | } 469 | f(); 470 | 471 | assert(c, "global"); 472 | f = function f(a, b = c, probe = () => c) { 473 | eval("var c = 1"); 474 | assert(c, 1); 475 | assert(b, "global"); 476 | assert(probe(), "global") 477 | } 478 | f(); 479 | assert(c, "global"); 480 | 481 | f = function f(a = eval("var c = 1"), probe = (d = eval("c")) => d) { 482 | assert(probe(), 1) 483 | } 484 | f(); 485 | } 486 | 487 | function test_function_expr_name() 488 | { 489 | var f; 490 | 491 | /* non strict mode test : assignment to the function name silently 492 | fails */ 493 | 494 | f = function myfunc() { 495 | myfunc = 1; 496 | return myfunc; 497 | }; 498 | assert(f(), f); 499 | 500 | f = function myfunc() { 501 | myfunc = 1; 502 | (() => { 503 | myfunc = 1; 504 | })(); 505 | return myfunc; 506 | }; 507 | assert(f(), f); 508 | 509 | f = function myfunc() { 510 | eval("myfunc = 1"); 511 | return myfunc; 512 | }; 513 | assert(f(), f); 514 | 515 | /* strict mode test : assignment to the function name raises a 516 | TypeError exception */ 517 | 518 | f = function myfunc() { 519 | "use strict"; 520 | myfunc = 1; 521 | }; 522 | assert_throws(TypeError, f); 523 | 524 | f = function myfunc() { 525 | "use strict"; 526 | (() => { 527 | myfunc = 1; 528 | })(); 529 | }; 530 | assert_throws(TypeError, f); 531 | 532 | f = function myfunc() { 533 | "use strict"; 534 | eval("myfunc = 1"); 535 | }; 536 | assert_throws(TypeError, f); 537 | } 538 | 539 | function test_parse_semicolon() 540 | { 541 | /* 'yield' or 'await' may not be considered as a token if the 542 | previous ';' is missing */ 543 | function *f() 544 | { 545 | function func() { 546 | } 547 | yield 1; 548 | var h = x => x + 1 549 | yield 2; 550 | } 551 | async function g() 552 | { 553 | function func() { 554 | } 555 | await 1; 556 | var h = x => x + 1 557 | await 2; 558 | } 559 | } 560 | 561 | function test_parse_arrow_function() 562 | { 563 | assert(typeof eval("() => {}\n() => {}"), "function"); 564 | assert(eval("() => {}\n+1"), 1); 565 | assert(typeof eval("x => {}\n() => {}"), "function"); 566 | assert(typeof eval("async () => {}\n() => {}"), "function"); 567 | assert(typeof eval("async x => {}\n() => {}"), "function"); 568 | } 569 | 570 | /* optional chaining tests not present in test262 */ 571 | function test_optional_chaining() 572 | { 573 | var a, z; 574 | z = null; 575 | a = { b: { c: 2 } }; 576 | assert(delete z?.b.c, true); 577 | assert(delete a?.b.c, true); 578 | assert(JSON.stringify(a), '{"b":{}}', "optional chaining delete"); 579 | 580 | a = { b: { c: 2 } }; 581 | assert(delete z?.b["c"], true); 582 | assert(delete a?.b["c"], true); 583 | assert(JSON.stringify(a), '{"b":{}}'); 584 | 585 | a = { 586 | b() { return this._b; }, 587 | _b: { c: 42 } 588 | }; 589 | 590 | assert((a?.b)().c, 42); 591 | 592 | assert((a?.["b"])().c, 42); 593 | } 594 | 595 | test_op1(); 596 | test_cvt(); 597 | test_eq(); 598 | test_inc_dec(); 599 | test_op2(); 600 | test_delete(); 601 | test_prototype(); 602 | test_arguments(); 603 | test_class(); 604 | test_template(); 605 | test_template_skip(); 606 | test_object_literal(); 607 | test_regexp_skip(); 608 | test_labels(); 609 | test_destructuring(); 610 | test_spread(); 611 | test_function_length(); 612 | test_argument_scope(); 613 | test_function_expr_name(); 614 | test_parse_semicolon(); 615 | test_optional_chaining(); 616 | test_parse_arrow_function(); 617 | -------------------------------------------------------------------------------- /tests/test_loop.js: -------------------------------------------------------------------------------- 1 | function assert(actual, expected, message) { 2 | if (arguments.length == 1) 3 | expected = true; 4 | 5 | if (actual === expected) 6 | return; 7 | 8 | if (actual !== null && expected !== null 9 | && typeof actual == 'object' && typeof expected == 'object' 10 | && actual.toString() === expected.toString()) 11 | return; 12 | 13 | throw Error("assertion failed: got |" + actual + "|" + 14 | ", expected |" + expected + "|" + 15 | (message ? " (" + message + ")" : "")); 16 | } 17 | 18 | // load more elaborate version of assert if available 19 | try { __loadScript("test_assert.js"); } catch(e) {} 20 | 21 | /*----------------*/ 22 | 23 | function test_while() 24 | { 25 | var i, c; 26 | i = 0; 27 | c = 0; 28 | while (i < 3) { 29 | c++; 30 | i++; 31 | } 32 | assert(c === 3); 33 | } 34 | 35 | function test_while_break() 36 | { 37 | var i, c; 38 | i = 0; 39 | c = 0; 40 | while (i < 3) { 41 | c++; 42 | if (i == 1) 43 | break; 44 | i++; 45 | } 46 | assert(c === 2 && i === 1); 47 | } 48 | 49 | function test_do_while() 50 | { 51 | var i, c; 52 | i = 0; 53 | c = 0; 54 | do { 55 | c++; 56 | i++; 57 | } while (i < 3); 58 | assert(c === 3 && i === 3); 59 | } 60 | 61 | function test_for() 62 | { 63 | var i, c; 64 | c = 0; 65 | for(i = 0; i < 3; i++) { 66 | c++; 67 | } 68 | assert(c === 3 && i === 3); 69 | 70 | c = 0; 71 | for(var j = 0; j < 3; j++) { 72 | c++; 73 | } 74 | assert(c === 3 && j === 3); 75 | } 76 | 77 | function test_for_in() 78 | { 79 | var i, tab, a, b; 80 | 81 | tab = []; 82 | for(i in {x:1, y: 2}) { 83 | tab.push(i); 84 | } 85 | assert(tab.toString(), "x,y", "for_in"); 86 | 87 | /* prototype chain test */ 88 | a = {x:2, y: 2, "1": 3}; 89 | b = {"4" : 3 }; 90 | Object.setPrototypeOf(a, b); 91 | tab = []; 92 | for(i in a) { 93 | tab.push(i); 94 | } 95 | assert(tab.toString(), "1,x,y,4", "for_in"); 96 | 97 | /* non enumerable properties hide enumerables ones in the 98 | prototype chain */ 99 | a = {y: 2, "1": 3}; 100 | Object.defineProperty(a, "x", { value: 1 }); 101 | b = {"x" : 3 }; 102 | Object.setPrototypeOf(a, b); 103 | tab = []; 104 | for(i in a) { 105 | tab.push(i); 106 | } 107 | assert(tab.toString(), "1,y", "for_in"); 108 | 109 | /* array optimization */ 110 | a = []; 111 | for(i = 0; i < 10; i++) 112 | a.push(i); 113 | tab = []; 114 | for(i in a) { 115 | tab.push(i); 116 | } 117 | assert(tab.toString(), "0,1,2,3,4,5,6,7,8,9", "for_in"); 118 | 119 | /* iterate with a field */ 120 | a={x:0}; 121 | tab = []; 122 | for(a.x in {x:1, y: 2}) { 123 | tab.push(a.x); 124 | } 125 | assert(tab.toString(), "x,y", "for_in"); 126 | 127 | /* iterate with a variable field */ 128 | a=[0]; 129 | tab = []; 130 | for(a[0] in {x:1, y: 2}) { 131 | tab.push(a[0]); 132 | } 133 | assert(tab.toString(), "x,y", "for_in"); 134 | 135 | /* variable definition in the for in */ 136 | tab = []; 137 | for(var j in {x:1, y: 2}) { 138 | tab.push(j); 139 | } 140 | assert(tab.toString(), "x,y", "for_in"); 141 | 142 | /* variable assigment in the for in */ 143 | tab = []; 144 | for(var k = 2 in {x:1, y: 2}) { 145 | tab.push(k); 146 | } 147 | assert(tab.toString(), "x,y", "for_in"); 148 | } 149 | 150 | function test_for_in2() 151 | { 152 | var i; 153 | tab = []; 154 | for(i in {x:1, y: 2, z:3}) { 155 | if (i === "y") 156 | continue; 157 | tab.push(i); 158 | } 159 | assert(tab.toString() == "x,z"); 160 | 161 | tab = []; 162 | for(i in {x:1, y: 2, z:3}) { 163 | if (i === "z") 164 | break; 165 | tab.push(i); 166 | } 167 | assert(tab.toString() == "x,y"); 168 | } 169 | 170 | function test_for_in_proxy() { 171 | let removed_key = ""; 172 | let target = {} 173 | let proxy = new Proxy(target, { 174 | ownKeys: function() { 175 | return ["a", "b", "c"]; 176 | }, 177 | getOwnPropertyDescriptor: function(target, key) { 178 | if (removed_key != "" && key == removed_key) 179 | return undefined; 180 | else 181 | return { enumerable: true, configurable: true, value: this[key] }; 182 | } 183 | }); 184 | let str = ""; 185 | for(let o in proxy) { 186 | str += " " + o; 187 | if (o == "a") 188 | removed_key = "b"; 189 | } 190 | assert(str == " a c"); 191 | } 192 | 193 | function test_for_break() 194 | { 195 | var i, c; 196 | c = 0; 197 | L1: for(i = 0; i < 3; i++) { 198 | c++; 199 | if (i == 0) 200 | continue; 201 | while (1) { 202 | break L1; 203 | } 204 | } 205 | assert(c === 2 && i === 1); 206 | } 207 | 208 | function test_switch1() 209 | { 210 | var i, a, s; 211 | s = ""; 212 | for(i = 0; i < 3; i++) { 213 | a = "?"; 214 | switch(i) { 215 | case 0: 216 | a = "a"; 217 | break; 218 | case 1: 219 | a = "b"; 220 | break; 221 | default: 222 | a = "c"; 223 | break; 224 | } 225 | s += a; 226 | } 227 | assert(s === "abc" && i === 3); 228 | } 229 | 230 | function test_switch2() 231 | { 232 | var i, a, s; 233 | s = ""; 234 | for(i = 0; i < 4; i++) { 235 | a = "?"; 236 | switch(i) { 237 | case 0: 238 | a = "a"; 239 | break; 240 | case 1: 241 | a = "b"; 242 | break; 243 | case 2: 244 | continue; 245 | default: 246 | a = "" + i; 247 | break; 248 | } 249 | s += a; 250 | } 251 | assert(s === "ab3" && i === 4); 252 | } 253 | 254 | function test_try_catch1() 255 | { 256 | try { 257 | throw "hello"; 258 | } catch (e) { 259 | assert(e, "hello", "catch"); 260 | return; 261 | } 262 | assert(false, "catch"); 263 | } 264 | 265 | function test_try_catch2() 266 | { 267 | var a; 268 | try { 269 | a = 1; 270 | } catch (e) { 271 | a = 2; 272 | } 273 | assert(a, 1, "catch"); 274 | } 275 | 276 | function test_try_catch3() 277 | { 278 | var s; 279 | s = ""; 280 | try { 281 | s += "t"; 282 | } catch (e) { 283 | s += "c"; 284 | } finally { 285 | s += "f"; 286 | } 287 | assert(s, "tf", "catch"); 288 | } 289 | 290 | function test_try_catch4() 291 | { 292 | var s; 293 | s = ""; 294 | try { 295 | s += "t"; 296 | throw "c"; 297 | } catch (e) { 298 | s += e; 299 | } finally { 300 | s += "f"; 301 | } 302 | assert(s, "tcf", "catch"); 303 | } 304 | 305 | function test_try_catch5() 306 | { 307 | var s; 308 | s = ""; 309 | for(;;) { 310 | try { 311 | s += "t"; 312 | break; 313 | s += "b"; 314 | } finally { 315 | s += "f"; 316 | } 317 | } 318 | assert(s, "tf", "catch"); 319 | } 320 | 321 | function test_try_catch6() 322 | { 323 | function f() { 324 | try { 325 | s += 't'; 326 | return 1; 327 | } finally { 328 | s += "f"; 329 | } 330 | } 331 | var s = ""; 332 | assert(f() === 1); 333 | assert(s, "tf", "catch6"); 334 | } 335 | 336 | function test_try_catch7() 337 | { 338 | var s; 339 | s = ""; 340 | 341 | try { 342 | try { 343 | s += "t"; 344 | throw "a"; 345 | } finally { 346 | s += "f"; 347 | } 348 | } catch(e) { 349 | s += e; 350 | } finally { 351 | s += "g"; 352 | } 353 | assert(s, "tfag", "catch"); 354 | } 355 | 356 | function test_try_catch8() 357 | { 358 | var i, s; 359 | 360 | s = ""; 361 | for(var i in {x:1, y:2}) { 362 | try { 363 | s += i; 364 | throw "a"; 365 | } catch (e) { 366 | s += e; 367 | } finally { 368 | s += "f"; 369 | } 370 | } 371 | assert(s === "xafyaf"); 372 | } 373 | 374 | test_while(); 375 | test_while_break(); 376 | test_do_while(); 377 | test_for(); 378 | test_for_break(); 379 | test_switch1(); 380 | test_switch2(); 381 | test_for_in(); 382 | test_for_in2(); 383 | test_for_in_proxy(); 384 | 385 | test_try_catch1(); 386 | test_try_catch2(); 387 | test_try_catch3(); 388 | test_try_catch4(); 389 | test_try_catch5(); 390 | test_try_catch6(); 391 | test_try_catch7(); 392 | test_try_catch8(); 393 | -------------------------------------------------------------------------------- /tests/test_op_overloading.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | 3 | function assert(actual, expected, message) { 4 | if (arguments.length == 1) 5 | expected = true; 6 | 7 | if (actual === expected) 8 | return; 9 | 10 | if (actual !== null && expected !== null 11 | && typeof actual == 'object' && typeof expected == 'object' 12 | && actual.toString() === expected.toString()) 13 | return; 14 | 15 | throw Error("assertion failed: got |" + actual + "|" + 16 | ", expected |" + expected + "|" + 17 | (message ? " (" + message + ")" : "")); 18 | } 19 | 20 | /* operators overloading with Operators.create() */ 21 | function test_operators_create() { 22 | class Vec2 23 | { 24 | constructor(x, y) { 25 | this.x = x; 26 | this.y = y; 27 | } 28 | static mul_scalar(p1, a) { 29 | var r = new Vec2(); 30 | r.x = p1.x * a; 31 | r.y = p1.y * a; 32 | return r; 33 | } 34 | toString() { 35 | return "Vec2(" + this.x + "," + this.y + ")"; 36 | } 37 | } 38 | 39 | Vec2.prototype[Symbol.operatorSet] = Operators.create( 40 | { 41 | "+"(p1, p2) { 42 | var r = new Vec2(); 43 | r.x = p1.x + p2.x; 44 | r.y = p1.y + p2.y; 45 | return r; 46 | }, 47 | "-"(p1, p2) { 48 | var r = new Vec2(); 49 | r.x = p1.x - p2.x; 50 | r.y = p1.y - p2.y; 51 | return r; 52 | }, 53 | "=="(a, b) { 54 | return a.x == b.x && a.y == b.y; 55 | }, 56 | "<"(a, b) { 57 | var r; 58 | /* lexicographic order */ 59 | if (a.x == b.x) 60 | r = (a.y < b.y); 61 | else 62 | r = (a.x < b.x); 63 | return r; 64 | }, 65 | "++"(a) { 66 | var r = new Vec2(); 67 | r.x = a.x + 1; 68 | r.y = a.y + 1; 69 | return r; 70 | } 71 | }, 72 | { 73 | left: Number, 74 | "*"(a, b) { 75 | return Vec2.mul_scalar(b, a); 76 | } 77 | }, 78 | { 79 | right: Number, 80 | "*"(a, b) { 81 | return Vec2.mul_scalar(a, b); 82 | } 83 | }); 84 | 85 | var a = new Vec2(1, 2); 86 | var b = new Vec2(3, 4); 87 | var r; 88 | 89 | r = a * 2 + 3 * b; 90 | assert(r.x === 11 && r.y === 16); 91 | assert(a == a, true); 92 | assert(a == b, false); 93 | assert(a != a, false); 94 | assert(a < b, true); 95 | assert(a <= b, true); 96 | assert(b < a, false); 97 | assert(b <= a, false); 98 | assert(a <= a, true); 99 | assert(a >= a, true); 100 | a++; 101 | assert(a.x === 2 && a.y === 3); 102 | r = ++a; 103 | assert(a.x === 3 && a.y === 4); 104 | assert(r === a); 105 | } 106 | 107 | /* operators overloading thru inheritance */ 108 | function test_operators() 109 | { 110 | var Vec2; 111 | 112 | function mul_scalar(p1, a) { 113 | var r = new Vec2(); 114 | r.x = p1.x * a; 115 | r.y = p1.y * a; 116 | return r; 117 | } 118 | 119 | var vec2_ops = Operators({ 120 | "+"(p1, p2) { 121 | var r = new Vec2(); 122 | r.x = p1.x + p2.x; 123 | r.y = p1.y + p2.y; 124 | return r; 125 | }, 126 | "-"(p1, p2) { 127 | var r = new Vec2(); 128 | r.x = p1.x - p2.x; 129 | r.y = p1.y - p2.y; 130 | return r; 131 | }, 132 | "=="(a, b) { 133 | return a.x == b.x && a.y == b.y; 134 | }, 135 | "<"(a, b) { 136 | var r; 137 | /* lexicographic order */ 138 | if (a.x == b.x) 139 | r = (a.y < b.y); 140 | else 141 | r = (a.x < b.x); 142 | return r; 143 | }, 144 | "++"(a) { 145 | var r = new Vec2(); 146 | r.x = a.x + 1; 147 | r.y = a.y + 1; 148 | return r; 149 | } 150 | }, 151 | { 152 | left: Number, 153 | "*"(a, b) { 154 | return mul_scalar(b, a); 155 | } 156 | }, 157 | { 158 | right: Number, 159 | "*"(a, b) { 160 | return mul_scalar(a, b); 161 | } 162 | }); 163 | 164 | Vec2 = class Vec2 extends vec2_ops 165 | { 166 | constructor(x, y) { 167 | super(); 168 | this.x = x; 169 | this.y = y; 170 | } 171 | toString() { 172 | return "Vec2(" + this.x + "," + this.y + ")"; 173 | } 174 | } 175 | 176 | var a = new Vec2(1, 2); 177 | var b = new Vec2(3, 4); 178 | var r; 179 | 180 | r = a * 2 + 3 * b; 181 | assert(r.x === 11 && r.y === 16); 182 | assert(a == a, true); 183 | assert(a == b, false); 184 | assert(a != a, false); 185 | assert(a < b, true); 186 | assert(a <= b, true); 187 | assert(b < a, false); 188 | assert(b <= a, false); 189 | assert(a <= a, true); 190 | assert(a >= a, true); 191 | a++; 192 | assert(a.x === 2 && a.y === 3); 193 | r = ++a; 194 | assert(a.x === 3 && a.y === 4); 195 | assert(r === a); 196 | } 197 | 198 | function test_default_op() 199 | { 200 | assert(Object(1) + 2, 3); 201 | assert(Object(1) + true, 2); 202 | assert(-Object(1), -1); 203 | } 204 | 205 | test_operators_create(); 206 | test_operators(); 207 | test_default_op(); 208 | -------------------------------------------------------------------------------- /tests/test_qjscalc.js: -------------------------------------------------------------------------------- 1 | "use math"; 2 | "use strict"; 3 | 4 | function assert(actual, expected, message) { 5 | if (arguments.length == 1) 6 | expected = true; 7 | 8 | if (actual === expected) 9 | return; 10 | 11 | if (actual !== null && expected !== null 12 | && typeof actual == 'object' && typeof expected == 'object' 13 | && actual.toString() === expected.toString()) 14 | return; 15 | 16 | throw Error("assertion failed: got |" + actual + "|" + 17 | ", expected |" + expected + "|" + 18 | (message ? " (" + message + ")" : "")); 19 | } 20 | 21 | function assertThrows(err, func) 22 | { 23 | var ex; 24 | ex = false; 25 | try { 26 | func(); 27 | } catch(e) { 28 | ex = true; 29 | assert(e instanceof err); 30 | } 31 | assert(ex, true, "exception expected"); 32 | } 33 | 34 | // load more elaborate version of assert if available 35 | try { __loadScript("test_assert.js"); } catch(e) {} 36 | 37 | /*----------------*/ 38 | 39 | function pow(a, n) 40 | { 41 | var r, i; 42 | r = 1; 43 | for(i = 0; i < n; i++) 44 | r *= a; 45 | return r; 46 | } 47 | 48 | function test_integer() 49 | { 50 | var a, r; 51 | a = pow(3, 100); 52 | assert((a - 1) != a); 53 | assert(a == 515377520732011331036461129765621272702107522001); 54 | assert(a == 0x5a4653ca673768565b41f775d6947d55cf3813d1); 55 | assert(Integer.isInteger(1) === true); 56 | assert(Integer.isInteger(1.0) === false); 57 | 58 | assert(Integer.floorLog2(0) === -1); 59 | assert(Integer.floorLog2(7) === 2); 60 | 61 | r = 1 << 31; 62 | assert(r, 2147483648, "1 << 31 === 2147483648"); 63 | 64 | r = 1 << 32; 65 | assert(r, 4294967296, "1 << 32 === 4294967296"); 66 | 67 | r = (1 << 31) < 0; 68 | assert(r, false, "(1 << 31) < 0 === false"); 69 | 70 | assert(typeof 1 === "number"); 71 | assert(typeof 9007199254740991 === "number"); 72 | assert(typeof 9007199254740992 === "bigint"); 73 | } 74 | 75 | function test_float() 76 | { 77 | assert(typeof 1.0 === "bigfloat"); 78 | assert(1 == 1.0); 79 | assert(1 !== 1.0); 80 | } 81 | 82 | /* jscalc tests */ 83 | 84 | function test_modulo() 85 | { 86 | var i, p, a, b; 87 | 88 | /* Euclidian modulo operator */ 89 | assert((-3) % 2 == 1); 90 | assert(3 % (-2) == 1); 91 | 92 | p = 101; 93 | for(i = 1; i < p; i++) { 94 | a = Integer.invmod(i, p); 95 | assert(a >= 0 && a < p); 96 | assert((i * a) % p == 1); 97 | } 98 | 99 | assert(Integer.isPrime(2^107-1)); 100 | assert(!Integer.isPrime((2^107-1) * (2^89-1))); 101 | a = Integer.factor((2^89-1)*2^3*11*13^2*1009); 102 | assert(a == [ 2,2,2,11,13,13,1009,618970019642690137449562111 ]); 103 | } 104 | 105 | function test_fraction() 106 | { 107 | assert((1/3 + 1).toString(), "4/3") 108 | assert((2/3)^30, 1073741824/205891132094649); 109 | assert(1/3 < 2/3); 110 | assert(1/3 < 1); 111 | assert(1/3 == 1.0/3); 112 | assert(1.0/3 < 2/3); 113 | } 114 | 115 | function test_mod() 116 | { 117 | var a, b, p; 118 | 119 | a = Mod(3, 101); 120 | b = Mod(-1, 101); 121 | assert((a + b) == Mod(2, 101)); 122 | assert(a ^ 100 == Mod(1, 101)); 123 | 124 | p = 2 ^ 607 - 1; /* mersenne prime */ 125 | a = Mod(3, p) ^ (p - 1); 126 | assert(a == Mod(1, p)); 127 | } 128 | 129 | function test_polynomial() 130 | { 131 | var a, b, q, r, t, i; 132 | a = (1 + X) ^ 4; 133 | assert(a == X^4+4*X^3+6*X^2+4*X+1); 134 | 135 | r = (1 + X); 136 | q = (1+X+X^2); 137 | b = (1 - X^2); 138 | a = q * b + r; 139 | t = Polynomial.divrem(a, b); 140 | assert(t[0] == q); 141 | assert(t[1] == r); 142 | 143 | a = 1 + 2*X + 3*X^2; 144 | assert(a.apply(0.1) == 1.23); 145 | 146 | a = 1-2*X^2+2*X^3; 147 | assert(deriv(a) == (6*X^2-4*X)); 148 | assert(deriv(integ(a)) == a); 149 | 150 | a = (X-1)*(X-2)*(X-3)*(X-4)*(X-0.1); 151 | r = polroots(a); 152 | for(i = 0; i < r.length; i++) { 153 | b = abs(a.apply(r[i])); 154 | assert(b <= 1e-13); 155 | } 156 | } 157 | 158 | function test_poly_mod() 159 | { 160 | var a, p; 161 | 162 | /* modulo using polynomials */ 163 | p = X^2 + X + 1; 164 | a = PolyMod(3+X, p) ^ 10; 165 | assert(a == PolyMod(-3725*X-18357, p)); 166 | 167 | a = PolyMod(1/X, 1+X^2); 168 | assert(a == PolyMod(-X, X^2+1)); 169 | } 170 | 171 | function test_rfunc() 172 | { 173 | var a; 174 | a = (X+1)/((X+1)*(X-1)); 175 | assert(a == 1/(X-1)); 176 | a = (X + 2) / (X - 2); 177 | assert(a.apply(1/3) == -7/5); 178 | 179 | assert(deriv((X^2-X+1)/(X-1)) == (X^2-2*X)/(X^2-2*X+1)); 180 | } 181 | 182 | function test_series() 183 | { 184 | var a, b; 185 | a = 1+X+O(X^5); 186 | b = a.inverse(); 187 | assert(b == 1-X+X^2-X^3+X^4+O(X^5)); 188 | assert(deriv(b) == -1+2*X-3*X^2+4*X^3+O(X^4)); 189 | assert(deriv(integ(b)) == b); 190 | 191 | a = Series(1/(1-X), 5); 192 | assert(a == 1+X+X^2+X^3+X^4+O(X^5)); 193 | b = a.apply(0.1); 194 | assert(b == 1.1111); 195 | 196 | assert(exp(3*X^2+O(X^10)) == 1+3*X^2+9/2*X^4+9/2*X^6+27/8*X^8+O(X^10)); 197 | assert(sin(X+O(X^6)) == X-1/6*X^3+1/120*X^5+O(X^6)); 198 | assert(cos(X+O(X^6)) == 1-1/2*X^2+1/24*X^4+O(X^6)); 199 | assert(tan(X+O(X^8)) == X+1/3*X^3+2/15*X^5+17/315*X^7+O(X^8)); 200 | assert((1+X+O(X^6))^(2+X) == 1+2*X+2*X^2+3/2*X^3+5/6*X^4+5/12*X^5+O(X^6)); 201 | } 202 | 203 | function test_matrix() 204 | { 205 | var a, b, r; 206 | a = [[1, 2],[3, 4]]; 207 | b = [3, 4]; 208 | r = a * b; 209 | assert(r == [11, 25]); 210 | r = (a^-1) * 2; 211 | assert(r == [[-4, 2],[3, -1]]); 212 | 213 | assert(norm2([1,2,3]) == 14); 214 | 215 | assert(diag([1,2,3]) == [ [ 1, 0, 0 ], [ 0, 2, 0 ], [ 0, 0, 3 ] ]); 216 | assert(trans(a) == [ [ 1, 3 ], [ 2, 4 ] ]); 217 | assert(trans([1,2,3]) == [[1,2,3]]); 218 | assert(trace(a) == 5); 219 | 220 | assert(charpoly(Matrix.hilbert(4)) == X^4-176/105*X^3+3341/12600*X^2-41/23625*X+1/6048000); 221 | assert(det(Matrix.hilbert(4)) == 1/6048000); 222 | 223 | a = [[1,2,1],[-2,-3,1],[3,5,0]]; 224 | assert(rank(a) == 2); 225 | assert(ker(a) == [ [ 5 ], [ -3 ], [ 1 ] ]); 226 | 227 | assert(dp([1, 2, 3], [3, -4, -7]) === -26); 228 | assert(cp([1, 2, 3], [3, -4, -7]) == [ -2, 16, -10 ]); 229 | } 230 | 231 | function assert_eq(a, ref) 232 | { 233 | assert(abs(a / ref - 1.0) <= 1e-15); 234 | } 235 | 236 | function test_trig() 237 | { 238 | assert_eq(sin(1/2), 0.479425538604203); 239 | assert_eq(sin(2+3*I), 9.154499146911428-4.168906959966565*I); 240 | assert_eq(cos(2+3*I), -4.189625690968807-9.109227893755337*I); 241 | assert_eq((2+0.5*I)^(1.1-0.5*I), 2.494363021357619-0.23076804554558092*I); 242 | assert_eq(sqrt(2*I), 1 + I); 243 | } 244 | 245 | test_integer(); 246 | test_float(); 247 | 248 | test_modulo(); 249 | test_fraction(); 250 | test_mod(); 251 | test_polynomial(); 252 | test_poly_mod(); 253 | test_rfunc(); 254 | test_series(); 255 | test_matrix(); 256 | test_trig(); 257 | -------------------------------------------------------------------------------- /tests/test_std.js: -------------------------------------------------------------------------------- 1 | #! (shebang test) 2 | import * as std from "std"; 3 | import * as os from "os"; 4 | 5 | function assert(actual, expected, message) { 6 | if (arguments.length == 1) 7 | expected = true; 8 | 9 | if (actual === expected) 10 | return; 11 | 12 | if (actual !== null && expected !== null 13 | && typeof actual == 'object' && typeof expected == 'object' 14 | && actual.toString() === expected.toString()) 15 | return; 16 | 17 | throw Error("assertion failed: got |" + actual + "|" + 18 | ", expected |" + expected + "|" + 19 | (message ? " (" + message + ")" : "")); 20 | } 21 | 22 | // load more elaborate version of assert if available 23 | try { std.loadScript("test_assert.js"); } catch(e) {} 24 | 25 | /*----------------*/ 26 | 27 | function test_printf() 28 | { 29 | assert(std.sprintf("a=%d s=%s", 123, "abc"), "a=123 s=abc"); 30 | assert(std.sprintf("%010d", 123), "0000000123"); 31 | assert(std.sprintf("%x", -2), "fffffffe"); 32 | assert(std.sprintf("%lx", -2), "fffffffffffffffe"); 33 | assert(std.sprintf("%10.1f", 2.1), " 2.1"); 34 | assert(std.sprintf("%*.*f", 10, 2, -2.13), " -2.13"); 35 | assert(std.sprintf("%#lx", 0x7fffffffffffffffn), "0x7fffffffffffffff"); 36 | } 37 | 38 | function test_file1() 39 | { 40 | var f, len, str, size, buf, ret, i, str1; 41 | 42 | f = std.tmpfile(); 43 | str = "hello world\n"; 44 | f.puts(str); 45 | 46 | f.seek(0, std.SEEK_SET); 47 | str1 = f.readAsString(); 48 | assert(str1 === str); 49 | 50 | f.seek(0, std.SEEK_END); 51 | size = f.tell(); 52 | assert(size === str.length); 53 | 54 | f.seek(0, std.SEEK_SET); 55 | 56 | buf = new Uint8Array(size); 57 | ret = f.read(buf.buffer, 0, size); 58 | assert(ret === size); 59 | for(i = 0; i < size; i++) 60 | assert(buf[i] === str.charCodeAt(i)); 61 | 62 | f.close(); 63 | } 64 | 65 | function test_file2() 66 | { 67 | var f, str, i, size; 68 | f = std.tmpfile(); 69 | str = "hello world\n"; 70 | size = str.length; 71 | for(i = 0; i < size; i++) 72 | f.putByte(str.charCodeAt(i)); 73 | f.seek(0, std.SEEK_SET); 74 | for(i = 0; i < size; i++) { 75 | assert(str.charCodeAt(i) === f.getByte()); 76 | } 77 | assert(f.getByte() === -1); 78 | f.close(); 79 | } 80 | 81 | function test_getline() 82 | { 83 | var f, line, line_count, lines, i; 84 | 85 | lines = ["hello world", "line 1", "line 2" ]; 86 | f = std.tmpfile(); 87 | for(i = 0; i < lines.length; i++) { 88 | f.puts(lines[i], "\n"); 89 | } 90 | 91 | f.seek(0, std.SEEK_SET); 92 | assert(!f.eof()); 93 | line_count = 0; 94 | for(;;) { 95 | line = f.getline(); 96 | if (line === null) 97 | break; 98 | assert(line == lines[line_count]); 99 | line_count++; 100 | } 101 | assert(f.eof()); 102 | assert(line_count === lines.length); 103 | 104 | f.close(); 105 | } 106 | 107 | function test_popen() 108 | { 109 | var str, f, fname = "tmp_file.txt"; 110 | var content = "hello world"; 111 | 112 | f = std.open(fname, "w"); 113 | f.puts(content); 114 | f.close(); 115 | 116 | /* test loadFile */ 117 | assert(std.loadFile(fname), content); 118 | 119 | /* execute the 'cat' shell command */ 120 | f = std.popen("cat " + fname, "r"); 121 | str = f.readAsString(); 122 | f.close(); 123 | 124 | assert(str, content); 125 | 126 | os.remove(fname); 127 | } 128 | 129 | function test_ext_json() 130 | { 131 | var expected, input, obj; 132 | expected = '{"x":false,"y":true,"z2":null,"a":[1,8,160],"s":"str"}'; 133 | input = `{ "x":false, /*comments are allowed */ 134 | "y":true, // also a comment 135 | z2:null, // unquoted property names 136 | "a":[+1,0o10,0xa0,], // plus prefix, octal, hexadecimal 137 | "s":"str",} // trailing comma in objects and arrays 138 | `; 139 | obj = std.parseExtJSON(input); 140 | assert(JSON.stringify(obj), expected); 141 | } 142 | 143 | function test_os() 144 | { 145 | var fd, fpath, fname, fdir, buf, buf2, i, files, err, fdate, st, link_path; 146 | 147 | assert(os.isatty(0)); 148 | 149 | fdir = "test_tmp_dir"; 150 | fname = "tmp_file.txt"; 151 | fpath = fdir + "/" + fname; 152 | link_path = fdir + "/test_link"; 153 | 154 | os.remove(link_path); 155 | os.remove(fpath); 156 | os.remove(fdir); 157 | 158 | err = os.mkdir(fdir, 0o755); 159 | assert(err === 0); 160 | 161 | fd = os.open(fpath, os.O_RDWR | os.O_CREAT | os.O_TRUNC); 162 | assert(fd >= 0); 163 | 164 | buf = new Uint8Array(10); 165 | for(i = 0; i < buf.length; i++) 166 | buf[i] = i; 167 | assert(os.write(fd, buf.buffer, 0, buf.length) === buf.length); 168 | 169 | assert(os.seek(fd, 0, std.SEEK_SET) === 0); 170 | buf2 = new Uint8Array(buf.length); 171 | assert(os.read(fd, buf2.buffer, 0, buf2.length) === buf2.length); 172 | 173 | for(i = 0; i < buf.length; i++) 174 | assert(buf[i] == buf2[i]); 175 | 176 | if (typeof BigInt !== "undefined") { 177 | assert(os.seek(fd, BigInt(6), std.SEEK_SET), BigInt(6)); 178 | assert(os.read(fd, buf2.buffer, 0, 1) === 1); 179 | assert(buf[6] == buf2[0]); 180 | } 181 | 182 | assert(os.close(fd) === 0); 183 | 184 | [files, err] = os.readdir(fdir); 185 | assert(err, 0); 186 | assert(files.indexOf(fname) >= 0); 187 | 188 | fdate = 10000; 189 | 190 | err = os.utimes(fpath, fdate, fdate); 191 | assert(err, 0); 192 | 193 | [st, err] = os.stat(fpath); 194 | assert(err, 0); 195 | assert(st.mode & os.S_IFMT, os.S_IFREG); 196 | assert(st.mtime, fdate); 197 | 198 | err = os.symlink(fname, link_path); 199 | assert(err === 0); 200 | 201 | [st, err] = os.lstat(link_path); 202 | assert(err, 0); 203 | assert(st.mode & os.S_IFMT, os.S_IFLNK); 204 | 205 | [buf, err] = os.readlink(link_path); 206 | assert(err, 0); 207 | assert(buf, fname); 208 | 209 | assert(os.remove(link_path) === 0); 210 | 211 | [buf, err] = os.getcwd(); 212 | assert(err, 0); 213 | 214 | [buf2, err] = os.realpath("."); 215 | assert(err, 0); 216 | 217 | assert(buf, buf2); 218 | 219 | assert(os.remove(fpath) === 0); 220 | 221 | fd = os.open(fpath, os.O_RDONLY); 222 | assert(fd < 0); 223 | 224 | assert(os.remove(fdir) === 0); 225 | } 226 | 227 | function test_os_exec() 228 | { 229 | var ret, fds, pid, f, status; 230 | 231 | ret = os.exec(["true"]); 232 | assert(ret, 0); 233 | 234 | ret = os.exec(["/bin/sh", "-c", "exit 1"], { usePath: false }); 235 | assert(ret, 1); 236 | 237 | fds = os.pipe(); 238 | pid = os.exec(["sh", "-c", "echo $FOO"], { 239 | stdout: fds[1], 240 | block: false, 241 | env: { FOO: "hello" }, 242 | } ); 243 | assert(pid >= 0); 244 | os.close(fds[1]); /* close the write end (as it is only in the child) */ 245 | f = std.fdopen(fds[0], "r"); 246 | assert(f.getline(), "hello"); 247 | assert(f.getline(), null); 248 | f.close(); 249 | [ret, status] = os.waitpid(pid, 0); 250 | assert(ret, pid); 251 | assert(status & 0x7f, 0); /* exited */ 252 | assert(status >> 8, 0); /* exit code */ 253 | 254 | pid = os.exec(["cat"], { block: false } ); 255 | assert(pid >= 0); 256 | os.kill(pid, os.SIGQUIT); 257 | [ret, status] = os.waitpid(pid, 0); 258 | assert(ret, pid); 259 | assert(status & 0x7f, os.SIGQUIT); 260 | } 261 | 262 | function test_timer() 263 | { 264 | var th, i; 265 | 266 | /* just test that a timer can be inserted and removed */ 267 | th = []; 268 | for(i = 0; i < 3; i++) 269 | th[i] = os.setTimeout(function () { }, 1000); 270 | for(i = 0; i < 3; i++) 271 | os.clearTimeout(th[i]); 272 | } 273 | 274 | /* test closure variable handling when freeing asynchronous 275 | function */ 276 | function test_async_gc() 277 | { 278 | (async function run () { 279 | let obj = {} 280 | 281 | let done = () => { 282 | obj 283 | std.gc(); 284 | } 285 | 286 | Promise.resolve().then(done) 287 | 288 | const p = new Promise(() => {}) 289 | 290 | await p 291 | })(); 292 | } 293 | 294 | test_printf(); 295 | test_file1(); 296 | test_file2(); 297 | test_getline(); 298 | test_popen(); 299 | test_os(); 300 | test_os_exec(); 301 | test_timer(); 302 | test_ext_json(); 303 | test_async_gc(); 304 | 305 | -------------------------------------------------------------------------------- /tests/test_worker.js: -------------------------------------------------------------------------------- 1 | /* os.Worker API test */ 2 | import * as std from "std"; 3 | import * as os from "os"; 4 | 5 | function assert(actual, expected, message) { 6 | if (arguments.length == 1) 7 | expected = true; 8 | 9 | if (actual === expected) 10 | return; 11 | 12 | if (actual !== null && expected !== null 13 | && typeof actual == 'object' && typeof expected == 'object' 14 | && actual.toString() === expected.toString()) 15 | return; 16 | 17 | throw Error("assertion failed: got |" + actual + "|" + 18 | ", expected |" + expected + "|" + 19 | (message ? " (" + message + ")" : "")); 20 | } 21 | 22 | var worker; 23 | 24 | function test_worker() 25 | { 26 | var counter; 27 | 28 | worker = new os.Worker("./test_worker_module.js"); 29 | 30 | counter = 0; 31 | worker.onmessage = function (e) { 32 | var ev = e.data; 33 | // print("recv", JSON.stringify(ev)); 34 | switch(ev.type) { 35 | case "num": 36 | assert(ev.num, counter); 37 | counter++; 38 | if (counter == 10) { 39 | /* test SharedArrayBuffer modification */ 40 | let sab = new SharedArrayBuffer(10); 41 | let buf = new Uint8Array(sab); 42 | worker.postMessage({ type: "sab", buf: buf }); 43 | } 44 | break; 45 | case "sab_done": 46 | { 47 | let buf = ev.buf; 48 | /* check that the SharedArrayBuffer was modified */ 49 | assert(buf[2], 10); 50 | worker.postMessage({ type: "abort" }); 51 | } 52 | break; 53 | case "done": 54 | /* terminate */ 55 | worker.onmessage = null; 56 | break; 57 | } 58 | }; 59 | } 60 | 61 | 62 | test_worker(); 63 | -------------------------------------------------------------------------------- /tests/test_worker_module.js: -------------------------------------------------------------------------------- 1 | /* Worker code for test_worker.js */ 2 | import * as std from "std"; 3 | import * as os from "os"; 4 | 5 | var parent = os.Worker.parent; 6 | 7 | function handle_msg(e) { 8 | var ev = e.data; 9 | // print("child_recv", JSON.stringify(ev)); 10 | switch(ev.type) { 11 | case "abort": 12 | parent.postMessage({ type: "done" }); 13 | parent.onMessage = null; /* terminate the worker */ 14 | break; 15 | case "sab": 16 | /* modify the SharedArrayBuffer */ 17 | ev.buf[2] = 10; 18 | parent.postMessage({ type: "sab_done", buf: ev.buf }); 19 | break; 20 | } 21 | } 22 | 23 | function worker_main() { 24 | var i; 25 | 26 | parent.onmessage = handle_msg; 27 | for(i = 0; i < 10; i++) { 28 | parent.postMessage({ type: "num", num: i }); 29 | } 30 | } 31 | 32 | worker_main(); 33 | -------------------------------------------------------------------------------- /unicode_download.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | url="ftp://ftp.unicode.org/Public/15.0.0/ucd" 5 | emoji_url="${url}/emoji/emoji-data.txt" 6 | 7 | files="CaseFolding.txt DerivedNormalizationProps.txt PropList.txt \ 8 | SpecialCasing.txt CompositionExclusions.txt ScriptExtensions.txt \ 9 | UnicodeData.txt DerivedCoreProperties.txt NormalizationTest.txt Scripts.txt \ 10 | PropertyValueAliases.txt" 11 | 12 | mkdir -p unicode 13 | 14 | for f in $files; do 15 | g="${url}/${f}" 16 | wget $g -O unicode/$f 17 | done 18 | 19 | wget $emoji_url -O unicode/emoji-data.txt 20 | -------------------------------------------------------------------------------- /unicode_gen_def.h: -------------------------------------------------------------------------------- 1 | #ifdef UNICODE_GENERAL_CATEGORY 2 | DEF(Cn, "Unassigned") /* must be zero */ 3 | DEF(Lu, "Uppercase_Letter") 4 | DEF(Ll, "Lowercase_Letter") 5 | DEF(Lt, "Titlecase_Letter") 6 | DEF(Lm, "Modifier_Letter") 7 | DEF(Lo, "Other_Letter") 8 | DEF(Mn, "Nonspacing_Mark") 9 | DEF(Mc, "Spacing_Mark") 10 | DEF(Me, "Enclosing_Mark") 11 | DEF(Nd, "Decimal_Number,digit") 12 | DEF(Nl, "Letter_Number") 13 | DEF(No, "Other_Number") 14 | DEF(Sm, "Math_Symbol") 15 | DEF(Sc, "Currency_Symbol") 16 | DEF(Sk, "Modifier_Symbol") 17 | DEF(So, "Other_Symbol") 18 | DEF(Pc, "Connector_Punctuation") 19 | DEF(Pd, "Dash_Punctuation") 20 | DEF(Ps, "Open_Punctuation") 21 | DEF(Pe, "Close_Punctuation") 22 | DEF(Pi, "Initial_Punctuation") 23 | DEF(Pf, "Final_Punctuation") 24 | DEF(Po, "Other_Punctuation") 25 | DEF(Zs, "Space_Separator") 26 | DEF(Zl, "Line_Separator") 27 | DEF(Zp, "Paragraph_Separator") 28 | DEF(Cc, "Control,cntrl") 29 | DEF(Cf, "Format") 30 | DEF(Cs, "Surrogate") 31 | DEF(Co, "Private_Use") 32 | /* synthetic properties */ 33 | DEF(LC, "Cased_Letter") 34 | DEF(L, "Letter") 35 | DEF(M, "Mark,Combining_Mark") 36 | DEF(N, "Number") 37 | DEF(S, "Symbol") 38 | DEF(P, "Punctuation,punct") 39 | DEF(Z, "Separator") 40 | DEF(C, "Other") 41 | #endif 42 | 43 | #ifdef UNICODE_SCRIPT 44 | /* scripts aliases names in PropertyValueAliases.txt */ 45 | DEF(Unknown, "Zzzz") 46 | DEF(Adlam, "Adlm") 47 | DEF(Ahom, "Ahom") 48 | DEF(Anatolian_Hieroglyphs, "Hluw") 49 | DEF(Arabic, "Arab") 50 | DEF(Armenian, "Armn") 51 | DEF(Avestan, "Avst") 52 | DEF(Balinese, "Bali") 53 | DEF(Bamum, "Bamu") 54 | DEF(Bassa_Vah, "Bass") 55 | DEF(Batak, "Batk") 56 | DEF(Bengali, "Beng") 57 | DEF(Bhaiksuki, "Bhks") 58 | DEF(Bopomofo, "Bopo") 59 | DEF(Brahmi, "Brah") 60 | DEF(Braille, "Brai") 61 | DEF(Buginese, "Bugi") 62 | DEF(Buhid, "Buhd") 63 | DEF(Canadian_Aboriginal, "Cans") 64 | DEF(Carian, "Cari") 65 | DEF(Caucasian_Albanian, "Aghb") 66 | DEF(Chakma, "Cakm") 67 | DEF(Cham, "Cham") 68 | DEF(Cherokee, "Cher") 69 | DEF(Chorasmian, "Chrs") 70 | DEF(Common, "Zyyy") 71 | DEF(Coptic, "Copt,Qaac") 72 | DEF(Cuneiform, "Xsux") 73 | DEF(Cypriot, "Cprt") 74 | DEF(Cyrillic, "Cyrl") 75 | DEF(Cypro_Minoan, "Cpmn") 76 | DEF(Deseret, "Dsrt") 77 | DEF(Devanagari, "Deva") 78 | DEF(Dives_Akuru, "Diak") 79 | DEF(Dogra, "Dogr") 80 | DEF(Duployan, "Dupl") 81 | DEF(Egyptian_Hieroglyphs, "Egyp") 82 | DEF(Elbasan, "Elba") 83 | DEF(Elymaic, "Elym") 84 | DEF(Ethiopic, "Ethi") 85 | DEF(Georgian, "Geor") 86 | DEF(Glagolitic, "Glag") 87 | DEF(Gothic, "Goth") 88 | DEF(Grantha, "Gran") 89 | DEF(Greek, "Grek") 90 | DEF(Gujarati, "Gujr") 91 | DEF(Gunjala_Gondi, "Gong") 92 | DEF(Gurmukhi, "Guru") 93 | DEF(Han, "Hani") 94 | DEF(Hangul, "Hang") 95 | DEF(Hanifi_Rohingya, "Rohg") 96 | DEF(Hanunoo, "Hano") 97 | DEF(Hatran, "Hatr") 98 | DEF(Hebrew, "Hebr") 99 | DEF(Hiragana, "Hira") 100 | DEF(Imperial_Aramaic, "Armi") 101 | DEF(Inherited, "Zinh,Qaai") 102 | DEF(Inscriptional_Pahlavi, "Phli") 103 | DEF(Inscriptional_Parthian, "Prti") 104 | DEF(Javanese, "Java") 105 | DEF(Kaithi, "Kthi") 106 | DEF(Kannada, "Knda") 107 | DEF(Katakana, "Kana") 108 | DEF(Kawi, "Kawi") 109 | DEF(Kayah_Li, "Kali") 110 | DEF(Kharoshthi, "Khar") 111 | DEF(Khmer, "Khmr") 112 | DEF(Khojki, "Khoj") 113 | DEF(Khitan_Small_Script, "Kits") 114 | DEF(Khudawadi, "Sind") 115 | DEF(Lao, "Laoo") 116 | DEF(Latin, "Latn") 117 | DEF(Lepcha, "Lepc") 118 | DEF(Limbu, "Limb") 119 | DEF(Linear_A, "Lina") 120 | DEF(Linear_B, "Linb") 121 | DEF(Lisu, "Lisu") 122 | DEF(Lycian, "Lyci") 123 | DEF(Lydian, "Lydi") 124 | DEF(Makasar, "Maka") 125 | DEF(Mahajani, "Mahj") 126 | DEF(Malayalam, "Mlym") 127 | DEF(Mandaic, "Mand") 128 | DEF(Manichaean, "Mani") 129 | DEF(Marchen, "Marc") 130 | DEF(Masaram_Gondi, "Gonm") 131 | DEF(Medefaidrin, "Medf") 132 | DEF(Meetei_Mayek, "Mtei") 133 | DEF(Mende_Kikakui, "Mend") 134 | DEF(Meroitic_Cursive, "Merc") 135 | DEF(Meroitic_Hieroglyphs, "Mero") 136 | DEF(Miao, "Plrd") 137 | DEF(Modi, "Modi") 138 | DEF(Mongolian, "Mong") 139 | DEF(Mro, "Mroo") 140 | DEF(Multani, "Mult") 141 | DEF(Myanmar, "Mymr") 142 | DEF(Nabataean, "Nbat") 143 | DEF(Nag_Mundari, "Nagm") 144 | DEF(Nandinagari, "Nand") 145 | DEF(New_Tai_Lue, "Talu") 146 | DEF(Newa, "Newa") 147 | DEF(Nko, "Nkoo") 148 | DEF(Nushu, "Nshu") 149 | DEF(Nyiakeng_Puachue_Hmong, "Hmnp") 150 | DEF(Ogham, "Ogam") 151 | DEF(Ol_Chiki, "Olck") 152 | DEF(Old_Hungarian, "Hung") 153 | DEF(Old_Italic, "Ital") 154 | DEF(Old_North_Arabian, "Narb") 155 | DEF(Old_Permic, "Perm") 156 | DEF(Old_Persian, "Xpeo") 157 | DEF(Old_Sogdian, "Sogo") 158 | DEF(Old_South_Arabian, "Sarb") 159 | DEF(Old_Turkic, "Orkh") 160 | DEF(Old_Uyghur, "Ougr") 161 | DEF(Oriya, "Orya") 162 | DEF(Osage, "Osge") 163 | DEF(Osmanya, "Osma") 164 | DEF(Pahawh_Hmong, "Hmng") 165 | DEF(Palmyrene, "Palm") 166 | DEF(Pau_Cin_Hau, "Pauc") 167 | DEF(Phags_Pa, "Phag") 168 | DEF(Phoenician, "Phnx") 169 | DEF(Psalter_Pahlavi, "Phlp") 170 | DEF(Rejang, "Rjng") 171 | DEF(Runic, "Runr") 172 | DEF(Samaritan, "Samr") 173 | DEF(Saurashtra, "Saur") 174 | DEF(Sharada, "Shrd") 175 | DEF(Shavian, "Shaw") 176 | DEF(Siddham, "Sidd") 177 | DEF(SignWriting, "Sgnw") 178 | DEF(Sinhala, "Sinh") 179 | DEF(Sogdian, "Sogd") 180 | DEF(Sora_Sompeng, "Sora") 181 | DEF(Soyombo, "Soyo") 182 | DEF(Sundanese, "Sund") 183 | DEF(Syloti_Nagri, "Sylo") 184 | DEF(Syriac, "Syrc") 185 | DEF(Tagalog, "Tglg") 186 | DEF(Tagbanwa, "Tagb") 187 | DEF(Tai_Le, "Tale") 188 | DEF(Tai_Tham, "Lana") 189 | DEF(Tai_Viet, "Tavt") 190 | DEF(Takri, "Takr") 191 | DEF(Tamil, "Taml") 192 | DEF(Tangut, "Tang") 193 | DEF(Telugu, "Telu") 194 | DEF(Thaana, "Thaa") 195 | DEF(Thai, "Thai") 196 | DEF(Tibetan, "Tibt") 197 | DEF(Tifinagh, "Tfng") 198 | DEF(Tirhuta, "Tirh") 199 | DEF(Tangsa, "Tnsa") 200 | DEF(Toto, "Toto") 201 | DEF(Ugaritic, "Ugar") 202 | DEF(Vai, "Vaii") 203 | DEF(Vithkuqi, "Vith") 204 | DEF(Wancho, "Wcho") 205 | DEF(Warang_Citi, "Wara") 206 | DEF(Yezidi, "Yezi") 207 | DEF(Yi, "Yiii") 208 | DEF(Zanabazar_Square, "Zanb") 209 | #endif 210 | 211 | #ifdef UNICODE_PROP_LIST 212 | /* Prop list not exported to regexp */ 213 | DEF(Hyphen, "") 214 | DEF(Other_Math, "") 215 | DEF(Other_Alphabetic, "") 216 | DEF(Other_Lowercase, "") 217 | DEF(Other_Uppercase, "") 218 | DEF(Other_Grapheme_Extend, "") 219 | DEF(Other_Default_Ignorable_Code_Point, "") 220 | DEF(Other_ID_Start, "") 221 | DEF(Other_ID_Continue, "") 222 | DEF(Prepended_Concatenation_Mark, "") 223 | /* additional computed properties for smaller tables */ 224 | DEF(ID_Continue1, "") 225 | DEF(XID_Start1, "") 226 | DEF(XID_Continue1, "") 227 | DEF(Changes_When_Titlecased1, "") 228 | DEF(Changes_When_Casefolded1, "") 229 | DEF(Changes_When_NFKC_Casefolded1, "") 230 | 231 | /* Prop list exported to JS */ 232 | DEF(ASCII_Hex_Digit, "AHex") 233 | DEF(Bidi_Control, "Bidi_C") 234 | DEF(Dash, "") 235 | DEF(Deprecated, "Dep") 236 | DEF(Diacritic, "Dia") 237 | DEF(Extender, "Ext") 238 | DEF(Hex_Digit, "Hex") 239 | DEF(IDS_Binary_Operator, "IDSB") 240 | DEF(IDS_Trinary_Operator, "IDST") 241 | DEF(Ideographic, "Ideo") 242 | DEF(Join_Control, "Join_C") 243 | DEF(Logical_Order_Exception, "LOE") 244 | DEF(Noncharacter_Code_Point, "NChar") 245 | DEF(Pattern_Syntax, "Pat_Syn") 246 | DEF(Pattern_White_Space, "Pat_WS") 247 | DEF(Quotation_Mark, "QMark") 248 | DEF(Radical, "") 249 | DEF(Regional_Indicator, "RI") 250 | DEF(Sentence_Terminal, "STerm") 251 | DEF(Soft_Dotted, "SD") 252 | DEF(Terminal_Punctuation, "Term") 253 | DEF(Unified_Ideograph, "UIdeo") 254 | DEF(Variation_Selector, "VS") 255 | DEF(White_Space, "space") 256 | DEF(Bidi_Mirrored, "Bidi_M") 257 | DEF(Emoji, "") 258 | DEF(Emoji_Component, "EComp") 259 | DEF(Emoji_Modifier, "EMod") 260 | DEF(Emoji_Modifier_Base, "EBase") 261 | DEF(Emoji_Presentation, "EPres") 262 | DEF(Extended_Pictographic, "ExtPict") 263 | DEF(Default_Ignorable_Code_Point, "DI") 264 | DEF(ID_Start, "IDS") 265 | DEF(Case_Ignorable, "CI") 266 | 267 | /* other binary properties */ 268 | DEF(ASCII,"") 269 | DEF(Alphabetic, "Alpha") 270 | DEF(Any, "") 271 | DEF(Assigned,"") 272 | DEF(Cased, "") 273 | DEF(Changes_When_Casefolded, "CWCF") 274 | DEF(Changes_When_Casemapped, "CWCM") 275 | DEF(Changes_When_Lowercased, "CWL") 276 | DEF(Changes_When_NFKC_Casefolded, "CWKCF") 277 | DEF(Changes_When_Titlecased, "CWT") 278 | DEF(Changes_When_Uppercased, "CWU") 279 | DEF(Grapheme_Base, "Gr_Base") 280 | DEF(Grapheme_Extend, "Gr_Ext") 281 | DEF(ID_Continue, "IDC") 282 | DEF(Lowercase, "Lower") 283 | DEF(Math, "") 284 | DEF(Uppercase, "Upper") 285 | DEF(XID_Continue, "XIDC") 286 | DEF(XID_Start, "XIDS") 287 | 288 | /* internal tables with index */ 289 | DEF(Cased1, "") 290 | 291 | #endif 292 | --------------------------------------------------------------------------------