| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764 |
- //------------------------------------------------------------
- // Copyright (c) Microsoft Corporation. All rights reserved.
- //------------------------------------------------------------
- namespace System.ServiceModel.Dispatcher
- {
- using System;
- using System.Runtime;
- internal struct StackFrame
- {
- internal int basePtr;
- internal int endPtr;
- #if NO
- internal StackFrame(int basePtr)
- {
- Fx.Assert(basePtr >= 0, "");
- this.basePtr = basePtr;
- this.endPtr = this.basePtr - 1;
- }
-
- internal StackFrame(int basePtr, int count)
- {
- Fx.Assert(basePtr >= 0, "");
- this.basePtr = basePtr;
- this.endPtr = basePtr + count - 1;
- }
- #endif
- internal int Count
- {
- get
- {
- return this.endPtr - this.basePtr + 1;
- }
- }
- internal int EndPtr
- {
- #if NO
- get
- {
- return this.endPtr;
- }
- #endif
- set
- {
- Fx.Assert(value >= this.basePtr, "");
- this.endPtr = value;
- }
- }
- #if NO
- internal void Clear()
- {
- this.endPtr = this.basePtr - 1;
- }
- #endif
- internal int this[int offset]
- {
- get
- {
- Fx.Assert(this.IsValidPtr(this.basePtr + offset), "");
- return this.basePtr + offset;
- }
- }
- #if NO
- internal void Set(int basePtr)
- {
- Fx.Assert(basePtr >= 0, "");
- this.basePtr = basePtr;
- this.endPtr = this.basePtr - 1;
- }
- #endif
- internal bool IsValidPtr(int ptr)
- {
- return (ptr >= this.basePtr && ptr <= this.endPtr);
- }
- }
- internal struct StackRegion
- {
- internal QueryRange bounds;
- internal int stackPtr;
- internal StackRegion(QueryRange bounds)
- {
- this.bounds = bounds;
- this.stackPtr = bounds.start - 1;
- }
- #if NO
- internal StackRegion(QueryRange bounds, int stackPtr)
- {
- Fx.Assert(bounds.IsInRange(stackPtr), "");
- this.bounds = bounds;
- this.stackPtr = stackPtr;
- }
- #endif
- internal int Count
- {
- get
- {
- return this.stackPtr - this.bounds.start + 1;
- }
- }
- #if NO
- internal bool IsReady
- {
- get
- {
- return this.bounds.IsNotEmpty;
- }
- }
- #endif
- internal bool NeedsGrowth
- {
- get
- {
- return (this.stackPtr > this.bounds.end);
- }
- }
- internal void Clear()
- {
- this.stackPtr = this.bounds.start - 1;
- }
- internal void Grow(int growBy)
- {
- this.bounds.end += growBy;
- }
- internal bool IsValidStackPtr()
- {
- return this.bounds.IsInRange(this.stackPtr);
- }
- internal bool IsValidStackPtr(int stackPtr)
- {
- return this.bounds.IsInRange(stackPtr);
- }
- #if NO
- internal void Set(int start, int end)
- {
- this.bounds.Set(start, end);
- this.stackPtr += start;
- }
- #endif
- internal void Shift(int shiftBy)
- {
- this.bounds.Shift(shiftBy);
- this.stackPtr += shiftBy;
- }
- }
- // The eval stack as well as all its contained data structures are STRUCTs
- // fast to allocate
- internal struct EvalStack
- {
- internal QueryBuffer<Value> buffer;
- internal StackRegion frames;
- internal StackRegion stack;
- internal const int DefaultSize = 2;
- internal bool contextOnTopOfStack;
- internal EvalStack(int frameCapacity, int stackCapacity)
- {
- Fx.Assert(frameCapacity >= 0 && stackCapacity >= 0, "");
- // All structs! Cost of allocation is relatively mild...
- this.buffer = new QueryBuffer<Value>(frameCapacity + stackCapacity);
- this.stack = new StackRegion(new QueryRange(0, stackCapacity - 1));
- this.buffer.Reserve(stackCapacity);
- this.frames = new StackRegion(new QueryRange(stackCapacity, stackCapacity + frameCapacity - 1));
- this.buffer.Reserve(frameCapacity);
- this.contextOnTopOfStack = false;
- }
- #if NO
- internal EvalStack(ref EvalStack stack)
- {
- this.buffer = new QueryBuffer<Value>(stack.buffer);
- this.stackCapacity = stack.stackCapacity;
- this.frameCapacity = stack.frameCapacity;
- this.stack = stack.stack;
- this.frames = stack.frames;
- }
- #endif
- internal Value[] Buffer
- {
- get
- {
- return this.buffer.buffer;
- }
- }
- #if NO
- internal int FrameCount
- {
- get
- {
- return this.frames.Count;
- }
- }
- internal int FramePtr
- {
- get
- {
- return this.frames.stackPtr;
- }
- }
- #endif
- internal StackFrame this[int frameIndex]
- {
- get
- {
- return this.buffer.buffer[this.frames.stackPtr - frameIndex].Frame;
- }
- }
- #if NO
- internal bool IsReady
- {
- get
- {
- return (this.buffer.count > 0);
- }
- }
- #endif
- internal StackFrame SecondArg
- {
- get
- {
- return this[1];
- }
- }
- #if NO
- internal int StackPtr
- {
- get
- {
- return this.stack.stackPtr;
- }
- }
- #endif
- internal StackFrame TopArg
- {
- get
- {
- return this[0];
- }
- }
- internal void Clear()
- {
- this.stack.Clear();
- this.frames.Clear();
- this.contextOnTopOfStack = false;
- }
- internal void CopyFrom(ref EvalStack stack)
- {
- this.buffer.CopyFrom(ref stack.buffer);
- this.frames = stack.frames;
- this.stack = stack.stack;
- this.contextOnTopOfStack = stack.contextOnTopOfStack;
- }
- internal int CalculateNodecount()
- {
- if (this.stack.stackPtr < 0)
- {
- return 0;
- }
- StackFrame topFrame = this.TopArg;
- int count = 0;
- for (int i = topFrame.basePtr; i <= topFrame.endPtr; ++i)
- {
- Fx.Assert(this.buffer[i].IsType(ValueDataType.Sequence), "");
- count += this.buffer[i].NodeCount;
- }
- return count;
- }
- #if NO
- internal void Erase()
- {
- this.buffer.Erase();
- }
- #endif
- void GrowFrames()
- {
- int growBy = this.frames.Count;
- this.buffer.ReserveAt(this.frames.bounds.end + 1, growBy);
- this.frames.Grow(growBy);
- }
- void GrowStack(int growthNeeded)
- {
- int growBy = this.stack.bounds.Count;
- if (growthNeeded > growBy)
- {
- growBy = growthNeeded;
- }
- this.buffer.ReserveAt(this.stack.bounds.end + 1, growBy);
- this.stack.Grow(growBy);
- this.frames.Shift(growBy);
- }
- #if NO
- internal void Init()
- {
- this.buffer.Reserve(this.stackCapacity);
- this.stack.Set(0, stackCapacity - 1);
- this.buffer.Reserve(this.frameCapacity);
- this.frames.Set(stackCapacity, stackCapacity + frameCapacity - 1);
- }
-
- internal void Init(Value[] buffer, int stackCapacity, int frameCapacity)
- {
- Fx.Assert(null != buffer, "");
- this.stackCapacity = stackCapacity;
- this.frameCapacity = frameCapacity;
-
- this.buffer = new QueryBuffer<Value>(buffer);
- this.stack = new StackRegion(new QueryRange(0, stackCapacity - 1));
- this.buffer.Reserve(stackCapacity);
- this.frames = new StackRegion(new QueryRange(stackCapacity, stackCapacity + frameCapacity - 1));
- this.buffer.Reserve(frameCapacity);
- }
- #endif
- internal bool InUse
- {
- get
- {
- if (contextOnTopOfStack)
- return (this.frames.Count > 1);
- else
- return (this.frames.Count > 0);
- }
- }
- internal bool PeekBoolean(int index)
- {
- Fx.Assert(this.stack.IsValidStackPtr(index), "");
- return this.buffer.buffer[index].GetBoolean();
- }
- internal double PeekDouble(int index)
- {
- Fx.Assert(this.stack.IsValidStackPtr(index), "");
- return this.buffer.buffer[index].GetDouble();
- }
- #if NO
- internal int PeekInteger(int index)
- {
- Fx.Assert(this.stack.IsValidStackPtr(index), "");
- return (int)this.buffer.buffer[index].GetDouble();
- }
- #endif
- internal NodeSequence PeekSequence(int index)
- {
- Fx.Assert(this.stack.IsValidStackPtr(index), "");
- return this.buffer.buffer[index].GetSequence();
- }
- internal string PeekString(int index)
- {
- Fx.Assert(this.stack.IsValidStackPtr(index), "");
- return this.buffer.buffer[index].GetString();
- }
- #if NO
- internal void Pop()
- {
- this.stack.stackPtr--;
- Fx.Assert(this.stack.IsValidStackPtr(), "");
- this.buffer.buffer[this.frames.stackPtr].FrameEndPtr = this.stack.stackPtr;
- }
- internal void PopFrame()
- {
- Fx.Assert(this.frames.IsValidStackPtr(), "");
- this.stack.stackPtr = this.buffer.buffer[this.frames.stackPtr].StackPtr;
- this.frames.stackPtr--;
- }
- #endif
- internal void PopFrame(ProcessingContext context)
- {
- Fx.Assert(this.frames.IsValidStackPtr(), "");
- StackFrame topArg = this.TopArg;
- for (int i = topArg.basePtr; i <= topArg.endPtr; ++i)
- {
- this.buffer.buffer[i].Clear(context);
- }
- this.stack.stackPtr = topArg.basePtr - 1;
- this.frames.stackPtr--;
- }
- internal void PushFrame()
- {
- this.frames.stackPtr++;
- if (this.frames.NeedsGrowth)
- {
- this.GrowFrames();
- }
- //
- // The first element in the new frame will be the NEXT item pushed onto the stack
- // We save offsets because stacks may get moved and repositioned
- //
- this.buffer.buffer[this.frames.stackPtr].StartFrame(this.stack.stackPtr);
- }
- internal void PopSequenceFrameTo(ref EvalStack dest)
- {
- StackFrame topFrame = this.TopArg;
- dest.PushFrame();
- int argCount = topFrame.Count;
- switch (argCount)
- {
- default:
- dest.Push(this.buffer.buffer, topFrame.basePtr, argCount);
- break;
- case 0:
- break;
- case 1:
- dest.Push(this.buffer.buffer[topFrame.basePtr].Sequence);
- break;
- }
- // Pop original fame
- this.stack.stackPtr = topFrame.basePtr - 1;
- this.frames.stackPtr--;
- }
- #if NO
- internal void Push()
- {
- this.stack.stackPtr++;
- if (this.stack.NeedsGrowth)
- {
- this.GrowStack(1);
- }
- this.buffer.buffer[this.frames.stackPtr].FrameEndPtr = this.stack.stackPtr;
- }
- internal void Push(int count)
- {
- this.stack.stackPtr += count;
- if (this.stack.NeedsGrowth)
- {
- this.GrowStack(count);
- }
- this.buffer.buffer[this.frames.stackPtr].FrameEndPtr = this.stack.stackPtr;
- }
- #endif
- internal void Push(string val)
- {
- this.stack.stackPtr++;
- if (this.stack.NeedsGrowth)
- {
- this.GrowStack(1);
- }
- this.buffer.buffer[this.stack.stackPtr].String = val;
- this.buffer.buffer[this.frames.stackPtr].FrameEndPtr = this.stack.stackPtr;
- }
- internal void Push(string val, int addCount)
- {
- int stackPtr = this.stack.stackPtr;
- this.stack.stackPtr += addCount;
- if (this.stack.NeedsGrowth)
- {
- this.GrowStack(addCount);
- }
- int stackMax = stackPtr + addCount;
- while (stackPtr < stackMax)
- {
- this.buffer.buffer[++stackPtr].String = val;
- }
- this.buffer.buffer[this.frames.stackPtr].FrameEndPtr = this.stack.stackPtr;
- }
- internal void Push(bool val)
- {
- this.stack.stackPtr++;
- if (this.stack.NeedsGrowth)
- {
- this.GrowStack(1);
- }
- this.buffer.buffer[this.stack.stackPtr].Boolean = val;
- this.buffer.buffer[this.frames.stackPtr].FrameEndPtr = this.stack.stackPtr;
- }
- internal void Push(bool val, int addCount)
- {
- int stackPtr = this.stack.stackPtr;
- this.stack.stackPtr += addCount;
- if (this.stack.NeedsGrowth)
- {
- this.GrowStack(addCount);
- }
- int stackMax = stackPtr + addCount;
- while (stackPtr < stackMax)
- {
- this.buffer.buffer[++stackPtr].Boolean = val;
- }
- this.buffer.buffer[this.frames.stackPtr].FrameEndPtr = this.stack.stackPtr;
- }
- internal void Push(double val)
- {
- this.stack.stackPtr++;
- if (this.stack.NeedsGrowth)
- {
- this.GrowStack(1);
- }
- this.buffer.buffer[this.stack.stackPtr].Double = val;
- this.buffer.buffer[this.frames.stackPtr].FrameEndPtr = this.stack.stackPtr;
- }
- internal void Push(double val, int addCount)
- {
- int stackPtr = this.stack.stackPtr;
- this.stack.stackPtr += addCount;
- if (this.stack.NeedsGrowth)
- {
- this.GrowStack(addCount);
- }
- int stackMax = stackPtr + addCount;
- while (stackPtr < stackMax)
- {
- this.buffer.buffer[++stackPtr].Double = val;
- }
- this.buffer.buffer[this.frames.stackPtr].FrameEndPtr = this.stack.stackPtr;
- }
- internal void Push(NodeSequence val)
- {
- this.stack.stackPtr++;
- if (this.stack.NeedsGrowth)
- {
- this.GrowStack(1);
- }
- this.buffer.buffer[this.stack.stackPtr].Sequence = val;
- this.buffer.buffer[this.frames.stackPtr].FrameEndPtr = this.stack.stackPtr;
- }
- internal void Push(NodeSequence val, int addCount)
- {
- // One of the addCount refs was added by the call to CreateSequence
- val.refCount += addCount - 1;
- int stackPtr = this.stack.stackPtr;
- this.stack.stackPtr += addCount;
- if (this.stack.NeedsGrowth)
- {
- this.GrowStack(addCount);
- }
- int stackMax = stackPtr + addCount;
- while (stackPtr < stackMax)
- {
- this.buffer.buffer[++stackPtr].Sequence = val;
- }
- this.buffer.buffer[this.frames.stackPtr].FrameEndPtr = this.stack.stackPtr;
- }
- internal void Push(Value[] buffer, int startAt, int addCount)
- {
- if (addCount > 0)
- {
- int stackPtr = this.stack.stackPtr + 1;
- this.stack.stackPtr += addCount;
- if (this.stack.NeedsGrowth)
- {
- this.GrowStack(addCount);
- }
- if (1 == addCount)
- {
- this.buffer.buffer[stackPtr] = buffer[startAt];
- }
- else
- {
- Array.Copy(buffer, startAt, this.buffer.buffer, stackPtr, addCount);
- }
- this.buffer.buffer[this.frames.stackPtr].FrameEndPtr = this.stack.stackPtr;
- }
- }
- #if NO
- internal void Push(ref EvalStack source)
- {
- this.Push(source.buffer.buffer, source.stack.bounds.start, source.frames.bounds.end + 1);
- }
- #endif
- internal void ReplaceAt(int index, NodeSequence seq)
- {
- Fx.Assert(this.stack.IsValidStackPtr(index) && this.buffer.buffer[index].IsType(ValueDataType.Sequence), "");
- this.buffer.buffer[index].Sequence = seq;
- }
- internal void SetValue(ProcessingContext context, int index, bool val)
- {
- Fx.Assert(this.stack.IsValidStackPtr(index), "");
- this.buffer.buffer[index].Update(context, val);
- }
- internal void SetValue(ProcessingContext context, int index, double val)
- {
- Fx.Assert(this.stack.IsValidStackPtr(index), "");
- this.buffer.buffer[index].Update(context, val);
- }
- internal void SetValue(ProcessingContext context, int index, string val)
- {
- Fx.Assert(this.stack.IsValidStackPtr(index), "");
- this.buffer.buffer[index].Update(context, val);
- }
- internal void SetValue(ProcessingContext context, int index, NodeSequence val)
- {
- Fx.Assert(this.stack.IsValidStackPtr(index), "");
- this.buffer.buffer[index].Update(context, val);
- }
- internal void TransferPositionsTo(ref EvalStack stack)
- {
- StackFrame arg = this.TopArg;
- stack.PushFrame();
- for (int i = arg.basePtr; i <= arg.endPtr; ++i)
- {
- NodeSequence seq = this.buffer.buffer[i].Sequence;
- int nodeCount = seq.Count;
- if ((this.stack.stackPtr + nodeCount) > this.stack.bounds.end)
- {
- this.GrowStack(nodeCount);
- }
- for (int n = 0; n < nodeCount; ++n)
- {
- stack.Push((double)seq.Items[n].Position);
- }
- }
- }
- internal void TransferSequenceSizeTo(ref EvalStack stack)
- {
- StackFrame arg = this.TopArg;
- stack.PushFrame();
- for (int i = arg.basePtr; i <= arg.endPtr; ++i)
- {
- NodeSequence seq = this.buffer.buffer[i].Sequence;
- int nodeCount = seq.Count;
- if ((this.stack.stackPtr + nodeCount) > this.stack.bounds.end)
- {
- this.GrowStack(nodeCount);
- }
- for (int n = 0; n < nodeCount; ++n)
- {
- stack.Push((double)NodeSequence.GetContextSize(seq, n));
- }
- }
- }
- #if NO
- internal void Trim()
- {
- this.buffer.TrimToCount();
- }
- #endif
- }
- #if NO
- internal struct BoundedStack<T>
- {
- QueryBuffer<T> buffer;
- int maxSize;
-
- internal BoundedStack(int capacity)
- {
- this.buffer = new QueryBuffer<T>(0);
- this.maxSize = capacity;
- }
-
- internal bool HasItems
- {
- get
- {
- return (this.buffer.count > 0);
- }
- }
-
- internal bool HasSpace
- {
- get
- {
- return (this.buffer.count < this.maxSize);
- }
- }
-
- internal int MaxSize
- {
- get
- {
- return this.maxSize;
- }
- set
- {
- Fx.Assert(value >= 0, "");
- this.maxSize = value;
- if (value < this.buffer.count)
- {
- this.buffer.count = value;
- this.buffer.TrimToCount();
- }
- }
- }
-
- internal T Pop()
- {
- return this.buffer.Pop();
- }
-
- internal void Push(T t)
- {
- if (this.buffer.count == this.maxSize)
- {
- return;
- }
-
- this.buffer.Push(t);
- }
-
- internal void Trim()
- {
- this.buffer.TrimToCount();
- }
- }
- #endif
- }
|