mirror of https://github.com/arendst/Tasmota.git
268 lines
9.4 KiB
C
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
|