Skip to content

Commit

Permalink
Implement [Unforgeable]
Browse files Browse the repository at this point in the history
This is mostly stolen from Gecko. As there, we define the unforgeable members
on an object stored in the slots of the prototype object. They are then copied
onto instance objects when they are instantiated. It should be noted that
proxy objects see their unforgeable memebers defined on their expando object.

Unforgeable attributes aren't properly inherited in codegen (in a similar
fashion as getters and setters as filed in #5875) and require to be redefined
in derived interfaces. Fortunately, there are currently no such interfaces.

No unforgeable members can be included into the TestBinding interfaces for good
measure because they are not compatible with setters.
  • Loading branch information
nox committed Oct 13, 2015
1 parent ac1b595 commit ba41013
Show file tree
Hide file tree
Showing 9 changed files with 244 additions and 102 deletions.
294 changes: 218 additions & 76 deletions components/script/dom/bindings/codegen/CodegenRust.py

Large diffs are not rendered by default.

10 changes: 10 additions & 0 deletions components/script/dom/bindings/codegen/Configuration.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,13 @@ def getDescriptor(self, interfaceName):
return self.config.getDescriptor(interfaceName)


def MemberIsUnforgeable(member, descriptor):
return ((member.isAttr() or member.isMethod()) and
not member.isStatic() and
(member.isUnforgeable() or
bool(descriptor.interface.getExtendedAttribute("Unforgeable"))))


class Descriptor(DescriptorProvider):
"""
Represents a single descriptor for an interface. See Bindings.conf.
Expand Down Expand Up @@ -175,6 +182,9 @@ def __init__(self, config, interface, desc):
# them as having a concrete descendant.
self.concrete = (not self.interface.isCallback() and
desc.get('concrete', True))
self.hasUnforgeableMembers = (self.concrete and
any(MemberIsUnforgeable(m, self) for m in
self.interface.members))

self.operations = {
'IndexedGetter': None,
Expand Down
16 changes: 12 additions & 4 deletions components/script/dom/bindings/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ impl GlobalStaticData {
// changes.
const DOM_PROTO_INSTANCE_CLASS_SLOT: u32 = 0;

/// The index of the slot where the object holder of that interface's
/// unforgeable members are defined.
pub const DOM_PROTO_UNFORGEABLE_HOLDER_SLOT: u32 = 1;

/// The index of the slot that contains a reference to the ProtoOrIfaceArray.
// All DOM globals must have a slot at DOM_PROTOTYPE_SLOT.
pub const DOM_PROTOTYPE_SLOT: u32 = js::JSCLASS_GLOBAL_SLOT_COUNT;
Expand Down Expand Up @@ -191,8 +195,12 @@ pub fn get_proto_or_iface_array(global: *mut JSObject) -> *mut ProtoOrIfaceArray
pub struct NativeProperties {
/// Instance methods for the interface.
pub methods: Option<&'static [JSFunctionSpec]>,
/// Unforgeable instance methods for the interface.
pub unforgeable_methods: Option<&'static [JSFunctionSpec]>,
/// Instance attributes for the interface.
pub attrs: Option<&'static [JSPropertySpec]>,
/// Unforgeable instance attributes for the interface.
pub unforgeable_attrs: Option<&'static [JSPropertySpec]>,
/// Constants for the interface.
pub consts: Option<&'static [ConstantSpec]>,
/// Static methods for the interface.
Expand Down Expand Up @@ -342,8 +350,8 @@ fn define_constants(cx: *mut JSContext, obj: HandleObject,
/// Defines methods on `obj`. The last entry of `methods` must contain zeroed
/// memory.
/// Fails on JSAPI failure.
fn define_methods(cx: *mut JSContext, obj: HandleObject,
methods: &'static [JSFunctionSpec]) {
pub fn define_methods(cx: *mut JSContext, obj: HandleObject,
methods: &'static [JSFunctionSpec]) {
unsafe {
assert!(JS_DefineFunctions(cx, obj, methods.as_ptr(), PropertyDefinitionBehavior::DefineAllProperties) != 0);
}
Expand All @@ -352,8 +360,8 @@ fn define_methods(cx: *mut JSContext, obj: HandleObject,
/// Defines attributes on `obj`. The last entry of `properties` must contain
/// zeroed memory.
/// Fails on JSAPI failure.
fn define_properties(cx: *mut JSContext, obj: HandleObject,
properties: &'static [JSPropertySpec]) {
pub fn define_properties(cx: *mut JSContext, obj: HandleObject,
properties: &'static [JSPropertySpec]) {
unsafe {
assert!(JS_DefineProperties(cx, obj, properties.as_ptr()) != 0);
}
Expand Down
1 change: 0 additions & 1 deletion components/script/dom/testbindingproxy.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,4 @@ impl TestBindingProxyMethods for TestBindingProxy {
fn IndexedSetter(&self, _: u32, _: DOMString) -> () {}
fn NamedSetter(&self, _: DOMString, _: DOMString) -> () {}
fn NamedGetter(&self, _: DOMString, _: &mut bool) -> DOMString { "".to_owned() }

}
2 changes: 1 addition & 1 deletion components/script/dom/webidls/Document.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ enum DocumentReadyState { "loading", "interactive", "complete" };
// [OverrideBuiltins]
partial /*sealed*/ interface Document {
// resource metadata management
// [PutForwards=href, Unforgeable]
[/*PutForwards=href, */Unforgeable]
readonly attribute Location/*?*/ location;
// attribute DOMString domain;
// readonly attribute DOMString referrer;
Expand Down
2 changes: 1 addition & 1 deletion components/script/dom/webidls/Location.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */

// https://html.spec.whatwg.org/multipage/#location
/*[Unforgeable]*/ interface Location {
[Unforgeable] interface Location {
void assign(DOMString url);
//void replace(DOMString url);
void reload();
Expand Down
4 changes: 2 additions & 2 deletions components/script/dom/webidls/Window.webidl
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
//[Replaceable] readonly attribute WindowProxy self;
readonly attribute Window window;
[BinaryName="Self_"] readonly attribute Window self;
/*[Unforgeable]*/ readonly attribute Document document;
[Unforgeable] readonly attribute Document document;
// attribute DOMString name;
/*[PutForwards=href, Unforgeable]*/ readonly attribute Location location;
[/*PutForwards=href, */Unforgeable] readonly attribute Location location;
//readonly attribute History history;
//[Replaceable] readonly attribute BarProp locationbar;
//[Replaceable] readonly attribute BarProp menubar;
Expand Down
12 changes: 0 additions & 12 deletions tests/wpt/metadata/html/dom/interfaces.html.ini
Original file line number Diff line number Diff line change
Expand Up @@ -7029,9 +7029,6 @@
[Window interface: window must inherit property "self" with the proper type (1)]
expected: FAIL

[Window interface: window must have own property "document"]
expected: FAIL

[Window interface: window must inherit property "name" with the proper type (3)]
expected: FAIL

Expand Down Expand Up @@ -8667,18 +8664,9 @@
[Window interface: window must inherit property "localStorage" with the proper type (124)]
expected: FAIL
[Location interface: window.location must have own property "assign"]
expected: FAIL
[Location interface: calling assign(DOMString) on window.location with too few arguments must throw TypeError]
expected: FAIL
[Location interface: window.location must have own property "replace"]
expected: FAIL
[Location interface: window.location must have own property "reload"]
expected: FAIL
[HTMLOptionElement must be primary interface of new Option()]
expected: FAIL
Expand Down
5 changes: 0 additions & 5 deletions tests/wpt/mozilla/meta/mozilla/windowproxy.html.ini

This file was deleted.

0 comments on commit ba41013

Please sign in to comment.