├── .gitignore
├── Changelog
├── Makefile
├── README.md
├── TODO
├── VERSION
├── bench
├── test.c
├── test.js
└── test.wasm
├── build.sh
├── compile-bench.sh
├── cutils.c
├── cutils.h
├── jscompress.c
├── libbf.c
├── libbf.h
├── libregexp-opcode.h
├── libregexp.c
├── libregexp.h
├── libunicode-table.h
├── libunicode.c
├── libunicode.h
├── list.h
├── qjs.c
├── qjsc.c
├── qjsc.precompiled
├── qjscalc.js
├── quickjs-atom.h
├── quickjs-libc.c
├── quickjs-libc.h
├── quickjs-opcode.h
├── quickjs.c
├── quickjs.h
├── release.sh
├── 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_loop.js
├── test_op.js
├── test_op_overloading.js
├── test_qjscalc.js
└── test_std.js
├── unicode_download.sh
├── unicode_gen.c
└── unicode_gen_def.h
/.gitignore:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dip-proto/quickjs-wasi/802bb926008a68812bfb991f536df9c5039fdb01/.gitignore
--------------------------------------------------------------------------------
/Changelog:
--------------------------------------------------------------------------------
1 | 2020-01-19:
2 |
3 | - keep CONFIG_BIGNUM in the makefile
4 | - added os.chdir()
5 | - qjs: added -I option
6 | - more memory checks in the bignum operations
7 | - modified operator overloading semantics to be closer to the TC39
8 | proposal
9 | - suppressed "use bigint" mode. Simplified "use math" mode
10 | - BigDecimal: changed suffix from 'd' to 'm'
11 | - misc bug fixes
12 |
13 | 2020-01-05:
14 |
15 | - always compile the bignum code. Added '--bignum' option to qjs.
16 | - added BigDecimal
17 | - added String.prototype.replaceAll
18 | - misc bug fixes
19 |
20 | 2019-12-21:
21 |
22 | - added nullish coalescing operator (ES2020)
23 | - added optional chaining (ES2020)
24 | - removed recursions in garbage collector
25 | - test stack overflow in the parser
26 | - improved backtrace logic
27 | - added JS_SetHostPromiseRejectionTracker()
28 | - allow exotic constructors
29 | - improved c++ compatibility
30 | - misc bug fixes
31 |
32 | 2019-10-27:
33 |
34 | - added example of C class in a module (examples/test_point.js)
35 | - added JS_GetTypedArrayBuffer()
36 | - misc bug fixes
37 |
38 | 2019-09-18:
39 |
40 | - added os.exec and other system calls
41 | - exported JS_ValueToAtom()
42 | - qjsc: added 'qjsc_' prefix to the generated C identifiers
43 | - added cross-compilation support
44 | - misc bug fixes
45 |
46 | 2019-09-01:
47 |
48 | - added globalThis
49 | - documented JS_EVAL_FLAG_COMPILE_ONLY
50 | - added import.meta.url and import.meta.main
51 | - added 'debugger' statement
52 | - misc bug fixes
53 |
54 | 2019-08-18:
55 |
56 | - added os.realpath, os.getcwd, os.mkdir, os.stat, os.lstat,
57 | os.readlink, os.readdir, os.utimes, std.popen
58 | - module autodetection
59 | - added import.meta
60 | - misc bug fixes
61 |
62 | 2019-08-10:
63 |
64 | - added public class fields and private class fields, methods and
65 | accessors (TC39 proposal)
66 | - changed JS_ToCStringLen() prototype
67 | - qjsc: handle '-' in module names and modules with the same filename
68 | - added std.urlGet
69 | - exported JS_GetOwnPropertyNames() and JS_GetOwnProperty()
70 | - exported some bigint C functions
71 | - added support for eshost in run-test262
72 | - misc bug fixes
73 |
74 | 2019-07-28:
75 |
76 | - added dynamic import
77 | - added Promise.allSettled
78 | - added String.prototype.matchAll
79 | - added Object.fromEntries
80 | - reduced number of ticks in await
81 | - added BigInt support in Atomics
82 | - exported JS_NewPromiseCapability()
83 | - misc async function and async generator fixes
84 | - enabled hashbang support by default
85 |
86 | 2019-07-21:
87 |
88 | - updated test262 tests
89 | - updated to Unicode version 12.1.0
90 | - fixed missing Date object in qjsc
91 | - fixed multi-context creation
92 | - misc ES2020 related fixes
93 | - simplified power and division operators in bignum extension
94 | - fixed several crash conditions
95 |
96 | 2019-07-09:
97 |
98 | - first public release
99 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # QuickJS Javascript Engine
3 | #
4 | # Copyright (c) 2017-2020 Fabrice Bellard
5 | # Copyright (c) 2017-2020 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 |
37 | ifdef CONFIG_DARWIN
38 | # use clang instead of gcc
39 | CONFIG_CLANG=y
40 | CONFIG_DEFAULT_AR=y
41 | endif
42 |
43 | # installation directory
44 | prefix=/usr/local
45 |
46 | # use the gprof profiler
47 | #CONFIG_PROFILE=y
48 | # use address sanitizer
49 | #CONFIG_ASAN=y
50 | # include the code for BigInt/BigFloat/BigDecimal and math mode
51 | CONFIG_BIGNUM=y
52 |
53 | OBJDIR=.obj
54 |
55 | ifdef CONFIG_WIN32
56 | CROSS_PREFIX=i686-w64-mingw32-
57 | EXE=.exe
58 | else
59 | CROSS_PREFIX=
60 | EXE=
61 | endif
62 | ifdef CONFIG_CLANG
63 | HOST_CC=clang
64 | CROSS_PREFIX=/usr/local/opt/llvm/bin/
65 | CC=$(CROSS_PREFIX)clang
66 | CFLAGS=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d
67 | CFLAGS += --target=wasm32-wasi --sysroot=/opt/wasi-sysroot -D__wasi__=1
68 | CFLAGS += -Wextra
69 | CFLAGS += -Wno-sign-compare
70 | CFLAGS += -Wno-missing-field-initializers
71 | CFLAGS += -Wundef -Wuninitialized
72 | CFLAGS += -Wno-unused -Wno-unused-parameter
73 | CFLAGS += -Wwrite-strings
74 | CFLAGS += -Wchar-subscripts -funsigned-char
75 | CFLAGS += -MMD -MF $(OBJDIR)/$(@F).d
76 | ifdef CONFIG_DEFAULT_AR
77 | AR=$(CROSS_PREFIX)llvm-ar
78 | else
79 | ifdef CONFIG_LTO
80 | AR=$(CROSS_PREFIX)llvm-ar
81 | else
82 | AR=$(CROSS_PREFIX)llvm-ar
83 | endif
84 | endif
85 | else
86 | HOST_CC=gcc
87 | CC=$(CROSS_PREFIX)gcc
88 | CFLAGS=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d
89 | CFLAGS += -Wno-array-bounds -Wno-format-truncation
90 | ifdef CONFIG_LTO
91 | AR=$(CROSS_PREFIX)gcc-ar
92 | else
93 | AR=$(CROSS_PREFIX)ar
94 | endif
95 | endif
96 | STRIP=$(CROSS_PREFIX)strip
97 | ifdef CONFIG_WERROR
98 | CFLAGS+=-Werror
99 | endif
100 | DEFINES:=-D_GNU_SOURCE -DCONFIG_VERSION=\"$(shell cat VERSION)\"
101 | ifdef CONFIG_BIGNUM
102 | DEFINES+=-DCONFIG_BIGNUM
103 | endif
104 | CFLAGS+=$(DEFINES)
105 | CFLAGS_DEBUG=$(CFLAGS) -O0
106 | CFLAGS_SMALL=$(CFLAGS) -Os
107 | CFLAGS_OPT=$(CFLAGS) -Ofast
108 | CFLAGS_NOLTO:=$(CFLAGS_OPT)
109 | LDFLAGS=-g --target=wasm32-wasi --sysroot=/opt/wasi-sysroot -D__wasi__=1
110 | ifdef CONFIG_LTO
111 | CFLAGS_SMALL+=-flto
112 | CFLAGS_OPT+=-flto
113 | LDFLAGS+=-flto
114 | endif
115 | ifdef CONFIG_PROFILE
116 | CFLAGS+=-p
117 | LDFLAGS+=-p
118 | endif
119 | ifdef CONFIG_ASAN
120 | CFLAGS+=-fsanitize=address
121 | LDFLAGS+=-fsanitize=address
122 | endif
123 | ifdef CONFIG_WIN32
124 | LDEXPORT=
125 | else
126 | LDEXPORT=-rdynamic
127 | endif
128 |
129 | PROGS=qjs$(EXE) qjsc$(EXE)
130 | ifneq ($(CROSS_PREFIX),)
131 | QJSC_CC=gcc
132 | QJSC=wavm run --mount-root . --enable all-proposed host-qjsc
133 | PROGS+=$(QJSC)
134 | else
135 | QJSC_CC=$(CC)
136 | QJSC=./qjsc$(EXE)
137 | endif
138 | ifndef CONFIG_WIN32
139 | PROGS+=qjscalc
140 | endif
141 | ifdef CONFIG_M32
142 | PROGS+=qjs32 qjs32_s
143 | endif
144 | PROGS+=libquickjs.a
145 | ifdef CONFIG_LTO
146 | PROGS+=libquickjs.lto.a
147 | endif
148 |
149 | # examples
150 | ifeq ($(CROSS_PREFIX),)
151 | ifdef CONFIG_ASAN
152 | PROGS+=
153 | else
154 | PROGS+=examples/hello examples/hello_module examples/test_fib
155 | ifndef CONFIG_DARWIN
156 | PROGS+=examples/fib.so examples/point.so
157 | endif
158 | endif
159 | endif
160 |
161 | all: $(OBJDIR) $(OBJDIR)/quickjs.check.o $(OBJDIR)/qjs.check.o $(PROGS)
162 |
163 | QJS_LIB_OBJS=$(OBJDIR)/quickjs.o $(OBJDIR)/libregexp.o $(OBJDIR)/libunicode.o $(OBJDIR)/cutils.o $(OBJDIR)/quickjs-libc.o
164 |
165 | QJS_OBJS=$(OBJDIR)/qjs.o $(OBJDIR)/repl.o $(QJS_LIB_OBJS)
166 | ifdef CONFIG_BIGNUM
167 | QJS_LIB_OBJS+=$(OBJDIR)/libbf.o
168 | QJS_OBJS+=$(OBJDIR)/qjscalc.o
169 | endif
170 |
171 | LIBS=-lm
172 | ifndef CONFIG_WIN32
173 | LIBS+=-ldl
174 | endif
175 |
176 | $(OBJDIR):
177 | mkdir -p $(OBJDIR) $(OBJDIR)/examples $(OBJDIR)/tests
178 |
179 | qjs$(EXE): $(QJS_OBJS)
180 | $(CC) $(LDFLAGS) $(LDEXPORT) -o $@ $^ $(LIBS)
181 |
182 | qjs-debug$(EXE): $(patsubst %.o, %.debug.o, $(QJS_OBJS))
183 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
184 |
185 | qjsc$(EXE): $(OBJDIR)/qjsc.o $(QJS_LIB_OBJS)
186 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
187 |
188 | ifneq ($(CROSS_PREFIX),)
189 |
190 | $(QJSC): $(OBJDIR)/qjsc.host.o \
191 | $(patsubst %.o, %.host.o, $(QJS_LIB_OBJS))
192 | $(HOST_CC) $(LDFLAGS) -o $@ $^ $(LIBS)
193 |
194 | endif #CROSS_PREFIX
195 |
196 | QJSC_DEFINES:=-DCONFIG_CC=\"$(QJSC_CC)\" -DCONFIG_PREFIX=\"$(prefix)\"
197 | ifdef CONFIG_LTO
198 | QJSC_DEFINES+=-DCONFIG_LTO
199 | endif
200 | QJSC_HOST_DEFINES:=-DCONFIG_CC=\"$(HOST_CC)\" -DCONFIG_PREFIX=\"$(prefix)\"
201 |
202 | $(OBJDIR)/qjsc.o: CFLAGS+=$(QJSC_DEFINES)
203 | $(OBJDIR)/qjsc.host.o: CFLAGS+=$(QJSC_HOST_DEFINES)
204 |
205 | qjs32: $(patsubst %.o, %.m32.o, $(QJS_OBJS))
206 | $(CC) -m32 $(LDFLAGS) $(LDEXPORT) -o $@ $^ $(LIBS)
207 |
208 | qjs32_s: $(patsubst %.o, %.m32s.o, $(QJS_OBJS))
209 | $(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS)
210 | @size $@
211 |
212 | qjscalc: qjs
213 | ln -sf $< $@
214 |
215 | ifdef CONFIG_LTO
216 | LTOEXT=.lto
217 | else
218 | LTOEXT=
219 | endif
220 |
221 | libquickjs$(LTOEXT).a: $(QJS_LIB_OBJS)
222 | $(AR) rcs $@ $^
223 |
224 | ifdef CONFIG_LTO
225 | libquickjs.a: $(patsubst %.o, %.nolto.o, $(QJS_LIB_OBJS))
226 | $(AR) rcs $@ $^
227 | endif # CONFIG_LTO
228 |
229 | repl.c: $(QJSC) repl.js
230 | $(QJSC) -c -o $@ -m repl.js
231 |
232 | qjscalc.c: $(QJSC) qjscalc.js
233 | $(QJSC) -fbignum -c -o $@ qjscalc.js
234 |
235 | ifneq ($(wildcard unicode/UnicodeData.txt),)
236 | $(OBJDIR)/libunicode.o $(OBJDIR)/libunicode.m32.o $(OBJDIR)/libunicode.m32s.o \
237 | $(OBJDIR)/libunicode.nolto.o: libunicode-table.h
238 |
239 | libunicode-table.h: unicode_gen
240 | ./unicode_gen unicode $@
241 | endif
242 |
243 | # object suffix order: nolto, [m32|m32s]
244 |
245 | $(OBJDIR)/%.o: %.c | $(OBJDIR)
246 | $(CC) $(CFLAGS_OPT) -c -o $@ $<
247 |
248 | $(OBJDIR)/%.host.o: %.c | $(OBJDIR)
249 | $(HOST_CC) $(CFLAGS_OPT) -c -o $@ $<
250 |
251 | $(OBJDIR)/%.pic.o: %.c | $(OBJDIR)
252 | $(CC) $(CFLAGS_OPT) -fPIC -DJS_SHARED_LIBRARY -c -o $@ $<
253 |
254 | $(OBJDIR)/%.nolto.o: %.c | $(OBJDIR)
255 | $(CC) $(CFLAGS_NOLTO) -c -o $@ $<
256 |
257 | $(OBJDIR)/%.m32.o: %.c | $(OBJDIR)
258 | $(CC) -m32 $(CFLAGS_OPT) -c -o $@ $<
259 |
260 | $(OBJDIR)/%.m32s.o: %.c | $(OBJDIR)
261 | $(CC) -m32 $(CFLAGS_SMALL) -c -o $@ $<
262 |
263 | $(OBJDIR)/%.debug.o: %.c | $(OBJDIR)
264 | $(CC) $(CFLAGS_DEBUG) -c -o $@ $<
265 |
266 | $(OBJDIR)/%.check.o: %.c | $(OBJDIR)
267 | $(CC) $(CFLAGS) -DCONFIG_CHECK_JSVALUE -c -o $@ $<
268 |
269 | regexp_test: libregexp.c libunicode.c cutils.c
270 | $(CC) $(LDFLAGS) $(CFLAGS) -DTEST -o $@ libregexp.c libunicode.c cutils.c $(LIBS)
271 |
272 | jscompress: jscompress.c
273 | $(CC) $(LDFLAGS) $(CFLAGS) -o $@ jscompress.c
274 |
275 | unicode_gen: $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o libunicode.c unicode_gen_def.h
276 | $(HOST_CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o
277 |
278 | clean:
279 | rm -f repl.c qjscalc.c out.c
280 | rm -f *.a *.o *.d *~ jscompress unicode_gen regexp_test $(PROGS)
281 | rm -f hello.c hello_module.c test_fib.c
282 | rm -f examples/*.so tests/*.so
283 | rm -rf $(OBJDIR)/ *.dSYM/ qjs-debug
284 | rm -rf run-test262-debug run-test262-32
285 |
286 | install: all
287 | mkdir -p "$(DESTDIR)$(prefix)/bin"
288 | $(STRIP) qjs qjsc
289 | install -m755 qjs qjsc "$(DESTDIR)$(prefix)/bin"
290 | ln -sf qjs "$(DESTDIR)$(prefix)/bin/qjscalc"
291 | mkdir -p "$(DESTDIR)$(prefix)/lib/quickjs"
292 | install -m644 libquickjs.a "$(DESTDIR)$(prefix)/lib/quickjs"
293 | ifdef CONFIG_LTO
294 | install -m644 libquickjs.lto.a "$(DESTDIR)$(prefix)/lib/quickjs"
295 | endif
296 | mkdir -p "$(DESTDIR)$(prefix)/include/quickjs"
297 | install -m644 quickjs.h quickjs-libc.h "$(DESTDIR)$(prefix)/include/quickjs"
298 |
299 | ###############################################################################
300 | # examples
301 |
302 | # example of static JS compilation
303 | HELLO_SRCS=examples/hello.js
304 | HELLO_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \
305 | -fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \
306 | -fno-date -fno-module-loader
307 | ifdef CONFIG_BIGNUM
308 | HELLO_OPTS+=-fno-bigint
309 | endif
310 |
311 | hello.c: $(QJSC) $(HELLO_SRCS)
312 | $(QJSC) -e $(HELLO_OPTS) -o $@ $(HELLO_SRCS)
313 |
314 | ifdef CONFIG_M32
315 | examples/hello: $(OBJDIR)/hello.m32s.o $(patsubst %.o, %.m32s.o, $(QJS_LIB_OBJS))
316 | $(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS)
317 | else
318 | examples/hello: $(OBJDIR)/hello.o $(QJS_LIB_OBJS)
319 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
320 | endif
321 |
322 | # example of static JS compilation with modules
323 | HELLO_MODULE_SRCS=examples/hello_module.js
324 | HELLO_MODULE_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \
325 | -fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \
326 | -fno-date -m
327 | examples/hello_module: $(QJSC) libquickjs$(LTOEXT).a $(HELLO_MODULE_SRCS)
328 | $(QJSC) $(HELLO_MODULE_OPTS) -o $@ $(HELLO_MODULE_SRCS)
329 |
330 | # use of an external C module (static compilation)
331 |
332 | test_fib.c: $(QJSC) examples/test_fib.js
333 | $(QJSC) -e -M examples/fib.so,fib -m -o $@ examples/test_fib.js
334 |
335 | examples/test_fib: $(OBJDIR)/test_fib.o $(OBJDIR)/examples/fib.o libquickjs$(LTOEXT).a
336 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
337 |
338 | examples/fib.so: $(OBJDIR)/examples/fib.pic.o
339 | $(CC) $(LDFLAGS) -shared -o $@ $^
340 |
341 | examples/point.so: $(OBJDIR)/examples/point.pic.o
342 | $(CC) $(LDFLAGS) -shared -o $@ $^
343 |
344 | ###############################################################################
345 | # documentation
346 |
347 | DOCS=doc/quickjs.pdf doc/quickjs.html doc/jsbignum.pdf doc/jsbignum.html
348 |
349 | build_doc: $(DOCS)
350 |
351 | clean_doc:
352 | rm -f $(DOCS)
353 |
354 | doc/%.pdf: doc/%.texi
355 | texi2pdf --clean -o $@ -q $<
356 |
357 | doc/%.html.pre: doc/%.texi
358 | makeinfo --html --no-headers --no-split --number-sections -o $@ $<
359 |
360 | doc/%.html: doc/%.html.pre
361 | sed -e 's||\n|' < $< > $@
362 |
363 | ###############################################################################
364 | # tests
365 |
366 | ifndef CONFIG_DARWIN
367 | test: tests/bjson.so examples/point.so
368 | endif
369 | ifdef CONFIG_M32
370 | test: qjs32
371 | endif
372 |
373 | test: qjs
374 | ./qjs tests/test_closure.js
375 | ./qjs tests/test_op.js
376 | ./qjs tests/test_builtin.js
377 | ./qjs tests/test_loop.js
378 | ./qjs tests/test_std.js
379 | ifndef CONFIG_DARWIN
380 | ifdef CONFIG_BIGNUM
381 | ./qjs --bignum tests/test_bjson.js
382 | else
383 | ./qjs tests/test_bjson.js
384 | endif
385 | ./qjs examples/test_point.js
386 | endif
387 | ifdef CONFIG_BIGNUM
388 | ./qjs --bignum tests/test_op_overloading.js
389 | ./qjs --bignum tests/test_bignum.js
390 | ./qjs --qjscalc tests/test_qjscalc.js
391 | endif
392 | ifdef CONFIG_M32
393 | ./qjs32 tests/test_closure.js
394 | ./qjs32 tests/test_op.js
395 | ./qjs32 tests/test_builtin.js
396 | ./qjs32 tests/test_loop.js
397 | ./qjs32 tests/test_std.js
398 | ifdef CONFIG_BIGNUM
399 | ./qjs32 --bignum tests/test_op_overloading.js
400 | ./qjs32 --bignum tests/test_bignum.js
401 | ./qjs32 --qjscalc tests/test_qjscalc.js
402 | endif
403 | endif
404 |
405 | stats: qjs qjs32
406 | ./qjs -qd
407 | ./qjs32 -qd
408 |
409 | microbench: qjs
410 | ./qjs tests/microbench.js
411 |
412 | microbench-32: qjs32
413 | ./qjs32 tests/microbench.js
414 |
415 | testall: all test microbench test2o test2
416 |
417 | testall-32: all test-32 microbench-32 test2o-32 test2-32
418 |
419 | testall-complete: testall testall-32
420 |
421 | bench-v8: qjs
422 | make -C tests/bench-v8
423 | ./qjs -d tests/bench-v8/combined.js
424 |
425 | tests/bjson.so: $(OBJDIR)/tests/bjson.pic.o
426 | $(CC) $(LDFLAGS) -shared -o $@ $^ $(LIBS)
427 |
428 | -include $(wildcard $(OBJDIR)/*.d)
429 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Build dependencies:
2 |
3 | - `wavm` (or set the `QJSC` value in the `Makefile` accordingly)
4 | - LLVM (`brew install llvm`)
5 | - [`libclang_rt.builtins-wasm32.a`](https://github.com/jedisct1/libclang_rt.builtins-wasm32.a)
6 | - [`wasi-sysroot`](https://github.com/WebAssembly/wasi-sdk/releases) installed in `/opt/wasi-sysroot`.
7 |
8 | ## Compilation (on MacOS):
9 |
10 | ```sh
11 | export PATH=/usr/local/opt/llvm/bin:$PATH
12 | make
13 | ```
14 |
--------------------------------------------------------------------------------
/TODO:
--------------------------------------------------------------------------------
1 | Misc:
2 | - use custom printf to avoid C library compatibility issues
3 | - rename CONFIG_ALL_UNICODE, CONFIG_BIGNUM, CONFIG_ATOMICS, CONFIG_CHECK_JSVALUE ?
4 | - unify coding style and naming conventions
5 | - use names from the ECMA spec in library implementation
6 | - modules: if no ".", use a well known module loading path ?
7 | - use JSHoistedDef only for global variables (JSHoistedDef.var_name != JS_ATOM_NULL)
8 | - add index in JSVarDef and is_arg flag to merge args and vars in JSFunctionDef
9 | - replace most JSVarDef flags with var_type enumeration
10 | - use byte code emitters with typed arguments (for clarity)
11 | - use 2 bytecode DynBufs in JSFunctionDef, one for reading, one for writing
12 | and use the same wrappers in all phases
13 | - use more generic method for line numbers in resolve_variables and resolve_labels
14 | - use custom timezone support to avoid C library compatibility issues
15 |
16 | Memory:
17 | - test border cases for max number of atoms, object properties, string length
18 | - add emergency malloc mode for out of memory exceptions.
19 | - test all DynBuf memory errors
20 | - test all js_realloc memory errors
21 | - bignum: handle memory errors
22 | - use memory pools for objects, etc?
23 | - improve JS_ComputeMemoryUsage() with more info
24 |
25 | Optimizations:
26 | - 64-bit atoms in 64-bit mode ?
27 | - use auto-init properties for more global objects
28 | - reuse stack slots for disjoint scopes, if strip
29 | - optimize `for of` iterator for built-in array objects
30 | - add heuristic to avoid some cycles in closures
31 | - small String (0-2 charcodes) with immediate storage
32 | - perform static string concatenation at compile time
33 | - optimize string concatenation with ropes or miniropes?
34 | - add implicit numeric strings for Uint32 numbers?
35 | - optimize `s += a + b`, `s += a.b` and similar simple expressions
36 | - ensure string canonical representation and optimise comparisons and hashes?
37 | - remove JSObject.first_weak_ref, use bit+context based hashed array for weak references
38 | - optimize function storage with length and name accessors?
39 | - property access optimization on the global object, functions,
40 | prototypes and special non extensible objects.
41 | - create object literals with the correct length by backpatching length argument
42 | - remove redundant set_loc_uninitialized/check_uninitialized opcodes
43 | - peephole optim: push_atom_value, to_propkey -> push_atom_value
44 | - peephole optim: put_loc x, get_loc_check x -> set_loc x
45 | - comparative performance benchmark
46 | - use variable name when throwing uninitialized exception if available
47 | - convert slow array to fast array when all properties != length are numeric
48 | - optimize destructuring assignments for global and local variables
49 | - implement some form of tail-call-optimization
50 | - optimize OP_apply
51 | - optimize f(...b)
52 |
53 | Extensions:
54 | - support more features in [features] section
55 | - add built-in preprocessor in compiler, get rid of jscompress
56 | handle #if, #ifdef, #line, limited support for #define
57 | - get rid of __loadScript, use more common name
58 | - BSD sockets
59 | - Workers
60 |
61 | REPL:
62 | - debugger
63 | - readline: support MS Windows terminal
64 | - readline: handle dynamic terminal resizing
65 | - multiline editing
66 | - runtime object and function inspectors
67 | - interactive object browser
68 | - use more generic approach to display evaluation results
69 | - improve directive handling: dispatch, colorize, completion...
70 | - save history
71 | - close all predefined methods in repl.js and jscalc.js
72 |
73 | Test262o: 0/11262 errors, 463 excluded
74 | Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
75 |
76 | Test262: 17/69942 errors, 855 excluded, 581 skipped
77 | test262 commit: 28b4fcca4b1b1d278dfe0cc0e69c7d9d59b31aab
78 |
--------------------------------------------------------------------------------
/VERSION:
--------------------------------------------------------------------------------
1 | 2020-01-19
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/dip-proto/quickjs-wasi/802bb926008a68812bfb991f536df9c5039fdb01/bench/test.wasm
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | compile.sh
--------------------------------------------------------------------------------
/compile-bench.sh:
--------------------------------------------------------------------------------
1 | #! /bin/sh
2 |
3 | export PATH=/usr/local/opt/llvm/bin:$PATH
4 |
5 | wavm run --mount-root . --enable all-proposed --precompiled \
6 | ./qjsc -e -o bench/test.c \
7 | -flto -fno-eval -fno-bigint -fno-module-loader -fno-proxy bench/test.js
8 |
9 | clang --target=wasm32-wasi --sysroot=/opt/wasi-libc \
10 | -I . bench/test.c libquickjs.lto.a -flto -O2 -s -o bench/test.wasm
11 |
12 | wavm compile --enable all-proposed bench/test.wasm bench/test.wasm.precompiled &&
13 | mv -f bench/test.wasm.precompiled bench/test.wasm
14 |
15 | wavm run --enable all-proposed --precompiled bench/test.wasm
16 |
--------------------------------------------------------------------------------
/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 | typedef int BOOL;
53 |
54 | #ifndef FALSE
55 | enum {
56 | FALSE = 0,
57 | TRUE = 1,
58 | };
59 | #endif
60 |
61 | void pstrcpy(char *buf, int buf_size, const char *str);
62 | char *pstrcat(char *buf, int buf_size, const char *s);
63 | int strstart(const char *str, const char *val, const char **ptr);
64 | int has_suffix(const char *str, const char *suffix);
65 |
66 | static inline int max_int(int a, int b)
67 | {
68 | if (a > b)
69 | return a;
70 | else
71 | return b;
72 | }
73 |
74 | static inline int min_int(int a, int b)
75 | {
76 | if (a < b)
77 | return a;
78 | else
79 | return b;
80 | }
81 |
82 | static inline uint32_t max_uint32(uint32_t a, uint32_t b)
83 | {
84 | if (a > b)
85 | return a;
86 | else
87 | return b;
88 | }
89 |
90 | static inline uint32_t min_uint32(uint32_t a, uint32_t b)
91 | {
92 | if (a < b)
93 | return a;
94 | else
95 | return b;
96 | }
97 |
98 | static inline int64_t max_int64(int64_t a, int64_t b)
99 | {
100 | if (a > b)
101 | return a;
102 | else
103 | return b;
104 | }
105 |
106 | static inline int64_t min_int64(int64_t a, int64_t b)
107 | {
108 | if (a < b)
109 | return a;
110 | else
111 | return b;
112 | }
113 |
114 | /* WARNING: undefined if a = 0 */
115 | static inline int clz32(unsigned int a)
116 | {
117 | return __builtin_clz(a);
118 | }
119 |
120 | /* WARNING: undefined if a = 0 */
121 | static inline int clz64(uint64_t a)
122 | {
123 | return __builtin_clzll(a);
124 | }
125 |
126 | /* WARNING: undefined if a = 0 */
127 | static inline int ctz32(unsigned int a)
128 | {
129 | return __builtin_ctz(a);
130 | }
131 |
132 | /* WARNING: undefined if a = 0 */
133 | static inline int ctz64(uint64_t a)
134 | {
135 | return __builtin_ctzll(a);
136 | }
137 |
138 | struct __attribute__((packed)) packed_u64 {
139 | uint64_t v;
140 | };
141 |
142 | struct __attribute__((packed)) packed_u32 {
143 | uint32_t v;
144 | };
145 |
146 | struct __attribute__((packed)) packed_u16 {
147 | uint16_t v;
148 | };
149 |
150 | static inline uint64_t get_u64(const uint8_t *tab)
151 | {
152 | return ((const struct packed_u64 *)tab)->v;
153 | }
154 |
155 | static inline int64_t get_i64(const uint8_t *tab)
156 | {
157 | return (int64_t)((const struct packed_u64 *)tab)->v;
158 | }
159 |
160 | static inline void put_u64(uint8_t *tab, uint64_t val)
161 | {
162 | ((struct packed_u64 *)tab)->v = val;
163 | }
164 |
165 | static inline uint32_t get_u32(const uint8_t *tab)
166 | {
167 | return ((const struct packed_u32 *)tab)->v;
168 | }
169 |
170 | static inline int32_t get_i32(const uint8_t *tab)
171 | {
172 | return (int32_t)((const struct packed_u32 *)tab)->v;
173 | }
174 |
175 | static inline void put_u32(uint8_t *tab, uint32_t val)
176 | {
177 | ((struct packed_u32 *)tab)->v = val;
178 | }
179 |
180 | static inline uint32_t get_u16(const uint8_t *tab)
181 | {
182 | return ((const struct packed_u16 *)tab)->v;
183 | }
184 |
185 | static inline int32_t get_i16(const uint8_t *tab)
186 | {
187 | return (int16_t)((const struct packed_u16 *)tab)->v;
188 | }
189 |
190 | static inline void put_u16(uint8_t *tab, uint16_t val)
191 | {
192 | ((struct packed_u16 *)tab)->v = val;
193 | }
194 |
195 | static inline uint32_t get_u8(const uint8_t *tab)
196 | {
197 | return *tab;
198 | }
199 |
200 | static inline int32_t get_i8(const uint8_t *tab)
201 | {
202 | return (int8_t)*tab;
203 | }
204 |
205 | static inline void put_u8(uint8_t *tab, uint8_t val)
206 | {
207 | *tab = val;
208 | }
209 |
210 | static inline uint16_t bswap16(uint16_t x)
211 | {
212 | return (x >> 8) | (x << 8);
213 | }
214 |
215 | static inline uint32_t bswap32(uint32_t v)
216 | {
217 | return ((v & 0xff000000) >> 24) | ((v & 0x00ff0000) >> 8) |
218 | ((v & 0x0000ff00) << 8) | ((v & 0x000000ff) << 24);
219 | }
220 |
221 | static inline uint64_t bswap64(uint64_t v)
222 | {
223 | return ((v & ((uint64_t)0xff << (7 * 8))) >> (7 * 8)) |
224 | ((v & ((uint64_t)0xff << (6 * 8))) >> (5 * 8)) |
225 | ((v & ((uint64_t)0xff << (5 * 8))) >> (3 * 8)) |
226 | ((v & ((uint64_t)0xff << (4 * 8))) >> (1 * 8)) |
227 | ((v & ((uint64_t)0xff << (3 * 8))) << (1 * 8)) |
228 | ((v & ((uint64_t)0xff << (2 * 8))) << (3 * 8)) |
229 | ((v & ((uint64_t)0xff << (1 * 8))) << (5 * 8)) |
230 | ((v & ((uint64_t)0xff << (0 * 8))) << (7 * 8));
231 | }
232 |
233 | /* XXX: should take an extra argument to pass slack information to the caller */
234 | typedef void *DynBufReallocFunc(void *opaque, void *ptr, size_t size);
235 |
236 | typedef struct DynBuf {
237 | uint8_t *buf;
238 | size_t size;
239 | size_t allocated_size;
240 | BOOL error; /* true if a memory allocation error occurred */
241 | DynBufReallocFunc *realloc_func;
242 | void *opaque; /* for realloc_func */
243 | } DynBuf;
244 |
245 | void dbuf_init(DynBuf *s);
246 | void dbuf_init2(DynBuf *s, void *opaque, DynBufReallocFunc *realloc_func);
247 | int dbuf_realloc(DynBuf *s, size_t new_size);
248 | int dbuf_write(DynBuf *s, size_t offset, const uint8_t *data, size_t len);
249 | int dbuf_put(DynBuf *s, const uint8_t *data, size_t len);
250 | int dbuf_put_self(DynBuf *s, size_t offset, size_t len);
251 | int dbuf_putc(DynBuf *s, uint8_t c);
252 | int dbuf_putstr(DynBuf *s, const char *str);
253 | static inline int dbuf_put_u16(DynBuf *s, uint16_t val)
254 | {
255 | return dbuf_put(s, (uint8_t *)&val, 2);
256 | }
257 | static inline int dbuf_put_u32(DynBuf *s, uint32_t val)
258 | {
259 | return dbuf_put(s, (uint8_t *)&val, 4);
260 | }
261 | static inline int dbuf_put_u64(DynBuf *s, uint64_t val)
262 | {
263 | return dbuf_put(s, (uint8_t *)&val, 8);
264 | }
265 | int __attribute__((format(printf, 2, 3))) dbuf_printf(DynBuf *s,
266 | const char *fmt, ...);
267 | void dbuf_free(DynBuf *s);
268 | static inline BOOL dbuf_error(DynBuf *s) {
269 | return s->error;
270 | }
271 |
272 | #define UTF8_CHAR_LEN_MAX 6
273 |
274 | int unicode_to_utf8(uint8_t *buf, unsigned int c);
275 | int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp);
276 |
277 | static inline int from_hex(int c)
278 | {
279 | if (c >= '0' && c <= '9')
280 | return c - '0';
281 | else if (c >= 'A' && c <= 'F')
282 | return c - 'A' + 10;
283 | else if (c >= 'a' && c <= 'f')
284 | return c - 'a' + 10;
285 | else
286 | return -1;
287 | }
288 |
289 | void rqsort(void *base, size_t nmemb, size_t size,
290 | int (*cmp)(const void *, const void *, void *),
291 | void *arg);
292 |
293 | #endif /* CUTILS_H */
294 |
--------------------------------------------------------------------------------
/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(bne_char_pos, 5) /* pop one stack element and jump if equal to the character
54 | position */
55 | DEF(prev, 1) /* go to the previous char */
56 | DEF(simple_greedy_quant, 17)
57 |
58 | #endif /* DEF */
59 |
--------------------------------------------------------------------------------
/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 |
40 | #define LRE_FLAG_NAMED_GROUPS (1 << 7) /* named groups are present in the regexp */
41 |
42 | uint8_t *lre_compile(int *plen, char *error_msg, int error_msg_size,
43 | const char *buf, size_t buf_len, int re_flags,
44 | void *opaque);
45 | int lre_get_capture_count(const uint8_t *bc_buf);
46 | int lre_get_flags(const uint8_t *bc_buf);
47 | int lre_exec(uint8_t **capture,
48 | const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen,
49 | int cbuf_type, void *opaque);
50 |
51 | int lre_parse_escape(const uint8_t **pp, int allow_utf16);
52 | LRE_BOOL lre_is_space(int c);
53 |
54 | /* must be provided by the user */
55 | LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size);
56 | void *lre_realloc(void *opaque, void *ptr, size_t size);
57 |
58 | /* JS identifier test */
59 | extern uint32_t const lre_id_start_table_ascii[4];
60 | extern uint32_t const lre_id_continue_table_ascii[4];
61 |
62 | static inline int lre_js_is_ident_first(int c)
63 | {
64 | if ((uint32_t)c < 128) {
65 | return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1;
66 | } else {
67 | #ifdef CONFIG_ALL_UNICODE
68 | return lre_is_id_start(c);
69 | #else
70 | return !lre_is_space(c);
71 | #endif
72 | }
73 | }
74 |
75 | static inline int lre_js_is_ident_next(int c)
76 | {
77 | if ((uint32_t)c < 128) {
78 | return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1;
79 | } else {
80 | /* ZWNJ and ZWJ are accepted in identifiers */
81 | #ifdef CONFIG_ALL_UNICODE
82 | return lre_is_id_continue(c) || c == 0x200C || c == 0x200D;
83 | #else
84 | return !lre_is_space(c) || c == 0x200C || c == 0x200D;
85 | #endif
86 | }
87 | }
88 |
89 | #undef LRE_BOOL
90 |
91 | #endif /* LIBREGEXP_H */
92 |
--------------------------------------------------------------------------------
/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 | LRE_BOOL lre_is_cased(uint32_t c);
45 | LRE_BOOL lre_is_case_ignorable(uint32_t c);
46 |
47 | /* char ranges */
48 |
49 | typedef struct {
50 | int len; /* in points, always even */
51 | int size;
52 | uint32_t *points; /* points sorted by increasing value */
53 | void *mem_opaque;
54 | void *(*realloc_func)(void *opaque, void *ptr, size_t size);
55 | } CharRange;
56 |
57 | typedef enum {
58 | CR_OP_UNION,
59 | CR_OP_INTER,
60 | CR_OP_XOR,
61 | } CharRangeOpEnum;
62 |
63 | void cr_init(CharRange *cr, void *mem_opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size));
64 | void cr_free(CharRange *cr);
65 | int cr_realloc(CharRange *cr, int size);
66 | int cr_copy(CharRange *cr, const CharRange *cr1);
67 |
68 | static inline int cr_add_point(CharRange *cr, uint32_t v)
69 | {
70 | if (cr->len >= cr->size) {
71 | if (cr_realloc(cr, cr->len + 1))
72 | return -1;
73 | }
74 | cr->points[cr->len++] = v;
75 | return 0;
76 | }
77 |
78 | static inline int cr_add_interval(CharRange *cr, uint32_t c1, uint32_t c2)
79 | {
80 | if ((cr->len + 2) > cr->size) {
81 | if (cr_realloc(cr, cr->len + 2))
82 | return -1;
83 | }
84 | cr->points[cr->len++] = c1;
85 | cr->points[cr->len++] = c2;
86 | return 0;
87 | }
88 |
89 | int cr_union1(CharRange *cr, const uint32_t *b_pt, int b_len);
90 |
91 | static inline int cr_union_interval(CharRange *cr, uint32_t c1, uint32_t c2)
92 | {
93 | uint32_t b_pt[2];
94 | b_pt[0] = c1;
95 | b_pt[1] = c2 + 1;
96 | return cr_union1(cr, b_pt, 2);
97 | }
98 |
99 | int cr_op(CharRange *cr, const uint32_t *a_pt, int a_len,
100 | const uint32_t *b_pt, int b_len, int op);
101 |
102 | int cr_invert(CharRange *cr);
103 |
104 | #ifdef CONFIG_ALL_UNICODE
105 |
106 | LRE_BOOL lre_is_id_start(uint32_t c);
107 | LRE_BOOL lre_is_id_continue(uint32_t c);
108 |
109 | int unicode_normalize(uint32_t **pdst, const uint32_t *src, int src_len,
110 | UnicodeNormalizationEnum n_type,
111 | void *opaque, void *(*realloc_func)(void *opaque, void *ptr, size_t size));
112 |
113 | /* Unicode character range functions */
114 |
115 | int unicode_script(CharRange *cr,
116 | const char *script_name, LRE_BOOL is_ext);
117 | int unicode_general_category(CharRange *cr, const char *gc_name);
118 | int unicode_prop(CharRange *cr, const char *prop_name);
119 |
120 | #endif /* CONFIG_ALL_UNICODE */
121 |
122 | #undef LRE_BOOL
123 |
124 | #endif /* LIBUNICODE_H */
125 |
--------------------------------------------------------------------------------
/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) \
40 | ((type *)((uint8_t *)(el) - offsetof(type, member)))
41 |
42 | static inline void init_list_head(struct list_head *head)
43 | {
44 | head->prev = head;
45 | head->next = head;
46 | }
47 |
48 | /* insert 'el' between 'prev' and 'next' */
49 | static inline void __list_add(struct list_head *el,
50 | struct list_head *prev, struct list_head *next)
51 | {
52 | prev->next = el;
53 | el->prev = prev;
54 | el->next = next;
55 | next->prev = el;
56 | }
57 |
58 | /* add 'el' at the head of the list 'head' (= after element head) */
59 | static inline void list_add(struct list_head *el, struct list_head *head)
60 | {
61 | __list_add(el, head, head->next);
62 | }
63 |
64 | /* add 'el' at the end of the list 'head' (= before element head) */
65 | static inline void list_add_tail(struct list_head *el, struct list_head *head)
66 | {
67 | __list_add(el, head->prev, head);
68 | }
69 |
70 | static inline void list_del(struct list_head *el)
71 | {
72 | struct list_head *prev, *next;
73 | prev = el->prev;
74 | next = el->next;
75 | prev->next = next;
76 | next->prev = prev;
77 | el->prev = NULL; /* fail safe */
78 | el->next = NULL; /* fail safe */
79 | }
80 |
81 | static inline int list_empty(struct list_head *el)
82 | {
83 | return el->next == el;
84 | }
85 |
86 | #define list_for_each(el, head) \
87 | for(el = (head)->next; el != (head); el = el->next)
88 |
89 | #define list_for_each_safe(el, el1, head) \
90 | for(el = (head)->next, el1 = el->next; el != (head); \
91 | el = el1, el1 = el->next)
92 |
93 | #define list_for_each_prev(el, head) \
94 | for(el = (head)->prev; el != (head); el = el->prev)
95 |
96 | #define list_for_each_prev_safe(el, el1, head) \
97 | for(el = (head)->prev, el1 = el->prev; el != (head); \
98 | el = el1, el1 = el->prev)
99 |
100 | #endif /* LIST_H */
101 |
--------------------------------------------------------------------------------
/qjs.c:
--------------------------------------------------------------------------------
1 | /*
2 | * QuickJS stand alone interpreter
3 | *
4 | * Copyright (c) 2017-2020 Fabrice Bellard
5 | * Copyright (c) 2017-2020 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 | #include
26 | #include
27 | #include
28 | #include
29 | #include
30 | #include
31 | #include
32 | #include
33 | #include
34 | #include
35 | #if defined(__APPLE__)
36 | #include
37 | #elif defined(__linux__)
38 | #include
39 | #endif
40 |
41 | #include "cutils.h"
42 | #include "quickjs-libc.h"
43 |
44 | extern const uint8_t qjsc_repl[];
45 | extern const uint32_t qjsc_repl_size;
46 | #ifdef CONFIG_BIGNUM
47 | extern const uint8_t qjsc_qjscalc[];
48 | extern const uint32_t qjsc_qjscalc_size;
49 | #endif
50 |
51 | static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
52 | const char *filename, int eval_flags)
53 | {
54 | JSValue val;
55 | int ret;
56 |
57 | if ((eval_flags & JS_EVAL_TYPE_MASK) == JS_EVAL_TYPE_MODULE) {
58 | /* for the modules, we compile then run to be able to set
59 | import.meta */
60 | val = JS_Eval(ctx, buf, buf_len, filename,
61 | eval_flags | JS_EVAL_FLAG_COMPILE_ONLY);
62 | if (!JS_IsException(val)) {
63 | js_module_set_import_meta(ctx, val, TRUE, TRUE);
64 | val = JS_EvalFunction(ctx, val);
65 | }
66 | } else {
67 | val = JS_Eval(ctx, buf, buf_len, filename, eval_flags);
68 | }
69 | if (JS_IsException(val)) {
70 | js_std_dump_error(ctx);
71 | ret = -1;
72 | } else {
73 | ret = 0;
74 | }
75 | JS_FreeValue(ctx, val);
76 | return ret;
77 | }
78 |
79 | static int eval_file(JSContext *ctx, const char *filename, int module)
80 | {
81 | uint8_t *buf;
82 | int ret, eval_flags;
83 | size_t buf_len;
84 |
85 | buf = js_load_file(ctx, &buf_len, filename);
86 | if (!buf) {
87 | perror(filename);
88 | exit(1);
89 | }
90 |
91 | if (module < 0) {
92 | module = (has_suffix(filename, ".mjs") ||
93 | JS_DetectModule((const char *)buf, buf_len));
94 | }
95 | if (module)
96 | eval_flags = JS_EVAL_TYPE_MODULE;
97 | else
98 | eval_flags = JS_EVAL_TYPE_GLOBAL;
99 | ret = eval_buf(ctx, buf, buf_len, filename, eval_flags);
100 | js_free(ctx, buf);
101 | return ret;
102 | }
103 |
104 | #if defined(__APPLE__)
105 | #define MALLOC_OVERHEAD 0
106 | #else
107 | #define MALLOC_OVERHEAD 8
108 | #endif
109 |
110 | struct trace_malloc_data {
111 | uint8_t *base;
112 | };
113 |
114 | static inline unsigned long long js_trace_malloc_ptr_offset(uint8_t *ptr,
115 | struct trace_malloc_data *dp)
116 | {
117 | return ptr - dp->base;
118 | }
119 |
120 | /* default memory allocation functions with memory limitation */
121 | static inline size_t js_trace_malloc_usable_size(void *ptr)
122 | {
123 | #if defined(__APPLE__)
124 | return malloc_size(ptr);
125 | #elif defined(_WIN32)
126 | return _msize(ptr);
127 | #elif defined(__wasi__)
128 | return 0;
129 | #elif defined(__linux__)
130 | return malloc_usable_size(ptr);
131 | #else
132 | /* change this to `return 0;` if compilation fails */
133 | return malloc_usable_size(ptr);
134 | #endif
135 | }
136 |
137 | static void __attribute__((format(printf, 2, 3)))
138 | js_trace_malloc_printf(JSMallocState *s, const char *fmt, ...)
139 | {
140 | va_list ap;
141 | int c;
142 |
143 | va_start(ap, fmt);
144 | while ((c = *fmt++) != '\0') {
145 | if (c == '%') {
146 | /* only handle %p and %zd */
147 | if (*fmt == 'p') {
148 | uint8_t *ptr = va_arg(ap, void *);
149 | if (ptr == NULL) {
150 | printf("NULL");
151 | } else {
152 | printf("H%+06lld.%zd",
153 | js_trace_malloc_ptr_offset(ptr, s->opaque),
154 | js_trace_malloc_usable_size(ptr));
155 | }
156 | fmt++;
157 | continue;
158 | }
159 | if (fmt[0] == 'z' && fmt[1] == 'd') {
160 | size_t sz = va_arg(ap, size_t);
161 | printf("%zd", sz);
162 | fmt += 2;
163 | continue;
164 | }
165 | }
166 | putc(c, stdout);
167 | }
168 | va_end(ap);
169 | }
170 |
171 | static void js_trace_malloc_init(struct trace_malloc_data *s)
172 | {
173 | free(s->base = malloc(8));
174 | }
175 |
176 | static void *js_trace_malloc(JSMallocState *s, size_t size)
177 | {
178 | void *ptr;
179 |
180 | /* Do not allocate zero bytes: behavior is platform dependent */
181 | assert(size != 0);
182 |
183 | if (unlikely(s->malloc_size + size > s->malloc_limit))
184 | return NULL;
185 | ptr = malloc(size);
186 | js_trace_malloc_printf(s, "A %zd -> %p\n", size, ptr);
187 | if (ptr) {
188 | s->malloc_count++;
189 | s->malloc_size += js_trace_malloc_usable_size(ptr) + MALLOC_OVERHEAD;
190 | }
191 | return ptr;
192 | }
193 |
194 | static void js_trace_free(JSMallocState *s, void *ptr)
195 | {
196 | if (!ptr)
197 | return;
198 |
199 | js_trace_malloc_printf(s, "F %p\n", ptr);
200 | s->malloc_count--;
201 | s->malloc_size -= js_trace_malloc_usable_size(ptr) + MALLOC_OVERHEAD;
202 | free(ptr);
203 | }
204 |
205 | static void *js_trace_realloc(JSMallocState *s, void *ptr, size_t size)
206 | {
207 | size_t old_size;
208 |
209 | if (!ptr) {
210 | if (size == 0)
211 | return NULL;
212 | return js_trace_malloc(s, size);
213 | }
214 | old_size = js_trace_malloc_usable_size(ptr);
215 | if (size == 0) {
216 | js_trace_malloc_printf(s, "R %zd %p\n", size, ptr);
217 | s->malloc_count--;
218 | s->malloc_size -= old_size + MALLOC_OVERHEAD;
219 | free(ptr);
220 | return NULL;
221 | }
222 | if (s->malloc_size + size - old_size > s->malloc_limit)
223 | return NULL;
224 |
225 | js_trace_malloc_printf(s, "R %zd %p", size, ptr);
226 |
227 | ptr = realloc(ptr, size);
228 | js_trace_malloc_printf(s, " -> %p\n", ptr);
229 | if (ptr) {
230 | s->malloc_size += js_trace_malloc_usable_size(ptr) - old_size;
231 | }
232 | return ptr;
233 | }
234 |
235 | static const JSMallocFunctions trace_mf = {
236 | js_trace_malloc,
237 | js_trace_free,
238 | js_trace_realloc,
239 | #if defined(__APPLE__)
240 | malloc_size,
241 | #elif defined(_WIN32)
242 | (size_t (*)(const void *))_msize,
243 | #elif defined(__wasi__)
244 | NULL,
245 | #elif defined(__linux__)
246 | (size_t (*)(const void *))malloc_usable_size,
247 | #else
248 | /* change this to `NULL,` if compilation fails */
249 | malloc_usable_size,
250 | #endif
251 | };
252 |
253 | #define PROG_NAME "qjs"
254 |
255 | void help(void)
256 | {
257 | printf("QuickJS version " CONFIG_VERSION "\n"
258 | "usage: " PROG_NAME " [options] [file [args]]\n"
259 | "-h --help list options\n"
260 | "-e --eval EXPR evaluate EXPR\n"
261 | "-i --interactive go to interactive mode\n"
262 | "-m --module load as ES6 module (default=autodetect)\n"
263 | " --script load as ES6 script (default=autodetect)\n"
264 | "-I --include file include an additional file\n"
265 | " --std make 'std' and 'os' available to the loaded script\n"
266 | #ifdef CONFIG_BIGNUM
267 | " --bignum enable the bignum extensions (BigFloat, BigDecimal)\n"
268 | " --qjscalc load the QJSCalc runtime (default if invoked as qjscalc)\n"
269 | #endif
270 | "-T --trace trace memory allocation\n"
271 | "-d --dump dump the memory usage stats\n"
272 | " --memory-limit n limit the memory usage to 'n' bytes\n"
273 | " --unhandled-rejection dump unhandled promise rejections\n"
274 | "-q --quit just instantiate the interpreter and quit\n");
275 | exit(1);
276 | }
277 |
278 | int main(int argc, char **argv)
279 | {
280 | JSRuntime *rt;
281 | JSContext *ctx;
282 | struct trace_malloc_data trace_data = { NULL };
283 | int optind;
284 | char *expr = NULL;
285 | int interactive = 0;
286 | int dump_memory = 0;
287 | int trace_memory = 0;
288 | int empty_run = 0;
289 | int module = -1;
290 | int load_std = 0;
291 | int dump_unhandled_promise_rejection = 0;
292 | size_t memory_limit = 0;
293 | char *include_list[32];
294 | int i, include_count = 0;
295 | #ifdef CONFIG_BIGNUM
296 | int load_jscalc, bignum_ext = 0;
297 | #endif
298 |
299 | #ifdef CONFIG_BIGNUM
300 | /* load jscalc runtime if invoked as 'qjscalc' */
301 | {
302 | const char *p, *exename;
303 | exename = argv[0];
304 | p = strrchr(exename, '/');
305 | if (p)
306 | exename = p + 1;
307 | load_jscalc = !strcmp(exename, "qjscalc");
308 | }
309 | #endif
310 |
311 | /* cannot use getopt because we want to pass the command line to
312 | the script */
313 | optind = 1;
314 | while (optind < argc && *argv[optind] == '-') {
315 | char *arg = argv[optind] + 1;
316 | const char *longopt = "";
317 | /* a single - is not an option, it also stops argument scanning */
318 | if (!*arg)
319 | break;
320 | optind++;
321 | if (*arg == '-') {
322 | longopt = arg + 1;
323 | arg += strlen(arg);
324 | /* -- stops argument scanning */
325 | if (!*longopt)
326 | break;
327 | }
328 | for (; *arg || *longopt; longopt = "") {
329 | char opt = *arg;
330 | if (opt)
331 | arg++;
332 | if (opt == 'h' || opt == '?' || !strcmp(longopt, "help")) {
333 | help();
334 | continue;
335 | }
336 | if (opt == 'e' || !strcmp(longopt, "eval")) {
337 | if (*arg) {
338 | expr = arg;
339 | break;
340 | }
341 | if (optind < argc) {
342 | expr = argv[optind++];
343 | break;
344 | }
345 | fprintf(stderr, "qjs: missing expression for -e\n");
346 | exit(2);
347 | }
348 | if (opt == 'I' || !strcmp(longopt, "include")) {
349 | if (optind >= argc) {
350 | fprintf(stderr, "expecting filename");
351 | exit(1);
352 | }
353 | if (include_count >= countof(include_list)) {
354 | fprintf(stderr, "too many included files");
355 | exit(1);
356 | }
357 | include_list[include_count++] = argv[optind++];
358 | continue;
359 | }
360 | if (opt == 'i' || !strcmp(longopt, "interactive")) {
361 | interactive++;
362 | continue;
363 | }
364 | if (opt == 'm' || !strcmp(longopt, "module")) {
365 | module = 1;
366 | continue;
367 | }
368 | if (!strcmp(longopt, "script")) {
369 | module = 0;
370 | continue;
371 | }
372 | if (opt == 'd' || !strcmp(longopt, "dump")) {
373 | dump_memory++;
374 | continue;
375 | }
376 | if (opt == 'T' || !strcmp(longopt, "trace")) {
377 | trace_memory++;
378 | continue;
379 | }
380 | if (!strcmp(longopt, "std")) {
381 | load_std = 1;
382 | continue;
383 | }
384 | if (!strcmp(longopt, "unhandled-rejection")) {
385 | dump_unhandled_promise_rejection = 1;
386 | continue;
387 | }
388 | #ifdef CONFIG_BIGNUM
389 | if (!strcmp(longopt, "bignum")) {
390 | bignum_ext = 1;
391 | continue;
392 | }
393 | if (!strcmp(longopt, "qjscalc")) {
394 | load_jscalc = 1;
395 | continue;
396 | }
397 | #endif
398 | if (opt == 'q' || !strcmp(longopt, "quit")) {
399 | empty_run++;
400 | continue;
401 | }
402 | if (!strcmp(longopt, "memory-limit")) {
403 | if (optind >= argc) {
404 | fprintf(stderr, "expecting memory limit");
405 | exit(1);
406 | }
407 | memory_limit = (size_t)strtod(argv[optind++], NULL);
408 | continue;
409 | }
410 | if (opt) {
411 | fprintf(stderr, "qjs: unknown option '-%c'\n", opt);
412 | } else {
413 | fprintf(stderr, "qjs: unknown option '--%s'\n", longopt);
414 | }
415 | help();
416 | }
417 | }
418 |
419 | if (trace_memory) {
420 | js_trace_malloc_init(&trace_data);
421 | rt = JS_NewRuntime2(&trace_mf, &trace_data);
422 | } else {
423 | rt = JS_NewRuntime();
424 | }
425 | if (!rt) {
426 | fprintf(stderr, "qjs: cannot allocate JS runtime\n");
427 | exit(2);
428 | }
429 | if (memory_limit != 0)
430 | JS_SetMemoryLimit(rt, memory_limit);
431 | ctx = JS_NewContext(rt);
432 | if (!ctx) {
433 | fprintf(stderr, "qjs: cannot allocate JS context\n");
434 | exit(2);
435 | }
436 |
437 | #ifdef CONFIG_BIGNUM
438 | if (bignum_ext || load_jscalc) {
439 | JS_AddIntrinsicBigFloat(ctx);
440 | JS_AddIntrinsicBigDecimal(ctx);
441 | JS_AddIntrinsicOperators(ctx);
442 | JS_EnableBignumExt(ctx, TRUE);
443 | }
444 | #endif
445 |
446 | /* loader for ES6 modules */
447 | JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
448 |
449 | if (dump_unhandled_promise_rejection) {
450 | JS_SetHostPromiseRejectionTracker(rt, js_std_promise_rejection_tracker,
451 | NULL);
452 | }
453 |
454 | if (!empty_run) {
455 | #ifdef CONFIG_BIGNUM
456 | if (load_jscalc) {
457 | js_std_eval_binary(ctx, qjsc_qjscalc, qjsc_qjscalc_size, 0);
458 | }
459 | #endif
460 | js_std_add_helpers(ctx, argc - optind, argv + optind);
461 |
462 | /* system modules */
463 | js_init_module_std(ctx, "std");
464 | js_init_module_os(ctx, "os");
465 |
466 | /* make 'std' and 'os' visible to non module code */
467 | if (load_std) {
468 | const char *str = "import * as std from 'std';\n"
469 | "import * as os from 'os';\n"
470 | "globalThis.std = std;\n"
471 | "globalThis.os = os;\n";
472 | eval_buf(ctx, str, strlen(str), "", JS_EVAL_TYPE_MODULE);
473 | }
474 |
475 | for(i = 0; i < include_count; i++) {
476 | if (eval_file(ctx, include_list[i], module))
477 | goto fail;
478 | }
479 |
480 | if (expr) {
481 | if (eval_buf(ctx, expr, strlen(expr), "", 0))
482 | goto fail;
483 | } else
484 | if (optind >= argc) {
485 | /* interactive mode */
486 | interactive = 1;
487 | } else {
488 | const char *filename;
489 | filename = argv[optind];
490 | if (eval_file(ctx, filename, module))
491 | goto fail;
492 | }
493 | if (interactive) {
494 | js_std_eval_binary(ctx, qjsc_repl, qjsc_repl_size, 0);
495 | }
496 | js_std_loop(ctx);
497 | }
498 |
499 | if (dump_memory) {
500 | JSMemoryUsage stats;
501 | JS_ComputeMemoryUsage(rt, &stats);
502 | JS_DumpMemoryUsage(stdout, &stats, rt);
503 | }
504 | js_std_free_handlers(rt);
505 | JS_FreeContext(ctx);
506 | JS_FreeRuntime(rt);
507 |
508 | if (empty_run && dump_memory) {
509 | clock_t t[5];
510 | double best[5];
511 | int i, j;
512 | for (i = 0; i < 100; i++) {
513 | t[0] = clock();
514 | rt = JS_NewRuntime();
515 | t[1] = clock();
516 | ctx = JS_NewContext(rt);
517 | t[2] = clock();
518 | JS_FreeContext(ctx);
519 | t[3] = clock();
520 | JS_FreeRuntime(rt);
521 | t[4] = clock();
522 | for (j = 4; j > 0; j--) {
523 | double ms = 1000.0 * (t[j] - t[j - 1]) / CLOCKS_PER_SEC;
524 | if (i == 0 || best[j] > ms)
525 | best[j] = ms;
526 | }
527 | }
528 | printf("\nInstantiation times (ms): %.3f = %.3f+%.3f+%.3f+%.3f\n",
529 | best[1] + best[2] + best[3] + best[4],
530 | best[1], best[2], best[3], best[4]);
531 | }
532 | return 0;
533 | fail:
534 | js_std_free_handlers(rt);
535 | JS_FreeContext(ctx);
536 | JS_FreeRuntime(rt);
537 | return 1;
538 | }
539 |
--------------------------------------------------------------------------------
/qjsc.precompiled:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dip-proto/quickjs-wasi/802bb926008a68812bfb991f536df9c5039fdb01/qjsc.precompiled
--------------------------------------------------------------------------------
/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(stack, "stack")
86 | DEF(name, "name")
87 | DEF(toString, "toString")
88 | DEF(toLocaleString, "toLocaleString")
89 | DEF(valueOf, "valueOf")
90 | DEF(eval, "eval")
91 | DEF(prototype, "prototype")
92 | DEF(constructor, "constructor")
93 | DEF(configurable, "configurable")
94 | DEF(writable, "writable")
95 | DEF(enumerable, "enumerable")
96 | DEF(value, "value")
97 | DEF(get, "get")
98 | DEF(set, "set")
99 | DEF(of, "of")
100 | DEF(__proto__, "__proto__")
101 | DEF(undefined, "undefined")
102 | DEF(number, "number")
103 | DEF(boolean, "boolean")
104 | DEF(string, "string")
105 | DEF(object, "object")
106 | DEF(symbol, "symbol")
107 | DEF(integer, "integer")
108 | DEF(unknown, "unknown")
109 | DEF(arguments, "arguments")
110 | DEF(callee, "callee")
111 | DEF(caller, "caller")
112 | DEF(_eval_, "")
113 | DEF(_ret_, "")
114 | DEF(_var_, "")
115 | DEF(_with_, "")
116 | DEF(lastIndex, "lastIndex")
117 | DEF(target, "target")
118 | DEF(index, "index")
119 | DEF(input, "input")
120 | DEF(defineProperties, "defineProperties")
121 | DEF(apply, "apply")
122 | DEF(join, "join")
123 | DEF(concat, "concat")
124 | DEF(split, "split")
125 | DEF(construct, "construct")
126 | DEF(getPrototypeOf, "getPrototypeOf")
127 | DEF(setPrototypeOf, "setPrototypeOf")
128 | DEF(isExtensible, "isExtensible")
129 | DEF(preventExtensions, "preventExtensions")
130 | DEF(has, "has")
131 | DEF(deleteProperty, "deleteProperty")
132 | DEF(defineProperty, "defineProperty")
133 | DEF(getOwnPropertyDescriptor, "getOwnPropertyDescriptor")
134 | DEF(ownKeys, "ownKeys")
135 | DEF(add, "add")
136 | DEF(done, "done")
137 | DEF(next, "next")
138 | DEF(values, "values")
139 | DEF(source, "source")
140 | DEF(flags, "flags")
141 | DEF(global, "global")
142 | DEF(unicode, "unicode")
143 | DEF(raw, "raw")
144 | DEF(new_target, "new.target")
145 | DEF(this_active_func, "this.active_func")
146 | DEF(home_object, "")
147 | DEF(computed_field, "")
148 | DEF(static_computed_field, "") /* must come after computed_fields */
149 | DEF(class_fields_init, "")
150 | DEF(brand, "")
151 | DEF(hash_constructor, "#constructor")
152 | DEF(as, "as")
153 | DEF(from, "from")
154 | DEF(meta, "meta")
155 | DEF(_default_, "*default*")
156 | DEF(_star_, "*")
157 | DEF(Module, "Module")
158 | DEF(then, "then")
159 | DEF(resolve, "resolve")
160 | DEF(reject, "reject")
161 | DEF(promise, "promise")
162 | DEF(proxy, "proxy")
163 | DEF(revoke, "revoke")
164 | DEF(async, "async")
165 | DEF(exec, "exec")
166 | DEF(groups, "groups")
167 | DEF(status, "status")
168 | DEF(reason, "reason")
169 | DEF(globalThis, "globalThis")
170 | #ifdef CONFIG_BIGNUM
171 | DEF(bigint, "bigint")
172 | DEF(bigfloat, "bigfloat")
173 | DEF(bigdecimal, "bigdecimal")
174 | DEF(roundingMode, "roundingMode")
175 | DEF(maximumSignificantDigits, "maximumSignificantDigits")
176 | DEF(maximumFractionDigits, "maximumFractionDigits")
177 | #endif
178 | #ifdef CONFIG_ATOMICS
179 | DEF(not_equal, "not-equal")
180 | DEF(timed_out, "timed-out")
181 | DEF(ok, "ok")
182 | #endif
183 | DEF(toJSON, "toJSON")
184 | /* class names */
185 | DEF(Object, "Object")
186 | DEF(Array, "Array")
187 | DEF(Error, "Error")
188 | DEF(Number, "Number")
189 | DEF(String, "String")
190 | DEF(Boolean, "Boolean")
191 | DEF(Symbol, "Symbol")
192 | DEF(Arguments, "Arguments")
193 | DEF(Math, "Math")
194 | DEF(JSON, "JSON")
195 | DEF(Date, "Date")
196 | DEF(Function, "Function")
197 | DEF(GeneratorFunction, "GeneratorFunction")
198 | DEF(ForInIterator, "ForInIterator")
199 | DEF(RegExp, "RegExp")
200 | DEF(ArrayBuffer, "ArrayBuffer")
201 | DEF(SharedArrayBuffer, "SharedArrayBuffer")
202 | /* must keep same order as class IDs for typed arrays */
203 | DEF(Uint8ClampedArray, "Uint8ClampedArray")
204 | DEF(Int8Array, "Int8Array")
205 | DEF(Uint8Array, "Uint8Array")
206 | DEF(Int16Array, "Int16Array")
207 | DEF(Uint16Array, "Uint16Array")
208 | DEF(Int32Array, "Int32Array")
209 | DEF(Uint32Array, "Uint32Array")
210 | #ifdef CONFIG_BIGNUM
211 | DEF(BigInt64Array, "BigInt64Array")
212 | DEF(BigUint64Array, "BigUint64Array")
213 | #endif
214 | DEF(Float32Array, "Float32Array")
215 | DEF(Float64Array, "Float64Array")
216 | DEF(DataView, "DataView")
217 | #ifdef CONFIG_BIGNUM
218 | DEF(BigInt, "BigInt")
219 | DEF(BigFloat, "BigFloat")
220 | DEF(BigFloatEnv, "BigFloatEnv")
221 | DEF(BigDecimal, "BigDecimal")
222 | DEF(OperatorSet, "OperatorSet")
223 | DEF(Operators, "Operators")
224 | #endif
225 | DEF(Map, "Map")
226 | DEF(Set, "Set") /* Map + 1 */
227 | DEF(WeakMap, "WeakMap") /* Map + 2 */
228 | DEF(WeakSet, "WeakSet") /* Map + 3 */
229 | DEF(Map_Iterator, "Map Iterator")
230 | DEF(Set_Iterator, "Set Iterator")
231 | DEF(Array_Iterator, "Array Iterator")
232 | DEF(String_Iterator, "String Iterator")
233 | DEF(RegExp_String_Iterator, "RegExp String Iterator")
234 | DEF(Generator, "Generator")
235 | DEF(Proxy, "Proxy")
236 | DEF(Promise, "Promise")
237 | DEF(PromiseResolveFunction, "PromiseResolveFunction")
238 | DEF(PromiseRejectFunction, "PromiseRejectFunction")
239 | DEF(AsyncFunction, "AsyncFunction")
240 | DEF(AsyncFunctionResolve, "AsyncFunctionResolve")
241 | DEF(AsyncFunctionReject, "AsyncFunctionReject")
242 | DEF(AsyncGeneratorFunction, "AsyncGeneratorFunction")
243 | DEF(AsyncGenerator, "AsyncGenerator")
244 | DEF(EvalError, "EvalError")
245 | DEF(RangeError, "RangeError")
246 | DEF(ReferenceError, "ReferenceError")
247 | DEF(SyntaxError, "SyntaxError")
248 | DEF(TypeError, "TypeError")
249 | DEF(URIError, "URIError")
250 | DEF(InternalError, "InternalError")
251 | /* private symbols */
252 | DEF(Private_brand, "")
253 | /* symbols */
254 | DEF(Symbol_toPrimitive, "Symbol.toPrimitive")
255 | DEF(Symbol_iterator, "Symbol.iterator")
256 | DEF(Symbol_match, "Symbol.match")
257 | DEF(Symbol_matchAll, "Symbol.matchAll")
258 | DEF(Symbol_replace, "Symbol.replace")
259 | DEF(Symbol_search, "Symbol.search")
260 | DEF(Symbol_split, "Symbol.split")
261 | DEF(Symbol_toStringTag, "Symbol.toStringTag")
262 | DEF(Symbol_isConcatSpreadable, "Symbol.isConcatSpreadable")
263 | DEF(Symbol_hasInstance, "Symbol.hasInstance")
264 | DEF(Symbol_species, "Symbol.species")
265 | DEF(Symbol_unscopables, "Symbol.unscopables")
266 | DEF(Symbol_asyncIterator, "Symbol.asyncIterator")
267 | #ifdef CONFIG_BIGNUM
268 | DEF(Symbol_operatorSet, "Symbol.operatorSet")
269 | #endif
270 |
271 | #endif /* DEF */
272 |
--------------------------------------------------------------------------------
/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 | JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name);
33 | JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name);
34 | void js_std_add_helpers(JSContext *ctx, int argc, char **argv);
35 | void js_std_loop(JSContext *ctx);
36 | void js_std_free_handlers(JSRuntime *rt);
37 | void js_std_dump_error(JSContext *ctx);
38 | uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename);
39 | int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val,
40 | JS_BOOL use_realpath, JS_BOOL is_main);
41 | JSModuleDef *js_module_loader(JSContext *ctx,
42 | const char *module_name, void *opaque);
43 | void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
44 | int flags);
45 | void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
46 | JSValueConst reason,
47 | JS_BOOL is_handled, void *opaque);
48 |
49 | #endif /* QUICKJS_LIBC_H */
50 |
--------------------------------------------------------------------------------
/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_var, 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_ctor, 1, 1, 1, none)
123 | DEF( get_super, 1, 1, 1, none)
124 | DEF( import, 1, 1, 1, none) /* dynamic module import */
125 |
126 | DEF( check_var, 5, 0, 1, atom) /* check if a variable exists */
127 | DEF( get_var_undef, 5, 0, 1, atom) /* push undefined if the variable does not exist */
128 | DEF( get_var, 5, 0, 1, atom) /* throw an exception if the variable does not exist */
129 | DEF( put_var, 5, 1, 0, atom) /* must come after get_var */
130 | DEF( put_var_init, 5, 1, 0, atom) /* must come after put_var. Used to initialize a global lexical variable */
131 | DEF( put_var_strict, 5, 2, 0, atom) /* for strict mode variable write */
132 |
133 | DEF( get_ref_value, 1, 2, 3, none)
134 | DEF( put_ref_value, 1, 3, 0, none)
135 |
136 | DEF( define_var, 6, 0, 0, atom_u8)
137 | DEF(check_define_var, 6, 0, 0, atom_u8)
138 | DEF( define_func, 6, 1, 0, atom_u8)
139 | DEF( get_field, 5, 1, 1, atom)
140 | DEF( get_field2, 5, 1, 2, atom)
141 | DEF( put_field, 5, 2, 0, atom)
142 | DEF( get_private_field, 1, 2, 1, none) /* obj prop -> value */
143 | DEF( put_private_field, 1, 3, 0, none) /* obj value prop -> */
144 | DEF(define_private_field, 1, 3, 1, none) /* obj prop value -> obj */
145 | DEF( get_array_el, 1, 2, 1, none)
146 | DEF( get_array_el2, 1, 2, 2, none) /* obj prop -> obj value */
147 | DEF( put_array_el, 1, 3, 0, none)
148 | DEF(get_super_value, 1, 3, 1, none) /* this obj prop -> value */
149 | DEF(put_super_value, 1, 4, 0, none) /* this obj prop value -> */
150 | DEF( define_field, 5, 2, 1, atom)
151 | DEF( set_name, 5, 1, 1, atom)
152 | DEF(set_name_computed, 1, 2, 2, none)
153 | DEF( set_proto, 1, 2, 1, none)
154 | DEF(set_home_object, 1, 2, 2, none)
155 | DEF(define_array_el, 1, 3, 2, none)
156 | DEF( append, 1, 3, 2, none) /* append enumerated object, update length */
157 | DEF(copy_data_properties, 2, 3, 3, u8)
158 | DEF( define_method, 6, 2, 1, atom_u8)
159 | DEF(define_method_computed, 2, 3, 1, u8) /* must come after define_method */
160 | DEF( define_class, 6, 2, 2, atom_u8) /* parent ctor -> ctor proto */
161 | DEF( define_class_computed, 6, 3, 3, atom_u8) /* field_name parent ctor -> field_name ctor proto (class with computed name) */
162 |
163 | DEF( get_loc, 3, 0, 1, loc)
164 | DEF( put_loc, 3, 1, 0, loc) /* must come after get_loc */
165 | DEF( set_loc, 3, 1, 1, loc) /* must come after put_loc */
166 | DEF( get_arg, 3, 0, 1, arg)
167 | DEF( put_arg, 3, 1, 0, arg) /* must come after get_arg */
168 | DEF( set_arg, 3, 1, 1, arg) /* must come after put_arg */
169 | DEF( get_var_ref, 3, 0, 1, var_ref)
170 | DEF( put_var_ref, 3, 1, 0, var_ref) /* must come after get_var_ref */
171 | DEF( set_var_ref, 3, 1, 1, var_ref) /* must come after put_var_ref */
172 | DEF(set_loc_uninitialized, 3, 0, 0, loc)
173 | DEF( get_loc_check, 3, 0, 1, loc)
174 | DEF( put_loc_check, 3, 1, 0, loc) /* must come after get_loc_check */
175 | DEF( put_loc_check_init, 3, 1, 0, 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 |
187 | DEF( to_object, 1, 1, 1, none)
188 | //DEF( to_string, 1, 1, 1, none)
189 | DEF( to_propkey, 1, 1, 1, none)
190 | DEF( to_propkey2, 1, 2, 2, none)
191 |
192 | DEF( with_get_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */
193 | DEF( with_put_var, 10, 2, 1, atom_label_u8) /* must be in the same order as scope_xxx */
194 | DEF(with_delete_var, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */
195 | DEF( with_make_ref, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */
196 | DEF( with_get_ref, 10, 1, 0, atom_label_u8) /* must be in the same order as scope_xxx */
197 | DEF(with_get_ref_undef, 10, 1, 0, atom_label_u8)
198 |
199 | DEF( make_loc_ref, 7, 0, 2, atom_u16)
200 | DEF( make_arg_ref, 7, 0, 2, atom_u16)
201 | DEF(make_var_ref_ref, 7, 0, 2, atom_u16)
202 | DEF( make_var_ref, 5, 0, 2, atom)
203 |
204 | DEF( for_in_start, 1, 1, 1, none)
205 | DEF( for_of_start, 1, 1, 3, none)
206 | DEF(for_await_of_start, 1, 1, 3, none)
207 | DEF( for_in_next, 1, 1, 3, none)
208 | DEF( for_of_next, 2, 3, 5, u8)
209 | DEF(for_await_of_next, 1, 3, 4, none)
210 | DEF(iterator_get_value_done, 1, 1, 2, none)
211 | DEF( iterator_close, 1, 3, 0, none)
212 | DEF(iterator_close_return, 1, 4, 4, none)
213 | DEF(async_iterator_close, 1, 3, 2, none)
214 | DEF(async_iterator_next, 1, 4, 4, none)
215 | DEF(async_iterator_get, 2, 4, 5, u8)
216 | DEF( initial_yield, 1, 0, 0, none)
217 | DEF( yield, 1, 1, 2, none)
218 | DEF( yield_star, 1, 2, 2, none)
219 | DEF(async_yield_star, 1, 1, 2, none)
220 | DEF( await, 1, 1, 1, none)
221 |
222 | /* arithmetic/logic operations */
223 | DEF( neg, 1, 1, 1, none)
224 | DEF( plus, 1, 1, 1, none)
225 | DEF( dec, 1, 1, 1, none)
226 | DEF( inc, 1, 1, 1, none)
227 | DEF( post_dec, 1, 1, 2, none)
228 | DEF( post_inc, 1, 1, 2, none)
229 | DEF( dec_loc, 2, 0, 0, loc8)
230 | DEF( inc_loc, 2, 0, 0, loc8)
231 | DEF( add_loc, 2, 1, 0, loc8)
232 | DEF( not, 1, 1, 1, none)
233 | DEF( lnot, 1, 1, 1, none)
234 | DEF( typeof, 1, 1, 1, none)
235 | DEF( delete, 1, 2, 1, none)
236 | DEF( delete_var, 5, 0, 1, atom)
237 |
238 | DEF( mul, 1, 2, 1, none)
239 | DEF( div, 1, 2, 1, none)
240 | DEF( mod, 1, 2, 1, none)
241 | DEF( add, 1, 2, 1, none)
242 | DEF( sub, 1, 2, 1, none)
243 | DEF( pow, 1, 2, 1, none)
244 | DEF( shl, 1, 2, 1, none)
245 | DEF( sar, 1, 2, 1, none)
246 | DEF( shr, 1, 2, 1, none)
247 | DEF( lt, 1, 2, 1, none)
248 | DEF( lte, 1, 2, 1, none)
249 | DEF( gt, 1, 2, 1, none)
250 | DEF( gte, 1, 2, 1, none)
251 | DEF( instanceof, 1, 2, 1, none)
252 | DEF( in, 1, 2, 1, none)
253 | DEF( eq, 1, 2, 1, none)
254 | DEF( neq, 1, 2, 1, none)
255 | DEF( strict_eq, 1, 2, 1, none)
256 | DEF( strict_neq, 1, 2, 1, none)
257 | DEF( and, 1, 2, 1, none)
258 | DEF( xor, 1, 2, 1, none)
259 | DEF( or, 1, 2, 1, none)
260 | DEF(is_undefined_or_null, 1, 1, 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(set_arg_valid_upto, 3, 0, 0, arg) /* emitted in phase 1, removed in phase 2 */
271 |
272 | def( enter_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */
273 | def( leave_scope, 3, 0, 0, u16) /* emitted in phase 1, removed in phase 2 */
274 |
275 | def( label, 5, 0, 0, label) /* emitted in phase 1, removed in phase 3 */
276 |
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_private_field, 7, 1, 1, atom_u16) /* obj -> value, emitted in phase 1, removed in phase 2 */
285 | def(scope_get_private_field2, 7, 1, 2, atom_u16) /* obj -> obj value, emitted in phase 1, removed in phase 2 */
286 | def(scope_put_private_field, 7, 1, 1, atom_u16) /* obj value ->, emitted in phase 1, removed in phase 2 */
287 |
288 | def( set_class_name, 5, 1, 1, u32) /* emitted in phase 1, removed in phase 2 */
289 |
290 | def( line_num, 5, 0, 0, u32) /* emitted in phase 1, removed in phase 3 */
291 |
292 | #if SHORT_OPCODES
293 | DEF( push_minus1, 1, 0, 1, none_int)
294 | DEF( push_0, 1, 0, 1, none_int)
295 | DEF( push_1, 1, 0, 1, none_int)
296 | DEF( push_2, 1, 0, 1, none_int)
297 | DEF( push_3, 1, 0, 1, none_int)
298 | DEF( push_4, 1, 0, 1, none_int)
299 | DEF( push_5, 1, 0, 1, none_int)
300 | DEF( push_6, 1, 0, 1, none_int)
301 | DEF( push_7, 1, 0, 1, none_int)
302 | DEF( push_i8, 2, 0, 1, i8)
303 | DEF( push_i16, 3, 0, 1, i16)
304 | DEF( push_const8, 2, 0, 1, const8)
305 | DEF( fclosure8, 2, 0, 1, const8) /* must follow push_const8 */
306 | DEF(push_empty_string, 1, 0, 1, none)
307 |
308 | DEF( get_loc8, 2, 0, 1, loc8)
309 | DEF( put_loc8, 2, 1, 0, loc8)
310 | DEF( set_loc8, 2, 1, 1, loc8)
311 |
312 | DEF( get_loc0, 1, 0, 1, none_loc)
313 | DEF( get_loc1, 1, 0, 1, none_loc)
314 | DEF( get_loc2, 1, 0, 1, none_loc)
315 | DEF( get_loc3, 1, 0, 1, none_loc)
316 | DEF( put_loc0, 1, 1, 0, none_loc)
317 | DEF( put_loc1, 1, 1, 0, none_loc)
318 | DEF( put_loc2, 1, 1, 0, none_loc)
319 | DEF( put_loc3, 1, 1, 0, none_loc)
320 | DEF( set_loc0, 1, 1, 1, none_loc)
321 | DEF( set_loc1, 1, 1, 1, none_loc)
322 | DEF( set_loc2, 1, 1, 1, none_loc)
323 | DEF( set_loc3, 1, 1, 1, none_loc)
324 | DEF( get_arg0, 1, 0, 1, none_arg)
325 | DEF( get_arg1, 1, 0, 1, none_arg)
326 | DEF( get_arg2, 1, 0, 1, none_arg)
327 | DEF( get_arg3, 1, 0, 1, none_arg)
328 | DEF( put_arg0, 1, 1, 0, none_arg)
329 | DEF( put_arg1, 1, 1, 0, none_arg)
330 | DEF( put_arg2, 1, 1, 0, none_arg)
331 | DEF( put_arg3, 1, 1, 0, none_arg)
332 | DEF( set_arg0, 1, 1, 1, none_arg)
333 | DEF( set_arg1, 1, 1, 1, none_arg)
334 | DEF( set_arg2, 1, 1, 1, none_arg)
335 | DEF( set_arg3, 1, 1, 1, none_arg)
336 | DEF( get_var_ref0, 1, 0, 1, none_var_ref)
337 | DEF( get_var_ref1, 1, 0, 1, none_var_ref)
338 | DEF( get_var_ref2, 1, 0, 1, none_var_ref)
339 | DEF( get_var_ref3, 1, 0, 1, none_var_ref)
340 | DEF( put_var_ref0, 1, 1, 0, none_var_ref)
341 | DEF( put_var_ref1, 1, 1, 0, none_var_ref)
342 | DEF( put_var_ref2, 1, 1, 0, none_var_ref)
343 | DEF( put_var_ref3, 1, 1, 0, none_var_ref)
344 | DEF( set_var_ref0, 1, 1, 1, none_var_ref)
345 | DEF( set_var_ref1, 1, 1, 1, none_var_ref)
346 | DEF( set_var_ref2, 1, 1, 1, none_var_ref)
347 | DEF( set_var_ref3, 1, 1, 1, none_var_ref)
348 |
349 | DEF( get_length, 1, 1, 1, none)
350 |
351 | DEF( if_false8, 2, 1, 0, label8)
352 | DEF( if_true8, 2, 1, 0, label8) /* must come after if_false8 */
353 | DEF( goto8, 2, 0, 0, label8) /* must come after if_true8 */
354 | DEF( goto16, 3, 0, 0, label16)
355 |
356 | DEF( call0, 1, 1, 1, npopx)
357 | DEF( call1, 1, 1, 1, npopx)
358 | DEF( call2, 1, 1, 1, npopx)
359 | DEF( call3, 1, 1, 1, npopx)
360 |
361 | DEF( is_undefined, 1, 1, 1, none)
362 | DEF( is_null, 1, 1, 1, none)
363 | DEF( is_function, 1, 1, 1, none)
364 | #endif
365 |
366 | #undef DEF
367 | #undef def
368 | #endif /* DEF */
369 |
--------------------------------------------------------------------------------
/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 [all]"
10 | echo ""
11 | echo "all: build all the archives. Otherwise only build the quickjs source archive."
12 | exit 1
13 | fi
14 |
15 | extras="no"
16 | binary="no"
17 | quickjs="no"
18 |
19 | if [ "$1" = "all" ] ; then
20 | extras="yes"
21 | binary="yes"
22 | quickjs="yes"
23 | elif [ "$1" = "binary" ] ; then
24 | binary="yes"
25 | else
26 | quickjs="yes"
27 | fi
28 |
29 | #################################################"
30 | # extras
31 |
32 | if [ "$extras" = "yes" ] ; then
33 |
34 | d="quickjs-${version}"
35 | name="quickjs-extras-${version}"
36 | outdir="/tmp/${d}"
37 |
38 | rm -rf $outdir
39 | mkdir -p $outdir $outdir/unicode $outdir/tests
40 |
41 | cp unicode/* $outdir/unicode
42 | cp -a tests/bench-v8 $outdir/tests
43 |
44 | ( cd /tmp && tar Jcvf /tmp/${name}.tar.xz ${d} )
45 |
46 | fi
47 |
48 | #################################################"
49 | # binary release
50 |
51 | if [ "$binary" = "yes" ] ; then
52 |
53 | d="quickjs-linux-x86_64-${version}"
54 | name="quickjs-linux-x86_64-${version}"
55 | outdir="/tmp/${d}"
56 |
57 | rm -rf $outdir
58 | mkdir -p $outdir
59 |
60 | files="qjs run-test262"
61 |
62 | make -j4 $files
63 |
64 | strip $files
65 | cp $files $outdir
66 |
67 | ( cd /tmp/$d && rm -f ../${name}.zip && zip -r ../${name}.zip . )
68 |
69 | fi
70 |
71 | #################################################"
72 | # quickjs
73 |
74 | if [ "$quickjs" = "yes" ] ; then
75 |
76 | make build_doc
77 |
78 | d="quickjs-${version}"
79 | outdir="/tmp/${d}"
80 |
81 | rm -rf $outdir
82 | mkdir -p $outdir $outdir/doc $outdir/tests $outdir/examples
83 |
84 | cp Makefile VERSION TODO Changelog readme.txt release.sh unicode_download.sh \
85 | qjs.c qjsc.c qjscalc.js repl.js \
86 | quickjs.c quickjs.h quickjs-atom.h \
87 | quickjs-libc.c quickjs-libc.h quickjs-opcode.h \
88 | cutils.c cutils.h list.h \
89 | libregexp.c libregexp.h libregexp-opcode.h \
90 | libunicode.c libunicode.h libunicode-table.h \
91 | libbf.c libbf.h \
92 | jscompress.c unicode_gen.c unicode_gen_def.h \
93 | run-test262.c test262o.conf test262.conf \
94 | test262o_errors.txt test262_errors.txt \
95 | $outdir
96 |
97 | cp tests/*.js tests/*.patch tests/bjson.c $outdir/tests
98 |
99 | cp examples/*.js examples/*.c $outdir/examples
100 |
101 | cp doc/quickjs.texi doc/quickjs.pdf doc/quickjs.html \
102 | doc/jsbignum.texi doc/jsbignum.html doc/jsbignum.pdf \
103 | $outdir/doc
104 |
105 | ( cd /tmp && tar Jcvf /tmp/${d}.tar.xz ${d} )
106 |
107 | fi
108 |
--------------------------------------------------------------------------------
/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 |
51 | AggregateError=skip
52 | Array.prototype.flat
53 | Array.prototype.flatMap
54 | Array.prototype.flatten
55 | Array.prototype.values
56 | ArrayBuffer
57 | arrow-function
58 | async-functions
59 | async-iteration
60 | Atomics
61 | BigInt
62 | caller
63 | class
64 | class-fields-private
65 | class-fields-public
66 | class-methods-private
67 | class-static-fields-public
68 | class-static-fields-private
69 | class-static-methods-private
70 | coalesce-expression
71 | computed-property-names
72 | const
73 | cross-realm=skip
74 | DataView
75 | DataView.prototype.getFloat32
76 | DataView.prototype.getFloat64
77 | DataView.prototype.getInt16
78 | DataView.prototype.getInt32
79 | DataView.prototype.getInt8
80 | DataView.prototype.getUint16
81 | DataView.prototype.getUint32
82 | DataView.prototype.setUint8
83 | default-arg
84 | default-parameters
85 | destructuring-assignment
86 | destructuring-binding
87 | dynamic-import
88 | export-star-as-namespace-from-module
89 | FinalizationGroup=skip
90 | Float32Array
91 | Float64Array
92 | for-in-order
93 | for-of
94 | generators
95 | globalThis
96 | hashbang
97 | host-gc-required=skip
98 | import.meta
99 | Int32Array
100 | Int8Array
101 | IsHTMLDDA=skip
102 | json-superset
103 | let
104 | Map
105 | new.target
106 | numeric-separator-literal
107 | object-rest
108 | object-spread
109 | Object.fromEntries
110 | Object.is
111 | optional-catch-binding
112 | optional-chaining
113 | Promise.allSettled
114 | Promise.prototype.finally
115 | Proxy
116 | proxy-missing-checks
117 | Reflect
118 | Reflect.construct
119 | Reflect.set
120 | Reflect.setPrototypeOf
121 | regexp-dotall
122 | regexp-lookbehind
123 | regexp-match-indices=skip
124 | regexp-named-groups
125 | regexp-unicode-property-escapes
126 | rest-parameters
127 | Set
128 | SharedArrayBuffer
129 | string-trimming
130 | String.fromCodePoint
131 | String.prototype.endsWith
132 | String.prototype.includes
133 | String.prototype.matchAll
134 | String.prototype.replaceAll
135 | String.prototype.trimEnd
136 | String.prototype.trimStart
137 | super
138 | Symbol
139 | Symbol.asyncIterator
140 | Symbol.hasInstance
141 | Symbol.isConcatSpreadable
142 | Symbol.iterator
143 | Symbol.match
144 | Symbol.matchAll
145 | Symbol.prototype.description
146 | Symbol.replace
147 | Symbol.search
148 | Symbol.species
149 | Symbol.split
150 | Symbol.toPrimitive
151 | Symbol.toStringTag
152 | Symbol.unscopables
153 | tail-call-optimization=skip
154 | template
155 | top-level-await=skip
156 | TypedArray
157 | u180e
158 | Uint16Array
159 | Uint8Array
160 | Uint8ClampedArray
161 | WeakMap
162 | WeakRef=skip
163 | WeakSet
164 | well-formed-json-stringify
165 |
166 | [exclude]
167 | # list excluded tests and directories here
168 |
169 | # intl not supported
170 | test262/test/intl402/
171 |
172 | # incompatible with the "caller" feature
173 | test262/test/built-ins/Function/prototype/restricted-property-caller.js
174 | test262/test/built-ins/Function/prototype/restricted-property-arguments.js
175 | test262/test/built-ins/ThrowTypeError/unique-per-realm-function-proto.js
176 |
177 | # slow tests
178 | #test262/test/built-ins/RegExp/CharacterClassEscapes/
179 | #test262/test/built-ins/RegExp/property-escapes/
180 |
181 | [tests]
182 | # list test files or use config.testdir
183 |
--------------------------------------------------------------------------------
/test262_errors.txt:
--------------------------------------------------------------------------------
1 | test262/test/language/expressions/arrow-function/eval-var-scope-syntax-err.js:47: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
2 | test262/test/language/expressions/async-generator/eval-var-scope-syntax-err.js:28: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
3 | test262/test/language/expressions/async-generator/named-eval-var-scope-syntax-err.js:28: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
4 | test262/test/language/expressions/class/super-evaluation-order.js:26: Test262Error: via ArgumentListEvaluation Expected SameValue(«0», «123») to be true
5 | test262/test/language/expressions/class/super-evaluation-order.js:26: strict mode: Test262Error: via ArgumentListEvaluation Expected SameValue(«0», «123») to be true
6 | test262/test/language/expressions/dynamic-import/usage-from-eval.js:26: TypeError: $DONE() not called
7 | test262/test/language/expressions/dynamic-import/usage-from-eval.js:26: strict mode: TypeError: $DONE() not called
8 | test262/test/language/expressions/function/eval-var-scope-syntax-err.js:48: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
9 | test262/test/language/expressions/generators/eval-var-scope-syntax-err.js:49: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
10 | test262/test/language/expressions/object/method-definition/async-gen-meth-eval-var-scope-syntax-err.js:32: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
11 | test262/test/language/expressions/object/method-definition/gen-meth-eval-var-scope-syntax-err.js:54: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
12 | test262/test/language/expressions/object/method-definition/meth-eval-var-scope-syntax-err.js:50: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
13 | test262/test/language/expressions/optional-chaining/optional-call-preserves-this.js:21: TypeError: value has no property
14 | test262/test/language/expressions/optional-chaining/optional-call-preserves-this.js:15: strict mode: TypeError: value has no property
15 | test262/test/language/statements/async-generator/eval-var-scope-syntax-err.js:28: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
16 | test262/test/language/statements/function/eval-var-scope-syntax-err.js:49: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
17 | test262/test/language/statements/generators/eval-var-scope-syntax-err.js:49: Test262Error: Expected a SyntaxError to be thrown but no exception was thrown at all
18 |
--------------------------------------------------------------------------------
/test262o_errors.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dip-proto/quickjs-wasi/802bb926008a68812bfb991f536df9c5039fdb01/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 |
35 | if (JS_ToIndex(ctx, &pos, argv[1]))
36 | return JS_EXCEPTION;
37 | if (JS_ToIndex(ctx, &len, argv[2]))
38 | return JS_EXCEPTION;
39 | buf = JS_GetArrayBuffer(ctx, &size, argv[0]);
40 | if (!buf)
41 | return JS_EXCEPTION;
42 | if (pos + len > size)
43 | return JS_ThrowRangeError(ctx, "array buffer overflow");
44 | obj = JS_ReadObject(ctx, buf + pos, len, 0);
45 | return obj;
46 | }
47 |
48 | static JSValue js_bjson_write(JSContext *ctx, JSValueConst this_val,
49 | int argc, JSValueConst *argv)
50 | {
51 | size_t len;
52 | uint8_t *buf;
53 | JSValue array;
54 |
55 | buf = JS_WriteObject(ctx, &len, argv[0], 0);
56 | if (!buf)
57 | return JS_EXCEPTION;
58 | array = JS_NewArrayBufferCopy(ctx, buf, len);
59 | js_free(ctx, buf);
60 | return array;
61 | }
62 |
63 | static const JSCFunctionListEntry js_bjson_funcs[] = {
64 | JS_CFUNC_DEF("read", 3, js_bjson_read ),
65 | JS_CFUNC_DEF("write", 1, js_bjson_write ),
66 | };
67 |
68 | static int js_bjson_init(JSContext *ctx, JSModuleDef *m)
69 | {
70 | return JS_SetModuleExportList(ctx, m, js_bjson_funcs,
71 | countof(js_bjson_funcs));
72 | }
73 |
74 | #ifdef JS_SHARED_LIBRARY
75 | #define JS_INIT_MODULE js_init_module
76 | #else
77 | #define JS_INIT_MODULE js_init_module_bjson
78 | #endif
79 |
80 | JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name)
81 | {
82 | JSModuleDef *m;
83 | m = JS_NewCModule(ctx, module_name, js_bjson_init);
84 | if (!m)
85 | return NULL;
86 | JS_AddModuleExportList(ctx, m, js_bjson_funcs, countof(js_bjson_funcs));
87 | return m;
88 | }
89 |
--------------------------------------------------------------------------------
/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(b, str)
4 | {
5 | if (b) {
6 | return;
7 | } else {
8 | throw Error("assertion failed: " + str);
9 | }
10 | }
11 |
12 | function toHex(a)
13 | {
14 | var i, s = "", tab, v;
15 | tab = new Uint8Array(a);
16 | for(i = 0; i < tab.length; i++) {
17 | v = tab[i].toString(16);
18 | if (v.length < 2)
19 | v = "0" + v;
20 | if (i !== 0)
21 | s += " ";
22 | s += v;
23 | }
24 | return s;
25 | }
26 |
27 | function toStr(a)
28 | {
29 | var s, i, props, prop;
30 |
31 | switch(typeof(a)) {
32 | case "object":
33 | if (a === null)
34 | return "null";
35 | if (Array.isArray(a)) {
36 | s = "[";
37 | for(i = 0; i < a.length; i++) {
38 | if (i != 0)
39 | s += ",";
40 | s += toStr(a[i]);
41 | }
42 | s += "]";
43 | } else {
44 | props = Object.keys(a);
45 | s = "{";
46 | for(i = 0; i < props.length; i++) {
47 | if (i != 0)
48 | s += ",";
49 | prop = props[i];
50 | s += prop + ":" + toStr(a[prop]);
51 | }
52 | s += "}";
53 | }
54 | return s;
55 | case "undefined":
56 | return "undefined";
57 | case "string":
58 | return a.__quote();
59 | case "number":
60 | case "bigfloat":
61 | if (a == 0 && 1 / a < 0)
62 | return "-0";
63 | else
64 | return a.toString();
65 | break;
66 | default:
67 | return a.toString();
68 | }
69 | }
70 |
71 | function bjson_test(a)
72 | {
73 | var buf, r, a_str, r_str;
74 | a_str = toStr(a);
75 | buf = bjson.write(a);
76 | if (0) {
77 | print(a_str, "->", toHex(buf));
78 | }
79 | r = bjson.read(buf, 0, buf.byteLength);
80 | r_str = toStr(r);
81 | if (a_str != r_str) {
82 | print(a_str);
83 | print(r_str);
84 | assert(false);
85 | }
86 | }
87 |
88 | function bjson_test_all()
89 | {
90 | var obj;
91 |
92 | bjson_test({x:1, y:2, if:3});
93 | bjson_test([1, 2, 3]);
94 | bjson_test([1.0, "aa", true, false, undefined, null, NaN, -Infinity, -0.0]);
95 | if (typeof BigInt !== "undefined") {
96 | bjson_test([BigInt("1"), -BigInt("0x123456789"),
97 | BigInt("0x123456789abcdef123456789abcdef")]);
98 | }
99 | if (typeof BigFloat !== "undefined") {
100 | BigFloatEnv.setPrec(function () {
101 | bjson_test([BigFloat("0.1"), BigFloat("-1e30"), BigFloat("0"),
102 | BigFloat("-0"), BigFloat("Infinity"), BigFloat("-Infinity"),
103 | 0.0 / BigFloat("0"), BigFloat.MAX_VALUE,
104 | BigFloat.MIN_VALUE]);
105 | }, 113, 15);
106 | }
107 | if (typeof BigDecimal !== "undefined") {
108 | bjson_test([BigDecimal("0"),
109 | BigDecimal("0.8"), BigDecimal("123321312321321e100"),
110 | BigDecimal("-1233213123213214332333223332e100"),
111 | BigDecimal("1.233e-1000")]);
112 | }
113 |
114 | /* tested with a circular reference */
115 | obj = {};
116 | obj.x = obj;
117 | try {
118 | bjson.write(obj);
119 | assert(false);
120 | } catch(e) {
121 | assert(e instanceof TypeError);
122 | }
123 | }
124 |
125 | bjson_test_all();
126 |
--------------------------------------------------------------------------------
/tests/test_builtin.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 | // load more elaborate version of assert if available
21 | try { __loadScript("test_assert.js"); } catch(e) {}
22 |
23 | /*----------------*/
24 |
25 | function my_func(a, b)
26 | {
27 | return a + b;
28 | }
29 |
30 | function test_function()
31 | {
32 | function f(a, b) {
33 | var i, tab = [];
34 | tab.push(this);
35 | for(i = 0; i < arguments.length; i++)
36 | tab.push(arguments[i]);
37 | return tab;
38 | }
39 | function constructor1(a) {
40 | this.x = a;
41 | }
42 |
43 | var r, g;
44 |
45 | r = my_func.call(null, 1, 2);
46 | assert(r, 3, "call");
47 |
48 | r = my_func.apply(null, [1, 2]);
49 | assert(r, 3, "apply");
50 |
51 | r = new Function("a", "b", "return a + b;");
52 | assert(r(2,3), 5, "function");
53 |
54 | g = f.bind(1, 2);
55 | assert(g.length, 1);
56 | assert(g.name, "bound f");
57 | assert(g(3), [1,2,3]);
58 |
59 | g = constructor1.bind(null, 1);
60 | r = new g();
61 | assert(r.x, 1);
62 | }
63 |
64 | function test()
65 | {
66 | var r, a, b, c, err;
67 |
68 | r = Error("hello");
69 | assert(r.message, "hello", "Error");
70 |
71 | a = new Object();
72 | a.x = 1;
73 | assert(a.x, 1, "Object");
74 |
75 | assert(Object.getPrototypeOf(a), Object.prototype, "getPrototypeOf");
76 | Object.defineProperty(a, "y", { value: 3, writable: true, configurable: true, enumerable: true });
77 | assert(a.y, 3, "defineProperty");
78 |
79 | Object.defineProperty(a, "z", { get: function () { return 4; }, set: function(val) { this.z_val = val; }, configurable: true, enumerable: true });
80 | assert(a.z, 4, "get");
81 | a.z = 5;
82 | assert(a.z_val, 5, "set");
83 |
84 | a = { get z() { return 4; }, set z(val) { this.z_val = val; } };
85 | assert(a.z, 4, "get");
86 | a.z = 5;
87 | assert(a.z_val, 5, "set");
88 |
89 | b = Object.create(a);
90 | assert(Object.getPrototypeOf(b), a, "create");
91 | c = {u:2};
92 | /* XXX: refcount bug in 'b' instead of 'a' */
93 | Object.setPrototypeOf(a, c);
94 | assert(Object.getPrototypeOf(a), c, "setPrototypeOf");
95 |
96 | a = {};
97 | assert(a.toString(), "[object Object]", "toString");
98 |
99 | a = {x:1};
100 | assert(Object.isExtensible(a), true, "extensible");
101 | Object.preventExtensions(a);
102 |
103 | err = false;
104 | try {
105 | a.y = 2;
106 | } catch(e) {
107 | err = true;
108 | }
109 | assert(Object.isExtensible(a), false, "extensible");
110 | assert(typeof a.y, "undefined", "extensible");
111 | assert(err, true, "extensible");
112 | }
113 |
114 | function test_enum()
115 | {
116 | var a, tab;
117 | a = {x:1,
118 | "18014398509481984": 1,
119 | "9007199254740992": 1,
120 | "9007199254740991": 1,
121 | "4294967296": 1,
122 | "4294967295": 1,
123 | y:1,
124 | "4294967294": 1,
125 | "1": 2};
126 | tab = Object.keys(a);
127 | // console.log("tab=" + tab.toString());
128 | assert(tab, ["1","4294967294","x","18014398509481984","9007199254740992","9007199254740991","4294967296","4294967295","y"], "keys");
129 | }
130 |
131 | function test_array()
132 | {
133 | var a, err;
134 |
135 | a = [1, 2, 3];
136 | assert(a.length, 3, "array");
137 | assert(a[2], 3, "array1");
138 |
139 | a = new Array(10);
140 | assert(a.length, 10, "array2");
141 |
142 | a = new Array(1, 2);
143 | assert(a.length === 2 && a[0] === 1 && a[1] === 2, true, "array3");
144 |
145 | a = [1, 2, 3];
146 | a.length = 2;
147 | assert(a.length === 2 && a[0] === 1 && a[1] === 2, true, "array4");
148 |
149 | a = [];
150 | a[1] = 10;
151 | a[4] = 3;
152 | assert(a.length, 5);
153 |
154 | a = [1,2];
155 | a.length = 5;
156 | a[4] = 1;
157 | a.length = 4;
158 | assert(a[4] !== 1, true, "array5");
159 |
160 | a = [1,2];
161 | a.push(3,4);
162 | assert(a.join(), "1,2,3,4", "join");
163 |
164 | a = [1,2,3,4,5];
165 | Object.defineProperty(a, "3", { configurable: false });
166 | err = false;
167 | try {
168 | a.length = 2;
169 | } catch(e) {
170 | err = true;
171 | }
172 | assert(err && a.toString() === "1,2,3,4");
173 | }
174 |
175 | function test_string()
176 | {
177 | var a;
178 | a = String("abc");
179 | assert(a.length, 3, "string");
180 | assert(a[1], "b", "string");
181 | assert(a.charCodeAt(1), 0x62, "string");
182 | assert(String.fromCharCode(65), "A", "string");
183 | assert(String.fromCharCode.apply(null, [65, 66, 67]), "ABC", "string");
184 | assert(a.charAt(1), "b");
185 | assert(a.charAt(-1), "");
186 | assert(a.charAt(3), "");
187 |
188 | a = "abcd";
189 | assert(a.substring(1, 3), "bc", "substring");
190 | a = String.fromCharCode(0x20ac);
191 | assert(a.charCodeAt(0), 0x20ac, "unicode");
192 | assert(a, "€", "unicode");
193 | assert(a, "\u20ac", "unicode");
194 | assert(a, "\u{20ac}", "unicode");
195 | assert("a", "\x61", "unicode");
196 |
197 | a = "\u{10ffff}";
198 | assert(a.length, 2, "unicode");
199 | assert(a, "\u{dbff}\u{dfff}", "unicode");
200 | assert(a.codePointAt(0), 0x10ffff);
201 | assert(String.fromCodePoint(0x10ffff), a);
202 |
203 | assert("a".concat("b", "c"), "abc");
204 |
205 | assert("abcabc".indexOf("cab"), 2);
206 | assert("abcabc".indexOf("cab2"), -1);
207 | assert("abc".indexOf("c"), 2);
208 |
209 | assert("aaa".indexOf("a"), 0);
210 | assert("aaa".indexOf("a", NaN), 0);
211 | assert("aaa".indexOf("a", -Infinity), 0);
212 | assert("aaa".indexOf("a", -1), 0);
213 | assert("aaa".indexOf("a", -0), 0);
214 | assert("aaa".indexOf("a", 0), 0);
215 | assert("aaa".indexOf("a", 1), 1);
216 | assert("aaa".indexOf("a", 2), 2);
217 | assert("aaa".indexOf("a", 3), -1);
218 | assert("aaa".indexOf("a", 4), -1);
219 | assert("aaa".indexOf("a", Infinity), -1);
220 |
221 | assert("aaa".indexOf(""), 0);
222 | assert("aaa".indexOf("", NaN), 0);
223 | assert("aaa".indexOf("", -Infinity), 0);
224 | assert("aaa".indexOf("", -1), 0);
225 | assert("aaa".indexOf("", -0), 0);
226 | assert("aaa".indexOf("", 0), 0);
227 | assert("aaa".indexOf("", 1), 1);
228 | assert("aaa".indexOf("", 2), 2);
229 | assert("aaa".indexOf("", 3), 3);
230 | assert("aaa".indexOf("", 4), 3);
231 | assert("aaa".indexOf("", Infinity), 3);
232 |
233 | assert("aaa".lastIndexOf("a"), 2);
234 | assert("aaa".lastIndexOf("a", NaN), 2);
235 | assert("aaa".lastIndexOf("a", -Infinity), 0);
236 | assert("aaa".lastIndexOf("a", -1), 0);
237 | assert("aaa".lastIndexOf("a", -0), 0);
238 | assert("aaa".lastIndexOf("a", 0), 0);
239 | assert("aaa".lastIndexOf("a", 1), 1);
240 | assert("aaa".lastIndexOf("a", 2), 2);
241 | assert("aaa".lastIndexOf("a", 3), 2);
242 | assert("aaa".lastIndexOf("a", 4), 2);
243 | assert("aaa".lastIndexOf("a", Infinity), 2);
244 |
245 | assert("aaa".lastIndexOf(""), 3);
246 | assert("aaa".lastIndexOf("", NaN), 3);
247 | assert("aaa".lastIndexOf("", -Infinity), 0);
248 | assert("aaa".lastIndexOf("", -1), 0);
249 | assert("aaa".lastIndexOf("", -0), 0);
250 | assert("aaa".lastIndexOf("", 0), 0);
251 | assert("aaa".lastIndexOf("", 1), 1);
252 | assert("aaa".lastIndexOf("", 2), 2);
253 | assert("aaa".lastIndexOf("", 3), 3);
254 | assert("aaa".lastIndexOf("", 4), 3);
255 | assert("aaa".lastIndexOf("", Infinity), 3);
256 |
257 | assert("a,b,c".split(","), ["a","b","c"]);
258 | assert(",b,c".split(","), ["","b","c"]);
259 | assert("a,b,".split(","), ["a","b",""]);
260 |
261 | assert("aaaa".split(), [ "aaaa" ]);
262 | assert("aaaa".split(undefined, 0), [ ]);
263 | assert("aaaa".split(""), [ "a", "a", "a", "a" ]);
264 | assert("aaaa".split("", 0), [ ]);
265 | assert("aaaa".split("", 1), [ "a" ]);
266 | assert("aaaa".split("", 2), [ "a", "a" ]);
267 | assert("aaaa".split("a"), [ "", "", "", "", "" ]);
268 | assert("aaaa".split("a", 2), [ "", "" ]);
269 | assert("aaaa".split("aa"), [ "", "", "" ]);
270 | assert("aaaa".split("aa", 0), [ ]);
271 | assert("aaaa".split("aa", 1), [ "" ]);
272 | assert("aaaa".split("aa", 2), [ "", "" ]);
273 | assert("aaaa".split("aaa"), [ "", "a" ]);
274 | assert("aaaa".split("aaaa"), [ "", "" ]);
275 | assert("aaaa".split("aaaaa"), [ "aaaa" ]);
276 | assert("aaaa".split("aaaaa", 0), [ ]);
277 | assert("aaaa".split("aaaaa", 1), [ "aaaa" ]);
278 |
279 | assert(eval('"\0"'), "\0");
280 | }
281 |
282 | function test_math()
283 | {
284 | var a;
285 | a = 1.4;
286 | assert(Math.floor(a), 1);
287 | assert(Math.ceil(a), 2);
288 | assert(Math.imul(0x12345678, 123), -1088058456);
289 | assert(Math.fround(0.1), 0.10000000149011612);
290 | }
291 |
292 | function test_number()
293 | {
294 | assert(parseInt("123"), 123);
295 | assert(parseInt(" 123r"), 123);
296 | assert(parseInt("0x123"), 0x123);
297 | assert(parseInt("0o123"), 0);
298 | assert(+" 123 ", 123);
299 | assert(+"0b111", 7);
300 | assert(+"0o123", 83);
301 | assert(parseFloat("0x1234"), 0);
302 | assert(parseFloat("Infinity"), Infinity);
303 | assert(parseFloat("-Infinity"), -Infinity);
304 | assert(parseFloat("123.2"), 123.2);
305 | assert(parseFloat("123.2e3"), 123200);
306 | assert(Number.isNaN(Number("+")));
307 | assert(Number.isNaN(Number("-")));
308 | assert(Number.isNaN(Number("\x00a")));
309 |
310 | assert((25).toExponential(0), "3e+1");
311 | assert((-25).toExponential(0), "-3e+1");
312 | assert((2.5).toPrecision(1), "3");
313 | assert((-2.5).toPrecision(1), "-3");
314 | assert((1.125).toFixed(2), "1.13");
315 | assert((-1.125).toFixed(2), "-1.13");
316 | }
317 |
318 | function test_eval2()
319 | {
320 | var g_call_count = 0;
321 | /* force non strict mode for f1 and f2 */
322 | var f1 = new Function("eval", "eval(1, 2)");
323 | var f2 = new Function("eval", "eval(...[1, 2])");
324 | function g(a, b) {
325 | assert(a, 1);
326 | assert(b, 2);
327 | g_call_count++;
328 | }
329 | f1(g);
330 | f2(g);
331 | assert(g_call_count, 2);
332 | }
333 |
334 | function test_eval()
335 | {
336 | function f(b) {
337 | var x = 1;
338 | return eval(b);
339 | }
340 | var r, a;
341 |
342 | r = eval("1+1;");
343 | assert(r, 2, "eval");
344 |
345 | r = eval("var my_var=2; my_var;");
346 | assert(r, 2, "eval");
347 | assert(typeof my_var, "undefined");
348 |
349 | assert(eval("if (1) 2; else 3;"), 2);
350 | assert(eval("if (0) 2; else 3;"), 3);
351 |
352 | assert(f.call(1, "this"), 1);
353 |
354 | a = 2;
355 | assert(eval("a"), 2);
356 |
357 | eval("a = 3");
358 | assert(a, 3);
359 |
360 | assert(f("arguments.length", 1), 2);
361 | assert(f("arguments[1]", 1), 1);
362 |
363 | a = 4;
364 | assert(f("a"), 4);
365 | f("a=3");
366 | assert(a, 3);
367 |
368 | test_eval2();
369 | }
370 |
371 | function test_typed_array()
372 | {
373 | var buffer, a, i;
374 |
375 | a = new Uint8Array(4);
376 | assert(a.length, 4);
377 | for(i = 0; i < a.length; i++)
378 | a[i] = i;
379 | assert(a.join(","), "0,1,2,3");
380 | a[0] = -1;
381 | assert(a[0], 255);
382 |
383 | a = new Int8Array(3);
384 | a[0] = 255;
385 | assert(a[0], -1);
386 |
387 | a = new Int32Array(3);
388 | a[0] = Math.pow(2, 32) - 1;
389 | assert(a[0], -1);
390 | assert(a.BYTES_PER_ELEMENT, 4);
391 |
392 | a = new Uint8ClampedArray(4);
393 | a[0] = -100;
394 | a[1] = 1.5;
395 | a[2] = 0.5;
396 | a[3] = 1233.5;
397 | assert(a.toString(), "0,2,0,255");
398 |
399 | buffer = new ArrayBuffer(16);
400 | assert(buffer.byteLength, 16);
401 | a = new Uint32Array(buffer, 12, 1);
402 | assert(a.length, 1);
403 | a[0] = -1;
404 |
405 | a = new Uint16Array(buffer, 2);
406 | a[0] = -1;
407 |
408 | a = new Float32Array(buffer, 8, 1);
409 | a[0] = 1;
410 |
411 | a = new Uint8Array(buffer);
412 |
413 | assert(a.toString(), "0,0,255,255,0,0,0,0,0,0,128,63,255,255,255,255");
414 |
415 | assert(a.buffer, buffer);
416 |
417 | a = new Uint8Array([1, 2, 3, 4]);
418 | assert(a.toString(), "1,2,3,4");
419 | a.set([10, 11], 2);
420 | assert(a.toString(), "1,2,10,11");
421 | }
422 |
423 | function test_json()
424 | {
425 | var a, s;
426 | s = '{"x":1,"y":true,"z":null,"a":[1,2,3],"s":"str"}';
427 | a = JSON.parse(s);
428 | assert(a.x, 1);
429 | assert(a.y, true);
430 | assert(a.z, null);
431 | assert(JSON.stringify(a), s);
432 |
433 | /* indentation test */
434 | assert(JSON.stringify([[{x:1,y:{},z:[]},2,3]],undefined,1),
435 | `[
436 | [
437 | {
438 | "x": 1,
439 | "y": {},
440 | "z": []
441 | },
442 | 2,
443 | 3
444 | ]
445 | ]`);
446 | }
447 |
448 | function test_date()
449 | {
450 | var d = new Date(1506098258091), a, s;
451 | assert(d.toISOString(), "2017-09-22T16:37:38.091Z");
452 | d.setUTCHours(18, 10, 11);
453 | assert(d.toISOString(), "2017-09-22T18:10:11.091Z");
454 | a = Date.parse(d.toISOString());
455 | assert((new Date(a)).toISOString(), d.toISOString());
456 | s = new Date("2020-01-01T01:01:01.1Z").toISOString();
457 | assert(s == "2020-01-01T01:01:01.100Z");
458 | s = new Date("2020-01-01T01:01:01.12Z").toISOString();
459 | assert(s == "2020-01-01T01:01:01.120Z");
460 | s = new Date("2020-01-01T01:01:01.123Z").toISOString();
461 | assert(s == "2020-01-01T01:01:01.123Z");
462 | s = new Date("2020-01-01T01:01:01.1234Z").toISOString();
463 | assert(s == "2020-01-01T01:01:01.123Z");
464 | s = new Date("2020-01-01T01:01:01.12345Z").toISOString();
465 | assert(s == "2020-01-01T01:01:01.123Z");
466 | s = new Date("2020-01-01T01:01:01.1235Z").toISOString();
467 | assert(s == "2020-01-01T01:01:01.124Z");
468 | s = new Date("2020-01-01T01:01:01.9999Z").toISOString();
469 | assert(s == "2020-01-01T01:01:02.000Z");
470 | }
471 |
472 | function test_regexp()
473 | {
474 | var a, str;
475 | str = "abbbbbc";
476 | a = /(b+)c/.exec(str);
477 | assert(a[0], "bbbbbc");
478 | assert(a[1], "bbbbb");
479 | assert(a.index, 1);
480 | assert(a.input, str);
481 | a = /(b+)c/.test(str);
482 | assert(a, true);
483 | assert(/\x61/.exec("a")[0], "a");
484 | assert(/\u0061/.exec("a")[0], "a");
485 | assert(/\ca/.exec("\x01")[0], "\x01");
486 | assert(/\\a/.exec("\\a")[0], "\\a");
487 | assert(/\c0/.exec("\\c0")[0], "\\c0");
488 |
489 | a = /(\.(?=com|org)|\/)/.exec("ah.com");
490 | assert(a.index === 2 && a[0] === ".");
491 |
492 | a = /(\.(?!com|org)|\/)/.exec("ah.com");
493 | assert(a, null);
494 |
495 | a = /(?=(a+))/.exec("baaabac");
496 | assert(a.index === 1 && a[0] === "" && a[1] === "aaa");
497 |
498 | a = /(z)((a+)?(b+)?(c))*/.exec("zaacbbbcac");
499 | assert(a, ["zaacbbbcac","z","ac","a",,"c"]);
500 |
501 | a = eval("/\0a/");
502 | assert(a.toString(), "/\0a/");
503 | assert(a.exec("\0a")[0], "\0a");
504 | }
505 |
506 | function test_symbol()
507 | {
508 | var a, b, obj, c;
509 | a = Symbol("abc");
510 | obj = {};
511 | obj[a] = 2;
512 | assert(obj[a], 2);
513 | assert(typeof obj["abc"], "undefined");
514 | assert(String(a), "Symbol(abc)");
515 | b = Symbol("abc");
516 | assert(a == a);
517 | assert(a === a);
518 | assert(a != b);
519 | assert(a !== b);
520 |
521 | b = Symbol.for("abc");
522 | c = Symbol.for("abc");
523 | assert(b === c);
524 | assert(b !== a);
525 |
526 | assert(Symbol.keyFor(b), "abc");
527 | assert(Symbol.keyFor(a), undefined);
528 |
529 | a = Symbol("aaa");
530 | assert(a.valueOf(), a);
531 | assert(a.toString(), "Symbol(aaa)");
532 |
533 | b = Object(a);
534 | assert(b.valueOf(), a);
535 | assert(b.toString(), "Symbol(aaa)");
536 | }
537 |
538 | function test_map()
539 | {
540 | var a, i, n, tab, o, v;
541 | n = 1000;
542 | a = new Map();
543 | tab = [];
544 | for(i = 0; i < n; i++) {
545 | v = { };
546 | o = { id: i };
547 | tab[i] = [o, v];
548 | a.set(o, v);
549 | }
550 |
551 | assert(a.size, n);
552 | for(i = 0; i < n; i++) {
553 | assert(a.get(tab[i][0]), tab[i][1]);
554 | }
555 |
556 | i = 0;
557 | a.forEach(function (v, o) {
558 | assert(o, tab[i++][0]);
559 | assert(a.has(o));
560 | assert(a.delete(o));
561 | assert(!a.has(o));
562 | });
563 |
564 | assert(a.size, 0);
565 | }
566 |
567 | function test_weak_map()
568 | {
569 | var a, i, n, tab, o, v, n2;
570 | a = new WeakMap();
571 | n = 10;
572 | tab = [];
573 | for(i = 0; i < n; i++) {
574 | v = { };
575 | o = { id: i };
576 | tab[i] = [o, v];
577 | a.set(o, v);
578 | }
579 | o = null;
580 |
581 | n2 = n >> 1;
582 | for(i = 0; i < n2; i++) {
583 | a.delete(tab[i][0]);
584 | }
585 | for(i = n2; i < n; i++) {
586 | tab[i][0] = null; /* should remove the object from the WeakMap too */
587 | }
588 | /* the WeakMap should be empty here */
589 | }
590 |
591 | function test_generator()
592 | {
593 | function *f() {
594 | var ret;
595 | yield 1;
596 | ret = yield 2;
597 | assert(ret, "next_arg");
598 | return 3;
599 | }
600 | function *f2() {
601 | yield 1;
602 | yield 2;
603 | return "ret_val";
604 | }
605 | function *f1() {
606 | var ret = yield *f2();
607 | assert(ret, "ret_val");
608 | return 3;
609 | }
610 | var g, v;
611 | g = f();
612 | v = g.next();
613 | assert(v.value === 1 && v.done === false);
614 | v = g.next();
615 | assert(v.value === 2 && v.done === false);
616 | v = g.next("next_arg");
617 | assert(v.value === 3 && v.done === true);
618 | v = g.next();
619 | assert(v.value === undefined && v.done === true);
620 |
621 | g = f1();
622 | v = g.next();
623 | assert(v.value === 1 && v.done === false);
624 | v = g.next();
625 | assert(v.value === 2 && v.done === false);
626 | v = g.next();
627 | assert(v.value === 3 && v.done === true);
628 | v = g.next();
629 | assert(v.value === undefined && v.done === true);
630 | }
631 |
632 | test();
633 | test_function();
634 | test_enum();
635 | test_array();
636 | test_string();
637 | test_math();
638 | test_number();
639 | test_eval();
640 | test_typed_array();
641 | test_json();
642 | test_date();
643 | test_regexp();
644 | test_symbol();
645 | test_map();
646 | test_weak_map();
647 | test_generator();
648 |
--------------------------------------------------------------------------------
/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_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_break()
171 | {
172 | var i, c;
173 | c = 0;
174 | L1: for(i = 0; i < 3; i++) {
175 | c++;
176 | if (i == 0)
177 | continue;
178 | while (1) {
179 | break L1;
180 | }
181 | }
182 | assert(c === 2 && i === 1);
183 | }
184 |
185 | function test_switch1()
186 | {
187 | var i, a, s;
188 | s = "";
189 | for(i = 0; i < 3; i++) {
190 | a = "?";
191 | switch(i) {
192 | case 0:
193 | a = "a";
194 | break;
195 | case 1:
196 | a = "b";
197 | break;
198 | default:
199 | a = "c";
200 | break;
201 | }
202 | s += a;
203 | }
204 | assert(s === "abc" && i === 3);
205 | }
206 |
207 | function test_switch2()
208 | {
209 | var i, a, s;
210 | s = "";
211 | for(i = 0; i < 4; i++) {
212 | a = "?";
213 | switch(i) {
214 | case 0:
215 | a = "a";
216 | break;
217 | case 1:
218 | a = "b";
219 | break;
220 | case 2:
221 | continue;
222 | default:
223 | a = "" + i;
224 | break;
225 | }
226 | s += a;
227 | }
228 | assert(s === "ab3" && i === 4);
229 | }
230 |
231 | function test_try_catch1()
232 | {
233 | try {
234 | throw "hello";
235 | } catch (e) {
236 | assert(e, "hello", "catch");
237 | return;
238 | }
239 | assert(false, "catch");
240 | }
241 |
242 | function test_try_catch2()
243 | {
244 | var a;
245 | try {
246 | a = 1;
247 | } catch (e) {
248 | a = 2;
249 | }
250 | assert(a, 1, "catch");
251 | }
252 |
253 | function test_try_catch3()
254 | {
255 | var s;
256 | s = "";
257 | try {
258 | s += "t";
259 | } catch (e) {
260 | s += "c";
261 | } finally {
262 | s += "f";
263 | }
264 | assert(s, "tf", "catch");
265 | }
266 |
267 | function test_try_catch4()
268 | {
269 | var s;
270 | s = "";
271 | try {
272 | s += "t";
273 | throw "c";
274 | } catch (e) {
275 | s += e;
276 | } finally {
277 | s += "f";
278 | }
279 | assert(s, "tcf", "catch");
280 | }
281 |
282 | function test_try_catch5()
283 | {
284 | var s;
285 | s = "";
286 | for(;;) {
287 | try {
288 | s += "t";
289 | break;
290 | s += "b";
291 | } finally {
292 | s += "f";
293 | }
294 | }
295 | assert(s, "tf", "catch");
296 | }
297 |
298 | function test_try_catch6()
299 | {
300 | function f() {
301 | try {
302 | s += 't';
303 | return 1;
304 | } finally {
305 | s += "f";
306 | }
307 | }
308 | var s = "";
309 | assert(f() === 1);
310 | assert(s, "tf", "catch6");
311 | }
312 |
313 | function test_try_catch7()
314 | {
315 | var s;
316 | s = "";
317 |
318 | try {
319 | try {
320 | s += "t";
321 | throw "a";
322 | } finally {
323 | s += "f";
324 | }
325 | } catch(e) {
326 | s += e;
327 | } finally {
328 | s += "g";
329 | }
330 | assert(s, "tfag", "catch");
331 | }
332 |
333 | function test_try_catch8()
334 | {
335 | var i, s;
336 |
337 | s = "";
338 | for(var i in {x:1, y:2}) {
339 | try {
340 | s += i;
341 | throw "a";
342 | } catch (e) {
343 | s += e;
344 | } finally {
345 | s += "f";
346 | }
347 | }
348 | assert(s === "xafyaf");
349 | }
350 |
351 | test_while();
352 | test_while_break();
353 | test_do_while();
354 | test_for();
355 | test_for_break();
356 | test_switch1();
357 | test_switch2();
358 | test_for_in();
359 | test_for_in2();
360 |
361 | test_try_catch1();
362 | test_try_catch2();
363 | test_try_catch3();
364 | test_try_catch4();
365 | test_try_catch5();
366 | test_try_catch6();
367 | test_try_catch7();
368 | test_try_catch8();
369 |
--------------------------------------------------------------------------------
/tests/test_op.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_op1()
24 | {
25 | var r, a;
26 | r = 1 + 2;
27 | assert(r, 3, "1 + 2 === 3");
28 |
29 | r = 1 - 2;
30 | assert(r, -1, "1 - 2 === -1");
31 |
32 | r = -1;
33 | assert(r, -1, "-1 === -1");
34 |
35 | r = +2;
36 | assert(r, 2, "+2 === 2");
37 |
38 | r = 2 * 3;
39 | assert(r, 6, "2 * 3 === 6");
40 |
41 | r = 4 / 2;
42 | assert(r, 2, "4 / 2 === 2");
43 |
44 | r = 4 % 3;
45 | assert(r, 1, "4 % 3 === 3");
46 |
47 | r = 4 << 2;
48 | assert(r, 16, "4 << 2 === 16");
49 |
50 | r = 1 << 0;
51 | assert(r, 1, "1 << 0 === 1");
52 |
53 | r = 1 << 31;
54 | assert(r, -2147483648, "1 << 31 === -2147483648");
55 |
56 | r = 1 << 32;
57 | assert(r, 1, "1 << 32 === 1");
58 |
59 | r = (1 << 31) < 0;
60 | assert(r, true, "(1 << 31) < 0 === true");
61 |
62 | r = -4 >> 1;
63 | assert(r, -2, "-4 >> 1 === -2");
64 |
65 | r = -4 >>> 1;
66 | assert(r, 0x7ffffffe, "-4 >>> 1 === 0x7ffffffe");
67 |
68 | r = 1 & 1;
69 | assert(r, 1, "1 & 1 === 1");
70 |
71 | r = 0 | 1;
72 | assert(r, 1, "0 | 1 === 1");
73 |
74 | r = 1 ^ 1;
75 | assert(r, 0, "1 ^ 1 === 0");
76 |
77 | r = ~1;
78 | assert(r, -2, "~1 === -2");
79 |
80 | r = !1;
81 | assert(r, false, "!1 === false");
82 |
83 | assert((1 < 2), true, "(1 < 2) === true");
84 |
85 | assert((2 > 1), true, "(2 > 1) === true");
86 |
87 | assert(('b' > 'a'), true, "('b' > 'a') === true");
88 |
89 | assert(2 ** 8, 256, "2 ** 8 === 256");
90 | }
91 |
92 | function test_cvt()
93 | {
94 | assert((NaN | 0) === 0);
95 | assert((Infinity | 0) === 0);
96 | assert(((-Infinity) | 0) === 0);
97 | assert(("12345" | 0) === 12345);
98 | assert(("0x12345" | 0) === 0x12345);
99 | assert(((4294967296 * 3 - 4) | 0) === -4);
100 |
101 | assert(("12345" >>> 0) === 12345);
102 | assert(("0x12345" >>> 0) === 0x12345);
103 | assert((NaN >>> 0) === 0);
104 | assert((Infinity >>> 0) === 0);
105 | assert(((-Infinity) >>> 0) === 0);
106 | assert(((4294967296 * 3 - 4) >>> 0) === (4294967296 - 4));
107 | }
108 |
109 | function test_eq()
110 | {
111 | assert(null == undefined);
112 | assert(undefined == null);
113 | assert(true == 1);
114 | assert(0 == false);
115 | assert("" == 0);
116 | assert("123" == 123);
117 | assert("122" != 123);
118 | assert((new Number(1)) == 1);
119 | assert(2 == (new Number(2)));
120 | assert((new String("abc")) == "abc");
121 | assert({} != "abc");
122 | }
123 |
124 | function test_inc_dec()
125 | {
126 | var a, r;
127 |
128 | a = 1;
129 | r = a++;
130 | assert(r === 1 && a === 2, true, "++");
131 |
132 | a = 1;
133 | r = ++a;
134 | assert(r === 2 && a === 2, true, "++");
135 |
136 | a = 1;
137 | r = a--;
138 | assert(r === 1 && a === 0, true, "--");
139 |
140 | a = 1;
141 | r = --a;
142 | assert(r === 0 && a === 0, true, "--");
143 |
144 | a = {x:true};
145 | a.x++;
146 | assert(a.x, 2, "++");
147 |
148 | a = {x:true};
149 | a.x--;
150 | assert(a.x, 0, "--");
151 |
152 | a = [true];
153 | a[0]++;
154 | assert(a[0], 2, "++");
155 |
156 | a = {x:true};
157 | r = a.x++;
158 | assert(r === 1 && a.x === 2, true, "++");
159 |
160 | a = {x:true};
161 | r = a.x--;
162 | assert(r === 1 && a.x === 0, true, "--");
163 |
164 | a = [true];
165 | r = a[0]++;
166 | assert(r === 1 && a[0] === 2, true, "++");
167 |
168 | a = [true];
169 | r = a[0]--;
170 | assert(r === 1 && a[0] === 0, true, "--");
171 | }
172 |
173 | function F(x)
174 | {
175 | this.x = x;
176 | }
177 |
178 | function test_op2()
179 | {
180 | var a, b;
181 | a = new Object;
182 | a.x = 1;
183 | assert(a.x, 1, "new");
184 | b = new F(2);
185 | assert(b.x, 2, "new");
186 |
187 | a = {x : 2};
188 | assert(("x" in a), true, "in");
189 | assert(("y" in a), false, "in");
190 |
191 | a = {};
192 | assert((a instanceof Object), true, "instanceof");
193 | assert((a instanceof String), false, "instanceof");
194 |
195 | assert((typeof 1), "number", "typeof");
196 | assert((typeof Object), "function", "typeof");
197 | assert((typeof null), "object", "typeof");
198 | assert((typeof unknown_var), "undefined", "typeof");
199 |
200 | a = {x: 1, if: 2, async: 3};
201 | assert(a.if === 2);
202 | assert(a.async === 3);
203 | }
204 |
205 | function test_delete()
206 | {
207 | var a, err;
208 |
209 | a = {x: 1, y: 1};
210 | assert((delete a.x), true, "delete");
211 | assert(("x" in a), false, "delete");
212 |
213 | /* the following are not tested by test262 */
214 | assert(delete "abc"[100], true);
215 |
216 | err = false;
217 | try {
218 | delete null.a;
219 | } catch(e) {
220 | err = (e instanceof TypeError);
221 | }
222 | assert(err, true, "delete");
223 |
224 | err = false;
225 | try {
226 | a = { f() { delete super.a; } };
227 | a.f();
228 | } catch(e) {
229 | err = (e instanceof ReferenceError);
230 | }
231 | assert(err, true, "delete");
232 | }
233 |
234 | function test_prototype()
235 | {
236 | function f() { }
237 | assert(f.prototype.constructor, f, "prototype");
238 | }
239 |
240 | function test_arguments()
241 | {
242 | function f2() {
243 | assert(arguments.length, 2, "arguments");
244 | assert(arguments[0], 1, "arguments");
245 | assert(arguments[1], 3, "arguments");
246 | }
247 | f2(1, 3);
248 | }
249 |
250 | function test_class()
251 | {
252 | var o;
253 | class C {
254 | constructor() {
255 | this.x = 10;
256 | }
257 | f() {
258 | return 1;
259 | }
260 | static F() {
261 | return -1;
262 | }
263 | get y() {
264 | return 12;
265 | }
266 | };
267 | class D extends C {
268 | constructor() {
269 | super();
270 | this.z = 20;
271 | }
272 | g() {
273 | return 2;
274 | }
275 | static G() {
276 | return -2;
277 | }
278 | h() {
279 | return super.f();
280 | }
281 | static H() {
282 | return super["F"]();
283 | }
284 | }
285 |
286 | assert(C.F() === -1);
287 | assert(Object.getOwnPropertyDescriptor(C.prototype, "y").get.name === "get y");
288 |
289 | o = new C();
290 | assert(o.f() === 1);
291 | assert(o.x === 10);
292 |
293 | assert(D.F() === -1);
294 | assert(D.G() === -2);
295 | assert(D.H() === -1);
296 |
297 | o = new D();
298 | assert(o.f() === 1);
299 | assert(o.g() === 2);
300 | assert(o.x === 10);
301 | assert(o.z === 20);
302 | assert(o.h() === 1);
303 |
304 | /* test class name scope */
305 | var E1 = class E { static F() { return E; } };
306 | assert(E1 === E1.F());
307 | };
308 |
309 | function test_template()
310 | {
311 | var a, b;
312 | b = 123;
313 | a = `abc${b}d`;
314 | assert(a === "abc123d");
315 |
316 | a = String.raw `abc${b}d`;
317 | assert(a === "abc123d");
318 | }
319 |
320 | function test_object_literal()
321 | {
322 | var x = 0, get = 1, set = 2; async = 3;
323 | a = { get: 2, set: 3, async: 4 };
324 | assert(JSON.stringify(a), '{"get":2,"set":3,"async":4}');
325 |
326 | a = { x, get, set, async };
327 | assert(JSON.stringify(a), '{"x":0,"get":1,"set":2,"async":3}');
328 | }
329 |
330 | function test_regexp_skip()
331 | {
332 | var a, b;
333 | [a, b = /abc\(/] = [1];
334 | assert(a === 1);
335 |
336 | [a, b =/abc\(/] = [2];
337 | assert(a === 2);
338 | }
339 |
340 | function test_labels()
341 | {
342 | do x: { break x; } while(0);
343 | if (1)
344 | x: { break x; }
345 | else
346 | x: { break x; }
347 | with ({}) x: { break x; };
348 | while (0) x: { break x; };
349 | }
350 |
351 | test_op1();
352 | test_cvt();
353 | test_eq();
354 | test_inc_dec();
355 | test_op2();
356 | test_delete();
357 | test_prototype();
358 | test_arguments();
359 | test_class();
360 | test_template();
361 | test_object_literal();
362 | test_regexp_skip();
363 | test_labels();
364 |
--------------------------------------------------------------------------------
/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 | import * as std from "std";
2 | import * as os from "os";
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 | // load more elaborate version of assert if available
22 | try { std.loadScript("test_assert.js"); } catch(e) {}
23 |
24 | /*----------------*/
25 |
26 | function test_printf()
27 | {
28 | assert(std.sprintf("a=%d s=%s", 123, "abc"), "a=123 s=abc");
29 | }
30 |
31 | function test_file1()
32 | {
33 | var f, len, str, size, buf, ret, i, str1;
34 |
35 | f = std.tmpfile();
36 | str = "hello world\n";
37 | f.puts(str);
38 |
39 | f.seek(0, std.SEEK_SET);
40 | str1 = f.readAsString();
41 | assert(str1 === str);
42 |
43 | f.seek(0, std.SEEK_END);
44 | size = f.tell();
45 | assert(size === str.length);
46 |
47 | f.seek(0, std.SEEK_SET);
48 |
49 | buf = new Uint8Array(size);
50 | ret = f.read(buf.buffer, 0, size);
51 | assert(ret === size);
52 | for(i = 0; i < size; i++)
53 | assert(buf[i] === str.charCodeAt(i));
54 |
55 | f.close();
56 | }
57 |
58 | function test_file2()
59 | {
60 | var f, str, i, size;
61 | f = std.tmpfile();
62 | str = "hello world\n";
63 | size = str.length;
64 | for(i = 0; i < size; i++)
65 | f.putByte(str.charCodeAt(i));
66 | f.seek(0, std.SEEK_SET);
67 | for(i = 0; i < size; i++) {
68 | assert(str.charCodeAt(i) === f.getByte());
69 | }
70 | assert(f.getByte() === -1);
71 | f.close();
72 | }
73 |
74 | function test_getline()
75 | {
76 | var f, line, line_count, lines, i;
77 |
78 | lines = ["hello world", "line 1", "line 2" ];
79 | f = std.tmpfile();
80 | for(i = 0; i < lines.length; i++) {
81 | f.puts(lines[i], "\n");
82 | }
83 |
84 | f.seek(0, std.SEEK_SET);
85 | assert(!f.eof());
86 | line_count = 0;
87 | for(;;) {
88 | line = f.getline();
89 | if (line === null)
90 | break;
91 | assert(line == lines[line_count]);
92 | line_count++;
93 | }
94 | assert(f.eof());
95 | assert(line_count === lines.length);
96 |
97 | f.close();
98 | }
99 |
100 | function test_popen()
101 | {
102 | var str, f, fname = "tmp_file.txt";
103 | var content = "hello world";
104 |
105 | f = std.open(fname, "w");
106 | f.puts(content);
107 | f.close();
108 |
109 | /* execute the 'cat' shell command */
110 | f = std.popen("cat " + fname, "r");
111 | str = f.readAsString();
112 | f.close();
113 |
114 | assert(str, content);
115 |
116 | os.remove(fname);
117 | }
118 |
119 | function test_os()
120 | {
121 | var fd, fpath, fname, fdir, buf, buf2, i, files, err, fdate, st, link_path;
122 |
123 | assert(os.isatty(0));
124 |
125 | fdir = "test_tmp_dir";
126 | fname = "tmp_file.txt";
127 | fpath = fdir + "/" + fname;
128 | link_path = fdir + "/test_link";
129 |
130 | os.remove(link_path);
131 | os.remove(fpath);
132 | os.remove(fdir);
133 |
134 | err = os.mkdir(fdir, 0o755);
135 | assert(err === 0);
136 |
137 | fd = os.open(fpath, os.O_RDWR | os.O_CREAT | os.O_TRUNC);
138 | assert(fd >= 0);
139 |
140 | buf = new Uint8Array(10);
141 | for(i = 0; i < buf.length; i++)
142 | buf[i] = i;
143 | assert(os.write(fd, buf.buffer, 0, buf.length) === buf.length);
144 |
145 | assert(os.seek(fd, 0, os.SEEK_SET) === 0);
146 | buf2 = new Uint8Array(buf.length);
147 | assert(os.read(fd, buf2.buffer, 0, buf2.length) === buf2.length);
148 |
149 | for(i = 0; i < buf.length; i++)
150 | assert(buf[i] == buf2[i]);
151 |
152 | assert(os.close(fd) === 0);
153 |
154 | [files, err] = os.readdir(fdir);
155 | assert(err, 0);
156 | assert(files.indexOf(fname) >= 0);
157 |
158 | fdate = 10000;
159 |
160 | err = os.utimes(fpath, fdate, fdate);
161 | assert(err, 0);
162 |
163 | [st, err] = os.stat(fpath);
164 | assert(err, 0);
165 | assert(st.mode & os.S_IFMT, os.S_IFREG);
166 | assert(st.mtime, fdate);
167 |
168 | err = os.symlink(fname, link_path);
169 | assert(err === 0);
170 |
171 | [st, err] = os.lstat(link_path);
172 | assert(err, 0);
173 | assert(st.mode & os.S_IFMT, os.S_IFLNK);
174 |
175 | [buf, err] = os.readlink(link_path);
176 | assert(err, 0);
177 | assert(buf, fname);
178 |
179 | assert(os.remove(link_path) === 0);
180 |
181 | [buf, err] = os.getcwd();
182 | assert(err, 0);
183 |
184 | [buf2, err] = os.realpath(".");
185 | assert(err, 0);
186 |
187 | assert(buf, buf2);
188 |
189 | assert(os.remove(fpath) === 0);
190 |
191 | fd = os.open(fpath, os.O_RDONLY);
192 | assert(fd < 0);
193 |
194 | assert(os.remove(fdir) === 0);
195 | }
196 |
197 | function test_os_exec()
198 | {
199 | var ret, fds, pid, f, status;
200 |
201 | ret = os.exec(["true"]);
202 | assert(ret, 0);
203 |
204 | ret = os.exec(["/bin/sh", "-c", "exit 1"], { usePath: false });
205 | assert(ret, 1);
206 |
207 | fds = os.pipe();
208 | pid = os.exec(["echo", "hello"], { stdout: fds[1], block: false } );
209 | assert(pid >= 0);
210 | os.close(fds[1]); /* close the write end (as it is only in the child) */
211 | f = std.fdopen(fds[0], "r");
212 | assert(f.getline(), "hello");
213 | assert(f.getline(), null);
214 | f.close();
215 | [ret, status] = os.waitpid(pid, 0);
216 | assert(ret, pid);
217 | assert(status & 0x7f, 0); /* exited */
218 | assert(status >> 8, 0); /* exit code */
219 |
220 | pid = os.exec(["cat"], { block: false } );
221 | assert(pid >= 0);
222 | os.kill(pid, os.SIGQUIT);
223 | [ret, status] = os.waitpid(pid, 0);
224 | assert(ret, pid);
225 | assert(status & 0x7f, os.SIGQUIT);
226 | }
227 |
228 | function test_timer()
229 | {
230 | var th, i;
231 |
232 | /* just test that a timer can be inserted and removed */
233 | th = [];
234 | for(i = 0; i < 3; i++)
235 | th[i] = os.setTimeout(function () { }, 1000);
236 | for(i = 0; i < 3; i++)
237 | os.clearTimeout(th[i]);
238 | }
239 |
240 | test_printf();
241 | test_file1();
242 | test_file2();
243 | test_getline();
244 | test_popen();
245 | test_os();
246 | test_os_exec();
247 | test_timer();
248 |
--------------------------------------------------------------------------------
/unicode_download.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | url="ftp://ftp.unicode.org/Public/12.1.0/ucd"
5 | emoji_url="ftp://ftp.unicode.org/Public/emoji/12.0/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(Common, "Zyyy")
70 | DEF(Coptic, "Copt,Qaac")
71 | DEF(Cuneiform, "Xsux")
72 | DEF(Cypriot, "Cprt")
73 | DEF(Cyrillic, "Cyrl")
74 | DEF(Deseret, "Dsrt")
75 | DEF(Devanagari, "Deva")
76 | DEF(Dogra, "Dogr")
77 | DEF(Duployan, "Dupl")
78 | DEF(Egyptian_Hieroglyphs, "Egyp")
79 | DEF(Elbasan, "Elba")
80 | DEF(Elymaic, "Elym")
81 | DEF(Ethiopic, "Ethi")
82 | DEF(Georgian, "Geor")
83 | DEF(Glagolitic, "Glag")
84 | DEF(Gothic, "Goth")
85 | DEF(Grantha, "Gran")
86 | DEF(Greek, "Grek")
87 | DEF(Gujarati, "Gujr")
88 | DEF(Gunjala_Gondi, "Gong")
89 | DEF(Gurmukhi, "Guru")
90 | DEF(Han, "Hani")
91 | DEF(Hangul, "Hang")
92 | DEF(Hanifi_Rohingya, "Rohg")
93 | DEF(Hanunoo, "Hano")
94 | DEF(Hatran, "Hatr")
95 | DEF(Hebrew, "Hebr")
96 | DEF(Hiragana, "Hira")
97 | DEF(Imperial_Aramaic, "Armi")
98 | DEF(Inherited, "Zinh,Qaai")
99 | DEF(Inscriptional_Pahlavi, "Phli")
100 | DEF(Inscriptional_Parthian, "Prti")
101 | DEF(Javanese, "Java")
102 | DEF(Kaithi, "Kthi")
103 | DEF(Kannada, "Knda")
104 | DEF(Katakana, "Kana")
105 | DEF(Kayah_Li, "Kali")
106 | DEF(Kharoshthi, "Khar")
107 | DEF(Khmer, "Khmr")
108 | DEF(Khojki, "Khoj")
109 | DEF(Khudawadi, "Sind")
110 | DEF(Lao, "Laoo")
111 | DEF(Latin, "Latn")
112 | DEF(Lepcha, "Lepc")
113 | DEF(Limbu, "Limb")
114 | DEF(Linear_A, "Lina")
115 | DEF(Linear_B, "Linb")
116 | DEF(Lisu, "Lisu")
117 | DEF(Lycian, "Lyci")
118 | DEF(Lydian, "Lydi")
119 | DEF(Makasar, "Maka")
120 | DEF(Mahajani, "Mahj")
121 | DEF(Malayalam, "Mlym")
122 | DEF(Mandaic, "Mand")
123 | DEF(Manichaean, "Mani")
124 | DEF(Marchen, "Marc")
125 | DEF(Masaram_Gondi, "Gonm")
126 | DEF(Medefaidrin, "Medf")
127 | DEF(Meetei_Mayek, "Mtei")
128 | DEF(Mende_Kikakui, "Mend")
129 | DEF(Meroitic_Cursive, "Merc")
130 | DEF(Meroitic_Hieroglyphs, "Mero")
131 | DEF(Miao, "Plrd")
132 | DEF(Modi, "Modi")
133 | DEF(Mongolian, "Mong")
134 | DEF(Mro, "Mroo")
135 | DEF(Multani, "Mult")
136 | DEF(Myanmar, "Mymr")
137 | DEF(Nabataean, "Nbat")
138 | DEF(Nandinagari, "Nand")
139 | DEF(New_Tai_Lue, "Talu")
140 | DEF(Newa, "Newa")
141 | DEF(Nko, "Nkoo")
142 | DEF(Nushu, "Nshu")
143 | DEF(Nyiakeng_Puachue_Hmong, "Hmnp")
144 | DEF(Ogham, "Ogam")
145 | DEF(Ol_Chiki, "Olck")
146 | DEF(Old_Hungarian, "Hung")
147 | DEF(Old_Italic, "Ital")
148 | DEF(Old_North_Arabian, "Narb")
149 | DEF(Old_Permic, "Perm")
150 | DEF(Old_Persian, "Xpeo")
151 | DEF(Old_Sogdian, "Sogo")
152 | DEF(Old_South_Arabian, "Sarb")
153 | DEF(Old_Turkic, "Orkh")
154 | DEF(Oriya, "Orya")
155 | DEF(Osage, "Osge")
156 | DEF(Osmanya, "Osma")
157 | DEF(Pahawh_Hmong, "Hmng")
158 | DEF(Palmyrene, "Palm")
159 | DEF(Pau_Cin_Hau, "Pauc")
160 | DEF(Phags_Pa, "Phag")
161 | DEF(Phoenician, "Phnx")
162 | DEF(Psalter_Pahlavi, "Phlp")
163 | DEF(Rejang, "Rjng")
164 | DEF(Runic, "Runr")
165 | DEF(Samaritan, "Samr")
166 | DEF(Saurashtra, "Saur")
167 | DEF(Sharada, "Shrd")
168 | DEF(Shavian, "Shaw")
169 | DEF(Siddham, "Sidd")
170 | DEF(SignWriting, "Sgnw")
171 | DEF(Sinhala, "Sinh")
172 | DEF(Sogdian, "Sogd")
173 | DEF(Sora_Sompeng, "Sora")
174 | DEF(Soyombo, "Soyo")
175 | DEF(Sundanese, "Sund")
176 | DEF(Syloti_Nagri, "Sylo")
177 | DEF(Syriac, "Syrc")
178 | DEF(Tagalog, "Tglg")
179 | DEF(Tagbanwa, "Tagb")
180 | DEF(Tai_Le, "Tale")
181 | DEF(Tai_Tham, "Lana")
182 | DEF(Tai_Viet, "Tavt")
183 | DEF(Takri, "Takr")
184 | DEF(Tamil, "Taml")
185 | DEF(Tangut, "Tang")
186 | DEF(Telugu, "Telu")
187 | DEF(Thaana, "Thaa")
188 | DEF(Thai, "Thai")
189 | DEF(Tibetan, "Tibt")
190 | DEF(Tifinagh, "Tfng")
191 | DEF(Tirhuta, "Tirh")
192 | DEF(Ugaritic, "Ugar")
193 | DEF(Vai, "Vaii")
194 | DEF(Wancho, "Wcho")
195 | DEF(Warang_Citi, "Wara")
196 | DEF(Yi, "Yiii")
197 | DEF(Zanabazar_Square, "Zanb")
198 | #endif
199 |
200 | #ifdef UNICODE_PROP_LIST
201 | /* Prop list not exported to regexp */
202 | DEF(Hyphen, "")
203 | DEF(Other_Math, "")
204 | DEF(Other_Alphabetic, "")
205 | DEF(Other_Lowercase, "")
206 | DEF(Other_Uppercase, "")
207 | DEF(Other_Grapheme_Extend, "")
208 | DEF(Other_Default_Ignorable_Code_Point, "")
209 | DEF(Other_ID_Start, "")
210 | DEF(Other_ID_Continue, "")
211 | DEF(Prepended_Concatenation_Mark, "")
212 | /* additional computed properties for smaller tables */
213 | DEF(ID_Continue1, "")
214 | DEF(XID_Start1, "")
215 | DEF(XID_Continue1, "")
216 | DEF(Changes_When_Titlecased1, "")
217 | DEF(Changes_When_Casefolded1, "")
218 | DEF(Changes_When_NFKC_Casefolded1, "")
219 |
220 | /* Prop list exported to JS */
221 | DEF(ASCII_Hex_Digit, "AHex")
222 | DEF(Bidi_Control, "Bidi_C")
223 | DEF(Dash, "")
224 | DEF(Deprecated, "Dep")
225 | DEF(Diacritic, "Dia")
226 | DEF(Extender, "Ext")
227 | DEF(Hex_Digit, "Hex")
228 | DEF(IDS_Binary_Operator, "IDSB")
229 | DEF(IDS_Trinary_Operator, "IDST")
230 | DEF(Ideographic, "Ideo")
231 | DEF(Join_Control, "Join_C")
232 | DEF(Logical_Order_Exception, "LOE")
233 | DEF(Noncharacter_Code_Point, "NChar")
234 | DEF(Pattern_Syntax, "Pat_Syn")
235 | DEF(Pattern_White_Space, "Pat_WS")
236 | DEF(Quotation_Mark, "QMark")
237 | DEF(Radical, "")
238 | DEF(Regional_Indicator, "RI")
239 | DEF(Sentence_Terminal, "STerm")
240 | DEF(Soft_Dotted, "SD")
241 | DEF(Terminal_Punctuation, "Term")
242 | DEF(Unified_Ideograph, "UIdeo")
243 | DEF(Variation_Selector, "VS")
244 | DEF(White_Space, "space")
245 | DEF(Bidi_Mirrored, "Bidi_M")
246 | DEF(Emoji, "")
247 | DEF(Emoji_Component, "")
248 | DEF(Emoji_Modifier, "")
249 | DEF(Emoji_Modifier_Base, "")
250 | DEF(Emoji_Presentation, "")
251 | DEF(Extended_Pictographic, "")
252 | DEF(Default_Ignorable_Code_Point, "DI")
253 | DEF(ID_Start, "IDS")
254 | DEF(Case_Ignorable, "CI")
255 |
256 | /* other binary properties */
257 | DEF(ASCII,"")
258 | DEF(Alphabetic, "Alpha")
259 | DEF(Any, "")
260 | DEF(Assigned,"")
261 | DEF(Cased, "")
262 | DEF(Changes_When_Casefolded, "CWCF")
263 | DEF(Changes_When_Casemapped, "CWCM")
264 | DEF(Changes_When_Lowercased, "CWL")
265 | DEF(Changes_When_NFKC_Casefolded, "CWKCF")
266 | DEF(Changes_When_Titlecased, "CWT")
267 | DEF(Changes_When_Uppercased, "CWU")
268 | DEF(Grapheme_Base, "Gr_Base")
269 | DEF(Grapheme_Extend, "Gr_Ext")
270 | DEF(ID_Continue, "IDC")
271 | DEF(Lowercase, "Lower")
272 | DEF(Math, "")
273 | DEF(Uppercase, "Upper")
274 | DEF(XID_Continue, "XIDC")
275 | DEF(XID_Start, "XIDS")
276 |
277 | /* internal tables with index */
278 | DEF(Cased1, "")
279 |
280 | #endif
281 |
--------------------------------------------------------------------------------