mirror of
https://github.com/servo/servo.git
synced 2025-08-03 20:50:07 +01:00
Merge pull request #3170 from SimonSapin/trait-object-transmute
Transmute std::raw::TraitObject rather than (some) custom tuples/structs
This commit is contained in:
commit
aea6f849a0
3 changed files with 38 additions and 28 deletions
|
@ -57,6 +57,7 @@ use std::mem;
|
|||
use std::num::Zero;
|
||||
use std::fmt;
|
||||
use std::iter::Zip;
|
||||
use std::raw;
|
||||
use std::sync::atomics::{AtomicUint, Relaxed, SeqCst};
|
||||
use std::slice::MutItems;
|
||||
use style::computed_values::{clear, position, text_align};
|
||||
|
@ -274,8 +275,8 @@ pub trait Flow: fmt::Show + ToString + Share {
|
|||
#[inline(always)]
|
||||
pub fn base<'a>(this: &'a Flow) -> &'a BaseFlow {
|
||||
unsafe {
|
||||
let (_, ptr): (uint, &BaseFlow) = mem::transmute(this);
|
||||
ptr
|
||||
let obj = mem::transmute::<&'a Flow, raw::TraitObject>(this);
|
||||
mem::transmute::<*mut (), &'a BaseFlow>(obj.data)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -287,8 +288,8 @@ pub fn imm_child_iter<'a>(flow: &'a Flow) -> FlowListIterator<'a> {
|
|||
#[inline(always)]
|
||||
pub fn mut_base<'a>(this: &'a mut Flow) -> &'a mut BaseFlow {
|
||||
unsafe {
|
||||
let (_, ptr): (uint, &mut BaseFlow) = mem::transmute(this);
|
||||
ptr
|
||||
let obj = mem::transmute::<&'a mut Flow, raw::TraitObject>(this);
|
||||
mem::transmute::<*mut (), &'a mut BaseFlow>(obj.data)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,16 +11,14 @@ use flow_ref::FlowRef;
|
|||
use std::kinds::marker::ContravariantLifetime;
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::raw;
|
||||
|
||||
pub type Link = Option<FlowRef>;
|
||||
|
||||
|
||||
// FIXME: use TraitObject instead of duplicating the type
|
||||
#[allow(raw_pointer_deriving)]
|
||||
#[deriving(Clone)]
|
||||
pub struct Rawlink<'a> {
|
||||
vtable: *mut (),
|
||||
obj: *mut (),
|
||||
object: raw::TraitObject,
|
||||
marker: ContravariantLifetime<'a>,
|
||||
}
|
||||
|
||||
|
@ -50,23 +48,29 @@ impl<'a> Rawlink<'a> {
|
|||
/// Like Option::None for Rawlink
|
||||
pub fn none() -> Rawlink<'static> {
|
||||
Rawlink {
|
||||
object: raw::TraitObject {
|
||||
vtable: ptr::mut_null(),
|
||||
obj: ptr::mut_null(),
|
||||
data: ptr::mut_null(),
|
||||
},
|
||||
marker: ContravariantLifetime,
|
||||
}
|
||||
}
|
||||
|
||||
/// Like Option::Some for Rawlink
|
||||
pub fn some(n: &Flow) -> Rawlink {
|
||||
unsafe { mem::transmute(n) }
|
||||
unsafe {
|
||||
Rawlink {
|
||||
object: mem::transmute::<&Flow, raw::TraitObject>(n),
|
||||
marker: ContravariantLifetime,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn resolve_mut(&self) -> Option<&'a mut Flow> {
|
||||
if self.obj.is_null() {
|
||||
if self.object.data.is_null() {
|
||||
None
|
||||
} else {
|
||||
let me: &mut Flow = mem::transmute_copy(self);
|
||||
Some(me)
|
||||
Some(mem::transmute_copy::<raw::TraitObject, &mut Flow>(&self.object))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,13 +11,12 @@ use flow;
|
|||
|
||||
use std::mem;
|
||||
use std::ptr;
|
||||
use std::raw;
|
||||
use std::sync::atomics::SeqCst;
|
||||
|
||||
// FIXME: This should probably be a wrapper on TraitObject.
|
||||
#[unsafe_no_drop_flag]
|
||||
pub struct FlowRef {
|
||||
vtable: *const u8,
|
||||
ptr: *const u8,
|
||||
object: raw::TraitObject,
|
||||
}
|
||||
|
||||
impl FlowRef {
|
||||
|
@ -25,7 +24,8 @@ impl FlowRef {
|
|||
unsafe {
|
||||
let result = {
|
||||
let flow_ref: &mut Flow = flow;
|
||||
mem::transmute(flow_ref)
|
||||
let object = mem::transmute::<&mut Flow, raw::TraitObject>(flow_ref);
|
||||
FlowRef { object: object }
|
||||
};
|
||||
mem::forget(flow);
|
||||
result
|
||||
|
@ -34,13 +34,13 @@ impl FlowRef {
|
|||
|
||||
pub fn get<'a>(&'a self) -> &'a Flow {
|
||||
unsafe {
|
||||
mem::transmute_copy(self)
|
||||
mem::transmute_copy::<raw::TraitObject, &'a Flow>(&self.object)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_mut<'a>(&'a mut self) -> &'a mut Flow {
|
||||
unsafe {
|
||||
mem::transmute_copy(self)
|
||||
mem::transmute_copy::<raw::TraitObject, &'a mut Flow>(&self.object)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -48,19 +48,22 @@ impl FlowRef {
|
|||
impl Drop for FlowRef {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
if self.vtable == ptr::null() {
|
||||
if self.object.vtable.is_null() {
|
||||
return
|
||||
}
|
||||
if flow::base(self.get()).ref_count().fetch_sub(1, SeqCst) > 1 {
|
||||
return
|
||||
}
|
||||
let flow_ref: FlowRef = mem::replace(self, FlowRef {
|
||||
vtable: ptr::null(),
|
||||
ptr: ptr::null(),
|
||||
object: raw::TraitObject {
|
||||
vtable: ptr::mut_null(),
|
||||
data: ptr::mut_null(),
|
||||
}
|
||||
});
|
||||
drop(mem::transmute::<FlowRef,Box<Flow>>(flow_ref));
|
||||
self.vtable = ptr::null();
|
||||
self.ptr = ptr::null();
|
||||
drop(mem::transmute::<raw::TraitObject, Box<Flow>>(flow_ref.object));
|
||||
mem::forget(flow_ref);
|
||||
self.object.vtable = ptr::mut_null();
|
||||
self.object.data = ptr::mut_null();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -70,8 +73,10 @@ impl Clone for FlowRef {
|
|||
unsafe {
|
||||
drop(flow::base(self.get()).ref_count().fetch_add(1, SeqCst));
|
||||
FlowRef {
|
||||
vtable: self.vtable,
|
||||
ptr: self.ptr,
|
||||
object: raw::TraitObject {
|
||||
vtable: self.object.vtable,
|
||||
data: self.object.data,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue