Bug 1922351 - Move ffi serde serialization from Servo into somewhere usable by other crates in the tree. r=nika

Differential Revision: https://phabricator.services.mozilla.com/D224394
This commit is contained in:
Emilio Cobos Álvarez 2024-10-04 07:51:46 +00:00
parent e04c8b5dbf
commit 4f1b4c38f6
15 changed files with 166 additions and 155 deletions

10
Cargo.lock generated
View File

@ -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"

View File

@ -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",

View File

@ -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<mozilla::layers::DoubleTapToZoomMetrics> {
}
};
#define IMPL_PARAMTRAITS_BY_SERDE(type_) \
template <> \
struct ParamTraits<mozilla::type_> { \
typedef mozilla::type_ paramType; \
static void Write(MessageWriter* aWriter, const paramType& aParam) { \
mozilla::ipc::ByteBuf v; \
mozilla::DebugOnly<bool> rv = Servo_##type_##_Serialize(&aParam, &v); \
MOZ_ASSERT(rv, "Serialize ##type_## failed"); \
WriteParam(aWriter, std::move(v)); \
} \
static ReadResult<paramType> Read(MessageReader* aReader) { \
mozilla::ipc::ByteBuf in; \
ReadResult<paramType> result; \
if (!ReadParam(aReader, &in) || !in.mData) { \
return result; \
} \
/* TODO: Should be able to initialize `result` in-place instead */ \
mozilla::AlignedStorage2<paramType> 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 */

View File

@ -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<type_> { \
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<paramType> Read(IPC::MessageReader* aReader) { \
mozilla::ipc::ByteBuf in; \
IPC::ReadResult<paramType> result; \
if (!ReadParam(aReader, &in) || !in.mData) { \
return result; \
} \
/* TODO: Should be able to initialize `result` in-place instead */ \
mozilla::AlignedStorage2<paramType> value; \
if (!deserializer_(in.mData, in.mLen, value.addr())) { \
return result; \
} \
result = std::move(*value.addr()); \
value.addr()->~paramType(); \
return result; \
} \
};
#endif

View File

@ -54,6 +54,7 @@ EXPORTS.mozilla.ipc += [
"ProtocolUtils.h",
"RandomAccessStreamUtils.h",
"RawShmem.h",
"RustMessageUtils.h",
"ScopedPort.h",
"SerializedStructuredCloneBuffer.h",
"SharedMemory.h",

View File

@ -0,0 +1,14 @@
[package]
name = "ipdl_utils"
version = "0.1.0"
edition = "2021"
authors = [
"Emilio Cobos Álvarez <emilio@crisal.io>",
]
license = "MPL-2.0"
[lib]
path = "lib.rs"
[dependencies]
bincode = "1"

View File

@ -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
}
};
}

View File

@ -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);

View File

@ -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",

View File

@ -125,10 +125,6 @@ class ImageTracker;
} // namespace dom
namespace ipc {
class ByteBuf;
} // namespace ipc
// Replacement for a Rust Box<T> for a non-dynamically-sized-type.
//
// TODO(emilio): If this was some sort of nullable box then this could be made

View File

@ -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"]}

View File

@ -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<u8>) -> 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.

View File

@ -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)]

View File

@ -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"] }

View File

@ -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;