Example #1
0
        public static EcmaValue Wait(TypedArray array, EcmaValue index, EcmaValue value, EcmaValue timeout)
        {
            int  pos       = ValidateWaitableArrayAndIndex(array, index);
            bool isInt32   = array.ArrayKind == TypedArrayKind.Int32Array;
            long longValue = isInt32 ? value.ToInt32() : value.ToBigInt64().ToInt64();

            timeout = timeout.ToNumber();
            if (!RuntimeExecution.Current.CanSuspend)
            {
                throw new EcmaTypeErrorException("Atomics.wait cannot be called in this context");
            }
            bool comparandEquals, result;
            int  milliseconds        = timeout.IsNaN || timeout > Int32.MaxValue ? -1 : timeout < 0 ? 0 : timeout.ToInt32();
            SharedArrayBuffer buffer = (SharedArrayBuffer)array.Buffer;

            if (isInt32)
            {
                result = buffer.Wait(array.GetByteOffset(pos), (int)longValue, milliseconds, out comparandEquals);
            }
            else
            {
                result = buffer.Wait(array.GetByteOffset(pos), longValue, milliseconds, out comparandEquals);
            }
            return(result ? "ok" : comparandEquals ? "timed-out" : "not-equal");
        }
Example #2
0
        public void SetInt32(long index, EcmaValue value, DataViewEndianness isLittleEndian)
        {
            Guard.BufferNotDetached(this);
            int intValue = value.ToInt32();

            ThrowIfOutOfBound(index, sizeof(int));
            this.Buffer.SetValue(index + ByteOffset, CheckAndSwap(intValue, isLittleEndian));
        }
Example #3
0
        public static EcmaValue Sign(EcmaValue value)
        {
            switch (EcmaValue.GetNumberCoercion(value))
            {
            case EcmaNumberType.Int64:
                return(Math.Sign(value.ToInt64()));

            case EcmaNumberType.Int32:
                return(Math.Sign(value.ToInt32()));
            }
            double x = value.ToDouble();

            return(Double.IsNaN(x) ? EcmaValue.NaN : x == 0 ? x : Math.Sign(x));
        }
Example #4
0
        public static EcmaValue Abs(EcmaValue value)
        {
            switch (EcmaValue.GetNumberCoercion(value))
            {
            case EcmaNumberType.Double:
                return(Math.Abs(value.ToDouble()));

            case EcmaNumberType.Int64:
                return(Math.Abs(value.ToInt64()));

            case EcmaNumberType.Int32:
                return(Math.Abs(value.ToInt32()));
            }
            return(Abs(value.ToNumber()));
        }
Example #5
0
        public static EcmaValue Stringify(EcmaValue value, EcmaValue replacer, EcmaValue space)
        {
            string indentString;

            space = EcmaValueUtility.UnboxPrimitiveObject(space);
            if (space.Type == EcmaValueType.Number)
            {
                indentString = new String(' ', Math.Max(0, Math.Min(10, space.ToInt32())));
            }
            else if (space.Type == EcmaValueType.String)
            {
                indentString = space.ToStringOrThrow();
            }
            else
            {
                indentString = String.Empty;
            }
            string result;

            if (replacer.IsCallable)
            {
                result = new EcmaJsonWriter(indentString, replacer).Serialize(value);
            }
            else if (EcmaArray.IsArray(replacer))
            {
                HashSet <string> propertyList = new HashSet <string>();
                for (long i = 0, length = replacer[WellKnownProperty.Length].ToLength(); i < length; i++)
                {
                    EcmaValue item = EcmaValueUtility.UnboxPrimitiveObject(replacer[i]);
                    if (item.Type == EcmaValueType.String || item.Type == EcmaValueType.Number)
                    {
                        propertyList.Add(item.ToStringOrThrow());
                    }
                }
                result = new EcmaJsonWriter(indentString, propertyList).Serialize(value);
            }
            else
            {
                result = new EcmaJsonWriter(indentString).Serialize(value);
            }
            return(result ?? EcmaValue.Undefined);
        }
Example #6
0
        private static EcmaValue DoAtomicOperation(TypedArray array, EcmaValue index, Operation operation, EcmaValue value, EcmaValue replacement)
        {
            int i = ValidateArrayAndIndex(array, index);

            value       = value.ToNumber();
            replacement = replacement.ToNumber();

            long offset = array.GetByteOffset(i);

            int[] buffer          = array.Buffer.Int32Array;
            int   bufferIndex     = (int)(offset >> 2);
            int   bytesPerElement = array.ElementSize;
            int   operand         = value.ToInt32();
            int   bitShift        = 0;
            int   mask            = -1;

            if (bytesPerElement != 4)
            {
                int byteShift = (int)(offset % 4);
                if (byteShift != 0 && !BitConverter.IsLittleEndian)
                {
                    byteShift = 4 - byteShift;
                }
                bitShift  = byteShift * 8;
                operand <<= bitShift;
                mask      = (bytesPerElement == 2 ? shortMask : byteMask)[byteShift];
            }
            else
            {
                int result;
                switch (operation)
                {
                case Operation.CompareExchange:
                    result = Interlocked.CompareExchange(ref buffer[bufferIndex], replacement.ToInt32(), operand);
                    break;

                case Operation.Exchange:
                    result = Interlocked.Exchange(ref buffer[bufferIndex], operand);
                    break;

                case Operation.Add:
                    result = unchecked (Interlocked.Add(ref buffer[bufferIndex], operand) - operand);
                    break;

                case Operation.Sub:
                    result = unchecked (Interlocked.Add(ref buffer[bufferIndex], -operand) + operand);
                    break;

                default:
                    goto fallback;
                }
                return(array.ArrayKind == TypedArrayKind.Uint32Array ? (EcmaValue)(uint)result : result);
            }
fallback:
            while (true)
            {
                int curValue = buffer[bufferIndex];
                int newValue = curValue;
                switch (operation)
                {
                case Operation.Or:
                    newValue |= operand;
                    break;

                case Operation.And:
                    newValue &= operand;
                    break;

                case Operation.Xor:
                    newValue ^= operand;
                    break;

                case Operation.Add:
                    newValue = unchecked (curValue + operand);
                    break;

                case Operation.Sub:
                    newValue = unchecked (curValue - operand);
                    break;

                case Operation.CompareExchange:
                    newValue = (curValue & mask) == (operand & mask) ? replacement.ToInt32() << bitShift : curValue;
                    break;

                case Operation.Exchange:
                    newValue = operand;
                    break;
                }
                if (bytesPerElement != 4)
                {
                    newValue = (curValue & ~mask) | (newValue & mask);
                }
                if (curValue == Interlocked.CompareExchange(ref buffer[bufferIndex], newValue, curValue))
                {
                    int result = (curValue & mask) >> bitShift;
                    switch (array.ArrayKind)
                    {
                    case TypedArrayKind.Int8Array:
                        return((sbyte)result);

                    case TypedArrayKind.Uint8Array:
                        return((byte)result);

                    case TypedArrayKind.Int16Array:
                        return((short)result);

                    case TypedArrayKind.Uint16Array:
                        return((ushort)result);

                    case TypedArrayKind.Uint32Array:
                        return((uint)result);
                    }
                    return(result);
                }
            }
        }
Example #7
0
        public static EcmaValue Notify(TypedArray array, EcmaValue index, EcmaValue count)
        {
            int pos = ValidateWaitableArrayAndIndex(array, index);

            count = count == default ? Int32.MaxValue : count.ToNumber();
            int countValue           = count.IsNaN || count <= 0 ? 0 : count > Int32.MaxValue ? Int32.MaxValue : count.ToInt32();
            SharedArrayBuffer buffer = (SharedArrayBuffer)array.Buffer;

            return(buffer.Notify(array.GetByteOffset(pos), countValue));
        }
Example #8
0
        public static EcmaValue ParseInt(EcmaValue str, EcmaValue radix)
        {
            string inputString = str.ToStringOrThrow();

            return(EcmaValueUtility.ParseIntInternal(inputString, radix.ToInt32(), true));
        }