2015-06-09 1 views
6

Возможно ли получить размер функции в байтах, чтобы увидеть, соответствует ли она другой функции, аналогичной оператору C++ sizeof, или оценить две функции каким-либо другим способом, чтобы убедиться, что они равны, не зная, что функция/s находятся? Пример:Lua - Можно ли проверить, соответствуют ли 2 функции?

local function equals(func1, func2) 
    -- check them and return true if equal 
end 

Если это невозможно, просто скажите, и это удовлетворит мой ответ! Спасибо!

EDIT: Тело одной функции - это то, что мне нужно проверить, чтобы убедиться, что это то же самое, что и тело другой функции. Ссылка в памяти будет отличаться, поэтому я не могу использовать «==», но ссылочное имя функции может быть другим.

+0

Есть функция f (x) return x + 1 end' и 'function g (x) return x + 1 end' equal? –

+0

Да, и это сработает. Ключевая ссылка f и g на самом деле не имеет значения. Я просто искал способ проверить, равно ли тело. – Mayron

+1

Тогда это невозможно, если у вас нет источника. Функция может быть загружена из, например, байт-кода. –

ответ

5

Использование функций == для функций только проверяет, ссылаются ли они на одну и ту же функцию, чего вы не ожидали.

Эта задача довольно сложная, если вообще невозможная. Для очень простых случаев, вот идея:

function f(x) return x + 1 end 
local g = function(y) return y + 1 end 

f и g являются две функции, которые равны по вашему определению. Если предположить, что файл t.lua, запустите:

luac -l t.lua 

Выход:

main <t.lua:0,0> (4 instructions at 00000000003081c0) 
0+ params, 2 slots, 1 upvalue, 1 local, 1 constant, 2 functions 
     1  [1]  CLOSURE   0 0  ; 0000000000308330 
     2  [1]  SETTABUP  0 -1 0 ; _ENV "f" 
     3  [2]  CLOSURE   0 1  ; 0000000000308dc0 
     4  [2]  RETURN   0 1 

function <t.lua:1,1> (3 instructions at 0000000000308330) 
1 param, 2 slots, 0 upvalues, 1 local, 1 constant, 0 functions 
     1  [1]  ADD    1 0 -1 ; - 1 
     2  [1]  RETURN   1 2 
     3  [1]  RETURN   0 1 

function <t.lua:2,2> (3 instructions at 0000000000308dc0) 
1 param, 2 slots, 0 upvalues, 1 local, 1 constant, 0 functions 
     1  [2]  ADD    1 0 -1 ; - 1 
     2  [2]  RETURN   1 2 
     3  [2]  RETURN   0 1 

Как вы можете видеть, эти две функции имеют одни и те же инструкции в виртуальной машине.

+0

Благодарим вас за объяснение. Я думаю, это будет так близко, как я получу. Позор там проще, но мне нужно сделать это :) – Mayron

+2

Если доступ к байт-коду приближается к решению, есть [lbci] (http://webserver2.tecgraf.puc-rio.br/~lhf/ftp/lua/# lbci), библиотеку инспекторов байт-кода (для Lua 5.1 и 5.2, также устанавливаемую через LuaRocks), написанную @lhf, которая может предоставить вам ту же информацию, что и 'luac -l' выше. – siffiejoe

5

Будет ли сравнивать байт-код?

local function equals(func1, func2) 
    return string.dump(func1) == string.dump(func2) 
end 

Несомненно, были бы случаи, когда вышеизложенное не получится. Например:

local function f1 (...) 
    local a = print 
    a(...) 
end 

local function f2 (...) 
    print(...) 
end 


local function equals (f1, f2) 
    return string.dump(f1) == string.dump(f2) 
end 

print(equals(f1,f2)) --> false 

Обе функции выполняют одно и то же, но генерируют разные байт-коды. Возможно, если вы укажете, что вы пытаетесь достичь, может быть обеспечено лучшее решение, чем сравнение функций.

+0

Извините за медленный ответ. Я должен проверить, идентичны ли две таблицы, чтобы добавить только новые записи в одну таблицу, если они не отображаются в другой таблице, и я могу легко сравнить, действительно ли значение находится в другой таблице, но функции намного сложнее, так как == только сравнивает адреса памяти. – Mayron

+0

'string.dump' не сработает даже для этого:' function a() end' 'function b() end'' print (string.dump (a) == string.dump (b)) 'Выводит' false' , –

+0

Перед сопоставлением следует удалить информацию об отладке: 'string.dump (f1, true) == string.dump (f2, true)'. Он отлично работает на LuaJIT (но по какой-то причине не работает на Lua 5.3). –

Смежные вопросы