1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation.
5 * This source code is subject to terms and conditions of the Microsoft Public License. A
6 * copy of the license can be found in the License.html file at the root of this distribution. If
7 * you cannot locate the Microsoft Public License, please send an email to
8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound
9 * by the terms of the Microsoft Public License.
11 * You must not remove this notice, or any other, from this software.
14 * ***************************************************************************/
15 using System; using Microsoft;
20 using System.Diagnostics;
23 using System.Dynamic.Utils;
24 using System.Linq.Expressions;
25 using System.Linq.Expressions.Compiler;
27 using Microsoft.Scripting;
28 using Microsoft.Scripting.Utils;
29 using Microsoft.Linq.Expressions;
30 using Microsoft.Linq.Expressions.Compiler;
32 using System.Runtime.CompilerServices;
34 using Microsoft.Runtime.CompilerServices;
37 using System.Runtime.InteropServices;
38 using System.Collections.Generic;
41 namespace System.Dynamic {
43 namespace Microsoft.Scripting {
45 internal static class ComBinderHelpers {
47 internal static bool PreferPut(Type type, bool holdsNull) {
48 Debug.Assert(type != null);
50 if (type.IsValueType || type.IsArray) return true;
52 if (type == typeof(String) ||
53 type == typeof(DBNull) ||
55 type == typeof(System.Reflection.Missing) ||
56 type == typeof(CurrencyWrapper)) {
64 internal static bool IsByRef(DynamicMetaObject mo) {
65 ParameterExpression pe = mo.Expression as ParameterExpression;
66 return pe != null && pe.IsByRef;
69 internal static bool IsStrongBoxArg(DynamicMetaObject o) {
71 return t.IsGenericType && t.GetGenericTypeDefinition() == typeof(StrongBox<>);
74 // this helper prepares arguments for COM binding by transforming ByVal StongBox arguments
75 // into ByRef expressions that represent the argument's Value fields.
76 internal static bool[] ProcessArgumentsForCom(ref DynamicMetaObject[] args) {
77 Debug.Assert(args != null);
79 DynamicMetaObject[] newArgs = new DynamicMetaObject[args.Length];
80 bool[] isByRefArg = new bool[args.Length];
82 for (int i = 0; i < args.Length; i++) {
83 DynamicMetaObject curArgument = args[i];
85 // set new arg infos to their original values or set default ones
86 // we will do this fixup early so that we can assume we always have
87 // arginfos in COM binder.
89 if (IsByRef(curArgument)) {
90 newArgs[i] = curArgument;
93 if (IsStrongBoxArg(curArgument)) {
94 var restrictions = curArgument.Restrictions.Merge(
95 GetTypeRestrictionForDynamicMetaObject(curArgument)
98 // we have restricted this argument to LimitType so we can convert and conversion will be trivial cast.
99 Expression boxedValueAccessor = Expression.Field(
101 curArgument.Expression,
102 curArgument.LimitType
104 curArgument.LimitType.GetField("Value")
107 IStrongBox value = curArgument.Value as IStrongBox;
108 object boxedValue = value != null ? value.Value : null;
110 newArgs[i] = new DynamicMetaObject(
116 isByRefArg[i] = true;
118 newArgs[i] = curArgument;
119 isByRefArg[i] = false;
128 internal static BindingRestrictions GetTypeRestrictionForDynamicMetaObject(DynamicMetaObject obj) {
129 if (obj.Value == null && obj.HasValue) {
130 //If the meta object holds a null value, create an instance restriction for checking null
131 return BindingRestrictions.GetInstanceRestriction(obj.Expression, null);
133 return BindingRestrictions.GetTypeRestriction(obj.Expression, obj.LimitType);