aboutsummaryrefslogtreecommitdiff
path: root/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'lcode.c')
-rw-r--r--lcode.c76
1 files changed, 53 insertions, 23 deletions
diff --git a/lcode.c b/lcode.c
index ab91561c..d00038dd 100644
--- a/lcode.c
+++ b/lcode.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lcode.c,v 2.160 2018/03/16 14:22:09 roberto Exp roberto $ 2** $Id: lcode.c $
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*/
@@ -309,10 +309,19 @@ void luaK_patchclose (FuncState *fs, int list) {
309} 309}
310 310
311 311
312/*
313** MAXimum number of successive Instructions WiTHout ABSolute line
314** information.
315*/
312#if !defined(MAXIWTHABS) 316#if !defined(MAXIWTHABS)
313#define MAXIWTHABS 120 317#define MAXIWTHABS 120
314#endif 318#endif
315 319
320
321/* limit for difference between lines in relative line info. */
322#define LIMLINEDIFF 0x80
323
324
316/* 325/*
317** Save line info for a new instruction. If difference from last line 326** Save line info for a new instruction. If difference from last line
318** does not fit in a byte, of after that many instructions, save a new 327** does not fit in a byte, of after that many instructions, save a new
@@ -320,14 +329,15 @@ void luaK_patchclose (FuncState *fs, int list) {
320** in 'lineinfo' signals the existence of this absolute information.) 329** in 'lineinfo' signals the existence of this absolute information.)
321** Otherwise, store the difference from last line in 'lineinfo'. 330** Otherwise, store the difference from last line in 'lineinfo'.
322*/ 331*/
323static void savelineinfo (FuncState *fs, Proto *f, int pc, int line) { 332static void savelineinfo (FuncState *fs, Proto *f, int line) {
324 int linedif = line - fs->previousline; 333 int linedif = line - fs->previousline;
325 if (abs(linedif) >= 0x80 || fs->iwthabs++ > MAXIWTHABS) { 334 int pc = fs->pc - 1; /* last instruction coded */
335 if (abs(linedif) >= LIMLINEDIFF || fs->iwthabs++ > MAXIWTHABS) {
326 luaM_growvector(fs->ls->L, f->abslineinfo, fs->nabslineinfo, 336 luaM_growvector(fs->ls->L, f->abslineinfo, fs->nabslineinfo,
327 f->sizeabslineinfo, AbsLineInfo, MAX_INT, "lines"); 337 f->sizeabslineinfo, AbsLineInfo, MAX_INT, "lines");
328 f->abslineinfo[fs->nabslineinfo].pc = pc; 338 f->abslineinfo[fs->nabslineinfo].pc = pc;
329 f->abslineinfo[fs->nabslineinfo++].line = line; 339 f->abslineinfo[fs->nabslineinfo++].line = line;
330 linedif = ABSLINEINFO; /* signal there is absolute information */ 340 linedif = ABSLINEINFO; /* signal that there is absolute information */
331 fs->iwthabs = 0; /* restart counter */ 341 fs->iwthabs = 0; /* restart counter */
332 } 342 }
333 luaM_growvector(fs->ls->L, f->lineinfo, pc, f->sizelineinfo, ls_byte, 343 luaM_growvector(fs->ls->L, f->lineinfo, pc, f->sizelineinfo, ls_byte,
@@ -338,6 +348,37 @@ static void savelineinfo (FuncState *fs, Proto *f, int pc, int line) {
338 348
339 349
340/* 350/*
351** Remove line information from the last instruction.
352** If line information for that instruction is absolute, set 'iwthabs'
353** above its max to force the new (replacing) instruction to have
354** absolute line info, too.
355*/
356static void removelastlineinfo (FuncState *fs) {
357 Proto *f = fs->f;
358 int pc = fs->pc - 1; /* last instruction coded */
359 if (f->lineinfo[pc] != ABSLINEINFO) { /* relative line info? */
360 fs->previousline -= f->lineinfo[pc]; /* last line saved */
361 fs->iwthabs--;
362 }
363 else { /* absolute line information */
364 fs->nabslineinfo--; /* remove it */
365 lua_assert(f->abslineinfo[fs->nabslineinfo].pc = pc);
366 fs->iwthabs = MAXIWTHABS + 1; /* force next line info to be absolute */
367 }
368}
369
370
371/*
372** Remove the last instruction created, correcting line information
373** accordingly.
374*/
375static void removelastinstruction (FuncState *fs) {
376 removelastlineinfo(fs);
377 fs->pc--;
378}
379
380
381/*
341** Emit instruction 'i', checking for array sizes and saving also its 382** Emit instruction 'i', checking for array sizes and saving also its
342** line information. Return 'i' position. 383** line information. Return 'i' position.
343*/ 384*/
@@ -346,9 +387,9 @@ static int luaK_code (FuncState *fs, Instruction i) {
346 /* put new instruction in code array */ 387 /* put new instruction in code array */
347 luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction, 388 luaM_growvector(fs->ls->L, f->code, fs->pc, f->sizecode, Instruction,
348 MAX_INT, "opcodes"); 389 MAX_INT, "opcodes");
349 f->code[fs->pc] = i; 390 f->code[fs->pc++] = i;
350 savelineinfo(fs, f, fs->pc, fs->ls->lastline); 391 savelineinfo(fs, f, fs->ls->lastline);
351 return fs->pc++; 392 return fs->pc - 1; /* index of new instruction */
352} 393}
353 394
354 395
@@ -986,7 +1027,7 @@ static int jumponcond (FuncState *fs, expdesc *e, int cond) {
986 if (e->k == VRELOC) { 1027 if (e->k == VRELOC) {
987 Instruction ie = getinstruction(fs, e); 1028 Instruction ie = getinstruction(fs, e);
988 if (GET_OPCODE(ie) == OP_NOT) { 1029 if (GET_OPCODE(ie) == OP_NOT) {
989 fs->pc--; /* remove previous OP_NOT */ 1030 removelastinstruction(fs); /* remove previous OP_NOT */
990 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond); 1031 return condjump(fs, OP_TEST, GETARG_B(ie), 0, !cond);
991 } 1032 }
992 /* else go through */ 1033 /* else go through */
@@ -1572,23 +1613,12 @@ void luaK_posfix (FuncState *fs, BinOpr opr,
1572 1613
1573 1614
1574/* 1615/*
1575** Change line information associated with current position. If that 1616** Change line information associated with current position, by removing
1576** information is absolute, just change it and correct 'previousline'. 1617** previous info and adding it again with new line.
1577** Otherwise, restore 'previousline' to its value before saving the
1578** current position and than saves the line information again, with the
1579** new line.
1580*/ 1618*/
1581void luaK_fixline (FuncState *fs, int line) { 1619void luaK_fixline (FuncState *fs, int line) {
1582 Proto *f = fs->f; 1620 removelastlineinfo(fs);
1583 if (f->lineinfo[fs->pc - 1] == ABSLINEINFO) { 1621 savelineinfo(fs, fs->f, line);
1584 lua_assert(f->abslineinfo[fs->nabslineinfo - 1].pc == fs->pc - 1);
1585 f->abslineinfo[fs->nabslineinfo - 1].line = line;
1586 fs->previousline = line;
1587 }
1588 else {
1589 fs->previousline -= f->lineinfo[fs->pc - 1]; /* undo previous info. */
1590 savelineinfo(fs, f, fs->pc - 1, line); /* redo it */
1591 }
1592} 1622}
1593 1623
1594 1624