On Fri May 10 00:16:53 2024 +0000, Jacek Caban wrote:
Not sure if we have a test (or how to test it?)
I didn't talk about testing it, but your observations confirm my suspicious. Now imagine that we have `pobj` like that, with async properties not guarantying dispid stability, which initially has `async1` prop. Now consider this:
function f() {} f.prototype = pobj; var o = new f(); x = o.async1; // some other code; meantime async1 disappears, async2 appears and then a new async1 appears with a different dispid x = o.async1; // problem: now prototype ref points to wrong property and simple name dispid or name validation will not be enough
I expect the above to be a problem if you base prototypes on something like this MR, so I'm curious what you did about it. The test I asked was about something different, to show how `IDispatchEx should behave. That requires prototypes to test:
div = document.getElementById("divid"); Object.prototype.x = 1; // verify that div IDispatchEx can query x Element.prototype.y = 2; // verify that div IDispatchEx can query y detele Object.prototype.x; // ...
Do you have a test like that?
The other concerns, like forwarding calls to jscript, DISPIDs, and so
on, I don't see how they're relevant to this MR? I prefer doing it a bit at a time instead of all at once. The test above may be a bit of corner case, but more generally forwarding calls to jscript is by no means a corner case, it affects a pretty core part of the design and this MR is a part of its implementation. I'm not very interested in corner cases at this point, but I'm interested in making sure we don't end up with ad-hoc design mess (like the code in Proton).
I tried hard to reproduce what you meant but it doesn't seem to be possible? I mean, if o.async1 disappears, it doesn't mean the DISPID disappears. It just becomes PROP_DELETED on jscript or equivalent. Obviously it disappears from the jscript code's perspective, but not when querying the DISPID, the name is still "stored" in the object's props. Am I missing something?
I'm just using jscript's facility here. If you mean the "override" rather than the "fixup", then it's done on *existing props* so still have the same DISPID, although it's looked up via name on mshtml side but that's purely implementation detail, since mshtml doesn't know about jscript's DISPID (I guess it could be possible to obtain the name from DISPID via GetMemberName or the like but why complicate it when we can pass the name?).
In short: the prop "fixup" doesn't fixup the name, but rather the prop's value/contents (or deletes the prop). But deleted props don't delete the name—and DISPIDs are associated with the name, not the contents of the prop.
So: ```jscript x = o.async1 // ... x = o.async1 ``` First one let's say creates the async1 prop. Then it gets deleted on the file. jscript doesn't know this of course. Next time we obtain it, it's actually deleted, so it returns "undefined". But note that this is done in the getter, which already has the DISPID—the same DISPID as previously.
Unless I'm missing something? Maybe I'm testing it wrong.