VALUE make_normal_type_constructor(VALUE normal_type) { VALUE ret; OBJECT *normal_type_constructor; normal_type_constructor = NGS_MALLOC(sizeof(*normal_type_constructor)); assert(normal_type_constructor); SET_OBJ(ret, normal_type_constructor); OBJ_TYPE_NUM(ret) = T_UTCTR; NORMAL_TYPE_CONSTRUCTOR_TYPE(ret) = normal_type; return ret; }
VALUE make_normal_type_instance(VALUE normal_type) { VALUE ret; USER_TYPE_INSTANCE_OBJECT *normal_type_instance; normal_type_instance = NGS_MALLOC(sizeof(*normal_type_instance)); assert(normal_type_instance); SET_OBJ(ret, normal_type_instance); OBJ_TYPE(ret) = normal_type; OBJ_DATA(ret) = make_array(0); return ret; }
VALUE make_normal_type(VALUE name) { VALUE ret; NGS_TYPE *t; t = NGS_MALLOC(sizeof(*t)); assert(t); SET_OBJ(ret, t); OBJ_TYPE_NUM(ret) = T_TYPE; NGS_TYPE_NAME(ret) = name; NGS_TYPE_FIELDS(ret) = make_hash(8); // Hash: name->index NGS_TYPE_CONSTRUCTORS(ret) = make_array(1); NGS_TYPE_PARENTS(ret) = make_array(0); VALUE ctr = make_normal_type_constructor(ret); ARRAY_ITEMS(NGS_TYPE_CONSTRUCTORS(ret))[0] = ctr; return ret; }
VALUE make_hash(size_t start_buckets) { VALUE ret; HASH_OBJECT *hash; hash = NGS_MALLOC(sizeof(*hash)); assert(hash); SET_OBJ(ret, hash); OBJ_TYPE_NUM(ret) = T_HASH; if(start_buckets) { OBJ_DATA_PTR(ret) = NGS_MALLOC(start_buckets * sizeof(HASH_OBJECT_ENTRY *)); memset(OBJ_DATA_PTR(ret), 0, start_buckets * sizeof(HASH_OBJECT_ENTRY *)); // XXX check if needed } else { OBJ_DATA_PTR(ret) = NULL; } HASH_BUCKETS_N(ret) = start_buckets; HASH_HEAD(ret) = NULL; HASH_TAIL(ret) = NULL; OBJ_LEN(ret) = 0; return ret; }
// TODO: consider allocating power-of-two length VALUE make_var_len_obj(uintptr_t type, const size_t item_size, const size_t len) { VALUE v; VAR_LEN_OBJECT *vlo; vlo = NGS_MALLOC(sizeof(*vlo)); assert(vlo); vlo->base.type.num = type; vlo->len = len; vlo->allocated = len; vlo->item_size = item_size; if(len) { vlo->base.val.ptr = NGS_MALLOC(item_size*len); assert(vlo->base.val.ptr); } else { vlo->base.val.ptr = NULL; } SET_OBJ(v, vlo); return v; }
static void init_version_structure() { #define SET_INT(W,value) (W).type = TYPE_INT; (W).v.num = (value) #define SET_STR(W,value) (W).type = TYPE_STR; (W).v.str = str_dup(value) #define SET_OBJ(W,value) (W).type = TYPE_OBJ; (W).v.obj = (value) #define SET_VAR(W,value) (W) = var_ref(value) #define DEPTH 4 Var stack[DEPTH]; Var *the_list = stack; #define BEGIN_LIST(n) \ if (++the_list - stack >= DEPTH) \ panic("init_version_structure: push"); \ the_list[0] = new_list(n) #define END_LIST() \ if (the_list-- == stack) \ panic("init_version_structure: pop"); \ the_list[0] = listappend(the_list[0],the_list[1]) #define BEGIN_GROUP(name) \ BEGIN_LIST(1); \ SET_STR(the_list[0].v.list[1],#name); \ BEGIN_LIST(0) #define END_GROUP() END_LIST(); END_LIST() Var item; #define PUSH_VALUE(WHAT,value) \ SET_##WHAT(item,value); \ the_list[0] = listappend(the_list[0], item); #define PUSH_PAIR(name,WHAT,value) \ item = new_list(2); \ SET_STR(item.v.list[1],name); \ SET_##WHAT(item.v.list[2],value); \ the_list[0] = listappend(the_list[0], item); /* create non-string/int true and false values */ Var falsev; Var truev = new_list(1); SET_INT(truev.v.list[1],0); SET_OBJ(falsev,-1); the_list[0] = new_list(0); PUSH_PAIR("major",INT,VERSION_MAJOR); PUSH_PAIR("minor",INT,VERSION_MINOR); PUSH_PAIR("release",INT,VERSION_RELEASE); PUSH_PAIR("ext",STR,VERSION_EXT); PUSH_PAIR("string",STR,server_version); BEGIN_GROUP(features); #define _FDEF(name) PUSH_VALUE(STR,#name) #ifdef VERSION_FEATURES VERSION_FEATURES(_FDEF); #endif END_GROUP(); BEGIN_GROUP(options); #define _DINT(name,value) PUSH_PAIR(name,INT,value) #define _DSTR(name,value) PUSH_PAIR(name,STR,value) #define _DDEF(name) PUSH_PAIR(name,VAR,truev) #define _DNDEF(name) PUSH_PAIR(name,VAR,falsev) #include "version_options.h" END_GROUP(); #ifdef VERSION_MAKEVARS BEGIN_GROUP(make); #define _MDEF(name,value) PUSH_PAIR(#name,STR,value) VERSION_MAKEVARS(_MDEF); END_GROUP(); #endif BEGIN_GROUP(source); #define _SDEF(name,value) PUSH_PAIR(#name,STR,value) #ifdef VERSION_SOURCE VERSION_SOURCE(_SDEF); #endif END_GROUP(); if (stack != the_list) panic("init_version_structure: unpopped stuff"); free_var(truev); free_var(falsev); version_structure = the_list[0].v.list; }