Skip to content

Commit

Permalink
Command BrRestart to restart the Berry VM (experimental) (#19003)
Browse files Browse the repository at this point in the history
* Command ``BrRestart`` to restart the Berry VM (experimental)

* Add web button for Berry Restart
  • Loading branch information
s-hadinger authored Jul 2, 2023
1 parent 7cd2d78 commit d72f3b9
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ All notable changes to this project will be documented in this file.
- Command ``Delay -1`` to wait until next second (#18984)
- Matter add option to disable bridge mode (#18992)
- Support for SGP41 TVOC/NOx Sensor (#18880)
- Command ``BrRestart`` to restart the Berry VM (experimental)

### Breaking Changed
- Berry `bool( [] )` and `bool( {} )` now evaluate as `false` (#18986)
Expand Down
21 changes: 21 additions & 0 deletions lib/libesp32/berry_mapping/src/be_cb_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ static int32_t call_berry_cb(int32_t num, int32_t v0, int32_t v1, int32_t v2, in

bvm * vm = be_cb_hooks[num].vm;
bvalue *f = &be_cb_hooks[num].f;
if (vm == NULL) { return 0; } // function is not alive anymore, don't crash

// push function (don't check type)
bvalue *top = be_incrtop(vm);
Expand All @@ -271,6 +272,26 @@ static int32_t call_berry_cb(int32_t num, int32_t v0, int32_t v1, int32_t v2, in
return ret;
}

/*********************************************************************************************\
* `be_cb_deinit`:
* Clean any callback for this VM, they shouldn't call the registerd function anymore
\*********************************************************************************************/
void be_cb_deinit(bvm *vm) {
// remove all cb for this vm
for (int32_t slot = 0; slot < BE_MAX_CB; slot++) {
if (be_cb_hooks[slot].vm == vm) {
be_cb_hooks[slot].vm = NULL;
be_cb_hooks[slot].f.type == BE_NIL;
}
}
// remove the vm gen_cb for this vm
for (be_callback_handler_list_t **elt_ptr = &be_callback_handler_list_head; *elt_ptr != NULL; elt_ptr = &(*elt_ptr)->next) {
if (((*elt_ptr)->next != NULL) && ((*elt_ptr)->next->vm == vm)) {
(*elt_ptr)->next = (*elt_ptr)->next->next;
}
}
}

/* @const_object_info_begin
module cb (scope: global) {
gen_cb, func(be_cb_gen_cb)
Expand Down
2 changes: 2 additions & 0 deletions lib/libesp32/berry_mapping/src/be_mapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ extern int be_check_arg_type(bvm *vm, int arg_start, int argc, const char * arg_
extern int be_call_c_func(bvm *vm, const void * func, const char * return_type, const char * arg_type);
extern int be_call_ctype_func(bvm *vm, const void *definition); /* handler for Berry vm */

extern void be_cb_deinit(bvm *vm); /* remove all callbacks from the VM (just before shutdown of VM) */

#ifdef __cplusplus
}
#endif
Expand Down
1 change: 1 addition & 0 deletions tasmota/include/i18n.h
Original file line number Diff line number Diff line change
Expand Up @@ -764,6 +764,7 @@
// Commands xdrv_52_berry.ino - Berry scripting language
#define D_PRFX_BR "Br"
#define D_CMND_BR_RUN ""
#define D_CMND_BR_RESTART "Restart"
#define D_BR_NOT_STARTED "Berry not started"

// Commands xdrv_60_shift595.ino - 74x595 family shift register driver
Expand Down
1 change: 0 additions & 1 deletion tasmota/tasmota_xdrv_driver/xdrv_52_3_berry_webserver.ino
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,6 @@ extern "C" {
const char * uri = be_tostring(vm, 1);
Webserver->sendHeader("Location", uri, true);
Webserver->send(302, "text/plain", "");
// Webserver->sendHeader(F("Location"), String(F("http://")) + Webserver->client().localIP().toString(), true);
be_return_nil(vm);
}
be_raise(vm, kTypeError, nullptr);
Expand Down
38 changes: 31 additions & 7 deletions tasmota/tasmota_xdrv_driver/xdrv_52_9_berry.ino
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,11 @@ extern "C" {
}

const char kBrCommands[] PROGMEM = D_PRFX_BR "|" // prefix
D_CMND_BR_RUN
D_CMND_BR_RUN "|" D_CMND_BR_RESTART
;

void (* const BerryCommand[])(void) PROGMEM = {
CmndBrRun,
CmndBrRun, CmndBrRestart
};

int32_t callBerryEventDispatcher(const char *type, const char *cmd, int32_t idx, const char *payload, uint32_t data_len = 0);
Expand Down Expand Up @@ -307,8 +307,13 @@ void BrShowState(void) {
void BerryInit(void) {
// clean previous VM if any
if (berry.vm != nullptr) {
be_cb_deinit(berry.vm); // deregister any C callback for this VM
be_vm_delete(berry.vm);
berry.vm = nullptr;
berry.autoexec_done = false;
berry.repl_active = false;
berry.rules_busy = false;
berry.timeout = 0;
}

int32_t ret_code1, ret_code2;
Expand Down Expand Up @@ -367,6 +372,17 @@ void BerryInit(void) {
}
}

/*********************************************************************************************\
* BrRestart - restart a fresh new Berry vm, unloading everything from previous VM
\*********************************************************************************************/
void CmndBrRestart(void) {
if (berry.vm == nullptr) {
ResponseCmndChar_P("Berry VM not started");
}
BerryInit();
ResponseCmndChar_P("Berry VM restarted");
}

/*********************************************************************************************\
* Execute a script in Flash file-system
*
Expand Down Expand Up @@ -653,14 +669,16 @@ const char HTTP_BERRY_FORM_CMND[] PROGMEM =
"Check the <a href='https://tasmota.github.io/docs/Berry/' target='_blank'>documentation</a>."
"</div>"
"</div>"
// "<textarea readonly id='t1' cols='340' wrap='off'></textarea>"
// "<br><br>"
"<form method='get' id='fo' onsubmit='return l(1);'>"
"<textarea id='c1' class='br0 bri' rows='4' cols='340' wrap='soft' autofocus required></textarea>"
// "<input id='c1' class='bri' type='text' rows='5' placeholder='" D_ENTER_COMMAND "' autofocus><br>"
// "<input type='submit' value=\"Run code (or press 'Enter' twice)\">"
"<button type='submit'>Run code (or press 'Enter' twice)</button>"
"</form>";
"</form>"
#ifdef USE_BERRY_DEBUG
"<p><form method='post' >"
"<button type='submit' name='rst' class='bred' onclick=\"if(confirm('Confirm removing endpoint')){clearTimeout(lt);return true;}else{return false;}\">Restart Berry VM (for devs only)</button>"
"</form></p>"
#endif // USE_BERRY_DEBUG
;

const char HTTP_BTN_BERRY_CONSOLE[] PROGMEM =
"<p><form action='bc' method='get'><button>Berry Scripting console</button></form></p>";
Expand Down Expand Up @@ -706,6 +724,12 @@ void HandleBerryConsole(void)
return;
}

if (Webserver->hasArg(F("rst"))) { // restart VM
BerryInit();
Webserver->sendHeader("Location", "/bc", true);
Webserver->send(302, "text/plain", "");
}

AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Berry " D_CONSOLE));

WSContentStart_P(PSTR("Berry " D_CONSOLE));
Expand Down

0 comments on commit d72f3b9

Please sign in to comment.