├── .gitmodules
├── quickjs
├── test262o_errors.txt
├── VERSION
├── examples
│ ├── hello.js
│ ├── hello_module.js
│ ├── test_fib.js
│ ├── fib_module.js
│ ├── test_point.js
│ ├── pi_bigfloat.js
│ ├── pi_bigdecimal.js
│ ├── fib.c
│ ├── pi_bigint.js
│ └── point.c
├── readme.txt
├── unicode_download.sh
├── tests
│ ├── test_worker_module.js
│ ├── test_worker.js
│ ├── test262.patch
│ ├── bjson.c
│ ├── test_closure.js
│ ├── test_op_overloading.js
│ ├── test_bjson.js
│ ├── test_qjscalc.js
│ ├── test_std.js
│ ├── test_loop.js
│ ├── test_bignum.js
│ └── test_language.js
├── LICENSE
├── libregexp-opcode.h
├── quickjs-libc.h
├── TODO
├── libregexp.h
├── list.h
├── release.sh
├── libunicode.h
├── Changelog
├── test262.conf
├── test262_errors.txt
├── unicode_gen_def.h
├── cutils.h
├── quickjs-atom.h
└── Makefile
├── .gitignore
├── client.js
├── .editorconfig
├── server.js
├── index.html
├── Makefile
├── README.md
├── CMakeLists.txt
├── app.js
├── style.css
├── htm.js
├── CMakeLists.quickjs.txt
├── preact-render-to-string.js
├── tiny.c
├── htm.c
└── preact.js
/.gitmodules:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/quickjs/test262o_errors.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .cache
2 | build
3 |
--------------------------------------------------------------------------------
/quickjs/VERSION:
--------------------------------------------------------------------------------
1 | 2021-03-27
2 |
--------------------------------------------------------------------------------
/quickjs/examples/hello.js:
--------------------------------------------------------------------------------
1 | console.log("Hello World");
2 |
--------------------------------------------------------------------------------
/quickjs/readme.txt:
--------------------------------------------------------------------------------
1 | The main documentation is in doc/quickjs.pdf or doc/quickjs.html.
2 |
--------------------------------------------------------------------------------
/quickjs/examples/hello_module.js:
--------------------------------------------------------------------------------
1 | /* example of JS module */
2 |
3 | import { fib } from "./fib_module.js";
4 |
5 | console.log("Hello World");
6 | console.log("fib(10)=", fib(10));
7 |
--------------------------------------------------------------------------------
/quickjs/examples/test_fib.js:
--------------------------------------------------------------------------------
1 | /* example of JS module importing a C module */
2 |
3 | import { fib } from "./fib.so";
4 |
5 | console.log("Hello World");
6 | console.log("fib(10)=", fib(10));
7 |
--------------------------------------------------------------------------------
/client.js:
--------------------------------------------------------------------------------
1 | import App from "./app.js"
2 | import {h, hydrate} from "./preact.js"
3 | import htm from './htm.js'
4 |
5 | const html = htm.bind(h);
6 | hydrate(html`<${App} page="All" />`, document.body);
--------------------------------------------------------------------------------
/quickjs/examples/fib_module.js:
--------------------------------------------------------------------------------
1 | /* fib module */
2 | export function fib(n)
3 | {
4 | if (n <= 0)
5 | return 0;
6 | else if (n == 1)
7 | return 1;
8 | else
9 | return fib(n - 1) + fib(n - 2);
10 | }
11 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # EditorConfig is awesome: https://EditorConfig.org
2 |
3 | # top-most EditorConfig file
4 | root = true
5 |
6 | [*]
7 | indent_style = space
8 | indent_size = 4
9 | end_of_line = lf
10 | charset = utf-8
11 | trim_trailing_whitespace = false
12 | insert_final_newline = false
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | import * as std from 'std'
2 | import App from 'app.js'
3 | import {h} from 'preact.js'
4 | import htm from 'htm.js'
5 | import preactRenderToString from 'preact-render-to-string.js'
6 |
7 | const html = htm.bind(h);
8 |
9 | std.out.puts(preactRenderToString(html`<${App} page="All" />`))
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Preact
7 |
8 |
9 | PLACE_HOLDER
10 |
11 |
12 |
--------------------------------------------------------------------------------
/quickjs/unicode_download.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | set -e
3 |
4 | url="ftp://ftp.unicode.org/Public/13.0.0/ucd"
5 | emoji_url="${url}/emoji/emoji-data.txt"
6 |
7 | files="CaseFolding.txt DerivedNormalizationProps.txt PropList.txt \
8 | SpecialCasing.txt CompositionExclusions.txt ScriptExtensions.txt \
9 | UnicodeData.txt DerivedCoreProperties.txt NormalizationTest.txt Scripts.txt \
10 | PropertyValueAliases.txt"
11 |
12 | mkdir -p unicode
13 |
14 | #for f in $files; do
15 | # g="${url}/${f}"
16 | # wget $g -O unicode/$f
17 | #done
18 |
19 | wget $emoji_url -O unicode/emoji-data.txt
20 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | BUILD_DIR=build
2 | BUILDTYPE?=MinSizeRel
3 |
4 | all: build
5 |
6 | build:
7 | @mkdir -p $(BUILD_DIR)
8 | cd $(BUILD_DIR); cmake ../ -DCMAKE_BUILD_TYPE=$(BUILDTYPE)
9 | $(MAKE) -C $(BUILD_DIR) -j4
10 |
11 | install:
12 | @$(MAKE) -C $(BUILD_DIR) install
13 |
14 | clean:
15 | @$(MAKE) -C $(BUILD_DIR) clean
16 |
17 | distclean:
18 | @rm -rf $(BUILD_DIR)
19 |
20 | build/qjsc:
21 | $(MAKE) -C $(BUILD_DIR) qjsc -j4
22 |
23 | gen: build/qjsc
24 | $(BUILD_DIR)/qjsc -c -m -o preact.c -N preact preact.js
25 | $(BUILD_DIR)/qjsc -c -m -o htm.c -N htm htm.js
26 |
27 | .PHONY: all build install clean distclean gen
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Quick-Preact-SSR
2 | Inspired By https://github.com/saghul/njk. Fast Preact SSR.
3 |
4 | ### Features
5 | - low overhead and very small (use quickjs)
6 | - pre-compile dependencies(include preact and htm, and also other components if we want) to bytecode, fast in ssr
7 | - share code with client, no redundancy
8 |
9 | ### Get Started
10 | ```bash
11 | make
12 | # qpreact
13 | ./build/qpreact-linux-x86_64 5000 server.js
14 | ```
15 | Then, visit http://127.0.0.1:5000/, you can find the preact todo mvc in ssr.
16 |
17 | ## Others
18 | I change `quickjs` a little bit. So it's in here rather than submodule.
19 |
--------------------------------------------------------------------------------
/quickjs/tests/test_worker_module.js:
--------------------------------------------------------------------------------
1 | /* Worker code for test_worker.js */
2 | import * as std from "std";
3 | import * as os from "os";
4 |
5 | var parent = os.Worker.parent;
6 |
7 | function handle_msg(e) {
8 | var ev = e.data;
9 | // print("child_recv", JSON.stringify(ev));
10 | switch(ev.type) {
11 | case "abort":
12 | parent.postMessage({ type: "done" });
13 | break;
14 | case "sab":
15 | /* modify the SharedArrayBuffer */
16 | ev.buf[2] = 10;
17 | parent.postMessage({ type: "sab_done", buf: ev.buf });
18 | break;
19 | }
20 | }
21 |
22 | function worker_main() {
23 | var i;
24 |
25 | parent.onmessage = handle_msg;
26 | for(i = 0; i < 10; i++) {
27 | parent.postMessage({ type: "num", num: i });
28 | }
29 | }
30 |
31 | worker_main();
32 |
--------------------------------------------------------------------------------
/quickjs/examples/test_point.js:
--------------------------------------------------------------------------------
1 | /* example of JS module importing a C module */
2 | import { Point } from "./point.so";
3 |
4 | function assert(b, str)
5 | {
6 | if (b) {
7 | return;
8 | } else {
9 | throw Error("assertion failed: " + str);
10 | }
11 | }
12 |
13 | class ColorPoint extends Point {
14 | constructor(x, y, color) {
15 | super(x, y);
16 | this.color = color;
17 | }
18 | get_color() {
19 | return this.color;
20 | }
21 | };
22 |
23 | function main()
24 | {
25 | var pt, pt2;
26 |
27 | pt = new Point(2, 3);
28 | assert(pt.x === 2);
29 | assert(pt.y === 3);
30 | pt.x = 4;
31 | assert(pt.x === 4);
32 | assert(pt.norm() == 5);
33 |
34 | pt2 = new ColorPoint(2, 3, 0xffffff);
35 | assert(pt2.x === 2);
36 | assert(pt2.color === 0xffffff);
37 | assert(pt2.get_color() === 0xffffff);
38 | }
39 |
40 | main();
41 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.4)
2 |
3 | project(qpreact LANGUAGES C)
4 |
5 | include(GNUInstallDirs)
6 |
7 | if (NOT CMAKE_BUILD_TYPE)
8 | message(STATUS "No build type selected, default to Release")
9 | set(CMAKE_BUILD_TYPE "Release")
10 | endif()
11 | message(STATUS "Building in ${CMAKE_BUILD_TYPE} mode")
12 | message(STATUS "Building with ${CMAKE_C_COMPILER_ID} ${CMAKE_C_COMPILER_VERSION} on ${CMAKE_SYSTEM}")
13 |
14 | include(${CMAKE_SOURCE_DIR}/CMakeLists.quickjs.txt)
15 |
16 | add_executable(qpreact
17 | quickjs/quickjs-libc.c
18 | tiny.c
19 | preact.c
20 | htm.c
21 | )
22 |
23 | set_target_properties(qpreact PROPERTIES
24 | C_STANDARD 11
25 | C_STANDARD_REQUIRED ON
26 | OUTPUT_NAME qpreact-$-$
27 | )
28 |
29 | target_compile_definitions(qpreact PRIVATE
30 | _GNU_SOURCE
31 | )
32 |
33 | target_link_libraries(qpreact qjs m pthread dl)
34 |
--------------------------------------------------------------------------------
/app.js:
--------------------------------------------------------------------------------
1 | import htm from './htm.js'
2 | import * as preact from './preact.js'
3 |
4 | const {Component, h, hydrate} = preact
5 | // Create your app
6 | const html = htm.bind(preact.h);
7 |
8 | class App extends Component {
9 | addTodo() {
10 | const { todos = [] } = this.state;
11 | this.setState({ todos: todos.concat(`Item ${todos.length}`) });
12 | }
13 | render({ page }, { todos = [] }) {
14 | return html`
15 |
16 | <${Header} name="ToDo's (${page})" />
17 |
18 | ${todos.map(todo => html`
19 | - ${todo}
20 | `)}
21 |
22 |
23 | <${Footer}>footer content here/>
24 |
25 | `;
26 | }
27 | }
28 |
29 | const Header = ({ name }) => html`${name} List
`
30 |
31 | const Footer = props => html``
32 |
33 | export default App
--------------------------------------------------------------------------------
/quickjs/LICENSE:
--------------------------------------------------------------------------------
1 | QuickJS Javascript Engine
2 |
3 | Copyright (c) 2017-2021 Fabrice Bellard
4 | Copyright (c) 2017-2021 Charlie Gordon
5 |
6 | Permission is hereby granted, free of charge, to any person obtaining a copy
7 | of this software and associated documentation files (the "Software"), to deal
8 | in the Software without restriction, including without limitation the rights
9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | copies of the Software, and to permit persons to whom the Software is
11 | furnished to do so, subject to the following conditions:
12 |
13 | The above copyright notice and this permission notice shall be included in
14 | all copies or substantial portions of the Software.
15 |
16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0;
3 | padding: 0;
4 | font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
5 | font-size: 16px;
6 | line-height: 1.5;
7 | }
8 |
9 | h1 {
10 | text-align: center;
11 | }
12 |
13 | button {
14 | display: block;
15 | margin: auto;
16 | padding: 0.5em 3em;
17 | border: 3px solid rgb(24, 24, 24);
18 | box-sizing: border-box;
19 | text-decoration: none;
20 | text-transform: uppercase;
21 | font-weight:400;
22 | color:rgb(24, 24, 24);
23 | text-align:center;
24 | transition: all 0.15s;
25 | }
26 | button:hover{
27 | color:rgb(180, 180, 180);
28 | border-color: rgb(180, 180, 180);;
29 | }
30 |
31 | li {
32 | height: 50px;
33 | border: 0px solid rgba(123, 123, 123, 0.498039);
34 | border-radius: 4px;
35 | color: rgb(153, 153, 153);
36 | line-height: 90px;
37 | padding-left: 32px;
38 | font-size: 24px;
39 | display: flex;
40 | align-items: center;
41 | font-weight: 400;
42 | background-color: rgb(255, 255, 255);
43 | list-style: none;
44 | box-shadow: rgba(0,0,0,0.2) 0px 1px 2px 0px;
45 | margin-bottom: 20px;
46 | width: 90%;
47 | }
48 |
49 | footer {
50 | position: absolute;
51 | bottom: 0;
52 | padding: 20px 0;
53 | text-align: center;
54 | background: rgb(24, 24, 24);
55 | color: #fff;
56 | width: 100%;
57 | }
--------------------------------------------------------------------------------
/htm.js:
--------------------------------------------------------------------------------
1 | var n = function (t, s, r, e) {var u;s[0] = 0;for (var h = 1; h < s.length; h++) {var p = s[h++],a = s[h] ? (s[0] |= p ? 1 : 2, r[s[h++]]) : s[++h];3 === p ? e[0] = a : 4 === p ? e[1] = Object.assign(e[1] || {}, a) : 5 === p ? (e[1] = e[1] || {})[s[++h]] = a : 6 === p ? e[1][s[++h]] += a + "" : p ? (u = t.apply(a, n(t, a, r, ["", null])), e.push(u), a[0] ? s[0] |= 2 : (s[h - 2] = 0, s[h] = u)) : e.push(a);}return e;},t = new Map();export default function (s) {var r = t.get(this);return r || (r = new Map(), t.set(this, r)), (r = n(this, r.get(s) || (r.set(s, r = function (n) {for (var t, s, r = 1, e = "", u = "", h = [0], p = function (n) {1 === r && (n || (e = e.replace(/^\s*\n\s*|\s*\n\s*$/g, ""))) ? h.push(0, n, e) : 3 === r && (n || e) ? (h.push(3, n, e), r = 2) : 2 === r && "..." === e && n ? h.push(4, n, 0) : 2 === r && e && !n ? h.push(5, 0, !0, e) : r >= 5 && ((e || !n && 5 === r) && (h.push(r, 0, e, s), r = 6), n && (h.push(r, n, 0, s), r = 6)), e = "";}, a = 0; a < n.length; a++) {a && (1 === r && p(), p(a));for (var l = 0; l < n[a].length; l++) t = n[a][l], 1 === r ? "<" === t ? (p(), h = [h], r = 3) : e += t : 4 === r ? "--" === e && ">" === t ? (r = 1, e = "") : e = t + e[0] : u ? t === u ? u = "" : e += t : '"' === t || "'" === t ? u = t : ">" === t ? (p(), r = 1) : r && ("=" === t ? (r = 5, s = e, e = "") : "/" === t && (r < 5 || ">" === n[a][l + 1]) ? (p(), 3 === r && (h = h[0]), r = h, (h = h[0]).push(2, 0, r), r = 0) : " " === t || "\t" === t || "\n" === t || "\r" === t ? (p(), r = 2) : e += t), 3 === r && "!--" === e && (r = 4, h = h[0]);}return p(), h;}(s)), r), arguments, [])).length > 1 ? r : r[0];}
--------------------------------------------------------------------------------
/CMakeLists.quickjs.txt:
--------------------------------------------------------------------------------
1 | # QuickJS
2 |
3 | set(qjs_cflags -Wall)
4 | if(CMAKE_C_COMPILER_ID MATCHES "AppleClang|Clang")
5 | list(APPEND qjs_cflags
6 | -Wextra
7 | -Wno-sign-compare
8 | -Wno-missing-field-initializers
9 | -Wno-unused-parameter
10 | -Wno-unused-variable
11 | -funsigned-char)
12 | else()
13 | list(APPEND qjs_cflags
14 | -Wno-array-bounds
15 | -Wno-unused-variable
16 | -Wno-unused-but-set-variable)
17 | endif()
18 |
19 | file(STRINGS "quickjs/VERSION" QJS_VERSION_STR)
20 |
21 | add_library(qjs STATIC
22 | quickjs/cutils.c
23 | quickjs/libregexp.c
24 | quickjs/libunicode.c
25 | quickjs/quickjs.c
26 | )
27 | set_target_properties(qjs PROPERTIES
28 | C_STANDARD 11
29 | C_STANDARD_REQUIRED ON
30 | )
31 | target_compile_options(qjs PRIVATE ${qjs_cflags})
32 | target_compile_definitions(qjs PUBLIC
33 | QJS_VERSION_STR="${QJS_VERSION_STR}"
34 | )
35 | target_compile_definitions(qjs PRIVATE
36 | _GNU_SOURCE
37 | CONFIG_VERSION="${QJS_VERSION_STR}"
38 | )
39 | if (CMAKE_BUILD_TYPE MATCHES Debug)
40 | target_compile_definitions(qjs PRIVATE
41 | DUMP_LEAKS
42 | )
43 | endif()
44 |
45 | target_include_directories(qjs PUBLIC quickjs)
46 | if ("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU")
47 | target_link_libraries(qjs atomic)
48 | endif()
49 |
50 | add_executable(qjsc
51 | quickjs/qjsc.c
52 | quickjs/quickjs-libc.c
53 | )
54 |
55 | set_target_properties(qjsc PROPERTIES
56 | C_STANDARD 11
57 | C_STANDARD_REQUIRED ON
58 | EXCLUDE_FROM_ALL TRUE
59 | )
60 |
61 | target_compile_definitions(qjsc PRIVATE
62 | _GNU_SOURCE
63 | CONFIG_VERSION="${QJS_VERSION_STR}"
64 | )
65 |
66 | target_link_libraries(qjsc qjs m pthread dl)
--------------------------------------------------------------------------------
/quickjs/tests/test_worker.js:
--------------------------------------------------------------------------------
1 | /* os.Worker API test */
2 | import * as std from "std";
3 | import * as os from "os";
4 |
5 | function assert(actual, expected, message) {
6 | if (arguments.length == 1)
7 | expected = true;
8 |
9 | if (actual === expected)
10 | return;
11 |
12 | if (actual !== null && expected !== null
13 | && typeof actual == 'object' && typeof expected == 'object'
14 | && actual.toString() === expected.toString())
15 | return;
16 |
17 | throw Error("assertion failed: got |" + actual + "|" +
18 | ", expected |" + expected + "|" +
19 | (message ? " (" + message + ")" : ""));
20 | }
21 |
22 | var worker;
23 |
24 | function test_worker()
25 | {
26 | var counter;
27 |
28 | worker = new os.Worker("./test_worker_module.js");
29 |
30 | counter = 0;
31 | worker.onmessage = function (e) {
32 | var ev = e.data;
33 | // print("recv", JSON.stringify(ev));
34 | switch(ev.type) {
35 | case "num":
36 | assert(ev.num, counter);
37 | counter++;
38 | if (counter == 10) {
39 | /* test SharedArrayBuffer modification */
40 | let sab = new SharedArrayBuffer(10);
41 | let buf = new Uint8Array(sab);
42 | worker.postMessage({ type: "sab", buf: buf });
43 | }
44 | break;
45 | case "sab_done":
46 | {
47 | let buf = ev.buf;
48 | /* check that the SharedArrayBuffer was modified */
49 | assert(buf[2], 10);
50 | worker.postMessage({ type: "abort" });
51 | }
52 | break;
53 | case "done":
54 | /* terminate */
55 | worker.onmessage = null;
56 | break;
57 | }
58 | };
59 | }
60 |
61 |
62 | test_worker();
63 |
--------------------------------------------------------------------------------
/quickjs/examples/pi_bigfloat.js:
--------------------------------------------------------------------------------
1 | /*
2 | * PI computation in Javascript using the QuickJS bigfloat type
3 | * (binary floating point)
4 | */
5 | "use strict";
6 |
7 | /* compute PI with a precision of 'prec' bits */
8 | function calc_pi() {
9 | const CHUD_A = 13591409n;
10 | const CHUD_B = 545140134n;
11 | const CHUD_C = 640320n;
12 | const CHUD_C3 = 10939058860032000n; /* C^3/24 */
13 | const CHUD_BITS_PER_TERM = 47.11041313821584202247; /* log2(C/12)*3 */
14 |
15 | /* return [P, Q, G] */
16 | function chud_bs(a, b, need_G) {
17 | var c, P, Q, G, P1, Q1, G1, P2, Q2, G2;
18 | if (a == (b - 1n)) {
19 | G = (2n * b - 1n) * (6n * b - 1n) * (6n * b - 5n);
20 | P = BigFloat(G * (CHUD_B * b + CHUD_A));
21 | if (b & 1n)
22 | P = -P;
23 | G = BigFloat(G);
24 | Q = BigFloat(b * b * b * CHUD_C3);
25 | } else {
26 | c = (a + b) >> 1n;
27 | [P1, Q1, G1] = chud_bs(a, c, true);
28 | [P2, Q2, G2] = chud_bs(c, b, need_G);
29 | P = P1 * Q2 + P2 * G1;
30 | Q = Q1 * Q2;
31 | if (need_G)
32 | G = G1 * G2;
33 | else
34 | G = 0l;
35 | }
36 | return [P, Q, G];
37 | }
38 |
39 | var n, P, Q, G;
40 | /* number of serie terms */
41 | n = BigInt(Math.ceil(BigFloatEnv.prec / CHUD_BITS_PER_TERM)) + 10n;
42 | [P, Q, G] = chud_bs(0n, n, false);
43 | Q = Q / (P + Q * BigFloat(CHUD_A));
44 | G = BigFloat((CHUD_C / 12n)) * BigFloat.sqrt(BigFloat(CHUD_C));
45 | return Q * G;
46 | }
47 |
48 | (function() {
49 | var r, n_digits, n_bits;
50 | if (typeof scriptArgs != "undefined") {
51 | if (scriptArgs.length < 2) {
52 | print("usage: pi n_digits");
53 | return;
54 | }
55 | n_digits = scriptArgs[1];
56 | } else {
57 | n_digits = 1000;
58 | }
59 | n_bits = Math.ceil(n_digits * Math.log2(10));
60 | /* we add more bits to reduce the probability of bad rounding for
61 | the last digits */
62 | BigFloatEnv.setPrec( () => {
63 | r = calc_pi();
64 | print(r.toFixed(n_digits, BigFloatEnv.RNDZ));
65 | }, n_bits + 32);
66 | })();
67 |
--------------------------------------------------------------------------------
/quickjs/examples/pi_bigdecimal.js:
--------------------------------------------------------------------------------
1 | /*
2 | * PI computation in Javascript using the QuickJS bigdecimal type
3 | * (decimal floating point)
4 | */
5 | "use strict";
6 |
7 | /* compute PI with a precision of 'prec' digits */
8 | function calc_pi(prec) {
9 | const CHUD_A = 13591409m;
10 | const CHUD_B = 545140134m;
11 | const CHUD_C = 640320m;
12 | const CHUD_C3 = 10939058860032000m; /* C^3/24 */
13 | const CHUD_DIGITS_PER_TERM = 14.18164746272548; /* log10(C/12)*3 */
14 |
15 | /* return [P, Q, G] */
16 | function chud_bs(a, b, need_G) {
17 | var c, P, Q, G, P1, Q1, G1, P2, Q2, G2, b1;
18 | if (a == (b - 1n)) {
19 | b1 = BigDecimal(b);
20 | G = (2m * b1 - 1m) * (6m * b1 - 1m) * (6m * b1 - 5m);
21 | P = G * (CHUD_B * b1 + CHUD_A);
22 | if (b & 1n)
23 | P = -P;
24 | G = G;
25 | Q = b1 * b1 * b1 * CHUD_C3;
26 | } else {
27 | c = (a + b) >> 1n;
28 | [P1, Q1, G1] = chud_bs(a, c, true);
29 | [P2, Q2, G2] = chud_bs(c, b, need_G);
30 | P = P1 * Q2 + P2 * G1;
31 | Q = Q1 * Q2;
32 | if (need_G)
33 | G = G1 * G2;
34 | else
35 | G = 0m;
36 | }
37 | return [P, Q, G];
38 | }
39 |
40 | var n, P, Q, G;
41 | /* number of serie terms */
42 | n = BigInt(Math.ceil(prec / CHUD_DIGITS_PER_TERM)) + 10n;
43 | [P, Q, G] = chud_bs(0n, n, false);
44 | Q = BigDecimal.div(Q, (P + Q * CHUD_A),
45 | { roundingMode: "half-even",
46 | maximumSignificantDigits: prec });
47 | G = (CHUD_C / 12m) * BigDecimal.sqrt(CHUD_C,
48 | { roundingMode: "half-even",
49 | maximumSignificantDigits: prec });
50 | return Q * G;
51 | }
52 |
53 | (function() {
54 | var r, n_digits, n_bits;
55 | if (typeof scriptArgs != "undefined") {
56 | if (scriptArgs.length < 2) {
57 | print("usage: pi n_digits");
58 | return;
59 | }
60 | n_digits = scriptArgs[1] | 0;
61 | } else {
62 | n_digits = 1000;
63 | }
64 | /* we add more digits to reduce the probability of bad rounding for
65 | the last digits */
66 | r = calc_pi(n_digits + 20);
67 | print(r.toFixed(n_digits, "down"));
68 | })();
69 |
--------------------------------------------------------------------------------
/quickjs/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 |
--------------------------------------------------------------------------------
/quickjs/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 |
--------------------------------------------------------------------------------
/quickjs/examples/fib.c:
--------------------------------------------------------------------------------
1 | /*
2 | * QuickJS: Example of C module
3 | *
4 | * Copyright (c) 2017-2018 Fabrice Bellard
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | #include "../quickjs.h"
25 |
26 | #define countof(x) (sizeof(x) / sizeof((x)[0]))
27 |
28 | static int fib(int n)
29 | {
30 | if (n <= 0)
31 | return 0;
32 | else if (n == 1)
33 | return 1;
34 | else
35 | return fib(n - 1) + fib(n - 2);
36 | }
37 |
38 | static JSValue js_fib(JSContext *ctx, JSValueConst this_val,
39 | int argc, JSValueConst *argv)
40 | {
41 | int n, res;
42 | if (JS_ToInt32(ctx, &n, argv[0]))
43 | return JS_EXCEPTION;
44 | res = fib(n);
45 | return JS_NewInt32(ctx, res);
46 | }
47 |
48 | static const JSCFunctionListEntry js_fib_funcs[] = {
49 | JS_CFUNC_DEF("fib", 1, js_fib ),
50 | };
51 |
52 | static int js_fib_init(JSContext *ctx, JSModuleDef *m)
53 | {
54 | return JS_SetModuleExportList(ctx, m, js_fib_funcs,
55 | countof(js_fib_funcs));
56 | }
57 |
58 | #ifdef JS_SHARED_LIBRARY
59 | #define JS_INIT_MODULE js_init_module
60 | #else
61 | #define JS_INIT_MODULE js_init_module_fib
62 | #endif
63 |
64 | JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name)
65 | {
66 | JSModuleDef *m;
67 | m = JS_NewCModule(ctx, module_name, js_fib_init);
68 | if (!m)
69 | return NULL;
70 | JS_AddModuleExportList(ctx, m, js_fib_funcs, countof(js_fib_funcs));
71 | return m;
72 | }
73 |
--------------------------------------------------------------------------------
/quickjs/quickjs-libc.h:
--------------------------------------------------------------------------------
1 | /*
2 | * QuickJS C library
3 | *
4 | * Copyright (c) 2017-2018 Fabrice Bellard
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | #ifndef QUICKJS_LIBC_H
25 | #define QUICKJS_LIBC_H
26 |
27 | #include
28 | #include
29 |
30 | #include "quickjs.h"
31 |
32 | #ifdef __cplusplus
33 | extern "C" {
34 | #endif
35 |
36 | JSModuleDef *js_init_module_std(JSContext *ctx, const char *module_name);
37 | JSModuleDef *js_init_module_os(JSContext *ctx, const char *module_name);
38 | void js_std_add_helpers(JSContext *ctx, int argc, char **argv);
39 | void js_std_loop(JSContext *ctx);
40 | void js_std_init_handlers(JSRuntime *rt);
41 | void js_std_free_handlers(JSRuntime *rt);
42 | void js_std_dump_error(JSContext *ctx);
43 | uint8_t *js_load_file(JSContext *ctx, size_t *pbuf_len, const char *filename);
44 | int js_module_set_import_meta(JSContext *ctx, JSValueConst func_val,
45 | JS_BOOL use_realpath, JS_BOOL is_main);
46 | JSModuleDef *js_module_loader(JSContext *ctx,
47 | const char *module_name, void *opaque);
48 | void js_std_eval_binary(JSContext *ctx, const uint8_t *buf, size_t buf_len,
49 | int flags);
50 | void js_std_promise_rejection_tracker(JSContext *ctx, JSValueConst promise,
51 | JSValueConst reason,
52 | JS_BOOL is_handled, void *opaque);
53 | void js_std_set_worker_new_context_func(JSContext *(*func)(JSRuntime *rt));
54 |
55 | #ifdef __cplusplus
56 | } /* extern "C" { */
57 | #endif
58 |
59 | #endif /* QUICKJS_LIBC_H */
60 |
--------------------------------------------------------------------------------
/quickjs/TODO:
--------------------------------------------------------------------------------
1 | Bugs:
2 | - modules: better error handling with cyclic module references
3 |
4 | Misc ideas:
5 | - use custom printf to avoid compatibility issues with floating point numbers
6 | - consistent naming for preprocessor defines
7 | - unify coding style and naming conventions
8 | - use names from the ECMA spec in library implementation
9 | - use byte code emitters with typed arguments (for clarity)
10 | - use 2 bytecode DynBufs in JSFunctionDef, one for reading, one for writing
11 | and use the same wrappers in all phases
12 | - use more generic method for line numbers in resolve_variables and resolve_labels
13 | - use custom timezone support to avoid C library compatibility issues
14 |
15 | Memory:
16 | - use memory pools for objects, etc?
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 | - improve JS_ComputeMemoryUsage() with more info
22 |
23 | Built-in standard library:
24 | - BSD sockets
25 | - modules: use realpath in module name normalizer and put it in quickjs-libc
26 | - modules: if no ".", use a well known module loading path ?
27 | - get rid of __loadScript, use more common name
28 |
29 | REPL:
30 | - debugger
31 | - readline: support MS Windows terminal
32 | - readline: handle dynamic terminal resizing
33 | - readline: handle double width unicode characters
34 | - multiline editing
35 | - runtime object and function inspectors
36 | - interactive object browser
37 | - use more generic approach to display evaluation results
38 | - improve directive handling: dispatch, colorize, completion...
39 | - save history
40 | - close all predefined methods in repl.js and jscalc.js
41 |
42 | Optimization ideas:
43 | - 64-bit atoms in 64-bit mode ?
44 | - 64-bit small bigint in 64-bit mode ?
45 | - reuse stack slots for disjoint scopes, if strip
46 | - add heuristic to avoid some cycles in closures
47 | - small String (0-2 charcodes) with immediate storage
48 | - perform static string concatenation at compile time
49 | - optimize string concatenation with ropes or miniropes?
50 | - add implicit numeric strings for Uint32 numbers?
51 | - optimize `s += a + b`, `s += a.b` and similar simple expressions
52 | - ensure string canonical representation and optimise comparisons and hashes?
53 | - remove JSObject.first_weak_ref, use bit+context based hashed array for weak references
54 | - property access optimization on the global object, functions,
55 | prototypes and special non extensible objects.
56 | - create object literals with the correct length by backpatching length argument
57 | - remove redundant set_loc_uninitialized/check_uninitialized opcodes
58 | - peephole optim: push_atom_value, to_propkey -> push_atom_value
59 | - peephole optim: put_loc x, get_loc_check x -> set_loc x
60 | - convert slow array to fast array when all properties != length are numeric
61 | - optimize destructuring assignments for global and local variables
62 | - implement some form of tail-call-optimization
63 | - optimize OP_apply
64 | - optimize f(...b)
65 |
66 | Test262o: 0/11262 errors, 463 excluded
67 | Test262o commit: 7da91bceb9ce7613f87db47ddd1292a2dda58b42 (es5-tests branch)
68 |
69 | Result: 35/75280 errors, 909 excluded, 585 skipped
70 | Test262 commit: 31126581e7290f9233c29cefd93f66c6ac78f1c9
71 |
--------------------------------------------------------------------------------
/quickjs/examples/pi_bigint.js:
--------------------------------------------------------------------------------
1 | /*
2 | * PI computation in Javascript using the BigInt type
3 | */
4 | "use strict";
5 |
6 | /* return floor(log2(a)) for a > 0 and 0 for a = 0 */
7 | function floor_log2(a)
8 | {
9 | var k_max, a1, k, i;
10 | k_max = 0n;
11 | while ((a >> (2n ** k_max)) != 0n) {
12 | k_max++;
13 | }
14 | k = 0n;
15 | a1 = a;
16 | for(i = k_max - 1n; i >= 0n; i--) {
17 | a1 = a >> (2n ** i);
18 | if (a1 != 0n) {
19 | a = a1;
20 | k |= (1n << i);
21 | }
22 | }
23 | return k;
24 | }
25 |
26 | /* return ceil(log2(a)) for a > 0 */
27 | function ceil_log2(a)
28 | {
29 | return floor_log2(a - 1n) + 1n;
30 | }
31 |
32 | /* return floor(sqrt(a)) (not efficient but simple) */
33 | function int_sqrt(a)
34 | {
35 | var l, u, s;
36 | if (a == 0n)
37 | return a;
38 | l = ceil_log2(a);
39 | u = 1n << ((l + 1n) / 2n);
40 | /* u >= floor(sqrt(a)) */
41 | for(;;) {
42 | s = u;
43 | u = ((a / s) + s) / 2n;
44 | if (u >= s)
45 | break;
46 | }
47 | return s;
48 | }
49 |
50 | /* return pi * 2**prec */
51 | function calc_pi(prec) {
52 | const CHUD_A = 13591409n;
53 | const CHUD_B = 545140134n;
54 | const CHUD_C = 640320n;
55 | const CHUD_C3 = 10939058860032000n; /* C^3/24 */
56 | const CHUD_BITS_PER_TERM = 47.11041313821584202247; /* log2(C/12)*3 */
57 |
58 | /* return [P, Q, G] */
59 | function chud_bs(a, b, need_G) {
60 | var c, P, Q, G, P1, Q1, G1, P2, Q2, G2;
61 | if (a == (b - 1n)) {
62 | G = (2n * b - 1n) * (6n * b - 1n) * (6n * b - 5n);
63 | P = G * (CHUD_B * b + CHUD_A);
64 | if (b & 1n)
65 | P = -P;
66 | Q = b * b * b * CHUD_C3;
67 | } else {
68 | c = (a + b) >> 1n;
69 | [P1, Q1, G1] = chud_bs(a, c, true);
70 | [P2, Q2, G2] = chud_bs(c, b, need_G);
71 | P = P1 * Q2 + P2 * G1;
72 | Q = Q1 * Q2;
73 | if (need_G)
74 | G = G1 * G2;
75 | else
76 | G = 0n;
77 | }
78 | return [P, Q, G];
79 | }
80 |
81 | var n, P, Q, G;
82 | /* number of serie terms */
83 | n = BigInt(Math.ceil(Number(prec) / CHUD_BITS_PER_TERM)) + 10n;
84 | [P, Q, G] = chud_bs(0n, n, false);
85 | Q = (CHUD_C / 12n) * (Q << prec) / (P + Q * CHUD_A);
86 | G = int_sqrt(CHUD_C << (2n * prec));
87 | return (Q * G) >> prec;
88 | }
89 |
90 | function main(args) {
91 | var r, n_digits, n_bits, out;
92 | if (args.length < 1) {
93 | print("usage: pi n_digits");
94 | return;
95 | }
96 | n_digits = args[0] | 0;
97 |
98 | /* we add more bits to reduce the probability of bad rounding for
99 | the last digits */
100 | n_bits = BigInt(Math.ceil(n_digits * Math.log2(10))) + 32n;
101 | r = calc_pi(n_bits);
102 | r = ((10n ** BigInt(n_digits)) * r) >> n_bits;
103 | out = r.toString();
104 | print(out[0] + "." + out.slice(1));
105 | }
106 |
107 | var args;
108 | if (typeof scriptArgs != "undefined") {
109 | args = scriptArgs;
110 | args.shift();
111 | } else if (typeof arguments != "undefined") {
112 | args = arguments;
113 | } else {
114 | /* default: 1000 digits */
115 | args=[1000];
116 | }
117 |
118 | main(args);
119 |
--------------------------------------------------------------------------------
/quickjs/tests/bjson.c:
--------------------------------------------------------------------------------
1 | /*
2 | * QuickJS: binary JSON module (test only)
3 | *
4 | * Copyright (c) 2017-2019 Fabrice Bellard
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | #include "../quickjs-libc.h"
25 | #include "../cutils.h"
26 |
27 | static JSValue js_bjson_read(JSContext *ctx, JSValueConst this_val,
28 | int argc, JSValueConst *argv)
29 | {
30 | uint8_t *buf;
31 | uint64_t pos, len;
32 | JSValue obj;
33 | size_t size;
34 | int flags;
35 |
36 | if (JS_ToIndex(ctx, &pos, argv[1]))
37 | return JS_EXCEPTION;
38 | if (JS_ToIndex(ctx, &len, argv[2]))
39 | return JS_EXCEPTION;
40 | buf = JS_GetArrayBuffer(ctx, &size, argv[0]);
41 | if (!buf)
42 | return JS_EXCEPTION;
43 | if (pos + len > size)
44 | return JS_ThrowRangeError(ctx, "array buffer overflow");
45 | flags = 0;
46 | if (JS_ToBool(ctx, argv[3]))
47 | flags |= JS_READ_OBJ_REFERENCE;
48 | obj = JS_ReadObject(ctx, buf + pos, len, flags);
49 | return obj;
50 | }
51 |
52 | static JSValue js_bjson_write(JSContext *ctx, JSValueConst this_val,
53 | int argc, JSValueConst *argv)
54 | {
55 | size_t len;
56 | uint8_t *buf;
57 | JSValue array;
58 | int flags;
59 |
60 | flags = 0;
61 | if (JS_ToBool(ctx, argv[1]))
62 | flags |= JS_WRITE_OBJ_REFERENCE;
63 | buf = JS_WriteObject(ctx, &len, argv[0], flags);
64 | if (!buf)
65 | return JS_EXCEPTION;
66 | array = JS_NewArrayBufferCopy(ctx, buf, len);
67 | js_free(ctx, buf);
68 | return array;
69 | }
70 |
71 | static const JSCFunctionListEntry js_bjson_funcs[] = {
72 | JS_CFUNC_DEF("read", 4, js_bjson_read ),
73 | JS_CFUNC_DEF("write", 2, js_bjson_write ),
74 | };
75 |
76 | static int js_bjson_init(JSContext *ctx, JSModuleDef *m)
77 | {
78 | return JS_SetModuleExportList(ctx, m, js_bjson_funcs,
79 | countof(js_bjson_funcs));
80 | }
81 |
82 | #ifdef JS_SHARED_LIBRARY
83 | #define JS_INIT_MODULE js_init_module
84 | #else
85 | #define JS_INIT_MODULE js_init_module_bjson
86 | #endif
87 |
88 | JSModuleDef *JS_INIT_MODULE(JSContext *ctx, const char *module_name)
89 | {
90 | JSModuleDef *m;
91 | m = JS_NewCModule(ctx, module_name, js_bjson_init);
92 | if (!m)
93 | return NULL;
94 | JS_AddModuleExportList(ctx, m, js_bjson_funcs, countof(js_bjson_funcs));
95 | return m;
96 | }
97 |
--------------------------------------------------------------------------------
/quickjs/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 | const char *lre_get_groupnames(const uint8_t *bc_buf);
48 | int lre_exec(uint8_t **capture,
49 | const uint8_t *bc_buf, const uint8_t *cbuf, int cindex, int clen,
50 | int cbuf_type, void *opaque);
51 |
52 | int lre_parse_escape(const uint8_t **pp, int allow_utf16);
53 | LRE_BOOL lre_is_space(int c);
54 |
55 | /* must be provided by the user */
56 | LRE_BOOL lre_check_stack_overflow(void *opaque, size_t alloca_size);
57 | void *lre_realloc(void *opaque, void *ptr, size_t size);
58 |
59 | /* JS identifier test */
60 | extern uint32_t const lre_id_start_table_ascii[4];
61 | extern uint32_t const lre_id_continue_table_ascii[4];
62 |
63 | static inline int lre_js_is_ident_first(int c)
64 | {
65 | if ((uint32_t)c < 128) {
66 | return (lre_id_start_table_ascii[c >> 5] >> (c & 31)) & 1;
67 | } else {
68 | #ifdef CONFIG_ALL_UNICODE
69 | return lre_is_id_start(c);
70 | #else
71 | return !lre_is_space(c);
72 | #endif
73 | }
74 | }
75 |
76 | static inline int lre_js_is_ident_next(int c)
77 | {
78 | if ((uint32_t)c < 128) {
79 | return (lre_id_continue_table_ascii[c >> 5] >> (c & 31)) & 1;
80 | } else {
81 | /* ZWNJ and ZWJ are accepted in identifiers */
82 | #ifdef CONFIG_ALL_UNICODE
83 | return lre_is_id_continue(c) || c == 0x200C || c == 0x200D;
84 | #else
85 | return !lre_is_space(c) || c == 0x200C || c == 0x200D;
86 | #endif
87 | }
88 | }
89 |
90 | #undef LRE_BOOL
91 |
92 | #endif /* LIBREGEXP_H */
93 |
--------------------------------------------------------------------------------
/quickjs/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 |
--------------------------------------------------------------------------------
/quickjs/release.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | # Release the QuickJS source code
3 |
4 | set -e
5 |
6 | version=`cat VERSION`
7 |
8 | if [ "$1" = "-h" ] ; then
9 | echo "release.sh [release_list]"
10 | echo ""
11 | echo "release_list: extras binary win_binary quickjs"
12 |
13 | exit 1
14 | fi
15 |
16 | release_list="extras binary win_binary quickjs"
17 |
18 | if [ "$1" != "" ] ; then
19 | release_list="$1"
20 | fi
21 |
22 | #################################################"
23 | # extras
24 |
25 | if echo $release_list | grep -w -q extras ; then
26 |
27 | d="quickjs-${version}"
28 | name="quickjs-extras-${version}"
29 | outdir="/tmp/${d}"
30 |
31 | rm -rf $outdir
32 | mkdir -p $outdir $outdir/unicode $outdir/tests
33 |
34 | cp unicode/* $outdir/unicode
35 | cp -a tests/bench-v8 $outdir/tests
36 |
37 | ( cd /tmp && tar Jcvf /tmp/${name}.tar.xz ${d} )
38 |
39 | fi
40 |
41 | #################################################"
42 | # Windows binary release
43 |
44 | if echo $release_list | grep -w -q win_binary ; then
45 |
46 | # win64
47 |
48 | dlldir=/usr/x86_64-w64-mingw32/sys-root/mingw/bin
49 | cross_prefix="x86_64-w64-mingw32-"
50 | d="quickjs-win-x86_64-${version}"
51 | outdir="/tmp/${d}"
52 |
53 | rm -rf $outdir
54 | mkdir -p $outdir
55 |
56 | make CONFIG_WIN32=y qjs.exe
57 | cp qjs.exe $outdir
58 | ${cross_prefix}strip $outdir/qjs.exe
59 | cp $dlldir/libwinpthread-1.dll $outdir
60 |
61 | ( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . )
62 |
63 | make CONFIG_WIN32=y clean
64 |
65 | # win32
66 |
67 | dlldir=/usr/i686-w64-mingw32/sys-root/mingw/bin
68 | cross_prefix="i686-w64-mingw32-"
69 | d="quickjs-win-i686-${version}"
70 | outdir="/tmp/${d}"
71 |
72 | rm -rf $outdir
73 | mkdir -p $outdir
74 |
75 | make clean
76 | make CONFIG_WIN32=y clean
77 |
78 | make CONFIG_WIN32=y CONFIG_M32=y qjs.exe
79 | cp qjs.exe $outdir
80 | ${cross_prefix}strip $outdir/qjs.exe
81 | cp $dlldir/libwinpthread-1.dll $outdir
82 |
83 | ( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . )
84 |
85 | fi
86 |
87 | #################################################"
88 | # Linux binary release
89 |
90 | if echo $release_list | grep -w -q binary ; then
91 |
92 | make clean
93 | make CONFIG_WIN32=y clean
94 | make -j4 qjs run-test262
95 | make -j4 CONFIG_M32=y qjs32 run-test262-32
96 | strip qjs run-test262 qjs32 run-test262-32
97 |
98 | d="quickjs-linux-x86_64-${version}"
99 | outdir="/tmp/${d}"
100 |
101 | rm -rf $outdir
102 | mkdir -p $outdir
103 |
104 | cp qjs run-test262 $outdir
105 |
106 | ( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . )
107 |
108 | d="quickjs-linux-i686-${version}"
109 | outdir="/tmp/${d}"
110 |
111 | rm -rf $outdir
112 | mkdir -p $outdir
113 |
114 | cp qjs32 $outdir/qjs
115 | cp run-test262-32 $outdir/run-test262
116 |
117 | ( cd /tmp/$d && rm -f ../${d}.zip && zip -r ../${d}.zip . )
118 |
119 | fi
120 |
121 | #################################################"
122 | # quickjs
123 |
124 | if echo $release_list | grep -w -q quickjs ; then
125 |
126 | make build_doc
127 |
128 | d="quickjs-${version}"
129 | outdir="/tmp/${d}"
130 |
131 | rm -rf $outdir
132 | mkdir -p $outdir $outdir/doc $outdir/tests $outdir/examples
133 |
134 | cp Makefile VERSION TODO Changelog readme.txt LICENSE \
135 | release.sh unicode_download.sh \
136 | qjs.c qjsc.c qjscalc.js repl.js \
137 | quickjs.c quickjs.h quickjs-atom.h \
138 | quickjs-libc.c quickjs-libc.h quickjs-opcode.h \
139 | cutils.c cutils.h list.h \
140 | libregexp.c libregexp.h libregexp-opcode.h \
141 | libunicode.c libunicode.h libunicode-table.h \
142 | libbf.c libbf.h \
143 | unicode_gen.c unicode_gen_def.h \
144 | run-test262.c test262o.conf test262.conf \
145 | test262o_errors.txt test262_errors.txt \
146 | $outdir
147 |
148 | cp tests/*.js tests/*.patch tests/bjson.c $outdir/tests
149 |
150 | cp examples/*.js examples/*.c $outdir/examples
151 |
152 | cp doc/quickjs.texi doc/quickjs.pdf doc/quickjs.html \
153 | doc/jsbignum.texi doc/jsbignum.html doc/jsbignum.pdf \
154 | $outdir/doc
155 |
156 | ( cd /tmp && tar Jcvf /tmp/${d}.tar.xz ${d} )
157 |
158 | fi
159 |
--------------------------------------------------------------------------------
/quickjs/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 |
--------------------------------------------------------------------------------
/preact-render-to-string.js:
--------------------------------------------------------------------------------
1 | import{options as e,Fragment as t}from"preact.js";var r=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|^--/i,n=/[&<>"]/;function o(e){var t=String(e);return n.test(t)?t.replace(/&/g,"&").replace(//g,">").replace(/"/g,"""):t}var a=function(e,t){return String(e).replace(/(\n+)/g,"$1"+(t||"\t"))},i=function(e,t,r){return String(e).length>(t||40)||!r&&-1!==String(e).indexOf("\n")||-1!==String(e).indexOf("<")},l={};function s(e){var t="";for(var n in e){var o=e[n];null!=o&&""!==o&&(t&&(t+=" "),t+="-"==n[0]?n:l[n]||(l[n]=n.replace(/([A-Z])/g,"-$1").toLowerCase()),t+=": ",t+=o,"number"==typeof o&&!1===r.test(n)&&(t+="px"),t+=";")}return t||void 0}function f(e,t){for(var r in t)e[r]=t[r];return e}function u(e,t){return Array.isArray(t)?t.reduce(u,e):null!=t&&!1!==t&&e.push(t),e}var c={shallow:!0},p=[],_=/^(area|base|br|col|embed|hr|img|input|link|meta|param|source|track|wbr)$/,v=/[\s\n\\/='"\0<>]/,d=function(){};m.render=m;var g=function(e,t){return m(e,t,c)},h=[];function m(t,r,n){r=r||{},n=n||{};var o=e.__s;e.__s=!0;var a=x(t,r,n);return e.__c&&e.__c(t,h),h.length=0,e.__s=o,a}function x(r,n,l,c,g,h){if(null==r||"boolean"==typeof r)return"";if("object"!=typeof r)return o(r);var m=l.pretty,y=m&&"string"==typeof m?m:"\t";if(Array.isArray(r)){for(var b="",S=0;S0&&(b+="\n"),b+=x(r[S],n,l,c,g,h);return b}var w,k=r.type,O=r.props,C=!1;if("function"==typeof k){if(C=!0,!l.shallow||!c&&!1!==l.renderRootComponent){if(k===t){var A=[];return u(A,r.props.children),x(A,n,l,!1!==l.shallowHighOrder,g,h)}var H,j=r.__c={__v:r,context:n,props:r.props,setState:d,forceUpdate:d,__h:[]};if(e.__b&&e.__b(r),e.__r&&e.__r(r),k.prototype&&"function"==typeof k.prototype.render){var F=k.contextType,M=F&&n[F.__c],T=null!=F?M?M.props.value:F.__:n;(j=r.__c=new k(O,T)).__v=r,j._dirty=j.__d=!0,j.props=O,null==j.state&&(j.state={}),null==j._nextState&&null==j.__s&&(j._nextState=j.__s=j.state),j.context=T,k.getDerivedStateFromProps?j.state=f(f({},j.state),k.getDerivedStateFromProps(j.props,j.state)):j.componentWillMount&&(j.componentWillMount(),j.state=j._nextState!==j.state?j._nextState:j.__s!==j.state?j.__s:j.state),H=j.render(j.props,j.state,j.context)}else{var $=k.contextType,L=$&&n[$.__c];H=k.call(r.__c,O,null!=$?L?L.props.value:$.__:n)}return j.getChildContext&&(n=f(f({},n),j.getChildContext())),e.diffed&&e.diffed(r),x(H,n,l,!1!==l.shallowHighOrder,g,h)}k=(w=k).displayName||w!==Function&&w.name||function(e){var t=(Function.prototype.toString.call(e).match(/^\s*function\s+([^( ]+)/)||"")[1];if(!t){for(var r=-1,n=p.length;n--;)if(p[n]===e){r=n;break}r<0&&(r=p.push(e)-1),t="UnnamedComponent"+r}return t}(w)}var E,D,N="<"+k;if(O){var P=Object.keys(O);l&&!0===l.sortAttributes&&P.sort();for(var R=0;R",v.test(k))throw new Error(k+" is not a valid HTML tag name in "+N);var I,V=_.test(k)||l.voidElements&&l.voidElements.test(k),Z=[];if(D)m&&i(D)&&(D="\n"+y+a(D,y)),N+=D;else if(null!=E&&u(I=[],E).length){for(var B=m&&~N.indexOf("\n"),G=!1,J=0;J0&&"<"!=Q[0];G&&X?Z[Z.length-1]+=Q:Z.push(Q),G=X}else Z.push(Q)}}if(m&&B)for(var Y=Z.length;Y--;)Z[Y]="\n"+y+a(Z[Y],y)}if(Z.length||D)N+=Z.join("");else if(l&&l.xml)return N.substring(0,N.length-1)+" />";return!V||I||D?(m&&~N.indexOf("\n")&&(N+="\n"),N+=""+k+">"):N=N.replace(/>$/," />"),N}m.shallowRender=g;export default m;export{m as render,m as renderToStaticMarkup,m as renderToString,g as shallowRender};
2 | //# sourceMappingURL=index.module.js.map
--------------------------------------------------------------------------------
/quickjs/Changelog:
--------------------------------------------------------------------------------
1 | 2021-03-27:
2 |
3 | - faster Array.prototype.push and Array.prototype.unshift
4 | - added JS_UpdateStackTop()
5 | - fixed Windows console
6 | - misc bug fixes
7 |
8 | 2020-11-08:
9 |
10 | - improved function parameter initializers
11 | - added std.setenv(), std.unsetenv() and std.getenviron()
12 | - added JS_EvalThis()
13 | - misc bug fixes
14 |
15 | 2020-09-06:
16 |
17 | - added logical assignment operators
18 | - added IsHTMLDDA support
19 | - faster for-of loops
20 | - os.Worker now takes a module filename as parameter
21 | - qjsc: added -D option to compile dynamically loaded modules or workers
22 | - misc bug fixes
23 |
24 | 2020-07-05:
25 |
26 | - modified JS_GetPrototype() to return a live value
27 | - REPL: support unicode characters larger than 16 bits
28 | - added os.Worker
29 | - improved object serialization
30 | - added std.parseExtJSON
31 | - misc bug fixes
32 |
33 | 2020-04-12:
34 |
35 | - added cross realm support
36 | - added AggregateError and Promise.any
37 | - added env, uid and gid options in os.exec()
38 | - misc bug fixes
39 |
40 | 2020-03-16:
41 |
42 | - reworked error handling in std and os libraries: suppressed I/O
43 | exceptions in std FILE functions and return a positive errno value
44 | when it is explicit
45 | - output exception messages to stderr
46 | - added std.loadFile(), std.strerror(), std.FILE.prototype.tello()
47 | - added JS_GetRuntimeOpaque(), JS_SetRuntimeOpaque(), JS_NewUint32()
48 | - updated to Unicode 13.0.0
49 | - misc bug fixes
50 |
51 | 2020-01-19:
52 |
53 | - keep CONFIG_BIGNUM in the makefile
54 | - added os.chdir()
55 | - qjs: added -I option
56 | - more memory checks in the bignum operations
57 | - modified operator overloading semantics to be closer to the TC39
58 | proposal
59 | - suppressed "use bigint" mode. Simplified "use math" mode
60 | - BigDecimal: changed suffix from 'd' to 'm'
61 | - misc bug fixes
62 |
63 | 2020-01-05:
64 |
65 | - always compile the bignum code. Added '--bignum' option to qjs.
66 | - added BigDecimal
67 | - added String.prototype.replaceAll
68 | - misc bug fixes
69 |
70 | 2019-12-21:
71 |
72 | - added nullish coalescing operator (ES2020)
73 | - added optional chaining (ES2020)
74 | - removed recursions in garbage collector
75 | - test stack overflow in the parser
76 | - improved backtrace logic
77 | - added JS_SetHostPromiseRejectionTracker()
78 | - allow exotic constructors
79 | - improved c++ compatibility
80 | - misc bug fixes
81 |
82 | 2019-10-27:
83 |
84 | - added example of C class in a module (examples/test_point.js)
85 | - added JS_GetTypedArrayBuffer()
86 | - misc bug fixes
87 |
88 | 2019-09-18:
89 |
90 | - added os.exec and other system calls
91 | - exported JS_ValueToAtom()
92 | - qjsc: added 'qjsc_' prefix to the generated C identifiers
93 | - added cross-compilation support
94 | - misc bug fixes
95 |
96 | 2019-09-01:
97 |
98 | - added globalThis
99 | - documented JS_EVAL_FLAG_COMPILE_ONLY
100 | - added import.meta.url and import.meta.main
101 | - added 'debugger' statement
102 | - misc bug fixes
103 |
104 | 2019-08-18:
105 |
106 | - added os.realpath, os.getcwd, os.mkdir, os.stat, os.lstat,
107 | os.readlink, os.readdir, os.utimes, std.popen
108 | - module autodetection
109 | - added import.meta
110 | - misc bug fixes
111 |
112 | 2019-08-10:
113 |
114 | - added public class fields and private class fields, methods and
115 | accessors (TC39 proposal)
116 | - changed JS_ToCStringLen() prototype
117 | - qjsc: handle '-' in module names and modules with the same filename
118 | - added std.urlGet
119 | - exported JS_GetOwnPropertyNames() and JS_GetOwnProperty()
120 | - exported some bigint C functions
121 | - added support for eshost in run-test262
122 | - misc bug fixes
123 |
124 | 2019-07-28:
125 |
126 | - added dynamic import
127 | - added Promise.allSettled
128 | - added String.prototype.matchAll
129 | - added Object.fromEntries
130 | - reduced number of ticks in await
131 | - added BigInt support in Atomics
132 | - exported JS_NewPromiseCapability()
133 | - misc async function and async generator fixes
134 | - enabled hashbang support by default
135 |
136 | 2019-07-21:
137 |
138 | - updated test262 tests
139 | - updated to Unicode version 12.1.0
140 | - fixed missing Date object in qjsc
141 | - fixed multi-context creation
142 | - misc ES2020 related fixes
143 | - simplified power and division operators in bignum extension
144 | - fixed several crash conditions
145 |
146 | 2019-07-09:
147 |
148 | - first public release
149 |
--------------------------------------------------------------------------------
/quickjs/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
52 | align-detached-buffer-semantics-with-web-reality
53 | arbitrary-module-namespace-names=skip
54 | Array.prototype.at=skip
55 | Array.prototype.flat
56 | Array.prototype.flatMap
57 | Array.prototype.flatten
58 | Array.prototype.values
59 | ArrayBuffer
60 | arrow-function
61 | async-functions
62 | async-iteration
63 | Atomics
64 | Atomics.waitAsync=skip
65 | BigInt
66 | caller
67 | class
68 | class-fields-private
69 | class-fields-public
70 | class-methods-private
71 | class-static-fields-public
72 | class-static-fields-private
73 | class-static-methods-private
74 | cleanupSome=skip
75 | coalesce-expression
76 | computed-property-names
77 | const
78 | cross-realm
79 | DataView
80 | DataView.prototype.getFloat32
81 | DataView.prototype.getFloat64
82 | DataView.prototype.getInt16
83 | DataView.prototype.getInt32
84 | DataView.prototype.getInt8
85 | DataView.prototype.getUint16
86 | DataView.prototype.getUint32
87 | DataView.prototype.setUint8
88 | default-parameters
89 | destructuring-assignment
90 | destructuring-binding
91 | dynamic-import
92 | export-star-as-namespace-from-module
93 | FinalizationGroup=skip
94 | FinalizationRegistry=skip
95 | FinalizationRegistry.prototype.cleanupSome=skip
96 | Float32Array
97 | Float64Array
98 | for-in-order
99 | for-of
100 | generators
101 | globalThis
102 | hashbang
103 | host-gc-required=skip
104 | import.meta
105 | Int16Array
106 | Int32Array
107 | Int8Array
108 | IsHTMLDDA
109 | json-superset
110 | legacy-regexp=skip
111 | let
112 | logical-assignment-operators
113 | Map
114 | new.target
115 | numeric-separator-literal
116 | object-rest
117 | object-spread
118 | Object.fromEntries
119 | Object.is
120 | optional-catch-binding
121 | optional-chaining
122 | Promise
123 | Promise.allSettled
124 | Promise.any
125 | Promise.prototype.finally
126 | Proxy
127 | proxy-missing-checks
128 | Reflect
129 | Reflect.construct
130 | Reflect.set
131 | Reflect.setPrototypeOf
132 | regexp-dotall
133 | regexp-lookbehind
134 | regexp-match-indices=skip
135 | regexp-named-groups
136 | regexp-unicode-property-escapes
137 | rest-parameters
138 | Set
139 | SharedArrayBuffer
140 | string-trimming
141 | String.fromCodePoint
142 | String.prototype.endsWith
143 | String.prototype.includes
144 | String.prototype.at=skip
145 | String.prototype.matchAll
146 | String.prototype.replaceAll
147 | String.prototype.trimEnd
148 | String.prototype.trimStart
149 | super
150 | Symbol
151 | Symbol.asyncIterator
152 | Symbol.hasInstance
153 | Symbol.isConcatSpreadable
154 | Symbol.iterator
155 | Symbol.match
156 | Symbol.matchAll
157 | Symbol.prototype.description
158 | Symbol.replace
159 | Symbol.search
160 | Symbol.species
161 | Symbol.split
162 | Symbol.toPrimitive
163 | Symbol.toStringTag
164 | Symbol.unscopables
165 | tail-call-optimization=skip
166 | template
167 | top-level-await=skip
168 | TypedArray
169 | TypedArray.prototype.at=skip
170 | u180e
171 | Uint16Array
172 | Uint32Array
173 | Uint8Array
174 | Uint8ClampedArray
175 | WeakMap
176 | WeakRef=skip
177 | WeakSet
178 | well-formed-json-stringify
179 | __getter__
180 | __proto__
181 | __setter__
182 |
183 | [exclude]
184 | # list excluded tests and directories here
185 |
186 | # intl not supported
187 | test262/test/intl402/
188 |
189 | # incompatible with the "caller" feature
190 | test262/test/built-ins/Function/prototype/restricted-property-caller.js
191 | test262/test/built-ins/Function/prototype/restricted-property-arguments.js
192 | test262/test/built-ins/ThrowTypeError/unique-per-realm-function-proto.js
193 |
194 | # slow tests
195 | #test262/test/built-ins/RegExp/CharacterClassEscapes/
196 | #test262/test/built-ins/RegExp/property-escapes/
197 |
198 | [tests]
199 | # list test files or use config.testdir
200 |
--------------------------------------------------------------------------------
/quickjs/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 |
--------------------------------------------------------------------------------
/quickjs/examples/point.c:
--------------------------------------------------------------------------------
1 | /*
2 | * QuickJS: Example of C module with a class
3 | *
4 | * Copyright (c) 2019 Fabrice Bellard
5 | *
6 | * Permission is hereby granted, free of charge, to any person obtaining a copy
7 | * of this software and associated documentation files (the "Software"), to deal
8 | * in the Software without restriction, including without limitation the rights
9 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 | * copies of the Software, and to permit persons to whom the Software is
11 | * furnished to do so, subject to the following conditions:
12 | *
13 | * The above copyright notice and this permission notice shall be included in
14 | * all copies or substantial portions of the Software.
15 | *
16 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 | * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 | * THE SOFTWARE.
23 | */
24 | #include "../quickjs.h"
25 | #include
26 |
27 | #define countof(x) (sizeof(x) / sizeof((x)[0]))
28 |
29 | /* Point Class */
30 |
31 | typedef struct {
32 | int x;
33 | int y;
34 | } JSPointData;
35 |
36 | static JSClassID js_point_class_id;
37 |
38 | static void js_point_finalizer(JSRuntime *rt, JSValue val)
39 | {
40 | JSPointData *s = JS_GetOpaque(val, js_point_class_id);
41 | /* Note: 's' can be NULL in case JS_SetOpaque() was not called */
42 | js_free_rt(rt, s);
43 | }
44 |
45 | static JSValue js_point_ctor(JSContext *ctx,
46 | JSValueConst new_target,
47 | int argc, JSValueConst *argv)
48 | {
49 | JSPointData *s;
50 | JSValue obj = JS_UNDEFINED;
51 | JSValue proto;
52 |
53 | s = js_mallocz(ctx, sizeof(*s));
54 | if (!s)
55 | return JS_EXCEPTION;
56 | if (JS_ToInt32(ctx, &s->x, argv[0]))
57 | goto fail;
58 | if (JS_ToInt32(ctx, &s->y, argv[1]))
59 | goto fail;
60 | /* using new_target to get the prototype is necessary when the
61 | class is extended. */
62 | proto = JS_GetPropertyStr(ctx, new_target, "prototype");
63 | if (JS_IsException(proto))
64 | goto fail;
65 | obj = JS_NewObjectProtoClass(ctx, proto, js_point_class_id);
66 | JS_FreeValue(ctx, proto);
67 | if (JS_IsException(obj))
68 | goto fail;
69 | JS_SetOpaque(obj, s);
70 | return obj;
71 | fail:
72 | js_free(ctx, s);
73 | JS_FreeValue(ctx, obj);
74 | return JS_EXCEPTION;
75 | }
76 |
77 | static JSValue js_point_get_xy(JSContext *ctx, JSValueConst this_val, int magic)
78 | {
79 | JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id);
80 | if (!s)
81 | return JS_EXCEPTION;
82 | if (magic == 0)
83 | return JS_NewInt32(ctx, s->x);
84 | else
85 | return JS_NewInt32(ctx, s->y);
86 | }
87 |
88 | static JSValue js_point_set_xy(JSContext *ctx, JSValueConst this_val, JSValue val, int magic)
89 | {
90 | JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id);
91 | int v;
92 | if (!s)
93 | return JS_EXCEPTION;
94 | if (JS_ToInt32(ctx, &v, val))
95 | return JS_EXCEPTION;
96 | if (magic == 0)
97 | s->x = v;
98 | else
99 | s->y = v;
100 | return JS_UNDEFINED;
101 | }
102 |
103 | static JSValue js_point_norm(JSContext *ctx, JSValueConst this_val,
104 | int argc, JSValueConst *argv)
105 | {
106 | JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id);
107 | if (!s)
108 | return JS_EXCEPTION;
109 | return JS_NewFloat64(ctx, sqrt((double)s->x * s->x + (double)s->y * s->y));
110 | }
111 |
112 | static JSClassDef js_point_class = {
113 | "Point",
114 | .finalizer = js_point_finalizer,
115 | };
116 |
117 | static const JSCFunctionListEntry js_point_proto_funcs[] = {
118 | JS_CGETSET_MAGIC_DEF("x", js_point_get_xy, js_point_set_xy, 0),
119 | JS_CGETSET_MAGIC_DEF("y", js_point_get_xy, js_point_set_xy, 1),
120 | JS_CFUNC_DEF("norm", 0, js_point_norm),
121 | };
122 |
123 | static int js_point_init(JSContext *ctx, JSModuleDef *m)
124 | {
125 | JSValue point_proto, point_class;
126 |
127 | /* create the Point class */
128 | JS_NewClassID(&js_point_class_id);
129 | JS_NewClass(JS_GetRuntime(ctx), js_point_class_id, &js_point_class);
130 |
131 | point_proto = JS_NewObject(ctx);
132 | JS_SetPropertyFunctionList(ctx, point_proto, js_point_proto_funcs, countof(js_point_proto_funcs));
133 |
134 | point_class = JS_NewCFunction2(ctx, js_point_ctor, "Point", 2, JS_CFUNC_constructor, 0);
135 | /* set proto.constructor and ctor.prototype */
136 | JS_SetConstructor(ctx, point_class, point_proto);
137 | JS_SetClassProto(ctx, js_point_class_id, point_proto);
138 |
139 | JS_SetModuleExport(ctx, m, "Point", point_class);
140 | return 0;
141 | }
142 |
143 | JSModuleDef *js_init_module(JSContext *ctx, const char *module_name)
144 | {
145 | JSModuleDef *m;
146 | m = JS_NewCModule(ctx, module_name, js_point_init);
147 | if (!m)
148 | return NULL;
149 | JS_AddModuleExport(ctx, m, "Point");
150 | return m;
151 | }
152 |
--------------------------------------------------------------------------------
/quickjs/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 |
--------------------------------------------------------------------------------
/quickjs/tests/test_bjson.js:
--------------------------------------------------------------------------------
1 | import * as bjson from "./bjson.so";
2 |
3 | function assert(actual, expected, message) {
4 | if (arguments.length == 1)
5 | expected = true;
6 |
7 | if (actual === expected)
8 | return;
9 |
10 | if (actual !== null && expected !== null
11 | && typeof actual == 'object' && typeof expected == 'object'
12 | && actual.toString() === expected.toString())
13 | return;
14 |
15 | throw Error("assertion failed: got |" + actual + "|" +
16 | ", expected |" + expected + "|" +
17 | (message ? " (" + message + ")" : ""));
18 | }
19 |
20 | function toHex(a)
21 | {
22 | var i, s = "", tab, v;
23 | tab = new Uint8Array(a);
24 | for(i = 0; i < tab.length; i++) {
25 | v = tab[i].toString(16);
26 | if (v.length < 2)
27 | v = "0" + v;
28 | if (i !== 0)
29 | s += " ";
30 | s += v;
31 | }
32 | return s;
33 | }
34 |
35 | function isArrayLike(a)
36 | {
37 | return Array.isArray(a) ||
38 | (a instanceof Uint8ClampedArray) ||
39 | (a instanceof Uint8Array) ||
40 | (a instanceof Uint16Array) ||
41 | (a instanceof Uint32Array) ||
42 | (a instanceof Int8Array) ||
43 | (a instanceof Int16Array) ||
44 | (a instanceof Int32Array) ||
45 | (a instanceof Float32Array) ||
46 | (a instanceof Float64Array);
47 | }
48 |
49 | function toStr(a)
50 | {
51 | var s, i, props, prop;
52 |
53 | switch(typeof(a)) {
54 | case "object":
55 | if (a === null)
56 | return "null";
57 | if (a instanceof Date) {
58 | s = "Date(" + toStr(a.valueOf()) + ")";
59 | } else if (a instanceof Number) {
60 | s = "Number(" + toStr(a.valueOf()) + ")";
61 | } else if (a instanceof String) {
62 | s = "String(" + toStr(a.valueOf()) + ")";
63 | } else if (a instanceof Boolean) {
64 | s = "Boolean(" + toStr(a.valueOf()) + ")";
65 | } else if (isArrayLike(a)) {
66 | s = "[";
67 | for(i = 0; i < a.length; i++) {
68 | if (i != 0)
69 | s += ",";
70 | s += toStr(a[i]);
71 | }
72 | s += "]";
73 | } else {
74 | props = Object.keys(a);
75 | s = "{";
76 | for(i = 0; i < props.length; i++) {
77 | if (i != 0)
78 | s += ",";
79 | prop = props[i];
80 | s += prop + ":" + toStr(a[prop]);
81 | }
82 | s += "}";
83 | }
84 | return s;
85 | case "undefined":
86 | return "undefined";
87 | case "string":
88 | return a.__quote();
89 | case "number":
90 | case "bigfloat":
91 | if (a == 0 && 1 / a < 0)
92 | return "-0";
93 | else
94 | return a.toString();
95 | break;
96 | default:
97 | return a.toString();
98 | }
99 | }
100 |
101 | function bjson_test(a)
102 | {
103 | var buf, r, a_str, r_str;
104 | a_str = toStr(a);
105 | buf = bjson.write(a);
106 | if (0) {
107 | print(a_str, "->", toHex(buf));
108 | }
109 | r = bjson.read(buf, 0, buf.byteLength);
110 | r_str = toStr(r);
111 | if (a_str != r_str) {
112 | print(a_str);
113 | print(r_str);
114 | assert(false);
115 | }
116 | }
117 |
118 | /* test multiple references to an object including circular
119 | references */
120 | function bjson_test_reference()
121 | {
122 | var array, buf, i, n, array_buffer;
123 | n = 16;
124 | array = [];
125 | for(i = 0; i < n; i++)
126 | array[i] = {};
127 | array_buffer = new ArrayBuffer(n);
128 | for(i = 0; i < n; i++) {
129 | array[i].next = array[(i + 1) % n];
130 | array[i].idx = i;
131 | array[i].typed_array = new Uint8Array(array_buffer, i, 1);
132 | }
133 | buf = bjson.write(array, true);
134 |
135 | array = bjson.read(buf, 0, buf.byteLength, true);
136 |
137 | /* check the result */
138 | for(i = 0; i < n; i++) {
139 | assert(array[i].next, array[(i + 1) % n]);
140 | assert(array[i].idx, i);
141 | assert(array[i].typed_array.buffer, array_buffer);
142 | assert(array[i].typed_array.length, 1);
143 | assert(array[i].typed_array.byteOffset, i);
144 | }
145 | }
146 |
147 | function bjson_test_all()
148 | {
149 | var obj;
150 |
151 | bjson_test({x:1, y:2, if:3});
152 | bjson_test([1, 2, 3]);
153 | bjson_test([1.0, "aa", true, false, undefined, null, NaN, -Infinity, -0.0]);
154 | if (typeof BigInt !== "undefined") {
155 | bjson_test([BigInt("1"), -BigInt("0x123456789"),
156 | BigInt("0x123456789abcdef123456789abcdef")]);
157 | }
158 | if (typeof BigFloat !== "undefined") {
159 | BigFloatEnv.setPrec(function () {
160 | bjson_test([BigFloat("0.1"), BigFloat("-1e30"), BigFloat("0"),
161 | BigFloat("-0"), BigFloat("Infinity"), BigFloat("-Infinity"),
162 | 0.0 / BigFloat("0"), BigFloat.MAX_VALUE,
163 | BigFloat.MIN_VALUE]);
164 | }, 113, 15);
165 | }
166 | if (typeof BigDecimal !== "undefined") {
167 | bjson_test([BigDecimal("0"),
168 | BigDecimal("0.8"), BigDecimal("123321312321321e100"),
169 | BigDecimal("-1233213123213214332333223332e100"),
170 | BigDecimal("1.233e-1000")]);
171 | }
172 |
173 | bjson_test([new Date(1234), new String("abc"), new Number(-12.1), new Boolean(true)]);
174 |
175 | bjson_test(new Int32Array([123123, 222111, -32222]));
176 | bjson_test(new Float64Array([123123, 222111.5]));
177 |
178 | /* tested with a circular reference */
179 | obj = {};
180 | obj.x = obj;
181 | try {
182 | bjson.write(obj);
183 | assert(false);
184 | } catch(e) {
185 | assert(e instanceof TypeError);
186 | }
187 |
188 | bjson_test_reference();
189 | }
190 |
191 | bjson_test_all();
192 |
--------------------------------------------------------------------------------
/quickjs/test262_errors.txt:
--------------------------------------------------------------------------------
1 | test262/test/built-ins/Function/internals/Construct/derived-this-uninitialized-realm.js:20: Test262Error: Expected a ReferenceError but got a ReferenceError
2 | test262/test/built-ins/Function/internals/Construct/derived-this-uninitialized-realm.js:20: strict mode: Test262Error: Expected a ReferenceError but got a ReferenceError
3 | test262/test/built-ins/RegExp/named-groups/non-unicode-property-names-valid.js:46: SyntaxError: invalid group name
4 | test262/test/built-ins/RegExp/named-groups/non-unicode-property-names-valid.js:46: strict mode: SyntaxError: invalid group name
5 | test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/BigInt/detached-buffer.js:46: Test262Error: (Testing with BigInt64Array.)
6 | test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/BigInt/detached-buffer.js:46: strict mode: Test262Error: (Testing with BigInt64Array.)
7 | test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/detached-buffer.js:47: Test262Error: (Testing with Float64Array.)
8 | test262/test/built-ins/TypedArrayConstructors/internals/DefineOwnProperty/detached-buffer.js:47: strict mode: Test262Error: (Testing with Float64Array.)
9 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/detached-buffer-realm.js:37: strict mode: TypeError: out-of-bound numeric index (Testing with BigInt64Array.)
10 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/detached-buffer.js:34: TypeError: cannot convert bigint to number (Testing with BigInt64Array.)
11 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/detached-buffer.js:32: strict mode: TypeError: out-of-bound numeric index (Testing with BigInt64Array.)
12 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-minus-zero.js:20: Test262Error: Reflect.set("new TA([42n])", "-0", 1n) must return true Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
13 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-minus-zero.js:20: strict mode: Test262Error: Reflect.set("new TA([42n])", "-0", 1n) must return true Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
14 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-not-integer.js:21: Test262Error: Reflect.set("new TA([42n])", "1.1", 1n) must return true Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
15 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-not-integer.js:21: strict mode: Test262Error: Reflect.set("new TA([42n])", "1.1", 1n) must return true Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
16 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-out-of-bounds.js:27: Test262Error: Reflect.set("new TA([42n])", "-1", 1n) must return false Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
17 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/key-is-out-of-bounds.js:27: strict mode: Test262Error: Reflect.set("new TA([42n])", "-1", 1n) must return false Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
18 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/tonumber-value-detached-buffer.js:24: Test262Error: Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
19 | test262/test/built-ins/TypedArrayConstructors/internals/Set/BigInt/tonumber-value-detached-buffer.js:24: strict mode: Test262Error: Expected SameValue(«false», «true») to be true (Testing with BigInt64Array.)
20 | test262/test/built-ins/TypedArrayConstructors/internals/Set/detached-buffer-realm.js:37: strict mode: TypeError: out-of-bound numeric index (Testing with Float64Array.)
21 | test262/test/built-ins/TypedArrayConstructors/internals/Set/detached-buffer.js:32: strict mode: TypeError: out-of-bound numeric index (Testing with Float64Array.)
22 | test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-minus-zero.js:22: Test262Error: Reflect.set(sample, "-0", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
23 | test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-minus-zero.js:22: strict mode: Test262Error: Reflect.set(sample, "-0", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
24 | test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-not-integer.js:22: Test262Error: Reflect.set(sample, "1.1", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
25 | test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-not-integer.js:22: strict mode: Test262Error: Reflect.set(sample, "1.1", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
26 | test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds.js:22: Test262Error: Reflect.set(sample, "-1", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
27 | test262/test/built-ins/TypedArrayConstructors/internals/Set/key-is-out-of-bounds.js:22: strict mode: Test262Error: Reflect.set(sample, "-1", 1) must return true Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
28 | test262/test/built-ins/TypedArrayConstructors/internals/Set/tonumber-value-detached-buffer.js:39: Test262Error: Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
29 | test262/test/built-ins/TypedArrayConstructors/internals/Set/tonumber-value-detached-buffer.js:39: strict mode: Test262Error: Expected SameValue(«false», «true») to be true (Testing with Float64Array.)
30 | test262/test/language/expressions/dynamic-import/usage-from-eval.js:26: TypeError: $DONE() not called
31 | test262/test/language/expressions/dynamic-import/usage-from-eval.js:26: strict mode: TypeError: $DONE() not called
32 | test262/test/language/expressions/optional-chaining/optional-call-preserves-this.js:21: TypeError: cannot read property 'c' of undefined
33 | test262/test/language/expressions/optional-chaining/optional-call-preserves-this.js:15: strict mode: TypeError: cannot read property '_b' of undefined
34 | test262/test/language/statements/for-of/head-lhs-async-invalid.js:14: unexpected error type: Test262: This statement should not be evaluated.
35 | test262/test/language/statements/for-of/head-lhs-async-invalid.js:14: strict mode: unexpected error type: Test262: This statement should not be evaluated.
36 |
--------------------------------------------------------------------------------
/quickjs/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 |
--------------------------------------------------------------------------------
/quickjs/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 | assert(std.sprintf("%010d", 123), "0000000123");
30 | assert(std.sprintf("%x", -2), "fffffffe");
31 | assert(std.sprintf("%lx", -2), "fffffffffffffffe");
32 | assert(std.sprintf("%10.1f", 2.1), " 2.1");
33 | assert(std.sprintf("%*.*f", 10, 2, -2.13), " -2.13");
34 | assert(std.sprintf("%#lx", 0x7fffffffffffffffn), "0x7fffffffffffffff");
35 | }
36 |
37 | function test_file1()
38 | {
39 | var f, len, str, size, buf, ret, i, str1;
40 |
41 | f = std.tmpfile();
42 | str = "hello world\n";
43 | f.puts(str);
44 |
45 | f.seek(0, std.SEEK_SET);
46 | str1 = f.readAsString();
47 | assert(str1 === str);
48 |
49 | f.seek(0, std.SEEK_END);
50 | size = f.tell();
51 | assert(size === str.length);
52 |
53 | f.seek(0, std.SEEK_SET);
54 |
55 | buf = new Uint8Array(size);
56 | ret = f.read(buf.buffer, 0, size);
57 | assert(ret === size);
58 | for(i = 0; i < size; i++)
59 | assert(buf[i] === str.charCodeAt(i));
60 |
61 | f.close();
62 | }
63 |
64 | function test_file2()
65 | {
66 | var f, str, i, size;
67 | f = std.tmpfile();
68 | str = "hello world\n";
69 | size = str.length;
70 | for(i = 0; i < size; i++)
71 | f.putByte(str.charCodeAt(i));
72 | f.seek(0, std.SEEK_SET);
73 | for(i = 0; i < size; i++) {
74 | assert(str.charCodeAt(i) === f.getByte());
75 | }
76 | assert(f.getByte() === -1);
77 | f.close();
78 | }
79 |
80 | function test_getline()
81 | {
82 | var f, line, line_count, lines, i;
83 |
84 | lines = ["hello world", "line 1", "line 2" ];
85 | f = std.tmpfile();
86 | for(i = 0; i < lines.length; i++) {
87 | f.puts(lines[i], "\n");
88 | }
89 |
90 | f.seek(0, std.SEEK_SET);
91 | assert(!f.eof());
92 | line_count = 0;
93 | for(;;) {
94 | line = f.getline();
95 | if (line === null)
96 | break;
97 | assert(line == lines[line_count]);
98 | line_count++;
99 | }
100 | assert(f.eof());
101 | assert(line_count === lines.length);
102 |
103 | f.close();
104 | }
105 |
106 | function test_popen()
107 | {
108 | var str, f, fname = "tmp_file.txt";
109 | var content = "hello world";
110 |
111 | f = std.open(fname, "w");
112 | f.puts(content);
113 | f.close();
114 |
115 | /* test loadFile */
116 | assert(std.loadFile(fname), content);
117 |
118 | /* execute the 'cat' shell command */
119 | f = std.popen("cat " + fname, "r");
120 | str = f.readAsString();
121 | f.close();
122 |
123 | assert(str, content);
124 |
125 | os.remove(fname);
126 | }
127 |
128 | function test_ext_json()
129 | {
130 | var expected, input, obj;
131 | expected = '{"x":false,"y":true,"z2":null,"a":[1,8,160],"s":"str"}';
132 | input = `{ "x":false, /*comments are allowed */
133 | "y":true, // also a comment
134 | z2:null, // unquoted property names
135 | "a":[+1,0o10,0xa0,], // plus prefix, octal, hexadecimal
136 | "s":"str",} // trailing comma in objects and arrays
137 | `;
138 | obj = std.parseExtJSON(input);
139 | assert(JSON.stringify(obj), expected);
140 | }
141 |
142 | function test_os()
143 | {
144 | var fd, fpath, fname, fdir, buf, buf2, i, files, err, fdate, st, link_path;
145 |
146 | assert(os.isatty(0));
147 |
148 | fdir = "test_tmp_dir";
149 | fname = "tmp_file.txt";
150 | fpath = fdir + "/" + fname;
151 | link_path = fdir + "/test_link";
152 |
153 | os.remove(link_path);
154 | os.remove(fpath);
155 | os.remove(fdir);
156 |
157 | err = os.mkdir(fdir, 0o755);
158 | assert(err === 0);
159 |
160 | fd = os.open(fpath, os.O_RDWR | os.O_CREAT | os.O_TRUNC);
161 | assert(fd >= 0);
162 |
163 | buf = new Uint8Array(10);
164 | for(i = 0; i < buf.length; i++)
165 | buf[i] = i;
166 | assert(os.write(fd, buf.buffer, 0, buf.length) === buf.length);
167 |
168 | assert(os.seek(fd, 0, std.SEEK_SET) === 0);
169 | buf2 = new Uint8Array(buf.length);
170 | assert(os.read(fd, buf2.buffer, 0, buf2.length) === buf2.length);
171 |
172 | for(i = 0; i < buf.length; i++)
173 | assert(buf[i] == buf2[i]);
174 |
175 | if (typeof BigInt !== "undefined") {
176 | assert(os.seek(fd, BigInt(6), std.SEEK_SET), BigInt(6));
177 | assert(os.read(fd, buf2.buffer, 0, 1) === 1);
178 | assert(buf[6] == buf2[0]);
179 | }
180 |
181 | assert(os.close(fd) === 0);
182 |
183 | [files, err] = os.readdir(fdir);
184 | assert(err, 0);
185 | assert(files.indexOf(fname) >= 0);
186 |
187 | fdate = 10000;
188 |
189 | err = os.utimes(fpath, fdate, fdate);
190 | assert(err, 0);
191 |
192 | [st, err] = os.stat(fpath);
193 | assert(err, 0);
194 | assert(st.mode & os.S_IFMT, os.S_IFREG);
195 | assert(st.mtime, fdate);
196 |
197 | err = os.symlink(fname, link_path);
198 | assert(err === 0);
199 |
200 | [st, err] = os.lstat(link_path);
201 | assert(err, 0);
202 | assert(st.mode & os.S_IFMT, os.S_IFLNK);
203 |
204 | [buf, err] = os.readlink(link_path);
205 | assert(err, 0);
206 | assert(buf, fname);
207 |
208 | assert(os.remove(link_path) === 0);
209 |
210 | [buf, err] = os.getcwd();
211 | assert(err, 0);
212 |
213 | [buf2, err] = os.realpath(".");
214 | assert(err, 0);
215 |
216 | assert(buf, buf2);
217 |
218 | assert(os.remove(fpath) === 0);
219 |
220 | fd = os.open(fpath, os.O_RDONLY);
221 | assert(fd < 0);
222 |
223 | assert(os.remove(fdir) === 0);
224 | }
225 |
226 | function test_os_exec()
227 | {
228 | var ret, fds, pid, f, status;
229 |
230 | ret = os.exec(["true"]);
231 | assert(ret, 0);
232 |
233 | ret = os.exec(["/bin/sh", "-c", "exit 1"], { usePath: false });
234 | assert(ret, 1);
235 |
236 | fds = os.pipe();
237 | pid = os.exec(["sh", "-c", "echo $FOO"], {
238 | stdout: fds[1],
239 | block: false,
240 | env: { FOO: "hello" },
241 | } );
242 | assert(pid >= 0);
243 | os.close(fds[1]); /* close the write end (as it is only in the child) */
244 | f = std.fdopen(fds[0], "r");
245 | assert(f.getline(), "hello");
246 | assert(f.getline(), null);
247 | f.close();
248 | [ret, status] = os.waitpid(pid, 0);
249 | assert(ret, pid);
250 | assert(status & 0x7f, 0); /* exited */
251 | assert(status >> 8, 0); /* exit code */
252 |
253 | pid = os.exec(["cat"], { block: false } );
254 | assert(pid >= 0);
255 | os.kill(pid, os.SIGQUIT);
256 | [ret, status] = os.waitpid(pid, 0);
257 | assert(ret, pid);
258 | assert(status & 0x7f, os.SIGQUIT);
259 | }
260 |
261 | function test_timer()
262 | {
263 | var th, i;
264 |
265 | /* just test that a timer can be inserted and removed */
266 | th = [];
267 | for(i = 0; i < 3; i++)
268 | th[i] = os.setTimeout(function () { }, 1000);
269 | for(i = 0; i < 3; i++)
270 | os.clearTimeout(th[i]);
271 | }
272 |
273 | test_printf();
274 | test_file1();
275 | test_file2();
276 | test_getline();
277 | test_popen();
278 | test_os();
279 | test_os_exec();
280 | test_timer();
281 | test_ext_json();
282 |
--------------------------------------------------------------------------------
/quickjs/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 |
--------------------------------------------------------------------------------
/quickjs/unicode_gen_def.h:
--------------------------------------------------------------------------------
1 | #ifdef UNICODE_GENERAL_CATEGORY
2 | DEF(Cn, "Unassigned") /* must be zero */
3 | DEF(Lu, "Uppercase_Letter")
4 | DEF(Ll, "Lowercase_Letter")
5 | DEF(Lt, "Titlecase_Letter")
6 | DEF(Lm, "Modifier_Letter")
7 | DEF(Lo, "Other_Letter")
8 | DEF(Mn, "Nonspacing_Mark")
9 | DEF(Mc, "Spacing_Mark")
10 | DEF(Me, "Enclosing_Mark")
11 | DEF(Nd, "Decimal_Number,digit")
12 | DEF(Nl, "Letter_Number")
13 | DEF(No, "Other_Number")
14 | DEF(Sm, "Math_Symbol")
15 | DEF(Sc, "Currency_Symbol")
16 | DEF(Sk, "Modifier_Symbol")
17 | DEF(So, "Other_Symbol")
18 | DEF(Pc, "Connector_Punctuation")
19 | DEF(Pd, "Dash_Punctuation")
20 | DEF(Ps, "Open_Punctuation")
21 | DEF(Pe, "Close_Punctuation")
22 | DEF(Pi, "Initial_Punctuation")
23 | DEF(Pf, "Final_Punctuation")
24 | DEF(Po, "Other_Punctuation")
25 | DEF(Zs, "Space_Separator")
26 | DEF(Zl, "Line_Separator")
27 | DEF(Zp, "Paragraph_Separator")
28 | DEF(Cc, "Control,cntrl")
29 | DEF(Cf, "Format")
30 | DEF(Cs, "Surrogate")
31 | DEF(Co, "Private_Use")
32 | /* synthetic properties */
33 | DEF(LC, "Cased_Letter")
34 | DEF(L, "Letter")
35 | DEF(M, "Mark,Combining_Mark")
36 | DEF(N, "Number")
37 | DEF(S, "Symbol")
38 | DEF(P, "Punctuation,punct")
39 | DEF(Z, "Separator")
40 | DEF(C, "Other")
41 | #endif
42 |
43 | #ifdef UNICODE_SCRIPT
44 | /* scripts aliases names in PropertyValueAliases.txt */
45 | DEF(Unknown, "Zzzz")
46 | DEF(Adlam, "Adlm")
47 | DEF(Ahom, "Ahom")
48 | DEF(Anatolian_Hieroglyphs, "Hluw")
49 | DEF(Arabic, "Arab")
50 | DEF(Armenian, "Armn")
51 | DEF(Avestan, "Avst")
52 | DEF(Balinese, "Bali")
53 | DEF(Bamum, "Bamu")
54 | DEF(Bassa_Vah, "Bass")
55 | DEF(Batak, "Batk")
56 | DEF(Bengali, "Beng")
57 | DEF(Bhaiksuki, "Bhks")
58 | DEF(Bopomofo, "Bopo")
59 | DEF(Brahmi, "Brah")
60 | DEF(Braille, "Brai")
61 | DEF(Buginese, "Bugi")
62 | DEF(Buhid, "Buhd")
63 | DEF(Canadian_Aboriginal, "Cans")
64 | DEF(Carian, "Cari")
65 | DEF(Caucasian_Albanian, "Aghb")
66 | DEF(Chakma, "Cakm")
67 | DEF(Cham, "Cham")
68 | DEF(Cherokee, "Cher")
69 | DEF(Chorasmian, "Chrs")
70 | DEF(Common, "Zyyy")
71 | DEF(Coptic, "Copt,Qaac")
72 | DEF(Cuneiform, "Xsux")
73 | DEF(Cypriot, "Cprt")
74 | DEF(Cyrillic, "Cyrl")
75 | DEF(Deseret, "Dsrt")
76 | DEF(Devanagari, "Deva")
77 | DEF(Dives_Akuru, "Diak")
78 | DEF(Dogra, "Dogr")
79 | DEF(Duployan, "Dupl")
80 | DEF(Egyptian_Hieroglyphs, "Egyp")
81 | DEF(Elbasan, "Elba")
82 | DEF(Elymaic, "Elym")
83 | DEF(Ethiopic, "Ethi")
84 | DEF(Georgian, "Geor")
85 | DEF(Glagolitic, "Glag")
86 | DEF(Gothic, "Goth")
87 | DEF(Grantha, "Gran")
88 | DEF(Greek, "Grek")
89 | DEF(Gujarati, "Gujr")
90 | DEF(Gunjala_Gondi, "Gong")
91 | DEF(Gurmukhi, "Guru")
92 | DEF(Han, "Hani")
93 | DEF(Hangul, "Hang")
94 | DEF(Hanifi_Rohingya, "Rohg")
95 | DEF(Hanunoo, "Hano")
96 | DEF(Hatran, "Hatr")
97 | DEF(Hebrew, "Hebr")
98 | DEF(Hiragana, "Hira")
99 | DEF(Imperial_Aramaic, "Armi")
100 | DEF(Inherited, "Zinh,Qaai")
101 | DEF(Inscriptional_Pahlavi, "Phli")
102 | DEF(Inscriptional_Parthian, "Prti")
103 | DEF(Javanese, "Java")
104 | DEF(Kaithi, "Kthi")
105 | DEF(Kannada, "Knda")
106 | DEF(Katakana, "Kana")
107 | DEF(Kayah_Li, "Kali")
108 | DEF(Kharoshthi, "Khar")
109 | DEF(Khmer, "Khmr")
110 | DEF(Khojki, "Khoj")
111 | DEF(Khitan_Small_Script, "Kits")
112 | DEF(Khudawadi, "Sind")
113 | DEF(Lao, "Laoo")
114 | DEF(Latin, "Latn")
115 | DEF(Lepcha, "Lepc")
116 | DEF(Limbu, "Limb")
117 | DEF(Linear_A, "Lina")
118 | DEF(Linear_B, "Linb")
119 | DEF(Lisu, "Lisu")
120 | DEF(Lycian, "Lyci")
121 | DEF(Lydian, "Lydi")
122 | DEF(Makasar, "Maka")
123 | DEF(Mahajani, "Mahj")
124 | DEF(Malayalam, "Mlym")
125 | DEF(Mandaic, "Mand")
126 | DEF(Manichaean, "Mani")
127 | DEF(Marchen, "Marc")
128 | DEF(Masaram_Gondi, "Gonm")
129 | DEF(Medefaidrin, "Medf")
130 | DEF(Meetei_Mayek, "Mtei")
131 | DEF(Mende_Kikakui, "Mend")
132 | DEF(Meroitic_Cursive, "Merc")
133 | DEF(Meroitic_Hieroglyphs, "Mero")
134 | DEF(Miao, "Plrd")
135 | DEF(Modi, "Modi")
136 | DEF(Mongolian, "Mong")
137 | DEF(Mro, "Mroo")
138 | DEF(Multani, "Mult")
139 | DEF(Myanmar, "Mymr")
140 | DEF(Nabataean, "Nbat")
141 | DEF(Nandinagari, "Nand")
142 | DEF(New_Tai_Lue, "Talu")
143 | DEF(Newa, "Newa")
144 | DEF(Nko, "Nkoo")
145 | DEF(Nushu, "Nshu")
146 | DEF(Nyiakeng_Puachue_Hmong, "Hmnp")
147 | DEF(Ogham, "Ogam")
148 | DEF(Ol_Chiki, "Olck")
149 | DEF(Old_Hungarian, "Hung")
150 | DEF(Old_Italic, "Ital")
151 | DEF(Old_North_Arabian, "Narb")
152 | DEF(Old_Permic, "Perm")
153 | DEF(Old_Persian, "Xpeo")
154 | DEF(Old_Sogdian, "Sogo")
155 | DEF(Old_South_Arabian, "Sarb")
156 | DEF(Old_Turkic, "Orkh")
157 | DEF(Oriya, "Orya")
158 | DEF(Osage, "Osge")
159 | DEF(Osmanya, "Osma")
160 | DEF(Pahawh_Hmong, "Hmng")
161 | DEF(Palmyrene, "Palm")
162 | DEF(Pau_Cin_Hau, "Pauc")
163 | DEF(Phags_Pa, "Phag")
164 | DEF(Phoenician, "Phnx")
165 | DEF(Psalter_Pahlavi, "Phlp")
166 | DEF(Rejang, "Rjng")
167 | DEF(Runic, "Runr")
168 | DEF(Samaritan, "Samr")
169 | DEF(Saurashtra, "Saur")
170 | DEF(Sharada, "Shrd")
171 | DEF(Shavian, "Shaw")
172 | DEF(Siddham, "Sidd")
173 | DEF(SignWriting, "Sgnw")
174 | DEF(Sinhala, "Sinh")
175 | DEF(Sogdian, "Sogd")
176 | DEF(Sora_Sompeng, "Sora")
177 | DEF(Soyombo, "Soyo")
178 | DEF(Sundanese, "Sund")
179 | DEF(Syloti_Nagri, "Sylo")
180 | DEF(Syriac, "Syrc")
181 | DEF(Tagalog, "Tglg")
182 | DEF(Tagbanwa, "Tagb")
183 | DEF(Tai_Le, "Tale")
184 | DEF(Tai_Tham, "Lana")
185 | DEF(Tai_Viet, "Tavt")
186 | DEF(Takri, "Takr")
187 | DEF(Tamil, "Taml")
188 | DEF(Tangut, "Tang")
189 | DEF(Telugu, "Telu")
190 | DEF(Thaana, "Thaa")
191 | DEF(Thai, "Thai")
192 | DEF(Tibetan, "Tibt")
193 | DEF(Tifinagh, "Tfng")
194 | DEF(Tirhuta, "Tirh")
195 | DEF(Ugaritic, "Ugar")
196 | DEF(Vai, "Vaii")
197 | DEF(Wancho, "Wcho")
198 | DEF(Warang_Citi, "Wara")
199 | DEF(Yezidi, "Yezi")
200 | DEF(Yi, "Yiii")
201 | DEF(Zanabazar_Square, "Zanb")
202 | #endif
203 |
204 | #ifdef UNICODE_PROP_LIST
205 | /* Prop list not exported to regexp */
206 | DEF(Hyphen, "")
207 | DEF(Other_Math, "")
208 | DEF(Other_Alphabetic, "")
209 | DEF(Other_Lowercase, "")
210 | DEF(Other_Uppercase, "")
211 | DEF(Other_Grapheme_Extend, "")
212 | DEF(Other_Default_Ignorable_Code_Point, "")
213 | DEF(Other_ID_Start, "")
214 | DEF(Other_ID_Continue, "")
215 | DEF(Prepended_Concatenation_Mark, "")
216 | /* additional computed properties for smaller tables */
217 | DEF(ID_Continue1, "")
218 | DEF(XID_Start1, "")
219 | DEF(XID_Continue1, "")
220 | DEF(Changes_When_Titlecased1, "")
221 | DEF(Changes_When_Casefolded1, "")
222 | DEF(Changes_When_NFKC_Casefolded1, "")
223 |
224 | /* Prop list exported to JS */
225 | DEF(ASCII_Hex_Digit, "AHex")
226 | DEF(Bidi_Control, "Bidi_C")
227 | DEF(Dash, "")
228 | DEF(Deprecated, "Dep")
229 | DEF(Diacritic, "Dia")
230 | DEF(Extender, "Ext")
231 | DEF(Hex_Digit, "Hex")
232 | DEF(IDS_Binary_Operator, "IDSB")
233 | DEF(IDS_Trinary_Operator, "IDST")
234 | DEF(Ideographic, "Ideo")
235 | DEF(Join_Control, "Join_C")
236 | DEF(Logical_Order_Exception, "LOE")
237 | DEF(Noncharacter_Code_Point, "NChar")
238 | DEF(Pattern_Syntax, "Pat_Syn")
239 | DEF(Pattern_White_Space, "Pat_WS")
240 | DEF(Quotation_Mark, "QMark")
241 | DEF(Radical, "")
242 | DEF(Regional_Indicator, "RI")
243 | DEF(Sentence_Terminal, "STerm")
244 | DEF(Soft_Dotted, "SD")
245 | DEF(Terminal_Punctuation, "Term")
246 | DEF(Unified_Ideograph, "UIdeo")
247 | DEF(Variation_Selector, "VS")
248 | DEF(White_Space, "space")
249 | DEF(Bidi_Mirrored, "Bidi_M")
250 | DEF(Emoji, "")
251 | DEF(Emoji_Component, "EComp")
252 | DEF(Emoji_Modifier, "EMod")
253 | DEF(Emoji_Modifier_Base, "EBase")
254 | DEF(Emoji_Presentation, "EPres")
255 | DEF(Extended_Pictographic, "ExtPict")
256 | DEF(Default_Ignorable_Code_Point, "DI")
257 | DEF(ID_Start, "IDS")
258 | DEF(Case_Ignorable, "CI")
259 |
260 | /* other binary properties */
261 | DEF(ASCII,"")
262 | DEF(Alphabetic, "Alpha")
263 | DEF(Any, "")
264 | DEF(Assigned,"")
265 | DEF(Cased, "")
266 | DEF(Changes_When_Casefolded, "CWCF")
267 | DEF(Changes_When_Casemapped, "CWCM")
268 | DEF(Changes_When_Lowercased, "CWL")
269 | DEF(Changes_When_NFKC_Casefolded, "CWKCF")
270 | DEF(Changes_When_Titlecased, "CWT")
271 | DEF(Changes_When_Uppercased, "CWU")
272 | DEF(Grapheme_Base, "Gr_Base")
273 | DEF(Grapheme_Extend, "Gr_Ext")
274 | DEF(ID_Continue, "IDC")
275 | DEF(Lowercase, "Lower")
276 | DEF(Math, "")
277 | DEF(Uppercase, "Upper")
278 | DEF(XID_Continue, "XIDC")
279 | DEF(XID_Start, "XIDS")
280 |
281 | /* internal tables with index */
282 | DEF(Cased1, "")
283 |
284 | #endif
285 |
--------------------------------------------------------------------------------
/quickjs/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 | static inline void dbuf_set_error(DynBuf *s)
272 | {
273 | s->error = TRUE;
274 | }
275 |
276 | #define UTF8_CHAR_LEN_MAX 6
277 |
278 | int unicode_to_utf8(uint8_t *buf, unsigned int c);
279 | int unicode_from_utf8(const uint8_t *p, int max_len, const uint8_t **pp);
280 |
281 | static inline int from_hex(int c)
282 | {
283 | if (c >= '0' && c <= '9')
284 | return c - '0';
285 | else if (c >= 'A' && c <= 'F')
286 | return c - 'A' + 10;
287 | else if (c >= 'a' && c <= 'f')
288 | return c - 'a' + 10;
289 | else
290 | return -1;
291 | }
292 |
293 | void rqsort(void *base, size_t nmemb, size_t size,
294 | int (*cmp)(const void *, const void *, void *),
295 | void *arg);
296 |
297 | #endif /* CUTILS_H */
298 |
--------------------------------------------------------------------------------
/quickjs/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(errors, "errors")
86 | DEF(stack, "stack")
87 | DEF(name, "name")
88 | DEF(toString, "toString")
89 | DEF(toLocaleString, "toLocaleString")
90 | DEF(valueOf, "valueOf")
91 | DEF(eval, "eval")
92 | DEF(prototype, "prototype")
93 | DEF(constructor, "constructor")
94 | DEF(configurable, "configurable")
95 | DEF(writable, "writable")
96 | DEF(enumerable, "enumerable")
97 | DEF(value, "value")
98 | DEF(get, "get")
99 | DEF(set, "set")
100 | DEF(of, "of")
101 | DEF(__proto__, "__proto__")
102 | DEF(undefined, "undefined")
103 | DEF(number, "number")
104 | DEF(boolean, "boolean")
105 | DEF(string, "string")
106 | DEF(object, "object")
107 | DEF(symbol, "symbol")
108 | DEF(integer, "integer")
109 | DEF(unknown, "unknown")
110 | DEF(arguments, "arguments")
111 | DEF(callee, "callee")
112 | DEF(caller, "caller")
113 | DEF(_eval_, "")
114 | DEF(_ret_, "")
115 | DEF(_var_, "")
116 | DEF(_arg_var_, "")
117 | DEF(_with_, "")
118 | DEF(lastIndex, "lastIndex")
119 | DEF(target, "target")
120 | DEF(index, "index")
121 | DEF(input, "input")
122 | DEF(defineProperties, "defineProperties")
123 | DEF(apply, "apply")
124 | DEF(join, "join")
125 | DEF(concat, "concat")
126 | DEF(split, "split")
127 | DEF(construct, "construct")
128 | DEF(getPrototypeOf, "getPrototypeOf")
129 | DEF(setPrototypeOf, "setPrototypeOf")
130 | DEF(isExtensible, "isExtensible")
131 | DEF(preventExtensions, "preventExtensions")
132 | DEF(has, "has")
133 | DEF(deleteProperty, "deleteProperty")
134 | DEF(defineProperty, "defineProperty")
135 | DEF(getOwnPropertyDescriptor, "getOwnPropertyDescriptor")
136 | DEF(ownKeys, "ownKeys")
137 | DEF(add, "add")
138 | DEF(done, "done")
139 | DEF(next, "next")
140 | DEF(values, "values")
141 | DEF(source, "source")
142 | DEF(flags, "flags")
143 | DEF(global, "global")
144 | DEF(unicode, "unicode")
145 | DEF(raw, "raw")
146 | DEF(new_target, "new.target")
147 | DEF(this_active_func, "this.active_func")
148 | DEF(home_object, "")
149 | DEF(computed_field, "")
150 | DEF(static_computed_field, "") /* must come after computed_fields */
151 | DEF(class_fields_init, "")
152 | DEF(brand, "")
153 | DEF(hash_constructor, "#constructor")
154 | DEF(as, "as")
155 | DEF(from, "from")
156 | DEF(meta, "meta")
157 | DEF(_default_, "*default*")
158 | DEF(_star_, "*")
159 | DEF(Module, "Module")
160 | DEF(then, "then")
161 | DEF(resolve, "resolve")
162 | DEF(reject, "reject")
163 | DEF(promise, "promise")
164 | DEF(proxy, "proxy")
165 | DEF(revoke, "revoke")
166 | DEF(async, "async")
167 | DEF(exec, "exec")
168 | DEF(groups, "groups")
169 | DEF(status, "status")
170 | DEF(reason, "reason")
171 | DEF(globalThis, "globalThis")
172 | #ifdef CONFIG_BIGNUM
173 | DEF(bigint, "bigint")
174 | DEF(bigfloat, "bigfloat")
175 | DEF(bigdecimal, "bigdecimal")
176 | DEF(roundingMode, "roundingMode")
177 | DEF(maximumSignificantDigits, "maximumSignificantDigits")
178 | DEF(maximumFractionDigits, "maximumFractionDigits")
179 | #endif
180 | #ifdef CONFIG_ATOMICS
181 | DEF(not_equal, "not-equal")
182 | DEF(timed_out, "timed-out")
183 | DEF(ok, "ok")
184 | #endif
185 | DEF(toJSON, "toJSON")
186 | /* class names */
187 | DEF(Object, "Object")
188 | DEF(Array, "Array")
189 | DEF(Error, "Error")
190 | DEF(Number, "Number")
191 | DEF(String, "String")
192 | DEF(Boolean, "Boolean")
193 | DEF(Symbol, "Symbol")
194 | DEF(Arguments, "Arguments")
195 | DEF(Math, "Math")
196 | DEF(JSON, "JSON")
197 | DEF(Date, "Date")
198 | DEF(Function, "Function")
199 | DEF(GeneratorFunction, "GeneratorFunction")
200 | DEF(ForInIterator, "ForInIterator")
201 | DEF(RegExp, "RegExp")
202 | DEF(ArrayBuffer, "ArrayBuffer")
203 | DEF(SharedArrayBuffer, "SharedArrayBuffer")
204 | /* must keep same order as class IDs for typed arrays */
205 | DEF(Uint8ClampedArray, "Uint8ClampedArray")
206 | DEF(Int8Array, "Int8Array")
207 | DEF(Uint8Array, "Uint8Array")
208 | DEF(Int16Array, "Int16Array")
209 | DEF(Uint16Array, "Uint16Array")
210 | DEF(Int32Array, "Int32Array")
211 | DEF(Uint32Array, "Uint32Array")
212 | #ifdef CONFIG_BIGNUM
213 | DEF(BigInt64Array, "BigInt64Array")
214 | DEF(BigUint64Array, "BigUint64Array")
215 | #endif
216 | DEF(Float32Array, "Float32Array")
217 | DEF(Float64Array, "Float64Array")
218 | DEF(DataView, "DataView")
219 | #ifdef CONFIG_BIGNUM
220 | DEF(BigInt, "BigInt")
221 | DEF(BigFloat, "BigFloat")
222 | DEF(BigFloatEnv, "BigFloatEnv")
223 | DEF(BigDecimal, "BigDecimal")
224 | DEF(OperatorSet, "OperatorSet")
225 | DEF(Operators, "Operators")
226 | #endif
227 | DEF(Map, "Map")
228 | DEF(Set, "Set") /* Map + 1 */
229 | DEF(WeakMap, "WeakMap") /* Map + 2 */
230 | DEF(WeakSet, "WeakSet") /* Map + 3 */
231 | DEF(Map_Iterator, "Map Iterator")
232 | DEF(Set_Iterator, "Set Iterator")
233 | DEF(Array_Iterator, "Array Iterator")
234 | DEF(String_Iterator, "String Iterator")
235 | DEF(RegExp_String_Iterator, "RegExp String Iterator")
236 | DEF(Generator, "Generator")
237 | DEF(Proxy, "Proxy")
238 | DEF(Promise, "Promise")
239 | DEF(PromiseResolveFunction, "PromiseResolveFunction")
240 | DEF(PromiseRejectFunction, "PromiseRejectFunction")
241 | DEF(AsyncFunction, "AsyncFunction")
242 | DEF(AsyncFunctionResolve, "AsyncFunctionResolve")
243 | DEF(AsyncFunctionReject, "AsyncFunctionReject")
244 | DEF(AsyncGeneratorFunction, "AsyncGeneratorFunction")
245 | DEF(AsyncGenerator, "AsyncGenerator")
246 | DEF(EvalError, "EvalError")
247 | DEF(RangeError, "RangeError")
248 | DEF(ReferenceError, "ReferenceError")
249 | DEF(SyntaxError, "SyntaxError")
250 | DEF(TypeError, "TypeError")
251 | DEF(URIError, "URIError")
252 | DEF(InternalError, "InternalError")
253 | /* private symbols */
254 | DEF(Private_brand, "")
255 | /* symbols */
256 | DEF(Symbol_toPrimitive, "Symbol.toPrimitive")
257 | DEF(Symbol_iterator, "Symbol.iterator")
258 | DEF(Symbol_match, "Symbol.match")
259 | DEF(Symbol_matchAll, "Symbol.matchAll")
260 | DEF(Symbol_replace, "Symbol.replace")
261 | DEF(Symbol_search, "Symbol.search")
262 | DEF(Symbol_split, "Symbol.split")
263 | DEF(Symbol_toStringTag, "Symbol.toStringTag")
264 | DEF(Symbol_isConcatSpreadable, "Symbol.isConcatSpreadable")
265 | DEF(Symbol_hasInstance, "Symbol.hasInstance")
266 | DEF(Symbol_species, "Symbol.species")
267 | DEF(Symbol_unscopables, "Symbol.unscopables")
268 | DEF(Symbol_asyncIterator, "Symbol.asyncIterator")
269 | #ifdef CONFIG_BIGNUM
270 | DEF(Symbol_operatorSet, "Symbol.operatorSet")
271 | #endif
272 |
273 | #endif /* DEF */
274 |
--------------------------------------------------------------------------------
/tiny.c:
--------------------------------------------------------------------------------
1 | // http://www.cs.cmu.edu/afs/cs/academic/class/15213-s00/www/class28/tiny.c
2 | /*
3 | * tiny.c - a minimal HTTP server that serves static and
4 | * dynamic content with the GET method. Neither
5 | * robust, secure, nor modular. Use for instructional
6 | * purposes only.
7 | * Dave O'Hallaron, Carnegie Mellon
8 | *
9 | * usage: tiny
10 | */
11 | #include "quickjs/quickjs.h"
12 | #include "quickjs/quickjs-libc.h"
13 | #include
14 | #include
15 | #include
16 | #include
17 | #include
18 | #include
19 | #include
20 | #include
21 | #include
22 | #include
23 | #include
24 | #include
25 | #include
26 | #include
27 | #include
28 | #include
29 |
30 | #define BUFSIZE 1024
31 | #define MAXERRS 16
32 |
33 | extern char **environ; /* the environment */
34 |
35 | /*
36 | * error - wrapper for perror used for bad syscalls
37 | */
38 | void error(char *msg) {
39 | perror(msg);
40 | exit(1);
41 | }
42 |
43 | /*
44 | * cerror - returns an error message to the client
45 | */
46 | void cerror(FILE *stream, char *cause, char *errno,
47 | char *shortmsg, char *longmsg) {
48 | fprintf(stream, "HTTP/1.1 %s %s\n", errno, shortmsg);
49 | fprintf(stream, "Content-type: text/html\n");
50 | fprintf(stream, "\n");
51 | fprintf(stream, "Tiny Error");
52 | fprintf(stream, "\n");
53 | fprintf(stream, "%s: %s\n", errno, shortmsg);
54 | fprintf(stream, "%s: %s\n", longmsg, cause);
55 | fprintf(stream, "
The Tiny Web server\n");
56 | }
57 |
58 | extern const uint8_t preact[];
59 | extern const uint32_t preact_size;
60 | extern const uint8_t preact_module[];
61 | extern const uint32_t preact_module_size;
62 | extern const uint8_t htm[];
63 | extern const uint32_t htm_size;
64 | typedef struct JSString JSString;
65 |
66 | char *strrpc(char *str,char *oldstr,char *newstr){
67 | char bstr[strlen(str)+strlen(newstr)+1];
68 | memset(bstr,0,sizeof(bstr));
69 | int i;
70 | for(i = 0;i < strlen(str);i++){
71 | if(!strncmp(str+i,oldstr,strlen(oldstr))){
72 | strcat(bstr,newstr);
73 | i += strlen(oldstr) - 1;
74 | }else{
75 | strncat(bstr,str + i,1);
76 | }
77 | }
78 |
79 | strcpy(str,bstr);
80 | return str;
81 | }
82 |
83 | const char* init(int argc,char* argv[]){
84 | int pfd[2];
85 | if(pipe(pfd)==-1){
86 | perror("pipe failed");
87 | exit(1);
88 | }
89 | int stdout_copy = dup(STDOUT_FILENO);
90 | dup2(pfd[1], STDOUT_FILENO);
91 | close(pfd[1]);
92 |
93 | JSRuntime *rt;
94 | JSContext *ctx;
95 |
96 | rt = JS_NewRuntime();
97 | JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL);
98 | js_std_init_handlers(rt);
99 |
100 | ctx = JS_NewContext(rt);
101 | js_std_add_helpers(ctx, argc, argv);
102 | js_init_module_std(ctx, "std");
103 | js_init_module_os(ctx, "os");
104 |
105 | js_std_eval_binary(ctx, preact, preact_size, 0);
106 | js_std_eval_binary(ctx, htm, htm_size,0);
107 |
108 | if (argc < 3) {
109 | printf("A file need to be specified");
110 | exit(1);
111 | }
112 | char* filename = argv[2];
113 | char *buf;
114 | size_t buf_len;
115 | buf = (char*)js_load_file(ctx, &buf_len, filename);
116 | if (!buf) {
117 | perror(filename);
118 | exit(1);
119 | }
120 |
121 | JSValue val = JS_Eval(ctx, buf, buf_len, filename, JS_EVAL_TYPE_MODULE);
122 | js_std_loop(ctx);
123 |
124 |
125 | if (JS_IsException(val)) {
126 | js_std_dump_error(ctx);
127 | exit(1);
128 | }
129 |
130 | // JSString* js_str = JS_VALUE_GET_STRING(val);
131 | // char* res = (char*)malloc(js_str->len+1);
132 | // memcpy(res, js_str->u.str8, js_str->len);
133 | fflush(stdout);
134 | dup2(stdout_copy, 1);
135 | char res[BUFSIZE];
136 | while(1){
137 | int n = read(pfd[0], res, BUFSIZE-1);
138 | if(n<=0){
139 | break;
140 | }
141 | }
142 |
143 | JS_FreeValue(ctx, val);
144 | js_free(ctx, buf);
145 | JS_FreeContext(ctx);
146 | JS_FreeRuntime(rt);
147 |
148 | buf = (char*)js_load_file(NULL, &buf_len, "index.html");
149 |
150 | strrpc(buf, "PLACE_HOLDER", res);
151 |
152 | return buf;
153 | }
154 |
155 | int main(int argc, char **argv) {
156 |
157 | /* variables for connection management */
158 | int parentfd; /* parent socket */
159 | int childfd; /* child socket */
160 | int portno; /* port to listen on */
161 | int clientlen; /* byte size of client's address */
162 | struct hostent *hostp; /* client host info */
163 | char *hostaddrp; /* dotted decimal host addr string */
164 | int optval; /* flag value for setsockopt */
165 | struct sockaddr_in serveraddr; /* server's addr */
166 | struct sockaddr_in clientaddr; /* client addr */
167 |
168 | /* variables for connection I/O */
169 | FILE *stream; /* stream version of childfd */
170 | char buf[BUFSIZE]; /* message buffer */
171 | char method[BUFSIZE]; /* request method */
172 | char uri[BUFSIZE]; /* request uri */
173 | char version[BUFSIZE]; /* request method */
174 | char filename[BUFSIZE];/* path derived from uri */
175 | char filetype[BUFSIZE];/* path derived from uri */
176 | char cgiargs[BUFSIZE]; /* cgi argument list */
177 | char *p; /* temporary pointer */
178 | int is_static; /* static request? */
179 | struct stat sbuf; /* file status */
180 | int fd; /* static content filedes */
181 | int pid; /* process id from fork */
182 | int wait_status; /* status from wait */
183 |
184 | /* check command line args */
185 | if (argc < 2) {
186 | fprintf(stderr, "usage: %s \n", argv[0]);
187 | exit(1);
188 | }
189 | portno = atoi(argv[1]);
190 |
191 | /* open socket descriptor */
192 | parentfd = socket(AF_INET, SOCK_STREAM, 0);
193 | if (parentfd < 0)
194 | error("ERROR opening socket");
195 |
196 | /* allows us to restart server immediately */
197 | optval = 1;
198 | setsockopt(parentfd, SOL_SOCKET, SO_REUSEADDR,
199 | (const void *)&optval , sizeof(int));
200 |
201 | /* bind port to socket */
202 | bzero((char *) &serveraddr, sizeof(serveraddr));
203 | serveraddr.sin_family = AF_INET;
204 | serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
205 | serveraddr.sin_port = htons((unsigned short)portno);
206 | if (bind(parentfd, (struct sockaddr *) &serveraddr,
207 | sizeof(serveraddr)) < 0)
208 | error("ERROR on binding");
209 |
210 | /* get us ready to accept connection requests */
211 | if (listen(parentfd, 5) < 0) /* allow 5 requests to queue up */
212 | error("ERROR on listen");
213 |
214 | /*
215 | * main loop: wait for a connection request, parse HTTP,
216 | * serve requested content, close connection.
217 | */
218 |
219 | const char* res = init(argc, argv);
220 | printf("GENERAYE:\n %s\n",res);
221 | fflush(stdout);
222 |
223 | clientlen = sizeof(clientaddr);
224 | while (1) {
225 |
226 | /* wait for a connection request */
227 | childfd = accept(parentfd, (struct sockaddr *) &clientaddr, (socklen_t*)&clientlen);
228 | if (childfd < 0)
229 | error("ERROR on accept");
230 | hostaddrp = inet_ntoa(clientaddr.sin_addr);
231 | if (hostaddrp == NULL)
232 | error("ERROR on inet_ntoa\n");
233 |
234 | /* open the child socket descriptor as a stream */
235 | if ((stream = fdopen(childfd, "r+")) == NULL)
236 | error("ERROR on fdopen");
237 |
238 | /* get the HTTP request line */
239 | bzero(buf, BUFSIZE);
240 | char* _ = fgets(buf, BUFSIZE, stream);
241 | printf("%s", buf);
242 | sscanf(buf, "%s %s %s\n", method, uri, version);
243 |
244 | /* tiny only supports the GET method */
245 | if (strcasecmp(method, "GET")) {
246 | cerror(stream, method, "501", "Not Implemented",
247 | "Tiny does not implement this method");
248 | fclose(stream);
249 | close(childfd);
250 | continue;
251 | }
252 |
253 | /* read (and ignore) the HTTP headers */
254 | _ = fgets(buf, BUFSIZE, stream);
255 | printf("%s", buf);
256 | while(strcmp(buf, "\r\n")) {
257 | char* _ = fgets(buf, BUFSIZE, stream);
258 | printf("%s", buf);
259 | }
260 |
261 | bzero(filename, sizeof(filename));
262 | strcpy(filename, ".");
263 | strcat(filename, uri);
264 | if (uri[strlen(uri)-1] == '/')
265 | strcat(filename, "index.html");
266 |
267 | /* make sure the file exists */
268 | if (stat(filename, &sbuf) < 0) {
269 | cerror(stream, filename, "404", "Not found",
270 | "Tiny couldn't find this file");
271 | fclose(stream);
272 | close(childfd);
273 | continue;
274 | }
275 |
276 | /* serve static content */
277 | if (strstr(filename, ".html"))
278 | strcpy(filetype, "text/html");
279 | else if (strstr(filename, ".gif"))
280 | strcpy(filetype, "image/gif");
281 | else if (strstr(filename, ".jpg"))
282 | strcpy(filetype, "image/jpg");
283 | else if (strstr(filename, ".js"))
284 | strcpy(filetype, "application/javascript");
285 | else
286 | strcpy(filetype, "text/plain");
287 |
288 | /* print response header */
289 | fprintf(stream, "HTTP/1.1 200 OK\n");
290 | fprintf(stream, "Server: Tiny Web Server\n");
291 | fprintf(stream, "Content-type: %s\n", filetype);
292 |
293 | /* Use mmap to return arbitrary-sized response body */
294 | if(!strcmp("./index.html", filename)){
295 | fprintf(stream, "Content-length: %d\n", (int)strlen(res));
296 | fprintf(stream, "\r\n");
297 | fprintf(stream, "%s",res);
298 | fflush(stream);
299 | } else {
300 | fprintf(stream, "Content-length: %d\n", (int)sbuf.st_size);
301 | fprintf(stream, "\r\n");
302 | fd = open(filename, O_RDONLY);
303 | p = mmap(0, sbuf.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
304 | fwrite(p, 1, sbuf.st_size, stream);
305 | munmap(p, sbuf.st_size);
306 | fflush(stream);
307 | }
308 | /* clean up */
309 | fclose(stream);
310 | close(childfd);
311 |
312 | }
313 | }
--------------------------------------------------------------------------------
/htm.c:
--------------------------------------------------------------------------------
1 | /* File generated automatically by the QuickJS compiler. */
2 |
3 | #include
4 |
5 | const uint32_t htm_size = 1637;
6 |
7 | const uint8_t htm[1637] = {
8 | 0x01, 0x1b, 0x0c, 0x68, 0x74, 0x6d, 0x2e, 0x6a,
9 | 0x73, 0x02, 0x6e, 0x02, 0x74, 0x02, 0x73, 0x02,
10 | 0x72, 0x02, 0x65, 0x02, 0x75, 0x02, 0x68, 0x02,
11 | 0x70, 0x02, 0x61, 0x0c, 0x61, 0x73, 0x73, 0x69,
12 | 0x67, 0x6e, 0x08, 0x70, 0x75, 0x73, 0x68, 0x02,
13 | 0x6c, 0x02, 0x3c, 0x04, 0x2d, 0x2d, 0x02, 0x3e,
14 | 0x02, 0x22, 0x02, 0x27, 0x02, 0x3d, 0x02, 0x2f,
15 | 0x02, 0x20, 0x02, 0x09, 0x02, 0x0a, 0x02, 0x0d,
16 | 0x06, 0x21, 0x2d, 0x2d, 0x0e, 0x72, 0x65, 0x70,
17 | 0x6c, 0x61, 0x63, 0x65, 0x06, 0x2e, 0x2e, 0x2e,
18 | 0x0f, 0xa4, 0x03, 0x00, 0x01, 0x00, 0x02, 0x2c,
19 | 0x00, 0x00, 0x0e, 0x00, 0x06, 0x01, 0xa0, 0x01,
20 | 0x00, 0x00, 0x00, 0x02, 0x03, 0x02, 0x1f, 0x00,
21 | 0xa6, 0x03, 0x00, 0x01, 0xa8, 0x03, 0x01, 0x01,
22 | 0xf8, 0x01, 0x02, 0x01, 0x08, 0xe8, 0x0a, 0xbe,
23 | 0x01, 0x4d, 0x16, 0x00, 0x00, 0x00, 0xe1, 0x29,
24 | 0xbe, 0x00, 0x4d, 0xd3, 0x00, 0x00, 0x00, 0xdf,
25 | 0x38, 0xaa, 0x00, 0x00, 0x00, 0x11, 0x21, 0x00,
26 | 0x00, 0xe0, 0x29, 0xa4, 0x03, 0x01, 0x02, 0x01,
27 | 0x3f, 0x0e, 0x43, 0x06, 0x01, 0x00, 0x04, 0x04,
28 | 0x04, 0x09, 0x01, 0x00, 0xf2, 0x01, 0x08, 0xa8,
29 | 0x03, 0x00, 0x01, 0x00, 0xaa, 0x03, 0x00, 0x01,
30 | 0x00, 0xac, 0x03, 0x00, 0x01, 0x00, 0xae, 0x03,
31 | 0x00, 0x01, 0x00, 0xb0, 0x03, 0x00, 0x00, 0x00,
32 | 0xb2, 0x03, 0x00, 0x01, 0x00, 0xb4, 0x03, 0x00,
33 | 0x02, 0x00, 0xb6, 0x03, 0x00, 0x03, 0x00, 0xa6,
34 | 0x03, 0x00, 0x00, 0xd0, 0xb3, 0xb3, 0x49, 0xb4,
35 | 0xc8, 0xc4, 0xd0, 0xe7, 0xa3, 0x69, 0xe5, 0x00,
36 | 0x00, 0x00, 0xd0, 0xc4, 0x91, 0xc8, 0x47, 0xc9,
37 | 0xd0, 0xc4, 0x47, 0xe8, 0x18, 0xd0, 0xb3, 0x71,
38 | 0x13, 0x47, 0xc5, 0xe8, 0x04, 0xb4, 0xea, 0x02,
39 | 0xb5, 0xaf, 0x49, 0xd1, 0xd0, 0xc4, 0x91, 0xc8,
40 | 0x47, 0x47, 0xea, 0x06, 0xd0, 0xc4, 0x8f, 0xcc,
41 | 0x47, 0xca, 0xb6, 0xc5, 0xab, 0xe8, 0x0a, 0xd2,
42 | 0xb3, 0x71, 0xc6, 0x16, 0x49, 0xeb, 0xa7, 0x00,
43 | 0xb7, 0xc5, 0xab, 0xe8, 0x1f, 0xd2, 0xb4, 0x71,
44 | 0x38, 0x8f, 0x00, 0x00, 0x00, 0x42, 0xdc, 0x00,
45 | 0x00, 0x00, 0xd2, 0xb4, 0x47, 0x11, 0xe9, 0x03,
46 | 0x0e, 0x0b, 0xc6, 0x24, 0x02, 0x00, 0x16, 0x49,
47 | 0xeb, 0x84, 0x00, 0xb8, 0xc5, 0xab, 0xe8, 0x19,
48 | 0xd2, 0xb4, 0x71, 0xd2, 0xb4, 0x47, 0x11, 0xe9,
49 | 0x03, 0x0e, 0x0b, 0x16, 0x49, 0xd0, 0xc4, 0x8f,
50 | 0xcc, 0x47, 0x71, 0xc6, 0x16, 0x49, 0xea, 0x66,
51 | 0xb9, 0xc5, 0xab, 0xe8, 0x14, 0xd2, 0xb4, 0x47,
52 | 0xd0, 0xc4, 0x8f, 0xcc, 0x47, 0x71, 0x13, 0x47,
53 | 0xc6, 0xbf, 0x9d, 0x9d, 0x16, 0x49, 0xea, 0x4e,
54 | 0xc5, 0xe8, 0x41, 0xcf, 0x42, 0x5a, 0x00, 0x00,
55 | 0x00, 0xc6, 0xdb, 0xcf, 0xc6, 0xd1, 0xbf, 0x07,
56 | 0x26, 0x02, 0x00, 0x22, 0x04, 0x00, 0x24, 0x02,
57 | 0x00, 0xc7, 0xd2, 0x42, 0xdd, 0x00, 0x00, 0x00,
58 | 0xc3, 0x24, 0x01, 0x00, 0x0e, 0xc6, 0xb3, 0x47,
59 | 0xe8, 0x0c, 0xd0, 0xb3, 0x71, 0x13, 0x47, 0xb5,
60 | 0xaf, 0x16, 0x49, 0xea, 0x19, 0xd0, 0xc4, 0xb5,
61 | 0x9e, 0xb3, 0x49, 0xd0, 0xc4, 0x71, 0xc3, 0x16,
62 | 0x49, 0xea, 0x0b, 0xd2, 0x42, 0xdd, 0x00, 0x00,
63 | 0x00, 0xc6, 0x24, 0x01, 0x00, 0x0e, 0x93, 0x01,
64 | 0xeb, 0x18, 0xff, 0xd2, 0x28, 0xa4, 0x03, 0x01,
65 | 0x00, 0x0e, 0x43, 0x06, 0x01, 0x00, 0x01, 0x03,
66 | 0x01, 0x07, 0x02, 0x01, 0x5e, 0x04, 0xaa, 0x03,
67 | 0x00, 0x01, 0x00, 0xac, 0x03, 0x00, 0x00, 0x00,
68 | 0x10, 0x00, 0x01, 0x00, 0x9a, 0x01, 0x00, 0x01,
69 | 0x00, 0xa8, 0x03, 0x01, 0x00, 0xa6, 0x03, 0x00,
70 | 0x00, 0x08, 0xc8, 0x0c, 0x00, 0xc9, 0xdb, 0x42,
71 | 0x41, 0x00, 0x00, 0x00, 0xc4, 0x24, 0x01, 0x00,
72 | 0xcb, 0x11, 0xe9, 0x17, 0x0e, 0x38, 0xaa, 0x00,
73 | 0x00, 0x00, 0x11, 0x21, 0x00, 0x00, 0xc7, 0xdb,
74 | 0x42, 0x42, 0x00, 0x00, 0x00, 0xc4, 0xc3, 0x24,
75 | 0x02, 0x00, 0x0e, 0xdc, 0xc4, 0xc3, 0x42, 0x41,
76 | 0x00, 0x00, 0x00, 0xcf, 0x24, 0x01, 0x00, 0x11,
77 | 0xe9, 0x13, 0x0e, 0xc3, 0x42, 0x42, 0x00, 0x00,
78 | 0x00, 0xcf, 0xbe, 0x00, 0xcf, 0xed, 0xcb, 0x24,
79 | 0x02, 0x00, 0x0e, 0xc3, 0xc5, 0x26, 0x00, 0x00,
80 | 0x22, 0x04, 0x00, 0xcb, 0xe7, 0xb4, 0xa5, 0xe8,
81 | 0x03, 0xc3, 0x28, 0xc3, 0xb3, 0x47, 0x28, 0xa4,
82 | 0x03, 0x01, 0x00, 0x0e, 0x43, 0x06, 0x01, 0x00,
83 | 0x01, 0x09, 0x01, 0x05, 0x00, 0x01, 0xaa, 0x03,
84 | 0x0a, 0xa6, 0x03, 0x00, 0x01, 0x00, 0xa8, 0x03,
85 | 0x00, 0x00, 0x00, 0xaa, 0x03, 0x00, 0x01, 0x40,
86 | 0xac, 0x03, 0x00, 0x02, 0x40, 0xae, 0x03, 0x00,
87 | 0x03, 0x40, 0xb0, 0x03, 0x00, 0x04, 0x00, 0xb2,
88 | 0x03, 0x00, 0x05, 0x40, 0xb4, 0x03, 0x00, 0x06,
89 | 0x00, 0xb6, 0x03, 0x00, 0x07, 0x00, 0xbc, 0x03,
90 | 0x00, 0x08, 0x00, 0xb4, 0xc9, 0xbf, 0xca, 0xbf,
91 | 0xc1, 0x04, 0xb3, 0x26, 0x01, 0x00, 0xc1, 0x05,
92 | 0xbe, 0x00, 0x4d, 0xda, 0x00, 0x00, 0x00, 0xc1,
93 | 0x06, 0xb3, 0xc1, 0x07, 0xc0, 0x07, 0xcf, 0xe7,
94 | 0xa3, 0x69, 0x84, 0x01, 0x00, 0x00, 0xc0, 0x07,
95 | 0x11, 0xe8, 0x12, 0x0e, 0xb4, 0xc5, 0xab, 0x11,
96 | 0xe8, 0x05, 0x0e, 0xc0, 0x06, 0xec, 0x0e, 0xc0,
97 | 0x06, 0xc0, 0x07, 0xed, 0x0e, 0xb3, 0xc1, 0x08,
98 | 0xc0, 0x08, 0xcf, 0xc0, 0x07, 0x47, 0xe7, 0xa3,
99 | 0x69, 0x58, 0x01, 0x00, 0x00, 0xcf, 0xc0, 0x07,
100 | 0x47, 0xc0, 0x08, 0x47, 0xc7, 0xb4, 0xc5, 0xab,
101 | 0xe8, 0x21, 0x04, 0xdf, 0x00, 0x00, 0x00, 0xc3,
102 | 0xab, 0xe8, 0x11, 0xc0, 0x06, 0xec, 0x0e, 0xc0,
103 | 0x05, 0x26, 0x01, 0x00, 0xc1, 0x05, 0xb6, 0xcd,
104 | 0xeb, 0x0f, 0x01, 0xc6, 0xc3, 0x9d, 0xce, 0xeb,
105 | 0x08, 0x01, 0xb7, 0xc5, 0xab, 0xe8, 0x23, 0x04,
106 | 0xe0, 0x00, 0x00, 0x00, 0xc6, 0xab, 0xe8, 0x11,
107 | 0x04, 0xe1, 0x00, 0x00, 0x00, 0xc3, 0xab, 0xe8,
108 | 0x08, 0xb4, 0xc9, 0xbf, 0xce, 0xeb, 0xea, 0x00,
109 | 0xc3, 0xc6, 0xb3, 0x47, 0x9d, 0xce, 0xeb, 0xe1,
110 | 0x00, 0xc0, 0x04, 0xe8, 0x14, 0xc3, 0xc0, 0x04,
111 | 0xab, 0xe8, 0x07, 0xbf, 0xc2, 0x04, 0xeb, 0xd1,
112 | 0x00, 0xc6, 0xc3, 0x9d, 0xce, 0xeb, 0xca, 0x00,
113 | 0x04, 0xe2, 0x00, 0x00, 0x00, 0xc3, 0xab, 0x11,
114 | 0xe9, 0x09, 0x0e, 0x04, 0xe3, 0x00, 0x00, 0x00,
115 | 0xc3, 0xab, 0xe8, 0x07, 0xc3, 0xc2, 0x04, 0xeb,
116 | 0xb0, 0x00, 0x04, 0xe1, 0x00, 0x00, 0x00, 0xc3,
117 | 0xab, 0xe8, 0x0a, 0xc0, 0x06, 0xec, 0x0e, 0xb4,
118 | 0xcd, 0xeb, 0x9e, 0x00, 0xc5, 0x11, 0x69, 0x99,
119 | 0x00, 0x00, 0x00, 0x0e, 0x04, 0xe4, 0x00, 0x00,
120 | 0x00, 0xc3, 0xab, 0xe8, 0x0a, 0xb8, 0xc9, 0xc6,
121 | 0xc8, 0xbf, 0xce, 0xeb, 0x84, 0x00, 0x04, 0xe5,
122 | 0x00, 0x00, 0x00, 0xc3, 0xab, 0xe8, 0x44, 0xc5,
123 | 0xb8, 0xa3, 0x11, 0xe9, 0x11, 0x0e, 0x04, 0xe1,
124 | 0x00, 0x00, 0x00, 0xcf, 0xc0, 0x07, 0x47, 0xc0,
125 | 0x08, 0xb4, 0x9d, 0x47, 0xab, 0xe8, 0x2c, 0xc0,
126 | 0x06, 0xec, 0x0e, 0xb6, 0xc5, 0xab, 0x11, 0xe8,
127 | 0x08, 0x0e, 0xc0, 0x05, 0xb3, 0x47, 0xc2, 0x05,
128 | 0x0e, 0xc0, 0x05, 0xc9, 0xc0, 0x05, 0xb3, 0x47,
129 | 0xc2, 0x05, 0x42, 0xdd, 0x00, 0x00, 0x00, 0xb5,
130 | 0xb3, 0xc5, 0x24, 0x03, 0x00, 0x0e, 0xb3, 0xcd,
131 | 0xea, 0x37, 0x04, 0xe6, 0x00, 0x00, 0x00, 0xc3,
132 | 0xab, 0x11, 0xe9, 0x1f, 0x0e, 0x04, 0xe7, 0x00,
133 | 0x00, 0x00, 0xc3, 0xab, 0x11, 0xe9, 0x14, 0x0e,
134 | 0x04, 0xe8, 0x00, 0x00, 0x00, 0xc3, 0xab, 0x11,
135 | 0xe9, 0x09, 0x0e, 0x04, 0xe9, 0x00, 0x00, 0x00,
136 | 0xc3, 0xab, 0xe8, 0x09, 0xc0, 0x06, 0xec, 0x0e,
137 | 0xb5, 0xcd, 0xea, 0x05, 0xc6, 0xc3, 0x9d, 0xce,
138 | 0x0e, 0xb6, 0xc5, 0xab, 0x11, 0xe8, 0x15, 0x0e,
139 | 0x04, 0xea, 0x00, 0x00, 0x00, 0xc6, 0xab, 0x11,
140 | 0xe8, 0x0a, 0x0e, 0xb7, 0xc9, 0xc0, 0x05, 0xb3,
141 | 0x47, 0xc2, 0x05, 0x0e, 0x93, 0x08, 0xeb, 0xa1,
142 | 0xfe, 0x93, 0x07, 0xeb, 0x78, 0xfe, 0xc0, 0x06,
143 | 0xec, 0x0e, 0xc0, 0x05, 0x28, 0xa4, 0x03, 0x01,
144 | 0x00, 0x0e, 0x43, 0x06, 0x01, 0x00, 0x01, 0x00,
145 | 0x01, 0x06, 0x04, 0x02, 0xc8, 0x01, 0x01, 0xa6,
146 | 0x03, 0x00, 0x01, 0x00, 0xac, 0x03, 0x02, 0x01,
147 | 0xae, 0x03, 0x03, 0x01, 0xb2, 0x03, 0x05, 0x01,
148 | 0xaa, 0x03, 0x01, 0x01, 0xb4, 0xdb, 0xab, 0xe8,
149 | 0x27, 0xcf, 0x11, 0xe9, 0x12, 0x0e, 0xdc, 0x42,
150 | 0xeb, 0x00, 0x00, 0x00, 0xbd, 0x00, 0xbd, 0x01,
151 | 0x33, 0xbf, 0x24, 0x02, 0x00, 0xe4, 0xe8, 0x10,
152 | 0xdd, 0x42, 0xdd, 0x00, 0x00, 0x00, 0xb3, 0xcf,
153 | 0xdc, 0x24, 0x03, 0x00, 0xeb, 0x9b, 0x00, 0xb6,
154 | 0xdb, 0xab, 0xe8, 0x1b, 0xcf, 0x11, 0xe9, 0x03,
155 | 0x0e, 0xdc, 0xe8, 0x13, 0xdd, 0x42, 0xdd, 0x00,
156 | 0x00, 0x00, 0xb6, 0xcf, 0xdc, 0x24, 0x03, 0x00,
157 | 0x0e, 0xb5, 0xe3, 0xeb, 0x7c, 0x00, 0xb5, 0xdb,
158 | 0xab, 0xe8, 0x1b, 0x04, 0xec, 0x00, 0x00, 0x00,
159 | 0xdc, 0xab, 0xe8, 0x12, 0xcf, 0xe8, 0x0f, 0xdd,
160 | 0x42, 0xdd, 0x00, 0x00, 0x00, 0xb7, 0xcf, 0xb3,
161 | 0x24, 0x03, 0x00, 0xea, 0x5c, 0xb5, 0xdb, 0xab,
162 | 0xe8, 0x18, 0xdc, 0xe8, 0x15, 0xcf, 0x96, 0xe8,
163 | 0x11, 0xdd, 0x42, 0xdd, 0x00, 0x00, 0x00, 0xb8,
164 | 0xb3, 0xb3, 0x96, 0xdc, 0x24, 0x04, 0x00, 0xea,
165 | 0x40, 0xdb, 0xb8, 0xa6, 0x11, 0xe8, 0x3a, 0x0e,
166 | 0xdc, 0x11, 0xe9, 0x0b, 0x0e, 0xcf, 0x96, 0x11,
167 | 0xe8, 0x05, 0x0e, 0xb8, 0xdb, 0xab, 0x11, 0xe8,
168 | 0x12, 0x0e, 0xdd, 0x42, 0xdd, 0x00, 0x00, 0x00,
169 | 0xdb, 0xb3, 0xdc, 0xde, 0x24, 0x04, 0x00, 0x0e,
170 | 0xb9, 0xe3, 0x0e, 0xcf, 0x11, 0xe8, 0x12, 0x0e,
171 | 0xdd, 0x42, 0xdd, 0x00, 0x00, 0x00, 0xdb, 0xcf,
172 | 0xb3, 0xde, 0x24, 0x04, 0x00, 0x0e, 0xb9, 0xe3,
173 | 0x0e, 0xbf, 0xe0, 0x29, 0xa4, 0x03, 0x01, 0x00,
174 | 0x07, 0x26, 0x5e, 0x5c, 0x73, 0x2a, 0x5c, 0x6e,
175 | 0x5c, 0x73, 0x2a, 0x7c, 0x5c, 0x73, 0x2a, 0x5c,
176 | 0x6e, 0x5c, 0x73, 0x2a, 0x24, 0x07, 0xba, 0x04,
177 | 0x01, 0x01, 0x00, 0x16, 0x01, 0x00, 0x00, 0x08,
178 | 0x06, 0x00, 0x00, 0x00, 0x04, 0x07, 0xf5, 0xff,
179 | 0xff, 0xff, 0x0b, 0x00, 0x09, 0x83, 0x00, 0x00,
180 | 0x00, 0x05, 0x1c, 0x2c, 0x00, 0x00, 0x00, 0x00,
181 | 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x01,
182 | 0x00, 0x00, 0x00, 0x15, 0x0a, 0x00, 0x09, 0x00,
183 | 0x0d, 0x00, 0x20, 0x00, 0x20, 0x00, 0xa0, 0x00,
184 | 0xa0, 0x00, 0x80, 0x16, 0x80, 0x16, 0x00, 0x20,
185 | 0x0a, 0x20, 0x28, 0x20, 0x29, 0x20, 0x2f, 0x20,
186 | 0x2f, 0x20, 0x5f, 0x20, 0x5f, 0x20, 0x00, 0x30,
187 | 0x00, 0x30, 0xff, 0xfe, 0xff, 0xfe, 0x0a, 0x01,
188 | 0x0a, 0x00, 0x1c, 0x2c, 0x00, 0x00, 0x00, 0x00,
189 | 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0x7f, 0x01,
190 | 0x00, 0x00, 0x00, 0x15, 0x0a, 0x00, 0x09, 0x00,
191 | 0x0d, 0x00, 0x20, 0x00, 0x20, 0x00, 0xa0, 0x00,
192 | 0xa0, 0x00, 0x80, 0x16, 0x80, 0x16, 0x00, 0x20,
193 | 0x0a, 0x20, 0x28, 0x20, 0x29, 0x20, 0x2f, 0x20,
194 | 0x2f, 0x20, 0x5f, 0x20, 0x5f, 0x20, 0x00, 0x30,
195 | 0x00, 0x30, 0xff, 0xfe, 0xff, 0xfe, 0x0a, 0x07,
196 | 0x7e, 0x00, 0x00, 0x00, 0x1c, 0x2c, 0x00, 0x00,
197 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
198 | 0x7f, 0x01, 0x00, 0x00, 0x00, 0x15, 0x0a, 0x00,
199 | 0x09, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x00,
200 | 0xa0, 0x00, 0xa0, 0x00, 0x80, 0x16, 0x80, 0x16,
201 | 0x00, 0x20, 0x0a, 0x20, 0x28, 0x20, 0x29, 0x20,
202 | 0x2f, 0x20, 0x2f, 0x20, 0x5f, 0x20, 0x5f, 0x20,
203 | 0x00, 0x30, 0x00, 0x30, 0xff, 0xfe, 0xff, 0xfe,
204 | 0x0a, 0x01, 0x0a, 0x00, 0x1c, 0x2c, 0x00, 0x00,
205 | 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff,
206 | 0x7f, 0x01, 0x00, 0x00, 0x00, 0x15, 0x0a, 0x00,
207 | 0x09, 0x00, 0x0d, 0x00, 0x20, 0x00, 0x20, 0x00,
208 | 0xa0, 0x00, 0xa0, 0x00, 0x80, 0x16, 0x80, 0x16,
209 | 0x00, 0x20, 0x0a, 0x20, 0x28, 0x20, 0x29, 0x20,
210 | 0x2f, 0x20, 0x2f, 0x20, 0x5f, 0x20, 0x5f, 0x20,
211 | 0x00, 0x30, 0x00, 0x30, 0xff, 0xfe, 0xff, 0xfe,
212 | 0x0a, 0x06, 0x0c, 0x00, 0x0a,
213 | };
214 |
215 |
--------------------------------------------------------------------------------
/quickjs/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 |
--------------------------------------------------------------------------------
/preact.js:
--------------------------------------------------------------------------------
1 | var n,l,u,i,t,o,r = {},f = [],e = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i;function c(n, l) {for (var u in l) n[u] = l[u];return n;}function s(n) {var l = n.parentNode;l && l.removeChild(n);}function a(n, l, u) {var i,t,o,r = arguments,f = {};for (o in l) "key" == o ? i = l[o] : "ref" == o ? t = l[o] : f[o] = l[o];if (arguments.length > 3) for (u = [u], o = 3; o < arguments.length; o++) u.push(r[o]);if (null != u && (f.children = u), "function" == typeof n && null != n.defaultProps) for (o in n.defaultProps) void 0 === f[o] && (f[o] = n.defaultProps[o]);return v(n, f, i, t, null);}function v(l, u, i, t, o) {var r = { type: l, props: u, key: i, ref: t, __k: null, __: null, __b: 0, __e: null, __d: void 0, __c: null, __h: null, constructor: void 0, __v: null == o ? ++n.__v : o };return null != n.vnode && n.vnode(r), r;}function h() {return { current: null };}function y(n) {return n.children;}function p(n, l) {this.props = n, this.context = l;}function d(n, l) {if (null == l) return n.__ ? d(n.__, n.__.__k.indexOf(n) + 1) : null;for (var u; l < n.__k.length; l++) if (null != (u = n.__k[l]) && null != u.__e) return u.__e;return "function" == typeof n.type ? d(n) : null;}function _(n) {var l, u;if (null != (n = n.__) && null != n.__c) {for (n.__e = n.__c.base = null, l = 0; l < n.__k.length; l++) if (null != (u = n.__k[l]) && null != u.__e) {n.__e = n.__c.base = u.__e;break;}return _(n);}}function k(l) {(!l.__d && (l.__d = !0) && u.push(l) && !b.__r++ || t !== n.debounceRendering) && ((t = n.debounceRendering) || i)(b);}function b() {for (var n; b.__r = u.length;) n = u.sort(function (n, l) {return n.__v.__b - l.__v.__b;}), u = [], n.some(function (n) {var l, u, i, t, o, r;n.__d && (o = (t = (l = n).__v).__e, (r = l.__P) && (u = [], (i = c({}, t)).__v = t.__v + 1, I(r, t, i, l.__n, void 0 !== r.ownerSVGElement, null != t.__h ? [o] : null, u, null == o ? d(t) : o, t.__h), T(u, t), t.__e != o && _(t)));});}function m(n, l, u, i, t, o, e, c, s, a) {var h,p,_,k,b,m,w,A = i && i.__k || f,P = A.length;for (u.__k = [], h = 0; h < l.length; h++) if (null != (k = u.__k[h] = null == (k = l[h]) || "boolean" == typeof k ? null : "string" == typeof k || "number" == typeof k || "bigint" == typeof k ? v(null, k, null, null, k) : Array.isArray(k) ? v(y, { children: k }, null, null, null) : k.__b > 0 ? v(k.type, k.props, k.key, null, k.__v) : k)) {if (k.__ = u, k.__b = u.__b + 1, null === (_ = A[h]) || _ && k.key == _.key && k.type === _.type) A[h] = void 0;else for (p = 0; p < P; p++) {if ((_ = A[p]) && k.key == _.key && k.type === _.type) {A[p] = void 0;break;}_ = null;}I(n, k, _ = _ || r, t, o, e, c, s, a), b = k.__e, (p = k.ref) && _.ref != p && (w || (w = []), _.ref && w.push(_.ref, null, k), w.push(p, k.__c || b, k)), null != b ? (null == m && (m = b), "function" == typeof k.type && null != k.__k && k.__k === _.__k ? k.__d = s = g(k, s, n) : s = x(n, k, _, A, b, s), a || "option" !== u.type ? "function" == typeof u.type && (u.__d = s) : n.value = "") : s && _.__e == s && s.parentNode != n && (s = d(_));}for (u.__e = m, h = P; h--;) null != A[h] && ("function" == typeof u.type && null != A[h].__e && A[h].__e == u.__d && (u.__d = d(i, h + 1)), L(A[h], A[h]));if (w) for (h = 0; h < w.length; h++) z(w[h], w[++h], w[++h]);}function g(n, l, u) {var i, t;for (i = 0; i < n.__k.length; i++) (t = n.__k[i]) && (t.__ = n, l = "function" == typeof t.type ? g(t, l, u) : x(u, t, t, n.__k, t.__e, l));return l;}function w(n, l) {return l = l || [], null == n || "boolean" == typeof n || (Array.isArray(n) ? n.some(function (n) {w(n, l);}) : l.push(n)), l;}function x(n, l, u, i, t, o) {var r, f, e;if (void 0 !== l.__d) r = l.__d, l.__d = void 0;else if (null == u || t != o || null == t.parentNode) n: if (null == o || o.parentNode !== n) n.appendChild(t), r = null;else {for (f = o, e = 0; (f = f.nextSibling) && e < i.length; e += 2) if (f == t) break n;n.insertBefore(t, o), r = o;}return void 0 !== r ? r : t.nextSibling;}function A(n, l, u, i, t) {var o;for (o in u) "children" === o || "key" === o || o in l || C(n, o, null, u[o], i);for (o in l) t && "function" != typeof l[o] || "children" === o || "key" === o || "value" === o || "checked" === o || u[o] === l[o] || C(n, o, l[o], u[o], i);}function P(n, l, u) {"-" === l[0] ? n.setProperty(l, u) : n[l] = null == u ? "" : "number" != typeof u || e.test(l) ? u : u + "px";}function C(n, l, u, i, t) {var o;n: if ("style" === l) {if ("string" == typeof u) n.style.cssText = u;else {if ("string" == typeof i && (n.style.cssText = i = ""), i) for (l in i) u && l in u || P(n.style, l, "");if (u) for (l in u) i && u[l] === i[l] || P(n.style, l, u[l]);}} else if ("o" === l[0] && "n" === l[1]) o = l !== (l = l.replace(/Capture$/, "")), l = l.toLowerCase() in n ? l.toLowerCase().slice(2) : l.slice(2), n.l || (n.l = {}), n.l[l + o] = u, u ? i || n.addEventListener(l, o ? H : $, o) : n.removeEventListener(l, o ? H : $, o);else if ("dangerouslySetInnerHTML" !== l) {if (t) l = l.replace(/xlink[H:h]/, "h").replace(/sName$/, "s");else if ("href" !== l && "list" !== l && "form" !== l && "tabIndex" !== l && "download" !== l && l in n) try {n[l] = null == u ? "" : u;break n;} catch (n) {}"function" == typeof u || (null != u && (!1 !== u || "a" === l[0] && "r" === l[1]) ? n.setAttribute(l, u) : n.removeAttribute(l));}}function $(l) {this.l[l.type + !1](n.event ? n.event(l) : l);}function H(l) {this.l[l.type + !0](n.event ? n.event(l) : l);}function I(l, u, i, t, o, r, f, e, s) {var a,v,h,d,_,k,b,g,w,x,A,P = u.type;if (void 0 !== u.constructor) return null;null != i.__h && (s = i.__h, e = u.__e = i.__e, u.__h = null, r = [e]), (a = n.__b) && a(u);try {n: if ("function" == typeof P) {if (g = u.props, w = (a = P.contextType) && t[a.__c], x = a ? w ? w.props.value : a.__ : t, i.__c ? b = (v = u.__c = i.__c).__ = v.__E : ("prototype" in P && P.prototype.render ? u.__c = v = new P(g, x) : (u.__c = v = new p(g, x), v.constructor = P, v.render = M), w && w.sub(v), v.props = g, v.state || (v.state = {}), v.context = x, v.__n = t, h = v.__d = !0, v.__h = []), null == v.__s && (v.__s = v.state), null != P.getDerivedStateFromProps && (v.__s == v.state && (v.__s = c({}, v.__s)), c(v.__s, P.getDerivedStateFromProps(g, v.__s))), d = v.props, _ = v.state, h) null == P.getDerivedStateFromProps && null != v.componentWillMount && v.componentWillMount(), null != v.componentDidMount && v.__h.push(v.componentDidMount);else {if (null == P.getDerivedStateFromProps && g !== d && null != v.componentWillReceiveProps && v.componentWillReceiveProps(g, x), !v.__e && null != v.shouldComponentUpdate && !1 === v.shouldComponentUpdate(g, v.__s, x) || u.__v === i.__v) {v.props = g, v.state = v.__s, u.__v !== i.__v && (v.__d = !1), v.__v = u, u.__e = i.__e, u.__k = i.__k, u.__k.forEach(function (n) {n && (n.__ = u);}), v.__h.length && f.push(v);break n;}null != v.componentWillUpdate && v.componentWillUpdate(g, v.__s, x), null != v.componentDidUpdate && v.__h.push(function () {v.componentDidUpdate(d, _, k);});}v.context = x, v.props = g, v.state = v.__s, (a = n.__r) && a(u), v.__d = !1, v.__v = u, v.__P = l, a = v.render(v.props, v.state, v.context), v.state = v.__s, null != v.getChildContext && (t = c(c({}, t), v.getChildContext())), h || null == v.getSnapshotBeforeUpdate || (k = v.getSnapshotBeforeUpdate(d, _)), A = null != a && a.type === y && null == a.key ? a.props.children : a, m(l, Array.isArray(A) ? A : [A], u, i, t, o, r, f, e, s), v.base = u.__e, u.__h = null, v.__h.length && f.push(v), b && (v.__E = v.__ = null), v.__e = !1;} else null == r && u.__v === i.__v ? (u.__k = i.__k, u.__e = i.__e) : u.__e = j(i.__e, u, i, t, o, r, f, s);(a = n.diffed) && a(u);} catch (l) {u.__v = null, (s || null != r) && (u.__e = e, u.__h = !!s, r[r.indexOf(e)] = null), n.__e(l, u, i);}}function T(l, u) {n.__c && n.__c(u, l), l.some(function (u) {try {l = u.__h, u.__h = [], l.some(function (n) {n.call(u);});} catch (l) {n.__e(l, u.__v);}});}function j(n, l, u, i, t, o, e, c) {var a,v,h,y,p = u.props,d = l.props,_ = l.type,k = 0;if ("svg" === _ && (t = !0), null != o) for (; k < o.length; k++) if ((a = o[k]) && (a === n || (_ ? a.localName == _ : 3 == a.nodeType))) {n = a, o[k] = null;break;}if (null == n) {if (null === _) return document.createTextNode(d);n = t ? document.createElementNS("http://www.w3.org/2000/svg", _) : document.createElement(_, d.is && d), o = null, c = !1;}if (null === _) p === d || c && n.data === d || (n.data = d);else {if (o = o && f.slice.call(n.childNodes), v = (p = u.props || r).dangerouslySetInnerHTML, h = d.dangerouslySetInnerHTML, !c) {if (null != o) for (p = {}, y = 0; y < n.attributes.length; y++) p[n.attributes[y].name] = n.attributes[y].value;(h || v) && (h && (v && h.__html == v.__html || h.__html === n.innerHTML) || (n.innerHTML = h && h.__html || ""));}if (A(n, d, p, t, c), h) l.__k = [];else if (k = l.props.children, m(n, Array.isArray(k) ? k : [k], l, u, i, t && "foreignObject" !== _, o, e, n.firstChild, c), null != o) for (k = o.length; k--;) null != o[k] && s(o[k]);c || ("value" in d && void 0 !== (k = d.value) && (k !== n.value || "progress" === _ && !k) && C(n, "value", k, p.value, !1), "checked" in d && void 0 !== (k = d.checked) && k !== n.checked && C(n, "checked", k, p.checked, !1));}return n;}function z(l, u, i) {try {"function" == typeof l ? l(u) : l.current = u;} catch (l) {n.__e(l, i);}}function L(l, u, i) {var t, o, r;if (n.unmount && n.unmount(l), (t = l.ref) && (t.current && t.current !== l.__e || z(t, null, u)), i || "function" == typeof l.type || (i = null != (o = l.__e)), l.__e = l.__d = void 0, null != (t = l.__c)) {if (t.componentWillUnmount) try {t.componentWillUnmount();} catch (l) {n.__e(l, u);}t.base = t.__P = null;}if (t = l.__k) for (r = 0; r < t.length; r++) t[r] && L(t[r], u, i);null != o && s(o);}function M(n, l, u) {return this.constructor(n, u);}function N(l, u, i) {var t, o, e;n.__ && n.__(l, u), o = (t = "function" == typeof i) ? null : i && i.__k || u.__k, e = [], I(u, l = (!t && i || u).__k = a(y, null, [l]), o || r, r, void 0 !== u.ownerSVGElement, !t && i ? [i] : o ? null : u.firstChild ? f.slice.call(u.childNodes) : null, e, !t && i ? i : o ? o.__e : u.firstChild, t), T(e, l);}function O(n, l) {N(n, l, O);}function S(n, l, u) {var i,t,o,r = arguments,f = c({}, n.props);for (o in l) "key" == o ? i = l[o] : "ref" == o ? t = l[o] : f[o] = l[o];if (arguments.length > 3) for (u = [u], o = 3; o < arguments.length; o++) u.push(r[o]);return null != u && (f.children = u), v(n.type, f, i || n.key, t || n.ref, null);}function q(n, l) {var u = { __c: l = "__cC" + o++, __: n, Consumer: function (n, l) {return n.children(l);}, Provider: function (n) {var u, i;return this.getChildContext || (u = [], (i = {})[l] = this, this.getChildContext = function () {return i;}, this.shouldComponentUpdate = function (n) {this.props.value !== n.value && u.some(k);}, this.sub = function (n) {u.push(n);var l = n.componentWillUnmount;n.componentWillUnmount = function () {u.splice(u.indexOf(n), 1), l && l.call(n);};}), n.children;} };return u.Provider.__ = u.Consumer.contextType = u;}n = { __e: function (n, l) {for (var u, i, t; l = l.__;) if ((u = l.__c) && !u.__) try {if ((i = u.constructor) && null != i.getDerivedStateFromError && (u.setState(i.getDerivedStateFromError(n)), t = u.__d), null != u.componentDidCatch && (u.componentDidCatch(n), t = u.__d), t) return u.__E = u;} catch (l) {n = l;}throw n;}, __v: 0 }, l = function (n) {return null != n && void 0 === n.constructor;}, p.prototype.setState = function (n, l) {var u;u = null != this.__s && this.__s !== this.state ? this.__s : this.__s = c({}, this.state), "function" == typeof n && (n = n(c({}, u), this.props)), n && c(u, n), null != n && this.__v && (l && this.__h.push(l), k(this));}, p.prototype.forceUpdate = function (n) {this.__v && (this.__e = !0, n && this.__h.push(n), k(this));}, p.prototype.render = y, u = [], i = "function" == typeof Promise ? Promise.prototype.then.bind(Promise.resolve()) : setTimeout, b.__r = 0, o = 0;export { N as render, O as hydrate, a as createElement, a as h, y as Fragment, h as createRef, l as isValidElement, p as Component, S as cloneElement, q as createContext, w as toChildArray, n as options };
--------------------------------------------------------------------------------
/quickjs/tests/test_language.js:
--------------------------------------------------------------------------------
1 | function assert(actual, expected, message) {
2 | if (arguments.length == 1)
3 | expected = true;
4 |
5 | if (actual === expected)
6 | return;
7 |
8 | if (actual !== null && expected !== null
9 | && typeof actual == 'object' && typeof expected == 'object'
10 | && actual.toString() === expected.toString())
11 | return;
12 |
13 | throw Error("assertion failed: got |" + actual + "|" +
14 | ", expected |" + expected + "|" +
15 | (message ? " (" + message + ")" : ""));
16 | }
17 |
18 | function assert_throws(expected_error, func)
19 | {
20 | var err = false;
21 | try {
22 | func();
23 | } catch(e) {
24 | err = true;
25 | if (!(e instanceof expected_error)) {
26 | throw Error("unexpected exception type");
27 | }
28 | }
29 | if (!err) {
30 | throw Error("expected exception");
31 | }
32 | }
33 |
34 | // load more elaborate version of assert if available
35 | try { __loadScript("test_assert.js"); } catch(e) {}
36 |
37 | /*----------------*/
38 |
39 | function test_op1()
40 | {
41 | var r, a;
42 | r = 1 + 2;
43 | assert(r, 3, "1 + 2 === 3");
44 |
45 | r = 1 - 2;
46 | assert(r, -1, "1 - 2 === -1");
47 |
48 | r = -1;
49 | assert(r, -1, "-1 === -1");
50 |
51 | r = +2;
52 | assert(r, 2, "+2 === 2");
53 |
54 | r = 2 * 3;
55 | assert(r, 6, "2 * 3 === 6");
56 |
57 | r = 4 / 2;
58 | assert(r, 2, "4 / 2 === 2");
59 |
60 | r = 4 % 3;
61 | assert(r, 1, "4 % 3 === 3");
62 |
63 | r = 4 << 2;
64 | assert(r, 16, "4 << 2 === 16");
65 |
66 | r = 1 << 0;
67 | assert(r, 1, "1 << 0 === 1");
68 |
69 | r = 1 << 31;
70 | assert(r, -2147483648, "1 << 31 === -2147483648");
71 |
72 | r = 1 << 32;
73 | assert(r, 1, "1 << 32 === 1");
74 |
75 | r = (1 << 31) < 0;
76 | assert(r, true, "(1 << 31) < 0 === true");
77 |
78 | r = -4 >> 1;
79 | assert(r, -2, "-4 >> 1 === -2");
80 |
81 | r = -4 >>> 1;
82 | assert(r, 0x7ffffffe, "-4 >>> 1 === 0x7ffffffe");
83 |
84 | r = 1 & 1;
85 | assert(r, 1, "1 & 1 === 1");
86 |
87 | r = 0 | 1;
88 | assert(r, 1, "0 | 1 === 1");
89 |
90 | r = 1 ^ 1;
91 | assert(r, 0, "1 ^ 1 === 0");
92 |
93 | r = ~1;
94 | assert(r, -2, "~1 === -2");
95 |
96 | r = !1;
97 | assert(r, false, "!1 === false");
98 |
99 | assert((1 < 2), true, "(1 < 2) === true");
100 |
101 | assert((2 > 1), true, "(2 > 1) === true");
102 |
103 | assert(('b' > 'a'), true, "('b' > 'a') === true");
104 |
105 | assert(2 ** 8, 256, "2 ** 8 === 256");
106 | }
107 |
108 | function test_cvt()
109 | {
110 | assert((NaN | 0) === 0);
111 | assert((Infinity | 0) === 0);
112 | assert(((-Infinity) | 0) === 0);
113 | assert(("12345" | 0) === 12345);
114 | assert(("0x12345" | 0) === 0x12345);
115 | assert(((4294967296 * 3 - 4) | 0) === -4);
116 |
117 | assert(("12345" >>> 0) === 12345);
118 | assert(("0x12345" >>> 0) === 0x12345);
119 | assert((NaN >>> 0) === 0);
120 | assert((Infinity >>> 0) === 0);
121 | assert(((-Infinity) >>> 0) === 0);
122 | assert(((4294967296 * 3 - 4) >>> 0) === (4294967296 - 4));
123 | }
124 |
125 | function test_eq()
126 | {
127 | assert(null == undefined);
128 | assert(undefined == null);
129 | assert(true == 1);
130 | assert(0 == false);
131 | assert("" == 0);
132 | assert("123" == 123);
133 | assert("122" != 123);
134 | assert((new Number(1)) == 1);
135 | assert(2 == (new Number(2)));
136 | assert((new String("abc")) == "abc");
137 | assert({} != "abc");
138 | }
139 |
140 | function test_inc_dec()
141 | {
142 | var a, r;
143 |
144 | a = 1;
145 | r = a++;
146 | assert(r === 1 && a === 2, true, "++");
147 |
148 | a = 1;
149 | r = ++a;
150 | assert(r === 2 && a === 2, true, "++");
151 |
152 | a = 1;
153 | r = a--;
154 | assert(r === 1 && a === 0, true, "--");
155 |
156 | a = 1;
157 | r = --a;
158 | assert(r === 0 && a === 0, true, "--");
159 |
160 | a = {x:true};
161 | a.x++;
162 | assert(a.x, 2, "++");
163 |
164 | a = {x:true};
165 | a.x--;
166 | assert(a.x, 0, "--");
167 |
168 | a = [true];
169 | a[0]++;
170 | assert(a[0], 2, "++");
171 |
172 | a = {x:true};
173 | r = a.x++;
174 | assert(r === 1 && a.x === 2, true, "++");
175 |
176 | a = {x:true};
177 | r = a.x--;
178 | assert(r === 1 && a.x === 0, true, "--");
179 |
180 | a = [true];
181 | r = a[0]++;
182 | assert(r === 1 && a[0] === 2, true, "++");
183 |
184 | a = [true];
185 | r = a[0]--;
186 | assert(r === 1 && a[0] === 0, true, "--");
187 | }
188 |
189 | function F(x)
190 | {
191 | this.x = x;
192 | }
193 |
194 | function test_op2()
195 | {
196 | var a, b;
197 | a = new Object;
198 | a.x = 1;
199 | assert(a.x, 1, "new");
200 | b = new F(2);
201 | assert(b.x, 2, "new");
202 |
203 | a = {x : 2};
204 | assert(("x" in a), true, "in");
205 | assert(("y" in a), false, "in");
206 |
207 | a = {};
208 | assert((a instanceof Object), true, "instanceof");
209 | assert((a instanceof String), false, "instanceof");
210 |
211 | assert((typeof 1), "number", "typeof");
212 | assert((typeof Object), "function", "typeof");
213 | assert((typeof null), "object", "typeof");
214 | assert((typeof unknown_var), "undefined", "typeof");
215 |
216 | a = {x: 1, if: 2, async: 3};
217 | assert(a.if === 2);
218 | assert(a.async === 3);
219 | }
220 |
221 | function test_delete()
222 | {
223 | var a, err;
224 |
225 | a = {x: 1, y: 1};
226 | assert((delete a.x), true, "delete");
227 | assert(("x" in a), false, "delete");
228 |
229 | /* the following are not tested by test262 */
230 | assert(delete "abc"[100], true);
231 |
232 | err = false;
233 | try {
234 | delete null.a;
235 | } catch(e) {
236 | err = (e instanceof TypeError);
237 | }
238 | assert(err, true, "delete");
239 |
240 | err = false;
241 | try {
242 | a = { f() { delete super.a; } };
243 | a.f();
244 | } catch(e) {
245 | err = (e instanceof ReferenceError);
246 | }
247 | assert(err, true, "delete");
248 | }
249 |
250 | function test_prototype()
251 | {
252 | var f = function f() { };
253 | assert(f.prototype.constructor, f, "prototype");
254 |
255 | var g = function g() { };
256 | /* QuickJS bug */
257 | Object.defineProperty(g, "prototype", { writable: false });
258 | assert(g.prototype.constructor, g, "prototype");
259 | }
260 |
261 | function test_arguments()
262 | {
263 | function f2() {
264 | assert(arguments.length, 2, "arguments");
265 | assert(arguments[0], 1, "arguments");
266 | assert(arguments[1], 3, "arguments");
267 | }
268 | f2(1, 3);
269 | }
270 |
271 | function test_class()
272 | {
273 | var o;
274 | class C {
275 | constructor() {
276 | this.x = 10;
277 | }
278 | f() {
279 | return 1;
280 | }
281 | static F() {
282 | return -1;
283 | }
284 | get y() {
285 | return 12;
286 | }
287 | };
288 | class D extends C {
289 | constructor() {
290 | super();
291 | this.z = 20;
292 | }
293 | g() {
294 | return 2;
295 | }
296 | static G() {
297 | return -2;
298 | }
299 | h() {
300 | return super.f();
301 | }
302 | static H() {
303 | return super["F"]();
304 | }
305 | }
306 |
307 | assert(C.F() === -1);
308 | assert(Object.getOwnPropertyDescriptor(C.prototype, "y").get.name === "get y");
309 |
310 | o = new C();
311 | assert(o.f() === 1);
312 | assert(o.x === 10);
313 |
314 | assert(D.F() === -1);
315 | assert(D.G() === -2);
316 | assert(D.H() === -1);
317 |
318 | o = new D();
319 | assert(o.f() === 1);
320 | assert(o.g() === 2);
321 | assert(o.x === 10);
322 | assert(o.z === 20);
323 | assert(o.h() === 1);
324 |
325 | /* test class name scope */
326 | var E1 = class E { static F() { return E; } };
327 | assert(E1 === E1.F());
328 | };
329 |
330 | function test_template()
331 | {
332 | var a, b;
333 | b = 123;
334 | a = `abc${b}d`;
335 | assert(a, "abc123d");
336 |
337 | a = String.raw `abc${b}d`;
338 | assert(a, "abc123d");
339 |
340 | a = "aaa";
341 | b = "bbb";
342 | assert(`aaa${a, b}ccc`, "aaabbbccc");
343 | }
344 |
345 | function test_template_skip()
346 | {
347 | var a = "Bar";
348 | var { b = `${a + `a${a}` }baz` } = {};
349 | assert(b, "BaraBarbaz");
350 | }
351 |
352 | function test_object_literal()
353 | {
354 | var x = 0, get = 1, set = 2; async = 3;
355 | a = { get: 2, set: 3, async: 4 };
356 | assert(JSON.stringify(a), '{"get":2,"set":3,"async":4}');
357 |
358 | a = { x, get, set, async };
359 | assert(JSON.stringify(a), '{"x":0,"get":1,"set":2,"async":3}');
360 | }
361 |
362 | function test_regexp_skip()
363 | {
364 | var a, b;
365 | [a, b = /abc\(/] = [1];
366 | assert(a === 1);
367 |
368 | [a, b =/abc\(/] = [2];
369 | assert(a === 2);
370 | }
371 |
372 | function test_labels()
373 | {
374 | do x: { break x; } while(0);
375 | if (1)
376 | x: { break x; }
377 | else
378 | x: { break x; }
379 | with ({}) x: { break x; };
380 | while (0) x: { break x; };
381 | }
382 |
383 | function test_destructuring()
384 | {
385 | function * g () { return 0; };
386 | var [x] = g();
387 | assert(x, void 0);
388 | }
389 |
390 | function test_spread()
391 | {
392 | var x;
393 | x = [1, 2, ...[3, 4]];
394 | assert(x.toString(), "1,2,3,4");
395 |
396 | x = [ ...[ , ] ];
397 | assert(Object.getOwnPropertyNames(x).toString(), "0,length");
398 | }
399 |
400 | function test_function_length()
401 | {
402 | assert( ((a, b = 1, c) => {}).length, 1);
403 | assert( (([a,b]) => {}).length, 1);
404 | assert( (({a,b}) => {}).length, 1);
405 | assert( ((c, [a,b] = 1, d) => {}).length, 1);
406 | }
407 |
408 | function test_argument_scope()
409 | {
410 | var f;
411 | var c = "global";
412 |
413 | f = function(a = eval("var arguments")) {};
414 | assert_throws(SyntaxError, f);
415 |
416 | f = function(a = eval("1"), b = arguments[0]) { return b; };
417 | assert(f(12), 12);
418 |
419 | f = function(a, b = arguments[0]) { return b; };
420 | assert(f(12), 12);
421 |
422 | f = function(a, b = () => arguments) { return b; };
423 | assert(f(12)()[0], 12);
424 |
425 | f = function(a = eval("1"), b = () => arguments) { return b; };
426 | assert(f(12)()[0], 12);
427 |
428 | (function() {
429 | "use strict";
430 | f = function(a = this) { return a; };
431 | assert(f.call(123), 123);
432 |
433 | f = function f(a = f) { return a; };
434 | assert(f(), f);
435 |
436 | f = function f(a = eval("f")) { return a; };
437 | assert(f(), f);
438 | })();
439 |
440 | f = (a = eval("var c = 1"), probe = () => c) => {
441 | var c = 2;
442 | assert(c, 2);
443 | assert(probe(), 1);
444 | }
445 | f();
446 |
447 | f = (a = eval("var arguments = 1"), probe = () => arguments) => {
448 | var arguments = 2;
449 | assert(arguments, 2);
450 | assert(probe(), 1);
451 | }
452 | f();
453 |
454 | f = function f(a = eval("var c = 1"), b = c, probe = () => c) {
455 | assert(b, 1);
456 | assert(c, 1);
457 | assert(probe(), 1)
458 | }
459 | f();
460 |
461 | assert(c, "global");
462 | f = function f(a, b = c, probe = () => c) {
463 | eval("var c = 1");
464 | assert(c, 1);
465 | assert(b, "global");
466 | assert(probe(), "global")
467 | }
468 | f();
469 | assert(c, "global");
470 |
471 | f = function f(a = eval("var c = 1"), probe = (d = eval("c")) => d) {
472 | assert(probe(), 1)
473 | }
474 | f();
475 | }
476 |
477 | function test_function_expr_name()
478 | {
479 | var f;
480 |
481 | /* non strict mode test : assignment to the function name silently
482 | fails */
483 |
484 | f = function myfunc() {
485 | myfunc = 1;
486 | return myfunc;
487 | };
488 | assert(f(), f);
489 |
490 | f = function myfunc() {
491 | myfunc = 1;
492 | (() => {
493 | myfunc = 1;
494 | })();
495 | return myfunc;
496 | };
497 | assert(f(), f);
498 |
499 | f = function myfunc() {
500 | eval("myfunc = 1");
501 | return myfunc;
502 | };
503 | assert(f(), f);
504 |
505 | /* strict mode test : assignment to the function name raises a
506 | TypeError exception */
507 |
508 | f = function myfunc() {
509 | "use strict";
510 | myfunc = 1;
511 | };
512 | assert_throws(TypeError, f);
513 |
514 | f = function myfunc() {
515 | "use strict";
516 | (() => {
517 | myfunc = 1;
518 | })();
519 | };
520 | assert_throws(TypeError, f);
521 |
522 | f = function myfunc() {
523 | "use strict";
524 | eval("myfunc = 1");
525 | };
526 | assert_throws(TypeError, f);
527 | }
528 |
529 | test_op1();
530 | test_cvt();
531 | test_eq();
532 | test_inc_dec();
533 | test_op2();
534 | test_delete();
535 | test_prototype();
536 | test_arguments();
537 | test_class();
538 | test_template();
539 | test_template_skip();
540 | test_object_literal();
541 | test_regexp_skip();
542 | test_labels();
543 | test_destructuring();
544 | test_spread();
545 | test_function_length();
546 | test_argument_scope();
547 | test_function_expr_name();
548 |
--------------------------------------------------------------------------------
/quickjs/Makefile:
--------------------------------------------------------------------------------
1 | #
2 | # QuickJS Javascript Engine
3 | #
4 | # Copyright (c) 2017-2021 Fabrice Bellard
5 | # Copyright (c) 2017-2021 Charlie Gordon
6 | #
7 | # Permission is hereby granted, free of charge, to any person obtaining a copy
8 | # of this software and associated documentation files (the "Software"), to deal
9 | # in the Software without restriction, including without limitation the rights
10 | # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | # copies of the Software, and to permit persons to whom the Software is
12 | # furnished to do so, subject to the following conditions:
13 | #
14 | # The above copyright notice and this permission notice shall be included in
15 | # all copies or substantial portions of the Software.
16 | #
17 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | # THE SOFTWARE.
24 |
25 | ifeq ($(shell uname -s),Darwin)
26 | CONFIG_DARWIN=y
27 | endif
28 | # Windows cross compilation from Linux
29 | #CONFIG_WIN32=y
30 | # use link time optimization (smaller and faster executables but slower build)
31 | CONFIG_LTO=y
32 | # consider warnings as errors (for development)
33 | #CONFIG_WERROR=y
34 | # force 32 bit build for some utilities
35 | #CONFIG_M32=y
36 |
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 | ifdef CONFIG_M32
57 | CROSS_PREFIX=i686-w64-mingw32-
58 | else
59 | CROSS_PREFIX=x86_64-w64-mingw32-
60 | endif
61 | EXE=.exe
62 | else
63 | CROSS_PREFIX=
64 | EXE=
65 | endif
66 | ifdef CONFIG_CLANG
67 | HOST_CC=clang
68 | CC=$(CROSS_PREFIX)clang
69 | CFLAGS=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d
70 | CFLAGS += -Wextra
71 | CFLAGS += -Wno-sign-compare
72 | CFLAGS += -Wno-missing-field-initializers
73 | CFLAGS += -Wundef -Wuninitialized
74 | CFLAGS += -Wunused -Wno-unused-parameter
75 | CFLAGS += -Wwrite-strings
76 | CFLAGS += -Wchar-subscripts -funsigned-char
77 | CFLAGS += -MMD -MF $(OBJDIR)/$(@F).d
78 | ifdef CONFIG_DEFAULT_AR
79 | AR=$(CROSS_PREFIX)ar
80 | else
81 | ifdef CONFIG_LTO
82 | AR=$(CROSS_PREFIX)llvm-ar
83 | else
84 | AR=$(CROSS_PREFIX)ar
85 | endif
86 | endif
87 | else
88 | HOST_CC=gcc
89 | CC=$(CROSS_PREFIX)gcc
90 | CFLAGS=-g -Wall -MMD -MF $(OBJDIR)/$(@F).d
91 | CFLAGS += -Wno-array-bounds -Wno-format-truncation
92 | ifdef CONFIG_LTO
93 | AR=$(CROSS_PREFIX)gcc-ar
94 | else
95 | AR=$(CROSS_PREFIX)ar
96 | endif
97 | endif
98 | STRIP=$(CROSS_PREFIX)strip
99 | ifdef CONFIG_WERROR
100 | CFLAGS+=-Werror
101 | endif
102 | DEFINES:=-D_GNU_SOURCE -DCONFIG_VERSION=\"$(shell cat VERSION)\"
103 | ifdef CONFIG_BIGNUM
104 | DEFINES+=-DCONFIG_BIGNUM
105 | endif
106 | ifdef CONFIG_WIN32
107 | DEFINES+=-D__USE_MINGW_ANSI_STDIO # for standard snprintf behavior
108 | endif
109 |
110 | CFLAGS+=$(DEFINES)
111 | CFLAGS_DEBUG=$(CFLAGS) -O0
112 | CFLAGS_SMALL=$(CFLAGS) -Os
113 | CFLAGS_OPT=$(CFLAGS) -O2
114 | CFLAGS_NOLTO:=$(CFLAGS_OPT)
115 | LDFLAGS=-g
116 | ifdef CONFIG_LTO
117 | CFLAGS_SMALL+=-flto
118 | CFLAGS_OPT+=-flto
119 | LDFLAGS+=-flto
120 | endif
121 | ifdef CONFIG_PROFILE
122 | CFLAGS+=-p
123 | LDFLAGS+=-p
124 | endif
125 | ifdef CONFIG_ASAN
126 | CFLAGS+=-fsanitize=address -fno-omit-frame-pointer
127 | LDFLAGS+=-fsanitize=address -fno-omit-frame-pointer
128 | endif
129 | ifdef CONFIG_WIN32
130 | LDEXPORT=
131 | else
132 | LDEXPORT=-rdynamic
133 | endif
134 |
135 | PROGS=qjs$(EXE) qjsc$(EXE) run-test262
136 | ifneq ($(CROSS_PREFIX),)
137 | QJSC_CC=gcc
138 | QJSC=./host-qjsc
139 | PROGS+=$(QJSC)
140 | else
141 | QJSC_CC=$(CC)
142 | QJSC=./qjsc$(EXE)
143 | endif
144 | ifndef CONFIG_WIN32
145 | PROGS+=qjscalc
146 | endif
147 | ifdef CONFIG_M32
148 | PROGS+=qjs32 qjs32_s
149 | endif
150 | PROGS+=libquickjs.a
151 | ifdef CONFIG_LTO
152 | PROGS+=libquickjs.lto.a
153 | endif
154 |
155 | # examples
156 | ifeq ($(CROSS_PREFIX),)
157 | ifdef CONFIG_ASAN
158 | PROGS+=
159 | else
160 | PROGS+=examples/hello examples/hello_module examples/test_fib
161 | ifndef CONFIG_DARWIN
162 | PROGS+=examples/fib.so examples/point.so
163 | endif
164 | endif
165 | endif
166 |
167 | all: $(OBJDIR) $(OBJDIR)/quickjs.check.o $(OBJDIR)/qjs.check.o $(PROGS)
168 |
169 | QJS_LIB_OBJS=$(OBJDIR)/quickjs.o $(OBJDIR)/libregexp.o $(OBJDIR)/libunicode.o $(OBJDIR)/cutils.o $(OBJDIR)/quickjs-libc.o
170 |
171 | QJS_OBJS=$(OBJDIR)/qjs.o $(OBJDIR)/repl.o $(QJS_LIB_OBJS)
172 | ifdef CONFIG_BIGNUM
173 | QJS_LIB_OBJS+=$(OBJDIR)/libbf.o
174 | QJS_OBJS+=$(OBJDIR)/qjscalc.o
175 | endif
176 |
177 | HOST_LIBS=-lm -ldl -lpthread
178 | LIBS=-lm
179 | ifndef CONFIG_WIN32
180 | LIBS+=-ldl -lpthread
181 | endif
182 | LIBS+=$(EXTRA_LIBS)
183 |
184 | $(OBJDIR):
185 | mkdir -p $(OBJDIR) $(OBJDIR)/examples $(OBJDIR)/tests
186 |
187 | qjs$(EXE): $(QJS_OBJS)
188 | $(CC) $(LDFLAGS) $(LDEXPORT) -o $@ $^ $(LIBS)
189 |
190 | qjs-debug$(EXE): $(patsubst %.o, %.debug.o, $(QJS_OBJS))
191 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
192 |
193 | qjsc$(EXE): $(OBJDIR)/qjsc.o $(QJS_LIB_OBJS)
194 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
195 |
196 | ifneq ($(CROSS_PREFIX),)
197 |
198 | $(QJSC): $(OBJDIR)/qjsc.host.o \
199 | $(patsubst %.o, %.host.o, $(QJS_LIB_OBJS))
200 | $(HOST_CC) $(LDFLAGS) -o $@ $^ $(HOST_LIBS)
201 |
202 | endif #CROSS_PREFIX
203 |
204 | QJSC_DEFINES:=-DCONFIG_CC=\"$(QJSC_CC)\" -DCONFIG_PREFIX=\"$(prefix)\"
205 | ifdef CONFIG_LTO
206 | QJSC_DEFINES+=-DCONFIG_LTO
207 | endif
208 | QJSC_HOST_DEFINES:=-DCONFIG_CC=\"$(HOST_CC)\" -DCONFIG_PREFIX=\"$(prefix)\"
209 |
210 | $(OBJDIR)/qjsc.o: CFLAGS+=$(QJSC_DEFINES)
211 | $(OBJDIR)/qjsc.host.o: CFLAGS+=$(QJSC_HOST_DEFINES)
212 |
213 | qjs32: $(patsubst %.o, %.m32.o, $(QJS_OBJS))
214 | $(CC) -m32 $(LDFLAGS) $(LDEXPORT) -o $@ $^ $(LIBS)
215 |
216 | qjs32_s: $(patsubst %.o, %.m32s.o, $(QJS_OBJS))
217 | $(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS)
218 | @size $@
219 |
220 | qjscalc: qjs
221 | ln -sf $< $@
222 |
223 | ifdef CONFIG_LTO
224 | LTOEXT=.lto
225 | else
226 | LTOEXT=
227 | endif
228 |
229 | libquickjs$(LTOEXT).a: $(QJS_LIB_OBJS)
230 | $(AR) rcs $@ $^
231 |
232 | ifdef CONFIG_LTO
233 | libquickjs.a: $(patsubst %.o, %.nolto.o, $(QJS_LIB_OBJS))
234 | $(AR) rcs $@ $^
235 | endif # CONFIG_LTO
236 |
237 | repl.c: $(QJSC) repl.js
238 | $(QJSC) -c -o $@ -m repl.js
239 |
240 | qjscalc.c: $(QJSC) qjscalc.js
241 | $(QJSC) -fbignum -c -o $@ qjscalc.js
242 |
243 | ifneq ($(wildcard unicode/UnicodeData.txt),)
244 | $(OBJDIR)/libunicode.o $(OBJDIR)/libunicode.m32.o $(OBJDIR)/libunicode.m32s.o \
245 | $(OBJDIR)/libunicode.nolto.o: libunicode-table.h
246 |
247 | libunicode-table.h: unicode_gen
248 | ./unicode_gen unicode $@
249 | endif
250 |
251 | run-test262: $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS)
252 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
253 |
254 | run-test262-debug: $(patsubst %.o, %.debug.o, $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS))
255 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
256 |
257 | run-test262-32: $(patsubst %.o, %.m32.o, $(OBJDIR)/run-test262.o $(QJS_LIB_OBJS))
258 | $(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS)
259 |
260 | # object suffix order: nolto, [m32|m32s]
261 |
262 | $(OBJDIR)/%.o: %.c | $(OBJDIR)
263 | $(CC) $(CFLAGS_OPT) -c -o $@ $<
264 |
265 | $(OBJDIR)/%.host.o: %.c | $(OBJDIR)
266 | $(HOST_CC) $(CFLAGS_OPT) -c -o $@ $<
267 |
268 | $(OBJDIR)/%.pic.o: %.c | $(OBJDIR)
269 | $(CC) $(CFLAGS_OPT) -fPIC -DJS_SHARED_LIBRARY -c -o $@ $<
270 |
271 | $(OBJDIR)/%.nolto.o: %.c | $(OBJDIR)
272 | $(CC) $(CFLAGS_NOLTO) -c -o $@ $<
273 |
274 | $(OBJDIR)/%.m32.o: %.c | $(OBJDIR)
275 | $(CC) -m32 $(CFLAGS_OPT) -c -o $@ $<
276 |
277 | $(OBJDIR)/%.m32s.o: %.c | $(OBJDIR)
278 | $(CC) -m32 $(CFLAGS_SMALL) -c -o $@ $<
279 |
280 | $(OBJDIR)/%.debug.o: %.c | $(OBJDIR)
281 | $(CC) $(CFLAGS_DEBUG) -c -o $@ $<
282 |
283 | $(OBJDIR)/%.check.o: %.c | $(OBJDIR)
284 | $(CC) $(CFLAGS) -DCONFIG_CHECK_JSVALUE -c -o $@ $<
285 |
286 | regexp_test: libregexp.c libunicode.c cutils.c
287 | $(CC) $(LDFLAGS) $(CFLAGS) -DTEST -o $@ libregexp.c libunicode.c cutils.c $(LIBS)
288 |
289 | unicode_gen: $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o libunicode.c unicode_gen_def.h
290 | $(HOST_CC) $(LDFLAGS) $(CFLAGS) -o $@ $(OBJDIR)/unicode_gen.host.o $(OBJDIR)/cutils.host.o
291 |
292 | clean:
293 | rm -f repl.c qjscalc.c out.c
294 | rm -f *.a *.o *.d *~ unicode_gen regexp_test $(PROGS)
295 | rm -f hello.c test_fib.c
296 | rm -f examples/*.so tests/*.so
297 | rm -rf $(OBJDIR)/ *.dSYM/ qjs-debug
298 | rm -rf run-test262-debug run-test262-32
299 |
300 | install: all
301 | mkdir -p "$(DESTDIR)$(prefix)/bin"
302 | $(STRIP) qjs qjsc
303 | install -m755 qjs qjsc "$(DESTDIR)$(prefix)/bin"
304 | ln -sf qjs "$(DESTDIR)$(prefix)/bin/qjscalc"
305 | mkdir -p "$(DESTDIR)$(prefix)/lib/quickjs"
306 | install -m644 libquickjs.a "$(DESTDIR)$(prefix)/lib/quickjs"
307 | ifdef CONFIG_LTO
308 | install -m644 libquickjs.lto.a "$(DESTDIR)$(prefix)/lib/quickjs"
309 | endif
310 | mkdir -p "$(DESTDIR)$(prefix)/include/quickjs"
311 | install -m644 quickjs.h quickjs-libc.h "$(DESTDIR)$(prefix)/include/quickjs"
312 |
313 | ###############################################################################
314 | # examples
315 |
316 | # example of static JS compilation
317 | HELLO_SRCS=examples/hello.js
318 | HELLO_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \
319 | -fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \
320 | -fno-date -fno-module-loader
321 | ifdef CONFIG_BIGNUM
322 | HELLO_OPTS+=-fno-bigint
323 | endif
324 |
325 | hello.c: $(QJSC) $(HELLO_SRCS)
326 | $(QJSC) -e $(HELLO_OPTS) -o $@ $(HELLO_SRCS)
327 |
328 | ifdef CONFIG_M32
329 | examples/hello: $(OBJDIR)/hello.m32s.o $(patsubst %.o, %.m32s.o, $(QJS_LIB_OBJS))
330 | $(CC) -m32 $(LDFLAGS) -o $@ $^ $(LIBS)
331 | else
332 | examples/hello: $(OBJDIR)/hello.o $(QJS_LIB_OBJS)
333 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
334 | endif
335 |
336 | # example of static JS compilation with modules
337 | HELLO_MODULE_SRCS=examples/hello_module.js
338 | HELLO_MODULE_OPTS=-fno-string-normalize -fno-map -fno-promise -fno-typedarray \
339 | -fno-typedarray -fno-regexp -fno-json -fno-eval -fno-proxy \
340 | -fno-date -m
341 | examples/hello_module: $(QJSC) libquickjs$(LTOEXT).a $(HELLO_MODULE_SRCS)
342 | $(QJSC) $(HELLO_MODULE_OPTS) -o $@ $(HELLO_MODULE_SRCS)
343 |
344 | # use of an external C module (static compilation)
345 |
346 | test_fib.c: $(QJSC) examples/test_fib.js
347 | $(QJSC) -e -M examples/fib.so,fib -m -o $@ examples/test_fib.js
348 |
349 | examples/test_fib: $(OBJDIR)/test_fib.o $(OBJDIR)/examples/fib.o libquickjs$(LTOEXT).a
350 | $(CC) $(LDFLAGS) -o $@ $^ $(LIBS)
351 |
352 | examples/fib.so: $(OBJDIR)/examples/fib.pic.o
353 | $(CC) $(LDFLAGS) -shared -o $@ $^
354 |
355 | examples/point.so: $(OBJDIR)/examples/point.pic.o
356 | $(CC) $(LDFLAGS) -shared -o $@ $^
357 |
358 | ###############################################################################
359 | # documentation
360 |
361 | DOCS=doc/quickjs.pdf doc/quickjs.html doc/jsbignum.pdf doc/jsbignum.html
362 |
363 | build_doc: $(DOCS)
364 |
365 | clean_doc:
366 | rm -f $(DOCS)
367 |
368 | doc/%.pdf: doc/%.texi
369 | texi2pdf --clean -o $@ -q $<
370 |
371 | doc/%.html.pre: doc/%.texi
372 | makeinfo --html --no-headers --no-split --number-sections -o $@ $<
373 |
374 | doc/%.html: doc/%.html.pre
375 | sed -e 's||\n|' < $< > $@
376 |
377 | ###############################################################################
378 | # tests
379 |
380 | ifndef CONFIG_DARWIN
381 | test: tests/bjson.so examples/point.so
382 | endif
383 | ifdef CONFIG_M32
384 | test: qjs32
385 | endif
386 |
387 | test: qjs
388 | ./qjs tests/test_closure.js
389 | ./qjs tests/test_language.js
390 | ./qjs tests/test_builtin.js
391 | ./qjs tests/test_loop.js
392 | ./qjs tests/test_std.js
393 | ./qjs tests/test_worker.js
394 | ifndef CONFIG_DARWIN
395 | ifdef CONFIG_BIGNUM
396 | ./qjs --bignum tests/test_bjson.js
397 | else
398 | ./qjs tests/test_bjson.js
399 | endif
400 | ./qjs examples/test_point.js
401 | endif
402 | ifdef CONFIG_BIGNUM
403 | ./qjs --bignum tests/test_op_overloading.js
404 | ./qjs --bignum tests/test_bignum.js
405 | ./qjs --qjscalc tests/test_qjscalc.js
406 | endif
407 | ifdef CONFIG_M32
408 | ./qjs32 tests/test_closure.js
409 | ./qjs32 tests/test_language.js
410 | ./qjs32 tests/test_builtin.js
411 | ./qjs32 tests/test_loop.js
412 | ./qjs32 tests/test_std.js
413 | ./qjs32 tests/test_worker.js
414 | ifdef CONFIG_BIGNUM
415 | ./qjs32 --bignum tests/test_op_overloading.js
416 | ./qjs32 --bignum tests/test_bignum.js
417 | ./qjs32 --qjscalc tests/test_qjscalc.js
418 | endif
419 | endif
420 |
421 | stats: qjs qjs32
422 | ./qjs -qd
423 | ./qjs32 -qd
424 |
425 | microbench: qjs
426 | ./qjs tests/microbench.js
427 |
428 | microbench-32: qjs32
429 | ./qjs32 tests/microbench.js
430 |
431 | # ES5 tests (obsolete)
432 | test2o: run-test262
433 | time ./run-test262 -m -c test262o.conf
434 |
435 | test2o-32: run-test262-32
436 | time ./run-test262-32 -m -c test262o.conf
437 |
438 | test2o-update: run-test262
439 | ./run-test262 -u -c test262o.conf
440 |
441 | # Test262 tests
442 | test2-default: run-test262
443 | time ./run-test262 -m -c test262.conf
444 |
445 | test2: run-test262
446 | time ./run-test262 -m -c test262.conf -a
447 |
448 | test2-32: run-test262-32
449 | time ./run-test262-32 -m -c test262.conf -a
450 |
451 | test2-update: run-test262
452 | ./run-test262 -u -c test262.conf -a
453 |
454 | test2-check: run-test262
455 | time ./run-test262 -m -c test262.conf -E -a
456 |
457 | testall: all test microbench test2o test2
458 |
459 | testall-32: all test-32 microbench-32 test2o-32 test2-32
460 |
461 | testall-complete: testall testall-32
462 |
463 | bench-v8: qjs
464 | make -C tests/bench-v8
465 | ./qjs -d tests/bench-v8/combined.js
466 |
467 | tests/bjson.so: $(OBJDIR)/tests/bjson.pic.o
468 | $(CC) $(LDFLAGS) -shared -o $@ $^ $(LIBS)
469 |
470 | -include $(wildcard $(OBJDIR)/*.d)
471 |
--------------------------------------------------------------------------------