seafoam 0.13 → 0.14
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/bin/bgv2isabelle +3 -2
- data/bin/bgv2json +3 -2
- data/bin/seafoam +3 -2
- data/lib/seafoam/bgv/bgv_parser.rb +58 -50
- data/lib/seafoam/binary/io_binary_reader.rb +19 -17
- data/lib/seafoam/colors.rb +17 -11
- data/lib/seafoam/commands.rb +177 -153
- data/lib/seafoam/formatters/base.rb +2 -0
- data/lib/seafoam/formatters/formatters.rb +5 -3
- data/lib/seafoam/formatters/json.rb +8 -5
- data/lib/seafoam/formatters/text.rb +7 -4
- data/lib/seafoam/graal/graph_description.rb +9 -1
- data/lib/seafoam/graal/pi.rb +10 -6
- data/lib/seafoam/graal/source.rb +13 -9
- data/lib/seafoam/graph.rb +15 -9
- data/lib/seafoam/graphviz_writer.rb +129 -99
- data/lib/seafoam/isabelle_writer.rb +9 -7
- data/lib/seafoam/json_writer.rb +17 -13
- data/lib/seafoam/markdown_writer.rb +5 -3
- data/lib/seafoam/mermaid_writer.rb +36 -24
- data/lib/seafoam/passes/fallback.rb +10 -6
- data/lib/seafoam/passes/graal.rb +189 -161
- data/lib/seafoam/passes/truffle.rb +120 -22
- data/lib/seafoam/passes.rb +36 -29
- data/lib/seafoam/spotlight.rb +4 -2
- data/lib/seafoam/version.rb +3 -1
- data/lib/seafoam.rb +22 -20
- metadata +12 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 44f9af9b54052ddbfc03bc99833eb0af6e2e5f2bd0a5612a77ea10e3d30b3fca
|
4
|
+
data.tar.gz: 7d1613577c3e033c69149eb51845540b88adc0c05bda3327c59a41c700647181
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f35b3f93409e92be806e793817461900f66d7d1a8e91e6ae95fc52f66fa61955d7c48f0de1899ad15b35e88fa2b6b4cbb70fed976accb9f20ee7725f201828fe
|
7
|
+
data.tar.gz: 03d4b654e6f2001128aa711ccddb4cccf09aed480d65578e0e49edb3d59c2acb5b594e3ef4f32b972e9821862aa24b9daa12c4fb7f1cef838a46c43c2c3b4fa9
|
data/bin/bgv2isabelle
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
+
require "seafoam"
|
4
5
|
|
5
6
|
# This is the 'bgv2isabelle' command line entry point.
|
6
7
|
|
@@ -15,6 +16,6 @@ rescue StandardError => e
|
|
15
16
|
raise e
|
16
17
|
else
|
17
18
|
# Otherwise, just print the message.
|
18
|
-
warn
|
19
|
+
warn("seafoam: #{e.message}")
|
19
20
|
end
|
20
21
|
end
|
data/bin/bgv2json
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
+
require "seafoam"
|
4
5
|
|
5
6
|
# This is the 'bgv2json' command line entry point.
|
6
7
|
|
@@ -15,6 +16,6 @@ rescue StandardError => e
|
|
15
16
|
raise e
|
16
17
|
else
|
17
18
|
# Otherwise, just print the message.
|
18
|
-
warn
|
19
|
+
warn("seafoam: #{e.message}")
|
19
20
|
end
|
20
21
|
end
|
data/bin/seafoam
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
2
3
|
|
3
|
-
require
|
4
|
+
require "seafoam"
|
4
5
|
|
5
6
|
# This is the 'seafoam' command line entry point.
|
6
7
|
|
@@ -15,6 +16,6 @@ rescue StandardError => e
|
|
15
16
|
raise e
|
16
17
|
else
|
17
18
|
# Otherwise, just print the message.
|
18
|
-
warn
|
19
|
+
warn("seafoam: #{e.message}")
|
19
20
|
end
|
20
21
|
end
|
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "stringio"
|
4
|
+
require "zlib"
|
3
5
|
|
4
6
|
module Seafoam
|
5
7
|
module BGV
|
@@ -21,7 +23,7 @@ module Seafoam
|
|
21
23
|
|
22
24
|
# Read the file header and return the version.
|
23
25
|
def read_file_header(version_check: true)
|
24
|
-
raise EncodingError,
|
26
|
+
raise EncodingError, "does not appear to be a BGV file - missing header" unless @reader.read_bytes(4) == MAGIC
|
25
27
|
|
26
28
|
@major = @reader.read_sint8
|
27
29
|
@minor = @reader.read_sint8
|
@@ -90,7 +92,7 @@ module Seafoam
|
|
90
92
|
group: @group_stack.dup,
|
91
93
|
format: format,
|
92
94
|
args: args,
|
93
|
-
props: props
|
95
|
+
props: props,
|
94
96
|
}
|
95
97
|
end
|
96
98
|
|
@@ -115,15 +117,17 @@ module Seafoam
|
|
115
117
|
node = edge[:node]
|
116
118
|
props = edge[:edge]
|
117
119
|
inputs = edge[:inputs]
|
118
|
-
others = edge[:ids].reject(&:nil?).map
|
120
|
+
others = edge[:ids].reject(&:nil?).map do |id|
|
121
|
+
graph.nodes[id] || raise(EncodingError, "BGV edge with unknown node #{id}")
|
122
|
+
end
|
119
123
|
others.each_with_index do |other, index|
|
120
124
|
# We need to give each edge their own property as they're annotated separately.
|
121
125
|
props = props.dup
|
122
126
|
props[:index] = index
|
123
127
|
if inputs
|
124
|
-
graph.create_edge
|
128
|
+
graph.create_edge(other, node, props)
|
125
129
|
else
|
126
|
-
graph.create_edge
|
130
|
+
graph.create_edge(node, other, props)
|
127
131
|
end
|
128
132
|
end
|
129
133
|
end
|
@@ -134,7 +138,7 @@ module Seafoam
|
|
134
138
|
block_nodes = @reader.read_sint32.times.map { @reader.read_sint32 }
|
135
139
|
# Followers aren't used but could be.
|
136
140
|
@reader.read_sint32.times.map { @reader.read_sint32 }
|
137
|
-
graph.create_block
|
141
|
+
graph.create_block(block_id, block_nodes)
|
138
142
|
end
|
139
143
|
graph
|
140
144
|
end
|
@@ -147,8 +151,8 @@ module Seafoam
|
|
147
151
|
node_class = read_pool_object
|
148
152
|
skip_bool
|
149
153
|
skip_props
|
150
|
-
skip_edges
|
151
|
-
skip_edges
|
154
|
+
skip_edges(node_class, true)
|
155
|
+
skip_edges(node_class, false)
|
152
156
|
end
|
153
157
|
skip_blocks
|
154
158
|
end
|
@@ -200,9 +204,9 @@ module Seafoam
|
|
200
204
|
short_name: short_name,
|
201
205
|
method: method,
|
202
206
|
bci: bci,
|
203
|
-
props: props
|
207
|
+
props: props,
|
204
208
|
}
|
205
|
-
@group_stack.push
|
209
|
+
@group_stack.push(group)
|
206
210
|
end
|
207
211
|
|
208
212
|
# Read the closing of a group.
|
@@ -228,16 +232,16 @@ module Seafoam
|
|
228
232
|
# Skip over edges.
|
229
233
|
def skip_edges(node_class, inputs)
|
230
234
|
edges = if inputs
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
+
node_class[:inputs]
|
236
|
+
else
|
237
|
+
node_class[:outputs]
|
238
|
+
end
|
235
239
|
edges.each do |edge|
|
236
240
|
count = if edge[:direct]
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
+
1
|
242
|
+
else
|
243
|
+
@reader.read_sint16
|
244
|
+
end
|
241
245
|
count.times do
|
242
246
|
@reader.skip_int32
|
243
247
|
end
|
@@ -247,16 +251,16 @@ module Seafoam
|
|
247
251
|
# Read edges, producing an array of edge hashes.
|
248
252
|
def read_edges(node, node_class, inputs)
|
249
253
|
edges = if inputs
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
+
node_class[:inputs]
|
255
|
+
else
|
256
|
+
node_class[:outputs]
|
257
|
+
end
|
254
258
|
edges.map do |edge|
|
255
259
|
count = if edge[:direct]
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
+
1
|
261
|
+
else
|
262
|
+
@reader.read_sint16
|
263
|
+
end
|
260
264
|
ids = count.times.map do
|
261
265
|
id = @reader.read_sint32
|
262
266
|
raise if id < -1
|
@@ -268,7 +272,7 @@ module Seafoam
|
|
268
272
|
node: node,
|
269
273
|
edge: edge,
|
270
274
|
ids: ids,
|
271
|
-
inputs: inputs
|
275
|
+
inputs: inputs,
|
272
276
|
}
|
273
277
|
end
|
274
278
|
end
|
@@ -277,8 +281,8 @@ module Seafoam
|
|
277
281
|
def skip_blocks
|
278
282
|
@reader.read_sint32.times do
|
279
283
|
@reader.skip_int32
|
280
|
-
@reader.skip_int32
|
281
|
-
@reader.skip_int32
|
284
|
+
@reader.skip_int32(@reader.read_sint32)
|
285
|
+
@reader.skip_int32(@reader.read_sint32)
|
282
286
|
end
|
283
287
|
end
|
284
288
|
|
@@ -323,9 +327,9 @@ module Seafoam
|
|
323
327
|
skip_pool_object
|
324
328
|
end
|
325
329
|
when PROPERTY_INT
|
326
|
-
@reader.skip_int32
|
330
|
+
@reader.skip_int32(@reader.read_sint32)
|
327
331
|
when PROPERTY_DOUBLE
|
328
|
-
@reader.skip_float64
|
332
|
+
@reader.skip_float64(@reader.read_sint32)
|
329
333
|
else
|
330
334
|
raise EncodingError, "unknown BGV property array type 0x#{type.to_s(16)}"
|
331
335
|
end
|
@@ -388,7 +392,8 @@ module Seafoam
|
|
388
392
|
when POOL_NULL
|
389
393
|
when POOL_NEW
|
390
394
|
read_pool_entry
|
391
|
-
when POOL_STRING, POOL_ENUM, POOL_CLASS, POOL_METHOD, POOL_NODE_CLASS,
|
395
|
+
when POOL_STRING, POOL_ENUM, POOL_CLASS, POOL_METHOD, POOL_NODE_CLASS,
|
396
|
+
POOL_FIELD, POOL_SIGNATURE, POOL_NODE_SOURCE_POSITION, POOL_NODE
|
392
397
|
@reader.skip_int16
|
393
398
|
else
|
394
399
|
raise EncodingError, "unknown token 0x#{token.to_s(16)} in BGV pool object"
|
@@ -403,7 +408,8 @@ module Seafoam
|
|
403
408
|
nil
|
404
409
|
when POOL_NEW
|
405
410
|
read_pool_entry
|
406
|
-
when POOL_STRING, POOL_ENUM, POOL_CLASS, POOL_METHOD, POOL_NODE_CLASS,
|
411
|
+
when POOL_STRING, POOL_ENUM, POOL_CLASS, POOL_METHOD, POOL_NODE_CLASS,
|
412
|
+
POOL_FIELD, POOL_SIGNATURE, POOL_NODE_SOURCE_POSITION, POOL_NODE
|
407
413
|
id = @reader.read_uint16
|
408
414
|
object = @pool[id]
|
409
415
|
raise EncodingError, "unknown BGV pool object #{token}" unless object
|
@@ -425,7 +431,9 @@ module Seafoam
|
|
425
431
|
when POOL_ENUM
|
426
432
|
enum_class = read_pool_object
|
427
433
|
enum_ordinal = @reader.read_sint32
|
428
|
-
|
434
|
+
if enum_ordinal.negative? || enum_ordinal >= enum_class.size
|
435
|
+
raise EncodingError, "unknown BGV eum ordinal #{enum_ordinal} in #{enum_class}"
|
436
|
+
end
|
429
437
|
|
430
438
|
object = enum_class[enum_ordinal]
|
431
439
|
when POOL_CLASS
|
@@ -448,12 +456,12 @@ module Seafoam
|
|
448
456
|
signature = read_pool_object
|
449
457
|
modifiers = @reader.read_sint32
|
450
458
|
bytes_length = @reader.read_sint32
|
451
|
-
@reader.skip
|
459
|
+
@reader.skip(bytes_length) if bytes_length != -1
|
452
460
|
object = {
|
453
461
|
declaring_class: declaring_class,
|
454
462
|
method_name: method_name,
|
455
463
|
signature: signature,
|
456
|
-
modifiers: modifiers
|
464
|
+
modifiers: modifiers,
|
457
465
|
}
|
458
466
|
when POOL_NODE_CLASS
|
459
467
|
node_class = read_pool_object
|
@@ -464,7 +472,7 @@ module Seafoam
|
|
464
472
|
node_class: node_class,
|
465
473
|
name_template: name_template,
|
466
474
|
inputs: inputs,
|
467
|
-
outputs: outputs
|
475
|
+
outputs: outputs,
|
468
476
|
}
|
469
477
|
when POOL_FIELD
|
470
478
|
field_class = read_pool_object
|
@@ -475,7 +483,7 @@ module Seafoam
|
|
475
483
|
field_class: field_class,
|
476
484
|
name: name,
|
477
485
|
type_name: type_name,
|
478
|
-
modifiers: modifiers
|
486
|
+
modifiers: modifiers,
|
479
487
|
}
|
480
488
|
when POOL_SIGNATURE
|
481
489
|
args = @reader.read_sint16.times.map do
|
@@ -484,7 +492,7 @@ module Seafoam
|
|
484
492
|
ret = read_pool_object
|
485
493
|
object = {
|
486
494
|
args: args,
|
487
|
-
ret: ret
|
495
|
+
ret: ret,
|
488
496
|
}
|
489
497
|
when POOL_NODE_SOURCE_POSITION
|
490
498
|
method = read_pool_object
|
@@ -498,26 +506,26 @@ module Seafoam
|
|
498
506
|
loc_line = @reader.read_sint32
|
499
507
|
loc_start = @reader.read_sint32
|
500
508
|
loc_end = @reader.read_sint32
|
501
|
-
locs.push
|
509
|
+
locs.push([location, loc_line, loc_start, loc_end])
|
502
510
|
end
|
503
511
|
caller = read_pool_object
|
504
512
|
object = {
|
505
513
|
method: method,
|
506
514
|
bci: bci,
|
507
515
|
locs: locs,
|
508
|
-
caller: caller
|
516
|
+
caller: caller,
|
509
517
|
}
|
510
518
|
when POOL_NODE
|
511
519
|
node_id = @reader.read_sint32
|
512
520
|
node_class = read_pool_object
|
513
521
|
object = {
|
514
522
|
node_id: node_id,
|
515
|
-
node_class: node_class
|
523
|
+
node_class: node_class,
|
516
524
|
}
|
517
525
|
else
|
518
526
|
raise EncodingError, "unknown BGV pool type 0x#{type.to_s(16)}"
|
519
527
|
end
|
520
|
-
set_pool_entry
|
528
|
+
set_pool_entry(id, object)
|
521
529
|
end
|
522
530
|
|
523
531
|
# Hook method that can be overidden for debugging.
|
@@ -534,7 +542,7 @@ module Seafoam
|
|
534
542
|
{
|
535
543
|
direct: !indirect,
|
536
544
|
name: name,
|
537
|
-
type: type
|
545
|
+
type: type,
|
538
546
|
}
|
539
547
|
end
|
540
548
|
end
|
@@ -542,7 +550,7 @@ module Seafoam
|
|
542
550
|
# Skip over a UTF-8 string.
|
543
551
|
def skip_string
|
544
552
|
length = @reader.read_sint32
|
545
|
-
@reader.skip
|
553
|
+
@reader.skip(length) if length != -1
|
546
554
|
end
|
547
555
|
|
548
556
|
# Read a UTF-8 string.
|
@@ -552,7 +560,7 @@ module Seafoam
|
|
552
560
|
nil
|
553
561
|
else
|
554
562
|
string = @reader.read_utf8(length)
|
555
|
-
raise EncodingError,
|
563
|
+
raise EncodingError, "null byte in BGV string" if string.include?("\0")
|
556
564
|
|
557
565
|
string
|
558
566
|
end
|
@@ -578,11 +586,11 @@ module Seafoam
|
|
578
586
|
|
579
587
|
# File format constants.
|
580
588
|
|
581
|
-
MAGIC =
|
589
|
+
MAGIC = "BIGV"
|
582
590
|
|
583
591
|
SUPPORTED_VERSIONS = [
|
584
592
|
[6, 1],
|
585
|
-
[7, 0]
|
593
|
+
[7, 0],
|
586
594
|
]
|
587
595
|
|
588
596
|
BEGIN_GROUP = 0x00
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Seafoam
|
2
4
|
module Binary
|
3
5
|
# An adapter to read binary values from an IO stream.
|
@@ -7,7 +9,7 @@ module Seafoam
|
|
7
9
|
end
|
8
10
|
|
9
11
|
def read_utf8(length)
|
10
|
-
read_bytes(length).force_encoding
|
12
|
+
read_bytes(length).force_encoding(Encoding::UTF_8)
|
11
13
|
end
|
12
14
|
|
13
15
|
def read_bytes(length)
|
@@ -15,31 +17,31 @@ module Seafoam
|
|
15
17
|
end
|
16
18
|
|
17
19
|
def read_float64
|
18
|
-
@io.read(8).unpack1(
|
20
|
+
@io.read(8).unpack1("G")
|
19
21
|
end
|
20
22
|
|
21
23
|
def read_float32
|
22
|
-
@io.read(4).unpack1(
|
24
|
+
@io.read(4).unpack1("g")
|
23
25
|
end
|
24
26
|
|
25
27
|
def read_sint64
|
26
|
-
@io.read(8).unpack1(
|
28
|
+
@io.read(8).unpack1("q>")
|
27
29
|
end
|
28
30
|
|
29
31
|
def read_sint32
|
30
|
-
@io.read(4).unpack1(
|
32
|
+
@io.read(4).unpack1("l>")
|
31
33
|
end
|
32
34
|
|
33
35
|
def read_sint16
|
34
|
-
@io.read(2).unpack1(
|
36
|
+
@io.read(2).unpack1("s>")
|
35
37
|
end
|
36
38
|
|
37
39
|
def read_uint16
|
38
|
-
@io.read(2).unpack1(
|
40
|
+
@io.read(2).unpack1("S>")
|
39
41
|
end
|
40
42
|
|
41
43
|
def read_sint8
|
42
|
-
@io.read(1).unpack1(
|
44
|
+
@io.read(1).unpack1("c")
|
43
45
|
end
|
44
46
|
|
45
47
|
def read_uint8
|
@@ -47,37 +49,37 @@ module Seafoam
|
|
47
49
|
end
|
48
50
|
|
49
51
|
def peek_sint8
|
50
|
-
byte = @io.read(1).unpack1(
|
51
|
-
@io.ungetbyte
|
52
|
+
byte = @io.read(1).unpack1("c")
|
53
|
+
@io.ungetbyte(byte)
|
52
54
|
byte
|
53
55
|
end
|
54
56
|
|
55
57
|
def skip_float64(count = 1)
|
56
|
-
skip
|
58
|
+
skip(count * 8)
|
57
59
|
end
|
58
60
|
|
59
61
|
def skip_float32(count = 1)
|
60
|
-
skip
|
62
|
+
skip(count * 4)
|
61
63
|
end
|
62
64
|
|
63
65
|
def skip_int64(count = 1)
|
64
|
-
skip
|
66
|
+
skip(count * 8)
|
65
67
|
end
|
66
68
|
|
67
69
|
def skip_int32(count = 1)
|
68
|
-
skip
|
70
|
+
skip(count * 4)
|
69
71
|
end
|
70
72
|
|
71
73
|
def skip_int16(count = 1)
|
72
|
-
skip
|
74
|
+
skip(count * 2)
|
73
75
|
end
|
74
76
|
|
75
77
|
def skip_int8(count = 1)
|
76
|
-
skip
|
78
|
+
skip(count)
|
77
79
|
end
|
78
80
|
|
79
81
|
def skip(count)
|
80
|
-
@io.seek
|
82
|
+
@io.seek(count, IO::SEEK_CUR)
|
81
83
|
end
|
82
84
|
|
83
85
|
def eof?
|
data/lib/seafoam/colors.rb
CHANGED
@@ -1,18 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Seafoam
|
2
4
|
# Colors from and derived from the TruffleRuby logo.
|
3
5
|
|
4
6
|
# TruffleRuby logo Copyright (C) 2017 Talkdesk, Inc.
|
5
7
|
# Licensed under CC BY 4.0: https://creativecommons.org/licenses/by/4.0/
|
6
8
|
|
7
|
-
WHITE_ICE =
|
8
|
-
CRUISE =
|
9
|
-
KEPPEL =
|
10
|
-
CARISSMA =
|
11
|
-
AMARANTH =
|
12
|
-
BLACK =
|
13
|
-
WHITE =
|
14
|
-
DUST =
|
15
|
-
BIG_STONE =
|
16
|
-
ICE_STONE =
|
17
|
-
ORANGE =
|
9
|
+
WHITE_ICE = "#d7ede7"
|
10
|
+
CRUISE = "#b8ddd1"
|
11
|
+
KEPPEL = "#3cb4a4"
|
12
|
+
CARISSMA = "#e98693"
|
13
|
+
AMARANTH = "#da2d4f"
|
14
|
+
BLACK = "#1a1919"
|
15
|
+
WHITE = "#ffffff"
|
16
|
+
DUST = "#f9f9f9"
|
17
|
+
BIG_STONE = "#343d46"
|
18
|
+
ICE_STONE = "#b3bbc3"
|
19
|
+
ORANGE = "#ffa500"
|
20
|
+
LIGHT_BLUE = "#ccccff"
|
21
|
+
LIGHT_PURPLE = "#c39bd3"
|
22
|
+
LIGHT_YELLOW = "#ffffde"
|
23
|
+
DARK_YELLOW = "#aaaa33"
|
18
24
|
end
|