From 9f917d23b67b6f9e7de5040dfea64bbff6e53dbb Mon Sep 17 00:00:00 2001 From: Elias Castegren Date: Wed, 10 Dec 2014 14:36:11 +0100 Subject: [PATCH] Assigning from this turns the alias into a normal active reference Note that getting a future from a method called on the alias will cause a deadlock! --- src/back/CodeGen/Expr.hs | 14 ++++++++---- src/tests/encore/basic/activeThis.enc | 33 +++++++++++++++++++++++++++ src/tests/encore/basic/activeThis.out | 1 + 3 files changed, 44 insertions(+), 4 deletions(-) create mode 100644 src/tests/encore/basic/activeThis.enc create mode 100644 src/tests/encore/basic/activeThis.out diff --git a/src/back/CodeGen/Expr.hs b/src/back/CodeGen/Expr.hs index 7d1ed2981..8b5ecaaa8 100644 --- a/src/back/CodeGen/Expr.hs +++ b/src/back/CodeGen/Expr.hs @@ -135,7 +135,9 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where return (last nes, Seq tes) translate (A.Assign {A.lhs, A.rhs}) = do - (nrhs, trhs) <- translate rhs + (nrhs, trhs) <- if A.isThisAccess rhs && (Ty.isActiveRefType $ A.getType rhs) + then return (Deref (Var "this") `Dot` (Nam "aref"), Skip) + else translate rhs lval <- mk_lval lhs return (unit, Seq [trhs, Assign lval nrhs]) where @@ -170,8 +172,10 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where return (nbody, Seq $ tdecls ++ [tbody]) where translate_decls [] = return [] - translate_decls ((name, expr):decls) = - do (ne, te) <- translate expr + translate_decls ((name, expr):decls) = + do (ne, te) <- if A.isThisAccess expr && (Ty.isActiveRefType $ A.getType expr) + then return (Deref (Var "this") `Dot` (Nam "aref"), Skip) + else translate expr tmp <- Ctx.gen_sym substitute_var name (Var tmp) tdecls <- translate_decls decls @@ -391,7 +395,9 @@ instance Translatable A.Expr (State Ctx.Context (CCode Lval, CCode Stat)) where | Ty.isRealType ty = AsExpr $ e `Dot` Nam "d" | otherwise = AsExpr $ e `Dot` Nam "p" translateArgument arg = - do (ntother, tother) <- translate arg + do (ntother, tother) <- if A.isThisAccess arg && (Ty.isActiveRefType $ A.getType arg) + then return (Deref (Var "this") `Dot` (Nam "aref"), Skip) + else translate arg return $ UnionInst (arg_member $ A.getType arg) (StatAsExpr ntother tother) where arg_member ty diff --git a/src/tests/encore/basic/activeThis.enc b/src/tests/encore/basic/activeThis.enc new file mode 100644 index 000000000..2ea614da5 --- /dev/null +++ b/src/tests/encore/basic/activeThis.enc @@ -0,0 +1,33 @@ +class Foo + def fr0b() : bool + true + + def foo() : Fut bool + let that = this in{ + that.fr0b(); + } + + def bar() : Fut bool + let that = null : Foo in{ + that = this; + that.fr0b() + } + + def baz() : Fut bool + let id = \ (x : a) -> x + that = id(this) + in + that.fr0b() + +class Main + def main() : void + let x = new Foo in{ + assertTrue(get get x.foo()); + assertTrue(get get x.bar()); + assertTrue(get get x.baz()); + print "Done!"; + -- TODO: Find out why this is needed! + embed void + fflush(NULL); + end + } \ No newline at end of file diff --git a/src/tests/encore/basic/activeThis.out b/src/tests/encore/basic/activeThis.out new file mode 100644 index 000000000..76f5a5a5a --- /dev/null +++ b/src/tests/encore/basic/activeThis.out @@ -0,0 +1 @@ +Done!