private void Initialize()
        {
            var jintStatements = new Pair[_statements.Count];

            for (var i = 0; i < jintStatements.Length; i++)
            {
                var esprimaStatement = _statements[i];
                jintStatements[i] = new Pair
                {
                    Statement = JintStatement.Build(_engine, esprimaStatement),
                    Value     = JintStatement.FastResolve(esprimaStatement)
                };
            }
            _jintStatements = jintStatements;
        }
        /// <summary>
        /// https://tc39.es/ecma262/#sec-performeval
        /// </summary>
        public JsValue Call(JsValue thisObject, JsValue[] arguments, bool direct)
        {
            if (!(arguments.At(0) is JsString x))
            {
                return(arguments.At(0));
            }

            var    parser = new JavaScriptParser(x.ToString(), ParserOptions);
            Script script;

            try
            {
                script = parser.ParseScript(StrictModeScope.IsStrictModeCode);
            }
            catch (ParserException e)
            {
                return(e.Description == Messages.InvalidLHSInAssignment
                    ? ExceptionHelper.ThrowReferenceError <JsValue>(_engine)
                    : ExceptionHelper.ThrowSyntaxError <JsValue>(_engine));
            }

            var body = script.Body;

            if (body.Count == 0)
            {
                return(Undefined);
            }

            var strictEval = script.Strict || _engine._isStrict;
            var ctx        = _engine.ExecutionContext;

            using (new StrictModeScope(strictEval))
            {
                LexicalEnvironment lexEnv;
                LexicalEnvironment varEnv;
                if (direct)
                {
                    lexEnv = LexicalEnvironment.NewDeclarativeEnvironment(_engine, ctx.LexicalEnvironment);
                    varEnv = ctx.VariableEnvironment;
                }
                else
                {
                    lexEnv = LexicalEnvironment.NewDeclarativeEnvironment(_engine, Engine.GlobalEnvironment);
                    varEnv = Engine.GlobalEnvironment;
                }

                if (strictEval)
                {
                    varEnv = lexEnv;
                }

                // If ctx is not already suspended, suspend ctx.

                Engine.EnterExecutionContext(lexEnv, varEnv);

                try
                {
                    Engine.EvalDeclarationInstantiation(script, varEnv, lexEnv, strictEval);

                    var statement = JintStatement.Build(_engine, script);
                    var result    = statement.Execute();
                    var value     = result.GetValueOrDefault();

                    if (result.Type == CompletionType.Throw)
                    {
                        var ex = new JavaScriptException(value).SetCallstack(_engine, result.Location);
                        throw ex;
                    }
                    else
                    {
                        return(value);
                    }
                }
                finally
                {
                    Engine.LeaveExecutionContext();
                }
            }
        }
        public Completion Execute()
        {
            if (!_initialized)
            {
                Initialize();
                _initialized = true;
            }

            if (_statement != null)
            {
                _engine._lastSyntaxNode = _statement;
                _engine.RunBeforeExecuteStatementChecks(_statement);
            }

            JintStatement s  = null;
            var           c  = new Completion(CompletionType.Normal, null, null, _engine._lastSyntaxNode?.Location ?? default);
            Completion    sl = c;

            // The value of a StatementList is the value of the last value-producing item in the StatementList
            JsValue lastValue = null;

            try
            {
                foreach (var pair in _jintStatements)
                {
                    s = pair.Statement;
                    c = pair.Value ?? s.Execute();
                    if (c.Type != CompletionType.Normal)
                    {
                        return(new Completion(
                                   c.Type,
                                   c.Value ?? sl.Value,
                                   c.Identifier,
                                   c.Location));
                    }
                    sl        = c;
                    lastValue = c.Value ?? lastValue;
                }
            }
            catch (JavaScriptException v)
            {
                var location   = v.Location == default ? s.Location : v.Location;
                var completion = new Completion(CompletionType.Throw, v.Error, null, location);
                return(completion);
            }
            catch (TypeErrorException e)
            {
                var error = _engine.TypeError.Construct(new JsValue[]
                {
                    e.Message
                });
                return(new Completion(CompletionType.Throw, error, null, s.Location));
            }
            catch (RangeErrorException e)
            {
                var error = _engine.RangeError.Construct(new JsValue[]
                {
                    e.Message
                });
                c = new Completion(CompletionType.Throw, error, null, s.Location);
            }
            return(new Completion(c.Type, lastValue ?? JsValue.Undefined, c.Identifier, c.Location));
        }