private void Initialize()
 {
     _jintSwitchBlock = new JintSwitchCase[_switchBlock.Count];
     for (var i = 0; i < _jintSwitchBlock.Length; i++)
     {
         _jintSwitchBlock[i] = new JintSwitchCase(_engine, _switchBlock[i]);
     }
 }
Пример #2
0
        private void Initialize(EvaluationContext context)
        {
            var engine = context.Engine;

            _jintSwitchBlock = new JintSwitchCase[_switchBlock.Count];
            for (var i = 0; i < _jintSwitchBlock.Length; i++)
            {
                _jintSwitchBlock[i] = new JintSwitchCase(engine, _switchBlock[i]);
            }
        }
Пример #3
0
        public Completion Execute(EvaluationContext context, JsValue input)
        {
            if (!_initialized)
            {
                Initialize(context);
                _initialized = true;
            }

            var            engine      = context.Engine;
            JsValue        v           = Undefined.Instance;
            Location       l           = context.LastSyntaxNode.Location;
            JintSwitchCase defaultCase = null;
            bool           hit         = false;

            for (var i = 0; i < (uint)_jintSwitchBlock.Length; i++)
            {
                var clause = _jintSwitchBlock[i];

                EnvironmentRecord oldEnv = null;
                if (clause.LexicalDeclarations != null)
                {
                    oldEnv = engine.ExecutionContext.LexicalEnvironment;
                    var blockEnv = JintEnvironment.NewDeclarativeEnvironment(engine, oldEnv);
                    JintStatementList.BlockDeclarationInstantiation(engine, blockEnv, clause.LexicalDeclarations);
                    engine.UpdateLexicalEnvironment(blockEnv);
                }

                if (clause.Test == null)
                {
                    defaultCase = clause;
                }
                else
                {
                    var clauseSelector = clause.Test.GetValue(context).Value;
                    if (clauseSelector == input)
                    {
                        hit = true;
                    }
                }

                if (hit && clause.Consequent != null)
                {
                    var r = clause.Consequent.Execute(context);

                    if (oldEnv is not null)
                    {
                        engine.UpdateLexicalEnvironment(oldEnv);
                    }

                    if (r.Type != CompletionType.Normal)
                    {
                        return(r);
                    }

                    l = r.Location;
                    v = r.Value ?? Undefined.Instance;
                }
            }

            // do we need to execute the default case ?
            if (hit == false && defaultCase != null)
            {
                EnvironmentRecord oldEnv = null;
                if (defaultCase.LexicalDeclarations != null)
                {
                    oldEnv = engine.ExecutionContext.LexicalEnvironment;
                    var blockEnv = JintEnvironment.NewDeclarativeEnvironment(engine, oldEnv);
                    JintStatementList.BlockDeclarationInstantiation(engine, blockEnv, defaultCase.LexicalDeclarations);
                    engine.UpdateLexicalEnvironment(blockEnv);
                }

                var r = defaultCase.Consequent.Execute(context);

                if (oldEnv is not null)
                {
                    engine.UpdateLexicalEnvironment(oldEnv);
                }
                if (r.Type != CompletionType.Normal)
                {
                    return(r);
                }

                l = r.Location;
                v = r.Value ?? Undefined.Instance;
            }

            return(new Completion(CompletionType.Normal, v, null, l));
        }
        public Completion Execute(JsValue input)
        {
            if (!_initialized)
            {
                Initialize();
                _initialized = true;
            }

            JsValue        v           = Undefined.Instance;
            Location       l           = _engine._lastSyntaxNode.Location;
            JintSwitchCase defaultCase = null;
            bool           hit         = false;

            for (var i = 0; i < (uint)_jintSwitchBlock.Length; i++)
            {
                var clause = _jintSwitchBlock[i];

                LexicalEnvironment oldEnv = null;
                if (clause.LexicalDeclarations != null)
                {
                    oldEnv = _engine.ExecutionContext.LexicalEnvironment;
                    var blockEnv = LexicalEnvironment.NewDeclarativeEnvironment(_engine, oldEnv);
                    JintStatementList.BlockDeclarationInstantiation(blockEnv, clause.LexicalDeclarations);
                    _engine.UpdateLexicalEnvironment(blockEnv);
                }

                if (clause.Test == null)
                {
                    defaultCase = clause;
                }
                else
                {
                    var clauseSelector = clause.Test.GetValue();
                    if (JintBinaryExpression.StrictlyEqual(clauseSelector, input))
                    {
                        hit = true;
                    }
                }

                if (hit && clause.Consequent != null)
                {
                    var r = clause.Consequent.Execute();

                    if (oldEnv != null)
                    {
                        _engine.UpdateLexicalEnvironment(oldEnv);
                    }

                    if (r.Type != CompletionType.Normal)
                    {
                        return(r);
                    }

                    l = r.Location;
                    v = r.Value ?? Undefined.Instance;
                }
            }

            // do we need to execute the default case ?
            if (hit == false && defaultCase != null)
            {
                LexicalEnvironment oldEnv = null;
                if (defaultCase.LexicalDeclarations != null)
                {
                    oldEnv = _engine.ExecutionContext.LexicalEnvironment;
                    var blockEnv = LexicalEnvironment.NewDeclarativeEnvironment(_engine, oldEnv);
                    JintStatementList.BlockDeclarationInstantiation(blockEnv, defaultCase.LexicalDeclarations);
                    _engine.UpdateLexicalEnvironment(blockEnv);
                }

                var r = defaultCase.Consequent.Execute();

                if (oldEnv != null)
                {
                    _engine.UpdateLexicalEnvironment(oldEnv);
                }
                if (r.Type != CompletionType.Normal)
                {
                    return(r);
                }

                l = r.Location;
                v = r.Value ?? Undefined.Instance;
            }

            return(new Completion(CompletionType.Normal, v, null, l));
        }