diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-28 14:29:10 +0000 |
commit | 2aa4a82499d4becd2284cdb482213d541b8804dd (patch) | |
tree | b80bf8bf13c3766139fbacc530efd0dd9d54394c /mozglue/static | |
parent | Initial commit. (diff) | |
download | firefox-upstream.tar.xz firefox-upstream.zip |
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'mozglue/static')
-rw-r--r-- | mozglue/static/README | 2 | ||||
-rw-r--r-- | mozglue/static/rust/Cargo.toml | 14 | ||||
-rw-r--r-- | mozglue/static/rust/build.rs | 38 | ||||
-rw-r--r-- | mozglue/static/rust/lib.rs | 101 | ||||
-rw-r--r-- | mozglue/static/rust/wrappers.cpp | 18 |
5 files changed, 173 insertions, 0 deletions
diff --git a/mozglue/static/README b/mozglue/static/README new file mode 100644 index 0000000000..e52c716166 --- /dev/null +++ b/mozglue/static/README @@ -0,0 +1,2 @@ +mozglue/static contains parts of the mozglue library that can/should be +statically linked to e.g. js/Gecko. diff --git a/mozglue/static/rust/Cargo.toml b/mozglue/static/rust/Cargo.toml new file mode 100644 index 0000000000..e78b396cde --- /dev/null +++ b/mozglue/static/rust/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "mozglue-static" +version = "0.1.0" +edition = "2018" +license = "MPL" + +[lib] +path = "lib.rs" + +[dependencies] +arrayvec = "0.5" + +[build-dependencies] +cc = "1" diff --git a/mozglue/static/rust/build.rs b/mozglue/static/rust/build.rs new file mode 100644 index 0000000000..5bc6bae40c --- /dev/null +++ b/mozglue/static/rust/build.rs @@ -0,0 +1,38 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use std::env; +use std::path::PathBuf; + +fn main() { + let dist_path = { + let path = PathBuf::from(env::var_os("MOZ_DIST").unwrap()); + if !path.is_absolute() || !path.is_dir() { + panic!( + "MOZ_DIST must be an absolute directory, was: {}", + path.display() + ); + } + path + }; + let topobjdir = { + let path = PathBuf::from(env::var_os("MOZ_TOPOBJDIR").unwrap()); + if !path.is_absolute() || !path.is_dir() { + panic!( + "MOZ_TOPOBJDIR must be an absolute directory, was: {}", + path.display() + ); + } + path + }; + let mut build = cc::Build::new(); + build.cpp(true); + // For js-confdefs.h, see wrappers.cpp. + build.include(topobjdir.join("js").join("src")); + build.include(dist_path.join("include")); + build.define("MOZ_HAS_MOZGLUE", None); + build.file("wrappers.cpp"); + build.compile("wrappers"); + println!("cargo:rerun-if-changed=wrappers.cpp"); +} diff --git a/mozglue/static/rust/lib.rs b/mozglue/static/rust/lib.rs new file mode 100644 index 0000000000..7faf9d3873 --- /dev/null +++ b/mozglue/static/rust/lib.rs @@ -0,0 +1,101 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +use arrayvec::{Array, ArrayString}; +use std::cmp; +use std::ops::Deref; +use std::os::raw::c_char; +use std::os::raw::c_int; +use std::panic; + +#[link(name = "wrappers")] +extern "C" { + // We can't use MOZ_Crash directly because it may be weakly linked + // and rust can't handle that. + fn RustMozCrash(filename: *const c_char, line: c_int, reason: *const c_char) -> !; +} + +/// Truncate a string at the closest unicode character boundary +/// ``` +/// assert_eq!(str_truncate_valid("éà", 3), "é"); +/// assert_eq!(str_truncate_valid("éà", 4), "éè"); +/// ``` +fn str_truncate_valid(s: &str, mut mid: usize) -> &str { + loop { + if let Some(res) = s.get(..mid) { + return res; + } + mid -= 1; + } +} + +/// Similar to ArrayString, but with terminating nul character. +#[derive(Debug, PartialEq)] +struct ArrayCString<A: Array<Item = u8> + Copy> { + inner: ArrayString<A>, +} + +impl<S: AsRef<str>, A: Array<Item = u8> + Copy> From<S> for ArrayCString<A> { + /// Contrary to ArrayString::from, truncates at the closest unicode + /// character boundary. + /// ``` + /// assert_eq!(ArrayCString::<[_; 4]>::from("éà"), + /// ArrayCString::<[_; 4]>::from("é")); + /// assert_eq!(&*ArrayCString::<[_; 4]>::from("éà"), "é\0"); + /// ``` + fn from(s: S) -> Self { + let s = s.as_ref(); + let len = cmp::min(s.len(), A::CAPACITY - 1); + let mut result = Self { + inner: ArrayString::from(str_truncate_valid(s, len)).unwrap(), + }; + result.inner.push('\0'); + result + } +} + +impl<A: Array<Item = u8> + Copy> Deref for ArrayCString<A> { + type Target = str; + + fn deref(&self) -> &str { + self.inner.as_str() + } +} + +fn panic_hook(info: &panic::PanicInfo) { + // Try to handle &str/String payloads, which should handle 99% of cases. + let payload = info.payload(); + let message = if let Some(s) = payload.downcast_ref::<&str>() { + s + } else if let Some(s) = payload.downcast_ref::<String>() { + s.as_str() + } else { + // Not the most helpful thing, but seems unlikely to happen + // in practice. + "Unhandled rust panic payload!" + }; + let (filename, line) = if let Some(loc) = info.location() { + (loc.file(), loc.line()) + } else { + ("unknown.rs", 0) + }; + // Copy the message and filename to the stack in order to safely add + // a terminating nul character (since rust strings don't come with one + // and RustMozCrash wants one). + let message = ArrayCString::<[_; 512]>::from(message); + let filename = ArrayCString::<[_; 512]>::from(filename); + unsafe { + RustMozCrash( + filename.as_ptr() as *const c_char, + line as c_int, + message.as_ptr() as *const c_char, + ); + } +} + +/// Configure a panic hook to redirect rust panics to MFBT's MOZ_Crash. +#[no_mangle] +pub extern "C" fn install_rust_panic_hook() { + panic::set_hook(Box::new(panic_hook)); +} diff --git a/mozglue/static/rust/wrappers.cpp b/mozglue/static/rust/wrappers.cpp new file mode 100644 index 0000000000..ac86bbdd5b --- /dev/null +++ b/mozglue/static/rust/wrappers.cpp @@ -0,0 +1,18 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this file, + * You can obtain one at http://mozilla.org/MPL/2.0/. */ + +// This ensures the right configuration for e.g. MOZ_GLUE_IN_PROGRAM, +// used in the MFBT headers included further below. We use js-confdefs.h +// instead of mozilla-config.h because the latter is not present in +// spidermonkey standalone builds while the former is always present. +#include "js-confdefs.h" +#include "mozilla/Assertions.h" +#include "mozilla/Types.h" + +// MOZ_Crash wrapper for use by rust, since MOZ_Crash is an inline function. +extern "C" void RustMozCrash(const char* aFilename, int aLine, + const char* aReason) { + MOZ_Crash(aFilename, aLine, aReason); +} |