/* ILEngineer - Crummy .NET Decompiler * Copyright (C) 2001-2002 Jay Freeman (saurik) */ /* * Redistribution and use in source and binary * forms, with or without modification, are permitted * provided that the following conditions are met: * * 1. Redistributions of source code must retain the * above copyright notice, this list of conditions * and the following disclaimer. * 2. Redistributions in binary form must reproduce the * above copyright notice, this list of conditions * and the following disclaimer in the documentation * and/or other materials provided with the * distribution. * 3. The name of the author may not be used to endorse * or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #pragma once #include "ilengineer/Statement.h" #include "metallurgy/Method.h" #include "metallurgy/ILMethodImpl.h" #include "ilengineer/ilengineer.h" namespace ILEngineer { class ILENGINEER_API Block : public Statement { protected: StatementVector m_Statements; uint8_t *m_End; public: Block(Blocks::Method *method, uint8_t *offset = NULL, uint8_t *end = NULL) : Statement(method, offset), m_End(end) {} virtual ~Block() { if (isOpen && isBroken) del++; if (!m_Garbage) { if (isOpen && isBroken) std::cout << "deleting blk: " << del << std::endl; for (StatementVector::iterator stI(m_Statements.begin()); stI != m_Statements.end(); stI++) { if (isOpen && isBroken) std::cout << "delete(" << del << "): " << typeid(**stI).name() << std::endl; delete *stI; } } if (isOpen && isBroken) del--; } StatementVector & getStatements() { return m_Statements; } uint8_t * getEnd() { return m_End; } void setEnd(uint8_t *offset) { m_End = offset; } void OptimizeBranch(); void OptimizeDoWhile(); void OptimizeElse(); void OptimizeForEach(); void OptimizeIf(); void OptimizeIfBranch(); void OptimizeIfWhile(); void OptimizeInline(); void OptimizeLock(); void OptimizeStrings(); void OptimizeSwitch(); void OptimizeTry(); void OptimizeTypeOf(); void OptimizeWhileFor(); void OptimizeBreak(uint8_t *offset = NULL); void OptimizeContinue(uint8_t *offset = NULL); void OptimizeReturn(uint8_t *offset); void ResetTargets(); virtual void UpdateTargets(); void Populate(uint8_t * &offset, ULONG length, Metallurgy::ILMethodImpl::ExceptionVector &exs, bool disregard = false); void getBlocks(BlockVector &blocks) { blocks.push_back(this); for (StatementVector::iterator stI(m_Statements.begin()); stI != m_Statements.end(); stI++) if (typeid(**stI) == typeid(Block)) dynamic_cast(*stI)->getBlocks(blocks); } virtual void Find(const type_info &type, Operation::Reference::Vector &ops) { Statement::Find(type, ops); for (StatementVector::iterator stI(m_Statements.begin()); stI != m_Statements.end(); stI++) (*stI)->Find(type, ops); } /* // XXX: These are going to be required. virtual bool Find(const type_info &type, Operation::Reference &ref) { if (Operation::Find(type, ref)) return true; } virtual bool Find(const uint8_t *offset, Operation::Reference &ref) { if (Operation::Find(offset, ref)) return true; }*/ bool Find(const uint8_t *offset, Statement::Reference &ref) { for (StatementVector::iterator stI(m_Statements.begin()); stI != m_Statements.end(); stI++) { if ((*stI)->getOffset() == offset) { ref = Statement::Reference(&m_Statements, stI); return true; } if ((*stI)->isBlock()) { if (dynamic_cast(*stI)->Find(offset, ref)) return true; } } return false; } }; }