- Timestamp:
- Jul 9, 2020, 8:51:43 AM (4 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-2.1.1
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-fiber/src/fiber.c
r331 r439 73 73 size_t slen; 74 74 75 mrb_get_args(mrb, "& ", &blk);75 mrb_get_args(mrb, "&!", &blk); 76 76 77 77 if (f->cxt) { 78 78 mrb_raise(mrb, E_RUNTIME_ERROR, "cannot initialize twice"); 79 }80 if (mrb_nil_p(blk)) {81 mrb_raise(mrb, E_ARGUMENT_ERROR, "tried to create Fiber object without a block");82 79 } 83 80 p = mrb_proc_ptr(blk); … … 124 121 /* adjust return callinfo */ 125 122 ci = c->ci; 126 ci->target_class = p->target_class;123 ci->target_class = MRB_PROC_TARGET_CLASS(p); 127 124 ci->proc = p; 125 mrb_field_write_barrier(mrb, (struct RBasic*)mrb_obj_ptr(self), (struct RBasic*)p); 128 126 ci->pc = p->body.irep->iseq; 129 ci->nregs = p->body.irep->nregs;130 127 ci[1] = ci[0]; 131 128 c->ci++; /* push dummy callinfo */ … … 187 184 struct mrb_context *c = fiber_check(mrb, self); 188 185 struct mrb_context *old_c = mrb->c; 186 enum mrb_fiber_state status; 189 187 mrb_value value; 190 188 191 189 fiber_check_cfunc(mrb, c); 192 if (resume && c->status == MRB_FIBER_TRANSFERRED) { 193 mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber"); 194 } 195 if (c->status == MRB_FIBER_RUNNING || c->status == MRB_FIBER_RESUMED) { 196 mrb_raise(mrb, E_FIBER_ERROR, "double resume (fib)"); 197 } 198 if (c->status == MRB_FIBER_TERMINATED) { 190 status = c->status; 191 switch (status) { 192 case MRB_FIBER_TRANSFERRED: 193 if (resume) { 194 mrb_raise(mrb, E_FIBER_ERROR, "resuming transferred fiber"); 195 } 196 break; 197 case MRB_FIBER_RUNNING: 198 case MRB_FIBER_RESUMED: 199 mrb_raise(mrb, E_FIBER_ERROR, "double resume"); 200 break; 201 case MRB_FIBER_TERMINATED: 199 202 mrb_raise(mrb, E_FIBER_ERROR, "resuming dead fiber"); 200 } 201 mrb->c->status = resume ? MRB_FIBER_RESUMED : MRB_FIBER_TRANSFERRED; 203 break; 204 default: 205 break; 206 } 207 old_c->status = resume ? MRB_FIBER_RESUMED : MRB_FIBER_TRANSFERRED; 202 208 c->prev = resume ? mrb->c : (c->prev ? c->prev : mrb->root_c); 203 if (c->status == MRB_FIBER_CREATED) { 209 fiber_switch_context(mrb, c); 210 if (status == MRB_FIBER_CREATED) { 204 211 mrb_value *b, *e; 205 212 206 if ( len >= c->stend - c->stack) {207 mrb_raise(mrb, E_FIBER_ERROR, " too many arguments to fiber");213 if (!c->ci->proc) { 214 mrb_raise(mrb, E_FIBER_ERROR, "double resume (current)"); 208 215 } 216 mrb_stack_extend(mrb, len+2); /* for receiver and (optional) block */ 209 217 b = c->stack+1; 210 218 e = b + len; … … 212 220 *b++ = *a++; 213 221 } 214 c->cibase->argc = len;215 value = c->stack[0] = c->ci->proc->env->stack[0];222 c->cibase->argc = (int)len; 223 value = c->stack[0] = MRB_PROC_ENV(c->ci->proc)->stack[0]; 216 224 } 217 225 else { 218 226 value = fiber_result(mrb, a, len); 219 227 } 220 fiber_switch_context(mrb, c);221 228 222 229 if (vmexec) { … … 253 260 mrb_bool vmexec = FALSE; 254 261 255 mrb_get_args(mrb, "* ", &a, &len);262 mrb_get_args(mrb, "*!", &a, &len); 256 263 if (mrb->c->ci->acc < 0) { 257 264 vmexec = TRUE; … … 274 281 * execution of the fiber block this method will always return false. 275 282 */ 276 staticmrb_value277 fiber_alive_p(mrb_state *mrb, mrb_value self)283 MRB_API mrb_value 284 mrb_fiber_alive_p(mrb_state *mrb, mrb_value self) 278 285 { 279 286 struct mrb_context *c = fiber_check(mrb, self); 280 287 return mrb_bool_value(c->status != MRB_FIBER_TERMINATED); 281 288 } 289 #define fiber_alive_p mrb_fiber_alive_p 282 290 283 291 static mrb_value … … 287 295 mrb_get_args(mrb, "o", &other); 288 296 289 if ( mrb_type(other) != MRB_TT_FIBER) {297 if (!mrb_fiber_p(other)) { 290 298 return mrb_false_value(); 291 299 } … … 313 321 314 322 fiber_check_cfunc(mrb, mrb->c); 315 mrb_get_args(mrb, "* ", &a, &len);323 mrb_get_args(mrb, "*!", &a, &len); 316 324 317 325 if (c == mrb->root_c) { … … 371 379 mrb_int len; 372 380 373 mrb_get_args(mrb, "* ", &a, &len);381 mrb_get_args(mrb, "*!", &a, &len); 374 382 return mrb_fiber_yield(mrb, len, a); 375 383 } … … 402 410 MRB_SET_INSTANCE_TT(c, MRB_TT_FIBER); 403 411 404 mrb_define_method(mrb, c, "initialize", fiber_init, MRB_ARGS_NONE() );412 mrb_define_method(mrb, c, "initialize", fiber_init, MRB_ARGS_NONE()|MRB_ARGS_BLOCK()); 405 413 mrb_define_method(mrb, c, "resume", fiber_resume, MRB_ARGS_ANY()); 406 414 mrb_define_method(mrb, c, "transfer", fiber_transfer, MRB_ARGS_ANY());
Note:
See TracChangeset
for help on using the changeset viewer.