MethodInfoFunctionInstance.cs 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  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. public MethodInfoFunctionInstance(Engine engine, MethodInfo[] methods)
  14. : base(engine, null, null, false)
  15. {
  16. _methods = methods;
  17. Prototype = engine.Function.PrototypeObject;
  18. }
  19. public override JsValue Call(JsValue thisObject, JsValue[] arguments)
  20. {
  21. // filter methods with the expected number of parameters
  22. var methods = _methods
  23. .Where(m => m.GetParameters().Count() == arguments.Length)
  24. .ToArray()
  25. ;
  26. if (!methods.Any())
  27. {
  28. throw new JavaScriptException(Engine.TypeError, "Invalid number of arguments");
  29. }
  30. // todo: look for compatible types
  31. var method = methods.First();
  32. var parameters = new List<object>();
  33. for (int i = 0; i < arguments.Length; i++)
  34. {
  35. parameters[i] = Convert.ChangeType(arguments[i].ToObject(), method.GetParameters()[i].ParameterType,
  36. CultureInfo.InvariantCulture);
  37. }
  38. var obj = thisObject.ToObject() as ObjectWrapper;
  39. if (obj == null)
  40. {
  41. throw new JavaScriptException(Engine.TypeError, "Can't call a CLR method on a non CLR instance");
  42. }
  43. return JsValue.FromObject(Engine, method.Invoke(obj.Target, parameters.ToArray()));
  44. }
  45. }
  46. }