diff --git a/src/components/main/servo.rs b/src/components/main/servo.rs index 2e65d299d2c..aa61286bd32 100644 --- a/src/components/main/servo.rs +++ b/src/components/main/servo.rs @@ -19,6 +19,7 @@ extern crate servo_net = "net"; extern crate servo_msg = "msg"; #[phase(plugin, link)] extern crate servo_util = "util"; +extern crate script; extern crate green; extern crate gfx; extern crate libc; @@ -30,6 +31,8 @@ extern crate url; use compositing::{CompositorChan, CompositorTask, Constellation}; #[cfg(not(test))] use servo_msg::constellation_msg::{ConstellationChan, InitLoadUrlMsg}; +#[cfg(not(test))] +use script::dom::bindings::codegen::RegisterBindings; #[cfg(not(test))] use servo_net::image_cache_task::ImageCacheTask; @@ -94,6 +97,8 @@ pub extern "C" fn android_start(argc: int, argv: **u8) -> int { #[cfg(not(test))] pub fn run(opts: opts::Opts) { + RegisterBindings::RegisterProxyHandlers(); + let mut pool_config = green::PoolConfig::new(); pool_config.event_loop_factory = rustuv::event_loop; let mut pool = green::SchedPool::new(pool_config); diff --git a/src/components/script/dom/bindings/codegen/CodegenRust.py b/src/components/script/dom/bindings/codegen/CodegenRust.py index c399b80fb09..afa0bcaa9e8 100644 --- a/src/components/script/dom/bindings/codegen/CodegenRust.py +++ b/src/components/script/dom/bindings/codegen/CodegenRust.py @@ -1763,12 +1763,10 @@ def CreateBindingJSObject(descriptor, parent=None): if descriptor.proxy: assert not descriptor.createGlobal create += """ -let js_info = aScope.deref().page().js_info(); -let mut handlers = js_info.get_ref().dom_static.proxy_handlers.deref().borrow_mut(); -let handler = handlers.get(&(PrototypeList::id::%s as uint)); +let handler = RegisterBindings::proxy_handlers[PrototypeList::proxies::%s as uint]; let mut private = PrivateValue(squirrel_away_unique(aObject) as *libc::c_void); let obj = with_compartment(aCx, proto, || { - NewProxyObject(aCx, *handler, + NewProxyObject(aCx, handler, &private, proto, %s, ptr::mut_null(), ptr::mut_null()) @@ -2039,26 +2037,21 @@ class CGGetConstructorObjectMethod(CGGetPerInterfaceObject): CGGetPerInterfaceObject.definition_body(self), ]) -class CGDefineDOMInterfaceMethod(CGAbstractMethod): + +class CGDefineProxyHandler(CGAbstractMethod): """ - A method for resolve hooks to try to lazily define the interface object for - a given interface. + A method to create and cache the proxy trap for a given interface. """ def __init__(self, descriptor): - args = [ - Argument('&JSRef', 'window'), - Argument('&mut JSPageInfo', 'js_info'), - ] - CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'void', args, pub=True) + assert descriptor.proxy + CGAbstractMethod.__init__(self, descriptor, 'DefineProxyHandler', '*libc::c_void', [], pub=True) def define(self): return CGAbstractMethod.define(self) def definition_body(self): - body = CGList([]) - #XXXjdm This self.descriptor.concrete check shouldn't be necessary - if not self.descriptor.concrete or self.descriptor.proxy: - body.append(CGGeneric("""let traps = ProxyTraps { + body = """\ +let traps = ProxyTraps { getPropertyDescriptor: Some(getPropertyDescriptor), getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor), defineProperty: Some(defineProperty), @@ -2089,21 +2082,35 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod): getPrototypeOf: None, trace: Some(%s) }; -let mut handlers = js_info.dom_static.proxy_handlers.deref().borrow_mut(); -handlers.insert(PrototypeList::id::%s as uint, - CreateProxyHandler(&traps, &Class as *_ as *_)); +CreateProxyHandler(&traps, &Class as *_ as *_) """ % (FINALIZE_HOOK_NAME, - TRACE_HOOK_NAME, - self.descriptor.name))) + TRACE_HOOK_NAME) + return CGGeneric(body) - if self.descriptor.interface.hasInterfaceObject(): - body.append(CGGeneric("""let cx = (**js_info.js_context).ptr; + + +class CGDefineDOMInterfaceMethod(CGAbstractMethod): + """ + A method for resolve hooks to try to lazily define the interface object for + a given interface. + """ + def __init__(self, descriptor): + assert descriptor.interface.hasInterfaceObject() + args = [ + Argument('&JSRef', 'window'), + ] + CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'void', args, pub=True) + + def define(self): + return CGAbstractMethod.define(self) + + def definition_body(self): + return CGGeneric("""\ +let cx = window.get_cx(); let global = window.reflector().get_jsobject(); assert!(global.is_not_null()); -assert!(GetProtoObject(cx, global, global).is_not_null());""")) - - return body +assert!(GetProtoObject(cx, global, global).is_not_null());""") def needCx(returnType, arguments, extendedAttributes, considerTypes): return (considerTypes and @@ -4019,7 +4026,11 @@ class CGDescriptor(CGThing): CGConstant(m for m in descriptor.interface.members if m.isConst()), public=True)) - cgThings.append(CGDefineDOMInterfaceMethod(descriptor)) + if descriptor.interface.hasInterfaceObject(): + cgThings.append(CGDefineDOMInterfaceMethod(descriptor)) + + if descriptor.proxy: + cgThings.append(CGDefineProxyHandler(descriptor)) if descriptor.concrete: if descriptor.proxy: @@ -4257,7 +4268,6 @@ class CGRegisterProtos(CGAbstractMethod): def __init__(self, config): arguments = [ Argument('&JSRef', 'window'), - Argument('&mut JSPageInfo', 'js_info'), ] CGAbstractMethod.__init__(self, None, 'Register', 'void', arguments, unsafe=False, pub=True) @@ -4265,10 +4275,37 @@ class CGRegisterProtos(CGAbstractMethod): def definition_body(self): return CGList([ - CGGeneric("codegen::Bindings::%sBinding::DefineDOMInterface(window, js_info);" % desc.name) - for desc in self.config.getDescriptors(isCallback=False, register=True) + CGGeneric("codegen::Bindings::%sBinding::DefineDOMInterface(window);" % desc.name) + for desc in self.config.getDescriptors(hasInterfaceObject=True, register=True) ], "\n") + +class CGRegisterProxyHandlersMethod(CGAbstractMethod): + def __init__(self, descriptors): + CGAbstractMethod.__init__(self, None, 'RegisterProxyHandlers', 'void', [], + unsafe=True, pub=True) + self.descriptors = descriptors + + def definition_body(self): + return CGList([ + CGGeneric("proxy_handlers[proxies::%s as uint] = codegen::Bindings::%sBinding::DefineProxyHandler();" % (desc.name, desc.name)) + for desc in self.descriptors + ], "\n") + + +class CGRegisterProxyHandlers(CGThing): + def __init__(self, config): + descriptors = config.getDescriptors(proxy=True) + length = len(descriptors) + self.root = CGList([ + CGGeneric("pub static mut proxy_handlers: [*libc::c_void, ..%d] = [0 as *libc::c_void, ..%d];" % (length, length)), + CGRegisterProxyHandlersMethod(descriptors), + ], "\n") + + def define(self): + return self.root.define() + + class CGBindingRoot(CGThing): """ Root codegen class for binding generation. Instantiate the class, and call @@ -4393,6 +4430,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::conversions::{Default, Empty}', 'dom::bindings::codegen::*', 'dom::bindings::codegen::Bindings::*', + 'dom::bindings::codegen::RegisterBindings', 'dom::bindings::codegen::UnionTypes::*', 'dom::bindings::error::{FailureUnknown, Fallible, Error, ErrorResult}', 'dom::bindings::error::throw_dom_exception', @@ -5244,22 +5282,30 @@ class GlobalGenRoots(): def PrototypeList(config): # Prototype ID enum. protos = [d.name for d in config.getDescriptors(hasInterfacePrototypeObject=True)] + proxies = [d.name for d in config.getDescriptors(proxy=True)] return CGList([ CGGeneric(AUTOGENERATED_WARNING_COMMENT), CGGeneric("pub static MAX_PROTO_CHAIN_LENGTH: uint = %d;\n\n" % config.maxProtoChainLength), CGNamespacedEnum('id', 'ID', protos, [0], deriving="PartialEq"), + CGNamespacedEnum('proxies', 'Proxy', proxies, [0], deriving="PartialEq"), ]) @staticmethod def RegisterBindings(config): # TODO - Generate the methods we want - return CGImports(CGRegisterProtos(config), [], [ + code = CGList([ + CGRegisterProtos(config), + CGRegisterProxyHandlers(config), + ], "\n") + + return CGImports(code, [], [ 'dom::bindings::codegen', + 'dom::bindings::codegen::PrototypeList::proxies', 'dom::bindings::js::{JS, JSRef}', 'dom::window::Window', - 'page::JSPageInfo', + 'libc', ]) @staticmethod diff --git a/src/components/script/dom/bindings/utils.rs b/src/components/script/dom/bindings/utils.rs index 99398bfc2f8..0c3375111ef 100644 --- a/src/components/script/dom/bindings/utils.rs +++ b/src/components/script/dom/bindings/utils.rs @@ -11,10 +11,9 @@ use dom::browsercontext; use dom::window; use servo_util::str::DOMString; -use std::collections::hashmap::HashMap; use libc; use libc::c_uint; -use std::cell::{Cell, RefCell}; +use std::cell::Cell; use std::mem; use std::cmp::PartialEq; use std::ptr; @@ -52,13 +51,11 @@ use js; #[allow(raw_pointer_deriving)] #[deriving(Encodable)] pub struct GlobalStaticData { - pub proxy_handlers: Untraceable>>, pub windowproxy_handler: Untraceable<*libc::c_void>, } pub fn GlobalStaticData() -> GlobalStaticData { GlobalStaticData { - proxy_handlers: Untraceable::new(RefCell::new(HashMap::new())), windowproxy_handler: Untraceable::new(browsercontext::new_window_proxy_handler()), } } diff --git a/src/components/script/script_task.rs b/src/components/script/script_task.rs index c75e639be09..c584d5735f8 100644 --- a/src/components/script/script_task.rs +++ b/src/components/script/script_task.rs @@ -549,8 +549,7 @@ impl ScriptTask { window.deref().init_browser_context(&*document); with_compartment((**cx).ptr, window.reflector().get_jsobject(), || { - let mut js_info = page.mut_js_info(); - RegisterBindings::Register(&*window, js_info.get_mut_ref()); + RegisterBindings::Register(&*window); }); self.compositor.set_ready_state(Loading);