diff options
author | yvt <i@yvt.jp> | 2021-07-17 13:31:39 +0900 |
---|---|---|
committer | yvt <i@yvt.jp> | 2021-07-17 15:26:15 +0900 |
commit | 4bc345317439f8eabd4f1e4817407d2f62cebf6c (patch) | |
tree | 69fa8a260f5c3557c49259db6ffe5ac4549dbd1b /components/script/dom/bindings/codegen | |
parent | 80cda12a87aecdcdfd7e1fca3e7f172933e710e9 (diff) | |
download | servo-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.py | 60 |
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)) |