summaryrefslogtreecommitdiff
path: root/apps/plugins/lua/lcode.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/lua/lcode.c')
-rw-r--r--apps/plugins/lua/lcode.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/apps/plugins/lua/lcode.c b/apps/plugins/lua/lcode.c
index 07f9cbe4c4..18102d460e 100644
--- a/apps/plugins/lua/lcode.c
+++ b/apps/plugins/lua/lcode.c
@@ -784,8 +784,95 @@ void luaK_posfix (FuncState *fs, BinOpr op, expdesc *e1, expdesc *e2) {
784} 784}
785 785
786 786
787#ifdef LUA_OPTIMIZE_DEBUG
788/*
789 * Attempted to write to last (null terminator) byte of lineinfo, so need
790 * to grow the lineinfo vector and extend the fill bytes
791 */
792static unsigned char *growLineInfo(FuncState *fs) {
793 Proto *f = fs->f;
794 int start = (f->sizelineinfo > 0 ? f->sizelineinfo - 1 : 0);
795
796 unsigned char *p;
797
798 lua_assert(f->packedlineinfo==NULL || f->packedlineinfo[start] == '\0');
799
800 /* using the macro results in a redundant if test, but what the hell */
801 luaM_growvector(fs->L, f->packedlineinfo, f->sizelineinfo, f->sizelineinfo,
802 unsigned char, MAX_INT, "code size overflow");
803
804 p = &f->packedlineinfo[start];
805 memset(p, INFO_FILL_BYTE, f->sizelineinfo - start);
806 f->packedlineinfo[f->sizelineinfo - 1] = '\0';
807 return p;
808}
809
810
811static void generateInfoDeltaLine(FuncState *fs, int line) {
812 /* Handle first time through when lineinfo points is NULL */
813 unsigned char mask = INFO_DELTA_MASK;
814 unsigned char *p = fs->f->packedlineinfo ? lineInfoTop(fs) + 1 : growLineInfo(fs);
815#define addDLbyte(v) if (*p=='\0') p = growLineInfo(fs); *p++ = (v);
816 int delta = line - fs->lastline - 1;
817 if (delta != 0) {
818 if (delta < 0) {
819 delta = -delta;
820 mask |= INFO_SIGN_MASK;
821 }
822 delta -= 1;
823 mask |= (delta & INFO_DELTA_6BITS);
824 delta >>= 6;
825 addDLbyte(mask);
826
827 while (delta > 0) {
828 mask = INFO_DELTA_MASK | (delta & INFO_DELTA_7BITS);
829 delta >>= 7;
830 addDLbyte(mask);
831 }
832 }
833 addDLbyte(1);
834 fs->lastline = line;
835 fs->lastlineOffset = p - fs->f->packedlineinfo - 1;
836#undef addDLbyte
837}
838#endif
839
840
787void luaK_fixline (FuncState *fs, int line) { 841void luaK_fixline (FuncState *fs, int line) {
842#ifdef LUA_OPTIMIZE_DEBUG
843 /* The fixup line can be the same as existing one and in this case there's nothing to do */
844 if (line != fs->lastline) {
845 /* first remove the current line reference */
846 unsigned char *p = lineInfoTop(fs);
847 lua_assert(*p < 127);
848 if (*p >1) {
849 (*p)--; /* this is simply decrementing the last count a multi-PC line */
850 } else {
851 /* it's a bit more complicated if it's the 1st instruction on the line */
852 int delta = 0;
853 unsigned char code;
854 /* this logic handles <i/c> [1snnnnnnn [1nnnnnnn]*]? <i/c=1> */
855 *p-- = INFO_FILL_BYTE;
856 /* work backwards over the coded delta computing the delta */
857 while ((code=*p) & INFO_DELTA_MASK) {
858 *p-- = INFO_FILL_BYTE;
859 if (*p & INFO_DELTA_MASK) {
860 delta += ((code & INFO_DELTA_7BITS)<<7);
861 } else {
862 delta += (code & INFO_DELTA_6BITS) + 1;
863 if (code & INFO_SIGN_MASK) delta = -delta;
864 }
865 }
866 /* and reposition the FuncState lastline pointers at the previous instruction count */
867 fs->lastline-= delta + 1;
868 fs->lastlineOffset = p - fs->f->packedlineinfo;
869 }
870 /* Then add the new line reference */
871 generateInfoDeltaLine(fs, line);
872 }
873#else
788 fs->f->lineinfo[fs->pc - 1] = line; 874 fs->f->lineinfo[fs->pc - 1] = line;
875#endif
789} 876}
790 877
791 878
@@ -797,9 +884,25 @@ static int luaK_code (FuncState *fs, Instruction i, int line) {
797 MAX_INT, "code size overflow"); 884 MAX_INT, "code size overflow");
798 f->code[fs->pc] = i; 885 f->code[fs->pc] = i;
799 /* save corresponding line information */ 886 /* save corresponding line information */
887#ifdef LUA_OPTIMIZE_DEBUG
888 /* note that frst time fs->lastline==0 through, so the else branch is taken */
889 if (fs->pc == fs->lineinfoLastPC+1) {
890 if (line == fs->lastline && f->packedlineinfo[fs->lastlineOffset] < INFO_MAX_LINECNT) {
891 f->packedlineinfo[fs->lastlineOffset]++;
892 } else {
893 generateInfoDeltaLine(fs, line);
894 }
895 } else {
896 /* The last instruction is occasionally overwritten as part of branch optimisation*/
897 lua_assert(fs->pc == fs->lineinfoLastPC); /* panic if its anything other than this !! */
898 luaK_fixline(fs,line);
899 }
900 fs->lineinfoLastPC = fs->pc;
901#else
800 luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int, 902 luaM_growvector(fs->L, f->lineinfo, fs->pc, f->sizelineinfo, int,
801 MAX_INT, "code size overflow"); 903 MAX_INT, "code size overflow");
802 f->lineinfo[fs->pc] = line; 904 f->lineinfo[fs->pc] = line;
905#endif
803 return fs->pc++; 906 return fs->pc++;
804} 907}
805 908