@@ -217,6 +217,18 @@ public override (string managed, string native) GetIdentifiers(TypePositionInfo
217217
218218 public BlockSyntax GeneratePInvokeBody ( string dllImportName )
219219 {
220+ bool invokeReturnsVoid = _retMarshaller . TypeInfo . ManagedType == SpecialTypeInfo . Void ;
221+
222+ // Handle GuaranteedUnmarshal and Cleanup first since whether or not those stages produce statements affects multiple other stages.
223+ var guaranteedUnmarshalStatements = new List < StatementSyntax > ( ) ;
224+ GenerateStatementsForStage ( Stage . GuaranteedUnmarshal , guaranteedUnmarshalStatements ) ;
225+ bool hasGuaranteedUnmarshalStatements = guaranteedUnmarshalStatements . Count > 0 ;
226+
227+ var cleanupStatements = new List < StatementSyntax > ( ) ;
228+ GenerateStatementsForStage ( Stage . Cleanup , cleanupStatements ) ;
229+
230+ bool shouldInitializeVariables = hasGuaranteedUnmarshalStatements || cleanupStatements . Count > 0 ;
231+
220232 var setupStatements = new List < StatementSyntax > ( ) ;
221233
222234 foreach ( BoundGenerator marshaller in _paramMarshallers )
@@ -238,11 +250,9 @@ public BlockSyntax GeneratePInvokeBody(string dllImportName)
238250 }
239251
240252 // Declare variables for parameters
241- AppendVariableDeclations ( setupStatements , info , marshaller . Generator ) ;
253+ AppendVariableDeclations ( setupStatements , info , marshaller . Generator , initializeToDefault : shouldInitializeVariables ) ;
242254 }
243255
244- bool invokeReturnsVoid = _retMarshaller . TypeInfo . ManagedType == SpecialTypeInfo . Void ;
245-
246256 // Stub return is not the same as invoke return
247257 if ( ! _stubReturnsVoid && ! _retMarshaller . TypeInfo . IsManagedReturnPosition )
248258 {
@@ -252,47 +262,41 @@ public BlockSyntax GeneratePInvokeBody(string dllImportName)
252262 ( TypePositionInfo stubRetTypeInfo , IMarshallingGenerator stubRetGenerator ) = _paramMarshallers . Last ( ) ;
253263
254264 // Declare variables for stub return value
255- AppendVariableDeclations ( setupStatements , stubRetTypeInfo , stubRetGenerator ) ;
265+ AppendVariableDeclations ( setupStatements , stubRetTypeInfo , stubRetGenerator , initializeToDefault : shouldInitializeVariables ) ;
256266 }
257267
258268 if ( ! invokeReturnsVoid )
259269 {
260270 // Declare variables for invoke return value
261- AppendVariableDeclations ( setupStatements , _retMarshaller . TypeInfo , _retMarshaller . Generator ) ;
271+ AppendVariableDeclations ( setupStatements , _retMarshaller . TypeInfo , _retMarshaller . Generator , initializeToDefault : shouldInitializeVariables ) ;
262272 }
263273
264- // Do not manually handle SetLastError when generating forwarders.
265- // We want the runtime to handle everything.
266274 if ( _setLastError )
267275 {
268276 // Declare variable for last error
269- setupStatements . Add ( MarshallerHelpers . DeclareWithDefault (
277+ setupStatements . Add ( MarshallerHelpers . Declare (
270278 PredefinedType ( Token ( SyntaxKind . IntKeyword ) ) ,
271- LastErrorIdentifier ) ) ;
279+ LastErrorIdentifier ,
280+ initializeToDefault : false ) ) ;
272281 }
273282
274- var tryStatements = new List < StatementSyntax > ( ) ;
275- var guaranteedUnmarshalStatements = new List < StatementSyntax > ( ) ;
276- var cleanupStatements = new List < StatementSyntax > ( ) ;
277- InvocationExpressionSyntax invoke = InvocationExpression ( IdentifierName ( dllImportName ) ) ;
278-
279- // Handle GuaranteedUnmarshal first since that stage producing statements affects multiple other stages.
280- GenerateStatementsForStage ( Stage . GuaranteedUnmarshal , guaranteedUnmarshalStatements ) ;
281- if ( guaranteedUnmarshalStatements . Count > 0 )
283+ if ( hasGuaranteedUnmarshalStatements )
282284 {
283- setupStatements . Add ( MarshallerHelpers . DeclareWithDefault ( PredefinedType ( Token ( SyntaxKind . BoolKeyword ) ) , InvokeSucceededIdentifier ) ) ;
285+ setupStatements . Add ( MarshallerHelpers . Declare ( PredefinedType ( Token ( SyntaxKind . BoolKeyword ) ) , InvokeSucceededIdentifier , initializeToDefault : true ) ) ;
284286 }
285287
288+ var tryStatements = new List < StatementSyntax > ( ) ;
289+ InvocationExpressionSyntax invoke = InvocationExpression ( IdentifierName ( dllImportName ) ) ;
290+
286291 GenerateStatementsForStage ( Stage . Setup , setupStatements ) ;
287292 GenerateStatementsForStage ( Stage . Marshal , tryStatements ) ;
288293 GenerateStatementsForInvoke ( tryStatements , invoke ) ;
289294 GenerateStatementsForStage ( Stage . KeepAlive , tryStatements ) ;
290295 GenerateStatementsForStage ( Stage . Unmarshal , tryStatements ) ;
291- GenerateStatementsForStage ( Stage . Cleanup , cleanupStatements ) ;
292296
293297 List < StatementSyntax > allStatements = setupStatements ;
294298 List < StatementSyntax > finallyStatements = new List < StatementSyntax > ( ) ;
295- if ( guaranteedUnmarshalStatements . Count > 0 )
299+ if ( hasGuaranteedUnmarshalStatements )
296300 {
297301 finallyStatements . Add ( IfStatement ( IdentifierName ( InvokeSucceededIdentifier ) , Block ( guaranteedUnmarshalStatements ) ) ) ;
298302 }
@@ -477,24 +481,26 @@ _retMarshaller.Generator is IAttributedReturnTypeMarshallingGenerator attributed
477481 ) ;
478482 }
479483
480- private void AppendVariableDeclations ( List < StatementSyntax > statementsToUpdate , TypePositionInfo info , IMarshallingGenerator generator )
484+ private void AppendVariableDeclations ( List < StatementSyntax > statementsToUpdate , TypePositionInfo info , IMarshallingGenerator generator , bool initializeToDefault )
481485 {
482486 ( string managed , string native ) = GetIdentifiers ( info ) ;
483487
484488 // Declare variable for return value
485489 if ( info . IsManagedReturnPosition || info . IsNativeReturnPosition )
486490 {
487- statementsToUpdate . Add ( MarshallerHelpers . DeclareWithDefault (
491+ statementsToUpdate . Add ( MarshallerHelpers . Declare (
488492 info . ManagedType . Syntax ,
489- managed ) ) ;
493+ managed ,
494+ false ) ) ;
490495 }
491496
492497 // Declare variable with native type for parameter or return value
493498 if ( generator . UsesNativeIdentifier ( info , this ) )
494499 {
495- statementsToUpdate . Add ( MarshallerHelpers . DeclareWithDefault (
500+ statementsToUpdate . Add ( MarshallerHelpers . Declare (
496501 generator . AsNativeType ( info ) ,
497- native ) ) ;
502+ native ,
503+ initializeToDefault ) ) ;
498504 }
499505 }
500506 }
0 commit comments