furnace-xray 1.1.0.pre1 → 1.1.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/furnace-xray/app/assets/javascripts/application.js.coffee +9 -9
- data/lib/furnace-xray/app/assets/javascripts/lib/graph.js.coffee +6 -5
- data/lib/furnace-xray/app/assets/javascripts/lib/input.js.coffee +43 -104
- data/lib/furnace-xray/app/assets/javascripts/lib/input_state.js.coffee +6 -4
- data/lib/furnace-xray/app/assets/javascripts/lib/node.js.coffee +39 -0
- data/lib/furnace-xray/app/assets/javascripts/lib/nodes/argument.js.coffee +9 -2
- data/lib/furnace-xray/app/assets/javascripts/lib/nodes/basic_block.js.coffee +82 -0
- data/lib/furnace-xray/app/assets/javascripts/lib/nodes/constant.js.coffee +9 -0
- data/lib/furnace-xray/app/assets/javascripts/lib/nodes/function.js.coffee +20 -5
- data/lib/furnace-xray/app/assets/javascripts/lib/nodes/instruction.js.coffee +43 -23
- data/lib/furnace-xray/app/assets/javascripts/lib/nodes/module.js.coffee +8 -0
- data/lib/furnace-xray/app/assets/javascripts/lib/nodes/phi.js.coffee +10 -0
- data/lib/furnace-xray/app/assets/javascripts/lib/nodes/type.js.coffee +6 -9
- data/lib/furnace-xray/app/assets/javascripts/lib/nodes/type_bottom.js.coffee +3 -0
- data/lib/furnace-xray/app/assets/javascripts/lib/nodes/type_variable.js.coffee +1 -0
- data/lib/furnace-xray/app/views/nodes/{instruction_typed.jst.mustache → instruction.jst.mustache} +0 -0
- data/lib/furnace-xray/app/views/nodes/{operand_argument.jst.mustache → operands/argument.jst.mustache} +0 -0
- data/lib/furnace-xray/app/views/nodes/{operand_basic_block.jst.mustache → operands/basic_block.jst.mustache} +0 -0
- data/lib/furnace-xray/app/views/nodes/{operand_constant.jst.mustache → operands/constant.jst.mustache} +0 -0
- data/lib/furnace-xray/app/views/nodes/{operand_instruction.jst.mustache → operands/instruction.jst.mustache} +0 -0
- data/lib/furnace-xray/app/views/nodes/{type_constant.jst.mustache → type.jst.mustache} +0 -0
- data/lib/furnace-xray/version.rb +1 -1
- data/sample.json +8909 -1
- metadata +15 -13
- data/lib/furnace-xray/app/assets/javascripts/lib/map.js.coffee +0 -48
- data/lib/furnace-xray/app/assets/javascripts/lib/nodes/block.js.coffee +0 -76
- data/lib/furnace-xray/app/assets/javascripts/lib/nodes/operand.js.coffee +0 -21
- data/lib/furnace-xray/app/views/nodes/operand_constant_function.jst.mustache +0 -1
- data/lib/furnace-xray/app/views/nodes/type_parametric.jst.mustache +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c33b7ac042d318fbb36bc37effca9374300eff92
|
4
|
+
data.tar.gz: 126063f60ad1f161a7d3f8b093dbdf78a6637e94
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 14b818259d317c73fe046ef38ed131dbc24cd32430c4afdb2413f4100f90f76c7a12c0e7d418066caba2018ad396791fc0ea548b995f2bfae4502af630c1bf7c
|
7
|
+
data.tar.gz: aa33c93878d6d0a011c4640526c949114d89768bc0d9a631e2a145429047722924ebcade79660fb13028628e90d133c39e8ab23c464e123a361c4113d69bd5b7
|
@@ -64,16 +64,16 @@ class Application
|
|
64
64
|
@transform.removeClass('active').html('')
|
65
65
|
@diff.html('')
|
66
66
|
|
67
|
-
input =
|
67
|
+
input = Input.functions[@currentFunction].input
|
68
68
|
|
69
|
-
Drawer.reset() if @input?.
|
69
|
+
Drawer.reset() if @input?.function.name != input.function.name
|
70
70
|
Drawer.clear()
|
71
71
|
|
72
72
|
@input = input
|
73
73
|
@input.rewind(@currentStep)
|
74
74
|
@drawer = new Drawer(new Graph(@input))
|
75
75
|
|
76
|
-
@title.html @input.function.title()
|
76
|
+
@title.html @input.map[@input.function.id]?.title()
|
77
77
|
@diff.html "~ " + @input.previousState.cursor if @input.previousState?.cursor?
|
78
78
|
|
79
79
|
@renewZoomer()
|
@@ -87,7 +87,7 @@ class Application
|
|
87
87
|
|
88
88
|
dehasherize: ->
|
89
89
|
hash = window.location.hash.from(1)
|
90
|
-
hash = "0:#{
|
90
|
+
hash = "0:#{Input.functions[0].input.events.length-1}" if hash.length == 0
|
91
91
|
[@currentFunction, @currentStep] = hash.split(":").map (x) -> x.toNumber()
|
92
92
|
|
93
93
|
jumpTo: (func, step) ->
|
@@ -95,8 +95,8 @@ class Application
|
|
95
95
|
@selector.find('option').each (x) ->
|
96
96
|
func = $(@).attr('value').toNumber() if $(@).text() == func
|
97
97
|
|
98
|
-
@currentFunction = func; step =
|
99
|
-
@currentStep = [step,
|
98
|
+
@currentFunction = func; step = Input.functions[func].input.events.length-1 if step == undefined
|
99
|
+
@currentStep = [step, Input.functions[func].input.events.length-1].min()
|
100
100
|
@currentStep = [0, @currentStep].max()
|
101
101
|
window.location.hash = "#{@currentFunction}:#{@currentStep || 0}"
|
102
102
|
|
@@ -162,9 +162,9 @@ class Application
|
|
162
162
|
buildSelector: ->
|
163
163
|
groups = ['Present', 'Removed'].map (x) -> $("<optgroup label='#{x}'></optgroup>")
|
164
164
|
|
165
|
-
|
166
|
-
group = if f.
|
167
|
-
group.append "<option value='#{i}'>#{f.
|
165
|
+
Input.functions.each (f, i) ->
|
166
|
+
group = if f.present then groups[0] else groups[1]
|
167
|
+
group.append "<option value='#{i}'>#{f.name}</option>"
|
168
168
|
|
169
169
|
groups.each (x) => @selector.append x
|
170
170
|
|
@@ -8,18 +8,19 @@ class @Graph
|
|
8
8
|
@edges = []
|
9
9
|
blockNodes = Object.extended()
|
10
10
|
|
11
|
-
@input.
|
12
|
-
blockNodes[b.
|
11
|
+
@input.activeBlocks()?.each (b) =>
|
12
|
+
blockNodes[b.id] =
|
13
13
|
edges: b.references()
|
14
14
|
label: b.name
|
15
|
-
data: b.title(@input.previousState
|
15
|
+
data: b.title(unless @input.previousState? then false else (@input.previousState.basicBlocks[b.id] || []))
|
16
16
|
|
17
17
|
blockNodes.each (i, n) =>
|
18
18
|
edges = []
|
19
19
|
|
20
20
|
n.edges.each (x) =>
|
21
|
-
|
22
|
-
|
21
|
+
if blockNodes[x]?
|
22
|
+
edges.add {source: n, target: blockNodes[x], data: blockNodes[x].label}
|
23
|
+
@edges.add edges.last()
|
23
24
|
|
24
25
|
n.edges = edges
|
25
26
|
|
@@ -2,61 +2,63 @@
|
|
2
2
|
# Internal representation of input JSON
|
3
3
|
#
|
4
4
|
class @Input
|
5
|
-
@normalize: (
|
6
|
-
|
7
|
-
|
8
|
-
constructor: (@source) ->
|
9
|
-
@source.events.each (x) -> x.event = x.event.camelize(false)
|
10
|
-
|
11
|
-
# Scan for effective events
|
12
|
-
@events = []
|
13
|
-
reducer = []
|
5
|
+
@normalize: (@events) =>
|
6
|
+
@functions = []
|
7
|
+
events = Object.extended()
|
14
8
|
transforms = Object.extended()
|
15
9
|
|
16
|
-
@
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
10
|
+
@events.each (event, i) =>
|
11
|
+
if event['kind'] == 'transform'
|
12
|
+
f = event['function_id']
|
13
|
+
|
14
|
+
transforms[f] ||= []
|
15
|
+
transforms[f].push
|
16
|
+
id: events[f].length - 1
|
17
|
+
label: event['name']
|
18
|
+
else
|
19
|
+
node = Node.refresh(event)
|
20
|
+
|
21
|
+
if node.attachedFunctions?
|
22
|
+
Object.each node.attachedFunctions(), (id, f) =>
|
23
|
+
events[id] ||= []
|
24
|
+
events[id].push i
|
25
|
+
|
26
|
+
Node.kinds['function'].each (f) =>
|
27
|
+
@functions.push
|
28
|
+
name: f.name
|
29
|
+
present: f.present
|
30
|
+
input: new Input(f, events[f.id], transforms[f.id])
|
31
|
+
|
32
|
+
@constantize: (kind) ->
|
33
|
+
result = window[kind.camelize()+'Node']
|
34
|
+
result
|
35
|
+
|
36
|
+
constructor: (@function, @events, @transforms) ->
|
35
37
|
@transforms = @transforms.filter (x, i) =>
|
36
38
|
x.length = (@transforms[i+1]?.id || @events.length) - x.id
|
37
|
-
x.id < @events.length-1
|
39
|
+
x.id < @events.length-1 && x.length > 0
|
38
40
|
|
39
41
|
@reset()
|
40
42
|
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
@instructions = Object.extended()
|
45
|
-
@blocksMap = new Map 'blocks'
|
46
|
-
@instructionsMap = new Map 'instructions'
|
43
|
+
activeBlocks: ->
|
44
|
+
data = @kinds['basic_block']?.findAll (b) =>
|
45
|
+
b.attachedFunctions()[@function.id]?
|
47
46
|
|
48
|
-
|
49
|
-
@cursor = 0
|
47
|
+
data || []
|
50
48
|
|
51
|
-
|
52
|
-
|
49
|
+
reset: ->
|
50
|
+
@map = Object.extended()
|
51
|
+
@kinds = Object.extended()
|
52
|
+
@cursor = 0
|
53
|
+
|
54
|
+
# run upcoming steps at initialization
|
55
|
+
i = -1; @run(i) while (i+=1) < @events[0]
|
53
56
|
|
54
57
|
rewind: (to) ->
|
55
58
|
return if to == @cursor
|
56
59
|
|
57
60
|
if to < @cursor
|
58
61
|
delete @previousState
|
59
|
-
@reset()
|
60
62
|
else
|
61
63
|
@previousState = new InputState(@)
|
62
64
|
|
@@ -72,67 +74,4 @@ class @Input
|
|
72
74
|
@cursor = stop
|
73
75
|
|
74
76
|
run: (step) ->
|
75
|
-
|
76
|
-
|
77
|
-
if event.event == 'type'
|
78
|
-
@types[event.id] = new TypeNode(event.kind, event.name, event.parameters)
|
79
|
-
else
|
80
|
-
@[event.event]?(event)
|
81
|
-
console.log "UNKNOWN EVENT: #{event.event}" unless @[event.event]?
|
82
|
-
|
83
|
-
type: (id) ->
|
84
|
-
return undefined unless id?
|
85
|
-
|
86
|
-
if type = @types[id]
|
87
|
-
return type
|
88
|
-
else
|
89
|
-
@reset()
|
90
|
-
throw "Type #{id} not found in #{@types.keys().join(',')}"
|
91
|
-
|
92
|
-
setReturnType: (event) ->
|
93
|
-
@function.setReturnType @type(event.return_type)
|
94
|
-
|
95
|
-
setArguments: (event) ->
|
96
|
-
@function.setArguments(event.arguments.map (x) =>
|
97
|
-
new ArgumentNode(x.name, @type(x.type)))
|
98
|
-
|
99
|
-
addBasicBlock: (event) ->
|
100
|
-
@blocksMap.add event.name, (id) =>
|
101
|
-
@blocks[id] = new BlockNode(event.name)
|
102
|
-
|
103
|
-
removeBasicBlock: (event) ->
|
104
|
-
@blocksMap.remove event.name, (id) =>
|
105
|
-
delete @blocks[id]
|
106
|
-
|
107
|
-
renameBasicBlock: (event) ->
|
108
|
-
@blocksMap.rename event.name, event.new_name, (id) =>
|
109
|
-
@blocks[id].setName(event.new_name)
|
110
|
-
|
111
|
-
updateInstruction: (event) ->
|
112
|
-
id = @instructionsMap.add event.name, (id) =>
|
113
|
-
@instructions[id] = new InstructionNode
|
114
|
-
|
115
|
-
if Object.isArray(event.operands)
|
116
|
-
operands = event.operands.map (x) =>
|
117
|
-
new OperandNode x.kind, @type(x.type), x.name, x.value
|
118
|
-
else
|
119
|
-
operands = []
|
120
|
-
Object.each event.operands, (key, x) =>
|
121
|
-
operands.push [key, new OperandNode(x.kind, @type(x.type), x.name, x.value)]
|
122
|
-
|
123
|
-
@instructions[id].update event.opcode, event.name, event.parameters, operands, @type(event.type)
|
124
|
-
|
125
|
-
addInstruction: (event) ->
|
126
|
-
@instructionsMap.locateOrAdd event.name, (i) =>
|
127
|
-
@blocksMap.locate event.basic_block, (b) =>
|
128
|
-
@instructions[i].link @blocks[b], event.index
|
129
|
-
|
130
|
-
removeInstruction: (event) ->
|
131
|
-
@instructionsMap.locate event.name, (i) =>
|
132
|
-
@instructions[i].unlink()
|
133
|
-
|
134
|
-
renameInstruction: (event) ->
|
135
|
-
@instructionsMap.rename event.name, event.new_name, (i) =>
|
136
|
-
@instructions[i].name = event.new_name
|
137
|
-
|
138
|
-
transformStart: (event) ->
|
77
|
+
node = Node.refresh(Input.events[step], @map, @kinds)
|
@@ -1,8 +1,10 @@
|
|
1
1
|
class @InputState
|
2
2
|
constructor: (input) ->
|
3
|
-
@
|
3
|
+
@basicBlocks = Object.extended()
|
4
4
|
@cursor = input.cursor
|
5
5
|
|
6
|
-
input.
|
7
|
-
@
|
8
|
-
|
6
|
+
input.kinds['basic_block']?.each (b) =>
|
7
|
+
@basicBlocks[b.id] = b.instructions.map (i) =>
|
8
|
+
id: i.id
|
9
|
+
name: i.name
|
10
|
+
title: i.title()
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class @Node
|
2
|
+
@refresh: (data, map=false, kinds=false) ->
|
3
|
+
Node.map ||= Object.extended()
|
4
|
+
Node.kinds ||= Object.extended()
|
5
|
+
|
6
|
+
map ||= Node.map
|
7
|
+
kinds ||= Node.kinds
|
8
|
+
|
9
|
+
if map[data.id]
|
10
|
+
map[data.id].update(data, map)
|
11
|
+
else
|
12
|
+
klass = window[data.kind.camelize()+'Node']
|
13
|
+
|
14
|
+
return false if !klass?
|
15
|
+
|
16
|
+
kinds[data.kind] ||= []
|
17
|
+
kinds[data.kind].push map[data.id] = new klass(data, map)
|
18
|
+
|
19
|
+
map[data.id]
|
20
|
+
|
21
|
+
@reset: ->
|
22
|
+
Node.map = Object.extended()
|
23
|
+
Node.kinds = {}
|
24
|
+
|
25
|
+
constructor: (data, map) ->
|
26
|
+
@id = data.id
|
27
|
+
@update(data, map)
|
28
|
+
|
29
|
+
update: (data, map) ->
|
30
|
+
|
31
|
+
locate: (id, map) ->
|
32
|
+
map[id] || throw("Element #{id} not found in map")
|
33
|
+
|
34
|
+
reassign: (before, after, callback) ->
|
35
|
+
if !before? || before.length == 0
|
36
|
+
callback([], after)
|
37
|
+
else
|
38
|
+
intersection = before.intersect(after)
|
39
|
+
callback before.subtract(intersection), after.subtract(intersection)
|
@@ -1,7 +1,14 @@
|
|
1
|
-
class @ArgumentNode
|
2
|
-
|
1
|
+
class @ArgumentNode extends Node
|
2
|
+
update: (data, map) ->
|
3
|
+
@name = data['name']
|
4
|
+
@type = @locate(data['type'], map)
|
3
5
|
|
4
6
|
title: ->
|
5
7
|
JST['nodes/argument']
|
8
|
+
type: @type.title()
|
9
|
+
name: @name
|
10
|
+
|
11
|
+
operandTitle: ->
|
12
|
+
JST['nodes/operands/argument']
|
6
13
|
type: @type.title()
|
7
14
|
name: @name
|
@@ -0,0 +1,82 @@
|
|
1
|
+
class @BasicBlockNode extends Node
|
2
|
+
constructor: (data, map) ->
|
3
|
+
super
|
4
|
+
@functions = Object.extended()
|
5
|
+
|
6
|
+
update: (data, map) ->
|
7
|
+
@name = data['name']
|
8
|
+
|
9
|
+
@reassign @instructionIds, data['instruction_ids'], (removed, added) =>
|
10
|
+
removed.each (id) => @locate(id, map).unlinkBlock(@)
|
11
|
+
added.each (id) => @locate(id, map).linkBlock(@)
|
12
|
+
|
13
|
+
@instructionIds = data['instruction_ids']
|
14
|
+
@instructions = @instructionIds.map (id) => @locate(id, map)
|
15
|
+
|
16
|
+
linkFunction: (f) ->
|
17
|
+
@functions[f.id] = f
|
18
|
+
|
19
|
+
unlinkFunction: (f) ->
|
20
|
+
delete @functions[f.id]
|
21
|
+
|
22
|
+
attachedFunctions: -> @functions
|
23
|
+
|
24
|
+
title: (previousInstructions) ->
|
25
|
+
JST['nodes/block']
|
26
|
+
name: @name
|
27
|
+
instructions: @titleizeInstructions(previousInstructions)
|
28
|
+
|
29
|
+
operandTitle: ->
|
30
|
+
JST['nodes/operands/basic_block']
|
31
|
+
name: @name
|
32
|
+
|
33
|
+
titleizeInstructions: (previousInstructions) ->
|
34
|
+
unless previousInstructions
|
35
|
+
result = ""
|
36
|
+
result += JST['nodes/diff/unchanged_line'] line: x.title() for x in @instructions
|
37
|
+
result
|
38
|
+
else
|
39
|
+
result = ""
|
40
|
+
removed = Object.extended()
|
41
|
+
added = Object.extended()
|
42
|
+
changed = Object.extended()
|
43
|
+
unchanged = Object.extended()
|
44
|
+
|
45
|
+
for cs, i in @instructions
|
46
|
+
previous = previousInstructions.find (ps) -> ps.id == cs.id
|
47
|
+
currentTitle = cs.title()
|
48
|
+
|
49
|
+
if previous && previous.title == currentTitle
|
50
|
+
unchanged[i] = previous.title
|
51
|
+
previous.newPosition = i
|
52
|
+
else if previous
|
53
|
+
changed[i] = [previous.title, currentTitle]
|
54
|
+
previous.newPosition = i
|
55
|
+
else
|
56
|
+
added[i] = currentTitle
|
57
|
+
|
58
|
+
for ps, i in previousInstructions
|
59
|
+
if !ps.newPosition?
|
60
|
+
position = 0
|
61
|
+
|
62
|
+
while --i >= 0
|
63
|
+
if previousInstructions[i].newPosition?
|
64
|
+
position = previousInstructions[i].newPosition+1
|
65
|
+
break
|
66
|
+
|
67
|
+
removed[position] ||= []
|
68
|
+
removed[position].push ps.title
|
69
|
+
|
70
|
+
[@instructions.length, previousInstructions.length].max().times (i) ->
|
71
|
+
if removed[i]
|
72
|
+
result += JST['nodes/diff/removed_line'](line: l) for l in removed[i]
|
73
|
+
|
74
|
+
result += JST['nodes/diff/added_line'](line: added[i]) if added[i]
|
75
|
+
result += JST['nodes/diff/changed_line'](before: changed[i][0], after:changed[i][1]) if changed[i]
|
76
|
+
result += JST['nodes/diff/unchanged_line'](line: unchanged[i]) if unchanged[i]
|
77
|
+
|
78
|
+
result
|
79
|
+
|
80
|
+
references: ->
|
81
|
+
ids = @instructions.last()?.operands.findAll((x) -> x instanceof BasicBlockNode).map((x) -> x.id)
|
82
|
+
(ids || []).exclude((x) => x == @id)
|
@@ -1,10 +1,25 @@
|
|
1
|
-
class @FunctionNode
|
2
|
-
|
3
|
-
@
|
1
|
+
class @FunctionNode extends Node
|
2
|
+
update: (data, map) ->
|
3
|
+
@name = data['name']
|
4
|
+
@type = @locate(data['return_type'], map)
|
5
|
+
@present = false
|
4
6
|
|
5
|
-
|
7
|
+
@arguments = data['argument_ids'].map (id) => @locate(id, map)
|
6
8
|
|
7
|
-
|
9
|
+
@reassign @blockIds, data['basic_block_ids'], (removed, added) =>
|
10
|
+
removed.each (id) => @locate(id, map).unlinkFunction(@)
|
11
|
+
added.each (id) => @locate(id, map).linkFunction(@)
|
12
|
+
|
13
|
+
@blockIds = data['basic_block_ids']
|
14
|
+
@blocks = @blockIds.map (id) => @locate(id, map)
|
15
|
+
|
16
|
+
linkModule: -> @present = true
|
17
|
+
unlinkModule: -> @present = false
|
18
|
+
|
19
|
+
attachedFunctions: ->
|
20
|
+
result = {}
|
21
|
+
result[@id] = @
|
22
|
+
result
|
8
23
|
|
9
24
|
title: ->
|
10
25
|
template = if @present then 'nodes/function' else 'nodes/function_removed'
|
@@ -1,33 +1,53 @@
|
|
1
|
-
class @InstructionNode
|
2
|
-
constructor: ->
|
3
|
-
|
1
|
+
class @InstructionNode extends Node
|
2
|
+
constructor: (data, map) ->
|
3
|
+
super
|
4
|
+
@blocks = Object.extended()
|
4
5
|
|
5
|
-
|
6
|
+
linkBlock: (block) ->
|
7
|
+
@blocks[block.id] = block
|
8
|
+
@operands?.each (x) => x.linkBlock(block) if x['linkBlock']?
|
6
9
|
|
7
|
-
|
8
|
-
block.
|
9
|
-
@
|
10
|
+
unlinkBlock: (block) ->
|
11
|
+
delete @blocks[block.id]
|
12
|
+
@operands?.each (x) => x.unlinkBlock(block) if x['unlinkBlock']?
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
@blocks
|
14
|
+
attachedFunctions: ->
|
15
|
+
result = {}
|
16
|
+
@blocks.values().each (x) -> Object.merge result, x.attachedFunctions()
|
17
|
+
result
|
14
18
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
"%#{x[0]} => #{x[1].title()}"
|
19
|
+
update: (data, map) ->
|
20
|
+
@type = @locate(data['type'], map)
|
21
|
+
@name = data['name']
|
22
|
+
@opcode = data['opcode']
|
23
|
+
@parameters = data['parameters']
|
21
24
|
|
22
|
-
if
|
23
|
-
|
24
|
-
opcode: @opcode
|
25
|
-
parameters: @parameters
|
26
|
-
operands: operands.join(', ')
|
25
|
+
if data['operand_ids']
|
26
|
+
@updateOperands(data['operand_ids'], map)
|
27
27
|
else
|
28
|
-
|
28
|
+
@operands = null
|
29
|
+
|
30
|
+
updateOperands: (data, map) ->
|
31
|
+
@operands = data.map (x) => @locate(x, map)
|
32
|
+
|
33
|
+
title: ->
|
34
|
+
if @type && !@type.void()
|
35
|
+
JST['nodes/instruction']
|
29
36
|
type: @type.title()
|
30
37
|
name: @name
|
31
38
|
opcode: @opcode
|
32
39
|
parameters: @parameters
|
33
|
-
operands:
|
40
|
+
operands: @titleizeOperands()
|
41
|
+
else
|
42
|
+
JST['nodes/instruction_void']
|
43
|
+
opcode: @opcode
|
44
|
+
parameters: @parameters
|
45
|
+
operands: @titleizeOperands()
|
46
|
+
|
47
|
+
titleizeOperands: ->
|
48
|
+
return "<DETACHED>" unless @operands
|
49
|
+
@operands.map((x) -> x.operandTitle()).join(', ')
|
50
|
+
|
51
|
+
operandTitle: ->
|
52
|
+
JST['nodes/operands/instruction']
|
53
|
+
name: @name
|
@@ -0,0 +1,8 @@
|
|
1
|
+
class @ModuleNode extends Node
|
2
|
+
update: (data, map) ->
|
3
|
+
@reassign @functionIds, data['function_ids'], (removed, added) =>
|
4
|
+
removed.each (id) => @locate(id, map).unlinkModule(@)
|
5
|
+
added.each (id) => @locate(id, map).linkModule(@)
|
6
|
+
|
7
|
+
@functionIds = data['function_ids']
|
8
|
+
@functions = @functionIds.map (id) => @locate(id, map)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
class @PhiNode extends InstructionNode
|
2
|
+
|
3
|
+
updateOperands: (data, map) ->
|
4
|
+
@operands = data.map (pair) =>
|
5
|
+
pair.map (x) =>
|
6
|
+
@locate(x, map)
|
7
|
+
|
8
|
+
titleizeOperands: (data) ->
|
9
|
+
return "<DETACHED>" unless @operands
|
10
|
+
@operands.map (pair) => "#{pair[0].operandTitle()} => #{pair[1].operandTitle()}"
|
@@ -1,12 +1,9 @@
|
|
1
|
-
class @TypeNode
|
1
|
+
class @TypeNode extends Node
|
2
2
|
|
3
|
-
|
3
|
+
update: (data, map) ->
|
4
|
+
@name = data['name']
|
5
|
+
|
6
|
+
void: () -> false
|
4
7
|
|
5
8
|
title: ->
|
6
|
-
|
7
|
-
when 'void' then JST['nodes/type_constant'](type: 'void')
|
8
|
-
when 'monotype' then JST['nodes/type_constant'](type: @name)
|
9
|
-
when 'parametric'
|
10
|
-
JST['nodes/type_parametric']
|
11
|
-
type: @name
|
12
|
-
parameters: @parameters.map((x) -> x.title()).join(', ')
|
9
|
+
JST['nodes/type'](type: @name)
|
@@ -0,0 +1 @@
|
|
1
|
+
class @TypeVariableNode extends @TypeNode
|
data/lib/furnace-xray/app/views/nodes/{instruction_typed.jst.mustache → instruction.jst.mustache}
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
data/lib/furnace-xray/version.rb
CHANGED