mirror of
https://github.com/servo/servo.git
synced 2025-08-04 13:10:20 +01:00
Merge pull request #2810 from Ms2ger/proxy-handlers
Store proxy handlers in a static array rather than a hashtable per window.
This commit is contained in:
commit
cb10614355
4 changed files with 85 additions and 38 deletions
|
@ -19,6 +19,7 @@ extern crate servo_net = "net";
|
||||||
extern crate servo_msg = "msg";
|
extern crate servo_msg = "msg";
|
||||||
#[phase(plugin, link)]
|
#[phase(plugin, link)]
|
||||||
extern crate servo_util = "util";
|
extern crate servo_util = "util";
|
||||||
|
extern crate script;
|
||||||
extern crate green;
|
extern crate green;
|
||||||
extern crate gfx;
|
extern crate gfx;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
@ -30,6 +31,8 @@ extern crate url;
|
||||||
use compositing::{CompositorChan, CompositorTask, Constellation};
|
use compositing::{CompositorChan, CompositorTask, Constellation};
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use servo_msg::constellation_msg::{ConstellationChan, InitLoadUrlMsg};
|
use servo_msg::constellation_msg::{ConstellationChan, InitLoadUrlMsg};
|
||||||
|
#[cfg(not(test))]
|
||||||
|
use script::dom::bindings::codegen::RegisterBindings;
|
||||||
|
|
||||||
#[cfg(not(test))]
|
#[cfg(not(test))]
|
||||||
use servo_net::image_cache_task::ImageCacheTask;
|
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))]
|
#[cfg(not(test))]
|
||||||
pub fn run(opts: opts::Opts) {
|
pub fn run(opts: opts::Opts) {
|
||||||
|
RegisterBindings::RegisterProxyHandlers();
|
||||||
|
|
||||||
let mut pool_config = green::PoolConfig::new();
|
let mut pool_config = green::PoolConfig::new();
|
||||||
pool_config.event_loop_factory = rustuv::event_loop;
|
pool_config.event_loop_factory = rustuv::event_loop;
|
||||||
let mut pool = green::SchedPool::new(pool_config);
|
let mut pool = green::SchedPool::new(pool_config);
|
||||||
|
|
|
@ -1763,12 +1763,10 @@ def CreateBindingJSObject(descriptor, parent=None):
|
||||||
if descriptor.proxy:
|
if descriptor.proxy:
|
||||||
assert not descriptor.createGlobal
|
assert not descriptor.createGlobal
|
||||||
create += """
|
create += """
|
||||||
let js_info = aScope.deref().page().js_info();
|
let handler = RegisterBindings::proxy_handlers[PrototypeList::proxies::%s as uint];
|
||||||
let mut handlers = js_info.get_ref().dom_static.proxy_handlers.deref().borrow_mut();
|
|
||||||
let handler = handlers.get(&(PrototypeList::id::%s as uint));
|
|
||||||
let mut private = PrivateValue(squirrel_away_unique(aObject) as *libc::c_void);
|
let mut private = PrivateValue(squirrel_away_unique(aObject) as *libc::c_void);
|
||||||
let obj = with_compartment(aCx, proto, || {
|
let obj = with_compartment(aCx, proto, || {
|
||||||
NewProxyObject(aCx, *handler,
|
NewProxyObject(aCx, handler,
|
||||||
&private,
|
&private,
|
||||||
proto, %s,
|
proto, %s,
|
||||||
ptr::mut_null(), ptr::mut_null())
|
ptr::mut_null(), ptr::mut_null())
|
||||||
|
@ -2039,26 +2037,21 @@ class CGGetConstructorObjectMethod(CGGetPerInterfaceObject):
|
||||||
CGGetPerInterfaceObject.definition_body(self),
|
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 method to create and cache the proxy trap for a given interface.
|
||||||
a given interface.
|
|
||||||
"""
|
"""
|
||||||
def __init__(self, descriptor):
|
def __init__(self, descriptor):
|
||||||
args = [
|
assert descriptor.proxy
|
||||||
Argument('&JSRef<Window>', 'window'),
|
CGAbstractMethod.__init__(self, descriptor, 'DefineProxyHandler', '*libc::c_void', [], pub=True)
|
||||||
Argument('&mut JSPageInfo', 'js_info'),
|
|
||||||
]
|
|
||||||
CGAbstractMethod.__init__(self, descriptor, 'DefineDOMInterface', 'void', args, pub=True)
|
|
||||||
|
|
||||||
def define(self):
|
def define(self):
|
||||||
return CGAbstractMethod.define(self)
|
return CGAbstractMethod.define(self)
|
||||||
|
|
||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
body = CGList([])
|
body = """\
|
||||||
#XXXjdm This self.descriptor.concrete check shouldn't be necessary
|
let traps = ProxyTraps {
|
||||||
if not self.descriptor.concrete or self.descriptor.proxy:
|
|
||||||
body.append(CGGeneric("""let traps = ProxyTraps {
|
|
||||||
getPropertyDescriptor: Some(getPropertyDescriptor),
|
getPropertyDescriptor: Some(getPropertyDescriptor),
|
||||||
getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor),
|
getOwnPropertyDescriptor: Some(getOwnPropertyDescriptor),
|
||||||
defineProperty: Some(defineProperty),
|
defineProperty: Some(defineProperty),
|
||||||
|
@ -2089,21 +2082,35 @@ class CGDefineDOMInterfaceMethod(CGAbstractMethod):
|
||||||
getPrototypeOf: None,
|
getPrototypeOf: None,
|
||||||
trace: Some(%s)
|
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,
|
""" % (FINALIZE_HOOK_NAME,
|
||||||
TRACE_HOOK_NAME,
|
TRACE_HOOK_NAME)
|
||||||
self.descriptor.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>', '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();
|
let global = window.reflector().get_jsobject();
|
||||||
assert!(global.is_not_null());
|
assert!(global.is_not_null());
|
||||||
assert!(GetProtoObject(cx, global, global).is_not_null());"""))
|
assert!(GetProtoObject(cx, global, global).is_not_null());""")
|
||||||
|
|
||||||
return body
|
|
||||||
|
|
||||||
def needCx(returnType, arguments, extendedAttributes, considerTypes):
|
def needCx(returnType, arguments, extendedAttributes, considerTypes):
|
||||||
return (considerTypes and
|
return (considerTypes and
|
||||||
|
@ -4019,7 +4026,11 @@ class CGDescriptor(CGThing):
|
||||||
CGConstant(m for m in descriptor.interface.members if m.isConst()),
|
CGConstant(m for m in descriptor.interface.members if m.isConst()),
|
||||||
public=True))
|
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.concrete:
|
||||||
if descriptor.proxy:
|
if descriptor.proxy:
|
||||||
|
@ -4257,7 +4268,6 @@ class CGRegisterProtos(CGAbstractMethod):
|
||||||
def __init__(self, config):
|
def __init__(self, config):
|
||||||
arguments = [
|
arguments = [
|
||||||
Argument('&JSRef<Window>', 'window'),
|
Argument('&JSRef<Window>', 'window'),
|
||||||
Argument('&mut JSPageInfo', 'js_info'),
|
|
||||||
]
|
]
|
||||||
CGAbstractMethod.__init__(self, None, 'Register', 'void', arguments,
|
CGAbstractMethod.__init__(self, None, 'Register', 'void', arguments,
|
||||||
unsafe=False, pub=True)
|
unsafe=False, pub=True)
|
||||||
|
@ -4265,10 +4275,37 @@ class CGRegisterProtos(CGAbstractMethod):
|
||||||
|
|
||||||
def definition_body(self):
|
def definition_body(self):
|
||||||
return CGList([
|
return CGList([
|
||||||
CGGeneric("codegen::Bindings::%sBinding::DefineDOMInterface(window, js_info);" % desc.name)
|
CGGeneric("codegen::Bindings::%sBinding::DefineDOMInterface(window);" % desc.name)
|
||||||
for desc in self.config.getDescriptors(isCallback=False, register=True)
|
for desc in self.config.getDescriptors(hasInterfaceObject=True, register=True)
|
||||||
], "\n")
|
], "\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):
|
class CGBindingRoot(CGThing):
|
||||||
"""
|
"""
|
||||||
Root codegen class for binding generation. Instantiate the class, and call
|
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::conversions::{Default, Empty}',
|
||||||
'dom::bindings::codegen::*',
|
'dom::bindings::codegen::*',
|
||||||
'dom::bindings::codegen::Bindings::*',
|
'dom::bindings::codegen::Bindings::*',
|
||||||
|
'dom::bindings::codegen::RegisterBindings',
|
||||||
'dom::bindings::codegen::UnionTypes::*',
|
'dom::bindings::codegen::UnionTypes::*',
|
||||||
'dom::bindings::error::{FailureUnknown, Fallible, Error, ErrorResult}',
|
'dom::bindings::error::{FailureUnknown, Fallible, Error, ErrorResult}',
|
||||||
'dom::bindings::error::throw_dom_exception',
|
'dom::bindings::error::throw_dom_exception',
|
||||||
|
@ -5244,22 +5282,30 @@ class GlobalGenRoots():
|
||||||
def PrototypeList(config):
|
def PrototypeList(config):
|
||||||
# Prototype ID enum.
|
# Prototype ID enum.
|
||||||
protos = [d.name for d in config.getDescriptors(hasInterfacePrototypeObject=True)]
|
protos = [d.name for d in config.getDescriptors(hasInterfacePrototypeObject=True)]
|
||||||
|
proxies = [d.name for d in config.getDescriptors(proxy=True)]
|
||||||
|
|
||||||
return CGList([
|
return CGList([
|
||||||
CGGeneric(AUTOGENERATED_WARNING_COMMENT),
|
CGGeneric(AUTOGENERATED_WARNING_COMMENT),
|
||||||
CGGeneric("pub static MAX_PROTO_CHAIN_LENGTH: uint = %d;\n\n" % config.maxProtoChainLength),
|
CGGeneric("pub static MAX_PROTO_CHAIN_LENGTH: uint = %d;\n\n" % config.maxProtoChainLength),
|
||||||
CGNamespacedEnum('id', 'ID', protos, [0], deriving="PartialEq"),
|
CGNamespacedEnum('id', 'ID', protos, [0], deriving="PartialEq"),
|
||||||
|
CGNamespacedEnum('proxies', 'Proxy', proxies, [0], deriving="PartialEq"),
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def RegisterBindings(config):
|
def RegisterBindings(config):
|
||||||
# TODO - Generate the methods we want
|
# 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',
|
||||||
|
'dom::bindings::codegen::PrototypeList::proxies',
|
||||||
'dom::bindings::js::{JS, JSRef}',
|
'dom::bindings::js::{JS, JSRef}',
|
||||||
'dom::window::Window',
|
'dom::window::Window',
|
||||||
'page::JSPageInfo',
|
'libc',
|
||||||
])
|
])
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
|
|
@ -11,10 +11,9 @@ use dom::browsercontext;
|
||||||
use dom::window;
|
use dom::window;
|
||||||
use servo_util::str::DOMString;
|
use servo_util::str::DOMString;
|
||||||
|
|
||||||
use std::collections::hashmap::HashMap;
|
|
||||||
use libc;
|
use libc;
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
use std::cell::{Cell, RefCell};
|
use std::cell::Cell;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::cmp::PartialEq;
|
use std::cmp::PartialEq;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
@ -52,13 +51,11 @@ use js;
|
||||||
#[allow(raw_pointer_deriving)]
|
#[allow(raw_pointer_deriving)]
|
||||||
#[deriving(Encodable)]
|
#[deriving(Encodable)]
|
||||||
pub struct GlobalStaticData {
|
pub struct GlobalStaticData {
|
||||||
pub proxy_handlers: Untraceable<RefCell<HashMap<uint, *libc::c_void>>>,
|
|
||||||
pub windowproxy_handler: Untraceable<*libc::c_void>,
|
pub windowproxy_handler: Untraceable<*libc::c_void>,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn GlobalStaticData() -> GlobalStaticData {
|
pub fn GlobalStaticData() -> GlobalStaticData {
|
||||||
GlobalStaticData {
|
GlobalStaticData {
|
||||||
proxy_handlers: Untraceable::new(RefCell::new(HashMap::new())),
|
|
||||||
windowproxy_handler: Untraceable::new(browsercontext::new_window_proxy_handler()),
|
windowproxy_handler: Untraceable::new(browsercontext::new_window_proxy_handler()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -549,8 +549,7 @@ impl ScriptTask {
|
||||||
window.deref().init_browser_context(&*document);
|
window.deref().init_browser_context(&*document);
|
||||||
|
|
||||||
with_compartment((**cx).ptr, window.reflector().get_jsobject(), || {
|
with_compartment((**cx).ptr, window.reflector().get_jsobject(), || {
|
||||||
let mut js_info = page.mut_js_info();
|
RegisterBindings::Register(&*window);
|
||||||
RegisterBindings::Register(&*window, js_info.get_mut_ref());
|
|
||||||
});
|
});
|
||||||
|
|
||||||
self.compositor.set_ready_state(Loading);
|
self.compositor.set_ready_state(Loading);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue