Merge pull request #866 from linquize/content-type-encoding
[mono.git] / mcs / class / dlr / Runtime / Microsoft.Dynamic / SplatCallSite.cs
1 /* ****************************************************************************
2  *
3  * Copyright (c) Microsoft Corporation. 
4  *
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.
10  *
11  * You must not remove this notice, or any other, from this software.
12  *
13  *
14  * ***************************************************************************/
15 using System; using Microsoft;
16
17
18 using System.Diagnostics;
19 #if CODEPLEX_40
20 using System.Linq.Expressions;
21 #else
22 using Microsoft.Linq.Expressions;
23 #endif
24 using System.Runtime.CompilerServices;
25 #if !CODEPLEX_40
26 using Microsoft.Runtime.CompilerServices;
27 #endif
28
29
30 #if CODEPLEX_40
31 namespace System.Dynamic {
32 #else
33 namespace Microsoft.Scripting {
34 #endif
35
36     internal sealed class SplatCallSite {
37         // Stored callable Delegate or IDynamicMetaObjectProvider.
38         internal readonly object _callable;
39
40         // Can the number of arguments to a given event change each call?
41         // If not, we don't need this level of indirection--we could cache a
42         // delegate that does the splatting.
43         internal CallSite<Func<CallSite, object, object[], object>> _site;
44
45         internal SplatCallSite(object callable) {
46             Debug.Assert(callable != null);
47             _callable = callable;
48         }
49
50         internal object Invoke(object[] args) {
51             Debug.Assert(args != null);
52
53             // If it is a delegate, just let DynamicInvoke do the binding.
54             var d = _callable as Delegate;
55             if (d != null) {
56                 return d.DynamicInvoke(args);
57             }
58
59             // Otherwise, create a CallSite and invoke it.
60             if (_site == null) {
61                 _site = CallSite<Func<CallSite, object, object[], object>>.Create(SplatInvokeBinder.Instance);
62             }
63
64             return _site.Target(_site, _callable, args);
65         }
66     }
67 }