Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Cargo-all.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[profile.release]
lto = true # Enable link-time optimization
codegen-units = 1 # Reduce number of codegen units to increase optimizations
panic = 'abort' # Abort on panic
strip = true
69 changes: 46 additions & 23 deletions ext/herb/extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,13 @@ typedef struct {
AST_DOCUMENT_NODE_T* root;
VALUE source;
const parser_options_T* parser_options;
hb_allocator_T allocator;
} parse_args_T;

typedef struct {
hb_array_T* tokens;
VALUE source;
hb_allocator_T allocator;
} lex_args_T;

typedef struct {
Expand All @@ -41,10 +43,9 @@ static VALUE parse_convert_body(VALUE arg) {
static VALUE parse_cleanup(VALUE arg) {
parse_args_T* args = (parse_args_T*) arg;

if (args->root != NULL) {
hb_allocator_T allocator = hb_allocator_with_malloc();
ast_node_free((AST_NODE_T*) args->root, &allocator);
}
if (args->root != NULL) { ast_node_free((AST_NODE_T*) args->root, &args->allocator); }

hb_allocator_destroy(&args->allocator);

return Qnil;
}
Expand All @@ -58,10 +59,9 @@ static VALUE lex_convert_body(VALUE arg) {
static VALUE lex_cleanup(VALUE arg) {
lex_args_T* args = (lex_args_T*) arg;

if (args->tokens != NULL) {
hb_allocator_T allocator = hb_allocator_with_malloc();
herb_free_tokens(&args->tokens, &allocator);
}
if (args->tokens != NULL) { herb_free_tokens(&args->tokens, &args->allocator); }

hb_allocator_destroy(&args->allocator);

return Qnil;
}
Expand All @@ -83,18 +83,25 @@ static VALUE buffer_cleanup(VALUE arg) {
static VALUE Herb_lex(VALUE self, VALUE source) {
char* string = (char*) check_string(source);

hb_allocator_T allocator = hb_allocator_with_malloc();
lex_args_T args = { .tokens = herb_lex(string, &allocator), .source = source };
lex_args_T args = { 0 };
args.source = source;

if (!hb_allocator_init(&args.allocator, HB_ALLOCATOR_ARENA)) { return Qnil; }

args.tokens = herb_lex(string, &args.allocator);

return rb_ensure(lex_convert_body, (VALUE) &args, lex_cleanup, (VALUE) &args);
}

static VALUE Herb_lex_file(VALUE self, VALUE path) {
char* file_path = (char*) check_string(path);

hb_allocator_T allocator = hb_allocator_with_malloc();
VALUE source_value = read_file_to_ruby_string(file_path);
lex_args_T args = { .tokens = herb_lex_file(file_path, &allocator), .source = source_value };
lex_args_T args = { 0 };
args.source = read_file_to_ruby_string(file_path);

if (!hb_allocator_init(&args.allocator, HB_ALLOCATOR_ARENA)) { return Qnil; }

args.tokens = herb_lex_file(file_path, &args.allocator);

return rb_ensure(lex_convert_body, (VALUE) &args, lex_cleanup, (VALUE) &args);
}
Expand All @@ -121,10 +128,13 @@ static VALUE Herb_parse(int argc, VALUE* argv, VALUE self) {
if (!NIL_P(strict)) { parser_options.strict = RTEST(strict); }
}

hb_allocator_T allocator = hb_allocator_with_malloc();
parse_args_T args = { .root = herb_parse(string, &parser_options, &allocator),
.source = source,
.parser_options = &parser_options };
parse_args_T args = { 0 };
args.source = source;
args.parser_options = &parser_options;

if (!hb_allocator_init(&args.allocator, HB_ALLOCATOR_ARENA)) { return Qnil; }

args.root = herb_parse(string, &parser_options, &args.allocator);

return rb_ensure(parse_convert_body, (VALUE) &args, parse_cleanup, (VALUE) &args);
}
Expand Down Expand Up @@ -154,10 +164,13 @@ static VALUE Herb_parse_file(int argc, VALUE* argv, VALUE self) {
if (!NIL_P(strict)) { parser_options.strict = RTEST(strict); }
}

hb_allocator_T allocator = hb_allocator_with_malloc();
parse_args_T args = { .root = herb_parse(string, &parser_options, &allocator),
.source = source_value,
.parser_options = &parser_options };
parse_args_T args = { 0 };
args.source = source_value;
args.parser_options = &parser_options;

if (!hb_allocator_init(&args.allocator, HB_ALLOCATOR_ARENA)) { return Qnil; }

args.root = herb_parse(string, &parser_options, &args.allocator);

return rb_ensure(parse_convert_body, (VALUE) &args, parse_cleanup, (VALUE) &args);
}
Expand Down Expand Up @@ -189,7 +202,12 @@ static VALUE Herb_extract_ruby(int argc, VALUE* argv, VALUE self) {
if (!NIL_P(preserve_positions_value)) { extract_options.preserve_positions = RTEST(preserve_positions_value); }
}

herb_extract_ruby_to_buffer_with_options(string, &output, &extract_options);
hb_allocator_T allocator;
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) { return Qnil; }

herb_extract_ruby_to_buffer_with_options(string, &output, &extract_options, &allocator);

hb_allocator_destroy(&allocator);

buffer_args_T args = { .buffer_value = output.value };

Expand All @@ -202,7 +220,12 @@ static VALUE Herb_extract_html(VALUE self, VALUE source) {

if (!hb_buffer_init(&output, strlen(string))) { return Qnil; }

herb_extract_html_to_buffer(string, &output);
hb_allocator_T allocator;
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) { return Qnil; }

herb_extract_html_to_buffer(string, &output, &allocator);

hb_allocator_destroy(&allocator);

buffer_args_T args = { .buffer_value = output.value };

Expand Down
33 changes: 29 additions & 4 deletions java/herb_jni.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,18 @@ Java_org_herb_Herb_parse(JNIEnv* env, jclass clazz, jstring source, jobject opti
}
}

hb_allocator_T allocator = hb_allocator_with_malloc();
hb_allocator_T allocator;
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
(*env)->ReleaseStringUTFChars(env, source, src);
return NULL;
}

AST_DOCUMENT_NODE_T* ast = herb_parse(src, &parser_options, &allocator);

jobject result = CreateParseResult(env, ast, source);

ast_node_free((AST_NODE_T*) ast, &allocator);
hb_allocator_destroy(&allocator);
(*env)->ReleaseStringUTFChars(env, source, src);

return result;
Expand All @@ -78,13 +83,18 @@ JNIEXPORT jobject JNICALL
Java_org_herb_Herb_lex(JNIEnv* env, jclass clazz, jstring source) {
const char* src = (*env)->GetStringUTFChars(env, source, 0);

hb_allocator_T allocator = hb_allocator_with_malloc();
hb_allocator_T allocator;
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
(*env)->ReleaseStringUTFChars(env, source, src);
return NULL;
}

hb_array_T* tokens = herb_lex(src, &allocator);

jobject result = CreateLexResult(env, tokens, source);

herb_free_tokens(&tokens, &allocator);
hb_allocator_destroy(&allocator);
(*env)->ReleaseStringUTFChars(env, source, src);

return result;
Expand Down Expand Up @@ -126,10 +136,17 @@ Java_org_herb_Herb_extractRuby(JNIEnv* env, jclass clazz, jstring source, jobjec
}
}

herb_extract_ruby_to_buffer_with_options(src, &output, &extract_options);
hb_allocator_T allocator;
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
(*env)->ReleaseStringUTFChars(env, source, src);
return NULL;
}

herb_extract_ruby_to_buffer_with_options(src, &output, &extract_options, &allocator);

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

hb_allocator_destroy(&allocator);
free(output.value);
(*env)->ReleaseStringUTFChars(env, source, src);

Expand All @@ -148,10 +165,18 @@ Java_org_herb_Herb_extractHTML(JNIEnv* env, jclass clazz, jstring source) {
return NULL;
}

herb_extract_html_to_buffer(src, &output);
hb_allocator_T allocator;
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
free(output.value);
(*env)->ReleaseStringUTFChars(env, source, src);
return NULL;
}

herb_extract_html_to_buffer(src, &output, &allocator);

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

hb_allocator_destroy(&allocator);
free(output.value);
(*env)->ReleaseStringUTFChars(env, source, src);

Expand Down
59 changes: 53 additions & 6 deletions javascript/packages/node/extension/herb.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,18 @@ napi_value Herb_lex(napi_env env, napi_callback_info info) {
char* string = CheckString(env, args[0]);
if (!string) { return nullptr; }

hb_allocator_T allocator = hb_allocator_with_malloc();
hb_allocator_T allocator;
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
free(string);
napi_throw_error(env, nullptr, "Failed to initialize allocator");
return nullptr;
}

hb_array_T* tokens = herb_lex(string, &allocator);
napi_value result = CreateLexResult(env, tokens, args[0]);

herb_free_tokens(&tokens, &allocator);
hb_allocator_destroy(&allocator);
free(string);

return result;
Expand All @@ -55,12 +62,19 @@ napi_value Herb_lex_file(napi_env env, napi_callback_info info) {
char* file_path = CheckString(env, args[0]);
if (!file_path) { return nullptr; }

hb_allocator_T allocator = hb_allocator_with_malloc();
hb_allocator_T allocator;
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
free(file_path);
napi_throw_error(env, nullptr, "Failed to initialize allocator");
return nullptr;
}

hb_array_T* tokens = herb_lex_file(file_path, &allocator);
napi_value source_value = ReadFileToString(env, file_path);
napi_value result = CreateLexResult(env, tokens, source_value);

herb_free_tokens(&tokens, &allocator);
hb_allocator_destroy(&allocator);
free(file_path);

return result;
Expand Down Expand Up @@ -127,11 +141,18 @@ napi_value Herb_parse(napi_env env, napi_callback_info info) {
}
}

hb_allocator_T allocator = hb_allocator_with_malloc();
hb_allocator_T allocator;
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
free(string);
napi_throw_error(env, nullptr, "Failed to initialize allocator");
return nullptr;
}

AST_DOCUMENT_NODE_T* root = herb_parse(string, &parser_options, &allocator);
napi_value result = CreateParseResult(env, root, args[0], &parser_options);

ast_node_free((AST_NODE_T *) root, &allocator);
hb_allocator_destroy(&allocator);
free(string);

return result;
Expand All @@ -158,12 +179,20 @@ napi_value Herb_parse_file(napi_env env, napi_callback_info info) {
return nullptr;
}

hb_allocator_T allocator = hb_allocator_with_malloc();
hb_allocator_T allocator;
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
free(file_path);
free(string);
napi_throw_error(env, nullptr, "Failed to initialize allocator");
return nullptr;
}

parser_options_T parser_options = HERB_DEFAULT_PARSER_OPTIONS;
AST_DOCUMENT_NODE_T* root = herb_parse(string, &parser_options, &allocator);
napi_value result = CreateParseResult(env, root, source_value, &parser_options);

ast_node_free((AST_NODE_T *) root, &allocator);
hb_allocator_destroy(&allocator);
free(file_path);
free(string);

Expand Down Expand Up @@ -226,11 +255,20 @@ napi_value Herb_extract_ruby(napi_env env, napi_callback_info info) {
}
}

herb_extract_ruby_to_buffer_with_options(string, &output, &extract_options);
hb_allocator_T allocator;
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
free(output.value);
free(string);
napi_throw_error(env, nullptr, "Failed to initialize allocator");
return nullptr;
}

herb_extract_ruby_to_buffer_with_options(string, &output, &extract_options, &allocator);

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

hb_allocator_destroy(&allocator);
free(output.value);
free(string);
return result;
Expand All @@ -256,11 +294,20 @@ napi_value Herb_extract_html(napi_env env, napi_callback_info info) {
return nullptr;
}

herb_extract_html_to_buffer(string, &output);
hb_allocator_T allocator;
if (!hb_allocator_init(&allocator, HB_ALLOCATOR_ARENA)) {
free(output.value);
free(string);
napi_throw_error(env, nullptr, "Failed to initialize allocator");
return nullptr;
}

herb_extract_html_to_buffer(string, &output, &allocator);

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

hb_allocator_destroy(&allocator);
free(output.value);
free(string);
return result;
Expand Down
1 change: 1 addition & 0 deletions rust/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,7 @@ fn main() {
.allowlist_var("AST_.*")
.allowlist_var("ERROR_.*")
.allowlist_var("ELEMENT_SOURCE_.*")
.allowlist_var("HB_ALLOCATOR_.*")
.allowlist_var("HERB_EXTRACT_.*")
.derive_debug(true)
.derive_default(false)
Expand Down
5 changes: 3 additions & 2 deletions rust/src/ffi.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub use crate::bindings::{
ast_node_free, element_source_to_string, hb_allocator_T, hb_allocator_with_malloc, hb_array_get, hb_array_size, 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, herb_prism_version, herb_version, token_type_to_string,
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,
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,
herb_version, token_type_to_string, HB_ALLOCATOR_ARENA,
};
Loading
Loading