ArrowFunctionInstance.cs 2.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. using Esprima.Ast;
  2. using Jint.Runtime;
  3. using Jint.Runtime.Descriptors;
  4. using Jint.Runtime.Descriptors.Specialized;
  5. using Jint.Runtime.Environments;
  6. using Jint.Runtime.Interpreter;
  7. namespace Jint.Native.Function
  8. {
  9. public sealed class ArrowFunctionInstance : FunctionInstance
  10. {
  11. private readonly JintFunctionDefinition _function;
  12. /// <summary>
  13. /// http://www.ecma-international.org/ecma-262/6.0/#sec-arrow-function-definitions
  14. /// </summary>
  15. public ArrowFunctionInstance(
  16. Engine engine,
  17. IFunction functionDeclaration,
  18. LexicalEnvironment scope,
  19. bool strict)
  20. : this(engine, new JintFunctionDefinition(engine, functionDeclaration), scope, strict)
  21. {
  22. }
  23. internal ArrowFunctionInstance(
  24. Engine engine,
  25. JintFunctionDefinition function,
  26. LexicalEnvironment scope,
  27. bool strict)
  28. : base(engine, function, scope, strict ? FunctionThisMode.Strict : FunctionThisMode.Lexical)
  29. {
  30. _function = function;
  31. PreventExtensions();
  32. _prototype = Engine.Function.PrototypeObject;
  33. _length = new LazyPropertyDescriptor(() => JsNumber.Create(function.Initialize(engine, this).Length), PropertyFlag.Configurable);
  34. }
  35. // for example RavenDB wants to inspect this
  36. public IFunction FunctionDeclaration => _function.Function;
  37. /// <summary>
  38. /// http://www.ecma-international.org/ecma-262/5.1/#sec-13.2.1
  39. /// </summary>
  40. public override JsValue Call(JsValue thisArg, JsValue[] arguments)
  41. {
  42. var strict = Strict || _engine._isStrict;
  43. using (new StrictModeScope(strict, true))
  44. {
  45. var localEnv = LexicalEnvironment.NewFunctionEnvironment(_engine, this, Undefined);
  46. _engine.EnterExecutionContext(localEnv, localEnv);
  47. try
  48. {
  49. _engine.FunctionDeclarationInstantiation(
  50. functionInstance: this,
  51. arguments,
  52. localEnv);
  53. var result = _function.Execute();
  54. var value = result.GetValueOrDefault().Clone();
  55. if (result.Type == CompletionType.Throw)
  56. {
  57. ExceptionHelper.ThrowJavaScriptException(_engine, value, result);
  58. }
  59. if (result.Type == CompletionType.Return)
  60. {
  61. return value;
  62. }
  63. }
  64. finally
  65. {
  66. _engine.LeaveExecutionContext();
  67. }
  68. return Undefined;
  69. }
  70. }
  71. }
  72. }