MethodInfoFunctionInstance.cs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Globalization;
  4. using System.Linq;
  5. using System.Reflection;
  6. using Jint.Native;
  7. using Jint.Native.Function;
  8. namespace Jint.Runtime.Interop
  9. {
  10. public sealed class MethodInfoFunctionInstance : FunctionInstance
  11. {
  12. private readonly MethodInfo[] _methods;
  13. private readonly Func<JsValue, JsValue[], JsValue> _func;
  14. public MethodInfoFunctionInstance(Engine engine, MethodInfo[] methods)
  15. : base(engine, null, null, false)
  16. {
  17. _methods = methods;
  18. Prototype = engine.Function.PrototypeObject;
  19. }
  20. public override JsValue Call(JsValue thisObject, JsValue[] arguments)
  21. {
  22. // filter methods with the expected number of parameters
  23. var methods = _methods
  24. .Where(m => m.GetParameters().Count() == arguments.Length)
  25. .ToArray()
  26. ;
  27. if (!methods.Any())
  28. {
  29. throw new JavaScriptException(Engine.TypeError, "Invalid number of arguments");
  30. }
  31. // todo: look for compatible types
  32. var method = methods.First();
  33. var parameters = new List<object>();
  34. for (int i = 0; i < arguments.Length; i++)
  35. {
  36. parameters[i] = Convert.ChangeType(arguments[i].ToObject(), method.GetParameters()[i].ParameterType,
  37. CultureInfo.InvariantCulture);
  38. }
  39. var obj = thisObject.ToObject() as ObjectWrapper;
  40. if (obj == null)
  41. {
  42. throw new JavaScriptException(Engine.TypeError, "Can't call a CLR method on a non CLR instance");
  43. }
  44. return JsValue.FromObject(Engine, method.Invoke(obj.Target, parameters.ToArray()));
  45. }
  46. }
  47. }