diff --git a/Cargo.lock b/Cargo.lock index 4303101d9b12..25725e6d588b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2273,11 +2273,11 @@ name = "geckoservo" version = "0.0.1" dependencies = [ "atomic_refcell", - "bincode", "cssparser", "cstr", "dom", "gecko-profiler", + "ipdl_utils", "lazy_static", "libc", "log", @@ -2402,6 +2402,7 @@ dependencies = [ "gkrust_utils", "http_sfv", "idna_glue", + "ipdl_utils", "jog", "jsrust_shared", "kvstore", @@ -3191,6 +3192,13 @@ dependencies = [ "sha2", ] +[[package]] +name = "ipdl_utils" +version = "0.1.0" +dependencies = [ + "bincode", +] + [[package]] name = "itertools" version = "0.10.5" diff --git a/Cargo.toml b/Cargo.toml index 4ac92de912d2..5473cfa71d10 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,7 @@ exclude = [ "tools/fuzzing/rust", "dom/base/rust", "dom/origin-trials/ffi", + "ipc/rust/ipdl_utils", # Excluded because we don't want to vendor their dependencies. "intl/l10n/rust/l10nregistry-tests", diff --git a/gfx/layers/ipc/LayersMessageUtils.h b/gfx/layers/ipc/LayersMessageUtils.h index b48c6438d8aa..323c28b097b4 100644 --- a/gfx/layers/ipc/LayersMessageUtils.h +++ b/gfx/layers/ipc/LayersMessageUtils.h @@ -21,6 +21,7 @@ #include "mozilla/dom/WebGLIpdl.h" #include "mozilla/ipc/ByteBuf.h" #include "mozilla/ipc/ProtocolMessageUtils.h" +#include "mozilla/ipc/RustMessageUtils.h" #include "mozilla/layers/APZInputBridge.h" #include "mozilla/layers/AsyncDragMetrics.h" #include "mozilla/layers/CompositorOptions.h" @@ -1159,44 +1160,23 @@ struct ParamTraits { } }; -#define IMPL_PARAMTRAITS_BY_SERDE(type_) \ - template <> \ - struct ParamTraits { \ - typedef mozilla::type_ paramType; \ - static void Write(MessageWriter* aWriter, const paramType& aParam) { \ - mozilla::ipc::ByteBuf v; \ - mozilla::DebugOnly rv = Servo_##type_##_Serialize(&aParam, &v); \ - MOZ_ASSERT(rv, "Serialize ##type_## failed"); \ - WriteParam(aWriter, std::move(v)); \ - } \ - static ReadResult Read(MessageReader* aReader) { \ - mozilla::ipc::ByteBuf in; \ - ReadResult result; \ - if (!ReadParam(aReader, &in) || !in.mData) { \ - return result; \ - } \ - /* TODO: Should be able to initialize `result` in-place instead */ \ - mozilla::AlignedStorage2 value; \ - if (!Servo_##type_##_Deserialize(&in, value.addr())) { \ - return result; \ - } \ - result = std::move(*value.addr()); \ - value.addr()->~paramType(); \ - return result; \ - } \ - }; - -IMPL_PARAMTRAITS_BY_SERDE(LengthPercentage) -IMPL_PARAMTRAITS_BY_SERDE(StyleOffsetPath) -IMPL_PARAMTRAITS_BY_SERDE(StyleOffsetRotate) -IMPL_PARAMTRAITS_BY_SERDE(StylePositionOrAuto) -IMPL_PARAMTRAITS_BY_SERDE(StyleOffsetPosition) -IMPL_PARAMTRAITS_BY_SERDE(StyleRotate) -IMPL_PARAMTRAITS_BY_SERDE(StyleScale) -IMPL_PARAMTRAITS_BY_SERDE(StyleTranslate) -IMPL_PARAMTRAITS_BY_SERDE(StyleTransform) -IMPL_PARAMTRAITS_BY_SERDE(StyleComputedTimingFunction) - } /* namespace IPC */ +#define DEFINE_SERVO_PARAMTRAITS(ty_) \ + MOZ_DEFINE_RUST_PARAMTRAITS(mozilla::ty_, Servo_##ty_##_Serialize, \ + Servo_##ty_##_Deserialize) + +DEFINE_SERVO_PARAMTRAITS(LengthPercentage) +DEFINE_SERVO_PARAMTRAITS(StyleOffsetPath) +DEFINE_SERVO_PARAMTRAITS(StyleOffsetRotate) +DEFINE_SERVO_PARAMTRAITS(StylePositionOrAuto) +DEFINE_SERVO_PARAMTRAITS(StyleOffsetPosition) +DEFINE_SERVO_PARAMTRAITS(StyleRotate) +DEFINE_SERVO_PARAMTRAITS(StyleScale) +DEFINE_SERVO_PARAMTRAITS(StyleTranslate) +DEFINE_SERVO_PARAMTRAITS(StyleTransform) +DEFINE_SERVO_PARAMTRAITS(StyleComputedTimingFunction) + +#undef DEFINE_SERVO_PARAMTRAITS + #endif /* mozilla_layers_LayersMessageUtils */ diff --git a/ipc/glue/RustMessageUtils.h b/ipc/glue/RustMessageUtils.h new file mode 100644 index 000000000000..901466682adf --- /dev/null +++ b/ipc/glue/RustMessageUtils.h @@ -0,0 +1,42 @@ +/* -*- Mode: C++; tab-width: 4; 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/. */ + +#ifndef mozilla_ipc_RustMessageUtils_h +#define mozilla_ipc_RustMessageUtils_h + +#include "chrome/common/ipc_message_utils.h" + +// Some macros for rust integrations. See ipc/rust/ipdl_utils +#define MOZ_DEFINE_RUST_PARAMTRAITS(type_, serializer_, deserializer_) \ + extern "C" uint8_t* serializer_(const type_*, size_t* len, size_t* cap); \ + extern "C" bool deserializer_(const uint8_t*, size_t len, type_*); \ + \ + template <> \ + struct IPC::ParamTraits { \ + using paramType = type_; \ + static void Write(IPC::MessageWriter* aWriter, const paramType& aParam) { \ + size_t len, cap; \ + uint8_t* buf = serializer_(&aParam, &cap, &len); \ + MOZ_DIAGNOSTIC_ASSERT(buf, #type_ " serialization failed"); \ + WriteParam(aWriter, mozilla::ipc::ByteBuf(buf, len, cap)); \ + } \ + static IPC::ReadResult Read(IPC::MessageReader* aReader) { \ + mozilla::ipc::ByteBuf in; \ + IPC::ReadResult result; \ + if (!ReadParam(aReader, &in) || !in.mData) { \ + return result; \ + } \ + /* TODO: Should be able to initialize `result` in-place instead */ \ + mozilla::AlignedStorage2 value; \ + if (!deserializer_(in.mData, in.mLen, value.addr())) { \ + return result; \ + } \ + result = std::move(*value.addr()); \ + value.addr()->~paramType(); \ + return result; \ + } \ + }; + +#endif diff --git a/ipc/glue/moz.build b/ipc/glue/moz.build index cc699a8ffa5c..e07fbddf46f0 100644 --- a/ipc/glue/moz.build +++ b/ipc/glue/moz.build @@ -54,6 +54,7 @@ EXPORTS.mozilla.ipc += [ "ProtocolUtils.h", "RandomAccessStreamUtils.h", "RawShmem.h", + "RustMessageUtils.h", "ScopedPort.h", "SerializedStructuredCloneBuffer.h", "SharedMemory.h", diff --git a/ipc/rust/ipdl_utils/Cargo.toml b/ipc/rust/ipdl_utils/Cargo.toml new file mode 100644 index 000000000000..3b796e0961c4 --- /dev/null +++ b/ipc/rust/ipdl_utils/Cargo.toml @@ -0,0 +1,14 @@ +[package] +name = "ipdl_utils" +version = "0.1.0" +edition = "2021" +authors = [ + "Emilio Cobos Álvarez ", +] +license = "MPL-2.0" + +[lib] +path = "lib.rs" + +[dependencies] +bincode = "1" diff --git a/ipc/rust/ipdl_utils/lib.rs b/ipc/rust/ipdl_utils/lib.rs new file mode 100644 index 000000000000..448ad57ae5a7 --- /dev/null +++ b/ipc/rust/ipdl_utils/lib.rs @@ -0,0 +1,47 @@ +/* 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 https://mozilla.org/MPL/2.0/. */ + +#[doc(hidden)] +pub use bincode as _bincode; + +/// Takes a type, a serializer, and a deserializer name. The type must implement serde::Serialize. +/// Defines a pair of ffi functions that go along with the MOZ_DEFINE_RUST_PARAMTRAITS macro. +#[macro_export] +macro_rules! define_ffi_serializer { + ($ty:ty, $serializer:ident, $deserializer:ident) => { + #[no_mangle] + pub extern "C" fn $serializer( + v: &$ty, + out_len: &mut usize, + out_cap: &mut usize, + ) -> *mut u8 { + *out_len = 0; + *out_cap = 0; + let mut buf = match $crate::_bincode::serialize(v) { + Ok(buf) => buf, + Err(..) => return std::ptr::null_mut(), + }; + *out_len = buf.len(); + *out_cap = buf.capacity(); + let ptr = buf.as_mut_ptr(); + std::mem::forget(buf); + ptr + } + + #[no_mangle] + pub unsafe extern "C" fn $deserializer( + input: *const u8, + len: usize, + out: *mut $ty, + ) -> bool { + let slice = std::slice::from_raw_parts(input, len); + let element = match $crate::_bincode::deserialize(slice) { + Ok(buf) => buf, + Err(..) => return false, + }; + std::ptr::write(out, element); + true + } + }; +} diff --git a/layout/style/ServoBindings.h b/layout/style/ServoBindings.h index e6690b844617..f1b0a47c29c4 100644 --- a/layout/style/ServoBindings.h +++ b/layout/style/ServoBindings.h @@ -103,23 +103,6 @@ BASIC_RULE_FUNCS_LOCKED(NestedDeclarations) #undef BASIC_RULE_FUNCS_WITHOUT_GETTER_UNLOCKED #undef BASIC_RULE_FUNCS_WITHOUT_GETTER_WITH_PREFIX -#define BASIC_SERDE_FUNCS(type_) \ - bool Servo_##type_##_Deserialize(mozilla::ipc::ByteBuf* input, type_* v); \ - bool Servo_##type_##_Serialize(const type_* v, mozilla::ipc::ByteBuf* output); - -BASIC_SERDE_FUNCS(LengthPercentage) -BASIC_SERDE_FUNCS(StyleRotate) -BASIC_SERDE_FUNCS(StyleScale) -BASIC_SERDE_FUNCS(StyleTranslate) -BASIC_SERDE_FUNCS(StyleTransform) -BASIC_SERDE_FUNCS(StyleOffsetPath) -BASIC_SERDE_FUNCS(StyleOffsetRotate) -BASIC_SERDE_FUNCS(StylePositionOrAuto) -BASIC_SERDE_FUNCS(StyleOffsetPosition) -BASIC_SERDE_FUNCS(StyleComputedTimingFunction) - -#undef BASIC_SERDE_FUNCS - void Servo_CounterStyleRule_GetDescriptorCssText( const StyleLockedCounterStyleRule* rule, nsCSSCounterDesc desc, nsACString* result); diff --git a/layout/style/ServoBindings.toml b/layout/style/ServoBindings.toml index b8e66d8f6025..ccd244bbeb24 100644 --- a/layout/style/ServoBindings.toml +++ b/layout/style/ServoBindings.toml @@ -12,7 +12,6 @@ headers = [ "mozilla/dom/MediaList.h", "mozilla/dom/ShadowRoot.h", "mozilla/gfx/FontFeature.h", - "mozilla/ipc/ByteBuf.h", "mozilla/AnimationPropertySegment.h", "mozilla/ComputedTiming.h", "mozilla/CORSMode.h", @@ -209,7 +208,6 @@ allowlist-types = [ "mozilla::dom::IterationCompositeOperation", "mozilla::dom::StyleChildrenIterator", "mozilla::HalfCorner", - "mozilla::ipc::ByteBuf", "mozilla::MallocSizeOf", "mozilla::OriginFlags", "mozilla::PropertyStyleAnimationValuePair", diff --git a/layout/style/ServoStyleConstsForwards.h b/layout/style/ServoStyleConstsForwards.h index d6c5ec089e59..d78e073348db 100644 --- a/layout/style/ServoStyleConstsForwards.h +++ b/layout/style/ServoStyleConstsForwards.h @@ -125,10 +125,6 @@ class ImageTracker; } // namespace dom -namespace ipc { -class ByteBuf; -} // namespace ipc - // Replacement for a Rust Box for a non-dynamically-sized-type. // // TODO(emilio): If this was some sort of nullable box then this could be made diff --git a/servo/ports/geckolib/Cargo.toml b/servo/ports/geckolib/Cargo.toml index 37a44c2e61c7..165a1e3ba9b5 100644 --- a/servo/ports/geckolib/Cargo.toml +++ b/servo/ports/geckolib/Cargo.toml @@ -3,6 +3,7 @@ name = "geckoservo" version = "0.0.1" authors = ["The Servo Project Developers"] license = "MPL-2.0" +edition = "2021" [lib] name = "geckoservo" @@ -14,10 +15,10 @@ gecko_refcount_logging = ["style/gecko_refcount_logging", "servo_arc/gecko_refco [dependencies] atomic_refcell = "0.1" -bincode = "1.0" cssparser = "0.34" cstr = "0.2" dom = { path = "../../../dom/base/rust" } +ipdl_utils = { path = "../../../ipc/rust/ipdl_utils" } gecko-profiler = { path = "../../../tools/profiler/rust-api" } libc = "0.2" log = {version = "0.4", features = ["release_max_level_info"]} diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs index 437984e438df..35decb837d12 100644 --- a/servo/ports/geckolib/glue.rs +++ b/servo/ports/geckolib/glue.rs @@ -4,7 +4,6 @@ use super::error_reporter::ErrorReporter; use super::stylesheet_loader::{AsyncStylesheetParser, StylesheetLoader}; -use bincode::{deserialize, serialize}; use cssparser::ToCss as ParserToCss; use cssparser::{ BasicParseError, ParseError as CssParseError, Parser, ParserInput, ParserState, SourceLocation, @@ -60,7 +59,6 @@ use style::gecko_bindings::bindings::Gecko_HaveSeenPtr; use style::gecko_bindings::structs; use style::gecko_bindings::structs::gfx::FontPaletteValueSet; use style::gecko_bindings::structs::gfxFontFeatureValueSet; -use style::gecko_bindings::structs::ipc::ByteBuf; use style::gecko_bindings::structs::nsAtom; use style::gecko_bindings::structs::nsCSSCounterDesc; use style::gecko_bindings::structs::nsCSSFontDesc; @@ -994,110 +992,64 @@ pub extern "C" fn Servo_AnimationValue_Uncompute( .into() } -#[inline] -fn create_byte_buf_from_vec(mut v: Vec) -> ByteBuf { - let w = ByteBuf { - mData: v.as_mut_ptr(), - mLen: v.len(), - mCapacity: v.capacity(), - }; - std::mem::forget(v); - w -} - -#[inline] -fn view_byte_buf(b: &ByteBuf) -> &[u8] { - if b.mData.is_null() { - debug_assert_eq!(b.mCapacity, 0); - return &[]; - } - unsafe { std::slice::from_raw_parts(b.mData, b.mLen) } -} - -macro_rules! impl_basic_serde_funcs { - ($ser_name:ident, $de_name:ident, $computed_type:ty) => { - #[no_mangle] - pub extern "C" fn $ser_name(v: &$computed_type, output: &mut ByteBuf) -> bool { - let buf = match serialize(v) { - Ok(buf) => buf, - Err(..) => return false, - }; - - *output = create_byte_buf_from_vec(buf); - true - } - - #[no_mangle] - pub unsafe extern "C" fn $de_name(input: &ByteBuf, v: *mut $computed_type) -> bool { - let buf = match deserialize(view_byte_buf(input)) { - Ok(buf) => buf, - Err(..) => return false, - }; - - std::ptr::write(v, buf); - true - } - }; -} - -impl_basic_serde_funcs!( +ipdl_utils::define_ffi_serializer!( + computed::LengthPercentage, Servo_LengthPercentage_Serialize, - Servo_LengthPercentage_Deserialize, - computed::LengthPercentage + Servo_LengthPercentage_Deserialize ); -impl_basic_serde_funcs!( +ipdl_utils::define_ffi_serializer!( + computed::transform::Rotate, Servo_StyleRotate_Serialize, - Servo_StyleRotate_Deserialize, - computed::transform::Rotate + Servo_StyleRotate_Deserialize ); -impl_basic_serde_funcs!( +ipdl_utils::define_ffi_serializer!( + computed::transform::Scale, Servo_StyleScale_Serialize, - Servo_StyleScale_Deserialize, - computed::transform::Scale + Servo_StyleScale_Deserialize ); -impl_basic_serde_funcs!( +ipdl_utils::define_ffi_serializer!( + computed::transform::Translate, Servo_StyleTranslate_Serialize, - Servo_StyleTranslate_Deserialize, - computed::transform::Translate + Servo_StyleTranslate_Deserialize ); -impl_basic_serde_funcs!( +ipdl_utils::define_ffi_serializer!( + computed::transform::Transform, Servo_StyleTransform_Serialize, - Servo_StyleTransform_Deserialize, - computed::transform::Transform + Servo_StyleTransform_Deserialize ); -impl_basic_serde_funcs!( +ipdl_utils::define_ffi_serializer!( + computed::motion::OffsetPath, Servo_StyleOffsetPath_Serialize, - Servo_StyleOffsetPath_Deserialize, - computed::motion::OffsetPath + Servo_StyleOffsetPath_Deserialize ); -impl_basic_serde_funcs!( +ipdl_utils::define_ffi_serializer!( + computed::motion::OffsetRotate, Servo_StyleOffsetRotate_Serialize, - Servo_StyleOffsetRotate_Deserialize, - computed::motion::OffsetRotate + Servo_StyleOffsetRotate_Deserialize ); -impl_basic_serde_funcs!( +ipdl_utils::define_ffi_serializer!( + computed::position::PositionOrAuto, Servo_StylePositionOrAuto_Serialize, - Servo_StylePositionOrAuto_Deserialize, - computed::position::PositionOrAuto + Servo_StylePositionOrAuto_Deserialize ); -impl_basic_serde_funcs!( +ipdl_utils::define_ffi_serializer!( + computed::motion::OffsetPosition, Servo_StyleOffsetPosition_Serialize, - Servo_StyleOffsetPosition_Deserialize, - computed::motion::OffsetPosition + Servo_StyleOffsetPosition_Deserialize ); -impl_basic_serde_funcs!( +ipdl_utils::define_ffi_serializer!( + ComputedTimingFunction, Servo_StyleComputedTimingFunction_Serialize, - Servo_StyleComputedTimingFunction_Deserialize, - ComputedTimingFunction + Servo_StyleComputedTimingFunction_Deserialize ); // Return the ComputedValues by a base ComputedValues and the rules. diff --git a/servo/ports/geckolib/lib.rs b/servo/ports/geckolib/lib.rs index 8f6f344d4ddd..46797cabadbe 100644 --- a/servo/ports/geckolib/lib.rs +++ b/servo/ports/geckolib/lib.rs @@ -2,28 +2,14 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -extern crate bincode; -extern crate cssparser; #[macro_use] extern crate cstr; -extern crate dom; #[macro_use] extern crate gecko_profiler; -extern crate libc; #[macro_use] extern crate log; -extern crate malloc_size_of; -extern crate nsstring; -extern crate num_traits; -extern crate selectors; -extern crate servo_arc; -extern crate smallvec; #[macro_use] extern crate style; -extern crate style_traits; -extern crate thin_vec; -extern crate to_shmem; -extern crate lazy_static; mod error_reporter; #[allow(non_snake_case)] diff --git a/toolkit/library/rust/shared/Cargo.toml b/toolkit/library/rust/shared/Cargo.toml index e0d17d9b22fd..d21b9a904e18 100644 --- a/toolkit/library/rust/shared/Cargo.toml +++ b/toolkit/library/rust/shared/Cargo.toml @@ -55,6 +55,7 @@ fog_control = { path = "../../../components/glean" } app_services_logger = { path = "../../../../services/common/app_services_logger" } http_sfv = { path = "../../../../netwerk/base/http-sfv" } idna_glue = { path = "../../../../netwerk/base/idna_glue" } +ipdl_utils = { path = "../../../../ipc/rust/ipdl_utils" } unic-langid = { version = "0.9", features = ["likelysubtags"] } unic-langid-ffi = { path = "../../../../intl/locale/rust/unic-langid-ffi" } fluent-langneg = { version = "0.13", features = ["cldr"] } diff --git a/toolkit/library/rust/shared/lib.rs b/toolkit/library/rust/shared/lib.rs index 7910ca4f63f6..c5385d938a67 100644 --- a/toolkit/library/rust/shared/lib.rs +++ b/toolkit/library/rust/shared/lib.rs @@ -32,6 +32,7 @@ extern crate gecko_profiler; extern crate gkrust_utils; extern crate http_sfv; extern crate idna_glue; +extern crate ipdl_utils; extern crate jog; extern crate jsrust_shared; extern crate kvstore;