@@ -287,26 +287,15 @@ public void CopyOut(out IExpression[] arguments, out LocalReference?[] byRefArgu
287287
288288 IExpression dereferencedArgument ;
289289
290- #if FEATURE_BYREFLIKE
291- if ( dereferencedArgumentType . IsByRefLikeSafe ( ) )
292- {
293- // The argument value in the invocation `Arguments` array is an `object`
294- // and cannot be converted back to its original by-ref-like type.
295- // We need to replace it with some other value.
290+ // Note that we don't need special logic for by-ref-like values / `ByRefLikeProxy` here,
291+ // since `ConvertArgumentFromObjectExpression` knows how to deal with those.
296292
297- // For now, we just substitute the by-ref-like type's default value:
298- dereferencedArgument = new DefaultValueExpression ( dereferencedArgumentType ) ;
299- }
300- else
301- #endif
302- {
303- dereferencedArgument = new ConvertArgumentFromObjectExpression (
304- new MethodInvocationExpression (
305- ThisExpression . Instance ,
306- InvocationMethods . GetArgumentValue ,
307- new LiteralIntExpression ( i ) ) ,
308- dereferencedArgumentType ) ;
309- }
293+ dereferencedArgument = new ConvertArgumentFromObjectExpression (
294+ new MethodInvocationExpression (
295+ ThisExpression . Instance ,
296+ InvocationMethods . GetArgumentValue ,
297+ new LiteralIntExpression ( i ) ) ,
298+ dereferencedArgumentType ) ;
310299
311300 if ( argumentType . IsByRef )
312301 {
@@ -333,17 +322,20 @@ public void CopyIn(LocalReference?[] byRefArguments)
333322#if FEATURE_BYREFLIKE
334323 if ( localCopy . Type . IsByRefLikeSafe ( ) )
335324 {
336- // The by-ref-like value in the local buffer variable cannot be put back
337- // into the invocation `Arguments` array, because it cannot be boxed.
338- // We need to replace it with some other value.
339-
340- // For now, we just erase it by substituting `null`:
325+ // For by-ref-like values, a `ByRefLikeProxy` has previously been placed in `IInvocation.Arguments`.
326+ // We must not replace that proxy, but use it to update the referenced by-ref-like parameter:
341327 method . CodeBuilder . AddStatement (
342- new MethodInvocationExpression (
343- ThisExpression . Instance ,
344- InvocationMethods . SetArgumentValue ,
345- new LiteralIntExpression ( i ) ,
346- NullExpression . Instance ) ) ;
328+ new AssignStatement (
329+ new PointerReference (
330+ new MethodInvocationExpression (
331+ new MethodInvocationExpression (
332+ ThisExpression . Instance ,
333+ InvocationMethods . GetArgumentValue ,
334+ new LiteralIntExpression ( i ) ) ,
335+ ByRefLikeProxyMethods . GetPtr ,
336+ new TypeTokenExpression ( localCopy . Type ) ) ,
337+ localCopy . Type ) ,
338+ localCopy ) ) ;
347339 }
348340 else
349341#endif
@@ -361,25 +353,14 @@ public void CopyIn(LocalReference?[] byRefArguments)
361353 public void SetReturnValue ( LocalReference returnValue )
362354 {
363355#if FEATURE_BYREFLIKE
364- if ( returnValue . Type . IsByRefLikeSafe ( ) )
365- {
366- // The by-ref-like return value cannot be put into the `ReturnValue` property,
367- // because it cannot be boxed. We need to replace it with some other value.
368-
369- // For now, we just erase it by substituting `null`:
370- method . CodeBuilder . AddStatement ( new MethodInvocationExpression (
371- ThisExpression . Instance ,
372- InvocationMethods . SetReturnValue ,
373- NullExpression . Instance ) ) ;
374- }
375- else
356+ // TODO: For by-ref-like return values, we will need to read `IInvocation.ReturnValue`
357+ // and set the return value via pointer indirection (`ByRefLikeProxy.GetPtr`).
376358#endif
377- {
378- method . CodeBuilder . AddStatement ( new MethodInvocationExpression (
379- ThisExpression . Instance ,
380- InvocationMethods . SetReturnValue ,
381- new ConvertArgumentToObjectExpression ( returnValue ) ) ) ;
382- }
359+
360+ method . CodeBuilder . AddStatement ( new MethodInvocationExpression (
361+ ThisExpression . Instance ,
362+ InvocationMethods . SetReturnValue ,
363+ new ConvertArgumentToObjectExpression ( returnValue ) ) ) ;
383364 }
384365 }
385366 }
0 commit comments