@@ -139,44 +139,7 @@ protected override MethodEmitter BuildProxiedMethodBody(MethodEmitter emitter, C
139139 emitter . CodeBuilder . AddStatement ( EndExceptionBlockStatement . Instance ) ;
140140 }
141141
142- if ( MethodToOverride . ReturnType != typeof ( void ) )
143- {
144- IExpression retVal ;
145-
146- #if FEATURE_BYREFLIKE
147- if ( emitter . ReturnType . IsByRefLikeSafe ( ) )
148- {
149- // The return value in the `ReturnValue` property is an `object`
150- // and cannot be converted back to the original by-ref-like return type.
151- // We need to replace it with some other value.
152-
153- // For now, we just substitute the by-ref-like type's default value:
154- retVal = new DefaultValueExpression ( emitter . ReturnType ) ;
155- }
156- else
157- #endif
158- {
159- retVal = new MethodInvocationExpression ( invocationLocal , InvocationMethods . GetReturnValue ) ;
160-
161- // Emit code to ensure a value type return type is not null, otherwise the cast will cause a null-deref
162- if ( emitter . ReturnType . IsValueType && ! emitter . ReturnType . IsNullableType ( ) )
163- {
164- LocalReference returnValue = emitter . CodeBuilder . DeclareLocal ( typeof ( object ) ) ;
165- emitter . CodeBuilder . AddStatement ( new AssignStatement ( returnValue , retVal ) ) ;
166-
167- emitter . CodeBuilder . AddStatement ( new IfNullExpression ( returnValue , new ThrowStatement ( typeof ( InvalidOperationException ) ,
168- "Interceptors failed to set a return value, or swallowed the exception thrown by the target" ) ) ) ;
169- }
170-
171- retVal = new ConvertExpression ( emitter . ReturnType , retVal ) ;
172- }
173-
174- emitter . CodeBuilder . AddStatement ( new ReturnStatement ( retVal ) ) ;
175- }
176- else
177- {
178- emitter . CodeBuilder . AddStatement ( ReturnStatement . Instance ) ;
179- }
142+ argumentsMarshaller . Return ( invocationLocal ) ;
180143
181144 return emitter ;
182145 }
@@ -370,6 +333,54 @@ public void CopyOut(LocalReference argumentsArray)
370333 }
371334 }
372335 }
336+
337+ public void Return ( LocalReference invocation )
338+ {
339+ var returnType = method . ReturnType ;
340+
341+ if ( returnType == typeof ( void ) )
342+ {
343+ method . CodeBuilder . AddStatement ( ReturnStatement . Instance ) ;
344+ return ;
345+ }
346+
347+ #if FEATURE_BYREFLIKE
348+ if ( returnType . IsByRefLikeSafe ( ) )
349+ {
350+ // The return value in the `ReturnValue` property is an `object`
351+ // and cannot be converted back to the original by-ref-like return type.
352+ // We need to replace it with some other value.
353+
354+ // For now, we just substitute the by-ref-like type's default value:
355+ method . CodeBuilder . AddStatement (
356+ new ReturnStatement (
357+ new DefaultValueExpression ( returnType ) ) ) ;
358+ }
359+ else
360+ #endif
361+ {
362+ var returnValue = method . CodeBuilder . DeclareLocal ( typeof ( object ) ) ;
363+ method . CodeBuilder . AddStatement (
364+ new AssignStatement (
365+ returnValue ,
366+ new MethodInvocationExpression ( invocation , InvocationMethods . GetReturnValue ) ) ) ;
367+
368+ // Emit code to ensure a value type return type is not null, otherwise the cast will cause a null-deref
369+ if ( returnType . IsValueType && ! returnType . IsNullableType ( ) )
370+ {
371+ method . CodeBuilder . AddStatement (
372+ new IfNullExpression (
373+ returnValue ,
374+ new ThrowStatement (
375+ typeof ( InvalidOperationException ) ,
376+ "Interceptors failed to set a return value, or swallowed the exception thrown by the target" ) ) ) ;
377+ }
378+
379+ method . CodeBuilder . AddStatement (
380+ new ReturnStatement (
381+ new ConvertExpression ( returnType , returnValue ) ) ) ;
382+ }
383+ }
373384 }
374385 }
375386}
0 commit comments