Пример #1
0
        public static void ImportType(IScriptable scope, Type type)
        {
            if (!type.IsPublic)
            {
                return;
            }

            if (ScriptRuntime.IsNativeRuntimeType(type))
            {
                return;
            }

            // Cannot define 'Object'
            if (type.Name == "Object")
            {
                return;
            }


            string [] ns = type.FullName.Split('.');

            IScriptable parent = scope;

            for (int i = 0; i < ns.Length - 1; i++)
            {
                IScriptable obj = (parent.Get(ns [i], parent) as IScriptable);
                if (obj == null)
                {
                    obj = new BuiltinObject();
                    parent.Put(ns [i], parent, obj);
                }
                parent = obj;
            }

            object thisObj = null;

            if (type.IsEnum)
            {
                thisObj = new CliEnum((Enum)Activator.CreateInstance(type));
            }
            else
            {
                thisObj = CliType.GetNativeCliType(type);
            }
            // Define as toplevel object
            scope.Put(ns [ns.Length - 1], scope, thisObj);

            // Define as full qualified name
            parent.Put(ns [ns.Length - 1], parent, thisObj);
        }
Пример #2
0
            internal void Set(int id, IScriptable start, object value)
            {
                if (value == UniqueTag.NotFound)
                {
                    throw new ArgumentException();
                }
                EnsureId(id);
                int attr = attributeArray [id - 1];

                if ((attr & ScriptableObject.READONLY) == 0)
                {
                    if (start == obj)
                    {
                        if (value == null)
                        {
                            value = UniqueTag.NullValue;
                        }
                        int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT;
                        lock (this) {
                            valueArray [valueSlot] = value;
                        }
                    }
                    else
                    {
                        int    nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT;
                        string name     = (string)valueArray [nameSlot];
                        start.Put(name, start, value);
                    }
                }
            }
Пример #3
0
        public override object Put(string name, IScriptable start, object value)
        {
            int info = FindInstanceIdInfo(name);

            if (info != 0)
            {
                if (start == this && Sealed)
                {
                    throw Context.ReportRuntimeErrorById("msg.modify.sealed", name);
                }
                int attr = (int)((uint)info >> 16);
                if ((attr & READONLY) == 0)
                {
                    if (start == this)
                    {
                        int id = (info & 0xFFFF);
                        SetInstanceIdValue(id, value);
                    }
                    else
                    {
                        return(start.Put(name, start, value));
                    }
                }
                else
                {
                    ReadOnlyPropertyChanged(name);
                }
                return(value);
            }
            if (prototypeValues != null)
            {
                int id = prototypeValues.FindId(name);
                if (id != 0)
                {
                    if (start == this && Sealed)
                    {
                        throw Context.ReportRuntimeErrorById("msg.modify.sealed", name);
                    }
                    prototypeValues.Set(id, start, value);
                    return(value);
                }
            }
            return(base.Put(name, start, value));
        }
Пример #4
0
        public static void ImportType(IScriptable scope, Type type)
        {
            if (!type.IsPublic)
                return;

            if (ScriptRuntime.IsNativeRuntimeType (type))
                return;

            // Cannot define 'Object'
            if (type.Name == "Object")
                return;

            string [] ns = type.FullName.Split ('.');

            IScriptable parent = scope;
            for (int i = 0; i < ns.Length - 1; i++) {
                IScriptable obj = (parent.Get (ns [i], parent) as IScriptable);
                if (obj == null) {
                    obj = new BuiltinObject ();
                    parent.Put (ns [i], parent, obj);
                }
                parent = obj;
            }

            object thisObj = null;
            if (type.IsEnum) {
                thisObj = new CliEnum ((Enum)Activator.CreateInstance (type));
            }
            else {
                thisObj = CliType.GetNativeCliType (type);

            }
            // Define as toplevel object
            scope.Put (ns [ns.Length - 1], scope, thisObj);

            // Define as full qualified name
            parent.Put (ns [ns.Length - 1], parent, thisObj);
        }
 /// <summary> Utility method to add properties to arbitrary Scriptable object.
 /// If destination is instance of ScriptableObject, calls
 /// defineProperty there, otherwise calls put in destination
 /// ignoring attributes
 /// </summary>
 public static void DefineProperty (IScriptable destination, string propertyName, object value, int attributes)
 {
     if (!(destination is ScriptableObject)) {
         destination.Put (propertyName, destination, value);
         return;
     }
     ScriptableObject so = (ScriptableObject)destination;
     so.DefineProperty (propertyName, value, attributes);
 }
 /// <summary> Sets the value of the indexed property, creating it if need be.
 /// 
 /// </summary>
 /// <param name="index">the numeric index for the property
 /// </param>
 /// <param name="start">the object whose property is being set
 /// </param>
 /// <param name="value">value to set the property to
 /// </param>
 public virtual object Put (int index, IScriptable start, object value)
 {
     Slot slot = GetSlot (null, index);
     if (slot == null) {
         if (start != this) {
             return start.Put (index, start, value);
         }
         slot = AddSlot (null, index, null);
     }
     if (start == this && Sealed) {
         throw Context.ReportRuntimeErrorById ("msg.modify.sealed", Convert.ToString (index));
     }
     if ((slot.attributes & ScriptableObject.READONLY) != 0) {
         return slot.GetValue (null, start, start); // TODO: ???
     }
     if (this == start) {
         return slot.SetValue (null, start, start, value);
     }
     else {
         return start.Put (index, start, value);
     }
 }
 /// <summary> Sets the value of the named property, creating it if need be.
 /// 
 /// If the property was created using defineProperty, the
 /// appropriate setter method is called. <p>
 /// 
 /// If the property's attributes include READONLY, no action is
 /// taken.
 /// This method will actually set the property in the start
 /// object.
 /// 
 /// </summary>
 /// <param name="name">the name of the property
 /// </param>
 /// <param name="start">the object whose property is being set
 /// </param>
 /// <param name="value">value to set the property to
 /// </param>
 public virtual object Put (string name, IScriptable start, object value)
 {
     Slot slot = lastAccess; // Get local copy
     if ((object)name != (object)slot.stringKey || slot.wasDeleted != 0) {
         int hash = name.GetHashCode ();
         slot = GetSlot (name, hash);
         if (slot == null) {
             if (start != this) {
                 start.Put (name, start, value);
                 return value;
             }
             slot = AddSlot (name, hash, null);
         }
         // Note: cache is not updated in put
     }
     if (start == this && Sealed) {
         throw Context.ReportRuntimeErrorById ("msg.modify.sealed", name);
     }
     if ((slot.attributes & ScriptableObject.READONLY) != 0) {
         // FINDME                
         Context cx = Context.CurrentContext;
         if (cx.Version == Context.Versions.JS1_2) {
             throw Context.ReportRuntimeErrorById ("msg.read-only", name);
         } else {
             if (cx.HasFeature (Context.Features.Strict)) {
                 Context.ReportWarningById ("msg.read-only", name);                        
             }
         }
         return value;
     }
     if (this == start) {
         return slot.SetValue (null, start, start, value);
     }
     else {
         if (slot.setter != null) {
             Slot newSlot = (Slot)slot.Clone ();
             ((ScriptableObject)start).AddSlotImpl (newSlot.stringKey, newSlot.intKey, newSlot);
             return newSlot.SetValue (null, start, start, value);
         }
         else {
             return start.Put (name, start, value);
         }
     }
     return value;
 }
Пример #8
0
 public override object Put (string name, IScriptable start, object value)
 {
     int info = FindInstanceIdInfo (name);
     if (info != 0) {
         if (start == this && Sealed) {
             throw Context.ReportRuntimeErrorById ("msg.modify.sealed", name);
         }
         int attr = (int)((uint)info >> 16);
         if ((attr & READONLY) == 0) {
             if (start == this) {
                 int id = (info & 0xFFFF);
                 SetInstanceIdValue (id, value);
             }
             else {
                 return start.Put (name, start, value);
             }
         } else {
             ReadOnlyPropertyChanged (name);
         }
         return value;
     }
     if (prototypeValues != null) {
         int id = prototypeValues.FindId (name);
         if (id != 0) {
             if (start == this && Sealed) {
                 throw Context.ReportRuntimeErrorById ("msg.modify.sealed", name);
             }
             prototypeValues.Set (id, start, value);
             return value;
         }
     }
     return base.Put (name, start, value);
 }
Пример #9
0
 internal void Set (int id, IScriptable start, object value)
 {
     if (value == UniqueTag.NotFound)
         throw new ArgumentException ();
     EnsureId (id);
     int attr = attributeArray [id - 1];
     if ((attr & ScriptableObject.READONLY) == 0) {
         if (start == obj) {
             if (value == null) {
                 value = UniqueTag.NullValue;
             }
             int valueSlot = (id - 1) * SLOT_SPAN + VALUE_SLOT;
             lock (this) {
                 valueArray [valueSlot] = value;
             }
         }
         else {
             int nameSlot = (id - 1) * SLOT_SPAN + NAME_SLOT;
             string name = (string)valueArray [nameSlot];
             start.Put (name, start, value);
         }
     }
 }
Пример #10
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();
            }
        }
Пример #11
0
 /// <summary> Sets the value of the named property, creating it if need be.
 /// 
 /// If the property was created using defineProperty, the
 /// appropriate setter method is called. <p>
 /// 
 /// If the property's attributes include READONLY, no action is
 /// taken.
 /// This method will actually set the property in the start
 /// object.
 /// 
 /// </summary>
 /// <param name="name">the name of the property
 /// </param>
 /// <param name="start">the object whose property is being set
 /// </param>
 /// <param name="value">value to set the property to
 /// </param>
 public virtual object Put (string name, IScriptable start, object value)
 {
     Slot slot = lastAccess; // Get local copy
     if ((object)name != (object)slot.stringKey || slot.wasDeleted != 0) {
         int hash = name.GetHashCode ();
         slot = GetSlot (name, hash);
         if (slot == null) {
             if (start != this) {
                 start.Put (name, start, value);
                 return value;
             }
             slot = AddSlot (name, hash, null);
         }
         // Note: cache is not updated in put
     }
     if (start == this && Sealed) {
         throw Context.ReportRuntimeErrorById ("msg.modify.sealed", name);
     }
     if ((slot.attributes & ScriptableObject.READONLY) != 0) {
         ReadOnlyPropertyChanged (name);
         return value;
     }
     if (this == start) {
         return slot.SetValue (null, start, start, value);
     }
     else {
         if (slot.setter != null) {
             Slot newSlot = (Slot)slot.Clone ();
             ((ScriptableObject)start).AddSlotImpl (newSlot.stringKey, newSlot.intKey, newSlot);
             return newSlot.SetValue (null, start, start, value);
         }
         else {
             return start.Put (name, start, value);
         }
     }
     return value;
 }
Пример #12
0
 private static object doScriptableIncrDecr(IScriptable target, string id, IScriptable protoChainStart, object value, int incrDecrMask)
 {
     bool post = ((incrDecrMask & Node.POST_FLAG) != 0);
     double number;
     if (CliHelper.IsNumber (value)) {
         number = Convert.ToDouble (value);
     }
     else {
         number = ScriptConvert.ToNumber (value);
         if (post) {
             // convert result to number
             value = number;
         }
     }
     if ((incrDecrMask & Node.DECR_FLAG) == 0) {
         ++number;
     }
     else {
         --number;
     }
     object result = number;
     target.Put (id, protoChainStart, result);
     if (post) {
         return value;
     }
     else {
         return result;
     }
 }
Пример #13
0
 public static object setName(IScriptable bound, object value, Context cx, IScriptable scope, string id)
 {
     if (bound != null) {
         if (bound is XMLObject) {
             XMLObject xmlObject = (XMLObject)bound;
             xmlObject.EcmaPut (cx, id, value);
         }
         else {
             ScriptableObject.PutProperty (bound, id, value);
         }
     }
     else {
         // "newname = 7;", where 'newname' has not yet
         // been defined, creates a new property in the
         // top scope unless strict mode is specified.
         if (cx.HasFeature (Context.Features.StrictVars)) {
             throw Context.ReportRuntimeErrorById ("msg.assn.create.strict", id);
         }
         // Find the top scope by walking up the scope chain.
         bound = ScriptableObject.GetTopLevelScope (scope);
         if (cx.useDynamicScope) {
             bound = checkDynamicScope (cx.topCallScope, bound);
         }
         bound.Put (id, bound, value);
     }
     return value;
 }
Пример #14
0
 public static void initFunction(Context cx, IScriptable scope, BuiltinFunction function, int type, bool fromEvalCode)
 {
     if (type == FunctionNode.FUNCTION_STATEMENT) {
         string name = function.FunctionName;
         if (name != null && name.Length != 0) {
             if (!fromEvalCode) {
                 // ECMA specifies that functions defined in global and
                 // function scope outside eval should have DONTDELETE set.
                 ScriptableObject.DefineProperty (scope, name, function, ScriptableObject.PERMANENT);
             }
             else {
                 scope.Put (name, scope, function);
             }
         }
     }
     else if (type == FunctionNode.FUNCTION_EXPRESSION_STATEMENT) {
         string name = function.FunctionName;
         if (name != null && name.Length != 0) {
             // Always put function expression statements into initial
             // activation object ignoring the with statement to follow
             // SpiderMonkey
             while (scope is BuiltinWith) {
                 scope = scope.ParentScope;
             }
             scope.Put (name, scope, function);
         }
     }
     else {
         throw Context.CodeBug ();
     }
 }
Пример #15
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);
        }
Пример #16
0
 public virtual object Put(string name, IScriptable start, object value)
 {
     return(obj.Put(name, start, value));
 }