2 * Copyright 2009, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
7 #include "DisassembledCode.h"
16 #include "SourceLanguage.h"
17 #include "Statement.h"
20 struct DisassembledCode::Line
{
22 ContiguousStatement
* statement
;
24 Line(const BString
& line
, ContiguousStatement
* statement
)
33 DisassembledCode::DisassembledCode(SourceLanguage
* language
)
38 fLanguage
->AcquireReference();
42 DisassembledCode::~DisassembledCode()
44 for (int32 i
= 0; Statement
* statement
= fStatements
.ItemAt(i
); i
++)
45 statement
->ReleaseReference();
47 fLanguage
->ReleaseReference();
52 DisassembledCode::Lock()
54 // We're immutable, so no locking required.
60 DisassembledCode::Unlock()
66 DisassembledCode::GetSourceLanguage() const
73 DisassembledCode::CountLines() const
75 return fLines
.CountItems();
80 DisassembledCode::LineAt(int32 index
) const
82 Line
* line
= fLines
.ItemAt(index
);
83 return line
!= NULL
? line
->line
.String() : NULL
;
88 DisassembledCode::LineLengthAt(int32 index
) const
90 Line
* line
= fLines
.ItemAt(index
);
91 return line
!= NULL
? line
->line
.Length() : 0;
96 DisassembledCode::GetStatementLocationRange(const SourceLocation
& location
,
97 SourceLocation
& _start
, SourceLocation
& _end
) const
99 Line
* line
= fLines
.ItemAt(location
.Line());
100 if (line
== NULL
|| line
->statement
== NULL
)
103 _start
= line
->statement
->StartSourceLocation();
104 _end
= SourceLocation(_start
.Line() + 1);
105 // TODO: Multi-line instructions!
111 DisassembledCode::GetSourceFile() const
118 DisassembledCode::StatementAtLocation(const SourceLocation
& location
) const
120 Line
* line
= fLines
.ItemAt(location
.Line());
121 return line
!= NULL
? line
->statement
: NULL
;
126 DisassembledCode::StatementAtAddress(target_addr_t address
) const
128 return fStatements
.BinarySearchByKey(address
, &_CompareAddressStatement
);
133 DisassembledCode::StatementAddressRange() const
135 if (fStatements
.IsEmpty())
136 return TargetAddressRange();
138 ContiguousStatement
* first
= fStatements
.ItemAt(0);
139 ContiguousStatement
* last
140 = fStatements
.ItemAt(fStatements
.CountItems() - 1);
141 return TargetAddressRange(first
->AddressRange().Start(),
142 last
->AddressRange().End());
147 DisassembledCode::AddCommentLine(const BString
& line
)
149 return _AddLine(line
, NULL
);
154 DisassembledCode::AddInstructionLine(const BString
& line
, target_addr_t address
,
157 int32 lineIndex
= fLines
.CountItems();
159 ContiguousStatement
* statement
= new(std::nothrow
) ContiguousStatement(
160 SourceLocation(lineIndex
), TargetAddressRange(address
, size
));
161 if (statement
== NULL
)
164 if (!fStatements
.AddItem(statement
)) {
169 if (!_AddLine(line
, statement
))
177 DisassembledCode::_AddLine(const BString
& _line
, ContiguousStatement
* statement
)
179 Line
* line
= new(std::nothrow
) Line(_line
, statement
);
183 if (!fLines
.AddItem(line
)) {
193 DisassembledCode::_CompareAddressStatement(const target_addr_t
* address
,
194 const ContiguousStatement
* statement
)
196 const TargetAddressRange
& range
= statement
->AddressRange();
198 if (*address
< range
.Start())
200 return *address
< range
.End() ? 0 : 1;