26 #if defined(__cplusplus)
30 #if defined(__cplusplus)
35 #define SET_TRUE_VALUE(r) MRB_SET_VALUE(r, MRB_TT_TRUE, value.i, 1)
36 #define SET_FALSE_VALUE(r) MRB_SET_VALUE(r, MRB_TT_FALSE, value.i, 1)
37 #define SET_NIL_VALUE(r) MRB_SET_VALUE(r, MRB_TT_FALSE, value.i, 0)
38 #define SET_INT_VALUE(r,n) MRB_SET_VALUE(r, MRB_TT_FIXNUM, value.i, (n))
39 #define SET_SYM_VALUE(r,v) MRB_SET_VALUE(r, MRB_TT_SYMBOL, value.sym, (v))
40 #define SET_OBJ_VALUE(r,v) MRB_SET_VALUE(r, (((struct RObject*)(v))->tt), value.p, (v))
42 #define SET_FLT_VALUE(mrb,r,v) r.f = (v)
43 #elif defined(MRB_WORD_BOXING)
44 #define SET_FLT_VALUE(mrb,r,v) r = mrb_float_value(mrb, (v))
46 #define SET_FLT_VALUE(mrb,r,v) MRB_SET_VALUE(r, MRB_TT_FLOAT, value.f, (v))
49 #define STACK_INIT_SIZE 128
50 #define CALLINFO_INIT_SIZE 32
53 #ifndef MRB_STACK_GROWTH
54 #define MRB_STACK_GROWTH 128
60 #define MRB_STACK_MAX (0x40000 - MRB_STACK_GROWTH)
69 #define TO_STR(x) TO_STR_(x)
73 stack_clear(
mrb_value *from,
size_t count)
75 const mrb_value mrb_value_zero = { { 0 } };
78 *from++ = mrb_value_zero;
112 while (ci <= mrb->c->
ci) {
114 if (e && e->
cioff >= 0) {
115 ptrdiff_t off = e->
stack - oldbase;
117 e->
stack = newbase + off;
126 stack_extend(
mrb_state *mrb,
int room,
int keep)
137 if (keep > size) keep = size;
150 envadjust(mrb, oldbase, mrb->
c->
stbase);
159 #ifndef MRB_NAN_BOXING
160 stack_clear(&(mrb->
c->
stack[keep]), room - keep);
164 for (i=keep; i<room; i++) {
171 static inline struct REnv*
178 e = (
struct REnv*)e->c;
195 static inline struct REnv*
200 if (is_strict(mrb, e))
return e;
202 e = (
struct REnv*)e->c;
203 if (is_strict(mrb, e))
return e;
208 #define CI_ACC_SKIP -1
209 #define CI_ACC_DIRECT -2
220 if (ci + 1 == c->
ciend) {
221 size_t size = ci - c->
cibase;
242 size_t len = (size_t)e->flags;
246 stack_copy(p, e->
stack, len);
272 exc = mrb->
exc; mrb->
exc = 0;
275 if (!mrb->
exc) mrb->
exc = exc;
278 #ifndef MRB_FUNCALL_ARGC_MAX
279 #define MRB_FUNCALL_ARGC_MAX 16
290 else if (argc == 1) {
309 for (i = 0; i < argc; i++) {
326 if (setjmp(c_jmp) != 0) {
327 while (old_ci != mrb->
c->
ci) {
332 val = mrb_obj_value(mrb->
exc);
355 c = mrb_class(mrb,
self);
370 ci->
nregs = argc + 2;
377 stack_extend(mrb, ci->
nregs, 0);
380 mrb->
c->
stack[1] = mrb_symbol_value(undef);
381 stack_copy(mrb->
c->
stack+2, argv, argc-1);
384 stack_copy(mrb->
c->
stack+1, argv, argc);
386 mrb->
c->
stack[argc+1] = blk;
432 ci->
nregs = argc + 2;
440 stack_extend(mrb, ci->
nregs, 0);
443 stack_copy(mrb->
c->
stack+1, argv, argc);
445 mrb->
c->
stack[argc+1] = mrb_nil_value();
483 char kind_str[3][7] = {
"return",
"break",
"yield" };
484 char kind_str_len[] = { 6, 5, 5 };
485 static const char lead[] =
"unexpected ";
503 str =
mrb_format(mrb,
"'%S': wrong number of arguments (%S for %S)",
505 mrb_fixnum_value(mrb->
c->
ci->
argc), mrb_fixnum_value(num));
508 str =
mrb_format(mrb,
"wrong number of arguments (%S for %S)",
509 mrb_fixnum_value(mrb->
c->
ci->
argc), mrb_fixnum_value(num));
516 #define CODE_FETCH_HOOK(mrb, irep, pc, regs) ((mrb)->code_fetch_hook ? (mrb)->code_fetch_hook((mrb), (irep), (pc), (regs)) : NULL)
518 #define CODE_FETCH_HOOK(mrb, irep, pc, regs)
522 #define DIRECT_THREADED
525 #ifndef DIRECT_THREADED
527 #define INIT_DISPATCH for (;;) { i = *pc; CODE_FETCH_HOOK(mrb, irep, pc, regs); switch (GET_OPCODE(i)) {
528 #define CASE(op) case op:
529 #define NEXT pc++; break
531 #define END_DISPATCH }}
535 #define INIT_DISPATCH JUMP; return mrb_nil_value();
536 #define CASE(op) L_ ## op:
537 #define NEXT i=*++pc; CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]
538 #define JUMP i=*pc; CODE_FETCH_HOOK(mrb, irep, pc, regs); goto *optable[GET_OPCODE(i)]
547 #define CALL_MAXARGS 127
560 jmp_buf *prev_jmp = (jmp_buf *)mrb->
jmp;
563 #ifdef DIRECT_THREADED
564 static void *optable[] = {
565 &&L_OP_NOP, &&L_OP_MOVE,
566 &&L_OP_LOADL, &&L_OP_LOADI, &&L_OP_LOADSYM, &&L_OP_LOADNIL,
567 &&L_OP_LOADSELF, &&L_OP_LOADT, &&L_OP_LOADF,
568 &&L_OP_GETGLOBAL, &&L_OP_SETGLOBAL, &&L_OP_GETSPECIAL, &&L_OP_SETSPECIAL,
569 &&L_OP_GETIV, &&L_OP_SETIV, &&L_OP_GETCV, &&L_OP_SETCV,
570 &&L_OP_GETCONST, &&L_OP_SETCONST, &&L_OP_GETMCNST, &&L_OP_SETMCNST,
571 &&L_OP_GETUPVAR, &&L_OP_SETUPVAR,
572 &&L_OP_JMP, &&L_OP_JMPIF, &&L_OP_JMPNOT,
573 &&L_OP_ONERR, &&L_OP_RESCUE, &&L_OP_POPERR, &&L_OP_RAISE, &&L_OP_EPUSH, &&L_OP_EPOP,
574 &&L_OP_SEND, &&L_OP_SENDB, &&L_OP_FSEND,
575 &&L_OP_CALL, &&L_OP_SUPER, &&L_OP_ARGARY, &&L_OP_ENTER,
576 &&L_OP_KARG, &&L_OP_KDICT, &&L_OP_RETURN, &&L_OP_TAILCALL, &&L_OP_BLKPUSH,
577 &&L_OP_ADD, &&L_OP_ADDI, &&L_OP_SUB, &&L_OP_SUBI, &&L_OP_MUL, &&L_OP_DIV,
578 &&L_OP_EQ, &&L_OP_LT, &&L_OP_LE, &&L_OP_GT, &&L_OP_GE,
579 &&L_OP_ARRAY, &&L_OP_ARYCAT, &&L_OP_ARYPUSH, &&L_OP_AREF, &&L_OP_ASET, &&L_OP_APOST,
580 &&L_OP_STRING, &&L_OP_STRCAT, &&L_OP_HASH,
581 &&L_OP_LAMBDA, &&L_OP_RANGE, &&L_OP_OCLASS,
582 &&L_OP_CLASS, &&L_OP_MODULE, &&L_OP_EXEC,
583 &&L_OP_METHOD, &&L_OP_SCLASS, &&L_OP_TCLASS,
584 &&L_OP_DEBUG, &&L_OP_STOP, &&L_OP_ERR,
589 if (setjmp(c_jmp) == 0) {
733 struct REnv *e = uvenv(mrb, up);
736 *regs_a = mrb_nil_value();
740 *regs_a = e->
stack[idx];
750 struct REnv *e = uvenv(mrb, up);
755 e->
stack[idx] = *regs_a;
839 for (n=0; n<a; n++) {
840 ecall(mrb, --mrb->
c->
ci->
eidx);
878 c = mrb_class(mrb, recv);
889 value_move(regs+a+2, regs+a+1, ++n);
926 mrb->
c->
stack[0] = result;
928 if (mrb->
exc)
goto L_RAISE;
949 ci->
nregs = irep->nregs;
951 stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3);
954 stack_extend(mrb, irep->nregs, ci->
argc+2);
990 if (mrb->
exc)
goto L_RAISE;
994 regs[ci->
acc] = recv;
1007 mrb->
c->
stack[0] = mrb_nil_value();
1046 value_move(regs+a+2, regs+a+1, ++n);
1072 if (mrb->
exc)
goto L_RAISE;
1087 ci->
nregs = irep->nregs;
1089 stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3);
1092 stack_extend(mrb, irep->nregs, ci->
argc+2);
1104 int m1 = (bx>>10)&0x3f;
1105 int r = (bx>>9)&0x1;
1106 int m2 = (bx>>4)&0x1f;
1107 int lv = (bx>>0)&0xf;
1110 if (lv == 0) stack = regs + 1;
1112 struct REnv *e = uvenv(mrb, lv-1);
1115 static const char m[] =
"super called outside of method";
1120 stack = e->
stack + 1;
1138 stack_copy(rest->
ptr, stack, m1);
1140 stack_copy(rest->
ptr+m1, pp, len);
1143 stack_copy(rest->
ptr+m1+len, stack+m1+1, m2);
1145 rest->
len = m1+len+m2;
1147 regs[a+1] = stack[m1+r+m2];
1156 int m1 = (ax>>18)&0x1f;
1157 int o = (ax>>13)&0x1f;
1158 int r = (ax>>12)&0x1;
1159 int m2 = (ax>>7)&0x1f;
1168 int len = m1 + o + r + m2;
1169 mrb_value *blk = &argv[argc < 0 ? 1 : argc];
1179 if (argc < m1 + m2 || (r == 0 && argc > len)) {
1180 argnum_error(mrb, m1+m2);
1185 else if (len > 1 && argc == 1 &&
mrb_array_p(argv[0])) {
1192 if (argv0 != argv) {
1193 value_move(®s[1], argv, argc-m2);
1197 if (argc-m2 <= m1) {
1200 value_move(®s[len-m2+1], &argv[argc-mlen], mlen);
1207 pc += argc - m1 - m2 + 1;
1210 if (argv0 != argv) {
1212 value_move(®s[1], argv, m1+o);
1219 value_move(®s[m1+o+r+1], &argv[argc-m2], m2);
1222 if (argv0 == argv) {
1257 if (ci->
ridx == 0)
goto L_STOP;
1260 while (eidx > ci[-1].eidx) {
1263 while (ci[0].ridx == ci[-1].ridx) {
1268 mrb->
jmp = prev_jmp;
1271 while (eidx > ci->
eidx) {
1275 if (ci->
ridx == 0) {
1291 int acc, eidx = mrb->
c->
ci->
eidx;
1298 struct REnv *e = top_env(mrb, proc);
1314 if (!mrb->
c->
prev) {
1340 while (eidx > mrb->
c->
ci[-1].
eidx) {
1348 mrb->
jmp = prev_jmp;
1373 c = mrb_class(mrb, recv);
1384 value_move(regs+a+2, regs+a+1, ++n);
1401 value_move(mrb->
c->
stack, ®s[a], ci->
argc+1);
1414 stack_extend(mrb, (irep->nregs < 3) ? 3 : irep->nregs, 3);
1417 stack_extend(mrb, irep->nregs, ci->
argc+2);
1429 int m1 = (bx>>10)&0x3f;
1430 int r = (bx>>9)&0x1;
1431 int m2 = (bx>>4)&0x1f;
1432 int lv = (bx>>0)&0xf;
1435 if (lv == 0) stack = regs + 1;
1437 struct REnv *e = uvenv(mrb, lv-1);
1442 stack = e->
stack + 1;
1444 regs[a] = stack[m1+r+m2];
1448 #define attr_i value.i
1449 #ifdef MRB_NAN_BOXING
1451 #elif defined(MRB_WORD_BOXING)
1452 #define attr_f value.fp->f
1454 #define attr_f value.f
1457 #define TYPES2(a,b) ((((uint16_t)(a))<<8)|(((uint16_t)(b))&0xff))
1458 #define OP_MATH_BODY(op,v1,v2) do {\
1459 regs[a].v1 = regs[a].v1 op regs[a+1].v2;\
1476 #ifdef MRB_WORD_BOXING
1477 z = (z << MRB_FIXNUM_SHIFT) / (1 << MRB_FIXNUM_SHIFT);
1479 if ((x < 0) != (z < 0) && ((x < 0) ^ (y < 0)) == 0) {
1495 #ifdef MRB_WORD_BOXING
1506 #ifdef MRB_WORD_BOXING
1539 #ifdef MRB_WORD_BOXING
1540 z = (z << MRB_FIXNUM_SHIFT) / (1 << MRB_FIXNUM_SHIFT);
1542 if (((x < 0) ^ (y < 0)) != 0 && (x < 0) != (z < 0)) {
1558 #ifdef MRB_WORD_BOXING
1569 #ifdef MRB_WORD_BOXING
1598 #ifdef MRB_WORD_BOXING
1599 z = (z << MRB_FIXNUM_SHIFT) / (1 << MRB_FIXNUM_SHIFT);
1601 if (x != 0 && z/x != y) {
1617 #ifdef MRB_WORD_BOXING
1628 #ifdef MRB_WORD_BOXING
1665 #ifdef MRB_WORD_BOXING
1676 #ifdef MRB_WORD_BOXING
1704 if (((x < 0) ^ (y < 0)) == 0 && (x < 0) != (z < 0)) {
1713 #ifdef MRB_WORD_BOXING
1743 if ((x < 0) != (z < 0) && ((x < 0) ^ (y < 0)) != 0) {
1748 regs_a[0].attr_i = z;
1753 #ifdef MRB_WORD_BOXING
1770 #define OP_CMP_BODY(op,v1,v2) do {\
1771 if (regs[a].v1 op regs[a+1].v2) {\
1772 SET_TRUE_VALUE(regs[a]);\
1775 SET_FALSE_VALUE(regs[a]);\
1779 #define OP_CMP(op) do {\
1780 int a = GETARG_A(i);\
1782 switch (TYPES2(mrb_type(regs[a]),mrb_type(regs[a+1]))) {\
1783 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FIXNUM):\
1784 OP_CMP_BODY(op,attr_i,attr_i);\
1786 case TYPES2(MRB_TT_FIXNUM,MRB_TT_FLOAT):\
1787 OP_CMP_BODY(op,attr_i,attr_f);\
1789 case TYPES2(MRB_TT_FLOAT,MRB_TT_FIXNUM):\
1790 OP_CMP_BODY(op,attr_f,attr_i);\
1792 case TYPES2(MRB_TT_FLOAT,MRB_TT_FLOAT):\
1793 OP_CMP_BODY(op,attr_f,attr_f);\
1902 if (len > pre + post) {
1905 regs[a++] = ary->
ptr[len-post-1];
1910 for (i=0; i+pre<
len; i++) {
1911 regs[a+
i] = ary->
ptr[pre+
i];
1964 regs[
GETARG_A(i)] = mrb_obj_value(p);
1988 regs[a] = mrb_obj_value(c);
2005 regs[a] = mrb_obj_value(c);
2036 if (mrb->
exc)
goto L_RAISE;
2074 static const char msg[] =
"no target class or module";
2111 mrb->
jmp = prev_jmp;
2113 return mrb_obj_value(mrb->
exc);
2115 return regs[irep->nlocals];
2139 longjmp(*(jmp_buf*)mrb->
jmp, 1);