Skip to content

BETA | 1.9.9

Burkino edited this page Nov 5, 2019 · 1 revision

SX compile-time attributes - usage/info:

A (now) common problem in SX scripts is namecall issues - when doing a namecall hook, attempting to do another namecall can cause an infinite loop or corruption of the method name. Compile time attributes fix this issue at the compiler level.

local MT = getrawmetatable(game)
local OldNameCall = MT.__namecall
setreadonly(MT, false)

MT.__namecall = newcclosure(function(self, ...)
    local Method = getnamecallmethod()
    local Args = {...}

    if Method == "FireServer" then
        local Children = game:GetChildren() --this will cause corruption of the namecall method name!
        for i,v in pairs(Children) do pcall(function() warn(v) end) end
        print(Method, ...)
    end

    return OldNameCall(self, ...)
end)

setreadonly(MT, true)

With the nonamecall function attribute, this issue is fixed:

local MT = getrawmetatable(game)
local OldNameCall = MT.__namecall
setreadonly(MT, false)

MT.__namecall = newcclosure(function(self, ...) [nonamecall]
    local Method = getnamecallmethod()
    local Args = {...}

    if Method == "FireServer" then
        local Children = game:GetChildren() --now it wont!
        for i,v in pairs(Children) do pcall(function() warn(v) end) end
        print(Method, ...)
    end

    return OldNameCall(self, ...)
end)

setreadonly(MT, true)

This marker tells the compiler to not emit namecall accesses in the resulting function, allowing you to do whatever you want without fear of corrupting the method/causing an inf loop.

Note that compiler attributes are still in beta - we might change the syntax from [nonamecall] to <nonamecall> if users like it more. Please put any comments/things you guys might want from attributes in #beta-bugs-and-features.

The syntax itself is pretty simple - define the attribute right after defining the function itself. You cannot put any statements before the attributes.

Clone this wiki locally