예제 #1
0
        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;
        }
예제 #2
0
        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;
        }