Tasmota/lib/libesp32/berry/src/be_object.h

268 lines
9.4 KiB
C

/********************************************************************
** Copyright (c) 2018-2020 Guan Wenliang
** This file is part of the Berry default interpreter.
** skiars@qq.com, https://github.com/Skiars/berry
** See Copyright Notice in the LICENSE file or at
** https://github.com/Skiars/berry/blob/master/LICENSE
********************************************************************/
#ifndef BE_OBJECT_H
#define BE_OBJECT_H
#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_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 */
#define BE_GCOBJECT_MAX (3<<5) /* 96 - from this type can't be gced */
#define BE_STRING 16
#define BE_CLASS 17
#define BE_INSTANCE 18
#define BE_PROTO 19
#define BE_LIST 20
#define BE_MAP 21
#define BE_MODULE 22
#define BE_COMOBJ 23 /* common object */
#define BE_NTVFUNC ((0 << 5) | BE_FUNCTION) /* 6 - cannot be gced */
#define BE_CLOSURE ((1 << 5) | BE_FUNCTION) /* 38 - can be gced */
#define BE_NTVCLOS ((2 << 5) | BE_FUNCTION) /* 70 - can be gced*/
#define BE_CTYPE_FUNC ((3 << 5) | BE_FUNCTION) /* 102 - cannot be gced */
#define BE_STATIC (1 << 7) /* 128 */
/* values for bproto.varg */
#define BE_VA_VARARG (1 << 0) /* function has variable number of arguments */
#define BE_VA_METHOD (1 << 1) /* function is a method (this is only a hint) */
#define BE_VA_STATICMETHOD (1 << 2) /* the function is a static method and has the class as implicit '_class' variable */
#define BE_VA_SHARED_KTAB (1 << 3) /* the funciton has a shared consolidated ktab */
#define BE_VA_NOCOMPACT (1 << 4) /* the funciton has a shared consolidated ktab */
#define array_count(a) (sizeof(a) / sizeof((a)[0]))
#define bcommon_header \
struct bgcobject *next; \
bbyte type; \
bbyte marked
#define bstring_header \
bcommon_header; \
bbyte extra; \
bbyte slen
typedef struct bgcobject {
bcommon_header;
} bgcobject;
typedef struct bclosure bclosure;
typedef struct bntvclos bntvclos;
typedef struct bclass bclass;
typedef struct binstance binstance;
typedef struct binstance_arg3 binstance_arg3;
typedef struct blist blist;
typedef struct bmap bmap;
typedef struct bupval bupval;
typedef uint32_t binstruction;
typedef struct bstring {
bstring_header;
} bstring;
/* the definition of the vector and stack data structures.
* in fact, the stack is implemented by vector. */
typedef struct bvector {
int capacity; /* the number of elements that the vector can store */
int size; /* the size of each element (bytes) */
int count; /* number of elements of the vector */
void *data; /* the data block pointer, if vector is empty,
it will point to the first element */
void *end; /* pointer to the last element, if the vector is empty,
the end pointer will be smaller than the data pointer */
} bvector, bstack;
/* berry value data union, a berry value is always described
* by the data structure contained in the bvaldata union. */
union bvaldata {
bbool b; /* boolean */
breal r; /* real number */
bint i; /* integer number */
void *p; /* object pointer */
const void *c; /* const object pointer */
bstring *s; /* string pointer */
bgcobject *gc; /* GC object */
bntvfunc nf; /* native C function */
#ifdef __cplusplus
BE_CONSTEXPR bvaldata(bbool v) : b(v) {}
BE_CONSTEXPR bvaldata(breal v) : r(v) {}
BE_CONSTEXPR bvaldata(bint v) : i(v) {}
BE_CONSTEXPR bvaldata(void *v) : p(v) {}
BE_CONSTEXPR bvaldata(const void *v) : c(v) {}
BE_CONSTEXPR bvaldata(bntvfunc v) : nf(v) {}
#endif
};
/* berry value. for simple types, the value of the data is stored,
* while the complex type stores a reference to the data. */
typedef struct bvalue {
union bvaldata v; /* the value data */
int type; /* the value type */
} bvalue;
typedef struct {
#if BE_DEBUG_VAR_INFO
bstring *name;
#endif
bbyte instack;
bbyte idx;
} bupvaldesc;
typedef struct {
#if BE_DEBUG_RUNTIME_INFO > 1
uint16_t linenumber;
uint16_t endpc;
#else
int linenumber;
int endpc;
#endif
} blineinfo;
typedef struct {
bstring *name;
#if BE_DEBUG_RUNTIME_INFO > 1
uint16_t beginpc;
uint16_t endpc;
#else
int beginpc;
int endpc;
#endif
} bvarinfo;
typedef struct bproto {
bcommon_header;
bbyte nstack; /* number of stack size by this function */
bbyte nupvals; /* upvalue count */
bbyte argc; /* argument count */
bbyte varg; /* variable argument position + 1 */
int16_t codesize; /* code size */
int16_t nconst; /* constants count */
int16_t nproto; /* proto count */
bgcobject *gray; /* for gc gray list */
bupvaldesc *upvals;
bvalue *ktab; /* constants table */
struct bproto **ptab; /* proto table */
binstruction *code; /* instructions sequence */
bstring *name; /* function name */
#if BE_DEBUG_SOURCE_FILE
bstring *source; /* source file name */
#endif
#if BE_DEBUG_RUNTIME_INFO /* debug information */
blineinfo *lineinfo;
int nlineinfo;
#endif
#if BE_DEBUG_VAR_INFO
bvarinfo *varinfo;
int nvarinfo;
#endif
} bproto;
/* berry closure */
struct bclosure {
bcommon_header;
bbyte nupvals;
bgcobject *gray; /* for gc gray list */
bproto *proto;
bupval *upvals[1];
};
/* C native function or closure */
struct bntvclos {
bcommon_header;
bbyte nupvals;
bgcobject *gray; /* for gc gray list */
bntvfunc f;
};
/* common object */
typedef struct {
bcommon_header;
void *data;
bntvfunc destroy;
} bcommomobj;
struct blexer;
typedef const char* (*breader)(struct blexer*, void*, size_t*);
#define cast(_T, _v) ((_T)(_v))
#define cast_int(_v) cast(int, _v)
#define cast_bool(_v) cast(bbool, _v)
#define basetype(_t) ((_t) & 0x1F)
#define var_type(_v) ((_v)->type)
#define var_basetype(_v) basetype((_v)->type)
#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)
#define var_isbool(_v) var_istype(_v, BE_BOOL)
#define var_isint(_v) var_istype(_v, BE_INT)
#define var_isreal(_v) var_istype(_v, BE_REAL)
#define var_isstr(_v) var_istype(_v, BE_STRING)
#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_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)
#define var_isinstance(_v) var_istype(_v, BE_INSTANCE)
#define var_islist(_v) var_istype(_v, BE_LIST)
#define var_ismap(_v) var_istype(_v, BE_MAP)
#define var_ismodule(_v) var_istype(_v, BE_MODULE)
#define var_isindex(_v) var_istype(_v, BE_INDEX)
#define var_iscomptr(_v) var_istype(_v, BE_COMPTR)
#define var_isnumber(_v) (var_isint(_v) || var_isreal(_v))
#define var_setnil(_v) var_settype(_v, BE_NIL)
#define var_setval(_v, _s) (*(_v) = *(_s))
#define var_setbool(_v, _b) { var_settype(_v, BE_BOOL); (_v)->v.b = (bbool)(_b); }
#define var_setint(_v, _i) { var_settype(_v, BE_INT); (_v)->v.i = (_i); }
#define var_setreal(_v, _r) { var_settype(_v, BE_REAL); (_v)->v.r = (_r); }
#define var_setstr(_v, _s) var_setobj(_v, BE_STRING, _s)
#define var_setinstance(_v, _o) var_setobj(_v, BE_INSTANCE, _o)
#define var_setclass(_v, _o) var_setobj(_v, BE_CLASS, _o)
#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_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_setproto(_v, _o) var_setobj(_v, BE_PROTO, _o)
#define var_tobool(_v) ((_v)->v.b)
#define var_toint(_v) ((_v)->v.i)
#define var_toreal(_v) ((_v)->v.r)
#define var_tostr(_v) ((_v)->v.s)
#define var_togc(_v) ((_v)->v.gc)
#define var_toobj(_v) ((_v)->v.p)
#define var_tontvfunc(_v) ((_v)->v.nf)
#define var_toidx(_v) cast_int(var_toint(_v))
const char* be_vtype2str(bvalue *v);
bvalue* be_indexof(bvm *vm, int idx);
void be_commonobj_delete(bvm *vm, bgcobject *obj);
int be_commonobj_destroy_generic(bvm* vm);
#endif