using Esprima.Ast; using Jint.Native; using Jint.Runtime.Interpreter.Expressions; namespace Jint.Runtime.Interpreter.Statements { /// /// http://www.ecma-international.org/ecma-262/5.1/#sec-12.6.2 /// internal sealed class JintWhileStatement : JintStatement { private readonly string _labelSetName; private readonly JintStatement _body; private readonly JintExpression _test; public JintWhileStatement(Engine engine, WhileStatement statement) : base(engine, statement) { _labelSetName = _statement?.LabelSet?.Name; _body = Build(engine, statement.Body); _test = JintExpression.Build(engine, statement.Test); } protected override Completion ExecuteInternal() { var v = Undefined.Instance; while (true) { var jsValue = _test.GetValue(); if (!TypeConverter.ToBoolean(jsValue)) { return new Completion(CompletionType.Normal, v, null, Location); } var completion = _body.Execute(); if (!ReferenceEquals(completion.Value, null)) { v = completion.Value; } if (completion.Type != CompletionType.Continue || completion.Identifier != _labelSetName) { if (completion.Type == CompletionType.Break && (completion.Identifier == null || completion.Identifier == _labelSetName)) { return new Completion(CompletionType.Normal, v, null, Location); } if (completion.Type != CompletionType.Normal) { return completion; } } } } } }