| 108 | } |
| 109 | |
| 110 | unsigned int PrintStackFrame(int address, char* current, unsigned int bufSize) |
| 111 | { |
| 112 | const char *start = current; |
| 113 | |
| 114 | FastVector<ExternFuncInfo> &exFunctions = NULLC::commonLinker->exFunctions; |
| 115 | FastVector<char> &exSymbols = NULLC::commonLinker->exSymbols; |
| 116 | FastVector<ExternModuleInfo> &exModules = NULLC::commonLinker->exModules; |
| 117 | |
| 118 | struct SourceInfo |
| 119 | { |
| 120 | unsigned int byteCodePos; |
| 121 | unsigned int sourceOffset; |
| 122 | }; |
| 123 | |
| 124 | SourceInfo *exInfo = (SourceInfo*)&NULLC::commonLinker->exCodeInfo[0]; |
| 125 | const char *source = &NULLC::commonLinker->exSource[0]; |
| 126 | unsigned int infoSize = NULLC::commonLinker->exCodeInfo.size() / 2; |
| 127 | |
| 128 | int funcID = -1; |
| 129 | for(unsigned int i = 0; i < exFunctions.size(); i++) |
| 130 | if(address >= exFunctions[i].address && address <= (exFunctions[i].address + exFunctions[i].codeSize)) |
| 131 | funcID = i; |
| 132 | if(funcID != -1) |
| 133 | current += SafeSprintf(current, bufSize - int(current - start), "%s", &exSymbols[exFunctions[funcID].offsetToName]); |
| 134 | else |
| 135 | current += SafeSprintf(current, bufSize - int(current - start), "%s", address == -1 ? "external" : "global scope"); |
| 136 | if(address != -1) |
| 137 | { |
| 138 | unsigned int infoID = 0; |
| 139 | unsigned int i = address - 1; |
| 140 | while((infoID < infoSize - 1) && (i >= exInfo[infoID + 1].byteCodePos)) |
| 141 | infoID++; |
| 142 | const char *codeStart = source + exInfo[infoID].sourceOffset; |
| 143 | // Find beginning of the line |
| 144 | while(codeStart != source && *(codeStart-1) != '\n') |
| 145 | codeStart--; |
| 146 | // Skip whitespace |
| 147 | while(*codeStart == ' ' || *codeStart == '\t') |
| 148 | codeStart++; |
| 149 | const char *codeEnd = codeStart; |
| 150 | // Find corresponding module |
| 151 | unsigned moduleID = ~0u; |
| 152 | for(unsigned l = 0; l < exModules.size(); l++) |
| 153 | { |
| 154 | if(codeStart >= source + exModules[l].sourceOffset && codeStart < source + exModules[l].sourceOffset + exModules[l].sourceSize) |
| 155 | moduleID = l; |
| 156 | } |
| 157 | const char *moduleStart = NULL; |
| 158 | if(moduleID != ~0u) |
| 159 | moduleStart = source + exModules[moduleID].sourceOffset; |
| 160 | else |
| 161 | moduleStart = source + exModules[exModules.size()-1].sourceOffset + exModules[exModules.size()-1].sourceSize; |
| 162 | // Find line number |
| 163 | unsigned line = 0; |
| 164 | while(moduleStart != codeStart) |
| 165 | { |
| 166 | if(*moduleStart++ == '\n') |
| 167 | line++; |
no test coverage detected