File: block.h

package info (click to toggle)
residualvm 0.3.1%2Bdfsg-2
  • links: PTS, VCS
  • area: contrib
  • in suites: bullseye
  • size: 31,292 kB
  • sloc: cpp: 227,029; sh: 7,256; xml: 1,731; perl: 1,067; java: 861; asm: 738; python: 691; ansic: 272; makefile: 139; objc: 81; sed: 22; php: 1
file content (141 lines) | stat: -rw-r--r-- 4,590 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
/* ResidualVM - A 3D game interpreter
 *
 * ResidualVM is the legal property of its developers, whose names
 * are too numerous to list here. Please refer to the AUTHORS
 * file distributed with this source distribution.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#ifndef STARK_TOOLS_BLOCK_H
#define STARK_TOOLS_BLOCK_H

#include "common/array.h"

namespace Stark {
namespace Tools {

class CFGCommand;
struct ControlStructure;

/**
 * An aggregate of script commands
 *
 * Commands in the same group are always executed in sequence.
 *
 * This class is a node in the disassembly node graph.
 */
class Block {
public:
	Block();

	/** Add a command at the end of the block, and set it as the command's block */
	void appendCommand(CFGCommand *command);

	/** Get the commands from the block that are not part of a condition */
	Common::Array<CFGCommand *> getLinearCommands() const;

	/** Get the command from the block that plays as a condition in a control structure */
	CFGCommand *getConditionCommand() const;

	/** Does the block contain commands? */
	bool isEmpty() const;

	/** Can the block branch? */
	bool isCondition() const;

	/**
	 * Blocks are linked together in the block graph with these relationships:
	 * - follower: The natural follower of the block. Used when the block is not a branch, nor an end point.
	 * - true branch: The next block when the block's condition evaluates to true.
	 * - false branch: The next block when the block's condition evaluates to false.
	 * - predecessors: A list of blocks whose execution can lead to this block.
	 */
	void setBranches(Block *trueBranch, Block *falseBranch);
	void setFollower(Block *follower);
	void addPredecessor(Block *predecessor);
	Block *getTrueBranch() const;
	Block *getFalseBranch() const;
	Block *getFollower() const;

	/**
	 * Print a list of this block's commands to the debug output
	 */
	void print() const;

	/**
	 * The high level control structure this block has the main role in
	 */
	bool hasControlStructure() const;
	ControlStructure *getControlStructure() const;
	void setControlStructure(ControlStructure *controlStructure);

	/** Flag to indicate this block is the first in an unconditional infinite loop */
	bool isInfiniteLoopStart() const;
	void setInfiniteLoopStart(bool infiniteLoopStart);

	/** Can this block appear multiple times in the decompiled output? */
	bool allowDuplication() const;

	// Graph query methods
	bool hasPredecessor(Block *predecessor) const;
	bool hasSuccessor(Block *successor) const;
	Block *findMergePoint(Block *other);
	bool checkAllBranchesConverge(Block *junction) const;

private:
	bool hasPredecessorIntern(Common::Array<const Block *> &visited, Block *predecessor) const;
	bool hasSuccessorIntern(Common::Array<const Block *> &visited, Block *successor) const;
	bool hasChildSuccessorIntern(Common::Array<const Block *> &visited, Block *child, Block *successor) const;
	Block *findMergePointIntern(Common::Array<const Block *> &visited, Block *other);
	Block *findChildMergePoint(Common::Array<const Block *> &visited, Block *child, Block *other) const;
	bool checkAllBranchesConvergeIntern(Common::Array<const Block *> &visited, Block *junction) const;
	bool checkChildConvergeIntern(Common::Array<const Block *> &visited, Block *child, Block *junction) const;

	uint16 getFirstCommandIndex() const;

	Common::Array<CFGCommand *> _commands;

	Block *_follower;
	Block *_trueBranch;
	Block *_falseBranch;
	Common::Array<Block *> _predecessors;

	ControlStructure *_controlStructure;
	bool _infiniteLoopStart;
};

struct ControlStructure {
	enum ControlStructureType {
		kTypeIf,
		kTypeWhile
	};

	ControlStructureType type;
	Block *condition;
	bool invertedCondition;
	Block *loopHead;
	Block *thenHead;
	Block *elseHead;
	Block *next;

	ControlStructure(ControlStructureType t);
};

} // End of namespace Tools
} // End of namespace Stark

#endif // STARK_TOOLS_BLOCK_H