-
Notifications
You must be signed in to change notification settings - Fork 43
servo_arc: bad drop in WASM target #129
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
Comments
https://github.com/noahbald/stylo-selector-fail-129 |
I've found this line to be the source of the panic Line 367 in 8422412
|
I've found that adding the following to [target.'cfg(target_arch = "wasm32")'.dependencies.servo_arc]
path = "../servo_arc"
features = ["track_alloc_size"] Any maintainer know if this is a reasonable fix? |
Also, updating my crate's |
I suspect that none of the maintainers (like myself) have any idea why this happens and why that feature fixes the issue. If you have suggestions for how to document it, I'm listening! |
I believe it is generally the case that one needs to track allocation size to safely deallocate. jemalloc which both Servo and Firefox use is a bit of an exception in that regard. The // NOTE(emilio): This needs to be here so that HeaderSlice<> is deallocated properly if the
// allocator relies on getting the right Layout. We don't need to track the right alignment,
// since we know that statically.
//
// This member could be completely avoided once min_specialization feature is stable (by
// implementing a trait for HeaderSlice that gives you the right layout). For now, servo-only
// since Gecko doesn't need it (its allocator doesn't need the size for the alignments we care
// about). See https://github.com/rust-lang/rust/issues/31844.
alloc_size: usize, Probably |
Some context in #28 |
This isn't limited to WASM. It also fails MIRI tests. Here's a reproducer: [dependencies]
selectors = "0.27"
cssparser = "0.35"
precomputed-hash = "0.1.1" rustc 1.88.0-nightly (077cedc2a 2025-04-19) #[test]
fn native_test() {
drop(SelectorsParser::parse("a[href]"));
}
use cssparser::{Parser as CssParser, ParserInput, ToCss};
use selectors::parser::{
NonTSPseudoClass, Parser, PseudoElement, SelectorImpl, SelectorList,
SelectorParseErrorKind,
};
use selectors::parser::ParseRelative;
use std::fmt;
#[derive(Debug, Clone, Eq, PartialEq)]
pub(crate) struct SelectorImplDescriptor;
#[derive(Clone, Default, Eq, PartialEq)]
pub struct CssString(Box<str>);
impl<'a> From<&'a str> for CssString {
fn from(value: &'a str) -> Self {
Self(value.into())
}
}
impl ToCss for CssString {
fn to_css<W: fmt::Write>(&self, dest: &mut W) -> fmt::Result {
dest.write_str(&self.0)
}
}
impl precomputed_hash::PrecomputedHash for CssString {
fn precomputed_hash(&self) -> u32 {
if let Some(v) = self.0.as_bytes().get(..4) {
let mut tmp = [0u8; 4];
tmp.copy_from_slice(v);
u32::from_ne_bytes(tmp)
} else {
0
}
}
}
impl precomputed_hash::PrecomputedHash for Namespace {
fn precomputed_hash(&self) -> u32 {
*self as u32
}
}
// Pub only for integration tests
#[derive(Default, Copy, Clone, Eq, PartialEq, Debug)]
pub enum Namespace {
#[default]
Html = 0,
Svg = 1,
MathML = 2,
}
impl Namespace {
#[inline]
#[must_use]
pub const fn uri(self) -> &'static str {
use Namespace::{Html, MathML, Svg};
// NOTE: https://infra.spec.whatwg.org/#namespaces
match self {
Html => "http://www.w3.org/1999/xhtml",
Svg => "http://www.w3.org/2000/svg",
MathML => "http://www.w3.org/1998/Math/MathML",
}
}
}
impl SelectorImpl for SelectorImplDescriptor {
type AttrValue = CssString;
type Identifier = CssString;
type LocalName = CssString;
type NamespacePrefix = CssString;
type NamespaceUrl = CssString;
type BorrowedNamespaceUrl = CssString;
type BorrowedLocalName = CssString;
type NonTSPseudoClass = NonTSPseudoClassStub;
type PseudoElement = PseudoElementStub;
type ExtraMatchingData<'unused> = ();
}
#[derive(PartialEq, Eq, Clone, Debug, Hash)]
pub(crate) enum PseudoElementStub {}
impl ToCss for PseudoElementStub {
fn to_css<W: fmt::Write>(&self, _dest: &mut W) -> fmt::Result {
Ok(())
}
}
impl PseudoElement for PseudoElementStub {
type Impl = SelectorImplDescriptor;
}
#[derive(PartialEq, Eq, Clone, Debug, Hash)]
pub(crate) enum NonTSPseudoClassStub {}
impl NonTSPseudoClass for NonTSPseudoClassStub {
type Impl = SelectorImplDescriptor;
fn is_active_or_hover(&self) -> bool {
false
}
fn is_user_action_state(&self) -> bool {
false
}
}
impl ToCss for NonTSPseudoClassStub {
fn to_css<W: fmt::Write>(&self, _dest: &mut W) -> fmt::Result {
Ok(())
}
}
#[allow(dead_code)]
struct SelectorsParser;
impl SelectorsParser {
pub fn parse(selector: &str) -> Result<SelectorList<SelectorImplDescriptor>, ()> {
let mut input = ParserInput::new(selector);
let mut css_parser = CssParser::new(&mut input);
SelectorList::parse(&Self, &mut css_parser, ParseRelative::No).map_err(drop)
}
}
impl<'i> Parser<'i> for SelectorsParser {
type Impl = SelectorImplDescriptor;
type Error = SelectorParseErrorKind<'i>;
} Miri crash log
And the same does fail in WASM too: use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn do_crash() {
#[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once();
drop(SelectorsParser::parse("a[href]"));
}
|
Workaround for servo/stylo#129
Sorry if this issue is a bit vague because I'm having a hard time finding the exact cause.
I'm compiling to WASM using wasm-bindgen 0.2.100 and when running I receive the following panic
And this seems to happening when I create a selector with a selector list, e.g.
related: rustwasm/wasm-pack#1389
The text was updated successfully, but these errors were encountered: