#nullable enable using System.Runtime.CompilerServices; using Esprima; using Jint.Native; using Jint.Runtime.Interpreter.Expressions; namespace Jint.Runtime { public enum CompletionType { Normal = 0, Return = 1, Throw = 2, Break, Continue } /// /// https://tc39.es/ecma262/#sec-completion-record-specification-type /// public readonly struct Completion { internal Completion(CompletionType type, JsValue value, string? target, in Location location) { Type = type; Value = value; Target = target; Location = location; } public Completion(CompletionType type, JsValue value, in Location location) : this(type, value, null, location) { } public Completion(CompletionType type, string target, in Location location) : this(type, null!, target, location) { } internal Completion(in ExpressionResult result) { Type = (CompletionType) result.Type; // this cast protects us from getting from type Value = (JsValue) result.Value; Target = null; Location = result.Location; } public readonly CompletionType Type; public readonly JsValue Value; public readonly string? Target; public readonly Location Location; public static Completion Normal(JsValue value, in Location location) => new Completion(CompletionType.Normal, value, location); public static Completion Empty() => new Completion(CompletionType.Normal, null!, default); [MethodImpl(MethodImplOptions.AggressiveInlining)] public JsValue GetValueOrDefault() { return Value ?? Undefined.Instance; } [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool IsAbrupt() { return Type != CompletionType.Normal; } /// /// https://tc39.es/ecma262/#sec-updateempty /// internal Completion UpdateEmpty(JsValue value) { if (Value is not null) { return this; } return new Completion(Type, value, Target, Location); } } }