Class: Laser::Analysis::LaserProc
- Inherits:
-
LaserObject
show all
- Defined in:
- lib/laser/analysis/bootstrap/laser_proc.rb
Instance Attribute Summary (collapse)
Attributes inherited from LaserObject
#scope, #singleton_class
Instance Method Summary
(collapse)
Methods inherited from LaserObject
#add_instance_method!, #instance_variable_defined?, #instance_variable_get, #instance_variable_set, #laser_simulate, #normal_class
#attr_accessor_with_default, #cattr_accessor, #cattr_accessor_with_default, #cattr_get_and_setter, #cattr_reader, #cattr_writer, #opposite_method
Constructor Details
- (LaserProc) initialize(arguments, ast_node, cfg = nil, callsite_block = nil)
A new instance of LaserProc
7
8
9
10
11
12
13
14
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 7
def initialize(arguments, ast_node, cfg = nil, callsite_block = nil)
@ast_node = ast_node
@arguments = arguments
@cfg = cfg
@callsite_block = callsite_block
@lexical_self = @exit_block = nil
@annotations = Hash.new { |h, k| h[k] = [] }
end
|
Instance Attribute Details
- (Object) annotations
Returns the value of attribute annotations
6
7
8
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 6
def annotations
@annotations
end
|
- (Object) arguments
Returns the value of attribute arguments
5
6
7
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 5
def arguments
@arguments
end
|
- (Object) ast_node
Returns the value of attribute ast_node
5
6
7
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 5
def ast_node
@ast_node
end
|
- (Object) cfg
Returns the value of attribute cfg
5
6
7
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 5
def cfg
@cfg
end
|
- (Object) exit_block
Returns the value of attribute exit_block
5
6
7
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 5
def exit_block
@exit_block
end
|
- (Object) lexical_self
Returns the value of attribute lexical_self
5
6
7
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 5
def lexical_self
@lexical_self
end
|
- (Object) line_number
Returns the value of attribute line_number
6
7
8
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 6
def line_number
@line_number
end
|
Instance Method Details
- (Object) annotated_raise_frequency
136
137
138
139
140
141
142
143
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 136
def annotated_raise_frequency
if annotations['raises'].any?
annotations['raises'].select(&:literal?).map(&:literal).each do |literal|
return Frequency[literal] if !literal || Symbol === literal
end
nil
end
end
|
- (Object) annotated_return
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 95
def annotated_return
notes = annotations['returns']
if notes.any?
if notes.size > 1
raise ArgumentError.new("Cannot have more than one 'returns' annotation")
end
return_type = notes.first
if return_type.type?
return_type.type
else
raise NotImplementedError.new('Literal annotated return types not implemented')
end
end
end
|
- (Object) annotated_yield_usage
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 110
def annotated_yield_usage
notes = annotations['yield_usage']
if notes.any?
if notes.size > 1
raise ArgumentError.new("Cannot have more than one 'yield_usage' annotation")
end
yield_usage = notes.first
if yield_usage.type?
raise ArgumentError.new('yield_usage requires a literal yield usage category')
else
yield_usage.literal
end
end
end
|
- (Object) call(*args, &blk)
69
70
71
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 69
def call(*args, &blk)
end
|
- (Object) compiled_cfg
31
32
33
34
35
36
37
38
39
40
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 31
def compiled_cfg
return @cfg if @cfg
if @ast_node.scope.self_ptr != Scope::GlobalScope.self_ptr
@ast_node.scope.lexical_target = @ast_node.scope.self_ptr.value.binding
end
builder = ControlFlow::GraphBuilder.new(@ast_node, @arguments, @ast_node.scope)
@cfg = builder.build
end
|
- (Object) inspect
Also known as:
name
20
21
22
23
24
25
26
27
28
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 20
def inspect
desc_part = "Proc:0x#{object_id.to_s(16)}@#{ast_node.file_name}"
arg_part = "(#{arguments.map(&:name).join(', ')})"
if ast_node.source_begin
"#<#{desc_part}:#{ast_node.line_number}*#{arg_part}>"
else
"#<#{desc_part}*#{arg_part}>"
end
end
|
- (Object) klass
82
83
84
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 82
def klass
ClassRegistry['Proc']
end
|
- (Object) overloads
125
126
127
128
129
130
131
132
133
134
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 125
def overloads
Hash[*(annotations['overload'].map do |overload|
raise ArgumentError.new('overload must be a type') unless overload.type?
proc_type = overload.type
unless Types::GenericType === proc_type && proc_type.base_type == Types::PROC
raise ArgumentError.new('overload must be a function type')
end
[proc_type.subtypes[0].element_types, proc_type]
end.flatten(1))]
end
|
- (Object) raises
145
146
147
148
149
150
151
152
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 145
def raises
if annotations['raises'].any?
types = annotations['raises'].select(&:type?)
if types.any?
Types::UnionType.new(types.map { |note| note.type })
end
end
end
|
- (Object) simulate(args, block, opts = {})
42
43
44
45
46
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 42
def simulate(args, block, opts={})
update_cfg_edges(opts) if opts[:invocation_sites]
self_to_use = opts[:self] || @lexical_self
cfg.simulate(args, opts.merge({self: self_to_use, block: block, start_block: start_block}))
end
|
- (Object) ssa_cfg
73
74
75
76
77
78
79
80
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 73
def ssa_cfg
@ssa_cfg ||= compiled_cfg.tap do |cfg|
cfg.perform_dead_code_discovery(true)
Laser.debug_puts('>>> Starting SSA Transformation <<<')
cfg.static_single_assignment_form
Laser.debug_puts('>>> Finished SSA Transformation <<<')
end
end
|
- (Object) start_block
16
17
18
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 16
def start_block
@callsite_block && @callsite_block.block_taken_successors.first
end
|
- (Object) to_proc
65
66
67
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 65
def to_proc
self
end
|
- (Object) update_cfg_edges(opts)
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
# File 'lib/laser/analysis/bootstrap/laser_proc.rb', line 48
def update_cfg_edges(opts)
opts[:invocation_sites][self].each do |callsite|
opts[:invocation_counts][self][callsite] += 1
callsite_succ = callsite.successors.find do |b|
b.name == start_block.name || b.name.include?("SSA-FIX-#{start_block.name}")
end
if !callsite.has_flag?(callsite_succ, RGL::ControlFlowGraph::EDGE_EXECUTABLE)
callsite.add_flag(callsite_succ, RGL::ControlFlowGraph::EDGE_EXECUTABLE)
else
exit_succ = exit_block.successors.find do |b|
b.name == start_block.name || b.name.include?("SSA-FIX-#{start_block.name}")
end
exit_block.add_flag(exit_succ, RGL::ControlFlowGraph::EDGE_EXECUTABLE)
end
end
end
|