@@ -4371,7 +4371,7 @@ and GenObjectMethod cenv eenvinner (cgbuf: CodeGenBuffer) useMethodImpl tmethod
43714371 GenGenericParams cenv eenvUnderTypars methTyparsOfOverridingMethod,
43724372 ilParamsOfOverridingMethod,
43734373 ilReturnOfOverridingMethod,
4374- MethodBody.IL ilMethodBody)
4374+ MethodBody.IL ( lazy ilMethodBody) )
43754375 // fixup attributes to generate a method impl
43764376 let mdef = if useMethodImpl then fixupMethodImplFlags mdef else mdef
43774377 let mdef = fixupVirtualSlotFlags mdef
@@ -4473,20 +4473,20 @@ and GenSequenceExpr
44734473 CG.EmitInstr cgbuf ( pop ilCloAllFreeVars.Length) ( Push [ ilCloRetTyInner]) ( I_ newobj ( formalClospec.Constructor, None))
44744474 GenSequel cenv eenv.cloc cgbuf Return),
44754475 m)
4476- mkILNonGenericVirtualMethod( " GetFreshEnumerator" , ILMemberAccess.Public, [], mkILReturn ilCloEnumeratorTy, MethodBody.IL mbody)
4476+ mkILNonGenericVirtualMethod( " GetFreshEnumerator" , ILMemberAccess.Public, [], mkILReturn ilCloEnumeratorTy, MethodBody.IL ( lazy mbody) )
44774477 |> AddNonUserCompilerGeneratedAttribs g
44784478
44794479 let closeMethod =
44804480 // Note: We suppress the first sequence point in the body of this method since it is the initial state machine jump
44814481 let spReq = SPSuppress
44824482 let ilCode = CodeGenMethodForExpr cenv cgbuf.mgbuf ( spReq, [], " Close" , eenvinner, 1 , closeExpr, discardAndReturnVoid)
4483- mkILNonGenericVirtualMethod( " Close" , ILMemberAccess.Public, [], mkILReturn ILType.Void, MethodBody.IL ilCode)
4483+ mkILNonGenericVirtualMethod( " Close" , ILMemberAccess.Public, [], mkILReturn ILType.Void, MethodBody.IL ( lazy ilCode) )
44844484
44854485 let checkCloseMethod =
44864486 // Note: We suppress the first sequence point in the body of this method since it is the initial state machine jump
44874487 let spReq = SPSuppress
44884488 let ilCode = CodeGenMethodForExpr cenv cgbuf.mgbuf ( spReq, [], " get_CheckClose" , eenvinner, 1 , checkCloseExpr, Return)
4489- mkILNonGenericVirtualMethod( " get_CheckClose" , ILMemberAccess.Public, [], mkILReturn g.ilg.typ_ Bool, MethodBody.IL ilCode)
4489+ mkILNonGenericVirtualMethod( " get_CheckClose" , ILMemberAccess.Public, [], mkILReturn g.ilg.typ_ Bool, MethodBody.IL ( lazy ilCode) )
44904490
44914491 let generateNextMethod =
44924492 // Note: We suppress the first sequence point in the body of this method since it is the initial state machine jump
@@ -4495,12 +4495,12 @@ and GenSequenceExpr
44954495 let eenvinner = eenvinner |> AddStorageForLocalVals g [ ( nextEnumeratorValRef.Deref, Arg 1 ) ]
44964496 let ilParams = [ mkILParamNamed( " next" , ILType.Byref ilCloEnumerableTy)]
44974497 let ilReturn = mkILReturn g.ilg.typ_ Int32
4498- let ilCode = MethodBody.IL ( CodeGenMethodForExpr cenv cgbuf.mgbuf ( spReq, [], " GenerateNext" , eenvinner, 2 , generateNextExpr, Return))
4498+ let ilCode = MethodBody.IL ( lazy ( CodeGenMethodForExpr cenv cgbuf.mgbuf ( spReq, [], " GenerateNext" , eenvinner, 2 , generateNextExpr, Return) ))
44994499 mkILNonGenericVirtualMethod( " GenerateNext" , ILMemberAccess.Public, ilParams, ilReturn, ilCode)
45004500
45014501 let lastGeneratedMethod =
45024502 let ilCode = CodeGenMethodForExpr cenv cgbuf.mgbuf ( SPSuppress, [], " get_LastGenerated" , eenvinner, 1 , exprForValRef m currvref, Return)
4503- mkILNonGenericVirtualMethod( " get_LastGenerated" , ILMemberAccess.Public, [], mkILReturn ilCloSeqElemTy, MethodBody.IL ilCode)
4503+ mkILNonGenericVirtualMethod( " get_LastGenerated" , ILMemberAccess.Public, [], mkILReturn ilCloSeqElemTy, MethodBody.IL ( lazy ilCode) )
45044504 |> AddNonUserCompilerGeneratedAttribs g
45054505
45064506 let ilCtorBody =
@@ -4543,7 +4543,7 @@ and GenClosureTypeDefs cenv (tref: ILTypeRef, ilGenParams, attrs, ilCloAllFreeVa
45434543 let fspec = mkILFieldSpec ( cloSpec.GetStaticFieldSpec() .FieldRef, cloTy)
45444544 let ctorSpec = mkILMethSpecForMethRefInTy ( cloSpec.Constructor.MethodRef, cloTy, [])
45454545 let ilCode = mkILMethodBody ( true , [], 8 , nonBranchingInstrsToCode ([ I_ newobj ( ctorSpec, None); mkNormalStsfld fspec ]), None)
4546- let cctor = mkILClassCtor ( MethodBody.IL ilCode)
4546+ let cctor = mkILClassCtor ( MethodBody.IL ( lazy ilCode) )
45474547 let ilFieldDef = mkILStaticField( fspec.Name, fspec.FormalType, None, None, ILMemberAccess.Assembly) .WithInitOnly( true )
45484548 ( cctor :: mdefs), [ ilFieldDef ]
45494549 else
@@ -4642,7 +4642,7 @@ and GenLambdaClosure cenv (cgbuf: CodeGenBuffer) eenv isLocalTypeFunc thisVars e
46424642 cgbuf.mgbuf.AddTypeDef( ilContractTypeRef, ilContractTypeDef, false , false , None)
46434643
46444644 let ilCtorBody = mkILMethodBody ( true , [], 8 , nonBranchingInstrsToCode ( mkCallBaseConstructor( ilContractTy, [])), None )
4645- let cloMethods = [ mkILGenericVirtualMethod( " DirectInvoke" , ILMemberAccess.Assembly, cloinfo.localTypeFuncDirectILGenericParams, [], mkILReturn ( cloinfo.ilCloFormalReturnTy), MethodBody.IL ilCloBody) ]
4645+ let cloMethods = [ mkILGenericVirtualMethod( " DirectInvoke" , ILMemberAccess.Assembly, cloinfo.localTypeFuncDirectILGenericParams, [], mkILReturn ( cloinfo.ilCloFormalReturnTy), MethodBody.IL( lazy ilCloBody) ) ]
46464646 let cloTypeDefs = GenClosureTypeDefs cenv ( ilCloTypeRef, cloinfo.cloILGenericParams, [], cloinfo.ilCloAllFreeVars, cloinfo.ilCloLambdas, ilCtorBody, cloMethods, [], ilContractTy, [], Some cloinfo.cloSpec)
46474647 cloTypeDefs
46484648
@@ -5039,7 +5039,7 @@ and GenDelegateExpr cenv cgbuf eenvouter expr (TObjExprMethod((TSlotSig(_, deleg
50395039 ILMemberAccess.Assembly,
50405040 ilDelegeeParams,
50415041 ilDelegeeRet,
5042- MethodBody.IL ilMethodBody)
5042+ MethodBody.IL( lazy ilMethodBody) )
50435043 let delegeeCtorMeth = mkILSimpleStorageCtor( None, Some g.ilg.typ_ Object.TypeSpec, ilDelegeeTyInner, [], [], ILMemberAccess.Assembly)
50445044 let ilCtorBody = delegeeCtorMeth.MethodBody
50455045
@@ -5616,8 +5616,7 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv sp (TBind(vspec, rhsExpr, _)) star
56165616
56175617 CommitStartScope cgbuf startScopeMarkOpt
56185618
5619- // if we have any expression recursion depth, we should delay the generation of a method to prevent stack overflows
5620- let generator = if cenv.exprRecursionDepth > 0 then DelayGenMethodForBinding else GenMethodForBinding
5619+ let generator = GenMethodForBinding
56215620 let hasWitnessEntry = cenv.g.generateWitnesses && not witnessInfos.IsEmpty
56225621
56235622 generator cenv cgbuf.mgbuf eenv ( vspec, mspec, hasWitnessEntry, false , access, ctps, mtps, [], curriedArgInfos, paramInfos, argTys, retInfo, topValInfo, methLambdaCtorThisValOpt, methLambdaBaseValOpt, methLambdaTypars, methLambdaVars, methLambdaBody, methLambdaBodyTy)
@@ -5645,7 +5644,8 @@ and GenBindingAfterDebugPoint cenv cgbuf eenv sp (TBind(vspec, rhsExpr, _)) star
56455644 cgbuf.mgbuf.AddOrMergePropertyDef( ilGetterMethSpec.MethodRef.DeclaringTypeRef, ilPropDef, m)
56465645
56475646 let ilMethodDef =
5648- let ilMethodBody = MethodBody.IL( CodeGenMethodForExpr cenv cgbuf.mgbuf ( SPSuppress, [], ilGetterMethSpec.Name, eenv, 0 , rhsExpr, Return))
5647+ let ilCode = CodeGenMethodForExpr cenv cgbuf.mgbuf ( SPSuppress, [], ilGetterMethSpec.Name, eenv, 0 , rhsExpr, Return)
5648+ let ilMethodBody = MethodBody.IL( lazy ilCode)
56495649 ( mkILStaticMethod ([], ilGetterMethSpec.Name, access, [], mkILReturn ilTy, ilMethodBody)) .WithSpecialName
56505650 |> AddNonUserCompilerGeneratedAttribs g
56515651
@@ -6188,10 +6188,20 @@ and GenMethodForBinding
61886188 else
61896189 body
61906190
6191- let ilCode = CodeGenMethodForExpr cenv mgbuf ( SPAlways, tailCallInfo, mspec.Name, eenvForMeth, 0 , bodyExpr, sequel)
6191+ let ilCodeLazy = lazy CodeGenMethodForExpr cenv mgbuf ( SPAlways, tailCallInfo, mspec.Name, eenvForMeth, 0 , bodyExpr, sequel)
61926192
61936193 // This is the main code generation for most methods
6194- false , MethodBody.IL ilCode, false
6194+ false , MethodBody.IL( ilCodeLazy), false
6195+
6196+ match ilMethodBody with
6197+ | MethodBody.IL( ilCodeLazy) ->
6198+ if cenv.exprRecursionDepth > 0 then
6199+ cenv.delayedGenMethods.Enqueue( fun _ -> ilCodeLazy.Force() |> ignore)
6200+ else
6201+ // Eagerly codegen if we are not in an expression depth.
6202+ ilCodeLazy.Force() |> ignore
6203+ | _ ->
6204+ ()
61956205
61966206 // Do not generate DllImport attributes into the code - they are implicit from the P/Invoke
61976207 let attrs =
@@ -6396,7 +6406,7 @@ and GenPInvokeMethod (nm, dll, namedArgs) =
63966406
63976407 let hasPreserveSigNamedArg = decoder.FindBool " PreserveSig" true
63986408 hasPreserveSigNamedArg,
6399- MethodBody.PInvoke
6409+ let pinvoke =
64006410 { Where= mkSimpleModRef dll
64016411 Name= decoder.FindString " EntryPoint" nm
64026412 CallingConv=
@@ -6417,7 +6427,8 @@ and GenPInvokeMethod (nm, dll, namedArgs) =
64176427 NoMangle= decoder.FindBool " ExactSpelling" false
64186428 LastError= decoder.FindBool " SetLastError" false
64196429 ThrowOnUnmappableChar= if ( decoder.FindBool " ThrowOnUnmappableChar" false ) then PInvokeThrowOnUnmappableChar.Enabled else PInvokeThrowOnUnmappableChar.UseAssembly
6420- CharBestFit= if ( decoder.FindBool " BestFitMapping" false ) then PInvokeCharBestFit.Enabled else PInvokeCharBestFit.UseAssembly }
6430+ CharBestFit= if ( decoder.FindBool " BestFitMapping" false ) then PInvokeCharBestFit.Enabled else PInvokeCharBestFit.UseAssembly } : PInvokeMethod
6431+ MethodBody.PInvoke( lazy pinvoke)
64216432
64226433and GenBindings cenv cgbuf eenv binds = List.iter ( GenBinding cenv cgbuf eenv) binds
64236434
@@ -7033,7 +7044,7 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: TypedI
70337044 // This adds the explicit init of the .cctor to the explicit entry point main method
70347045 mgbuf.AddExplicitInitToSpecificMethodDef(( fun md -> md.IsEntryPoint), tref, fspec, GenPossibleILSourceMarker cenv m, feefee, seqpt))
70357046
7036- let cctorMethDef = mkILClassCtor ( MethodBody.IL topCode)
7047+ let cctorMethDef = mkILClassCtor ( MethodBody.IL ( lazy topCode) )
70377048 mgbuf.AddMethodDef( initClassTy.TypeRef, cctorMethDef)
70387049
70397050 // Final file, implicit entry point. We generate no .cctor.
@@ -7048,7 +7059,7 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: TypedI
70487059
70497060 // generate main@
70507061 let ilMainMethodDef =
7051- let mdef = mkILNonGenericStaticMethod( mainMethName, ILMemberAccess.Public, [], mkILReturn ILType.Void, MethodBody.IL topCode)
7062+ let mdef = mkILNonGenericStaticMethod( mainMethName, ILMemberAccess.Public, [], mkILReturn ILType.Void, MethodBody.IL ( lazy topCode) )
70527063 mdef.With( isEntryPoint= true , customAttrs = ilAttrs)
70537064
70547065 mgbuf.AddMethodDef( initClassTy.TypeRef, ilMainMethodDef)
@@ -7058,7 +7069,7 @@ and GenImplFile cenv (mgbuf: AssemblyBuilder) mainInfoOpt eenv (implFile: TypedI
70587069 | None ->
70597070 if doesSomething then
70607071 // Add the cctor
7061- let cctorMethDef = mkILClassCtor ( MethodBody.IL topCode)
7072+ let cctorMethDef = mkILClassCtor ( MethodBody.IL ( lazy topCode) )
70627073 mgbuf.AddMethodDef( initClassTy.TypeRef, cctorMethDef)
70637074
70647075 // Commit the directed initializations
0 commit comments