@@ -75,7 +75,10 @@ def self.load_exported_functions_from(header, *functions)
75
75
76
76
load_exported_functions_from (
77
77
"yarp/util/yp_buffer.h" ,
78
+ "yp_buffer_sizeof" ,
78
79
"yp_buffer_init" ,
80
+ "yp_buffer_value" ,
81
+ "yp_buffer_length" ,
79
82
"yp_buffer_free"
80
83
)
81
84
@@ -88,34 +91,49 @@ def self.load_exported_functions_from(header, *functions)
88
91
"yp_string_sizeof"
89
92
)
90
93
91
- # This object represents a yp_buffer_t. Its structure must be kept in sync
92
- # with the C version .
93
- class YPBuffer < FFI :: Struct
94
- layout value : :pointer , length : :size_t , capacity : :size_t
94
+ # This object represents a yp_buffer_t. We only use it as an opaque pointer,
95
+ # so it doesn't need to know the fields of yp_buffer_t .
96
+ class YPBuffer
97
+ SIZEOF = LibRubyParser . yp_buffer_sizeof
95
98
96
- # Read the contents of the buffer into a String object and return it.
97
- def to_ruby_string
98
- self [ :value ] . read_string ( self [ :length ] )
99
+ attr_reader :pointer
100
+
101
+ def initialize ( pointer )
102
+ @pointer = pointer
99
103
end
100
- end
101
104
102
- # Initialize a new buffer and yield it to the block. The buffer will be
103
- # automatically freed when the block returns.
104
- def self . with_buffer ( &block )
105
- buffer = YPBuffer . new
106
-
107
- begin
108
- raise unless yp_buffer_init ( buffer )
109
- yield buffer
110
- ensure
111
- yp_buffer_free ( buffer )
112
- buffer . pointer . free
105
+ def value
106
+ LibRubyParser . yp_buffer_value ( pointer )
107
+ end
108
+
109
+ def length
110
+ LibRubyParser . yp_buffer_length ( pointer )
111
+ end
112
+
113
+ def read
114
+ value . read_string ( length )
115
+ end
116
+
117
+ # Initialize a new buffer and yield it to the block. The buffer will be
118
+ # automatically freed when the block returns.
119
+ def self . with ( &block )
120
+ pointer = FFI ::MemoryPointer . new ( SIZEOF )
121
+
122
+ begin
123
+ raise unless LibRubyParser . yp_buffer_init ( pointer )
124
+ yield new ( pointer )
125
+ ensure
126
+ LibRubyParser . yp_buffer_free ( pointer )
127
+ pointer . free
128
+ end
113
129
end
114
130
end
115
131
116
132
# This object represents a yp_string_t. We only use it as an opaque pointer,
117
133
# so it doesn't have to be an FFI::Struct.
118
134
class YPString
135
+ SIZEOF = LibRubyParser . yp_string_sizeof
136
+
119
137
attr_reader :pointer
120
138
121
139
def initialize ( pointer )
@@ -133,23 +151,18 @@ def length
133
151
def read
134
152
source . read_string ( length )
135
153
end
136
- end
137
154
138
- # This is the size of a yp_string_t. It is returned by the yp_string_sizeof
139
- # function which we call once to ensure we have sufficient space for the
140
- # yp_string_t FFI pointer.
141
- SIZEOF_YP_STRING = yp_string_sizeof
142
-
143
- # Yields a yp_string_t pointer to the given block.
144
- def self . with_string ( filepath , &block )
145
- string = FFI ::MemoryPointer . new ( SIZEOF_YP_STRING )
146
-
147
- begin
148
- raise unless yp_string_mapped_init ( string , filepath )
149
- yield YPString . new ( string )
150
- ensure
151
- yp_string_free ( string )
152
- string . free
155
+ # Yields a yp_string_t pointer to the given block.
156
+ def self . with ( filepath , &block )
157
+ pointer = FFI ::MemoryPointer . new ( SIZEOF )
158
+
159
+ begin
160
+ raise unless LibRubyParser . yp_string_mapped_init ( pointer , filepath )
161
+ yield new ( pointer )
162
+ ensure
163
+ LibRubyParser . yp_string_free ( pointer )
164
+ pointer . free
165
+ end
153
166
end
154
167
end
155
168
end
@@ -162,10 +175,10 @@ def self.with_string(filepath, &block)
162
175
VERSION = LibRubyParser . yp_version . read_string
163
176
164
177
def self . dump_internal ( source , source_size , filepath )
165
- LibRubyParser . with_buffer do |buffer |
178
+ LibRubyParser :: YPBuffer . with do |buffer |
166
179
metadata = [ filepath . bytesize , filepath . b , 0 ] . pack ( "LA*L" ) if filepath
167
- LibRubyParser . yp_parse_serialize ( source , source_size , buffer , metadata )
168
- buffer . to_ruby_string
180
+ LibRubyParser . yp_parse_serialize ( source , source_size , buffer . pointer , metadata )
181
+ buffer . read
169
182
end
170
183
end
171
184
private_class_method :dump_internal
@@ -177,24 +190,24 @@ def self.dump(code, filepath = nil)
177
190
178
191
# Mirror the YARP.dump_file API by using the serialization API.
179
192
def self . dump_file ( filepath )
180
- LibRubyParser . with_string ( filepath ) do |string |
193
+ LibRubyParser :: YPString . with ( filepath ) do |string |
181
194
dump_internal ( string . source , string . length , filepath )
182
195
end
183
196
end
184
197
185
198
# Mirror the YARP.lex API by using the serialization API.
186
199
def self . lex ( code , filepath = nil )
187
- LibRubyParser . with_buffer do |buffer |
188
- LibRubyParser . yp_lex_serialize ( code , code . bytesize , filepath , buffer )
189
-
190
- source = Source . new ( code )
191
- Serialize . load_tokens ( source , buffer . to_ruby_string )
200
+ LibRubyParser ::YPBuffer . with do |buffer |
201
+ LibRubyParser . yp_lex_serialize ( code , code . bytesize , filepath , buffer . pointer )
202
+ Serialize . load_tokens ( Source . new ( code ) , buffer . read )
192
203
end
193
204
end
194
205
195
206
# Mirror the YARP.lex_file API by using the serialization API.
196
207
def self . lex_file ( filepath )
197
- LibRubyParser . with_string ( filepath ) { |string | lex ( string . read , filepath ) }
208
+ LibRubyParser ::YPString . with ( filepath ) do |string |
209
+ lex ( string . read , filepath )
210
+ end
198
211
end
199
212
200
213
# Mirror the YARP.parse API by using the serialization API.
@@ -206,6 +219,8 @@ def self.parse(code, filepath = nil)
206
219
# native strings instead of Ruby strings because it allows us to use mmap when
207
220
# it is available.
208
221
def self . parse_file ( filepath )
209
- LibRubyParser . with_string ( filepath ) { |string | parse ( string . read , filepath ) }
222
+ LibRubyParser ::YPString . with ( filepath ) do |string |
223
+ parse ( string . read , filepath )
224
+ end
210
225
end
211
226
end
0 commit comments