diff --git a/CHANGELOG.md b/CHANGELOG.md index 049f597bc..478c2dff7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ All notable changes to this project will be documented in this file. ### Fixed - Syslog RFC5424 compliance (#23509) +- Berry fix calling `setmember` with a function ### Removed - `user-scalable=no` from HTTP HEADER (#23798) diff --git a/lib/libesp32/berry/src/be_class.c b/lib/libesp32/berry/src/be_class.c index 90c7b5599..ceb00255a 100644 --- a/lib/libesp32/berry/src/be_class.c +++ b/lib/libesp32/berry/src/be_class.c @@ -331,11 +331,14 @@ bbool be_instance_setmember(bvm *vm, binstance *o, bstring *name, bvalue *src) v = obj->members[v.v.i]; } if (var_basetype(&v) == BE_FUNCTION) { + if (var_isfunction(src)) { + var_clearstatic(src); + } bvalue *top = vm->top; var_setval(top, &v); var_setinstance(top + 1, o); /* move instance to argv[0] */ - var_setstr(top + 2, name); /* move method name to argv[1] */ - var_setval(top + 3, src); /* move method name to argv[1] */ + var_setstr(top + 2, name); /* move key to argv[1] */ + var_setval(top + 3, src); /* move value to argv[2] */ vm->top += 4; /* prevent collection results */ be_dofunc(vm, top, 3); /* call method 'member' */ vm->top -= 4; diff --git a/lib/libesp32/berry/tests/virtual_methods2.be b/lib/libesp32/berry/tests/virtual_methods2.be index 10fee905d..892faac2a 100644 --- a/lib/libesp32/berry/tests/virtual_methods2.be +++ b/lib/libesp32/berry/tests/virtual_methods2.be @@ -37,3 +37,20 @@ ta.c = 30 assert(ta.c == 30) assert(ta.virtual_c == 30) assert_attribute_error(def() ta.d = 0 end) + +# bug: if a function is sent to 'setmember()', the internal BE_STATIC flag is added +# which makes the function not callable and scrambles tostring() +class A + var _v + def init() + self._v = {} + end + def setmember(name, value) + self._v[name] = value + end +end +a = A() +f = def(name, time_ms) return 42 end +a.f = f + +assert(a._v['f']() == 42)