- Timestamp:
- Jul 9, 2020, 8:51:43 AM (4 years ago)
- Location:
- EcnlProtoTool/trunk/mruby-2.1.1
- Files:
-
- 1 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
EcnlProtoTool/trunk/mruby-2.1.1/mrbgems/mruby-compiler/core/codegen.c
r331 r439 9 9 #include <stdlib.h> 10 10 #include <string.h> 11 #include <math.h> 11 12 #include <mruby.h> 12 13 #include <mruby/compile.h> … … 24 25 #endif 25 26 27 #define MAXARG_S (1<<16) 28 26 29 typedef mrb_ast_node node; 27 30 typedef struct mrb_parser_state parser_state; … … 37 40 struct loopinfo { 38 41 enum looptype type; 39 int pc 1, pc2, pc3, acc;42 int pc0, pc1, pc2, pc3, acc; 40 43 int ensure_level; 41 44 struct loopinfo *prev; … … 51 54 node *lv; 52 55 53 int sp; 54 int pc; 55 int lastlabel; 56 uint16_t sp; 57 uint16_t pc; 58 uint16_t lastpc; 59 uint16_t lastlabel; 56 60 int ainfo:15; 57 61 mrb_bool mscope:1; … … 59 63 struct loopinfo *loop; 60 64 int ensure_level; 61 char const *filename;65 mrb_sym filename_sym; 62 66 uint16_t lineno; 63 67 64 68 mrb_code *iseq; 65 69 uint16_t *lines; 66 int icapa;70 uint32_t icapa; 67 71 68 72 mrb_irep *irep; 69 size_t pcapa; 70 size_t scapa; 71 size_t rcapa; 73 uint32_t pcapa, scapa, rcapa; 72 74 73 75 uint16_t nlocals; … … 101 103 codegen_scope *tmp = s->prev; 102 104 mrb_free(s->mrb, s->iseq); 105 mrb_free(s->mrb, s->lines); 103 106 mrb_pool_close(s->mpool); 104 107 s = tmp; 105 108 } 106 109 #ifndef MRB_DISABLE_STDIO 107 if (s->filename && s->lineno) { 108 fprintf(stderr, "codegen error:%s:%d: %s\n", s->filename, s->lineno, message); 110 if (s->filename_sym && s->lineno) { 111 const char *filename = mrb_sym_name_len(s->mrb, s->filename_sym, NULL); 112 fprintf(stderr, "codegen error:%s:%d: %s\n", filename, s->lineno, message); 109 113 } 110 114 else { … … 125 129 126 130 static void* 127 codegen_malloc(codegen_scope *s, size_t len)128 {129 void *p = mrb_malloc_simple(s->mrb, len);130 131 if (!p) codegen_error(s, "mrb_malloc");132 return p;133 }134 135 static void*136 131 codegen_realloc(codegen_scope *s, void *p, size_t len) 137 132 { … … 145 140 new_label(codegen_scope *s) 146 141 { 147 s->lastlabel = s->pc; 148 return s->pc; 149 } 150 151 static inline int 152 genop(codegen_scope *s, mrb_code i) 153 { 154 if (s->pc == s->icapa) { 142 return s->lastlabel = s->pc; 143 } 144 145 static void 146 emit_B(codegen_scope *s, uint32_t pc, uint8_t i) 147 { 148 if (pc >= MAXARG_S || s->icapa >= MAXARG_S) { 149 codegen_error(s, "too big code block"); 150 } 151 if (pc >= s->icapa) { 155 152 s->icapa *= 2; 153 if (s->icapa > MAXARG_S) { 154 s->icapa = MAXARG_S; 155 } 156 156 s->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->icapa); 157 157 if (s->lines) { 158 s->lines = (uint16_t*)codegen_realloc(s, s->lines, sizeof(short)*s->icapa); 159 s->irep->lines = s->lines; 160 } 161 } 162 s->iseq[s->pc] = i; 158 s->lines = (uint16_t*)codegen_realloc(s, s->lines, sizeof(uint16_t)*s->icapa); 159 } 160 } 163 161 if (s->lines) { 164 s->lines[s->pc] = s->lineno; 165 } 166 return s->pc++; 162 if (s->lineno > 0 || pc == 0) 163 s->lines[pc] = s->lineno; 164 else 165 s->lines[pc] = s->lines[pc-1]; 166 } 167 s->iseq[pc] = i; 168 } 169 170 static void 171 emit_S(codegen_scope *s, int pc, uint16_t i) 172 { 173 uint8_t hi = i>>8; 174 uint8_t lo = i&0xff; 175 176 emit_B(s, pc, hi); 177 emit_B(s, pc+1, lo); 178 } 179 180 static void 181 gen_B(codegen_scope *s, uint8_t i) 182 { 183 emit_B(s, s->pc, i); 184 s->pc++; 185 } 186 187 static void 188 gen_S(codegen_scope *s, uint16_t i) 189 { 190 emit_S(s, s->pc, i); 191 s->pc += 2; 192 } 193 194 static void 195 genop_0(codegen_scope *s, mrb_code i) 196 { 197 s->lastpc = s->pc; 198 gen_B(s, i); 199 } 200 201 static void 202 genop_1(codegen_scope *s, mrb_code i, uint16_t a) 203 { 204 s->lastpc = s->pc; 205 if (a > 0xff) { 206 gen_B(s, OP_EXT1); 207 gen_B(s, i); 208 gen_S(s, a); 209 } 210 else { 211 gen_B(s, i); 212 gen_B(s, (uint8_t)a); 213 } 214 } 215 216 static void 217 genop_2(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b) 218 { 219 s->lastpc = s->pc; 220 if (a > 0xff && b > 0xff) { 221 gen_B(s, OP_EXT3); 222 gen_B(s, i); 223 gen_S(s, a); 224 gen_S(s, b); 225 } 226 else if (b > 0xff) { 227 gen_B(s, OP_EXT2); 228 gen_B(s, i); 229 gen_B(s, (uint8_t)a); 230 gen_S(s, b); 231 } 232 else if (a > 0xff) { 233 gen_B(s, OP_EXT1); 234 gen_B(s, i); 235 gen_S(s, a); 236 gen_B(s, (uint8_t)b); 237 } 238 else { 239 gen_B(s, i); 240 gen_B(s, (uint8_t)a); 241 gen_B(s, (uint8_t)b); 242 } 243 } 244 245 static void 246 genop_3(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b, uint8_t c) 247 { 248 genop_2(s, i, a, b); 249 gen_B(s, c); 250 } 251 252 static void 253 genop_2S(codegen_scope *s, mrb_code i, uint16_t a, uint16_t b) 254 { 255 genop_1(s, i, a); 256 gen_S(s, b); 257 } 258 259 static void 260 genop_W(codegen_scope *s, mrb_code i, uint32_t a) 261 { 262 uint8_t a1 = (a>>16) & 0xff; 263 uint8_t a2 = (a>>8) & 0xff; 264 uint8_t a3 = a & 0xff; 265 266 s->lastpc = s->pc; 267 gen_B(s, i); 268 gen_B(s, a1); 269 gen_B(s, a2); 270 gen_B(s, a3); 167 271 } 168 272 … … 178 282 } 179 283 180 static int 181 genop_peep(codegen_scope *s, mrb_code i, int val) 182 { 183 /* peephole optimization */ 184 if (!no_optimize(s) && s->lastlabel != s->pc && s->pc > 0) { 185 mrb_code i0 = s->iseq[s->pc-1]; 186 int c1 = GET_OPCODE(i); 187 int c0 = GET_OPCODE(i0); 188 189 switch (c1) { 284 static 285 mrb_bool 286 on_eval(codegen_scope *s) 287 { 288 if (s && s->parser && s->parser->on_eval) 289 return TRUE; 290 return FALSE; 291 } 292 293 struct mrb_insn_data 294 mrb_decode_insn(const mrb_code *pc) 295 { 296 struct mrb_insn_data data = { 0 }; 297 mrb_code insn = READ_B(); 298 uint16_t a = 0; 299 uint16_t b = 0; 300 uint8_t c = 0; 301 302 switch (insn) { 303 #define FETCH_Z() /* empty */ 304 #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x (); break; 305 #include "mruby/ops.h" 306 #undef OPCODE 307 } 308 switch (insn) { 309 case OP_EXT1: 310 insn = READ_B(); 311 switch (insn) { 312 #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _1 (); break; 313 #include "mruby/ops.h" 314 #undef OPCODE 315 } 316 break; 317 case OP_EXT2: 318 insn = READ_B(); 319 switch (insn) { 320 #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _2 (); break; 321 #include "mruby/ops.h" 322 #undef OPCODE 323 } 324 break; 325 case OP_EXT3: 326 insn = READ_B(); 327 switch (insn) { 328 #define OPCODE(i,x) case OP_ ## i: FETCH_ ## x ## _3 (); break; 329 #include "mruby/ops.h" 330 #undef OPCODE 331 } 332 break; 333 default: 334 break; 335 } 336 data.insn = insn; 337 data.a = a; 338 data.b = b; 339 data.c = c; 340 return data; 341 } 342 343 static struct mrb_insn_data 344 mrb_last_insn(codegen_scope *s) 345 { 346 if (s->pc == s->lastpc) { 347 struct mrb_insn_data data; 348 349 data.insn = OP_NOP; 350 return data; 351 } 352 return mrb_decode_insn(&s->iseq[s->lastpc]); 353 } 354 355 static mrb_bool 356 no_peephole(codegen_scope *s) 357 { 358 return no_optimize(s) || s->lastlabel == s->pc || s->pc == 0 || s->pc == s->lastpc; 359 } 360 361 static uint16_t 362 genjmp(codegen_scope *s, mrb_code i, uint16_t pc) 363 { 364 uint16_t pos; 365 366 s->lastpc = s->pc; 367 gen_B(s, i); 368 pos = s->pc; 369 gen_S(s, pc); 370 return pos; 371 } 372 373 static uint16_t 374 genjmp2(codegen_scope *s, mrb_code i, uint16_t a, int pc, int val) 375 { 376 uint16_t pos; 377 378 if (!no_peephole(s) && !val) { 379 struct mrb_insn_data data = mrb_last_insn(s); 380 381 if (data.insn == OP_MOVE && data.a == a) { 382 s->pc = s->lastpc; 383 a = data.b; 384 } 385 } 386 387 s->lastpc = s->pc; 388 if (a > 0xff) { 389 gen_B(s, OP_EXT1); 390 gen_B(s, i); 391 gen_S(s, a); 392 pos = s->pc; 393 gen_S(s, pc); 394 } 395 else { 396 gen_B(s, i); 397 gen_B(s, (uint8_t)a); 398 pos = s->pc; 399 gen_S(s, pc); 400 } 401 return pos; 402 } 403 404 static void 405 gen_move(codegen_scope *s, uint16_t dst, uint16_t src, int nopeep) 406 { 407 if (no_peephole(s)) { 408 normal: 409 genop_2(s, OP_MOVE, dst, src); 410 if (on_eval(s)) { 411 genop_0(s, OP_NOP); 412 } 413 return; 414 } 415 else { 416 struct mrb_insn_data data = mrb_last_insn(s); 417 418 switch (data.insn) { 190 419 case OP_MOVE: 191 if (GETARG_A(i) == GETARG_B(i)) { 192 /* skip useless OP_MOVE */ 193 return 0; 194 } 195 if (val) break; 196 switch (c0) { 197 case OP_MOVE: 198 if (GETARG_A(i) == GETARG_A(i0)) { 199 /* skip overriden OP_MOVE */ 200 s->pc--; 201 s->iseq[s->pc] = i; 202 } 203 if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i) == GETARG_B(i0)) { 204 /* skip swapping OP_MOVE */ 205 return 0; 206 } 207 if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { 208 s->pc--; 209 return genop_peep(s, MKOP_AB(OP_MOVE, GETARG_A(i), GETARG_B(i0)), val); 210 } 211 break; 212 case OP_LOADI: 213 if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { 214 s->iseq[s->pc-1] = MKOP_AsBx(OP_LOADI, GETARG_A(i), GETARG_sBx(i0)); 215 return 0; 216 } 217 break; 218 case OP_ARRAY: 219 case OP_HASH: 220 case OP_RANGE: 221 case OP_AREF: 222 case OP_GETUPVAR: 223 if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { 224 s->iseq[s->pc-1] = MKOP_ABC(c0, GETARG_A(i), GETARG_B(i0), GETARG_C(i0)); 225 return 0; 226 } 227 break; 228 case OP_LOADSYM: 229 case OP_GETGLOBAL: 230 case OP_GETIV: 231 case OP_GETCV: 232 case OP_GETCONST: 233 case OP_GETSPECIAL: 234 case OP_LOADL: 235 case OP_STRING: 236 if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { 237 s->iseq[s->pc-1] = MKOP_ABx(c0, GETARG_A(i), GETARG_Bx(i0)); 238 return 0; 239 } 240 break; 241 case OP_SCLASS: 242 if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { 243 s->iseq[s->pc-1] = MKOP_AB(c0, GETARG_A(i), GETARG_B(i0)); 244 return 0; 245 } 246 break; 247 case OP_LOADNIL: 248 case OP_LOADSELF: 249 case OP_LOADT: 250 case OP_LOADF: 251 case OP_OCLASS: 252 if (GETARG_B(i) == GETARG_A(i0) && GETARG_A(i0) >= s->nlocals) { 253 s->iseq[s->pc-1] = MKOP_A(c0, GETARG_A(i)); 254 return 0; 255 } 256 break; 257 default: 258 break; 259 } 420 if (dst == src) return; /* remove useless MOVE */ 421 if (data.b == dst && data.a == src) /* skip swapping MOVE */ 422 return; 423 goto normal; 424 case OP_LOADNIL: case OP_LOADSELF: case OP_LOADT: case OP_LOADF: 425 case OP_LOADI__1: 426 case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3: 427 case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7: 428 if (nopeep || data.a != src || data.a < s->nlocals) goto normal; 429 s->pc = s->lastpc; 430 genop_1(s, data.insn, dst); 260 431 break; 261 case OP_SETIV: 262 case OP_SETCV: 263 case OP_SETCONST: 264 case OP_SETMCNST: 265 case OP_SETGLOBAL: 266 if (val) break; 267 if (c0 == OP_MOVE) { 268 if (GETARG_A(i) == GETARG_A(i0)) { 269 s->iseq[s->pc-1] = MKOP_ABx(c1, GETARG_B(i0), GETARG_Bx(i)); 270 return 0; 271 } 272 } 273 break; 274 case OP_SETUPVAR: 275 if (val) break; 276 if (c0 == OP_MOVE) { 277 if (GETARG_A(i) == GETARG_A(i0)) { 278 s->iseq[s->pc-1] = MKOP_ABC(c1, GETARG_B(i0), GETARG_B(i), GETARG_C(i)); 279 return 0; 280 } 281 } 282 break; 283 case OP_EPOP: 284 if (c0 == OP_EPOP) { 285 s->iseq[s->pc-1] = MKOP_A(OP_EPOP, GETARG_A(i0)+GETARG_A(i)); 286 return 0; 287 } 288 break; 289 case OP_POPERR: 290 if (c0 == OP_POPERR) { 291 s->iseq[s->pc-1] = MKOP_A(OP_POPERR, GETARG_A(i0)+GETARG_A(i)); 292 return 0; 293 } 294 break; 295 case OP_RETURN: 296 switch (c0) { 297 case OP_RETURN: 298 return 0; 299 case OP_MOVE: 300 if (GETARG_A(i0) >= s->nlocals) { 301 s->iseq[s->pc-1] = MKOP_AB(OP_RETURN, GETARG_B(i0), OP_R_NORMAL); 302 return 0; 303 } 304 break; 305 case OP_SETIV: 306 case OP_SETCV: 307 case OP_SETCONST: 308 case OP_SETMCNST: 309 case OP_SETUPVAR: 310 case OP_SETGLOBAL: 311 s->pc--; 312 genop_peep(s, i0, NOVAL); 313 i0 = s->iseq[s->pc-1]; 314 return genop(s, MKOP_AB(OP_RETURN, GETARG_A(i0), OP_R_NORMAL)); 315 #if 0 316 case OP_SEND: 317 if (GETARG_B(i) == OP_R_NORMAL && GETARG_A(i) == GETARG_A(i0)) { 318 s->iseq[s->pc-1] = MKOP_ABC(OP_TAILCALL, GETARG_A(i0), GETARG_B(i0), GETARG_C(i0)); 319 return; 320 } 321 break; 322 #endif 323 default: 324 break; 325 } 326 break; 327 case OP_ADD: 328 case OP_SUB: 329 if (c0 == OP_LOADI) { 330 int c = GETARG_sBx(i0); 331 332 if (c1 == OP_SUB) c = -c; 333 if (c > 127 || c < -127) break; 334 if (0 <= c) 335 s->iseq[s->pc-1] = MKOP_ABC(OP_ADDI, GETARG_A(i), GETARG_B(i), c); 336 else 337 s->iseq[s->pc-1] = MKOP_ABC(OP_SUBI, GETARG_A(i), GETARG_B(i), -c); 338 return 0; 339 } 340 case OP_STRCAT: 341 if (c0 == OP_STRING) { 342 mrb_value v = s->irep->pool[GETARG_Bx(i0)]; 343 344 if (mrb_string_p(v) && RSTRING_LEN(v) == 0) { 345 s->pc--; 346 return 0; 347 } 348 } 349 if (c0 == OP_LOADNIL) { 350 if (GETARG_B(i) == GETARG_A(i0)) { 351 s->pc--; 352 return 0; 353 } 354 } 355 break; 356 case OP_JMPIF: 357 case OP_JMPNOT: 358 if (c0 == OP_MOVE && GETARG_A(i) == GETARG_A(i0)) { 359 s->iseq[s->pc-1] = MKOP_AsBx(c1, GETARG_B(i0), GETARG_sBx(i)); 360 return s->pc-1; 361 } 432 case OP_LOADI: case OP_LOADINEG: case OP_LOADL: case OP_LOADSYM: 433 case OP_GETGV: case OP_GETSV: case OP_GETIV: case OP_GETCV: 434 case OP_GETCONST: case OP_STRING: 435 case OP_LAMBDA: case OP_BLOCK: case OP_METHOD: case OP_BLKPUSH: 436 if (nopeep || data.a != src || data.a < s->nlocals) goto normal; 437 s->pc = s->lastpc; 438 genop_2(s, data.insn, dst, data.b); 362 439 break; 363 440 default: 441 goto normal; 442 } 443 } 444 } 445 446 static void 447 gen_return(codegen_scope *s, uint8_t op, uint16_t src) 448 { 449 if (no_peephole(s)) { 450 genop_1(s, op, src); 451 } 452 else { 453 struct mrb_insn_data data = mrb_last_insn(s); 454 455 if (data.insn == OP_MOVE && src == data.a) { 456 s->pc = s->lastpc; 457 genop_1(s, op, data.b); 458 } 459 else if (data.insn != OP_RETURN) { 460 genop_1(s, op, src); 461 } 462 } 463 } 464 465 static void 466 gen_addsub(codegen_scope *s, uint8_t op, uint16_t dst) 467 { 468 if (no_peephole(s)) { 469 normal: 470 genop_1(s, op, dst); 471 return; 472 } 473 else { 474 struct mrb_insn_data data = mrb_last_insn(s); 475 476 switch (data.insn) { 477 case OP_LOADI__1: 478 if (op == OP_ADD) op = OP_SUB; 479 else op = OP_ADD; 480 data.b = 1; 481 goto replace; 482 case OP_LOADI_0: case OP_LOADI_1: case OP_LOADI_2: case OP_LOADI_3: 483 case OP_LOADI_4: case OP_LOADI_5: case OP_LOADI_6: case OP_LOADI_7: 484 data.b = data.insn - OP_LOADI_0; 485 /* fall through */ 486 case OP_LOADI: 487 replace: 488 if (data.b >= 128) goto normal; 489 s->pc = s->lastpc; 490 if (op == OP_ADD) { 491 genop_2(s, OP_ADDI, dst, (uint8_t)data.b); 492 } 493 else { 494 genop_2(s, OP_SUBI, dst, (uint8_t)data.b); 495 } 364 496 break; 365 } 366 } 367 return genop(s, i); 497 default: 498 goto normal; 499 } 500 } 501 } 502 503 static int 504 dispatch(codegen_scope *s, uint16_t pos0) 505 { 506 uint16_t newpos; 507 508 s->lastlabel = s->pc; 509 newpos = PEEK_S(s->iseq+pos0); 510 emit_S(s, pos0, s->pc); 511 return newpos; 368 512 } 369 513 370 514 static void 371 scope_error(codegen_scope *s) 372 { 373 exit(EXIT_FAILURE); 374 } 375 376 static inline void 377 dispatch(codegen_scope *s, int pc) 378 { 379 int diff = s->pc - pc; 380 mrb_code i = s->iseq[pc]; 381 int c = GET_OPCODE(i); 382 383 s->lastlabel = s->pc; 384 switch (c) { 385 case OP_JMP: 386 case OP_JMPIF: 387 case OP_JMPNOT: 388 case OP_ONERR: 389 break; 390 default: 391 #ifndef MRB_DISABLE_STDIO 392 fprintf(stderr, "bug: dispatch on non JMP op\n"); 393 #endif 394 scope_error(s); 395 break; 396 } 397 if (diff > MAXARG_sBx) { 398 codegen_error(s, "too distant jump address"); 399 } 400 s->iseq[pc] = MKOP_AsBx(c, GETARG_A(i), diff); 401 } 402 403 static void 404 dispatch_linked(codegen_scope *s, int pc) 405 { 406 mrb_code i; 407 int pos; 408 409 if (!pc) return; 515 dispatch_linked(codegen_scope *s, uint16_t pos) 516 { 517 if (pos==0) return; 410 518 for (;;) { 411 i = s->iseq[pc]; 412 pos = GETARG_sBx(i); 413 dispatch(s, pc); 414 if (!pos) break; 415 pc = pos; 519 pos = dispatch(s, pos); 520 if (pos==0) break; 416 521 } 417 522 } … … 419 524 #define nregs_update do {if (s->sp > s->nregs) s->nregs = s->sp;} while (0) 420 525 static void 421 push_(codegen_scope *s) 422 { 423 if (s->sp > 511) { 424 codegen_error(s, "too complex expression"); 425 } 426 s->sp++; 427 nregs_update; 428 } 429 430 static void 431 push_n_(codegen_scope *s, size_t n) 432 { 433 if (s->sp+n > 511) { 526 push_n_(codegen_scope *s, int n) 527 { 528 if (s->sp+n >= 0xffff) { 434 529 codegen_error(s, "too complex expression"); 435 530 } … … 438 533 } 439 534 440 #define push() push_(s) 535 static void 536 pop_n_(codegen_scope *s, int n) 537 { 538 if ((int)s->sp-n < 0) { 539 codegen_error(s, "stack pointer underflow"); 540 } 541 s->sp-=n; 542 } 543 544 #define push() push_n_(s,1) 441 545 #define push_n(n) push_n_(s,n) 442 #define pop_(s) ((s)->sp--) 443 #define pop() pop_(s) 444 #define pop_n(n) (s->sp-=(n)) 546 #define pop() pop_n_(s,1) 547 #define pop_n(n) pop_n_(s,n) 445 548 #define cursp() (s->sp) 446 549 … … 448 551 new_lit(codegen_scope *s, mrb_value val) 449 552 { 450 size_t i;553 int i; 451 554 mrb_value *pv; 452 555 … … 457 560 pv = &s->irep->pool[i]; 458 561 459 if ( mrb_type(*pv) != MRB_TT_STRING) continue;562 if (!mrb_string_p(*pv)) continue; 460 563 if ((len = RSTRING_LEN(*pv)) != RSTRING_LEN(val)) continue; 461 564 if (memcmp(RSTRING_PTR(*pv), RSTRING_PTR(val), len) == 0) … … 463 566 } 464 567 break; 568 #ifndef MRB_WITHOUT_FLOAT 465 569 case MRB_TT_FLOAT: 466 570 for (i=0; i<s->irep->plen; i++) { 571 mrb_float f1, f2; 467 572 pv = &s->irep->pool[i]; 468 if (mrb_type(*pv) != MRB_TT_FLOAT) continue; 469 if (mrb_float(*pv) == mrb_float(val)) return i; 470 } 471 break; 573 if (!mrb_float_p(*pv)) continue; 574 f1 = mrb_float(*pv); 575 f2 = mrb_float(val); 576 if (f1 == f2 && !signbit(f1) == !signbit(f2)) return i; 577 } 578 break; 579 #endif 472 580 case MRB_TT_FIXNUM: 473 581 for (i=0; i<s->irep->plen; i++) { … … 492 600 switch (mrb_type(val)) { 493 601 case MRB_TT_STRING: 494 *pv = mrb_str_pool(s->mrb, val); 495 break; 496 602 *pv = mrb_str_pool(s->mrb, RSTRING_PTR(val), RSTRING_LEN(val), RSTR_NOFREE_P(RSTRING(val))); 603 break; 604 605 #ifndef MRB_WITHOUT_FLOAT 497 606 case MRB_TT_FLOAT: 498 607 #ifdef MRB_WORD_BOXING … … 500 609 break; 501 610 #endif 611 #endif 502 612 case MRB_TT_FIXNUM: 503 613 *pv = val; … … 511 621 } 512 622 513 /* method symbols should be fit in 9 bits */514 #define MAXMSYMLEN 512515 623 /* maximum symbol numbers */ 516 #define MAXSYMLEN 65536624 #define MAXSYMLEN 0x10000 517 625 518 626 static int 519 new_ msym(codegen_scope *s, mrb_sym sym)520 { 521 size_t i, len;627 new_sym(codegen_scope *s, mrb_sym sym) 628 { 629 int i, len; 522 630 523 631 mrb_assert(s->irep); 524 632 525 633 len = s->irep->slen; 526 if (len > MAXMSYMLEN) len = MAXMSYMLEN;527 634 for (i=0; i<len; i++) { 528 635 if (s->irep->syms[i] == sym) return i; 529 if (s->irep->syms[i] == 0) break; 530 } 531 if (i == MAXMSYMLEN) { 532 codegen_error(s, "too many symbols (max " MRB_STRINGIZE(MAXMSYMLEN) ")"); 533 } 534 s->irep->syms[i] = sym; 535 if (i == s->irep->slen) s->irep->slen++; 536 return i; 537 } 538 539 static int 540 new_sym(codegen_scope *s, mrb_sym sym) 541 { 542 size_t i; 543 544 for (i=0; i<s->irep->slen; i++) { 545 if (s->irep->syms[i] == sym) return i; 546 } 547 if (s->irep->slen == MAXSYMLEN) { 548 codegen_error(s, "too many symbols (max " MRB_STRINGIZE(MAXSYMLEN) ")"); 549 } 550 551 if (s->irep->slen > MAXMSYMLEN/2 && s->scapa == MAXMSYMLEN) { 552 s->scapa = MAXSYMLEN; 553 s->irep->syms = (mrb_sym *)codegen_realloc(s, s->irep->syms, sizeof(mrb_sym)*MAXSYMLEN); 554 for (i = s->irep->slen; i < MAXMSYMLEN; i++) { 555 static const mrb_sym mrb_sym_zero = { 0 }; 556 s->irep->syms[i] = mrb_sym_zero; 557 } 558 s->irep->slen = MAXMSYMLEN; 636 } 637 if (s->irep->slen >= s->scapa) { 638 s->scapa *= 2; 639 s->irep->syms = (mrb_sym*)codegen_realloc(s, s->irep->syms, sizeof(mrb_sym)*s->scapa); 559 640 } 560 641 s->irep->syms[s->irep->slen] = sym; … … 574 655 } 575 656 576 #define sym(x) ((mrb_sym)(intptr_t)(x)) 577 #define lv_name(lv) sym((lv)->car) 657 #define nint(x) ((int)(intptr_t)(x)) 658 #define nchar(x) ((char)(intptr_t)(x)) 659 #define nsym(x) ((mrb_sym)(intptr_t)(x)) 660 661 #define lv_name(lv) nsym((lv)->car) 662 578 663 static int 579 664 lv_idx(codegen_scope *s, mrb_sym id) … … 597 682 struct loopinfo *lp; 598 683 node *n2; 599 mrb_code c;600 684 601 685 /* generate receiver */ … … 603 687 /* generate loop-block */ 604 688 s = scope_new(s->mrb, s, NULL); 605 if (s == NULL) {606 raise_error(prev, "unexpected scope");607 }608 689 609 690 push(); /* push for a block parameter */ … … 611 692 /* generate loop variable */ 612 693 n2 = tree->car; 613 genop (s, MKOP_Ax(OP_ENTER, 0x40000));694 genop_W(s, OP_ENTER, 0x40000); 614 695 if (n2->car && !n2->car->cdr && !n2->cdr) { 615 696 gen_assignment(s, n2->car->car, 1, NOVAL); … … 625 706 codegen(s, tree->cdr->cdr->car, VAL); 626 707 pop(); 627 if (s->pc > 0) { 628 c = s->iseq[s->pc-1]; 629 if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel) 630 genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL); 631 } 708 gen_return(s, OP_RETURN, cursp()); 632 709 loop_pop(s, NOVAL); 633 710 scope_finish(s); 634 711 s = prev; 635 genop(s, MKOP_Abc(OP_LAMBDA, cursp(), s->irep->rlen-1, OP_L_BLOCK)); 712 genop_2(s, OP_BLOCK, cursp(), s->irep->rlen-1); 713 push();pop(); /* space for a block */ 636 714 pop(); 637 idx = new_ msym(s, mrb_intern_lit(s->mrb, "each"));638 genop (s, MKOP_ABC(OP_SENDB, cursp(), idx, 0));715 idx = new_sym(s, mrb_intern_lit(s->mrb, "each")); 716 genop_3(s, OP_SENDB, cursp(), idx, 0); 639 717 } 640 718 … … 642 720 lambda_body(codegen_scope *s, node *tree, int blk) 643 721 { 644 mrb_code c;645 722 codegen_scope *parent = s; 646 723 s = scope_new(s->mrb, s, tree->car); 647 if (s == NULL) {648 raise_error(parent, "unexpected scope");649 }650 724 651 725 s->mscope = !blk; … … 653 727 if (blk) { 654 728 struct loopinfo *lp = loop_push(s, LOOP_BLOCK); 655 lp->pc 1= new_label(s);729 lp->pc0 = new_label(s); 656 730 } 657 731 tree = tree->cdr; 658 if (tree->car) { 732 if (tree->car == NULL) { 733 genop_W(s, OP_ENTER, 0); 734 } 735 else { 659 736 mrb_aspec a; 660 737 int ma, oa, ra, pa, ka, kd, ba; 661 738 int pos, i; 662 node *n, *opt; 663 739 node *opt; 740 node *margs, *pargs; 741 node *tail; 742 743 /* mandatory arguments */ 664 744 ma = node_len(tree->car->car); 665 n= tree->car->car;666 while (n) {667 n = n->cdr; 668 }745 margs = tree->car->car; 746 tail = tree->car->cdr->cdr->cdr->cdr; 747 748 /* optional arguments */ 669 749 oa = node_len(tree->car->cdr->car); 750 /* rest argument? */ 670 751 ra = tree->car->cdr->cdr->car ? 1 : 0; 752 /* mandatory arugments after rest argument */ 671 753 pa = node_len(tree->car->cdr->cdr->cdr->car); 672 ka = kd = 0; 673 ba = tree->car->cdr->cdr->cdr->cdr ? 1 : 0; 754 pargs = tree->car->cdr->cdr->cdr->car; 755 /* keyword arguments */ 756 ka = tail? node_len(tail->cdr->car) : 0; 757 /* keyword dictionary? */ 758 kd = tail && tail->cdr->cdr->car? 1 : 0; 759 /* block argument? */ 760 ba = tail && tail->cdr->cdr->cdr->car ? 1 : 0; 674 761 675 762 if (ma > 0x1f || oa > 0x1f || pa > 0x1f || ka > 0x1f) { 676 763 codegen_error(s, "too many formal arguments"); 677 764 } 678 a = ((mrb_aspec)(ma & 0x1f) << 18) 679 | ((mrb_aspec)(oa & 0x1f) << 13) 680 | ((ra & 1) << 12) 681 | ((pa & 0x1f) << 7) 682 | ((ka & 0x1f) << 2) 683 | ((kd & 1)<< 1) 684 | (ba & 1); 685 s->ainfo = (((ma+oa) & 0x3f) << 6) /* (12bits = 6:1:5) */ 686 | ((ra & 1) << 5) 687 | (pa & 0x1f); 688 genop(s, MKOP_Ax(OP_ENTER, a)); 765 a = MRB_ARGS_REQ(ma) 766 | MRB_ARGS_OPT(oa) 767 | (ra? MRB_ARGS_REST() : 0) 768 | MRB_ARGS_POST(pa) 769 | MRB_ARGS_KEY(ka, kd) 770 | (ba? MRB_ARGS_BLOCK() : 0); 771 s->ainfo = (((ma+oa) & 0x3f) << 7) /* (12bits = 5:1:5:1) */ 772 | ((ra & 0x1) << 6) 773 | ((pa & 0x1f) << 1) 774 | ((ka | kd) != 0 ? 0x01 : 0x00); 775 genop_W(s, OP_ENTER, a); 776 /* generate jump table for optional arguments initializer */ 689 777 pos = new_label(s); 690 778 for (i=0; i<oa; i++) { 691 779 new_label(s); 692 gen op(s, MKOP_sBx(OP_JMP, 0));780 genjmp(s, OP_JMP, 0); 693 781 } 694 782 if (oa > 0) { 695 gen op(s, MKOP_sBx(OP_JMP, 0));783 genjmp(s, OP_JMP, 0); 696 784 } 697 785 opt = tree->car->cdr->car; … … 700 788 int idx; 701 789 702 dispatch(s, pos+i );790 dispatch(s, pos+i*3+1); 703 791 codegen(s, opt->car->cdr, VAL); 704 idx = lv_idx(s, (mrb_sym)(intptr_t)opt->car->car);705 792 pop(); 706 genop_peep(s, MKOP_AB(OP_MOVE, idx, cursp()), NOVAL); 793 idx = lv_idx(s, nsym(opt->car->car)); 794 gen_move(s, idx, cursp(), 0); 707 795 i++; 708 796 opt = opt->cdr; 709 797 } 710 798 if (oa > 0) { 711 dispatch(s, pos+i); 712 } 713 } 799 dispatch(s, pos+i*3+1); 800 } 801 802 /* keyword arguments */ 803 if (tail) { 804 node *kwds = tail->cdr->car; 805 int kwrest = 0; 806 807 if (tail->cdr->cdr->car) { 808 kwrest = 1; 809 } 810 mrb_assert(nint(tail->car) == NODE_ARGS_TAIL); 811 mrb_assert(node_len(tail) == 4); 812 813 while (kwds) { 814 int jmpif_key_p, jmp_def_set = -1; 815 node *kwd = kwds->car, *def_arg = kwd->cdr->cdr->car; 816 mrb_sym kwd_sym = nsym(kwd->cdr->car); 817 818 mrb_assert(nint(kwd->car) == NODE_KW_ARG); 819 820 if (def_arg) { 821 genop_2(s, OP_KEY_P, lv_idx(s, kwd_sym), new_sym(s, kwd_sym)); 822 jmpif_key_p = genjmp2(s, OP_JMPIF, lv_idx(s, kwd_sym), 0, 0); 823 codegen(s, def_arg, VAL); 824 pop(); 825 gen_move(s, lv_idx(s, kwd_sym), cursp(), 0); 826 jmp_def_set = genjmp(s, OP_JMP, 0); 827 dispatch(s, jmpif_key_p); 828 } 829 genop_2(s, OP_KARG, lv_idx(s, kwd_sym), new_sym(s, kwd_sym)); 830 if (jmp_def_set != -1) { 831 dispatch(s, jmp_def_set); 832 } 833 i++; 834 835 kwds = kwds->cdr; 836 } 837 if (tail->cdr->car && !kwrest) { 838 genop_0(s, OP_KEYEND); 839 } 840 } 841 842 /* argument destructuring */ 843 if (margs) { 844 node *n = margs; 845 846 pos = 1; 847 while (n) { 848 if (nint(n->car->car) == NODE_MASGN) { 849 gen_vmassignment(s, n->car->cdr->car, pos, NOVAL); 850 } 851 pos++; 852 n = n->cdr; 853 } 854 } 855 if (pargs) { 856 node *n = margs; 857 858 pos = ma+oa+ra+1; 859 while (n) { 860 if (nint(n->car->car) == NODE_MASGN) { 861 gen_vmassignment(s, n->car->cdr->car, pos, NOVAL); 862 } 863 pos++; 864 n = n->cdr; 865 } 866 } 867 } 868 714 869 codegen(s, tree->cdr->car, VAL); 715 870 pop(); 716 871 if (s->pc > 0) { 717 c = s->iseq[s->pc-1]; 718 if (GET_OPCODE(c) != OP_RETURN || GETARG_B(c) != OP_R_NORMAL || s->pc == s->lastlabel) { 719 if (s->nregs == 0) { 720 genop(s, MKOP_A(OP_LOADNIL, 0)); 721 genop(s, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); 722 } 723 else { 724 genop_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL); 725 } 726 } 872 gen_return(s, OP_RETURN, cursp()); 727 873 } 728 874 if (blk) { … … 737 883 { 738 884 codegen_scope *scope = scope_new(s->mrb, s, tree->car); 739 if (scope == NULL) {740 raise_error(s, "unexpected scope");741 }742 885 743 886 codegen(scope, tree->cdr, VAL); 887 gen_return(scope, OP_RETURN, scope->sp-1); 744 888 if (!s->iseq) { 745 genop(scope, MKOP_A(OP_STOP, 0)); 746 } 747 else if (!val) { 748 genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); 749 } 750 else { 751 if (scope->nregs == 0) { 752 genop(scope, MKOP_A(OP_LOADNIL, 0)); 753 genop(scope, MKOP_AB(OP_RETURN, 0, OP_R_NORMAL)); 754 } 755 else { 756 genop_peep(scope, MKOP_AB(OP_RETURN, scope->sp-1, OP_R_NORMAL), NOVAL); 757 } 889 genop_0(scope, OP_STOP); 758 890 } 759 891 scope_finish(scope); … … 769 901 { 770 902 while (t) { 771 if ( (intptr_t)t->car->car== NODE_SPLAT) return FALSE;903 if (nint(t->car->car) == NODE_SPLAT) return FALSE; 772 904 t = t->cdr; 773 905 } … … 782 914 char *name2; 783 915 784 name = mrb_sym 2name_len(s->mrb, a, &len);916 name = mrb_sym_name_len(s->mrb, a, &len); 785 917 name2 = (char *)codegen_palloc(s, 786 918 (size_t)len … … 805 937 806 938 while (t) { 807 is_splat = (intptr_t)t->car->car== NODE_SPLAT; /* splat mode */939 is_splat = nint(t->car->car) == NODE_SPLAT; /* splat mode */ 808 940 if ( 809 941 n+extra >= CALL_MAXARGS - 1 /* need to subtract one because vm.c expects an array if n == CALL_MAXARGS */ 810 942 || is_splat) { 811 943 if (val) { 812 if (is_splat && n == 0 && (intptr_t)t->car->cdr->car== NODE_ARRAY) {944 if (is_splat && n == 0 && nint(t->car->cdr->car) == NODE_ARRAY) { 813 945 codegen(s, t->car->cdr, VAL); 814 946 pop(); … … 816 948 else { 817 949 pop_n(n); 818 genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n)); 950 if (n == 0 && is_splat) { 951 genop_1(s, OP_LOADNIL, cursp()); 952 } 953 else { 954 genop_2(s, OP_ARRAY, cursp(), n); 955 } 819 956 push(); 820 957 codegen(s, t->car, VAL); 821 958 pop(); pop(); 822 959 if (is_splat) { 823 genop (s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));960 genop_1(s, OP_ARYCAT, cursp()); 824 961 } 825 962 else { 826 genop (s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));963 genop_1(s, OP_ARYPUSH, cursp()); 827 964 } 828 965 } … … 832 969 codegen(s, t->car, VAL); 833 970 pop(); pop(); 834 if ( (intptr_t)t->car->car== NODE_SPLAT) {835 genop (s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));971 if (nint(t->car->car) == NODE_SPLAT) { 972 genop_1(s, OP_ARYCAT, cursp()); 836 973 } 837 974 else { 838 genop (s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));975 genop_1(s, OP_ARYPUSH, cursp()); 839 976 } 840 977 t = t->cdr; … … 860 997 gen_call(codegen_scope *s, node *tree, mrb_sym name, int sp, int val, int safe) 861 998 { 862 mrb_sym sym = name ? name : sym(tree->cdr->car);863 int idx,skip = 0;999 mrb_sym sym = name ? name : nsym(tree->cdr->car); 1000 int skip = 0; 864 1001 int n = 0, noop = 0, sendv = 0, blk = 0; 865 1002 … … 867 1004 if (safe) { 868 1005 int recv = cursp()-1; 869 genop(s, MKOP_A(OP_LOADNIL, cursp())); 870 push(); 871 genop(s, MKOP_AB(OP_MOVE, cursp(), recv)); 872 push(); pop(); /* space for a block */ 873 pop(); 874 idx = new_msym(s, mrb_intern_lit(s->mrb, "==")); 875 genop(s, MKOP_ABC(OP_EQ, cursp(), idx, 1)); 876 skip = genop(s, MKOP_AsBx(OP_JMPIF, cursp(), 0)); 877 } 878 idx = new_msym(s, sym); 1006 gen_move(s, cursp(), recv, 1); 1007 skip = genjmp2(s, OP_JMPNIL, cursp(), 0, val); 1008 } 879 1009 tree = tree->cdr->cdr->car; 880 1010 if (tree) { … … 885 1015 } 886 1016 } 887 if (sp) { 1017 if (sp) { /* last argument pushed (attr=) */ 888 1018 if (sendv) { 1019 gen_move(s, cursp(), sp, 0); 889 1020 pop(); 890 genop (s, MKOP_AB(OP_ARYPUSH, cursp(), sp));1021 genop_1(s, OP_ARYPUSH, cursp()); 891 1022 push(); 892 1023 } 893 1024 else { 894 gen op(s, MKOP_AB(OP_MOVE, cursp(), sp));1025 gen_move(s, cursp(), sp, 0); 895 1026 push(); 896 1027 n++; … … 901 1032 codegen(s, tree->cdr, VAL); 902 1033 pop(); 903 } 904 else { 905 blk = cursp(); 1034 blk = 1; 906 1035 } 907 1036 push();pop(); … … 909 1038 { 910 1039 mrb_int symlen; 911 const char *symname = mrb_sym 2name_len(s->mrb, sym, &symlen);1040 const char *symname = mrb_sym_name_len(s->mrb, sym, &symlen); 912 1041 913 1042 if (!noop && symlen == 1 && symname[0] == '+' && n == 1) { 914 gen op_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, n), val);1043 gen_addsub(s, OP_ADD, cursp()); 915 1044 } 916 1045 else if (!noop && symlen == 1 && symname[0] == '-' && n == 1) { 917 gen op_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, n), val);1046 gen_addsub(s, OP_SUB, cursp()); 918 1047 } 919 1048 else if (!noop && symlen == 1 && symname[0] == '*' && n == 1) { 920 genop (s, MKOP_ABC(OP_MUL, cursp(), idx, n));1049 genop_1(s, OP_MUL, cursp()); 921 1050 } 922 1051 else if (!noop && symlen == 1 && symname[0] == '/' && n == 1) { 923 genop (s, MKOP_ABC(OP_DIV, cursp(), idx, n));1052 genop_1(s, OP_DIV, cursp()); 924 1053 } 925 1054 else if (!noop && symlen == 1 && symname[0] == '<' && n == 1) { 926 genop (s, MKOP_ABC(OP_LT, cursp(), idx, n));1055 genop_1(s, OP_LT, cursp()); 927 1056 } 928 1057 else if (!noop && symlen == 2 && symname[0] == '<' && symname[1] == '=' && n == 1) { 929 genop (s, MKOP_ABC(OP_LE, cursp(), idx, n));1058 genop_1(s, OP_LE, cursp()); 930 1059 } 931 1060 else if (!noop && symlen == 1 && symname[0] == '>' && n == 1) { 932 genop (s, MKOP_ABC(OP_GT, cursp(), idx, n));1061 genop_1(s, OP_GT, cursp()); 933 1062 } 934 1063 else if (!noop && symlen == 2 && symname[0] == '>' && symname[1] == '=' && n == 1) { 935 genop (s, MKOP_ABC(OP_GE, cursp(), idx, n));1064 genop_1(s, OP_GE, cursp()); 936 1065 } 937 1066 else if (!noop && symlen == 2 && symname[0] == '=' && symname[1] == '=' && n == 1) { 938 genop (s, MKOP_ABC(OP_EQ, cursp(), idx, n));1067 genop_1(s, OP_EQ, cursp()); 939 1068 } 940 1069 else { 941 if (sendv) n = CALL_MAXARGS; 942 if (blk > 0) { /* no block */ 943 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, n)); 1070 int idx = new_sym(s, sym); 1071 1072 if (sendv) { 1073 genop_2(s, blk ? OP_SENDVB : OP_SENDV, cursp(), idx); 944 1074 } 945 1075 else { 946 genop (s, MKOP_ABC(OP_SENDB, cursp(), idx, n));1076 genop_3(s, blk ? OP_SENDB : OP_SEND, cursp(), idx, n); 947 1077 } 948 1078 } … … 960 1090 { 961 1091 int idx; 962 int type = (intptr_t)tree->car;1092 int type = nint(tree->car); 963 1093 964 1094 tree = tree->cdr; 965 1095 switch (type) { 966 1096 case NODE_GVAR: 967 idx = new_sym(s, sym(tree)); 968 genop_peep(s, MKOP_ABx(OP_SETGLOBAL, sp, idx), val); 969 break; 1097 idx = new_sym(s, nsym(tree)); 1098 genop_2(s, OP_SETGV, sp, idx); 1099 break; 1100 case NODE_ARG: 970 1101 case NODE_LVAR: 971 idx = lv_idx(s, sym(tree));1102 idx = lv_idx(s, nsym(tree)); 972 1103 if (idx > 0) { 973 1104 if (idx != sp) { 974 genop_peep(s, MKOP_AB(OP_MOVE, idx, sp), val); 1105 gen_move(s, idx, sp, val); 1106 if (val && on_eval(s)) genop_0(s, OP_NOP); 975 1107 } 976 1108 break; … … 981 1113 982 1114 while (up) { 983 idx = lv_idx(up, sym(tree));1115 idx = lv_idx(up, nsym(tree)); 984 1116 if (idx > 0) { 985 genop_ peep(s, MKOP_ABC(OP_SETUPVAR, sp, idx, lv), val);1117 genop_3(s, OP_SETUPVAR, sp, idx, lv); 986 1118 break; 987 1119 } … … 991 1123 } 992 1124 break; 1125 case NODE_NVAR: 1126 idx = nint(tree); 1127 codegen_error(s, "Can't assign to numbered parameter"); 1128 break; 993 1129 case NODE_IVAR: 994 idx = new_sym(s, sym(tree));995 genop_ peep(s, MKOP_ABx(OP_SETIV, sp, idx), val);1130 idx = new_sym(s, nsym(tree)); 1131 genop_2(s, OP_SETIV, sp, idx); 996 1132 break; 997 1133 case NODE_CVAR: 998 idx = new_sym(s, sym(tree));999 genop_ peep(s, MKOP_ABx(OP_SETCV, sp, idx), val);1134 idx = new_sym(s, nsym(tree)); 1135 genop_2(s, OP_SETCV, sp, idx); 1000 1136 break; 1001 1137 case NODE_CONST: 1002 idx = new_sym(s, sym(tree));1003 genop_ peep(s, MKOP_ABx(OP_SETCONST, sp, idx), val);1138 idx = new_sym(s, nsym(tree)); 1139 genop_2(s, OP_SETCONST, sp, idx); 1004 1140 break; 1005 1141 case NODE_COLON2: 1006 idx = new_sym(s, sym(tree->cdr)); 1007 genop_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), NOVAL); 1142 gen_move(s, cursp(), sp, 0); 1008 1143 push(); 1009 1144 codegen(s, tree->car, VAL); 1010 1145 pop_n(2); 1011 genop_peep(s, MKOP_ABx(OP_SETMCNST, cursp(), idx), val); 1146 idx = new_sym(s, nsym(tree->cdr)); 1147 genop_2(s, OP_SETMCNST, sp, idx); 1012 1148 break; 1013 1149 … … 1015 1151 case NODE_SCALL: 1016 1152 push(); 1017 gen_call(s, tree, attrsym(s, sym(tree->cdr->car)), sp, NOVAL,1153 gen_call(s, tree, attrsym(s, nsym(tree->cdr->car)), sp, NOVAL, 1018 1154 type == NODE_SCALL); 1019 1155 pop(); 1020 1156 if (val) { 1021 gen op_peep(s, MKOP_AB(OP_MOVE, cursp(), sp), val);1157 gen_move(s, cursp(), sp, 0); 1022 1158 } 1023 1159 break; … … 1050 1186 n = 0; 1051 1187 while (t) { 1052 genop(s, MKOP_ABC(OP_AREF, cursp(), rhs, n)); 1053 gen_assignment(s, t->car, cursp(), NOVAL); 1188 int sp = cursp(); 1189 1190 genop_3(s, OP_AREF, sp, rhs, n); 1191 push(); 1192 gen_assignment(s, t->car, sp, NOVAL); 1193 pop(); 1054 1194 n++; 1055 1195 t = t->cdr; … … 1065 1205 } 1066 1206 } 1067 if (val) { 1068 genop(s, MKOP_AB(OP_MOVE, cursp(), rhs)); 1069 } 1070 else { 1071 pop(); 1072 } 1073 push_n(post); 1074 pop_n(post); 1075 genop(s, MKOP_ABC(OP_APOST, cursp(), n, post)); 1207 gen_move(s, cursp(), rhs, val); 1208 push_n(post+1); 1209 pop_n(post+1); 1210 genop_3(s, OP_APOST, cursp(), n, post); 1076 1211 n = 1; 1077 if (t->car ) {/* rest */1212 if (t->car && t->car != (node*)-1) { /* rest */ 1078 1213 gen_assignment(s, t->car, cursp(), NOVAL); 1079 1214 } … … 1086 1221 } 1087 1222 } 1088 if ( !val) {1089 push();1223 if (val) { 1224 gen_move(s, cursp(), rhs, 0); 1090 1225 } 1091 1226 } … … 1093 1228 1094 1229 static void 1095 gen_ send_intern(codegen_scope *s)1230 gen_intern(codegen_scope *s) 1096 1231 { 1097 1232 pop(); 1098 genop (s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "intern")), 0));1233 genop_1(s, OP_INTERN, cursp()); 1099 1234 push(); 1100 1235 } 1236 1101 1237 static void 1102 1238 gen_literal_array(codegen_scope *s, node *tree, mrb_bool sym, int val) … … 1106 1242 1107 1243 while (tree) { 1108 switch ( (intptr_t)tree->car->car) {1244 switch (nint(tree->car->car)) { 1109 1245 case NODE_STR: 1110 if ((tree->cdr == NULL) && ( (intptr_t)tree->car->cdr->cdr== 0))1246 if ((tree->cdr == NULL) && (nint(tree->car->cdr->cdr) == 0)) 1111 1247 break; 1112 1248 /* fall through */ … … 1121 1257 ++i; 1122 1258 if (sym) 1123 gen_ send_intern(s);1259 gen_intern(s); 1124 1260 } 1125 1261 break; 1126 1262 } 1127 if(j >= 2) {1263 while (j >= 2) { 1128 1264 pop(); pop(); 1129 genop_ peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);1265 genop_1(s, OP_STRCAT, cursp()); 1130 1266 push(); 1131 j = 1;1267 j--; 1132 1268 } 1133 1269 tree = tree->cdr; … … 1136 1272 ++i; 1137 1273 if (sym) 1138 gen_ send_intern(s);1274 gen_intern(s); 1139 1275 } 1140 1276 pop_n(i); 1141 genop (s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), i));1277 genop_2(s, OP_ARRAY, cursp(), i); 1142 1278 push(); 1143 1279 } 1144 1280 else { 1145 1281 while (tree) { 1146 switch ( (intptr_t)tree->car->car) {1282 switch (nint(tree->car->car)) { 1147 1283 case NODE_BEGIN: case NODE_BLOCK: 1148 1284 codegen(s, tree->car, NOVAL); … … 1158 1294 int idx = new_lit(s, mrb_str_new_cstr(s->mrb, msg)); 1159 1295 1160 genop(s, MKOP_ABx(OP_ERR, 1, idx)); 1161 } 1162 1296 genop_1(s, OP_ERR, idx); 1297 } 1298 1299 #ifndef MRB_WITHOUT_FLOAT 1163 1300 static double 1164 1301 readint_float(codegen_scope *s, const char *p, int base) … … 1186 1323 return f; 1187 1324 } 1325 #endif 1188 1326 1189 1327 static mrb_int … … 1233 1371 gen_retval(codegen_scope *s, node *tree) 1234 1372 { 1235 if ((intptr_t)tree->car == NODE_SPLAT) { 1236 genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), 0)); 1237 push(); 1373 if (nint(tree->car) == NODE_SPLAT) { 1238 1374 codegen(s, tree, VAL); 1239 pop(); pop();1240 genop (s, MKOP_AB(OP_ARYCAT, cursp(), cursp()+1));1375 pop(); 1376 genop_1(s, OP_ARYDUP, cursp()); 1241 1377 } 1242 1378 else { … … 1254 1390 if (!tree) { 1255 1391 if (val) { 1256 genop (s, MKOP_A(OP_LOADNIL, cursp()));1392 genop_1(s, OP_LOADNIL, cursp()); 1257 1393 push(); 1258 1394 } … … 1265 1401 } 1266 1402 if (s->irep && s->filename_index != tree->filename_index) { 1267 s->irep->filename = mrb_parser_get_filename(s->parser, s->filename_index); 1268 mrb_debug_info_append_file(s->mrb, s->irep, s->debug_start_pos, s->pc); 1403 mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index); 1404 const char *filename = mrb_sym_name_len(s->mrb, fname, NULL); 1405 1406 mrb_debug_info_append_file(s->mrb, s->irep->debug_info, 1407 filename, s->lines, s->debug_start_pos, s->pc); 1269 1408 s->debug_start_pos = s->pc; 1270 1409 s->filename_index = tree->filename_index; 1271 s->filename = mrb_parser_get_filename(s->parser, tree->filename_index);1272 } 1273 1274 nt = (intptr_t)tree->car;1410 s->filename_sym = mrb_parser_get_filename(s->parser, tree->filename_index); 1411 } 1412 1413 nt = nint(tree->car); 1275 1414 s->lineno = tree->lineno; 1276 1415 tree = tree->cdr; … … 1278 1417 case NODE_BEGIN: 1279 1418 if (val && !tree) { 1280 genop (s, MKOP_A(OP_LOADNIL, cursp()));1419 genop_1(s, OP_LOADNIL, cursp()); 1281 1420 push(); 1282 1421 } … … 1289 1428 case NODE_RESCUE: 1290 1429 { 1291 int onerr,noexc, exend, pos1, pos2, tmp;1430 int noexc, exend, pos1, pos2, tmp; 1292 1431 struct loopinfo *lp; 1293 1432 1294 1433 if (tree->car == NULL) goto exit; 1295 onerr = genop(s, MKOP_Bx(OP_ONERR, 0));1296 1434 lp = loop_push(s, LOOP_BEGIN); 1297 lp->pc1 = onerr; 1435 lp->pc0 = new_label(s); 1436 lp->pc1 = genjmp(s, OP_ONERR, 0); 1298 1437 codegen(s, tree->car, VAL); 1299 1438 pop(); 1300 1439 lp->type = LOOP_RESCUE; 1301 noexc = gen op(s, MKOP_Bx(OP_JMP, 0));1302 dispatch(s, onerr);1440 noexc = genjmp(s, OP_JMP, 0); 1441 dispatch(s, lp->pc1); 1303 1442 tree = tree->cdr; 1304 1443 exend = 0; … … 1308 1447 int exc = cursp(); 1309 1448 1310 genop (s, MKOP_ABC(OP_RESCUE, exc, 0, 0));1449 genop_1(s, OP_EXCEPT, exc); 1311 1450 push(); 1312 1451 while (n2) { … … 1317 1456 pos2 = 0; 1318 1457 do { 1319 if (n4 && n4->car && (intptr_t)n4->car->car== NODE_SPLAT) {1458 if (n4 && n4->car && nint(n4->car->car) == NODE_SPLAT) { 1320 1459 codegen(s, n4->car, VAL); 1321 genop(s, MKOP_AB(OP_MOVE, cursp(), exc)); 1460 gen_move(s, cursp(), exc, 0); 1461 push_n(2); pop_n(2); /* space for one arg and a block */ 1322 1462 pop(); 1323 genop (s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1));1463 genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1); 1324 1464 } 1325 1465 else { … … 1328 1468 } 1329 1469 else { 1330 genop (s, MKOP_ABx(OP_GETCONST, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "StandardError"))));1470 genop_2(s, OP_GETCONST, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "StandardError"))); 1331 1471 push(); 1332 1472 } 1333 1473 pop(); 1334 genop (s, MKOP_ABC(OP_RESCUE, exc, cursp(), 1));1474 genop_2(s, OP_RESCUE, exc, cursp()); 1335 1475 } 1336 tmp = gen op(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));1476 tmp = genjmp2(s, OP_JMPIF, cursp(), pos2, val); 1337 1477 pos2 = tmp; 1338 1478 if (n4) { … … 1340 1480 } 1341 1481 } while (n4); 1342 pos1 = gen op(s, MKOP_sBx(OP_JMP, 0));1482 pos1 = genjmp(s, OP_JMP, 0); 1343 1483 dispatch_linked(s, pos2); 1344 1484 … … 1351 1491 if (val) pop(); 1352 1492 } 1353 tmp = gen op(s, MKOP_sBx(OP_JMP, exend));1493 tmp = genjmp(s, OP_JMP, exend); 1354 1494 exend = tmp; 1355 1495 n2 = n2->cdr; … … 1358 1498 if (pos1) { 1359 1499 dispatch(s, pos1); 1360 genop (s, MKOP_A(OP_RAISE, exc));1500 genop_1(s, OP_RAISE, exc); 1361 1501 } 1362 1502 } … … 1364 1504 tree = tree->cdr; 1365 1505 dispatch(s, noexc); 1366 genop (s, MKOP_A(OP_POPERR, 1));1506 genop_1(s, OP_POPERR, 1); 1367 1507 if (tree->car) { 1368 1508 codegen(s, tree->car, val); … … 1378 1518 case NODE_ENSURE: 1379 1519 if (!tree->cdr || !tree->cdr->cdr || 1380 ( (intptr_t)tree->cdr->cdr->car== NODE_BEGIN &&1520 (nint(tree->cdr->cdr->car) == NODE_BEGIN && 1381 1521 tree->cdr->cdr->cdr)) { 1382 1522 int idx; 1383 int epush = s->pc; 1384 1385 genop(s, MKOP_Bx(OP_EPUSH, 0)); 1523 1386 1524 s->ensure_level++; 1525 idx = scope_body(s, tree->cdr, NOVAL); 1526 genop_1(s, OP_EPUSH, idx); 1387 1527 codegen(s, tree->car, val); 1388 idx = scope_body(s, tree->cdr, NOVAL);1389 s->iseq[epush] = MKOP_Bx(OP_EPUSH, idx);1390 1528 s->ensure_level--; 1391 genop_ peep(s, MKOP_A(OP_EPOP, 1), NOVAL);1529 genop_1(s, OP_EPOP, 1); 1392 1530 } 1393 1531 else { /* empty ensure ignored */ … … 1400 1538 int idx = lambda_body(s, tree, 1); 1401 1539 1402 genop (s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_LAMBDA));1540 genop_2(s, OP_LAMBDA, cursp(), idx); 1403 1541 push(); 1404 1542 } … … 1409 1547 int idx = lambda_body(s, tree, 1); 1410 1548 1411 genop (s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_BLOCK));1549 genop_2(s, OP_BLOCK, cursp(), idx); 1412 1550 push(); 1413 1551 } … … 1416 1554 case NODE_IF: 1417 1555 { 1418 int pos1, pos2 ;1419 node *e = tree->cdr->cdr->car;1556 int pos1, pos2, nil_p = FALSE; 1557 node *elsepart = tree->cdr->cdr->car; 1420 1558 1421 1559 if (!tree->car) { 1422 codegen(s, e , val);1560 codegen(s, elsepart, val); 1423 1561 goto exit; 1424 1562 } 1425 switch ( (intptr_t)tree->car->car) {1563 switch (nint(tree->car->car)) { 1426 1564 case NODE_TRUE: 1427 1565 case NODE_INT: … … 1431 1569 case NODE_FALSE: 1432 1570 case NODE_NIL: 1433 codegen(s, e , val);1571 codegen(s, elsepart, val); 1434 1572 goto exit; 1435 } 1436 codegen(s, tree->car, VAL); 1573 case NODE_CALL: 1574 { 1575 node *n = tree->car->cdr; 1576 mrb_sym mid = nsym(n->cdr->car); 1577 mrb_sym mnil = mrb_intern_lit(s->mrb, "nil?"); 1578 if (mid == mnil && n->cdr->cdr->car == NULL) { 1579 nil_p = TRUE; 1580 codegen(s, n->car, VAL); 1581 } 1582 } 1583 break; 1584 } 1585 if (!nil_p) { 1586 codegen(s, tree->car, VAL); 1587 } 1437 1588 pop(); 1438 pos1 = genop_peep(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0), NOVAL); 1439 1440 codegen(s, tree->cdr->car, val); 1441 if (e) { 1589 if (val || tree->cdr->car) { 1590 if (nil_p) { 1591 pos2 = genjmp2(s, OP_JMPNIL, cursp(), 0, val); 1592 pos1 = genjmp(s, OP_JMP, 0); 1593 dispatch(s, pos2); 1594 } 1595 else { 1596 pos1 = genjmp2(s, OP_JMPNOT, cursp(), 0, val); 1597 } 1598 codegen(s, tree->cdr->car, val); 1442 1599 if (val) pop(); 1443 pos2 = genop(s, MKOP_sBx(OP_JMP, 0)); 1444 dispatch(s, pos1); 1445 codegen(s, e, val); 1446 dispatch(s, pos2); 1447 } 1448 else { 1449 if (val) { 1450 pop(); 1451 pos2 = genop(s, MKOP_sBx(OP_JMP, 0)); 1600 if (elsepart || val) { 1601 pos2 = genjmp(s, OP_JMP, 0); 1452 1602 dispatch(s, pos1); 1453 genop(s, MKOP_A(OP_LOADNIL, cursp()));1603 codegen(s, elsepart, val); 1454 1604 dispatch(s, pos2); 1455 push();1456 1605 } 1457 1606 else { 1458 1607 dispatch(s, pos1); 1608 } 1609 } 1610 else { /* empty then-part */ 1611 if (elsepart) { 1612 if (nil_p) { 1613 pos1 = genjmp2(s, OP_JMPNIL, cursp(), 0, val); 1614 } 1615 else { 1616 pos1 = genjmp2(s, OP_JMPIF, cursp(), 0, val); 1617 } 1618 codegen(s, elsepart, val); 1619 dispatch(s, pos1); 1620 } 1621 else if (val && !nil_p) { 1622 genop_1(s, OP_LOADNIL, cursp()); 1623 push(); 1459 1624 } 1460 1625 } … … 1468 1633 codegen(s, tree->car, VAL); 1469 1634 pop(); 1470 pos = gen op(s, MKOP_AsBx(OP_JMPNOT, cursp(), 0));1635 pos = genjmp2(s, OP_JMPNOT, cursp(), 0, val); 1471 1636 codegen(s, tree->cdr, val); 1472 1637 dispatch(s, pos); … … 1480 1645 codegen(s, tree->car, VAL); 1481 1646 pop(); 1482 pos = gen op(s, MKOP_AsBx(OP_JMPIF, cursp(), 0));1647 pos = genjmp2(s, OP_JMPIF, cursp(), 0, val); 1483 1648 codegen(s, tree->cdr, val); 1484 1649 dispatch(s, pos); … … 1490 1655 struct loopinfo *lp = loop_push(s, LOOP_NORMAL); 1491 1656 1492 lp->pc1 = genop(s, MKOP_sBx(OP_JMP, 0)); 1657 lp->pc0 = new_label(s); 1658 lp->pc1 = genjmp(s, OP_JMP, 0); 1493 1659 lp->pc2 = new_label(s); 1494 1660 codegen(s, tree->cdr, NOVAL); … … 1496 1662 codegen(s, tree->car, VAL); 1497 1663 pop(); 1498 gen op(s, MKOP_AsBx(OP_JMPIF, cursp(), lp->pc2 - s->pc));1664 genjmp2(s, OP_JMPIF, cursp(), lp->pc2, NOVAL); 1499 1665 1500 1666 loop_pop(s, val); … … 1506 1672 struct loopinfo *lp = loop_push(s, LOOP_NORMAL); 1507 1673 1508 lp->pc1 = genop(s, MKOP_sBx(OP_JMP, 0)); 1674 lp->pc0 = new_label(s); 1675 lp->pc1 = genjmp(s, OP_JMP, 0); 1509 1676 lp->pc2 = new_label(s); 1510 1677 codegen(s, tree->cdr, NOVAL); … … 1512 1679 codegen(s, tree->car, VAL); 1513 1680 pop(); 1514 gen op(s, MKOP_AsBx(OP_JMPNOT, cursp(), lp->pc2 - s->pc));1681 genjmp2(s, OP_JMPNOT, cursp(), lp->pc2, NOVAL); 1515 1682 1516 1683 loop_pop(s, val); … … 1541 1708 codegen(s, n->car, VAL); 1542 1709 if (head) { 1543 gen op(s, MKOP_AB(OP_MOVE, cursp(), head));1544 p op();1545 if ( (intptr_t)n->car->car== NODE_SPLAT) {1546 genop (s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1));1710 gen_move(s, cursp(), head, 0); 1711 push(); push(); pop(); pop(); pop(); 1712 if (nint(n->car->car) == NODE_SPLAT) { 1713 genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "__case_eqq")), 1); 1547 1714 } 1548 1715 else { 1549 genop (s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "===")), 1));1716 genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "===")), 1); 1550 1717 } 1551 1718 } … … 1553 1720 pop(); 1554 1721 } 1555 tmp = gen op(s, MKOP_AsBx(OP_JMPIF, cursp(), pos2));1722 tmp = genjmp2(s, OP_JMPIF, cursp(), pos2, NOVAL); 1556 1723 pos2 = tmp; 1557 1724 n = n->cdr; 1558 1725 } 1559 1726 if (tree->car->car) { 1560 pos1 = gen op(s, MKOP_sBx(OP_JMP, 0));1727 pos1 = genjmp(s, OP_JMP, 0); 1561 1728 dispatch_linked(s, pos2); 1562 1729 } 1563 1730 codegen(s, tree->car->cdr, val); 1564 1731 if (val) pop(); 1565 tmp = gen op(s, MKOP_sBx(OP_JMP, pos3));1732 tmp = genjmp(s, OP_JMP, pos3); 1566 1733 pos3 = tmp; 1567 1734 if (pos1) dispatch(s, pos1); … … 1570 1737 if (val) { 1571 1738 int pos = cursp(); 1572 genop (s, MKOP_A(OP_LOADNIL, cursp()));1739 genop_1(s, OP_LOADNIL, cursp()); 1573 1740 if (pos3) dispatch_linked(s, pos3); 1574 1741 if (head) pop(); 1575 1742 if (cursp() != pos) { 1576 gen op(s, MKOP_AB(OP_MOVE, cursp(), pos));1743 gen_move(s, cursp(), pos, 0); 1577 1744 } 1578 1745 push(); … … 1606 1773 if (val) { 1607 1774 pop(); pop(); 1608 genop (s, MKOP_ABC(OP_RANGE, cursp(), cursp(), FALSE));1775 genop_1(s, OP_RANGE_INC, cursp()); 1609 1776 push(); 1610 1777 } … … 1616 1783 if (val) { 1617 1784 pop(); pop(); 1618 genop (s, MKOP_ABC(OP_RANGE, cursp(), cursp(), TRUE));1785 genop_1(s, OP_RANGE_EXC, cursp()); 1619 1786 push(); 1620 1787 } … … 1623 1790 case NODE_COLON2: 1624 1791 { 1625 int sym = new_sym(s, sym(tree->cdr));1792 int sym = new_sym(s, nsym(tree->cdr)); 1626 1793 1627 1794 codegen(s, tree->car, VAL); 1628 1795 pop(); 1629 genop (s, MKOP_ABx(OP_GETMCNST, cursp(), sym));1796 genop_2(s, OP_GETMCNST, cursp(), sym); 1630 1797 if (val) push(); 1631 1798 } … … 1634 1801 case NODE_COLON3: 1635 1802 { 1636 int sym = new_sym(s, sym(tree));1637 1638 genop (s, MKOP_A(OP_OCLASS, cursp()));1639 genop (s, MKOP_ABx(OP_GETMCNST, cursp(), sym));1803 int sym = new_sym(s, nsym(tree)); 1804 1805 genop_1(s, OP_OCLASS, cursp()); 1806 genop_2(s, OP_GETMCNST, cursp(), sym); 1640 1807 if (val) push(); 1641 1808 } … … 1650 1817 if (val) { 1651 1818 pop_n(n); 1652 genop (s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), n));1819 genop_2(s, OP_ARRAY, cursp(), n); 1653 1820 push(); 1654 1821 } … … 1661 1828 1662 1829 case NODE_HASH: 1830 case NODE_KW_HASH: 1663 1831 { 1664 1832 int len = 0; … … 1666 1834 1667 1835 while (tree) { 1668 codegen(s, tree->car->car, val); 1669 codegen(s, tree->car->cdr, val); 1670 len++; 1836 if (nint(tree->car->car->car) == NODE_KW_REST_ARGS) { 1837 if (len > 0) { 1838 pop_n(len*2); 1839 if (!update) { 1840 genop_2(s, OP_HASH, cursp(), len); 1841 } 1842 else { 1843 pop(); 1844 genop_2(s, OP_HASHADD, cursp(), len); 1845 } 1846 push(); 1847 } 1848 codegen(s, tree->car->cdr, VAL); 1849 if (len > 0 || update) { 1850 pop(); pop(); 1851 genop_1(s, OP_HASHCAT, cursp()); 1852 push(); 1853 } 1854 update = TRUE; 1855 len = 0; 1856 } 1857 else { 1858 codegen(s, tree->car->car, val); 1859 codegen(s, tree->car->cdr, val); 1860 len++; 1861 } 1671 1862 tree = tree->cdr; 1672 if (val && len == 126) {1863 if (val && len == 255) { 1673 1864 pop_n(len*2); 1674 genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len)); 1675 if (update) { 1865 if (!update) { 1866 genop_2(s, OP_HASH, cursp(), len); 1867 } 1868 else { 1676 1869 pop(); 1677 genop (s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__update")), 1));1870 genop_2(s, OP_HASHADD, cursp(), len); 1678 1871 } 1679 1872 push(); … … 1684 1877 if (val) { 1685 1878 pop_n(len*2); 1686 genop(s, MKOP_ABC(OP_HASH, cursp(), cursp(), len)); 1687 if (update) { 1879 if (!update) { 1880 genop_2(s, OP_HASH, cursp(), len); 1881 } 1882 else { 1688 1883 pop(); 1689 genop(s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "__update")), 1)); 1884 if (len > 0) { 1885 genop_2(s, OP_HASHADD, cursp(), len); 1886 } 1690 1887 } 1691 1888 push(); … … 1710 1907 int rhs = cursp(); 1711 1908 1712 if ( (intptr_t)t->car== NODE_ARRAY && t->cdr && nosplat(t->cdr)) {1909 if (nint(t->car) == NODE_ARRAY && t->cdr && nosplat(t->cdr)) { 1713 1910 /* fixed rhs */ 1714 1911 t = t->cdr; … … 1728 1925 } 1729 1926 else { 1730 genop (s, MKOP_A(OP_LOADNIL, rhs+n));1927 genop_1(s, OP_LOADNIL, rhs+n); 1731 1928 gen_assignment(s, t->car, rhs+n, NOVAL); 1732 1929 } … … 1752 1949 rn = len - post - n; 1753 1950 } 1754 genop (s, MKOP_ABC(OP_ARRAY, cursp(), rhs+n, rn));1951 genop_3(s, OP_ARRAY2, cursp(), rhs+n, rn); 1755 1952 gen_assignment(s, t->car, cursp(), NOVAL); 1756 1953 n += rn; … … 1767 1964 pop_n(len); 1768 1965 if (val) { 1769 genop (s, MKOP_ABC(OP_ARRAY, rhs, rhs, len));1966 genop_2(s, OP_ARRAY, rhs, len); 1770 1967 push(); 1771 1968 } … … 1784 1981 case NODE_OP_ASGN: 1785 1982 { 1786 mrb_sym sym = sym(tree->cdr->car);1983 mrb_sym sym = nsym(tree->cdr->car); 1787 1984 mrb_int len; 1788 const char *name = mrb_sym 2name_len(s->mrb, sym, &len);1985 const char *name = mrb_sym_name_len(s->mrb, sym, &len); 1789 1986 int idx, callargs = -1, vsp = -1; 1790 1987 1791 1988 if ((len == 2 && name[0] == '|' && name[1] == '|') && 1792 ( (intptr_t)tree->car->car== NODE_CONST ||1793 (intptr_t)tree->car->car== NODE_CVAR)) {1989 (nint(tree->car->car) == NODE_CONST || 1990 nint(tree->car->car) == NODE_CVAR)) { 1794 1991 int onerr, noexc, exc; 1795 1992 struct loopinfo *lp; 1796 1993 1797 onerr = gen op(s, MKOP_Bx(OP_ONERR, 0));1994 onerr = genjmp(s, OP_ONERR, 0); 1798 1995 lp = loop_push(s, LOOP_BEGIN); 1799 1996 lp->pc1 = onerr; … … 1801 1998 codegen(s, tree->car, VAL); 1802 1999 lp->type = LOOP_RESCUE; 1803 genop (s, MKOP_A(OP_POPERR, 1));1804 noexc = gen op(s, MKOP_Bx(OP_JMP, 0));2000 genop_1(s, OP_POPERR, 1); 2001 noexc = genjmp(s, OP_JMP, 0); 1805 2002 dispatch(s, onerr); 1806 genop (s, MKOP_ABC(OP_RESCUE, exc, 0, 0));1807 genop (s, MKOP_A(OP_LOADF, exc));2003 genop_1(s, OP_EXCEPT, exc); 2004 genop_1(s, OP_LOADF, exc); 1808 2005 dispatch(s, noexc); 1809 2006 loop_pop(s, NOVAL); 1810 2007 } 1811 else if ( (intptr_t)tree->car->car== NODE_CALL) {2008 else if (nint(tree->car->car) == NODE_CALL) { 1812 2009 node *n = tree->car->cdr; 2010 int base, i, nargs = 0; 2011 callargs = 0; 1813 2012 1814 2013 if (val) { … … 1817 2016 } 1818 2017 codegen(s, n->car, VAL); /* receiver */ 1819 idx = new_msym(s, sym(n->cdr->car)); 2018 idx = new_sym(s, nsym(n->cdr->car)); 2019 base = cursp()-1; 1820 2020 if (n->cdr->cdr->car) { 1821 int base = cursp()-1; 1822 int nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1); 1823 1824 /* copy receiver and arguments */ 2021 nargs = gen_values(s, n->cdr->cdr->car->car, VAL, 1); 1825 2022 if (nargs >= 0) { 1826 int i;1827 1828 genop(s, MKOP_AB(OP_MOVE, cursp(), base));1829 for (i=0; i<nargs; i++) {1830 genop(s, MKOP_AB(OP_MOVE, cursp()+i+1, base+i+1));1831 }1832 push_n(nargs+1);1833 pop_n(nargs+1);1834 2023 callargs = nargs; 1835 2024 } 1836 else { 1837 /* varargs */ 2025 else { /* varargs */ 1838 2026 push(); 1839 genop(s, MKOP_AB(OP_MOVE, cursp(), base)); 1840 genop(s, MKOP_AB(OP_MOVE, cursp()+1, base+1)); 2027 nargs = 1; 1841 2028 callargs = CALL_MAXARGS; 1842 2029 } 1843 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs)); 1844 } 1845 else { 1846 genop(s, MKOP_AB(OP_MOVE, cursp(), cursp()-1)); 1847 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 0)); 1848 callargs = 0; 1849 } 2030 } 2031 /* copy receiver and arguments */ 2032 gen_move(s, cursp(), base, 1); 2033 for (i=0; i<nargs; i++) { 2034 gen_move(s, cursp()+i+1, base+i+1, 1); 2035 } 2036 push_n(nargs+2);pop_n(nargs+2); /* space for receiver, arguments and a block */ 2037 genop_3(s, OP_SEND, cursp(), idx, callargs); 1850 2038 push(); 1851 2039 } … … 1861 2049 if (val) { 1862 2050 if (vsp >= 0) { 1863 gen op(s, MKOP_AB(OP_MOVE, vsp, cursp()));1864 } 1865 pos = gen op(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0));2051 gen_move(s, vsp, cursp(), 1); 2052 } 2053 pos = genjmp2(s, name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0, val); 1866 2054 } 1867 2055 else { 1868 pos = gen op_peep(s, MKOP_AsBx(name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0), NOVAL);2056 pos = genjmp2(s, name[0]=='|'?OP_JMPIF:OP_JMPNOT, cursp(), 0, val); 1869 2057 } 1870 2058 codegen(s, tree->cdr->cdr->car, VAL); 1871 2059 pop(); 1872 2060 if (val && vsp >= 0) { 1873 genop(s, MKOP_AB(OP_MOVE, vsp, cursp())); 1874 } 1875 if ((intptr_t)tree->car->car == NODE_CALL) { 1876 mrb_sym m = sym(tree->car->cdr->cdr->car); 1877 mrb_sym m2 = attrsym(s, m); 1878 1879 idx = new_msym(s, m2); 1880 pop(); 2061 gen_move(s, vsp, cursp(), 1); 2062 } 2063 if (nint(tree->car->car) == NODE_CALL) { 1881 2064 if (callargs == CALL_MAXARGS) { 1882 genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));1883 2065 pop(); 1884 genop (s, MKOP_ABC(OP_SEND, cursp(), idx, callargs));2066 genop_1(s, OP_ARYPUSH, cursp()); 1885 2067 } 1886 2068 else { 1887 2069 pop_n(callargs); 1888 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, callargs+1)); 1889 } 2070 callargs++; 2071 } 2072 pop(); 2073 idx = new_sym(s, attrsym(s, nsym(tree->car->cdr->cdr->car))); 2074 genop_3(s, OP_SEND, cursp(), idx, callargs); 1890 2075 } 1891 2076 else { … … 1899 2084 pop(); pop(); 1900 2085 1901 idx = new_msym(s, sym);1902 2086 if (len == 1 && name[0] == '+') { 1903 gen op_peep(s, MKOP_ABC(OP_ADD, cursp(), idx, 1), val);2087 gen_addsub(s, OP_ADD, cursp()); 1904 2088 } 1905 2089 else if (len == 1 && name[0] == '-') { 1906 gen op_peep(s, MKOP_ABC(OP_SUB, cursp(), idx, 1), val);2090 gen_addsub(s, OP_SUB, cursp()); 1907 2091 } 1908 2092 else if (len == 1 && name[0] == '*') { 1909 genop (s, MKOP_ABC(OP_MUL, cursp(), idx, 1));2093 genop_1(s, OP_MUL, cursp()); 1910 2094 } 1911 2095 else if (len == 1 && name[0] == '/') { 1912 genop (s, MKOP_ABC(OP_DIV, cursp(), idx, 1));2096 genop_1(s, OP_DIV, cursp()); 1913 2097 } 1914 2098 else if (len == 1 && name[0] == '<') { 1915 genop (s, MKOP_ABC(OP_LT, cursp(), idx, 1));2099 genop_1(s, OP_LT, cursp()); 1916 2100 } 1917 2101 else if (len == 2 && name[0] == '<' && name[1] == '=') { 1918 genop (s, MKOP_ABC(OP_LE, cursp(), idx, 1));2102 genop_1(s, OP_LE, cursp()); 1919 2103 } 1920 2104 else if (len == 1 && name[0] == '>') { 1921 genop (s, MKOP_ABC(OP_GT, cursp(), idx, 1));2105 genop_1(s, OP_GT, cursp()); 1922 2106 } 1923 2107 else if (len == 2 && name[0] == '>' && name[1] == '=') { 1924 genop (s, MKOP_ABC(OP_GE, cursp(), idx, 1));2108 genop_1(s, OP_GE, cursp()); 1925 2109 } 1926 2110 else { 1927 genop(s, MKOP_ABC(OP_SEND, cursp(), idx, 1)); 2111 idx = new_sym(s, sym); 2112 genop_3(s, OP_SEND, cursp(), idx, 1); 1928 2113 } 1929 2114 if (callargs < 0) { … … 1932 2117 else { 1933 2118 if (val && vsp >= 0) { 1934 gen op(s, MKOP_AB(OP_MOVE, vsp, cursp()));2119 gen_move(s, vsp, cursp(), 0); 1935 2120 } 1936 2121 if (callargs == CALL_MAXARGS) { 1937 2122 pop(); 1938 genop (s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1));2123 genop_1(s, OP_ARYPUSH, cursp()); 1939 2124 } 1940 2125 else { … … 1943 2128 } 1944 2129 pop(); 1945 idx = new_ msym(s, attrsym(s,sym(tree->car->cdr->cdr->car)));1946 genop (s, MKOP_ABC(OP_SEND, cursp(), idx, callargs));2130 idx = new_sym(s, attrsym(s,nsym(tree->car->cdr->cdr->car))); 2131 genop_3(s, OP_SEND, cursp(), idx, callargs); 1947 2132 } 1948 2133 } … … 1961 2146 if (!s2) break; 1962 2147 } 1963 genop (s, MKOP_ABx(OP_ARGARY, cursp(), (lv & 0xf)));2148 genop_2S(s, OP_ARGARY, cursp(), (lv & 0xf)); 1964 2149 push(); push(); /* ARGARY pushes two values */ 1965 2150 pop(); pop(); … … 1979 2164 } 1980 2165 else { 1981 genop (s, MKOP_A(OP_LOADNIL, cursp()));2166 genop_1(s, OP_LOADNIL, cursp()); 1982 2167 push(); pop(); 1983 2168 } 1984 2169 pop_n(n+1); 1985 2170 if (sendv) n = CALL_MAXARGS; 1986 genop (s, MKOP_ABC(OP_SUPER, cursp(), 0, n));2171 genop_2(s, OP_SUPER, cursp(), n); 1987 2172 if (val) push(); 1988 2173 } … … 2001 2186 } 2002 2187 if (s2) ainfo = s2->ainfo; 2003 genop (s, MKOP_ABx(OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf)));2188 genop_2S(s, OP_ARGARY, cursp(), (ainfo<<4)|(lv & 0xf)); 2004 2189 push(); push(); pop(); /* ARGARY pushes two values */ 2005 2190 if (tree && tree->cdr) { … … 2008 2193 } 2009 2194 pop(); pop(); 2010 genop (s, MKOP_ABC(OP_SUPER, cursp(), 0, CALL_MAXARGS));2195 genop_2(s, OP_SUPER, cursp(), CALL_MAXARGS); 2011 2196 if (val) push(); 2012 2197 } … … 2018 2203 } 2019 2204 else { 2020 genop (s, MKOP_A(OP_LOADNIL, cursp()));2205 genop_1(s, OP_LOADNIL, cursp()); 2021 2206 } 2022 2207 if (s->loop) { 2023 gen op(s, MKOP_AB(OP_RETURN, cursp(), OP_R_RETURN));2208 gen_return(s, OP_RETURN_BLK, cursp()); 2024 2209 } 2025 2210 else { 2026 gen op_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);2211 gen_return(s, OP_RETURN, cursp()); 2027 2212 } 2028 2213 if (val) push(); … … 2049 2234 } 2050 2235 } 2236 push();pop(); /* space for a block */ 2051 2237 pop_n(n+1); 2052 genop (s, MKOP_ABx(OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf)));2238 genop_2S(s, OP_BLKPUSH, cursp(), (ainfo<<4)|(lv & 0xf)); 2053 2239 if (sendv) n = CALL_MAXARGS; 2054 genop (s, MKOP_ABC(OP_SEND, cursp(), new_msym(s, mrb_intern_lit(s->mrb, "call")), n));2240 genop_3(s, OP_SEND, cursp(), new_sym(s, mrb_intern_lit(s->mrb, "call")), n); 2055 2241 if (val) push(); 2056 2242 } … … 2068 2254 else if (s->loop->type == LOOP_NORMAL) { 2069 2255 if (s->ensure_level > s->loop->ensure_level) { 2070 genop_ peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);2256 genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level); 2071 2257 } 2072 2258 codegen(s, tree, NOVAL); 2073 gen op(s, MKOP_sBx(OP_JMP, s->loop->pc1 - s->pc));2259 genjmp(s, OP_JMP, s->loop->pc0); 2074 2260 } 2075 2261 else { … … 2079 2265 } 2080 2266 else { 2081 genop (s, MKOP_A(OP_LOADNIL, cursp()));2082 } 2083 gen op_peep(s, MKOP_AB(OP_RETURN, cursp(), OP_R_NORMAL), NOVAL);2267 genop_1(s, OP_LOADNIL, cursp()); 2268 } 2269 gen_return(s, OP_RETURN, cursp()); 2084 2270 } 2085 2271 if (val) push(); … … 2092 2278 else { 2093 2279 if (s->ensure_level > s->loop->ensure_level) { 2094 genop_ peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);2095 } 2096 gen op(s, MKOP_sBx(OP_JMP, s->loop->pc2 - s->pc));2280 genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level); 2281 } 2282 genjmp(s, OP_JMP, s->loop->pc2); 2097 2283 } 2098 2284 if (val) push(); … … 2121 2307 else { 2122 2308 if (n > 0) { 2123 while (n--) { 2124 genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL); 2125 } 2309 genop_1(s, OP_POPERR, n); 2126 2310 } 2127 2311 if (s->ensure_level > lp->ensure_level) { 2128 genop_ peep(s, MKOP_A(OP_EPOP, s->ensure_level - lp->ensure_level), NOVAL);2129 } 2130 gen op(s, MKOP_sBx(OP_JMP, lp->pc1 - s->pc));2312 genop_1(s, OP_EPOP, s->ensure_level - lp->ensure_level); 2313 } 2314 genjmp(s, OP_JMP, lp->pc0); 2131 2315 } 2132 2316 } … … 2137 2321 case NODE_LVAR: 2138 2322 if (val) { 2139 int idx = lv_idx(s, sym(tree));2323 int idx = lv_idx(s, nsym(tree)); 2140 2324 2141 2325 if (idx > 0) { 2142 genop_peep(s, MKOP_AB(OP_MOVE, cursp(), idx), NOVAL); 2326 gen_move(s, cursp(), idx, val); 2327 if (val && on_eval(s)) genop_0(s, OP_NOP); 2143 2328 } 2144 2329 else { … … 2147 2332 2148 2333 while (up) { 2149 idx = lv_idx(up, sym(tree));2334 idx = lv_idx(up, nsym(tree)); 2150 2335 if (idx > 0) { 2151 genop (s, MKOP_ABC(OP_GETUPVAR, cursp(), idx, lv));2336 genop_3(s, OP_GETUPVAR, cursp(), idx, lv); 2152 2337 break; 2153 2338 } … … 2160 2345 break; 2161 2346 2347 case NODE_NVAR: 2348 if (val) { 2349 int idx = nint(tree); 2350 2351 gen_move(s, cursp(), idx, val); 2352 if (val && on_eval(s)) genop_0(s, OP_NOP); 2353 2354 push(); 2355 } 2356 break; 2357 2162 2358 case NODE_GVAR: 2163 if (val){2164 int sym = new_sym(s, sym(tree));2165 2166 genop (s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));2167 push();2359 { 2360 int sym = new_sym(s, nsym(tree)); 2361 2362 genop_2(s, OP_GETGV, cursp(), sym); 2363 if (val) push(); 2168 2364 } 2169 2365 break; 2170 2366 2171 2367 case NODE_IVAR: 2172 if (val){2173 int sym = new_sym(s, sym(tree));2174 2175 genop (s, MKOP_ABx(OP_GETIV, cursp(), sym));2176 push();2368 { 2369 int sym = new_sym(s, nsym(tree)); 2370 2371 genop_2(s, OP_GETIV, cursp(), sym); 2372 if (val) push(); 2177 2373 } 2178 2374 break; 2179 2375 2180 2376 case NODE_CVAR: 2181 if (val){2182 int sym = new_sym(s, sym(tree));2183 2184 genop (s, MKOP_ABx(OP_GETCV, cursp(), sym));2185 push();2377 { 2378 int sym = new_sym(s, nsym(tree)); 2379 2380 genop_2(s, OP_GETCV, cursp(), sym); 2381 if (val) push(); 2186 2382 } 2187 2383 break; … … 2189 2385 case NODE_CONST: 2190 2386 { 2191 int sym = new_sym(s, sym(tree)); 2192 2193 genop(s, MKOP_ABx(OP_GETCONST, cursp(), sym)); 2194 if (val) { 2195 push(); 2196 } 2197 } 2198 break; 2199 2200 case NODE_DEFINED: 2201 codegen(s, tree, VAL); 2387 int sym = new_sym(s, nsym(tree)); 2388 2389 genop_2(s, OP_GETCONST, cursp(), sym); 2390 if (val) push(); 2391 } 2202 2392 break; 2203 2393 2204 2394 case NODE_BACK_REF: 2205 2395 if (val) { 2206 char buf[3]; 2207 int sym; 2208 2209 buf[0] = '$'; 2210 buf[1] = (char)(intptr_t)tree; 2211 buf[2] = 0; 2212 sym = new_sym(s, mrb_intern_cstr(s->mrb, buf)); 2213 genop(s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym)); 2396 char buf[] = {'$', nchar(tree)}; 2397 int sym = new_sym(s, mrb_intern(s->mrb, buf, sizeof(buf))); 2398 2399 genop_2(s, OP_GETGV, cursp(), sym); 2214 2400 push(); 2215 2401 } … … 2222 2408 int sym; 2223 2409 2224 str = mrb_format(mrb, "$% S", mrb_fixnum_value((mrb_int)(intptr_t)tree));2410 str = mrb_format(mrb, "$%d", nint(tree)); 2225 2411 sym = new_sym(s, mrb_intern_str(mrb, str)); 2226 genop (s, MKOP_ABx(OP_GETGLOBAL, cursp(), sym));2412 genop_2(s, OP_GETGV, cursp(), sym); 2227 2413 push(); 2228 2414 } … … 2234 2420 2235 2421 case NODE_BLOCK_ARG: 2236 codegen(s, tree, VAL);2422 codegen(s, tree, val); 2237 2423 break; 2238 2424 … … 2240 2426 if (val) { 2241 2427 char *p = (char*)tree->car; 2242 int base = (intptr_t)tree->cdr->car;2428 int base = nint(tree->cdr->car); 2243 2429 mrb_int i; 2244 mrb_code co;2245 2430 mrb_bool overflow; 2246 2431 2247 2432 i = readint_mrb_int(s, p, base, FALSE, &overflow); 2433 #ifndef MRB_WITHOUT_FLOAT 2248 2434 if (overflow) { 2249 2435 double f = readint_float(s, p, base); 2250 2436 int off = new_lit(s, mrb_float_value(s->mrb, f)); 2251 2437 2252 genop(s, MKOP_ABx(OP_LOADL, cursp(), off)); 2253 } 2254 else { 2255 if (i < MAXARG_sBx && i > -MAXARG_sBx) { 2256 co = MKOP_AsBx(OP_LOADI, cursp(), i); 2257 } 2438 genop_2(s, OP_LOADL, cursp(), off); 2439 } 2440 else 2441 #endif 2442 { 2443 if (i == -1) genop_1(s, OP_LOADI__1, cursp()); 2444 else if (i < 0) genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i); 2445 else if (i < 8) genop_1(s, OP_LOADI_0 + (uint8_t)i, cursp()); 2446 else if (i <= 0xffff) genop_2(s, OP_LOADI, cursp(), (uint16_t)i); 2258 2447 else { 2259 2448 int off = new_lit(s, mrb_fixnum_value(i)); 2260 co = MKOP_ABx(OP_LOADL, cursp(), off); 2261 } 2262 genop(s, co); 2449 genop_2(s, OP_LOADL, cursp(), off); 2450 } 2263 2451 } 2264 2452 push(); … … 2266 2454 break; 2267 2455 2456 #ifndef MRB_WITHOUT_FLOAT 2268 2457 case NODE_FLOAT: 2269 2458 if (val) { … … 2272 2461 int off = new_lit(s, mrb_float_value(s->mrb, f)); 2273 2462 2274 genop (s, MKOP_ABx(OP_LOADL, cursp(), off));2463 genop_2(s, OP_LOADL, cursp(), off); 2275 2464 push(); 2276 2465 } 2277 2466 break; 2467 #endif 2278 2468 2279 2469 case NODE_NEGATE: 2280 2470 { 2281 nt = (intptr_t)tree->car; 2282 tree = tree->cdr; 2471 nt = nint(tree->car); 2283 2472 switch (nt) { 2473 #ifndef MRB_WITHOUT_FLOAT 2284 2474 case NODE_FLOAT: 2285 2475 if (val) { 2286 char *p = (char*)tree ;2476 char *p = (char*)tree->cdr; 2287 2477 mrb_float f = mrb_float_read(p, NULL); 2288 2478 int off = new_lit(s, mrb_float_value(s->mrb, -f)); 2289 2479 2290 genop (s, MKOP_ABx(OP_LOADL, cursp(), off));2480 genop_2(s, OP_LOADL, cursp(), off); 2291 2481 push(); 2292 2482 } 2293 2483 break; 2484 #endif 2294 2485 2295 2486 case NODE_INT: 2296 2487 if (val) { 2297 char *p = (char*)tree->c ar;2298 int base = (intptr_t)tree->cdr->car;2488 char *p = (char*)tree->cdr->car; 2489 int base = nint(tree->cdr->cdr->car); 2299 2490 mrb_int i; 2300 mrb_code co;2301 2491 mrb_bool overflow; 2302 2492 2303 2493 i = readint_mrb_int(s, p, base, TRUE, &overflow); 2494 #ifndef MRB_WITHOUT_FLOAT 2304 2495 if (overflow) { 2305 2496 double f = readint_float(s, p, base); 2306 2497 int off = new_lit(s, mrb_float_value(s->mrb, -f)); 2307 2498 2308 genop (s, MKOP_ABx(OP_LOADL, cursp(), off));2499 genop_2(s, OP_LOADL, cursp(), off); 2309 2500 } 2310 2501 else { 2311 if (i < MAXARG_sBx && i > -MAXARG_sBx) { 2312 co = MKOP_AsBx(OP_LOADI, cursp(), i); 2502 #endif 2503 if (i == -1) genop_1(s, OP_LOADI__1, cursp()); 2504 else if (i >= -0xffff) { 2505 genop_2(s, OP_LOADINEG, cursp(), (uint16_t)-i); 2313 2506 } 2314 2507 else { 2315 2508 int off = new_lit(s, mrb_fixnum_value(i)); 2316 co = MKOP_ABx(OP_LOADL, cursp(), off);2509 genop_2(s, OP_LOADL, cursp(), off); 2317 2510 } 2318 genop(s, co); 2319 } 2511 #ifndef MRB_WITHOUT_FLOAT 2512 } 2513 #endif 2320 2514 push(); 2321 2515 } … … 2324 2518 default: 2325 2519 if (val) { 2326 int sym = new_msym(s, mrb_intern_lit(s->mrb, "-")); 2327 2328 genop(s, MKOP_ABx(OP_LOADI, cursp(), 0)); 2520 int sym = new_sym(s, mrb_intern_lit(s->mrb, "-@")); 2521 codegen(s, tree, VAL); 2522 pop(); 2523 genop_3(s, OP_SEND, cursp(), sym, 0); 2329 2524 push(); 2330 codegen(s, tree, VAL);2331 pop(); pop();2332 genop(s, MKOP_ABC(OP_SUB, cursp(), sym, 2));2333 2525 } 2334 2526 else { … … 2348 2540 2349 2541 mrb_gc_arena_restore(s->mrb, ai); 2350 genop (s, MKOP_ABx(OP_STRING, cursp(), off));2542 genop_2(s, OP_STRING, cursp(), off); 2351 2543 push(); 2352 2544 } … … 2361 2553 2362 2554 if (!n) { 2363 genop (s, MKOP_A(OP_LOADNIL, cursp()));2555 genop_1(s, OP_LOADNIL, cursp()); 2364 2556 push(); 2365 2557 break; … … 2370 2562 codegen(s, n->car, VAL); 2371 2563 pop(); pop(); 2372 genop_ peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);2564 genop_1(s, OP_STRCAT, cursp()); 2373 2565 push(); 2374 2566 n = n->cdr; … … 2379 2571 2380 2572 while (n) { 2381 if ( (intptr_t)n->car->car!= NODE_STR) {2573 if (nint(n->car->car) != NODE_STR) { 2382 2574 codegen(s, n->car, NOVAL); 2383 2575 } … … 2401 2593 int sym = new_sym(s, mrb_intern_lit(s->mrb, "Kernel")); 2402 2594 2403 genop (s, MKOP_A(OP_LOADSELF, cursp()));2595 genop_1(s, OP_LOADSELF, cursp()); 2404 2596 push(); 2405 2597 codegen(s, tree->car, VAL); 2406 2598 n = tree->cdr; 2407 2599 while (n) { 2408 if ( (intptr_t)n->car->car== NODE_XSTR) {2600 if (nint(n->car->car) == NODE_XSTR) { 2409 2601 n->car->car = (struct mrb_ast_node*)(intptr_t)NODE_STR; 2410 2602 mrb_assert(!n->cdr); /* must be the end */ … … 2412 2604 codegen(s, n->car, VAL); 2413 2605 pop(); pop(); 2414 genop_ peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);2606 genop_1(s, OP_STRCAT, cursp()); 2415 2607 push(); 2416 2608 n = n->cdr; … … 2419 2611 pop_n(3); 2420 2612 sym = new_sym(s, mrb_intern_lit(s->mrb, "`")); 2421 genop (s, MKOP_ABC(OP_SEND, cursp(), sym, 1));2613 genop_3(s, OP_SEND, cursp(), sym, 1); 2422 2614 if (val) push(); 2423 2615 mrb_gc_arena_restore(s->mrb, ai); … … 2433 2625 int sym; 2434 2626 2435 genop (s, MKOP_A(OP_LOADSELF, cursp()));2627 genop_1(s, OP_LOADSELF, cursp()); 2436 2628 push(); 2437 genop (s, MKOP_ABx(OP_STRING, cursp(), off));2629 genop_2(s, OP_STRING, cursp(), off); 2438 2630 push(); push(); 2439 2631 pop_n(3); 2440 2632 sym = new_sym(s, mrb_intern_lit(s->mrb, "`")); 2441 genop (s, MKOP_ABC(OP_SEND, cursp(), sym, 1));2633 genop_3(s, OP_SEND, cursp(), sym, 1); 2442 2634 if (val) push(); 2443 2635 mrb_gc_arena_restore(s->mrb, ai); … … 2455 2647 int argc = 1; 2456 2648 2457 genop (s, MKOP_A(OP_OCLASS, cursp()));2458 genop (s, MKOP_ABx(OP_GETMCNST, cursp(), sym));2649 genop_1(s, OP_OCLASS, cursp()); 2650 genop_2(s, OP_GETMCNST, cursp(), sym); 2459 2651 push(); 2460 genop(s, MKOP_ABx(OP_STRING, cursp(), off)); 2652 genop_2(s, OP_STRING, cursp(), off); 2653 push(); 2461 2654 if (p2 || p3) { 2655 if (p2) { /* opt */ 2656 off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); 2657 genop_2(s, OP_STRING, cursp(), off); 2658 } 2659 else { 2660 genop_1(s, OP_LOADNIL, cursp()); 2661 } 2462 2662 push(); 2463 if (p2) {2464 off = new_lit(s, mrb_str_new_cstr(s->mrb, p2));2465 genop(s, MKOP_ABx(OP_STRING, cursp(), off));2466 }2467 else {2468 genop(s, MKOP_A(OP_LOADNIL, cursp()));2469 }2470 2663 argc++; 2471 if (p3) { 2664 if (p3) { /* enc */ 2665 off = new_lit(s, mrb_str_new(s->mrb, p3, 1)); 2666 genop_2(s, OP_STRING, cursp(), off); 2472 2667 push(); 2473 off = new_lit(s, mrb_str_new(s->mrb, p3, 1));2474 genop(s, MKOP_ABx(OP_STRING, cursp(), off));2475 2668 argc++; 2476 pop(); 2477 } 2478 pop(); 2479 } 2480 pop(); 2669 } 2670 } 2671 push(); /* space for a block */ 2672 pop_n(argc+2); 2481 2673 sym = new_sym(s, mrb_intern_lit(s->mrb, "compile")); 2482 genop (s, MKOP_ABC(OP_SEND, cursp(), sym, argc));2674 genop_3(s, OP_SEND, cursp(), sym, argc); 2483 2675 mrb_gc_arena_restore(s->mrb, ai); 2484 2676 push(); … … 2495 2687 char *p; 2496 2688 2497 genop (s, MKOP_A(OP_OCLASS, cursp()));2498 genop (s, MKOP_ABx(OP_GETMCNST, cursp(), sym));2689 genop_1(s, OP_OCLASS, cursp()); 2690 genop_2(s, OP_GETMCNST, cursp(), sym); 2499 2691 push(); 2500 2692 codegen(s, n->car, VAL); … … 2503 2695 codegen(s, n->car, VAL); 2504 2696 pop(); pop(); 2505 genop_ peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL);2697 genop_1(s, OP_STRCAT, cursp()); 2506 2698 push(); 2507 2699 n = n->cdr; 2508 2700 } 2509 2701 n = tree->cdr->cdr; 2510 if (n->car) { 2702 if (n->car) { /* tail */ 2511 2703 p = (char*)n->car; 2512 2704 off = new_lit(s, mrb_str_new_cstr(s->mrb, p)); 2513 2705 codegen(s, tree->car, VAL); 2514 genop (s, MKOP_ABx(OP_STRING, cursp(), off));2706 genop_2(s, OP_STRING, cursp(), off); 2515 2707 pop(); 2516 genop_peep(s, MKOP_AB(OP_STRCAT, cursp(), cursp()+1), VAL); 2517 } 2518 if (n->cdr->car) { 2708 genop_1(s, OP_STRCAT, cursp()); 2709 push(); 2710 } 2711 if (n->cdr->car) { /* opt */ 2519 2712 char *p2 = (char*)n->cdr->car; 2520 2713 off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); 2714 genop_2(s, OP_STRING, cursp(), off); 2521 2715 push(); 2716 argc++; 2717 } 2718 if (n->cdr->cdr) { /* enc */ 2719 char *p2 = (char*)n->cdr->cdr; 2522 2720 off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); 2523 genop(s, MKOP_ABx(OP_STRING, cursp(), off)); 2721 genop_2(s, OP_STRING, cursp(), off); 2722 push(); 2524 2723 argc++; 2525 2724 } 2526 if (n->cdr->cdr) { 2527 char *p2 = (char*)n->cdr->cdr; 2528 2529 push(); 2530 off = new_lit(s, mrb_str_new_cstr(s->mrb, p2)); 2531 genop(s, MKOP_ABx(OP_STRING, cursp(), off)); 2532 argc++; 2533 } 2534 pop_n(argc); 2725 push(); /* space for a block */ 2726 pop_n(argc+2); 2535 2727 sym = new_sym(s, mrb_intern_lit(s->mrb, "compile")); 2536 genop (s, MKOP_ABC(OP_SEND, cursp(), sym, argc));2728 genop_3(s, OP_SEND, cursp(), sym, argc); 2537 2729 mrb_gc_arena_restore(s->mrb, ai); 2538 2730 push(); … … 2542 2734 2543 2735 while (n) { 2544 if ( (intptr_t)n->car->car!= NODE_STR) {2736 if (nint(n->car->car) != NODE_STR) { 2545 2737 codegen(s, n->car, NOVAL); 2546 2738 } … … 2552 2744 case NODE_SYM: 2553 2745 if (val) { 2554 int sym = new_sym(s, sym(tree));2555 2556 genop (s, MKOP_ABx(OP_LOADSYM, cursp(), sym));2746 int sym = new_sym(s, nsym(tree)); 2747 2748 genop_2(s, OP_LOADSYM, cursp(), sym); 2557 2749 push(); 2558 2750 } … … 2562 2754 codegen(s, tree, val); 2563 2755 if (val) { 2564 gen_ send_intern(s);2756 gen_intern(s); 2565 2757 } 2566 2758 break; … … 2568 2760 case NODE_SELF: 2569 2761 if (val) { 2570 genop (s, MKOP_A(OP_LOADSELF, cursp()));2762 genop_1(s, OP_LOADSELF, cursp()); 2571 2763 push(); 2572 2764 } … … 2575 2767 case NODE_NIL: 2576 2768 if (val) { 2577 genop (s, MKOP_A(OP_LOADNIL, cursp()));2769 genop_1(s, OP_LOADNIL, cursp()); 2578 2770 push(); 2579 2771 } … … 2582 2774 case NODE_TRUE: 2583 2775 if (val) { 2584 genop (s, MKOP_A(OP_LOADT, cursp()));2776 genop_1(s, OP_LOADT, cursp()); 2585 2777 push(); 2586 2778 } … … 2589 2781 case NODE_FALSE: 2590 2782 if (val) { 2591 genop (s, MKOP_A(OP_LOADF, cursp()));2783 genop_1(s, OP_LOADF, cursp()); 2592 2784 push(); 2593 2785 } … … 2596 2788 case NODE_ALIAS: 2597 2789 { 2598 int a = new_msym(s, sym(tree->car)); 2599 int b = new_msym(s, sym(tree->cdr)); 2600 int c = new_msym(s, mrb_intern_lit(s->mrb, "alias_method")); 2601 2602 genop(s, MKOP_A(OP_TCLASS, cursp())); 2603 push(); 2604 genop(s, MKOP_ABx(OP_LOADSYM, cursp(), a)); 2605 push(); 2606 genop(s, MKOP_ABx(OP_LOADSYM, cursp(), b)); 2607 push(); 2608 genop(s, MKOP_A(OP_LOADNIL, cursp())); 2609 push(); 2610 pop_n(4); 2611 genop(s, MKOP_ABC(OP_SEND, cursp(), c, 2)); 2790 int a = new_sym(s, nsym(tree->car)); 2791 int b = new_sym(s, nsym(tree->cdr)); 2792 2793 genop_2(s, OP_ALIAS, a, b); 2612 2794 if (val) { 2795 genop_1(s, OP_LOADNIL, cursp()); 2613 2796 push(); 2614 2797 } … … 2618 2801 case NODE_UNDEF: 2619 2802 { 2620 int undef = new_msym(s, mrb_intern_lit(s->mrb, "undef_method"));2621 int num = 0;2622 2803 node *t = tree; 2623 2804 2624 genop(s, MKOP_A(OP_TCLASS, cursp()));2625 push();2626 2805 while (t) { 2627 int symbol; 2628 if (num >= CALL_MAXARGS - 1) { 2629 pop_n(num); 2630 genop(s, MKOP_ABC(OP_ARRAY, cursp(), cursp(), num)); 2631 while (t) { 2632 symbol = new_msym(s, sym(t->car)); 2633 push(); 2634 genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol)); 2635 pop(); 2636 genop(s, MKOP_AB(OP_ARYPUSH, cursp(), cursp()+1)); 2637 t = t->cdr; 2638 } 2639 num = CALL_MAXARGS; 2640 break; 2641 } 2642 symbol = new_msym(s, sym(t->car)); 2643 genop(s, MKOP_ABx(OP_LOADSYM, cursp(), symbol)); 2644 push(); 2806 int symbol = new_sym(s, nsym(t->car)); 2807 genop_1(s, OP_UNDEF, symbol); 2645 2808 t = t->cdr; 2646 num++; 2647 } 2648 pop(); 2649 if (num < CALL_MAXARGS) { 2650 pop_n(num); 2651 } 2652 genop(s, MKOP_ABC(OP_SEND, cursp(), undef, num)); 2809 } 2653 2810 if (val) { 2811 genop_1(s, OP_LOADNIL, cursp()); 2654 2812 push(); 2655 2813 } … … 2660 2818 { 2661 2819 int idx; 2820 node *body; 2662 2821 2663 2822 if (tree->car->car == (node*)0) { 2664 genop (s, MKOP_A(OP_LOADNIL, cursp()));2823 genop_1(s, OP_LOADNIL, cursp()); 2665 2824 push(); 2666 2825 } 2667 2826 else if (tree->car->car == (node*)1) { 2668 genop (s, MKOP_A(OP_OCLASS, cursp()));2827 genop_1(s, OP_OCLASS, cursp()); 2669 2828 push(); 2670 2829 } … … 2676 2835 } 2677 2836 else { 2678 genop (s, MKOP_A(OP_LOADNIL, cursp()));2837 genop_1(s, OP_LOADNIL, cursp()); 2679 2838 push(); 2680 2839 } 2681 2840 pop(); pop(); 2682 idx = new_msym(s, sym(tree->car->cdr)); 2683 genop(s, MKOP_AB(OP_CLASS, cursp(), idx)); 2684 idx = scope_body(s, tree->cdr->cdr->car, val); 2685 genop(s, MKOP_ABx(OP_EXEC, cursp(), idx)); 2841 idx = new_sym(s, nsym(tree->car->cdr)); 2842 genop_2(s, OP_CLASS, cursp(), idx); 2843 body = tree->cdr->cdr->car; 2844 if (nint(body->cdr->car) == NODE_BEGIN && body->cdr->cdr == NULL) { 2845 genop_1(s, OP_LOADNIL, cursp()); 2846 } 2847 else { 2848 idx = scope_body(s, body, val); 2849 genop_2(s, OP_EXEC, cursp(), idx); 2850 } 2686 2851 if (val) { 2687 2852 push(); … … 2695 2860 2696 2861 if (tree->car->car == (node*)0) { 2697 genop (s, MKOP_A(OP_LOADNIL, cursp()));2862 genop_1(s, OP_LOADNIL, cursp()); 2698 2863 push(); 2699 2864 } 2700 2865 else if (tree->car->car == (node*)1) { 2701 genop (s, MKOP_A(OP_OCLASS, cursp()));2866 genop_1(s, OP_OCLASS, cursp()); 2702 2867 push(); 2703 2868 } … … 2706 2871 } 2707 2872 pop(); 2708 idx = new_msym(s, sym(tree->car->cdr)); 2709 genop(s, MKOP_AB(OP_MODULE, cursp(), idx)); 2710 idx = scope_body(s, tree->cdr->car, val); 2711 genop(s, MKOP_ABx(OP_EXEC, cursp(), idx)); 2873 idx = new_sym(s, nsym(tree->car->cdr)); 2874 genop_2(s, OP_MODULE, cursp(), idx); 2875 if (nint(tree->cdr->car->cdr->car) == NODE_BEGIN && 2876 tree->cdr->car->cdr->cdr == NULL) { 2877 genop_1(s, OP_LOADNIL, cursp()); 2878 } 2879 else { 2880 idx = scope_body(s, tree->cdr->car, val); 2881 genop_2(s, OP_EXEC, cursp(), idx); 2882 } 2712 2883 if (val) { 2713 2884 push(); … … 2722 2893 codegen(s, tree->car, VAL); 2723 2894 pop(); 2724 genop(s, MKOP_AB(OP_SCLASS, cursp(), cursp())); 2725 idx = scope_body(s, tree->cdr->car, val); 2726 genop(s, MKOP_ABx(OP_EXEC, cursp(), idx)); 2895 genop_1(s, OP_SCLASS, cursp()); 2896 if (nint(tree->cdr->car->cdr->car) == NODE_BEGIN && 2897 tree->cdr->car->cdr->cdr == NULL) { 2898 genop_1(s, OP_LOADNIL, cursp()); 2899 } 2900 else { 2901 idx = scope_body(s, tree->cdr->car, val); 2902 genop_2(s, OP_EXEC, cursp(), idx); 2903 } 2727 2904 if (val) { 2728 2905 push(); … … 2733 2910 case NODE_DEF: 2734 2911 { 2735 int sym = new_ msym(s,sym(tree->car));2912 int sym = new_sym(s, nsym(tree->car)); 2736 2913 int idx = lambda_body(s, tree->cdr, 0); 2737 2914 2738 genop (s, MKOP_A(OP_TCLASS, cursp()));2915 genop_1(s, OP_TCLASS, cursp()); 2739 2916 push(); 2740 genop (s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_METHOD));2917 genop_2(s, OP_METHOD, cursp(), idx); 2741 2918 push(); pop(); 2742 2919 pop(); 2743 genop (s, MKOP_AB(OP_METHOD, cursp(), sym));2920 genop_2(s, OP_DEF, cursp(), sym); 2744 2921 if (val) { 2745 genop (s, MKOP_ABx(OP_LOADSYM, cursp(), sym));2922 genop_2(s, OP_LOADSYM, cursp(), sym); 2746 2923 push(); 2747 2924 } … … 2752 2929 { 2753 2930 node *recv = tree->car; 2754 int sym = new_ msym(s,sym(tree->cdr->car));2931 int sym = new_sym(s, nsym(tree->cdr->car)); 2755 2932 int idx = lambda_body(s, tree->cdr->cdr, 0); 2756 2933 2757 2934 codegen(s, recv, VAL); 2758 2935 pop(); 2759 genop (s, MKOP_AB(OP_SCLASS, cursp(), cursp()));2936 genop_1(s, OP_SCLASS, cursp()); 2760 2937 push(); 2761 genop (s, MKOP_Abc(OP_LAMBDA, cursp(), idx, OP_L_METHOD));2938 genop_2(s, OP_METHOD, cursp(), idx); 2762 2939 pop(); 2763 genop (s, MKOP_AB(OP_METHOD, cursp(), sym));2940 genop_2(s, OP_DEF, cursp(), sym); 2764 2941 if (val) { 2765 genop (s, MKOP_ABx(OP_LOADSYM, cursp(), sym));2942 genop_2(s, OP_LOADSYM, cursp(), sym); 2766 2943 push(); 2767 2944 } … … 2802 2979 codegen_scope *p = (codegen_scope *)mrb_pool_alloc(pool, sizeof(codegen_scope)); 2803 2980 2804 if (!p) return NULL; 2981 if (!p) { 2982 if (prev) 2983 codegen_error(prev, "unexpected scope"); 2984 return NULL; 2985 } 2805 2986 *p = codegen_scope_zero; 2806 2987 p->mrb = mrb; … … 2825 3006 p->irep->plen = 0; 2826 3007 2827 p->scapa = MAXMSYMLEN;3008 p->scapa = 256; 2828 3009 p->irep->syms = (mrb_sym*)mrb_malloc(mrb, sizeof(mrb_sym)*p->scapa); 2829 3010 p->irep->slen = 0; … … 2850 3031 p->ai = mrb_gc_arena_save(mrb); 2851 3032 2852 p->filename = prev->filename;2853 if (p->filename ) {3033 p->filename_sym = prev->filename_sym; 3034 if (p->filename_sym) { 2854 3035 p->lines = (uint16_t*)mrb_malloc(mrb, sizeof(short)*p->icapa); 2855 3036 } … … 2858 3039 /* debug setting */ 2859 3040 p->debug_start_pos = 0; 2860 if (p->filename ) {3041 if (p->filename_sym) { 2861 3042 mrb_debug_info_alloc(mrb, p->irep); 2862 p->irep->filename = p->filename;2863 p->irep->lines = p->lines;2864 3043 } 2865 3044 else { … … 2879 3058 mrb_state *mrb = s->mrb; 2880 3059 mrb_irep *irep = s->irep; 2881 size_t fname_len; 2882 char *fname; 2883 3060 3061 if (s->nlocals >= 0x3ff) { 3062 codegen_error(s, "too many local variables"); 3063 } 2884 3064 irep->flags = 0; 2885 3065 if (s->iseq) { 2886 3066 irep->iseq = (mrb_code *)codegen_realloc(s, s->iseq, sizeof(mrb_code)*s->pc); 2887 3067 irep->ilen = s->pc; 2888 if (s->lines) {2889 irep->lines = (uint16_t *)codegen_realloc(s, s->lines, sizeof(uint16_t)*s->pc);2890 }2891 else {2892 irep->lines = 0;2893 }2894 3068 } 2895 3069 irep->pool = (mrb_value*)codegen_realloc(s, irep->pool, sizeof(mrb_value)*irep->plen); 2896 3070 irep->syms = (mrb_sym*)codegen_realloc(s, irep->syms, sizeof(mrb_sym)*irep->slen); 2897 3071 irep->reps = (mrb_irep**)codegen_realloc(s, irep->reps, sizeof(mrb_irep*)*irep->rlen); 2898 if (s->filename) { 2899 irep->filename = mrb_parser_get_filename(s->parser, s->filename_index); 2900 mrb_debug_info_append_file(mrb, irep, s->debug_start_pos, s->pc); 2901 2902 fname_len = strlen(s->filename); 2903 fname = (char*)codegen_malloc(s, fname_len + 1); 2904 memcpy(fname, s->filename, fname_len); 2905 fname[fname_len] = '\0'; 2906 irep->filename = fname; 2907 irep->own_filename = TRUE; 2908 } 3072 if (s->filename_sym) { 3073 mrb_sym fname = mrb_parser_get_filename(s->parser, s->filename_index); 3074 const char *filename = mrb_sym_name_len(s->mrb, fname, NULL); 3075 3076 mrb_debug_info_append_file(s->mrb, s->irep->debug_info, 3077 filename, s->lines, s->debug_start_pos, s->pc); 3078 } 3079 mrb_free(s->mrb, s->lines); 2909 3080 2910 3081 irep->nlocals = s->nlocals; … … 2921 3092 2922 3093 p->type = t; 2923 p->pc 1 = p->pc2 = p->pc3 = 0;3094 p->pc0 = p->pc1 = p->pc2 = p->pc3 = 0; 2924 3095 p->prev = s->loop; 2925 3096 p->ensure_level = s->ensure_level; … … 2939 3110 else { 2940 3111 struct loopinfo *loop; 3112 int n = 0; 2941 3113 2942 3114 if (tree) { … … 2945 3117 2946 3118 loop = s->loop; 2947 while (loop && loop->type == LOOP_BEGIN) { 2948 genop_peep(s, MKOP_A(OP_POPERR, 1), NOVAL); 2949 loop = loop->prev; 2950 } 2951 while (loop && loop->type == LOOP_RESCUE) { 2952 loop = loop->prev; 3119 while (loop) { 3120 if (loop->type == LOOP_BEGIN) { 3121 n++; 3122 loop = loop->prev; 3123 } 3124 else if (loop->type == LOOP_RESCUE) { 3125 loop = loop->prev; 3126 } 3127 else{ 3128 break; 3129 } 2953 3130 } 2954 3131 if (!loop) { … … 2956 3133 return; 2957 3134 } 3135 if (n > 0) { 3136 genop_1(s, OP_POPERR, n); 3137 } 2958 3138 2959 3139 if (loop->type == LOOP_NORMAL) { … … 2961 3141 2962 3142 if (s->ensure_level > s->loop->ensure_level) { 2963 genop_ peep(s, MKOP_A(OP_EPOP, s->ensure_level - s->loop->ensure_level), NOVAL);3143 genop_1(s, OP_EPOP, s->ensure_level - s->loop->ensure_level); 2964 3144 } 2965 3145 if (tree) { 2966 gen op_peep(s, MKOP_AB(OP_MOVE, loop->acc, cursp()), NOVAL);2967 } 2968 tmp = gen op(s, MKOP_sBx(OP_JMP, loop->pc3));3146 gen_move(s, loop->acc, cursp(), 0); 3147 } 3148 tmp = genjmp(s, OP_JMP, loop->pc3); 2969 3149 loop->pc3 = tmp; 2970 3150 } 2971 3151 else { 2972 3152 if (!tree) { 2973 genop (s, MKOP_A(OP_LOADNIL, cursp()));2974 } 2975 gen op(s, MKOP_AB(OP_RETURN, cursp(), OP_R_BREAK));3153 genop_1(s, OP_LOADNIL, cursp()); 3154 } 3155 gen_return(s, OP_BREAK, cursp()); 2976 3156 } 2977 3157 } … … 2981 3161 loop_pop(codegen_scope *s, int val) 2982 3162 { 3163 if (val) { 3164 genop_1(s, OP_LOADNIL, cursp()); 3165 } 2983 3166 dispatch_linked(s, s->loop->pc3); 2984 if (val) {2985 genop(s, MKOP_A(OP_LOADNIL, cursp()));2986 }2987 3167 s->loop = s->loop->prev; 2988 3168 if (val) push(); 2989 3169 } 2990 3170 2991 MRB_APIstruct RProc*2992 mrb_generate_code(mrb_state *mrb, parser_state *p)3171 static struct RProc* 3172 generate_code(mrb_state *mrb, parser_state *p, int val) 2993 3173 { 2994 3174 codegen_scope *scope = scope_new(mrb, 0, 0); … … 2996 3176 struct mrb_jmpbuf *prev_jmp = mrb->jmp; 2997 3177 2998 if (!scope) {2999 return NULL;3000 }3001 3178 scope->mrb = mrb; 3002 3179 scope->parser = p; 3003 scope->filename = p->filename;3180 scope->filename_sym = p->filename_sym; 3004 3181 scope->filename_index = p->current_filename_index; 3005 3182 3006 3183 MRB_TRY(&scope->jmp) { 3007 mrb->jmp = &scope->jmp; 3184 mrb->jmp = &scope->jmp; 3008 3185 /* prepare irep */ 3009 codegen(scope, p->tree, NOVAL);3186 codegen(scope, p->tree, val); 3010 3187 proc = mrb_proc_new(mrb, scope->irep); 3011 3188 mrb_irep_decref(mrb, scope->irep); 3012 3189 mrb_pool_close(scope->mpool); 3013 3190 proc->c = NULL; 3191 if (mrb->c->cibase && mrb->c->cibase->proc == proc->upper) { 3192 proc->upper = NULL; 3193 } 3014 3194 mrb->jmp = prev_jmp; 3015 3195 return proc; … … 3023 3203 MRB_END_EXC(&scope->jmp); 3024 3204 } 3205 3206 MRB_API struct RProc* 3207 mrb_generate_code(mrb_state *mrb, parser_state *p) 3208 { 3209 return generate_code(mrb, p, VAL); 3210 } 3211 3212 void 3213 mrb_irep_remove_lv(mrb_state *mrb, mrb_irep *irep) 3214 { 3215 int i; 3216 3217 if (irep->lv) { 3218 mrb_free(mrb, irep->lv); 3219 irep->lv = NULL; 3220 } 3221 3222 for (i = 0; i < irep->rlen; ++i) { 3223 mrb_irep_remove_lv(mrb, irep->reps[i]); 3224 } 3225 } 3226 3227 #undef OPCODE 3228 #define Z 1 3229 #define S 3 3230 #define W 4 3231 /* instruction sizes */ 3232 uint8_t mrb_insn_size[] = { 3233 #define B 2 3234 #define BB 3 3235 #define BBB 4 3236 #define BS 4 3237 #define SB 4 3238 #define OPCODE(_,x) x, 3239 #include "mruby/ops.h" 3240 #undef OPCODE 3241 #undef B 3242 #undef BB 3243 #undef BS 3244 #undef SB 3245 #undef BBB 3246 }; 3247 /* EXT1 instruction sizes */ 3248 uint8_t mrb_insn_size1[] = { 3249 #define B 3 3250 #define BB 4 3251 #define BBB 5 3252 #define BS 5 3253 #define SB 5 3254 #define OPCODE(_,x) x, 3255 #include "mruby/ops.h" 3256 #undef OPCODE 3257 #undef B 3258 }; 3259 /* EXT2 instruction sizes */ 3260 uint8_t mrb_insn_size2[] = { 3261 #define B 2 3262 #define OPCODE(_,x) x, 3263 #include "mruby/ops.h" 3264 #undef OPCODE 3265 #undef BB 3266 #undef BBB 3267 #undef BS 3268 #undef SB 3269 }; 3270 /* EXT3 instruction sizes */ 3271 #define BB 5 3272 #define BBB 6 3273 #define BS 4 3274 #define SB 5 3275 uint8_t mrb_insn_size3[] = { 3276 #define OPCODE(_,x) x, 3277 #include "mruby/ops.h" 3278 };
Note:
See TracChangeset
for help on using the changeset viewer.