Changeset 439 for EcnlProtoTool/trunk/mruby-2.1.1/src/vm.c
- 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/src/vm.c
r331 r439 7 7 #include <stddef.h> 8 8 #include <stdarg.h> 9 #ifndef MRB_WITHOUT_FLOAT 9 10 #include <math.h> 11 #endif 10 12 #include <mruby.h> 11 13 #include <mruby/array.h> … … 23 25 #include <mruby/throw.h> 24 26 25 #if ndef MRB_DISABLE_STDIO27 #ifdef MRB_DISABLE_STDIO 26 28 #if defined(__cplusplus) 27 29 extern "C" { … … 52 54 #ifndef MRB_FUNCALL_DEPTH_MAX 53 55 #define MRB_FUNCALL_DEPTH_MAX 512 56 #endif 57 58 /* Maximum depth of ecall() recursion. */ 59 #ifndef MRB_ECALL_DEPTH_MAX 60 #define MRB_ECALL_DEPTH_MAX 512 54 61 #endif 55 62 … … 66 73 #endif 67 74 68 #define ARENA_RESTORE(mrb,ai) (mrb)->gc.arena_idx = (ai) 75 76 #ifndef MRB_GC_FIXED_ARENA 77 static void 78 mrb_gc_arena_shrink(mrb_state *mrb, int idx) 79 { 80 mrb_gc *gc = &mrb->gc; 81 int capa = gc->arena_capa; 82 83 if (idx < capa / 4) { 84 capa >>= 2; 85 if (capa < MRB_GC_ARENA_SIZE) { 86 capa = MRB_GC_ARENA_SIZE; 87 } 88 if (capa != gc->arena_capa) { 89 gc->arena = (struct RBasic**)mrb_realloc(mrb, gc->arena, sizeof(struct RBasic*)*capa); 90 gc->arena_capa = capa; 91 } 92 } 93 } 94 #else 95 #define mrb_gc_arena_shrink(mrb,idx) 96 #endif 69 97 70 98 #define CALL_MAXARGS 127 … … 116 144 117 145 static inline void 118 envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t size)146 envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t oldsize) 119 147 { 120 148 mrb_callinfo *ci = mrb->c->cibase; … … 126 154 127 155 if (e && MRB_ENV_STACK_SHARED_P(e) && 128 (st = e->stack) && oldbase <= st && st < oldbase+ size) {156 (st = e->stack) && oldbase <= st && st < oldbase+oldsize) { 129 157 ptrdiff_t off = e->stack - oldbase; 130 158 131 159 e->stack = newbase + off; 132 160 } 161 162 if (ci->proc && MRB_PROC_ENV_P(ci->proc) && ci->env != MRB_PROC_ENV(ci->proc)) { 163 e = MRB_PROC_ENV(ci->proc); 164 165 if (e && MRB_ENV_STACK_SHARED_P(e) && 166 (st = e->stack) && oldbase <= st && st < oldbase+oldsize) { 167 ptrdiff_t off = e->stack - oldbase; 168 169 e->stack = newbase + off; 170 } 171 } 172 133 173 ci->stackent = newbase + (ci->stackent - oldbase); 134 174 ci++; … … 139 179 140 180 static void 141 stack_extend_alloc(mrb_state *mrb, int room)181 stack_extend_alloc(mrb_state *mrb, mrb_int room) 142 182 { 143 183 mrb_value *oldbase = mrb->c->stbase; … … 149 189 if (off > size) size = off; 150 190 #ifdef MRB_STACK_EXTEND_DOUBLING 151 if ( room <= size)191 if ((size_t)room <= size) 152 192 size *= 2; 153 193 else … … 168 208 } 169 209 stack_clear(&(newstack[oldsize]), size - oldsize); 170 envadjust(mrb, oldbase, newstack, size);210 envadjust(mrb, oldbase, newstack, oldsize); 171 211 mrb->c->stbase = newstack; 172 212 mrb->c->stack = mrb->c->stbase + off; … … 180 220 } 181 221 182 static inlinevoid183 stack_extend(mrb_state *mrb,int room)222 MRB_API void 223 mrb_stack_extend(mrb_state *mrb, mrb_int room) 184 224 { 185 225 if (mrb->c->stack + room >= mrb->c->stend) { … … 191 231 uvenv(mrb_state *mrb, int up) 192 232 { 193 struct REnv *e = mrb->c->ci->proc->env; 233 struct RProc *proc = mrb->c->ci->proc; 234 struct REnv *e; 194 235 195 236 while (up--) { 196 if (!e) return NULL; 197 e = (struct REnv*)e->c; 198 } 199 return e; 200 } 201 202 static inline mrb_bool 203 is_strict(mrb_state *mrb, struct REnv *e) 204 { 205 int cioff = e->cioff; 206 207 if (MRB_ENV_STACK_SHARED_P(e) && e->cxt.c->cibase[cioff].proc && 208 MRB_PROC_STRICT_P(e->cxt.c->cibase[cioff].proc)) { 209 return TRUE; 210 } 211 return FALSE; 212 } 213 214 static inline struct REnv* 215 top_env(mrb_state *mrb, struct RProc *proc) 216 { 217 struct REnv *e = proc->env; 218 219 if (is_strict(mrb, e)) return e; 220 while (e->c) { 221 e = (struct REnv*)e->c; 222 if (is_strict(mrb, e)) return e; 223 } 224 return e; 237 proc = proc->upper; 238 if (!proc) return NULL; 239 } 240 e = MRB_PROC_ENV(proc); 241 if (e) return e; /* proc has enclosed env */ 242 else { 243 mrb_callinfo *ci = mrb->c->ci; 244 mrb_callinfo *cb = mrb->c->cibase; 245 246 while (cb <= ci) { 247 if (ci->proc == proc) { 248 return ci->env; 249 } 250 ci--; 251 } 252 } 253 return NULL; 254 } 255 256 static inline struct RProc* 257 top_proc(mrb_state *mrb, struct RProc *proc) 258 { 259 while (proc->upper) { 260 if (MRB_PROC_SCOPE_P(proc) || MRB_PROC_STRICT_P(proc)) 261 return proc; 262 proc = proc->upper; 263 } 264 return proc; 225 265 } 226 266 … … 229 269 #define CI_ACC_RESUMED -3 230 270 231 static mrb_callinfo*271 static inline mrb_callinfo* 232 272 cipush(mrb_state *mrb) 233 273 { 234 274 struct mrb_context *c = mrb->c; 275 static const mrb_callinfo ci_zero = { 0 }; 235 276 mrb_callinfo *ci = c->ci; 236 277 … … 245 286 } 246 287 ci = ++c->ci; 288 *ci = ci_zero; 247 289 ci->epos = mrb->c->eidx; 248 290 ci->ridx = ridx; 249 ci->env = 0;250 ci->pc = 0;251 ci->err = 0;252 ci->proc = 0;253 ci->acc = 0;254 291 255 292 return ci; 256 293 } 257 294 258 MRB_APIvoid295 void 259 296 mrb_env_unshare(mrb_state *mrb, struct REnv *e) 260 297 { 261 size_t len = (size_t)MRB_ENV_STACK_LEN(e); 262 ptrdiff_t cioff = e->cioff; 263 mrb_value *p; 264 265 if (!MRB_ENV_STACK_SHARED_P(e)) return; 266 if (e->cxt.c != mrb->c) return; 267 if (e->cioff == 0 && e->cxt.c == mrb->root_c) return; 268 MRB_ENV_UNSHARE_STACK(e); 269 if (!e->c) { 270 /* save block argument position (negated) */ 271 e->cioff = -e->cxt.c->cibase[cioff].argc-1; 272 } 273 e->cxt.mid = e->cxt.c->cibase[cioff].mid; 274 p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len); 275 if (len > 0) { 276 stack_copy(p, e->stack, len); 277 } 278 e->stack = p; 279 mrb_write_barrier(mrb, (struct RBasic *)e); 280 } 281 282 static void 298 if (e == NULL) return; 299 else { 300 size_t len = (size_t)MRB_ENV_STACK_LEN(e); 301 mrb_value *p; 302 303 if (!MRB_ENV_STACK_SHARED_P(e)) return; 304 if (e->cxt != mrb->c) return; 305 if (e == mrb->c->cibase->env) return; /* for mirb */ 306 p = (mrb_value *)mrb_malloc(mrb, sizeof(mrb_value)*len); 307 if (len > 0) { 308 stack_copy(p, e->stack, len); 309 } 310 e->stack = p; 311 MRB_ENV_UNSHARE_STACK(e); 312 mrb_write_barrier(mrb, (struct RBasic *)e); 313 } 314 } 315 316 static inline void 283 317 cipop(mrb_state *mrb) 284 318 { … … 287 321 288 322 c->ci--; 289 290 if (env) { 291 mrb_env_unshare(mrb, env); 292 } 323 if (env) mrb_env_unshare(mrb, env); 293 324 } 294 325 … … 296 327 297 328 static void 298 ecall(mrb_state *mrb , int i)329 ecall(mrb_state *mrb) 299 330 { 300 331 struct RProc *p; 301 mrb_callinfo *ci = mrb->c->ci;302 mrb_ value *self = mrb->c->stack;332 struct mrb_context *c = mrb->c; 333 mrb_callinfo *ci = c->ci; 303 334 struct RObject *exc; 335 struct REnv *env; 304 336 ptrdiff_t cioff; 305 337 int ai = mrb_gc_arena_save(mrb); 338 uint16_t i = --c->eidx; 339 int nregs; 306 340 307 341 if (i<0) return; 308 if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { 342 /* restrict total call depth of ecall() */ 343 if (++mrb->ecall_nest > MRB_ECALL_DEPTH_MAX) { 309 344 mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); 310 345 } 311 p = mrb->c->ensure[i];346 p = c->ensure[i]; 312 347 if (!p) return; 313 mrb->c->ensure[i] = NULL; 314 cioff = ci - mrb->c->cibase; 348 mrb_assert(!MRB_PROC_CFUNC_P(p)); 349 c->ensure[i] = NULL; 350 nregs = p->upper->body.irep->nregs; 351 if (ci->proc && !MRB_PROC_CFUNC_P(ci->proc) && 352 ci->proc->body.irep->nregs > nregs) { 353 nregs = ci->proc->body.irep->nregs; 354 } 355 cioff = ci - c->cibase; 315 356 ci = cipush(mrb); 316 357 ci->stackent = mrb->c->stack; … … 319 360 ci->argc = 0; 320 361 ci->proc = p; 321 ci->nregs = p->body.irep->nregs; 322 ci->target_class = p->target_class; 323 mrb->c->stack = mrb->c->stack + ci[-1].nregs; 362 ci->target_class = MRB_PROC_TARGET_CLASS(p); 363 env = MRB_PROC_ENV(p); 364 mrb_assert(env); 365 c->stack += nregs; 324 366 exc = mrb->exc; mrb->exc = 0; 325 367 if (exc) { 326 368 mrb_gc_protect(mrb, mrb_obj_value(exc)); 327 369 } 328 mrb_run(mrb, p, *self); 329 mrb->c->ci = mrb->c->cibase + cioff; 370 if (mrb->c->fib) { 371 mrb_gc_protect(mrb, mrb_obj_value(mrb->c->fib)); 372 } 373 mrb_run(mrb, p, env->stack[0]); 374 mrb->c = c; 375 c->ci = c->cibase + cioff; 330 376 if (!mrb->exc) mrb->exc = exc; 331 377 mrb_gc_arena_restore(mrb, ai); 378 mrb->ecall_nest--; 332 379 } 333 380 … … 356 403 } 357 404 405 static int 406 ci_nregs(mrb_callinfo *ci) 407 { 408 struct RProc *p; 409 int n = 0; 410 411 if (!ci) return 3; 412 p = ci->proc; 413 if (!p) { 414 if (ci->argc < 0) return 3; 415 return ci->argc+2; 416 } 417 if (!MRB_PROC_CFUNC_P(p) && p->body.irep) { 418 n = p->body.irep->nregs; 419 } 420 if (ci->argc < 0) { 421 if (n < 3) n = 3; /* self + args + blk */ 422 } 423 if (ci->argc > n) { 424 n = ci->argc + 2; /* self + blk */ 425 } 426 return n; 427 } 428 358 429 MRB_API mrb_value 359 430 mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk) 360 431 { 361 432 mrb_value val; 433 int ai = mrb_gc_arena_save(mrb); 362 434 363 435 if (!mrb->jmp) { … … 383 455 } 384 456 else { 385 struct RProc *p;457 mrb_method_t m; 386 458 struct RClass *c; 387 459 mrb_callinfo *ci; 388 int n ;460 int n = ci_nregs(mrb->c->ci); 389 461 ptrdiff_t voff = -1; 390 462 … … 392 464 stack_init(mrb); 393 465 } 394 n = mrb->c->ci->nregs;395 466 if (argc < 0) { 396 mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (% S)", mrb_fixnum_value(argc));467 mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%i)", argc); 397 468 } 398 469 c = mrb_class(mrb, self); 399 p= mrb_method_search_vm(mrb, &c, mid);400 if ( !p) {470 m = mrb_method_search_vm(mrb, &c, mid); 471 if (MRB_METHOD_UNDEF_P(m)) { 401 472 mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); 402 473 mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); 403 p= mrb_method_search_vm(mrb, &c, missing);404 if ( !p) {474 m = mrb_method_search_vm(mrb, &c, missing); 475 if (MRB_METHOD_UNDEF_P(m)) { 405 476 mrb_method_missing(mrb, mid, self, args); 406 477 } 407 478 mrb_ary_unshift(mrb, args, mrb_symbol_value(mid)); 408 stack_extend(mrb, n+2);479 mrb_stack_extend(mrb, n+2); 409 480 mrb->c->stack[n+1] = args; 410 481 argc = -1; … … 415 486 ci = cipush(mrb); 416 487 ci->mid = mid; 417 ci->proc = p;418 488 ci->stackent = mrb->c->stack; 419 ci->argc = argc;489 ci->argc = (int)argc; 420 490 ci->target_class = c; 421 491 mrb->c->stack = mrb->c->stack + n; 492 if (argc < 0) argc = 1; 422 493 if (mrb->c->stbase <= argv && argv < mrb->c->stend) { 423 494 voff = argv - mrb->c->stbase; 424 495 } 425 if (MRB_PROC_CFUNC_P(p)) { 426 ci->nregs = argc + 2; 427 stack_extend(mrb, ci->nregs); 428 } 429 else if (argc >= CALL_MAXARGS) { 496 if (argc >= CALL_MAXARGS) { 430 497 mrb_value args = mrb_ary_new_from_values(mrb, argc, argv); 431 stack_extend(mrb, ci->nregs); 498 432 499 mrb->c->stack[1] = args; 433 500 ci->argc = -1; 434 501 argc = 1; 435 502 } 436 else { 437 if (argc < 0) argc = 1; 438 ci->nregs = p->body.irep->nregs + argc; 439 stack_extend(mrb, ci->nregs); 503 mrb_stack_extend(mrb, argc + 2); 504 if (MRB_METHOD_PROC_P(m)) { 505 struct RProc *p = MRB_METHOD_PROC(m); 506 507 ci->proc = p; 508 if (!MRB_PROC_CFUNC_P(p)) { 509 mrb_stack_extend(mrb, p->body.irep->nregs + argc); 510 } 440 511 } 441 512 if (voff >= 0) { … … 448 519 mrb->c->stack[argc+1] = blk; 449 520 450 if (MRB_PROC_CFUNC_P(p)) { 451 int ai = mrb_gc_arena_save(mrb); 452 521 if (MRB_METHOD_CFUNC_P(m)) { 453 522 ci->acc = CI_ACC_DIRECT; 454 val = p->body.func(mrb, self);523 val = MRB_METHOD_CFUNC(m)(mrb, self); 455 524 mrb->c->stack = mrb->c->ci->stackent; 456 525 cipop(mrb); 457 mrb_gc_arena_restore(mrb, ai);458 526 } 459 527 else { 460 528 ci->acc = CI_ACC_SKIP; 461 val = mrb_run(mrb, p, self); 462 } 463 } 529 val = mrb_run(mrb, MRB_METHOD_PROC(m), self); 530 } 531 } 532 mrb_gc_arena_restore(mrb, ai); 464 533 mrb_gc_protect(mrb, val); 465 534 return val; … … 476 545 { 477 546 mrb_callinfo *ci = mrb->c->ci; 547 int keep, nregs; 478 548 479 549 mrb->c->stack[0] = self; 480 550 ci->proc = p; 481 ci->target_class = p->target_class;482 551 if (MRB_PROC_CFUNC_P(p)) { 483 return p->body.func(mrb, self); 484 } 485 if (ci->argc < 0) { 486 stack_extend(mrb, (p->body.irep->nregs < 3) ? 3 : p->body.irep->nregs); 552 return MRB_PROC_CFUNC(p)(mrb, self); 553 } 554 nregs = p->body.irep->nregs; 555 if (ci->argc < 0) keep = 3; 556 else keep = ci->argc + 2; 557 if (nregs < keep) { 558 mrb_stack_extend(mrb, keep); 487 559 } 488 560 else { 489 stack_extend(mrb, p->body.irep->nregs);490 }491 492 ci->nregs = p->body.irep->nregs; 561 mrb_stack_extend(mrb, nregs); 562 stack_clear(mrb->c->stack+keep, nregs-keep); 563 } 564 493 565 ci = cipush(mrb); 494 ci->nregs = 0;495 566 ci->target_class = 0; 496 567 ci->pc = p->body.irep->iseq; … … 520 591 * k.send :hello, "gentle", "readers" #=> "Hello gentle readers" 521 592 */ 522 MRB_APImrb_value593 mrb_value 523 594 mrb_f_send(mrb_state *mrb, mrb_value self) 524 595 { … … 526 597 mrb_value block, *argv, *regs; 527 598 mrb_int argc, i, len; 528 struct RProc *p;599 mrb_method_t m; 529 600 struct RClass *c; 530 601 mrb_callinfo *ci; … … 538 609 539 610 c = mrb_class(mrb, self); 540 p = mrb_method_search_vm(mrb, &c, name); 541 542 if (!p) { /* call method_mising */ 611 m = mrb_method_search_vm(mrb, &c, name); 612 if (MRB_METHOD_UNDEF_P(m)) { /* call method_mising */ 543 613 goto funcall; 544 614 } … … 558 628 } 559 629 560 return mrb_exec_irep(mrb, self, p); 630 if (MRB_METHOD_CFUNC_P(m)) { 631 if (MRB_METHOD_PROC_P(m)) { 632 ci->proc = MRB_METHOD_PROC(m); 633 } 634 return MRB_METHOD_CFUNC(m)(mrb, self); 635 } 636 return mrb_exec_irep(mrb, self, MRB_METHOD_PROC(m)); 561 637 } 562 638 … … 566 642 struct RProc *p; 567 643 mrb_callinfo *ci; 568 mrb_int max = 3;644 int nregs; 569 645 570 646 if (mrb_nil_p(blk)) { … … 582 658 ci->mid = ci[-1].mid; 583 659 if (MRB_PROC_CFUNC_P(p)) { 584 stack_extend(mrb, 3);660 mrb_stack_extend(mrb, 3); 585 661 mrb->c->stack[0] = self; 586 662 mrb->c->stack[1] = self; 587 663 mrb->c->stack[2] = mrb_nil_value(); 588 return p->body.func(mrb, self);589 } 590 ci->nregs = p->body.irep->nregs;591 if ( max < ci->nregs) max = ci->nregs;592 stack_extend(mrb, max);664 return MRB_PROC_CFUNC(p)(mrb, self); 665 } 666 nregs = p->body.irep->nregs; 667 if (nregs < 3) nregs = 3; 668 mrb_stack_extend(mrb, nregs); 593 669 mrb->c->stack[0] = self; 594 670 mrb->c->stack[1] = self; 595 mrb->c->stack[2] = mrb_nil_value();671 stack_clear(mrb->c->stack+2, nregs-2); 596 672 ci = cipush(mrb); 597 ci->nregs = 0;598 673 ci->target_class = 0; 599 674 ci->pc = p->body.irep->iseq; … … 659 734 case MRB_TT_SYMBOL: 660 735 case MRB_TT_FIXNUM: 736 #ifndef MRB_WITHOUT_FLOAT 661 737 case MRB_TT_FLOAT: 738 #endif 662 739 c = 0; 663 740 break; … … 676 753 mrb_sym mid = mrb->c->ci->mid; 677 754 mrb_callinfo *ci; 678 int n = mrb->c->ci->nregs;679 755 mrb_value val; 756 int n; 680 757 681 758 if (mrb_nil_p(b)) { 682 759 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); 683 760 } 684 if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { 761 ci = mrb->c->ci; 762 n = ci_nregs(ci); 763 if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) { 685 764 mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err)); 686 765 } … … 690 769 ci->proc = p; 691 770 ci->stackent = mrb->c->stack; 692 ci->argc = argc;771 ci->argc = (int)argc; 693 772 ci->target_class = c; 694 773 ci->acc = CI_ACC_SKIP; 774 n = MRB_PROC_CFUNC_P(p) ? (int)(argc+2) : p->body.irep->nregs; 695 775 mrb->c->stack = mrb->c->stack + n; 696 if (MRB_PROC_CFUNC_P(p)) { 697 ci->nregs = argc + 2; 698 stack_extend(mrb, ci->nregs); 699 } 700 else { 701 ci->nregs = p->body.irep->nregs; 702 stack_extend(mrb, ci->nregs); 703 } 776 mrb_stack_extend(mrb, n); 704 777 705 778 mrb->c->stack[0] = self; … … 710 783 711 784 if (MRB_PROC_CFUNC_P(p)) { 712 val = p->body.func(mrb, self);785 val = MRB_PROC_CFUNC(p)(mrb, self); 713 786 mrb->c->stack = mrb->c->ci->stackent; 787 cipop(mrb); 714 788 } 715 789 else { 716 int cioff = mrb->c->ci - mrb->c->cibase;717 790 val = mrb_run(mrb, p, self); 718 mrb->c->ci = mrb->c->cibase + cioff; 719 } 720 cipop(mrb); 791 } 721 792 return val; 722 793 } … … 727 798 struct RProc *p = mrb_proc_ptr(b); 728 799 729 return mrb_yield_with_class(mrb, b, argc, argv, p->env->stack[0], p->target_class);800 return mrb_yield_with_class(mrb, b, argc, argv, MRB_PROC_ENV(p)->stack[0], MRB_PROC_TARGET_CLASS(p)); 730 801 } 731 802 … … 735 806 struct RProc *p = mrb_proc_ptr(b); 736 807 737 return mrb_yield_with_class(mrb, b, 1, &arg, p->env->stack[0], p->target_class);808 return mrb_yield_with_class(mrb, b, 1, &arg, MRB_PROC_ENV(p)->stack[0], MRB_PROC_TARGET_CLASS(p)); 738 809 } 739 810 … … 747 818 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given"); 748 819 } 749 if ( mrb_type(b) != MRB_TT_PROC) {820 if (!mrb_proc_p(b)) { 750 821 mrb_raise(mrb, E_TYPE_ERROR, "not a block"); 751 822 } … … 754 825 ci = mrb->c->ci; 755 826 756 stack_extend(mrb, 3);827 mrb_stack_extend(mrb, 3); 757 828 mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv); 758 829 mrb->c->stack[2] = mrb_nil_value(); … … 767 838 768 839 brk = (struct RBreak*)mrb_obj_alloc(mrb, MRB_TT_BREAK, NULL); 769 brk->iv = NULL; 770 brk->proc = p; 771 brk->val = val; 840 mrb_break_proc_set(brk, p); 841 mrb_break_value_set(brk, val); 772 842 773 843 return brk; … … 789 859 mrb_value exc; 790 860 791 msg = mrb_str_ buf_new(mrb, sizeof(lead) + 7);861 msg = mrb_str_new_capa(mrb, sizeof(lead) + 7); 792 862 mrb_str_cat(mrb, msg, lead, sizeof(lead) - 1); 793 863 mrb_str_cat(mrb, msg, kind_str[kind], kind_str_len[kind]); … … 810 880 } 811 881 if (mrb->c->ci->mid) { 812 str = mrb_format(mrb, "'%S': wrong number of arguments (%S for %S)", 813 mrb_sym2str(mrb, mrb->c->ci->mid), 814 mrb_fixnum_value(argc), mrb_fixnum_value(num)); 882 str = mrb_format(mrb, "'%n': wrong number of arguments (%i for %i)", 883 mrb->c->ci->mid, argc, num); 815 884 } 816 885 else { 817 str = mrb_format(mrb, "wrong number of arguments (%S for %S)", 818 mrb_fixnum_value(argc), mrb_fixnum_value(num)); 886 str = mrb_format(mrb, "wrong number of arguments (%i for %i)", argc, num); 819 887 } 820 888 exc = mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str); … … 822 890 } 823 891 824 #define ERR_PC_SET(mrb , pc) mrb->c->ci->err = pc;825 #define ERR_PC_CLR(mrb) 892 #define ERR_PC_SET(mrb) mrb->c->ci->err = pc0; 893 #define ERR_PC_CLR(mrb) mrb->c->ci->err = 0; 826 894 #ifdef MRB_ENABLE_DEBUG_HOOK 827 895 #define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs)); … … 836 904 #endif 837 905 838 906 #ifndef MRB_DISABLE_DIRECT_THREADING 839 907 #if defined __GNUC__ || defined __clang__ || defined __INTEL_COMPILER 840 908 #define DIRECT_THREADED 841 909 #endif 910 #endif /* ifndef MRB_DISABLE_DIRECT_THREADING */ 842 911 843 912 #ifndef DIRECT_THREADED 844 913 845 #define INIT_DISPATCH for (;;) { i = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (GET_OPCODE(i)) {846 #define CASE( op) case op:847 #define NEXT pc++;break848 #define JUMP break914 #define INIT_DISPATCH for (;;) { insn = BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (insn) { 915 #define CASE(insn,ops) case insn: pc0=pc++; FETCH_ ## ops ();; L_ ## insn ## _BODY: 916 #define NEXT break 917 #define JUMP NEXT 849 918 #define END_DISPATCH }} 850 919 … … 852 921 853 922 #define INIT_DISPATCH JUMP; return mrb_nil_value(); 854 #define CASE( op) L_ ## op:855 #define NEXT i =BYTECODE_DECODER(*++pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]856 #define JUMP i=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]923 #define CASE(insn,ops) L_ ## insn: pc0=pc++; FETCH_ ## ops (); L_ ## insn ## _BODY: 924 #define NEXT insn=BYTECODE_DECODER(*pc); CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[insn] 925 #define JUMP NEXT 857 926 858 927 #define END_DISPATCH … … 866 935 mrb_value result; 867 936 struct mrb_context *c = mrb->c; 868 int cioff = c->ci - c->cibase;937 ptrdiff_t cioff = c->ci - c->cibase; 869 938 unsigned int nregs = irep->nregs; 870 939 … … 874 943 if (stack_keep > nregs) 875 944 nregs = stack_keep; 876 stack_extend(mrb, nregs);945 mrb_stack_extend(mrb, nregs); 877 946 stack_clear(c->stack + stack_keep, nregs - stack_keep); 878 947 c->stack[0] = self; 879 948 result = mrb_vm_exec(mrb, proc, irep->iseq); 880 if (c->ci - c->cibase > cioff) {881 c->ci = c->cibase + cioff;882 }883 949 if (mrb->c != c) { 884 950 if (mrb->c->fib) { … … 887 953 mrb->c = c; 888 954 } 955 else if (c->ci - c->cibase > cioff) { 956 c->ci = c->cibase + cioff; 957 } 889 958 return result; 890 959 } 891 960 961 static mrb_bool 962 check_target_class(mrb_state *mrb) 963 { 964 if (!mrb->c->ci->target_class) { 965 mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, "no target class or module"); 966 mrb_exc_set(mrb, exc); 967 return FALSE; 968 } 969 return TRUE; 970 } 971 972 void mrb_hash_check_kdict(mrb_state *mrb, mrb_value self); 973 892 974 MRB_API mrb_value 893 mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc) 894 { 895 /* mrb_assert(mrb_proc_cfunc_p(proc)) */ 975 mrb_vm_exec(mrb_state *mrb, struct RProc *proc, const mrb_code *pc) 976 { 977 /* mrb_assert(MRB_PROC_CFUNC_P(proc)) */ 978 const mrb_code *pc0 = pc; 896 979 mrb_irep *irep = proc->body.irep; 897 980 mrb_value *pool = irep->pool; 898 981 mrb_sym *syms = irep->syms; 899 mrb_code i ;982 mrb_code insn; 900 983 int ai = mrb_gc_arena_save(mrb); 901 984 struct mrb_jmpbuf *prev_jmp = mrb->jmp; 902 985 struct mrb_jmpbuf c_jmp; 986 uint32_t a; 987 uint16_t b; 988 uint8_t c; 989 mrb_sym mid; 903 990 904 991 #ifdef DIRECT_THREADED 905 992 static void *optable[] = { 906 &&L_OP_NOP, &&L_OP_MOVE, 907 &&L_OP_LOADL, &&L_OP_LOADI, &&L_OP_LOADSYM, &&L_OP_LOADNIL, 908 &&L_OP_LOADSELF, &&L_OP_LOADT, &&L_OP_LOADF, 909 &&L_OP_GETGLOBAL, &&L_OP_SETGLOBAL, &&L_OP_GETSPECIAL, &&L_OP_SETSPECIAL, 910 &&L_OP_GETIV, &&L_OP_SETIV, &&L_OP_GETCV, &&L_OP_SETCV, 911 &&L_OP_GETCONST, &&L_OP_SETCONST, &&L_OP_GETMCNST, &&L_OP_SETMCNST, 912 &&L_OP_GETUPVAR, &&L_OP_SETUPVAR, 913 &&L_OP_JMP, &&L_OP_JMPIF, &&L_OP_JMPNOT, 914 &&L_OP_ONERR, &&L_OP_RESCUE, &&L_OP_POPERR, &&L_OP_RAISE, &&L_OP_EPUSH, &&L_OP_EPOP, 915 &&L_OP_SEND, &&L_OP_SENDB, &&L_OP_FSEND, 916 &&L_OP_CALL, &&L_OP_SUPER, &&L_OP_ARGARY, &&L_OP_ENTER, 917 &&L_OP_KARG, &&L_OP_KDICT, &&L_OP_RETURN, &&L_OP_TAILCALL, &&L_OP_BLKPUSH, 918 &&L_OP_ADD, &&L_OP_ADDI, &&L_OP_SUB, &&L_OP_SUBI, &&L_OP_MUL, &&L_OP_DIV, 919 &&L_OP_EQ, &&L_OP_LT, &&L_OP_LE, &&L_OP_GT, &&L_OP_GE, 920 &&L_OP_ARRAY, &&L_OP_ARYCAT, &&L_OP_ARYPUSH, &&L_OP_AREF, &&L_OP_ASET, &&L_OP_APOST, 921 &&L_OP_STRING, &&L_OP_STRCAT, &&L_OP_HASH, 922 &&L_OP_LAMBDA, &&L_OP_RANGE, &&L_OP_OCLASS, 923 &&L_OP_CLASS, &&L_OP_MODULE, &&L_OP_EXEC, 924 &&L_OP_METHOD, &&L_OP_SCLASS, &&L_OP_TCLASS, 925 &&L_OP_DEBUG, &&L_OP_STOP, &&L_OP_ERR, 993 #define OPCODE(x,_) &&L_OP_ ## x, 994 #include "mruby/ops.h" 995 #undef OPCODE 926 996 }; 927 997 #endif … … 934 1004 if (exc_catched) { 935 1005 exc_catched = FALSE; 1006 mrb_gc_arena_restore(mrb, ai); 936 1007 if (mrb->exc && mrb->exc->tt == MRB_TT_BREAK) 937 1008 goto L_BREAK; … … 940 1011 mrb->jmp = &c_jmp; 941 1012 mrb->c->ci->proc = proc; 942 mrb->c->ci->nregs = irep->nregs;943 1013 944 1014 #define regs (mrb->c->stack) 945 1015 INIT_DISPATCH { 946 CASE(OP_NOP ) {1016 CASE(OP_NOP, Z) { 947 1017 /* do nothing */ 948 1018 NEXT; 949 1019 } 950 1020 951 CASE(OP_MOVE) { 952 /* A B R(A) := R(B) */ 953 int a = GETARG_A(i); 954 int b = GETARG_B(i); 1021 CASE(OP_MOVE, BB) { 955 1022 regs[a] = regs[b]; 956 1023 NEXT; 957 1024 } 958 1025 959 CASE(OP_LOADL) { 960 /* A Bx R(A) := Pool(Bx) */ 961 int a = GETARG_A(i); 962 int bx = GETARG_Bx(i); 1026 CASE(OP_LOADL, BB) { 963 1027 #ifdef MRB_WORD_BOXING 964 mrb_value val = pool[bx]; 1028 mrb_value val = pool[b]; 1029 #ifndef MRB_WITHOUT_FLOAT 965 1030 if (mrb_float_p(val)) { 966 1031 val = mrb_float_value(mrb, mrb_float(val)); 967 1032 } 1033 #endif 968 1034 regs[a] = val; 969 1035 #else 970 regs[a] = pool[bx]; 971 #endif 972 NEXT; 973 } 974 975 CASE(OP_LOADI) { 976 /* A sBx R(A) := sBx */ 977 SET_INT_VALUE(regs[GETARG_A(i)], GETARG_sBx(i)); 978 NEXT; 979 } 980 981 CASE(OP_LOADSYM) { 982 /* A Bx R(A) := Syms(Bx) */ 983 int a = GETARG_A(i); 984 int bx = GETARG_Bx(i); 985 SET_SYM_VALUE(regs[a], syms[bx]); 986 NEXT; 987 } 988 989 CASE(OP_LOADSELF) { 990 /* A R(A) := self */ 991 int a = GETARG_A(i); 1036 regs[a] = pool[b]; 1037 #endif 1038 NEXT; 1039 } 1040 1041 CASE(OP_LOADI, BB) { 1042 SET_INT_VALUE(regs[a], b); 1043 NEXT; 1044 } 1045 1046 CASE(OP_LOADINEG, BB) { 1047 SET_INT_VALUE(regs[a], -b); 1048 NEXT; 1049 } 1050 1051 CASE(OP_LOADI__1,B) goto L_LOADI; 1052 CASE(OP_LOADI_0,B) goto L_LOADI; 1053 CASE(OP_LOADI_1,B) goto L_LOADI; 1054 CASE(OP_LOADI_2,B) goto L_LOADI; 1055 CASE(OP_LOADI_3,B) goto L_LOADI; 1056 CASE(OP_LOADI_4,B) goto L_LOADI; 1057 CASE(OP_LOADI_5,B) goto L_LOADI; 1058 CASE(OP_LOADI_6,B) goto L_LOADI; 1059 CASE(OP_LOADI_7, B) { 1060 L_LOADI: 1061 SET_INT_VALUE(regs[a], (mrb_int)insn - (mrb_int)OP_LOADI_0); 1062 NEXT; 1063 } 1064 1065 CASE(OP_LOADSYM, BB) { 1066 SET_SYM_VALUE(regs[a], syms[b]); 1067 NEXT; 1068 } 1069 1070 CASE(OP_LOADNIL, B) { 1071 SET_NIL_VALUE(regs[a]); 1072 NEXT; 1073 } 1074 1075 CASE(OP_LOADSELF, B) { 992 1076 regs[a] = regs[0]; 993 1077 NEXT; 994 1078 } 995 1079 996 CASE(OP_LOADT) { 997 /* A R(A) := true */ 998 int a = GETARG_A(i); 1080 CASE(OP_LOADT, B) { 999 1081 SET_TRUE_VALUE(regs[a]); 1000 1082 NEXT; 1001 1083 } 1002 1084 1003 CASE(OP_LOADF) { 1004 /* A R(A) := false */ 1005 int a = GETARG_A(i); 1085 CASE(OP_LOADF, B) { 1006 1086 SET_FALSE_VALUE(regs[a]); 1007 1087 NEXT; 1008 1088 } 1009 1089 1010 CASE(OP_GETGLOBAL) { 1011 /* A Bx R(A) := getglobal(Syms(Bx)) */ 1012 int a = GETARG_A(i); 1013 int bx = GETARG_Bx(i); 1014 mrb_value val = mrb_gv_get(mrb, syms[bx]); 1090 CASE(OP_GETGV, BB) { 1091 mrb_value val = mrb_gv_get(mrb, syms[b]); 1015 1092 regs[a] = val; 1016 1093 NEXT; 1017 1094 } 1018 1095 1019 CASE(OP_SETGLOBAL) { 1020 /* A Bx setglobal(Syms(Bx), R(A)) */ 1021 int a = GETARG_A(i); 1022 int bx = GETARG_Bx(i); 1023 mrb_gv_set(mrb, syms[bx], regs[a]); 1024 NEXT; 1025 } 1026 1027 CASE(OP_GETSPECIAL) { 1028 /* A Bx R(A) := Special[Bx] */ 1029 int a = GETARG_A(i); 1030 int bx = GETARG_Bx(i); 1031 mrb_value val = mrb_vm_special_get(mrb, bx); 1096 CASE(OP_SETGV, BB) { 1097 mrb_gv_set(mrb, syms[b], regs[a]); 1098 NEXT; 1099 } 1100 1101 CASE(OP_GETSV, BB) { 1102 mrb_value val = mrb_vm_special_get(mrb, b); 1032 1103 regs[a] = val; 1033 1104 NEXT; 1034 1105 } 1035 1106 1036 CASE(OP_SETSPECIAL) { 1037 /* A Bx Special[Bx] := R(A) */ 1038 int a = GETARG_A(i); 1039 int bx = GETARG_Bx(i); 1040 mrb_vm_special_set(mrb, bx, regs[a]); 1041 NEXT; 1042 } 1043 1044 CASE(OP_GETIV) { 1045 /* A Bx R(A) := ivget(Bx) */ 1046 int a = GETARG_A(i); 1047 int bx = GETARG_Bx(i); 1048 mrb_value val = mrb_vm_iv_get(mrb, syms[bx]); 1049 regs[a] = val; 1050 NEXT; 1051 } 1052 1053 CASE(OP_SETIV) { 1054 /* A Bx ivset(Syms(Bx),R(A)) */ 1055 int a = GETARG_A(i); 1056 int bx = GETARG_Bx(i); 1057 mrb_vm_iv_set(mrb, syms[bx], regs[a]); 1058 NEXT; 1059 } 1060 1061 CASE(OP_GETCV) { 1062 /* A Bx R(A) := cvget(Syms(Bx)) */ 1063 int a = GETARG_A(i); 1064 int bx = GETARG_Bx(i); 1107 CASE(OP_SETSV, BB) { 1108 mrb_vm_special_set(mrb, b, regs[a]); 1109 NEXT; 1110 } 1111 1112 CASE(OP_GETIV, BB) { 1113 regs[a] = mrb_iv_get(mrb, regs[0], syms[b]); 1114 NEXT; 1115 } 1116 1117 CASE(OP_SETIV, BB) { 1118 mrb_iv_set(mrb, regs[0], syms[b], regs[a]); 1119 NEXT; 1120 } 1121 1122 CASE(OP_GETCV, BB) { 1065 1123 mrb_value val; 1066 ERR_PC_SET(mrb , pc);1067 val = mrb_vm_cv_get(mrb, syms[b x]);1124 ERR_PC_SET(mrb); 1125 val = mrb_vm_cv_get(mrb, syms[b]); 1068 1126 ERR_PC_CLR(mrb); 1069 1127 regs[a] = val; … … 1071 1129 } 1072 1130 1073 CASE(OP_SETCV) { 1074 /* A Bx cvset(Syms(Bx),R(A)) */ 1075 int a = GETARG_A(i); 1076 int bx = GETARG_Bx(i); 1077 mrb_vm_cv_set(mrb, syms[bx], regs[a]); 1078 NEXT; 1079 } 1080 1081 CASE(OP_GETCONST) { 1082 /* A Bx R(A) := constget(Syms(Bx)) */ 1131 CASE(OP_SETCV, BB) { 1132 mrb_vm_cv_set(mrb, syms[b], regs[a]); 1133 NEXT; 1134 } 1135 1136 CASE(OP_GETCONST, BB) { 1083 1137 mrb_value val; 1084 int a = GETARG_A(i); 1085 int bx = GETARG_Bx(i); 1086 mrb_sym sym = syms[bx]; 1087 1088 ERR_PC_SET(mrb, pc); 1138 mrb_sym sym = syms[b]; 1139 1140 ERR_PC_SET(mrb); 1089 1141 val = mrb_vm_const_get(mrb, sym); 1090 1142 ERR_PC_CLR(mrb); … … 1093 1145 } 1094 1146 1095 CASE(OP_SETCONST) { 1096 /* A Bx constset(Syms(Bx),R(A)) */ 1097 int a = GETARG_A(i); 1098 int bx = GETARG_Bx(i); 1099 mrb_vm_const_set(mrb, syms[bx], regs[a]); 1100 NEXT; 1101 } 1102 1103 CASE(OP_GETMCNST) { 1104 /* A Bx R(A) := R(A)::Syms(Bx) */ 1147 CASE(OP_SETCONST, BB) { 1148 mrb_vm_const_set(mrb, syms[b], regs[a]); 1149 NEXT; 1150 } 1151 1152 CASE(OP_GETMCNST, BB) { 1105 1153 mrb_value val; 1106 int a = GETARG_A(i); 1107 int bx = GETARG_Bx(i); 1108 1109 ERR_PC_SET(mrb, pc); 1110 val = mrb_const_get(mrb, regs[a], syms[bx]); 1154 1155 ERR_PC_SET(mrb); 1156 val = mrb_const_get(mrb, regs[a], syms[b]); 1111 1157 ERR_PC_CLR(mrb); 1112 1158 regs[a] = val; … … 1114 1160 } 1115 1161 1116 CASE(OP_SETMCNST) { 1117 /* A Bx R(A+1)::Syms(Bx) := R(A) */ 1118 int a = GETARG_A(i); 1119 int bx = GETARG_Bx(i); 1120 mrb_const_set(mrb, regs[a+1], syms[bx], regs[a]); 1121 NEXT; 1122 } 1123 1124 CASE(OP_GETUPVAR) { 1125 /* A B C R(A) := uvget(B,C) */ 1126 int a = GETARG_A(i); 1127 int b = GETARG_B(i); 1128 int c = GETARG_C(i); 1162 CASE(OP_SETMCNST, BB) { 1163 mrb_const_set(mrb, regs[a+1], syms[b], regs[a]); 1164 NEXT; 1165 } 1166 1167 CASE(OP_GETUPVAR, BBB) { 1129 1168 mrb_value *regs_a = regs + a; 1130 1169 struct REnv *e = uvenv(mrb, c); 1131 1170 1132 if (!e) { 1171 if (e && b < MRB_ENV_STACK_LEN(e)) { 1172 *regs_a = e->stack[b]; 1173 } 1174 else { 1133 1175 *regs_a = mrb_nil_value(); 1134 1176 } 1135 else { 1136 *regs_a = e->stack[b]; 1137 } 1138 NEXT; 1139 } 1140 1141 CASE(OP_SETUPVAR) { 1142 /* A B C uvset(B,C,R(A)) */ 1143 int a = GETARG_A(i); 1144 int b = GETARG_B(i); 1145 int c = GETARG_C(i); 1146 1177 NEXT; 1178 } 1179 1180 CASE(OP_SETUPVAR, BBB) { 1147 1181 struct REnv *e = uvenv(mrb, c); 1148 1182 … … 1158 1192 } 1159 1193 1160 CASE(OP_JMP) { 1161 /* sBx pc+=sBx */ 1162 int sbx = GETARG_sBx(i); 1163 pc += sbx; 1194 CASE(OP_JMP, S) { 1195 pc = irep->iseq+a; 1164 1196 JUMP; 1165 1197 } 1166 1167 CASE(OP_JMPIF) { 1168 /* A sBx if R(A) pc+=sBx */ 1169 int a = GETARG_A(i); 1170 int sbx = GETARG_sBx(i); 1198 CASE(OP_JMPIF, BS) { 1171 1199 if (mrb_test(regs[a])) { 1172 pc += sbx;1200 pc = irep->iseq+b; 1173 1201 JUMP; 1174 1202 } 1175 1203 NEXT; 1176 1204 } 1177 1178 CASE(OP_JMPNOT) { 1179 /* A sBx if !R(A) pc+=sBx */ 1180 int a = GETARG_A(i); 1181 int sbx = GETARG_sBx(i); 1205 CASE(OP_JMPNOT, BS) { 1182 1206 if (!mrb_test(regs[a])) { 1183 pc += sbx;1207 pc = irep->iseq+b; 1184 1208 JUMP; 1185 1209 } 1186 1210 NEXT; 1187 1211 } 1188 1189 CASE(OP_ONERR) { 1190 /* sBx pc+=sBx on exception */ 1191 int sbx = GETARG_sBx(i); 1212 CASE(OP_JMPNIL, BS) { 1213 if (mrb_nil_p(regs[a])) { 1214 pc = irep->iseq+b; 1215 JUMP; 1216 } 1217 NEXT; 1218 } 1219 1220 CASE(OP_ONERR, S) { 1221 /* check rescue stack */ 1222 if (mrb->c->ci->ridx == UINT16_MAX-1) { 1223 mrb_value exc = mrb_exc_new_str_lit(mrb, E_RUNTIME_ERROR, "too many nested rescues"); 1224 mrb_exc_set(mrb, exc); 1225 goto L_RAISE; 1226 } 1227 /* expand rescue stack */ 1192 1228 if (mrb->c->rsize <= mrb->c->ci->ridx) { 1193 1229 if (mrb->c->rsize == 0) mrb->c->rsize = RESCUE_STACK_INIT_SIZE; 1194 else mrb->c->rsize *= 2; 1195 mrb->c->rescue = (mrb_code **)mrb_realloc(mrb, mrb->c->rescue, sizeof(mrb_code*) * mrb->c->rsize); 1196 } 1197 mrb->c->rescue[mrb->c->ci->ridx++] = pc + sbx; 1198 NEXT; 1199 } 1200 1201 CASE(OP_RESCUE) { 1202 /* A B R(A) := exc; clear(exc); R(B) := matched (bool) */ 1203 int a = GETARG_A(i); 1204 int b = GETARG_B(i); 1205 int c = GETARG_C(i); 1206 mrb_value exc; 1207 1208 if (c == 0) { 1209 exc = mrb_obj_value(mrb->exc); 1210 mrb->exc = 0; 1211 } 1212 else { /* continued; exc taken from R(A) */ 1213 exc = regs[a]; 1214 } 1215 if (b != 0) { 1216 mrb_value e = regs[b]; 1217 struct RClass *ec; 1218 1219 switch (mrb_type(e)) { 1220 case MRB_TT_CLASS: 1221 case MRB_TT_MODULE: 1222 break; 1223 default: 1224 { 1225 mrb_value exc; 1226 1227 exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, 1228 "class or module required for rescue clause"); 1229 mrb_exc_set(mrb, exc); 1230 goto L_RAISE; 1231 } 1232 } 1233 ec = mrb_class_ptr(e); 1234 regs[b] = mrb_bool_value(mrb_obj_is_kind_of(mrb, exc, ec)); 1235 } 1236 if (a != 0 && c == 0) { 1237 regs[a] = exc; 1238 } 1239 NEXT; 1240 } 1241 1242 CASE(OP_POPERR) { 1243 /* A A.times{rescue_pop()} */ 1244 int a = GETARG_A(i); 1245 1246 while (a--) { 1247 mrb->c->ci->ridx--; 1248 } 1249 NEXT; 1250 } 1251 1252 CASE(OP_RAISE) { 1253 /* A raise(R(A)) */ 1254 int a = GETARG_A(i); 1255 1230 else { 1231 mrb->c->rsize *= 2; 1232 if (mrb->c->rsize <= mrb->c->ci->ridx) { 1233 mrb->c->rsize = UINT16_MAX; 1234 } 1235 } 1236 mrb->c->rescue = (uint16_t*)mrb_realloc(mrb, mrb->c->rescue, sizeof(uint16_t)*mrb->c->rsize); 1237 } 1238 /* push rescue stack */ 1239 mrb->c->rescue[mrb->c->ci->ridx++] = a; 1240 NEXT; 1241 } 1242 1243 CASE(OP_EXCEPT, B) { 1244 mrb_value exc = mrb_obj_value(mrb->exc); 1245 mrb->exc = 0; 1246 regs[a] = exc; 1247 NEXT; 1248 } 1249 CASE(OP_RESCUE, BB) { 1250 mrb_value exc = regs[a]; /* exc on stack */ 1251 mrb_value e = regs[b]; 1252 struct RClass *ec; 1253 1254 switch (mrb_type(e)) { 1255 case MRB_TT_CLASS: 1256 case MRB_TT_MODULE: 1257 break; 1258 default: 1259 { 1260 mrb_value exc; 1261 1262 exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, 1263 "class or module required for rescue clause"); 1264 mrb_exc_set(mrb, exc); 1265 goto L_RAISE; 1266 } 1267 } 1268 ec = mrb_class_ptr(e); 1269 regs[b] = mrb_bool_value(mrb_obj_is_kind_of(mrb, exc, ec)); 1270 NEXT; 1271 } 1272 1273 CASE(OP_POPERR, B) { 1274 mrb->c->ci->ridx -= a; 1275 NEXT; 1276 } 1277 1278 CASE(OP_RAISE, B) { 1256 1279 mrb_exc_set(mrb, regs[a]); 1257 1280 goto L_RAISE; 1258 1281 } 1259 1282 1260 CASE(OP_EPUSH) { 1261 /* Bx ensure_push(SEQ[Bx]) */ 1262 int bx = GETARG_Bx(i); 1283 CASE(OP_EPUSH, B) { 1263 1284 struct RProc *p; 1264 1285 1265 p = mrb_closure_new(mrb, irep->reps[bx]); 1266 /* push ensure_stack */ 1286 p = mrb_closure_new(mrb, irep->reps[a]); 1287 /* check ensure stack */ 1288 if (mrb->c->eidx == UINT16_MAX-1) { 1289 mrb_value exc = mrb_exc_new_str_lit(mrb, E_RUNTIME_ERROR, "too many nested ensures"); 1290 mrb_exc_set(mrb, exc); 1291 goto L_RAISE; 1292 } 1293 /* expand ensure stack */ 1267 1294 if (mrb->c->esize <= mrb->c->eidx+1) { 1268 1295 if (mrb->c->esize == 0) mrb->c->esize = ENSURE_STACK_INIT_SIZE; 1269 else mrb->c->esize *= 2; 1270 mrb->c->ensure = (struct RProc **)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*) * mrb->c->esize); 1271 } 1296 else { 1297 mrb->c->esize *= 2; 1298 if (mrb->c->esize <= mrb->c->eidx) { 1299 mrb->c->esize = UINT16_MAX; 1300 } 1301 } 1302 mrb->c->ensure = (struct RProc**)mrb_realloc(mrb, mrb->c->ensure, sizeof(struct RProc*)*mrb->c->esize); 1303 } 1304 /* push ensure stack */ 1272 1305 mrb->c->ensure[mrb->c->eidx++] = p; 1273 1306 mrb->c->ensure[mrb->c->eidx] = NULL; 1274 ARENA_RESTORE(mrb, ai); 1275 NEXT; 1276 } 1277 1278 CASE(OP_EPOP) { 1279 /* A A.times{ensure_pop().call} */ 1280 int a = GETARG_A(i); 1307 mrb_gc_arena_restore(mrb, ai); 1308 NEXT; 1309 } 1310 1311 CASE(OP_EPOP, B) { 1281 1312 mrb_callinfo *ci = mrb->c->ci; 1282 int n, epos = ci->epos; 1283 1284 for (n=0; n<a && mrb->c->eidx > epos; n++) { 1285 ecall(mrb, --mrb->c->eidx); 1286 ARENA_RESTORE(mrb, ai); 1287 } 1288 NEXT; 1289 } 1290 1291 CASE(OP_LOADNIL) { 1292 /* A R(A) := nil */ 1293 int a = GETARG_A(i); 1294 1295 SET_NIL_VALUE(regs[a]); 1296 NEXT; 1297 } 1298 1299 CASE(OP_SENDB) { 1300 /* A B C R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C),&R(A+C+1))*/ 1301 /* fall through */ 1313 unsigned int n, epos = ci->epos; 1314 mrb_value self = regs[0]; 1315 struct RClass *target_class = ci->target_class; 1316 1317 if (mrb->c->eidx <= epos) { 1318 NEXT; 1319 } 1320 1321 if (a > (int)mrb->c->eidx - epos) 1322 a = mrb->c->eidx - epos; 1323 for (n=0; n<a; n++) { 1324 int nregs = irep->nregs; 1325 1326 proc = mrb->c->ensure[epos+n]; 1327 mrb->c->ensure[epos+n] = NULL; 1328 if (proc == NULL) continue; 1329 irep = proc->body.irep; 1330 ci = cipush(mrb); 1331 ci->mid = ci[-1].mid; 1332 ci->argc = 0; 1333 ci->proc = proc; 1334 ci->stackent = mrb->c->stack; 1335 ci->target_class = target_class; 1336 ci->pc = pc; 1337 ci->acc = nregs; 1338 mrb->c->stack += ci->acc; 1339 mrb_stack_extend(mrb, irep->nregs); 1340 regs[0] = self; 1341 pc = irep->iseq; 1342 } 1343 pool = irep->pool; 1344 syms = irep->syms; 1345 mrb->c->eidx = epos; 1346 JUMP; 1347 } 1348 1349 CASE(OP_SENDV, BB) { 1350 c = CALL_MAXARGS; 1351 goto L_SEND; 1302 1352 }; 1303 1353 1304 L_SEND: 1305 CASE(OP_SEND) { 1306 /* A B C R(A) := call(R(A),Syms(B),R(A+1),...,R(A+C)) */ 1307 int a = GETARG_A(i); 1308 int n = GETARG_C(i); 1309 struct RProc *m; 1310 struct RClass *c; 1354 CASE(OP_SENDVB, BB) { 1355 c = CALL_MAXARGS; 1356 goto L_SENDB; 1357 }; 1358 1359 CASE(OP_SEND, BBB) 1360 L_SEND: 1361 { 1362 /* push nil after arguments */ 1363 int bidx = (c == CALL_MAXARGS) ? a+2 : a+c+1; 1364 SET_NIL_VALUE(regs[bidx]); 1365 goto L_SENDB; 1366 }; 1367 L_SEND_SYM: 1368 { 1369 /* push nil after arguments */ 1370 int bidx = (c == CALL_MAXARGS) ? a+2 : a+c+1; 1371 SET_NIL_VALUE(regs[bidx]); 1372 goto L_SENDB_SYM; 1373 }; 1374 1375 CASE(OP_SENDB, BBB) 1376 L_SENDB: 1377 mid = syms[b]; 1378 L_SENDB_SYM: 1379 { 1380 int argc = (c == CALL_MAXARGS) ? -1 : c; 1381 int bidx = (argc < 0) ? a+2 : a+c+1; 1382 mrb_method_t m; 1383 struct RClass *cls; 1311 1384 mrb_callinfo *ci = mrb->c->ci; 1312 mrb_value recv, result; 1313 mrb_sym mid = syms[GETARG_B(i)]; 1314 int bidx; 1315 mrb_value blk; 1385 mrb_value recv, blk; 1386 1387 mrb_assert(bidx < irep->nregs); 1316 1388 1317 1389 recv = regs[a]; 1318 if (n == CALL_MAXARGS) { 1319 bidx = a+2; 1320 } 1321 else { 1322 bidx = a+n+1; 1323 } 1324 if (GET_OPCODE(i) != OP_SENDB) { 1325 if (bidx >= ci->nregs) { 1326 stack_extend(mrb, bidx+1); 1327 ci->nregs = bidx+1; 1328 } 1329 SET_NIL_VALUE(regs[bidx]); 1330 blk = mrb_nil_value(); 1331 } 1332 else { 1333 blk = regs[bidx]; 1334 if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { 1335 if (bidx >= ci->nregs) { 1336 stack_extend(mrb, bidx+1); 1337 ci->nregs = bidx+1; 1338 } 1339 result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); 1340 blk = regs[bidx] = result; 1341 } 1342 } 1343 c = mrb_class(mrb, recv); 1344 m = mrb_method_search_vm(mrb, &c, mid); 1345 if (!m) { 1346 mrb_value sym = mrb_symbol_value(mid); 1390 blk = regs[bidx]; 1391 if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) { 1392 blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); 1393 /* The stack might have been reallocated during mrb_convert_type(), 1394 see #3622 */ 1395 regs[bidx] = blk; 1396 } 1397 cls = mrb_class(mrb, recv); 1398 m = mrb_method_search_vm(mrb, &cls, mid); 1399 if (MRB_METHOD_UNDEF_P(m)) { 1347 1400 mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); 1348 1349 m = mrb_method_search_vm(mrb, &c, missing); 1350 if (!m) { 1351 mrb_value args; 1352 1353 if (n == CALL_MAXARGS) { 1354 args = regs[a+1]; 1355 } 1356 else { 1357 args = mrb_ary_new_from_values(mrb, n, regs+a+1); 1358 } 1359 ERR_PC_SET(mrb, pc); 1401 m = mrb_method_search_vm(mrb, &cls, missing); 1402 if (MRB_METHOD_UNDEF_P(m) || (missing == mrb->c->ci->mid && mrb_obj_eq(mrb, regs[0], recv))) { 1403 mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, c, regs+a+1); 1404 ERR_PC_SET(mrb); 1360 1405 mrb_method_missing(mrb, mid, recv, args); 1361 1406 } 1407 if (argc >= 0) { 1408 if (a+2 >= irep->nregs) { 1409 mrb_stack_extend(mrb, a+3); 1410 } 1411 regs[a+1] = mrb_ary_new_from_values(mrb, c, regs+a+1); 1412 regs[a+2] = blk; 1413 argc = -1; 1414 } 1415 mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(mid)); 1362 1416 mid = missing; 1363 if (n != CALL_MAXARGS) {1364 if (a+2 >= irep->nregs) {1365 stack_extend(mrb, a+3);1366 }1367 regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1);1368 regs[a+2] = blk;1369 n = CALL_MAXARGS;1370 }1371 mrb_ary_unshift(mrb, regs[a+1], sym);1372 1417 } 1373 1418 … … 1375 1420 ci = cipush(mrb); 1376 1421 ci->mid = mid; 1377 ci->proc = m;1378 1422 ci->stackent = mrb->c->stack; 1379 ci->target_class = c; 1380 1381 ci->pc = pc + 1; 1423 ci->target_class = cls; 1424 ci->argc = argc; 1425 1426 ci->pc = pc; 1382 1427 ci->acc = a; 1383 1428 … … 1385 1430 mrb->c->stack += a; 1386 1431 1387 if (MRB_PROC_CFUNC_P(m)) { 1388 if (n == CALL_MAXARGS) { 1389 ci->argc = -1; 1390 ci->nregs = 3; 1432 if (MRB_METHOD_CFUNC_P(m)) { 1433 if (MRB_METHOD_PROC_P(m)) { 1434 struct RProc *p = MRB_METHOD_PROC(m); 1435 1436 ci->proc = p; 1437 recv = p->body.func(mrb, recv); 1438 } 1439 else if (MRB_METHOD_NOARG_P(m) && 1440 (argc > 0 || (argc == -1 && RARRAY_LEN(regs[1]) != 0))) { 1441 argnum_error(mrb, 0); 1442 goto L_RAISE; 1391 1443 } 1392 1444 else { 1393 ci->argc = n; 1394 ci->nregs = n + 2; 1395 } 1396 result = m->body.func(mrb, recv); 1445 recv = MRB_METHOD_FUNC(m)(mrb, recv); 1446 } 1397 1447 mrb_gc_arena_restore(mrb, ai); 1448 mrb_gc_arena_shrink(mrb, ai); 1398 1449 if (mrb->exc) goto L_RAISE; 1399 1450 ci = mrb->c->ci; 1400 if (GET_OPCODE(i) == OP_SENDB) { 1401 if (mrb_type(blk) == MRB_TT_PROC) { 1402 struct RProc *p = mrb_proc_ptr(blk); 1403 1404 if (p && !MRB_PROC_STRICT_P(p) && p->env == ci[-1].env) { 1405 p->flags |= MRB_PROC_ORPHAN; 1406 } 1451 if (mrb_proc_p(blk)) { 1452 struct RProc *p = mrb_proc_ptr(blk); 1453 if (p && !MRB_PROC_STRICT_P(p) && MRB_PROC_ENV(p) == ci[-1].env) { 1454 p->flags |= MRB_PROC_ORPHAN; 1407 1455 } 1408 1456 } … … 1410 1458 if (ci->acc == CI_ACC_RESUMED) { 1411 1459 mrb->jmp = prev_jmp; 1412 return re sult;1460 return recv; 1413 1461 } 1414 1462 else { … … 1420 1468 } 1421 1469 } 1422 mrb->c->stack[0] = re sult;1470 mrb->c->stack[0] = recv; 1423 1471 /* pop stackpos */ 1424 1472 mrb->c->stack = ci->stackent; … … 1429 1477 else { 1430 1478 /* setup environment for calling method */ 1431 proc = mrb->c->ci->proc = m;1432 irep = m->body.irep;1479 proc = ci->proc = MRB_METHOD_PROC(m); 1480 irep = proc->body.irep; 1433 1481 pool = irep->pool; 1434 1482 syms = irep->syms; 1435 ci->nregs = irep->nregs; 1436 if (n == CALL_MAXARGS) { 1437 ci->argc = -1; 1438 stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs); 1439 } 1440 else { 1441 ci->argc = n; 1442 stack_extend(mrb, irep->nregs); 1443 } 1483 mrb_stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs); 1444 1484 pc = irep->iseq; 1445 1485 JUMP; … … 1447 1487 } 1448 1488 1449 CASE(OP_FSEND) { 1450 /* A B C R(A) := fcall(R(A),Syms(B),R(A+1),... ,R(A+C-1)) */ 1451 /* not implemented yet */ 1452 NEXT; 1453 } 1454 1455 CASE(OP_CALL) { 1456 /* A R(A) := self.call(frame.argc, frame.argv) */ 1489 CASE(OP_CALL, Z) { 1457 1490 mrb_callinfo *ci; 1458 1491 mrb_value recv = mrb->c->stack[0]; … … 1461 1494 /* replace callinfo */ 1462 1495 ci = mrb->c->ci; 1463 ci->target_class = m->target_class;1496 ci->target_class = MRB_PROC_TARGET_CLASS(m); 1464 1497 ci->proc = m; 1465 if (m->env) { 1466 mrb_sym mid; 1467 1468 if (MRB_ENV_STACK_SHARED_P(m->env)) { 1469 mid = m->env->cxt.c->cibase[m->env->cioff].mid; 1470 } 1471 else { 1472 mid = m->env->cxt.mid; 1473 } 1474 if (mid) ci->mid = mid; 1475 if (!m->env->stack) { 1476 m->env->stack = mrb->c->stack; 1498 if (MRB_PROC_ENV_P(m)) { 1499 struct REnv *e = MRB_PROC_ENV(m); 1500 1501 ci->mid = e->mid; 1502 if (!e->stack) { 1503 e->stack = mrb->c->stack; 1477 1504 } 1478 1505 } … … 1480 1507 /* prepare stack */ 1481 1508 if (MRB_PROC_CFUNC_P(m)) { 1482 recv = m->body.func(mrb, recv);1509 recv = MRB_PROC_CFUNC(m)(mrb, recv); 1483 1510 mrb_gc_arena_restore(mrb, ai); 1511 mrb_gc_arena_shrink(mrb, ai); 1484 1512 if (mrb->exc) goto L_RAISE; 1485 1513 /* pop stackpos */ … … 1500 1528 if (!irep) { 1501 1529 mrb->c->stack[0] = mrb_nil_value(); 1502 goto L_RETURN; 1530 a = 0; 1531 c = OP_R_NORMAL; 1532 goto L_OP_RETURN_BODY; 1503 1533 } 1504 1534 pool = irep->pool; 1505 1535 syms = irep->syms; 1506 ci->nregs = irep->nregs; 1507 stack_extend(mrb, irep->nregs); 1536 mrb_stack_extend(mrb, irep->nregs); 1508 1537 if (ci->argc < 0) { 1509 1538 if (irep->nregs > 3) { … … 1514 1543 stack_clear(regs+ci->argc+2, irep->nregs-ci->argc-2); 1515 1544 } 1516 if ( m->env) {1517 regs[0] = m->env->stack[0];1545 if (MRB_PROC_ENV_P(m)) { 1546 regs[0] = MRB_PROC_ENV(m)->stack[0]; 1518 1547 } 1519 1548 pc = irep->iseq; … … 1522 1551 } 1523 1552 1524 CASE(OP_SUPER) { 1525 /* A C R(A) := super(R(A+1),... ,R(A+C+1)) */ 1526 mrb_value recv; 1553 CASE(OP_SUPER, BB) { 1554 int argc = (b == CALL_MAXARGS) ? -1 : b; 1555 int bidx = (argc < 0) ? a+2 : a+b+1; 1556 mrb_method_t m; 1557 struct RClass *cls; 1527 1558 mrb_callinfo *ci = mrb->c->ci; 1528 struct RProc *m;1529 struct R Class *c;1559 mrb_value recv, blk; 1560 struct RProc *p = ci->proc; 1530 1561 mrb_sym mid = ci->mid; 1531 int a = GETARG_A(i);1532 int n = GETARG_C(i); 1533 mrb_value blk;1534 int bidx;1535 1536 if (mid == 0 || !ci->target_class) {1537 mrb_value exc; 1538 1539 exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");1562 struct RClass* target_class = MRB_PROC_TARGET_CLASS(p); 1563 1564 if (MRB_PROC_ENV_P(p) && p->e.env->mid && p->e.env->mid != mid) { /* alias support */ 1565 mid = p->e.env->mid; /* restore old mid */ 1566 } 1567 mrb_assert(bidx < irep->nregs); 1568 1569 if (mid == 0 || !target_class) { 1570 mrb_value exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method"); 1540 1571 mrb_exc_set(mrb, exc); 1541 1572 goto L_RAISE; 1542 1573 } 1574 if (target_class->tt == MRB_TT_MODULE) { 1575 target_class = ci->target_class; 1576 if (target_class->tt != MRB_TT_ICLASS) { 1577 mrb_value exc = mrb_exc_new_str_lit(mrb, E_RUNTIME_ERROR, "superclass info lost [mruby limitations]"); 1578 mrb_exc_set(mrb, exc); 1579 goto L_RAISE; 1580 } 1581 } 1543 1582 recv = regs[0]; 1544 c = mrb->c->ci->target_class->super; 1545 m = mrb_method_search_vm(mrb, &c, mid); 1546 if (!m) { 1583 if (!mrb_obj_is_kind_of(mrb, recv, target_class)) { 1584 mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, 1585 "self has wrong type to call super in this context"); 1586 mrb_exc_set(mrb, exc); 1587 goto L_RAISE; 1588 } 1589 blk = regs[bidx]; 1590 if (!mrb_nil_p(blk) && !mrb_proc_p(blk)) { 1591 blk = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); 1592 /* The stack or ci stack might have been reallocated during 1593 mrb_convert_type(), see #3622 and #3784 */ 1594 regs[bidx] = blk; 1595 ci = mrb->c->ci; 1596 } 1597 cls = target_class->super; 1598 m = mrb_method_search_vm(mrb, &cls, mid); 1599 if (MRB_METHOD_UNDEF_P(m)) { 1547 1600 mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); 1548 m = mrb_method_search_vm(mrb, &c, missing); 1549 if (!m) { 1550 mrb_value args; 1551 1552 if (n == CALL_MAXARGS) { 1553 args = regs[a+1]; 1554 } 1555 else { 1556 args = mrb_ary_new_from_values(mrb, n, regs+a+1); 1557 } 1558 ERR_PC_SET(mrb, pc); 1601 1602 if (mid != missing) { 1603 cls = mrb_class(mrb, recv); 1604 } 1605 m = mrb_method_search_vm(mrb, &cls, missing); 1606 if (MRB_METHOD_UNDEF_P(m)) { 1607 mrb_value args = (argc < 0) ? regs[a+1] : mrb_ary_new_from_values(mrb, b, regs+a+1); 1608 ERR_PC_SET(mrb); 1559 1609 mrb_method_missing(mrb, mid, recv, args); 1560 1610 } 1561 1611 mid = missing; 1562 if (n == CALL_MAXARGS-1) { 1563 regs[a+1] = mrb_ary_new_from_values(mrb, n, regs+a+1); 1564 n++; 1565 } 1566 if (n == CALL_MAXARGS) { 1567 mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid)); 1568 } 1569 else { 1570 value_move(regs+a+2, regs+a+1, ++n); 1571 SET_SYM_VALUE(regs[a+1], ci->mid); 1572 } 1573 } 1574 1575 if (n == CALL_MAXARGS) { 1576 bidx = a+2; 1577 } 1578 else { 1579 bidx = a+n+1; 1580 } 1581 blk = regs[bidx]; 1582 if (!mrb_nil_p(blk) && mrb_type(blk) != MRB_TT_PROC) { 1583 mrb_value result; 1584 1585 if (bidx >= ci->nregs) { 1586 stack_extend(mrb, bidx+1); 1587 ci->nregs = bidx+1; 1588 } 1589 result = mrb_convert_type(mrb, blk, MRB_TT_PROC, "Proc", "to_proc"); 1590 regs[bidx] = result; 1612 if (argc >= 0) { 1613 if (a+2 >= irep->nregs) { 1614 mrb_stack_extend(mrb, a+3); 1615 } 1616 regs[a+1] = mrb_ary_new_from_values(mrb, b, regs+a+1); 1617 regs[a+2] = blk; 1618 argc = -1; 1619 } 1620 mrb_ary_unshift(mrb, regs[a+1], mrb_symbol_value(ci->mid)); 1591 1621 } 1592 1622 … … 1594 1624 ci = cipush(mrb); 1595 1625 ci->mid = mid; 1596 ci->proc = m;1597 1626 ci->stackent = mrb->c->stack; 1598 ci->target_class = c; 1599 ci->pc = pc + 1; 1600 if (n == CALL_MAXARGS) { 1601 ci->argc = -1; 1602 } 1603 else { 1604 ci->argc = n; 1605 } 1627 ci->target_class = cls; 1628 ci->pc = pc; 1629 ci->argc = argc; 1606 1630 1607 1631 /* prepare stack */ … … 1609 1633 mrb->c->stack[0] = recv; 1610 1634 1611 if (MRB_ PROC_CFUNC_P(m)) {1635 if (MRB_METHOD_CFUNC_P(m)) { 1612 1636 mrb_value v; 1613 1637 1614 if (n == CALL_MAXARGS) { 1615 ci->nregs = 3; 1616 } 1617 else { 1618 ci->nregs = n + 2; 1619 } 1620 v = m->body.func(mrb, recv); 1638 if (MRB_METHOD_PROC_P(m)) { 1639 ci->proc = MRB_METHOD_PROC(m); 1640 } 1641 v = MRB_METHOD_CFUNC(m)(mrb, recv); 1621 1642 mrb_gc_arena_restore(mrb, ai); 1622 1643 if (mrb->exc) goto L_RAISE; … … 1647 1668 1648 1669 /* setup environment for calling method */ 1649 ci->proc = m;1650 irep = m->body.irep;1670 proc = ci->proc = MRB_METHOD_PROC(m); 1671 irep = proc->body.irep; 1651 1672 pool = irep->pool; 1652 1673 syms = irep->syms; 1653 ci->nregs = irep->nregs; 1654 if (n == CALL_MAXARGS) { 1655 stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs); 1656 } 1657 else { 1658 stack_extend(mrb, irep->nregs); 1659 } 1674 mrb_stack_extend(mrb, (argc < 0 && irep->nregs < 3) ? 3 : irep->nregs); 1660 1675 pc = irep->iseq; 1661 1676 JUMP; … … 1663 1678 } 1664 1679 1665 CASE(OP_ARGARY) { 1666 /* A Bx R(A) := argument array (16=6:1:5:4) */ 1667 int a = GETARG_A(i); 1668 int bx = GETARG_Bx(i); 1669 int m1 = (bx>>10)&0x3f; 1670 int r = (bx>>9)&0x1; 1671 int m2 = (bx>>4)&0x1f; 1672 int lv = (bx>>0)&0xf; 1680 CASE(OP_ARGARY, BS) { 1681 int m1 = (b>>11)&0x3f; 1682 int r = (b>>10)&0x1; 1683 int m2 = (b>>5)&0x1f; 1684 int kd = (b>>4)&0x1; 1685 int lv = (b>>0)&0xf; 1673 1686 mrb_value *stack; 1674 1687 … … 1685 1698 struct REnv *e = uvenv(mrb, lv-1); 1686 1699 if (!e) goto L_NOSUPER; 1700 if (MRB_ENV_STACK_LEN(e) <= m1+r+m2+kd+1) 1701 goto L_NOSUPER; 1687 1702 stack = e->stack + 1; 1688 1703 } 1689 1704 if (r == 0) { 1690 regs[a] = mrb_ary_new_from_values(mrb, m1+m2 , stack);1705 regs[a] = mrb_ary_new_from_values(mrb, m1+m2+kd, stack); 1691 1706 } 1692 1707 else { … … 1698 1713 struct RArray *ary = mrb_ary_ptr(stack[m1]); 1699 1714 1700 pp = ary->ptr;1701 len = ary->len;1702 } 1703 regs[a] = mrb_ary_new_capa(mrb, m1+len+m2 );1715 pp = ARY_PTR(ary); 1716 len = (int)ARY_LEN(ary); 1717 } 1718 regs[a] = mrb_ary_new_capa(mrb, m1+len+m2+kd); 1704 1719 rest = mrb_ary_ptr(regs[a]); 1705 1720 if (m1 > 0) { 1706 stack_copy( rest->ptr, stack, m1);1721 stack_copy(ARY_PTR(rest), stack, m1); 1707 1722 } 1708 1723 if (len > 0) { 1709 stack_copy( rest->ptr+m1, pp, len);1724 stack_copy(ARY_PTR(rest)+m1, pp, len); 1710 1725 } 1711 1726 if (m2 > 0) { 1712 stack_copy(rest->ptr+m1+len, stack+m1+1, m2); 1713 } 1714 rest->len = m1+len+m2; 1727 stack_copy(ARY_PTR(rest)+m1+len, stack+m1+1, m2); 1728 } 1729 if (kd) { 1730 stack_copy(ARY_PTR(rest)+m1+len+m2, stack+m1+m2+1, kd); 1731 } 1732 ARY_SET_LEN(rest, m1+len+m2+kd); 1715 1733 } 1716 1734 regs[a+1] = stack[m1+r+m2]; 1717 ARENA_RESTORE(mrb, ai); 1718 NEXT; 1719 } 1720 1721 CASE(OP_ENTER) { 1722 /* Ax arg setup according to flags (23=5:5:1:5:5:1:1) */ 1723 /* number of optional arguments times OP_JMP should follow */ 1724 mrb_aspec ax = GETARG_Ax(i); 1725 int m1 = MRB_ASPEC_REQ(ax); 1726 int o = MRB_ASPEC_OPT(ax); 1727 int r = MRB_ASPEC_REST(ax); 1728 int m2 = MRB_ASPEC_POST(ax); 1735 mrb_gc_arena_restore(mrb, ai); 1736 NEXT; 1737 } 1738 1739 CASE(OP_ENTER, W) { 1740 int m1 = MRB_ASPEC_REQ(a); 1741 int o = MRB_ASPEC_OPT(a); 1742 int r = MRB_ASPEC_REST(a); 1743 int m2 = MRB_ASPEC_POST(a); 1744 int kd = (MRB_ASPEC_KEY(a) > 0 || MRB_ASPEC_KDICT(a))? 1 : 0; 1729 1745 /* unused 1730 int k = MRB_ASPEC_KEY(ax); 1731 int kd = MRB_ASPEC_KDICT(ax); 1732 int b = MRB_ASPEC_BLOCK(ax); 1746 int b = MRB_ASPEC_BLOCK(a); 1733 1747 */ 1734 1748 int argc = mrb->c->ci->argc; 1735 1749 mrb_value *argv = regs+1; 1736 mrb_value *argv0 = argv; 1737 int len = m1 + o + r + m2; 1750 mrb_value * const argv0 = argv; 1751 int const len = m1 + o + r + m2; 1752 int const blk_pos = len + kd + 1; 1738 1753 mrb_value *blk = &argv[argc < 0 ? 1 : argc]; 1739 1754 mrb_value kdict; 1755 int kargs = kd; 1756 1757 /* arguments is passed with Array */ 1740 1758 if (argc < 0) { 1741 1759 struct RArray *ary = mrb_ary_ptr(regs[1]); 1742 argv = ary->ptr;1743 argc = ary->len;1760 argv = ARY_PTR(ary); 1761 argc = (int)ARY_LEN(ary); 1744 1762 mrb_gc_protect(mrb, regs[1]); 1745 1763 } 1764 1765 /* strict argument check */ 1746 1766 if (mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc)) { 1747 if (argc >= 0) { 1748 if (argc < m1 + m2 || (r == 0 && argc > len)) { 1767 if (argc < m1 + m2 || (r == 0 && argc > len + kd)) { 1768 argnum_error(mrb, m1+m2); 1769 goto L_RAISE; 1770 } 1771 } 1772 /* extract first argument array to arguments */ 1773 else if (len > 1 && argc == 1 && mrb_array_p(argv[0])) { 1774 mrb_gc_protect(mrb, argv[0]); 1775 argc = (int)RARRAY_LEN(argv[0]); 1776 argv = RARRAY_PTR(argv[0]); 1777 } 1778 1779 if (kd) { 1780 /* check last arguments is hash if method takes keyword arguments */ 1781 if (argc == m1+m2) { 1782 kdict = mrb_hash_new(mrb); 1783 kargs = 0; 1784 } 1785 else { 1786 if (argv && argc > 0 && mrb_hash_p(argv[argc-1])) { 1787 kdict = argv[argc-1]; 1788 mrb_hash_check_kdict(mrb, kdict); 1789 } 1790 else if (r || argc <= m1+m2+o 1791 || !(mrb->c->ci->proc && MRB_PROC_STRICT_P(mrb->c->ci->proc))) { 1792 kdict = mrb_hash_new(mrb); 1793 kargs = 0; 1794 } 1795 else { 1749 1796 argnum_error(mrb, m1+m2); 1750 1797 goto L_RAISE; 1751 1798 } 1752 }1753 }1754 else if (len > 1 && argc == 1 && mrb_array_p(argv[0])) {1755 mrb_gc_protect(mrb, argv[0]);1756 argc = mrb_ary_ptr(argv[0])->len;1757 argv = mrb_ary_ptr(argv[0])->ptr; 1758 }1759 if (argc < len) {1799 if (MRB_ASPEC_KEY(a) > 0) { 1800 kdict = mrb_hash_dup(mrb, kdict); 1801 } 1802 } 1803 } 1804 1805 /* no rest arguments */ 1806 if (argc-kargs < len) { 1760 1807 int mlen = m2; 1761 1808 if (argc < m1+m2) { 1762 if (m1 < argc) 1763 mlen = argc - m1; 1764 else 1765 mlen = 0; 1766 } 1767 regs[len+1] = *blk; /* move block */ 1768 SET_NIL_VALUE(regs[argc+1]); 1809 mlen = m1 < argc ? argc - m1 : 0; 1810 } 1811 regs[blk_pos] = *blk; /* move block */ 1812 if (kd) regs[len + 1] = kdict; 1813 1814 /* copy mandatory and optional arguments */ 1769 1815 if (argv0 != argv) { 1770 1816 value_move(®s[1], argv, argc-mlen); /* m1 + o */ … … 1773 1819 stack_clear(®s[argc+1], m1-argc); 1774 1820 } 1821 /* copy post mandatory arguments */ 1775 1822 if (mlen) { 1776 1823 value_move(®s[len-m2+1], &argv[argc-mlen], mlen); … … 1779 1826 stack_clear(®s[len-m2+mlen+1], m2-mlen); 1780 1827 } 1828 /* initalize rest arguments with empty Array */ 1781 1829 if (r) { 1782 1830 regs[m1+o+1] = mrb_ary_new_capa(mrb, 0); 1783 1831 } 1784 if (o == 0 || argc < m1+m2) pc++;1785 else1786 pc += argc - m1 - m2 + 1;1832 /* skip initailizer of passed arguments */ 1833 if (o > 0 && argc-kargs > m1+m2) 1834 pc += (argc - kargs - m1 - m2)*3; 1787 1835 } 1788 1836 else { 1789 1837 int rnum = 0; 1790 1838 if (argv0 != argv) { 1791 regs[len+1] = *blk; /* move block */ 1839 regs[blk_pos] = *blk; /* move block */ 1840 if (kd) regs[len + 1] = kdict; 1792 1841 value_move(®s[1], argv, m1+o); 1793 1842 } 1794 1843 if (r) { 1795 rnum = argc-m1-o-m2; 1796 regs[m1+o+1] = mrb_ary_new_from_values(mrb, rnum, argv+m1+o); 1844 mrb_value ary; 1845 1846 rnum = argc-m1-o-m2-kargs; 1847 ary = mrb_ary_new_from_values(mrb, rnum, argv+m1+o); 1848 regs[m1+o+1] = ary; 1797 1849 } 1798 1850 if (m2) { … … 1802 1854 } 1803 1855 if (argv0 == argv) { 1804 regs[len+1] = *blk; /* move block */ 1805 } 1806 pc += o + 1; 1807 } 1808 mrb->c->ci->argc = len; 1856 regs[blk_pos] = *blk; /* move block */ 1857 if (kd) regs[len + 1] = kdict; 1858 } 1859 pc += o*3; 1860 } 1861 1862 /* format arguments for generated code */ 1863 mrb->c->ci->argc = len + kd; 1864 1809 1865 /* clear local (but non-argument) variables */ 1810 if (irep->nlocals- len-2> 0) {1811 stack_clear(®s[ len+2], irep->nlocals-len-2);1866 if (irep->nlocals-blk_pos-1 > 0) { 1867 stack_clear(®s[blk_pos+1], irep->nlocals-blk_pos-1); 1812 1868 } 1813 1869 JUMP; 1814 1870 } 1815 1871 1816 CASE(OP_KARG) { 1817 /* A B C R(A) := kdict[Syms(B)]; if C kdict.rm(Syms(B)) */ 1818 /* if C == 2; raise unless kdict.empty? */ 1819 /* OP_JMP should follow to skip init code */ 1820 NEXT; 1821 } 1822 1823 CASE(OP_KDICT) { 1824 /* A C R(A) := kdict */ 1825 NEXT; 1826 } 1827 1872 CASE(OP_KARG, BB) { 1873 mrb_value k = mrb_symbol_value(syms[b]); 1874 mrb_value kdict = regs[mrb->c->ci->argc]; 1875 1876 if (!mrb_hash_p(kdict) || !mrb_hash_key_p(mrb, kdict, k)) { 1877 mrb_value str = mrb_format(mrb, "missing keyword: %v", k); 1878 mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str)); 1879 goto L_RAISE; 1880 } 1881 regs[a] = mrb_hash_get(mrb, kdict, k); 1882 mrb_hash_delete_key(mrb, kdict, k); 1883 NEXT; 1884 } 1885 1886 CASE(OP_KEY_P, BB) { 1887 mrb_value k = mrb_symbol_value(syms[b]); 1888 mrb_value kdict = regs[mrb->c->ci->argc]; 1889 mrb_bool key_p = FALSE; 1890 1891 if (mrb_hash_p(kdict)) { 1892 key_p = mrb_hash_key_p(mrb, kdict, k); 1893 } 1894 regs[a] = mrb_bool_value(key_p); 1895 NEXT; 1896 } 1897 1898 CASE(OP_KEYEND, Z) { 1899 mrb_value kdict = regs[mrb->c->ci->argc]; 1900 1901 if (mrb_hash_p(kdict) && !mrb_hash_empty_p(mrb, kdict)) { 1902 mrb_value keys = mrb_hash_keys(mrb, kdict); 1903 mrb_value key1 = RARRAY_PTR(keys)[0]; 1904 mrb_value str = mrb_format(mrb, "unknown keyword: %v", key1); 1905 mrb_exc_set(mrb, mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str)); 1906 goto L_RAISE; 1907 } 1908 NEXT; 1909 } 1910 1911 CASE(OP_BREAK, B) { 1912 c = OP_R_BREAK; 1913 goto L_RETURN; 1914 } 1915 CASE(OP_RETURN_BLK, B) { 1916 c = OP_R_RETURN; 1917 goto L_RETURN; 1918 } 1919 CASE(OP_RETURN, B) 1920 c = OP_R_NORMAL; 1828 1921 L_RETURN: 1829 i = MKOP_AB(OP_RETURN, GETARG_A(i), OP_R_NORMAL); 1830 /* fall through */ 1831 CASE(OP_RETURN) { 1832 /* A B return R(A) (B=normal,in-block return/break) */ 1833 mrb_callinfo *ci; 1922 { 1923 mrb_callinfo *ci; 1924 1925 #define ecall_adjust() do {\ 1926 ptrdiff_t cioff = ci - mrb->c->cibase;\ 1927 ecall(mrb);\ 1928 ci = mrb->c->cibase + cioff;\ 1929 } while (0) 1834 1930 1835 1931 ci = mrb->c->ci; … … 1843 1939 blk = regs[ci->argc+1]; 1844 1940 } 1845 if (mrb_ type(blk) == MRB_TT_PROC) {1941 if (mrb_proc_p(blk)) { 1846 1942 struct RProc *p = mrb_proc_ptr(blk); 1847 1943 1848 if (!MRB_PROC_STRICT_P(p roc) &&1849 ci > mrb->c->cibase && p->env== ci[-1].env) {1944 if (!MRB_PROC_STRICT_P(p) && 1945 ci > mrb->c->cibase && MRB_PROC_ENV(p) == ci[-1].env) { 1850 1946 p->flags |= MRB_PROC_ORPHAN; 1851 1947 } … … 1855 1951 if (mrb->exc) { 1856 1952 mrb_callinfo *ci0; 1857 mrb_value *stk;1858 1953 1859 1954 L_RAISE: … … 1863 1958 goto L_RESCUE; 1864 1959 } 1865 stk = mrb->c->stack;1866 1960 while (ci[0].ridx == ci[-1].ridx) { 1867 1961 cipop(mrb); … … 1873 1967 ci = mrb->c->ci; 1874 1968 if (ci == mrb->c->cibase) { 1875 mrb->c->stack = stk;1876 1969 if (ci->ridx == 0) { 1877 1970 L_FTOP: /* fiber top */ … … 1883 1976 struct mrb_context *c = mrb->c; 1884 1977 1885 if (c->fib) {1886 mrb_write_barrier(mrb, (struct RBasic*)c->fib);1978 while (c->eidx > ci->epos) { 1979 ecall_adjust(); 1887 1980 } 1981 c->status = MRB_FIBER_TERMINATED; 1888 1982 mrb->c = c->prev; 1889 1983 c->prev = NULL; … … 1896 1990 if (ci[0].ridx == ci[-1].ridx) { 1897 1991 while (mrb->c->eidx > ci->epos) { 1898 ecall(mrb, --mrb->c->eidx); 1899 ci = mrb->c->ci; 1992 ecall_adjust(); 1900 1993 } 1901 1994 } … … 1907 2000 pool = irep->pool; 1908 2001 syms = irep->syms; 1909 if (ci !=ci0) {2002 if (ci < ci0) { 1910 2003 mrb->c->stack = ci[1].stackent; 1911 2004 } 1912 stack_extend(mrb, irep->nregs);1913 pc = mrb->c->rescue[--ci->ridx];2005 mrb_stack_extend(mrb, irep->nregs); 2006 pc = irep->iseq+mrb->c->rescue[--ci->ridx]; 1914 2007 } 1915 2008 else { 1916 2009 int acc; 1917 2010 mrb_value v; 1918 1919 v = regs[GETARG_A(i)]; 2011 struct RProc *dst; 2012 2013 ci = mrb->c->ci; 2014 v = regs[a]; 1920 2015 mrb_gc_protect(mrb, v); 1921 switch ( GETARG_B(i)) {2016 switch (c) { 1922 2017 case OP_R_RETURN: 1923 2018 /* Fall through to OP_R_NORMAL otherwise */ 1924 if (ci->acc >=0 && proc->env && !MRB_PROC_STRICT_P(proc)) { 1925 struct REnv *e = top_env(mrb, proc); 1926 mrb_callinfo *ce; 1927 1928 if (!MRB_ENV_STACK_SHARED_P(e) || e->cxt.c != mrb->c) { 1929 localjump_error(mrb, LOCALJUMP_ERROR_RETURN); 1930 goto L_RAISE; 2019 if (ci->acc >=0 && MRB_PROC_ENV_P(proc) && !MRB_PROC_STRICT_P(proc)) { 2020 mrb_callinfo *cibase = mrb->c->cibase; 2021 dst = top_proc(mrb, proc); 2022 2023 if (MRB_PROC_ENV_P(dst)) { 2024 struct REnv *e = MRB_PROC_ENV(dst); 2025 2026 if (!MRB_ENV_STACK_SHARED_P(e) || (e->cxt && e->cxt != mrb->c)) { 2027 localjump_error(mrb, LOCALJUMP_ERROR_RETURN); 2028 goto L_RAISE; 2029 } 1931 2030 } 1932 1933 ce = mrb->c->cibase + e->cioff; 1934 while (ci >= ce) { 1935 if (ci->env) { 1936 mrb_env_unshare(mrb, ci->env); 1937 } 2031 while (cibase <= ci && ci->proc != dst) { 1938 2032 if (ci->acc < 0) { 1939 2033 localjump_error(mrb, LOCALJUMP_ERROR_RETURN); … … 1942 2036 ci--; 1943 2037 } 1944 if (c e == mrb->c->cibase) {2038 if (ci <= cibase) { 1945 2039 localjump_error(mrb, LOCALJUMP_ERROR_RETURN); 1946 2040 goto L_RAISE; 1947 2041 } 1948 mrb->c->stack = mrb->c->ci->stackent;1949 mrb->c->ci = ce;1950 2042 break; 1951 2043 } 2044 /* fallthrough */ 1952 2045 case OP_R_NORMAL: 1953 2046 NORMAL_RETURN: 1954 2047 if (ci == mrb->c->cibase) { 1955 if (!mrb->c->prev) { /* toplevel return */ 1956 localjump_error(mrb, LOCALJUMP_ERROR_RETURN); 1957 goto L_RAISE; 2048 struct mrb_context *c = mrb->c; 2049 2050 if (!c->prev) { /* toplevel return */ 2051 regs[irep->nlocals] = v; 2052 goto L_STOP; 1958 2053 } 1959 if ( mrb->c->prev->ci == mrb->c->prev->cibase) {2054 if (c->prev->ci == c->prev->cibase) { 1960 2055 mrb_value exc = mrb_exc_new_str_lit(mrb, E_FIBER_ERROR, "double resume"); 1961 2056 mrb_exc_set(mrb, exc); 1962 2057 goto L_RAISE; 1963 2058 } 1964 while ( mrb->c->eidx > 0) {1965 ecall(mrb , --mrb->c->eidx);2059 while (c->eidx > 0) { 2060 ecall(mrb); 1966 2061 } 1967 2062 /* automatic yield at the end */ 1968 mrb->c->status = MRB_FIBER_TERMINATED; 1969 mrb->c = mrb->c->prev; 2063 c->status = MRB_FIBER_TERMINATED; 2064 mrb->c = c->prev; 2065 c->prev = NULL; 1970 2066 mrb->c->status = MRB_FIBER_RUNNING; 1971 }1972 ci = mrb->c->ci;2067 ci = mrb->c->ci; 2068 } 1973 2069 break; 1974 2070 case OP_R_BREAK: 1975 2071 if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN; 1976 if (MRB_PROC_ORPHAN_P(proc)) { 2072 if (MRB_PROC_ORPHAN_P(proc)) { 1977 2073 mrb_value exc; 1978 2074 … … 1983 2079 goto L_RAISE; 1984 2080 } 1985 if (! proc->env || !MRB_ENV_STACK_SHARED_P(proc->env)) {2081 if (!MRB_PROC_ENV_P(proc) || !MRB_ENV_STACK_SHARED_P(MRB_PROC_ENV(proc))) { 1986 2082 goto L_BREAK_ERROR; 1987 2083 } 2084 else { 2085 struct REnv *e = MRB_PROC_ENV(proc); 2086 2087 if (e->cxt != mrb->c) { 2088 goto L_BREAK_ERROR; 2089 } 2090 } 2091 while (mrb->c->eidx > mrb->c->ci->epos) { 2092 ecall_adjust(); 2093 } 1988 2094 /* break from fiber block */ 1989 if ( mrb->c->ci == mrb->c->cibase && mrb->c->ci->pc) {2095 if (ci == mrb->c->cibase && ci->pc) { 1990 2096 struct mrb_context *c = mrb->c; 1991 2097 1992 while (mrb->c->eidx > 0) {1993 ecall(mrb, --mrb->c->eidx);1994 }1995 2098 mrb->c = c->prev; 1996 2099 c->prev = NULL; … … 1998 2101 } 1999 2102 if (ci->acc < 0) { 2000 while (mrb->c->eidx > mrb->c->ci->epos) { 2001 ecall(mrb, --mrb->c->eidx); 2002 } 2003 ARENA_RESTORE(mrb, ai); 2103 mrb_gc_arena_restore(mrb, ai); 2004 2104 mrb->c->vmexec = FALSE; 2005 2105 mrb->exc = (struct RObject*)break_new(mrb, proc, v); … … 2009 2109 if (FALSE) { 2010 2110 L_BREAK: 2011 v = ((struct RBreak*)mrb->exc)->val;2012 proc = ((struct RBreak*)mrb->exc)->proc;2111 v = mrb_break_value_get((struct RBreak*)mrb->exc); 2112 proc = mrb_break_proc_get((struct RBreak*)mrb->exc); 2013 2113 mrb->exc = NULL; 2014 2114 ci = mrb->c->ci; 2015 2115 } 2016 2116 mrb->c->stack = ci->stackent; 2017 mrb->c->ci = mrb->c->cibase + proc->env->cioff + 1; 2018 while (ci > mrb->c->ci) { 2019 if (ci->env) { 2020 mrb_env_unshare(mrb, ci->env); 2021 } 2117 proc = proc->upper; 2118 while (mrb->c->cibase < ci && ci[-1].proc != proc) { 2022 2119 if (ci[-1].acc == CI_ACC_SKIP) { 2023 mrb->c->ci = ci; 2120 while (ci < mrb->c->ci) { 2121 cipop(mrb); 2122 } 2024 2123 goto L_BREAK_ERROR; 2025 2124 } 2026 2125 ci--; 2126 } 2127 if (ci == mrb->c->cibase) { 2128 goto L_BREAK_ERROR; 2027 2129 } 2028 2130 break; … … 2031 2133 break; 2032 2134 } 2033 while (mrb->c->eidx > mrb->c->ci->epos) { 2034 ecall(mrb, --mrb->c->eidx); 2035 } 2036 if (mrb->c->vmexec && !mrb->c->ci->target_class) { 2037 ARENA_RESTORE(mrb, ai); 2135 while (ci < mrb->c->ci) { 2136 cipop(mrb); 2137 } 2138 ci[0].ridx = ci[-1].ridx; 2139 while (mrb->c->eidx > ci->epos) { 2140 ecall_adjust(); 2141 } 2142 if (mrb->c->vmexec && !ci->target_class) { 2143 mrb_gc_arena_restore(mrb, ai); 2038 2144 mrb->c->vmexec = FALSE; 2039 2145 mrb->jmp = prev_jmp; 2040 2146 return v; 2041 2147 } 2042 ci = mrb->c->ci;2043 2148 acc = ci->acc; 2044 2149 mrb->c->stack = ci->stackent; 2045 2150 cipop(mrb); 2046 2151 if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) { 2047 ARENA_RESTORE(mrb, ai);2152 mrb_gc_arena_restore(mrb, ai); 2048 2153 mrb->jmp = prev_jmp; 2049 2154 return v; 2050 2155 } 2051 2156 pc = ci->pc; 2052 DEBUG(fprintf(stderr, "from :%s\n", mrb_sym2name(mrb, ci->mid))); 2157 ci = mrb->c->ci; 2158 DEBUG(fprintf(stderr, "from :%s\n", mrb_sym_name(mrb, ci->mid))); 2053 2159 proc = mrb->c->ci->proc; 2054 2160 irep = proc->body.irep; … … 2057 2163 2058 2164 regs[acc] = v; 2059 ARENA_RESTORE(mrb, ai);2165 mrb_gc_arena_restore(mrb, ai); 2060 2166 } 2061 2167 JUMP; 2062 2168 } 2063 2169 2064 CASE(OP_TAILCALL) { 2065 /* A B C return call(R(A),Syms(B),R(A+1),... ,R(A+C+1)) */ 2066 int a = GETARG_A(i); 2067 int n = GETARG_C(i); 2068 struct RProc *m; 2069 struct RClass *c; 2070 mrb_callinfo *ci; 2071 mrb_value recv; 2072 mrb_sym mid = syms[GETARG_B(i)]; 2073 2074 recv = regs[a]; 2075 c = mrb_class(mrb, recv); 2076 m = mrb_method_search_vm(mrb, &c, mid); 2077 if (!m) { 2078 mrb_value sym = mrb_symbol_value(mid); 2079 mrb_sym missing = mrb_intern_lit(mrb, "method_missing"); 2080 m = mrb_method_search_vm(mrb, &c, missing); 2081 if (!m) { 2082 mrb_value args; 2083 2084 if (n == CALL_MAXARGS) { 2085 args = regs[a+1]; 2086 } 2087 else { 2088 args = mrb_ary_new_from_values(mrb, n, regs+a+1); 2089 } 2090 ERR_PC_SET(mrb, pc); 2091 mrb_method_missing(mrb, mid, recv, args); 2092 } 2093 mid = missing; 2094 if (n == CALL_MAXARGS) { 2095 mrb_ary_unshift(mrb, regs[a+1], sym); 2096 } 2097 else { 2098 value_move(regs+a+2, regs+a+1, ++n); 2099 regs[a+1] = sym; 2100 } 2101 } 2102 2103 /* replace callinfo */ 2104 ci = mrb->c->ci; 2105 ci->mid = mid; 2106 ci->target_class = c; 2107 if (n == CALL_MAXARGS) { 2108 ci->argc = -1; 2109 } 2110 else { 2111 ci->argc = n; 2112 } 2113 2114 /* move stack */ 2115 value_move(mrb->c->stack, ®s[a], ci->argc+1); 2116 2117 if (MRB_PROC_CFUNC_P(m)) { 2118 mrb_value v = m->body.func(mrb, recv); 2119 mrb->c->stack[0] = v; 2120 mrb_gc_arena_restore(mrb, ai); 2121 goto L_RETURN; 2122 } 2123 else { 2124 /* setup environment for calling method */ 2125 irep = m->body.irep; 2126 pool = irep->pool; 2127 syms = irep->syms; 2128 if (ci->argc < 0) { 2129 stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs); 2130 } 2131 else { 2132 stack_extend(mrb, irep->nregs); 2133 } 2134 pc = irep->iseq; 2135 } 2136 JUMP; 2137 } 2138 2139 CASE(OP_BLKPUSH) { 2140 /* A Bx R(A) := block (16=6:1:5:4) */ 2141 int a = GETARG_A(i); 2142 int bx = GETARG_Bx(i); 2143 int m1 = (bx>>10)&0x3f; 2144 int r = (bx>>9)&0x1; 2145 int m2 = (bx>>4)&0x1f; 2146 int lv = (bx>>0)&0xf; 2170 CASE(OP_BLKPUSH, BS) { 2171 int m1 = (b>>11)&0x3f; 2172 int r = (b>>10)&0x1; 2173 int m2 = (b>>5)&0x1f; 2174 int kd = (b>>4)&0x1; 2175 int lv = (b>>0)&0xf; 2147 2176 mrb_value *stack; 2148 2177 … … 2150 2179 else { 2151 2180 struct REnv *e = uvenv(mrb, lv-1); 2152 if (!e || e->cioff == 0||2153 (!MRB_ENV_STACK_SHARED_P(e) && e->cxt.mid == 0)) {2181 if (!e || (!MRB_ENV_STACK_SHARED_P(e) && e->mid == 0) || 2182 MRB_ENV_STACK_LEN(e) <= m1+r+m2+1) { 2154 2183 localjump_error(mrb, LOCALJUMP_ERROR_YIELD); 2155 2184 goto L_RAISE; … … 2161 2190 goto L_RAISE; 2162 2191 } 2163 regs[a] = stack[m1+r+m2 ];2192 regs[a] = stack[m1+r+m2+kd]; 2164 2193 NEXT; 2165 2194 } 2166 2195 2167 2196 #define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff)) 2168 #define OP_MATH_BODY(op,v1,v2) do {\ 2169 v1(regs[a]) = v1(regs[a]) op v2(regs[a+1]);\ 2170 } while(0) 2171 2172 CASE(OP_ADD) { 2173 /* A B C R(A) := R(A)+R(A+1) (Syms[B]=:+,C=1)*/ 2174 int a = GETARG_A(i); 2197 #define OP_MATH(op_name) \ 2198 /* need to check if op is overridden */ \ 2199 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { \ 2200 OP_MATH_CASE_FIXNUM(op_name); \ 2201 OP_MATH_CASE_FLOAT(op_name, fixnum, float); \ 2202 OP_MATH_CASE_FLOAT(op_name, float, fixnum); \ 2203 OP_MATH_CASE_FLOAT(op_name, float, float); \ 2204 OP_MATH_CASE_STRING_##op_name(); \ 2205 default: \ 2206 c = 1; \ 2207 mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name)); \ 2208 goto L_SEND_SYM; \ 2209 } \ 2210 NEXT; 2211 #define OP_MATH_CASE_FIXNUM(op_name) \ 2212 case TYPES2(MRB_TT_FIXNUM, MRB_TT_FIXNUM): \ 2213 { \ 2214 mrb_int x = mrb_fixnum(regs[a]), y = mrb_fixnum(regs[a+1]), z; \ 2215 if (mrb_int_##op_name##_overflow(x, y, &z)) \ 2216 OP_MATH_OVERFLOW_INT(op_name, x, y, z); \ 2217 else \ 2218 SET_INT_VALUE(regs[a], z); \ 2219 } \ 2220 break 2221 #ifdef MRB_WITHOUT_FLOAT 2222 #define OP_MATH_CASE_FLOAT(op_name, t1, t2) (void)0 2223 #define OP_MATH_OVERFLOW_INT(op_name, x, y, z) SET_INT_VALUE(regs[a], z) 2224 #else 2225 #define OP_MATH_CASE_FLOAT(op_name, t1, t2) \ 2226 case TYPES2(OP_MATH_TT_##t1, OP_MATH_TT_##t2): \ 2227 { \ 2228 mrb_float z = mrb_##t1(regs[a]) OP_MATH_OP_##op_name mrb_##t2(regs[a+1]); \ 2229 SET_FLOAT_VALUE(mrb, regs[a], z); \ 2230 } \ 2231 break 2232 #define OP_MATH_OVERFLOW_INT(op_name, x, y, z) \ 2233 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x OP_MATH_OP_##op_name (mrb_float)y) 2234 #endif 2235 #define OP_MATH_CASE_STRING_add() \ 2236 case TYPES2(MRB_TT_STRING, MRB_TT_STRING): \ 2237 regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); \ 2238 mrb_gc_arena_restore(mrb, ai); \ 2239 break 2240 #define OP_MATH_CASE_STRING_sub() (void)0 2241 #define OP_MATH_CASE_STRING_mul() (void)0 2242 #define OP_MATH_OP_add + 2243 #define OP_MATH_OP_sub - 2244 #define OP_MATH_OP_mul * 2245 #define OP_MATH_TT_fixnum MRB_TT_FIXNUM 2246 #define OP_MATH_TT_float MRB_TT_FLOAT 2247 2248 CASE(OP_ADD, B) { 2249 OP_MATH(add); 2250 } 2251 2252 CASE(OP_SUB, B) { 2253 OP_MATH(sub); 2254 } 2255 2256 CASE(OP_MUL, B) { 2257 OP_MATH(mul); 2258 } 2259 2260 CASE(OP_DIV, B) { 2261 #ifndef MRB_WITHOUT_FLOAT 2262 double x, y, f; 2263 #endif 2175 2264 2176 2265 /* need to check if op is overridden */ 2177 2266 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { 2178 2267 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): 2179 { 2180 mrb_int x, y, z; 2181 mrb_value *regs_a = regs + a; 2182 2183 x = mrb_fixnum(regs_a[0]); 2184 y = mrb_fixnum(regs_a[1]); 2185 if (mrb_int_add_overflow(x, y, &z)) { 2186 SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x + (mrb_float)y); 2187 break; 2188 } 2189 SET_INT_VALUE(regs[a], z); 2190 } 2191 break; 2192 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): 2193 { 2194 mrb_int x = mrb_fixnum(regs[a]); 2195 mrb_float y = mrb_float(regs[a+1]); 2196 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + y); 2197 } 2198 break; 2199 case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): 2200 #ifdef MRB_WORD_BOXING 2201 { 2202 mrb_float x = mrb_float(regs[a]); 2203 mrb_int y = mrb_fixnum(regs[a+1]); 2204 SET_FLOAT_VALUE(mrb, regs[a], x + y); 2205 } 2206 #else 2207 OP_MATH_BODY(+,mrb_float,mrb_fixnum); 2208 #endif 2209 break; 2210 case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): 2211 #ifdef MRB_WORD_BOXING 2212 { 2213 mrb_float x = mrb_float(regs[a]); 2214 mrb_float y = mrb_float(regs[a+1]); 2215 SET_FLOAT_VALUE(mrb, regs[a], x + y); 2216 } 2217 #else 2218 OP_MATH_BODY(+,mrb_float,mrb_float); 2219 #endif 2220 break; 2221 case TYPES2(MRB_TT_STRING,MRB_TT_STRING): 2222 regs[a] = mrb_str_plus(mrb, regs[a], regs[a+1]); 2223 break; 2224 default: 2225 goto L_SEND; 2226 } 2227 ARENA_RESTORE(mrb, ai); 2228 NEXT; 2229 } 2230 2231 CASE(OP_SUB) { 2232 /* A B C R(A) := R(A)-R(A+1) (Syms[B]=:-,C=1)*/ 2233 int a = GETARG_A(i); 2234 2235 /* need to check if op is overridden */ 2236 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { 2237 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): 2238 { 2239 mrb_int x, y, z; 2240 2241 x = mrb_fixnum(regs[a]); 2242 y = mrb_fixnum(regs[a+1]); 2243 if (mrb_int_sub_overflow(x, y, &z)) { 2244 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - (mrb_float)y); 2245 break; 2246 } 2247 SET_INT_VALUE(regs[a], z); 2248 } 2249 break; 2250 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): 2251 { 2252 mrb_int x = mrb_fixnum(regs[a]); 2253 mrb_float y = mrb_float(regs[a+1]); 2254 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x - y); 2255 } 2256 break; 2257 case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): 2258 #ifdef MRB_WORD_BOXING 2259 { 2260 mrb_float x = mrb_float(regs[a]); 2261 mrb_int y = mrb_fixnum(regs[a+1]); 2262 SET_FLOAT_VALUE(mrb, regs[a], x - y); 2263 } 2264 #else 2265 OP_MATH_BODY(-,mrb_float,mrb_fixnum); 2266 #endif 2267 break; 2268 case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): 2269 #ifdef MRB_WORD_BOXING 2270 { 2271 mrb_float x = mrb_float(regs[a]); 2272 mrb_float y = mrb_float(regs[a+1]); 2273 SET_FLOAT_VALUE(mrb, regs[a], x - y); 2274 } 2275 #else 2276 OP_MATH_BODY(-,mrb_float,mrb_float); 2277 #endif 2278 break; 2279 default: 2280 goto L_SEND; 2281 } 2282 NEXT; 2283 } 2284 2285 CASE(OP_MUL) { 2286 /* A B C R(A) := R(A)*R(A+1) (Syms[B]=:*,C=1)*/ 2287 int a = GETARG_A(i); 2288 2289 /* need to check if op is overridden */ 2290 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { 2291 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): 2292 { 2293 mrb_int x, y, z; 2294 2295 x = mrb_fixnum(regs[a]); 2296 y = mrb_fixnum(regs[a+1]); 2297 if (mrb_int_mul_overflow(x, y, &z)) { 2298 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * (mrb_float)y); 2299 break; 2300 } 2301 SET_INT_VALUE(regs[a], z); 2302 } 2303 break; 2304 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): 2305 { 2306 mrb_int x = mrb_fixnum(regs[a]); 2307 mrb_float y = mrb_float(regs[a+1]); 2308 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x * y); 2309 } 2310 break; 2311 case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): 2312 #ifdef MRB_WORD_BOXING 2313 { 2314 mrb_float x = mrb_float(regs[a]); 2315 mrb_int y = mrb_fixnum(regs[a+1]); 2316 SET_FLOAT_VALUE(mrb, regs[a], x * y); 2317 } 2318 #else 2319 OP_MATH_BODY(*,mrb_float,mrb_fixnum); 2320 #endif 2321 break; 2322 case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): 2323 #ifdef MRB_WORD_BOXING 2324 { 2325 mrb_float x = mrb_float(regs[a]); 2326 mrb_float y = mrb_float(regs[a+1]); 2327 SET_FLOAT_VALUE(mrb, regs[a], x * y); 2328 } 2329 #else 2330 OP_MATH_BODY(*,mrb_float,mrb_float); 2331 #endif 2332 break; 2333 default: 2334 goto L_SEND; 2335 } 2336 NEXT; 2337 } 2338 2339 CASE(OP_DIV) { 2340 /* A B C R(A) := R(A)/R(A+1) (Syms[B]=:/,C=1)*/ 2341 int a = GETARG_A(i); 2342 2343 /* need to check if op is overridden */ 2344 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) { 2345 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM): 2268 #ifdef MRB_WITHOUT_FLOAT 2346 2269 { 2347 2270 mrb_int x = mrb_fixnum(regs[a]); 2348 2271 mrb_int y = mrb_fixnum(regs[a+1]); 2349 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / (mrb_float)y); 2350 } 2272 SET_INT_VALUE(regs[a], y ? x / y : 0); 2273 } 2274 break; 2275 #else 2276 x = (mrb_float)mrb_fixnum(regs[a]); 2277 y = (mrb_float)mrb_fixnum(regs[a+1]); 2351 2278 break; 2352 2279 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT): 2353 { 2354 mrb_int x = mrb_fixnum(regs[a]); 2355 mrb_float y = mrb_float(regs[a+1]); 2356 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / y); 2357 } 2280 x = (mrb_float)mrb_fixnum(regs[a]); 2281 y = mrb_float(regs[a+1]); 2358 2282 break; 2359 2283 case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM): 2360 #ifdef MRB_WORD_BOXING 2361 { 2362 mrb_float x = mrb_float(regs[a]); 2363 mrb_int y = mrb_fixnum(regs[a+1]); 2364 SET_FLOAT_VALUE(mrb, regs[a], x / y); 2365 } 2366 #else 2367 OP_MATH_BODY(/,mrb_float,mrb_fixnum); 2368 #endif 2284 x = mrb_float(regs[a]); 2285 y = (mrb_float)mrb_fixnum(regs[a+1]); 2369 2286 break; 2370 2287 case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT): 2371 #ifdef MRB_WORD_BOXING 2372 { 2373 mrb_float x = mrb_float(regs[a]); 2374 mrb_float y = mrb_float(regs[a+1]); 2375 SET_FLOAT_VALUE(mrb, regs[a], x / y); 2376 } 2288 x = mrb_float(regs[a]); 2289 y = mrb_float(regs[a+1]); 2290 break; 2291 #endif 2292 default: 2293 c = 1; 2294 mid = mrb_intern_lit(mrb, "/"); 2295 goto L_SEND_SYM; 2296 } 2297 2298 #ifndef MRB_WITHOUT_FLOAT 2299 if (y == 0) { 2300 if (x > 0) f = INFINITY; 2301 else if (x < 0) f = -INFINITY; 2302 else /* if (x == 0) */ f = NAN; 2303 } 2304 else { 2305 f = x / y; 2306 } 2307 SET_FLOAT_VALUE(mrb, regs[a], f); 2308 #endif 2309 NEXT; 2310 } 2311 2312 #define OP_MATHI(op_name) \ 2313 /* need to check if op is overridden */ \ 2314 switch (mrb_type(regs[a])) { \ 2315 OP_MATHI_CASE_FIXNUM(op_name); \ 2316 OP_MATHI_CASE_FLOAT(op_name); \ 2317 default: \ 2318 SET_INT_VALUE(regs[a+1], b); \ 2319 c = 1; \ 2320 mid = mrb_intern_lit(mrb, MRB_STRINGIZE(OP_MATH_OP_##op_name)); \ 2321 goto L_SEND_SYM; \ 2322 } \ 2323 NEXT; 2324 #define OP_MATHI_CASE_FIXNUM(op_name) \ 2325 case MRB_TT_FIXNUM: \ 2326 { \ 2327 mrb_int x = mrb_fixnum(regs[a]), y = (mrb_int)b, z; \ 2328 if (mrb_int_##op_name##_overflow(x, y, &z)) \ 2329 OP_MATH_OVERFLOW_INT(op_name, x, y, z); \ 2330 else \ 2331 SET_INT_VALUE(regs[a], z); \ 2332 } \ 2333 break 2334 #ifdef MRB_WITHOUT_FLOAT 2335 #define OP_MATHI_CASE_FLOAT(op_name) (void)0 2377 2336 #else 2378 OP_MATH_BODY(/,mrb_float,mrb_float); 2379 #endif 2380 break; 2381 default: 2382 goto L_SEND; 2383 } 2384 #ifdef MRB_NAN_BOXING 2385 if (isnan(mrb_float(regs[a]))) { 2386 mrb_value v = mrb_float_value(mrb, mrb_float(regs[a])); 2387 regs[a] = v; 2388 } 2389 #endif 2390 NEXT; 2391 } 2392 2393 CASE(OP_ADDI) { 2394 /* A B C R(A) := R(A)+C (Syms[B]=:+)*/ 2395 int a = GETARG_A(i); 2396 2397 /* need to check if + is overridden */ 2398 switch (mrb_type(regs[a])) { 2399 case MRB_TT_FIXNUM: 2400 { 2401 mrb_int x = mrb_fixnum(regs[a]); 2402 mrb_int y = GETARG_C(i); 2403 mrb_int z; 2404 2405 if (mrb_int_add_overflow(x, y, &z)) { 2406 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x + (mrb_float)y); 2407 break; 2408 } 2409 SET_INT_VALUE(regs[a], z); 2410 } 2411 break; 2412 case MRB_TT_FLOAT: 2413 #ifdef MRB_WORD_BOXING 2414 { 2415 mrb_float x = mrb_float(regs[a]); 2416 SET_FLOAT_VALUE(mrb, regs[a], x + GETARG_C(i)); 2417 } 2337 #define OP_MATHI_CASE_FLOAT(op_name) \ 2338 case MRB_TT_FLOAT: \ 2339 { \ 2340 mrb_float z = mrb_float(regs[a]) OP_MATH_OP_##op_name b; \ 2341 SET_FLOAT_VALUE(mrb, regs[a], z); \ 2342 } \ 2343 break 2344 #endif 2345 2346 CASE(OP_ADDI, BB) { 2347 OP_MATHI(add); 2348 } 2349 2350 CASE(OP_SUBI, BB) { 2351 OP_MATHI(sub); 2352 } 2353 2354 #define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1])) 2355 2356 #ifdef MRB_WITHOUT_FLOAT 2357 #define OP_CMP(op) do {\ 2358 int result;\ 2359 /* need to check if - is overridden */\ 2360 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\ 2361 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):\ 2362 result = OP_CMP_BODY(op,mrb_fixnum,mrb_fixnum);\ 2363 break;\ 2364 default:\ 2365 c = 1;\ 2366 mid = mrb_intern_lit(mrb, # op);\ 2367 goto L_SEND_SYM;\ 2368 }\ 2369 if (result) {\ 2370 SET_TRUE_VALUE(regs[a]);\ 2371 }\ 2372 else {\ 2373 SET_FALSE_VALUE(regs[a]);\ 2374 }\ 2375 } while(0) 2418 2376 #else 2419 mrb_float(regs[a]) += GETARG_C(i);2420 #endif2421 break;2422 default:2423 SET_INT_VALUE(regs[a+1], GETARG_C(i));2424 i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);2425 goto L_SEND;2426 }2427 NEXT;2428 }2429 2430 CASE(OP_SUBI) {2431 /* A B C R(A) := R(A)-C (Syms[B]=:-)*/2432 int a = GETARG_A(i);2433 mrb_value *regs_a = regs + a;2434 2435 /* need to check if + is overridden */2436 switch (mrb_type(regs_a[0])) {2437 case MRB_TT_FIXNUM:2438 {2439 mrb_int x = mrb_fixnum(regs_a[0]);2440 mrb_int y = GETARG_C(i);2441 mrb_int z;2442 2443 if (mrb_int_sub_overflow(x, y, &z)) {2444 SET_FLOAT_VALUE(mrb, regs_a[0], (mrb_float)x - (mrb_float)y);2445 }2446 else {2447 SET_INT_VALUE(regs_a[0], z);2448 }2449 }2450 break;2451 case MRB_TT_FLOAT:2452 #ifdef MRB_WORD_BOXING2453 {2454 mrb_float x = mrb_float(regs[a]);2455 SET_FLOAT_VALUE(mrb, regs[a], x - GETARG_C(i));2456 }2457 #else2458 mrb_float(regs_a[0]) -= GETARG_C(i);2459 #endif2460 break;2461 default:2462 SET_INT_VALUE(regs_a[1], GETARG_C(i));2463 i = MKOP_ABC(OP_SEND, a, GETARG_B(i), 1);2464 goto L_SEND;2465 }2466 NEXT;2467 }2468 2469 #define OP_CMP_BODY(op,v1,v2) (v1(regs[a]) op v2(regs[a+1]))2470 2471 2377 #define OP_CMP(op) do {\ 2472 2378 int result;\ … … 2486 2392 break;\ 2487 2393 default:\ 2488 goto L_SEND;\ 2394 c = 1;\ 2395 mid = mrb_intern_lit(mrb, # op);\ 2396 goto L_SEND_SYM;\ 2489 2397 }\ 2490 2398 if (result) {\ … … 2495 2403 }\ 2496 2404 } while(0) 2497 2498 CASE(OP_EQ) { 2499 /* A B C R(A) := R(A)==R(A+1) (Syms[B]=:==,C=1)*/ 2500 int a = GETARG_A(i); 2405 #endif 2406 2407 CASE(OP_EQ, B) { 2501 2408 if (mrb_obj_eq(mrb, regs[a], regs[a+1])) { 2502 2409 SET_TRUE_VALUE(regs[a]); … … 2508 2415 } 2509 2416 2510 CASE(OP_LT) { 2511 /* A B C R(A) := R(A)<R(A+1) (Syms[B]=:<,C=1)*/ 2512 int a = GETARG_A(i); 2417 CASE(OP_LT, B) { 2513 2418 OP_CMP(<); 2514 2419 NEXT; 2515 2420 } 2516 2421 2517 CASE(OP_LE) { 2518 /* A B C R(A) := R(A)<=R(A+1) (Syms[B]=:<=,C=1)*/ 2519 int a = GETARG_A(i); 2422 CASE(OP_LE, B) { 2520 2423 OP_CMP(<=); 2521 2424 NEXT; 2522 2425 } 2523 2426 2524 CASE(OP_GT) { 2525 /* A B C R(A) := R(A)>R(A+1) (Syms[B]=:>,C=1)*/ 2526 int a = GETARG_A(i); 2427 CASE(OP_GT, B) { 2527 2428 OP_CMP(>); 2528 2429 NEXT; 2529 2430 } 2530 2431 2531 CASE(OP_GE) { 2532 /* A B C R(A) := R(A)>=R(A+1) (Syms[B]=:>=,C=1)*/ 2533 int a = GETARG_A(i); 2432 CASE(OP_GE, B) { 2534 2433 OP_CMP(>=); 2535 2434 NEXT; 2536 2435 } 2537 2436 2538 CASE(OP_ARRAY) { 2539 /* A B C R(A) := ary_new(R(B),R(B+1)..R(B+C)) */ 2540 int a = GETARG_A(i); 2541 int b = GETARG_B(i); 2542 int c = GETARG_C(i); 2437 CASE(OP_ARRAY, BB) { 2438 mrb_value v = mrb_ary_new_from_values(mrb, b, ®s[a]); 2439 regs[a] = v; 2440 mrb_gc_arena_restore(mrb, ai); 2441 NEXT; 2442 } 2443 CASE(OP_ARRAY2, BBB) { 2543 2444 mrb_value v = mrb_ary_new_from_values(mrb, c, ®s[b]); 2544 2445 regs[a] = v; 2545 ARENA_RESTORE(mrb, ai); 2546 NEXT; 2547 } 2548 2549 CASE(OP_ARYCAT) { 2550 /* A B mrb_ary_concat(R(A),R(B)) */ 2551 int a = GETARG_A(i); 2552 int b = GETARG_B(i); 2553 mrb_value splat = mrb_ary_splat(mrb, regs[b]); 2554 mrb_ary_concat(mrb, regs[a], splat); 2555 ARENA_RESTORE(mrb, ai); 2556 NEXT; 2557 } 2558 2559 CASE(OP_ARYPUSH) { 2560 /* A B R(A).push(R(B)) */ 2561 int a = GETARG_A(i); 2562 int b = GETARG_B(i); 2563 mrb_ary_push(mrb, regs[a], regs[b]); 2564 NEXT; 2565 } 2566 2567 CASE(OP_AREF) { 2568 /* A B C R(A) := R(B)[C] */ 2569 int a = GETARG_A(i); 2570 int b = GETARG_B(i); 2571 int c = GETARG_C(i); 2446 mrb_gc_arena_restore(mrb, ai); 2447 NEXT; 2448 } 2449 2450 CASE(OP_ARYCAT, B) { 2451 mrb_value splat = mrb_ary_splat(mrb, regs[a+1]); 2452 if (mrb_nil_p(regs[a])) { 2453 regs[a] = splat; 2454 } 2455 else { 2456 mrb_ary_concat(mrb, regs[a], splat); 2457 } 2458 mrb_gc_arena_restore(mrb, ai); 2459 NEXT; 2460 } 2461 2462 CASE(OP_ARYPUSH, B) { 2463 mrb_ary_push(mrb, regs[a], regs[a+1]); 2464 NEXT; 2465 } 2466 2467 CASE(OP_ARYDUP, B) { 2468 mrb_value ary = regs[a]; 2469 if (mrb_array_p(ary)) { 2470 ary = mrb_ary_new_from_values(mrb, RARRAY_LEN(ary), RARRAY_PTR(ary)); 2471 } 2472 else { 2473 ary = mrb_ary_new_from_values(mrb, 1, &ary); 2474 } 2475 regs[a] = ary; 2476 NEXT; 2477 } 2478 2479 CASE(OP_AREF, BBB) { 2572 2480 mrb_value v = regs[b]; 2573 2481 … … 2587 2495 } 2588 2496 2589 CASE(OP_ASET) { 2590 /* A B C R(B)[C] := R(A) */ 2591 int a = GETARG_A(i); 2592 int b = GETARG_B(i); 2593 int c = GETARG_C(i); 2497 CASE(OP_ASET, BBB) { 2594 2498 mrb_ary_set(mrb, regs[b], c, regs[a]); 2595 2499 NEXT; 2596 2500 } 2597 2501 2598 CASE(OP_APOST) { 2599 /* A B C *R(A),R(A+1)..R(A+C) := R(A) */ 2600 int a = GETARG_A(i); 2502 CASE(OP_APOST, BBB) { 2601 2503 mrb_value v = regs[a]; 2602 int pre = GETARG_B(i);2603 int post = GETARG_C(i);2504 int pre = b; 2505 int post = c; 2604 2506 struct RArray *ary; 2605 2507 int len, idx; … … 2609 2511 } 2610 2512 ary = mrb_ary_ptr(v); 2611 len = ary->len;2513 len = (int)ARY_LEN(ary); 2612 2514 if (len > pre + post) { 2613 v = mrb_ary_new_from_values(mrb, len - pre - post, ary->ptr+pre);2515 v = mrb_ary_new_from_values(mrb, len - pre - post, ARY_PTR(ary)+pre); 2614 2516 regs[a++] = v; 2615 2517 while (post--) { 2616 regs[a++] = ary->ptr[len-post-1];2518 regs[a++] = ARY_PTR(ary)[len-post-1]; 2617 2519 } 2618 2520 } … … 2621 2523 regs[a++] = v; 2622 2524 for (idx=0; idx+pre<len; idx++) { 2623 regs[a+idx] = ary->ptr[pre+idx];2525 regs[a+idx] = ARY_PTR(ary)[pre+idx]; 2624 2526 } 2625 2527 while (idx < post) { … … 2628 2530 } 2629 2531 } 2630 ARENA_RESTORE(mrb, ai); 2631 NEXT; 2632 } 2633 2634 CASE(OP_STRING) { 2635 /* A Bx R(A) := str_new(Lit(Bx)) */ 2636 mrb_value str = mrb_str_dup(mrb, pool[GETARG_Bx(i)]); 2637 regs[GETARG_A(i)] = str; 2638 ARENA_RESTORE(mrb, ai); 2639 NEXT; 2640 } 2641 2642 CASE(OP_STRCAT) { 2643 /* A B R(A).concat(R(B)) */ 2644 mrb_str_concat(mrb, regs[GETARG_A(i)], regs[GETARG_B(i)]); 2645 NEXT; 2646 } 2647 2648 CASE(OP_HASH) { 2649 /* A B C R(A) := hash_new(R(B),R(B+1)..R(B+C)) */ 2650 int b = GETARG_B(i); 2651 int c = GETARG_C(i); 2652 int lim = b+c*2; 2653 mrb_value hash = mrb_hash_new_capa(mrb, c); 2654 2655 while (b < lim) { 2656 mrb_hash_set(mrb, hash, regs[b], regs[b+1]); 2657 b+=2; 2658 } 2659 regs[GETARG_A(i)] = hash; 2660 ARENA_RESTORE(mrb, ai); 2661 NEXT; 2662 } 2663 2664 CASE(OP_LAMBDA) { 2665 /* A b c R(A) := lambda(SEQ[b],c) (b:c = 14:2) */ 2532 mrb_gc_arena_restore(mrb, ai); 2533 NEXT; 2534 } 2535 2536 CASE(OP_INTERN, B) { 2537 mrb_sym sym = mrb_intern_str(mrb, regs[a]); 2538 2539 regs[a] = mrb_symbol_value(sym); 2540 mrb_gc_arena_restore(mrb, ai); 2541 NEXT; 2542 } 2543 2544 CASE(OP_STRING, BB) { 2545 mrb_value str = mrb_str_dup(mrb, pool[b]); 2546 2547 regs[a] = str; 2548 mrb_gc_arena_restore(mrb, ai); 2549 NEXT; 2550 } 2551 2552 CASE(OP_STRCAT, B) { 2553 mrb_str_concat(mrb, regs[a], regs[a+1]); 2554 NEXT; 2555 } 2556 2557 CASE(OP_HASH, BB) { 2558 mrb_value hash = mrb_hash_new_capa(mrb, b); 2559 int i; 2560 int lim = a+b*2; 2561 2562 for (i=a; i<lim; i+=2) { 2563 mrb_hash_set(mrb, hash, regs[i], regs[i+1]); 2564 } 2565 regs[a] = hash; 2566 mrb_gc_arena_restore(mrb, ai); 2567 NEXT; 2568 } 2569 2570 CASE(OP_HASHADD, BB) { 2571 mrb_value hash; 2572 int i; 2573 int lim = a+b*2+1; 2574 2575 hash = mrb_ensure_hash_type(mrb, regs[a]); 2576 for (i=a+1; i<lim; i+=2) { 2577 mrb_hash_set(mrb, hash, regs[i], regs[i+1]); 2578 } 2579 mrb_gc_arena_restore(mrb, ai); 2580 NEXT; 2581 } 2582 CASE(OP_HASHCAT, B) { 2583 mrb_value hash = mrb_ensure_hash_type(mrb, regs[a]); 2584 2585 mrb_hash_merge(mrb, hash, regs[a+1]); 2586 mrb_gc_arena_restore(mrb, ai); 2587 NEXT; 2588 } 2589 2590 CASE(OP_LAMBDA, BB) 2591 c = OP_L_LAMBDA; 2592 L_MAKE_LAMBDA: 2593 { 2666 2594 struct RProc *p; 2667 int c = GETARG_c(i);2595 mrb_irep *nirep = irep->reps[b]; 2668 2596 2669 2597 if (c & OP_L_CAPTURE) { 2670 p = mrb_closure_new(mrb, irep->reps[GETARG_b(i)]);2598 p = mrb_closure_new(mrb, nirep); 2671 2599 } 2672 2600 else { 2673 p = mrb_proc_new(mrb, irep->reps[GETARG_b(i)]); 2601 p = mrb_proc_new(mrb, nirep); 2602 p->flags |= MRB_PROC_SCOPE; 2674 2603 } 2675 2604 if (c & OP_L_STRICT) p->flags |= MRB_PROC_STRICT; 2676 regs[GETARG_A(i)] = mrb_obj_value(p); 2677 ARENA_RESTORE(mrb, ai); 2678 NEXT; 2679 } 2680 2681 CASE(OP_OCLASS) { 2682 /* A R(A) := ::Object */ 2683 regs[GETARG_A(i)] = mrb_obj_value(mrb->object_class); 2684 NEXT; 2685 } 2686 2687 CASE(OP_CLASS) { 2688 /* A B R(A) := newclass(R(A),Syms(B),R(A+1)) */ 2605 regs[a] = mrb_obj_value(p); 2606 mrb_gc_arena_restore(mrb, ai); 2607 NEXT; 2608 } 2609 CASE(OP_BLOCK, BB) { 2610 c = OP_L_BLOCK; 2611 goto L_MAKE_LAMBDA; 2612 } 2613 CASE(OP_METHOD, BB) { 2614 c = OP_L_METHOD; 2615 goto L_MAKE_LAMBDA; 2616 } 2617 2618 CASE(OP_RANGE_INC, B) { 2619 mrb_value val = mrb_range_new(mrb, regs[a], regs[a+1], FALSE); 2620 regs[a] = val; 2621 mrb_gc_arena_restore(mrb, ai); 2622 NEXT; 2623 } 2624 2625 CASE(OP_RANGE_EXC, B) { 2626 mrb_value val = mrb_range_new(mrb, regs[a], regs[a+1], TRUE); 2627 regs[a] = val; 2628 mrb_gc_arena_restore(mrb, ai); 2629 NEXT; 2630 } 2631 2632 CASE(OP_OCLASS, B) { 2633 regs[a] = mrb_obj_value(mrb->object_class); 2634 NEXT; 2635 } 2636 2637 CASE(OP_CLASS, BB) { 2689 2638 struct RClass *c = 0, *baseclass; 2690 int a = GETARG_A(i);2691 2639 mrb_value base, super; 2692 mrb_sym id = syms[ GETARG_B(i)];2640 mrb_sym id = syms[b]; 2693 2641 2694 2642 base = regs[a]; 2695 2643 super = regs[a+1]; 2696 2644 if (mrb_nil_p(base)) { 2697 baseclass = mrb->c->ci->proc->target_class; 2698 if (!baseclass) baseclass = mrb->c->ci->target_class; 2699 2645 baseclass = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc); 2700 2646 base = mrb_obj_value(baseclass); 2701 2647 } 2702 2648 c = mrb_vm_define_class(mrb, base, super, id); 2703 2649 regs[a] = mrb_obj_value(c); 2704 ARENA_RESTORE(mrb, ai); 2705 NEXT; 2706 } 2707 2708 CASE(OP_MODULE) { 2709 /* A B R(A) := newmodule(R(A),Syms(B)) */ 2710 struct RClass *c = 0, *baseclass; 2711 int a = GETARG_A(i); 2650 mrb_gc_arena_restore(mrb, ai); 2651 NEXT; 2652 } 2653 2654 CASE(OP_MODULE, BB) { 2655 struct RClass *cls = 0, *baseclass; 2712 2656 mrb_value base; 2713 mrb_sym id = syms[ GETARG_B(i)];2657 mrb_sym id = syms[b]; 2714 2658 2715 2659 base = regs[a]; 2716 2660 if (mrb_nil_p(base)) { 2717 baseclass = mrb->c->ci->proc->target_class; 2718 if (!baseclass) baseclass = mrb->c->ci->target_class; 2719 2661 baseclass = MRB_PROC_TARGET_CLASS(mrb->c->ci->proc); 2720 2662 base = mrb_obj_value(baseclass); 2721 2663 } 2722 c = mrb_vm_define_module(mrb, base, id); 2723 regs[a] = mrb_obj_value(c); 2724 ARENA_RESTORE(mrb, ai); 2725 NEXT; 2726 } 2727 2728 CASE(OP_EXEC) { 2729 /* A Bx R(A) := blockexec(R(A),SEQ[Bx]) */ 2730 int a = GETARG_A(i); 2664 cls = mrb_vm_define_module(mrb, base, id); 2665 regs[a] = mrb_obj_value(cls); 2666 mrb_gc_arena_restore(mrb, ai); 2667 NEXT; 2668 } 2669 2670 CASE(OP_EXEC, BB) { 2731 2671 mrb_callinfo *ci; 2732 2672 mrb_value recv = regs[a]; 2733 2673 struct RProc *p; 2674 mrb_irep *nirep = irep->reps[b]; 2734 2675 2735 2676 /* prepare closure */ 2736 p = mrb_ closure_new(mrb, irep->reps[GETARG_Bx(i)]);2677 p = mrb_proc_new(mrb, nirep); 2737 2678 p->c = NULL; 2738 2739 /* prepare stack */ 2679 mrb_field_write_barrier(mrb, (struct RBasic*)p, (struct RBasic*)proc); 2680 MRB_PROC_SET_TARGET_CLASS(p, mrb_class_ptr(recv)); 2681 p->flags |= MRB_PROC_SCOPE; 2682 2683 /* prepare call stack */ 2740 2684 ci = cipush(mrb); 2741 ci->pc = pc + 1;2685 ci->pc = pc; 2742 2686 ci->acc = a; 2743 2687 ci->mid = 0; … … 2749 2693 mrb->c->stack += a; 2750 2694 2751 /* setup closure */ 2752 p->target_class = ci->target_class; 2695 /* setup block to call */ 2753 2696 ci->proc = p; 2754 2697 … … 2756 2699 pool = irep->pool; 2757 2700 syms = irep->syms; 2758 stack_extend(mrb, irep->nregs);2701 mrb_stack_extend(mrb, irep->nregs); 2759 2702 stack_clear(regs+1, irep->nregs-1); 2760 ci->nregs = irep->nregs;2761 2703 pc = irep->iseq; 2762 2704 JUMP; 2763 2705 } 2764 2706 2765 CASE(OP_METHOD) { 2766 /* A B R(A).newmethod(Syms(B),R(A+1)) */ 2767 int a = GETARG_A(i); 2768 struct RClass *c = mrb_class_ptr(regs[a]); 2707 CASE(OP_DEF, BB) { 2708 struct RClass *target = mrb_class_ptr(regs[a]); 2769 2709 struct RProc *p = mrb_proc_ptr(regs[a+1]); 2770 2771 mrb_define_method_raw(mrb, c, syms[GETARG_B(i)], p); 2772 ARENA_RESTORE(mrb, ai); 2773 NEXT; 2774 } 2775 2776 CASE(OP_SCLASS) { 2777 /* A B R(A) := R(B).singleton_class */ 2778 regs[GETARG_A(i)] = mrb_singleton_class(mrb, regs[GETARG_B(i)]); 2779 ARENA_RESTORE(mrb, ai); 2780 NEXT; 2781 } 2782 2783 CASE(OP_TCLASS) { 2784 /* A R(A) := target_class */ 2785 if (!mrb->c->ci->target_class) { 2786 mrb_value exc = mrb_exc_new_str_lit(mrb, E_TYPE_ERROR, "no target class or module"); 2787 mrb_exc_set(mrb, exc); 2788 goto L_RAISE; 2789 } 2790 regs[GETARG_A(i)] = mrb_obj_value(mrb->c->ci->target_class); 2791 NEXT; 2792 } 2793 2794 CASE(OP_RANGE) { 2795 /* A B C R(A) := range_new(R(B),R(B+1),C) */ 2796 int b = GETARG_B(i); 2797 mrb_value val = mrb_range_new(mrb, regs[b], regs[b+1], GETARG_C(i)); 2798 regs[GETARG_A(i)] = val; 2799 ARENA_RESTORE(mrb, ai); 2800 NEXT; 2801 } 2802 2803 CASE(OP_DEBUG) { 2804 /* A B C debug print R(A),R(B),R(C) */ 2710 mrb_method_t m; 2711 2712 MRB_METHOD_FROM_PROC(m, p); 2713 mrb_define_method_raw(mrb, target, syms[b], m); 2714 mrb_gc_arena_restore(mrb, ai); 2715 NEXT; 2716 } 2717 2718 CASE(OP_SCLASS, B) { 2719 regs[a] = mrb_singleton_class(mrb, regs[a]); 2720 mrb_gc_arena_restore(mrb, ai); 2721 NEXT; 2722 } 2723 2724 CASE(OP_TCLASS, B) { 2725 if (!check_target_class(mrb)) goto L_RAISE; 2726 regs[a] = mrb_obj_value(mrb->c->ci->target_class); 2727 NEXT; 2728 } 2729 2730 CASE(OP_ALIAS, BB) { 2731 struct RClass *target; 2732 2733 if (!check_target_class(mrb)) goto L_RAISE; 2734 target = mrb->c->ci->target_class; 2735 mrb_alias_method(mrb, target, syms[a], syms[b]); 2736 NEXT; 2737 } 2738 CASE(OP_UNDEF, B) { 2739 struct RClass *target; 2740 2741 if (!check_target_class(mrb)) goto L_RAISE; 2742 target = mrb->c->ci->target_class; 2743 mrb_undef_method_id(mrb, target, syms[a]); 2744 NEXT; 2745 } 2746 2747 CASE(OP_DEBUG, Z) { 2748 FETCH_BBB(); 2805 2749 #ifdef MRB_ENABLE_DEBUG_HOOK 2806 2750 mrb->debug_op_hook(mrb, irep, pc, regs); 2807 2751 #else 2808 2752 #ifndef MRB_DISABLE_STDIO 2809 printf("OP_DEBUG %d %d %d\n", GETARG_A(i), GETARG_B(i), GETARG_C(i));2753 printf("OP_DEBUG %d %d %d\n", a, b, c); 2810 2754 #else 2811 2755 abort(); … … 2815 2759 } 2816 2760 2817 CASE(OP_STOP) { 2761 CASE(OP_ERR, B) { 2762 mrb_value msg = mrb_str_dup(mrb, pool[a]); 2763 mrb_value exc; 2764 2765 exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg); 2766 ERR_PC_SET(mrb); 2767 mrb_exc_set(mrb, exc); 2768 goto L_RAISE; 2769 } 2770 2771 CASE(OP_EXT1, Z) { 2772 insn = READ_B(); 2773 switch (insn) { 2774 #define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _1(); goto L_OP_ ## insn ## _BODY; 2775 #include "mruby/ops.h" 2776 #undef OPCODE 2777 } 2778 pc--; 2779 NEXT; 2780 } 2781 CASE(OP_EXT2, Z) { 2782 insn = READ_B(); 2783 switch (insn) { 2784 #define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _2(); goto L_OP_ ## insn ## _BODY; 2785 #include "mruby/ops.h" 2786 #undef OPCODE 2787 } 2788 pc--; 2789 NEXT; 2790 } 2791 CASE(OP_EXT3, Z) { 2792 uint8_t insn = READ_B(); 2793 switch (insn) { 2794 #define OPCODE(insn,ops) case OP_ ## insn: FETCH_ ## ops ## _3(); goto L_OP_ ## insn ## _BODY; 2795 #include "mruby/ops.h" 2796 #undef OPCODE 2797 } 2798 pc--; 2799 NEXT; 2800 } 2801 2802 CASE(OP_STOP, Z) { 2818 2803 /* stop VM */ 2819 2804 L_STOP: 2820 { 2821 int epos = mrb->c->ci->epos; 2822 2823 while (mrb->c->eidx > epos) { 2824 ecall(mrb, --mrb->c->eidx); 2825 } 2826 } 2805 while (mrb->c->eidx > 0) { 2806 ecall(mrb); 2807 } 2808 mrb->c->cibase->ridx = 0; 2827 2809 ERR_PC_CLR(mrb); 2828 2810 mrb->jmp = prev_jmp; … … 2832 2814 return regs[irep->nlocals]; 2833 2815 } 2834 2835 CASE(OP_ERR) {2836 /* Bx raise RuntimeError with message Lit(Bx) */2837 mrb_value msg = mrb_str_dup(mrb, pool[GETARG_Bx(i)]);2838 mrb_value exc;2839 2840 if (GETARG_A(i) == 0) {2841 exc = mrb_exc_new_str(mrb, E_RUNTIME_ERROR, msg);2842 }2843 else {2844 exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg);2845 }2846 mrb_exc_set(mrb, exc);2847 goto L_RAISE;2848 }2849 2816 } 2850 2817 END_DISPATCH; 2851 2818 #undef regs 2852 2853 2819 } 2854 2820 MRB_CATCH(&c_jmp) { … … 2884 2850 } 2885 2851 ci = cipush(mrb); 2852 ci->stackent = mrb->c->stack; 2886 2853 ci->mid = 0; 2887 ci->nregs = 1; /* protect the receiver */2888 2854 ci->acc = CI_ACC_SKIP; 2889 2855 ci->target_class = mrb->object_class; 2890 2856 v = mrb_vm_run(mrb, proc, self, stack_keep); 2891 cipop(mrb);2892 2857 2893 2858 return v;
Note:
See TracChangeset
for help on using the changeset viewer.