using System.Diagnostics; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using Jint.Native; namespace Jint.Runtime; public enum CompletionType : byte { Normal = 0, Return = 1, Throw = 2, Break, Continue } /// /// https://tc39.es/ecma262/#sec-completion-record-specification-type /// [StructLayout(LayoutKind.Auto)] public readonly struct Completion { private static readonly Node _emptyNode = new Identifier(""); private static readonly Completion _emptyCompletion = new(CompletionType.Normal, JsEmpty.Instance, _emptyNode); internal readonly Node _source; public Completion(CompletionType type, JsValue value, Node source) { Debug.Assert(value is not null); Type = type; Value = value!; _source = source; } public readonly CompletionType Type; public readonly JsValue Value; public readonly ref readonly SourceLocation Location => ref _source.LocationRef; public static ref readonly Completion Empty() => ref _emptyCompletion; [MethodImpl(MethodImplOptions.AggressiveInlining)] public JsValue GetValueOrDefault() => Value.IsEmpty ? JsValue.Undefined : Value; [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsAbrupt() => Type != CompletionType.Normal; /// /// https://tc39.es/ecma262/#sec-updateempty /// internal Completion UpdateEmpty(JsValue value) { if (Value?._type != InternalTypes.Empty) { return this; } return new Completion(Type, value, _source); } }