@@ -6450,7 +6450,7 @@ and GenObjectExpr cenv cgbuf eenvouter objExpr (baseType, baseValOpt, basecall,
64506450 GenWitnessArgsFromWitnessInfos cenv cgbuf eenvouter m cloinfo.cloWitnessInfos
64516451
64526452 for fv in cloinfo.cloFreeVars do
6453- GenGetLocalVal cenv cgbuf eenvouter m fv None
6453+ GenGetFreeVarForClosure cenv cgbuf eenvouter m fv
64546454
64556455 CG.EmitInstr
64566456 cgbuf
@@ -6541,7 +6541,7 @@ and GenSequenceExpr
65416541 if stateVarsSet.Contains fv then
65426542 GenDefaultValue cenv cgbuf eenv (fv.Type, m)
65436543 else
6544- GenGetLocalVal cenv cgbuf eenv m fv None
6544+ GenGetFreeVarForClosure cenv cgbuf eenv m fv
65456545
65466546 CG.EmitInstr
65476547 cgbuf
@@ -6653,7 +6653,7 @@ and GenSequenceExpr
66536653 if stateVarsSet.Contains fv then
66546654 GenDefaultValue cenv cgbuf eenvouter (fv.Type, m)
66556655 else
6656- GenGetLocalVal cenv cgbuf eenvouter m fv None
6656+ GenGetFreeVarForClosure cenv cgbuf eenvouter m fv
66576657
66586658 CG.EmitInstr cgbuf (pop ilCloAllFreeVars.Length) (Push [ ilCloRetTyOuter ]) (I_newobj(ilxCloSpec.Constructor, None))
66596659 GenSequel cenv eenvouter.cloc cgbuf sequel
@@ -6886,7 +6886,9 @@ and GenClosureAlloc cenv (cgbuf: CodeGenBuffer) eenv (cloinfo, m) =
68866886 CG.EmitInstr cgbuf (pop 0) (Push [ EraseClosures.mkTyOfLambdas cenv.ilxPubCloEnv cloinfo.ilCloLambdas ]) (mkNormalLdsfld fspec)
68876887 else
68886888 GenWitnessArgsFromWitnessInfos cenv cgbuf eenv m cloinfo.cloWitnessInfos
6889- GenGetLocalVals cenv cgbuf eenv m cloinfo.cloFreeVars
6889+
6890+ for fv in cloinfo.cloFreeVars do
6891+ GenGetFreeVarForClosure cenv cgbuf eenv m fv
68906892
68916893 CG.EmitInstr
68926894 cgbuf
@@ -6901,6 +6903,12 @@ and GenLambda cenv cgbuf eenv isLocalTypeFunc thisVars expr sequel =
69016903
69026904and GenTypeOfVal cenv eenv (v: Val) = GenType cenv v.Range eenv.tyenv v.Type
69036905
6906+ and capturedTypeForFreeVar (g: TcGlobals) (fv: Val) =
6907+ if isByrefTy g fv.Type then
6908+ destByrefTy g fv.Type
6909+ else
6910+ fv.Type
6911+
69046912and GenFreevar cenv m eenvouter tyenvinner (fv: Val) =
69056913 let g = cenv.g
69066914
@@ -6915,7 +6923,7 @@ and GenFreevar cenv m eenvouter tyenvinner (fv: Val) =
69156923 | Method _
69166924 | Null -> error (InternalError("GenFreevar: compiler error: unexpected unrealized value", fv.Range))
69176925#endif
6918- | _ -> GenType cenv m tyenvinner fv.Type
6926+ | _ -> GenType cenv m tyenvinner (capturedTypeForFreeVar g fv)
69196927
69206928and GetIlxClosureFreeVars cenv m (thisVars: ValRef list) boxity eenv takenNames expr =
69216929 let g = cenv.g
@@ -7276,7 +7284,9 @@ and GenDelegateExpr cenv cgbuf eenvouter expr (TObjExprMethod(slotsig, _attribs,
72767284 IlxClosureSpec.Create(IlxClosureRef(ilDelegeeTypeRef, ilCloLambdas, ilCloAllFreeVars), ctxtGenericArgsForDelegee, false)
72777285
72787286 GenWitnessArgsFromWitnessInfos cenv cgbuf eenvouter m cloWitnessInfos
7279- GenGetLocalVals cenv cgbuf eenvouter m cloFreeVars
7287+
7288+ for fv in cloFreeVars do
7289+ GenGetFreeVarForClosure cenv cgbuf eenvouter m fv
72807290
72817291 CG.EmitInstr
72827292 cgbuf
@@ -8206,6 +8216,17 @@ and GenLetRecFixup cenv cgbuf eenv (ilxCloSpec: IlxClosureSpec, e, ilField: ILFi
82068216 GenExpr cenv cgbuf eenv e2 Continue
82078217 CG.EmitInstr cgbuf (pop 2) Push0 (mkNormalStfld (mkILFieldSpec (ilField.FieldRef, ilxCloSpec.ILType)))
82088218
8219+ and isLambdaBinding (TBind(_, expr, _)) =
8220+ match stripDebugPoints expr with
8221+ | Expr.Lambda _
8222+ | Expr.TyLambda _
8223+ | Expr.Obj _ -> true
8224+ | _ -> false
8225+
8226+ and reorderBindingsLambdasFirst binds =
8227+ let lambdas, nonLambdas = binds |> List.partition isLambdaBinding
8228+ lambdas @ nonLambdas
8229+
82098230/// Generate letrec bindings
82108231and GenLetRecBindings cenv (cgbuf: CodeGenBuffer) eenv (allBinds: Bindings, m) (dict: Dictionary<Stamp, ILTypeRef> option) =
82118232
@@ -8299,8 +8320,11 @@ and GenLetRecBindings cenv (cgbuf: CodeGenBuffer) eenv (allBinds: Bindings, m) (
82998320 let recursiveVars =
83008321 Zset.addList (bindsPossiblyRequiringFixup |> List.map (fun v -> v.Var)) (Zset.empty valOrder)
83018322
8323+ let reorderedBindsPossiblyRequiringFixup =
8324+ reorderBindingsLambdasFirst bindsPossiblyRequiringFixup
8325+
83028326 let _ =
8303- (recursiveVars, bindsPossiblyRequiringFixup )
8327+ (recursiveVars, reorderedBindsPossiblyRequiringFixup )
83048328 ||> List.fold (fun forwardReferenceSet (bind: Binding) ->
83058329 // Compute fixups
83068330 bind.Expr
@@ -8344,6 +8368,8 @@ and GenLetRecBindings cenv (cgbuf: CodeGenBuffer) eenv (allBinds: Bindings, m) (
83448368 let _ =
83458369 (recursiveVars, groupBinds)
83468370 ||> List.fold (fun forwardReferenceSet (binds: Binding list) ->
8371+ let binds = reorderBindingsLambdasFirst binds
8372+
83478373 match dict, cenv.g.realsig, binds with
83488374 | _, false, _
83498375 | None, _, _
@@ -8380,8 +8406,11 @@ and GenLetRecBindings cenv (cgbuf: CodeGenBuffer) eenv (allBinds: Bindings, m) (
83808406
83818407and GenLetRec cenv cgbuf eenv (binds, body, m) sequel =
83828408 let _, endMark as scopeMarks = StartLocalScope "letrec" cgbuf
8383- let eenv = AllocStorageForBinds cenv cgbuf scopeMarks eenv binds
8384- GenLetRecBindings cenv cgbuf eenv (binds, m) None
8409+
8410+ let reorderedBinds = reorderBindingsLambdasFirst binds
8411+
8412+ let eenv = AllocStorageForBinds cenv cgbuf scopeMarks eenv reorderedBinds
8413+ GenLetRecBindings cenv cgbuf eenv (reorderedBinds, m) None
83858414 GenExpr cenv cgbuf eenv body (EndLocalScope(sequel, endMark))
83868415
83878416//-------------------------------------------------------------------------
@@ -9850,8 +9879,14 @@ and GenGetStorageAndSequel (cenv: cenv) cgbuf eenv m (ty, ilTy) storage storeSeq
98509879 CG.EmitInstrs cgbuf (pop 0) (Push [ ilTy ]) [ mkLdarg0; mkNormalLdfld ilField ]
98519880 CommitGetStorageSequel cenv cgbuf eenv m ty localCloInfo storeSequel
98529881
9853- and GenGetLocalVals cenv cgbuf eenvouter m fvs =
9854- List.iter (fun v -> GenGetLocalVal cenv cgbuf eenvouter m v None) fvs
9882+ /// Load free variables for closure capture, dereferencing byrefs.
9883+ and GenGetFreeVarForClosure cenv cgbuf eenv m (fv: Val) =
9884+ let g = cenv.g
9885+ GenGetLocalVal cenv cgbuf eenv m fv None
9886+
9887+ if isByrefTy g fv.Type then
9888+ let ilUnderlyingTy = GenType cenv m eenv.tyenv (capturedTypeForFreeVar g fv)
9889+ CG.EmitInstr cgbuf (pop 1) (Push [ ilUnderlyingTy ]) (mkNormalLdobj ilUnderlyingTy)
98559890
98569891and GenGetLocalVal cenv cgbuf eenv m (vspec: Val) storeSequel =
98579892 GenGetStorageAndSequel cenv cgbuf eenv m (vspec.Type, GenTypeOfVal cenv eenv vspec) (StorageForVal m vspec eenv) storeSequel
0 commit comments