mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-24 21:31:04 +00:00
Bug 1501124 - Switch BackstagePass to use WebIDLGlobalNameHash, r=bzbarsky
Differential Revision: https://phabricator.services.mozilla.com/D9736
This commit is contained in:
parent
7059a8ac77
commit
84828b5af3
@ -9,7 +9,6 @@
|
||||
|
||||
#include "mozilla/DOMEventTargetHelper.h"
|
||||
#include "mozilla/dom/MessageManagerGlobal.h"
|
||||
#include "mozilla/dom/ResolveSystemBinding.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "xpcpublic.h"
|
||||
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/MessageManagerBinding.h"
|
||||
#include "mozilla/dom/ParentProcessMessageManager.h"
|
||||
#include "mozilla/dom/ResolveSystemBinding.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/ipc/SharedMap.h"
|
||||
|
||||
|
@ -47,7 +47,6 @@
|
||||
#include "mozilla/dom/ParentProcessMessageManager.h"
|
||||
#include "mozilla/dom/PermissionMessageUtils.h"
|
||||
#include "mozilla/dom/ProcessMessageManager.h"
|
||||
#include "mozilla/dom/ResolveSystemBinding.h"
|
||||
#include "mozilla/dom/SameProcessMessageQueue.h"
|
||||
#include "mozilla/dom/ScriptSettings.h"
|
||||
#include "mozilla/dom/ToJSValue.h"
|
||||
|
@ -56,7 +56,6 @@
|
||||
#include "mozilla/dom/XULPopupElementBinding.h"
|
||||
#include "mozilla/dom/XULTextElementBinding.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/ResolveSystemBinding.h"
|
||||
#include "mozilla/dom/WebIDLGlobalNameHash.h"
|
||||
#include "mozilla/dom/WorkerPrivate.h"
|
||||
#include "mozilla/dom/WorkerScope.h"
|
||||
@ -3512,29 +3511,6 @@ UnwrapWindowProxyImpl(JSContext* cx,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
SystemGlobalResolve(JSContext* cx, JS::Handle<JSObject*> obj,
|
||||
JS::Handle<jsid> id, bool* resolvedp)
|
||||
{
|
||||
if (!ResolveGlobal(cx, obj, id, resolvedp)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (*resolvedp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ResolveSystemBinding(cx, obj, id, resolvedp);
|
||||
}
|
||||
|
||||
bool
|
||||
SystemGlobalEnumerate(JSContext* cx, JS::Handle<JSObject*> obj)
|
||||
{
|
||||
bool ignored = false;
|
||||
return JS_EnumerateStandardClasses(cx, obj) &&
|
||||
ResolveSystemBinding(cx, obj, JSID_VOIDHANDLE, &ignored);
|
||||
}
|
||||
|
||||
template<decltype(JS::NewMapObject) Method>
|
||||
bool
|
||||
GetMaplikeSetlikeBackingObject(JSContext* aCx, JS::Handle<JSObject*> aObj,
|
||||
|
@ -13576,121 +13576,6 @@ class CGRegisterWorkletBindings(CGAbstractMethod):
|
||||
return CGList(lines, "\n").define()
|
||||
|
||||
|
||||
class CGSystemBindingInitIds(CGAbstractMethod):
|
||||
def __init__(self):
|
||||
CGAbstractMethod.__init__(self, None, 'SystemBindingInitIds', 'bool',
|
||||
[Argument('JSContext*', 'aCx')])
|
||||
|
||||
def definition_body(self):
|
||||
return dedent("""
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!idsInited) {
|
||||
// We can't use range-based for because we need the index to call IdString.
|
||||
for (uint32_t i = 0; i < ArrayLength(properties); ++i) {
|
||||
if (!properties[i].id.init(aCx, IdString(i))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
idsInited = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
""")
|
||||
|
||||
|
||||
class CGResolveSystemBinding(CGAbstractMethod):
|
||||
def __init__(self):
|
||||
CGAbstractMethod.__init__(self, None, 'ResolveSystemBinding', 'bool',
|
||||
[Argument('JSContext*', 'aCx'),
|
||||
Argument('JS::Handle<JSObject*>', 'aObj'),
|
||||
Argument('JS::Handle<jsid>', 'aId'),
|
||||
Argument('bool*', 'aResolvedp')])
|
||||
|
||||
def definition_body(self):
|
||||
return dedent("""
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(idsInited);
|
||||
|
||||
if (JSID_IS_VOID(aId)) {
|
||||
for (const auto& property : properties) {
|
||||
if (!property.enabled || property.enabled(aCx, aObj)) {
|
||||
if (!property.define(aCx)) {
|
||||
return false;
|
||||
}
|
||||
*aResolvedp = true;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
for (const auto& property : properties) {
|
||||
if (property.id == aId) {
|
||||
if (!property.enabled || property.enabled(aCx, aObj)) {
|
||||
if (!property.define(aCx)) {
|
||||
return false;
|
||||
}
|
||||
*aResolvedp = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
""")
|
||||
|
||||
|
||||
class CGMayResolveAsSystemBindingName(CGAbstractMethod):
|
||||
def __init__(self):
|
||||
CGAbstractMethod.__init__(self, None, 'MayResolveAsSystemBindingName', 'bool',
|
||||
[Argument('jsid', 'aId')])
|
||||
|
||||
def definition_body(self):
|
||||
return dedent("""
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(idsInited);
|
||||
|
||||
for (const auto& property : properties) {
|
||||
if (aId == property.id) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
""")
|
||||
|
||||
|
||||
class CGGetSystemBindingNames(CGAbstractMethod):
|
||||
def __init__(self):
|
||||
CGAbstractMethod.__init__(self, None, 'GetSystemBindingNames', 'void',
|
||||
[Argument('JSContext*', 'aCx'),
|
||||
Argument('JS::Handle<JSObject*>', 'aObj'),
|
||||
Argument('JS::AutoIdVector&', 'aNames'),
|
||||
Argument('bool', 'aEnumerableOnly'),
|
||||
Argument('mozilla::ErrorResult&', 'aRv')])
|
||||
|
||||
def definition_body(self):
|
||||
return dedent("""
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (aEnumerableOnly) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!SystemBindingInitIds(aCx)) {
|
||||
aRv.NoteJSContextException(aCx);
|
||||
return;
|
||||
}
|
||||
|
||||
for (const auto& property : properties) {
|
||||
if (!property.enabled || property.enabled(aCx, aObj)) {
|
||||
if (!aNames.append(property.id)) {
|
||||
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
""")
|
||||
|
||||
|
||||
def getGlobalNames(config):
|
||||
names = []
|
||||
for desc in config.getDescriptors(registersGlobalNamesOnWindow=True):
|
||||
@ -17259,70 +17144,6 @@ class GlobalGenRoots():
|
||||
# Done.
|
||||
return curr
|
||||
|
||||
@staticmethod
|
||||
def ResolveSystemBinding(config):
|
||||
curr = CGList([], "\n")
|
||||
|
||||
descriptors = config.getDescriptors(hasInterfaceObject=True,
|
||||
isExposedInWindow=True,
|
||||
register=True)
|
||||
properties = [desc.name for desc in descriptors]
|
||||
|
||||
curr.append(CGStringTable("IdString", properties, static=True))
|
||||
|
||||
initValues = []
|
||||
for desc in descriptors:
|
||||
bindingNS = toBindingNamespace(desc.name)
|
||||
if desc.isExposedConditionally():
|
||||
enabled = "%s::ConstructorEnabled" % bindingNS
|
||||
else:
|
||||
enabled = "nullptr"
|
||||
define = "%s::GetConstructorObject" % bindingNS
|
||||
initValues.append("{ %s, %s },\n" % (enabled, define))
|
||||
curr.append(CGGeneric(fill("""
|
||||
struct SystemProperty
|
||||
{
|
||||
WebIDLGlobalNameHash::ConstructorEnabled enabled;
|
||||
ProtoGetter define;
|
||||
PinnedStringId id;
|
||||
};
|
||||
|
||||
static SystemProperty properties[] = {
|
||||
$*{init}
|
||||
};
|
||||
|
||||
static bool idsInited = false;
|
||||
""",
|
||||
init="".join(initValues))))
|
||||
|
||||
curr.append(CGSystemBindingInitIds())
|
||||
curr.append(CGResolveSystemBinding())
|
||||
curr.append(CGMayResolveAsSystemBindingName())
|
||||
curr.append(CGGetSystemBindingNames())
|
||||
|
||||
# Wrap all of that in our namespaces.
|
||||
curr = CGNamespace.build(['mozilla', 'dom'],
|
||||
CGWrapper(curr, post='\n'))
|
||||
curr = CGWrapper(curr, post='\n')
|
||||
|
||||
# Add the includes
|
||||
defineIncludes = [CGHeaders.getDeclarationFilename(desc.interface)
|
||||
for desc in config.getDescriptors(hasInterfaceObject=True,
|
||||
register=True,
|
||||
isExposedInWindow=True)]
|
||||
defineIncludes.append("nsThreadUtils.h") # For NS_IsMainThread
|
||||
defineIncludes.append("js/Id.h") # For jsid
|
||||
defineIncludes.append("mozilla/dom/WebIDLGlobalNameHash.h")
|
||||
|
||||
curr = CGHeaders([], [], [], [], [], defineIncludes,
|
||||
'ResolveSystemBinding', curr)
|
||||
|
||||
# Add include guards.
|
||||
curr = CGIncludeGuard('ResolveSystemBinding', curr)
|
||||
|
||||
# Done.
|
||||
return curr
|
||||
|
||||
@staticmethod
|
||||
def UnionTypes(config):
|
||||
unionTypes = UnionsForFile(config, None)
|
||||
|
@ -206,5 +206,79 @@ WebIDLGlobalNameHash::GetNames(JSContext* aCx, JS::Handle<JSObject*> aObj,
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
WebIDLGlobalNameHash::ResolveForSystemGlobal(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aObj,
|
||||
JS::Handle<jsid> aId,
|
||||
bool* aResolvedp)
|
||||
{
|
||||
MOZ_ASSERT(JS_IsGlobalObject(aObj));
|
||||
|
||||
// First we try to resolve standard classes.
|
||||
if (!JS_ResolveStandardClass(aCx, aObj, aId, aResolvedp)) {
|
||||
return false;
|
||||
}
|
||||
if (*aResolvedp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// We don't resolve any non-string entries.
|
||||
if (!JSID_IS_STRING(aId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// XXX(nika): In the Window case, we unwrap our global object here to handle
|
||||
// XRays. I don't think we ever create xrays to system globals, so I believe
|
||||
// we can skip this step.
|
||||
MOZ_ASSERT(!xpc::WrapperFactory::IsXrayWrapper(aObj), "Xrays not supported!");
|
||||
|
||||
// Look up the corresponding entry in the name table, and resolve if enabled.
|
||||
const WebIDLNameTableEntry* entry = GetEntry(JSID_TO_FLAT_STRING(aId));
|
||||
if (entry && (!entry->mEnabled || entry->mEnabled(aCx, aObj))) {
|
||||
if (NS_WARN_IF(!GetPerInterfaceObjectHandle(aCx, entry->mConstructorId,
|
||||
entry->mCreate,
|
||||
/* aDefineOnGlobal = */ true))) {
|
||||
return Throw(aCx, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
*aResolvedp = true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
WebIDLGlobalNameHash::NewEnumerateSystemGlobal(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aObj,
|
||||
JS::AutoIdVector& aProperties,
|
||||
bool aEnumerableOnly)
|
||||
{
|
||||
MOZ_ASSERT(JS_IsGlobalObject(aObj));
|
||||
|
||||
if (!JS_NewEnumerateStandardClasses(aCx, aObj, aProperties, aEnumerableOnly)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// All properties defined on our global are non-enumerable, so we can skip
|
||||
// remaining properties.
|
||||
if (aEnumerableOnly) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Enumerate all entries & add enabled ones.
|
||||
for (size_t i = 0; i < sCount; ++i) {
|
||||
const WebIDLNameTableEntry& entry = sEntries[i];
|
||||
if (!entry.mEnabled || entry.mEnabled(aCx, aObj)) {
|
||||
JSString* str = JS_AtomizeStringN(aCx, sNames + entry.mNameOffset,
|
||||
entry.mNameLength);
|
||||
if (!str || !aProperties.append(NON_INTEGER_ATOM_TO_JSID(str))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace dom
|
||||
} // namespace mozilla
|
||||
|
@ -64,6 +64,17 @@ public:
|
||||
NameType aNameType,
|
||||
JS::AutoIdVector& aNames);
|
||||
|
||||
// Helpers for resolving & enumerating names on the system global.
|
||||
// NOTE: These are distinct as it currently lacks a ProtoAndIfaceCache, and is
|
||||
// an XPCOM global.
|
||||
static bool ResolveForSystemGlobal(JSContext* aCx, JS::Handle<JSObject*> aObj,
|
||||
JS::Handle<jsid> aId, bool* aResolvedp);
|
||||
|
||||
static bool NewEnumerateSystemGlobal(JSContext* aCx,
|
||||
JS::Handle<JSObject*> aObj,
|
||||
JS::AutoIdVector& aProperties,
|
||||
bool aEnumerableOnly);
|
||||
|
||||
private:
|
||||
friend struct WebIDLNameTableEntry;
|
||||
|
||||
|
@ -134,7 +134,6 @@ class WebIDLCodegenManager(LoggingMixin):
|
||||
'RegisterWorkerBindings.h',
|
||||
'RegisterWorkerDebuggerBindings.h',
|
||||
'RegisterWorkletBindings.h',
|
||||
'ResolveSystemBinding.h',
|
||||
'UnionConversions.h',
|
||||
'UnionTypes.h',
|
||||
}
|
||||
@ -145,7 +144,6 @@ class WebIDLCodegenManager(LoggingMixin):
|
||||
'RegisterWorkerBindings.cpp',
|
||||
'RegisterWorkerDebuggerBindings.cpp',
|
||||
'RegisterWorkletBindings.cpp',
|
||||
'ResolveSystemBinding.cpp',
|
||||
'UnionTypes.cpp',
|
||||
'PrototypeList.cpp',
|
||||
}
|
||||
|
@ -10,6 +10,9 @@
|
||||
#include "BackstagePass.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "mozilla/dom/BindingUtils.h"
|
||||
#include "mozilla/dom/WebIDLGlobalNameHash.h"
|
||||
|
||||
using namespace mozilla::dom;
|
||||
|
||||
NS_IMPL_ISUPPORTS(BackstagePass,
|
||||
nsIXPCScriptable,
|
||||
@ -18,11 +21,15 @@ NS_IMPL_ISUPPORTS(BackstagePass,
|
||||
nsIScriptObjectPrincipal,
|
||||
nsISupportsWeakReference)
|
||||
|
||||
// XXX(nika): It appears we don't have support for mayresolve hooks in
|
||||
// nsIXPCScriptable, and I don't really want to add it because I'd rather just
|
||||
// kill nsIXPCScriptable alltogether, so we don't use it here.
|
||||
|
||||
// The nsIXPCScriptable map declaration that will generate stubs for us...
|
||||
#define XPC_MAP_CLASSNAME BackstagePass
|
||||
#define XPC_MAP_QUOTED_CLASSNAME "BackstagePass"
|
||||
#define XPC_MAP_FLAGS (XPC_SCRIPTABLE_WANT_RESOLVE | \
|
||||
XPC_SCRIPTABLE_WANT_ENUMERATE | \
|
||||
XPC_SCRIPTABLE_WANT_NEWENUMERATE | \
|
||||
XPC_SCRIPTABLE_WANT_FINALIZE | \
|
||||
XPC_SCRIPTABLE_WANT_PRECREATE | \
|
||||
XPC_SCRIPTABLE_USE_JSSTUB_FOR_ADDPROPERTY | \
|
||||
@ -58,17 +65,21 @@ BackstagePass::Resolve(nsIXPConnectWrappedNative* wrapper,
|
||||
{
|
||||
JS::RootedObject obj(cx, objArg);
|
||||
JS::RootedId id(cx, idArg);
|
||||
*_retval = mozilla::dom::SystemGlobalResolve(cx, obj, id, resolvedp);
|
||||
*_retval =
|
||||
WebIDLGlobalNameHash::ResolveForSystemGlobal(cx, obj, id, resolvedp);
|
||||
return *_retval ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
BackstagePass::Enumerate(nsIXPConnectWrappedNative* wrapper, JSContext* cx,
|
||||
JSObject* objArg, bool* _retval)
|
||||
BackstagePass::NewEnumerate(nsIXPConnectWrappedNative* wrapper, JSContext* cx,
|
||||
JSObject* objArg, JS::AutoIdVector& properties,
|
||||
bool enumerableOnly, bool* _retval)
|
||||
{
|
||||
JS::RootedObject obj(cx, objArg);
|
||||
*_retval = mozilla::dom::SystemGlobalEnumerate(cx, obj);
|
||||
return *_retval ? NS_OK : NS_ERROR_FAILURE;
|
||||
*_retval =
|
||||
WebIDLGlobalNameHash::NewEnumerateSystemGlobal(cx, obj, properties,
|
||||
enumerableOnly);
|
||||
return *_retval ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/***************************************************************************/
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include "mozilla/dom/DOMPrefs.h"
|
||||
#include "mozilla/dom/Exceptions.h"
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "mozilla/dom/ResolveSystemBinding.h"
|
||||
|
||||
#include "nsDOMMutationObserver.h"
|
||||
#include "nsICycleCollectorListener.h"
|
||||
@ -580,10 +579,6 @@ InitClassesWithNewWrappedGlobal(JSContext* aJSContext,
|
||||
// we need to have a principal.
|
||||
MOZ_ASSERT(aPrincipal);
|
||||
|
||||
if (!SystemBindingInitIds(aJSContext)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
InitGlobalObjectOptions(aOptions, aPrincipal);
|
||||
|
||||
// Call into XPCWrappedNative to make a new global object, scope, and global
|
||||
|
@ -23,8 +23,8 @@ module.exports = {
|
||||
"Ci": false,
|
||||
"Cr": false,
|
||||
"Cu": false,
|
||||
// These globals are made available via WebIDL files, see ResolveSystemBinding in:
|
||||
// https://searchfox.org/mozilla-central/source/__GENERATED__/dom/bindings/ResolveSystemBinding.cpp
|
||||
// These globals are made available via WebIDL files, see WebIDLGlobalNameHash.
|
||||
// XXX(nika): We should also explicitly include window-defined globals here now.
|
||||
"AbortController": false,
|
||||
"AbortSignal": false,
|
||||
"AddonManagerPermissions": false,
|
||||
|
Loading…
Reference in New Issue
Block a user