Merge pull request #900 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / dlr / Runtime / Microsoft.Dynamic / Runtime / ArgumentArray.cs
1 /* ****************************************************************************
2  *
3  * Copyright (c) Microsoft Corporation. 
4  *
5  * This source code is subject to terms and conditions of the Apache License, Version 2.0. 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  Apache License, Version 2.0, please send an email to 
8  * ironruby@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
9  * by the terms of the Apache License, Version 2.0.
10  *
11  * You must not remove this notice, or any other, from this software.
12  *
13  *
14  * ***************************************************************************/
15
16 #if FEATURE_CORE_DLR
17 using System.Linq.Expressions;
18 #else
19 using Microsoft.Scripting.Ast;
20 #endif
21
22 using System;
23 using System.Dynamic;
24 using System.Reflection;
25 using Microsoft.Scripting.Utils;
26
27 namespace Microsoft.Scripting.Runtime {
28     using AstUtils = Microsoft.Scripting.Ast.Utils;
29
30     /// <summary>
31     /// Wraps all arguments passed to a dynamic site with more arguments than can be accepted by a Func/Action delegate.
32     /// The binder generating a rule for such a site should unwrap the arguments first and then perform a binding to them.
33     /// </summary>
34     public sealed class ArgumentArray {
35         private readonly object[] _arguments;
36
37         // the index of the first item _arguments that represents an argument:
38         private readonly int _first;
39
40         // the number of items in _arguments that represent the arguments:
41         private readonly int _count;
42
43         internal ArgumentArray(object[] arguments, int first, int count) {
44             _arguments = arguments;
45             _first = first;
46             _count = count;
47         }
48
49         public int Count {
50             get { return _count; }
51         }
52
53         public object GetArgument(int index) {
54             ContractUtils.RequiresArrayIndex(_arguments, index, "index");
55             return _arguments[_first + index];
56         }
57
58         public DynamicMetaObject GetMetaObject(Expression parameter, int index) {
59             return DynamicMetaObject.Create(
60                 GetArgument(index),
61                 Expression.Call(
62                     _GetArgMethod, 
63                     AstUtils.Convert(parameter, typeof(ArgumentArray)),
64                     AstUtils.Constant(index)
65                 )
66             );
67         }
68
69         [CLSCompliant(false)]
70         public static object GetArg(ArgumentArray array, int index) {
71             return array._arguments[array._first + index];
72         }
73
74         private static readonly MethodInfo _GetArgMethod = new Func<ArgumentArray, int, object>(GetArg).GetMethodInfo();
75     }
76 }