GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/lib/instr.c Lines: 96 98 98.0 %
Date: 2020-08-07 19:15:19 Branches: 26 32 81.2 %

Line Branch Exec Source
1
#include <stdlib.h>
2
#include <string.h>
3
#include "gwion_util.h"
4
#include "gwion_ast.h"
5
#include "gwion_env.h"
6
#include "vm.h"
7
#include "instr.h"
8
#include "object.h"
9
#include "array.h"
10
#include "shreduler_private.h"
11
#include "gwion.h"
12
#include "operator.h"
13
#include "import.h"
14
#include "emit.h"
15
#include "template.h"
16
17
7
INSTR(DTOR_EOC) {
18
7
  const M_Object o = *(M_Object*)MEM(0);
19
7
  o->type_ref = o->type_ref->e->parent;
20
7
  _release(o, shred);
21
7
  shred->info->me->ref = 1;
22
7
  vm_shred_exit(shred);
23
7
}
24
25
8
INSTR(PopArrayClass) {
26
8
  POP_REG(shred, SZ_INT);
27
8
  const M_Object obj = *(M_Object*)REG(-SZ_INT);
28
8
  const M_Object tmp = *(M_Object*)REG(0);
29
8
  ARRAY(obj) = ARRAY(tmp);
30
8
  free_object(shred->info->mp, tmp);
31
8
}
32
33
22
ANN static Func_Def from_base(const Env env, struct dottmpl_ *const dt, const Nspc nspc) {
34
22
  const Func_Def fdef = dt->def ?: dt->base;
35
22
  const Symbol sym = func_symbol(env, nspc->name, s_name(fdef->base->xid),
36
    "template", dt->vt_index);
37

22
  DECL_OO(const Value, v, = nspc_lookup_value0(nspc, sym) ?: nspc_lookup_value0(nspc, fdef->base->xid))
38
20
  if(isa(v->type, env->gwion->type[et_class]) > 0)
39
    return NULL;
40
20
  const Func_Def def = cpy_func_def(env->gwion->mp, v->d.func_ref->def);
41
20
  def->base->tmpl->call = cpy_type_list(env->gwion->mp, dt->tl);
42
20
  def->base->tmpl->base = dt->vt_index;
43
20
  dt->def = def;
44
20
  dt->owner = v->from->owner;
45
20
  dt->owner_class = v->from->owner_class;
46
20
  SET_FLAG(def, template);
47
20
  return def;
48
}
49
50
22
ANN static Func_Def traverse_tmpl(const Emitter emit, struct dottmpl_ *const dt, const Nspc nspc) {
51
22
  DECL_OO(const Func_Def, def, = from_base(emit->env, dt, nspc))
52
20
  CHECK_BO(traverse_dot_tmpl(emit, dt))
53
18
  return def;
54
}
55
56
18
INSTR(GTmpl) {
57
18
  struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val;
58
18
  const Func f = *(Func*)REG(-SZ_INT);
59
18
  const m_str name = f->name;
60
18
  const Emitter emit = shred->info->vm->gwion->emit;
61
18
  emit->env->name = "runtime";
62
18
  m_str tmpl_name = tl2str(emit->env, dt->tl);
63
26
  for(m_uint i = 0 ; i <= f->value_ref->from->offset; ++i) {
64
18
    const Symbol sym = func_symbol(emit->env, f->value_ref->from->owner->name,
65
      name, tmpl_name, i);
66
18
    const Func base = nspc_lookup_func0(f->value_ref->from->owner, sym);
67
18
    if(base) {
68
10
      free_mstr(emit->gwion->mp, tmpl_name);
69
      assert(base->code);
70
10
      *(VM_Code*)(shred->reg -SZ_INT) = base->code;
71
10
      return;
72
    }
73
  }
74
8
  free_mstr(emit->gwion->mp, tmpl_name);
75
8
  dt->def = f->def;
76
8
  const Func_Def def = traverse_tmpl(emit, dt, f->value_ref->from->owner);
77
8
  if(!def)
78
    Except(shred, "MissigTmplPtrException[internal]");
79
8
  *(VM_Code*)(shred->reg -SZ_INT) = def->base->func->code;
80
}
81
82
37
INSTR(DotTmpl) {
83
37
  struct dottmpl_ *dt = (struct dottmpl_*)instr->m_val;
84
37
  const m_str name = dt->name;
85
37
  const M_Object o = *(M_Object*)REG(-SZ_INT);
86
37
  Type t = !GET_FLAG(o->type_ref, nonnull) ? o->type_ref : o->type_ref->e->parent;
87
41
  do {
88
41
    const Emitter emit = shred->info->vm->gwion->emit;
89
41
    emit->env->name = "runtime";
90
41
    char str[instr->m_val2 + strlen(t->name) + 1];
91
41
    strcpy(str, name);
92
41
    strcpy(str + instr->m_val2, t->name);
93
41
    const Func f = nspc_lookup_func0(t->nspc, insert_symbol(emit->env->gwion->st, str));
94
41
    if(f) {
95
27
      if(!f->code)
96
1
        break;
97
26
      if(GET_FLAG(f, member))
98
26
        shred->reg += SZ_INT;
99
26
      *(VM_Code*)(shred->reg-SZ_INT) = f->code;
100
26
      return;
101
    } else {
102
14
      const Func_Def def = traverse_tmpl(emit, dt, t->nspc);
103
14
      if(!def)
104
4
        continue;
105
10
      const Func f = def->base->func;
106
10
      if(GET_FLAG(f, member))
107
10
        shred->reg += SZ_INT;
108
10
      *(VM_Code*)(shred->reg-SZ_INT) = f->code;
109
10
      return;
110
    }
111
4
  } while((t = t->e->parent));
112
1
  Except(shred, "MissigTmplException[internal]");
113
}
114
115
#define VAL (*(m_uint*)(byte + SZ_INT))
116
#define FVAL (*(m_float*)(byte + SZ_INT))
117
#define VAL2 (*(m_uint*)(byte + SZ_INT*2))
118
#define BYTE(a)  m_bit *byte = shred->code->bytecode + (shred->pc -1)* SZ_INT*3; *(m_bit*)byte = a;
119
120
3
INSTR(SetFunc) {
121
3
  BYTE(eRegPushImm)
122
3
  const Func f = (Func)instr->m_val;
123
3
  VAL = *(m_uint*)(shred->reg) = (m_uint)f->code;
124
3
  shred->reg += SZ_INT;
125
3
}
126
127
2
INSTR(SetRecurs) {
128
2
  BYTE(eRegPushImm)
129
2
  VAL = *(m_uint*)(shred->reg) = (m_uint)shred->code;
130
2
  shred->reg += SZ_INT;
131
2
}
132
133
1
INSTR(SetCtor) {
134
1
  BYTE(eRegSetImm)
135
1
  const Type t = (Type)instr->m_val;
136
1
  VAL = *(m_uint*)(shred->reg + SZ_INT) = (m_uint)t->nspc->pre_ctor;
137
1
  VAL2 = SZ_INT;
138
1
}
139