diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-12-17 13:02:44 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-12-17 13:02:44 -0200 |
| commit | a01eba657e3146f85b516a1c05c2009c626483cc (patch) | |
| tree | aba8cbb14209bec94137b3298367df969975c002 | |
| parent | b7446ea88dc3565b32ff180b9aea4f5313bb890b (diff) | |
| download | lua-a01eba657e3146f85b516a1c05c2009c626483cc.tar.gz lua-a01eba657e3146f85b516a1c05c2009c626483cc.tar.bz2 lua-a01eba657e3146f85b516a1c05c2009c626483cc.zip | |
reordering of some functions + 'code_label' renamed to 'code_loadbool'
Diffstat (limited to '')
| -rw-r--r-- | lcode.c | 122 |
1 files changed, 61 insertions, 61 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 2.103 2015/11/19 19:16:22 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.104 2015/12/17 14:52:53 roberto Exp roberto $ |
| 3 | ** Code generator for Lua | 3 | ** Code generator for Lua |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -73,6 +73,39 @@ void luaK_nil (FuncState *fs, int from, int n) { | |||
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | 75 | ||
| 76 | static int getjump (FuncState *fs, int pc) { | ||
| 77 | int offset = GETARG_sBx(fs->f->code[pc]); | ||
| 78 | if (offset == NO_JUMP) /* point to itself represents end of list */ | ||
| 79 | return NO_JUMP; /* end of list */ | ||
| 80 | else | ||
| 81 | return (pc+1)+offset; /* turn offset into absolute position */ | ||
| 82 | } | ||
| 83 | |||
| 84 | |||
| 85 | static void fixjump (FuncState *fs, int pc, int dest) { | ||
| 86 | Instruction *jmp = &fs->f->code[pc]; | ||
| 87 | int offset = dest-(pc+1); | ||
| 88 | lua_assert(dest != NO_JUMP); | ||
| 89 | if (abs(offset) > MAXARG_sBx) | ||
| 90 | luaX_syntaxerror(fs->ls, "control structure too long"); | ||
| 91 | SETARG_sBx(*jmp, offset); | ||
| 92 | } | ||
| 93 | |||
| 94 | |||
| 95 | void luaK_concat (FuncState *fs, int *l1, int l2) { | ||
| 96 | if (l2 == NO_JUMP) return; | ||
| 97 | else if (*l1 == NO_JUMP) | ||
| 98 | *l1 = l2; | ||
| 99 | else { | ||
| 100 | int list = *l1; | ||
| 101 | int next; | ||
| 102 | while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ | ||
| 103 | list = next; | ||
| 104 | fixjump(fs, list, l2); | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | |||
| 76 | int luaK_jump (FuncState *fs) { | 109 | int luaK_jump (FuncState *fs) { |
| 77 | int jpc = fs->jpc; /* save list of jumps to here */ | 110 | int jpc = fs->jpc; /* save list of jumps to here */ |
| 78 | int j; | 111 | int j; |
| @@ -94,16 +127,6 @@ static int condjump (FuncState *fs, OpCode op, int A, int B, int C) { | |||
| 94 | } | 127 | } |
| 95 | 128 | ||
| 96 | 129 | ||
| 97 | static void fixjump (FuncState *fs, int pc, int dest) { | ||
| 98 | Instruction *jmp = &fs->f->code[pc]; | ||
| 99 | int offset = dest-(pc+1); | ||
| 100 | lua_assert(dest != NO_JUMP); | ||
| 101 | if (abs(offset) > MAXARG_sBx) | ||
| 102 | luaX_syntaxerror(fs->ls, "control structure too long"); | ||
| 103 | SETARG_sBx(*jmp, offset); | ||
| 104 | } | ||
| 105 | |||
| 106 | |||
| 107 | /* | 130 | /* |
| 108 | ** returns current 'pc' and marks it as a jump target (to avoid wrong | 131 | ** returns current 'pc' and marks it as a jump target (to avoid wrong |
| 109 | ** optimizations with consecutive instructions not in the same basic block). | 132 | ** optimizations with consecutive instructions not in the same basic block). |
| @@ -114,15 +137,6 @@ int luaK_getlabel (FuncState *fs) { | |||
| 114 | } | 137 | } |
| 115 | 138 | ||
| 116 | 139 | ||
| 117 | static int getjump (FuncState *fs, int pc) { | ||
| 118 | int offset = GETARG_sBx(fs->f->code[pc]); | ||
| 119 | if (offset == NO_JUMP) /* point to itself represents end of list */ | ||
| 120 | return NO_JUMP; /* end of list */ | ||
| 121 | else | ||
| 122 | return (pc+1)+offset; /* turn offset into absolute position */ | ||
| 123 | } | ||
| 124 | |||
| 125 | |||
| 126 | static Instruction *getjumpcontrol (FuncState *fs, int pc) { | 140 | static Instruction *getjumpcontrol (FuncState *fs, int pc) { |
| 127 | Instruction *pi = &fs->f->code[pc]; | 141 | Instruction *pi = &fs->f->code[pc]; |
| 128 | if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) | 142 | if (pc >= 1 && testTMode(GET_OPCODE(*(pi-1)))) |
| @@ -132,19 +146,6 @@ static Instruction *getjumpcontrol (FuncState *fs, int pc) { | |||
| 132 | } | 146 | } |
| 133 | 147 | ||
| 134 | 148 | ||
| 135 | /* | ||
| 136 | ** check whether list has any jump that do not produce a value | ||
| 137 | ** (or produce an inverted value) | ||
| 138 | */ | ||
| 139 | static int need_value (FuncState *fs, int list) { | ||
| 140 | for (; list != NO_JUMP; list = getjump(fs, list)) { | ||
| 141 | Instruction i = *getjumpcontrol(fs, list); | ||
| 142 | if (GET_OPCODE(i) != OP_TESTSET) return 1; | ||
| 143 | } | ||
| 144 | return 0; /* not found */ | ||
| 145 | } | ||
| 146 | |||
| 147 | |||
| 148 | static int patchtestreg (FuncState *fs, int node, int reg) { | 149 | static int patchtestreg (FuncState *fs, int node, int reg) { |
| 149 | Instruction *i = getjumpcontrol(fs, node); | 150 | Instruction *i = getjumpcontrol(fs, node); |
| 150 | if (GET_OPCODE(*i) != OP_TESTSET) | 151 | if (GET_OPCODE(*i) != OP_TESTSET) |
| @@ -183,6 +184,12 @@ static void dischargejpc (FuncState *fs) { | |||
| 183 | } | 184 | } |
| 184 | 185 | ||
| 185 | 186 | ||
| 187 | void luaK_patchtohere (FuncState *fs, int list) { | ||
| 188 | luaK_getlabel(fs); | ||
| 189 | luaK_concat(fs, &fs->jpc, list); | ||
| 190 | } | ||
| 191 | |||
| 192 | |||
| 186 | void luaK_patchlist (FuncState *fs, int list, int target) { | 193 | void luaK_patchlist (FuncState *fs, int list, int target) { |
| 187 | if (target == fs->pc) | 194 | if (target == fs->pc) |
| 188 | luaK_patchtohere(fs, list); | 195 | luaK_patchtohere(fs, list); |
| @@ -204,26 +211,6 @@ void luaK_patchclose (FuncState *fs, int list, int level) { | |||
| 204 | } | 211 | } |
| 205 | 212 | ||
| 206 | 213 | ||
| 207 | void luaK_patchtohere (FuncState *fs, int list) { | ||
| 208 | luaK_getlabel(fs); | ||
| 209 | luaK_concat(fs, &fs->jpc, list); | ||
| 210 | } | ||
| 211 | |||
| 212 | |||
| 213 | void luaK_concat (FuncState *fs, int *l1, int l2) { | ||
| 214 | if (l2 == NO_JUMP) return; | ||
| 215 | else if (*l1 == NO_JUMP) | ||
| 216 | *l1 = l2; | ||
| 217 | else { | ||
| 218 | int list = *l1; | ||
| 219 | int next; | ||
| 220 | while ((next = getjump(fs, list)) != NO_JUMP) /* find last element */ | ||
| 221 | list = next; | ||
| 222 | fixjump(fs, list, l2); | ||
| 223 | } | ||
| 224 | } | ||
| 225 | |||
| 226 | |||
| 227 | static int luaK_code (FuncState *fs, Instruction i) { | 214 | static int luaK_code (FuncState *fs, Instruction i) { |
| 228 | Proto *f = fs->f; | 215 | Proto *f = fs->f; |
| 229 | dischargejpc(fs); /* 'pc' will change */ | 216 | dischargejpc(fs); /* 'pc' will change */ |
| @@ -434,12 +421,6 @@ void luaK_dischargevars (FuncState *fs, expdesc *e) { | |||
| 434 | } | 421 | } |
| 435 | 422 | ||
| 436 | 423 | ||
| 437 | static int code_label (FuncState *fs, int A, int b, int jump) { | ||
| 438 | luaK_getlabel(fs); /* those instructions may be jump targets */ | ||
| 439 | return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); | ||
| 440 | } | ||
| 441 | |||
| 442 | |||
| 443 | static void discharge2reg (FuncState *fs, expdesc *e, int reg) { | 424 | static void discharge2reg (FuncState *fs, expdesc *e, int reg) { |
| 444 | luaK_dischargevars(fs, e); | 425 | luaK_dischargevars(fs, e); |
| 445 | switch (e->k) { | 426 | switch (e->k) { |
| @@ -491,6 +472,25 @@ static void discharge2anyreg (FuncState *fs, expdesc *e) { | |||
| 491 | } | 472 | } |
| 492 | 473 | ||
| 493 | 474 | ||
| 475 | static int code_loadbool (FuncState *fs, int A, int b, int jump) { | ||
| 476 | luaK_getlabel(fs); /* those instructions may be jump targets */ | ||
| 477 | return luaK_codeABC(fs, OP_LOADBOOL, A, b, jump); | ||
| 478 | } | ||
| 479 | |||
| 480 | |||
| 481 | /* | ||
| 482 | ** check whether list has any jump that do not produce a value | ||
| 483 | ** (or produce an inverted value) | ||
| 484 | */ | ||
| 485 | static int need_value (FuncState *fs, int list) { | ||
| 486 | for (; list != NO_JUMP; list = getjump(fs, list)) { | ||
| 487 | Instruction i = *getjumpcontrol(fs, list); | ||
| 488 | if (GET_OPCODE(i) != OP_TESTSET) return 1; | ||
| 489 | } | ||
| 490 | return 0; /* not found */ | ||
| 491 | } | ||
| 492 | |||
| 493 | |||
| 494 | static void exp2reg (FuncState *fs, expdesc *e, int reg) { | 494 | static void exp2reg (FuncState *fs, expdesc *e, int reg) { |
| 495 | discharge2reg(fs, e, reg); | 495 | discharge2reg(fs, e, reg); |
| 496 | if (e->k == VJMP) | 496 | if (e->k == VJMP) |
| @@ -501,8 +501,8 @@ static void exp2reg (FuncState *fs, expdesc *e, int reg) { | |||
| 501 | int p_t = NO_JUMP; /* position of an eventual LOAD true */ | 501 | int p_t = NO_JUMP; /* position of an eventual LOAD true */ |
| 502 | if (need_value(fs, e->t) || need_value(fs, e->f)) { | 502 | if (need_value(fs, e->t) || need_value(fs, e->f)) { |
| 503 | int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); | 503 | int fj = (e->k == VJMP) ? NO_JUMP : luaK_jump(fs); |
| 504 | p_f = code_label(fs, reg, 0, 1); | 504 | p_f = code_loadbool(fs, reg, 0, 1); |
| 505 | p_t = code_label(fs, reg, 1, 0); | 505 | p_t = code_loadbool(fs, reg, 1, 0); |
| 506 | luaK_patchtohere(fs, fj); | 506 | luaK_patchtohere(fs, fj); |
| 507 | } | 507 | } |
| 508 | final = luaK_getlabel(fs); | 508 | final = luaK_getlabel(fs); |
