Пример #1
0
        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();
        }
Пример #2
0
        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);
        }