From 49f9101702009479a6ec6713359df60cad4765b6 Mon Sep 17 00:00:00 2001 From: Volodymyr Shymanskyy Date: Mon, 20 Jan 2020 04:00:08 +0200 Subject: [PATCH] Add memoryLimit, update examples. #57 --- platforms/arduino_blink/platformio.ini | 2 +- .../arduino_blink/src/m3_arduino_api.cpp | 16 +++--- platforms/arduino_blink/src/main.cpp | 54 ++++++++++++++----- source/m3_config_platforms.h | 2 +- source/m3_env.c | 7 ++- source/m3_env.h | 1 + source/m3_math_utils.h | 2 +- 7 files changed, 60 insertions(+), 24 deletions(-) diff --git a/platforms/arduino_blink/platformio.ini b/platforms/arduino_blink/platformio.ini index 39b33f7..8c0b478 100644 --- a/platforms/arduino_blink/platformio.ini +++ b/platforms/arduino_blink/platformio.ini @@ -33,6 +33,6 @@ upload_speed = 460800 src_build_flags = -DLED_BUILTIN=13 - -DESP8266 -Dd_m3FixedHeap=0x6000 -Dd_m3LinearMemLimit=2048 -Dd_m3LogOutput=false + -DESP8266 -Dd_m3FixedHeap=0x6000 -Dd_m3LogOutput=false -O3 -flto -Wno-unused-function -Wno-unused-variable -Wno-unused-parameter -Wno-missing-field-initializers diff --git a/platforms/arduino_blink/src/m3_arduino_api.cpp b/platforms/arduino_blink/src/m3_arduino_api.cpp index f3d6f38..49dac80 100644 --- a/platforms/arduino_blink/src/m3_arduino_api.cpp +++ b/platforms/arduino_blink/src/m3_arduino_api.cpp @@ -21,7 +21,8 @@ m3ApiRawFunction(m3_arduino_delay) { m3ApiGetArg (uint32_t, ms) - //printf("api: delay %d\n", ms); // you can also trace API calls + // You can also trace API calls + //Serial.print("api: delay "); Serial.println(ms); delay(ms); @@ -33,9 +34,9 @@ m3ApiRawFunction(m3_arduino_delay) uint8_t mapPinMode(uint8_t mode) { switch(mode) { - case (0): return INPUT; - case (1): return OUTPUT; - case (2): return INPUT_PULLUP; + case 0: return INPUT; + case 1: return OUTPUT; + case 2: return INPUT_PULLUP; } return INPUT; } @@ -45,7 +46,10 @@ m3ApiRawFunction(m3_arduino_pinMode) m3ApiGetArg (uint32_t, pin) m3ApiGetArg (uint32_t, mode) - pinMode(pin, mapPinMode(mode)); +#if !defined(PARTICLE) + typedef uint8_t PinMode; +#endif + pinMode(pin, (PinMode)mapPinMode(mode)); m3ApiSuccess(); } @@ -74,7 +78,7 @@ m3ApiRawFunction(m3_dummy) m3ApiSuccess(); } -M3Result m3_LinkArduino (IM3Runtime runtime) +M3Result LinkArduino (IM3Runtime runtime) { IM3Module module = runtime->modules; const char* arduino = "arduino"; diff --git a/platforms/arduino_blink/src/main.cpp b/platforms/arduino_blink/src/main.cpp index e538a15..7c6a0c9 100644 --- a/platforms/arduino_blink/src/main.cpp +++ b/platforms/arduino_blink/src/main.cpp @@ -8,6 +8,24 @@ #include "Arduino.h" #include "m3/m3.h" +#include "m3/m3_env.h" + +/* + * Configuration + */ + +// Redefine the default LED pin here, if needed +#define LED_BUILTIN 13 + +#define WASM_STACK_SLOTS 1024 +#define NATIVE_STACK_SIZE 32768 + +// Most devices that cannot allocate a 64KiB wasm page +#define WASM_MEMORY_LIMIT 2048 + +/* + * WebAssembly app + */ // C++ app #include "../wasm_cpp/app.wasm.h" @@ -21,40 +39,48 @@ // TinyGO app. For this, change _start to cwa_main below //#include "../wasm_tinygo/app.wasm.h" -M3Result m3_LinkArduino (IM3Runtime runtime); +M3Result LinkArduino (IM3Runtime runtime); + +/* + * Engine start, liftoff! + */ -#define FATAL(msg, ...) { printf("Fatal: " msg "\n", ##__VA_ARGS__); return; } +#define FATAL(func, msg) { Serial.print("Fatal: " func " "); Serial.println(msg); return; } void wasm_task(void*) { M3Result result = m3Err_none; IM3Environment env = m3_NewEnvironment (); - if (!env) FATAL("m3_NewEnvironment failed"); + if (!env) FATAL("NewEnvironment", "failed"); - IM3Runtime runtime = m3_NewRuntime (env, 1024, NULL); - if (!runtime) FATAL("m3_NewRuntime failed"); + IM3Runtime runtime = m3_NewRuntime (env, WASM_STACK_SLOTS, NULL); + if (!runtime) FATAL("NewRuntime", "failed"); + +#ifdef WASM_MEMORY_LIMIT + runtime->memoryLimit = WASM_MEMORY_LIMIT; +#endif IM3Module module; result = m3_ParseModule (env, &module, app_wasm, app_wasm_len-1); - if (result) FATAL("m3_ParseModule: %s", result); + if (result) FATAL("ParseModule", result); result = m3_LoadModule (runtime, module); - if (result) FATAL("m3_LoadModule: %s", result); + if (result) FATAL("LoadModule", result); - result = m3_LinkArduino (runtime); - if (result) FATAL("m3_LinkArduino: %s", result); + result = LinkArduino (runtime); + if (result) FATAL("LinkArduino", result); IM3Function f; result = m3_FindFunction (&f, runtime, "_start"); - if (result) FATAL("m3_FindFunction: %s", result); + if (result) FATAL("FindFunction", result); - printf("Running WebAssembly...\n"); + Serial.println("Running WebAssembly..."); const char* i_argv[1] = { NULL }; result = m3_CallWithArgs (f, 0, i_argv); - if (result) FATAL("m3_CallWithArgs: %s", result); + if (result) FATAL("CallWithArgs", result); // Should not arrive here } @@ -64,11 +90,11 @@ void setup() Serial.begin(115200); delay(100); - Serial.print("\nWasm3 v" M3_VERSION ", build " __DATE__ " " __TIME__ "\n"); + Serial.println("\nWasm3 v" M3_VERSION ", build " __DATE__ " " __TIME__); #ifdef ESP32 // On ESP32, we can launch in a separate thread - xTaskCreate(&wasm_task, "wasm3", 32768, NULL, 5, NULL); + xTaskCreate(&wasm_task, "wasm3", NATIVE_STACK_SIZE, NULL, 5, NULL); #else wasm_task(NULL); #endif diff --git a/source/m3_config_platforms.h b/source/m3_config_platforms.h index 7f56259..0492fde 100644 --- a/source/m3_config_platforms.h +++ b/source/m3_config_platforms.h @@ -248,7 +248,7 @@ typedef int8_t i8; # if defined(ESP8266) || defined(BLUE_PILL) || defined(FOMU) # ifndef d_m3FixedHeap -# define d_m3FixedHeap (8*1024) +# define d_m3FixedHeap (12*1024) # endif # endif diff --git a/source/m3_env.c b/source/m3_env.c index 281689b..851332c 100644 --- a/source/m3_env.c +++ b/source/m3_env.c @@ -7,7 +7,6 @@ #include -#include "m3.h" #include "m3_env.h" #include "m3_compile.h" #include "m3_exec.h" @@ -292,6 +291,12 @@ M3Result ResizeMemory (IM3Runtime io_runtime, u32 i_numPages) if (numPagesToAlloc <= memory->maxPages) { size_t numPageBytes = numPagesToAlloc * d_m3MemPageSize; + + // Limit the amount of memory that gets allocated + if (io_runtime->memoryLimit) { + numPageBytes = min(numPageBytes, io_runtime->memoryLimit); + } + size_t numBytes = numPageBytes + sizeof (M3MemoryHeader); size_t numPreviousBytes = memory->numPages * d_m3MemPageSize; diff --git a/source/m3_env.h b/source/m3_env.h index fafc60e..b73459b 100644 --- a/source/m3_env.h +++ b/source/m3_env.h @@ -223,6 +223,7 @@ typedef struct M3Runtime M3Result runtimeError; M3Memory memory; + u32 memoryLimit; M3ErrorInfo error; #if defined(d_m3VerboseLogs) diff --git a/source/m3_math_utils.h b/source/m3_math_utils.h index 9e33945..f08cb8a 100644 --- a/source/m3_math_utils.h +++ b/source/m3_math_utils.h @@ -81,7 +81,7 @@ int __builtin_clzll(uint64_t value) { // TODO: not sure why, signbit is actually defined in math.h -#if defined (PLATFORMIO) && (defined(ESP8266) || defined(ESP32)) +#if defined(ESP8266) || defined(ESP32) #define signbit(__x) \ ((sizeof(__x) == sizeof(float)) ? __signbitf(__x) : __signbitd(__x)) #endif