Пример #1
0
        public static unsafe double GetValueFromBuffer([NotNull] Agent agent, [NotNull] ScriptObject arrayBuffer, long byteIndex, [NotNull] TypeDescription description, bool isTypedArray, OrderType order, bool isLittleEndian)
        {
            //https://tc39.github.io/ecma262/#sec-getvaluefrombuffer
            Debug.Assert(!IsDetachedBuffer(arrayBuffer));
            var block = arrayBuffer.ArrayBuffer.Data;

            Debug.Assert(byteIndex + description.Size <= block.LongLength);

            byte *rawBytes = stackalloc byte[8];

            if (SharedArrayBufferIntrinsics.IsSharedArrayBuffer(arrayBuffer))
            {
                //Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
                //Let eventList be the [[EventList]] field of the element in execution.[[EventLists]] whose [[AgentSignifier]] is AgentSignifier().
                //If isTypedArray is true and type is "Int8", "Uint8", "Int16", "Uint16", "Int32", or "Uint32", let noTear be true; otherwise let noTear be false.
                //Let rawValue be a List of length elementSize of nondeterministically chosen byte values.
                //NOTE: In implementations, rawValue is the result of a non-atomic or atomic read instruction on the underlying hardware. The nondeterminism is a semantic prescription of the memory model to describe observable behaviour of hardware with weak consistency.
                //Let readEvent be ReadSharedMemory{ [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize }.
                //Append readEvent to eventList.
                //Append Chosen Value Record { [[Event]]: readEvent, [[ChosenValue]]: rawValue } to execution.[[ChosenValues]].
                throw new NotImplementedException();
            }
            else
            {
                for (var i = 0u; i < description.Size; i++)
                {
                    rawBytes[i] = block[byteIndex + i];
                }
            }

            return(RawBytesToNumber(description, rawBytes, isLittleEndian));
        }
Пример #2
0
        public static unsafe void SetValueInBuffer([NotNull] Agent agent, [NotNull] ScriptObject arrayBuffer, long byteIndex, [NotNull] TypeDescription description, double value, bool isTypedArray, OrderType order, bool isLittleEndian)
        {
            //https://tc39.github.io/ecma262/#sec-setvalueinbuffer
            Debug.Assert(!IsDetachedBuffer(arrayBuffer));
            var block = arrayBuffer.ArrayBuffer.Data;

            Debug.Assert(byteIndex + description.Size <= block.LongLength);
            byte *rawBytes = stackalloc byte[8];

            NumberToRawBytes(description, value, isLittleEndian, rawBytes);
            if (SharedArrayBufferIntrinsics.IsSharedArrayBuffer(arrayBuffer))
            {
                //Let execution be the [[CandidateExecution]] field of the surrounding agent's Agent Record.
                //Let eventList be the [[EventList]] field of the element in execution.[[EventLists]] whose [[AgentSignifier]] is AgentSignifier().
                //If isTypedArray is true and type is "Int8", "Uint8", "Int16", "Uint16", "Int32", or "Uint32", let noTear be true; otherwise let noTear be false.
                //Append WriteSharedMemory{ [[Order]]: order, [[NoTear]]: noTear, [[Block]]: block, [[ByteIndex]]: byteIndex, [[ElementSize]]: elementSize, [[Payload]]: rawBytes } to eventList.
                throw new NotImplementedException();
            }
            else
            {
                for (var i = 0u; i < description.Size; i++)
                {
                    block[byteIndex + i] = rawBytes[i];
                }
            }
        }
Пример #3
0
        private static ScriptValue Slice([NotNull] ScriptArguments arg)
        {
            //https://tc39.github.io/ecma262/#sec-arraybuffer.prototype.slice
            var obj = arg.ThisValue.AsObject(arg.Agent);

            if (obj.SpecialObjectType != SpecialObjectType.ArrayBuffer)
            {
                throw arg.Agent.CreateTypeError();
            }

            if (SharedArrayBufferIntrinsics.IsSharedArrayBuffer(obj))
            {
                throw arg.Agent.CreateTypeError();
            }

            if (IsDetachedBuffer(obj))
            {
                throw arg.Agent.CreateTypeError();
            }

            var length        = obj.ArrayBuffer.Data.LongLength;
            var relativeStart = (long)arg.Agent.ToInteger(arg[0]);
            var first         = relativeStart < 0 ? Math.Max(length + relativeStart, 0) : Math.Min(relativeStart, length);
            var relativeEnd   = arg[1] == ScriptValue.Undefined ? length : (long)arg.Agent.ToInteger(arg[1]);
            var final         = relativeEnd < 0 ? Math.Max(length + relativeEnd, 0) : Math.Min(relativeEnd, length);
            var newLength     = Math.Max(final - first, 0);

            var constructor = arg.Agent.SpeciesConstructor(obj, arg.Function.Realm.ArrayBuffer);
            var newObject   = Agent.Construct(constructor, new ScriptValue[]
            {
                newLength
            }).AsObject(arg.Agent);

            if (newObject.SpecialObjectType != SpecialObjectType.ArrayBuffer)
            {
                throw arg.Agent.CreateTypeError();
            }

            if (SharedArrayBufferIntrinsics.IsSharedArrayBuffer(newObject))
            {
                throw arg.Agent.CreateTypeError();
            }

            if (IsDetachedBuffer(newObject))
            {
                throw arg.Agent.CreateTypeError();
            }

            if (newObject == obj)
            {
                throw arg.Agent.CreateTypeError();
            }

            if (newObject.ArrayBuffer.Data.LongLength < newLength)
            {
                throw arg.Agent.CreateTypeError();
            }

            //NOTE: Side-effects of the above steps may have detached O.
            if (IsDetachedBuffer(obj))
            {
                throw arg.Agent.CreateTypeError();
            }

            var fromBuffer = obj.ArrayBuffer.Data;
            var toBuffer   = newObject.ArrayBuffer.Data;

            Array.Copy(fromBuffer, first, toBuffer, 0, newLength);
            return(newObject);
        }