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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
|
/*
** 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_final_core(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);
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(void)
{
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_irep_free(mrb_state *mrb, struct mrb_irep *irep)
{
if (!(irep->flags & MRB_ISEQ_NO_FREE))
mrb_free(mrb, irep->iseq);
mrb_free(mrb, irep->pool);
mrb_free(mrb, irep->syms);
mrb_free(mrb, irep->lines);
mrb_free(mrb, irep);
}
void
mrb_close(mrb_state *mrb)
{
size_t i;
mrb_final_core(mrb);
/* free */
mrb_gc_free_gv(mrb);
mrb_free(mrb, mrb->stbase);
mrb_free(mrb, mrb->cibase);
for (i=0; i<mrb->irep_len; i++) {
mrb_irep_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);
}
#ifndef MRB_IREP_ARRAY_INIT_SIZE
# define MRB_IREP_ARRAY_INIT_SIZE (256u)
#endif
mrb_irep*
mrb_add_irep(mrb_state *mrb)
{
static const mrb_irep mrb_irep_zero = { 0 };
mrb_irep *irep;
if (!mrb->irep) {
size_t max = MRB_IREP_ARRAY_INIT_SIZE;
if (mrb->irep_len > max) max = mrb->irep_len+1;
mrb->irep = (mrb_irep **)mrb_calloc(mrb, max, sizeof(mrb_irep*));
mrb->irep_capa = max;
}
else if (mrb->irep_capa <= mrb->irep_len) {
int i;
size_t old_capa = mrb->irep_capa;
while (mrb->irep_capa <= mrb->irep_len) {
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;
}
}
irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep));
*irep = mrb_irep_zero;
mrb->irep[mrb->irep_len] = irep;
irep->idx = mrb->irep_len++;
return irep;
}
mrb_value
mrb_top_self(mrb_state *mrb)
{
mrb_value v;
MRB_SET_VALUE(v, MRB_TT_MAIN, value.i, 0);
return v;
}
|