@@ -275,6 +275,19 @@ namespace ProviderImplementation.ProvidedTypes
275
275
let canBindNestedType (bindingFlags: BindingFlags) (c: Type) =
276
276
hasFlag bindingFlags BindingFlags.Public && c.IsNestedPublic || hasFlag bindingFlags BindingFlags.NonPublic && not c.IsNestedPublic
277
277
278
+ // We only want to return source types "typeof<Void>" values as _target_ types in one very specific location due to a limitation in the
279
+ // F# compiler code for multi-targeting.
280
+ let ImportProvidedMethodBaseAsILMethodRef_OnStack_HACK() =
281
+ let rec loop i =
282
+ if i > 9 then
283
+ false
284
+ else
285
+ let frame = StackFrame(i, true)
286
+ match frame.GetMethod() with
287
+ | null -> loop (i+1)
288
+ | m -> m.Name = "ImportProvidedMethodBaseAsILMethodRef" || loop (i+1)
289
+ loop 1
290
+
278
291
//--------------------------------------------------------------------------------
279
292
// UncheckedQuotations
280
293
@@ -1039,17 +1052,36 @@ namespace ProviderImplementation.ProvidedTypes
1039
1052
1040
1053
// Implement overloads
1041
1054
override __.GetParameters() = parameterInfos
1055
+
1042
1056
override __.Attributes = attrs
1057
+
1043
1058
override __.Name = methodName
1059
+
1044
1060
override __.DeclaringType = declaringType |> nonNone "DeclaringType" :> Type
1061
+
1045
1062
override __.IsDefined(_attributeType, _inherit): bool = true
1063
+
1046
1064
override __.MemberType = MemberTypes.Method
1065
+
1047
1066
override x.CallingConvention =
1048
1067
let cc = CallingConventions.Standard
1049
1068
let cc = if not x.IsStatic then cc ||| CallingConventions.HasThis else cc
1050
1069
cc
1051
- override __.ReturnType = returnType
1070
+
1071
+ override __.ReturnType =
1072
+ if isTgt then
1073
+ match returnType.Namespace, returnType.Name with
1074
+ | "System", "Void"->
1075
+ if ImportProvidedMethodBaseAsILMethodRef_OnStack_HACK() then
1076
+ typeof<Void>
1077
+ else
1078
+ returnType
1079
+ | _ -> returnType
1080
+ else
1081
+ returnType
1082
+
1052
1083
override __.ReturnParameter = null // REVIEW: Give it a name and type?
1084
+
1053
1085
override __.ToString() = "Method " + methodName
1054
1086
1055
1087
// These don't have to return fully accurate results - they are used
@@ -3049,6 +3081,7 @@ namespace ProviderImplementation.ProvidedTypes.AssemblyReader
3049
3081
type ILGlobals =
3050
3082
{ typ_Object: ILType
3051
3083
typ_String: ILType
3084
+ typ_Void: ILType
3052
3085
typ_Type: ILType
3053
3086
typ_TypedReference: ILType option
3054
3087
typ_SByte: ILType
@@ -4537,6 +4570,7 @@ namespace ProviderImplementation.ProvidedTypes.AssemblyReader
4537
4570
let mkILTyspec nsp nm = mkILNonGenericTySpec(ILTypeRef(ILTypeRefScope.Top(systemRuntimeScopeRef),USome nsp,nm))
4538
4571
{ typ_Object = ILType.Boxed (mkILTyspec "System" "Object")
4539
4572
typ_String = ILType.Boxed (mkILTyspec "System" "String")
4573
+ typ_Void = ILType.Value (mkILTyspec "System" "Void")
4540
4574
typ_Type = ILType.Boxed (mkILTyspec "System" "Type")
4541
4575
typ_Int64 = ILType.Value (mkILTyspec "System" "Int64")
4542
4576
typ_UInt64 = ILType.Value (mkILTyspec "System" "UInt64")
@@ -7465,7 +7499,17 @@ namespace ProviderImplementation.ProvidedTypes
7465
7499
override __.Attributes = inp.Attributes
7466
7500
override __.GetParameters() = inp.Parameters |> Array.map (txILParameter (gps, gps2))
7467
7501
override __.CallingConvention = if inp.IsStatic then CallingConventions.Standard else CallingConventions.HasThis ||| CallingConventions.Standard
7468
- override __.ReturnType = inp.Return.Type |> txILType (gps, gps2)
7502
+
7503
+ override __.ReturnType =
7504
+ let returnType = inp.Return.Type |> txILType (gps, gps2)
7505
+ match returnType.Namespace, returnType.Name with
7506
+ | "System", "Void"->
7507
+ if ImportProvidedMethodBaseAsILMethodRef_OnStack_HACK() then
7508
+ typeof<Void>
7509
+ else
7510
+ returnType
7511
+ | t -> returnType
7512
+
7469
7513
override __.GetCustomAttributesData() = inp.CustomAttrs |> txCustomAttributesData
7470
7514
override __.GetGenericArguments() = gps2
7471
7515
override __.IsGenericMethod = (gps2.Length <> 0)
@@ -7629,7 +7673,7 @@ namespace ProviderImplementation.ProvidedTypes
7629
7673
and txILType gps (ty: ILType) =
7630
7674
7631
7675
match ty with
7632
- | ILType.Void -> typeof<System.Void>
7676
+ | ILType.Void -> txILType gps ilGlobals.typ_Void
7633
7677
| ILType.Value tspec
7634
7678
| ILType.Boxed tspec ->
7635
7679
let tdefR = txILTypeRef tspec.TypeRef
@@ -7855,7 +7899,7 @@ namespace ProviderImplementation.ProvidedTypes
7855
7899
// https://github.com/Microsoft/visualfsharp/blob/44fa027b308681a1b78a089e44fa1ab35ff77b41/src/fsharp/MethodCalls.fs#L842
7856
7900
// for the accepted types.
7857
7901
match inp.Namespace, inp.Name with
7858
- | USome "System", "Void"-> typeof<Void>
7902
+ // | USome "System", "Void"-> typeof<Void>
7859
7903
(*
7860
7904
| USome "System", "Boolean" -> typeof<bool>
7861
7905
| USome "System", "String"-> typeof<string>
@@ -8835,6 +8879,12 @@ namespace ProviderImplementation.ProvidedTypes
8835
8879
Expr.NewObjectUnchecked (convConstructorRefToTgt c, exprsR)
8836
8880
| Coerce (expr, t) ->
8837
8881
Expr.Coerce (convExprToTgt expr, convTypeToTgt t)
8882
+ | TypeTest (expr, t) ->
8883
+ Expr.TypeTest (convExprToTgt expr, convTypeToTgt t)
8884
+ | TryWith (body, filterVar, filterBody, catchVar, catchBody) ->
8885
+ Expr.TryWith (convExprToTgt body, convVarToTgt filterVar, convExprToTgt filterBody, convVarToTgt catchVar, convExprToTgt catchBody)
8886
+ | TryFinally (body, compensation) ->
8887
+ Expr.TryFinally (convExprToTgt body, convExprToTgt compensation)
8838
8888
| NewArray (t, exprs) ->
8839
8889
Expr.NewArrayUnchecked (convTypeToTgt t, List.map convExprToTgt exprs)
8840
8890
| NewTuple (exprs) ->
@@ -13260,8 +13310,9 @@ namespace ProviderImplementation.ProvidedTypes
13260
13310
| FilterCatch of ILCodeLabel * (ILCodeLabel * ILCodeLabel)
13261
13311
| TypeCatch of ILCodeLabel * ILType
13262
13312
13263
- type ILExceptionBlockBuilder(i: ILCodeLabel) =
13313
+ type ILExceptionBlockBuilder(i: ILCodeLabel, leave: ILCodeLabel ) =
13264
13314
member __.StartIndex = i
13315
+ member __.Leave = leave
13265
13316
member val EndIndex : int = 0 with get, set
13266
13317
member val Clause : ILExceptionClauseBuilder option = None with get, set
13267
13318
@@ -13291,10 +13342,12 @@ namespace ProviderImplementation.ProvidedTypes
13291
13342
ILLocalBuilder(idx)
13292
13343
13293
13344
member ilg.BeginExceptionBlock() =
13294
- exceptionBlocks.Push(ILExceptionBlockBuilder(ilg.DefineLabelHere()))
13345
+ exceptionBlocks.Push(ILExceptionBlockBuilder(ilg.DefineLabelHere(), ilg.DefineLabel() ))
13295
13346
13296
13347
member ilg.EndGuardedBlock() =
13297
- exceptionBlocks.Peek().EndIndex <- ilg.DefineLabelHere()
13348
+ let block = exceptionBlocks.Peek()
13349
+ ilg.Emit(I_leave block.Leave)
13350
+ block.EndIndex <- ilg.DefineLabelHere()
13298
13351
13299
13352
member ilg.BeginCatchBlock(typ: ILType) =
13300
13353
exceptionBlocks.Peek().Clause <- Some <|
@@ -13314,7 +13367,17 @@ namespace ProviderImplementation.ProvidedTypes
13314
13367
13315
13368
member ilg.EndExceptionBlock() =
13316
13369
let exnBlock = exceptionBlocks.Pop()
13370
+ match exnBlock.Clause.Value with
13371
+ | ILExceptionClauseBuilder.Finally(start) ->
13372
+ ilg.Emit(I_endfinally)
13373
+ | ILExceptionClauseBuilder.Fault(start) ->
13374
+ ilg.Emit(I_endfinally)
13375
+ | ILExceptionClauseBuilder.FilterCatch _ ->
13376
+ ilg.Emit(I_leave exnBlock.Leave)
13377
+ | ILExceptionClauseBuilder.TypeCatch _ ->
13378
+ ilg.Emit(I_leave exnBlock.Leave)
13317
13379
let endIndex = ilg.DefineLabelHere()
13380
+ ilg.MarkLabel(exnBlock.Leave)
13318
13381
let clause =
13319
13382
match exnBlock.Clause.Value with
13320
13383
| ILExceptionClauseBuilder.Finally(start) ->
0 commit comments