# frozen_string_literal: true =begin This file is generated by the bin/template script and should not be modified manually. See templates/lib/yarp/serialize.rb.erb if you are looking to modify the template =end require "stringio" module YARP module Serialize def self.load(source, serialized) io = StringIO.new(serialized) io.set_encoding(Encoding::BINARY) Loader.new(source, serialized, io).load end class Loader attr_reader :encoding, :source, :serialized, :io attr_reader :constant_pool_offset, :constant_pool def initialize(source, serialized, io) @encoding = Encoding::UTF_8 @source = source.dup @serialized = serialized @io = io @constant_pool_offset = nil @constant_pool = nil end def load io.read(4) => "YARP" io.read(3).unpack("C3") => [0, 4, 0] @encoding = Encoding.find(io.read(load_varint)) @source = source.force_encoding(@encoding).freeze @constant_pool_offset = io.read(4).unpack1("L") @constant_pool = Array.new(load_varint, nil) load_node end private # variable-length integer using https://en.wikipedia.org/wiki/LEB128 # This is also what protobuf uses: https://protobuf.dev/programming-guides/encoding/#varints def load_varint n = io.getbyte if n < 128 n else n -= 128 shift = 0 while (b = io.getbyte) >= 128 n += (b - 128) << (shift += 7) end n + (b << (shift + 7)) end end def load_serialized_length io.read(4).unpack1("L") end def load_optional_node if io.getbyte != 0 io.pos -= 1 load_node end end def load_string io.read(load_varint).force_encoding(encoding) end def load_location Location.new(load_varint, load_varint) end def load_optional_location load_location if io.getbyte != 0 end def load_constant index = load_varint - 1 constant = constant_pool[index] unless constant offset = constant_pool_offset + index * 8 start = serialized.unpack1("L", offset: offset) length = serialized.unpack1("L", offset: offset + 4) constant = source.byteslice(start, length).to_sym constant_pool[index] = constant end constant end def load_node type = io.getbyte start_offset, length = load_varint, load_varint case type when 1 then AliasNode.new(load_node, load_node, load_location, start_offset, length) when 2 then AlternationPatternNode.new(load_node, load_node, load_location, start_offset, length) when 3 then AndNode.new(load_node, load_node, load_location, start_offset, length) when 4 then ArgumentsNode.new(Array.new(load_varint) { load_node }, start_offset, length) when 5 then ArrayNode.new(Array.new(load_varint) { load_node }, load_optional_location, load_optional_location, start_offset, length) when 6 then ArrayPatternNode.new(load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, Array.new(load_varint) { load_node }, load_optional_location, load_optional_location, start_offset, length) when 7 then AssocNode.new(load_node, load_optional_node, load_optional_location, start_offset, length) when 8 then AssocSplatNode.new(load_optional_node, load_location, start_offset, length) when 9 then BackReferenceReadNode.new(start_offset, length) when 10 then BeginNode.new(load_optional_location, load_optional_node, load_optional_node, load_optional_node, load_optional_node, load_optional_location, start_offset, length) when 11 then BlockArgumentNode.new(load_optional_node, load_location, start_offset, length) when 12 then BlockNode.new(Array.new(load_varint) { load_constant }, load_optional_node, load_optional_node, load_location, load_location, start_offset, length) when 13 then BlockParameterNode.new(load_optional_location, load_location, start_offset, length) when 14 then BlockParametersNode.new(load_optional_node, Array.new(load_varint) { load_location }, load_optional_location, load_optional_location, start_offset, length) when 15 then BreakNode.new(load_optional_node, load_location, start_offset, length) when 16 then CallNode.new(load_optional_node, load_optional_location, load_optional_location, load_optional_location, load_optional_node, load_optional_location, load_optional_node, load_varint, load_string, start_offset, length) when 17 then CallOperatorAndWriteNode.new(load_node, load_location, load_node, start_offset, length) when 18 then CallOperatorOrWriteNode.new(load_node, load_node, load_location, start_offset, length) when 19 then CallOperatorWriteNode.new(load_node, load_location, load_node, load_constant, start_offset, length) when 20 then CapturePatternNode.new(load_node, load_node, load_location, start_offset, length) when 21 then CaseNode.new(load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, load_location, load_location, start_offset, length) when 22 then ClassNode.new(Array.new(load_varint) { load_constant }, load_location, load_node, load_optional_location, load_optional_node, load_optional_node, load_location, start_offset, length) when 23 then ClassVariableOperatorAndWriteNode.new(load_location, load_location, load_node, start_offset, length) when 24 then ClassVariableOperatorOrWriteNode.new(load_location, load_location, load_node, start_offset, length) when 25 then ClassVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length) when 26 then ClassVariableReadNode.new(start_offset, length) when 27 then ClassVariableWriteNode.new(load_location, load_optional_node, load_optional_location, start_offset, length) when 28 then ConstantOperatorAndWriteNode.new(load_location, load_location, load_node, start_offset, length) when 29 then ConstantOperatorOrWriteNode.new(load_location, load_location, load_node, start_offset, length) when 30 then ConstantOperatorWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length) when 31 then ConstantPathNode.new(load_optional_node, load_node, load_location, start_offset, length) when 32 then ConstantPathOperatorAndWriteNode.new(load_node, load_location, load_node, start_offset, length) when 33 then ConstantPathOperatorOrWriteNode.new(load_node, load_location, load_node, start_offset, length) when 34 then ConstantPathOperatorWriteNode.new(load_node, load_location, load_node, load_constant, start_offset, length) when 35 then ConstantPathWriteNode.new(load_node, load_optional_location, load_optional_node, start_offset, length) when 36 then ConstantReadNode.new(start_offset, length) when 37 then load_serialized_length DefNode.new(load_location, load_optional_node, load_optional_node, load_optional_node, Array.new(load_varint) { load_constant }, load_location, load_optional_location, load_optional_location, load_optional_location, load_optional_location, load_optional_location, start_offset, length) when 38 then DefinedNode.new(load_optional_location, load_node, load_optional_location, load_location, start_offset, length) when 39 then ElseNode.new(load_location, load_optional_node, load_optional_location, start_offset, length) when 40 then EmbeddedStatementsNode.new(load_location, load_optional_node, load_location, start_offset, length) when 41 then EmbeddedVariableNode.new(load_location, load_node, start_offset, length) when 42 then EnsureNode.new(load_location, load_optional_node, load_location, start_offset, length) when 43 then FalseNode.new(start_offset, length) when 44 then FindPatternNode.new(load_optional_node, load_node, Array.new(load_varint) { load_node }, load_node, load_optional_location, load_optional_location, start_offset, length) when 45 then FloatNode.new(start_offset, length) when 46 then ForNode.new(load_node, load_node, load_optional_node, load_location, load_location, load_optional_location, load_location, start_offset, length) when 47 then ForwardingArgumentsNode.new(start_offset, length) when 48 then ForwardingParameterNode.new(start_offset, length) when 49 then ForwardingSuperNode.new(load_optional_node, start_offset, length) when 50 then GlobalVariableOperatorAndWriteNode.new(load_location, load_location, load_node, start_offset, length) when 51 then GlobalVariableOperatorOrWriteNode.new(load_location, load_location, load_node, start_offset, length) when 52 then GlobalVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length) when 53 then GlobalVariableReadNode.new(start_offset, length) when 54 then GlobalVariableWriteNode.new(load_location, load_optional_location, load_optional_node, start_offset, length) when 55 then HashNode.new(load_location, Array.new(load_varint) { load_node }, load_location, start_offset, length) when 56 then HashPatternNode.new(load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, load_optional_location, load_optional_location, start_offset, length) when 57 then IfNode.new(load_optional_location, load_node, load_optional_node, load_optional_node, load_optional_location, start_offset, length) when 58 then ImaginaryNode.new(load_node, start_offset, length) when 59 then InNode.new(load_node, load_optional_node, load_location, load_optional_location, start_offset, length) when 60 then InstanceVariableOperatorAndWriteNode.new(load_location, load_location, load_node, start_offset, length) when 61 then InstanceVariableOperatorOrWriteNode.new(load_location, load_location, load_node, start_offset, length) when 62 then InstanceVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length) when 63 then InstanceVariableReadNode.new(start_offset, length) when 64 then InstanceVariableWriteNode.new(load_location, load_optional_node, load_optional_location, start_offset, length) when 65 then IntegerNode.new(start_offset, length) when 66 then InterpolatedRegularExpressionNode.new(load_location, Array.new(load_varint) { load_node }, load_location, load_varint, start_offset, length) when 67 then InterpolatedStringNode.new(load_optional_location, Array.new(load_varint) { load_node }, load_optional_location, start_offset, length) when 68 then InterpolatedSymbolNode.new(load_optional_location, Array.new(load_varint) { load_node }, load_optional_location, start_offset, length) when 69 then InterpolatedXStringNode.new(load_location, Array.new(load_varint) { load_node }, load_location, start_offset, length) when 70 then KeywordHashNode.new(Array.new(load_varint) { load_node }, start_offset, length) when 71 then KeywordParameterNode.new(load_location, load_optional_node, start_offset, length) when 72 then KeywordRestParameterNode.new(load_location, load_optional_location, start_offset, length) when 73 then LambdaNode.new(Array.new(load_varint) { load_constant }, load_location, load_optional_node, load_optional_node, start_offset, length) when 74 then LocalVariableOperatorAndWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length) when 75 then LocalVariableOperatorOrWriteNode.new(load_location, load_location, load_node, load_constant, start_offset, length) when 76 then LocalVariableOperatorWriteNode.new(load_location, load_location, load_node, load_constant, load_constant, start_offset, length) when 77 then LocalVariableReadNode.new(load_constant, load_varint, start_offset, length) when 78 then LocalVariableWriteNode.new(load_constant, load_varint, load_optional_node, load_location, load_optional_location, start_offset, length) when 79 then MatchPredicateNode.new(load_node, load_node, load_location, start_offset, length) when 80 then MatchRequiredNode.new(load_node, load_node, load_location, start_offset, length) when 81 then MissingNode.new(start_offset, length) when 82 then ModuleNode.new(Array.new(load_varint) { load_constant }, load_location, load_node, load_optional_node, load_location, start_offset, length) when 83 then MultiWriteNode.new(Array.new(load_varint) { load_node }, load_optional_location, load_optional_node, load_optional_location, load_optional_location, start_offset, length) when 84 then NextNode.new(load_optional_node, load_location, start_offset, length) when 85 then NilNode.new(start_offset, length) when 86 then NoKeywordsParameterNode.new(load_location, load_location, start_offset, length) when 87 then NumberedReferenceReadNode.new(start_offset, length) when 88 then OptionalParameterNode.new(load_constant, load_location, load_location, load_node, start_offset, length) when 89 then OrNode.new(load_node, load_node, load_location, start_offset, length) when 90 then ParametersNode.new(Array.new(load_varint) { load_node }, Array.new(load_varint) { load_node }, Array.new(load_varint) { load_node }, load_optional_node, Array.new(load_varint) { load_node }, load_optional_node, load_optional_node, start_offset, length) when 91 then ParenthesesNode.new(load_optional_node, load_location, load_location, start_offset, length) when 92 then PinnedExpressionNode.new(load_node, load_location, load_location, load_location, start_offset, length) when 93 then PinnedVariableNode.new(load_node, load_location, start_offset, length) when 94 then PostExecutionNode.new(load_optional_node, load_location, load_location, load_location, start_offset, length) when 95 then PreExecutionNode.new(load_optional_node, load_location, load_location, load_location, start_offset, length) when 96 then ProgramNode.new(Array.new(load_varint) { load_constant }, load_node, start_offset, length) when 97 then RangeNode.new(load_optional_node, load_optional_node, load_location, load_varint, start_offset, length) when 98 then RationalNode.new(load_node, start_offset, length) when 99 then RedoNode.new(start_offset, length) when 100 then RegularExpressionNode.new(load_location, load_location, load_location, load_string, load_varint, start_offset, length) when 101 then RequiredDestructuredParameterNode.new(Array.new(load_varint) { load_node }, load_location, load_location, start_offset, length) when 102 then RequiredParameterNode.new(load_constant, start_offset, length) when 103 then RescueModifierNode.new(load_node, load_location, load_node, start_offset, length) when 104 then RescueNode.new(load_location, Array.new(load_varint) { load_node }, load_optional_location, load_optional_node, load_optional_node, load_optional_node, start_offset, length) when 105 then RestParameterNode.new(load_location, load_optional_location, start_offset, length) when 106 then RetryNode.new(start_offset, length) when 107 then ReturnNode.new(load_location, load_optional_node, start_offset, length) when 108 then SelfNode.new(start_offset, length) when 109 then SingletonClassNode.new(Array.new(load_varint) { load_constant }, load_location, load_location, load_node, load_optional_node, load_location, start_offset, length) when 110 then SourceEncodingNode.new(start_offset, length) when 111 then SourceFileNode.new(load_string, start_offset, length) when 112 then SourceLineNode.new(start_offset, length) when 113 then SplatNode.new(load_location, load_optional_node, start_offset, length) when 114 then StatementsNode.new(Array.new(load_varint) { load_node }, start_offset, length) when 115 then StringConcatNode.new(load_node, load_node, start_offset, length) when 116 then StringNode.new(load_optional_location, load_location, load_optional_location, load_string, start_offset, length) when 117 then SuperNode.new(load_location, load_optional_location, load_optional_node, load_optional_location, load_optional_node, start_offset, length) when 118 then SymbolNode.new(load_optional_location, load_location, load_optional_location, load_string, start_offset, length) when 119 then TrueNode.new(start_offset, length) when 120 then UndefNode.new(Array.new(load_varint) { load_node }, load_location, start_offset, length) when 121 then UnlessNode.new(load_location, load_node, load_optional_node, load_optional_node, load_optional_location, start_offset, length) when 122 then UntilNode.new(load_location, load_node, load_optional_node, start_offset, length) when 123 then WhenNode.new(load_location, Array.new(load_varint) { load_node }, load_optional_node, start_offset, length) when 124 then WhileNode.new(load_location, load_node, load_optional_node, start_offset, length) when 125 then XStringNode.new(load_location, load_location, load_location, load_string, start_offset, length) when 126 then YieldNode.new(load_location, load_optional_location, load_optional_node, load_optional_location, start_offset, length) end end end end end