serdataMetatable :: String     -- ^ name of the registered
                                      -- metatable which should be used.
                        -> Lua ()     -- ^ set additional properties; this
                                      -- operation will be called with the newly
                                      -- created metadata table at the top of
                                      -- the stack.
                        -> Lua ()
ensureUserdataMetatable name modMt = do
  mtCreated <- Lua.newmetatable name
  when mtCreated $ do
    -- Prevent accessing or changing the metatable with
    -- getmetatable/setmetatable.
    Lua.pushboolean True
    Lua.setfield (Lua.nthFromTop 2) "__metatable"
    -- Mark objects for finalization when collecting garbage.
    Lua.pushcfunction hslua_userdata_gc_ptr
    Lua.setfield (Lua.nthFromTop 2) "__gc"
    -- Execute additional modifications on metatable
    modMt

-- | Retrieve data which has been pushed with @'pushAny'@.
toAny 
ensureUserdataMetatable :: String     -- ^ name of the registered
                                      -- metatable which should be used.
                        -> Lua ()     -- ^ set additional properties; this
                                      -- operation will be called with the newly
                                      -- created metadata table at the top of
                                      -- the stack.
                        -> Lua ()
ensureUserdataMetatable name modMt = do
  mtCreated <- Lua.newmetatable name
  when mtCreated $ do
    -- Prevent accessing or changing the metatable with
    -- getmetatable/setmetatable.
    Lua.pushboolean True
    Lua.setfield (Lua.nthFromTop 2) "__metatable"
    -- Mark objects for finalization when collecting garbage.
    Lua.pushcfunction hslua_userdata_gc_ptr
    Lua.setfield (Lua.nthFromTop 2) "__gc"
    -- Execute additional modifications on metatable
    modMt

-- | Retrieve data which has been pushed with @'pushAny'@.
ensureUserdataMetatable name modMt = do
  mtCreated <- Lua.newmetatable name
  when mtCreated $ do
    -- Prevent accessing or changing the metatable with
    -- getmetatable/setmetatable.
    Lua.pushboolean True
    Lua.setfield (Lua.nthFromTop 2) "__metatable"
    -- Mark objects for finalization when collecting garbage.
    Lua.pushcfunction hslua_userdata_gc_ptr
    Lua.setfield (Lua.nthFromTop 2) "__gc"
    -- Execute additional modifications on metatable
    modMt

-- | Retrieve data which has been pushed with @'pushAny'@.