summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2022-09-17 16:48:15 +0530
committerGitHub <noreply@github.com>2022-09-17 16:48:15 +0530
commit5fe660ecd76fe164c2065bea00fbba49d39553c2 (patch)
tree5a8c718e9e685e335a5720eca6d37bf5a44531f6 /ext
parent6154188786108b253e8c775f728783e9ffa5293f (diff)
perf(web): optimize encodeInto() (#15922)
Diffstat (limited to 'ext')
-rw-r--r--ext/web/08_text_encoding.js9
-rw-r--r--ext/web/lib.rs59
2 files changed, 28 insertions, 40 deletions
diff --git a/ext/web/08_text_encoding.js b/ext/web/08_text_encoding.js
index 9e0c1f311..db724033f 100644
--- a/ext/web/08_text_encoding.js
+++ b/ext/web/08_text_encoding.js
@@ -25,6 +25,7 @@
TypedArrayPrototypeSubarray,
TypedArrayPrototypeSlice,
Uint8Array,
+ Uint32Array,
} = window.__bootstrap.primordials;
class TextDecoder {
@@ -199,10 +200,16 @@
context: "Argument 2",
allowShared: true,
});
- return ops.op_encoding_encode_into(source, destination);
+ ops.op_encoding_encode_into(source, destination, encodeIntoBuf);
+ return {
+ read: encodeIntoBuf[0],
+ written: encodeIntoBuf[1],
+ };
}
}
+ const encodeIntoBuf = new Uint32Array(2);
+
webidl.configurePrototype(TextEncoder);
const TextEncoderPrototype = TextEncoder.prototype;
diff --git a/ext/web/lib.rs b/ext/web/lib.rs
index 9c1e85952..0eec63ab9 100644
--- a/ext/web/lib.rs
+++ b/ext/web/lib.rs
@@ -10,7 +10,9 @@ use deno_core::error::type_error;
use deno_core::error::AnyError;
use deno_core::include_js_files;
use deno_core::op;
+use deno_core::serde_v8;
use deno_core::url::Url;
+use deno_core::v8;
use deno_core::ByteString;
use deno_core::CancelHandle;
use deno_core::Extension;
@@ -19,11 +21,11 @@ use deno_core::Resource;
use deno_core::ResourceId;
use deno_core::U16String;
use deno_core::ZeroCopyBuf;
+
use encoding_rs::CoderResult;
use encoding_rs::Decoder;
use encoding_rs::DecoderResult;
use encoding_rs::Encoding;
-use serde::Serialize;
use std::borrow::Cow;
use std::cell::RefCell;
use std::fmt;
@@ -314,46 +316,25 @@ impl Resource for TextDecoderResource {
}
}
-#[derive(Serialize)]
-#[serde(rename_all = "camelCase")]
-struct EncodeIntoResult {
- read: usize,
- written: usize,
-}
-
-#[op]
+#[op(v8)]
fn op_encoding_encode_into(
- input: String,
+ scope: &mut v8::HandleScope,
+ input: serde_v8::Value,
buffer: &mut [u8],
-) -> EncodeIntoResult {
- // Since `input` is already UTF-8, we can simply find the last UTF-8 code
- // point boundary from input that fits in `buffer`, and copy the bytes up to
- // that point.
- let boundary = if buffer.len() >= input.len() {
- input.len()
- } else {
- let mut boundary = buffer.len();
-
- // The maximum length of a UTF-8 code point is 4 bytes.
- for _ in 0..4 {
- if input.is_char_boundary(boundary) {
- break;
- }
- debug_assert!(boundary > 0);
- boundary -= 1;
- }
-
- debug_assert!(input.is_char_boundary(boundary));
- boundary
- };
-
- buffer[..boundary].copy_from_slice(input[..boundary].as_bytes());
-
- EncodeIntoResult {
- // The `read` output parameter is measured in UTF-16 code units.
- read: input[..boundary].encode_utf16().count(),
- written: boundary,
- }
+ out_buf: &mut [u32],
+) -> Result<(), AnyError> {
+ let s = v8::Local::<v8::String>::try_from(input.v8_value)?;
+
+ let mut nchars = 0;
+ out_buf[1] = s.write_utf8(
+ scope,
+ buffer,
+ Some(&mut nchars),
+ v8::WriteOptions::NO_NULL_TERMINATION
+ | v8::WriteOptions::REPLACE_INVALID_UTF8,
+ ) as u32;
+ out_buf[0] = nchars as u32;
+ Ok(())
}
/// Creates a [`CancelHandle`] resource that can be used to cancel invocations of certain ops.