Introduce mutable/immutable variants of reflector() with named lifetimes, and kill unsafe casts.

This commit is contained in:
Bobby Holley 2013-10-10 11:49:17 +02:00
parent e6be738d97
commit c4bbc4cd37
24 changed files with 158 additions and 87 deletions

View file

@ -2464,7 +2464,7 @@ class CGAbstractMethod(CGThing):
def CreateBindingJSObject(descriptor, parent=None):
if descriptor.proxy:
handler = """ //let reflector = ptr::to_unsafe_ptr(aObject.reflector());
handler = """ //let reflector = aObject.mut_reflector();
let page = page_from_context(aCx);
let handler = (*page).js_info.get_ref().dom_static.proxy_handlers.get(&(PrototypeList::id::%s as uint));
@ -2520,7 +2520,7 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
return ptr::null();
}
let reflector = ptr::to_mut_unsafe_ptr(aObject.reflector());
let reflector = aObject.mut_reflector();
%s
//NS_ADDREF(aObject);
@ -2529,7 +2529,7 @@ class CGWrapWithCacheMethod(CGAbstractMethod):
return obj;""" % (CreateBindingJSObject(self.descriptor, "parent"))
else:
return """ let reflector = ptr::to_mut_unsafe_ptr(aObject.reflector());
return """ let reflector = aObject.mut_reflector();
%s
let proto = GetProtoObject(aCx, obj, obj);
JS_SetPrototype(aCx, obj, proto);

View file

@ -10,11 +10,13 @@ use dom::domparser::DOMParser;
use js::jsapi::{JSContext, JSObject, JSVal};
use js::glue::{RUST_OBJECT_TO_JSVAL};
use std::cast;
impl Reflectable for DOMParser {
fn reflector(&mut self) -> &mut Reflector {
unsafe { cast::transmute(&self.reflector_) }
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
&mut self.reflector_
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {

View file

@ -12,10 +12,14 @@ use js::jsapi::{JSContext, JSObject, JSTracer};
macro_rules! generate_cacheable_wrapper(
($name: path, $wrap: path) => (
impl Reflectable for $name {
fn reflector(&mut self) -> &mut Reflector {
fn reflector<'a>(&'a self) -> &'a Reflector {
self.element.reflector()
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
self.element.mut_reflector()
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
let mut unused = false;
$wrap(cx, scope, self, &mut unused)
@ -27,10 +31,14 @@ macro_rules! generate_cacheable_wrapper(
macro_rules! generate_cacheable_wrapper_htmlelement(
($name: path, $wrap: path) => (
impl Reflectable for $name {
fn reflector(&mut self) -> &mut Reflector {
fn reflector<'a>(&'a self) -> &'a Reflector {
self.htmlelement.reflector()
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
self.htmlelement.mut_reflector()
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
let mut unused = false;
$wrap(cx, scope, self, &mut unused)
@ -42,10 +50,14 @@ macro_rules! generate_cacheable_wrapper_htmlelement(
macro_rules! generate_cacheable_wrapper_node(
($name: path, $wrap: path) => (
impl Reflectable for $name {
fn reflector(&mut self) -> &mut Reflector {
fn reflector<'a>(&'a self) -> &'a Reflector {
self.node.reflector()
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
self.node.mut_reflector()
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
let mut unused = false;
$wrap(cx, scope, self, &mut unused)

View file

@ -96,11 +96,15 @@ pub fn create(cx: *JSContext, node: &mut AbstractNode<ScriptView>) -> *JSObject
}
impl Reflectable for AbstractNode<ScriptView> {
fn reflector(&mut self) -> &mut Reflector {
fn reflector<'a>(&'a self) -> &'a Reflector {
do self.with_base |base| {
unsafe { cast::transmute(base.reflector()) }
}
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
do self.with_mut_base |base| {
unsafe {
cast::transmute(&base.reflector_)
}
unsafe { cast::transmute(base.reflector()) }
}
}
@ -117,7 +121,7 @@ impl Traceable for Node<ScriptView> {
return;
}
debug!("tracing %s", name);
let mut node = node.unwrap();
let node = node.unwrap();
let obj = node.reflector().get_jsobject();
assert!(obj.is_not_null());
unsafe {

View file

@ -528,7 +528,8 @@ pub fn initialize_global(global: *JSObject) {
}
pub trait Reflectable {
fn reflector(&mut self) -> &mut Reflector;
fn reflector<'a>(&'a self) -> &'a Reflector;
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector;
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject;
}
@ -561,7 +562,7 @@ pub fn WrapNewBindingObject(cx: *JSContext, scope: *JSObject,
value: @mut Reflectable,
vp: *mut JSVal) -> JSBool {
unsafe {
let reflector = value.reflector();
let reflector = value.mut_reflector();
let obj = reflector.get_jsobject();
if obj.is_not_null() /*&& js::GetObjectCompartment(obj) == js::GetObjectCompartment(scope)*/ {
*vp = RUST_OBJECT_TO_JSVAL(obj);
@ -589,7 +590,7 @@ pub fn WrapNativeParent(cx: *JSContext, scope: *JSObject, mut p: Option<@mut Ref
return obj;
}
let obj = p.wrap_object_shared(cx, scope);
p.reflector().set_jsobject(obj);
p.mut_reflector().set_jsobject(obj);
obj
}
None => unsafe { JS_GetGlobalObject(cx) }
@ -733,10 +734,9 @@ pub trait DerivedWrapper {
impl DerivedWrapper for AbstractNode<ScriptView> {
#[fixed_stack_segment]
fn wrap(&mut self, cx: *JSContext, _scope: *JSObject, vp: *mut JSVal) -> i32 {
let cache = self.reflector();
let wrapper = cache.get_jsobject();
if wrapper.is_not_null() {
unsafe { *vp = RUST_OBJECT_TO_JSVAL(wrapper) };
let obj = self.reflector().get_jsobject();
if obj.is_not_null() {
unsafe { *vp = RUST_OBJECT_TO_JSVAL(obj) };
return 1;
}
unsafe { *vp = RUST_OBJECT_TO_JSVAL(node::create(cx, self)) };

View file

@ -8,8 +8,6 @@ use script_task::{page_from_context};
use js::jsapi::{JSContext, JSObject};
use std::cast;
pub struct Blob {
reflector_: Reflector
}
@ -23,8 +21,12 @@ impl Blob {
}
impl Reflectable for Blob {
fn reflector(&mut self) -> &mut Reflector {
unsafe { cast::transmute(&self.reflector_) }
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
&mut self.reflector_
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {

View file

@ -59,10 +59,14 @@ impl CharacterData {
}
impl Reflectable for CharacterData {
fn reflector(&mut self) -> &mut Reflector {
fn reflector<'a>(&'a self) -> &'a Reflector {
self.node.reflector()
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
self.node.mut_reflector()
}
fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!(~"need to implement wrapping");
}

View file

@ -9,8 +9,6 @@ use script_task::page_from_context;
use js::jsapi::{JSObject, JSContext, JSVal};
use js::glue::RUST_OBJECT_TO_JSVAL;
use std::cast;
pub struct ClientRect {
reflector_: Reflector,
top: f32,
@ -62,10 +60,12 @@ impl ClientRect {
}
impl Reflectable for ClientRect {
fn reflector(&mut self) -> &mut Reflector {
unsafe {
cast::transmute(&self.reflector_)
}
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
&mut self.reflector_
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {

View file

@ -9,8 +9,6 @@ use script_task::page_from_context;
use js::jsapi::{JSObject, JSContext};
use std::cast;
pub struct ClientRectList {
reflector_: Reflector,
rects: ~[@mut ClientRect]
@ -49,10 +47,12 @@ impl ClientRectList {
}
impl Reflectable for ClientRectList {
fn reflector(&mut self) -> &mut Reflector {
unsafe {
cast::transmute(&self.reflector_)
}
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
&mut self.reflector_
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {

View file

@ -144,9 +144,15 @@ impl ReflectableDocument for Document {
}
impl Reflectable for AbstractDocument {
fn reflector(&mut self) -> &mut Reflector {
fn reflector<'a>(&'a self) -> &'a Reflector {
do self.with_mut_base |doc| {
doc.reflector()
unsafe { cast::transmute(doc.reflector()) }
}
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
do self.with_mut_base |doc| {
unsafe { cast::transmute(doc.mut_reflector()) }
}
}
@ -185,10 +191,12 @@ impl DerivedWrapper for AbstractDocument {
impl Reflectable for Document {
fn reflector(&mut self) -> &mut Reflector {
unsafe {
cast::transmute(&self.reflector_)
}
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
&mut self.reflector_
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {

View file

@ -30,10 +30,14 @@ pub struct Element {
}
impl Reflectable for Element {
fn reflector(&mut self) -> &mut Reflector {
fn reflector<'a>(&'a self) -> &'a Reflector {
self.node.reflector()
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
self.node.mut_reflector()
}
fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {
fail!("no wrapping")
}

View file

@ -14,9 +14,6 @@ use js::jsapi::{JSObject, JSContext, JSVal};
use script_task::page_from_context;
use std::cast;
pub enum Event_ {
ResizeEvent(uint, uint),
ReflowEvent,
@ -114,8 +111,12 @@ impl Event {
}
impl Reflectable for Event {
fn reflector(&mut self) -> &mut Reflector {
unsafe { cast::transmute(&self.reflector_) }
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
&mut self.reflector_
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {

View file

@ -9,8 +9,6 @@ use script_task::page_from_context;
use js::glue::RUST_OBJECT_TO_JSVAL;
use js::jsapi::{JSObject, JSContext, JSVal};
use std::cast;
pub struct EventTarget {
reflector_: Reflector
}
@ -28,8 +26,12 @@ impl EventTarget {
}
impl Reflectable for EventTarget {
fn reflector(&mut self) -> &mut Reflector {
unsafe { cast::transmute(&self.reflector_) }
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
&mut self.reflector_
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {

View file

@ -11,7 +11,6 @@ use script_task::{page_from_context};
use js::jsapi::{JSObject, JSContext, JSVal};
use js::glue::RUST_OBJECT_TO_JSVAL;
use std::cast;
use std::hashmap::HashMap;
enum FormDatum {
@ -50,10 +49,12 @@ impl FormData {
}
impl Reflectable for FormData {
fn reflector(&mut self) -> &mut Reflector {
unsafe {
cast::transmute(&self.reflector_)
}
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
&mut self.reflector_
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {

View file

@ -10,7 +10,6 @@ use script_task::page_from_context;
use js::jsapi::{JSObject, JSContext};
use std::cast;
use std::ptr;
pub struct HTMLCollection {
@ -69,10 +68,12 @@ impl BindingObject for HTMLCollection {
}
impl Reflectable for HTMLCollection {
fn reflector(&mut self) -> &mut Reflector {
unsafe {
cast::transmute(&self.reflector_)
}
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
&mut self.reflector_
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {

View file

@ -200,10 +200,14 @@ impl HTMLDocument {
}
impl Reflectable for HTMLDocument {
fn reflector(&mut self) -> &mut Reflector {
fn reflector<'a>(&'a self) -> &'a Reflector {
self.parent.reflector()
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
self.parent.mut_reflector()
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
let mut unused = false;
HTMLDocumentBinding::Wrap(cx, scope, self, &mut unused)

View file

@ -150,10 +150,14 @@ impl HTMLElement {
}
impl Reflectable for HTMLElement {
fn reflector(&mut self) -> &mut Reflector {
fn reflector<'a>(&'a self) -> &'a Reflector {
self.element.reflector()
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
self.element.mut_reflector()
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {
let mut unused = false;
HTMLElementBinding::Wrap(cx, scope, self, &mut unused)

View file

@ -143,8 +143,12 @@ impl MouseEvent {
}
impl Reflectable for MouseEvent {
fn reflector(&mut self) -> &mut Reflector {
return self.parent.reflector()
fn reflector<'a>(&'a self) -> &'a Reflector {
self.parent.reflector()
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
self.parent.mut_reflector()
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {

View file

@ -9,8 +9,6 @@ use script_task::{page_from_context};
use js::jsapi::{JSContext, JSObject};
use std::cast;
pub struct Navigator {
reflector_: Reflector
}
@ -88,8 +86,12 @@ impl Navigator {
}
impl Reflectable for Navigator {
fn reflector(&mut self) -> &mut Reflector {
unsafe { cast::transmute(&self.reflector_) }
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
&mut self.reflector_
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {

View file

@ -790,8 +790,12 @@ impl VoidPtrLike for AbstractNode<LayoutView> {
}
impl Reflectable for Node<ScriptView> {
fn reflector(&mut self) -> &mut Reflector {
unsafe { cast::transmute(&mut self.reflector_) }
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
&mut self.reflector_
}
fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {

View file

@ -116,8 +116,12 @@ impl UIEvent {
}
impl Reflectable for UIEvent {
fn reflector(&mut self) -> &mut Reflector {
return self.parent.reflector()
fn reflector<'a>(&'a self) -> &'a Reflector {
self.parent.reflector()
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
self.parent.mut_reflector()
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {

View file

@ -5,7 +5,6 @@
use dom::bindings::utils::{Reflector, BindingObject, Reflectable};
use dom::bindings::codegen::ValidityStateBinding;
use js::jsapi::{JSContext, JSObject};
use std::cast;
pub struct ValidityState {
reflector_: Reflector,
@ -60,8 +59,12 @@ impl ValidityState {
}
impl Reflectable for ValidityState {
fn reflector(&mut self) -> &mut Reflector {
unsafe { cast::transmute(&self.reflector_) }
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
&mut self.reflector_
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {

View file

@ -19,7 +19,6 @@ use js::jsapi::{JSObject, JSContext, JS_DefineProperty, JS_CallTracer};
use js::jsapi::{JSPropertyOp, JSStrictPropertyOp, JSTracer, JSTRACE_OBJECT};
use js::{JSVAL_NULL, JSPROP_ENUMERATE};
use std::cast;
use std::cell::Cell;
use std::comm;
use std::comm::SharedChan;
@ -136,8 +135,12 @@ impl Window {
}
impl Reflectable for Window {
fn reflector(&mut self) -> &mut Reflector {
unsafe { cast::transmute(&self.reflector_) }
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
&mut self.reflector_
}
fn wrap_object_shared(@mut self, cx: *JSContext, scope: *JSObject) -> *JSObject {

View file

@ -7,8 +7,6 @@ use script_task::page_from_context;
use js::jsapi::{JSContext, JSObject};
use std::cast;
pub struct WindowProxy {
reflector_: Reflector
}
@ -35,8 +33,12 @@ impl BindingObject for WindowProxy {
}
impl Reflectable for WindowProxy {
fn reflector(&mut self) -> &mut Reflector {
unsafe { cast::transmute(self.reflector_) }
fn reflector<'a>(&'a self) -> &'a Reflector {
&self.reflector_
}
fn mut_reflector<'a>(&'a mut self) -> &'a mut Reflector {
&mut self.reflector_
}
fn wrap_object_shared(@mut self, _cx: *JSContext, _scope: *JSObject) -> *JSObject {