summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorDamien George <damien@micropython.org>2021-06-24 10:04:15 +1000
committerDamien George <damien@micropython.org>2021-06-25 11:29:39 +1000
commitc13853f4dab9c65ee6d1af99b25f999b16ef2827 (patch)
tree7d7dd91c9da886439b97779c43b1b6a1f3e43c70
parentcfd08448a1cba0040ad3c62bce02b5f8bd76dd1d (diff)
downloadmicropython-c13853f4dab9c65ee6d1af99b25f999b16ef2827.tar.gz
micropython-c13853f4dab9c65ee6d1af99b25f999b16ef2827.zip
javascript: Rework Makefile and GC so it works with latest Emscripten.
The GC now works correctly using asyncify and the functions emscripten_scan_stack() and emscripten_scan_registers(). Stack/call depth is monitored via the use of the pystack option. Fixes issue #6738. Signed-off-by: Damien George <damien@micropython.org>
-rw-r--r--ports/javascript/JSBackend.patch10
-rw-r--r--ports/javascript/Makefile26
-rw-r--r--ports/javascript/README.md22
-rw-r--r--ports/javascript/main.c21
4 files changed, 23 insertions, 56 deletions
diff --git a/ports/javascript/JSBackend.patch b/ports/javascript/JSBackend.patch
deleted file mode 100644
index a5fd41a3fb..0000000000
--- a/ports/javascript/JSBackend.patch
+++ /dev/null
@@ -1,10 +0,0 @@
---- JSBackend.cpp 2018-01-10 16:35:07.331418145 +1100
-+++ JSBackend_mp_js.cpp 2018-01-10 16:40:04.804633134 +1100
-@@ -4280,6 +4280,7 @@
-
- void JSWriter::calculateNativizedVars(const Function *F) {
- NativizedVars.clear();
-+ return;
-
- for (Function::const_iterator I = F->begin(), BE = F->end(); I != BE; ++I) {
- auto BI = &*I;
diff --git a/ports/javascript/Makefile b/ports/javascript/Makefile
index 9723675546..171f53b952 100644
--- a/ports/javascript/Makefile
+++ b/ports/javascript/Makefile
@@ -6,24 +6,16 @@ QSTR_DEFS = qstrdefsport.h
include $(TOP)/py/py.mk
-CC = emcc -g4
-LD = emcc -g4
+CC = emcc
+LD = emcc
INC += -I.
INC += -I$(TOP)
INC += -I$(BUILD)
-CPP = clang -E
-
-ifdef EMSCRIPTEN
- CPP += -isystem $(EMSCRIPTEN)/system/include/libc -cxx-isystem $(EMSCRIPTEN)/system/include/libcxx
-endif
-
-CFLAGS = -m32 -Wall -Werror -Wdouble-promotion -Wfloat-conversion $(INC) -std=c99 $(COPT)
-LDFLAGS = -m32 -Wl,-Map=$@.map,--cref -Wl,--gc-sections
-
-CFLAGS += -O0 -DNDEBUG
-CFLAGS += -fdata-sections -ffunction-sections
+CFLAGS += -std=c99 -Wall -Werror -Wdouble-promotion -Wfloat-conversion
+CFLAGS += -O3 -DNDEBUG
+CFLAGS += $(INC)
ifneq ($(FROZEN_MPY_DIR),)
# To use frozen bytecode, put your .py files in a subdirectory (eg frozen/) and
@@ -46,12 +38,12 @@ SRC_C = \
SRC_QSTR += $(SRC_C)
-OBJ =
-OBJ = $(PY_O)
+OBJ += $(PY_O)
OBJ += $(addprefix $(BUILD)/, $(SRC_LIB:.c=.o))
OBJ += $(addprefix $(BUILD)/, $(SRC_C:.c=.o))
-JSFLAGS = -O0 -s EXPORTED_FUNCTIONS="['_mp_js_init', '_mp_js_init_repl', '_mp_js_do_str', '_mp_js_process_char', '_mp_hal_get_interrupt_char', '_mp_sched_keyboard_interrupt']" -s EXTRA_EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']" -s "BINARYEN_TRAP_MODE='clamp'" --memory-init-file 0 --js-library library.js
+JSFLAGS += -s ASYNCIFY
+JSFLAGS += -s EXPORTED_FUNCTIONS="['_mp_js_init', '_mp_js_init_repl', '_mp_js_do_str', '_mp_js_process_char', '_mp_hal_get_interrupt_char', '_mp_sched_keyboard_interrupt']" -s EXTRA_EXPORTED_RUNTIME_METHODS="['ccall', 'cwrap']" -s --memory-init-file 0 --js-library library.js
all: $(BUILD)/micropython.js
@@ -65,6 +57,6 @@ min: $(BUILD)/micropython.js
test: $(BUILD)/micropython.js $(TOP)/tests/run-tests.py
$(eval DIRNAME=ports/$(notdir $(CURDIR)))
- cd $(TOP)/tests && MICROPY_MICROPYTHON=../ports/javascript/node_run.sh ./run-tests.py
+ cd $(TOP)/tests && MICROPY_MICROPYTHON=../ports/javascript/node_run.sh ./run-tests.py -j1
include $(TOP)/py/mkrules.mk
diff --git a/ports/javascript/README.md b/ports/javascript/README.md
index ac268bb3bf..39808943b1 100644
--- a/ports/javascript/README.md
+++ b/ports/javascript/README.md
@@ -7,17 +7,7 @@ Dependencies
------------
Building micropython.js bears the same requirements as the standard MicroPython
-ports with the addition of Emscripten (and uglify-js for the minified file).
-
-A standard installation of Emscripten should provide functional code, however
-if memory errors are encountered it may be worthwhile to modify the tool.
-`emscripten-fastcomp/lib/Target/JSBackend.cpp` may require the minor fix
-found in JSBackend.patch. This patch attempts to address situations where
-C code running through Emscripten is denied access to Javascript variables
-leading to false-positives in the MicroPython garbage collector as variables
-with pointers exclusively in Javascript will be erased prematurely.
-Refer to Emscripten documentation for instructions on building Emscripten
-from source.
+ports with the addition of Emscripten (and uglify-js for the minified file).
Build instructions
------------------
@@ -39,15 +29,15 @@ Access the repl with:
Stack size may be modified using:
- $ node build/micropython.js -X stack=64K
+ $ node build/micropython.js -X stack=64K
Where stack size may be represented in Bytes, KiB or MiB.
MicroPython scripts may be executed using:
- $ node build/micropython.js hello.py
+ $ node build/micropython.js hello.py
-Alternatively micropython.js may by accessed by other javascript programs in node
+Alternatively micropython.js may by accessed by other javascript programs in node
using the require command and the general API outlined below. For example:
```javascript
@@ -85,7 +75,7 @@ demonstrates basic functionality:
```
MicroPython code execution will suspend the browser so be sure to atomize usage
-within this environment. Unfortunately interrupts have not been implemented for the
+within this environment. Unfortunately interrupts have not been implemented for the
browser.
Testing
@@ -124,5 +114,5 @@ the repl.
mp_js_process_char(char)
```
-Input character into MicroPython repl. `char` must be of type `number`. This
+Input character into MicroPython repl. `char` must be of type `number`. This
will execute MicroPython code when necessary.
diff --git a/ports/javascript/main.c b/ports/javascript/main.c
index 5d295f9295..c56f1a2cba 100644
--- a/ports/javascript/main.c
+++ b/ports/javascript/main.c
@@ -3,7 +3,7 @@
*
* The MIT License (MIT)
*
- * Copyright (c) 2013, 2014 Damien P. George and 2017, 2018 Rami Ali
+ * Copyright (c) 2013-2021 Damien P. George and 2017, 2018 Rami Ali
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -36,6 +36,7 @@
#include "py/mperrno.h"
#include "lib/utils/pyexec.h"
+#include "emscripten.h"
#include "library.h"
#if MICROPY_ENABLE_COMPILER
@@ -70,8 +71,6 @@ int do_str(const char *src, mp_parse_input_kind_t input_kind) {
}
#endif
-static char *stack_top;
-
int mp_js_do_str(const char *code) {
return do_str(code, MP_PARSE_FILE_INPUT);
}
@@ -81,9 +80,6 @@ int mp_js_process_char(int c) {
}
void mp_js_init(int heap_size) {
- int stack_dummy;
- stack_top = (char *)&stack_dummy;
-
#if MICROPY_ENABLE_GC
char *heap = (char *)malloc(heap_size * sizeof(char));
gc_init(heap, heap + heap_size);
@@ -105,15 +101,14 @@ void mp_js_init_repl() {
pyexec_event_repl_init();
}
+STATIC void gc_scan_func(void *begin, void *end) {
+ gc_collect_root((void **)begin, (void **)end - (void **)begin + 1);
+}
+
void gc_collect(void) {
- // WARNING: This gc_collect implementation doesn't try to get root
- // pointers from CPU registers, and thus may function incorrectly.
- jmp_buf dummy;
- if (setjmp(dummy) == 0) {
- longjmp(dummy, 1);
- }
gc_collect_start();
- gc_collect_root((void *)stack_top, ((mp_uint_t)(void *)(&dummy + 1) - (mp_uint_t)stack_top) / sizeof(mp_uint_t));
+ emscripten_scan_stack(gc_scan_func);
+ emscripten_scan_registers(gc_scan_func);
gc_collect_end();
}