Groonga 3.0.9 Source Code Document
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
codegen.c
Go to the documentation of this file.
1 /*
2 ** codegen.c - mruby code generator
3 **
4 ** See Copyright Notice in mruby.h
5 */
6 
7 #include <ctype.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include "mruby.h"
11 #include "mruby/compile.h"
12 #include "mruby/irep.h"
13 #include "mruby/numeric.h"
14 #include "mruby/string.h"
15 #include "mruby/debug.h"
16 #include "node.h"
17 #include "opcode.h"
18 #include "re.h"
19 
22 
23 enum looptype {
29 } type;
30 
31 struct loopinfo {
32  enum looptype type;
33  int pc1, pc2, pc3, acc;
35  struct loopinfo *prev;
36 };
37 
38 typedef struct scope {
41  jmp_buf jmp;
42 
43  struct scope *prev;
44 
45  node *lv;
46 
47  int sp;
48  int pc;
49  int lastlabel;
50  int ainfo:15;
52 
53  struct loopinfo *loop;
55  char const *filename;
56  uint16_t lineno;
57 
59  uint16_t *lines;
60  int icapa;
61 
63  size_t pcapa;
64  int scapa;
65 
66  int nlocals;
67  int nregs;
68  int ai;
69 
70  int idx;
71 
73  uint16_t filename_index;
76 
77 static codegen_scope* scope_new(mrb_state *mrb, codegen_scope *prev, node *lv);
78 static void scope_finish(codegen_scope *s);
79 static struct loopinfo *loop_push(codegen_scope *s, enum looptype t);
80 static void loop_break(codegen_scope *s, node *tree);
81 static void loop_pop(codegen_scope *s, int val);
82 
83 static void gen_assignment(codegen_scope *s, node *node, int sp, int val);
84 static void gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val);
85 
86 static void codegen(codegen_scope *s, node *tree, int val);
87 
88 static void
89 codegen_error(codegen_scope *s, const char *message)
90 {
91  if (!s) return;
92  while (s->prev) {
94  s = s->prev;
95  }
97 #ifdef ENABLE_STDIO
98  if (s->filename && s->lineno) {
99  fprintf(stderr, "codegen error:%s:%d: %s\n", s->filename, s->lineno, message);
100  }
101  else {
102  fprintf(stderr, "codegen error: %s\n", message);
103  }
104 #endif
105  longjmp(s->jmp, 1);
106 }
107 
108 static void*
109 codegen_palloc(codegen_scope *s, size_t len)
110 {
111  void *p = mrb_pool_alloc(s->mpool, len);
112 
113  if (!p) codegen_error(s, "pool memory allocation");
114  return p;
115 }
116 
117 void*
119 {
120  void *p = mrb_malloc(s->mrb, len);
121 
122  if (!p) codegen_error(s, "mrb_malloc");
123  return p;
124 }
125 
126 void*
127 codegen_realloc(codegen_scope *s, void *p, size_t len)
128 {
129  p = mrb_realloc(s->mrb, p, len);
130 
131  if (!p && len > 0) codegen_error(s, "mrb_realloc");
132  return p;
133 }
134 
135 static int
136 new_label(codegen_scope *s)
137 {
138  s->lastlabel = s->pc;
139  return s->pc;
140 }
141 
142 static inline void
143 genop(codegen_scope *s, mrb_code i)
144 {
145  if (s->pc == s->icapa) {
146  s->icapa *= 2;
147  s->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->icapa);
148  if (s->lines) {
149  s->lines = (uint16_t*)codegen_realloc(s, s->lines, sizeof(short)*s->icapa);
150  s->irep->lines = s->lines;
151  }
152  }
153  s->iseq[s->pc] = i;
154  if (s->lines) {
155  s->lines[s->pc] = s->lineno;
156  }
157  s->pc++;
158 }
159 
160 #define NOVAL 0
161 #define VAL 1
162 
163 static void
164 genop_peep(codegen_scope *s, mrb_code i, int val)
165 {
166  /* peephole optimization */
167  if (s->lastlabel != s->pc && s->pc > 0) {
168  mrb_code i0 = s->iseq[s->pc-1];
169  int c1 = GET_OPCODE(i);
170  int c0 = GET_OPCODE(i0);
171 
172  switch (c1) {
173  case OP_MOVE:
174  if (GETARG_A(i) == GETARG_B(i)) {
175  /* skip useless OP_MOVE */
176  return;
177  }
178  if (val) break;
179  switch (c0) {
180  case OP_MOVE:
181  if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0) && GETARG_A(i) >= s->nlocals) {
182  /* skip swapping OP_MOVE */
183  return;
184  }
185  if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
186  s->iseq[s->pc-1] = MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0));
187  return;
188  }
189  break;
190  case OP_LOADI:
191  if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
192  s->iseq[s->pc-1] = MKOP_AsBx(OP_LOADI, GETARG_A(i), GETARG_sBx(i0));
193  return;
194  }
195  break;
196  case OP_ARRAY:
197  case OP_HASH:
198  case OP_RANGE:
199  case OP_AREF:
200  case OP_GETUPVAR:
201  if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
202  s->iseq[s->pc-1] = MKOP_ABC(c0, GETARG_A(i), GETARG_B(i0), GETARG_C(i0));
203  return;
204  }
205  break;
206  case OP_LOADSYM:
207  case OP_GETGLOBAL:
208  case OP_GETIV:
209  case OP_GETCV:
210  case OP_GETCONST:
211  case OP_GETSPECIAL:
212  case OP_LOADL:
213  case OP_STRING:
214  if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
215  s->iseq[s->pc-1] = MKOP_ABx(c0, GETARG_A(i), GETARG_Bx(i0));
216  return;
217  }
218  break;
219  case OP_SCLASS:
220  if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
221  s->iseq[s->pc-1] = MKOP_AB(c0, GETARG_A(i), GETARG_B(i0));
222  return;
223  }
224  break;
225  case OP_LOADNIL:
226  case OP_LOADSELF:
227  case OP_LOADT:
228  case OP_LOADF:
229  case OP_OCLASS:
230  if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) {
231  s->iseq[s->pc-1] = MKOP_A(c0, GETARG_A(i));
232  return;
233  }
234  break;
235  default:
236  break;
237  }
238  break;
239  case OP_SETIV:
240  case OP_SETCV:
241  case OP_SETCONST:
242  case OP_SETMCNST:
243  case OP_SETGLOBAL:
244  if (val) break;
245  if (c0 == OP_MOVE) {
246  if (GETARG_A(i) == GETARG_A(i0)) {
247  s->iseq[s->pc-1] = MKOP_ABx(c1, GETARG_B(i0), GETARG_Bx(i));
248  return;
249  }
250  }
251  break;
252  case OP_SETUPVAR:
253  if (val) break;
254  if (c0 == OP_MOVE) {
255  if (GETARG_A(i) == GETARG_A(i0)) {
256  s->iseq[s->pc-1] = MKOP_ABC(c1, GETARG_B(i0), GETARG_B(i), GETARG_C(i));
257  return;
258  }
259  }
260  break;
261  case OP_EPOP:
262  if (c0 == OP_EPOP) {
263  s->iseq[s->pc-1] = MKOP_A(OP_EPOP, GETARG_A(i0)+GETARG_A(i));
264  return;
265  }
266  break;
267  case OP_POPERR:
268  if (c0 == OP_POPERR) {
269  s->iseq[s->pc-1] = MKOP_A(OP_POPERR, GETARG_A(i0)+GETARG_A(i));
270  return;
271  }
272  break;
273  case OP_RETURN:
274  switch (c0) {
275  case OP_RETURN:
276  return;
277  case OP_MOVE:
278  s->iseq[s->pc-1] = MKOP_AB(OP_RETURN, GETARG_B(i0), OP_R_NORMAL);
279  return;
280  case OP_SETIV:
281  case OP_SETCV:
282  case OP_SETCONST:
283  case OP_SETMCNST:
284  case OP_SETUPVAR:
285  case OP_SETGLOBAL:
286  s->pc--;
287  genop_peep(s, i0, NOVAL);
288  i0 = s->iseq[s->pc-1];
289  genop(s, MKOP_AB(OP_RETURN, GETARG_A(i0), OP_R_NORMAL));
290  return;
291 #if 0
292  case OP_SEND:
293  if (GETARG_B(i) == OP_R_NORMAL && GETARG_A(i) == GETARG_A(i0)) {
294  s->iseq[s->pc-1] = MKOP_ABC(OP_TAILCALL, GETARG_A(i0), GETARG_B(i0), GETARG_C(i0));
295  return;
296  }
297  break;
298 #endif
299  default:
300  break;
301  }
302  break;
303  case OP_ADD:
304  case OP_SUB:
305  if (c0 == OP_LOADI) {
306  int c = GETARG_sBx(i0);
307 
308  if (c1 == OP_SUB) c = -c;
309  if (c > 127 || c < -127) break;
310  if (0 <= c)
311  s->iseq[s->pc-1] = MKOP_ABC(OP_ADDI, GETARG_A(i), GETARG_B(i), c);
312  else
313  s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c);
314  return;
315  }
316  case OP_STRCAT:
317  if (c0 == OP_STRING) {
318  int i = GETARG_Bx(i0);
319 
320  if (mrb_type(s->irep->pool[i]) == MRB_TT_STRING &&
321  RSTRING_LEN(s->irep->pool[i]) == 0) {
322  s->pc--;
323  return;
324  }
325  }
326  break;
327  default:
328  break;
329  }
330  }
331  genop(s, i);
332 }
333 
334 static void
335 scope_error(codegen_scope *s)
336 {
337  exit(EXIT_FAILURE);
338 }
339 
340 static inline void
341 dispatch(codegen_scope *s, int pc)
342 {
343  int diff = s->pc - pc;
344  mrb_code i = s->iseq[pc];
345  int c = GET_OPCODE(i);
346 
347  s->lastlabel = s->pc;
348  switch (c) {
349  case OP_JMP:
350  case OP_JMPIF:
351  case OP_JMPNOT:
352  case OP_ONERR:
353  break;
354  default:
355 #ifdef ENABLE_STDIO
356  fprintf(stderr, "bug: dispatch on non JMP op\n");
357 #endif
358  scope_error(s);
359  break;
360  }
361  s->iseq[pc] = MKOP_AsBx(c, GETARG_A(i), diff);
362 }
363 
364 static void
365 dispatch_linked(codegen_scope *s, int pc)
366 {
367  mrb_code i;
368  int pos;
369 
370  if (!pc) return;
371  for (;;) {
372  i = s->iseq[pc];
373  pos = GETARG_sBx(i);
374  dispatch(s, pc);
375  if (!pos) break;
376  pc = pos;
377  }
378 }
379 
380 #define nregs_update do {if (s->sp > s->nregs) s->nregs = s->sp;} while (0)
381 static void
382 push_(codegen_scope *s)
383 {
384  if (s->sp > 511) {
385  codegen_error(s, "too complex expression");
386  }
387  s->sp++;
388  nregs_update;
389 }
390 
391 #define push() push_(s)
392 #define pop_(s) ((s)->sp--)
393 #define pop() pop_(s)
394 #define pop_n(n) (s->sp-=(n))
395 #define cursp() (s->sp)
396 
397 static inline int
398 new_lit(codegen_scope *s, mrb_value val)
399 {
400  size_t i;
401 
402  switch (mrb_type(val)) {
403  case MRB_TT_STRING:
404  for (i=0; i<s->irep->plen; i++) {
405  mrb_value pv = s->irep->pool[i];
406  mrb_int len;
407 
408  if (mrb_type(pv) != MRB_TT_STRING) continue;
409  if ((len = RSTRING_LEN(pv)) != RSTRING_LEN(val)) continue;
410  if (memcmp(RSTRING_PTR(pv), RSTRING_PTR(val), len) == 0)
411  return i;
412  }
413  break;
414  case MRB_TT_FLOAT:
415  default:
416  for (i=0; i<s->irep->plen; i++) {
417  if (mrb_obj_equal(s->mrb, s->irep->pool[i], val)) return i;
418  }
419  break;
420  }
421 
422  if (s->irep->plen == s->pcapa) {
423  s->pcapa *= 2;
424  s->irep->pool = (mrb_value *)codegen_realloc(s, s->irep->pool, sizeof(mrb_value)*s->pcapa);
425  }
426  s->irep->pool[s->irep->plen] = val;
427  i = s->irep->plen++;
428 
429  return i;
430 }
431 
432 static inline int
433 new_msym(codegen_scope *s, mrb_sym sym)
434 {
435  size_t i, len;
436 
437  len = s->irep->slen;
438  if (len > 256) len = 256;
439  for (i=0; i<len; i++) {
440  if (s->irep->syms[i] == sym) return i;
441  if (s->irep->syms[i] == 0) break;
442  }
443  if (i == 256) {
444  codegen_error(s, "too many symbols (max 256)");
445  }
446  s->irep->syms[i] = sym;
447  if (i == s->irep->slen) s->irep->slen++;
448  return i;
449 }
450 
451 static inline int
452 new_sym(codegen_scope *s, mrb_sym sym)
453 {
454  size_t i;
455 
456  for (i=0; i<s->irep->slen; i++) {
457  if (s->irep->syms[i] == sym) return i;
458  }
459  if (s->irep->slen > 125 && s->irep->slen < 256) {
460  s->irep->syms = (mrb_sym *)codegen_realloc(s, s->irep->syms, sizeof(mrb_sym)*65536);
461  for (i = 0; i < 256 - s->irep->slen; i++) {
462  static const mrb_sym mrb_sym_zero = { 0 };
463  s->irep->syms[i + s->irep->slen] = mrb_sym_zero;
464  }
465  s->irep->slen = 256;
466  }
467  s->irep->syms[s->irep->slen] = sym;
468  return s->irep->slen++;
469 }
470 
471 static int
472 node_len(node *tree)
473 {
474  int n = 0;
475 
476  while (tree) {
477  n++;
478  tree = tree->cdr;
479  }
480  return n;
481 }
482 
483 #define sym(x) ((mrb_sym)(intptr_t)(x))
484 #define lv_name(lv) sym((lv)->car)
485 static int
486 lv_idx(codegen_scope *s, mrb_sym id)
487 {
488  node *lv = s->lv;
489  int n = 1;
490 
491  while (lv) {
492  if (lv_name(lv) == id) return n;
493  n++;
494  lv = lv->cdr;
495  }
496  return 0;
497 }
498 
499 static void
500 for_body(codegen_scope *s, node *tree)
501 {
502  codegen_scope *prev = s;
503  int idx, base = s->idx;
504  struct loopinfo *lp;
505  node *n2;
506  mrb_code c;
507 
508  // generate receiver
509  codegen(s, tree->cdr->car, VAL);
510  // generate loop-block
511  s = scope_new(s->mrb, s, tree->car);
512  idx = s->idx;
513 
514  lp = loop_push(s, LOOP_FOR);
515  lp->pc1 = new_label(s);
516 
517  // generate loop variable
518  n2 = tree->car;
519  if (n2->car && !n2->car->cdr && !n2->cdr) {
520  genop(s, MKOP_Ax(OP_ENTER, 0x40000));
521  gen_assignment(s, n2->car->car, 1, NOVAL);
522  }
523  else {
524  genop(s, MKOP_Ax(OP_ENTER, 0x40000));
525  gen_vmassignment(s, n2, 1, VAL);
526  }
527  codegen(s, tree->cdr->cdr->car, VAL);
528  pop();
529  if (s->pc > 0) {
530  c = s->iseq[s->pc-1];
531  if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel)
532  genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
533  }
534  loop_pop(s, NOVAL);
535  scope_finish(s);
536  s = prev;
537  genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx - base, OP_L_BLOCK));
538  pop();
539  idx = new_msym(s, mrb_intern2(s->mrb, "each", 4));
540  genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, 0));
541 }
542 
543 static int
544 lambda_body(codegen_scope *s, node *tree, int blk)
545 {
546  int idx, base = s->idx;
547  mrb_code c;
548 
549  s = scope_new(s->mrb, s, tree->car);
550  idx = s->idx;
551  s->mscope = !blk;
552 
553  if (blk) {
554  struct loopinfo *lp = loop_push(s, LOOP_BLOCK);
555  lp->pc1 = new_label(s);
556  }
557  tree = tree->cdr;
558  if (tree->car) {
559  mrb_aspec a;
560  int ma, oa, ra, pa, ka, kd, ba;
561  int pos, i;
562  node *n, *opt;
563 
564  ma = node_len(tree->car->car);
565  n = tree->car->car;
566  while (n) {
567  n = n->cdr;
568  }
569  oa = node_len(tree->car->cdr->car);
570  ra = tree->car->cdr->cdr->car ? 1 : 0;
571  pa = node_len(tree->car->cdr->cdr->cdr->car);
572  ka = kd = 0;
573  ba = tree->car->cdr->cdr->cdr->cdr ? 1 : 0;
574 
575  a = ((mrb_aspec)(ma & 0x1f) << 18)
576  | ((mrb_aspec)(oa & 0x1f) << 13)
577  | ((ra & 1) << 12)
578  | ((pa & 0x1f) << 7)
579  | ((ka & 0x1f) << 2)
580  | ((kd & 1)<< 1)
581  | (ba & 1);
582  s->ainfo = (((ma+oa) & 0x3f) << 6) /* (12bits = 6:1:5) */
583  | ((ra & 1) << 5)
584  | (pa & 0x1f);
585  genop(s, MKOP_Ax(OP_ENTER, a));
586  pos = new_label(s);
587  for (i=0; i<oa; i++) {
588  new_label(s);
589  genop(s, MKOP_sBx(OP_JMP, 0));
590  }
591  if (oa > 0) {
592  genop(s, MKOP_sBx(OP_JMP, 0));
593  }
594  opt = tree->car->cdr->car;
595  i = 0;
596  while (opt) {
597  int idx;
598 
599  dispatch(s, pos+i);
600  codegen(s, opt->car->cdr, VAL);
601  idx = lv_idx(s, (mrb_sym)(intptr_t)opt->car->car);
602  pop();
603  genop_peep(s, MKOP_AB(OP_MOVE, idx, cursp()), NOVAL);
604  i++;
605  opt = opt->cdr;
606  }
607  if (oa > 0) {
608  dispatch(s, pos+i);
609  }
610  }
611  codegen(s, tree->cdr->car, VAL);
612  pop();
613  if (s->pc > 0) {
614  c = s->iseq[s->pc-1];
615  if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel) {
616  if (s->nregs == 0) {
617  genop(s, MKOP_A(OP_LOADNIL, 0));
618  genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
619  }
620  else {
621  genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
622  }
623  }
624  }
625  if (blk) {
626  loop_pop(s, NOVAL);
627  }
628  scope_finish(s);
629 
630  return idx - base;
631 }
632 
633 static int
634 scope_body(codegen_scope *s, node *tree)
635 {
636  codegen_scope *scope = scope_new(s->mrb, s, tree->car);
637  int idx = scope->idx;
638 
639  codegen(scope, tree->cdr, VAL);
640  if (!s->iseq) {
641  genop(scope, MKOP_A(OP_STOP, 0));
642  }
643  else {
644  if (scope->nregs == 0) {
645  genop(scope, MKOP_A(OP_LOADNIL, 0));
646  genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL));
647  }
648  else {
649  genop_peep(scope, MKOP_AB(OP_RETURN, scope->sp, OP_R_NORMAL), NOVAL);
650  }
651  }
652  scope_finish(scope);
653 
654  return idx - s->idx;
655 }
656 
657 static mrb_bool
658 nosplat(node *t)
659 {
660  while (t) {
661  if ((intptr_t)t->car->car == NODE_SPLAT) return FALSE;
662  t = t->cdr;
663  }
664  return TRUE;
665 }
666 
667 static mrb_sym
668 attrsym(codegen_scope *s, mrb_sym a)
669 {
670  const char *name;
671  size_t len;
672  char *name2;
673 
674  name = mrb_sym2name_len(s->mrb, a, &len);
675  name2 = (char *)codegen_palloc(s, len+1);
676  memcpy(name2, name, len);
677  name2[len] = '=';
678  name2[len+1] = '\0';
679 
680  return mrb_intern2(s->mrb, name2, len+1);
681 }
682 
683 static int
684 gen_values(codegen_scope *s, node *t, int val)
685 {
686  int n = 0;
687 
688  while (t) {
689  if (n >= 127 || (intptr_t)t->car->car == NODE_SPLAT) { // splat mode
690  if (val) {
691  pop_n(n);
692  genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n));
693  push();
694  codegen(s, t->car, VAL);
695  pop(); pop();
696  genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
697  t = t->cdr;
698  while (t) {
699  push();
700  codegen(s, t->car, VAL);
701  pop(); pop();
702  if ((intptr_t)t->car->car == NODE_SPLAT) {
703  genop(s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));
704  }
705  else {
706  genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));
707  }
708  t = t->cdr;
709  }
710  }
711  else {
712  codegen(s, t->car->cdr, NOVAL);
713  t = t->cdr;
714  while (t) {
715  codegen(s, t->car, NOVAL);
716  t = t->cdr;
717  }
718  }
719  return -1;
720  }
721  // normal (no splat) mode
722  codegen(s, t->car, val);
723  n++;
724  t = t->cdr;
725  }
726  return n;
727 }
728 
729 #define CALL_MAXARGS 127
730 
731 static void
732 gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val)
733 {
734  mrb_sym sym = name ? name : sym(tree->cdr->car);
735  int idx;
736  int n = 0, noop = 0, sendv = 0, blk = 0;
737 
738  codegen(s, tree->car, VAL); /* receiver */
739  idx = new_msym(s, sym);
740  tree = tree->cdr->cdr->car;
741  if (tree) {
742  n = gen_values(s, tree->car, VAL);
743  if (n < 0) {
744  n = noop = sendv = 1;
745  push();
746  }
747  }
748  if (sp) {
749  if (sendv) {
750  pop();
751  genop(s, MKOP_AB(OP_ARYPUSH, cursp(), sp));
752  push();
753  }
754  else {
755  genop(s, MKOP_AB(OP_MOVE, cursp(), sp));
756  push();
757  n++;
758  }
759  }
760  if (tree && tree->cdr) {
761  noop = 1;
762  codegen(s, tree->cdr, VAL);
763  pop();
764  }
765  else {
766  blk = cursp();
767  }
768  pop_n(n+1);
769  {
770  size_t len;
771  const char *name = mrb_sym2name_len(s->mrb, sym, &len);
772 
773  if (!noop && len == 1 && name[0] == '+') {
774  genop_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, n), val);
775  }
776  else if (!noop && len == 1 && name[0] == '-') {
777  genop_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, n), val);
778  }
779  else if (!noop && len == 1 && name[0] == '*') {
780  genop(s, MKOP_ABC(OP_MUL, cursp(), idx, n));
781  }
782  else if (!noop && len == 1 && name[0] == '/') {
783  genop(s, MKOP_ABC(OP_DIV, cursp(), idx, n));
784  }
785  else if (!noop && len == 1 && name[0] == '<') {
786  genop(s, MKOP_ABC(OP_LT, cursp(), idx, n));
787  }
788  else if (!noop && len == 2 && name[0] == '<' && name[1] == '=') {
789  genop(s, MKOP_ABC(OP_LE, cursp(), idx, n));
790  }
791  else if (!noop && len == 1 && name[0] == '>') {
792  genop(s, MKOP_ABC(OP_GT, cursp(), idx, n));
793  }
794  else if (!noop && len == 2 && name[0] == '>' && name[1] == '=') {
795  genop(s, MKOP_ABC(OP_GE, cursp(), idx, n));
796  }
797  else if (!noop && len == 2 && name[0] == '=' && name[1] == '=') {
798  genop(s, MKOP_ABC(OP_EQ, cursp(), idx, n));
799  }
800  else {
801  if (sendv) n = CALL_MAXARGS;
802  if (blk > 0) { /* no block */
803  genop(s, MKOP_ABC(OP_SEND, cursp(), idx, n));
804  }
805  else {
806  genop(s, MKOP_ABC(OP_SENDB, cursp(), idx, n));
807  }
808  }
809  }
810  if (val) {
811  push();
812  }
813 }
814 
815 static void
816 gen_assignment(codegen_scope *s, node *node, int sp, int val)
817 {
818  int idx;
819  int type = (intptr_t)node->car;
820 
821  node = node->cdr;
822  switch ((intptr_t)type) {
823  case NODE_GVAR:
824  idx = new_sym(s, sym(node));
825  genop_peep(s, MKOP_ABx(OP_SETGLOBAL, sp, idx), val);
826  break;
827  case NODE_LVAR:
828  idx = lv_idx(s, sym(node));
829  if (idx > 0) {
830  if (idx != sp) {
831  genop_peep(s, MKOP_AB(OP_MOVE, idx, sp), val);
832  }
833  break;
834  }
835  else { /* upvar */
836  int lv = 0;
837  codegen_scope *up = s->prev;
838 
839  while (up) {
840  idx = lv_idx(up, sym(node));
841  if (idx > 0) {
842  genop_peep(s, MKOP_ABC(OP_SETUPVAR, sp, idx, lv), val);
843  break;
844  }
845  lv++;
846  up = up->prev;
847  }
848  }
849  break;
850  case NODE_IVAR:
851  idx = new_sym(s, sym(node));
852  genop_peep(s, MKOP_ABx(OP_SETIV, sp, idx), val);
853  break;
854  case NODE_CVAR:
855  idx = new_sym(s, sym(node));
856  genop_peep(s, MKOP_ABx(OP_SETCV, sp, idx), val);
857  break;
858  case NODE_CONST:
859  idx = new_sym(s, sym(node));
860  genop_peep(s, MKOP_ABx(OP_SETCONST, sp, idx), val);
861  break;
862  case NODE_COLON2:
863  idx = new_sym(s, sym(node->cdr));
864  genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), NOVAL);
865  push();
866  codegen(s, node->car, VAL);
867  pop_n(2);
868  genop_peep(s, MKOP_ABx(OP_SETMCNST, cursp(), idx), val);
869  break;
870 
871  case NODE_CALL:
872  push();
873  gen_call(s, node, attrsym(s, sym(node->cdr->car)), sp, NOVAL);
874  pop();
875  if (val) {
876  genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), val);
877  }
878  break;
879 
880  default:
881 #ifdef ENABLE_STDIO
882  printf("unknown lhs %d\n", type);
883 #endif
884  break;
885  }
886  if (val) push();
887 }
888 
889 static void
890 gen_vmassignment(codegen_scope *s, node *tree, int rhs, int val)
891 {
892  int n = 0, post = 0;
893  node *t, *p;
894 
895  if (tree->car) { /* pre */
896  t = tree->car;
897  n = 0;
898  while (t) {
899  genop(s, MKOP_ABC(OP_AREF, cursp(), rhs, n));
900  gen_assignment(s, t->car, cursp(), NOVAL);
901  n++;
902  t = t->cdr;
903  }
904  }
905  t = tree->cdr;
906  if (t) {
907  if (t->cdr) { /* post count */
908  p = t->cdr->car;
909  while (p) {
910  post++;
911  p = p->cdr;
912  }
913  }
914  if (val) {
915  genop(s, MKOP_AB(OP_MOVE, cursp(), rhs));
916  push();
917  }
918  pop();
919  genop(s, MKOP_ABC(OP_APOST, cursp(), n, post));
920  n = 1;
921  if (t->car) { /* rest */
922  gen_assignment(s, t->car, cursp(), NOVAL);
923  }
924  if (t->cdr && t->cdr->car) {
925  t = t->cdr->car;
926  while (t) {
927  gen_assignment(s, t->car, cursp()+n, NOVAL);
928  t = t->cdr;
929  n++;
930  }
931  }
932  }
933  else {
934  pop();
935  }
936 }
937 
938 static void
939 gen_send_intern(codegen_scope *s)
940 {
941  pop();
942  genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern2(s->mrb, "intern", 6)), 0));
943  push();
944 }
945 static void
946 gen_literal_array(codegen_scope *s, node *tree, int sym, int val)
947 {
948  if (val) {
949  int i = 0, j = 0;
950 
951  while (tree) {
952  switch ((intptr_t)tree->car->car) {
953  case NODE_STR:
954  if ((tree->cdr == NULL) && ((intptr_t)tree->car->cdr->cdr == 0))
955  break;
956  /* fall through */
957  case NODE_BEGIN:
958  codegen(s, tree->car, VAL);
959  ++j;
960  break;
961 
962  case NODE_LITERAL_DELIM:
963  if (j > 0) {
964  j = 0;
965  ++i;
966  if (sym)
967  gen_send_intern(s);
968  }
969  break;
970  }
971  if (j >= 2) {
972  pop(); pop();
973  genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
974  push();
975  j = 1;
976  }
977  tree = tree->cdr;
978  }
979  if (j > 0) {
980  ++i;
981  if (sym)
982  gen_send_intern(s);
983  }
984  pop_n(i);
985  genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), i));
986  push();
987  }
988  else {
989  while (tree) {
990  switch ((intptr_t)tree->car->car) {
991  case NODE_BEGIN: case NODE_BLOCK:
992  codegen(s, tree->car, NOVAL);
993  }
994  tree = tree->cdr;
995  }
996  }
997 }
998 
999 static void
1000 raise_error(codegen_scope *s, const char *msg)
1001 {
1002  int idx = new_lit(s, mrb_str_new_cstr(s->mrb, msg));
1003 
1004  genop(s, MKOP_ABx(OP_ERR, 1, idx));
1005 }
1006 
1007 static double
1008 readint_float(codegen_scope *s, const char *p, int base)
1009 {
1010  const char *e = p + strlen(p);
1011  double f = 0;
1012  int n;
1013 
1014  if (*p == '+') p++;
1015  while (p < e) {
1016  char c = *p;
1017  c = tolower((unsigned char)c);
1018  for (n=0; n<base; n++) {
1019  if (mrb_digitmap[n] == c) {
1020  f *= base;
1021  f += n;
1022  break;
1023  }
1024  }
1025  if (n == base) {
1026  codegen_error(s, "malformed readint input");
1027  }
1028  p++;
1029  }
1030  return f;
1031 }
1032 
1033 static mrb_int
1034 readint_mrb_int(codegen_scope *s, const char *p, int base, int neg, int *overflow)
1035 {
1036  const char *e = p + strlen(p);
1037  mrb_int result = 0;
1038  int n;
1039 
1040  if (*p == '+') p++;
1041  while (p < e) {
1042  char c = *p;
1043  c = tolower((unsigned char)c);
1044  for (n=0; n<base; n++) {
1045  if (mrb_digitmap[n] == c) {
1046  break;
1047  }
1048  }
1049  if (n == base) {
1050  codegen_error(s, "malformed readint input");
1051  }
1052 
1053  if (neg) {
1054  if ((MRB_INT_MIN + n)/base > result) {
1055  *overflow = TRUE;
1056  return 0;
1057  }
1058  result *= base;
1059  result -= n;
1060  }
1061  else {
1062  if ((MRB_INT_MAX - n)/base < result) {
1063  *overflow = TRUE;
1064  return 0;
1065  }
1066  result *= base;
1067  result += n;
1068  }
1069  p++;
1070  }
1071  *overflow = FALSE;
1072  return result;
1073 }
1074 
1075 static void
1076 codegen(codegen_scope *s, node *tree, int val)
1077 {
1078  int nt;
1079 
1080  if (!tree) return;
1081 
1082  if (s->irep && s->pc > 0 && s->filename_index != tree->filename_index) {
1085  s->debug_start_pos = s->pc;
1086  s->filename_index = tree->filename_index;
1088  }
1089 
1090  nt = (intptr_t)tree->car;
1091  s->lineno = tree->lineno;
1092  tree = tree->cdr;
1093  switch (nt) {
1094  case NODE_BEGIN:
1095  if (val && !tree) {
1096  genop(s, MKOP_A(OP_LOADNIL, cursp()));
1097  push();
1098  }
1099  while (tree) {
1100  codegen(s, tree->car, tree->cdr ? NOVAL : val);
1101  tree = tree->cdr;
1102  }
1103  break;
1104 
1105  case NODE_RESCUE:
1106  {
1107  int onerr, noexc, exend, pos1, pos2, tmp;
1108  struct loopinfo *lp;
1109 
1110  onerr = new_label(s);
1111  genop(s, MKOP_Bx(OP_ONERR, 0));
1112  lp = loop_push(s, LOOP_BEGIN);
1113  lp->pc1 = onerr;
1114  if (tree->car) {
1115  codegen(s, tree->car, val);
1116  if (val) pop();
1117  }
1118  lp->type = LOOP_RESCUE;
1119  noexc = new_label(s);
1120  genop(s, MKOP_Bx(OP_JMP, 0));
1121  dispatch(s, onerr);
1122  tree = tree->cdr;
1123  exend = 0;
1124  pos1 = 0;
1125  if (tree->car) {
1126  node *n2 = tree->car;
1127  int exc = cursp();
1128 
1129  genop(s, MKOP_A(OP_RESCUE, exc));
1130  push();
1131  while (n2) {
1132  node *n3 = n2->car;
1133  node *n4 = n3->car;
1134 
1135  if (pos1) dispatch(s, pos1);
1136  pos2 = 0;
1137  do {
1138  if (n4) {
1139  codegen(s, n4->car, VAL);
1140  }
1141  else {
1142  genop(s, MKOP_ABx(OP_GETCONST, cursp(), new_msym(s, mrb_intern2(s->mrb, "StandardError", 13))));
1143  push();
1144  }
1145  genop(s, MKOP_AB(OP_MOVE, cursp(), exc));
1146  pop();
1147  genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern2(s->mrb, "===", 3)), 1));
1148  tmp = new_label(s);
1149  genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
1150  pos2 = tmp;
1151  if (n4) {
1152  n4 = n4->cdr;
1153  }
1154  } while (n4);
1155  pos1 = new_label(s);
1156  genop(s, MKOP_sBx(OP_JMP, 0));
1157  dispatch_linked(s, pos2);
1158 
1159  pop();
1160  if (n3->cdr->car) {
1161  gen_assignment(s, n3->cdr->car, exc, NOVAL);
1162  }
1163  if (n3->cdr->cdr->car) {
1164  codegen(s, n3->cdr->cdr->car, val);
1165  if (val) pop();
1166  }
1167  tmp = new_label(s);
1168  genop(s, MKOP_sBx(OP_JMP, exend));
1169  exend = tmp;
1170  n2 = n2->cdr;
1171  push();
1172  }
1173  if (pos1) {
1174  dispatch(s, pos1);
1175  genop(s, MKOP_A(OP_RAISE, exc));
1176  }
1177  }
1178  pop();
1179  tree = tree->cdr;
1180  dispatch(s, noexc);
1181  genop(s, MKOP_A(OP_POPERR, 1));
1182  if (tree->car) {
1183  codegen(s, tree->car, val);
1184  }
1185  else if (val) {
1186  push();
1187  }
1188  dispatch_linked(s, exend);
1189  loop_pop(s, NOVAL);
1190  }
1191  break;
1192 
1193  case NODE_ENSURE:
1194  {
1195  int idx;
1196  int epush = s->pc;
1197 
1198  genop(s, MKOP_Bx(OP_EPUSH, 0));
1199  s->ensure_level++;
1200  codegen(s, tree->car, val);
1201  idx = scope_body(s, tree->cdr);
1202  s->iseq[epush] = MKOP_Bx(OP_EPUSH, idx);
1203  s->ensure_level--;
1204  genop_peep(s, MKOP_A(OP_EPOP, 1), NOVAL);
1205  }
1206  break;
1207 
1208  case NODE_LAMBDA:
1209  {
1210  int idx = lambda_body(s, tree, 1);
1211 
1212  genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_LAMBDA));
1213  push();
1214  }
1215  break;
1216 
1217  case NODE_BLOCK:
1218  {
1219  int idx = lambda_body(s, tree, 1);
1220 
1221  genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_BLOCK));
1222  push();
1223  }
1224  break;
1225 
1226  case NODE_IF:
1227  {
1228  int pos1, pos2;
1229  node *e = tree->cdr->cdr->car;
1230 
1231  codegen(s, tree->car, VAL);
1232  pop();
1233  pos1 = new_label(s);
1234  genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0));
1235 
1236  codegen(s, tree->cdr->car, val);
1237  if (val && !(tree->cdr->car)) {
1238  genop(s, MKOP_A(OP_LOADNIL, cursp()));
1239  push();
1240  }
1241  if (e) {
1242  if (val) pop();
1243  pos2 = new_label(s);
1244  genop(s, MKOP_sBx(OP_JMP, 0));
1245  dispatch(s, pos1);
1246  codegen(s, e, val);
1247  dispatch(s, pos2);
1248  }
1249  else {
1250  if (val) {
1251  pop();
1252  pos2 = new_label(s);
1253  genop(s, MKOP_sBx(OP_JMP, 0));
1254  dispatch(s, pos1);
1255  genop(s, MKOP_A(OP_LOADNIL, cursp()));
1256  dispatch(s, pos2);
1257  push();
1258  }
1259  else {
1260  dispatch(s, pos1);
1261  }
1262  }
1263  }
1264  break;
1265 
1266  case NODE_AND:
1267  {
1268  int pos;
1269 
1270  codegen(s, tree->car, VAL);
1271  pos = new_label(s);
1272  pop();
1273  genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0));
1274  codegen(s, tree->cdr, val);
1275  dispatch(s, pos);
1276  }
1277  break;
1278 
1279  case NODE_OR:
1280  {
1281  int pos;
1282 
1283  codegen(s, tree->car, VAL);
1284  pos = new_label(s);
1285  pop();
1286  genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0));
1287  codegen(s, tree->cdr, val);
1288  dispatch(s, pos);
1289  }
1290  break;
1291 
1292  case NODE_WHILE:
1293  {
1294  struct loopinfo *lp = loop_push(s, LOOP_NORMAL);
1295 
1296  lp->pc1 = new_label(s);
1297  genop(s, MKOP_sBx(OP_JMP, 0));
1298  lp->pc2 = new_label(s);
1299  codegen(s, tree->cdr, NOVAL);
1300  dispatch(s, lp->pc1);
1301  codegen(s, tree->car, VAL);
1302  pop();
1303  genop(s, MKOP_AsBx(OP_JMPIF, cursp(), lp->pc2 - s->pc));
1304 
1305  loop_pop(s, val);
1306  }
1307  break;
1308 
1309  case NODE_UNTIL:
1310  {
1311  struct loopinfo *lp = loop_push(s, LOOP_NORMAL);
1312 
1313  lp->pc1 = new_label(s);
1314  genop(s, MKOP_sBx(OP_JMP, 0));
1315  lp->pc2 = new_label(s);
1316  codegen(s, tree->cdr, NOVAL);
1317  dispatch(s, lp->pc1);
1318  codegen(s, tree->car, VAL);
1319  pop();
1320  genop(s, MKOP_AsBx(OP_JMPNOT, cursp(), lp->pc2 - s->pc));
1321 
1322  loop_pop(s, val);
1323  }
1324  break;
1325 
1326  case NODE_FOR:
1327  for_body(s, tree);
1328  if (val) push();
1329  break;
1330 
1331  case NODE_CASE:
1332  {
1333  int head = 0;
1334  int pos1, pos2, pos3, tmp;
1335  node *n;
1336 
1337  pos3 = 0;
1338  if (tree->car) {
1339  head = cursp();
1340  codegen(s, tree->car, VAL);
1341  }
1342  tree = tree->cdr;
1343  while (tree) {
1344  n = tree->car->car;
1345  pos1 = pos2 = 0;
1346  while (n) {
1347  codegen(s, n->car, VAL);
1348  if (head) {
1349  genop(s, MKOP_AB(OP_MOVE, cursp(), head));
1350  pop();
1351  genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern2(s->mrb, "===", 3)), 1));
1352  }
1353  else {
1354  pop();
1355  }
1356  tmp = new_label(s);
1357  genop(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));
1358  pos2 = tmp;
1359  n = n->cdr;
1360  }
1361  if (tree->car->car) {
1362  pos1 = new_label(s);
1363  genop(s, MKOP_sBx(OP_JMP, 0));
1364  dispatch_linked(s, pos2);
1365  }
1366  codegen(s, tree->car->cdr, val);
1367  if (val) pop();
1368  tmp = new_label(s);
1369  genop(s, MKOP_sBx(OP_JMP, pos3));
1370  pos3 = tmp;
1371  if (pos1) dispatch(s, pos1);
1372  tree = tree->cdr;
1373  }
1374  if (val) {
1375  genop(s, MKOP_A(OP_LOADNIL, cursp()));
1376  push();
1377  }
1378  if (pos3) dispatch_linked(s, pos3);
1379  }
1380  break;
1381 
1382  case NODE_SCOPE:
1383  scope_body(s, tree);
1384  break;
1385 
1386  case NODE_FCALL:
1387  case NODE_CALL:
1388  gen_call(s, tree, 0, 0, val);
1389  break;
1390 
1391  case NODE_DOT2:
1392  codegen(s, tree->car, val);
1393  codegen(s, tree->cdr, val);
1394  if (val) {
1395  pop(); pop();
1396  genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), 0));
1397  push();
1398  }
1399  break;
1400 
1401  case NODE_DOT3:
1402  codegen(s, tree->car, val);
1403  codegen(s, tree->cdr, val);
1404  if (val) {
1405  pop(); pop();
1406  genop(s, MKOP_ABC(OP_RANGE, cursp(), cursp(), 1));
1407  push();
1408  }
1409  break;
1410 
1411  case NODE_COLON2:
1412  {
1413  int sym = new_sym(s, sym(tree->cdr));
1414 
1415  codegen(s, tree->car, VAL);
1416  pop();
1417  genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
1418  if (val) push();
1419  }
1420  break;
1421 
1422  case NODE_COLON3:
1423  {
1424  int sym = new_sym(s, sym(tree));
1425 
1426  genop(s, MKOP_A(OP_OCLASS, cursp()));
1427  genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
1428  if (val) push();
1429  }
1430  break;
1431 
1432  case NODE_ARRAY:
1433  {
1434  int n;
1435 
1436  n = gen_values(s, tree, val);
1437  if (n >= 0) {
1438  if (val) {
1439  pop_n(n);
1440  genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n));
1441  push();
1442  }
1443  }
1444  else if (val) {
1445  push();
1446  }
1447  }
1448  break;
1449 
1450  case NODE_HASH:
1451  {
1452  int len = 0;
1453 
1454  while (tree) {
1455  codegen(s, tree->car->car, val);
1456  codegen(s, tree->car->cdr, val);
1457  len++;
1458  tree = tree->cdr;
1459  }
1460  if (val) {
1461  pop_n(len*2);
1462  genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len));
1463  push();
1464  }
1465  }
1466  break;
1467 
1468  case NODE_SPLAT:
1469  codegen(s, tree, VAL);
1470  break;
1471 
1472  case NODE_ASGN:
1473  codegen(s, tree->cdr, VAL);
1474  pop();
1475  gen_assignment(s, tree->car, cursp(), val);
1476  break;
1477 
1478  case NODE_MASGN:
1479  {
1480  int len = 0, n = 0, post = 0;
1481  node *t = tree->cdr, *p;
1482  int rhs = cursp();
1483 
1484  if ((intptr_t)t->car == NODE_ARRAY && nosplat(t->cdr)) {
1485  // fixed rhs
1486  t = t->cdr;
1487  while (t) {
1488  codegen(s, t->car, VAL);
1489  len++;
1490  t = t->cdr;
1491  }
1492  tree = tree->car;
1493  if (tree->car) { /* pre */
1494  t = tree->car;
1495  n = 0;
1496  while (t) {
1497  gen_assignment(s, t->car, rhs+n, NOVAL);
1498  n++;
1499  t = t->cdr;
1500  }
1501  }
1502  t = tree->cdr;
1503  if (t) {
1504  if (t->cdr) { /* post count */
1505  p = t->cdr->car;
1506  while (p) {
1507  post++;
1508  p = p->cdr;
1509  }
1510  }
1511  if (t->car) { /* rest (len - pre - post) */
1512  int rn = len - post - n;
1513 
1514  genop(s, MKOP_ABC(OP_ARRAY, cursp(), rhs+n, rn));
1515  gen_assignment(s, t->car, cursp(), NOVAL);
1516  n += rn;
1517  }
1518  if (t->cdr && t->cdr->car) {
1519  t = t->cdr->car;
1520  while (n<len) {
1521  gen_assignment(s, t->car, rhs+n, NOVAL);
1522  t = t->cdr;
1523  n++;
1524  }
1525  }
1526  }
1527  pop_n(len);
1528  if (val) {
1529  genop(s, MKOP_ABC(OP_ARRAY, rhs, rhs, len));
1530  push();
1531  }
1532  }
1533  else {
1534  // variable rhs
1535  codegen(s, t, VAL);
1536  gen_vmassignment(s, tree->car, rhs, val);
1537  }
1538  }
1539  break;
1540 
1541  case NODE_OP_ASGN:
1542  {
1543  mrb_sym sym = sym(tree->cdr->car);
1544  size_t len;
1545  const char *name = mrb_sym2name_len(s->mrb, sym, &len);
1546  int idx;
1547 
1548  codegen(s, tree->car, VAL);
1549  if (len == 2 &&
1550  ((name[0] == '|' && name[1] == '|') ||
1551  (name[0] == '&' && name[1] == '&'))) {
1552  int pos;
1553 
1554  pop();
1555  pos = new_label(s);
1556  genop(s, MKOP_AsBx(name[0] == '|' ? OP_JMPIF : OP_JMPNOT, cursp(), 0));
1557  codegen(s, tree->cdr->cdr->car, VAL);
1558  pop();
1559  gen_assignment(s, tree->car, cursp(), val);
1560  dispatch(s, pos);
1561  break;
1562  }
1563  codegen(s, tree->cdr->cdr->car, VAL);
1564  pop(); pop();
1565 
1566  idx = new_msym(s, sym);
1567  if (len == 1 && name[0] == '+') {
1568  genop_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, 1), val);
1569  }
1570  else if (len == 1 && name[0] == '-') {
1571  genop_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, 1), val);
1572  }
1573  else if (len == 1 && name[0] == '*') {
1574  genop(s, MKOP_ABC(OP_MUL, cursp(), idx, 1));
1575  }
1576  else if (len == 1 && name[0] == '/') {
1577  genop(s, MKOP_ABC(OP_DIV, cursp(), idx, 1));
1578  }
1579  else if (len == 1 && name[0] == '<') {
1580  genop(s, MKOP_ABC(OP_LT, cursp(), idx, 1));
1581  }
1582  else if (len == 2 && name[0] == '<' && name[1] == '=') {
1583  genop(s, MKOP_ABC(OP_LE, cursp(), idx, 1));
1584  }
1585  else if (len == 1 && name[0] == '>') {
1586  genop(s, MKOP_ABC(OP_GT, cursp(), idx, 1));
1587  }
1588  else if (len == 2 && name[0] == '>' && name[1] == '=') {
1589  genop(s, MKOP_ABC(OP_GE, cursp(), idx, 1));
1590  }
1591  else {
1592  genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1));
1593  }
1594  }
1595  gen_assignment(s, tree->car, cursp(), val);
1596  break;
1597 
1598  case NODE_SUPER:
1599  {
1600  int n = 0, noop = 0, sendv = 0;
1601 
1602  push(); /* room for receiver */
1603  if (tree) {
1604  node *args = tree->car;
1605  if (args) {
1606  n = gen_values(s, args, VAL);
1607  if (n < 0) {
1608  n = noop = sendv = 1;
1609  push();
1610  }
1611  }
1612  }
1613  if (tree && tree->cdr) {
1614  codegen(s, tree->cdr, VAL);
1615  pop();
1616  }
1617  else {
1618  genop(s, MKOP_A(OP_LOADNIL, cursp()));
1619  }
1620  pop_n(n+1);
1621  if (sendv) n = CALL_MAXARGS;
1622  genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, n));
1623  if (val) push();
1624  }
1625  break;
1626 
1627  case NODE_ZSUPER:
1628  {
1629  codegen_scope *s2 = s;
1630  int lv = 0, ainfo = 0;
1631 
1632  push(); /* room for receiver */
1633  while (!s2->mscope) {
1634  lv++;
1635  s2 = s2->prev;
1636  if (!s2) break;
1637  }
1638  if (s2) ainfo = s2->ainfo;
1639  genop(s, MKOP_ABx(OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf)));
1640  if (tree && tree->cdr) {
1641  push();
1642  codegen(s, tree->cdr, VAL);
1643  pop_n(2);
1644  }
1645  pop();
1646  genop(s, MKOP_ABC(OP_SUPER, cursp(), 0, CALL_MAXARGS));
1647  if (val) push();
1648  }
1649  break;
1650 
1651  case NODE_RETURN:
1652  if (tree) {
1653  codegen(s, tree, VAL);
1654  pop();
1655  }
1656  else {
1657  genop(s, MKOP_A(OP_LOADNIL, cursp()));
1658  }
1659  if (s->loop) {
1660  genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_RETURN));
1661  }
1662  else {
1663  genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
1664  }
1665  if (val) push();
1666  break;
1667 
1668  case NODE_YIELD:
1669  {
1670  codegen_scope *s2 = s;
1671  int lv = 0, ainfo = 0;
1672  int n = 0, sendv = 0;
1673 
1674  while (!s2->mscope) {
1675  lv++;
1676  s2 = s2->prev;
1677  if (!s2) break;
1678  }
1679  if (s2) ainfo = s2->ainfo;
1680  genop(s, MKOP_ABx(OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf)));
1681  push();
1682  if (tree) {
1683  n = gen_values(s, tree, VAL);
1684  if (n < 0) {
1685  n = sendv = 1;
1686  push();
1687  }
1688  }
1689  pop_n(n+1);
1690  if (sendv) n = CALL_MAXARGS;
1691  genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern2(s->mrb, "call", 4)), n));
1692  if (val) push();
1693  }
1694  break;
1695 
1696  case NODE_BREAK:
1697  loop_break(s, tree);
1698  if (val) push();
1699  break;
1700 
1701  case NODE_NEXT:
1702  if (!s->loop) {
1703  raise_error(s, "unexpected next");
1704  }
1705  else if (s->loop->type == LOOP_NORMAL) {
1706  if (s->ensure_level > s->loop->ensure_level) {
1707  genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);
1708  }
1709  codegen(s, tree, NOVAL);
1710  genop(s, MKOP_sBx(OP_JMP, s->loop->pc1 - s->pc));
1711  }
1712  else {
1713  if (tree) {
1714  codegen(s, tree, VAL);
1715  pop();
1716  }
1717  else {
1718  genop(s, MKOP_A(OP_LOADNIL, cursp()));
1719  }
1720  genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);
1721  }
1722  if (val) push();
1723  break;
1724 
1725  case NODE_REDO:
1726  if (!s->loop) {
1727  raise_error(s, "unexpected redo");
1728  }
1729  else {
1730  if (s->ensure_level > s->loop->ensure_level) {
1731  genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);
1732  }
1733  genop(s, MKOP_sBx(OP_JMP, s->loop->pc2 - s->pc));
1734  }
1735  break;
1736 
1737  case NODE_RETRY:
1738  {
1739  const char *msg = "unexpected retry";
1740 
1741  if (!s->loop) {
1742  raise_error(s, msg);
1743  }
1744  else {
1745  struct loopinfo *lp = s->loop;
1746  int n = 0;
1747 
1748  while (lp && lp->type != LOOP_RESCUE) {
1749  if (lp->type == LOOP_BEGIN) {
1750  n++;
1751  }
1752  lp = lp->prev;
1753  }
1754  if (!lp) {
1755  raise_error(s, msg);
1756  }
1757  else {
1758  if (n > 0) {
1759  while (n--) {
1760  genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL);
1761  }
1762  }
1763  if (s->ensure_level > lp->ensure_level) {
1764  genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - lp->ensure_level), NOVAL);
1765  }
1766  genop(s, MKOP_sBx(OP_JMP, lp->pc1 - s->pc));
1767  }
1768  }
1769  }
1770  break;
1771 
1772  case NODE_LVAR:
1773  if (val) {
1774  int idx = lv_idx(s, sym(tree));
1775 
1776  if (idx > 0) {
1777  genop(s, MKOP_AB(OP_MOVE, cursp(), idx));
1778  }
1779  else {
1780  int lv = 0;
1781  codegen_scope *up = s->prev;
1782 
1783  while (up) {
1784  idx = lv_idx(up, sym(tree));
1785  if (idx > 0) {
1786  genop(s, MKOP_ABC(OP_GETUPVAR, cursp(), idx, lv));
1787  break;
1788  }
1789  lv++;
1790  up = up->prev;
1791  }
1792  }
1793  push();
1794  }
1795  break;
1796 
1797  case NODE_GVAR:
1798  {
1799  int sym = new_sym(s, sym(tree));
1800 
1801  genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
1802  push();
1803  }
1804  break;
1805 
1806  case NODE_IVAR:
1807  {
1808  int sym = new_sym(s, sym(tree));
1809 
1810  genop(s, MKOP_ABx(OP_GETIV, cursp(), sym));
1811  push();
1812  }
1813  break;
1814 
1815  case NODE_CVAR:
1816  {
1817  int sym = new_sym(s, sym(tree));
1818 
1819  genop(s, MKOP_ABx(OP_GETCV, cursp(), sym));
1820  push();
1821  }
1822  break;
1823 
1824  case NODE_CONST:
1825  {
1826  int sym = new_sym(s, sym(tree));
1827 
1828  genop(s, MKOP_ABx(OP_GETCONST, cursp(), sym));
1829  push();
1830  }
1831  break;
1832 
1833  case NODE_DEFINED:
1834  codegen(s, tree, VAL);
1835  break;
1836 
1837  case NODE_BACK_REF:
1838  {
1839  char buf[2] = { '$' };
1840  mrb_value str;
1841  int sym;
1842 
1843  buf[1] = (char)(intptr_t)tree;
1844  str = mrb_str_new(s->mrb, buf, 2);
1845  sym = new_sym(s, mrb_intern_str(s->mrb, str));
1846  genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
1847  push();
1848  }
1849  break;
1850 
1851  case NODE_NTH_REF:
1852  {
1853  int sym;
1854  mrb_state *mrb = s->mrb;
1855  mrb_value fix = mrb_fixnum_value((intptr_t)tree);
1856  mrb_value str = mrb_str_buf_new(mrb, 4);
1857 
1858  mrb_str_buf_cat(mrb, str, "$", 1);
1859  mrb_str_buf_append(mrb, str, mrb_fixnum_to_str(mrb, fix, 10));
1860  sym = new_sym(s, mrb_intern_str(mrb, str));
1861  genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));
1862  push();
1863  }
1864  break;
1865 
1866  case NODE_ARG:
1867  // should not happen
1868  break;
1869 
1870  case NODE_BLOCK_ARG:
1871  codegen(s, tree, VAL);
1872  break;
1873 
1874  case NODE_INT:
1875  if (val) {
1876  char *p = (char*)tree->car;
1877  int base = (intptr_t)tree->cdr->car;
1878  mrb_int i;
1879  mrb_code co;
1880  int overflow;
1881 
1882  i = readint_mrb_int(s, p, base, FALSE, &overflow);
1883  if (overflow) {
1884  double f = readint_float(s, p, base);
1885  int off = new_lit(s, mrb_float_value(s->mrb, f));
1886 
1887  genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
1888  }
1889  else {
1890  if (i < MAXARG_sBx && i > -MAXARG_sBx) {
1891  co = MKOP_AsBx(OP_LOADI, cursp(), i);
1892  }
1893  else {
1894  int off = new_lit(s, mrb_fixnum_value(i));
1895  co = MKOP_ABx(OP_LOADL, cursp(), off);
1896  }
1897  genop(s, co);
1898  }
1899  push();
1900  }
1901  break;
1902 
1903  case NODE_FLOAT:
1904  if (val) {
1905  char *p = (char*)tree;
1906  mrb_float f = str_to_mrb_float(p);
1907  int off = new_lit(s, mrb_float_value(s->mrb, f));
1908 
1909  genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
1910  push();
1911  }
1912  break;
1913 
1914  case NODE_NEGATE:
1915  {
1916  nt = (intptr_t)tree->car;
1917  tree = tree->cdr;
1918  switch (nt) {
1919  case NODE_FLOAT:
1920  {
1921  char *p = (char*)tree;
1922  mrb_float f = str_to_mrb_float(p);
1923  int off = new_lit(s, mrb_float_value(s->mrb, -f));
1924 
1925  genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
1926  push();
1927  }
1928  break;
1929 
1930  case NODE_INT:
1931  {
1932  char *p = (char*)tree->car;
1933  int base = (intptr_t)tree->cdr->car;
1934  mrb_int i;
1935  mrb_code co;
1936  int overflow;
1937 
1938  i = readint_mrb_int(s, p, base, TRUE, &overflow);
1939  if (overflow) {
1940  double f = readint_float(s, p, base);
1941  int off = new_lit(s, mrb_float_value(s->mrb, -f));
1942 
1943  genop(s, MKOP_ABx(OP_LOADL, cursp(), off));
1944  }
1945  else {
1946  if (i < MAXARG_sBx && i > -MAXARG_sBx) {
1947  co = MKOP_AsBx(OP_LOADI, cursp(), i);
1948  }
1949  else {
1950  int off = new_lit(s, mrb_fixnum_value(i));
1951  co = MKOP_ABx(OP_LOADL, cursp(), off);
1952  }
1953  genop(s, co);
1954  }
1955  push();
1956  }
1957  break;
1958 
1959  default:
1960  {
1961  int sym = new_msym(s, mrb_intern2(s->mrb, "-", 1));
1962 
1963  genop(s, MKOP_ABx(OP_LOADI, cursp(), 0));
1964  push();
1965  codegen(s, tree, VAL);
1966  pop(); pop();
1967  genop(s, MKOP_ABC(OP_SUB, cursp(), sym, 2));
1968  }
1969  break;
1970  }
1971  }
1972  break;
1973 
1974  case NODE_STR:
1975  if (val) {
1976  char *p = (char*)tree->car;
1977  size_t len = (intptr_t)tree->cdr;
1978  int ai = mrb_gc_arena_save(s->mrb);
1979  int off = new_lit(s, mrb_str_new(s->mrb, p, len));
1980 
1981  mrb_gc_arena_restore(s->mrb, ai);
1982  genop(s, MKOP_ABx(OP_STRING, cursp(), off));
1983  push();
1984  }
1985  break;
1986 
1987  case NODE_HEREDOC:
1988  tree = ((struct mrb_parser_heredoc_info *)tree)->doc;
1989  /* fall through */
1990  case NODE_DSTR:
1991  if (val) {
1992  node *n = tree;
1993 
1994  codegen(s, n->car, VAL);
1995  n = n->cdr;
1996  while (n) {
1997  codegen(s, n->car, VAL);
1998  pop(); pop();
1999  genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
2000  push();
2001  n = n->cdr;
2002  }
2003  }
2004  else {
2005  node *n = tree;
2006 
2007  while (n) {
2008  if ((intptr_t)n->car->car != NODE_STR) {
2009  codegen(s, n->car, NOVAL);
2010  }
2011  n = n->cdr;
2012  }
2013  }
2014  break;
2015 
2016  case NODE_WORDS:
2017  gen_literal_array(s, tree, FALSE, val);
2018  break;
2019 
2020  case NODE_SYMBOLS:
2021  gen_literal_array(s, tree, TRUE, val);
2022  break;
2023 
2024  case NODE_XSTR:
2025  if (val) {
2026  char *p = (char*)tree->car;
2027  size_t len = (intptr_t)tree->cdr;
2028  int ai = mrb_gc_arena_save(s->mrb);
2029  int sym = new_sym(s, mrb_intern2(s->mrb, "Kernel", 6));
2030  int off = new_lit(s, mrb_str_new(s->mrb, p, len));
2031 
2032  genop(s, MKOP_A(OP_OCLASS, cursp()));
2033  genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
2034  push();
2035  genop(s, MKOP_ABx(OP_STRING, cursp(), off));
2036  pop();
2037  sym = new_sym(s, mrb_intern2(s->mrb, "`", 1));
2038  genop(s, MKOP_ABC(OP_SEND, cursp(), sym, 1));
2039  mrb_gc_arena_restore(s->mrb, ai);
2040  push();
2041  }
2042  break;
2043 
2044  case NODE_REGX:
2045  if (val) {
2046  char *p1 = (char*)tree->car;
2047  char *p2 = (char*)tree->cdr;
2048  int ai = mrb_gc_arena_save(s->mrb);
2049  int sym = new_sym(s, mrb_intern2(s->mrb, REGEXP_CLASS, REGEXP_CLASS_CSTR_LEN));
2050  int off = new_lit(s, mrb_str_new(s->mrb, p1, strlen(p1)));
2051  int argc = 1;
2052 
2053  genop(s, MKOP_A(OP_OCLASS, cursp()));
2054  genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
2055  push();
2056  genop(s, MKOP_ABx(OP_STRING, cursp(), off));
2057  if (p2) {
2058  push();
2059  off = new_lit(s, mrb_str_new(s->mrb, p2, strlen(p2)));
2060  genop(s, MKOP_ABx(OP_STRING, cursp(), off));
2061  argc++;
2062  pop();
2063  }
2064  pop();
2065  sym = new_sym(s, mrb_intern2(s->mrb, "compile", 7));
2066  genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc));
2067  mrb_gc_arena_restore(s->mrb, ai);
2068  push();
2069  }
2070  break;
2071 
2072  case NODE_DREGX:
2073  if (val) {
2074  node *n = tree->car;
2075  int ai = mrb_gc_arena_save(s->mrb);
2076  int sym = new_sym(s, mrb_intern2(s->mrb, REGEXP_CLASS, REGEXP_CLASS_CSTR_LEN));
2077  int argc = 1;
2078  int off;
2079  char *p;
2080 
2081  genop(s, MKOP_A(OP_OCLASS, cursp()));
2082  genop(s, MKOP_ABx(OP_GETMCNST, cursp(), sym));
2083  push();
2084  codegen(s, n->car, VAL);
2085  n = n->cdr;
2086  while (n) {
2087  codegen(s, n->car, VAL);
2088  pop(); pop();
2089  genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
2090  push();
2091  n = n->cdr;
2092  }
2093  n = tree->cdr->cdr;
2094  if (n->car) {
2095  p = (char*)n->car;
2096  off = new_lit(s, mrb_str_new(s->mrb, p, strlen(p)));
2097  codegen(s, tree->car, VAL);
2098  genop(s, MKOP_ABx(OP_STRING, cursp(), off));
2099  pop();
2100  genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);
2101  }
2102  if (n->cdr) {
2103  char *p2 = (char*)n->cdr;
2104  int off;
2105 
2106  push();
2107  off = new_lit(s, mrb_str_new(s->mrb, p2, strlen(p2)));
2108  genop(s, MKOP_ABx(OP_STRING, cursp(), off));
2109  argc++;
2110  pop();
2111  }
2112  pop();
2113  sym = new_sym(s, mrb_intern2(s->mrb, "compile", 7));
2114  genop(s, MKOP_ABC(OP_SEND, cursp(), sym, argc));
2115  mrb_gc_arena_restore(s->mrb, ai);
2116  push();
2117  }
2118  else {
2119  node *n = tree->car;
2120 
2121  while (n) {
2122  if ((intptr_t)n->car->car != NODE_STR) {
2123  codegen(s, n->car, NOVAL);
2124  }
2125  n = n->cdr;
2126  }
2127  }
2128  break;
2129 
2130  case NODE_SYM:
2131  if (val) {
2132  int sym = new_sym(s, sym(tree));
2133 
2134  genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym));
2135  push();
2136  }
2137  break;
2138 
2139  case NODE_DSYM:
2140  codegen(s, tree, val);
2141  if (val) {
2142  gen_send_intern(s);
2143  }
2144  break;
2145 
2146  case NODE_SELF:
2147  if (val) {
2148  genop(s, MKOP_A(OP_LOADSELF, cursp()));
2149  push();
2150  }
2151  break;
2152 
2153  case NODE_NIL:
2154  if (val) {
2155  genop(s, MKOP_A(OP_LOADNIL, cursp()));
2156  push();
2157  }
2158  break;
2159 
2160  case NODE_TRUE:
2161  if (val) {
2162  genop(s, MKOP_A(OP_LOADT, cursp()));
2163  push();
2164  }
2165  break;
2166 
2167  case NODE_FALSE:
2168  if (val) {
2169  genop(s, MKOP_A(OP_LOADF, cursp()));
2170  push();
2171  }
2172  break;
2173 
2174  case NODE_ALIAS:
2175  {
2176  int a = new_msym(s, sym(tree->car));
2177  int b = new_msym(s, sym(tree->cdr));
2178  int c = new_msym(s, mrb_intern2(s->mrb, "alias_method", 12));
2179 
2180  genop(s, MKOP_A(OP_TCLASS, cursp()));
2181  push();
2182  genop(s, MKOP_ABx(OP_LOADSYM, cursp(), a));
2183  push();
2184  genop(s, MKOP_ABx(OP_LOADSYM, cursp(), b));
2185  push();
2186  genop(s, MKOP_A(OP_LOADNIL, cursp()));
2187  pop_n(3);
2188  genop(s, MKOP_ABC(OP_SEND, cursp(), c, 2));
2189  if (val) {
2190  push();
2191  }
2192  }
2193  break;
2194 
2195  case NODE_UNDEF:
2196  {
2197  int undef = new_msym(s, mrb_intern2(s->mrb, "undef_method", 12));
2198  int num = 0;
2199  node *t = tree;
2200 
2201  genop(s, MKOP_A(OP_TCLASS, cursp()));
2202  push();
2203  while (t) {
2204  int symbol = new_msym(s, sym(t->car));
2205  genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol));
2206  push();
2207  t = t->cdr;
2208  num++;
2209  }
2210  pop_n(num + 1);
2211  genop(s, MKOP_ABC(OP_SEND, cursp(), undef, num));
2212  if (val) {
2213  push();
2214  }
2215  }
2216  break;
2217 
2218  case NODE_CLASS:
2219  {
2220  int idx;
2221 
2222  if (tree->car->car == (node*)0) {
2223  genop(s, MKOP_A(OP_LOADNIL, cursp()));
2224  push();
2225  }
2226  else if (tree->car->car == (node*)1) {
2227  genop(s, MKOP_A(OP_OCLASS, cursp()));
2228  push();
2229  }
2230  else {
2231  codegen(s, tree->car->car, VAL);
2232  }
2233  if (tree->cdr->car) {
2234  codegen(s, tree->cdr->car, VAL);
2235  }
2236  else {
2237  genop(s, MKOP_A(OP_LOADNIL, cursp()));
2238  push();
2239  }
2240  pop(); pop();
2241  idx = new_msym(s, sym(tree->car->cdr));
2242  genop(s, MKOP_AB(OP_CLASS, cursp(), idx));
2243  idx = scope_body(s, tree->cdr->cdr->car);
2244  genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
2245  if (val) {
2246  push();
2247  }
2248  }
2249  break;
2250 
2251  case NODE_MODULE:
2252  {
2253  int idx;
2254 
2255  if (tree->car->car == (node*)0) {
2256  genop(s, MKOP_A(OP_LOADNIL, cursp()));
2257  push();
2258  }
2259  else if (tree->car->car == (node*)1) {
2260  genop(s, MKOP_A(OP_OCLASS, cursp()));
2261  push();
2262  }
2263  else {
2264  codegen(s, tree->car->car, VAL);
2265  }
2266  pop();
2267  idx = new_msym(s, sym(tree->car->cdr));
2268  genop(s, MKOP_AB(OP_MODULE, cursp(), idx));
2269  idx = scope_body(s, tree->cdr->car);
2270  genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
2271  if (val) {
2272  push();
2273  }
2274  }
2275  break;
2276 
2277  case NODE_SCLASS:
2278  {
2279  int idx;
2280 
2281  codegen(s, tree->car, VAL);
2282  pop();
2283  genop(s, MKOP_AB(OP_SCLASS, cursp(), cursp()));
2284  idx = scope_body(s, tree->cdr->car);
2285  genop(s, MKOP_ABx(OP_EXEC, cursp(), idx));
2286  if (val) {
2287  push();
2288  }
2289  }
2290  break;
2291 
2292  case NODE_DEF:
2293  {
2294  int sym = new_msym(s, sym(tree->car));
2295  int idx = lambda_body(s, tree->cdr, 0);
2296 
2297  genop(s, MKOP_A(OP_TCLASS, cursp()));
2298  push();
2299  genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_METHOD));
2300  pop();
2301  genop(s, MKOP_AB(OP_METHOD, cursp(), sym));
2302  if (val) {
2303  genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym));
2304  push();
2305  }
2306  }
2307  break;
2308 
2309  case NODE_SDEF:
2310  {
2311  node *recv = tree->car;
2312  int sym = new_msym(s, sym(tree->cdr->car));
2313  int idx = lambda_body(s, tree->cdr->cdr, 0);
2314 
2315  codegen(s, recv, VAL);
2316  pop();
2317  genop(s, MKOP_AB(OP_SCLASS, cursp(), cursp()));
2318  push();
2319  genop(s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_METHOD));
2320  pop();
2321  genop(s, MKOP_AB(OP_METHOD, cursp(), sym));
2322  if (val) {
2323  genop(s, MKOP_ABx(OP_LOADSYM, cursp(), sym));
2324  push();
2325  }
2326  }
2327  break;
2328 
2329  case NODE_POSTEXE:
2330  codegen(s, tree, NOVAL);
2331  break;
2332 
2333  default:
2334  break;
2335  }
2336 }
2337 
2338 static codegen_scope*
2339 scope_new(mrb_state *mrb, codegen_scope *prev, node *lv)
2340 {
2341  static const codegen_scope codegen_scope_zero = { 0 };
2342  mrb_pool *pool = mrb_pool_open(mrb);
2344 
2345  if (!p) return 0;
2346  *p = codegen_scope_zero;
2347  p->mrb = mrb;
2348  p->mpool = pool;
2349  if (!prev) return p;
2350  p->prev = prev;
2351  p->ainfo = -1;
2352  p->mscope = 0;
2353 
2354  p->irep = mrb_add_irep(mrb);
2355  p->idx = p->irep->idx;
2356 
2357  p->icapa = 1024;
2358  p->iseq = (mrb_code*)mrb_malloc(mrb, sizeof(mrb_code)*p->icapa);
2359 
2360  p->pcapa = 32;
2361  p->irep->pool = (mrb_value*)mrb_malloc(mrb, sizeof(mrb_value)*p->pcapa);
2362  p->irep->plen = 0;
2363 
2364  p->scapa = 256;
2365  p->irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*256);
2366  p->irep->slen = 0;
2367 
2368  p->lv = lv;
2369  p->sp += node_len(lv)+1; /* add self */
2370  p->nlocals = p->sp;
2371  p->ai = mrb_gc_arena_save(mrb);
2372 
2373  p->filename = prev->filename;
2374  if (p->filename) {
2375  p->lines = (uint16_t*)mrb_malloc(mrb, sizeof(short)*p->icapa);
2376  }
2377  p->lineno = prev->lineno;
2378 
2379  // debug setting
2380  p->debug_start_pos = 0;
2381  if(p->filename) {
2382  mrb_debug_info_alloc(mrb, p->irep);
2383  p->irep->filename = p->filename;
2384  p->irep->lines = p->lines;
2385  }
2386  else {
2387  p->irep->debug_info = NULL;
2388  }
2389  p->parser = prev->parser;
2390  p->filename_index = prev->filename_index;
2391 
2392  return p;
2393 }
2394 
2395 static void
2396 scope_finish(codegen_scope *s)
2397 {
2398  mrb_state *mrb = s->mrb;
2399  mrb_irep *irep = s->irep;
2400  size_t fname_len;
2401  char *fname;
2402 
2403  irep->flags = 0;
2404  if (s->iseq) {
2405  irep->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc);
2406  irep->ilen = s->pc;
2407  if (s->lines) {
2408  irep->lines = (uint16_t *)codegen_realloc(s, s->lines, sizeof(uint16_t)*s->pc);
2409  }
2410  else {
2411  irep->lines = 0;
2412  }
2413  }
2414  irep->pool = (mrb_value *)codegen_realloc(s, irep->pool, sizeof(mrb_value)*irep->plen);
2415  irep->syms = (mrb_sym *)codegen_realloc(s, irep->syms, sizeof(mrb_sym)*irep->slen);
2416  if (s->filename) {
2419 
2420  fname_len = strlen(s->filename);
2421  fname = codegen_malloc(s, fname_len + 1);
2422  memcpy(fname, s->filename, fname_len);
2423  fname[fname_len] = '\0';
2424  irep->filename = fname;
2425  }
2426 
2427  irep->nlocals = s->nlocals;
2428  irep->nregs = s->nregs;
2429 
2430  mrb_gc_arena_restore(mrb, s->ai);
2431  mrb_pool_close(s->mpool);
2432 }
2433 
2434 static struct loopinfo*
2435 loop_push(codegen_scope *s, enum looptype t)
2436 {
2437  struct loopinfo *p = (struct loopinfo *)codegen_palloc(s, sizeof(struct loopinfo));
2438 
2439  p->type = t;
2440  p->pc1 = p->pc2 = p->pc3 = 0;
2441  p->prev = s->loop;
2442  p->ensure_level = s->ensure_level;
2443  p->acc = cursp();
2444  s->loop = p;
2445 
2446  return p;
2447 }
2448 
2449 static void
2450 loop_break(codegen_scope *s, node *tree)
2451 {
2452  if (!s->loop) {
2453  codegen(s, tree, NOVAL);
2454  raise_error(s, "unexpected break");
2455  }
2456  else {
2457  struct loopinfo *loop;
2458 
2459  if (tree) {
2460  codegen(s, tree, VAL);
2461  pop();
2462  }
2463 
2464  loop = s->loop;
2465  while (loop->type == LOOP_BEGIN) {
2466  genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL);
2467  loop = loop->prev;
2468  }
2469  while (loop->type == LOOP_RESCUE) {
2470  loop = loop->prev;
2471  }
2472  if (loop->type == LOOP_NORMAL) {
2473  int tmp;
2474 
2475  if (s->ensure_level > s->loop->ensure_level) {
2476  genop_peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);
2477  }
2478  if (tree) {
2479  genop_peep(s, MKOP_AB(OP_MOVE, loop->acc, cursp()), NOVAL);
2480  }
2481  tmp = new_label(s);
2482  genop(s, MKOP_sBx(OP_JMP, loop->pc3));
2483  loop->pc3 = tmp;
2484  }
2485  else {
2486  genop(s, MKOP_AB(OP_RETURN, cursp(), OP_R_BREAK));
2487  }
2488  }
2489 }
2490 
2491 static void
2492 loop_pop(codegen_scope *s, int val)
2493 {
2494  if (val) {
2495  genop(s, MKOP_A(OP_LOADNIL, cursp()));
2496  }
2497  dispatch_linked(s, s->loop->pc3);
2498  s->loop = s->loop->prev;
2499  if (val) push();
2500 }
2501 
2502 static void
2503 codedump(mrb_state *mrb, int n)
2504 {
2505 #ifdef ENABLE_STDIO
2506  mrb_irep *irep = mrb->irep[n];
2507  uint32_t i;
2508  int ai;
2509  mrb_code c;
2510 
2511  if (!irep) return;
2512  printf("irep %d nregs=%d nlocals=%d pools=%d syms=%d\n", n,
2513  irep->nregs, irep->nlocals, (int)irep->plen, (int)irep->slen);
2514  for (i=0; i<irep->ilen; i++) {
2515  ai = mrb_gc_arena_save(mrb);
2516  printf("%03d ", i);
2517  c = irep->iseq[i];
2518  switch (GET_OPCODE(c)) {
2519  case OP_NOP:
2520  printf("OP_NOP\n");
2521  break;
2522  case OP_MOVE:
2523  printf("OP_MOVE\tR%d\tR%d\n", GETARG_A(c), GETARG_B(c));
2524  break;
2525  case OP_LOADL:
2526  printf("OP_LOADL\tR%d\tL(%d)\n", GETARG_A(c), GETARG_Bx(c));
2527  break;
2528  case OP_LOADI:
2529  printf("OP_LOADI\tR%d\t%d\n", GETARG_A(c), GETARG_sBx(c));
2530  break;
2531  case OP_LOADSYM:
2532  printf("OP_LOADSYM\tR%d\t:%s\n", GETARG_A(c),
2533  mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
2534  break;
2535  case OP_LOADNIL:
2536  printf("OP_LOADNIL\tR%d\n", GETARG_A(c));
2537  break;
2538  case OP_LOADSELF:
2539  printf("OP_LOADSELF\tR%d\n", GETARG_A(c));
2540  break;
2541  case OP_LOADT:
2542  printf("OP_LOADT\tR%d\n", GETARG_A(c));
2543  break;
2544  case OP_LOADF:
2545  printf("OP_LOADF\tR%d\n", GETARG_A(c));
2546  break;
2547  case OP_GETGLOBAL:
2548  printf("OP_GETGLOBAL\tR%d\t:%s\n", GETARG_A(c),
2549  mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
2550  break;
2551  case OP_SETGLOBAL:
2552  printf("OP_SETGLOBAL\t:%s\tR%d\n",
2553  mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
2554  GETARG_A(c));
2555  break;
2556  case OP_GETCONST:
2557  printf("OP_GETCONST\tR%d\t:%s\n", GETARG_A(c),
2558  mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
2559  break;
2560  case OP_SETCONST:
2561  printf("OP_SETCONST\t:%s\tR%d\n",
2562  mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
2563  GETARG_A(c));
2564  break;
2565  case OP_GETMCNST:
2566  printf("OP_GETMCNST\tR%d\tR%d::%s\n", GETARG_A(c), GETARG_A(c),
2567  mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
2568  break;
2569  case OP_SETMCNST:
2570  printf("OP_SETMCNST\tR%d::%s\tR%d\n", GETARG_A(c)+1,
2571  mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
2572  GETARG_A(c));
2573  break;
2574  case OP_GETIV:
2575  printf("OP_GETIV\tR%d\t%s\n", GETARG_A(c),
2576  mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
2577  break;
2578  case OP_SETIV:
2579  printf("OP_SETIV\t%s\tR%d\n",
2580  mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
2581  GETARG_A(c));
2582  break;
2583  case OP_GETUPVAR:
2584  printf("OP_GETUPVAR\tR%d\t%d\t%d\n",
2585  GETARG_A(c), GETARG_B(c), GETARG_C(c));
2586  break;
2587  case OP_SETUPVAR:
2588  printf("OP_SETUPVAR\tR%d\t%d\t%d\n",
2589  GETARG_A(c), GETARG_B(c), GETARG_C(c));
2590  break;
2591  case OP_GETCV:
2592  printf("OP_GETCV\tR%d\t%s\n", GETARG_A(c),
2593  mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]));
2594  break;
2595  case OP_SETCV:
2596  printf("OP_SETCV\t%s\tR%d\n",
2597  mrb_sym2name(mrb, irep->syms[GETARG_Bx(c)]),
2598  GETARG_A(c));
2599  break;
2600  case OP_JMP:
2601  printf("OP_JMP\t\t%03d\n", i+GETARG_sBx(c));
2602  break;
2603  case OP_JMPIF:
2604  printf("OP_JMPIF\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c));
2605  break;
2606  case OP_JMPNOT:
2607  printf("OP_JMPNOT\tR%d\t%03d\n", GETARG_A(c), i+GETARG_sBx(c));
2608  break;
2609  case OP_SEND:
2610  printf("OP_SEND\tR%d\t:%s\t%d\n", GETARG_A(c),
2611  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
2612  GETARG_C(c));
2613  break;
2614  case OP_SENDB:
2615  printf("OP_SENDB\tR%d\t:%s\t%d\n", GETARG_A(c),
2616  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
2617  GETARG_C(c));
2618  break;
2619  case OP_TAILCALL:
2620  printf("OP_TAILCALL\tR%d\t:%s\t%d\n", GETARG_A(c),
2621  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
2622  GETARG_C(c));
2623  break;
2624  case OP_SUPER:
2625  printf("OP_SUPER\tR%d\t%d\n", GETARG_A(c),
2626  GETARG_C(c));
2627  break;
2628  case OP_ARGARY:
2629  printf("OP_ARGARY\tR%d\t%d:%d:%d:%d\n", GETARG_A(c),
2630  (GETARG_Bx(c)>>10)&0x3f,
2631  (GETARG_Bx(c)>>9)&0x1,
2632  (GETARG_Bx(c)>>4)&0x1f,
2633  (GETARG_Bx(c)>>0)&0xf);
2634  break;
2635 
2636  case OP_ENTER:
2637  printf("OP_ENTER\t%d:%d:%d:%d:%d:%d:%d\n",
2638  (GETARG_Ax(c)>>18)&0x1f,
2639  (GETARG_Ax(c)>>13)&0x1f,
2640  (GETARG_Ax(c)>>12)&0x1,
2641  (GETARG_Ax(c)>>7)&0x1f,
2642  (GETARG_Ax(c)>>2)&0x1f,
2643  (GETARG_Ax(c)>>1)&0x1,
2644  GETARG_Ax(c) & 0x1);
2645  break;
2646  case OP_RETURN:
2647  printf("OP_RETURN\tR%d", GETARG_A(c));
2648  switch (GETARG_B(c)) {
2649  case OP_R_NORMAL:
2650  printf("\n"); break;
2651  case OP_R_RETURN:
2652  printf("\treturn\n"); break;
2653  case OP_R_BREAK:
2654  printf("\tbreak\n"); break;
2655  default:
2656  printf("\tbroken\n"); break;
2657  break;
2658  }
2659  break;
2660  case OP_BLKPUSH:
2661  printf("OP_BLKPUSH\tR%d\t%d:%d:%d:%d\n", GETARG_A(c),
2662  (GETARG_Bx(c)>>10)&0x3f,
2663  (GETARG_Bx(c)>>9)&0x1,
2664  (GETARG_Bx(c)>>4)&0x1f,
2665  (GETARG_Bx(c)>>0)&0xf);
2666  break;
2667 
2668  case OP_LAMBDA:
2669  printf("OP_LAMBDA\tR%d\tI(%+d)\t%d\n", GETARG_A(c), GETARG_b(c), GETARG_c(c));
2670  break;
2671  case OP_RANGE:
2672  printf("OP_RANGE\tR%d\tR%d\t%d\n", GETARG_A(c), GETARG_B(c), GETARG_C(c));
2673  break;
2674  case OP_METHOD:
2675  printf("OP_METHOD\tR%d\t:%s\n", GETARG_A(c),
2676  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
2677  break;
2678 
2679  case OP_ADD:
2680  printf("OP_ADD\tR%d\t:%s\t%d\n", GETARG_A(c),
2681  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
2682  GETARG_C(c));
2683  break;
2684  case OP_ADDI:
2685  printf("OP_ADDI\tR%d\t:%s\t%d\n", GETARG_A(c),
2686  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
2687  GETARG_C(c));
2688  break;
2689  case OP_SUB:
2690  printf("OP_SUB\tR%d\t:%s\t%d\n", GETARG_A(c),
2691  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
2692  GETARG_C(c));
2693  break;
2694  case OP_SUBI:
2695  printf("OP_SUBI\tR%d\t:%s\t%d\n", GETARG_A(c),
2696  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
2697  GETARG_C(c));
2698  break;
2699  case OP_MUL:
2700  printf("OP_MUL\tR%d\t:%s\t%d\n", GETARG_A(c),
2701  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
2702  GETARG_C(c));
2703  break;
2704  case OP_DIV:
2705  printf("OP_DIV\tR%d\t:%s\t%d\n", GETARG_A(c),
2706  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
2707  GETARG_C(c));
2708  break;
2709  case OP_LT:
2710  printf("OP_LT\tR%d\t:%s\t%d\n", GETARG_A(c),
2711  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
2712  GETARG_C(c));
2713  break;
2714  case OP_LE:
2715  printf("OP_LE\tR%d\t:%s\t%d\n", GETARG_A(c),
2716  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
2717  GETARG_C(c));
2718  break;
2719  case OP_GT:
2720  printf("OP_GT\tR%d\t:%s\t%d\n", GETARG_A(c),
2721  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
2722  GETARG_C(c));
2723  break;
2724  case OP_GE:
2725  printf("OP_GE\tR%d\t:%s\t%d\n", GETARG_A(c),
2726  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
2727  GETARG_C(c));
2728  break;
2729  case OP_EQ:
2730  printf("OP_EQ\tR%d\t:%s\t%d\n", GETARG_A(c),
2731  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]),
2732  GETARG_C(c));
2733  break;
2734 
2735  case OP_STOP:
2736  printf("OP_STOP\n");
2737  break;
2738 
2739  case OP_ARRAY:
2740  printf("OP_ARRAY\tR%d\tR%d\t%d\n", GETARG_A(c), GETARG_B(c), GETARG_C(c));
2741  break;
2742  case OP_ARYCAT:
2743  printf("OP_ARYCAT\tR%d\tR%d\n", GETARG_A(c), GETARG_B(c));
2744  break;
2745  case OP_ARYPUSH:
2746  printf("OP_ARYPUSH\tR%d\tR%d\n", GETARG_A(c), GETARG_B(c));
2747  break;
2748  case OP_AREF:
2749  printf("OP_AREF\tR%d\tR%d\t%d\n", GETARG_A(c), GETARG_B(c), GETARG_C(c));
2750  break;
2751  case OP_APOST:
2752  printf("OP_APOST\tR%d\t%d\t%d\n", GETARG_A(c), GETARG_B(c), GETARG_C(c));
2753  break;
2754  case OP_STRING:
2755  {
2756  mrb_value s = irep->pool[GETARG_Bx(c)];
2757 
2758  s = mrb_str_dump(mrb, s);
2759  printf("OP_STRING\tR%d\t%s\n", GETARG_A(c), RSTRING_PTR(s));
2760  }
2761  break;
2762  case OP_STRCAT:
2763  printf("OP_STRCAT\tR%d\tR%d\n", GETARG_A(c), GETARG_B(c));
2764  break;
2765  case OP_HASH:
2766  printf("OP_HASH\tR%d\tR%d\t%d\n", GETARG_A(c), GETARG_B(c), GETARG_C(c));
2767  break;
2768 
2769  case OP_OCLASS:
2770  printf("OP_OCLASS\tR%d\n", GETARG_A(c));
2771  break;
2772  case OP_CLASS:
2773  printf("OP_CLASS\tR%d\t:%s\n", GETARG_A(c),
2774  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
2775  break;
2776  case OP_MODULE:
2777  printf("OP_MODULE\tR%d\t:%s\n", GETARG_A(c),
2778  mrb_sym2name(mrb, irep->syms[GETARG_B(c)]));
2779  break;
2780  case OP_EXEC:
2781  printf("OP_EXEC\tR%d\tI(%d)\n", GETARG_A(c), n+GETARG_Bx(c));
2782  break;
2783  case OP_SCLASS:
2784  printf("OP_SCLASS\tR%d\tR%d\n", GETARG_A(c), GETARG_B(c));
2785  break;
2786  case OP_TCLASS:
2787  printf("OP_TCLASS\tR%d\n", GETARG_A(c));
2788  break;
2789  case OP_ERR:
2790  printf("OP_ERR\tL(%d)\n", GETARG_Bx(c));
2791  break;
2792  case OP_EPUSH:
2793  printf("OP_EPUSH\t:I(%d)\n", n+GETARG_Bx(c));
2794  break;
2795  case OP_ONERR:
2796  printf("OP_ONERR\t%03d\n", i+GETARG_sBx(c));
2797  break;
2798  case OP_RESCUE:
2799  printf("OP_RESCUE\tR%d\n", GETARG_A(c));
2800  break;
2801  case OP_RAISE:
2802  printf("OP_RAISE\tR%d\n", GETARG_A(c));
2803  break;
2804  case OP_POPERR:
2805  printf("OP_POPERR\t%d\n", GETARG_A(c));
2806  break;
2807  case OP_EPOP:
2808  printf("OP_EPOP\t%d\n", GETARG_A(c));
2809  break;
2810 
2811  default:
2812  printf("OP_unknown %d\t%d\t%d\t%d\n", GET_OPCODE(c),
2813  GETARG_A(c), GETARG_B(c), GETARG_C(c));
2814  break;
2815  }
2816  mrb_gc_arena_restore(mrb, ai);
2817  }
2818  printf("\n");
2819 #endif
2820 }
2821 
2822 void
2823 codedump_all(mrb_state *mrb, int start)
2824 {
2825  size_t i;
2826 
2827  for (i=start; i<mrb->irep_len; i++) {
2828  codedump(mrb, i);
2829  }
2830 }
2831 static int
2832 codegen_start(mrb_state *mrb, parser_state *p)
2833 {
2834  codegen_scope *scope = scope_new(mrb, 0, 0);
2835 
2836  if (!scope) {
2837  return -1;
2838  }
2839  scope->mrb = mrb;
2840  scope->parser = p;
2841  scope->filename = p->filename;
2843  if (setjmp(scope->jmp) == 0) {
2844  // prepare irep
2845  codegen(scope, p->tree, NOVAL);
2846  mrb_pool_close(scope->mpool);
2847  return 0;
2848  }
2849  else {
2850  return -1;
2851  }
2852 }
2853 
2854 int
2856 {
2857  int start = mrb->irep_len;
2858  int n;
2859 
2860  n = codegen_start(mrb, p);
2861  if (n < 0) return n;
2862 
2863  return start;
2864 }