MegaBites-AI/Windows-powershell
0372
1// Licensed to the .NET Foundation under one or more agreements.2// The .NET Foundation licenses this file to you under the MIT license.3 4using System;5using System.Collections.Generic;6using System.Diagnostics;7using System.Globalization;8using System.Linq.Expressions;9using System.Reflection;10using System.Reflection.Emit;11using System.Management.Automation.InteropServices;12using System.Runtime.InteropServices;13 14namespace System.Management.Automation.ComInterop15{16 [StructLayout(LayoutKind.Sequential)]17 internal struct VariantArray118 {19 public Variant Element0;20 }21 22 [StructLayout(LayoutKind.Sequential)]23 internal struct VariantArray224 {25 public Variant Element0, Element1;26 }27 28 [StructLayout(LayoutKind.Sequential)]29 internal struct VariantArray430 {31 public Variant Element0, Element1, Element2, Element3;32 }33 34 [StructLayout(LayoutKind.Sequential)]35 internal struct VariantArray836 {37 public Variant Element0, Element1, Element2, Element3, Element4, Element5, Element6, Element7;38 }39 40 //41 // Helper for getting the right VariantArray struct for a given number of42 // arguments. Will generate a struct if needed.43 //44 // We use this because we don't have stackalloc or pinning in Expression45 // Trees, so we can't create an array of Variants directly.46 //47 internal static class VariantArray48 {49 // Don't need a dictionary for this, it will have very few elements50 // (guaranteed less than 28, in practice 0-2)51 private static readonly List<Type> s_generatedTypes = new List<Type>(0);52 53 internal static MemberExpression GetStructField(ParameterExpression variantArray, int field)54 {55 return Expression.Field(variantArray, "Element" + field);56 }57 58 internal static Type GetStructType(int args)59 {60 Debug.Assert(args >= 0);61 if (args <= 1)62 {63 return typeof(VariantArray1);64 }65 66 if (args <= 2)67 {68 return typeof(VariantArray2);69 }70 71 if (args <= 4)72 {73 return typeof(VariantArray4);74 }75 76 if (args <= 8)77 {78 return typeof(VariantArray8);79 }80 81 int size = 1;82 while (args > size)83 {84 size *= 2;85 }86 87 lock (s_generatedTypes)88 {89 // See if we can find an existing type90 foreach (Type t in s_generatedTypes)91 {92 int arity = int.Parse(t.Name.AsSpan("VariantArray".Length), NumberStyles.Integer, CultureInfo.InvariantCulture);93 if (size == arity)94 {95 return t;96 }97 }98 99 // Else generate a new type100 Type type = CreateCustomType(size).MakeGenericType(new Type[] { typeof(Variant) });101 s_generatedTypes.Add(type);102 return type;103 }104 }105 106 private static Type CreateCustomType(int size)107 {108 TypeAttributes attrs = TypeAttributes.NotPublic | TypeAttributes.SequentialLayout;109 TypeBuilder type = UnsafeMethods.DynamicModule.DefineType("VariantArray" + size, attrs, typeof(ValueType));110 GenericTypeParameterBuilder T = type.DefineGenericParameters(new string[] { "T" })[0];111 for (int i = 0; i < size; i++)112 {113 type.DefineField("Element" + i, T, FieldAttributes.Public);114 }115 return type.CreateType();116 }117 }118}119 