feat(plugin): Implement more SourceMap apis (#4769)

This commit is contained in:
OJ Kwon 2022-05-24 00:19:27 -07:00 committed by GitHub
parent 6fd58b0d8b
commit 3298cb7906
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 119 additions and 15 deletions

View File

@ -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<Span> {
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")
}
}

View File

@ -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,
}
}
}

View File

@ -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
}
}

View File

@ -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",