JintNewExpression.cs 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354
  1. namespace Jint.Runtime.Interpreter.Expressions;
  2. internal sealed class JintNewExpression : JintExpression
  3. {
  4. private readonly ExpressionCache _arguments = new();
  5. private JintExpression _calleeExpression = null!;
  6. private bool _initialized;
  7. public JintNewExpression(NewExpression expression) : base(expression)
  8. {
  9. }
  10. private void Initialize(EvaluationContext context)
  11. {
  12. var expression = (NewExpression) _expression;
  13. _arguments.Initialize(context, expression.Arguments.AsSpan());
  14. _calleeExpression = Build(expression.Callee);
  15. }
  16. protected override object EvaluateInternal(EvaluationContext context)
  17. {
  18. if (!_initialized)
  19. {
  20. Initialize(context);
  21. _initialized = true;
  22. }
  23. var engine = context.Engine;
  24. // todo: optimize by defining a common abstract class or interface
  25. var jsValue = _calleeExpression.GetValue(context);
  26. var arguments = _arguments.ArgumentListEvaluation(context, out var rented);
  27. // Reset the location to the "new" keyword so that if an Error object is
  28. // constructed below, the stack trace will capture the correct location.
  29. context.LastSyntaxElement = _expression;
  30. if (!jsValue.IsConstructor)
  31. {
  32. Throw.TypeError(engine.Realm, $"{_calleeExpression.SourceText} is not a constructor");
  33. }
  34. // construct the new instance using the Function's constructor method
  35. var instance = engine.Construct(jsValue, arguments, jsValue, _calleeExpression);
  36. if (rented)
  37. {
  38. engine._jsValueArrayPool.ReturnArray(arguments);
  39. }
  40. return instance;
  41. }
  42. }