Skip to content

Problem with a table of functions defined within a table definition #11

@Jake-NotTheMuss

Description

@Jake-NotTheMuss

Issue

There seems to be a decompiler bug that I noticed in the file lua.Lobby.Common.LobbyCore. In this file, a table is defined like the following:

Lobby = {
	ProcessTree = nil,
	Navigation = {},
	Core = {},
	HANDLER_TYPE_FWD = 1,
	HANDLER_TYPE_BACK = 2,
	Core = function ( fromTarget, toTarget, handlerType, handler )
		if Lobby.Navigation[fromTarget.name] == nil then
			Lobby.Navigation[fromTarget.name] = {}
		end
		if Lobby.Navigation[fromTarget.name][handlerType] == nil then
			Lobby.Navigation[fromTarget.name][handlerType] = {}
		end
		Lobby.Navigation[fromTarget.name][handlerType][toTarget.name] = handler
	end,
	Core = function ( fromTarget, toTarget, handler )
		local handlerType = Lobby.HANDLER_TYPE_FWD
		if Lobby.Navigation[fromTarget.name] ~= nil and Lobby.Navigation[fromTarget.name][handlerType] ~= nil and Lobby.Navigation[fromTarget.name][handlerType][toTarget.name] ~= nil then
			error( "LobbyVM: A forward handler already exists from '" .. fromTarget.name .. " to " .. toTarget.name )
		end
		Lobby.Core.AddHandler( fromTarget, toTarget, handlerType, handler )
	end,

In this file, 6 functions are defined within the Lobby.Core table:

Lobby.Core.AddHandler = function(fromTarget, toTarget, handlerType, handler)
Lobby.Core.AddProcessForward = function(fromTarget, toTarget, handler)
Lobby.Core.AddProcessBack = function(fromTarget, toTarget, handler)
Lobby.Core.GetForwardProcessFunc = function(fromTarget, toTarget)
Lobby.Core.GetBackProcessFunc = function(fromTarget)
Lobby.Core.GetMainModeStr = function(mainMode)

In the decompilation, however, these functions are simply named "Core", overwriting the Core previously defined. Each function is simply defined in the form Core = function() ....

I also have a question about something within this same file that I can't find any answers to online.

Question

In the function Lobby.Core.GetBackProcessFunc(), there is a call to pairs():

if backNavTable ~= nil then
	local f5_local0, f5_local1, f5_local2 = pairs( backNavTable )
	local backMenuName, handler = f5_local0( f5_local1, f5_local2 )
	if backMenuName ~= nil then
		f5_local2 = backMenuName
		return LobbyData:UITargetFromName( backMenuName ), handler
	end
end

This snippet is taken from a decompilation of the beta version of the script. I am using the beta version to highlight the fact that certain variables do not have names and are therefore decompiler-generated. The current version of the same script decompiles the same way, resulting in an identical result, only without any variable names.

What I'm trying to figure out is what this function should look like in source. Since the 3 variables assigned after calling pairs() do not have names, in the source, the call to pairs() was not assigned immediately. It was part of a more complex expression, than assigned to the variables backMenuName and handler.

Having an extra parenthesis after the pairs() call would then call the 1st return value of pairs(), like the following:

local backMenuName, handler = pairs(backNavTable)()

But what I am confused about is how the 2nd and 3rd return value of pairs() were used as arguments to the second call. Could you enlighten me on this problem?

UPDATE 7/25/22: It seems this is caused by a for loop which returns or breaks unconditionally. I don't know if it's the compiler optimizing away the loop, or if its the decompiler not recognizing it as a loop. In any case, the source would probably looked like the following:

for backMenuName, handler in pairs(backNavTable) do
	return LobbyData:UITargetFromName(backMenuName), handler
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions