Skip to content

Commit 251cd2c

Browse files
committed
First pass at a script to generate random type definitions.
This will be useful to generate input for fuzzing runtime layout, ABI compatibility, layout algorithms, etc.
1 parent 9af6cd8 commit 251cd2c

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed

utils/type-layout-fuzzer.py

+97
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
#!/usr/bin/env python
2+
3+
# This script outputs a Swift source with randomly-generated type definitions,
4+
# which can be used for ABI or layout algorithm fuzzing.
5+
6+
# TODO: generate types with generics, existentials, compositions
7+
# TODO: prevent cycles in inline storage
8+
9+
import collections
10+
import random
11+
12+
maxDepth = 5
13+
maxMembers = 5
14+
typesToDefine = collections.deque([0])
15+
nextName = 1
16+
random.seed()
17+
18+
19+
def randomTypeList(depth):
20+
count = random.randint(0, maxMembers)
21+
result = "("
22+
for i in xrange(count):
23+
if i > 0:
24+
result += ", "
25+
result += randomTypeReference(depth + 1)
26+
result += ")"
27+
return result
28+
29+
30+
def randomTypeReference(depth):
31+
def nominal():
32+
global nextName
33+
global typesToDefine
34+
which = random.randint(0,
35+
nextName if depth < maxDepth else nextName - 1)
36+
if which == nextName:
37+
typesToDefine.append(which)
38+
nextName += 1
39+
return "T" + str(which)
40+
41+
def tuple():
42+
return randomTypeList(depth + 1)
43+
44+
def metatype():
45+
return "(" + randomTypeReference(depth + 1) + ").Type"
46+
47+
def leaf():
48+
leaves = ["Int", "String", "Int8", "Int16", "Int32", "Int64"]
49+
return random.choice(leaves)
50+
51+
if depth < maxDepth:
52+
kinds = [nominal, tuple, metatype, leaf, leaf, leaf, leaf, leaf]
53+
else:
54+
kinds = [leaf]
55+
return random.choice(kinds)()
56+
57+
58+
def defineRandomProduct(kind, name, depth):
59+
print(kind + " " + name + " {")
60+
# Suppress errors about missing initializers
61+
print(" init() { fatalError() }")
62+
63+
numMembers = random.randint(0, maxMembers)
64+
for i in xrange(numMembers):
65+
print(" var x" + str(i) + ": " + randomTypeReference(depth + 1))
66+
67+
print("}")
68+
69+
70+
def defineRandomEnum(name, depth):
71+
# TODO: indirect cases
72+
print("enum " + name + " {")
73+
74+
numCases = random.randint(0, maxMembers)
75+
for i in xrange(numCases):
76+
print(" case x" + str(i) + randomTypeList(depth + 1))
77+
78+
print("}")
79+
80+
81+
def defineRandomType(name, depth):
82+
def struct():
83+
defineRandomProduct("struct", name, depth)
84+
85+
def clas():
86+
defineRandomProduct("class", name, depth)
87+
88+
def enum():
89+
defineRandomEnum(name, depth)
90+
91+
kinds = [struct, clas, enum]
92+
return random.choice(kinds)()
93+
94+
95+
while len(typesToDefine) > 0:
96+
ty = typesToDefine.popleft()
97+
defineRandomType("T" + str(ty), 0)

0 commit comments

Comments
 (0)