Skip to content
This repository has been archived by the owner on May 20, 2023. It is now read-only.

Commit

Permalink
Merge pull request #18 from Demonthos/custom_memcpy
Browse files Browse the repository at this point in the history
use a custom implementation instead of memcpy
  • Loading branch information
ealmloff authored Nov 6, 2022
2 parents 2ad56fd + 64b0ade commit f7b2b64
Show file tree
Hide file tree
Showing 6 changed files with 201 additions and 161 deletions.
3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,4 @@ categories = ["web-programming", "wasm", "api-bindings"]
[dependencies]
wasm-bindgen = "0.2.83"
web-sys = { version = "0.3.60", features = ["console", "Window", "Document", "Element", "HtmlElement", "HtmlHeadElement"] }
js-sys = "0.3.60"
ufmt = "0.2.0"
js-sys = "0.3.60"
86 changes: 29 additions & 57 deletions interpreter.js
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,7 @@ export class JsInterpreter {
this.parents = [];
this.UpdateMemory(mem);
this.last_start_pos;
this.last_str_start;
this.metadata_ptr = _metadata_ptr;
this.ptr_ptr = _ptr_ptr;
this.str_ptr_ptr = _str_ptr_ptr;
Expand All @@ -364,21 +365,40 @@ export class JsInterpreter {
this.last_start_pos = this.view.getUint32(this.ptr_ptr, true);
}
this.u8BufPos = this.last_start_pos;
if (metadata & 0x02) {
if (metadata & 0x04) {
len = this.view.getUint32(this.str_len_ptr, true);
ptr = this.view.getUint32(this.str_ptr_ptr, true);
if (metadata & 0x02) {
this.last_str_start = this.view.getUint32(this.str_ptr_ptr, true);
}
// for small strings decoding them in javascript to avoid the overhead of native calls is faster
if (len < 100) {
// the fourth boolean contains information about whether the string is all ascii or utf8
if (metadata & 0x04) {
this.strings = this.batchedAsciiDecode(ptr, len);
// the fourth boolean contains information about whether the string is all ascii or utf8 and small
if (metadata & 0x08) {
pos = this.last_str_start;
this.strings = "";
endRounded = pos + ((len / 4) | 0) * 4;
while (pos < endRounded) {
char = this.view.getUint32(pos);
this.strings += String.fromCharCode(char >> 24, (char & 0x00FF0000) >> 16, (char & 0x0000FF00) >> 8, (char & 0x000000FF));
pos += 4;
}
else {
this.strings = this.utf8Decode(ptr, len);
switch (this.last_str_start + len - pos) {
case 3:
char = this.view.getUint32(pos);
this.strings += String.fromCharCode(char >> 24, (char & 0x00FF0000) >> 16, (char & 0x0000FF00) >> 8);
break;
case 2:
char = this.view.getUint16(pos);
this.strings += String.fromCharCode(char >> 8, char & 0xFF);
break;
case 1:
this.strings += String.fromCharCode(this.view.getUint8(pos));
break;
case 0:
break;
}
}
else {
this.strings = this.decoder.decode(new DataView(this.view.buffer, ptr, len));
this.strings = this.decoder.decode(new DataView(this.view.buffer, this.last_str_start, len));
}
this.strPos = 0;
}
Expand Down Expand Up @@ -508,54 +528,6 @@ export class JsInterpreter {
GetNode(id) {
return this.nodes[id];
}

utf8Decode(start, byteLength) {
pos = start;
end = pos + byteLength;
out = "";
while (pos < end) {
char = this.view.getUint8(pos++);
if ((char & 0x80) === 0) {
// 1 byte
out += String.fromCharCode(char);
} else if ((char & 0xe0) === 0xc0) {
// 2 bytes
out += String.fromCharCode(((char & 0x1f) << 6) | (this.view.getUint8(pos++) & 0x3f));
} else if ((char & 0xf0) === 0xe0) {
// 3 bytes
out += String.fromCharCode(((char & 0x1f) << 12) | ((this.view.getUint8(pos++) & 0x3f) << 6) | (this.view.getUint8(pos++) & 0x3f));
} else if ((char & 0xf8) === 0xf0) {
// 4 bytes
let unit = ((char & 0x07) << 0x12) | ((this.view.getUint8(pos++) & 0x3f) << 0x0c) | ((this.view.getUint8(pos++) & 0x3f) << 0x06) | (this.view.getUint8(pos++) & 0x3f);
if (unit > 0xffff) {
unit -= 0x10000;
out += String.fromCharCode(((unit >>> 10) & 0x3ff) | 0xd800);
unit = 0xdc00 | (unit & 0x3ff);
}
out += String.fromCharCode(unit);
} else {
out += String.fromCharCode(char);
}
}

return out;
}

batchedAsciiDecode(start, byteLength) {
pos = start;
end = pos + byteLength;
out = "";
endRounded = pos + ((byteLength / 4) | 0) * 4;
while (pos < endRounded) {
char = this.view.getUint32(pos);
out += String.fromCharCode(char >> 24, (char & 0x00FF0000) >> 16, (char & 0x0000FF00) >> 8, (char & 0x000000FF));
pos += 4;
}
while (pos < end) {
out += String.fromCharCode(this.view.getUint8(pos++));
}
return out;
}
}

const els = [
Expand Down
2 changes: 1 addition & 1 deletion interpreter_opt.js

Large diffs are not rendered by default.

13 changes: 10 additions & 3 deletions src/batch.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use web_sys::console;

use crate::{builder::MaybeId, ElementBuilder, IntoAttribue, IntoElement, NodeId, WritableText};

// operations that have no booleans can be encoded as a half byte, these are placed first
Expand Down Expand Up @@ -380,7 +382,9 @@ impl Batch {

self.current_op_byte_idx += 1;
if self.current_op_byte_idx - self.current_op_batch_idx < 4 {
self.msg[self.current_op_byte_idx] = u8_op;
unsafe {
*self.msg.get_unchecked_mut(self.current_op_byte_idx) = u8_op;
}
} else {
self.current_op_batch_idx = self.msg.len();
self.current_op_byte_idx = self.current_op_batch_idx;
Expand All @@ -390,8 +394,8 @@ impl Batch {
let len = self.msg.len();
self.msg.reserve(4);
self.msg.set_len(len + 4);
*self.msg.get_unchecked_mut(self.current_op_batch_idx) = u8_op;
}
self.msg[self.current_op_batch_idx] = u8_op;
}
self.current_op_bit_pack_index = 0;
}
Expand All @@ -400,7 +404,10 @@ impl Batch {
pub(crate) fn encode_bool(&mut self, value: bool) {
if self.current_op_bit_pack_index < 3 {
if value {
self.msg[self.current_op_byte_idx] |= 1 << (self.current_op_bit_pack_index + 5);
unsafe {
*self.msg.get_unchecked_mut(self.current_op_byte_idx) |=
1 << (self.current_op_bit_pack_index + 5);
}
}
self.current_op_bit_pack_index += 1;
} else {
Expand Down
Loading

0 comments on commit f7b2b64

Please sign in to comment.