ToString() public static method

http://www.ecma-international.org/ecma-262/5.1/#sec-9.8
public static ToString ( Jint.Native.JsValue o ) : string
o Jint.Native.JsValue
return string
Exemplo n.º 1
0
        public override IEnumerable <KeyValuePair <string, PropertyDescriptor> > GetOwnProperties()
        {
            if (_length != null)
            {
                yield return(new KeyValuePair <string, PropertyDescriptor>(PropertyNameLength, _length));
            }

            if (_dense != null)
            {
                var length = System.Math.Min(_dense.Length, GetLength());
                for (var i = 0; i < length; i++)
                {
                    if (_dense[i] != null)
                    {
                        yield return(new KeyValuePair <string, PropertyDescriptor>(TypeConverter.ToString(i), _dense[i]));
                    }
                }
            }
            else
            {
                foreach (var entry in _sparse)
                {
                    yield return(new KeyValuePair <string, PropertyDescriptor>(TypeConverter.ToString(entry.Key), entry.Value));
                }
            }

            foreach (var entry in base.GetOwnProperties())
            {
                yield return(entry);
            }
        }
Exemplo n.º 2
0
        public bool TryGetValue(uint index, out JsValue value)
        {
            value = Undefined;

            PropertyDescriptor desc;

            TryGetDescriptor(index, out desc);
            desc = desc ?? GetProperty(TypeConverter.ToString(index)) ?? PropertyDescriptor.Undefined;
            return(desc.TryGetValue(this, out value));
        }
Exemplo n.º 3
0
        internal uint Push(JsValue[] arguments)
        {
            var initialLength = GetLength();
            var newLength     = initialLength + arguments.Length;

            // if we see that we are bringing more than normal growth algorithm handles, ensure capacity eagerly
            if (_dense != null &&
                initialLength != 0 &&
                arguments.Length > initialLength * 2 &&
                newLength <= MaxDenseArrayLength)
            {
                EnsureCapacity((uint)newLength);
            }

            double n = initialLength;

            for (var i = 0; i < arguments.Length; i++)
            {
                var desc = new PropertyDescriptor(arguments[i], PropertyFlag.ConfigurableEnumerableWritable);
                if (_dense != null && n < _dense.Length)
                {
                    _dense[(int)n] = desc;
                }
                else if (n < uint.MaxValue)
                {
                    WriteArrayValue((uint)n, desc);
                }
                else
                {
                    DefineOwnProperty(TypeConverter.ToString((uint)n), desc, true);
                }
                n++;
            }

            // check if we can set length fast without breaking ECMA specification
            if (n < uint.MaxValue && CanPut(PropertyNameLength))
            {
                _length.Value = (uint)n;
            }
            else
            {
                Put(PropertyNameLength, newLength, true);
            }

            return((uint)n);
        }
Exemplo n.º 4
0
        public override bool DefineOwnProperty(string propertyName, PropertyDescriptor desc, bool throwOnError)
        {
            var oldLenDesc = _length;
            var oldLen     = (uint)TypeConverter.ToNumber(oldLenDesc.Value);

            uint index;

            if (propertyName.Length == 6 && propertyName == "length")
            {
                var value = desc.Value;
                if (ReferenceEquals(value, null))
                {
                    return(base.DefineOwnProperty("length", desc, throwOnError));
                }

                var  newLenDesc = new PropertyDescriptor(desc);
                uint newLen     = TypeConverter.ToUint32(value);
                if (newLen != TypeConverter.ToNumber(value))
                {
                    ExceptionHelper.ThrowRangeError(_engine);
                }

                newLenDesc.Value = newLen;
                if (newLen >= oldLen)
                {
                    return(base.DefineOwnProperty("length", newLenDesc, throwOnError));
                }

                if (!oldLenDesc.Writable)
                {
                    if (throwOnError)
                    {
                        ExceptionHelper.ThrowTypeError(_engine);
                    }

                    return(false);
                }

                bool newWritable;
                if (!newLenDesc.WritableSet || newLenDesc.Writable)
                {
                    newWritable = true;
                }
                else
                {
                    newWritable         = false;
                    newLenDesc.Writable = true;
                }

                var succeeded = base.DefineOwnProperty("length", newLenDesc, throwOnError);
                if (!succeeded)
                {
                    return(false);
                }

                var count = _dense?.Length ?? _sparse.Count;
                if (count < oldLen - newLen)
                {
                    if (_dense != null)
                    {
                        for (uint keyIndex = 0; keyIndex < _dense.Length; ++keyIndex)
                        {
                            if (_dense[keyIndex] == null)
                            {
                                continue;
                            }

                            // is it the index of the array
                            if (keyIndex >= newLen && keyIndex < oldLen)
                            {
                                var deleteSucceeded = DeleteAt(keyIndex);
                                if (!deleteSucceeded)
                                {
                                    newLenDesc.Value = keyIndex + 1;
                                    if (!newWritable)
                                    {
                                        newLenDesc.Writable = false;
                                    }

                                    base.DefineOwnProperty("length", newLenDesc, false);

                                    if (throwOnError)
                                    {
                                        ExceptionHelper.ThrowTypeError(_engine);
                                    }

                                    return(false);
                                }
                            }
                        }
                    }
                    else
                    {
                        // in the case of sparse arrays, treat each concrete element instead of
                        // iterating over all indexes
                        var keys      = new List <uint>(_sparse.Keys);
                        var keysCount = keys.Count;
                        for (var i = 0; i < keysCount; i++)
                        {
                            var keyIndex = keys[i];

                            // is it the index of the array
                            if (keyIndex >= newLen && keyIndex < oldLen)
                            {
                                var deleteSucceeded = Delete(TypeConverter.ToString(keyIndex), false);
                                if (!deleteSucceeded)
                                {
                                    newLenDesc.Value = JsNumber.Create(keyIndex + 1);
                                    if (!newWritable)
                                    {
                                        newLenDesc.Writable = false;
                                    }

                                    base.DefineOwnProperty("length", newLenDesc, false);

                                    if (throwOnError)
                                    {
                                        ExceptionHelper.ThrowTypeError(_engine);
                                    }

                                    return(false);
                                }
                            }
                        }
                    }
                }
                else
                {
                    while (newLen < oldLen)
                    {
                        // algorithm as per the spec
                        oldLen--;
                        var deleteSucceeded = Delete(TypeConverter.ToString(oldLen), false);
                        if (!deleteSucceeded)
                        {
                            newLenDesc.Value = oldLen + 1;
                            if (!newWritable)
                            {
                                newLenDesc.Writable = false;
                            }

                            base.DefineOwnProperty("length", newLenDesc, false);

                            if (throwOnError)
                            {
                                ExceptionHelper.ThrowTypeError(_engine);
                            }

                            return(false);
                        }
                    }
                }

                if (!newWritable)
                {
                    DefineOwnProperty("length", new PropertyDescriptor(value: null, flags: PropertyFlag.WritableSet), false);
                }

                return(true);
            }
            else if (IsArrayIndex(propertyName, out index))
            {
                if (index >= oldLen && !oldLenDesc.Writable)
                {
                    if (throwOnError)
                    {
                        ExceptionHelper.ThrowTypeError(_engine);
                    }

                    return(false);
                }

                var succeeded = base.DefineOwnProperty(propertyName, desc, false);
                if (!succeeded)
                {
                    if (throwOnError)
                    {
                        ExceptionHelper.ThrowTypeError(_engine);
                    }

                    return(false);
                }

                if (index >= oldLen)
                {
                    oldLenDesc.Value = index + 1;
                    base.DefineOwnProperty("length", oldLenDesc, false);
                }

                return(true);
            }

            return(base.DefineOwnProperty(propertyName, desc, throwOnError));
        }
Exemplo n.º 5
0
        public JsValue EvaluateAssignmentExpression(AssignmentExpression assignmentExpression)
        {
            var     lref = EvaluateExpression(assignmentExpression.Left) as Reference;
            JsValue rval = _engine.GetValue(EvaluateExpression(assignmentExpression.Right));

            if (lref == null)
            {
                throw new JavaScriptException(_engine.ReferenceError);
            }

            if (assignmentExpression.Operator == AssignmentOperator.Assign) // "="
            {
                if (lref.IsStrict() && lref.GetBase().TryCast <EnvironmentRecord>() != null && (lref.GetReferencedName() == "eval" || lref.GetReferencedName() == "arguments"))
                {
                    throw new JavaScriptException(_engine.SyntaxError);
                }

                _engine.PutValue(lref, rval);
                return(rval);
            }

            JsValue lval = _engine.GetValue(lref);

            switch (assignmentExpression.Operator)
            {
            case AssignmentOperator.PlusAssign:
                var lprim = TypeConverter.ToPrimitive(lval);
                var rprim = TypeConverter.ToPrimitive(rval);
                if (lprim.IsString() || rprim.IsString())
                {
                    lval = TypeConverter.ToString(lprim) + TypeConverter.ToString(rprim);
                }
                else
                {
                    lval = TypeConverter.ToNumber(lprim) + TypeConverter.ToNumber(rprim);
                }
                break;

            case AssignmentOperator.MinusAssign:
                lval = TypeConverter.ToNumber(lval) - TypeConverter.ToNumber(rval);
                break;

            case AssignmentOperator.TimesAssign:
                if (lval == Undefined.Instance || rval == Undefined.Instance)
                {
                    lval = Undefined.Instance;
                }
                else
                {
                    lval = TypeConverter.ToNumber(lval) * TypeConverter.ToNumber(rval);
                }
                break;

            case AssignmentOperator.DivideAssign:
                lval = Divide(lval, rval);
                break;

            case AssignmentOperator.ModuloAssign:
                if (lval == Undefined.Instance || rval == Undefined.Instance)
                {
                    lval = Undefined.Instance;
                }
                else
                {
                    lval = TypeConverter.ToNumber(lval) % TypeConverter.ToNumber(rval);
                }
                break;

            case AssignmentOperator.BitwiseAndAssign:
                lval = TypeConverter.ToInt32(lval) & TypeConverter.ToInt32(rval);
                break;

            case AssignmentOperator.BitwiseOrAssign:
                lval = TypeConverter.ToInt32(lval) | TypeConverter.ToInt32(rval);
                break;

            case AssignmentOperator.BitwiseXOrAssign:
                lval = TypeConverter.ToInt32(lval) ^ TypeConverter.ToInt32(rval);
                break;

            case AssignmentOperator.LeftShiftAssign:
                lval = TypeConverter.ToInt32(lval) << (int)(TypeConverter.ToUint32(rval) & 0x1F);
                break;

            case AssignmentOperator.RightShiftAssign:
                lval = TypeConverter.ToInt32(lval) >> (int)(TypeConverter.ToUint32(rval) & 0x1F);
                break;

            case AssignmentOperator.UnsignedRightShiftAssign:
                lval = (uint)TypeConverter.ToInt32(lval) >> (int)(TypeConverter.ToUint32(rval) & 0x1F);
                break;

            default:
                throw new NotImplementedException();
            }

            _engine.PutValue(lref, lval);

            return(lval);
        }
Exemplo n.º 6
0
        public static bool Equal(JsValue x, JsValue y)
        {
            var typex = x.Type;
            var typey = y.Type;

            if (typex == typey)
            {
                if (typex == Types.Undefined || typex == Types.Null)
                {
                    return(true);
                }

                if (typex == Types.Number)
                {
                    var nx = TypeConverter.ToNumber(x);
                    var ny = TypeConverter.ToNumber(y);

                    if (double.IsNaN(nx) || double.IsNaN(ny))
                    {
                        return(false);
                    }

                    if (nx.Equals(ny))
                    {
                        return(true);
                    }

                    return(false);
                }

                if (typex == Types.String)
                {
                    return(TypeConverter.ToString(x) == TypeConverter.ToString(y));
                }

                if (typex == Types.Boolean)
                {
                    return(x.AsBoolean() == y.AsBoolean());
                }

                return(x == y);
            }

            if (x == Null.Instance && y == Undefined.Instance)
            {
                return(true);
            }

            if (x == Undefined.Instance && y == Null.Instance)
            {
                return(true);
            }

            if (typex == Types.Number && typey == Types.String)
            {
                return(Equal(x, TypeConverter.ToNumber(y)));
            }

            if (typex == Types.String && typey == Types.Number)
            {
                return(Equal(TypeConverter.ToNumber(x), y));
            }

            if (typex == Types.Boolean)
            {
                return(Equal(TypeConverter.ToNumber(x), y));
            }

            if (typey == Types.Boolean)
            {
                return(Equal(x, TypeConverter.ToNumber(y)));
            }

            if (typey == Types.Object && (typex == Types.String || typex == Types.Number))
            {
                return(Equal(x, TypeConverter.ToPrimitive(y)));
            }

            if (typex == Types.Object && (typey == Types.String || typey == Types.Number))
            {
                return(Equal(TypeConverter.ToPrimitive(x), y));
            }

            return(false);
        }
Exemplo n.º 7
0
        public JsValue EvaluateBinaryExpression(BinaryExpression expression)
        {
            var     leftExpression = EvaluateExpression(expression.Left);
            JsValue left           = _engine.GetValue(leftExpression);

            var     rightExpression = EvaluateExpression(expression.Right);
            JsValue right           = _engine.GetValue(rightExpression);

            JsValue value;

            switch (expression.Operator)
            {
            case BinaryOperator.Plus:
                var lprim = TypeConverter.ToPrimitive(left);
                var rprim = TypeConverter.ToPrimitive(right);
                if (lprim.IsString() || rprim.IsString())
                {
                    value = TypeConverter.ToString(lprim) + TypeConverter.ToString(rprim);
                }
                else
                {
                    value = TypeConverter.ToNumber(lprim) + TypeConverter.ToNumber(rprim);
                }
                break;

            case BinaryOperator.Minus:
                value = TypeConverter.ToNumber(left) - TypeConverter.ToNumber(right);
                break;

            case BinaryOperator.Times:
                if (left == Undefined.Instance || right == Undefined.Instance)
                {
                    value = Undefined.Instance;
                }
                else
                {
                    value = TypeConverter.ToNumber(left) * TypeConverter.ToNumber(right);
                }
                break;

            case BinaryOperator.Divide:
                value = Divide(left, right);
                break;

            case BinaryOperator.Modulo:
                if (left == Undefined.Instance || right == Undefined.Instance)
                {
                    value = Undefined.Instance;
                }
                else
                {
                    value = TypeConverter.ToNumber(left) % TypeConverter.ToNumber(right);
                }
                break;

            case BinaryOperator.Equal:
                value = Equal(left, right);
                break;

            case BinaryOperator.NotEqual:
                value = !Equal(left, right);
                break;

            case BinaryOperator.Greater:
                value = Compare(right, left, false);
                if (value == Undefined.Instance)
                {
                    value = false;
                }
                break;

            case BinaryOperator.GreaterOrEqual:
                value = Compare(left, right);
                if (value == Undefined.Instance || value.AsBoolean())
                {
                    value = false;
                }
                else
                {
                    value = true;
                }
                break;

            case BinaryOperator.Less:
                value = Compare(left, right);
                if (value == Undefined.Instance)
                {
                    value = false;
                }
                break;

            case BinaryOperator.LessOrEqual:
                value = Compare(right, left, false);
                if (value == Undefined.Instance || value.AsBoolean())
                {
                    value = false;
                }
                else
                {
                    value = true;
                }
                break;

            case BinaryOperator.StrictlyEqual:
                return(StrictlyEqual(left, right));

            case BinaryOperator.StricltyNotEqual:
                return(!StrictlyEqual(left, right));

            case BinaryOperator.BitwiseAnd:
                return(TypeConverter.ToInt32(left) & TypeConverter.ToInt32(right));

            case BinaryOperator.BitwiseOr:
                return(TypeConverter.ToInt32(left) | TypeConverter.ToInt32(right));

            case BinaryOperator.BitwiseXOr:
                return(TypeConverter.ToInt32(left) ^ TypeConverter.ToInt32(right));

            case BinaryOperator.LeftShift:
                return(TypeConverter.ToInt32(left) << (int)(TypeConverter.ToUint32(right) & 0x1F));

            case BinaryOperator.RightShift:
                return(TypeConverter.ToInt32(left) >> (int)(TypeConverter.ToUint32(right) & 0x1F));

            case BinaryOperator.UnsignedRightShift:
                return((uint)TypeConverter.ToInt32(left) >> (int)(TypeConverter.ToUint32(right) & 0x1F));

            case BinaryOperator.InstanceOf:
                var f = right.TryCast <FunctionInstance>();

                if (f == null)
                {
                    throw new JavaScriptException(_engine.TypeError, "instanceof can only be used with a function object");
                }

                value = f.HasInstance(left);
                break;

            case BinaryOperator.In:
                if (!right.IsObject())
                {
                    throw new JavaScriptException(_engine.TypeError, "in can only be used with an object");
                }

                value = right.AsObject().HasProperty(TypeConverter.ToString(left));
                break;

            default:
                throw new NotImplementedException();
            }

            return(value);
        }