Update GaCy-GO
This commit is contained in:
1 parent
da8a32f60d
commit
0cbe460e49
345 files changed
+98202
-77559
No files matched your search
@@ -0,0 +1,92 @@
|
||||
"""Read version-4 Luau chunks without executing them.
|
||||
|
||||
Layout: upstream Luau VM/src/lvmload.cpp, Common/include/Luau/Bytecode.h.
|
||||
Only v4/type1 is accepted; later/custom layouts fail instead of guessing.
|
||||
"""
|
||||
import argparse
|
||||
import json
|
||||
import struct
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
def inspect(path):
|
||||
data = Path(path).read_bytes()
|
||||
offset = 0
|
||||
|
||||
def read(size):
|
||||
nonlocal offset
|
||||
value = data[offset:offset + size]
|
||||
if len(value) != size:
|
||||
raise ValueError('truncated chunk')
|
||||
offset += size
|
||||
return value
|
||||
|
||||
def byte():
|
||||
return read(1)[0]
|
||||
|
||||
def integer():
|
||||
value, shift = 0, 0
|
||||
while True:
|
||||
v = byte()
|
||||
value |= (v & 127) << shift
|
||||
if v < 128:
|
||||
return value
|
||||
shift += 7
|
||||
if shift > 28:
|
||||
raise ValueError('oversized integer')
|
||||
|
||||
if (byte(), byte()) != (4, 1):
|
||||
raise ValueError('only Luau v4/type1 supported')
|
||||
strings = [None] + [read(integer()).decode('utf-8', 'replace') for _ in range(integer())]
|
||||
protos = []
|
||||
for index in range(integer()):
|
||||
stack, params, upvalues, vararg, flags = [byte() for _ in range(5)]
|
||||
read(integer())
|
||||
code = [struct.unpack('<I', read(4))[0] for _ in range(integer())]
|
||||
constants = []
|
||||
for _ in range(integer()):
|
||||
kind = byte()
|
||||
if kind == 0:
|
||||
value = None
|
||||
elif kind == 1:
|
||||
value = bool(byte())
|
||||
elif kind == 2:
|
||||
value = struct.unpack('<d', read(8))[0]
|
||||
elif kind == 3:
|
||||
value = strings[integer()]
|
||||
elif kind == 4:
|
||||
value = {'import': struct.unpack('<I', read(4))[0]}
|
||||
elif kind == 5:
|
||||
value = {'table_keys': [integer() for _ in range(integer())]}
|
||||
elif kind == 6:
|
||||
value = {'closure': integer()}
|
||||
else:
|
||||
raise ValueError(f'unsupported constant {kind}')
|
||||
constants.append(value)
|
||||
children = [integer() for _ in range(integer())]
|
||||
line, name = integer(), strings[integer()]
|
||||
if byte():
|
||||
gap = byte()
|
||||
read(len(code))
|
||||
read((((len(code) - 1) >> gap) + 1) * 4)
|
||||
locals_ = []
|
||||
ups = []
|
||||
if byte():
|
||||
for _ in range(integer()):
|
||||
locals_.append([strings[integer()], integer(), integer(), byte()])
|
||||
ups = [strings[integer()] for _ in range(integer())]
|
||||
protos.append(dict(index=index, name=name, line=line, stack=stack,
|
||||
params=params, upvalues=ups, children=children,
|
||||
constants=constants, code=code, locals=locals_))
|
||||
main = integer()
|
||||
if offset != len(data):
|
||||
raise ValueError(f'unconsumed bytes: {len(data) - offset}')
|
||||
return dict(main=main, strings=strings, protos=protos)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument('path')
|
||||
parser.add_argument('--output', required=True)
|
||||
args = parser.parse_args()
|
||||
Path(args.output).write_text(json.dumps(inspect(args.path), indent=2, ensure_ascii=False), encoding='utf-8')
|
||||
Reference in new issue
Block a user