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);
22 int mrb_core_init_protect(mrb_state *mrb, void (*body)(mrb_state *, void *), void *opaque);
25 init_gc_and_core(mrb_state *mrb, void *opaque)
27 static const struct mrb_context mrb_context_zero = { 0 };
29 mrb_gc_init(mrb, &mrb->gc);
30 mrb->c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context));
31 *mrb->c = mrb_context_zero;
38 mrb_open_core(mrb_allocf f, void *ud)
40 static const mrb_state mrb_state_zero = { 0 };
43 if (f == NULL) f = mrb_default_allocf;
44 mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud);
45 if (mrb == NULL) return NULL;
47 *mrb = mrb_state_zero;
50 mrb->atexit_stack_len = 0;
52 if (mrb_core_init_protect(mrb, init_gc_and_core, NULL)) {
61 mrb_default_allocf(mrb_state *mrb, void *p, size_t size, void *ud)
68 return realloc(p, size);
75 mrb_state *mrb = mrb_open_allocf(mrb_default_allocf, NULL);
81 init_mrbgems(mrb_state *mrb, void *opaque)
83 mrb_init_mrbgems(mrb);
87 mrb_open_allocf(mrb_allocf f, void *ud)
89 mrb_state *mrb = mrb_open_core(f, ud);
96 if (mrb_core_init_protect(mrb, init_mrbgems, NULL)) {
100 mrb_gc_arena_restore(mrb, 0);
105 void mrb_free_symtbl(mrb_state *mrb);
108 mrb_irep_incref(mrb_state *mrb, mrb_irep *irep)
114 mrb_irep_decref(mrb_state *mrb, mrb_irep *irep)
117 if (irep->refcnt == 0) {
118 mrb_irep_free(mrb, irep);
123 mrb_irep_cutref(mrb_state *mrb, mrb_irep *irep)
128 for (i=0; i<irep->rlen; i++) {
130 irep->reps[i] = NULL;
131 if (tmp) mrb_irep_decref(mrb, tmp);
136 mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
140 if (!(irep->flags & MRB_ISEQ_NO_FREE))
141 mrb_free(mrb, (void*)irep->iseq);
142 if (irep->pool) for (i=0; i<irep->plen; i++) {
143 if (mrb_string_p(irep->pool[i])) {
144 mrb_gc_free_str(mrb, RSTRING(irep->pool[i]));
145 mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
147 #if defined(MRB_WORD_BOXING) && !defined(MRB_WITHOUT_FLOAT)
148 else if (mrb_float_p(irep->pool[i])) {
149 mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
153 mrb_free(mrb, irep->pool);
154 mrb_free(mrb, irep->syms);
156 for (i=0; i<irep->rlen; i++) {
158 mrb_irep_decref(mrb, irep->reps[i]);
161 mrb_free(mrb, irep->reps);
162 mrb_free(mrb, irep->lv);
163 mrb_debug_info_free(mrb, irep->debug_info);
167 void mrb_free_backtrace(mrb_state *mrb);
170 mrb_free_context(mrb_state *mrb, struct mrb_context *c)
173 mrb_free(mrb, c->stbase);
174 mrb_free(mrb, c->cibase);
175 mrb_free(mrb, c->rescue);
176 mrb_free(mrb, c->ensure);
181 mrb_close(mrb_state *mrb)
184 if (mrb->atexit_stack_len > 0) {
186 for (i = mrb->atexit_stack_len; i > 0; --i) {
187 mrb->atexit_stack[i - 1](mrb);
189 #ifndef MRB_FIXED_STATE_ATEXIT_STACK
190 mrb_free(mrb, mrb->atexit_stack);
195 mrb_gc_destroy(mrb, &mrb->gc);
196 mrb_free_context(mrb, mrb->root_c);
198 mrb_free_symtbl(mrb);
203 mrb_add_irep(mrb_state *mrb)
205 static const mrb_irep mrb_irep_zero = { 0 };
208 irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep));
209 *irep = mrb_irep_zero;
216 mrb_top_self(mrb_state *mrb)
218 return mrb_obj_value(mrb->top_self);
222 mrb_state_atexit(mrb_state *mrb, mrb_atexit_func f)
224 #ifdef MRB_FIXED_STATE_ATEXIT_STACK
225 if (mrb->atexit_stack_len + 1 > MRB_FIXED_STATE_ATEXIT_STACK_SIZE) {
226 mrb_raise(mrb, E_RUNTIME_ERROR, "exceeded fixed state atexit stack limit");
231 stack_size = sizeof(mrb_atexit_func) * (mrb->atexit_stack_len + 1);
232 if (mrb->atexit_stack_len == 0) {
233 mrb->atexit_stack = (mrb_atexit_func*)mrb_malloc(mrb, stack_size);
236 mrb->atexit_stack = (mrb_atexit_func*)mrb_realloc(mrb, mrb->atexit_stack, stack_size);
240 mrb->atexit_stack[mrb->atexit_stack_len++] = f;