From e02c2dccdd5044c9aa3edb874d26759afb0e1cb9 Mon Sep 17 00:00:00 2001 From: ewowi Date: Sun, 2 Nov 2025 21:51:27 +0100 Subject: [PATCH 1/4] Fix warnings findtext: const char * heap_caps_free instead of heap_caps_aligned_free const char * _div[] add return to _rand displayStat: const char * --- src/NodeToken.h | 2 +- src/asm_struct_enum.h | 2 +- src/execute_asm.h | 2 +- src/functionlib.h | 5 +++-- 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/NodeToken.h b/src/NodeToken.h index 44b59bd..9322ade 100644 --- a/src/NodeToken.h +++ b/src/NodeToken.h @@ -135,7 +135,7 @@ void initMem() // printf("We satrt with: %ld free and stack:%ld \n", __startmem, __startStackMemory); #endif } -void displayStat(char *text) +void displayStat(const char *text) { pushToConsole(string_format(" %s :max used memory: %ld maxstack:%ld started %d free mem:%ld consumed %ld time:%dms", text, __maxMemUsage, __MaxStackMemory, __startmem, esp_get_free_heap_size(), __startmem - esp_get_free_heap_size(), (__endtime - __starttime) / 240000)); } diff --git a/src/asm_struct_enum.h b/src/asm_struct_enum.h index b3305a3..69d2eeb 100644 --- a/src/asm_struct_enum.h +++ b/src/asm_struct_enum.h @@ -109,7 +109,7 @@ class Text // _texts.push_back(cc); _it = _texts.begin(); } - int findText(char * str) + int findText(const char * str) { #ifdef __SPEED return -1; diff --git a/src/execute_asm.h b/src/execute_asm.h index 215e5fc..c173f89 100644 --- a/src/execute_asm.h +++ b/src/execute_asm.h @@ -556,7 +556,7 @@ void freeExecutable(executable *ex) if (ex->start_program != NULL) { - heap_caps_aligned_free(ex->start_program); + heap_caps_free(ex->start_program); } ex->start_program = NULL; diff --git a/src/functionlib.h b/src/functionlib.h index e1bb296..432bc7a 100644 --- a/src/functionlib.h +++ b/src/functionlib.h @@ -57,7 +57,7 @@ __ASM__ float __div(float a,float b)\n\ \"divn.s f0, f2, f6\"\n\ \"retw.n\"\n\ }@"; -char * _div[]={ +const char * _div[]={ "@___div(d|d):", "entry a1,16", "div0.s f3, f2", @@ -109,7 +109,8 @@ __ASM__ uint32_t rand(uint32_t mod) \n\ \"retw.n\" \n\ }@"; #else -string _rand="\__ASM__ uint32_t rand(uint32_t mod) \n\ +string _rand="\ +__ASM__ uint32_t rand(uint32_t mod) \n\ {\n\ \"entry a1,56\" \n\ //\"l32r a4,@_stack_rand(d)\" \n\ From 6747ed011f2478a239a19fbb42c4071b9f83ff51 Mon Sep 17 00:00:00 2001 From: ewowi Date: Sat, 28 Mar 2026 20:03:27 +0100 Subject: [PATCH 2/4] add stack_size (default 8K) to _run() and executeAsTask() --- src/execute.h | 56 +++++++++++++++++++++++++-------------------------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/execute.h b/src/execute.h index 7dc67d8..1538af2 100644 --- a/src/execute.h +++ b/src/execute.h @@ -531,7 +531,7 @@ class Executable #endif } - int _run(vector args, bool second_core, int core, Arguments arguments, string json) + int _run(vector args, bool second_core, int core, Arguments arguments, string json, uint32_t stack_size = 4096 * 2) { __run_handle_index = 9999; #ifndef __TEST_DEBUG @@ -580,7 +580,7 @@ class Executable taskname = string_format("_run_task_%d", __run_handle_index); else taskname = string_format("%s_%d", name.c_str(), __run_handle_index); - xTaskCreateUniversal(_run_task, taskname.c_str(), 4096 * 2, this, 3, (TaskHandle_t *)runningPrograms.getHandleByIndex(__run_handle_index), core); + xTaskCreateUniversal(_run_task, taskname.c_str(), stack_size, this, 3, (TaskHandle_t *)runningPrograms.getHandleByIndex(__run_handle_index), core); pushToConsole("Execution on going CTRL + k to stop", true); } @@ -695,7 +695,7 @@ class Executable } return false; } - void executeAsTask(string prog, int core, Arguments arguments, string json) + void executeAsTask(string prog, int core, Arguments arguments, string json, uint32_t stack_size = 8192) { // printf("herqsd sqdsq\n"); args.clear(); @@ -708,7 +708,7 @@ class Executable { vector __args; __args.push_back("@__" + prog); - _run(__args, true, core, arguments, json); + _run(__args, true, core, arguments, json, stack_size); } else { @@ -717,30 +717,30 @@ class Executable #endif } - void executeAsTask(string prog, int core, Arguments arguments) + void executeAsTask(string prog, int core, Arguments arguments, uint32_t stack_size = 8192) { - executeAsTask(prog, core, arguments, ""); + executeAsTask(prog, core, arguments, "", stack_size); } - void executeAsTask(string prog, Arguments arguments) + void executeAsTask(string prog, Arguments arguments, uint32_t stack_size = 8192) { - executeAsTask(prog, __RUN_CORE, arguments); + executeAsTask(prog, __RUN_CORE, arguments, stack_size); } - void executeAsTask(string prog) + void executeAsTask(string prog, uint32_t stack_size = 8192) { args.clear(); - executeAsTask(prog, __RUN_CORE, args); + executeAsTask(prog, __RUN_CORE, args, stack_size); } - void executeAsTask(string prog, int core) + void executeAsTask(string prog, int core, uint32_t stack_size = 8192) { args.clear(); - executeAsTask(prog, core, args); + executeAsTask(prog, core, args, stack_size); } - void executeAsTask(string prog, string json) + void executeAsTask(string prog, string json, uint32_t stack_size = 8192) { // printf("her\n"); args.clear(); - executeAsTask(prog, __RUN_CORE, args, json); + executeAsTask(prog, __RUN_CORE, args, json, stack_size); } #endif bool isRunning() @@ -952,81 +952,81 @@ class _ScriptRuntime } } - void executeAsTask(string name, Arguments arguments) + void executeAsTask(string name, Arguments arguments, uint32_t stack_size = 8192) { Executable *exec = findExecutable(name); if (exec != NULL) { #ifndef __TEST_DEBUG - exec->executeAsTask("main", arguments); + exec->executeAsTask("main", arguments, stack_size); #endif } } - void executeAsTask(string name) + void executeAsTask(string name, uint32_t stack_size = 8192) { Executable *exec = findExecutable(name); if (exec != NULL) { #ifndef __TEST_DEBUG - exec->executeAsTask("main"); + exec->executeAsTask("main", stack_size); #endif } } - void executeAsTaskJ(string name, string json) + void executeAsTaskJ(string name, string json, uint32_t stack_size = 8192) { Executable *exec = findExecutable(name); if (exec != NULL) { #ifndef __TEST_DEBUG - exec->executeAsTask("main", json); + exec->executeAsTask("main", json, stack_size); #endif } } - void executeAsTask(string name, string function, Arguments arguments) + void executeAsTask(string name, string function, Arguments arguments, uint32_t stack_size = 8192) { Executable *exec = findExecutable(name); if (exec != NULL) { #ifndef __TEST_DEBUG - exec->executeAsTask(function, arguments); + exec->executeAsTask(function, arguments, stack_size); #endif } } - void executeAsTask(string name, string function) + void executeAsTask(string name, string function, uint32_t stack_size = 8192) { Executable *exec = findExecutable(name); if (exec != NULL) { #ifndef __TEST_DEBUG - exec->executeAsTask(function); + exec->executeAsTask(function, stack_size); #endif } } - void executeAsTask(string name, int core, Arguments args) + void executeAsTask(string name, int core, Arguments args, uint32_t stack_size = 8192) { Executable *exec = findExecutable(name); if (exec != NULL) { #ifndef __TEST_DEBUG - exec->executeAsTask("main", core, args); + exec->executeAsTask("main", core, args, stack_size); #endif } } - void executeAsTask(string name, int core) + void executeAsTask(string name, int core, uint32_t stack_size = 8192) { Executable *exec = findExecutable(name); if (exec != NULL) { #ifndef __TEST_DEBUG - exec->executeAsTask("main", core); + exec->executeAsTask("main", core, stack_size); #endif } } From bd364c3bf08af2fb3eb4c142c86268403b6ce7e6 Mon Sep 17 00:00:00 2001 From: ewowi Date: Sat, 28 Mar 2026 20:51:05 +0100 Subject: [PATCH 3/4] Support tasks running in PSRAM --- src/execute.h | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/execute.h b/src/execute.h index 1538af2..331f801 100644 --- a/src/execute.h +++ b/src/execute.h @@ -6,6 +6,13 @@ #ifndef __RUN_CORE #define __RUN_CORE 0 #endif +#ifndef __LS_STACK_CAPS +#if defined(CONFIG_IDF_TARGET_ESP32S3) || defined(CONFIG_IDF_TARGET_ESP32P4) + #define __LS_STACK_CAPS (MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT) +#else + #define __LS_STACK_CAPS (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT) +#endif +#endif using namespace std; #ifndef _MAX_PROG_AT_ONCE #define _MAX_PROG_AT_ONCE 10 @@ -507,7 +514,7 @@ class Executable if (__run_handle_index != 9999) { - vTaskDelete(*runningPrograms.getHandleByIndex(__run_handle_index)); + vTaskDeleteWithCaps(*runningPrograms.getHandleByIndex(__run_handle_index)); } _isRunning = false; @@ -580,7 +587,7 @@ class Executable taskname = string_format("_run_task_%d", __run_handle_index); else taskname = string_format("%s_%d", name.c_str(), __run_handle_index); - xTaskCreateUniversal(_run_task, taskname.c_str(), stack_size, this, 3, (TaskHandle_t *)runningPrograms.getHandleByIndex(__run_handle_index), core); + xTaskCreatePinnedToCoreWithCaps(_run_task, taskname.c_str(), stack_size, this, 3, (TaskHandle_t *)runningPrograms.getHandleByIndex(__run_handle_index), core, __LS_STACK_CAPS); pushToConsole("Execution on going CTRL + k to stop", true); } @@ -802,7 +809,7 @@ static void _run_task(void *pvParameters) exec->_isRunning = false; runningPrograms.removeHandle(exec->__run_handle_index); isSyncalled = false; - vTaskDelete(NULL); + vTaskDeleteWithCaps(xTaskGetCurrentTaskHandle()); #endif } From 48715099a9c82cc914efe576b70c7a7364f258ce Mon Sep 17 00:00:00 2001 From: ewowi Date: Thu, 2 Apr 2026 19:08:49 +0200 Subject: [PATCH 4/4] Fix setRGB(random16(NUM_LEDS), CRGB(0, 0, 255)); MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit getChildAtPos returns NULL when out of bounds — that's the confirmed null. The fix belongs in findMaxArgumentSize() in NodeToken.h. Root cause: when an addExternal-registered function (like random16) is used as a nested argument expression (not a statement), ESPLiveScript builds its AST node without children 1 and 2. findMaxArgumentSize() enters the extCallFunctionNode branch and immediately dereferences getChildAtPos(1) without a null check → crash. The fix — add null guards before the two dereferences in findMaxArgumentSize(): Why returning cur_size (0) is semantically correct: findMaxArgumentSize() tells _visitCallFunctionTemplate whether an argument needs stack-spilling before the outer call. The check is findMaxArgumentSize() - 1 >= i — for a scalar like uint16_t from random16, the correct answer is 0 (fits in one register, no spill). Arithmetic expressions like y*width+x also return 0 via the else branch. The early-return preserves that behaviour for nested extern scalars. PR description for the ESPLiveScript repo: ▎ findMaxArgumentSize() crashes when an addExternal-registered function is used as a nested argument expression (e.g. setRGB(random16(n), color)). When an extern call is built as a sub-expression rather than a statement, children 1 and 2 are not populated; the existing code dereferences getChildAtPos(1) unconditionally → null-deref / LoadProhibited on ESP32. ▎ Fix: guard both getChildAtPos(1) and getChildAtPos(2) and return early with 0 if either is null. Zero is the correct return value for a scalar nested extern call (same as arithmetic sub-expressions). --- src/NodeToken.h | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/NodeToken.h b/src/NodeToken.h index 9322ade..0942400 100644 --- a/src/NodeToken.h +++ b/src/NodeToken.h @@ -789,10 +789,14 @@ class NodeToken int cur_size = 0; if (_nodetype == extCallFunctionNode or _nodetype == callFunctionNode) { - cur_size = getChildAtPos(1)->children_size(); - for (int i = 0; i < getChildAtPos(2)->children_size(); i++) + NodeToken *child1 = getChildAtPos(1); + if (!child1) return cur_size; // nested extern call built without formal-param child — scalar, no spill needed + cur_size = child1->children_size(); + NodeToken *child2 = getChildAtPos(2); + if (!child2) return cur_size; + for (int i = 0; i < child2->children_size(); i++) { - int cmp = getChildAtPos(2)->getChildAtPos(i)->findMaxArgumentSize(); + int cmp = child2->getChildAtPos(i)->findMaxArgumentSize(); if (cmp > cur_size) cur_size = cmp; }