source: EcnlProtoTool/trunk/mruby-1.3.0/src/vm.c@ 331

Last change on this file since 331 was 331, checked in by coas-nagasima, 6 years ago

prototoolに関連するプロジェクトをnewlibからmuslを使うよう変更・更新
ntshellをnewlibの下位の実装から、muslのsyscallの実装に変更・更新
以下のOSSをアップデート
・mruby-1.3.0
・musl-1.1.18
・onigmo-6.1.3
・tcc-0.9.27
以下のOSSを追加
・openssl-1.1.0e
・curl-7.57.0
・zlib-1.2.11
以下のmrbgemsを追加
・iij/mruby-digest
・iij/mruby-env
・iij/mruby-errno
・iij/mruby-iijson
・iij/mruby-ipaddr
・iij/mruby-mock
・iij/mruby-require
・iij/mruby-tls-openssl

  • Property svn:eol-style set to native
  • Property svn:mime-type set to text/x-csrc;charset=UTF-8
File size: 72.8 KB
Line 
1/*
2** vm.c - virtual machine for mruby
3**
4** See Copyright Notice in mruby.h
5*/
6
7#include <stddef.h>
8#include <stdarg.h>
9#include <math.h>
10#include <mruby.h>
11#include <mruby/array.h>
12#include <mruby/class.h>
13#include <mruby/hash.h>
14#include <mruby/irep.h>
15#include <mruby/numeric.h>
16#include <mruby/proc.h>
17#include <mruby/range.h>
18#include <mruby/string.h>
19#include <mruby/variable.h>
20#include <mruby/error.h>
21#include <mruby/opcode.h>
22#include "value_array.h"
23#include <mruby/throw.h>
24
25#ifndef MRB_DISABLE_STDIO
26#if defined(__cplusplus)
27extern "C" {
28#endif
29void abort(void);
30#if defined(__cplusplus)
31} /* extern "C" { */
32#endif
33#endif
34
35#define STACK_INIT_SIZE 128
36#define CALLINFO_INIT_SIZE 32
37
38#ifndef ENSURE_STACK_INIT_SIZE
39#define ENSURE_STACK_INIT_SIZE 16
40#endif
41
42#ifndef RESCUE_STACK_INIT_SIZE
43#define RESCUE_STACK_INIT_SIZE 16
44#endif
45
46/* Define amount of linear stack growth. */
47#ifndef MRB_STACK_GROWTH
48#define MRB_STACK_GROWTH 128
49#endif
50
51/* Maximum mrb_funcall() depth. Should be set lower on memory constrained systems. */
52#ifndef MRB_FUNCALL_DEPTH_MAX
53#define MRB_FUNCALL_DEPTH_MAX 512
54#endif
55
56/* Maximum stack depth. Should be set lower on memory constrained systems.
57The value below allows about 60000 recursive calls in the simplest case. */
58#ifndef MRB_STACK_MAX
59#define MRB_STACK_MAX (0x40000 - MRB_STACK_GROWTH)
60#endif
61
62#ifdef VM_DEBUG
63# define DEBUG(x) (x)
64#else
65# define DEBUG(x)
66#endif
67
68#define ARENA_RESTORE(mrb,ai) (mrb)->gc.arena_idx = (ai)
69
70#define CALL_MAXARGS 127
71
72void mrb_method_missing(mrb_state *mrb, mrb_sym name, mrb_value self, mrb_value args);
73
74static inline void
75stack_clear(mrb_value *from, size_t count)
76{
77#ifndef MRB_NAN_BOXING
78 const mrb_value mrb_value_zero = { { 0 } };
79
80 while (count-- > 0) {
81 *from++ = mrb_value_zero;
82 }
83#else
84 while (count-- > 0) {
85 SET_NIL_VALUE(*from);
86 from++;
87 }
88#endif
89}
90
91static inline void
92stack_copy(mrb_value *dst, const mrb_value *src, size_t size)
93{
94 while (size-- > 0) {
95 *dst++ = *src++;
96 }
97}
98
99static void
100stack_init(mrb_state *mrb)
101{
102 struct mrb_context *c = mrb->c;
103
104 /* mrb_assert(mrb->stack == NULL); */
105 c->stbase = (mrb_value *)mrb_calloc(mrb, STACK_INIT_SIZE, sizeof(mrb_value));
106 c->stend = c->stbase + STACK_INIT_SIZE;
107 c->stack = c->stbase;
108
109 /* mrb_assert(ci == NULL); */
110 c->cibase = (mrb_callinfo *)mrb_calloc(mrb, CALLINFO_INIT_SIZE, sizeof(mrb_callinfo));
111 c->ciend = c->cibase + CALLINFO_INIT_SIZE;
112 c->ci = c->cibase;
113 c->ci->target_class = mrb->object_class;
114 c->ci->stackent = c->stack;
115}
116
117static inline void
118envadjust(mrb_state *mrb, mrb_value *oldbase, mrb_value *newbase, size_t size)
119{
120 mrb_callinfo *ci = mrb->c->cibase;
121
122 if (newbase == oldbase) return;
123 while (ci <= mrb->c->ci) {
124 struct REnv *e = ci->env;
125 mrb_value *st;
126
127 if (e && MRB_ENV_STACK_SHARED_P(e) &&
128 (st = e->stack) && oldbase <= st && st < oldbase+size) {
129 ptrdiff_t off = e->stack - oldbase;
130
131 e->stack = newbase + off;
132 }
133 ci->stackent = newbase + (ci->stackent - oldbase);
134 ci++;
135 }
136}
137
138/** def rec ; $deep =+ 1 ; if $deep > 1000 ; return 0 ; end ; rec ; end */
139
140static void
141stack_extend_alloc(mrb_state *mrb, int room)
142{
143 mrb_value *oldbase = mrb->c->stbase;
144 mrb_value *newstack;
145 size_t oldsize = mrb->c->stend - mrb->c->stbase;
146 size_t size = oldsize;
147 size_t off = mrb->c->stack - mrb->c->stbase;
148
149 if (off > size) size = off;
150#ifdef MRB_STACK_EXTEND_DOUBLING
151 if (room <= size)
152 size *= 2;
153 else
154 size += room;
155#else
156 /* Use linear stack growth.
157 It is slightly slower than doubling the stack space,
158 but it saves memory on small devices. */
159 if (room <= MRB_STACK_GROWTH)
160 size += MRB_STACK_GROWTH;
161 else
162 size += room;
163#endif
164
165 newstack = (mrb_value *)mrb_realloc(mrb, mrb->c->stbase, sizeof(mrb_value) * size);
166 if (newstack == NULL) {
167 mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
168 }
169 stack_clear(&(newstack[oldsize]), size - oldsize);
170 envadjust(mrb, oldbase, newstack, size);
171 mrb->c->stbase = newstack;
172 mrb->c->stack = mrb->c->stbase + off;
173 mrb->c->stend = mrb->c->stbase + size;
174
175 /* Raise an exception if the new stack size will be too large,
176 to prevent infinite recursion. However, do this only after resizing the stack, so mrb_raise has stack space to work with. */
177 if (size > MRB_STACK_MAX) {
178 mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
179 }
180}
181
182static inline void
183stack_extend(mrb_state *mrb, int room)
184{
185 if (mrb->c->stack + room >= mrb->c->stend) {
186 stack_extend_alloc(mrb, room);
187 }
188}
189
190static inline struct REnv*
191uvenv(mrb_state *mrb, int up)
192{
193 struct REnv *e = mrb->c->ci->proc->env;
194
195 while (up--) {
196 if (!e) return NULL;
197 e = (struct REnv*)e->c;
198 }
199 return e;
200}
201
202static inline mrb_bool
203is_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
214static inline struct REnv*
215top_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;
225}
226
227#define CI_ACC_SKIP -1
228#define CI_ACC_DIRECT -2
229#define CI_ACC_RESUMED -3
230
231static mrb_callinfo*
232cipush(mrb_state *mrb)
233{
234 struct mrb_context *c = mrb->c;
235 mrb_callinfo *ci = c->ci;
236
237 int ridx = ci->ridx;
238
239 if (ci + 1 == c->ciend) {
240 ptrdiff_t size = ci - c->cibase;
241
242 c->cibase = (mrb_callinfo *)mrb_realloc(mrb, c->cibase, sizeof(mrb_callinfo)*size*2);
243 c->ci = c->cibase + size;
244 c->ciend = c->cibase + size * 2;
245 }
246 ci = ++c->ci;
247 ci->epos = mrb->c->eidx;
248 ci->ridx = ridx;
249 ci->env = 0;
250 ci->pc = 0;
251 ci->err = 0;
252 ci->proc = 0;
253 ci->acc = 0;
254
255 return ci;
256}
257
258MRB_API void
259mrb_env_unshare(mrb_state *mrb, struct REnv *e)
260{
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
282static void
283cipop(mrb_state *mrb)
284{
285 struct mrb_context *c = mrb->c;
286 struct REnv *env = c->ci->env;
287
288 c->ci--;
289
290 if (env) {
291 mrb_env_unshare(mrb, env);
292 }
293}
294
295void mrb_exc_set(mrb_state *mrb, mrb_value exc);
296
297static void
298ecall(mrb_state *mrb, int i)
299{
300 struct RProc *p;
301 mrb_callinfo *ci = mrb->c->ci;
302 mrb_value *self = mrb->c->stack;
303 struct RObject *exc;
304 ptrdiff_t cioff;
305 int ai = mrb_gc_arena_save(mrb);
306
307 if (i<0) return;
308 if (ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
309 mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
310 }
311 p = mrb->c->ensure[i];
312 if (!p) return;
313 mrb->c->ensure[i] = NULL;
314 cioff = ci - mrb->c->cibase;
315 ci = cipush(mrb);
316 ci->stackent = mrb->c->stack;
317 ci->mid = ci[-1].mid;
318 ci->acc = CI_ACC_SKIP;
319 ci->argc = 0;
320 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;
324 exc = mrb->exc; mrb->exc = 0;
325 if (exc) {
326 mrb_gc_protect(mrb, mrb_obj_value(exc));
327 }
328 mrb_run(mrb, p, *self);
329 mrb->c->ci = mrb->c->cibase + cioff;
330 if (!mrb->exc) mrb->exc = exc;
331 mrb_gc_arena_restore(mrb, ai);
332}
333
334#ifndef MRB_FUNCALL_ARGC_MAX
335#define MRB_FUNCALL_ARGC_MAX 16
336#endif
337
338MRB_API mrb_value
339mrb_funcall(mrb_state *mrb, mrb_value self, const char *name, mrb_int argc, ...)
340{
341 mrb_value argv[MRB_FUNCALL_ARGC_MAX];
342 va_list ap;
343 mrb_int i;
344 mrb_sym mid = mrb_intern_cstr(mrb, name);
345
346 if (argc > MRB_FUNCALL_ARGC_MAX) {
347 mrb_raise(mrb, E_ARGUMENT_ERROR, "Too long arguments. (limit=" MRB_STRINGIZE(MRB_FUNCALL_ARGC_MAX) ")");
348 }
349
350 va_start(ap, argc);
351 for (i = 0; i < argc; i++) {
352 argv[i] = va_arg(ap, mrb_value);
353 }
354 va_end(ap);
355 return mrb_funcall_argv(mrb, self, mid, argc, argv);
356}
357
358MRB_API mrb_value
359mrb_funcall_with_block(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv, mrb_value blk)
360{
361 mrb_value val;
362
363 if (!mrb->jmp) {
364 struct mrb_jmpbuf c_jmp;
365 ptrdiff_t nth_ci = mrb->c->ci - mrb->c->cibase;
366
367 MRB_TRY(&c_jmp) {
368 mrb->jmp = &c_jmp;
369 /* recursive call */
370 val = mrb_funcall_with_block(mrb, self, mid, argc, argv, blk);
371 mrb->jmp = 0;
372 }
373 MRB_CATCH(&c_jmp) { /* error */
374 while (nth_ci < (mrb->c->ci - mrb->c->cibase)) {
375 mrb->c->stack = mrb->c->ci->stackent;
376 cipop(mrb);
377 }
378 mrb->jmp = 0;
379 val = mrb_obj_value(mrb->exc);
380 }
381 MRB_END_EXC(&c_jmp);
382 mrb->jmp = 0;
383 }
384 else {
385 struct RProc *p;
386 struct RClass *c;
387 mrb_callinfo *ci;
388 int n;
389 ptrdiff_t voff = -1;
390
391 if (!mrb->c->stack) {
392 stack_init(mrb);
393 }
394 n = mrb->c->ci->nregs;
395 if (argc < 0) {
396 mrb_raisef(mrb, E_ARGUMENT_ERROR, "negative argc for funcall (%S)", mrb_fixnum_value(argc));
397 }
398 c = mrb_class(mrb, self);
399 p = mrb_method_search_vm(mrb, &c, mid);
400 if (!p) {
401 mrb_sym missing = mrb_intern_lit(mrb, "method_missing");
402 mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
403 p = mrb_method_search_vm(mrb, &c, missing);
404 if (!p) {
405 mrb_method_missing(mrb, mid, self, args);
406 }
407 mrb_ary_unshift(mrb, args, mrb_symbol_value(mid));
408 stack_extend(mrb, n+2);
409 mrb->c->stack[n+1] = args;
410 argc = -1;
411 }
412 if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
413 mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
414 }
415 ci = cipush(mrb);
416 ci->mid = mid;
417 ci->proc = p;
418 ci->stackent = mrb->c->stack;
419 ci->argc = argc;
420 ci->target_class = c;
421 mrb->c->stack = mrb->c->stack + n;
422 if (mrb->c->stbase <= argv && argv < mrb->c->stend) {
423 voff = argv - mrb->c->stbase;
424 }
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) {
430 mrb_value args = mrb_ary_new_from_values(mrb, argc, argv);
431 stack_extend(mrb, ci->nregs);
432 mrb->c->stack[1] = args;
433 ci->argc = -1;
434 argc = 1;
435 }
436 else {
437 if (argc < 0) argc = 1;
438 ci->nregs = p->body.irep->nregs + argc;
439 stack_extend(mrb, ci->nregs);
440 }
441 if (voff >= 0) {
442 argv = mrb->c->stbase + voff;
443 }
444 mrb->c->stack[0] = self;
445 if (ci->argc > 0) {
446 stack_copy(mrb->c->stack+1, argv, argc);
447 }
448 mrb->c->stack[argc+1] = blk;
449
450 if (MRB_PROC_CFUNC_P(p)) {
451 int ai = mrb_gc_arena_save(mrb);
452
453 ci->acc = CI_ACC_DIRECT;
454 val = p->body.func(mrb, self);
455 mrb->c->stack = mrb->c->ci->stackent;
456 cipop(mrb);
457 mrb_gc_arena_restore(mrb, ai);
458 }
459 else {
460 ci->acc = CI_ACC_SKIP;
461 val = mrb_run(mrb, p, self);
462 }
463 }
464 mrb_gc_protect(mrb, val);
465 return val;
466}
467
468MRB_API mrb_value
469mrb_funcall_argv(mrb_state *mrb, mrb_value self, mrb_sym mid, mrb_int argc, const mrb_value *argv)
470{
471 return mrb_funcall_with_block(mrb, self, mid, argc, argv, mrb_nil_value());
472}
473
474mrb_value
475mrb_exec_irep(mrb_state *mrb, mrb_value self, struct RProc *p)
476{
477 mrb_callinfo *ci = mrb->c->ci;
478
479 mrb->c->stack[0] = self;
480 ci->proc = p;
481 ci->target_class = p->target_class;
482 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);
487 }
488 else {
489 stack_extend(mrb, p->body.irep->nregs);
490 }
491
492 ci->nregs = p->body.irep->nregs;
493 ci = cipush(mrb);
494 ci->nregs = 0;
495 ci->target_class = 0;
496 ci->pc = p->body.irep->iseq;
497 ci->stackent = mrb->c->stack;
498 ci->acc = 0;
499
500 return self;
501}
502
503/* 15.3.1.3.4 */
504/* 15.3.1.3.44 */
505/*
506 * call-seq:
507 * obj.send(symbol [, args...]) -> obj
508 * obj.__send__(symbol [, args...]) -> obj
509 *
510 * Invokes the method identified by _symbol_, passing it any
511 * arguments specified. You can use <code>__send__</code> if the name
512 * +send+ clashes with an existing method in _obj_.
513 *
514 * class Klass
515 * def hello(*args)
516 * "Hello " + args.join(' ')
517 * end
518 * end
519 * k = Klass.new
520 * k.send :hello, "gentle", "readers" #=> "Hello gentle readers"
521 */
522MRB_API mrb_value
523mrb_f_send(mrb_state *mrb, mrb_value self)
524{
525 mrb_sym name;
526 mrb_value block, *argv, *regs;
527 mrb_int argc, i, len;
528 struct RProc *p;
529 struct RClass *c;
530 mrb_callinfo *ci;
531
532 mrb_get_args(mrb, "n*&", &name, &argv, &argc, &block);
533 ci = mrb->c->ci;
534 if (ci->acc < 0) {
535 funcall:
536 return mrb_funcall_with_block(mrb, self, name, argc, argv, block);
537 }
538
539 c = mrb_class(mrb, self);
540 p = mrb_method_search_vm(mrb, &c, name);
541
542 if (!p) { /* call method_mising */
543 goto funcall;
544 }
545
546 ci->mid = name;
547 ci->target_class = c;
548 regs = mrb->c->stack+1;
549 /* remove first symbol from arguments */
550 if (ci->argc >= 0) {
551 for (i=0,len=ci->argc; i<len; i++) {
552 regs[i] = regs[i+1];
553 }
554 ci->argc--;
555 }
556 else { /* variable length arguments */
557 mrb_ary_shift(mrb, regs[0]);
558 }
559
560 return mrb_exec_irep(mrb, self, p);
561}
562
563static mrb_value
564eval_under(mrb_state *mrb, mrb_value self, mrb_value blk, struct RClass *c)
565{
566 struct RProc *p;
567 mrb_callinfo *ci;
568 mrb_int max = 3;
569
570 if (mrb_nil_p(blk)) {
571 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
572 }
573 ci = mrb->c->ci;
574 if (ci->acc == CI_ACC_DIRECT) {
575 ci->target_class = c;
576 return mrb_yield_cont(mrb, blk, self, 1, &self);
577 }
578 ci->target_class = c;
579 p = mrb_proc_ptr(blk);
580 ci->proc = p;
581 ci->argc = 1;
582 ci->mid = ci[-1].mid;
583 if (MRB_PROC_CFUNC_P(p)) {
584 stack_extend(mrb, 3);
585 mrb->c->stack[0] = self;
586 mrb->c->stack[1] = self;
587 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);
593 mrb->c->stack[0] = self;
594 mrb->c->stack[1] = self;
595 mrb->c->stack[2] = mrb_nil_value();
596 ci = cipush(mrb);
597 ci->nregs = 0;
598 ci->target_class = 0;
599 ci->pc = p->body.irep->iseq;
600 ci->stackent = mrb->c->stack;
601 ci->acc = 0;
602
603 return self;
604}
605
606/* 15.2.2.4.35 */
607/*
608 * call-seq:
609 * mod.class_eval {| | block } -> obj
610 * mod.module_eval {| | block } -> obj
611 *
612 * Evaluates block in the context of _mod_. This can
613 * be used to add methods to a class. <code>module_eval</code> returns
614 * the result of evaluating its argument.
615 */
616mrb_value
617mrb_mod_module_eval(mrb_state *mrb, mrb_value mod)
618{
619 mrb_value a, b;
620
621 if (mrb_get_args(mrb, "|S&", &a, &b) == 1) {
622 mrb_raise(mrb, E_NOTIMP_ERROR, "module_eval/class_eval with string not implemented");
623 }
624 return eval_under(mrb, mod, b, mrb_class_ptr(mod));
625}
626
627/* 15.3.1.3.18 */
628/*
629 * call-seq:
630 * obj.instance_eval {| | block } -> obj
631 *
632 * Evaluates the given block,within the context of the receiver (_obj_).
633 * In order to set the context, the variable +self+ is set to _obj_ while
634 * the code is executing, giving the code access to _obj_'s
635 * instance variables. In the version of <code>instance_eval</code>
636 * that takes a +String+, the optional second and third
637 * parameters supply a filename and starting line number that are used
638 * when reporting compilation errors.
639 *
640 * class KlassWithSecret
641 * def initialize
642 * @secret = 99
643 * end
644 * end
645 * k = KlassWithSecret.new
646 * k.instance_eval { @secret } #=> 99
647 */
648mrb_value
649mrb_obj_instance_eval(mrb_state *mrb, mrb_value self)
650{
651 mrb_value a, b;
652 mrb_value cv;
653 struct RClass *c;
654
655 if (mrb_get_args(mrb, "|S&", &a, &b) == 1) {
656 mrb_raise(mrb, E_NOTIMP_ERROR, "instance_eval with string not implemented");
657 }
658 switch (mrb_type(self)) {
659 case MRB_TT_SYMBOL:
660 case MRB_TT_FIXNUM:
661 case MRB_TT_FLOAT:
662 c = 0;
663 break;
664 default:
665 cv = mrb_singleton_class(mrb, self);
666 c = mrb_class_ptr(cv);
667 break;
668 }
669 return eval_under(mrb, self, b, c);
670}
671
672MRB_API mrb_value
673mrb_yield_with_class(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv, mrb_value self, struct RClass *c)
674{
675 struct RProc *p;
676 mrb_sym mid = mrb->c->ci->mid;
677 mrb_callinfo *ci;
678 int n = mrb->c->ci->nregs;
679 mrb_value val;
680
681 if (mrb_nil_p(b)) {
682 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
683 }
684 if (mrb->c->ci - mrb->c->cibase > MRB_FUNCALL_DEPTH_MAX) {
685 mrb_exc_raise(mrb, mrb_obj_value(mrb->stack_err));
686 }
687 p = mrb_proc_ptr(b);
688 ci = cipush(mrb);
689 ci->mid = mid;
690 ci->proc = p;
691 ci->stackent = mrb->c->stack;
692 ci->argc = argc;
693 ci->target_class = c;
694 ci->acc = CI_ACC_SKIP;
695 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 }
704
705 mrb->c->stack[0] = self;
706 if (argc > 0) {
707 stack_copy(mrb->c->stack+1, argv, argc);
708 }
709 mrb->c->stack[argc+1] = mrb_nil_value();
710
711 if (MRB_PROC_CFUNC_P(p)) {
712 val = p->body.func(mrb, self);
713 mrb->c->stack = mrb->c->ci->stackent;
714 }
715 else {
716 int cioff = mrb->c->ci - mrb->c->cibase;
717 val = mrb_run(mrb, p, self);
718 mrb->c->ci = mrb->c->cibase + cioff;
719 }
720 cipop(mrb);
721 return val;
722}
723
724MRB_API mrb_value
725mrb_yield_argv(mrb_state *mrb, mrb_value b, mrb_int argc, const mrb_value *argv)
726{
727 struct RProc *p = mrb_proc_ptr(b);
728
729 return mrb_yield_with_class(mrb, b, argc, argv, p->env->stack[0], p->target_class);
730}
731
732MRB_API mrb_value
733mrb_yield(mrb_state *mrb, mrb_value b, mrb_value arg)
734{
735 struct RProc *p = mrb_proc_ptr(b);
736
737 return mrb_yield_with_class(mrb, b, 1, &arg, p->env->stack[0], p->target_class);
738}
739
740mrb_value
741mrb_yield_cont(mrb_state *mrb, mrb_value b, mrb_value self, mrb_int argc, const mrb_value *argv)
742{
743 struct RProc *p;
744 mrb_callinfo *ci;
745
746 if (mrb_nil_p(b)) {
747 mrb_raise(mrb, E_ARGUMENT_ERROR, "no block given");
748 }
749 if (mrb_type(b) != MRB_TT_PROC) {
750 mrb_raise(mrb, E_TYPE_ERROR, "not a block");
751 }
752
753 p = mrb_proc_ptr(b);
754 ci = mrb->c->ci;
755
756 stack_extend(mrb, 3);
757 mrb->c->stack[1] = mrb_ary_new_from_values(mrb, argc, argv);
758 mrb->c->stack[2] = mrb_nil_value();
759 ci->argc = -1;
760 return mrb_exec_irep(mrb, self, p);
761}
762
763static struct RBreak*
764break_new(mrb_state *mrb, struct RProc *p, mrb_value val)
765{
766 struct RBreak *brk;
767
768 brk = (struct RBreak*)mrb_obj_alloc(mrb, MRB_TT_BREAK, NULL);
769 brk->iv = NULL;
770 brk->proc = p;
771 brk->val = val;
772
773 return brk;
774}
775
776typedef enum {
777 LOCALJUMP_ERROR_RETURN = 0,
778 LOCALJUMP_ERROR_BREAK = 1,
779 LOCALJUMP_ERROR_YIELD = 2
780} localjump_error_kind;
781
782static void
783localjump_error(mrb_state *mrb, localjump_error_kind kind)
784{
785 char kind_str[3][7] = { "return", "break", "yield" };
786 char kind_str_len[] = { 6, 5, 5 };
787 static const char lead[] = "unexpected ";
788 mrb_value msg;
789 mrb_value exc;
790
791 msg = mrb_str_buf_new(mrb, sizeof(lead) + 7);
792 mrb_str_cat(mrb, msg, lead, sizeof(lead) - 1);
793 mrb_str_cat(mrb, msg, kind_str[kind], kind_str_len[kind]);
794 exc = mrb_exc_new_str(mrb, E_LOCALJUMP_ERROR, msg);
795 mrb_exc_set(mrb, exc);
796}
797
798static void
799argnum_error(mrb_state *mrb, mrb_int num)
800{
801 mrb_value exc;
802 mrb_value str;
803 mrb_int argc = mrb->c->ci->argc;
804
805 if (argc < 0) {
806 mrb_value args = mrb->c->stack[1];
807 if (mrb_array_p(args)) {
808 argc = RARRAY_LEN(args);
809 }
810 }
811 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));
815 }
816 else {
817 str = mrb_format(mrb, "wrong number of arguments (%S for %S)",
818 mrb_fixnum_value(argc), mrb_fixnum_value(num));
819 }
820 exc = mrb_exc_new_str(mrb, E_ARGUMENT_ERROR, str);
821 mrb_exc_set(mrb, exc);
822}
823
824#define ERR_PC_SET(mrb, pc) mrb->c->ci->err = pc;
825#define ERR_PC_CLR(mrb) mrb->c->ci->err = 0;
826#ifdef MRB_ENABLE_DEBUG_HOOK
827#define CODE_FETCH_HOOK(mrb, irep, pc, regs) if ((mrb)->code_fetch_hook) (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs));
828#else
829#define CODE_FETCH_HOOK(mrb, irep, pc, regs)
830#endif
831
832#ifdef MRB_BYTECODE_DECODE_OPTION
833#define BYTECODE_DECODER(x) ((mrb)->bytecode_decoder)?(mrb)->bytecode_decoder((mrb), (x)):(x)
834#else
835#define BYTECODE_DECODER(x) (x)
836#endif
837
838
839#if defined __GNUC__ || defined __clang__ || defined __INTEL_COMPILER
840#define DIRECT_THREADED
841#endif
842
843#ifndef DIRECT_THREADED
844
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++; break
848#define JUMP break
849#define END_DISPATCH }}
850
851#else
852
853#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)]
857
858#define END_DISPATCH
859
860#endif
861
862MRB_API mrb_value
863mrb_vm_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
864{
865 mrb_irep *irep = proc->body.irep;
866 mrb_value result;
867 struct mrb_context *c = mrb->c;
868 int cioff = c->ci - c->cibase;
869 unsigned int nregs = irep->nregs;
870
871 if (!c->stack) {
872 stack_init(mrb);
873 }
874 if (stack_keep > nregs)
875 nregs = stack_keep;
876 stack_extend(mrb, nregs);
877 stack_clear(c->stack + stack_keep, nregs - stack_keep);
878 c->stack[0] = self;
879 result = mrb_vm_exec(mrb, proc, irep->iseq);
880 if (c->ci - c->cibase > cioff) {
881 c->ci = c->cibase + cioff;
882 }
883 if (mrb->c != c) {
884 if (mrb->c->fib) {
885 mrb_write_barrier(mrb, (struct RBasic*)mrb->c->fib);
886 }
887 mrb->c = c;
888 }
889 return result;
890}
891
892MRB_API mrb_value
893mrb_vm_exec(mrb_state *mrb, struct RProc *proc, mrb_code *pc)
894{
895 /* mrb_assert(mrb_proc_cfunc_p(proc)) */
896 mrb_irep *irep = proc->body.irep;
897 mrb_value *pool = irep->pool;
898 mrb_sym *syms = irep->syms;
899 mrb_code i;
900 int ai = mrb_gc_arena_save(mrb);
901 struct mrb_jmpbuf *prev_jmp = mrb->jmp;
902 struct mrb_jmpbuf c_jmp;
903
904#ifdef DIRECT_THREADED
905 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,
926 };
927#endif
928
929 mrb_bool exc_catched = FALSE;
930RETRY_TRY_BLOCK:
931
932 MRB_TRY(&c_jmp) {
933
934 if (exc_catched) {
935 exc_catched = FALSE;
936 if (mrb->exc && mrb->exc->tt == MRB_TT_BREAK)
937 goto L_BREAK;
938 goto L_RAISE;
939 }
940 mrb->jmp = &c_jmp;
941 mrb->c->ci->proc = proc;
942 mrb->c->ci->nregs = irep->nregs;
943
944#define regs (mrb->c->stack)
945 INIT_DISPATCH {
946 CASE(OP_NOP) {
947 /* do nothing */
948 NEXT;
949 }
950
951 CASE(OP_MOVE) {
952 /* A B R(A) := R(B) */
953 int a = GETARG_A(i);
954 int b = GETARG_B(i);
955 regs[a] = regs[b];
956 NEXT;
957 }
958
959 CASE(OP_LOADL) {
960 /* A Bx R(A) := Pool(Bx) */
961 int a = GETARG_A(i);
962 int bx = GETARG_Bx(i);
963#ifdef MRB_WORD_BOXING
964 mrb_value val = pool[bx];
965 if (mrb_float_p(val)) {
966 val = mrb_float_value(mrb, mrb_float(val));
967 }
968 regs[a] = val;
969#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);
992 regs[a] = regs[0];
993 NEXT;
994 }
995
996 CASE(OP_LOADT) {
997 /* A R(A) := true */
998 int a = GETARG_A(i);
999 SET_TRUE_VALUE(regs[a]);
1000 NEXT;
1001 }
1002
1003 CASE(OP_LOADF) {
1004 /* A R(A) := false */
1005 int a = GETARG_A(i);
1006 SET_FALSE_VALUE(regs[a]);
1007 NEXT;
1008 }
1009
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]);
1015 regs[a] = val;
1016 NEXT;
1017 }
1018
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);
1032 regs[a] = val;
1033 NEXT;
1034 }
1035
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);
1065 mrb_value val;
1066 ERR_PC_SET(mrb, pc);
1067 val = mrb_vm_cv_get(mrb, syms[bx]);
1068 ERR_PC_CLR(mrb);
1069 regs[a] = val;
1070 NEXT;
1071 }
1072
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)) */
1083 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);
1089 val = mrb_vm_const_get(mrb, sym);
1090 ERR_PC_CLR(mrb);
1091 regs[a] = val;
1092 NEXT;
1093 }
1094
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) */
1105 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]);
1111 ERR_PC_CLR(mrb);
1112 regs[a] = val;
1113 NEXT;
1114 }
1115
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);
1129 mrb_value *regs_a = regs + a;
1130 struct REnv *e = uvenv(mrb, c);
1131
1132 if (!e) {
1133 *regs_a = mrb_nil_value();
1134 }
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
1147 struct REnv *e = uvenv(mrb, c);
1148
1149 if (e) {
1150 mrb_value *regs_a = regs + a;
1151
1152 if (b < MRB_ENV_STACK_LEN(e)) {
1153 e->stack[b] = *regs_a;
1154 mrb_write_barrier(mrb, (struct RBasic*)e);
1155 }
1156 }
1157 NEXT;
1158 }
1159
1160 CASE(OP_JMP) {
1161 /* sBx pc+=sBx */
1162 int sbx = GETARG_sBx(i);
1163 pc += sbx;
1164 JUMP;
1165 }
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);
1171 if (mrb_test(regs[a])) {
1172 pc += sbx;
1173 JUMP;
1174 }
1175 NEXT;
1176 }
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);
1182 if (!mrb_test(regs[a])) {
1183 pc += sbx;
1184 JUMP;
1185 }
1186 NEXT;
1187 }
1188
1189 CASE(OP_ONERR) {
1190 /* sBx pc+=sBx on exception */
1191 int sbx = GETARG_sBx(i);
1192 if (mrb->c->rsize <= mrb->c->ci->ridx) {
1193 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
1256 mrb_exc_set(mrb, regs[a]);
1257 goto L_RAISE;
1258 }
1259
1260 CASE(OP_EPUSH) {
1261 /* Bx ensure_push(SEQ[Bx]) */
1262 int bx = GETARG_Bx(i);
1263 struct RProc *p;
1264
1265 p = mrb_closure_new(mrb, irep->reps[bx]);
1266 /* push ensure_stack */
1267 if (mrb->c->esize <= mrb->c->eidx+1) {
1268 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 }
1272 mrb->c->ensure[mrb->c->eidx++] = p;
1273 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);
1281 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 */
1302 };
1303
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;
1311 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;
1316
1317 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);
1347 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);
1360 mrb_method_missing(mrb, mid, recv, args);
1361 }
1362 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 }
1373
1374 /* push callinfo */
1375 ci = cipush(mrb);
1376 ci->mid = mid;
1377 ci->proc = m;
1378 ci->stackent = mrb->c->stack;
1379 ci->target_class = c;
1380
1381 ci->pc = pc + 1;
1382 ci->acc = a;
1383
1384 /* prepare stack */
1385 mrb->c->stack += a;
1386
1387 if (MRB_PROC_CFUNC_P(m)) {
1388 if (n == CALL_MAXARGS) {
1389 ci->argc = -1;
1390 ci->nregs = 3;
1391 }
1392 else {
1393 ci->argc = n;
1394 ci->nregs = n + 2;
1395 }
1396 result = m->body.func(mrb, recv);
1397 mrb_gc_arena_restore(mrb, ai);
1398 if (mrb->exc) goto L_RAISE;
1399 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 }
1407 }
1408 }
1409 if (!ci->target_class) { /* return from context modifying method (resume/yield) */
1410 if (ci->acc == CI_ACC_RESUMED) {
1411 mrb->jmp = prev_jmp;
1412 return result;
1413 }
1414 else {
1415 mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc));
1416 proc = ci[-1].proc;
1417 irep = proc->body.irep;
1418 pool = irep->pool;
1419 syms = irep->syms;
1420 }
1421 }
1422 mrb->c->stack[0] = result;
1423 /* pop stackpos */
1424 mrb->c->stack = ci->stackent;
1425 pc = ci->pc;
1426 cipop(mrb);
1427 JUMP;
1428 }
1429 else {
1430 /* setup environment for calling method */
1431 proc = mrb->c->ci->proc = m;
1432 irep = m->body.irep;
1433 pool = irep->pool;
1434 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 }
1444 pc = irep->iseq;
1445 JUMP;
1446 }
1447 }
1448
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) */
1457 mrb_callinfo *ci;
1458 mrb_value recv = mrb->c->stack[0];
1459 struct RProc *m = mrb_proc_ptr(recv);
1460
1461 /* replace callinfo */
1462 ci = mrb->c->ci;
1463 ci->target_class = m->target_class;
1464 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;
1477 }
1478 }
1479
1480 /* prepare stack */
1481 if (MRB_PROC_CFUNC_P(m)) {
1482 recv = m->body.func(mrb, recv);
1483 mrb_gc_arena_restore(mrb, ai);
1484 if (mrb->exc) goto L_RAISE;
1485 /* pop stackpos */
1486 ci = mrb->c->ci;
1487 mrb->c->stack = ci->stackent;
1488 regs[ci->acc] = recv;
1489 pc = ci->pc;
1490 cipop(mrb);
1491 irep = mrb->c->ci->proc->body.irep;
1492 pool = irep->pool;
1493 syms = irep->syms;
1494 JUMP;
1495 }
1496 else {
1497 /* setup environment for calling method */
1498 proc = m;
1499 irep = m->body.irep;
1500 if (!irep) {
1501 mrb->c->stack[0] = mrb_nil_value();
1502 goto L_RETURN;
1503 }
1504 pool = irep->pool;
1505 syms = irep->syms;
1506 ci->nregs = irep->nregs;
1507 stack_extend(mrb, irep->nregs);
1508 if (ci->argc < 0) {
1509 if (irep->nregs > 3) {
1510 stack_clear(regs+3, irep->nregs-3);
1511 }
1512 }
1513 else if (ci->argc+2 < irep->nregs) {
1514 stack_clear(regs+ci->argc+2, irep->nregs-ci->argc-2);
1515 }
1516 if (m->env) {
1517 regs[0] = m->env->stack[0];
1518 }
1519 pc = irep->iseq;
1520 JUMP;
1521 }
1522 }
1523
1524 CASE(OP_SUPER) {
1525 /* A C R(A) := super(R(A+1),... ,R(A+C+1)) */
1526 mrb_value recv;
1527 mrb_callinfo *ci = mrb->c->ci;
1528 struct RProc *m;
1529 struct RClass *c;
1530 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");
1540 mrb_exc_set(mrb, exc);
1541 goto L_RAISE;
1542 }
1543 recv = regs[0];
1544 c = mrb->c->ci->target_class->super;
1545 m = mrb_method_search_vm(mrb, &c, mid);
1546 if (!m) {
1547 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);
1559 mrb_method_missing(mrb, mid, recv, args);
1560 }
1561 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;
1591 }
1592
1593 /* push callinfo */
1594 ci = cipush(mrb);
1595 ci->mid = mid;
1596 ci->proc = m;
1597 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 }
1606
1607 /* prepare stack */
1608 mrb->c->stack += a;
1609 mrb->c->stack[0] = recv;
1610
1611 if (MRB_PROC_CFUNC_P(m)) {
1612 mrb_value v;
1613
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);
1621 mrb_gc_arena_restore(mrb, ai);
1622 if (mrb->exc) goto L_RAISE;
1623 ci = mrb->c->ci;
1624 if (!ci->target_class) { /* return from context modifying method (resume/yield) */
1625 if (ci->acc == CI_ACC_RESUMED) {
1626 mrb->jmp = prev_jmp;
1627 return v;
1628 }
1629 else {
1630 mrb_assert(!MRB_PROC_CFUNC_P(ci[-1].proc));
1631 proc = ci[-1].proc;
1632 irep = proc->body.irep;
1633 pool = irep->pool;
1634 syms = irep->syms;
1635 }
1636 }
1637 mrb->c->stack[0] = v;
1638 /* pop stackpos */
1639 mrb->c->stack = ci->stackent;
1640 pc = ci->pc;
1641 cipop(mrb);
1642 JUMP;
1643 }
1644 else {
1645 /* fill callinfo */
1646 ci->acc = a;
1647
1648 /* setup environment for calling method */
1649 ci->proc = m;
1650 irep = m->body.irep;
1651 pool = irep->pool;
1652 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 }
1660 pc = irep->iseq;
1661 JUMP;
1662 }
1663 }
1664
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;
1673 mrb_value *stack;
1674
1675 if (mrb->c->ci->mid == 0 || mrb->c->ci->target_class == NULL) {
1676 mrb_value exc;
1677
1678 L_NOSUPER:
1679 exc = mrb_exc_new_str_lit(mrb, E_NOMETHOD_ERROR, "super called outside of method");
1680 mrb_exc_set(mrb, exc);
1681 goto L_RAISE;
1682 }
1683 if (lv == 0) stack = regs + 1;
1684 else {
1685 struct REnv *e = uvenv(mrb, lv-1);
1686 if (!e) goto L_NOSUPER;
1687 stack = e->stack + 1;
1688 }
1689 if (r == 0) {
1690 regs[a] = mrb_ary_new_from_values(mrb, m1+m2, stack);
1691 }
1692 else {
1693 mrb_value *pp = NULL;
1694 struct RArray *rest;
1695 int len = 0;
1696
1697 if (mrb_array_p(stack[m1])) {
1698 struct RArray *ary = mrb_ary_ptr(stack[m1]);
1699
1700 pp = ary->ptr;
1701 len = ary->len;
1702 }
1703 regs[a] = mrb_ary_new_capa(mrb, m1+len+m2);
1704 rest = mrb_ary_ptr(regs[a]);
1705 if (m1 > 0) {
1706 stack_copy(rest->ptr, stack, m1);
1707 }
1708 if (len > 0) {
1709 stack_copy(rest->ptr+m1, pp, len);
1710 }
1711 if (m2 > 0) {
1712 stack_copy(rest->ptr+m1+len, stack+m1+1, m2);
1713 }
1714 rest->len = m1+len+m2;
1715 }
1716 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);
1729 /* unused
1730 int k = MRB_ASPEC_KEY(ax);
1731 int kd = MRB_ASPEC_KDICT(ax);
1732 int b = MRB_ASPEC_BLOCK(ax);
1733 */
1734 int argc = mrb->c->ci->argc;
1735 mrb_value *argv = regs+1;
1736 mrb_value *argv0 = argv;
1737 int len = m1 + o + r + m2;
1738 mrb_value *blk = &argv[argc < 0 ? 1 : argc];
1739
1740 if (argc < 0) {
1741 struct RArray *ary = mrb_ary_ptr(regs[1]);
1742 argv = ary->ptr;
1743 argc = ary->len;
1744 mrb_gc_protect(mrb, regs[1]);
1745 }
1746 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)) {
1749 argnum_error(mrb, m1+m2);
1750 goto L_RAISE;
1751 }
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) {
1760 int mlen = m2;
1761 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]);
1769 if (argv0 != argv) {
1770 value_move(&regs[1], argv, argc-mlen); /* m1 + o */
1771 }
1772 if (argc < m1) {
1773 stack_clear(&regs[argc+1], m1-argc);
1774 }
1775 if (mlen) {
1776 value_move(&regs[len-m2+1], &argv[argc-mlen], mlen);
1777 }
1778 if (mlen < m2) {
1779 stack_clear(&regs[len-m2+mlen+1], m2-mlen);
1780 }
1781 if (r) {
1782 regs[m1+o+1] = mrb_ary_new_capa(mrb, 0);
1783 }
1784 if (o == 0 || argc < m1+m2) pc++;
1785 else
1786 pc += argc - m1 - m2 + 1;
1787 }
1788 else {
1789 int rnum = 0;
1790 if (argv0 != argv) {
1791 regs[len+1] = *blk; /* move block */
1792 value_move(&regs[1], argv, m1+o);
1793 }
1794 if (r) {
1795 rnum = argc-m1-o-m2;
1796 regs[m1+o+1] = mrb_ary_new_from_values(mrb, rnum, argv+m1+o);
1797 }
1798 if (m2) {
1799 if (argc-m2 > m1) {
1800 value_move(&regs[m1+o+r+1], &argv[m1+o+rnum], m2);
1801 }
1802 }
1803 if (argv0 == argv) {
1804 regs[len+1] = *blk; /* move block */
1805 }
1806 pc += o + 1;
1807 }
1808 mrb->c->ci->argc = len;
1809 /* clear local (but non-argument) variables */
1810 if (irep->nlocals-len-2 > 0) {
1811 stack_clear(&regs[len+2], irep->nlocals-len-2);
1812 }
1813 JUMP;
1814 }
1815
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
1828 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;
1834
1835 ci = mrb->c->ci;
1836 if (ci->mid) {
1837 mrb_value blk;
1838
1839 if (ci->argc < 0) {
1840 blk = regs[2];
1841 }
1842 else {
1843 blk = regs[ci->argc+1];
1844 }
1845 if (mrb_type(blk) == MRB_TT_PROC) {
1846 struct RProc *p = mrb_proc_ptr(blk);
1847
1848 if (!MRB_PROC_STRICT_P(proc) &&
1849 ci > mrb->c->cibase && p->env == ci[-1].env) {
1850 p->flags |= MRB_PROC_ORPHAN;
1851 }
1852 }
1853 }
1854
1855 if (mrb->exc) {
1856 mrb_callinfo *ci0;
1857 mrb_value *stk;
1858
1859 L_RAISE:
1860 ci0 = ci = mrb->c->ci;
1861 if (ci == mrb->c->cibase) {
1862 if (ci->ridx == 0) goto L_FTOP;
1863 goto L_RESCUE;
1864 }
1865 stk = mrb->c->stack;
1866 while (ci[0].ridx == ci[-1].ridx) {
1867 cipop(mrb);
1868 mrb->c->stack = ci->stackent;
1869 if (ci->acc == CI_ACC_SKIP && prev_jmp) {
1870 mrb->jmp = prev_jmp;
1871 MRB_THROW(prev_jmp);
1872 }
1873 ci = mrb->c->ci;
1874 if (ci == mrb->c->cibase) {
1875 mrb->c->stack = stk;
1876 if (ci->ridx == 0) {
1877 L_FTOP: /* fiber top */
1878 if (mrb->c == mrb->root_c) {
1879 mrb->c->stack = mrb->c->stbase;
1880 goto L_STOP;
1881 }
1882 else {
1883 struct mrb_context *c = mrb->c;
1884
1885 if (c->fib) {
1886 mrb_write_barrier(mrb, (struct RBasic*)c->fib);
1887 }
1888 mrb->c = c->prev;
1889 c->prev = NULL;
1890 goto L_RAISE;
1891 }
1892 }
1893 break;
1894 }
1895 /* call ensure only when we skip this callinfo */
1896 if (ci[0].ridx == ci[-1].ridx) {
1897 while (mrb->c->eidx > ci->epos) {
1898 ecall(mrb, --mrb->c->eidx);
1899 ci = mrb->c->ci;
1900 }
1901 }
1902 }
1903 L_RESCUE:
1904 if (ci->ridx == 0) goto L_STOP;
1905 proc = ci->proc;
1906 irep = proc->body.irep;
1907 pool = irep->pool;
1908 syms = irep->syms;
1909 if (ci != ci0) {
1910 mrb->c->stack = ci[1].stackent;
1911 }
1912 stack_extend(mrb, irep->nregs);
1913 pc = mrb->c->rescue[--ci->ridx];
1914 }
1915 else {
1916 int acc;
1917 mrb_value v;
1918
1919 v = regs[GETARG_A(i)];
1920 mrb_gc_protect(mrb, v);
1921 switch (GETARG_B(i)) {
1922 case OP_R_RETURN:
1923 /* 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;
1931 }
1932
1933 ce = mrb->c->cibase + e->cioff;
1934 while (ci >= ce) {
1935 if (ci->env) {
1936 mrb_env_unshare(mrb, ci->env);
1937 }
1938 if (ci->acc < 0) {
1939 localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
1940 goto L_RAISE;
1941 }
1942 ci--;
1943 }
1944 if (ce == mrb->c->cibase) {
1945 localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
1946 goto L_RAISE;
1947 }
1948 mrb->c->stack = mrb->c->ci->stackent;
1949 mrb->c->ci = ce;
1950 break;
1951 }
1952 case OP_R_NORMAL:
1953 NORMAL_RETURN:
1954 if (ci == mrb->c->cibase) {
1955 if (!mrb->c->prev) { /* toplevel return */
1956 localjump_error(mrb, LOCALJUMP_ERROR_RETURN);
1957 goto L_RAISE;
1958 }
1959 if (mrb->c->prev->ci == mrb->c->prev->cibase) {
1960 mrb_value exc = mrb_exc_new_str_lit(mrb, E_FIBER_ERROR, "double resume");
1961 mrb_exc_set(mrb, exc);
1962 goto L_RAISE;
1963 }
1964 while (mrb->c->eidx > 0) {
1965 ecall(mrb, --mrb->c->eidx);
1966 }
1967 /* automatic yield at the end */
1968 mrb->c->status = MRB_FIBER_TERMINATED;
1969 mrb->c = mrb->c->prev;
1970 mrb->c->status = MRB_FIBER_RUNNING;
1971 }
1972 ci = mrb->c->ci;
1973 break;
1974 case OP_R_BREAK:
1975 if (MRB_PROC_STRICT_P(proc)) goto NORMAL_RETURN;
1976 if (MRB_PROC_ORPHAN_P(proc)) {
1977 mrb_value exc;
1978
1979 L_BREAK_ERROR:
1980 exc = mrb_exc_new_str_lit(mrb, E_LOCALJUMP_ERROR,
1981 "break from proc-closure");
1982 mrb_exc_set(mrb, exc);
1983 goto L_RAISE;
1984 }
1985 if (!proc->env || !MRB_ENV_STACK_SHARED_P(proc->env)) {
1986 goto L_BREAK_ERROR;
1987 }
1988 /* break from fiber block */
1989 if (mrb->c->ci == mrb->c->cibase && mrb->c->ci->pc) {
1990 struct mrb_context *c = mrb->c;
1991
1992 while (mrb->c->eidx > 0) {
1993 ecall(mrb, --mrb->c->eidx);
1994 }
1995 mrb->c = c->prev;
1996 c->prev = NULL;
1997 ci = mrb->c->ci;
1998 }
1999 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);
2004 mrb->c->vmexec = FALSE;
2005 mrb->exc = (struct RObject*)break_new(mrb, proc, v);
2006 mrb->jmp = prev_jmp;
2007 MRB_THROW(prev_jmp);
2008 }
2009 if (FALSE) {
2010 L_BREAK:
2011 v = ((struct RBreak*)mrb->exc)->val;
2012 proc = ((struct RBreak*)mrb->exc)->proc;
2013 mrb->exc = NULL;
2014 ci = mrb->c->ci;
2015 }
2016 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 }
2022 if (ci[-1].acc == CI_ACC_SKIP) {
2023 mrb->c->ci = ci;
2024 goto L_BREAK_ERROR;
2025 }
2026 ci--;
2027 }
2028 break;
2029 default:
2030 /* cannot happen */
2031 break;
2032 }
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);
2038 mrb->c->vmexec = FALSE;
2039 mrb->jmp = prev_jmp;
2040 return v;
2041 }
2042 ci = mrb->c->ci;
2043 acc = ci->acc;
2044 mrb->c->stack = ci->stackent;
2045 cipop(mrb);
2046 if (acc == CI_ACC_SKIP || acc == CI_ACC_DIRECT) {
2047 ARENA_RESTORE(mrb, ai);
2048 mrb->jmp = prev_jmp;
2049 return v;
2050 }
2051 pc = ci->pc;
2052 DEBUG(fprintf(stderr, "from :%s\n", mrb_sym2name(mrb, ci->mid)));
2053 proc = mrb->c->ci->proc;
2054 irep = proc->body.irep;
2055 pool = irep->pool;
2056 syms = irep->syms;
2057
2058 regs[acc] = v;
2059 ARENA_RESTORE(mrb, ai);
2060 }
2061 JUMP;
2062 }
2063
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, &regs[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;
2147 mrb_value *stack;
2148
2149 if (lv == 0) stack = regs + 1;
2150 else {
2151 struct REnv *e = uvenv(mrb, lv-1);
2152 if (!e || e->cioff == 0 ||
2153 (!MRB_ENV_STACK_SHARED_P(e) && e->cxt.mid == 0)) {
2154 localjump_error(mrb, LOCALJUMP_ERROR_YIELD);
2155 goto L_RAISE;
2156 }
2157 stack = e->stack + 1;
2158 }
2159 if (mrb_nil_p(stack[m1+r+m2])) {
2160 localjump_error(mrb, LOCALJUMP_ERROR_YIELD);
2161 goto L_RAISE;
2162 }
2163 regs[a] = stack[m1+r+m2];
2164 NEXT;
2165 }
2166
2167#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);
2175
2176 /* need to check if op is overridden */
2177 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {
2178 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):
2346 {
2347 mrb_int x = mrb_fixnum(regs[a]);
2348 mrb_int y = mrb_fixnum(regs[a+1]);
2349 SET_FLOAT_VALUE(mrb, regs[a], (mrb_float)x / (mrb_float)y);
2350 }
2351 break;
2352 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 }
2358 break;
2359 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
2369 break;
2370 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 }
2377#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 }
2418#else
2419 mrb_float(regs[a]) += GETARG_C(i);
2420#endif
2421 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_BOXING
2453 {
2454 mrb_float x = mrb_float(regs[a]);
2455 SET_FLOAT_VALUE(mrb, regs[a], x - GETARG_C(i));
2456 }
2457#else
2458 mrb_float(regs_a[0]) -= GETARG_C(i);
2459#endif
2460 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#define OP_CMP(op) do {\
2472 int result;\
2473 /* need to check if - is overridden */\
2474 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\
2475 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):\
2476 result = OP_CMP_BODY(op,mrb_fixnum,mrb_fixnum);\
2477 break;\
2478 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):\
2479 result = OP_CMP_BODY(op,mrb_fixnum,mrb_float);\
2480 break;\
2481 case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):\
2482 result = OP_CMP_BODY(op,mrb_float,mrb_fixnum);\
2483 break;\
2484 case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):\
2485 result = OP_CMP_BODY(op,mrb_float,mrb_float);\
2486 break;\
2487 default:\
2488 goto L_SEND;\
2489 }\
2490 if (result) {\
2491 SET_TRUE_VALUE(regs[a]);\
2492 }\
2493 else {\
2494 SET_FALSE_VALUE(regs[a]);\
2495 }\
2496} 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);
2501 if (mrb_obj_eq(mrb, regs[a], regs[a+1])) {
2502 SET_TRUE_VALUE(regs[a]);
2503 }
2504 else {
2505 OP_CMP(==);
2506 }
2507 NEXT;
2508 }
2509
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);
2513 OP_CMP(<);
2514 NEXT;
2515 }
2516
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);
2520 OP_CMP(<=);
2521 NEXT;
2522 }
2523
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);
2527 OP_CMP(>);
2528 NEXT;
2529 }
2530
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);
2534 OP_CMP(>=);
2535 NEXT;
2536 }
2537
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);
2543 mrb_value v = mrb_ary_new_from_values(mrb, c, &regs[b]);
2544 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);
2572 mrb_value v = regs[b];
2573
2574 if (!mrb_array_p(v)) {
2575 if (c == 0) {
2576 regs[a] = v;
2577 }
2578 else {
2579 SET_NIL_VALUE(regs[a]);
2580 }
2581 }
2582 else {
2583 v = mrb_ary_ref(mrb, v, c);
2584 regs[a] = v;
2585 }
2586 NEXT;
2587 }
2588
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);
2594 mrb_ary_set(mrb, regs[b], c, regs[a]);
2595 NEXT;
2596 }
2597
2598 CASE(OP_APOST) {
2599 /* A B C *R(A),R(A+1)..R(A+C) := R(A) */
2600 int a = GETARG_A(i);
2601 mrb_value v = regs[a];
2602 int pre = GETARG_B(i);
2603 int post = GETARG_C(i);
2604 struct RArray *ary;
2605 int len, idx;
2606
2607 if (!mrb_array_p(v)) {
2608 v = mrb_ary_new_from_values(mrb, 1, &regs[a]);
2609 }
2610 ary = mrb_ary_ptr(v);
2611 len = ary->len;
2612 if (len > pre + post) {
2613 v = mrb_ary_new_from_values(mrb, len - pre - post, ary->ptr+pre);
2614 regs[a++] = v;
2615 while (post--) {
2616 regs[a++] = ary->ptr[len-post-1];
2617 }
2618 }
2619 else {
2620 v = mrb_ary_new_capa(mrb, 0);
2621 regs[a++] = v;
2622 for (idx=0; idx+pre<len; idx++) {
2623 regs[a+idx] = ary->ptr[pre+idx];
2624 }
2625 while (idx < post) {
2626 SET_NIL_VALUE(regs[a+idx]);
2627 idx++;
2628 }
2629 }
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) */
2666 struct RProc *p;
2667 int c = GETARG_c(i);
2668
2669 if (c & OP_L_CAPTURE) {
2670 p = mrb_closure_new(mrb, irep->reps[GETARG_b(i)]);
2671 }
2672 else {
2673 p = mrb_proc_new(mrb, irep->reps[GETARG_b(i)]);
2674 }
2675 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)) */
2689 struct RClass *c = 0, *baseclass;
2690 int a = GETARG_A(i);
2691 mrb_value base, super;
2692 mrb_sym id = syms[GETARG_B(i)];
2693
2694 base = regs[a];
2695 super = regs[a+1];
2696 if (mrb_nil_p(base)) {
2697 baseclass = mrb->c->ci->proc->target_class;
2698 if (!baseclass) baseclass = mrb->c->ci->target_class;
2699
2700 base = mrb_obj_value(baseclass);
2701 }
2702 c = mrb_vm_define_class(mrb, base, super, id);
2703 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);
2712 mrb_value base;
2713 mrb_sym id = syms[GETARG_B(i)];
2714
2715 base = regs[a];
2716 if (mrb_nil_p(base)) {
2717 baseclass = mrb->c->ci->proc->target_class;
2718 if (!baseclass) baseclass = mrb->c->ci->target_class;
2719
2720 base = mrb_obj_value(baseclass);
2721 }
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);
2731 mrb_callinfo *ci;
2732 mrb_value recv = regs[a];
2733 struct RProc *p;
2734
2735 /* prepare closure */
2736 p = mrb_closure_new(mrb, irep->reps[GETARG_Bx(i)]);
2737 p->c = NULL;
2738
2739 /* prepare stack */
2740 ci = cipush(mrb);
2741 ci->pc = pc + 1;
2742 ci->acc = a;
2743 ci->mid = 0;
2744 ci->stackent = mrb->c->stack;
2745 ci->argc = 0;
2746 ci->target_class = mrb_class_ptr(recv);
2747
2748 /* prepare stack */
2749 mrb->c->stack += a;
2750
2751 /* setup closure */
2752 p->target_class = ci->target_class;
2753 ci->proc = p;
2754
2755 irep = p->body.irep;
2756 pool = irep->pool;
2757 syms = irep->syms;
2758 stack_extend(mrb, irep->nregs);
2759 stack_clear(regs+1, irep->nregs-1);
2760 ci->nregs = irep->nregs;
2761 pc = irep->iseq;
2762 JUMP;
2763 }
2764
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]);
2769 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) */
2805#ifdef MRB_ENABLE_DEBUG_HOOK
2806 mrb->debug_op_hook(mrb, irep, pc, regs);
2807#else
2808#ifndef MRB_DISABLE_STDIO
2809 printf("OP_DEBUG %d %d %d\n", GETARG_A(i), GETARG_B(i), GETARG_C(i));
2810#else
2811 abort();
2812#endif
2813#endif
2814 NEXT;
2815 }
2816
2817 CASE(OP_STOP) {
2818 /* stop VM */
2819 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 }
2827 ERR_PC_CLR(mrb);
2828 mrb->jmp = prev_jmp;
2829 if (mrb->exc) {
2830 return mrb_obj_value(mrb->exc);
2831 }
2832 return regs[irep->nlocals];
2833 }
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 }
2850 END_DISPATCH;
2851#undef regs
2852
2853 }
2854 MRB_CATCH(&c_jmp) {
2855 exc_catched = TRUE;
2856 goto RETRY_TRY_BLOCK;
2857 }
2858 MRB_END_EXC(&c_jmp);
2859}
2860
2861MRB_API mrb_value
2862mrb_run(mrb_state *mrb, struct RProc *proc, mrb_value self)
2863{
2864 if (mrb->c->ci->argc < 0) {
2865 return mrb_vm_run(mrb, proc, self, 3); /* receiver, args and block) */
2866 }
2867 else {
2868 return mrb_vm_run(mrb, proc, self, mrb->c->ci->argc + 2); /* argc + 2 (receiver and block) */
2869 }
2870}
2871
2872MRB_API mrb_value
2873mrb_top_run(mrb_state *mrb, struct RProc *proc, mrb_value self, unsigned int stack_keep)
2874{
2875 mrb_callinfo *ci;
2876 mrb_value v;
2877
2878 if (!mrb->c->cibase) {
2879 return mrb_vm_run(mrb, proc, self, stack_keep);
2880 }
2881 if (mrb->c->ci == mrb->c->cibase) {
2882 mrb->c->ci->env = NULL;
2883 return mrb_vm_run(mrb, proc, self, stack_keep);
2884 }
2885 ci = cipush(mrb);
2886 ci->mid = 0;
2887 ci->nregs = 1; /* protect the receiver */
2888 ci->acc = CI_ACC_SKIP;
2889 ci->target_class = mrb->object_class;
2890 v = mrb_vm_run(mrb, proc, self, stack_keep);
2891 cipop(mrb);
2892
2893 return v;
2894}
2895
2896#if defined(MRB_ENABLE_CXX_EXCEPTION) && defined(__cplusplus)
2897# if !defined(MRB_ENABLE_CXX_ABI)
2898} /* end of extern "C" */
2899# endif
2900mrb_int mrb_jmpbuf::jmpbuf_id = 0;
2901# if !defined(MRB_ENABLE_CXX_ABI)
2902extern "C" {
2903# endif
2904#endif
Note: See TracBrowser for help on using the repository browser.