JintNewExpression.cs 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. using Esprima.Ast;
  2. using Jint.Native;
  3. namespace Jint.Runtime.Interpreter.Expressions
  4. {
  5. internal sealed class JintNewExpression : JintExpression
  6. {
  7. private readonly JintExpression _calleeExpression;
  8. private JintExpression[] _jintArguments;
  9. private bool _hasSpreads;
  10. public JintNewExpression(Engine engine, NewExpression expression) : base(engine, expression)
  11. {
  12. _initialized = false;
  13. _calleeExpression = Build(engine, expression.Callee);
  14. }
  15. protected override void Initialize()
  16. {
  17. var expression = (NewExpression) _expression;
  18. _jintArguments = new JintExpression[expression.Arguments.Count];
  19. for (var i = 0; i < _jintArguments.Length; i++)
  20. {
  21. _jintArguments[i] = Build(_engine, (Expression) expression.Arguments[i]);
  22. _hasSpreads |= _jintArguments[i] is JintSpreadExpression;
  23. }
  24. }
  25. protected override object EvaluateInternal()
  26. {
  27. JsValue[] arguments;
  28. if (_hasSpreads)
  29. {
  30. arguments = BuildArgumentsWithSpreads(_jintArguments);
  31. }
  32. else
  33. {
  34. arguments = _engine._jsValueArrayPool.RentArray(_jintArguments.Length);
  35. BuildArguments(_jintArguments, arguments);
  36. }
  37. // todo: optimize by defining a common abstract class or interface
  38. if (!(_calleeExpression.GetValue() is IConstructor callee))
  39. {
  40. return ExceptionHelper.ThrowTypeError<object>(_engine, "The object can't be used as constructor.");
  41. }
  42. // construct the new instance using the Function's constructor method
  43. var instance = callee.Construct(arguments);
  44. _engine._jsValueArrayPool.ReturnArray(arguments);
  45. return instance;
  46. }
  47. }
  48. }