Skip to content

Commit

Permalink
Closing issue #204
Browse files Browse the repository at this point in the history
  • Loading branch information
TobiasWrigstad committed Jun 13, 2016
1 parent 45a8325 commit d3e5f18
Show file tree
Hide file tree
Showing 6 changed files with 31 additions and 6 deletions.
15 changes: 9 additions & 6 deletions src/back/CodeGen/Expr.hs
Original file line number Diff line number Diff line change
Expand Up @@ -447,12 +447,12 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where
in
do
typeArgs <- mapM getTypeVar typeParams
(nnew, ctorCall) <- namedTmpVar "new" ty callCtor
(nnew, constructorCall) <- namedTmpVar "new" ty callCtor
(initArgs, result) <-
methodCall nnew ty initName args ty
return (nnew,
Seq $
[ctorCall] ++
[constructorCall] ++
initArgs ++
[ Statement $ callTypeParamsInit $ (AsExpr nnew):typeArgs
, Statement result]
Expand Down Expand Up @@ -526,12 +526,12 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where
(Call arraySize [ntarg])
return (Var tmp, Seq [ttarg, theSize])

translate call@(A.MethodCall { A.target, A.name, A.args})
translate call@(A.MethodCall { A.emeta, A.target, A.name, A.args})
| (Ty.isTraitType . A.getType) target = do
(ntarget, ttarget) <- translate target
(nCall, tCall) <- traitMethod ntarget (A.getType target) name args
(translate (A.getType call))
return (nCall, Seq $ ttarget : [tCall])
return (nCall, Seq $ ttarget : targetNullCheck ntarget target name emeta : [tCall])
| syncAccess = delegateUse callTheMethodSync "sync_method_call"
| sharedAccess = delegateUse callTheMethodFuture "shared_method_call"
| isActive && isStream = delegateUse callTheMethodStream "stream"
Expand All @@ -548,6 +548,7 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where
return (Var result,
Seq $
ttarget :
targetNullCheck ntarget target name emeta:
initArgs ++
[Assign (Decl (translate retTy, Var result)) resultExpr]
)
Expand All @@ -557,8 +558,9 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where
isActive = Ty.isActiveClassType targetTy
isStream = Ty.isStreamType retTy
isFuture = Ty.isFutureType retTy
targetNullCheck ntarget target name meta = Statement $ Call (Nam "check_reciever") [AsExpr $ ntarget, String ".", String (show (PP.ppExpr target)), String (show name), String (show (Meta.getPos meta))]

translate call@(A.MessageSend { A.target, A.name, A.args })
translate call@(A.MessageSend { A.emeta, A.target, A.name, A.args })
| (Ty.isActiveClassType . A.getType) target = messageSend
| sharedAccess = sharedObjectMethodOneWay call
| otherwise = error "Tried to send a message to something that was not an active reference"
Expand All @@ -568,7 +570,8 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where
messageSend =
do (ntarg, ttarg) <- translate target
theSend <- activeMessageSend ntarg (A.getType target) name args
return (unit, Seq (Comm "message send" : ttarg : [theSend]))
return (unit, Seq (Comm "message send" : ttarg : targetNullCheck ntarg target name emeta : [theSend]))
targetNullCheck ntarget target name meta = Statement $ Call (Nam "check_reciever") [AsExpr $ ntarget, String " ! ", String (show (PP.ppExpr target)), String (show name), String (show (Meta.getPos meta))]

translate w@(A.While {A.cond, A.body}) =
do (ncond,tcond) <- translate cond
Expand Down
2 changes: 2 additions & 0 deletions src/runtime/encore/encore.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
#include <pony.h>
#include <atomics.h>

#define check_reciever(this, op, recv, msg, file) if (!this) { fprintf(stderr, "Error: empty receiver in " recv op msg "(...) in " file "\n"); abort(); }

typedef struct context {
ucontext_t uctx;
struct context *next;
Expand Down
9 changes: 9 additions & 0 deletions src/tests/encore/basic/recvNullCall.enc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Main
def test() : void
print("If you can read this, then recvNullCall failed")
def main() : void
let
x = null:Main
in
x.test()

1 change: 1 addition & 0 deletions src/tests/encore/basic/recvNullCall.err
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: empty receiver in x.test(...) in "src/tests/encore/basic/recvNullCall.enc" (line 8, column 7)
9 changes: 9 additions & 0 deletions src/tests/encore/basic/recvNullSend.enc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
class Main
def test() : void
print("If you can read this, then recvNullSend failed")
def main() : void
let
x = null:Main
in
x ! test()

1 change: 1 addition & 0 deletions src/tests/encore/basic/recvNullSend.err
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Error: empty receiver in x ! test(...) in "src/tests/encore/basic/recvNullSend.enc" (line 8, column 9)

0 comments on commit d3e5f18

Please sign in to comment.