Module: Optimize::Passes::LiteralValue
- Defined in:
- lib/optimize/passes/literal_value.rb
Overview
Reads and emits literal-producer instructions.
Ruby 4.0.2 literal-producer shapes we recognize (confirmed via RubyVM::InstructionSequence disassembly on Ruby 4.0.2):
putobject_INT2FIX_0_ — pushes 0 (no operand)
putobject_INT2FIX_1_ — pushes 1 (no operand)
putobject <index> — pushes object_table.objects[index]
putchilledstring <index> — default string literal in 4.0.2; pushes the
String at object_table.objects[index]
putstring <index> — mutable-string variant; same operand shape
putnil — pushes nil (no operand)
‘read` returning nil is ambiguous (putnil legitimately reads as nil, and an unrecognized opcode also returns nil). Callers that need to distinguish “literal nil” from “not a literal” must use `literal?`.
‘emit` is unchanged from the Integer/boolean tier — it only knows how to emit putobject-family opcodes.
Constant Summary collapse
- LITERAL_OPCODES =
%i[ putobject putobject_INT2FIX_0_ putobject_INT2FIX_1_ putchilledstring putstring putnil ].freeze
Class Method Summary collapse
- .emit(value, line:, object_table:) ⇒ IR::Instruction
-
.literal?(inst) ⇒ Boolean
True iff ‘inst` is a recognized literal producer.
-
.read(inst, object_table:) ⇒ Object?
The pushed value.
Class Method Details
.emit(value, line:, object_table:) ⇒ IR::Instruction
62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/optimize/passes/literal_value.rb', line 62 def emit(value, line:, object_table:) case value when 0 IR::Instruction.new(opcode: :putobject_INT2FIX_0_, operands: [], line: line) when 1 IR::Instruction.new(opcode: :putobject_INT2FIX_1_, operands: [], line: line) else idx = object_table.intern(value) IR::Instruction.new(opcode: :putobject, operands: [idx], line: line) end end |
.literal?(inst) ⇒ Boolean
Returns true iff ‘inst` is a recognized literal producer.
38 39 40 |
# File 'lib/optimize/passes/literal_value.rb', line 38 def literal?(inst) LITERAL_OPCODES.include?(inst.opcode) end |
.read(inst, object_table:) ⇒ Object?
Returns the pushed value. Returns nil for :putnil AND for unrecognized opcodes — use ‘literal?` to disambiguate.
46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/optimize/passes/literal_value.rb', line 46 def read(inst, object_table:) case inst.opcode when :putobject_INT2FIX_0_ then 0 when :putobject_INT2FIX_1_ then 1 when :putnil then nil when :putobject, :putchilledstring, :putstring idx = inst.operands[0] return nil unless idx.is_a?(Integer) object_table.objects[idx] end end |