Skip to content

Commit 676351d

Browse files
authored
C: Migrate hb_buffer to use hb_allocator_T infrastructure (#1326)
With the new `hb_allocator_realloc` implemented in #1322 we can now port `hb_buffer` to use the `hb_allocator_T` infrastructure. Follow up on #1323
1 parent 2585052 commit 676351d

31 files changed

+321
-296
lines changed

ext/herb/extension.c

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ typedef struct {
3333

3434
typedef struct {
3535
char* buffer_value;
36+
hb_allocator_T allocator;
3637
} buffer_args_T;
3738

3839
static VALUE parse_convert_body(VALUE arg) {
@@ -76,7 +77,8 @@ static VALUE buffer_to_string_body(VALUE arg) {
7677
static VALUE buffer_cleanup(VALUE arg) {
7778
buffer_args_T* args = (buffer_args_T*) arg;
7879

79-
if (args->buffer_value != NULL) { free(args->buffer_value); }
80+
hb_allocator_dealloc(&args->allocator, args->buffer_value);
81+
hb_allocator_destroy(&args->allocator);
8082

8183
return Qnil;
8284
}
@@ -151,9 +153,12 @@ static VALUE Herb_extract_ruby(int argc, VALUE* argv, VALUE self) {
151153
rb_scan_args(argc, argv, "1:", &source, &options);
152154

153155
char* string = (char*) check_string(source);
154-
hb_buffer_T output;
155156

156-
if (!hb_buffer_init(&output, strlen(string))) { return Qnil; }
157+
hb_allocator_T allocator;
158+
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) { return Qnil; }
159+
160+
hb_buffer_T output;
161+
if (!hb_buffer_init(&output, strlen(string), &allocator)) { return Qnil; }
157162

158163
herb_extract_ruby_options_T extract_options = HERB_EXTRACT_RUBY_DEFAULT_OPTIONS;
159164

@@ -173,32 +178,25 @@ static VALUE Herb_extract_ruby(int argc, VALUE* argv, VALUE self) {
173178
if (!NIL_P(preserve_positions_value)) { extract_options.preserve_positions = RTEST(preserve_positions_value); }
174179
}
175180

176-
hb_allocator_T allocator;
177-
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) { return Qnil; }
178-
179181
herb_extract_ruby_to_buffer_with_options(string, &output, &extract_options, &allocator);
180182

181-
hb_allocator_destroy(&allocator);
182-
183-
buffer_args_T args = { .buffer_value = output.value };
183+
buffer_args_T args = { .buffer_value = output.value, .allocator = allocator };
184184

185185
return rb_ensure(buffer_to_string_body, (VALUE) &args, buffer_cleanup, (VALUE) &args);
186186
}
187187

188188
static VALUE Herb_extract_html(VALUE self, VALUE source) {
189189
char* string = (char*) check_string(source);
190-
hb_buffer_T output;
191-
192-
if (!hb_buffer_init(&output, strlen(string))) { return Qnil; }
193190

194191
hb_allocator_T allocator;
195192
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) { return Qnil; }
196193

197-
herb_extract_html_to_buffer(string, &output, &allocator);
194+
hb_buffer_T output;
195+
if (!hb_buffer_init(&output, strlen(string), &allocator)) { return Qnil; }
198196

199-
hb_allocator_destroy(&allocator);
197+
herb_extract_html_to_buffer(string, &output, &allocator);
200198

201-
buffer_args_T args = { .buffer_value = output.value };
199+
buffer_args_T args = { .buffer_value = output.value, .allocator = allocator };
202200

203201
return rb_ensure(buffer_to_string_body, (VALUE) &args, buffer_cleanup, (VALUE) &args);
204202
}
@@ -304,36 +302,36 @@ static VALUE Herb_leak_check(VALUE self, VALUE source) {
304302
}
305303

306304
{
307-
hb_buffer_T output;
308-
if (!hb_buffer_init(&output, strlen(string))) { return Qnil; }
309-
310305
hb_allocator_T allocator;
311306
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_TRACKING)) { return Qnil; }
312307

308+
hb_buffer_T output;
309+
if (!hb_buffer_init(&output, strlen(string), &allocator)) { return Qnil; }
310+
313311
herb_extract_ruby_options_T extract_options = HERB_EXTRACT_RUBY_DEFAULT_OPTIONS;
314312
herb_extract_ruby_to_buffer_with_options(string, &output, &extract_options, &allocator);
315313

316314
hb_allocator_tracking_stats_T* stats = hb_allocator_tracking_stats(&allocator);
317315
rb_hash_aset(result, ID2SYM(rb_intern("extract_ruby")), make_tracking_hash(stats));
318316

317+
hb_buffer_free(&output);
319318
hb_allocator_destroy(&allocator);
320-
free(output.value);
321319
}
322320

323321
{
324-
hb_buffer_T output;
325-
if (!hb_buffer_init(&output, strlen(string))) { return Qnil; }
326-
327322
hb_allocator_T allocator;
328323
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_TRACKING)) { return Qnil; }
329324

325+
hb_buffer_T output;
326+
if (!hb_buffer_init(&output, strlen(string), &allocator)) { return Qnil; }
327+
330328
herb_extract_html_to_buffer(string, &output, &allocator);
331329

332330
hb_allocator_tracking_stats_T* stats = hb_allocator_tracking_stats(&allocator);
333331
rb_hash_aset(result, ID2SYM(rb_intern("extract_html")), make_tracking_hash(stats));
334332

333+
hb_buffer_free(&output);
335334
hb_allocator_destroy(&allocator);
336-
free(output.value);
337335
}
338336

339337
return result;

ext/herb/extension_helpers.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "../../src/include/location.h"
99
#include "../../src/include/position.h"
1010
#include "../../src/include/token.h"
11+
#include "../../src/include/util/hb_allocator.h"
1112
#include "../../src/include/util/hb_string.h"
1213

1314
const char* check_string(VALUE value) {

java/herb_jni.c

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,17 @@ JNIEXPORT jstring JNICALL
104104
Java_org_herb_Herb_extractRuby(JNIEnv* env, jclass clazz, jstring source, jobject options) {
105105
const char* src = (*env)->GetStringUTFChars(env, source, 0);
106106

107+
hb_allocator_T allocator;
108+
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
109+
(*env)->ReleaseStringUTFChars(env, source, src);
110+
return NULL;
111+
}
112+
107113
hb_buffer_T output;
108114

109-
if (!hb_buffer_init(&output, strlen(src))) {
115+
if (!hb_buffer_init(&output, strlen(src), &allocator)) {
116+
hb_allocator_destroy(&allocator);
110117
(*env)->ReleaseStringUTFChars(env, source, src);
111-
112118
return NULL;
113119
}
114120

@@ -136,18 +142,12 @@ Java_org_herb_Herb_extractRuby(JNIEnv* env, jclass clazz, jstring source, jobjec
136142
}
137143
}
138144

139-
hb_allocator_T allocator;
140-
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
141-
(*env)->ReleaseStringUTFChars(env, source, src);
142-
return NULL;
143-
}
144-
145145
herb_extract_ruby_to_buffer_with_options(src, &output, &extract_options, &allocator);
146146

147147
jstring result = (*env)->NewStringUTF(env, output.value);
148148

149+
hb_buffer_free(&output);
149150
hb_allocator_destroy(&allocator);
150-
free(output.value);
151151
(*env)->ReleaseStringUTFChars(env, source, src);
152152

153153
return result;
@@ -157,17 +157,16 @@ JNIEXPORT jstring JNICALL
157157
Java_org_herb_Herb_extractHTML(JNIEnv* env, jclass clazz, jstring source) {
158158
const char* src = (*env)->GetStringUTFChars(env, source, 0);
159159

160-
hb_buffer_T output;
161-
162-
if (!hb_buffer_init(&output, strlen(src))) {
160+
hb_allocator_T allocator;
161+
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
163162
(*env)->ReleaseStringUTFChars(env, source, src);
164-
165163
return NULL;
166164
}
167165

168-
hb_allocator_T allocator;
169-
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
170-
free(output.value);
166+
hb_buffer_T output;
167+
168+
if (!hb_buffer_init(&output, strlen(src), &allocator)) {
169+
hb_allocator_destroy(&allocator);
171170
(*env)->ReleaseStringUTFChars(env, source, src);
172171
return NULL;
173172
}
@@ -176,8 +175,8 @@ Java_org_herb_Herb_extractHTML(JNIEnv* env, jclass clazz, jstring source) {
176175

177176
jstring result = (*env)->NewStringUTF(env, output.value);
178177

178+
hb_buffer_free(&output);
179179
hb_allocator_destroy(&allocator);
180-
free(output.value);
181180
(*env)->ReleaseStringUTFChars(env, source, src);
182181

183182
return result;

javascript/packages/node/extension/herb.cpp

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,16 @@ napi_value Herb_extract_ruby(napi_env env, napi_callback_info info) {
140140
char* string = CheckString(env, args[0]);
141141
if (!string) { return nullptr; }
142142

143+
hb_allocator_T allocator;
144+
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
145+
free(string);
146+
napi_throw_error(env, nullptr, "Failed to initialize allocator");
147+
return nullptr;
148+
}
149+
143150
hb_buffer_T output;
144-
if (!hb_buffer_init(&output, strlen(string))) {
151+
if (!hb_buffer_init(&output, strlen(string), &allocator)) {
152+
hb_allocator_destroy(&allocator);
145153
free(string);
146154
napi_throw_error(env, nullptr, "Failed to initialize buffer");
147155
return nullptr;
@@ -183,21 +191,13 @@ napi_value Herb_extract_ruby(napi_env env, napi_callback_info info) {
183191
}
184192
}
185193

186-
hb_allocator_T allocator;
187-
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
188-
free(output.value);
189-
free(string);
190-
napi_throw_error(env, nullptr, "Failed to initialize allocator");
191-
return nullptr;
192-
}
193-
194194
herb_extract_ruby_to_buffer_with_options(string, &output, &extract_options, &allocator);
195195

196196
napi_value result;
197197
napi_create_string_utf8(env, output.value, NAPI_AUTO_LENGTH, &result);
198198

199+
hb_buffer_free(&output);
199200
hb_allocator_destroy(&allocator);
200-
free(output.value);
201201
free(string);
202202
return result;
203203
}
@@ -215,18 +215,18 @@ napi_value Herb_extract_html(napi_env env, napi_callback_info info) {
215215
char* string = CheckString(env, args[0]);
216216
if (!string) { return nullptr; }
217217

218-
hb_buffer_T output;
219-
if (!hb_buffer_init(&output, strlen(string))) {
218+
hb_allocator_T allocator;
219+
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
220220
free(string);
221-
napi_throw_error(env, nullptr, "Failed to initialize buffer");
221+
napi_throw_error(env, nullptr, "Failed to initialize allocator");
222222
return nullptr;
223223
}
224224

225-
hb_allocator_T allocator;
226-
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
227-
free(output.value);
225+
hb_buffer_T output;
226+
if (!hb_buffer_init(&output, strlen(string), &allocator)) {
227+
hb_allocator_destroy(&allocator);
228228
free(string);
229-
napi_throw_error(env, nullptr, "Failed to initialize allocator");
229+
napi_throw_error(env, nullptr, "Failed to initialize buffer");
230230
return nullptr;
231231
}
232232

@@ -235,8 +235,8 @@ napi_value Herb_extract_html(napi_env env, napi_callback_info info) {
235235
napi_value result;
236236
napi_create_string_utf8(env, output.value, NAPI_AUTO_LENGTH, &result);
237237

238+
hb_buffer_free(&output);
238239
hb_allocator_destroy(&allocator);
239-
free(output.value);
240240
free(string);
241241
return result;
242242
}

rust/src/ffi.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
pub use crate::bindings::{
2-
ast_node_free, element_source_to_string, hb_allocator_T, hb_allocator_destroy, hb_allocator_init, hb_array_get, hb_array_size, hb_buffer_init,
3-
hb_buffer_value, hb_string_T, herb_extract, herb_extract_ruby_to_buffer_with_options, herb_free_tokens, herb_lex, herb_parse, herb_prism_version,
4-
herb_version, token_type_to_string, HB_ALLOCATOR_ARENA,
2+
ast_node_free, element_source_to_string, hb_allocator_T, hb_allocator_destroy, hb_allocator_init, hb_array_get, hb_array_size, hb_buffer_free,
3+
hb_buffer_init, hb_buffer_value, hb_string_T, herb_extract, herb_extract_ruby_to_buffer_with_options, herb_free_tokens, herb_lex, herb_parse,
4+
herb_prism_version, herb_version, token_type_to_string, HB_ALLOCATOR_ARENA,
55
};

rust/src/herb.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,19 @@ pub fn extract_ruby_with_options(source: &str, options: &ExtractRubyOptions) ->
123123
unsafe {
124124
let c_source = CString::new(source).map_err(|e| e.to_string())?;
125125

126-
let mut output: hb_buffer_T = std::mem::zeroed();
127-
128-
if !crate::ffi::hb_buffer_init(&mut output, source.len()) {
129-
return Err("Failed to initialize buffer".to_string());
130-
}
131-
132126
let mut allocator: crate::ffi::hb_allocator_T = std::mem::zeroed();
133127

134128
if !crate::ffi::hb_allocator_init(&mut allocator, crate::ffi::HB_ALLOCATOR_ARENA) {
135-
libc::free(output.value as *mut std::ffi::c_void);
136129
return Err("Failed to initialize allocator".to_string());
137130
}
138131

132+
let mut output: hb_buffer_T = std::mem::zeroed();
133+
134+
if !crate::ffi::hb_buffer_init(&mut output, source.len(), &mut allocator) {
135+
crate::ffi::hb_allocator_destroy(&mut allocator);
136+
return Err("Failed to initialize buffer".to_string());
137+
}
138+
139139
let c_options = crate::bindings::herb_extract_ruby_options_T {
140140
semicolons: options.semicolons,
141141
comments: options.comments,
@@ -147,8 +147,8 @@ pub fn extract_ruby_with_options(source: &str, options: &ExtractRubyOptions) ->
147147
let c_str = std::ffi::CStr::from_ptr(crate::ffi::hb_buffer_value(&output));
148148
let rust_str = c_str.to_string_lossy().into_owned();
149149

150+
crate::ffi::hb_buffer_free(&mut output);
150151
crate::ffi::hb_allocator_destroy(&mut allocator);
151-
libc::free(output.value as *mut std::ffi::c_void);
152152

153153
Ok(rust_str)
154154
}
@@ -175,7 +175,6 @@ pub fn extract_html(source: &str) -> Result<String, String> {
175175
let rust_str = c_str.to_string_lossy().into_owned();
176176

177177
crate::ffi::hb_allocator_destroy(&mut allocator);
178-
libc::free(result as *mut std::ffi::c_void);
179178

180179
Ok(rust_str)
181180
}

src/analyze/parse_errors.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include "../include/errors.h"
55
#include "../include/extract.h"
66
#include "../include/prism_helpers.h"
7+
#include "../include/util/hb_allocator.h"
78
#include "../include/util/hb_string.h"
89

910
#include <prism.h>
@@ -79,5 +80,5 @@ void herb_analyze_parse_errors(AST_DOCUMENT_NODE_T* document, const char* source
7980
pm_node_destroy(&parser, root);
8081
pm_parser_free(&parser);
8182
pm_options_free(&options);
82-
free(extracted_ruby);
83+
hb_allocator_dealloc(allocator, extracted_ruby);
8384
}

src/extract.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,7 @@ char* herb_extract_ruby_with_semicolons(const char* source, hb_allocator_T* allo
220220
if (!source) { return NULL; }
221221

222222
hb_buffer_T output;
223-
hb_buffer_init(&output, strlen(source));
223+
hb_buffer_init(&output, strlen(source), allocator);
224224

225225
herb_extract_ruby_to_buffer(source, &output, allocator);
226226

@@ -231,7 +231,7 @@ char* herb_extract(const char* source, const herb_extract_language_T language, h
231231
if (!source) { return NULL; }
232232

233233
hb_buffer_T output;
234-
hb_buffer_init(&output, strlen(source));
234+
hb_buffer_init(&output, strlen(source), allocator);
235235

236236
switch (language) {
237237
case HERB_EXTRACT_LANGUAGE_RUBY: herb_extract_ruby_to_buffer(source, &output, allocator); break;

src/html_util.c

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "include/html_util.h"
2+
#include "include/util/hb_allocator.h"
23
#include "include/util/hb_buffer.h"
34
#include "include/util/hb_string.h"
45

@@ -206,9 +207,9 @@ bool parent_closes_element(hb_string_T open_tag_name, hb_string_T parent_close_t
206207
* free(tag.data);
207208
* @endcode
208209
*/
209-
hb_string_T html_closing_tag_string(hb_string_T tag_name) {
210+
hb_string_T html_closing_tag_string(hb_string_T tag_name, struct hb_allocator* allocator) {
210211
hb_buffer_T buffer;
211-
hb_buffer_init(&buffer, tag_name.length + 3);
212+
hb_buffer_init(&buffer, tag_name.length + 3, allocator);
212213

213214
hb_buffer_append_char(&buffer, '<');
214215
hb_buffer_append_char(&buffer, '/');
@@ -232,9 +233,9 @@ hb_string_T html_closing_tag_string(hb_string_T tag_name) {
232233
* free(tag);
233234
* @endcode
234235
*/
235-
hb_string_T html_self_closing_tag_string(hb_string_T tag_name) {
236+
hb_string_T html_self_closing_tag_string(hb_string_T tag_name, struct hb_allocator* allocator) {
236237
hb_buffer_T buffer;
237-
hb_buffer_init(&buffer, tag_name.length + 4);
238+
hb_buffer_init(&buffer, tag_name.length + 4, allocator);
238239

239240
hb_buffer_append_char(&buffer, '<');
240241
hb_buffer_append_string(&buffer, tag_name);

0 commit comments

Comments
 (0)