diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,14 @@
 
 `lua` uses [PVP Versioning][].
 
+## lua-2.2.1
+
+Released 2022-06-19.
+
+-   Make string-peeking independent of the current foreign
+    encoding: always use char8 encoding to retrieve values of
+    `LUA_PRELOAD_TABLE` and `LUA_LOADED_TABLE`.
+
 ## lua-2.2.0
 
 Released 2022-02-19.
diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright © 1994-2020 Lua.org, PUC-Rio.
+Copyright © 1994-2022 Lua.org, PUC-Rio.
 Copyright © 2007-2012 Gracjan Polak
 Copyright © 2012-2015 Ömer Sinan Ağacan
 Copyright © 2016-2022 Albert Krewinkel
diff --git a/lua.cabal b/lua.cabal
--- a/lua.cabal
+++ b/lua.cabal
@@ -1,6 +1,6 @@
 cabal-version:       2.2
 name:                lua
-version:             2.2.0
+version:             2.2.1
 synopsis:            Lua, an embeddable scripting language
 description:         This package provides bindings and types to bridge
                      Haskell and <https://www.lua.org/ Lua>.
@@ -29,8 +29,8 @@
                    , GHC == 8.6.5
                    , GHC == 8.8.4
                    , GHC == 8.10.7
-                   , GHC == 9.0.1
-                   , GHC == 9.2.1
+                   , GHC == 9.0.2
+                   , GHC == 9.2.3
 
 source-repository head
   type:                git
diff --git a/src/Lua/Auxiliary.hs b/src/Lua/Auxiliary.hs
--- a/src/Lua/Auxiliary.hs
+++ b/src/Lua/Auxiliary.hs
@@ -38,7 +38,8 @@
 import Lua.Types as Lua
 import Foreign.Ptr
 import System.IO.Unsafe (unsafePerformIO)
-import qualified Foreign.C as C
+import qualified GHC.Foreign as GHC
+import qualified GHC.IO.Encoding as GHC
 
 #ifdef ALLOW_UNSAFE_GC
 #define SAFTY unsafe
@@ -50,7 +51,8 @@
 
 -- | Key, in the registry, for table of loaded modules.
 loadedTableRegistryField :: String
-loadedTableRegistryField = unsafePerformIO (C.peekCString c_loaded_table)
+loadedTableRegistryField = unsafePerformIO $ do
+  GHC.peekCString GHC.char8 c_loaded_table
 {-# NOINLINE loadedTableRegistryField #-}
 
 foreign import capi unsafe "lauxlib.h value LUA_LOADED_TABLE"
@@ -58,7 +60,8 @@
 
 -- | Key, in the registry, for table of preloaded loaders.
 preloadTableRegistryField :: String
-preloadTableRegistryField = unsafePerformIO (C.peekCString c_preload_table)
+preloadTableRegistryField = unsafePerformIO $ do
+  GHC.peekCString GHC.char8 c_preload_table
 {-# NOINLINE preloadTableRegistryField #-}
 
 foreign import capi unsafe "lauxlib.h value LUA_PRELOAD_TABLE"
diff --git a/src/Lua/Primary.hs b/src/Lua/Primary.hs
--- a/src/Lua/Primary.hs
+++ b/src/Lua/Primary.hs
@@ -30,6 +30,7 @@
   , lua_arith
   , lua_checkstack
   , lua_close
+  , lua_close_ptr
   , lua_concat
   , lua_copy
   , lua_createtable
@@ -188,6 +189,11 @@
 -- <https://www.lua.org/manual/5.4/manual.html#lua_close>
 foreign import capi safe "lua.h lua_close"
   lua_close :: Lua.State -> IO ()
+
+-- | Function pointer to function 'lua_close'; intended to be used with
+-- 'Foreign.ForeignPtr.newForeignPtr'.
+foreign import ccall safe "lua.h &lua_close"
+  lua_close_ptr :: FunPtr (Ptr () -> IO ())
 
 -- | Concatenates the @n@ values at the top of the stack, pops them, and
 -- leaves the result at the top. If @n@ is 1, the result is the single
