Completion.cs 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. using System.Diagnostics;
  2. using System.Runtime.CompilerServices;
  3. using System.Runtime.InteropServices;
  4. using Esprima;
  5. using Esprima.Ast;
  6. using Jint.Native;
  7. namespace Jint.Runtime;
  8. public enum CompletionType : byte
  9. {
  10. Normal = 0,
  11. Return = 1,
  12. Throw = 2,
  13. Break,
  14. Continue
  15. }
  16. /// <summary>
  17. /// https://tc39.es/ecma262/#sec-completion-record-specification-type
  18. /// </summary>
  19. [StructLayout(LayoutKind.Auto)]
  20. public readonly struct Completion
  21. {
  22. private static readonly Node _emptyNode = new Identifier("");
  23. private static readonly Completion _emptyCompletion = new(CompletionType.Normal, JsEmpty.Instance, _emptyNode);
  24. internal readonly SyntaxElement _source;
  25. public Completion(CompletionType type, JsValue value, SyntaxElement source)
  26. {
  27. Debug.Assert(value is not null);
  28. Type = type;
  29. Value = value!;
  30. _source = source;
  31. }
  32. public readonly CompletionType Type;
  33. public readonly JsValue Value;
  34. public ref readonly Location Location => ref _source.Location;
  35. public static ref readonly Completion Empty() => ref _emptyCompletion;
  36. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  37. public JsValue GetValueOrDefault() => Value.IsEmpty ? JsValue.Undefined : Value;
  38. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  39. public bool IsAbrupt() => Type != CompletionType.Normal;
  40. /// <summary>
  41. /// https://tc39.es/ecma262/#sec-updateempty
  42. /// </summary>
  43. internal Completion UpdateEmpty(JsValue value)
  44. {
  45. if (Value?._type != InternalTypes.Empty)
  46. {
  47. return this;
  48. }
  49. return new Completion(Type, value, _source);
  50. }
  51. }