diff options
Diffstat (limited to 'lcode.c')
| -rw-r--r-- | lcode.c | 52 |
1 files changed, 45 insertions, 7 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lcode.c,v 2.118 2017/04/28 20:57:45 roberto Exp roberto $ | 2 | ** $Id: lcode.c,v 2.119 2017/05/18 19:44:19 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 | */ |
| @@ -10,6 +10,7 @@ | |||
| 10 | #include "lprefix.h" | 10 | #include "lprefix.h" |
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | #include <limits.h> | ||
| 13 | #include <math.h> | 14 | #include <math.h> |
| 14 | #include <stdlib.h> | 15 | #include <stdlib.h> |
| 15 | 16 | ||
| @@ -285,6 +286,33 @@ void luaK_patchclose (FuncState *fs, int list, int level) { | |||
| 285 | } | 286 | } |
| 286 | } | 287 | } |
| 287 | 288 | ||
| 289 | #if !defined(MAXIWTHABS) | ||
| 290 | #define MAXIWTHABS 120 | ||
| 291 | #endif | ||
| 292 | |||
| 293 | /* | ||
| 294 | ** Save line info for a new instruction. If difference from last line | ||
| 295 | ** does not fit in a byte, of after that many instructions, save a new | ||
| 296 | ** absolute line info; (in that case, the special value 'ABSLINEINFO' | ||
| 297 | ** in 'lineinfo' signals the existence of this absolute information.) | ||
| 298 | ** Otherwise, store the difference from last line in 'lineinfo'. | ||
| 299 | */ | ||
| 300 | static void savelineinfo (FuncState *fs, Proto *f, int pc, int line) { | ||
| 301 | int linedif = line - fs->previousline; | ||
| 302 | if (abs(linedif) >= 0x80 || fs->iwthabs++ > MAXIWTHABS) { | ||
| 303 | luaM_growvector(fs->ls->L, f->abslineinfo, fs->nabslineinfo, | ||
| 304 | f->sizeabslineinfo, AbsLineInfo, MAX_INT, "lines"); | ||
| 305 | f->abslineinfo[fs->nabslineinfo].pc = pc; | ||
| 306 | f->abslineinfo[fs->nabslineinfo++].line = line; | ||
| 307 | linedif = ABSLINEINFO; /* signal there is absolute information */ | ||
| 308 | fs->iwthabs = 0; /* restart counter */ | ||
| 309 | } | ||
| 310 | luaM_growvector(fs->ls->L, f->lineinfo, pc, f->sizelineinfo, ls_byte, | ||
| 311 | MAX_INT, "opcodes"); | ||
| 312 | f->lineinfo[pc] = linedif; | ||
| 313 | fs->previousline = line; /* last line saved */ | ||
| 314 | } | ||
| 315 | |||
| 288 | 316 | ||
| 289 | /* | 317 | /* |
| 290 | ** Emit instruction 'i', checking for array sizes and saving also its | 318 | ** Emit instruction 'i', checking for array sizes and saving also its |
| @@ -297,10 +325,7 @@ static int luaK_code (FuncState *fs, Instruction i) { | |||
| 297 | luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, | 325 | luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, |
| 298 | MAX_INT, "opcodes"); | 326 | MAX_INT, "opcodes"); |
| 299 | f->code[fs->pc] = i; | 327 | f->code[fs->pc] = i; |
| 300 | /* save corresponding line information */ | 328 | savelineinfo(fs, f, fs->pc, fs->ls->lastline); |
| 301 | luaM_growvector(fs->ls->L, f->lineinfo, fs->pc, f->sizelineinfo, int, | ||
| 302 | MAX_INT, "opcodes"); | ||
| 303 | f->lineinfo[fs->pc] = fs->ls->lastline; | ||
| 304 | return fs->pc++; | 329 | return fs->pc++; |
| 305 | } | 330 | } |
| 306 | 331 | ||
| @@ -1260,10 +1285,23 @@ void luaK_posfix (FuncState *fs, BinOpr op, | |||
| 1260 | 1285 | ||
| 1261 | 1286 | ||
| 1262 | /* | 1287 | /* |
| 1263 | ** Change line information associated with current position. | 1288 | ** Change line information associated with current position. If that |
| 1289 | ** information is absolute, just change it and correct 'previousline'. | ||
| 1290 | ** Otherwise, restore 'previousline' to its value before saving the | ||
| 1291 | ** current position and than saves the line information again, with the | ||
| 1292 | ** new line. | ||
| 1264 | */ | 1293 | */ |
| 1265 | void luaK_fixline (FuncState *fs, int line) { | 1294 | void luaK_fixline (FuncState *fs, int line) { |
| 1266 | fs->f->lineinfo[fs->pc - 1] = line; | 1295 | Proto *f = fs->f; |
| 1296 | if (f->lineinfo[fs->pc - 1] == ABSLINEINFO) { | ||
| 1297 | lua_assert(f->abslineinfo[fs->nabslineinfo - 1].pc == fs->pc - 1); | ||
| 1298 | f->abslineinfo[fs->nabslineinfo - 1].line = line; | ||
| 1299 | fs->previousline = line; | ||
| 1300 | } | ||
| 1301 | else { | ||
| 1302 | fs->previousline -= f->lineinfo[fs->pc - 1]; /* undo previous info. */ | ||
| 1303 | savelineinfo(fs, f, fs->pc - 1, line); /* redo it */ | ||
| 1304 | } | ||
| 1267 | } | 1305 | } |
| 1268 | 1306 | ||
| 1269 | 1307 | ||
