Adds CheckPrivateField, and uses it to guard private field access before
calling regular element ops, rather than having custom element ops
CheckPrivateField takes two arguments: A ThrowCondition, a message, then using
the top two elements of the stack determines if a throw is required, and if it
is not, places on top of the stack whether or not the field exists.
This design is nice because it means that we'll be able to easily use this
opcode for implementing private methods and ergonomic brand checks for private
fields.
This patch implements the new opcode, deletes the old PrivateElem ops,
and provides Baseline callVM support. It's future work to provide IC, Ion and
Warp support.
Differential Revision: https://phabricator.services.mozilla.com/D83941
All DOMProxyHandler::ClearExternalRefsForWrapperRelease now does is clear a backpointer to the expando, and that's handled during reflector finalization already.
The patch makes the following proxy changes:
* The number of slots in ProxyValueArray is now dynamic and depends on the number of reserved slots we get from the Class.
* "Extra slots" was renamed to "Reserved slots" to make this clearer.
* All proxy Classes now have 2 reserved slots, but it should be easy to change that for proxy Classes that need more than 2 slots.
* Proxies now store a pointer to these slots and this means GetReservedSlot and SetReservedSlot can be used on proxies as well. We no longer need GetReservedOrProxyPrivateSlot and SetReservedOrProxyPrivateSlot.
And some changes to make DOM Proxies work with this:
* We now store the C++ object in the first reserved slot (DOM_OBJECT_SLOT) instead of in the proxy's private slot. This is pretty nice because it matches what we do for non-proxy DOM objects.
* We now store the expando in the proxy's private slot so I removed GetDOMProxyExpandoSlot and changed the IC code to get the expando from the private slot instead.
This should also fix bug 1296775 and bug 1290359.
There's a very good chance it will also fix bug 1293386, bug 1292855, bug
1289452, and bug 1303340: those would get hit if we happened to start _another_
gc after the expando died but while it was still in the Rooted. All of them
seem to be dying under the domClass->mGetProto call, which could finish up a GC
that kills the expando and then do _another_ one, causing the Rooted to try to
mark a dead object.
This should also fix bug 1296775 and bug 1290359.
There's a very good chance it will also fix bug 1293386, bug 1292855, and bug
1289452: those would get hit if we happened to start _another_ gc after the
expando died but while it was still in the Rooted. All of them seem to be
dying under the domClass->mGetProto call, which could finish up a GC that kills
the expando and then do _another_ one, causing the Rooted to try to mark a dead
object.
Also: Change signature of these functions and methods to all have the same arguments in the same order: (cx, obj, id, v, receiver). Also change v from MutableHandleValue to HandleValue.
There is no change in behavior.
In fact the new error message `JSMSG_SET_NON_OBJECT_RECEIVER` is
impossible to trigger from scripts for now, I think (after re-reading
the whole patch with this in mind). JS_ForwardSetPropertyTo is the only
way to get a non-object receiver into the engine, but no caller
currently does so.
We're installing new pipes here, and they should work, but for now it's
the same cold water flowing through as before. Actually hooking up the
hot water is left for another bug (one with tests, not to put too fine a
point on it).
Notes:
* InvokeGetterOrSetter had to be split into two functions:
InvokeGetter takes a MutableHandleValue out-param,
InvokeSetter a HandleValue in-param.
* Watchpoints can still tamper with values being assigned. So can
JSSetterOps. I'm pleased we can support this craziness in a way that
doesn't have to spread via the type system to encompass the entire
codebase.
* Change in GlobalObject::setIntrinsicValue is not really a change.
Yes, it asserted before, but an exception thrown during self-hosting
initialization is not going to go unnoticed either.
* Since the receiver argument to js::SetProperty() is at the end now, it
makes sense for it to be optional. Some callers look nicer.