mirror of https://github.com/arendst/Tasmota.git
Merge pull request #15338 from s-hadinger/berry_stack_resize
Berry stack resize debug mode
This commit is contained in:
commit
942c2e9806
|
@ -175,6 +175,14 @@
|
|||
**/
|
||||
#define BE_USE_DEBUG_GC 0
|
||||
|
||||
/* Macro: BE_USE_DEBUG_STACK
|
||||
* Enable Stack Resize debug mode. At each function call
|
||||
* the stack is reallocated at a different memory location
|
||||
* and the previous location is cleared with toxic data.
|
||||
* Default: 0
|
||||
**/
|
||||
#define BE_USE_DEBUG_STACK 0
|
||||
|
||||
/* Macro: BE_USE_MEM_ALIGNED
|
||||
* Some embedded processors have special memory areas
|
||||
* with read/write constraints of being aligned to 32 bits boundaries.
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#include "be_bytecode.h"
|
||||
#include "be_decoder.h"
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if !BE_USE_SCRIPT_COMPILER && !BE_USE_BYTECODE_LOADER
|
||||
#error no compiler or bytecode loader enabled.
|
||||
|
@ -337,9 +338,13 @@ void be_stackpush(bvm *vm)
|
|||
/* check that the stack is able to store `count` items, and increase stack if needed */
|
||||
BERRY_API void be_stack_require(bvm *vm, int count)
|
||||
{
|
||||
#if BE_USE_DEBUG_STACK == 0
|
||||
if (vm->top + count >= vm->stacktop) {
|
||||
be_stack_expansion(vm, count);
|
||||
}
|
||||
#else
|
||||
be_stack_expansion(vm, vm->top - vm->stacktop + count); /* force exact resize each time */
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Scan the entire callstack and adjust all pointer by `offset` */
|
||||
|
@ -372,7 +377,16 @@ static void stack_resize(bvm *vm, size_t size)
|
|||
intptr_t offset;
|
||||
bvalue *old = vm->stack; /* save original pointer of stack before resize */
|
||||
size_t os = (vm->stacktop - old) * sizeof(bvalue); /* size of current stack allocated in bytes */
|
||||
#if BE_USE_DEBUG_STACK == 0
|
||||
vm->stack = be_realloc(vm, old, os, sizeof(bvalue) * size); /* reallocate with the new size */
|
||||
#else /* force a reallocation */
|
||||
size_t ns = sizeof(bvalue) * size;
|
||||
vm->stack = be_malloc(vm, ns);
|
||||
size_t transf = (os < ns) ? os : ns; /* min size */
|
||||
memmove(vm->stack, old, transf); /* copy to new location */
|
||||
memset(old, 0xFF, os); /* fill the structure with invalid pointers */
|
||||
be_free(vm, old, os);
|
||||
#endif
|
||||
vm->stacktop = vm->stack + size; /* compute new stacktop */
|
||||
offset = ptr_offset(vm->stack, old); /* compute the address difference between old and ne stack addresses */
|
||||
/* update callframes */
|
||||
|
@ -386,7 +400,7 @@ static void stack_resize(bvm *vm, size_t size)
|
|||
/* Check if we are above the max allowed stack */
|
||||
void be_stack_expansion(bvm *vm, int n)
|
||||
{
|
||||
size_t size = vm->stacktop - vm->stack;
|
||||
int size = vm->stacktop - vm->stack; /* with debug enabled, stack increase may be negative */
|
||||
/* check new stack size */
|
||||
if (size + n > BE_STACK_TOTAL_MAX) {
|
||||
/* ensure the stack is enough when generating error messages. */
|
||||
|
|
|
@ -1207,11 +1207,12 @@ static void prep_closure(bvm *vm, int pos, int argc, int mode)
|
|||
for (v = vm->reg + argc; v <= end; ++v) {
|
||||
var_setnil(v);
|
||||
}
|
||||
int v_offset = v - vm->stack; /* offset from stack base, stack may be reallocated */
|
||||
if (proto->varg & BE_VA_VARARG) { /* there are vararg at the last argument, build the list */
|
||||
/* code below uses mostly low-level calls for performance */
|
||||
be_stack_require(vm, argc + 2); /* make sure we don't overflow the stack */
|
||||
bvalue *top_save = vm->top; /* save original stack, we need fresh slots to create the 'list' instance */
|
||||
vm->top = v; /* move top of stack right after last argument */
|
||||
be_stack_require(vm, argc + 4); /* make sure we don't overflow the stack */
|
||||
int top_save_offset = vm->top - vm->stack; /* save original stack, we need fresh slots to create the 'list' instance */
|
||||
vm->top = vm->stack + v_offset; /* move top of stack right after last argument */
|
||||
be_newobject(vm, "list"); /* this creates 2 objects on stack: list instance, BE_LIST object */
|
||||
blist *list = var_toobj(vm->top-1); /* get low-level BE_LIST structure */
|
||||
v = vm->reg + proto->argc - 1; /* last argument */
|
||||
|
@ -1219,7 +1220,7 @@ static void prep_closure(bvm *vm, int pos, int argc, int mode)
|
|||
be_list_push(vm, list, v); /* push all varargs into list */
|
||||
}
|
||||
*(vm->reg + proto->argc - 1) = *(vm->top-2); /* change the vararg argument to now contain the list instance */
|
||||
vm->top = top_save; /* restore top of stack pointer */
|
||||
vm->top = vm->stack + top_save_offset; /* restore top of stack pointer */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue