import CoreUtils
import MkCore
import Var
-import Id
import MkId
import Maybes
import ForeignCall
dsCCall lbl args may_gc result_ty
= do (unboxed_args, arg_wrappers) <- mapAndUnzipM unboxArg args
- (ccall_result_ty, res_wrapper) <- boxResult id Nothing result_ty
+ (ccall_result_ty, res_wrapper) <- boxResult result_ty
uniq <- newUnique
let
target = StaticTarget lbl
\begin{code}
-boxResult :: ((Maybe Type, CoreExpr -> CoreExpr)
- -> (Maybe Type, CoreExpr -> CoreExpr))
- -> Maybe Id
- -> Type
+boxResult :: Type
-> DsM (Type, CoreExpr -> CoreExpr)
-- Takes the result of the user-level ccall:
-- where t' is the unwrapped form of t. If t is simply (), then
-- the result type will be
-- State# RealWorld -> (# State# RealWorld #)
---
--- The gruesome 'augment' and 'mbTopCon' are to do with .NET foreign calls
--- It looks a mess: I wonder if it could be refactored.
-boxResult augment mbTopCon result_ty
+boxResult result_ty
| Just (io_tycon, io_res_ty, co) <- tcSplitIOType_maybe result_ty
-- isIOType_maybe handles the case where the type is a
-- simple wrapping of IO. E.g.
-- another case, and a coercion.)
-- The result is IO t, so wrap the result in an IO constructor
= do { res <- resultWrapper io_res_ty
- ; let aug_res = augment res
- extra_result_tys
- = case aug_res of
+ ; let extra_result_tys
+ = case res of
(Just ty,_)
| isUnboxedTupleType ty
-> let (Just (_, ls)) = splitTyConApp_maybe ty in tail ls
(map Type (realWorldStatePrimTy : io_res_ty : extra_result_tys)
++ (state : anss))
- ; (ccall_res_ty, the_alt) <- mk_alt return_result aug_res
+ ; (ccall_res_ty, the_alt) <- mk_alt return_result res
; state_id <- newSysLocalDs realWorldStatePrimTy
; let io_data_con = head (tyConDataCons io_tycon)
- toIOCon = mbTopCon `orElse` dataConWrapId io_data_con
+ toIOCon = dataConWrapId io_data_con
wrap the_call = mkCoerceI (mkSymCoI co) $
mkApps (Var toIOCon)
; return (realWorldStatePrimTy `mkFunTy` ccall_res_ty, wrap) }
-boxResult augment _mbTopCon result_ty
+boxResult result_ty
= do -- It isn't IO, so do unsafePerformIO
-- It's not conveniently available, so we inline it
res <- resultWrapper result_ty
- (ccall_res_ty, the_alt) <- mk_alt return_result (augment res)
+ (ccall_res_ty, the_alt) <- mk_alt return_result res
let
wrap = \ the_call -> mkWildCase (App the_call (Var realWorldPrimId))
ccall_res_ty