forked from actor-framework/actor-framework
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdemystify.py
More file actions
executable file
·118 lines (103 loc) · 3 KB
/
Copy pathdemystify.py
File metadata and controls
executable file
·118 lines (103 loc) · 3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#!/usr/bin/env python
# This script demystifies C++ compiler output for CAF by
# replacing cryptic `typed_mpi<...>` templates with
# `replies_to<...>::with<...>` and `atom_constant<...>`
# with human-readable representation of the actual atom.
import sys
# decodes 6bit characters to ASCII
DECODING_TABLE = ' 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz'
# CAF type strings
ATOM_CONSTANT_SUFFIX = "caf::atom_constant<"
# `pos` points to first character after '<':
# template_name<...>
# ^
# and returns the position of the closing '>'
def end_of_template(x, pos):
open_templates = 1
while open_templates > 0:
if line[pos] == '<':
open_templates += 1
elif line[pos] == '>':
open_templates -= 1
pos += 1
# exclude final '>'
return pos - 1
def next_element(x, pos, last):
# scan for ',' that isn't inside <...>
while pos < last and x[pos] != ',':
if x[pos] == '<':
pos = end_of_template(x, pos + 1)
else:
pos += 1
return pos
def atom_read(x):
result = ""
read_chars = ((x & 0xF000000000000000) >> 60) == 0xF
mask = 0x0FC0000000000000
bitshift = 54
while bitshift >= 0:
if read_chars:
result += DECODING_TABLE[(x & mask) >> bitshift]
elif ((x & mask) >> bitshift) == 0xF:
read_chars = True
bitshift -= 6
mask = mask >> 6
return result
def decompose_type_list(x, first, last):
res = []
i = first
n = next_element(x, first, last)
while i != last:
res.append(x[i:n])
# skip following ','
i = min(n + 2, last)
n = next_element(x, i, last)
return res
def stringify(x):
if x.startswith(ATOM_CONSTANT_SUFFIX):
begin = len(ATOM_CONSTANT_SUFFIX)
end = len(x) - 1
res = "'"
res += atom_read(int(x[begin:end]))
res += "'"
return res
return x
def stringify_list(xs):
res = ""
for index in range(len(xs)):
if index > 0:
res += ", "
res += stringify(xs[index].strip(' '))
return res
def decompose_typed_actor(x, first, last):
needle = "caf::type_list<"
# first type list -> input types
j = x.find(needle, first) + len(needle)
k = end_of_template(x, j)
inputs = decompose_type_list(x, j, k)
# second type list -> outputs
j = x.find(needle, k) + len(needle)
k = end_of_template(x, j)
outputs = decompose_type_list(x, j, k)
# replace all 'caf::atom_constant<...>' entries in inputs
res = "replies_to<"
res += stringify_list(inputs)
res += ">::with<"
res += stringify_list(outputs)
res += ">"
return res
for line in sys.stdin:
# replace "std::__1" with "std::" (Clang libc++)
line = line.replace("std::__1", "std::")
needle = "caf::typed_mpi<"
idx = line.find(needle)
while idx != -1:
# find end of typed_actor<...>
first = idx + len(needle)
last = end_of_template(line, first)
updated = decompose_typed_actor(line, first, last)
prefix = line[:idx]
suffix = line[last:]
line = prefix + updated + suffix
idx = line.find(needle, idx + len(updated))
sys.stdout.write(line.replace("caf::", ""))