From 3298cb790682524f740d3f6bff20ec4d07ed7075 Mon Sep 17 00:00:00 2001 From: OJ Kwon <1210596+kwonoj@users.noreply.github.com> Date: Tue, 24 May 2022 00:19:27 -0700 Subject: [PATCH] feat(plugin): Implement more `SourceMap` apis (#4769) --- .../src/source_map/plugin_source_map_proxy.rs | 53 +++++++++++++++++-- .../swc_plugin_runner/src/imported_fn/mod.rs | 18 ++++++- .../src/imported_fn/source_map.rs | 45 +++++++++++++++- .../swc_internal_plugin/Cargo.lock | 18 +++---- 4 files changed, 119 insertions(+), 15 deletions(-) diff --git a/crates/swc_plugin_proxy/src/source_map/plugin_source_map_proxy.rs b/crates/swc_plugin_proxy/src/source_map/plugin_source_map_proxy.rs index 33bc23cf48b..3aa2b2deac6 100644 --- a/crates/swc_plugin_proxy/src/source_map/plugin_source_map_proxy.rs +++ b/crates/swc_plugin_proxy/src/source_map/plugin_source_map_proxy.rs @@ -9,6 +9,16 @@ use crate::memory_interop::read_returned_result_from_host_fallible; #[cfg(target_arch = "wasm32")] extern "C" { fn __lookup_char_pos_source_map_proxy(byte_pos: u32, allocated_ret_ptr: i32) -> i32; + fn __doctest_offset_line_proxy(orig: u32) -> u32; + fn __merge_spans_proxy( + lhs_lo: u32, + lhs_hi: u32, + lhs_ctxt: u32, + rhs_lo: u32, + rhs_hi: u32, + rhs_ctxt: u32, + allocated_ptr: i32, + ) -> i32; } #[cfg(feature = "plugin-mode")] @@ -44,14 +54,51 @@ impl SourceMapper for PluginSourceMapProxy { } fn merge_spans(&self, sp_lhs: Span, sp_rhs: Span) -> Option { - unimplemented!("Not implemented yet"); + #[cfg(target_arch = "wasm32")] + unsafe { + // We need to `allocate` memory, force creates empty span instead of DUMMY_SP + let span = Span { + lo: BytePos(0), + hi: BytePos(0), + ctxt: swc_common::SyntaxContext::empty(), + }; + + let serialized = + swc_common::plugin::Serialized::serialize(&span).expect("Should be serializable"); + let serialized_ref = serialized.as_ref(); + let ptr = serialized_ref.as_ptr(); + let len = serialized_ref.len(); + + let ret = __merge_spans_proxy( + sp_lhs.lo.0, + sp_lhs.hi.0, + sp_lhs.ctxt.as_u32(), + sp_rhs.lo.0, + sp_rhs.hi.0, + sp_rhs.ctxt.as_u32(), + ptr as _, + ); + + return if ret == 1 { Some(span) } else { None }; + }; + + #[cfg(not(target_arch = "wasm32"))] + unimplemented!("Sourcemap proxy cannot be called in this context") } fn call_span_if_macro(&self, sp: Span) -> Span { - unimplemented!("Not implemented yet"); + // This mimics host's behavior + // https://github.com/swc-project/swc/blob/f7dc3fff1f03c9b7cee27ef760dc11bc96083f60/crates/swc_common/src/source_map.rs#L1283-L1285= + sp } fn doctest_offset_line(&self, line: usize) -> usize { - unimplemented!("Not implemented yet"); + #[cfg(target_arch = "wasm32")] + unsafe { + return __doctest_offset_line_proxy(line as u32) as usize; + }; + + #[cfg(not(target_arch = "wasm32"))] + unimplemented!("Sourcemap proxy cannot be called in this context") } } diff --git a/crates/swc_plugin_runner/src/imported_fn/mod.rs b/crates/swc_plugin_runner/src/imported_fn/mod.rs index 7f85e0e87a2..ec3af7637bf 100644 --- a/crates/swc_plugin_runner/src/imported_fn/mod.rs +++ b/crates/swc_plugin_runner/src/imported_fn/mod.rs @@ -72,7 +72,9 @@ mod span; use handler::*; use hygiene::*; -use self::source_map::{lookup_char_pos_proxy, SourceMapHostEnvironment}; +use self::source_map::{ + doctest_offset_line_proxy, lookup_char_pos_proxy, merge_spans_proxy, SourceMapHostEnvironment, +}; /// Create an ImportObject includes functions to be imported from host to the /// plugins. @@ -213,6 +215,18 @@ pub(crate) fn build_import_object( lookup_char_pos_proxy, ); + let doctest_offset_line_fn_decl = Function::new_native_with_env( + wasmer_store, + SourceMapHostEnvironment::new(&source_map, &source_map_buffer), + doctest_offset_line_proxy, + ); + + let merge_spans_fn_decl = Function::new_native_with_env( + wasmer_store, + SourceMapHostEnvironment::new(&source_map, &source_map_buffer), + merge_spans_proxy, + ); + imports! { "env" => { // transform @@ -248,6 +262,8 @@ pub(crate) fn build_import_object( "__add_pure_comment_proxy" => add_pure_comment_fn_decl, // source_map "__lookup_char_pos_source_map_proxy" =>lookup_char_pos_source_map_fn_decl, + "__doctest_offset_line_proxy" => doctest_offset_line_fn_decl, + "__merge_spans_proxy" => merge_spans_fn_decl, } } } diff --git a/crates/swc_plugin_runner/src/imported_fn/source_map.rs b/crates/swc_plugin_runner/src/imported_fn/source_map.rs index 03a2e0ce977..77382e71227 100644 --- a/crates/swc_plugin_runner/src/imported_fn/source_map.rs +++ b/crates/swc_plugin_runner/src/imported_fn/source_map.rs @@ -1,10 +1,10 @@ use std::sync::Arc; use parking_lot::Mutex; -use swc_common::{plugin::Serialized, BytePos, SourceMap}; +use swc_common::{plugin::Serialized, BytePos, SourceMap, Span, SyntaxContext}; use wasmer::{LazyInit, Memory, NativeFunc}; -use crate::memory_interop::allocate_return_values_into_guest; +use crate::memory_interop::{allocate_return_values_into_guest, write_into_memory_view}; /// External environment state for imported (declared in host, injected into /// guest) fn for source map proxy. @@ -59,3 +59,44 @@ pub fn lookup_char_pos_proxy( 0 } } + +pub fn doctest_offset_line_proxy(env: &SourceMapHostEnvironment, orig: u32) -> u32 { + (env.source_map.lock()).doctest_offset_line(orig as usize) as u32 +} + +#[allow(clippy::too_many_arguments)] +pub fn merge_spans_proxy( + env: &SourceMapHostEnvironment, + lhs_lo: u32, + lhs_hi: u32, + lhs_ctxt: u32, + rhs_lo: u32, + rhs_hi: u32, + rhs_ctxt: u32, + allocated_ptr: i32, +) -> i32 { + if let Some(memory) = env.memory_ref() { + let sp_lhs = Span { + lo: BytePos(lhs_lo), + hi: BytePos(lhs_hi), + ctxt: SyntaxContext::from_u32(lhs_ctxt), + }; + + let sp_rhs = Span { + lo: BytePos(rhs_lo), + hi: BytePos(rhs_hi), + ctxt: SyntaxContext::from_u32(rhs_ctxt), + }; + + let ret = (env.source_map.lock()).merge_spans(sp_lhs, sp_rhs); + if let Some(span) = ret { + let serialized_bytes = Serialized::serialize(&span).expect("Should be serializable"); + write_into_memory_view(memory, &serialized_bytes, |_| allocated_ptr); + 1 + } else { + 0 + } + } else { + 0 + } +} diff --git a/tests/rust-plugins/swc_internal_plugin/Cargo.lock b/tests/rust-plugins/swc_internal_plugin/Cargo.lock index 496355abb77..f3f0b7378d7 100644 --- a/tests/rust-plugins/swc_internal_plugin/Cargo.lock +++ b/tests/rust-plugins/swc_internal_plugin/Cargo.lock @@ -717,7 +717,7 @@ dependencies = [ [[package]] name = "swc_common" -version = "0.17.25" +version = "0.18.7" dependencies = [ "ahash", "anyhow", @@ -743,11 +743,12 @@ dependencies = [ [[package]] name = "swc_ecma_ast" -version = "0.77.2" +version = "0.78.1" dependencies = [ "is-macro", "num-bigint", "rkyv", + "scoped-tls", "serde", "string_enum", "swc_atoms", @@ -757,7 +758,7 @@ dependencies = [ [[package]] name = "swc_ecma_parser" -version = "0.103.1" +version = "0.104.2" dependencies = [ "either", "enum_kind", @@ -770,12 +771,11 @@ dependencies = [ "swc_ecma_ast", "tracing", "typed-arena", - "unicode-id", ] [[package]] name = "swc_ecma_utils" -version = "0.84.0" +version = "0.85.1" dependencies = [ "indexmap", "once_cell", @@ -788,7 +788,7 @@ dependencies = [ [[package]] name = "swc_ecma_visit" -version = "0.63.1" +version = "0.64.0" dependencies = [ "num-bigint", "swc_atoms", @@ -800,7 +800,7 @@ dependencies = [ [[package]] name = "swc_ecmascript" -version = "0.155.0" +version = "0.157.0" dependencies = [ "swc_ecma_ast", "swc_ecma_parser", @@ -838,7 +838,7 @@ dependencies = [ [[package]] name = "swc_plugin" -version = "0.52.0" +version = "0.54.0" dependencies = [ "swc_atoms", "swc_common", @@ -858,7 +858,7 @@ dependencies = [ [[package]] name = "swc_plugin_proxy" -version = "0.2.2" +version = "0.3.0" dependencies = [ "better_scoped_tls", "rkyv",