mbed I/F binding for mruby
Dependents: mruby_mbed_web mirb_mbed
state.c
00001 /* 00002 ** state.c - mrb_state open/close functions 00003 ** 00004 ** See Copyright Notice in mruby.h 00005 */ 00006 00007 #include <stdlib.h> 00008 #include <string.h> 00009 #include "mruby.h" 00010 #include "mruby/irep.h" 00011 #include "mruby/variable.h" 00012 #include "mruby/debug.h" 00013 #include "mruby/string.h" 00014 00015 void mrb_init_heap(mrb_state*); 00016 void mrb_init_core(mrb_state*); 00017 void mrb_init_mrbgems(mrb_state*); 00018 00019 static mrb_value 00020 inspect_main(mrb_state *mrb, mrb_value mod) 00021 { 00022 return mrb_str_new_lit(mrb, "main"); 00023 } 00024 00025 MRB_API mrb_state* 00026 mrb_open_core(mrb_allocf f, void *ud) 00027 { 00028 static const mrb_state mrb_state_zero = { 0 }; 00029 static const struct mrb_context mrb_context_zero = { 0 }; 00030 mrb_state *mrb; 00031 00032 mrb = (mrb_state *)(f)(NULL, NULL, sizeof(mrb_state), ud); 00033 if (mrb == NULL) return NULL; 00034 00035 *mrb = mrb_state_zero; 00036 mrb->allocf_ud = ud; 00037 mrb->allocf = f; 00038 mrb->current_white_part = MRB_GC_WHITE_A; 00039 mrb->atexit_stack_len = 0; 00040 00041 #ifndef MRB_GC_FIXED_ARENA 00042 mrb->arena = (struct RBasic**)mrb_malloc(mrb, sizeof(struct RBasic*)*MRB_GC_ARENA_SIZE); 00043 mrb->arena_capa = MRB_GC_ARENA_SIZE; 00044 #endif 00045 00046 mrb_init_heap(mrb); 00047 mrb->c = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context)); 00048 *mrb->c = mrb_context_zero; 00049 mrb->root_c = mrb->c; 00050 00051 mrb_init_core(mrb); 00052 00053 return mrb; 00054 } 00055 00056 void* 00057 mrb_default_allocf(mrb_state *mrb, void *p, size_t size, void *ud) 00058 { 00059 if (size == 0) { 00060 free(p); 00061 return NULL; 00062 } 00063 else { 00064 return realloc(p, size); 00065 } 00066 } 00067 00068 struct alloca_header { 00069 struct alloca_header *next; 00070 char buf[]; 00071 }; 00072 00073 MRB_API void* 00074 mrb_alloca(mrb_state *mrb, size_t size) 00075 { 00076 struct alloca_header *p; 00077 00078 p = (struct alloca_header*) mrb_malloc(mrb, sizeof(struct alloca_header)+size); 00079 p->next = mrb->mems; 00080 mrb->mems = p; 00081 return (void*)p->buf; 00082 } 00083 00084 static void 00085 mrb_alloca_free(mrb_state *mrb) 00086 { 00087 struct alloca_header *p; 00088 struct alloca_header *tmp; 00089 00090 if (mrb == NULL) return; 00091 p = mrb->mems; 00092 00093 while (p) { 00094 tmp = p; 00095 p = p->next; 00096 mrb_free(mrb, tmp); 00097 } 00098 } 00099 00100 MRB_API mrb_state* 00101 mrb_open(void) 00102 { 00103 mrb_state *mrb = mrb_open_allocf(mrb_default_allocf, NULL); 00104 00105 return mrb; 00106 } 00107 00108 MRB_API mrb_state* 00109 mrb_open_allocf(mrb_allocf f, void *ud) 00110 { 00111 mrb_state *mrb = mrb_open_core(f, ud); 00112 00113 if (mrb == NULL) { 00114 return NULL; 00115 } 00116 00117 #ifndef DISABLE_GEMS 00118 mrb_init_mrbgems(mrb); 00119 mrb_gc_arena_restore(mrb, 0); 00120 #endif 00121 return mrb; 00122 } 00123 00124 void mrb_free_symtbl(mrb_state *mrb); 00125 void mrb_free_heap(mrb_state *mrb); 00126 00127 void 00128 mrb_irep_incref(mrb_state *mrb, mrb_irep *irep) 00129 { 00130 irep->refcnt++; 00131 } 00132 00133 void 00134 mrb_irep_decref(mrb_state *mrb, mrb_irep *irep) 00135 { 00136 irep->refcnt--; 00137 if (irep->refcnt == 0) { 00138 mrb_irep_free(mrb, irep); 00139 } 00140 } 00141 00142 void 00143 mrb_irep_free(mrb_state *mrb, mrb_irep *irep) 00144 { 00145 size_t i; 00146 00147 if (!(irep->flags & MRB_ISEQ_NO_FREE)) 00148 mrb_free(mrb, irep->iseq); 00149 for (i=0; i<irep->plen; i++) { 00150 if (mrb_type(irep->pool[i]) == MRB_TT_STRING) { 00151 mrb_gc_free_str(mrb, RSTRING(irep->pool[i])); 00152 mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); 00153 } 00154 #ifdef MRB_WORD_BOXING 00155 else if (mrb_type(irep->pool[i]) == MRB_TT_FLOAT) { 00156 mrb_free(mrb, mrb_obj_ptr(irep->pool[i])); 00157 } 00158 #endif 00159 } 00160 mrb_free(mrb, irep->pool); 00161 mrb_free(mrb, irep->syms); 00162 for (i=0; i<irep->rlen; i++) { 00163 mrb_irep_decref(mrb, irep->reps[i]); 00164 } 00165 mrb_free(mrb, irep->reps); 00166 mrb_free(mrb, irep->lv); 00167 mrb_free(mrb, (void *)irep->filename); 00168 mrb_free(mrb, irep->lines); 00169 mrb_debug_info_free(mrb, irep->debug_info); 00170 mrb_free(mrb, irep); 00171 } 00172 00173 mrb_value 00174 mrb_str_pool(mrb_state *mrb, mrb_value str) 00175 { 00176 struct RString *s = mrb_str_ptr(str); 00177 struct RString *ns; 00178 char *ptr; 00179 mrb_int len; 00180 00181 ns = (struct RString *)mrb_malloc(mrb, sizeof(struct RString)); 00182 ns->tt = MRB_TT_STRING; 00183 ns->c = mrb->string_class; 00184 00185 if (RSTR_NOFREE_P(s)) { 00186 ns->flags = MRB_STR_NOFREE; 00187 ns->as.heap.ptr = s->as.heap.ptr; 00188 ns->as.heap.len = s->as.heap.len; 00189 ns->as.heap.aux.capa = 0; 00190 } 00191 else { 00192 ns->flags = 0; 00193 if (RSTR_EMBED_P(s)) { 00194 ptr = s->as.ary; 00195 len = RSTR_EMBED_LEN(s); 00196 } 00197 else { 00198 ptr = s->as.heap.ptr; 00199 len = s->as.heap.len; 00200 } 00201 00202 if (len < RSTRING_EMBED_LEN_MAX) { 00203 RSTR_SET_EMBED_FLAG(ns); 00204 RSTR_SET_EMBED_LEN(ns, len); 00205 if (ptr) { 00206 memcpy(ns->as.ary, ptr, len); 00207 } 00208 ns->as.ary[len] = '\0'; 00209 } 00210 else { 00211 ns->as.heap.ptr = (char *)mrb_malloc(mrb, (size_t)len+1); 00212 ns->as.heap.len = len; 00213 ns->as.heap.aux.capa = len; 00214 if (ptr) { 00215 memcpy(ns->as.heap.ptr, ptr, len); 00216 } 00217 ns->as.heap.ptr[len] = '\0'; 00218 } 00219 } 00220 return mrb_obj_value(ns); 00221 } 00222 00223 MRB_API void 00224 mrb_free_context(mrb_state *mrb, struct mrb_context *c) 00225 { 00226 if (!c) return; 00227 mrb_free(mrb, c->stbase); 00228 mrb_free(mrb, c->cibase); 00229 mrb_free(mrb, c->rescue); 00230 mrb_free(mrb, c->ensure); 00231 mrb_free(mrb, c); 00232 } 00233 00234 MRB_API void 00235 mrb_close(mrb_state *mrb) 00236 { 00237 if (mrb->atexit_stack_len > 0) { 00238 mrb_int i; 00239 for (i = mrb->atexit_stack_len; i > 0; --i) { 00240 mrb->atexit_stack[i - 1](mrb); 00241 } 00242 #ifndef MRB_FIXED_STATE_ATEXIT_STACK 00243 mrb_free(mrb, mrb->atexit_stack); 00244 #endif 00245 } 00246 00247 /* free */ 00248 mrb_gc_free_gv(mrb); 00249 mrb_free_context(mrb, mrb->root_c); 00250 mrb_free_symtbl(mrb); 00251 mrb_free_heap(mrb); 00252 mrb_alloca_free(mrb); 00253 #ifndef MRB_GC_FIXED_ARENA 00254 mrb_free(mrb, mrb->arena); 00255 #endif 00256 mrb_free(mrb, mrb); 00257 } 00258 00259 MRB_API mrb_irep* 00260 mrb_add_irep(mrb_state *mrb) 00261 { 00262 static const mrb_irep mrb_irep_zero = { 0 }; 00263 mrb_irep *irep; 00264 00265 irep = (mrb_irep *)mrb_malloc(mrb, sizeof(mrb_irep)); 00266 *irep = mrb_irep_zero; 00267 irep->refcnt = 1; 00268 00269 return irep; 00270 } 00271 00272 MRB_API mrb_value 00273 mrb_top_self(mrb_state *mrb) 00274 { 00275 if (!mrb->top_self) { 00276 mrb->top_self = (struct RObject*)mrb_obj_alloc(mrb, MRB_TT_OBJECT, mrb->object_class); 00277 mrb_define_singleton_method(mrb, mrb->top_self, "inspect", inspect_main, MRB_ARGS_NONE()); 00278 mrb_define_singleton_method(mrb, mrb->top_self, "to_s", inspect_main, MRB_ARGS_NONE()); 00279 } 00280 return mrb_obj_value(mrb->top_self); 00281 } 00282 00283 MRB_API void 00284 mrb_state_atexit(mrb_state *mrb, mrb_atexit_func f) 00285 { 00286 #ifdef MRB_FIXED_STATE_ATEXIT_STACK 00287 if (mrb->atexit_stack_len + 1 > MRB_FIXED_STATE_ATEXIT_STACK_SIZE) { 00288 mrb_raise(mrb, E_RUNTIME_ERROR, "exceeded fixed state atexit stack limit"); 00289 } 00290 #else 00291 size_t stack_size; 00292 00293 stack_size = sizeof(mrb_atexit_func) * (mrb->atexit_stack_len + 1); 00294 if (mrb->atexit_stack_len == 0) { 00295 mrb->atexit_stack = (mrb_atexit_func*)mrb_malloc(mrb, stack_size); 00296 } else { 00297 mrb->atexit_stack = (mrb_atexit_func*)mrb_realloc(mrb, mrb->atexit_stack, stack_size); 00298 } 00299 #endif 00300 00301 mrb->atexit_stack[mrb->atexit_stack_len++] = f; 00302 } 00303
Generated on Tue Jul 12 2022 18:00:35 by 1.7.2