| Line | Branch | Exec | Source | 
|---|---|---|---|
| 1 | #include "gwion_util.h" | ||
| 2 | #include "gwion_ast.h" | ||
| 3 | #include "gwion_env.h" | ||
| 4 | #include "vm.h" | ||
| 5 | #include "traverse.h" | ||
| 6 | #include "parse.h" | ||
| 7 | #include "gwion.h" | ||
| 8 | #include "clean.h" | ||
| 9 | #include "object.h" | ||
| 10 | #include "instr.h" | ||
| 11 | #include "operator.h" | ||
| 12 | #include "import.h" | ||
| 13 | |||
| 14 | 140739 | ANN static inline m_bool freeable(const Type a) { | |
| 15 | 4/4✓ Branch 1 taken 132131 times. ✓ Branch 2 taken 8608 times. ✓ Branch 3 taken 7 times. ✓ Branch 4 taken 132124 times. | 140739 | return tflag(a, tflag_tmpl) || GET_FLAG(a, global); | 
| 16 | } | ||
| 17 | |||
| 18 | 140739 | ANN void free_type(const Type a, struct Gwion_ *const gwion) { | |
| 19 | 2/2✓ Branch 1 taken 8615 times. ✓ Branch 2 taken 132124 times. | 140739 | if (freeable(a)) { | 
| 20 | 2/2✓ Branch 1 taken 638 times. ✓ Branch 2 taken 7977 times. | 8615 | if (tflag(a, tflag_udef)) | 
| 21 | 638 | free_union_def(gwion->mp, a->info->udef); | |
| 22 | 2/2✓ Branch 1 taken 3914 times. ✓ Branch 2 taken 4063 times. | 7977 | else if (tflag(a, tflag_cdef)) | 
| 23 | 3914 | class_def_cleaner(gwion, a->info->cdef); | |
| 24 | } | ||
| 25 | // if (tflag(a, tflag_cdef) && a->info->parent) | ||
| 26 | // type_remref(a->info->parent, gwion); | ||
| 27 | 2/2✓ Branch 0 taken 22962 times. ✓ Branch 1 taken 117777 times. | 140739 | if (a->nspc) nspc_remref(a->nspc, gwion); | 
| 28 | 2/2✓ Branch 0 taken 22323 times. ✓ Branch 1 taken 118416 times. | 140739 | if (a->info->tuple) free_tupleform(a->info->tuple, gwion); | 
| 29 | 140739 | mp_free(gwion->mp, TypeInfo, a->info); | |
| 30 | 140739 | mp_free(gwion->mp, Type, a); | |
| 31 | 140739 | } | |
| 32 | |||
| 33 | 218831 | Type new_type(MemPool p, const m_str name, const Type parent) { | |
| 34 | 218831 | const Type type = mp_calloc(p, Type); | |
| 35 | 218831 | type->name = name; | |
| 36 | 218831 | type->info = mp_calloc(p, TypeInfo); | |
| 37 | 218831 | type->info->parent = parent; | |
| 38 | 2/2✓ Branch 0 taken 93424 times. ✓ Branch 1 taken 125407 times. | 218831 | if (parent) type->size = parent->size; | 
| 39 | 218831 | type->ref = 1; | |
| 40 | 218831 | return type; | |
| 41 | } | ||
| 42 | |||
| 43 | 182260 | ANN Type type_copy(MemPool p, const Type type) { | |
| 44 | 182260 | const Type a = new_type(p, type->name, type->info->parent); | |
| 45 | 182260 | a->size = type->size; | |
| 46 | 182260 | a->array_depth = type->array_depth; | |
| 47 | 182260 | a->info->gack = type->info->gack; | |
| 48 | 182260 | return a; | |
| 49 | } | ||
| 50 | |||
| 51 | 273145 | ANN m_bool isa(const restrict Type var, const restrict Type parent) { | |
| 52 | return (var == parent) ? GW_OK | ||
| 53 | 4/4✓ Branch 0 taken 209799 times. ✓ Branch 1 taken 63346 times. ✓ Branch 2 taken 162641 times. ✓ Branch 3 taken 47158 times. | 273145 | : var->info->parent ? isa(var->info->parent, parent) | 
| 54 | : GW_ERROR; | ||
| 55 | } | ||
| 56 | |||
| 57 | 73 | ANN Type find_common_anc(const restrict Type lhs, const restrict Type rhs) { | |
| 58 | 3/4✓ Branch 0 taken 7 times. ✓ Branch 1 taken 66 times. ✗ Branch 2 not taken. ✓ Branch 3 taken 7 times. | 73 | return isa(lhs, rhs) > 0 ? rhs : isa(rhs, lhs) > 0 ? lhs : NULL; | 
| 59 | } | ||
| 60 | |||
| 61 | #define describe_find(name, t) \ | ||
| 62 | ANN t find_##name(const Type type, const Symbol xid) { \ | ||
| 63 | if (type->nspc) { \ | ||
| 64 | const t val = nspc_lookup_##name##2(type->nspc, xid); \ | ||
| 65 | if (val) return val; \ | ||
| 66 | } \ | ||
| 67 | return type->info->parent ? find_##name(type->info->parent, xid) : NULL; \ | ||
| 68 | } | ||
| 69 | 6/6✓ Branch 0 taken 291513 times. ✓ Branch 1 taken 190719 times. ✓ Branch 3 taken 16335 times. ✓ Branch 4 taken 275178 times. ✓ Branch 5 taken 275178 times. ✓ Branch 6 taken 190719 times. | 482232 | describe_find(value, Value) | 
| 70 | // describe_find(func, Func) | ||
| 71 | |||
| 72 | 50763 | ANN Type array_base(Type type) { | |
| 73 | 50763 | const Type t = typedef_base(type); | |
| 74 | 2/2✓ Branch 0 taken 173 times. ✓ Branch 1 taken 50590 times. | 50763 | return t->array_depth ? array_base(t->info->base_type) : t; | 
| 75 | } | ||
| 76 | |||
| 77 | 23688 | ANN /*static */ Symbol array_sym(const Env env, const Type src, | |
| 78 | 23688 | const m_uint depth) { | |
| 79 | 2/2✓ Branch 0 taken 17 times. ✓ Branch 1 taken 23671 times. | 23688 | if (src->array_depth == depth) return insert_symbol(src->name); | 
| 80 | 23671 | const m_uint total_depth = src->array_depth + depth; | |
| 81 | 23671 | const Type t = array_base_simple(src); | |
| 82 | 23671 | size_t len = strlen(t->name); | |
| 83 | 23671 | char name[len + 2 * total_depth + 1]; | |
| 84 | 23671 | strcpy(name, t->name); | |
| 85 | 23671 | m_uint i = total_depth + 1; | |
| 86 | 2/2✓ Branch 0 taken 23740 times. ✓ Branch 1 taken 23671 times. | 47411 | while (--i) { | 
| 87 | 23740 | strcpy(name + len, "[]"); | |
| 88 | 23740 | len += 2; | |
| 89 | } | ||
| 90 | 23671 | return insert_symbol(name); | |
| 91 | } | ||
| 92 | |||
| 93 | 22336 | ANN Type array_type(const Env env, const Type src, const m_uint depth) { | |
| 94 | 22336 | const Symbol sym = array_sym(env, src, depth); | |
| 95 | 22336 | const Type type = nspc_lookup_type1(src->info->value->from->owner, sym); | |
| 96 | 2/2✓ Branch 0 taken 20984 times. ✓ Branch 1 taken 1352 times. | 22336 | if (type) return type; | 
| 97 | 1352 | const size_t tdepth = depth + src->array_depth; | |
| 98 | 2/2✓ Branch 0 taken 15 times. ✓ Branch 1 taken 1337 times. | 1352 | const Type base = tdepth > 1 ? array_type(env, src, tdepth - 1) : src; | 
| 99 | 1352 | struct TemplateScan ts = {.t = base, /*.td=td*/ }; | |
| 100 | 1352 | struct Op_Import opi = {.op = insert_symbol("class"), | |
| 101 | 1352 | .lhs = env->gwion->type[et_array], | |
| 102 | 1352 | .data = (uintptr_t)&ts}; | |
| 103 | 1352 | return op_check(env, &opi); | |
| 104 | } | ||
| 105 | |||
| 106 | 13558 | ANN bool type_ref(Type t) { | |
| 107 | do { | ||
| 108 | 2/2✓ Branch 1 taken 2 times. ✓ Branch 2 taken 13556 times. | 13558 | if (tflag(t, tflag_empty)) return true; | 
| 109 | 4/4✓ Branch 1 taken 11 times. ✓ Branch 2 taken 13545 times. ✓ Branch 4 taken 7 times. ✓ Branch 5 taken 4 times. | 13556 | if (tflag(t, tflag_typedef) && tflag(t, tflag_cdef)) { | 
| 110 | 3/4✓ Branch 0 taken 7 times. ✗ Branch 1 not taken. ✓ Branch 2 taken 5 times. ✓ Branch 3 taken 2 times. | 7 | if (t->info->cdef->base.ext && t->info->cdef->base.ext->array) { | 
| 111 | 1/2✗ Branch 0 not taken. ✓ Branch 1 taken 5 times. | 5 | if (!t->info->cdef->base.ext->array->exp) | 
| 112 | ✗ | return true; | |
| 113 | else { | ||
| 114 | 5 | const Type type = t->info->parent->info->base_type; | |
| 115 | 1/2✗ Branch 1 not taken. ✓ Branch 2 taken 5 times. | 5 | if (tflag(type, tflag_empty)) return true; | 
| 116 | } | ||
| 117 | } | ||
| 118 | } | ||
| 119 | 2/2✓ Branch 0 taken 8844 times. ✓ Branch 1 taken 4712 times. | 13556 | } while ((t = t->info->parent)); | 
| 120 | 4712 | return false; | |
| 121 | } | ||
| 122 | |||
| 123 | 34 | ANN m_uint get_depth(const Type type) { | |
| 124 | 34 | m_uint depth = 0; | |
| 125 | 34 | Type t = type; | |
| 126 | do { | ||
| 127 | 2/2✓ Branch 0 taken 30 times. ✓ Branch 1 taken 55 times. | 85 | if (t->array_depth) { | 
| 128 | 30 | depth += t->array_depth; | |
| 129 | 30 | t = t->info->base_type; | |
| 130 | } else | ||
| 131 | 55 | t = t->info->parent; | |
| 132 | 2/2✓ Branch 0 taken 51 times. ✓ Branch 1 taken 34 times. | 85 | } while (t); | 
| 133 | 34 | return depth; | |
| 134 | } | ||
| 135 | |||
| 136 | 59259 | ANN bool is_func(const struct Gwion_ *gwion, const Type t) { | |
| 137 | 59259 | return isa(actual_type(gwion, t), gwion->type[et_function]) > 0; | |
| 138 | } | ||
| 139 | |||
| 140 | 202156 | ANN inline bool is_class(const struct Gwion_ *gwion, const Type t) { | |
| 141 | // return isa(t, gwion->type[et_class]) > 0; | ||
| 142 | 202156 | return t->info->parent == gwion->type[et_class]; | |
| 143 | } | ||
| 144 | |||
| 145 | 70592 | ANN Type actual_type(const struct Gwion_ *gwion, const Type t) { | |
| 146 | 2/2✓ Branch 1 taken 78 times. ✓ Branch 2 taken 70514 times. | 70592 | return is_class(gwion, t) ? t->info->base_type : t; | 
| 147 | } | ||
| 148 | |||
| 149 | 15797 | ANN void inherit(const Type t) { | |
| 150 | 15797 | const Nspc nspc = t->nspc, parent = t->info->parent->nspc; | |
| 151 | 2/2✓ Branch 0 taken 15792 times. ✓ Branch 1 taken 5 times. | 15797 | if (nspc) nspc->offset = parent->offset; | 
| 152 | 4/4✓ Branch 0 taken 15792 times. ✓ Branch 1 taken 5 times. ✓ Branch 2 taken 9173 times. ✓ Branch 3 taken 6619 times. | 15797 | if (parent && parent->vtable.ptr) vector_copy2(&parent->vtable, &nspc->vtable); | 
| 153 | 15797 | } | |
| 154 | |||
| 155 | 5979 | ANN bool from_global_nspc(const Env env, const Nspc nspc) { | |
| 156 | 5979 | Nspc global = env->global_nspc; | |
| 157 | 2/2✓ Branch 0 taken 6431 times. ✓ Branch 1 taken 174 times. | 6605 | while(global) { | 
| 158 | 2/2✓ Branch 0 taken 5805 times. ✓ Branch 1 taken 626 times. | 6431 | if (nspc == global) | 
| 159 | 5805 | return true; | |
| 160 | 626 | global = global->parent; | |
| 161 | } | ||
| 162 | 174 | return false; | |
| 163 | } | ||
| 164 | |||
| 165 | 3418 | ANN bool type_global(const Env env, Type t) { | |
| 166 | 2/2✓ Branch 1 taken 3246 times. ✓ Branch 2 taken 172 times. | 3418 | do if(from_global_nspc(env, t->info->value->from->owner)) return true; | 
| 167 | 2/2✓ Branch 0 taken 5 times. ✓ Branch 1 taken 167 times. | 172 | while((t = t->info->value->from->owner_class)); | 
| 168 | 167 | return false; | |
| 169 | } | ||
| 170 |