Class: Bundler::Spinel::Localizer
- Inherits:
-
Object
- Object
- Bundler::Spinel::Localizer
- Defined in:
- lib/bundler/spinel/localizer.rb
Overview
Upgrades a bare ‘miscompile` verdict (CRuby and Spinel agree to run but disagree on stdout) into a located one: the (file, line, variable) where a scalar local first diverges — via the value-bisection harness that lives in the spinel-dev repo (tools/value-bisect/bisect.sh).
Why: a miscompile reason of ‘diff:L2 cruby=“42” spinel=“0”` says two outputs differ but not why. The bisector traces every scalar local under both CRuby and a Spinel –debug build and reports the first to part ways, turning that into `localized:foo.rb:12 total cruby=42 spinel=0` — a line to look at.
Strictly best-effort and non-fatal. If the harness can’t be found (it’s a separate repo), can’t run (the engine dir is a bare binary with no compiler sources / no lldb), or can’t pin a scalar (the divergence is in output formatting, not a traced local), verify still returns the miscompile verdict unchanged — this only ever adds a ‘localized:` reason when it has one.
Instance Method Summary collapse
-
#initialize(engine) ⇒ Localizer
constructor
A new instance of Localizer.
-
#localize(harness) ⇒ Object
Run the bisector on ‘harness` (a self-contained .rb; require_relative’d files are traced too) and return a short reason string, or nil when localization isn’t possible or didn’t pin a value.
Constructor Details
#initialize(engine) ⇒ Localizer
Returns a new instance of Localizer.
22 23 24 |
# File 'lib/bundler/spinel/localizer.rb', line 22 def initialize(engine) @engine = engine end |
Instance Method Details
#localize(harness) ⇒ Object
Run the bisector on ‘harness` (a self-contained .rb; require_relative’d files are traced too) and return a short reason string, or nil when localization isn’t possible or didn’t pin a value.
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/bundler/spinel/localizer.rb', line 29 def localize(harness) script = bisect_script or return nil # SPINEL_DIR points the bisector at the same compiler the engine uses; # it shells out to that checkout's spinel_analyze.rb / spinel_codegen.rb. # bisect.sh exits 1 *on divergence* (the case we want), so the exit code # is not a success signal — parse stdout regardless. stdout carries only # the single JSON object in --json mode; progress goes to stderr. out, _err, _st = Open3.capture3( { "SPINEL_DIR" => @engine.dir }, "sh", script, "--json", harness ) line = out.lines.map(&:strip).reject(&:empty?).last or return nil verdict = begin JSON.parse(line) rescue JSON::ParserError return nil end format_verdict(verdict) rescue StandardError nil end |