Completion.cs 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. using System.Runtime.CompilerServices;
  2. using System.Runtime.InteropServices;
  3. using Esprima;
  4. using Esprima.Ast;
  5. using Jint.Native;
  6. using Jint.Runtime.Interpreter.Expressions;
  7. namespace Jint.Runtime
  8. {
  9. public enum CompletionType : byte
  10. {
  11. Normal = 0,
  12. Return = 1,
  13. Throw = 2,
  14. Break,
  15. Continue
  16. }
  17. /// <summary>
  18. /// https://tc39.es/ecma262/#sec-completion-record-specification-type
  19. /// </summary>
  20. [StructLayout(LayoutKind.Auto)]
  21. public readonly struct Completion
  22. {
  23. private static readonly Node _emptyNode = new Identifier("");
  24. private static readonly Completion _emptyCompletion = new(CompletionType.Normal, null!, _emptyNode);
  25. internal readonly SyntaxElement _source;
  26. internal Completion(CompletionType type, JsValue value, string? target, SyntaxElement source)
  27. {
  28. Type = type;
  29. Value = value;
  30. Target = target;
  31. _source = source;
  32. }
  33. public Completion(CompletionType type, JsValue value, SyntaxElement source)
  34. {
  35. Type = type;
  36. Value = value;
  37. Target = null;
  38. _source = source;
  39. }
  40. public Completion(CompletionType type, string target, SyntaxElement source)
  41. {
  42. Type = type;
  43. Value = null!;
  44. Target = target;
  45. _source = source;
  46. }
  47. internal Completion(in ExpressionResult result)
  48. {
  49. Type = (CompletionType) result.Type;
  50. // this cast protects us from getting from type
  51. Value = (JsValue) result.Value;
  52. Target = null;
  53. _source = result._source;
  54. }
  55. public readonly CompletionType Type;
  56. public readonly JsValue Value;
  57. public readonly string? Target;
  58. public ref readonly Location Location => ref _source.Location;
  59. public static ref readonly Completion Empty() => ref _emptyCompletion;
  60. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  61. public JsValue GetValueOrDefault()
  62. {
  63. return Value ?? Undefined.Instance;
  64. }
  65. [MethodImpl(MethodImplOptions.AggressiveInlining)]
  66. public bool IsAbrupt()
  67. {
  68. return Type != CompletionType.Normal;
  69. }
  70. /// <summary>
  71. /// https://tc39.es/ecma262/#sec-updateempty
  72. /// </summary>
  73. internal Completion UpdateEmpty(JsValue value)
  74. {
  75. if (Value is not null)
  76. {
  77. return this;
  78. }
  79. return new Completion(Type, value, Target, _source);
  80. }
  81. }
  82. }