Skip to content

feat(swc/common): wrap serialized struct with versioned (#5060: Part 3) #5128

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jul 7, 2022
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 34 additions & 10 deletions crates/swc/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,10 @@ impl RustPlugins {
use std::{path::PathBuf, sync::Arc};

use anyhow::Context;
use swc_common::{plugin::PluginSerializedBytes, FileName};
use swc_common::{
plugin::{PluginSerializedBytes, VersionedSerializable},
FileName,
};
use swc_ecma_loader::resolve::Resolve;

// swc_plugin_macro will not inject proxy to the comments if comments is empty
Expand All @@ -92,7 +95,8 @@ impl RustPlugins {
inner: self.comments.clone(),
},
|| {
let mut serialized = PluginSerializedBytes::try_serialize(&n)?;
let program = VersionedSerializable::new(n);
let mut serialized = PluginSerializedBytes::try_serialize(&program)?;

// Run plugin transformation against current program.
// We do not serialize / deserialize between each plugin execution but
Expand All @@ -111,11 +115,19 @@ impl RustPlugins {

let config_json = serde_json::to_string(&p.1)
.context("Failed to serialize plugin config as json")
.and_then(|value| PluginSerializedBytes::try_serialize(&value))?;
.and_then(|value| {
PluginSerializedBytes::try_serialize(&VersionedSerializable::new(
value,
))
})?;

let context_json = serde_json::to_string(&self.plugin_context)
.context("Failed to serialize plugin context as json")
.and_then(|value| PluginSerializedBytes::try_serialize(&value))?;
.and_then(|value| {
PluginSerializedBytes::try_serialize(&VersionedSerializable::new(
value,
))
})?;

let resolved_path = self
.resolver
Expand Down Expand Up @@ -152,7 +164,7 @@ impl RustPlugins {

// Plugin transformation is done. Deserialize transformed bytes back
// into Program
serialized.deserialize()
serialized.deserialize().map(|mut v| v.take())
},
)
}
Expand All @@ -162,7 +174,10 @@ impl RustPlugins {
use std::{path::PathBuf, sync::Arc};

use anyhow::Context;
use swc_common::{plugin::PluginSerializedBytes, FileName};
use swc_common::{
plugin::{PluginSerializedBytes, VersionedSerializable},
FileName,
};
use swc_ecma_loader::resolve::Resolve;

let should_enable_comments_proxy = self.comments.is_some();
Expand All @@ -172,17 +187,26 @@ impl RustPlugins {
inner: self.comments.clone(),
},
|| {
let mut serialized = PluginSerializedBytes::try_serialize(&n)?;
let program = VersionedSerializable::new(n);
let mut serialized = PluginSerializedBytes::try_serialize(&program)?;

if let Some(plugins) = &self.plugins {
for p in plugins {
let config_json = serde_json::to_string(&p.1)
.context("Failed to serialize plugin config as json")
.and_then(|value| PluginSerializedBytes::try_serialize(&value))?;
.and_then(|value| {
PluginSerializedBytes::try_serialize(&VersionedSerializable::new(
value,
))
})?;

let context_json = serde_json::to_string(&self.plugin_context)
.context("Failed to serialize plugin context as json")
.and_then(|value| PluginSerializedBytes::try_serialize(&value))?;
.and_then(|value| {
PluginSerializedBytes::try_serialize(&VersionedSerializable::new(
value,
))
})?;

serialized = swc_plugin_runner::apply_transform_plugin(
&p.0,
Expand All @@ -197,7 +221,7 @@ impl RustPlugins {
}
}

serialized.deserialize()
serialized.deserialize().map(|mut v| v.take())
},
)
}
Expand Down
10 changes: 10 additions & 0 deletions crates/swc_common/src/comments.rs
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,16 @@ pub struct Comment {
pub text: String,
}

impl Default for Comment {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this still required, even if we add into_inner()?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

default was added to satisfy mem::take in VersionedSerializable::take. if there's other way default is not required mandatoriliy.

I'm bit unsure if I understood the suggestion correctly, mind elaborate bit more? The way I understood is let each struct implement Take::dummy() instead of default, and VersionedSerializable should utilize it for the take. Not sure where into_inner plays in here.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

into_inner take ownership of VersionedSerializable so it does not require take(&mut self.0.1).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Default constraint comes from it.

fn default() -> Self {
Comment {
kind: CommentKind::Line,
span: DUMMY_SP,
text: "".into(),
}
}
}

impl Spanned for Comment {
fn span(&self) -> Span {
self.span
Expand Down
13 changes: 13 additions & 0 deletions crates/swc_common/src/errors/diagnostic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,19 @@ pub struct Diagnostic {
pub suggestions: Vec<CodeSuggestion>,
}

impl Default for Diagnostic {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

fn default() -> Self {
Diagnostic {
level: Level::Bug,
message: vec![],
code: None,
span: MultiSpan::new(),
children: vec![],
suggestions: vec![],
}
}
}

#[derive(Clone, Debug, PartialEq, Eq, Hash)]
#[cfg_attr(
feature = "diagnostic-serde",
Expand Down
18 changes: 12 additions & 6 deletions crates/swc_common/src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,12 @@ pub enum PluginError {
Serialize(String),
}

impl Default for PluginError {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

fn default() -> Self {
PluginError::Deserialize("Default serialization error".to_string())
}
}

/// Wraps internal representation of serialized data for exchanging data between
/// plugin to the host. Consumers should not rely on specific details of byte
/// format struct contains: it is strict implementation detail which can
Expand All @@ -62,12 +68,12 @@ impl PluginSerializedBytes {
}

/**
* Constructs an instance from given struct by serializing it.
* Constructs an instance from versioned struct by serializing it.
*
* This is sort of mimic TryFrom behavior, since we can't use generic
* to implement TryFrom trait
*/
pub fn try_serialize<W>(t: &W) -> Result<Self, Error>
pub fn try_serialize<W>(t: &VersionedSerializable<W>) -> Result<Self, Error>
where
W: rkyv::Serialize<rkyv::ser::serializers::AllocSerializer<512>>,
{
Expand Down Expand Up @@ -105,15 +111,15 @@ impl PluginSerializedBytes {
(self.field.as_ptr(), self.field.len())
}

pub fn deserialize<W>(&self) -> Result<W, Error>
pub fn deserialize<W>(&self) -> Result<VersionedSerializable<W>, Error>
where
W: rkyv::Archive,
W::Archived: rkyv::Deserialize<W, rkyv::de::deserializers::SharedDeserializeMap>,
{
use anyhow::Context;
use rkyv::Deserialize;

let archived = unsafe { rkyv::archived_root::<W>(&self.field[..]) };
let archived = unsafe { rkyv::archived_root::<VersionedSerializable<W>>(&self.field[..]) };

archived
.deserialize(&mut rkyv::de::deserializers::SharedDeserializeMap::new())
Expand All @@ -130,7 +136,7 @@ impl PluginSerializedBytes {
pub unsafe fn deserialize_from_ptr<W>(
raw_allocated_ptr: *const u8,
raw_allocated_ptr_len: i32,
) -> Result<W, Error>
) -> Result<VersionedSerializable<W>, Error>
where
W: rkyv::Archive,
W::Archived: rkyv::Deserialize<W, rkyv::de::deserializers::SharedDeserializeMap>,
Expand All @@ -153,7 +159,7 @@ where
pub unsafe fn deserialize_from_ptr_into_fallible<W>(
raw_allocated_ptr: *const u8,
raw_allocated_ptr_len: i32,
) -> Result<W, Error>
) -> Result<VersionedSerializable<W>, Error>
where
W: rkyv::Archive,
W::Archived: rkyv::Deserialize<W, rkyv::de::deserializers::SharedDeserializeMap>,
Expand Down
32 changes: 28 additions & 4 deletions crates/swc_common/src/syntax_pos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,12 @@ pub enum FileName {
Custom(String),
}

impl Default for FileName {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

fn default() -> Self {
FileName::Anon
}
}

/// A wrapper that attempts to convert a type to and from UTF-8.
///
/// Types like `OsString` and `PathBuf` aren't guaranteed to be encoded as
Expand Down Expand Up @@ -805,7 +811,7 @@ impl Sub<BytePos> for NonNarrowChar {
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
)]
#[cfg_attr(feature = "rkyv", archive_attr(repr(C), derive(bytecheck::CheckBytes)))]
#[derive(Clone)]
#[derive(Clone, Default)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

pub struct SourceFile {
/// The name of the file that the source came from. Source that doesn't
/// originate from files has names between angle brackets by convention,
Expand Down Expand Up @@ -998,7 +1004,9 @@ pub trait Pos {
/// - Values larger than `u32::MAX - 2^16` are reserved for the comments.
///
/// `u32::MAX` is special value used to generate source map entries.
#[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize)]
#[derive(
Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Serialize, Deserialize, Default,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

)]
#[serde(transparent)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
#[cfg_attr(
Expand Down Expand Up @@ -1032,7 +1040,7 @@ impl BytePos {
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
)]
#[cfg_attr(feature = "rkyv", archive_attr(repr(C), derive(bytecheck::CheckBytes)))]
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug)]
#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, Debug, Default)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

pub struct CharPos(pub usize);

// FIXME: Lots of boilerplate in these impls, but so far my attempts to fix
Expand Down Expand Up @@ -1128,7 +1136,7 @@ impl Sub for CharPos {
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
)]
#[cfg_attr(feature = "rkyv", archive_attr(repr(C), derive(bytecheck::CheckBytes)))]
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Default)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

pub struct Loc {
/// Information about the original source
pub file: Lrc<SourceFile>,
Expand Down Expand Up @@ -1169,6 +1177,15 @@ pub struct SourceFileAndBytePos {
pub pos: BytePos,
}

impl Default for SourceFileAndBytePos {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

fn default() -> Self {
SourceFileAndBytePos {
sf: Lrc::new(SourceFile::default()),
pos: Default::default(),
}
}
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
#[cfg_attr(
feature = "rkyv",
Expand All @@ -1193,6 +1210,7 @@ pub struct LineCol {
pub col: u32,
}

#[derive(Default)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

#[cfg_attr(
feature = "rkyv",
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
Expand Down Expand Up @@ -1224,6 +1242,12 @@ pub enum SpanLinesError {
DistinctSources(DistinctSources),
}

impl Default for SpanLinesError {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

fn default() -> Self {
SpanLinesError::IllFormedSpan(DUMMY_SP)
}
}

#[derive(Clone, PartialEq, Eq, Debug)]
pub enum SpanSnippetError {
DummyBytePos,
Expand Down
20 changes: 13 additions & 7 deletions crates/swc_common/src/syntax_pos/hygiene.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ struct MarkData {
is_builtin: bool,
}

#[derive(Default)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same here

#[cfg_attr(
feature = "rkyv",
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
Expand Down Expand Up @@ -179,9 +180,10 @@ impl Mark {
pub fn is_descendant_of(mut self, ancestor: Mark) -> bool {
// This code path executed inside of the guest memory context.
// In here, preallocate memory for the context.
let serialized =
crate::plugin::PluginSerializedBytes::try_serialize(&MutableMarkContext(0, 0, 0))
.expect("Should be serializable");
let serialized = crate::plugin::PluginSerializedBytes::try_serialize(
&crate::plugin::VersionedSerializable::new(MutableMarkContext(0, 0, 0)),
)
.expect("Should be serializable");
let (ptr, len) = serialized.as_ptr();

// Calling host proxy fn. Inside of host proxy, host will
Expand All @@ -197,6 +199,7 @@ impl Mark {
len.try_into().expect("Should able to convert ptr length"),
)
.expect("Should able to deserialize")
.take()
};
self = Mark::from_u32(context.0);

Expand All @@ -219,9 +222,10 @@ impl Mark {
#[allow(unused_mut, unused_assignments)]
#[cfg(all(feature = "plugin-mode", target_arch = "wasm32"))]
pub fn least_ancestor(mut a: Mark, mut b: Mark) -> Mark {
let serialized =
crate::plugin::PluginSerializedBytes::try_serialize(&MutableMarkContext(0, 0, 0))
.expect("Should be serializable");
let serialized = crate::plugin::PluginSerializedBytes::try_serialize(
&crate::plugin::VersionedSerializable::new(MutableMarkContext(0, 0, 0)),
)
.expect("Should be serializable");
let (ptr, len) = serialized.as_ptr();

unsafe {
Expand All @@ -234,6 +238,7 @@ impl Mark {
len.try_into().expect("Should able to convert ptr length"),
)
.expect("Should able to deserialize")
.take()
};
a = Mark::from_u32(context.0);
b = Mark::from_u32(context.1);
Expand Down Expand Up @@ -383,7 +388,7 @@ impl SyntaxContext {

#[cfg(all(feature = "plugin-mode", target_arch = "wasm32"))]
pub fn remove_mark(&mut self) -> Mark {
let context = MutableMarkContext(0, 0, 0);
let context = crate::plugin::VersionedSerializable::new(MutableMarkContext(0, 0, 0));
let serialized = crate::plugin::PluginSerializedBytes::try_serialize(&context)
.expect("Should be serializable");
let (ptr, len) = serialized.as_ptr();
Expand All @@ -398,6 +403,7 @@ impl SyntaxContext {
len.try_into().expect("Should able to convert ptr length"),
)
.expect("Should able to deserialize")
.take()
};

*self = SyntaxContext(context.0);
Expand Down
8 changes: 6 additions & 2 deletions crates/swc_plugin/src/handler.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
use swc_common::{plugin::PluginSerializedBytes, sync::OnceCell};
use swc_common::{
plugin::{PluginSerializedBytes, VersionedSerializable},
sync::OnceCell,
};

use crate::pseudo_scoped_key::PseudoScopedKey;

Expand All @@ -18,7 +21,8 @@ pub struct PluginDiagnosticsEmitter;
impl swc_common::errors::Emitter for PluginDiagnosticsEmitter {
#[cfg_attr(not(target_arch = "wasm32"), allow(unused))]
fn emit(&mut self, db: &swc_common::errors::DiagnosticBuilder<'_>) {
let diag = PluginSerializedBytes::try_serialize(&*db.diagnostic)
let diagnostic = VersionedSerializable::new((*db.diagnostic).clone());
let diag = PluginSerializedBytes::try_serialize(&diagnostic)
.expect("Should able to serialize Diagnostic");
let (ptr, len) = diag.as_ptr();

Expand Down
2 changes: 1 addition & 1 deletion crates/swc_plugin/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
// Reexports
pub use swc_common::{
chain,
plugin::{deserialize_from_ptr, PluginError, PluginSerializedBytes},
plugin::{deserialize_from_ptr, PluginError, PluginSerializedBytes, VersionedSerializable},
};

pub mod comments {
Expand Down
Loading