Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
state.c
Go to the documentation of this file.
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/class.h"
11 #include "mruby/irep.h"
12 #include "mruby/variable.h"
13 #include "mruby/debug.h"
14 
18 
19 static mrb_value
20 inspect_main(mrb_state *mrb, mrb_value mod)
21 {
22  return mrb_str_new(mrb, "main", 4);
23 }
24 
25 mrb_state*
27 {
28  static const mrb_state mrb_state_zero = { 0 };
29  static const struct mrb_context mrb_context_zero = { 0 };
30  mrb_state *mrb;
31 
32 #ifdef MRB_NAN_BOXING
33  mrb_assert(sizeof(void*) == 4);
34 #endif
35 
36  mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud);
37  if (mrb == NULL) return NULL;
38 
39  *mrb = mrb_state_zero;
40  mrb->ud = ud;
41  mrb->allocf = f;
43 
44  mrb_init_heap(mrb);
45  mrb->c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context));
46  *mrb->c = mrb_context_zero;
47  mrb->root_c = mrb->c;
48  mrb_init_core(mrb);
49 
50  return mrb;
51 }
52 
53 static void*
54 allocf(mrb_state *mrb, void *p, size_t size, void *ud)
55 {
56  if (size == 0) {
57  free(p);
58  return NULL;
59  }
60  else {
61  return realloc(p, size);
62  }
63 }
64 
65 struct alloca_header {
67  char buf[];
68 };
69 
70 void*
71 mrb_alloca(mrb_state *mrb, size_t size)
72 {
73  struct alloca_header *p;
74 
75  p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size);
76  if (p == NULL) return NULL;
77  p->next = mrb->mems;
78  mrb->mems = p;
79  return (void*)p->buf;
80 }
81 
82 static void
83 mrb_alloca_free(mrb_state *mrb)
84 {
85  struct alloca_header *p;
86  struct alloca_header *tmp;
87 
88  if (mrb == NULL) return;
89  p = mrb->mems;
90 
91  while (p) {
92  tmp = p;
93  p = p->next;
94  mrb_free(mrb, tmp);
95  }
96 }
97 
98 mrb_state*
99 mrb_open(void)
100 {
101  mrb_state *mrb = mrb_open_allocf(allocf, NULL);
102 
103  return mrb;
104 }
105 
106 void mrb_free_symtbl(mrb_state *mrb);
107 void mrb_free_heap(mrb_state *mrb);
108 
109 void
110 mrb_irep_free(mrb_state *mrb, struct mrb_irep *irep)
111 {
112  if (!(irep->flags & MRB_ISEQ_NO_FREE))
113  mrb_free(mrb, irep->iseq);
114  mrb_free(mrb, irep->pool);
115  mrb_free(mrb, irep->syms);
116  mrb_free(mrb, (void *)irep->filename);
117  mrb_free(mrb, irep->lines);
118  mrb_debug_info_free(mrb, irep->debug_info);
119  mrb_free(mrb, irep);
120 }
121 
122 void
124 {
125  if (!c) return;
126  mrb_free(mrb, c->stbase);
127  mrb_free(mrb, c->cibase);
128  mrb_free(mrb, c->rescue);
129  mrb_free(mrb, c->ensure);
130  mrb_free(mrb, c);
131 }
132 
133 void
135 {
136  size_t i;
137 
138  mrb_final_core(mrb);
139 
140  /* free */
141  mrb_gc_free_gv(mrb);
142  for (i=0; i<mrb->irep_len; i++) {
143  mrb_irep_free(mrb, mrb->irep[i]);
144  }
145  mrb_free(mrb, mrb->irep);
146  mrb_free_context(mrb, mrb->root_c);
147  mrb_free_symtbl(mrb);
148  mrb_free_heap(mrb);
149  mrb_alloca_free(mrb);
150  mrb_free(mrb, mrb);
151 }
152 
153 #ifndef MRB_IREP_ARRAY_INIT_SIZE
154 # define MRB_IREP_ARRAY_INIT_SIZE (256u)
155 #endif
156 
157 mrb_irep*
159 {
160  static const mrb_irep mrb_irep_zero = { 0 };
161  mrb_irep *irep;
162 
163  if (!mrb->irep) {
164  size_t max = MRB_IREP_ARRAY_INIT_SIZE;
165 
166  if (mrb->irep_len > max) max = mrb->irep_len+1;
167  mrb->irep = (mrb_irep **)mrb_calloc(mrb, max, sizeof(mrb_irep*));
168  mrb->irep_capa = max;
169  }
170  else if (mrb->irep_capa <= mrb->irep_len) {
171  size_t i;
172  size_t old_capa = mrb->irep_capa;
173  while (mrb->irep_capa <= mrb->irep_len) {
174  mrb->irep_capa *= 2;
175  }
176  mrb->irep = (mrb_irep **)mrb_realloc(mrb, mrb->irep, sizeof(mrb_irep*)*mrb->irep_capa);
177  for (i = old_capa; i < mrb->irep_capa; i++) {
178  mrb->irep[i] = NULL;
179  }
180  }
181  irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep));
182  *irep = mrb_irep_zero;
183  mrb->irep[mrb->irep_len] = irep;
184  irep->idx = mrb->irep_len++;
185 
186  return irep;
187 }
188 
189 mrb_value
191 {
192  if (!mrb->top_self) {
193  mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class);
194  mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE());
195  mrb_define_singleton_method(mrb, mrb->top_self, "to_s", inspect_main, MRB_ARGS_NONE());
196  }
197  return mrb_obj_value(mrb->top_self);
198 }