Skip to content

Commit

Permalink
Merge pull request #303 from maxime-esa/EfficientEnumEncodings
Browse files Browse the repository at this point in the history
Efficient enum encodings
  • Loading branch information
usr3-1415 authored Apr 20, 2024
2 parents 6a2c5da + f9071b4 commit e1f6ca1
Show file tree
Hide file tree
Showing 27 changed files with 403 additions and 75 deletions.
25 changes: 21 additions & 4 deletions BackendAst/DAstACN.fs
Original file line number Diff line number Diff line change
Expand Up @@ -551,12 +551,16 @@ let createEnumCommon (r:Asn1AcnAst.AstRoot) (lm:LanguageMacros) (codec:CommonTyp
let EnumeratedEncValues = lm.acn.EnumeratedEncValues
let Enumerated_item = lm.acn.Enumerated_item
let IntFullyConstraintPos = lm.uper.IntFullyConstraintPos
let Enumerated_no_switch = lm.acn.EnumeratedEncValues_no_switch

let min = o.items |> List.map(fun x -> x.acnEncodeValue) |> Seq.min
let max = o.items |> List.map(fun x -> x.acnEncodeValue) |> Seq.max
let sFirstItemName = lm.lg.getNamedItemBackendName (Some defOrRef) o.items.Head
let uperRange = (Concrete (min,max))
let intTypeClass = getIntEncodingClassByUperRange r.args uperRange
let rtlIntType = (DAstTypeDefinition.getIntegerTypeByClass lm intTypeClass)()
let nLastItemIndex = BigInteger(Seq.length o.items) - 1I

let funcBody (errCode:ErrorCode) (acnArgs: (AcnGenericTypes.RelativePath*AcnGenericTypes.AcnParameter) list) (nestingScope: NestingScope) (p:CallerScope) =
let td = (lm.lg.getEnumTypeDefinition o.typeDef).longTypedefName2 lm.lg.hasModules (ToC p.modName)
let localVar, intVal =
Expand Down Expand Up @@ -586,10 +590,23 @@ let createEnumCommon (r:Asn1AcnAst.AstRoot) (lm:LanguageMacros) (codec:CommonTyp
match intFuncBody errCode acnArgs nestingScope pVal with
| None -> None
| Some intAcnFuncBdResult ->
let arrItems = o.items |> List.map(fun it ->
let enumClassName = extractEnumClassName "" it.scala_name it.Name.Value
Enumerated_item (lm.lg.getValue p.arg) (lm.lg.getNamedItemBackendName (Some defOrRef) it) enumClassName it.acnEncodeValue (lm.lg.intValueToString it.acnEncodeValue intTypeClass) intVal codec)
Some (EnumeratedEncValues (lm.lg.getValue p.arg) td arrItems intAcnFuncBdResult.funcBody errCode.errCodeName sFirstItemName intVal codec, intAcnFuncBdResult.resultExpr, intAcnFuncBdResult.errCodes, localVar@intAcnFuncBdResult.localVariables, intAcnFuncBdResult.typeEncodingKind)
let resultExpr, errCodes, typeEncodingKind =
intAcnFuncBdResult.resultExpr, intAcnFuncBdResult.errCodes, intAcnFuncBdResult.typeEncodingKind
let mainContent, localVariables =
match r.args.isEnumEfficientEnabled o.items.Length with
| false ->
let arrItems =
o.items |>
List.map(fun it ->
let enumClassName = extractEnumClassName "" it.scala_name it.Name.Value
Enumerated_item (lm.lg.getValue p.arg) (lm.lg.getNamedItemBackendName (Some defOrRef) it) enumClassName it.acnEncodeValue (lm.lg.intValueToString it.acnEncodeValue intTypeClass) intVal codec)
EnumeratedEncValues (lm.lg.getValue p.arg) td arrItems intAcnFuncBdResult.funcBody errCode.errCodeName sFirstItemName intVal codec, localVar@intAcnFuncBdResult.localVariables
| true ->
let sEnumIndex = "nEnumIndex"
let enumIndexVar = (Asn1SIntLocalVariable (sEnumIndex, None))
Enumerated_no_switch (lm.lg.getValue p.arg) td intAcnFuncBdResult.funcBody errCode.errCodeName sFirstItemName intVal sEnumIndex nLastItemIndex o.encodeValues codec, enumIndexVar::localVar@intAcnFuncBdResult.localVariables
Some (mainContent, resultExpr, errCodes, localVariables, typeEncodingKind)

match funcBodyContent with
| None -> None
| Some (funcBodyContent, resultExpr, errCodes, localVariables, typeEncodingKind) ->
Expand Down
144 changes: 104 additions & 40 deletions BackendAst/DAstTypeDefinition.fs

Large diffs are not rendered by default.

32 changes: 22 additions & 10 deletions BackendAst/DAstUPer.fs
Original file line number Diff line number Diff line change
Expand Up @@ -293,21 +293,33 @@ let createNullTypeFunction (r:Asn1AcnAst.AstRoot) (lm:LanguageMacros) (codec:Co
createUperFunction r lm codec t typeDefinition baseTypeUperFunc isValidFunc funcBody soSparkAnnotations [] us

let createEnumeratedFunction (r:Asn1AcnAst.AstRoot) (lm:LanguageMacros) (codec:CommonTypes.Codec) (t:Asn1AcnAst.Asn1Type) (o:Asn1AcnAst.Enumerated) (typeDefinition:TypeDefinitionOrReference) (baseTypeUperFunc : UPerFunction option) (isValidFunc: IsValidFunction option) (us:State) =

let Enumerated = lm.uper.Enumerated
let Enumerated_item = lm.uper.Enumerated_item
let Enumerated_no_switch = lm.uper.Enumerated_no_switch


let funcBody (errCode:ErrorCode) (nestingScope: NestingScope) (p:CallerScope) =
let Enumerated = lm.uper.Enumerated
let Enumerated_item = lm.uper.Enumerated_item
let nMax = BigInteger(Seq.length o.items) - 1I
let nLastItemIndex = nMax
let typeDef0 = lm.lg.getEnumTypeDefinition o.typeDef
let td = typeDef0.longTypedefName2 lm.lg.hasModules (ToC p.modName)
let pp, resultExpr = adaptArgumentValue lm codec p
let nMin = 0I
let nMax = BigInteger(Seq.length o.items) - 1I
let nLastItemIndex = nMax
let items =
o.items |> List.mapi(fun i itm -> Enumerated_item pp (lm.lg.getNamedItemBackendName (Some typeDefinition) itm) (BigInteger i) nLastItemIndex codec)
let nBits = (GetNumberOfBitsForNonNegativeInteger (nMax-nMin))
let sFirstItemName = lm.lg.getNamedItemBackendName (Some typeDefinition) o.items.Head
let funcBodyContent = Enumerated pp td items nMin nMax nBits errCode.errCodeName nLastItemIndex sFirstItemName codec
{UPERFuncBodyResult.funcBody = funcBodyContent; errCodes = [errCode]; localVariables = []; bValIsUnReferenced=false; bBsIsUnReferenced=false; resultExpr=resultExpr; typeEncodingKind=Some (Asn1IntegerEncodingType (Some (FullyConstrained (nMin, nMax))))}
let nMin = 0I
match r.args.isEnumEfficientEnabled o.items.Length with
| false ->
let items =
o.items |> List.mapi(fun i itm -> Enumerated_item pp (lm.lg.getNamedItemBackendName (Some typeDefinition) itm) (BigInteger i) nLastItemIndex codec)
let nBits = (GetNumberOfBitsForNonNegativeInteger (nMax-nMin))
let funcBodyContent = Enumerated pp td items nMin nMax nBits errCode.errCodeName nLastItemIndex sFirstItemName codec
{UPERFuncBodyResult.funcBody = funcBodyContent; errCodes = [errCode]; localVariables = []; bValIsUnReferenced=false; bBsIsUnReferenced=false; resultExpr=resultExpr; typeEncodingKind=Some (Asn1IntegerEncodingType (Some (FullyConstrained (nMin, nMax))))}
| true ->
let sEnumIndex = "nEnumIndex"
let enumIndexVar = (Asn1SIntLocalVariable (sEnumIndex, None))
let funcBodyContent = Enumerated_no_switch pp td errCode.errCodeName sEnumIndex nLastItemIndex sFirstItemName codec
{UPERFuncBodyResult.funcBody = funcBodyContent; errCodes = [errCode]; localVariables = [enumIndexVar]; bValIsUnReferenced=false; bBsIsUnReferenced=false; resultExpr=resultExpr; typeEncodingKind=Some (Asn1IntegerEncodingType (Some (FullyConstrained (nMin, nMax))))}

let soSparkAnnotations = Some(sparkAnnotations lm (lm.lg.getLongTypedefName typeDefinition) codec)
createUperFunction r lm codec t typeDefinition baseTypeUperFunc isValidFunc (fun e ns p -> Some (funcBody e ns p)) soSparkAnnotations [] us

Expand Down
24 changes: 21 additions & 3 deletions BackendAst/DastValidate2.fs
Original file line number Diff line number Diff line change
Expand Up @@ -691,9 +691,24 @@ let createTimeTypeFunction (r:Asn1AcnAst.AstRoot) (l:LanguageMacros) (t:Asn1AcnA
createIsValidFunction r l t (funcBody l fncs) typeDefinition [] [] [] [] (Some errorCodeComment) ns


let createEfficientEnumValidation (r:Asn1AcnAst.AstRoot) (l:LanguageMacros) (o:Asn1AcnAst.Enumerated) (us:State) =
let getEnumIndexByName = l.isvalid.GetEnumIndexByName
let td = (l.lg.getEnumTypeDefinition o.typeDef)
let bSorted =
let sortedItems = o.validItems |> List.map(fun x -> x.definitionValue) |> List.sort
let items = o.validItems |> List.map(fun x -> x.definitionValue)
sortedItems = items
let optimizedValidation (p:CallerScope) =
let ret = getEnumIndexByName td.values_array td.values_array_count (l.lg.getValue p.arg) bSorted
VCBExpression (ret)
[optimizedValidation], us


let createEnumeratedFunction (r:Asn1AcnAst.AstRoot) (l:LanguageMacros) (t:Asn1AcnAst.Asn1Type) (o:Asn1AcnAst.Enumerated) (typeDefinition:TypeDefinitionOrReference) (us:State) =
let fncs, ns = o.cons |> Asn1Fold.foldMap (fun us c -> enumeratedConstraint2ValidationCodeBlock l o typeDefinition c us) us
let fncs, ns =
match r.args.isEnumEfficientEnabled o.items.Length with
| false -> o.cons |> Asn1Fold.foldMap (fun us c -> enumeratedConstraint2ValidationCodeBlock l o typeDefinition c us) us
| true -> createEfficientEnumValidation r l o us
let errorCodeComment = o.cons |> List.map(fun z -> z.ASN1) |> Seq.StrJoin ""
createIsValidFunction r l t (funcBody l fncs) typeDefinition [] [] [] [] (Some errorCodeComment) ns

Expand Down Expand Up @@ -933,8 +948,11 @@ let rec createReferenceTypeFunction_this_type (r:Asn1AcnAst.AstRoot) (l:Language
| NullType _ ->
[],us
| Enumerated en ->
let cons = refCons |> List.choose(fun c -> match c with Asn1AcnAst.EnumConstraint z -> Some z | _ -> None )
cons |> Asn1Fold.foldMap (fun us c -> enumeratedConstraint2ValidationCodeBlock l en.baseInfo typeDefinition c us) us
match r.args.isEnumEfficientEnabled en.baseInfo.items.Length with
| false ->
let cons = refCons |> List.choose(fun c -> match c with Asn1AcnAst.EnumConstraint z -> Some z | _ -> None )
cons |> Asn1Fold.foldMap (fun us c -> enumeratedConstraint2ValidationCodeBlock l en.baseInfo typeDefinition c us) us
| true -> createEfficientEnumValidation r l en.baseInfo us
| Choice ch ->
let valToStrFunc (p:CallerScope) (v:Asn1AcnAst.ChValue) = VCBTrue
let cons = refCons |> List.choose(fun c -> match c with Asn1AcnAst.ChoiceConstraint z -> Some z | _ -> None )
Expand Down
8 changes: 7 additions & 1 deletion BackendAst/GenerateFiles.fs
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,12 @@ let private printUnit (r:DAst.AstRoot) (lm:LanguageMacros) (encodings: CommonTy
//sourse file
let arrsTypeAssignments =
tases |> List.map(fun t ->
let privateDefinition =
match t.Type.typeDefinitionOrReference with
| TypeDefinition td -> td.privateTypeDefinition
| ReferenceToExistingDefinition _ -> None


let initialize =
match lm.lg.initMethod with
| InitMethod.Procedure ->
Expand Down Expand Up @@ -256,7 +262,7 @@ let private printUnit (r:DAst.AstRoot) (lm:LanguageMacros) (encodings: CommonTy
| CommonTypes.Encode -> match t.Type.acnEncFunction with None -> None | Some x -> x.func
| CommonTypes.Decode -> match t.Type.acnDecFunction with None -> None | Some x -> x.func
| false -> None
let allProcs = eqFuncs@isValidFuncs@special_init_funcs@([init_globals;initialize; (uperEncDec CommonTypes.Encode); (uperEncDec CommonTypes.Decode);(ancEncDec CommonTypes.Encode); (ancEncDec CommonTypes.Decode);(xerEncDec CommonTypes.Encode); (xerEncDec CommonTypes.Decode)] |> List.choose id)
let allProcs = ([privateDefinition]|>List.choose id)@eqFuncs@isValidFuncs@special_init_funcs@([init_globals;initialize; (uperEncDec CommonTypes.Encode); (uperEncDec CommonTypes.Decode);(ancEncDec CommonTypes.Encode); (ancEncDec CommonTypes.Decode);(xerEncDec CommonTypes.Encode); (xerEncDec CommonTypes.Decode)] |> List.choose id)
lm.src.printTass allProcs )


Expand Down
5 changes: 5 additions & 0 deletions CommonTypes/AbstractMacros.fs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ Generated by the C stg macros with the following command
abstract member Define_new_enumerated_item_macro : td:FE_EnumeratedTypeDefinition -> sAsn1Name:string -> sCName:string -> string;
abstract member Define_new_enumerated : td:FE_EnumeratedTypeDefinition -> arrsEnumNames:seq<string> -> arrsEnumNamesAndValues:seq<string> -> nIndexMax:BigInteger -> arrsResolvingMacros:seq<string> -> string;
abstract member Define_subType_enumerated : td:FE_EnumeratedTypeDefinition -> prTd:FE_EnumeratedTypeDefinition -> soParentTypePackage:string option -> string;
abstract member Define_new_enumerated_private : td:FE_EnumeratedTypeDefinition -> arrsValidEnumNames:seq<string> -> arrsEnumNames:seq<string> -> string;
abstract member Define_subType_enumerated_private : td:FE_EnumeratedTypeDefinition -> prTd:FE_EnumeratedTypeDefinition -> arrsValidEnumNames:seq<string> -> arrsEnumNames:seq<string> -> string;
abstract member Define_new_ia5string : td:FE_StringTypeDefinition -> nMin:BigInteger -> nMax:BigInteger -> nCMax:BigInteger -> arrnAlphaChars:seq<BigInteger> -> string;
abstract member Define_subType_ia5string : td:FE_StringTypeDefinition -> prTd:FE_StringTypeDefinition -> soParentTypePackage:string option -> string;
abstract member Define_new_octet_string : td:FE_SizeableTypeDefinition -> nMin:BigInteger -> nMax:BigInteger -> bFixedSize:bool -> string;
Expand Down Expand Up @@ -175,6 +177,7 @@ Generated by the C stg macros with the following command
abstract member EmitTypeAssignment_composite_def_err_code : sErrCode:string -> nErrValue:BigInteger -> arrsErrorCodeComments:seq<string> -> string;
abstract member EmitTypeAssignment_composite_def : sVarName:string -> sStar:string -> sFuncName:string -> sTypeDefName:string -> arrsErrcodes:seq<string> -> string;
abstract member EmitTypeAssignment_composite : sVarName:string -> sPtrPrefix:string -> sPtrSuffix:string -> sFuncName:string -> sTypeDefName:string -> sContent:string -> arrsAlphaFuncs:seq<string> -> arrsLocalVars:seq<string> -> bUnreferenced:bool -> string;
abstract member GetEnumIndexByName : sEnumValuesArray:string -> sEnumValuesArrayCount:string -> sExp:string -> bBinarySearch:bool -> string;
abstract member ExpEqual : sExp1:string -> sExp2:string -> string;
abstract member ExpStringEqual : sExp1:string -> sExp2:string -> string;
abstract member ExpGt : sExp1:string -> sExp2:string -> string;
Expand Down Expand Up @@ -324,6 +327,7 @@ Generated by the C stg macros with the following command
abstract member Time : p:string -> sTimeSubType:string -> sErrCode:string -> codec:Codec -> string;
abstract member Enumerated_item : p:string -> sName:string -> nIndex:BigInteger -> nLastItemIndex:BigInteger -> codec:Codec -> string;
abstract member Enumerated : p:string -> td:FE_EnumeratedTypeDefinition -> arrsItem:seq<string> -> nMin:BigInteger -> nMax:BigInteger -> nBits:BigInteger -> sErrCode:string -> nLastItemIndex:BigInteger -> sFirstItemName:string -> codec:Codec -> string;
abstract member Enumerated_no_switch : p:string -> td:FE_EnumeratedTypeDefinition -> sErrCode:string -> sEnumIndex:string -> nLastItemIndex:BigInteger -> sFirstItemName:string -> codec:Codec -> string;
abstract member choice_child : p:string -> sAcc:string -> sChildID:string -> nChildIndex:BigInteger -> nIndexSizeInBits:BigInteger -> nLastItemIndex:BigInteger -> sChildContent:string -> sChildName:string -> sChildTypeDef:string -> sChoiceTypeName:string -> sChildInitExpr:string -> bIsSequence:bool -> bIsEnum:bool -> codec:Codec -> string;
abstract member choice : p:string -> sAcc:string -> arrsChildren:seq<string> -> nLastItemIndex:BigInteger -> sChoiceIndexName:string -> sErrCode:string -> td:FE_ChoiceTypeDefinition -> nIndexSizeInBits:BigInteger -> bIntroSnap:bool -> codec:Codec -> string;
abstract member sequence_presence_bit : p:string -> sAcc:string -> sChName:string -> soExistVar:string option -> sErrCode:string -> codec:Codec -> string;
Expand Down Expand Up @@ -402,6 +406,7 @@ Generated by the C stg macros with the following command
abstract member Enumerated_item : p:string -> sName:string -> sEnumHolder:string -> nItemIdx:BigInteger -> sItemVal:string -> sIntVal:string -> codec:Codec -> string;
abstract member EnumeratedEncIdx : p:string -> td:FE_EnumeratedTypeDefinition -> arrsItem:seq<string> -> sActualCodecFunc:string -> sIntVal:string -> codec:Codec -> string;
abstract member EnumeratedEncValues : p:string -> td:FE_EnumeratedTypeDefinition -> arrsItem:seq<string> -> sActualCodecFunc:string -> sErrCode:string -> sFirstItemName:string -> sIntVal:string -> codec:Codec -> string;
abstract member EnumeratedEncValues_no_switch : p:string -> td:FE_EnumeratedTypeDefinition -> sActualCodecFunc:string -> sErrCode:string -> sFirstItemName:string -> sIntVal:string -> sEnumIndex:string -> nLastItemIndex:BigInteger -> bEncodeValues:bool -> codec:Codec -> string;
abstract member Acn_String_Ascii_FixSize : p:string -> sErrCode:string -> nAsn1Max:BigInteger -> codec:Codec -> string;
abstract member Acn_String_Ascii_Null_Terminated : p:string -> sErrCode:string -> nAsn1Max:BigInteger -> arruNullBytes:seq<byte> -> codec:Codec -> string;
abstract member Acn_String_Ascii_External_Field_Determinant : p:string -> sErrCode:string -> nAsn1Max:BigInteger -> sExtFld:string -> codec:Codec -> string;
Expand Down
7 changes: 7 additions & 0 deletions CommonTypes/CommonTypes.fs
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,10 @@ type FE_EnumeratedTypeDefinition = {
programUnit : string //the program unit where this type is defined
typeName : string //e.g. MyInt, Asn1SccInt, Asn1SccUInt
index_range : string
values_array : string //The name of the array that holds the possible values of the enumeration.
values_array_count : string //The name of the variable that holds the number of elements in the enumeration.
encoded_values_array : string //The name of the array that holds the encoded values of the enumeration.
encoded_values_array_count : string //The name of the variable that holds the number of encoded elements in the enumeration.
kind : FE_NonPrimitiveTypeDefinitionKind<FE_EnumeratedTypeDefinition>
}
with
Expand Down Expand Up @@ -885,6 +889,7 @@ type CommandLineSettings = {
handleEmptySequences : bool
blm : (ProgrammingLanguage*ILangBasic) list
userRtlFunctionsToGenerate : string list
enum_Items_To_Enable_Efficient_Enumerations : uint
}
with
member this.SIntMax =
Expand Down Expand Up @@ -918,6 +923,8 @@ with
this.encodings |> Seq.contains (UPER)
member this.getBasicLang l =
this.blm |> List.find(fun (l1,_) -> l1 = l) |> snd
member this.isEnumEfficientEnabled (nItems:int) =
(uint) nItems >= this.enum_Items_To_Enable_Efficient_Enumerations

let CharCR = Convert.ToChar(13)
let CharLF = Convert.ToChar(10)
Expand Down
17 changes: 8 additions & 9 deletions FrontEndAst/AcnCreateFromAntlr.fs
Original file line number Diff line number Diff line change
Expand Up @@ -650,15 +650,14 @@ let private mergeEnumerated (asn1: Asn1Ast.AstRoot) (items: Asn1Ast.NamedItem li

let alignment = tryGetProp props (fun x -> match x with ALIGNTONEXT e -> Some e | _ -> None)
let acnEncodingClass, acnMinSizeInBits, acnMaxSizeInBits= AcnEncodingClasses.GetEnumeratedEncodingClass asn1.args.integerSizeInBytes items alignment loc acnProperties uperSizeInBits uperSizeInBits encodeValues
match cons with
| [] -> ()
| _ ->
match items |> List.filter (Asn1Fold.isValidValueGeneric cons (fun a b -> a = b.Name.Value)) with
| [] ->
raise(SemanticError(loc, (sprintf "The constraints defined for this type do not allow any value" )))
| _ -> ()

{Enumerated.acnProperties = acnProperties; items=items; cons = cons; withcons = withcons;uperMaxSizeInBits = uperSizeInBits;

let validItems = items |> List.filter (Asn1Fold.isValidValueGeneric cons (fun a b -> a = b.Name.Value)) |> List.sortBy(fun x -> x.definitionValue)

match validItems with
| [] -> raise(SemanticError(loc, (sprintf "The constraints defined for this type do not allow any value" )))
| _ -> ()

{Enumerated.acnProperties = acnProperties; items=items; validItems=validItems; cons = cons; withcons = withcons;uperMaxSizeInBits = uperSizeInBits;
uperMinSizeInBits=uperSizeInBits;encodeValues=encodeValues; acnEncodingClass = acnEncodingClass; acnMinSizeInBits=acnMinSizeInBits;
acnMaxSizeInBits = acnMaxSizeInBits;userDefinedValues=userDefinedValues; typeDef=typeDef}, us1

Expand Down
Loading

0 comments on commit e1f6ca1

Please sign in to comment.