diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-09-13 16:50:08 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2017-09-13 16:50:08 -0300 |
| commit | 80d9b09f351c7a9be557116e9c79ae11e9b3f032 (patch) | |
| tree | a6ae7cce019e85c2f79987035c77d4e4213d07a9 /lcode.c | |
| parent | 029d269f4d1afd0e9ea0f889eb3e65a7f0fab0f9 (diff) | |
| download | lua-80d9b09f351c7a9be557116e9c79ae11e9b3f032.tar.gz lua-80d9b09f351c7a9be557116e9c79ae11e9b3f032.tar.bz2 lua-80d9b09f351c7a9be557116e9c79ae11e9b3f032.zip | |
jumps do not close upvalues (to be faster and simpler);
explicit instruction to close upvalues; command 'break' not
handled like a 'goto' (to optimize removal of uneeded 'close'
instructions)
Diffstat (limited to 'lcode.c')
| -rw-r--r-- | lcode.c | 51 |
1 files changed, 41 insertions, 10 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 2.120 2017/06/27 11:35:31 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.121 2017/06/29 15:06:44 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 | */ |
| @@ -272,20 +272,51 @@ void luaK_patchlist (FuncState *fs, int list, int target) { | |||
| 272 | 272 | ||
| 273 | 273 | ||
| 274 | /* | 274 | /* |
| 275 | ** Path all jumps in 'list' to close upvalues up to given 'level' | 275 | ** Check whether some jump in given list needs a close instruction. |
| 276 | ** (The assertion checks that jumps either were closing nothing | ||
| 277 | ** or were closing higher levels, from inner blocks.) | ||
| 278 | */ | 276 | */ |
| 279 | void luaK_patchclose (FuncState *fs, int list, int level) { | 277 | int luaK_needclose (FuncState *fs, int list) { |
| 280 | level++; /* argument is +1 to reserve 0 as non-op */ | ||
| 281 | for (; list != NO_JUMP; list = getjump(fs, list)) { | 278 | for (; list != NO_JUMP; list = getjump(fs, list)) { |
| 282 | lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP && | 279 | if (GETARG_A(fs->f->code[list])) /* needs close? */ |
| 283 | (GETARG_A(fs->f->code[list]) == 0 || | 280 | return 1; |
| 284 | GETARG_A(fs->f->code[list]) >= level)); | 281 | } |
| 285 | SETARG_A(fs->f->code[list], level); | 282 | return 0; |
| 283 | } | ||
| 284 | |||
| 285 | |||
| 286 | /* | ||
| 287 | ** Correct a jump list to jump to 'target'. If 'hasclose' is true, | ||
| 288 | ** 'target' contains an OP_CLOSE instruction (see first assert). | ||
| 289 | ** Only jumps with the A arg true need that close; other jumps | ||
| 290 | ** avoid it jumping to the next instruction. | ||
| 291 | */ | ||
| 292 | void luaK_patchgoto (FuncState *fs, int list, int target, int hasclose) { | ||
| 293 | lua_assert(!hasclose || GET_OPCODE(fs->f->code[target]) == OP_CLOSE); | ||
| 294 | while (list != NO_JUMP) { | ||
| 295 | int next = getjump(fs, list); | ||
| 296 | lua_assert(!GETARG_A(fs->f->code[list]) || hasclose); | ||
| 297 | patchtestreg(fs, list, NO_REG); /* do not generate values */ | ||
| 298 | if (!hasclose || GETARG_A(fs->f->code[list])) | ||
| 299 | fixjump(fs, list, target); | ||
| 300 | else /* there is a CLOSE instruction but jump does not need it */ | ||
| 301 | fixjump(fs, list, target + 1); /* avoid CLOSE instruction */ | ||
| 302 | list = next; | ||
| 286 | } | 303 | } |
| 287 | } | 304 | } |
| 288 | 305 | ||
| 306 | |||
| 307 | /* | ||
| 308 | ** Mark (using the A arg) all jumps in 'list' to close upvalues. Mark | ||
| 309 | ** will instruct 'luaK_patchgoto' to make these jumps go to OP_CLOSE | ||
| 310 | ** instructions. | ||
| 311 | */ | ||
| 312 | void luaK_patchclose (FuncState *fs, int list) { | ||
| 313 | for (; list != NO_JUMP; list = getjump(fs, list)) { | ||
| 314 | lua_assert(GET_OPCODE(fs->f->code[list]) == OP_JMP); | ||
| 315 | SETARG_A(fs->f->code[list], 1); | ||
| 316 | } | ||
| 317 | } | ||
| 318 | |||
| 319 | |||
| 289 | #if !defined(MAXIWTHABS) | 320 | #if !defined(MAXIWTHABS) |
| 290 | #define MAXIWTHABS 120 | 321 | #define MAXIWTHABS 120 |
| 291 | #endif | 322 | #endif |
