Пример #1
0
        public Arguments(BuiltinCall activation)
        {
            this.activation = activation;

            IScriptable parent = activation.ParentScope;

            ParentScope = parent;
            SetPrototype(ScriptableObject.GetObjectPrototype(parent));

            args      = activation.originalArgs;
            lengthObj = (int)args.Length;

            BuiltinFunction f = activation.function;

            calleeObj = f;

            Context.Versions version = f.LanguageVersion;
            if (version <= Context.Versions.JS1_3 && version != Context.Versions.Default)
            {
                callerObj = null;
            }
            else
            {
                callerObj = UniqueTag.NotFound;
            }
        }
        internal InterpreterData(Context.Versions languageVersion, string sourceFile, string encodedSource)
        {
            this.languageVersion = languageVersion;
            this.itsSourceFile = sourceFile;
            this.encodedSource = encodedSource;

            Init ();
        }
Пример #3
0
        internal InterpreterData(Context.Versions languageVersion, string sourceFile, string encodedSource)
        {
            this.languageVersion = languageVersion;
            this.itsSourceFile   = sourceFile;
            this.encodedSource   = encodedSource;

            Init();
        }
        internal InterpreterData(InterpreterData parent)
        {
            this.parentData = parent;
            this.languageVersion = parent.languageVersion;
            this.itsSourceFile = parent.itsSourceFile;
            this.encodedSource = parent.encodedSource;

            Init ();
        }
 public CompilerEnvirons()
 {
     errorReporter = DefaultErrorReporter.instance;
     languageVersion = Context.Versions.Default;
     generateDebugInfo = true;
     useDynamicScope = false;
     reservedKeywordAsIdentifier = false;
     allowMemberExprAsFunctionName = false;
     xmlAvailable = true;
     optimizationLevel = 0;
     generatingSource = true;
 }
Пример #6
0
        /*
         * See ECMA 15.5.4.8.  Modified to match JS 1.2 - optionally takes
         * a limit argument and accepts a regular expression as the split
         * argument.
         */
        private static object ImplSplit(Context cx, IScriptable scope, string target, object [] args)
        {
            // create an empty Array to return;
            IScriptable top    = GetTopLevelScope(scope);
            IScriptable result = ScriptRuntime.NewObject(cx, top, "Array", null);

            // return an array consisting of the target if no separator given
            // don't check against undefined, because we want
            // 'fooundefinedbar'.split(void 0) to split to ['foo', 'bar']
            if (args.Length < 1)
            {
                result.Put(0, result, target);
                return(result);
            }

            // Use the second argument as the split limit, if given.
            bool limited = (args.Length > 1) && (args [1] != Undefined.Value);
            long limit   = 0; // Initialize to avoid warning.

            if (limited)
            {
                /* Clamp limit between 0 and 1 + string length. */
                limit = ScriptConvert.ToUint32(args [1]);
                if (limit > target.Length)
                {
                    limit = 1 + target.Length;
                }
            }

            string separator = null;

            int []      matchlen = new int [1];
            IScriptable re       = null;
            RegExpProxy reProxy  = null;

            if (args [0] is IScriptable)
            {
                reProxy = cx.RegExpProxy;
                if (reProxy != null)
                {
                    IScriptable test = (IScriptable)args [0];
                    if (reProxy.IsRegExp(test))
                    {
                        re = test;
                    }
                }
            }
            if (re == null)
            {
                separator    = ScriptConvert.ToString(args [0]);
                matchlen [0] = separator.Length;
            }

            // split target with separator or re
            int [] ip = new int [] { 0 };
            int    match;
            int    len = 0;

            bool []          matched = new bool [] { false };
            string [] []     parens  = new string [] [] { null };
            Context.Versions version = cx.Version;
            while ((match = find_split(cx, scope, target, separator, version, reProxy, re, ip, matchlen, matched, parens)) >= 0)
            {
                if ((limited && len >= limit) || (match > target.Length))
                {
                    break;
                }

                string substr;
                if (target.Length == 0)
                {
                    substr = target;
                }
                else
                {
                    substr = target.Substring(ip [0], (match) - (ip [0]));
                }

                result.Put(len, result, substr);
                len++;

                /*
                 * Imitate perl's feature of including parenthesized substrings
                 * that matched part of the delimiter in the new array, after the
                 * split substring that was delimited.
                 */
                // CB, 02.01.2007: Don't do this, causes bug #287630
                // https://bugzilla.mozilla.org/show_bug.cgi?query_format=specific&order=relevance+desc&bug_status=__open__&id=287630

                /*
                 * if (re != null && matched [0] == true) {
                 *  int size = parens [0].Length;
                 *  for (int num = 0; num < size; num++) {
                 *      if (limited && len >= limit)
                 *          break;
                 *      result.Put (len, result, parens [0] [num]);
                 *      len++;
                 *  }
                 *  matched [0] = false;
                 * }
                 */
                ip [0] = match + matchlen [0];

                if (version < Context.Versions.JS1_3 && version != Context.Versions.Default)
                {
                    /*
                     * Deviate from ECMA to imitate Perl, which omits a final
                     * split unless a limit argument is given and big enough.
                     */
                    if (!limited && ip [0] == target.Length)
                    {
                        break;
                    }
                }
            }
            return(result);
        }
Пример #7
0
        /*
         * Used by js_split to find the next split point in target,
         * starting at offset ip and looking either for the given
         * separator substring, or for the next re match.  ip and
         * matchlen must be reference variables (assumed to be arrays of
         * length 1) so they can be updated in the leading whitespace or
         * re case.
         *
         * Return -1 on end of string, >= 0 for a valid index of the next
         * separator occurrence if found, or the string length if no
         * separator is found.
         */
        private static int find_split(Context cx, IScriptable scope, string target, string separator, Context.Versions version, RegExpProxy reProxy, IScriptable re, int [] ip, int [] matchlen, bool [] matched, string [] [] parensp)
        {
            int i      = ip [0];
            int length = target.Length;

            /*
             * Perl4 special case for str.split(' '), only if the user has selected
             * JavaScript1.2 explicitly.  Split on whitespace, and skip leading w/s.
             * Strange but true, apparently modeled after awk.
             */
            if (version == Context.Versions.JS1_2 && re == null && separator.Length == 1 && separator [0] == ' ')
            {
                /* Skip leading whitespace if at front of str. */
                if (i == 0)
                {
                    while (i < length && char.IsWhiteSpace(target [i]))
                    {
                        i++;
                    }
                    ip [0] = i;
                }

                /* Don't delimit whitespace at end of string. */
                if (i == length)
                {
                    return(-1);
                }

                /* Skip over the non-whitespace chars. */
                while (i < length && !char.IsWhiteSpace(target [i]))
                {
                    i++;
                }

                /* Now skip the next run of whitespace. */
                int j = i;
                while (j < length && char.IsWhiteSpace(target [j]))
                {
                    j++;
                }

                /* Update matchlen to count delimiter chars. */
                matchlen [0] = j - i;
                return(i);
            }

            /*
             * Stop if past end of string.  If at end of string, we will
             * return target length, so that
             *
             *  "ab,".split(',') => new Array("ab", "")
             *
             * and the resulting array converts back to the string "ab,"
             * for symmetry.  NB: This differs from perl, which drops the
             * trailing empty substring if the LIMIT argument is omitted.
             */
            if (i > length)
            {
                return(-1);
            }

            /*
             * Match a regular expression against the separator at or
             * above index i.  Return -1 at end of string instead of
             * trying for a match, so we don't get stuck in a loop.
             */
            if (re != null)
            {
                return(reProxy.FindSplit(cx, scope, target, separator, re, ip, matchlen, matched, parensp));
            }

            /*
             * Deviate from ECMA by never splitting an empty string by any separator
             * string into a non-empty array (an array of length 1 that contains the
             * empty string).
             */
            if (version != Context.Versions.Default && version < Context.Versions.JS1_3 && length == 0)
            {
                return(-1);
            }

            /*
             * Special case: if sep is the empty string, split str into
             * one character substrings.  Let our caller worry about
             * whether to split once at end of string into an empty
             * substring.
             *
             * For 1.2 compatibility, at the end of the string, we return the length as
             * the result, and set the separator length to 1 -- this allows the caller
             * to include an additional null string at the end of the substring list.
             */
            if (separator.Length == 0)
            {
                if (version == Context.Versions.JS1_2)
                {
                    if (i == length)
                    {
                        matchlen [0] = 1;
                        return(i);
                    }
                    return(i + 1);
                }
                return((i == length) ? -1 : i + 1);
            }

            /* Punt to j.l.s.indexOf; return target length if seperator is
             * not found.
             */
            if (ip [0] >= length)
            {
                return(length);
            }

            i = target.IndexOf(separator, ip [0]);

            return((i != -1) ? i : length);
        }
        public virtual void initFromContext(Context cx)
        {
            setErrorReporter (cx.ErrorReporter);
            this.languageVersion = cx.Version;
            useDynamicScope = cx.compileFunctionsWithDynamicScopeFlag;
            generateDebugInfo = (!cx.GeneratingDebugChanged || cx.GeneratingDebug);
            reservedKeywordAsIdentifier = cx.HasFeature (Context.Features.ReservedKeywordAsIdentifier);
            allowMemberExprAsFunctionName = cx.HasFeature (Context.Features.MemberExprAsFunctionName);
            xmlAvailable = cx.HasFeature (Context.Features.E4x);
            getterAndSetterSupport = cx.HasFeature (Context.Features.GetterAndSetter);

            optimizationLevel = cx.OptimizationLevel;

            generatingSource = cx.GeneratingSource;
            activationNames = cx.activationNames;
        }
Пример #9
0
        private static SubString interpretDollar(Context cx, RegExpImpl res, string da, int dp, int [] skip)
        {
            char dc;
            int  num, tmp;

            if (da [dp] != '$')
            {
                Context.CodeBug();
            }

            /* Allow a real backslash (literal "\\") to escape "$1" etc. */
            Context.Versions version = cx.Version;
            if (version != Context.Versions.Default && version <= Context.Versions.JS1_4)
            {
                if (dp > 0 && da [dp - 1] == '\\')
                {
                    return(null);
                }
            }
            int daL = da.Length;

            if (dp + 1 >= daL)
            {
                return(null);
            }
            /* Interpret all Perl match-induced dollar variables. */
            dc = da [dp + 1];
            if (BuiltinRegExp.isDigit(dc))
            {
                int cp;
                if (version != Context.Versions.Default && version <= Context.Versions.JS1_4)
                {
                    if (dc == '0')
                    {
                        return(null);
                    }
                    /* Check for overflow to avoid gobbling arbitrary decimal digits. */
                    num = 0;
                    cp  = dp;
                    while (++cp < daL && BuiltinRegExp.isDigit(dc = da [cp]))
                    {
                        tmp = 10 * num + (dc - '0');
                        if (tmp < num)
                        {
                            break;
                        }
                        num = tmp;
                    }
                }
                else
                {
                    /* ECMA 3, 1-9 or 01-99 */
                    int parenCount = (res.parens == null) ? 0 : res.parens.Length;
                    num = dc - '0';
                    if (num > parenCount)
                    {
                        return(null);
                    }
                    cp = dp + 2;
                    if ((dp + 2) < daL)
                    {
                        dc = da [dp + 2];
                        if (BuiltinRegExp.isDigit(dc))
                        {
                            tmp = 10 * num + (dc - '0');
                            if (tmp <= parenCount)
                            {
                                cp++;
                                num = tmp;
                            }
                        }
                    }
                    if (num == 0)
                    {
                        return(null); /* $0 or $00 is not valid */
                    }
                }
                /* Adjust num from 1 $n-origin to 0 array-index-origin. */
                num--;
                skip [0] = cp - dp;
                return(res.getParenSubString(num));
            }

            skip [0] = 2;
            switch (dc)
            {
            case '$':
                return(new SubString("$"));

            case '&':
                return(res.lastMatch);

            case '+':
                return(res.lastParen);

            case '`':
                if (version == Context.Versions.JS1_2)
                {
                    /*
                     * JS1.2 imitated the Perl4 bug where left context at each step
                     * in an iterative use of a global regexp started from last match,
                     * not from the start of the target string.  But Perl4 does start
                     * $` at the beginning of the target string when it is used in a
                     * substitution, so we emulate that special case here.
                     */
                    res.leftContext.index  = 0;
                    res.leftContext.length = res.lastMatch.index;
                }
                return(res.leftContext);

            case '\'':
                return(res.rightContext);
            }
            return(null);
        }
Пример #10
0
        public virtual int FindSplit(Context cx, IScriptable scope, string target, string separator, IScriptable reObj, int [] ip, int [] matchlen, bool [] matched, string [] [] parensp)
        {
            int i      = ip [0];
            int length = target.Length;
            int result;

            Context.Versions version = cx.Version;
            BuiltinRegExp    re      = (BuiltinRegExp)reObj;

            while (true)
            {
                // imitating C label
                /* JS1.2 deviated from Perl by never matching at end of string. */
                int ipsave = ip [0]; // reuse ip to save object creation
                ip [0] = i;
                object ret = re.executeRegExp(cx, scope, this, target, ip, BuiltinRegExp.TEST);
                if (ret == null || !ret.Equals(true))
                {
                    // Mismatch: ensure our caller advances i past end of string.
                    ip [0]       = ipsave;
                    matchlen [0] = 1;
                    matched [0]  = false;
                    return(length);
                }
                i           = ip [0];
                ip [0]      = ipsave;
                matched [0] = true;

                SubString sep = this.lastMatch;
                matchlen [0] = sep.length;
                if (matchlen [0] == 0)
                {
                    /*
                     * Empty string match: never split on an empty
                     * match at the start of a find_split cycle.  Same
                     * rule as for an empty global match in
                     * match_or_replace.
                     */
                    if (i == ip [0])
                    {
                        /*
                         * "Bump-along" to avoid sticking at an empty
                         * match, but don't bump past end of string --
                         * our caller must do that by adding
                         * sep->length to our return value.
                         */
                        if (i == length)
                        {
                            if (version == Context.Versions.JS1_2)
                            {
                                matchlen [0] = 1;
                                result       = i;
                            }
                            else
                            {
                                result = -1;
                            }
                            break;
                        }
                        i++;

                        goto again; // imitating C goto
                    }
                }
                // PR_ASSERT((size_t)i >= sep->length);
                result = i - matchlen [0];
                break;


again:
                ;
            }
            int size = (parens == null) ? 0 : parens.Length;

            parensp [0] = new string [size];
            for (int num = 0; num < size; num++)
            {
                SubString parsub = getParenSubString(num);
                parensp [0] [num] = parsub.ToString();
            }
            return(result);
        }