summaryrefslogtreecommitdiffstats
path: root/mozglue/static
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /mozglue/static
parentInitial commit. (diff)
downloadfirefox-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/README2
-rw-r--r--mozglue/static/rust/Cargo.toml14
-rw-r--r--mozglue/static/rust/build.rs38
-rw-r--r--mozglue/static/rust/lib.rs101
-rw-r--r--mozglue/static/rust/wrappers.cpp18
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);
+}