source: EcnlProtoTool/trunk/mruby-2.1.1/src/state.c@ 439

Last change on this file since 439 was 439, checked in by coas-nagasima, 4 years ago

mrubyを2.1.1に更新

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 4.5 KB
RevLine 
[270]1/*
2** state.c - mrb_state open/close functions
3**
4** See Copyright Notice in mruby.h
5*/
6
7#include <stdlib.h>
8#include <string.h>
[331]9#include <mruby.h>
10#include <mruby/irep.h>
11#include <mruby/variable.h>
12#include <mruby/debug.h>
13#include <mruby/string.h>
[439]14#include <mruby/class.h>
[270]15
16void mrb_init_core(mrb_state*);
17void mrb_init_mrbgems(mrb_state*);
18
19void mrb_gc_init(mrb_state*, mrb_gc *gc);
20void mrb_gc_destroy(mrb_state*, mrb_gc *gc);
21
22MRB_API mrb_state*
23mrb_open_core(mrb_allocf f, void *ud)
24{
25 static const mrb_state mrb_state_zero = { 0 };
26 static const struct mrb_context mrb_context_zero = { 0 };
27 mrb_state *mrb;
28
[439]29 if (f == NULL) f = mrb_default_allocf;
[270]30 mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud);
31 if (mrb == NULL) return NULL;
32
33 *mrb = mrb_state_zero;
34 mrb->allocf_ud = ud;
35 mrb->allocf = f;
36 mrb->atexit_stack_len = 0;
37
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;
41 mrb->root_c = mrb->c;
42
43 mrb_init_core(mrb);
44
45 return mrb;
46}
47
48void*
49mrb_default_allocf(mrb_state *mrb, void *p, size_t size, void *ud)
50{
51 if (size == 0) {
52 free(p);
53 return NULL;
54 }
55 else {
56 return realloc(p, size);
57 }
58}
59
60MRB_API mrb_state*
61mrb_open(void)
62{
[279]63 mrb_state *mrb = mrb_open_allocf(mrb_default_allocf, NULL, FALSE);
[270]64
65 return mrb;
66}
67
68MRB_API mrb_state*
[279]69mrb_open_allocf(mrb_allocf f, void *ud, mrb_bool disable_gems)
[270]70{
71 mrb_state *mrb = mrb_open_core(f, ud);
72
73 if (mrb == NULL) {
74 return NULL;
75 }
76
[279]77 if (!disable_gems) {
[439]78#ifndef DISABLE_GEMS
[279]79 mrb_init_mrbgems(mrb);
80 mrb_gc_arena_restore(mrb, 0);
[439]81#endif
[279]82 }
[270]83 return mrb;
84}
85
86void mrb_free_symtbl(mrb_state *mrb);
87
88void
89mrb_irep_incref(mrb_state *mrb, mrb_irep *irep)
90{
91 irep->refcnt++;
92}
93
94void
95mrb_irep_decref(mrb_state *mrb, mrb_irep *irep)
96{
97 irep->refcnt--;
98 if (irep->refcnt == 0) {
99 mrb_irep_free(mrb, irep);
100 }
101}
102
103void
[439]104mrb_irep_cutref(mrb_state *mrb, mrb_irep *irep)
105{
106 mrb_irep *tmp;
107 int i;
108
109 for (i=0; i<irep->rlen; i++) {
110 tmp = irep->reps[i];
111 irep->reps[i] = NULL;
112 if (tmp) mrb_irep_decref(mrb, tmp);
113 }
114}
115
116void
[270]117mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
118{
[439]119 int i;
[270]120
121 if (!(irep->flags & MRB_ISEQ_NO_FREE))
[439]122 mrb_free(mrb, (void*)irep->iseq);
[331]123 if (irep->pool) for (i=0; i<irep->plen; i++) {
[439]124 if (mrb_string_p(irep->pool[i])) {
[270]125 mrb_gc_free_str(mrb, RSTRING(irep->pool[i]));
126 mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
127 }
[439]128#if defined(MRB_WORD_BOXING) && !defined(MRB_WITHOUT_FLOAT)
129 else if (mrb_float_p(irep->pool[i])) {
[270]130 mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
131 }
132#endif
133 }
134 mrb_free(mrb, irep->pool);
135 mrb_free(mrb, irep->syms);
136 for (i=0; i<irep->rlen; i++) {
[439]137 if (irep->reps[i])
138 mrb_irep_decref(mrb, irep->reps[i]);
[270]139 }
140 mrb_free(mrb, irep->reps);
141 mrb_free(mrb, irep->lv);
142 mrb_debug_info_free(mrb, irep->debug_info);
143 mrb_free(mrb, irep);
144}
145
[331]146void mrb_free_backtrace(mrb_state *mrb);
147
[270]148MRB_API void
149mrb_free_context(mrb_state *mrb, struct mrb_context *c)
150{
151 if (!c) return;
152 mrb_free(mrb, c->stbase);
153 mrb_free(mrb, c->cibase);
154 mrb_free(mrb, c->rescue);
155 mrb_free(mrb, c->ensure);
156 mrb_free(mrb, c);
157}
158
159MRB_API void
160mrb_close(mrb_state *mrb)
161{
162 if (!mrb) return;
163 if (mrb->atexit_stack_len > 0) {
164 mrb_int i;
165 for (i = mrb->atexit_stack_len; i > 0; --i) {
166 mrb->atexit_stack[i - 1](mrb);
167 }
168#ifndef MRB_FIXED_STATE_ATEXIT_STACK
169 mrb_free(mrb, mrb->atexit_stack);
170#endif
171 }
172
173 /* free */
[439]174 mrb_gc_destroy(mrb, &mrb->gc);
175 mrb_free_context(mrb, mrb->root_c);
[270]176 mrb_gc_free_gv(mrb);
177 mrb_free_symtbl(mrb);
178 mrb_free(mrb, mrb);
179}
180
181MRB_API mrb_irep*
182mrb_add_irep(mrb_state *mrb)
183{
184 static const mrb_irep mrb_irep_zero = { 0 };
185 mrb_irep *irep;
186
187 irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep));
188 *irep = mrb_irep_zero;
189 irep->refcnt = 1;
190
191 return irep;
192}
193
194MRB_API mrb_value
195mrb_top_self(mrb_state *mrb)
196{
197 return mrb_obj_value(mrb->top_self);
198}
199
200MRB_API void
201mrb_state_atexit(mrb_state *mrb, mrb_atexit_func f)
202{
203#ifdef MRB_FIXED_STATE_ATEXIT_STACK
204 if (mrb->atexit_stack_len + 1 > MRB_FIXED_STATE_ATEXIT_STACK_SIZE) {
205 mrb_raise(mrb, E_RUNTIME_ERROR, "exceeded fixed state atexit stack limit");
206 }
207#else
208 size_t stack_size;
209
210 stack_size = sizeof(mrb_atexit_func) * (mrb->atexit_stack_len + 1);
211 if (mrb->atexit_stack_len == 0) {
212 mrb->atexit_stack = (mrb_atexit_func*)mrb_malloc(mrb, stack_size);
[331]213 }
214 else {
[270]215 mrb->atexit_stack = (mrb_atexit_func*)mrb_realloc(mrb, mrb->atexit_stack, stack_size);
216 }
217#endif
218
219 mrb->atexit_stack[mrb->atexit_stack_len++] = f;
220}
Note: See TracBrowser for help on using the repository browser.