Bug 1501124 - Switch BackstagePass to use WebIDLGlobalNameHash, r=bzbarsky

Differential Revision: https://phabricator.services.mozilla.com/D9736
This commit is contained in:
Nika Layzell 2018-10-24 19:14:35 -04:00
parent 7059a8ac77
commit 84828b5af3
11 changed files with 104 additions and 221 deletions

View File

@ -9,7 +9,6 @@
#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/MessageManagerGlobal.h"
#include "mozilla/dom/ResolveSystemBinding.h"
#include "nsContentUtils.h"
#include "xpcpublic.h"

View File

@ -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"

View File

@ -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"

View File

@ -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,

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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',
}

View File

@ -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;
}
/***************************************************************************/

View File

@ -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

View File

@ -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,