@zappdev/cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (209) hide show
  1. package/README.md +55 -0
  2. package/dist/zapp-cli.js +9471 -0
  3. package/native/src/app/app.zc +490 -0
  4. package/native/src/event/event.zc +24 -0
  5. package/native/src/event/events.zc +70 -0
  6. package/native/src/platform/darwin/backend.zc +923 -0
  7. package/native/src/platform/darwin/backend_bootstrap.zc +9 -0
  8. package/native/src/platform/darwin/bootstrap.zc +9 -0
  9. package/native/src/platform/darwin/engine_jsc.zc +86 -0
  10. package/native/src/platform/darwin/engine_qjs.zc +92 -0
  11. package/native/src/platform/darwin/platform.zc +156 -0
  12. package/native/src/platform/darwin/webview.zc +550 -0
  13. package/native/src/platform/darwin/webview_bootstrap.zc +9 -0
  14. package/native/src/platform/darwin/window.zc +1223 -0
  15. package/native/src/platform/darwin/worker/common.zc +223 -0
  16. package/native/src/platform/darwin/worker/core/base64_core.zc +29 -0
  17. package/native/src/platform/darwin/worker/core/crypto_core.zc +19 -0
  18. package/native/src/platform/darwin/worker/core/encoding_core.zc +32 -0
  19. package/native/src/platform/darwin/worker/core/fetch_core.zc +145 -0
  20. package/native/src/platform/darwin/worker/core/url_core.zc +69 -0
  21. package/native/src/platform/darwin/worker/core/websocket_core.zc +179 -0
  22. package/native/src/platform/darwin/worker/dispatch.zc +55 -0
  23. package/native/src/platform/darwin/worker/jsc/base64_jsc.zc +39 -0
  24. package/native/src/platform/darwin/worker/jsc/crypto_jsc.zc +49 -0
  25. package/native/src/platform/darwin/worker/jsc/encoding_jsc.zc +86 -0
  26. package/native/src/platform/darwin/worker/jsc/fetch_jsc.zc +149 -0
  27. package/native/src/platform/darwin/worker/jsc/url_jsc.zc +54 -0
  28. package/native/src/platform/darwin/worker/jsc/websocket_jsc.zc +127 -0
  29. package/native/src/platform/darwin/worker/jsc.zc +670 -0
  30. package/native/src/platform/darwin/worker/mod.zc +30 -0
  31. package/native/src/platform/darwin/worker/qjs/fetch_qjs.zc +233 -0
  32. package/native/src/platform/darwin/worker/qjs/qjs_macros.zc +23 -0
  33. package/native/src/platform/darwin/worker/qjs/websocket_qjs.zc +223 -0
  34. package/native/src/platform/darwin/worker/qjs.zc +1053 -0
  35. package/native/src/platform/darwin/worker/timers.zc +149 -0
  36. package/native/src/platform/darwin/worker/timers_qjs.zc +209 -0
  37. package/native/src/platform/platform.zc +64 -0
  38. package/native/src/platform/shared/log.zc +156 -0
  39. package/native/src/platform/shared/worker/qjs/base64_qjs.zc +38 -0
  40. package/native/src/platform/shared/worker/qjs/crypto_qjs.zc +44 -0
  41. package/native/src/platform/shared/worker/qjs/encoding_qjs.zc +95 -0
  42. package/native/src/platform/shared/worker/qjs/url_qjs.zc +65 -0
  43. package/native/src/platform/shared/worker_registry.zc +206 -0
  44. package/native/src/platform/window.zc +446 -0
  45. package/native/src/platform/windows/backend.zc +452 -0
  46. package/native/src/platform/windows/backend_bootstrap.zc +9 -0
  47. package/native/src/platform/windows/bootstrap.zc +9 -0
  48. package/native/src/platform/windows/engine_qjs.zc +60 -0
  49. package/native/src/platform/windows/platform.zc +387 -0
  50. package/native/src/platform/windows/webview.zc +1175 -0
  51. package/native/src/platform/windows/webview_bootstrap.zc +9 -0
  52. package/native/src/platform/windows/window.zc +1271 -0
  53. package/native/src/platform/windows/worker/common.zc +409 -0
  54. package/native/src/platform/windows/worker/core/base64_core.zc +52 -0
  55. package/native/src/platform/windows/worker/core/crypto_core.zc +34 -0
  56. package/native/src/platform/windows/worker/core/encoding_core.zc +60 -0
  57. package/native/src/platform/windows/worker/core/fetch_core.zc +274 -0
  58. package/native/src/platform/windows/worker/core/url_core.zc +216 -0
  59. package/native/src/platform/windows/worker/core/websocket_core.zc +343 -0
  60. package/native/src/platform/windows/worker/dispatch.zc +34 -0
  61. package/native/src/platform/windows/worker/mod.zc +46 -0
  62. package/native/src/platform/windows/worker/qjs/fetch_qjs.zc +255 -0
  63. package/native/src/platform/windows/worker/qjs/websocket_qjs.zc +263 -0
  64. package/native/src/platform/windows/worker/qjs.zc +1049 -0
  65. package/native/src/platform/windows/worker/timers_qjs.zc +288 -0
  66. package/native/src/platform/worker.zc +8 -0
  67. package/native/src/service/service.zc +228 -0
  68. package/native/vendor/quickjs-ng/.gitattributes +4 -0
  69. package/native/vendor/quickjs-ng/.github/dependabot.yml +7 -0
  70. package/native/vendor/quickjs-ng/.github/workflows/ci.yml +812 -0
  71. package/native/vendor/quickjs-ng/.github/workflows/docs.yml +49 -0
  72. package/native/vendor/quickjs-ng/.github/workflows/release.yml +162 -0
  73. package/native/vendor/quickjs-ng/.github/workflows/test-docs.yml +23 -0
  74. package/native/vendor/quickjs-ng/.github/workflows/tsan.yml +32 -0
  75. package/native/vendor/quickjs-ng/.github/workflows/valgrind.yml +33 -0
  76. package/native/vendor/quickjs-ng/.gitmodules +5 -0
  77. package/native/vendor/quickjs-ng/CMakeLists.txt +553 -0
  78. package/native/vendor/quickjs-ng/LICENSE +24 -0
  79. package/native/vendor/quickjs-ng/Makefile +149 -0
  80. package/native/vendor/quickjs-ng/amalgam.js +53 -0
  81. package/native/vendor/quickjs-ng/api-test.c +927 -0
  82. package/native/vendor/quickjs-ng/builtin-array-fromasync.h +119 -0
  83. package/native/vendor/quickjs-ng/builtin-array-fromasync.js +36 -0
  84. package/native/vendor/quickjs-ng/builtin-iterator-zip-keyed.h +332 -0
  85. package/native/vendor/quickjs-ng/builtin-iterator-zip-keyed.js +194 -0
  86. package/native/vendor/quickjs-ng/builtin-iterator-zip.h +337 -0
  87. package/native/vendor/quickjs-ng/builtin-iterator-zip.js +210 -0
  88. package/native/vendor/quickjs-ng/ctest.c +17 -0
  89. package/native/vendor/quickjs-ng/cutils.h +2013 -0
  90. package/native/vendor/quickjs-ng/cxxtest.cc +2 -0
  91. package/native/vendor/quickjs-ng/dtoa.c +1619 -0
  92. package/native/vendor/quickjs-ng/dtoa.h +87 -0
  93. package/native/vendor/quickjs-ng/examples/fib.c +67 -0
  94. package/native/vendor/quickjs-ng/examples/fib_module.js +10 -0
  95. package/native/vendor/quickjs-ng/examples/hello.js +1 -0
  96. package/native/vendor/quickjs-ng/examples/hello_module.js +6 -0
  97. package/native/vendor/quickjs-ng/examples/meson.build +17 -0
  98. package/native/vendor/quickjs-ng/examples/pi_bigint.js +118 -0
  99. package/native/vendor/quickjs-ng/examples/point.c +154 -0
  100. package/native/vendor/quickjs-ng/examples/test_fib.js +8 -0
  101. package/native/vendor/quickjs-ng/examples/test_point.js +43 -0
  102. package/native/vendor/quickjs-ng/fuzz.c +51 -0
  103. package/native/vendor/quickjs-ng/gen/function_source.c +81 -0
  104. package/native/vendor/quickjs-ng/gen/hello.c +53 -0
  105. package/native/vendor/quickjs-ng/gen/hello_module.c +106 -0
  106. package/native/vendor/quickjs-ng/gen/repl.c +3053 -0
  107. package/native/vendor/quickjs-ng/gen/standalone.c +324 -0
  108. package/native/vendor/quickjs-ng/gen/test_fib.c +81 -0
  109. package/native/vendor/quickjs-ng/libregexp-opcode.h +58 -0
  110. package/native/vendor/quickjs-ng/libregexp.c +2687 -0
  111. package/native/vendor/quickjs-ng/libregexp.h +98 -0
  112. package/native/vendor/quickjs-ng/libunicode-table.h +4707 -0
  113. package/native/vendor/quickjs-ng/libunicode.c +1746 -0
  114. package/native/vendor/quickjs-ng/libunicode.h +126 -0
  115. package/native/vendor/quickjs-ng/list.h +107 -0
  116. package/native/vendor/quickjs-ng/lre-test.c +73 -0
  117. package/native/vendor/quickjs-ng/meson.build +684 -0
  118. package/native/vendor/quickjs-ng/meson_options.txt +6 -0
  119. package/native/vendor/quickjs-ng/qjs-wasi-reactor.c +208 -0
  120. package/native/vendor/quickjs-ng/qjs.c +748 -0
  121. package/native/vendor/quickjs-ng/qjsc.c +673 -0
  122. package/native/vendor/quickjs-ng/quickjs-atom.h +267 -0
  123. package/native/vendor/quickjs-ng/quickjs-c-atomics.h +54 -0
  124. package/native/vendor/quickjs-ng/quickjs-libc.c +4986 -0
  125. package/native/vendor/quickjs-ng/quickjs-libc.h +79 -0
  126. package/native/vendor/quickjs-ng/quickjs-opcode.h +369 -0
  127. package/native/vendor/quickjs-ng/quickjs.c +60259 -0
  128. package/native/vendor/quickjs-ng/quickjs.h +1419 -0
  129. package/native/vendor/quickjs-ng/repl.js +1927 -0
  130. package/native/vendor/quickjs-ng/run-test262.c +2417 -0
  131. package/native/vendor/quickjs-ng/standalone.js +129 -0
  132. package/native/vendor/quickjs-ng/tests/assert.js +49 -0
  133. package/native/vendor/quickjs-ng/tests/bug1221.js +16 -0
  134. package/native/vendor/quickjs-ng/tests/bug1296.js +12 -0
  135. package/native/vendor/quickjs-ng/tests/bug1297.js +22 -0
  136. package/native/vendor/quickjs-ng/tests/bug1301.js +21 -0
  137. package/native/vendor/quickjs-ng/tests/bug1302.js +24 -0
  138. package/native/vendor/quickjs-ng/tests/bug1305.js +26 -0
  139. package/native/vendor/quickjs-ng/tests/bug1318.js +54 -0
  140. package/native/vendor/quickjs-ng/tests/bug1352.js +8 -0
  141. package/native/vendor/quickjs-ng/tests/bug1354.js +6 -0
  142. package/native/vendor/quickjs-ng/tests/bug1355.js +58 -0
  143. package/native/vendor/quickjs-ng/tests/bug1368.js +9 -0
  144. package/native/vendor/quickjs-ng/tests/bug39/1.js +6 -0
  145. package/native/vendor/quickjs-ng/tests/bug39/2.js +6 -0
  146. package/native/vendor/quickjs-ng/tests/bug39/3.js +7 -0
  147. package/native/vendor/quickjs-ng/tests/bug488-upstream.js +7 -0
  148. package/native/vendor/quickjs-ng/tests/bug633/0.js +7 -0
  149. package/native/vendor/quickjs-ng/tests/bug633/1.js +4 -0
  150. package/native/vendor/quickjs-ng/tests/bug633/2.js +4 -0
  151. package/native/vendor/quickjs-ng/tests/bug633/3.js +4 -0
  152. package/native/vendor/quickjs-ng/tests/bug645/0.js +4 -0
  153. package/native/vendor/quickjs-ng/tests/bug645/1.js +9 -0
  154. package/native/vendor/quickjs-ng/tests/bug645/2.js +7 -0
  155. package/native/vendor/quickjs-ng/tests/bug648.js +13 -0
  156. package/native/vendor/quickjs-ng/tests/bug652.js +4 -0
  157. package/native/vendor/quickjs-ng/tests/bug741.js +19 -0
  158. package/native/vendor/quickjs-ng/tests/bug775.js +7 -0
  159. package/native/vendor/quickjs-ng/tests/bug776.js +7 -0
  160. package/native/vendor/quickjs-ng/tests/bug832.js +2 -0
  161. package/native/vendor/quickjs-ng/tests/bug858.js +26 -0
  162. package/native/vendor/quickjs-ng/tests/bug904.js +6 -0
  163. package/native/vendor/quickjs-ng/tests/bug988.js +7 -0
  164. package/native/vendor/quickjs-ng/tests/bug999.js +3 -0
  165. package/native/vendor/quickjs-ng/tests/destructured-export.js +8 -0
  166. package/native/vendor/quickjs-ng/tests/detect_module/0.js +1 -0
  167. package/native/vendor/quickjs-ng/tests/detect_module/1.js +2 -0
  168. package/native/vendor/quickjs-ng/tests/detect_module/2.js +1 -0
  169. package/native/vendor/quickjs-ng/tests/detect_module/3.js +8 -0
  170. package/native/vendor/quickjs-ng/tests/detect_module/4.js +3 -0
  171. package/native/vendor/quickjs-ng/tests/empty.js +0 -0
  172. package/native/vendor/quickjs-ng/tests/fixture_cyclic_import.js +2 -0
  173. package/native/vendor/quickjs-ng/tests/fixture_string_exports.js +12 -0
  174. package/native/vendor/quickjs-ng/tests/function_source.js +14 -0
  175. package/native/vendor/quickjs-ng/tests/microbench.js +1267 -0
  176. package/native/vendor/quickjs-ng/tests/null_or_undefined.js +38 -0
  177. package/native/vendor/quickjs-ng/tests/str-pad-leak.js +5 -0
  178. package/native/vendor/quickjs-ng/tests/test_bigint.js +107 -0
  179. package/native/vendor/quickjs-ng/tests/test_bjson.js +366 -0
  180. package/native/vendor/quickjs-ng/tests/test_builtin.js +1314 -0
  181. package/native/vendor/quickjs-ng/tests/test_closure.js +220 -0
  182. package/native/vendor/quickjs-ng/tests/test_cyclic_import.js +12 -0
  183. package/native/vendor/quickjs-ng/tests/test_domexception.js +35 -0
  184. package/native/vendor/quickjs-ng/tests/test_language.js +755 -0
  185. package/native/vendor/quickjs-ng/tests/test_loop.js +367 -0
  186. package/native/vendor/quickjs-ng/tests/test_queue_microtask.js +39 -0
  187. package/native/vendor/quickjs-ng/tests/test_std.js +340 -0
  188. package/native/vendor/quickjs-ng/tests/test_string_exports.js +25 -0
  189. package/native/vendor/quickjs-ng/tests/test_worker.js +43 -0
  190. package/native/vendor/quickjs-ng/tests/test_worker_module.js +30 -0
  191. package/native/vendor/quickjs-ng/tests.conf +14 -0
  192. package/native/vendor/quickjs-ng/unicode_download.sh +19 -0
  193. package/native/vendor/quickjs-ng/unicode_gen.c +3108 -0
  194. package/native/vendor/quickjs-ng/unicode_gen_def.h +310 -0
  195. package/native/vendor/quickjs-ng/update-version.sh +32 -0
  196. package/native/vendor/webview2/include/WebView2.h +60636 -0
  197. package/native/vendor/webview2/include/WebView2EnvironmentOptions.h +406 -0
  198. package/package.json +33 -0
  199. package/src/backend.ts +139 -0
  200. package/src/build-config.ts +87 -0
  201. package/src/build.ts +276 -0
  202. package/src/common.ts +195 -0
  203. package/src/config.ts +89 -0
  204. package/src/dev.ts +164 -0
  205. package/src/generate.ts +200 -0
  206. package/src/icons.ts +116 -0
  207. package/src/init.ts +190 -0
  208. package/src/package.ts +150 -0
  209. package/src/zapp-cli.ts +263 -0
@@ -0,0 +1,748 @@
1
+ /*
2
+ * QuickJS stand alone interpreter
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
+ #include <stdlib.h>
26
+ #include <stdio.h>
27
+ #include <stdarg.h>
28
+ #include <inttypes.h>
29
+ #include <string.h>
30
+ #include <assert.h>
31
+ #include <errno.h>
32
+ #include <fcntl.h>
33
+ #include <time.h>
34
+
35
+ #include "cutils.h"
36
+ #include "quickjs.h"
37
+ #include "quickjs-libc.h"
38
+
39
+ #ifdef QJS_USE_MIMALLOC
40
+ #include <mimalloc.h>
41
+ #endif
42
+
43
+ extern const uint8_t qjsc_repl[];
44
+ extern const uint32_t qjsc_repl_size;
45
+ extern const uint8_t qjsc_standalone[];
46
+ extern const uint32_t qjsc_standalone_size;
47
+
48
+ // Must match standalone.js
49
+ #define TRAILER_SIZE 12
50
+ static const char trailer_magic[] = "quickjs2";
51
+ static const int trailer_magic_size = sizeof(trailer_magic) - 1;
52
+ static const int trailer_size = TRAILER_SIZE;
53
+
54
+ static int qjs__argc;
55
+ static char **qjs__argv;
56
+
57
+
58
+ static bool is_standalone(const char *exe)
59
+ {
60
+ FILE *exe_f = fopen(exe, "rb");
61
+ if (!exe_f)
62
+ return false;
63
+ if (fseek(exe_f, -trailer_size, SEEK_END) < 0)
64
+ goto fail;
65
+ uint8_t buf[TRAILER_SIZE];
66
+ if (fread(buf, 1, trailer_size, exe_f) != trailer_size)
67
+ goto fail;
68
+ fclose(exe_f);
69
+ return !memcmp(buf, trailer_magic, trailer_magic_size);
70
+ fail:
71
+ fclose(exe_f);
72
+ return false;
73
+ }
74
+
75
+ static JSValue load_standalone_module(JSContext *ctx)
76
+ {
77
+ JSModuleDef *m;
78
+ JSValue obj, val;
79
+ obj = JS_ReadObject(ctx, qjsc_standalone, qjsc_standalone_size, JS_READ_OBJ_BYTECODE);
80
+ if (JS_IsException(obj))
81
+ goto exception;
82
+ assert(JS_VALUE_GET_TAG(obj) == JS_TAG_MODULE);
83
+ if (JS_ResolveModule(ctx, obj) < 0) {
84
+ JS_FreeValue(ctx, obj);
85
+ goto exception;
86
+ }
87
+ if (js_module_set_import_meta(ctx, obj, false, true) < 0) {
88
+ JS_FreeValue(ctx, obj);
89
+ goto exception;
90
+ }
91
+ val = JS_EvalFunction(ctx, JS_DupValue(ctx, obj));
92
+ val = js_std_await(ctx, val);
93
+
94
+ if (JS_IsException(val)) {
95
+ JS_FreeValue(ctx, obj);
96
+ exception:
97
+ js_std_dump_error(ctx);
98
+ exit(1);
99
+ }
100
+ JS_FreeValue(ctx, val);
101
+
102
+ m = JS_VALUE_GET_PTR(obj);
103
+ JS_FreeValue(ctx, obj);
104
+ return JS_GetModuleNamespace(ctx, m);
105
+ }
106
+
107
+ static int eval_buf(JSContext *ctx, const void *buf, int buf_len,
108
+ const char *filename, int eval_flags)
109
+ {
110
+ bool use_realpath;
111
+ JSValue val;
112
+ int ret;
113
+
114
+ if ((eval_flags & JS_EVAL_TYPE_MASK) == JS_EVAL_TYPE_MODULE) {
115
+ /* for the modules, we compile then run to be able to set
116
+ import.meta */
117
+ val = JS_Eval(ctx, buf, buf_len, filename,
118
+ eval_flags | JS_EVAL_FLAG_COMPILE_ONLY);
119
+ if (!JS_IsException(val)) {
120
+ // ex. "<cmdline>" pr "/dev/stdin"
121
+ use_realpath =
122
+ !(*filename == '<' || !strncmp(filename, "/dev/", 5));
123
+ if (js_module_set_import_meta(ctx, val, use_realpath, true) < 0) {
124
+ js_std_dump_error(ctx);
125
+ ret = -1;
126
+ goto end;
127
+ }
128
+ val = JS_EvalFunction(ctx, val);
129
+ }
130
+ val = js_std_await(ctx, val);
131
+ } else {
132
+ val = JS_Eval(ctx, buf, buf_len, filename, eval_flags);
133
+ }
134
+ if (JS_IsException(val)) {
135
+ js_std_dump_error(ctx);
136
+ ret = -1;
137
+ } else {
138
+ ret = 0;
139
+ }
140
+ end:
141
+ JS_FreeValue(ctx, val);
142
+ return ret;
143
+ }
144
+
145
+ static int eval_file(JSContext *ctx, const char *filename, int module)
146
+ {
147
+ uint8_t *buf;
148
+ int ret, eval_flags;
149
+ size_t buf_len;
150
+
151
+ buf = js_load_file(ctx, &buf_len, filename);
152
+ if (!buf) {
153
+ perror(filename);
154
+ exit(1);
155
+ }
156
+
157
+ if (module < 0) {
158
+ module = (js__has_suffix(filename, ".mjs") ||
159
+ JS_DetectModule((const char *)buf, buf_len));
160
+ }
161
+ if (module)
162
+ eval_flags = JS_EVAL_TYPE_MODULE;
163
+ else
164
+ eval_flags = JS_EVAL_TYPE_GLOBAL;
165
+ ret = eval_buf(ctx, buf, buf_len, filename, eval_flags);
166
+ js_free(ctx, buf);
167
+ return ret;
168
+ }
169
+
170
+ static int64_t parse_limit(const char *arg) {
171
+ char *p;
172
+ unsigned long unit = 1024; /* default to traditional KB */
173
+ double d = strtod(arg, &p);
174
+
175
+ if (p == arg) {
176
+ fprintf(stderr, "Invalid limit: %s\n", arg);
177
+ return -1;
178
+ }
179
+
180
+ if (*p) {
181
+ switch (*p++) {
182
+ case 'b': case 'B': unit = 1UL << 0; break;
183
+ case 'k': case 'K': unit = 1UL << 10; break; /* IEC kibibytes */
184
+ case 'm': case 'M': unit = 1UL << 20; break; /* IEC mebibytes */
185
+ case 'g': case 'G': unit = 1UL << 30; break; /* IEC gigibytes */
186
+ default:
187
+ fprintf(stderr, "Invalid limit: %s, unrecognized suffix, only k,m,g are allowed\n", arg);
188
+ return -1;
189
+ }
190
+ if (*p) {
191
+ fprintf(stderr, "Invalid limit: %s, only one suffix allowed\n", arg);
192
+ return -1;
193
+ }
194
+ }
195
+
196
+ return (int64_t)(d * unit);
197
+ }
198
+
199
+ static JSValue js_gc(JSContext *ctx, JSValueConst this_val,
200
+ int argc, JSValueConst *argv)
201
+ {
202
+ JS_RunGC(JS_GetRuntime(ctx));
203
+ return JS_UNDEFINED;
204
+ }
205
+
206
+ static JSValue js_navigator_get_userAgent(JSContext *ctx, JSValueConst this_val)
207
+ {
208
+ char version[32];
209
+ snprintf(version, sizeof(version), "quickjs-ng/%s", JS_GetVersion());
210
+ return JS_NewString(ctx, version);
211
+ }
212
+
213
+ static const JSCFunctionListEntry navigator_proto_funcs[] = {
214
+ JS_CGETSET_DEF2("userAgent", js_navigator_get_userAgent, NULL, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE),
215
+ JS_PROP_STRING_DEF("[Symbol.toStringTag]", "Navigator", JS_PROP_CONFIGURABLE),
216
+ };
217
+
218
+ static const JSCFunctionListEntry global_obj[] = {
219
+ JS_CFUNC_DEF("gc", 0, js_gc),
220
+ };
221
+
222
+ /* also used to initialize the worker context */
223
+ static JSContext *JS_NewCustomContext(JSRuntime *rt)
224
+ {
225
+ JSContext *ctx;
226
+ ctx = JS_NewContext(rt);
227
+ if (!ctx)
228
+ return NULL;
229
+ /* system modules */
230
+ js_init_module_std(ctx, "qjs:std");
231
+ js_init_module_os(ctx, "qjs:os");
232
+ js_init_module_bjson(ctx, "qjs:bjson");
233
+
234
+ JSValue global = JS_GetGlobalObject(ctx);
235
+ JS_SetPropertyFunctionList(ctx, global, global_obj, countof(global_obj));
236
+ JSValue args = JS_NewArray(ctx);
237
+ int i;
238
+ for(i = 0; i < qjs__argc; i++) {
239
+ JS_SetPropertyUint32(ctx, args, i, JS_NewString(ctx, qjs__argv[i]));
240
+ }
241
+ JS_SetPropertyStr(ctx, global, "execArgv", args);
242
+ JS_SetPropertyStr(ctx, global, "argv0", JS_NewString(ctx, qjs__argv[0]));
243
+ JSValue navigator_proto = JS_NewObject(ctx);
244
+ JS_SetPropertyFunctionList(ctx, navigator_proto, navigator_proto_funcs, countof(navigator_proto_funcs));
245
+ JSValue navigator = JS_NewObjectProto(ctx, navigator_proto);
246
+ JS_DefinePropertyValueStr(ctx, global, "navigator", navigator, JS_PROP_CONFIGURABLE | JS_PROP_ENUMERABLE);
247
+ JS_FreeValue(ctx, global);
248
+ JS_FreeValue(ctx, navigator_proto);
249
+
250
+ return ctx;
251
+ }
252
+
253
+ struct trace_malloc_data {
254
+ uint8_t *base;
255
+ };
256
+
257
+ static inline unsigned long long js_trace_malloc_ptr_offset(uint8_t *ptr,
258
+ struct trace_malloc_data *dp)
259
+ {
260
+ return ptr - dp->base;
261
+ }
262
+
263
+ static void JS_PRINTF_FORMAT_ATTR(2, 3) js_trace_malloc_printf(void *opaque, JS_PRINTF_FORMAT const char *fmt, ...)
264
+ {
265
+ va_list ap;
266
+ int c;
267
+
268
+ va_start(ap, fmt);
269
+ while ((c = *fmt++) != '\0') {
270
+ if (c == '%') {
271
+ /* only handle %p and %zd */
272
+ if (*fmt == 'p') {
273
+ uint8_t *ptr = va_arg(ap, void *);
274
+ if (ptr == NULL) {
275
+ printf("NULL");
276
+ } else {
277
+ printf("H%+06lld.%zd",
278
+ js_trace_malloc_ptr_offset(ptr, opaque),
279
+ js__malloc_usable_size(ptr));
280
+ }
281
+ fmt++;
282
+ continue;
283
+ }
284
+ if (fmt[0] == 'z' && fmt[1] == 'd') {
285
+ size_t sz = va_arg(ap, size_t);
286
+ printf("%zd", sz);
287
+ fmt += 2;
288
+ continue;
289
+ }
290
+ }
291
+ putc(c, stdout);
292
+ }
293
+ va_end(ap);
294
+ }
295
+
296
+ static void js_trace_malloc_init(struct trace_malloc_data *s)
297
+ {
298
+ free(s->base = malloc(8));
299
+ }
300
+
301
+ static void *js_trace_calloc(void *opaque, size_t count, size_t size)
302
+ {
303
+ void *ptr;
304
+ ptr = calloc(count, size);
305
+ js_trace_malloc_printf(opaque, "C %zd %zd -> %p\n", count, size, ptr);
306
+ return ptr;
307
+ }
308
+
309
+ static void *js_trace_malloc(void *opaque, size_t size)
310
+ {
311
+ void *ptr;
312
+ ptr = malloc(size);
313
+ js_trace_malloc_printf(opaque, "A %zd -> %p\n", size, ptr);
314
+ return ptr;
315
+ }
316
+
317
+ static void js_trace_free(void *opaque, void *ptr)
318
+ {
319
+ if (!ptr)
320
+ return;
321
+ js_trace_malloc_printf(opaque, "F %p\n", ptr);
322
+ free(ptr);
323
+ }
324
+
325
+ static void *js_trace_realloc(void *opaque, void *ptr, size_t size)
326
+ {
327
+ js_trace_malloc_printf(opaque, "R %zd %p", size, ptr);
328
+ ptr = realloc(ptr, size);
329
+ js_trace_malloc_printf(opaque, " -> %p\n", ptr);
330
+ return ptr;
331
+ }
332
+
333
+ static const JSMallocFunctions trace_mf = {
334
+ js_trace_calloc,
335
+ js_trace_malloc,
336
+ js_trace_free,
337
+ js_trace_realloc,
338
+ js__malloc_usable_size
339
+ };
340
+
341
+ #ifdef QJS_USE_MIMALLOC
342
+ static void *js_mi_calloc(void *opaque, size_t count, size_t size)
343
+ {
344
+ return mi_calloc(count, size);
345
+ }
346
+
347
+ static void *js_mi_malloc(void *opaque, size_t size)
348
+ {
349
+ return mi_malloc(size);
350
+ }
351
+
352
+ static void js_mi_free(void *opaque, void *ptr)
353
+ {
354
+ if (!ptr)
355
+ return;
356
+ mi_free(ptr);
357
+ }
358
+
359
+ static void *js_mi_realloc(void *opaque, void *ptr, size_t size)
360
+ {
361
+ return mi_realloc(ptr, size);
362
+ }
363
+
364
+ static const JSMallocFunctions mi_mf = {
365
+ js_mi_calloc,
366
+ js_mi_malloc,
367
+ js_mi_free,
368
+ js_mi_realloc,
369
+ mi_malloc_usable_size
370
+ };
371
+ #endif
372
+
373
+ #define PROG_NAME "qjs"
374
+
375
+ void help(void)
376
+ {
377
+ printf("QuickJS-ng version %s\n"
378
+ "usage: " PROG_NAME " [options] [file [args]]\n"
379
+ "-h --help list options\n"
380
+ "-e --eval EXPR evaluate EXPR\n"
381
+ "-i --interactive go to interactive mode\n"
382
+ "-C --script load as JS classic script (default=autodetect)\n"
383
+ "-m --module load as ES module (default=autodetect)\n"
384
+ "-I --include file include an additional file\n"
385
+ " --std make 'std', 'os' and 'bjson' available to script\n"
386
+ "-T --trace trace memory allocation\n"
387
+ "-d --dump dump the memory usage stats\n"
388
+ "-D --dump-flags flags for dumping debug data (see DUMP_* defines)\n"
389
+ "-c --compile FILE compile the given JS file as a standalone executable\n"
390
+ "-o --out FILE output file for standalone executables\n"
391
+ " --exe select the executable to use as the base, defaults to the current one\n"
392
+ " --memory-limit n limit the memory usage to 'n' Kbytes\n"
393
+ " --stack-size n limit the stack size to 'n' Kbytes\n"
394
+ "-q --quit just instantiate the interpreter and quit\n", JS_GetVersion());
395
+ exit(1);
396
+ }
397
+
398
+ int main(int argc, char **argv)
399
+ {
400
+ JSRuntime *rt;
401
+ JSContext *ctx;
402
+ JSValue ret = JS_UNDEFINED;
403
+ struct trace_malloc_data trace_data = { NULL };
404
+ int r = 0;
405
+ int optind = 1;
406
+ char exebuf[JS__PATH_MAX];
407
+ size_t exebuf_size = sizeof(exebuf);
408
+ char *compile_file = NULL;
409
+ char *exe = NULL;
410
+ char *expr = NULL;
411
+ char *dump_flags_str = NULL;
412
+ char *out = NULL;
413
+ int standalone = 0;
414
+ int interactive = 0;
415
+ int dump_memory = 0;
416
+ int dump_flags = 0;
417
+ int trace_memory = 0;
418
+ int empty_run = 0;
419
+ int module = -1;
420
+ int load_std = 0;
421
+ char *include_list[32];
422
+ int i, include_count = 0;
423
+ int64_t memory_limit = -1;
424
+ int64_t stack_size = -1;
425
+
426
+ /* save for later */
427
+ qjs__argc = argc;
428
+ qjs__argv = argv;
429
+
430
+ /* check if this is a standalone executable */
431
+
432
+ if (!js_exepath(exebuf, &exebuf_size) && is_standalone(exebuf)) {
433
+ standalone = 1;
434
+ goto start;
435
+ }
436
+
437
+ dump_flags_str = getenv("QJS_DUMP_FLAGS");
438
+ dump_flags = dump_flags_str ? strtol(dump_flags_str, NULL, 16) : 0;
439
+
440
+ /* cannot use getopt because we want to pass the command line to
441
+ the script */
442
+ while (optind < argc && *argv[optind] == '-') {
443
+ char *arg = argv[optind] + 1;
444
+ const char *longopt = "";
445
+ char *optarg = NULL;
446
+ /* a single - is not an option, it also stops argument scanning */
447
+ if (!*arg)
448
+ break;
449
+ optind++;
450
+ if (*arg == '-') {
451
+ longopt = arg + 1;
452
+ optarg = strchr(longopt, '=');
453
+ if (optarg)
454
+ *optarg++ = '\0';
455
+ arg += strlen(arg);
456
+ /* -- stops argument scanning */
457
+ if (!*longopt)
458
+ break;
459
+ }
460
+ for (; *arg || *longopt; longopt = "") {
461
+ char opt = *arg;
462
+ if (opt) {
463
+ arg++;
464
+ if (!optarg && *arg)
465
+ optarg = arg;
466
+ }
467
+ if (opt == 'h' || opt == '?' || !strcmp(longopt, "help")) {
468
+ help();
469
+ continue;
470
+ }
471
+ if (opt == 'e' || !strcmp(longopt, "eval")) {
472
+ if (!optarg) {
473
+ if (optind >= argc) {
474
+ fprintf(stderr, "qjs: missing expression for -e\n");
475
+ exit(1);
476
+ }
477
+ optarg = argv[optind++];
478
+ }
479
+ expr = optarg;
480
+ break;
481
+ }
482
+ if (opt == 'I' || !strcmp(longopt, "include")) {
483
+ if (optind >= argc) {
484
+ fprintf(stderr, "expecting filename");
485
+ exit(1);
486
+ }
487
+ if (include_count >= countof(include_list)) {
488
+ fprintf(stderr, "too many included files");
489
+ exit(1);
490
+ }
491
+ include_list[include_count++] = argv[optind++];
492
+ continue;
493
+ }
494
+ if (opt == 'i' || !strcmp(longopt, "interactive")) {
495
+ interactive++;
496
+ continue;
497
+ }
498
+ if (opt == 'm' || !strcmp(longopt, "module")) {
499
+ module = 1;
500
+ continue;
501
+ }
502
+ if (opt == 'C' || !strcmp(longopt, "script")) {
503
+ module = 0;
504
+ continue;
505
+ }
506
+ if (opt == 'd' || !strcmp(longopt, "dump")) {
507
+ dump_memory++;
508
+ continue;
509
+ }
510
+ if (opt == 'D' || !strcmp(longopt, "dump-flags")) {
511
+ dump_flags = optarg ? strtol(optarg, NULL, 16) : 0;
512
+ break;
513
+ }
514
+ if (opt == 'T' || !strcmp(longopt, "trace")) {
515
+ trace_memory++;
516
+ continue;
517
+ }
518
+ if (!strcmp(longopt, "std")) {
519
+ load_std = 1;
520
+ continue;
521
+ }
522
+ if (opt == 'q' || !strcmp(longopt, "quit")) {
523
+ empty_run++;
524
+ continue;
525
+ }
526
+ if (!strcmp(longopt, "memory-limit")) {
527
+ if (!optarg) {
528
+ if (optind >= argc) {
529
+ fprintf(stderr, "expecting memory limit");
530
+ exit(1);
531
+ }
532
+ optarg = argv[optind++];
533
+ }
534
+ memory_limit = parse_limit(optarg);
535
+ break;
536
+ }
537
+ if (!strcmp(longopt, "stack-size")) {
538
+ if (!optarg) {
539
+ if (optind >= argc) {
540
+ fprintf(stderr, "expecting stack size");
541
+ exit(1);
542
+ }
543
+ optarg = argv[optind++];
544
+ }
545
+ stack_size = parse_limit(optarg);
546
+ break;
547
+ }
548
+ if (opt == 'c' || !strcmp(longopt, "compile")) {
549
+ if (!optarg) {
550
+ if (optind >= argc) {
551
+ fprintf(stderr, "qjs: missing file for -c\n");
552
+ exit(1);
553
+ }
554
+ optarg = argv[optind++];
555
+ }
556
+ compile_file = optarg;
557
+ break;
558
+ }
559
+ if (opt == 'o' || !strcmp(longopt, "out")) {
560
+ if (!optarg) {
561
+ if (optind >= argc) {
562
+ fprintf(stderr, "qjs: missing file for -o\n");
563
+ exit(1);
564
+ }
565
+ optarg = argv[optind++];
566
+ }
567
+ out = optarg;
568
+ break;
569
+ }
570
+ if (!strcmp(longopt, "exe")) {
571
+ if (!optarg) {
572
+ if (optind >= argc) {
573
+ fprintf(stderr, "qjs: missing file for --exe\n");
574
+ exit(1);
575
+ }
576
+ optarg = argv[optind++];
577
+ }
578
+ exe = optarg;
579
+ break;
580
+ }
581
+ if (opt) {
582
+ fprintf(stderr, "qjs: unknown option '-%c'\n", opt);
583
+ } else {
584
+ fprintf(stderr, "qjs: unknown option '--%s'\n", longopt);
585
+ }
586
+ help();
587
+ }
588
+ }
589
+
590
+ if (compile_file && !out)
591
+ help();
592
+
593
+ start:
594
+
595
+ if (trace_memory) {
596
+ js_trace_malloc_init(&trace_data);
597
+ rt = JS_NewRuntime2(&trace_mf, &trace_data);
598
+ } else {
599
+ #ifdef QJS_USE_MIMALLOC
600
+ rt = JS_NewRuntime2(&mi_mf, NULL);
601
+ #else
602
+ rt = JS_NewRuntime();
603
+ #endif
604
+ }
605
+ if (!rt) {
606
+ fprintf(stderr, "qjs: cannot allocate JS runtime\n");
607
+ exit(2);
608
+ }
609
+ if (memory_limit >= 0)
610
+ JS_SetMemoryLimit(rt, (size_t)memory_limit);
611
+ if (stack_size >= 0)
612
+ JS_SetMaxStackSize(rt, (size_t)stack_size);
613
+ if (dump_flags != 0)
614
+ JS_SetDumpFlags(rt, dump_flags);
615
+ js_std_set_worker_new_context_func(JS_NewCustomContext);
616
+ js_std_init_handlers(rt);
617
+ ctx = JS_NewCustomContext(rt);
618
+ if (!ctx) {
619
+ fprintf(stderr, "qjs: cannot allocate JS context\n");
620
+ exit(2);
621
+ }
622
+
623
+ /* loader for ES6 modules */
624
+ JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader, js_module_check_attributes, NULL);
625
+
626
+ /* exit on unhandled promise rejections */
627
+ JS_SetHostPromiseRejectionTracker(rt, js_std_promise_rejection_tracker, NULL);
628
+
629
+ if (!empty_run) {
630
+ js_std_add_helpers(ctx, argc - optind, argv + optind);
631
+
632
+ /* make 'std' and 'os' visible to non module code */
633
+ if (load_std) {
634
+ const char *str =
635
+ "import * as bjson from 'qjs:bjson';\n"
636
+ "import * as std from 'qjs:std';\n"
637
+ "import * as os from 'qjs:os';\n"
638
+ "globalThis.bjson = bjson;\n"
639
+ "globalThis.std = std;\n"
640
+ "globalThis.os = os;\n";
641
+ eval_buf(ctx, str, strlen(str), "<input>", JS_EVAL_TYPE_MODULE);
642
+ }
643
+
644
+ for(i = 0; i < include_count; i++) {
645
+ if (eval_file(ctx, include_list[i], 0))
646
+ goto fail;
647
+ }
648
+
649
+ if (standalone) {
650
+ JSValue ns = load_standalone_module(ctx);
651
+ if (JS_IsException(ns))
652
+ goto fail;
653
+ JSValue func = JS_GetPropertyStr(ctx, ns, "runStandalone");
654
+ JS_FreeValue(ctx, ns);
655
+ if (JS_IsException(func))
656
+ goto fail;
657
+ ret = JS_Call(ctx, func, JS_UNDEFINED, 0, NULL);
658
+ JS_FreeValue(ctx, func);
659
+ } else if (compile_file) {
660
+ JSValue ns = load_standalone_module(ctx);
661
+ if (JS_IsException(ns))
662
+ goto fail;
663
+ JSValue func = JS_GetPropertyStr(ctx, ns, "compileStandalone");
664
+ JS_FreeValue(ctx, ns);
665
+ if (JS_IsException(func))
666
+ goto fail;
667
+ JSValue args[3];
668
+ args[0] = JS_NewString(ctx, compile_file);
669
+ args[1] = JS_NewString(ctx, out);
670
+ args[2] = exe != NULL ? JS_NewString(ctx, exe) : JS_UNDEFINED;
671
+ ret = JS_Call(ctx, func, JS_UNDEFINED, 3, (JSValueConst *)args);
672
+ JS_FreeValue(ctx, func);
673
+ JS_FreeValue(ctx, args[0]);
674
+ JS_FreeValue(ctx, args[1]);
675
+ JS_FreeValue(ctx, args[2]);
676
+ } else if (expr) {
677
+ int flags = module ? JS_EVAL_TYPE_MODULE : 0;
678
+ if (eval_buf(ctx, expr, strlen(expr), "<cmdline>", flags))
679
+ goto fail;
680
+ } else if (optind >= argc) {
681
+ /* interactive mode */
682
+ interactive = 1;
683
+ } else {
684
+ const char *filename;
685
+ filename = argv[optind];
686
+ if (eval_file(ctx, filename, module))
687
+ goto fail;
688
+ }
689
+ if (interactive) {
690
+ JS_SetHostPromiseRejectionTracker(rt, NULL, NULL);
691
+ js_std_eval_binary(ctx, qjsc_repl, qjsc_repl_size, 0);
692
+ }
693
+ if (standalone || compile_file) {
694
+ if (JS_IsException(ret)) {
695
+ r = 1;
696
+ } else {
697
+ JS_FreeValue(ctx, ret);
698
+ r = js_std_loop(ctx);
699
+ }
700
+ } else {
701
+ r = js_std_loop(ctx);
702
+ }
703
+ if (r) {
704
+ js_std_dump_error(ctx);
705
+ goto fail;
706
+ }
707
+ }
708
+
709
+ if (dump_memory) {
710
+ JSMemoryUsage stats;
711
+ JS_ComputeMemoryUsage(rt, &stats);
712
+ JS_DumpMemoryUsage(stdout, &stats, rt);
713
+ }
714
+ js_std_free_handlers(rt);
715
+ JS_FreeContext(ctx);
716
+ JS_FreeRuntime(rt);
717
+
718
+ if (empty_run && dump_memory) {
719
+ clock_t t[5];
720
+ double best[5] = {0};
721
+ int i, j;
722
+ for (i = 0; i < 100; i++) {
723
+ t[0] = clock();
724
+ rt = JS_NewRuntime();
725
+ t[1] = clock();
726
+ ctx = JS_NewContext(rt);
727
+ t[2] = clock();
728
+ JS_FreeContext(ctx);
729
+ t[3] = clock();
730
+ JS_FreeRuntime(rt);
731
+ t[4] = clock();
732
+ for (j = 4; j > 0; j--) {
733
+ double ms = 1000.0 * (t[j] - t[j - 1]) / CLOCKS_PER_SEC;
734
+ if (i == 0 || best[j] > ms)
735
+ best[j] = ms;
736
+ }
737
+ }
738
+ printf("\nInstantiation times (ms): %.3f = %.3f+%.3f+%.3f+%.3f\n",
739
+ best[1] + best[2] + best[3] + best[4],
740
+ best[1], best[2], best[3], best[4]);
741
+ }
742
+ return 0;
743
+ fail:
744
+ js_std_free_handlers(rt);
745
+ JS_FreeContext(ctx);
746
+ JS_FreeRuntime(rt);
747
+ return 1;
748
+ }