source: EcnlProtoTool/trunk/mruby-1.2.0/src/state.c@ 270

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

mruby版ECNLプロトタイピング・ツールを追加

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
  • Property svn:mime-type set to text/x-csrc
File size: 6.1 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>
9#include "mruby.h"
10#include "mruby/irep.h"
11#include "mruby/variable.h"
12#include "mruby/debug.h"
13#include "mruby/string.h"
14
15void mrb_init_core(mrb_state*);
16void mrb_init_mrbgems(mrb_state*);
17
18void mrb_gc_init(mrb_state*, mrb_gc *gc);
19void mrb_gc_destroy(mrb_state*, mrb_gc *gc);
20
21static mrb_value
22inspect_main(mrb_state *mrb, mrb_value mod)
23{
24 return mrb_str_new_lit(mrb, "main");
25}
26
27MRB_API mrb_state*
28mrb_open_core(mrb_allocf f, void *ud)
29{
30 static const mrb_state mrb_state_zero = { 0 };
31 static const struct mrb_context mrb_context_zero = { 0 };
32 mrb_state *mrb;
33
34 mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud);
35 if (mrb == NULL) return NULL;
36
37 *mrb = mrb_state_zero;
38 mrb->allocf_ud = ud;
39 mrb->allocf = f;
40 mrb->atexit_stack_len = 0;
41
42 mrb_gc_init(mrb, &mrb->gc);
43 mrb->c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context));
44 *mrb->c = mrb_context_zero;
45 mrb->root_c = mrb->c;
46
47 mrb_init_core(mrb);
48
49 return mrb;
50}
51
52void*
53mrb_default_allocf(mrb_state *mrb, void *p, size_t size, void *ud)
54{
55 if (size == 0) {
56 free(p);
57 return NULL;
58 }
59 else {
60 return realloc(p, size);
61 }
62}
63
64struct alloca_header {
65 struct alloca_header *next;
66 char buf[];
67};
68
69MRB_API void*
70mrb_alloca(mrb_state *mrb, size_t size)
71{
72 struct alloca_header *p;
73
74 p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size);
75 p->next = mrb->mems;
76 mrb->mems = p;
77 return (void*)p->buf;
78}
79
80static void
81mrb_alloca_free(mrb_state *mrb)
82{
83 struct alloca_header *p;
84 struct alloca_header *tmp;
85
86 if (mrb == NULL) return;
87 p = mrb->mems;
88
89 while (p) {
90 tmp = p;
91 p = p->next;
92 mrb_free(mrb, tmp);
93 }
94}
95
96MRB_API mrb_state*
97mrb_open(void)
98{
99 mrb_state *mrb = mrb_open_allocf(mrb_default_allocf, NULL);
100
101 return mrb;
102}
103
104MRB_API mrb_state*
105mrb_open_allocf(mrb_allocf f, void *ud)
106{
107 mrb_state *mrb = mrb_open_core(f, ud);
108
109 if (mrb == NULL) {
110 return NULL;
111 }
112
113#ifndef DISABLE_GEMS
114 mrb_init_mrbgems(mrb);
115 mrb_gc_arena_restore(mrb, 0);
116#endif
117 return mrb;
118}
119
120void mrb_free_symtbl(mrb_state *mrb);
121
122void
123mrb_irep_incref(mrb_state *mrb, mrb_irep *irep)
124{
125 irep->refcnt++;
126}
127
128void
129mrb_irep_decref(mrb_state *mrb, mrb_irep *irep)
130{
131 irep->refcnt--;
132 if (irep->refcnt == 0) {
133 mrb_irep_free(mrb, irep);
134 }
135}
136
137void
138mrb_irep_free(mrb_state *mrb, mrb_irep *irep)
139{
140 size_t i;
141
142 if (!(irep->flags & MRB_ISEQ_NO_FREE))
143 mrb_free(mrb, irep->iseq);
144 for (i=0; i<irep->plen; i++) {
145 if (mrb_type(irep->pool[i]) == MRB_TT_STRING) {
146 mrb_gc_free_str(mrb, RSTRING(irep->pool[i]));
147 mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
148 }
149#ifdef MRB_WORD_BOXING
150 else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) {
151 mrb_free(mrb, mrb_obj_ptr(irep->pool[i]));
152 }
153#endif
154 }
155 mrb_free(mrb, irep->pool);
156 mrb_free(mrb, irep->syms);
157 for (i=0; i<irep->rlen; i++) {
158 mrb_irep_decref(mrb, irep->reps[i]);
159 }
160 mrb_free(mrb, irep->reps);
161 mrb_free(mrb, irep->lv);
162 mrb_free(mrb, (void *)irep->filename);
163 mrb_free(mrb, irep->lines);
164 mrb_debug_info_free(mrb, irep->debug_info);
165 mrb_free(mrb, irep);
166}
167
168mrb_value
169mrb_str_pool(mrb_state *mrb, mrb_value str)
170{
171 struct RString *s = mrb_str_ptr(str);
172 struct RString *ns;
173 char *ptr;
174 mrb_int len;
175
176 ns = (struct RString *)mrb_malloc(mrb, sizeof(struct RString));
177 ns->tt = MRB_TT_STRING;
178 ns->c = mrb->string_class;
179
180 if (RSTR_NOFREE_P(s)) {
181 ns->flags = MRB_STR_NOFREE;
182 ns->as.heap.ptr = s->as.heap.ptr;
183 ns->as.heap.len = s->as.heap.len;
184 ns->as.heap.aux.capa = 0;
185 }
186 else {
187 ns->flags = 0;
188 if (RSTR_EMBED_P(s)) {
189 ptr = s->as.ary;
190 len = RSTR_EMBED_LEN(s);
191 }
192 else {
193 ptr = s->as.heap.ptr;
194 len = s->as.heap.len;
195 }
196
197 if (len < RSTRING_EMBED_LEN_MAX) {
198 RSTR_SET_EMBED_FLAG(ns);
199 RSTR_SET_EMBED_LEN(ns, len);
200 if (ptr) {
201 memcpy(ns->as.ary, ptr, len);
202 }
203 ns->as.ary[len] = '\0';
204 }
205 else {
206 ns->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1);
207 ns->as.heap.len = len;
208 ns->as.heap.aux.capa = len;
209 if (ptr) {
210 memcpy(ns->as.heap.ptr, ptr, len);
211 }
212 ns->as.heap.ptr[len] = '\0';
213 }
214 }
215 return mrb_obj_value(ns);
216}
217
218MRB_API void
219mrb_free_context(mrb_state *mrb, struct mrb_context *c)
220{
221 if (!c) return;
222 mrb_free(mrb, c->stbase);
223 mrb_free(mrb, c->cibase);
224 mrb_free(mrb, c->rescue);
225 mrb_free(mrb, c->ensure);
226 mrb_free(mrb, c);
227}
228
229MRB_API void
230mrb_close(mrb_state *mrb)
231{
232 if (!mrb) return;
233 if (mrb->atexit_stack_len > 0) {
234 mrb_int i;
235 for (i = mrb->atexit_stack_len; i > 0; --i) {
236 mrb->atexit_stack[i - 1](mrb);
237 }
238#ifndef MRB_FIXED_STATE_ATEXIT_STACK
239 mrb_free(mrb, mrb->atexit_stack);
240#endif
241 }
242
243 /* free */
244 mrb_gc_free_gv(mrb);
245 mrb_free_context(mrb, mrb->root_c);
246 mrb_free_symtbl(mrb);
247 mrb_alloca_free(mrb);
248 mrb_gc_destroy(mrb, &mrb->gc);
249 mrb_free(mrb, mrb);
250}
251
252MRB_API mrb_irep*
253mrb_add_irep(mrb_state *mrb)
254{
255 static const mrb_irep mrb_irep_zero = { 0 };
256 mrb_irep *irep;
257
258 irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep));
259 *irep = mrb_irep_zero;
260 irep->refcnt = 1;
261
262 return irep;
263}
264
265MRB_API mrb_value
266mrb_top_self(mrb_state *mrb)
267{
268 if (!mrb->top_self) {
269 mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);
270 mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE());
271 mrb_define_singleton_method(mrb, mrb->top_self, "to_s", inspect_main, MRB_ARGS_NONE());
272 }
273 return mrb_obj_value(mrb->top_self);
274}
275
276MRB_API void
277mrb_state_atexit(mrb_state *mrb, mrb_atexit_func f)
278{
279#ifdef MRB_FIXED_STATE_ATEXIT_STACK
280 if (mrb->atexit_stack_len + 1 > MRB_FIXED_STATE_ATEXIT_STACK_SIZE) {
281 mrb_raise(mrb, E_RUNTIME_ERROR, "exceeded fixed state atexit stack limit");
282 }
283#else
284 size_t stack_size;
285
286 stack_size = sizeof(mrb_atexit_func) * (mrb->atexit_stack_len + 1);
287 if (mrb->atexit_stack_len == 0) {
288 mrb->atexit_stack = (mrb_atexit_func*)mrb_malloc(mrb, stack_size);
289 } else {
290 mrb->atexit_stack = (mrb_atexit_func*)mrb_realloc(mrb, mrb->atexit_stack, stack_size);
291 }
292#endif
293
294 mrb->atexit_stack[mrb->atexit_stack_len++] = f;
295}
Note: See TracBrowser for help on using the repository browser.