Skip to content
This repository was archived by the owner on Aug 5, 2022. It is now read-only.

Commit e4e4c95

Browse files
brianjjonesgrgustaf
authored andcommitted
[modules] Create a new build target 'dynamic' (#1784)
This new target allows an app to run JS files from the FS, allowing you to change what JS is running on the fly in regular non-ashell builds. This mode only gives read access, but it does include the parser. Signed-off-by: Brian J Jones <[email protected]>
1 parent ed85a4d commit e4e4c95

File tree

11 files changed

+121
-43
lines changed

11 files changed

+121
-43
lines changed

Makefile

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright (c) 2016-2017, Intel Corporation.
1+
# Copyright (c) 2016-2018, Intel Corporation.
22

33
# a place to add temporary defines to ZJS builds such as -DZJS_GPIO_MOCK
44
#ZJS_FLAGS :=
@@ -109,7 +109,7 @@ JERRY_BASE ?= $(ZJS_BASE)/deps/jerryscript
109109
JERRY_OUTPUT = $(OUT)/$(BOARD)/jerry/build
110110

111111
# Generate and run snapshot as byte code instead of running JS directly
112-
ifneq (,$(filter $(MAKECMDGOALS),ide ashell linux))
112+
ifneq (,$(filter $(MAKECMDGOALS),ide ashell linux dynamic))
113113
SNAPSHOT=off
114114
# if the user passes in SNAPSHOT=on for ide, ashell, or linux give an error
115115
ifeq ($(SNAPSHOT), on)
@@ -141,6 +141,11 @@ ZJS_FLAGS += -DIDE_GPIO_PIN=$(IDE_GPIO_PIN)
141141
endif
142142
endif
143143

144+
# Settings for dynamic load builds
145+
ifneq (,$(filter $(MAKECMDGOALS),dynamic))
146+
FORCED := dynamic_load.json,$(FORCED)
147+
endif
148+
144149
ifeq ($(BOARD), arduino_101)
145150
ARC = arc
146151
ARC_RAM = $$((79 - $(RAM)))
@@ -222,6 +227,9 @@ ide: zephyr
222227
.PHONY: ashell
223228
ashell: zephyr
224229

230+
.PHONY: dynamic
231+
dynamic: zephyr
232+
225233
# Flash images
226234
.PHONY: dfu
227235
dfu:
@@ -491,6 +499,7 @@ help:
491499
@echo " pristine: Completely remove all generated files"
492500
@echo " check: Run all the automated build tests"
493501
@echo " quickcheck: Run the quick Linux subset of automated build tests"
502+
@echo " dynamic Build Zephyr in dynamic loading mode. Includes the parser"
494503
@echo
495504
@echo "Build options:"
496505
@echo " BOARD= Specify a Zephyr board to build for"

src/ashell/jerry-code.c

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
#include <zephyr.h>
1616

1717
// JerryScript includes
18-
#include "file-utils.h"
18+
#include "../zjs_file_utils.h"
1919
#include "jerry-code.h"
2020
#include "jerryscript-port.h"
2121

@@ -41,12 +41,6 @@ void javascript_eval_code(const char *source_buffer, ssize_t size)
4141
}
4242
}
4343

44-
void restore_zjs_api()
45-
{
46-
jerry_init(JERRY_INIT_EMPTY);
47-
zjs_modules_init();
48-
}
49-
5044
void javascript_stop()
5145
{
5246
if (parsed_code == 0)
@@ -55,16 +49,7 @@ void javascript_stop()
5549
/* Parsed source code must be freed */
5650
jerry_release_value(parsed_code);
5751
parsed_code = 0;
58-
59-
/* Cleanup engine */
60-
zjs_modules_cleanup();
61-
zjs_remove_all_callbacks();
62-
#ifdef CONFIG_BOARD_ARDUINO_101
63-
zjs_ipm_free_callbacks();
64-
#endif
65-
jerry_cleanup();
66-
67-
restore_zjs_api();
52+
zjs_stop_js();
6853
}
6954

7055
int javascript_parse_code(const char *file_name)

src/ashell/term-cmd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
#include <string.h>
1414

1515
// Zephyr includes
16-
#include "file-utils.h"
16+
#include "../zjs_file_utils.h"
1717
#include "jerryscript-port.h"
1818
#include <atomic.h>
1919
#include <misc/printk.h>

src/ashell/term-ihex.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222
#include "term-cmd.h"
2323
#include "term-uart.h"
2424

25-
#include "file-utils.h"
25+
#include "../zjs_file_utils.h"
2626

2727
#ifndef CONFIG_IHEX_UPLOADER_DEBUG
2828
#define DBG(...) { ; }

src/dynamic_load.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
{
2+
"module": "dynamicload",
3+
"depends": ["buffer", "fs"],
4+
"zjs_config": [
5+
"-I${ZEPHYR_BASE}/ext/fs/fat/include",
6+
"-I./deps",
7+
"-DZJS_DYNAMIC_LOAD"
8+
],
9+
"src": [
10+
"src/zjs_file_utils.c"
11+
]
12+
}

src/main.c

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,12 +20,14 @@
2020
#endif // ZJS_LINUX_BUILD
2121
#include "zjs_script.h"
2222
#include "zjs_util.h"
23-
#ifdef ZJS_ASHELL
23+
#if defined (ZJS_ASHELL) || defined (ZJS_DYNAMIC_LOAD)
2424
#include <gpio.h>
2525
#include "zjs_board.h"
26+
#include "zjs_file_utils.h"
27+
#ifdef ZJS_ASHELL
2628
#include "ashell/ashell.h"
27-
#include "ashell/file-utils.h"
28-
#endif
29+
#endif // ZJS_ASHELL
30+
#endif // defined (ZJS_ASHELL) || defined (ZJS_DYNAMIC_LOAD)
2931

3032
// JerryScript includes
3133
#include "jerryscript.h"
@@ -183,7 +185,7 @@ int main(int argc, char *argv[])
183185

184186
file_name = argv[1];
185187
file_name_len = strlen(argv[1]);
186-
#elif defined ZJS_ASHELL
188+
#elif defined ZJS_ASHELL || defined ZJS_DYNAMIC_LOAD
187189
char *script = NULL;
188190
#else
189191
const char *script = NULL;
@@ -356,6 +358,10 @@ int main(int argc, char *argv[])
356358
}
357359
#endif
358360
while (1) {
361+
#ifdef ZJS_DYNAMIC_LOAD
362+
// Check if we should load a new JS file
363+
zjs_modules_check_load_file();
364+
#endif
359365
#ifdef ZJS_ASHELL
360366
if (ashell_mode) {
361367
zjs_ashell_process();

src/zjs_ashell.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
],
1919
"targets": ["arduino_101", "stm32f4_disco", "olimex_stm32_e407"],
2020
"src": [
21-
"src/ashell/file-utils.c",
21+
"src/zjs_file_utils.c",
2222
"src/ashell/jerry-code.c",
2323
"src/ashell/term-cmd.c",
2424
"src/ashell/term-ihex.c",

src/ashell/file-utils.c renamed to src/zjs_file_utils.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2016-2017, Intel Corporation.
1+
// Copyright (c) 2016-2018, Intel Corporation.
22

33
/**
44
* @file
@@ -8,6 +8,7 @@
88
*/
99

1010
// C includes
11+
#if defined(ZJS_ASHELL) || defined(ZJS_DYNAMIC_LOAD)
1112
#include <ctype.h>
1213
#include <errno.h>
1314
#include <stdint.h>
@@ -24,8 +25,8 @@
2425
#include <misc/printk.h>
2526

2627
// ZJS includes
27-
#include "file-utils.h"
28-
#include "../zjs_util.h"
28+
#include "zjs_file_utils.h"
29+
#include "zjs_util.h"
2930

3031
#define FILE_ERR ERR_PRINT("Read file failed\n")
3132

@@ -210,3 +211,4 @@ char *read_file_alloc(const char *file_name, ssize_t *size)
210211
fs_close_alloc(fp);
211212
return file_buf;
212213
}
214+
#endif // defined(ZJS_ASHELL) || defined(ZJS_DYNAMIC_LOAD)

src/ashell/file-utils.h renamed to src/zjs_file_utils.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
#ifndef __file_wrapper_h__
44
#define __file_wrapper_h__
5-
5+
#if defined(ZJS_ASHELL) || defined(ZJS_DYNAMIC_LOAD)
66
#include <ff.h>
77
#include <fs.h>
88
#include <fs/fat_fs.h>
@@ -18,4 +18,5 @@ ssize_t fs_size(fs_file_t *file);
1818
bool fs_valid_filename(char *filename);
1919
char *read_file_alloc(const char *file_name, ssize_t *size);
2020
int fs_get_boot_cfg_filename(const char *timestamp, char *filename);
21+
#endif // defined(ZJS_ASHELL) || defined(ZJS_DYNAMIC_LOAD)
2122
#endif // __file_wrapper_h__

src/zjs_modules.c

Lines changed: 75 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,27 @@
2424
#include "zjs_timers.h"
2525
#include "zjs_util.h"
2626
#include "jerryscript-ext/module.h"
27-
#ifdef ZJS_ASHELL
28-
#include "ashell/file-utils.h"
27+
#if defined(ZJS_ASHELL) || defined(ZJS_DYNAMIC_LOAD)
28+
#include "zjs_file_utils.h"
2929
#endif
3030

3131
struct routine_map {
3232
zjs_service_routine func;
3333
void *handle;
3434
};
3535

36+
#ifdef ZJS_DYNAMIC_LOAD
37+
static char *load_file;
38+
#endif // ZJS_DYNAMIC_LOAD
39+
3640
static u8_t num_routines = 0;
3741
struct routine_map svc_routine_map[NUM_SERVICE_ROUTINES];
3842

3943
/*****************************************************************
4044
* Real board JavaScript module resolver (ASHELL only currently)
4145
******************************************************************/
4246
#ifndef ZJS_LINUX_BUILD
43-
#ifdef ZJS_ASHELL
44-
47+
#if defined(ZJS_ASHELL) || defined(ZJS_DYNAMIC_LOAD)
4548
// Eval the JavaScript, and return the module.
4649
static bool javascript_eval_code(const char *source_buffer, ssize_t size,
4750
jerry_value_t *ret_val)
@@ -53,14 +56,14 @@ static bool javascript_eval_code(const char *source_buffer, ssize_t size,
5356
}
5457
return true;
5558
}
56-
#endif
59+
#endif // defined(ZJS_ASHELL) || defined(ZJS_DYNAMIC_LOAD)
5760

5861
// Find the module on the filestystem
5962
static bool load_js_module_fs(const jerry_value_t module_name,
6063
jerry_value_t *result)
6164
{
62-
// Currently searching the filesystem is only supported on ashell
63-
#ifdef ZJS_ASHELL
65+
// Currently searching the filesystem is only supported on arduino 101
66+
#if defined(ZJS_ASHELL) || defined(ZJS_DYNAMIC_LOAD)
6467
jerry_size_t module_size = jerry_get_utf8_string_size(module_name) + 1;
6568
char module[module_size];
6669
zjs_copy_jstring(module_name, module, &module_size);
@@ -78,7 +81,8 @@ static bool load_js_module_fs(const jerry_value_t module_name,
7881
return ret;
7982
#else
8083
return false;
81-
#endif
84+
#endif // defined(ZJS_ASHELL) || defined(ZJS_DYNAMIC_LOAD)
85+
8286
}
8387
#else // ZJS_LINUX_BUILD
8488
/****************************************
@@ -228,16 +232,23 @@ static ZJS_DECL_FUNC(native_print_handler)
228232
zjs_free(str);
229233
return ZJS_UNDEFINED;
230234
}
231-
232-
static ZJS_DECL_FUNC(stop_js_handler)
235+
void zjs_stop_js()
233236
{
237+
zjs_modules_cleanup();
238+
zjs_remove_all_callbacks();
234239
#ifdef CONFIG_BOARD_ARDUINO_101
235240
#ifdef CONFIG_IPM
236241
zjs_ipm_free_callbacks();
237-
#endif
238-
#endif
239-
zjs_modules_cleanup();
242+
#endif // CONFIG_IPM
243+
#endif // CONFIG_BOARD_ARDUINO_101
240244
jerry_cleanup();
245+
jerry_init(JERRY_INIT_EMPTY);
246+
zjs_modules_init();
247+
}
248+
249+
static ZJS_DECL_FUNC(stop_js_handler)
250+
{
251+
zjs_stop_js();
241252
return ZJS_UNDEFINED;
242253
}
243254

@@ -255,6 +266,54 @@ static ZJS_DECL_FUNC(process_exit)
255266
exit(status);
256267
}
257268
#endif
269+
#ifdef ZJS_DYNAMIC_LOAD
270+
void zjs_modules_check_load_file()
271+
{
272+
// No file waiting to load, just return
273+
if (load_file == NULL) {
274+
return;
275+
}
276+
277+
zjs_stop_js();
278+
char *buf = NULL;
279+
size_t size;
280+
jerry_value_t parsed_code = 0;
281+
buf = read_file_alloc(load_file, &size);
282+
parsed_code = jerry_parse((const jerry_char_t *)buf, size, false);
283+
zjs_free(buf);
284+
285+
if (!jerry_value_has_error_flag(parsed_code)) {
286+
ZVAL ret_value = jerry_run(parsed_code);
287+
if (jerry_value_has_error_flag(ret_value)) {
288+
ERR_PRINT("Error running JS\n");
289+
}
290+
}
291+
else {
292+
ERR_PRINT("Error parsing JS\n");
293+
}
294+
295+
// Remove the load file so it doesn't load it again
296+
zjs_free(load_file);
297+
load_file = NULL;
298+
jerry_release_value(parsed_code);
299+
}
300+
301+
static ZJS_DECL_FUNC(zjs_run_js)
302+
{
303+
ZJS_VALIDATE_ARGS(Z_STRING);
304+
size_t len = MAX_FILE_NAME;
305+
size_t file_len;
306+
load_file = zjs_malloc(len);
307+
308+
zjs_copy_jstring(argv[0], load_file, &file_len);
309+
310+
if (!fs_exist(load_file)) {
311+
return ZJS_ERROR("File doesn't exist");
312+
}
313+
314+
return ZJS_UNDEFINED;
315+
}
316+
#endif // ZJS_DYNAMIC_LOAD
258317

259318
void zjs_modules_init()
260319
{
@@ -271,6 +330,9 @@ void zjs_modules_init()
271330
zjs_obj_add_function(global_obj, "eval", native_eval_handler);
272331
zjs_obj_add_function(global_obj, "print", native_print_handler);
273332
zjs_obj_add_function(global_obj, "stopJS", stop_js_handler);
333+
#ifdef ZJS_DYNAMIC_LOAD
334+
zjs_obj_add_function(global_obj, "runJS", zjs_run_js);
335+
#endif // ZJS_DYNAMIC_LOAD
274336

275337
// create the C handler for require JS call
276338
zjs_obj_add_function(global_obj, "require", native_require_handler);

src/zjs_modules.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ void zjs_modules_cleanup();
2626
void zjs_register_service_routine(void *handle, zjs_service_routine func);
2727
void zjs_unregister_service_routine(zjs_service_routine func);
2828
s32_t zjs_service_routines(void);
29+
void zjs_stop_js();
2930

3031
#endif // __zjs_modules_h__

0 commit comments

Comments
 (0)