yarp 0.7.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
1
  #define YP_VERSION_MAJOR 0
2
- #define YP_VERSION_MINOR 7
2
+ #define YP_VERSION_MINOR 8
3
3
  #define YP_VERSION_PATCH 0
4
- #define YP_VERSION "0.7.0"
4
+ #define YP_VERSION "0.8.0"
data/lib/yarp/ffi.rb CHANGED
@@ -75,7 +75,10 @@ module YARP
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 @@ module YARP
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 @@ module YARP
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 @@ module YARP
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,35 +190,37 @@ module YARP
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).with_source(source)
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.
201
214
  def self.parse(code, filepath = nil)
202
- YARP.load(code, dump(code, filepath)).with_source(Source.new(code))
215
+ YARP.load(code, dump(code, filepath))
203
216
  end
204
217
 
205
218
  # Mirror the YARP.parse_file API by using the serialization API. This uses
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