8
0
mirror of https://github.com/FirebirdSQL/firebird.git synced 2025-01-22 20:03:02 +01:00

Track names of FOR ... AS CURSOR <name>.

This commit is contained in:
Adriano dos Santos Fernandes 2023-01-04 21:42:04 -03:00 committed by Adriano dos Santos Fernandes
parent aa847a7846
commit 88d89bb918
10 changed files with 104 additions and 33 deletions

View File

@ -103,7 +103,7 @@ void BlrDebugWriter::putDebugArgument(UCHAR type, USHORT number, const TEXT* nam
debugData.add(reinterpret_cast<const UCHAR*>(name), len); debugData.add(reinterpret_cast<const UCHAR*>(name), len);
} }
void BlrDebugWriter::putDebugCursor(USHORT number, const MetaName& name) void BlrDebugWriter::putDebugDeclaredCursor(USHORT number, const MetaName& name)
{ {
if (debugData.isEmpty()) if (debugData.isEmpty())
return; return;
@ -119,6 +119,21 @@ void BlrDebugWriter::putDebugCursor(USHORT number, const MetaName& name)
debugData.add(reinterpret_cast<const UCHAR*>(name.c_str()), len); debugData.add(reinterpret_cast<const UCHAR*>(name.c_str()), len);
} }
void BlrDebugWriter::putDebugForCursor(const MetaName& name)
{
if (debugData.isEmpty())
return;
debugData.add(fb_dbg_map_for_curname);
putBlrOffset();
USHORT len = MIN(name.length(), MAX_UCHAR);
debugData.add(len);
debugData.add(reinterpret_cast<const UCHAR*>(name.c_str()), len);
}
void BlrDebugWriter::putDebugSubFunction(DeclareSubFuncNode* subFuncNode) void BlrDebugWriter::putDebugSubFunction(DeclareSubFuncNode* subFuncNode)
{ {
if (debugData.isEmpty()) if (debugData.isEmpty())

View File

@ -47,7 +47,8 @@ public:
void putDebugSrcInfo(ULONG, ULONG); void putDebugSrcInfo(ULONG, ULONG);
void putDebugVariable(USHORT, const MetaName&); void putDebugVariable(USHORT, const MetaName&);
void putDebugArgument(UCHAR, USHORT, const TEXT*); void putDebugArgument(UCHAR, USHORT, const TEXT*);
void putDebugCursor(USHORT, const MetaName&); void putDebugDeclaredCursor(USHORT, const MetaName&);
void putDebugForCursor(const MetaName&);
void putDebugSubFunction(DeclareSubFuncNode* subFuncNode); void putDebugSubFunction(DeclareSubFuncNode* subFuncNode);
void putDebugSubProcedure(DeclareSubProcNode* subProcNode); void putDebugSubProcedure(DeclareSubProcNode* subProcNode);

View File

@ -1244,7 +1244,7 @@ DeclareCursorNode* DeclareCursorNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
cursorNumber = dsqlScratch->cursorNumber++; cursorNumber = dsqlScratch->cursorNumber++;
dsqlScratch->cursors.push(this); dsqlScratch->cursors.push(this);
dsqlScratch->putDebugCursor(cursorNumber, dsqlName); dsqlScratch->putDebugDeclaredCursor(cursorNumber, dsqlName);
++dsqlScratch->scopeLevel; ++dsqlScratch->scopeLevel;
@ -1303,7 +1303,7 @@ DeclareCursorNode* DeclareCursorNode::pass2(thread_db* tdbb, CompilerScratch* cs
ExprNode::doPass2(tdbb, csb, refs.getAddress()); ExprNode::doPass2(tdbb, csb, refs.getAddress());
MetaName cursorName; MetaName cursorName;
csb->csb_dbg_info->curIndexToName.get(cursorNumber, cursorName); csb->csb_dbg_info->declaredCursorIndexToName.get(cursorNumber, cursorName);
// Finish up processing of record selection expressions. // Finish up processing of record selection expressions.
@ -4881,6 +4881,9 @@ DmlNode* ForNode::parse(thread_db* tdbb, MemoryPool& pool, CompilerScratch* csb,
{ {
ForNode* node = FB_NEW_POOL(pool) ForNode(pool); ForNode* node = FB_NEW_POOL(pool) ForNode(pool);
if (auto cursorName = csb->csb_dbg_info->forCursorOffsetToName.get(csb->csb_blr_reader.getOffset() - 1))
csb->csb_forCursorNames.put(node, *cursorName);
if (csb->csb_blr_reader.peekByte() == blr_marks) if (csb->csb_blr_reader.peekByte() == blr_marks)
node->marks |= PAR_marks(csb); node->marks |= PAR_marks(csb);
@ -4929,9 +4932,6 @@ ForNode* ForNode::dsqlPass(DsqlCompilerScratch* dsqlScratch)
dsqlCursor->rse = node->rse; dsqlCursor->rse = node->rse;
dsqlCursor->cursorNumber = dsqlScratch->cursorNumber++; dsqlCursor->cursorNumber = dsqlScratch->cursorNumber++;
dsqlScratch->cursors.push(dsqlCursor); dsqlScratch->cursors.push(dsqlCursor);
// ASF: We cannot write this cursor name in debug info, as dsqlScratch->cursorNumber is
// decremented below. But for now we don't need it.
} }
else else
node->rse = dsqlSelect->dsqlPass(dsqlScratch)->dsqlRse; node->rse = dsqlSelect->dsqlPass(dsqlScratch)->dsqlRse;
@ -5001,6 +5001,9 @@ void ForNode::genBlr(DsqlCompilerScratch* dsqlScratch)
// Generate FOR loop // Generate FOR loop
if (dsqlCursor)
dsqlScratch->putDebugForCursor(dsqlCursor->dsqlName);
dsqlScratch->appendUChar(blr_for); dsqlScratch->appendUChar(blr_for);
if (marks) if (marks)
@ -5069,11 +5072,11 @@ StmtNode* ForNode::pass2(thread_db* tdbb, CompilerScratch* csb)
RecordSource* const rsb = CMP_post_rse(tdbb, csb, rse.getObject()); RecordSource* const rsb = CMP_post_rse(tdbb, csb, rse.getObject());
MetaName cursorName;
csb->csb_forCursorNames.get(this, cursorName);
cursor = FB_NEW_POOL(*tdbb->getDefaultPool()) cursor = FB_NEW_POOL(*tdbb->getDefaultPool())
Cursor(csb, rsb, rse, !(marks & MARK_AVOID_COUNTERS), line, column); Cursor(csb, rsb, rse, !(marks & MARK_AVOID_COUNTERS), line, column, cursorName);
// ASF: We cannot define the name of the cursor here, but this is not a problem,
// as implicit cursors are always positioned in a valid record, and the name is
// only used to raise isc_cursor_not_positioned.
csb->csb_fors.add(cursor); csb->csb_fors.add(cursor);

View File

@ -780,7 +780,8 @@
#define fb_dbg_map_argument 4 #define fb_dbg_map_argument 4
#define fb_dbg_subproc 5 #define fb_dbg_subproc 5
#define fb_dbg_subfunc 6 #define fb_dbg_subfunc 6
#define fb_dbg_map_curname 7 #define fb_dbg_map_curname 7 /* declared cursor */
#define fb_dbg_map_for_curname 8 /* FOR cursor */
//// TODO: LocalTable name. //// TODO: LocalTable name.
// sub code for fb_dbg_map_argument // sub code for fb_dbg_map_argument

View File

@ -4327,6 +4327,7 @@ const
fb_dbg_subproc = byte(5); fb_dbg_subproc = byte(5);
fb_dbg_subfunc = byte(6); fb_dbg_subfunc = byte(6);
fb_dbg_map_curname = byte(7); fb_dbg_map_curname = byte(7);
fb_dbg_map_for_curname = byte(8);
fb_dbg_arg_input = byte(0); fb_dbg_arg_input = byte(0);
fb_dbg_arg_output = byte(1); fb_dbg_arg_output = byte(1);
isc_facility = 20; isc_facility = 20;

View File

@ -135,13 +135,44 @@ void DBG_parse_debug_info(ULONG length, const UCHAR* data, DbgInfo& dbgInfo)
if (code == fb_dbg_map_varname) if (code == fb_dbg_map_varname)
dbgInfo.varIndexToName.put(index, MetaName((const TEXT*) data, length)); dbgInfo.varIndexToName.put(index, MetaName((const TEXT*) data, length));
else else
dbgInfo.curIndexToName.put(index, MetaName((const TEXT*) data, length)); dbgInfo.declaredCursorIndexToName.put(index, MetaName((const TEXT*) data, length));
// variable/cursor name string // variable/cursor name string
data += length; data += length;
} }
break; break;
case fb_dbg_map_for_curname:
{
if (data + 5 > end)
{
bad_format = true;
break;
}
// fb_dbg_map_for_curname do not exist in DBG_INFO_VERSION_1,
// so always use DBG_INFO_VERSION_2 format.
ULONG offset = *data++;
offset |= *data++ << 8;
offset |= *data++ << 16;
offset |= *data++ << 24;
// variable/cursor name string length
USHORT length = *data++;
if (data + length > end)
{
bad_format = true;
break;
}
dbgInfo.forCursorOffsetToName.put(offset, MetaName((const TEXT*) data, length));
// cursor name string
data += length;
}
break;
case fb_dbg_map_argument: case fb_dbg_map_argument:
{ {
if (data + 4 > end) if (data + 4 > end)

View File

@ -58,8 +58,6 @@ typedef Firebird::SortedArray<
ULONG, ULONG,
MapBlrToSrcItem> MapBlrToSrc; MapBlrToSrcItem> MapBlrToSrc;
typedef GenericMap<Pair<Right<USHORT, Jrd::MetaName> > > MapVarIndexToName;
struct ArgumentInfo struct ArgumentInfo
{ {
ArgumentInfo(UCHAR aType, USHORT aIndex) ArgumentInfo(UCHAR aType, USHORT aIndex)
@ -86,8 +84,6 @@ struct ArgumentInfo
} }
}; };
typedef GenericMap<Pair<Right<ArgumentInfo, Jrd::MetaName> > > MapArgumentInfoToName;
struct DbgInfo : public PermanentStorage struct DbgInfo : public PermanentStorage
{ {
explicit DbgInfo(MemoryPool& p) explicit DbgInfo(MemoryPool& p)
@ -95,7 +91,8 @@ struct DbgInfo : public PermanentStorage
blrToSrc(p), blrToSrc(p),
varIndexToName(p), varIndexToName(p),
argInfoToName(p), argInfoToName(p),
curIndexToName(p), declaredCursorIndexToName(p),
forCursorOffsetToName(p),
subFuncs(p), subFuncs(p),
subProcs(p) subProcs(p)
{ {
@ -111,10 +108,11 @@ struct DbgInfo : public PermanentStorage
blrToSrc.clear(); blrToSrc.clear();
varIndexToName.clear(); varIndexToName.clear();
argInfoToName.clear(); argInfoToName.clear();
curIndexToName.clear(); declaredCursorIndexToName.clear();
forCursorOffsetToName.clear();
{ // scope { // scope
GenericMap<Pair<Left<Jrd::MetaName, DbgInfo*> > >::Accessor accessor(&subFuncs); LeftPooledMap<Jrd::MetaName, DbgInfo*>::Accessor accessor(&subFuncs);
for (bool found = accessor.getFirst(); found; found = accessor.getNext()) for (bool found = accessor.getFirst(); found; found = accessor.getNext())
delete accessor.current()->second; delete accessor.current()->second;
@ -123,7 +121,7 @@ struct DbgInfo : public PermanentStorage
} }
{ // scope { // scope
GenericMap<Pair<Left<Jrd::MetaName, DbgInfo*> > >::Accessor accessor(&subProcs); LeftPooledMap<Jrd::MetaName, DbgInfo*>::Accessor accessor(&subProcs);
for (bool found = accessor.getFirst(); found; found = accessor.getNext()) for (bool found = accessor.getFirst(); found; found = accessor.getNext())
delete accessor.current()->second; delete accessor.current()->second;
@ -133,11 +131,12 @@ struct DbgInfo : public PermanentStorage
} }
MapBlrToSrc blrToSrc; // mapping between blr offsets and source text position MapBlrToSrc blrToSrc; // mapping between blr offsets and source text position
MapVarIndexToName varIndexToName; // mapping between variable index and name RightPooledMap<USHORT, Jrd::MetaName> varIndexToName; // mapping between variable index and name
MapArgumentInfoToName argInfoToName; // mapping between argument info (type, index) and name RightPooledMap<ArgumentInfo, Jrd::MetaName> argInfoToName; // mapping between argument info (type, index) and name
MapVarIndexToName curIndexToName; // mapping between cursor index and name RightPooledMap<USHORT, Jrd::MetaName> declaredCursorIndexToName; // mapping between declared cursor index and name
GenericMap<Pair<Left<Jrd::MetaName, DbgInfo*> > > subFuncs; // sub functions RightPooledMap<ULONG, Jrd::MetaName> forCursorOffsetToName; // mapping between for-cursor offset and name
GenericMap<Pair<Left<Jrd::MetaName, DbgInfo*> > > subProcs; // sub procedures LeftPooledMap<Jrd::MetaName, DbgInfo*> subFuncs; // sub functions
LeftPooledMap<Jrd::MetaName, DbgInfo*> subProcs; // sub procedures
}; };
} // namespace Firebird } // namespace Firebird

View File

@ -479,6 +479,7 @@ public:
csb_invariants(p), csb_invariants(p),
csb_current_nodes(p), csb_current_nodes(p),
csb_current_for_nodes(p), csb_current_for_nodes(p),
csb_forCursorNames(p),
csb_computing_fields(p), csb_computing_fields(p),
csb_inner_booleans(p), csb_inner_booleans(p),
csb_variables_used_in_subroutines(p), csb_variables_used_in_subroutines(p),
@ -558,6 +559,7 @@ public:
Firebird::Array<ExprNode*> csb_current_nodes; // RseNode's and other invariant Firebird::Array<ExprNode*> csb_current_nodes; // RseNode's and other invariant
// candidates within whose scope we are // candidates within whose scope we are
Firebird::Array<ForNode*> csb_current_for_nodes; Firebird::Array<ForNode*> csb_current_for_nodes;
Firebird::RightPooledMap<ForNode*, MetaName> csb_forCursorNames;
Firebird::SortedArray<jrd_fld*> csb_computing_fields; // Computed fields being compiled Firebird::SortedArray<jrd_fld*> csb_computing_fields; // Computed fields being compiled
Firebird::Array<BoolExprNode*> csb_inner_booleans; // Inner booleans at the current scope Firebird::Array<BoolExprNode*> csb_inner_booleans; // Inner booleans at the current scope
Firebird::SortedArray<USHORT> csb_variables_used_in_subroutines; Firebird::SortedArray<USHORT> csb_variables_used_in_subroutines;

View File

@ -1432,8 +1432,8 @@ ISC_STATUS filter_debug_info(USHORT action, BlobControl* control)
string str; string str;
MapArgumentInfoToName::ConstAccessor args(&dbgInfo.argInfoToName); if (auto args = dbgInfo.argInfoToName.constAccessor();
if (args.getFirst()) args.getFirst())
{ {
string_put(control, "Parameters:"); string_put(control, "Parameters:");
str.printf("%10s %-32s %-6s", "Number", "Name", "Type"); str.printf("%10s %-32s %-6s", "Number", "Name", "Type");
@ -1453,8 +1453,8 @@ ISC_STATUS filter_debug_info(USHORT action, BlobControl* control)
string_put(control, ""); string_put(control, "");
} }
MapVarIndexToName::ConstAccessor vars(&dbgInfo.varIndexToName); if (auto vars = dbgInfo.varIndexToName.constAccessor();
if (vars.getFirst()) vars.getFirst())
{ {
string_put(control, "Variables:"); string_put(control, "Variables:");
str.printf("%10s %-32s", "Number", "Name"); str.printf("%10s %-32s", "Number", "Name");
@ -1471,8 +1471,8 @@ ISC_STATUS filter_debug_info(USHORT action, BlobControl* control)
string_put(control, ""); string_put(control, "");
} }
MapVarIndexToName::ConstAccessor cursors(&dbgInfo.curIndexToName); if (auto cursors = dbgInfo.declaredCursorIndexToName.constAccessor();
if (cursors.getFirst()) cursors.getFirst())
{ {
string_put(control, "Cursors:"); string_put(control, "Cursors:");
str.printf("%10s %-32s", "Number", "Name"); str.printf("%10s %-32s", "Number", "Name");
@ -1489,6 +1489,24 @@ ISC_STATUS filter_debug_info(USHORT action, BlobControl* control)
string_put(control, ""); string_put(control, "");
} }
if (auto cursors = dbgInfo.forCursorOffsetToName.constAccessor();
cursors.getFirst())
{
string_put(control, "FOR Cursors:");
str.printf("%10s %-32s", "Offset", "Name");
string_put(control, str.c_str());
str.replace(str.begin(), str.end(), str.length(), '-');
string_put(control, str.c_str());
do
{
str.printf("%10d %-32s", cursors.current()->first, cursors.current()->second.c_str());
string_put(control, str.c_str());
} while (cursors.getNext());
string_put(control, "");
}
string_put(control, "BLR to Source mapping:"); string_put(control, "BLR to Source mapping:");
str.printf("%10s %10s %10s", "BLR offset", "Line", "Column"); str.printf("%10s %10s %10s", "BLR offset", "Line", "Column");
string_put(control, str.c_str()); string_put(control, str.c_str());

View File

@ -101,7 +101,7 @@ namespace Jrd
public: public:
Cursor(CompilerScratch* csb, const RecordSource* rsb, const RseNode* rse, Cursor(CompilerScratch* csb, const RecordSource* rsb, const RseNode* rse,
bool updateCounters, ULONG line, ULONG column, const MetaName& name = ""); bool updateCounters, ULONG line, ULONG column, const MetaName& name);
void open(thread_db* tdbb) const override; void open(thread_db* tdbb) const override;
void close(thread_db* tdbb) const override; void close(thread_db* tdbb) const override;