diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index 6b0c50a206d..51174f89320 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -133,6 +133,7 @@ ### Improved * Nullness warning FS3261 on dotted method or property access (e.g. `x.Member`) now underlines the receiver expression and includes the member name and (when known) the binding name in the message. ([Issue #19658](https://github.com/dotnet/fsharp/issues/19658), [PR #19814](https://github.com/dotnet/fsharp/pull/19814)) +* Direct delegate construction ([PR ##19993](https://github.com/dotnet/fsharp/pull/19993)) ### Changed diff --git a/docs/release-notes/.Language/preview.md b/docs/release-notes/.Language/preview.md index 8172d510f76..85ffa6886c4 100644 --- a/docs/release-notes/.Language/preview.md +++ b/docs/release-notes/.Language/preview.md @@ -8,4 +8,6 @@ ### Fixed -### Changed \ No newline at end of file +### Changed + +* Direct delegate construction ([PR ##19993](https://github.com/dotnet/fsharp/pull/19993)) \ No newline at end of file diff --git a/src/Compiler/CodeGen/IlxGen.fs b/src/Compiler/CodeGen/IlxGen.fs index 2fda64ce02a..b6f488153b8 100644 --- a/src/Compiler/CodeGen/IlxGen.fs +++ b/src/Compiler/CodeGen/IlxGen.fs @@ -25,6 +25,7 @@ open FSharp.Compiler.AbstractIL.ILX open FSharp.Compiler.AbstractIL.ILX.Types open FSharp.Compiler.AttributeChecking open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.DelegateForwarding open FSharp.Compiler.DiagnosticsLogger open FSharp.Compiler.Features open FSharp.Compiler.Infos @@ -7558,136 +7559,303 @@ and GenDelegateExpr cenv cgbuf eenvouter expr (TObjExprMethod(slotsig, _attribs, with _ -> false - // Work out the free type variables for the morphing thunk - let takenNames = List.map nameOfVal tmvs + let invokeParamInfos = + List.replicate (List.concat slotsig.FormalParams).Length ValReprInfo.unnamedTopArg1 - let cloFreeTyvars, cloWitnessInfos, cloFreeVars, ilDelegeeTypeRef, ilCloAllFreeVars, eenvinner = - GetIlxClosureFreeVars cenv m [] ILBoxity.AsObject eenvouter takenNames expr + let numDelegeeParams = invokeParamInfos.Length - let ilDelegeeGenericParams = GenGenericParams cenv eenvinner cloFreeTyvars - let ilDelegeeGenericActualsInner = mkILFormalGenericArgs 0 ilDelegeeGenericParams + let etaUnitDelegate = + match tmvs, invokeParamInfos with + | [ _ ], [] -> true + | _ -> false - // When creating a delegate that does not capture any variables, we can instead create a static closure and directly reference the method. - let useStaticClosure = cloFreeVars.IsEmpty + let tmvs, body = BindUnitVars g (tmvs, invokeParamInfos, body) - // Create a new closure class with a single "delegee" method that implements the delegate. - let delegeeMethName = "Invoke" - let ilDelegeeTyInner = mkILBoxedTy ilDelegeeTypeRef ilDelegeeGenericActualsInner + // Point the delegate directly at a recognized transparent-forwarding target instead of generating an + // intermediate closure; anything unmatched falls back to the closure path below. + let directDelegateTarget = + if not (g.langVersion.SupportsFeature LanguageFeature.DirectDelegateConstruction) then + None + elif + not cenv.options.localOptimizationsEnabled + && (etaUnitDelegate || tmvs |> List.exists (fun v -> not v.IsCompilerGenerated)) + then + // Keep eta-expanded delegates as closures in unoptimized builds so the user's lambda parameter + // names survive for debugging; non-eta parameters are synthesized, so nothing is lost there. + None + else + match classifyForwardingTarget (Optimizer.ExprHasEffect Optimizer.EffectContext.Emit) g tmvs body with + | DirectDelegateForwardingTargetCandidate.FSharpVal(vref, valUseFlags, tyargs, leadingArgs) -> + match StorageForValRef m vref eenvouter with + | Method(valReprInfo, vrefM, mspec, _, _, ctps, _, _, _, _, _, _) -> + let _, witnessInfos, _, _, _ = + GetValReprTypeInCompiledForm g valReprInfo ctps.Length vrefM.Type m - let envForDelegeeUnderTypars = AddTyparsToEnv methTyparsOfOverridingMethod eenvinner + let hasWitnesses = ComputeGenerateWitnesses g eenvouter && not witnessInfos.IsEmpty - let numthis = if useStaticClosure then 0 else 1 + match + fsharpValDirectlyBindable + (Optimizer.ExprHasEffect Optimizer.EffectContext.Emit) + g + tmvs + leadingArgs + vrefM + valUseFlags + hasWitnesses + with + | ValueSome(virtualCall, takesInstanceArg) -> + let ilTyArgs = GenTypeArgs cenv m eenvouter.tyenv tyargs - let tmvs, body = - BindUnitVars g (tmvs, List.replicate (List.concat slotsig.FormalParams).Length ValReprInfo.unnamedTopArg1, body) + let numEnclILTypeArgs = + if vrefM.MemberInfo.IsSome && not vrefM.IsExtensionMember then + List.length (vrefM.MemberApparentEntity.Typars |> DropErasedTypars) + else + 0 - // The slot sig contains a formal instantiation. When creating delegates we're only - // interested in the actual instantiation since we don't have to emit a method impl. - let ilDelegeeParams, ilDelegeeRet = - GenActualSlotsig m cenv envForDelegeeUnderTypars slotsig methTyparsOfOverridingMethod tmvs + if ilTyArgs.Length < numEnclILTypeArgs then + None + else + let ilEnclArgTys, ilMethArgTys = List.splitAt numEnclILTypeArgs ilTyArgs - let envForDelegeeMeth = - AddStorageForLocalVals g (List.mapi (fun i v -> (v, Arg(i + numthis))) tmvs) envForDelegeeUnderTypars + let targetMspec = + mkILMethSpec (mspec.MethodRef, mspec.DeclaringType.Boxity, ilEnclArgTys, ilMethArgTys) - let ilMethodBody = - CodeGenMethodForExpr - cenv - cgbuf.mgbuf - ([], - delegeeMethName, - envForDelegeeMeth, - 1, - None, - body, - (if slotSigHasVoidReturnTy slotsig then - discardAndReturnVoid - else - Return)) + let numBoundLeadingFormals = if takesInstanceArg then 0 else leadingArgs.Length - let delegeeInvokeMeth = - (if useStaticClosure then - mkILNonGenericStaticMethod - else - mkILNonGenericInstanceMethod) ( - delegeeMethName, - ILMemberAccess.Assembly, - ilDelegeeParams, - ilDelegeeRet, - MethodBody.IL(InterruptibleLazy.FromValue ilMethodBody) - ) + if takesInstanceArg <> targetMspec.MethodRef.CallingConv.IsInstance then + None + else + let ilDelegeeRetTy = + let envUnderTypars = AddTyparsToEnv methTyparsOfOverridingMethod eenvouter - let delegeeCtorMeth = - mkILSimpleStorageCtor (Some g.ilg.typ_Object.TypeSpec, ilDelegeeTyInner, [], [], ILMemberAccess.Assembly, None, eenvouter.imports) + let _, ilDelegeeRet = + GenActualSlotsig m cenv envUnderTypars slotsig methTyparsOfOverridingMethod tmvs - let ilCtorBody = delegeeCtorMeth.MethodBody + ilDelegeeRet.Type - let ilCloLambdas = Lambdas_return ilCtxtDelTy + if + signatureMatches + numBoundLeadingFormals + numDelegeeParams + ilDelegeeRetTy + ilEnclArgTys + ilMethArgTys + targetMspec + then + Some(targetMspec, receiverInfo leadingArgs virtualCall) + else + None + | ValueNone -> None + | _ -> None - let cloTypeDefs = - (if useStaticClosure then - GenStaticDelegateClosureTypeDefs - else - GenClosureTypeDefs) - cenv - (ilDelegeeTypeRef, - ilDelegeeGenericParams, - [], - ilCloAllFreeVars, - ilCloLambdas, - ilCtorBody, - [ delegeeInvokeMeth ], - [], - g.ilg.typ_Object, - [], - None) + | DirectDelegateForwardingTargetCandidate.ILMethod(isVirtual, + isStruct, + isCtor, + valUseFlag, + ilMethRef, + enclTypeInst, + methInst, + leadingArgs) -> + if + ilMethodDirectlyBindable + (Optimizer.ExprHasEffect Optimizer.EffectContext.Emit) + g + tmvs + leadingArgs + ilMethRef + valUseFlag + isCtor + then + let ilEnclArgTys = GenTypeArgs cenv m eenvouter.tyenv enclTypeInst + let ilMethArgTys = GenTypeArgs cenv m eenvouter.tyenv methInst + let boxity = if isStruct then AsValue else AsObject + let targetMspec = mkILMethSpec (ilMethRef, boxity, ilEnclArgTys, ilMethArgTys) + + let numBoundLeadingFormals = + if ilMethRef.CallingConv.IsInstance then + 0 + else + leadingArgs.Length - for cloTypeDef in cloTypeDefs do - cgbuf.mgbuf.AddTypeDef(ilDelegeeTypeRef, cloTypeDef, false, false, None, m) + // Imported metadata carries different assembly scope refs than the compiler-generated + // delegee types, so structural IL type comparison reports false negatives even for + // primitives; the arity check is the sound residual guard (the call is already typed). + if targetMspec.FormalArgTypes.Length - numBoundLeadingFormals = numDelegeeParams then + Some(targetMspec, receiverInfo leadingArgs isVirtual) + else + None + else + None - CountClosure() + | DirectDelegateForwardingTargetCandidate.Other -> None - // Push the constructor for the delegee - let ctxtGenericArgsForDelegee = GenGenericArgs m eenvouter.tyenv cloFreeTyvars + match directDelegateTarget with + | Some(targetMspec, receiverInfo) -> + match receiverInfo with + | None -> + // Static target: null Target. + GenUnit cenv eenvouter m cgbuf + CG.EmitInstr cgbuf (pop 0) (Push [ g.ilg.typ_IntPtr ]) (I_ldftn targetMspec) + | Some(receiverExpr, isVirtual) -> + // Instance target: the receiver becomes the Target. + GenExpr cenv cgbuf eenvouter receiverExpr Continue + + if targetMspec.DeclaringType.Boxity.IsAsValue then + // Box a copy as the 'object' Target; invocation reaches 'this' through the runtime's + // unboxing stub, matching the closure's by-value capture. (Struct instance methods are + // non-virtual, so the ldftn path below is taken.) + CG.EmitInstr cgbuf (pop 1) (Push [ g.ilg.typ_Object ]) (I_box targetMspec.DeclaringType) + + if isVirtual then + // dup the receiver so ldvirtftn can bind its runtime type's override. + CG.EmitInstr cgbuf (pop 0) (Push [ targetMspec.DeclaringType ]) AI_dup + CG.EmitInstr cgbuf (pop 1) (Push [ g.ilg.typ_IntPtr ]) (I_ldvirtftn targetMspec) + else + CG.EmitInstr cgbuf (pop 0) (Push [ g.ilg.typ_IntPtr ]) (I_ldftn targetMspec) - if useStaticClosure then - GenUnit cenv eenvouter m cgbuf - else - let ilxCloSpec = - IlxClosureSpec.Create(IlxClosureRef(ilDelegeeTypeRef, ilCloLambdas, ilCloAllFreeVars), ctxtGenericArgsForDelegee, false) + // newobj Delegate::.ctor(object, native int) + let ilDelegeeCtorMethOuter = + mkCtorMethSpecForDelegate g.ilg (ilCtxtDelTy, useUIntPtrForDelegateCtor) - GenWitnessArgsFromWitnessInfos cenv cgbuf eenvouter m cloWitnessInfos + CG.EmitInstr cgbuf (pop 2) (Push [ ilCtxtDelTy ]) (I_newobj(ilDelegeeCtorMethOuter, None)) + GenSequel cenv eenvouter.cloc cgbuf sequel - for fv in cloFreeVars do - GenGetFreeVarForClosure cenv cgbuf eenvouter m fv + | None -> + let takenNames = List.map nameOfVal tmvs - CG.EmitInstr - cgbuf - (pop ilCloAllFreeVars.Length) - (Push [ EraseClosures.mkTyOfLambdas cenv.ilxPubCloEnv ilCloLambdas ]) - (I_newobj(ilxCloSpec.Constructor, None)) + // Work out the free type variables for the morphing thunk + let cloFreeTyvars, cloWitnessInfos, cloFreeVars, ilDelegeeTypeRef, ilCloAllFreeVars, eenvinner = + GetIlxClosureFreeVars cenv m [] ILBoxity.AsObject eenvouter takenNames expr - // Push the function pointer to the Invoke method of the delegee - let ilDelegeeTyOuter = mkILBoxedTy ilDelegeeTypeRef ctxtGenericArgsForDelegee + let ilDelegeeGenericParams = GenGenericParams cenv eenvinner cloFreeTyvars + let ilDelegeeGenericActualsInner = mkILFormalGenericArgs 0 ilDelegeeGenericParams - let ilDelegeeInvokeMethOuter = - (if useStaticClosure then - mkILNonGenericStaticMethSpecInTy - else - mkILNonGenericInstanceMethSpecInTy) ( - ilDelegeeTyOuter, - "Invoke", - typesOfILParams ilDelegeeParams, - ilDelegeeRet.Type - ) + // When creating a delegate that does not capture any variables, we can instead create a static closure and directly reference the method. + let useStaticClosure = cloFreeVars.IsEmpty - CG.EmitInstr cgbuf (pop 0) (Push [ g.ilg.typ_IntPtr ]) (I_ldftn ilDelegeeInvokeMethOuter) + // Create a new closure class with a single "delegee" method that implements the delegate. + let delegeeMethName = "Invoke" + let ilDelegeeTyInner = mkILBoxedTy ilDelegeeTypeRef ilDelegeeGenericActualsInner - // Instantiate the delegate - let ilDelegeeCtorMethOuter = - mkCtorMethSpecForDelegate g.ilg (ilCtxtDelTy, useUIntPtrForDelegateCtor) + let envForDelegeeUnderTypars = AddTyparsToEnv methTyparsOfOverridingMethod eenvinner - CG.EmitInstr cgbuf (pop 2) (Push [ ilCtxtDelTy ]) (I_newobj(ilDelegeeCtorMethOuter, None)) - GenSequel cenv eenvouter.cloc cgbuf sequel + let numthis = if useStaticClosure then 0 else 1 + + // The slot sig contains a formal instantiation. When creating delegates we're only + // interested in the actual instantiation since we don't have to emit a method impl. + let ilDelegeeParams, ilDelegeeRet = + GenActualSlotsig m cenv envForDelegeeUnderTypars slotsig methTyparsOfOverridingMethod tmvs + + let envForDelegeeMeth = + AddStorageForLocalVals g (List.mapi (fun i v -> (v, Arg(i + numthis))) tmvs) envForDelegeeUnderTypars + + let ilMethodBody = + CodeGenMethodForExpr + cenv + cgbuf.mgbuf + ([], + delegeeMethName, + envForDelegeeMeth, + 1, + None, + body, + (if slotSigHasVoidReturnTy slotsig then + discardAndReturnVoid + else + Return)) + + let delegeeInvokeMeth = + (if useStaticClosure then + mkILNonGenericStaticMethod + else + mkILNonGenericInstanceMethod) ( + delegeeMethName, + ILMemberAccess.Assembly, + ilDelegeeParams, + ilDelegeeRet, + MethodBody.IL(InterruptibleLazy.FromValue ilMethodBody) + ) + + let delegeeCtorMeth = + mkILSimpleStorageCtor ( + Some g.ilg.typ_Object.TypeSpec, + ilDelegeeTyInner, + [], + [], + ILMemberAccess.Assembly, + None, + eenvouter.imports + ) + + let ilCtorBody = delegeeCtorMeth.MethodBody + + let ilCloLambdas = Lambdas_return ilCtxtDelTy + + let cloTypeDefs = + (if useStaticClosure then + GenStaticDelegateClosureTypeDefs + else + GenClosureTypeDefs) + cenv + (ilDelegeeTypeRef, + ilDelegeeGenericParams, + [], + ilCloAllFreeVars, + ilCloLambdas, + ilCtorBody, + [ delegeeInvokeMeth ], + [], + g.ilg.typ_Object, + [], + None) + + for cloTypeDef in cloTypeDefs do + cgbuf.mgbuf.AddTypeDef(ilDelegeeTypeRef, cloTypeDef, false, false, None, m) + + CountClosure() + + // Push the constructor for the delegee + let ctxtGenericArgsForDelegee = GenGenericArgs m eenvouter.tyenv cloFreeTyvars + + if useStaticClosure then + GenUnit cenv eenvouter m cgbuf + else + let ilxCloSpec = + IlxClosureSpec.Create(IlxClosureRef(ilDelegeeTypeRef, ilCloLambdas, ilCloAllFreeVars), ctxtGenericArgsForDelegee, false) + + GenWitnessArgsFromWitnessInfos cenv cgbuf eenvouter m cloWitnessInfos + + for fv in cloFreeVars do + GenGetFreeVarForClosure cenv cgbuf eenvouter m fv + + CG.EmitInstr + cgbuf + (pop ilCloAllFreeVars.Length) + (Push [ EraseClosures.mkTyOfLambdas cenv.ilxPubCloEnv ilCloLambdas ]) + (I_newobj(ilxCloSpec.Constructor, None)) + + // Push the function pointer to the Invoke method of the delegee + let ilDelegeeTyOuter = mkILBoxedTy ilDelegeeTypeRef ctxtGenericArgsForDelegee + + let ilDelegeeInvokeMethOuter = + (if useStaticClosure then + mkILNonGenericStaticMethSpecInTy + else + mkILNonGenericInstanceMethSpecInTy) ( + ilDelegeeTyOuter, + "Invoke", + typesOfILParams ilDelegeeParams, + ilDelegeeRet.Type + ) + + CG.EmitInstr cgbuf (pop 0) (Push [ g.ilg.typ_IntPtr ]) (I_ldftn ilDelegeeInvokeMethOuter) + + // Instantiate the delegate + let ilDelegeeCtorMethOuter = + mkCtorMethSpecForDelegate g.ilg (ilCtxtDelTy, useUIntPtrForDelegateCtor) + + CG.EmitInstr cgbuf (pop 2) (Push [ ilCtxtDelTy ]) (I_newobj(ilDelegeeCtorMethOuter, None)) + GenSequel cenv eenvouter.cloc cgbuf sequel /// Used to search FSharp.Core implementations of "^T : ^T" and decide whether the conditional activates and ExprIsTraitCall expr = diff --git a/src/Compiler/FSComp.txt b/src/Compiler/FSComp.txt index c6cbc797da5..173e2bed8a8 100644 --- a/src/Compiler/FSComp.txt +++ b/src/Compiler/FSComp.txt @@ -1824,5 +1824,6 @@ featurePreprocessorElif,"#elif preprocessor directive" 3890,tcRecursiveInlineNotAllowed,"The value or member '%s' has been marked 'inline' but is part of a recursive binding group. F# does not support recursive 'inline' values. Either remove the 'inline' modifier or refactor the recursion." featureExceptionFieldSerializationSupport,"emit GetObjectData and field-restoring deserialization constructor for exception types" featureErrorOnMissingSignatureAttribute,"error (rather than warning) when an enforced compiler-semantic attribute is present in the .fs but missing from the .fsi" +featureDirectDelegateConstruction,"construct delegates that point directly at the target method, avoiding an intermediate closure" featureAccessProtectedBaseFieldFromClosure,"Access a protected base-class field from a closure inside a member" featureImprovedImpliedArgumentNamesPartTwo,"Improved implied argument names with partial application" diff --git a/src/Compiler/FSharp.Compiler.Service.fsproj b/src/Compiler/FSharp.Compiler.Service.fsproj index 5510af6b3f6..c29afb5c369 100644 --- a/src/Compiler/FSharp.Compiler.Service.fsproj +++ b/src/Compiler/FSharp.Compiler.Service.fsproj @@ -418,6 +418,7 @@ + diff --git a/src/Compiler/Facilities/LanguageFeatures.fs b/src/Compiler/Facilities/LanguageFeatures.fs index 9ecc56472c6..199b759e0ff 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fs +++ b/src/Compiler/Facilities/LanguageFeatures.fs @@ -110,6 +110,7 @@ type LanguageFeature = | PreprocessorElif | ExceptionFieldSerializationSupport | ErrorOnMissingSignatureAttribute + | DirectDelegateConstruction | AccessProtectedBaseFieldFromClosure | ImprovedImpliedArgumentNamesPartTwo @@ -266,6 +267,7 @@ type LanguageVersion(versionText, ?disabledFeaturesArray: LanguageFeature array) LanguageFeature.MethodOverloadsCache, previewVersion // Performance optimization for overload resolution LanguageFeature.ImplicitDIMCoverage, languageVersion110 LanguageFeature.ErrorOnMissingSignatureAttribute, previewVersion // Opt-in: turn FS3888 from warning into error + LanguageFeature.DirectDelegateConstruction, previewVersion LanguageFeature.AccessProtectedBaseFieldFromClosure, previewVersion // #5302: read a protected base field from a closure ] @@ -463,6 +465,7 @@ type LanguageVersion(versionText, ?disabledFeaturesArray: LanguageFeature array) | LanguageFeature.PreprocessorElif -> FSComp.SR.featurePreprocessorElif () | LanguageFeature.ExceptionFieldSerializationSupport -> FSComp.SR.featureExceptionFieldSerializationSupport () | LanguageFeature.ErrorOnMissingSignatureAttribute -> FSComp.SR.featureErrorOnMissingSignatureAttribute () + | LanguageFeature.DirectDelegateConstruction -> FSComp.SR.featureDirectDelegateConstruction () | LanguageFeature.AccessProtectedBaseFieldFromClosure -> FSComp.SR.featureAccessProtectedBaseFieldFromClosure () | LanguageFeature.ImprovedImpliedArgumentNamesPartTwo -> FSComp.SR.featureImprovedImpliedArgumentNamesPartTwo () diff --git a/src/Compiler/Facilities/LanguageFeatures.fsi b/src/Compiler/Facilities/LanguageFeatures.fsi index 4aa85a42224..76ce2d75236 100644 --- a/src/Compiler/Facilities/LanguageFeatures.fsi +++ b/src/Compiler/Facilities/LanguageFeatures.fsi @@ -101,6 +101,7 @@ type LanguageFeature = | PreprocessorElif | ExceptionFieldSerializationSupport | ErrorOnMissingSignatureAttribute + | DirectDelegateConstruction | AccessProtectedBaseFieldFromClosure | ImprovedImpliedArgumentNamesPartTwo diff --git a/src/Compiler/Optimize/DelegateForwarding.fs b/src/Compiler/Optimize/DelegateForwarding.fs new file mode 100644 index 00000000000..c720f9bf1b5 --- /dev/null +++ b/src/Compiler/Optimize/DelegateForwarding.fs @@ -0,0 +1,282 @@ +// Copyright (c) Microsoft Corporation. All Rights Reserved. See License.txt in the project root for license information. + +/// Recognition of delegate constructions whose Invoke body is a transparent forwarding call to a known +/// method, shared by the optimizer (which preserves the call from inlining) and the ILX generator (which +/// points the delegate directly at the target). The 'exprHasEffect' parameter is Optimizer.ExprHasEffect; +/// it is passed in because this file compiles before the optimizer. +module internal FSharp.Compiler.DelegateForwarding + +open Internal.Utilities.Collections + +open FSharp.Compiler.AbstractIL.IL +open FSharp.Compiler.TcGlobals +open FSharp.Compiler.TypedTree +open FSharp.Compiler.TypedTreeBasics +open FSharp.Compiler.TypedTreeOps + +/// A delegate target that can potentially be forwarded to directly, without an intermediate closure +[] +type DirectDelegateForwardingTargetCandidate = + /// A known F# value: a module-level function or a member + | FSharpVal of vref: ValRef * valUseFlags: ValUseFlag * tyargs: TypeInst * leadingArgs: Expr list + /// A direct IL method call (e.g. a BCL method) + | ILMethod of + isVirtual: bool * + isStruct: bool * + isCtor: bool * + valUseFlags: ValUseFlag * + ilMethRef: ILMethodRef * + enclTypeInst: TypeInst * + methInst: TypeInst * + leadingArgs: Expr list + | Other + +let private isUnitValue e = + match stripDebugPoints e with + | Expr.Const(Const.Unit, _, _) -> true + | _ -> false + +// Mirror the code generator's arity-based de-tupling (a tupled argument group is one tuple node in the +// call but separate IL parameters in the compiled target) so the match sees the flattened argument list. +// The group count must equal the target's arity exactly: fewer is a partial application, more an +// over-application whose trailing arguments are consumed by the target's *result*, and a target without +// arity information has no compiled method to point at. +let private tryFlattenTupledArgs (vref: ValRef) (args: Expr list) = + let arities = (arityOfVal vref.Deref).AritiesOfArgs + + if arities.Length <> args.Length then + None + else + (arities, args) + ||> List.map2 (fun arity arg -> + match stripDebugPoints arg with + | Expr.Op(TOp.Tuple _, _, elems, _) when arity >= 2 && elems.Length = arity -> elems + | _ -> [ arg ]) + |> List.concat + |> Some + +let rec private resolveAliases (aliases: ValMap) e = + let e = stripDebugPoints e + + match e with + | Expr.Val(vref, _, _) -> + match aliases.TryFind vref.Deref with + | Some e2 -> resolveAliases aliases e2 + | None -> e + | _ -> e + +// Trailing arguments must be the delegate's Invoke parameters, verbatim and in order; the leading rest +// (e.g. an instance receiver) is resolved and returned for the caller to check and emit. +let private matchForwarding g (aliases: ValMap) (invokeParams: Val list) (args: Expr list) = + let args = args |> List.map (resolveAliases aliases) + + // Drop the elided unit argument when the Invoke takes no parameters. + let args = + match List.tryLast args with + | Some last when List.isEmpty invokeParams && isUnitValue last -> List.truncate (args.Length - 1) args + | _ -> args + + let numLeading = args.Length - invokeParams.Length + + if numLeading >= 0 then + let leadingArgs, forwardedArgs = List.splitAt numLeading args + + if + List.forall2 + (fun (a: Expr) (tv: Val) -> + match a with + | Expr.Val(avref, _, _) -> valRefEq g avref (mkLocalValRef tv) + | _ -> false) + forwardedArgs + invokeParams + then + // A struct receiver arrives by address; recover the value so the emit can box it as the + // Target (invocation reaches 'this' through the runtime's unboxing stub). + let leadingArgs = + leadingArgs + |> List.map (fun a -> + match a with + | Expr.Op(TOp.LValueOp(LAddrOf _, vref), _, _, m) -> resolveAliases aliases (exprForValRef m vref) + | _ -> a) + + Some leadingArgs + else + None + else + None + +// Peel the wrappers the elaborator and BuildNewDelegateExpr leave around the forwarding call: effect-free +// let-bindings, applications of let-wrapped or immediate lambdas (method-group coercions, the shells of +// curried member calls), and curried application nesting. The optimizer reduces these only while already +// making inlining decisions - too late for a recognizer that must precede them - so peel by aliasing: +// each bound value maps to the expression flowing into it, resolved when the arguments are matched. +// Anything else is left in place and fails the match, conservatively keeping the closure. +let rec private stripToForwardingCall exprHasEffect g (aliases: ValMap) expr = + match stripDebugPoints expr with + | Expr.Let(TBind(v, rhs, _), inner, _, _) when not (exprHasEffect g rhs) -> + stripToForwardingCall exprHasEffect g (aliases.Add v rhs) inner + | Expr.App(f, fty, tyargs, args, m) as app -> + match stripDebugPoints f with + | Expr.Let(TBind(v, rhs, _), f2, _, _) when not (exprHasEffect g rhs) -> + stripToForwardingCall exprHasEffect g (aliases.Add v rhs) (Expr.App(f2, fty, tyargs, args, m)) + | Expr.Lambda(_, None, None, [ v ], body, _, _) when List.isEmpty tyargs -> + match args with + | a :: rest when not (exprHasEffect g a) -> + let aliases = aliases.Add v a + + match rest with + | [] -> stripToForwardingCall exprHasEffect g aliases body + | _ -> stripToForwardingCall exprHasEffect g aliases (Expr.App(body, tyOfExpr g body, [], rest, m)) + | _ -> app, aliases + | Expr.App(f2, f2ty, tyargs2, args2, _) when List.isEmpty tyargs -> + stripToForwardingCall exprHasEffect g aliases (Expr.App(f2, f2ty, tyargs2, args2 @ args, m)) + | _ -> app, aliases + | e -> e, aliases + +let classifyForwardingTarget exprHasEffect g (invokeParams: Val list) expr = + let call, aliases = stripToForwardingCall exprHasEffect g ValMap.Empty expr + + match call with + | Expr.App(f, _, tyargs, args, _) -> + match stripDebugPoints f with + | Expr.Val(vref, valUseFlags, _) -> + match + tryFlattenTupledArgs vref args + |> Option.bind (matchForwarding g aliases invokeParams) + with + | Some leadingArgs -> DirectDelegateForwardingTargetCandidate.FSharpVal(vref, valUseFlags, tyargs, leadingArgs) + | None -> DirectDelegateForwardingTargetCandidate.Other + | _ -> DirectDelegateForwardingTargetCandidate.Other + | Expr.Op(TOp.ILCall(isVirtual, _, isStruct, isCtor, valUseFlag, _, _, ilMethRef, enclTypeInst, methInst, _), _, args, _) -> + match matchForwarding g aliases invokeParams args with + | Some leadingArgs -> + DirectDelegateForwardingTargetCandidate.ILMethod( + isVirtual, + isStruct, + isCtor, + valUseFlag, + ilMethRef, + enclTypeInst, + methInst, + leadingArgs + ) + | None -> DirectDelegateForwardingTargetCandidate.Other + | _ -> DirectDelegateForwardingTargetCandidate.Other + +/// At most one leading argument can become the delegate's Target: the receiver of an instance target, or +/// the first parameter of a static one via the CLR's "closed over the first argument" delegate form +/// (extension-member receivers, one-argument partial applications). More has no closed form. +let private receiverShapeOk (leadingArgs: Expr list) takesInstanceArg = + if takesInstanceArg then + match leadingArgs with + | [ _ ] -> true + | _ -> false + else + match leadingArgs with + | [] + | [ _ ] -> true + | _ -> false + +/// The closed-delegate thunk passes the Target into a static target's first parameter with no unboxing, +/// so a value-type leading argument has no closed form (unlike an instance receiver's unboxing stub). +let private staticLeadingArgIsRefType g takesInstanceArg (leadingArgs: Expr list) = + match leadingArgs with + | [ recv ] when not takesInstanceArg -> not (isStructTy g (tyOfExpr g recv)) + | _ -> true + +/// Boxing the receiver needs it as a value: '&localVar' is recovered by the recognizer, but any other +/// address form leaves a byref the box cannot consume. +let private receiverNotByref g (leadingArgs: Expr list) = + match leadingArgs with + | [ recv ] -> not (isByrefTy g (tyOfExpr g recv)) + | _ -> true + +/// The receiver is evaluated once at the construction site rather than on every Invoke, which is only +/// unobservable when it is effect-free; and it must not reference the Invoke parameters, which exist +/// only inside the delegee. +let private receiverBindable exprHasEffect g (invokeParams: Val list) (leadingArgs: Expr list) = + match leadingArgs with + | [ recv ] -> + let recvFreeLocals = (freeInExpr CollectLocals recv).FreeLocals + + not (exprHasEffect g recv) + && (not (invokeParams |> List.exists (fun tv -> Zset.contains tv recvFreeLocals))) + | _ -> true + +/// Returns the virtual-call and instance-receiver facts derived from the member call info when the +/// target is directly bindable. Witnesses are passed in: computing them needs the IlxGen environment. +let fsharpValDirectlyBindable + exprHasEffect + g + (invokeParams: Val list) + (leadingArgs: Expr list) + (vrefM: ValRef) + (valUseFlags: ValUseFlag) + hasWitnesses + = + let _, virtualCall, newobj, isSuperInit, isSelfInit, takesInstanceArg, _, _ = + GetMemberCallInfo g (vrefM, valUseFlags) + + if + not hasWitnesses + && not newobj + && not isSuperInit + && not isSelfInit + && not valUseFlags.IsVSlotDirectCall + && receiverShapeOk leadingArgs takesInstanceArg + && receiverBindable exprHasEffect g invokeParams leadingArgs + && staticLeadingArgIsRefType g takesInstanceArg leadingArgs + && receiverNotByref g leadingArgs + then + ValueSome(virtualCall, takesInstanceArg) + else + ValueNone + +let ilMethodDirectlyBindable + exprHasEffect + g + (invokeParams: Val list) + (leadingArgs: Expr list) + (ilMethRef: ILMethodRef) + (valUseFlag: ValUseFlag) + isCtor + = + let takesInstanceArg = ilMethRef.CallingConv.IsInstance + + not isCtor + && not valUseFlag.IsVSlotDirectCall + && not valUseFlag.IsPossibleConstrainedCall + && receiverShapeOk leadingArgs takesInstanceArg + && receiverBindable exprHasEffect g invokeParams leadingArgs + && staticLeadingArgIsRefType g takesInstanceArg leadingArgs + && receiverNotByref g leadingArgs + +/// Residual IL compatibility check; the type checker verified the call and the forwarding match pinned +/// the shape. Parameter types are deliberately not compared - value types are exact by construction and +/// reference types may use the CLR's contravariant delegate relaxation - only their count, minus any +/// leading formals consumed by a bound Target. The return type must match exactly for a non-generic +/// target (the CLR does not relax e.g. 'void' against 'Unit'); a generic target's return is written in +/// type variables, where no exact comparison is meaningful. +let signatureMatches + numBoundLeadingFormals + (numDelegeeParams: int) + (ilDelegeeRetTy: ILType) + (ilEnclArgTys: ILType list) + (ilMethArgTys: ILType list) + (targetMspec: ILMethodSpec) + = + let arityMatches = + targetMspec.FormalArgTypes.Length - numBoundLeadingFormals = numDelegeeParams + + let returnMatches = + if List.isEmpty ilEnclArgTys && List.isEmpty ilMethArgTys then + ilDelegeeRetTy = targetMspec.FormalReturnType + else + true + + arityMatches && returnMatches + +let receiverInfo (leadingArgs: Expr list) virtualCall = + match leadingArgs with + | [ recv ] -> Some(recv, virtualCall) + | _ -> None diff --git a/src/Compiler/Optimize/Optimizer.fs b/src/Compiler/Optimize/Optimizer.fs index f67072c1c78..1e8afe2fafd 100644 --- a/src/Compiler/Optimize/Optimizer.fs +++ b/src/Compiler/Optimize/Optimizer.fs @@ -12,6 +12,7 @@ open FSharp.Compiler open FSharp.Compiler.AbstractIL.IL open FSharp.Compiler.AttributeChecking open FSharp.Compiler.CompilerGlobalState +open FSharp.Compiler.DelegateForwarding open FSharp.Compiler.DiagnosticsLogger open FSharp.Compiler.Text.Range open FSharp.Compiler.Syntax.PrettyNaming @@ -1707,7 +1708,7 @@ and OpHasEffect context g m op tyargs = | TOp.ExnFieldSet _ | TOp.Coerce | TOp.Reraise - | TOp.IntegerForLoop _ + | TOp.IntegerForLoop _ | TOp.While _ | TOp.TryWith _ (* conservative *) | TOp.TryFinally _ (* conservative *) @@ -1722,6 +1723,43 @@ and OpHasEffect context g m op tyargs = let effectContextOf (cenv: cenv) = if cenv.optimizing then EffectContext.Emit else EffectContext.InlineBody +/// Prevent the optimizer from inlining a recognized direct-delegate forwarding target into the delegate +/// body: inlining would dissolve the call before IlxGen can point the delegate at it, making the emitted +/// form depend on the target's size (locally, and through a referenced assembly's optimization data). +/// Mandatory inlining of 'inline' values takes precedence via OptimizeVal. +let AddDirectDelegateTargetToDontInlineSet cenv env (slotsig: SlotSig) tmvs body m = + let g = cenv.g + + if + g.langVersion.SupportsFeature Features.LanguageFeature.DirectDelegateConstruction + && cenv.optimizing + && cenv.settings.InlineLambdas + then + let exprHasEffect = ExprHasEffect (effectContextOf cenv) + + // Normalize the elided unit parameter of a zero-parameter Invoke (e.g. System.Action) exactly as + // IlxGen will before it runs the recognizer + let tmvs, body = + if slotsig.FormalParams |> List.forall List.isEmpty then + BindUnitVars g (tmvs, [], body) + else + tmvs, body + + match classifyForwardingTarget exprHasEffect g tmvs body with + | DirectDelegateForwardingTargetCandidate.FSharpVal(vref, valUseFlags, _, leadingArgs) when + // ValReprInfo.IsSome mirrors IlxGen's Method-storage requirement. Witnesses are not knowable + // here; over-suppressing a witness-requiring target only costs an inline in a closure body. + vref.ValReprInfo.IsSome + && (fsharpValDirectlyBindable exprHasEffect g tmvs leadingArgs vref valUseFlags false) + .IsSome + -> + match (GetInfoForVal cenv env m vref).ValExprInfo with + | StripLambdaValue(lambdaId, _, _, _, _) -> + { env with dontInline = Map.add lambdaId [] env.dontInline } + | _ -> env + | _ -> env + else + env let TryEliminateBinding cenv _env bind e2 _m = let g = cenv.g @@ -2441,11 +2479,16 @@ let rec OptimizeExpr cenv (env: IncrementalOptimizationEnv) expr = MightMakeCriticalTailcall=false Info=UnknownValue } - | Expr.Obj (_, ty, basev, createExpr, overrides, iimpls, m) -> - match expr with - | NewDelegateExpr g (lambdaId, vsl, body, _, remake) -> + | Expr.Obj (_, ty, basev, createExpr, overrides, iimpls, m) -> + match expr with + | NewDelegateExpr g (lambdaId, vsl, body, _, remake) -> + let env = + match overrides with + | [ TObjExprMethod(slotsig, _, _, _, _, mMeth) ] -> + AddDirectDelegateTargetToDontInlineSet cenv env slotsig vsl body mMeth + | _ -> env OptimizeNewDelegateExpr cenv env (lambdaId, vsl, body, remake) - | _ -> + | _ -> OptimizeObjectExpr cenv env (ty, basev, createExpr, overrides, iimpls, m) | Expr.Op (op, tyargs, args, m) -> diff --git a/src/Compiler/xlf/FSComp.txt.cs.xlf b/src/Compiler/xlf/FSComp.txt.cs.xlf index 48fae4742da..478b952edc1 100644 --- a/src/Compiler/xlf/FSComp.txt.cs.xlf +++ b/src/Compiler/xlf/FSComp.txt.cs.xlf @@ -367,6 +367,11 @@ Deprecate places where 'seq' can be omitted + + construct delegates that point directly at the target method, avoiding an intermediate closure + construct delegates that point directly at the target method, avoiding an intermediate closure + + discard pattern in use binding vzor discard ve vazbě použití diff --git a/src/Compiler/xlf/FSComp.txt.de.xlf b/src/Compiler/xlf/FSComp.txt.de.xlf index 256a5b49e0f..4845e1b9591 100644 --- a/src/Compiler/xlf/FSComp.txt.de.xlf +++ b/src/Compiler/xlf/FSComp.txt.de.xlf @@ -367,6 +367,11 @@ Deprecate places where 'seq' can be omitted + + construct delegates that point directly at the target method, avoiding an intermediate closure + construct delegates that point directly at the target method, avoiding an intermediate closure + + discard pattern in use binding Das Verwerfen des verwendeten Musters ist verbindlich. diff --git a/src/Compiler/xlf/FSComp.txt.es.xlf b/src/Compiler/xlf/FSComp.txt.es.xlf index 965b77b54c1..52738ac8dd0 100644 --- a/src/Compiler/xlf/FSComp.txt.es.xlf +++ b/src/Compiler/xlf/FSComp.txt.es.xlf @@ -367,6 +367,11 @@ Deprecate places where 'seq' can be omitted + + construct delegates that point directly at the target method, avoiding an intermediate closure + construct delegates that point directly at the target method, avoiding an intermediate closure + + discard pattern in use binding descartar enlace de patrón en uso diff --git a/src/Compiler/xlf/FSComp.txt.fr.xlf b/src/Compiler/xlf/FSComp.txt.fr.xlf index 36af4f462ea..4a4bb89f563 100644 --- a/src/Compiler/xlf/FSComp.txt.fr.xlf +++ b/src/Compiler/xlf/FSComp.txt.fr.xlf @@ -367,6 +367,11 @@ Deprecate places where 'seq' can be omitted + + construct delegates that point directly at the target method, avoiding an intermediate closure + construct delegates that point directly at the target method, avoiding an intermediate closure + + discard pattern in use binding annuler le modèle dans la liaison d’utilisation diff --git a/src/Compiler/xlf/FSComp.txt.it.xlf b/src/Compiler/xlf/FSComp.txt.it.xlf index cf5834247b2..b5b3316708d 100644 --- a/src/Compiler/xlf/FSComp.txt.it.xlf +++ b/src/Compiler/xlf/FSComp.txt.it.xlf @@ -367,6 +367,11 @@ Deprecate places where 'seq' can be omitted + + construct delegates that point directly at the target method, avoiding an intermediate closure + construct delegates that point directly at the target method, avoiding an intermediate closure + + discard pattern in use binding rimuovi criterio nell'utilizzo dell'associazione diff --git a/src/Compiler/xlf/FSComp.txt.ja.xlf b/src/Compiler/xlf/FSComp.txt.ja.xlf index d684f435a7f..aef60cd08b5 100644 --- a/src/Compiler/xlf/FSComp.txt.ja.xlf +++ b/src/Compiler/xlf/FSComp.txt.ja.xlf @@ -367,6 +367,11 @@ Deprecate places where 'seq' can be omitted + + construct delegates that point directly at the target method, avoiding an intermediate closure + construct delegates that point directly at the target method, avoiding an intermediate closure + + discard pattern in use binding 使用バインドでパターンを破棄する diff --git a/src/Compiler/xlf/FSComp.txt.ko.xlf b/src/Compiler/xlf/FSComp.txt.ko.xlf index ae0bdce0e1f..7ea2563baaf 100644 --- a/src/Compiler/xlf/FSComp.txt.ko.xlf +++ b/src/Compiler/xlf/FSComp.txt.ko.xlf @@ -367,6 +367,11 @@ Deprecate places where 'seq' can be omitted + + construct delegates that point directly at the target method, avoiding an intermediate closure + construct delegates that point directly at the target method, avoiding an intermediate closure + + discard pattern in use binding 사용 중인 패턴 바인딩 무시 diff --git a/src/Compiler/xlf/FSComp.txt.pl.xlf b/src/Compiler/xlf/FSComp.txt.pl.xlf index e7f9fbedc3e..3cc10ec0448 100644 --- a/src/Compiler/xlf/FSComp.txt.pl.xlf +++ b/src/Compiler/xlf/FSComp.txt.pl.xlf @@ -367,6 +367,11 @@ Deprecate places where 'seq' can be omitted + + construct delegates that point directly at the target method, avoiding an intermediate closure + construct delegates that point directly at the target method, avoiding an intermediate closure + + discard pattern in use binding odrzuć wzorzec w powiązaniu użycia diff --git a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf index 2ee0777fb1b..fc43f3f6faf 100644 --- a/src/Compiler/xlf/FSComp.txt.pt-BR.xlf +++ b/src/Compiler/xlf/FSComp.txt.pt-BR.xlf @@ -367,6 +367,11 @@ Deprecate places where 'seq' can be omitted + + construct delegates that point directly at the target method, avoiding an intermediate closure + construct delegates that point directly at the target method, avoiding an intermediate closure + + discard pattern in use binding descartar o padrão em uso de associação diff --git a/src/Compiler/xlf/FSComp.txt.ru.xlf b/src/Compiler/xlf/FSComp.txt.ru.xlf index 4b425932b82..cad6afcf849 100644 --- a/src/Compiler/xlf/FSComp.txt.ru.xlf +++ b/src/Compiler/xlf/FSComp.txt.ru.xlf @@ -367,6 +367,11 @@ Deprecate places where 'seq' can be omitted + + construct delegates that point directly at the target method, avoiding an intermediate closure + construct delegates that point directly at the target method, avoiding an intermediate closure + + discard pattern in use binding шаблон отмены в привязке использования diff --git a/src/Compiler/xlf/FSComp.txt.tr.xlf b/src/Compiler/xlf/FSComp.txt.tr.xlf index 851fc063da5..b4b623b0f14 100644 --- a/src/Compiler/xlf/FSComp.txt.tr.xlf +++ b/src/Compiler/xlf/FSComp.txt.tr.xlf @@ -367,6 +367,11 @@ Deprecate places where 'seq' can be omitted + + construct delegates that point directly at the target method, avoiding an intermediate closure + construct delegates that point directly at the target method, avoiding an intermediate closure + + discard pattern in use binding kullanım bağlamasında deseni at diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf index 589fc4eac1a..c068aab598a 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hans.xlf @@ -367,6 +367,11 @@ Deprecate places where 'seq' can be omitted + + construct delegates that point directly at the target method, avoiding an intermediate closure + construct delegates that point directly at the target method, avoiding an intermediate closure + + discard pattern in use binding 放弃使用绑定模式 diff --git a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf index e3f84137cdb..35835c63633 100644 --- a/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf +++ b/src/Compiler/xlf/FSComp.txt.zh-Hant.xlf @@ -367,6 +367,11 @@ Deprecate places where 'seq' can be omitted + + construct delegates that point directly at the target method, avoiding an intermediate closure + construct delegates that point directly at the target method, avoiding an intermediate closure + + discard pattern in use binding 捨棄使用繫結中的模式 diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs new file mode 100644 index 00000000000..b0d991a9b7f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs @@ -0,0 +1,42 @@ +module DelegateCustomType + +open System + +// Custom, F#-declared delegate types exercise construction with delegates defined in the *compiled* assembly +// (local scope, unlike imported BCL Func/Action) and with Invoke signatures the Func/Action tests do not +// cover: a multi-argument (tupled) signature, a generic delegate, and a byref parameter. (F# forbids curried +// delegate signatures — FS0950 — so every F# delegate has a single tupled Invoke parameter group.) + +type DTupled = delegate of int * int -> int +type DGen<'T> = delegate of 'T -> 'T +type DByref = delegate of byref -> unit + +let acc (x: int) (y: int) : int = x + y + +let ident (x: 'T) : 'T = x + +type C() = + member _.M (x: int) (y: int) : int = x * y + +// Tupled-signature custom delegate: Invoke(int, int). +// 28. non-eta module function, custom delegate +let tupledNonEta () = DTupled(acc) +// 14. eta module function, custom delegate +let tupledEta () = DTupled(fun a b -> acc a b) + +// Instance member through a custom delegate: the receiver becomes the delegate's Target. +// 29. non-eta instance member, custom delegate +let instanceNonEta (c: C) = DTupled(c.M) +// 15. eta instance member, custom delegate +let instanceEta (c: C) = DTupled(fun a b -> c.M a b) + +// Generic custom delegate instantiated at int: Invoke(int):int over the generic target. +// 30. non-eta generic method, generic custom delegate +let genNonEta () = DGen(ident) +// 16. eta generic method, generic custom delegate +let genEta () = DGen(fun x -> ident x) + +// byref-parameter custom delegate: the body mutates through the byref, so it is not a transparent forwarding +// call and stays a closure. Documents that a byref Invoke parameter does not break the recognizer. +// 53. byref-parameter delegate (mutating body) +let byrefMutate () = DByref(fun x -> x <- x + 1) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs.OptimizeOff.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs.OptimizeOff.Preview.il.bsl new file mode 100644 index 00000000000..c9d56b7d0a0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs.OptimizeOff.Preview.il.bsl @@ -0,0 +1,348 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable sealed nested public DTupled + extends [runtime]System.MulticastDelegate + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed + { + } + + .method public hidebysig strict virtual instance int32 Invoke(int32 A_1, int32 A_2) runtime managed + { + } + + .method public hidebysig strict virtual + instance class [runtime]System.IAsyncResult + BeginInvoke(int32 A_1, + int32 A_2, + class [runtime]System.AsyncCallback callback, + object objects) runtime managed + { + } + + .method public hidebysig strict virtual instance int32 EndInvoke(class [runtime]System.IAsyncResult result) runtime managed + { + } + + } + + .class auto ansi serializable sealed nested public DGen`1 + extends [runtime]System.MulticastDelegate + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed + { + } + + .method public hidebysig strict virtual instance !T Invoke(!T A_1) runtime managed + { + } + + .method public hidebysig strict virtual + instance class [runtime]System.IAsyncResult + BeginInvoke(!T A_1, + class [runtime]System.AsyncCallback callback, + object objects) runtime managed + { + } + + .method public hidebysig strict virtual instance !T EndInvoke(class [runtime]System.IAsyncResult result) runtime managed + { + } + + } + + .class auto ansi serializable sealed nested public DByref + extends [runtime]System.MulticastDelegate + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed + { + } + + .method public hidebysig strict virtual instance void Invoke(int32& A_1) runtime managed + { + } + + .method public hidebysig strict virtual + instance class [runtime]System.IAsyncResult + BeginInvoke(int32& A_1, + class [runtime]System.AsyncCallback callback, + object objects) runtime managed + { + } + + .method public hidebysig strict virtual instance void EndInvoke(class [runtime]System.IAsyncResult result) runtime managed + { + } + + } + + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance int32 M(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: mul + IL_0003: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname tupledEta@25 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call int32 assembly::acc(int32, + int32) + IL_0007: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname instanceEta@31 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C c + .method public specialname rtspecialname instance void .ctor(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/instanceEta@31::c + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance int32 Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/instanceEta@31::c + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: callvirt instance int32 assembly/C::M(int32, + int32) + IL_000d: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname genEta@37 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call !!0 assembly::ident(!!0) + IL_0006: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname byrefMutate@42 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32& x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: ldobj [runtime]System.Int32 + IL_0007: ldc.i4.1 + IL_0008: add + IL_0009: stobj [runtime]System.Int32 + IL_000e: ret + } + + } + + .method public static int32 acc(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: add + IL_0003: ret + } + + .method public static !!T ident(!!T x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static class assembly/DTupled tupledNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly::acc(int32, + int32) + IL_0007: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DTupled tupledEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/tupledEta@25::Invoke(int32, + int32) + IL_0007: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DTupled instanceNonEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldftn instance int32 assembly/C::M(int32, + int32) + IL_0007: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DTupled instanceEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/instanceEta@31::.ctor(class assembly/C) + IL_0006: ldftn instance int32 assembly/instanceEta@31::Invoke(int32, + int32) + IL_000c: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class assembly/DGen`1 genNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn !!0 assembly::ident(!!0) + IL_0007: newobj instance void class assembly/DGen`1::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DGen`1 genEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/genEta@37::Invoke(int32) + IL_0007: newobj instance void class assembly/DGen`1::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DByref byrefMutate() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/byrefMutate@42::Invoke(int32&) + IL_0007: newobj instance void assembly/DByref::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs.OptimizeOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs.OptimizeOff.il.bsl new file mode 100644 index 00000000000..66053083940 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs.OptimizeOff.il.bsl @@ -0,0 +1,414 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable sealed nested public DTupled + extends [runtime]System.MulticastDelegate + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed + { + } + + .method public hidebysig strict virtual instance int32 Invoke(int32 A_1, int32 A_2) runtime managed + { + } + + .method public hidebysig strict virtual + instance class [runtime]System.IAsyncResult + BeginInvoke(int32 A_1, + int32 A_2, + class [runtime]System.AsyncCallback callback, + object objects) runtime managed + { + } + + .method public hidebysig strict virtual instance int32 EndInvoke(class [runtime]System.IAsyncResult result) runtime managed + { + } + + } + + .class auto ansi serializable sealed nested public DGen`1 + extends [runtime]System.MulticastDelegate + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed + { + } + + .method public hidebysig strict virtual instance !T Invoke(!T A_1) runtime managed + { + } + + .method public hidebysig strict virtual + instance class [runtime]System.IAsyncResult + BeginInvoke(!T A_1, + class [runtime]System.AsyncCallback callback, + object objects) runtime managed + { + } + + .method public hidebysig strict virtual instance !T EndInvoke(class [runtime]System.IAsyncResult result) runtime managed + { + } + + } + + .class auto ansi serializable sealed nested public DByref + extends [runtime]System.MulticastDelegate + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed + { + } + + .method public hidebysig strict virtual instance void Invoke(int32& A_1) runtime managed + { + } + + .method public hidebysig strict virtual + instance class [runtime]System.IAsyncResult + BeginInvoke(int32& A_1, + class [runtime]System.AsyncCallback callback, + object objects) runtime managed + { + } + + .method public hidebysig strict virtual instance void EndInvoke(class [runtime]System.IAsyncResult result) runtime managed + { + } + + } + + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance int32 M(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: mul + IL_0003: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname tupledNonEta@23 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call int32 assembly::acc(int32, + int32) + IL_0007: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname tupledEta@25 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call int32 assembly::acc(int32, + int32) + IL_0007: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname instanceNonEta@29 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C c + .method public specialname rtspecialname instance void .ctor(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/instanceNonEta@29::c + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance int32 Invoke(int32 delegateArg0, int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/instanceNonEta@29::c + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: callvirt instance int32 assembly/C::M(int32, + int32) + IL_000d: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname instanceEta@31 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C c + .method public specialname rtspecialname instance void .ctor(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/instanceEta@31::c + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance int32 Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/instanceEta@31::c + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: callvirt instance int32 assembly/C::M(int32, + int32) + IL_000d: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname genNonEta@35 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 delegateArg0) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call !!0 assembly::ident(!!0) + IL_0006: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname genEta@37 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call !!0 assembly::ident(!!0) + IL_0006: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname byrefMutate@42 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32& x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: ldobj [runtime]System.Int32 + IL_0007: ldc.i4.1 + IL_0008: add + IL_0009: stobj [runtime]System.Int32 + IL_000e: ret + } + + } + + .method public static int32 acc(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: add + IL_0003: ret + } + + .method public static !!T ident(!!T x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static class assembly/DTupled tupledNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/tupledNonEta@23::Invoke(int32, + int32) + IL_0007: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DTupled tupledEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/tupledEta@25::Invoke(int32, + int32) + IL_0007: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DTupled instanceNonEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/instanceNonEta@29::.ctor(class assembly/C) + IL_0006: ldftn instance int32 assembly/instanceNonEta@29::Invoke(int32, + int32) + IL_000c: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class assembly/DTupled instanceEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/instanceEta@31::.ctor(class assembly/C) + IL_0006: ldftn instance int32 assembly/instanceEta@31::Invoke(int32, + int32) + IL_000c: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class assembly/DGen`1 genNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/genNonEta@35::Invoke(int32) + IL_0007: newobj instance void class assembly/DGen`1::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DGen`1 genEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/genEta@37::Invoke(int32) + IL_0007: newobj instance void class assembly/DGen`1::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DByref byrefMutate() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/byrefMutate@42::Invoke(int32&) + IL_0007: newobj instance void assembly/DByref::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs.OptimizeOn.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs.OptimizeOn.Preview.il.bsl new file mode 100644 index 00000000000..15a1a5f9f34 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs.OptimizeOn.Preview.il.bsl @@ -0,0 +1,282 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable sealed nested public DTupled + extends [runtime]System.MulticastDelegate + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed + { + } + + .method public hidebysig strict virtual instance int32 Invoke(int32 A_1, int32 A_2) runtime managed + { + } + + .method public hidebysig strict virtual + instance class [runtime]System.IAsyncResult + BeginInvoke(int32 A_1, + int32 A_2, + class [runtime]System.AsyncCallback callback, + object objects) runtime managed + { + } + + .method public hidebysig strict virtual instance int32 EndInvoke(class [runtime]System.IAsyncResult result) runtime managed + { + } + + } + + .class auto ansi serializable sealed nested public DGen`1 + extends [runtime]System.MulticastDelegate + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed + { + } + + .method public hidebysig strict virtual instance !T Invoke(!T A_1) runtime managed + { + } + + .method public hidebysig strict virtual + instance class [runtime]System.IAsyncResult + BeginInvoke(!T A_1, + class [runtime]System.AsyncCallback callback, + object objects) runtime managed + { + } + + .method public hidebysig strict virtual instance !T EndInvoke(class [runtime]System.IAsyncResult result) runtime managed + { + } + + } + + .class auto ansi serializable sealed nested public DByref + extends [runtime]System.MulticastDelegate + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed + { + } + + .method public hidebysig strict virtual instance void Invoke(int32& A_1) runtime managed + { + } + + .method public hidebysig strict virtual + instance class [runtime]System.IAsyncResult + BeginInvoke(int32& A_1, + class [runtime]System.AsyncCallback callback, + object objects) runtime managed + { + } + + .method public hidebysig strict virtual instance void EndInvoke(class [runtime]System.IAsyncResult result) runtime managed + { + } + + } + + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance int32 M(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: mul + IL_0003: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname byrefMutate@42 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32& x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: ldobj [runtime]System.Int32 + IL_0007: ldc.i4.1 + IL_0008: add + IL_0009: stobj [runtime]System.Int32 + IL_000e: ret + } + + } + + .method public static int32 acc(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: add + IL_0003: ret + } + + .method public static !!T ident(!!T x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static class assembly/DTupled tupledNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly::acc(int32, + int32) + IL_0007: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DTupled tupledEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly::acc(int32, + int32) + IL_0007: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DTupled instanceNonEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldftn instance int32 assembly/C::M(int32, + int32) + IL_0007: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DTupled instanceEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldftn instance int32 assembly/C::M(int32, + int32) + IL_0007: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DGen`1 genNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn !!0 assembly::ident(!!0) + IL_0007: newobj instance void class assembly/DGen`1::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DGen`1 genEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn !!0 assembly::ident(!!0) + IL_0007: newobj instance void class assembly/DGen`1::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DByref byrefMutate() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/byrefMutate@42::Invoke(int32&) + IL_0007: newobj instance void assembly/DByref::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs.OptimizeOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs.OptimizeOn.il.bsl new file mode 100644 index 00000000000..91f76166944 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateCustomType.fs.OptimizeOn.il.bsl @@ -0,0 +1,378 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable sealed nested public DTupled + extends [runtime]System.MulticastDelegate + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed + { + } + + .method public hidebysig strict virtual instance int32 Invoke(int32 A_1, int32 A_2) runtime managed + { + } + + .method public hidebysig strict virtual + instance class [runtime]System.IAsyncResult + BeginInvoke(int32 A_1, + int32 A_2, + class [runtime]System.AsyncCallback callback, + object objects) runtime managed + { + } + + .method public hidebysig strict virtual instance int32 EndInvoke(class [runtime]System.IAsyncResult result) runtime managed + { + } + + } + + .class auto ansi serializable sealed nested public DGen`1 + extends [runtime]System.MulticastDelegate + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed + { + } + + .method public hidebysig strict virtual instance !T Invoke(!T A_1) runtime managed + { + } + + .method public hidebysig strict virtual + instance class [runtime]System.IAsyncResult + BeginInvoke(!T A_1, + class [runtime]System.AsyncCallback callback, + object objects) runtime managed + { + } + + .method public hidebysig strict virtual instance !T EndInvoke(class [runtime]System.IAsyncResult result) runtime managed + { + } + + } + + .class auto ansi serializable sealed nested public DByref + extends [runtime]System.MulticastDelegate + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig specialname rtspecialname instance void .ctor(object 'object', native int 'method') runtime managed + { + } + + .method public hidebysig strict virtual instance void Invoke(int32& A_1) runtime managed + { + } + + .method public hidebysig strict virtual + instance class [runtime]System.IAsyncResult + BeginInvoke(int32& A_1, + class [runtime]System.AsyncCallback callback, + object objects) runtime managed + { + } + + .method public hidebysig strict virtual instance void EndInvoke(class [runtime]System.IAsyncResult result) runtime managed + { + } + + } + + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance int32 M(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: mul + IL_0003: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname tupledNonEta@23 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: add + IL_0003: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname tupledEta@25 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: add + IL_0003: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname instanceNonEta@29 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 delegateArg0, + int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: mul + IL_0003: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname instanceEta@31 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: mul + IL_0003: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname genNonEta@35 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 delegateArg0) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname genEta@37 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname byrefMutate@42 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32& x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.0 + IL_0002: ldobj [runtime]System.Int32 + IL_0007: ldc.i4.1 + IL_0008: add + IL_0009: stobj [runtime]System.Int32 + IL_000e: ret + } + + } + + .method public static int32 acc(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: add + IL_0003: ret + } + + .method public static !!T ident(!!T x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + .method public static class assembly/DTupled tupledNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/tupledNonEta@23::Invoke(int32, + int32) + IL_0007: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DTupled tupledEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/tupledEta@25::Invoke(int32, + int32) + IL_0007: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DTupled instanceNonEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/instanceNonEta@29::Invoke(int32, + int32) + IL_0007: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DTupled instanceEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/instanceEta@31::Invoke(int32, + int32) + IL_0007: newobj instance void assembly/DTupled::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DGen`1 genNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/genNonEta@35::Invoke(int32) + IL_0007: newobj instance void class assembly/DGen`1::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DGen`1 genEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/genEta@37::Invoke(int32) + IL_0007: newobj instance void class assembly/DGen`1::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class assembly/DByref byrefMutate() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/byrefMutate@42::Invoke(int32&) + IL_0007: newobj instance void assembly/DByref::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs new file mode 100644 index 00000000000..6d7ecdd9960 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs @@ -0,0 +1,22 @@ +module DelegateExtensionMethod + +open System +open System.Runtime.CompilerServices + +type Holder() = + class + end + +[] +type HolderExtensions = + [] + static member Combine (h: Holder, x: int, y: int) : int = x + y + +// An extension member compiles to a static method whose first parameter is the receiver. Using it as a +// delegate target binds that receiver as a leading argument, which the CLR's "closed over the first argument" +// delegate stores as the Target while the function pointer points at the static method - a direct delegate. +// (The member here is tupled, 'Combine(h, x, y)'; the recognizer de-tuples the forwarding call by the target's +// arity, exactly as the code generator does when emitting the call.) As an eta-expanded delegate it is direct +// only in optimized builds, where the user's lambda need not survive for debugging. +// 52. extension member (receiver is a leading static arg, bound as Target) +let extensionEta (h: Holder) = Func(fun a b -> h.Combine(a, b)) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs.OptimizeOff.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs.OptimizeOff.Preview.il.bsl new file mode 100644 index 00000000000..0e4b863938b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs.OptimizeOff.Preview.il.bsl @@ -0,0 +1,138 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public Holder + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + } + + .class auto ansi serializable nested public HolderExtensions + extends [runtime]System.Object + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static int32 Combine(class assembly/Holder h, + int32 x, + int32 y) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: add + IL_0003: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname extensionEta@22 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/Holder h + .method public specialname rtspecialname instance void .ctor(class assembly/Holder h) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/Holder assembly/extensionEta@22::h + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance int32 Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/Holder assembly/extensionEta@22::h + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: call int32 assembly/HolderExtensions::Combine(class assembly/Holder, + int32, + int32) + IL_000d: ret + } + + } + + .method public static class [runtime]System.Func`3 extensionEta(class assembly/Holder h) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/extensionEta@22::.ctor(class assembly/Holder) + IL_0006: ldftn instance int32 assembly/extensionEta@22::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_0011: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs.OptimizeOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs.OptimizeOff.il.bsl new file mode 100644 index 00000000000..940811fcfab --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs.OptimizeOff.il.bsl @@ -0,0 +1,138 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public Holder + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + } + + .class auto ansi serializable nested public HolderExtensions + extends [runtime]System.Object + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static int32 Combine(class assembly/Holder h, + int32 x, + int32 y) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: add + IL_0003: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname extensionEta@22 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/Holder h + .method public specialname rtspecialname instance void .ctor(class assembly/Holder h) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/Holder assembly/extensionEta@22::h + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance int32 Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/Holder assembly/extensionEta@22::h + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: call int32 assembly/HolderExtensions::Combine(class assembly/Holder, + int32, + int32) + IL_000d: ret + } + + } + + .method public static class [runtime]System.Func`3 extensionEta(class assembly/Holder h) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/extensionEta@22::.ctor(class assembly/Holder) + IL_0006: ldftn instance int32 assembly/extensionEta@22::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_0011: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs.OptimizeOn.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs.OptimizeOn.Preview.il.bsl new file mode 100644 index 00000000000..6e78d1cdc46 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs.OptimizeOn.Preview.il.bsl @@ -0,0 +1,105 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public Holder + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + } + + .class auto ansi serializable nested public HolderExtensions + extends [runtime]System.Object + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static int32 Combine(class assembly/Holder h, + int32 x, + int32 y) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: add + IL_0003: ret + } + + } + + .method public static class [runtime]System.Func`3 extensionEta(class assembly/Holder h) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldftn int32 assembly/HolderExtensions::Combine(class assembly/Holder, + int32, + int32) + IL_0007: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs.OptimizeOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs.OptimizeOn.il.bsl new file mode 100644 index 00000000000..8168284b0b3 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateExtensionMethod.fs.OptimizeOn.il.bsl @@ -0,0 +1,121 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public Holder + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + } + + .class auto ansi serializable nested public HolderExtensions + extends [runtime]System.Object + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static int32 Combine(class assembly/Holder h, + int32 x, + int32 y) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: add + IL_0003: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname extensionEta@22 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: add + IL_0003: ret + } + + } + + .method public static class [runtime]System.Func`3 extensionEta(class assembly/Holder h) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/extensionEta@22::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs new file mode 100644 index 00000000000..535bee3d582 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs @@ -0,0 +1,13 @@ +module DelegateGenericInstanceMethod + +open System + +type C() = + member _.IMc<'T> (x: 'T) (y: 'T) : unit = () + member _.IMt<'T> (x: 'T, y: 'T) : unit = () + +// 5. eta generic instance method (curried application) +let case5_etaCurried (o: C) = Action(fun a b -> o.IMc a b) + +// 35. eta generic instance method, tupled application +let case35_etaTupled (o: C) = Action(fun a b -> o.IMt(a, b)) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs.OptimizeOff.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs.OptimizeOff.Preview.il.bsl new file mode 100644 index 00000000000..12696733399 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs.OptimizeOff.Preview.il.bsl @@ -0,0 +1,179 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance void IMc(!!T x, !!T y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public hidebysig instance void IMt(!!T x, !!T y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname case5_etaCurried@10 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C o + .method public specialname rtspecialname instance void .ctor(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/case5_etaCurried@10::o + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/case5_etaCurried@10::o + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: callvirt instance void assembly/C::IMc(!!0, + !!0) + IL_000d: nop + IL_000e: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname case35_etaTupled@13 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C o + .method public specialname rtspecialname instance void .ctor(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/case35_etaTupled@13::o + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/case35_etaTupled@13::o + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: callvirt instance void assembly/C::IMt(!!0, + !!0) + IL_000d: nop + IL_000e: ret + } + + } + + .method public static class [runtime]System.Action`2 case5_etaCurried(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/case5_etaCurried@10::.ctor(class assembly/C) + IL_0006: ldftn instance void assembly/case5_etaCurried@10::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Action`2 case35_etaTupled(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/case35_etaTupled@13::.ctor(class assembly/C) + IL_0006: ldftn instance void assembly/case35_etaTupled@13::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs.OptimizeOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs.OptimizeOff.il.bsl new file mode 100644 index 00000000000..12696733399 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs.OptimizeOff.il.bsl @@ -0,0 +1,179 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance void IMc(!!T x, !!T y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public hidebysig instance void IMt(!!T x, !!T y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname case5_etaCurried@10 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C o + .method public specialname rtspecialname instance void .ctor(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/case5_etaCurried@10::o + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/case5_etaCurried@10::o + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: callvirt instance void assembly/C::IMc(!!0, + !!0) + IL_000d: nop + IL_000e: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname case35_etaTupled@13 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C o + .method public specialname rtspecialname instance void .ctor(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/case35_etaTupled@13::o + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/case35_etaTupled@13::o + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: callvirt instance void assembly/C::IMt(!!0, + !!0) + IL_000d: nop + IL_000e: ret + } + + } + + .method public static class [runtime]System.Action`2 case5_etaCurried(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/case5_etaCurried@10::.ctor(class assembly/C) + IL_0006: ldftn instance void assembly/case5_etaCurried@10::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Action`2 case35_etaTupled(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/case35_etaTupled@13::.ctor(class assembly/C) + IL_0006: ldftn instance void assembly/case35_etaTupled@13::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs.OptimizeOn.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs.OptimizeOn.Preview.il.bsl new file mode 100644 index 00000000000..26e0b7e9705 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs.OptimizeOn.Preview.il.bsl @@ -0,0 +1,111 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance void IMc(!!T x, !!T y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public hidebysig instance void IMt(!!T x, !!T y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .method public static class [runtime]System.Action`2 case5_etaCurried(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldftn instance void assembly/C::IMc(!!0, + !!0) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case35_etaTupled(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldftn instance void assembly/C::IMt(!!0, + !!0) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs.OptimizeOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs.OptimizeOn.il.bsl new file mode 100644 index 00000000000..74be77228f1 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericInstanceMethod.fs.OptimizeOn.il.bsl @@ -0,0 +1,139 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance void IMc(!!T x, !!T y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public hidebysig instance void IMt(!!T x, !!T y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case5_etaCurried@10 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case35_etaTupled@13 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .method public static class [runtime]System.Action`2 case5_etaCurried(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case5_etaCurried@10::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case35_etaTupled(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case35_etaTupled@13::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs new file mode 100644 index 00000000000..a4e30bdaf08 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs @@ -0,0 +1,16 @@ +module DelegateGenericStaticMethod + +open System + +type G<'U> = + static member SMc<'T> (x: 'T) (y: 'T) : unit = () + static member SMt<'T> (x: 'T, y: 'T) : unit = () + +// 19. non-eta generic static method (generic type + generic method) +let case19_nonEta () = Action(G.SMc) + +// 3. eta generic static method (curried application) +let case3_etaCurried () = Action(fun a b -> G.SMc a b) + +// 33. eta generic static method, tupled application +let case33_etaTupled () = Action(fun a b -> G.SMt(a, b)) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs.OptimizeOff.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs.OptimizeOff.Preview.il.bsl new file mode 100644 index 00000000000..39cb26442a6 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs.OptimizeOff.Preview.il.bsl @@ -0,0 +1,152 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public G`1 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static void SMc(!!T x, + !!T y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static void SMt(!!T x, + !!T y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case3_etaCurried@13 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void class assembly/G`1::SMc(!!0, + !!0) + IL_0007: nop + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case33_etaTupled@16 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void class assembly/G`1::SMt(!!0, + !!0) + IL_0007: nop + IL_0008: ret + } + + } + + .method public static class [runtime]System.Action`2 case19_nonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void class assembly/G`1::SMc(!!0, + !!0) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case3_etaCurried() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case3_etaCurried@13::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case33_etaTupled() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case33_etaTupled@16::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs.OptimizeOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs.OptimizeOff.il.bsl new file mode 100644 index 00000000000..52f0ce42863 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs.OptimizeOff.il.bsl @@ -0,0 +1,171 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public G`1 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static void SMc(!!T x, + !!T y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static void SMt(!!T x, + !!T y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case19_nonEta@10 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void class assembly/G`1::SMc(!!0, + !!0) + IL_0007: nop + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case3_etaCurried@13 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void class assembly/G`1::SMc(!!0, + !!0) + IL_0007: nop + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case33_etaTupled@16 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void class assembly/G`1::SMt(!!0, + !!0) + IL_0007: nop + IL_0008: ret + } + + } + + .method public static class [runtime]System.Action`2 case19_nonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case19_nonEta@10::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case3_etaCurried() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case3_etaCurried@13::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case33_etaTupled() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case33_etaTupled@16::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs.OptimizeOn.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs.OptimizeOn.Preview.il.bsl new file mode 100644 index 00000000000..cb158381c58 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs.OptimizeOn.Preview.il.bsl @@ -0,0 +1,114 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public G`1 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static void SMc(!!T x, + !!T y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static void SMt(!!T x, + !!T y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .method public static class [runtime]System.Action`2 case19_nonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void class assembly/G`1::SMc(!!0, + !!0) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case3_etaCurried() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void class assembly/G`1::SMc(!!0, + !!0) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case33_etaTupled() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void class assembly/G`1::SMt(!!0, + !!0) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs.OptimizeOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs.OptimizeOn.il.bsl new file mode 100644 index 00000000000..97f8c55b9dc --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateGenericStaticMethod.fs.OptimizeOn.il.bsl @@ -0,0 +1,156 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public G`1 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static void SMc(!!T x, + !!T y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static void SMt(!!T x, + !!T y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case19_nonEta@10 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case3_etaCurried@13 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case33_etaTupled@16 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .method public static class [runtime]System.Action`2 case19_nonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case19_nonEta@10::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case3_etaCurried() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case3_etaCurried@13::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case33_etaTupled() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case33_etaTupled@16::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs new file mode 100644 index 00000000000..d5a9ebf9fbe --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs @@ -0,0 +1,15 @@ +module DelegateILMethod + +open System +open System.Text + +// IL (BCL) method targets are compiled as TOp.ILCall rather than an F# value application. They are made +// direct only in optimized builds; in unoptimized builds the eta form keeps a closure (matching the F# +// eta policy). See DelegateKnownFunction for the F#-value equivalent. + +// 12. eta IL/BCL static method (System.Math.Max). +let ilStaticEta () = Func(fun a b -> Math.Max(a, b)) + +// 13. eta IL/BCL instance method (StringBuilder.Append(string)) on a reference type. The receiver is a +// parameter, evaluated at the construction site and carried as the delegate's Target. +let ilInstanceEta (sb: StringBuilder) = Func(fun s -> sb.Append(s)) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs.OptimizeOff.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs.OptimizeOff.Preview.il.bsl new file mode 100644 index 00000000000..5ca457d058f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs.OptimizeOff.Preview.il.bsl @@ -0,0 +1,127 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname ilStaticEta@11 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call int32 [runtime]System.Math::Max(int32, + int32) + IL_0007: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname ilInstanceEta@15 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class [runtime]System.Text.StringBuilder sb + .method public specialname rtspecialname instance void .ctor(class [runtime]System.Text.StringBuilder sb) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [runtime]System.Text.StringBuilder assembly/ilInstanceEta@15::sb + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance class [runtime]System.Text.StringBuilder Invoke(string s) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [runtime]System.Text.StringBuilder assembly/ilInstanceEta@15::sb + IL_0006: ldarg.1 + IL_0007: callvirt instance class [runtime]System.Text.StringBuilder [runtime]System.Text.StringBuilder::Append(string) + IL_000c: ret + } + + } + + .method public static class [runtime]System.Func`3 ilStaticEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/ilStaticEta@11::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`2 ilInstanceEta(class [runtime]System.Text.StringBuilder sb) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/ilInstanceEta@15::.ctor(class [runtime]System.Text.StringBuilder) + IL_0006: ldftn instance class [runtime]System.Text.StringBuilder assembly/ilInstanceEta@15::Invoke(string) + IL_000c: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_0011: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs.OptimizeOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs.OptimizeOff.il.bsl new file mode 100644 index 00000000000..98e340a1d79 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs.OptimizeOff.il.bsl @@ -0,0 +1,127 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname ilStaticEta@11 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call int32 [runtime]System.Math::Max(int32, + int32) + IL_0007: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname ilInstanceEta@15 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class [runtime]System.Text.StringBuilder sb + .method public specialname rtspecialname instance void .ctor(class [runtime]System.Text.StringBuilder sb) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [runtime]System.Text.StringBuilder assembly/ilInstanceEta@15::sb + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance class [runtime]System.Text.StringBuilder Invoke(string s) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [runtime]System.Text.StringBuilder assembly/ilInstanceEta@15::sb + IL_0006: ldarg.1 + IL_0007: callvirt instance class [runtime]System.Text.StringBuilder [runtime]System.Text.StringBuilder::Append(string) + IL_000c: ret + } + + } + + .method public static class [runtime]System.Func`3 ilStaticEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/ilStaticEta@11::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`2 ilInstanceEta(class [runtime]System.Text.StringBuilder sb) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/ilInstanceEta@15::.ctor(class [runtime]System.Text.StringBuilder) + IL_0006: ldftn instance class [runtime]System.Text.StringBuilder assembly/ilInstanceEta@15::Invoke(string) + IL_000c: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_0011: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs.OptimizeOn.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs.OptimizeOn.Preview.il.bsl new file mode 100644 index 00000000000..ef4e95130a2 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs.OptimizeOn.Preview.il.bsl @@ -0,0 +1,78 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .method public static class [runtime]System.Func`3 ilStaticEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 [runtime]System.Math::Max(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`2 ilInstanceEta(class [runtime]System.Text.StringBuilder sb) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldftn instance class [runtime]System.Text.StringBuilder [runtime]System.Text.StringBuilder::Append(string) + IL_0007: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs.OptimizeOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs.OptimizeOn.il.bsl new file mode 100644 index 00000000000..98e340a1d79 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateILMethod.fs.OptimizeOn.il.bsl @@ -0,0 +1,127 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname ilStaticEta@11 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call int32 [runtime]System.Math::Max(int32, + int32) + IL_0007: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname ilInstanceEta@15 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class [runtime]System.Text.StringBuilder sb + .method public specialname rtspecialname instance void .ctor(class [runtime]System.Text.StringBuilder sb) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [runtime]System.Text.StringBuilder assembly/ilInstanceEta@15::sb + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance class [runtime]System.Text.StringBuilder Invoke(string s) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [runtime]System.Text.StringBuilder assembly/ilInstanceEta@15::sb + IL_0006: ldarg.1 + IL_0007: callvirt instance class [runtime]System.Text.StringBuilder [runtime]System.Text.StringBuilder::Append(string) + IL_000c: ret + } + + } + + .method public static class [runtime]System.Func`3 ilStaticEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/ilStaticEta@11::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`2 ilInstanceEta(class [runtime]System.Text.StringBuilder sb) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/ilInstanceEta@15::.ctor(class [runtime]System.Text.StringBuilder) + IL_0006: ldftn instance class [runtime]System.Text.StringBuilder assembly/ilInstanceEta@15::Invoke(string) + IL_000c: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_0011: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs new file mode 100644 index 00000000000..76c6c53e334 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs @@ -0,0 +1,21 @@ +module DelegateInstanceMethod + +open System + +type C(k: int) = + member _.AddC (x: int) (y: int) : unit = ignore k + member _.AddT (x: int, y: int) : unit = ignore k + abstract V : int -> int -> unit + default _.V (x: int) (y: int) : unit = ignore k + +// 20. non-eta instance method +let case20_nonEta (o: C) = Action(o.AddC) + +// 4. eta instance method (curried application) +let case4_etaCurried (o: C) = Action(fun a b -> o.AddC a b) + +// 34. eta instance method, tupled application +let case34_etaTupled (o: C) = Action(fun a b -> o.AddT(a, b)) + +// 21. non-eta virtual instance method: a direct delegate must use ldvirtftn (with dup) to preserve dispatch +let case21_virtual (o: C) = Action(o.V) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs.OptimizeOff.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs.OptimizeOff.Preview.il.bsl new file mode 100644 index 00000000000..876f6a1aaee --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs.OptimizeOff.Preview.il.bsl @@ -0,0 +1,228 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .field assembly int32 k + .method public specialname rtspecialname instance void .ctor(int32 k) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld int32 assembly/C::k + IL_000f: ret + } + + .method public hidebysig instance void AddC(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 3 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldfld int32 assembly/C::k + IL_0006: stloc.0 + IL_0007: ret + } + + .method public hidebysig instance void AddT(int32 x, int32 y) cil managed + { + + .maxstack 3 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldfld int32 assembly/C::k + IL_0006: stloc.0 + IL_0007: ret + } + + .method public hidebysig virtual instance void V(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 3 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldfld int32 assembly/C::k + IL_0006: stloc.0 + IL_0007: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname case4_etaCurried@15 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C o + .method public specialname rtspecialname instance void .ctor(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/case4_etaCurried@15::o + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/case4_etaCurried@15::o + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: callvirt instance void assembly/C::AddC(int32, + int32) + IL_000d: nop + IL_000e: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname case34_etaTupled@18 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C o + .method public specialname rtspecialname instance void .ctor(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/case34_etaTupled@18::o + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/case34_etaTupled@18::o + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: callvirt instance void assembly/C::AddT(int32, + int32) + IL_000d: nop + IL_000e: ret + } + + } + + .method public static class [runtime]System.Action`2 case20_nonEta(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldftn instance void assembly/C::AddC(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case4_etaCurried(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/case4_etaCurried@15::.ctor(class assembly/C) + IL_0006: ldftn instance void assembly/case4_etaCurried@15::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Action`2 case34_etaTupled(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/case34_etaTupled@18::.ctor(class assembly/C) + IL_0006: ldftn instance void assembly/case34_etaTupled@18::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Action`2 case21_virtual(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: dup + IL_0002: ldvirtftn instance void assembly/C::V(int32, + int32) + IL_0008: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000d: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs.OptimizeOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs.OptimizeOff.il.bsl new file mode 100644 index 00000000000..a9c6bfae607 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs.OptimizeOff.il.bsl @@ -0,0 +1,295 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .field assembly int32 k + .method public specialname rtspecialname instance void .ctor(int32 k) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld int32 assembly/C::k + IL_000f: ret + } + + .method public hidebysig instance void AddC(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 3 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldfld int32 assembly/C::k + IL_0006: stloc.0 + IL_0007: ret + } + + .method public hidebysig instance void AddT(int32 x, int32 y) cil managed + { + + .maxstack 3 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldfld int32 assembly/C::k + IL_0006: stloc.0 + IL_0007: ret + } + + .method public hidebysig virtual instance void V(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 3 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldfld int32 assembly/C::k + IL_0006: stloc.0 + IL_0007: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname case20_nonEta@12 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C o + .method public specialname rtspecialname instance void .ctor(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/case20_nonEta@12::o + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 delegateArg0, int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/case20_nonEta@12::o + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: callvirt instance void assembly/C::AddC(int32, + int32) + IL_000d: nop + IL_000e: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname case4_etaCurried@15 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C o + .method public specialname rtspecialname instance void .ctor(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/case4_etaCurried@15::o + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/case4_etaCurried@15::o + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: callvirt instance void assembly/C::AddC(int32, + int32) + IL_000d: nop + IL_000e: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname case34_etaTupled@18 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C o + .method public specialname rtspecialname instance void .ctor(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/case34_etaTupled@18::o + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/case34_etaTupled@18::o + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: callvirt instance void assembly/C::AddT(int32, + int32) + IL_000d: nop + IL_000e: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname case21_virtual@21 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C o + .method public specialname rtspecialname instance void .ctor(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/case21_virtual@21::o + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 delegateArg0, int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/case21_virtual@21::o + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: tail. + IL_000a: callvirt instance void assembly/C::V(int32, + int32) + IL_000f: ret + } + + } + + .method public static class [runtime]System.Action`2 case20_nonEta(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/case20_nonEta@12::.ctor(class assembly/C) + IL_0006: ldftn instance void assembly/case20_nonEta@12::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Action`2 case4_etaCurried(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/case4_etaCurried@15::.ctor(class assembly/C) + IL_0006: ldftn instance void assembly/case4_etaCurried@15::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Action`2 case34_etaTupled(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/case34_etaTupled@18::.ctor(class assembly/C) + IL_0006: ldftn instance void assembly/case34_etaTupled@18::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Action`2 case21_virtual(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/case21_virtual@21::.ctor(class assembly/C) + IL_0006: ldftn instance void assembly/case21_virtual@21::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs.OptimizeOn.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs.OptimizeOn.Preview.il.bsl new file mode 100644 index 00000000000..13e7184f77c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs.OptimizeOn.Preview.il.bsl @@ -0,0 +1,148 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .field assembly int32 k + .method public specialname rtspecialname instance void .ctor(int32 k) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld int32 assembly/C::k + IL_000f: ret + } + + .method public hidebysig instance void AddC(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public hidebysig instance void AddT(int32 x, int32 y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public hidebysig virtual instance void V(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + } + + .method public static class [runtime]System.Action`2 case20_nonEta(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldftn instance void assembly/C::AddC(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case4_etaCurried(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldftn instance void assembly/C::AddC(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case34_etaTupled(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldftn instance void assembly/C::AddT(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case21_virtual(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: dup + IL_0002: ldvirtftn instance void assembly/C::V(int32, + int32) + IL_0008: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000d: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs.OptimizeOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs.OptimizeOn.il.bsl new file mode 100644 index 00000000000..b3569cf1a24 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateInstanceMethod.fs.OptimizeOn.il.bsl @@ -0,0 +1,223 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .field assembly int32 k + .method public specialname rtspecialname instance void .ctor(int32 k) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld int32 assembly/C::k + IL_000f: ret + } + + .method public hidebysig instance void AddC(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public hidebysig instance void AddT(int32 x, int32 y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public hidebysig virtual instance void V(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case20_nonEta@12 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 delegateArg0, + int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case4_etaCurried@15 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case34_etaTupled@18 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname case21_virtual@21 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C o + .method public specialname rtspecialname instance void .ctor(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/case21_virtual@21::o + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 delegateArg0, int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/case21_virtual@21::o + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: tail. + IL_000a: callvirt instance void assembly/C::V(int32, + int32) + IL_000f: ret + } + + } + + .method public static class [runtime]System.Action`2 case20_nonEta(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case20_nonEta@12::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case4_etaCurried(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case4_etaCurried@15::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case34_etaTupled(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case34_etaTupled@18::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case21_virtual(class assembly/C o) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/case21_virtual@21::.ctor(class assembly/C) + IL_0006: ldftn instance void assembly/case21_virtual@21::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs new file mode 100644 index 00000000000..8e550999ddf --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs @@ -0,0 +1,20 @@ +module DelegateKnownFunction + +open System + +// known F# functions compiled as methods +let handlerCurried (x: int) (y: int) : unit = () +let handlerTupled (x: int, y: int) : unit = () +let handler3 (x: int) (y: int) (z: int) : unit = () + +// 17. non-eta module function +let case17_nonEta () = Action(handlerCurried) + +// 1. eta module function (curried application) +let case1_etaCurried () = Action(fun a b -> handlerCurried a b) + +// 31. eta module function, tupled application (same compiled representation) +let case31_etaTupled () = Action(fun a b -> handlerTupled (a, b)) + +// 37. partial application of module function (constant arg) +let case37_partial () = Action(handler3 1) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs.OptimizeOff.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs.OptimizeOff.Preview.il.bsl new file mode 100644 index 00000000000..dd1c081a62f --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs.OptimizeOff.Preview.il.bsl @@ -0,0 +1,190 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case1_etaCurried@14 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void assembly::handlerCurried(int32, + int32) + IL_0007: nop + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case31_etaTupled@17 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void assembly::handlerTupled(int32, + int32) + IL_0007: nop + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case37_partial@20 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 arg1, + int32 arg2) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: call void assembly::handler3(int32, + int32, + int32) + IL_0008: nop + IL_0009: ret + } + + } + + .method public static void handlerCurried(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static void handlerTupled(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static void handler3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 case17_nonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly::handlerCurried(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case1_etaCurried() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case1_etaCurried@14::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case31_etaTupled() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case31_etaTupled@17::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case37_partial() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case37_partial@20::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs.OptimizeOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs.OptimizeOff.il.bsl new file mode 100644 index 00000000000..4d080c7c4a9 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs.OptimizeOff.il.bsl @@ -0,0 +1,209 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case17_nonEta@11 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void assembly::handlerCurried(int32, + int32) + IL_0007: nop + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case1_etaCurried@14 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void assembly::handlerCurried(int32, + int32) + IL_0007: nop + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case31_etaTupled@17 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void assembly::handlerTupled(int32, + int32) + IL_0007: nop + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case37_partial@20 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 delegateArg0, + int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: call void assembly::handler3(int32, + int32, + int32) + IL_0008: nop + IL_0009: ret + } + + } + + .method public static void handlerCurried(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static void handlerTupled(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static void handler3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 case17_nonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case17_nonEta@11::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case1_etaCurried() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case1_etaCurried@14::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case31_etaTupled() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case31_etaTupled@17::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case37_partial() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case37_partial@20::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs.OptimizeOn.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs.OptimizeOn.Preview.il.bsl new file mode 100644 index 00000000000..d881a035d3d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs.OptimizeOn.Preview.il.bsl @@ -0,0 +1,145 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case37_partial@20 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 arg1, + int32 arg2) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .method public static void handlerCurried(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static void handlerTupled(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static void handler3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 case17_nonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly::handlerCurried(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case1_etaCurried() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly::handlerCurried(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case31_etaTupled() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly::handlerTupled(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case37_partial() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case37_partial@20::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs.OptimizeOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs.OptimizeOn.il.bsl new file mode 100644 index 00000000000..2ac94696387 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateKnownFunction.fs.OptimizeOn.il.bsl @@ -0,0 +1,187 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case17_nonEta@11 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case1_etaCurried@14 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case31_etaTupled@17 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case37_partial@20 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 delegateArg0, + int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .method public static void handlerCurried(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static void handlerTupled(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static void handler3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 case17_nonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case17_nonEta@11::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case1_etaCurried() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case1_etaCurried@14::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case31_etaTupled() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case31_etaTupled@17::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case37_partial() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case37_partial@20::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs new file mode 100644 index 00000000000..3d00a59a5cb --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs @@ -0,0 +1,42 @@ +module DelegateNegativeCases + +open System +open System.Runtime.CompilerServices + +// 42. first-class function value: there is no target method to point at, so a closure must remain +let firstClass (handler: int -> int -> unit) = Action(handler) + +// 43. lambda body is not a single direct forwarding call to a known target (the argument is computed, +// not the delegate parameters forwarded as-is): a closure must remain +let private sink (x: int) : unit = () +let notDirect (k: int) = Action(fun a b -> sink (a + b + k)) + +// 44. arguments reordered: not a transparent forwarding, so a closure must remain +let reordered (handler: int -> int -> unit) = Action(fun a b -> handler b a) + +type Holder() = + member _.TakesObj (x: obj) : int = 1 + +// 45. Reference-parameter contravariance: the delegate's Invoke is (string):int and the target is (object):int. +// The CLR would accept this binding directly (a delegate may bind a method whose parameter is a supertype), +// but it stays a closure: F# elaborates the 'string -> obj' argument upcast as a coercion, so the forwarded +// argument is no longer a verbatim Invoke parameter and the direct-delegate recognizer does not match. (The +// signature check is not involved - it never even runs here.) +let contra (h: Holder) = System.Func(fun s -> h.TakesObj s) + +[] +type Extensions = + [] + static member Echo<'T> (x: 'T, y: int, z: int) : 'T = x + +// 54. extension member on a VALUE-TYPE receiver: an extension member compiles to a static method whose first +// parameter is the receiver, which the closed-delegate mechanism would store as the 'object' Target and pass +// straight into that first by-value parameter with no unboxing. A value-type receiver therefore has no closed +// form (unlike a value-type *instance* receiver, which is reached through the method's unboxing stub), so a +// closure must remain. +let valueTypeExtension () = Func(fun a b -> (3).Echo(a, b)) + +// 55. over-application: 'failwith' takes only the message, and it is the *returned function* that consumes +// the delegate's (elided unit) argument. There is no saturated call to the target to point at - and binding +// 'failwith' directly would evaluate it once instead of per invocation - so a closure must remain. +let overApplied () = Action(failwith "nope") diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs.OptimizeOff.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs.OptimizeOff.Preview.il.bsl new file mode 100644 index 00000000000..77ad669f0e0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs.OptimizeOff.Preview.il.bsl @@ -0,0 +1,361 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto autochar serializable sealed nested assembly beforefieldinit specialname firstClass@7 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler' + .method public specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/firstClass@7::'handler' + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 arg1, int32 arg2) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/firstClass@7::'handler' + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: call !!0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::InvokeFast(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, + !0, + !1) + IL_000d: pop + IL_000e: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname notDirect@12 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public int32 k + .method public specialname rtspecialname instance void .ctor(int32 k) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 assembly/notDirect@12::k + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: add + IL_0003: ldarg.0 + IL_0004: ldfld int32 assembly/notDirect@12::k + IL_0009: add + IL_000a: call void assembly::sink(int32) + IL_000f: nop + IL_0010: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname reordered@15 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler' + .method public specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/reordered@15::'handler' + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/reordered@15::'handler' + IL_0006: ldarg.2 + IL_0007: ldarg.1 + IL_0008: call !!0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::InvokeFast(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, + !0, + !1) + IL_000d: pop + IL_000e: ret + } + + } + + .class auto ansi serializable nested public Holder + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance int32 TakesObj(object x) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname contra@25 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/Holder h + .method public specialname rtspecialname instance void .ctor(class assembly/Holder h) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/Holder assembly/contra@25::h + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance int32 Invoke(string s) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/Holder assembly/contra@25::h + IL_0006: ldarg.1 + IL_0007: callvirt instance int32 assembly/Holder::TakesObj(object) + IL_000c: ret + } + + } + + .class auto ansi serializable nested public Extensions + extends [runtime]System.Object + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static !!T Echo(!!T x, + int32 y, + int32 z) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname valueTypeExtension@37 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.3 + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: call !!0 assembly/Extensions::Echo(!!0, + int32, + int32) + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname overApplied@42 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke() cil managed + { + + .maxstack 6 + .locals init (string V_0) + IL_0000: ldstr "nope" + IL_0005: stloc.0 + IL_0006: ldc.i4.0 + IL_0007: brfalse.s IL_0011 + + IL_0009: ldnull + IL_000a: unbox.any class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 + IL_000f: br.s IL_0018 + + IL_0011: ldloc.0 + IL_0012: call class [runtime]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) + IL_0017: throw + + IL_0018: ldnull + IL_0019: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001e: pop + IL_001f: ret + } + + } + + .method public static class [runtime]System.Action`2 firstClass(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/firstClass@7::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0006: ldftn instance void assembly/firstClass@7::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method private static void sink(int32 x) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 notDirect(int32 k) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/notDirect@12::.ctor(int32) + IL_0006: ldftn instance void assembly/notDirect@12::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Action`2 reordered(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/reordered@15::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0006: ldftn instance void assembly/reordered@15::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Func`2 contra(class assembly/Holder h) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/contra@25::.ctor(class assembly/Holder) + IL_0006: ldftn instance int32 assembly/contra@25::Invoke(string) + IL_000c: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Func`3 valueTypeExtension() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/valueTypeExtension@37::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action overApplied() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/overApplied@42::Invoke() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs.OptimizeOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs.OptimizeOff.il.bsl new file mode 100644 index 00000000000..ea6c1edee84 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs.OptimizeOff.il.bsl @@ -0,0 +1,361 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto autochar serializable sealed nested assembly beforefieldinit specialname firstClass@7 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler' + .method public specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/firstClass@7::'handler' + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 delegateArg0, int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/firstClass@7::'handler' + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: call !!0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::InvokeFast(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, + !0, + !1) + IL_000d: pop + IL_000e: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname notDirect@12 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public int32 k + .method public specialname rtspecialname instance void .ctor(int32 k) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 assembly/notDirect@12::k + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: add + IL_0003: ldarg.0 + IL_0004: ldfld int32 assembly/notDirect@12::k + IL_0009: add + IL_000a: call void assembly::sink(int32) + IL_000f: nop + IL_0010: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname reordered@15 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler' + .method public specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/reordered@15::'handler' + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/reordered@15::'handler' + IL_0006: ldarg.2 + IL_0007: ldarg.1 + IL_0008: call !!0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::InvokeFast(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, + !0, + !1) + IL_000d: pop + IL_000e: ret + } + + } + + .class auto ansi serializable nested public Holder + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance int32 TakesObj(object x) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname contra@25 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/Holder h + .method public specialname rtspecialname instance void .ctor(class assembly/Holder h) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/Holder assembly/contra@25::h + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance int32 Invoke(string s) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/Holder assembly/contra@25::h + IL_0006: ldarg.1 + IL_0007: callvirt instance int32 assembly/Holder::TakesObj(object) + IL_000c: ret + } + + } + + .class auto ansi serializable nested public Extensions + extends [runtime]System.Object + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static !!T Echo(!!T x, + int32 y, + int32 z) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname valueTypeExtension@37 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.3 + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: call !!0 assembly/Extensions::Echo(!!0, + int32, + int32) + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname overApplied@42 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke() cil managed + { + + .maxstack 6 + .locals init (string V_0) + IL_0000: ldstr "nope" + IL_0005: stloc.0 + IL_0006: ldc.i4.0 + IL_0007: brfalse.s IL_0011 + + IL_0009: ldnull + IL_000a: unbox.any class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 + IL_000f: br.s IL_0018 + + IL_0011: ldloc.0 + IL_0012: call class [runtime]System.Exception [FSharp.Core]Microsoft.FSharp.Core.Operators::Failure(string) + IL_0017: throw + + IL_0018: ldnull + IL_0019: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001e: pop + IL_001f: ret + } + + } + + .method public static class [runtime]System.Action`2 firstClass(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/firstClass@7::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0006: ldftn instance void assembly/firstClass@7::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method private static void sink(int32 x) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 notDirect(int32 k) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/notDirect@12::.ctor(int32) + IL_0006: ldftn instance void assembly/notDirect@12::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Action`2 reordered(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/reordered@15::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0006: ldftn instance void assembly/reordered@15::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Func`2 contra(class assembly/Holder h) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/contra@25::.ctor(class assembly/Holder) + IL_0006: ldftn instance int32 assembly/contra@25::Invoke(string) + IL_000c: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Func`3 valueTypeExtension() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/valueTypeExtension@37::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action overApplied() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/overApplied@42::Invoke() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs.OptimizeOn.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs.OptimizeOn.Preview.il.bsl new file mode 100644 index 00000000000..cadd0be4581 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs.OptimizeOn.Preview.il.bsl @@ -0,0 +1,323 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) + .ver 2:1:0:0 +} +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto autochar serializable sealed nested assembly beforefieldinit specialname firstClass@7 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler' + .method public specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/firstClass@7::'handler' + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 arg1, int32 arg2) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/firstClass@7::'handler' + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: call !!0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::InvokeFast(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, + !0, + !1) + IL_000d: pop + IL_000e: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname notDirect@12 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname reordered@15 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler' + .method public specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/reordered@15::'handler' + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/reordered@15::'handler' + IL_0006: ldarg.2 + IL_0007: ldarg.1 + IL_0008: call !!0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::InvokeFast(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, + !0, + !1) + IL_000d: pop + IL_000e: ret + } + + } + + .class auto ansi serializable nested public Holder + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance int32 TakesObj(object x) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname contra@25 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(string s) cil managed + { + + .maxstack 5 + .locals init (object V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldc.i4.1 + IL_0003: ret + } + + } + + .class auto ansi serializable nested public Extensions + extends [runtime]System.Object + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static !!T Echo(!!T x, + int32 y, + int32 z) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname valueTypeExtension@37 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.3 + IL_0001: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname overApplied@42 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke() cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: brfalse.s IL_000b + + IL_0003: ldnull + IL_0004: unbox.any class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 + IL_0009: br.s IL_0016 + + IL_000b: ldstr "nope" + IL_0010: newobj instance void [netstandard]System.Exception::.ctor(string) + IL_0015: throw + + IL_0016: ldnull + IL_0017: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001c: pop + IL_001d: ret + } + + } + + .method public static class [runtime]System.Action`2 firstClass(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/firstClass@7::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0006: ldftn instance void assembly/firstClass@7::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method private static void sink(int32 x) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 notDirect(int32 k) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/notDirect@12::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 reordered(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/reordered@15::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0006: ldftn instance void assembly/reordered@15::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Func`2 contra(class assembly/Holder h) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/contra@25::Invoke(string) + IL_0007: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`3 valueTypeExtension() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/valueTypeExtension@37::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action overApplied() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/overApplied@42::Invoke() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs.OptimizeOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs.OptimizeOn.il.bsl new file mode 100644 index 00000000000..6f3ed2ddc14 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateNegativeCases.fs.OptimizeOn.il.bsl @@ -0,0 +1,323 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly extern netstandard +{ + .publickeytoken = (CC 7B 13 FF CD 2D DD 51 ) + .ver 2:1:0:0 +} +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto autochar serializable sealed nested assembly beforefieldinit specialname firstClass@7 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler' + .method public specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/firstClass@7::'handler' + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 delegateArg0, int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/firstClass@7::'handler' + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: call !!0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::InvokeFast(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, + !0, + !1) + IL_000d: pop + IL_000e: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname notDirect@12 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname reordered@15 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler' + .method public specialname rtspecialname instance void .ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/reordered@15::'handler' + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 a, int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> assembly/reordered@15::'handler' + IL_0006: ldarg.2 + IL_0007: ldarg.1 + IL_0008: call !!0 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::InvokeFast(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>, + !0, + !1) + IL_000d: pop + IL_000e: ret + } + + } + + .class auto ansi serializable nested public Holder + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance int32 TakesObj(object x) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname contra@25 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(string s) cil managed + { + + .maxstack 5 + .locals init (object V_0) + IL_0000: ldarg.0 + IL_0001: stloc.0 + IL_0002: ldc.i4.1 + IL_0003: ret + } + + } + + .class auto ansi serializable nested public Extensions + extends [runtime]System.Object + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static !!T Echo(!!T x, + int32 y, + int32 z) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.ExtensionAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname valueTypeExtension@37 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.3 + IL_0001: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname overApplied@42 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke() cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: brfalse.s IL_000b + + IL_0003: ldnull + IL_0004: unbox.any class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2 + IL_0009: br.s IL_0016 + + IL_000b: ldstr "nope" + IL_0010: newobj instance void [netstandard]System.Exception::.ctor(string) + IL_0015: throw + + IL_0016: ldnull + IL_0017: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2::Invoke(!0) + IL_001c: pop + IL_001d: ret + } + + } + + .method public static class [runtime]System.Action`2 firstClass(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/firstClass@7::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0006: ldftn instance void assembly/firstClass@7::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method private static void sink(int32 x) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 notDirect(int32 k) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/notDirect@12::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 reordered(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2> 'handler') cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/reordered@15::.ctor(class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2>) + IL_0006: ldftn instance void assembly/reordered@15::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Func`2 contra(class assembly/Holder h) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/contra@25::Invoke(string) + IL_0007: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`3 valueTypeExtension() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/valueTypeExtension@37::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action overApplied() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/overApplied@42::Invoke() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs new file mode 100644 index 00000000000..a77f70c8adb --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs @@ -0,0 +1,32 @@ +module DelegatePartialApplication + +open System + +// Cases 37/38 (in DelegateKnownFunction.fs / DelegateStaticMethod.fs) capture a +// constant first argument, so their closure can stay static (the constant is re-materialised in Invoke +// with no instance field). Capturing a runtime VALUE instead forces the closure to carry an instance +// field, which exercises a distinct emit path. None of the cases below can become a direct delegate: +// - The CLR's closed delegate binds exactly ONE leading value as the Target. papInstanceVar fixes two +// leading values (the receiver 'o' and the argument 'n'), so there is no closed form. +// - papKnownVar / papStaticVar fix a single leading value, but it is an 'int'. The closed-delegate thunk +// passes the Target (an 'object') straight into the method's first parameter with NO unboxing, so a +// value-type first parameter has no closed form at all (the same reason a value-type receiver is +// excluded). A reference-type fixed argument, by contrast, IS emitted directly (see the execution test +// `Reference-type single-argument partial application is direct`). + +let handler3 (x: int) (y: int) (z: int) : unit = () + +type C = + static member Add3 (x: int) (y: int) (z: int) : unit = () + +type I(k: int) = + member _.Add3 (x: int) (y: int) (z: int) : unit = ignore k + +// 39. partial application of module function (captured var: instance-field capture of n) +let papKnownVar (n: int) = Action(handler3 n) + +// 40. partial application of static method (captured var) +let papStaticVar (n: int) = Action(C.Add3 n) + +// 41. partial application of instance method (captures both the receiver and n) +let papInstanceVar (o: I) (n: int) = Action(o.Add3 n) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs.OptimizeOff.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs.OptimizeOff.Preview.il.bsl new file mode 100644 index 00000000000..64b30067a6b --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs.OptimizeOff.Preview.il.bsl @@ -0,0 +1,270 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static void Add3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + } + + .class auto ansi serializable nested public I + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .field assembly int32 k + .method public specialname rtspecialname instance void .ctor(int32 k) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld int32 assembly/I::k + IL_000f: ret + } + + .method public hidebysig instance void + Add3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 3 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldfld int32 assembly/I::k + IL_0006: stloc.0 + IL_0007: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname papKnownVar@26 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public int32 n + .method public specialname rtspecialname instance void .ctor(int32 n) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 assembly/papKnownVar@26::n + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 arg1, int32 arg2) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 assembly/papKnownVar@26::n + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: call void assembly::handler3(int32, + int32, + int32) + IL_000d: nop + IL_000e: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname papStaticVar@29 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public int32 n + .method public specialname rtspecialname instance void .ctor(int32 n) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 assembly/papStaticVar@29::n + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 arg1, int32 arg2) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 assembly/papStaticVar@29::n + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: call void assembly/C::Add3(int32, + int32, + int32) + IL_000d: nop + IL_000e: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname papInstanceVar@32 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/I o + .field public int32 n + .method public specialname rtspecialname instance void .ctor(class assembly/I o, int32 n) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/I assembly/papInstanceVar@32::o + IL_0007: ldarg.0 + IL_0008: ldarg.2 + IL_0009: stfld int32 assembly/papInstanceVar@32::n + IL_000e: ldarg.0 + IL_000f: call instance void [runtime]System.Object::.ctor() + IL_0014: ret + } + + .method assembly hidebysig instance void Invoke(int32 arg1, int32 arg2) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/I assembly/papInstanceVar@32::o + IL_0006: ldarg.0 + IL_0007: ldfld int32 assembly/papInstanceVar@32::n + IL_000c: ldarg.1 + IL_000d: ldarg.2 + IL_000e: callvirt instance void assembly/I::Add3(int32, + int32, + int32) + IL_0013: nop + IL_0014: ret + } + + } + + .method public static void handler3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 papKnownVar(int32 n) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/papKnownVar@26::.ctor(int32) + IL_0006: ldftn instance void assembly/papKnownVar@26::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Action`2 papStaticVar(int32 n) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/papStaticVar@29::.ctor(int32) + IL_0006: ldftn instance void assembly/papStaticVar@29::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Action`2 papInstanceVar(class assembly/I o, int32 n) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: newobj instance void assembly/papInstanceVar@32::.ctor(class assembly/I, + int32) + IL_0007: ldftn instance void assembly/papInstanceVar@32::Invoke(int32, + int32) + IL_000d: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0012: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs.OptimizeOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs.OptimizeOff.il.bsl new file mode 100644 index 00000000000..d8ecbf83e0c --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs.OptimizeOff.il.bsl @@ -0,0 +1,270 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static void Add3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + } + + .class auto ansi serializable nested public I + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .field assembly int32 k + .method public specialname rtspecialname instance void .ctor(int32 k) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld int32 assembly/I::k + IL_000f: ret + } + + .method public hidebysig instance void + Add3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 3 + .locals init (int32 V_0) + IL_0000: ldarg.0 + IL_0001: ldfld int32 assembly/I::k + IL_0006: stloc.0 + IL_0007: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname papKnownVar@26 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public int32 n + .method public specialname rtspecialname instance void .ctor(int32 n) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 assembly/papKnownVar@26::n + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 delegateArg0, int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 assembly/papKnownVar@26::n + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: call void assembly::handler3(int32, + int32, + int32) + IL_000d: nop + IL_000e: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname papStaticVar@29 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public int32 n + .method public specialname rtspecialname instance void .ctor(int32 n) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld int32 assembly/papStaticVar@29::n + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke(int32 delegateArg0, int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld int32 assembly/papStaticVar@29::n + IL_0006: ldarg.1 + IL_0007: ldarg.2 + IL_0008: call void assembly/C::Add3(int32, + int32, + int32) + IL_000d: nop + IL_000e: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname papInstanceVar@32 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/I o + .field public int32 n + .method public specialname rtspecialname instance void .ctor(class assembly/I o, int32 n) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/I assembly/papInstanceVar@32::o + IL_0007: ldarg.0 + IL_0008: ldarg.2 + IL_0009: stfld int32 assembly/papInstanceVar@32::n + IL_000e: ldarg.0 + IL_000f: call instance void [runtime]System.Object::.ctor() + IL_0014: ret + } + + .method assembly hidebysig instance void Invoke(int32 delegateArg0, int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/I assembly/papInstanceVar@32::o + IL_0006: ldarg.0 + IL_0007: ldfld int32 assembly/papInstanceVar@32::n + IL_000c: ldarg.1 + IL_000d: ldarg.2 + IL_000e: callvirt instance void assembly/I::Add3(int32, + int32, + int32) + IL_0013: nop + IL_0014: ret + } + + } + + .method public static void handler3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 papKnownVar(int32 n) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/papKnownVar@26::.ctor(int32) + IL_0006: ldftn instance void assembly/papKnownVar@26::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Action`2 papStaticVar(int32 n) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/papStaticVar@29::.ctor(int32) + IL_0006: ldftn instance void assembly/papStaticVar@29::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Action`2 papInstanceVar(class assembly/I o, int32 n) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: newobj instance void assembly/papInstanceVar@32::.ctor(class assembly/I, + int32) + IL_0007: ldftn instance void assembly/papInstanceVar@32::Invoke(int32, + int32) + IL_000d: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_0012: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs.OptimizeOn.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs.OptimizeOn.Preview.il.bsl new file mode 100644 index 00000000000..bfbde14b661 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs.OptimizeOn.Preview.il.bsl @@ -0,0 +1,195 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static void Add3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + } + + .class auto ansi serializable nested public I + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .field assembly int32 k + .method public specialname rtspecialname instance void .ctor(int32 k) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld int32 assembly/I::k + IL_000f: ret + } + + .method public hidebysig instance void + Add3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname papKnownVar@26 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 arg1, + int32 arg2) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname papStaticVar@29 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 arg1, + int32 arg2) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname papInstanceVar@32 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 arg1, + int32 arg2) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .method public static void handler3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 papKnownVar(int32 n) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/papKnownVar@26::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 papStaticVar(int32 n) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/papStaticVar@29::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 papInstanceVar(class assembly/I o, int32 n) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/papInstanceVar@32::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs.OptimizeOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs.OptimizeOn.il.bsl new file mode 100644 index 00000000000..4c748f45b02 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegatePartialApplication.fs.OptimizeOn.il.bsl @@ -0,0 +1,195 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static void Add3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + } + + .class auto ansi serializable nested public I + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .field assembly int32 k + .method public specialname rtspecialname instance void .ctor(int32 k) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ldarg.0 + IL_0009: ldarg.1 + IL_000a: stfld int32 assembly/I::k + IL_000f: ret + } + + .method public hidebysig instance void + Add3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname papKnownVar@26 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 delegateArg0, + int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname papStaticVar@29 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 delegateArg0, + int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname papInstanceVar@32 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 delegateArg0, + int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .method public static void handler3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 papKnownVar(int32 n) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/papKnownVar@26::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 papStaticVar(int32 n) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/papStaticVar@29::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 papInstanceVar(class assembly/I o, int32 n) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/papInstanceVar@32::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs new file mode 100644 index 00000000000..a78c9c97dac --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs @@ -0,0 +1,21 @@ +module DelegateStaticMethod + +open System + +type C = + static member AddC (x: int) (y: int) : unit = () + static member AddT (x: int, y: int) : unit = () + static member Add3 (x: int) (y: int) (z: int) : unit = () + +// 18. non-eta static method +// (a tupled member is seen as a single tuple-arg value and will not coerce non-eta; use the curried member) +let case18_nonEta () = Action(C.AddC) + +// 2. eta static method (curried application) +let case2_etaCurried () = Action(fun a b -> C.AddC a b) + +// 32. eta static method, tupled application +let case32_etaTupled () = Action(fun a b -> C.AddT(a, b)) + +// 38. partial application of static method (constant arg) +let case38_partial () = Action(C.Add3 1) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs.OptimizeOff.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs.OptimizeOff.Preview.il.bsl new file mode 100644 index 00000000000..35c6be20bc0 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs.OptimizeOff.Preview.il.bsl @@ -0,0 +1,196 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static void AddC(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static void AddT(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static void Add3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case2_etaCurried@15 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void assembly/C::AddC(int32, + int32) + IL_0007: nop + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case32_etaTupled@18 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void assembly/C::AddT(int32, + int32) + IL_0007: nop + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case38_partial@21 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 arg1, + int32 arg2) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: call void assembly/C::Add3(int32, + int32, + int32) + IL_0008: nop + IL_0009: ret + } + + } + + .method public static class [runtime]System.Action`2 case18_nonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/C::AddC(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case2_etaCurried() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case2_etaCurried@15::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case32_etaTupled() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case32_etaTupled@18::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case38_partial() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case38_partial@21::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs.OptimizeOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs.OptimizeOff.il.bsl new file mode 100644 index 00000000000..ce68901f780 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs.OptimizeOff.il.bsl @@ -0,0 +1,215 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static void AddC(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static void AddT(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static void Add3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case18_nonEta@12 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void assembly/C::AddC(int32, + int32) + IL_0007: nop + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case2_etaCurried@15 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void assembly/C::AddC(int32, + int32) + IL_0007: nop + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case32_etaTupled@18 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void assembly/C::AddT(int32, + int32) + IL_0007: nop + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case38_partial@21 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 delegateArg0, + int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ldarg.0 + IL_0002: ldarg.1 + IL_0003: call void assembly/C::Add3(int32, + int32, + int32) + IL_0008: nop + IL_0009: ret + } + + } + + .method public static class [runtime]System.Action`2 case18_nonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case18_nonEta@12::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case2_etaCurried() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case2_etaCurried@15::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case32_etaTupled() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case32_etaTupled@18::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case38_partial() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case38_partial@21::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs.OptimizeOn.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs.OptimizeOn.Preview.il.bsl new file mode 100644 index 00000000000..8fa5fc34989 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs.OptimizeOn.Preview.il.bsl @@ -0,0 +1,151 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static void AddC(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static void AddT(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static void Add3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case38_partial@21 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 arg1, + int32 arg2) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .method public static class [runtime]System.Action`2 case18_nonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/C::AddC(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case2_etaCurried() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/C::AddC(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case32_etaTupled() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/C::AddT(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case38_partial() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case38_partial@21::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs.OptimizeOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs.OptimizeOn.il.bsl new file mode 100644 index 00000000000..1de6bfcc577 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStaticMethod.fs.OptimizeOn.il.bsl @@ -0,0 +1,193 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static void AddC(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static void AddT(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static void Add3(int32 x, + int32 y, + int32 z) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 03 00 00 00 01 00 00 00 01 00 00 00 01 00 + 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case18_nonEta@12 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case2_etaCurried@15 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case32_etaTupled@18 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname case38_partial@21 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 delegateArg0, + int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .method public static class [runtime]System.Action`2 case18_nonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case18_nonEta@12::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case2_etaCurried() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case2_etaCurried@15::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case32_etaTupled() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case32_etaTupled@18::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 case38_partial() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/case38_partial@21::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs new file mode 100644 index 00000000000..7bed97158ec --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs @@ -0,0 +1,16 @@ +module DelegateStructTarget + +open System + +[] +type S = + member _.Add (x: int) (y: int) : int = x + y + +// The target is an instance method on a value type. A delegate's Target is an 'object', so the receiver is +// boxed (a copy) at the construction site and the runtime binds the unboxing stub; this matches the closure +// form, which also captures the struct by value. (See DelegateInstanceMethod for the reference-type case.) +// 50. non-eta struct (value-type) receiver +let structInstanceNonEta (s: S) = Func(s.Add) + +// 51. eta struct (value-type) receiver +let structInstanceEta (s: S) = Func(fun a b -> s.Add a b) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs.OptimizeOff.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs.OptimizeOff.Preview.il.bsl new file mode 100644 index 00000000000..5b9ce3e8a8d --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs.OptimizeOff.Preview.il.bsl @@ -0,0 +1,281 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class sequential ansi serializable sealed nested public S + extends [runtime]System.ValueType + implements class [runtime]System.IEquatable`1, + [runtime]System.Collections.IStructuralEquatable, + class [runtime]System.IComparable`1, + [runtime]System.IComparable, + [runtime]System.Collections.IStructuralComparable + { + .pack 0 + .size 1 + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.StructAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig virtual final instance int32 CompareTo(valuetype assembly/S obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S& V_0) + IL_0000: ldarga.s obj + IL_0002: stloc.0 + IL_0003: ldc.i4.0 + IL_0004: ret + } + + .method public hidebysig virtual final instance int32 CompareTo(object obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: unbox.any assembly/S + IL_0007: call instance int32 assembly/S::CompareTo(valuetype assembly/S) + IL_000c: ret + } + + .method public hidebysig virtual final instance int32 CompareTo(object obj, class [runtime]System.Collections.IComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S V_0, + valuetype assembly/S& V_1) + IL_0000: ldarg.1 + IL_0001: unbox.any assembly/S + IL_0006: stloc.0 + IL_0007: ldloca.s V_0 + IL_0009: stloc.1 + IL_000a: ldc.i4.0 + IL_000b: ret + } + + .method public hidebysig virtual final instance int32 GetHashCode(class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } + + .method public hidebysig virtual final instance int32 GetHashCode() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call class [runtime]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: call instance int32 assembly/S::GetHashCode(class [runtime]System.Collections.IEqualityComparer) + IL_000b: ret + } + + .method public hidebysig instance bool Equals(valuetype assembly/S obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S& V_0) + IL_0000: ldarga.s obj + IL_0002: stloc.0 + IL_0003: ldc.i4.1 + IL_0004: ret + } + + .method public hidebysig virtual final instance bool Equals(object obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 5 + .locals init (object V_0, + valuetype assembly/S V_1) + IL_0000: ldarg.1 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: isinst assembly/S + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_001d + + IL_000d: ldarg.1 + IL_000e: unbox.any assembly/S + IL_0013: stloc.1 + IL_0014: ldarg.0 + IL_0015: ldloc.1 + IL_0016: ldarg.2 + IL_0017: call instance bool assembly/S::Equals(valuetype assembly/S, + class [runtime]System.Collections.IEqualityComparer) + IL_001c: ret + + IL_001d: ldc.i4.0 + IL_001e: ret + } + + .method public hidebysig instance int32 Add(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: add + IL_0003: ret + } + + .method public hidebysig virtual final instance bool Equals(valuetype assembly/S obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S& V_0) + IL_0000: ldarga.s obj + IL_0002: stloc.0 + IL_0003: ldc.i4.1 + IL_0004: ret + } + + .method public hidebysig virtual final instance bool Equals(object obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 4 + .locals init (object V_0, + valuetype assembly/S V_1) + IL_0000: ldarg.1 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: isinst assembly/S + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_001c + + IL_000d: ldarg.1 + IL_000e: unbox.any assembly/S + IL_0013: stloc.1 + IL_0014: ldarg.0 + IL_0015: ldloc.1 + IL_0016: call instance bool assembly/S::Equals(valuetype assembly/S) + IL_001b: ret + + IL_001c: ldc.i4.0 + IL_001d: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname structInstanceEta@16 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public valuetype assembly/S s + .method public specialname rtspecialname instance void .ctor(valuetype assembly/S s) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype assembly/S assembly/structInstanceEta@16::s + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance int32 Invoke(int32 a, int32 b) cil managed + { + + .maxstack 7 + .locals init (valuetype assembly/S V_0) + IL_0000: ldarg.0 + IL_0001: ldfld valuetype assembly/S assembly/structInstanceEta@16::s + IL_0006: stloc.0 + IL_0007: ldloca.s V_0 + IL_0009: ldarg.1 + IL_000a: ldarg.2 + IL_000b: call instance int32 assembly/S::Add(int32, + int32) + IL_0010: ret + } + + } + + .method public static class [runtime]System.Func`3 structInstanceNonEta(valuetype assembly/S s) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: box assembly/S + IL_0006: ldftn instance int32 assembly/S::Add(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Func`3 structInstanceEta(valuetype assembly/S s) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/structInstanceEta@16::.ctor(valuetype assembly/S) + IL_0006: ldftn instance int32 assembly/structInstanceEta@16::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_0011: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs.OptimizeOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs.OptimizeOff.il.bsl new file mode 100644 index 00000000000..474c9e2b6ad --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs.OptimizeOff.il.bsl @@ -0,0 +1,316 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class sequential ansi serializable sealed nested public S + extends [runtime]System.ValueType + implements class [runtime]System.IEquatable`1, + [runtime]System.Collections.IStructuralEquatable, + class [runtime]System.IComparable`1, + [runtime]System.IComparable, + [runtime]System.Collections.IStructuralComparable + { + .pack 0 + .size 1 + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.StructAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig virtual final instance int32 CompareTo(valuetype assembly/S obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S& V_0) + IL_0000: ldarga.s obj + IL_0002: stloc.0 + IL_0003: ldc.i4.0 + IL_0004: ret + } + + .method public hidebysig virtual final instance int32 CompareTo(object obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: unbox.any assembly/S + IL_0007: call instance int32 assembly/S::CompareTo(valuetype assembly/S) + IL_000c: ret + } + + .method public hidebysig virtual final instance int32 CompareTo(object obj, class [runtime]System.Collections.IComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S V_0, + valuetype assembly/S& V_1) + IL_0000: ldarg.1 + IL_0001: unbox.any assembly/S + IL_0006: stloc.0 + IL_0007: ldloca.s V_0 + IL_0009: stloc.1 + IL_000a: ldc.i4.0 + IL_000b: ret + } + + .method public hidebysig virtual final instance int32 GetHashCode(class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } + + .method public hidebysig virtual final instance int32 GetHashCode() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call class [runtime]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: call instance int32 assembly/S::GetHashCode(class [runtime]System.Collections.IEqualityComparer) + IL_000b: ret + } + + .method public hidebysig instance bool Equals(valuetype assembly/S obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S& V_0) + IL_0000: ldarga.s obj + IL_0002: stloc.0 + IL_0003: ldc.i4.1 + IL_0004: ret + } + + .method public hidebysig virtual final instance bool Equals(object obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 5 + .locals init (object V_0, + valuetype assembly/S V_1) + IL_0000: ldarg.1 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: isinst assembly/S + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_001d + + IL_000d: ldarg.1 + IL_000e: unbox.any assembly/S + IL_0013: stloc.1 + IL_0014: ldarg.0 + IL_0015: ldloc.1 + IL_0016: ldarg.2 + IL_0017: call instance bool assembly/S::Equals(valuetype assembly/S, + class [runtime]System.Collections.IEqualityComparer) + IL_001c: ret + + IL_001d: ldc.i4.0 + IL_001e: ret + } + + .method public hidebysig instance int32 Add(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: add + IL_0003: ret + } + + .method public hidebysig virtual final instance bool Equals(valuetype assembly/S obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S& V_0) + IL_0000: ldarga.s obj + IL_0002: stloc.0 + IL_0003: ldc.i4.1 + IL_0004: ret + } + + .method public hidebysig virtual final instance bool Equals(object obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 4 + .locals init (object V_0, + valuetype assembly/S V_1) + IL_0000: ldarg.1 + IL_0001: stloc.0 + IL_0002: ldloc.0 + IL_0003: isinst assembly/S + IL_0008: ldnull + IL_0009: cgt.un + IL_000b: brfalse.s IL_001c + + IL_000d: ldarg.1 + IL_000e: unbox.any assembly/S + IL_0013: stloc.1 + IL_0014: ldarg.0 + IL_0015: ldloc.1 + IL_0016: call instance bool assembly/S::Equals(valuetype assembly/S) + IL_001b: ret + + IL_001c: ldc.i4.0 + IL_001d: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname structInstanceNonEta@13 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public valuetype assembly/S s + .method public specialname rtspecialname instance void .ctor(valuetype assembly/S s) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype assembly/S assembly/structInstanceNonEta@13::s + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance int32 Invoke(int32 delegateArg0, int32 delegateArg1) cil managed + { + + .maxstack 7 + .locals init (valuetype assembly/S V_0) + IL_0000: ldarg.0 + IL_0001: ldfld valuetype assembly/S assembly/structInstanceNonEta@13::s + IL_0006: stloc.0 + IL_0007: ldloca.s V_0 + IL_0009: ldarg.1 + IL_000a: ldarg.2 + IL_000b: call instance int32 assembly/S::Add(int32, + int32) + IL_0010: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname structInstanceEta@16 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public valuetype assembly/S s + .method public specialname rtspecialname instance void .ctor(valuetype assembly/S s) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld valuetype assembly/S assembly/structInstanceEta@16::s + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance int32 Invoke(int32 a, int32 b) cil managed + { + + .maxstack 7 + .locals init (valuetype assembly/S V_0) + IL_0000: ldarg.0 + IL_0001: ldfld valuetype assembly/S assembly/structInstanceEta@16::s + IL_0006: stloc.0 + IL_0007: ldloca.s V_0 + IL_0009: ldarg.1 + IL_000a: ldarg.2 + IL_000b: call instance int32 assembly/S::Add(int32, + int32) + IL_0010: ret + } + + } + + .method public static class [runtime]System.Func`3 structInstanceNonEta(valuetype assembly/S s) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/structInstanceNonEta@13::.ctor(valuetype assembly/S) + IL_0006: ldftn instance int32 assembly/structInstanceNonEta@13::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Func`3 structInstanceEta(valuetype assembly/S s) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/structInstanceEta@16::.ctor(valuetype assembly/S) + IL_0006: ldftn instance int32 assembly/structInstanceEta@16::Invoke(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_0011: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs.OptimizeOn.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs.OptimizeOn.Preview.il.bsl new file mode 100644 index 00000000000..72cbb30bc84 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs.OptimizeOn.Preview.il.bsl @@ -0,0 +1,219 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class sequential ansi serializable sealed nested public S + extends [runtime]System.ValueType + implements class [runtime]System.IEquatable`1, + [runtime]System.Collections.IStructuralEquatable, + class [runtime]System.IComparable`1, + [runtime]System.IComparable, + [runtime]System.Collections.IStructuralComparable + { + .pack 0 + .size 1 + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.StructAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig virtual final instance int32 CompareTo(valuetype assembly/S obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } + + .method public hidebysig virtual final instance int32 CompareTo(object obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S V_0) + IL_0000: ldarg.1 + IL_0001: unbox.any assembly/S + IL_0006: stloc.0 + IL_0007: ldc.i4.0 + IL_0008: ret + } + + .method public hidebysig virtual final instance int32 CompareTo(object obj, class [runtime]System.Collections.IComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S V_0) + IL_0000: ldarg.1 + IL_0001: unbox.any assembly/S + IL_0006: stloc.0 + IL_0007: ldc.i4.0 + IL_0008: ret + } + + .method public hidebysig virtual final instance int32 GetHashCode(class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } + + .method public hidebysig virtual final instance int32 GetHashCode() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call class [runtime]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: call instance int32 assembly/S::GetHashCode(class [runtime]System.Collections.IEqualityComparer) + IL_000b: ret + } + + .method public hidebysig instance bool Equals(valuetype assembly/S obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } + + .method public hidebysig virtual final instance bool Equals(object obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S V_0) + IL_0000: ldarg.1 + IL_0001: isinst assembly/S + IL_0006: brfalse.s IL_0011 + + IL_0008: ldarg.1 + IL_0009: unbox.any assembly/S + IL_000e: stloc.0 + IL_000f: ldc.i4.1 + IL_0010: ret + + IL_0011: ldc.i4.0 + IL_0012: ret + } + + .method public hidebysig instance int32 Add(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: add + IL_0003: ret + } + + .method public hidebysig virtual final instance bool Equals(valuetype assembly/S obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } + + .method public hidebysig virtual final instance bool Equals(object obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S V_0) + IL_0000: ldarg.1 + IL_0001: isinst assembly/S + IL_0006: brfalse.s IL_0011 + + IL_0008: ldarg.1 + IL_0009: unbox.any assembly/S + IL_000e: stloc.0 + IL_000f: ldc.i4.1 + IL_0010: ret + + IL_0011: ldc.i4.0 + IL_0012: ret + } + + } + + .method public static class [runtime]System.Func`3 structInstanceNonEta(valuetype assembly/S s) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: box assembly/S + IL_0006: ldftn instance int32 assembly/S::Add(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Func`3 structInstanceEta(valuetype assembly/S s) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: box assembly/S + IL_0006: ldftn instance int32 assembly/S::Add(int32, + int32) + IL_000c: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_0011: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs.OptimizeOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs.OptimizeOn.il.bsl new file mode 100644 index 00000000000..c00b5018301 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateStructTarget.fs.OptimizeOn.il.bsl @@ -0,0 +1,251 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class sequential ansi serializable sealed nested public S + extends [runtime]System.ValueType + implements class [runtime]System.IEquatable`1, + [runtime]System.Collections.IStructuralEquatable, + class [runtime]System.IComparable`1, + [runtime]System.IComparable, + [runtime]System.Collections.IStructuralComparable + { + .pack 0 + .size 1 + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.StructAttribute::.ctor() = ( 01 00 00 00 ) + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public hidebysig virtual final instance int32 CompareTo(valuetype assembly/S obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } + + .method public hidebysig virtual final instance int32 CompareTo(object obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S V_0) + IL_0000: ldarg.1 + IL_0001: unbox.any assembly/S + IL_0006: stloc.0 + IL_0007: ldc.i4.0 + IL_0008: ret + } + + .method public hidebysig virtual final instance int32 CompareTo(object obj, class [runtime]System.Collections.IComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S V_0) + IL_0000: ldarg.1 + IL_0001: unbox.any assembly/S + IL_0006: stloc.0 + IL_0007: ldc.i4.0 + IL_0008: ret + } + + .method public hidebysig virtual final instance int32 GetHashCode(class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.0 + IL_0001: ret + } + + .method public hidebysig virtual final instance int32 GetHashCode() cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call class [runtime]System.Collections.IEqualityComparer [FSharp.Core]Microsoft.FSharp.Core.LanguagePrimitives::get_GenericEqualityComparer() + IL_0006: call instance int32 assembly/S::GetHashCode(class [runtime]System.Collections.IEqualityComparer) + IL_000b: ret + } + + .method public hidebysig instance bool Equals(valuetype assembly/S obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } + + .method public hidebysig virtual final instance bool Equals(object obj, class [runtime]System.Collections.IEqualityComparer comp) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S V_0) + IL_0000: ldarg.1 + IL_0001: isinst assembly/S + IL_0006: brfalse.s IL_0011 + + IL_0008: ldarg.1 + IL_0009: unbox.any assembly/S + IL_000e: stloc.0 + IL_000f: ldc.i4.1 + IL_0010: ret + + IL_0011: ldc.i4.0 + IL_0012: ret + } + + .method public hidebysig instance int32 Add(int32 x, int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ldarg.1 + IL_0001: ldarg.2 + IL_0002: add + IL_0003: ret + } + + .method public hidebysig virtual final instance bool Equals(valuetype assembly/S obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 8 + IL_0000: ldc.i4.1 + IL_0001: ret + } + + .method public hidebysig virtual final instance bool Equals(object obj) cil managed + { + .custom instance void [runtime]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 ) + + .maxstack 3 + .locals init (valuetype assembly/S V_0) + IL_0000: ldarg.1 + IL_0001: isinst assembly/S + IL_0006: brfalse.s IL_0011 + + IL_0008: ldarg.1 + IL_0009: unbox.any assembly/S + IL_000e: stloc.0 + IL_000f: ldc.i4.1 + IL_0010: ret + + IL_0011: ldc.i4.0 + IL_0012: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname structInstanceNonEta@13 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 delegateArg0, + int32 delegateArg1) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: add + IL_0003: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname structInstanceEta@16 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static int32 Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: add + IL_0003: ret + } + + } + + .method public static class [runtime]System.Func`3 structInstanceNonEta(valuetype assembly/S s) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/structInstanceNonEta@13::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`3 structInstanceEta(valuetype assembly/S s) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn int32 assembly/structInstanceEta@16::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Func`3::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs new file mode 100644 index 00000000000..27c5b27b332 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs @@ -0,0 +1,20 @@ +module DelegateUnitArg + +open System + +let handler () : unit = () + +type C() = + member _.M () : unit = () + +// 46. non-eta unit-argument delegate +let caseUnitNonEta () = Action(handler) + +// 47. eta unit-argument delegate +let caseUnitEta () = Action(fun () -> handler ()) + +// 48. non-eta unit-argument delegate, instance method (receiver kept, unit stripped) +let caseUnitInstanceNonEta (c: C) = Action(c.M) + +// 49. eta unit-argument delegate, instance method +let caseUnitInstanceEta (c: C) = Action(fun () -> c.M ()) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs.OptimizeOff.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs.OptimizeOff.Preview.il.bsl new file mode 100644 index 00000000000..a6ffdf256a7 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs.OptimizeOff.Preview.il.bsl @@ -0,0 +1,176 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance void M() cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname caseUnitEta@14 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke() cil managed + { + + .maxstack 8 + IL_0000: call void assembly::'handler'() + IL_0005: nop + IL_0006: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname caseUnitInstanceEta@20 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C c + .method public specialname rtspecialname instance void .ctor(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/caseUnitInstanceEta@20::c + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/caseUnitInstanceEta@20::c + IL_0006: callvirt instance void assembly/C::M() + IL_000b: nop + IL_000c: ret + } + + } + + .method public static void 'handler'() cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action caseUnitNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly::'handler'() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action caseUnitEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/caseUnitEta@14::Invoke() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action caseUnitInstanceNonEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldftn instance void assembly/C::M() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action caseUnitInstanceEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/caseUnitInstanceEta@20::.ctor(class assembly/C) + IL_0006: ldftn instance void assembly/caseUnitInstanceEta@20::Invoke() + IL_000c: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_0011: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs.OptimizeOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs.OptimizeOff.il.bsl new file mode 100644 index 00000000000..da567add265 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs.OptimizeOff.il.bsl @@ -0,0 +1,225 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance void M() cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname caseUnitNonEta@11 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke() cil managed + { + + .maxstack 8 + IL_0000: call void assembly::'handler'() + IL_0005: nop + IL_0006: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname caseUnitEta@14 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke() cil managed + { + + .maxstack 8 + IL_0000: call void assembly::'handler'() + IL_0005: nop + IL_0006: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname caseUnitInstanceNonEta@17 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C c + .method public specialname rtspecialname instance void .ctor(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/caseUnitInstanceNonEta@17::c + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke() cil managed + { + + .maxstack 5 + .locals init (class assembly/C V_0) + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/caseUnitInstanceNonEta@17::c + IL_0006: stloc.0 + IL_0007: ldloc.0 + IL_0008: callvirt instance void assembly/C::M() + IL_000d: nop + IL_000e: ret + } + + } + + .class auto autochar serializable sealed nested assembly beforefieldinit specialname caseUnitInstanceEta@20 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .field public class assembly/C c + .method public specialname rtspecialname instance void .ctor(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: stfld class assembly/C assembly/caseUnitInstanceEta@20::c + IL_0007: ldarg.0 + IL_0008: call instance void [runtime]System.Object::.ctor() + IL_000d: ret + } + + .method assembly hidebysig instance void Invoke() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldfld class assembly/C assembly/caseUnitInstanceEta@20::c + IL_0006: callvirt instance void assembly/C::M() + IL_000b: nop + IL_000c: ret + } + + } + + .method public static void 'handler'() cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action caseUnitNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/caseUnitNonEta@11::Invoke() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action caseUnitEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/caseUnitEta@14::Invoke() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action caseUnitInstanceNonEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/caseUnitInstanceNonEta@17::.ctor(class assembly/C) + IL_0006: ldftn instance void assembly/caseUnitInstanceNonEta@17::Invoke() + IL_000c: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_0011: ret + } + + .method public static class [runtime]System.Action caseUnitInstanceEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: newobj instance void assembly/caseUnitInstanceEta@20::.ctor(class assembly/C) + IL_0006: ldftn instance void assembly/caseUnitInstanceEta@20::Invoke() + IL_000c: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_0011: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs.OptimizeOn.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs.OptimizeOn.Preview.il.bsl new file mode 100644 index 00000000000..2c12314501a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs.OptimizeOn.Preview.il.bsl @@ -0,0 +1,130 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance void M() cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .method public static void 'handler'() cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action caseUnitNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly::'handler'() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action caseUnitEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly::'handler'() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action caseUnitInstanceNonEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldftn instance void assembly/C::M() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action caseUnitInstanceEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldftn instance void assembly/C::M() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs.OptimizeOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs.OptimizeOn.il.bsl new file mode 100644 index 00000000000..9746aa37757 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitArg.fs.OptimizeOn.il.bsl @@ -0,0 +1,182 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public specialname rtspecialname instance void .ctor() cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: callvirt instance void [runtime]System.Object::.ctor() + IL_0006: ldarg.0 + IL_0007: pop + IL_0008: ret + } + + .method public hidebysig instance void M() cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname caseUnitNonEta@11 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke() cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname caseUnitEta@14 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke() cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname caseUnitInstanceNonEta@17 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke() cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname caseUnitInstanceEta@20 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke() cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .method public static void 'handler'() cil managed + { + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action caseUnitNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/caseUnitNonEta@11::Invoke() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action caseUnitEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/caseUnitEta@14::Invoke() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action caseUnitInstanceNonEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/caseUnitInstanceNonEta@17::Invoke() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action caseUnitInstanceEta(class assembly/C c) cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/caseUnitInstanceEta@20::Invoke() + IL_0007: newobj instance void [runtime]System.Action::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs new file mode 100644 index 00000000000..ba6da87996a --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs @@ -0,0 +1,25 @@ +module DelegateUnitReturn + +open System + +// Target returns unit, compiled to void; delegate (Action) returns void. +let returnsUnit (x: int) (y: int) : unit = () + +// 26. non-eta unit-returning member (compiled to void) +let voidNonEta () = Action(returnsUnit) + +// 10. eta unit-returning member +let voidEta () = Action(fun a b -> returnsUnit a b) + +type C = + // Generic method returning its own type variable; instantiated to unit below. The compiled method + // returns the type variable (System.Unit once instantiated), not void - a distinct case from the + // void-returning member above. + static member Echo<'T>(x: 'T) : 'T = x + +// Generic return type variable instantiated to unit; the delegate likewise returns unit. +// 27. non-eta generic return tyvar instantiated to unit (compiled return is Unit, not void) +let unitGenericReturnNonEta () = Func(C.Echo) + +// 11. eta generic unit-returning method +let unitGenericReturnEta () = Func(fun (x: unit) -> C.Echo x) diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs.OptimizeOff.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs.OptimizeOff.Preview.il.bsl new file mode 100644 index 00000000000..2f1068b4215 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs.OptimizeOff.Preview.il.bsl @@ -0,0 +1,158 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname voidEta@12 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void assembly::returnsUnit(int32, + int32) + IL_0007: nop + IL_0008: ret + } + + } + + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static !!T Echo(!!T x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname unitGenericReturnEta@25 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static class [FSharp.Core]Microsoft.FSharp.Core.Unit Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call !!0 assembly/C::Echo(!!0) + IL_0006: ret + } + + } + + .method public static void returnsUnit(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 voidNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly::returnsUnit(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 voidEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/voidEta@12::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`2 unitGenericReturnNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn !!0 assembly/C::Echo(!!0) + IL_0007: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`2 unitGenericReturnEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn class [FSharp.Core]Microsoft.FSharp.Core.Unit assembly/unitGenericReturnEta@25::Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit) + IL_0007: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs.OptimizeOff.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs.OptimizeOff.il.bsl new file mode 100644 index 00000000000..69a6b147055 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs.OptimizeOff.il.bsl @@ -0,0 +1,192 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname voidNonEta@9 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void assembly::returnsUnit(int32, + int32) + IL_0007: nop + IL_0008: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname voidEta@12 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ldarg.1 + IL_0002: call void assembly::returnsUnit(int32, + int32) + IL_0007: nop + IL_0008: ret + } + + } + + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static !!T Echo(!!T x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname unitGenericReturnNonEta@22 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static class [FSharp.Core]Microsoft.FSharp.Core.Unit Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call !!0 assembly/C::Echo(!!0) + IL_0006: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname unitGenericReturnEta@25 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static class [FSharp.Core]Microsoft.FSharp.Core.Unit Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: call !!0 assembly/C::Echo(!!0) + IL_0006: ret + } + + } + + .method public static void returnsUnit(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 voidNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/voidNonEta@9::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 voidEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/voidEta@12::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`2 unitGenericReturnNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn class [FSharp.Core]Microsoft.FSharp.Core.Unit assembly/unitGenericReturnNonEta@22::Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit) + IL_0007: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`2 unitGenericReturnEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn class [FSharp.Core]Microsoft.FSharp.Core.Unit assembly/unitGenericReturnEta@25::Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit) + IL_0007: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs.OptimizeOn.Preview.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs.OptimizeOn.Preview.il.bsl new file mode 100644 index 00000000000..a9708f88712 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs.OptimizeOn.Preview.il.bsl @@ -0,0 +1,124 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static !!T Echo(!!T x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + } + + .method public static void returnsUnit(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 voidNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly::returnsUnit(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 voidEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly::returnsUnit(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`2 unitGenericReturnNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn !!0 assembly/C::Echo(!!0) + IL_0007: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`2 unitGenericReturnEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn !!0 assembly/C::Echo(!!0) + IL_0007: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs.OptimizeOn.il.bsl b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs.OptimizeOn.il.bsl new file mode 100644 index 00000000000..f57b5694074 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DelegateUnitReturn.fs.OptimizeOn.il.bsl @@ -0,0 +1,180 @@ + + + + + +.assembly extern runtime { } +.assembly extern FSharp.Core { } +.assembly assembly +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.FSharpInterfaceDataVersionAttribute::.ctor(int32, + int32, + int32) = ( 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 ) + + + + + .hash algorithm 0x00008004 + .ver 0:0:0:0 +} +.module assembly.exe + +.imagebase {value} +.file alignment 0x00000200 +.stackreserve 0x00100000 +.subsystem 0x0003 +.corflags 0x00000001 + + + + + +.class public abstract auto ansi sealed assembly + extends [runtime]System.Object +{ + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 07 00 00 00 00 00 ) + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname voidNonEta@9 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 x, + int32 y) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname voidEta@12 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static void Invoke(int32 a, + int32 b) cil managed + { + + .maxstack 8 + IL_0000: ret + } + + } + + .class auto ansi serializable nested public C + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 03 00 00 00 00 00 ) + .method public static !!T Echo(!!T x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname unitGenericReturnNonEta@22 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static class [FSharp.Core]Microsoft.FSharp.Core.Unit Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + } + + .class abstract auto autochar serializable sealed nested assembly beforefieldinit specialname unitGenericReturnEta@25 + extends [runtime]System.Object + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationMappingAttribute::.ctor(valuetype [FSharp.Core]Microsoft.FSharp.Core.SourceConstructFlags) = ( 01 00 06 00 00 00 00 00 ) + .method assembly static class [FSharp.Core]Microsoft.FSharp.Core.Unit Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit x) cil managed + { + + .maxstack 8 + IL_0000: ldarg.0 + IL_0001: ret + } + + } + + .method public static void returnsUnit(int32 x, + int32 y) cil managed + { + .custom instance void [FSharp.Core]Microsoft.FSharp.Core.CompilationArgumentCountsAttribute::.ctor(int32[]) = ( 01 00 02 00 00 00 01 00 00 00 01 00 00 00 00 00 ) + + .maxstack 8 + IL_0000: ret + } + + .method public static class [runtime]System.Action`2 voidNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/voidNonEta@9::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Action`2 voidEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn void assembly/voidEta@12::Invoke(int32, + int32) + IL_0007: newobj instance void class [runtime]System.Action`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`2 unitGenericReturnNonEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn class [FSharp.Core]Microsoft.FSharp.Core.Unit assembly/unitGenericReturnNonEta@22::Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit) + IL_0007: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_000c: ret + } + + .method public static class [runtime]System.Func`2 unitGenericReturnEta() cil managed + { + + .maxstack 8 + IL_0000: ldnull + IL_0001: ldftn class [FSharp.Core]Microsoft.FSharp.Core.Unit assembly/unitGenericReturnEta@25::Invoke(class [FSharp.Core]Microsoft.FSharp.Core.Unit) + IL_0007: newobj instance void class [runtime]System.Func`2::.ctor(object, + native int) + IL_000c: ret + } + +} + +.class private abstract auto ansi sealed ''.$assembly + extends [runtime]System.Object +{ + .method public static void main@() cil managed + { + .entrypoint + + .maxstack 8 + IL_0000: ret + } + +} + + + + + + diff --git a/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DirectDelegates.fs b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DirectDelegates.fs new file mode 100644 index 00000000000..4b612998927 --- /dev/null +++ b/tests/FSharp.Compiler.ComponentTests/EmittedIL/DirectDelegates/DirectDelegates.fs @@ -0,0 +1,779 @@ +module EmittedIL.RealInternalSignature.DirectDelegates + +open System.IO +open Xunit +open FSharp.Test +open FSharp.Test.Compiler +open FSharp.Test.ProjectGeneration + +let private coreOptions compilation = + compilation + |> withOptions [ "--test:EmitFeeFeeAs100001" ] + |> asExe + |> withEmbeddedPdb + |> withEmbedAllSource + |> ignoreWarnings + +let verifyCompilation compilation = + compilation + |> coreOptions + |> compile + |> shouldSucceed + |> verifyPEFileWithSystemDlls + |> verifyILBaseline + +// Redirect the IL baseline to a distinct *.Preview.il.bsl path so the preview variant can reuse the +// very same input .fs file (no input duplication / drift) without clobbering the default baseline. +let private withPreviewBaseline (cUnit: CompilationUnit) : CompilationUnit = + match cUnit with + | FS src -> + let baseline = + src.Baseline + |> Option.map (fun bsl -> + let path = bsl.ILBaseline.BslSource.Replace(".il.bsl", ".Preview.il.bsl") + let content = if File.Exists path then Some(File.ReadAllText path) else None + { bsl with ILBaseline = { bsl.ILBaseline with BslSource = path; Content = content } }) + FS { src with Baseline = baseline } + | other -> other + +let verifyPreviewCompilation compilation = + compilation + |> coreOptions + |> withLangVersionPreview + |> withPreviewBaseline + |> compile + |> shouldSucceed + |> verifyPEFileWithSystemDlls + |> verifyILBaseline + +[] +let ``DelegateKnownFunction_fs`` compilation = + compilation |> getCompilation |> verifyCompilation + +[] +let ``DelegateKnownFunction_fs preview`` compilation = + compilation |> getCompilation |> verifyPreviewCompilation + +[] +let ``DelegateStaticMethod_fs`` compilation = + compilation |> getCompilation |> verifyCompilation + +[] +let ``DelegateStaticMethod_fs preview`` compilation = + compilation |> getCompilation |> verifyPreviewCompilation + +[] +let ``DelegateGenericStaticMethod_fs`` compilation = + compilation |> getCompilation |> verifyCompilation + +[] +let ``DelegateGenericStaticMethod_fs preview`` compilation = + compilation |> getCompilation |> verifyPreviewCompilation + +[] +let ``DelegateInstanceMethod_fs`` compilation = + compilation |> getCompilation |> verifyCompilation + +[] +let ``DelegateInstanceMethod_fs preview`` compilation = + compilation |> getCompilation |> verifyPreviewCompilation + +[] +let ``DelegateGenericInstanceMethod_fs`` compilation = + compilation |> getCompilation |> verifyCompilation + +[] +let ``DelegateGenericInstanceMethod_fs preview`` compilation = + compilation |> getCompilation |> verifyPreviewCompilation + +[] +let ``DelegateUnitArg_fs`` compilation = + compilation |> getCompilation |> verifyCompilation + +[] +let ``DelegateUnitArg_fs preview`` compilation = + compilation |> getCompilation |> verifyPreviewCompilation + +[] +let ``DelegateNegativeCases_fs`` compilation = + compilation |> getCompilation |> verifyCompilation + +[] +let ``DelegateNegativeCases_fs preview`` compilation = + compilation |> getCompilation |> verifyPreviewCompilation + +[] +let ``DelegatePartialApplication_fs`` compilation = + compilation |> getCompilation |> verifyCompilation + +[] +let ``DelegatePartialApplication_fs preview`` compilation = + compilation |> getCompilation |> verifyPreviewCompilation + +[] +let ``DelegateUnitReturn_fs`` compilation = + compilation |> getCompilation |> verifyCompilation + +[] +let ``DelegateUnitReturn_fs preview`` compilation = + compilation |> getCompilation |> verifyPreviewCompilation + +[] +let ``DelegateStructTarget_fs`` compilation = + compilation |> getCompilation |> verifyCompilation + +[] +let ``DelegateStructTarget_fs preview`` compilation = + compilation |> getCompilation |> verifyPreviewCompilation + +[] +let ``DelegateExtensionMethod_fs`` compilation = + compilation |> getCompilation |> verifyCompilation + +[] +let ``DelegateExtensionMethod_fs preview`` compilation = + compilation |> getCompilation |> verifyPreviewCompilation + +[] +let ``DelegateILMethod_fs`` compilation = + compilation |> getCompilation |> verifyCompilation + +[] +let ``DelegateILMethod_fs preview`` compilation = + compilation |> getCompilation |> verifyPreviewCompilation + +[] +let ``DelegateCustomType_fs`` compilation = + compilation |> getCompilation |> verifyCompilation + +[] +let ``DelegateCustomType_fs preview`` compilation = + compilation |> getCompilation |> verifyPreviewCompilation + +[] +let ``Direct delegates target the real method and dispatch correctly (preview)`` () = + FSharp """ +module DirectDelegateExecution + +open System + +let add (x: int) (y: int) : int = x + y + +type G<'U> = + static member Pick<'T>(x: 'T) (y: 'T) : 'T = x + +[] +type Base() = + abstract M: int -> int + +type Derived() = + inherit Base() + override _.M x = x + 100 + +[] +let main _ = + // Non-eta known function: the delegate points directly at 'add'. + let d = Func(add) + if d.Invoke(2, 3) <> 5 then failwith "add: wrong result" + if d.Method.Name <> "add" then failwithf "add: expected Method.Name 'add' but got '%s'" d.Method.Name + + // Non-eta generic method on a generic type: the delegate points directly at the fully instantiated method. + let gd = Func(G.Pick) + if gd.Invoke(7, 9) <> 7 then failwithf "generic: expected 7 but got %d" (gd.Invoke(7, 9)) + if gd.Method.Name <> "Pick" then failwithf "generic: expected Method.Name 'Pick' but got '%s'" gd.Method.Name + + // Non-eta virtual instance method: dup; ldvirtftn must preserve override dispatch. + let b: Base = Derived() + let vd = Func(b.M) + if vd.Invoke 1 <> 101 then failwithf "virtual: expected 101 but got %d" (vd.Invoke 1) + if vd.Method.Name <> "M" then failwithf "virtual: expected Method.Name 'M' but got '%s'" vd.Method.Name + if not (obj.ReferenceEquals(vd.Target, b)) then failwith "virtual: Target is not the receiver" + + 0 + """ + |> withLangVersionPreview + |> compileExeAndRun + |> shouldSucceed + +[] +let ``Without the feature the delegate goes through a closure (default langversion)`` () = + FSharp """ +module ClosureDelegateExecution + +open System + +let add (x: int) (y: int) : int = x + y + +[] +let main _ = + let d = Func(add) + if d.Invoke(2, 3) <> 5 then failwith "add: wrong result" + // Without the feature the delegate is built over a generated closure method named 'Invoke'. + if d.Method.Name <> "Invoke" then failwithf "expected closure Method.Name 'Invoke' but got '%s'" d.Method.Name + 0 + """ + |> compileExeAndRun + |> shouldSucceed + +// IL (BCL) method target: compiled as TOp.ILCall. With ILCall recognition the optimized eta-expanded +// delegate points directly at the BCL method, so Method.Name is the real method ('Max'), not a closure +// 'Invoke'. Compiled with --optimize+ so the eta forwarding call survives to codegen. +[] +let ``IL method targets are emitted directly when optimized (preview)`` () = + FSharp """ +module IlMethodDelegate + +open System + +[] +let main _ = + let d = Func(fun a b -> Math.Max(a, b)) + if d.Invoke(3, 7) <> 7 then failwith "il: wrong result" + if d.Method.Name <> "Max" then failwithf "il: expected direct 'Max' but got '%s'" d.Method.Name + 0 + """ + |> withLangVersionPreview + |> withOptions [ "--optimize+" ] + |> compileExeAndRun + |> shouldSucceed + +// A closure built from an explicit eta-lambda re-evaluates the receiver on every Invoke; a direct +// delegate would evaluate it once at construction. When the receiver has an effect (here a counter- +// bumping call) that difference is observable, so the closure must be kept even under optimization. +[] +let ``Side-effecting receiver keeps the closure so it is re-evaluated per invoke (preview)`` () = + FSharp """ +module ReceiverEffectDelegate + +open System + +let mutable calls = 0 + +type Box(tag: int) = + member _.Read (_: int) : int = tag + +let getBox () = + calls <- calls + 1 + Box(calls) + +[] +let main _ = + // The receiver 'getBox()' has an effect, so it must run on each invocation, not once at construction. + let d = Func(fun a -> (getBox()).Read a) + let r1 = d.Invoke 0 + let r2 = d.Invoke 0 + if calls <> 2 then failwithf "receiver should be re-evaluated per invoke; calls=%d" calls + if r1 = r2 then failwithf "expected distinct boxes per invoke but got %d and %d" r1 r2 + if d.Method.Name <> "Invoke" then failwithf "expected closure 'Invoke' but got '%s'" d.Method.Name + 0 + """ + |> withLangVersionPreview + |> withOptions [ "--optimize+" ] + |> compileExeAndRun + |> shouldSucceed + +// Instance IL method target: a BCL instance method bound directly. The delegate's Target must be the +// receiver and Method.Name the real method. +[] +let ``Instance IL method targets are emitted directly when optimized (preview)`` () = + FSharp """ +module IlInstanceMethodDelegate + +open System +open System.Text + +[] +let main _ = + let sb = StringBuilder() + // StringBuilder.Append(string) is an instance method on a reference type. + let d = Func(fun s -> sb.Append(s)) + d.Invoke "hello" |> ignore + if sb.ToString() <> "hello" then failwith "il-instance: wrong result" + if d.Method.Name <> "Append" then failwithf "il-instance: expected direct 'Append' but got '%s'" d.Method.Name + if not (obj.ReferenceEquals(d.Target, sb)) then failwith "il-instance: Target is not the receiver" + 0 + """ + |> withLangVersionPreview + |> withOptions [ "--optimize+" ] + |> compileExeAndRun + |> shouldSucceed + +// Custom, F#-declared delegate types (not just BCL Func/Action) point directly at the target method. +// Non-eta targets, so direct in both debug and release. Covers a static target (null Target) and an +// instance target (Target = receiver) through a user-defined delegate. +[] +let ``Custom F# delegate targets the real method and dispatch correctly (preview)`` () = + FSharp """ +module CustomDelegateExecution + +open System + +type DTupled = delegate of int * int -> int + +let acc (x: int) (y: int) : int = x + y + +type C() = + member _.M (x: int) (y: int) : int = x * y + +[] +let main _ = + let ds = DTupled(acc) + if ds.Invoke(2, 3) <> 5 then failwith "static: wrong result" + if ds.Method.Name <> "acc" then failwithf "static: expected 'acc' but got '%s'" ds.Method.Name + if not (isNull ds.Target) then failwith "static: Target should be null" + + let c = C() + let di = DTupled(c.M) + if di.Invoke(4, 5) <> 20 then failwith "instance: wrong result" + if di.Method.Name <> "M" then failwithf "instance: expected 'M' but got '%s'" di.Method.Name + if not (obj.ReferenceEquals(di.Target, c)) then failwith "instance: Target is not the receiver" + 0 + """ + |> withLangVersionPreview + |> compileExeAndRun + |> shouldSucceed + +// Cases 31-35: a tupled application carries each tupled group as a single tuple node, exactly the shape the +// code generator de-tuples by the target's arity when it emits the call. The recognizer de-tuples the same +// way, so a tupled target is as direct-able as its curried counterpart and points at the real method. +[] +let ``Tupled application targets the real method (preview)`` () = + FSharp """ +module TupledDirect + +open System + +let accT (x: int, y: int) : int = x + y + +[] +let main _ = + let d = Func(fun a b -> accT (a, b)) + if d.Invoke(2, 3) <> 5 then failwith "wrong result" + if d.Method.Name <> "accT" then failwithf "expected direct 'accT' but got '%s'" d.Method.Name + if not (isNull d.Target) then failwith "Target should be null for a static target" + 0 + """ + |> withLangVersionPreview + |> withOptions [ "--optimize+" ] + |> compileExeAndRun + |> shouldSucceed + +// Cases 37-41: the CLR's closed delegate binds exactly one leading argument as the Target, so a partial +// application that fixes two or more arguments (or also fixes a receiver) has no closed direct form and stays +// a closure. A one-argument partial application could be closed, but only if that argument is a reference type +// (a value-type Target would need boxing - the same gap as a value-type receiver), so fixing a value-type +// argument keeps a closure too. +[] +let ``Partial application stays a closure (preview)`` () = + FSharp """ +module PartialClosure + +open System + +let add3 (x: int) (y: int) (z: int) : int = x + y + z + +[] +let main _ = + // One fixed argument, but it is a value type: a value-type Target would need boxing, so a closure is kept. + let d = Func(add3 1) + if d.Invoke(2, 3) <> 6 then failwith "wrong result" + if d.Method.Name <> "Invoke" then failwithf "expected closure 'Invoke' but got '%s'" d.Method.Name + 0 + """ + |> withLangVersionPreview + |> compileExeAndRun + |> shouldSucceed + +// A one-argument partial application whose fixed argument is a reference type is expressible as a closed +// delegate: the argument is bound as the Target and the delegate points directly at the static method. +[] +let ``Reference-type single-argument partial application is direct (preview)`` () = + FSharp """ +module PartialDirect + +open System + +let prepend (prefix: string) (x: int) (y: int) : string = sprintf "%s%d%d" prefix x y + +[] +let main _ = + let p = "p" + let d = Func(prepend p) + if d.Invoke(2, 3) <> "p23" then failwith "wrong result" + if d.Method.Name <> "prepend" then failwithf "expected direct 'prepend' but got '%s'" d.Method.Name + if not (obj.ReferenceEquals(d.Target, p)) then failwith "Target is not the fixed argument" + 0 + """ + |> withLangVersionPreview + |> withOptions [ "--optimize+" ] + |> compileExeAndRun + |> shouldSucceed + +// Cases 46-49: the forwarded unit argument is stripped, so a unit-argument delegate points directly at the +// target - a static target carries a null Target, an instance target carries the receiver. +[] +let ``Unit-argument delegate targets the real method (preview)`` () = + FSharp """ +module UnitArgDirect + +open System + +let mutable ran = 0 + +let handler () : unit = ran <- ran + 1 + +type C() = + member _.M () : unit = ran <- ran + 10 + +[] +let main _ = + // Static unit-argument target: direct, null Target, real Method.Name. + let ds = Action(handler) + ds.Invoke() + if ds.Method.Name <> "handler" then failwithf "static: expected 'handler' but got '%s'" ds.Method.Name + if not (isNull ds.Target) then failwith "static: Target should be null" + + // Instance unit-argument target: direct, Target is the receiver. + let c = C() + let di = Action(c.M) + di.Invoke() + if di.Method.Name <> "M" then failwithf "instance: expected 'M' but got '%s'" di.Method.Name + if not (obj.ReferenceEquals(di.Target, c)) then failwith "instance: Target is not the receiver" + + if ran <> 11 then failwithf "expected both targets to run (ran=%d)" ran + 0 + """ + |> withLangVersionPreview + |> compileExeAndRun + |> shouldSucceed + +// Cases 50-51: a value-type receiver is boxed (a copy) and stored as the delegate's Target; the runtime binds +// the unboxing stub, so the delegate points at the real struct method and dispatches correctly, with the boxed +// copy carrying the receiver's value. The receiver must be effect-free, so it comes from a (non-mutable) +// parameter here. (By-value capture cannot be observed via external mutation on a *direct* struct delegate: a +// mutable receiver - or the defensive copy it forces - reads a mutable value, which counts as an effect, so it +// is kept as a closure instead. The boxing itself guarantees the by-value copy.) +[] +let ``Struct value-type receiver targets the real method (preview)`` () = + FSharp """ +module StructDirect + +open System + +[] +type S = + val V : int + new (v: int) = { V = v } + member this.AddV (x: int) (y: int) : int = this.V + x + y + +let makeAdder (s: S) = Func(s.AddV) + +[] +let main _ = + let d = makeAdder (S(100)) + if d.Invoke(2, 3) <> 105 then failwithf "wrong result: %d" (d.Invoke(2, 3)) + if d.Method.Name <> "AddV" then failwithf "expected direct 'AddV' but got '%s'" d.Method.Name + if isNull d.Target then failwith "Target should be the boxed receiver, not null" + if not (d.Target :? S) then failwith "Target should be a boxed S" + 0 + """ + |> withLangVersionPreview + |> compileExeAndRun + |> shouldSucceed + +// Case 52: an extension member compiles to a static method whose first parameter is the receiver. The CLR's +// "closed over the first argument" delegate binds that receiver as the Target, so the delegate points directly +// at the static extension method (in release, where the eta-lambda does not need to survive for debugging). +[] +let ``Extension member targets the real method (preview)`` () = + FSharp """ +module ExtensionDirect + +open System +open System.Runtime.CompilerServices + +type Holder() = class end + +[] +type Extensions = + [] + static member Combine (h: Holder, x: int, y: int) : int = x + y + +[] +let main _ = + let h = Holder() + let d = Func(fun a b -> h.Combine(a, b)) + if d.Invoke(2, 3) <> 5 then failwith "wrong result" + if d.Method.Name <> "Combine" then failwithf "expected direct 'Combine' but got '%s'" d.Method.Name + if not (obj.ReferenceEquals(d.Target, h)) then failwith "Target is not the extension receiver" + 0 + """ + |> withLangVersionPreview + |> withOptions [ "--optimize+" ] + |> compileExeAndRun + |> shouldSucceed + +// A generic extension member whose receiver type uses the method's type parameter ('T list) still binds the +// receiver as the Target: the type argument is threaded through as a method instantiation (an extension member +// has no enclosing type arguments), and the receiver - a reference type - is the closed-over first argument. +[] +let ``Generic extension member receiver targets the real method (preview)`` () = + FSharp """ +module GenericExtensionDirect + +open System +open System.Runtime.CompilerServices + +[] +type ListExtensions = + [] + static member CountWith<'T> (xs: 'T list, x: int, y: int) : int = List.length xs + x + y + +[] +let main _ = + let xs = [ "a"; "b"; "c" ] + let d = Func(fun a b -> xs.CountWith(a, b)) + if d.Invoke(2, 3) <> 8 then failwithf "wrong result: %d" (d.Invoke(2, 3)) + if d.Method.Name <> "CountWith" then failwithf "expected direct 'CountWith' but got '%s'" d.Method.Name + if not (obj.ReferenceEquals(d.Target, xs)) then failwith "Target is not the extension receiver" + 0 + """ + |> withLangVersionPreview + |> withOptions [ "--optimize+" ] + |> compileExeAndRun + |> shouldSucceed + +// Case 53: a byref Invoke parameter with a mutating body is not a transparent forwarding call, so it stays +// a closure and mutates through the byref correctly. +[] +let ``Byref-parameter delegate stays a closure and mutates (preview)`` () = + FSharp """ +module ByrefClosure + +open System + +type D = delegate of byref -> unit + +[] +let main _ = + let d = D(fun x -> x <- x + 1) + let mutable v = 10 + d.Invoke(&v) + if v <> 11 then failwithf "expected 11 but got %d" v + if d.Method.Name <> "Invoke" then failwithf "expected closure 'Invoke' but got '%s'" d.Method.Name + 0 + """ + |> withLangVersionPreview + |> compileExeAndRun + |> shouldSucceed + +// Case 55: an over-application - the target's *result* consumes the delegate argument(s) - is not a saturated +// call to the target, so it must stay a closure with per-invocation evaluation of the function position. A +// direct delegate here would be doubly wrong: it would point at the wrong method (with an incompatible IL +// return) and would stop re-evaluating the function position on each invocation. +[] +let ``Over-application stays a closure and evaluates per invocation (preview)`` () = + FSharp """ +module OverApplicationClosure + +open System + +let mutable calls = 0 + +let makeHandler (tag: string) : unit -> unit = + calls <- calls + 1 + fun () -> () + +[] +let main _ = + // 'makeHandler "h"' returns the function that consumes the Invoke argument list, so the closure must + // re-evaluate it on every invocation, not bind 'makeHandler' at construction. + let d = Action(makeHandler "h") + if calls <> 0 then failwith "over-application was evaluated at construction" + if d.Method.Name <> "Invoke" then failwithf "expected closure 'Invoke' but got '%s'" d.Method.Name + d.Invoke() + d.Invoke() + if calls <> 2 then failwithf "expected per-invocation evaluation, calls=%d" calls + + // A throwing function position likewise stays a closure and faults at invocation, not construction. + let f = Action(failwith "boom") + if f.Method.Name <> "Invoke" then failwithf "expected closure 'Invoke' but got '%s'" f.Method.Name + + try + f.Invoke() + failwith "expected the lazy 'failwith' to throw on Invoke" + with Failure "boom" -> + () + + 0 + """ + |> withLangVersionPreview + |> withOptions [ "--optimize+" ] + |> compileExeAndRun + |> shouldSucceed + +let private crossAssemblyLibrary = + FSharp """ +module DelegateLib + +let add (x: int) (y: int) : int = x + y + +type Calc(k: int) = + member _.Scale (x: int) (y: int) : int = (x + y) * k + +// A small inline function: its body is serialized into the referenced assembly and is always inlined at the +// use site (independent of --optimize), so a delegate over it can never see a forwarding call. +let inline addInline (x: int) (y: int) : int = x + y + """ + |> asLibrary + +[] +let ``Cross-assembly F# target is emitted directly (preview)`` () = + FSharp """ +module CrossAsmDirect + +open System +open DelegateLib + +[] +let main _ = + // Static module function imported from another assembly: direct, null Target, real Method.Name. + let ds = Func(add) + if ds.Invoke(2, 3) <> 5 then failwith "static: wrong result" + if ds.Method.Name <> "add" then failwithf "static: expected 'add' but got '%s'" ds.Method.Name + if not (isNull ds.Target) then failwith "static: Target should be null" + + // Instance member imported from another assembly: direct, Target is the receiver. + let c = Calc(10) + let di = Func(c.Scale) + if di.Invoke(2, 3) <> 50 then failwithf "instance: expected 50 but got %d" (di.Invoke(2, 3)) + if di.Method.Name <> "Scale" then failwithf "instance: expected 'Scale' but got '%s'" di.Method.Name + if not (obj.ReferenceEquals(di.Target, c)) then failwith "instance: Target is not the receiver" + 0 + """ + |> withReferences [ crossAssemblyLibrary ] + |> withLangVersionPreview + |> withOptions [ "--optimize+" ] + |> compileExeAndRun + |> shouldSucceed + +// An 'inline' target from a referenced assembly is always inlined (mandatory inlining takes precedence over +// the forwarding-call preservation), so the forwarding call vanishes and a closure is kept even in release. +[] +let ``Cross-assembly inline target stays a closure (preview)`` () = + FSharp """ +module CrossAsmInline + +open System +open DelegateLib + +[] +let main _ = + let d = Func(fun a b -> addInline a b) + if d.Invoke(2, 3) <> 5 then failwith "wrong result" + if d.Method.Name <> "Invoke" then failwithf "expected closure 'Invoke' but got '%s'" d.Method.Name + 0 + """ + |> withReferences [ crossAssemblyLibrary ] + |> withLangVersionPreview + |> withOptions [ "--optimize+" ] + |> compileExeAndRun + |> shouldSucceed + +// An [] function parameter yields a direct delegate only when full inlining leaves a +// forwarding call to a named method as the delegate body: when the inlined lambda body is arbitrary code +// there is no method to point at, and when either inlining does not happen, the parameter is a first-class +// function value (case 42) - both keep a closure. +[] +let ``InlineIfLambda function parameter keeps a closure unless inlining exposes a forwarding call (preview)`` () = + FSharp """ +module InlineIfLambdaClosure + +open System + +let mutable acc = 0 + +let inline makeAction ([] f: int -> int -> unit) = Action(fun a b -> f a b) + +// Read through a mutable so no inlining step can turn the argument back into a lambda. +let mutable handler : int -> int -> unit = fun a b -> acc <- acc + a * 100 + b + +let bump (a: int) (b: int) : unit = acc <- acc + a * 1000 + b + +[] +let main _ = + // Lambda argument: 'makeAction' and the lambda both inline, leaving inlined code as the delegate body. + let k = 7 + let d = makeAction (fun a b -> acc <- acc + a * 10 + b + k) + d.Invoke(1, 2) + if acc <> 19 then failwithf "lambda: wrong result %d" acc + if d.Method.Name <> "Invoke" then failwithf "lambda: expected closure 'Invoke' but got '%s'" d.Method.Name + + // First-class argument: there is no lambda to inline, so 'f' is a function value. + acc <- 0 + let d2 = makeAction handler + d2.Invoke(1, 2) + if acc <> 102 then failwithf "value: wrong result %d" acc + if d2.Method.Name <> "Invoke" then failwithf "value: expected closure 'Invoke' but got '%s'" d2.Method.Name + + // Forwarding lambda argument: after both inline, the delegate body is a forwarding call to 'bump', + // which the recognizer binds directly. + acc <- 0 + let d3 = makeAction (fun a b -> bump a b) + d3.Invoke(1, 2) + if acc <> 1002 then failwithf "forwarding: wrong result %d" acc + if d3.Method.Name <> "bump" then failwithf "forwarding: expected direct 'bump' but got '%s'" d3.Method.Name + if not (isNull d3.Target) then failwith "forwarding: Target should be null for a static target" + 0 + """ + |> withLangVersionPreview + |> withOptions [ "--optimize+" ] + |> compileExeAndRun + |> shouldSucceed + +#if NETCOREAPP +[] +let ``Minimal API binds a direct delegate handler by parameter name (preview)`` () = + let aspNetFrameworkReferences = + ReferenceHelpers.getFrameworkReference { Name = "Microsoft.AspNetCore.App"; Version = None } + + Fsx (aspNetFrameworkReferences + """ +module X = + open System + open System.Net + open System.Net.Http + open System.Net.Sockets + open Microsoft.AspNetCore.Builder + open Microsoft.AspNetCore.Http + + let divide (first: int) (second: int) : int = first / second + + let run () = + let port = + let listener = new TcpListener(IPAddress.Loopback, 0) + listener.Start() + let p = (listener.LocalEndpoint :?> IPEndPoint).Port + listener.Stop() + p + + let url = sprintf "http://127.0.0.1:%d" port + let app = WebApplication.CreateBuilder().Build() + + // Route parameters {second}/{first} bind to the handler's parameters by name, which requires delegate.Method to be the + // real 'divide' (a direct delegate), not a synthesized closure 'Invoke'. + app.MapGet("/divide/{second}/{first}", Func(fun z w -> divide z w)) |> ignore + app.Urls.Add url + app.StartAsync().GetAwaiter().GetResult() + + try + let client = new HttpClient() + let body = client.GetStringAsync(url + "/divide/2/6").GetAwaiter().GetResult() + if body.Trim() <> "3" then failwithf "minimal API returned '%s', expected '3'" body + finally + app.StopAsync().GetAwaiter().GetResult() + +X.run () """) + |> withLangVersionPreview + |> runFsi + |> shouldSucceed +#endif diff --git a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj index 0908b6600ea..a10a8ef8700 100644 --- a/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj +++ b/tests/FSharp.Compiler.ComponentTests/FSharp.Compiler.ComponentTests.fsproj @@ -263,6 +263,7 @@ + diff --git a/tests/FSharp.Compiler.ComponentTests/Language/CodeQuotationTests.fs b/tests/FSharp.Compiler.ComponentTests/Language/CodeQuotationTests.fs index 29556381221..7085bd7a3a7 100644 --- a/tests/FSharp.Compiler.ComponentTests/Language/CodeQuotationTests.fs +++ b/tests/FSharp.Compiler.ComponentTests/Language/CodeQuotationTests.fs @@ -40,6 +40,42 @@ let z : unit = |> compileAndRun |> shouldSucceed + [] + let ``Delegate construction quotations are unaffected by the direct delegate optimization`` () = + Fsx """ +open System +open FSharp.Quotations.Patterns + +let handlerCurried (x: int) (y: int) : unit = () + +type C(k: int) = + member _.AddC (x: int) (y: int) : unit = ignore k + +let check (label: string) (target: string) (expr: Quotations.Expr) = + match expr with + | NewDelegate(dty, _, _) when dty = typeof> -> () + | e -> failwithf "%s: expected NewDelegate of Action, got %A" label e + if not ((string expr).Contains target) then + failwithf "%s: expected the quotation to reference target '%s', got %A" label target expr + +let o = C(1) + +// non-eta-expanded known function +check "nonEta" "handlerCurried" <@ Action(handlerCurried) @> +// eta-expanded known function +check "etaCurried" "handlerCurried" <@ Action(fun a b -> handlerCurried a b) @> +// non-eta-expanded instance method +check "instanceNonEta" "AddC" <@ Action(o.AddC) @> +// eta-expanded instance method +check "instanceEta" "AddC" <@ Action(fun a b -> o.AddC a b) @> + +printfn "ok" + """ + |> asExe + |> withLangVersionPreview + |> compileAndRun + |> shouldSucceed + [] let ``Quotation on decimal literal compiles and runs`` () = FSharp """