cfad47cfa3/tads3/vmsrcf.cpp
Commiter: Nikos Chantziaras
Author: Nikos Chantziaras
Revision: cfad47cfa3
File Size: 6.7 KB
(June 01, 2009 20:54 UTC) Almost 3 years ago
Initial commit.
#ifdef RCSID
static char RCSid[] =
"$Header$";
#endif
/*
* Copyright (c) 1999, 2002 Michael J. Roberts. All Rights Reserved.
*
* Please see the accompanying license file, LICENSE.TXT, for information
* on using and copying this software.
*/
/*
Name
vmsrcf.cpp - T3 VM source file list
Function
Notes
Modified
12/01/99 MJRoberts - Creation
*/
#include "t3std.h"
#include "vmsrcf.h"
/* ------------------------------------------------------------------------ */
/*
* Source file table implementation
*/
/*
* Initialize
*/
CVmSrcfTable::CVmSrcfTable()
{
/* no entries yet */
list_ = 0;
list_used_ = 0;
list_alloc_ = 0;
}
/*
* Delete
*/
CVmSrcfTable::~CVmSrcfTable()
{
/* delete the list if we allocated one */
if (list_ != 0)
{
/* clear the table */
clear();
/* delete the list */
t3free(list_);
}
}
/*
* Clear the table
*/
void CVmSrcfTable::clear()
{
size_t i;
/* delete each entry */
for (i = 0 ; i < list_used_ ; ++i)
delete(list_[i]);
/*
* we no longer have any entries, but leave the list allocated in
* case we add entries again
*/
list_used_ = 0;
}
/*
* Add a new entry to the table
*/
CVmSrcfEntry *CVmSrcfTable::add_entry(int orig_index, size_t name_len)
{
CVmSrcfEntry *entry;
/* allocate the new entry */
entry = new CVmSrcfEntry(orig_index, (uint)orig_index == list_used_,
name_len);
/*
* make sure we have room in our list for a new entry; if not,
* expand the list
*/
if (list_used_ >= list_alloc_)
{
size_t siz;
/* calculate the expanded list size */
list_alloc_ += 10;
siz = list_alloc_ * sizeof(list_[0]);
/* allocate or reallocate the list */
if (list_ == 0)
list_ = (CVmSrcfEntry **)t3malloc(siz);
else
list_ = (CVmSrcfEntry **)t3realloc(list_, siz);
}
/* add the new entry */
list_[list_used_] = entry;
/* count the new entry */
++list_used_;
/* return the new entry */
return entry;
}
/* ------------------------------------------------------------------------ */
/*
* Source file record implementation
*/
/*
* Allocate or expand the line records array
*/
void CVmSrcfEntry::alloc_line_records(ulong cnt)
{
ulong siz;
/*
* if the current array size is already big enough for the given
* count, there's nothing to do
*/
if (cnt <= lines_alo_)
return;
/* calculate the allocation size */
siz = cnt * sizeof(lines_[0]);
/*
* if the new size exceeds the maximum local system's architectural
* limit for a single allocation, restrict the size to the maximum
* allocation
*/
if (siz > OSMALMAX)
{
/* recalculate the size for the maximum architectural allocation */
cnt = OSMALMAX / sizeof(lines_[0]);
siz = cnt * sizeof(lines_[0]);
/* if we're already there, ignore the request */
if (cnt <= lines_alo_)
return;
}
/* allocate or reallocate the line record array */
if (lines_ == 0)
lines_ = (CVmSrcfLine *)t3malloc((size_t)siz);
else
lines_ = (CVmSrcfLine *)t3realloc(lines_, (size_t)siz);
/* remember the new array size */
lines_alo_ = cnt;
}
/*
* add a line record
*/
void CVmSrcfEntry::add_line_record(ulong linenum, ulong code_addr)
{
/* make sure we have enough space */
if (lines_cnt_ >= lines_alo_)
{
/* expand the line records array */
alloc_line_records(lines_alo_ + 1024);
/* if that didn't create enough space, ignore the new record */
if (lines_cnt_ >= lines_alo_)
return;
}
/* add the new record */
lines_[lines_cnt_].linenum = linenum;
lines_[lines_cnt_].code_addr = code_addr;
/* count the new record */
++lines_cnt_;
}
/*
* Find a source line
*/
ulong CVmSrcfEntry::find_src_addr(ulong *linenum, int exact)
{
long hi, lo, cur;
/* if there are no line records, return failure */
if (lines_cnt_ == 0)
return 0;
/* perform a binary search of the line record array */
lo = 0;
hi = (long)lines_cnt_ - 1;
while (lo <= hi)
{
int match;
/* split the difference */
cur = lo + (hi - lo)/2;
/*
* Check for a match. If they require an exact match, we must
* find the line number exactly. Otherwise, check to see if
* this is the next executable line after the given line.
*/
if (exact)
{
/* exact match required */
match = (lines_[cur].linenum == *linenum);
}
else
{
/*
* exact match not required - match if this is the next
* executable line after the requested line, or this is the
* last executable line and the requested line is higher
*/
if (cur == 0)
{
/*
* this is the first executable line - if the requested
* line is before this one, this is our match
*/
match = (*linenum <= lines_[cur].linenum);
}
else if (cur == (long)lines_cnt_ - 1)
{
/*
* this is the last executable line - if the requested
* line is after this one, this is our match
*/
match = (*linenum >= lines_[cur].linenum);
}
else
{
/*
* we're somewhere in the middle of the file - if the
* requested line is before this one, but after the
* previous executable line, this is our match
*/
match = (*linenum <= lines_[cur].linenum
&& *linenum > lines_[cur - 1].linenum);
}
}
/* if we have a match, return it; otherwise, keep searching */
if (match)
{
/*
* if this is a non-exact match, update the caller's line
* number with the actual line number we found
*/
*linenum = lines_[cur].linenum;
/* return our code address */
return lines_[cur].code_addr;
}
else if (*linenum > lines_[cur].linenum)
{
/* we need to go higher */
lo = (cur == lo ? cur + 1 : cur);
}
else
{
/* we need to go lower */
hi = (cur == hi ? hi - 1 : cur);
}
}
/* failure */
return 0;
} |