diff --git a/lib/compiler/src/engine/artifact.rs b/lib/compiler/src/engine/artifact.rs index 2608723a037..2d28c7f4fb3 100644 --- a/lib/compiler/src/engine/artifact.rs +++ b/lib/compiler/src/engine/artifact.rs @@ -96,14 +96,33 @@ impl Artifact { )) } + /// Deserialize a ArtifactBuild /// /// # Safety + /// /// This function is unsafe because rkyv reads directly without validating - /// the data. - pub unsafe fn deserialize(engine: &Engine, bytes: &[u8]) -> Result { + /// the data. This function does not check whether the `Artifact` is an object file + /// (use [`deserialize`] instead) + pub unsafe fn deserialize_unchecked(engine: &Engine, bytes: &[u8]) -> Result { + let bytes = &bytes[ArtifactBuild::MAGIC_HEADER.len()..]; + let metadata_len = MetadataHeader::parse(bytes)?; + let metadata_slice: &[u8] = &bytes[MetadataHeader::LEN..][..metadata_len]; + let serializable = SerializableModule::deserialize(metadata_slice)?; + let artifact = ArtifactBuild::from_serializable(serializable); + let mut inner_engine = engine.inner_mut(); + Self::from_parts(&mut inner_engine, artifact).map_err(DeserializeError::Compiler) + } + + /// Deserialize a ArtifactBuild + /// + /// # Error + /// + /// Returns an error if the bytes are not deserializable. If you don't + /// want this behaviour, use [`deserialize_unchecked`] + pub fn deserialize(engine: &Engine, bytes: &[u8]) -> Result { if !ArtifactBuild::is_deserializable(bytes) { - let static_artifact = Self::deserialize_object(engine, bytes); + let static_artifact = unsafe { Self::deserialize_object(engine, bytes) }; match static_artifact { Ok(v) => { return Ok(v); @@ -116,13 +135,7 @@ impl Artifact { "The provided bytes are not wasmer-universal".to_string(), )); } - let bytes = &bytes[ArtifactBuild::MAGIC_HEADER.len()..]; - let metadata_len = MetadataHeader::parse(bytes)?; - let metadata_slice: &[u8] = &bytes[MetadataHeader::LEN..][..metadata_len]; - let serializable = SerializableModule::deserialize(metadata_slice)?; - let artifact = ArtifactBuild::from_serializable(serializable); - let mut inner_engine = engine.inner_mut(); - Self::from_parts(&mut inner_engine, artifact).map_err(DeserializeError::Compiler) + unsafe { Self::deserialize_unchecked(engine, bytes) } } /// Construct a `ArtifactBuild` from component parts.