GCC Code Coverage Report
Directory: src/ Exec Total Coverage
File: src/emit/emit.c Lines: 1515 1559 97.2 %
Date: 2020-09-12 17:36:58 Branches: 673 862 78.1 %

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 "gwion.h"
6
#include "instr.h"
7
#include "emit.h"
8
#include "object.h"
9
#include "array.h"
10
#include "traverse.h"
11
#include "template.h"
12
#include "escape.h"
13
#include "parse.h"
14
#include "memoize.h"
15
#include "operator.h"
16
#include "import.h"
17
#include "match.h"
18
#include "parser.h"
19
#include "specialid.h"
20
#include "vararg.h"
21
22
#undef insert_symbol
23
#define insert_symbol(a) insert_symbol(emit->gwion->st, (a))
24
25
#undef ERR_B
26
#define ERR_B(a, b, ...) { env_err(emit->env, (a), (b), ## __VA_ARGS__); return GW_ERROR; }
27
#undef ERR_O
28
#define ERR_O(a, b, ...) { env_err(emit->env, (a), (b), ## __VA_ARGS__); return NULL; }
29
30
typedef struct Local_ {
31
  Type type;
32
  m_uint offset;
33
} Local;
34
35
76
static inline void emit_pop(const Emitter emit, const m_uint scope) { env_pop(emit->env, scope); }
36
59
static inline m_uint emit_push(const Emitter emit, const Type type, const Nspc nspc) {
37
59
  return env_push(emit->env, type, nspc);
38
}
39
10
static inline m_uint emit_push_type(const Emitter emit, const Type type) {
40
10
  return env_push_type(emit->env, type);
41
}
42
6
static inline m_uint emit_push_global(const Emitter emit) {
43
6
  return env_push_global(emit->env);
44
}
45
46
856
ANEW static Frame* new_frame(MemPool p) {
47
856
  Frame* frame = mp_calloc(p, Frame);
48
856
  vector_init(&frame->stack);
49
856
  vector_add(&frame->stack, (vtype)NULL);
50
856
  return frame;
51
}
52
53
856
ANN static void free_frame(MemPool p, Frame* a) {
54
  LOOP_OPTIM
55
2819
  for(vtype i = vector_size(&a->stack) + 1; --i;)
56
1107
    if(vector_at(&a->stack, i - 1))
57
251
      mp_free(p, Local, (Local*)vector_at(&a->stack, i - 1));
58
856
  vector_release(&a->stack);
59
856
  mp_free(p, Frame, a);
60
856
}
61
62
1091
ANN static Local* new_local(MemPool p, const Type type) {
63
1091
  Local* local  = mp_calloc(p, Local);
64
1091
  local->type   = type;
65
1091
  return local;
66
}
67
68
1091
ANN static m_uint frame_local(MemPool p, Frame* frame, const Type t) {
69
1091
  Local* local = new_local(p, t);
70
1091
  local->offset = frame->curr_offset;
71
1091
  frame->curr_offset += t->size;
72
1091
  vector_add(&frame->stack, (vtype)local);
73
1091
  return local->offset;
74
}
75
76
1134
ANN static inline void frame_push(Frame* frame) {
77
1134
  vector_add(&frame->stack, (vtype)NULL);
78
1134
}
79
80
9
ANN static void struct_pop(const Emitter emit, const Type type, const m_uint offset) {
81
9
  if(!type->e->tuple)
82
    return;
83
25
  for(m_uint i = 0; i < vector_size(&type->e->tuple->types); ++i) {
84
16
    const Type t = (Type)vector_at(&type->e->tuple->types, i);
85
16
    if(isa(t, emit->gwion->type[et_object]) > 0) {
86
1
      const Instr instr = emit_add_instr(emit, ObjectRelease);
87
1
      instr->m_val = offset + vector_at(&type->e->tuple->offset, i);
88
15
    } else if(GET_FLAG(t, struct))
89
      struct_pop(emit, t, offset + vector_at(&type->e->tuple->offset, i));
90
  }
91
}
92
93
1974
ANN static m_int frame_pop(const Emitter emit) {
94
1974
  Frame *frame = emit->code->frame;
95
1974
  DECL_OB(const Local*, l, = (Local*)vector_pop(&frame->stack))
96
840
  frame->curr_offset -= l->type->size;
97
840
  if(GET_FLAG(l->type, struct)) {
98
9
    struct_pop(emit, l->type, l->offset);
99
9
    return frame_pop(emit);
100
  }
101
831
  return isa(l->type, emit->gwion->type[et_object]) > 0 ? (m_int)l->offset : frame_pop(emit);
102
}
103
104
ANN /*static */m_bool emit_exp(const Emitter emit, Exp exp);
105
ANN static m_bool emit_stmt(const Emitter emit, const Stmt stmt, const m_bool pop);
106
ANN static m_bool emit_stmt_list(const Emitter emit, Stmt_List list);
107
ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot* member);
108
ANN static m_bool emit_func_def(const Emitter emit, const Func_Def func_def);
109
110
856
ANEW static Code* new_code(const Emitter emit, const m_str name) {
111
856
  Code* code = mp_calloc(emit->gwion->mp, Code);
112
856
  code->name = code_name_set(emit->gwion->mp, name, emit->env->name);
113
856
  vector_init(&code->instr);
114
856
  vector_init(&code->stack_break);
115
856
  vector_init(&code->stack_cont);
116
856
  vector_init(&code->stack_return);
117
856
  code->frame = new_frame(emit->gwion->mp);
118
856
  return code;
119
}
120
121
856
ANN static void free_code(MemPool p, Code* code) {
122
856
  vector_release(&code->instr);
123
856
  vector_release(&code->stack_break);
124
856
  vector_release(&code->stack_cont);
125
856
  vector_release(&code->stack_return);
126
856
  free_frame(p, code->frame);
127
856
  free_mstr(p, code->name);
128
856
  mp_free(p, Code, code);
129
856
}
130
131
1134
ANN static void emit_pop_scope(const Emitter emit) {
132
  m_int offset;
133
2543
  while((offset = frame_pop(emit)) > -1) {
134
275
    Instr instr = emit_add_instr(emit, ObjectRelease);
135
275
    instr->m_val = (m_uint)offset;
136
  }
137
1134
  vector_pop(&emit->info->pure);
138
1134
}
139
140
444
ANN static inline void emit_push_code(const Emitter emit, const m_str name) {
141
444
  vector_add(&emit->stack, (vtype)emit->code);
142
444
  emit->code = new_code(emit, name);
143
444
}
144
145
ANN static inline void emit_pop_code(const Emitter emit) {
146
  emit->code = (Code*)vector_pop(&emit->stack);
147
}
148
149
1134
ANN static inline void emit_push_scope(const Emitter emit) {
150
1134
  frame_push(emit->code->frame);
151
1134
  vector_add(&emit->info->pure, 0);
152
1134
}
153
154
565
ANN static inline m_uint emit_code_size(const Emitter emit) {
155
565
  return vector_size(&emit->code->instr);
156
}
157
158
1760
ANN m_uint emit_code_offset(const Emitter emit) {
159
1760
  return emit->code->frame->curr_offset;
160
}
161
162
1091
ANN m_uint emit_local(const Emitter emit, const Type t) {
163
1091
  return frame_local(emit->gwion->mp, emit->code->frame, t);
164
}
165
166
ANN void emit_ext_ctor(const Emitter emit, const Type t);
167
168
656
ANN static inline void maybe_ctor(const Emitter emit, const Type t) {
169

656
  if(!is_special(t) && GET_FLAG(t, ctor))
170
161
    emit_ext_ctor(emit, t);
171
656
}
172
173
656
ANN static void emit_pre_ctor(const Emitter emit, const Type type) {
174
656
  if(type->e->parent)
175
447
    emit_pre_ctor(emit, type->e->parent);
176
656
  maybe_ctor(emit, type);
177

656
  if(GET_FLAG(type, typedef) && type->e->parent->array_depth)
178
7
    emit_array_extend(emit, type->e->parent, type->e->def->base.ext->array->exp);
179
656
}
180
181
#define regxxx(name, instr) \
182
ANN static inline Instr reg##name(const Emitter emit, const m_uint sz) { \
183
  const Instr instr = emit_add_instr(emit, Reg##instr); \
184
  instr->m_val = sz; \
185
  return instr; \
186
}
187
1913
regxxx(pop, Pop)
188
58
regxxx(push, Push)
189
1826
regxxx(pushi, PushImm)
190
3058
regxxx(seti, SetImm)
191
192
12
ANN static void struct_expand(const Emitter emit, const Type t) {
193
12
  const Instr instr = emit_add_instr(emit, Reg2RegDeref);
194
12
  instr->m_val = -SZ_INT;
195
12
  instr->m_val2 = t->size;
196
//  regpush(emit, t->size - SZ_INT);
197
12
}
198
199
200
INSTR(ArrayStruct);
201
202
12
ANN static void emit_pre_constructor_array(const Emitter emit, const Type type) {
203
12
  const m_uint start_index = emit_code_size(emit);
204
12
  const Instr top = emit_add_instr(emit, ArrayTop);
205
12
  top->m_val2 = (m_uint)type;
206
12
  if(GET_FLAG(type, struct)) {
207
    const Instr instr = emit_add_instr(emit, ArrayStruct);
208
    instr->m_val = type->size;
209
  }
210
12
  emit_pre_ctor(emit, type);
211
12
  if(!GET_FLAG(type, struct))
212
12
    emit_add_instr(emit, ArrayBottom);
213
  else
214
    regpop(emit, SZ_INT);
215
12
  regpop(emit, SZ_INT);
216
12
  const Instr pc = emit_add_instr(emit, Goto);
217
12
  pc->m_val = start_index;
218
12
  top->m_val = emit_code_size(emit);
219
12
  regpop(emit, SZ_INT*3);
220
12
  emit_add_instr(emit, ArrayPost);
221
12
}
222
223
38
ANN2(1) static m_bool extend_indices(const Emitter emit, Exp e, const m_uint depth) {
224
38
  if(e)
225
36
    CHECK_BB(emit_exp(emit, e))
226
38
  m_uint count = 0;
227
133
  while(e) {
228
57
    ++count;
229
57
    e = e->next;
230
  }
231
40
  for(m_uint i = count; i < depth; ++i)
232
2
    regpushi(emit, 0);
233
38
  return GW_OK;
234
}
235
236
38
ANEW ANN static ArrayInfo* new_arrayinfo(const Emitter emit, const Type t) {
237
38
  const Type base = array_base(t);
238
38
  ArrayInfo* info = mp_calloc(emit->gwion->mp, ArrayInfo);
239
38
  vector_init(&info->type);
240
59
  for(m_uint i = 1; i < t->array_depth; ++i)
241
21
    vector_add(&info->type, (vtype)array_type(emit->env, base, i));
242
38
  vector_add(&info->type, (vtype)t);
243
38
  info->depth = (m_int)t->array_depth;
244
38
  info->base = base;
245
38
  return info;
246
}
247
248
38
ANN static inline void arrayinfo_ctor(const Emitter emit, ArrayInfo *info) {
249
38
  const Type base = info->base;
250

38
  if(isa(base, emit->gwion->type[et_compound]) > 0 && !GET_FLAG(base, abstract)) {
251
12
    emit_pre_constructor_array(emit, base);
252
//  if(isa(base, emit->gwion->type[et_object]) > 0)
253
12
    info->is_obj = 1;
254
  }
255
38
}
256
257
38
ANN2(1,2) static ArrayInfo* emit_array_extend_inner(const Emitter emit, const Type t, const Exp e) {
258
38
  CHECK_BO(extend_indices(emit, e, t->array_depth))
259
38
  ArrayInfo* info = new_arrayinfo(emit, t);
260
38
  const Instr alloc = emit_add_instr(emit, ArrayAlloc);
261
38
  alloc->m_val = (m_uint)info;
262
38
  arrayinfo_ctor(emit, info);
263
38
  return info;
264
}
265
266
173
ANN void emit_ext_ctor(const Emitter emit, const Type t) {
267
173
  const Instr cpy = emit_add_instr(emit, Reg2Reg);
268
173
  cpy->m_val2 = -SZ_INT;
269
173
  if(t->nspc->pre_ctor) {
270
171
    const Instr set_code = regseti(emit, (m_uint)t->nspc->pre_ctor);
271
171
    set_code->m_val2 = SZ_INT;
272
  } else {
273
2
    const Instr instr = emit_add_instr(emit, SetCtor);
274
2
    instr->m_val = (m_uint)t;
275
  }
276
173
  const m_uint offset = emit_code_offset(emit);
277
173
  const Instr regset = regseti(emit, offset);
278
173
  regset->m_val2 = SZ_INT *2;
279
173
  const Instr push = emit_add_instr(emit, RegPush);
280
173
  push->m_val = SZ_INT *2;
281
173
  const Instr prelude = emit_add_instr(emit, SetCode);
282
173
  prelude->m_val2 = 2;
283
173
  prelude->m_val = SZ_INT;
284
173
  emit_add_instr(emit, Reg2Mem);
285
173
  const Instr next = emit_add_instr(emit, Overflow);
286
173
  next->m_val2 = offset;
287
173
}
288
289
7
ANN m_bool emit_array_extend(const Emitter emit, const Type t, const Exp e) {
290
7
  CHECK_OB(emit_array_extend_inner(emit, t, e))
291
7
  emit_add_instr(emit, PopArrayClass);
292
7
  emit_add_instr(emit, RegAddRef);
293
7
  return GW_OK;
294
}
295
296
240
ANN static inline void emit_notpure(const Emitter emit) {
297
240
  ++VPTR(&emit->info->pure, VLEN(&emit->info->pure) - 1);
298
240
}
299
300
228
ANN2(1,2) m_bool emit_instantiate_object(const Emitter emit, const Type type,
301
      const Array_Sub array, const m_bool is_ref) {
302
228
  emit_notpure(emit);
303
228
  if(type->array_depth) {
304
31
    ArrayInfo* info = emit_array_extend_inner(emit, type, array ? array->exp : NULL);
305
31
    if(info)
306
31
      info->is_ref = is_ref;
307
31
    return info ? GW_OK : GW_ERROR;
308
197
  } else if(!is_ref) {
309
197
    const Instr instr = emit_add_instr(emit, ObjectInstantiate);
310
197
    instr->m_val2 = (m_uint)type;
311
197
    emit_pre_ctor(emit, type);
312
  }
313
197
  return GW_OK;
314
}
315
316
2261
static inline enum Kind kindof(const m_uint size, const uint emit_var) {
317
2261
  if(emit_var)
318
479
    return KIND_ADDR;
319

1782
  return size == SZ_INT ? KIND_INT : size == SZ_FLOAT ? KIND_FLOAT : KIND_OTHER;
320
}
321
322
2261
ANN /*static */Instr emit_kind(Emitter emit, const m_uint size, const uint addr, const f_instr func[]) {
323
2261
  const enum Kind kind = kindof(size, addr);
324
2261
  const Instr instr = emit_add_instr(emit, func[kind]);
325
2261
  instr->m_val2 = size;
326
2261
  return instr;
327
}
328
329
static const f_instr regpushimm[] = { RegPushImm, RegPushImm2, RegPushImm3, RegPushImm4 };
330
static const f_instr regpushmem[] = { RegPushMem, RegPushMem2, RegPushMem3, RegPushMem4 };
331
static const f_instr regpushbase[] = { RegPushBase, RegPushBase2, RegPushBase3, RegPushBase4 };
332
static const f_instr dotstatic[]  = { DotStatic, DotStatic2, DotStatic3, RegPushImm };
333
static const f_instr allocmember[]  = { RegPushImm, RegPushImm2, RegPushImm3, AllocMember4 };
334
static const f_instr allocword[]  = { AllocWord, AllocWord2, AllocWord3, RegPushMem4 };
335
static const f_instr structmember[]  = { StructMember, StructMemberFloat, StructMemberOther, StructMemberAddr };
336
337
ANN Exp symbol_owned_exp(const Gwion gwion, const Symbol *data);
338
144
ANN static m_bool emit_symbol_owned(const Emitter emit, const Symbol *data) {
339
144
  const Exp dot = symbol_owned_exp(emit->gwion, data);
340
144
  dot->info->nspc = prim_exp(data)->info->nspc;
341
144
  const m_bool ret = emit_exp_dot(emit, &dot->d.exp_dot);
342
144
  free_exp(emit->gwion->mp, dot);
343
144
  return ret;
344
}
345
346
167
ANN static m_bool emit_symbol_builtin(const Emitter emit, const Symbol *data) {
347
167
  const Value v = prim_self(data)->value;
348
167
  if(GET_FLAG(v, union)) {
349
7
    const m_uint size = v->type->size;
350
7
    const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), dotstatic);
351
7
    instr->m_val = (m_uint)v->d.ptr;
352
  } else {
353
160
    const m_uint size = v->type->size;
354
160
    const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), regpushimm);
355

160
    if(!exp_getvar(prim_exp(data)) && size == SZ_INT) {
356
166
      if(isa(v->type, emit->gwion->type[et_object]) > 0)
357
34
        instr->m_val = (m_uint)v->d.ptr;
358
49
      else if(v->d.ptr)
359
34
        instr->m_val = *(m_uint*)v->d.ptr;
360
    } else {
361
      assert(v->d.ptr); // instr->m_val = v->d.ptr;
362
77
      memcpy(&instr->m_val, v->d.ptr, v->type->size);
363
    }
364
160
    instr->m_val2 = size;
365
  }
366
167
  return GW_OK;
367
}
368
369
1421
ANN static m_bool _emit_symbol(const Emitter emit, const Symbol *data) {
370
1421
  const Value v = prim_self(data)->value;
371
1421
  if(is_class(emit->gwion, v->type)) {
372
8
    regpushi(emit, (m_uint)actual_type(emit->gwion, v->type));
373
8
    return GW_OK;
374
  }
375
1413
  if(v->from->owner_class)
376
144
    return emit_symbol_owned(emit, data);
377

1269
  if(GET_FLAG(v, builtin) || GET_FLAG(v, union) || GET_FLAG(v, enum))
378
167
    return emit_symbol_builtin(emit, data);
379
1102
  const m_uint size = v->type->size;
380
1102
  const Instr instr = emit_kind(emit, size, exp_getvar(prim_exp(data)), !GET_FLAG(v, global) ? regpushmem : regpushbase);
381
1102
  instr->m_val  = v->from->offset;
382
1102
  return GW_OK;
383
}
384
385
1421
ANN static m_bool emit_symbol(const Emitter emit, const Exp_Primary* prim) {
386
1421
  return _emit_symbol(emit, &prim->d.var);
387
}
388
389
852
ANN static VM_Code finalyze(const Emitter emit, const f_instr exec) {
390
852
  emit_add_instr(emit, exec);
391
852
  const VM_Code code = emit->info->emit_code(emit);
392
852
  free_code(emit->gwion->mp, emit->code);
393
852
  emit->code = (Code*)vector_pop(&emit->stack);
394
852
  return code;
395
}
396
397
12
ANN static m_bool emit_prim_array(const Emitter emit, const Array_Sub *data) {
398
12
  Exp e = (*data)->exp;
399
12
  CHECK_BB(emit_exp(emit, e))
400
12
  m_uint count = 0;
401
39
  do ++count;
402
39
  while((e = e->next));
403
12
  const Type type = (*data)->type;
404
12
  regseti(emit, count);
405
12
  const Instr instr = emit_add_instr(emit, ArrayInit);
406
12
  instr->m_val = (m_uint)type;
407
12
  instr->m_val2 = type->array_depth == 1 ? array_base(type)->size : SZ_INT;
408
12
  emit_add_instr(emit, GcAdd);
409
12
  emit_notpure(emit);
410
12
  return GW_OK;
411
}
412
413
ANN static inline m_bool emit_exp_pop_next(const Emitter emit, Exp e);
414
415
9
ANN static m_bool emit_range(const Emitter emit, Range *range) {
416
9
  if(range->start)
417
8
    CHECK_BB(emit_exp_pop_next(emit, range->start))
418
  else
419
1
    regpushi(emit, 0);
420
9
  if(range->end)
421
7
    CHECK_BB(emit_exp_pop_next(emit, range->end))
422
  else
423
2
    regpushi(emit, -1);
424
9
  return GW_OK;
425
}
426
427
2
ANN static m_bool emit_prim_range(const Emitter emit, Range **data) {
428
2
  Range *range = *data;
429
2
  CHECK_BB(emit_range(emit, range))
430
2
  const Exp e = range->start ?: range->end;
431
2
  const Symbol sym = insert_symbol("@range");
432
6
  struct Op_Import opi = { .op=sym, .rhs=e->info->type,
433
4
    .pos=e->pos, .data=(uintptr_t)prim_exp(data), .op_type=op_exp };
434
2
  CHECK_OB(op_emit(emit, &opi))
435
2
  emit_add_instr(emit, GcAdd);
436
2
  return GW_OK;
437
}
438
439
25
ANN m_bool emit_array_access(const Emitter emit, struct ArrayAccessInfo *const info) {
440
25
  if(GET_FLAG(info->array.type, typedef)) {
441
    info->array.type = info->array.type->e->parent;
442
    return emit_array_access(emit, info);
443
  }
444
  // look mum no pos
445
50
  struct Op_Import opi = { .op=insert_symbol("@array"), .lhs=info->array.exp->info->type, .rhs=info->array.type,
446
25
    .data=(uintptr_t)info, .op_type=op_array };
447
25
  return op_emit(emit, &opi) != (Instr)GW_ERROR ? GW_OK : GW_ERROR;
448
}
449
450
25
ANN static m_bool emit_exp_array(const Emitter emit, const Exp_Array* array) {
451
25
  CHECK_BB(emit_exp(emit, array->base))
452
25
  const Exp e = exp_self(array);
453
25
  struct ArrayAccessInfo info = { *array->array, e->info->type, exp_getvar(e) };
454
25
  return emit_array_access(emit, &info);
455
}
456
457
7
ANN static m_bool emit_exp_slice(const Emitter emit, const Exp_Slice* range) {
458
7
  CHECK_BB(emit_exp(emit, range->base))
459
7
  CHECK_BB(emit_range(emit, range->range))
460
7
  const Symbol sym = insert_symbol("@slice");
461
7
  const Exp e = range->range->start ?: range->range->end;
462
21
  struct Op_Import opi = { .op=sym, .lhs=e->info->type, .rhs=range->base->info->type,
463
14
    .pos=e->pos, .data=(uintptr_t)exp_self(range), .op_type=op_exp };
464
7
  CHECK_OB(op_emit(emit, &opi))
465
7
  return GW_OK;
466
}
467
468
1799
ANN static m_bool emit_prim_id(const Emitter emit, const Symbol *data) {
469
1799
  struct SpecialId_ * spid = specialid_get(emit->gwion, *data);
470
1799
  if(spid)
471
378
    return specialid_instr(emit, spid, prim_self(data)) ? GW_OK : GW_ERROR;
472
1421
  return emit_symbol(emit, prim_self(data));
473
}
474
475
570
ANN static m_bool emit_prim_num(const Emitter emit, const m_uint *num) {
476
570
  regpushi(emit, *num);
477
570
  return GW_OK;
478
}
479
480
74
ANN static m_bool emit_prim_float(const Emitter emit, const m_float *fnum) {
481
74
  const Instr instr = emit_add_instr(emit, RegPushImm2);
482
74
  instr->f = *fnum;
483
74
  return GW_OK;
484
}
485
486
15
ANN static m_bool emit_prim_char(const Emitter emit, const m_str *str) {
487
15
  const char c = str2char(emit, *str, prim_pos(str));
488
15
  regpushi(emit, c);
489
15
  return GW_OK;
490
}
491
492
565
ANN static Instr emit_addref(const Emitter emit, const m_bool emit_var) {
493
565
  const f_instr exec = !emit_var ? RegAddRef : RegAddRefAddr;
494
565
  const Instr instr = emit_add_instr(emit, exec);
495
565
  instr->m_val = -SZ_INT;
496
565
  return instr;
497
}
498
499
310
ANN static m_bool emit_prim_str(const Emitter emit, const m_str *str) {
500
310
  char c[strlen(*str) + 1];
501
310
  if(strlen(*str)) {
502
304
    strcpy(c, *str);
503
304
    CHECK_BB(escape_str(emit, c, prim_pos(str)));
504
6
  } else c[0] = '\0';
505
308
  const Value v = prim_self(str)->value;
506
308
  const Symbol sym = insert_symbol(c);
507
308
  if(!v->d.ptr)
508
246
    v->d.ptr = (m_uint*)new_string2(emit->gwion, NULL, s_name(sym));
509
308
  regpushi(emit, (m_uint)v->d.ptr);
510
308
  emit_addref(emit, 0);
511
308
  return GW_OK;
512
}
513
514
#define emit_prim_nil     (void*)dummy_func
515
516
24
ANN static m_bool emit_prim_typeof(const Emitter emit, const Exp *exp) {
517
24
  const Exp e = *exp;
518
24
  if(!e->info->type->array_depth)
519
23
    regpushi(emit, (m_uint)(actual_type(emit->gwion, e->info->type)));
520
  else
521
1
    regpushi(emit, (m_uint)e->info->type);
522
24
  return GW_OK;
523
}
524
525
24
ANN static void interp_multi(const Emitter emit, const Exp e) {
526
24
  Var_Decl_List list = e->d.exp_decl.list;
527
24
  const int emit_var = exp_getvar(e);
528
24
  m_uint offset = 0;
529
48
  while((list = list->next))
530
    offset += !emit_var ? list->self->value->type->size : SZ_INT;
531
24
  if(offset)
532
    regpop(emit, offset);
533
24
}
534
535
1115
ANN static inline void interp_size(const Emitter emit, const Type t) {
536
1115
  const Instr instr = regseti(emit, t->size);
537
1115
  instr->m_val2 = SZ_INT;
538
1115
}
539
540
856
ANN static m_bool emit_interp(const Emitter emit, const Exp exp) {
541
856
  regpushi(emit, 0);
542
856
  Exp e = exp, next = NULL;
543
  do {
544
1117
    next = e->next;
545
1117
    e->next = NULL;
546
1117
    if(emit_exp(emit, e) < 0) {
547
2
      e->next = next;
548
2
      return GW_ERROR;
549
    }
550
1115
    if(e->exp_type == ae_exp_decl) // why only objects?
551
24
      interp_multi(emit, e);
552
1115
    regseti(emit, (m_uint)e->info->type);
553
1115
    interp_size(emit, e->info->type);
554
1115
    const m_bool isobj = isa(e->info->type, emit->gwion->type[et_object]) > 0;
555

1115
    if(isobj && !GET_FLAG(e->info->type, force))
556
491
      emit_add_instr(emit, GackType);
557
1115
    const Instr instr = emit_add_instr(emit, Gack);
558
1115
    instr->m_val = emit_code_offset(emit);
559
1115
  } while((e = e->next = next));
560
854
  return GW_OK;
561
}
562
563
851
ANN static m_bool emit_prim_hack(const Emitter emit, const Exp *exp) {
564
851
  CHECK_BB(emit_interp(emit, *exp))
565

849
  if(!(emit->env->func && emit->env->func->def->base->xid == insert_symbol("@gack")))
566
847
    emit_add_instr(emit, GackEnd);
567
  else {
568
2
    const Instr instr = emit_add_instr(emit, Reg2Mem);
569
2
    instr->m_val = SZ_INT;
570
2
    instr->m_val2 = -SZ_INT;
571
  }
572
849
  return GW_OK;
573
}
574
575
5
ANN static m_bool emit_prim_interp(const Emitter emit, const Exp *exp) {
576
5
  const Exp e = *exp;
577
5
  CHECK_BB(emit_interp(emit, e))
578
5
  const Instr instr = emit_add_instr(emit, GackEnd);
579
5
  instr->m_val = 1;
580
5
  return GW_OK;
581
}
582
583
DECL_PRIM_FUNC(emit, m_bool , Emitter);
584
3669
ANN static m_bool emit_prim(const Emitter emit, Exp_Primary *const prim) {
585
3669
  return emit_prim_func[prim->prim_type](emit, &prim->d);
586
}
587
588
21
ANN static m_bool emit_dot_static_data(const Emitter emit, const Value v, const uint emit_var) {
589
21
  const m_uint size = v->type->size;
590
21
  const Instr instr = emit_kind(emit, size, emit_var, dotstatic);
591
21
  instr->m_val = (m_uint)(v->from->owner->info->class_data + v->from->offset);
592
21
  instr->m_val2 = size;
593
21
  return GW_OK;
594
}
595
596
5
ANN static m_bool decl_static(const Emitter emit, const Var_Decl var_decl, const uint is_ref) {
597
5
  const Value v = var_decl->value;
598
5
  Code* code = emit->code;
599
5
  emit->code = (Code*)vector_back(&emit->stack);
600
5
  CHECK_BB(emit_instantiate_object(emit, v->type, var_decl->array, is_ref))
601
5
  CHECK_BB(emit_dot_static_data(emit, v, 1))
602
5
  emit_add_instr(emit, Assign);
603
5
  (void)emit_addref(emit, 0);
604
5
  regpop(emit, SZ_INT);
605
5
  emit->code = code;
606
5
  return GW_OK;
607
}
608
609
1090
ANN static inline int struct_ctor(const Value v) {
610

1090
  return GET_FLAG(v->type, struct) && v->type->nspc->pre_ctor;
611
}
612
613
12
ANN static void decl_expand(const Emitter emit, const Type t) {
614
12
  struct_expand(emit, t);
615
12
  regpush(emit, t->size - SZ_INT);
616
12
}
617
618
12
ANN static void emit_struct_decl_finish(const Emitter emit, const Type t, const uint emit_addr) {
619
12
  emit->code->frame->curr_offset += t->size + SZ_INT;
620
12
  emit_ext_ctor(emit, t);
621
12
  if(!emit_addr)
622
12
    decl_expand(emit, t);
623
12
  emit->code->frame->curr_offset -= t->size + SZ_INT;
624
12
}
625
626
16
ANN static m_bool emit_exp_decl_static(const Emitter emit, const Var_Decl var_decl, const uint is_ref, const uint emit_addr) {
627
16
  const Value v = var_decl->value;
628

16
  if(isa(v->type, emit->gwion->type[et_object]) > 0 && !is_ref)
629
5
    CHECK_BB(decl_static(emit, var_decl, 0))
630

16
  CHECK_BB(emit_dot_static_data(emit, v, !struct_ctor(v) ? emit_addr : 1))
631
16
  if(struct_ctor(v) /* && !GET_FLAG(decl->td, ref) */)
632
1
    emit_struct_decl_finish(emit, v->type, emit_addr);
633
16
  return GW_OK;
634
}
635
636
26
ANN static Instr emit_struct_decl(const Emitter emit, const Value v, const m_bool emit_addr) {
637
26
  emit_add_instr(emit, RegPushMem);
638
26
  const Instr instr = emit_kind(emit, v->type->size, emit_addr, structmember);
639
26
  if(!emit_addr)
640
15
    regpush(emit, v->type->size - SZ_INT);
641
26
  return instr;
642
}
643
644
625
ANN static m_bool emit_exp_decl_non_static(const Emitter emit, const Exp_Decl *decl, const Var_Decl var_decl,
645
  const uint is_ref, const uint emit_var) {
646
625
  const Value v = var_decl->value;
647
625
  const Type type = v->type;
648
625
  const Array_Sub array = var_decl->array;
649

625
  const m_bool is_array = (array && array->exp) /*|| GET_FLAG(decl->td, force)*/;
650
625
  const m_bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
651

625
  const uint emit_addr = (!is_obj || (is_ref && !is_array)) ? emit_var : 1;
652


625
  if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref))
653
202
    CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
654
625
  f_instr *exec = (f_instr*)allocmember;
655
625
  if(!GET_FLAG(v, member)) {
656
499
    v->from->offset = emit_local(emit, type);
657
499
    exec = (f_instr*)(allocword);
658
499
    if(GET_FLAG(v, ref)) { // ref or emit_var ?
659
55
      const Instr clean = emit_add_instr(emit, MemSetImm);
660
55
      clean->m_val = v->from->offset;
661
    }
662
  }
663

1384
  const Instr instr = !(SAFE_FLAG(emit->env->class_def, struct) && !emit->env->scope->depth) ?
664

1224
    emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, exec) : emit_struct_decl(emit, v, !struct_ctor(v) ? emit_addr : 1);
665
625
  instr->m_val = v->from->offset;
666


827
  if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref)) {
667
202
    if(!emit_var)
668
202
      emit_add_instr(emit, Assign);
669
    else {
670
      regpop(emit, SZ_INT);
671
      const Instr instr = emit_add_instr(emit, Reg2Reg);
672
      instr->m_val = -SZ_INT;
673
    }
674
202
    const size_t missing_depth = type->array_depth - (array ? array->depth : 0);
675

202
    if(missing_depth && !GET_FLAG(decl->td, force)) {
676
2
      const Instr push = emit_add_instr(emit, Reg2Reg);
677
2
      push->m_val = -(missing_depth) * SZ_INT;
678
    }
679
423
  } else if(struct_ctor(v) /* && !GET_FLAG(decl->td, ref) */)
680
10
    emit_struct_decl_finish(emit, v->type, emit_addr);
681
625
  return GW_OK;
682
}
683
684
6
ANN static m_bool emit_exp_decl_global(const Emitter emit, const Exp_Decl *decl, const Var_Decl var_decl,
685
  const uint is_ref, const uint emit_var) {
686
6
  const Value v = var_decl->value;
687
6
  const Type type = v->type;
688
6
  const Array_Sub array = var_decl->array;
689

6
  const m_bool is_array = array && array->exp;
690
6
  const m_bool is_obj = isa(type, emit->gwion->type[et_object]) > 0;
691

6
  const uint emit_addr = (!is_obj || (is_ref && !is_array)) ? emit_var : 1;
692


6
  if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref))
693
2
    CHECK_BB(emit_instantiate_object(emit, type, array, is_ref))
694
6
  const Instr instr = emit_kind(emit, v->type->size, !struct_ctor(v) ? emit_addr : 1, dotstatic);
695
6
  v->d.ptr = mp_calloc2(emit->gwion->mp, v->type->size);
696
6
  SET_FLAG(v, union);
697
6
  instr->m_val = (m_uint)v->d.ptr;
698
6
  instr->m_val2 = v->type->size;
699


8
  if(is_obj && (is_array || !is_ref) && !GET_FLAG(v, ref)) {
700
2
    const Instr assign = emit_add_instr(emit, Assign);
701
2
    const size_t missing_depth = type->array_depth - (array ? array->depth : 0);
702

2
    if(missing_depth && !GET_FLAG(decl->td, force)) {
703
      const Instr push = emit_add_instr(emit, Reg2Reg);
704
      push->m_val = -(missing_depth) * SZ_INT;
705
    }
706
2
    assign->m_val = emit_var;
707
2
    (void)emit_addref(emit, emit_var);
708
4
  } else if(struct_ctor(v) /* && !GET_FLAG(decl->td, ref) */)
709
1
    emit_struct_decl_finish(emit, v->type, emit_addr);
710
6
  return GW_OK;
711
}
712
713
ANN static m_bool emit_class_def(const Emitter, const Class_Def);
714
ANN static m_bool emit_cdef(const Emitter, const Class_Def);
715
716
31
ANN static inline m_bool ensure_emit(const Emitter emit, const Type t) {
717
62
  struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
718
31
    .scope=emit->env->scope->depth, .flag=ae_flag_emit };
719
31
  return envset_run(&es, t);
720
}
721
722
640
ANN static m_bool emit_decl(const Emitter emit, const Exp_Decl* decl) {
723
640
  const m_bool global = GET_FLAG(decl->td, global);
724
640
  const uint var = exp_getvar(exp_self(decl));
725

640
  const uint ref = GET_FLAG(decl->td, ref) || type_ref(decl->type);
726
640
  Var_Decl_List list = decl->list;
727
  do {
728
647
    const uint r = GET_FLAG(list->self->value, ref) + ref;
729
647
    if(GET_FLAG(decl->td, static))
730
16
      CHECK_BB(emit_exp_decl_static(emit, list->self, r, var))
731
631
    else if(!global)
732
625
      CHECK_BB(emit_exp_decl_non_static(emit, decl, list->self, r, var))
733
    else
734
6
      CHECK_BB(emit_exp_decl_global(emit, decl, list->self, r, var))
735
647
  } while((list = list->next));
736
640
  return GW_OK;
737
}
738
739
640
ANN /*static */m_bool emit_exp_decl(const Emitter emit, const Exp_Decl* decl) {
740
640
  const Type t = get_type(decl->type);
741

640
  if(!GET_FLAG(t, emit) && t->e->def)
742
24
    CHECK_BB(ensure_emit(emit, t))
743
640
  const m_bool global = GET_FLAG(decl->td, global);
744
640
  const m_uint scope = !global ? emit->env->scope->depth : emit_push_global(emit);
745
640
  const m_bool ret = emit_decl(emit, decl);
746
640
  if(global)
747
6
    emit_pop(emit, scope);
748
640
  return ret;
749
}
750
751
24
ANN static m_uint vararg_size(const Exp_Call* exp_call, const Vector kinds) {
752
24
  Exp e = exp_call->args;
753
24
  Arg_List l = exp_call->m_func->def->base->args;
754
24
  m_uint size = 0;
755
102
  while(e) {
756
54
    if(!l) {
757
45
      size += e->info->type->size;
758
45
      vector_add(kinds, (vtype)e->info->type); // ->size
759
    } else
760
9
      l = l->next;
761
54
    e = e->next;
762
  }
763
24
  return size;
764
}
765
766
24
ANN static void emit_func_arg_vararg(const Emitter emit, const Exp_Call* exp_call) {
767
24
  const Instr instr = emit_add_instr(emit, VarargIni);
768
24
  const Vector kinds = new_vector(emit->gwion->mp);
769
24
  if((instr->m_val = vararg_size(exp_call, kinds)))
770
18
    instr->m_val2 = (m_uint)kinds;
771
  else
772
6
    free_vector(emit->gwion->mp, kinds);
773
24
}
774
775
ANN static inline m_uint exp_size(Exp e);
776
277
ANN static inline m_uint exp_totalsize(Exp e) {
777
277
  m_uint size = 0;
778
383
  do size += exp_size(e);
779
383
  while((e = e->next));
780
277
  return size;
781
}
782
ANN static /*inline */void emit_exp_addref1(const Emitter emit, Exp, const m_int size);
783
ANN static /*inline */void emit_exp_addref(const Emitter emit, Exp, const m_int size);
784
785
459
ANN static m_bool emit_func_args(const Emitter emit, const Exp_Call* exp_call) {
786
459
  if(exp_call->args) {
787
234
    CHECK_BB(emit_exp(emit, exp_call->args))
788
234
    emit_exp_addref(emit, exp_call->args, -exp_totalsize(exp_call->args));
789
  }
790

459
  if(exp_call->m_func && GET_FLAG(exp_call->m_func->def, variadic))
791
24
    emit_func_arg_vararg(emit, exp_call);
792
459
  return GW_OK;
793
}
794
795
458
ANN static m_bool prepare_call(const Emitter emit, const Exp_Call* exp_call) {
796
458
  CHECK_BB(emit_func_args(emit, exp_call))
797
458
  return emit_exp(emit, exp_call->func);
798
}
799
800
431
ANN static m_bool emit_exp_call(const Emitter emit, const Exp_Call* exp_call) {
801
431
  CHECK_BB(prepare_call(emit, exp_call))
802
431
  if(exp_call->m_func)
803
431
    CHECK_OB(emit_exp_call1(emit, exp_call->m_func))
804
  else {
805
    struct Op_Import opi = { .op=insert_symbol("@ctor"), .rhs=exp_call->func->info->type->e->d.base_type,
806
      .data=(uintptr_t)exp_call, .pos=exp_self(exp_call)->pos, .op_type=op_exp };
807
    CHECK_OB(op_emit(emit, &opi))
808
  }
809
431
  const Exp e = exp_self(exp_call);
810
431
  if(exp_getvar(e)) {
811
2
    regpop(emit, exp_self(exp_call)->info->type->size - SZ_INT);
812
2
    const Instr instr = emit_add_instr(emit, Reg2RegAddr);
813
2
    instr->m_val = -SZ_INT;
814
2
    instr->m_val2 = -SZ_INT;
815

429
  } else if(!exp_call->m_func && GET_FLAG(e->info->type, struct))
816
    regpop(emit, SZ_INT);
817
431
  return GW_OK;
818
}
819
820
477
ANN static m_uint get_decl_size(Var_Decl_List a, uint emit_addr) {
821
477
  m_uint size = 0;
822
  do //if(GET_FLAG(a->self->value, used))
823
484
    size += !emit_addr ? a->self->value->type->size : SZ_INT;
824
484
  while((a = a->next));
825
477
  return size;
826
}
827
828
1994
ANN static m_uint pop_exp_size(Exp e) {
829
1994
  const uint emit_addr = exp_getvar(e);
830
1994
  m_uint size = 0;
831
  do { // account for emit_var ?
832
3988
    size += (e->exp_type == ae_exp_decl ?
833
1994
        get_decl_size(e->d.exp_decl.list, emit_addr) : e->info->type->size);
834
1994
  } while((e = e->next));
835
1994
  return size;
836
}
837
838
1994
ANN static inline void pop_exp(const Emitter emit, Exp e) {
839
1994
  const m_uint size = pop_exp_size(e);
840
1994
  if(size)
841
1802
   regpop(emit, size);
842
1994
}
843
844
1226
ANN static inline m_bool emit_exp_pop_next(const Emitter emit, Exp e) {
845
1226
  CHECK_BB(emit_exp(emit, e))
846
1226
  if(e->exp_type == ae_exp_decl) {
847
123
    Var_Decl_List list = e->d.exp_decl.list->next;
848
246
    while(list) {
849
      regpop(emit, !exp_getvar(e) ? list->self->value->type->size : SZ_INT);
850
      list = list->next;
851
    }
852
  }
853
1226
  if(e->next)
854
1
    pop_exp(emit, e->next);
855
1226
  return GW_OK;
856
}
857
858
1258
ANN static inline m_bool op_emit_bool(const Emitter emit, const struct Op_Import* opi) {
859
1258
  DECL_OB(const Instr, instr, = op_emit(emit, opi))
860
1258
  return GW_OK;
861
}
862
863
497
ANN static m_bool emit_exp_binary(const Emitter emit, const Exp_Binary* bin) {
864
497
  const Exp lhs = bin->lhs;
865
497
  const Exp rhs = bin->rhs;
866
1491
  struct Op_Import opi = { .op=bin->op, .lhs=lhs->info->type, .rhs=rhs->info->type,
867
994
    .pos=exp_self(bin)->pos, .data=(uintptr_t)bin, .op_type=op_binary };
868
497
  CHECK_BB(emit_exp_pop_next(emit, lhs))
869
497
  CHECK_BB(emit_exp_pop_next(emit, rhs))
870
497
  const m_int size = exp_size(rhs);
871
497
  emit_exp_addref1(emit, lhs, -exp_size(lhs) - size);
872
497
  emit_exp_addref1(emit, rhs, -size);
873
497
  return op_emit_bool(emit, &opi);
874
}
875
876
34
ANN static m_bool emit_exp_cast(const Emitter emit, const Exp_Cast* cast) {
877
  // no pos ?
878
68
  struct Op_Import opi = { .op=insert_symbol("$"), .lhs=cast->exp->info->type, .rhs=exp_self(cast)->info->type,
879
34
    .data=(uintptr_t)cast, .op_type=op_cast};
880
34
  CHECK_BB(emit_exp(emit, cast->exp))
881
34
  (void)op_emit(emit, &opi);
882
34
  return GW_OK;
883
}
884
885
35
ANN static m_bool emit_exp_post(const Emitter emit, const Exp_Postfix* post) {
886
  // no pos ?
887
70
  struct Op_Import opi = { .op=post->op, .lhs=post->exp->info->type,
888
35
    .data=(uintptr_t)post, .op_type=op_postfix };
889
35
  CHECK_BB(emit_exp(emit, post->exp))
890
35
  emit_exp_addref(emit, post->exp, -exp_totalsize(post->exp));
891
35
  return op_emit_bool(emit, &opi);
892
}
893
894
20
ANN static inline m_bool traverse_emit_func_def(const Emitter emit, const Func_Def fdef) {
895
20
  if(!fdef->base->ret_type)
896
20
    CHECK_BB(traverse_func_def(emit->env, fdef))
897
18
  return emit_func_def(emit, fdef);
898
}
899
900
20
ANN m_bool traverse_dot_tmpl(const Emitter emit, const struct dottmpl_ *dt) {
901
20
  const m_uint scope = emit->env->scope->depth;
902
20
  struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
903
    .scope=scope, .flag=ae_flag_emit };
904
20
  CHECK_BB(envset_push(&es, dt->owner_class, dt->owner))
905
20
  (void)emit_push(emit, dt->owner_class, dt->owner);
906
20
  const m_bool ret = traverse_emit_func_def(emit, dt->def);
907
20
  if(es.run)
908
4
    envset_pop(&es, dt->owner_class);
909
20
  emit_pop(emit, scope);
910
20
  return ret;
911
}
912
913
191
static inline m_bool push_func_code(const Emitter emit, const Func f) {
914
191
  if(!vector_size(&emit->code->instr))
915
10
    return GW_OK;
916
181
  const Instr instr = (Instr)vector_back(&emit->code->instr);
917
181
  if(instr->opcode == eDotTmplVal) {
918
45
    size_t len = strlen(f->name);
919
45
    size_t sz = len - strlen(f->value_ref->from->owner_class->name);
920
45
    char c[sz + 1];
921
45
    memcpy(c, f->name, sz);
922
45
    c[sz] = '\0';
923
45
    struct dottmpl_ *dt = mp_calloc(emit->gwion->mp, dottmpl);
924
45
    dt->name = s_name(insert_symbol(c));
925
45
    dt->vt_index = f->def->base->tmpl->base;
926
45
    dt->tl = cpy_type_list(emit->gwion->mp, f->def->base->tmpl->call);
927
45
    dt->base = f->def;
928
45
    instr->opcode = eOP_MAX;
929
45
    instr->m_val = (m_uint)dt;
930
45
    instr->m_val2 = strlen(c);
931
45
    instr->execute = DotTmpl;
932
45
    return GW_OK;
933
  }
934
136
  instr->opcode = eRegPushImm;
935
136
  instr->m_val = (m_uint)f->code;
936
136
  return GW_OK;
937
}
938
939
39
ANN static m_bool emit_template_code(const Emitter emit, const Func f) {
940
39
  const Value v = f->value_ref;
941
39
  const size_t scope = emit->env->scope->depth;
942
39
  struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
943
    .scope=scope, .flag=ae_flag_emit };
944
39
  CHECK_BB(envset_push(&es, v->from->owner_class, v->from->owner))
945
39
  (void)emit_push(emit, v->from->owner_class, v->from->owner);
946
39
  const m_bool ret = emit_func_def(emit, f->def);
947
39
  if(es.run)
948
18
    envset_pop(&es, v->from->owner_class);
949
39
  emit_pop(emit, scope);
950
39
  return ret > 0 ? push_func_code(emit, f) : GW_ERROR;
951
}
952
953
18
ANN static void tmpl_prelude(const Emitter emit, const Func f) {
954
18
  struct dottmpl_ *dt = (struct dottmpl_*)mp_calloc(emit->gwion->mp, dottmpl);
955
18
  size_t len = strlen(f->name);
956
18
  size_t slen = strlen(f->value_ref->from->owner->name);
957
  assert(len > slen);
958
18
  size_t sz = len - slen;
959
18
  char c[sz + 1];
960
18
  memcpy(c, f->name, sz);
961
18
  c[sz] = '\0';
962
18
  dt->tl = cpy_type_list(emit->gwion->mp, f->def->base->tmpl->call);
963
18
  dt->name = s_name(insert_symbol(c));
964
18
  dt->vt_index = f->def->base->tmpl->base;
965
18
  dt->base = f->def;
966
18
  dt->owner = f->value_ref->from->owner;
967
18
  dt->owner_class = f->value_ref->from->owner_class;
968
18
  const Instr gtmpl = emit_add_instr(emit, GTmpl);
969
18
  gtmpl->m_val = (m_uint)dt;
970
18
  gtmpl->m_val2 = strlen(c);
971
18
}
972
973
472
ANN static Instr get_prelude(const Emitter emit, const Func f) {
974
472
  const Type t = actual_type(emit->gwion, f->value_ref->type);
975
472
  if(is_fptr(emit->gwion, t)) {
976
64
    emit_except(emit, t);
977
64
    if(f->def->base->tmpl)
978
18
      tmpl_prelude(emit, f);
979
  }
980
472
  const Instr instr = emit_add_instr(emit, SetCode);
981
472
  instr->m_val2 = 1;
982
472
  return instr;
983
}
984
985
248
ANN static void emit_args(const Emitter emit, const Func f) {
986
248
  const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0;
987
248
  if((f->def->stack_depth - member) == SZ_INT) {
988
155
    const Instr instr = emit_add_instr(emit, Reg2Mem);
989
155
    instr->m_val = member;
990
  } else {
991
93
    const Instr instr = emit_add_instr(emit, Reg2Mem4);
992
93
    instr->m_val = member;
993
93
    instr->m_val2 = f->def->stack_depth - member;
994
  }
995
248
}
996
997
typedef struct {
998
  const Emitter  emit;
999
  const Func_Def fdef;
1000
  struct Vector_   branch;
1001
  const m_uint   offset;
1002
  m_uint         arg_offset;
1003
} MemoizeEmitter;
1004
1005
2
ANN static Instr me_push(const MemoizeEmitter *me, const m_uint sz) {
1006
2
  const Instr instr = emit_kind(me->emit, sz, 0, regpushmem);
1007
2
  instr->m_val  = me->arg_offset;
1008
2
  return instr;
1009
}
1010
1011
1
static m_bool me_cmp(MemoizeEmitter *me, const Arg_List arg) {
1012
1
  const Emitter emit = me->emit;
1013
1
  const Symbol sym = insert_symbol("==");
1014
1
  struct ExpInfo_ info = { .nspc=me->fdef->base->func->value_ref->from->owner };
1015
1
  struct Exp_ exp = { .info=&info };
1016
3
  struct Op_Import opi = { .op=sym, .lhs=arg->type, .rhs=arg->type,
1017
2
    .pos=me->fdef->pos, .data=(uintptr_t)&exp.d, .op_type=op_binary };
1018
1
  CHECK_BB(op_emit_bool(emit, &opi))
1019
1
  const Instr instr = emit_add_instr(emit, BranchEqInt);
1020
1
  vector_add(&me->branch, (vtype)instr);
1021
1
  return GW_OK;
1022
}
1023
1024
1
ANN static m_bool me_arg(MemoizeEmitter *me) {
1025
1
  Arg_List arg = me->fdef->base->args;
1026
  do {
1027
1
    const m_uint sz = arg->type->size;
1028
1
    (void)me_push(me, sz);
1029
1
    const Instr instr = me_push(me, sz);
1030
1
    instr->m_val  += me->offset + SZ_INT *2;
1031
1
    CHECK_BB(me_cmp(me, arg))
1032
1
    me->arg_offset += arg->type->size;
1033
1
  } while((arg = arg->next));
1034
1
  return GW_OK;
1035
}
1036
1037
472
ANN static Instr emit_call(const Emitter emit, const Func f) {
1038
472
  const Instr prelude = get_prelude(emit, f);
1039
472
  prelude->m_val = f->def->stack_depth;
1040
472
  const m_uint member = GET_FLAG(f, member) ? SZ_INT : 0;
1041
472
  if(member) {
1042
259
    const Instr instr = emit_add_instr(emit, Reg2Mem);
1043
259
    instr->m_val2 = f->def->stack_depth - SZ_INT;
1044
259
    ++prelude->m_val2;
1045
  }
1046
472
  if(f->def->stack_depth - member) {
1047
247
    emit_args(emit, f);
1048
247
    ++prelude->m_val2;
1049
  }
1050
472
  return emit_add_instr(emit, Overflow);
1051
}
1052
1053
472
ANN Instr emit_exp_call1(const Emitter emit, const Func f) {
1054

472
  if(!f->code || (GET_FLAG(f, ref) && !GET_FLAG(f, builtin))) {
1055

244
    if(GET_FLAG(f, template) && !is_fptr(emit->gwion, f->value_ref->type)) {
1056
88
      if(emit->env->func != f)
1057
39
        CHECK_BO(emit_template_code(emit, f))
1058
      else { // recursive function. (maybe should be used only for global funcs)
1059
10
        const Instr back = (Instr) vector_size(&emit->code->instr) ?
1060
5
            (Instr)vector_back(&emit->code->instr) : emit_add_instr(emit, RegPushImm);
1061
5
        back->opcode = eOP_MAX;
1062
5
        back->execute = SetRecurs;
1063
5
        back->m_val = 0;
1064
      }
1065


78
    } else if(emit->env->func != f && !f->value_ref->from->owner_class && !f->code && !is_fptr(emit->gwion, f->value_ref->type)) {
1066
1
      if(GET_FLAG(f->def, op)) {
1067
        const Instr back = (Instr)vector_back(&emit->code->instr);
1068
        back->m_val = (m_uint)f;
1069
      } else {
1070
// ensure env?
1071
1
        CHECK_BO(emit_func_def(emit, f->def))
1072
1
        const Instr instr = emit_add_instr(emit, RegSetImm);
1073
1
        instr->m_val = (m_uint)f->code;
1074
1
        instr->m_val2 = -SZ_INT;
1075
      }
1076
    }
1077

695
  } else if((f->value_ref->from->owner_class && GET_FLAG(f->value_ref->from->owner_class, struct)) ||
1078

597
        !f->value_ref->from->owner_class || (GET_FLAG(f, template) &&
1079
27
        !is_fptr(emit->gwion, f->value_ref->type)))
1080
152
    push_func_code(emit, f);
1081
198
  else if(vector_size(&emit->code->instr)) {
1082
187
    const Instr back = (Instr)vector_back(&emit->code->instr);
1083

187
    if((f_instr)(m_uint)back->opcode == DotFunc || (f_instr)(m_uint)back->opcode == DotStaticFunc)
1084
169
      back->m_val = f->vt_index;
1085
  }
1086

717
  if(vector_size(&emit->code->instr) && GET_FLAG(f, member) &&
1087
273
        is_fptr(emit->gwion, f->value_ref->type)) {
1088
28
    const Instr back = (Instr)vector_back(&emit->code->instr);
1089
28
    m_bit exec = back->opcode;
1090
28
    m_uint val = back->m_val;
1091
28
    m_uint val2 = back->m_val2;
1092
28
    back->opcode = eReg2Reg;
1093
28
    back->m_val2 = -SZ_INT;
1094
28
    regpush(emit, SZ_INT);
1095
28
    const Instr instr = emit_add_instr(emit, (f_instr)(m_uint)exec);
1096
28
    instr->m_val = val;
1097
28
    instr->m_val2 = val2;
1098

444
  } else if(f != emit->env->func && !f->code && !is_fptr(emit->gwion, f->value_ref->type)){
1099
    // not yet emitted static func
1100
2
    if(f->value_ref->from->owner_class) {
1101
4
      const Instr instr = vector_size(&emit->code->instr) ?
1102
2
        (Instr)vector_back(&emit->code->instr) : emit_add_instr(emit, SetFunc);
1103
2
      instr->opcode = eOP_MAX;
1104
2
      instr->execute = SetFunc;
1105
2
      instr->m_val = (m_uint)f;
1106
    } else {
1107
      const Instr instr = emit_add_instr(emit, SetFunc);
1108
      instr->m_val = (m_uint)f;
1109
    }
1110
  }
1111
472
  const m_uint offset = emit_code_offset(emit);
1112
472
  regseti(emit, offset);
1113
472
  const Instr instr = emit_call(emit, f);
1114
472
  instr->m_val = f->def->base->ret_type->size;
1115
472
  instr->m_val2 = offset;
1116
472
  return instr;
1117
}
1118
1119
24
ANN static void emit_exp_spork_finish(const Emitter emit, const m_uint depth) {
1120
24
  regpop(emit, depth);
1121
24
  const Instr spork = emit_add_instr(emit, SporkFunc);
1122
24
  spork->m_val = depth + SZ_INT;
1123
24
  spork->m_val2 = -SZ_INT;
1124
24
}
1125
1126
263
static inline void stack_alloc(const Emitter emit) { // maybe vararg could use t_vararg instead
1127
263
  emit_local(emit, emit->gwion->type[et_int]); // hiding the fact it is an object
1128
263
  emit->code->stack_depth += SZ_INT;
1129
263
}
1130
1131
251
static inline void stack_alloc_this(const Emitter emit) {
1132
251
  SET_FLAG(emit->code, member);
1133
251
  stack_alloc(emit);
1134
251
}
1135
1136
372
static m_bool scoped_stmt(const Emitter emit, const Stmt stmt, const m_bool pop) {
1137
372
  ++emit->env->scope->depth;
1138
372
  emit_push_scope(emit);
1139
372
  const Instr gc = emit_add_instr(emit, NoOp);
1140
372
  const m_bool ret = emit_stmt(emit, stmt, pop);
1141
372
  if(ret > 0) {
1142
372
    const m_bool pure = !vector_back(&emit->info->pure);
1143
372
    if(!pure) {
1144
8
      gc->opcode = eGcIni;
1145
8
      emit_add_instr(emit, GcEnd);
1146
    }
1147
  }
1148
372
  emit_pop_scope(emit);
1149
372
  --emit->env->scope->depth;
1150
372
  return ret;
1151
}
1152
1153
#define SPORK_FUNC_PREFIX "spork~func:%i"
1154
#define FORK_FUNC_PREFIX "fork~func:%i"
1155
#define SPORK_CODE_PREFIX "spork~code:%i"
1156
#define FORK_CODE_PREFIX  "fork~code:%i"
1157
1158
53
static void push_spork_code(const Emitter emit, const m_str prefix, const loc_t pos) {
1159
53
  char c[strlen(SPORK_FUNC_PREFIX) + num_digit(pos->first.line) + 1];
1160
53
  sprintf(c, prefix, pos->first.line);
1161
53
  emit_push_code(emit, c);
1162
53
}
1163
1164
27
ANN static m_bool call_spork_func(const Emitter emit, const Exp_Call *exp) {
1165
27
  if(GET_FLAG(exp->m_func, member))
1166
14
    SET_FLAG(emit->code, member);
1167
27
  return emit_exp_call1(emit, exp->m_func) ? GW_OK : GW_ERROR;
1168
}
1169
1170
struct Sporker {
1171
  const Stmt code;
1172
  const Exp  exp;
1173
  VM_Code vm_code;
1174
  const Type type;
1175
  const m_bool emit_var;
1176
  const m_bool is_spork;
1177
};
1178
1179
26
ANN static m_bool spork_prepare_code(const Emitter emit, const struct Sporker *sp) {
1180
26
  emit_add_instr(emit, RegPushImm);
1181
26
  push_spork_code(emit, sp->is_spork ? SPORK_CODE_PREFIX : FORK_CODE_PREFIX, sp->code->pos);
1182

26
  if(SAFE_FLAG(emit->env->func, member))
1183
2
    stack_alloc_this(emit);
1184
26
  return scoped_stmt(emit, sp->code, 0);
1185
}
1186
1187
27
ANN static m_bool spork_prepare_func(const Emitter emit, const struct Sporker *sp) {
1188
27
  push_spork_code(emit, sp->is_spork ? SPORK_FUNC_PREFIX : FORK_CODE_PREFIX, sp->exp->pos);
1189
27
  return call_spork_func(emit, &sp->exp->d.exp_call);
1190
}
1191
1192
53
ANN static VM_Code spork_prepare(const Emitter emit, const struct Sporker *sp) {
1193
53
  if(!sp->code)
1194
27
    CHECK_BO(prepare_call(emit, &sp->exp->d.exp_call))
1195

53
  if((sp->code ? spork_prepare_code : spork_prepare_func)(emit, sp) > 0)
1196
53
    return finalyze(emit, EOC);
1197
  emit_pop_code(emit);
1198
  return NULL;
1199
}
1200
1201
26
ANN void spork_code(const Emitter emit, const struct Sporker *sp) {
1202
26
  const Instr args = emit_add_instr(emit, SporkExp);
1203
26
  args->m_val = emit->code->stack_depth;
1204
26
  const Instr instr = emit_add_instr(emit, SporkEnd);
1205
26
  instr->m_val = sp->emit_var;
1206
26
}
1207
1208
27
ANN void spork_func(const Emitter emit, const struct Sporker *sp) {
1209
27
  const Func f = sp->exp->d.exp_call.m_func;
1210

30
  if(GET_FLAG(f, member) && is_fptr(emit->gwion, f->value_ref->type)) {
1211
3
    regpush(emit, SZ_INT*2);
1212
    // (re-)emit owner
1213
3
    if(sp->exp->d.exp_call.func->exp_type == ae_exp_dot)
1214
1
      emit_exp(emit, sp->exp->d.exp_call.func->d.exp_dot.base);
1215
    else {
1216
      assert(sp->exp->d.exp_call.func->exp_type == ae_exp_primary);
1217
2
      emit_add_instr(emit, RegPushMem);
1218
    }
1219
3
    regpop(emit, SZ_INT*3);
1220
3
    const m_uint depth = f->def->stack_depth;
1221
3
    regpop(emit, depth -SZ_INT);
1222
3
    const Instr spork = emit_add_instr(emit, SporkMemberFptr);
1223
3
    spork->m_val = depth;
1224
  } else
1225
24
    emit_exp_spork_finish(emit, f->def->stack_depth);
1226
27
  (void)emit_add_instr(emit, SporkEnd);
1227
27
}
1228
1229
53
ANN static Instr spork_ini(const Emitter emit, const struct Sporker *sp) {
1230
53
  if(sp->is_spork) {
1231
45
    const Instr instr = emit_add_instr(emit, SporkIni);
1232
45
    instr->m_val = (m_uint)sp->vm_code;
1233
45
    instr->m_val2 = sp->is_spork;
1234
45
    return instr;
1235
  }
1236
8
  regpushi(emit, (m_uint)sp->type);
1237
8
  const Func f = !sp->code ? sp->exp->d.exp_call.m_func : NULL;
1238
8
  const Instr instr = emit_add_instr(emit, ForkIni);
1239
8
  instr->m_val = (m_uint)sp->vm_code;
1240
8
  instr->m_val2 = f ? sp->type->size : 0;
1241
8
  return instr;
1242
}
1243
1244
53
ANN Instr emit_exp_spork(const Emitter emit, const Exp_Unary* unary) {
1245
318
  struct Sporker sporker = {
1246
53
    .exp=unary->exp,
1247
53
    .code=unary->code,
1248
53
    .type=exp_self(unary)->info->type,
1249
53
    .is_spork=(unary->op == insert_symbol("spork")),
1250
53
    .emit_var=exp_getvar(exp_self(unary))
1251
  };
1252
53
  CHECK_OO((sporker.vm_code = spork_prepare(emit, &sporker)))
1253
53
  const Instr ini = spork_ini(emit, &sporker);
1254
53
  (unary->code ? spork_code : spork_func)(emit, &sporker);
1255
53
  return ini;
1256
}
1257
1258
119
ANN static m_bool emit_exp_unary(const Emitter emit, const Exp_Unary* unary) {
1259
119
  const Type t = exp_self(unary)->info->type;
1260
119
  const Type base = get_type(actual_type(emit->gwion, t));
1261

119
  if(base->e->def && !GET_FLAG(base, emit))
1262
1
    CHECK_BB(ensure_emit(emit, base))
1263
  // no pos ?
1264
119
  struct Op_Import opi = { .op=unary->op, .data=(uintptr_t)unary, .op_type=op_unary };
1265

119
  if(unary->op != insert_symbol("spork") && unary->op != insert_symbol("fork") && unary->exp) {
1266
47
    CHECK_BB(emit_exp_pop_next(emit, unary->exp))
1267
47
    emit_exp_addref1(emit, unary->exp, -exp_size(unary->exp));
1268
47
    opi.rhs = unary->exp->info->type;
1269
  }
1270
119
  return op_emit_bool(emit, &opi);
1271
}
1272
1273
40
ANN static m_bool emit_implicit_cast(const Emitter emit,
1274
    const restrict Exp  from, const restrict Type to) {
1275
40
  const struct Implicit imp = { from, to, from->pos };
1276
  // no pos
1277
80
  struct Op_Import opi = { .op=insert_symbol("@implicit"), .lhs=from->info->type, .rhs=to,
1278
40
    .data=(m_uint)&imp, .op_type=op_implicit };
1279
40
  return op_emit_bool(emit, &opi);
1280
}
1281
1282
87
ANN static Instr _flow(const Emitter emit, const Exp e, const m_bool b) {
1283
87
  CHECK_BO(emit_exp_pop_next(emit, e))
1284
87
  emit_exp_addref1(emit, e, -exp_size(e));
1285
348
  struct Op_Import opi = { .op=insert_symbol(b ? "@conditionnal" : "@unconditionnal"),
1286
261
                           .rhs=e->info->type, .pos=e->pos, .data=(uintptr_t)e, .op_type=op_exp };
1287
87
  const Instr instr = op_emit(emit, &opi);
1288
  assert(instr != (Instr)GW_OK);
1289
87
  return instr;
1290
}
1291
#define emit_flow(emit,b) _flow(emit, b, 1)
1292
1293
7
ANN static m_bool emit_exp_if(const Emitter emit, const Exp_If* exp_if) {
1294
7
  DECL_OB(const Instr, op, = emit_flow(emit, exp_if->cond))
1295

7
  CHECK_BB(emit_exp_pop_next(emit, exp_if->if_exp ?: exp_if->cond))
1296
7
  const Instr op2 = emit_add_instr(emit, Goto);
1297
7
  op->m_val = emit_code_size(emit);
1298
7
  const m_bool ret = emit_exp_pop_next(emit, exp_if->else_exp);
1299
7
  op2->m_val = emit_code_size(emit);
1300
7
  return ret;
1301
}
1302
1303
13
ANN static m_bool emit_lambda(const Emitter emit, const Exp_Lambda * lambda) {
1304
13
  CHECK_BB(emit_func_def(emit, lambda->def))
1305

13
  if(GET_FLAG(lambda->def, member) && !exp_getvar(exp_self(lambda)))
1306
7
    emit_add_instr(emit, RegPushMem);
1307
13
  regpushi(emit, (m_uint)lambda->def->base->func->code);
1308
13
  return GW_OK;
1309
}
1310
1311
14
ANN static m_bool emit_exp_lambda(const Emitter emit, const Exp_Lambda * lambda) {
1312
14
  if(!lambda->def->base->func) {
1313
1
    regpushi(emit, SZ_INT);
1314
1
    return GW_OK;
1315
  }
1316
26
  struct EnvSet es = { .env=emit->env, .data=emit, .func=(_exp_func)emit_cdef,
1317
13
    .scope=emit->env->scope->depth, .flag=ae_flag_emit };
1318
13
  CHECK_BB(envset_push(&es, lambda->owner, lambda->def->base->func->value_ref->from->owner))
1319
13
  const m_bool ret = emit_lambda(emit, lambda);
1320
13
  if(es.run)
1321
5
    envset_pop(&es, lambda->owner);
1322
13
  return ret;
1323
}
1324
1325
DECL_EXP_FUNC(emit, m_bool, Emitter)
1326
1327
1328
1
ANN static void struct_addref(const Emitter emit, const Type type,
1329
    const m_int size, const m_bool offset, const m_bool emit_var) {
1330
1
  if(!type->e->tuple)
1331
1
    return;
1332
  for(m_uint i = 0; i < vector_size(&type->e->tuple->types); ++i) {
1333
    const Type t = (Type)vector_at(&type->e->tuple->types, i);
1334
    if(isa(t, emit->gwion->type[et_object]) > 0) {
1335
      const Instr instr = emit_addref(emit, emit_var);
1336
      instr->m_val = size;
1337
      instr->m_val2 = vector_at(&type->e->tuple->offset, i);
1338
    } else if(GET_FLAG(t, struct))
1339
      struct_addref(emit, t, size, offset + vector_at(&type->e->tuple->offset, i), emit_var);
1340
  }
1341
}
1342
1343
1901
ANN static inline m_uint exp_size(const Exp e) {
1344
1901
  if(exp_getvar(e))
1345
354
    return SZ_INT;
1346
1547
  const Type type = e->info->cast_to ?: e->info->type;
1347
1547
  return type->size;
1348
}
1349
1350
1518
ANN2(1) static void emit_exp_addref1(const Emitter emit, /* const */Exp exp, m_int size) {
1351

1778
  if(isa(exp->info->type, emit->gwion->type[et_object]) > 0 &&
1352
506
    (exp->info->cast_to ? isa(exp->info->cast_to, emit->gwion->type[et_object]) > 0 : 1)) {
1353
246
    const Instr instr = emit_addref(emit, exp_getvar(exp));
1354
246
    instr->m_val = size;
1355
1272
  } else if(GET_FLAG(exp->info->type, struct)) // check cast_to ?
1356
1
    struct_addref(emit, exp->info->type, size, 0, exp_getvar(exp));
1357
1518
}
1358
1359
383
ANN2(1) static void emit_exp_addref(const Emitter emit, /* const */Exp exp, m_int size) {
1360
  do {
1361
383
    emit_exp_addref1(emit, exp, size);
1362
383
    size += exp_size(exp);
1363
383
  } while((exp = exp->next));
1364
277
}
1365
1366
5720
ANN2(1) /*static */m_bool emit_exp(const Emitter emit, /* const */Exp e) {
1367
5720
  Exp exp = e;
1368
  do {
1369
5887
    CHECK_BB(emit_exp_func[exp->exp_type](emit, &exp->d))
1370
5883
    if(exp_getnonnull(exp))
1371
91
      emit_except(emit, exp->info->type);
1372
5883
    if(exp->info->cast_to)
1373
40
      CHECK_BB(emit_implicit_cast(emit, exp, exp->info->cast_to))
1374
5883
  } while((exp = exp->next));
1375
5716
  return GW_OK;
1376
}
1377
1378
40
ANN static m_bool emit_if(const Emitter emit, const Stmt_If stmt) {
1379
40
  DECL_OB(const Instr, op, = emit_flow(emit, stmt->cond))
1380
40
  CHECK_BB(scoped_stmt(emit, stmt->if_body, 1))
1381
40
  const Instr op2 = emit_add_instr(emit, Goto);
1382
40
  op->m_val = emit_code_size(emit);
1383
40
  if(stmt->else_body)
1384
12
    CHECK_BB(scoped_stmt(emit, stmt->else_body, 1))
1385
40
  op2->m_val = emit_code_size(emit);
1386
40
  return GW_OK;
1387
}
1388
1389
40
ANN static m_bool emit_stmt_if(const Emitter emit, const Stmt_If stmt) {
1390
40
  emit_push_scope(emit);
1391
40
  const m_bool ret = emit_if(emit, stmt);
1392
40
  emit_pop_scope(emit);
1393
40
  return ret;
1394
}
1395
1396
395
ANN static m_bool emit_stmt_code(const Emitter emit, const Stmt_Code stmt) {
1397
395
  ++emit->env->scope->depth;
1398
395
  const m_bool ret = stmt->stmt_list ? emit_stmt_list(emit, stmt->stmt_list) : 1;
1399
395
  --emit->env->scope->depth;
1400
395
  return ret;
1401
}
1402
1403
1
ANN static m_bool optimize_taill_call(const Emitter emit, const Exp_Call* e) {
1404
1
  if(e->args) {
1405
1
    emit_func_args(emit, e);
1406
1
    regpop(emit, e->m_func->def->stack_depth);
1407
1
    emit_args(emit, e->m_func);
1408
  }
1409
1
  emit_add_instr(emit, Goto);
1410
1
  return GW_OK;
1411
}
1412
1413
58
ANN static m_bool emit_stmt_return(const Emitter emit, const Stmt_Exp stmt) {
1414
58
  if(stmt->val) {
1415

56
    if(stmt->val->exp_type == ae_exp_call && emit->env->func == stmt->val->d.exp_call.m_func)
1416
1
      return optimize_taill_call(emit, &stmt->val->d.exp_call);
1417
55
    CHECK_BB(emit_exp_pop_next(emit, stmt->val))
1418
  }
1419
57
  vector_add(&emit->code->stack_return, (vtype)emit_add_instr(emit, Goto));
1420
57
  return GW_OK;
1421
}
1422
1423
9
ANN static inline m_bool emit_stmt_continue(const Emitter emit, const Stmt stmt NUSED) {
1424
9
  vector_add(&emit->code->stack_cont, (vtype)emit_add_instr(emit, Goto));
1425
9
  return GW_OK;
1426
}
1427
1428
8
ANN static inline m_bool emit_stmt_break(const Emitter emit, const Stmt stmt NUSED) {
1429
8
  vector_add(&emit->code->stack_break, (vtype)emit_add_instr(emit, Goto));
1430
8
  return GW_OK;
1431
}
1432
1433
53
ANN static inline void emit_push_stack(const Emitter emit) {
1434
53
  emit_push_scope(emit);
1435
53
  vector_add(&emit->code->stack_cont, (vtype)NULL);
1436
53
  vector_add(&emit->code->stack_break, (vtype)NULL);
1437
53
}
1438
1439
106
ANN static void pop_vector(Vector v, const  m_uint pc) {
1440
  Instr instr;
1441
229
  while((instr = (Instr)vector_pop(v)))
1442
17
    instr->m_val = pc;
1443
106
}
1444
1445
53
ANN static void emit_pop_stack(const Emitter emit, const m_uint index) {
1446
53
  pop_vector(&emit->code->stack_cont, index);
1447
53
  pop_vector(&emit->code->stack_break, emit_code_size(emit));
1448
53
  emit_pop_scope(emit);
1449
53
}
1450
1451
26
ANN static m_bool _emit_stmt_flow(const Emitter emit, const Stmt_Flow stmt, const m_uint index) {
1452
26
  Instr op = NULL;
1453
26
  if(!stmt->is_do)
1454
12
    op = _flow(emit, stmt->cond, stmt_self(stmt)->stmt_type == ae_stmt_while);
1455
26
  CHECK_BB(scoped_stmt(emit, stmt->body, 1))
1456
26
  if(stmt->is_do) {
1457
14
    CHECK_OB((op = _flow(emit, stmt->cond, stmt_self(stmt)->stmt_type != ae_stmt_while)))
1458
14
    op->m_val = index;
1459
  } else {
1460
12
    const Instr goto_ = emit_add_instr(emit, Goto);
1461
12
    goto_->m_val = index;
1462
12
    op->m_val = emit_code_size(emit);
1463
  }
1464
26
  return GW_OK;
1465
}
1466
1467
26
ANN static m_bool emit_stmt_flow(const Emitter emit, const Stmt_Flow stmt) {
1468
26
  const m_uint index = emit_code_size(emit);
1469
26
  emit_push_stack(emit);
1470
26
  const m_bool ret = _emit_stmt_flow(emit, stmt, index);
1471
26
  emit_pop_stack(emit, index);
1472
26
  return ret;
1473
}
1474
1475
18
ANN static m_bool variadic_state(const Emitter emit, const Stmt_VarLoop stmt, const m_uint status) {
1476
18
  regpushi(emit, status);
1477
18
  CHECK_BB(emit_exp(emit, stmt->exp))
1478
18
  const Instr member = emit_add_instr(emit, DotMember4);
1479
18
  member->m_val = SZ_INT;
1480
18
  emit_add_instr(emit, int_r_assign);
1481
18
  regpop(emit, SZ_INT);
1482
18
  return GW_OK;
1483
}
1484
1485
9
ANN static m_bool emit_stmt_varloop(const Emitter emit, const Stmt_VarLoop stmt) {
1486
9
  CHECK_BB(variadic_state(emit, stmt, 1))
1487
9
  CHECK_BB(emit_exp(emit, stmt->exp))
1488
9
  const Instr check = emit_add_instr(emit, VarargCheck);
1489
9
  const Instr member = emit_add_instr(emit, DotMember4);
1490
9
  member->m_val = SZ_INT*2;
1491
9
  const Instr instr = emit_add_instr(emit, BranchEqInt);
1492
9
  const m_uint pc = emit_code_size(emit);
1493
9
  emit_stmt(emit, stmt->body, 1);
1494
9
  CHECK_BB(emit_exp(emit, stmt->exp))
1495
9
  emit_vararg_end(emit, pc);
1496
9
  CHECK_BB(variadic_state(emit, stmt, 0))
1497
9
  check->m_val = instr->m_val = emit_code_size(emit);
1498
9
  return GW_OK;
1499
}
1500
1501
10
ANN static m_bool _emit_stmt_for(const Emitter emit, const Stmt_For stmt, m_uint *action_index) {
1502
10
  CHECK_BB(emit_stmt(emit, stmt->c1, 1))
1503
10
  const m_uint index = emit_code_size(emit);
1504
10
  DECL_OB(const Instr, op, = emit_flow(emit, stmt->c2->d.stmt_exp.val))
1505
10
  CHECK_BB(scoped_stmt(emit, stmt->body, 1))
1506
10
  *action_index = emit_code_size(emit);
1507
10
  if(stmt->c3) {
1508
9
    CHECK_BB(emit_exp(emit, stmt->c3))
1509
9
    pop_exp(emit, stmt->c3);
1510
  }
1511
10
  const Instr _goto = emit_add_instr(emit, Goto);
1512
10
  _goto->m_val = index;
1513
10
  op->m_val = emit_code_size(emit);
1514
10
  return GW_OK;
1515
}
1516
1517
10
ANN static m_bool emit_stmt_for(const Emitter emit, const Stmt_For stmt) {
1518
10
  emit_push_stack(emit);
1519
10
  m_uint action_index = 0;
1520
10
  const m_bool ret = _emit_stmt_for(emit, stmt, &action_index);
1521
10
  emit_pop_stack(emit, action_index);
1522
10
  return ret;
1523
}
1524
1525
4
ANN static Instr emit_stmt_autoptr_init(const Emitter emit, const Type type) {
1526
4
  const Instr new_obj = emit_add_instr(emit, ObjectInstantiate);
1527
4
  new_obj->m_val2 = (m_uint)type;
1528
4
  (void)emit_addref(emit, 0);
1529
4
  regpop(emit, SZ_INT);
1530
4
  return emit_add_instr(emit, Reg2Mem);
1531
}
1532
1533
10
ANN static m_bool _emit_stmt_auto(const Emitter emit, const Stmt_Auto stmt, m_uint *end_pc) {
1534
10
  const Instr s1 = emit_add_instr(emit, MemSetImm);
1535
10
  Instr cpy = stmt->is_ptr ? emit_stmt_autoptr_init(emit, stmt->v->type) : NULL;
1536
10
  emit_local(emit, emit->gwion->type[et_int]);
1537
10
  const m_uint offset = emit_local(emit, emit->gwion->type[et_int]);
1538
10
  emit_local(emit, emit->gwion->type[et_int]);
1539
10
  stmt->v->from->offset = offset + SZ_INT;
1540
10
  const m_uint ini_pc  = emit_code_size(emit);
1541
10
  emit_except(emit, stmt->exp->info->type);
1542
10
  const Instr loop = emit_add_instr(emit, stmt->is_ptr ? AutoLoopPtr : AutoLoop);
1543
10
  const Instr end = emit_add_instr(emit, BranchEqInt);
1544
10
  const m_bool ret = scoped_stmt(emit, stmt->body, 1);
1545
10
  *end_pc = emit_code_size(emit);
1546
10
  if(stmt->is_ptr) {
1547
4
    loop->m_val2 = (m_uint)stmt->v->type;
1548
4
    cpy->m_val = stmt->v->from->offset;
1549
  }
1550
10
  const Instr tgt = emit_add_instr(emit, Goto);
1551
10
  end->m_val = emit_code_size(emit);
1552
10
  tgt->m_val = ini_pc;
1553
10
  s1->m_val = loop->m_val = offset;
1554
10
  return ret;
1555
}
1556
1557
10
ANN static m_bool emit_stmt_auto(const Emitter emit, const Stmt_Auto stmt) {
1558
10
  CHECK_BB(emit_exp(emit, stmt->exp))
1559
10
  emit_push_stack(emit);
1560
10
  m_uint end_pc = 0;
1561
10
  const m_bool ret = _emit_stmt_auto(emit, stmt, &end_pc);
1562
10
  emit_pop_stack(emit, end_pc);
1563
10
  regpop(emit, SZ_INT);
1564
10
  return ret;
1565
}
1566
1567
7
ANN static m_bool _emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt, m_uint *index) {
1568
7
  CHECK_BB(emit_exp_pop_next(emit, stmt->cond))
1569
7
  const m_uint offset = emit_local(emit, emit->gwion->type[et_int]);
1570
7
  const Instr tomem = emit_add_instr(emit, Reg2Mem);
1571
7
  tomem->m_val = offset;
1572
7
  tomem->m_val2 = -SZ_INT;
1573
7
  regpop(emit, SZ_INT);
1574
7
  *index = emit_code_size(emit);
1575
7
  const Instr cpy = emit_add_instr(emit, RegPushMem4);
1576
7
  cpy->m_val = offset;
1577
7
  emit_add_instr(emit, int_post_dec);
1578
7
  const Instr op = emit_add_instr(emit, BranchEqInt);
1579
7
  CHECK_BB(scoped_stmt(emit, stmt->body, 1))
1580
7
  const Instr _goto = emit_add_instr(emit, Goto);
1581
7
  _goto->m_val = *index;
1582
7
  op->m_val = emit_code_size(emit);
1583
7
  return GW_OK;
1584
}
1585
1586
7
ANN static m_bool emit_stmt_loop(const Emitter emit, const Stmt_Loop stmt) {
1587
7
  emit_push_stack(emit);
1588
7
  m_uint index = 0;
1589
7
  const m_bool ret = _emit_stmt_loop(emit, stmt, &index);
1590
7
  emit_pop_stack(emit, index);
1591
7
  return ret;
1592
}
1593
1594
8
ANN static m_bool emit_stmt_jump(const Emitter emit, const Stmt_Jump stmt) {
1595
8
  if(!stmt->is_label)
1596
3
    stmt->data.instr = emit_add_instr(emit, Goto);
1597
  else {
1598
    assert(stmt->data.v.ptr);
1599
5
    const m_uint size = vector_size(&stmt->data.v);
1600
5
    if(!size)
1601
//return GW_OK;
1602
1
      ERR_B(stmt_self(stmt)->pos, _("label '%s' defined but not used."), s_name(stmt->name))
1603
    LOOP_OPTIM
1604
11
    for(m_uint i = size + 1; --i;) {
1605
4
      const Stmt_Jump label = (Stmt_Jump)vector_at(&stmt->data.v, i - 1);
1606
4
      if(!label->data.instr)
1607
1
        ERR_B(stmt_self(label)->pos, _("you are trying to use a upper label."))
1608
3
      label->data.instr->m_val = emit_code_size(emit);
1609
    }
1610
  }
1611
6
  return GW_OK;
1612
}
1613
1614
14
ANN static m_bool emit_type_def(const Emitter emit, const Type_Def tdef) {
1615
14
  return tdef->type->e->def ? emit_class_def(emit, tdef->type->e->def) : GW_OK;
1616
}
1617
1618
5
ANN static m_bool emit_enum_def(const Emitter emit, const Enum_Def edef) {
1619
  LOOP_OPTIM
1620
18
  for(m_uint i = 0; i < vector_size(&edef->values); ++i) {
1621
13
    const Value v = (Value)vector_at(&edef->values, i);
1622
13
    if(!emit->env->class_def) {
1623
7
      ALLOC_PTR(emit->gwion->mp, addr, m_uint, i);
1624
7
      v->from->offset = emit_local(emit, emit->gwion->type[et_int]);
1625
7
      v->d.ptr = addr;
1626
    } else
1627
6
      *(m_bit*)(emit->env->class_def->nspc->info->class_data + v->from->offset) = i;
1628
  }
1629
5
  return GW_OK;
1630
}
1631
1632
34
ANN void emit_union_offset(Decl_List l, const m_uint o) {
1633
  do {
1634
34
    Var_Decl_List v = l->self->d.exp_decl.list;
1635
34
    do v->self->value->from->offset = o;
1636
34
    while((v = v->next));
1637
34
  } while((l = l->next));
1638
18
}
1639
1640
10
ANN static inline void union_allocdata(MemPool mp, const Union_Def udef) {
1641
10
  const Nspc nspc = (udef->xid ? udef->value->type : udef->type)->nspc;
1642
10
  nspc_allocdata(mp, nspc);
1643
10
  nspc->info->offset = udef->s;
1644
10
}
1645
1646
18
ANN static m_bool emit_union_def(const Emitter emit, const Union_Def udef) {
1647
18
  if(tmpl_base(udef->tmpl))
1648
3
    return GW_OK;
1649
15
  Decl_List l = udef->l;
1650
15
  m_uint scope = emit->env->scope->depth;
1651
15
  const m_bool global = GET_FLAG(udef, global);
1652
15
  if(udef->xid) {
1653
6
    union_allocdata(emit->gwion->mp, udef);
1654
12
    Type_Decl *type_decl = new_type_decl(emit->gwion->mp,
1655
6
        udef->xid, loc_cpy(emit->gwion->mp, udef->pos));
1656
6
    type_decl->flag = udef->flag;
1657
6
    const Var_Decl var_decl = new_var_decl(emit->gwion->mp, udef->xid, NULL, loc_cpy(emit->gwion->mp, udef->pos));
1658
6
    const Var_Decl_List var_decl_list = new_var_decl_list(emit->gwion->mp, var_decl, NULL);
1659
6
    const Exp exp = new_exp_decl(emit->gwion->mp, type_decl, var_decl_list);
1660
6
    exp->d.exp_decl.type = udef->value->type;
1661
6
    var_decl->value = udef->value;
1662
6
    const m_bool ret = emit_exp_decl(emit, &exp->d.exp_decl);
1663
6
    free_exp(emit->gwion->mp, exp);
1664
6
    CHECK_BB(ret)
1665
6
    if(global) {
1666
1
      const M_Object o = new_object(emit->gwion->mp, NULL, udef->value->type);
1667
1
      udef->value->d.ptr = (m_uint*)o;
1668
1
      SET_FLAG(udef->value, builtin);
1669
1
      UNSET_FLAG(udef->value, union);
1670
    }
1671
6
    scope = emit_push_type(emit, udef->value->type);
1672
9
  } else if(udef->type_xid) {
1673
4
    union_allocdata(emit->gwion->mp, udef);
1674
4
    scope = emit_push_type(emit, udef->type);
1675
5
  } else if(global) {
1676
    // TODO: use mpool allocation
1677
1
    void* ptr = (void*)xcalloc(1, udef->s);
1678
1
    l = udef->l;
1679
1
    udef->value->d.ptr = ptr;
1680
1
    SET_FLAG(udef->value, enum);
1681
1
    SET_FLAG(udef->value, dtor);
1682
    do {
1683
2
      Var_Decl_List list = l->self->d.exp_decl.list;
1684
2
      list->self->value->d.ptr = ptr;
1685
2
      SET_FLAG(list->self->value, union);
1686
2
    } while((l = l->next));
1687
1
    SET_FLAG(udef->l->self->d.exp_decl.list->self->value, enum);
1688
1
    SET_FLAG(udef->l->self->d.exp_decl.list->self->value, dtor);
1689
  }
1690
15
  if(udef->xid)
1691
6
    regpop(emit, SZ_INT);
1692
15
  emit_union_offset(udef->l, udef->o);
1693

15
  if(udef->xid || udef->type_xid || global)
1694
11
    emit_pop(emit, scope);
1695
15
  union_flag(udef, ae_flag_emit);
1696
15
  return GW_OK;
1697
}
1698
1699
2003
ANN static m_bool emit_stmt_exp(const Emitter emit, const struct Stmt_Exp_* exp) {
1700
2003
  return exp->val ? emit_exp(emit, exp->val) : GW_OK;
1701
}
1702
1703
7
ANN static m_bool emit_case_head(const Emitter emit, const Exp base,
1704
    const Exp e, const Symbol op, const Vector v) {
1705
7
  CHECK_BB(emit_exp(emit, base))
1706
7
  CHECK_BB(emit_exp_pop_next(emit, e))
1707
7
  const m_int size = -exp_size(e);
1708
7
  emit_exp_addref(emit, base, -exp_totalsize(base) - size);
1709
7
  emit_exp_addref1(emit, e, -size);
1710
7
  const Exp_Binary bin = { .lhs=base, .rhs=e, .op=op };
1711
7
  struct ExpInfo_ info = { .nspc=e->info->nspc };
1712
7
  struct Exp_ ebin = { .d={.exp_binary=bin}, .info=&info };
1713
21
  struct Op_Import opi = { .op=op, .lhs=base->info->type, .rhs=e->info->type,
1714
14
    .data=(uintptr_t)&ebin.d.exp_binary, .pos=e->pos, .op_type=op_binary };
1715
7
  CHECK_BB(op_emit_bool(emit, &opi))
1716
7
  const Instr instr = emit_add_instr(emit, BranchEqInt);
1717
7
  vector_add(v, (vtype)instr);
1718
7
  return GW_OK;
1719
}
1720
1721
10
ANN static m_bool emit_case_body(const Emitter emit, const struct Stmt_Match_* stmt) {
1722
10
  const Instr when = stmt->when ? emit_flow(emit, stmt->when) : NULL;
1723
10
  if(stmt->when)
1724
4
    CHECK_OB(when)
1725
10
  CHECK_BB(emit_stmt_list(emit, stmt->list))
1726
10
  const Instr instr = emit_add_instr(emit, Goto);
1727
10
  vector_add(&emit->env->scope->match->vec, (vtype)instr);
1728
10
  if(when)
1729
4
    when->m_val = emit_code_size(emit);
1730
10
  return GW_OK;
1731
}
1732
1733
1
ANN static m_bool case_value(const Emitter emit, const Exp base, const Exp e) {
1734
1
  const Value v = e->d.prim.value;
1735
1
  v->from->offset = emit_local(emit, base->info->type);
1736
1
  CHECK_BB(emit_exp(emit, base))
1737
1
  emit_exp_addref(emit, base, -exp_totalsize(base));
1738
1
  regpop(emit, base->info->type->size);
1739
1
  const Instr instr = emit_add_instr(emit, Reg2Mem4);
1740
1
  instr->m_val = v->from->offset;
1741
1
  instr->m_val2 = base->info->type->size;
1742
1
  return GW_OK;
1743
}
1744
1745
1746
#define CASE_PASS (Symbol)1
1747
10
ANN static Symbol case_op(const Emitter emit, const Exp base, const Exp e) {
1748
10
  if(e->exp_type == ae_exp_primary) {
1749
10
    if(e->d.prim.prim_type == ae_prim_id) {
1750
3
      if(e->d.prim.d.var == insert_symbol("_"))
1751
2
        return CASE_PASS;
1752
1
      if(!nspc_lookup_value1(emit->env->curr, e->d.prim.d.var)) {
1753
1
        CHECK_BO(case_value(emit, base, e))
1754
1
        return CASE_PASS;
1755
      }
1756
    }
1757
  }
1758
7
  return insert_symbol("==");
1759
}
1760
1761
10
ANN static m_bool _emit_stmt_match_case(const Emitter emit, const struct Stmt_Match_* stmt,
1762
    const Vector v) {
1763
10
  Exp e = stmt->cond;
1764
10
  const Map map = &emit->env->scope->match->map;
1765

20
  for(m_uint i = 0; i < map_size(map) && e; e = e->next, ++i) {
1766
10
    const Exp base = (Exp)VKEY(map, i);
1767
10
    const Symbol op = case_op(emit, base, e);
1768
10
    if(op != CASE_PASS)
1769
7
      CHECK_BB(emit_case_head(emit, base, e, op, v))
1770
  }
1771
10
  CHECK_BB(emit_case_body(emit, stmt))
1772
10
  return GW_OK;
1773
}
1774
1775
10
ANN static m_bool emit_stmt_match_case(const Emitter emit, const struct Stmt_Match_* stmt) {
1776
10
  emit_push_scope(emit);
1777
  struct Vector_ v;
1778
10
  vector_init(&v);
1779
10
  const m_bool ret = _emit_stmt_match_case(emit, stmt, &v);
1780
10
  emit_pop_scope(emit);
1781
17
  for(m_uint i = 0; i < vector_size(&v); ++i) {
1782
7
    const Instr instr = (Instr)vector_at(&v, i);
1783
7
    instr->m_val = emit_code_size(emit);
1784
  }
1785
10
  vector_release(&v);
1786
10
  return ret;
1787
}
1788
1789
6
ANN static inline void match_unvec(struct Match_ *const match , const m_uint pc) {
1790
6
  const Vector vec = &match->vec;
1791
16
  for(m_uint i = 0; i < vector_size(vec); ++i) {
1792
10
    const Instr instr = (Instr)VPTR(vec, i);
1793
10
    instr->m_val = pc;
1794
  }
1795
6
  vector_release(vec);
1796
6
}
1797
1798
10
ANN static m_bool emit_stmt_cases(const Emitter emit, Stmt_List list) {
1799
10
  do CHECK_BB(emit_stmt_match_case(emit, &list->stmt->d.stmt_match))
1800
10
  while((list = list->next));
1801
6
  return GW_OK;
1802
}
1803
1804
6
ANN static m_bool emit_match(const Emitter emit, const struct Stmt_Match_* stmt) {
1805
6
  if(stmt->where)
1806
2
    CHECK_BB(emit_stmt(emit, stmt->where, 1))
1807
6
  MATCH_INI(emit->env->scope)
1808
6
  vector_init(&m.vec);
1809
6
  const m_bool ret = emit_stmt_cases(emit, stmt->list);
1810
6
  match_unvec(&m, emit_code_size(emit));
1811
6
  MATCH_END(emit->env->scope)
1812
6
  return ret;
1813
}
1814
1815
6
ANN static m_bool emit_stmt_match(const Emitter emit, const struct Stmt_Match_* stmt) {
1816
6
  emit_push_scope(emit);
1817
6
  const m_bool ret = emit_match(emit, stmt);
1818
6
  emit_pop_scope(emit);
1819
6
  return ret;
1820
}
1821
1822
1
ANN static m_bool emit_stmt_pp(const Emitter emit, const struct Stmt_PP_* stmt) {
1823
1
  if(stmt->pp_type == ae_pp_pragma) {
1824
1
    if(!strncmp(stmt->data, "memoize", strlen("memoize")))
1825
1
      emit->info->memoize = strtol(stmt->data + 7, NULL, 10);
1826
  }
1827
1
  return GW_OK;
1828
}
1829
1830
#define emit_stmt_while emit_stmt_flow
1831
#define emit_stmt_until emit_stmt_flow
1832
DECL_STMT_FUNC(emit, m_bool , Emitter)
1833
1834
2590
ANN static m_bool emit_stmt(const Emitter emit, const Stmt stmt, const m_bool pop) {
1835
2590
  CHECK_BB(emit_stmt_func[stmt->stmt_type](emit, &stmt->d))
1836

2586
  if(pop && stmt->stmt_type == ae_stmt_exp && stmt->d.stmt_exp.val) {
1837
1984
    pop_exp(emit, stmt->d.stmt_exp.val);
1838
  }
1839
2586
  return GW_OK;
1840
}
1841
1842
2197
ANN static m_bool emit_stmt_list(const Emitter emit, Stmt_List l) {
1843
2197
  do CHECK_BB(emit_stmt(emit, l->stmt, 1))
1844
2193
  while((l = l->next));
1845
899
  return GW_OK;
1846
}
1847
1848
559
ANN static m_bool emit_exp_dot(const Emitter emit, const Exp_Dot* member) {
1849
2236
  struct Op_Import opi = { .op=insert_symbol("@dot"), .lhs=member->t_base,
1850
1677
    .rhs=exp_self(member)->info->type, .data=(uintptr_t)member, .pos=exp_self(member)->pos, .op_type=op_dot };
1851
559
  return op_emit_bool(emit, &opi);
1852
}
1853
1854
95
ANN static inline void emit_func_def_global(const Emitter emit, const Value value) {
1855
95
  const Instr set_mem = emit_add_instr(emit, MemSetImm);
1856
95
  set_mem->m_val = value->from->offset;
1857
95
  set_mem->m_val2 = (m_uint)value->d.func_ref->code;
1858
95
}
1859
1860
241
ANN static void emit_func_def_init(const Emitter emit, const Func func) {
1861
241
  const Type t = emit->env->class_def;
1862
241
  char c[(t ? strlen(t->name) + 1 : 0) + strlen(func->name) + 6];
1863

241
  sprintf(c, "%s%s%s(...)", t ? t->name : "", t ? "." : "", func->name);
1864
241
  emit_push_code(emit, c);
1865
241
}
1866
1867
187
ANN static void emit_func_def_args(const Emitter emit, Arg_List a) {
1868
  do {
1869
187
    const Type type = a->var_decl->value->type;
1870
187
    emit->code->stack_depth += type->size;
1871
187
    a->var_decl->value->from->offset = emit_local(emit, type);
1872
187
  } while((a = a->next));
1873
134
}
1874
1875
241
ANN static void emit_func_def_ensure(const Emitter emit, const Func_Def fdef) {
1876
241
  const m_uint size = fdef->base->ret_type->size;
1877
241
  if(size) {
1878
83
    const Instr instr = emit_kind(emit, size, 0, regpushimm);
1879
83
    instr->m_val2 = size;
1880
  }
1881
241
  vector_add(&emit->code->stack_return, (vtype)emit_add_instr(emit, Goto));
1882
241
}
1883
1884
241
ANN static void emit_func_def_return(const Emitter emit) {
1885
241
  const m_uint val = emit_code_size(emit);
1886
  LOOP_OPTIM
1887
780
  for(m_uint i = vector_size(&emit->code->stack_return) + 1; --i; ) {
1888
298
    const Instr instr = (Instr)vector_at(&emit->code->stack_return, i-1);
1889
298
    instr->m_val = val;
1890
  }
1891
241
  vector_clear(&emit->code->stack_return);
1892

241
  if(emit->info->memoize && GET_FLAG(emit->env->func, pure)) {
1893
1
    const Instr instr = emit_add_instr(emit, MemoizeStore);
1894
1
    instr->m_val = emit->env->func->def->stack_depth;
1895
  }
1896
241
}
1897
1898
11
ANN static VM_Code emit_internal(const Emitter emit, const Func f) {
1899
11
  if(f->def->base->xid == insert_symbol("@dtor")) {
1900
6
    emit->env->class_def->nspc->dtor = f->code = finalyze(emit, DTOR_EOC);
1901
6
    ADD_REF(f->code)
1902
6
    return f->code;
1903
5
  } else if(f->def->base->xid == insert_symbol("@gack")) {
1904
2
    regpop(emit, SZ_INT + f->value_ref->from->owner_class->size);
1905
2
    const Instr instr = emit_add_instr(emit, RegPushMem);
1906
2
    instr->m_val = SZ_INT;
1907
2
    f->code = finalyze(emit, FuncReturn);
1908
2
    return emit->env->class_def->e->gack = f->code;
1909
  }
1910
3
  return finalyze(emit, FuncReturn);
1911
}
1912
1913
241
ANN static VM_Code emit_func_def_code(const Emitter emit, const Func func) {
1914
241
  if(GET_FLAG(func->def, typedef))
1915
11
    return emit_internal(emit, func);
1916
  else
1917
230
    return finalyze(emit, FuncReturn);
1918
}
1919
1920
241
ANN static m_bool emit_func_def_body(const Emitter emit, const Func_Def fdef) {
1921
241
  if(fdef->base->args)
1922
134
    emit_func_def_args(emit, fdef->base->args);
1923
241
  if(GET_FLAG(fdef, variadic))
1924
12
    stack_alloc(emit);
1925
241
  if(fdef->d.code)
1926
241
    CHECK_BB(scoped_stmt(emit, fdef->d.code, 1))
1927
241
  emit_func_def_ensure(emit, fdef);
1928
241
  return GW_OK;
1929
}
1930
1931
1
ANN static Instr me_top(MemoizeEmitter *me) {
1932
1
  const Instr idx = emit_add_instr(me->emit, MemSetImm);
1933
1
  idx->m_val = me->offset;
1934
1
  const Instr pc = emit_add_instr(me->emit, MemSetImm);
1935
1
  pc->m_val = me->offset + SZ_INT;
1936
1
  return pc;
1937
}
1938
1939
1
ANN static void me_ini(MemoizeEmitter *me) {
1940
1
  const Instr ini = emit_add_instr(me->emit, MemoizeIni);
1941
1
  ini->m_val = me->offset;
1942
1
  ini->m_val2 = me->fdef->stack_depth + me->fdef->base->ret_type->size;
1943
1
}
1944
1945
1
ANN static void me_end(MemoizeEmitter *me, const m_uint pc) {
1946
2
  for(m_uint i = 0; i < vector_size(&me->branch); ++i)
1947
1
	  ((Instr)vector_at(&me->branch, i))->m_val = pc;
1948
1
}
1949
1950
1
ANN static void me_bottom(MemoizeEmitter *me, const m_uint pc) {
1951
1
  const Instr idx = emit_add_instr(me->emit, RegPushMem4);
1952
1
  idx->m_val = me->offset;
1953
1
  emit_add_instr(me->emit, int_pre_inc);
1954
1
  regpop(me->emit, SZ_INT);
1955
1
  const Instr loop = emit_add_instr(me->emit, Goto);
1956
1
  loop->m_val = pc;
1957
1
}
1958
1959
1
ANN static void me_ret(MemoizeEmitter *me) {
1960
1
  const Instr instr = emit_kind(me->emit, me->fdef->base->ret_type->size, 0, regpushmem);
1961
1
  instr->m_val = (me->offset + SZ_INT)*2;
1962
1
  emit_add_instr(me->emit, FuncReturn);
1963
1
}
1964
1965
1
ANN static m_bool me_run(MemoizeEmitter *me, const m_uint pc) {
1966
1
  me_ini(me);
1967
1
  if(me->fdef->base->args)
1968
1
    CHECK_BB(me_arg(me))
1969
1
  me_ret(me);
1970
1
  me_end(me, emit_code_size(me->emit));
1971
1
  me_bottom(me, pc);
1972
1
  return GW_OK;
1973
}
1974
1975
1
ANN static m_bool emit_memoize(const Emitter emit, const Func_Def fdef) {
1976
1
  MemoizeEmitter me = { .emit=emit, .fdef=fdef, .offset=fdef->stack_depth };
1977
1
  const Instr pc = me_top(&me);
1978
1
  const m_uint top = emit_code_size(emit);
1979
1
  vector_init(&me.branch);
1980
1
  const m_bool ret = me_run(&me, top);
1981
1
  vector_release(&me.branch);
1982
1
  pc->m_val2 = emit_code_size(emit);
1983
1
  return ret;
1984
}
1985
1986
241
ANN static m_bool emit_fdef(const Emitter emit, const Func_Def fdef) {
1987

241
  if(emit->info->memoize && GET_FLAG(fdef->base->func, pure))
1988
1
    CHECK_BB(emit_memoize(emit, fdef))
1989
241
  CHECK_BB(emit_func_def_body(emit, fdef))
1990
241
  emit_func_def_return(emit);
1991
241
  return GW_OK;
1992
}
1993
1994
482
static ANN int fdef_is_file_global(const Emitter emit, const Func_Def fdef) {
1995
948
  return isa(fdef->base->func->value_ref->type, emit->gwion->type[et_lambda]) < 0 &&
1996


918
    !emit->env->class_def && !GET_FLAG(fdef, global) && !fdef->base->tmpl &&
1997
192
    !emit->env->scope->depth;
1998
}
1999
2000
241
ANN static void emit_fdef_finish(const Emitter emit, const Func_Def fdef) {
2001
241
  const Func func = fdef->base->func;
2002
241
  func->code = emit_func_def_code(emit, func);
2003
241
  if(fdef_is_file_global(emit, fdef))
2004
95
    emit_func_def_global(emit, func->value_ref);
2005

241
  if(emit->info->memoize && GET_FLAG(func, pure))
2006
1
    func->code->memoize = memoize_ini(emit, func);
2007
241
}
2008
2009
286
ANN static m_bool emit_func_def(const Emitter emit, const Func_Def f) {
2010
286
  const Func func = f->base->func;
2011
286
  const Func_Def fdef = func->def;
2012
286
  const Func former = emit->env->func;
2013

286
  if(func->code || tmpl_base(fdef->base->tmpl))
2014
45
    return GW_OK;
2015

241
  if(SAFE_FLAG(emit->env->class_def, builtin) && GET_FLAG(emit->env->class_def, template))
2016
    return GW_OK;
2017
241
  if(fdef_is_file_global(emit, fdef))
2018
95
    func->value_ref->from->offset = emit_local(emit, emit->gwion->type[et_int]);
2019
241
  emit_func_def_init(emit, func);
2020
241
  if(GET_FLAG(func, member))
2021
99
    stack_alloc_this(emit);
2022
241
  emit->env->func = func;
2023
241
  emit_push_scope(emit);
2024
241
  if(!strcmp(s_name(fdef->base->xid), "@gack")) {
2025
2
    emit_local(emit, emit->gwion->type[et_int]);
2026
2
    const Instr instr = emit_add_instr(emit, MemSetImm);
2027
2
    instr->m_val = SZ_INT;
2028
  }
2029
241
  const m_bool ret = scanx_fdef(emit->env, emit, fdef, (_exp_func)emit_fdef);
2030
241
  emit_pop_scope(emit);
2031
241
  emit->env->func = former;
2032
241
  if(ret > 0)
2033
241
    emit_fdef_finish(emit, fdef);
2034
  else
2035
    emit_pop_code(emit);
2036
241
  return ret;
2037
}
2038
2039
#define emit_fptr_def dummy_func
2040
981
HANDLE_SECTION_FUNC(emit, m_bool, Emitter)
2041
2042
150
ANN Code* emit_class_code(const Emitter emit, const m_str name) {
2043
150
  const m_uint len = strlen(name) + 7;
2044
150
  char c[len];
2045
150
  snprintf(c, len, "class %s", name);
2046
150
  emit_push_code(emit, c);
2047
150
  stack_alloc_this(emit);
2048
150
  return emit->code;
2049
}
2050
2051
6
ANN static m_bool emit_parent(const Emitter emit, const Class_Def cdef) {
2052
6
  const Type parent = cdef->base.type->e->parent;
2053
6
  return !GET_FLAG(parent, emit) ? ensure_emit(emit, parent) : GW_OK;
2054
}
2055
2056
31
ANN static inline m_bool emit_cdef(const Emitter emit, const Class_Def cdef) {
2057
31
  return scanx_cdef(emit->env, emit, cdef,
2058
      (_exp_func)emit_class_def, (_exp_func)emit_union_def);
2059
}
2060
2061
150
ANN void emit_class_finish(const Emitter emit, const Nspc nspc) {
2062
150
  nspc->pre_ctor = finalyze(emit, FuncReturn);
2063
150
  SET_FLAG(nspc->pre_ctor, ctor);
2064
150
}
2065
2066
6
ANN static m_bool cdef_parent(const Emitter emit, const Class_Def cdef) {
2067

6
  if(cdef->base.tmpl && cdef->base.tmpl->list)
2068
4
    CHECK_BB(template_push_types(emit->env, cdef->base.tmpl))
2069
6
  const m_bool ret = emit_parent(emit, cdef);
2070

6
  if(cdef->base.tmpl && cdef->base.tmpl->list)
2071
4
    nspc_pop_type(emit->gwion->mp, emit->env->curr);
2072
6
  return ret;
2073
}
2074
2075
193
ANN static m_bool emit_class_def(const Emitter emit, const Class_Def cdef) {
2076
193
  if(tmpl_base(cdef->base.tmpl))
2077
19
    return GW_OK;
2078
174
  const Type t = cdef->base.type;
2079
174
  if(GET_FLAG(t, emit))
2080
    return GW_OK;
2081
174
  SET_FLAG(t, emit);
2082

174
  if(t->e->owner_class && !GET_FLAG(t->e->owner_class, emit))
2083
    CHECK_BB(ensure_emit(emit, t->e->owner_class))
2084

174
  if(cdef->base.ext && t->e->parent->e->def && !GET_FLAG(t->e->parent, emit))
2085
6
    CHECK_BB(cdef_parent(emit, cdef))
2086
174
  nspc_allocdata(emit->gwion->mp, t->nspc);
2087
174
  if(cdef->body) {
2088
150
    emit_class_code(emit, t->name);
2089
150
    if(scanx_body(emit->env, cdef, (_exp_func)emit_section, emit) > 0)
2090
150
      emit_class_finish(emit, t->nspc);
2091
    else {
2092
      free_code(emit->gwion->mp, emit->code);
2093
      emit_pop_code(emit);
2094
      return GW_ERROR;
2095
    }
2096
  }
2097
174
  return GW_OK;
2098
}
2099
2100
4
ANN static inline void emit_free_code(const Emitter emit, Code* code) {
2101
4
  if(vector_size(&code->instr))
2102
2
    free_code_instr(&code->instr, emit->gwion);
2103
4
  free_code(emit->gwion->mp, code);
2104
4
}
2105
2106
4
ANN static VM_Code emit_free_stack(const Emitter emit) {
2107
  LOOP_OPTIM
2108
8
  for(m_uint i = vector_size(&emit->stack) + 1; --i;)
2109
    emit_free_code(emit, (Code*)vector_at(&emit->stack, i - 1));
2110
4
  vector_clear(&emit->stack);
2111
4
  vector_clear(&emit->info->pure);
2112
4
  emit_free_code(emit, emit->code);
2113
4
  return NULL;
2114
}
2115
2116
699
ANN static inline m_bool emit_ast_inner(const Emitter emit, Ast ast) {
2117
699
  do CHECK_BB(emit_section(emit, ast->section))
2118
695
  while((ast = ast->next));
2119
408
  return GW_OK;
2120
}
2121
2122
412
ANN m_bool emit_ast(const Env env, Ast ast) {
2123
412
  const Emitter emit = env->gwion->emit;
2124
412
  emit->info->memoize = 0;
2125
412
  emit->code = new_code(emit, emit->env->name);
2126
412
  emit_push_scope(emit);
2127
412
  const m_bool ret = emit_ast_inner(emit, ast);
2128
412
  emit_pop_scope(emit);
2129
412
  if(ret > 0)
2130
408
    emit->info->code = finalyze(emit, emit->info->finalyzer);
2131
  else
2132
4
    emit_free_stack(emit);
2133
412
  return ret;
2134
}