/*
* Copyright © 2011, Petro Protsyk, Denys Vuika
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Reflection;
using Scripting.SSharp.Parser.Ast;
namespace Scripting.SSharp.Runtime.Promotion
{
///
/// Binding to the method or constructor, also used for index getters
///
internal class MethodBinding : IBinding
{
MethodBase Method { get; set; }
object Target { get; set; }
object[] Arguments { get; set; }
///
/// Creates binding to the method
///
/// method or constructor to invoke
/// method's owner or type if method is static
/// a list of converted arguments that will be directly passed to the method
public MethodBinding(MethodBase method, object target, object[] arguments)
{
Method = method;
Arguments = arguments;
Target = target;
}
#region IInvokable Members
public bool CanInvoke()
{
return Method != null;
}
///
///
///
///
/// Ignored for strongly bound objects (null should be passed)
///
public object Invoke(IScriptContext context, object[] args)
{
//object result = RuntimeHost.NullValue;
//if (args != null)
//{
// if (Target == null && !Method.IsStatic)
// result = Method.Invoke(args.First(), args.Skip(1).ToArray());
// else
// result = Method.Invoke(Target, args);
//}
//else
//{
// result = Method.Invoke(Target, Arguments);
//}
//context.Result = result;
//return result;
if (args != null) Arguments = args;
//NOTE: ref, out
object[] callArguments = new object[Arguments.Length];
for (int i = 0; i < callArguments.Length; i++)
{
ScopeValueReference vr = Arguments[i] as ScopeValueReference;
if (vr != null){
callArguments[i] = vr.ConvertedValue;
continue;
}
FunctionDelegate d = Arguments[i] as FunctionDelegate;
if (d != null) {
d.ActiveContext = context;
callArguments[i] = d.Method;
continue;
}
callArguments[i] = Arguments[i];
}
var result = Method.Invoke(Target, callArguments);
//NOTE: ref, out
for (var i = 0; i < callArguments.Length; i++)
{
var vr = Arguments[i] as ScopeValueReference;
if (vr != null)
vr.Value = callArguments[i];
}
return result;
}
#endregion
#if !PocketPC && !SILVERLIGHT
//TODO: Review this approach
public static implicit operator IntPtr(MethodBinding invokableMethod)
{
return invokableMethod.Method.MethodHandle.GetFunctionPointer();
}
#endif
}
}