From da1271d9f4e9292bd82e7756987f2813290a847c Mon Sep 17 00:00:00 2001 From: Spotandjake <40705786+spotandjake@users.noreply.github.com> Date: Thu, 25 Jan 2024 23:16:52 -0500 Subject: [PATCH] chore(stdlib): Optimize `Buffer.addChar` (#1933) --- stdlib/buffer.gr | 55 +++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/stdlib/buffer.gr b/stdlib/buffer.gr index 92ae4c0f68..6aa4641955 100644 --- a/stdlib/buffer.gr +++ b/stdlib/buffer.gr @@ -16,6 +16,8 @@ include "runtime/unsafe/memory" include "runtime/unsafe/wasmi32" include "runtime/unsafe/conv" include "runtime/exception" +include "runtime/dataStructures" +from DataStructures use { untagChar } include "int32" include "bytes" include "string" @@ -386,8 +388,59 @@ provide let addString = (string, buffer) => { * * @since v0.4.0 */ +@unsafe provide let addChar = (char, buffer) => { - addString(Char.toString(char), buffer) + from WasmI32 use { + (-), + (*), + (&), + (|), + (>>>), + ltU as (<), + gtU as (>), + leU as (<=), + } + let usv = untagChar(char) + + let bytelen = if (usv < 0x80n) { + autogrow(1, buffer) + from WasmI32 use { (+) } + let off = coerceNumberToWasmI32(buffer.len) + let dst = WasmI32.fromGrain(buffer.data) + _VALUE_OFFSET + WasmI32.store8(dst, usv, off) + 1 + } else { + let mut count = 0n + let mut bytelen = 0 + let mut offset = 0n + if (usv <= 0x07FFn) { + count = 1n + bytelen = 2 + offset = 0xC0n + } else if (usv <= 0xFFFFn) { + count = 2n + bytelen = 3 + offset = 0xE0n + } else { + count = 3n + bytelen = 4 + offset = 0xF0n + } + from WasmI32 use { (+) } + autogrow(bytelen, buffer) + let off = coerceNumberToWasmI32(buffer.len) + let dst = WasmI32.fromGrain(buffer.data) + _VALUE_OFFSET + WasmI32.store8(dst, (usv >>> 6n * count) + offset, off) + let mut n = 0n + while (count > 0n) { + n += 1n + let temp = usv >>> 6n * (count - 1n) + WasmI32.store8(dst + n, 0x80n | temp & 0x3Fn, off) + count -= 1n + } + bytelen + } + buffer.len += bytelen } /**