From 69de76338c8b9a637fef97ee7c5f58ad29047d05 Mon Sep 17 00:00:00 2001 From: Stephan Hadinger Date: Tue, 5 Jul 2022 21:14:50 +0200 Subject: [PATCH] Berry allow setmember() to fail with `false` or `undefined` --- lib/libesp32/berry/src/be_class.c | 18 ++++++++++++++++-- lib/libesp32/berry/src/be_module.c | 15 ++++++++++++++- lib/libesp32/berry/tests/virtual_methods2.be | 11 +++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) diff --git a/lib/libesp32/berry/src/be_class.c b/lib/libesp32/berry/src/be_class.c index 225974aff..90c7b5599 100644 --- a/lib/libesp32/berry/src/be_class.c +++ b/lib/libesp32/berry/src/be_class.c @@ -299,8 +299,8 @@ int be_instance_member(bvm *vm, binstance *instance, bstring *name, bvalue *dst) return BE_NONE; /* if the return value is module `undefined`, consider it is an error */ } } - var_clearstatic(dst); - return type; + var_clearstatic(dst); + return type; } } } @@ -339,6 +339,20 @@ bbool be_instance_setmember(bvm *vm, binstance *o, bstring *name, bvalue *src) vm->top += 4; /* prevent collection results */ be_dofunc(vm, top, 3); /* call method 'member' */ vm->top -= 4; + /* if return value is `false` or `undefined` signal an unknown attribute */ + int type = var_type(vm->top); + if (type == BE_BOOL) { + bbool ret = var_tobool(vm->top); + if (!ret) { + return bfalse; + } + } else if (type == BE_MODULE) { + /* check if the module is named `undefined` */ + bmodule *mod = var_toobj(vm->top); + if (strcmp(be_module_name(mod), "undefined") == 0) { + return bfalse; /* if the return value is module `undefined`, consider it is an error */ + } + } return btrue; } } diff --git a/lib/libesp32/berry/src/be_module.c b/lib/libesp32/berry/src/be_module.c index 935b89bb3..bf7c7720f 100644 --- a/lib/libesp32/berry/src/be_module.c +++ b/lib/libesp32/berry/src/be_module.c @@ -339,7 +339,7 @@ int be_module_attr(bvm *vm, bmodule *module, bstring *attr, bvalue *dst) bmodule *mod = var_toobj(dst); if (strcmp(be_module_name(mod), "undefined") == 0) { return BE_NONE; /* if the return value is module `undefined`, consider it is an error */ - } + } } return type; } @@ -373,6 +373,19 @@ bbool be_module_setmember(bvm *vm, bmodule *module, bstring *attr, bvalue *src) vm->top += 3; /* prevent collection results */ be_dofunc(vm, top, 2); /* call method 'setmember' */ vm->top -= 3; + int type = var_type(vm->top); + if (type == BE_BOOL) { + bbool ret = var_tobool(vm->top); + if (!ret) { + return bfalse; + } + } else if (type == BE_MODULE) { + /* check if the module is named `undefined` */ + bmodule *mod = var_toobj(vm->top); + if (strcmp(be_module_name(mod), "undefined") == 0) { + return bfalse; /* if the return value is module `undefined`, consider it is an error */ + } + } return btrue; } } diff --git a/lib/libesp32/berry/tests/virtual_methods2.be b/lib/libesp32/berry/tests/virtual_methods2.be index 9bb38a9c5..10fee905d 100644 --- a/lib/libesp32/berry/tests/virtual_methods2.be +++ b/lib/libesp32/berry/tests/virtual_methods2.be @@ -1,4 +1,14 @@ #- virtual attributes -# + +def assert_attribute_error(f) + try + f() + assert(false, 'unexpected execution flow') + except .. as e, m + assert(e == 'attribute_error') + end +end + class Ta var a, b, virtual_c def init() @@ -26,3 +36,4 @@ assert(ta.c == 3) ta.c = 30 assert(ta.c == 30) assert(ta.virtual_c == 30) +assert_attribute_error(def() ta.d = 0 end)