NullishCoalescingExpression.cs 1.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. using System.Runtime.CompilerServices;
  2. using Esprima.Ast;
  3. using Jint.Native;
  4. namespace Jint.Runtime.Interpreter.Expressions
  5. {
  6. internal sealed class NullishCoalescingExpression : JintExpression
  7. {
  8. private readonly JintExpression _left;
  9. private readonly JintExpression? _right;
  10. private readonly JsValue? _constant;
  11. public NullishCoalescingExpression(BinaryExpression expression) : base(expression)
  12. {
  13. _left = Build(expression.Left);
  14. // we can create a fast path for common literal case like variable ?? 0
  15. if (expression.Right is Literal l)
  16. {
  17. _constant = JintLiteralExpression.ConvertToJsValue(l);
  18. }
  19. else
  20. {
  21. _right = Build(expression.Right);
  22. }
  23. }
  24. public override JsValue GetValue(EvaluationContext context)
  25. {
  26. // need to notify correct node when taking shortcut
  27. context.LastSyntaxElement = _expression;
  28. return EvaluateConstantOrExpression(context);
  29. }
  30. protected override object EvaluateInternal(EvaluationContext context)
  31. {
  32. return EvaluateConstantOrExpression(context);
  33. }
  34. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  35. private JsValue EvaluateConstantOrExpression(EvaluationContext context)
  36. {
  37. var left = _left.GetValue(context);
  38. return !left.IsNullOrUndefined()
  39. ? left
  40. : _constant ?? _right!.GetValue(context);
  41. }
  42. }
  43. }