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(); }
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; }