Module: Ibex::Codegen::GeneratedActionABI
- Defined in:
- lib/ibex/codegen/generated_action_abi.rb,
sig/ibex/codegen/generated_action_abi.rbs
Overview
Selects the smallest generated semantic-action ABI that preserves the action's declared inputs. rubocop:disable Metrics/ModuleLength -- ABI proof and source rewriting must evolve together.
Defined Under Namespace
Classes: Cache
Constant Summary collapse
- LEGACY_PARAMETERS =
%w[ _values _ibex_locations _ibex_location_stack _ibex_location _ibex_lookahead_location ].freeze
- SIMPLE_POSITIONAL_READ =
/(?<![.\w@$])val\[\s*(\d+)\s*\]/- SIMPLE_POSITIONAL_UNSAFE =
%r{['"`#%/\\]|<<}
Class Method Summary collapse
-
.borrowed_values?(production, analysis: self) ⇒ Boolean
The direct runtime can share one reduction-values array with an action and a hook installed by that action only when the action cannot mutate or retain the array itself.
-
.positional_action_source(production, analysis: self) ⇒ Object
Return semantic source rewritten for zero-to-four positional RHS arguments, or nil when the values container remains observable.
- .positional_values?(production) ⇒ Boolean
- .values_only?(production) ⇒ Boolean
Instance Method Summary collapse
-
#self?.borrowed_values? ⇒ Boolean
The direct runtime can share one reduction-values array with an action and a hook installed by that action only when the action cannot mutate or retain the array itself.
- #self?.fast_positional_action_source ⇒ String?
-
#self?.positional_action_source ⇒ String?
Return semantic source rewritten for zero-to-four positional RHS arguments, or nil when the values container remains observable.
- #self?.positional_value_reference ⇒ [ String, Integer ]?
- #self?.positional_values? ⇒ Boolean
- #self?.read_only_value_references? ⇒ Boolean
- #self?.receiver_before_value? ⇒ Boolean
- #self?.references_legacy_parameter? ⇒ Boolean
- #self?.rewrite_positional_values ⇒ String?
- #self?.safe_value_reference? ⇒ Boolean
-
#self?.simple_indexed_positional_action_source ⇒ String?
Rewrite the common string/comment/regexp-free action shape without loading Ripper.
-
#self?.simple_indexed_values_action? ⇒ Boolean
Avoid loading a Ruby parser for the overwhelmingly common generated action shape.
-
#self?.simple_positional_action_source ⇒ String?
Keep the most common identity action off the Ripper load path.
- #self?.value_reference? ⇒ Boolean
- #self?.values_only? ⇒ Boolean
Class Method Details
.borrowed_values?(production, analysis: self) ⇒ Boolean
The direct runtime can share one reduction-values array with an action and a hook installed by that action only when the action cannot mutate or retain the array itself. Element reads and parallel assignment copy values out without exposing the container.
86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/ibex/codegen/generated_action_abi.rb', line 86 def borrowed_values?(production, analysis: self) return false unless analysis.values_only?(production) action = production.action return false unless action maximum = production.rhs.length source = ActionLocations.new(action.code, maximum: maximum, location: action.location).rewrite return true if simple_indexed_values_action?(source) require "ripper" syntax = Object.const_get(:Ripper).__send__(:sexp, source) !syntax.nil? && read_only_value_references?(syntax) end |
.positional_action_source(production, analysis: self) ⇒ Object
Return semantic source rewritten for zero-to-four positional RHS arguments, or nil when the values container remains observable.
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
# File 'lib/ibex/codegen/generated_action_abi.rb', line 104 def positional_action_source(production, analysis: self) return nil unless analysis.values_only?(production) return nil unless production.rhs.length <= 4 action = production.action return "" unless action return nil unless analysis.borrowed_values?(production) parameters = Array.new(production.rhs.length) { |index| "v#{index}" } return nil if action.named_refs.any? { |reference| parameters.include?(reference[:name]) } maximum = production.rhs.length source = ActionLocations.new(action.code, maximum: maximum, location: action.location).rewrite simple = fast_positional_action_source(source, parameters) return simple unless simple.nil? require "ripper" tokens = Object.const_get(:Ripper).__send__(:lex, source) return nil unless tokens.map { |_position, _event, token, _state| token }.join == source rewrite_positional_values(tokens, parameters) end |
.positional_values?(production) ⇒ Boolean
137 138 139 |
# File 'lib/ibex/codegen/generated_action_abi.rb', line 137 def positional_values?(production) !positional_action_source(production).nil? end |
.values_only?(production) ⇒ Boolean
69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/ibex/codegen/generated_action_abi.rb', line 69 def values_only?(production) return false if production.action&.composition action = production.action return true unless action return false if action.context_length.positive? maximum = production.rhs.length locations = ActionLocations.new(action.code, maximum: maximum, location: action.location) !locations.references? && !references_legacy_parameter?(action.code) end |
Instance Method Details
#self?.borrowed_values? ⇒ Boolean
The direct runtime can share one reduction-values array with an action and a hook installed by that action only when the action cannot mutate or retain the array itself. Element reads and parallel assignment copy values out without exposing the container.
47 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 47
def self?.borrowed_values?: (IR::Production production, ?analysis: singleton(GeneratedActionABI) | Cache) -> bool
|
#self?.fast_positional_action_source ⇒ String?
55 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 55
def self?.fast_positional_action_source: (String source, Array[String] parameters) -> String?
|
#self?.positional_action_source ⇒ String?
Return semantic source rewritten for zero-to-four positional RHS arguments, or nil when the values container remains observable.
52 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 52
def self?.positional_action_source: (IR::Production production, ?analysis: singleton(GeneratedActionABI) | Cache) -> String?
|
#self?.positional_value_reference ⇒ [ String, Integer ]?
83 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 83
def self?.positional_value_reference: (Array[untyped] tokens, Integer index, Array[String] parameters) -> [ String, Integer ]?
|
#self?.positional_values? ⇒ Boolean
58 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 58
def self?.positional_values?: (IR::Production production) -> bool
|
#self?.read_only_value_references? ⇒ Boolean
92 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 92
def self?.read_only_value_references?: (untyped node, ?untyped parent, ?Integer? child_index) -> bool
|
#self?.receiver_before_value? ⇒ Boolean
86 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 86
def self?.receiver_before_value?: (Array[untyped] tokens, Integer index) -> bool
|
#self?.references_legacy_parameter? ⇒ Boolean
89 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 89
def self?.references_legacy_parameter?: (String source) -> bool
|
#self?.rewrite_positional_values ⇒ String?
80 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 80
def self?.rewrite_positional_values: (Array[untyped] tokens, Array[String] parameters) -> String?
|
#self?.safe_value_reference? ⇒ Boolean
98 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 98
def self?.safe_value_reference?: (untyped parent, Integer? child_index) -> bool
|
#self?.simple_indexed_positional_action_source ⇒ String?
Rewrite the common string/comment/regexp-free action shape without loading Ripper. The borrowed-values proof has already rejected writes and escaping uses of the values container.
77 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 77
def self?.simple_indexed_positional_action_source: (String source, Array[String] parameters) -> String?
|
#self?.simple_indexed_values_action? ⇒ Boolean
Avoid loading a Ruby parser for the overwhelmingly common generated action shape. This accepts only a single result assignment (or a bare expression), simple numeric val reads, and no further assignment. Anything less obvious falls back to Ripper below.
65 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 65
def self?.simple_indexed_values_action?: (String source) -> bool
|
#self?.simple_positional_action_source ⇒ String?
Keep the most common identity action off the Ripper load path. The whole-source match excludes strings, comments, receivers, and compound expressions before replacing the one direct read.
71 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 71
def self?.simple_positional_action_source: (String source, Array[String] parameters) -> String?
|
#self?.value_reference? ⇒ Boolean
95 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 95
def self?.value_reference?: (untyped node) -> bool
|
#self?.values_only? ⇒ Boolean
40 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 40
def self?.values_only?: (IR::Production production) -> bool
|