зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1888683 - Upgrade UniFFI to 0.27.1. r=markh,janerik,glandium,supply-chain-reviewers,mach-reviewers,android-reviewers,kaya
Update: - UniFFI to 0.27.1 - Glean to 59.0.0 - App-services to a recent version This removes the need for the goblin build hack, although we still have duplicate versions of goblin since UniFFI is ahead of the moz-central version. I think that should be easy to resolve as a follow-up. Updating uniffi-bindget-gecko-js based on upstream changes: - Clone objects before lowering them (https://github.com/mozilla/uniffi-rs/pull/1880) - Use u64 for the RustBuffer length and capacity field (https://github.com/mozilla/uniffi-rs/pull/1978) I didn't implement the new callback interface VTable code. Instead I simply disabled the one fixture that tests it. I'd rather implement https://bugzilla.mozilla.org/show_bug.cgi?id=1888668 first, since that will simplify the process a bunch. The only real-world use-case for callbacks that I know of is Mark's logging changes, but that will require implementing trait interfaces anyways so I'd rather wait than write a bunch of C++ code that we then throw away. Differential Revision: https://phabricator.services.mozilla.com/D206130
This commit is contained in:
Родитель
259ecaefdf
Коммит
3c47b31e06
|
@ -2330,6 +2330,7 @@ dependencies = [
|
|||
"uniffi-example-todolist",
|
||||
"uniffi-fixture-callbacks",
|
||||
"uniffi-fixture-external-types",
|
||||
"uniffi-fixture-refcounts",
|
||||
"url",
|
||||
"viaduct",
|
||||
"webext_storage_bridge",
|
||||
|
@ -6107,6 +6108,13 @@ dependencies = [
|
|||
"uniffi-example-geometry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi-fixture-refcounts"
|
||||
version = "0.21.0"
|
||||
dependencies = [
|
||||
"uniffi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uniffi_bindgen"
|
||||
version = "0.25.3"
|
||||
|
|
35
Cargo.toml
35
Cargo.toml
|
@ -53,7 +53,8 @@ resolver = "2"
|
|||
|
||||
[workspace.dependencies]
|
||||
# Shared across multiple UniFFI consumers.
|
||||
uniffi = "0.25.3"
|
||||
uniffi = "0.27.1"
|
||||
uniffi_bindgen = "0.27.1"
|
||||
# Shared across multiple application-services consumers.
|
||||
rusqlite = "0.30.0"
|
||||
|
||||
|
@ -164,10 +165,12 @@ derive_more = { path = "build/rust/derive_more" }
|
|||
# Patch autocfg to hide rustc output. Workaround for https://github.com/cuviper/autocfg/issues/30
|
||||
autocfg = { path = "third_party/rust/autocfg" }
|
||||
|
||||
# Patch goblin 0.6.0 to 0.7.0 because uniffi crates still use the older version
|
||||
# and we want to avoid duplications
|
||||
# Patch goblin 0.7.0 to 0.8
|
||||
goblin = { path = "build/rust/goblin" }
|
||||
|
||||
# Patch scroll 0.11 to 0.12
|
||||
scroll = { path = "build/rust/scroll" }
|
||||
|
||||
# Patch memoffset from 0.8.0 to 0.9.0 since it's compatible and it avoids duplication
|
||||
memoffset = { path = "build/rust/memoffset" }
|
||||
|
||||
|
@ -209,14 +212,14 @@ warp = { git = "https://github.com/seanmonstar/warp", rev = "9d081461ae1167eb321
|
|||
malloc_size_of_derive = { path = "xpcom/rust/malloc_size_of_derive" }
|
||||
|
||||
# application-services overrides to make updating them all simpler.
|
||||
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "9054db4bb5031881550ceab3448665ef6499a706" }
|
||||
relevancy = { git = "https://github.com/mozilla/application-services", rev = "9054db4bb5031881550ceab3448665ef6499a706" }
|
||||
sql-support = { git = "https://github.com/mozilla/application-services", rev = "9054db4bb5031881550ceab3448665ef6499a706" }
|
||||
suggest = { git = "https://github.com/mozilla/application-services", rev = "9054db4bb5031881550ceab3448665ef6499a706" }
|
||||
sync15 = { git = "https://github.com/mozilla/application-services", rev = "9054db4bb5031881550ceab3448665ef6499a706" }
|
||||
tabs = { git = "https://github.com/mozilla/application-services", rev = "9054db4bb5031881550ceab3448665ef6499a706" }
|
||||
viaduct = { git = "https://github.com/mozilla/application-services", rev = "9054db4bb5031881550ceab3448665ef6499a706" }
|
||||
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "9054db4bb5031881550ceab3448665ef6499a706" }
|
||||
interrupt-support = { git = "https://github.com/mozilla/application-services", rev = "e6ccfed09ebe663f464a33968f42e656c152e584" }
|
||||
relevancy = { git = "https://github.com/mozilla/application-services", rev = "e6ccfed09ebe663f464a33968f42e656c152e584" }
|
||||
sql-support = { git = "https://github.com/mozilla/application-services", rev = "e6ccfed09ebe663f464a33968f42e656c152e584" }
|
||||
suggest = { git = "https://github.com/mozilla/application-services", rev = "e6ccfed09ebe663f464a33968f42e656c152e584" }
|
||||
sync15 = { git = "https://github.com/mozilla/application-services", rev = "e6ccfed09ebe663f464a33968f42e656c152e584" }
|
||||
tabs = { git = "https://github.com/mozilla/application-services", rev = "e6ccfed09ebe663f464a33968f42e656c152e584" }
|
||||
viaduct = { git = "https://github.com/mozilla/application-services", rev = "e6ccfed09ebe663f464a33968f42e656c152e584" }
|
||||
webext-storage = { git = "https://github.com/mozilla/application-services", rev = "e6ccfed09ebe663f464a33968f42e656c152e584" }
|
||||
|
||||
# Patch mio 0.8.8 to use windows-sys 0.52 (backport https://github.com/tokio-rs/mio/commit/eea9e3e0c469480e5c59c01e6c3c7e5fd88f0848)
|
||||
mio_0_8 = { package = "mio", git = "https://github.com/glandium/mio", rev = "9a2ef335c366044ffe73b1c4acabe50a1daefe05" }
|
||||
|
@ -227,8 +230,8 @@ mio_0_8 = { package = "mio", git = "https://github.com/glandium/mio", rev = "9a2
|
|||
path = "third_party/rust/mio-0.6.23"
|
||||
|
||||
[patch."https://github.com/mozilla/uniffi-rs.git"]
|
||||
uniffi = "=0.25.3"
|
||||
uniffi_bindgen = "=0.25.3"
|
||||
uniffi_build = "=0.25.3"
|
||||
uniffi_macros = "=0.25.3"
|
||||
weedle2 = "=4.0.0"
|
||||
uniffi = "0.27.1"
|
||||
uniffi_bindgen = "0.27.1"
|
||||
uniffi_build = "0.27.1"
|
||||
uniffi_macros = "0.27.1"
|
||||
weedle2 = "=5.0.0"
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "goblin"
|
||||
version = "0.6.999"
|
||||
version = "0.7.999"
|
||||
edition = "2018"
|
||||
license = "MIT/Apache-2.0"
|
||||
|
||||
|
@ -8,4 +8,19 @@ license = "MIT/Apache-2.0"
|
|||
path = "lib.rs"
|
||||
|
||||
[dependencies.goblin]
|
||||
version = "0.7.0"
|
||||
version = "0.8.0"
|
||||
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
alloc = ["goblin/alloc"]
|
||||
archive = ["goblin/archive"]
|
||||
default = ["goblin/default"]
|
||||
elf32 = ["goblin/elf32"]
|
||||
elf64 = ["goblin/elf64"]
|
||||
endian_fd = ["goblin/endian_fd"]
|
||||
mach32 = ["goblin/mach32"]
|
||||
mach64 = ["goblin/mach64"]
|
||||
pe32 = ["goblin/pe32"]
|
||||
pe64 = ["goblin/pe64"]
|
||||
std = ["goblin/std"]
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
[package]
|
||||
name = "scroll"
|
||||
version = "0.11.999"
|
||||
edition = "2018"
|
||||
license = "MIT/Apache-2.0"
|
||||
|
||||
[lib]
|
||||
path = "lib.rs"
|
||||
|
||||
[dependencies.scroll]
|
||||
version = "0.12.0"
|
||||
default-features = false
|
||||
|
||||
[features]
|
||||
default = ["scroll/default"]
|
||||
derive = ["scroll/derive"]
|
||||
std = ["scroll/std"]
|
|
@ -0,0 +1,11 @@
|
|||
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
pub use scroll::*;
|
|
@ -35,7 +35,7 @@ typedef unsigned long long UniFFICallbackObjectHandle;
|
|||
|
||||
// Opaque type used to represent a pointer from Rust
|
||||
[ChromeOnly, Exposed=Window]
|
||||
interface UniFFIPointer {};
|
||||
interface UniFFIPointer { };
|
||||
|
||||
// Types that can be passed or returned from scaffolding functions
|
||||
//
|
||||
|
|
|
@ -32,6 +32,8 @@ packages = [
|
|||
# transition to syn 2 is underway.
|
||||
"syn",
|
||||
"synstructure",
|
||||
# Requires an update to clap v4
|
||||
"textwrap",
|
||||
# Can be fixed by removing time dependency - see bug 1765324
|
||||
"wasi",
|
||||
]
|
||||
|
|
|
@ -52,7 +52,7 @@ svg_fmt = "0.4"
|
|||
tracy-rs = "0.1.2"
|
||||
derive_more = { version = "0.99", default-features = false, features = ["add_assign"] }
|
||||
etagere = "0.2.6"
|
||||
glean = { version = "58.1.0", optional = true }
|
||||
glean = { version = "59.0.0", optional = true }
|
||||
firefox-on-glean = { version = "0.1.0", optional = true }
|
||||
swgl = { path = "../swgl", optional = true }
|
||||
topological-sort = "0.1"
|
||||
|
|
|
@ -25,7 +25,7 @@ tracy-rs = "0.1.2"
|
|||
log = "0.4"
|
||||
lazy_static = "1"
|
||||
fxhash = "0.2.1"
|
||||
glean = { version = "58.1.0", optional = true }
|
||||
glean = { version = "59.0.0", optional = true }
|
||||
firefox-on-glean = { version = "0.1.0", optional = true }
|
||||
serde = { optional = true, version = "1.0", features = ["serde_derive"] }
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ object Versions {
|
|||
const val serialization = "1.6.3"
|
||||
const val python_envs_plugin = "0.0.31"
|
||||
|
||||
const val mozilla_glean = "58.1.0"
|
||||
const val mozilla_glean = "59.0.0"
|
||||
|
||||
const val junit = "4.13.2"
|
||||
const val robolectric = "4.11.1"
|
||||
|
|
|
@ -93,7 +93,7 @@ vendored:third_party/python/wheel
|
|||
vendored:third_party/python/zipp
|
||||
# glean-sdk may not be installable if a wheel isn't available
|
||||
# and it has to be built from source.
|
||||
pypi-optional:glean-sdk==58.1.0:telemetry will not be collected
|
||||
pypi-optional:glean-sdk==59.0.0:telemetry will not be collected
|
||||
# Mach gracefully handles the case where `psutil` is unavailable.
|
||||
# We aren't (yet) able to pin packages in automation, so we have to
|
||||
# support down to the oldest locally-installed version (5.4.2).
|
||||
|
|
|
@ -3750,6 +3750,11 @@ who = "Mike Hommey <mh+mozilla@glandium.org>"
|
|||
criteria = "safe-to-deploy"
|
||||
delta = "0.15.2 -> 0.16.0"
|
||||
|
||||
[[audits.textwrap]]
|
||||
who = "Jan-Erik Rediger <jrediger@mozilla.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
delta = "0.16.0 -> 0.16.1"
|
||||
|
||||
[[audits.thin-vec]]
|
||||
who = "Aria Beingessner <a.beingessner@gmail.com>"
|
||||
criteria = "safe-to-deploy"
|
||||
|
|
|
@ -6,7 +6,7 @@ edition = "2018"
|
|||
license = "MPL-2.0"
|
||||
|
||||
[dependencies]
|
||||
glean = "58.1.0"
|
||||
glean = "59.0.0"
|
||||
log = "0.4"
|
||||
nserror = { path = "../../../xpcom/rust/nserror" }
|
||||
nsstring = { path = "../../../xpcom/rust/nsstring" }
|
||||
|
|
|
@ -9,7 +9,7 @@ license = "MPL-2.0"
|
|||
[dependencies]
|
||||
bincode = "1.0"
|
||||
chrono = "0.4.10"
|
||||
glean = "58.1.0"
|
||||
glean = "59.0.0"
|
||||
inherent = "1.0.0"
|
||||
log = "0.4"
|
||||
nsstring = { path = "../../../../xpcom/rust/nsstring", optional = true }
|
||||
|
|
|
@ -43,6 +43,7 @@ fn setup_glean(tempdir: Option<tempfile::TempDir>) -> tempfile::TempDir {
|
|||
rate_limit: None,
|
||||
enable_event_timestamps: false,
|
||||
experimentation_id: None,
|
||||
enable_internal_pings: true
|
||||
};
|
||||
|
||||
let client_info = glean::ClientInfoMetrics {
|
||||
|
|
|
@ -184,6 +184,7 @@ fn build_configuration(
|
|||
rate_limit,
|
||||
enable_event_timestamps,
|
||||
experimentation_id: None,
|
||||
enable_internal_pings: true,
|
||||
};
|
||||
|
||||
Ok((configuration, client_info))
|
||||
|
|
|
@ -15,7 +15,7 @@ clap = { version = "4", default-features = false, features = ["std", "derive", "
|
|||
extend = "1.1"
|
||||
heck = "0.4"
|
||||
uniffi = { workspace = true }
|
||||
uniffi_bindgen = "0.25"
|
||||
uniffi_bindgen = { workspace = true }
|
||||
serde = "1"
|
||||
toml = "0.5"
|
||||
camino = "1.0.8"
|
||||
|
|
|
@ -72,16 +72,27 @@ crate_name = "uniffi_todolist"
|
|||
udl_file = "third_party/rust/uniffi-example-todolist/src/todolist.udl"
|
||||
fixture = true
|
||||
|
||||
[fixture_callbacks]
|
||||
crate_name = "uniffi_fixture_callbacks"
|
||||
udl_file = "toolkit/components/uniffi-fixture-callbacks/src/callbacks.udl"
|
||||
[fixture_refcounts]
|
||||
crate_name = "uniffi_fixture_refcounts"
|
||||
udl_file = "toolkit/components/uniffi-fixture-refcounts/src/refcounts.udl"
|
||||
fixture = true
|
||||
|
||||
[fixture_callbacks.receiver_thread]
|
||||
default = "worker"
|
||||
main = [
|
||||
"log_even_numbers_main_thread",
|
||||
]
|
||||
[fixture_refcounts.receiver_thread]
|
||||
default = "main"
|
||||
|
||||
# Temporarily disabled until we can re-enable callback support
|
||||
#
|
||||
# I think this can be done when we implement https://bugzilla.mozilla.org/show_bug.cgi?id=1888668
|
||||
# [fixture_callbacks]
|
||||
# crate_name = "uniffi_fixture_callbacks"
|
||||
# udl_file = "toolkit/components/uniffi-fixture-callbacks/src/callbacks.udl"
|
||||
# fixture = true
|
||||
#
|
||||
# [fixture_callbacks.receiver_thread]
|
||||
# default = "worker"
|
||||
# main = [
|
||||
# "log_even_numbers_main_thread",
|
||||
# ]
|
||||
|
||||
[custom_types]
|
||||
crate_name = "uniffi_custom_types"
|
||||
|
|
|
@ -12,6 +12,7 @@ components = [
|
|||
"ExternalTypes",
|
||||
"FixtureCallbacks",
|
||||
"Geometry",
|
||||
"Refcounts",
|
||||
"Rondpoint",
|
||||
"Sprites",
|
||||
"Todolist",
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const { getSingleton, getJsRefcount } = ChromeUtils.importESModule(
|
||||
"resource://gre/modules/RustRefcounts.sys.mjs"
|
||||
);
|
||||
|
||||
// Test refcounts when we call methods.
|
||||
//
|
||||
// Each method call requires that we clone the Arc pointer on the JS side, then pass it to Rust
|
||||
// which will consumer the reference. Make sure we get this right
|
||||
|
||||
function createObjectAndCallMethods() {
|
||||
const obj = getSingleton();
|
||||
obj.method();
|
||||
}
|
||||
|
||||
add_test(() => {
|
||||
// Create an object that we'll keep around. If the ref count ends up being low, we don't want
|
||||
// to reduce it below 0, since the Rust code may catch that and clamp it
|
||||
const obj = getSingleton();
|
||||
createObjectAndCallMethods();
|
||||
Cu.forceGC();
|
||||
Cu.forceCC();
|
||||
do_test_pending();
|
||||
do_timeout(500, () => {
|
||||
Assert.equal(getJsRefcount(), 1);
|
||||
// Use `obj` to avoid unused warnings and try to ensure that JS doesn't destroy it early
|
||||
obj.method();
|
||||
do_test_finished();
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
|
||||
// Test refcounts when creating/destroying objects
|
||||
function createAndDeleteObjects() {
|
||||
[getSingleton(), getSingleton(), getSingleton()];
|
||||
}
|
||||
|
||||
add_test(() => {
|
||||
const obj = getSingleton();
|
||||
createAndDeleteObjects();
|
||||
Cu.forceGC();
|
||||
Cu.forceCC();
|
||||
do_timeout(500, () => {
|
||||
Assert.equal(getJsRefcount(), 1);
|
||||
obj.method();
|
||||
do_test_finished();
|
||||
run_next_test();
|
||||
});
|
||||
});
|
||||
|
||||
// As we implement more UniFFI features we should probably add refcount tests for it.
|
||||
// Some features that should probably have tests:
|
||||
// - Async methods
|
||||
// - UniFFI builtin trait methods like 'to_string'
|
||||
// - Rust trait objects
|
|
@ -2,18 +2,33 @@
|
|||
|
||||
["test_arithmetic.js"]
|
||||
|
||||
# I think this can be re-enabled when we implement https://bugzilla.mozilla.org/show_bug.cgi?id=1888668
|
||||
lineno = "3"
|
||||
|
||||
["test_callbacks.js"]
|
||||
disabled = "Temporarily disabled until we can re-enable callback support"
|
||||
lineno = "8"
|
||||
|
||||
["test_custom_types.js"]
|
||||
lineno = "12"
|
||||
|
||||
["test_external_types.js"]
|
||||
lineno = "15"
|
||||
|
||||
["test_geometry.js"]
|
||||
lineno = "18"
|
||||
|
||||
["test_refcounts.js"]
|
||||
lineno = "21"
|
||||
|
||||
["test_rondpoint.js"]
|
||||
lineno = "24"
|
||||
|
||||
["test_sprites.js"]
|
||||
lineno = "27"
|
||||
|
||||
["test_todolist.js"]
|
||||
lineno = "30"
|
||||
|
||||
["test_type_checking.js"]
|
||||
lineno = "33"
|
||||
|
|
|
@ -136,31 +136,25 @@ pub impl FfiType {
|
|||
// Type for the Rust scaffolding code
|
||||
fn rust_type(&self) -> String {
|
||||
match self {
|
||||
FfiType::UInt8 => "uint8_t",
|
||||
FfiType::Int8 => "int8_t",
|
||||
FfiType::UInt16 => "uint16_t",
|
||||
FfiType::Int16 => "int16_t",
|
||||
FfiType::UInt32 => "uint32_t",
|
||||
FfiType::Int32 => "int32_t",
|
||||
FfiType::UInt64 => "uint64_t",
|
||||
FfiType::Int64 => "int64_t",
|
||||
FfiType::Float32 => "float",
|
||||
FfiType::Float64 => "double",
|
||||
FfiType::RustBuffer(_) => "RustBuffer",
|
||||
FfiType::RustArcPtr(_) => "void *",
|
||||
FfiType::ForeignCallback => "ForeignCallback",
|
||||
FfiType::UInt8 => "uint8_t".to_owned(),
|
||||
FfiType::Int8 => "int8_t".to_owned(),
|
||||
FfiType::UInt16 => "uint16_t".to_owned(),
|
||||
FfiType::Int16 => "int16_t".to_owned(),
|
||||
FfiType::UInt32 => "uint32_t".to_owned(),
|
||||
FfiType::Int32 => "int32_t".to_owned(),
|
||||
FfiType::UInt64 => "uint64_t".to_owned(),
|
||||
FfiType::Int64 => "int64_t".to_owned(),
|
||||
FfiType::Float32 => "float".to_owned(),
|
||||
FfiType::Float64 => "double".to_owned(),
|
||||
FfiType::RustBuffer(_) => "RustBuffer".to_owned(),
|
||||
FfiType::RustArcPtr(_) => "void *".to_owned(),
|
||||
FfiType::ForeignBytes => unimplemented!("ForeignBytes not supported"),
|
||||
FfiType::ForeignExecutorHandle => unimplemented!("ForeignExecutorHandle not supported"),
|
||||
FfiType::ForeignExecutorCallback => {
|
||||
unimplemented!("ForeignExecutorCallback not supported")
|
||||
}
|
||||
FfiType::RustFutureHandle
|
||||
| FfiType::RustFutureContinuationCallback
|
||||
| FfiType::RustFutureContinuationData => {
|
||||
unimplemented!("Rust async functions not supported")
|
||||
}
|
||||
FfiType::Handle => "uint64_t".to_owned(),
|
||||
FfiType::RustCallStatus => "RustCallStatus".to_owned(),
|
||||
FfiType::Callback(name) | FfiType::Struct(name) => name.to_owned(),
|
||||
FfiType::VoidPointer => "void *".to_owned(),
|
||||
FfiType::Reference(_) => unimplemented!("References not supported"),
|
||||
}
|
||||
.to_owned()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -92,7 +92,8 @@ pub impl Literal {
|
|||
Literal::Enum(name, typ) => render_enum_literal(typ, name),
|
||||
Literal::EmptyMap => "{}".to_string(),
|
||||
Literal::EmptySequence => "[]".to_string(),
|
||||
Literal::Null => "null".to_string(),
|
||||
Literal::Some { inner } => inner.render(),
|
||||
Literal::None => "null".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -258,7 +259,6 @@ pub impl Type {
|
|||
| Type::CallbackInterface { name, .. } => format!("Type{name}"),
|
||||
Type::Timestamp => "Timestamp".into(),
|
||||
Type::Duration => "Duration".into(),
|
||||
Type::ForeignExecutor => "ForeignExecutor".into(),
|
||||
Type::Optional { inner_type } => format!("Optional{}", inner_type.canonical_name()),
|
||||
Type::Sequence { inner_type } => format!("Sequence{}", inner_type.canonical_name()),
|
||||
Type::Map {
|
||||
|
|
|
@ -37,7 +37,8 @@ extern "C" {
|
|||
{%- let pointer_type = ci.pointer_type(object) %}
|
||||
const static mozilla::uniffi::UniFFIPointerType {{ pointer_type }} {
|
||||
"{{ "{}::{}"|format(ci.namespace(), object.name()) }}"_ns,
|
||||
{{ object.ffi_object_free().rust_name() }}
|
||||
{{ object.ffi_object_clone().rust_name() }},
|
||||
{{ object.ffi_object_free().rust_name() }},
|
||||
};
|
||||
{%- endfor %}
|
||||
{%- endfor %}
|
||||
|
|
|
@ -7,7 +7,7 @@ license = "MPL-2.0"
|
|||
publish = false
|
||||
|
||||
[dependencies]
|
||||
uniffi-example-geometry = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "afb29ebdc1d9edf15021b1c5332fc9f285bbe13b" }
|
||||
uniffi-example-geometry = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "d52c5460ae42ecad1e73a5b394ac96d48f4769de" }
|
||||
uniffi = { workspace = true }
|
||||
thiserror = "1.0"
|
||||
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
[package]
|
||||
name = "uniffi-fixture-refcounts"
|
||||
edition = "2021"
|
||||
version = "0.21.0"
|
||||
license = "MPL-2.0"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
uniffi = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
uniffi = { workspace = true, features = ["build"] }
|
|
@ -0,0 +1,7 @@
|
|||
/* 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/. */
|
||||
|
||||
fn main() {
|
||||
uniffi::generate_scaffolding("./src/refcounts.udl").unwrap();
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
/* 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 crate exists to test managing the Rust Arc strong counts as JS objects are
|
||||
/// created/destroyed. See `test_refcounts.js` for how it's used.
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
pub struct SingletonObject;
|
||||
|
||||
impl SingletonObject {
|
||||
pub fn method(&self) { }
|
||||
}
|
||||
|
||||
static SINGLETON: Mutex<Option<Arc<SingletonObject>>> = Mutex::new(None);
|
||||
|
||||
pub fn get_singleton() -> Arc<SingletonObject> {
|
||||
Arc::clone(SINGLETON.lock().unwrap().get_or_insert_with(|| Arc::new(SingletonObject)))
|
||||
}
|
||||
|
||||
pub fn get_js_refcount() -> i32 {
|
||||
// Subtract 2: one for the reference in the Mutex and one for the temporary reference that
|
||||
// we're calling Arc::strong_count on.
|
||||
(Arc::strong_count(&get_singleton()) as i32) - 2
|
||||
}
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/refcounts.uniffi.rs"));
|
|
@ -0,0 +1,8 @@
|
|||
namespace refcounts {
|
||||
SingletonObject get_singleton();
|
||||
i32 get_js_refcount();
|
||||
};
|
||||
|
||||
interface SingletonObject {
|
||||
void method();
|
||||
};
|
|
@ -27,7 +27,7 @@ Result<OwnedRustBuffer, nsCString> OwnedRustBuffer::FromArrayBuffer(
|
|||
|
||||
RustCallStatus status{};
|
||||
RustBuffer buf = uniffi_rustbuffer_alloc(
|
||||
static_cast<int32_t>(aData.Length()), &status);
|
||||
static_cast<uint64_t>(aData.Length()), &status);
|
||||
buf.len = aData.Length();
|
||||
if (status.code != 0) {
|
||||
if (status.error_buf.data) {
|
||||
|
@ -84,7 +84,7 @@ RustBuffer OwnedRustBuffer::IntoRustBuffer() {
|
|||
JSObject* OwnedRustBuffer::IntoArrayBuffer(JSContext* cx) {
|
||||
JS::Rooted<JSObject*> obj(cx);
|
||||
{
|
||||
int32_t len = mBuf.len;
|
||||
auto len = mBuf.len;
|
||||
void* data = mBuf.data;
|
||||
auto userData = MakeUnique<OwnedRustBuffer>(std::move(*this));
|
||||
UniquePtr<void, JS::BufferContentsDeleter> dataPtr{
|
||||
|
|
|
@ -173,7 +173,7 @@ class ScaffoldingObjectConverter {
|
|||
if (!value.IsSamePtrType(PointerType)) {
|
||||
return Err("Bad pointer type"_ns);
|
||||
}
|
||||
return value.GetPtr();
|
||||
return value.ClonePtr();
|
||||
}
|
||||
|
||||
static void* IntoRust(void* aValue) { return aValue; }
|
||||
|
|
|
@ -82,7 +82,7 @@ void UniFFIPointer::Write(const ArrayBuffer& aArrayBuff, uint32_t aPosition,
|
|||
// a pointer we do the reverse here
|
||||
const auto& data_ptr = aData.Subspan(aPosition, 8);
|
||||
mozilla::BigEndian::writeUint64(data_ptr.Elements(),
|
||||
(uint64_t)GetPtr());
|
||||
(uint64_t)ClonePtr());
|
||||
return true;
|
||||
})) {
|
||||
aError.ThrowRangeError("position is out of range");
|
||||
|
@ -100,10 +100,14 @@ JSObject* UniFFIPointer::WrapObject(JSContext* aCx,
|
|||
return dom::UniFFIPointer_Binding::Wrap(aCx, this, aGivenProto);
|
||||
}
|
||||
|
||||
void* UniFFIPointer::GetPtr() const {
|
||||
void* UniFFIPointer::ClonePtr() const {
|
||||
MOZ_LOG(sUniFFIPointerLogger, LogLevel::Info,
|
||||
("[UniFFI] Getting raw pointer"));
|
||||
return this->mPtr;
|
||||
("[UniFFI] Cloning raw pointer"));
|
||||
RustCallStatus status{};
|
||||
auto cloned = this->mType->clone(this->mPtr, &status);
|
||||
MOZ_DIAGNOSTIC_ASSERT(status.code == RUST_CALL_SUCCESS,
|
||||
"UniFFI clone call returned a non-success result");
|
||||
return cloned;
|
||||
}
|
||||
|
||||
bool UniFFIPointer::IsSamePtrType(const UniFFIPointerType* aType) const {
|
||||
|
|
|
@ -36,15 +36,13 @@ class UniFFIPointer final : public nsISupports, public nsWrapperCache {
|
|||
nsISupports* GetParentObject() { return nullptr; }
|
||||
|
||||
/**
|
||||
* returns the raw pointer `UniFFIPointer` holds
|
||||
* This is safe because:
|
||||
* - The pointer was allocated in Rust as a reference counted `Arc<T>`
|
||||
* - Rust cloned the pointer without destructing it when passed into C++
|
||||
* - Eventually, when the destructor of `UniFFIPointer` runs, we return
|
||||
* ownership to Rust, which then decrements the count and deallocates the
|
||||
* memory the pointer points to.
|
||||
* Clone the raw pointer that `UniFFIPointer` holds
|
||||
*
|
||||
* Use this when lowering the pointer to pass it across the FFI, for example:
|
||||
* - When calling a method
|
||||
* - When passing the object as an argument to a function
|
||||
*/
|
||||
void* GetPtr() const;
|
||||
void* ClonePtr() const;
|
||||
|
||||
/**
|
||||
* Returns true if the pointer type `this` holds is the same as the argument
|
||||
|
|
|
@ -21,7 +21,9 @@ namespace mozilla::uniffi {
|
|||
**/
|
||||
struct UniFFIPointerType {
|
||||
nsLiteralCString typeName;
|
||||
// The Rust destructor for the pointer, this gives back ownership to Rust
|
||||
// Rust FFI function to clone for the pointer
|
||||
void* (*clone)(void*, RustCallStatus*);
|
||||
// Rust FFI function to destroy for the pointer
|
||||
void (*destructor)(void*, RustCallStatus*);
|
||||
};
|
||||
} // namespace mozilla::uniffi
|
||||
|
|
|
@ -28,8 +28,8 @@ constexpr int8_t CALLBACK_INTERFACE_UNEXPECTED_ERROR = 2;
|
|||
// structs/functions from UniFFI
|
||||
extern "C" {
|
||||
struct RustBuffer {
|
||||
int32_t capacity;
|
||||
int32_t len;
|
||||
uint64_t capacity;
|
||||
uint64_t len;
|
||||
uint8_t* data;
|
||||
};
|
||||
|
||||
|
@ -42,7 +42,7 @@ typedef int (*ForeignCallback)(uint64_t handle, uint32_t method,
|
|||
const uint8_t* argsData, int32_t argsLen,
|
||||
RustBuffer* buf_ptr);
|
||||
|
||||
RustBuffer uniffi_rustbuffer_alloc(int32_t size, RustCallStatus* call_status);
|
||||
RustBuffer uniffi_rustbuffer_alloc(uint64_t size, RustCallStatus* call_status);
|
||||
void uniffi_rustbuffer_free(RustBuffer buf, RustCallStatus* call_status);
|
||||
}
|
||||
|
||||
|
|
|
@ -72,18 +72,19 @@ origin-trials-ffi = { path = "../../../../dom/origin-trials/ffi" }
|
|||
jog = { path = "../../../components/glean/bindings/jog" }
|
||||
dap_ffi = { path = "../../../components/telemetry/dap/ffi" }
|
||||
data-encoding-ffi = { path = "../../../../dom/fs/parent/rust/data-encoding-ffi" }
|
||||
uniffi-example-arithmetic = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "afb29ebdc1d9edf15021b1c5332fc9f285bbe13b", optional = true }
|
||||
uniffi-example-geometry = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "afb29ebdc1d9edf15021b1c5332fc9f285bbe13b", optional = true }
|
||||
uniffi-example-rondpoint = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "afb29ebdc1d9edf15021b1c5332fc9f285bbe13b", optional = true }
|
||||
uniffi-example-sprites = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "afb29ebdc1d9edf15021b1c5332fc9f285bbe13b", optional = true }
|
||||
uniffi-example-todolist = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "afb29ebdc1d9edf15021b1c5332fc9f285bbe13b", optional = true }
|
||||
uniffi-example-arithmetic = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "d52c5460ae42ecad1e73a5b394ac96d48f4769de", optional = true }
|
||||
uniffi-example-geometry = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "d52c5460ae42ecad1e73a5b394ac96d48f4769de", optional = true }
|
||||
uniffi-example-rondpoint = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "d52c5460ae42ecad1e73a5b394ac96d48f4769de", optional = true }
|
||||
uniffi-example-sprites = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "d52c5460ae42ecad1e73a5b394ac96d48f4769de", optional = true }
|
||||
uniffi-example-todolist = { git = "https://github.com/mozilla/uniffi-rs.git", rev = "d52c5460ae42ecad1e73a5b394ac96d48f4769de", optional = true }
|
||||
uniffi-example-custom-types = { path = "../../../components/uniffi-example-custom-types/", optional = true }
|
||||
uniffi-fixture-callbacks = { path = "../../../components/uniffi-fixture-callbacks/", optional = true }
|
||||
uniffi-fixture-external-types = { path = "../../../components/uniffi-fixture-external-types/", optional = true }
|
||||
uniffi-fixture-refcounts = { path = "../../../components/uniffi-fixture-refcounts/", optional = true }
|
||||
binary_http = { path = "../../../../netwerk/protocol/http/binary_http" }
|
||||
oblivious_http = { path = "../../../../netwerk/protocol/http/oblivious_http" }
|
||||
mime-guess-ffi = { path = "../../../../dom/fs/parent/rust/mime-guess-ffi" }
|
||||
uniffi = { version = "0.25.2" }
|
||||
uniffi = { workspace = true }
|
||||
|
||||
# Note: `modern_sqlite` means rusqlite's bindings file be for a sqlite with
|
||||
# version less than or equal to what we link to. This isn't a problem because we
|
||||
|
@ -145,7 +146,7 @@ thread_sanitizer = ["xpcom/thread_sanitizer"]
|
|||
uniffi_fixtures = [
|
||||
"uniffi-example-arithmetic", "uniffi-example-geometry", "uniffi-example-rondpoint", "uniffi-example-sprites",
|
||||
"uniffi-example-todolist", "uniffi-example-custom-types", "uniffi-fixture-callbacks",
|
||||
"uniffi-fixture-external-types",
|
||||
"uniffi-fixture-external-types", "uniffi-fixture-refcounts",
|
||||
]
|
||||
webmidi_midir_impl = ["midir_impl"]
|
||||
icu4x = ["jsrust_shared/icu4x"]
|
||||
|
|
|
@ -136,6 +136,7 @@ mod uniffi_fixtures {
|
|||
uniffi_fixture_callbacks::uniffi_reexport_scaffolding!();
|
||||
uniffi_custom_types::uniffi_reexport_scaffolding!();
|
||||
uniffi_fixture_external_types::uniffi_reexport_scaffolding!();
|
||||
uniffi_fixture_refcounts::uniffi_reexport_scaffolding!();
|
||||
uniffi_geometry::uniffi_reexport_scaffolding!();
|
||||
uniffi_rondpoint::uniffi_reexport_scaffolding!();
|
||||
uniffi_sprites::uniffi_reexport_scaffolding!();
|
||||
|
@ -174,7 +175,7 @@ pub unsafe extern "C" fn debug_log(target: *const c_char, message: *const c_char
|
|||
// Define extern "C" versions of these UniFFI functions, so that they can be called from C++
|
||||
#[no_mangle]
|
||||
pub extern "C" fn uniffi_rustbuffer_alloc(
|
||||
size: i32,
|
||||
size: u64,
|
||||
call_status: &mut uniffi::RustCallStatus,
|
||||
) -> uniffi::RustBuffer {
|
||||
uniffi::uniffi_rustbuffer_alloc(size, call_status)
|
||||
|
|
|
@ -14,6 +14,7 @@ trojan-source:
|
|||
- third_party/python/arrow/arrow/locales.py
|
||||
- third_party/rust/chardetng/src/data.rs
|
||||
- third_party/rust/clap_builder/src/output/textwrap/core.rs
|
||||
- third_party/rust/textwrap/src/core.rs
|
||||
- third_party/rust/icu_provider/src/hello_world.rs
|
||||
- third_party/rust/uniffi-example-rondpoint/tests/bindings/test_rondpoint.py
|
||||
- third_party/rust/error-chain/tests/tests.rs
|
||||
|
|
Загрузка…
Ссылка в новой задаче