示例#1
0
        //Build Memory Map for Array types,
        private void ConstructArrayMemoryMap(ArrayTypeName array, HashSet <KeyValuePair <BoogieType, BoogieType> > generatedTypes)
        {
            BoogieType boogieKeyType   = BoogieType.Int;
            BoogieType boogieValueType = null;

            if (array.BaseType is ArrayTypeName subarray)
            {
                boogieValueType = BoogieType.Ref;
                ConstructArrayMemoryMap(subarray, generatedTypes); //construct array memory map with sub array
            }
            else if (array.BaseType is Mapping mapping)
            {
                boogieValueType = BoogieType.Ref;
                ConstructMappingMemoryArray(mapping, generatedTypes); // construct array memory map using mapping type
            }
            else
            {
                boogieValueType = Conversion_Utility_Tool.GetBoogieTypeFromSolidityTypeName(array.BaseType); //type cannot be resolve, request type declaration
            }

            KeyValuePair <BoogieType, BoogieType> pair = new KeyValuePair <BoogieType, BoogieType>(boogieKeyType, boogieValueType);

            if (generatedTypes.Contains(pair) == false)
            {
                generatedTypes.Add(pair);
                BuildSingleMapMemoryName(boogieKeyType, boogieValueType);
            }
        }
示例#2
0
        //Construct Memory Maps for Arrays for Mapping and ArrayTypeName types.
        private void ConstructMappingMemoryArray(Mapping mapping, HashSet <KeyValuePair <BoogieType, BoogieType> > generatedTypes)
        {
            BoogieType boogieKeyType   = Conversion_Utility_Tool.GetBoogieTypeFromSolidityTypeName(mapping.KeyType);
            BoogieType boogieValueType = null;

            if (mapping.ValueType is Mapping submapping)
            {
                boogieValueType = BoogieType.Ref;
                ConstructMappingMemoryArray(submapping, generatedTypes);
            }
            else if (mapping.ValueType is ArrayTypeName array)
            {
                boogieValueType = BoogieType.Ref;
                ConstructArrayMemoryMap(array, generatedTypes);
            }
            else
            {
                boogieValueType = Conversion_Utility_Tool.GetBoogieTypeFromSolidityTypeName(mapping.ValueType);
            }

            KeyValuePair <BoogieType, BoogieType> pair = new KeyValuePair <BoogieType, BoogieType>(boogieKeyType, boogieValueType);

            if (!generatedTypes.Contains(pair))
            {
                generatedTypes.Add(pair);
                BuildSingleMapMemoryName(boogieKeyType, boogieValueType);
            }
        }
示例#3
0
        private void GenerateStructConstructors(ContractDefinition contract, StructDefinition structDefn)
        {
            // generate the internal one without base constructors
            string procName = structDefn.CanonicalName + "_ctor";
            List <BoogieVariable> inParams = new List <BoogieVariable>();

            inParams.AddRange(Conversion_Utility_Tool.GetDefaultInParams());
            foreach (var member in structDefn.Members)
            {
                Debug.Assert(!member.TypeDescriptions.IsStruct(), "Do no handle nested structs yet!");
                var formalType = Conversion_Utility_Tool.GetBoogieTypeFromSolidityTypeName(member.TypeName);
                var formalName = member.Name;
                inParams.Add(new BoogieFormalParam(new BoogieTypedIdent(formalName, formalType)));
            }

            List <BoogieVariable>  outParams  = new List <BoogieVariable>();
            List <BoogieAttribute> attributes = new List <BoogieAttribute>();

            if (Flags_HelperClass.GenerateInlineAttributes)
            {
                attributes.Add(new BoogieAttribute("inline", 1));
            }
            ;
            BoogieProcedure procedure = new BoogieProcedure(procName, inParams, outParams, attributes);

            context.getProgram.AddBoogieDeclaration(procedure);

            List <BoogieVariable> localVars = new List <BoogieVariable>();
            BoogieStmtList        procBody  = new BoogieStmtList();

            foreach (var member in structDefn.Members)
            {
                Debug.Assert(!member.TypeDescriptions.IsStruct(), "Do no handle nested structs yet!");
                var mapName       = member.Name + "_" + structDefn.CanonicalName;
                var formalName    = member.Name;
                var mapSelectExpr = new BoogieMapSelect(new BoogieIdentifierExpr(mapName), new BoogieIdentifierExpr("this"));
                procBody.AddStatement(new BoogieAssignCmd(mapSelectExpr, new BoogieIdentifierExpr(member.Name)));
            }

            BoogieImplementation implementation = new BoogieImplementation(procName, inParams, outParams, localVars, procBody);

            context.getProgram.AddBoogieDeclaration(implementation);
        }
        public static List <BoogieVariable> CollectLocalVars(List <ContractDefinition> contracts, AST_Handler context)
        {
            Debug.Assert(contracts.Count > 0, "Internal exception: expecting at least one contract here");
            List <BoogieVariable> localVars = new List <BoogieVariable>()
            {
                new BoogieLocalVariable(new BoogieTypedIdent("this", BoogieType.Ref)),
                new BoogieLocalVariable(new BoogieTypedIdent("msgsender_MSG", BoogieType.Ref)),
                new BoogieLocalVariable(new BoogieTypedIdent("msgvalue_MSG", BoogieType.Int)),
                new BoogieLocalVariable(new BoogieTypedIdent("choice", BoogieType.Int)),
            };

            // use to remove duplicated variables by name
            HashSet <string> uniqueVarNames = new HashSet <string>()
            {
                "this", "msgsender_MSG", "msgvalue_MSG", "choice"
            };

            foreach (var contract in contracts)
            {
                if (contract.ContractKind != EnumContractKind.CONTRACT)
                {
                    continue;
                }

                // Consider all visible functions
                HashSet <FunctionDefinition> funcDefs = context.RetrieveVisibleFunctions(contract);
                foreach (FunctionDefinition funcDef in funcDefs)
                {
                    if (funcDef.Visibility == EnumVisibility.PUBLIC || funcDef.Visibility == EnumVisibility.EXTERNAL)
                    {
                        var inpParamCount = 0;
                        foreach (VariableDeclaration param in funcDef.Parameters.Parameters)
                        {
                            string name = $"__arg_{inpParamCount++}_" + funcDef.Name;
                            if (!string.IsNullOrEmpty(param.Name))
                            {
                                name = Conversion_Utility_Tool.GetCanonicalLocalVariableName(param, context);
                            }
                            if (!uniqueVarNames.Contains(name))
                            {
                                BoogieType     type     = Conversion_Utility_Tool.GetBoogieTypeFromSolidityTypeName(param.TypeName);
                                BoogieVariable localVar = new BoogieLocalVariable(new BoogieTypedIdent(name, type));
                                localVars.Add(localVar);
                                uniqueVarNames.Add(name);
                            }
                        }

                        var retParamCount = 0;
                        foreach (VariableDeclaration param in funcDef.ReturnParameters.Parameters)
                        {
                            string name = $"__ret_{retParamCount++}_" + funcDef.Name;
                            if (!string.IsNullOrEmpty(param.Name))
                            {
                                name = Conversion_Utility_Tool.GetCanonicalLocalVariableName(param, context);
                            }
                            if (!uniqueVarNames.Contains(name))
                            {
                                BoogieType     type     = Conversion_Utility_Tool.GetBoogieTypeFromSolidityTypeName(param.TypeName);
                                BoogieVariable localVar = new BoogieLocalVariable(new BoogieTypedIdent(name, type));
                                localVars.Add(localVar);
                                uniqueVarNames.Add(name);
                            }
                        }
                    }
                }
            }
            return(localVars);
        }