From 8bed07292c0a36673e72080f0ba18d98f35b31a4 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Tue, 23 Aug 2016 20:10:08 +0530 Subject: [PATCH] Add bindings for owned types, use for servostyleset --- ports/geckolib/binding_tools/regen.py | 15 ++++---- ports/geckolib/data.rs | 3 +- ports/geckolib/gecko_bindings/bindings.rs | 7 ++-- ports/geckolib/gecko_bindings/sugar/refptr.rs | 36 +++++++++++++++++++ ports/geckolib/glue.rs | 14 ++++---- 5 files changed, 56 insertions(+), 19 deletions(-) diff --git a/ports/geckolib/binding_tools/regen.py b/ports/geckolib/binding_tools/regen.py index 1e767ff1701..08ae548205c 100755 --- a/ports/geckolib/binding_tools/regen.py +++ b/ports/geckolib/binding_tools/regen.py @@ -154,12 +154,9 @@ COMPILATION_TARGETS = { "ServoComputedValues", "RawServoStyleSheet", "ServoDeclarationBlock" ], - "servo_borrowed_types": [ + "servo_owned_types": [ "RawServoStyleSet", ], - "servo_borrowed_mut_types": [ - "RawServoStyleSet", - ] }, "atoms": { @@ -331,18 +328,20 @@ def build(objdir, target_name, debug, debugger, kind_name=None, flags.append("{}Borrowed".format(ty)) flags.append("--raw-line") flags.append("pub type {0}Borrowed<'a> = ::sugar::refptr::Borrowed<'a, {0}>;".format(ty)) - if "servo_borrowed_types" in current_target: - for ty in current_target["servo_borrowed_types"]: + if "servo_owned_types" in current_target: + for ty in current_target["servo_owned_types"]: flags.append("-blacklist-type") flags.append("{}Borrowed".format(ty)) flags.append("-raw-line") flags.append("pub type {0}Borrowed<'a> = &'a {0};".format(ty)) - if "servo_borrowed_mut_types" in current_target: - for ty in current_target["servo_borrowed_mut_types"]: flags.append("-blacklist-type") flags.append("{}BorrowedMut".format(ty)) flags.append("-raw-line") flags.append("pub type {0}BorrowedMut<'a> = &'a mut {0};".format(ty)) + flags.append("-blacklist-type") + flags.append("{}Owned".format(ty)) + flags.append("-raw-line") + flags.append("pub type {0}Owned = ::sugar::refptr::Owned<{0}>;".format(ty)) if "structs_types" in current_target: for ty in current_target["structs_types"]: ty_fragments = ty.split("::") diff --git a/ports/geckolib/data.rs b/ports/geckolib/data.rs index 769e8b7e79d..893206901a4 100644 --- a/ports/geckolib/data.rs +++ b/ports/geckolib/data.rs @@ -4,7 +4,7 @@ use euclid::size::TypedSize2D; use gecko_bindings::bindings::RawServoStyleSet; -use gecko_bindings::sugar::refptr::{HasSimpleFFI, HasFFI}; +use gecko_bindings::sugar::refptr::{HasBoxFFI, HasFFI, HasSimpleFFI}; use num_cpus; use std::cmp; use std::collections::HashMap; @@ -94,6 +94,7 @@ unsafe impl HasFFI for PerDocumentStyleData { type FFIType = RawServoStyleSet; } unsafe impl HasSimpleFFI for PerDocumentStyleData {} +unsafe impl HasBoxFFI for PerDocumentStyleData {} impl Drop for PerDocumentStyleData { fn drop(&mut self) { diff --git a/ports/geckolib/gecko_bindings/bindings.rs b/ports/geckolib/gecko_bindings/bindings.rs index 26bf82e6894..3696b30fd42 100644 --- a/ports/geckolib/gecko_bindings/bindings.rs +++ b/ports/geckolib/gecko_bindings/bindings.rs @@ -13,6 +13,7 @@ pub type ServoDeclarationBlockStrong = ::sugar::refptr::Strong = ::sugar::refptr::Borrowed<'a, ServoDeclarationBlock>; pub type RawServoStyleSetBorrowed<'a> = &'a RawServoStyleSet; pub type RawServoStyleSetBorrowedMut<'a> = &'a mut RawServoStyleSet; +pub type RawServoStyleSetOwned = ::sugar::refptr::Owned; use structs::nsStyleFont; unsafe impl Send for nsStyleFont {} unsafe impl Sync for nsStyleFont {} @@ -472,9 +473,9 @@ extern "C" { pub fn Servo_StyleSheet_Release(sheet: RawServoStyleSheetBorrowed); pub fn Servo_StyleSheet_HasRules(sheet: RawServoStyleSheetBorrowed) -> bool; - pub fn Servo_StyleSet_Init() -> *mut RawServoStyleSet; - pub fn Servo_StyleSet_Drop(set: *mut RawServoStyleSet); - pub fn Servo_StyleSet_AppendStyleSheet(set: *mut RawServoStyleSet, + pub fn Servo_StyleSet_Init() -> RawServoStyleSetOwned; + pub fn Servo_StyleSet_Drop(set: RawServoStyleSetOwned); + pub fn Servo_StyleSet_AppendStyleSheet(set: RawServoStyleSetBorrowedMut, sheet: RawServoStyleSheetBorrowed); pub fn Servo_StyleSet_PrependStyleSheet(set: RawServoStyleSetBorrowedMut, sheet: diff --git a/ports/geckolib/gecko_bindings/sugar/refptr.rs b/ports/geckolib/gecko_bindings/sugar/refptr.rs index a70ad3d20ad..2030ccbe807 100644 --- a/ports/geckolib/gecko_bindings/sugar/refptr.rs +++ b/ports/geckolib/gecko_bindings/sugar/refptr.rs @@ -4,6 +4,7 @@ use std::marker::PhantomData; use std::mem::{forget, transmute}; +use std::ops::{Deref, DerefMut}; use std::ptr; use std::sync::Arc; @@ -32,6 +33,14 @@ pub unsafe trait HasSimpleFFI : HasFFI { } } +/// Indicates that the given Servo type is passed over FFI +/// as a Box +pub unsafe trait HasBoxFFI : HasSimpleFFI { + fn into_ffi(self: Box) -> Owned { + unsafe { transmute(self) } + } +} + /// Helper trait for conversions between FFI Strong/Borrowed types and Arcs /// /// Should be implemented by types which are passed over FFI as Arcs @@ -138,3 +147,30 @@ unsafe impl FFIArcHelpers for Arc { unsafe { ptr::read(borrowedptr) } } } + +#[repr(C)] +/// Gecko-FFI-safe owned pointer +/// Cannot be null +pub struct Owned { + ptr: *mut T, + _marker: PhantomData, +} + +impl Owned { + pub fn into_box(self) -> Box where U: HasBoxFFI { + unsafe { transmute(self) } + } +} + +impl Deref for Owned { + type Target = T; + fn deref(&self) -> &T { + unsafe { &*self.ptr } + } +} + +impl DerefMut for Owned { + fn deref_mut(&mut self) -> &mut T { + unsafe { &mut *self.ptr } + } +} diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 404a1e6fe22..4431a6b55b1 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -10,6 +10,7 @@ use env_logger; use euclid::Size2D; use gecko_bindings::bindings::{RawGeckoDocument, RawGeckoElement, RawGeckoNode}; use gecko_bindings::bindings::{RawServoStyleSet, RawServoStyleSetBorrowedMut}; +use gecko_bindings::bindings::RawServoStyleSetOwned; use gecko_bindings::bindings::{RawServoStyleSheetBorrowed, ServoComputedValuesBorrowed}; use gecko_bindings::bindings::{RawServoStyleSheetStrong, ServoComputedValuesStrong}; use gecko_bindings::bindings::{ServoDeclarationBlock, ServoNodeData, ThreadSafePrincipalHolder}; @@ -19,7 +20,8 @@ use gecko_bindings::ptr::{GeckoArcPrincipal, GeckoArcURI}; use gecko_bindings::structs::ServoElementSnapshot; use gecko_bindings::structs::nsRestyleHint; use gecko_bindings::structs::{SheetParsingMode, nsIAtom}; -use gecko_bindings::sugar::refptr::{FFIArcHelpers, HasArcFFI, HasSimpleFFI, HasFFI, Strong}; +use gecko_bindings::sugar::refptr::{FFIArcHelpers, HasArcFFI, HasBoxFFI}; +use gecko_bindings::sugar::refptr::{HasSimpleFFI, HasFFI, Strong}; use gecko_string_cache::Atom; use snapshot::GeckoElementSnapshot; use std::mem::transmute; @@ -336,16 +338,14 @@ pub extern "C" fn Servo_ComputedValues_Release(ptr: ServoComputedValuesBorrowed) } #[no_mangle] -pub extern "C" fn Servo_StyleSet_Init() -> *mut RawServoStyleSet { +pub extern "C" fn Servo_StyleSet_Init() -> RawServoStyleSetOwned { let data = Box::new(PerDocumentStyleData::new()); - Box::into_raw(data) as *mut RawServoStyleSet + data.into_ffi() } #[no_mangle] -pub extern "C" fn Servo_StyleSet_Drop(data: *mut RawServoStyleSet) -> () { - unsafe { - let _ = Box::::from_raw(data as *mut PerDocumentStyleData); - } +pub extern "C" fn Servo_StyleSet_Drop(data: RawServoStyleSetOwned) -> () { + let _ = data.into_box::(); } pub struct GeckoDeclarationBlock {