예제 #1
0
        internal static Completion IteratorBindingInitializationBindingRestIdentifier(Identifier restParameterIdentifier, LexicalEnvironment?env, ArgumentIterator arguments)
        {
            var lhsComp = Interpreter.Instance().ResolveBinding(restParameterIdentifier.name, restParameterIdentifier.IsStrictMode, env);

            if (lhsComp.IsAbrupt())
            {
                return(lhsComp);
            }
            var lhs = (lhsComp.value as ReferenceValue) !;
            var A   = ArrayObject.ArrayCreate(0);
            int n   = 0;

            for (; ; n++)
            {
                if (arguments.Done)
                {
                    if (env == null)
                    {
                        return(lhs.PutValue(A));
                    }
                    return(lhs.InitializeReferencedBinding(A));
                }
                var nextValue = arguments.Next();
                var status    = Utils.CreateDataProperty(A, n.ToString(System.Globalization.CultureInfo.InvariantCulture), nextValue);
                if (!status.Other)
                {
                    throw new InvalidOperationException("BindingRestElement IteratorBindingInitialization: assert step 4g");
                }
            }
        }
예제 #2
0
        public static ArrayObject ArrayCreate(double lengthInteger, Object?proto = null)
        {
            var length = (int)lengthInteger;

            if (proto == null)
            {
                proto = Interpreter.Instance().CurrentRealm().Intrinsics.ArrayPrototype;
            }
            var A = new ArrayObject();

            A.prototype    = proto;
            A.IsExtensible = true;
            A.OrdinaryDefineOwnProperty("length", new PropertyDescriptor(new NumberValue(length), true, false, false));
            return(A);
        }
예제 #3
0
        private static Completion RegExpBuiltinExec(RegExpObject R, string S)
        {
            var length = S.Length;
            int lastIndex;
            {
                var lastIndexComp = R.Get("lastIndex");
                if (lastIndexComp.IsAbrupt())
                {
                    return(lastIndexComp);
                }
                var lastIndexLength = lastIndexComp.value !.ToLength();
                if (lastIndexLength.IsAbrupt())
                {
                    return(lastIndexLength);
                }
                lastIndex = (int)lastIndexLength.Other;
            }
            var flags  = R.OriginalFlags;
            var global = flags.Contains('g', StringComparison.Ordinal);
            var sticky = flags.Contains('y', StringComparison.Ordinal);

            if (!global && !sticky)
            {
                lastIndex = 0;
            }
            var   matcher        = R.RegExpMatcher;
            var   fullUnicode    = flags.Contains('u', StringComparison.Ordinal);
            var   matchSucceeded = false;
            Match?r = null;

            while (!matchSucceeded)
            {
                if (lastIndex > length)
                {
                    if (global || sticky)
                    {
                        var set = R.Set("lastIndex", NumberValue.PositiveZero, true);
                        if (set.IsAbrupt())
                        {
                            return(set);
                        }
                    }
                    return(Completion.NormalCompletion(NullValue.Instance));
                }
                r = matcher.Match(S, lastIndex);
                if (!r.Success)
                {
                    if (sticky)
                    {
                        var set = R.Set("lastIndex", NumberValue.PositiveZero, true);
                        if (set.IsAbrupt())
                        {
                            return(set);
                        }
                        return(Completion.NormalCompletion(NullValue.Instance));
                    }
                    lastIndex = AdvanceStringIndex(S, lastIndex, fullUnicode);
                }
                else
                {
                    matchSucceeded = true;
                }
            }

            var e = r !.Index + r.Length;

            if (fullUnicode)
            {
                // e is an index into the Input character list, derived from S, matched by matcher.
                // Let eUTF be the smallest index into S that corresponds to the character at element e of Input.
                // If e is greater than or equal to the number of elements in Input, then eUTF is the number of code units in S.
                // Set e to eUTF.
                var indexes = StringInfo.ParseCombiningCharacters(S);
                if (r.Index < indexes.Length)
                {
                    var sub = StringInfo.GetNextTextElement(S, r.Index);
                    e += sub.Length - 1;
                }
            }
            if (global || sticky)
            {
                var set = R.Set("lastIndex", new NumberValue(e), true);
                if (set.IsAbrupt())
                {
                    return(set);
                }
            }
            var n = r.Groups.Count;
            var A = ArrayObject.ArrayCreate(n + 1);

            Utils.CreateDataProperty(A, "index", new NumberValue(lastIndex));
            Utils.CreateDataProperty(A, "input", new StringValue(S));
            Utils.CreateDataProperty(A, "0", new StringValue(r.Value));
            IValue groups;

            if (R.RegExpMatcher.GetGroupNames().Any())
            {
                groups = Utils.ObjectCreate(null);
            }
            else
            {
                groups = UndefinedValue.Instance;
            }
            Utils.CreateDataProperty(A, "groups", groups);
            for (int i = 0; i <= n; i++)
            {
                var    captureI = r.Groups[i];
                IValue capturedValue;
                if (captureI.Success)
                {
                    if (fullUnicode)
                    {
                        capturedValue = new StringValue(StringInfo.GetNextTextElement(S, captureI.Index));
                    }
                    else
                    {
                        capturedValue = new StringValue(captureI.Value);
                    }
                }
                else
                {
                    capturedValue = UndefinedValue.Instance;
                }
                Utils.CreateDataProperty(A, i.ToString(CultureInfo.InvariantCulture), capturedValue);
                if (!string.IsNullOrEmpty(captureI.Name))
                {
                    Utils.CreateDataProperty(groups, captureI.Name, capturedValue);
                }
            }
            return(Completion.NormalCompletion(A));
        }
예제 #4
0
        public override Completion InternalConstruct(IReadOnlyList <IValue> arguments, Object?newTarget)
        {
            if (newTarget == null)
            {
                newTarget = this;
            }
            var proto = Utils.GetPrototypeFromConstructor(newTarget, i => i.ArrayPrototype);

            if (proto.IsAbrupt())
            {
                return(proto);
            }

            if (arguments.Count == 0)
            {
                return(Completion.NormalCompletion(ArrayObject.ArrayCreate(0, proto.value as Object)));
            }
            else if (arguments.Count == 1)
            {
                var array = ArrayObject.ArrayCreate(0, proto.value as Object);

                int intLen;

                if (!(arguments[0] is NumberValue))
                {
                    var defineStatus = Utils.CreateDataProperty(array, "0", arguments[0]);
                    if (!defineStatus.Other)
                    {
                        throw new InvalidOperationException("CreateDataProperty [0] in array constructor failed. Spec 22.1.1.2 step 6b");
                    }
                    intLen = 1;
                }
                else
                {
                    intLen = (int)(arguments[0] as NumberValue) !.number;
                    if (intLen != (arguments[0] as NumberValue) !.number || intLen < 0)
                    {
                        return(Completion.ThrowRangeError("length argument cannot be used as a length"));
                    }
                }
                array.Set("length", new NumberValue(intLen), true);
                return(Completion.NormalCompletion(array));
            }
            else
            {
                var array = ArrayObject.ArrayCreate(arguments.Count, proto.value as Object);
                int k     = 0;
                foreach (var arg in arguments)
                {
                    var defineStatus = Utils.CreateDataProperty(array, k.ToString(System.Globalization.CultureInfo.InvariantCulture), arg);
                    if (!defineStatus.Other)
                    {
                        throw new InvalidOperationException("CreateDataProperty in array constructor failed. Spec 22.1.1.3 step 8d");
                    }
                    k++;
                }
                if ((array.Get("length").value as NumberValue) !.number != arguments.Count)
                {
                    throw new InvalidOperationException("array length is invalid. Spec 22.1.1.3 step 9");
                }
                return(Completion.NormalCompletion(array));
            }
        }