mirror of
https://github.com/encounter/objdiff.git
synced 2025-06-07 07:03:39 +00:00
wasm: Cache objects via data hash (XXH3)
This commit is contained in:
parent
311de887ec
commit
7b00a9e9f2
15
Cargo.lock
generated
15
Cargo.lock
generated
@ -3280,7 +3280,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objdiff-cli"
|
||||
version = "3.0.0-beta.4"
|
||||
version = "3.0.0-beta.5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argp",
|
||||
@ -3303,7 +3303,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objdiff-core"
|
||||
version = "3.0.0-beta.4"
|
||||
version = "3.0.0-beta.5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arm-attr",
|
||||
@ -3356,7 +3356,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objdiff-gui"
|
||||
version = "3.0.0-beta.4"
|
||||
version = "3.0.0-beta.5"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"cfg-if",
|
||||
@ -3392,7 +3392,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "objdiff-wasm"
|
||||
version = "3.0.0-beta.4"
|
||||
version = "3.0.0-beta.5"
|
||||
dependencies = [
|
||||
"log",
|
||||
"objdiff-core",
|
||||
@ -3400,6 +3400,7 @@ dependencies = [
|
||||
"talc",
|
||||
"wit-bindgen",
|
||||
"wit-deps",
|
||||
"xxhash-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -6547,6 +6548,12 @@ version = "0.8.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c5b940ebc25896e71dd073bad2dbaa2abfe97b0a391415e22ad1326d9c54e3c4"
|
||||
|
||||
[[package]]
|
||||
name = "xxhash-rust"
|
||||
version = "0.8.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3"
|
||||
|
||||
[[package]]
|
||||
name = "yaxpeax-arch"
|
||||
version = "0.3.2"
|
||||
|
@ -14,7 +14,7 @@ strip = "debuginfo"
|
||||
codegen-units = 1
|
||||
|
||||
[workspace.package]
|
||||
version = "3.0.0-beta.4"
|
||||
version = "3.0.0-beta.5"
|
||||
authors = ["Luke Street <luke@street.dev>"]
|
||||
edition = "2024"
|
||||
license = "MIT OR Apache-2.0"
|
||||
|
@ -25,6 +25,7 @@ std = ["objdiff-core/std"]
|
||||
[dependencies]
|
||||
log = { version = "0.4", default-features = false }
|
||||
regex = { version = "1.11", default-features = false, features = ["unicode-case"] }
|
||||
xxhash-rust = { version = "0.8", default-features = false, features = ["xxh3"] }
|
||||
|
||||
[dependencies.objdiff-core]
|
||||
path = "../objdiff-core"
|
||||
|
4
objdiff-wasm/package-lock.json
generated
4
objdiff-wasm/package-lock.json
generated
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "objdiff-wasm",
|
||||
"version": "3.0.0-beta.4",
|
||||
"version": "3.0.0-beta.5",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "objdiff-wasm",
|
||||
"version": "3.0.0-beta.4",
|
||||
"version": "3.0.0-beta.5",
|
||||
"license": "MIT OR Apache-2.0",
|
||||
"devDependencies": {
|
||||
"@biomejs/biome": "^1.9.3",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "objdiff-wasm",
|
||||
"version": "3.0.0-beta.4",
|
||||
"version": "3.0.0-beta.5",
|
||||
"description": "A local diffing tool for decompilation projects.",
|
||||
"author": {
|
||||
"name": "Luke Street",
|
||||
|
@ -1,6 +1,6 @@
|
||||
use alloc::{
|
||||
format,
|
||||
rc::Rc,
|
||||
rc::{Rc, Weak},
|
||||
str::FromStr,
|
||||
string::{String, ToString},
|
||||
vec::Vec,
|
||||
@ -9,6 +9,7 @@ use core::cell::RefCell;
|
||||
|
||||
use objdiff_core::{diff, obj};
|
||||
use regex::{Regex, RegexBuilder};
|
||||
use xxhash_rust::xxh3::xxh3_64;
|
||||
|
||||
use super::logging;
|
||||
|
||||
@ -41,8 +42,7 @@ impl Guest for Component {
|
||||
fn version() -> String { env!("CARGO_PKG_VERSION").to_string() }
|
||||
}
|
||||
|
||||
#[repr(transparent)]
|
||||
struct ResourceObject(Rc<obj::Object>);
|
||||
struct ResourceObject(Rc<obj::Object>, u64);
|
||||
|
||||
struct ResourceObjectDiff(Rc<obj::Object>, diff::ObjectDiff);
|
||||
|
||||
@ -421,13 +421,49 @@ impl GuestDiffConfig for ResourceDiffConfig {
|
||||
}
|
||||
}
|
||||
|
||||
struct CachedObject(Weak<obj::Object>, u64);
|
||||
|
||||
struct ObjectCache(RefCell<Vec<CachedObject>>);
|
||||
|
||||
impl ObjectCache {
|
||||
#[inline]
|
||||
const fn new() -> Self { Self(RefCell::new(Vec::new())) }
|
||||
}
|
||||
|
||||
impl core::ops::Deref for ObjectCache {
|
||||
type Target = RefCell<Vec<CachedObject>>;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.0 }
|
||||
}
|
||||
|
||||
// Assume single-threaded environment
|
||||
unsafe impl Sync for ObjectCache {}
|
||||
|
||||
static OBJECT_CACHE: ObjectCache = ObjectCache::new();
|
||||
|
||||
impl GuestObject for ResourceObject {
|
||||
fn parse(data: Vec<u8>, diff_config: DiffConfigBorrow) -> Result<Object, String> {
|
||||
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
||||
obj::read::parse(&data, &diff_config)
|
||||
.map(|o| Object::new(ResourceObject(Rc::new(o))))
|
||||
.map_err(|e| e.to_string())
|
||||
let hash = xxh3_64(&data);
|
||||
let mut cached = None;
|
||||
OBJECT_CACHE.borrow_mut().retain(|c| {
|
||||
if c.0.strong_count() == 0 {
|
||||
return false;
|
||||
}
|
||||
if c.1 == hash {
|
||||
cached = c.0.upgrade();
|
||||
}
|
||||
true
|
||||
});
|
||||
if let Some(obj) = cached {
|
||||
return Ok(Object::new(ResourceObject(obj, hash)));
|
||||
}
|
||||
let diff_config = diff_config.get::<ResourceDiffConfig>().0.borrow();
|
||||
let obj = Rc::new(obj::read::parse(&data, &diff_config).map_err(|e| e.to_string())?);
|
||||
OBJECT_CACHE.borrow_mut().push(CachedObject(Rc::downgrade(&obj), hash));
|
||||
Ok(Object::new(ResourceObject(obj, hash)))
|
||||
}
|
||||
|
||||
fn hash(&self) -> u64 { self.1 }
|
||||
}
|
||||
|
||||
impl GuestObjectDiff for ResourceObjectDiff {
|
||||
|
@ -20,6 +20,8 @@ interface diff {
|
||||
data: list<u8>,
|
||||
config: borrow<diff-config>,
|
||||
) -> result<object, string>;
|
||||
|
||||
hash: func() -> u64;
|
||||
}
|
||||
|
||||
resource object-diff {
|
||||
|
Loading…
x
Reference in New Issue
Block a user