Пример #1
0
        /// <summary> Convert the value to an object.
        ///
        /// See ECMA 9.9.
        /// </summary>
        public static IScriptable ToObject(Context cx, IScriptable scope, object val)
        {
            if (val is IScriptable)
            {
                return((IScriptable)val);
            }
            if (val == null)
            {
                throw ScriptRuntime.TypeErrorById("msg.null.to.object");
            }
            if (val == Undefined.Value)
            {
                throw ScriptRuntime.TypeErrorById("msg.undef.to.object");
            }
            string className = val is string? "String" : (CliHelper.IsNumber(val) ? "Number" : (val is bool? "Boolean" : null));

            if (className != null)
            {
                object [] args = new object [] { val };
                scope = ScriptableObject.GetTopLevelScope(scope);
                return(ScriptRuntime.NewObject(cx == null ? Context.CurrentContext : cx, scope, className, args));
            }

            // Extension: Wrap as a LiveConnect object.
            object wrapped = cx.Wrap(scope, val, null);

            if (wrapped is IScriptable)
            {
                return((IScriptable)wrapped);
            }
            throw ScriptRuntime.errorWithClassName("msg.invalid.type", val);
        }
Пример #2
0
        /*
         * Analog of match_glob() in jsstr.c
         */
        private static void match_glob(GlobData mdata, Context cx, IScriptable scope, int count, RegExpImpl reImpl)
        {
            if (mdata.arrayobj == null)
            {
                IScriptable s = ScriptableObject.GetTopLevelScope(scope);
                mdata.arrayobj = ScriptRuntime.NewObject(cx, s, "Array", null);
            }
            SubString matchsub = reImpl.lastMatch;
            string    matchstr = matchsub.ToString();

            mdata.arrayobj.Put(count, mdata.arrayobj, matchstr);
        }
Пример #3
0
        public static void Init(Context cx, IScriptable scope, bool zealed)
        {
            BuiltinGlobal obj = new BuiltinGlobal();

            for (int id = 1; id <= LAST_SCOPE_FUNCTION_ID; ++id)
            {
                string name;
                int    arity = 1;
                switch (id)
                {
                case Id_decodeURI:
                    name = "decodeURI";
                    break;

                case Id_decodeURIComponent:
                    name = "decodeURIComponent";
                    break;

                case Id_encodeURI:
                    name = "encodeURI";
                    break;

                case Id_encodeURIComponent:
                    name = "encodeURIComponent";
                    break;

                case Id_escape:
                    name = "escape";
                    break;

                case Id_eval:
                    name = "eval";
                    break;

                case Id_isFinite:
                    name = "isFinite";
                    break;

                case Id_isNaN:
                    name = "isNaN";
                    break;

                case Id_isXMLName:
                    name = "isXMLName";
                    break;

                case Id_parseFloat:
                    name = "parseFloat";
                    break;

                case Id_parseInt:
                    name  = "parseInt";
                    arity = 2;
                    break;

                case Id_unescape:
                    name = "unescape";
                    break;

                case Id_uneval:
                    name = "uneval";
                    break;

                default:
                    throw Context.CodeBug();
                }
                IdFunctionObject f = new IdFunctionObject(obj, FTAG, id, name, arity, scope);
                if (zealed)
                {
                    f.SealObject();
                }
                f.ExportAsScopeProperty();
            }

            ScriptableObject.DefineProperty(scope, "NaN", (object)double.NaN, ScriptableObject.DONTENUM);
            ScriptableObject.DefineProperty(scope, "Infinity", (System.Double.PositiveInfinity), ScriptableObject.DONTENUM);
            ScriptableObject.DefineProperty(scope, "undefined", Undefined.Value, ScriptableObject.DONTENUM);

            string [] errorMethods = new string [] {
                "ConversionError",
                "EvalError",
                "RangeError",
                "ReferenceError",
                "SyntaxError",
                "TypeError",
                "URIError",
                "InternalError",
                "JavaException"
            };

            /*
             * Each error constructor gets its own Error object as a prototype,
             * with the 'name' property set to the name of the error.
             */
            for (int i = 0; i < errorMethods.Length; i++)
            {
                string      name       = errorMethods [i];
                IScriptable errorProto = ScriptRuntime.NewObject(cx, scope, "Error", ScriptRuntime.EmptyArgs);
                errorProto.Put("name", errorProto, name);
                if (zealed)
                {
                    if (errorProto is ScriptableObject)
                    {
                        ((ScriptableObject)errorProto).SealObject();
                    }
                }
                IdFunctionObject ctor = new IdFunctionObject(obj, FTAG, Id_new_CommonError, name, 1, scope);
                ctor.MarkAsConstructor(errorProto);
                if (zealed)
                {
                    ctor.SealObject();
                }
                ctor.ExportAsScopeProperty();
            }
        }
Пример #4
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);
        }