Class: Udb::Extension
Overview
Defined Under Namespace
Classes: ConditionallyApplicableParameter
Instance Attribute Summary
#arch, #data, #data_path, #name
Instance Method Summary
collapse
create_json_schemer_resolver, #initialize, #key?, #keys, #validate
#__source, #cfg_arch, #cfg_arch?, #clone, #defer, #defined_by_condition, #description, #initialize, #inspect, #kind, #source_line
Instance Method Details
#<=>(other_ext) ⇒ Object
404
405
406
407
|
# File 'lib/udb/obj/extension.rb', line 404
def <=>(other_ext)
return nil unless other_ext.is_a?(Extension)
other_ext.name <=> name
end
|
#all_csrs_that_must_be_implemented ⇒ Object
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
|
# File 'lib/udb/obj/extension.rb', line 273
def all_csrs_that_must_be_implemented
@all_csrs_that_must_be_implemented ||=
begin
pb =
Udb.create_progressbar(
"Finding all required csrs for #{name} [:bar] :current/:total",
total: @arch.csrs.size,
clear: true
)
@arch.csrs.select do |csr|
pb.advance
(-csr.defined_by_condition & to_condition).unsatisfiable_by_arch?(@arch)
end
end
end
|
#all_instructions_that_must_be_implemented ⇒ Object
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
|
# File 'lib/udb/obj/extension.rb', line 207
def all_instructions_that_must_be_implemented
@all_instructions_that_must_be_implemented ||=
begin
pb =
Udb.create_progressbar(
"Finding all required instructions for #{name} [:bar] :current/:total",
total: @arch.instructions.size,
clear: true
)
@arch.instructions.select do |i|
pb.advance
(-i.defined_by_condition & to_condition).unsatisfiable_by_arch?(@arch)
end
end
end
|
#all_params_that_must_be_implemented ⇒ Object
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
|
# File 'lib/udb/obj/extension.rb', line 161
def all_params_that_must_be_implemented
@all_params_that_must_be_implemented ||=
begin
pb =
Udb.create_progressbar(
"Finding implied params for #{name} [:bar] :current/:total",
total: cfg_arch.params.size,
clear: true
)
cfg_arch.params.select do |p|
pb.advance
param_defined = p.defined_by_condition
(-param_defined & to_condition).unsatisfiable_by_arch?(cfg_arch)
end
end
end
|
#compact_priv_type ⇒ Object
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
# File 'lib/udb/obj/extension.rb', line 30
def compact_priv_type
case priv_type
when "unprivileged"
"unpriv"
when "privileged"
"priv"
else
if priv_type.nil? || priv_type.empty?
raise ArgumentError, "Extension #{name} missing its type in database (must be privileged or unprivileged)"
else
raise ArgumentError, "Extension #{name} has illegal privileged/unprivileged type of #{priv_type}"
end
end
end
|
#company ⇒ Object
48
49
50
51
52
|
# File 'lib/udb/obj/extension.rb', line 48
def company
if @data.key?("company")
@company ||= Company.new(@data["company"])
end
end
|
#conditional_params ⇒ Object
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
# File 'lib/udb/obj/extension.rb', line 116
def conditional_params
@cond_params ||=
begin
pb =
Udb.create_progressbar(
"Finding conditional params for #{name} [:bar] :current/:total",
total: cfg_arch.params.size,
clear: true
)
cfg_arch.params.filter_map do |p|
pb.advance
next if params.include?(p)
next unless p.defined_by_condition.mentions?(self)
next unless (p.defined_by_condition & self.to_condition).satisfiable?
cond = p.defined_by_condition.partial_eval(ext_reqs: [self.to_ext_req]).minimize(expand: false)
ConditionallyApplicableParameter.new(cond:, param: p)
end
end
end
|
#conflicting_extensions ⇒ Object
Returns list of extensions that conflict with self.
201
202
203
204
205
|
# File 'lib/udb/obj/extension.rb', line 201
def conflicting_extensions
@cfg_arch.extensions.select do |ext|
(to_condition & ext.to_condition).unsatisfiable?
end
end
|
#csrs ⇒ Object
310
311
312
|
# File 'lib/udb/obj/extension.rb', line 310
def csrs
@csrs ||= all_csrs_that_must_be_implemented - implied_csrs
end
|
#csrs_that_must_be_implemented ⇒ Object
344
345
346
|
# File 'lib/udb/obj/extension.rb', line 344
def csrs_that_must_be_implemented
@csrs_that_must_be_implemented ||= csrs + implied_csrs
end
|
#doc_license ⇒ Object
57
58
59
|
# File 'lib/udb/obj/extension.rb', line 57
def doc_license
@data["doc_license"]
end
|
#exception_codes ⇒ Object
411
412
413
414
415
416
417
418
419
420
421
|
# File 'lib/udb/obj/extension.rb', line 411
def exception_codes
@exception_codes ||=
@cfg_arch.exception_codes.select do |ecode|
if ecode.defined_by_condition.mentions?(self)
ecode.defined_by_condition.satisfied_by_ext_req?(to_ext_req, include_requirements: false) ||
ecode.defined_by_condition.satisfiability_depends_on_ext_req?(to_ext_req)
else
false
end
end
end
|
#general_extension_requirements_condition ⇒ Object
187
188
189
190
191
192
|
# File 'lib/udb/obj/extension.rb', line 187
def general_extension_requirements_condition
@general_extension_requirements_condition ||=
@data.key?("requirements") \
? Condition.new(@data.fetch("requirements"), @cfg_arch, input_file: Pathname.new(__source), input_line: source_line(["requirements"]))
: AlwaysTrueCondition.new(@cfg_arch)
end
|
#implied_csrs ⇒ Object
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
|
# File 'lib/udb/obj/extension.rb', line 290
def implied_csrs
@implied_csrs ||=
begin
pb =
Udb.create_progressbar(
"Finding implied csrs for #{name} [:bar] :current/:total",
total: @arch.csrs.size,
clear: true
)
@arch.csrs.select do |csr|
pb.advance
(-csr.defined_by_condition & requirements_condition).unsatisfiable_by_arch?(@arch)
end
end
end
|
#implied_instructions ⇒ Object
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
|
# File 'lib/udb/obj/extension.rb', line 232
def implied_instructions
@implied_instructions ||=
begin
pb =
Udb.create_progressbar(
"Finding implied instructions for #{name} [:bar] :current/:total",
total: @arch.instructions.size,
clear: true
)
@arch.instructions.select do |i|
pb.advance
(-i.defined_by_condition & requirements_condition).unsatisfiable_by_arch?(@arch)
end
end
end
|
#implied_instructions_set ⇒ Object
268
269
270
|
# File 'lib/udb/obj/extension.rb', line 268
def implied_instructions_set
@implied_instructions_set ||= Set.new(implied_instructions)
end
|
#implied_params ⇒ Object
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
|
# File 'lib/udb/obj/extension.rb', line 140
def implied_params
@implied_params ||=
begin
pb =
Udb.create_progressbar(
"Finding implied params for #{name} [:bar] :current/:total",
total: cfg_arch.params.size,
clear: true
)
cfg_arch.params.select do |p|
pb.advance
param_defined = p.defined_by_condition
preconditions_met = requirements_condition
(-param_defined & preconditions_met).unsatisfiable_by_arch?(cfg_arch)
end
end
end
|
#instructions ⇒ Object
255
256
257
|
# File 'lib/udb/obj/extension.rb', line 255
def instructions
@instructions ||= all_instructions_that_must_be_implemented - implied_instructions
end
|
#instructions_set ⇒ Object
261
262
263
|
# File 'lib/udb/obj/extension.rb', line 261
def instructions_set
@instructions_set ||= Set.new(instructions)
end
|
#interrupt_codes ⇒ Object
425
426
427
428
429
430
431
432
433
434
435
|
# File 'lib/udb/obj/extension.rb', line 425
def interrupt_codes
@interrupt_codes ||=
@cfg_arch.interrupt_codes.select do |icode|
if icode.defined_by_condition.mentions?(self)
icode.defined_by_condition.satisfied_by_ext_req?(to_ext_req, include_requirements: false) ||
icode.defined_by_condition.satisfiability_depends_on_ext_req?(to_ext_req)
else
false
end
end
end
|
#long_name ⇒ Object
22
|
# File 'lib/udb/obj/extension.rb', line 22
def long_name = @data.fetch("long_name")
|
#max_version ⇒ Object
91
92
93
|
# File 'lib/udb/obj/extension.rb', line 91
def max_version
T.must(versions.max { |a, b| T.must(a.version_spec <=> b.version_spec) })
end
|
#min_ratified_version ⇒ Object
97
98
99
100
101
|
# File 'lib/udb/obj/extension.rb', line 97
def min_ratified_version
return nil if ratified_versions.empty?
ratified_versions.min { |a, b| T.must(a.version_spec <=> b.version_spec) }
end
|
#min_version ⇒ Object
85
86
87
|
# File 'lib/udb/obj/extension.rb', line 85
def min_version
T.must(versions.min { |a, b| T.must(a.version_spec <=> b.version_spec) })
end
|
#mmrs ⇒ Object
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
|
# File 'lib/udb/obj/extension.rb', line 350
def mmrs
@mmrs ||=
begin
pb =
Udb.create_progressbar(
"Finding mmrs for #{name} [:bar] :current/:total",
total: cfg_arch.mmrs.size,
clear: true
)
cfg_arch.mmrs.select do |mmr|
pb.advance
mmr_defined = mmr.defined_by_condition
next unless mmr_defined.mentions?(self)
requirement_met = to_condition
preconditions_met = requirements_condition
(
(-mmr_defined & requirement_met) ).unsatisfiable? &
(
(-mmr_defined & preconditions_met) ).satisfiable?
end
end
end
|
#params ⇒ Object
106
107
108
|
# File 'lib/udb/obj/extension.rb', line 106
def params
@params ||= all_params_that_must_be_implemented - implied_params
end
|
#priv_type ⇒ Object
26
|
# File 'lib/udb/obj/extension.rb', line 26
def priv_type = @data.fetch("type")
|
#ratified ⇒ Object
81
|
# File 'lib/udb/obj/extension.rb', line 81
def ratified = ratified_versions.any?
|
#ratified_versions ⇒ Object
75
76
77
|
# File 'lib/udb/obj/extension.rb', line 75
def ratified_versions
versions.select { |v| v.state == "ratified" }
end
|
#reachable_functions ⇒ Object
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
|
# File 'lib/udb/obj/extension.rb', line 381
def reachable_functions
return @reachable_functions unless @reachable_functions.nil?
funcs = T.let([], T::Array[Idl::FunctionDefAst])
Udb.logger.info "Finding all reachable functions from extension #{name}"
cache = T.let({ 32 => {}, 64 => {}, nil => {} }, T::Hash[Integer, Idl::AstNode::ReachableFunctionCacheType])
instructions.each do |inst|
funcs += inst.reachable_functions(32, cache.fetch(32)) if inst.defined_in_base?(32)
funcs += inst.reachable_functions(64, cache.fetch(64)) if inst.defined_in_base?(64)
end
csrs.each do |csr|
funcs += csr.reachable_functions(32, cache) if csr.defined_in_base?(32)
funcs += csr.reachable_functions(64, cache) if csr.defined_in_base?(64)
end
@reachable_functions = funcs.uniq
end
|
#requirements_condition ⇒ Object
196
197
198
|
# File 'lib/udb/obj/extension.rb', line 196
def requirements_condition
@requirements_condition ||= to_ext_req.requirements_condition
end
|
#to_condition ⇒ Object
181
182
183
|
# File 'lib/udb/obj/extension.rb', line 181
def to_condition
@condition ||= Condition.new({ "extension" => { "name" => name } }, @cfg_arch)
end
|
#to_ext_req ⇒ Object
439
440
441
|
# File 'lib/udb/obj/extension.rb', line 439
def to_ext_req
@ext_req ||= @cfg_arch.extension_requirement(name, ">= 0")
end
|
#versions ⇒ Object
63
64
65
66
67
68
69
70
71
|
# File 'lib/udb/obj/extension.rb', line 63
def versions
return @versions unless @versions.nil?
@versions = @data["versions"].map do |v|
cfg_arch.extension_version(name, v["version"])
end
@versions.sort!
@versions
end
|