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.
90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
# File 'lib/ibex/codegen/generated_action_abi.rb', line 90 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.
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 |
# File 'lib/ibex/codegen/generated_action_abi.rb', line 108 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
141 142 143 |
# File 'lib/ibex/codegen/generated_action_abi.rb', line 141 def positional_values?(production) !positional_action_source(production).nil? end |
.values_only?(production) ⇒ Boolean
73 74 75 76 77 78 79 80 81 82 83 |
# File 'lib/ibex/codegen/generated_action_abi.rb', line 73 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.
51 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 51
def self?.borrowed_values?: (IR::Production production, ?analysis: singleton(GeneratedActionABI) | Cache) -> bool
|
#self?.fast_positional_action_source ⇒ String?
59 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 59
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.
56 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 56
def self?.positional_action_source: (IR::Production production, ?analysis: singleton(GeneratedActionABI) | Cache) -> String?
|
#self?.positional_value_reference ⇒ [ String, Integer ]?
87 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 87
def self?.positional_value_reference: (Array[ripper_token] tokens, Integer index, Array[String] parameters) -> [ String, Integer ]?
|
#self?.positional_values? ⇒ Boolean
62 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 62
def self?.positional_values?: (IR::Production production) -> bool
|
#self?.read_only_value_references? ⇒ Boolean
96 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 96
def self?.read_only_value_references?: (sexp_value node, ?sexp_value parent, ?Integer? child_index) -> bool
|
#self?.receiver_before_value? ⇒ Boolean
90 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 90
def self?.receiver_before_value?: (Array[ripper_token] tokens, Integer index) -> bool
|
#self?.references_legacy_parameter? ⇒ Boolean
93 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 93
def self?.references_legacy_parameter?: (String source) -> bool
|
#self?.rewrite_positional_values ⇒ String?
84 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 84
def self?.rewrite_positional_values: (Array[ripper_token] tokens, Array[String] parameters) -> String?
|
#self?.safe_value_reference? ⇒ Boolean
102 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 102
def self?.safe_value_reference?: (sexp_value? 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.
81 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 81
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.
69 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 69
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.
75 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 75
def self?.simple_positional_action_source: (String source, Array[String] parameters) -> String?
|
#self?.value_reference? ⇒ Boolean
99 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 99
def self?.value_reference?: (untyped node) -> bool
|
#self?.values_only? ⇒ Boolean
44 |
# File 'sig/ibex/codegen/generated_action_abi.rbs', line 44
def self?.values_only?: (IR::Production production) -> bool
|