internal void PrepareVariables(CompilerItem first)
        {
            int i;
            int count = _functionPrototype.Arguments.Length;

            for (i = 0; i < count; i++)
            {
                CompilerVar vdata = _argumentVariables[i];

                // This is where variable scope starts.
                vdata.FirstItem = first;
                // If this will not be changed then it will be deallocated immediately.
                vdata.LastItem = first;
            }
        }
        internal void PatchMemoryOperands(CompilerItem start, CompilerItem stop)
        {
            CompilerItem current;

            for (current = start; ; current = current.Next)
            {
                CompilerInstruction instruction = current as CompilerInstruction;
                if (instruction != null)
                {
                    Mem mem = instruction.MemoryOperand;

                    if (mem != null && (mem.Id & Operand.OperandIdTypeMask) == Operand.OperandIdTypeVar)
                    {
                        CompilerVar varData = _compiler.GetVarData(mem.Id);
                        Contract.Assert(varData != null);

                        if (varData.IsMemArgument)
                        {
                            mem.Base = _argumentsBaseReg;
                            mem.Displacement += varData.HomeMemoryOffset;
                            mem.Displacement += _argumentsBaseOffset;
                        }
                        else
                        {
                            VarMemBlock mb = varData.HomeMemoryData;
                            if (mb == null)
                                throw new CompilerException();

                            mem.Base = _variablesBaseReg;
                            mem.Displacement += mb.Offset;
                            mem.Displacement += _variablesBaseOffset;
                        }
                    }
                }

                if (current == stop)
                    break;
            }
        }
        public void UnuseVarOnEndOfScope(CompilerItem e, VarAllocRecord rec)
        {
            Contract.Requires(e != null);
            Contract.Requires(rec != null);
            Contract.Requires(rec.VarData != null);

            CompilerVar v = rec.VarData;
            if (v.LastItem == e || (rec.VarFlags & VariableAlloc.UnuseAfterUse) != 0)
                UnuseVar(v, VariableState.Unused);
        }
        internal void Clear()
        {
            Contract.Ensures(Function == null);

            //_zone.clear();
            _function = null;

            _start = null;
            _stop = null;

            _state.Clear();
            _active = null;

            _forwardJumps = null;

            _currentOffset = 0;
            //_unreachable = 0;

            _modifiedGPRegisters = RegisterMask.Zero;
            _modifiedMMRegisters = RegisterMask.Zero;
            _modifiedXMMRegisters = RegisterMask.Zero;

            _allocableEBP = false;

            _adjustESP = 0;

            _argumentsBaseReg = RegIndex.Invalid;
            _argumentsBaseOffset = 0;
            _argumentsActualDisp = 0;

            _variablesBaseReg = RegIndex.Invalid;
            _variablesBaseOffset = 0;
            _variablesActualDisp = 0;

            _memUsed = null;
            _memFree = null;

            _mem4BlocksCount = 0;
            _mem8BlocksCount = 0;
            _mem16BlocksCount = 0;

            _memBytesTotal = 0;

            _backCode.Clear();
            _backPos = 0;
        }
        public void UnuseVarOnEndOfScope(CompilerItem e, CompilerVar vdata)
        {
            Contract.Requires(e != null);
            Contract.Requires(vdata != null);

            if (vdata.LastItem == e)
                UnuseVar(vdata, VariableState.Unused);
        }