Exemplo n.º 1
0
        private void _StatsFunction(String name, uint value, ScriptOpCodes opCode, bool isSet)
        {
            uint rowIndex = value >> 22;
            uint param = value & 0x3FFFFF;

            // check if we have an object ptr reference
            if ((!isSet && _stack.Count > 0) || (isSet && _stack.Count > 1))
            {
                StackObject stackObjectPeek = _stack.Peek();
                if (stackObjectPeek.IsVarAssign && stackObjectPeek.Type == ArgType.ContextPtr)
                {
                    name = stackObjectPeek.Value + name;
                    _stack.Pop();
                }
            }

            // get index string details
            String indexStr;
            String paramStr;
            if (_statsTable == null)
            {
                indexStr = rowIndex.ToString();
                paramStr = param.ToString();
            }
            else
            {
                Debug.Assert(rowIndex >= 0 && rowIndex < _statsTable.Rows.Count);
                Object statsRow = _statsTable.Rows[(int)rowIndex];

                indexStr = (String)_statsDelegator["stat"](statsRow);

                int param1Table = (int)_statsDelegator["param1Table"](statsRow);
                if (param1Table != -1)
                {
                    paramStr = _fileManager.GetExcelRowStringFromTableIndex(param1Table, (int)param);
                }
                else
                {
                    paramStr = null;
                }

                // A couple of TCv4 stats have this - don't think it matters though...
                Debug.Assert((int)_statsDelegator["param2Table"](statsRow) == -1);
            }

            // generate the arg string
            String argStr = String.Empty;
            if (isSet)
            {
                _CheckStack(1, opCode);
                StackObject varStackObject = _stack.Pop();

                argStr = ", " + varStackObject.Value;
            }

            // format paramStr if needed
            if (paramStr != null) // we can have empty excel strings (e.g. STATES row 0); just not null strings (i.e. no or invalid param)
            {
                paramStr = String.Format(", '{0}'", paramStr);
            }
            else if (param != 0) // we have an excel index, but no excel row string
            {
                paramStr = ", " + param;
            }

            // create new stack object
            StackObject newStackObject = new StackObject
            {
                Value = String.Format("{0}('{1}'{2}{3})", name, indexStr, paramStr, argStr),
                IsFunction = true
            };

            _stack.Push(newStackObject);
        }
Exemplo n.º 2
0
        private void _DecompileCondition(byte[] scriptBytes, ScriptOpCodes opCode, int ifLevel)
        {
            _CheckStack(1, opCode);

            uint byteOffset = FileTools.ByteArrayToUInt32(scriptBytes, ref _offset);
            Debug.Assert(byteOffset % 4 == 0 && FileTools.ByteArrayToUInt32(scriptBytes, _startOffset + (int)byteOffset - 4) == (uint)ScriptOpCodes.EndCond);

            StackObject conditionObject = _stack.Pop();
            conditionObject.OpCode = opCode;
            _stack.Push(conditionObject);

            int subMaxBytes = (int)byteOffset - (_offset - _startOffset);
            _Decompile(scriptBytes, subMaxBytes, ifLevel + 1);

            if (!DebugEnabled || !_debugFormatConditionalByteCounts) return;

            conditionObject = _stack.Pop();
            conditionObject.Value = String.Format("{0}[{1}]", conditionObject.Value, byteOffset);
            _stack.Push(conditionObject);
        }
Exemplo n.º 3
0
        private void _DoOperator(String op, int precedence, ScriptOpCodes opCode, int ifLevel)
        {
            _CheckStack(2, opCode);

            StackObject value2Object = _stack.Pop();
            StackObject value1Object = _stack.Pop();

            const String operatorFormat = "{0}{1}{2}";
            const String operatorFormatLParentheses = "({0}){1}{2}";
            const String operatorFormatRParentheses = "{0}{1}({2})";
            const String operatorFormat2Parentheses = "({0}){1}({2})";

            String opFormat = operatorFormat;
            bool debugTest = false;
            if (value1Object.Precedence > precedence)
            {
                opFormat = operatorFormatLParentheses;
                debugTest = true;
            }
            else if (value2Object.Precedence > precedence)
            {
                opFormat = operatorFormatRParentheses;
                debugTest = true;
            }

            // some of these extra conditions are purely to ensure complete fidelity when recompiling
            // in some cases they are completely unnecessary from an arithmetic perspective
            if (value1Object.Precedence == value2Object.Precedence && value1Object.IsPrecedenceFunc && value2Object.IsPrecedenceFunc)
            {
                opFormat = operatorFormat2Parentheses;
            }
            else if (value1Object.OperatorCount > 0 && value2Object.OperatorCount > 0) // e.g.   (a * b) * (c * d)
            {
                opFormat = operatorFormat2Parentheses;
            }
            else if (value2Object.OperatorCount > 0 && value2Object.Precedence >= precedence && !debugTest)
            {
                opFormat = operatorFormatRParentheses;
            }

            int operatorCount = (value2Object.OperatorCount == -1) ? 1 : value2Object.OperatorCount + 1;
            StackObject newStackObject = new StackObject
            {
                Value = String.Format(opFormat, value1Object.Value, op, value2Object.Value),
                Precedence = precedence,
                IsPrecedenceFunc = true,
                OperatorCount = operatorCount,
                ByteOffset = (uint)_offset,
                IfLevel = ifLevel
            };

            _stack.Push(newStackObject);
        }
Exemplo n.º 4
0
        private void _CheckStack(int requiredCount, ScriptOpCodes opCode, Function functionDetails = null)
        {
            if (requiredCount <= _stack.Count) return;

            String extra = String.Empty;
            if (functionDetails != null)
            {
                extra = String.Format(" Function Name: '{0}'", functionDetails.Name);
            }

            String error = String.Format("The OpCode {0} requires {1} values on the stack.{2}\n{3}", opCode, requiredCount, extra, _DumpStack(_stack));
            throw new Exceptions.ScriptInvalidStackStateException(error);
        }