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

Remove utils::Prefable in favour of guard::Guard

  • Loading branch information
nox committed May 26, 2016
commit fd7c4f814949c45518d69216aa384d4d82d60107
@@ -1335,8 +1335,8 @@ def MemberCondition(pref, func):
assert pref is None or isinstance(pref, str)
assert func is None or isinstance(func, str)
if pref:
return 'Some("%s")' % pref
return "None"
return 'Condition::Pref("%s")' % pref
return "Condition::Satisfied"


class PropertyDefiner:
@@ -1380,8 +1380,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.
@@ -1409,7 +1409,7 @@ def generatePrefableArray(self, array, name, specTemplate, specTerminator,
assert len(array) != 0
specs = []
prefableSpecs = []
prefableTemplate = ' Prefable { pref: %s, specs: %s[%d] }'
prefableTemplate = ' Guard::new(%s, %s[%d])'

for cond, members in groupby(array, lambda m: getCondition(m, self.descriptor)):
currentSpecs = [specTemplate % getDataTuple(m) for m in members]
@@ -1423,7 +1423,7 @@ def generatePrefableArray(self, array, name, specTemplate, specTerminator,
",\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
@@ -1470,7 +1470,7 @@ def __init__(self, descriptor, name, static, unforgeable):
"methodInfo": False,
"selfHostedName": "ArrayValues",
"length": 0,
"condition": "None"})
"condition": "Condition::Satisfied"})

isUnforgeableInterface = bool(descriptor.interface.getExtendedAttribute("Unforgeable"))
if not static and unforgeable == isUnforgeableInterface:
@@ -1521,7 +1521,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'
@@ -1601,7 +1601,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'
@@ -1636,7 +1636,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,
@@ -2297,8 +2297,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),
@@ -5528,13 +5528,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}',
@@ -5558,6 +5558,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}',
@@ -0,0 +1,49 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! Machinery to conditionally expose things.

use util::prefs::get_pref;

/// A container with a condition.
pub struct Guard<T: Clone + Copy> {
condition: Condition,
value: T,
}

impl<T: Clone + Copy> Guard<T> {
/// Construct a new guarded value.
pub const fn new(condition: Condition, value: T) -> Self {
Guard {
condition: condition,
value: value,
}
}

/// Expose the value if the condition is satisfied.
pub fn expose(&self) -> Option<T> {
if self.condition.is_satisfied() {
Some(self.value)
} else {
None
}
}
}

/// A condition to expose things.
pub enum Condition {
/// The condition is satisfied if the preference is set.
Pref(&'static str),
/// The condition is always satisfied.
Satisfied,
}

impl Condition {
fn is_satisfied(&self) -> bool {
match *self {
Condition::Pref(name) => get_pref(name).as_boolean().unwrap_or(false),
Condition::Satisfied => true,
}
}
}
@@ -6,7 +6,8 @@

use dom::bindings::codegen::PrototypeList;
use dom::bindings::conversions::get_dom_class;
use dom::bindings::utils::{get_proto_or_iface_array, Prefable};
use dom::bindings::guard::Guard;
use dom::bindings::utils::get_proto_or_iface_array;
use js::error::throw_type_error;
use js::glue::UncheckedUnwrapObject;
use js::jsapi::{Class, ClassExtension, ClassSpec, GetGlobalForObjectCrossCompartment};
@@ -209,14 +210,14 @@ impl InterfaceConstructorBehavior {
pub unsafe fn create_callback_interface_object(
cx: *mut JSContext,
receiver: HandleObject,
constants: &'static [Prefable<ConstantSpec>],
constants: &'static [Guard<&'static [ConstantSpec]>],
name: &'static [u8],
rval: MutableHandleObject) {
assert!(!constants.is_empty());
rval.set(JS_NewObject(cx, ptr::null()));
assert!(!rval.ptr.is_null());
for prefable in constants {
if let Some(specs) = prefable.specs() {
for guard in constants {
if let Some(specs) = guard.expose() {
define_constants(cx, rval.handle(), specs);
}
}
@@ -229,9 +230,9 @@ pub unsafe fn create_interface_prototype_object(
cx: *mut JSContext,
proto: HandleObject,
class: &'static JSClass,
regular_methods: &'static [Prefable<JSFunctionSpec>],
regular_properties: &'static [Prefable<JSPropertySpec>],
constants: &'static [Prefable<ConstantSpec>],
regular_methods: &'static [Guard<&'static [JSFunctionSpec]>],
regular_properties: &'static [Guard<&'static [JSPropertySpec]>],
constants: &'static [Guard<&'static [ConstantSpec]>],
rval: MutableHandleObject) {
create_object(cx, proto, class, regular_methods, regular_properties, constants, rval);
}
@@ -242,9 +243,9 @@ pub unsafe fn create_noncallback_interface_object(
receiver: HandleObject,
proto: HandleObject,
class: &'static NonCallbackInterfaceObjectClass,
static_methods: &'static [Prefable<JSFunctionSpec>],
static_properties: &'static [Prefable<JSPropertySpec>],
constants: &'static [Prefable<ConstantSpec>],
static_methods: &'static [Guard<&'static [JSFunctionSpec]>],
static_properties: &'static [Guard<&'static [JSPropertySpec]>],
constants: &'static [Guard<&'static [ConstantSpec]>],
interface_prototype_object: HandleObject,
name: &'static [u8],
length: u32,
@@ -356,40 +357,40 @@ unsafe fn create_object(
cx: *mut JSContext,
proto: HandleObject,
class: &'static JSClass,
methods: &'static [Prefable<JSFunctionSpec>],
properties: &'static [Prefable<JSPropertySpec>],
constants: &'static [Prefable<ConstantSpec>],
methods: &'static [Guard<&'static [JSFunctionSpec]>],
properties: &'static [Guard<&'static [JSPropertySpec]>],
constants: &'static [Guard<&'static [ConstantSpec]>],
rval: MutableHandleObject) {
rval.set(JS_NewObjectWithUniqueType(cx, class, proto));
assert!(!rval.ptr.is_null());
define_prefable_methods(cx, rval.handle(), methods);
define_prefable_properties(cx, rval.handle(), properties);
for prefable in constants {
if let Some(specs) = prefable.specs() {
define_guarded_methods(cx, rval.handle(), methods);
define_guarded_properties(cx, rval.handle(), properties);
for guard in constants {
if let Some(specs) = guard.expose() {
define_constants(cx, rval.handle(), specs);
}
}
}

/// Conditionally define methods on an object.
pub unsafe fn define_prefable_methods(
pub unsafe fn define_guarded_methods(
cx: *mut JSContext,
obj: HandleObject,
methods: &'static [Prefable<JSFunctionSpec>]) {
for prefable in methods {
if let Some(specs) = prefable.specs() {
methods: &'static [Guard<&'static [JSFunctionSpec]>]) {
for guard in methods {
if let Some(specs) = guard.expose() {
define_methods(cx, obj, specs).unwrap();
}
}
}

/// Conditionally define properties on an object.
pub unsafe fn define_prefable_properties(
pub unsafe fn define_guarded_properties(
cx: *mut JSContext,
obj: HandleObject,
properties: &'static [Prefable<JSPropertySpec>]) {
for prefable in properties {
if let Some(specs) = prefable.specs() {
properties: &'static [Guard<&'static [JSPropertySpec]>]) {
for guard in properties {
if let Some(specs) = guard.expose() {
define_properties(cx, obj, specs).unwrap();
}
}
@@ -133,6 +133,7 @@ pub mod cell;
pub mod conversions;
pub mod error;
pub mod global;
pub mod guard;
pub mod inheritance;
pub mod interface;
pub mod js;
@@ -39,7 +39,6 @@ use std::ffi::CString;
use std::os::raw::c_void;
use std::ptr;
use std::slice;
use util::prefs;

/// Proxy handler for a WindowProxy.
pub struct WindowProxyHandler(pub *const libc::c_void);
@@ -550,24 +549,3 @@ unsafe extern "C" fn instance_class_has_proto_at_depth(clasp: *const js::jsapi::
pub const DOM_CALLBACKS: DOMCallbacks = DOMCallbacks {
instanceClassMatchesProto: Some(instance_class_has_proto_at_depth),
};

/// A container around JS member specifications that are conditionally enabled.
pub struct Prefable<T: 'static> {
/// If present, the name of the preference used to conditionally enable these specs.
pub pref: Option<&'static str>,
/// The underlying slice of specifications.
pub specs: &'static [T],
}

impl<T> Prefable<T> {
/// Retrieve the slice represented by this container, unless the condition
/// guarding it is false.
pub fn specs(&self) -> Option<&'static [T]> {
if let Some(pref) = self.pref {
if !prefs::get_pref(pref).as_boolean().unwrap_or(false) {
return None;
}
}
Some(self.specs)
}
}
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.