Esempio n. 1
0
        internal override SObject GetMember(ScriptProcessor processor, SObject accessor, bool isIndexer)
        {
            if (isIndexer && accessor.TypeOf() == LiteralTypeNumber)
            {
                if (Prototype.GetIndexerGetFunction() != IndexerGetFunction)
                {
                    IndexerGetFunction = Prototype.GetIndexerGetFunction();
                }

                return(IndexerGetFunction != null?IndexerGetFunction.Call(processor, this, this, new[] { accessor }) : processor.Undefined);
            }

            var accessorAsString = accessor as SString;
            var memberName       = accessorAsString != null ? accessorAsString.Value : accessor.ToString(processor).Value;

            if (Members.ContainsKey(PropertyGetPrefix + memberName)) // getter property
            {
                return(((SFunction)Members[PropertyGetPrefix + memberName].Data).Call(processor, this, this, new SObject[] { }));
            }
            if (Members.ContainsKey(memberName))
            {
                return(Members[memberName]);
            }
            if (Prototype != null && Prototype.HasMember(processor, memberName))
            {
                return(Prototype.GetMember(processor, accessor, isIndexer));
            }
            if (SuperClass != null)
            {
                return(SuperClass.GetMember(processor, accessor, isIndexer));
            }

            return(processor.Undefined);
        }
Esempio n. 2
0
        /// <summary>
        /// Compares two objects for equality, respecting their typings.
        /// </summary>
        /// <remarks>Used by the === and !== equality operators.</remarks>
        public static bool StrictEquals(ScriptProcessor processor, SObject left, SObject right)
        {
            left  = SObject.Unbox(left);
            right = SObject.Unbox(right);

            if (left.TypeOf() != right.TypeOf())
            {
                return(false);
            }
            // If they are undefined or null, return true:
            if (left.TypeOf() == SObject.LiteralUndefined || left.TypeOf() == SObject.LiteralNull)
            {
                return(true);
            }
            // Both are numbers:
            if (left.TypeOf() == SObject.LiteralTypeNumber)
            {
                var numLeft  = ((SNumber)left).Value;
                var numRight = ((SNumber)right).Value;

                return(Math.Abs(numLeft - numRight) < double.Epsilon);
            }
            // Both are string:
            if (left.TypeOf() == SObject.LiteralTypeString)
            {
                var strLeft  = ((SString)left).Value;
                var strRight = ((SString)right).Value;

                return(strLeft == strRight);
            }
            // Both are bool:
            if (left.TypeOf() == SObject.LiteralTypeBool)
            {
                var boolLeft  = ((SBool)left).Value;
                var boolRight = ((SBool)right).Value;

                return(boolLeft == boolRight);
            }
            return(ReferenceEquals(left, right));
        }
Esempio n. 3
0
        internal override void SetMember(ScriptProcessor processor, SObject accessor, bool isIndexer, SObject value)
        {
            if (isIndexer)
            {
                if (Prototype.GetIndexerSetFunction() != IndexerSetFunction)
                {
                    IndexerSetFunction = Prototype.GetIndexerSetFunction();
                }
            }

            if (isIndexer && accessor.TypeOf() == LiteralTypeNumber && IndexerSetFunction != null)
            {
                IndexerSetFunction.Call(processor, this, this, new[] { accessor, value });
            }
            else
            {
                var accessorAsString = accessor as SString;
                var memberName       = accessorAsString != null ? accessorAsString.Value : accessor.ToString(processor).Value;

                if (Members.ContainsKey(PropertySetPrefix + memberName)) // setter property
                {
                    ((SFunction)Members[PropertySetPrefix + memberName].Data).Call(processor, this, this, new[] { value });
                }
                if (Members.ContainsKey(memberName))
                {
                    Members[memberName].Data = value;
                }
                else if (Prototype != null && Prototype.HasMember(processor, memberName) && !Prototype.IsStaticMember(memberName))
                {
                    // This is the case when new members got added to the prototype, and we haven't copied them over to the instance yet.
                    // So we do that now, and then set the value of that member:
                    AddMember(memberName, value);
                }
                else
                {
                    SuperClass?.SetMember(processor, accessor, isIndexer, value);
                }
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Compares two objects for equality, converting types if needed.
        /// </summary>
        /// <remarks>Used by the == and != equality operators.</remarks>
        public static bool LooseEquals(ScriptProcessor processor, SObject left, SObject right)
        {
            left  = SObject.Unbox(left);
            right = SObject.Unbox(right);

            // both types are the same:
            if (left.TypeOf() == right.TypeOf())
            {
                // If they are undefined or null, return true:
                if (left.TypeOf() == SObject.LiteralUndefined || left.TypeOf() == SObject.LiteralNull)
                {
                    return(true);
                }
                // Both are numbers:
                if (left.TypeOf() == SObject.LiteralTypeNumber)
                {
                    var numLeft  = ((SNumber)left).Value;
                    var numRight = ((SNumber)right).Value;

                    return(Math.Abs(numLeft - numRight) < double.Epsilon);
                }
                // Both are string:
                if (left.TypeOf() == SObject.LiteralTypeString)
                {
                    var strLeft  = ((SString)left).Value;
                    var strRight = ((SString)right).Value;

                    return(strLeft == strRight);
                }
                // Both are bool:
                if (left.TypeOf() == SObject.LiteralTypeBool)
                {
                    var boolLeft  = ((SBool)left).Value;
                    var boolRight = ((SBool)right).Value;

                    return(boolLeft == boolRight);
                }
                return(ReferenceEquals(left, right));
            }
            // null & undefined
            if (left.TypeOf() == SObject.LiteralNull && right.TypeOf() == SObject.LiteralUndefined ||
                left.TypeOf() == SObject.LiteralUndefined && right.TypeOf() == SObject.LiteralNull)
            {
                return(true);
            }
            // When one is a number and another is a string, convert the string to a number and compare:
            if (left.TypeOf() == SObject.LiteralTypeString && right.TypeOf() == SObject.LiteralTypeNumber)
            {
                var numLeft  = left.ToNumber(processor).Value;
                var numRight = ((SNumber)right).Value;

                return(Math.Abs(numLeft - numRight) < double.Epsilon);
            }
            if (left.TypeOf() == SObject.LiteralTypeNumber && right.TypeOf() == SObject.LiteralTypeString)
            {
                var numRight = right.ToNumber(processor).Value;
                var numLeft  = ((SNumber)left).Value;

                return(Math.Abs(numLeft - numRight) < double.Epsilon);
            }
            if (left.TypeOf() == SObject.LiteralTypeBool)
            {
                return(LooseEquals(processor, left.ToNumber(processor), right));
            }
            if (right.TypeOf() == SObject.LiteralTypeBool)
            {
                return(LooseEquals(processor, left, right.ToNumber(processor)));
            }

            return(false);
        }