Safe Haskell | None |
---|
This is the main module of this library. Other functionnalities are exposed in Foreign.Ruby.Bindings and Foreign.Ruby.Helpers, but this should be enough for most cases.
- initialize :: IO ()
- finalize :: IO ()
- type RValue = Ptr CULong
- type RID = CULong
- class FromRuby a where
- class ToRuby a where
- getSymbol :: String -> IO RValue
- embedHaskellValue :: a -> IO RValue
- extractHaskellValue :: RValue -> IO a
- freeHaskellValue :: RValue -> IO ()
- mkRegistered0 :: Registered0 -> IO (FunPtr Registered0)
- mkRegistered1 :: Registered1 -> IO (FunPtr Registered1)
- mkRegistered2 :: Registered2 -> IO (FunPtr Registered2)
- rb_define_global_function :: String -> FunPtr a -> Int -> IO ()
- setGC :: Bool -> IO (Either (String, RValue) RValue)
- startGC :: IO ()
- freezeGC :: IO a -> IO a
- rb_load_protect :: String -> Int -> IO Int
- safeMethodCall :: String -> String -> [RValue] -> IO (Either (String, RValue) RValue)
- showErrorStack :: IO String
Initialization / cleanup
initialize :: IO ()Source
You must run this before anything else.
Converting from and to Ruby values
type RValue = Ptr CULongSource
This is the type of Ruby values. It is defined as a pointer to some unsigned long, just like Ruby does. The actual value is either pointed to, or encoded in the pointer.
The class of things that can be converted from Ruby values. Note that
there are a ton of stuff that are Ruby values, hence the Maybe
type,
as the instances will probably be incomplete.
fromRuby :: RValue -> IO (Maybe a)Source
To define more instances, please look at the instances defined in Foreign.Ruby.Helpers.
FromRuby Double | |
FromRuby Int | |
FromRuby Integer | |
FromRuby ByteString | |
FromRuby Text | |
FromRuby Value | This is the most complete instance that is provided in this module.
Please note that it is far from being sufficient for even basic
requirements. For example, the |
FromRuby a => FromRuby [a] |
Callbacks
These functions could be used to call Haskell functions from the Ruby world. While fancier stuff could be achieved by tapping into Foreign.Ruby.Bindings, those methods should be easy to use and should cover most use cases.
The embedHaskellValue
, extractHaskellValue
and
freeHaskellValue
functions are very unsafe, and should be used only in very
controlled environments.
embedHaskellValue :: a -> IO RValueSource
This transforms any Haskell value into a Ruby big integer encoding the
address of the corresponding StablePtr
. This is useful when you want
to pass such values to a Ruby program that will call Haskell functions.
This is probably a bad idea to do this. The use case is for calling Haskell functions from Ruby, using values generated from the Haskell world. If your main program is in Haskell, you should probably wrap a function partially applied with the value you would want to embed.
extractHaskellValue :: RValue -> IO aSource
This is unsafe as hell, so you'd better be certain this RValue has not been tempered with : GC frozen, bugfree Ruby scripts.
If it has been tempered by an attacker, you are probably looking at a good vector for arbitrary code execution.
freeHaskellValue :: RValue -> IO ()Source
Frees the Haskell value represented by the corresponding RValue
.
This is probably extremely unsafe to do, and will most certainly lead to
exploitable security bug if you use something modified from Ruby land.
You should always free the RValue
you generated from
embedHaskellValue
.
mkRegistered0 :: Registered0 -> IO (FunPtr Registered0)Source
Creates a function pointer suitable for usage with rb_define_global_function
of type Registered0
(with 0 arguments).
mkRegistered1 :: Registered1 -> IO (FunPtr Registered1)Source
Creates a function pointer suitable for usage with rb_define_global_function
of type Registered1
(with 1 RValue
arguments).
mkRegistered2 :: Registered2 -> IO (FunPtr Registered2)Source
Creates a function pointer suitable for usage with rb_define_global_function
of type Registered2
(with 2 RValue
arguments).
rb_define_global_functionSource
:: String | Name of the function |
-> FunPtr a | Pointer to the function (created with something like |
-> Int | Number of arguments the function accepts. |
-> IO () |
Defines a global function that can be called from the Ruby world. This function must only accept RValue
s as arguments.
GC control
This is a critical part of embedding the Ruby interpreter. Data
created using the toRuby
function might be collected at any time.
For now, the solution is to disable the GC mechanism during calls to
Ruby functions. If someone knows of a better solution, please
contact the author of this library.
Sets the current GC operation. Please note that this could be modified from Ruby scripts.
freezeGC :: IO a -> IO aSource
Runs a computation with the Ruby GC disabled. Once the computation is over, GC
will be re-enabled and the startGC
function run.
Interacting with the interpreter
:: String | Path to the script |
-> Int | Just set this to 0, unless you know what you are doing |
-> IO Int | Return code, equal to 0 if everything went right. |
Loads a ruby script (and executes it).
:: String | Class name. |
-> String | Method name. |
-> [RValue] | Arguments. Please note that the maximum number of arguments is 16. |
-> IO (Either (String, RValue) RValue) | Returns either an error message / value couple, or the value returned by the function. |
Runs a Ruby method, capturing errors.
Error handling
showErrorStack :: IO StringSource
Gives a (multiline) error friendly string representation of the last error.