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 #include "mruby.h"
mzta 0:158c61bb030f 2 #include "mruby/array.h"
mzta 0:158c61bb030f 3 #include "mruby/class.h"
mzta 0:158c61bb030f 4 #include "mruby/proc.h"
mzta 0:158c61bb030f 5
mzta 0:158c61bb030f 6 #define fiber_ptr(o) ((struct RFiber*)mrb_ptr(o))
mzta 0:158c61bb030f 7
mzta 0:158c61bb030f 8 #define FIBER_STACK_INIT_SIZE 64
mzta 0:158c61bb030f 9 #define FIBER_CI_INIT_SIZE 8
mzta 0:158c61bb030f 10
mzta 0:158c61bb030f 11 /*
mzta 0:158c61bb030f 12 * call-seq:
mzta 0:158c61bb030f 13 * Fiber.new{...} -> obj
mzta 0:158c61bb030f 14 *
mzta 0:158c61bb030f 15 * Creates a fiber, whose execution is suspend until it is explicitly
mzta 0:158c61bb030f 16 * resumed using <code>Fiber#resume</code> method.
mzta 0:158c61bb030f 17 * The code running inside the fiber can give up control by calling
mzta 0:158c61bb030f 18 * <code>Fiber.yield</code> in which case it yields control back to caller
mzta 0:158c61bb030f 19 * (the caller of the <code>Fiber#resume</code>).
mzta 0:158c61bb030f 20 *
mzta 0:158c61bb030f 21 * Upon yielding or termination the Fiber returns the value of the last
mzta 0:158c61bb030f 22 * executed expression
mzta 0:158c61bb030f 23 *
mzta 0:158c61bb030f 24 * For instance:
mzta 0:158c61bb030f 25 *
mzta 0:158c61bb030f 26 * fiber = Fiber.new do
mzta 0:158c61bb030f 27 * Fiber.yield 1
mzta 0:158c61bb030f 28 * 2
mzta 0:158c61bb030f 29 * end
mzta 0:158c61bb030f 30 *
mzta 0:158c61bb030f 31 * puts fiber.resume
mzta 0:158c61bb030f 32 * puts fiber.resume
mzta 0:158c61bb030f 33 * puts fiber.resume
mzta 0:158c61bb030f 34 *
mzta 0:158c61bb030f 35 * <em>produces</em>
mzta 0:158c61bb030f 36 *
mzta 0:158c61bb030f 37 * 1
mzta 0:158c61bb030f 38 * 2
mzta 0:158c61bb030f 39 * resuming dead fiber (FiberError)
mzta 0:158c61bb030f 40 *
mzta 0:158c61bb030f 41 * The <code>Fiber#resume</code> method accepts an arbitrary number of
mzta 0:158c61bb030f 42 * parameters, if it is the first call to <code>resume</code> then they
mzta 0:158c61bb030f 43 * will be passed as block arguments. Otherwise they will be the return
mzta 0:158c61bb030f 44 * value of the call to <code>Fiber.yield</code>
mzta 0:158c61bb030f 45 *
mzta 0:158c61bb030f 46 * Example:
mzta 0:158c61bb030f 47 *
mzta 0:158c61bb030f 48 * fiber = Fiber.new do |first|
mzta 0:158c61bb030f 49 * second = Fiber.yield first + 2
mzta 0:158c61bb030f 50 * end
mzta 0:158c61bb030f 51 *
mzta 0:158c61bb030f 52 * puts fiber.resume 10
mzta 0:158c61bb030f 53 * puts fiber.resume 14
mzta 0:158c61bb030f 54 * puts fiber.resume 18
mzta 0:158c61bb030f 55 *
mzta 0:158c61bb030f 56 * <em>produces</em>
mzta 0:158c61bb030f 57 *
mzta 0:158c61bb030f 58 * 12
mzta 0:158c61bb030f 59 * 14
mzta 0:158c61bb030f 60 * resuming dead fiber (FiberError)
mzta 0:158c61bb030f 61 *
mzta 0:158c61bb030f 62 */
mzta 0:158c61bb030f 63 static mrb_value
mzta 0:158c61bb030f 64 fiber_init(mrb_state *mrb, mrb_value self)
mzta 0:158c61bb030f 65 {
mzta 0:158c61bb030f 66 static const struct mrb_context mrb_context_zero = { 0 };
mzta 0:158c61bb030f 67 struct RFiber *f = fiber_ptr(self);
mzta 0:158c61bb030f 68 struct mrb_context *c;
mzta 0:158c61bb030f 69 struct RProc *p;
mzta 0:158c61bb030f 70 mrb_callinfo *ci;
mzta 0:158c61bb030f 71 mrb_value blk;
mzta 0:158c61bb030f 72 size_t slen;
mzta 0:158c61bb030f 73
mzta 0:158c61bb030f 74 mrb_get_args(mrb, "&", &blk);
mzta 0:158c61bb030f 75
mzta 0:158c61bb030f 76 if (mrb_nil_p(blk)) {
mzta 0:158c61bb030f 77 mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Fiber object without a block");
mzta 0:158c61bb030f 78 }
mzta 0:158c61bb030f 79 p = mrb_proc_ptr(blk);
mzta 0:158c61bb030f 80 if (MRB_PROC_CFUNC_P(p)) {
mzta 0:158c61bb030f 81 mrb_raise(mrb, E_FIBER_ERROR, "tried to create Fiber from C defined method");
mzta 0:158c61bb030f 82 }
mzta 0:158c61bb030f 83
mzta 0:158c61bb030f 84 f->cxt = (struct mrb_context*)mrb_malloc(mrb, sizeof(struct mrb_context));
mzta 0:158c61bb030f 85 *f->cxt = mrb_context_zero;
mzta 0:158c61bb030f 86 c = f->cxt;
mzta 0:158c61bb030f 87
mzta 0:158c61bb030f 88 /* initialize VM stack */
mzta 0:158c61bb030f 89 slen = FIBER_STACK_INIT_SIZE;
mzta 0:158c61bb030f 90 if (p->body.irep->nregs > slen) {
mzta 0:158c61bb030f 91 slen += p->body.irep->nregs;
mzta 0:158c61bb030f 92 }
mzta 0:158c61bb030f 93 c->stbase = (mrb_value *)mrb_malloc(mrb, slen*sizeof(mrb_value));
mzta 0:158c61bb030f 94 c->stend = c->stbase + slen;
mzta 0:158c61bb030f 95 c->stack = c->stbase;
mzta 0:158c61bb030f 96
mzta 0:158c61bb030f 97 #ifdef MRB_NAN_BOXING
mzta 0:158c61bb030f 98 {
mzta 0:158c61bb030f 99 mrb_value *p = c->stbase;
mzta 0:158c61bb030f 100 mrb_value *pend = c->stend;
mzta 0:158c61bb030f 101
mzta 0:158c61bb030f 102 while (p < pend) {
mzta 0:158c61bb030f 103 SET_NIL_VALUE(*p);
mzta 0:158c61bb030f 104 p++;
mzta 0:158c61bb030f 105 }
mzta 0:158c61bb030f 106 }
mzta 0:158c61bb030f 107 #else
mzta 0:158c61bb030f 108 memset(c->stbase, 0, slen * sizeof(mrb_value));
mzta 0:158c61bb030f 109 #endif
mzta 0:158c61bb030f 110
mzta 0:158c61bb030f 111 /* copy receiver from a block */
mzta 0:158c61bb030f 112 c->stack[0] = mrb->c->stack[0];
mzta 0:158c61bb030f 113
mzta 0:158c61bb030f 114 /* initialize callinfo stack */
mzta 0:158c61bb030f 115 c->cibase = (mrb_callinfo *)mrb_calloc(mrb, FIBER_CI_INIT_SIZE, sizeof(mrb_callinfo));
mzta 0:158c61bb030f 116 c->ciend = c->cibase + FIBER_CI_INIT_SIZE;
mzta 0:158c61bb030f 117 c->ci = c->cibase;
mzta 0:158c61bb030f 118 c->ci->stackent = c->stack;
mzta 0:158c61bb030f 119
mzta 0:158c61bb030f 120 /* adjust return callinfo */
mzta 0:158c61bb030f 121 ci = c->ci;
mzta 0:158c61bb030f 122 ci->target_class = p->target_class;
mzta 0:158c61bb030f 123 ci->proc = p;
mzta 0:158c61bb030f 124 ci->pc = p->body.irep->iseq;
mzta 0:158c61bb030f 125 ci->nregs = p->body.irep->nregs;
mzta 0:158c61bb030f 126 ci[1] = ci[0];
mzta 0:158c61bb030f 127 c->ci++; /* push dummy callinfo */
mzta 0:158c61bb030f 128
mzta 0:158c61bb030f 129 c->fib = f;
mzta 0:158c61bb030f 130 c->status = MRB_FIBER_CREATED;
mzta 0:158c61bb030f 131
mzta 0:158c61bb030f 132 return self;
mzta 0:158c61bb030f 133 }
mzta 0:158c61bb030f 134
mzta 0:158c61bb030f 135 static struct mrb_context*
mzta 0:158c61bb030f 136 fiber_check(mrb_state *mrb, mrb_value fib)
mzta 0:158c61bb030f 137 {
mzta 0:158c61bb030f 138 struct RFiber *f = fiber_ptr(fib);
mzta 0:158c61bb030f 139
mzta 0:158c61bb030f 140 mrb_assert(f->tt == MRB_TT_FIBER);
mzta 0:158c61bb030f 141 if (!f->cxt) {
mzta 0:158c61bb030f 142 mrb_raise(mrb, E_FIBER_ERROR, "uninitialized Fiber");
mzta 0:158c61bb030f 143 }
mzta 0:158c61bb030f 144 return f->cxt;
mzta 0:158c61bb030f 145 }
mzta 0:158c61bb030f 146
mzta 0:158c61bb030f 147 static mrb_value
mzta 0:158c61bb030f 148 fiber_result(mrb_state *mrb, const mrb_value *a, mrb_int len)
mzta 0:158c61bb030f 149 {
mzta 0:158c61bb030f 150 if (len == 0) return mrb_nil_value();
mzta 0:158c61bb030f 151 if (len == 1) return a[0];
mzta 0:158c61bb030f 152 return mrb_ary_new_from_values(mrb, len, a);
mzta 0:158c61bb030f 153 }
mzta 0:158c61bb030f 154
mzta 0:158c61bb030f 155 /* mark return from context modifying method */
mzta 0:158c61bb030f 156 #define MARK_CONTEXT_MODIFY(c) (c)->ci->target_class = NULL
mzta 0:158c61bb030f 157
mzta 0:158c61bb030f 158 static mrb_value
mzta 0:158c61bb030f 159 fiber_switch(mrb_state *mrb, mrb_value self, mrb_int len, const mrb_value *a, mrb_bool resume)
mzta 0:158c61bb030f 160 {
mzta 0:158c61bb030f 161 struct mrb_context *c = fiber_check(mrb, self);
mzta 0:158c61bb030f 162 mrb_callinfo *ci;
mzta 0:158c61bb030f 163
mzta 0:158c61bb030f 164 for (ci = c->ci; ci >= c->cibase; ci--) {
mzta 0:158c61bb030f 165 if (ci->acc < 0) {
mzta 0:158c61bb030f 166 mrb_raise(mrb, E_FIBER_ERROR, "can't cross C function boundary");
mzta 0:158c61bb030f 167 }
mzta 0:158c61bb030f 168 }
mzta 0:158c61bb030f 169 if (resume && c->status == MRB_FIBER_TRANSFERRED) {
mzta 0:158c61bb030f 170 mrb_raise(mrb, E_FIBER_ERROR, "resuming transfered fiber");
mzta 0:158c61bb030f 171 }
mzta 0:158c61bb030f 172 if (c->status == MRB_FIBER_RUNNING || c->status == MRB_FIBER_RESUMING) {
mzta 0:158c61bb030f 173 mrb_raise(mrb, E_FIBER_ERROR, "double resume");
mzta 0:158c61bb030f 174 }
mzta 0:158c61bb030f 175 if (c->status == MRB_FIBER_TERMINATED) {
mzta 0:158c61bb030f 176 mrb_raise(mrb, E_FIBER_ERROR, "resuming dead fiber");
mzta 0:158c61bb030f 177 }
mzta 0:158c61bb030f 178 mrb->c->status = resume ? MRB_FIBER_RESUMING : MRB_FIBER_TRANSFERRED;
mzta 0:158c61bb030f 179 c->prev = resume ? mrb->c : (c->prev ? c->prev : mrb->root_c);
mzta 0:158c61bb030f 180 if (c->status == MRB_FIBER_CREATED) {
mzta 0:158c61bb030f 181 mrb_value *b = c->stack+1;
mzta 0:158c61bb030f 182 mrb_value *e = b + len;
mzta 0:158c61bb030f 183
mzta 0:158c61bb030f 184 while (b<e) {
mzta 0:158c61bb030f 185 *b++ = *a++;
mzta 0:158c61bb030f 186 }
mzta 0:158c61bb030f 187 c->cibase->argc = len;
mzta 0:158c61bb030f 188 if (c->prev->fib)
mzta 0:158c61bb030f 189 mrb_field_write_barrier(mrb, (struct RBasic*)c->fib, (struct RBasic*)c->prev->fib);
mzta 0:158c61bb030f 190 mrb_write_barrier(mrb, (struct RBasic*)c->fib);
mzta 0:158c61bb030f 191 c->status = MRB_FIBER_RUNNING;
mzta 0:158c61bb030f 192 mrb->c = c;
mzta 0:158c61bb030f 193
mzta 0:158c61bb030f 194 MARK_CONTEXT_MODIFY(c);
mzta 0:158c61bb030f 195 return c->ci->proc->env->stack[0];
mzta 0:158c61bb030f 196 }
mzta 0:158c61bb030f 197 MARK_CONTEXT_MODIFY(c);
mzta 0:158c61bb030f 198 if (c->prev->fib)
mzta 0:158c61bb030f 199 mrb_field_write_barrier(mrb, (struct RBasic*)c->fib, (struct RBasic*)c->prev->fib);
mzta 0:158c61bb030f 200 mrb_write_barrier(mrb, (struct RBasic*)c->fib);
mzta 0:158c61bb030f 201 c->status = MRB_FIBER_RUNNING;
mzta 0:158c61bb030f 202 mrb->c = c;
mzta 0:158c61bb030f 203 return fiber_result(mrb, a, len);
mzta 0:158c61bb030f 204 }
mzta 0:158c61bb030f 205
mzta 0:158c61bb030f 206 /*
mzta 0:158c61bb030f 207 * call-seq:
mzta 0:158c61bb030f 208 * fiber.resume(args, ...) -> obj
mzta 0:158c61bb030f 209 *
mzta 0:158c61bb030f 210 * Resumes the fiber from the point at which the last <code>Fiber.yield</code>
mzta 0:158c61bb030f 211 * was called, or starts running it if it is the first call to
mzta 0:158c61bb030f 212 * <code>resume</code>. Arguments passed to resume will be the value of
mzta 0:158c61bb030f 213 * the <code>Fiber.yield</code> expression or will be passed as block
mzta 0:158c61bb030f 214 * parameters to the fiber's block if this is the first <code>resume</code>.
mzta 0:158c61bb030f 215 *
mzta 0:158c61bb030f 216 * Alternatively, when resume is called it evaluates to the arguments passed
mzta 0:158c61bb030f 217 * to the next <code>Fiber.yield</code> statement inside the fiber's block
mzta 0:158c61bb030f 218 * or to the block value if it runs to completion without any
mzta 0:158c61bb030f 219 * <code>Fiber.yield</code>
mzta 0:158c61bb030f 220 */
mzta 0:158c61bb030f 221 static mrb_value
mzta 0:158c61bb030f 222 fiber_resume(mrb_state *mrb, mrb_value self)
mzta 0:158c61bb030f 223 {
mzta 0:158c61bb030f 224 mrb_value *a;
mzta 0:158c61bb030f 225 mrb_int len;
mzta 0:158c61bb030f 226
mzta 0:158c61bb030f 227 mrb_get_args(mrb, "*", &a, &len);
mzta 0:158c61bb030f 228 return fiber_switch(mrb, self, len, a, TRUE);
mzta 0:158c61bb030f 229 }
mzta 0:158c61bb030f 230
mzta 0:158c61bb030f 231 /*
mzta 0:158c61bb030f 232 * call-seq:
mzta 0:158c61bb030f 233 * fiber.alive? -> true or false
mzta 0:158c61bb030f 234 *
mzta 0:158c61bb030f 235 * Returns true if the fiber can still be resumed. After finishing
mzta 0:158c61bb030f 236 * execution of the fiber block this method will always return false.
mzta 0:158c61bb030f 237 */
mzta 0:158c61bb030f 238 static mrb_value
mzta 0:158c61bb030f 239 fiber_alive_p(mrb_state *mrb, mrb_value self)
mzta 0:158c61bb030f 240 {
mzta 0:158c61bb030f 241 struct mrb_context *c = fiber_check(mrb, self);
mzta 0:158c61bb030f 242 return mrb_bool_value(c->status != MRB_FIBER_TERMINATED);
mzta 0:158c61bb030f 243 }
mzta 0:158c61bb030f 244
mzta 0:158c61bb030f 245 static mrb_value
mzta 0:158c61bb030f 246 fiber_eq(mrb_state *mrb, mrb_value self)
mzta 0:158c61bb030f 247 {
mzta 0:158c61bb030f 248 mrb_value other;
mzta 0:158c61bb030f 249 mrb_get_args(mrb, "o", &other);
mzta 0:158c61bb030f 250
mzta 0:158c61bb030f 251 if (mrb_type(other) != MRB_TT_FIBER) {
mzta 0:158c61bb030f 252 return mrb_false_value();
mzta 0:158c61bb030f 253 }
mzta 0:158c61bb030f 254 return mrb_bool_value(fiber_ptr(self) == fiber_ptr(other));
mzta 0:158c61bb030f 255 }
mzta 0:158c61bb030f 256
mzta 0:158c61bb030f 257 /*
mzta 0:158c61bb030f 258 * call-seq:
mzta 0:158c61bb030f 259 * fiber.transfer(args, ...) -> obj
mzta 0:158c61bb030f 260 *
mzta 0:158c61bb030f 261 * Transfers control to reciever fiber of the method call.
mzta 0:158c61bb030f 262 * Unlike <code>resume</code> the reciever wouldn't be pushed to call
mzta 0:158c61bb030f 263 * stack of fibers. Instead it will switch to the call stack of
mzta 0:158c61bb030f 264 * transferring fiber.
mzta 0:158c61bb030f 265 * When resuming a fiber that was transferred to another fiber it would
mzta 0:158c61bb030f 266 * cause double resume error. Though when the fiber is re-transferred
mzta 0:158c61bb030f 267 * and <code>Fiber.yield</code> is called, the fiber would be resumable.
mzta 0:158c61bb030f 268 */
mzta 0:158c61bb030f 269 static mrb_value
mzta 0:158c61bb030f 270 fiber_transfer(mrb_state *mrb, mrb_value self)
mzta 0:158c61bb030f 271 {
mzta 0:158c61bb030f 272 struct mrb_context *c = fiber_check(mrb, self);
mzta 0:158c61bb030f 273 mrb_value* a;
mzta 0:158c61bb030f 274 mrb_int len;
mzta 0:158c61bb030f 275
mzta 0:158c61bb030f 276 mrb_get_args(mrb, "*", &a, &len);
mzta 0:158c61bb030f 277
mzta 0:158c61bb030f 278 if (c == mrb->root_c) {
mzta 0:158c61bb030f 279 mrb->c->status = MRB_FIBER_TRANSFERRED;
mzta 0:158c61bb030f 280 mrb->c = c;
mzta 0:158c61bb030f 281 c->status = MRB_FIBER_RUNNING;
mzta 0:158c61bb030f 282 MARK_CONTEXT_MODIFY(c);
mzta 0:158c61bb030f 283 mrb_write_barrier(mrb, (struct RBasic*)c->fib);
mzta 0:158c61bb030f 284 return fiber_result(mrb, a, len);
mzta 0:158c61bb030f 285 }
mzta 0:158c61bb030f 286
mzta 0:158c61bb030f 287 if (c == mrb->c) {
mzta 0:158c61bb030f 288 return fiber_result(mrb, a, len);
mzta 0:158c61bb030f 289 }
mzta 0:158c61bb030f 290
mzta 0:158c61bb030f 291 return fiber_switch(mrb, self, len, a, FALSE);
mzta 0:158c61bb030f 292 }
mzta 0:158c61bb030f 293
mzta 0:158c61bb030f 294 MRB_API mrb_value
mzta 0:158c61bb030f 295 mrb_fiber_yield(mrb_state *mrb, mrb_int len, const mrb_value *a)
mzta 0:158c61bb030f 296 {
mzta 0:158c61bb030f 297 struct mrb_context *c = mrb->c;
mzta 0:158c61bb030f 298 mrb_callinfo *ci;
mzta 0:158c61bb030f 299
mzta 0:158c61bb030f 300 for (ci = c->ci; ci >= c->cibase; ci--) {
mzta 0:158c61bb030f 301 if (ci->acc < 0) {
mzta 0:158c61bb030f 302 mrb_raise(mrb, E_FIBER_ERROR, "can't cross C function boundary");
mzta 0:158c61bb030f 303 }
mzta 0:158c61bb030f 304 }
mzta 0:158c61bb030f 305 if (!c->prev) {
mzta 0:158c61bb030f 306 mrb_raise(mrb, E_FIBER_ERROR, "can't yield from root fiber");
mzta 0:158c61bb030f 307 }
mzta 0:158c61bb030f 308
mzta 0:158c61bb030f 309 c->prev->status = MRB_FIBER_RUNNING;
mzta 0:158c61bb030f 310 c->status = MRB_FIBER_SUSPENDED;
mzta 0:158c61bb030f 311 mrb->c = c->prev;
mzta 0:158c61bb030f 312 c->prev = NULL;
mzta 0:158c61bb030f 313 MARK_CONTEXT_MODIFY(mrb->c);
mzta 0:158c61bb030f 314 mrb_write_barrier(mrb, (struct RBasic*)c->fib);
mzta 0:158c61bb030f 315 return fiber_result(mrb, a, len);
mzta 0:158c61bb030f 316 }
mzta 0:158c61bb030f 317
mzta 0:158c61bb030f 318 /*
mzta 0:158c61bb030f 319 * call-seq:
mzta 0:158c61bb030f 320 * Fiber.yield(args, ...) -> obj
mzta 0:158c61bb030f 321 *
mzta 0:158c61bb030f 322 * Yields control back to the context that resumed the fiber, passing
mzta 0:158c61bb030f 323 * along any arguments that were passed to it. The fiber will resume
mzta 0:158c61bb030f 324 * processing at this point when <code>resume</code> is called next.
mzta 0:158c61bb030f 325 * Any arguments passed to the next <code>resume</code> will be the
mzta 0:158c61bb030f 326 * value that this <code>Fiber.yield</code> expression evaluates to.
mzta 0:158c61bb030f 327 */
mzta 0:158c61bb030f 328 static mrb_value
mzta 0:158c61bb030f 329 fiber_yield(mrb_state *mrb, mrb_value self)
mzta 0:158c61bb030f 330 {
mzta 0:158c61bb030f 331 mrb_value *a;
mzta 0:158c61bb030f 332 mrb_int len;
mzta 0:158c61bb030f 333
mzta 0:158c61bb030f 334 mrb_get_args(mrb, "*", &a, &len);
mzta 0:158c61bb030f 335 return mrb_fiber_yield(mrb, len, a);
mzta 0:158c61bb030f 336 }
mzta 0:158c61bb030f 337
mzta 0:158c61bb030f 338 /*
mzta 0:158c61bb030f 339 * call-seq:
mzta 0:158c61bb030f 340 * Fiber.current() -> fiber
mzta 0:158c61bb030f 341 *
mzta 0:158c61bb030f 342 * Returns the current fiber. If you are not running in the context of
mzta 0:158c61bb030f 343 * a fiber this method will return the root fiber.
mzta 0:158c61bb030f 344 */
mzta 0:158c61bb030f 345 static mrb_value
mzta 0:158c61bb030f 346 fiber_current(mrb_state *mrb, mrb_value self)
mzta 0:158c61bb030f 347 {
mzta 0:158c61bb030f 348 if (!mrb->c->fib) {
mzta 0:158c61bb030f 349 struct RFiber *f = (struct RFiber*)mrb_obj_alloc(mrb, MRB_TT_FIBER, mrb_class_ptr(self));
mzta 0:158c61bb030f 350
mzta 0:158c61bb030f 351 f->cxt = mrb->c;
mzta 0:158c61bb030f 352 mrb->c->fib = f;
mzta 0:158c61bb030f 353 }
mzta 0:158c61bb030f 354 return mrb_obj_value(mrb->c->fib);
mzta 0:158c61bb030f 355 }
mzta 0:158c61bb030f 356
mzta 0:158c61bb030f 357 void
mzta 0:158c61bb030f 358 mrb_mruby_fiber_gem_init(mrb_state* mrb)
mzta 0:158c61bb030f 359 {
mzta 0:158c61bb030f 360 struct RClass *c;
mzta 0:158c61bb030f 361
mzta 0:158c61bb030f 362 c = mrb_define_class(mrb, "Fiber", mrb->object_class);
mzta 0:158c61bb030f 363 MRB_SET_INSTANCE_TT(c, MRB_TT_FIBER);
mzta 0:158c61bb030f 364
mzta 0:158c61bb030f 365 mrb_define_method(mrb, c, "initialize", fiber_init, MRB_ARGS_NONE());
mzta 0:158c61bb030f 366 mrb_define_method(mrb, c, "resume", fiber_resume, MRB_ARGS_ANY());
mzta 0:158c61bb030f 367 mrb_define_method(mrb, c, "transfer", fiber_transfer, MRB_ARGS_ANY());
mzta 0:158c61bb030f 368 mrb_define_method(mrb, c, "alive?", fiber_alive_p, MRB_ARGS_NONE());
mzta 0:158c61bb030f 369 mrb_define_method(mrb, c, "==", fiber_eq, MRB_ARGS_REQ(1));
mzta 0:158c61bb030f 370
mzta 0:158c61bb030f 371 mrb_define_class_method(mrb, c, "yield", fiber_yield, MRB_ARGS_ANY());
mzta 0:158c61bb030f 372 mrb_define_class_method(mrb, c, "current", fiber_current, MRB_ARGS_NONE());
mzta 0:158c61bb030f 373
mzta 0:158c61bb030f 374 mrb_define_class(mrb, "FiberError", mrb->eStandardError_class);
mzta 0:158c61bb030f 375 }
mzta 0:158c61bb030f 376
mzta 0:158c61bb030f 377 void
mzta 0:158c61bb030f 378 mrb_mruby_fiber_gem_final(mrb_state* mrb)
mzta 0:158c61bb030f 379 {
mzta 0:158c61bb030f 380 }
mzta 0:158c61bb030f 381