mbed I/F binding for mruby

Dependents:   mruby_mbed_web mirb_mbed

mbed-mruby

How to use

Class

Committer:
mzta
Date:
Mon Apr 13 05:20:15 2015 +0000
Revision:
1:8ccd1d494a4b
Parent:
0:158c61bb030f
- code refactoring.; - add SPI, SPISlave, I2C class to mruby-mbed (Incomplete).

Who changed what in which revision?

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