-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcode.c
86 lines (72 loc) · 1.58 KB
/
code.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#include <stdlib.h>
#include "alloc.h"
#include "code.h"
#include "constant.h"
#include "gc.h"
#include "module.h"
#include "struct.h"
static void code_deinit(void *code_ptr)
{
struct cb_code *code = (struct cb_code *)code_ptr;
free(code->bytecode);
for (int i = 0; i < code->nconsts; i += 1)
cb_const_free(&code->const_pool[i]);
free(code->const_pool);
free(code->ic);
if (code->loc)
free(code->loc);
}
struct cb_code *cb_code_new(void)
{
return cb_malloc(sizeof(struct cb_code), code_deinit);
}
static void code_mark_fn(void *obj)
{
cb_code_mark((struct cb_code *) obj);
}
static void queue_mark(struct cb_code *code)
{
cb_gc_queue_mark((void *) code, code_mark_fn);
}
cb_gc_hold_key *cb_code_gc_hold(struct cb_code *code)
{
return cb_gc_hold((void *) code, code_mark_fn);
}
static void mark_const(struct cb_const c)
{
switch (c.type) {
case CB_CONST_MODULE:
queue_mark(cb_modspec_code(c.val.as_module));
break;
case CB_CONST_FUNCTION:
queue_mark(c.val.as_function->code);
break;
case CB_CONST_STRUCT_SPEC:
cb_struct_spec_mark(c.val.as_struct_spec);
break;
default:
break;
}
}
void cb_code_mark(struct cb_code *code)
{
cb_gc_mark(&code->gc_header);
for (unsigned i = 0; i < code->nconsts; i += 1)
mark_const(code->const_pool[i]);
}
void cb_code_lineno(const struct cb_code *code, size_t ip, unsigned *line,
unsigned *column)
{
*line = *column = 0;
size_t sum = 0;
/* FIXME: danger */
for (unsigned i = 0; sum < ip; i++) {
struct cb_loc *l = &code->loc[i];
sum += l->run;
if (sum >= ip) {
*line = l->line;
*column = l->column;
return;
}
}
}