1 #include "amp_config.h"
2 #include "aos/list.h"
3 #include "aos_system.h"
4 #include "quickjs-libc.h"
5 #include "quickjs.h"
6 #include "quickjs_addon.h"
7 #include <stdbool.h>
8 #include <stdint.h>
9 #include <stdio.h>
10 #include <string.h>
11
12 #define MOD_STR "QUICKJS_INIT"
13
14 static JSRuntime *rt = NULL;
15 static JSContext *ctx = NULL;
16 static JSValue val;
17
18 extern int g_repl_config;
19 extern JSModuleDef *quickjs_module_loader(JSContext *ctx, const char *module_name, void *opaque);
20
js_get_context(void)21 JSContext *js_get_context(void)
22 {
23 return ctx;
24 }
25
jsengine_register_addons()26 static void jsengine_register_addons()
27 {
28 module_builtin_register();
29 #if 1
30 extern uint32_t jslib_events_size;
31 extern uint8_t jslib_events[];
32 quickjs_add_prebuild_module("events", jslib_events, jslib_events_size);
33 #endif
34 #ifdef JSE_HW_ADDON_GPIO
35 module_gpio_register();
36 extern uint32_t jslib_gpio_size;
37 extern uint8_t jslib_gpio[];
38 quickjs_add_prebuild_module("gpio", jslib_gpio, jslib_gpio_size);
39 #endif
40
41 #ifdef JSE_HW_ADDON_IR
42 module_ir_register();
43 #endif
44
45 #ifdef JSE_HW_ADDON_PWM
46 module_pwm_register();
47 extern uint32_t jslib_pwm_size;
48 extern uint8_t jslib_pwm[];
49 quickjs_add_prebuild_module("pwm", jslib_pwm, jslib_pwm_size);
50 #endif
51
52 #ifdef JSE_HW_ADDON_ONEWIRE
53 module_onewire_register();
54 extern uint32_t jslib_onewire_size;
55 extern uint8_t jslib_onewire[];
56 quickjs_add_prebuild_module("onewire", jslib_onewire, jslib_onewire_size);
57 #endif
58
59 #ifdef JSE_HW_ADDON_RTC
60 module_rtc_register();
61 extern uint32_t jslib_rtc_size;
62 extern uint8_t jslib_rtc[];
63 quickjs_add_prebuild_module("rtc", jslib_rtc, jslib_rtc_size);
64 #endif
65 #ifdef JSE_CORE_ADDON_CRYPTO
66 module_crypto_register();
67 extern uint32_t jslib_crypto_size;
68 extern uint8_t jslib_crypto[];
69 quickjs_add_prebuild_module("crypto", jslib_crypto, jslib_crypto_size);
70 #endif
71 #ifdef JSE_HW_ADDON_WDG
72 module_wdg_register();
73 extern uint32_t jslib_wdg_size;
74 extern uint8_t jslib_wdg[];
75 quickjs_add_prebuild_module("wdg", jslib_wdg, jslib_wdg_size);
76 #endif
77
78 #ifdef JSE_HW_ADDON_UART
79 module_uart_register();
80 extern uint32_t jslib_uart_size;
81 extern uint8_t jslib_uart[];
82 quickjs_add_prebuild_module("uart", jslib_uart, jslib_uart_size);
83 #endif
84
85 #ifdef JSE_HW_ADDON_SPI
86 module_spi_register();
87 extern uint32_t jslib_spi_size;
88 extern uint8_t jslib_spi[];
89 quickjs_add_prebuild_module("spi", jslib_spi, jslib_spi_size);
90 #endif
91
92 #ifdef JSE_HW_ADDON_ADC
93 module_adc_register();
94 extern uint32_t jslib_adc_size;
95 extern uint8_t jslib_adc[];
96 quickjs_add_prebuild_module("adc", jslib_adc, jslib_adc_size);
97 #endif
98
99 #ifdef JSE_HW_ADDON_TIMER
100 module_timer_register();
101 #endif
102
103 #ifdef JSE_HW_ADDON_DAC
104 module_dac_register();
105 extern uint32_t jslib_dac_size;
106 extern uint8_t jslib_dac[];
107 quickjs_add_prebuild_module("dac", jslib_dac, jslib_dac_size);
108 #endif
109
110 #ifdef JSE_HW_ADDON_DS18B20
111 extern uint32_t jslib_ds18b20_size;
112 extern uint8_t jslib_ds18b20[];
113 quickjs_add_prebuild_module("ds18b20", jslib_ds18b20, jslib_ds18b20_size);
114 #endif
115
116 #ifdef JSE_CORE_ADDON_SYSTIMER
117 module_systimer_register();
118 #endif
119
120 #ifdef JSE_NET_ADDON_TCP
121 module_tcp_register();
122 extern uint32_t jslib_tcp_size;
123 extern uint8_t jslib_tcp[];
124 quickjs_add_prebuild_module("tcp", jslib_tcp, jslib_tcp_size);
125 #endif
126
127 #ifdef JSE_NET_ADDON_UDP
128 module_udp_register();
129 extern uint32_t jslib_udp_size;
130 extern uint8_t jslib_udp[];
131 quickjs_add_prebuild_module("udp", jslib_udp, jslib_udp_size);
132 #endif
133
134 #ifdef JSE_NET_ADDON_HTTP
135 module_http_register();
136 #endif
137
138 #ifdef JSE_NET_ADDON_MQTT
139 module_mqtt_register();
140 extern uint32_t jslib_mqtt_size;
141 extern uint8_t jslib_mqtt[];
142 quickjs_add_prebuild_module("mqtt", jslib_mqtt, jslib_mqtt_size);
143 #endif
144
145 #ifdef JSE_NET_ADDON_NETMGR
146 module_netmgr_register();
147 extern uint32_t jslib_netmgr_size;
148 extern uint8_t jslib_netmgr[];
149 quickjs_add_prebuild_module("netmgr", jslib_netmgr, jslib_netmgr_size);
150 #endif
151
152 #ifdef JSE_CORE_ADDON_SYSTEM
153 module_system_register();
154 #endif
155
156 #ifdef JSE_ADVANCED_ADDON_OTA
157 module_app_ota_register();
158 extern uint32_t jslib_appota_size;
159 extern uint8_t jslib_appota[];
160 quickjs_add_prebuild_module("appota", jslib_appota, jslib_appota_size);
161 #endif
162
163 #ifdef JSE_ADVANCED_ADDON_UI
164 page_entry_register();
165 app_entry_register();
166 // module_vm_register();
167 module_ui_register();
168 #endif
169
170 #ifdef JSE_HW_ADDON_LCD
171 module_lcd_register();
172 #endif
173
174 #ifdef JSE_HW_ADDON_I2C
175 module_i2c_register();
176 extern uint32_t jslib_i2c_size;
177 extern uint8_t jslib_i2c[];
178 quickjs_add_prebuild_module("i2c", jslib_i2c, jslib_i2c_size);
179 #endif
180
181 #ifdef JSE_ADVANCED_ADDON_AIOT_DEVICE
182 module_aiot_device_register();
183 module_aiot_gateway_register();
184 extern uint32_t jslib_iot_size;
185 extern uint8_t jslib_iot[];
186 quickjs_add_prebuild_module("iot", jslib_iot, jslib_iot_size);
187 #endif
188
189 #ifdef JSE_CORE_ADDON_LOG
190 module_log_register();
191 #endif
192
193 #ifdef JSE_WIRELESS_ADDON_BT_HOST
194 module_bt_host_register();
195 extern uint32_t jslib_bt_host_size;
196 extern uint8_t jslib_bt_host[];
197 quickjs_add_prebuild_module("bt_host", jslib_bt_host, jslib_bt_host_size);
198 #endif
199
200 #ifdef JSE_CORE_ADDON_FS
201 module_fs_register();
202 extern uint32_t jslib_fs_size;
203 extern uint8_t jslib_fs[];
204 quickjs_add_prebuild_module("fs", jslib_fs, jslib_fs_size);
205 #endif
206
207 #ifdef JSE_CORE_ADDON_KV
208 module_kv_register();
209 #endif
210
211 #ifdef JSE_ADVANCED_ADDON_AUDIOPLAYER
212 module_audio_register();
213 extern uint32_t jslib_audioplayer_size;
214 extern uint8_t jslib_audioplayer[];
215 quickjs_add_prebuild_module("audioplayer", jslib_audioplayer, jslib_audioplayer_size);
216 #endif
217
218 #ifdef JSE_CORE_ADDON_CHECKSUM
219 module_checksum_register();
220 extern uint32_t jslib_checksum_size;
221 extern uint8_t jslib_checksum[];
222 quickjs_add_prebuild_module("checksum", jslib_checksum, jslib_checksum_size);
223 #endif
224
225 #ifdef JSE_ADVANCED_ADDON_BLECFGNET
226 module_blecfgnet_register();
227 #endif
228
229 #ifdef JSE_NET_ADDON_CELLULAR
230 module_cellular_register();
231 #endif
232
233 #if defined(JSE_NET_ADDON_NETMGR) || defined(JSE_NET_ADDON_CELLULAR)
234 module_network_register();
235 extern uint32_t jslib_network_size;
236 extern uint8_t jslib_network[];
237 quickjs_add_prebuild_module("network", jslib_network, jslib_network_size);
238 #endif
239
240 #if (defined(JSE_NET_ADDON_NETMGR) || defined(JSE_NET_ADDON_CELLULAR)) && defined(JSE_ADVANCED_ADDON_LOCATION)
241 extern uint32_t jslib_location_size;
242 extern uint8_t jslib_location[];
243 quickjs_add_prebuild_module("location", jslib_location, jslib_location_size);
244 #endif
245
246 #ifdef JSE_ADVANCED_ADDON_OSS
247 module_oss_register();
248 #endif
249 }
250
amp_context_set(JSContext * context)251 int amp_context_set(JSContext *context)
252 {
253 if (!context) {
254 aos_printf("%s: context null", __func__);
255 return -1;
256 }
257 ctx = context;
258 aos_printf("%s: js context set\r\n", __func__);
259 return 0;
260 }
261
amp_modules_load(JSContext * ctx,const char * module_name,void * opaque)262 JSModuleDef *amp_modules_load(JSContext *ctx, const char *module_name, void *opaque)
263 {
264 aos_printf("%s: load module %s\r\n", __func__, module_name ? module_name : "null");
265 return quickjs_module_loader(ctx, module_name, opaque);
266 }
267
jsengine_init(void)268 int jsengine_init(void)
269 {
270 #ifndef HAASUI_AMP_BUILD
271 rt = JS_NewRuntime();
272 if (rt == NULL) {
273 aos_printf("JS_NewRuntime failure");
274 aos_task_exit(1);
275 }
276 js_std_init_handlers(rt);
277
278 ctx = JS_NewContext(rt);
279 if (ctx == NULL) {
280 aos_printf("JS_NewContext failure");
281 }
282
283 JS_SetCanBlock(rt, 1);
284
285 /* loader for ES6 modules */
286 JS_SetModuleLoaderFunc(rt, NULL, quickjs_module_loader, NULL);
287
288 js_std_add_helpers(ctx, -1, NULL);
289
290 /* system modules */
291 js_init_module_std(ctx, "std");
292 js_init_module_os(ctx, "os");
293
294 jsengine_register_addons();
295
296 if (g_repl_config) {
297 module_repl_register();
298 }
299
300 #else
301 js_std_add_helpers(ctx, -1, NULL);
302
303 /* system modules */
304 js_init_module_std(ctx, "std");
305 js_init_module_os(ctx, "os");
306
307 jsengine_register_addons();
308 #endif
309 aos_printf("quickjs engine started !\n");
310
311 return 0;
312 }
313
qjs_dump_obj(JSContext * ctx,JSValueConst val)314 void qjs_dump_obj(JSContext *ctx, JSValueConst val)
315 {
316 const char *str;
317
318 str = JS_ToCString(ctx, val);
319 if (str) {
320 aos_printf("%s", str);
321 JS_FreeCString(ctx, str);
322 } else {
323 aos_printf("[exception]\n");
324 }
325 }
326
qjs_std_dump_error1(JSContext * ctx,JSValueConst exception_val)327 void qjs_std_dump_error1(JSContext *ctx, JSValueConst exception_val)
328 {
329 JSValue val;
330 bool is_error;
331
332 is_error = JS_IsError(ctx, exception_val);
333 qjs_dump_obj(ctx, exception_val);
334 if (is_error) {
335 val = JS_GetPropertyStr(ctx, exception_val, "stack");
336 if (!JS_IsUndefined(val)) {
337 qjs_dump_obj(ctx, val);
338 }
339 JS_FreeValue(ctx, val);
340 }
341 }
342
qjs_std_dump_error(JSContext * ctx)343 void qjs_std_dump_error(JSContext *ctx)
344 {
345 JSValue exception_val;
346
347 exception_val = JS_GetException(ctx);
348
349 qjs_std_dump_error1(ctx, exception_val);
350 JS_FreeValue(ctx, exception_val);
351 }
352
jsengine_eval_file(const char * filename)353 void jsengine_eval_file(const char *filename)
354 {
355 uint8_t *buf = NULL;
356 size_t buf_len = 0;
357 int eval_flags = JS_EVAL_TYPE_MODULE;
358
359 aos_printf("begin eval file: %s\n", filename);
360
361 buf = js_load_file(ctx, &buf_len, filename);
362 if (buf == NULL) {
363 aos_printf("read js file %s error\n", filename);
364 return;
365 }
366 if (filename[strlen(filename) - 1] == 's') {
367 val = JS_Eval(ctx, buf, buf_len, filename, eval_flags);
368 if (JS_IsException(val)) {
369 aos_printf("js engine eval %s error\n", filename);
370 aos_printf("app.js content: \r\n");
371 aos_printf("%s\r\n", buf);
372 qjs_std_dump_error(ctx);
373 }
374 JS_FreeValue(ctx, val);
375 } else {
376 js_std_eval_binary(ctx, buf, buf_len, 0);
377 }
378
379 js_free(ctx, buf);
380 if (g_repl_config) {
381 extern uint32_t jslib_repl_size;
382 extern uint8_t jslib_repl[];
383 js_std_eval_binary(ctx, jslib_repl, jslib_repl_size, 0);
384 }
385 }
386
jsengine_loop_once(void)387 void jsengine_loop_once(void)
388 {
389 js_std_loop_once(ctx);
390 }
391
jsengine_exit(void)392 void jsengine_exit(void)
393 {
394 JS_FreeValue(ctx, val);
395 js_std_loop(ctx);
396 JS_FreeContext(ctx);
397 JS_FreeRuntime(rt);
398 }
399
dump_quickjs_memory(void)400 void dump_quickjs_memory(void)
401 {
402 JS_RunGC(rt);
403 JSMemoryUsage stats;
404 JS_ComputeMemoryUsage(rt, &stats);
405 JS_DumpMemoryUsage(stdout, &stats, rt);
406 }