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>
This commit is contained in:
parent
cfd08448a1
commit
c13853f4da
@ -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;
|
@ -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
|
||||
|
@ -9,16 +9,6 @@ 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.
|
||||
|
||||
Build instructions
|
||||
------------------
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user