seafoam 0.8 → 0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/bin/bgv2isabelle +1 -5
- data/bin/bgv2json +1 -5
- data/bin/cfg2asm +1 -5
- data/bin/seafoam +1 -5
- data/lib/seafoam/commands.rb +48 -31
- data/lib/seafoam/graal/pi.rb +18 -0
- data/lib/seafoam/graph.rb +9 -1
- data/lib/seafoam/graphviz_writer.rb +3 -0
- data/lib/seafoam/json_writer.rb +1 -3
- data/lib/seafoam/{annotators → passes}/fallback.rb +4 -4
- data/lib/seafoam/{annotators → passes}/graal.rb +43 -13
- data/lib/seafoam/passes/truffle.rb +58 -0
- data/lib/seafoam/passes.rb +61 -0
- data/lib/seafoam/version.rb +1 -1
- data/lib/seafoam.rb +5 -4
- metadata +23 -60
- data/.github/probots.yml +0 -2
- data/.github/workflows/workflows.yml +0 -40
- data/.gitignore +0 -6
- data/.rubocop.yml +0 -37
- data/.ruby-version +0 -1
- data/.seafoam/config +0 -1
- data/CODE_OF_CONDUCT.md +0 -128
- data/CONTRIBUTING.md +0 -5
- data/Gemfile +0 -2
- data/Gemfile.lock +0 -59
- data/LICENSE.md +0 -7
- data/README.md +0 -378
- data/demos/box-unbox-stats +0 -65
- data/docs/annotators.md +0 -43
- data/docs/bgv.md +0 -294
- data/docs/getting-graphs.md +0 -63
- data/docs/images/igv.png +0 -0
- data/docs/images/seafoam.png +0 -0
- data/docs/images/spotlight-igv.png +0 -0
- data/docs/images/spotlight-seafoam.png +0 -0
- data/docs/json.md +0 -35
- data/examples/Fib.java +0 -24
- data/examples/MatMult.java +0 -39
- data/examples/fib-java.bgv.gz +0 -0
- data/examples/fib.js +0 -15
- data/examples/fib.rb +0 -15
- data/examples/identity.rb +0 -13
- data/examples/java/Irreducible.class +0 -0
- data/examples/java/Irreducible.j +0 -35
- data/examples/java/IrreducibleDecompiled.java +0 -21
- data/examples/java/JavaExamples.java +0 -418
- data/examples/matmult.rb +0 -29
- data/examples/overflow.rb +0 -13
- data/examples/ruby/clamps.rb +0 -20
- data/examples/ruby/graal.patch +0 -15
- data/examples/ruby/ruby_examples.rb +0 -278
- data/lib/seafoam/annotators.rb +0 -54
- data/lib/seafoam/config.rb +0 -34
- data/seafoam.gemspec +0 -22
- data/spec/seafoam/annotators/fallback_spec.rb +0 -69
- data/spec/seafoam/annotators/graal_spec.rb +0 -96
- data/spec/seafoam/annotators_spec.rb +0 -61
- data/spec/seafoam/bgv/bgv_parser_spec.rb +0 -167
- data/spec/seafoam/binary/io_binary_reader_spec.rb +0 -176
- data/spec/seafoam/cfg/cfg_parser_spec.rb +0 -21
- data/spec/seafoam/cfg/disassembler_spec.rb +0 -32
- data/spec/seafoam/command_spec.rb +0 -314
- data/spec/seafoam/graph_spec.rb +0 -172
- data/spec/seafoam/graphviz_writer_spec.rb +0 -63
- data/spec/seafoam/json_writer_spec.rb +0 -14
- data/spec/seafoam/spec_helpers.rb +0 -34
- data/spec/seafoam/spotlight_spec.rb +0 -38
- data/tools/render-all +0 -36
@@ -1,278 +0,0 @@
|
|
1
|
-
# truffleruby_primitives: true
|
2
|
-
|
3
|
-
# We're using Graal with graal.patch, to disable some inlining.
|
4
|
-
|
5
|
-
# % ruby --jvm --experimental-options --engine.OSR=false --engine.MultiTier=false --engine.TraceCompilation --vm.Dgraal.Dump=Truffle:1 ruby_examples.rb
|
6
|
-
|
7
|
-
RANDOM = Random.new
|
8
|
-
EXCEPTION = Exception.new
|
9
|
-
|
10
|
-
def example_local_variables(x, y)
|
11
|
-
a = x + y
|
12
|
-
a * 2 + a
|
13
|
-
end
|
14
|
-
|
15
|
-
def example_local_variables_state(x, y)
|
16
|
-
a = x + y
|
17
|
-
opaque_call
|
18
|
-
a * 2 + a
|
19
|
-
end
|
20
|
-
|
21
|
-
def example_arith_operator(x, y)
|
22
|
-
x + y
|
23
|
-
end
|
24
|
-
|
25
|
-
def example_compare_operator(x, y)
|
26
|
-
x <= y
|
27
|
-
end
|
28
|
-
|
29
|
-
def example_phi(condition, x)
|
30
|
-
if condition
|
31
|
-
a = opaque_call_a
|
32
|
-
else
|
33
|
-
a = opaque_call_b
|
34
|
-
end
|
35
|
-
a + x
|
36
|
-
end
|
37
|
-
|
38
|
-
def example_simple_call(object, x)
|
39
|
-
object.instance_call(x)
|
40
|
-
end
|
41
|
-
|
42
|
-
def example_stamp(x)
|
43
|
-
x & 0x1234
|
44
|
-
end
|
45
|
-
|
46
|
-
def example_full_escape(x)
|
47
|
-
a = [x]
|
48
|
-
Primitive.blackhole a
|
49
|
-
a[0]
|
50
|
-
end
|
51
|
-
|
52
|
-
def example_no_escape(x)
|
53
|
-
a = [x]
|
54
|
-
a[0]
|
55
|
-
end
|
56
|
-
|
57
|
-
def example_partial_escape(condition, x)
|
58
|
-
a = [x]
|
59
|
-
if condition
|
60
|
-
Primitive.blackhole a
|
61
|
-
a[0]
|
62
|
-
else
|
63
|
-
a[0]
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def example_if(condition, x, y)
|
68
|
-
if condition
|
69
|
-
Primitive.blackhole x
|
70
|
-
a = x
|
71
|
-
else
|
72
|
-
Primitive.blackhole y
|
73
|
-
a = y
|
74
|
-
end
|
75
|
-
a
|
76
|
-
end
|
77
|
-
|
78
|
-
def example_if_never_taken(condition, x, y)
|
79
|
-
if condition
|
80
|
-
Primitive.blackhole x
|
81
|
-
a = x
|
82
|
-
else
|
83
|
-
Primitive.blackhole y
|
84
|
-
a = y
|
85
|
-
end
|
86
|
-
a
|
87
|
-
end
|
88
|
-
|
89
|
-
def example_int_switch(value, x, y, z)
|
90
|
-
case value
|
91
|
-
when 0
|
92
|
-
Primitive.blackhole x
|
93
|
-
a = x
|
94
|
-
when 1
|
95
|
-
Primitive.blackhole y
|
96
|
-
a = y
|
97
|
-
else
|
98
|
-
Primitive.blackhole z
|
99
|
-
a = z
|
100
|
-
end
|
101
|
-
a
|
102
|
-
end
|
103
|
-
|
104
|
-
def example_string_switch(value, x, y, z)
|
105
|
-
case value
|
106
|
-
when 'foo'
|
107
|
-
Primitive.blackhole x
|
108
|
-
a = x
|
109
|
-
when 'bar'
|
110
|
-
Primitive.blackhole y
|
111
|
-
a = y
|
112
|
-
else
|
113
|
-
Primitive.blackhole z
|
114
|
-
a = z
|
115
|
-
end
|
116
|
-
a
|
117
|
-
end
|
118
|
-
|
119
|
-
def example_while(count)
|
120
|
-
a = count
|
121
|
-
while a > 0
|
122
|
-
Primitive.blackhole a
|
123
|
-
a -= 1
|
124
|
-
end
|
125
|
-
count
|
126
|
-
end
|
127
|
-
|
128
|
-
def example_for(count)
|
129
|
-
count.times do |a|
|
130
|
-
Primitive.blackhole a
|
131
|
-
end
|
132
|
-
end
|
133
|
-
|
134
|
-
def example_nested_while(count)
|
135
|
-
a = count
|
136
|
-
while (a > 0)
|
137
|
-
y = count
|
138
|
-
while (y > 0)
|
139
|
-
Primitive.blackhole a
|
140
|
-
y -= 1
|
141
|
-
end
|
142
|
-
a -= 1
|
143
|
-
end
|
144
|
-
count
|
145
|
-
end
|
146
|
-
|
147
|
-
def example_while_break(count)
|
148
|
-
a = count
|
149
|
-
while a > 0
|
150
|
-
if a == 4
|
151
|
-
break
|
152
|
-
end
|
153
|
-
Primitive.blackhole a
|
154
|
-
a -= 1
|
155
|
-
end
|
156
|
-
count
|
157
|
-
end
|
158
|
-
|
159
|
-
def example_raise
|
160
|
-
raise EXCEPTION
|
161
|
-
end
|
162
|
-
|
163
|
-
def example_rescue
|
164
|
-
begin
|
165
|
-
opaque_raise
|
166
|
-
rescue Exception => e
|
167
|
-
Primitive.blackhole e
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
def example_raise_rescue
|
172
|
-
begin
|
173
|
-
raise EXCEPTION
|
174
|
-
rescue Exception => e
|
175
|
-
Primitive.blackhole e
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
def example_object_allocation(x)
|
180
|
-
ExampleObject.new(x)
|
181
|
-
end
|
182
|
-
|
183
|
-
def example_array_allocation(x, y)
|
184
|
-
[x, y]
|
185
|
-
end
|
186
|
-
|
187
|
-
def example_field_write(object, x)
|
188
|
-
object.x = x
|
189
|
-
end
|
190
|
-
|
191
|
-
def example_field_read(object)
|
192
|
-
object.x
|
193
|
-
end
|
194
|
-
|
195
|
-
def example_array_write(array, n, x)
|
196
|
-
array[n] = x
|
197
|
-
end
|
198
|
-
|
199
|
-
def example_array_read(array, n)
|
200
|
-
array[n]
|
201
|
-
end
|
202
|
-
|
203
|
-
def example_instance_of(x)
|
204
|
-
x.is_a?(ExampleObject)
|
205
|
-
end
|
206
|
-
|
207
|
-
# no inline
|
208
|
-
def opaque_call
|
209
|
-
RANDOM.rand(1000)
|
210
|
-
end
|
211
|
-
|
212
|
-
# no inline
|
213
|
-
def opaque_call_a
|
214
|
-
opaque_call
|
215
|
-
end
|
216
|
-
|
217
|
-
# no inline
|
218
|
-
def opaque_call_b
|
219
|
-
opaque_call
|
220
|
-
end
|
221
|
-
|
222
|
-
# no inline
|
223
|
-
def opaque_raise
|
224
|
-
raise EXCEPTION
|
225
|
-
end
|
226
|
-
|
227
|
-
# no inline
|
228
|
-
def static_call(x)
|
229
|
-
x
|
230
|
-
end
|
231
|
-
|
232
|
-
class ExampleObject
|
233
|
-
attr_accessor :x
|
234
|
-
|
235
|
-
def initialize(x)
|
236
|
-
@x = x
|
237
|
-
end
|
238
|
-
|
239
|
-
# no inline
|
240
|
-
def instance_call(y)
|
241
|
-
@x + y
|
242
|
-
end
|
243
|
-
end
|
244
|
-
|
245
|
-
loop do
|
246
|
-
example_local_variables RANDOM.rand(1000), RANDOM.rand(1000)
|
247
|
-
example_local_variables_state RANDOM.rand(1000), RANDOM.rand(1000)
|
248
|
-
example_arith_operator RANDOM.rand(1000), RANDOM.rand(1000)
|
249
|
-
example_compare_operator RANDOM.rand(1000), RANDOM.rand(1000)
|
250
|
-
example_phi [true, false].sample, RANDOM.rand(1000)
|
251
|
-
example_simple_call ExampleObject.new(RANDOM.rand(1000)), RANDOM.rand(1000)
|
252
|
-
example_stamp RANDOM.rand(1000)
|
253
|
-
example_full_escape RANDOM.rand(1000)
|
254
|
-
example_no_escape RANDOM.rand(1000)
|
255
|
-
example_partial_escape [true, false].sample, RANDOM.rand(1000)
|
256
|
-
example_if [true, false].sample, RANDOM.rand(1000), RANDOM.rand(1000)
|
257
|
-
example_if_never_taken false, RANDOM.rand(1000), RANDOM.rand(1000)
|
258
|
-
example_int_switch RANDOM.rand(3), RANDOM.rand(1000), RANDOM.rand(1000), RANDOM.rand(1000)
|
259
|
-
example_string_switch ['foo', 'bar', 'baz'].sample, RANDOM.rand(1000), RANDOM.rand(1000), RANDOM.rand(1000)
|
260
|
-
example_while RANDOM.rand(10)
|
261
|
-
example_for RANDOM.rand(10)
|
262
|
-
example_nested_while RANDOM.rand(10)
|
263
|
-
example_while_break RANDOM.rand(10)
|
264
|
-
begin
|
265
|
-
example_raise
|
266
|
-
rescue Exception => e
|
267
|
-
#
|
268
|
-
end
|
269
|
-
example_rescue
|
270
|
-
example_raise_rescue
|
271
|
-
example_object_allocation RANDOM.rand(1000)
|
272
|
-
example_array_allocation RANDOM.rand(1000), RANDOM.rand(1000)
|
273
|
-
example_field_write ExampleObject.new(RANDOM.rand(1000)), RANDOM.rand(1000)
|
274
|
-
example_field_read ExampleObject.new(RANDOM.rand(1000))
|
275
|
-
example_array_write [RANDOM.rand(1000), RANDOM.rand(1000), RANDOM.rand(1000)], RANDOM.rand(3), RANDOM.rand(1000)
|
276
|
-
example_array_read [RANDOM.rand(1000), RANDOM.rand(1000), RANDOM.rand(1000)], RANDOM.rand(3)
|
277
|
-
example_instance_of [Object.new, ExampleObject.new(0)].sample
|
278
|
-
end
|
data/lib/seafoam/annotators.rb
DELETED
@@ -1,54 +0,0 @@
|
|
1
|
-
module Seafoam
|
2
|
-
# Annotators are routines to read the graph and apply properties which tools,
|
3
|
-
# such as the render command, can use to show more understandable output.
|
4
|
-
module Annotators
|
5
|
-
# Apply all applicable annotators to a graph.
|
6
|
-
def self.apply(graph, options = {})
|
7
|
-
annotators.each do |annotator|
|
8
|
-
next unless annotator.applies?(graph)
|
9
|
-
|
10
|
-
# Record for information that the annotator annotated this graph.
|
11
|
-
annotated_by = graph.props[:annotated_by] ||= []
|
12
|
-
annotated_by.push annotator
|
13
|
-
|
14
|
-
# Run the annotator.
|
15
|
-
instance = annotator.new(options)
|
16
|
-
instance.annotate graph
|
17
|
-
end
|
18
|
-
end
|
19
|
-
|
20
|
-
# Get a list of all annotators in the system.
|
21
|
-
def self.annotators
|
22
|
-
# Get all subclasses of Annotator.
|
23
|
-
annotators = Annotator::SUBCLASSES.dup
|
24
|
-
|
25
|
-
# We want the FallbackAnnotator to run last.
|
26
|
-
annotators.delete FallbackAnnotator
|
27
|
-
annotators.push FallbackAnnotator
|
28
|
-
|
29
|
-
annotators
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
# The base class for all annotators. You must subclass this to be recognized
|
34
|
-
# as an annotator.
|
35
|
-
class Annotator
|
36
|
-
SUBCLASSES = []
|
37
|
-
|
38
|
-
def initialize(options = {})
|
39
|
-
@options = options
|
40
|
-
end
|
41
|
-
|
42
|
-
def applies?(_graph)
|
43
|
-
raise NotImplementedError
|
44
|
-
end
|
45
|
-
|
46
|
-
def annotate(_graph)
|
47
|
-
raise NotImplementedError
|
48
|
-
end
|
49
|
-
|
50
|
-
def self.inherited(annotator)
|
51
|
-
SUBCLASSES.push annotator
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
data/lib/seafoam/config.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
module Seafoam
|
2
|
-
# Finds and loads configuration.
|
3
|
-
class Config
|
4
|
-
def initialize
|
5
|
-
@dot_dir = find_dot_dir
|
6
|
-
end
|
7
|
-
|
8
|
-
# Load the configuration.
|
9
|
-
def load_config
|
10
|
-
config_file = File.expand_path('config', @dot_dir)
|
11
|
-
if File.exist?(config_file)
|
12
|
-
puts "loading config #{config_file}" if $DEBUG
|
13
|
-
load config_file
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
# Walk up the directory chain from the current directory to root, looking
|
20
|
-
# for .seafoam.
|
21
|
-
def find_dot_dir
|
22
|
-
dir = Dir.getwd
|
23
|
-
loop do
|
24
|
-
dot_dir = File.expand_path('.seafoam', dir)
|
25
|
-
return dot_dir if Dir.exist?(dot_dir)
|
26
|
-
|
27
|
-
new_dir = File.expand_path('..', dir)
|
28
|
-
break if new_dir == dir
|
29
|
-
|
30
|
-
dir = new_dir
|
31
|
-
end
|
32
|
-
end
|
33
|
-
end
|
34
|
-
end
|
data/seafoam.gemspec
DELETED
@@ -1,22 +0,0 @@
|
|
1
|
-
require_relative 'lib/seafoam/version'
|
2
|
-
|
3
|
-
Gem::Specification.new do |spec|
|
4
|
-
spec.name = 'seafoam'
|
5
|
-
spec.version = Seafoam::VERSION
|
6
|
-
spec.summary = 'A tool for working with compiler graphs'
|
7
|
-
spec.authors = ['Chris Seaton']
|
8
|
-
spec.homepage = 'https://github.com/Shopify/seafoam'
|
9
|
-
spec.license = 'MIT'
|
10
|
-
|
11
|
-
spec.files = `git ls-files`.split("\n").reject { |f| f.end_with?('.bgv') || f.end_with?('.cfg') }
|
12
|
-
spec.bindir = 'bin'
|
13
|
-
spec.executables = %w[seafoam bgv2json bgv2isabelle cfg2asm]
|
14
|
-
|
15
|
-
spec.required_ruby_version = '>= 2.5.8'
|
16
|
-
|
17
|
-
spec.add_dependency 'crabstone', '~> 4.0'
|
18
|
-
|
19
|
-
spec.add_development_dependency 'benchmark-ips', '~> 2.7'
|
20
|
-
spec.add_development_dependency 'rspec', '~> 3.8'
|
21
|
-
spec.add_development_dependency 'rubocop', '~> 0.74'
|
22
|
-
end
|
@@ -1,69 +0,0 @@
|
|
1
|
-
require 'seafoam'
|
2
|
-
|
3
|
-
require 'rspec'
|
4
|
-
|
5
|
-
describe Seafoam::Annotators::FallbackAnnotator do
|
6
|
-
it 'always applies' do
|
7
|
-
expect(Seafoam::Annotators::FallbackAnnotator.applies?(Seafoam::Graph.new)).to be true
|
8
|
-
end
|
9
|
-
|
10
|
-
it 'adds a label annotation when there is a label property' do
|
11
|
-
graph = Seafoam::Graph.new
|
12
|
-
node = graph.create_node(0, 'label' => 'foo')
|
13
|
-
annotator = Seafoam::Annotators::FallbackAnnotator.new
|
14
|
-
annotator.annotate graph
|
15
|
-
expect(node.props[:label]).to eq 'foo'
|
16
|
-
end
|
17
|
-
|
18
|
-
it 'does not overwrite an existing label annotation' do
|
19
|
-
graph = Seafoam::Graph.new
|
20
|
-
node = graph.create_node(0, 'label' => 'foo', :label => 'bar')
|
21
|
-
annotator = Seafoam::Annotators::FallbackAnnotator.new
|
22
|
-
annotator.annotate graph
|
23
|
-
expect(node.props[:label]).to eq 'bar'
|
24
|
-
end
|
25
|
-
|
26
|
-
it 'adds nothing when there is no label property' do
|
27
|
-
graph = Seafoam::Graph.new
|
28
|
-
node = graph.create_node(0, 'xlabel' => 'foo')
|
29
|
-
annotator = Seafoam::Annotators::FallbackAnnotator.new
|
30
|
-
annotator.annotate graph
|
31
|
-
expect(node.props[:label]).to be nil
|
32
|
-
end
|
33
|
-
|
34
|
-
it 'sets node kind to other when there is no kind' do
|
35
|
-
graph = Seafoam::Graph.new
|
36
|
-
node = graph.create_node(0)
|
37
|
-
annotator = Seafoam::Annotators::FallbackAnnotator.new
|
38
|
-
annotator.annotate graph
|
39
|
-
expect(node.props[:kind]).to eq 'other'
|
40
|
-
end
|
41
|
-
|
42
|
-
it 'does not overwrite an existing node kind annotations' do
|
43
|
-
graph = Seafoam::Graph.new
|
44
|
-
node = graph.create_node(0, kind: 'control')
|
45
|
-
annotator = Seafoam::Annotators::FallbackAnnotator.new
|
46
|
-
annotator.annotate graph
|
47
|
-
expect(node.props[:kind]).to eq 'control'
|
48
|
-
end
|
49
|
-
|
50
|
-
it 'sets edge kind to other when there is no kind' do
|
51
|
-
graph = Seafoam::Graph.new
|
52
|
-
node_a = graph.create_node(0)
|
53
|
-
node_b = graph.create_node(1)
|
54
|
-
edge = graph.create_edge(node_a, node_b)
|
55
|
-
annotator = Seafoam::Annotators::FallbackAnnotator.new
|
56
|
-
annotator.annotate graph
|
57
|
-
expect(edge.props[:kind]).to eq 'other'
|
58
|
-
end
|
59
|
-
|
60
|
-
it 'does not overwrite an existing edge kind annotations' do
|
61
|
-
graph = Seafoam::Graph.new
|
62
|
-
node_a = graph.create_node(0)
|
63
|
-
node_b = graph.create_node(1)
|
64
|
-
edge = graph.create_edge(node_a, node_b, kind: 'control')
|
65
|
-
annotator = Seafoam::Annotators::FallbackAnnotator.new
|
66
|
-
annotator.annotate graph
|
67
|
-
expect(edge.props[:kind]).to eq 'control'
|
68
|
-
end
|
69
|
-
end
|
@@ -1,96 +0,0 @@
|
|
1
|
-
require 'seafoam'
|
2
|
-
|
3
|
-
require 'rspec'
|
4
|
-
|
5
|
-
require_relative '../spec_helpers'
|
6
|
-
|
7
|
-
describe Seafoam::Annotators::GraalAnnotator do
|
8
|
-
it 'applies to Graal graphs' do
|
9
|
-
expect(Seafoam::Annotators::GraalAnnotator.applies?(Seafoam::SpecHelpers.example_graph('fib-java', 0))).to be true
|
10
|
-
end
|
11
|
-
|
12
|
-
it 'does not apply to Truffle trees' do
|
13
|
-
expect(Seafoam::Annotators::GraalAnnotator.applies?(Seafoam::SpecHelpers.example_graph('fib-js', 0))).to be false
|
14
|
-
end
|
15
|
-
|
16
|
-
it 'applies to Truffle graphs' do
|
17
|
-
expect(Seafoam::Annotators::GraalAnnotator.applies?(Seafoam::SpecHelpers.example_graph('fib-js', 2))).to be true
|
18
|
-
end
|
19
|
-
|
20
|
-
describe 'when run' do
|
21
|
-
describe 'without options' do
|
22
|
-
before :all do
|
23
|
-
@graph = Seafoam::SpecHelpers.example_graph('matmult-ruby', 8)
|
24
|
-
annotator = Seafoam::Annotators::GraalAnnotator.new({})
|
25
|
-
annotator.annotate @graph
|
26
|
-
end
|
27
|
-
|
28
|
-
it 'annotates all nodes with a kind' do
|
29
|
-
expect(@graph.nodes.values.any? { |n| n.props[:kind].nil? }).to be_falsey
|
30
|
-
end
|
31
|
-
|
32
|
-
it 'annotates all nodes with a label' do
|
33
|
-
expect(@graph.nodes.values.any? { |n| n.props[:label].nil? }).to be_falsey
|
34
|
-
end
|
35
|
-
|
36
|
-
it 'annotates all edges with a kind' do
|
37
|
-
expect(@graph.edges.any? { |e| e.props[:kind].nil? }).to be_falsey
|
38
|
-
end
|
39
|
-
|
40
|
-
it 'annotates not negated GuardNodes with "Guard, else ..."' do
|
41
|
-
expect(@graph.nodes[7101].props['negated']).to be false
|
42
|
-
expect(@graph.nodes[7101].props[:label]).to start_with 'Guard, else'
|
43
|
-
end
|
44
|
-
|
45
|
-
it 'annotates negated GuardNodes with "Guard not, else ..."' do
|
46
|
-
expect(@graph.nodes[7102].props['negated']).to be true
|
47
|
-
expect(@graph.nodes[7102].props[:label]).to start_with 'Guard not, else'
|
48
|
-
end
|
49
|
-
end
|
50
|
-
|
51
|
-
describe 'with :hide_frame_state' do
|
52
|
-
before :all do
|
53
|
-
@graph = Seafoam::SpecHelpers.example_graph('matmult-ruby', 2)
|
54
|
-
annotator = Seafoam::Annotators::GraalAnnotator.new(hide_frame_state: true)
|
55
|
-
annotator.annotate @graph
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'sets the hidden property on all frame state nodes' do
|
59
|
-
frame_state_nodes = @graph.nodes.values.select do |n|
|
60
|
-
Seafoam::Annotators::GraalAnnotator::FRAME_STATE_NODES.include?(n.props.dig(:node_class, :node_class))
|
61
|
-
end
|
62
|
-
expect(frame_state_nodes.all? { |n| n.props[:hidden] }).to be_truthy
|
63
|
-
end
|
64
|
-
end
|
65
|
-
|
66
|
-
describe 'with :hide_floating' do
|
67
|
-
before :all do
|
68
|
-
@graph = Seafoam::SpecHelpers.example_graph('matmult-ruby', 2)
|
69
|
-
annotator = Seafoam::Annotators::GraalAnnotator.new(hide_floating: true)
|
70
|
-
annotator.annotate @graph
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'sets the hidden property on all nodes without a control edge' do
|
74
|
-
nodes_without_control_edge = @graph.nodes.values.select do |n|
|
75
|
-
n.edges.none? { |e| e.props[:kind] == 'control' }
|
76
|
-
end
|
77
|
-
expect(nodes_without_control_edge.all? { |n| n.props[:hidden] }).to be_truthy
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
81
|
-
describe 'with :reduce_edges' do
|
82
|
-
before :all do
|
83
|
-
@graph = Seafoam::SpecHelpers.example_graph('matmult-ruby', 2)
|
84
|
-
annotator = Seafoam::Annotators::GraalAnnotator.new(reduce_edges: true)
|
85
|
-
annotator.annotate @graph
|
86
|
-
end
|
87
|
-
|
88
|
-
it 'inlines all constant nodes' do
|
89
|
-
constant_nodes = @graph.nodes.values.select do |n|
|
90
|
-
Seafoam::Annotators::GraalAnnotator::SIMPLE_INPUTS.include?(n.props.dig(:node_class, :node_class))
|
91
|
-
end
|
92
|
-
expect(constant_nodes.all? { |n| n.props[:inlined] }).to be_truthy
|
93
|
-
end
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
@@ -1,61 +0,0 @@
|
|
1
|
-
require 'seafoam'
|
2
|
-
|
3
|
-
require 'rspec'
|
4
|
-
|
5
|
-
describe Seafoam::Annotators do
|
6
|
-
describe '#annotate' do
|
7
|
-
it 'asks annotators if they apply' do
|
8
|
-
check_applied = false
|
9
|
-
|
10
|
-
Class.new(Seafoam::Annotator) do
|
11
|
-
singleton_class.define_method(:applies?) do |_graph|
|
12
|
-
check_applied = true
|
13
|
-
false
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
Seafoam::Annotators.apply(Seafoam::Graph.new)
|
18
|
-
expect(check_applied).to be true
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'runs annotators that apply' do
|
22
|
-
check_annotated = false
|
23
|
-
|
24
|
-
Class.new(Seafoam::Annotator) do
|
25
|
-
singleton_class.define_method(:applies?) do |_graph|
|
26
|
-
true
|
27
|
-
end
|
28
|
-
|
29
|
-
define_method(:annotate) do |_graph|
|
30
|
-
check_annotated = true
|
31
|
-
end
|
32
|
-
end
|
33
|
-
|
34
|
-
Seafoam::Annotators.apply(Seafoam::Graph.new)
|
35
|
-
expect(check_annotated).to be true
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
describe '#annotators' do
|
40
|
-
it 'returns the standard annotators' do
|
41
|
-
annotators = Seafoam::Annotators.annotators
|
42
|
-
expect(annotators).to include Seafoam::Annotators::FallbackAnnotator
|
43
|
-
expect(annotators).to include Seafoam::Annotators::GraalAnnotator
|
44
|
-
end
|
45
|
-
|
46
|
-
it 'returns custom annotators' do
|
47
|
-
custom_annotator = Class.new(Seafoam::Annotator) do
|
48
|
-
def self.applies?(_graph)
|
49
|
-
false
|
50
|
-
end
|
51
|
-
end
|
52
|
-
annotators = Seafoam::Annotators.annotators
|
53
|
-
expect(annotators).to include custom_annotator
|
54
|
-
end
|
55
|
-
|
56
|
-
it 'returns the FallbackAnnotator annotator last' do
|
57
|
-
annotators = Seafoam::Annotators.annotators
|
58
|
-
expect(annotators.last).to eq Seafoam::Annotators::FallbackAnnotator
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|