1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
local function num_args(func)
	local ok = pcall(function() string.dump(func) end)
	if not ok then return "?" end
	local dump = string.dump(func)
	--Set up the cursor
	local cursor = 1
	--Skip Header Stuff
	cursor = cursor + 12
	--Skip Source Name
	local offset = ReadInt(dump:sub(cursor, cursor + 4))
	cursor = cursor + 4
	local sourceName = dump:sub(cursor, cursor+offset)
	cursor = cursor + offset
	--Skip Line Defined
	cursor = cursor + 4
	--Skip Last Line Defined
	cursor = cursor + 4
	--Get the Upvalues
	local numUpvalues = dump:sub(cursor, cursor + 1):byte()
	cursor = cursor + 1
	--Get the Parameters
	local numParams = dump:sub(cursor, cursor + 1):byte()
	cursor = cursor + 1
	--Get the Variable-Args flag (whether there's a ... in the param)
	local varFlag = dump:sub(cursor, cursor + 1):byte()
	cursor = cursor + 1
	local ret = tostring(numParams)
	if varFlag > 1 then ret = ret .. "s" end
	return ret
end
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
local function get_args(func)
	local function _get_args(dump, cursor)
		--Set up the cursor
		if not cursor then
			cursor = 1
			--Skip Header Stuff
			cursor = cursor + 12
		end
		--Skip Source Name
		local offset = ReadInt(dump:sub(cursor, cursor + 4))
		cursor = cursor + 4
		local sourceName = dump:sub(cursor, cursor+offset)
		cursor = cursor + offset
		--Skip Line Defined
		cursor = cursor + 4
		--Skip Last Line Defined
		cursor = cursor + 4
		--Get the Upvalues
		local numUpvalues = dump:sub(cursor, cursor + 1):byte()
		cursor = cursor + 1
		--Get the Parameters
		local numParams = dump:sub(cursor, cursor + 1):byte()
		cursor = cursor + 1
		--Get the Variable-Args flag (whether there's a ... in the param)
		local varFlag = dump:sub(cursor, cursor + 1):byte()
		cursor = cursor + 1
		--Skip the Stacksizes
		cursor = cursor + 1
		--CODE:
		--~Skip the entire code...
		local offset = ReadInt(dump:sub(cursor, cursor + 4))
		cursor = cursor + 4
		cursor = cursor + offset*4
		--CONSTANTS:
		--~Skip the entire constant section...
		local offset = ReadInt(dump:sub(cursor, cursor + 4))
		cursor = cursor + 4
		for i=1,offset do
			local tp = dump:sub(cursor, cursor):byte()
			cursor = cursor + 1
			if tp == 1 then
				--Boolean
				local off = t(dump:sub(cursor, cursor):byte()
				cursor = cursor + 1
			elseif tp == 3 then
				--Number
				local off = ReadInt(dump:sub(cursor, cursor + 8))
				cursor = cursor + 8
			elseif tp == 4 then
				--String
				local off = ReadInt(dump:sub(cursor, cursor + 4))
				cursor = cursor + 4
				--print(dump:sub(cursor, cursor+off))
				cursor = cursor + off
			else
				-- Pass on nil
			end
		end
		--FUNCTIONS:
		--Reget...
		local offset = ReadInt(dump:sub(cursor, cursor + 4))
		cursor = cursor + 4
		for i=1, offset do
			local _
			_, cursor = _get_args(dump, cursor)
		end
		--LINES:
		--~Skip the entire Line section...
		local offset = ReadInt(dump:sub(cursor, cursor + 4))
		cursor = cursor + 4
		cursor = cursor + offset*4
		--LOCALS:
		--~Get Locals
		local offset = ReadInt(dump:sub(cursor, cursor + 4))
		cursor = cursor + 4
		local locals = {}
		local params = {}
		for i=1,offset do
			local off = ReadInt(dump:sub(cursor, cursor + 4))
			cursor = cursor + 4
			local varname = dump:sub(cursor, cursor+off)
			table.insert(locals,varname)
			if i <= numParams then table.insert(params,varname) end
			cursor = cursor + off
			cursor = cursor + 4
			cursor = cursor + 4
		end
		if varFlag > 1 then
			--table.insert(params, "...")
			params['...'] = true
		end
		--UPVALUES:
		--~Get Upvalues
		local offset = ReadInt(dump:sub(cursor, cursor + 4))
		cursor = cursor + 4
		for i=1,offset do
			local off = ReadInt(dump:sub(cursor, cursor + 4))
			cursor = cursor + 4
			cursor = cursor + off
		end
		return params, cursor
	end
	local ok = pcall(function() string.dump(func) end)
	if not ok then return {"..."} end
	local dump = string.dump(func)
	local ret = {_get_args(dump)}
	return ret[1]
end