From d2c1f45f5a1a1d72fa6d6fa28bd84f242d5aff81 Mon Sep 17 00:00:00 2001 From: OJ Kwon <1210596+kwonoj@users.noreply.github.com> Date: Fri, 5 May 2023 20:54:25 -0700 Subject: [PATCH] feat(plugin): Enable bytecheck (#7280) **Description:** Second attempt to enable bytecheck. This PR does not have versioned struct yet, just enabling bytecheck wherever possible. Also, it is for the ast only yet, so transform metadata and others might need this later. PR seems to be passing all the ci, but as we've experienced before, there might be some unexpected outcomes with the release. Maybe better to hold this until clear https://github.com/swc-project/swc/issues/7238, then land as a separate release. --- Cargo.lock | 39 ++-------------- crates/ast_node/src/lib.rs | 4 ++ crates/swc_atoms/Cargo.toml | 4 +- crates/swc_atoms/src/lib.rs | 24 +++++----- crates/swc_common/Cargo.toml | 29 ++++++------ crates/swc_common/src/errors/diagnostic.rs | 8 ++++ crates/swc_common/src/errors/mod.rs | 10 +++++ crates/swc_common/src/errors/snippet.rs | 2 + crates/swc_common/src/plugin/diagnostics.rs | 2 + crates/swc_common/src/plugin/serialized.rs | 2 + crates/swc_common/src/syntax_pos.rs | 44 ++++++++++++++++++- crates/swc_common/src/syntax_pos/hygiene.rs | 4 ++ crates/swc_common/tests/attr_interop.rs | 2 + crates/swc_ecma_ast/Cargo.toml | 19 +++++--- crates/swc_ecma_ast/src/class.rs | 2 + crates/swc_ecma_ast/src/decl.rs | 2 + crates/swc_ecma_ast/src/expr.rs | 6 +++ crates/swc_ecma_ast/src/ident.rs | 2 + crates/swc_ecma_ast/src/lit.rs | 4 +- crates/swc_ecma_ast/src/operators.rs | 8 ++++ crates/swc_ecma_ast/src/typescript.rs | 8 ++++ .../read_returned_result_from_host.rs | 2 + 22 files changed, 156 insertions(+), 71 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index eedea55d7e4..9bd9a0d3dec 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2747,15 +2747,6 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a49a831dc1e13c9392b660b162333d4cb0033bbbdfe6a1687177e59e89037c86" -[[package]] -name = "rend" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "79af64b4b6362ffba04eef3a4e10829718a4896dac19daa741851c86781edf95" -dependencies = [ - "bytecheck", -] - [[package]] name = "rend" version = "0.4.0" @@ -2812,25 +2803,11 @@ dependencies = [ "hashbrown 0.12.3", "indexmap", "ptr_meta", - "rend 0.4.0", + "rend", "rkyv_derive", "seahash", ] -[[package]] -name = "rkyv-test" -version = "0.7.38-test.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddf47bca568385a5121422d265f8ea7ca2c8816141e29fd415498eabb150f14e" -dependencies = [ - "bytecheck", - "hashbrown 0.12.3", - "ptr_meta", - "rend 0.3.6", - "rkyv_derive_test", - "seahash", -] - [[package]] name = "rkyv_derive" version = "0.7.41" @@ -2842,17 +2819,6 @@ dependencies = [ "syn 1.0.109", ] -[[package]] -name = "rkyv_derive_test" -version = "0.7.38-test.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e573710463b17b3cc3c5de19cc12118a788392b056ff097c6ee700920a4545ce" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "rustc-demangle" version = "0.1.21" @@ -3467,6 +3433,7 @@ dependencies = [ name = "swc_atoms" version = "0.5.3" dependencies = [ + "bytecheck", "once_cell", "rkyv", "rustc-hash", @@ -3543,6 +3510,7 @@ dependencies = [ "atty", "better_scoped_tls", "bitflags 2.1.0", + "bytecheck", "cfg-if", "criterion", "either", @@ -3553,7 +3521,6 @@ dependencies = [ "parking_lot", "rayon", "rkyv", - "rkyv-test", "rustc-hash", "serde", "serde_json", diff --git a/crates/ast_node/src/lib.rs b/crates/ast_node/src/lib.rs index 2d9b08a13ad..fa5cb1c4fd5 100644 --- a/crates/ast_node/src/lib.rs +++ b/crates/ast_node/src/lib.rs @@ -207,6 +207,8 @@ pub fn ast_node( feature = "rkyv-impl", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] + #[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] + #[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] #[cfg_attr( feature = "rkyv-impl", archive(bound( @@ -272,6 +274,8 @@ pub fn ast_node( feature = "rkyv-impl", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] + #[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] + #[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] #[cfg_attr( feature = "rkyv-impl", archive( diff --git a/crates/swc_atoms/Cargo.toml b/crates/swc_atoms/Cargo.toml index 6dd98cf035b..e5400a78957 100644 --- a/crates/swc_atoms/Cargo.toml +++ b/crates/swc_atoms/Cargo.toml @@ -14,9 +14,11 @@ bench = false [features] __rkyv = [] -rkyv-impl = ["__rkyv", "rkyv"] +rkyv-impl = ["__rkyv", "rkyv", "bytecheck"] [dependencies] +# bytecheck version should be in sync with rkyv version. Do not bump individually. +bytecheck = { version = "0.6.10", optional = true } once_cell = "1" rkyv = { package = "rkyv", version = "=0.7.41", optional = true, features = [ "strict", diff --git a/crates/swc_atoms/src/lib.rs b/crates/swc_atoms/src/lib.rs index 40019b7565c..988cd8755f5 100644 --- a/crates/swc_atoms/src/lib.rs +++ b/crates/swc_atoms/src/lib.rs @@ -42,6 +42,8 @@ include!(concat!(env!("OUT_DIR"), "/js_word.rs")); /// "longer than xx" as this is a type. /// - Raw values. #[derive(Clone)] +#[cfg_attr(feature = "rkyv-impl", derive(rkyv::bytecheck::CheckBytes))] +#[cfg_attr(feature = "rkyv-impl", repr(C))] pub struct Atom(ThinArc, u8>); fn _assert_size() { @@ -275,7 +277,7 @@ impl PartialEq for str { } /// NOT A PUBLIC API -#[cfg(feature = "__rkyv")] +#[cfg(feature = "rkyv-impl")] impl rkyv::Archive for Atom { type Archived = rkyv::string::ArchivedString; type Resolver = rkyv::string::StringResolver; @@ -287,7 +289,7 @@ impl rkyv::Archive for Atom { } /// NOT A PUBLIC API -#[cfg(feature = "__rkyv")] +#[cfg(feature = "rkyv-impl")] impl rkyv::Serialize for Atom { fn serialize(&self, serializer: &mut S) -> Result { String::serialize(&self.to_string(), serializer) @@ -295,7 +297,7 @@ impl rkyv::Serialize for Atom { } /// NOT A PUBLIC API -#[cfg(feature = "__rkyv")] +#[cfg(feature = "rkyv-impl")] impl rkyv::Deserialize for rkyv::string::ArchivedString where D: ?Sized + rkyv::Fallible, @@ -310,11 +312,13 @@ where /// NOT A PUBLIC API. /// /// This type exists to allow serializing [JsWord] using `rkyv`. -#[cfg(feature = "__rkyv")] +#[cfg(feature = "rkyv-impl")] #[derive(Debug, Clone, Copy)] +#[cfg_attr(feature = "rkyv-impl", derive(rkyv::bytecheck::CheckBytes))] +#[cfg_attr(feature = "rkyv-impl", repr(C))] pub struct EncodeJsWord; -#[cfg(feature = "__rkyv")] +#[cfg(feature = "rkyv-impl")] impl rkyv::with::ArchiveWith for EncodeJsWord { type Archived = rkyv::Archived; type Resolver = rkyv::Resolver; @@ -332,7 +336,7 @@ impl rkyv::with::ArchiveWith for EncodeJsWord { } } -#[cfg(feature = "__rkyv")] +#[cfg(feature = "rkyv-impl")] impl rkyv::with::SerializeWith for EncodeJsWord where S: ?Sized + rkyv::ser::Serializer, @@ -345,7 +349,7 @@ where } } -#[cfg(feature = "__rkyv")] +#[cfg(feature = "rkyv-impl")] impl rkyv::with::DeserializeWith, crate::JsWord, D> for EncodeJsWord where D: ?Sized + rkyv::Fallible, @@ -362,7 +366,7 @@ where } } -#[cfg(feature = "__rkyv")] +#[cfg(feature = "rkyv-impl")] impl rkyv::with::ArchiveWith> for EncodeJsWord { type Archived = rkyv::Archived>; type Resolver = rkyv::Resolver>; @@ -380,7 +384,7 @@ impl rkyv::with::ArchiveWith> for EncodeJsWord { } } -#[cfg(feature = "__rkyv")] +#[cfg(feature = "rkyv-impl")] impl rkyv::with::SerializeWith, S> for EncodeJsWord where S: ?Sized + rkyv::ser::Serializer, @@ -396,7 +400,7 @@ where } } -#[cfg(feature = "__rkyv")] +#[cfg(feature = "rkyv-impl")] impl rkyv::with::DeserializeWith>, Option, D> for EncodeJsWord where diff --git a/crates/swc_common/Cargo.toml b/crates/swc_common/Cargo.toml index ff46ba2e397..4284127e266 100644 --- a/crates/swc_common/Cargo.toml +++ b/crates/swc_common/Cargo.toml @@ -34,13 +34,15 @@ plugin_transform_schema_vtest = [] tty-emitter = ["atty", "termcolor"] __rkyv = [] -rkyv-impl = ["__rkyv", "rkyv", "swc_atoms/rkyv-impl"] +rkyv-impl = ["__rkyv", "rkyv", "swc_atoms/rkyv-impl", "bytecheck"] [dependencies] -ahash = "0.7.4" -anyhow = { version = "1.0.45", optional = true } +ahash = "0.7.4" +anyhow = { version = "1.0.45", optional = true } arbitrary = { version = "1", optional = true, features = ["derive"] } -atty = { version = "0.2", optional = true } +atty = { version = "0.2", optional = true } +# bytecheck version should be in sync with rkyv version. Do not bump individually. +bytecheck = { version = "0.6.10", optional = true } cfg-if = "1.0.0" either = "1.5" new_debug_unreachable = "1.0.4" @@ -51,18 +53,15 @@ rkyv = { version = "=0.7.41", optional = true, features = [ "strict", "validation", ] } -# This is to avoid cargo version selection conflict between rkyv=0.7.40 and other versions, as it is strictly pinned -# cannot be merged. -rkyv-latest = { package = "rkyv-test", version = "=0.7.38-test.2", optional = true } -rustc-hash = "1.1.0" -serde = { version = "1.0.119", features = ["derive"] } -siphasher = "0.3.9" -sourcemap = { version = "6", optional = true } -string_cache = "0.8.7" -termcolor = { version = "1.0", optional = true } -tracing = "0.1.32" +rustc-hash = "1.1.0" +serde = { version = "1.0.119", features = ["derive"] } +siphasher = "0.3.9" +sourcemap = { version = "6", optional = true } +string_cache = "0.8.7" +termcolor = { version = "1.0", optional = true } +tracing = "0.1.32" unicode-width = "0.1.4" -url = "2.2.2" +url = "2.2.2" ast_node = { version = "0.9.3", path = "../ast_node" } better_scoped_tls = { version = "0.1.0", path = "../better_scoped_tls" } diff --git a/crates/swc_common/src/errors/diagnostic.rs b/crates/swc_common/src/errors/diagnostic.rs index f6da23d5620..be198a3f2c6 100644 --- a/crates/swc_common/src/errors/diagnostic.rs +++ b/crates/swc_common/src/errors/diagnostic.rs @@ -22,6 +22,8 @@ use crate::syntax_pos::{MultiSpan, Span}; any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct Message(pub String, pub Style); #[must_use] @@ -34,6 +36,8 @@ pub struct Message(pub String, pub Style); any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct Diagnostic { pub level: Level, pub message: Vec, @@ -52,6 +56,8 @@ pub struct Diagnostic { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] pub enum DiagnosticId { Error(String), Lint(String), @@ -67,6 +73,8 @@ pub enum DiagnosticId { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct SubDiagnostic { pub level: Level, pub message: Vec, diff --git a/crates/swc_common/src/errors/mod.rs b/crates/swc_common/src/errors/mod.rs index c8934f03ac9..8f838643a83 100644 --- a/crates/swc_common/src/errors/mod.rs +++ b/crates/swc_common/src/errors/mod.rs @@ -50,6 +50,8 @@ mod styled_buffer; any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] pub enum Applicability { MachineApplicable, HasPlaceholders, @@ -66,6 +68,8 @@ pub enum Applicability { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct CodeSuggestion { /// Each substitute can have multiple variants due to multiple /// applicable suggestions @@ -117,6 +121,8 @@ pub struct CodeSuggestion { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct Substitution { pub parts: Vec, } @@ -130,6 +136,8 @@ pub struct Substitution { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct SubstitutionPart { pub span: Span, pub snippet: String, @@ -877,6 +885,8 @@ impl Handler { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] pub enum Level { Bug, Fatal, diff --git a/crates/swc_common/src/errors/snippet.rs b/crates/swc_common/src/errors/snippet.rs index f1447733e3d..7eb6e85f22a 100644 --- a/crates/swc_common/src/errors/snippet.rs +++ b/crates/swc_common/src/errors/snippet.rs @@ -184,6 +184,8 @@ pub struct StyledString { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] pub enum Style { MainHeaderMsg, HeaderMsg, diff --git a/crates/swc_common/src/plugin/diagnostics.rs b/crates/swc_common/src/plugin/diagnostics.rs index 9d8176b244f..5e72903e9f5 100644 --- a/crates/swc_common/src/plugin/diagnostics.rs +++ b/crates/swc_common/src/plugin/diagnostics.rs @@ -7,6 +7,8 @@ any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct PluginCorePkgDiagnostics { pub pkg_version: String, pub git_sha: String, diff --git a/crates/swc_common/src/plugin/serialized.rs b/crates/swc_common/src/plugin/serialized.rs index 0637d25d4d8..7b905092161 100644 --- a/crates/swc_common/src/plugin/serialized.rs +++ b/crates/swc_common/src/plugin/serialized.rs @@ -10,6 +10,8 @@ use rkyv::Deserialize; feature = "__plugin", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "__plugin", archive(check_bytes))] +#[cfg_attr(feature = "__plugin", archive_attr(repr(u32)))] /// Enum for possible errors while running transform via plugin. /// This error indicates internal operation failure either in plugin_runner /// or plugin_macro. Plugin's transform fn itself does not allow to return diff --git a/crates/swc_common/src/syntax_pos.rs b/crates/swc_common/src/syntax_pos.rs index 775801839f3..0a323ba88d1 100644 --- a/crates/swc_common/src/syntax_pos.rs +++ b/crates/swc_common/src/syntax_pos.rs @@ -34,6 +34,8 @@ pub mod hygiene; any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct Span { #[serde(rename = "start")] #[cfg_attr(feature = "__rkyv", omit_bounds)] @@ -120,6 +122,8 @@ better_scoped_tls::scoped_tls!( any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] #[derive(Debug, Eq, PartialEq, Clone, Ord, PartialOrd, Hash)] pub enum FileName { Real(#[cfg_attr(any(feature = "rkyv-impl"), with(crate::source_map::EncodePathBuf))] PathBuf), @@ -148,8 +152,10 @@ pub enum FileName { /// There is built-in `AsString` supports PathBuf but it requires custom /// serializer wrapper to handle conversion errors. This wrapper is simplified /// version accepts errors -#[cfg(feature = "__rkyv")] +#[cfg(feature = "rkyv-impl")] #[derive(Debug, Clone, Copy)] +#[cfg_attr(feature = "rkyv-impl", derive(rkyv::bytecheck::CheckBytes))] +#[cfg_attr(feature = "rkyv-impl", repr(C))] pub struct EncodePathBuf; #[cfg(any(feature = "rkyv-impl"))] @@ -197,8 +203,10 @@ where } /// A wrapper that attempts to convert a Url to and from String. -#[cfg(feature = "__rkyv")] +#[cfg(feature = "rkyv-impl")] #[derive(Debug, Clone, Copy)] +#[cfg_attr(feature = "rkyv-impl", derive(rkyv::bytecheck::CheckBytes))] +#[cfg_attr(feature = "rkyv-impl", repr(C))] pub struct EncodeUrl; #[cfg(any(feature = "rkyv-impl"))] @@ -307,6 +315,8 @@ impl FileName { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct PrimarySpanLabel(pub Span, pub String); /// A collection of spans. Spans have two orthogonal attributes: @@ -324,6 +334,8 @@ pub struct PrimarySpanLabel(pub Span, pub String); any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct MultiSpan { primary_spans: Vec, span_labels: Vec, @@ -726,6 +738,8 @@ pub const NO_EXPANSION: SyntaxContext = SyntaxContext::empty(); any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub struct MultiByteChar { /// The absolute offset of the character in the SourceMap @@ -754,6 +768,8 @@ impl MultiByteChar { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] #[derive(Copy, Clone, Eq, PartialEq, Debug)] pub enum NonNarrowChar { /// Represents a zero-width character @@ -870,6 +886,8 @@ where any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] #[derive(Clone)] pub struct SourceFile { /// The name of the file that the source came from. Source that doesn't @@ -1090,6 +1108,8 @@ pub trait Pos { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct BytePos(#[cfg_attr(feature = "__rkyv", omit_bounds)] pub u32); impl BytePos { @@ -1117,6 +1137,8 @@ impl BytePos { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)] pub struct CharPos(pub usize); @@ -1230,6 +1252,8 @@ pub struct Loc { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Debug, Clone) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct PartialLoc { pub source_file: Option>, pub line: usize, @@ -1259,6 +1283,8 @@ pub struct SourceFileAndLine { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] #[derive(Debug)] pub struct SourceFileAndBytePos { pub sf: Lrc, @@ -1270,6 +1296,8 @@ pub struct SourceFileAndBytePos { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct LineInfo { /// Index of line, starting from 0. pub line_index: usize, @@ -1306,6 +1334,8 @@ pub struct FileLines { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize, Debug, Clone) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct PartialFileLines { pub file: Option>, pub lines: Vec, @@ -1325,6 +1355,8 @@ pub type PartialFileLinesResult = Result>; any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] pub enum SpanLinesError { IllFormedSpan(Span), DistinctSources(DistinctSources), @@ -1335,6 +1367,8 @@ pub enum SpanLinesError { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] pub enum SpanSnippetError { DummyBytePos, IllFormedSpan(Span), @@ -1348,6 +1382,8 @@ pub enum SpanSnippetError { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct FilePos(pub FileName, pub BytePos); #[derive(Clone, PartialEq, Eq, Debug)] @@ -1355,6 +1391,8 @@ pub struct FilePos(pub FileName, pub BytePos); any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct DistinctSources { pub begin: FilePos, pub end: FilePos, @@ -1365,6 +1403,8 @@ pub struct DistinctSources { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct MalformedSourceMapPositions { pub name: FileName, pub source_len: usize, diff --git a/crates/swc_common/src/syntax_pos/hygiene.rs b/crates/swc_common/src/syntax_pos/hygiene.rs index 790107f688d..2b637b35ad9 100644 --- a/crates/swc_common/src/syntax_pos/hygiene.rs +++ b/crates/swc_common/src/syntax_pos/hygiene.rs @@ -34,6 +34,8 @@ use crate::collections::AHashMap; any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct SyntaxContext(#[cfg_attr(feature = "__rkyv", omit_bounds)] u32); #[cfg(feature = "arbitrary")] @@ -70,6 +72,8 @@ pub(crate) struct MarkData { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct MutableMarkContext(pub u32, pub u32, pub u32); // List of proxy calls injected by the host in the plugin's runtime context. diff --git a/crates/swc_common/tests/attr_interop.rs b/crates/swc_common/tests/attr_interop.rs index 09131a1f84a..2db21d74314 100644 --- a/crates/swc_common/tests/attr_interop.rs +++ b/crates/swc_common/tests/attr_interop.rs @@ -22,6 +22,8 @@ pub struct Tuple(#[span] HasSpan, usize, usize); any(feature = "rkyv-impl"), archive(bound(serialize = "__S: rkyv::ser::Serializer + rkyv::ser::ScratchSpace")) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] pub struct HasSpan { #[cfg_attr(feature = "__rkyv", omit_bounds)] pub span: Span, diff --git a/crates/swc_ecma_ast/Cargo.toml b/crates/swc_ecma_ast/Cargo.toml index 31be5de18da..3c7bfce378e 100644 --- a/crates/swc_ecma_ast/Cargo.toml +++ b/crates/swc_ecma_ast/Cargo.toml @@ -16,16 +16,23 @@ version = "0.103.5" bench = false [features] -__rkyv = [] -default = [] -fuzzing = ["arbitrary", "swc_common/arbitrary"] -rkyv-impl = ["__rkyv", "rkyv", "swc_atoms/rkyv-impl", "swc_common/rkyv-impl"] +__rkyv = [] +default = [] +fuzzing = ["arbitrary", "swc_common/arbitrary"] +rkyv-impl = [ + "__rkyv", + "rkyv", + "bytecheck", + "swc_atoms/rkyv-impl", + "swc_common/rkyv-impl", +] serde-impl = ["serde"] [dependencies] arbitrary = { version = "1", optional = true, features = ["derive"] } -bitflags = "2.1.0" -bytecheck = { version = "0.6.9", optional = true } +bitflags = "2.1.0" +# bytecheck version should be in sync with rkyv version. Do not bump individually. +bytecheck = { version = "0.6.10", optional = true } is-macro = "0.2.1" num-bigint = { version = "0.4", features = ["serde"] } rkyv = { package = "rkyv", version = "=0.7.41", optional = true, features = [ diff --git a/crates/swc_ecma_ast/src/class.rs b/crates/swc_ecma_ast/src/class.rs index 24dbb89db55..ba3762e2fae 100644 --- a/crates/swc_ecma_ast/src/class.rs +++ b/crates/swc_ecma_ast/src/class.rs @@ -251,6 +251,8 @@ pub struct Decorator { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] #[cfg_attr(feature = "serde-impl", derive(serde::Serialize, serde::Deserialize))] pub enum MethodKind { #[cfg_attr(feature = "serde-impl", serde(rename = "method"))] diff --git a/crates/swc_ecma_ast/src/decl.rs b/crates/swc_ecma_ast/src/decl.rs index b1013e29149..eae1493f826 100644 --- a/crates/swc_ecma_ast/src/decl.rs +++ b/crates/swc_ecma_ast/src/decl.rs @@ -118,6 +118,8 @@ impl Take for VarDecl { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] pub enum VarDeclKind { /// `var` Var, diff --git a/crates/swc_ecma_ast/src/expr.rs b/crates/swc_ecma_ast/src/expr.rs index 08be25fb8cc..f45c316778c 100644 --- a/crates/swc_ecma_ast/src/expr.rs +++ b/crates/swc_ecma_ast/src/expr.rs @@ -583,6 +583,8 @@ bridge_expr_from!(ClassExpr, Box); deserialize = "__D: rkyv::de::SharedDeserializeRegistry" )) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] #[derive(Eq, Hash, EqIgnoreSpan)] #[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))] #[cfg_attr(feature = "serde-impl", derive(serde::Serialize))] @@ -940,6 +942,8 @@ pub struct MetaPropExpr { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] pub enum MetaPropKind { /// `new.target` NewTarget, @@ -1129,6 +1133,8 @@ impl Take for Import { deserialize = "__D: rkyv::de::SharedDeserializeRegistry" )) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] #[cfg_attr(feature = "serde-impl", derive(serde::Serialize, serde::Deserialize))] pub struct ExprOrSpread { #[cfg_attr(feature = "serde-impl", serde(default))] diff --git a/crates/swc_ecma_ast/src/ident.rs b/crates/swc_ecma_ast/src/ident.rs index f4e1f10f5bd..2b32a3ed800 100644 --- a/crates/swc_ecma_ast/src/ident.rs +++ b/crates/swc_ecma_ast/src/ident.rs @@ -24,6 +24,8 @@ use crate::typescript::TsTypeAnn; deserialize = "__D: rkyv::de::SharedDeserializeRegistry" )) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(C)))] #[cfg_attr(feature = "serde-impl", derive(serde::Serialize, serde::Deserialize))] pub struct BindingIdent { #[span] diff --git a/crates/swc_ecma_ast/src/lit.rs b/crates/swc_ecma_ast/src/lit.rs index a09d5c1f2f6..f390795476c 100644 --- a/crates/swc_ecma_ast/src/lit.rs +++ b/crates/swc_ecma_ast/src/lit.rs @@ -80,8 +80,10 @@ impl EqIgnoreSpan for BigInt { } } -#[cfg(feature = "__rkyv")] +#[cfg(feature = "rkyv-impl")] #[derive(Debug, Clone, Copy)] +#[cfg_attr(feature = "rkyv-impl", derive(rkyv::bytecheck::CheckBytes))] +#[cfg_attr(feature = "rkyv-impl", repr(C))] pub struct EncodeBigInt; #[cfg(any(feature = "rkyv-impl"))] diff --git a/crates/swc_ecma_ast/src/operators.rs b/crates/swc_ecma_ast/src/operators.rs index ded98f9c36e..7f71d7b7114 100644 --- a/crates/swc_ecma_ast/src/operators.rs +++ b/crates/swc_ecma_ast/src/operators.rs @@ -7,6 +7,8 @@ use swc_common::EqIgnoreSpan; any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] pub enum BinaryOp { /// `==` EqEq, @@ -116,6 +118,8 @@ impl BinaryOp { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] pub enum AssignOp { /// `=` Assign, @@ -189,6 +193,8 @@ impl AssignOp { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] pub enum UpdateOp { /// `++` PlusPlus, @@ -202,6 +208,8 @@ pub enum UpdateOp { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] pub enum UnaryOp { /// `-` Minus, diff --git a/crates/swc_ecma_ast/src/typescript.rs b/crates/swc_ecma_ast/src/typescript.rs index eb0af2b83f8..22a74e83cc1 100644 --- a/crates/swc_ecma_ast/src/typescript.rs +++ b/crates/swc_ecma_ast/src/typescript.rs @@ -398,6 +398,8 @@ pub struct TsKeywordType { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] #[cfg_attr(feature = "serde-impl", derive(serde::Serialize, serde::Deserialize))] pub enum TsKeywordTypeKind { #[cfg_attr(feature = "serde-impl", serde(rename = "any"))] @@ -680,6 +682,8 @@ pub struct TsTypeOperator { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] pub enum TsTypeOperatorOp { /// `keyof` KeyOf, @@ -706,6 +710,8 @@ pub struct TsIndexedAccessType { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] pub enum TruePlusMinus { True, Plus, @@ -1079,6 +1085,8 @@ pub struct TsSatisfiesExpr { any(feature = "rkyv-impl"), derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "rkyv-impl", archive(check_bytes))] +#[cfg_attr(feature = "rkyv-impl", archive_attr(repr(u32)))] #[cfg_attr(feature = "serde-impl", derive(serde::Serialize, serde::Deserialize))] pub enum Accessibility { #[cfg_attr(feature = "serde-impl", serde(rename = "public"))] diff --git a/crates/swc_plugin_proxy/src/memory_interop/read_returned_result_from_host.rs b/crates/swc_plugin_proxy/src/memory_interop/read_returned_result_from_host.rs index 0d52373ef64..b34f35347c6 100644 --- a/crates/swc_plugin_proxy/src/memory_interop/read_returned_result_from_host.rs +++ b/crates/swc_plugin_proxy/src/memory_interop/read_returned_result_from_host.rs @@ -7,6 +7,8 @@ use swc_common::plugin::serialized::{deserialize_from_ptr, PluginSerializedBytes feature = "__rkyv", derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize) )] +#[cfg_attr(feature = "__rkyv", archive(check_bytes))] +#[cfg_attr(feature = "__rkyv", archive_attr(repr(C)))] pub struct AllocatedBytesPtr(pub u32, pub u32); #[cfg(target_arch = "wasm32")]