| File: System\Linq\Expressions\Interpreter\NewInstruction.cs | Web Access |
| Project: src\runtime\src\libraries\System.Linq.Expressions\src\System.Linq.Expressions.csproj (System.Linq.Expressions) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using System.Dynamic.Utils; using System.Reflection; namespace System.Linq.Expressions.Interpreter { internal class NewInstruction : Instruction { protected readonly ConstructorInfo _constructor; protected readonly int _argumentCount; public NewInstruction(ConstructorInfo constructor, int argumentCount) { _constructor = constructor; _argumentCount = argumentCount; } public override int ConsumedStack => _argumentCount; public override int ProducedStack => 1; public override string InstructionName => "New"; public override int Run(InterpretedFrame frame) { int first = frame.StackIndex - _argumentCount; object?[] args = GetArgs(frame, first); object ret; try { ret = _constructor.Invoke(args); } catch (TargetInvocationException e) { ExceptionHelpers.UnwrapAndRethrow(e); throw ContractUtils.Unreachable; } frame.Data[first] = ret; frame.StackIndex = first + 1; return 1; } protected object?[] GetArgs(InterpretedFrame frame, int first) { if (_argumentCount > 0) { var args = new object?[_argumentCount]; for (int i = 0; i < args.Length; i++) { args[i] = frame.Data[first + i]; } return args; } else { return Array.Empty<object>(); } } public override string ToString() => "New " + _constructor.DeclaringType!.Name + "(" + _constructor + ")"; } internal sealed class ByRefNewInstruction : NewInstruction { private readonly ByRefUpdater[] _byrefArgs; internal ByRefNewInstruction(ConstructorInfo target, int argumentCount, ByRefUpdater[] byrefArgs) : base(target, argumentCount) { _byrefArgs = byrefArgs; } public override string InstructionName => "ByRefNew"; public sealed override int Run(InterpretedFrame frame) { int first = frame.StackIndex - _argumentCount; object?[] args = GetArgs(frame, first); try { object ret; try { ret = _constructor.Invoke(args); } catch (TargetInvocationException e) { ExceptionHelpers.UnwrapAndRethrow(e); throw ContractUtils.Unreachable; } frame.Data[first] = ret; frame.StackIndex = first + 1; } finally { foreach (ByRefUpdater arg in _byrefArgs) { arg.Update(frame, args[arg.ArgumentIndex]); } } return 1; } } }