public ByteCodeGenerator(CompileManager manager, Method method)
        {
            Manager = manager;
            Method = method;

            byteCodeStream = new byte[64];
            length = 0;

            variableList = new Variable[256];
            if (method.Modifiers.HasFlag(Modifier.Static))
            {
                variableCount = 0;
                MaxVariables = 0;
            }
            else
            {
                variableCount = 1;
                MaxVariables = 1;

                variableList[0] = new Variable(0, "this", method.DeclaringType);
            }
            variableListStack = new Stack<Tuple<short, Variable[]>>();

            state = new State();
        }
示例#2
0
        public State Join(State other)
        {
            Debug.Assert(StackSize == other.StackSize);

            for (var i = 0; i < StackSize; )
            {
                var t = stack[i];
                var tother = other.stack[i];

                var result = t.FindCommonType(tother);

                var w = TypeCodeHelper.Width(result);

                stack[i] = result;

                if (w == 2) Debug.Assert(stack[i + 1] == null);
                i += w;
            }
            return this;
        }
        public void ResolveChain(Chain chain, int target)
        {
            var changed = false;
            var newState = state;

            for (; chain != null; chain = chain.Next)
            {
                Debug.Assert(state != chain.State && (target > chain.PC || state.StackSize == 0));
                if (target >= length)
                {
                    target = length;
                }
                else if (byteCodeStream[target] == (byte)OpCodeValue.@goto)
                {
                    if (fatcode)
                    {
                        target = target + (byteCodeStream[target + 1] << 24)
                                        + (byteCodeStream[target + 2] << 16)
                                        + (byteCodeStream[target + 3] << 8)
                                        + (byteCodeStream[target + 4]);
                    }
                    else
                    {
                        target = target + (byteCodeStream[target + 1] << 8) + (byteCodeStream[target + 2]);
                    }
                }
                if (byteCodeStream[chain.PC] == (byte)OpCodeValue.@goto && chain.PC + 3 == target && target == length && !fixedPc)
                {
                    length = length - 3;
                    target = target - 3;
                    if (chain.Next == null)
                    {
                        alive = true;
                        break;
                    }
                }
                else
                {
                    var value = target - chain.PC;

                    if (fatcode)
                    {
                        byteCodeStream[chain.PC + 1] = (byte)((value >> 24) & 0xFF);
                        byteCodeStream[chain.PC + 2] = (byte)((value >> 16) & 0xFF);
                        byteCodeStream[chain.PC + 3] = (byte)((value >> 8) & 0xFF);
                        byteCodeStream[chain.PC + 4] = (byte)(value & 0xFF);
                    }
                    else if (value < short.MinValue || value > short.MaxValue)
                    {
                        fatcode = true;
                    }
                    else
                    {
                        byteCodeStream[chain.PC + 1] = (byte)((value >> 8) & 0xFF);
                        byteCodeStream[chain.PC + 2] = (byte)(value & 0xFF);
                    }
                    Debug.Assert(!alive || chain.State.StackSize == newState.StackSize);
                }

                fixedPc = true;
                if (length != target) continue;

                changed = true;

                if (alive)
                {
                    newState = chain.State.Join(newState);
                }
                else
                {
                    newState = chain.State;
                    alive = true;
                }
            }

            Debug.Assert(!changed || state != newState);
            if (state == newState) return;

            newState.MaxStackSize = Math.Max(newState.MaxStackSize, state.MaxStackSize);

            state = newState;
            pendingStackMap = true;
        }