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::num::Zero;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter::Zip;
|
use std::iter::Zip;
|
||||||
|
use std::raw;
|
||||||
use std::sync::atomics::{AtomicUint, Relaxed, SeqCst};
|
use std::sync::atomics::{AtomicUint, Relaxed, SeqCst};
|
||||||
use std::slice::MutItems;
|
use std::slice::MutItems;
|
||||||
use style::computed_values::{clear, position, text_align};
|
use style::computed_values::{clear, position, text_align};
|
||||||
|
@ -274,8 +275,8 @@ pub trait Flow: fmt::Show + ToString + Share {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn base<'a>(this: &'a Flow) -> &'a BaseFlow {
|
pub fn base<'a>(this: &'a Flow) -> &'a BaseFlow {
|
||||||
unsafe {
|
unsafe {
|
||||||
let (_, ptr): (uint, &BaseFlow) = mem::transmute(this);
|
let obj = mem::transmute::<&'a Flow, raw::TraitObject>(this);
|
||||||
ptr
|
mem::transmute::<*mut (), &'a BaseFlow>(obj.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,8 +288,8 @@ pub fn imm_child_iter<'a>(flow: &'a Flow) -> FlowListIterator<'a> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn mut_base<'a>(this: &'a mut Flow) -> &'a mut BaseFlow {
|
pub fn mut_base<'a>(this: &'a mut Flow) -> &'a mut BaseFlow {
|
||||||
unsafe {
|
unsafe {
|
||||||
let (_, ptr): (uint, &mut BaseFlow) = mem::transmute(this);
|
let obj = mem::transmute::<&'a mut Flow, raw::TraitObject>(this);
|
||||||
ptr
|
mem::transmute::<*mut (), &'a mut BaseFlow>(obj.data)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,16 +11,14 @@ use flow_ref::FlowRef;
|
||||||
use std::kinds::marker::ContravariantLifetime;
|
use std::kinds::marker::ContravariantLifetime;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
use std::raw;
|
||||||
|
|
||||||
pub type Link = Option<FlowRef>;
|
pub type Link = Option<FlowRef>;
|
||||||
|
|
||||||
|
|
||||||
// FIXME: use TraitObject instead of duplicating the type
|
|
||||||
#[allow(raw_pointer_deriving)]
|
#[allow(raw_pointer_deriving)]
|
||||||
#[deriving(Clone)]
|
|
||||||
pub struct Rawlink<'a> {
|
pub struct Rawlink<'a> {
|
||||||
vtable: *mut (),
|
object: raw::TraitObject,
|
||||||
obj: *mut (),
|
|
||||||
marker: ContravariantLifetime<'a>,
|
marker: ContravariantLifetime<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,23 +48,29 @@ impl<'a> Rawlink<'a> {
|
||||||
/// Like Option::None for Rawlink
|
/// Like Option::None for Rawlink
|
||||||
pub fn none() -> Rawlink<'static> {
|
pub fn none() -> Rawlink<'static> {
|
||||||
Rawlink {
|
Rawlink {
|
||||||
vtable: ptr::mut_null(),
|
object: raw::TraitObject {
|
||||||
obj: ptr::mut_null(),
|
vtable: ptr::mut_null(),
|
||||||
|
data: ptr::mut_null(),
|
||||||
|
},
|
||||||
marker: ContravariantLifetime,
|
marker: ContravariantLifetime,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Like Option::Some for Rawlink
|
/// Like Option::Some for Rawlink
|
||||||
pub fn some(n: &Flow) -> 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> {
|
pub unsafe fn resolve_mut(&self) -> Option<&'a mut Flow> {
|
||||||
if self.obj.is_null() {
|
if self.object.data.is_null() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let me: &mut Flow = mem::transmute_copy(self);
|
Some(mem::transmute_copy::<raw::TraitObject, &mut Flow>(&self.object))
|
||||||
Some(me)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,13 +11,12 @@ use flow;
|
||||||
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
use std::raw;
|
||||||
use std::sync::atomics::SeqCst;
|
use std::sync::atomics::SeqCst;
|
||||||
|
|
||||||
// FIXME: This should probably be a wrapper on TraitObject.
|
|
||||||
#[unsafe_no_drop_flag]
|
#[unsafe_no_drop_flag]
|
||||||
pub struct FlowRef {
|
pub struct FlowRef {
|
||||||
vtable: *const u8,
|
object: raw::TraitObject,
|
||||||
ptr: *const u8,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FlowRef {
|
impl FlowRef {
|
||||||
|
@ -25,7 +24,8 @@ impl FlowRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
let result = {
|
let result = {
|
||||||
let flow_ref: &mut Flow = flow;
|
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);
|
mem::forget(flow);
|
||||||
result
|
result
|
||||||
|
@ -34,13 +34,13 @@ impl FlowRef {
|
||||||
|
|
||||||
pub fn get<'a>(&'a self) -> &'a Flow {
|
pub fn get<'a>(&'a self) -> &'a Flow {
|
||||||
unsafe {
|
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 {
|
pub fn get_mut<'a>(&'a mut self) -> &'a mut Flow {
|
||||||
unsafe {
|
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 {
|
impl Drop for FlowRef {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
if self.vtable == ptr::null() {
|
if self.object.vtable.is_null() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if flow::base(self.get()).ref_count().fetch_sub(1, SeqCst) > 1 {
|
if flow::base(self.get()).ref_count().fetch_sub(1, SeqCst) > 1 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
let flow_ref: FlowRef = mem::replace(self, FlowRef {
|
let flow_ref: FlowRef = mem::replace(self, FlowRef {
|
||||||
vtable: ptr::null(),
|
object: raw::TraitObject {
|
||||||
ptr: ptr::null(),
|
vtable: ptr::mut_null(),
|
||||||
|
data: ptr::mut_null(),
|
||||||
|
}
|
||||||
});
|
});
|
||||||
drop(mem::transmute::<FlowRef,Box<Flow>>(flow_ref));
|
drop(mem::transmute::<raw::TraitObject, Box<Flow>>(flow_ref.object));
|
||||||
self.vtable = ptr::null();
|
mem::forget(flow_ref);
|
||||||
self.ptr = ptr::null();
|
self.object.vtable = ptr::mut_null();
|
||||||
|
self.object.data = ptr::mut_null();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -70,8 +73,10 @@ impl Clone for FlowRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
drop(flow::base(self.get()).ref_count().fetch_add(1, SeqCst));
|
drop(flow::base(self.get()).ref_count().fetch_add(1, SeqCst));
|
||||||
FlowRef {
|
FlowRef {
|
||||||
vtable: self.vtable,
|
object: raw::TraitObject {
|
||||||
ptr: self.ptr,
|
vtable: self.object.vtable,
|
||||||
|
data: self.object.data,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue