aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJosh Rahm <joshuarahm@gmail.com>2024-02-11 17:47:02 -0700
committerJosh Rahm <joshuarahm@gmail.com>2024-02-11 17:51:21 -0700
commitd1ef7fab6edb3550f46f65803fe53f027cfb5dd8 (patch)
treef9970803b67751490486a1d1c84a01bebee350ba /src
parenta0f290b2e82e1331f4f932042dcdbc7d919a374f (diff)
downloadwetterhorn-d1ef7fab6edb3550f46f65803fe53f027cfb5dd8.tar.gz
wetterhorn-d1ef7fab6edb3550f46f65803fe53f027cfb5dd8.tar.bz2
wetterhorn-d1ef7fab6edb3550f46f65803fe53f027cfb5dd8.zip
Change up a lot of stuff.
Add more functions to the plugin interface and write some generators to generate an interface header file and the plugin's loading code.
Diffstat (limited to 'src')
-rw-r--r--src/Wetterhorn/Core.hs26
-rw-r--r--src/Wetterhorn/FFI.hs55
-rw-r--r--src/harness_adapter.c21
3 files changed, 75 insertions, 27 deletions
diff --git a/src/Wetterhorn/Core.hs b/src/Wetterhorn/Core.hs
index 5ce93f0..e04cb49 100644
--- a/src/Wetterhorn/Core.hs
+++ b/src/Wetterhorn/Core.hs
@@ -11,14 +11,18 @@ module Wetterhorn.Core
initWetterhorn,
wio,
incrementState,
+ readWState,
)
where
-import Control.Applicative
import Control.Arrow (first)
-import Foreign (StablePtr, deRefStablePtr, freeStablePtr, newStablePtr)
+import Control.Exception
+import Data.ByteString (ByteString)
+import qualified Data.ByteString.Char8 as CH
+import Foreign (StablePtr, newStablePtr)
-type Wetterhorn = (StablePtr (WConfig, WState))
+-- This is this opaque state presented to the harness.
+type Wetterhorn = StablePtr (WConfig, WState)
initWetterhorn :: WConfig -> IO Wetterhorn
initWetterhorn conf = do
@@ -28,20 +32,20 @@ data WState = WState
{ someString :: String,
integer :: Int
}
+ deriving (Show, Read)
data WConfig = WConfig
{ someConfig :: String,
handleSomething :: W ()
}
-foreign export ccall handle_thing :: StablePtr (WConfig, WState) -> IO (StablePtr (WConfig, WState))
-
-handle_thing :: StablePtr (WConfig, WState) -> IO (StablePtr (WConfig, WState))
-handle_thing ptr = do
- (conf, st) <- deRefStablePtr ptr
- (_, st') <- runW (handleSomething conf) (conf, st)
- newStablePtr (conf, st')
- <* freeStablePtr ptr
+readWState :: ByteString -> IO WState
+readWState bs =
+ catch
+ (return $ read (CH.unpack bs))
+ ( \e ->
+ let _ = (e :: SomeException) in return (WState "" 0)
+ )
newtype W a = W ((WConfig, WState) -> IO (a, WState))
diff --git a/src/Wetterhorn/FFI.hs b/src/Wetterhorn/FFI.hs
new file mode 100644
index 0000000..c27c129
--- /dev/null
+++ b/src/Wetterhorn/FFI.hs
@@ -0,0 +1,55 @@
+-- | This module does not export anything. It exists simply to provide C-symbols
+-- for the plugin.
+module Wetterhorn.FFI() where
+
+import Control.Monad (forM_)
+import qualified Data.ByteString as BS
+import qualified Data.ByteString.Char8 as CH
+import Foreign
+ ( Ptr,
+ Storable (poke, pokeByteOff),
+ Word32,
+ Word8,
+ deRefStablePtr,
+ freeStablePtr,
+ mallocBytes,
+ newStablePtr,
+ )
+import Foreign.C (CChar)
+import Wetterhorn.Core
+
+foreign import ccall wetterhorn :: IO Wetterhorn
+
+-- | This function is the implementation of the "hotstart" mechanism. It gives a
+-- pointer to the previously marshalled state and the length of that array and
+-- this function returns a Wetterhorn instance.
+foreign export ccall "plugin_hot_start"
+ pluginHotStart ::
+ Ptr CChar -> Word32 -> IO Wetterhorn
+
+pluginHotStart :: Ptr CChar -> Word32 -> IO Wetterhorn
+pluginHotStart chars len = do
+ bs <- BS.packCStringLen (chars, fromIntegral len)
+ wtrPtr <- wetterhorn
+ (conf, _) <- deRefStablePtr wtrPtr
+ freeStablePtr wtrPtr
+ newStablePtr . (conf,) =<< readWState bs
+
+foreign export ccall "plugin_cold_start"
+ pluginColdStart :: IO Wetterhorn
+
+pluginColdStart :: IO Wetterhorn
+pluginColdStart = wetterhorn
+
+foreign export ccall "plugin_marshal_state"
+ pluginMarshalState :: Wetterhorn -> Ptr Word32 -> IO (Ptr Word8)
+
+pluginMarshalState :: Wetterhorn -> Ptr Word32 -> IO (Ptr Word8)
+pluginMarshalState stblptr outlen = do
+ (_, st) <- deRefStablePtr stblptr
+ let bs = CH.pack (show st)
+ ret <- mallocBytes (BS.length bs)
+ poke outlen (fromIntegral $ BS.length bs)
+ forM_ (zip [0 ..] (BS.unpack bs)) $ \(off, w8) -> do
+ pokeByteOff ret off w8
+ return ret
diff --git a/src/harness_adapter.c b/src/harness_adapter.c
index dbae57a..15a2269 100644
--- a/src/harness_adapter.c
+++ b/src/harness_adapter.c
@@ -1,19 +1,8 @@
-#include <stdio.h>
#include "HsFFI.h"
+#include "plugin_interface.h"
-typedef void* opst_t;
+const char *plugin_name = "Wetterhorn";
-extern opst_t wetterhorn();
-
-opst_t plugin_init(int* argc, char*** argv)
-{
- hs_init(argc, argv);
- return wetterhorn();
-}
-
-void plugin_teardown()
-{
- hs_exit();
-}
-
-const char* plugin_name = "Wetterhorn";
+void plugin_load(int argc, char **argv) { hs_init(&argc, &argv); }
+void plugin_metaload(int argc, char **argv) { hs_init(&argc, &argv); }
+void plugin_teardown(opqst_t st) { hs_exit(); }