Merge branch 'development' into pre-release-9.5.0

This commit is contained in:
Theo Arends 2021-06-17 09:44:42 +02:00
commit cbc74ab873
10 changed files with 107 additions and 103 deletions

View File

@ -165,6 +165,7 @@ static binstance* newobjself(bvm *vm, bclass *c)
while (v < end) { var_setnil(v); ++v; }
obj->_class = c;
obj->super = NULL;
obj->sub = NULL;
}
return obj;
}
@ -178,6 +179,7 @@ static binstance* newobject(bvm *vm, bclass *c)
be_incrtop(vm); /* protect new objects from GC */
for (c = c->super; c; c = c->super) {
prev->super = newobjself(vm, c);
prev->super->sub = prev;
prev = prev->super;
}
be_stackpop(vm, 1);

View File

@ -18,11 +18,13 @@
#define be_class_members(cl) ((cl)->members)
#define be_class_super(cl) ((cl)->super)
#define be_class_setsuper(self, sup) ((self)->super = (sup))
#define be_class_setsub(self, sub) ((self)->sub = (sub))
#define be_instance_name(obj) ((obj)->_class->name)
#define be_instance_class(obj) ((obj)->_class)
#define be_instance_members(obj) ((obj)->members)
#define be_instance_member_count(obj) ((obj)->_class->nvar)
#define be_instance_super(obj) ((obj)->super)
#define be_instance_sub(obj) ((obj)->sub)
struct bclass {
bcommon_header;
@ -41,6 +43,7 @@ struct bclass {
struct binstance {
bcommon_header;
struct binstance *super;
struct binstance *sub;
bclass *_class;
bgcobject *gray; /* for gc gray list */
bvalue members[1]; /* members variable data field */

View File

@ -54,17 +54,22 @@ void be_initupvals(bvm *vm, bclosure *cl)
void be_upvals_close(bvm *vm, bvalue *level)
{
bupval *node = vm->upvalist, *next;
while (node && node->value >= level) {
bupval **prev = &vm->upvalist;
while (node) {
next = node->u.next;
if (!node->refcnt) {
be_free(vm, node, sizeof(bupval));
if (node->value >= level) {
if (!node->refcnt) {
be_free(vm, node, sizeof(bupval));
} else {
node->u.value = *node->value; /* move value to upvalue slot */
node->value = &node->u.value;
}
*prev = next; /* remove from linked list */
} else {
node->u.value = *node->value; /* move value to upvalue slot */
node->value = &node->u.value;
prev = &node->u.next;
}
node = next;
}
vm->upvalist = node;
}
void be_release_upvalues(bvm *vm, bclosure *cl)

View File

@ -779,6 +779,11 @@ newframe: /* a new call frame */
int type = obj_attribute(vm, b, c, a);
reg = vm->reg;
if (basetype(type) == BE_FUNCTION) {
/* check if the object is a superinstance, if so get the lowest possible subclass */
while (obj->sub) {
obj = obj->sub;
}
var_setobj(&self, var_type(&self), obj); /* replace superinstance by lowest subinstance */
a[1] = self;
} else {
vm_error(vm, "attribute_error",

View File

@ -0,0 +1,13 @@
#- test for issue #105 -#
l=[]
def tick()
var start=100
for i : 1..3
l.push(def () return [i, start] end)
end
end
tick()
assert(l[0]() == [1, 100])
assert(l[1]() == [2, 100])
assert(l[2]() == [3, 100])

View File

@ -1017,7 +1017,9 @@ void WebSliderColdWarm(void)
void HandleRoot(void)
{
#ifndef NO_CAPTIVE_PORTAL
if (CaptivePortal()) { return; } // If captive portal redirect instead of displaying the page.
#endif // NO_CAPTIVE_PORTAL
if (Webserver->hasArg(F("rst"))) {
WebRestart(0);
@ -2941,8 +2943,9 @@ void HandleConsoleRefresh(void)
void HandleNotFound(void)
{
// AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP "Not found (%s)"), Webserver->uri().c_str());
#ifndef NO_CAPTIVE_PORTAL
if (CaptivePortal()) { return; } // If captive portal redirect instead of displaying the error page.
#endif // NO_CAPTIVE_PORTAL
#ifdef USE_EMULATION
#ifdef USE_EMULATION_HUE
@ -2962,6 +2965,7 @@ void HandleNotFound(void)
}
}
#ifndef NO_CAPTIVE_PORTAL
/* Redirect to captive portal if we got a request for another domain. Return true in that case so the page handler do not try to handle the request again. */
bool CaptivePortal(void)
{
@ -2976,6 +2980,7 @@ bool CaptivePortal(void)
}
return false;
}
#endif // NO_CAPTIVE_PORTAL
/*********************************************************************************************/

View File

@ -2497,11 +2497,18 @@ void CmndSupportColor(void)
else {
#endif // USE_LIGHT_PALETTE
uint32_t old_bri = light_state.getBri();
uint32_t old_bri_rgb = light_state.getBriRGB();
// change all channels to specified values
light_controller.changeChannels(Light.entry_color);
if (2 == XdrvMailbox.index) {
// If Color2, set back old brightness
LightSetBriScaled(old_bri);
if (light_controller.isCTRGBLinked()) {
// RGB and white are linked, adjust brightness of all channels
LightSetBriScaled(old_bri);
} else {
// RGB and white are unlinked, adjust brightness only of RGB channels
LightSetBri(Light.device, old_bri_rgb);
}
}
#ifdef USE_LIGHT_PALETTE
}

View File

@ -593,7 +593,7 @@ const char HTTP_BERRY_FORM_CMND[] PROGMEM =
"<br>"
"<div contenteditable='false' class='br0 bro' readonly id='t1' cols='340' wrap='off'>"
"<div class='br1'>Welcome to the Berry Scripting console. "
"Check the <a href='https://tasmota.github.io/docs/Berry-Scripting/' target='_blank'>documentation</a>."
"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>"

View File

@ -1408,22 +1408,16 @@ class BLEAdvCallbacks: public NimBLEAdvertisedDeviceCallbacks {
// call anyone who asked about advertisements
for (int i = 0; i < advertismentCallbacks.size(); i++) {
try {
ADVERTISMENT_CALLBACK* pFN;
pFN = advertismentCallbacks[i];
int res = pFN(&BLEAdvertisment);
ADVERTISMENT_CALLBACK* pFN;
pFN = advertismentCallbacks[i];
int res = pFN(&BLEAdvertisment);
// if this callback wants to stop here, then do so.
if (1 == res) break;
// if this callback wants to stop here, then do so.
if (1 == res) break;
// if this callback wants to kill this device
if (2 == res) {
//BLEScan->erase(address);
}
} catch(const std::exception& e){
#ifdef BLE_ESP32_DEBUG
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: exception in advertismentCallbacks"));
#endif
// if this callback wants to kill this device
if (2 == res) {
//BLEScan->erase(address);
}
}
@ -1444,17 +1438,11 @@ static void BLEscanEndedCB(NimBLEScanResults results){
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: Scan ended"));
#endif
for (int i = 0; i < scancompleteCallbacks.size(); i++){
try {
SCANCOMPLETE_CALLBACK *pFn = scancompleteCallbacks[i];
int callbackres = pFn(results);
SCANCOMPLETE_CALLBACK *pFn = scancompleteCallbacks[i];
int callbackres = pFn(results);
#ifdef BLE_ESP32_DEBUG
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: scancompleteCallbacks %d %d"), i, callbackres);
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: scancompleteCallbacks %d %d"), i, callbackres);
#endif
} catch(const std::exception& e){
#ifdef BLE_ESP32_DEBUG
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: exception in operationsCallbacks"));
#endif
}
}
BLERunningScan = 2;
@ -1659,23 +1647,17 @@ static void BLETaskStopStartNimBLE(NimBLEClient **ppClient, bool start = true){
(*ppClient)->setClientCallbacks(nullptr, false);
try {
if ((*ppClient)->isConnected()){
if ((*ppClient)->isConnected()){
#ifdef BLE_ESP32_DEBUG
AddLog(LOG_LEVEL_INFO,PSTR("BLE: disconnecting connected client"));
#endif
(*ppClient)->disconnect();
}
NimBLEDevice::deleteClient((*ppClient));
(*ppClient) = nullptr;
#ifdef BLE_ESP32_DEBUG
AddLog(LOG_LEVEL_INFO,PSTR("BLE: deleted client"));
#endif
} catch(const std::exception& e){
#ifdef BLE_ESP32_DEBUG
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: Stopping NimBLE:exception in delete client"));
AddLog(LOG_LEVEL_INFO,PSTR("BLE: disconnecting connected client"));
#endif
(*ppClient)->disconnect();
}
NimBLEDevice::deleteClient((*ppClient));
(*ppClient) = nullptr;
#ifdef BLE_ESP32_DEBUG
AddLog(LOG_LEVEL_INFO,PSTR("BLE: deleted client"));
#endif
if (ble32Scan){
ble32Scan->setAdvertisedDeviceCallbacks(nullptr,true);
@ -2089,47 +2071,41 @@ static void BLETaskRunCurrentOperation(BLE_ESP32::generic_sensor_t** pCurrentOpe
// for safety's sake, only call from the run task
static void BLETaskRunTaskDoneOperation(BLE_ESP32::generic_sensor_t** op, NimBLEClient **ppClient){
try {
if ((*ppClient)->isConnected()){
if ((*ppClient)->isConnected()){
#ifdef BLE_ESP32_DEBUG
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: runTaskDoneOperation: disconnecting connected client"));
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: runTaskDoneOperation: disconnecting connected client"));
#endif
(*ppClient)->disconnect();
// wait for 1/2 second after disconnect
int waits = 0;
do {
vTaskDelay(500/ portTICK_PERIOD_MS);
if (waits) {
//(*ppClient)->disconnect();
// we will stall here forever!!! - as testing
#ifdef BLE_ESP32_DEBUG
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: wait discon%d"), waits);
#endif
(*ppClient)->disconnect();
// wait for 1/2 second after disconnect
int waits = 0;
do {
vTaskDelay(500/ portTICK_PERIOD_MS);
if (waits) {
//(*ppClient)->disconnect();
// we will stall here forever!!! - as testing
}
waits++;
if (waits == 5){
int conn_id = (*ppClient)->getConnId();
ble_gap_conn_broken(conn_id, -1);
#ifdef BLE_ESP32_DEBUG
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: wait discon%d"), waits);
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: wait discon%d - kill connection"), waits);
#endif
vTaskDelay(500/ portTICK_PERIOD_MS);
}
waits++;
if (waits == 5){
int conn_id = (*ppClient)->getConnId();
ble_gap_conn_broken(conn_id, -1);
#ifdef BLE_ESP32_DEBUG
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: wait discon%d - kill connection"), waits);
#endif
}
if (waits == 60){
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: >60s waiting -> BLE Failed, restart Tasmota %d"), waits);
BLEStop = 1;
BLEStopAt = esp_timer_get_time();
}
if (waits == 60){
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: >60s waiting -> BLE Failed, restart Tasmota %d"), waits);
BLEStop = 1;
BLEStopAt = esp_timer_get_time();
BLERestartTasmota = 10;
BLERestartTasmotaReason = BLE_RESTART_TEAMOTA_REASON_BLE_DISCONNECT_FAIL;
break;
}
} while ((*ppClient)->isConnected());
}
} catch(const std::exception& e){
#ifdef BLE_ESP32_DEBUG
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: runTaskDoneOperation: exception in disconnect"));
#endif
BLERestartTasmota = 10;
BLERestartTasmotaReason = BLE_RESTART_TEAMOTA_REASON_BLE_DISCONNECT_FAIL;
break;
}
} while ((*ppClient)->isConnected());
}
@ -3322,35 +3298,23 @@ static void mainThreadOpCallbacks() {
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: op->completecallback is %u opid %d"), op->completecallback, op->opid);
if (op->completecallback){
try {
OPCOMPLETE_CALLBACK *pFn = (OPCOMPLETE_CALLBACK *)(op->completecallback);
callbackres = pFn(op);
OPCOMPLETE_CALLBACK *pFn = (OPCOMPLETE_CALLBACK *)(op->completecallback);
callbackres = pFn(op);
#ifdef BLE_ESP32_DEBUG
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: op->completecallback %d opid %d"), callbackres, op->opid);
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: op->completecallback %d opid %d"), callbackres, op->opid);
#endif
} catch(const std::exception& e){
#ifdef BLE_ESP32_DEBUG
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: exception in op->completecallback"));
#endif
}
}
if (!callbackres){
for (int i = 0; i < operationsCallbacks.size(); i++){
try {
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: operationsCallbacks %d is %u"), i, operationsCallbacks[i]);
OPCOMPLETE_CALLBACK *pFn = operationsCallbacks[i];
callbackres = pFn(op);
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: operationsCallbacks %d is %u"), i, operationsCallbacks[i]);
OPCOMPLETE_CALLBACK *pFn = operationsCallbacks[i];
callbackres = pFn(op);
#ifdef BLE_ESP32_DEBUG
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: operationsCallbacks %d %d"), i, callbackres);
#endif
if (callbackres){
break; // this callback ate the op.
}
} catch(const std::exception& e){
#ifdef BLE_ESP32_DEBUG
AddLog(LOG_LEVEL_ERROR,PSTR("BLE: exception in operationsCallbacks"));
if (BLEDebugMode > 0) AddLog(LOG_LEVEL_DEBUG,PSTR("BLE: operationsCallbacks %d %d"), i, callbackres);
#endif
if (callbackres){
break; // this callback ate the op.
}
}
}

View File

@ -69,7 +69,7 @@ void (* const Ws2812Command[])(void) PROGMEM = {
#elif (USE_WS2812_CTYPE == NEO_RBG)
#define NEO_FEATURE_TYPE Rbg
#elif (USE_WS2812_CTYPE == NEO_RGBW)
#define NEO_FEATURE_TYPE Rbgw
#define NEO_FEATURE_TYPE Rgbw
#elif (USE_WS2812_CTYPE == NEO_GRBW)
#define NEO_FEATURE_TYPE Grbw
#else