JintSpreadExpression.cs 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. using Esprima.Ast;
  2. using Jint.Native;
  3. using Jint.Native.Iterator;
  4. namespace Jint.Runtime.Interpreter.Expressions
  5. {
  6. internal sealed class JintSpreadExpression : JintExpression
  7. {
  8. private readonly JintExpression _argument;
  9. private readonly string? _argumentName;
  10. public JintSpreadExpression(Engine engine, SpreadElement expression) : base(expression)
  11. {
  12. _argument = Build(engine, expression.Argument);
  13. _argumentName = (expression.Argument as Identifier)?.Name;
  14. }
  15. protected override ExpressionResult EvaluateInternal(EvaluationContext context)
  16. {
  17. GetValueAndCheckIterator(context, out var objectInstance, out var iterator);
  18. return NormalCompletion(objectInstance);
  19. }
  20. public override Completion GetValue(EvaluationContext context)
  21. {
  22. // need to notify correct node when taking shortcut
  23. context.LastSyntaxElement = _expression;
  24. GetValueAndCheckIterator(context, out var objectInstance, out var iterator);
  25. return new(CompletionType.Normal, objectInstance, _expression);
  26. }
  27. internal void GetValueAndCheckIterator(EvaluationContext context, out JsValue instance, out IteratorInstance? iterator)
  28. {
  29. instance = _argument.GetValue(context).Value;
  30. if (instance is null || !instance.TryGetIterator(context.Engine.Realm, out iterator))
  31. {
  32. iterator = null;
  33. ExceptionHelper.ThrowTypeError(context.Engine.Realm, _argumentName + " is not iterable");
  34. }
  35. }
  36. }
  37. }