/* * 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 } }