private static void CreateDelegateRemoveMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates) { Bpl.Formal a = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "a", sink.Heap.RefType), true); Bpl.Formal b = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "b", sink.Heap.RefType), true); Bpl.Formal c = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false); Bpl.IdentifierExpr aExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, a); Bpl.IdentifierExpr bExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, b); Bpl.IdentifierExpr cExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, c); Bpl.Procedure proc = new Bpl.Procedure( Bpl.Token.NoToken, sink.DelegateRemove(type), new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(new Bpl.Variable[] { a, b }), new List <Bpl.Variable>(new Bpl.Variable[] { c }), new List <Bpl.Requires>(), new List <Bpl.IdentifierExpr>(), new List <Bpl.Ensures>()); proc.AddAttribute("inline", Bpl.Expr.Literal(1)); sink.TranslatedProgram.AddTopLevelDeclaration(proc); Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder(); stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List <Bpl.Expr>(), new List <Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] { cExpr }))); foreach (IMethodDefinition defn in delegates) { Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn)); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, cExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, sink.ReadMethod(cie, aExpr), Bpl.Expr.Unary(Bpl.Token.NoToken, Bpl.UnaryOperator.Opcode.Not, sink.ReadMethod(cie, bExpr)))))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(cie, cExpr), sink.ReadReceiver(cie, aExpr)))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(cie, cExpr), sink.ReadTypeParameters(cie, aExpr)))); } Bpl.IdentifierExpr nullExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.Heap.NullRef); Bpl.IfCmd ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, bExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, aExpr), stmtBuilder.Collect(Bpl.Token.NoToken)); ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, aExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, nullExpr), ifCmd); Bpl.Implementation impl = new Bpl.Implementation( Bpl.Token.NoToken, sink.DelegateRemove(type), new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(new Bpl.Variable[] { a, b }), new List <Bpl.Variable>(new Bpl.Variable[] { c }), new List <Bpl.Variable>(), BuildStmtList(ifCmd) ); impl.AddAttribute("inline", Bpl.Expr.Literal(1)); impl.Proc = proc; sink.TranslatedProgram.AddTopLevelDeclaration(impl); }
private static void CreateDelegateCreateMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates) { Bpl.Formal method = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Method", Bpl.Type.Int), true); Bpl.Formal receiver = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Receiver", sink.Heap.RefType), true); Bpl.Formal typeParameters = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "TypeParameters", sink.Heap.TypeType), true); Bpl.Formal returnDelegate = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false); Bpl.IdentifierExpr methodExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, method); Bpl.IdentifierExpr receiverExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, receiver); Bpl.IdentifierExpr typeParametersExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, typeParameters); Bpl.IdentifierExpr returnDelegateExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, returnDelegate); Bpl.Procedure proc = new Bpl.Procedure( Bpl.Token.NoToken, sink.DelegateCreate(type), new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(new Bpl.Variable[] { method, receiver, typeParameters }), new List <Bpl.Variable>(new Bpl.Variable[] { returnDelegate }), new List <Bpl.Requires>(), new List <Bpl.IdentifierExpr>(), new List <Bpl.Ensures>()); proc.AddAttribute("inline", Bpl.Expr.Literal(1)); sink.TranslatedProgram.AddTopLevelDeclaration(proc); Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder(); stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List <Bpl.Expr>(), new List <Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] { returnDelegateExpr }))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(methodExpr, returnDelegateExpr), receiverExpr))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(methodExpr, returnDelegateExpr), typeParametersExpr))); foreach (IMethodDefinition defn in delegates) { Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn)); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, returnDelegateExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, methodExpr, cie)))); } Bpl.Implementation impl = new Bpl.Implementation( Bpl.Token.NoToken, sink.DelegateCreate(type), new List <Bpl.TypeVariable>(), new List <Bpl.Variable>(new Bpl.Variable[] { method, receiver, typeParameters }), new List <Bpl.Variable>(new Bpl.Variable[] { returnDelegate }), new List <Bpl.Variable>(), stmtBuilder.Collect(Bpl.Token.NoToken)); impl.AddAttribute("inline", Bpl.Expr.Literal(1)); impl.Proc = proc; sink.TranslatedProgram.AddTopLevelDeclaration(impl); }
private void CreateYieldCheckerImpl(Implementation impl, List<List<Cmd>> yields) { if (yields.Count == 0) return; Dictionary<Variable, Expr> map = new Dictionary<Variable, Expr>(); foreach (Variable local in impl.LocVars) { var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, local.Name, local.TypedIdent.Type)); map[local] = Expr.Ident(copy); } Program program = linearTypeChecker.program; List<Variable> locals = new List<Variable>(); List<Variable> inputs = new List<Variable>(); foreach (IdentifierExpr ie in map.Values) { locals.Add(ie.Decl); } for (int i = 0; i < impl.InParams.Count - linearTypeChecker.linearDomains.Count; i++) { Variable inParam = impl.InParams[i]; Variable copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, inParam.Name, inParam.TypedIdent.Type)); locals.Add(copy); map[impl.InParams[i]] = Expr.Ident(copy); } { int i = impl.InParams.Count - linearTypeChecker.linearDomains.Count; foreach (string domainName in linearTypeChecker.linearDomains.Keys) { Variable inParam = impl.InParams[i]; Variable copy = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, inParam.Name, inParam.TypedIdent.Type), true); inputs.Add(copy); map[impl.InParams[i]] = Expr.Ident(copy); i++; } } for (int i = 0; i < impl.OutParams.Count; i++) { Variable outParam = impl.OutParams[i]; var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, outParam.Name, outParam.TypedIdent.Type)); locals.Add(copy); map[impl.OutParams[i]] = Expr.Ident(copy); } Dictionary<Variable, Expr> ogOldLocalMap = new Dictionary<Variable, Expr>(); Dictionary<Variable, Expr> assumeMap = new Dictionary<Variable, Expr>(map); foreach (IdentifierExpr ie in globalMods) { Variable g = ie.Decl; var copy = new LocalVariable(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_local_old_{0}", g.Name), g.TypedIdent.Type)); locals.Add(copy); ogOldLocalMap[g] = Expr.Ident(copy); Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_global_old_{0}", g.Name), g.TypedIdent.Type), true); inputs.Add(f); assumeMap[g] = Expr.Ident(f); } Substitution assumeSubst = Substituter.SubstitutionFromHashtable(assumeMap); Substitution oldSubst = Substituter.SubstitutionFromHashtable(ogOldLocalMap); Substitution subst = Substituter.SubstitutionFromHashtable(map); List<Block> yieldCheckerBlocks = new List<Block>(); List<String> labels = new List<String>(); List<Block> labelTargets = new List<Block>(); Block yieldCheckerBlock = new Block(Token.NoToken, "exit", new List<Cmd>(), new ReturnCmd(Token.NoToken)); labels.Add(yieldCheckerBlock.Label); labelTargets.Add(yieldCheckerBlock); yieldCheckerBlocks.Add(yieldCheckerBlock); int yieldCount = 0; foreach (List<Cmd> cs in yields) { List<Cmd> newCmds = new List<Cmd>(); foreach (Cmd cmd in cs) { PredicateCmd predCmd = (PredicateCmd)cmd; newCmds.Add(new AssumeCmd(Token.NoToken, Substituter.ApplyReplacingOldExprs(assumeSubst, oldSubst, predCmd.Expr))); } foreach (Cmd cmd in cs) { PredicateCmd predCmd = (PredicateCmd)cmd; var newExpr = Substituter.ApplyReplacingOldExprs(subst, oldSubst, predCmd.Expr); if (predCmd is AssertCmd) { AssertCmd assertCmd = new AssertCmd(predCmd.tok, newExpr, predCmd.Attributes); assertCmd.ErrorData = "Non-interference check failed"; newCmds.Add(assertCmd); } else { newCmds.Add(new AssumeCmd(Token.NoToken, newExpr)); } } newCmds.Add(new AssumeCmd(Token.NoToken, Expr.False)); yieldCheckerBlock = new Block(Token.NoToken, "L" + yieldCount++, newCmds, new ReturnCmd(Token.NoToken)); labels.Add(yieldCheckerBlock.Label); labelTargets.Add(yieldCheckerBlock); yieldCheckerBlocks.Add(yieldCheckerBlock); } yieldCheckerBlocks.Insert(0, new Block(Token.NoToken, "enter", new List<Cmd>(), new GotoCmd(Token.NoToken, labels, labelTargets))); // Create the yield checker procedure var yieldCheckerName = string.Format("{0}_YieldChecker_{1}", "Impl", impl.Name); var yieldCheckerProc = new Procedure(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs, new List<Variable>(), new List<Requires>(), new List<IdentifierExpr>(), new List<Ensures>()); yieldCheckerProc.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); yieldCheckerProcs.Add(yieldCheckerProc); // Create the yield checker implementation var yieldCheckerImpl = new Implementation(Token.NoToken, yieldCheckerName, impl.TypeParameters, inputs, new List<Variable>(), locals, yieldCheckerBlocks); yieldCheckerImpl.Proc = yieldCheckerProc; yieldCheckerImpl.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); yieldCheckerImpls.Add(yieldCheckerImpl); }
private void AddYieldProcAndImpl(List<Declaration> decls) { if (yieldProc == null) return; Program program = linearTypeChecker.program; List<Variable> inputs = new List<Variable>(); foreach (string domainName in linearTypeChecker.linearDomains.Keys) { var domain = linearTypeChecker.linearDomains[domainName]; Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, "linear_" + domainName + "_in", new MapType(Token.NoToken, new List<TypeVariable>(), new List<Type> { domain.elementType }, Type.Bool)), true); inputs.Add(f); } foreach (IdentifierExpr ie in globalMods) { Formal f = new Formal(Token.NoToken, new TypedIdent(Token.NoToken, string.Format("og_global_old_{0}", ie.Decl.Name), ie.Decl.TypedIdent.Type), true); inputs.Add(f); } List<Block> blocks = new List<Block>(); TransferCmd transferCmd = new ReturnCmd(Token.NoToken); if (yieldCheckerProcs.Count > 0) { List<Block> blockTargets = new List<Block>(); List<String> labelTargets = new List<String>(); int labelCount = 0; foreach (Procedure proc in yieldCheckerProcs) { List<Expr> exprSeq = new List<Expr>(); foreach (Variable v in inputs) { exprSeq.Add(Expr.Ident(v)); } CallCmd callCmd = new CallCmd(Token.NoToken, proc.Name, exprSeq, new List<IdentifierExpr>()); callCmd.Proc = proc; string label = string.Format("L_{0}", labelCount++); Block block = new Block(Token.NoToken, label, new List<Cmd> { callCmd }, new ReturnCmd(Token.NoToken)); labelTargets.Add(label); blockTargets.Add(block); blocks.Add(block); } transferCmd = new GotoCmd(Token.NoToken, labelTargets, blockTargets); } blocks.Insert(0, new Block(Token.NoToken, "enter", new List<Cmd>(), transferCmd)); var yieldImpl = new Implementation(Token.NoToken, yieldProc.Name, new List<TypeVariable>(), inputs, new List<Variable>(), new List<Variable>(), blocks); yieldImpl.Proc = yieldProc; yieldImpl.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); decls.Add(yieldProc); decls.Add(yieldImpl); }
private static void CreateDispatchMethod(Sink sink, ITypeDefinition type, HashSet <IMethodDefinition> delegates) { Contract.Assert(type.IsDelegate); IMethodDefinition invokeMethod = null; foreach (IMethodDefinition m in type.Methods) { if (m.Name.Value == "Invoke") { invokeMethod = m; break; } } try { IMethodDefinition unspecializedInvokeMethod = Sink.Unspecialize(invokeMethod).ResolvedMethod; Sink.ProcedureInfo invokeProcedureInfo = sink.FindOrCreateProcedure(unspecializedInvokeMethod); Bpl.Procedure invokeProcedure = (Bpl.Procedure)invokeProcedureInfo.Decl; invokeProcedure.AddAttribute("inline", Bpl.Expr.Literal(1)); Bpl.Formal delegateVariable = invokeProcedureInfo.ThisVariable; Bpl.IToken token = invokeMethod.Token(); List <Bpl.Variable> dispatchProcInExprs = new List <Bpl.Variable>(); for (int i = 1; i < invokeProcedure.InParams.Count; i++) { Bpl.Variable v = invokeProcedure.InParams[i]; dispatchProcInExprs.Add(v); } List <Bpl.Variable> dispatchProcOutExprs = new List <Bpl.Variable>(); foreach (Bpl.Variable v in invokeProcedure.OutParams) { dispatchProcOutExprs.Add(v); } List <Bpl.Variable> localVariables = new List <Bpl.Variable>(); Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder(); int localCounter = 0; foreach (IMethodDefinition defn in delegates) { Bpl.Constant c = sink.FindOrCreateDelegateMethodConstant(defn); Sink.ProcedureInfo delegateProcedureInfo = sink.FindOrCreateProcedure(defn); Bpl.Procedure delegateProcedure = (Bpl.Procedure)delegateProcedureInfo.Decl; Bpl.Formal thisVariable = delegateProcedureInfo.ThisVariable; int numArguments = defn.ParameterCount; List <Bpl.Variable> tempInputs = new List <Bpl.Variable>(); List <Bpl.Variable> tempOutputs = new List <Bpl.Variable>(); for (int i = 0; i < defn.ParameterCount; i++) { Bpl.Variable v = delegateProcedure.InParams[(thisVariable == null ? 0 : 1) + i]; Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type)); localVariables.Add(localVariable); tempInputs.Add(localVariable); } for (int i = 0; i < delegateProcedure.OutParams.Count; i++) { Bpl.Variable v = delegateProcedure.OutParams[i]; Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type)); localVariables.Add(localVariable); tempOutputs.Add(localVariable); } List <Bpl.Expr> ins = new List <Bpl.Expr>(); List <Bpl.IdentifierExpr> outs = new List <Bpl.IdentifierExpr>(); if (!defn.IsStatic) { ins.Add(sink.ReadReceiver(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable))); } for (int i = 0; i < tempInputs.Count; i++) { ins.Add(Bpl.Expr.Ident(tempInputs[i])); } if (defn.IsGeneric) { for (int i = 0; i < defn.GenericParameterCount; i++) { ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)), new List <Bpl.Expr>(new Bpl.Expr[] { sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)) }))); } } if (defn.IsStatic) { int numTypeParameters = Sink.ConsolidatedGenericParameterCount(defn.ContainingType); for (int i = 0; i < numTypeParameters; i++) { ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)), new List <Bpl.Expr>(new Bpl.Expr[] { sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)) }))); } } for (int i = 0; i < tempOutputs.Count; i++) { outs.Add(Bpl.Expr.Ident(tempOutputs[i])); } Bpl.Expr bexpr = sink.ReadMethod(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)); Bpl.StmtListBuilder ifStmtBuilder = new Bpl.StmtListBuilder(); System.Diagnostics.Debug.Assert(tempInputs.Count == dispatchProcInExprs.Count); if (tempInputs.Count > 0) { BuildAssignment(sink, ifStmtBuilder, tempInputs, dispatchProcInExprs); } ifStmtBuilder.Add(EmitDummySourceContext()); ifStmtBuilder.Add(new Bpl.CallCmd(token, delegateProcedure.Name, ins, outs)); System.Diagnostics.Debug.Assert(tempOutputs.Count == dispatchProcOutExprs.Count); if (tempOutputs.Count > 0) { BuildAssignment(sink, ifStmtBuilder, dispatchProcOutExprs, tempOutputs); } stmtBuilder.Add(new Bpl.IfCmd(bexpr.tok, bexpr, ifStmtBuilder.Collect(bexpr.tok), null, null)); } Bpl.Implementation dispatchImpl = new Bpl.Implementation(token, invokeProcedure.Name, new List <Bpl.TypeVariable>(), invokeProcedure.InParams, invokeProcedure.OutParams, localVariables, stmtBuilder.Collect(token) ); dispatchImpl.Proc = invokeProcedure; dispatchImpl.AddAttribute("inline", Bpl.Expr.Literal(1)); sink.TranslatedProgram.AddTopLevelDeclaration(dispatchImpl); } catch (TranslationException te) { throw new NotImplementedException(te.ToString()); } catch { throw; } finally { // Maybe this is a good place to add the procedure to the toplevel declarations } }
private static void CreateDispatchMethod(Sink sink, ITypeDefinition type, HashSet<IMethodDefinition> delegates) { Contract.Assert(type.IsDelegate); IMethodDefinition invokeMethod = null; foreach (IMethodDefinition m in type.Methods) { if (m.Name.Value == "Invoke") { invokeMethod = m; break; } } try { IMethodDefinition unspecializedInvokeMethod = Sink.Unspecialize(invokeMethod).ResolvedMethod; Sink.ProcedureInfo invokeProcedureInfo = sink.FindOrCreateProcedure(unspecializedInvokeMethod); Bpl.Procedure invokeProcedure = (Bpl.Procedure) invokeProcedureInfo.Decl; invokeProcedure.AddAttribute("inline", Bpl.Expr.Literal(1)); Bpl.Formal delegateVariable = invokeProcedureInfo.ThisVariable; Bpl.IToken token = invokeMethod.Token(); List<Bpl.Variable> dispatchProcInExprs = new List<Bpl.Variable>(); for (int i = 1; i < invokeProcedure.InParams.Count; i++) { Bpl.Variable v = invokeProcedure.InParams[i]; dispatchProcInExprs.Add(v); } List<Bpl.Variable> dispatchProcOutExprs = new List<Bpl.Variable>(); foreach (Bpl.Variable v in invokeProcedure.OutParams) { dispatchProcOutExprs.Add(v); } List<Bpl.Variable> localVariables = new List<Bpl.Variable>(); Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder(); int localCounter = 0; foreach (IMethodDefinition defn in delegates) { Bpl.Constant c = sink.FindOrCreateDelegateMethodConstant(defn); Sink.ProcedureInfo delegateProcedureInfo = sink.FindOrCreateProcedure(defn); Bpl.Procedure delegateProcedure = (Bpl.Procedure)delegateProcedureInfo.Decl; Bpl.Formal thisVariable = delegateProcedureInfo.ThisVariable; int numArguments = defn.ParameterCount; List<Bpl.Variable> tempInputs = new List<Bpl.Variable>(); List<Bpl.Variable> tempOutputs = new List<Bpl.Variable>(); for (int i = 0; i < defn.ParameterCount; i++) { Bpl.Variable v = delegateProcedure.InParams[(thisVariable == null ? 0 : 1) + i]; Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type)); localVariables.Add(localVariable); tempInputs.Add(localVariable); } for (int i = 0; i < delegateProcedure.OutParams.Count; i++) { Bpl.Variable v = delegateProcedure.OutParams[i]; Bpl.LocalVariable localVariable = new Bpl.LocalVariable(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "local" + localCounter++, v.TypedIdent.Type)); localVariables.Add(localVariable); tempOutputs.Add(localVariable); } List<Bpl.Expr> ins = new List<Bpl.Expr>(); List<Bpl.IdentifierExpr> outs = new List<Bpl.IdentifierExpr>(); if (!defn.IsStatic) ins.Add(sink.ReadReceiver(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable))); for (int i = 0; i < tempInputs.Count; i++) { ins.Add(Bpl.Expr.Ident(tempInputs[i])); } if (defn.IsGeneric) { for (int i = 0; i < defn.GenericParameterCount; i++) { ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)), new List<Bpl.Expr>(new Bpl.Expr[] {sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable))}))); } } if (defn.IsStatic) { int numTypeParameters = Sink.ConsolidatedGenericParameterCount(defn.ContainingType); for (int i = 0; i < numTypeParameters; i++) { ins.Add(new Bpl.NAryExpr(Bpl.Token.NoToken, new Bpl.FunctionCall(sink.FindOrCreateTypeParameterFunction(i)), new List<Bpl.Expr>(new Bpl.Expr[] {sink.ReadTypeParameters(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable))}))); } } for (int i = 0; i < tempOutputs.Count; i++) { outs.Add(Bpl.Expr.Ident(tempOutputs[i])); } Bpl.Expr bexpr = sink.ReadMethod(Bpl.Expr.Ident(c), Bpl.Expr.Ident(delegateVariable)); Bpl.StmtListBuilder ifStmtBuilder = new Bpl.StmtListBuilder(); System.Diagnostics.Debug.Assert(tempInputs.Count == dispatchProcInExprs.Count); if (tempInputs.Count > 0) { BuildAssignment(sink, ifStmtBuilder, tempInputs, dispatchProcInExprs); } ifStmtBuilder.Add(EmitDummySourceContext()); ifStmtBuilder.Add(new Bpl.CallCmd(token, delegateProcedure.Name, ins, outs)); System.Diagnostics.Debug.Assert(tempOutputs.Count == dispatchProcOutExprs.Count); if (tempOutputs.Count > 0) { BuildAssignment(sink, ifStmtBuilder, dispatchProcOutExprs, tempOutputs); } stmtBuilder.Add(new Bpl.IfCmd(bexpr.tok, bexpr, ifStmtBuilder.Collect(bexpr.tok), null, null)); } Bpl.Implementation dispatchImpl = new Bpl.Implementation(token, invokeProcedure.Name, new List<Bpl.TypeVariable>(), invokeProcedure.InParams, invokeProcedure.OutParams, localVariables, stmtBuilder.Collect(token) ); dispatchImpl.Proc = invokeProcedure; dispatchImpl.AddAttribute("inline", Bpl.Expr.Literal(1)); sink.TranslatedProgram.AddTopLevelDeclaration(dispatchImpl); } catch (TranslationException te) { throw new NotImplementedException(te.ToString()); } catch { throw; } finally { // Maybe this is a good place to add the procedure to the toplevel declarations } }
private static void CreateDelegateRemoveMethod(Sink sink, ITypeDefinition type, HashSet<IMethodDefinition> delegates) { Bpl.Formal a = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "a", sink.Heap.RefType), true); Bpl.Formal b = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "b", sink.Heap.RefType), true); Bpl.Formal c = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false); Bpl.IdentifierExpr aExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, a); Bpl.IdentifierExpr bExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, b); Bpl.IdentifierExpr cExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, c); Bpl.Procedure proc = new Bpl.Procedure( Bpl.Token.NoToken, sink.DelegateRemove(type), new List<Bpl.TypeVariable>(), new List<Bpl.Variable>(new Bpl.Variable[] { a, b }), new List<Bpl.Variable>(new Bpl.Variable[] {c}), new List<Bpl.Requires>(), new List<Bpl.IdentifierExpr>(), new List<Bpl.Ensures>()); proc.AddAttribute("inline", Bpl.Expr.Literal(1)); sink.TranslatedProgram.AddTopLevelDeclaration(proc); Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder(); stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List<Bpl.Expr>(), new List<Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] {cExpr}))); foreach (IMethodDefinition defn in delegates) { Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn)); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, cExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.And, sink.ReadMethod(cie, aExpr), Bpl.Expr.Unary(Bpl.Token.NoToken, Bpl.UnaryOperator.Opcode.Not, sink.ReadMethod(cie, bExpr)))))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(cie, cExpr), sink.ReadReceiver(cie, aExpr)))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(cie, cExpr), sink.ReadTypeParameters(cie, aExpr)))); } Bpl.IdentifierExpr nullExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.Heap.NullRef); Bpl.IfCmd ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, bExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, aExpr), stmtBuilder.Collect(Bpl.Token.NoToken)); ifCmd = BuildIfCmd(Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, aExpr, nullExpr), TranslationHelper.BuildAssignCmd(cExpr, nullExpr), ifCmd); Bpl.Implementation impl = new Bpl.Implementation( Bpl.Token.NoToken, sink.DelegateRemove(type), new List<Bpl.TypeVariable>(), new List<Bpl.Variable>(new Bpl.Variable[] { a, b }), new List<Bpl.Variable>(new Bpl.Variable[] {c}), new List<Bpl.Variable>(), BuildStmtList(ifCmd) ); impl.AddAttribute("inline", Bpl.Expr.Literal(1)); impl.Proc = proc; sink.TranslatedProgram.AddTopLevelDeclaration(impl); }
private static void CreateDelegateCreateMethod(Sink sink, ITypeDefinition type, HashSet<IMethodDefinition> delegates) { Bpl.Formal method = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Method", Bpl.Type.Int), true); Bpl.Formal receiver = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "Receiver", sink.Heap.RefType), true); Bpl.Formal typeParameters = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "TypeParameters", sink.Heap.TypeType), true); Bpl.Formal returnDelegate = new Bpl.Formal(Bpl.Token.NoToken, new Bpl.TypedIdent(Bpl.Token.NoToken, "c", sink.Heap.RefType), false); Bpl.IdentifierExpr methodExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, method); Bpl.IdentifierExpr receiverExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, receiver); Bpl.IdentifierExpr typeParametersExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, typeParameters); Bpl.IdentifierExpr returnDelegateExpr = new Bpl.IdentifierExpr(Bpl.Token.NoToken, returnDelegate); Bpl.Procedure proc = new Bpl.Procedure( Bpl.Token.NoToken, sink.DelegateCreate(type), new List<Bpl.TypeVariable>(), new List<Bpl.Variable>(new Bpl.Variable[] {method, receiver, typeParameters}), new List<Bpl.Variable>(new Bpl.Variable[] {returnDelegate}), new List<Bpl.Requires>(), new List<Bpl.IdentifierExpr>(), new List<Bpl.Ensures>()); proc.AddAttribute("inline", Bpl.Expr.Literal(1)); sink.TranslatedProgram.AddTopLevelDeclaration(proc); Bpl.StmtListBuilder stmtBuilder = new Bpl.StmtListBuilder(); stmtBuilder.Add(new Bpl.CallCmd(Bpl.Token.NoToken, "Alloc", new List<Bpl.Expr>(), new List<Bpl.IdentifierExpr>(new Bpl.IdentifierExpr[] {returnDelegateExpr}))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadReceiver(methodExpr, returnDelegateExpr), receiverExpr))); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, sink.ReadTypeParameters(methodExpr, returnDelegateExpr), typeParametersExpr))); foreach (IMethodDefinition defn in delegates) { Bpl.IdentifierExpr cie = new Bpl.IdentifierExpr(Bpl.Token.NoToken, sink.FindOrCreateDelegateMethodConstant(defn)); stmtBuilder.Add(new Bpl.AssumeCmd(Bpl.Token.NoToken, Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Iff, sink.ReadMethod(cie, returnDelegateExpr), Bpl.Expr.Binary(Bpl.BinaryOperator.Opcode.Eq, methodExpr, cie)))); } Bpl.Implementation impl = new Bpl.Implementation( Bpl.Token.NoToken, sink.DelegateCreate(type), new List<Bpl.TypeVariable>(), new List<Bpl.Variable>(new Bpl.Variable[] { method, receiver, typeParameters }), new List<Bpl.Variable>(new Bpl.Variable[] {returnDelegate}), new List<Bpl.Variable>(), stmtBuilder.Collect(Bpl.Token.NoToken)); impl.AddAttribute("inline", Bpl.Expr.Literal(1)); impl.Proc = proc; sink.TranslatedProgram.AddTopLevelDeclaration(impl); }
public static void AddCheckers(LinearTypeChecker linearTypeChecker, MoverTypeChecker moverTypeChecker, List<Declaration> decls) { Program program = linearTypeChecker.program; foreach (int phaseNum in moverTypeChecker.assertionPhaseNums) { MyDuplicator duplicator = new MyDuplicator(moverTypeChecker, phaseNum); List<Implementation> impls = new List<Implementation>(); List<Procedure> procs = new List<Procedure>(); foreach (var decl in program.TopLevelDeclarations) { Procedure proc = decl as Procedure; if (proc == null || !QKeyValue.FindBoolAttribute(proc.Attributes, "yields")) continue; Procedure duplicateProc = duplicator.VisitProcedure(proc); procs.Add(duplicateProc); if (moverTypeChecker.procToActionInfo.ContainsKey(proc) && moverTypeChecker.procToActionInfo[proc].phaseNum < phaseNum) { duplicateProc.Attributes = OwickiGries.RemoveYieldsAttribute(duplicateProc.Attributes); program.GlobalVariables().Iter(x => duplicateProc.Modifies.Add(new IdentifierExpr(Token.NoToken, x))); CodeExpr action = (CodeExpr)duplicator.VisitCodeExpr(moverTypeChecker.procToActionInfo[proc].thisAction); Implementation impl = new Implementation(Token.NoToken, duplicateProc.Name, proc.TypeParameters, proc.InParams, proc.OutParams, new List<Variable>(), action.Blocks); impl.Proc = duplicateProc; impl.Proc.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); impl.AddAttribute("inline", new LiteralExpr(Token.NoToken, Microsoft.Basetypes.BigNum.FromInt(1))); impls.Add(impl); } } foreach (var decl in program.TopLevelDeclarations) { Implementation impl = decl as Implementation; if (impl == null || !QKeyValue.FindBoolAttribute(impl.Proc.Attributes, "yields") || (moverTypeChecker.procToActionInfo.ContainsKey(impl.Proc) && moverTypeChecker.procToActionInfo[impl.Proc].phaseNum < phaseNum)) continue; Implementation duplicateImpl = duplicator.VisitImplementation(impl); impls.Add(duplicateImpl); } Dictionary<Absy, Absy> reverseAbsyMap = new Dictionary<Absy, Absy>(); foreach (Absy key in duplicator.absyMap.Keys) { reverseAbsyMap[duplicator.absyMap[key]] = key; } OwickiGries ogTransform = new OwickiGries(linearTypeChecker, reverseAbsyMap, phaseNum, decls); ogTransform.Transform(impls, procs); } }