Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement [Func] #11308

Merged
merged 12 commits into from May 27, 2016
@@ -69,8 +69,9 @@ use style_traits::viewport::ViewportConstraints;
use timer_scheduler::TimerScheduler;
use url::Url;
use util::geometry::PagePx;
use util::opts;
use util::prefs::mozbrowser_enabled;
use util::thread::spawn_named;
use util::{opts, prefs};
use webrender_traits;

#[derive(Debug, PartialEq)]
@@ -1129,7 +1130,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
}

fn handle_alert(&mut self, pipeline_id: PipelineId, message: String, sender: IpcSender<bool>) {
let display_alert_dialog = if prefs::get_pref("dom.mozbrowser.enabled").as_boolean().unwrap_or(false) {
let display_alert_dialog = if mozbrowser_enabled() {
let parent_pipeline_info = self.pipelines.get(&pipeline_id).and_then(|source| source.parent_info);
if let Some(_) = parent_pipeline_info {
let root_pipeline_id = self.root_frame_id
@@ -1421,7 +1422,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
containing_pipeline_id: PipelineId,
subpage_id: SubpageId,
event: MozBrowserEvent) {
assert!(prefs::get_pref("dom.mozbrowser.enabled").as_boolean().unwrap_or(false));
assert!(mozbrowser_enabled());

// Find the script channel for the given parent pipeline,
// and pass the event to that script thread.
@@ -1993,9 +1994,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
if let Some(pipeline_id) = rng.choose(&*pipeline_ids) {
if let Some(pipeline) = self.pipelines.get(pipeline_id) {
// Don't kill the mozbrowser pipeline
if prefs::get_pref("dom.mozbrowser.enabled").as_boolean().unwrap_or(false) &&
pipeline.parent_info.is_none()
{
if mozbrowser_enabled() && pipeline.parent_info.is_none() {
info!("Not closing mozbrowser pipeline {}.", pipeline_id);
} else {
// Note that we deliberately do not do any of the tidying up
@@ -2088,7 +2087,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowserlocationchange
// Note that this is a no-op if the pipeline is not an immediate child iframe of the root
fn trigger_mozbrowserlocationchange(&self, pipeline_id: PipelineId) {
if !prefs::get_pref("dom.mozbrowser.enabled").as_boolean().unwrap_or(false) { return; }
if !mozbrowser_enabled() { return; }

let event_info = self.pipelines.get(&pipeline_id).and_then(|pipeline| {
pipeline.parent_info.map(|(containing_pipeline_id, subpage_id)| {
@@ -2114,7 +2113,7 @@ impl<Message, LTF, STF> Constellation<Message, LTF, STF>
// https://developer.mozilla.org/en-US/docs/Web/Events/mozbrowsererror
// Note that this does not require the pipeline to be an immediate child of the root
fn trigger_mozbrowsererror(&self, pipeline_id: PipelineId, reason: String, backtrace: String) {
if !prefs::get_pref("dom.mozbrowser.enabled").as_boolean().unwrap_or(false) { return; }
if !mozbrowser_enabled() { return; }

let ancestor_info = self.get_root_pipeline_and_containing_parent(&pipeline_id);

@@ -356,7 +356,7 @@ impl Pipeline {
pub fn trigger_mozbrowser_event(&self,
subpage_id: SubpageId,
event: MozBrowserEvent) {
assert!(prefs::get_pref("dom.mozbrowser.enabled").as_boolean().unwrap_or(false));
assert!(prefs::mozbrowser_enabled());

let event = ConstellationControlMsg::MozBrowserEvent(self.id,
subpage_id,
@@ -164,7 +164,7 @@ impl CallSetup {
/// Performs the setup needed to make a call.
#[allow(unrooted_must_root)]
pub fn new<T: CallbackContainer>(callback: &T, handling: ExceptionHandling) -> CallSetup {
let global = global_root_from_object(callback.callback());
let global = unsafe { global_root_from_object(callback.callback()) };
let cx = global.r().get_cx();

let exception_compartment = unsafe {
@@ -5,6 +5,7 @@
# Common codegen classes.

from collections import defaultdict
from itertools import groupby

import operator
import re
@@ -1322,31 +1323,23 @@ def getRetvalDeclarationForType(returnType, descriptorProvider):
returnType)


class MemberCondition:
def MemberCondition(pref, func):
"""
An object representing the condition for a member to actually be
exposed. Any of the arguments can be None. If not
None, they should have the following types:
A string representing the condition for a member to actually be exposed.
Any of the arguments can be None. If not None, they should have the
following types:
pref: The name of the preference.
func: The name of the function.
"""
def __init__(self, pref=None, func=None):
assert pref is None or isinstance(pref, str)
assert func is None or isinstance(func, str)
self.pref = pref

def toFuncPtr(val):
if val is None:
return "None"
return "Some(%s)" % val
self.func = toFuncPtr(func)

def __eq__(self, other):
return (self.pref == other.pref and self.func == other.func)

def __ne__(self, other):
return not self.__eq__(other)
assert pref is None or isinstance(pref, str)
assert func is None or isinstance(func, str)
assert func is None or pref is None
if pref:
return 'Condition::Pref("%s")' % pref
if func:
return 'Condition::Func(%s)' % func
return "Condition::Satisfied"


class PropertyDefiner:
@@ -1390,8 +1383,8 @@ def getControllingCondition(interfaceMember, descriptor):
PropertyDefiner.getStringAttr(interfaceMember,
"Func"))

def generatePrefableArray(self, array, name, specTemplate, specTerminator,
specType, getCondition, getDataTuple):
def generateGuardedArray(self, array, name, specTemplate, specTerminator,
specType, getCondition, getDataTuple):
"""
This method generates our various arrays.
@@ -1417,43 +1410,23 @@ def generatePrefableArray(self, array, name, specTemplate, specTerminator,
# members while still allowing us to define all the members in the smallest
# number of JSAPI calls.
assert len(array) != 0
# So we won't put a specTerminator at the very front of the list:
lastCondition = getCondition(array[0], self.descriptor)
specs = []
currentSpecs = []
prefableSpecs = []
prefableTemplate = ' Guard::new(%s, %s[%d])'

prefableTemplate = ' Prefable { pref: %s, specs: %s[%d], terminator: %s }'

def switchToCondition(props, condition):
prefableSpecs.append(prefableTemplate %
('Some("%s")' % condition.pref if condition.pref else 'None',
name + "_specs",
len(specs),
'true' if specTerminator else 'false'))
for cond, members in groupby(array, lambda m: getCondition(m, self.descriptor)):
currentSpecs = [specTemplate % getDataTuple(m) for m in members]
if specTerminator:
currentSpecs.append(specTerminator)
specs.append("&[\n" + ",\n".join(currentSpecs) + "]\n")
del currentSpecs[:]

for member in array:
curCondition = getCondition(member, self.descriptor)
if lastCondition != curCondition:
# Terminate previous list
if specTerminator:
currentSpecs.append(specTerminator)
# And switch to our new pref
switchToCondition(self, lastCondition)
lastCondition = curCondition
# And the actual spec
currentSpecs.append(specTemplate % getDataTuple(member))
if specTerminator:
currentSpecs.append(specTerminator)
switchToCondition(self, lastCondition)
prefableSpecs.append(
prefableTemplate % (cond, name + "_specs", len(specs) - 1))

specsArray = ("const %s_specs: &'static [&'static[%s]] = &[\n" +
",\n".join(specs) + "\n" +
"];\n") % (name, specType)

prefArray = ("const %s: &'static [Prefable<%s>] = &[\n" +
prefArray = ("const %s: &'static [Guard<&'static [%s]>] = &[\n" +
",\n".join(prefableSpecs) + "\n" +
"];\n") % (name, specType)
return specsArray + prefArray
@@ -1500,7 +1473,7 @@ def __init__(self, descriptor, name, static, unforgeable):
"methodInfo": False,
"selfHostedName": "ArrayValues",
"length": 0,
"condition": MemberCondition()})
"condition": "Condition::Satisfied"})

isUnforgeableInterface = bool(descriptor.interface.getExtendedAttribute("Unforgeable"))
if not static and unforgeable == isUnforgeableInterface:
@@ -1551,7 +1524,7 @@ def specData(m):
% m["name"][2:], accessor, jitinfo, m["length"], flags, selfHostedName)
return (str_to_const_array(m["name"]), accessor, jitinfo, m["length"], flags, selfHostedName)

return self.generatePrefableArray(
return self.generateGuardedArray(
array, name,
' JSFunctionSpec {\n'
' name: %s as *const u8 as *const libc::c_char,\n'
@@ -1631,7 +1604,7 @@ def specData(attr):
return (str_to_const_array(attr.identifier.name), flags, getter(attr),
setter(attr))

return self.generatePrefableArray(
return self.generateGuardedArray(
array, name,
' JSPropertySpec {\n'
' name: %s as *const u8 as *const libc::c_char,\n'
@@ -1666,7 +1639,7 @@ def specData(const):
return (str_to_const_array(const.identifier.name),
convertConstIDLValueToJSVal(const.value))

return self.generatePrefableArray(
return self.generateGuardedArray(
array, name,
' ConstantSpec { name: %s, value: %s }',
None,
@@ -2327,8 +2300,8 @@ def InitUnforgeablePropertiesOnHolder(descriptor, properties):
"""
unforgeables = []

defineUnforgeableAttrs = "define_prefable_properties(cx, unforgeable_holder.handle(), %s);"
defineUnforgeableMethods = "define_prefable_methods(cx, unforgeable_holder.handle(), %s);"
defineUnforgeableAttrs = "define_guarded_properties(cx, unforgeable_holder.handle(), %s);"
defineUnforgeableMethods = "define_guarded_methods(cx, unforgeable_holder.handle(), %s);"

unforgeableMembers = [
(defineUnforgeableAttrs, properties.unforgeable_attrs),
@@ -2560,15 +2533,10 @@ def definition_body(self):
properties = {"id": name}
for arrayName in self.properties.arrayNames():
array = getattr(self.properties, arrayName)
if arrayName == "consts":
if array.length():
properties[arrayName] = array.variableName()
else:
properties[arrayName] = "&[]"
elif array.length():
properties[arrayName] = "Some(%s)" % array.variableName()
if array.length():
properties[arrayName] = array.variableName()
else:
properties[arrayName] = "None"
properties[arrayName] = "&[]"

code.append(CGGeneric("""
let mut prototype = RootedObject::new(cx, ptr::null_mut());
@@ -5563,13 +5531,13 @@ def __init__(self, config, prefix, webIDLFile):
'dom::bindings::interface::{InterfaceConstructorBehavior, NonCallbackInterfaceObjectClass}',
'dom::bindings::interface::{create_callback_interface_object, create_interface_prototype_object}',
'dom::bindings::interface::{create_named_constructors, create_noncallback_interface_object}',
'dom::bindings::interface::{define_prefable_methods, define_prefable_properties}',
'dom::bindings::interface::{define_guarded_methods, define_guarded_properties}',
'dom::bindings::interface::{ConstantSpec, NonNullJSNative}',
'dom::bindings::interface::ConstantVal::{IntVal, UintVal}',
'dom::bindings::js::{JS, Root, RootedReference}',
'dom::bindings::js::{OptionalRootedReference}',
'dom::bindings::reflector::{Reflectable}',
'dom::bindings::utils::{DOMClass, DOMJSClass, Prefable}',
'dom::bindings::utils::{DOMClass, DOMJSClass}',
'dom::bindings::utils::{DOM_PROTO_UNFORGEABLE_HOLDER_SLOT, JSCLASS_DOM_GLOBAL}',
'dom::bindings::utils::{ProtoOrIfaceArray, create_dom_global}',
'dom::bindings::utils::{enumerate_global, finalize_global, find_enum_string_index}',
@@ -5593,6 +5561,7 @@ def __init__(self, config, prefix, webIDLFile):
'dom::bindings::error::{Fallible, Error, ErrorResult}',
'dom::bindings::error::Error::JSFailed',
'dom::bindings::error::throw_dom_exception',
'dom::bindings::guard::{Condition, Guard}',
'dom::bindings::proxyhandler',
'dom::bindings::proxyhandler::{ensure_expando_object, fill_property_descriptor}',
'dom::bindings::proxyhandler::{get_expando_object, get_property_descriptor}',
@@ -302,44 +302,39 @@ impl GlobalRoot {

/// Returns the global object of the realm that the given DOM object's reflector was created in.
pub fn global_root_from_reflector<T: Reflectable>(reflector: &T) -> GlobalRoot {
global_root_from_object(*reflector.reflector().get_jsobject())
unsafe { global_root_from_object(*reflector.reflector().get_jsobject()) }
}

/// Returns the Rust global object from a JS global object.
#[allow(unrooted_must_root)]
pub fn global_root_from_global(global: *mut JSObject) -> GlobalRoot {
unsafe {
let clasp = JS_GetClass(global);
assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0);
match root_from_object(global) {
Ok(window) => return GlobalRoot::Window(window),
Err(_) => (),
}

match root_from_object(global) {
Ok(worker) => return GlobalRoot::Worker(worker),
Err(_) => (),
}
unsafe fn global_root_from_global(global: *mut JSObject) -> GlobalRoot {
assert!(!global.is_null());
let clasp = JS_GetClass(global);
assert!(((*clasp).flags & (JSCLASS_IS_DOMJSCLASS | JSCLASS_IS_GLOBAL)) != 0);
match root_from_object(global) {
Ok(window) => return GlobalRoot::Window(window),
Err(_) => (),
}

panic!("found DOM global that doesn't unwrap to Window or WorkerGlobalScope")
match root_from_object(global) {
Ok(worker) => return GlobalRoot::Worker(worker),
Err(_) => (),
}

panic!("found DOM global that doesn't unwrap to Window or WorkerGlobalScope")
}

/// Returns the global object of the realm that the given JS object was created in.
#[allow(unrooted_must_root)]
pub fn global_root_from_object(obj: *mut JSObject) -> GlobalRoot {
unsafe {
let global = GetGlobalForObjectCrossCompartment(obj);
global_root_from_global(global)
}
pub unsafe fn global_root_from_object(obj: *mut JSObject) -> GlobalRoot {
assert!(!obj.is_null());
let global = GetGlobalForObjectCrossCompartment(obj);
global_root_from_global(global)
}

/// Returns the global object for the given JSContext
#[allow(unrooted_must_root)]
pub fn global_root_from_context(cx: *mut JSContext) -> GlobalRoot {
unsafe {
let global = CurrentGlobalOrNull(cx);
assert!(!global.is_null());
global_root_from_global(global)
}
pub unsafe fn global_root_from_context(cx: *mut JSContext) -> GlobalRoot {
let global = CurrentGlobalOrNull(cx);
global_root_from_global(global)
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.