diff --git a/Cargo.lock b/Cargo.lock index a97661393..096639111 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2361,6 +2361,26 @@ version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f" +[[package]] +name = "linkme" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22bcb06ef182e7557cf18d85bd151319d657bd8f699d381435781871f3027af8" +dependencies = [ + "linkme-impl", +] + +[[package]] +name = "linkme-impl" +version = "0.3.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83f2011c1121c45eb4d9639cf5dcbae9622d2978fc5e922a346bfdc6c46700b5" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "linux-raw-sys" version = "0.1.4" @@ -3463,6 +3483,7 @@ dependencies = [ "generational-arena", "indexmap", "instant", + "linkme", "lzma-rs", "nellymoser-rs", "num-derive", diff --git a/core/Cargo.toml b/core/Cargo.toml index a759e02d0..f8f4aba7d 100644 --- a/core/Cargo.toml +++ b/core/Cargo.toml @@ -8,6 +8,7 @@ repository.workspace = true version.workspace = true [dependencies] +linkme = { version = "0.3", optional = true } byteorder = "1.4" bitstream-io = "1.6.0" flate2 = "1.0.25" @@ -64,6 +65,7 @@ timeline_debug = [] mp3 = ["symphonia"] nellymoser = ["nellymoser-rs"] audio = ["dasp"] +known_stubs = ["linkme"] [build-dependencies] build_playerglobal = { path = "build_playerglobal" } diff --git a/core/src/avm1.rs b/core/src/avm1.rs index f46930e85..84b06d6f9 100644 --- a/core/src/avm1.rs +++ b/core/src/avm1.rs @@ -63,3 +63,31 @@ macro_rules! avm_error { } ) } + +#[macro_export] +macro_rules! avm1_stub { + ($activation: ident, $class: literal, $method: literal) => { + #[cfg_attr( + feature = "known_stubs", + linkme::distributed_slice($crate::stub::KNOWN_STUBS) + )] + static STUB: $crate::stub::Stub = $crate::stub::Stub::Avm1Method { + class: $class, + method: $method, + specifics: None, + }; + $activation.context.stub_tracker.encounter(&STUB); + }; + ($activation: ident, $class: literal, $method: literal, $specifics: literal) => { + #[cfg_attr( + feature = "known_stubs", + linkme::distributed_slice($crate::stub::KNOWN_STUBS) + )] + static STUB: $crate::stub::Stub = $crate::stub::Stub::Avm1Method { + class: $class, + method: $method, + specifics: Some(Cow::Borrowed($specifics)), + }; + $activation.context.stub_tracker.encounter(&STUB); + }; +} diff --git a/core/src/stub.rs b/core/src/stub.rs index 7e1bedad6..82830c6a3 100644 --- a/core/src/stub.rs +++ b/core/src/stub.rs @@ -3,12 +3,16 @@ use std::borrow::Cow; use std::collections::hash_set::Iter; use std::fmt::{Debug, Display, Formatter}; +#[cfg(feature = "known_stubs")] +#[linkme::distributed_slice] +pub static KNOWN_STUBS: [Stub] = [..]; + #[derive(Ord, PartialOrd, Eq, PartialEq, Hash, Debug, Clone)] pub enum Stub { Avm1Method { class: &'static str, method: &'static str, - specifics: Option>, + specifics: Option<&'static str>, }, Other(Cow<'static, str>), } @@ -45,10 +49,10 @@ impl StubCollection { Self::default() } - pub fn encounter(&mut self, stub: Stub) { - if !self.inner.contains(&stub) { + pub fn encounter(&mut self, stub: &Stub) { + if !self.inner.contains(stub) { tracing::warn!("Encountered stub: {stub}"); - self.inner.insert(stub); + self.inner.insert(stub.clone()); } }