2 ** state.c - mrb_state open/close functions
4 ** See Copyright Notice in mruby.h
10 #include <mruby/irep.h>
11 #include <mruby/variable.h>
12 #include <mruby/debug.h>
13 #include <mruby/string.h>
14 #include <mruby/class.h>
16 void mrb_init_core(mrb_state*);
17 void mrb_init_mrbgems(mrb_state*);
19 void mrb_gc_init(mrb_state*, mrb_gc *gc);
20 void mrb_gc_destroy(mrb_state*, mrb_gc *gc);
23 mrb_open_core(mrb_allocf f, void *ud)
25 static const mrb_state mrb_state_zero = { 0 };
26 static const struct mrb_context mrb_context_zero = { 0 };
29 if (f == NULL) f = mrb_default_allocf;
30 mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud);
31 if (mrb == NULL) return NULL;
33 *mrb = mrb_state_zero;
36 mrb->atexit_stack_len = 0;
38 mrb_gc_init(mrb, &mrb->gc);
39 mrb->c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context));
40 *mrb->c = mrb_context_zero;
45 #if !defined(MRB_DISABLE_STDIO) && defined(_MSC_VER) && _MSC_VER < 1900
46 _set_output_format(_TWO_DIGIT_EXPONENT);
53 mrb_default_allocf(mrb_state *mrb, void *p, size_t size, void *ud)
60 return realloc(p, size);
64 struct alloca_header {
65 struct alloca_header *next;
70 mrb_alloca(mrb_state *mrb, size_t size)
72 struct alloca_header *p;
74 p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size);
81 mrb_alloca_free(mrb_state *mrb)
83 struct alloca_header *p;
84 struct alloca_header *tmp;
86 if (mrb == NULL) return;
99 mrb_state *mrb = mrb_open_allocf(mrb_default_allocf, NULL);
105 mrb_open_allocf(mrb_allocf f, void *ud)
107 mrb_state *mrb = mrb_open_core(f, ud);
114 mrb_init_mrbgems(mrb);
115 mrb_gc_arena_restore(mrb, 0);
120 void mrb_free_symtbl(mrb_state *mrb);
123 mrb_irep_incref(mrb_state *mrb, mrb_irep *irep)
129 mrb_irep_decref(mrb_state *mrb, mrb_irep *irep)
132 if (irep->refcnt == 0) {
133 mrb_irep_free(mrb, irep);
138 mrb_irep_cutref(mrb_state *mrb, mrb_irep *irep)
143 for (i=0; i<irep->rlen; i++) {
145 irep->reps[i] = NULL;
146 if (tmp) mrb_irep_decref(mrb, tmp);
151 mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
155 if (!(irep->flags & MRB_ISEQ_NO_FREE))
156 mrb_free(mrb, irep->iseq);
157 if (irep->pool) for (i=0; i<irep->plen; i++) {
158 if (mrb_type(irep->pool[i]) == MRB_TT_STRING) {
159 mrb_gc_free_str(mrb, RSTRING(irep->pool[i]));
160 mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
162 #if defined(MRB_WORD_BOXING) && !defined(MRB_WITHOUT_FLOAT)
163 else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) {
164 mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
168 mrb_free(mrb, irep->pool);
169 mrb_free(mrb, irep->syms);
170 for (i=0; i<irep->rlen; i++) {
172 mrb_irep_decref(mrb, irep->reps[i]);
174 mrb_free(mrb, irep->reps);
175 mrb_free(mrb, irep->lv);
176 mrb_debug_info_free(mrb, irep->debug_info);
181 mrb_str_pool(mrb_state *mrb, mrb_value str)
183 struct RString *s = mrb_str_ptr(str);
188 ns = (struct RString *)mrb_malloc(mrb, sizeof(struct RString));
189 ns->tt = MRB_TT_STRING;
190 ns->c = mrb->string_class;
192 if (RSTR_NOFREE_P(s)) {
193 ns->flags = MRB_STR_NOFREE;
194 ns->as.heap.ptr = s->as.heap.ptr;
195 ns->as.heap.len = s->as.heap.len;
196 ns->as.heap.aux.capa = 0;
200 if (RSTR_EMBED_P(s)) {
202 len = RSTR_EMBED_LEN(s);
205 ptr = s->as.heap.ptr;
206 len = s->as.heap.len;
209 if (len < RSTRING_EMBED_LEN_MAX) {
210 RSTR_SET_EMBED_FLAG(ns);
211 RSTR_SET_EMBED_LEN(ns, len);
213 memcpy(ns->as.ary, ptr, len);
215 ns->as.ary[len] = '\0';
218 ns->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
219 ns->as.heap.len = len;
220 ns->as.heap.aux.capa = len;
222 memcpy(ns->as.heap.ptr, ptr, len);
224 ns->as.heap.ptr[len] = '\0';
227 RSTR_SET_POOL_FLAG(ns);
228 MRB_SET_FROZEN_FLAG(ns);
229 return mrb_obj_value(ns);
232 void mrb_free_backtrace(mrb_state *mrb);
235 mrb_free_context(mrb_state *mrb, struct mrb_context *c)
238 mrb_free(mrb, c->stbase);
239 mrb_free(mrb, c->cibase);
240 mrb_free(mrb, c->rescue);
241 mrb_free(mrb, c->ensure);
246 mrb_close(mrb_state *mrb)
249 if (mrb->atexit_stack_len > 0) {
251 for (i = mrb->atexit_stack_len; i > 0; --i) {
252 mrb->atexit_stack[i - 1](mrb);
254 #ifndef MRB_FIXED_STATE_ATEXIT_STACK
255 mrb_free(mrb, mrb->atexit_stack);
261 mrb_free_context(mrb, mrb->root_c);
262 mrb_free_symtbl(mrb);
263 mrb_alloca_free(mrb);
264 mrb_gc_destroy(mrb, &mrb->gc);
269 mrb_add_irep(mrb_state *mrb)
271 static const mrb_irep mrb_irep_zero = { 0 };
274 irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep));
275 *irep = mrb_irep_zero;
282 mrb_top_self(mrb_state *mrb)
284 return mrb_obj_value(mrb->top_self);
288 mrb_state_atexit(mrb_state *mrb, mrb_atexit_func f)
290 #ifdef MRB_FIXED_STATE_ATEXIT_STACK
291 if (mrb->atexit_stack_len + 1 > MRB_FIXED_STATE_ATEXIT_STACK_SIZE) {
292 mrb_raise(mrb, E_RUNTIME_ERROR, "exceeded fixed state atexit stack limit");
297 stack_size = sizeof(mrb_atexit_func) * (mrb->atexit_stack_len + 1);
298 if (mrb->atexit_stack_len == 0) {
299 mrb->atexit_stack = (mrb_atexit_func*)mrb_malloc(mrb, stack_size);
302 mrb->atexit_stack = (mrb_atexit_func*)mrb_realloc(mrb, mrb->atexit_stack, stack_size);
306 mrb->atexit_stack[mrb->atexit_stack_len++] = f;