Skip to content

Commit 25f3131

Browse files
committed
copilot-c99: Pass output arrays as arguments to trigger argument functions. Refs #431.
Copilot's C99 backend generates incorrect code for trigger argument functions that return constant arrays. Currently, the code will return a pointer to a stack-allocated array. That memory may be used for something else after the call to the trigger argument function, so it may be overwritten or freed by the time the array is used. This may lead to the array holding incorrect values. This is almost the same issue that was noticed in #386, except that #386 was specifically about stream generator functions, whereas this issue is specifically about trigger argument functions. This commit changes array trigger argument functions so that they receive a pointer to an array for the output argument. The part of the generated code that applies the trigger argument functions has also been updated accordingly such that when the argument has an array type, the output array is passed directly as an argument (e.g., `f_arg0(temp_array)`) rather than being assigned (e.g., `temp_array = f_arg0()`). Because we pass output arrays directly to trigger argument functions, we no longer have to have a special case in the code for declaring temporary variables for output arrays as pointers (e.g., `int* temp_array;`). Instead, we can declare these temporary variables directly as arrays (e.g., `int temp_array[2];`). This makes the intent clearer and simplifies the implementation in `copilot-c99`.
1 parent 907d5bb commit 25f3131

File tree

2 files changed

+19
-22
lines changed

2 files changed

+19
-22
lines changed

copilot-c99/src/Copilot/Compile/C99/CodeGen.hs

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -250,22 +250,8 @@ mkStep cSettings streams triggers exts =
250250
aTmpDeclns = zipWith declare args aTempNames
251251
where
252252
declare :: UExpr -> C.Ident -> C.Decln
253-
declare arg tmpVar =
254-
C.VarDecln Nothing (tempType arg) tmpVar Nothing
255-
256-
-- Type of the temporary variable used to store values of the type
257-
-- of a given expression.
258-
tempType :: UExpr -> C.Type
259-
tempType (UExpr { uExprType = ty }) =
260-
case ty of
261-
-- If a temporary variable is being used to store an array,
262-
-- declare the type of the temporary variable as a pointer, not
263-
-- an array. The problem with declaring it as an array is that
264-
-- the `arg` function will return a pointer, not an array, and
265-
-- C doesn't make it easy to cast directly from an array to a
266-
-- pointer.
267-
Array ty' -> C.Ptr $ transType ty'
268-
_ -> transType ty
253+
declare (UExpr { uExprType = ty }) tmpVar =
254+
C.VarDecln Nothing (transType ty) tmpVar Nothing
269255

270256
triggerCheckStmt :: C.Stmt
271257
triggerCheckStmt = C.If guard' fireTrigger
@@ -283,13 +269,21 @@ mkStep cSettings streams triggers exts =
283269
where
284270
-- List of assignments of values of temporary variables.
285271
argAssigns :: [C.Expr]
286-
argAssigns = zipWith assign aTempNames args'
272+
argAssigns = zipWith3 assign aTempNames aArgNames args
287273

288-
assign :: C.Ident -> C.Expr -> C.Expr
289-
assign aTempName = C.AssignOp C.Assign (C.Ident aTempName)
274+
assign :: C.Ident -> C.Ident -> UExpr -> C.Expr
275+
assign aTempName aArgName (UExpr { uExprType = ty }) =
276+
case ty of
277+
Array _ -> argCall aArgName [C.Ident aTempName]
278+
_ -> C.AssignOp C.Assign
279+
(C.Ident aTempName)
280+
(argCall aArgName [])
281+
282+
aArgNames :: [C.Ident]
283+
aArgNames = take (length args) (argNames name)
290284

291-
args' = take (length args) (map argCall (argNames name))
292-
argCall name' = C.Funcall (C.Ident name') []
285+
argCall :: C.Ident -> [C.Expr] -> C.Expr
286+
argCall name' = C.Funcall (C.Ident name')
293287

294288
-- Build an expression to pass a temporary variable as argument
295289
-- to a trigger handler.

copilot-c99/src/Copilot/Compile/C99/Compile.hs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,10 @@ compileC cSettings spec = C.TransUnit declns funs
130130
argDefs = zipWith argGen (argNames name) args
131131

132132
argGen :: String -> UExpr -> C.FunDef
133-
argGen argName (UExpr ty expr) = mkGenFun argName expr ty
133+
argGen argName (UExpr ty expr) =
134+
case ty of
135+
Array _ -> mkGenFunArray argName (argName ++ "_output") expr ty
136+
_ -> mkGenFun argName expr ty
134137

135138
-- | Generate the .h file from a 'Spec'.
136139
compileH :: CSettings -> Spec -> C.TransUnit

0 commit comments

Comments
 (0)