public ConditionalItem(ByteCodeGenerator generator, OpCodeValue opCode, Chain trueChain, Chain falseChain) : base(generator, PrimativeTypes.Boolean) { OpCode = opCode; TrueJumps = trueChain; FalseJumps = falseChain; }
public void ResolvePendingJumps() { var x = pendingJumps; pendingJumps = null; ResolveChain(x, length); }
public void ResolveChain(Chain chain) { Debug.Assert(!alive || chain == null || state.StackSize == chain.State.StackSize); pendingJumps = MergeChains(chain, pendingJumps); }
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; }
public Chain Branch(OpCodeValue opcode) { Chain result = null; if (opcode == OpCodeValue.@goto) { result = pendingJumps; pendingJumps = null; } if (opcode != OpCodeValue.jsr && alive) { result = new Chain(EmitJump(opcode), result, state.Clone()); fixedPc = fatcode; if (opcode == OpCodeValue.@goto) alive = false; } return result; }
public static Chain MergeChains(Chain chain1, Chain chain2) { // recursive merge sort if (chain2 == null) return chain1; if (chain1 == null) return chain2; Debug.Assert(chain1.State.StackSize == chain2.State.StackSize); var chain = chain1.PC < chain2.PC ? new Chain(chain2.PC, MergeChains(chain1, chain2.Next), chain2.State) : new Chain(chain1.PC, MergeChains(chain1.Next, chain2), chain1.State); chain.State.MaxStackSize = Math.Max(chain1.State.MaxStackSize, chain2.State.MaxStackSize); return chain; }