forked from mruby/mruby
/
state.c
142 lines (122 loc) · 2.7 KB
/
state.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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/*
** state.c - mrb_state open/close functions
**
** See Copyright Notice in mruby.h
*/
#include "mruby.h"
#include "mruby/irep.h"
#include "mruby/variable.h"
#include <string.h>
void mrb_init_heap(mrb_state*);
void mrb_init_core(mrb_state*);
void mrb_init_ext(mrb_state*);
mrb_state*
mrb_open_allocf(mrb_allocf f, void *ud)
{
static const mrb_state mrb_state_zero = { 0 };
mrb_state *mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud);
if (mrb == NULL) return NULL;
*mrb = mrb_state_zero;
mrb->ud = ud;
mrb->allocf = f;
mrb->current_white_part = MRB_GC_WHITE_A;
mrb_init_heap(mrb);
mrb_init_core(mrb);
mrb_init_ext(mrb);
return mrb;
}
static void*
allocf(mrb_state *mrb, void *p, size_t size, void *ud)
{
if (size == 0) {
free(p);
return NULL;
}
else {
return realloc(p, size);
}
}
struct alloca_header {
struct alloca_header *next;
char buf[0];
};
void*
mrb_alloca(mrb_state *mrb, size_t size)
{
struct alloca_header *p;
p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size);
p->next = mrb->mems;
mrb->mems = p;
return (void*)p->buf;
}
static void
mrb_alloca_free(mrb_state *mrb)
{
struct alloca_header *p = mrb->mems;
struct alloca_header *tmp;
while (p) {
tmp = p;
p = p->next;
mrb_free(mrb, tmp);
}
}
mrb_state*
mrb_open()
{
mrb_state *mrb = mrb_open_allocf(allocf, NULL);
return mrb;
}
void mrb_free_symtbl(mrb_state *mrb);
void mrb_free_heap(mrb_state *mrb);
void
mrb_close(mrb_state *mrb)
{
int i;
/* free */
mrb_gc_free_gv(mrb);
mrb_free(mrb, mrb->stbase);
mrb_free(mrb, mrb->cibase);
for (i=0; i<mrb->irep_len; i++) {
if (!(mrb->irep[i]->flags & MRB_ISEQ_NO_FREE))
mrb_free(mrb, mrb->irep[i]->iseq);
mrb_free(mrb, mrb->irep[i]->pool);
mrb_free(mrb, mrb->irep[i]->syms);
mrb_free(mrb, mrb->irep[i]->lines);
mrb_free(mrb, mrb->irep[i]);
}
mrb_free(mrb, mrb->irep);
mrb_free(mrb, mrb->rescue);
mrb_free(mrb, mrb->ensure);
mrb_free_symtbl(mrb);
mrb_free_heap(mrb);
mrb_alloca_free(mrb);
mrb_free(mrb, mrb);
}
void
mrb_add_irep(mrb_state *mrb, int idx)
{
if (!mrb->irep) {
int max = 256;
if (idx > max) max = idx+1;
mrb->irep = (mrb_irep **)mrb_calloc(mrb, max, sizeof(mrb_irep*));
mrb->irep_capa = max;
}
else if (mrb->irep_capa <= idx) {
int i;
size_t old_capa = mrb->irep_capa;
while (mrb->irep_capa <= idx) {
mrb->irep_capa *= 2;
}
mrb->irep = (mrb_irep **)mrb_realloc(mrb, mrb->irep, sizeof(mrb_irep*)*mrb->irep_capa);
for (i = old_capa; i < mrb->irep_capa; i++) {
mrb->irep[i] = NULL;
}
}
}
mrb_value
mrb_top_self(mrb_state *mrb)
{
mrb_value v;
MRB_SET_VALUE(v, MRB_TT_MAIN, value.i, 0);
return v;
}