@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,673 @@
1
+ /*
2
+ * QuickJS command line compiler
3
+ *
4
+ * Copyright (c) 2018-2026 Fabrice Bellard
5
+ * Copyright (c) 2023-2026 Ben Noordhuis
6
+ * Copyright (c) 2023-2026 Saúl Ibarra Corretgé
7
+ *
8
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
9
+ * of this software and associated documentation files (the "Software"), to deal
10
+ * in the Software without restriction, including without limitation the rights
11
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ * copies of the Software, and to permit persons to whom the Software is
13
+ * furnished to do so, subject to the following conditions:
14
+ *
15
+ * The above copyright notice and this permission notice shall be included in
16
+ * all copies or substantial portions of the Software.
17
+ *
18
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24
+ * THE SOFTWARE.
25
+ */
26
+ #include <stdlib.h>
27
+ #include <stdio.h>
28
+ #include <stdarg.h>
29
+ #include <inttypes.h>
30
+ #include <string.h>
31
+ #include <assert.h>
32
+ #include <errno.h>
33
+
34
+ #include "cutils.h"
35
+ #include "quickjs-libc.h"
36
+
37
+ typedef enum {
38
+ OUTPUT_C,
39
+ OUTPUT_C_MAIN,
40
+ OUTPUT_RAW,
41
+ } OutputTypeEnum;
42
+
43
+ typedef struct {
44
+ char *name;
45
+ char *short_name;
46
+ int flags;
47
+ } namelist_entry_t;
48
+
49
+ typedef struct namelist_t {
50
+ namelist_entry_t *array;
51
+ int count;
52
+ int size;
53
+ } namelist_t;
54
+
55
+ static namelist_t cname_list;
56
+ static namelist_t cmodule_list;
57
+ static namelist_t init_module_list;
58
+ static OutputTypeEnum output_type;
59
+ static FILE *outfile;
60
+ static const char *c_ident_prefix = "qjsc_";
61
+ static int strip;
62
+
63
+ void namelist_add(namelist_t *lp, const char *name, const char *short_name,
64
+ int flags)
65
+ {
66
+ namelist_entry_t *e;
67
+ if (lp->count == lp->size) {
68
+ size_t newsize = lp->size + (lp->size >> 1) + 4;
69
+ namelist_entry_t *a =
70
+ realloc(lp->array, sizeof(lp->array[0]) * newsize);
71
+ /* XXX: check for realloc failure */
72
+ lp->array = a;
73
+ lp->size = newsize;
74
+ }
75
+ e = &lp->array[lp->count++];
76
+ e->name = strdup(name);
77
+ if (short_name)
78
+ e->short_name = strdup(short_name);
79
+ else
80
+ e->short_name = NULL;
81
+ e->flags = flags;
82
+ }
83
+
84
+ void namelist_free(namelist_t *lp)
85
+ {
86
+ while (lp->count > 0) {
87
+ namelist_entry_t *e = &lp->array[--lp->count];
88
+ free(e->name);
89
+ free(e->short_name);
90
+ }
91
+ free(lp->array);
92
+ lp->array = NULL;
93
+ lp->size = 0;
94
+ }
95
+
96
+ namelist_entry_t *namelist_find(namelist_t *lp, const char *name)
97
+ {
98
+ int i;
99
+ for(i = 0; i < lp->count; i++) {
100
+ namelist_entry_t *e = &lp->array[i];
101
+ if (!strcmp(e->name, name))
102
+ return e;
103
+ }
104
+ return NULL;
105
+ }
106
+
107
+ static void get_c_name(char *buf, size_t buf_size, const char *file)
108
+ {
109
+ const char *p, *r;
110
+ size_t len, i;
111
+ int c;
112
+ char *q;
113
+
114
+ p = strrchr(file, '/');
115
+ if (!p)
116
+ p = file;
117
+ else
118
+ p++;
119
+ r = strrchr(p, '.');
120
+ if (!r)
121
+ len = strlen(p);
122
+ else
123
+ len = r - p;
124
+ js__pstrcpy(buf, buf_size, c_ident_prefix);
125
+ q = buf + strlen(buf);
126
+ for(i = 0; i < len; i++) {
127
+ c = p[i];
128
+ if (!((c >= '0' && c <= '9') ||
129
+ (c >= 'A' && c <= 'Z') ||
130
+ (c >= 'a' && c <= 'z'))) {
131
+ c = '_';
132
+ }
133
+ if ((q - buf) < buf_size - 1)
134
+ *q++ = c;
135
+ }
136
+ *q = '\0';
137
+ }
138
+
139
+ static void dump_hex(FILE *f, const uint8_t *buf, size_t len)
140
+ {
141
+ size_t i, col;
142
+ col = 0;
143
+ for(i = 0; i < len; i++) {
144
+ fprintf(f, " 0x%02x,", buf[i]);
145
+ if (++col == 8) {
146
+ fprintf(f, "\n");
147
+ col = 0;
148
+ }
149
+ }
150
+ if (col != 0)
151
+ fprintf(f, "\n");
152
+ }
153
+
154
+ static void output_object_code(JSContext *ctx,
155
+ FILE *fo, JSValue obj, const char *c_name,
156
+ bool load_only)
157
+ {
158
+ uint8_t *out_buf;
159
+ size_t out_buf_len;
160
+ int flags = JS_WRITE_OBJ_BYTECODE;
161
+
162
+ if (strip) {
163
+ flags |= JS_WRITE_OBJ_STRIP_SOURCE;
164
+ if (strip > 1)
165
+ flags |= JS_WRITE_OBJ_STRIP_DEBUG;
166
+ }
167
+
168
+ out_buf = JS_WriteObject(ctx, &out_buf_len, obj, flags);
169
+ if (!out_buf) {
170
+ js_std_dump_error(ctx);
171
+ exit(1);
172
+ }
173
+
174
+ namelist_add(&cname_list, c_name, NULL, load_only);
175
+
176
+ if (output_type == OUTPUT_RAW) {
177
+ fwrite(out_buf, 1, out_buf_len, fo);
178
+ } else {
179
+ fprintf(fo, "const uint32_t %s_size = %u;\n\n",
180
+ c_name, (unsigned int)out_buf_len);
181
+ fprintf(fo, "const uint8_t %s[%u] = {\n",
182
+ c_name, (unsigned int)out_buf_len);
183
+ dump_hex(fo, out_buf, out_buf_len);
184
+ fprintf(fo, "};\n\n");
185
+ }
186
+
187
+ js_free(ctx, out_buf);
188
+ }
189
+
190
+ static int js_module_dummy_init(JSContext *ctx, JSModuleDef *m)
191
+ {
192
+ /* should never be called when compiling JS code */
193
+ abort();
194
+ return -1; // pacify compiler
195
+ }
196
+
197
+ static void find_unique_cname(char *cname, size_t cname_size)
198
+ {
199
+ char cname1[1024];
200
+ int suffix_num;
201
+ size_t len, max_len;
202
+ assert(cname_size >= 32);
203
+ /* find a C name not matching an existing module C name by
204
+ adding a numeric suffix */
205
+ len = strlen(cname);
206
+ max_len = cname_size - 16;
207
+ if (len > max_len)
208
+ cname[max_len] = '\0';
209
+ suffix_num = 1;
210
+ for(;;) {
211
+ snprintf(cname1, sizeof(cname1), "%s_%d", cname, suffix_num);
212
+ if (!namelist_find(&cname_list, cname1))
213
+ break;
214
+ suffix_num++;
215
+ }
216
+ js__pstrcpy(cname, cname_size, cname1);
217
+ }
218
+
219
+ JSModuleDef *jsc_module_loader(JSContext *ctx,
220
+ const char *module_name, void *opaque)
221
+ {
222
+ JSModuleDef *m;
223
+ namelist_entry_t *e;
224
+
225
+ /* check if it is a declared C or system module */
226
+ e = namelist_find(&cmodule_list, module_name);
227
+ if (e) {
228
+ /* add in the static init module list */
229
+ namelist_add(&init_module_list, e->name, e->short_name, 0);
230
+ /* create a dummy module */
231
+ m = JS_NewCModule(ctx, module_name, js_module_dummy_init);
232
+ } else if (js__has_suffix(module_name, ".so")) {
233
+ JS_ThrowReferenceError(ctx, "%s: dynamically linking to shared libraries not supported",
234
+ module_name);
235
+ return NULL;
236
+ } else {
237
+ size_t buf_len;
238
+ uint8_t *buf;
239
+ JSValue func_val;
240
+ char cname[1000];
241
+
242
+ buf = js_load_file(ctx, &buf_len, module_name);
243
+ if (!buf) {
244
+ JS_ThrowReferenceError(ctx, "could not load module filename '%s'",
245
+ module_name);
246
+ return NULL;
247
+ }
248
+
249
+ /* compile the module */
250
+ func_val = JS_Eval(ctx, (char *)buf, buf_len, module_name,
251
+ JS_EVAL_TYPE_MODULE | JS_EVAL_FLAG_COMPILE_ONLY);
252
+ js_free(ctx, buf);
253
+ if (JS_IsException(func_val))
254
+ return NULL;
255
+ get_c_name(cname, sizeof(cname), module_name);
256
+ if (namelist_find(&cname_list, cname)) {
257
+ find_unique_cname(cname, sizeof(cname));
258
+ }
259
+ output_object_code(ctx, outfile, func_val, cname, true);
260
+
261
+ /* the module is already referenced, so we must free it */
262
+ m = JS_VALUE_GET_PTR(func_val);
263
+ JS_FreeValue(ctx, func_val);
264
+ }
265
+ return m;
266
+ }
267
+
268
+ static void compile_file(JSContext *ctx, FILE *fo,
269
+ const char *filename,
270
+ const char *script_name,
271
+ const char *c_name1,
272
+ int module)
273
+ {
274
+ uint8_t *buf;
275
+ char c_name[1024];
276
+ int eval_flags;
277
+ JSValue obj;
278
+ size_t buf_len;
279
+
280
+ buf = js_load_file(ctx, &buf_len, filename);
281
+ if (!buf) {
282
+ fprintf(stderr, "Could not load '%s'\n", filename);
283
+ exit(1);
284
+ }
285
+ eval_flags = JS_EVAL_FLAG_COMPILE_ONLY;
286
+ if (module < 0) {
287
+ module = (js__has_suffix(filename, ".mjs") ||
288
+ JS_DetectModule((const char *)buf, buf_len));
289
+ }
290
+ if (module)
291
+ eval_flags |= JS_EVAL_TYPE_MODULE;
292
+ else
293
+ eval_flags |= JS_EVAL_TYPE_GLOBAL;
294
+ obj = JS_Eval(ctx, (const char *)buf, buf_len, script_name ? script_name : filename, eval_flags);
295
+ if (JS_IsException(obj)) {
296
+ js_std_dump_error(ctx);
297
+ exit(1);
298
+ }
299
+ js_free(ctx, buf);
300
+ if (c_name1) {
301
+ js__pstrcpy(c_name, sizeof(c_name), c_name1);
302
+ } else {
303
+ get_c_name(c_name, sizeof(c_name), filename);
304
+ }
305
+ output_object_code(ctx, fo, obj, c_name, false);
306
+ JS_FreeValue(ctx, obj);
307
+ }
308
+
309
+ static const char main_c_template1[] =
310
+ "int main(int argc, char **argv)\n"
311
+ "{\n"
312
+ " int r;\n"
313
+ " JSRuntime *rt;\n"
314
+ " JSContext *ctx;\n"
315
+ " r = 0;\n"
316
+ " rt = JS_NewRuntime();\n"
317
+ " js_std_set_worker_new_context_func(JS_NewCustomContext);\n"
318
+ " js_std_init_handlers(rt);\n"
319
+ ;
320
+
321
+ static const char main_c_template2[] =
322
+ " r = js_std_loop(ctx);\n"
323
+ " if (r) {\n"
324
+ " js_std_dump_error(ctx);\n"
325
+ " }\n"
326
+ " js_std_free_handlers(rt);\n"
327
+ " JS_FreeContext(ctx);\n"
328
+ " JS_FreeRuntime(rt);\n"
329
+ " return r;\n"
330
+ "}\n";
331
+
332
+ #define PROG_NAME "qjsc"
333
+
334
+ void help(void)
335
+ {
336
+ printf("QuickJS-ng Compiler version %s\n"
337
+ "usage: " PROG_NAME " [options] [files]\n"
338
+ "\n"
339
+ "options are:\n"
340
+ "-b output raw bytecode instead of C code\n"
341
+ "-e output main() and bytecode in a C file\n"
342
+ "-o output set the output filename\n"
343
+ "-n script_name set the script name (as used in stack traces)\n"
344
+ "-N cname set the C name of the generated data\n"
345
+ "-C compile as JS classic script (default=autodetect)\n"
346
+ "-m compile as ES module (default=autodetect)\n"
347
+ "-D module_name compile a dynamically loaded module or worker\n"
348
+ "-M module_name[,cname] add initialization code for an external C module\n"
349
+ "-p prefix set the prefix of the generated C names\n"
350
+ "-P do not add default system modules\n"
351
+ "-s strip the source code, specify twice to also strip debug info\n"
352
+ "-S n set the maximum stack size to 'n' bytes (default=%d)\n",
353
+ JS_GetVersion(),
354
+ JS_DEFAULT_STACK_SIZE);
355
+ exit(1);
356
+ }
357
+
358
+ // TODO(bnoordhuis) share with qjs.c maybe
359
+ static int64_t parse_limit(const char *arg) {
360
+ char *p;
361
+ unsigned long unit = 1; // bytes for backcompat; qjs defaults to kilobytes
362
+ double d = strtod(arg, &p);
363
+
364
+ if (p == arg) {
365
+ fprintf(stderr, "qjsc: invalid limit: %s\n", arg);
366
+ return -1;
367
+ }
368
+
369
+ if (*p) {
370
+ switch (*p++) {
371
+ case 'b': case 'B': unit = 1UL << 0; break;
372
+ case 'k': case 'K': unit = 1UL << 10; break; /* IEC kibibytes */
373
+ case 'm': case 'M': unit = 1UL << 20; break; /* IEC mebibytes */
374
+ case 'g': case 'G': unit = 1UL << 30; break; /* IEC gigibytes */
375
+ default:
376
+ fprintf(stderr, "qjsc: invalid limit: %s, unrecognized suffix, only k,m,g are allowed\n", arg);
377
+ return -1;
378
+ }
379
+ if (*p) {
380
+ fprintf(stderr, "qjsc: invalid limit: %s, only one suffix allowed\n", arg);
381
+ return -1;
382
+ }
383
+ }
384
+
385
+ return (int64_t)(d * unit);
386
+ }
387
+
388
+ static void check_hasarg(int optind, int argc, int opt)
389
+ {
390
+ if (optind >= argc) {
391
+ fprintf(stderr, "qjsc: missing file for -%c\n", opt);
392
+ exit(1);
393
+ }
394
+ }
395
+
396
+ int main(int argc, char **argv)
397
+ {
398
+ int optind = 1;
399
+ int i;
400
+ const char *out_filename, *cname, *script_name;
401
+ char cfilename[1024];
402
+ FILE *fo;
403
+ JSRuntime *rt;
404
+ JSContext *ctx;
405
+ int module;
406
+ size_t stack_size;
407
+ namelist_t dynamic_module_list;
408
+ bool load_system_modules = true;
409
+
410
+ out_filename = NULL;
411
+ script_name = NULL;
412
+ output_type = OUTPUT_C;
413
+ cname = NULL;
414
+ module = -1;
415
+ strip = 0;
416
+ stack_size = 0;
417
+ memset(&dynamic_module_list, 0, sizeof(dynamic_module_list));
418
+
419
+
420
+ while (optind < argc && *argv[optind] == '-') {
421
+ char *arg = argv[optind] + 1;
422
+ const char *longopt = "";
423
+ char *optarg = NULL;
424
+ /* a single - is not an option, it also stops argument scanning */
425
+ if (!*arg)
426
+ break;
427
+ optind++;
428
+ if (*arg == '-') {
429
+ longopt = arg + 1;
430
+ optarg = strchr(longopt, '=');
431
+ if (optarg)
432
+ *optarg++ = '\0';
433
+ arg += strlen(arg);
434
+ /* -- stops argument scanning */
435
+ if (!*longopt)
436
+ break;
437
+ }
438
+ for (; *arg || *longopt; longopt = "") {
439
+ char opt = *arg;
440
+ if (opt) {
441
+ arg++;
442
+ if (!optarg && *arg)
443
+ optarg = arg;
444
+ }
445
+ if (opt == 'h' || opt == '?' || !strcmp(longopt, "help")) {
446
+ help();
447
+ continue;
448
+ }
449
+ if (opt == 'b') {
450
+ output_type = OUTPUT_RAW;
451
+ continue;
452
+ }
453
+ if (opt == 'o') {
454
+ if (!optarg) {
455
+ check_hasarg(optind, argc, opt);
456
+ optarg = argv[optind++];
457
+ }
458
+ out_filename = optarg;
459
+ continue;
460
+ }
461
+ if (opt == 'e') {
462
+ output_type = OUTPUT_C_MAIN;
463
+ continue;
464
+ }
465
+ if (opt == 'n') {
466
+ if (!optarg) {
467
+ check_hasarg(optind, argc, opt);
468
+ optarg = argv[optind++];
469
+ }
470
+ script_name = optarg;
471
+ continue;
472
+ }
473
+ if (opt == 'N') {
474
+ if (!optarg) {
475
+ check_hasarg(optind, argc, opt);
476
+ optarg = argv[optind++];
477
+ }
478
+ cname = optarg;
479
+ continue;
480
+ }
481
+ if (opt == 'C') {
482
+ module = 0;
483
+ continue;
484
+ }
485
+ if (opt == 'm') {
486
+ module = 1;
487
+ continue;
488
+ }
489
+ if (opt == 'M') {
490
+ char *p;
491
+ char path[1024];
492
+ char cname[1024];
493
+ if (!optarg) {
494
+ check_hasarg(optind, argc, opt);
495
+ optarg = argv[optind++];
496
+ }
497
+ js__pstrcpy(path, sizeof(path), optarg);
498
+ p = strchr(path, ',');
499
+ if (p) {
500
+ *p = '\0';
501
+ js__pstrcpy(cname, sizeof(cname), p + 1);
502
+ } else {
503
+ get_c_name(cname, sizeof(cname), path);
504
+ }
505
+ namelist_add(&cmodule_list, path, cname, 0);
506
+ continue;
507
+ }
508
+ if (opt == 'D') {
509
+ if (!optarg) {
510
+ check_hasarg(optind, argc, opt);
511
+ optarg = argv[optind++];
512
+ }
513
+ namelist_add(&dynamic_module_list, optarg, NULL, 0);
514
+ continue;
515
+ }
516
+ if (opt == 'P') {
517
+ load_system_modules = false;
518
+ continue;
519
+ }
520
+ if (opt == 's') {
521
+ strip++;
522
+ continue;
523
+ }
524
+ if (opt == 'p') {
525
+ if (!optarg) {
526
+ check_hasarg(optind, argc, opt);
527
+ optarg = argv[optind++];
528
+ }
529
+ c_ident_prefix = optarg;
530
+ continue;
531
+ }
532
+ if (opt == 'S') {
533
+ if (!optarg) {
534
+ check_hasarg(optind, argc, opt);
535
+ optarg = argv[optind++];
536
+ }
537
+ stack_size = parse_limit(optarg);
538
+ continue;
539
+ }
540
+ help();
541
+ }
542
+ }
543
+
544
+ if (load_system_modules) {
545
+ /* add system modules */
546
+ namelist_add(&cmodule_list, "qjs:std", "std", 0);
547
+ namelist_add(&cmodule_list, "qjs:os", "os", 0);
548
+ namelist_add(&cmodule_list, "qjs:bjson", "bjson", 0);
549
+ namelist_add(&cmodule_list, "std", "std", 0);
550
+ namelist_add(&cmodule_list, "os", "os", 0);
551
+ namelist_add(&cmodule_list, "bjson", "bjson", 0);
552
+ }
553
+
554
+ if (optind >= argc)
555
+ help();
556
+
557
+ if (!out_filename)
558
+ out_filename = "out.c";
559
+
560
+ js__pstrcpy(cfilename, sizeof(cfilename), out_filename);
561
+
562
+ if (output_type == OUTPUT_RAW)
563
+ fo = fopen(cfilename, "wb");
564
+ else
565
+ fo = fopen(cfilename, "w");
566
+
567
+ if (!fo) {
568
+ perror(cfilename);
569
+ exit(1);
570
+ }
571
+ outfile = fo;
572
+
573
+ rt = JS_NewRuntime();
574
+ ctx = JS_NewContext(rt);
575
+
576
+ /* loader for ES6 modules */
577
+ JS_SetModuleLoaderFunc(rt, NULL, jsc_module_loader, NULL);
578
+
579
+ if (output_type != OUTPUT_RAW) {
580
+ fprintf(fo, "/* File generated automatically by the QuickJS-ng compiler. */\n"
581
+ "\n"
582
+ );
583
+ }
584
+
585
+ if (output_type == OUTPUT_C_MAIN) {
586
+ fprintf(fo, "#include \"quickjs-libc.h\"\n"
587
+ "\n"
588
+ );
589
+ } else if (output_type == OUTPUT_C) {
590
+ fprintf(fo, "#include <inttypes.h>\n"
591
+ "\n"
592
+ );
593
+ }
594
+
595
+ for(i = optind; i < argc; i++) {
596
+ const char *filename = argv[i];
597
+ compile_file(ctx, fo, filename, script_name, cname, module);
598
+ cname = NULL;
599
+ }
600
+
601
+ for(i = 0; i < dynamic_module_list.count; i++) {
602
+ if (!jsc_module_loader(ctx, dynamic_module_list.array[i].name, NULL)) {
603
+ fprintf(stderr, "Could not load dynamic module '%s'\n",
604
+ dynamic_module_list.array[i].name);
605
+ exit(1);
606
+ }
607
+ }
608
+
609
+ if (output_type == OUTPUT_C_MAIN) {
610
+ fprintf(fo,
611
+ "static JSContext *JS_NewCustomContext(JSRuntime *rt)\n"
612
+ "{\n"
613
+ " JSContext *ctx = JS_NewContext(rt);\n"
614
+ " if (!ctx)\n"
615
+ " return NULL;\n");
616
+ /* add the precompiled modules (XXX: could modify the module
617
+ loader instead) */
618
+ for(i = 0; i < init_module_list.count; i++) {
619
+ namelist_entry_t *e = &init_module_list.array[i];
620
+ /* initialize the static C modules */
621
+
622
+ fprintf(fo,
623
+ " {\n"
624
+ " extern JSModuleDef *js_init_module_%s(JSContext *ctx, const char *name);\n"
625
+ " js_init_module_%s(ctx, \"%s\");\n"
626
+ " }\n",
627
+ e->short_name, e->short_name, e->name);
628
+ }
629
+ for(i = 0; i < cname_list.count; i++) {
630
+ namelist_entry_t *e = &cname_list.array[i];
631
+ if (e->flags) {
632
+ fprintf(fo, " js_std_eval_binary(ctx, %s, %s_size, 1);\n",
633
+ e->name, e->name);
634
+ }
635
+ }
636
+ fprintf(fo,
637
+ " return ctx;\n"
638
+ "}\n\n");
639
+
640
+ fputs(main_c_template1, fo);
641
+
642
+ if (stack_size != 0) {
643
+ fprintf(fo, " JS_SetMaxStackSize(rt, %u);\n",
644
+ (unsigned int)stack_size);
645
+ }
646
+
647
+ /* add the module loader */
648
+ fprintf(fo, " JS_SetModuleLoaderFunc2(rt, NULL, js_module_loader, js_module_check_attributes, NULL);\n");
649
+
650
+ fprintf(fo,
651
+ " ctx = JS_NewCustomContext(rt);\n"
652
+ " js_std_add_helpers(ctx, argc, argv);\n");
653
+
654
+ for(i = 0; i < cname_list.count; i++) {
655
+ namelist_entry_t *e = &cname_list.array[i];
656
+ if (!e->flags) {
657
+ fprintf(fo, " js_std_eval_binary(ctx, %s, %s_size, 0);\n",
658
+ e->name, e->name);
659
+ }
660
+ }
661
+ fputs(main_c_template2, fo);
662
+ }
663
+
664
+ JS_FreeContext(ctx);
665
+ JS_FreeRuntime(rt);
666
+
667
+ fclose(fo);
668
+
669
+ namelist_free(&cname_list);
670
+ namelist_free(&cmodule_list);
671
+ namelist_free(&init_module_list);
672
+ return 0;
673
+ }