@@ -12,23 +12,23 @@ local function LoadByte()
1212 return unpack " B"
1313end
1414
15- local function LoadInteger ()
16- return unpack " j"
17- end
18-
1915local function LoadNumber ()
2016 return unpack " n"
2117end
2218
2319local function LoadCharN (n )
24- return unpack (" c" .. tostring (n ))
20+ return unpack (" c" .. tostring (n ))
2521end
2622
2723local undump53 ; do
2824 local function LoadInt ()
2925 return unpack " i"
3026 end
3127
28+ local function LoadInteger ()
29+ return unpack " j"
30+ end
31+
3232 local function LoadString ()
3333 local size = LoadByte ()
3434 if size == 0xFF then
@@ -51,14 +51,17 @@ local undump53; do
5151 end
5252
5353 local function LoadConstants (f )
54- local LUA_TNIL = 0
54+ local function makevariant (t , v ) return t | (v << 4 ) end
55+ local LUA_TNIL = 0
5556 local LUA_TBOOLEAN = 1
56- local LUA_TNUMFLT = 3 | (0 << 4 )
57- local LUA_TNUMINT = 3 | (1 << 4 )
58- local LUA_TSHRSTR = 4 | (0 << 4 )
59- local LUA_TLNGSTR = 4 | (1 << 4 )
60- f .sizek = LoadInt ()
61- f .k = {}
57+ local LUA_TNUMBER = 3
58+ local LUA_TSTRING = 4
59+ local LUA_TNUMFLT = makevariant (LUA_TNUMBER , 0 )
60+ local LUA_TNUMINT = makevariant (LUA_TNUMBER , 1 )
61+ local LUA_TSHRSTR = makevariant (LUA_TSTRING , 0 )
62+ local LUA_TLNGSTR = makevariant (LUA_TSTRING , 1 )
63+ f .sizek = LoadInt ()
64+ f .k = {}
6265 for i = 1 , f .sizek do
6366 local t = LoadByte ()
6467 if t == LUA_TNIL then
@@ -73,7 +76,7 @@ local undump53; do
7376 elseif t == LUA_TLNGSTR then
7477 f .k [i ] = LoadString ()
7578 else
76- error (" unknown type: " .. t )
79+ error (string.format ( " unknown constant type: <%d, %d> " , t >> 4 , t & 0xf ) )
7780 end
7881 end
7982 end
@@ -112,6 +115,9 @@ local undump53; do
112115 f .locvars [i ].endpc = LoadInt ()
113116 end
114117 local n = LoadInt ()
118+ if n ~= 0 then
119+ n = f .sizeupvalues
120+ end
115121 for i = 1 , n do
116122 f .upvalues [i ].name = LoadString ()
117123 end
@@ -138,8 +144,6 @@ local undump53; do
138144 local function CheckHeader ()
139145 local LUAC_INT = 0x5678
140146 local LUAC_NUM = 370.5
141- assert (LoadByte () == 0 )
142- assert (LoadCharN (6 ) == " \x19\x93 \r\n \x1a \n " )
143147 -- int
144148 assert (string.packsize " i" == LoadByte ())
145149 -- size_t
@@ -163,13 +167,17 @@ local undump53; do
163167end
164168
165169local undump54 ; do
170+ local function LoadInteger ()
171+ return unpack " j"
172+ end
173+
166174 local function LoadUnsigned (limit )
167175 local b
168176 local x = 0
169177 limit = limit >> 7
170178 repeat
171179 b = LoadByte ()
172- if x >= limit then
180+ if x > limit then
173181 error (" integer overflow" )
174182 end
175183 x = (x << 7 ) | (b & 0x7f )
@@ -228,7 +236,7 @@ local undump54; do
228236 elseif t == LUA_VSHRSTR or t == LUA_VLNGSTR then
229237 f .k [i ] = LoadString ()
230238 else
231- error (" unknown type: " .. t )
239+ error (string.format ( " unknown constant type: <%d, %d> " , t >> 4 , t & 0xf ) )
232240 end
233241 end
234242 end
@@ -275,6 +283,9 @@ local undump54; do
275283 f .locvars [i ].endpc = LoadInt ()
276284 end
277285 local n = LoadInt ()
286+ if n ~= 0 then
287+ n = f .sizeupvalues
288+ end
278289 for i = 1 , n do
279290 f .upvalues [i ].name = LoadString ()
280291 end
@@ -301,8 +312,6 @@ local undump54; do
301312 local function CheckHeader ()
302313 local LUAC_INT = 0x5678
303314 local LUAC_NUM = 370.5
304- assert (LoadByte () == 0 )
305- assert (LoadCharN (6 ) == " \x19\x93 \r\n \x1a \n " )
306315 -- Instruction
307316 assert (string.packsize " i4" == LoadByte ())
308317 -- lua_Integer
@@ -321,16 +330,213 @@ local undump54; do
321330 end
322331end
323332
324- return function (bytes )
333+ local undump55 ; do
334+ local cached = {}
335+
336+ local function LoadAlign (align )
337+ local padding = align - (unpack_pos - 1 ) % align
338+ if padding < align then
339+ unpack_pos = unpack_pos + padding
340+ assert ((unpack_pos - 1 ) % align == 0 )
341+ end
342+ end
343+
344+ local function LoadUnsigned (limit )
345+ local b
346+ local x = 0
347+ limit = limit >> 7
348+ repeat
349+ b = LoadByte ()
350+ if x > limit then
351+ error (" integer overflow" )
352+ end
353+ x = (x << 7 ) | (b & 0x7f )
354+ until ((b & 0x80 ) == 0 )
355+ return x
356+ end
357+
358+ local function LoadInteger ()
359+ local cx = LoadUnsigned (math.maxinteger )
360+ if (cx & 1 ) ~= 0 then
361+ return ~(cx >> 1 )
362+ else
363+ return cx >> 1
364+ end
365+ end
366+
367+ local function LoadInt ()
368+ return LoadUnsigned (0x7fffffff )
369+ end
370+
371+ local function LoadString ()
372+ local size = LoadUnsigned (math.maxinteger )
373+ if size == 0 then
374+ return nil
375+ end
376+ if size == 1 then
377+ local idx = LoadUnsigned (math.maxinteger )
378+ if not cached [idx ] then
379+ error (" invalid string index" )
380+ end
381+ return cached [idx ]
382+ end
383+ local str = LoadCharN (size - 1 )
384+ cached [# cached + 1 ] = str
385+ return str
386+ end
387+
388+ local LoadFunction
389+
390+ local function LoadCode (f )
391+ f .sizecode = LoadInt ()
392+ LoadAlign (4 )
393+ f .code = {}
394+ for i = 1 , f .sizecode do
395+ f .code [i ] = unpack " i4"
396+ end
397+ end
398+
399+ local function LoadConstants (f )
400+ local function makevariant (t , v ) return t | (v << 4 ) end
401+ local LUA_TNIL = 0
402+ local LUA_TBOOLEAN = 1
403+ local LUA_TNUMBER = 3
404+ local LUA_TSTRING = 4
405+ local LUA_VNIL = makevariant (LUA_TNIL , 0 )
406+ local LUA_VFALSE = makevariant (LUA_TBOOLEAN , 0 )
407+ local LUA_VTRUE = makevariant (LUA_TBOOLEAN , 1 )
408+ local LUA_VNUMINT = makevariant (LUA_TNUMBER , 0 )
409+ local LUA_VNUMFLT = makevariant (LUA_TNUMBER , 1 )
410+ local LUA_VSHRSTR = makevariant (LUA_TSTRING , 0 )
411+ local LUA_VLNGSTR = makevariant (LUA_TSTRING , 1 )
412+ f .sizek = LoadInt ()
413+ f .k = {}
414+ for i = 1 , f .sizek do
415+ local t = LoadByte ()
416+ if t == LUA_VNIL then
417+ elseif t == LUA_VTRUE then
418+ f .k [i ] = true
419+ elseif t == LUA_VFALSE then
420+ f .k [i ] = false
421+ elseif t == LUA_VNUMFLT then
422+ f .k [i ] = LoadNumber ()
423+ elseif t == LUA_VNUMINT then
424+ f .k [i ] = LoadInteger ()
425+ elseif t == LUA_VSHRSTR or t == LUA_VLNGSTR then
426+ f .k [i ] = LoadString ()
427+ else
428+ error (string.format (" unknown constant type: <%d, %d>" , t >> 4 , t & 0xf ))
429+ end
430+ end
431+ end
432+
433+ local function LoadUpvalues (f )
434+ f .sizeupvalues = LoadInt ()
435+ f .upvalues = {}
436+ for i = 1 , f .sizeupvalues do
437+ f .upvalues [i ] = {}
438+ f .upvalues [i ].instack = LoadByte ()
439+ f .upvalues [i ].idx = LoadByte ()
440+ f .upvalues [i ].kind = LoadByte ()
441+ end
442+ end
443+
444+ local function LoadProtos (f )
445+ f .sizep = LoadInt ()
446+ f .p = {}
447+ for i = 1 , f .sizep do
448+ f .p [i ] = {}
449+ LoadFunction (f .p [i ], f .source )
450+ end
451+ end
452+
453+ local function LoadDebug (f )
454+ f .sizelineinfo = LoadInt ()
455+ f .lineinfo = {}
456+ for i = 1 , f .sizelineinfo do
457+ f .lineinfo [i ] = unpack " b"
458+ end
459+ f .sizeabslineinfo = LoadInt ()
460+ f .abslineinfo = {}
461+ if f .sizeabslineinfo > 0 then
462+ LoadAlign (4 )
463+ for i = 1 , f .sizeabslineinfo do
464+ f .abslineinfo [i ] = {}
465+ f .abslineinfo [i ].pc = unpack " i"
466+ f .abslineinfo [i ].line = unpack " i"
467+ end
468+ end
469+ f .sizelocvars = LoadInt ()
470+ f .locvars = {}
471+ for i = 1 , f .sizelocvars do
472+ f .locvars [i ] = {}
473+ f .locvars [i ].varname = LoadString ()
474+ f .locvars [i ].startpc = LoadInt ()
475+ f .locvars [i ].endpc = LoadInt ()
476+ end
477+ local n = LoadInt ()
478+ if n ~= 0 then
479+ n = f .sizeupvalues
480+ end
481+ for i = 1 , n do
482+ f .upvalues [i ].name = LoadString ()
483+ end
484+ end
485+
486+ function LoadFunction (f , psource )
487+ f .linedefined = LoadInt ()
488+ f .lastlinedefined = LoadInt ()
489+ f .numparams = LoadByte ()
490+ f .is_vararg = LoadByte () & 1
491+ f .maxstacksize = LoadByte ()
492+ LoadCode (f )
493+ LoadConstants (f )
494+ LoadUpvalues (f )
495+ LoadProtos (f )
496+ f .source = LoadString ()
497+ if not f .source then
498+ f .source = psource
499+ end
500+ LoadDebug (f )
501+ return f
502+ end
503+
504+ local function CheckHeader ()
505+ local LUAC_INT = - 0x5678
506+ local LUAC_INST = 0x12345678
507+ local LUAC_NUM = - 370.5
508+ assert (string.packsize " i" == LoadByte ())
509+ assert (unpack " i" == LUAC_INT )
510+ assert (string.packsize " i4" == LoadByte ())
511+ assert (unpack " i4" == LUAC_INST )
512+ assert (string.packsize " j" == LoadByte ())
513+ assert (unpack " j" == LUAC_INT )
514+ assert (string.packsize " n" == LoadByte ())
515+ assert (unpack " n" == LUAC_NUM )
516+ end
517+
518+ function undump55 (cl )
519+ CheckHeader ()
520+ cl .nupvalues = LoadByte ()
521+ cl .f = {}
522+ LoadFunction (cl .f , nil )
523+ end
524+ end
525+
526+ return function (bytes )
325527 unpack_pos = 1
326528 unpack_buf = bytes
327529 assert (LoadCharN (4 ) == " \x1b Lua" )
328530 local Version = LoadByte ()
531+ assert (LoadByte () == 0 )
532+ assert (LoadCharN (6 ) == " \x19\x93 \r\n \x1a \n " )
329533 local cl = {}
330534 if Version == 0x53 then
331535 undump53 (cl )
332536 elseif Version == 0x54 then
333537 undump54 (cl )
538+ elseif Version == 0x55 then
539+ undump55 (cl )
334540 else
335541 error ((" unknown lua version: 0x%x" ):format (Version ))
336542 end
0 commit comments