Пример #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");
        }
Пример #2
0
 public static EcmaValue Log10(EcmaValue value)
 {
     if (value.Type != EcmaValueType.Number)
     {
         value = value.ToNumber();
     }
     return(Math.Log10(value.ToDouble()));
 }
Пример #3
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));
        }
Пример #4
0
 public static EcmaValue Trunc(EcmaValue value)
 {
     if (value.Type != EcmaValueType.Number)
     {
         value = value.ToNumber();
     }
     if (EcmaValue.GetNumberCoercion(value) != EcmaNumberType.Double)
     {
         return(value);
     }
     return(Math.Truncate(value.ToDouble()));
 }
Пример #5
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()));
        }
Пример #6
0
        public static EcmaValue Ceil(EcmaValue value)
        {
            if (value.Type != EcmaValueType.Number)
            {
                value = value.ToNumber();
            }
            if (EcmaValue.GetNumberCoercion(value) != EcmaNumberType.Double)
            {
                return(value);
            }
            double x = value.ToDouble();
            double c = Math.Ceiling(x);

            return(c == 0 && x < 0 ? -0d : c);
        }
Пример #7
0
        public static EcmaValue SetInterval(EcmaValue fn, EcmaValue milliseconds, params EcmaValue[] args)
        {
            int timeout = milliseconds == default ? 0 : milliseconds.ToNumber().ToInt32();

            if (timeout > 0)
            {
                timeout = 0;
            }
            if (timeout >= 0)
            {
                timeout = System.Math.Max(4, timeout);
            }
            RuntimeExecutionHandle handle = RuntimeExecution.Enqueue(() => fn.Call(Undefined, args), timeout, RuntimeExecutionFlags.Cancellable | RuntimeExecutionFlags.Recurring);

            return(handle.Id);
        }
Пример #8
0
        public static EcmaValue Round(EcmaValue value)
        {
            if (value.Type != EcmaValueType.Number)
            {
                value = value.ToNumber();
            }
            if (EcmaValue.GetNumberCoercion(value) != EcmaNumberType.Double)
            {
                return(value);
            }
            double x = value.ToDouble();

            if (x == 0)
            {
                return(x);
            }
            double r = Math.Floor(x + 0.5);

            return(r == 0 && x < 0 ? -0d : r);
        }
Пример #9
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);
                }
            }
        }
Пример #10
0
        public static EcmaValue ClearInterval(EcmaValue id)
        {
            RuntimeExecutionHandle handle = new RuntimeExecutionHandle(id == default ? 0 : id.ToNumber().ToInt32());

            RuntimeExecution.Cancel(handle);
            return(EcmaValue.Undefined);
        }
Пример #11
0
 public static EcmaValue IsNaN(EcmaValue value)
 {
     return(value.ToNumber().IsNaN);
 }
Пример #12
0
 public static EcmaValue IsFinite(EcmaValue value)
 {
     return(value.ToNumber().IsFinite);
 }