@@ -221,7 +221,7 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where
221
221
let string = head args
222
222
rest = tail args
223
223
unless (Ty. isStringType $ A. getType string) $
224
- error " Expr.hs: Print expects first argument to be a string literal"
224
+ error $ " Expr.hs: Print expects first argument to be a string literal"
225
225
targs <- mapM translate rest
226
226
let argNames = map (AsExpr . fst ) targs
227
227
argDecls = map snd targs
@@ -1015,6 +1015,7 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where
1015
1015
then do
1016
1016
(ntarget, ttarget) <- translate target
1017
1017
let targetType = A. getType target
1018
+
1018
1019
(initArgs, forwardingCall) <-
1019
1020
callTheMethodForward [futVar]
1020
1021
ntarget targetType name args typeArguments Ty. unitType
@@ -1024,25 +1025,37 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where
1024
1025
ntarget targetType name args typeArguments Ty. unitType
1025
1026
1026
1027
let nullCheck = targetNullCheck (AsExpr ntarget) target name emeta " ."
1028
+ result =
1029
+ case eCtx of
1030
+ Ctx. ClosureContext clos -> []
1031
+ _ -> [dtraceExit, Return Skip ]
1027
1032
1028
1033
return (unit, Seq $
1029
1034
ttarget : nullCheck :
1030
1035
[Statement $
1031
1036
If futVar
1032
1037
(Seq $ initArgs ++ [Statement forwardingCall])
1033
- (Seq $ initArgs1 ++ [Statement oneWayMsg]),
1034
- dtraceExit,
1035
- Return Skip ])
1036
-
1038
+ (Seq $ initArgs1 ++ [Statement oneWayMsg])] ++
1039
+ result
1040
+ )
1037
1041
else do
1038
1042
(sendn, sendt) <- translate A. MessageSend {A. emeta
1039
1043
,A. target
1040
1044
,A. name
1041
1045
,A. typeArguments
1042
1046
,A. args}
1047
+ tmp <- Ctx. genSym
1043
1048
let resultType = translate (Ty. getResultType $ A. getType expr)
1044
1049
theGet = fromEncoreArgT resultType (Call futureGetActor [encoreCtxVar, sendn])
1045
- return (unit, Seq [sendt, dtraceExit, Return theGet])
1050
+ result =
1051
+ case eCtx of
1052
+ Ctx. MethodContext mdecl ->
1053
+ (unit, Seq [sendt, dtraceExit, Return theGet])
1054
+ Ctx. ClosureContext clos ->
1055
+ let ty = (Ty. getResultType $ A. getType clos)
1056
+ in (Var tmp, Seq [sendt, Assign (Decl (resultType, Var tmp)) theGet])
1057
+ _ -> error " Expr.hs: No context to forward"
1058
+ return result
1046
1059
1047
1060
translate A. Forward {A. emeta, A. forwardExpr = fchain@ A. FutureChain {A. future, A. chain}} = do
1048
1061
(nfuture,tfuture) <- translate future
@@ -1051,17 +1064,26 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where
1051
1064
isAsyncForward <- gets Ctx. isAsyncForward
1052
1065
let ty = getRuntimeType chain
1053
1066
dtraceExit = getDtraceExit eCtx
1067
+ result = case eCtx of
1068
+ Ctx. ClosureContext clos -> []
1069
+ _ -> [dtraceExit, Return Skip ]
1070
+ futureChain =
1071
+ if Util. isForwardInExpr chain
1072
+ then Call futureChainActor
1073
+ [AsExpr encoreCtxVar, AsExpr nfuture, ty, AsExpr nchain]
1074
+ else Call futureChainWithFut
1075
+ [AsExpr encoreCtxVar, AsExpr nfuture, ty, AsExpr nchain
1076
+ ,AsExpr futVar, AsExpr $ AsLval $ Nam " false" ]
1077
+ when (A. isVarAccess chain) $
1078
+ unless (A. isIdClosure chain) $
1079
+ error $ " Expr.hs: The closure that contains forward must be defined in chain."
1054
1080
if isAsyncForward
1055
1081
then do
1056
1082
return (unit, Seq $
1057
1083
[tfuture,
1058
1084
tchain,
1059
- (Statement $
1060
- Call futureChainActorForward
1061
- [AsExpr encoreCtxVar, AsExpr nfuture, ty, AsExpr nchain, AsExpr futVar]
1062
- )] ++
1063
- [dtraceExit,
1064
- Return Skip ])
1085
+ Statement futureChain] ++
1086
+ result)
1065
1087
else do
1066
1088
tmp <- Ctx. genSym
1067
1089
result <- Ctx. genSym
@@ -1094,17 +1116,40 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where
1094
1116
translate ret@ (A. Return {A. val}) =
1095
1117
do (nval, tval) <- translate val
1096
1118
eCtx <- gets Ctx. getExecCtx
1119
+ isAsyncForward <- gets Ctx. isAsyncForward
1097
1120
let theReturn =
1098
- case eCtx of
1099
- Ctx. FunctionContext fun ->
1100
- [dtraceFunctionExit (A. functionName fun), Return nval]
1101
- Ctx. MethodContext mdecl ->
1102
- [dtraceMethodExit thisVar (A. methodName mdecl), Return nval]
1103
- Ctx. ClosureContext clos ->
1104
- let ty = (Ty. getResultType $ A. getType clos)
1105
- in [dtraceClosureExit,
1106
- Return $ asEncoreArgT (translate ty) nval]
1107
- _ -> error " Expr.hs: No context to return from"
1121
+ if isAsyncForward then
1122
+ case eCtx of
1123
+ Ctx. FunctionContext fun ->
1124
+ let ty = A. getType fun
1125
+ in [dtraceFunctionExit (A. functionName fun)
1126
+ ,Statement $ Call futureFulfil [AsExpr encoreCtxVar, AsExpr futVar
1127
+ ,asEncoreArgT (translate ty) nval]
1128
+ ,Return Skip ]
1129
+ Ctx. MethodContext mdecl ->
1130
+ let ty = A. getType mdecl
1131
+ in [dtraceMethodExit thisVar (A. methodName mdecl)
1132
+ ,Statement $ Call futureFulfil [AsExpr encoreCtxVar, AsExpr futVar
1133
+ ,asEncoreArgT (translate ty) nval]
1134
+ ,Return Skip ]
1135
+ Ctx. ClosureContext clos ->
1136
+ let ty = (Ty. getResultType $ A. getType clos)
1137
+ in [dtraceClosureExit
1138
+ ,Statement $ Call futureFulfil [AsExpr encoreCtxVar, AsExpr futVar
1139
+ ,asEncoreArgT (translate ty) nval]
1140
+ ,Return Skip ]
1141
+ _ -> error " Expr.hs: No context to return from"
1142
+ else
1143
+ case eCtx of
1144
+ Ctx. FunctionContext fun ->
1145
+ [dtraceFunctionExit (A. functionName fun), Return nval]
1146
+ Ctx. MethodContext mdecl ->
1147
+ [dtraceMethodExit thisVar (A. methodName mdecl), Return nval]
1148
+ Ctx. ClosureContext clos ->
1149
+ let ty = (Ty. getResultType $ A. getType clos)
1150
+ in [dtraceClosureExit,
1151
+ Return $ asEncoreArgT (translate ty) nval]
1152
+ _ -> error " Expr.hs: No context to return from"
1108
1153
return (unit, Seq $ tval: theReturn)
1109
1154
1110
1155
translate iseos@ (A. IsEos {A. target}) =
@@ -1129,30 +1174,62 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where
1129
1174
translate futureChain@ (A. FutureChain {A. future, A. chain}) = do
1130
1175
(nfuture,tfuture) <- translate future
1131
1176
(nchain, tchain) <- translate chain
1132
- let ty = getRuntimeType chain
1133
1177
result <- Ctx. genSym
1178
+ isAsyncForward <- gets Ctx. isAsyncForward
1179
+ let ty = getRuntimeType chain
1134
1180
return $ (Var result,
1135
- Seq [tfuture,
1136
- tchain,
1137
- (Assign (Decl (C. future, Var result))
1138
- (Call futureChainActor
1139
- [AsExpr encoreCtxVar, AsExpr nfuture, ty, AsExpr nchain]
1140
- ))])
1181
+ Seq $ [tfuture,
1182
+ tchain,
1183
+ if (Util. isForwardInExpr chain && isAsyncForward)
1184
+ then Statement $
1185
+ (Call futureChainWithFut
1186
+ [AsExpr encoreCtxVar, AsExpr nfuture, ty, AsExpr nchain,
1187
+ AsExpr ((Deref envName) `Dot ` futNam), AsExpr $ AsLval $ Nam " true" ])
1188
+ else Assign (Decl (C. future, Var result))
1189
+ (Call futureChainActor [AsExpr encoreCtxVar, AsExpr nfuture, ty, AsExpr nchain])
1190
+ ] ++
1191
+ if (Util. isForwardInExpr chain && isAsyncForward)
1192
+ then [assignVar futNam (Decl (C. future, Var result))]
1193
+ else [] )
1194
+ where
1195
+ metaId = Meta. getMetaId . A. getMeta $ chain
1196
+ envName = closureEnvName metaId
1197
+ assignVar lhs rhs = Assign rhs ((Deref envName) `Dot ` lhs)
1141
1198
1142
1199
translate clos@ (A. Closure {A. eparams, A. body}) = do
1143
1200
tmp <- Ctx. genSym
1201
+ futClos <- Ctx. genNamedSym " fut_closure"
1144
1202
globalFunctionNames <- gets Ctx. getGlobalFunctionNames
1203
+ isAsyncForward <- gets Ctx. isAsyncForward
1145
1204
let bound = map (ID. qLocal . A. pname) eparams
1146
1205
freeVars = filter (ID. isLocalQName . fst ) $
1147
1206
Util. freeVariables bound body
1207
+ ty = runtimeType . A. getType $ body
1148
1208
fillEnv <- insertAllVars freeVars fTypeVars
1149
1209
return
1150
1210
(Var tmp,
1151
- Seq $
1152
- mkEnv envName : fillEnv ++
1153
- [Assign (Decl (closure, Var tmp))
1154
- (Call closureMkFn [encoreCtxName, funName, envName, traceName, nullName])])
1211
+ Seq $
1212
+ mkEnv envName : fillEnv ++
1213
+ if isAsyncForward then
1214
+ if forwardInBody
1215
+ then [Assign (Decl (future, Var futClos))
1216
+ (Call futureMkFn [AsExpr encoreCtxVar, ty])
1217
+ ,assignVar futNam (Var futClos)
1218
+ ,Assign (Decl (closure, Var tmp))
1219
+ (Call closureMkFn [encoreCtxName, funNameAsync, envName, traceNameAsync, nullName])]
1220
+ else [Assign (Decl (closure, Var tmp))
1221
+ (Call closureMkFn [encoreCtxName, funName, envName, traceName, nullName])]
1222
+ else
1223
+ [Assign (Decl (closure, Var tmp))
1224
+ (Call closureMkFn [encoreCtxName, funName, envName, traceName, nullName])])
1155
1225
where
1226
+ forwardInBody = Util. isForwardInExpr body
1227
+ metaIdAsync = metaId ++ " _async"
1228
+ idClos = A. isIdClosure body
1229
+ funNameAsync = if idClos || not forwardInBody then funName
1230
+ else closureFunName metaIdAsync
1231
+ traceNameAsync = if idClos || not forwardInBody then traceName
1232
+ else closureTraceName metaIdAsync
1156
1233
metaId = Meta. getMetaId . A. getMeta $ clos
1157
1234
funName = closureFunName metaId
1158
1235
envName = closureEnvName metaId
0 commit comments