public static Delegate MarshalJsFunction(JintRuntime runtime, JsObject function, JsObject that, Type delegateType) { if (runtime == null) throw new ArgumentNullException("runtime"); if (function == null) throw new ArgumentNullException("function"); if (delegateType == null) throw new ArgumentNullException("delegateType"); if (!typeof(Delegate).IsAssignableFrom(delegateType)) throw new ArgumentException("A delegate type is required", "delegateType"); var invokeMethod = delegateType.GetMethod("Invoke"); var parameters = invokeMethod .GetParameters() .Select(p => Expression.Parameter(p.ParameterType, p.Name)) .ToList(); Expression call = Expression.Call( Expression.Constant(function), typeof(JsObject).GetMethod("Execute"), Expression.Constant(runtime), Expression.Constant(that), MakeArrayInit( parameters.Select(p => Expression.Call( Expression.Constant(runtime.Global.Marshaller), typeof(Marshaller).GetMethod("MarshalClrValue").MakeGenericMethod(p.Type), p )), typeof(object), false ) ); if (invokeMethod.ReturnType != typeof(void)) { call = Expression.Call( Expression.Constant(runtime.Global.Marshaller), typeof(Marshaller).GetMethod("MarshalJsValue").MakeGenericMethod(invokeMethod.ReturnType), call ); } var lambda = Expression.Lambda( delegateType, Expression.Block( invokeMethod.ReturnType, call ), parameters ); return lambda.Compile(); }
public object Execute(JintRuntime runtime, object @this, JsObject callee, object[] arguments) { var genericArguments = JintRuntime.ExtractGenericArguments(ref arguments); if ( _generics.Count == 0 && genericArguments != null && genericArguments.Length > 0 ) throw new InvalidOperationException("Method cannot be called without generic arguments"); var implementation = _overloads.ResolveOverload( arguments, runtime.Global.Marshaller.MarshalGenericArguments(genericArguments) ); if (implementation == null) throw new JintException(String.Format("No matching overload found {0}<{1}>", callee.Delegate.Name, genericArguments)); return implementation(runtime, @this, callee, arguments); }