aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c52
1 files changed, 45 insertions, 7 deletions
diff --git a/lcode.c b/lcode.c
index 2d396000..740cf564 100644
--- a/lcode.c
+++ b/lcode.c
@@ -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*/
300static 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*/
1265void luaK_fixline (FuncState *fs, int line) { 1294void 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