private JsValue LastIndexOf(JsValue thisObj, JsValue[] arguments)
        {
            var o   = ArrayOperations.For(Engine, thisObj);
            var len = o.GetLongLength();

            if (len == 0)
            {
                return(-1);
            }

            var n = arguments.Length > 1
                ? TypeConverter.ToInteger(arguments[1])
                : len - 1;
            double k;

            if (n >= 0)
            {
                k = System.Math.Min(n, len - 1); // min
            }
            else
            {
                k = len - System.Math.Abs(n);
            }

            if (k < 0 || k > uint.MaxValue)
            {
                return(-1);
            }

            var searchElement = arguments.At(0);
            var i             = (uint)k;

            for (;; i--)
            {
                var kPresent = o.HasProperty(i);
                if (kPresent)
                {
                    var elementK = o.Get(i);
                    var same     = JintBinaryExpression.StrictlyEqual(elementK, searchElement);
                    if (same)
                    {
                        return(i);
                    }
                }

                if (i == 0)
                {
                    break;
                }
            }

            return(-1);
        }
        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));
        }
Пример #3
0
        private JsValue IndexOf(JsValue thisObj, JsValue[] arguments)
        {
            var o   = ArrayOperations.For(Engine, thisObj);
            var len = o.GetLongLength();

            if (len == 0)
            {
                return(-1);
            }

            var startIndex = arguments.Length > 1
                ? TypeConverter.ToNumber(arguments[1])
                : 0;

            if (startIndex > uint.MaxValue)
            {
                return(-1);
            }

            ulong k;

            if (startIndex < 0)
            {
                var   abs  = System.Math.Abs(startIndex);
                ulong temp = len - (uint)abs;
                if (abs > len || temp < 0)
                {
                    temp = 0;
                }

                k = temp;
            }
            else
            {
                k = (ulong)startIndex;
            }

            if (k >= len)
            {
                return(-1);
            }

            ulong smallestIndex = o.GetSmallestIndex(len);

            if (smallestIndex > k)
            {
                k = smallestIndex;
            }

            var searchElement = arguments.At(0);

            for (; k < len; k++)
            {
                var kPresent = o.HasProperty(k);
                if (kPresent)
                {
                    var elementK = o.Get(k);
                    var same     = JintBinaryExpression.StrictlyEqual(elementK, searchElement);
                    if (same)
                    {
                        return(k);
                    }
                }
            }

            return(-1);
        }