protected override CompilerItem TranslateImpl(CompilerContext cc) { // translate using Instruction CompilerItem ret = base.TranslateImpl(cc); // we jump with item if it's InstructionCode.JMP (unconditional) and points to yet unknown location. if (Code == InstructionCode.Jmp && !JumpTarget.IsTranslated) { cc.AddBackwardCode(this); ret = JumpTarget; } else { _state = cc.SaveState(); if (JumpTarget.IsTranslated) { DoJump(cc); } else { // state is not known, so we need to call DoJump() later. Compiler will do it for us. cc.AddForwardJump(this); JumpTarget.State = _state; } // Mark next code as unrecheable, cleared by a next label (ETarget). if (Code == InstructionCode.Jmp) { cc.Unreachable = true; } } // Need to traverse over all active variables and unuse them if their scope ends here if (cc.Active != null) { CompilerVar first = cc.Active; CompilerVar var = first; do { cc.UnuseVarOnEndOfScope(this, var); var = var.NextActive; } while (var != first); } return ret; }
protected override CompilerItem TranslateImpl(CompilerContext cc) { // If this Target was already translated, it's needed to change the current // state and return null to tell CompilerContext to process next untranslated // item. if (IsTranslated) { cc.RestoreState(_state); return null; } if (cc.Unreachable) { // If the context has "isUnreachable" flag set and there is no state then // it means that this code will be never called. This is a problem, because // we are unable to assign a state to current location so we can't allocate // registers for variables used inside. So instead of doing anything wrong // we remove the unreachable code. if (_state == null) return RemoveUnreachableItems(); // Assign state to the compiler context. cc.Unreachable = false; cc.AssignState(_state); } else { _state = cc.SaveState(); } return Next; }