Skip to content

Instantly share code, notes, and snippets.

@JustAPerson
Forked from SunsetTech/args.lua
Created April 4, 2012 22:12
Show Gist options
  • Save JustAPerson/2306070 to your computer and use it in GitHub Desktop.
Save JustAPerson/2306070 to your computer and use it in GitHub Desktop.
Number of arguments in function -- Extended with number of upvalues
function int(t)
return t:byte(1)+t:byte(2)*0x100+t:byte(3)*0x10000+t:byte(4)*0x1000000
end
function num_args(func)
local ok, dump = pcall(string.dump,func)
if (not ok) then return -1 end
local cursor = 13
local offset = int(dump:sub(cursor))
cursor = cursor + offset + 13
--Get the Parameters
local params= dump:sub(cursor):byte()
cursor = cursor + 1
--Get the Variable Args flag (whether there's a ... in the param)
local varargs= dump:sub(cursor):byte()
return params, varargs
end
-- Usage:
num_args(function(a,b,c,d, ...) end) -- return 4, 7
--
-- Saw this gist today and remembered the following code I partially wrote for someone just a few days ago
--
function has_upvalues(func) -- cross platform by the way
local dump = ("").dump(func); -- pretty nice, eh?
local int_len,size_t_len = dump:byte(8,9)
local bytes = {dump:byte(13, 12+size_t_len)}; -- get integer size of the name string
local name_len = bytes[1]
for i=2,#bytes do -- decode the integer
name_len = name_len + bytes[i]*(256^(i-1)-1)
end
local upvalue_position = 12 + size_t_len + (name_len > 0 and 1 or 0) + name_len + int_len + int_len;
local number_upvalues = dump:byte(upvalue_position); -- return the number of upvalues
return number_upvalues > 0, number_upvalues;
end
-- usage:
local a, b;
local f0, f1, f2 = function() end,
function() return a; end,
function() return a, b; end
has_upvalues(f0) --> returns false, 0
has_upvalues(f1) --> returns true, 1
has_upvalues(f2) --> returns true, 2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment