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 | ||