Skip to content
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

fix(plugin): Make span_to_source use dedicated function #6853

Merged
merged 17 commits into from
Jan 26, 2023
12 changes: 8 additions & 4 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,14 @@
"crates/swc_html_parser/tests/html5lib-tests"
],
"eslint.enable": false,
"cSpell.allowCompoundWords": true,
"cSpell.caseSensitive": true,
"rust-analyzer.checkOnSave.command": "clippy",
"rust-analyzer.checkOnSave.features": [
"rust-analyzer.check.command": "clippy",
"rust-analyzer.check.features": [
// We use this to make IDE faster
"rust-analyzer",
"rkyv-impl",
"debug"
],
"rust-analyzer.cargo.features": [
// We use this to make IDE faster
"rust-analyzer",
"rkyv-impl",
Expand Down
8 changes: 8 additions & 0 deletions crates/swc_common/src/syntax_pos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,10 @@ pub enum SpanLinesError {
}

#[derive(Clone, PartialEq, Eq, Debug)]
#[cfg_attr(
any(feature = "rkyv-impl", feature = "rkyv-bytecheck-impl"),
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
)]
pub enum SpanSnippetError {
DummyBytePos,
IllFormedSpan(Span),
Expand All @@ -1286,6 +1290,10 @@ pub struct DistinctSources {
}

#[derive(Clone, PartialEq, Eq, Debug)]
#[cfg_attr(
any(feature = "rkyv-impl", feature = "rkyv-bytecheck-impl"),
derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
)]
pub struct MalformedSourceMapPositions {
pub name: FileName,
pub source_len: usize,
Expand Down
95 changes: 11 additions & 84 deletions crates/swc_plugin_proxy/src/source_map/plugin_source_map_proxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ extern "C" {
span_ctxt: u32,
allocated_ret_ptr: u32,
) -> u32;
fn __span_to_source_proxy(
span_lo: u32,
span_hi: u32,
span_ctxt: u32,
allocated_ret_ptr: u32,
) -> u32;
fn __span_to_lines_proxy(
span_lo: u32,
span_hi: u32,
Expand All @@ -67,49 +73,6 @@ pub struct PluginSourceMapProxy {
#[cfg(all(feature = "__rkyv", feature = "__plugin_mode", target_arch = "wasm32"))]
#[swc_trace]
impl PluginSourceMapProxy {
/*
fn sss<F, Ret>(&self, sp: Span, extract_source: F) -> Result<Ret, Box<SpanSnippetError>>
where
F: FnOnce(&str, usize, usize) -> Ret,
{
if sp.lo() > sp.hi() {
return Err(SpanSnippetError::IllFormedSpan(sp));
}
if sp.lo.is_dummy() || sp.hi.is_dummy() {
return Err(SpanSnippetError::DummyBytePos);
}

let local_begin = self.lookup_byte_offset(sp.lo());
let local_end = self.lookup_byte_offset(sp.hi());

if local_begin.sf.start_pos != local_end.sf.start_pos {
Err(SpanSnippetError::DistinctSources(DistinctSources {
begin: (local_begin.sf.name.clone(), local_begin.sf.start_pos),
end: (local_end.sf.name.clone(), local_end.sf.start_pos),
}))
} else {
let pos: BytePos = BytePos(0);
let start_index = pos.to_usize();
let end_index = local_end.pos.to_usize();
let source_len = (local_begin.sf.end_pos - local_begin.sf.start_pos).to_usize();

if start_index > end_index || end_index > source_len {
return Err(SpanSnippetError::MalformedForSourcemap(
MalformedSourceMapPositions {
name: local_begin.sf.name.clone(),
source_len,
begin_pos: local_begin.pos,
end_pos: local_end.pos,
},
));
}

let src = &local_begin.sf.src;
Ok(extract_source(src, start_index, end_index))
}
}
*/

pub fn span_to_source<F, Ret>(
&self,
sp: Span,
Expand All @@ -120,50 +83,14 @@ impl PluginSourceMapProxy {
{
#[cfg(target_arch = "wasm32")]
{
if sp.lo() > sp.hi() {
return Err(Box::new(SpanSnippetError::IllFormedSpan(sp)));
}
if sp.lo.is_dummy() || sp.hi.is_dummy() {
return Err(Box::new(SpanSnippetError::DummyBytePos));
}

let local_begin: SourceFileAndBytePos =
let src: Result<String, Box<SpanSnippetError>> =
read_returned_result_from_host_fallible(|serialized_ptr| unsafe {
__lookup_byte_offset_proxy(sp.lo().0, serialized_ptr)
__span_to_source_proxy(sp.lo.0, sp.hi.0, sp.ctxt.as_u32(), serialized_ptr)
})
.expect("Should return begin offset");
let local_end: SourceFileAndBytePos =
read_returned_result_from_host_fallible(|serialized_ptr| unsafe {
__lookup_byte_offset_proxy(sp.hi().0, serialized_ptr)
})
.expect("Should return end offset");

if local_begin.sf.start_pos != local_end.sf.start_pos {
Err(Box::new(SpanSnippetError::DistinctSources(
DistinctSources {
begin: (local_begin.sf.name.clone(), local_begin.sf.start_pos),
end: (local_end.sf.name.clone(), local_end.sf.start_pos),
},
)))
} else {
let start_index = local_begin.pos.to_usize();
let end_index = local_end.pos.to_usize();
let source_len = (local_begin.sf.end_pos - local_begin.sf.start_pos).to_usize();
.expect("Host should return source code");

if start_index > end_index || end_index > source_len {
return Err(Box::new(SpanSnippetError::MalformedForSourcemap(
MalformedSourceMapPositions {
name: local_begin.sf.name.clone(),
source_len,
begin_pos: local_begin.pos,
end_pos: local_end.pos,
},
)));
}

let src = &local_begin.sf.src;
return Ok(extract_source(src, start_index, end_index));
}
let src = src?;
return Ok(extract_source(&src, 0, src.len()));
}

#[cfg(not(target_arch = "wasm32"))]
Expand Down
11 changes: 9 additions & 2 deletions crates/swc_plugin_runner/src/imported_fn/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,8 @@ use self::{
},
source_map::{
doctest_offset_line_proxy, lookup_byte_offset_proxy, lookup_char_pos_proxy,
merge_spans_proxy, span_to_filename_proxy, span_to_lines_proxy, span_to_string_proxy,
SourceMapHostEnvironment,
merge_spans_proxy, span_to_filename_proxy, span_to_lines_proxy, span_to_source_proxy,
span_to_string_proxy, SourceMapHostEnvironment,
},
};

Expand Down Expand Up @@ -281,6 +281,12 @@ pub(crate) fn build_import_object(
span_to_filename_proxy,
);

let span_to_source_fn_decl = Function::new_native_with_env(
store,
SourceMapHostEnvironment::new(&source_map, &source_map_buffer),
span_to_source_proxy,
);

let span_to_lines_fn_decl = Function::new_native_with_env(
store,
SourceMapHostEnvironment::new(&source_map, &source_map_buffer),
Expand Down Expand Up @@ -339,6 +345,7 @@ pub(crate) fn build_import_object(
"__merge_spans_proxy" => merge_spans_fn_decl,
"__span_to_string_proxy" => span_to_string_fn_decl,
"__span_to_filename_proxy" => span_to_filename_fn_decl,
"__span_to_source_proxy" => span_to_source_fn_decl,
"__span_to_lines_proxy" => span_to_lines_fn_decl,
"__lookup_byte_offset_proxy" => lookup_byte_offset_fn_decl
}
Expand Down
36 changes: 35 additions & 1 deletion crates/swc_plugin_runner/src/imported_fn/source_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use parking_lot::Mutex;
use swc_common::{
plugin::serialized::PluginSerializedBytes,
source_map::{PartialFileLines, PartialLoc},
BytePos, SourceMap, Span, SyntaxContext,
BytePos, SourceMap, SourceMapper, Span, SyntaxContext,
};
use wasmer::{LazyInit, Memory, NativeFunc};

Expand Down Expand Up @@ -267,3 +267,37 @@ pub fn span_to_filename_proxy(
0
}
}

#[tracing::instrument(level = "info", skip_all)]
pub fn span_to_source_proxy(
env: &SourceMapHostEnvironment,
span_lo: u32,
span_hi: u32,
span_ctxt: u32,
allocated_ret_ptr: u32,
) -> i32 {
if let Some(memory) = env.memory_ref() {
let span = Span {
lo: BytePos(span_lo),
hi: BytePos(span_hi),
ctxt: SyntaxContext::from_u32(span_ctxt),
};
let ret = (env.source_map.lock()).span_to_snippet(span);
let serialized_loc_bytes =
PluginSerializedBytes::try_serialize(&ret).expect("Should be serializable");

if let Some(alloc_guest_memory) = env.alloc_guest_memory_ref() {
allocate_return_values_into_guest(
memory,
alloc_guest_memory,
allocated_ret_ptr,
&serialized_loc_bytes,
);
1
} else {
0
}
} else {
0
}
}
Loading