aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/dom/bindings/codegen
diff options
context:
space:
mode:
authoryvt <i@yvt.jp>2021-07-17 13:31:39 +0900
committeryvt <i@yvt.jp>2021-07-17 15:26:15 +0900
commit4bc345317439f8eabd4f1e4817407d2f62cebf6c (patch)
tree69fa8a260f5c3557c49259db6ffe5ac4549dbd1b /components/script/dom/bindings/codegen
parent80cda12a87aecdcdfd7e1fca3e7f172933e710e9 (diff)
downloadservo-4bc345317439f8eabd4f1e4817407d2f62cebf6c.tar.gz
servo-4bc345317439f8eabd4f1e4817407d2f62cebf6c.zip
feat(script): Implement `[[Set]]` for `Location`
Diffstat (limited to 'components/script/dom/bindings/codegen')
-rw-r--r--components/script/dom/bindings/codegen/CodegenRust.py60
1 files changed, 57 insertions, 3 deletions
diff --git a/components/script/dom/bindings/codegen/CodegenRust.py b/components/script/dom/bindings/codegen/CodegenRust.py
index eb94029ccdd..f76be4619f0 100644
--- a/components/script/dom/bindings/codegen/CodegenRust.py
+++ b/components/script/dom/bindings/codegen/CodegenRust.py
@@ -3554,6 +3554,10 @@ class CGDefineProxyHandler(CGAbstractMethod):
# confused with ECMAScript's `[[SetImmutablePrototype]]`) always fails.
# This is the desired behavior, so we don't override it.
+ customSet = 'None'
+ if self.descriptor.isMaybeCrossOriginObject():
+ customSet = 'Some(set)'
+
getOwnEnumerablePropertyKeys = "own_property_keys"
if self.descriptor.interface.getExtendedAttribute("LegacyUnenumerableNamedProperties"):
getOwnEnumerablePropertyKeys = "getOwnEnumerablePropertyKeys"
@@ -3564,6 +3568,7 @@ class CGDefineProxyHandler(CGAbstractMethod):
"getPrototypeIfOrdinary": customGetPrototypeIfOrdinary,
"getPrototype": customGetPrototype,
"setPrototype": customSetPrototype,
+ "set": customSet,
"getOwnEnumerablePropertyKeys": getOwnEnumerablePropertyKeys,
"trace": TRACE_HOOK_NAME,
"finalize": FINALIZE_HOOK_NAME,
@@ -3585,7 +3590,7 @@ let traps = ProxyTraps {
isExtensible: Some(proxyhandler::is_extensible),
has: None,
get: Some(get),
- set: None,
+ set: %(set)s,
call: None,
construct: None,
hasOwn: Some(hasOwn),
@@ -5951,12 +5956,61 @@ return true;""" % (maybeCrossOriginGet, getIndexedOrExpando, getNamed)
return CGGeneric(self.getBody())
+class CGDOMJSProxyHandler_set(CGAbstractExternMethod):
+ def __init__(self, descriptor):
+ args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'),
+ Argument('RawHandleId', 'id'), Argument('RawHandleValue', 'v'),
+ Argument('RawHandleValue', 'receiver'),
+ Argument('*mut ObjectOpResult', 'opresult')]
+ CGAbstractExternMethod.__init__(self, descriptor, "set", "bool", args)
+ self.descriptor = descriptor
+
+ def getBody(self):
+ descriptor = self.descriptor
+
+ # `CGDOMJSProxyHandler_set` doesn't support legacy platform objects'
+ # `[[Set]]` (https://heycam.github.io/webidl/#legacy-platform-object-set) yet.
+ #
+ assert descriptor.isMaybeCrossOriginObject()
+ assert not descriptor.operations['IndexedGetter']
+ assert not descriptor.operations['NamedGetter']
+
+ maybeCrossOriginSet = dedent(
+ """
+ if !proxyhandler::is_platform_object_same_origin(cx, proxy) {
+ return proxyhandler::cross_origin_set(cx, proxy, id, v, receiver, opresult);
+ }
+
+ // Safe to enter the Realm of proxy now.
+ let _ac = JSAutoRealm::new(*cx, proxy.get());
+ """)
+
+ return dedent(
+ """
+ let cx = SafeJSContext::from_ptr(cx);
+ %(maybeCrossOriginSet)s
+
+ // OrdinarySet
+ // <https://tc39.es/ecma262/#sec-ordinaryset>
+ rooted!(in(*cx) let mut own_desc = PropertyDescriptor::default());
+ if !getOwnPropertyDescriptor(*cx, proxy, id, own_desc.handle_mut().into()) {
+ return false;
+ }
+
+ js::jsapi::SetPropertyIgnoringNamedGetter(
+ *cx, proxy, id, v, receiver, own_desc.handle().into(), opresult)
+ """) % { "maybeCrossOriginSet": maybeCrossOriginSet }
+
+ def definition_body(self):
+ return CGGeneric(self.getBody())
+
+
class CGDOMJSProxyHandler_getPrototype(CGAbstractExternMethod):
def __init__(self, descriptor):
args = [Argument('*mut JSContext', 'cx'), Argument('RawHandleObject', 'proxy'),
Argument('RawMutableHandleObject', 'proto')]
CGAbstractExternMethod.__init__(self, descriptor, "getPrototype", "bool", args)
- assert self.descriptor.isMaybeCrossOriginObject()
+ assert descriptor.isMaybeCrossOriginObject()
self.descriptor = descriptor
def getBody(self):
@@ -6636,7 +6690,7 @@ class CGDescriptor(CGThing):
if descriptor.isMaybeCrossOriginObject():
cgThings.append(CGDOMJSProxyHandler_getPrototype(descriptor))
- # TODO: CGDOMJSProxyHandler_set(descriptor),
+ cgThings.append(CGDOMJSProxyHandler_set(descriptor))
pass
# cgThings.append(CGDOMJSProxyHandler(descriptor))