MethodInfoFunctionInstance.cs 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455
  1. using System;
  2. using System.Globalization;
  3. using System.Linq;
  4. using System.Reflection;
  5. using Jint.Native;
  6. using Jint.Native.Function;
  7. namespace Jint.Runtime.Interop
  8. {
  9. public sealed class MethodInfoFunctionInstance : FunctionInstance
  10. {
  11. private readonly MethodInfo[] _methods;
  12. public MethodInfoFunctionInstance(Engine engine, MethodInfo[] methods)
  13. : base(engine, null, null, false)
  14. {
  15. _methods = methods;
  16. Prototype = engine.Function.PrototypeObject;
  17. }
  18. public override JsValue Call(JsValue thisObject, JsValue[] arguments)
  19. {
  20. // filter methods with the expected number of parameters
  21. var methods = _methods
  22. .Where(m => m.GetParameters().Count() == arguments.Length)
  23. .ToArray()
  24. ;
  25. if (!methods.Any())
  26. {
  27. throw new JavaScriptException(Engine.TypeError, "Invalid number of arguments");
  28. }
  29. // todo: look for compatible types
  30. var method = methods.First();
  31. var parameters = new object[arguments.Length];
  32. for (var i = 0; i < arguments.Length; i++)
  33. {
  34. parameters[i] = Convert.ChangeType(
  35. arguments[i].ToObject(),
  36. 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. }