From 88059acd7efb4dceda48ec305528a247fd520c4f Mon Sep 17 00:00:00 2001 From: Josh Matthews Date: Wed, 23 Mar 2016 19:00:32 -0400 Subject: [PATCH] Start generating arrays of specs for easier implementation of preference checks. --- .../dom/bindings/codegen/CodegenRust.py | 20 +++++++--- components/script/dom/bindings/interface.rs | 38 +++++++++++-------- components/script/dom/bindings/utils.rs | 6 +++ 3 files changed, 43 insertions(+), 21 deletions(-) diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py index 939fc05d581..ce524583930 100644 --- a/components/script/dom/bindings/codegen/CodegenRust.py +++ b/components/script/dom/bindings/codegen/CodegenRust.py @@ -1368,9 +1368,17 @@ class PropertyDefiner: if specTerminator: specs.append(specTerminator) - return (("const %s: &'static [%s] = &[\n" + - ",\n".join(specs) + "\n" + - "];\n") % (name, specType)) + specsArray = ("const %s_specs: &'static [%s] = &[\n" + + ",\n".join(specs) + "\n" + + "];\n") % (name, specType) + + prefArray = ("const %s: &'static [Prefable<%s>] = &[\n" + + " Prefable {\n" + + " pref: None,\n" + + " specs: &%s_specs,\n" + + " },\n" + + "];\n") % (name, specType, name) + return specsArray + prefArray # The length of a method is the minimum of the lengths of the @@ -2240,8 +2248,8 @@ def InitUnforgeablePropertiesOnHolder(descriptor, properties): """ unforgeables = [] - defineUnforgeableAttrs = "define_properties(cx, unforgeable_holder.handle(), %s).unwrap();" - defineUnforgeableMethods = "define_methods(cx, unforgeable_holder.handle(), %s).unwrap();" + defineUnforgeableAttrs = "define_properties(cx, unforgeable_holder.handle(), %s_specs).unwrap();" + defineUnforgeableMethods = "define_methods(cx, unforgeable_holder.handle(), %s_specs).unwrap();" unforgeableMembers = [ (defineUnforgeableAttrs, properties.unforgeable_attrs), @@ -5467,7 +5475,7 @@ class CGBindingRoot(CGThing): 'dom::bindings::js::{JS, Root, RootedReference}', 'dom::bindings::js::{OptionalRootedReference}', 'dom::bindings::reflector::{Reflectable}', - 'dom::bindings::utils::{DOMClass, DOMJSClass}', + 'dom::bindings::utils::{DOMClass, DOMJSClass, Prefable}', '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}', diff --git a/components/script/dom/bindings/interface.rs b/components/script/dom/bindings/interface.rs index f41941f08b0..eef2913dabd 100644 --- a/components/script/dom/bindings/interface.rs +++ b/components/script/dom/bindings/interface.rs @@ -6,7 +6,7 @@ use dom::bindings::codegen::PrototypeList; use dom::bindings::conversions::get_dom_class; -use dom::bindings::utils::get_proto_or_iface_array; +use dom::bindings::utils::{get_proto_or_iface_array, Prefable}; use js::error::throw_type_error; use js::glue::UncheckedUnwrapObject; use js::jsapi::{Class, ClassExtension, ClassSpec, GetGlobalForObjectCrossCompartment}; @@ -212,13 +212,15 @@ impl InterfaceConstructorBehavior { pub unsafe fn create_callback_interface_object( cx: *mut JSContext, receiver: HandleObject, - constants: &'static [ConstantSpec], + constants: &'static [Prefable], name: &'static [u8], rval: MutableHandleObject) { assert!(!constants.is_empty()); rval.set(JS_NewObject(cx, ptr::null())); assert!(!rval.ptr.is_null()); - define_constants(cx, rval.handle(), constants); + for prefable in constants { + define_constants(cx, rval.handle(), prefable.specs); + } define_name(cx, rval.handle(), name); define_on_global_object(cx, receiver, name, rval.handle()); } @@ -228,9 +230,9 @@ pub unsafe fn create_interface_prototype_object( cx: *mut JSContext, proto: HandleObject, class: &'static JSClass, - regular_methods: Option<&'static [JSFunctionSpec]>, - regular_properties: Option<&'static [JSPropertySpec]>, - constants: &'static [ConstantSpec], + regular_methods: Option<&'static [Prefable]>, + regular_properties: Option<&'static [Prefable]>, + constants: &'static [Prefable], rval: MutableHandleObject) { create_object(cx, proto, class, regular_methods, regular_properties, constants, rval); } @@ -241,9 +243,9 @@ pub unsafe fn create_noncallback_interface_object( receiver: HandleObject, proto: HandleObject, class: &'static NonCallbackInterfaceObjectClass, - static_methods: Option<&'static [JSFunctionSpec]>, - static_properties: Option<&'static [JSPropertySpec]>, - constants: &'static [ConstantSpec], + static_methods: Option<&'static [Prefable]>, + static_properties: Option<&'static [Prefable]>, + constants: &'static [Prefable], interface_prototype_object: HandleObject, name: &'static [u8], length: u32, @@ -355,19 +357,25 @@ unsafe fn create_object( cx: *mut JSContext, proto: HandleObject, class: &'static JSClass, - methods: Option<&'static [JSFunctionSpec]>, - properties: Option<&'static [JSPropertySpec]>, - constants: &'static [ConstantSpec], + methods: Option<&'static [Prefable]>, + properties: Option<&'static [Prefable]>, + constants: &'static [Prefable], rval: MutableHandleObject) { rval.set(JS_NewObjectWithUniqueType(cx, class, proto)); assert!(!rval.ptr.is_null()); if let Some(methods) = methods { - define_methods(cx, rval.handle(), methods).unwrap(); + for prefable in methods { + define_methods(cx, rval.handle(), prefable.specs).unwrap(); + } } if let Some(properties) = properties { - define_properties(cx, rval.handle(), properties).unwrap(); + for prefable in properties { + define_properties(cx, rval.handle(), prefable.specs).unwrap(); + } + } + for prefable in constants { + define_constants(cx, rval.handle(), prefable.specs); } - define_constants(cx, rval.handle(), constants); } unsafe fn define_name(cx: *mut JSContext, obj: HandleObject, name: &'static [u8]) { diff --git a/components/script/dom/bindings/utils.rs b/components/script/dom/bindings/utils.rs index 9302bb40a09..1e2cf5c40f6 100644 --- a/components/script/dom/bindings/utils.rs +++ b/components/script/dom/bindings/utils.rs @@ -557,3 +557,9 @@ 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), }; + +#[allow(missing_docs)] +pub struct Prefable { + pub pref: Option<&'static str>, + pub specs: &'static [T] +}