Skip to content

Commit 6f71fa0

Browse files
authored
Merge pull request #12747 from dotnet/merges/main-to-release/dev17.2
Merge main to release/dev17.2
2 parents 39eb973 + 055ebe1 commit 6f71fa0

File tree

13 files changed

+573
-63
lines changed

13 files changed

+573
-63
lines changed

src/fsharp/IlxGen.fs

Lines changed: 80 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3789,18 +3789,70 @@ and GenTry cenv cgbuf eenv scopeMarks (e1, m, resultTy, spTry) =
37893789
let tryMarks = (startTryMark.CodeLabel, endTryMark.CodeLabel)
37903790
whereToSaveOpt, eenvinner, stack, tryMarks, afterHandler
37913791

3792-
and GenTryWith cenv cgbuf eenv (e1, vf: Val, ef, vh: Val, eh, m, resty, spTry, spWith) sequel =
3792+
/// Determine if a filter block is side-effect free, meaning it can be run on the first pass and
3793+
/// the pattern match logic repeated on the second pass.
3794+
///
3795+
/// Filter blocks are only ever generated by pattern match compilation so we can safely look for particular
3796+
/// constructs.
3797+
and eligibleForFilter (cenv: cenv) expr =
3798+
let rec check expr =
3799+
match expr with
3800+
| Expr.Let (TBind(_, be, _), body, _, _) ->
3801+
check be && check body
3802+
| Expr.DebugPoint(_, expr) -> check expr
3803+
| Expr.Match (_spBind, _exprm, dtree, targets, _, _) ->
3804+
checkDecisionTree dtree &&
3805+
targets |> Array.forall (fun (TTarget(_, e, _)) -> check e)
3806+
| Expr.Const _ -> true
3807+
| Expr.Op(TOp.ILAsm([ I_isinst _ ], _), _, _, _) -> true
3808+
| Expr.Op(TOp.UnionCaseTagGet _, _, _, _) -> true
3809+
| Expr.Op(TOp.ExnFieldGet _, _, _, _) -> true
3810+
| Expr.Op(TOp.UnionCaseFieldGet _, _, _, _) -> true
3811+
| Expr.Op(TOp.ValFieldGet _, _, _, _) -> true
3812+
| Expr.Op(TOp.TupleFieldGet _, _, _, _) -> true
3813+
| Expr.Op(TOp.Coerce _, _, _, _) -> true
3814+
| Expr.Val _ -> true
3815+
| _ -> false
3816+
and checkDecisionTree dtree =
3817+
match dtree with
3818+
| TDSwitch(ve, cases, dflt, _) ->
3819+
check ve &&
3820+
cases |> List.forall checkDecisionTreeCase &&
3821+
dflt |> Option.forall checkDecisionTree
3822+
| TDSuccess (es, _) -> es |> List.forall check
3823+
| TDBind(bind, rest) -> check bind.Expr && checkDecisionTree rest
3824+
and checkDecisionTreeCase dcase =
3825+
let (TCase(test, tree)) = dcase
3826+
checkDecisionTree tree &&
3827+
match test with
3828+
| DecisionTreeTest.UnionCase _ -> true
3829+
| DecisionTreeTest.ArrayLength _ -> true
3830+
| DecisionTreeTest.Const _ -> true
3831+
| DecisionTreeTest.IsNull -> true
3832+
| DecisionTreeTest.IsInst _ -> true
3833+
| DecisionTreeTest.ActivePatternCase _ -> false // must only be run once
3834+
| DecisionTreeTest.Error _ -> false
3835+
3836+
let isTrivial =
3837+
match expr with
3838+
| DebugPoints (Expr.Const _, _) -> true
3839+
| _ -> false
3840+
3841+
// Filters seem to generate invalid code for the ilreflect.fs backend
3842+
(cenv.opts.ilxBackend = IlxGenBackend.IlWriteBackend) &&
3843+
not isTrivial &&
3844+
check expr
3845+
3846+
and GenTryWith cenv cgbuf eenv (e1, valForFilter: Val, filterExpr, valForHandler: Val, handlerExpr, m, resty, spTry, spWith) sequel =
37933847
let g = cenv.g
37943848

37953849
// Save the stack - gross because IL flushes the stack at the exn. handler
37963850
// note: eenvinner notes spill vars are live
37973851
LocalScope "trystack" cgbuf (fun scopeMarks ->
37983852
let whereToSaveOpt, eenvinner, stack, tryMarks, afterHandler = GenTry cenv cgbuf eenv scopeMarks (e1, m, resty, spTry)
37993853

3800-
// Now the filter and catch blocks
3801-
38023854
let seh =
3803-
if cenv.opts.generateFilterBlocks then
3855+
if cenv.opts.generateFilterBlocks || eligibleForFilter cenv filterExpr then
38043856
let startOfFilter = CG.GenerateMark cgbuf "startOfFilter"
38053857
let afterFilter = CG.GenerateDelayMark cgbuf "afterFilter"
38063858
let sequelOnBranches, afterJoin, stackAfterJoin, sequelAfterJoin = GenJoinPoint cenv cgbuf "filter" eenv g.int_ty m EndFilter
@@ -3819,14 +3871,14 @@ and GenTryWith cenv cgbuf eenv (e1, vf: Val, ef, vh: Val, eh, m, resty, spTry, s
38193871
| DebugPointAtWith.No -> ()
38203872

38213873
CG.SetStack cgbuf [g.ilg.typ_Object]
3822-
let _, eenvinner = AllocLocalVal cenv cgbuf vf eenvinner None (startOfFilter, afterFilter)
3874+
let _, eenvinner = AllocLocalVal cenv cgbuf valForFilter eenvinner None (startOfFilter, afterFilter)
38233875
CG.EmitInstr cgbuf (pop 1) (Push [g.iltyp_Exception]) (I_castclass g.iltyp_Exception)
38243876

3825-
GenStoreVal cenv cgbuf eenvinner vf.Range vf
3877+
GenStoreVal cenv cgbuf eenvinner valForFilter.Range valForFilter
38263878

38273879
// Why SPSuppress? Because we do not emit a debug point at the start of the List.filter - we've already put one on
38283880
// the 'with' keyword above
3829-
GenExpr cenv cgbuf eenvinner ef sequelOnBranches
3881+
GenExpr cenv cgbuf eenvinner filterExpr sequelOnBranches
38303882
CG.SetMarkToHere cgbuf afterJoin
38313883
CG.SetStack cgbuf stackAfterJoin
38323884
GenSequel cenv eenv.cloc cgbuf sequelAfterJoin
@@ -3837,12 +3889,12 @@ and GenTryWith cenv cgbuf eenv (e1, vf: Val, ef, vh: Val, eh, m, resty, spTry, s
38373889
let startOfHandler = CG.GenerateMark cgbuf "startOfHandler"
38383890

38393891
CG.SetStack cgbuf [g.ilg.typ_Object]
3840-
let _, eenvinner = AllocLocalVal cenv cgbuf vh eenvinner None (startOfHandler, afterHandler)
3892+
let _, eenvinner = AllocLocalVal cenv cgbuf valForHandler eenvinner None (startOfHandler, afterHandler)
38413893
CG.EmitInstr cgbuf (pop 1) (Push [g.iltyp_Exception]) (I_castclass g.iltyp_Exception)
3842-
GenStoreVal cenv cgbuf eenvinner vh.Range vh
3894+
GenStoreVal cenv cgbuf eenvinner valForHandler.Range valForHandler
38433895

38443896
let exitSequel = LeaveHandler (false, whereToSaveOpt, afterHandler, true)
3845-
GenExpr cenv cgbuf eenvinner eh exitSequel
3897+
GenExpr cenv cgbuf eenvinner handlerExpr exitSequel
38463898

38473899
let endOfHandler = CG.GenerateMark cgbuf "endOfHandler"
38483900
let handlerMarks = (startOfHandler.CodeLabel, endOfHandler.CodeLabel)
@@ -3855,14 +3907,14 @@ and GenTryWith cenv cgbuf eenv (e1, vf: Val, ef, vh: Val, eh, m, resty, spTry, s
38553907
| DebugPointAtWith.No -> ()
38563908

38573909
CG.SetStack cgbuf [g.ilg.typ_Object]
3858-
let _, eenvinner = AllocLocalVal cenv cgbuf vh eenvinner None (startOfHandler, afterHandler)
3910+
let _, eenvinner = AllocLocalVal cenv cgbuf valForHandler eenvinner None (startOfHandler, afterHandler)
38593911
CG.EmitInstr cgbuf (pop 1) (Push [g.iltyp_Exception]) (I_castclass g.iltyp_Exception)
38603912

3861-
GenStoreVal cenv cgbuf eenvinner m vh
3913+
GenStoreVal cenv cgbuf eenvinner m valForHandler
38623914

38633915
let exitSequel = LeaveHandler (false, whereToSaveOpt, afterHandler, true)
38643916
let eenvinner = { eenvinner with exitSequel = exitSequel }
3865-
GenExpr cenv cgbuf eenvinner eh exitSequel
3917+
GenExpr cenv cgbuf eenvinner handlerExpr exitSequel
38663918

38673919
let endOfHandler = CG.GenerateMark cgbuf "endOfHandler"
38683920
let handlerMarks = (startOfHandler.CodeLabel, endOfHandler.CodeLabel)
@@ -7709,8 +7761,10 @@ and GenAbstractBinding cenv eenv tref (vref: ValRef) =
77097761
else
77107762
[], [], []
77117763

7712-
/// Generate a ToString method that calls 'sprintf "%A"'
7713-
and GenToStringMethod cenv eenv ilThisTy m =
7764+
and GenToStringMethod cenv eenv ilThisTy m = GenPrintingMethod cenv eenv "ToString" ilThisTy m
7765+
7766+
/// Generate a ToString/get_Message method that calls 'sprintf "%A"'
7767+
and GenPrintingMethod cenv eenv methName ilThisTy m =
77147768
let g = cenv.g
77157769
[ match (eenv.valsInScope.TryFind g.sprintf_vref.Deref,
77167770
eenv.valsInScope.TryFind g.new_format_vref.Deref) with
@@ -7750,7 +7804,7 @@ and GenToStringMethod cenv eenv ilThisTy m =
77507804

77517805
let ilMethodBody = mkMethodBody (true, [], 2, nonBranchingInstrsToCode ilInstrs, None, eenv.imports)
77527806

7753-
let mdef = mkILNonGenericVirtualMethod ("ToString", ILMemberAccess.Public, [], mkILReturn g.ilg.typ_String, ilMethodBody)
7807+
let mdef = mkILNonGenericVirtualMethod (methName, ILMemberAccess.Public, [], mkILReturn g.ilg.typ_String, ilMethodBody)
77547808
let mdef = mdef.With(customAttrs = mkILCustomAttrs [ g.CompilerGeneratedAttribute ])
77557809
yield mdef
77567810
| _ -> () ]
@@ -8433,12 +8487,21 @@ and GenExnDef cenv mgbuf eenv m (exnc: Tycon) =
84338487

84348488
let ilTypeName = tref.Name
84358489

8490+
let ilMethodDefs =
8491+
[ ilCtorDef
8492+
yield! ilCtorDefNoArgs
8493+
yield! serializationRelatedMembers
8494+
yield! ilMethodDefsForProperties
8495+
8496+
if not (exnc.HasMember g "get_Message" []) && not (exnc.HasMember g "Message" []) then
8497+
yield! GenPrintingMethod cenv eenv "get_Message" ilThisTy m ]
8498+
84368499
let interfaces = exnc.ImmediateInterfaceTypesOfFSharpTycon |> List.map (GenType cenv.amap m eenv.tyenv)
84378500
let tdef =
84388501
mkILGenericClass
84398502
(ilTypeName, access, [], g.iltyp_Exception,
84408503
interfaces,
8441-
mkILMethods ([ilCtorDef] @ ilCtorDefNoArgs @ serializationRelatedMembers @ ilMethodDefsForProperties),
8504+
mkILMethods ilMethodDefs,
84428505
mkILFields ilFieldDefs,
84438506
emptyILTypeDefs,
84448507
mkILProperties ilPropertyDefs,

src/fsharp/utils/FileSystem.fsi

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,22 @@ open System.Reflection
99
open System.Text
1010
open System.Runtime.CompilerServices
1111

12-
exception IllegalFileNameChar of string * char
12+
exception internal IllegalFileNameChar of string * char
1313

1414
module internal Bytes =
1515
/// returned int will be 0 <= x <= 255
1616
val get: byte[] -> int -> int
17+
1718
val zeroCreate: int -> byte[]
19+
1820
/// each int must be 0 <= x <= 255
1921
val ofInt32Array: int[] -> byte[]
22+
2023
/// each int will be 0 <= x <= 255
2124
val blit: byte[] -> int -> byte[] -> int -> int -> unit
2225

2326
val stringAsUnicodeNullTerminated: string -> byte[]
27+
2428
val stringAsUtf8NullTerminated: string -> byte[]
2529

2630
/// A view over bytes.
@@ -91,7 +95,9 @@ type internal ReadOnlyByteMemory =
9195
/// MemoryMapped extensions
9296
module internal MemoryMappedFileExtensions =
9397
type MemoryMappedFile with
98+
9499
static member TryFromByteMemory : bytes: ReadOnlyByteMemory -> MemoryMappedFile option
100+
95101
static member TryFromMemory : bytes: ReadOnlyMemory<byte> -> MemoryMappedFile option
96102

97103
/// Filesystem helpers

src/fsharp/xlf/FSComp.txt.cs.xlf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@
299299
</trans-unit>
300300
<trans-unit id="ilxGenUnknownDebugPoint">
301301
<source>Unknown debug point '{0}'. The available debug points are '{1}'.</source>
302-
<target state="new">Unknown debug point '{0}'. The available debug points are '{1}'.</target>
302+
<target state="translated">Neznámý bod ladění {0}. Dostupné body ladění jsou {1}.</target>
303303
<note />
304304
</trans-unit>
305305
<trans-unit id="ilxgenInvalidConstructInStateMachineDuringCodegen">

src/fsharp/xlf/FSComp.txt.ko.xlf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@
299299
</trans-unit>
300300
<trans-unit id="ilxGenUnknownDebugPoint">
301301
<source>Unknown debug point '{0}'. The available debug points are '{1}'.</source>
302-
<target state="new">Unknown debug point '{0}'. The available debug points are '{1}'.</target>
302+
<target state="translated">알 수 없는 디버그 지점 '{0}'. 사용 가능한 디버그 지점은 '{1}'입니다.</target>
303303
<note />
304304
</trans-unit>
305305
<trans-unit id="ilxgenInvalidConstructInStateMachineDuringCodegen">

src/fsharp/xlf/FSComp.txt.pl.xlf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@
299299
</trans-unit>
300300
<trans-unit id="ilxGenUnknownDebugPoint">
301301
<source>Unknown debug point '{0}'. The available debug points are '{1}'.</source>
302-
<target state="new">Unknown debug point '{0}'. The available debug points are '{1}'.</target>
302+
<target state="translated">Nieznany punkt debugowania „{0}”. Dostępnymi punktami debugowania są „{1}.</target>
303303
<note />
304304
</trans-unit>
305305
<trans-unit id="ilxgenInvalidConstructInStateMachineDuringCodegen">

src/fsharp/xlf/FSComp.txt.ru.xlf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@
299299
</trans-unit>
300300
<trans-unit id="ilxGenUnknownDebugPoint">
301301
<source>Unknown debug point '{0}'. The available debug points are '{1}'.</source>
302-
<target state="new">Unknown debug point '{0}'. The available debug points are '{1}'.</target>
302+
<target state="translated">Неизвестная точка отладки \"{0}\". Доступные точки отладки: \"{1}\".</target>
303303
<note />
304304
</trans-unit>
305305
<trans-unit id="ilxgenInvalidConstructInStateMachineDuringCodegen">

src/fsharp/xlf/FSComp.txt.zh-Hans.xlf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@
299299
</trans-unit>
300300
<trans-unit id="ilxGenUnknownDebugPoint">
301301
<source>Unknown debug point '{0}'. The available debug points are '{1}'.</source>
302-
<target state="new">Unknown debug point '{0}'. The available debug points are '{1}'.</target>
302+
<target state="translated">调试点“{0}”未知。可用的调试点为“{1}”。</target>
303303
<note />
304304
</trans-unit>
305305
<trans-unit id="ilxgenInvalidConstructInStateMachineDuringCodegen">

src/fsharp/xlf/FSComp.txt.zh-Hant.xlf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@
299299
</trans-unit>
300300
<trans-unit id="ilxGenUnknownDebugPoint">
301301
<source>Unknown debug point '{0}'. The available debug points are '{1}'.</source>
302-
<target state="new">Unknown debug point '{0}'. The available debug points are '{1}'.</target>
302+
<target state="translated">未知的偵錯點 '{0}'。可用的偵錯點為 '{1}'</target>
303303
<note />
304304
</trans-unit>
305305
<trans-unit id="ilxgenInvalidConstructInStateMachineDuringCodegen">

tests/FSharp.Compiler.Service.Tests/FSharp.CompilerService.SurfaceArea.netstandard.expected

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -4087,17 +4087,6 @@ FSharp.Compiler.IO.IFileSystem: System.String NormalizePathShim(System.String)
40874087
FSharp.Compiler.IO.IFileSystem: Void CopyShim(System.String, System.String, Boolean)
40884088
FSharp.Compiler.IO.IFileSystem: Void DirectoryDeleteShim(System.String)
40894089
FSharp.Compiler.IO.IFileSystem: Void FileDeleteShim(System.String)
4090-
FSharp.Compiler.IO.IllegalFileNameChar
4091-
FSharp.Compiler.IO.IllegalFileNameChar: Boolean Equals(System.Object)
4092-
FSharp.Compiler.IO.IllegalFileNameChar: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
4093-
FSharp.Compiler.IO.IllegalFileNameChar: Char Data1
4094-
FSharp.Compiler.IO.IllegalFileNameChar: Char get_Data1()
4095-
FSharp.Compiler.IO.IllegalFileNameChar: Int32 GetHashCode()
4096-
FSharp.Compiler.IO.IllegalFileNameChar: Int32 GetHashCode(System.Collections.IEqualityComparer)
4097-
FSharp.Compiler.IO.IllegalFileNameChar: System.String Data0
4098-
FSharp.Compiler.IO.IllegalFileNameChar: System.String get_Data0()
4099-
FSharp.Compiler.IO.IllegalFileNameChar: Void .ctor()
4100-
FSharp.Compiler.IO.IllegalFileNameChar: Void .ctor(System.String, Char)
41014090
FSharp.Compiler.IO.StreamExtensions
41024091
FSharp.Compiler.IO.StreamExtensions: Byte[] Stream.ReadAllBytes(System.IO.Stream)
41034092
FSharp.Compiler.IO.StreamExtensions: Byte[] Stream.ReadBytes(System.IO.Stream, Int32, Int32)

tests/fsharpqa/Source/CodeGen/EmittedIL/SerializableAttribute/ToplevelModule.il.bsl

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@
3636
// Offset: 0x00001148 Length: 0x000003FD
3737
}
3838
.module TopLevelModule.dll
39-
// MVID: {61F2D6CA-37F5-C118-A745-0383CAD6F261}
39+
// MVID: {620E3D71-37F5-C118-A745-0383713D0E62}
4040
.imagebase 0x00400000
4141
.file alignment 0x00000200
4242
.stackreserve 0x00100000
4343
.subsystem 0x0003 // WINDOWS_CUI
4444
.corflags 0x00000001 // ILONLY
45-
// Image base: 0x07430000
45+
// Image base: 0x07130000
4646

4747

4848
// =============== CLASS MEMBERS DECLARATION ===================
@@ -580,6 +580,20 @@
580580
IL_0006: ret
581581
} // end of method MyExn::get_Data0
582582

583+
.method public strict virtual instance string
584+
get_Message() cil managed
585+
{
586+
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
587+
// Code size 22 (0x16)
588+
.maxstack 8
589+
IL_0000: ldstr "%+A"
590+
IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class ABC/MyExn,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class ABC/MyExn>::.ctor(string)
591+
IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class ABC/MyExn,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<!!0,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string>)
592+
IL_000f: ldarg.0
593+
IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class ABC/MyExn,string>::Invoke(!0)
594+
IL_0015: ret
595+
} // end of method MyExn::get_Message
596+
583597
.method public hidebysig virtual instance int32
584598
GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed
585599
{
@@ -1352,6 +1366,20 @@
13521366
IL_0006: ret
13531367
} // end of method MyExn::get_Data0
13541368

1369+
.method public strict virtual instance string
1370+
get_Message() cil managed
1371+
{
1372+
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
1373+
// Code size 22 (0x16)
1374+
.maxstack 8
1375+
IL_0000: ldstr "%+A"
1376+
IL_0005: newobj instance void class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`5<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class ABC/ABC/MyExn,string>,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string,class ABC/ABC/MyExn>::.ctor(string)
1377+
IL_000a: call !!0 [FSharp.Core]Microsoft.FSharp.Core.ExtraTopLevelOperators::PrintFormatToString<class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class ABC/ABC/MyExn,string>>(class [FSharp.Core]Microsoft.FSharp.Core.PrintfFormat`4<!!0,class [FSharp.Core]Microsoft.FSharp.Core.Unit,string,string>)
1378+
IL_000f: ldarg.0
1379+
IL_0010: callvirt instance !1 class [FSharp.Core]Microsoft.FSharp.Core.FSharpFunc`2<class ABC/ABC/MyExn,string>::Invoke(!0)
1380+
IL_0015: ret
1381+
} // end of method MyExn::get_Message
1382+
13551383
.method public hidebysig virtual instance int32
13561384
GetHashCode(class [mscorlib]System.Collections.IEqualityComparer comp) cil managed
13571385
{

0 commit comments

Comments
 (0)