Stream: wasmtime

Topic: ✔ Split dwarf - Rust borrowing help ?


view this post on Zulip Scott Waye (Feb 29 2024 at 15:38):

    pub fn read_dwarf_package(
        wasm_file: PathBuf,
    ) -> Option<DwarfPackage<Relocate<'static, gimli::EndianSlice<'static, gimli::LittleEndian>>>>
    {
        let dwp_path = wasm_file.with_extension("dwp");
        match fs::File::open(&dwp_path) {
            Ok(mut file) => {
                let mut buffer = Vec::new();

                if let Err(err) = file.read_to_end(&mut buffer) {
                    eprintln!("Error reading dwarf package: {}", err);
                    return None;
                }

                let object_file = match object::File::parse(&*buffer) {
                    Ok(file) => file,
                    Err(err) => {
                        eprintln!("Failed to parse file '{:?}': {}", dwp_path, err);
                        return None;
                    }
                };

                match Module::load_dwp(object_file) {
                    Ok(package) => Some(package),
                    Err(err) => {
                        eprintln!("Failed to load Dwarf package '{:?}': {}", dwp_path, err);
                        None
                    }
                }
            }
            Err(_) => None,
        }
    }

This RUst fails with

error[E0515]: cannot return value referencing local variable `buffer`
   --> crates\wasmtime\src\runtime\module.rs:326:36
    |
317 |                 let object_file = match object::File::parse(&*buffer) {
    |                                                               ------ `buffer` is borrowed here
...
326 |                     Ok(package) => Some(package),
    |                                    ^^^^^^^^^^^^^ returns a value referencing data owned by the current function

which I understand but I can't find the solution. I've been playing for a few hours with ReadCache and ReadCachedRange to try and move the Vec into ownership by package but my Rust skills are too poor. Any tips for how I can stop the borrow ?

view this post on Zulip Alex Crichton (Feb 29 2024 at 16:12):

I think you'll probably want to refactor this to have the buffer owned on the stack above this function, e.g. the caller reads the dwp file and passes in the buffer. Having buffer owned by the package return value is (if I understand this correctly) a self-borrowing struct which isn't easy to manage in Rust.

Another, perhaps wonky, option would be to use ScopeVec to extend the lifetime of something to a higher lifetime, basically you'd take &ScopeVec<u8> in this function and then scope_vec.push(buffer) would return &[u8] tied to the ScopeVec, not the local stack allocation

view this post on Zulip Scott Waye (Feb 29 2024 at 17:04):

Alex Crichton said:

I think you'll probably want to refactor this to have the buffer owned on the stack above this function, e.g. the caller reads the dwp file and passes in the buffer. Having buffer owned by the package return value is (if I understand this correctly) a self-borrowing struct which isn't easy to manage in Rust.

Another, perhaps wonky, option would be to use ScopeVec to extend the lifetime of something to a higher lifetime, basically you'd take &ScopeVec<u8> in this function and then scope_vec.push(buffer) would return &[u8] tied to the ScopeVec, not the local stack allocation

Thanks!

view this post on Zulip Notification Bot (Feb 29 2024 at 17:04):

Scott Waye has marked this topic as resolved.


Last updated: Nov 22 2024 at 16:03 UTC