Avoid Node.js double copying of result
This commit is contained in:
parent
397327bdeb
commit
d20d6c6a18
|
@ -40,22 +40,13 @@ static inline bool napi_is(napi_env env, napi_value value, napi_is_pred pred) {
|
|||
return res;
|
||||
}
|
||||
|
||||
typedef struct js_min_buf_metadata {
|
||||
napi_ref src_buf_ref;
|
||||
} js_min_buf_metadata;
|
||||
|
||||
void js_cfg_finalizer(napi_env env, void* finalize_data, void* _finalize_hint) {
|
||||
ffi_drop_cfg((Cfg const*) finalize_data);
|
||||
}
|
||||
|
||||
void js_min_buf_finalizer(napi_env env, void* _finalize_data, void* finalize_hint) {
|
||||
js_min_buf_metadata* metadata = (js_min_buf_metadata*) finalize_hint;
|
||||
assert_ok(napi_delete_reference(env, metadata->src_buf_ref));
|
||||
free(metadata);
|
||||
}
|
||||
|
||||
void js_copy_min_buf_finalizer(napi_env env, void* _finalize_data, void* finalize_hint) {
|
||||
free(finalize_hint);
|
||||
void js_output_buf_finalizer(napi_env env, void* _finalize_data, void* finalize_hint) {
|
||||
ffi_output* metadata = (ffi_output*) finalize_hint;
|
||||
ffi_drop_output(metadata);
|
||||
}
|
||||
|
||||
napi_value node_method_create_configuration(napi_env env, napi_callback_info info) {
|
||||
|
@ -160,12 +151,11 @@ napi_value node_method_minify(napi_env env, napi_callback_info info) {
|
|||
}
|
||||
Cfg const* cfg = (Cfg const*) cfg_raw;
|
||||
|
||||
// Run minifier in place.
|
||||
size_t min_len;
|
||||
ffi_in_place(src_data_copy, src_data_len, cfg, &min_len);
|
||||
// Run minifier.
|
||||
ffi_output const* output = ffi_minify(src_data_copy, src_data_len, cfg);
|
||||
|
||||
// Create minified buffer with copied memory.
|
||||
if (napi_create_external_buffer(env, min_len, src_data_copy, js_copy_min_buf_finalizer, src_data_copy, &min_buf_rv) != napi_ok) {
|
||||
if (napi_create_external_buffer(env, output->len, output->data, js_output_buf_finalizer, (void*) output, &min_buf_rv) != napi_ok) {
|
||||
assert_ok(napi_throw_error(env, NULL, "Failed to create minified buffer"));
|
||||
goto rollback;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use minify_html::{minify, Cfg};
|
||||
use std::slice;
|
||||
use std::{mem, slice};
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_create_cfg(
|
||||
|
@ -31,19 +31,35 @@ pub extern "C" fn ffi_drop_cfg(cfg: *const Cfg) -> () {
|
|||
};
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ffi_output {
|
||||
data: *mut u8,
|
||||
len: usize,
|
||||
cap: usize,
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn ffi_drop_output(ptr: *const ffi_output) -> () {
|
||||
unsafe {
|
||||
let out = Box::from_raw(ptr as *mut ffi_output);
|
||||
Vec::from_raw_parts(out.data, out.len, out.cap);
|
||||
};
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
// TODO Return result memory (let Node.js manage GC) instead of overwriting source.
|
||||
pub extern "C" fn ffi_in_place(
|
||||
code: *mut u8,
|
||||
pub extern "C" fn ffi_minify(
|
||||
code: *const u8,
|
||||
code_len: usize,
|
||||
cfg: *const Cfg,
|
||||
out_min_len: *mut usize,
|
||||
) {
|
||||
let code_slice = unsafe { slice::from_raw_parts_mut(code, code_len) };
|
||||
let min_code = minify(code_slice, unsafe { &*cfg });
|
||||
let min_len = min_code.len();
|
||||
code_slice[..min_len].copy_from_slice(&min_code);
|
||||
unsafe {
|
||||
*out_min_len = min_len;
|
||||
}
|
||||
) -> *const ffi_output {
|
||||
let code_slice = unsafe { slice::from_raw_parts(code, code_len) };
|
||||
let mut out_code = minify(code_slice, unsafe { &*cfg });
|
||||
let res = Box::into_raw(Box::new(ffi_output {
|
||||
data: out_code.as_mut_ptr(),
|
||||
len: out_code.len(),
|
||||
cap: out_code.capacity(),
|
||||
}));
|
||||
mem::forget(out_code);
|
||||
res
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue