Skip to content

Commit 19adaa0

Browse files
committed
feat(#495): add foreign lpvm sizeof instr
1 parent d852900 commit 19adaa0

File tree

5 files changed

+33
-8
lines changed

5 files changed

+33
-8
lines changed

src/AST.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3632,6 +3632,7 @@ expOutputs (DisjExp pexp1 pexp2) = pexpListOutputs [pexp1,pexp2]
36323632
expOutputs (Where _ pexp) = expOutputs $ content pexp
36333633
expOutputs (CondExp _ pexp1 pexp2) = pexpListOutputs [pexp1,pexp2]
36343634
expOutputs (Fncall _ _ _ args) = pexpListOutputs args
3635+
expOutputs (ForeignFn "lpvm" "sizeof" _ (_:args)) = pexpListOutputs args
36353636
expOutputs (ForeignFn _ _ _ args) = pexpListOutputs args
36363637
expOutputs (CaseExp _ cases deflt) =
36373638
pexpListOutputs $ maybe id (:) deflt (snd <$> cases)

src/Clause.hs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ compileProc proc procID =
163163
gFlows = makeGlobalFlows (zip [0..] params') $ procProtoResources proto
164164
let proto' = PrimProto (procProtoName proto) params' gFlows
165165
logClause $ " comparams : " ++ show params'
166-
logClause $ " globalFlows: " ++ show gFlows
166+
logClause $ " globalFlows: " ++ show gFlows
167167
callSiteCount <- gets nextCallSiteID
168168
mSpec <- lift $ getModule modSpec
169169
let pSpec = ProcSpec mSpec procName procID Set.empty
@@ -287,6 +287,13 @@ compileSimpleStmt' call@(ProcCall func _ _ args) = do
287287
. trustFromJust ("untyped higher-order term " ++ show fn) . maybeExpType $ content fn
288288
fn' <- compileHigherFunc fn
289289
return $ PrimHigher callSiteID fn' impurity' args'
290+
compileSimpleStmt' (ForeignCall "lpvm" "sizeof" flags [arg, out]) = do
291+
repSize <- case content arg of
292+
Typed _ ty _ -> typeRepSize . trustFromJust "sizeof with unkown typerep" <$> lift (lookupTypeRepresentation ty)
293+
_ -> shouldnt $ "untyped in sizeof " ++ show arg
294+
[out'] <- placedApply compileArg out
295+
let size = if "bits" `elem` flags then repSize else (repSize + 7) `div` 8
296+
return $ PrimForeign "llvm" "move" [] [ArgInt (fromIntegral size) intType, out']
290297
compileSimpleStmt' (ForeignCall lang name flags args) = do
291298
args' <- concat <$> mapM (placedApply compileArg) args
292299
return $ PrimForeign lang name flags args'
@@ -377,24 +384,24 @@ compileParam allFlows startVars endVars procName idx param@(Param name ty flow f
377384
(shouldnt ("compileParam for input param " ++ show param
378385
++ " of proc " ++ show procName))
379386
name startVars
380-
gFlows
381-
| (isResourcefulHigherOrder ||| genericType) ty
387+
gFlows
388+
| (isResourcefulHigherOrder ||| genericType) ty
382389
= emptyGlobalFlows{globalFlowsParams=USet.singleton inIdx}
383390
| otherwise = emptyGlobalFlows
384391
]
385-
++
392+
++
386393
[PrimParam (PrimVarName name num) ty FlowOut ftype (ParamInfo False gFlows)
387394
| flowsOut flow
388395
, let num = Map.findWithDefault
389396
(shouldnt ("compileParam for output param " ++ show param
390397
++ " of proc " ++ show procName))
391398
name endVars
392-
gFlows
399+
gFlows
393400
| isResourcefulHigherOrder ty = univGlobalFlows
394401
| genericType ty = emptyGlobalFlows{globalFlowsParams=UniversalSet}
395402
| otherwise = emptyGlobalFlows
396403
]
397-
where
404+
where
398405
inIdx = idx
399406
outIdx = if flowsIn flow then idx + 1 else idx
400407

src/Flatten.hs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -329,6 +329,15 @@ flattenStmt' stmt@(ProcCall func detism res args) pos d = do
329329
args' <- flattenStmtArgs args pos
330330
emit pos $ ProcCall func detism res args'
331331
flushPostponed
332+
flattenStmt' (ForeignCall "lpvm" "sizeof" flags args@(arg:_)) pos _ = do
333+
let (arg', argPos) = unPlace arg
334+
case innerExp arg' of
335+
Var var flow _ | var /= "_" && flow /= ParamIn ->
336+
lift $ message Error "First argument to sizeof cannot be an out variable" argPos
337+
_ -> return ()
338+
args' <- flattenStmtArgs args pos
339+
emit pos $ ForeignCall "lpvm" "sizeof" flags args'
340+
flushPostponed
332341
flattenStmt' (ForeignCall lang name flags args) pos _ = do
333342
args' <- flattenStmtArgs args pos
334343
emit pos $ ForeignCall lang name flags args'
@@ -635,6 +644,9 @@ flattenExp (Fncall mod name bang exps) ty castFrom pos = do
635644
$ errmsg pos "function call cannot have preceding !"
636645
let stmtBuilder = ProcCall (First mod name Nothing) Det bang
637646
flattenCall stmtBuilder False ty castFrom pos exps
647+
flattenExp (ForeignFn "lpvm" "sizeof" flags (exp:exps)) ty castFrom pos = do
648+
exp' <- flattenPExp exp
649+
flattenCall (ForeignCall "lpvm" "sizeof" flags . (exp':)) True ty castFrom pos exps
638650
flattenExp (ForeignFn lang name flags exps) ty castFrom pos = do
639651
flattenCall (ForeignCall lang name flags) True ty castFrom pos exps
640652
flattenExp (Typed exp AnyType _) ty castFrom pos = do

src/Types.hs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2907,6 +2907,11 @@ checkLPVMArgs "cast" _ [old,new] stmt pos = return ()
29072907
checkLPVMArgs "cast" _ [] stmt pos = return ()
29082908
checkLPVMArgs "cast" _ args stmt pos =
29092909
typeError (ReasonForeignArity "cast" (length args) 2 pos)
2910+
checkLPVMArgs "sizeof" _ [thing,sz] stmt pos =
2911+
reportErrorUnless (ReasonForeignArgRep "sizeof" 1 sz "integer" pos)
2912+
(integerTypeRep sz)
2913+
checkLPVMArgs "sizeof" _ args stmt pos =
2914+
typeError (ReasonForeignArity "sizeof" (length args) 2 pos)
29102915
checkLPVMArgs name _ args stmt pos =
29112916
typeError (ReasonBadForeign "lpvm" name pos)
29122917

wybelibs/wybe/machine_word.wybe

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ representation is address
77

88
use wybe.int
99

10-
pub def word_size_bytes:int = 8
10+
pub def word_size_bytes:int = foreign lpvm sizeof(_:_)
1111

12-
pub def word_size_bits:int = 8 * word_size_bytes
12+
pub def word_size_bits:int = foreign lpvm {bits} sizeof(_:_)

0 commit comments

Comments
 (0)