@@ -341,6 +341,8 @@ def extensions
341341 # may be overridden by subclass
342342 # @return [Array<ExtensionVersion>] List of all extensions known to be implemented in this architecture
343343 def implemented_extensions
344+ raise "implemented_extensions is only valid for a fully configured defintion" unless fully_configured?
345+
344346 return @implemented_extensions unless @implemented_extensions . nil?
345347
346348 @implemented_extensions = [ ]
@@ -352,6 +354,21 @@ def implemented_extensions
352354 @implemented_extensions
353355 end
354356
357+ # @return [Array<ExtensionRequirement>] List of extensions that are explicitly required by an arch def
358+ def mandatory_extensions
359+ raise "mandatory_extensions is only valid for a partially configured defintion" unless partially_configured?
360+
361+ return @mandatory_extensions unless @mandatory_extensions . nil?
362+
363+ @mandatory_extensions = [ ]
364+ if @arch_def . key? ( "mandatory_extensions" )
365+ @arch_def [ "mandatory_extensions" ] . each do |e |
366+ @mandatory_extensions << ExtensionRequirement . new ( e [ "name" ] , e [ "version" ] )
367+ end
368+ end
369+ @mandatory_extensions
370+ end
371+
355372 # @return [Array<ExtensionRequirement>] List of extensions that are explicitly prohibited by an arch def
356373 def prohibited_extensions
357374 return @prohibited_extensions unless @prohibited_extensions . nil?
@@ -411,12 +428,27 @@ def ext?(ext_name, *ext_version_requirements)
411428 return cached_result unless cached_result . nil?
412429
413430 result =
414- implemented_extensions . any? do |e |
415- if ext_version_requirements . empty?
416- e . name == ext_name . to_s
417- else
418- requirement = Gem ::Requirement . new ( ext_version_requirements )
419- ( e . name == ext_name . to_s ) && requirement . satisfied_by? ( e . version )
431+ if fully_configured?
432+ implemented_extensions . any? do |e |
433+ if ext_version_requirements . empty?
434+ e . name == ext_name . to_s
435+ else
436+ requirement = Gem ::Requirement . new ( ext_version_requirements )
437+ ( e . name == ext_name . to_s ) && requirement . satisfied_by? ( e . version )
438+ end
439+ end
440+ else
441+ raise "unexpected type" unless partially_configured?
442+
443+ mandatory_extensions . any? do |e |
444+ if ext_version_requirements . empty?
445+ e . name == ext_name . to_s
446+ else
447+ requirement = Gem ::Requirement . new ( ext_version_requirements )
448+ e . satisfying_versions . all? do |ext_ver |
449+ ( e . name == ext_name . to_s ) && requirement . satisfied_by? ( exrt_ver . version )
450+ end
451+ end
420452 end
421453 end
422454 @ext_cache [ [ ext_name , ext_version_requirements ] ] = result
@@ -935,6 +967,27 @@ def implemented_interrupt_codes
935967 end
936968 private :erb_env
937969
970+ # create a new raw *unconfigured* architecture defintion data structure
971+ #
972+ # The data will not include anything configuration-dependent such as implemented_*/mandatory_*/etc.
973+ #
974+ # This function can be used to create a new arch_def for a different configuration
975+ #
976+ # @return [Hash] A unconfigured architecture definition
977+ def unconfigured_data
978+ {
979+ "type" => "partially configured" ,
980+ "instructions" => instructions . map { |i | [ i . name , i . data ] } . to_h ,
981+ "extensions" => extensions . map . map { |e | [ e . name , e . data ] } . to_h ,
982+ "csrs" => csrs . map { |c | [ c . name , c . data ] } . to_h ,
983+ "profile_families" => profile_families . map { |f | [ f . name , f . data ] } . to_h ,
984+ "profiles" => profiles . map { |p | [ p . name , p . data ] } . to_h ,
985+ "manuals" => manuals . map { |m | [ m . name , m . data ] } . to_h ,
986+ "crd_families" => crd_families . map { |f | [ f . name , f . data ] } . to_h ,
987+ "crds" => crds . map { |c | [ c . name , c . data ] } . to_h
988+ }
989+ end
990+
938991 # passes _erb_template_ through ERB within the content of this config
939992 #
940993 # @param erb_template [String] ERB source
0 commit comments