| 243 | |
| 244 | |
| 245 | def calc_all_wcs(call_graph): |
| 246 | def calc_wcs(fxn_dict2, call_graph1, parents): |
| 247 | """ |
| 248 | Calculates the worst case stack for a fxn that is declared (or called from) in a given file. |
| 249 | :param parents: This function gets called recursively through the call graph. If a function has recursion the |
| 250 | tuple file, fxn will be in the parents stack and everything between the top of the stack and the matching entry |
| 251 | has recursion. |
| 252 | :return: |
| 253 | """ |
| 254 | |
| 255 | # If the wcs is already known, then nothing to do |
| 256 | if 'wcs' in fxn_dict2: |
| 257 | return |
| 258 | |
| 259 | # Check for pointer calls |
| 260 | if fxn_dict2['has_ptr_call']: |
| 261 | fxn_dict2['wcs'] = 'unbounded' |
| 262 | return |
| 263 | |
| 264 | # Check for recursion |
| 265 | if fxn_dict2 in parents: |
| 266 | fxn_dict2['wcs'] = 'unbounded' |
| 267 | return |
| 268 | |
| 269 | # Calculate WCS |
| 270 | call_max = 0 |
| 271 | for call_dict in fxn_dict2['r_calls']: |
| 272 | |
| 273 | # Calculate the WCS for the called function |
| 274 | parents.append(fxn_dict2) |
| 275 | calc_wcs(call_dict, call_graph1, parents) |
| 276 | parents.pop() |
| 277 | |
| 278 | # If the called function is unbounded, so is this function |
| 279 | if call_dict['wcs'] == 'unbounded': |
| 280 | fxn_dict2['wcs'] = 'unbounded' |
| 281 | return |
| 282 | |
| 283 | # Keep track of the call with the largest stack use |
| 284 | call_max = max(call_max, call_dict['wcs']) |
| 285 | |
| 286 | # Propagate Unresolved Calls |
| 287 | for unresolved_call in call_dict['unresolved_calls']: |
| 288 | fxn_dict2['unresolved_calls'].add(unresolved_call) |
| 289 | |
| 290 | fxn_dict2['wcs'] = call_max + fxn_dict2['local_stack'] |
| 291 | |
| 292 | # Loop through every global and local function |
| 293 | # and resolve each call, save results in r_calls |
| 294 | for fxn_dict in call_graph['globals'].values(): |
| 295 | calc_wcs(fxn_dict, call_graph, []) |
| 296 | |
| 297 | for l_dict in call_graph['locals'].values(): |
| 298 | for fxn_dict in l_dict.values(): |
| 299 | calc_wcs(fxn_dict, call_graph, []) |
| 300 | |
| 301 | |
| 302 | def print_all_fxns(call_graph): |