//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); } }
//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); } }
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); }