Berry allow setmember() to fail with false or undefined

This commit is contained in:
Stephan Hadinger 2022-07-05 21:14:50 +02:00
parent 720942e818
commit 69de76338c
3 changed files with 41 additions and 3 deletions

View File

@ -339,6 +339,20 @@ bbool be_instance_setmember(bvm *vm, binstance *o, bstring *name, bvalue *src)
vm->top += 4; /* prevent collection results */ vm->top += 4; /* prevent collection results */
be_dofunc(vm, top, 3); /* call method 'member' */ be_dofunc(vm, top, 3); /* call method 'member' */
vm->top -= 4; 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; return btrue;
} }
} }

View File

@ -373,6 +373,19 @@ bbool be_module_setmember(bvm *vm, bmodule *module, bstring *attr, bvalue *src)
vm->top += 3; /* prevent collection results */ vm->top += 3; /* prevent collection results */
be_dofunc(vm, top, 2); /* call method 'setmember' */ be_dofunc(vm, top, 2); /* call method 'setmember' */
vm->top -= 3; 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; return btrue;
} }
} }

View File

@ -1,4 +1,14 @@
#- virtual attributes -# #- 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 class Ta
var a, b, virtual_c var a, b, virtual_c
def init() def init()
@ -26,3 +36,4 @@ assert(ta.c == 3)
ta.c = 30 ta.c = 30
assert(ta.c == 30) assert(ta.c == 30)
assert(ta.virtual_c == 30) assert(ta.virtual_c == 30)
assert_attribute_error(def() ta.d = 0 end)