diff options
Diffstat (limited to 'lpcode.c')
| -rw-r--r-- | lpcode.c | 37 |
1 files changed, 26 insertions, 11 deletions
| @@ -459,7 +459,9 @@ int sizei (const Instruction *i) { | |||
| 459 | case IOpenCall: case ICommit: case IPartialCommit: case IBackCommit: | 459 | case IOpenCall: case ICommit: case IPartialCommit: case IBackCommit: |
| 460 | return 2; | 460 | return 2; |
| 461 | case IThrow: /* labeled failure */ | 461 | case IThrow: /* labeled failure */ |
| 462 | return 1; | 462 | return 2; |
| 463 | case IThrowRec: /* labeled failure */ | ||
| 464 | return 3; | ||
| 463 | case IRecov: case ILabChoice: | 465 | case IRecov: case ILabChoice: |
| 464 | return (CHARSETINSTSIZE - 1) + 2; /* labeled failure */ | 466 | return (CHARSETINSTSIZE - 1) + 2; /* labeled failure */ |
| 465 | 467 | ||
| @@ -519,15 +521,6 @@ static int addinstruction (CompileState *compst, Opcode op, int aux) { | |||
| 519 | return i; | 521 | return i; |
| 520 | } | 522 | } |
| 521 | 523 | ||
| 522 | /* labeled failure */ | ||
| 523 | static int addthrowinstruction (CompileState *compst, int aux, int key) { | ||
| 524 | int i = addinstruction(compst, IThrow, aux); | ||
| 525 | getinstr(compst, i).i.key = key; | ||
| 526 | return i; | ||
| 527 | } | ||
| 528 | |||
| 529 | /* labeled failure */ | ||
| 530 | |||
| 531 | 524 | ||
| 532 | /* | 525 | /* |
| 533 | ** Add an instruction followed by space for an offset (to be set later) | 526 | ** Add an instruction followed by space for an offset (to be set later) |
| @@ -541,6 +534,22 @@ static int addoffsetinst (CompileState *compst, Opcode op) { | |||
| 541 | } | 534 | } |
| 542 | 535 | ||
| 543 | 536 | ||
| 537 | /* labeled failure */ | ||
| 538 | static void codethrow (CompileState *compst, TTree *throw) { | ||
| 539 | int recov, aux; | ||
| 540 | if (throw->u.s.ps != 0) { | ||
| 541 | recov = addoffsetinst(compst, IThrowRec); | ||
| 542 | } else { | ||
| 543 | recov = addinstruction(compst, IThrow, 0); | ||
| 544 | } | ||
| 545 | aux = nextinstruction(compst); | ||
| 546 | getinstr(compst, aux).i.key = throw->key; /* next instruction keeps only rule name */ | ||
| 547 | getinstr(compst, recov).i.key = sib2(throw)->cap; /* rule number */ | ||
| 548 | assert(sib2(throw)->tag == TRule); | ||
| 549 | } | ||
| 550 | /* labeled failure */ | ||
| 551 | |||
| 552 | |||
| 544 | /* | 553 | /* |
| 545 | ** Set the offset of an instruction | 554 | ** Set the offset of an instruction |
| 546 | */ | 555 | */ |
| @@ -920,7 +929,13 @@ static void correctcalls (CompileState *compst, int *positions, | |||
| 920 | else | 929 | else |
| 921 | code[i].i.code = ICall; | 930 | code[i].i.code = ICall; |
| 922 | jumptothere(compst, i, rule); /* call jumps to respective rule */ | 931 | jumptothere(compst, i, rule); /* call jumps to respective rule */ |
| 932 | } else if (code[i].i.code == IThrowRec) { | ||
| 933 | int n = code[i].i.key; /* rule number */ | ||
| 934 | int rule = positions[n]; /* rule position */ | ||
| 935 | assert(rule == from || code[rule - 1].i.code == IRet); | ||
| 936 | jumptothere(compst, i, rule); /* call jumps to respective rule */ | ||
| 923 | } | 937 | } |
| 938 | |||
| 924 | } | 939 | } |
| 925 | assert(i == to); | 940 | assert(i == to); |
| 926 | } | 941 | } |
| @@ -1008,7 +1023,7 @@ static void codegen (CompileState *compst, TTree *tree, int opt, int tt, | |||
| 1008 | /*printf("TThrow %s top %d\n", lua_typename(compst->L, -1), lua_gettop(compst->L));*/ | 1023 | /*printf("TThrow %s top %d\n", lua_typename(compst->L, -1), lua_gettop(compst->L));*/ |
| 1009 | /*lua_rawgeti(compst->L, -1, tree->key);*/ | 1024 | /*lua_rawgeti(compst->L, -1, tree->key);*/ |
| 1010 | /*printf("Throw2 lab = %s\n", lua_tostring(compst->L, -1));*/ | 1025 | /*printf("Throw2 lab = %s\n", lua_tostring(compst->L, -1));*/ |
| 1011 | addthrowinstruction(compst, (byte) tree->u.label, tree->key); | 1026 | codethrow(compst, tree); |
| 1012 | break; | 1027 | break; |
| 1013 | } | 1028 | } |
| 1014 | case TRecov: { /* labeled failure */ | 1029 | case TRecov: { /* labeled failure */ |
