% % (c) The Foo Project, University of Glasgow, 1998 % % @(#) $Docid: Feb. 9th 2003 06:49 Sigbjorn Finne $ % @(#) $Contactid: sof@galois.com $ % CgM HDecl marshallAbstract i = do ds <- mapM exportify decl_list return (andDecls ds) where decl_list = (if isFinalised then ( ( fin_name, fin_decl ) :) else id) $ (if isFinalised then id -- ToDo: generate one (it's genuinely useful in some cases.) else ( ( f_name, f_tysig `andDecl` f_def) :)) [ ( m_name, m_tysig `andDecl` m_def) , ( u_name, u_tysig `andDecl` u_def) , ( w_name, w_tysig `andDecl` w_def) , ( r_name, r_tysig `andDecl` r_def) , ( s_name, s_tysig `andDecl` s_def) , ( l_name, l_tysig `andDecl` l_def) ] exportify (nm, d) = do addExport (ieValue nm) return d attrs = idAttributes i isFinalised = attrs `hasAttributeWithName` "finaliser" free_routine = case findAttribute "free" attrs of Just (Attribute _ [ParamLit (StringLit s)]) -> mkVarName s _ -> LibUtils.free abs_nm = idOrigName i con_name = mkHaskellTyConName abs_nm name = mkVarName con_name fin_name = finaliser fin_decl | optHugs = prim Cdecl (dname, Nothing, orig_fin_nm, Nothing) fin_name (tyFunPtr (funTy (tyPtr t_ty) io_unit)) False [] (False,"void*") | otherwise = extLabel orig_fin_nm fin_name (tyFunPtr (funTy (tyPtr t_ty) io_unit)) where dname = "" -- dll location. (finaliser, orig_fin_nm) = case (findAttribute "finaliser" attrs) of Just (Attribute _ [ParamLit (StringLit s)]) -> ("addrOf_" ++ idName i ++ '_':s, s) _ -> let s = "no-finaliser" in (s,s) ty_args = case findAttribute "ty_args" attrs of Just (Attribute _ [ParamLit (StringLit s)]) -> map tyVar (words s) _ -> [] v = var "v" vptr = var "ptr" t_ty = tyCon con_name ty_args prim_ty = tyPtr t_ty b_ty | isFinalised = tyForeignPtr t_ty | otherwise = prim_ty -- ** Marshalling ** -- m_name = qName (prefix marshallPrefix name) m_tysig = typeSig m_name (funTy t_ty (io b_ty)) m_def = funDef m_name [conPat (mkConName con_name) [varPat v]] m_rhs m_rhs = ret v -- ** unmarshalling ** -- u_name = qName (prefix unmarshallPrefix name) u_tysig = typeSig u_name u_type u_type | isFinalised = funTy tyBool (funTy prim_ty (io t_ty)) | otherwise = (funTy prim_ty (io t_ty)) u_def = funDef u_name u_pats u_rhs u_pats | isFinalised = [patVar "finaliseMe__", varPat v] | otherwise = [varPat v] u_rhs | isFinalised = bind (funApp mkForeignObj [v, hCase (var "finaliseMe__") [alt (conPat false []) (varName nullFinaliser) ,alt (conPat true []) (var finaliser) ]]) v $ ret (dataCon (mkConName con_name) [v]) | otherwise = ret (dataCon (mkConName con_name) [v]) -- ** Reference marshalling w_name = qName (prefix marshallRefPrefix name) w_tysig = typeSig w_name w_ty w_ty = funTy (tyPtr (tyPtr t_ty)) (funTy t_ty io_unit) w_def = funDef w_name [ varPat vptr , conPat (mkConName con_name) [varPat v]] w_rhs w_rhs | isFinalised = funApp w_fptr [vptr , v] | otherwise = funApp w_ptr [vptr , v] -- ** Reference unmarshalling r_name = qName (prefix unmarshallRefPrefix name) r_tysig = typeSig r_name r_ty r_ty | isFinalised = funTy tyBool (funTy (tyPtr t_ty) (io t_ty)) | otherwise = funTy (tyPtr t_ty) (io t_ty) r_def = funDef r_name r_pats r_rhs r_pats | isFinalised = [patVar "finaliseMe__", varPat vptr] | otherwise = [varPat vptr] r_rhs | isFinalised = bind (funApp r_ptr [vptr]) v $ bind (funApp mkForeignObj [v, hCase (var "finaliseMe__") [alt (conPat false []) (varName nullFinaliser) ,alt (conPat true []) (var finaliser) ]]) v $ ret (dataCon (mkConName con_name) [v]) | otherwise = bind (funApp r_ptr [vptr]) v $ ret (dataCon (mkConName con_name) [v]) f_name = qName (prefix freePrefix name) f_tysig = typeSig f_name (funTy t_ty io_unit) f_def = funDef f_name [conPat (mkConName con_name) [varPat v]] f_rhs f_rhs = funApp free_routine [v] s_name = qName (prefix sizeofPrefix name) -- s_name = sizeOfName s_tysig = typeSig s_name tyWord32 s_def = funDef s_name [] s_rhs s_rhs = szType addrTy -- addr --> ADT-type lifting fun. l_name = qName (prefix "addrTo" name) l_tysig = typeSig l_name (funTy anyTyPtr t_ty) l_def = funDef l_name [varPat v] l_rhs l_rhs | isFinalised = funApp (mkQVarName ioExts "unsafePerformIO") [bind (funApp mkForeignObj [castPtr v, var finaliser]) v $ ret (dataCon (mkConName con_name) [v])] | otherwise = dataCon (mkConName con_name) [castPtr v] w_ptr = prefix marshallRefPrefix (mkQVarName hdirectLib ptrName) r_ptr = prefix unmarshallRefPrefix (mkQVarName hdirectLib ptrName) w_fptr = prefix marshallRefPrefix (mkQVarName hdirectLib fptr) \end{code}