Incompatibility between Lua 5.1 and LuaJIT 2.0.

I realized an incompatibility issue between Lua 5.1 and LuaJIT 2.0.

This is the sample code that the issue appears.

f = function() return nil,nil,'string' end
t = { f() }
print('#table .. ' .. #t)
print('maxn   .. ' .. table.maxn(t))

Lua 5.1 result is

#table .. 3
maxn   .. 3

LuaJIT 2.0 result is

#table .. 0
maxn   .. 3

Other cases

A similar issue with preceding false and nil value.

f = function() return false,nil,'string' end
t = { f() }
print('#table .. ' .. #t)
print('maxn   .. ' .. table.maxn(t))

Lua 5.1 result is

#table .. 3
maxn   .. 3

LuaJIT 2.0 result is

#table .. 1
maxn   .. 3

No issue with preceding a nil value.

f = function() return nil,'string' end
t = { f() }
print('#table .. ' .. #t)
print('maxn   .. ' .. table.maxn(t))

Lua 5.1 result is

#table .. 2
maxn   .. 2

LuaJIT 2.0 result is

#table .. 2
maxn   .. 2

No issue with preceding 2 nils table initializer.

t = { nil,nil,'string' }
print('#table .. ' .. #t)
print('maxn   .. ' .. table.maxn(t))

Lua 5.1 result is

#table .. 3
maxn   .. 3

LuaJIT 2.0 result is

#table .. 3
maxn   .. 3

Problem in practice

For example, a function returns 2 values when it fails.

function fnc()
    ...
    if (failed)
      return nil, 'message'
    end

    return true
end

Wrapped this function to protect with pcall due to some reasons.

function fnc()
    return nil,'error message'
end

function fnc_safe()
    local result = { pcall(fnc) }
    local success = table.remove(result, 1)

    if success then
        -- no exception
        return unpack(result, 1, table.maxn(result))
    else
        -- catch an exception
        return nil,'exception raised.'
    end
end

local success,errmsg = fnc_safe()
if not success then
    print(errmsg)
end

Lua prints ‘error message’, but LuaJIT prints ‘nil’.

The problem is table.remove.
This code expected the result is an array table to decrease index number.
But the LuaJIT recognized the result is a non-array table.

Conclusion

I thought that it is better to return false and message string than nil and message string when a function was failed.
And it should be aware a table initialized with { function() }.
Perhaps the table is a non-array table on LuaJIT.

PS. Sorry for my poor English.

Leave a Reply

Your email address will not be published. Required fields are marked *