예제 #1
0
    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);
    }
예제 #2
0
    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
      }
    }
예제 #3
0
    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);
    }