diff --git a/lib/libesp32/berry/src/be_api.c b/lib/libesp32/berry/src/be_api.c index 79d5c48ff..c3fd59e23 100644 --- a/lib/libesp32/berry/src/be_api.c +++ b/lib/libesp32/berry/src/be_api.c @@ -34,19 +34,19 @@ static void class_init(bvm *vm, bclass *c, const bnfuncinfo *lib) while (lib->name) { bstring *s = be_newstr(vm, lib->name); if (lib->function) { /* method */ - be_prim_method_bind(vm, c, s, lib->function); + be_class_native_method_bind(vm, c, s, lib->function); } else { - be_member_bind(vm, c, s, btrue); /* member */ + be_class_member_bind(vm, c, s, btrue); /* member */ } ++lib; } - if (lib->function == (bntvfunc) BE_CLOSURE) { + if (lib->function == (bntvfunc)BE_CLOSURE) { /* next section is closures */ struct solidfuncinfo *slib = (struct solidfuncinfo*)++lib; while (slib->name) { if (slib->function) { /* method */ bstring *s = be_newstr(vm, slib->name); - be_closure_method_bind(vm, c, s, slib->function); + be_class_closure_method_bind(vm, c, s, slib->function); } ++slib; } diff --git a/lib/libesp32/berry/src/be_baselib.c b/lib/libesp32/berry/src/be_baselib.c index f09c5f812..2b9c25095 100644 --- a/lib/libesp32/berry/src/be_baselib.c +++ b/lib/libesp32/berry/src/be_baselib.c @@ -85,7 +85,7 @@ static bclass *find_class_closure(bclass *cl, bclosure *needle) if (members) { /* only iterate if there are members */ bmapiter iter = be_map_iter(); while ((node = be_map_next(members, &iter)) != NULL) { - if (var_type(&node->value) == BE_CLOSURE) { /* only native functions are considered */ + if (var_primetype(&node->value) == BE_CLOSURE) { /* only native functions are considered */ bclosure *clos_iter = var_toobj(&node->value); /* retrieve the method's closure */ if (clos_iter == needle) { /* we found the closure, we now know its class */ @@ -140,7 +140,7 @@ static int l_super(bvm *vm) if (size >= 2) { /* need at least 2 stackframes: current (for super() native) and caller (the one we are interested in) */ bcallframe *caller = be_vector_at(&vm->callstack, size - 2); /* get the callframe of caller */ bvalue *func = caller->func; /* function object of caller */ - if (var_type(func) == BE_CLOSURE) { /* only useful if the caller is a Berry closure (i.e. not native) */ + if (var_primetype(func) == BE_CLOSURE) { /* only useful if the caller is a Berry closure (i.e. not native) */ bclosure *clos_ctx = var_toobj(func); /* this is the closure we look for in the class chain */ base_class = find_class_closure(o->_class, clos_ctx); /* iterate on current and super classes to find where the closure belongs */ } diff --git a/lib/libesp32/berry/src/be_bytecode.c b/lib/libesp32/berry/src/be_bytecode.c index 9f9283fbe..e7ba8aaca 100644 --- a/lib/libesp32/berry/src/be_bytecode.c +++ b/lib/libesp32/berry/src/be_bytecode.c @@ -176,8 +176,8 @@ static void save_class(bvm *vm, void *fp, bclass *c) static void save_value(bvm *vm, void *fp, bvalue *v) { - save_byte(fp, (uint8_t)var_type(v)); /* type */ - switch (var_type(v)) { + save_byte(fp, (uint8_t)var_primetype(v)); /* type */ + switch (var_primetype(v)) { case BE_INT: save_int(fp, var_toint(v)); break; case BE_REAL: save_real(fp, var_toreal(v)); break; case BE_STRING: save_string(fp, var_tostr(v)); break; @@ -425,16 +425,16 @@ static void load_class(bvm *vm, void *fp, bvalue *v, int version) be_incrtop(vm); if (load_proto(vm, fp, (bproto**)&var_toobj(value), -3, version)) { /* actual method */ - be_method_bind(vm, c, name, var_toobj(value), bfalse); + be_class_method_bind(vm, c, name, var_toobj(value), bfalse); } else { /* no proto, static member set to nil */ - be_member_bind(vm, c, name, bfalse); + be_class_member_bind(vm, c, name, bfalse); } be_stackpop(vm, 2); /* pop the cached string and proto */ } for (count = 0; count < nvar; ++count) { /* load member-variable table */ bstring *name = cache_string(vm, fp); - be_member_bind(vm, c, name, btrue); + be_class_member_bind(vm, c, name, btrue); be_stackpop(vm, 1); /* pop the cached string */ } } diff --git a/lib/libesp32/berry/src/be_class.c b/lib/libesp32/berry/src/be_class.c index 0f4efb3d5..0ad035150 100644 --- a/lib/libesp32/berry/src/be_class.c +++ b/lib/libesp32/berry/src/be_class.c @@ -7,13 +7,11 @@ ********************************************************************/ #include "be_class.h" #include "be_string.h" -#include "be_vector.h" #include "be_map.h" #include "be_exec.h" #include "be_gc.h" #include "be_vm.h" #include "be_func.h" -#include "be_var.h" #include #define check_members(vm, c) \ @@ -44,6 +42,7 @@ void be_class_compress(bvm *vm, bclass *c) } } +/* Return the type of the class attribute, only used to check if the attribute already exists */ int be_class_attribute(bvm *vm, bclass *c, bstring *attr) { for (; c; c = c->super) { @@ -57,7 +56,7 @@ int be_class_attribute(bvm *vm, bclass *c, bstring *attr) return BE_NONE; } -void be_member_bind(bvm *vm, bclass *c, bstring *name, bbool var) +void be_class_member_bind(bvm *vm, bclass *c, bstring *name, bbool var) { bvalue *attr; set_fixed(name); @@ -75,7 +74,7 @@ void be_member_bind(bvm *vm, bclass *c, bstring *name, bbool var) } } -void be_method_bind(bvm *vm, bclass *c, bstring *name, bproto *p, bbool is_static) +void be_class_method_bind(bvm *vm, bclass *c, bstring *name, bproto *p, bbool is_static) { bclosure *cl; bvalue *attr; @@ -88,11 +87,11 @@ void be_method_bind(bvm *vm, bclass *c, bstring *name, bproto *p, bbool is_stati cl->proto = p; var_setclosure(attr, cl); if (is_static) { - func_setstatic(attr); + var_markstatic(attr); } } -void be_prim_method_bind(bvm *vm, bclass *c, bstring *name, bntvfunc f) +void be_class_native_method_bind(bvm *vm, bclass *c, bstring *name, bntvfunc f) { bvalue *attr; set_fixed(name); @@ -103,7 +102,7 @@ void be_prim_method_bind(bvm *vm, bclass *c, bstring *name, bntvfunc f) attr->type = MT_PRIMMETHOD; } -void be_closure_method_bind(bvm *vm, bclass *c, bstring *name, bclosure *cl) +void be_class_closure_method_bind(bvm *vm, bclass *c, bstring *name, bclosure *cl) { bvalue *attr; check_members(vm, c); @@ -242,7 +241,8 @@ bbool be_class_newobj(bvm *vm, bclass *c, int pos, int argc, int mode) } /* Default empty constructor */ -static int default_init_native_method(bvm *vm) { +static int default_init_native_method(bvm *vm) +{ be_return_nil(vm); } @@ -253,10 +253,11 @@ int be_instance_member_simple(bvm *vm, binstance *instance, bstring *name, bvalu int type; be_assert(name != NULL); binstance * obj = instance_member(vm, instance, name, dst); - type = var_type(dst); - if (obj && type == MT_VARIABLE) { + if (obj && var_type(dst) == MT_VARIABLE) { *dst = obj->members[dst->v.i]; } + type = var_type(dst); + var_clearstatic(dst); return type; } @@ -268,18 +269,19 @@ int be_instance_member(bvm *vm, binstance *instance, bstring *name, bvalue *dst) { int type; be_assert(name != NULL); - binstance * obj = instance_member(vm, instance, name, dst); - type = var_type(dst); - if (obj && type == MT_VARIABLE) { + binstance *obj = instance_member(vm, instance, name, dst); + if (obj && var_type(dst) == MT_VARIABLE) { *dst = obj->members[dst->v.i]; } + type = var_type(dst); if (obj) { + var_clearstatic(dst); return type; } else { /* if no method found, try virtual */ /* if 'init' does not exist, create a virtual empty constructor */ if (strcmp(str(name), "init") == 0) { var_setntvfunc(dst, default_init_native_method); - return var_type(dst); + return var_primetype(dst); } else { /* get method 'member' */ obj = instance_member(vm, instance, str_literal(vm, "member"), vm->top); @@ -296,6 +298,7 @@ int be_instance_member(bvm *vm, binstance *instance, bstring *name, bvalue *dst) } type = var_type(dst); if (type != BE_NIL) { + var_clearstatic(dst); return type; } } @@ -310,11 +313,8 @@ int be_class_member(bvm *vm, bclass *obj, bstring *name, bvalue *dst) be_assert(name != NULL); obj = class_member(vm, obj, name, dst); type = var_type(dst); - if (obj) { - return type; - } else { - return BE_NONE; - } + var_clearstatic(dst); + return obj ? type : BE_NONE; } bbool be_instance_setmember(bvm *vm, binstance *o, bstring *name, bvalue *src) diff --git a/lib/libesp32/berry/src/be_class.h b/lib/libesp32/berry/src/be_class.h index 405ea6d38..f80ca8799 100644 --- a/lib/libesp32/berry/src/be_class.h +++ b/lib/libesp32/berry/src/be_class.h @@ -52,17 +52,17 @@ struct binstance { bclass* be_newclass(bvm *vm, bstring *name, bclass *super); void be_class_compress(bvm *vm, bclass *c); int be_class_attribute(bvm *vm, bclass *c, bstring *attr); -void be_member_bind(bvm *vm, bclass *c, bstring *name, bbool var); -void be_method_bind(bvm *vm, bclass *c, bstring *name, bproto *p, bbool is_static); -void be_prim_method_bind(bvm *vm, bclass *c, bstring *name, bntvfunc f); -void be_closure_method_bind(bvm *vm, bclass *c, bstring *name, bclosure *cl); +void be_class_member_bind(bvm *vm, bclass *c, bstring *name, bbool var); +void be_class_method_bind(bvm *vm, bclass *c, bstring *name, bproto *p, bbool is_static); +void be_class_native_method_bind(bvm *vm, bclass *c, bstring *name, bntvfunc f); +void be_class_closure_method_bind(bvm *vm, bclass *c, bstring *name, bclosure *cl); +int be_class_member(bvm *vm, bclass *obj, bstring *name, bvalue *dst); +bbool be_class_setmember(bvm *vm, bclass *obj, bstring *name, bvalue *src); int be_class_closure_count(bclass *c); void be_class_upvalue_init(bvm *vm, bclass *c); bbool be_class_newobj(bvm *vm, bclass *c, int pos, int argc, int mode); int be_instance_member_simple(bvm *vm, binstance *obj, bstring *name, bvalue *dst); int be_instance_member(bvm *vm, binstance *obj, bstring *name, bvalue *dst); -int be_class_member(bvm *vm, bclass *obj, bstring *name, bvalue *dst); bbool be_instance_setmember(bvm *vm, binstance *obj, bstring *name, bvalue *src); -bbool be_class_setmember(bvm *vm, bclass *obj, bstring *name, bvalue *src); #endif diff --git a/lib/libesp32/berry/src/be_constobj.h b/lib/libesp32/berry/src/be_constobj.h index 301b06af8..708cce03d 100644 --- a/lib/libesp32/berry/src/be_constobj.h +++ b/lib/libesp32/berry/src/be_constobj.h @@ -40,7 +40,7 @@ extern "C" { #define be_const_static_func(_func) { \ .v.nf = (_func), \ - .type = BE_NTVFUNC | BE_FUNC_STATIC \ + .type = BE_NTVFUNC | BE_STATIC \ } #define be_const_nil() { \ @@ -79,7 +79,7 @@ extern "C" { } #define be_const_comptr(_val) { \ - .v.c = (const void*)(_val), \ + .v.c = (const void*)(_val), \ .type = BE_COMPTR \ } @@ -95,7 +95,7 @@ extern "C" { #define be_const_static_closure(_closure) { \ .v.c = &(_closure), \ - .type = BE_CLOSURE | BE_FUNC_STATIC \ + .type = BE_CLOSURE | BE_STATIC \ } #define be_const_module(_module) { \ @@ -256,7 +256,7 @@ const bntvmodule be_native_module(_module) = { \ #define be_const_static_func(_func) { \ bvaldata(_func), \ - BE_NTVFUNC | BE_FUNC_STATIC \ + BE_NTVFUNC | BE_STATIC \ } #define be_const_nil() { \ @@ -311,7 +311,7 @@ const bntvmodule be_native_module(_module) = { \ #define be_const_static_closure(_closure) { \ bvaldata(&(_closure)), \ - BE_CLOSURE | BE_FUNC_STATIC \ + BE_CLOSURE | BE_STATIC \ } #define be_const_module(_module) { \ diff --git a/lib/libesp32/berry/src/be_exec.c b/lib/libesp32/berry/src/be_exec.c index 14dbe903c..c2b2e1f6a 100644 --- a/lib/libesp32/berry/src/be_exec.c +++ b/lib/libesp32/berry/src/be_exec.c @@ -335,7 +335,7 @@ void be_stackpush(bvm *vm) } /* check that the stack is able to store `count` items, and increase stack if needed */ -void be_stack_require(bvm *vm, int count) +BERRY_API void be_stack_require(bvm *vm, int count) { if (vm->top + count >= vm->stacktop) { be_stack_expansion(vm, count); diff --git a/lib/libesp32/berry/src/be_gc.c b/lib/libesp32/berry/src/be_gc.c index 19e88cb12..9e1ca0b74 100644 --- a/lib/libesp32/berry/src/be_gc.c +++ b/lib/libesp32/berry/src/be_gc.c @@ -138,7 +138,8 @@ static void mark_gray(bvm *vm, bgcobject *obj) { if (obj && gc_iswhite(obj) && !gc_isconst(obj)) { gc_setgray(obj); - switch (var_type(obj)) { + be_assert(!var_isstatic(obj)); + switch (var_primetype(obj)) { case BE_STRING: gc_setdark(obj); break; /* just set dark */ case BE_CLASS: link_gray(vm, cast_class(obj)); break; case BE_PROTO: link_gray(vm, cast_proto(obj)); break; @@ -171,7 +172,7 @@ static void mark_map(bvm *vm, bgcobject *obj) while ((node = be_map_next(map, &iter)) != NULL) { bmapkey *key = &node->key; bvalue *val = &node->value; - if (be_isgctype((signed char)key->type)) { + if (be_isgcobj(key)) { mark_gray(vm, var_togc(key)); } mark_gray_var(vm, val); @@ -348,7 +349,7 @@ static void free_instance(bvm *vm, bgcobject *obj) static void free_object(bvm *vm, bgcobject *obj) { - switch (var_type(obj)) { + switch (var_primetype(obj)) { case BE_STRING: free_lstring(vm, obj); break; /* long string */ case BE_CLASS: be_free(vm, obj, sizeof(bclass)); break; case BE_INSTANCE: free_instance(vm, obj); break; @@ -432,7 +433,8 @@ static void mark_unscanned(bvm *vm) bgcobject *obj = vm->gc.gray; if (obj && !gc_isdark(obj) && !gc_isconst(obj)) { gc_setdark(obj); - switch (var_type(obj)) { + be_assert(!var_isstatic(obj)); + switch (var_primetype(obj)) { case BE_CLASS: mark_class(vm, obj); break; case BE_PROTO: mark_proto(vm, obj); break; case BE_INSTANCE: mark_instance(vm, obj); break; diff --git a/lib/libesp32/berry/src/be_gc.h b/lib/libesp32/berry/src/be_gc.h index 0e0ce9e82..49e311291 100644 --- a/lib/libesp32/berry/src/be_gc.h +++ b/lib/libesp32/berry/src/be_gc.h @@ -47,8 +47,7 @@ if (!gc_isconst(o)) { \ #define gc_exmark(o) (((o)->marked >> 4) & 0x0F) #define gc_setexmark(o, k) ((o)->marked |= (k) << 4) -#define be_isgctype(t) ((t) >= BE_GCOBJECT) -#define be_isgcobj(o) be_isgctype(var_type(o)) +#define be_isgcobj(o) (var_primetype(o) >= BE_GCOBJECT) #define be_gcnew(v, t, s) be_newgcobj((v), (t), sizeof(s)) #define set_fixed(s) bbool _was_fixed = be_gc_fix_set(vm, cast(bgcobject*, (s)), 1) diff --git a/lib/libesp32/berry/src/be_module.c b/lib/libesp32/berry/src/be_module.c index 0256809af..ab4504ee5 100644 --- a/lib/libesp32/berry/src/be_module.c +++ b/lib/libesp32/berry/src/be_module.c @@ -329,10 +329,9 @@ int be_module_attr(bvm *vm, bmodule *module, bstring *attr, bvalue *dst) } } return BE_NONE; - } else { - *dst = *member; - return var_type(dst); } + *dst = *member; + return var_type(dst); } bbool be_module_setmember(bvm *vm, bmodule *module, bstring *attr, bvalue *src) diff --git a/lib/libesp32/berry/src/be_object.c b/lib/libesp32/berry/src/be_object.c index ed338f790..138fcc1f1 100644 --- a/lib/libesp32/berry/src/be_object.c +++ b/lib/libesp32/berry/src/be_object.c @@ -15,7 +15,7 @@ const char* be_vtype2str(bvalue *v) { - switch(var_type(v)) { + switch(var_primetype(v)) { case BE_NIL: return "nil"; case BE_INT: return "int"; case BE_REAL: return "real"; diff --git a/lib/libesp32/berry/src/be_object.h b/lib/libesp32/berry/src/be_object.h index df7c7a9af..67e79bcdf 100644 --- a/lib/libesp32/berry/src/be_object.h +++ b/lib/libesp32/berry/src/be_object.h @@ -11,14 +11,14 @@ #include "berry.h" /* basic types, do not change value */ +#define BE_NONE -256 /* unknown type */ #define BE_NIL 0 #define BE_INT 1 #define BE_REAL 2 #define BE_BOOL 3 -#define BE_NONE 4 /* unknown type */ -#define BE_COMPTR 5 /* common pointer */ -#define BE_INDEX 6 /* index for instance variable, previously BE_INT */ -#define BE_FUNCTION 7 +#define BE_COMPTR 4 /* common pointer */ +#define BE_INDEX 5 /* index for instance variable, previously BE_INT */ +#define BE_FUNCTION 6 #define BE_GCOBJECT 16 /* from this type can be gced */ @@ -35,11 +35,11 @@ #define BE_CLOSURE ((1 << 5) | BE_FUNCTION) #define BE_NTVCLOS ((2 << 5) | BE_FUNCTION) #define BE_CTYPE_FUNC ((3 << 5) | BE_FUNCTION) -#define BE_FUNC_STATIC (1 << 7) +#define BE_STATIC (1 << 7) -#define func_isstatic(o) (((o)->type & BE_FUNC_STATIC) != 0) -#define func_setstatic(o) ((o)->type |= BE_FUNC_STATIC) -#define func_clearstatic(o) ((o)->type &= ~BE_FUNC_STATIC) +#define func_isstatic(o) (((o)->type & BE_STATIC) != 0) +#define func_setstatic(o) ((o)->type |= BE_STATIC) +#define func_clearstatic(o) ((o)->type &= ~BE_STATIC) /* values for bproto.varg */ #define BE_VA_VARARG (1 << 0) /* function has variable number of arguments */ @@ -201,10 +201,14 @@ typedef const char* (*breader)(void*, size_t*); #define cast_bool(_v) cast(bbool, _v) #define basetype(_t) ((_t) & 0x1F) -#define var_type(_v) ((_v)->type & 0x7F) +#define var_type(_v) ((_v)->type) #define var_basetype(_v) basetype((_v)->type) -#define var_istype(_v, _t) (var_type(_v) == _t) +#define var_primetype(_v) (var_type(_v) & ~BE_STATIC) +#define var_isstatic(_v) ((var_type(_v) & BE_STATIC) == BE_STATIC) +#define var_istype(_v, _t) (var_primetype(_v) == _t) #define var_settype(_v, _t) ((_v)->type = _t) +#define var_markstatic(_v) var_settype(_v, var_type(_v) | BE_STATIC) +#define var_clearstatic(_v) var_settype(_v, var_type(_v) & ~BE_STATIC) #define var_setobj(_v, _t, _o) { (_v)->v.p = _o; var_settype(_v, _t); } #define var_isnil(_v) var_istype(_v, BE_NIL) @@ -215,7 +219,6 @@ typedef const char* (*breader)(void*, size_t*); #define var_isclosure(_v) var_istype(_v, BE_CLOSURE) #define var_isntvclos(_v) var_istype(_v, BE_NTVCLOS) #define var_isntvfunc(_v) var_istype(_v, BE_NTVFUNC) -#define var_isctypefunc(_v) var_istype(_v, BE_CTYPEFUNC) #define var_isfunction(_v) (var_basetype(_v) == BE_FUNCTION) #define var_isproto(_v) var_istype(_v, BE_PROTO) #define var_isclass(_v) var_istype(_v, BE_CLASS) @@ -238,11 +241,10 @@ typedef const char* (*breader)(void*, size_t*); #define var_setclosure(_v, _o) var_setobj(_v, BE_CLOSURE, _o) #define var_setntvclos(_v, _o) var_setobj(_v, BE_NTVCLOS, _o) #define var_setntvfunc(_v, _o) { (_v)->v.nf = (_o); var_settype(_v, BE_NTVFUNC); } -#define var_setctypefunc(_v, _o) { (_v)->v.nf = (_o); var_settype(_v, BE_CTYPEFUNC); } #define var_setlist(_v, _o) var_setobj(_v, BE_LIST, _o) #define var_setmap(_v, _o) var_setobj(_v, BE_MAP, _o) #define var_setmodule(_v, _o) var_setobj(_v, BE_MODULE, _o) -#define var_setindex(_v, _i) { var_settype(_v, BE_INDEX); (_v)->v.i = (_i); } +#define var_setindex(_v, _i) { var_settype(_v, BE_INDEX); (_v)->v.i = (_i); } #define var_setproto(_v, _o) var_setobj(_v, BE_PROTO, _o) #define var_tobool(_v) ((_v)->v.b) diff --git a/lib/libesp32/berry/src/be_parser.c b/lib/libesp32/berry/src/be_parser.c index af59f5749..ba5b408d8 100644 --- a/lib/libesp32/berry/src/be_parser.c +++ b/lib/libesp32/berry/src/be_parser.c @@ -18,7 +18,6 @@ #include "be_func.h" #include "be_class.h" #include "be_decoder.h" -#include "be_debug.h" #include "be_exec.h" #include @@ -1392,11 +1391,11 @@ static void classvar_stmt(bparser *parser, bclass *c) scan_next_token(parser); /* skip 'var' */ if (match_id(parser, name) != NULL) { check_class_attr(parser, c, name); - be_member_bind(parser->vm, c, name, btrue); + be_class_member_bind(parser->vm, c, name, btrue); while (match_skip(parser, OptComma)) { /* ',' */ if (match_id(parser, name) != NULL) { check_class_attr(parser, c, name); - be_member_bind(parser->vm, c, name, btrue); + be_class_member_bind(parser->vm, c, name, btrue); } else { parser_error(parser, "class var error"); } @@ -1433,7 +1432,7 @@ static void classdef_stmt(bparser *parser, bclass *c, bbool is_static) name = func_name(parser, &e, 1); check_class_attr(parser, c, name); proto = funcbody(parser, name, is_static ? 0 : FUNC_METHOD); - be_method_bind(parser->vm, c, proto->name, proto, is_static); + be_class_method_bind(parser->vm, c, proto->name, proto, is_static); be_stackpop(parser->vm, 1); } @@ -1446,13 +1445,13 @@ static void classstatic_stmt(bparser *parser, bclass *c, bexpdesc *e) classdef_stmt(parser, c, btrue); } else if (match_id(parser, name) != NULL) { check_class_attr(parser, c, name); - be_member_bind(parser->vm, c, name, bfalse); + be_class_member_bind(parser->vm, c, name, bfalse); class_static_assignment_expr(parser, e, name); while (match_skip(parser, OptComma)) { /* ',' */ if (match_id(parser, name) != NULL) { check_class_attr(parser, c, name); - be_member_bind(parser->vm, c, name, bfalse); + be_class_member_bind(parser->vm, c, name, bfalse); class_static_assignment_expr(parser, e, name); } else { parser_error(parser, "class static error"); diff --git a/lib/libesp32/berry/src/be_solidifylib.c b/lib/libesp32/berry/src/be_solidifylib.c index 4d4e3bcb6..1767fb16b 100644 --- a/lib/libesp32/berry/src/be_solidifylib.c +++ b/lib/libesp32/berry/src/be_solidifylib.c @@ -148,7 +148,7 @@ static void m_solidify_list(bvm *vm, blist * list, const char *class_name) // pass key name in case of class, or NULL if none static void m_solidify_bvalue(bvm *vm, bvalue * value, const char *classname, const char *key) { - int type = var_type(value); + int type = var_primetype(value); switch (type) { case BE_NIL: logfmt("be_const_nil()"); @@ -197,7 +197,7 @@ static void m_solidify_bvalue(bvm *vm, bvalue * value, const char *classname, co char func_name_id[id_len]; toidentifier(func_name_id, func_name); logfmt("be_const_%sclosure(%s%s%s_closure)", - func_isstatic(value) ? "static_" : "", + var_isstatic(value) ? "static_" : "", classname ? classname : "", classname ? "_" : "", func_name_id); } @@ -210,7 +210,7 @@ static void m_solidify_bvalue(bvm *vm, bvalue * value, const char *classname, co break; case BE_NTVFUNC: logfmt("be_const_%sfunc(be_ntv_%s_%s)", - func_isstatic(value) ? "static_" : "", + var_isstatic(value) ? "static_" : "", classname ? classname : "unknown", key ? key : "unknown"); break; case BE_INSTANCE: diff --git a/lib/libesp32/berry/src/be_vm.c b/lib/libesp32/berry/src/be_vm.c index 3032fa8ae..622930526 100644 --- a/lib/libesp32/berry/src/be_vm.c +++ b/lib/libesp32/berry/src/be_vm.c @@ -83,13 +83,15 @@ #define equal_rule(op, iseq) \ bbool res; \ + be_assert(!var_isstatic(a)); \ + be_assert(!var_isstatic(b)); \ if (var_isint(a) && var_isint(b)) { \ res = ibinop(op, a, b); \ } else if (var_isnumber(a) && var_isnumber(b)) { \ res = var2real(a) op var2real(b); \ } else if (var_isinstance(a) && !var_isnil(b)) { \ res = object_eqop(vm, #op, iseq, a, b); \ - } else if (var_type(a) == var_type(b)) { /* same types */ \ + } else if (var_primetype(a) == var_primetype(b)) { /* same types */ \ if (var_isnil(a)) { /* nil op nil */ \ res = 1 op 1; \ } else if (var_isbool(a)) { /* bool op bool */ \ @@ -256,6 +258,7 @@ static bbool obj2bool(bvm *vm, bvalue *var) binstance *obj = var_toobj(var); bstring *tobool = str_literal(vm, "tobool"); /* get operator method */ + // TODO what if `tobool` is static int type = be_instance_member(vm, obj, tobool, vm->top); if (type != BE_NONE && type != BE_NIL) { vm->top[1] = *var; /* move self to argv[0] */ @@ -342,6 +345,7 @@ static bbool object_eqop(bvm *vm, bbool isself = var_isinstance(b) && o == var_toobj(b); /* first, try to call the overloaded operator of the object */ int type = be_instance_member(vm, o, be_newstr(vm, op), vm->top); + // TODO check that method is not static if (basetype(type) == BE_FUNCTION) { /* call method */ bvalue *top = vm->top; top[1] = self; /* move self to argv[0] */ @@ -826,41 +830,41 @@ newframe: /* a new call frame */ #if BE_USE_PERF_COUNTERS vm->counter_get++; #endif - bvalue a_temp; /* copy result to a temp variable because the stack may be relocated in virtual member calls */ + bvalue result; /* copy result to a temp variable because the stack may be relocated in virtual member calls */ bvalue *b = RKB(), *c = RKC(); if (var_isinstance(b) && var_isstr(c)) { - obj_attribute(vm, b, var_tostr(c), &a_temp); + obj_attribute(vm, b, var_tostr(c), &result); reg = vm->reg; } else if (var_isclass(b) && var_isstr(c)) { - class_attribute(vm, b, c, &a_temp); + class_attribute(vm, b, c, &result); reg = vm->reg; } else if (var_ismodule(b) && var_isstr(c)) { - module_attribute(vm, b, c, &a_temp); + module_attribute(vm, b, c, &result); reg = vm->reg; } else { attribute_error(vm, "attribute", b, c); - a_temp = *RA(); /* avoid gcc warning for uninitialized variable a_temp, this code is never reached */ + result = *RA(); /* avoid gcc warning for uninitialized variable result, this code is never reached */ } bvalue *a = RA(); - *a = a_temp; /* assign the resul to the specified register on the updated stack */ + *a = result; /* assign the resul to the specified register on the updated stack */ dispatch(); } opcase(GETMET): { #if BE_USE_PERF_COUNTERS vm->counter_get++; #endif - bvalue a_temp; /* copy result to a temp variable because the stack may be relocated in virtual member calls */ + bvalue result; /* copy result to a temp variable because the stack may be relocated in virtual member calls */ bvalue *b = RKB(), *c = RKC(); if (var_isinstance(b) && var_isstr(c)) { binstance *obj = var_toobj(b); - int type = obj_attribute(vm, b, var_tostr(c), &a_temp); + int type = obj_attribute(vm, b, var_tostr(c), &result); reg = vm->reg; bvalue *a = RA(); - *a = a_temp; + *a = result; if (var_basetype(a) == BE_FUNCTION) { - if (func_isstatic(a) || (type == BE_INDEX)) { /* if instance variable then we consider it's non-method */ - /* static method, don't bother with the instance */ - a[1] = a_temp; + if ((type & BE_STATIC) || (type == BE_INDEX)) { /* if instance variable then we consider it's non-method */ + /* static method, don't bother with the instance */ + a[1] = result; var_settype(a, NOT_METHOD); } else { /* this is a real method (i.e. non-static) */ @@ -876,16 +880,16 @@ newframe: /* a new call frame */ str(be_instance_name(obj)), str(var_tostr(c))); } } else if (var_isclass(b) && var_isstr(c)) { - class_attribute(vm, b, c, &a_temp); + class_attribute(vm, b, c, &result); reg = vm->reg; bvalue *a = RA(); - a[1] = a_temp; + a[1] = result; var_settype(a, NOT_METHOD); } else if (var_ismodule(b) && var_isstr(c)) { - module_attribute(vm, b, c, &a_temp); + module_attribute(vm, b, c, &result); reg = vm->reg; bvalue *a = RA(); - a[1] = a_temp; + a[1] = result; var_settype(a, NOT_METHOD); } else { attribute_error(vm, "method", b, c); @@ -913,11 +917,11 @@ newframe: /* a new call frame */ /* if value is a function, we mark it as a static to distinguish from methods */ bclass *obj = var_toobj(a); bstring *attr = var_tostr(b); - bvalue c_static = *c; - if (var_isfunction(&c_static)) { - c_static.type = func_setstatic(&c_static); + bvalue result = *c; + if (var_isfunction(&result)) { + var_markstatic(&result); } - if (!be_class_setmember(vm, obj, attr, &c_static)) { + if (!be_class_setmember(vm, obj, attr, &result)) { reg = vm->reg; vm_error(vm, "attribute_error", "class '%s' cannot assign to static attribute '%s'", @@ -1253,6 +1257,7 @@ void be_dofunc(bvm *vm, bvalue *v, int argc) be_assert(vm->reg <= v && v < vm->stacktop); be_assert(vm->stack <= vm->reg && vm->reg < vm->stacktop); int pos = v - vm->reg; + be_assert(!var_isstatic(v)); switch (var_type(v)) { case BE_CLASS: do_class(vm, pos, argc); break; case BE_CLOSURE: do_closure(vm, pos, argc); break;